From 4ac161da82648979988d617e5679c08db9897be4 Mon Sep 17 00:00:00 2001 From: Luke Usher Date: Wed, 25 Jul 2018 11:23:39 +0100 Subject: [PATCH] Fix compilation of D3D9 build With this, the Debug_Direct3D9 build now compiles and successfully runs basic XDK samples (Gamepad, Tutorials, etc) Known Issues: 1. Vertex Shaders are completely broken, any titles using vertex shaders WILL crash 2. Vertex conversion is completely broken, any titles using Xbox specific data types WILL crash This is NOT ready for use in any shape or form, just a step towards the eventual D3D9 port. --- build/win32/Cxbx.vcxproj | 7 +- build/win32/Cxbx.vcxproj.filters | 1 - src/CxbxKrnl/EmuD3D8.cpp | 92 +++++++++++++++++++++------ src/CxbxKrnl/EmuD3D8/PixelShader.cpp | 6 +- src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp | 6 +- src/CxbxKrnl/EmuD3D8/VertexShader.cpp | 9 ++- src/CxbxKrnl/EmuD3D8Types.h | 8 ++- 7 files changed, 98 insertions(+), 31 deletions(-) diff --git a/build/win32/Cxbx.vcxproj b/build/win32/Cxbx.vcxproj index 322a89925..94b4394ee 100644 --- a/build/win32/Cxbx.vcxproj +++ b/build/win32/Cxbx.vcxproj @@ -179,9 +179,9 @@ Include\Win32\Cxbx;%(AdditionalIncludeDirectories) - legacy_stdio_definitions.lib;d3d8.lib;dinput8.lib;dxguid.lib;odbc32.lib;odbccp32.lib;Shlwapi.lib;dxerr8.lib;ws2_32.lib;dsound.lib;winmm.lib;ddraw.lib;d3dx8.lib;dbghelp.lib;comctl32.lib;XINPUT9_1_0.LIB;%(AdditionalDependencies) + legacy_stdio_definitions.lib;d3d9.lib;dinput8.lib;dxguid.lib;odbc32.lib;odbccp32.lib;Shlwapi.lib;dxerr9.lib;ws2_32.lib;dsound.lib;winmm.lib;ddraw.lib;d3dx9.lib;dbghelp.lib;comctl32.lib;XINPUT9_1_0.LIB;%(AdditionalDependencies) true - $(Configuration)\;..\..\import\distorm\lib\Win32\;..\..\import\glew-2.0.0\lib\Release\Win32\;%(AdditionalLibraryDirectories) + $(Configuration)\;..\..\import\distorm\lib\Win32\;..\..\import\glew-2.0.0\lib\Release\Win32\;..\..\import\DirectX9\lib\;%(AdditionalLibraryDirectories) libcmt;%(IgnoreSpecificDefaultLibraries) true true @@ -740,6 +740,9 @@ + + {b8d9afc2-b38f-4714-846d-8a2754f076c9} + {cd2dde93-b45e-4d11-876d-d0056c3dd407} diff --git a/build/win32/Cxbx.vcxproj.filters b/build/win32/Cxbx.vcxproj.filters index 7c335b606..d5b56ec69 100644 --- a/build/win32/Cxbx.vcxproj.filters +++ b/build/win32/Cxbx.vcxproj.filters @@ -571,7 +571,6 @@ Emulator - diff --git a/src/CxbxKrnl/EmuD3D8.cpp b/src/CxbxKrnl/EmuD3D8.cpp index c36a315d9..7199cdc13 100644 --- a/src/CxbxKrnl/EmuD3D8.cpp +++ b/src/CxbxKrnl/EmuD3D8.cpp @@ -130,7 +130,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 +XTL::D3DCAPS g_D3DCaps = {}; // Direct3D Caps // wireframe toggle static int g_iWireframe = 0; @@ -1971,6 +1971,10 @@ static DWORD WINAPI EmuCreateDeviceProxy(LPVOID) // NOTE: It is possible to fix multisampling by having the host backbuffer normal size, the Xbox backbuffer being multisamples // and scaling that way, but that can be done as a future PR g_EmuCDPD.HostPresentationParameters.MultiSampleType = XTL::D3DMULTISAMPLE_NONE; +#ifdef CXBX_USE_D3D9 + g_EmuCDPD.HostPresentationParameters.MultiSampleQuality = 0; +#endif + /* if(g_EmuCDPD.XboxPresentationParameters.MultiSampleType != 0) { // TODO: Check card for multisampling abilities @@ -2056,17 +2060,22 @@ static DWORD WINAPI EmuCreateDeviceProxy(LPVOID) // Dxbx addition : Prevent Direct3D from changing the FPU Control word : g_EmuCDPD.BehaviorFlags |= D3DCREATE_FPU_PRESERVE; - // Address debug DirectX runtime warning in _DEBUG builds // Direct3D8: (WARN) :Device that was created without D3DCREATE_MULTITHREADED is being used by a thread other than the creation thread. - #ifdef _DEBUG - g_EmuCDPD.BehaviorFlags |= D3DCREATE_MULTITHREADED; - #endif + g_EmuCDPD.BehaviorFlags |= D3DCREATE_MULTITHREADED; // For some reason, D3DFMT_D16_LOCKABLE as the AudoDepthStencil causes CreateDevice to fail... + g_EmuCDPD.HostPresentationParameters.EnableAutoDepthStencil = TRUE; if (g_EmuCDPD.HostPresentationParameters.AutoDepthStencilFormat == XTL::D3DFMT_D16_LOCKABLE) { g_EmuCDPD.HostPresentationParameters.AutoDepthStencilFormat = XTL::D3DFMT_D16; } + // DirectX9 doesn't support 0 as a swap effect +#ifdef CXBX_USE_D3D9 + if (g_EmuCDPD.HostPresentationParameters.SwapEffect == 0) { + g_EmuCDPD.HostPresentationParameters.SwapEffect = XTL::D3DSWAPEFFECT_DISCARD; + } +#endif + // redirect to windows Direct3D g_EmuCDPD.hRet = g_pDirect3D->CreateDevice( g_EmuCDPD.Adapter, @@ -2968,9 +2977,15 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SelectVertexShader) if(VshHandleIsVertexShader(Handle)) { + #ifndef CXBX_USE_D3D9 + CxbxVertexShader *pVertexShader = MapXboxVertexShaderHandleToCxbxVertexShader(Handle); hRet = g_pD3DDevice->SetVertexShader(pVertexShader->Handle); DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetVertexShader(VshHandleIsVertexShader)"); + #else + hRet = D3D_OK; + EmuWarning("SetVertexShader (non-FVF) unimplemented for D3D9"); + #endif } else if(Handle == NULL) { @@ -2988,8 +3003,13 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SelectVertexShader) if(pVertexShader != NULL) { +#ifndef CXBX_USE_D3D9 hRet = g_pD3DDevice->SetVertexShader(((CxbxVertexShader *)((X_D3DVertexShader *)g_VertexShaderSlots[Address])->Handle)->Handle); DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetVertexShader(pVertexShader)"); +#else + hRet = D3D_OK; + EmuWarning("SetVertexShader (non-FVF) unimplemented for D3D9"); +#endif } else { @@ -3471,6 +3491,7 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateVertexShader) DWORD Usage ) { +#ifndef CXBX_USE_D3D9 FUNC_EXPORTS LOG_FUNC_BEGIN @@ -3555,10 +3576,16 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateVertexShader) { hRet = g_pD3DDevice->CreateVertexShader ( +#ifndef CXBX_USE_D3D9 pRecompiledDeclaration, +#endif pRecompiledFunction, - &Handle, - g_dwVertexShaderUsage // TODO: HACK: Xbox has extensions! +#ifdef CXBX_USE_D3D9 + (IDirect3DVertexShader9**)&Handle +#else + &Handle, + g_dwVertexShaderUsage // TODO: HACK: Xbox has extensions! +#endif ); DEBUG_D3DRESULT(hRet, "g_pD3DDevice->CreateVertexShader"); @@ -3589,11 +3616,17 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateVertexShader) hRet = g_pD3DDevice->CreateVertexShader ( - pRecompiledDeclaration, - (DWORD*)pRecompiledBuffer->GetBufferPointer(), - &Handle, - g_dwVertexShaderUsage - ); +#ifndef CXBX_USE_D3D9 + pRecompiledDeclaration, +#endif + (DWORD*)pRecompiledBuffer->GetBufferPointer(), +#ifdef CXBX_USE_D3D9 + (IDirect3DVertexShader9**)&Handle +#else + &Handle, + g_dwVertexShaderUsage // TODO: HACK: Xbox has extensions! +#endif + ); DEBUG_D3DRESULT(hRet, "g_pD3DDevice->CreateVertexShader(fallback)"); } //*/ @@ -3661,6 +3694,9 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateVertexShader) return hRet; +#else + return D3D_OK; +#endif } // LTCG specific D3DDevice_SetVertexShaderConstant function... @@ -5040,7 +5076,7 @@ void CreateHostResource(XTL::X_D3DResource *pResource, DWORD D3DUsage, int iText true, // Lockable &pNewHostSurface #ifdef CXBX_USE_D3D9 - , nullptr, // pSharedHandle + , nullptr // pSharedHandle #endif ); DEBUG_D3DRESULT(hRet, "g_pD3DDevice->CreateRenderTarget"); @@ -6979,7 +7015,6 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetVertexShader) HRESULT hRet = D3D_OK; g_CurrentXboxVertexShaderHandle = Handle; - // Store viewport offset and scale in constant registers 58 (c-38) and // 59 (c-37) used for screen space transformation. if(g_VertexShaderConstantMode != X_D3DSCM_NORESERVEDCONSTANTS) @@ -6999,6 +7034,7 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetVertexShader) #endif } +#ifndef CXBX_USE_D3D9 DWORD HostVertexShaderHandle; if(VshHandleIsVertexShader(Handle)) { @@ -7051,12 +7087,22 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetVertexShader) // TODO : Instead of changing the FVF here, see if (and which) users need to be updated. } } - -#ifdef CXBX_USE_D3D9 - hRet = g_pD3DDevice->SetVertexShader(nullptr); - hRet = g_pD3DDevice->SetFVF(HostVertexShaderHandle); -#else hRet = g_pD3DDevice->SetVertexShader(HostVertexShaderHandle); +#else + if (VshHandleIsVertexShader(Handle)) { +#ifndef CXBX_USE_D3D9 + + CxbxVertexShader *pVertexShader = MapXboxVertexShaderHandleToCxbxVertexShader(Handle); + hRet = g_pD3DDevice->SetVertexShader(pVertexShader->Handle); + DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetVertexShader(VshHandleIsVertexShader)"); +#else + hRet = D3D_OK; + EmuWarning("SetVertexShader (non-FVF) unimplemented for D3D9"); +#endif + } else { + hRet = g_pD3DDevice->SetVertexShader(nullptr); + hRet = g_pD3DDevice->SetFVF(Handle); + } #endif DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetVertexShader"); } @@ -8350,6 +8396,7 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_DeleteVertexShader) DWORD Handle ) { +#ifndef CXBX_USE_D3D9 FUNC_EXPORTS LOG_FUNC_ONE_ARG(Handle); @@ -8379,7 +8426,8 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_DeleteVertexShader) } HRESULT hRet = g_pD3DDevice->DeleteVertexShader(HostVertexShaderHandle); - DEBUG_D3DRESULT(hRet, "g_pD3DDevice->DeleteVertexShader"); + DEBUG_D3DRESULT(hRet, "g_pD3DDevice->DeleteVertexShader"); +#endif } // ****************************************************************** @@ -8447,6 +8495,7 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_GetVertexShaderConstant) DWORD ConstantCount ) { +#ifndef CXBX_USE_D3D9 FUNC_EXPORTS LOG_FUNC_BEGIN @@ -8462,7 +8511,8 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_GetVertexShaderConstant) ConstantCount ); - DEBUG_D3DRESULT(hRet, "g_pD3DDevice->GetVertexShaderConstant"); + DEBUG_D3DRESULT(hRet, "g_pD3DDevice->GetVertexShaderConstant"); +#endif } // ****************************************************************** diff --git a/src/CxbxKrnl/EmuD3D8/PixelShader.cpp b/src/CxbxKrnl/EmuD3D8/PixelShader.cpp index 9818d79c8..dbc230b18 100644 --- a/src/CxbxKrnl/EmuD3D8/PixelShader.cpp +++ b/src/CxbxKrnl/EmuD3D8/PixelShader.cpp @@ -4220,7 +4220,11 @@ static const /*pDefines=*/nullptr, /*pInclude=*/nullptr, #endif - /*Flags=*/D3DXASM_SKIPVALIDATION, +#ifndef CXBX_USE_D3D9 + /*Flags=*/D3DXASM_SKIPVALIDATION, +#else + /*Flags=*/0, +#endif #ifndef CXBX_USE_D3D9 /*ppConstants=*/NULL, #endif diff --git a/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp b/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp index 718781dae..2626a7da7 100755 --- a/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp +++ b/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp @@ -990,7 +990,11 @@ VOID XTL::EmuFlushIVB() CxbxDrawPrimitiveUP(DrawContext); if (bFVF) { - hRet = g_pD3DDevice->SetVertexShader(g_CurrentXboxVertexShaderHandle); +#ifdef CXBX_USE_D3D9 + hRet = g_pD3DDevice->SetFVF(g_CurrentXboxVertexShaderHandle); +#else + hRet = g_pD3DDevice->SetVertexShader(g_CurrentXboxVertexShaderHandle); +#endif //DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetVertexShader"); } g_InlineVertexBuffer_TableOffset = 0; // Might not be needed (also cleared in D3DDevice_Begin) diff --git a/src/CxbxKrnl/EmuD3D8/VertexShader.cpp b/src/CxbxKrnl/EmuD3D8/VertexShader.cpp index 5cf956acf..fb619e217 100644 --- a/src/CxbxKrnl/EmuD3D8/VertexShader.cpp +++ b/src/CxbxKrnl/EmuD3D8/VertexShader.cpp @@ -2394,6 +2394,7 @@ extern HRESULT XTL::EmuRecompileVshFunction DWORD *pRecompiledDeclaration ) { +#ifndef CXBX_USE_D3D9 VSH_SHADER_HEADER *pShaderHeader = (VSH_SHADER_HEADER*)pFunction; DWORD *pToken; boolean EOI = false; @@ -2506,10 +2507,9 @@ extern HRESULT XTL::EmuRecompileVshFunction } else { - hRet = D3DXAssembleShader(pShaderDisassembly, strlen(pShaderDisassembly), - D3DXASM_SKIPVALIDATION, + D3DXASM_SKIPVALIDATION, NULL, ppRecompiled, &pErrors); @@ -2530,6 +2530,9 @@ extern HRESULT XTL::EmuRecompileVshFunction free(pShader); return hRet; +#else + return D3D_OK; +#endif } extern void XTL::FreeVertexDynamicPatch(CxbxVertexShader *pVertexShader) @@ -2540,6 +2543,7 @@ extern void XTL::FreeVertexDynamicPatch(CxbxVertexShader *pVertexShader) // Checks for failed vertex shaders, and shaders that would need patching boolean VshHandleIsValidShader(DWORD Handle) { +#ifndef CXBX_USE_D3D9 //printf( "VS = 0x%.08X\n", Handle ); XTL::CxbxVertexShader *pVertexShader = XTL::MapXboxVertexShaderHandleToCxbxVertexShader(Handle); @@ -2560,6 +2564,7 @@ boolean VshHandleIsValidShader(DWORD Handle) } */ } +#endif return TRUE; } diff --git a/src/CxbxKrnl/EmuD3D8Types.h b/src/CxbxKrnl/EmuD3D8Types.h index e15bfb728..cd138e93c 100755 --- a/src/CxbxKrnl/EmuD3D8Types.h +++ b/src/CxbxKrnl/EmuD3D8Types.h @@ -48,8 +48,8 @@ #include // for D3DXVECTOR4, etc #include -#include -#pragma comment(lib, "dxerr.lib") // See https://blogs.msdn.microsoft.com/chuckw/2012/04/24/wheres-dxerr-lib/ +#include +//#pragma comment(lib, "dxerr.lib") // See https://blogs.msdn.microsoft.com/chuckw/2012/04/24/wheres-dxerr-lib/ // If the above doesn't compile, install the June 2010 DirectX SDK // from https://www.microsoft.com/en-us/download/details.aspx?id=6812 @@ -66,8 +66,10 @@ #define D3DENUM_NO_WHQL_LEVEL 0 // default in Direct3D 9 // Alias all host Direct3D 9 symbols to generic symbols +#define DXGetErrorString DXGetErrorString9A +#define DXGetErrorDescription DXGetErrorDescription9A #define Direct3DCreate Direct3DCreate9 -#define D3DXAssembleShader D3DXCompileShader +#define D3DXAssembleShader D3DXAssembleShader #define FullScreen_PresentationInterval PresentationInterval // a field in D3DPRESENT_PARAMETERS #define D3DLockData void #define PixelShaderConstantType float