~ppsspp/ppsspp/ppsspp_1.3.0

« back to all changes in this revision

Viewing changes to GPU/Common/ShaderId.cpp

  • Committer: Sérgio Benjamim
  • Date: 2017-01-02 00:12:05 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20170102001205-cxbta9za203nmjwm
1.3.0 source (from ppsspp_1.3.0-r160.p5.l1762.a165.t83~56~ubuntu16.04.1.tar.xz).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <string>
 
2
#include <sstream>
 
3
 
 
4
#include "Common/StringUtils.h"
 
5
#include "Core/Config.h"
 
6
 
 
7
#include "GPU/ge_constants.h"
 
8
#include "GPU/GPUState.h"
 
9
#include "GPU/Common/GPUStateUtils.h"
 
10
#include "GPU/Common/ShaderId.h"
 
11
#include "GPU/Common/VertexDecoderCommon.h"
 
12
 
 
13
std::string VertexShaderDesc(const ShaderID &id) {
 
14
        std::stringstream desc;
 
15
        desc << StringFromFormat("%08x:%08x ", id.d[1], id.d[0]);
 
16
        if (id.Bit(VS_BIT_IS_THROUGH)) desc << "THR ";
 
17
        if (id.Bit(VS_BIT_USE_HW_TRANSFORM)) desc << "HWX ";
 
18
        if (id.Bit(VS_BIT_HAS_COLOR)) desc << "C ";
 
19
        if (id.Bit(VS_BIT_HAS_TEXCOORD)) desc << "T ";
 
20
        if (id.Bit(VS_BIT_HAS_NORMAL)) desc << "N ";
 
21
        if (id.Bit(VS_BIT_LMODE)) desc << "LM ";
 
22
        if (id.Bit(VS_BIT_ENABLE_FOG)) desc << "Fog ";
 
23
        if (id.Bit(VS_BIT_NORM_REVERSE)) desc << "RevN ";
 
24
        if (id.Bit(VS_BIT_DO_TEXTURE)) desc << "Tex ";
 
25
        if (id.Bit(VS_BIT_DO_TEXTURE_PROJ)) desc << "TexProj ";
 
26
        int uvgMode = id.Bits(VS_BIT_UVGEN_MODE, 2);
 
27
        const char *uvgModes[4] = { "UV ", "UVMtx ", "UVEnv ", "UVUnk " };
 
28
        int ls0 = id.Bits(VS_BIT_LS0, 2);
 
29
        int ls1 = id.Bits(VS_BIT_LS1, 2);
 
30
 
 
31
        if (uvgMode) desc << uvgModes[uvgMode];
 
32
        if (id.Bit(VS_BIT_ENABLE_BONES)) desc << "Bones:" << (id.Bits(VS_BIT_BONES, 3) + 1) << " ";
 
33
        // Lights
 
34
        if (id.Bit(VS_BIT_LIGHTING_ENABLE)) {
 
35
                desc << "Light: ";
 
36
                for (int i = 0; i < 4; i++) {
 
37
                        if (id.Bit(VS_BIT_LIGHT0_ENABLE + i) || (uvgMode == GE_TEXMAP_ENVIRONMENT_MAP && (ls0 == i || ls1 == i))) {
 
38
                                desc << i << ": ";
 
39
                                desc << "c:" << id.Bits(VS_BIT_LIGHT0_COMP + 4 * i, 2) << " t:" << id.Bits(VS_BIT_LIGHT0_TYPE + 4 * i, 2) << " ";
 
40
                        }
 
41
                }
 
42
        }
 
43
        if (id.Bits(VS_BIT_MATERIAL_UPDATE, 3)) desc << "MatUp:" << id.Bits(VS_BIT_MATERIAL_UPDATE, 3) << " ";
 
44
        if (id.Bits(VS_BIT_WEIGHT_FMTSCALE, 2)) desc << "WScale " << id.Bits(VS_BIT_WEIGHT_FMTSCALE, 2) << " ";
 
45
        if (id.Bits(VS_BIT_TEXCOORD_FMTSCALE, 2)) desc << "TCScale " << id.Bits(VS_BIT_TEXCOORD_FMTSCALE, 2) << " ";
 
46
        if (id.Bit(VS_BIT_FLATSHADE)) desc << "Flat ";
 
47
 
 
48
        // TODO: More...
 
49
 
 
50
        return desc.str();
 
51
}
 
