diff --git a/GPU/Common/ShaderId.cpp b/GPU/Common/ShaderId.cpp index 46fc89e8aa..d7da61c290 100644 --- a/GPU/Common/ShaderId.cpp +++ b/GPU/Common/ShaderId.cpp @@ -91,7 +91,6 @@ void ComputeVertexShaderID(VShaderID *id_out, VertexDecoder *vertexDecoder, bool !isModeThrough && gstate_c.submitType == SubmitType::DRAW; // neither hw nor sw spline/bezier. See #11692 VShaderID id; - id.SetBit(VS_BIT_LMODE, lmode); id.SetBit(VS_BIT_IS_THROUGH, isModeThrough); id.SetBit(VS_BIT_HAS_COLOR, vtypeHasColor); id.SetBit(VS_BIT_VERTEX_RANGE_CULLING, vertexRangeCulling); @@ -134,6 +133,7 @@ void ComputeVertexShaderID(VShaderID *id_out, VertexDecoder *vertexDecoder, bool // doShadeMapping is stored as UVGenMode, and light type doesn't matter for shade mapping. id.SetBit(VS_BIT_LIGHTING_ENABLE); if (gstate_c.Use(GPU_USE_LIGHT_UBERSHADER)) { + lmode = false; // handled dynamically. id.SetBit(VS_BIT_LIGHT_UBERSHADER); } else { id.SetBits(VS_BIT_MATERIAL_UPDATE, 3, gstate.getMaterialUpdate()); @@ -165,6 +165,7 @@ void ComputeVertexShaderID(VShaderID *id_out, VertexDecoder *vertexDecoder, bool } } + id.SetBit(VS_BIT_LMODE, lmode); id.SetBit(VS_BIT_FLATSHADE, doFlatShading); // These two bits cannot be combined, otherwise havoc occurs. We get reports that indicate this happened somehow... "ERROR: 0:14: 'u_proj' : undeclared identifier" diff --git a/GPU/Common/ShaderUniforms.cpp b/GPU/Common/ShaderUniforms.cpp index 17229c540e..92c22be0fe 100644 --- a/GPU/Common/ShaderUniforms.cpp +++ b/GPU/Common/ShaderUniforms.cpp @@ -274,6 +274,7 @@ void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipView } } +// For "light ubershader" bits. uint32_t PackLightControlBits() { // Bit organization // Bottom 4 bits are enable bits for each light. @@ -292,8 +293,10 @@ uint32_t PackLightControlBits() { lightControl |= type << (4 + i * 4 + 2); } + // Material update is 3 bits. lightControl |= gstate.getMaterialUpdate() << 20; - + // LMODE is 1 bit. + lightControl |= gstate.isUsingSecondaryColor() << 23; return lightControl; } diff --git a/GPU/Common/VertexShaderGenerator.cpp b/GPU/Common/VertexShaderGenerator.cpp index 966ee93ece..295de3ab21 100644 --- a/GPU/Common/VertexShaderGenerator.cpp +++ b/GPU/Common/VertexShaderGenerator.cpp @@ -1157,13 +1157,24 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag WRITE(p, " %sv_color0 = lightSum0;\n", compat.vsOutPrefix); WRITE(p, " %sv_color1 = splat3(0.0);\n", compat.vsOutPrefix); } else { - if (lmode) { - WRITE(p, " %sv_color0 = lightSum0;\n", compat.vsOutPrefix); - // v_color1 only exists when lmode = 1. - WRITE(p, " %sv_color1 = clamp(lightSum1, 0.0, 1.0);\n", compat.vsOutPrefix); + if (lightUberShader) { + p.C(" bool lmode = (u_lightControl & (0x1u << 0x17u)) != 0u;\n"); + p.C(" if (lmode) {"); + p.F(" %sv_color0 = lightSum0;\n", compat.vsOutPrefix); + p.F(" %sv_color1 = clamp(lightSum1, 0.0, 1.0);\n", compat.vsOutPrefix); + p.C(" } else {"); + p.F(" %sv_color0 = clamp(lightSum0 + vec4(lightSum1, 0.0), 0.0, 1.0);\n", compat.vsOutPrefix); + p.F(" %sv_color1 = splat3(0.0);\n", compat.vsOutPrefix); + p.C(" }"); } else { - WRITE(p, " %sv_color0 = clamp(lightSum0 + vec4(lightSum1, 0.0), 0.0, 1.0);\n", compat.vsOutPrefix); - WRITE(p, " %sv_color1 = splat3(0.0);\n", compat.vsOutPrefix); + if (lmode) { + WRITE(p, " %sv_color0 = lightSum0;\n", compat.vsOutPrefix); + // v_color1 only exists when lmode = 1. + WRITE(p, " %sv_color1 = clamp(lightSum1, 0.0, 1.0);\n", compat.vsOutPrefix); + } else { + WRITE(p, " %sv_color0 = clamp(lightSum0 + vec4(lightSum1, 0.0), 0.0, 1.0);\n", compat.vsOutPrefix); + WRITE(p, " %sv_color1 = splat3(0.0);\n", compat.vsOutPrefix); + } } } } else { diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index a9c4b9318c..8cc6004347 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -113,8 +113,8 @@ const CommonCommandTableEntry commonCommandTable[] = { { GE_CMD_LIGHTTYPE3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VERTEXSHADER_STATE | DIRTY_LIGHT3 }, { GE_CMD_MATERIALUPDATE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VERTEXSHADER_STATE }, - // These change both shaders so need flushing. - { GE_CMD_LIGHTMODE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VERTEXSHADER_STATE | DIRTY_FRAGMENTSHADER_STATE | DIRTY_GEOMETRYSHADER_STATE }, + // These change vertex shaders (in non uber shader mode) so need flushing. + { GE_CMD_LIGHTMODE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VERTEXSHADER_STATE }, { GE_CMD_TEXFILTER, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, { GE_CMD_TEXWRAP, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS | DIRTY_FRAGMENTSHADER_STATE }, @@ -472,9 +472,11 @@ void GPUCommon::UpdateCmdInfo() { if (gstate_c.Use(GPU_USE_LIGHT_UBERSHADER)) { cmdInfo_[GE_CMD_MATERIALUPDATE].RemoveDirty(DIRTY_VERTEXSHADER_STATE); cmdInfo_[GE_CMD_MATERIALUPDATE].AddDirty(DIRTY_LIGHT_CONTROL); + cmdInfo_[GE_CMD_LIGHTMODE].AddDirty(DIRTY_LIGHT_CONTROL); } else { cmdInfo_[GE_CMD_MATERIALUPDATE].RemoveDirty(DIRTY_LIGHT_CONTROL); cmdInfo_[GE_CMD_MATERIALUPDATE].AddDirty(DIRTY_VERTEXSHADER_STATE); + cmdInfo_[GE_CMD_LIGHTMODE].RemoveDirty(DIRTY_LIGHT_CONTROL); } }