mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-07-11 01:25:07 +02:00
Fragment shader uniforms: Pack color mask in 32 bits instead of expand to 128 bits.
Allows us to save 16 bytes from the main uniform buffer, since there's free 32-bit spaces here and there to use.
This commit is contained in:
@@ -354,7 +354,7 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
|
||||
WRITE(p, "uniform vec4 u_alphacolorref;\n");
|
||||
if (compat.bitwiseOps && ((enableColorTest && !colorTestAgainstZero) || (enableAlphaTest && !alphaTestAgainstZero))) {
|
||||
*uniformMask |= DIRTY_ALPHACOLORMASK;
|
||||
WRITE(p, "uniform ivec4 u_alphacolormask;\n");
|
||||
WRITE(p, "uniform uint u_alphacolormask;\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -458,6 +458,12 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
|
||||
WRITE(p, "}\n");
|
||||
}
|
||||
|
||||
if (compat.bitwiseOps && enableColorTest) {
|
||||
p.C("ivec3 unpackIVec3(highp uint x) {\n");
|
||||
p.C(" return ivec3(x & 0xFF, (x >> 8) & 0xFF, (x >> 16) & 0xFF);\n");
|
||||
p.C("}\n");
|
||||
}
|
||||
|
||||
// PowerVR needs a custom modulo function. For some reason, this has far higher precision than the builtin one.
|
||||
if ((gl_extensions.bugs & BUG_PVR_SHADER_PRECISION_BAD) && needShaderTexClamp) {
|
||||
WRITE(p, "float mymod(float a, float b) { return a - b * floor(a / b); }\n");
|
||||
@@ -873,7 +879,7 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
|
||||
const char *alphaTestFuncs[] = { "#", "#", " != ", " == ", " >= ", " > ", " <= ", " < " };
|
||||
if (alphaTestFuncs[alphaTestFunc][0] != '#') {
|
||||
if (compat.bitwiseOps) {
|
||||
WRITE(p, " if ((roundAndScaleTo255i(v.a) & u_alphacolormask.a) %s int(u_alphacolorref.a)) %s\n", alphaTestFuncs[alphaTestFunc], discardStatement);
|
||||
WRITE(p, " if ((roundAndScaleTo255i(v.a) & int(u_alphacolormask >> 24)) %s int(u_alphacolorref.a)) %s\n", alphaTestFuncs[alphaTestFunc], discardStatement);
|
||||
} else if (gl_extensions.gpuVendor == GPU_VENDOR_IMGTEC) {
|
||||
// Work around bad PVR driver problem where equality check + discard just doesn't work.
|
||||
if (alphaTestFunc != GE_COMP_NOTEQUAL) {
|
||||
@@ -932,8 +938,9 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
|
||||
if (compat.shaderLanguage == HLSL_D3D11) {
|
||||
const char *test = colorTestFuncs[colorTestFunc];
|
||||
WRITE(p, " uvec3 v_scaled = roundAndScaleTo255iv(v.rgb);\n");
|
||||
WRITE(p, " uvec3 v_masked = v_scaled & u_alphacolormask.rgb;\n");
|
||||
WRITE(p, " uvec3 colorTestRef = u_alphacolorref.rgb & u_alphacolormask.rgb;\n");
|
||||
WRITE(p, " uvec3 colormask = unpackIVec3(u_alphacolormask);\n");
|
||||
WRITE(p, " uvec3 v_masked = v_scaled & colormask;\n");
|
||||
WRITE(p, " uvec3 colorTestRef = u_alphacolorref.rgb & colormask;\n");
|
||||
// We have to test the components separately, or we get incorrect results. See #10629.
|
||||
WRITE(p, " if (v_masked.r %s colorTestRef.r && v_masked.g %s colorTestRef.g && v_masked.b %s colorTestRef.b) %s\n", test, test, test, discardStatement);
|
||||
} else if (compat.shaderLanguage == HLSL_D3D9) {
|
||||
@@ -943,12 +950,13 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
|
||||
WRITE(p, " if ((colortest.r %s u_alphacolorref.r) && (colortest.g %s u_alphacolorref.g) && (colortest.b %s u_alphacolorref.b)) %s\n", test, test, test, discardStatement);
|
||||
} else if (compat.bitwiseOps) {
|
||||
WRITE(p, " ivec3 v_scaled = roundAndScaleTo255iv(v.rgb);\n");
|
||||
WRITE(p, " uvec3 colormask = unpackIVec3(u_alphacolormask);\n");
|
||||
if (compat.shaderLanguage == GLSL_VULKAN) {
|
||||
// Apparently GLES3 does not support vector bitwise ops, but Vulkan does?
|
||||
WRITE(p, " if ((v_scaled & u_alphacolormask.rgb) %s (u_alphacolorref.rgb & u_alphacolormask.rgb)) %s\n", colorTestFuncs[colorTestFunc], discardStatement);
|
||||
WRITE(p, " if ((v_scaled & colormask) %s (u_alphacolorref.rgb & colormask)) %s\n", colorTestFuncs[colorTestFunc], discardStatement);
|
||||
} else {
|
||||
const char *maskedFragColor = "ivec3(v_scaled.r & u_alphacolormask.r, v_scaled.g & u_alphacolormask.g, v_scaled.b & u_alphacolormask.b)";
|
||||
const char *maskedColorRef = "ivec3(int(u_alphacolorref.r) & u_alphacolormask.r, int(u_alphacolorref.g) & u_alphacolormask.g, int(u_alphacolorref.b) & u_alphacolormask.b)";
|
||||
const char *maskedFragColor = "ivec3(v_scaled.r & colormask.r, v_scaled.g & colormask.g, v_scaled.b & colormask.b)";
|
||||
const char *maskedColorRef = "ivec3(int(u_alphacolorref.r) & colormask.r, int(u_alphacolorref.g) & colormask.g, int(u_alphacolorref.b) & colormask.b)";
|
||||
WRITE(p, " if (%s %s %s) %s\n", maskedFragColor, colorTestFuncs[colorTestFunc], maskedColorRef, discardStatement);
|
||||
}
|
||||
} else if (gl_extensions.gpuVendor == GPU_VENDOR_IMGTEC) {
|
||||
|
||||
@@ -80,7 +80,7 @@ void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipView
|
||||
Uint8x3ToInt4_Alpha(ub->alphaColorRef, gstate.getColorTestRef(), gstate.getAlphaTestRef() & gstate.getAlphaTestMask());
|
||||
}
|
||||
if (dirtyUniforms & DIRTY_ALPHACOLORMASK) {
|
||||
Uint8x3ToInt4_Alpha(ub->colorTestMask, gstate.getColorTestMask(), gstate.getAlphaTestMask());
|
||||
ub->colorTestMask = gstate.getColorTestMask() | (gstate.getAlphaTestMask() << 24);
|
||||
}
|
||||
if (dirtyUniforms & DIRTY_FOGCOLOR) {
|
||||
Uint8x3ToFloat4(ub->fogColor, gstate.fogcolor);
|
||||
|
||||
@@ -36,10 +36,10 @@ struct UB_VS_FS_Base {
|
||||
uint32_t spline_counts; uint32_t depal_mask_shift_off_fmt; // 4 params packed into one.
|
||||
uint32_t colorWriteMask; float mipBias;
|
||||
// Fragment data
|
||||
float fogColor[4];
|
||||
float texEnvColor[4]; // .w is unused
|
||||
float fogColor[4]; // .w is unused
|
||||
float texEnvColor[3];
|
||||
uint32_t colorTestMask;
|
||||
int alphaColorRef[4];
|
||||
int colorTestMask[4];
|
||||
float blendFixA[4]; // .w is unused
|
||||
float blendFixB[4]; // .w is unused
|
||||
float texClamp[4];
|
||||
@@ -66,8 +66,8 @@ R"( mat4 u_proj;
|
||||
float u_mipBias;
|
||||
vec3 u_fogcolor;
|
||||
vec3 u_texenv;
|
||||
uint u_alphacolormask;
|
||||
ivec4 u_alphacolorref;
|
||||
ivec4 u_alphacolormask;
|
||||
vec3 u_blendFixA;
|
||||
vec3 u_blendFixB;
|
||||
vec4 u_texclamp;
|
||||
|
||||
@@ -448,7 +448,7 @@ void LinkedShader::UpdateUniforms(u32 vertType, const ShaderID &vsid, bool useBu
|
||||
SetColorUniform3Alpha255(render_, &u_alphacolorref, gstate.getColorTestRef(), gstate.getAlphaTestRef() & gstate.getAlphaTestMask());
|
||||
}
|
||||
if (dirty & DIRTY_ALPHACOLORMASK) {
|
||||
SetColorUniform3iAlpha(render_, &u_alphacolormask, gstate.colortestmask, gstate.getAlphaTestMask());
|
||||
render_->SetUniformUI1(&u_alphacolormask, gstate.getColorTestMask() | (gstate.getAlphaTestMask() << 24));
|
||||
}
|
||||
if (dirty & DIRTY_COLORWRITEMASK) {
|
||||
render_->SetUniformUI1(&u_colorWriteMask, ~((gstate.pmska << 24) | (gstate.pmskc & 0xFFFFFF)));
|
||||
|
||||
Reference in New Issue
Block a user