52
 
 
53
void ComputeVertexShaderID(ShaderID *id_out, u32 vertType, bool useHWTransform) {
 
54
        bool doTexture = gstate.isTextureMapEnabled() && !gstate.isModeClear();
 
55
        bool doTextureProjection = gstate.getUVGenMode() == GE_TEXMAP_TEXTURE_MATRIX;
 
56
        bool doShadeMapping = doTexture && (gstate.getUVGenMode() == GE_TEXMAP_ENVIRONMENT_MAP);
 
57
        bool doFlatShading = gstate.getShadeMode() == GE_SHADE_FLAT && !gstate.isModeClear();
 
58
 
 
59
        bool hasColor = (vertType & GE_VTYPE_COL_MASK) != 0;
 
60
        bool hasNormal = (vertType & GE_VTYPE_NRM_MASK) != 0;
 
61
        bool hasTexcoord = (vertType & GE_VTYPE_TC_MASK) != 0;
 
62
        bool enableFog = gstate.isFogEnabled() && !gstate.isModeThrough() && !gstate.isModeClear();
 
63
        bool lmode = gstate.isUsingSecondaryColor() && gstate.isLightingEnabled();
 
64
        // lmode: && !isModeThrough!?
 
65
 
 
66
        ShaderID id;
 
67
        id.SetBit(VS_BIT_LMODE, lmode);
 
68
        id.SetBit(VS_BIT_IS_THROUGH, gstate.isModeThrough());
 
69
        id.SetBit(VS_BIT_ENABLE_FOG, enableFog);
 
70
        id.SetBit(VS_BIT_HAS_COLOR, hasColor);
 
71
 
 
72
        if (doTexture) {
 
73
                id.SetBit(VS_BIT_DO_TEXTURE);
 
74
                id.SetBit(VS_BIT_DO_TEXTURE_PROJ, doTextureProjection);
 
75
        }
 
76
 
 
77
        if (useHWTransform) {
 
78
                id.SetBit(VS_BIT_USE_HW_TRANSFORM);
 
79
                id.SetBit(VS_BIT_HAS_NORMAL, hasNormal);
 
80
 
 
81
                // UV generation mode. doShadeMapping is implicitly stored here.
 
82
                id.SetBits(VS_BIT_UVGEN_MODE, 2, gstate.getUVGenMode());
 
83
 
 
84
                // The next bits are used differently depending on UVgen mode
 
85
                if (doTextureProjection) {
 
86
                        id.SetBits(VS_BIT_UVPROJ_MODE, 2, gstate.getUVProjMode());
 
87
                } else if (doShadeMapping) {
 
88
                        id.SetBits(VS_BIT_LS0, 2, gstate.getUVLS0());
 
89
                        id.SetBits(VS_BIT_LS1, 2, gstate.getUVLS1());
 
90
                }
 
91
 
 
92
                // Bones.
 
93
                bool enableBones = vertTypeIsSkinningEnabled(vertType);
 
94
                id.SetBit(VS_BIT_ENABLE_BONES, enableBones);
 
95
                if (enableBones) {
 
96
                        id.SetBits(VS_BIT_BONES, 3, TranslateNumBones(vertTypeGetNumBoneWeights(vertType)) - 1);
 
97
                        // 2 bits. We should probably send in the weight scalefactor as a uniform instead,
 
98
                        // or simply preconvert all weights to floats.
 
99
                        id.SetBits(VS_BIT_WEIGHT_FMTSCALE, 2, (vertType & GE_VTYPE_WEIGHT_MASK) >> GE_VTYPE_WEIGHT_SHIFT);
 
100
                }
 
101
 
 
102
                // Okay, d[1] coming up. ==============
 
103
                if (gstate.isLightingEnabled() || doShadeMapping) {
 
104
                        // doShadeMapping is stored as UVGenMode, so this is enough for isLightingEnabled.
 
105
                        if (gstate.isLightingEnabled()) {
 
106
                                id.SetBits(VS_BIT_MATERIAL_UPDATE, 3, gstate.getMaterialUpdate() & 7);
 
107
                                id.SetBit(VS_BIT_LIGHTING_ENABLE);
 
108
                        }
 
109
                        // Light bits
 
110
                        for (int i = 0; i < 4; i++) {
 
111
                                bool chanEnabled = gstate.isLightChanEnabled(i) != 0 && gstate.isLightingEnabled();
 
112
                                id.SetBit(VS_BIT_LIGHT0_ENABLE + i, chanEnabled);
 
113
                                if (chanEnabled || (doShadeMapping && (gstate.getUVLS0() == i || gstate.getUVLS1() == i))) {
 
114
                                        id.SetBits(VS_BIT_LIGHT0_COMP + 4 * i, 2, gstate.getLightComputation(i));
 
115
                                        id.SetBits(VS_BIT_LIGHT0_TYPE + 4 * i, 2, gstate.getLightType(i));
 
116
                                }
 
117
                        }
 
118
                }
 
119
 
 
120
                id.SetBit(VS_BIT_NORM_REVERSE, gstate.areNormalsReversed());
 
121
                id.SetBit(VS_BIT_HAS_TEXCOORD, hasTexcoord);
 
122
                if (doTextureProjection && gstate.getUVProjMode() == GE_PROJMAP_UV) {
 
123
                        id.SetBits(VS_BIT_TEXCOORD_FMTSCALE, 2, (vertType & GE_VTYPE_TC_MASK) >> GE_VTYPE_TC_SHIFT);  // two bits
 
124
                } else {
 
125
                        id.SetBits(VS_BIT_TEXCOORD_FMTSCALE, 2, 3);  // float - no scaling
 
126
                }
 
127
        }
 
128
 
 
129
        id.SetBit(VS_BIT_FLATSHADE, doFlatShading);
 
130
 
 
131
        *id_out = id;
 
132
}
 
