diff --git a/Include/Win32/CxbxKrnl/EmuD3D8/VertexShader.h b/Include/Win32/CxbxKrnl/EmuD3D8/VertexShader.h index e12532e87..361dd3138 100644 --- a/Include/Win32/CxbxKrnl/EmuD3D8/VertexShader.h +++ b/Include/Win32/CxbxKrnl/EmuD3D8/VertexShader.h @@ -70,6 +70,9 @@ extern HRESULT EmuRecompileVshFunction extern void FreeVertexDynamicPatch(VERTEX_SHADER *pVertexShader); +// Checks for failed vertex shaders, and shaders that would need patching +extern boolean IsValidCurrentShader(void); + inline boolean VshHandleIsVertexShader(DWORD Handle) { return (Handle & 0x80000000) ? TRUE : FALSE; } inline X_D3DVertexShader *VshHandleGetVertexShader(DWORD Handle) { return (X_D3DVertexShader *)(Handle & 0x7FFFFFFF); } diff --git a/Include/Win32/CxbxKrnl/EmuD3D8Types.h b/Include/Win32/CxbxKrnl/EmuD3D8Types.h index d5e014734..02d62463f 100644 --- a/Include/Win32/CxbxKrnl/EmuD3D8Types.h +++ b/Include/Win32/CxbxKrnl/EmuD3D8Types.h @@ -141,6 +141,7 @@ typedef struct _VERTEX_SHADER DWORD *pFunction; DWORD FunctionSize; DWORD Type; + DWORD Status; // Needed for dynamic stream patching VERTEX_DYNAMIC_PATCH VertexDynamicPatch; diff --git a/Source/Win32/CxbxKrnl/EmuD3D8.cpp b/Source/Win32/CxbxKrnl/EmuD3D8.cpp index 1fe6f1261..9b6af482c 100644 --- a/Source/Win32/CxbxKrnl/EmuD3D8.cpp +++ b/Source/Win32/CxbxKrnl/EmuD3D8.cpp @@ -2141,6 +2141,8 @@ HRESULT WINAPI XTL::EmuIDirect3DDevice8_CreateVertexShader pRecompiledBuffer = NULL; } } + // Save the status, to remove things later + pVertexShader->Status = hRet; CxbxFree(pRecompiledDeclaration); @@ -6026,28 +6028,31 @@ VOID WINAPI XTL::EmuIDirect3DDevice8_DrawVertices uint32 nStride = EmuFixupVerticesA(PrimitiveType, PrimitiveCount, pOrigVertexBuffer8, pHackVertexBuffer8, StartVertex, 0, 0, 0); - #ifdef _DEBUG_TRACK_VB - if(g_bVBSkipStream) + if (IsValidCurrentShader()) { - g_pD3DDevice8->DrawPrimitive - ( - PCPrimitiveType, - StartVertex, - 0 - ); + #ifdef _DEBUG_TRACK_VB + if(g_bVBSkipStream) + { + g_pD3DDevice8->DrawPrimitive + ( + PCPrimitiveType, + StartVertex, + 0 + ); + } + else + { + #endif + g_pD3DDevice8->DrawPrimitive + ( + PCPrimitiveType, + StartVertex, + PrimitiveCount + ); + #ifdef _DEBUG_TRACK_VB + } + #endif } - else - { - #endif - g_pD3DDevice8->DrawPrimitive - ( - PCPrimitiveType, - StartVertex, - PrimitiveCount - ); - #ifdef _DEBUG_TRACK_VB - } - #endif // TODO: use original stride here (duh!) if(nStride != -1) @@ -6098,22 +6103,25 @@ VOID WINAPI XTL::EmuIDirect3DDevice8_DrawVerticesUP uint32 nStride = EmuFixupVerticesA(PrimitiveType, PrimitiveCount, pOrigVertexBuffer8, pHackVertexBuffer8, 0, pVertexStreamZeroData, VertexStreamZeroStride, &pNewVertexStreamZeroData); - #ifdef _DEBUG_TRACK_VB - if(!g_bVBSkipStream) + if (IsValidCurrentShader()) { - #endif + #ifdef _DEBUG_TRACK_VB + if(!g_bVBSkipStream) + { + #endif - g_pD3DDevice8->DrawPrimitiveUP - ( - PCPrimitiveType, - PrimitiveCount, - pNewVertexStreamZeroData, - VertexStreamZeroStride - ); + g_pD3DDevice8->DrawPrimitiveUP + ( + PCPrimitiveType, + PrimitiveCount, + pNewVertexStreamZeroData, + VertexStreamZeroStride + ); - #ifdef _DEBUG_TRACK_VB + #ifdef _DEBUG_TRACK_VB + } + #endif } - #endif if(nStride != -1) { @@ -6248,10 +6256,13 @@ VOID WINAPI XTL::EmuIDirect3DDevice8_DrawIndexedVertices uiStartIndex = ((DWORD)pIndexData)/2; } - g_pD3DDevice8->DrawIndexedPrimitive - ( - PCPrimitiveType, 0, uiNumVertices, uiStartIndex, PrimitiveCount - ); + if (IsValidCurrentShader()) + { + g_pD3DDevice8->DrawIndexedPrimitive + ( + PCPrimitiveType, 0, uiNumVertices, uiStartIndex, PrimitiveCount + ); + } if(!bActiveIB) { @@ -6321,10 +6332,13 @@ VOID WINAPI XTL::EmuIDirect3DDevice8_DrawIndexedVerticesUP { #endif - g_pD3DDevice8->DrawIndexedPrimitiveUP - ( - PCPrimitiveType, 0, VertexCount, PrimitiveCount, pIndexData, D3DFMT_INDEX16, pNewVertexStreamZeroData, VertexStreamZeroStride - ); + if (IsValidCurrentShader()) + { + g_pD3DDevice8->DrawIndexedPrimitiveUP + ( + PCPrimitiveType, 0, VertexCount, PrimitiveCount, pIndexData, D3DFMT_INDEX16, pNewVertexStreamZeroData, VertexStreamZeroStride + ); + } #ifdef _DEBUG_TRACK_VB } diff --git a/Source/Win32/CxbxKrnl/EmuD3D8/PushBuffer.cpp b/Source/Win32/CxbxKrnl/EmuD3D8/PushBuffer.cpp index ba1ddb418..b9b36b5cb 100644 --- a/Source/Win32/CxbxKrnl/EmuD3D8/PushBuffer.cpp +++ b/Source/Win32/CxbxKrnl/EmuD3D8/PushBuffer.cpp @@ -241,10 +241,13 @@ void XTL::EmuExecutePushBuffer if(!g_bPBSkipPusher) { - g_pD3DDevice8->DrawIndexedPrimitive - ( - PCPrimitiveType, 0, dwCount*2, 0, EmuD3DVertex2PrimitiveCount(XBPrimitiveType, dwCount*2) - ); + if (IsValidCurrentShader()) + { + g_pD3DDevice8->DrawIndexedPrimitive + ( + PCPrimitiveType, 0, dwCount*2, 0, EmuD3DVertex2PrimitiveCount(XBPrimitiveType, dwCount*2) + ); + } } #ifdef _DEBUG_TRACK_PB diff --git a/Source/Win32/CxbxKrnl/EmuD3D8/VertexShader.cpp b/Source/Win32/CxbxKrnl/EmuD3D8/VertexShader.cpp index 814c7fbef..ffad386e7 100644 --- a/Source/Win32/CxbxKrnl/EmuD3D8/VertexShader.cpp +++ b/Source/Win32/CxbxKrnl/EmuD3D8/VertexShader.cpp @@ -1976,4 +1976,30 @@ extern void XTL::FreeVertexDynamicPatch(VERTEX_SHADER *pVertexShader) CxbxFree(pVertexShader->VertexDynamicPatch.pStreamPatches); pVertexShader->VertexDynamicPatch.pStreamPatches = NULL; pVertexShader->VertexDynamicPatch.NbrStreams = 0; +} + +extern boolean XTL::IsValidCurrentShader(void) +{ + DWORD Handle; + + EmuIDirect3DDevice8_GetVertexShader(&Handle); + if (VshHandleIsVertexShader(Handle)) + { + X_D3DVertexShader *pD3DVertexShader = (X_D3DVertexShader *)(Handle & 0x7FFFFFFF); + VERTEX_SHADER *pVertexShader = (VERTEX_SHADER *)pD3DVertexShader->Handle; + if (pVertexShader->Status != 0) + { + return FALSE; + } + for (uint32 i = 0; i < pVertexShader->VertexDynamicPatch.NbrStreams; i++) + { + if (pVertexShader->VertexDynamicPatch.pStreamPatches[i].NeedPatch) + { + // Just for caching purposes + pVertexShader->Status = 0x80000001; + return FALSE; + } + } + } + return TRUE; } \ No newline at end of file