diff --git a/src/core/hle/D3D8/Direct3D9/CxbxVertexShaderTemplate.hlsl b/src/core/hle/D3D8/Direct3D9/CxbxVertexShaderTemplate.hlsl index 19173ae0a..b352be68f 100644 --- a/src/core/hle/D3D8/Direct3D9/CxbxVertexShaderTemplate.hlsl +++ b/src/core/hle/D3D8/Direct3D9/CxbxVertexShaderTemplate.hlsl @@ -28,9 +28,9 @@ struct VS_OUTPUT // Xbox constant registers uniform float4 C[X_D3DVS_CONSTREG_COUNT] : register(c0); -// Vertex input overrides for SetVertexData4f support -uniform float4 vOverrideValue[16] : register(c192); -uniform float4 vOverridePacked[4] : register(c208); +// Default values for vertex registers, and whether to use them +uniform float4 vRegisterDefaultValues[16] : register(c192); +uniform float4 vRegisterDefaultFlagsPacked[4] : register(c208); uniform float4 xboxViewportScale : register(c212); uniform float4 xboxViewportOffset : register(c213); @@ -284,12 +284,12 @@ VS_OUTPUT main(const VS_INPUT xIn) // Input registers float4 v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15; - // View 4 packed overrides as an array of 16 floats - float vOverride[16] = (float[16])vOverridePacked; + // Unpack 16 flags from 4 float4 constant registers + float vRegisterDefaultFlags[16] = (float[16])vRegisterDefaultFlagsPacked; - // Initialize input registers from the vertex buffer - // Or use an override value set with SetVertexData4f - #define init_v(i) v##i = lerp(xIn.v[i], vOverride[i], vOverrideValue[i]); + // Initialize input registers from the vertex buffer data + // Or use the register's default value (which can be changed by the title) + #define init_v(i) v##i = lerp(xIn.v[i], vRegisterDefaultValues[i], vRegisterDefaultFlags[i]); // Note : unroll manually instead of for-loop, because of the ## concatenation init_v( 0); init_v( 1); init_v( 2); init_v( 3); init_v( 4); init_v( 5); init_v( 6); init_v( 7); diff --git a/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp b/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp index 337d97661..505de4aba 100644 --- a/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp +++ b/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp @@ -547,13 +547,16 @@ const char *CxbxGetErrorDescription(HRESULT hResult) } // TODO move to shader file. Needs to be called whenever a shader or declaration is set -void SetOverrideFlags(CxbxVertexShader* pCxbxVertexShader) { +void SetVertexRegisterDefaultFlags(CxbxVertexShader* pCxbxVertexShader) { if (pCxbxVertexShader != nullptr && pCxbxVertexShader->pHostVertexShader != nullptr) { - float overrideFlags[16]; + // Titles can specify default values for registers via calls like SetVertexData4f + // HLSL shaders need to know whether to use vertex data or default vertex shader values + // Any register not in the vertex declaration should be set to the default value + float vertexDefaultFlags[16]; for (int i = 0; i < 16; i++) { - overrideFlags[i] = pCxbxVertexShader->VertexShaderInfo.vRegisterInDeclaration[i] ? 1.0f : 0.0f; + vertexDefaultFlags[i] = pCxbxVertexShader->VertexShaderInfo.vRegisterInDeclaration[i] ? 0.0f : 1.0f; } - g_pD3DDevice->SetVertexShaderConstantF(CXBX_D3DVS_CONSTREG_VERTEXDATA4F_FLAG_BASE, overrideFlags, 4); + g_pD3DDevice->SetVertexShaderConstantF(CXBX_D3DVS_CONSTREG_VREGDEFAULTS_FLAG_BASE, vertexDefaultFlags, 4); } } @@ -3580,7 +3583,7 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SelectVertexShader) pHostVertexShader = pCxbxVertexShader->pHostVertexShader; HostFVF = pCxbxVertexShader->HostFVF; - SetOverrideFlags(pCxbxVertexShader); + SetVertexRegisterDefaultFlags(pCxbxVertexShader); } hRet = g_pD3DDevice->SetVertexDeclaration(pHostVertexDeclaration); @@ -4758,7 +4761,7 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetVertexData4f) FLOAT values[] = {a,b,c,d}; if (Register < 0) LOG_TEST_CASE("Register < 0"); if (Register >= 16) LOG_TEST_CASE("Register >= 16"); - g_pD3DDevice->SetVertexShaderConstantF(CXBX_D3DVS_CONSTREG_VERTEXDATA4F_BASE + Register, values, 1); + g_pD3DDevice->SetVertexShaderConstantF(CXBX_D3DVS_CONSTREG_VREGDEFAULTS_BASE + Register, values, 1); } // Grow g_InlineVertexBuffer_Table to contain at least current, and a potentially next vertex @@ -6804,7 +6807,7 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetVertexShader) } else { - SetOverrideFlags(pCxbxVertexShader); + SetVertexRegisterDefaultFlags(pCxbxVertexShader); hRet = g_pD3DDevice->SetVertexShader(pCxbxVertexShader->pHostVertexShader); DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetVertexShader(VshHandleIsVertexShader)"); diff --git a/src/core/hle/D3D8/XbD3D8Types.h b/src/core/hle/D3D8/XbD3D8Types.h index 974a0b26a..daf566898 100644 --- a/src/core/hle/D3D8/XbD3D8Types.h +++ b/src/core/hle/D3D8/XbD3D8Types.h @@ -991,9 +991,9 @@ typedef DWORD X_VERTEXSHADERCONSTANTMODE; // Special Registers, used to pass additional information to the shaders // TODO co-locate shader workaround constants with shader code -#define CXBX_D3DVS_CONSTREG_VERTEXDATA4F_BASE (X_D3DVS_CONSTREG_COUNT) -#define CXBX_D3DVS_CONSTREG_VERTEXDATA4F_FLAG_BASE (CXBX_D3DVS_CONSTREG_VERTEXDATA4F_BASE + 16) -#define CXBX_D3DVS_VIEWPORT_SCALE_MIRROR (CXBX_D3DVS_CONSTREG_VERTEXDATA4F_FLAG_BASE + 4) +#define CXBX_D3DVS_CONSTREG_VREGDEFAULTS_BASE (X_D3DVS_CONSTREG_COUNT) +#define CXBX_D3DVS_CONSTREG_VREGDEFAULTS_FLAG_BASE (CXBX_D3DVS_CONSTREG_VREGDEFAULTS_BASE + 16) +#define CXBX_D3DVS_VIEWPORT_SCALE_MIRROR (CXBX_D3DVS_CONSTREG_VREGDEFAULTS_FLAG_BASE + 4) #define CXBX_D3DVS_VIEWPORT_OFFSET_MIRROR (CXBX_D3DVS_VIEWPORT_SCALE_MIRROR + 1) #define X_D3DSCM_RESERVED_CONSTANT_SCALE_CORRECTED (X_D3DSCM_RESERVED_CONSTANT_SCALE + X_D3DSCM_CORRECTION)