-
Notifications
You must be signed in to change notification settings - Fork 2.1k
/
ShaderManagerGLES.h
230 lines (182 loc) · 5.9 KB
/
ShaderManagerGLES.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
// Copyright (c) 2012- PPSSPP Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0 or later versions.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#pragma once
#include <vector>
#include "base/basictypes.h"
#include "Common/Hashmaps.h"
#include "GPU/Common/ShaderCommon.h"
#include "GPU/Common/ShaderId.h"
#include "GPU/GLES/VertexShaderGeneratorGLES.h"
#include "GPU/GLES/FragmentShaderGeneratorGLES.h"
class Shader;
// Pre-fetched attrs and uniforms
enum {
ATTR_POSITION = 0,
ATTR_TEXCOORD = 1,
ATTR_NORMAL = 2,
ATTR_W1 = 3,
ATTR_W2 = 4,
ATTR_COLOR0 = 5,
ATTR_COLOR1 = 6,
ATTR_COUNT,
};
class LinkedShader {
public:
LinkedShader(VShaderID VSID, Shader *vs, FShaderID FSID, Shader *fs, bool useHWTransform, bool preloading = false);
~LinkedShader();
void use(const VShaderID &VSID, LinkedShader *previous);
void stop();
void UpdateUniforms(u32 vertType, const VShaderID &VSID);
Shader *vs_;
// Set to false if the VS failed, happens on Mali-400 a lot for complex shaders.
bool useHWTransform_;
uint32_t program = 0;
uint64_t availableUniforms;
uint64_t dirtyUniforms = 0;
// Present attributes in the shader.
int attrMask; // 1 << ATTR_ ... or-ed together.
int u_stencilReplaceValue;
int u_tex;
int u_proj;
int u_proj_through;
int u_texenv;
int u_view;
int u_texmtx;
int u_world;
int u_depthRange; // x,y = viewport xscale/xcenter. z,w=clipping minz/maxz (?)
#ifdef USE_BONE_ARRAY
int u_bone; // array, size is numBones
#else
int u_bone[8];
#endif
int numBones;
// Shader blending.
int u_fbotex;
int u_blendFixA;
int u_blendFixB;
int u_fbotexSize;
// Fragment processing inputs
int u_alphacolorref;
int u_alphacolormask;
int u_testtex;
int u_fogcolor;
int u_fogcoef;
// Texturing
int u_uvscaleoffset;
int u_texclamp;
int u_texclampoff;
// Lighting
int u_ambient;
int u_matambientalpha;
int u_matdiffuse;
int u_matspecular;
int u_matemissive;
int u_lightpos[4];
int u_lightdir[4];
int u_lightatt[4]; // attenuation
int u_lightangle[4]; // spotlight cone angle (cosine)
int u_lightspotCoef[4]; // spotlight dropoff
int u_lightdiffuse[4]; // each light consist of vec4[3]
int u_lightspecular[4]; // attenuation
int u_lightambient[4]; // attenuation
int u_tess_pos_tex;
int u_tess_tex_tex;
int u_tess_col_tex;
int u_spline_count_u;
int u_spline_count_v;
int u_spline_type_u;
int u_spline_type_v;
};
// Real public interface
class Shader {
public:
Shader(const ShaderID &id, const char *code, uint32_t glShaderType, bool useHWTransform, uint32_t attrMask, uint64_t uniformMask);
~Shader();
uint32_t shader;
bool Failed() const { return failed_; }
bool UseHWTransform() const { return useHWTransform_; } // only relevant for vtx shaders
std::string GetShaderString(DebugShaderStringType type, ShaderID id) const;
uint32_t GetAttrMask() const { return attrMask_; }
uint64_t GetUniformMask() const { return uniformMask_; }
private:
std::string source_;
bool failed_;
bool useHWTransform_;
bool isFragment_;
uint32_t attrMask_; // only used in vertex shaders
uint64_t uniformMask_;
};
class ShaderManagerGLES : public ShaderManagerCommon {
public:
ShaderManagerGLES();
~ShaderManagerGLES();
void ClearCache(bool deleteThem); // TODO: deleteThem currently not respected
// This is the old ApplyShader split into two parts, because of annoying information dependencies.
// If you call ApplyVertexShader, you MUST call ApplyFragmentShader soon afterwards.
Shader *ApplyVertexShader(int prim, u32 vertType, VShaderID *VSID);
LinkedShader *ApplyFragmentShader(VShaderID VSID, Shader *vs, u32 vertType, int prim);
void DirtyShader();
void DirtyLastShader() override; // disables vertex arrays
int GetNumVertexShaders() const { return (int)vsCache_.size(); }
int GetNumFragmentShaders() const { return (int)fsCache_.size(); }
int GetNumPrograms() const { return (int)linkedShaderCache_.size(); }
std::vector<std::string> DebugGetShaderIDs(DebugShaderType type);
std::string DebugGetShaderString(std::string id, DebugShaderType type, DebugShaderStringType stringType);
void Load(const std::string &filename);
bool ContinuePrecompile(float sliceTime = 1.0f / 60.0f);
void Save(const std::string &filename);
private:
void Clear();
Shader *CompileFragmentShader(FShaderID id);
Shader *CompileVertexShader(VShaderID id);
struct LinkedShaderCacheEntry {
LinkedShaderCacheEntry(Shader *vs_, Shader *fs_, LinkedShader *ls_)
: vs(vs_), fs(fs_), ls(ls_) { }
Shader *vs;
Shader *fs;
LinkedShader *ls;
};
typedef std::vector<LinkedShaderCacheEntry> LinkedShaderCache;
LinkedShaderCache linkedShaderCache_;
bool lastVShaderSame_;
FShaderID lastFSID_;
VShaderID lastVSID_;
LinkedShader *lastShader_;
u64 shaderSwitchDirtyUniforms_;
char *codeBuffer_;
typedef DenseHashMap<FShaderID, Shader *, nullptr> FSCache;
FSCache fsCache_;
typedef DenseHashMap<VShaderID, Shader *, nullptr> VSCache;
VSCache vsCache_;
bool diskCacheDirty_;
struct {
std::vector<VShaderID> vert;
std::vector<FShaderID> frag;
std::vector<std::pair<VShaderID, FShaderID>> link;
size_t vertPos = 0;
size_t fragPos = 0;
size_t linkPos = 0;
double start;
void Clear() {
vert.clear();
frag.clear();
link.clear();
vertPos = 0;
fragPos = 0;
linkPos = 0;
}
bool Done() {
return vertPos >= vert.size() && fragPos >= frag.size() && linkPos >= link.size();
}
} diskCachePending_;
};