diff --git a/src/core/hle/D3D8/Direct3D9/FixedFunctionPixelShader.hlsl b/src/core/hle/D3D8/Direct3D9/FixedFunctionPixelShader.hlsl index 9f8784faf..bc676711a 100644 --- a/src/core/hle/D3D8/Direct3D9/FixedFunctionPixelShader.hlsl +++ b/src/core/hle/D3D8/Direct3D9/FixedFunctionPixelShader.hlsl @@ -74,13 +74,7 @@ float4 ExecuteTextureOp(float op, float4 arg1, float4 arg2, float4 arg0, Texture // Note if we use ifs here instead of else if // D3DCompile may stackoverflow at runtime - - // X_D3DTOP_DISABLE can only be reached by ALPHAOP - // It's documented as undefined behaviour - // Test case: DoA:Xtreme menu, GTA III logos - if (op == X_D3DTOP_DISABLE) - return 1; - else if (op == X_D3DTOP_SELECTARG1) + if (op == X_D3DTOP_SELECTARG1) return arg1; else if (op == X_D3DTOP_SELECTARG2) return arg2; @@ -213,9 +207,14 @@ TextureArgs ExecuteTextureStage( float4 aArg0 = GetArg(s.ALPHAARG0, ctx); // Execute texture operation - float4 value; + // ALPHAOP == X_D3DTOP_DISABLE is undefined behaviour + // Using an intermediate value matches known cases... + // Test case: DoA:Xtreme (menu water), GTA III (logos), Crash Wrath of Cortex (relics UI) + static float4 value = 1; value.rgb = ExecuteTextureOp(s.COLOROP, cArg1, cArg2, cArg0, ctx, stage).rgb; - value.a = ExecuteTextureOp(s.ALPHAOP, aArg1, aArg2, aArg0, ctx, stage).a; + if (s.ALPHAOP != X_D3DTOP_DISABLE) { + value.a = ExecuteTextureOp(s.ALPHAOP, aArg1, aArg2, aArg0, ctx, stage).a; + } // Save the result // Note RESULTARG should either be CURRENT or TEMP diff --git a/src/core/hle/D3D8/XbPixelShader.cpp b/src/core/hle/D3D8/XbPixelShader.cpp index 6b8364764..204c1f8ca 100644 --- a/src/core/hle/D3D8/XbPixelShader.cpp +++ b/src/core/hle/D3D8/XbPixelShader.cpp @@ -818,7 +818,10 @@ IDirect3DPixelShader9* GetFixedFunctionShader() states[i].COLORARG1 = (float)XboxTextureStates.Get(i, xbox::X_D3DTSS_COLORARG1); states[i].COLORARG2 = (float)XboxTextureStates.Get(i, xbox::X_D3DTSS_COLORARG2); - states[i].ALPHAOP = (float)XboxTextureStates.Get(i, xbox::X_D3DTSS_ALPHAOP); + auto alphaOp = XboxTextureStates.Get(i, xbox::X_D3DTSS_ALPHAOP); + if (alphaOp == X_D3DTOP_DISABLE) LOG_TEST_CASE("Alpha stage disabled when colour stage is enabled"); + + states[i].ALPHAOP = (float)alphaOp; states[i].ALPHAARG0 = (float)XboxTextureStates.Get(i, xbox::X_D3DTSS_ALPHAARG0); states[i].ALPHAARG1 = (float)XboxTextureStates.Get(i, xbox::X_D3DTSS_ALPHAARG1); states[i].ALPHAARG2 = (float)XboxTextureStates.Get(i, xbox::X_D3DTSS_ALPHAARG2); @@ -879,18 +882,15 @@ IDirect3DPixelShader9* GetFixedFunctionShader() auto s = states[i]; stageSetup << target << "COLOROP = " << GetD3DTOPString(s.COLOROP) << ";\n"; - // TODO handle texture arg flags stageSetup << target << "COLORARG0 = " << GetD3DTASumString(s.COLORARG0) << ";\n"; stageSetup << target << "COLORARG1 = " << GetD3DTASumString(s.COLORARG1) << ";\n"; stageSetup << target << "COLORARG2 = " << GetD3DTASumString(s.COLORARG2) << ";\n"; stageSetup << target << "ALPHAOP = " << GetD3DTOPString(s.ALPHAOP) << ";\n"; - if (states[i].ALPHAOP != X_D3DTOP_DISABLE) { - stageSetup << target << "ALPHAARG0 = " << GetD3DTASumString(s.ALPHAARG0) << ";\n"; - stageSetup << target << "ALPHAARG1 = " << GetD3DTASumString(s.ALPHAARG1) << ";\n"; - stageSetup << target << "ALPHAARG2 = " << GetD3DTASumString(s.ALPHAARG2) << ";\n"; - } + stageSetup << target << "ALPHAARG0 = " << GetD3DTASumString(s.ALPHAARG0) << ";\n"; + stageSetup << target << "ALPHAARG1 = " << GetD3DTASumString(s.ALPHAARG1) << ";\n"; + stageSetup << target << "ALPHAARG2 = " << GetD3DTASumString(s.ALPHAARG2) << ";\n"; stageSetup << target << "RESULTARG = " << GetD3DTASumString(s.RESULTARG, false) << ";\n"; stageSetup << '\n';