diff --git a/GPU/Common/FragmentShaderGenerator.cpp b/GPU/Common/FragmentShaderGenerator.cpp index 0219a2391d..dc2c1efb3f 100644 --- a/GPU/Common/FragmentShaderGenerator.cpp +++ b/GPU/Common/FragmentShaderGenerator.cpp @@ -103,7 +103,6 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu bool testForceToZero = id.Bit(FS_BIT_TEST_DISCARD_TO_ZERO); bool enableColorTest = id.Bit(FS_BIT_COLOR_TEST); bool colorTestAgainstZero = id.Bit(FS_BIT_COLOR_AGAINST_ZERO); - bool enableColorDoubling = id.Bit(FS_BIT_COLOR_DOUBLE); bool doTextureProjection = id.Bit(FS_BIT_DO_TEXTURE_PROJ); if (texture3D && arrayTexture) { @@ -261,6 +260,7 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu WRITE(p, "float3 u_texenv : register(c%i);\n", CONST_PS_TEXENV); } WRITE(p, "float u_texNoAlpha : register(c%i);\n", CONST_PS_TEX_NO_ALPHA); + WRITE(p, "float u_texMul : register(c%i);\n", CONST_PS_TEX_MUL); } WRITE(p, "float3 u_fogcolor : register(c%i);\n", CONST_PS_FOGCOLOR); if (texture3D) { @@ -353,8 +353,9 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu } else { WRITE(p, "uniform sampler2D tex;\n"); } - *uniformMask |= DIRTY_TEXALPHA; + *uniformMask |= DIRTY_TEX_ALPHA_MUL; WRITE(p, "uniform float u_texNoAlpha;\n"); + WRITE(p, "uniform float u_texMul;\n"); } if (readFramebufferTex) { @@ -853,10 +854,10 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu WRITE(p, " vec4 v = p + s;\n"); break; break; } - if (enableColorDoubling) { - // This happens before fog is applied. - WRITE(p, " v.rgb = clamp(v.rgb * 2.0, 0.0, 1.0);\n"); - } + + // This happens before fog is applied. + *uniformMask |= DIRTY_TEX_ALPHA_MUL; + WRITE(p, " v.rgb = clamp(v.rgb * u_texMul, 0.0, 1.0);\n"); } else { // No texture mapping WRITE(p, " vec4 v = v_color0 + s;\n"); diff --git a/GPU/Common/FragmentShaderGenerator.h b/GPU/Common/FragmentShaderGenerator.h index bd96f6dcff..abfa97ff11 100644 --- a/GPU/Common/FragmentShaderGenerator.h +++ b/GPU/Common/FragmentShaderGenerator.h @@ -37,9 +37,10 @@ struct FShaderID; #define CONST_PS_TEXCLAMPOFF 9 #define CONST_PS_MIPBIAS 10 #define CONST_PS_TEX_NO_ALPHA 11 +#define CONST_PS_TEX_MUL 12 // For stencil upload -#define BCONST_PS_STENCILVALUE 12 +#define BCONST_PS_STENCILVALUE 13 // D3D9 bool constants, they have their own register space. diff --git a/GPU/Common/ShaderCommon.h b/GPU/Common/ShaderCommon.h index 7743dac933..1ffcfe5731 100644 --- a/GPU/Common/ShaderCommon.h +++ b/GPU/Common/ShaderCommon.h @@ -89,13 +89,11 @@ enum : uint64_t { DIRTY_MIPBIAS = 1ULL << 37, DIRTY_LIGHT_CONTROL = 1ULL << 38, - - DIRTY_TEXALPHA = 1ULL << 39, + DIRTY_TEX_ALPHA_MUL = 1ULL << 39, DIRTY_BONE_UNIFORMS = 0xFF000000ULL, DIRTY_ALL_UNIFORMS = 0xFFFFFFFFFFULL, - DIRTY_ALL_LIGHTS = DIRTY_LIGHT0 | DIRTY_LIGHT1 | DIRTY_LIGHT2 | DIRTY_LIGHT3, // Other dirty elements that aren't uniforms! DIRTY_FRAMEBUF = 1ULL << 40, diff --git a/GPU/Common/ShaderId.cpp b/GPU/Common/ShaderId.cpp index 1ec1012f75..bc447c735d 100644 --- a/GPU/Common/ShaderId.cpp +++ b/GPU/Common/ShaderId.cpp @@ -193,7 +193,6 @@ std::string FragmentShaderDesc(const FShaderID &id) { if (id.Bit(FS_BIT_DO_TEXTURE)) desc << (id.Bit(FS_BIT_3D_TEXTURE) ? "Tex3D " : "Tex "); if (id.Bit(FS_BIT_DO_TEXTURE_PROJ)) desc << "TexProj "; if (id.Bit(FS_BIT_TEXTURE_AT_OFFSET)) desc << "TexOffs "; - if (id.Bit(FS_BIT_COLOR_DOUBLE)) desc << "2x "; if (id.Bit(FS_BIT_FLATSHADE)) desc << "Flat "; if (id.Bit(FS_BIT_BGRA_TEXTURE)) desc << "BGRA "; switch ((ShaderDepalMode)id.Bits(FS_BIT_SHADER_DEPAL_MODE, 2)) { @@ -288,7 +287,6 @@ void ComputeFragmentShaderID(FShaderID *id_out, const ComputedPipelineState &pip bool enableFog = gstate.isFogEnabled() && !isModeThrough; bool enableAlphaTest = gstate.isAlphaTestEnabled() && !IsAlphaTestTriviallyTrue(); bool enableColorTest = gstate.isColorTestEnabled() && !IsColorTestTriviallyTrue(); - bool enableColorDoubling = gstate.isColorDoublingEnabled() && gstate.isTextureMapEnabled(); bool doTextureProjection = (gstate.getUVGenMode() == GE_TEXMAP_TEXTURE_MATRIX && MatrixNeedsProjection(gstate.tgenMatrix, gstate.getUVProjMode())); bool doFlatShading = gstate.getShadeMode() == GE_SHADE_FLAT; @@ -334,7 +332,6 @@ void ComputeFragmentShaderID(FShaderID *id_out, const ComputedPipelineState &pip } id.SetBit(FS_BIT_DO_TEXTURE_PROJ, doTextureProjection); - id.SetBit(FS_BIT_COLOR_DOUBLE, enableColorDoubling); // 2 bits id.SetBits(FS_BIT_STENCIL_TO_ALPHA, 2, stencilToAlpha); diff --git a/GPU/Common/ShaderId.h b/GPU/Common/ShaderId.h index 62adaaf38a..032042193a 100644 --- a/GPU/Common/ShaderId.h +++ b/GPU/Common/ShaderId.h @@ -82,7 +82,7 @@ enum FShaderBit : uint8_t { FS_BIT_COLOR_AGAINST_ZERO = 20, // 1 free bit FS_BIT_DO_TEXTURE_PROJ = 22, - FS_BIT_COLOR_DOUBLE = 23, + // 1 free bit FS_BIT_STENCIL_TO_ALPHA = 24, // 2 bits FS_BIT_REPLACE_ALPHA_WITH_STENCIL_TYPE = 26, // 4 bits (ReplaceAlphaType) FS_BIT_SIMULATE_LOGIC_OP_TYPE = 30, // 2 bits diff --git a/GPU/Common/ShaderUniforms.cpp b/GPU/Common/ShaderUniforms.cpp index e2baeabd1d..923a96c315 100644 --- a/GPU/Common/ShaderUniforms.cpp +++ b/GPU/Common/ShaderUniforms.cpp @@ -198,8 +198,9 @@ void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipView } } - if (dirtyUniforms & DIRTY_TEXALPHA) { + if (dirtyUniforms & DIRTY_TEX_ALPHA_MUL) { ub->texNoAlpha = gstate.isTextureAlphaUsed() ? 0.0f : 1.0f; + ub->texMul = gstate.isColorDoublingEnabled() ? 2.0f : 1.0f; } if (dirtyUniforms & DIRTY_STENCILREPLACEVALUE) { diff --git a/GPU/Common/ShaderUniforms.h b/GPU/Common/ShaderUniforms.h index 4e8a560065..02e16a1458 100644 --- a/GPU/Common/ShaderUniforms.h +++ b/GPU/Common/ShaderUniforms.h @@ -9,7 +9,7 @@ enum : uint64_t { DIRTY_BASE_UNIFORMS = DIRTY_WORLDMATRIX | DIRTY_PROJTHROUGHMATRIX | DIRTY_VIEWMATRIX | DIRTY_TEXMATRIX | DIRTY_ALPHACOLORREF | - DIRTY_PROJMATRIX | DIRTY_FOGCOLOR | DIRTY_FOGCOEFENABLE | DIRTY_TEXENV | DIRTY_TEXALPHA | DIRTY_STENCILREPLACEVALUE | + DIRTY_PROJMATRIX | DIRTY_FOGCOLOR | DIRTY_FOGCOEFENABLE | DIRTY_TEXENV | DIRTY_TEX_ALPHA_MUL | DIRTY_STENCILREPLACEVALUE | DIRTY_ALPHACOLORMASK | DIRTY_SHADERBLEND | DIRTY_COLORWRITEMASK | DIRTY_UVSCALEOFFSET | DIRTY_TEXCLAMP | DIRTY_DEPTHRANGE | DIRTY_MATAMBIENTALPHA | DIRTY_BEZIERSPLINE | DIRTY_DEPAL, DIRTY_LIGHT_UNIFORMS = @@ -39,7 +39,7 @@ struct alignas(16) UB_VS_FS_Base { float blendFixB[3]; float rotation; float texClamp[4]; float texClampOffset[2]; float fogCoef[2]; - float texNoAlpha; float pad[3]; + float texNoAlpha; float texMul; float padding[2]; // VR stuff is to go here, later. For normal drawing, we can then get away // with just uploading the first 448 bytes of the struct (up to and including fogCoef). }; @@ -66,7 +66,7 @@ R"( mat4 u_proj; vec4 u_texclamp; vec2 u_texclampoff; vec2 u_fogcoef; - float u_texNoAlpha; float pad0; float pad1; float pad2; + float u_texNoAlpha; float u_texMul; float pad1; float pad2; )"; // 512 bytes. Would like to shrink more. Some colors only have 8-bit precision and we expand diff --git a/GPU/Directx9/ShaderManagerDX9.cpp b/GPU/Directx9/ShaderManagerDX9.cpp index 4bb5d6b943..64dbb44544 100644 --- a/GPU/Directx9/ShaderManagerDX9.cpp +++ b/GPU/Directx9/ShaderManagerDX9.cpp @@ -261,7 +261,7 @@ static void ConvertProjMatrixToD3DThrough(Matrix4x4 &in) { in.translateAndScale(Vec3(xoff, yoff, 0.5f), Vec3(1.0f, 1.0f, 0.5f)); } -const uint64_t psUniforms = DIRTY_TEXENV | DIRTY_TEXALPHA | DIRTY_ALPHACOLORREF | DIRTY_ALPHACOLORMASK | DIRTY_FOGCOLOR | DIRTY_STENCILREPLACEVALUE | DIRTY_SHADERBLEND | DIRTY_TEXCLAMP | DIRTY_MIPBIAS; +const uint64_t psUniforms = DIRTY_TEXENV | DIRTY_TEX_ALPHA_MUL | DIRTY_ALPHACOLORREF | DIRTY_ALPHACOLORMASK | DIRTY_FOGCOLOR | DIRTY_STENCILREPLACEVALUE | DIRTY_SHADERBLEND | DIRTY_TEXCLAMP | DIRTY_MIPBIAS; void ShaderManagerDX9::PSUpdateUniforms(u64 dirtyUniforms) { if (dirtyUniforms & DIRTY_TEXENV) { @@ -279,9 +279,10 @@ void ShaderManagerDX9::PSUpdateUniforms(u64 dirtyUniforms) { if (dirtyUniforms & DIRTY_STENCILREPLACEVALUE) { PSSetFloat(CONST_PS_STENCILREPLACE, (float)gstate.getStencilTestRef() * (1.0f / 255.0f)); } - if (dirtyUniforms & DIRTY_TEXALPHA) { + if (dirtyUniforms & DIRTY_TEX_ALPHA_MUL) { // NOTE: Reversed value, more efficient in shader. PSSetFloat(CONST_PS_TEX_NO_ALPHA, gstate.isTextureAlphaUsed() ? 0.0f : 1.0f); + PSSetFloat(CONST_PS_TEX_MUL, gstate.isColorDoublingEnabled() ? 2.0f : 1.0f); } if (dirtyUniforms & DIRTY_SHADERBLEND) { PSSetColorUniform3(CONST_PS_BLENDFIXA, gstate.getFixA()); diff --git a/GPU/GLES/ShaderManagerGLES.cpp b/GPU/GLES/ShaderManagerGLES.cpp index 7bd7af8286..b7bd5711d6 100644 --- a/GPU/GLES/ShaderManagerGLES.cpp +++ b/GPU/GLES/ShaderManagerGLES.cpp @@ -153,6 +153,7 @@ LinkedShader::LinkedShader(GLRenderManager *render, VShaderID VSID, Shader *vs, queries.push_back({ &u_texclamp, "u_texclamp" }); queries.push_back({ &u_texclampoff, "u_texclampoff" }); queries.push_back({ &u_texNoAlpha, "u_texNoAlpha" }); + queries.push_back({ &u_texMul, "u_texMul" }); queries.push_back({ &u_lightControl, "u_lightControl" }); for (int i = 0; i < 4; i++) { @@ -441,8 +442,9 @@ void LinkedShader::UpdateUniforms(const ShaderID &vsid, bool useBufferedRenderin if (dirty & DIRTY_TEXENV) { SetColorUniform3(render_, &u_texenv, gstate.texenvcolor); } - if (dirty & DIRTY_TEXALPHA) { + if (dirty & DIRTY_TEX_ALPHA_MUL) { render_->SetUniformF1(&u_texNoAlpha, gstate.isTextureAlphaUsed() ? 0.0f : 1.0f); + render_->SetUniformF1(&u_texMul, gstate.isColorDoublingEnabled() ? 2.0f : 1.0f); } if (dirty & DIRTY_ALPHACOLORREF) { if (shaderLanguage.bitwiseOps) { @@ -949,7 +951,7 @@ enum class CacheDetectFlags { }; #define CACHE_HEADER_MAGIC 0x83277592 -#define CACHE_VERSION 22 +#define CACHE_VERSION 23 struct CacheHeader { uint32_t magic; uint32_t version; diff --git a/GPU/GLES/ShaderManagerGLES.h b/GPU/GLES/ShaderManagerGLES.h index c5665c533a..a768ff35a1 100644 --- a/GPU/GLES/ShaderManagerGLES.h +++ b/GPU/GLES/ShaderManagerGLES.h @@ -102,6 +102,7 @@ public: int u_texclamp; int u_texclampoff; int u_texNoAlpha; + int u_texMul; // Lighting int u_lightControl; diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index f7a8dfa7e6..fa26a53a1c 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -94,7 +94,7 @@ const CommonCommandTableEntry commonCommandTable[] = { { GE_CMD_TEXSHADELS, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VERTEXSHADER_STATE }, // Raster state for Direct3D 9, uncommon. { GE_CMD_SHADEMODE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VERTEXSHADER_STATE | DIRTY_FRAGMENTSHADER_STATE | DIRTY_RASTER_STATE }, - { GE_CMD_TEXFUNC, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAGMENTSHADER_STATE | DIRTY_TEXALPHA }, + { GE_CMD_TEXFUNC, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAGMENTSHADER_STATE | DIRTY_TEX_ALPHA_MUL }, { GE_CMD_COLORTEST, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAGMENTSHADER_STATE }, { GE_CMD_ALPHATESTENABLE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAGMENTSHADER_STATE }, { GE_CMD_COLORTESTENABLE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAGMENTSHADER_STATE }, diff --git a/GPU/Vulkan/ShaderManagerVulkan.cpp b/GPU/Vulkan/ShaderManagerVulkan.cpp index df2495c088..4cdcab138c 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.cpp +++ b/GPU/Vulkan/ShaderManagerVulkan.cpp @@ -516,7 +516,7 @@ enum class VulkanCacheDetectFlags { }; #define CACHE_HEADER_MAGIC 0xff51f420 -#define CACHE_VERSION 36 +#define CACHE_VERSION 37 struct VulkanCacheHeader { uint32_t magic; uint32_t version;