133
 
 
134
 
 
135
static const char *alphaTestFuncs[] = { "NEVER", "ALWAYS", "==", "!=", "<", "<=", ">", ">=" };
 
136
 
 
137
std::string FragmentShaderDesc(const ShaderID &id) {
 
138
        std::stringstream desc;
 
139
        desc << StringFromFormat("%08x:%08x ", id.d[1], id.d[0]);
 
140
        if (id.Bit(FS_BIT_CLEARMODE)) desc << "Clear ";
 
141
        if (id.Bit(FS_BIT_DO_TEXTURE)) desc << "Tex ";
 
142
        if (id.Bit(FS_BIT_DO_TEXTURE_PROJ)) desc << "TexProj ";
 
143
        if (id.Bit(FS_BIT_TEXALPHA)) desc << "TexAlpha ";
 
144
        if (id.Bit(FS_BIT_TEXTURE_AT_OFFSET)) desc << "TexOffs ";
 
145
        if (id.Bit(FS_BIT_LMODE)) desc << "LM ";
 
146
        if (id.Bit(FS_BIT_ENABLE_FOG)) desc << "Fog ";
 
147
        if (id.Bit(FS_BIT_COLOR_DOUBLE)) desc << "2x ";
 
148
        if (id.Bit(FS_BIT_FLATSHADE)) desc << "Flat ";
 
149
        if (id.Bit(FS_BIT_BGRA_TEXTURE)) desc << "BGRA ";
 
150
        if (id.Bit(FS_BIT_SHADER_TEX_CLAMP)) {
 
151
                desc << "TClamp";
 
152
                if (id.Bit(FS_BIT_CLAMP_S)) desc << "S";
 
153
                if (id.Bit(FS_BIT_CLAMP_T)) desc << "T";
 
154
                desc << " ";
 
155
        }
 
156
        if (id.Bits(FS_BIT_REPLACE_BLEND, 3)) {
 
157
                desc << "ReplaceBlend_" << id.Bits(FS_BIT_REPLACE_BLEND, 3) << "A:" << id.Bits(FS_BIT_BLENDFUNC_A, 4) << "_B:" << id.Bits(FS_BIT_BLENDFUNC_B, 4) << "_Eq:" << id.Bits(FS_BIT_BLENDEQ, 3) << " ";
 
158
        }
 
159
 
 
160
        switch (id.Bits(FS_BIT_STENCIL_TO_ALPHA, 2)) {
 
161
        case REPLACE_ALPHA_NO: break;
 
162
        case REPLACE_ALPHA_YES: desc << "StenToAlpha "; break;
 
163
        case REPLACE_ALPHA_DUALSOURCE: desc << "StenToAlphaDual "; break;
 
164
        }
 
165
        if (id.Bits(FS_BIT_STENCIL_TO_ALPHA, 2) != REPLACE_ALPHA_NO) {
 
166
                switch (id.Bits(FS_BIT_REPLACE_ALPHA_WITH_STENCIL_TYPE, 4)) {
 
167
                case STENCIL_VALUE_UNIFORM: desc << "StenUniform "; break;
 
168
                case STENCIL_VALUE_ZERO: desc << "Sten0 "; break;
 
169
                case STENCIL_VALUE_ONE: desc << "Sten1 "; break;
 
170
                case STENCIL_VALUE_KEEP: desc << "StenKeep "; break;
 
171
                case STENCIL_VALUE_INVERT: desc << "StenInv "; break;
 
172
                case STENCIL_VALUE_INCR_4: desc << "StenIncr4 "; break;
 
173
                case STENCIL_VALUE_INCR_8: desc << "StenIncr8 "; break;
 
174
                case STENCIL_VALUE_DECR_4: desc << "StenDecr4 "; break;
 
175
                case STENCIL_VALUE_DECR_8: desc << "StenDecr4 "; break;
 
176
                default: desc << "StenUnknown"; break;
 
177
                }
 
178
        }
 
179
        if (id.Bit(FS_BIT_DO_TEXTURE)) {
 
180
                switch (id.Bits(FS_BIT_TEXFUNC, 3)) {
 
181
                case GE_TEXFUNC_ADD: desc << "TFuncAdd "; break;
 
182
                case GE_TEXFUNC_BLEND: desc << "TFuncBlend "; break;
 
183
                case GE_TEXFUNC_DECAL: desc << "TFuncDecal "; break;
 
184
                case GE_TEXFUNC_MODULATE: desc << "TFuncMod "; break;
 
185
                case GE_TEXFUNC_REPLACE: desc << "TFuncRepl "; break;
 
186
                default: desc << "TFuncUnk "; break;
 
187
                }
 
188
        }
 
189
 
 
190
        if (id.Bit(FS_BIT_ALPHA_AGAINST_ZERO)) desc << "AlphaTest0 " << alphaTestFuncs[id.Bits(FS_BIT_ALPHA_TEST_FUNC, 3)] << " ";
 
191
        else if (id.Bit(FS_BIT_ALPHA_TEST)) desc << "AlphaTest " << alphaTestFuncs[id.Bits(FS_BIT_ALPHA_TEST_FUNC, 3)] << " ";
 
192
        if (id.Bit(FS_BIT_COLOR_AGAINST_ZERO)) desc << "ColorTest0 " << alphaTestFuncs[id.Bits(FS_BIT_COLOR_TEST_FUNC, 2)] << " ";  // first 4 match;
 
193
        else if (id.Bit(FS_BIT_COLOR_TEST)) desc << "ColorTest " << alphaTestFuncs[id.Bits(FS_BIT_COLOR_TEST_FUNC, 2)] << " ";  // first 4 match
 
194
 
 
195
        return desc.str();
 
196
}
 
