From c9880b4287cde078345b6924a3e002a9447d4040 Mon Sep 17 00:00:00 2001 From: sopskrutt <> Date: Tue, 16 Mar 2004 18:47:34 +0000 Subject: [PATCH] Vertex shader stuff --- Include/Win32/CxbxKrnl/EmuD3D8.h | 9 ++ Include/Win32/CxbxKrnl/EmuD3D8/VertexShader.h | 4 +- Source/Win32/CxbxKrnl/EmuD3D8.cpp | 91 +++++++++++++------ .../Win32/CxbxKrnl/EmuD3D8/VertexShader.cpp | 60 +++++++++--- .../CxbxKrnl/HLEDataBase/D3D8.1.0.4627.inl | 32 +++++++ 5 files changed, 158 insertions(+), 38 deletions(-) diff --git a/Include/Win32/CxbxKrnl/EmuD3D8.h b/Include/Win32/CxbxKrnl/EmuD3D8.h index 0958eba10..44693fd78 100644 --- a/Include/Win32/CxbxKrnl/EmuD3D8.h +++ b/Include/Win32/CxbxKrnl/EmuD3D8.h @@ -1103,6 +1103,15 @@ BYTE* WINAPI EmuIDirect3DVertexBuffer8_Lock2 DWORD Flags ); +// ****************************************************************** +// * func: EmuIDirect3DDevice8_GetStreamSource2 +// ****************************************************************** +XTL::X_D3DVertexBuffer* WINAPI EmuIDirect3DDevice8_GetStreamSource2 +( + UINT StreamNumber, + UINT *pStride +); + // ****************************************************************** // * func: EmuIDirect3DDevice8_SetStreamSource // ****************************************************************** diff --git a/Include/Win32/CxbxKrnl/EmuD3D8/VertexShader.h b/Include/Win32/CxbxKrnl/EmuD3D8/VertexShader.h index b38ec83da..2804c9de0 100644 --- a/Include/Win32/CxbxKrnl/EmuD3D8/VertexShader.h +++ b/Include/Win32/CxbxKrnl/EmuD3D8/VertexShader.h @@ -34,7 +34,7 @@ #ifndef VERTEXSHADER_H #define VERTEXSHADER_H -//#define _DEBUG_VSH +#define _DEBUG_VSH // nv2a microcode header typedef struct @@ -68,6 +68,8 @@ extern HRESULT EmuRecompileVshFunction boolean bNoReservedConstants ); +extern void FreeVertexDynamicPatch(VERTEX_SHADER *pVertexShader); + inline boolean VshHandleIsVertexShader(DWORD Handle) { return (Handle & 0x80000000) ? TRUE : FALSE; } inline X_D3DVertexShader *VshHandleGetVertexShader(DWORD Handle) { return (X_D3DVertexShader *)(Handle & 0x7FFFFFFF); } diff --git a/Source/Win32/CxbxKrnl/EmuD3D8.cpp b/Source/Win32/CxbxKrnl/EmuD3D8.cpp index f8b809849..48c09fbd2 100644 --- a/Source/Win32/CxbxKrnl/EmuD3D8.cpp +++ b/Source/Win32/CxbxKrnl/EmuD3D8.cpp @@ -2095,7 +2095,7 @@ HRESULT WINAPI XTL::EmuIDirect3DDevice8_CreateVertexShader pFunction == NULL, &pVertexShader->VertexDynamicPatch); - if(SUCCEEDED(hRet)) + if(SUCCEEDED(hRet) && pFunction) { hRet = XTL::EmuRecompileVshFunction((DWORD*)pFunction, &pRecompiledBuffer, @@ -2105,6 +2105,12 @@ HRESULT WINAPI XTL::EmuIDirect3DDevice8_CreateVertexShader { pRecompiledFunction = (DWORD*)pRecompiledBuffer->GetBufferPointer(); } + else + { + pRecompiledFunction = NULL; + EmuWarning("Couldn't recompile vertex shader function.\n"); + hRet = D3D_OK; // Try using a fixed function vertex shader instead + } } //DbgPrintf("MaxVertexShaderConst = %d\n", g_D3DCaps.MaxVertexShaderConst); @@ -2121,9 +2127,21 @@ HRESULT WINAPI XTL::EmuIDirect3DDevice8_CreateVertexShader if(pRecompiledBuffer) { pRecompiledBuffer->Release(); + pRecompiledBuffer = NULL; } } + free(pRecompiledDeclaration); + + pVertexShader->pDeclaration = (DWORD*)malloc(DeclarationSize); + memcpy(pVertexShader->pDeclaration, pDeclaration, DeclarationSize); + + pVertexShader->FunctionSize = 0; + pVertexShader->pFunction = NULL; + pVertexShader->Type = X_D3DSMT_VERTEXSHADER; + pVertexShader->Size = (VertexShaderSize - sizeof(VSH_SHADER_HEADER)) / VSH_INSTRUCTION_SIZE_BYTES; + pVertexShader->DeclarationSize = DeclarationSize; + if(SUCCEEDED(hRet)) { if(pFunction != NULL) @@ -2137,39 +2155,38 @@ HRESULT WINAPI XTL::EmuIDirect3DDevice8_CreateVertexShader pVertexShader->pFunction = NULL; pVertexShader->FunctionSize = 0; } - pVertexShader->pDeclaration = (DWORD*)malloc(DeclarationSize); - memcpy(pVertexShader->pDeclaration, pDeclaration, DeclarationSize); - pVertexShader->Type = X_D3DSMT_VERTEXSHADER; pVertexShader->Handle = Handle; - pVertexShader->Size = (VertexShaderSize - sizeof(VSH_SHADER_HEADER)) / VSH_INSTRUCTION_SIZE_BYTES; - pVertexShader->DeclarationSize = DeclarationSize; } else { - pVertexShader->Handle = D3DFVF_XYZ/* | D3DFVF_TEX0*/; + pVertexShader->Handle = D3DFVF_XYZ | D3DFVF_TEX0; } + pD3DVertexShader->Handle = (DWORD)pVertexShader; *pHandle = ((DWORD)pD3DVertexShader) | 0x80000000; -#ifdef _DEBUG_VSH if(FAILED(hRet)) { - char pFileName[30]; - static int FailedShaderCount = 0; - VSH_SHADER_HEADER *pHeader = (VSH_SHADER_HEADER*)pFunction; - EmuWarning("Couldn't create vertex shader!"); - sprintf(pFileName, "failed%05d.xvu", FailedShaderCount); - FILE *f = fopen(pFileName, "wb"); - if(f) +#ifdef _DEBUG_VSH + if (pFunction) { - fwrite(pFunction, sizeof(VSH_SHADER_HEADER) + pHeader->NumInst * 16, 1, f); - fclose(f); + char pFileName[30]; + static int FailedShaderCount = 0; + VSH_SHADER_HEADER *pHeader = (VSH_SHADER_HEADER*)pFunction; + EmuWarning("Couldn't create vertex shader!"); + sprintf(pFileName, "failed%05d.xvu", FailedShaderCount); + FILE *f = fopen(pFileName, "wb"); + if(f) + { + fwrite(pFunction, sizeof(VSH_SHADER_HEADER) + pHeader->NumInst * 16, 1, f); + fclose(f); + } + FailedShaderCount++; } - FailedShaderCount++; - //hRet = D3D_OK; - } #endif // _DEBUG_VSH + hRet = D3D_OK; + } EmuSwapFS(); // XBox FS @@ -6048,6 +6065,33 @@ BYTE* WINAPI XTL::EmuIDirect3DVertexBuffer8_Lock2 return pbData; } +// ****************************************************************** +// * func: EmuIDirect3DDevice8_GetStreamSource2 +// ****************************************************************** +XTL::X_D3DVertexBuffer* WINAPI XTL::EmuIDirect3DDevice8_GetStreamSource2 +( + UINT StreamNumber, + UINT *pStride +) +{ + EmuSwapFS(); + + // debug trace + DbgPrintf( "EmuD3D8 (0x%.08X): EmuIDirect3DDevice8_GetStreamSource2\n" + "(\n" + " StreamNumber : 0x%.08X\n" + " pStride : 0x%.08X\n" + ");\n", + GetCurrentThreadId(), StreamNumber, pStride); + + EmuWarning("Not correctly implemented yet!"); + X_D3DVertexBuffer* pVertexBuffer; + g_pD3DDevice8->GetStreamSource(StreamNumber, (struct XTL::IDirect3DVertexBuffer8 **)&pVertexBuffer, pStride); + + EmuSwapFS(); + return pVertexBuffer; +} + // ****************************************************************** // * func: EmuIDirect3DDevice8_SetStreamSource // ****************************************************************** @@ -6764,13 +6808,8 @@ VOID WINAPI XTL::EmuIDirect3DDevice8_DeleteVertexShader free(pVertexShader->pFunction); } - // TODO: Also free the dynamic streams patches! - for(DWORD i = 0; i < pVertexShader->VertexDynamicPatch.NbrStreams; i++) - { - free(pVertexShader->VertexDynamicPatch.pStreamPatches[i].pTypes); - } + FreeVertexDynamicPatch(pVertexShader); - free(pVertexShader->VertexDynamicPatch.pStreamPatches); free(pVertexShader); free(pD3DVertexShader); } diff --git a/Source/Win32/CxbxKrnl/EmuD3D8/VertexShader.cpp b/Source/Win32/CxbxKrnl/EmuD3D8/VertexShader.cpp index 4bc1ad767..5764be0a8 100644 --- a/Source/Win32/CxbxKrnl/EmuD3D8/VertexShader.cpp +++ b/Source/Win32/CxbxKrnl/EmuD3D8/VertexShader.cpp @@ -461,8 +461,8 @@ static inline boolean HasMACO(VSH_SHADER_INSTRUCTION *pInstruction) static inline boolean HasMACARL(VSH_SHADER_INSTRUCTION *pInstruction) { - return !IsInUse(pInstruction->Output.OutputMask) && - pInstruction->Output.OutputMux == OMUX_MAC && + return /*!IsInUse(pInstruction->Output.OutputMask) && + pInstruction->Output.OutputMux == OMUX_MAC &&*/ pInstruction->MAC == MAC_ARL; } @@ -852,6 +852,8 @@ static VSH_INTERMEDIATE_FORMAT *VshNewIntermediate(VSH_XBOX_SHADER *pShader) { VshVerifyBufferBounds(pShader); + ZeroMemory(&pShader->Intermediate[pShader->IntermediateCount], sizeof(VSH_INTERMEDIATE_FORMAT)); + return &pShader->Intermediate[pShader->IntermediateCount++]; } @@ -1185,6 +1187,13 @@ static boolean VshConvertShader(VSH_XBOX_SHADER *pShader, // Combining not supported in vs.1.1 pIntermediate->IsCombined = FALSE; + /* + if(pIntermediate->Output.Type == IMD_OUTPUT_O && pIntermediate->Output.Address == OREG_OFOG) + { + // The PC shader assembler doesn't like masks on scalar registers + VshSetOutputMask(&pIntermediate->Output, TRUE, TRUE, TRUE, TRUE); + }*/ + if(pIntermediate->InstructionType == IMD_ILU && pIntermediate->ILU == ILU_RCC) { // Convert rcc to rcp @@ -1355,42 +1364,55 @@ DWORD Xb2PCRegisterType(DWORD VertexRegister) case -1: DbgVshPrintf("D3DVSDE_VERTEX /* xbox ext. */"); PCRegisterType = -1; + break; case 0: DbgVshPrintf("D3DVSDE_POSITION"); PCRegisterType = D3DVSDE_POSITION; + break; case 1: DbgVshPrintf("D3DVSDE_BLENDWEIGHT"); PCRegisterType = D3DVSDE_BLENDWEIGHT; + break; case 2: DbgVshPrintf("D3DVSDE_NORMAL"); PCRegisterType = D3DVSDE_NORMAL; + break; case 3: DbgVshPrintf("D3DVSDE_DIFFUSE"); PCRegisterType = D3DVSDE_DIFFUSE; + break; case 4: DbgVshPrintf("D3DVSDE_SPECULAR"); PCRegisterType = D3DVSDE_SPECULAR; + break; case 5: DbgVshPrintf("D3DVSDE_FOG /* xbox ext. */"); PCRegisterType = -1; + break; case 7: DbgVshPrintf("D3DVSDE_BACKDIFFUSE /* xbox ext. */"); PCRegisterType = -1; + break; case 8: DbgVshPrintf("D3DVSDE_BACKSPECULAR /* xbox ext. */"); PCRegisterType = -1; + break; case 9: DbgVshPrintf("D3DVSDE_TEXCOORD0"); PCRegisterType = D3DVSDE_TEXCOORD0; + break; case 10: DbgVshPrintf("D3DVSDE_TEXCOORD1"); PCRegisterType = D3DVSDE_TEXCOORD1; + break; case 11: DbgVshPrintf("D3DVSDE_TEXCOORD2"); PCRegisterType = D3DVSDE_TEXCOORD2; + break; case 12: DbgVshPrintf("D3DVSDE_TEXCOORD3"); PCRegisterType = D3DVSDE_TEXCOORD3; + break; default: DbgVshPrintf("%d /* unknown register */", VertexRegister); PCRegisterType = -1; @@ -1523,9 +1545,9 @@ static boolean VshAddStreamPatch(VSH_PATCH_DATA *pPatchData) pStreamPatch->ConversionStride = pPatchData->ConversionStride; pStreamPatch->NbrTypes = pPatchData->TypePatchData.NbrTypes; - pStreamPatch->NeedPatch = pStreamPatch->NeedPatch; - pStreamPatch->pTypes = (UINT *)malloc(pPatchData->TypePatchData.NbrTypes); - memcpy(pStreamPatch->pTypes, pPatchData->TypePatchData.Types, pPatchData->TypePatchData.NbrTypes); + pStreamPatch->NeedPatch = pPatchData->NeedPatching; + pStreamPatch->pTypes = (UINT *)malloc(pPatchData->TypePatchData.NbrTypes * sizeof(VSH_TYPE_PATCH_DATA)); + memcpy(pStreamPatch->pTypes, pPatchData->TypePatchData.Types, pPatchData->TypePatchData.NbrTypes * sizeof(VSH_TYPE_PATCH_DATA)); return TRUE; } @@ -1927,12 +1949,17 @@ extern HRESULT XTL::EmuRecompileVshFunction DbgVshPrintf("%s", pShaderDisassembly); DbgVshPrintf("-----------------------\n"); - HRESULT Result = D3DXAssembleShader(pShaderDisassembly, - strlen(pShaderDisassembly), - D3DXASM_SKIPVALIDATION, - NULL, - ppRecompiled, - NULL); + hRet = D3DXAssembleShader(pShaderDisassembly, + strlen(pShaderDisassembly), + D3DXASM_SKIPVALIDATION, + NULL, + ppRecompiled, + NULL); + + if (FAILED(hRet)) + { + EmuWarning("Couldn't assemble recompiled vertex shader\n"); + } free(pShaderDisassembly); } @@ -1940,3 +1967,14 @@ extern HRESULT XTL::EmuRecompileVshFunction return hRet; } + +extern void XTL::FreeVertexDynamicPatch(VERTEX_SHADER *pVertexShader) +{ + for (DWORD i = 0; i < pVertexShader->VertexDynamicPatch.NbrStreams; i++) + { + free(pVertexShader->VertexDynamicPatch.pStreamPatches[i].pTypes); + } + free(pVertexShader->VertexDynamicPatch.pStreamPatches); + pVertexShader->VertexDynamicPatch.pStreamPatches = NULL; + pVertexShader->VertexDynamicPatch.NbrStreams = 0; +} \ No newline at end of file diff --git a/Source/Win32/CxbxKrnl/HLEDataBase/D3D8.1.0.4627.inl b/Source/Win32/CxbxKrnl/HLEDataBase/D3D8.1.0.4627.inl index 3cf9f4318..4445013b1 100644 --- a/Source/Win32/CxbxKrnl/HLEDataBase/D3D8.1.0.4627.inl +++ b/Source/Win32/CxbxKrnl/HLEDataBase/D3D8.1.0.4627.inl @@ -2440,6 +2440,28 @@ SOOVPA<8> X_D3DDevice_SetVertexShaderInput_1_0_4627 = } }; +// ****************************************************************** +// * D3DDevice_GetStreamSource2 (Maybe same in older versions) +// ****************************************************************** +SOOVPA<7> X_D3DDevice_GetStreamSource2_1_0_4627 = +{ + 0, // Large == 0 + 7, // Count == 7 + + -1, // Xref Not Saved + 0, // Xref Not Used + + { + { 0x06, 0x34 }, + { 0x12, 0x85 }, + { 0x16, 0x57 }, + { 0x22, 0x8B }, + { 0x26, 0x89 }, + { 0x2E, 0x00 }, + { 0x36, 0x89 }, + } +}; + // ****************************************************************** // * D3D8_1_0_4627 // ****************************************************************** @@ -3131,6 +3153,16 @@ OOVPATable D3D8_1_0_4627[] = "EmuIDirect3DDevice8_GetTransform" #endif }, + // D3DDevice_GetStreamSource2 + { + (OOVPA*)&X_D3DDevice_GetStreamSource2_1_0_4627, + XTL::EmuIDirect3DDevice8_GetStreamSource2, + + #ifdef _DEBUG_TRACE + "D3DDevice_GetStreamSource2" + #endif + + }, // IDirect3DDevice8::SetStreamSource (* unchanged since 4361 *) { (OOVPA*)&IDirect3DDevice8_SetStreamSource_1_0_4361,