From 377230bcf5cf8161fdda9346df4120f64d518658 Mon Sep 17 00:00:00 2001 From: PatrickvL Date: Wed, 21 Jul 2021 17:22:01 +0200 Subject: [PATCH] Ported GetBackBuffer --- src/core/hle/D3D8/Direct3D9/Direct3D9.cpp | 75 +++++++++++++++---- src/core/hle/D3D8/Direct3D9/TextureStates.cpp | 2 +- src/core/hle/D3D8/XbD3D8Types.h | 3 +- 3 files changed, 63 insertions(+), 17 deletions(-) diff --git a/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp b/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp index 8869aa016..79859bdfd 100644 --- a/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp +++ b/src/core/hle/D3D8/Direct3D9/Direct3D9.cpp @@ -104,6 +104,7 @@ HWND g_hEmuWindow = NULL; // rendering window bool g_bClipCursor = false; // indicates that the mouse cursor should be confined inside the rendering window IDirect3DDevice *g_pD3DDevice = nullptr; // Direct3D Device #ifdef CXBX_USE_D3D11 +IDXGISwapChain *g_pSwapChain = nullptr; // Direct3D 11 Swap Chain ID3D11DeviceContext *g_pD3DDeviceContext = nullptr; // Direct3D 11 Device Context #endif @@ -129,7 +130,7 @@ static DWORD g_dwPrimPerFrame = 0; // Number of primitives within one frame static float g_AspectRatioScale = 1.0f; static UINT g_AspectRatioScaleWidth = 0; static UINT g_AspectRatioScaleHeight = 0; -static D3DSURFACE_DESC g_HostBackBufferDesc; +static D3DSurfaceDesc g_HostBackBufferDesc; static Settings::s_video g_XBVideo; // D3D based variables @@ -2036,7 +2037,7 @@ void UpdateDepthStencilFlags(IDirect3DSurface *pDepthStencilSurface) g_bHasDepth = false; g_bHasStencil = false; if (pDepthStencilSurface != nullptr) { - D3DSURFACE_DESC Desc; + D3DSurfaceDesc Desc; pDepthStencilSurface->GetDesc(&Desc); switch (Desc.Format) { @@ -2310,6 +2311,27 @@ static void CreateDefaultD3D9Device #endif // only use feature level 10.0 D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_10_0 }; + +#if 0 + DXGI_SWAP_CHAIN_DESC SwapChainDesc; + + // Create the Direct3D 11 API device object and a corresponding context. + HRESULT hr = D3D11CreateDeviceAndSwapChain( + g_EmuCDPD.Adapter, // NULL + g_EmuCDPD.DeviceType, // D3D_DRIVER_TYPE_HARDWARE + nullptr, // Software + creationFlags, + featureLevels, + ARRAYSIZE(featureLevels), + D3D11_SDK_VERSION, // UWP apps must set this to D3D11_SDK_VERSION. + &SwapChainDesc, + &g_pSwapChain, + &g_pD3DDevice, // Returns the Direct3D device created. + nullptr, // pFeatureLevel + &g_pD3DDeviceContext // Returns the device immediate context. + ); + DEBUG_D3DRESULT(hr, "D3D11CreateDevice"); +#else // Create the Direct3D 11 API device object and a corresponding context. ComPtr device; ComPtr context; @@ -2349,17 +2371,18 @@ static void CreateDefaultD3D9Device dxgiFactory->CreateSwapChainForCoreWindow( g_pD3DDevice.Get(), reinterpret_cast(window), - &swapChainDesc, + &SwapChainDesc, nullptr, &swapChain ); - swapChain.As(&m_swapChain); + swapChain.As(&g_pSwapChain); dxgiDevice->SetMaximumFrameLatency(1); +#endif // Configure the back buffer as a render target ComPtr backBuffer; - m_swapChain->GetBuffer( + g_pSwapChain->GetBuffer( 0, __uuidof(ID3D11Texture2D), &backBuffer @@ -2372,7 +2395,7 @@ static void CreateDefaultD3D9Device &m_renderTargetView ); - D3D11_TEXTURE2D_DESC backBufferDesc = { 0 }; + D3DSurfaceDesc/*=D3D11_TEXTURE2D_DESC*/ backBufferDesc = { 0 }; backBuffer->GetDesc(&backBufferDesc); CD3D11_VIEWPORT viewport( @@ -2480,13 +2503,11 @@ static void EmuVerifyResourceIsRegistered(xbox::X_D3DResource *pResource, DWORD // would be overwritten by the surface created in SetRenderTarget // However, if a non-rendertarget surface is used here, we'll need to recreate it as a render target! auto hostResource = it->second.pHostResource.Get(); - auto xboxSurface = (xbox::X_D3DSurface*)pResource; - auto xboxTexture = (xbox::X_D3DTexture*)pResource; auto xboxResourceType = GetXboxD3DResourceType(pResource); // Determine if the associated host resource is a render target already, if so, do nothing HRESULT hRet = STATUS_INVALID_PARAMETER; // Default to an error condition, so we can use D3D_OK to check for success - D3DSURFACE_DESC surfaceDesc; + D3DSurfaceDesc surfaceDesc; if (xboxResourceType == xbox::X_D3DRTYPE_SURFACE) { hRet = ((IDirect3DSurface*)hostResource)->GetDesc(&surfaceDesc); } else if (xboxResourceType == xbox::X_D3DRTYPE_TEXTURE) { @@ -2505,6 +2526,8 @@ static void EmuVerifyResourceIsRegistered(xbox::X_D3DResource *pResource, DWORD // We need to re-create it as a render target switch (xboxResourceType) { case xbox::X_D3DRTYPE_SURFACE: { + auto xboxSurface = (xbox::X_D3DSurface*)pResource; + // Free the host surface FreeHostResource(key); @@ -2777,10 +2800,19 @@ ConvertedIndexBuffer& CxbxUpdateActiveIndexBuffer void UpdateHostBackBufferDesc() { IDirect3DSurface *pCurrentHostBackBuffer = nullptr; - auto hRet = g_pD3DDevice->GetBackBuffer( + +#ifdef CXBX_USE_D3D11 + // Get the surface from the swap chain + HRESULT hRet = g_pSwapChain->GetBuffer( + 0, // Buffer (zero-based buffer index) + __uuidof(pCurrentHostBackBuffer), + reinterpret_cast(&pCurrentHostBackBuffer) + ); +#else + auto hRet = g_pD3DDevice->GetBackBuffer( 0, // iSwapChain 0, D3DBACKBUFFER_TYPE_MONO, &pCurrentHostBackBuffer); - +#endif if (hRet != D3D_OK) { CxbxrAbort("Unable to get host backbuffer surface"); } @@ -4121,7 +4153,7 @@ xbox::X_D3DSurface* CxbxrImpl_GetBackBuffer2 return pXboxBackBuffer; } - D3DSURFACE_DESC copySurfaceDesc; + D3DSurfaceDesc copySurfaceDesc; hRet = pCopySrcSurface->GetDesc(©SurfaceDesc); if (hRet != D3D_OK) { EmuLog(LOG_LEVEL::WARNING, "Could not get Xbox Back Buffer Host Surface Desc"); @@ -4216,7 +4248,7 @@ bool GetHostRenderTargetDimensions(DWORD *pHostWidth, DWORD *pHostHeight, IDirec } // Get current host render target dimensions - D3DSURFACE_DESC HostRenderTarget_Desc; + D3DSurfaceDesc HostRenderTarget_Desc; pHostRenderTarget->GetDesc(&HostRenderTarget_Desc); if (shouldRelease) { @@ -5124,7 +5156,6 @@ xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_CopyRects) // We skip the trampoline to prevent unnecessary work // As our surfaces remain on the GPU, calling the trampoline would just // result in a memcpy from an empty Xbox surface to another empty Xbox Surface - D3DSURFACE_DESC hostSourceDesc, hostDestDesc; auto pHostSourceSurface = GetHostSurface(pSourceSurface); auto pHostDestSurface = GetHostSurface(pDestinationSurface); @@ -5135,6 +5166,7 @@ xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_CopyRects) return; } + D3DSurfaceDesc hostSourceDesc, hostDestDesc; pHostSourceSurface->GetDesc(&hostSourceDesc); pHostDestSurface->GetDesc(&hostDestDesc); @@ -5305,9 +5337,18 @@ xbox::dword_xt WINAPI xbox::EMUPATCH(D3DDevice_Swap) // Fetch the host backbuffer IDirect3DSurface *pCurrentHostBackBuffer = nullptr; +#ifdef CXBX_USE_D3D11 + // Get the surface from the swap chain + HRESULT hRet = g_pSwapChain->GetBuffer( + 0, // Buffer (zero-based buffer index) + __uuidof(pCurrentHostBackBuffer), + reinterpret_cast(&pCurrentHostBackBuffer) + ); +#else HRESULT hRet = g_pD3DDevice->GetBackBuffer( 0, // iSwapChain 0, D3DBACKBUFFER_TYPE_MONO, &pCurrentHostBackBuffer); +#endif DEBUG_D3DRESULT(hRet, "g_pD3DDevice->GetBackBuffer - Unable to get backbuffer surface!"); if (hRet == D3D_OK) { @@ -5526,13 +5567,17 @@ xbox::dword_xt WINAPI xbox::EMUPATCH(D3DDevice_Swap) pCurrentHostBackBuffer->Release(); } +#ifdef CXBX_USE_D3D11 + hRet = g_pSwapChain->Present(0, 0); + DEBUG_D3DRESULT(hRet, "g_pD3DDevice->Present"); +#else g_pD3DDevice->EndScene(); hRet = g_pD3DDevice->Present(0, 0, 0, 0); DEBUG_D3DRESULT(hRet, "g_pD3DDevice->Present"); hRet = g_pD3DDevice->BeginScene(); - +#endif // RenderStates need reapplying each frame, but can be re-used between draw calls // This forces them to be reset XboxRenderStates.SetDirty(); diff --git a/src/core/hle/D3D8/Direct3D9/TextureStates.cpp b/src/core/hle/D3D8/Direct3D9/TextureStates.cpp index 6ffe095ad..c306f94a4 100644 --- a/src/core/hle/D3D8/Direct3D9/TextureStates.cpp +++ b/src/core/hle/D3D8/Direct3D9/TextureStates.cpp @@ -373,7 +373,7 @@ void XboxTextureStateConverter::Apply() // set the point sprites texture g_pD3DDevice->GetTexture(3, &pTexture); - g_pD3DDevice->SetTexture(0, pTexture); + g_pD3DDevice->SetTexture(0, pTexture); // ID3D11Device::CreateShaderResourceView(), ::PSSetShaderResources() // Avoid a dangling reference that would lead to a memory leak if (pTexture != nullptr) diff --git a/src/core/hle/D3D8/XbD3D8Types.h b/src/core/hle/D3D8/XbD3D8Types.h index 5a05701e5..767d10713 100644 --- a/src/core/hle/D3D8/XbD3D8Types.h +++ b/src/core/hle/D3D8/XbD3D8Types.h @@ -80,6 +80,7 @@ #define CXBXFORMAT _9_11(D3DFORMAT, DXGI_FORMAT) #define D3DVERTEXELEMENT _9_11(D3DVERTEXELEMENT9, D3D11_INPUT_ELEMENT_DESC) #define D3DVIEWPORT _9_11(D3DVIEWPORT9, D3D11_VIEWPORT) +#define D3DSurfaceDesc _9_11(D3DSURFACE_DESC, D3D11_TEXTURE2D_DESC) #define IDirect3DDevice _9_11(IDirect3DDevice9Ex, ID3D11Device) #define IDirect3DVertexDeclaration _9_11(IDirect3DVertexDeclaration9, ID3D11InputLayout) @@ -92,7 +93,7 @@ #define IDirect3DCubeTexture _9_11(IDirect3DCubeTexture9, ID3D11Texture2D) // array of six 2D textures (one for each face) #define IDirect3DVertexBuffer _9_11(IDirect3DVertexBuffer9, ID3D11Buffer) #define IDirect3DIndexBuffer _9_11(IDirect3DIndexBuffer9, ID3D11Buffer) // or ID3D11ShaderResourceView ? -#define IDirect3DSurface IDirect3DSurface9 +#define IDirect3DSurface _9_11(IDirect3DSurface9, ID3D11Texture2D) #define IDirect3DVolume IDirect3DVolume9 #define IDirect3DQuery _9_11(IDirect3DQuery9, ID3D11Query)