Merge pull request #16709 from unknownbrackets/shader-errors

Correct some shader errors in reporting
This commit is contained in:
Unknown W. Brackets 2023-01-02 13:51:23 -08:00 committed by GitHub
commit 26dc773b2a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 29 additions and 27 deletions

View file

@ -61,7 +61,8 @@ void GenerateDepalShader300(ShaderWriter &writer, const DepalConfig &config) {
if (config.depthUpperBits == 0x2) {
writer.C(R"(
int x = int((texcoord.x / scaleFactor) * texSize.x);
int temp = (x & 0xFFFFFE0F) | ((x >> 1) & 0xF0) | ((x << 4) & 0x100);
int xclear = x & 0x01F0;
int temp = (x - xclear) | ((x >> 1) & 0xF0) | ((x << 4) & 0x100);
texcoord.x = (float(temp) / texSize.x) * scaleFactor;
)");
}
@ -192,7 +193,7 @@ void GenerateDepalShaderFloat(ShaderWriter &writer, const DepalConfig &config) {
if (rgba_shift == 0 && mask == 0xFF) {
sprintf(lookupMethod, "index.%c", rgba[shift]);
} else {
sprintf(lookupMethod, "fmod(index.%c * %f, %d.0)", rgba[shift], 255.99f / (1 << rgba_shift), mask + 1);
sprintf(lookupMethod, "mod(index.%c * %f, %d.0)", rgba[shift], 255.99f / (1 << rgba_shift), mask + 1);
index_multiplier = 1.0f / 256.0f;
// Format was OK if there weren't bits from another component.
formatOK = mask <= 255 - (1 << rgba_shift);
@ -210,7 +211,7 @@ void GenerateDepalShaderFloat(ShaderWriter &writer, const DepalConfig &config) {
index_multiplier = 15.0f / 256.0f;
} else {
// Let's divide and mod to get the right bits. A common case is shift=0, mask=01.
sprintf(lookupMethod, "fmod(index.%c * %f, %d.0)", rgba[shift], 15.99f / (1 << rgba_shift), mask + 1);
sprintf(lookupMethod, "mod(index.%c * %f, %d.0)", rgba[shift], 15.99f / (1 << rgba_shift), mask + 1);
index_multiplier = 1.0f / 256.0f;
formatOK = mask <= 15 - (1 << rgba_shift);
}
@ -230,7 +231,7 @@ void GenerateDepalShaderFloat(ShaderWriter &writer, const DepalConfig &config) {
} else {
// We just need to divide the right component by the right value, and then mod against the mask.
// A common case is shift=1, mask=0f.
sprintf(lookupMethod, "fmod(index.%c * %f, %d.0)", rgba[shift], ((float)multipliers[shift] + 0.99f) / (1 << rgba_shift), mask + 1);
sprintf(lookupMethod, "mod(index.%c * %f, %d.0)", rgba[shift], ((float)multipliers[shift] + 0.99f) / (1 << rgba_shift), mask + 1);
index_multiplier = 1.0f / 256.0f;
formatOK = mask <= multipliers[shift] - (1 << rgba_shift);
}
@ -250,7 +251,7 @@ void GenerateDepalShaderFloat(ShaderWriter &writer, const DepalConfig &config) {
index_multiplier = 1.0f / 256.0f;
} else {
// A isn't possible here.
sprintf(lookupMethod, "fmod(index.%c * %f, %d.0)", rgba[shift], 31.99f / (1 << rgba_shift), mask + 1);
sprintf(lookupMethod, "mod(index.%c * %f, %d.0)", rgba[shift], 31.99f / (1 << rgba_shift), mask + 1);
index_multiplier = 1.0f / 256.0f;
formatOK = mask <= 31 - (1 << rgba_shift);
}

View file

@ -707,16 +707,16 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
// Also, since we know the CLUT is smooth, we do not need to do the bilinear filter manually, we can just
// lookup with the filtered value once.
p.F(" vec4 t = ").SampleTexture2D("tex", "uv").C(";\n");
p.C(" uint depalShift = (u_depal_mask_shift_off_fmt >> 8) & 0xFFU;\n");
p.C(" uint depalFmt = (u_depal_mask_shift_off_fmt >> 24) & 0x3U;\n");
p.C(" uint depalShift = (u_depal_mask_shift_off_fmt >> 8) & 0xFFu;\n");
p.C(" uint depalFmt = (u_depal_mask_shift_off_fmt >> 24) & 0x3u;\n");
p.C(" float index0 = t.r;\n");
p.C(" float factor = 31.0 / 256.0;\n");
p.C(" if (depalFmt == 0u) {\n"); // yes, different versions of Test Drive use different formats. Could do compile time by adding more compat flags but meh.
p.C(" if (depalShift == 5u) { index0 = t.g; factor = 63.0 / 256.0; }\n");
p.C(" else if (depalShift == 11u) { index0 = t.b; }\n");
p.C(" if (depalFmt == 0x0u) {\n"); // yes, different versions of Test Drive use different formats. Could do compile time by adding more compat flags but meh.
p.C(" if (depalShift == 0x5u) { index0 = t.g; factor = 63.0 / 256.0; }\n");
p.C(" else if (depalShift == 0xBu) { index0 = t.b; }\n");
p.C(" } else {\n");
p.C(" if (depalShift == 5u) { index0 = t.g; }\n");
p.C(" else if (depalShift == 10u) { index0 = t.b; }\n");
p.C(" if (depalShift == 0x5u) { index0 = t.g; }\n");
p.C(" else if (depalShift == 0xAu) { index0 = t.b; }\n");
p.C(" }\n");
p.F(" t = ").SampleTexture2D("pal", "vec2(index0 * factor * 0.5, 0.0)").C(";\n"); // 0.5 for 512-entry CLUT.
break;
@ -730,7 +730,7 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
}
WRITE(p, " vec2 tsize = vec2(textureSize(tex, 0).xy);\n");
WRITE(p, " vec2 fraction;\n");
WRITE(p, " bool bilinear = (u_depal_mask_shift_off_fmt >> 31) != 0U;\n");
WRITE(p, " bool bilinear = (u_depal_mask_shift_off_fmt >> 31) != 0x0u;\n");
WRITE(p, " if (bilinear) {\n");
WRITE(p, " uv_round = uv * tsize - vec2(0.5, 0.5);\n");
WRITE(p, " fraction = fract(uv_round);\n");
@ -742,10 +742,10 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
p.C(" highp vec4 t1 = ").SampleTexture2DOffset("tex", "uv_round", 1, 0).C(";\n");
p.C(" highp vec4 t2 = ").SampleTexture2DOffset("tex", "uv_round", 0, 1).C(";\n");
p.C(" highp vec4 t3 = ").SampleTexture2DOffset("tex", "uv_round", 1, 1).C(";\n");
WRITE(p, " uint depalMask = (u_depal_mask_shift_off_fmt & 0xFFU);\n");
WRITE(p, " uint depalShift = (u_depal_mask_shift_off_fmt >> 8) & 0xFFU;\n");
WRITE(p, " uint depalOffset = ((u_depal_mask_shift_off_fmt >> 16) & 0xFFU) << 4;\n");
WRITE(p, " uint depalFmt = (u_depal_mask_shift_off_fmt >> 24) & 0x3U;\n");
WRITE(p, " uint depalMask = (u_depal_mask_shift_off_fmt & 0xFFu);\n");
WRITE(p, " uint depalShift = (u_depal_mask_shift_off_fmt >> 8) & 0xFFu;\n");
WRITE(p, " uint depalOffset = ((u_depal_mask_shift_off_fmt >> 16) & 0xFFu) << 4;\n");
WRITE(p, " uint depalFmt = (u_depal_mask_shift_off_fmt >> 24) & 0x3u;\n");
WRITE(p, " uvec4 col; uint index0; uint index1; uint index2; uint index3;\n");
WRITE(p, " switch (int(depalFmt)) {\n"); // We might want to include fmt in the shader ID if this is a performance issue.
WRITE(p, " case 0:\n"); // 565

View file

@ -967,10 +967,10 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
}
if (lightUberShader && hasColor) {
p.F(" vec4 ambientColor = ((u_lightControl & (1u << 20u)) != 0u) ? %s : u_matambientalpha;\n", srcCol);
p.F(" vec4 ambientColor = ((u_lightControl & (1u << 20u)) != 0x0u) ? %s : u_matambientalpha;\n", srcCol);
if (enableLighting) {
p.F(" vec3 diffuseColor = ((u_lightControl & (1u << 21u)) != 0u) ? %s.rgb : u_matdiffuse;\n", srcCol);
p.F(" vec3 specularColor = ((u_lightControl & (1u << 22u)) != 0u) ? %s.rgb : u_matspecular.rgb;\n", srcCol);
p.F(" vec3 diffuseColor = ((u_lightControl & (1u << 21u)) != 0x0u) ? %s.rgb : u_matdiffuse;\n", srcCol);
p.F(" vec3 specularColor = ((u_lightControl & (1u << 22u)) != 0x0u) ? %s.rgb : u_matspecular.rgb;\n", srcCol);
}
} else {
// This path also takes care of the lightUberShader && !hasColor path, because all comparisons fail.
@ -1031,10 +1031,10 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
// Will need to change how the data is stored to loop efficiently.
// u_lightControl is computed in PackLightControlBits().
for (int i = 0; i < 4; i++) {
p.F(" if ((u_lightControl & %du) != 0u) { \n", 1 << i);
p.F(" uint comp = (u_lightControl >> %d) & 3u;\n", 4 + 4 * i);
p.F(" uint type = (u_lightControl >> %d) & 3u;\n", 4 + 4 * i + 2);
p.C(" if (type == 0u) {\n"); // GE_LIGHTTYPE_DIRECTIONAL
p.F(" if ((u_lightControl & %du) != 0x0u) { \n", 1 << i);
p.F(" uint comp = (u_lightControl >> %d) & 0x3u;\n", 4 + 4 * i);
p.F(" uint type = (u_lightControl >> %d) & 0x3u;\n", 4 + 4 * i + 2);
p.C(" if (type == 0x0u) {\n"); // GE_LIGHTTYPE_DIRECTIONAL
p.F(" toLight = u_lightpos%d;\n", i);
p.C(" } else {\n");
p.F(" toLight = u_lightpos%d - worldpos;\n", i);
@ -1042,7 +1042,7 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
p.F(" toLight /= distance;\n", i);
p.C(" }\n");
p.C(" ldot = dot(toLight, worldnormal);\n");
p.C(" if (comp == 2u) {\n"); // GE_LIGHTCOMP_ONLYPOWDIFFUSE
p.C(" if (comp == 0x2u) {\n"); // GE_LIGHTCOMP_ONLYPOWDIFFUSE
p.C(" if (u_matspecular.a <= 0.0) {\n");
p.C(" ldot = 1.0;\n");
p.C(" } else {\n");
@ -1066,7 +1066,7 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
p.C(" break;\n");
p.C(" }\n");
p.F(" diffuse = (u_lightdiffuse%i * diffuseColor) * max(ldot, 0.0);\n", i);
p.C(" if (comp == 1u) {\n"); // do specular
p.C(" if (comp == 0x1u) {\n"); // do specular
p.C(" if (ldot >= 0.0) {\n");
p.C(" ldot = dot(normalize(toLight + vec3(0.0, 0.0, 1.0)), worldnormal);\n");
p.C(" if (u_matspecular.a <= 0.0) {\n");

View file

@ -168,7 +168,8 @@ u32 GPU_GLES::CheckGPUFeatures() const {
if (gl_extensions.ARB_texture_float || gl_extensions.OES_texture_float)
features |= GPU_USE_TEXTURE_FLOAT;
if (!draw_->GetShaderLanguageDesc().bitwiseOps) {
// Intel drivers have been seen rejecting fragment shader uint shifts used in the alpha test.
if (!draw_->GetShaderLanguageDesc().bitwiseOps || draw_->GetDeviceCaps().vendor == Draw::GPUVendor::VENDOR_INTEL) {
features |= GPU_USE_FRAGMENT_TEST_CACHE;
}