197
 
 
198
// Here we must take all the bits of the gstate that determine what the fragment shader will
 
199
// look like, and concatenate them together into an ID.
 
200
void ComputeFragmentShaderID(ShaderID *id_out) {
 
201
        ShaderID id;
 
202
        if (gstate.isModeClear()) {
 
203
                // We only need one clear shader, so let's ignore the rest of the bits.
 
204
                id.SetBit(FS_BIT_CLEARMODE);
 
205
        } else {
 
206
                bool isModeThrough = gstate.isModeThrough();
 
207
                bool lmode = gstate.isUsingSecondaryColor() && gstate.isLightingEnabled() && !isModeThrough;
 
208
                bool enableFog = gstate.isFogEnabled() && !isModeThrough;
 
209
                bool enableAlphaTest = gstate.isAlphaTestEnabled() && !IsAlphaTestTriviallyTrue() && !g_Config.bDisableAlphaTest;
 
210
                bool enableColorTest = gstate.isColorTestEnabled() && !IsColorTestTriviallyTrue();
 
211
                bool enableColorDoubling = gstate.isColorDoublingEnabled() && gstate.isTextureMapEnabled();
 
212
                bool doTextureProjection = gstate.getUVGenMode() == GE_TEXMAP_TEXTURE_MATRIX;
 
213
                bool doTextureAlpha = gstate.isTextureAlphaUsed();
 
214
                bool doFlatShading = gstate.getShadeMode() == GE_SHADE_FLAT;
 
215
 
 
216
                ReplaceBlendType replaceBlend = ReplaceBlendWithShader(gstate_c.allowShaderBlend, gstate.FrameBufFormat());
 
217
                ReplaceAlphaType stencilToAlpha = ReplaceAlphaWithStencil(replaceBlend);
 
218
 
 
219
                // All texfuncs except replace are the same for RGB as for RGBA with full alpha.
 
220
                if (gstate_c.textureFullAlpha && gstate.getTextureFunction() != GE_TEXFUNC_REPLACE)
 
221
                        doTextureAlpha = false;
 
222
 
 
223
                if (gstate.isTextureMapEnabled()) {
 
224
                        id.SetBit(FS_BIT_DO_TEXTURE);
 
225
                        id.SetBits(FS_BIT_TEXFUNC, 3, gstate.getTextureFunction());
 
226
                        id.SetBit(FS_BIT_TEXALPHA, doTextureAlpha & 1); // rgb or rgba
 
227
                        if (gstate_c.needShaderTexClamp) {
 
228
                                bool textureAtOffset = gstate_c.curTextureXOffset != 0 || gstate_c.curTextureYOffset != 0;
 
229
                                // 4 bits total.
 
230
                                id.SetBit(FS_BIT_SHADER_TEX_CLAMP);
 
231
                                id.SetBit(FS_BIT_CLAMP_S, gstate.isTexCoordClampedS());
 
232
                                id.SetBit(FS_BIT_CLAMP_T, gstate.isTexCoordClampedT());
 
233
                                id.SetBit(FS_BIT_TEXTURE_AT_OFFSET, textureAtOffset);
 
234
                        }
 
235
                        id.SetBit(FS_BIT_BGRA_TEXTURE, gstate_c.bgraTexture);
 
236
                }
 
237
 
 
238
                id.SetBit(FS_BIT_LMODE, lmode);
 
239
                if (enableAlphaTest) {
 
240
                        // 5 bits total.
 
241
                        id.SetBit(FS_BIT_ALPHA_TEST);
 
242
                        id.SetBits(FS_BIT_ALPHA_TEST_FUNC, 3, gstate.getAlphaTestFunction());
 
243
                        id.SetBit(FS_BIT_ALPHA_AGAINST_ZERO, IsAlphaTestAgainstZero());
 
244
                }
 
245
                if (enableColorTest) {
 
246
                        // 4 bits total.
 
247
                        id.SetBit(FS_BIT_COLOR_TEST);
 
248
                        id.SetBits(FS_BIT_COLOR_TEST_FUNC, 2, gstate.getColorTestFunction());
 
249
                        id.SetBit(FS_BIT_COLOR_AGAINST_ZERO, IsColorTestAgainstZero());
 
250
                }
 
251
 
 
252
                id.SetBit(FS_BIT_ENABLE_FOG, enableFog);
 
253
                id.SetBit(FS_BIT_DO_TEXTURE_PROJ, doTextureProjection);
 
254
                id.SetBit(FS_BIT_COLOR_DOUBLE, enableColorDoubling);
 
255
 
 
256
                // 2 bits
 
257
                id.SetBits(FS_BIT_STENCIL_TO_ALPHA, 2, stencilToAlpha);
 
258
 
 
259
                if (stencilToAlpha != REPLACE_ALPHA_NO) {
 
260
                        // 4 bits
 
261
                        id.SetBits(FS_BIT_REPLACE_ALPHA_WITH_STENCIL_TYPE, 4, ReplaceAlphaWithStencilType());
 
262
                }
 
263
 
 
264
                // 2 bits.
 
265
                id.SetBits(FS_BIT_REPLACE_LOGIC_OP_TYPE, 2, ReplaceLogicOpType());
 
266
 
 
267
                // If replaceBlend == REPLACE_BLEND_STANDARD (or REPLACE_BLEND_NO) nothing is done, so we kill these bits.
 
268
                if (replaceBlend > REPLACE_BLEND_STANDARD) {
 
269
                        // 3 bits.
 
270
                        id.SetBits(FS_BIT_REPLACE_BLEND, 3, replaceBlend);
 
271
                        // 11 bits total.
 
272
                        id.SetBits(FS_BIT_BLENDEQ, 3, gstate.getBlendEq());
 
273
                        id.SetBits(FS_BIT_BLENDFUNC_A, 4, gstate.getBlendFuncA());
 
274
                        id.SetBits(FS_BIT_BLENDFUNC_B, 4, gstate.getBlendFuncB());
 
275
                }
 
276
                id.SetBit(FS_BIT_FLATSHADE, doFlatShading);
 
277
        }
 
278
 
 
279
        *id_out = id;
 
280
}