From 0bee18f2481080687440d7459c45b89a51b6bad1 Mon Sep 17 00:00:00 2001 From: WinterSnowfall Date: Tue, 19 Nov 2024 20:51:44 +0200 Subject: [PATCH] [d3d8] Partially implement ValidateVertexShader/ValidatePixelShader --- src/d3d8/d3d8_main.cpp | 76 +++++++++++++++++++++++++++++++++--------- 1 file changed, 61 insertions(+), 15 deletions(-) diff --git a/src/d3d8/d3d8_main.cpp b/src/d3d8/d3d8_main.cpp index 13f842e05ac..16951482947 100644 --- a/src/d3d8/d3d8_main.cpp +++ b/src/d3d8/d3d8_main.cpp @@ -19,14 +19,38 @@ extern "C" { const D3DCAPS8* pCaps, BOOL errorReturn, char** pErrorString) { - dxvk::Logger::warn("D3D8: ValidatePixelShader: Stub"); + std::string errorMessage = ""; + + if (unlikely(pPixelShader == nullptr)) { + errorMessage = "D3D8: ValidatePixelShader: Null pPixelShader"; + } else { + uint32_t majorVersion = (pPixelShader[0] >> 8) & 0xff; + uint32_t minorVersion = pPixelShader[0] & 0xff; + + if (unlikely(majorVersion != 1 || minorVersion > 4)) { + errorMessage = dxvk::str::format("D3D8: ValidatePixelShader: Unsupported PS version ", + majorVersion, ".", minorVersion); + } else if (unlikely(pCaps && pPixelShader[0] > pCaps->PixelShaderVersion)) { + errorMessage = dxvk::str::format("D3D8: ValidatePixelShader: Caps: Unsupported PS version ", + majorVersion, ".", minorVersion); + } + } - if (unlikely(pPixelShader == nullptr)) - return E_FAIL; + const size_t errorMessageSize = errorMessage.size() + 1; + +#ifdef _WIN32 + if (pErrorString != nullptr && errorReturn) { + // Wine tests call HeapFree() on the returned error string, + // so the expectation is for it to be allocated on the heap. + *pErrorString = (char*) HeapAlloc(GetProcessHeap(), 0, errorMessageSize); + if (*pErrorString) + memcpy(*pErrorString, errorMessage.c_str(), errorMessageSize); + } +#endif - if (errorReturn && pErrorString != nullptr) { - const char* errorMessage = ""; - *pErrorString = (char *) errorMessage; + if (errorMessageSize > 1) { + dxvk::Logger::warn(errorMessage); + return E_FAIL; } return S_OK; @@ -38,22 +62,44 @@ extern "C" { const D3DCAPS8* pCaps, BOOL errorReturn, char** pErrorString) { - dxvk::Logger::warn("D3D8: ValidateVertexShader: Stub"); + std::string errorMessage = ""; + + if (unlikely(pVertexShader == nullptr)) { + errorMessage = "D3D8: ValidateVertexShader: Null pVertexShader"; + } else { + uint32_t majorVersion = (pVertexShader[0] >> 8) & 0xff; + uint32_t minorVersion = pVertexShader[0] & 0xff; + + if (unlikely(majorVersion != 1 || minorVersion > 1)) { + errorMessage = dxvk::str::format("D3D8: ValidateVertexShader: Unsupported VS version ", + majorVersion, ".", minorVersion); + } else if (unlikely(pCaps && pVertexShader[0] > pCaps->VertexShaderVersion)) { + errorMessage = dxvk::str::format("D3D8: ValidateVertexShader: Caps: Unsupported VS version ", + majorVersion, ".", minorVersion); + } + } - if (unlikely(pVertexShader == nullptr)) - return E_FAIL; + const size_t errorMessageSize = errorMessage.size() + 1; - if (errorReturn && pErrorString != nullptr) { - const char* errorMessage = ""; - *pErrorString = (char *) errorMessage; +#ifdef _WIN32 + if (pErrorString != nullptr && errorReturn) { + // Wine tests call HeapFree() on the returned error string, + // so the expectation is for it to be allocated on the heap. + *pErrorString = (char*) HeapAlloc(GetProcessHeap(), 0, errorMessageSize); + if (*pErrorString) + memcpy(*pErrorString, errorMessage.c_str(), errorMessageSize); + } +#endif + + if (errorMessageSize > 1) { + dxvk::Logger::warn(errorMessage); + return E_FAIL; } return S_OK; } - DLLEXPORT void __stdcall DebugSetMute() { - dxvk::Logger::debug("D3D8: DebugSetMute: Stub"); - } + DLLEXPORT void __stdcall DebugSetMute() {} DLLEXPORT IDirect3D8* __stdcall Direct3DCreate8(UINT nSDKVersion) { IDirect3D8* pDirect3D = nullptr;