CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/Common/GPU/ShaderWriter.h
Views: 1401
1
#pragma once
2
3
#include <cstring>
4
5
#include "Common/GPU/Shader.h"
6
#include "Common/Data/Collections/Slice.h"
7
8
#include "Common/GPU/thin3d.h"
9
10
// Helps generate a shader compatible with all backends.
11
//
12
// Can use the uniform buffer support in thin3d.
13
//
14
// Using #defines and magic in this class, we partially define our own shader language that basically looks
15
// like GLSL, but has a few little oddities like splat3.
16
17
struct InputDef {
18
const char *type;
19
const char *name;
20
int semantic;
21
};
22
23
struct VaryingDef {
24
const char *type;
25
const char *name;
26
int semantic;
27
int index;
28
const char *precision;
29
};
30
31
enum class ShaderWriterFlags {
32
NONE = 0,
33
FS_WRITE_DEPTH = 1,
34
FS_AUTO_STEREO = 2, // Automatically indexes makes samplers tagged with `array` by gl_ViewIndex. Useful for stereo rendering.
35
};
36
ENUM_CLASS_BITOPS(ShaderWriterFlags);
37
38
class ShaderWriter {
39
public:
40
// Extensions are supported for both OpenGL ES and Vulkan (though of course, they're different).
41
ShaderWriter(char *buffer, const ShaderLanguageDesc &lang, ShaderStage stage, Slice<const char *> extensions = Slice<const char *>(), ShaderWriterFlags flags = ShaderWriterFlags::NONE) : p_(buffer), lang_(lang), stage_(stage), flags_(flags) {
42
buffer[0] = '\0';
43
Preamble(extensions);
44
}
45
ShaderWriter(const ShaderWriter &) = delete;
46
47
// I tried to call all three write functions "W", but only MSVC
48
// managed to disentangle the ambiguities, so had to give up on that.
49
50
// Assumes the input is zero-terminated.
51
// C : Copies a buffer directly to the stream.
52
template<size_t T>
53
ShaderWriter &C(const char(&text)[T]) {
54
memcpy(p_, text, T);
55
p_ += T - 1;
56
return *this;
57
}
58
// W: Writes a zero-terminated string to the stream.
59
ShaderWriter &W(const char *text) {
60
size_t len = strlen(text);
61
memcpy(p_, text, len + 1);
62
p_ += len;
63
return *this;
64
}
65
66
// F: Formats into the buffer.
67
ShaderWriter &F(const char *format, ...);
68
69
ShaderWriter &endl() {
70
return C("\n");
71
}
72
73
// Useful for fragment shaders in GLES.
74
// We always default integers to high precision.
75
void HighPrecisionFloat();
76
void LowPrecisionFloat();
77
78
// NOTE: samplers must live for the rest of ShaderWriter's lifetime. No way to express that in C++ though :(
79
void DeclareSamplers(Slice<SamplerDef> samplers);
80
81
// Same as DeclareSamplers, but doesn't actually declare them.
82
// This is currently only required by FragmentShaderGenerator.
83
void ApplySamplerMetadata(Slice<SamplerDef> samplers);
84
85
void ConstFloat(const char *name, float value);
86
void SetFlags(ShaderWriterFlags flags) { flags_ |= flags; }
87
ShaderWriterFlags Flags() const { return flags_; }
88
void SetTexBindingBase(int base) { texBindingBase_ = base; }
89
90
ShaderWriter &SampleTexture2D(const char *texName, const char *uv);
91
ShaderWriter &SampleTexture2DOffset(const char *texName, const char *uv, int offX, int offY);
92
ShaderWriter &LoadTexture2D(const char *texName, const char *integer_uv, int level);
93
ShaderWriter &GetTextureSize(const char *szVariable, const char *texName);
94
95
// Simple shaders with no special tricks.
96
void BeginVSMain(Slice<InputDef> inputs, Slice<UniformDef> uniforms, Slice<VaryingDef> varyings);
97
void BeginFSMain(Slice<UniformDef> uniforms, Slice<VaryingDef> varyings);
98
void BeginGSMain(Slice<VaryingDef> varyings, Slice<VaryingDef> outVaryings);
99
100
// For simple shaders that output a single color, we can deal with this generically.
101
void EndVSMain(Slice<VaryingDef> varyings);
102
void EndFSMain(const char *vec4_color_variable);
103
void EndGSMain();
104
105
const ShaderLanguageDesc &Lang() const {
106
return lang_;
107
}
108
109
void Rewind(size_t offset) {
110
p_ -= offset;
111
}
112
113
// Can probably remove this
114
char *GetPos() {
115
return p_;
116
}
117
118
private:
119
// Several of the shader languages ignore samplers, beware of that.
120
void DeclareSampler2D(const SamplerDef &def);
121
void DeclareTexture2D(const SamplerDef &def);
122
const SamplerDef *GetSamplerDef(const char *name) const;
123
124
void Preamble(Slice<const char *> extensions);
125
126
char *p_;
127
const ShaderLanguageDesc &lang_;
128
const ShaderStage stage_;
129
Slice<SamplerDef> samplers_;
130
ShaderWriterFlags flags_ = ShaderWriterFlags::NONE;
131
Slice<SamplerDef> samplerDefs_;
132
int texBindingBase_ = 1;
133
};
134
135