From f235caca57aad8a2e90a97d2527751dbbe9dde51 Mon Sep 17 00:00:00 2001 From: PatrickvL Date: Mon, 23 Apr 2018 09:13:47 +0200 Subject: [PATCH 01/10] D3D9 : Porting more of the vertex shader conversion code --- src/CxbxKrnl/EmuD3D8/VertexShader.cpp | 163 ++++++++++++++++++-------- src/CxbxKrnl/EmuD3D8Types.h | 2 + 2 files changed, 117 insertions(+), 48 deletions(-) diff --git a/src/CxbxKrnl/EmuD3D8/VertexShader.cpp b/src/CxbxKrnl/EmuD3D8/VertexShader.cpp index 458772b3e..68d70b0bb 100644 --- a/src/CxbxKrnl/EmuD3D8/VertexShader.cpp +++ b/src/CxbxKrnl/EmuD3D8/VertexShader.cpp @@ -44,6 +44,10 @@ #include +#ifdef CXBX_USE_VS30 +//#define CXBX_USE_VS30 // Separate the port to Vertex Shader model 3.0 from the port to Direct3D9 +#endif + // **************************************************************************** // * Vertex shader function recompiler // **************************************************************************** @@ -56,6 +60,11 @@ #define VSH_XBOX_MAX_INSTRUCTION_COUNT 136 // The maximum Xbox shader instruction count #define VSH_MAX_INTERMEDIATE_COUNT 1024 // The maximum number of intermediate format slots +#define X_D3DVSD_MASK_TESSUV 0x10000000 +#define X_D3DVSD_MASK_SKIP 0x10000000 // Skips (normally) dwords +#define X_D3DVSD_MASK_SKIPBYTES 0x08000000 // Skips bytes (no, really?!) +#define X_D3DVSD_STREAMTESSMASK (1 << 28) + typedef enum _VSH_SWIZZLE { SWIZZLE_X = 0, @@ -785,7 +794,11 @@ static void VshWriteShader(VSH_XBOX_SHADER *pShader, switch(pShader->ShaderHeader.Version) { case VERSION_VS: +#ifdef CXBX_USE_VS30 + DisassemblyPos += sprintf(pDisassembly + DisassemblyPos, "vs.3.0\n"); +#else DisassemblyPos += sprintf(pDisassembly + DisassemblyPos, "vs.1.1\n"); +#endif break; case VERSION_XVS: DisassemblyPos += sprintf(pDisassembly + DisassemblyPos, "xvs.1.1\n"); @@ -1629,7 +1642,7 @@ static DWORD VshGetDeclarationSize(DWORD *pDeclaration) { Pos++; } - return (Pos + 1) * sizeof(DWORD); + return Pos + 1; } #ifndef CXBX_USE_D3D9 @@ -1785,7 +1798,10 @@ static inline DWORD VshGetVertexStream(DWORD Token) return (Token & X_D3DVSD_STREAMNUMBERMASK) >> X_D3DVSD_STREAMNUMBERSHIFT; } -static void VshConvertToken_NOP(DWORD *pToken) +static void VshConvertToken_NOP( + DWORD *pToken, + D3DVERTEXELEMENT *pRecompiled +) { // D3DVSD_NOP if(*pToken != DEF_VSH_NOP) @@ -1795,7 +1811,10 @@ static void VshConvertToken_NOP(DWORD *pToken) DbgVshPrintf("\tD3DVSD_NOP(),\n"); } -static DWORD VshConvertToken_CONSTMEM(DWORD *pToken) +static DWORD VshConvertToken_CONSTMEM( + DWORD *pToken, + D3DVERTEXELEMENT *pRecompiled +) { // D3DVSD_CONST DbgVshPrintf("\tD3DVSD_CONST("); @@ -1814,14 +1833,16 @@ static DWORD VshConvertToken_CONSTMEM(DWORD *pToken) return Count; } -static void VshConverToken_TESSELATOR(DWORD *pToken, - boolean IsFixedFunction) +static void VshConvertToken_TESSELATOR( + DWORD *pToken, + D3DVERTEXELEMENT *pRecompiled, + boolean IsFixedFunction +) { using namespace XTL; // TODO: Investigate why Xb2PCRegisterType is only used for fixed function vertex shaders - // D3DVSD_TESSUV - if(*pToken & 0x10000000) + if(*pToken & X_D3DVSD_MASK_TESSUV) { XTL::DWORD VertexRegister = VshGetVertexRegister(*pToken); XTL::DWORD NewVertexRegister = VertexRegister; @@ -1830,8 +1851,14 @@ static void VshConverToken_TESSELATOR(DWORD *pToken, NewVertexRegister = Xb2PCRegisterType(VertexRegister, IsFixedFunction); DbgVshPrintf("),\n"); - *pToken = D3DVSD_TESSUV(NewVertexRegister); - } +#ifdef CXBX_USE_D3D9 + // TODO : Expand on the setting of this TESSUV register element : + pRecompiled->Usage = D3DDECLUSAGE(NewVertexRegister); + pRecompiled->UsageIndex = 0; // TODO : Get Index from Xb2PCRegisterType +#else + *pRecompiled = D3DVSD_TESSUV(NewVertexRegister); +#endif + } // D3DVSD_TESSNORMAL else { @@ -1844,10 +1871,23 @@ static void VshConverToken_TESSELATOR(DWORD *pToken, DbgVshPrintf("\tD3DVSD_TESSNORMAL("); NewVertexRegisterIn = Xb2PCRegisterType(VertexRegisterIn, IsFixedFunction); DbgVshPrintf(", "); +#ifdef CXBX_USE_D3D9 + // TODO : Expand on the setting of this TESSNORMAL input register element : + pRecompiled->Usage = D3DDECLUSAGE(NewVertexRegisterIn); + pRecompiled->UsageIndex = 0; // TODO : Get Index from Xb2PCRegisterType +#endif NewVertexRegisterOut = Xb2PCRegisterType(VertexRegisterOut, IsFixedFunction); DbgVshPrintf("),\n"); - *pToken = D3DVSD_TESSNORMAL(NewVertexRegisterIn, NewVertexRegisterOut); - } + +#ifdef CXBX_USE_D3D9 + // TODO : Expand on the setting of this TESSNORMAL output register element : + pRecompiled++; + pRecompiled->Usage = D3DDECLUSAGE(NewVertexRegisterOut); + pRecompiled->UsageIndex = 0; // TODO : Get Index from Xb2PCRegisterType +#else + *pRecompiled = D3DVSD_TESSNORMAL(NewVertexRegisterIn, NewVertexRegisterOut); +#endif + } } static void VshEndPreviousStreamPatch(CxbxVertexShaderPatch *pPatchData) @@ -1857,11 +1897,14 @@ static void VshEndPreviousStreamPatch(CxbxVertexShaderPatch *pPatchData) } } -static void VshConvertToken_STREAM(DWORD *pToken, - CxbxVertexShaderPatch *pPatchData) +static void VshConvertToken_STREAM( + DWORD *pToken, + D3DVERTEXELEMENT *pRecompiled, + CxbxVertexShaderPatch *pPatchData +) { // D3DVSD_STREAM_TESS - if(*pToken & D3DVSD_STREAMTESSMASK) + if(*pToken & X_D3DVSD_STREAMTESSMASK) { DbgVshPrintf("\tD3DVSD_STREAM_TESS(),\n"); } @@ -1887,7 +1930,10 @@ static void VshConvertToken_STREAM(DWORD *pToken, } } -static void VshConvertToken_STREAMDATA_SKIP(DWORD *pToken) +static void VshConvertToken_STREAMDATA_SKIP( + DWORD *pToken, + D3DVERTEXELEMENT *pRecompiled +) { using namespace XTL; @@ -1896,7 +1942,10 @@ static void VshConvertToken_STREAMDATA_SKIP(DWORD *pToken) // No need to convert; D3DVSD_SKIP is encoded identically on host Direct3D8. } -static void VshConvertToken_STREAMDATA_SKIPBYTES(DWORD *pToken) +static void VshConvertToken_STREAMDATA_SKIPBYTES( + DWORD *pToken, + D3DVERTEXELEMENT *pRecompiled +) { using namespace XTL; @@ -1909,9 +1958,12 @@ static void VshConvertToken_STREAMDATA_SKIPBYTES(DWORD *pToken) *pToken = D3DVSD_SKIP(SkipBytesCount / sizeof(XTL::DWORD)); } -static void VshConvertToken_STREAMDATA_REG(DWORD *pToken, - boolean IsFixedFunction, - CxbxVertexShaderPatch *pPatchData) +static void VshConvertToken_STREAMDATA_REG( + DWORD *pToken, + D3DVERTEXELEMENT *pRecompiled, + boolean IsFixedFunction, + CxbxVertexShaderPatch *pPatchData +) { using namespace XTL; @@ -2068,34 +2120,35 @@ static void VshConvertToken_STREAMDATA_REG(DWORD *pToken, } } -#define D3DVSD_MASK_TESSUV 0x10000000 -#define D3DVSD_MASK_SKIP 0x10000000 // Skips (normally) dwords -#define D3DVSD_MASK_SKIPBYTES 0x08000000 // Skips bytes (no, really?!) - - -static void VshConvertToken_STREAMDATA(DWORD *pToken, - boolean IsFixedFunction, - CxbxVertexShaderPatch *pPatchData) +static void VshConvertToken_STREAMDATA( + DWORD *pToken, + D3DVERTEXELEMENT *pRecompiled, + boolean IsFixedFunction, + CxbxVertexShaderPatch *pPatchData +) { using namespace XTL; - if (*pToken & D3DVSD_MASK_SKIP) + if (*pToken & X_D3DVSD_MASK_SKIP) { // For D3D9, use D3DDECLTYPE_UNUSED ? - if (*pToken & D3DVSD_MASK_SKIPBYTES) { - VshConvertToken_STREAMDATA_SKIPBYTES(pToken); + if (*pToken & X_D3DVSD_MASK_SKIPBYTES) { + VshConvertToken_STREAMDATA_SKIPBYTES(pToken, pRecompiled); } else { - VshConvertToken_STREAMDATA_SKIP(pToken); + VshConvertToken_STREAMDATA_SKIP(pToken, pRecompiled); } } else // D3DVSD_REG { - VshConvertToken_STREAMDATA_REG(pToken, IsFixedFunction, pPatchData); + VshConvertToken_STREAMDATA_REG(pToken, pRecompiled, IsFixedFunction, pPatchData); } } -static DWORD VshRecompileToken(DWORD *pToken, - boolean IsFixedFunction, - CxbxVertexShaderPatch *pPatchData) +static DWORD VshRecompileToken( + DWORD *pToken, + D3DVERTEXELEMENT *&pRecompiled, + boolean IsFixedFunction, + CxbxVertexShaderPatch *pPatchData +) { using namespace XTL; @@ -2104,26 +2157,26 @@ static DWORD VshRecompileToken(DWORD *pToken, switch(VshGetTokenType(*pToken)) { case D3DVSD_TOKEN_NOP: - VshConvertToken_NOP(pToken); + VshConvertToken_NOP(pToken, pRecompiled); break; case D3DVSD_TOKEN_STREAM: { - VshConvertToken_STREAM(pToken, pPatchData); + VshConvertToken_STREAM(pToken, pRecompiled, pPatchData); break; } case D3DVSD_TOKEN_STREAMDATA: { - VshConvertToken_STREAMDATA(pToken, IsFixedFunction, pPatchData); + VshConvertToken_STREAMDATA(pToken, pRecompiled, IsFixedFunction, pPatchData); break; } case D3DVSD_TOKEN_TESSELLATOR: { - VshConverToken_TESSELATOR(pToken, IsFixedFunction); + VshConvertToken_TESSELATOR(pToken, pRecompiled, IsFixedFunction); break; } case D3DVSD_TOKEN_CONSTMEM: { - Step = VshConvertToken_CONSTMEM(pToken); + Step = VshConvertToken_CONSTMEM(pToken, pRecompiled); break; } default: @@ -2137,7 +2190,7 @@ static DWORD VshRecompileToken(DWORD *pToken, DWORD XTL::EmuRecompileVshDeclaration ( DWORD *pDeclaration, - DWORD **ppRecompiledDeclaration, + D3DVERTEXELEMENT **ppRecompiledDeclaration, DWORD *pDeclarationSize, boolean IsFixedFunction, CxbxVertexShaderInfo *pVertexShaderInfo @@ -2153,8 +2206,19 @@ DWORD XTL::EmuRecompileVshDeclaration // Calculate size of declaration DWORD DeclarationSize = VshGetDeclarationSize(pDeclaration); - DWORD *pRecompiled = (DWORD *)malloc(DeclarationSize); +#ifdef CXBX_USE_D3D9 + // For Direct3D9, we need to reserve at least twice the number of elements, as one token can generate two registers (in and out) : + DeclarationSize *= sizeof(D3DVERTEXELEMENT) * 2; +#else + // For Direct3D8, tokens are the same size as on Xbox (DWORD) and are translated in-place : + DeclarationSize *= sizeof(DWORD); +#endif + D3DVERTEXELEMENT *pRecompiled = (D3DVERTEXELEMENT *)malloc(DeclarationSize); +#ifdef CXBX_USE_D3D9 + memset(pRecompiled, 0, DeclarationSize); +#else memcpy(pRecompiled, pDeclaration, DeclarationSize); +#endif uint8_t *pRecompiledBufferOverflow = ((uint8_t*)pRecompiled) + DeclarationSize; *ppRecompiledDeclaration = pRecompiled; *pDeclarationSize = DeclarationSize; @@ -2164,18 +2228,21 @@ DWORD XTL::EmuRecompileVshDeclaration DbgVshPrintf("DWORD dwVSHDecl[] =\n{\n"); - while (*pRecompiled != DEF_VSH_END) + while (*pDeclaration != DEF_VSH_END) { if ((uint8*)pRecompiled >= pRecompiledBufferOverflow) { DbgVshPrintf("Detected buffer-overflow, breaking out...\n"); break; } - DWORD Step = VshRecompileToken(pRecompiled, IsFixedFunction, &PatchData); - pRecompiled += Step; - } - - VshEndPreviousStreamPatch(&PatchData); + DWORD Step = VshRecompileToken(pDeclaration, pRecompiled, IsFixedFunction, &PatchData); + pDeclaration += Step; +#ifndef CXBX_USE_D3D9 + pRecompiled += Step; +#endif + } + + VshEndPreviousStreamPatch(&PatchData); DbgVshPrintf("\tD3DVSD_END()\n};\n"); DbgVshPrintf("// NbrStreams: %d\n", PatchData.pVertexShaderInfoToSet->NumberOfVertexStreams); diff --git a/src/CxbxKrnl/EmuD3D8Types.h b/src/CxbxKrnl/EmuD3D8Types.h index 5560f1427..34913e0a5 100755 --- a/src/CxbxKrnl/EmuD3D8Types.h +++ b/src/CxbxKrnl/EmuD3D8Types.h @@ -73,6 +73,7 @@ #define D3DADAPTER_IDENTIFIER D3DADAPTER_IDENTIFIER9 #define D3DCAPS D3DCAPS9 +#define D3DVERTEXELEMENT D3DVERTEXELEMENT9 #define D3DVIEWPORT D3DVIEWPORT9 #define IDirect3D IDirect3D9 @@ -115,6 +116,7 @@ typedef D3DVIEWPORT9 X_D3DVIEWPORT8; #define D3DADAPTER_IDENTIFIER D3DADAPTER_IDENTIFIER8 #define D3DCAPS D3DCAPS8 +#define D3DVERTEXELEMENT DWORD #define D3DVIEWPORT D3DVIEWPORT8 #define IDirect3D IDirect3D8 From b54411774effbc364bf15498e77ca20b6426667f Mon Sep 17 00:00:00 2001 From: PatrickvL Date: Thu, 24 May 2018 14:15:49 +0200 Subject: [PATCH 02/10] D3D : More Direct3D 9 porting of vertex element conversion code (using more sensible types and code) --- src/CxbxKrnl/EmuD3D8.cpp | 10 +- src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp | 201 ++++++++++++++++---------- src/CxbxKrnl/EmuD3D8/VertexShader.cpp | 154 +++++++++++++------- src/CxbxKrnl/EmuD3D8/VertexShader.h | 2 +- 4 files changed, 235 insertions(+), 132 deletions(-) diff --git a/src/CxbxKrnl/EmuD3D8.cpp b/src/CxbxKrnl/EmuD3D8.cpp index dd160471b..49f9bd123 100644 --- a/src/CxbxKrnl/EmuD3D8.cpp +++ b/src/CxbxKrnl/EmuD3D8.cpp @@ -8087,7 +8087,7 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderTarget) DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetRenderTarget"); if (FAILED(hRet)) { // If Direct3D 9 SetRenderTarget failed, skip setting depth stencil - return hRet; + return; } } @@ -9497,10 +9497,18 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetPixelShaderConstant_4) if(g_BuildVersion <= 4361) Register += 96; +#ifdef CXBX_USE_D3D9 + HRESULT hRet = g_pD3DDevice->SetPixelShaderConstantF +#else HRESULT hRet = g_pD3DDevice->SetPixelShaderConstant +#endif ( Register, +#ifdef CXBX_USE_D3D9 + (float*)pConstantData, +#else pConstantData, +#endif ConstantCount ); //DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetPixelShaderConstant"); diff --git a/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp b/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp index 776298d11..89fbc2b4d 100755 --- a/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp +++ b/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp @@ -392,127 +392,168 @@ void XTL::CxbxVertexBufferConverter::ConvertStream // assert(bNeedStreamCopy || "bNeedVertexPatching implies bNeedStreamCopy (but copies via conversions"); for (uint32 uiVertex = 0; uiVertex < uiVertexCount; uiVertex++) { uint08 *pXboxVertex = &pXboxVertexData[uiVertex * uiXboxVertexStride]; - FLOAT *pHostVertexAsFloat = (FLOAT*)(&pHostVertexData[uiVertex * uiHostVertexStride]); + uint08 *pHostVertex = &pHostVertexData[uiVertex * uiHostVertexStride]; for (UINT uiElement = 0; uiElement < pVertexShaderStreamInfo->NumberOfVertexElements; uiElement++) { + FLOAT *pXboxVertexAsFloat = (FLOAT*)pXboxVertex; + SHORT *pXboxVertexAsShort = (SHORT*)pXboxVertex; + BYTE *pXboxVertexAsByte = (BYTE*)pXboxVertex; + int XboxElementSizeInBytes = pVertexShaderStreamInfo->VertexElements[uiElement].HostByteSize; + FLOAT *pHostVertexAsFloat = (FLOAT*)pHostVertex; + SHORT *pHostVertexAsShort = (SHORT*)pHostVertex; +#if CXBX_USE_D3D9 + BYTE *pHostVertexAsByte = (BYTE*)pHostVertex; +#endif // Dxbx note : The following code handles only the D3DVSDT enums that need conversion; // All other cases are catched by the memcpy in the default-block. switch (pVertexShaderStreamInfo->VertexElements[uiElement].XboxType) { + case X_D3DVSDT_NORMSHORT1: { // 0x11: + // Test-cases : Halo - Combat Evolved + XboxElementSizeInBytes = 1 * sizeof(SHORT); +#if CXBX_USE_D3D9 // Make it SHORT2N + pHostVertexAsShort[0] = pXboxVertexAsShort[0]; + pHostVertexAsShort[1] = 0; +#else // Make it FLOAT1 + pHostVertexAsFloat[0] = ((FLOAT)pXboxVertexAsShort[0]) / 32767.0f; + //pHostVertexAsFloat[1] = 0.0f; // Would be needed for FLOAT2 +#endif + break; + } +#if !CXBX_USE_D3D9 // No need for patching in D3D9 + case X_D3DVSDT_NORMSHORT2: { // 0x21: // Make it FLOAT2 + // Test-cases : Baldur's Gate: Dark Alliance 2, F1 2002, Gun, Halo - Combat Evolved, Scrapland + XboxElementSizeInBytes = 2 * sizeof(SHORT); + pHostVertexAsFloat[0] = ((FLOAT)pXboxVertexAsShort[0]) / 32767.0f; + pHostVertexAsFloat[1] = ((FLOAT)pXboxVertexAsShort[1]) / 32767.0f; + break; + } +#endif + case X_D3DVSDT_NORMSHORT3: { // 0x31: + // Test-cases : Cel Damage, Constantine, Destroy All Humans! + XboxElementSizeInBytes = 3 * sizeof(SHORT); +#if CXBX_USE_D3D9 // Make it SHORT4N + pHostVertexAsShort[0] = pXboxVertexAsShort[0]; + pHostVertexAsShort[1] = pXboxVertexAsShort[1]; + pHostVertexAsShort[2] = pXboxVertexAsShort[2]; + pHostVertexAsShort[3] = 32767; // TODO : verify +#else // Make it FLOAT3 + pHostVertexAsFloat[0] = ((FLOAT)pXboxVertexAsShort[0]) / 32767.0f; + pHostVertexAsFloat[1] = ((FLOAT)pXboxVertexAsShort[1]) / 32767.0f; + pHostVertexAsFloat[2] = ((FLOAT)pXboxVertexAsShort[2]) / 32767.0f; +#endif + break; + } +#if !CXBX_USE_D3D9 // No need for patching in D3D9 + case X_D3DVSDT_NORMSHORT4: { // 0x41: // Make it FLOAT4 + // Test-cases : Judge Dredd: Dredd vs Death, NHL Hitz 2002, Silent Hill 2, Sneakers, Tony Hawk Pro Skater 4 + XboxElementSizeInBytes = 4 * sizeof(SHORT); + pHostVertexAsFloat[0] = ((FLOAT)pXboxVertexAsShort[0]) / 32767.0f; + pHostVertexAsFloat[1] = ((FLOAT)pXboxVertexAsShort[1]) / 32767.0f; + pHostVertexAsFloat[2] = ((FLOAT)pXboxVertexAsShort[2]) / 32767.0f; + pHostVertexAsFloat[3] = ((FLOAT)pXboxVertexAsShort[3]) / 32767.0f; + break; + } +#endif case X_D3DVSDT_NORMPACKED3: { // 0x16: // Make it FLOAT3 - // Hit by Dashboard + // Test-cases : Dashboard + XboxElementSizeInBytes = 1 * sizeof(int32); int32 iPacked = ((int32 *)pXboxVertex)[0]; // Cxbx note : to make each component signed, two need to be shifted towards the sign-bit first : pHostVertexAsFloat[0] = ((FLOAT)((iPacked << 21) >> 21)) / 1023.0f; pHostVertexAsFloat[1] = ((FLOAT)((iPacked << 10) >> 21)) / 1023.0f; pHostVertexAsFloat[2] = ((FLOAT)((iPacked ) >> 22)) / 511.0f; - pXboxVertex += 1 * sizeof(int32); break; } case X_D3DVSDT_SHORT1: { // 0x15: // Make it SHORT2 and set the second short to 0 - //memcpy(pHostVertexAsFloat, pXboxVertex, pVertexShaderStreamInfo->VertexElements[uiElement].HostByteSize); - ((SHORT *)pHostVertexAsFloat)[0] = ((SHORT*)pXboxVertex)[0]; - ((SHORT *)pHostVertexAsFloat)[1] = 0x00; - pXboxVertex += 1 * sizeof(SHORT); + XboxElementSizeInBytes = 1 * sizeof(SHORT); + //memcpy(pHostVertexAsFloat, pXboxVertex, XboxElementSizeInBytes); + pHostVertexAsShort[0] = pXboxVertexAsShort[0]; + pHostVertexAsShort[1] = 0x00; break; } case X_D3DVSDT_SHORT3: { // 0x35: // Make it a SHORT4 and set the fourth short to 1 - // Hit by Turok - //memcpy(pHostVertexAsFloat, pXboxVertex, pVertexShaderStreamInfo->VertexElements[uiElement].HostByteSize); - ((SHORT *)pHostVertexAsFloat)[0] = ((SHORT*)pXboxVertex)[0]; - ((SHORT *)pHostVertexAsFloat)[1] = ((SHORT*)pXboxVertex)[1]; - ((SHORT *)pHostVertexAsFloat)[2] = ((SHORT*)pXboxVertex)[2]; - ((SHORT *)pHostVertexAsFloat)[3] = 0x01; // Turok verified (character disappears when this is 32767) - pXboxVertex += 3 * sizeof(SHORT); + // Test-cases : Turok + XboxElementSizeInBytes = 3 * sizeof(SHORT); + //memcpy(pHostVertexAsFloat, pXboxVertex, XboxElementSizeInBytes); + pHostVertexAsShort[0] = pXboxVertexAsShort[0]; + pHostVertexAsShort[1] = pXboxVertexAsShort[1]; + pHostVertexAsShort[2] = pXboxVertexAsShort[2]; + pHostVertexAsShort[3] = 0x01; // Turok verified (character disappears when this is 32767) break; } - case X_D3DVSDT_PBYTE1: { // 0x14: // Make it FLOAT1 - pHostVertexAsFloat[0] = ((FLOAT)((BYTE*)pXboxVertex)[0]) / 255.0f; - pXboxVertex += 1 * sizeof(BYTE); + case X_D3DVSDT_PBYTE1: { // 0x14: + XboxElementSizeInBytes = 1 * sizeof(BYTE); +#if CXBX_USE_D3D9 // Make it UBYTE4N + pHostVertexAsByte[0] = pXboxVertexAsByte[0]; + pHostVertexAsByte[1] = 0; + pHostVertexAsByte[2] = 0; + pHostVertexAsByte[3] = 255; // TODO : Verify +#else // Make it FLOAT1 + pHostVertexAsFloat[0] = ((FLOAT)pXboxVertexAsByte[0]) / 255.0f; +#endif break; } - case X_D3DVSDT_PBYTE2: { // 0x24: // Make it FLOAT2 - pHostVertexAsFloat[0] = ((FLOAT)((BYTE*)pXboxVertex)[0]) / 255.0f; - pHostVertexAsFloat[1] = ((FLOAT)((BYTE*)pXboxVertex)[1]) / 255.0f; - pXboxVertex += 2 * sizeof(BYTE); + case X_D3DVSDT_PBYTE2: { // 0x24: + XboxElementSizeInBytes = 2 * sizeof(BYTE); +#if CXBX_USE_D3D9 // Make it UBYTE4N + pHostVertexAsByte[0] = pXboxVertexAsByte[0]; + pHostVertexAsByte[1] = pXboxVertexAsByte[1]; + pHostVertexAsByte[2] = 0; + pHostVertexAsByte[3] = 255; // TODO : Verify +#else // Make it FLOAT2 + pHostVertexAsFloat[0] = ((FLOAT)pXboxVertexAsByte[0]) / 255.0f; + pHostVertexAsFloat[1] = ((FLOAT)pXboxVertexAsByte[1]) / 255.0f; +#endif break; } - case X_D3DVSDT_PBYTE3: { // 0x34: // Make it FLOAT3 - // Hit by Turok - pHostVertexAsFloat[0] = ((FLOAT)((BYTE*)pXboxVertex)[0]) / 255.0f; - pHostVertexAsFloat[1] = ((FLOAT)((BYTE*)pXboxVertex)[1]) / 255.0f; - pHostVertexAsFloat[2] = ((FLOAT)((BYTE*)pXboxVertex)[2]) / 255.0f; - pXboxVertex += 3 * sizeof(BYTE); + case X_D3DVSDT_PBYTE3: { // 0x34: + // Test-cases : Turok + XboxElementSizeInBytes = 3 * sizeof(BYTE); +#if CXBX_USE_D3D9 // Make it UBYTE4N + pHostVertexAsByte[0] = pXboxVertexAsByte[0]; + pHostVertexAsByte[1] = pXboxVertexAsByte[1]; + pHostVertexAsByte[2] = pXboxVertexAsByte[2]; + pHostVertexAsByte[3] = 255; // TODO : Verify +#else // Make it FLOAT3 + pHostVertexAsFloat[0] = ((FLOAT)pXboxVertexAsByte[0]) / 255.0f; + pHostVertexAsFloat[1] = ((FLOAT)pXboxVertexAsByte[1]) / 255.0f; + pHostVertexAsFloat[2] = ((FLOAT)pXboxVertexAsByte[2]) / 255.0f; +#endif break; } +#if !CXBX_USE_D3D9 // No need for patching in D3D9 case X_D3DVSDT_PBYTE4: { // 0x44: // Make it FLOAT4 // Hit by Jet Set Radio Future - pHostVertexAsFloat[0] = ((FLOAT)((BYTE*)pXboxVertex)[0]) / 255.0f; - pHostVertexAsFloat[1] = ((FLOAT)((BYTE*)pXboxVertex)[1]) / 255.0f; - pHostVertexAsFloat[2] = ((FLOAT)((BYTE*)pXboxVertex)[2]) / 255.0f; - pHostVertexAsFloat[3] = ((FLOAT)((BYTE*)pXboxVertex)[3]) / 255.0f; - pXboxVertex += 4 * sizeof(BYTE); - break; - } - case X_D3DVSDT_NORMSHORT1: { // 0x11: // Make it FLOAT1 - // Test-cases : Halo - Combat Evolved - - pHostVertexAsFloat[0] = ((FLOAT)((SHORT*)pXboxVertex)[0]) / 32767.0f; - //pHostVertexAsFloat[1] = 0.0f; // Would be needed for FLOAT2 - pXboxVertex += 1 * sizeof(SHORT); - break; - } -#if !DXBX_USE_D3D9 // No need for patching in D3D9 - case X_D3DVSDT_NORMSHORT2: { // 0x21: // Make it FLOAT2 - // Test-cases : Baldur's Gate: Dark Alliance 2, F1 2002, Gun, Halo - Combat Evolved, Scrapland - pHostVertexAsFloat[0] = ((FLOAT)((SHORT*)pXboxVertex)[0]) / 32767.0f; - pHostVertexAsFloat[1] = ((FLOAT)((SHORT*)pXboxVertex)[1]) / 32767.0f; - pXboxVertex += 2 * sizeof(SHORT); - break; - } -#endif - case X_D3DVSDT_NORMSHORT3: { // 0x31: // Make it FLOAT3 - // Test-cases : Cel Damage, Constantine, Destroy All Humans! - pHostVertexAsFloat[0] = ((FLOAT)((SHORT*)pXboxVertex)[0]) / 32767.0f; - pHostVertexAsFloat[1] = ((FLOAT)((SHORT*)pXboxVertex)[1]) / 32767.0f; - pHostVertexAsFloat[2] = ((FLOAT)((SHORT*)pXboxVertex)[2]) / 32767.0f; - pXboxVertex += 3 * sizeof(SHORT); - break; - } -#if !DXBX_USE_D3D9 // No need for patching in D3D9 - case X_D3DVSDT_NORMSHORT4: { // 0x41: // Make it FLOAT4 - LOG_TEST_CASE("X_D3DVSDT_NORMSHORT4"); // UNTESTED - Need test-case! - pHostVertexAsFloat[0] = ((FLOAT)((SHORT*)pXboxVertex)[0]) / 32767.0f; - pHostVertexAsFloat[1] = ((FLOAT)((SHORT*)pXboxVertex)[1]) / 32767.0f; - pHostVertexAsFloat[2] = ((FLOAT)((SHORT*)pXboxVertex)[2]) / 32767.0f; - pHostVertexAsFloat[3] = ((FLOAT)((SHORT*)pXboxVertex)[3]) / 32767.0f; - pXboxVertex += 4 * sizeof(SHORT); + XboxElementSizeInBytes = 4 * sizeof(BYTE); + pHostVertexAsFloat[0] = ((FLOAT)pXboxVertexAsByte[0]) / 255.0f; + pHostVertexAsFloat[1] = ((FLOAT)pXboxVertexAsByte[1]) / 255.0f; + pHostVertexAsFloat[2] = ((FLOAT)pXboxVertexAsByte[2]) / 255.0f; + pHostVertexAsFloat[3] = ((FLOAT)pXboxVertexAsByte[3]) / 255.0f; break; } #endif case X_D3DVSDT_FLOAT2H: { // 0x72: // Make it FLOAT4 and set the third float to 0.0 - pHostVertexAsFloat[0] = ((FLOAT*)pXboxVertex)[0]; - pHostVertexAsFloat[1] = ((FLOAT*)pXboxVertex)[1]; + XboxElementSizeInBytes = 3 * sizeof(FLOAT); + pHostVertexAsFloat[0] = pXboxVertexAsFloat[0]; + pHostVertexAsFloat[1] = pXboxVertexAsFloat[1]; pHostVertexAsFloat[2] = 0.0f; - pHostVertexAsFloat[3] = ((FLOAT*)pXboxVertex)[2]; - pXboxVertex += 3 * sizeof(FLOAT); + pHostVertexAsFloat[3] = pXboxVertexAsFloat[2]; break; } - /*TODO - case X_D3DVSDT_NONE: { // 0x02: - printf("D3DVSDT_NONE / xbox ext. nsp /"); - dwNewDataType = 0xFF; + case X_D3DVSDT_NONE: { // 0x02: // Skip it + LOG_TEST_CASE("X_D3DVSDT_NONE"); break; } - */ default: { // Generic 'conversion' - just make a copy : - memcpy(pHostVertexAsFloat, pXboxVertex, pVertexShaderStreamInfo->VertexElements[uiElement].HostByteSize); - pXboxVertex += pVertexShaderStreamInfo->VertexElements[uiElement].HostByteSize; + memcpy(pHostVertex, pXboxVertex, XboxElementSizeInBytes); break; } } // switch - // Increment the new pointer : - pHostVertexAsFloat = (FLOAT*)((uintptr_t)pHostVertexAsFloat + pVertexShaderStreamInfo->VertexElements[uiElement].HostByteSize); + // Increment the Xbox pointer : + pXboxVertex += XboxElementSizeInBytes; + // Increment the host pointer : + pHostVertex += pVertexShaderStreamInfo->VertexElements[uiElement].HostByteSize; } // for NumberOfVertexElements } // for uiVertexCount } diff --git a/src/CxbxKrnl/EmuD3D8/VertexShader.cpp b/src/CxbxKrnl/EmuD3D8/VertexShader.cpp index 68d70b0bb..1cf02555e 100644 --- a/src/CxbxKrnl/EmuD3D8/VertexShader.cpp +++ b/src/CxbxKrnl/EmuD3D8/VertexShader.cpp @@ -1800,7 +1800,7 @@ static inline DWORD VshGetVertexStream(DWORD Token) static void VshConvertToken_NOP( DWORD *pToken, - D3DVERTEXELEMENT *pRecompiled + XTL::D3DVERTEXELEMENT *pRecompiled ) { // D3DVSD_NOP @@ -1813,7 +1813,7 @@ static void VshConvertToken_NOP( static DWORD VshConvertToken_CONSTMEM( DWORD *pToken, - D3DVERTEXELEMENT *pRecompiled + XTL::D3DVERTEXELEMENT *pRecompiled ) { // D3DVSD_CONST @@ -1835,7 +1835,7 @@ static DWORD VshConvertToken_CONSTMEM( static void VshConvertToken_TESSELATOR( DWORD *pToken, - D3DVERTEXELEMENT *pRecompiled, + XTL::D3DVERTEXELEMENT *pRecompiled, boolean IsFixedFunction ) { @@ -1899,7 +1899,7 @@ static void VshEndPreviousStreamPatch(CxbxVertexShaderPatch *pPatchData) static void VshConvertToken_STREAM( DWORD *pToken, - D3DVERTEXELEMENT *pRecompiled, + XTL::D3DVERTEXELEMENT *pRecompiled, CxbxVertexShaderPatch *pPatchData ) { @@ -1932,7 +1932,7 @@ static void VshConvertToken_STREAM( static void VshConvertToken_STREAMDATA_SKIP( DWORD *pToken, - D3DVERTEXELEMENT *pRecompiled + XTL::D3DVERTEXELEMENT *pRecompiled ) { using namespace XTL; @@ -1944,7 +1944,7 @@ static void VshConvertToken_STREAMDATA_SKIP( static void VshConvertToken_STREAMDATA_SKIPBYTES( DWORD *pToken, - D3DVERTEXELEMENT *pRecompiled + XTL::D3DVERTEXELEMENT *pRecompiled ) { using namespace XTL; @@ -1960,13 +1960,24 @@ static void VshConvertToken_STREAMDATA_SKIPBYTES( static void VshConvertToken_STREAMDATA_REG( DWORD *pToken, - D3DVERTEXELEMENT *pRecompiled, + XTL::D3DVERTEXELEMENT *pRecompiled, boolean IsFixedFunction, CxbxVertexShaderPatch *pPatchData ) { using namespace XTL; +#if !CXBX_USE_D3D9 // For simpler support for both Direct3D 8 and 9, use these '9' constants in below '8' code paths too: +#define D3DDECLTYPE_FLOAT1 D3DVSDT_FLOAT1 +#define D3DDECLTYPE_FLOAT2 D3DVSDT_FLOAT2 +#define D3DDECLTYPE_FLOAT3 D3DVSDT_FLOAT3 +#define D3DDECLTYPE_FLOAT4 D3DVSDT_FLOAT4 +#define D3DDECLTYPE_D3DCOLOR D3DVSDT_D3DCOLOR +#define D3DDECLTYPE_SHORT2 D3DVSDT_SHORT2 +#define D3DDECLTYPE_SHORT4 D3DVSDT_SHORT4 +#define D3DDECLTYPE_UNUSED 0xFF +#endif + XTL::DWORD VertexRegister = VshGetVertexRegister(*pToken); XTL::DWORD HostVertexRegister; XTL::BOOL NeedPatching = FALSE; @@ -1983,118 +1994,161 @@ static void VshConvertToken_STREAMDATA_REG( { case X_D3DVSDT_FLOAT1: // 0x12: DbgVshPrintf("D3DVSDT_FLOAT1"); - HostVertexElementDataType = D3DVSDT_FLOAT1; + HostVertexElementDataType = D3DDECLTYPE_FLOAT1; HostVertexElementByteSize = 1*sizeof(FLOAT); break; case X_D3DVSDT_FLOAT2: // 0x22: DbgVshPrintf("D3DVSDT_FLOAT2"); - HostVertexElementDataType = D3DVSDT_FLOAT2; + HostVertexElementDataType = D3DDECLTYPE_FLOAT2; HostVertexElementByteSize = 2*sizeof(FLOAT); break; case X_D3DVSDT_FLOAT3: // 0x32: DbgVshPrintf("D3DVSDT_FLOAT3"); - HostVertexElementDataType = D3DVSDT_FLOAT3; + HostVertexElementDataType = D3DDECLTYPE_FLOAT3; HostVertexElementByteSize = 3*sizeof(FLOAT); break; case X_D3DVSDT_FLOAT4: // 0x42: DbgVshPrintf("D3DVSDT_FLOAT4"); - HostVertexElementDataType = D3DVSDT_FLOAT4; + HostVertexElementDataType = D3DDECLTYPE_FLOAT4; HostVertexElementByteSize = 4*sizeof(FLOAT); break; case X_D3DVSDT_D3DCOLOR: // 0x40: DbgVshPrintf("D3DVSDT_D3DCOLOR"); - HostVertexElementDataType = D3DVSDT_D3DCOLOR; - HostVertexElementByteSize = sizeof(D3DCOLOR); + HostVertexElementDataType = D3DDECLTYPE_D3DCOLOR; + HostVertexElementByteSize = 1*sizeof(D3DCOLOR); break; case X_D3DVSDT_SHORT2: // 0x25: DbgVshPrintf("D3DVSDT_SHORT2"); - HostVertexElementDataType = D3DVSDT_SHORT2; + HostVertexElementDataType = D3DDECLTYPE_SHORT2; HostVertexElementByteSize = 2*sizeof(XTL::SHORT); break; case X_D3DVSDT_SHORT4: // 0x45: DbgVshPrintf("D3DVSDT_SHORT4"); - HostVertexElementDataType = D3DVSDT_SHORT4; + HostVertexElementDataType = D3DDECLTYPE_SHORT4; HostVertexElementByteSize = 4*sizeof(XTL::SHORT); break; case X_D3DVSDT_NORMSHORT1: // 0x11: DbgVshPrintf("D3DVSDT_NORMSHORT1 /* xbox ext. */"); - HostVertexElementDataType = D3DVSDT_FLOAT1; // TODO -oDxbx : Is it better to use D3DVSDT_NORMSHORT2 in Direct3D9 ? - HostVertexElementByteSize = sizeof(FLOAT); +#if CXBX_USE_D3D9 + HostVertexElementDataType = D3DDECLTYPE_SHORT2N; + HostVertexElementByteSize = 2*sizeof(SHORT); +#else + HostVertexElementDataType = D3DDECLTYPE_FLOAT1; + HostVertexElementByteSize = 1*sizeof(FLOAT); +#endif NeedPatching = TRUE; break; case X_D3DVSDT_NORMSHORT2: // 0x21: - DbgVshPrintf("D3DVSDT_NORMSHORT2 /* xbox ext. */"); - HostVertexElementDataType = D3DVSDT_FLOAT2; +#if CXBX_USE_D3D9 + DbgVshPrintf("D3DVSDT_NORMSHORT2"); + HostVertexElementDataType = D3DDECLTYPE_SHORT2N; + HostVertexElementByteSize = 2*sizeof(SHORT); + // No need for patching in D3D9 +#else + DbgVshPrintf("D3DVSDT_NORMSHORT2 /* xbox ext. */"); + HostVertexElementDataType = D3DDECLTYPE_FLOAT2; HostVertexElementByteSize = 2*sizeof(FLOAT); NeedPatching = TRUE; - break; +#endif + break; case X_D3DVSDT_NORMSHORT3: // 0x31: - DbgVshPrintf("D3DVSDT_NORMSHORT3 /* xbox ext. nsp */"); - HostVertexElementDataType = D3DVSDT_FLOAT3; // TODO -oDxbx : Is it better to use D3DVSDT_NORMSHORT4 in Direct3D9 ? + DbgVshPrintf("D3DVSDT_NORMSHORT3 /* xbox ext. */"); +#if CXBX_USE_D3D9 + HostVertexElementDataType = D3DDECLTYPE_SHORT4N; + HostVertexElementByteSize = 4*sizeof(SHORT); +#else + HostVertexElementDataType = D3DDECLTYPE_FLOAT3; HostVertexElementByteSize = 3*sizeof(FLOAT); +#endif NeedPatching = TRUE; break; case X_D3DVSDT_NORMSHORT4: // 0x41: - DbgVshPrintf("D3DVSDT_NORMSHORT4 /* xbox ext. */"); - HostVertexElementDataType = D3DVSDT_FLOAT4; +#if CXBX_USE_D3D9 + DbgVshPrintf("D3DVSDT_NORMSHORT4"); + HostVertexElementDataType = D3DDECLTYPE_SHORT4N; + HostVertexElementByteSize = 4*sizeof(SHORT); + // No need for patching in D3D9 +#else + DbgVshPrintf("D3DVSDT_NORMSHORT4 /* xbox ext. */"); + HostVertexElementDataType = D3DDECLTYPE_FLOAT4; HostVertexElementByteSize = 4*sizeof(FLOAT); NeedPatching = TRUE; +#endif break; case X_D3DVSDT_NORMPACKED3: // 0x16: - DbgVshPrintf("D3DVSDT_NORMPACKED3 /* xbox ext. nsp */"); - HostVertexElementDataType = D3DVSDT_FLOAT3; + DbgVshPrintf("D3DVSDT_NORMPACKED3 /* xbox ext. */"); + HostVertexElementDataType = D3DDECLTYPE_FLOAT3; HostVertexElementByteSize = 3*sizeof(FLOAT); NeedPatching = TRUE; break; case X_D3DVSDT_SHORT1: // 0x15: - DbgVshPrintf("D3DVSDT_SHORT1 /* xbox ext. nsp */"); - HostVertexElementDataType = D3DVSDT_SHORT2; + DbgVshPrintf("D3DVSDT_SHORT1 /* xbox ext. */"); + HostVertexElementDataType = D3DDECLTYPE_SHORT2; HostVertexElementByteSize = 2*sizeof(XTL::SHORT); NeedPatching = TRUE; break; case X_D3DVSDT_SHORT3: // 0x35: - DbgVshPrintf("D3DVSDT_SHORT3 /* xbox ext. nsp */"); - HostVertexElementDataType = D3DVSDT_SHORT4; + DbgVshPrintf("D3DVSDT_SHORT3 /* xbox ext. */"); + HostVertexElementDataType = D3DDECLTYPE_SHORT4; HostVertexElementByteSize = 4*sizeof(XTL::SHORT); NeedPatching = TRUE; break; case X_D3DVSDT_PBYTE1: // 0x14: - DbgVshPrintf("D3DVSDT_PBYTE1 /* xbox ext. nsp */"); - HostVertexElementDataType = D3DVSDT_FLOAT1; // TODO -oDxbx : Is it better to use D3DVSDT_NORMSHORT2 in Direct3D9 ? + DbgVshPrintf("D3DVSDT_PBYTE1 /* xbox ext. */"); +#if CXBX_USE_D3D9 + HostVertexElementDataType = D3DDECLTYPE_UBYTE4N; + HostVertexElementByteSize = 4*sizeof(BYTE); +#else + HostVertexElementDataType = D3DDECLTYPE_FLOAT1; HostVertexElementByteSize = 1*sizeof(FLOAT); - NeedPatching = TRUE; +#endif + NeedPatching = TRUE; break; case X_D3DVSDT_PBYTE2: // 0x24: - DbgVshPrintf("D3DVSDT_PBYTE2 /* xbox ext. nsp */"); - HostVertexElementDataType = D3DVSDT_FLOAT2; // TODO -oDxbx : Is it better to use D3DVSDT_NORMSHORT2 in Direct3D9 ? + DbgVshPrintf("D3DVSDT_PBYTE2 /* xbox ext. */"); +#if CXBX_USE_D3D9 + HostVertexElementDataType = D3DDECLTYPE_UBYTE4N; + HostVertexElementByteSize = 4*sizeof(BYTE); +#else + HostVertexElementDataType = D3DDECLTYPE_FLOAT2; HostVertexElementByteSize = 2*sizeof(FLOAT); +#endif NeedPatching = TRUE; break; case X_D3DVSDT_PBYTE3: // 0x34: - DbgVshPrintf("D3DVSDT_PBYTE3 /* xbox ext. nsp */"); - HostVertexElementDataType = D3DVSDT_FLOAT3; // TODO -oDxbx : Is it better to use D3DVSDT_NORMSHORT4 in Direct3D9 ? + DbgVshPrintf("D3DVSDT_PBYTE3 /* xbox ext. */"); +#if CXBX_USE_D3D9 + HostVertexElementDataType = D3DDECLTYPE_UBYTE4N; + HostVertexElementByteSize = 4*sizeof(BYTE); +#else + HostVertexElementDataType = D3DDECLTYPE_FLOAT3; HostVertexElementByteSize = 3*sizeof(FLOAT); +#endif NeedPatching = TRUE; break; case X_D3DVSDT_PBYTE4: // 0x44: // Hit by Panzer +#if CXBX_USE_D3D9 + DbgVshPrintf("D3DVSDT_PBYTE4"); + HostVertexElementDataType = D3DDECLTYPE_UBYTE4N; + HostVertexElementByteSize = 4*sizeof(BYTE); + // No need for patching in D3D9 +#else DbgVshPrintf("D3DVSDT_PBYTE4 /* xbox ext. */"); - HostVertexElementDataType = D3DVSDT_FLOAT4; // TODO -oDxbx : Is it better to use D3DVSDT_NORMSHORT4 or D3DDECLTYPE_UBYTE4N (if in caps) in Direct3D9 ? + HostVertexElementDataType = D3DDECLTYPE_FLOAT4; HostVertexElementByteSize = 4*sizeof(FLOAT); NeedPatching = TRUE; +#endif break; case X_D3DVSDT_FLOAT2H: // 0x72: DbgVshPrintf("D3DVSDT_FLOAT2H /* xbox ext. */"); - HostVertexElementDataType = D3DVSDT_FLOAT4; + HostVertexElementDataType = D3DDECLTYPE_FLOAT4; HostVertexElementByteSize = 4*sizeof(FLOAT); NeedPatching = TRUE; break; case X_D3DVSDT_NONE: // 0x02: - DbgVshPrintf("D3DVSDT_NONE /* xbox ext. nsp */"); -#if CXBX_USE_D3D9 - HostVertexElementDataType = D3DVSDT_NONE; -#endif - // TODO -oDxbx: Use D3DVSD_NOP ? - HostVertexElementDataType = 0xFF; + DbgVshPrintf("D3DVSDT_NONE /* xbox ext. */"); + HostVertexElementDataType = D3DDECLTYPE_UNUSED; + NeedPatching = TRUE; break; default: DbgVshPrintf("Unknown data type for D3DVSD_REG: 0x%02X\n", XboxVertexElementDataType); @@ -2114,7 +2168,7 @@ static void VshConvertToken_STREAMDATA_REG( DbgVshPrintf("),\n"); - if(HostVertexElementDataType == 0xFF) + if(HostVertexElementDataType == D3DDECLTYPE_UNUSED) { EmuWarning("/* WARNING: Fatal type mismatch, no fitting type! */"); } @@ -2122,7 +2176,7 @@ static void VshConvertToken_STREAMDATA_REG( static void VshConvertToken_STREAMDATA( DWORD *pToken, - D3DVERTEXELEMENT *pRecompiled, + XTL::D3DVERTEXELEMENT *pRecompiled, boolean IsFixedFunction, CxbxVertexShaderPatch *pPatchData ) @@ -2145,7 +2199,7 @@ static void VshConvertToken_STREAMDATA( static DWORD VshRecompileToken( DWORD *pToken, - D3DVERTEXELEMENT *&pRecompiled, + XTL::D3DVERTEXELEMENT *&pRecompiled, boolean IsFixedFunction, CxbxVertexShaderPatch *pPatchData ) @@ -2190,7 +2244,7 @@ static DWORD VshRecompileToken( DWORD XTL::EmuRecompileVshDeclaration ( DWORD *pDeclaration, - D3DVERTEXELEMENT **ppRecompiledDeclaration, + D3DVERTEXELEMENT **ppRecompiledDeclaration, DWORD *pDeclarationSize, boolean IsFixedFunction, CxbxVertexShaderInfo *pVertexShaderInfo @@ -2442,4 +2496,4 @@ XTL::CxbxVertexShaderInfo *GetCxbxVertexShaderInfo(DWORD Handle) } } return NULL; -} \ No newline at end of file +} diff --git a/src/CxbxKrnl/EmuD3D8/VertexShader.h b/src/CxbxKrnl/EmuD3D8/VertexShader.h index d683df7f2..fff149950 100644 --- a/src/CxbxKrnl/EmuD3D8/VertexShader.h +++ b/src/CxbxKrnl/EmuD3D8/VertexShader.h @@ -53,7 +53,7 @@ VSH_SHADER_HEADER; extern DWORD EmuRecompileVshDeclaration ( DWORD *pDeclaration, - DWORD **ppRecompiledDeclaration, + D3DVERTEXELEMENT **ppRecompiledDeclaration, DWORD *pDeclarationSize, boolean IsFixedFunction, XTL::CxbxVertexShaderInfo *pVertexShaderInfo From 726c1ed77e04b2022ab4ac917cc7a42fa3a7f473 Mon Sep 17 00:00:00 2001 From: PatrickvL Date: Thu, 24 May 2018 14:30:23 +0200 Subject: [PATCH 03/10] D3D9 : Small rename --- src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp | 34 +++++++++++++-------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp b/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp index 89fbc2b4d..dd7a2f598 100755 --- a/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp +++ b/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp @@ -397,7 +397,7 @@ void XTL::CxbxVertexBufferConverter::ConvertStream FLOAT *pXboxVertexAsFloat = (FLOAT*)pXboxVertex; SHORT *pXboxVertexAsShort = (SHORT*)pXboxVertex; BYTE *pXboxVertexAsByte = (BYTE*)pXboxVertex; - int XboxElementSizeInBytes = pVertexShaderStreamInfo->VertexElements[uiElement].HostByteSize; + int XboxElementByteSize = pVertexShaderStreamInfo->VertexElements[uiElement].HostByteSize; FLOAT *pHostVertexAsFloat = (FLOAT*)pHostVertex; SHORT *pHostVertexAsShort = (SHORT*)pHostVertex; #if CXBX_USE_D3D9 @@ -408,7 +408,7 @@ void XTL::CxbxVertexBufferConverter::ConvertStream switch (pVertexShaderStreamInfo->VertexElements[uiElement].XboxType) { case X_D3DVSDT_NORMSHORT1: { // 0x11: // Test-cases : Halo - Combat Evolved - XboxElementSizeInBytes = 1 * sizeof(SHORT); + XboxElementByteSize = 1 * sizeof(SHORT); #if CXBX_USE_D3D9 // Make it SHORT2N pHostVertexAsShort[0] = pXboxVertexAsShort[0]; pHostVertexAsShort[1] = 0; @@ -421,7 +421,7 @@ void XTL::CxbxVertexBufferConverter::ConvertStream #if !CXBX_USE_D3D9 // No need for patching in D3D9 case X_D3DVSDT_NORMSHORT2: { // 0x21: // Make it FLOAT2 // Test-cases : Baldur's Gate: Dark Alliance 2, F1 2002, Gun, Halo - Combat Evolved, Scrapland - XboxElementSizeInBytes = 2 * sizeof(SHORT); + XboxElementByteSize = 2 * sizeof(SHORT); pHostVertexAsFloat[0] = ((FLOAT)pXboxVertexAsShort[0]) / 32767.0f; pHostVertexAsFloat[1] = ((FLOAT)pXboxVertexAsShort[1]) / 32767.0f; break; @@ -429,7 +429,7 @@ void XTL::CxbxVertexBufferConverter::ConvertStream #endif case X_D3DVSDT_NORMSHORT3: { // 0x31: // Test-cases : Cel Damage, Constantine, Destroy All Humans! - XboxElementSizeInBytes = 3 * sizeof(SHORT); + XboxElementByteSize = 3 * sizeof(SHORT); #if CXBX_USE_D3D9 // Make it SHORT4N pHostVertexAsShort[0] = pXboxVertexAsShort[0]; pHostVertexAsShort[1] = pXboxVertexAsShort[1]; @@ -445,7 +445,7 @@ void XTL::CxbxVertexBufferConverter::ConvertStream #if !CXBX_USE_D3D9 // No need for patching in D3D9 case X_D3DVSDT_NORMSHORT4: { // 0x41: // Make it FLOAT4 // Test-cases : Judge Dredd: Dredd vs Death, NHL Hitz 2002, Silent Hill 2, Sneakers, Tony Hawk Pro Skater 4 - XboxElementSizeInBytes = 4 * sizeof(SHORT); + XboxElementByteSize = 4 * sizeof(SHORT); pHostVertexAsFloat[0] = ((FLOAT)pXboxVertexAsShort[0]) / 32767.0f; pHostVertexAsFloat[1] = ((FLOAT)pXboxVertexAsShort[1]) / 32767.0f; pHostVertexAsFloat[2] = ((FLOAT)pXboxVertexAsShort[2]) / 32767.0f; @@ -455,7 +455,7 @@ void XTL::CxbxVertexBufferConverter::ConvertStream #endif case X_D3DVSDT_NORMPACKED3: { // 0x16: // Make it FLOAT3 // Test-cases : Dashboard - XboxElementSizeInBytes = 1 * sizeof(int32); + XboxElementByteSize = 1 * sizeof(int32); int32 iPacked = ((int32 *)pXboxVertex)[0]; // Cxbx note : to make each component signed, two need to be shifted towards the sign-bit first : pHostVertexAsFloat[0] = ((FLOAT)((iPacked << 21) >> 21)) / 1023.0f; @@ -464,16 +464,16 @@ void XTL::CxbxVertexBufferConverter::ConvertStream break; } case X_D3DVSDT_SHORT1: { // 0x15: // Make it SHORT2 and set the second short to 0 - XboxElementSizeInBytes = 1 * sizeof(SHORT); - //memcpy(pHostVertexAsFloat, pXboxVertex, XboxElementSizeInBytes); + XboxElementByteSize = 1 * sizeof(SHORT); + //memcpy(pHostVertexAsFloat, pXboxVertex, XboxElementByteSize); pHostVertexAsShort[0] = pXboxVertexAsShort[0]; pHostVertexAsShort[1] = 0x00; break; } case X_D3DVSDT_SHORT3: { // 0x35: // Make it a SHORT4 and set the fourth short to 1 // Test-cases : Turok - XboxElementSizeInBytes = 3 * sizeof(SHORT); - //memcpy(pHostVertexAsFloat, pXboxVertex, XboxElementSizeInBytes); + XboxElementByteSize = 3 * sizeof(SHORT); + //memcpy(pHostVertexAsFloat, pXboxVertex, XboxElementByteSize); pHostVertexAsShort[0] = pXboxVertexAsShort[0]; pHostVertexAsShort[1] = pXboxVertexAsShort[1]; pHostVertexAsShort[2] = pXboxVertexAsShort[2]; @@ -481,7 +481,7 @@ void XTL::CxbxVertexBufferConverter::ConvertStream break; } case X_D3DVSDT_PBYTE1: { // 0x14: - XboxElementSizeInBytes = 1 * sizeof(BYTE); + XboxElementByteSize = 1 * sizeof(BYTE); #if CXBX_USE_D3D9 // Make it UBYTE4N pHostVertexAsByte[0] = pXboxVertexAsByte[0]; pHostVertexAsByte[1] = 0; @@ -493,7 +493,7 @@ void XTL::CxbxVertexBufferConverter::ConvertStream break; } case X_D3DVSDT_PBYTE2: { // 0x24: - XboxElementSizeInBytes = 2 * sizeof(BYTE); + XboxElementByteSize = 2 * sizeof(BYTE); #if CXBX_USE_D3D9 // Make it UBYTE4N pHostVertexAsByte[0] = pXboxVertexAsByte[0]; pHostVertexAsByte[1] = pXboxVertexAsByte[1]; @@ -507,7 +507,7 @@ void XTL::CxbxVertexBufferConverter::ConvertStream } case X_D3DVSDT_PBYTE3: { // 0x34: // Test-cases : Turok - XboxElementSizeInBytes = 3 * sizeof(BYTE); + XboxElementByteSize = 3 * sizeof(BYTE); #if CXBX_USE_D3D9 // Make it UBYTE4N pHostVertexAsByte[0] = pXboxVertexAsByte[0]; pHostVertexAsByte[1] = pXboxVertexAsByte[1]; @@ -523,7 +523,7 @@ void XTL::CxbxVertexBufferConverter::ConvertStream #if !CXBX_USE_D3D9 // No need for patching in D3D9 case X_D3DVSDT_PBYTE4: { // 0x44: // Make it FLOAT4 // Hit by Jet Set Radio Future - XboxElementSizeInBytes = 4 * sizeof(BYTE); + XboxElementByteSize = 4 * sizeof(BYTE); pHostVertexAsFloat[0] = ((FLOAT)pXboxVertexAsByte[0]) / 255.0f; pHostVertexAsFloat[1] = ((FLOAT)pXboxVertexAsByte[1]) / 255.0f; pHostVertexAsFloat[2] = ((FLOAT)pXboxVertexAsByte[2]) / 255.0f; @@ -532,7 +532,7 @@ void XTL::CxbxVertexBufferConverter::ConvertStream } #endif case X_D3DVSDT_FLOAT2H: { // 0x72: // Make it FLOAT4 and set the third float to 0.0 - XboxElementSizeInBytes = 3 * sizeof(FLOAT); + XboxElementByteSize = 3 * sizeof(FLOAT); pHostVertexAsFloat[0] = pXboxVertexAsFloat[0]; pHostVertexAsFloat[1] = pXboxVertexAsFloat[1]; pHostVertexAsFloat[2] = 0.0f; @@ -545,13 +545,13 @@ void XTL::CxbxVertexBufferConverter::ConvertStream } default: { // Generic 'conversion' - just make a copy : - memcpy(pHostVertex, pXboxVertex, XboxElementSizeInBytes); + memcpy(pHostVertex, pXboxVertex, XboxElementByteSize); break; } } // switch // Increment the Xbox pointer : - pXboxVertex += XboxElementSizeInBytes; + pXboxVertex += XboxElementByteSize; // Increment the host pointer : pHostVertex += pVertexShaderStreamInfo->VertexElements[uiElement].HostByteSize; } // for NumberOfVertexElements From 341edd2512871ede00b91dc425edf5bbbcf528c4 Mon Sep 17 00:00:00 2001 From: patrickvl Date: Fri, 25 May 2018 08:38:05 +0200 Subject: [PATCH 04/10] D3D9 : Honour D3DCaps for UBTYE4 support --- src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp | 99 ++++++++------- src/CxbxKrnl/EmuD3D8/VertexShader.cpp | 166 +++++++++++++------------- 2 files changed, 142 insertions(+), 123 deletions(-) diff --git a/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp b/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp index dd7a2f598..bfd1b2a33 100755 --- a/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp +++ b/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp @@ -268,6 +268,16 @@ UINT XTL::CxbxVertexBufferConverter::GetNbrStreams(CxbxDrawContext *pDrawContext return 0; } +inline FLOAT NormShortToFloat(const SHORT value) +{ + return ((FLOAT)value) / 32767.0f; +} + +inline FLOAT ByteToFloat(const BYTE value) +{ + return ((FLOAT)value) / 255.0f; +} + void XTL::CxbxVertexBufferConverter::ConvertStream ( CxbxDrawContext *pDrawContext, @@ -391,18 +401,14 @@ void XTL::CxbxVertexBufferConverter::ConvertStream if (bNeedVertexPatching) { // assert(bNeedStreamCopy || "bNeedVertexPatching implies bNeedStreamCopy (but copies via conversions"); for (uint32 uiVertex = 0; uiVertex < uiVertexCount; uiVertex++) { - uint08 *pXboxVertex = &pXboxVertexData[uiVertex * uiXboxVertexStride]; - uint08 *pHostVertex = &pHostVertexData[uiVertex * uiHostVertexStride]; + uint08 *pXboxVertexAsByte = &pXboxVertexData[uiVertex * uiXboxVertexStride]; + uint08 *pHostVertexAsByte = &pHostVertexData[uiVertex * uiHostVertexStride]; for (UINT uiElement = 0; uiElement < pVertexShaderStreamInfo->NumberOfVertexElements; uiElement++) { - FLOAT *pXboxVertexAsFloat = (FLOAT*)pXboxVertex; - SHORT *pXboxVertexAsShort = (SHORT*)pXboxVertex; - BYTE *pXboxVertexAsByte = (BYTE*)pXboxVertex; + FLOAT *pXboxVertexAsFloat = (FLOAT*)pXboxVertexAsByte; + SHORT *pXboxVertexAsShort = (SHORT*)pXboxVertexAsByte; int XboxElementByteSize = pVertexShaderStreamInfo->VertexElements[uiElement].HostByteSize; - FLOAT *pHostVertexAsFloat = (FLOAT*)pHostVertex; - SHORT *pHostVertexAsShort = (SHORT*)pHostVertex; -#if CXBX_USE_D3D9 - BYTE *pHostVertexAsByte = (BYTE*)pHostVertex; -#endif + FLOAT *pHostVertexAsFloat = (FLOAT*)pHostVertexAsByte; + SHORT *pHostVertexAsShort = (SHORT*)pHostVertexAsByte; // Dxbx note : The following code handles only the D3DVSDT enums that need conversion; // All other cases are catched by the memcpy in the default-block. switch (pVertexShaderStreamInfo->VertexElements[uiElement].XboxType) { @@ -413,7 +419,7 @@ void XTL::CxbxVertexBufferConverter::ConvertStream pHostVertexAsShort[0] = pXboxVertexAsShort[0]; pHostVertexAsShort[1] = 0; #else // Make it FLOAT1 - pHostVertexAsFloat[0] = ((FLOAT)pXboxVertexAsShort[0]) / 32767.0f; + pHostVertexAsFloat[0] = NormShortToFloat(pXboxVertexAsShort[0]); //pHostVertexAsFloat[1] = 0.0f; // Would be needed for FLOAT2 #endif break; @@ -422,8 +428,8 @@ void XTL::CxbxVertexBufferConverter::ConvertStream case X_D3DVSDT_NORMSHORT2: { // 0x21: // Make it FLOAT2 // Test-cases : Baldur's Gate: Dark Alliance 2, F1 2002, Gun, Halo - Combat Evolved, Scrapland XboxElementByteSize = 2 * sizeof(SHORT); - pHostVertexAsFloat[0] = ((FLOAT)pXboxVertexAsShort[0]) / 32767.0f; - pHostVertexAsFloat[1] = ((FLOAT)pXboxVertexAsShort[1]) / 32767.0f; + pHostVertexAsFloat[0] = NormShortToFloat(pXboxVertexAsShort[0]); + pHostVertexAsFloat[1] = NormShortToFloat(pXboxVertexAsShort[1]); break; } #endif @@ -436,9 +442,9 @@ void XTL::CxbxVertexBufferConverter::ConvertStream pHostVertexAsShort[2] = pXboxVertexAsShort[2]; pHostVertexAsShort[3] = 32767; // TODO : verify #else // Make it FLOAT3 - pHostVertexAsFloat[0] = ((FLOAT)pXboxVertexAsShort[0]) / 32767.0f; - pHostVertexAsFloat[1] = ((FLOAT)pXboxVertexAsShort[1]) / 32767.0f; - pHostVertexAsFloat[2] = ((FLOAT)pXboxVertexAsShort[2]) / 32767.0f; + pHostVertexAsFloat[0] = NormShortToFloat(pXboxVertexAsShort[0]); + pHostVertexAsFloat[1] = NormShortToFloat(pXboxVertexAsShort[1]); + pHostVertexAsFloat[2] = NormShortToFloat(pXboxVertexAsShort[2]); #endif break; } @@ -446,17 +452,17 @@ void XTL::CxbxVertexBufferConverter::ConvertStream case X_D3DVSDT_NORMSHORT4: { // 0x41: // Make it FLOAT4 // Test-cases : Judge Dredd: Dredd vs Death, NHL Hitz 2002, Silent Hill 2, Sneakers, Tony Hawk Pro Skater 4 XboxElementByteSize = 4 * sizeof(SHORT); - pHostVertexAsFloat[0] = ((FLOAT)pXboxVertexAsShort[0]) / 32767.0f; - pHostVertexAsFloat[1] = ((FLOAT)pXboxVertexAsShort[1]) / 32767.0f; - pHostVertexAsFloat[2] = ((FLOAT)pXboxVertexAsShort[2]) / 32767.0f; - pHostVertexAsFloat[3] = ((FLOAT)pXboxVertexAsShort[3]) / 32767.0f; + pHostVertexAsFloat[0] = NormShortToFloat(pXboxVertexAsShort[0]); + pHostVertexAsFloat[1] = NormShortToFloat(pXboxVertexAsShort[1]); + pHostVertexAsFloat[2] = NormShortToFloat(pXboxVertexAsShort[2]); + pHostVertexAsFloat[3] = NormShortToFloat(pXboxVertexAsShort[3]); break; } #endif case X_D3DVSDT_NORMPACKED3: { // 0x16: // Make it FLOAT3 // Test-cases : Dashboard XboxElementByteSize = 1 * sizeof(int32); - int32 iPacked = ((int32 *)pXboxVertex)[0]; + int32 iPacked = ((int32 *)pXboxVertexAsByte)[0]; // Cxbx note : to make each component signed, two need to be shifted towards the sign-bit first : pHostVertexAsFloat[0] = ((FLOAT)((iPacked << 21) >> 21)) / 1023.0f; pHostVertexAsFloat[1] = ((FLOAT)((iPacked << 10) >> 21)) / 1023.0f; @@ -465,19 +471,19 @@ void XTL::CxbxVertexBufferConverter::ConvertStream } case X_D3DVSDT_SHORT1: { // 0x15: // Make it SHORT2 and set the second short to 0 XboxElementByteSize = 1 * sizeof(SHORT); - //memcpy(pHostVertexAsFloat, pXboxVertex, XboxElementByteSize); + //memcpy(pHostVertexAsFloat, pXboxVertexAsByte, XboxElementByteSize); pHostVertexAsShort[0] = pXboxVertexAsShort[0]; - pHostVertexAsShort[1] = 0x00; + pHostVertexAsShort[1] = 0; break; } case X_D3DVSDT_SHORT3: { // 0x35: // Make it a SHORT4 and set the fourth short to 1 // Test-cases : Turok XboxElementByteSize = 3 * sizeof(SHORT); - //memcpy(pHostVertexAsFloat, pXboxVertex, XboxElementByteSize); + //memcpy(pHostVertexAsFloat, pXboxVertexAsByte, XboxElementByteSize); pHostVertexAsShort[0] = pXboxVertexAsShort[0]; pHostVertexAsShort[1] = pXboxVertexAsShort[1]; pHostVertexAsShort[2] = pXboxVertexAsShort[2]; - pHostVertexAsShort[3] = 0x01; // Turok verified (character disappears when this is 32767) + pHostVertexAsShort[3] = 1; // Turok verified (character disappears when this is 32767) break; } case X_D3DVSDT_PBYTE1: { // 0x14: @@ -488,7 +494,7 @@ void XTL::CxbxVertexBufferConverter::ConvertStream pHostVertexAsByte[2] = 0; pHostVertexAsByte[3] = 255; // TODO : Verify #else // Make it FLOAT1 - pHostVertexAsFloat[0] = ((FLOAT)pXboxVertexAsByte[0]) / 255.0f; + pHostVertexAsFloat[0] = ByteToFloat(pXboxVertexAsByte[0]); #endif break; } @@ -500,8 +506,8 @@ void XTL::CxbxVertexBufferConverter::ConvertStream pHostVertexAsByte[2] = 0; pHostVertexAsByte[3] = 255; // TODO : Verify #else // Make it FLOAT2 - pHostVertexAsFloat[0] = ((FLOAT)pXboxVertexAsByte[0]) / 255.0f; - pHostVertexAsFloat[1] = ((FLOAT)pXboxVertexAsByte[1]) / 255.0f; + pHostVertexAsFloat[0] = ByteToFloat(pXboxVertexAsByte[0]); + pHostVertexAsFloat[1] = ByteToFloat(pXboxVertexAsByte[1]); #endif break; } @@ -514,23 +520,32 @@ void XTL::CxbxVertexBufferConverter::ConvertStream pHostVertexAsByte[2] = pXboxVertexAsByte[2]; pHostVertexAsByte[3] = 255; // TODO : Verify #else // Make it FLOAT3 - pHostVertexAsFloat[0] = ((FLOAT)pXboxVertexAsByte[0]) / 255.0f; - pHostVertexAsFloat[1] = ((FLOAT)pXboxVertexAsByte[1]) / 255.0f; - pHostVertexAsFloat[2] = ((FLOAT)pXboxVertexAsByte[2]) / 255.0f; + pHostVertexAsFloat[0] = ByteToFloat(pXboxVertexAsByte[0]); + pHostVertexAsFloat[1] = ByteToFloat(pXboxVertexAsByte[1]); + pHostVertexAsFloat[2] = ByteToFloat(pXboxVertexAsByte[2]); #endif break; } -#if !CXBX_USE_D3D9 // No need for patching in D3D9 - case X_D3DVSDT_PBYTE4: { // 0x44: // Make it FLOAT4 + case X_D3DVSDT_PBYTE4: { // 0x44: // Hit by Jet Set Radio Future - XboxElementByteSize = 4 * sizeof(BYTE); - pHostVertexAsFloat[0] = ((FLOAT)pXboxVertexAsByte[0]) / 255.0f; - pHostVertexAsFloat[1] = ((FLOAT)pXboxVertexAsByte[1]) / 255.0f; - pHostVertexAsFloat[2] = ((FLOAT)pXboxVertexAsByte[2]) / 255.0f; - pHostVertexAsFloat[3] = ((FLOAT)pXboxVertexAsByte[3]) / 255.0f; +#if CXBX_USE_D3D9 + if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) { + // No need for patching when D3D9 supports D3DDECLTYPE_UBYTE4N + // TODO : goto default; // ?? + memcpy(pHostVertexAsByte, pXboxVertexAsByte, XboxElementByteSize); + } + else +#endif + { + // Make it FLOAT4 + XboxElementByteSize = 4 * sizeof(BYTE); + pHostVertexAsFloat[0] = ByteToFloat(pXboxVertexAsByte[0]); + pHostVertexAsFloat[1] = ByteToFloat(pXboxVertexAsByte[1]); + pHostVertexAsFloat[2] = ByteToFloat(pXboxVertexAsByte[2]); + pHostVertexAsFloat[3] = ByteToFloat(pXboxVertexAsByte[3]); + } break; } -#endif case X_D3DVSDT_FLOAT2H: { // 0x72: // Make it FLOAT4 and set the third float to 0.0 XboxElementByteSize = 3 * sizeof(FLOAT); pHostVertexAsFloat[0] = pXboxVertexAsFloat[0]; @@ -545,15 +560,15 @@ void XTL::CxbxVertexBufferConverter::ConvertStream } default: { // Generic 'conversion' - just make a copy : - memcpy(pHostVertex, pXboxVertex, XboxElementByteSize); + memcpy(pHostVertexAsByte, pXboxVertexAsByte, XboxElementByteSize); break; } } // switch // Increment the Xbox pointer : - pXboxVertex += XboxElementByteSize; + pXboxVertexAsByte += XboxElementByteSize; // Increment the host pointer : - pHostVertex += pVertexShaderStreamInfo->VertexElements[uiElement].HostByteSize; + pHostVertexAsByte += pVertexShaderStreamInfo->VertexElements[uiElement].HostByteSize; } // for NumberOfVertexElements } // for uiVertexCount } diff --git a/src/CxbxKrnl/EmuD3D8/VertexShader.cpp b/src/CxbxKrnl/EmuD3D8/VertexShader.cpp index 1cf02555e..7bc9dac31 100644 --- a/src/CxbxKrnl/EmuD3D8/VertexShader.cpp +++ b/src/CxbxKrnl/EmuD3D8/VertexShader.cpp @@ -1990,154 +1990,158 @@ static void VshConvertToken_STREAMDATA_REG( XTL::DWORD HostVertexElementDataType = 0; XTL::DWORD HostVertexElementByteSize = 0; - switch(XboxVertexElementDataType) - { + switch (XboxVertexElementDataType) + { case X_D3DVSDT_FLOAT1: // 0x12: - DbgVshPrintf("D3DVSDT_FLOAT1"); + DbgVshPrintf("D3DVSDT_FLOAT1"); HostVertexElementDataType = D3DDECLTYPE_FLOAT1; - HostVertexElementByteSize = 1*sizeof(FLOAT); - break; + HostVertexElementByteSize = 1 * sizeof(FLOAT); + break; case X_D3DVSDT_FLOAT2: // 0x22: - DbgVshPrintf("D3DVSDT_FLOAT2"); + DbgVshPrintf("D3DVSDT_FLOAT2"); HostVertexElementDataType = D3DDECLTYPE_FLOAT2; - HostVertexElementByteSize = 2*sizeof(FLOAT); - break; + HostVertexElementByteSize = 2 * sizeof(FLOAT); + break; case X_D3DVSDT_FLOAT3: // 0x32: - DbgVshPrintf("D3DVSDT_FLOAT3"); + DbgVshPrintf("D3DVSDT_FLOAT3"); HostVertexElementDataType = D3DDECLTYPE_FLOAT3; - HostVertexElementByteSize = 3*sizeof(FLOAT); - break; + HostVertexElementByteSize = 3 * sizeof(FLOAT); + break; case X_D3DVSDT_FLOAT4: // 0x42: - DbgVshPrintf("D3DVSDT_FLOAT4"); + DbgVshPrintf("D3DVSDT_FLOAT4"); HostVertexElementDataType = D3DDECLTYPE_FLOAT4; - HostVertexElementByteSize = 4*sizeof(FLOAT); - break; + HostVertexElementByteSize = 4 * sizeof(FLOAT); + break; case X_D3DVSDT_D3DCOLOR: // 0x40: - DbgVshPrintf("D3DVSDT_D3DCOLOR"); + DbgVshPrintf("D3DVSDT_D3DCOLOR"); HostVertexElementDataType = D3DDECLTYPE_D3DCOLOR; - HostVertexElementByteSize = 1*sizeof(D3DCOLOR); - break; + HostVertexElementByteSize = 1 * sizeof(D3DCOLOR); + break; case X_D3DVSDT_SHORT2: // 0x25: - DbgVshPrintf("D3DVSDT_SHORT2"); + DbgVshPrintf("D3DVSDT_SHORT2"); HostVertexElementDataType = D3DDECLTYPE_SHORT2; - HostVertexElementByteSize = 2*sizeof(XTL::SHORT); - break; + HostVertexElementByteSize = 2 * sizeof(XTL::SHORT); + break; case X_D3DVSDT_SHORT4: // 0x45: - DbgVshPrintf("D3DVSDT_SHORT4"); + DbgVshPrintf("D3DVSDT_SHORT4"); HostVertexElementDataType = D3DDECLTYPE_SHORT4; - HostVertexElementByteSize = 4*sizeof(XTL::SHORT); - break; + HostVertexElementByteSize = 4 * sizeof(XTL::SHORT); + break; case X_D3DVSDT_NORMSHORT1: // 0x11: - DbgVshPrintf("D3DVSDT_NORMSHORT1 /* xbox ext. */"); + DbgVshPrintf("D3DVSDT_NORMSHORT1 /* xbox ext. */"); #if CXBX_USE_D3D9 HostVertexElementDataType = D3DDECLTYPE_SHORT2N; - HostVertexElementByteSize = 2*sizeof(SHORT); + HostVertexElementByteSize = 2 * sizeof(SHORT); #else HostVertexElementDataType = D3DDECLTYPE_FLOAT1; - HostVertexElementByteSize = 1*sizeof(FLOAT); + HostVertexElementByteSize = 1 * sizeof(FLOAT); #endif - NeedPatching = TRUE; - break; + NeedPatching = TRUE; + break; case X_D3DVSDT_NORMSHORT2: // 0x21: #if CXBX_USE_D3D9 DbgVshPrintf("D3DVSDT_NORMSHORT2"); HostVertexElementDataType = D3DDECLTYPE_SHORT2N; - HostVertexElementByteSize = 2*sizeof(SHORT); + HostVertexElementByteSize = 2 * sizeof(SHORT); // No need for patching in D3D9 #else DbgVshPrintf("D3DVSDT_NORMSHORT2 /* xbox ext. */"); - HostVertexElementDataType = D3DDECLTYPE_FLOAT2; - HostVertexElementByteSize = 2*sizeof(FLOAT); - NeedPatching = TRUE; + HostVertexElementDataType = D3DDECLTYPE_FLOAT2; + HostVertexElementByteSize = 2 * sizeof(FLOAT); + NeedPatching = TRUE; #endif break; case X_D3DVSDT_NORMSHORT3: // 0x31: - DbgVshPrintf("D3DVSDT_NORMSHORT3 /* xbox ext. */"); + DbgVshPrintf("D3DVSDT_NORMSHORT3 /* xbox ext. */"); #if CXBX_USE_D3D9 HostVertexElementDataType = D3DDECLTYPE_SHORT4N; - HostVertexElementByteSize = 4*sizeof(SHORT); + HostVertexElementByteSize = 4 * sizeof(SHORT); #else HostVertexElementDataType = D3DDECLTYPE_FLOAT3; - HostVertexElementByteSize = 3*sizeof(FLOAT); + HostVertexElementByteSize = 3 * sizeof(FLOAT); #endif - NeedPatching = TRUE; - break; + NeedPatching = TRUE; + break; case X_D3DVSDT_NORMSHORT4: // 0x41: #if CXBX_USE_D3D9 DbgVshPrintf("D3DVSDT_NORMSHORT4"); HostVertexElementDataType = D3DDECLTYPE_SHORT4N; - HostVertexElementByteSize = 4*sizeof(SHORT); + HostVertexElementByteSize = 4 * sizeof(SHORT); // No need for patching in D3D9 #else DbgVshPrintf("D3DVSDT_NORMSHORT4 /* xbox ext. */"); - HostVertexElementDataType = D3DDECLTYPE_FLOAT4; - HostVertexElementByteSize = 4*sizeof(FLOAT); - NeedPatching = TRUE; + HostVertexElementDataType = D3DDECLTYPE_FLOAT4; + HostVertexElementByteSize = 4 * sizeof(FLOAT); + NeedPatching = TRUE; #endif - break; + break; case X_D3DVSDT_NORMPACKED3: // 0x16: - DbgVshPrintf("D3DVSDT_NORMPACKED3 /* xbox ext. */"); + DbgVshPrintf("D3DVSDT_NORMPACKED3 /* xbox ext. */"); HostVertexElementDataType = D3DDECLTYPE_FLOAT3; - HostVertexElementByteSize = 3*sizeof(FLOAT); - NeedPatching = TRUE; - break; + HostVertexElementByteSize = 3 * sizeof(FLOAT); + NeedPatching = TRUE; + break; case X_D3DVSDT_SHORT1: // 0x15: - DbgVshPrintf("D3DVSDT_SHORT1 /* xbox ext. */"); - HostVertexElementDataType = D3DDECLTYPE_SHORT2; - HostVertexElementByteSize = 2*sizeof(XTL::SHORT); - NeedPatching = TRUE; - break; + DbgVshPrintf("D3DVSDT_SHORT1 /* xbox ext. */"); + HostVertexElementDataType = D3DDECLTYPE_SHORT2; + HostVertexElementByteSize = 2 * sizeof(XTL::SHORT); + NeedPatching = TRUE; + break; case X_D3DVSDT_SHORT3: // 0x35: - DbgVshPrintf("D3DVSDT_SHORT3 /* xbox ext. */"); - HostVertexElementDataType = D3DDECLTYPE_SHORT4; - HostVertexElementByteSize = 4*sizeof(XTL::SHORT); - NeedPatching = TRUE; - break; + DbgVshPrintf("D3DVSDT_SHORT3 /* xbox ext. */"); + HostVertexElementDataType = D3DDECLTYPE_SHORT4; + HostVertexElementByteSize = 4 * sizeof(XTL::SHORT); + NeedPatching = TRUE; + break; case X_D3DVSDT_PBYTE1: // 0x14: - DbgVshPrintf("D3DVSDT_PBYTE1 /* xbox ext. */"); + DbgVshPrintf("D3DVSDT_PBYTE1 /* xbox ext. */"); #if CXBX_USE_D3D9 HostVertexElementDataType = D3DDECLTYPE_UBYTE4N; - HostVertexElementByteSize = 4*sizeof(BYTE); + HostVertexElementByteSize = 4 * sizeof(BYTE); #else - HostVertexElementDataType = D3DDECLTYPE_FLOAT1; - HostVertexElementByteSize = 1*sizeof(FLOAT); + HostVertexElementDataType = D3DDECLTYPE_FLOAT1; + HostVertexElementByteSize = 1 * sizeof(FLOAT); #endif NeedPatching = TRUE; - break; + break; case X_D3DVSDT_PBYTE2: // 0x24: - DbgVshPrintf("D3DVSDT_PBYTE2 /* xbox ext. */"); + DbgVshPrintf("D3DVSDT_PBYTE2 /* xbox ext. */"); #if CXBX_USE_D3D9 HostVertexElementDataType = D3DDECLTYPE_UBYTE4N; - HostVertexElementByteSize = 4*sizeof(BYTE); + HostVertexElementByteSize = 4 * sizeof(BYTE); #else HostVertexElementDataType = D3DDECLTYPE_FLOAT2; - HostVertexElementByteSize = 2*sizeof(FLOAT); + HostVertexElementByteSize = 2 * sizeof(FLOAT); #endif - NeedPatching = TRUE; - break; + NeedPatching = TRUE; + break; case X_D3DVSDT_PBYTE3: // 0x34: - DbgVshPrintf("D3DVSDT_PBYTE3 /* xbox ext. */"); + DbgVshPrintf("D3DVSDT_PBYTE3 /* xbox ext. */"); #if CXBX_USE_D3D9 HostVertexElementDataType = D3DDECLTYPE_UBYTE4N; - HostVertexElementByteSize = 4*sizeof(BYTE); + HostVertexElementByteSize = 4 * sizeof(BYTE); #else HostVertexElementDataType = D3DDECLTYPE_FLOAT3; - HostVertexElementByteSize = 3*sizeof(FLOAT); + HostVertexElementByteSize = 3 * sizeof(FLOAT); #endif - NeedPatching = TRUE; - break; + NeedPatching = TRUE; + break; case X_D3DVSDT_PBYTE4: // 0x44: // Hit by Panzer #if CXBX_USE_D3D9 - DbgVshPrintf("D3DVSDT_PBYTE4"); - HostVertexElementDataType = D3DDECLTYPE_UBYTE4N; - HostVertexElementByteSize = 4*sizeof(BYTE); - // No need for patching in D3D9 -#else - DbgVshPrintf("D3DVSDT_PBYTE4 /* xbox ext. */"); - HostVertexElementDataType = D3DDECLTYPE_FLOAT4; - HostVertexElementByteSize = 4*sizeof(FLOAT); - NeedPatching = TRUE; + if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) { + DbgVshPrintf("D3DVSDT_PBYTE4"); + HostVertexElementDataType = D3DDECLTYPE_UBYTE4N; + HostVertexElementByteSize = 4 * sizeof(BYTE); + // No need for patching when D3D9 supports D3DDECLTYPE_UBYTE4N + } + else #endif + { + DbgVshPrintf("D3DVSDT_PBYTE4 /* xbox ext. */"); + HostVertexElementDataType = D3DDECLTYPE_FLOAT4; + HostVertexElementByteSize = 4 * sizeof(FLOAT); + NeedPatching = TRUE; + } break; case X_D3DVSDT_FLOAT2H: // 0x72: DbgVshPrintf("D3DVSDT_FLOAT2H /* xbox ext. */"); @@ -2148,7 +2152,7 @@ static void VshConvertToken_STREAMDATA_REG( case X_D3DVSDT_NONE: // 0x02: DbgVshPrintf("D3DVSDT_NONE /* xbox ext. */"); HostVertexElementDataType = D3DDECLTYPE_UNUSED; - NeedPatching = TRUE; + // NeedPatching = TRUE; // TODO : This seems to cause regressions? break; default: DbgVshPrintf("Unknown data type for D3DVSD_REG: 0x%02X\n", XboxVertexElementDataType); From 25dc51722657483a30e308c4f0fe00a417adcad0 Mon Sep 17 00:00:00 2001 From: patrickvl Date: Sun, 27 May 2018 14:45:56 +0200 Subject: [PATCH 05/10] D3D9 : Use an alias for pixel shader constant type --- src/CxbxKrnl/EmuD3D8.cpp | 6 +----- src/CxbxKrnl/EmuD3D8/PixelShader.cpp | 9 +++++++-- src/CxbxKrnl/EmuD3D8Types.h | 2 ++ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/CxbxKrnl/EmuD3D8.cpp b/src/CxbxKrnl/EmuD3D8.cpp index 49f9bd123..6a307d66f 100644 --- a/src/CxbxKrnl/EmuD3D8.cpp +++ b/src/CxbxKrnl/EmuD3D8.cpp @@ -9504,11 +9504,7 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetPixelShaderConstant_4) #endif ( Register, -#ifdef CXBX_USE_D3D9 - (float*)pConstantData, -#else - pConstantData, -#endif + (PixelShaderConstantType*)pConstantData, ConstantCount ); //DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetPixelShaderConstant"); diff --git a/src/CxbxKrnl/EmuD3D8/PixelShader.cpp b/src/CxbxKrnl/EmuD3D8/PixelShader.cpp index 3269a7795..89403333b 100644 --- a/src/CxbxKrnl/EmuD3D8/PixelShader.cpp +++ b/src/CxbxKrnl/EmuD3D8/PixelShader.cpp @@ -4338,10 +4338,15 @@ VOID XTL::DxbxUpdateActivePixelShader() // NOPATCH // TODO : Avoid the following setter if it's no different from the previous update (this might speed things up) // Set the value locally in this register : #ifdef CXBX_USE_D3D9 - g_pD3DDevice->SetPixelShaderConstantF(Register_, (float*)(&fColor), 1); + g_pD3DDevice->SetPixelShaderConstantF #else - g_pD3DDevice->SetPixelShaderConstant(Register_, &fColor, 1); + g_pD3DDevice->SetPixelShaderConstant #endif + ( + Register_, + (PixelShaderConstantType*)(&fColor), + 1 + ); } } } diff --git a/src/CxbxKrnl/EmuD3D8Types.h b/src/CxbxKrnl/EmuD3D8Types.h index 34913e0a5..6d81bc250 100755 --- a/src/CxbxKrnl/EmuD3D8Types.h +++ b/src/CxbxKrnl/EmuD3D8Types.h @@ -70,6 +70,7 @@ #define D3DXAssembleShader D3DXCompileShader #define FullScreen_PresentationInterval PresentationInterval // a field in D3DPRESENT_PARAMETERS #define D3DLockData void +#define PixelShaderConstantType float #define D3DADAPTER_IDENTIFIER D3DADAPTER_IDENTIFIER9 #define D3DCAPS D3DCAPS9 @@ -113,6 +114,7 @@ typedef D3DVIEWPORT9 X_D3DVIEWPORT8; #define DXGetErrorString DXGetErrorString8A #define DXGetErrorDescription DXGetErrorDescription8A #define D3DLockData BYTE +#define PixelShaderConstantType void #define D3DADAPTER_IDENTIFIER D3DADAPTER_IDENTIFIER8 #define D3DCAPS D3DCAPS8 From 2668a01a87c0a2df369057572824c1d564e78e01 Mon Sep 17 00:00:00 2001 From: patrickvl Date: Sun, 27 May 2018 15:55:17 +0200 Subject: [PATCH 06/10] D3D9 : Honour D3DCaps for all DECLTYPES --- src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp | 80 +++++++++++------- src/CxbxKrnl/EmuD3D8/VertexShader.cpp | 114 ++++++++++++++++---------- 2 files changed, 122 insertions(+), 72 deletions(-) diff --git a/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp b/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp index bfd1b2a33..29890a1b9 100755 --- a/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp +++ b/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp @@ -466,12 +466,12 @@ void XTL::CxbxVertexBufferConverter::ConvertStream // Cxbx note : to make each component signed, two need to be shifted towards the sign-bit first : pHostVertexAsFloat[0] = ((FLOAT)((iPacked << 21) >> 21)) / 1023.0f; pHostVertexAsFloat[1] = ((FLOAT)((iPacked << 10) >> 21)) / 1023.0f; - pHostVertexAsFloat[2] = ((FLOAT)((iPacked ) >> 22)) / 511.0f; + pHostVertexAsFloat[2] = ((FLOAT)((iPacked) >> 22)) / 511.0f; break; } case X_D3DVSDT_SHORT1: { // 0x15: // Make it SHORT2 and set the second short to 0 XboxElementByteSize = 1 * sizeof(SHORT); - //memcpy(pHostVertexAsFloat, pXboxVertexAsByte, XboxElementByteSize); + //memcpy(pHostVertexAsByte, pXboxVertexAsByte, XboxElementByteSize); pHostVertexAsShort[0] = pXboxVertexAsShort[0]; pHostVertexAsShort[1] = 0; break; @@ -479,7 +479,7 @@ void XTL::CxbxVertexBufferConverter::ConvertStream case X_D3DVSDT_SHORT3: { // 0x35: // Make it a SHORT4 and set the fourth short to 1 // Test-cases : Turok XboxElementByteSize = 3 * sizeof(SHORT); - //memcpy(pHostVertexAsFloat, pXboxVertexAsByte, XboxElementByteSize); + //memcpy(pHostVertexAsByte, pXboxVertexAsByte, XboxElementByteSize); pHostVertexAsShort[0] = pXboxVertexAsShort[0]; pHostVertexAsShort[1] = pXboxVertexAsShort[1]; pHostVertexAsShort[2] = pXboxVertexAsShort[2]; @@ -488,42 +488,59 @@ void XTL::CxbxVertexBufferConverter::ConvertStream } case X_D3DVSDT_PBYTE1: { // 0x14: XboxElementByteSize = 1 * sizeof(BYTE); -#if CXBX_USE_D3D9 // Make it UBYTE4N - pHostVertexAsByte[0] = pXboxVertexAsByte[0]; - pHostVertexAsByte[1] = 0; - pHostVertexAsByte[2] = 0; - pHostVertexAsByte[3] = 255; // TODO : Verify -#else // Make it FLOAT1 - pHostVertexAsFloat[0] = ByteToFloat(pXboxVertexAsByte[0]); +#if CXBX_USE_D3D9 + if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) { + // Make it UBYTE4N + pHostVertexAsByte[0] = pXboxVertexAsByte[0]; + pHostVertexAsByte[1] = 0; + pHostVertexAsByte[2] = 0; + pHostVertexAsByte[3] = 255; // TODO : Verify + } + else #endif + { + // Make it FLOAT1 + pHostVertexAsFloat[0] = ByteToFloat(pXboxVertexAsByte[0]); + } break; } case X_D3DVSDT_PBYTE2: { // 0x24: XboxElementByteSize = 2 * sizeof(BYTE); -#if CXBX_USE_D3D9 // Make it UBYTE4N - pHostVertexAsByte[0] = pXboxVertexAsByte[0]; - pHostVertexAsByte[1] = pXboxVertexAsByte[1]; - pHostVertexAsByte[2] = 0; - pHostVertexAsByte[3] = 255; // TODO : Verify -#else // Make it FLOAT2 - pHostVertexAsFloat[0] = ByteToFloat(pXboxVertexAsByte[0]); - pHostVertexAsFloat[1] = ByteToFloat(pXboxVertexAsByte[1]); +#if CXBX_USE_D3D9 + if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) { + // Make it UBYTE4N + pHostVertexAsByte[0] = pXboxVertexAsByte[0]; + pHostVertexAsByte[1] = pXboxVertexAsByte[1]; + pHostVertexAsByte[2] = 0; + pHostVertexAsByte[3] = 255; // TODO : Verify + } + else #endif - break; + { + // Make it FLOAT2 + pHostVertexAsFloat[0] = ByteToFloat(pXboxVertexAsByte[0]); + pHostVertexAsFloat[1] = ByteToFloat(pXboxVertexAsByte[1]); + } break; } case X_D3DVSDT_PBYTE3: { // 0x34: // Test-cases : Turok XboxElementByteSize = 3 * sizeof(BYTE); -#if CXBX_USE_D3D9 // Make it UBYTE4N - pHostVertexAsByte[0] = pXboxVertexAsByte[0]; - pHostVertexAsByte[1] = pXboxVertexAsByte[1]; - pHostVertexAsByte[2] = pXboxVertexAsByte[2]; - pHostVertexAsByte[3] = 255; // TODO : Verify -#else // Make it FLOAT3 - pHostVertexAsFloat[0] = ByteToFloat(pXboxVertexAsByte[0]); - pHostVertexAsFloat[1] = ByteToFloat(pXboxVertexAsByte[1]); - pHostVertexAsFloat[2] = ByteToFloat(pXboxVertexAsByte[2]); +#if CXBX_USE_D3D9 + if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) { + // Make it UBYTE4N + pHostVertexAsByte[0] = pXboxVertexAsByte[0]; + pHostVertexAsByte[1] = pXboxVertexAsByte[1]; + pHostVertexAsByte[2] = pXboxVertexAsByte[2]; + pHostVertexAsByte[3] = 255; // TODO : Verify + } + else #endif + { + // Make it FLOAT3 + pHostVertexAsFloat[0] = ByteToFloat(pXboxVertexAsByte[0]); + pHostVertexAsFloat[1] = ByteToFloat(pXboxVertexAsByte[1]); + pHostVertexAsFloat[2] = ByteToFloat(pXboxVertexAsByte[2]); + } break; } case X_D3DVSDT_PBYTE4: { // 0x44: @@ -532,7 +549,12 @@ void XTL::CxbxVertexBufferConverter::ConvertStream if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) { // No need for patching when D3D9 supports D3DDECLTYPE_UBYTE4N // TODO : goto default; // ?? - memcpy(pHostVertexAsByte, pXboxVertexAsByte, XboxElementByteSize); + //assert(XboxElementByteSize == 4 * sizeof(BYTE)); + //memcpy(pHostVertexAsByte, pXboxVertexAsByte, XboxElementByteSize); + pHostVertexAsByte[0] = pXboxVertexAsByte[0]; + pHostVertexAsByte[1] = pXboxVertexAsByte[1]; + pHostVertexAsByte[2] = pXboxVertexAsByte[2]; + pHostVertexAsByte[3] = pXboxVertexAsByte[3]; } else #endif diff --git a/src/CxbxKrnl/EmuD3D8/VertexShader.cpp b/src/CxbxKrnl/EmuD3D8/VertexShader.cpp index 7bc9dac31..a25f7225b 100644 --- a/src/CxbxKrnl/EmuD3D8/VertexShader.cpp +++ b/src/CxbxKrnl/EmuD3D8/VertexShader.cpp @@ -2030,50 +2030,66 @@ static void VshConvertToken_STREAMDATA_REG( case X_D3DVSDT_NORMSHORT1: // 0x11: DbgVshPrintf("D3DVSDT_NORMSHORT1 /* xbox ext. */"); #if CXBX_USE_D3D9 - HostVertexElementDataType = D3DDECLTYPE_SHORT2N; - HostVertexElementByteSize = 2 * sizeof(SHORT); -#else - HostVertexElementDataType = D3DDECLTYPE_FLOAT1; - HostVertexElementByteSize = 1 * sizeof(FLOAT); + if (g_D3DCaps.DeclTypes & D3DDTCAPS_SHORT2N) { + HostVertexElementDataType = D3DDECLTYPE_SHORT2N; + HostVertexElementByteSize = 2 * sizeof(SHORT); + } + else #endif + { + HostVertexElementDataType = D3DDECLTYPE_FLOAT1; + HostVertexElementByteSize = 1 * sizeof(FLOAT); + } NeedPatching = TRUE; break; case X_D3DVSDT_NORMSHORT2: // 0x21: #if CXBX_USE_D3D9 - DbgVshPrintf("D3DVSDT_NORMSHORT2"); - HostVertexElementDataType = D3DDECLTYPE_SHORT2N; - HostVertexElementByteSize = 2 * sizeof(SHORT); - // No need for patching in D3D9 -#else - DbgVshPrintf("D3DVSDT_NORMSHORT2 /* xbox ext. */"); - HostVertexElementDataType = D3DDECLTYPE_FLOAT2; - HostVertexElementByteSize = 2 * sizeof(FLOAT); - NeedPatching = TRUE; + if (g_D3DCaps.DeclTypes & D3DDTCAPS_SHORT2N) { + DbgVshPrintf("D3DVSDT_NORMSHORT2"); + HostVertexElementDataType = D3DDECLTYPE_SHORT2N; + HostVertexElementByteSize = 2 * sizeof(SHORT); + // No need for patching in D3D9 + } + else #endif + { + DbgVshPrintf("D3DVSDT_NORMSHORT2 /* xbox ext. */"); + HostVertexElementDataType = D3DDECLTYPE_FLOAT2; + HostVertexElementByteSize = 2 * sizeof(FLOAT); + NeedPatching = TRUE; + } break; case X_D3DVSDT_NORMSHORT3: // 0x31: DbgVshPrintf("D3DVSDT_NORMSHORT3 /* xbox ext. */"); #if CXBX_USE_D3D9 - HostVertexElementDataType = D3DDECLTYPE_SHORT4N; - HostVertexElementByteSize = 4 * sizeof(SHORT); -#else - HostVertexElementDataType = D3DDECLTYPE_FLOAT3; - HostVertexElementByteSize = 3 * sizeof(FLOAT); + if (g_D3DCaps.DeclTypes & D3DDTCAPS_SHORT4N) { + HostVertexElementDataType = D3DDECLTYPE_SHORT4N; + HostVertexElementByteSize = 4 * sizeof(SHORT); + } + else #endif + { + HostVertexElementDataType = D3DDECLTYPE_FLOAT3; + HostVertexElementByteSize = 3 * sizeof(FLOAT); + } NeedPatching = TRUE; break; case X_D3DVSDT_NORMSHORT4: // 0x41: #if CXBX_USE_D3D9 - DbgVshPrintf("D3DVSDT_NORMSHORT4"); - HostVertexElementDataType = D3DDECLTYPE_SHORT4N; - HostVertexElementByteSize = 4 * sizeof(SHORT); - // No need for patching in D3D9 -#else - DbgVshPrintf("D3DVSDT_NORMSHORT4 /* xbox ext. */"); - HostVertexElementDataType = D3DDECLTYPE_FLOAT4; - HostVertexElementByteSize = 4 * sizeof(FLOAT); - NeedPatching = TRUE; + if (g_D3DCaps.DeclTypes & D3DDTCAPS_SHORT4N) { + DbgVshPrintf("D3DVSDT_NORMSHORT4"); + HostVertexElementDataType = D3DDECLTYPE_SHORT4N; + HostVertexElementByteSize = 4 * sizeof(SHORT); + // No need for patching in D3D9 + } + else #endif + { + DbgVshPrintf("D3DVSDT_NORMSHORT4 /* xbox ext. */"); + HostVertexElementDataType = D3DDECLTYPE_FLOAT4; + HostVertexElementByteSize = 4 * sizeof(FLOAT); + NeedPatching = TRUE; + } break; case X_D3DVSDT_NORMPACKED3: // 0x16: DbgVshPrintf("D3DVSDT_NORMPACKED3 /* xbox ext. */"); @@ -2096,34 +2112,46 @@ static void VshConvertToken_STREAMDATA_REG( case X_D3DVSDT_PBYTE1: // 0x14: DbgVshPrintf("D3DVSDT_PBYTE1 /* xbox ext. */"); #if CXBX_USE_D3D9 - HostVertexElementDataType = D3DDECLTYPE_UBYTE4N; - HostVertexElementByteSize = 4 * sizeof(BYTE); -#else - HostVertexElementDataType = D3DDECLTYPE_FLOAT1; - HostVertexElementByteSize = 1 * sizeof(FLOAT); + if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) { + HostVertexElementDataType = D3DDECLTYPE_UBYTE4N; + HostVertexElementByteSize = 4 * sizeof(BYTE); + } + else #endif + { + HostVertexElementDataType = D3DDECLTYPE_FLOAT1; + HostVertexElementByteSize = 1 * sizeof(FLOAT); + } NeedPatching = TRUE; break; case X_D3DVSDT_PBYTE2: // 0x24: DbgVshPrintf("D3DVSDT_PBYTE2 /* xbox ext. */"); #if CXBX_USE_D3D9 - HostVertexElementDataType = D3DDECLTYPE_UBYTE4N; - HostVertexElementByteSize = 4 * sizeof(BYTE); -#else - HostVertexElementDataType = D3DDECLTYPE_FLOAT2; - HostVertexElementByteSize = 2 * sizeof(FLOAT); + if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) { + HostVertexElementDataType = D3DDECLTYPE_UBYTE4N; + HostVertexElementByteSize = 4 * sizeof(BYTE); + } + else #endif + { + HostVertexElementDataType = D3DDECLTYPE_FLOAT2; + HostVertexElementByteSize = 2 * sizeof(FLOAT); + } NeedPatching = TRUE; break; case X_D3DVSDT_PBYTE3: // 0x34: DbgVshPrintf("D3DVSDT_PBYTE3 /* xbox ext. */"); #if CXBX_USE_D3D9 - HostVertexElementDataType = D3DDECLTYPE_UBYTE4N; - HostVertexElementByteSize = 4 * sizeof(BYTE); -#else - HostVertexElementDataType = D3DDECLTYPE_FLOAT3; - HostVertexElementByteSize = 3 * sizeof(FLOAT); + if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) { + HostVertexElementDataType = D3DDECLTYPE_UBYTE4N; + HostVertexElementByteSize = 4 * sizeof(BYTE); + } + else #endif + { + HostVertexElementDataType = D3DDECLTYPE_FLOAT3; + HostVertexElementByteSize = 3 * sizeof(FLOAT); + } NeedPatching = TRUE; break; case X_D3DVSDT_PBYTE4: // 0x44: // Hit by Panzer From d0a499c545d54cec4af1facd2ec8bdc661baa0d3 Mon Sep 17 00:00:00 2001 From: patrickvl Date: Sun, 27 May 2018 20:57:16 +0200 Subject: [PATCH 07/10] D3D9 : Also check D3DDTCAPS during vertex element conversion --- src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp | 74 ++++++++++++++++++--------- 1 file changed, 50 insertions(+), 24 deletions(-) diff --git a/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp b/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp index 29890a1b9..abefc2198 100755 --- a/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp +++ b/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp @@ -425,9 +425,10 @@ void XTL::CxbxVertexBufferConverter::ConvertStream break; } #if !CXBX_USE_D3D9 // No need for patching in D3D9 - case X_D3DVSDT_NORMSHORT2: { // 0x21: // Make it FLOAT2 + case X_D3DVSDT_NORMSHORT2: { // 0x21: // Test-cases : Baldur's Gate: Dark Alliance 2, F1 2002, Gun, Halo - Combat Evolved, Scrapland XboxElementByteSize = 2 * sizeof(SHORT); + // Make it FLOAT2 pHostVertexAsFloat[0] = NormShortToFloat(pXboxVertexAsShort[0]); pHostVertexAsFloat[1] = NormShortToFloat(pXboxVertexAsShort[1]); break; @@ -436,32 +437,54 @@ void XTL::CxbxVertexBufferConverter::ConvertStream case X_D3DVSDT_NORMSHORT3: { // 0x31: // Test-cases : Cel Damage, Constantine, Destroy All Humans! XboxElementByteSize = 3 * sizeof(SHORT); -#if CXBX_USE_D3D9 // Make it SHORT4N - pHostVertexAsShort[0] = pXboxVertexAsShort[0]; - pHostVertexAsShort[1] = pXboxVertexAsShort[1]; - pHostVertexAsShort[2] = pXboxVertexAsShort[2]; - pHostVertexAsShort[3] = 32767; // TODO : verify -#else // Make it FLOAT3 - pHostVertexAsFloat[0] = NormShortToFloat(pXboxVertexAsShort[0]); - pHostVertexAsFloat[1] = NormShortToFloat(pXboxVertexAsShort[1]); - pHostVertexAsFloat[2] = NormShortToFloat(pXboxVertexAsShort[2]); +#if CXBX_USE_D3D9 + if (g_D3DCaps.DeclTypes & D3DDTCAPS_SHORT4N) { + // Make it SHORT4N + pHostVertexAsShort[0] = pXboxVertexAsShort[0]; + pHostVertexAsShort[1] = pXboxVertexAsShort[1]; + pHostVertexAsShort[2] = pXboxVertexAsShort[2]; + pHostVertexAsShort[3] = 32767; // TODO : verify + } + else #endif + { + // Make it FLOAT3 + pHostVertexAsFloat[0] = NormShortToFloat(pXboxVertexAsShort[0]); + pHostVertexAsFloat[1] = NormShortToFloat(pXboxVertexAsShort[1]); + pHostVertexAsFloat[2] = NormShortToFloat(pXboxVertexAsShort[2]); + } break; } -#if !CXBX_USE_D3D9 // No need for patching in D3D9 - case X_D3DVSDT_NORMSHORT4: { // 0x41: // Make it FLOAT4 + case X_D3DVSDT_NORMSHORT4: { // 0x41: // Test-cases : Judge Dredd: Dredd vs Death, NHL Hitz 2002, Silent Hill 2, Sneakers, Tony Hawk Pro Skater 4 XboxElementByteSize = 4 * sizeof(SHORT); - pHostVertexAsFloat[0] = NormShortToFloat(pXboxVertexAsShort[0]); - pHostVertexAsFloat[1] = NormShortToFloat(pXboxVertexAsShort[1]); - pHostVertexAsFloat[2] = NormShortToFloat(pXboxVertexAsShort[2]); - pHostVertexAsFloat[3] = NormShortToFloat(pXboxVertexAsShort[3]); +#if CXBX_USE_D3D9 + if (g_D3DCaps.DeclTypes & D3DDTCAPS_SHORT4N) { + // No need for patching when D3D9 supports D3DDECLTYPE_SHORT4N + // TODO : goto default; // ?? + //assert(XboxElementByteSize == 4 * sizeof(SHORT)); + //memcpy(pHostVertexAsByte, pXboxVertexAsByte, XboxElementByteSize); + // Make it SHORT4N + pHostVertexAsShort[0] = pXboxVertexAsShort[0]; + pHostVertexAsShort[1] = pXboxVertexAsShort[1]; + pHostVertexAsShort[2] = pXboxVertexAsShort[2]; + pHostVertexAsShort[3] = pXboxVertexAsShort[3]; + } + else +#endif + { + // Make it FLOAT4 + pHostVertexAsFloat[0] = NormShortToFloat(pXboxVertexAsShort[0]); + pHostVertexAsFloat[1] = NormShortToFloat(pXboxVertexAsShort[1]); + pHostVertexAsFloat[2] = NormShortToFloat(pXboxVertexAsShort[2]); + pHostVertexAsFloat[3] = NormShortToFloat(pXboxVertexAsShort[3]); + } break; } -#endif - case X_D3DVSDT_NORMPACKED3: { // 0x16: // Make it FLOAT3 + case X_D3DVSDT_NORMPACKED3: { // 0x16: // Test-cases : Dashboard XboxElementByteSize = 1 * sizeof(int32); + // Make it FLOAT3 int32 iPacked = ((int32 *)pXboxVertexAsByte)[0]; // Cxbx note : to make each component signed, two need to be shifted towards the sign-bit first : pHostVertexAsFloat[0] = ((FLOAT)((iPacked << 21) >> 21)) / 1023.0f; @@ -469,17 +492,17 @@ void XTL::CxbxVertexBufferConverter::ConvertStream pHostVertexAsFloat[2] = ((FLOAT)((iPacked) >> 22)) / 511.0f; break; } - case X_D3DVSDT_SHORT1: { // 0x15: // Make it SHORT2 and set the second short to 0 + case X_D3DVSDT_SHORT1: { // 0x15: XboxElementByteSize = 1 * sizeof(SHORT); - //memcpy(pHostVertexAsByte, pXboxVertexAsByte, XboxElementByteSize); + // Make it SHORT2 and set the second short to 0 pHostVertexAsShort[0] = pXboxVertexAsShort[0]; pHostVertexAsShort[1] = 0; break; } - case X_D3DVSDT_SHORT3: { // 0x35: // Make it a SHORT4 and set the fourth short to 1 + case X_D3DVSDT_SHORT3: { // 0x35: // Test-cases : Turok XboxElementByteSize = 3 * sizeof(SHORT); - //memcpy(pHostVertexAsByte, pXboxVertexAsByte, XboxElementByteSize); + // Make it a SHORT4 and set the fourth short to 1 pHostVertexAsShort[0] = pXboxVertexAsShort[0]; pHostVertexAsShort[1] = pXboxVertexAsShort[1]; pHostVertexAsShort[2] = pXboxVertexAsShort[2]; @@ -520,7 +543,8 @@ void XTL::CxbxVertexBufferConverter::ConvertStream // Make it FLOAT2 pHostVertexAsFloat[0] = ByteToFloat(pXboxVertexAsByte[0]); pHostVertexAsFloat[1] = ByteToFloat(pXboxVertexAsByte[1]); - } break; + } + break; } case X_D3DVSDT_PBYTE3: { // 0x34: // Test-cases : Turok @@ -551,6 +575,7 @@ void XTL::CxbxVertexBufferConverter::ConvertStream // TODO : goto default; // ?? //assert(XboxElementByteSize == 4 * sizeof(BYTE)); //memcpy(pHostVertexAsByte, pXboxVertexAsByte, XboxElementByteSize); + // Make it UBYTE4N pHostVertexAsByte[0] = pXboxVertexAsByte[0]; pHostVertexAsByte[1] = pXboxVertexAsByte[1]; pHostVertexAsByte[2] = pXboxVertexAsByte[2]; @@ -568,8 +593,9 @@ void XTL::CxbxVertexBufferConverter::ConvertStream } break; } - case X_D3DVSDT_FLOAT2H: { // 0x72: // Make it FLOAT4 and set the third float to 0.0 + case X_D3DVSDT_FLOAT2H: { // 0x72: XboxElementByteSize = 3 * sizeof(FLOAT); + // Make it FLOAT4 and set the third float to 0.0 pHostVertexAsFloat[0] = pXboxVertexAsFloat[0]; pHostVertexAsFloat[1] = pXboxVertexAsFloat[1]; pHostVertexAsFloat[2] = 0.0f; From b23e8cf3f37d31b06b361538134c85e97e6e0bcf Mon Sep 17 00:00:00 2001 From: patrickvl Date: Sun, 27 May 2018 21:04:22 +0200 Subject: [PATCH 08/10] D3D9 : More capability checks --- src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp | 42 +++++++++++++++++++-------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp b/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp index abefc2198..7517c297a 100755 --- a/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp +++ b/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp @@ -415,25 +415,43 @@ void XTL::CxbxVertexBufferConverter::ConvertStream case X_D3DVSDT_NORMSHORT1: { // 0x11: // Test-cases : Halo - Combat Evolved XboxElementByteSize = 1 * sizeof(SHORT); -#if CXBX_USE_D3D9 // Make it SHORT2N - pHostVertexAsShort[0] = pXboxVertexAsShort[0]; - pHostVertexAsShort[1] = 0; -#else // Make it FLOAT1 - pHostVertexAsFloat[0] = NormShortToFloat(pXboxVertexAsShort[0]); - //pHostVertexAsFloat[1] = 0.0f; // Would be needed for FLOAT2 +#if CXBX_USE_D3D9 + if (g_D3DCaps.DeclTypes & D3DDTCAPS_SHORT2N) { + // Make it SHORT2N + pHostVertexAsShort[0] = pXboxVertexAsShort[0]; + pHostVertexAsShort[1] = 0; + } + else #endif + { + // Make it FLOAT1 + pHostVertexAsFloat[0] = NormShortToFloat(pXboxVertexAsShort[0]); + //pHostVertexAsFloat[1] = 0.0f; // Would be needed for FLOAT2 + } break; } -#if !CXBX_USE_D3D9 // No need for patching in D3D9 case X_D3DVSDT_NORMSHORT2: { // 0x21: // Test-cases : Baldur's Gate: Dark Alliance 2, F1 2002, Gun, Halo - Combat Evolved, Scrapland XboxElementByteSize = 2 * sizeof(SHORT); - // Make it FLOAT2 - pHostVertexAsFloat[0] = NormShortToFloat(pXboxVertexAsShort[0]); - pHostVertexAsFloat[1] = NormShortToFloat(pXboxVertexAsShort[1]); +#if CXBX_USE_D3D9 + if (g_D3DCaps.DeclTypes & D3DDTCAPS_SHORT2N) { + // No need for patching when D3D9 supports D3DDECLTYPE_SHORT2N + // TODO : goto default; // ?? + //assert(XboxElementByteSize == 2 * sizeof(SHORT)); + //memcpy(pHostVertexAsByte, pXboxVertexAsByte, XboxElementByteSize); + // Make it SHORT2N + pHostVertexAsShort[0] = pXboxVertexAsShort[0]; + pHostVertexAsShort[1] = pXboxVertexAsShort[1]; + } + else +#endif + { + // Make it FLOAT2 + pHostVertexAsFloat[0] = NormShortToFloat(pXboxVertexAsShort[0]); + pHostVertexAsFloat[1] = NormShortToFloat(pXboxVertexAsShort[1]); + } break; } -#endif case X_D3DVSDT_NORMSHORT3: { // 0x31: // Test-cases : Cel Damage, Constantine, Destroy All Humans! XboxElementByteSize = 3 * sizeof(SHORT); @@ -569,6 +587,7 @@ void XTL::CxbxVertexBufferConverter::ConvertStream } case X_D3DVSDT_PBYTE4: { // 0x44: // Hit by Jet Set Radio Future + XboxElementByteSize = 4 * sizeof(BYTE); #if CXBX_USE_D3D9 if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) { // No need for patching when D3D9 supports D3DDECLTYPE_UBYTE4N @@ -585,7 +604,6 @@ void XTL::CxbxVertexBufferConverter::ConvertStream #endif { // Make it FLOAT4 - XboxElementByteSize = 4 * sizeof(BYTE); pHostVertexAsFloat[0] = ByteToFloat(pXboxVertexAsByte[0]); pHostVertexAsFloat[1] = ByteToFloat(pXboxVertexAsByte[1]); pHostVertexAsFloat[2] = ByteToFloat(pXboxVertexAsByte[2]); From 73de67367aa622d903477b5840121af2f9a9bd1e Mon Sep 17 00:00:00 2001 From: PatrickvL Date: Mon, 28 May 2018 16:15:04 +0200 Subject: [PATCH 09/10] D3D9 : Vertex shader declaration recompile fixes --- src/CxbxKrnl/EmuD3D8.cpp | 3 +- src/CxbxKrnl/EmuD3D8/PixelShader.cpp | 7 +-- src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp | 7 ++- src/CxbxKrnl/EmuD3D8/VertexShader.cpp | 79 +++++++++++++++++++++------ src/CxbxKrnl/EmuD3D8Types.h | 14 +++++ 5 files changed, 88 insertions(+), 22 deletions(-) diff --git a/src/CxbxKrnl/EmuD3D8.cpp b/src/CxbxKrnl/EmuD3D8.cpp index 6a307d66f..462de1ccf 100644 --- a/src/CxbxKrnl/EmuD3D8.cpp +++ b/src/CxbxKrnl/EmuD3D8.cpp @@ -124,7 +124,7 @@ struct { // D3D based variables static GUID g_ddguid; // DirectDraw driver GUID static XTL::IDirect3D *g_pDirect3D = nullptr; -static XTL::D3DCAPS g_D3DCaps; // Direct3D Caps +static XTL::D3DCAPS g_D3DCaps = {}; // Direct3D Caps // wireframe toggle static int g_iWireframe = 0; @@ -7555,6 +7555,7 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_DrawVertices) // test-case : BLiNX: the time sweeper // test-case : Halo - Combat Evolved // test-case : Worms 3D Special Edition + // test-case : XDK sample Lensflare DrawContext.dwStartVertex = StartVertex; // Breakpoint location for testing. } diff --git a/src/CxbxKrnl/EmuD3D8/PixelShader.cpp b/src/CxbxKrnl/EmuD3D8/PixelShader.cpp index 89403333b..4d47f51f5 100644 --- a/src/CxbxKrnl/EmuD3D8/PixelShader.cpp +++ b/src/CxbxKrnl/EmuD3D8/PixelShader.cpp @@ -4107,10 +4107,9 @@ PSH_RECOMPILED_SHADER XTL_EmuRecompilePshDef(XTL::X_D3DPIXELSHADERDEF *pPSDef) uint32 PSVersion = D3DPS_VERSION(1, 3); // Use pixel shader model 1.3 by default #if 0 // Once PS.1.4 can be generated, enable this : - XTL::D3DCAPS g_D3DCaps = {}; - if (g_pD3DDevice->GetDeviceCaps(&g_D3DCaps) == D3D_OK) { - PSVersion = g_D3DCaps.PixelShaderVersion; - } + extern XTL::D3DCAPS g_D3DCaps; + + PSVersion = g_D3DCaps.PixelShaderVersion; #endif // TODO : Make the pixel shader version configurable diff --git a/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp b/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp index 7517c297a..12eb186d1 100755 --- a/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp +++ b/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp @@ -284,6 +284,10 @@ void XTL::CxbxVertexBufferConverter::ConvertStream UINT uiStream ) { +#if CXBX_USE_D3D9 + extern XTL::D3DCAPS g_D3DCaps; +#endif + bool bVshHandleIsFVF = VshHandleIsFVF(pDrawContext->hVertexShader); DWORD XboxFVF = bVshHandleIsFVF ? pDrawContext->hVertexShader : 0; // Texture normalization can only be set for FVF shaders @@ -586,7 +590,7 @@ void XTL::CxbxVertexBufferConverter::ConvertStream break; } case X_D3DVSDT_PBYTE4: { // 0x44: - // Hit by Jet Set Radio Future + // Test-case : Jet Set Radio Future XboxElementByteSize = 4 * sizeof(BYTE); #if CXBX_USE_D3D9 if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) { @@ -621,6 +625,7 @@ void XTL::CxbxVertexBufferConverter::ConvertStream break; } case X_D3DVSDT_NONE: { // 0x02: // Skip it + // Test-case : WWE RAW2 LOG_TEST_CASE("X_D3DVSDT_NONE"); break; } diff --git a/src/CxbxKrnl/EmuD3D8/VertexShader.cpp b/src/CxbxKrnl/EmuD3D8/VertexShader.cpp index a25f7225b..71eb05f28 100644 --- a/src/CxbxKrnl/EmuD3D8/VertexShader.cpp +++ b/src/CxbxKrnl/EmuD3D8/VertexShader.cpp @@ -1816,20 +1816,34 @@ static DWORD VshConvertToken_CONSTMEM( XTL::D3DVERTEXELEMENT *pRecompiled ) { + using namespace XTL; + // D3DVSD_CONST DbgVshPrintf("\tD3DVSD_CONST("); DWORD ConstantAddress = (*pToken & X_D3DVSD_CONSTADDRESSMASK) >> X_D3DVSD_CONSTADDRESSSHIFT; DWORD Count = (*pToken & X_D3DVSD_CONSTCOUNTMASK) >> X_D3DVSD_CONSTCOUNTSHIFT; - DbgVshPrintf("%d, %d),\n", ConstantAddress, Count); - //pToken = D3DVSD_CONST(ConstantAddress, Count); +#ifdef CXBX_USE_D3D9 + // TODO +#else + *pRecompiled = D3DVSD_CONST(ConstantAddress, Count); +#endif for (uint i = 0; i < Count; i++) { + pToken++; + pRecompiled++; + DbgVshPrintf("\t0x%08X,\n", pToken); +#ifdef CXBX_USE_D3D9 + // TODO +#else + *pRecompiled = *pToken; +#endif } + return Count; } @@ -1903,10 +1917,18 @@ static void VshConvertToken_STREAM( CxbxVertexShaderPatch *pPatchData ) { + using namespace XTL; + // D3DVSD_STREAM_TESS if(*pToken & X_D3DVSD_STREAMTESSMASK) { DbgVshPrintf("\tD3DVSD_STREAM_TESS(),\n"); + +#ifdef CXBX_USE_D3D9 + // TODO +#else + *pRecompiled = D3DVSD_STREAM_TESS(); +#endif } // D3DVSD_STREAM else @@ -1924,7 +1946,13 @@ static void VshConvertToken_STREAM( // Dxbx note : Use Dophin(s), FieldRender, MatrixPaletteSkinning and PersistDisplay as a testcase DbgVshPrintf("\tD3DVSD_STREAM(%u),\n", StreamNumber); - + +#ifdef CXBX_USE_D3D9 + // TODO +#else + *pRecompiled = D3DVSD_STREAM(StreamNumber); +#endif + pPatchData->pVertexShaderInfoToSet->NumberOfVertexStreams++; // TODO : Keep a bitmask for all StreamNumber's seen? } @@ -1939,7 +1967,12 @@ static void VshConvertToken_STREAMDATA_SKIP( XTL::DWORD SkipCount = (*pToken & X_D3DVSD_SKIPCOUNTMASK) >> X_D3DVSD_SKIPCOUNTSHIFT; DbgVshPrintf("\tD3DVSD_SKIP(%d),\n", SkipCount); - // No need to convert; D3DVSD_SKIP is encoded identically on host Direct3D8. +#ifdef CXBX_USE_D3D9 + // TODO : Expand on the setting of this TESSNORMAL output register element : +#else + // D3DVSD_SKIP is encoded identically on host Direct3D8. + *pRecompiled = D3DVSD_SKIP(SkipCount); +#endif } static void VshConvertToken_STREAMDATA_SKIPBYTES( @@ -1950,12 +1983,17 @@ static void VshConvertToken_STREAMDATA_SKIPBYTES( using namespace XTL; XTL::DWORD SkipBytesCount = (*pToken & X_D3DVSD_SKIPCOUNTMASK) >> X_D3DVSD_SKIPCOUNTSHIFT; + DbgVshPrintf("\tD3DVSD_SKIPBYTES(%d), /* xbox ext. */\n", SkipBytesCount); - if(SkipBytesCount % sizeof(XTL::DWORD)) - { + if (SkipBytesCount % sizeof(XTL::DWORD)) { EmuWarning("D3DVSD_SKIPBYTES can't be converted to D3DVSD_SKIP, not divisble by 4."); } - *pToken = D3DVSD_SKIP(SkipBytesCount / sizeof(XTL::DWORD)); + +#ifdef CXBX_USE_D3D9 + // TODO +#else + *pRecompiled = D3DVSD_SKIP(SkipBytesCount / sizeof(XTL::DWORD)); +#endif } static void VshConvertToken_STREAMDATA_REG( @@ -1967,6 +2005,10 @@ static void VshConvertToken_STREAMDATA_REG( { using namespace XTL; +#if CXBX_USE_D3D9 + extern XTL::D3DCAPS g_D3DCaps; +#endif + #if !CXBX_USE_D3D9 // For simpler support for both Direct3D 8 and 9, use these '9' constants in below '8' code paths too: #define D3DDECLTYPE_FLOAT1 D3DVSDT_FLOAT1 #define D3DDECLTYPE_FLOAT2 D3DVSDT_FLOAT2 @@ -2154,7 +2196,8 @@ static void VshConvertToken_STREAMDATA_REG( } NeedPatching = TRUE; break; - case X_D3DVSDT_PBYTE4: // 0x44: // Hit by Panzer + case X_D3DVSDT_PBYTE4: // 0x44: + // Test-case : Panzer #if CXBX_USE_D3D9 if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) { DbgVshPrintf("D3DVSDT_PBYTE4"); @@ -2194,7 +2237,11 @@ static void VshConvertToken_STREAMDATA_REG( pPatchData->pCurrentVertexShaderStreamInfo->NumberOfVertexElements++; pPatchData->pCurrentVertexShaderStreamInfo->NeedPatch |= NeedPatching; - *pToken = D3DVSD_REG(HostVertexRegister, HostVertexElementDataType); +#ifdef CXBX_USE_D3D9 + // TODO +#else + *pRecompiled = D3DVSD_REG(HostVertexRegister, HostVertexElementDataType); +#endif pPatchData->pCurrentVertexShaderStreamInfo->HostVertexStride += HostVertexElementByteSize; @@ -2242,25 +2289,25 @@ static DWORD VshRecompileToken( switch(VshGetTokenType(*pToken)) { - case D3DVSD_TOKEN_NOP: + case X_D3DVSD_TOKEN_NOP: VshConvertToken_NOP(pToken, pRecompiled); break; - case D3DVSD_TOKEN_STREAM: + case X_D3DVSD_TOKEN_STREAM: { VshConvertToken_STREAM(pToken, pRecompiled, pPatchData); break; } - case D3DVSD_TOKEN_STREAMDATA: + case X_D3DVSD_TOKEN_STREAMDATA: { VshConvertToken_STREAMDATA(pToken, pRecompiled, IsFixedFunction, pPatchData); break; } - case D3DVSD_TOKEN_TESSELLATOR: + case X_D3DVSD_TOKEN_TESSELLATOR: { VshConvertToken_TESSELATOR(pToken, pRecompiled, IsFixedFunction); break; } - case D3DVSD_TOKEN_CONSTMEM: + case X_D3DVSD_TOKEN_CONSTMEM: { Step = VshConvertToken_CONSTMEM(pToken, pRecompiled); break; @@ -2360,10 +2407,10 @@ extern HRESULT XTL::EmuRecompileVshFunction bool declaredRegisters[13]; DWORD* pDeclToken = pRecompiledDeclaration; do { - DWORD regNum = *pDeclToken & D3DVSD_VERTEXREGMASK; + DWORD regNum = *pDeclToken & X_D3DVSD_VERTEXREGMASK; declaredRegisters[regNum] = true; pDeclToken++; - } while (*pDeclToken != D3DVSD_END()); + } while (*pDeclToken != X_D3DVSD_END()); // TODO: support this situation.. if(pFunction == NULL) diff --git a/src/CxbxKrnl/EmuD3D8Types.h b/src/CxbxKrnl/EmuD3D8Types.h index 6d81bc250..fcb47e11f 100755 --- a/src/CxbxKrnl/EmuD3D8Types.h +++ b/src/CxbxKrnl/EmuD3D8Types.h @@ -1208,6 +1208,18 @@ const int MAX_NBR_STREAMS = 16; typedef WORD INDEX16; +typedef enum _X_D3DVSD_TOKENTYPE +{ + X_D3DVSD_TOKEN_NOP = 0, // NOP or extension + X_D3DVSD_TOKEN_STREAM, // stream selector + X_D3DVSD_TOKEN_STREAMDATA, // stream data definition (map to vertex input memory) + X_D3DVSD_TOKEN_TESSELLATOR, // vertex input memory from tessellator + X_D3DVSD_TOKEN_CONSTMEM, // constant memory from shader + X_D3DVSD_TOKEN_EXT, // extension + X_D3DVSD_TOKEN_END = 7, // end-of-array (requires all DWORD bits to be 1) + X_D3DVSD_FORCE_DWORD = 0x7fffffff,// force 32-bit size enum +} X_D3DVSD_TOKENTYPE; + #define X_D3DVSD_TOKENTYPESHIFT 29 #define X_D3DVSD_TOKENTYPEMASK (7 << X_D3DVSD_TOKENTYPESHIFT) @@ -1244,4 +1256,6 @@ typedef WORD INDEX16; #define X_D3DVSD_EXTINFOSHIFT 0 #define X_D3DVSD_EXTINFOMASK (0xFFFFFF << X_D3DVSD_EXTINFOSHIFT) +#define X_D3DVSD_END() 0xFFFFFFFF + #endif From 3f885fb2025d8da1a11b55e0c34bcd597958ff24 Mon Sep 17 00:00:00 2001 From: PatrickvL Date: Mon, 28 May 2018 16:54:24 +0200 Subject: [PATCH 10/10] D3D9 : More accurate decoding of packed integer to float --- src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp | 31 +++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp b/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp index 12eb186d1..d7e70fd01 100755 --- a/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp +++ b/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp @@ -268,9 +268,19 @@ UINT XTL::CxbxVertexBufferConverter::GetNbrStreams(CxbxDrawContext *pDrawContext return 0; } +inline FLOAT PackedIntToFloat(const int value, const FLOAT PosFactor, const FLOAT NegFactor) +{ + if (value >= 0) { + return ((FLOAT)value) / PosFactor; + } + else { + return ((FLOAT)value) / NegFactor; + } +} + inline FLOAT NormShortToFloat(const SHORT value) { - return ((FLOAT)value) / 32767.0f; + return PackedIntToFloat((int)value, 32767.0f, 32768.0f); } inline FLOAT ByteToFloat(const BYTE value) @@ -507,11 +517,20 @@ void XTL::CxbxVertexBufferConverter::ConvertStream // Test-cases : Dashboard XboxElementByteSize = 1 * sizeof(int32); // Make it FLOAT3 - int32 iPacked = ((int32 *)pXboxVertexAsByte)[0]; - // Cxbx note : to make each component signed, two need to be shifted towards the sign-bit first : - pHostVertexAsFloat[0] = ((FLOAT)((iPacked << 21) >> 21)) / 1023.0f; - pHostVertexAsFloat[1] = ((FLOAT)((iPacked << 10) >> 21)) / 1023.0f; - pHostVertexAsFloat[2] = ((FLOAT)((iPacked) >> 22)) / 511.0f; + union { + int32 value; + struct { + int x : 11; + int y : 11; + int z : 10; + }; + } NormPacked3; + + NormPacked3.value = ((int32 *)pXboxVertexAsByte)[0]; + + pHostVertexAsFloat[0] = PackedIntToFloat(NormPacked3.x, 1023.0f, 1024.f); + pHostVertexAsFloat[1] = PackedIntToFloat(NormPacked3.y, 1023.0f, 1024.f); + pHostVertexAsFloat[2] = PackedIntToFloat(NormPacked3.z, 511.0f, 512.f); break; } case X_D3DVSDT_SHORT1: { // 0x15: