diff --git a/CMakeLists.txt b/CMakeLists.txt index de86641d033e..35dbbae77e1c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -608,12 +608,6 @@ source_group(LOONGARCH64 FILES ${CommonLOONGARCH64}) if(WIN32) set(CommonD3D - Common/GPU/D3D9/D3D9ShaderCompiler.cpp - Common/GPU/D3D9/D3D9ShaderCompiler.h - Common/GPU/D3D9/D3D9StateCache.cpp - Common/GPU/D3D9/D3D9StateCache.h - Common/GPU/D3D9/thin3d_d3d9.cpp - Common/GPU/D3D9/D3DCompilerLoader.cpp Common/GPU/D3D11/thin3d_d3d11.cpp Common/GPU/D3D11/D3D11Loader.cpp Common/GPU/D3D11/D3D11Loader.h @@ -1510,7 +1504,7 @@ else() endif() if(WIN32) - target_link_libraries(Common winmm d3d9 dsound dxguid Version) + target_link_libraries(Common winmm dsound dxguid Version) endif() if(NOT LIBRETRO) @@ -1863,21 +1857,6 @@ set(GPU_VULKAN GPU/Vulkan/VulkanUtil.h ) -set(GPU_D3D9 - GPU/Directx9/DrawEngineDX9.cpp - GPU/Directx9/DrawEngineDX9.h - GPU/Directx9/FramebufferManagerDX9.cpp - GPU/Directx9/FramebufferManagerDX9.h - GPU/Directx9/GPU_DX9.cpp - GPU/Directx9/GPU_DX9.h - GPU/Directx9/ShaderManagerDX9.cpp - GPU/Directx9/ShaderManagerDX9.h - GPU/Directx9/StateMappingDX9.cpp - GPU/Directx9/StateMappingDX9.h - GPU/Directx9/TextureCacheDX9.cpp - GPU/Directx9/TextureCacheDX9.h -) - set(GPU_D3D11 GPU/D3D11/DrawEngineD3D11.cpp GPU/D3D11/DrawEngineD3D11.h @@ -1898,7 +1877,7 @@ set(GPU_D3D11 # We build Vulkan even on Apple to avoid annoying build differences. set(GPU_IMPLS ${GPU_GLES} ${GPU_VULKAN}) if(WIN32) - list(APPEND GPU_IMPLS ${GPU_D3D9} ${GPU_D3D11}) + list(APPEND GPU_IMPLS ${GPU_D3D11}) endif() set(GPU_SOURCES @@ -2674,8 +2653,6 @@ set(WindowsFiles Windows/EmuThread.cpp Windows/EmuThread.h Windows/GeDebugger/GeDebugger.cpp - Windows/GPU/D3D9Context.cpp - Windows/GPU/D3D9Context.h Windows/GPU/D3D11Context.cpp Windows/GPU/D3D11Context.h Windows/GPU/WindowsGLContext.cpp @@ -2724,7 +2701,7 @@ set(WindowsFiles list(APPEND LinkCommon ${CoreLibName} ${CMAKE_THREAD_LIBS_INIT}) if(WIN32) - list(APPEND LinkCommon kernel32 user32 gdi32 shell32 comctl32 dsound xinput d3d9 winmm dinput8 ole32 winspool ksuser dwmapi mf uxtheme mfplat mfreadwrite mfuuid shlwapi) + list(APPEND LinkCommon kernel32 user32 gdi32 shell32 comctl32 dsound xinput winmm dinput8 ole32 winspool ksuser dwmapi mf uxtheme mfplat mfreadwrite mfuuid shlwapi) #setup_target_project(${TargetBin} Windows) list(APPEND NativeAppSource ${WindowsFiles}) endif() @@ -2781,8 +2758,6 @@ if(HEADLESS) list(APPEND HeadlessSource headless/WindowsHeadlessHost.cpp headless/WindowsHeadlessHost.h - Windows/GPU/D3D9Context.cpp - Windows/GPU/D3D9Context.h Windows/GPU/D3D11Context.cpp Windows/GPU/D3D11Context.h Windows/GPU/WindowsGLContext.cpp diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj index d3df13154186..bc2cbd9ace56 100644 --- a/Common/Common.vcxproj +++ b/Common/Common.vcxproj @@ -496,9 +496,6 @@ - - - @@ -991,10 +988,6 @@ - - - - diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters index a16e2e057a58..d26b8fedcb9e 100644 --- a/Common/Common.vcxproj.filters +++ b/Common/Common.vcxproj.filters @@ -250,15 +250,6 @@ UI - - GPU\D3D9 - - - GPU\D3D9 - - - GPU\D3D9 - GPU\D3D11 @@ -911,21 +902,9 @@ UI - - GPU\D3D9 - GPU\D3D11 - - GPU\D3D9 - - - GPU\D3D9 - - - GPU\D3D9 - GPU\D3D11 @@ -1368,9 +1347,6 @@ {3b448d70-d5c6-4732-96f0-29f3e101bfe8} - - {a1745de8-f61a-4f11-b715-705a8812862e} - {8241d0c2-78c8-4fc6-9543-69042ec5eb54} diff --git a/Common/GPU/D3D11/thin3d_d3d11.cpp b/Common/GPU/D3D11/thin3d_d3d11.cpp index 1fdfe6d33c85..030872fef5dc 100644 --- a/Common/GPU/D3D11/thin3d_d3d11.cpp +++ b/Common/GPU/D3D11/thin3d_d3d11.cpp @@ -352,12 +352,6 @@ D3D11DrawContext::D3D11DrawContext(ID3D11Device *device, ID3D11DeviceContext *de caps_.isTilingGPU = false; - // Hide D3D9 when we know it likely won't work well. - caps_.supportsD3D9 = true; - if (!strcmp(adapterDesc_.c_str(), "Intel(R) Iris(R) Xe Graphics")) { - caps_.supportsD3D9 = false; - } - #ifndef __LIBRETRO__ // their build server uses an old SDK if (swapChain_) { DXGI_SWAP_CHAIN_DESC swapChainDesc; @@ -368,6 +362,7 @@ D3D11DrawContext::D3D11DrawContext(ID3D11Device *device, ID3D11DeviceContext *de } } #endif + // Temp texture for read-back of small images. Custom textures are created on demand for larger ones. // TODO: Should really benchmark if this extra complexity has any benefit. D3D11_TEXTURE2D_DESC packDesc{}; diff --git a/Common/GPU/D3D9/D3D9ShaderCompiler.cpp b/Common/GPU/D3D9/D3D9ShaderCompiler.cpp deleted file mode 100644 index 411f2f2e052c..000000000000 --- a/Common/GPU/D3D9/D3D9ShaderCompiler.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include "ppsspp_config.h" - -#ifdef _WIN32 - -#include "Common/CommonWindows.h" -#include "Common/GPU/D3D9/D3DCompilerLoader.h" -#include "Common/GPU/D3D9/D3D9ShaderCompiler.h" -#include "Common/CommonFuncs.h" -#include "Common/SysError.h" -#include "Common/Log.h" -#include "Common/StringUtils.h" -#include - -using namespace Microsoft::WRL; - -HRESULT CompileShaderToByteCodeD3D9(const char *code, const char *target, std::string *errorMessage, ID3DBlob **ppShaderCode) { - ComPtr pErrorMsg; - - // Compile pixel shader. - HRESULT hr = dyn_D3DCompile(code, - (UINT)strlen(code), - nullptr, - nullptr, - nullptr, - "main", - target, - 0, - 0, - ppShaderCode, - &pErrorMsg); - - if (pErrorMsg) { - *errorMessage = std::string((CHAR *)pErrorMsg->GetBufferPointer()); - - OutputDebugStringUTF8(LineNumberString(std::string(code)).c_str()); - OutputDebugStringUTF8(errorMessage->c_str()); - } else if (FAILED(hr)) { - *errorMessage = GetStringErrorMsg(hr); - } else { - errorMessage->clear(); - } - - return hr; -} - -bool CompilePixelShaderD3D9(LPDIRECT3DDEVICE9 device, const char *code, LPDIRECT3DPIXELSHADER9 *pShader, std::string *errorMessage) { - ComPtr pShaderCode; - HRESULT hr = CompileShaderToByteCodeD3D9(code, "ps_3_0", errorMessage, &pShaderCode); - if (SUCCEEDED(hr)) { - // Create pixel shader. - device->CreatePixelShader((DWORD*)pShaderCode->GetBufferPointer(), pShader); - return true; - } else { - return false; - } -} - -bool CompileVertexShaderD3D9(LPDIRECT3DDEVICE9 device, const char *code, LPDIRECT3DVERTEXSHADER9 *pShader, std::string *errorMessage) { - ComPtr pShaderCode; - HRESULT hr = CompileShaderToByteCodeD3D9(code, "vs_3_0", errorMessage, &pShaderCode); - if (SUCCEEDED(hr)) { - // Create vertex shader. - device->CreateVertexShader((DWORD*)pShaderCode->GetBufferPointer(), pShader); - return true; - } else { - return false; - } -} - -#endif diff --git a/Common/GPU/D3D9/D3D9ShaderCompiler.h b/Common/GPU/D3D9/D3D9ShaderCompiler.h deleted file mode 100644 index 37fda163b106..000000000000 --- a/Common/GPU/D3D9/D3D9ShaderCompiler.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "Common/CommonWindows.h" -#include "Common/GPU/D3D9/D3DCompilerLoader.h" - -#include -#include -#include - -HRESULT CompileShaderToByteCodeD3D9(const char *code, const char *target, std::string *errorMessage, LPD3DBLOB *pShaderCode); - -bool CompilePixelShaderD3D9(LPDIRECT3DDEVICE9 device, const char *code, LPDIRECT3DPIXELSHADER9 *pShader, std::string *errorMessage); -bool CompileVertexShaderD3D9(LPDIRECT3DDEVICE9 device, const char *code, LPDIRECT3DVERTEXSHADER9 *pShader, std::string *errorMessage); diff --git a/Common/GPU/D3D9/D3D9StateCache.cpp b/Common/GPU/D3D9/D3D9StateCache.cpp deleted file mode 100644 index d7a09d0b2e4a..000000000000 --- a/Common/GPU/D3D9/D3D9StateCache.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#ifdef _WIN32 - -#include "Common/GPU/D3D9/D3D9StateCache.h" -#include - -DirectXState dxstate; - -Microsoft::WRL::ComPtr pD3Ddevice9; -Microsoft::WRL::ComPtr pD3DdeviceEx9; - -int DirectXState::state_count = 0; - -void DirectXState::Initialize() { - if (initialized) - return; - - Restore(); - - initialized = true; -} - -void DirectXState::Restore() { - int count = 0; - - blend.restore(); count++; - blendSeparate.restore(); count++; - blendEquation.restore(); count++; - blendFunc.restore(); count++; - blendColor.restore(); count++; - - scissorTest.restore(); count++; - scissorRect.restore(); count++; - - cullMode.restore(); count++; - shadeMode.restore(); count++; - - depthTest.restore(); count++; - depthFunc.restore(); count++; - depthWrite.restore(); count++; - - colorMask.restore(); count++; - - viewport.restore(); count++; - - alphaTest.restore(); count++; - alphaTestFunc.restore(); count++; - alphaTestRef.restore(); count++; - - stencilTest.restore(); count++; - stencilOp.restore(); count++; - stencilFunc.restore(); count++; - stencilWriteMask.restore(); count++; - - texMinFilter.restore(); count++; - texMagFilter.restore(); count++; - texMipFilter.restore(); count++; - texMipLodBias.restore(); count++; - texMaxMipLevel.restore(); count++; - texAddressU.restore(); count++; - texAddressV.restore(); count++; - texAddressW.restore(); count++; -} - -#endif // _MSC_VER diff --git a/Common/GPU/D3D9/D3D9StateCache.h b/Common/GPU/D3D9/D3D9StateCache.h deleted file mode 100644 index 17512752d2b6..000000000000 --- a/Common/GPU/D3D9/D3D9StateCache.h +++ /dev/null @@ -1,402 +0,0 @@ -#pragma once - -#include -#include - -#include "Common/GPU/D3D9/D3D9ShaderCompiler.h" - -// TODO: Get rid of these somehow. -extern Microsoft::WRL::ComPtr pD3Ddevice9; -extern Microsoft::WRL::ComPtr pD3DdeviceEx9; - -class DirectXState { -private: - template - class BoolState { - bool _value; - public: - BoolState() : _value(init) { - DirectXState::state_count++; - } - - inline void set(bool value) { - if (_value != value) { - _value = value; - restore(); - } - } - void force(bool value) { - bool old = _value; - set(value); - _value = old; - } - inline void enable() { - set(true); - } - inline void disable() { - set(false); - } - operator bool() const { - return isset(); - } - inline bool isset() { - return _value; - } - void restore() { - pD3Ddevice9->SetRenderState(cap, _value); - } - }; - - template - class DxState1 { - D3DRENDERSTATETYPE _state1; - DWORD p1; - public: - DxState1() : _state1(state1), p1(p1def) { - DirectXState::state_count++; - } - - inline void set(DWORD newp1) { - if (p1 != newp1) { - p1 = newp1; - restore(); - } - } - void force(DWORD newp1) { - DWORD old = p1; - set(newp1); - p1 = old; - } - void restore() { - pD3Ddevice9->SetRenderState(_state1, p1); - } - }; - - template - class DxSampler0State1 { - D3DSAMPLERSTATETYPE _state1; - DWORD p1; - public: - DxSampler0State1() : _state1(state1), p1(p1def) { - DirectXState::state_count++; - } - - inline void set(DWORD newp1) { - if (p1 != newp1) { - p1 = newp1; - restore(); - } - } - void force(DWORD newp1) { - DWORD old = p1; - set(newp1); - p1 = old; - } - void restore() { - pD3Ddevice9->SetSamplerState(0, _state1, p1); - } - }; - - // Can't have FLOAT template parameters... - template - class DxSampler0State1Float { - D3DSAMPLERSTATETYPE _state1; - union { - FLOAT p1; - DWORD p1d; - }; - public: - DxSampler0State1Float() : _state1(state1), p1d(p1def) { - DirectXState::state_count++; - } - - inline void set(FLOAT newp1) { - if (p1 != newp1) { - p1 = newp1; - restore(); - } - } - void force(FLOAT newp1) { - FLOAT old = p1; - set(newp1); - p1 = old; - } - void restore() { - pD3Ddevice9->SetSamplerState(0, _state1, p1d); - } - }; - - template - class DxState2 { - D3DRENDERSTATETYPE _state1; - D3DRENDERSTATETYPE _state2; - DWORD p1; - DWORD p2; - public: - DxState2() : _state1(state1),_state2(state2), p1(p1def), p2(p2def) { - DirectXState::state_count++; - } - - inline void set(DWORD newp1, DWORD newp2) { - if (p1 != newp1) { - p1 = newp1; - pD3Ddevice9->SetRenderState(_state1, p1); - } - if (p2 != newp2) { - p2 = newp2; - pD3Ddevice9->SetRenderState(_state2, p2); - } - } - void force(DWORD newp1, DWORD newp2) { - DWORD old1 = p1; - DWORD old2 = p2; - set(newp1, newp2); - p1 = old1; - p2 = old2; - } - void restore() { - pD3Ddevice9->SetRenderState(_state1, p1); - pD3Ddevice9->SetRenderState(_state2, p2); - } - }; - - template - class DxState3 { - D3DRENDERSTATETYPE _state1; - D3DRENDERSTATETYPE _state2; - D3DRENDERSTATETYPE _state3; - DWORD p1; - DWORD p2; - DWORD p3; - public: - DxState3() : _state1(state1),_state2(state2), _state3(state3), - p1(p1def), p2(p2def), p3(p3def) { - } - - inline void set(DWORD newp1, DWORD newp2, DWORD newp3) { - if (p1 != newp1) { - p1 = newp1; - pD3Ddevice9->SetRenderState(_state1, p1); - } - if (p2 != newp2) { - p2 = newp2; - pD3Ddevice9->SetRenderState(_state2, p2); - } - if (p3 != newp3) { - p3 = newp3; - pD3Ddevice9->SetRenderState(_state3, p3); - } - } - void force(DWORD newp1, DWORD newp2, DWORD newp3) { - DWORD old1 = p1; - DWORD old2 = p2; - DWORD old3 = p3; - set(newp1, newp2, newp3); - p1 = old1; - p2 = old2; - p3 = old3; - } - void restore() { - pD3Ddevice9->SetRenderState(_state1, p1); - pD3Ddevice9->SetRenderState(_state2, p2); - pD3Ddevice9->SetRenderState(_state3, p3); - } - }; - - template - class DxState4 { - D3DRENDERSTATETYPE _state1; - D3DRENDERSTATETYPE _state2; - D3DRENDERSTATETYPE _state3; - D3DRENDERSTATETYPE _state4; - DWORD p1; - DWORD p2; - DWORD p3; - DWORD p4; - public: - DxState4() : _state1(state1), _state2(state2), _state3(state3), _state4(state4), - p1(p1def), p2(p2def), p3(p3def), p4(p4def) { - } - - inline void set(DWORD newp1, DWORD newp2, DWORD newp3, DWORD newp4) { - if (p1 != newp1) { - p1 = newp1; - pD3Ddevice9->SetRenderState(_state1, p1); - } - if (p2 != newp2) { - p2 = newp2; - pD3Ddevice9->SetRenderState(_state2, p2); - } - if (p3 != newp3) { - p3 = newp3; - pD3Ddevice9->SetRenderState(_state3, p3); - } - if (p4 != newp4) { - p4 = newp4; - pD3Ddevice9->SetRenderState(_state4, p4); - } - } - void force(DWORD newp1, DWORD newp2, DWORD newp3, DWORD newp4) { - DWORD old1 = p1; - DWORD old2 = p2; - DWORD old3 = p3; - DWORD old4 = p4; - set(newp1, newp2, newp3, newp4); - p1 = old1; - p2 = old2; - p3 = old3; - p4 = old4; - } - void restore() { - pD3Ddevice9->SetRenderState(_state1, p1); - pD3Ddevice9->SetRenderState(_state2, p2); - pD3Ddevice9->SetRenderState(_state3, p3); - pD3Ddevice9->SetRenderState(_state4, p4); - } - }; - - - class SavedBlendFactor { - DWORD c; - public: - SavedBlendFactor() { - c = 0xFFFFFFFF; - DirectXState::state_count++; - } - inline void set(const float v[4]) { - DWORD newc = D3DCOLOR_COLORVALUE(v[0], v[1], v[2], v[3]); - if (c != newc) { - c = newc; - restore(); - } - } - void setDWORD(DWORD newc) { - newc = ((newc >> 8) & 0xff) | (newc & 0xff00ff00) | ((newc << 16) & 0xff0000); // ARGB -> ABGR fix - if (c != newc) { - c = newc; - restore(); - } - } - void force(const float v[4]) { - DWORD old = c; - set(v); - c = old; - } - inline void restore() { - pD3Ddevice9->SetRenderState(D3DRS_BLENDFACTOR, c); - } - }; - - class StateVp { - D3DVIEWPORT9 viewport; - public: - StateVp() { - memset(&viewport, 0, sizeof(viewport)); - // It's an error if w/h is zero, so let's start with something that can work. - viewport.Width = 1; - viewport.Height = 1; - } - inline void set(int x, int y, int w, int h, float n = 0.f, float f = 1.f) { - D3DVIEWPORT9 newviewport; - newviewport.X = x; - newviewport.Y = y; - newviewport.Width = w; - newviewport.Height = h; - newviewport.MinZ = n; - newviewport.MaxZ = f; - if (memcmp(&viewport, &newviewport, sizeof(viewport)) != 0) { - viewport = newviewport; - restore(); - } - } - - void force(int x, int y, int w, int h, float n = 0.f, float f = 1.f) { - D3DVIEWPORT9 old = viewport; - set(x, y, w, h, n, f); - viewport = old; - } - - inline void restore() { - pD3Ddevice9->SetViewport(&viewport); - } - }; - - class StateScissor { - RECT rect; - public: - inline void set(int x1, int y1, int x2, int y2) { - RECT newrect = {x1, y1, x2, y2}; - if (memcmp(&rect, &newrect, sizeof(rect))) { - rect = newrect; - restore(); - } - } - - void force(int x1, int y1, int x2, int y2) { - RECT old = rect; - set(x1, y1, x2, y2); - rect = old; - } - - inline void restore() { - pD3Ddevice9->SetScissorRect(&rect); - } - }; - - bool initialized; - -public: - static int state_count; - DirectXState() : initialized(false) {} - void Initialize(); - void Restore(); - - // When adding a state here, don't forget to add it to DirectxState::Restore() too - BoolState blend; - BoolState blendSeparate; - DxState4 blendFunc; - DxState2 blendEquation; - SavedBlendFactor blendColor; - - BoolState scissorTest; - - DxState1 cullMode; - DxState1 shadeMode; - DxState1 clipPlaneEnable; - - BoolState depthTest; - - DxState1 alphaTestFunc; - DxState1 alphaTestRef; - BoolState alphaTest; - - DxState1 depthFunc; - DxState1 depthWrite; - - DxState1 colorMask; - - StateVp viewport; - StateScissor scissorRect; - - BoolState stencilTest; - - DxState3 stencilOp; - DxState1 stencilFunc; - DxState1 stencilRef; - DxState1 stencilWriteMask; - DxState1 stencilCompareMask; - - DxSampler0State1 texMinFilter; - DxSampler0State1 texMagFilter; - DxSampler0State1 texMipFilter; - DxSampler0State1Float texMipLodBias; - DxSampler0State1 texMaxMipLevel; - DxSampler0State1 texAddressU; - DxSampler0State1 texAddressV; - DxSampler0State1 texAddressW; -}; - -#undef STATE1 -#undef STATE2 - -extern DirectXState dxstate; diff --git a/Common/GPU/D3D9/D3DCompilerLoader.cpp b/Common/GPU/D3D9/D3DCompilerLoader.cpp deleted file mode 100644 index 7670c1ae1fce..000000000000 --- a/Common/GPU/D3D9/D3DCompilerLoader.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include "ppsspp_config.h" - -#include "Common/CommonWindows.h" -#include - -#include "Common/Log.h" -#include "Common/GPU/D3D9/D3DCompilerLoader.h" - -static HMODULE g_D3DCompileModule; -extern pD3DCompile ptr_D3DCompile; - -static int d3dcompiler_version = 47; - -bool LoadD3DCompilerDynamic() { - g_D3DCompileModule = LoadLibrary(D3DCOMPILER_DLL); -#if PPSSPP_ARCH(X86) - // Workaround for distributing both 32-bit and 64-bit versions of the DLL. - if (!g_D3DCompileModule) { - g_D3DCompileModule = LoadLibrary(L"D3dcompiler_47.x86.dll"); - } -#endif - if (!g_D3DCompileModule) { - g_D3DCompileModule = LoadLibrary(L"D3dcompiler_42.dll"); - d3dcompiler_version = 42; - } - - if (!g_D3DCompileModule) { - return false; - } else { - ptr_D3DCompile = (pD3DCompile)GetProcAddress(g_D3DCompileModule, "D3DCompile"); - return true; - } - -} - -int GetD3DCompilerVersion() { - return d3dcompiler_version; -} - -bool UnloadD3DCompiler() { - if (!g_D3DCompileModule) - return false; - - FreeLibrary(g_D3DCompileModule); - g_D3DCompileModule = nullptr; - - return true; -} - -HRESULT dyn_D3DCompile(LPCSTR pSrcData, UINT SrcDataSize, LPCSTR pFileName, CONST D3D_SHADER_MACRO* pDefines, - LPD3DINCLUDE pInclude, LPCSTR pEntrypoint, LPCSTR pTarget, - UINT Flags1, UINT Flags2, LPD3DBLOB* ppShader, LPD3DBLOB* ppErrorMsgs) -{ - _assert_(g_D3DCompileModule != nullptr); - return ptr_D3DCompile(pSrcData, SrcDataSize, pFileName, pDefines, pInclude, pEntrypoint, pTarget, Flags1, Flags2, ppShader, ppErrorMsgs); -} diff --git a/Common/GPU/D3D9/D3DCompilerLoader.h b/Common/GPU/D3D9/D3DCompilerLoader.h deleted file mode 100644 index 25c2cabdc946..000000000000 --- a/Common/GPU/D3D9/D3DCompilerLoader.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once -#include "ppsspp_config.h" - -#include "Common/CommonWindows.h" -#include - -bool LoadD3DCompilerDynamic(); - -HRESULT dyn_D3DCompile(LPCSTR pSrcData, UINT SrcDataSize, LPCSTR pFileName, CONST D3D_SHADER_MACRO* pDefines, - LPD3DINCLUDE pInclude, LPCSTR pEntrypoint, LPCSTR pTarget, - UINT Flags1, UINT Flags2, LPD3DBLOB* ppShader, LPD3DBLOB* ppErrorMsgs); - -bool UnloadD3DCompiler(); - -int GetD3DCompilerVersion(); diff --git a/Common/GPU/D3D9/thin3d_d3d9.cpp b/Common/GPU/D3D9/thin3d_d3d9.cpp deleted file mode 100644 index 87bfa32451b9..000000000000 --- a/Common/GPU/D3D9/thin3d_d3d9.cpp +++ /dev/null @@ -1,1642 +0,0 @@ -#include -#include -#include - -#include "ppsspp_config.h" - -#ifdef _DEBUG -#define D3D_DEBUG_INFO -#endif - -#include -#ifdef USE_CRT_DBG -#undef new -#endif - -#include -#include "Common/GPU/D3D9/D3DCompilerLoader.h" - -#include "Common/Math/lin/matrix4x4.h" -#include "Common/GPU/thin3d.h" -#include "Common/GPU/D3D9/D3D9StateCache.h" -#include "Common/OSVersion.h" -#include "Common/StringUtils.h" -#include "Common/TimeUtil.h" - -#include "Common/Log.h" -#include - -using namespace Microsoft::WRL; - -namespace Draw { - -static constexpr int MAX_BOUND_TEXTURES = 8; - -// Could be declared as u8 -static const D3DCMPFUNC compareToD3D9[] = { - D3DCMP_NEVER, - D3DCMP_LESS, - D3DCMP_EQUAL, - D3DCMP_LESSEQUAL, - D3DCMP_GREATER, - D3DCMP_NOTEQUAL, - D3DCMP_GREATEREQUAL, - D3DCMP_ALWAYS -}; - -// Could be declared as u8 -static const D3DBLENDOP blendEqToD3D9[] = { - D3DBLENDOP_ADD, - D3DBLENDOP_SUBTRACT, - D3DBLENDOP_REVSUBTRACT, - D3DBLENDOP_MIN, - D3DBLENDOP_MAX, -}; - -// Could be declared as u8 -static const D3DBLEND blendFactorToD3D9[] = { - D3DBLEND_ZERO, - D3DBLEND_ONE, - D3DBLEND_SRCCOLOR, - D3DBLEND_INVSRCCOLOR, - D3DBLEND_DESTCOLOR, - D3DBLEND_INVDESTCOLOR, - D3DBLEND_SRCALPHA, - D3DBLEND_INVSRCALPHA, - D3DBLEND_DESTALPHA, - D3DBLEND_INVDESTALPHA, - D3DBLEND_BLENDFACTOR, - D3DBLEND_INVBLENDFACTOR, - D3DBLEND_BLENDFACTOR, - D3DBLEND_INVBLENDFACTOR, - D3DBLEND_ZERO, - D3DBLEND_ZERO, - D3DBLEND_ZERO, - D3DBLEND_ZERO, -}; - -static const D3DTEXTUREADDRESS texWrapToD3D9[] = { - D3DTADDRESS_WRAP, - D3DTADDRESS_MIRROR, - D3DTADDRESS_CLAMP, - D3DTADDRESS_BORDER, -}; - -static const D3DTEXTUREFILTERTYPE texFilterToD3D9[] = { - D3DTEXF_POINT, - D3DTEXF_LINEAR, -}; - -static const D3DPRIMITIVETYPE primToD3D9[] = { - D3DPT_POINTLIST, - D3DPT_LINELIST, - D3DPT_LINESTRIP, - D3DPT_TRIANGLELIST, - D3DPT_TRIANGLESTRIP, - D3DPT_TRIANGLEFAN, - // These aren't available. - D3DPT_POINTLIST, // tess - D3DPT_POINTLIST, // geom ... - D3DPT_POINTLIST, - D3DPT_POINTLIST, - D3DPT_POINTLIST, -}; - -static const D3DSTENCILOP stencilOpToD3D9[] = { - D3DSTENCILOP_KEEP, - D3DSTENCILOP_ZERO, - D3DSTENCILOP_REPLACE, - D3DSTENCILOP_INCRSAT, - D3DSTENCILOP_DECRSAT, - D3DSTENCILOP_INVERT, - D3DSTENCILOP_INCR, - D3DSTENCILOP_DECR, -}; - -static D3DFORMAT FormatToD3DFMT(DataFormat fmt) { - switch (fmt) { - case DataFormat::R16_UNORM: return D3DFMT_L16; // closest match, should be a fine substitution if we ignore channels except R. - case DataFormat::R8G8B8A8_UNORM: return D3DFMT_A8R8G8B8; - case DataFormat::B8G8R8A8_UNORM: return D3DFMT_A8R8G8B8; - case DataFormat::R4G4B4A4_UNORM_PACK16: return D3DFMT_A4R4G4B4; // emulated - case DataFormat::B4G4R4A4_UNORM_PACK16: return D3DFMT_A4R4G4B4; // native - case DataFormat::A4R4G4B4_UNORM_PACK16: return D3DFMT_A4R4G4B4; // emulated - case DataFormat::R5G6B5_UNORM_PACK16: return D3DFMT_R5G6B5; - case DataFormat::A1R5G5B5_UNORM_PACK16: return D3DFMT_A1R5G5B5; - case DataFormat::D24_S8: return D3DFMT_D24S8; - case DataFormat::D16: return D3DFMT_D16; - case DataFormat::BC1_RGBA_UNORM_BLOCK: return D3DFMT_DXT1; - case DataFormat::BC2_UNORM_BLOCK: return D3DFMT_DXT3; // DXT3 is indeed BC2. - case DataFormat::BC3_UNORM_BLOCK: return D3DFMT_DXT5; // DXT5 is indeed BC3 - default: return D3DFMT_UNKNOWN; - } -} - -static int FormatToD3DDeclType(DataFormat type) { - switch (type) { - case DataFormat::R32_FLOAT: return D3DDECLTYPE_FLOAT1; - case DataFormat::R32G32_FLOAT: return D3DDECLTYPE_FLOAT2; - case DataFormat::R32G32B32_FLOAT: return D3DDECLTYPE_FLOAT3; - case DataFormat::R32G32B32A32_FLOAT: return D3DDECLTYPE_FLOAT4; - case DataFormat::R8G8B8A8_UNORM: return D3DDECLTYPE_UBYTE4N; // D3DCOLOR has a different byte ordering. - default: return D3DDECLTYPE_UNUSED; - } -} - -class D3D9Buffer; - -class D3D9DepthStencilState : public DepthStencilState { -public: - BOOL depthTestEnabled; - BOOL depthWriteEnabled; - D3DCMPFUNC depthCompare; - BOOL stencilEnabled; - D3DSTENCILOP stencilFail; - D3DSTENCILOP stencilZFail; - D3DSTENCILOP stencilPass; - D3DCMPFUNC stencilCompareOp; - - void Apply(LPDIRECT3DDEVICE9 device, uint8_t stencilRef, uint8_t stencilWriteMask, uint8_t stencilCompareMask) { - dxstate.depthTest.set(depthTestEnabled); - if (depthTestEnabled) { - dxstate.depthWrite.set(depthWriteEnabled); - dxstate.depthFunc.set(depthCompare); - } - dxstate.stencilTest.set(stencilEnabled); - if (stencilEnabled) { - dxstate.stencilOp.set(stencilFail, stencilZFail, stencilPass); - dxstate.stencilFunc.set(stencilCompareOp); - dxstate.stencilRef.set(stencilRef); - dxstate.stencilCompareMask.set(stencilCompareMask); - dxstate.stencilWriteMask.set(stencilWriteMask); - } - } -}; - -class D3D9RasterState : public RasterState { -public: - DWORD cullMode; // D3DCULL_* - - void Apply(LPDIRECT3DDEVICE9 device) { - dxstate.cullMode.set(cullMode); - dxstate.scissorTest.enable(); - // Force user clipping off. - dxstate.clipPlaneEnable.set(0); - } -}; - -class D3D9BlendState : public BlendState { -public: - bool enabled; - D3DBLENDOP eqCol, eqAlpha; - D3DBLEND srcCol, srcAlpha, dstCol, dstAlpha; - uint32_t colorMask; - - void Apply(LPDIRECT3DDEVICE9 device) { - dxstate.blend.set(enabled); - dxstate.blendFunc.set(srcCol, dstCol, srcAlpha, dstAlpha); - dxstate.blendEquation.set(eqCol, eqAlpha); - dxstate.colorMask.set(colorMask); - } -}; - -class D3D9SamplerState : public SamplerState { -public: - D3DTEXTUREADDRESS wrapS, wrapT; - D3DTEXTUREFILTERTYPE magFilt, minFilt, mipFilt; - - void Apply(LPDIRECT3DDEVICE9 device, int index) { - if (index == 0) { - dxstate.texAddressU.set(wrapS); - dxstate.texAddressV.set(wrapT); - dxstate.texMagFilter.set(magFilt); - dxstate.texMinFilter.set(minFilt); - dxstate.texMipFilter.set(mipFilt); - } else { - pD3Ddevice9->SetSamplerState(index, D3DSAMP_ADDRESSU, wrapS); - pD3Ddevice9->SetSamplerState(index, D3DSAMP_ADDRESSV, wrapT); - pD3Ddevice9->SetSamplerState(index, D3DSAMP_MAGFILTER, magFilt); - pD3Ddevice9->SetSamplerState(index, D3DSAMP_MINFILTER, minFilt); - pD3Ddevice9->SetSamplerState(index, D3DSAMP_MIPFILTER, mipFilt); - } - } -}; - -class D3D9InputLayout : public InputLayout { -public: - D3D9InputLayout(LPDIRECT3DDEVICE9 device, const InputLayoutDesc &desc); - ~D3D9InputLayout() { - } - int GetStride() const { return stride_; } - void Apply(LPDIRECT3DDEVICE9 device) { - device->SetVertexDeclaration(decl_.Get()); - } - -private: - ComPtr decl_; - int stride_; -}; - -class D3D9ShaderModule : public ShaderModule { -public: - D3D9ShaderModule(ShaderStage stage, const std::string &tag) : stage_(stage), tag_(tag) {} - ~D3D9ShaderModule() { - } - bool Compile(LPDIRECT3DDEVICE9 device, const uint8_t *data, size_t size); - void Apply(LPDIRECT3DDEVICE9 device) { - if (stage_ == ShaderStage::Fragment) { - device->SetPixelShader(pshader_.Get()); - } else { - device->SetVertexShader(vshader_.Get()); - } - } - ShaderStage GetStage() const override { return stage_; } - -private: - ShaderStage stage_; - ComPtr vshader_; - ComPtr pshader_; - std::string tag_; -}; - -class D3D9Pipeline : public Pipeline { -public: - D3D9Pipeline() {} - ~D3D9Pipeline() { - } - - D3D9ShaderModule *vshader = nullptr; - D3D9ShaderModule *pshader = nullptr; - - D3DPRIMITIVETYPE prim{}; - AutoRef inputLayout; - AutoRef depthStencil; - AutoRef blend; - AutoRef raster; - UniformBufferDesc dynamicUniforms{}; - - void Apply(LPDIRECT3DDEVICE9 device, uint8_t stencilRef, uint8_t stencilWriteMask, uint8_t stencilCompareMask); -}; - -class D3D9Texture : public Texture { -public: - D3D9Texture(LPDIRECT3DDEVICE9 device, LPDIRECT3DDEVICE9EX deviceEx, const TextureDesc &desc); - ~D3D9Texture(); - void SetToSampler(LPDIRECT3DDEVICE9 device, int sampler); - LPDIRECT3DBASETEXTURE9 TexturePtr() const { - // TODO: Cleanup - if (tex_) { - return tex_.Get(); - } else if (volTex_) { - return volTex_.Get(); - } else if (cubeTex_) { - return cubeTex_.Get(); - } else { - return nullptr; - } - } - void UpdateTextureLevels(const uint8_t * const *data, int numLevels, TextureCallback initDataCallback); - -private: - void SetImageData(int x, int y, int z, int width, int height, int depth, int level, int stride, const uint8_t *data, TextureCallback initDataCallback); - bool Create(const TextureDesc &desc); - ComPtr device_; - ComPtr deviceEx_; - TextureType type_; - D3DFORMAT d3dfmt_; - ComPtr tex_; - ComPtr volTex_; - ComPtr cubeTex_; -}; - -D3D9Texture::D3D9Texture(LPDIRECT3DDEVICE9 device, LPDIRECT3DDEVICE9EX deviceEx, const TextureDesc &desc) - : device_(device), deviceEx_(deviceEx), tex_(nullptr), volTex_(nullptr), cubeTex_(nullptr) { - Create(desc); -} - -D3D9Texture::~D3D9Texture() { -} - -bool D3D9Texture::Create(const TextureDesc &desc) { - width_ = desc.width; - height_ = desc.height; - depth_ = desc.depth; - type_ = desc.type; - format_ = desc.format; - tex_ = nullptr; - d3dfmt_ = FormatToD3DFMT(desc.format); - - if (d3dfmt_ == D3DFMT_UNKNOWN) { - return false; - } - HRESULT hr = E_FAIL; - - D3DPOOL pool = D3DPOOL_MANAGED; - int usage = 0; - if (deviceEx_ != nullptr) { - pool = D3DPOOL_DEFAULT; - usage = D3DUSAGE_DYNAMIC; - } - if (desc.generateMips) - usage |= D3DUSAGE_AUTOGENMIPMAP; - switch (type_) { - case TextureType::LINEAR1D: - case TextureType::LINEAR2D: - hr = device_->CreateTexture(desc.width, desc.height, desc.generateMips ? 0 : desc.mipLevels, usage, d3dfmt_, pool, &tex_, NULL); - break; - case TextureType::LINEAR3D: - hr = device_->CreateVolumeTexture(desc.width, desc.height, desc.depth, desc.mipLevels, usage, d3dfmt_, pool, &volTex_, NULL); - break; - case TextureType::CUBE: - hr = device_->CreateCubeTexture(desc.width, desc.mipLevels, usage, d3dfmt_, pool, &cubeTex_, NULL); - break; - } - if (FAILED(hr)) { - ERROR_LOG(Log::G3D, "D3D9 Texture creation failed"); - return false; - } - - if (desc.initData.size()) { - // In D3D9, after setting D3DUSAGE_AUTOGENMIPS, we can only access the top layer. The rest will be - // automatically generated. - int numLevels = desc.generateMips ? 1 : (int)desc.initData.size(); - UpdateTextureLevels(desc.initData.data(), numLevels, desc.initDataCallback); - } - return true; -} - -void D3D9Texture::UpdateTextureLevels(const uint8_t * const *data, int numLevels, TextureCallback initDataCallback) { - int w = width_; - int h = height_; - int d = depth_; - for (int i = 0; i < numLevels; i++) { - SetImageData(0, 0, 0, w, h, d, i, 0, data[i], initDataCallback); - w = (w + 1) / 2; - h = (h + 1) / 2; - d = (d + 1) / 2; - } -} - -// Just switches R and G. -inline uint32_t Shuffle8888(uint32_t x) { - return (x & 0xFF00FF00) | ((x >> 16) & 0xFF) | ((x << 16) & 0xFF0000); -} - -void D3D9Texture::SetImageData(int x, int y, int z, int width, int height, int depth, int level, int stride, const uint8_t *data, TextureCallback callback) { - if (!tex_) - return; - - if (level == 0) { - width_ = width; - height_ = height; - depth_ = depth; - } - - if (!stride) { - stride = width * (int)DataFormatSizeInBytes(format_); - } - - switch (type_) { - case TextureType::LINEAR2D: - { - D3DLOCKED_RECT rect; - if (x == 0 && y == 0) { - tex_->LockRect(level, &rect, NULL, D3DLOCK_DISCARD); - - if (callback) { - if (callback((uint8_t *)rect.pBits, data, width, height, depth, rect.Pitch, height * rect.Pitch)) { - // Now this is the source. All conversions below support in-place. - data = (const uint8_t *)rect.pBits; - stride = rect.Pitch; - } - } - - for (int i = 0; i < height; i++) { - uint8_t *dest = (uint8_t *)rect.pBits + rect.Pitch * i; - const uint8_t *source = data + stride * i; - int j; - switch (format_) { - case DataFormat::B4G4R4A4_UNORM_PACK16: // We emulate support for this format. - for (j = 0; j < width; j++) { - uint16_t color = ((const uint16_t *)source)[j]; - ((uint16_t *)dest)[j] = (color << 12) | (color >> 4); - } - break; - case DataFormat::A4R4G4B4_UNORM_PACK16: - case DataFormat::A1R5G5B5_UNORM_PACK16: - case DataFormat::R5G6B5_UNORM_PACK16: - // Native - if (data != rect.pBits) - memcpy(dest, source, width * sizeof(uint16_t)); - break; - - case DataFormat::R8G8B8A8_UNORM: - for (j = 0; j < width; j++) { - ((uint32_t *)dest)[j] = Shuffle8888(((uint32_t *)source)[j]); - } - break; - - case DataFormat::B8G8R8A8_UNORM: - if (data != rect.pBits) - memcpy(dest, source, sizeof(uint32_t) * width); - break; - - case DataFormat::R8_UNORM: - if (data != rect.pBits) - memcpy(dest, source, width); - break; - - case DataFormat::R16_UNORM: - if (data != rect.pBits) - memcpy(dest, source, sizeof(uint16_t) * width); - break; - - default: - // Unhandled data format copy. - DebugBreak(); - break; - } - } - tex_->UnlockRect(level); - } - break; - } - - default: - ERROR_LOG(Log::G3D, "Non-LINEAR2D textures not yet supported"); - break; - } -} - -void D3D9Texture::SetToSampler(LPDIRECT3DDEVICE9 device, int sampler) { - switch (type_) { - case TextureType::LINEAR1D: - case TextureType::LINEAR2D: - device->SetTexture(sampler, tex_.Get()); - break; - - case TextureType::LINEAR3D: - device->SetTexture(sampler, volTex_.Get()); - break; - - case TextureType::CUBE: - device->SetTexture(sampler, cubeTex_.Get()); - break; - } -} - -class D3D9Context : public DrawContext { -public: - D3D9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, IDirect3DDevice9 *device, IDirect3DDevice9Ex *deviceEx); - ~D3D9Context(); - - const DeviceCaps &GetDeviceCaps() const override { - return caps_; - } - uint32_t GetSupportedShaderLanguages() const override { - return (uint32_t)ShaderLanguage::HLSL_D3D9; - } - uint32_t GetDataFormatSupport(DataFormat fmt) const override; - - ShaderModule *CreateShaderModule(ShaderStage stage, ShaderLanguage language, const uint8_t *data, size_t dataSize, const char *tag) override; - DepthStencilState *CreateDepthStencilState(const DepthStencilStateDesc &desc) override; - BlendState *CreateBlendState(const BlendStateDesc &desc) override; - SamplerState *CreateSamplerState(const SamplerStateDesc &desc) override; - RasterState *CreateRasterState(const RasterStateDesc &desc) override; - Buffer *CreateBuffer(size_t size, uint32_t usageFlags) override; - Pipeline *CreateGraphicsPipeline(const PipelineDesc &desc, const char *tag) override; - InputLayout *CreateInputLayout(const InputLayoutDesc &desc) override; - Texture *CreateTexture(const TextureDesc &desc) override; - - Framebuffer *CreateFramebuffer(const FramebufferDesc &desc) override; - - void UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offset, size_t size, UpdateBufferFlags flags) override; - void UpdateTextureLevels(Texture *texture, const uint8_t **data, TextureCallback initDataCallback, int numLevels) override; - - void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, Aspect aspect, const char *tag) override { - // Not implemented - } - bool BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, Aspect aspects, FBBlitFilter filter, const char *tag) override; - bool CopyFramebufferToMemory(Framebuffer *src, Aspect channelBits, int x, int y, int w, int h, Draw::DataFormat format, void *pixels, int pixelStride, ReadbackMode mode, const char *tag) override; - - // These functions should be self explanatory. - void BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp, const char *tag) override; - void BindFramebufferAsTexture(Framebuffer *fbo, int binding, Aspect channelBit, int layer) override; - - uintptr_t GetFramebufferAPITexture(Framebuffer *fbo, Aspect aspect, int attachment) override; - - void GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) override; - - void BindTextures(int start, int count, Texture **textures, TextureBindFlags flags) override; - void BindNativeTexture(int index, void *nativeTexture) override; - - void BindSamplerStates(int start, int count, SamplerState **states) override { - _assert_(start + count <= MAX_BOUND_TEXTURES); - for (int i = 0; i < count; ++i) { - D3D9SamplerState *s = static_cast(states[i]); - if (s) - s->Apply(device_, start + i); - } - } - void BindVertexBuffer(Buffer *vertexBuffer, int offset) override { - curVBuffer_ = (D3D9Buffer *)vertexBuffer; - curVBufferOffset_ = offset; - } - void BindIndexBuffer(Buffer *indexBuffer, int offset) override { - curIBuffer_ = (D3D9Buffer *)indexBuffer; - curIBufferOffset_ = offset; - } - - void BindPipeline(Pipeline *pipeline) override { - curPipeline_ = (D3D9Pipeline *)pipeline; - } - - void BeginFrame(Draw::DebugFlags debugFlags) override; - void EndFrame() override; - void Present(PresentMode presentMode, int vblanks) override; - - int GetFrameCount() override { return frameCount_; } - - void UpdateDynamicUniformBuffer(const void *ub, size_t size) override; - - // Raster state - void SetScissorRect(int left, int top, int width, int height) override; - void SetViewport(const Viewport &viewport) override; - void SetBlendFactor(float color[4]) override; - void SetStencilParams(uint8_t refValue, uint8_t writeMask, uint8_t compareMask) override; - - void ApplyDynamicState(); - void Draw(int vertexCount, int offset) override; - void DrawIndexed(int vertexCount, int offset) override; - void DrawUP(const void *vdata, int vertexCount) override; - void DrawIndexedUP(const void *vdata, int vertexCount, const void *idata, int indexCount) override; - void DrawIndexedClippedBatchUP(const void *vdata, int vertexCount, const void *idata, int indexCount, Slice draws, const void *ub, size_t ubSize) override; - - void Clear(Aspect aspects, uint32_t colorval, float depthVal, int stencilVal) override; - - uint64_t GetNativeObject(NativeObject obj, void *srcObject) override { - switch (obj) { - case NativeObject::CONTEXT: - return (uint64_t)(uintptr_t)d3d_; - case NativeObject::DEVICE: - return (uint64_t)(uintptr_t)device_; - case NativeObject::DEVICE_EX: - return (uint64_t)(uintptr_t)deviceEx_; - case NativeObject::TEXTURE_VIEW: - return (uint64_t)(((D3D9Texture *)srcObject)->TexturePtr()); - default: - return 0; - } - } - - std::string GetInfoString(InfoField info) const override { - switch (info) { - case InfoField::APIVERSION: return "DirectX 9.0"; - case InfoField::VENDORSTRING: return identifier_.Description; - case InfoField::VENDOR: return ""; - case InfoField::DRIVER: return identifier_.Driver; // eh, sort of - case InfoField::SHADELANGVERSION: return shadeLangVersion_; - case InfoField::APINAME: return "Direct3D 9"; - default: return "?"; - } - } - - void HandleEvent(Event ev, int width, int height, void *param1, void *param2) override; - - void Invalidate(InvalidationFlags flags) override; - - void SetInvalidationCallback(InvalidationCallback callback) override { - invalidationCallback_ = callback; - } - -private: - LPDIRECT3D9 d3d_; - LPDIRECT3D9EX d3dEx_; - LPDIRECT3DDEVICE9 device_; - LPDIRECT3DDEVICE9EX deviceEx_; - int adapterId_ = -1; - D3DADAPTER_IDENTIFIER9 identifier_{}; - D3DCAPS9 d3dCaps_; - char shadeLangVersion_[64]{}; - DeviceCaps caps_{}; - int frameCount_ = FRAME_TIME_HISTORY_LENGTH; - - // Bound state - AutoRef curPipeline_; - AutoRef curVBuffer_; - int curVBufferOffset_ = 0; - AutoRef curIBuffer_; - int curIBufferOffset_ = 0; - AutoRef curRenderTarget_; - - u8 stencilRefValue_ = 0; - u8 stencilCompareMask_ = 0xFF; - u8 stencilWriteMask_ = 0xFF; - - // Framebuffer state - ComPtr deviceRTsurf; - ComPtr deviceDSsurf; - bool supportsINTZ = false; - - // Dynamic state - uint8_t stencilRef_ = 0; - - InvalidationCallback invalidationCallback_; -}; - -void D3D9Context::Invalidate(InvalidationFlags flags) { - if (flags & InvalidationFlags::CACHED_RENDER_STATE) { - curPipeline_ = nullptr; - } -} - -// TODO: Move this detection elsewhere when it's needed elsewhere, not before. It's ugly. -// Source: https://envytools.readthedocs.io/en/latest/hw/pciid.html#gf100 -enum NVIDIAGeneration { - NV_PRE_KEPLER, - NV_KEPLER, - NV_MAXWELL, - NV_PASCAL, - NV_VOLTA, - NV_TURING, // or later -}; - -static NVIDIAGeneration NVIDIAGetDeviceGeneration(int deviceID) { - if (deviceID >= 0x1180 && deviceID <= 0x11bf) - return NV_KEPLER; // GK104 - if (deviceID >= 0x11c0 && deviceID <= 0x11fa) - return NV_KEPLER; // GK106 - if (deviceID >= 0x0fc0 && deviceID <= 0x0fff) - return NV_KEPLER; // GK107 - if (deviceID >= 0x1003 && deviceID <= 0x1028) - return NV_KEPLER; // GK110(B) - if (deviceID >= 0x1280 && deviceID <= 0x12ba) - return NV_KEPLER; // GK208 - if (deviceID >= 0x1381 && deviceID <= 0x13b0) - return NV_MAXWELL; // GM107 - if (deviceID >= 0x1340 && deviceID <= 0x134d) - return NV_MAXWELL; // GM108 - if (deviceID >= 0x13c0 && deviceID <= 0x13d9) - return NV_MAXWELL; // GM204 - if (deviceID >= 0x1401 && deviceID <= 0x1427) - return NV_MAXWELL; // GM206 - if (deviceID >= 0x15f7 && deviceID <= 0x15f9) - return NV_PASCAL; // GP100 - if (deviceID >= 0x15f7 && deviceID <= 0x15f9) - return NV_PASCAL; // GP100 - if (deviceID >= 0x1b00 && deviceID <= 0x1b38) - return NV_PASCAL; // GP102 - if (deviceID >= 0x1b80 && deviceID <= 0x1be1) - return NV_PASCAL; // GP104 - if (deviceID >= 0x1c02 && deviceID <= 0x1c62) - return NV_PASCAL; // GP106 - if (deviceID >= 0x1c81 && deviceID <= 0x1c92) - return NV_PASCAL; // GP107 - if (deviceID >= 0x1d01 && deviceID <= 0x1d12) - return NV_PASCAL; // GP108 - if (deviceID >= 0x1d81 && deviceID <= 0x1dba) - return NV_VOLTA; // GV100 - if (deviceID >= 0x1e02 && deviceID <= 0x1e3c) - return NV_TURING; // TU102 - if (deviceID >= 0x1e82 && deviceID <= 0x1ed0) - return NV_TURING; // TU104 - if (deviceID >= 0x1f02 && deviceID <= 0x1f51) - return NV_TURING; // TU104 - if (deviceID >= 0x1e02) - return NV_TURING; // More TU models or later, probably. - return NV_PRE_KEPLER; -} - -#define FB_DIV 1 -#define FOURCC_INTZ ((D3DFORMAT)(MAKEFOURCC('I', 'N', 'T', 'Z'))) - -D3D9Context::D3D9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, IDirect3DDevice9 *device, IDirect3DDevice9Ex *deviceEx) - : d3d_(d3d), d3dEx_(d3dEx), device_(device), deviceEx_(deviceEx), adapterId_(adapterId), caps_{} { - if (FAILED(d3d->GetAdapterIdentifier(adapterId, 0, &identifier_))) { - ERROR_LOG(Log::G3D, "Failed to get adapter identifier: %d", adapterId); - } - - caps_.coordConvention = CoordConvention::Direct3D9; - - switch (identifier_.VendorId) { - case 0x10DE: caps_.vendor = GPUVendor::VENDOR_NVIDIA; break; - case 0x1002: - case 0x1022: caps_.vendor = GPUVendor::VENDOR_AMD; break; - case 0x163C: - case 0x8086: - case 0x8087: caps_.vendor = GPUVendor::VENDOR_INTEL; break; - default: - caps_.vendor = GPUVendor::VENDOR_UNKNOWN; - } - - D3DCAPS9 caps; - ZeroMemory(&caps, sizeof(caps)); - HRESULT result = 0; - if (deviceEx_) { - result = deviceEx_->GetDeviceCaps(&caps); - } else { - result = device_->GetDeviceCaps(&caps); - } - - if (SUCCEEDED(result)) { - snprintf(shadeLangVersion_, sizeof(shadeLangVersion_), "PS: %04x VS: %04x", d3dCaps_.PixelShaderVersion & 0xFFFF, d3dCaps_.VertexShaderVersion & 0xFFFF); - } else { - WARN_LOG(Log::G3D, "Direct3D9: Failed to get the device caps!"); - truncate_cpy(shadeLangVersion_, "N/A"); - } - - caps_.deviceID = identifier_.DeviceId; - caps_.depthRangeMinusOneToOne = false; - caps_.preferredDepthBufferFormat = DataFormat::D24_S8; - caps_.dualSourceBlend = false; - caps_.tesselationShaderSupported = false; - caps_.framebufferBlitSupported = true; - caps_.framebufferCopySupported = false; - caps_.framebufferDepthBlitSupported = false; - caps_.framebufferStencilBlitSupported = false; - caps_.framebufferDepthCopySupported = false; - caps_.framebufferSeparateDepthCopySupported = false; - caps_.texture3DSupported = true; - caps_.fragmentShaderDepthWriteSupported = true; - caps_.requiresHalfPixelOffset = true; - caps_.fragmentShaderStencilWriteSupported = false; - caps_.blendMinMaxSupported = true; - caps_.isTilingGPU = false; - caps_.multiSampleLevelsMask = 1; // More could be supported with some work. - - caps_.clipPlanesSupported = caps.MaxUserClipPlanes; - caps_.presentInstantModeChange = false; - caps_.presentMaxInterval = 1; - caps_.presentModesSupported = PresentMode::FIFO; - - caps_.provokingVertexLast = false; // D3D has it first, unfortunately (and no way to change it). - - if ((caps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) != 0 && caps.MaxAnisotropy > 1) { - caps_.anisoSupported = true; - } - if ((caps.TextureCaps & (D3DPTEXTURECAPS_NONPOW2CONDITIONAL | D3DPTEXTURECAPS_POW2)) == 0) { - caps_.textureNPOTFullySupported = true; - } - - caps_.supportsD3D9 = true; - if (!strcmp(identifier_.Description, "Intel(R) Iris(R) Xe Graphics")) { - caps_.supportsD3D9 = false; - } - - // VS range culling (killing triangles in the vertex shader using NaN) causes problems on Intel. - // Also causes problems on old NVIDIA. - switch (caps_.vendor) { - case Draw::GPUVendor::VENDOR_INTEL: - bugs_.Infest(Bugs::BROKEN_NAN_IN_CONDITIONAL); - break; - case Draw::GPUVendor::VENDOR_NVIDIA: - // Older NVIDIAs don't seem to like NaNs in their DX9 vertex shaders. - // No idea if KEPLER is the right cutoff, but let's go with it. - if (NVIDIAGetDeviceGeneration(caps_.deviceID) < NV_KEPLER) { - bugs_.Infest(Bugs::BROKEN_NAN_IN_CONDITIONAL); - } - break; - } - - if (d3d) { - D3DDISPLAYMODE displayMode; - d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode); - - // To be safe, make sure both the display format and the FBO format support INTZ. - HRESULT displayINTZ = d3d->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, displayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, FOURCC_INTZ); - HRESULT displayINTY = d3d->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, displayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, ((D3DFORMAT)(MAKEFOURCC('I', 'N', 'T', 'Y')))); - // Try to prevent INTZ on older Intel drivers that claim support. - supportsINTZ = SUCCEEDED(displayINTZ) && !SUCCEEDED(displayINTY) && IsWin7OrHigher(); - } - caps_.textureDepthSupported = supportsINTZ; - - shaderLanguageDesc_.Init(HLSL_D3D9); - - dxstate.Restore(); -} - -D3D9Context::~D3D9Context() { - DestroyPresets(); -} - -ShaderModule *D3D9Context::CreateShaderModule(ShaderStage stage, ShaderLanguage language, const uint8_t *data, size_t size, const char *tag) { - D3D9ShaderModule *shader = new D3D9ShaderModule(stage, tag); - if (shader->Compile(device_, data, size)) { - return shader; - } else { - delete shader; - return NULL; - } -} - -Pipeline *D3D9Context::CreateGraphicsPipeline(const PipelineDesc &desc, const char *tag) { - if (!desc.shaders.size()) { - ERROR_LOG(Log::G3D, "Pipeline %s requires at least one shader", tag); - return NULL; - } - D3D9Pipeline *pipeline = new D3D9Pipeline(); - for (auto iter : desc.shaders) { - if (!iter) { - ERROR_LOG(Log::G3D, "NULL shader passed to CreateGraphicsPipeline(%s)", tag); - delete pipeline; - return NULL; - } - if (iter->GetStage() == ShaderStage::Fragment) { - pipeline->pshader = static_cast(iter); - pipeline->pshader->AddRef(); - } - else if (iter->GetStage() == ShaderStage::Vertex) { - pipeline->vshader = static_cast(iter); - pipeline->vshader->AddRef(); - } - } - pipeline->prim = primToD3D9[(int)desc.prim]; - pipeline->depthStencil = (D3D9DepthStencilState *)desc.depthStencil; - pipeline->blend = (D3D9BlendState *)desc.blend; - pipeline->raster = (D3D9RasterState *)desc.raster; - pipeline->inputLayout = (D3D9InputLayout *)desc.inputLayout; - if (desc.uniformDesc) - pipeline->dynamicUniforms = *desc.uniformDesc; - return pipeline; -} - -DepthStencilState *D3D9Context::CreateDepthStencilState(const DepthStencilStateDesc &desc) { - D3D9DepthStencilState *ds = new D3D9DepthStencilState(); - ds->depthTestEnabled = desc.depthTestEnabled; - ds->depthWriteEnabled = desc.depthWriteEnabled; - ds->depthCompare = compareToD3D9[(int)desc.depthCompare]; - ds->stencilEnabled = desc.stencilEnabled; - ds->stencilCompareOp = compareToD3D9[(int)desc.stencil.compareOp]; - ds->stencilPass = stencilOpToD3D9[(int)desc.stencil.passOp]; - ds->stencilFail = stencilOpToD3D9[(int)desc.stencil.failOp]; - ds->stencilZFail = stencilOpToD3D9[(int)desc.stencil.depthFailOp]; - return ds; -} - -InputLayout *D3D9Context::CreateInputLayout(const InputLayoutDesc &desc) { - D3D9InputLayout *fmt = new D3D9InputLayout(device_, desc); - return fmt; -} - -BlendState *D3D9Context::CreateBlendState(const BlendStateDesc &desc) { - D3D9BlendState *bs = new D3D9BlendState(); - bs->enabled = desc.enabled; - bs->eqCol = blendEqToD3D9[(int)desc.eqCol]; - bs->srcCol = blendFactorToD3D9[(int)desc.srcCol]; - bs->dstCol = blendFactorToD3D9[(int)desc.dstCol]; - bs->eqAlpha = blendEqToD3D9[(int)desc.eqAlpha]; - bs->srcAlpha = blendFactorToD3D9[(int)desc.srcAlpha]; - bs->dstAlpha = blendFactorToD3D9[(int)desc.dstAlpha]; - bs->colorMask = desc.colorMask; - // Ignore logic ops, we don't support them in D3D9 - return bs; -} - -SamplerState *D3D9Context::CreateSamplerState(const SamplerStateDesc &desc) { - D3D9SamplerState *samps = new D3D9SamplerState(); - samps->wrapS = texWrapToD3D9[(int)desc.wrapU]; - samps->wrapT = texWrapToD3D9[(int)desc.wrapV]; - samps->magFilt = texFilterToD3D9[(int)desc.magFilter]; - samps->minFilt = texFilterToD3D9[(int)desc.minFilter]; - samps->mipFilt = texFilterToD3D9[(int)desc.mipFilter]; - return samps; -} - -RasterState *D3D9Context::CreateRasterState(const RasterStateDesc &desc) { - D3D9RasterState *rs = new D3D9RasterState(); - rs->cullMode = D3DCULL_NONE; - if (desc.cull == CullMode::NONE) { - return rs; - } - switch (desc.frontFace) { - case Facing::CW: - switch (desc.cull) { - case CullMode::FRONT: rs->cullMode = D3DCULL_CCW; break; - case CullMode::BACK: rs->cullMode = D3DCULL_CW; break; - } - case Facing::CCW: - switch (desc.cull) { - case CullMode::FRONT: rs->cullMode = D3DCULL_CW; break; - case CullMode::BACK: rs->cullMode = D3DCULL_CCW; break; - } - } - return rs; -} - -Texture *D3D9Context::CreateTexture(const TextureDesc &desc) { - D3D9Texture *tex = new D3D9Texture(device_, deviceEx_, desc); - return tex; -} - -void D3D9Context::UpdateTextureLevels(Texture *texture, const uint8_t **data, TextureCallback initDataCallback, int numLevels) { - D3D9Texture *tex = (D3D9Texture *)texture; - tex->UpdateTextureLevels(data, numLevels, initDataCallback); -} - - -void D3D9Context::BindTextures(int start, int count, Texture **textures, TextureBindFlags flags) { - _assert_(start + count <= MAX_BOUND_TEXTURES); - for (int i = start; i < start + count; i++) { - D3D9Texture *tex = static_cast(textures[i - start]); - if (tex) { - tex->SetToSampler(device_, i); - } else { - device_->SetTexture(i, nullptr); - } - } -} - -void D3D9Context::BindNativeTexture(int index, void *nativeTexture) { - LPDIRECT3DTEXTURE9 texture = (LPDIRECT3DTEXTURE9)nativeTexture; - device_->SetTexture(index, texture); -} - -void D3D9Context::BeginFrame(Draw::DebugFlags debugFlags) { - FrameTimeData frameTimeData = frameTimeHistory_.Add(frameCount_); - frameTimeData.frameBegin = time_now_d(); - frameTimeData.afterFenceWait = frameTimeData.frameBegin; // no fence wait -} - -void D3D9Context::EndFrame() { - frameTimeHistory_[frameCount_].firstSubmit = time_now_d(); - curPipeline_ = nullptr; -} - -void D3D9Context::Present(PresentMode presentMode, int vblanks) { - frameTimeHistory_[frameCount_].queuePresent = time_now_d(); - if (deviceEx_) { - deviceEx_->EndScene(); - deviceEx_->PresentEx(NULL, NULL, NULL, NULL, 0); - deviceEx_->BeginScene(); - } else { - device_->EndScene(); - device_->Present(NULL, NULL, NULL, NULL); - device_->BeginScene(); - } - frameCount_++; -} - -static void SemanticToD3D9UsageAndIndex(int semantic, BYTE *usage, BYTE *index) { - *index = 0; - switch (semantic) { - case SEM_POSITION: - *usage = D3DDECLUSAGE_POSITION; - break; - case SEM_NORMAL: - *usage = D3DDECLUSAGE_NORMAL; - break; - case SEM_TANGENT: - *usage = D3DDECLUSAGE_TANGENT; - break; - case SEM_BINORMAL: - *usage = D3DDECLUSAGE_BINORMAL; - break; - case SEM_COLOR0: - *usage = D3DDECLUSAGE_COLOR; - break; - case SEM_COLOR1: - *usage = D3DDECLUSAGE_COLOR; - *index = 1; - break; - case SEM_TEXCOORD0: - *usage = D3DDECLUSAGE_TEXCOORD; - break; - case SEM_TEXCOORD1: - *usage = D3DDECLUSAGE_TEXCOORD; - *index = 1; - break; - } -} - -class D3D9Framebuffer : public Framebuffer { -public: - D3D9Framebuffer(int width, int height) { - width_ = width; - height_ = height; - } - ~D3D9Framebuffer(); - - uint32_t id = 0; - ComPtr surf; - ComPtr depthstencil; - ComPtr tex; - ComPtr depthstenciltex; -}; - -D3D9InputLayout::D3D9InputLayout(LPDIRECT3DDEVICE9 device, const InputLayoutDesc &desc) : decl_(NULL) { - D3DVERTEXELEMENT9 *elements = new D3DVERTEXELEMENT9[desc.attributes.size() + 1]; - size_t i; - for (i = 0; i < desc.attributes.size(); i++) { - elements[i].Stream = 0; - elements[i].Offset = desc.attributes[i].offset; - elements[i].Method = D3DDECLMETHOD_DEFAULT; - SemanticToD3D9UsageAndIndex(desc.attributes[i].location, &elements[i].Usage, &elements[i].UsageIndex); - elements[i].Type = FormatToD3DDeclType(desc.attributes[i].format); - } - D3DVERTEXELEMENT9 end = D3DDECL_END(); - // Zero the last one. - memcpy(&elements[i], &end, sizeof(elements[i])); - - stride_ = desc.stride; - - HRESULT hr = device->CreateVertexDeclaration(elements, &decl_); - if (FAILED(hr)) { - ERROR_LOG(Log::G3D, "Error creating vertex decl"); - } - delete[] elements; -} - -// Simulate a simple buffer type like the other backends have, use the usage flags to create the right internal type. -class D3D9Buffer : public Buffer { -public: - D3D9Buffer(LPDIRECT3DDEVICE9 device, size_t size, uint32_t flags) : vbuffer_(nullptr), ibuffer_(nullptr), maxSize_(size) { - if (flags & BufferUsageFlag::INDEXDATA) { - DWORD usage = D3DUSAGE_DYNAMIC; - device->CreateIndexBuffer((UINT)size, usage, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ibuffer_, NULL); - } else { - DWORD usage = D3DUSAGE_DYNAMIC; - device->CreateVertexBuffer((UINT)size, usage, 0, D3DPOOL_DEFAULT, &vbuffer_, NULL); - } - } - ~D3D9Buffer() { - } - - ComPtr vbuffer_; - ComPtr ibuffer_; - size_t maxSize_; -}; - -Buffer *D3D9Context::CreateBuffer(size_t size, uint32_t usageFlags) { - return new D3D9Buffer(device_, size, usageFlags); -} - -inline void Transpose4x4(float out[16], const float in[16]) { - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - out[i * 4 + j] = in[j * 4 + i]; - } - } -} - -void D3D9Context::UpdateDynamicUniformBuffer(const void *ub, size_t size) { - _assert_(size == curPipeline_->dynamicUniforms.uniformBufferSize); - for (auto &uniform : curPipeline_->dynamicUniforms.uniforms) { - int count = 0; - switch (uniform.type) { - case UniformType::FLOAT1: - case UniformType::FLOAT2: - case UniformType::FLOAT3: - case UniformType::FLOAT4: - count = 1; - break; - case UniformType::MATRIX4X4: - count = 4; - break; - } - const float *srcPtr = (const float *)((const uint8_t *)ub + uniform.offset); - if (uniform.vertexReg != -1) { - float transp[16]; - if (count == 4) { - Transpose4x4(transp, srcPtr); - srcPtr = transp; - } - device_->SetVertexShaderConstantF(uniform.vertexReg, srcPtr, count); - } - if (uniform.fragmentReg != -1) { - device_->SetPixelShaderConstantF(uniform.fragmentReg, srcPtr, count); - } - } -} - -void D3D9Context::UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offset, size_t size, UpdateBufferFlags flags) { - D3D9Buffer *buf = (D3D9Buffer *)buffer; - if (!size) - return; - if (offset + size > buf->maxSize_) { - ERROR_LOG(Log::G3D, "Can't SubData with bigger size than buffer was created with"); - return; - } - if (buf->vbuffer_) { - void *ptr = nullptr; - HRESULT res = buf->vbuffer_->Lock((UINT)offset, (UINT)size, &ptr, (flags & UPDATE_DISCARD) ? D3DLOCK_DISCARD : 0); - if (!FAILED(res) && ptr) { - memcpy(ptr, data, size); - buf->vbuffer_->Unlock(); - } - } else if (buf->ibuffer_) { - void *ptr = nullptr; - HRESULT res = buf->ibuffer_->Lock((UINT)offset, (UINT)size, &ptr, (flags & UPDATE_DISCARD) ? D3DLOCK_DISCARD : 0); - if (!FAILED(res) && ptr) { - memcpy(ptr, data, size); - buf->ibuffer_->Unlock(); - } - } -} - -void D3D9Pipeline::Apply(LPDIRECT3DDEVICE9 device, uint8_t stencilRef, uint8_t stencilWriteMask, uint8_t stencilCompareMask) { - vshader->Apply(device); - pshader->Apply(device); - blend->Apply(device); - depthStencil->Apply(device, stencilRef, stencilWriteMask, stencilCompareMask); - raster->Apply(device); -} - -void D3D9Context::ApplyDynamicState() { - // Apply dynamic state. - if (curPipeline_->depthStencil->stencilEnabled) { - device_->SetRenderState(D3DRS_STENCILREF, (DWORD)stencilRefValue_); - device_->SetRenderState(D3DRS_STENCILWRITEMASK, (DWORD)stencilWriteMask_); - device_->SetRenderState(D3DRS_STENCILMASK, (DWORD)stencilCompareMask_); - } -} - -static const int D3DPRIMITIVEVERTEXCOUNT[8][2] = { - {0, 0}, // invalid - {1, 0}, // 1 = D3DPT_POINTLIST, - {2, 0}, // 2 = D3DPT_LINELIST, - {2, 1}, // 3 = D3DPT_LINESTRIP, - {3, 0}, // 4 = D3DPT_TRIANGLELIST, - {1, 2}, // 5 = D3DPT_TRIANGLESTRIP, - {1, 2}, // 6 = D3DPT_TRIANGLEFAN, -}; - -inline int D3DPrimCount(D3DPRIMITIVETYPE prim, int size) { - return (size / D3DPRIMITIVEVERTEXCOUNT[prim][0]) - D3DPRIMITIVEVERTEXCOUNT[prim][1]; -} - -void D3D9Context::Draw(int vertexCount, int offset) { - device_->SetStreamSource(0, curVBuffer_->vbuffer_.Get(), curVBufferOffset_, curPipeline_->inputLayout->GetStride()); - curPipeline_->inputLayout->Apply(device_); - curPipeline_->Apply(device_, stencilRef_, stencilWriteMask_, stencilCompareMask_); - ApplyDynamicState(); - device_->DrawPrimitive(curPipeline_->prim, offset, D3DPrimCount(curPipeline_->prim, vertexCount)); -} - -void D3D9Context::DrawIndexed(int vertexCount, int offset) { - curPipeline_->inputLayout->Apply(device_); - curPipeline_->Apply(device_, stencilRef_, stencilWriteMask_, stencilCompareMask_); - ApplyDynamicState(); - device_->SetStreamSource(0, curVBuffer_->vbuffer_.Get(), curVBufferOffset_, curPipeline_->inputLayout->GetStride()); - device_->SetIndices(curIBuffer_->ibuffer_.Get()); - device_->DrawIndexedPrimitive(curPipeline_->prim, 0, 0, vertexCount, offset, D3DPrimCount(curPipeline_->prim, vertexCount)); -} - -void D3D9Context::DrawUP(const void *vdata, int vertexCount) { - curPipeline_->inputLayout->Apply(device_); - curPipeline_->Apply(device_, stencilRef_, stencilWriteMask_, stencilCompareMask_); - ApplyDynamicState(); - - device_->DrawPrimitiveUP(curPipeline_->prim, D3DPrimCount(curPipeline_->prim, vertexCount), vdata, curPipeline_->inputLayout->GetStride()); -} - -void D3D9Context::DrawIndexedUP(const void *vdata, int vertexCount, const void *idata, int indexCount) { - curPipeline_->inputLayout->Apply(device_); - curPipeline_->Apply(device_, stencilRef_, stencilWriteMask_, stencilCompareMask_); - ApplyDynamicState(); - - device_->DrawIndexedPrimitiveUP(curPipeline_->prim, 0, vertexCount, D3DPrimCount(curPipeline_->prim, indexCount), - idata, D3DFMT_INDEX16, - vdata, curPipeline_->inputLayout->GetStride()); -} - -void D3D9Context::DrawIndexedClippedBatchUP(const void *vdata, int vertexCount, const void *idata, int indexCount, Slice draws, const void *ub, size_t ubSize) { - if (draws.is_empty() || !vertexCount || !indexCount) { - return; - } - - BindPipeline(draws[0].pipeline); - curPipeline_->inputLayout->Apply(device_); - curPipeline_->Apply(device_, stencilRef_, stencilWriteMask_, stencilCompareMask_); - ApplyDynamicState(); - UpdateDynamicUniformBuffer(ub, ubSize); - - // Suboptimal! Should dirty-track textures. - for (int i = 0; i < draws.size(); i++) { - if (draws[i].pipeline != curPipeline_) { - D3D9Pipeline *d3d9Pipeline = (D3D9Pipeline *)draws[i].pipeline; - d3d9Pipeline->Apply(device_, stencilRef_, stencilWriteMask_, stencilCompareMask_); - curPipeline_ = d3d9Pipeline; - } - - if (draws[i].bindTexture) { - device_->SetTexture(0, ((D3D9Texture *)draws[i].bindTexture)->TexturePtr()); - } else if (draws[i].bindFramebufferAsTex) { - // We ignore aspect in D3D9 :( - device_->SetTexture(0, ((D3D9Framebuffer *)draws[i].bindFramebufferAsTex)->tex.Get()); - } - - RECT rc; - rc.left = draws[i].clipx; - rc.top = draws[i].clipy; - rc.right = draws[i].clipx + draws[i].clipw; - rc.bottom = draws[i].clipy + draws[i].cliph; - - device_->SetScissorRect(&rc); - device_->DrawIndexedPrimitiveUP(curPipeline_->prim, 0, vertexCount, D3DPrimCount(curPipeline_->prim, draws[i].indexCount), - (uint16_t *)idata + draws[i].indexOffset, D3DFMT_INDEX16, - vdata, curPipeline_->inputLayout->GetStride()); - } -} - -static uint32_t SwapRB(uint32_t c) { - return (c & 0xFF00FF00) | ((c >> 16) & 0xFF) | ((c << 16) & 0xFF0000); -} - -void D3D9Context::Clear(Aspect aspects, uint32_t colorval, float depthVal, int stencilVal) { - UINT d3dMask = 0; - if (aspects & Aspect::COLOR_BIT) d3dMask |= D3DCLEAR_TARGET; - if (aspects & Aspect::DEPTH_BIT) d3dMask |= D3DCLEAR_ZBUFFER; - if (aspects & Aspect::STENCIL_BIT) d3dMask |= D3DCLEAR_STENCIL; - if (d3dMask) { - device_->Clear(0, NULL, d3dMask, (D3DCOLOR)SwapRB(colorval), depthVal, stencilVal); - } -} - -void D3D9Context::SetScissorRect(int left, int top, int width, int height) { - dxstate.scissorRect.set(left, top, left + width, top + height); - dxstate.scissorTest.set(true); -} - -void D3D9Context::SetViewport(const Viewport &viewport) { - int x = (int)viewport.TopLeftX; - int y = (int)viewport.TopLeftY; - int w = (int)viewport.Width; - int h = (int)viewport.Height; - dxstate.viewport.set(x, y, w, h, viewport.MinDepth, viewport.MaxDepth); -} - -void D3D9Context::SetBlendFactor(float color[4]) { - uint32_t r = (uint32_t)(color[0] * 255.0f); - uint32_t g = (uint32_t)(color[1] * 255.0f); - uint32_t b = (uint32_t)(color[2] * 255.0f); - uint32_t a = (uint32_t)(color[3] * 255.0f); - dxstate.blendColor.set(color); -} - -void D3D9Context::SetStencilParams(uint8_t refValue, uint8_t writeMask, uint8_t compareMask) { - stencilRefValue_ = refValue; - stencilWriteMask_ = writeMask; - stencilCompareMask_ = compareMask; -} - -bool D3D9ShaderModule::Compile(LPDIRECT3DDEVICE9 device, const uint8_t *data, size_t size) { - LPD3D_SHADER_MACRO defines = nullptr; - LPD3DINCLUDE includes = nullptr; - ComPtr codeBuffer; - ComPtr errorBuffer; - const char *source = (const char *)data; - auto compile = [&](const char *profile) -> HRESULT { - return dyn_D3DCompile(source, (UINT)strlen(source), nullptr, defines, includes, "main", profile, 0, 0, &codeBuffer, &errorBuffer); - }; - HRESULT hr = compile(stage_ == ShaderStage::Fragment ? "ps_3_0" : "vs_3_0"); - if (FAILED(hr)) { - const char *error = errorBuffer ? (const char *)errorBuffer->GetBufferPointer() : "(no errorbuffer returned)"; - if (hr == ERROR_MOD_NOT_FOUND) { - // No D3D9-compatible shader compiler installed. - error = "D3D9 shader compiler not installed"; - } - - ERROR_LOG(Log::G3D, "Compile error: %s", error); - ERROR_LOG(Log::G3D, "%s", LineNumberString(std::string((const char *)data)).c_str()); - - OutputDebugStringA(source); - OutputDebugStringA(error); - return false; - } - - bool success = false; - if (stage_ == ShaderStage::Fragment) { - HRESULT result = device->CreatePixelShader((DWORD *)codeBuffer->GetBufferPointer(), &pshader_); - success = SUCCEEDED(result); - } else { - HRESULT result = device->CreateVertexShader((DWORD *)codeBuffer->GetBufferPointer(), &vshader_); - success = SUCCEEDED(result); - } - - return true; -} - -Framebuffer *D3D9Context::CreateFramebuffer(const FramebufferDesc &desc) { - // Don't think D3D9 does array layers. - _dbg_assert_(desc.numLayers == 1); - - static uint32_t id = 0; - - D3D9Framebuffer *fbo = new D3D9Framebuffer(desc.width, desc.height); - fbo->depthstenciltex = nullptr; - - HRESULT rtResult = device_->CreateTexture(desc.width, desc.height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &fbo->tex, nullptr); - if (FAILED(rtResult)) { - ERROR_LOG(Log::G3D, "Failed to create render target"); - fbo->Release(); - return NULL; - } - fbo->tex->GetSurfaceLevel(0, &fbo->surf); - - HRESULT dsResult; - if (supportsINTZ) { - dsResult = device_->CreateTexture(desc.width, desc.height, 1, D3DUSAGE_DEPTHSTENCIL, FOURCC_INTZ, D3DPOOL_DEFAULT, &fbo->depthstenciltex, NULL); - if (SUCCEEDED(dsResult)) { - dsResult = fbo->depthstenciltex->GetSurfaceLevel(0, &fbo->depthstencil); - } - } else { - dsResult = device_->CreateDepthStencilSurface(desc.width, desc.height, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &fbo->depthstencil, NULL); - } - if (FAILED(dsResult)) { - ERROR_LOG(Log::G3D, "Failed to create depth buffer"); - fbo->surf = nullptr; - fbo->tex = nullptr; - fbo->depthstenciltex = nullptr; - delete fbo; - return NULL; - } - fbo->id = id++; - return fbo; -} - -D3D9Framebuffer::~D3D9Framebuffer() { -} - -void D3D9Context::BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp, const char *tag) { - if (fbo) { - D3D9Framebuffer *fb = (D3D9Framebuffer *)fbo; - device_->SetRenderTarget(0, fb->surf.Get()); - device_->SetDepthStencilSurface(fb->depthstencil.Get()); - curRenderTarget_ = fb; - } else { - device_->SetRenderTarget(0, deviceRTsurf.Get()); - device_->SetDepthStencilSurface(deviceDSsurf.Get()); - curRenderTarget_ = nullptr; - } - - int clearFlags = 0; - if (rp.color == RPAction::CLEAR) { - clearFlags |= D3DCLEAR_TARGET; - } - if (rp.depth == RPAction::CLEAR) { - clearFlags |= D3DCLEAR_ZBUFFER; - } - if (rp.stencil == RPAction::CLEAR) { - clearFlags |= D3DCLEAR_STENCIL; - } - if (clearFlags) { - dxstate.scissorTest.force(false); - device_->Clear(0, nullptr, clearFlags, (D3DCOLOR)SwapRB(rp.clearColor), rp.clearDepth, rp.clearStencil); - dxstate.scissorRect.restore(); - } - - dxstate.scissorRect.restore(); - dxstate.scissorTest.restore(); - dxstate.viewport.restore(); - - if (invalidationCallback_) { - invalidationCallback_(InvalidationCallbackFlags::RENDER_PASS_STATE); - } -} - -uintptr_t D3D9Context::GetFramebufferAPITexture(Framebuffer *fbo, Aspect aspect, int attachment) { - D3D9Framebuffer *fb = (D3D9Framebuffer *)fbo; - if (aspect & Aspect::SURFACE_BIT) { - switch ((Aspect)(aspect & (Aspect)7)) { - case Aspect::DEPTH_BIT: - return (uintptr_t)fb->depthstencil.Get(); - case Aspect::STENCIL_BIT: - return (uintptr_t)fb->depthstencil.Get(); - case Aspect::COLOR_BIT: - default: - return (uintptr_t)fb->surf.Get(); - } - } else { - switch ((Aspect)(aspect & (Aspect)7)) { - case Aspect::DEPTH_BIT: - return (uintptr_t)fb->depthstenciltex.Get(); - case Aspect::STENCIL_BIT: - return 0; // Can't texture from stencil - case Aspect::COLOR_BIT: - default: - return (uintptr_t)fb->tex.Get(); - } - } -} - -void D3D9Context::BindFramebufferAsTexture(Framebuffer *fbo, int binding, Aspect channelBit, int layer) { - _dbg_assert_(binding < MAX_BOUND_TEXTURES); - _dbg_assert_(layer == ALL_LAYERS || layer == 0); // No stereo support - D3D9Framebuffer *fb = (D3D9Framebuffer *)fbo; - switch (channelBit) { - case Aspect::DEPTH_BIT: - if (fb->depthstenciltex) { - device_->SetTexture(binding, fb->depthstenciltex.Get()); - } - break; - case Aspect::COLOR_BIT: - default: - if (fb->tex) { - device_->SetTexture(binding, fb->tex.Get()); - } - break; - } -} - -void D3D9Context::GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) { - D3D9Framebuffer *fb = (D3D9Framebuffer *)fbo; - if (fb) { - *w = fb->Width(); - *h = fb->Height(); - } else { - *w = targetWidth_; - *h = targetHeight_; - } -} - -bool D3D9Context::BlitFramebuffer(Framebuffer *srcfb, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dstfb, int dstX1, int dstY1, int dstX2, int dstY2, Aspect aspects, FBBlitFilter filter, const char *tag) { - D3D9Framebuffer *src = (D3D9Framebuffer *)srcfb; - D3D9Framebuffer *dst = (D3D9Framebuffer *)dstfb; - - ComPtr srcSurf; - ComPtr dstSurf; - RECT srcRect{ (LONG)srcX1, (LONG)srcY1, (LONG)srcX2, (LONG)srcY2 }; - RECT dstRect{ (LONG)dstX1, (LONG)dstY1, (LONG)dstX2, (LONG)dstY2 }; - if (aspects == Aspect::COLOR_BIT) { - srcSurf = src ? src->surf : deviceRTsurf; - dstSurf = dst ? dst->surf : deviceRTsurf; - } else if (aspects & Aspect::DEPTH_BIT) { - if (!src || !dst) { - // Might have implications for non-buffered rendering. - return false; - } - srcSurf = src->depthstencil; - dstSurf = dst->depthstencil; - } else { - return false; - } - return SUCCEEDED(device_->StretchRect(srcSurf.Get(), &srcRect, dstSurf.Get(), &dstRect, (filter == FB_BLIT_LINEAR && aspects == Aspect::COLOR_BIT) ? D3DTEXF_LINEAR : D3DTEXF_POINT)); -} - -bool D3D9Context::CopyFramebufferToMemory(Framebuffer *src, Aspect aspects, int bx, int by, int bw, int bh, Draw::DataFormat destFormat, void *pixels, int pixelStride, ReadbackMode mode, const char *tag) { - D3D9Framebuffer *fb = (D3D9Framebuffer *)src; - - if (fb) { - if (bx + bw > fb->Width()) { - bw -= (bx + bw) - fb->Width(); - } - if (by + bh > fb->Height()) { - bh -= (by + bh) - fb->Height(); - } - } - - if (bh <= 0 || bw <= 0) - return true; - - DataFormat srcFormat = Draw::DataFormat::R8G8B8A8_UNORM; - if (aspects != Aspect::COLOR_BIT) { - srcFormat = Draw::DataFormat::D24_S8; - if (!supportsINTZ) - return false; - } - - D3DSURFACE_DESC desc; - D3DLOCKED_RECT locked; - RECT rect = { (LONG)bx, (LONG)by, (LONG)bw, (LONG)bh }; - - ComPtr offscreen; - HRESULT hr = E_UNEXPECTED; - if (aspects == Aspect::COLOR_BIT) { - if (fb) - fb->tex->GetLevelDesc(0, &desc); - else - deviceRTsurf->GetDesc(&desc); - - hr = device_->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &offscreen, nullptr); - if (SUCCEEDED(hr)) { - hr = device_->GetRenderTargetData(fb ? fb->surf.Get() : deviceRTsurf.Get(), offscreen.Get()); - if (SUCCEEDED(hr)) { - hr = offscreen->LockRect(&locked, &rect, D3DLOCK_READONLY); - } - } - } else { - _assert_(fb->depthstenciltex != nullptr); - fb->depthstenciltex->GetLevelDesc(0, &desc); - hr = fb->depthstenciltex->LockRect(0, &locked, &rect, D3DLOCK_READONLY); - } - - if (SUCCEEDED(hr)) { - switch (aspects) { - case Aspect::COLOR_BIT: - // Pixel size always 4 here because we always request BGRA8888. - ConvertFromBGRA8888((uint8_t *)pixels, (const uint8_t *)locked.pBits, pixelStride, locked.Pitch / sizeof(uint32_t), bw, bh, destFormat); - break; - case Aspect::DEPTH_BIT: - if (srcFormat == destFormat) { - // Can just memcpy when it matches no matter the format! - uint8_t *dst = (uint8_t *)pixels; - const uint8_t *src = (const uint8_t *)locked.pBits; - for (int y = 0; y < bh; ++y) { - memcpy(dst, src, bw * DataFormatSizeInBytes(srcFormat)); - dst += pixelStride * DataFormatSizeInBytes(srcFormat); - src += locked.Pitch; - } - } else if (destFormat == DataFormat::D32F) { - ConvertToD32F((uint8_t *)pixels, (const uint8_t *)locked.pBits, pixelStride, locked.Pitch / sizeof(uint32_t), bw, bh, srcFormat); - } else if (destFormat == DataFormat::D16) { - ConvertToD16((uint8_t *)pixels, (const uint8_t *)locked.pBits, pixelStride, locked.Pitch / sizeof(uint32_t), bw, bh, srcFormat); - } else { - _assert_(false); - } - break; - case Aspect::STENCIL_BIT: - if (srcFormat == destFormat) { - uint8_t *dst = (uint8_t *)pixels; - const uint8_t *src = (const uint8_t *)locked.pBits; - for (int y = 0; y < bh; ++y) { - memcpy(dst, src, bw * DataFormatSizeInBytes(srcFormat)); - dst += pixelStride * DataFormatSizeInBytes(srcFormat); - src += locked.Pitch; - } - } else if (destFormat == DataFormat::S8) { - for (int y = 0; y < bh; y++) { - uint8_t *destStencil = (uint8_t *)pixels + y * pixelStride; - const uint32_t *src = (const uint32_t *)((const uint8_t *)locked.pBits + locked.Pitch * y); - for (int x = 0; x < bw; x++) { - destStencil[x] = src[x] >> 24; - } - } - } else { - _assert_(false); - } - break; - } - } - - if (aspects != Aspect::COLOR_BIT) { - fb->depthstenciltex->UnlockRect(0); - } - if (offscreen) { - offscreen->UnlockRect(); - } - - return SUCCEEDED(hr); -} - -void D3D9Context::HandleEvent(Event ev, int width, int height, void *param1, void *param2) { - switch (ev) { - case Event::LOST_BACKBUFFER: - deviceRTsurf = nullptr; - deviceDSsurf = nullptr; - break; - case Event::GOT_BACKBUFFER: - device_->GetRenderTarget(0, &deviceRTsurf); - device_->GetDepthStencilSurface(&deviceDSsurf); - break; - case Event::PRESENTED: - break; - } -} - -DrawContext *T3DCreateDX9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, IDirect3DDevice9 *device, IDirect3DDevice9Ex *deviceEx) { - bool result = LoadD3DCompilerDynamic(); - if (!result) { - ERROR_LOG(Log::G3D, "Failed to load D3DCompiler!"); - return nullptr; - } - return new D3D9Context(d3d, d3dEx, adapterId, device, deviceEx); -} - -// Only partial implementation! -uint32_t D3D9Context::GetDataFormatSupport(DataFormat fmt) const { - switch (fmt) { - case DataFormat::B8G8R8A8_UNORM: - return FMT_RENDERTARGET | FMT_TEXTURE | FMT_AUTOGEN_MIPS; - - case DataFormat::R4G4B4A4_UNORM_PACK16: - return 0; - case DataFormat::B4G4R4A4_UNORM_PACK16: - return FMT_TEXTURE; // emulated support - case DataFormat::R5G6B5_UNORM_PACK16: - case DataFormat::A1R5G5B5_UNORM_PACK16: - case DataFormat::A4R4G4B4_UNORM_PACK16: - return FMT_RENDERTARGET | FMT_TEXTURE | FMT_AUTOGEN_MIPS; // native support - - case DataFormat::R8G8B8A8_UNORM: - return FMT_RENDERTARGET | FMT_TEXTURE | FMT_INPUTLAYOUT | FMT_AUTOGEN_MIPS; - - case DataFormat::R32_FLOAT: - case DataFormat::R32G32_FLOAT: - case DataFormat::R32G32B32_FLOAT: - case DataFormat::R32G32B32A32_FLOAT: - return FMT_INPUTLAYOUT; - - case DataFormat::R8_UNORM: - return 0; - case DataFormat::BC1_RGBA_UNORM_BLOCK: - case DataFormat::BC2_UNORM_BLOCK: - case DataFormat::BC3_UNORM_BLOCK: - // DXT1, DXT3, DXT5. - return FMT_TEXTURE; - default: - return 0; - } -} - - -} // namespace Draw diff --git a/Common/GPU/OpenGL/thin3d_gl.cpp b/Common/GPU/OpenGL/thin3d_gl.cpp index fdf8afd5714b..3b027d192da8 100644 --- a/Common/GPU/OpenGL/thin3d_gl.cpp +++ b/Common/GPU/OpenGL/thin3d_gl.cpp @@ -633,14 +633,6 @@ OpenGLContext::OpenGLContext(bool canChangeSwapInterval) : renderManager_(frameT break; } - // Hide D3D9 when we know it likely won't work well. -#if PPSSPP_PLATFORM(WINDOWS) - caps_.supportsD3D9 = true; - if (!strcmp(gl_extensions.model, "Intel(R) Iris(R) Xe Graphics")) { - caps_.supportsD3D9 = false; - } -#endif - // Very rough heuristic! caps_.isTilingGPU = gl_extensions.IsGLES && caps_.vendor != GPUVendor::VENDOR_NVIDIA && caps_.vendor != GPUVendor::VENDOR_INTEL; diff --git a/Common/GPU/Shader.cpp b/Common/GPU/Shader.cpp index 1310c96118d8..2fe810bb7333 100644 --- a/Common/GPU/Shader.cpp +++ b/Common/GPU/Shader.cpp @@ -11,7 +11,6 @@ const char *ShaderLanguageAsString(ShaderLanguage lang) { case GLSL_1xx: return "GLSL 1.x"; case GLSL_3xx: return "GLSL 3.x"; case GLSL_VULKAN: return "GLSL-VK"; - case HLSL_D3D9: return "HLSL-D3D9"; case HLSL_D3D11: return "HLSL-D3D11"; default: return "(combination)"; } @@ -88,22 +87,17 @@ void ShaderLanguageDesc::Init(ShaderLanguage lang) { coefsFromBuffers = true; vertexIndex = true; break; - case HLSL_D3D9: case HLSL_D3D11: - if (lang == HLSL_D3D11) { - fragColor0 = "outfragment.target"; - fragColor1 = "outfragment.target1"; - vertexIndex = true; // if declared as a semantic input - } else { - fragColor0 = "outfragment.target"; - } + fragColor0 = "outfragment.target"; + fragColor1 = "outfragment.target1"; + vertexIndex = true; // if declared as a semantic input varying_fs = "in"; varying_vs = "out"; attribute = "in"; bitwiseOps = lang == HLSL_D3D11; framebufferFetchExtension = nullptr; gles = false; - glslES30 = true; // Hm, D3D9 too? + glslES30 = true; glslVersionNumber = 0; lastFragData = nullptr; texture = "texture"; diff --git a/Common/GPU/Shader.h b/Common/GPU/Shader.h index 43f6f4d38c9c..5dbb6a549090 100644 --- a/Common/GPU/Shader.h +++ b/Common/GPU/Shader.h @@ -17,7 +17,6 @@ enum ShaderLanguage { GLSL_1xx = 1, GLSL_3xx = 2, GLSL_VULKAN = 4, - HLSL_D3D9 = 8, HLSL_D3D11 = 16, }; diff --git a/Common/GPU/ShaderTranslation.cpp b/Common/GPU/ShaderTranslation.cpp index ad8c1ee76b5f..9bbeeca4b274 100644 --- a/Common/GPU/ShaderTranslation.cpp +++ b/Common/GPU/ShaderTranslation.cpp @@ -102,22 +102,13 @@ layout (std140, set = 0, binding = 0) uniform Data { }; )"; -static const char * const d3d9RegisterDecl = R"( -float4 gl_HalfPixel : register(c0); -float2 u_texelDelta : register(c1); -float2 u_pixelDelta : register(c2); -float4 u_time : register(c3); -float4 u_timeDelta : register(c4); -float4 u_setting : register(c5); -float u_video : register(c6); -)"; // SPIRV-Cross' HLSL output has some deficiencies we need to work around. // Also we need to rip out single uniforms and replace them with blocks. // Should probably do it in the source shader instead and then back translate to old style GLSL, but // SPIRV-Cross currently won't compile with the Android NDK so I can't be bothered. std::string Postprocess(std::string code, ShaderLanguage lang, ShaderStage stage) { - if (lang != HLSL_D3D11 && lang != HLSL_D3D9) + if (lang != HLSL_D3D11) return code; std::stringstream out; @@ -125,18 +116,11 @@ std::string Postprocess(std::string code, ShaderLanguage lang, ShaderStage stage // Output the uniform buffer. if (lang == HLSL_D3D11) out << cbufferDecl; - else if (lang == HLSL_D3D9) - out << d3d9RegisterDecl; // Alright, now let's go through it line by line and zap the single uniforms. std::string line; std::stringstream instream(code); while (std::getline(instream, line)) { - int num; - if (lang == HLSL_D3D9 && sscanf(line.c_str(), "uniform sampler2D sampler%d;", &num) == 1) { - out << "sampler2D sampler" << num << " : register(s" << num << ");\n"; - continue; - } if (line.find("uniform float") != std::string::npos) { continue; } @@ -272,19 +256,6 @@ bool TranslateShader(std::string *dest, ShaderLanguage destLang, const ShaderLan switch (destLang) { #ifdef _WIN32 - case HLSL_D3D9: - { - spirv_cross::CompilerHLSL hlsl(spirv); - spirv_cross::CompilerHLSL::Options options{}; - options.shader_model = 30; - spirv_cross::CompilerGLSL::Options options_common{}; - options_common.vertex.fixup_clipspace = true; - hlsl.set_hlsl_options(options); - hlsl.set_common_options(options_common); - std::string raw = hlsl.compile(); - *dest = Postprocess(raw, destLang, stage); - return true; - } case HLSL_D3D11: { spirv_cross::CompilerHLSL hlsl(spirv); diff --git a/Common/GPU/ShaderWriter.cpp b/Common/GPU/ShaderWriter.cpp index 6ea3de07ab6a..19901e09389c 100644 --- a/Common/GPU/ShaderWriter.cpp +++ b/Common/GPU/ShaderWriter.cpp @@ -39,9 +39,6 @@ const char * const hlsl_preamble_fs = static const char * const hlsl_d3d11_preamble_fs = "#define DISCARD discard\n" "#define DISCARD_BELOW(x) clip(x);\n"; -static const char * const hlsl_d3d9_preamble_fs = -"#define DISCARD clip(-1)\n" -"#define DISCARD_BELOW(x) clip(x)\n"; static const char * const vulkan_glsl_preamble_vs = "#extension GL_ARB_separate_shader_objects : enable\n" @@ -136,18 +133,13 @@ void ShaderWriter::Preamble(Slice extensions) { } break; case HLSL_D3D11: - case HLSL_D3D9: switch (stage_) { case ShaderStage::Vertex: W(hlsl_preamble_vs); break; case ShaderStage::Fragment: W(hlsl_preamble_fs); - if (lang_.shaderLanguage == HLSL_D3D9) { - W(hlsl_d3d9_preamble_fs); - } else { - W(hlsl_d3d11_preamble_fs); - } + W(hlsl_d3d11_preamble_fs); break; case ShaderStage::Geometry: W(hlsl_preamble_gs); @@ -205,7 +197,6 @@ void ShaderWriter::BeginVSMain(Slice inputs, Slice uniform _assert_(this->stage_ == ShaderStage::Vertex); switch (lang_.shaderLanguage) { case HLSL_D3D11: - case HLSL_D3D9: { C("struct VS_OUTPUT {\n"); for (auto &varying : varyings) { @@ -215,9 +206,7 @@ void ShaderWriter::BeginVSMain(Slice inputs, Slice uniform C("};\n"); C("VS_OUTPUT main( "); // 2 spaces for the rewind - if (lang_.shaderLanguage == HLSL_D3D11) { - C("uint gl_VertexIndex : SV_VertexID, "); - } + C("uint gl_VertexIndex : SV_VertexID, "); // List the inputs. for (auto &input : inputs) { F("in %s %s : %s, ", input.type, input.name, semanticNames[input.semantic]); @@ -293,32 +282,6 @@ void ShaderWriter::BeginFSMain(Slice uniforms, Slice var if (flags_ & ShaderWriterFlags::FS_WRITE_DEPTH) { C(" float gl_FragDepth;\n"); } - break; - case HLSL_D3D9: - C("struct PS_OUT {\n"); - C(" vec4 target : SV_Target0;\n"); - if (flags_ & ShaderWriterFlags::FS_WRITE_DEPTH) { - C(" float depth : DEPTH;\n"); - } - C("};\n"); - - for (auto &uniform : uniforms) { - F(" %s %s : register(c%d);\n", uniform.type, uniform.name, uniform.index); - } - // Let's do the varyings as parameters to main, no struct. - C("PS_OUT main("); - for (auto &varying : varyings) { - F(" %s %s : %s, ", varying.type, varying.name, semanticNames[varying.semantic]); - } - // Erase the last comma - Rewind(2); - - F(") {\n"); - C(" PS_OUT ps_out;\n"); - if (flags_ & ShaderWriterFlags::FS_WRITE_DEPTH) { - C(" float gl_FragDepth;\n"); - } - break; case GLSL_VULKAN: for (auto &varying : varyings) { @@ -391,7 +354,6 @@ void ShaderWriter::EndVSMain(Slice varyings) { _assert_(this->stage_ == ShaderStage::Vertex); switch (lang_.shaderLanguage) { case HLSL_D3D11: - case HLSL_D3D9: C(" VS_OUTPUT vs_out;\n"); if (strlen(lang_.viewportYSign)) { F(" gl_Position.y *= %s1.0;\n", lang_.viewportYSign); @@ -413,7 +375,6 @@ void ShaderWriter::EndFSMain(const char *vec4_color_variable) { _assert_(this->stage_ == ShaderStage::Fragment); switch (lang_.shaderLanguage) { case HLSL_D3D11: - case HLSL_D3D9: F(" ps_out.target = %s;\n", vec4_color_variable); if (flags_ & ShaderWriterFlags::FS_WRITE_DEPTH) { C(" ps_out.depth = gl_FragDepth;\n"); @@ -448,7 +409,6 @@ void ShaderWriter::LowPrecisionFloat() { void ShaderWriter::ConstFloat(const char *name, float value) { switch (lang_.shaderLanguage) { case HLSL_D3D11: - case HLSL_D3D9: F("static const float %s = %f;\n", name, value); break; default: @@ -474,9 +434,6 @@ void ShaderWriter::DeclareTexture2D(const SamplerDef &def) { case HLSL_D3D11: F("Texture2D %s : register(t%d);\n", def.name, def.binding); break; - case HLSL_D3D9: - F("sampler %s: register(s%d);\n", def.name, def.binding); - break; case GLSL_VULKAN: // texBindingBase_ is used for the thin3d descriptor set layout, where they start at 1. if (def.flags & SamplerFlags::ARRAY_ON_VULKAN) { @@ -508,9 +465,6 @@ ShaderWriter &ShaderWriter::SampleTexture2D(const char *sampName, const char *uv case HLSL_D3D11: F("%s.Sample(%sSamp, %s)", sampName, sampName, uv); break; - case HLSL_D3D9: - F("tex2D(%s, %s)", sampName, uv); - break; default: // Note: we ignore the sampler. make sure you bound samplers to the textures correctly. if (samp && (samp->flags & SamplerFlags::ARRAY_ON_VULKAN) && lang_.shaderLanguage == GLSL_VULKAN) { @@ -531,10 +485,6 @@ ShaderWriter &ShaderWriter::SampleTexture2DOffset(const char *sampName, const ch case HLSL_D3D11: F("%s.Sample(%sSamp, %s, int2(%d, %d))", sampName, sampName, uv, offX, offY); break; - case HLSL_D3D9: - // Not supported, we do a normal sample here to not crash or something - F("tex2D(%s, %s)", sampName, uv); - break; default: // Note: we ignore the sampler. make sure you bound samplers to the textures correctly. if (samp && (samp->flags & SamplerFlags::ARRAY_ON_VULKAN) && lang_.shaderLanguage == GLSL_VULKAN) { @@ -555,10 +505,6 @@ ShaderWriter &ShaderWriter::LoadTexture2D(const char *sampName, const char *uv, case HLSL_D3D11: F("%s.Load(ivec3(%s, %d))", sampName, uv, level); break; - case HLSL_D3D9: - // Not supported, we return a bad value - C("float4(1.0, 0.0, 1.0, 1.0)"); - break; default: // Note: we ignore the sampler. make sure you bound samplers to the textures correctly. if (samp && (samp->flags & SamplerFlags::ARRAY_ON_VULKAN) && lang_.shaderLanguage == GLSL_VULKAN) { @@ -575,7 +521,6 @@ ShaderWriter &ShaderWriter::LoadTexture2D(const char *sampName, const char *uv, ShaderWriter &ShaderWriter::GetTextureSize(const char *szVariable, const char *texName) { switch (lang_.shaderLanguage) { case HLSL_D3D11: - case HLSL_D3D9: F(" float2 %s; %s.GetDimensions(%s.x, %s.y);", szVariable, texName, szVariable, szVariable); break; default: diff --git a/Common/GPU/Vulkan/thin3d_vulkan.cpp b/Common/GPU/Vulkan/thin3d_vulkan.cpp index b744235b892f..e3d5b004f75a 100644 --- a/Common/GPU/Vulkan/thin3d_vulkan.cpp +++ b/Common/GPU/Vulkan/thin3d_vulkan.cpp @@ -976,14 +976,6 @@ VKContext::VKContext(VulkanContext *vulkan, bool useRenderThread) caps_.verySlowShaderCompiler = true; } - // Hide D3D9 when we know it likely won't work well. -#if PPSSPP_PLATFORM(WINDOWS) - caps_.supportsD3D9 = true; - if (!strcmp(deviceProps.deviceName, "Intel(R) Iris(R) Xe Graphics")) { - caps_.supportsD3D9 = false; - } -#endif - // VkSampleCountFlagBits is arranged correctly for our purposes. // Only support MSAA levels that have support for all three of color, depth, stencil. diff --git a/Common/GPU/thin3d.cpp b/Common/GPU/thin3d.cpp index 72fbe873e86a..950acdb5e396 100644 --- a/Common/GPU/thin3d.cpp +++ b/Common/GPU/thin3d.cpp @@ -183,13 +183,6 @@ static const std::vector fsTexCol = { "uniform sampler2D Sampler0;\n" "void main() { gl_FragColor = texture2D(Sampler0, oTexCoord0) * oColor0; }\n" }, - {ShaderLanguage::HLSL_D3D9, - "struct PS_INPUT { float4 color : COLOR0; float2 uv : TEXCOORD0; };\n" - "sampler2D Sampler0 : register(s0);\n" - "float4 main(PS_INPUT input) : COLOR0 {\n" - " return input.color * tex2D(Sampler0, input.uv);\n" - "}\n" - }, {ShaderLanguage::HLSL_D3D11, "struct PS_INPUT { float4 color : COLOR0; float2 uv : TEXCOORD0; };\n" "SamplerState samp : register(s0);\n" @@ -227,13 +220,6 @@ static const std::vector fsTexColRBSwizzle = { "uniform sampler2D Sampler0;\n" "void main() { gl_FragColor = texture2D(Sampler0, oTexCoord0).zyxw * oColor0; }\n" }, - {ShaderLanguage::HLSL_D3D9, - "struct PS_INPUT { float4 color : COLOR0; float2 uv : TEXCOORD0; };\n" - "sampler2D Sampler0 : register(s0);\n" - "float4 main(PS_INPUT input) : COLOR0 {\n" - " return input.color * tex2D(Sampler0, input.uv).zyxw;\n" - "}\n" - }, {ShaderLanguage::HLSL_D3D11, "struct PS_INPUT { float4 color : COLOR0; float2 uv : TEXCOORD0; };\n" "SamplerState samp : register(s0);\n" @@ -268,12 +254,6 @@ static const std::vector fsCol = { "varying vec4 oColor0;\n" "void main() { gl_FragColor = oColor0; }\n" }, - { ShaderLanguage::HLSL_D3D9, - "struct PS_INPUT { float4 color : COLOR0; };\n" - "float4 main(PS_INPUT input) : COLOR0 {\n" - " return input.color;\n" - "}\n" - }, { ShaderLanguage::HLSL_D3D11, "struct PS_INPUT { float4 color : COLOR0; };\n" "float4 main(PS_INPUT input) : SV_Target {\n" @@ -309,18 +289,6 @@ static const std::vector vsCol = { " oColor0 = Color0;\n" "}" }, - { ShaderLanguage::HLSL_D3D9, - "struct VS_INPUT { float3 Position : POSITION; float4 Color0 : COLOR0; };\n" - "struct VS_OUTPUT { float4 Position : POSITION; float4 Color0 : COLOR0; };\n" - "float4x4 WorldViewProj : register(c0);\n" - "float2 TintSaturation : register(c4);\n" - "VS_OUTPUT main(VS_INPUT input) {\n" - " VS_OUTPUT output;\n" - " output.Position = mul(float4(input.Position, 1.0), WorldViewProj);\n" - " output.Color0 = input.Color0;\n" - " return output;\n" - "}\n" - }, { ShaderLanguage::HLSL_D3D11, "struct VS_INPUT { float3 Position : POSITION; float4 Color0 : COLOR0; };\n" "struct VS_OUTPUT { float4 Color0 : COLOR0; float4 Position : SV_Position; };\n" @@ -416,37 +384,6 @@ void main() { oColor0 = vec4(hsv2rgb(hsv), Color0.w); oTexCoord0 = TexCoord0; })", - }, - { ShaderLanguage::HLSL_D3D9, - R"( -struct VS_INPUT { float3 Position : POSITION; float2 Texcoord0 : TEXCOORD0; float4 Color0 : COLOR0; }; -struct VS_OUTPUT { float4 Position : POSITION; float2 Texcoord0 : TEXCOORD0; float4 Color0 : COLOR0; }; -float4x4 WorldViewProj : register(c0); -float2 TintSaturation : register(c4); -float3 rgb2hsv(float3 c) { - float4 K = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); - float4 p = lerp(float4(c.bg, K.wz), float4(c.gb, K.xy), step(c.b, c.g)); - float4 q = lerp(float4(p.xyw, c.r), float4(c.r, p.yzx), step(p.x, c.r)); - float d = q.x - min(q.w, q.y); - float e = 1.0e-10; - return float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); -} -float3 hsv2rgb(float3 c) { - float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); - float3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www); - return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y); -} -VS_OUTPUT main(VS_INPUT input) { - VS_OUTPUT output; - float3 hsv = rgb2hsv(input.Color0.xyz); - hsv.x += TintSaturation.x; - hsv.y *= TintSaturation.y; - output.Color0 = float4(hsv2rgb(hsv), input.Color0.w); - output.Position = mul(float4(input.Position, 1.0), WorldViewProj); - output.Texcoord0 = input.Texcoord0; - return output; -} -)" }, { ShaderLanguage::HLSL_D3D11, R"( diff --git a/Common/GPU/thin3d.h b/Common/GPU/thin3d.h index f7a23795b017..ab0766733696 100644 --- a/Common/GPU/thin3d.h +++ b/Common/GPU/thin3d.h @@ -265,7 +265,6 @@ enum class Aspect { STENCIL_BIT = 4, // Implementation specific - SURFACE_BIT = 32, // Used in conjunction with the others in D3D9 to get surfaces through get_api_texture VIEW_BIT = 64, // Used in conjunction with the others in D3D11 to get shader resource views through get_api_texture FORMAT_BIT = 128, // Actually retrieves the native format instead. D3D11 only. }; @@ -621,9 +620,6 @@ struct DeviceCaps { bool provokingVertexLast; // GL behavior, what the PSP does bool verySlowShaderCompiler; - // From the other backends, we can detect if D3D9 support is known bad (like on Xe) and disable it. - bool supportsD3D9; - // Old style, for older GL or Direct3D 9. u32 clipPlanesSupported; @@ -828,7 +824,6 @@ class DrawContext { // * Vulkan: VkImageView // * D3D11: ID3D11ShaderResourceView* // * OpenGL: GLRTexture - // * D3D9: LPDIRECT3DTEXTURE9 virtual void BindNativeTexture(int sampler, void *nativeTexture) = 0; // Only supports a single dynamic uniform buffer, for maximum compatibility with the old APIs and ease of emulation. diff --git a/Common/GPU/thin3d_create.h b/Common/GPU/thin3d_create.h index 81aba58a1e62..5d0d1d1de27f 100644 --- a/Common/GPU/thin3d_create.h +++ b/Common/GPU/thin3d_create.h @@ -27,7 +27,6 @@ namespace Draw { DrawContext *T3DCreateGLContext(bool canChangeSwapInterval); #ifdef _WIN32 -DrawContext *T3DCreateDX9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, IDirect3DDevice9 *device, IDirect3DDevice9Ex *deviceEx); DrawContext *T3DCreateD3D11Context(ID3D11Device *device, ID3D11DeviceContext *context, ID3D11Device1 *device1, ID3D11DeviceContext1 *context1, IDXGISwapChain *swapChain, D3D_FEATURE_LEVEL featureLevel, HWND hWnd, const std::vector &adapterNames, int maxInflightFrames); #endif diff --git a/Core/Config.cpp b/Core/Config.cpp index 64d8b2851970..89f785398ee2 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -89,8 +89,6 @@ std::string GPUBackendToString(GPUBackend backend) { switch (backend) { case GPUBackend::OPENGL: return "OPENGL"; - case GPUBackend::DIRECT3D9: - return "DIRECT3D9"; case GPUBackend::DIRECT3D11: return "DIRECT3D11"; case GPUBackend::VULKAN: @@ -103,8 +101,6 @@ std::string GPUBackendToString(GPUBackend backend) { GPUBackend GPUBackendFromString(std::string_view backend) { if (!equalsNoCase(backend, "OPENGL") || backend == "0") return GPUBackend::OPENGL; - if (!equalsNoCase(backend, "DIRECT3D9") || backend == "1") - return GPUBackend::DIRECT3D9; if (!equalsNoCase(backend, "DIRECT3D11") || backend == "2") return GPUBackend::DIRECT3D11; if (!equalsNoCase(backend, "VULKAN") || backend == "3") @@ -534,11 +530,6 @@ int Config::NextValidBackend() { return (int)GPUBackend::OPENGL; } #endif -#if PPSSPP_API(D3D9) - if (!failed.count(GPUBackend::DIRECT3D9)) { - return (int)GPUBackend::DIRECT3D9; - } -#endif // They've all failed. Let them try the default - or on Android, OpenGL. sFailedGPUBackends += ",ALL"; @@ -575,7 +566,7 @@ bool Config::IsBackendEnabled(GPUBackend backend) { if (backend == GPUBackend::DIRECT3D11 && !IsVistaOrHigher()) return false; #else - if (backend == GPUBackend::DIRECT3D11 || backend == GPUBackend::DIRECT3D9) + if (backend == GPUBackend::DIRECT3D11) return false; #endif @@ -1265,6 +1256,10 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) { } } + if (iGPUBackend == 1) { // d3d9, no longer supported + iGPUBackend = 2; // d3d11 + } + if (iMaxRecent > 0) { private_->ResetRecentIsosThread(); std::lock_guard guard(private_->recentIsosLock); diff --git a/Core/ConfigValues.h b/Core/ConfigValues.h index 1dd1fc88b4e2..08a41a2df9ec 100644 --- a/Core/ConfigValues.h +++ b/Core/ConfigValues.h @@ -90,7 +90,6 @@ enum BufferFilter { // Software is not among these because it will have one of these perform the blit to display. enum class GPUBackend { OPENGL = 0, - DIRECT3D9 = 1, DIRECT3D11 = 2, VULKAN = 3, }; diff --git a/Core/CoreParameter.h b/Core/CoreParameter.h index 13deda416219..308db15d5431 100644 --- a/Core/CoreParameter.h +++ b/Core/CoreParameter.h @@ -24,11 +24,10 @@ #include "Core/Loaders.h" enum GPUCore { - GPUCORE_GLES, - GPUCORE_SOFTWARE, - GPUCORE_DIRECTX9, - GPUCORE_DIRECTX11, - GPUCORE_VULKAN, + GPUCORE_GLES = 0, + GPUCORE_SOFTWARE = 1, + GPUCORE_DIRECTX11 = 3, + GPUCORE_VULKAN = 4, }; enum class FPSLimit { diff --git a/GPU/Common/DepalettizeShaderCommon.cpp b/GPU/Common/DepalettizeShaderCommon.cpp index 2d70fd95e703..aa7cdd211b49 100644 --- a/GPU/Common/DepalettizeShaderCommon.cpp +++ b/GPU/Common/DepalettizeShaderCommon.cpp @@ -182,10 +182,7 @@ void GenerateDepalShaderFloat(ShaderWriter &writer, const DepalConfig &config) { case GE_FORMAT_CLUT8: if (shift == 0 && mask == 0xFF) { // Easy peasy. - if (writer.Lang().shaderLanguage == HLSL_D3D9) - snprintf(lookupMethod, sizeof(lookupMethod), "index.a"); - else - snprintf(lookupMethod, sizeof(lookupMethod), "index.r"); + snprintf(lookupMethod, sizeof(lookupMethod), "index.r"); formatOK = true; } else { // Deal with this if we find it. @@ -318,10 +315,6 @@ void GenerateDepalShaderFloat(ShaderWriter &writer, const DepalConfig &config) { // Offset by half a texel (plus clutBase) to turn NEAREST filtering into FLOOR. // Technically, the clutBase should be |'d, not added, but that's hard with floats. float texel_offset = ((float)config.startPos + 0.5f) / texturePixels; - if (writer.Lang().shaderLanguage == HLSL_D3D9) { - // Seems to need a half-pixel offset fix? Might mean it was rendered wrong... - texel_offset += 0.5f / texturePixels; - } writer.F(" float coord = (%s * %f) + %f;\n", lookupMethod, index_multiplier, texel_offset); writer.C(" vec4 outColor = ").SampleTexture2D("pal", "vec2(coord, 0.0)").C(";\n"); } @@ -366,7 +359,6 @@ void GenerateDepalFs(ShaderWriter &writer, const DepalConfig &config) { GenerateDepalSmoothed(writer, config); } else { switch (writer.Lang().shaderLanguage) { - case HLSL_D3D9: case GLSL_1xx: GenerateDepalShaderFloat(writer, config); break; diff --git a/GPU/Common/FragmentShaderGenerator.cpp b/GPU/Common/FragmentShaderGenerator.cpp index 757cb4d291ab..1267c38c35f7 100644 --- a/GPU/Common/FragmentShaderGenerator.cpp +++ b/GPU/Common/FragmentShaderGenerator.cpp @@ -238,51 +238,8 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu if (stencilToAlpha == REPLACE_ALPHA_DUALSOURCE) { WRITE(p, "layout (location = 0, index = 1) out vec4 fragColor1;\n"); } - } else if (compat.shaderLanguage == HLSL_D3D11 || compat.shaderLanguage == HLSL_D3D9) { - if (compat.shaderLanguage == HLSL_D3D9) { - if (doTexture) - WRITE(p, "sampler tex : register(s0);\n"); - - if (readFramebufferTex) { - WRITE(p, "vec2 u_fbotexSize : register(c%i);\n", CONST_PS_FBOTEXSIZE); - WRITE(p, "sampler fbotex : register(s1);\n"); - } - - if (replaceBlend > REPLACE_BLEND_STANDARD) { - if (replaceBlendFuncA >= GE_SRCBLEND_FIXA) { - WRITE(p, "float3 u_blendFixA : register(c%i);\n", CONST_PS_BLENDFIXA); - } - if (replaceBlendFuncB >= GE_DSTBLEND_FIXB) { - WRITE(p, "float3 u_blendFixB : register(c%i);\n", CONST_PS_BLENDFIXB); - } - } - if (needShaderTexClamp && doTexture) { - WRITE(p, "vec4 u_texclamp : register(c%i);\n", CONST_PS_TEXCLAMP); - WRITE(p, "vec2 u_texclampoff : register(c%i);\n", CONST_PS_TEXCLAMPOFF); - } - - if (enableAlphaTest || enableColorTest) { - WRITE(p, "vec4 u_alphacolorref : register(c%i);\n", CONST_PS_ALPHACOLORREF); - WRITE(p, "vec4 u_alphacolormask : register(c%i);\n", CONST_PS_ALPHACOLORMASK); - } - if (stencilToAlpha && replaceAlphaWithStencilType == STENCIL_VALUE_UNIFORM) { - WRITE(p, "float u_stencilReplaceValue : register(c%i);\n", CONST_PS_STENCILREPLACE); - } - if (doTexture) { - if (texFunc == GE_TEXFUNC_BLEND) { - WRITE(p, "float3 u_texenv : register(c%i);\n", CONST_PS_TEXENV); - } - if (ubershader) { - WRITE(p, "float2 u_texNoAlphaMul : register(c%i);\n", CONST_PS_TEX_NO_ALPHA_MUL); - } - } - if (enableFog) { - WRITE(p, "float3 u_fogcolor : register(c%i);\n", CONST_PS_FOGCOLOR); - } - if (texture3D) { - WRITE(p, "float u_mipBias : register(c%i);\n", CONST_PS_MIPBIAS); - } - } else { + } else if (compat.shaderLanguage == HLSL_D3D11) { + { WRITE(p, "SamplerState texSamp : register(s0);\n"); if (texture3D) { WRITE(p, "Texture3D tex : register(t0);\n"); @@ -334,8 +291,6 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu if (needFragCoord) { if (compat.shaderLanguage == HLSL_D3D11) { WRITE(p, " vec4 pixelPos : SV_POSITION;\n"); - } else if (compat.shaderLanguage == HLSL_D3D9) { - WRITE(p, " vec4 pixelPos : VPOS;\n"); // VPOS is only supported for Shader Model 3.0, but we can probably forget about D3D9 SM2.0 at this point... } } WRITE(p, "};\n"); @@ -352,13 +307,6 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu WRITE(p, " float depth : SV_Depth;\n"); } WRITE(p, "};\n"); - } else if (compat.shaderLanguage == HLSL_D3D9) { - WRITE(p, "struct PS_OUT {\n"); - WRITE(p, " vec4 target : COLOR;\n"); - if (writeDepth) { - WRITE(p, " float depth : DEPTH;\n"); - } - WRITE(p, "};\n"); } } else if (ShaderLanguageIsOpenGL(compat.shaderLanguage)) { if ((shaderDepalMode != ShaderDepalMode::OFF || colorWriteMask) && gl_extensions.IsGLES) { @@ -545,17 +493,11 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu if (writeDepth) { WRITE(p, " float gl_FragDepth;\n"); } - } else if (compat.shaderLanguage == HLSL_D3D9) { - WRITE(p, "PS_OUT main( PS_IN In ) {\n"); - WRITE(p, " PS_OUT outfragment;\n"); - if (needFragCoord) { - WRITE(p, " vec4 gl_FragCoord = In.pixelPos;\n"); - } } else { WRITE(p, "void main() {\n"); } - if (compat.shaderLanguage == HLSL_D3D11 || compat.shaderLanguage == HLSL_D3D9) { + if (compat.shaderLanguage == HLSL_D3D11) { WRITE(p, " vec4 v_color0 = In.v_color0;\n"); if (lmode) { WRITE(p, " vec3 v_color1 = In.v_color1;\n"); @@ -572,8 +514,6 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu if (readFramebufferTex) { if (compat.shaderLanguage == HLSL_D3D11) { WRITE(p, " vec4 destColor = fbotex.Load(int3((int)gl_FragCoord.x, (int)gl_FragCoord.y, 0));\n"); - } else if (compat.shaderLanguage == HLSL_D3D9) { - WRITE(p, " vec4 destColor = tex2D(fbotex, gl_FragCoord.xy * u_fbotexSize.xy);\n", compat.texture); } else if (compat.shaderLanguage == GLSL_VULKAN) { WRITE(p, " lowp vec4 destColor = %s(fbotex, ivec3(gl_FragCoord.x, gl_FragCoord.y, %s), 0);\n", compat.texelFetch, useStereo ? "float(gl_ViewIndex)" : "0"); } else if (!compat.texelFetch) { @@ -663,20 +603,6 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu WRITE(p, " vec4 t = tex.Sample(texSamp, %s.xy)%s;\n", texcoord, bgraTexture ? ".bgra" : ""); } } - } else if (compat.shaderLanguage == HLSL_D3D9) { - if (texture3D) { - if (doTextureProjection) { - WRITE(p, " vec4 t = tex3Dproj(tex, vec4(v_texcoord.x, v_texcoord.y, u_mipBias, v_texcoord.z))%s;\n", bgraTexture ? ".bgra" : ""); - } else { - WRITE(p, " vec4 t = tex3D(tex, vec3(%s.x, %s.y, u_mipBias))%s;\n", texcoord, texcoord, bgraTexture ? ".bgra" : ""); - } - } else { - if (doTextureProjection) { - WRITE(p, " vec4 t = tex2Dproj(tex, vec4(v_texcoord.x, v_texcoord.y, 0.0, v_texcoord.z))%s;\n", bgraTexture ? ".bgra" : ""); - } else { - WRITE(p, " vec4 t = tex2D(tex, %s.xy)%s;\n", texcoord, bgraTexture ? ".bgra" : ""); - } - } } else { // Note that here we're relying on the filter to be linear. We would have to otherwise to do two samples and manually filter in Z. // Let's add that if we run into a case... @@ -1012,11 +938,7 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu const char *test = colorTestFuncs[colorTestFunc]; if (test[0] != '#') { // TODO: Unify these paths better. - if (compat.shaderLanguage == HLSL_D3D9) { - // TODO: Use a texture to lookup bitwise ops instead? - WRITE(p, " vec3 colortest = roundAndScaleTo255v(v.rgb);\n"); - WRITE(p, " if ((colortest.r %s u_alphacolorref.r) && (colortest.g %s u_alphacolorref.g) && (colortest.b %s u_alphacolorref.b)) %s\n", test, test, test, discardStatement); - } else if (compat.bitwiseOps) { + if (compat.bitwiseOps) { WRITE(p, " uint v_uint = roundAndScaleTo8x4(v.rgb);\n"); WRITE(p, " uint v_masked = v_uint & u_alphacolormask;\n"); WRITE(p, " uint colorTestRef = (u_alphacolorref & u_alphacolormask) & 0xFFFFFFu;\n"); @@ -1264,7 +1186,7 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu WRITE(p, " gl_FragDepth = gl_FragCoord.z;\n"); } - if (compat.shaderLanguage == HLSL_D3D11 || compat.shaderLanguage == HLSL_D3D9) { + if (compat.shaderLanguage == HLSL_D3D11) { if (writeDepth) { WRITE(p, " outfragment.depth = gl_FragDepth;\n"); } diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 055a85c06e2e..154205f055fe 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -1531,7 +1531,7 @@ bool FramebufferManagerCommon::DrawFramebufferToOutput(const u8 *srcPixels, int flags |= OutputFlags::BACKBUFFER_FLIPPED; } // CopyToOutput reverses these, probably to match "up". - if (GetGPUBackend() == GPUBackend::DIRECT3D9 || GetGPUBackend() == GPUBackend::DIRECT3D11) { + if (GetGPUBackend() == GPUBackend::DIRECT3D11) { flags |= OutputFlags::POSITION_FLIPPED; } @@ -1698,7 +1698,7 @@ void FramebufferManagerCommon::CopyDisplayToOutput(bool reallyDirty) { flags |= OutputFlags::BACKBUFFER_FLIPPED; } // DrawActiveTexture reverses these, probably to match "up". - if (GetGPUBackend() == GPUBackend::DIRECT3D9 || GetGPUBackend() == GPUBackend::DIRECT3D11) { + if (GetGPUBackend() == GPUBackend::DIRECT3D11) { flags |= OutputFlags::POSITION_FLIPPED; } diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index 3b862c88c497..090b6333fed0 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -473,7 +473,7 @@ Draw::Pipeline *PresentationCommon::CreatePipeline(std::vectorfb_format == GE_FORMAT_5551); // socom switch (draw_->GetShaderLanguageDesc().shaderLanguage) { - case ShaderLanguage::HLSL_D3D9: - useShaderDepal = false; - break; case ShaderLanguage::GLSL_1xx: // Force off for now, in case <= GLSL 1.20 or GLES 2, which don't support switch-case. useShaderDepal = false; @@ -3013,7 +3010,7 @@ void TextureCacheCommon::LoadTextureLevel(TexCacheEntry &entry, uint8_t *data, s if (decPitch != stride) { // Rearrange in place to match the requested pitch. // (it can only be larger than w * bpp, and a match is likely.) - // Note! This is bad because it reads the mapped memory! TODO: Look into if DX9 does this right. + // Note! This is bad because it reads the mapped memory! for (int y = scaledH - 1; y >= 0; --y) { memcpy((u8 *)data + stride * y, (u8 *)data + decPitch * y, scaledW *4); } diff --git a/GPU/Common/VertexShaderGenerator.cpp b/GPU/Common/VertexShaderGenerator.cpp index 55d62b7acc76..b49abbf00ee7 100644 --- a/GPU/Common/VertexShaderGenerator.cpp +++ b/GPU/Common/VertexShaderGenerator.cpp @@ -203,7 +203,7 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag *errorString = "Invalid flags - tess requires normal."; return false; } - if (compat.shaderLanguage == HLSL_D3D9 || compat.texelFetch == nullptr) { + if (compat.texelFetch == nullptr) { *errorString = "Tess not supported on this shader language version"; return false; } @@ -288,83 +288,11 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag WRITE(p, "layout (location = 3) out highp float v_fogdepth;\n"); WRITE(p, "invariant gl_Position;\n"); - } else if (compat.shaderLanguage == HLSL_D3D11 || compat.shaderLanguage == HLSL_D3D9) { + } else if (compat.shaderLanguage == HLSL_D3D11) { // Note: These two share some code after this hellishly large if/else. - if (compat.shaderLanguage == HLSL_D3D11) { - WRITE(p, "cbuffer base : register(b0) {\n%s};\n", ub_baseStr); - WRITE(p, "cbuffer lights: register(b1) {\n%s};\n", ub_vs_lightsStr); - WRITE(p, "cbuffer bones : register(b2) {\n%s};\n", ub_vs_bonesStr); - } else { - WRITE(p, "#pragma warning( disable : 3571 )\n"); - if (isModeThrough) { - WRITE(p, "mat4 u_proj_through : register(c%i);\n", CONST_VS_PROJ_THROUGH); - } else if (useHWTransform) { - WRITE(p, "mat4 u_proj : register(c%i);\n", CONST_VS_PROJ); - } else { - WRITE(p, "float u_rotation : register(c%i);\n", CONST_VS_ROTATION); - } - - if (useHWTransform) - WRITE(p, "vec2 u_fogcoef : register(c%i);\n", CONST_VS_FOGCOEF); - if (useHWTransform || !hasColor) - WRITE(p, "vec4 u_matambientalpha : register(c%i);\n", CONST_VS_MATAMBIENTALPHA); // matambient + matalpha - - if (useHWTransform) { - WRITE(p, "mat3x4 u_world : register(c%i);\n", CONST_VS_WORLD); - WRITE(p, "mat3x4 u_view : register(c%i);\n", CONST_VS_VIEW); - if (doTextureTransform) - WRITE(p, "mat3x4 u_texmtx : register(c%i);\n", CONST_VS_TEXMTX); - if (enableBones) { -#ifdef USE_BONE_ARRAY - WRITE(p, "mat3x4 u_bone[%i] : register(c%i);\n", numBones, CONST_VS_BONE0); -#else - for (int i = 0; i < numBoneWeights; i++) { - WRITE(p, "mat3x4 u_bone%i : register(c%i);\n", i, CONST_VS_BONE0 + i * 3); - } -#endif - } - WRITE(p, "vec4 u_uvscaleoffset : register(c%i);\n", CONST_VS_UVSCALEOFFSET); - // No need for light ubershader support here, D3D9 doesn't do it. - for (int i = 0; i < 4; i++) { - if (doLight[i] != LIGHT_OFF) { - // This is needed for shade mapping - WRITE(p, "vec3 u_lightpos%i : register(c%i);\n", i, CONST_VS_LIGHTPOS + i); - } - if (doLight[i] == LIGHT_FULL) { - GELightType type = static_cast(id.Bits(VS_BIT_LIGHT0_TYPE + 4 * i, 2)); - GELightComputation comp = static_cast(id.Bits(VS_BIT_LIGHT0_COMP + 4 * i, 2)); - - if (type != GE_LIGHTTYPE_DIRECTIONAL) - WRITE(p, "vec3 u_lightatt%i : register(c%i);\n", i, CONST_VS_LIGHTATT + i); - - if (type == GE_LIGHTTYPE_SPOT || type == GE_LIGHTTYPE_UNKNOWN) { - WRITE(p, "vec3 u_lightdir%i : register(c%i);\n", i, CONST_VS_LIGHTDIR + i); - WRITE(p, "vec4 u_lightangle_spotCoef%i : register(c%i);\n", i, CONST_VS_LIGHTANGLE_SPOTCOEF + i); - } - WRITE(p, "vec3 u_lightambient%i : register(c%i);\n", i, CONST_VS_LIGHTAMBIENT + i); - WRITE(p, "vec3 u_lightdiffuse%i : register(c%i);\n", i, CONST_VS_LIGHTDIFFUSE + i); - - if (comp == GE_LIGHTCOMP_BOTH) { - WRITE(p, "vec3 u_lightspecular%i : register(c%i);\n", i, CONST_VS_LIGHTSPECULAR + i); - } - } - } - if (enableLighting) { - WRITE(p, "vec4 u_ambient : register(c%i);\n", CONST_VS_AMBIENT); - if ((matUpdate & 2) == 0 || !hasColor) - WRITE(p, "vec3 u_matdiffuse : register(c%i);\n", CONST_VS_MATDIFFUSE); - // if ((matUpdate & 4) == 0) - WRITE(p, "vec4 u_matspecular : register(c%i);\n", CONST_VS_MATSPECULAR); // Specular coef is contained in alpha - WRITE(p, "vec3 u_matemissive : register(c%i);\n", CONST_VS_MATEMISSIVE); - } - } - - if (!isModeThrough) { - WRITE(p, "vec4 u_depthRange : register(c%i);\n", CONST_VS_DEPTHRANGE); - WRITE(p, "vec4 u_cullRangeMin : register(c%i);\n", CONST_VS_CULLRANGEMIN); - WRITE(p, "vec4 u_cullRangeMax : register(c%i);\n", CONST_VS_CULLRANGEMAX); - } - } + WRITE(p, "cbuffer base : register(b0) {\n%s};\n", ub_baseStr); + WRITE(p, "cbuffer lights: register(b1) {\n%s};\n", ub_vs_lightsStr); + WRITE(p, "cbuffer bones : register(b2) {\n%s};\n", ub_vs_bonesStr); // And the "varyings". if (useHWTransform) { @@ -417,9 +345,7 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag } WRITE(p, " float v_fogdepth : TEXCOORD1;\n"); - if (compat.shaderLanguage == HLSL_D3D9) { - WRITE(p, " vec4 gl_Position : POSITION;\n"); - } else { + { WRITE(p, " vec4 gl_Position : SV_Position;\n"); bool clipRange = vertexRangeCulling && gstate_c.Use(GPU_USE_CLIP_DISTANCE); if (clipClampedDepth && clipRange) { @@ -647,8 +573,6 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag WRITE(p, "};\n"); WRITE(p, "StructuredBuffer tess_weights_u : register(t1);\n"); WRITE(p, "StructuredBuffer tess_weights_v : register(t2);\n"); - } else if (compat.shaderLanguage == HLSL_D3D9) { - } const char *init[3] = { "0.0, 0.0", "0.0, 0.0, 0.0", "0.0, 0.0, 0.0, 0.0" }; @@ -669,7 +593,7 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag WRITE(p, "mat4 outerProduct(vec4 u, vec4 v) {\n"); WRITE(p, " return mat4(u * v[0], u * v[1], u * v[2], u * v[3]);\n"); WRITE(p, "}\n"); - } else if (compat.shaderLanguage == HLSL_D3D9 || compat.shaderLanguage == HLSL_D3D11) { + } else if (compat.shaderLanguage == HLSL_D3D11) { WRITE(p, "mat4 outerProduct(vec4 u, vec4 v) {\n"); WRITE(p, " return mul((float4x1)v, (float1x4)u);\n"); WRITE(p, "}\n"); @@ -683,7 +607,7 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag WRITE(p, " vec3 nrm;\n"); WRITE(p, "};\n"); - if (compat.shaderLanguage == HLSL_D3D9 || compat.shaderLanguage == HLSL_D3D11) { + if (compat.shaderLanguage == HLSL_D3D11) { WRITE(p, "void tessellate(in VS_IN In, out Tess tess) {\n"); WRITE(p, " vec3 position = In.position;\n"); WRITE(p, " vec3 normal = In.normal;\n"); @@ -770,7 +694,7 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag if (ShaderLanguageIsOpenGL(compat.shaderLanguage) || compat.shaderLanguage == GLSL_VULKAN) { WRITE(p, "void main() {\n"); - } else if (compat.shaderLanguage == HLSL_D3D9 || compat.shaderLanguage == HLSL_D3D11) { + } else if (compat.shaderLanguage == HLSL_D3D11) { WRITE(p, "VS_OUT main(VS_IN In) {\n"); WRITE(p, " VS_OUT Out;\n"); if (hasTexcoord) { @@ -851,7 +775,7 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag if (doBezier || doSpline) { // Hardware tessellation WRITE(p, " Tess tess;\n"); - if (compat.shaderLanguage == HLSL_D3D9 || compat.shaderLanguage == HLSL_D3D11) { + if (compat.shaderLanguage == HLSL_D3D11) { WRITE(p, " tessellate(In, tess);\n"); } else { WRITE(p, " tessellate(tess);\n"); @@ -1362,7 +1286,7 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag compat.vsOutPrefix, compat.vsOutPrefix, compat.vsOutPrefix); } - if (compat.shaderLanguage == HLSL_D3D11 || compat.shaderLanguage == HLSL_D3D9) { + if (compat.shaderLanguage == HLSL_D3D11) { WRITE(p, " return Out;\n"); } WRITE(p, "}\n"); diff --git a/GPU/Directx9/DrawEngineDX9.cpp b/GPU/Directx9/DrawEngineDX9.cpp deleted file mode 100644 index e6d7d3ab514b..000000000000 --- a/GPU/Directx9/DrawEngineDX9.cpp +++ /dev/null @@ -1,430 +0,0 @@ -// Copyright (c) 2012- PPSSPP Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0 or later versions. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official git repository and contact information can be found at -// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. - -#include -#include - -#include "Common/Log.h" - -#include "Common/GPU/D3D9/D3D9StateCache.h" - -#include "GPU/GPUState.h" -#include "GPU/ge_constants.h" - -#include "GPU/Common/SplineCommon.h" -#include "GPU/Common/TransformCommon.h" -#include "GPU/Common/VertexDecoderCommon.h" -#include "GPU/Common/SoftwareTransformCommon.h" -#include "GPU/Directx9/TextureCacheDX9.h" -#include "GPU/Directx9/DrawEngineDX9.h" -#include "GPU/Directx9/ShaderManagerDX9.h" -#include "GPU/Directx9/FramebufferManagerDX9.h" - -using Microsoft::WRL::ComPtr; - -static const D3DPRIMITIVETYPE d3d_prim[8] = { - // Points, which are expanded to triangles. - D3DPT_TRIANGLELIST, - // Lines and line strips, which are also expanded to triangles. - D3DPT_TRIANGLELIST, - D3DPT_TRIANGLELIST, - D3DPT_TRIANGLELIST, - D3DPT_TRIANGLESTRIP, - D3DPT_TRIANGLEFAN, - // Rectangles, which are expanded to triangles. - D3DPT_TRIANGLELIST, -}; - -static const int D3DPRIMITIVEVERTEXCOUNT[8][2] = { - {0, 0}, // invalid - {1, 0}, // 1 = D3DPT_POINTLIST, - {2, 0}, // 2 = D3DPT_LINELIST, - {2, 1}, // 3 = D3DPT_LINESTRIP, - {3, 0}, // 4 = D3DPT_TRIANGLELIST, - {1, 2}, // 5 = D3DPT_TRIANGLESTRIP, - {1, 2}, // 6 = D3DPT_TRIANGLEFAN, -}; - -inline int D3DPrimCount(D3DPRIMITIVETYPE prim, int size) { - return (size / D3DPRIMITIVEVERTEXCOUNT[prim][0]) - D3DPRIMITIVEVERTEXCOUNT[prim][1]; -} - -enum { - TRANSFORMED_VERTEX_BUFFER_SIZE = VERTEX_BUFFER_MAX * sizeof(TransformedVertex) -}; - -static const D3DVERTEXELEMENT9 TransformedVertexElements[] = { - { 0, offsetof(TransformedVertex, pos), D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, - { 0, offsetof(TransformedVertex, uv), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, - { 0, offsetof(TransformedVertex, color0), D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 }, - { 0, offsetof(TransformedVertex, color1), D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1 }, - { 0, offsetof(TransformedVertex, fog), D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 }, - D3DDECL_END() -}; - -DrawEngineDX9::DrawEngineDX9(Draw::DrawContext *draw) : draw_(draw), vertexDeclMap_(64) { - device_ = (LPDIRECT3DDEVICE9)draw->GetNativeObject(Draw::NativeObject::DEVICE); - decOptions_.expandAllWeightsToFloat = true; - decOptions_.expand8BitNormalsToFloat = true; - - InitDeviceObjects(); - - tessDataTransferDX9 = new TessellationDataTransferDX9(); - tessDataTransfer = tessDataTransferDX9; - - device_->CreateVertexDeclaration(TransformedVertexElements, &transformedVertexDecl_); -} - -DrawEngineDX9::~DrawEngineDX9() { - DestroyDeviceObjects(); - vertexDeclMap_.Clear(); - delete tessDataTransferDX9; -} - -void DrawEngineDX9::InitDeviceObjects() { - draw_->SetInvalidationCallback(std::bind(&DrawEngineDX9::Invalidate, this, std::placeholders::_1)); -} - -void DrawEngineDX9::DestroyDeviceObjects() { - if (draw_) { - draw_->SetInvalidationCallback(InvalidationCallback()); - } -} - -struct DeclTypeInfo { - u32 type; - const char * name; -}; - -static const DeclTypeInfo VComp[] = { - { 0, "NULL" }, // DEC_NONE, - { D3DDECLTYPE_FLOAT1, "D3DDECLTYPE_FLOAT1 " }, // DEC_FLOAT_1, - { D3DDECLTYPE_FLOAT2, "D3DDECLTYPE_FLOAT2 " }, // DEC_FLOAT_2, - { D3DDECLTYPE_FLOAT3, "D3DDECLTYPE_FLOAT3 " }, // DEC_FLOAT_3, - { D3DDECLTYPE_FLOAT4, "D3DDECLTYPE_FLOAT4 " }, // DEC_FLOAT_4, - - { 0, "UNUSED" }, // DEC_S8_3, - - { D3DDECLTYPE_SHORT4N, "D3DDECLTYPE_SHORT4N " }, // DEC_S16_3, - { D3DDECLTYPE_UBYTE4N, "D3DDECLTYPE_UBYTE4N " }, // DEC_U8_1, - { D3DDECLTYPE_UBYTE4N, "D3DDECLTYPE_UBYTE4N " }, // DEC_U8_2, - { D3DDECLTYPE_UBYTE4N, "D3DDECLTYPE_UBYTE4N " }, // DEC_U8_3, - { D3DDECLTYPE_UBYTE4N, "D3DDECLTYPE_UBYTE4N " }, // DEC_U8_4, - {0, "UNUSED_DEC_U16_1" }, // DEC_U16_1, - {0, "UNUSED_DEC_U16_2" }, // DEC_U16_2, - {D3DDECLTYPE_USHORT4N ,"D3DDECLTYPE_USHORT4N "}, // DEC_U16_3, - {D3DDECLTYPE_USHORT4N ,"D3DDECLTYPE_USHORT4N "}, // DEC_U16_4, -}; - -static void VertexAttribSetup(D3DVERTEXELEMENT9 * VertexElement, u8 fmt, u8 offset, u8 usage, u8 usage_index = 0) { - memset(VertexElement, 0, sizeof(D3DVERTEXELEMENT9)); - VertexElement->Offset = offset; - VertexElement->Type = VComp[fmt].type; - VertexElement->Usage = usage; - VertexElement->UsageIndex = usage_index; -} - -HRESULT DrawEngineDX9::SetupDecFmtForDraw(const DecVtxFormat &decFmt, u32 pspFmt, IDirect3DVertexDeclaration9 **ppVertextDeclaration) { - ComPtr vertexDeclCached; - if (vertexDeclMap_.Get(pspFmt, &vertexDeclCached)) { - *ppVertextDeclaration = vertexDeclCached.Detach(); - return S_OK; - } else { - D3DVERTEXELEMENT9 VertexElements[8]; - D3DVERTEXELEMENT9 *VertexElement = &VertexElements[0]; - - // Vertices Elements orders - // WEIGHT - if (decFmt.w0fmt != 0) { - VertexAttribSetup(VertexElement, decFmt.w0fmt, decFmt.w0off, D3DDECLUSAGE_TEXCOORD, 1); - VertexElement++; - } - - if (decFmt.w1fmt != 0) { - VertexAttribSetup(VertexElement, decFmt.w1fmt, decFmt.w1off, D3DDECLUSAGE_TEXCOORD, 2); - VertexElement++; - } - - // TC - if (decFmt.uvfmt != 0) { - VertexAttribSetup(VertexElement, decFmt.uvfmt, decFmt.uvoff, D3DDECLUSAGE_TEXCOORD, 0); - VertexElement++; - } - - // COLOR - if (decFmt.c0fmt != 0) { - VertexAttribSetup(VertexElement, decFmt.c0fmt, decFmt.c0off, D3DDECLUSAGE_COLOR, 0); - VertexElement++; - } - // Never used ? - if (decFmt.c1fmt != 0) { - VertexAttribSetup(VertexElement, decFmt.c1fmt, decFmt.c1off, D3DDECLUSAGE_COLOR, 1); - VertexElement++; - } - - // NORMAL - if (decFmt.nrmfmt != 0) { - VertexAttribSetup(VertexElement, decFmt.nrmfmt, decFmt.nrmoff, D3DDECLUSAGE_NORMAL, 0); - VertexElement++; - } - - // POSITION - // Always - VertexAttribSetup(VertexElement, DecVtxFormat::PosFmt(), decFmt.posoff, D3DDECLUSAGE_POSITION, 0); - VertexElement++; - - // End - D3DVERTEXELEMENT9 end = D3DDECL_END(); - memcpy(VertexElement, &end, sizeof(D3DVERTEXELEMENT9)); - - // Create declaration - ComPtr pHardwareVertexDecl; - HRESULT hr = device_->CreateVertexDeclaration( VertexElements, &pHardwareVertexDecl ); - if (FAILED(hr)) { - ERROR_LOG(Log::G3D, "Failed to create vertex declaration!"); - } - - // Add it to map - vertexDeclMap_.Insert(pspFmt, pHardwareVertexDecl); - *ppVertextDeclaration = pHardwareVertexDecl.Detach(); - return hr; - } -} - -static uint32_t SwapRB(uint32_t c) { - return (c & 0xFF00FF00) | ((c >> 16) & 0xFF) | ((c << 16) & 0xFF0000); -} - -void DrawEngineDX9::BeginFrame() { - DrawEngineCommon::BeginFrame(); - lastRenderStepId_ = -1; -} - -// In D3D, we're synchronous and state carries over so all we reset here on a new step is the viewport/scissor. -void DrawEngineDX9::Invalidate(InvalidationCallbackFlags flags) { - if (flags & InvalidationCallbackFlags::RENDER_PASS_STATE) { - gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); - } -} - -void DrawEngineDX9::Flush() { - if (!numDrawVerts_) { - return; - } - bool textureNeedsApply = false; - if (gstate_c.IsDirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS) && !gstate.isModeClear() && gstate.isTextureMapEnabled()) { - textureCache_->SetTexture(); - gstate_c.Clean(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); - textureNeedsApply = true; - } else if (gstate.getTextureAddress(0) == (gstate.getFrameBufRawAddress() | 0x04000000)) { - // This catches the case of clearing a texture. (#10957) - gstate_c.Dirty(DIRTY_TEXTURE_IMAGE); - } - - GEPrimitiveType prim = prevPrim_; - - // Always use software for flat shading to fix the provoking index. - bool tess = gstate_c.submitType == SubmitType::HW_BEZIER || gstate_c.submitType == SubmitType::HW_SPLINE; - bool useHWTransform = CanUseHardwareTransform(prim) && (tess || gstate.getShadeMode() != GE_SHADE_FLAT); - - if (useHWTransform) { - LPDIRECT3DVERTEXBUFFER9 vb_ = nullptr; - LPDIRECT3DINDEXBUFFER9 ib_ = nullptr; - - int vertexCount; - int maxIndex; - bool useElements; - DecodeVerts(dec_, decoded_); - DecodeIndsAndGetData(&prim, &vertexCount, &maxIndex, &useElements, false); - gpuStats.numUncachedVertsDrawn += vertexCount; - - _dbg_assert_((int)prim > 0); - - bool hasColor = (lastVType_ & GE_VTYPE_COL_MASK) != GE_VTYPE_COL_NONE; - if (gstate.isModeThrough()) { - gstate_c.vertexFullAlpha = gstate_c.vertexFullAlpha && (hasColor || gstate.getMaterialAmbientA() == 255); - } else { - gstate_c.vertexFullAlpha = gstate_c.vertexFullAlpha && ((hasColor && (gstate.materialupdate & 1)) || gstate.getMaterialAmbientA() == 255) && (!gstate.isLightingEnabled() || gstate.getAmbientA() == 255); - } - - if (textureNeedsApply) { - textureCache_->ApplyTexture(); - } - - ApplyDrawState(prim); - ApplyDrawStateLate(); - - VSShader *vshader = shaderManager_->ApplyShader(true, useHWTessellation_, dec_, decOptions_.expandAllWeightsToFloat, applySkinInDecode_, pipelineState_); - ComPtr pHardwareVertexDecl; - SetupDecFmtForDraw(dec_->GetDecVtxFmt(), dec_->VertexType(), &pHardwareVertexDecl); - - if (pHardwareVertexDecl) { - device_->SetVertexDeclaration(pHardwareVertexDecl.Get()); - if (vb_ == NULL) { - if (useElements) { - device_->DrawIndexedPrimitiveUP(d3d_prim[prim], 0, numDecodedVerts_, D3DPrimCount(d3d_prim[prim], vertexCount), decIndex_, D3DFMT_INDEX16, decoded_, dec_->GetDecVtxFmt().stride); - } else { - device_->DrawPrimitiveUP(d3d_prim[prim], D3DPrimCount(d3d_prim[prim], vertexCount), decoded_, dec_->GetDecVtxFmt().stride); - } - } else { - device_->SetStreamSource(0, vb_, 0, dec_->GetDecVtxFmt().stride); - - if (useElements) { - device_->SetIndices(ib_); - - device_->DrawIndexedPrimitive(d3d_prim[prim], 0, 0, numDecodedVerts_, 0, D3DPrimCount(d3d_prim[prim], vertexCount)); - } else { - device_->DrawPrimitive(d3d_prim[prim], 0, D3DPrimCount(d3d_prim[prim], vertexCount)); - } - } - } - if (useDepthRaster_) { - DepthRasterTransform(prim, dec_, dec_->VertexType(), vertexCount); - } - } else { - VertexDecoder *swDec = dec_; - if (swDec->nweights != 0) { - u32 withSkinning = lastVType_ | (1 << 26); - if (withSkinning != lastVType_) { - swDec = GetVertexDecoder(withSkinning); - } - } - DecodeVerts(swDec, decoded_); - int vertexCount = DecodeInds(); - - bool hasColor = (lastVType_ & GE_VTYPE_COL_MASK) != GE_VTYPE_COL_NONE; - if (gstate.isModeThrough()) { - gstate_c.vertexFullAlpha = gstate_c.vertexFullAlpha && (hasColor || gstate.getMaterialAmbientA() == 255); - } else { - gstate_c.vertexFullAlpha = gstate_c.vertexFullAlpha && ((hasColor && (gstate.materialupdate & 1)) || gstate.getMaterialAmbientA() == 255) && (!gstate.isLightingEnabled() || gstate.getAmbientA() == 255); - } - - gpuStats.numUncachedVertsDrawn += vertexCount; - prim = IndexGenerator::GeneralPrim((GEPrimitiveType)drawInds_[0].prim); - VERBOSE_LOG(Log::G3D, "Flush prim %i SW! %i verts in one go", prim, vertexCount); - - u16 *inds = decIndex_; - SoftwareTransformResult result{}; - SoftwareTransformParams params{}; - params.decoded = decoded_; - params.transformed = transformed_; - params.transformedExpanded = transformedExpanded_; - params.fbman = framebufferManager_; - params.texCache = textureCache_; - params.allowClear = true; - params.allowSeparateAlphaClear = false; - params.flippedY = false; - params.usesHalfZ = true; - - if (gstate.getShadeMode() == GE_SHADE_FLAT) { - // We need to rotate the index buffer to simulate a different provoking vertex. - // We do this before line expansion etc. - int indexCount = RemainingIndices(inds); - IndexBufferProvokingLastToFirst(prim, inds, vertexCount); - } - - // We need correct viewport values in gstate_c already. - if (gstate_c.IsDirty(DIRTY_VIEWPORTSCISSOR_STATE)) { - ViewportAndScissor vpAndScissor; - ConvertViewportAndScissor(framebufferManager_->UseBufferedRendering(), - framebufferManager_->GetRenderWidth(), framebufferManager_->GetRenderHeight(), - framebufferManager_->GetTargetBufferWidth(), framebufferManager_->GetTargetBufferHeight(), - vpAndScissor); - UpdateCachedViewportState(vpAndScissor); - } - - // At this point, rect and line primitives are still preserved as such. So, it's the best time to do software depth raster. - // We could piggyback on the viewport transform below, but it gets complicated since it's different per-backend. Which we really - // should clean up one day... - if (useDepthRaster_) { - DepthRasterPredecoded(prim, decoded_, numDecodedVerts_, swDec, vertexCount); - } - - int maxIndex = numDecodedVerts_; - SoftwareTransform swTransform(params); - - // Half pixel offset hack. - float xOffset = -1.0f / gstate_c.curRTRenderWidth; - float yOffset = 1.0f / gstate_c.curRTRenderHeight; - - const Lin::Vec3 trans(gstate_c.vpXOffset + xOffset, -gstate_c.vpYOffset + yOffset, gstate_c.vpZOffset * 0.5f + 0.5f); - const Lin::Vec3 scale(gstate_c.vpWidthScale, gstate_c.vpHeightScale, gstate_c.vpDepthScale * 0.5f); - swTransform.SetProjMatrix(gstate.projMatrix, gstate_c.vpWidth < 0, gstate_c.vpHeight > 0, trans, scale); - - swTransform.Transform(prim, swDec->VertexType(), swDec->GetDecVtxFmt(), numDecodedVerts_, &result); - // Non-zero depth clears are unusual, but some drivers don't match drawn depth values to cleared values. - // Games sometimes expect exact matches (see #12626, for example) for equal comparisons. - if (result.action == SW_CLEAR && everUsedEqualDepth_ && gstate.isClearModeDepthMask() && result.depth > 0.0f && result.depth < 1.0f) - result.action = SW_NOT_READY; - - if (textureNeedsApply) { - gstate_c.pixelMapped = result.pixelMapped; - textureCache_->ApplyTexture(); - gstate_c.pixelMapped = false; - } - - ApplyDrawState(prim); - - if (result.action == SW_NOT_READY) - swTransform.BuildDrawingParams(prim, vertexCount, swDec->VertexType(), inds, RemainingIndices(inds), numDecodedVerts_, VERTEX_BUFFER_MAX, &result); - if (result.setSafeSize) - framebufferManager_->SetSafeSize(result.safeWidth, result.safeHeight); - - ApplyDrawStateLate(); - - VSShader *vshader = shaderManager_->ApplyShader(false, false, swDec, decOptions_.expandAllWeightsToFloat, true, pipelineState_); - - if (result.action == SW_DRAW_INDEXED) { - if (result.setStencil) { - dxstate.stencilFunc.set(D3DCMP_ALWAYS); - dxstate.stencilRef.set(result.stencilValue); - dxstate.stencilCompareMask.set(255); - } - - // TODO: Add a post-transform cache here for multi-RECTANGLES only. - // Might help for text drawing. - - device_->SetVertexDeclaration(transformedVertexDecl_.Get()); - device_->DrawIndexedPrimitiveUP(d3d_prim[prim], 0, numDecodedVerts_, D3DPrimCount(d3d_prim[prim], result.drawNumTrans), inds, D3DFMT_INDEX16, result.drawBuffer, sizeof(TransformedVertex)); - } else if (result.action == SW_CLEAR) { - u32 clearColor = result.color; - float clearDepth = result.depth; - - int mask = gstate.isClearModeColorMask() ? D3DCLEAR_TARGET : 0; - if (gstate.isClearModeAlphaMask()) mask |= D3DCLEAR_STENCIL; - if (gstate.isClearModeDepthMask()) mask |= D3DCLEAR_ZBUFFER; - - device_->Clear(0, NULL, mask, SwapRB(clearColor), clearDepth, clearColor >> 24); - - if (gstate_c.Use(GPU_USE_CLEAR_RAM_HACK) && gstate.isClearModeColorMask() && (gstate.isClearModeAlphaMask() || gstate_c.framebufFormat == GE_FORMAT_565)) { - int scissorX1 = gstate.getScissorX1(); - int scissorY1 = gstate.getScissorY1(); - int scissorX2 = gstate.getScissorX2() + 1; - int scissorY2 = gstate.getScissorY2() + 1; - framebufferManager_->ApplyClearToMemory(scissorX1, scissorY1, scissorX2, scissorY2, clearColor); - } - } - } - - ResetAfterDrawInline(); - framebufferManager_->SetColorUpdated(gstate_c.skipDrawReason); - gpuCommon_->NotifyFlush(); -} - -void TessellationDataTransferDX9::SendDataToShader(const SimpleVertex *const *points, int size_u, int size_v, u32 vertType, const Spline::Weight2D &weights) { - // TODO -} diff --git a/GPU/Directx9/DrawEngineDX9.h b/GPU/Directx9/DrawEngineDX9.h deleted file mode 100644 index c31e960b4c9e..000000000000 --- a/GPU/Directx9/DrawEngineDX9.h +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (c) 2012- PPSSPP Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0 or later versions. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official git repository and contact information can be found at -// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. - -#pragma once - -#include -#include - -#include "Common/Data/Collections/Hashmaps.h" -#include "GPU/GPUState.h" -#include "GPU/Common/DrawEngineCommon.h" -#include "GPU/MiscTypes.h" - -struct DecVtxFormat; -struct UVScale; - -class VSShader; -class ShaderManagerDX9; -class TextureCacheDX9; -class FramebufferManagerDX9; - -class TessellationDataTransferDX9 : public TessellationDataTransfer { -public: - TessellationDataTransferDX9() {} - ~TessellationDataTransferDX9() {} - void SendDataToShader(const SimpleVertex *const *points, int size_u, int size_v, u32 vertType, const Spline::Weight2D &weights) override; -}; - -// Handles transform, lighting and drawing. -class DrawEngineDX9 : public DrawEngineCommon { -public: - DrawEngineDX9(Draw::DrawContext *draw); - ~DrawEngineDX9(); - - void DeviceLost() override { draw_ = nullptr; } - void DeviceRestore(Draw::DrawContext *draw) override { draw_ = draw; } - - void SetShaderManager(ShaderManagerDX9 *shaderManager) { - shaderManager_ = shaderManager; - } - void SetTextureCache(TextureCacheDX9 *textureCache) { - textureCache_ = textureCache; - } - void SetFramebufferManager(FramebufferManagerDX9 *fbManager) { - framebufferManager_ = fbManager; - } - void InitDeviceObjects(); - void DestroyDeviceObjects(); - - void BeginFrame() override; - - // So that this can be inlined - void Flush() override; - - void FinishDeferred() { - DecodeVerts(dec_, decoded_); - } - -protected: - // Not currently supported. - bool UpdateUseHWTessellation(bool enable) const override { return false; } - -private: - void Invalidate(InvalidationCallbackFlags flags); - - void ApplyDrawState(int prim); - void ApplyDrawStateLate(); - - HRESULT SetupDecFmtForDraw(const DecVtxFormat &decFmt, u32 pspFmt, IDirect3DVertexDeclaration9 **ppVertexDeclaration); - - LPDIRECT3DDEVICE9 device_ = nullptr; - Draw::DrawContext *draw_; - - DenseHashMap> vertexDeclMap_; - - // SimpleVertex - Microsoft::WRL::ComPtr transformedVertexDecl_; - - // Other - ShaderManagerDX9 *shaderManager_ = nullptr; - TextureCacheDX9 *textureCache_ = nullptr; - FramebufferManagerDX9 *framebufferManager_ = nullptr; - - // Hardware tessellation - TessellationDataTransferDX9 *tessDataTransferDX9; - - FBOTexState fboTexBindState_ = FBO_TEX_NONE; - - int lastRenderStepId_ = -1; - - bool fboTexNeedsBind_ = false; -}; diff --git a/GPU/Directx9/FramebufferManagerDX9.cpp b/GPU/Directx9/FramebufferManagerDX9.cpp deleted file mode 100644 index e03577e04982..000000000000 --- a/GPU/Directx9/FramebufferManagerDX9.cpp +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (c) 2012- PPSSPP Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0 or later versions. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official git repository and contact information can be found at -// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. - -#include - -#include "Common/Common.h" -#include "Common/GPU/thin3d.h" - -#include "GPU/Common/FramebufferManagerCommon.h" -#include "GPU/Common/GPUStateUtils.h" -#include "GPU/Common/PresentationCommon.h" -#include "GPU/Directx9/FramebufferManagerDX9.h" - -FramebufferManagerDX9::FramebufferManagerDX9(Draw::DrawContext *draw) - : FramebufferManagerCommon(draw) { - presentation_->SetLanguage(HLSL_D3D9); - preferredPixelsFormat_ = Draw::DataFormat::B8G8R8A8_UNORM; -} - -bool FramebufferManagerDX9::ReadbackDepthbuffer(Draw::Framebuffer *fbo, int x, int y, int w, int h, uint16_t *pixels, int pixelsStride, int destW, int destH, Draw::ReadbackMode mode) { - // Don't yet support stretched readbacks here. - if (destW != w || destH != h) { - return false; - } - - // We always read the depth buffer in 24_8 format. - LPDIRECT3DTEXTURE9 tex = (LPDIRECT3DTEXTURE9)draw_->GetFramebufferAPITexture(fbo, Draw::Aspect::DEPTH_BIT, 0); - if (!tex) - return false; - - // This is separate from the thin3d way because it applies DepthScaleFactors. - D3DSURFACE_DESC desc; - D3DLOCKED_RECT locked; - tex->GetLevelDesc(0, &desc); - - RECT rect = {(LONG)x, (LONG)y, (LONG)w, (LONG)h}; - HRESULT hr = tex->LockRect(0, &locked, &rect, D3DLOCK_READONLY); - if (!SUCCEEDED(hr)) - return false; - - const u32 *packed = (const u32 *)locked.pBits; - u16 *depth = (u16 *)pixels; - - DepthScaleFactors depthScale = GetDepthScaleFactors(gstate_c.UseFlags()); - // TODO: Optimize. - for (int yp = 0; yp < h; ++yp) { - for (int xp = 0; xp < w; ++xp) { - const int offset = (yp + y) * pixelsStride + x + xp; - - float scaled = depthScale.DecodeToU16((packed[offset] & 0x00FFFFFF) * (1.0f / 16777215.0f)); - if (scaled <= 0.0f) { - depth[offset] = 0; - } else if (scaled >= 65535.0f) { - depth[offset] = 65535; - } else { - depth[offset] = (int)scaled; - } - } - } - - tex->UnlockRect(0); - return true; -} diff --git a/GPU/Directx9/FramebufferManagerDX9.h b/GPU/Directx9/FramebufferManagerDX9.h deleted file mode 100644 index 5a76d059447c..000000000000 --- a/GPU/Directx9/FramebufferManagerDX9.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2012- PPSSPP Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0 or later versions. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official git repository and contact information can be found at -// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. - -#pragma once - -#include "GPU/GPUCommon.h" -#include "GPU/Common/FramebufferManagerCommon.h" - -class FramebufferManagerDX9 : public FramebufferManagerCommon { -public: - FramebufferManagerDX9(Draw::DrawContext *draw); - -protected: - // TODO: The non-color path of FramebufferManagerCommon::ReadbackDepthbufferSync seems to work just as well. - bool ReadbackDepthbuffer(Draw::Framebuffer *fbo, int x, int y, int w, int h, uint16_t *pixels, int pixelsStride, int destW, int destH, Draw::ReadbackMode mode) override; -}; diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp deleted file mode 100644 index 2adf0c62222f..000000000000 --- a/GPU/Directx9/GPU_DX9.cpp +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright (c) 2012- PPSSPP Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0 or later versions. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official git repository and contact information can be found at -// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. - -#include - -#include "Common/Serialize/Serializer.h" -#include "Common/GraphicsContext.h" -#include "Common/System/OSD.h" -#include "Common/Profiler/Profiler.h" -#include "Common/Data/Text/I18n.h" -#include "Core/Config.h" - -#include "Common/GPU/D3D9/D3D9StateCache.h" - -#include "GPU/GPUState.h" - -#include "GPU/Common/FramebufferManagerCommon.h" -#include "GPU/Directx9/ShaderManagerDX9.h" -#include "GPU/Directx9/GPU_DX9.h" -#include "GPU/Directx9/FramebufferManagerDX9.h" -#include "GPU/Directx9/DrawEngineDX9.h" -#include "GPU/Directx9/TextureCacheDX9.h" - -GPU_DX9::GPU_DX9(GraphicsContext *gfxCtx, Draw::DrawContext *draw) - : GPUCommonHW(gfxCtx, draw), - drawEngine_(draw) { - device_ = (LPDIRECT3DDEVICE9)draw->GetNativeObject(Draw::NativeObject::DEVICE); - deviceEx_ = (LPDIRECT3DDEVICE9EX)draw->GetNativeObject(Draw::NativeObject::DEVICE_EX); - - shaderManagerDX9_ = new ShaderManagerDX9(draw, device_); - framebufferManagerDX9_ = new FramebufferManagerDX9(draw); - framebufferManager_ = framebufferManagerDX9_; - textureCacheDX9_ = new TextureCacheDX9(draw, framebufferManager_->GetDraw2D()); - textureCache_ = textureCacheDX9_; - drawEngineCommon_ = &drawEngine_; - shaderManager_ = shaderManagerDX9_; - - drawEngine_.SetGPUCommon(this); - drawEngine_.SetShaderManager(shaderManagerDX9_); - drawEngine_.SetTextureCache(textureCacheDX9_); - drawEngine_.SetFramebufferManager(framebufferManagerDX9_); - drawEngine_.Init(); - framebufferManagerDX9_->SetTextureCache(textureCacheDX9_); - framebufferManagerDX9_->SetShaderManager(shaderManagerDX9_); - framebufferManagerDX9_->SetDrawEngine(&drawEngine_); - framebufferManagerDX9_->Init(msaaLevel_); - textureCacheDX9_->SetFramebufferManager(framebufferManagerDX9_); - textureCacheDX9_->SetShaderManager(shaderManagerDX9_); - - // Sanity check gstate - if ((int *)&gstate.transferstart - (int *)&gstate != 0xEA) { - ERROR_LOG(Log::G3D, "gstate has drifted out of sync!"); - } - - // No need to flush before the tex scale/offset commands if we are baking - // the tex scale/offset into the vertices anyway. - UpdateCmdInfo(); - gstate_c.SetUseFlags(CheckGPUFeatures()); - - BuildReportingInfo(); - - // Some of our defaults are different from hw defaults, let's assert them. - // We restore each frame anyway, but here is convenient for tests. - dxstate.Restore(); - textureCache_->NotifyConfigChanged(); - - if (g_Config.bHardwareTessellation) { - // Disable hardware tessellation bacause DX9 is still unsupported. - ERROR_LOG(Log::G3D, "Hardware Tessellation is unsupported, falling back to software tessellation"); - auto gr = GetI18NCategory(I18NCat::GRAPHICS); - // TODO: Badly formulated - g_OSD.Show(OSDType::MESSAGE_WARNING, gr->T("Turn off Hardware Tessellation - unsupported")); - } -} - -u32 GPU_DX9::CheckGPUFeatures() const { - u32 features = GPUCommonHW::CheckGPUFeatures(); - features |= GPU_USE_16BIT_FORMATS; - features |= GPU_USE_TEXTURE_LOD_CONTROL; - - // Accurate depth is required because the Direct3D API does not support inverse Z. - // So we cannot incorrectly use the viewport transform as the depth range on Direct3D. - features |= GPU_USE_ACCURATE_DEPTH; - - return CheckGPUFeaturesLate(features); -} - -void GPU_DX9::DeviceLost() { - GPUCommonHW::DeviceLost(); -} - -void GPU_DX9::DeviceRestore(Draw::DrawContext *draw) { - GPUCommonHW::DeviceRestore(draw); -} - -void GPU_DX9::ReapplyGfxState() { - dxstate.Restore(); - GPUCommonHW::ReapplyGfxState(); -} - -void GPU_DX9::BeginHostFrame() { - GPUCommonHW::BeginHostFrame(); - - textureCache_->StartFrame(); - drawEngine_.BeginFrame(); - - shaderManagerDX9_->DirtyLastShader(); - - framebufferManager_->BeginFrame(); - - if (gstate_c.useFlagsChanged) { - // TODO: It'd be better to recompile them in the background, probably? - // This most likely means that saw equal depth changed. - WARN_LOG(Log::G3D, "Shader use flags changed, clearing all shaders and depth buffers"); - shaderManager_->ClearShaders(); - framebufferManager_->ClearAllDepthBuffers(); - gstate_c.useFlagsChanged = false; - } -} - -void GPU_DX9::FinishDeferred() { - // This finishes reading any vertex data that is pending. - drawEngine_.FinishDeferred(); -} - -void GPU_DX9::GetStats(char *buffer, size_t bufsize) { - size_t offset = FormatGPUStatsCommon(buffer, bufsize); - buffer += offset; - bufsize -= offset; - if ((int)bufsize < 0) - return; - snprintf(buffer, bufsize, - "Vertex, Fragment shaders loaded: %i, %i\n", - shaderManagerDX9_->GetNumVertexShaders(), - shaderManagerDX9_->GetNumFragmentShaders() - ); -} diff --git a/GPU/Directx9/GPU_DX9.h b/GPU/Directx9/GPU_DX9.h deleted file mode 100644 index 5b675ae481a7..000000000000 --- a/GPU/Directx9/GPU_DX9.h +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 2012- PPSSPP Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0 or later versions. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official git repository and contact information can be found at -// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. - -#pragma once - -#include -#include - -#include "Common/GPU/thin3d.h" -#include "GPU/GPUCommonHW.h" -#include "GPU/Directx9/DrawEngineDX9.h" -#include "GPU/Common/TextureShaderCommon.h" -#include "GPU/Common/VertexDecoderCommon.h" - -class ShaderManagerDX9; -class LinkedShaderDX9; -class TextureCacheDX9; -class FramebufferManagerDX9; - -class GPU_DX9 : public GPUCommonHW { -public: - GPU_DX9(GraphicsContext *gfxCtx, Draw::DrawContext *draw); - - u32 CheckGPUFeatures() const override; - - void DeviceLost() override; - void DeviceRestore(Draw::DrawContext *draw) override; - - void ReapplyGfxState() override; - void GetStats(char *buffer, size_t bufsize) override; - -protected: - void FinishDeferred() override; - -private: - void BeginHostFrame() override; - - LPDIRECT3DDEVICE9 device_; - LPDIRECT3DDEVICE9EX deviceEx_; - - FramebufferManagerDX9 *framebufferManagerDX9_; - TextureCacheDX9 *textureCacheDX9_; - DrawEngineDX9 drawEngine_; - ShaderManagerDX9 *shaderManagerDX9_; -}; diff --git a/GPU/Directx9/ShaderManagerDX9.cpp b/GPU/Directx9/ShaderManagerDX9.cpp deleted file mode 100644 index f44cb97730a7..000000000000 --- a/GPU/Directx9/ShaderManagerDX9.cpp +++ /dev/null @@ -1,700 +0,0 @@ -// Copyright (c) 2012- PPSSPP Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0 or later versions. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official git repository and contact information can be found at -// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. - -#ifdef _WIN32 -//#define SHADERLOG -#endif - -#include -#include - -#include "Common/Data/Convert/SmallDataConvert.h" -#include "Common/Data/Encoding/Utf8.h" -#include "Common/Data/Text/I18n.h" -#include "Common/Math/lin/matrix4x4.h" -#include "Common/Math/math_util.h" -#include "Common/GPU/D3D9/D3D9ShaderCompiler.h" -#include "Common/GPU/thin3d.h" -#include "Common/System/OSD.h" -#include "Common/System/Display.h" - -#include "Common/CommonTypes.h" -#include "Common/Log.h" -#include "Common/LogReporting.h" -#include "Common/StringUtils.h" - -#include "Core/Config.h" -#include "GPU/Math3D.h" -#include "GPU/GPUState.h" -#include "GPU/ge_constants.h" -#include "GPU/Common/ShaderUniforms.h" -#include "GPU/Common/FragmentShaderGenerator.h" -#include "GPU/Directx9/ShaderManagerDX9.h" -#include "GPU/Directx9/DrawEngineDX9.h" -#include "GPU/Directx9/FramebufferManagerDX9.h" - -using namespace Lin; - -PSShader::PSShader(LPDIRECT3DDEVICE9 device, FShaderID id, const char *code) : id_(id) { - source_ = code; -#ifdef SHADERLOG - OutputDebugString(ConvertUTF8ToWString(code).c_str()); -#endif - bool success; - std::string errorMessage; - - success = CompilePixelShaderD3D9(device, code, &shader, &errorMessage); - - if (!errorMessage.empty()) { - if (success) { - ERROR_LOG(Log::G3D, "Warnings in shader compilation!"); - } else { - ERROR_LOG(Log::G3D, "Error in shader compilation!"); - } - ERROR_LOG(Log::G3D, "Messages: %s", errorMessage.c_str()); - ERROR_LOG(Log::G3D, "Shader source:\n%s", LineNumberString(code).c_str()); - OutputDebugStringUTF8("Messages:\n"); - OutputDebugStringUTF8(errorMessage.c_str()); - Reporting::ReportMessage("D3D error in shader compilation: info: %s / code: %s", errorMessage.c_str(), code); - } - - if (!success) { - failed_ = true; - shader = nullptr; - return; - } else { - VERBOSE_LOG(Log::G3D, "Compiled pixel shader:\n%s\n", (const char *)code); - } -} - -PSShader::~PSShader() { -} - -std::string PSShader::GetShaderString(DebugShaderStringType type) const { - switch (type) { - case SHADER_STRING_SOURCE_CODE: - return source_; - case SHADER_STRING_SHORT_DESC: - return FragmentShaderDesc(id_); - default: - return "N/A"; - } -} - -VSShader::VSShader(LPDIRECT3DDEVICE9 device, VShaderID id, const char *code, bool useHWTransform) : useHWTransform_(useHWTransform), id_(id) { - source_ = code; -#ifdef SHADERLOG - OutputDebugString(ConvertUTF8ToWString(code).c_str()); -#endif - bool success; - std::string errorMessage; - - success = CompileVertexShaderD3D9(device, code, &shader, &errorMessage); - if (!errorMessage.empty()) { - if (success) { - ERROR_LOG(Log::G3D, "Warnings in shader compilation!"); - } else { - ERROR_LOG(Log::G3D, "Error in shader compilation!"); - } - ERROR_LOG(Log::G3D, "Messages: %s", errorMessage.c_str()); - ERROR_LOG(Log::G3D, "Shader source:\n%s", code); - OutputDebugStringUTF8("Messages:\n"); - OutputDebugStringUTF8(errorMessage.c_str()); - Reporting::ReportMessage("D3D error in shader compilation: info: %s / code: %s", errorMessage.c_str(), code); - } - - if (!success) { - failed_ = true; - shader = nullptr; - return; - } else { - VERBOSE_LOG(Log::G3D, "Compiled vertex shader:\n%s\n", (const char *)code); - } -} - -VSShader::~VSShader() { -} - -std::string VSShader::GetShaderString(DebugShaderStringType type) const { - switch (type) { - case SHADER_STRING_SOURCE_CODE: - return source_; - case SHADER_STRING_SHORT_DESC: - return VertexShaderDesc(id_); - default: - return "N/A"; - } -} - -void ShaderManagerDX9::PSSetColorUniform3(int creg, u32 color) { - float f[4]; - Uint8x3ToFloat4(f, color); - device_->SetPixelShaderConstantF(creg, f, 1); -} - -void ShaderManagerDX9::PSSetColorUniform3Alpha255(int creg, u32 color, u8 alpha) { - const float col[4] = { - (float)((color & 0xFF)), - (float)((color & 0xFF00) >> 8), - (float)((color & 0xFF0000) >> 16), - (float)alpha, - }; - device_->SetPixelShaderConstantF(creg, col, 1); -} - -void ShaderManagerDX9::PSSetFloat(int creg, float value) { - const float f[4] = { value, 0.0f, 0.0f, 0.0f }; - device_->SetPixelShaderConstantF(creg, f, 1); -} - -void ShaderManagerDX9::PSSetFloatArray(int creg, const float *value, int count) { - float f[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; - for (int i = 0; i < count; i++) { - f[i] = value[i]; - } - device_->SetPixelShaderConstantF(creg, f, 1); -} - -void ShaderManagerDX9::VSSetFloat(int creg, float value) { - const float f[4] = { value, 0.0f, 0.0f, 0.0f }; - device_->SetVertexShaderConstantF(creg, f, 1); -} - -void ShaderManagerDX9::VSSetFloatArray(int creg, const float *value, int count) { - float f[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; - for (int i = 0; i < count; i++) { - f[i] = value[i]; - } - device_->SetVertexShaderConstantF(creg, f, 1); -} - -// Utility -void ShaderManagerDX9::VSSetColorUniform3(int creg, u32 color) { - float f[4]; - Uint8x3ToFloat4(f, color); - device_->SetVertexShaderConstantF(creg, f, 1); -} - -void ShaderManagerDX9::VSSetFloatUniform4(int creg, const float data[4]) { - device_->SetVertexShaderConstantF(creg, data, 1); -} - -void ShaderManagerDX9::VSSetFloat24Uniform3(int creg, const u32 data[3]) { - float f[4]; - ExpandFloat24x3ToFloat4(f, data); - device_->SetVertexShaderConstantF(creg, f, 1); -} - -void ShaderManagerDX9::VSSetFloat24Uniform3Normalized(int creg, const u32 data[3]) { - float f[4]; - ExpandFloat24x3ToFloat4AndNormalize(f, data); - device_->SetVertexShaderConstantF(creg, f, 1); -} - -void ShaderManagerDX9::VSSetColorUniform3Alpha(int creg, u32 color, u8 alpha) { - float f[4]; - Uint8x3ToFloat4_AlphaUint8(f, color, alpha); - device_->SetVertexShaderConstantF(creg, f, 1); -} - -void ShaderManagerDX9::VSSetColorUniform3ExtraFloat(int creg, u32 color, float extra) { - const float col[4] = { - ((color & 0xFF)) / 255.0f, - ((color & 0xFF00) >> 8) / 255.0f, - ((color & 0xFF0000) >> 16) / 255.0f, - extra - }; - device_->SetVertexShaderConstantF(creg, col, 1); -} - -void ShaderManagerDX9::VSSetMatrix4x3_3(int creg, const float *m4x3) { - float m3x4[12]; - ConvertMatrix4x3To3x4Transposed(m3x4, m4x3); - device_->SetVertexShaderConstantF(creg, m3x4, 3); -} - -void ShaderManagerDX9::VSSetMatrix(int creg, const float* pMatrix) { - device_->SetVertexShaderConstantF(creg, pMatrix, 4); -} - -// Depth in ogl is between -1;1 we need between 0;1 and optionally reverse it -static void ConvertProjMatrixToD3D(Matrix4x4 &in, bool invertedX, bool invertedY) { - // Half pixel offset hack - float xoff = 1.0f / gstate_c.curRTRenderWidth; - if (invertedX) { - xoff = -gstate_c.vpXOffset - xoff; - } else { - xoff = gstate_c.vpXOffset - xoff; - } - - float yoff = -1.0f / gstate_c.curRTRenderHeight; - if (invertedY) { - yoff = -gstate_c.vpYOffset - yoff; - } else { - yoff = gstate_c.vpYOffset - yoff; - } - - const Vec3 trans(xoff, yoff, gstate_c.vpZOffset * 0.5f + 0.5f); - const Vec3 scale(gstate_c.vpWidthScale, gstate_c.vpHeightScale, gstate_c.vpDepthScale * 0.5f); - in.translateAndScale(trans, scale); -} - -static void ConvertProjMatrixToD3DThrough(Matrix4x4 &in) { - float xoff = -1.0f / gstate_c.curRTRenderWidth; - float yoff = 1.0f / gstate_c.curRTRenderHeight; - in.translateAndScale(Vec3(xoff, yoff, 0.5f), Vec3(1.0f, 1.0f, 0.5f)); -} - -const uint64_t psUniforms = DIRTY_TEXENV | DIRTY_TEX_ALPHA_MUL | DIRTY_ALPHACOLORREF | DIRTY_ALPHACOLORMASK | DIRTY_FOGCOLOR | DIRTY_STENCILREPLACEVALUE | DIRTY_SHADERBLEND | DIRTY_TEXCLAMP | DIRTY_MIPBIAS; - -void ShaderManagerDX9::PSUpdateUniforms(u64 dirtyUniforms) { - if (dirtyUniforms & DIRTY_TEXENV) { - PSSetColorUniform3(CONST_PS_TEXENV, gstate.texenvcolor); - } - if (dirtyUniforms & DIRTY_ALPHACOLORREF) { - PSSetColorUniform3Alpha255(CONST_PS_ALPHACOLORREF, gstate.getColorTestRef(), gstate.getAlphaTestRef() & gstate.getAlphaTestMask()); - } - if (dirtyUniforms & DIRTY_ALPHACOLORMASK) { - PSSetColorUniform3Alpha255(CONST_PS_ALPHACOLORMASK, gstate.colortestmask, gstate.getAlphaTestMask()); - } - if (dirtyUniforms & DIRTY_FOGCOLOR) { - PSSetColorUniform3(CONST_PS_FOGCOLOR, gstate.fogcolor); - } - if (dirtyUniforms & DIRTY_STENCILREPLACEVALUE) { - PSSetFloat(CONST_PS_STENCILREPLACE, (float)gstate.getStencilTestRef() * (1.0f / 255.0f)); - } - if (dirtyUniforms & DIRTY_TEX_ALPHA_MUL) { - bool doTextureAlpha = gstate.isTextureAlphaUsed(); - if (gstate_c.textureFullAlpha && gstate.getTextureFunction() != GE_TEXFUNC_REPLACE) { - doTextureAlpha = false; - } - // NOTE: Reversed value, more efficient in shader. - float noAlphaMul[2] = { doTextureAlpha ? 0.0f : 1.0f, gstate.isColorDoublingEnabled() ? 2.0f : 1.0f }; - PSSetFloatArray(CONST_PS_TEX_NO_ALPHA_MUL, noAlphaMul, 2); - } - if (dirtyUniforms & DIRTY_SHADERBLEND) { - PSSetColorUniform3(CONST_PS_BLENDFIXA, gstate.getFixA()); - PSSetColorUniform3(CONST_PS_BLENDFIXB, gstate.getFixB()); - - const float fbotexSize[2] = { - 1.0f / (float)gstate_c.curRTRenderWidth, - 1.0f / (float)gstate_c.curRTRenderHeight, - }; - PSSetFloatArray(CONST_PS_FBOTEXSIZE, fbotexSize, 2); - } - - if (dirtyUniforms & DIRTY_TEXCLAMP) { - const float invW = 1.0f / (float)gstate_c.curTextureWidth; - const float invH = 1.0f / (float)gstate_c.curTextureHeight; - const int w = gstate.getTextureWidth(0); - const int h = gstate.getTextureHeight(0); - const float widthFactor = (float)w * invW; - const float heightFactor = (float)h * invH; - - // First wrap xy, then half texel xy (for clamp.) - const float texclamp[4] = { - widthFactor, - heightFactor, - invW * 0.5f, - invH * 0.5f, - }; - const float texclampoff[2] = { - gstate_c.curTextureXOffset * invW, - gstate_c.curTextureYOffset * invH, - }; - PSSetFloatArray(CONST_PS_TEXCLAMP, texclamp, 4); - PSSetFloatArray(CONST_PS_TEXCLAMPOFF, texclampoff, 2); - } - - if (dirtyUniforms & DIRTY_MIPBIAS) { - float mipBias = (float)gstate.getTexLevelOffset16() * (1.0 / 16.0f); - - // NOTE: This equation needs some adjustment in D3D9. Can't get it to look completely smooth :( - mipBias = (mipBias + 0.25f) / (float)(gstate.getTextureMaxLevel() + 1); - PSSetFloatArray(CONST_PS_MIPBIAS, &mipBias, 1); - } -} - -const uint64_t vsUniforms = DIRTY_PROJMATRIX | DIRTY_PROJTHROUGHMATRIX | DIRTY_WORLDMATRIX | DIRTY_VIEWMATRIX | DIRTY_TEXMATRIX | -DIRTY_FOGCOEF | DIRTY_BONE_UNIFORMS | DIRTY_UVSCALEOFFSET | DIRTY_DEPTHRANGE | DIRTY_CULLRANGE | -DIRTY_AMBIENT | DIRTY_MATAMBIENTALPHA | DIRTY_MATSPECULAR | DIRTY_MATDIFFUSE | DIRTY_MATEMISSIVE | DIRTY_LIGHT0 | DIRTY_LIGHT1 | DIRTY_LIGHT2 | DIRTY_LIGHT3; - -void ShaderManagerDX9::VSUpdateUniforms(u64 dirtyUniforms) { - // Update any dirty uniforms before we draw - if (dirtyUniforms & DIRTY_PROJMATRIX) { - Matrix4x4 flippedMatrix; - memcpy(&flippedMatrix, gstate.projMatrix, 16 * sizeof(float)); - - const bool invertedY = gstate_c.vpHeight < 0; - if (!invertedY) { - flippedMatrix[1] = -flippedMatrix[1]; - flippedMatrix[5] = -flippedMatrix[5]; - flippedMatrix[9] = -flippedMatrix[9]; - flippedMatrix[13] = -flippedMatrix[13]; - } - const bool invertedX = gstate_c.vpWidth < 0; - if (invertedX) { - flippedMatrix[0] = -flippedMatrix[0]; - flippedMatrix[4] = -flippedMatrix[4]; - flippedMatrix[8] = -flippedMatrix[8]; - flippedMatrix[12] = -flippedMatrix[12]; - } - - ConvertProjMatrixToD3D(flippedMatrix, invertedX, invertedY); - - VSSetMatrix(CONST_VS_PROJ, flippedMatrix.getReadPtr()); - VSSetFloat(CONST_VS_ROTATION, 0); // We don't use this on any platform in D3D9. - } - if (dirtyUniforms & DIRTY_PROJTHROUGHMATRIX) { - Matrix4x4 proj_through; - proj_through.setOrtho(0.0f, gstate_c.curRTWidth, gstate_c.curRTHeight, 0, 0, 1); - - ConvertProjMatrixToD3DThrough(proj_through); - - VSSetMatrix(CONST_VS_PROJ_THROUGH, proj_through.getReadPtr()); - } - // Transform - if (dirtyUniforms & DIRTY_WORLDMATRIX) { - VSSetMatrix4x3_3(CONST_VS_WORLD, gstate.worldMatrix); - } - if (dirtyUniforms & DIRTY_VIEWMATRIX) { - VSSetMatrix4x3_3(CONST_VS_VIEW, gstate.viewMatrix); - } - if (dirtyUniforms & DIRTY_TEXMATRIX) { - VSSetMatrix4x3_3(CONST_VS_TEXMTX, gstate.tgenMatrix); - } - if (dirtyUniforms & DIRTY_FOGCOEF) { - float fogcoef[2] = { - getFloat24(gstate.fog1), - getFloat24(gstate.fog2), - }; - // The PSP just ignores infnan here (ignoring IEEE), so take it down to a valid float. - // Workaround for https://github.com/hrydgard/ppsspp/issues/5384#issuecomment-38365988 - if (my_isnanorinf(fogcoef[0])) { - // Not really sure what a sensible value might be, but let's try 64k. - fogcoef[0] = std::signbit(fogcoef[0]) ? -65535.0f : 65535.0f; - } - if (my_isnanorinf(fogcoef[1])) { - fogcoef[1] = std::signbit(fogcoef[1]) ? -65535.0f : 65535.0f; - } - VSSetFloatArray(CONST_VS_FOGCOEF, fogcoef, 2); - } - // TODO: Could even set all bones in one go if they're all dirty. -#ifdef USE_BONE_ARRAY - if (u_bone != 0) { - float allBones[8 * 16]; - - bool allDirty = true; - for (int i = 0; i < numBones; i++) { - if (dirtyUniforms & (DIRTY_BONEMATRIX0 << i)) { - ConvertMatrix4x3To4x4(allBones + 16 * i, gstate.boneMatrix + 12 * i); - } else { - allDirty = false; - } - } - if (allDirty) { - // Set them all with one call - //glUniformMatrix4fv(u_bone, numBones, GL_FALSE, allBones); - } else { - // Set them one by one. Could try to coalesce two in a row etc but too lazy. - for (int i = 0; i < numBones; i++) { - if (dirtyUniforms & (DIRTY_BONEMATRIX0 << i)) { - //glUniformMatrix4fv(u_bone + i, 1, GL_FALSE, allBones + 16 * i); - } - } - } - } -#else - for (int i = 0; i < 8; i++) { - if (dirtyUniforms & (DIRTY_BONEMATRIX0 << i)) { - VSSetMatrix4x3_3(CONST_VS_BONE0 + 3 * i, gstate.boneMatrix + 12 * i); - } - } -#endif - - // Texturing - if (dirtyUniforms & DIRTY_UVSCALEOFFSET) { - float widthFactor = 1.0f; - float heightFactor = 1.0f; - if (gstate_c.textureIsFramebuffer) { - const float invW = 1.0f / (float)gstate_c.curTextureWidth; - const float invH = 1.0f / (float)gstate_c.curTextureHeight; - const int w = gstate.getTextureWidth(0); - const int h = gstate.getTextureHeight(0); - widthFactor = (float)w * invW; - heightFactor = (float)h * invH; - } - float uvscaleoff[4]; - uvscaleoff[0] = widthFactor; - uvscaleoff[1] = heightFactor; - uvscaleoff[2] = 0.0f; - uvscaleoff[3] = 0.0f; - VSSetFloatArray(CONST_VS_UVSCALEOFFSET, uvscaleoff, 4); - } - - if (dirtyUniforms & DIRTY_DEPTHRANGE) { - // Depth is [0, 1] mapping to [minz, maxz], not too hard. - float vpZScale = gstate.getViewportZScale(); - float vpZCenter = gstate.getViewportZCenter(); - - // These are just the reverse of the formulas in GPUStateUtils. - float halfActualZRange = InfToZero(gstate_c.vpDepthScale != 0.0f ? vpZScale / gstate_c.vpDepthScale : 0.0f); - float minz = -((gstate_c.vpZOffset * halfActualZRange) - vpZCenter) - halfActualZRange; - float viewZScale = halfActualZRange * 2.0f; - float viewZCenter = minz; - float reverseScale = InfToZero(gstate_c.vpDepthScale != 0.0f ? 2.0f * (1.0f / gstate_c.vpDepthScale) : 0.0f); - float reverseTranslate = gstate_c.vpZOffset * 0.5f + 0.5f; - - float data[4] = { viewZScale, viewZCenter, reverseTranslate, reverseScale }; - VSSetFloatUniform4(CONST_VS_DEPTHRANGE, data); - - if (draw_->GetDeviceCaps().clipPlanesSupported >= 1) { - float clip[4] = { 0.0f, 0.0f, reverseScale, 1.0f - reverseTranslate * reverseScale }; - // Well, not a uniform, but we treat it as one like other backends. - device_->SetClipPlane(0, clip); - } - } - if (dirtyUniforms & DIRTY_CULLRANGE) { - float minValues[4], maxValues[4]; - CalcCullRange(minValues, maxValues, false, false); - VSSetFloatUniform4(CONST_VS_CULLRANGEMIN, minValues); - VSSetFloatUniform4(CONST_VS_CULLRANGEMAX, maxValues); - } - - // Lighting - if (dirtyUniforms & DIRTY_AMBIENT) { - VSSetColorUniform3Alpha(CONST_VS_AMBIENT, gstate.ambientcolor, gstate.getAmbientA()); - } - if (dirtyUniforms & DIRTY_MATAMBIENTALPHA) { - VSSetColorUniform3Alpha(CONST_VS_MATAMBIENTALPHA, gstate.materialambient, gstate.getMaterialAmbientA()); - } - if (dirtyUniforms & DIRTY_MATDIFFUSE) { - VSSetColorUniform3(CONST_VS_MATDIFFUSE, gstate.materialdiffuse); - } - if (dirtyUniforms & DIRTY_MATEMISSIVE) { - VSSetColorUniform3(CONST_VS_MATEMISSIVE, gstate.materialemissive); - } - if (dirtyUniforms & DIRTY_MATSPECULAR) { - VSSetColorUniform3ExtraFloat(CONST_VS_MATSPECULAR, gstate.materialspecular, getFloat24(gstate.materialspecularcoef)); - } - for (int i = 0; i < 4; i++) { - if (dirtyUniforms & (DIRTY_LIGHT0 << i)) { - if (gstate.isDirectionalLight(i)) { - VSSetFloat24Uniform3Normalized(CONST_VS_LIGHTPOS + i, &gstate.lpos[i * 3]); - } else { - VSSetFloat24Uniform3(CONST_VS_LIGHTPOS + i, &gstate.lpos[i * 3]); - } - VSSetFloat24Uniform3Normalized(CONST_VS_LIGHTDIR + i, &gstate.ldir[i * 3]); - VSSetFloat24Uniform3(CONST_VS_LIGHTATT + i, &gstate.latt[i * 3]); - float angle_spotCoef[4] = { getFloat24(gstate.lcutoff[i]), getFloat24(gstate.lconv[i]) }; - VSSetFloatUniform4(CONST_VS_LIGHTANGLE_SPOTCOEF + i, angle_spotCoef); - VSSetColorUniform3(CONST_VS_LIGHTAMBIENT + i, gstate.lcolor[i * 3]); - VSSetColorUniform3(CONST_VS_LIGHTDIFFUSE + i, gstate.lcolor[i * 3 + 1]); - VSSetColorUniform3(CONST_VS_LIGHTSPECULAR + i, gstate.lcolor[i * 3 + 2]); - } - } -} - -ShaderManagerDX9::ShaderManagerDX9(Draw::DrawContext *draw, LPDIRECT3DDEVICE9 device) - : ShaderManagerCommon(draw), device_(device) { - codeBuffer_ = new char[32768]; -} - -ShaderManagerDX9::~ShaderManagerDX9() { - delete [] codeBuffer_; -} - -void ShaderManagerDX9::Clear() { - for (auto iter = fsCache_.begin(); iter != fsCache_.end(); ++iter) { - delete iter->second; - } - for (auto iter = vsCache_.begin(); iter != vsCache_.end(); ++iter) { - delete iter->second; - } - fsCache_.clear(); - vsCache_.clear(); - DirtyLastShader(); -} - -void ShaderManagerDX9::ClearShaders() { - Clear(); -} - -void ShaderManagerDX9::DirtyLastShader() { - // Forget the last shader ID - lastFSID_.set_invalid(); - lastVSID_.set_invalid(); - lastVShader_ = nullptr; - lastPShader_ = nullptr; - // TODO: Probably not necessary to dirty uniforms here on DX9. - gstate_c.Dirty(DIRTY_ALL_UNIFORMS | DIRTY_VERTEXSHADER_STATE | DIRTY_FRAGMENTSHADER_STATE); -} - -VSShader *ShaderManagerDX9::ApplyShader(bool useHWTransform, bool useHWTessellation, VertexDecoder *decoder, bool weightsAsFloat, bool useSkinInDecode, const ComputedPipelineState &pipelineState) { - VShaderID VSID; - if (gstate_c.IsDirty(DIRTY_VERTEXSHADER_STATE)) { - gstate_c.Clean(DIRTY_VERTEXSHADER_STATE); - ComputeVertexShaderID(&VSID, decoder, useHWTransform, useHWTessellation, weightsAsFloat, useSkinInDecode); - } else { - VSID = lastVSID_; - } - - FShaderID FSID; - if (gstate_c.IsDirty(DIRTY_FRAGMENTSHADER_STATE)) { - gstate_c.Clean(DIRTY_FRAGMENTSHADER_STATE); - ComputeFragmentShaderID(&FSID, pipelineState, draw_->GetBugs()); - } else { - FSID = lastFSID_; - } - - // Just update uniforms if this is the same shader as last time. - if (lastVShader_ != nullptr && lastPShader_ != nullptr && VSID == lastVSID_ && FSID == lastFSID_) { - uint64_t dirtyUniforms = gstate_c.GetDirtyUniforms(); - if (dirtyUniforms) { - if (dirtyUniforms & psUniforms) - PSUpdateUniforms(dirtyUniforms); - if (dirtyUniforms & vsUniforms) - VSUpdateUniforms(dirtyUniforms); - gstate_c.CleanUniforms(); - } - return lastVShader_; // Already all set. - } - - VSCache::iterator vsIter = vsCache_.find(VSID); - VSShader *vs = nullptr; - if (vsIter == vsCache_.end()) { - // Vertex shader not in cache. Let's compile it. - std::string genErrorString; - uint32_t attrMask; - uint64_t uniformMask; - VertexShaderFlags flags; - if (GenerateVertexShader(VSID, codeBuffer_, draw_->GetShaderLanguageDesc(), draw_->GetBugs(), &attrMask, &uniformMask, &flags, &genErrorString)) { - vs = new VSShader(device_, VSID, codeBuffer_, useHWTransform); - } - if (!vs || vs->Failed()) { - if (!vs) { - // TODO: Report this? - ERROR_LOG(Log::G3D, "Shader generation failed, falling back to software transform"); - } else { - ERROR_LOG(Log::G3D, "Shader compilation failed, falling back to software transform"); - } - if (!g_Config.bHideSlowWarnings) { - auto gr = GetI18NCategory(I18NCat::GRAPHICS); - g_OSD.Show(OSDType::MESSAGE_ERROR, gr->T("hardware transform error - falling back to software"), 2.5f); - } - delete vs; - - ComputeVertexShaderID(&VSID, decoder, false, false, weightsAsFloat, useSkinInDecode); - - // TODO: Look for existing shader with the appropriate ID, use that instead of generating a new one - however, need to make sure - // that that shader ID is not used when computing the linked shader ID below, because then IDs won't match - // next time and we'll do this over and over... - - // Can still work with software transform. - uint32_t attrMask; - uint64_t uniformMask; - bool success = GenerateVertexShader(VSID, codeBuffer_, draw_->GetShaderLanguageDesc(), draw_->GetBugs(), &attrMask, &uniformMask, &flags, &genErrorString); - _assert_(success); - vs = new VSShader(device_, VSID, codeBuffer_, false); - } - - vsCache_[VSID] = vs; - } else { - vs = vsIter->second; - } - lastVSID_ = VSID; - - FSCache::iterator fsIter = fsCache_.find(FSID); - PSShader *fs; - if (fsIter == fsCache_.end()) { - // Fragment shader not in cache. Let's compile it. - std::string errorString; - uint64_t uniformMask; - FragmentShaderFlags flags; - bool success = GenerateFragmentShader(FSID, codeBuffer_, draw_->GetShaderLanguageDesc(), draw_->GetBugs(), &uniformMask, &flags, &errorString); - // We're supposed to handle all possible cases. - _assert_(success); - fs = new PSShader(device_, FSID, codeBuffer_); - fsCache_[FSID] = fs; - } else { - fs = fsIter->second; - } - - lastFSID_ = FSID; - - uint64_t dirtyUniforms = gstate_c.GetDirtyUniforms(); - if (dirtyUniforms) { - if (dirtyUniforms & psUniforms) - PSUpdateUniforms(dirtyUniforms); - if (dirtyUniforms & vsUniforms) - VSUpdateUniforms(dirtyUniforms); - gstate_c.CleanUniforms(); - } - - device_->SetPixelShader(fs->shader.Get()); - device_->SetVertexShader(vs->shader.Get()); - - lastPShader_ = fs; - lastVShader_ = vs; - return vs; -} - -std::vector ShaderManagerDX9::DebugGetShaderIDs(DebugShaderType type) { - std::string id; - std::vector ids; - switch (type) { - case SHADER_TYPE_VERTEX: - for (auto iter : vsCache_) { - iter.first.ToString(&id); - ids.push_back(id); - } - break; - case SHADER_TYPE_FRAGMENT: - for (auto iter : fsCache_) { - iter.first.ToString(&id); - ids.push_back(id); - } - break; - } - return ids; -} - -std::string ShaderManagerDX9::DebugGetShaderString(std::string id, DebugShaderType type, DebugShaderStringType stringType) { - ShaderID shaderId; - shaderId.FromString(id); - switch (type) { - case SHADER_TYPE_VERTEX: - { - auto iter = vsCache_.find(VShaderID(shaderId)); - if (iter == vsCache_.end()) { - return ""; - } - return iter->second->GetShaderString(stringType); - } - - case SHADER_TYPE_FRAGMENT: - { - auto iter = fsCache_.find(FShaderID(shaderId)); - if (iter == fsCache_.end()) { - return ""; - } - return iter->second->GetShaderString(stringType); - } - default: - return "N/A"; - } -} diff --git a/GPU/Directx9/ShaderManagerDX9.h b/GPU/Directx9/ShaderManagerDX9.h deleted file mode 100644 index c30ca3c9122c..000000000000 --- a/GPU/Directx9/ShaderManagerDX9.h +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright (c) 2012- PPSSPP Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0 or later versions. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official git repository and contact information can be found at -// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. - -#pragma once - -#include -#include -#include -#include - -#include "Common/CommonTypes.h" -#include "GPU/Common/VertexShaderGenerator.h" -#include "GPU/Common/FragmentShaderGenerator.h" -#include "GPU/Common/ShaderCommon.h" -#include "GPU/Common/ShaderId.h" -#include "Common/Math/lin/matrix4x4.h" - -class PSShader; -class VSShader; - -// Real public interface - -class PSShader { -public: - PSShader(LPDIRECT3DDEVICE9 device, FShaderID id, const char *code); - ~PSShader(); - - const std::string &source() const { return source_; } - - bool Failed() const { return failed_; } - - std::string GetShaderString(DebugShaderStringType type) const; - - Microsoft::WRL::ComPtr shader; - -protected: - std::string source_; - bool failed_ = false; - FShaderID id_; -}; - -class VSShader { -public: - VSShader(LPDIRECT3DDEVICE9 device, VShaderID id, const char *code, bool useHWTransform); - ~VSShader(); - - const std::string &source() const { return source_; } - - bool Failed() const { return failed_; } - bool UseHWTransform() const { return useHWTransform_; } - - std::string GetShaderString(DebugShaderStringType type) const; - - Microsoft::WRL::ComPtr shader; - -protected: - std::string source_; - bool failed_ = false; - bool useHWTransform_; - VShaderID id_; -}; - -class ShaderManagerDX9 : public ShaderManagerCommon { -public: - ShaderManagerDX9(Draw::DrawContext *draw, LPDIRECT3DDEVICE9 device); - ~ShaderManagerDX9(); - - void ClearShaders() override; - VSShader *ApplyShader(bool useHWTransform, bool useHWTessellation, VertexDecoder *decoder, bool weightsAsFloat, bool useSkinInDecode, const ComputedPipelineState &pipelineState); - void DirtyLastShader() override; - - int GetNumVertexShaders() const { return (int)vsCache_.size(); } - int GetNumFragmentShaders() const { return (int)fsCache_.size(); } - - void DeviceLost() override { draw_ = nullptr; } - void DeviceRestore(Draw::DrawContext *draw) override { draw_ = draw; } - - std::vector DebugGetShaderIDs(DebugShaderType type) override; - std::string DebugGetShaderString(std::string id, DebugShaderType type, DebugShaderStringType stringType) override; - -private: - void PSUpdateUniforms(u64 dirtyUniforms); - void VSUpdateUniforms(u64 dirtyUniforms); - inline void PSSetColorUniform3Alpha255(int creg, u32 color, u8 alpha); - inline void PSSetColorUniform3(int creg, u32 color); - inline void PSSetFloat(int creg, float value); - inline void PSSetFloatArray(int creg, const float *value, int count); - - void VSSetMatrix4x3_3(int creg, const float *m4x3); - inline void VSSetColorUniform3(int creg, u32 color); - inline void VSSetColorUniform3ExtraFloat(int creg, u32 color, float extra); - inline void VSSetColorUniform3Alpha(int creg, u32 color, u8 alpha); - void VSSetMatrix(int creg, const float* pMatrix); - void VSSetFloat(int creg, float value); - void VSSetFloatArray(int creg, const float *value, int count); - void VSSetFloat24Uniform3(int creg, const u32 data[3]); - void VSSetFloat24Uniform3Normalized(int creg, const u32 data[3]); - void VSSetFloatUniform4(int creg, const float data[4]); - - void Clear(); - - LPDIRECT3DDEVICE9 device_; - - FShaderID lastFSID_; - VShaderID lastVSID_; - - char *codeBuffer_; - - VSShader *lastVShader_ = nullptr; - PSShader *lastPShader_ = nullptr; - - typedef std::map FSCache; - FSCache fsCache_; - - typedef std::map VSCache; - VSCache vsCache_; -}; diff --git a/GPU/Directx9/StateMappingDX9.cpp b/GPU/Directx9/StateMappingDX9.cpp deleted file mode 100644 index 24866d2d97ca..000000000000 --- a/GPU/Directx9/StateMappingDX9.cpp +++ /dev/null @@ -1,302 +0,0 @@ -// Copyright (c) 2012- PPSSPP Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0 or later versions. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official git repository and contact information can be found at -// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. - -#include "Common/Profiler/Profiler.h" -#include "Common/GPU/D3D9/D3D9ShaderCompiler.h" -#include "Common/GPU/D3D9/D3D9StateCache.h" - -#include "Core/System.h" -#include "Core/Config.h" - -#include "GPU/Math3D.h" -#include "GPU/GPUState.h" -#include "GPU/ge_constants.h" - -#include "GPU/Directx9/GPU_DX9.h" -#include "GPU/Directx9/ShaderManagerDX9.h" -#include "GPU/Directx9/TextureCacheDX9.h" -#include "GPU/Directx9/FramebufferManagerDX9.h" - -static const D3DBLEND dxBlendFactorLookup[(size_t)BlendFactor::COUNT] = { - D3DBLEND_ZERO, - D3DBLEND_ONE, - D3DBLEND_SRCCOLOR, - D3DBLEND_INVSRCCOLOR, - D3DBLEND_DESTCOLOR, - D3DBLEND_INVDESTCOLOR, - D3DBLEND_SRCALPHA, - D3DBLEND_INVSRCALPHA, - D3DBLEND_DESTALPHA, - D3DBLEND_INVDESTALPHA, - D3DBLEND_BLENDFACTOR, - D3DBLEND_INVBLENDFACTOR, - D3DBLEND_BLENDFACTOR, - D3DBLEND_INVBLENDFACTOR, -#if 0 // TODO: Requires D3D9Ex - D3DBLEND_SRCCOLOR2, - D3DBLEND_INVSRCCOLOR2, - D3DBLEND_SRCCOLOR2, - D3DBLEND_INVSRCCOLOR2, -#else - D3DBLEND_FORCE_DWORD, - D3DBLEND_FORCE_DWORD, -#endif - D3DBLEND_FORCE_DWORD, -}; - -static const D3DBLENDOP dxBlendEqLookup[(size_t)BlendEq::COUNT] = { - D3DBLENDOP_ADD, - D3DBLENDOP_SUBTRACT, - D3DBLENDOP_REVSUBTRACT, - D3DBLENDOP_MIN, - D3DBLENDOP_MAX, -}; - -static const D3DCULL cullingMode[] = { - D3DCULL_CW, - D3DCULL_CCW, -}; - -static const D3DCMPFUNC ztests[] = { - D3DCMP_NEVER, D3DCMP_ALWAYS, D3DCMP_EQUAL, D3DCMP_NOTEQUAL, - D3DCMP_LESS, D3DCMP_LESSEQUAL, D3DCMP_GREATER, D3DCMP_GREATEREQUAL, -}; - -static const D3DSTENCILOP stencilOps[] = { - D3DSTENCILOP_KEEP, - D3DSTENCILOP_ZERO, - D3DSTENCILOP_REPLACE, - D3DSTENCILOP_INVERT, - D3DSTENCILOP_INCRSAT, - D3DSTENCILOP_DECRSAT, - D3DSTENCILOP_KEEP, // reserved - D3DSTENCILOP_KEEP, // reserved -}; - -void DrawEngineDX9::ApplyDrawState(int prim) { - if (!gstate_c.IsDirty(DIRTY_BLEND_STATE | DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE)) { - // nothing to do - return; - } - - // At this point, we know if the vertices are full alpha or not. - // TODO: Set the nearest/linear here (since we correctly know if alpha/color tests are needed)? - if (!gstate.isModeClear()) { - textureCache_->ApplyTexture(); - - if (fboTexBindState_ == FBO_TEX_COPY_BIND_TEX) { - // Note that this is positions, not UVs, that we need the copy from. - framebufferManager_->BindFramebufferAsColorTexture(1, framebufferManager_->GetCurrentRenderVFB(), BINDFBCOLOR_MAY_COPY, 0); - // If we are rendering at a higher resolution, linear is probably best for the dest color. - device_->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - device_->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - fboTexBound_ = true; - fboTexBindState_ = FBO_TEX_NONE; - } - - // TODO: Test texture? - } - - bool useBufferedRendering = framebufferManager_->UseBufferedRendering(); - - if (gstate_c.IsDirty(DIRTY_BLEND_STATE)) { - if (gstate.isModeClear()) { - dxstate.blend.disable(); - // Color Mask - u32 mask = 0; - if (gstate.isClearModeColorMask()) { - mask |= 7; - } - if (gstate.isClearModeAlphaMask()) { - mask |= 8; - } - dxstate.colorMask.set(mask); - } else { - pipelineState_.Convert(draw_->GetShaderLanguageDesc().bitwiseOps); - GenericMaskState &maskState = pipelineState_.maskState; - GenericBlendState &blendState = pipelineState_.blendState; - // We ignore the logicState on D3D since there's no support, the emulation of it is blend-and-shader only. - - if (pipelineState_.FramebufferRead()) { - ApplyFramebufferRead(&fboTexBindState_); - // The shader takes over the responsibility for blending, so recompute. - ApplyStencilReplaceAndLogicOpIgnoreBlend(blendState.replaceAlphaWithStencil, blendState); - - if (fboTexBindState_ == FBO_TEX_COPY_BIND_TEX) { - // Note that this is positions, not UVs, that we need the copy from. - framebufferManager_->BindFramebufferAsColorTexture(1, framebufferManager_->GetCurrentRenderVFB(), BINDFBCOLOR_MAY_COPY | BINDFBCOLOR_UNCACHED, Draw::ALL_LAYERS); - // If we are rendering at a higher resolution, linear is probably best for the dest color. - device_->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - device_->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - fboTexBound_ = true; - fboTexBindState_ = FBO_TEX_NONE; - dirtyRequiresRecheck_ |= DIRTY_BLEND_STATE; - gstate_c.Dirty(DIRTY_BLEND_STATE); - } else if (fboTexBindState_ == FBO_TEX_READ_FRAMEBUFFER) { - // Not supported. - fboTexBindState_ = FBO_TEX_NONE; - } - - dirtyRequiresRecheck_ |= DIRTY_FRAGMENTSHADER_STATE; - gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE); - } else { - if (fboTexBound_) { - dirtyRequiresRecheck_ |= DIRTY_FRAGMENTSHADER_STATE; - gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE); - fboTexBound_ = false; - } - } - - if (blendState.blendEnabled) { - dxstate.blend.enable(); - dxstate.blendSeparate.enable(); - dxstate.blendEquation.set(dxBlendEqLookup[(size_t)blendState.eqColor], dxBlendEqLookup[(size_t)blendState.eqAlpha]); - dxstate.blendFunc.set( - dxBlendFactorLookup[(size_t)blendState.srcColor], dxBlendFactorLookup[(size_t)blendState.dstColor], - dxBlendFactorLookup[(size_t)blendState.srcAlpha], dxBlendFactorLookup[(size_t)blendState.dstAlpha]); - if (blendState.dirtyShaderBlendFixValues) { - dirtyRequiresRecheck_ |= DIRTY_SHADERBLEND; - gstate_c.Dirty(DIRTY_SHADERBLEND); - } - if (blendState.useBlendColor) { - dxstate.blendColor.setDWORD(blendState.blendColor); - } - } else { - dxstate.blend.disable(); - } - - dxstate.colorMask.set(maskState.channelMask); - } - } - - if (gstate_c.IsDirty(DIRTY_RASTER_STATE)) { - bool wantCull = !gstate.isModeClear() && prim != GE_PRIM_RECTANGLES && prim > GE_PRIM_LINE_STRIP && gstate.isCullEnabled(); - if (wantCull) { - if (gstate.getCullMode() == 1) { - dxstate.cullMode.set(D3DCULL_CCW); - } else { - dxstate.cullMode.set(D3DCULL_CW); - } - } else { - dxstate.cullMode.set(D3DCULL_NONE); - } - if (gstate.isModeClear()) { - // Well, probably doesn't matter... - dxstate.shadeMode.set(D3DSHADE_GOURAUD); - } else { - dxstate.shadeMode.set(gstate.getShadeMode() == GE_SHADE_GOURAUD ? D3DSHADE_GOURAUD : D3DSHADE_FLAT); - } - - // We use fixed-function user clipping on D3D9, where available, for negative Z clipping. - if (draw_->GetDeviceCaps().clipPlanesSupported >= 1) { - bool wantClip = !gstate.isModeThrough() && gstate_c.submitType == SubmitType::DRAW; - dxstate.clipPlaneEnable.set(wantClip ? 1 : 0); - } - } - - if (gstate_c.IsDirty(DIRTY_DEPTHSTENCIL_STATE)) { - GenericStencilFuncState stencilState; - ConvertStencilFuncState(stencilState); - - // Set Stencil/Depth - if (gstate.isModeClear()) { - // Depth Test - dxstate.depthTest.enable(); - dxstate.depthFunc.set(D3DCMP_ALWAYS); - dxstate.depthWrite.set(gstate.isClearModeDepthMask()); - - // Stencil Test - bool alphaMask = gstate.isClearModeAlphaMask(); - if (alphaMask) { - dxstate.stencilTest.enable(); - dxstate.stencilOp.set(D3DSTENCILOP_REPLACE, D3DSTENCILOP_REPLACE, D3DSTENCILOP_REPLACE); - dxstate.stencilFunc.set(D3DCMP_ALWAYS); - dxstate.stencilRef.set(0xFF); - dxstate.stencilCompareMask.set(0xFF); - dxstate.stencilWriteMask.set(stencilState.writeMask); - } else { - dxstate.stencilTest.disable(); - } - } else { - // Depth Test - if (!IsDepthTestEffectivelyDisabled()) { - dxstate.depthTest.enable(); - dxstate.depthFunc.set(ztests[gstate.getDepthTestFunction()]); - dxstate.depthWrite.set(gstate.isDepthWriteEnabled()); - UpdateEverUsedEqualDepth(gstate.getDepthTestFunction()); - } else { - dxstate.depthTest.disable(); - } - - // Stencil Test - if (stencilState.enabled) { - dxstate.stencilTest.enable(); - dxstate.stencilFunc.set(ztests[stencilState.testFunc]); - dxstate.stencilRef.set(stencilState.testRef); - dxstate.stencilCompareMask.set(stencilState.testMask); - dxstate.stencilOp.set(stencilOps[stencilState.sFail], stencilOps[stencilState.zFail], stencilOps[stencilState.zPass]); - dxstate.stencilWriteMask.set(stencilState.writeMask); - - // Nasty special case for Spongebob and similar where it tries to write zeros to alpha/stencil during - // depth-fail. We can't write to alpha then because the pixel is killed. However, we can invert the depth - // test and modify the alpha function... - if (SpongebobDepthInverseConditions(stencilState)) { - dxstate.blend.set(true); - dxstate.blendEquation.set(D3DBLENDOP_ADD, D3DBLENDOP_ADD); - dxstate.blendFunc.set(D3DBLEND_ZERO, D3DBLEND_ZERO, D3DBLEND_ZERO, D3DBLEND_ZERO); - dxstate.colorMask.set(8); - - dxstate.depthFunc.set(D3DCMP_LESS); - dxstate.stencilFunc.set(D3DCMP_ALWAYS); - // Invert - dxstate.stencilOp.set(D3DSTENCILOP_ZERO, D3DSTENCILOP_KEEP, D3DSTENCILOP_ZERO); - - dirtyRequiresRecheck_ |= DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE; - gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE); - } - } else { - dxstate.stencilTest.disable(); - } - } - } - - if (gstate_c.IsDirty(DIRTY_VIEWPORTSCISSOR_STATE)) { - ViewportAndScissor vpAndScissor; - ConvertViewportAndScissor(useBufferedRendering, - framebufferManager_->GetRenderWidth(), framebufferManager_->GetRenderHeight(), - framebufferManager_->GetTargetBufferWidth(), framebufferManager_->GetTargetBufferHeight(), - vpAndScissor); - UpdateCachedViewportState(vpAndScissor); - - dxstate.scissorTest.enable(); - dxstate.scissorRect.set(vpAndScissor.scissorX, vpAndScissor.scissorY, vpAndScissor.scissorX + vpAndScissor.scissorW, vpAndScissor.scissorY + vpAndScissor.scissorH); - - float depthMin = vpAndScissor.depthRangeMin; - float depthMax = vpAndScissor.depthRangeMax; - - dxstate.viewport.set(vpAndScissor.viewportX, vpAndScissor.viewportY, vpAndScissor.viewportW, vpAndScissor.viewportH, depthMin, depthMax); - } - - gstate_c.Clean(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_BLEND_STATE); - gstate_c.Dirty(dirtyRequiresRecheck_); - dirtyRequiresRecheck_ = 0; -} - -void DrawEngineDX9::ApplyDrawStateLate() { - // At this point, we know if the vertices are full alpha or not. - // TODO: Set the nearest/linear here (since we correctly know if alpha/color tests are needed)? -} diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp deleted file mode 100644 index 69a2412546e5..000000000000 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ /dev/null @@ -1,442 +0,0 @@ -// Copyright (c) 2012- PPSSPP Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0 or later versions. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official git repository and contact information can be found at -// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. - -#include -#include -#include - -#include "Common/TimeUtil.h" -#include "Core/MemMap.h" -#include "GPU/ge_constants.h" - -#include "GPU/GPUState.h" -#include "GPU/Directx9/TextureCacheDX9.h" -#include "GPU/Directx9/FramebufferManagerDX9.h" -#include "GPU/Directx9/ShaderManagerDX9.h" -#include "Common/GPU/D3D9/D3D9StateCache.h" -#include "GPU/Common/TextureShaderCommon.h" -#include "GPU/Common/FramebufferManagerCommon.h" -#include "GPU/Common/TextureDecoder.h" -#include "Core/Config.h" - -#include "ext/xxhash.h" -#include "Common/Math/math_util.h" - -// NOTE: In the D3D backends, we flip R and B in the shaders, so while these look wrong, they're OK. - -using Microsoft::WRL::ComPtr; - -Draw::DataFormat FromD3D9Format(u32 fmt) { - switch (fmt) { - case D3DFMT_A4R4G4B4: return Draw::DataFormat::B4G4R4A4_UNORM_PACK16; - case D3DFMT_A1R5G5B5: return Draw::DataFormat::A1R5G5B5_UNORM_PACK16; - case D3DFMT_R5G6B5: return Draw::DataFormat::R5G6B5_UNORM_PACK16; - case D3DFMT_A8: return Draw::DataFormat::R8_UNORM; - case D3DFMT_A8R8G8B8: default: return Draw::DataFormat::R8G8B8A8_UNORM; - } -} - -D3DFORMAT ToD3D9Format(Draw::DataFormat fmt) { - switch (fmt) { - case Draw::DataFormat::BC1_RGBA_UNORM_BLOCK: return D3DFMT_DXT1; - case Draw::DataFormat::BC2_UNORM_BLOCK: return D3DFMT_DXT3; - case Draw::DataFormat::BC3_UNORM_BLOCK: return D3DFMT_DXT5; - case Draw::DataFormat::R8G8B8A8_UNORM: return D3DFMT_A8R8G8B8; - default: _dbg_assert_(false); return D3DFMT_A8R8G8B8; - } -} - -#define INVALID_TEX (LPDIRECT3DTEXTURE9)(-1) - -static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { - { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, - { 0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, - D3DDECL_END() -}; - -TextureCacheDX9::TextureCacheDX9(Draw::DrawContext *draw, Draw2D *draw2D) - : TextureCacheCommon(draw, draw2D) { - lastBoundTexture = INVALID_TEX; - device_ = (LPDIRECT3DDEVICE9)draw->GetNativeObject(Draw::NativeObject::DEVICE); - deviceEx_ = (LPDIRECT3DDEVICE9EX)draw->GetNativeObject(Draw::NativeObject::DEVICE_EX); - D3DCAPS9 pCaps; - ZeroMemory(&pCaps, sizeof(pCaps)); - HRESULT result = 0; - if (deviceEx_) { - result = deviceEx_->GetDeviceCaps(&pCaps); - } else { - result = device_->GetDeviceCaps(&pCaps); - } - if (FAILED(result)) { - WARN_LOG(Log::G3D, "Failed to get the device caps!"); - maxAnisotropyLevel = 16; - } else { - maxAnisotropyLevel = pCaps.MaxAnisotropy; - } - - nextTexture_ = nullptr; - device_->CreateVertexDeclaration(g_FramebufferVertexElements, &pFramebufferVertexDecl); -} - -TextureCacheDX9::~TextureCacheDX9() { - Clear(true); -} - -void TextureCacheDX9::SetFramebufferManager(FramebufferManagerDX9 *fbManager) { - framebufferManager_ = fbManager; -} - -void TextureCacheDX9::ReleaseTexture(TexCacheEntry *entry, bool delete_them) { - LPDIRECT3DBASETEXTURE9 &texture = DxTex(entry); - if (texture) { - texture->Release(); - texture = nullptr; - } -} - -void TextureCacheDX9::ForgetLastTexture() { - lastBoundTexture = INVALID_TEX; -} - -static D3DFORMAT getClutDestFormat(GEPaletteFormat format) { - switch (format) { - case GE_CMODE_16BIT_ABGR4444: - return D3DFMT_A4R4G4B4; - case GE_CMODE_16BIT_ABGR5551: - return D3DFMT_A1R5G5B5; - case GE_CMODE_16BIT_BGR5650: - return D3DFMT_R5G6B5; - case GE_CMODE_32BIT_ABGR8888: - return D3DFMT_A8R8G8B8; - } - // Should never be here ! - return D3DFMT_A8R8G8B8; -} - -void TextureCacheDX9::ApplySamplingParams(const SamplerCacheKey &key) { - D3DTEXTUREFILTERTYPE minFilt = (false ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR); - dxstate.texMinFilter.set(key.minFilt ? minFilt : D3DTEXF_POINT); - dxstate.texMipFilter.set(key.mipFilt ? D3DTEXF_LINEAR : D3DTEXF_POINT); - dxstate.texMagFilter.set(key.magFilt ? D3DTEXF_LINEAR : D3DTEXF_POINT); - - // DX9 mip levels are .. odd. The "max level" sets the LARGEST mip to use. - // We can enforce only the top mip level by setting a massive negative lod bias. - - if (!key.mipEnable) { - dxstate.texMaxMipLevel.set(0); - dxstate.texMipLodBias.set(-100.0f); - } else { - dxstate.texMipLodBias.set((float)key.lodBias / 256.0f); - dxstate.texMaxMipLevel.set(key.minLevel / 256); - } - - dxstate.texAddressU.set(key.sClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP); - dxstate.texAddressV.set(key.tClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP); -} - -void TextureCacheDX9::StartFrame() { - TextureCacheCommon::StartFrame(); - - if (gstate_c.Use(GPU_USE_ANISOTROPY)) { - // Just take the opportunity to set the global aniso level here, once per frame. - DWORD aniso = 1 << g_Config.iAnisotropyLevel; - DWORD anisotropyLevel = aniso > maxAnisotropyLevel ? maxAnisotropyLevel : aniso; - device_->SetSamplerState(0, D3DSAMP_MAXANISOTROPY, anisotropyLevel); - } -} - -void TextureCacheDX9::UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple) { - const u32 clutBaseBytes = clutBase * (clutFormat == GE_CMODE_32BIT_ABGR8888 ? sizeof(u32) : sizeof(u16)); - // Technically, these extra bytes weren't loaded, but hopefully it was loaded earlier. - // If not, we're going to hash random data, which hopefully doesn't cause a performance issue. - // - // TODO: Actually, this seems like a hack. The game can upload part of a CLUT and reference other data. - // clutTotalBytes_ is the last amount uploaded. We should hash clutMaxBytes_, but this will often hash - // unrelated old entries for small palettes. - // Adding clutBaseBytes may just be mitigating this for some usage patterns. - const u32 clutExtendedBytes = std::min(clutTotalBytes_ + clutBaseBytes, clutMaxBytes_); - - if (replacer_.Enabled()) - clutHash_ = XXH32((const char *)clutBufRaw_, clutExtendedBytes, 0xC0108888); - else - clutHash_ = XXH3_64bits((const char *)clutBufRaw_, clutExtendedBytes) & 0xFFFFFFFF; - clutBuf_ = clutBufRaw_; - - // Special optimization: fonts typically draw clut4 with just alpha values in a single color. - clutAlphaLinear_ = false; - clutAlphaLinearColor_ = 0; - if (clutFormat == GE_CMODE_16BIT_ABGR4444 && clutIndexIsSimple) { - const u16_le *clut = GetCurrentClut(); - clutAlphaLinear_ = true; - clutAlphaLinearColor_ = clut[15] & 0x0FFF; - for (int i = 0; i < 16; ++i) { - u16 step = clutAlphaLinearColor_ | (i << 12); - if (clut[i] != step) { - clutAlphaLinear_ = false; - break; - } - } - } - - clutLastFormat_ = gstate.clutformat; -} - -void TextureCacheDX9::BindTexture(TexCacheEntry *entry) { - if (!entry) { - device_->SetTexture(0, nullptr); - return; - } - IDirect3DBaseTexture9 *texture = DxTex(entry); - if (texture != lastBoundTexture) { - device_->SetTexture(0, texture); - lastBoundTexture = texture; - } - int maxLevel = (entry->status & TexCacheEntry::STATUS_NO_MIPS) ? 0 : entry->maxLevel; - SamplerCacheKey samplerKey = GetSamplingParams(maxLevel, entry); - ApplySamplingParams(samplerKey); -} - -void TextureCacheDX9::Unbind() { - device_->SetTexture(0, nullptr); - ForgetLastTexture(); -} - -void TextureCacheDX9::BindAsClutTexture(Draw::Texture *tex, bool smooth) { - LPDIRECT3DBASETEXTURE9 clutTexture = (LPDIRECT3DBASETEXTURE9)draw_->GetNativeObject(Draw::NativeObject::TEXTURE_VIEW, tex); - device_->SetTexture(1, clutTexture); - device_->SetSamplerState(1, D3DSAMP_MINFILTER, smooth ? D3DTEXF_LINEAR : D3DTEXF_POINT); - device_->SetSamplerState(1, D3DSAMP_MAGFILTER, smooth ? D3DTEXF_LINEAR : D3DTEXF_POINT); - device_->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_NONE); -} - -void TextureCacheDX9::BuildTexture(TexCacheEntry *const entry) { - BuildTexturePlan plan; - if (!PrepareBuildTexture(plan, entry)) { - // We're screwed? - return; - } - - D3DFORMAT dstFmt = GetDestFormat(GETextureFormat(entry->format), gstate.getClutPaletteFormat()); - if (plan.doReplace) { - dstFmt = ToD3D9Format(plan.replaced->Format()); - } else if (plan.scaleFactor > 1 || plan.saveTexture) { - dstFmt = D3DFMT_A8R8G8B8; - } else if (plan.decodeToClut8) { - dstFmt = D3DFMT_A8; - } - - int levels; - - LPDIRECT3DBASETEXTURE9 &texture = DxTex(entry); - D3DPOOL pool = D3DPOOL_DEFAULT; - int usage = D3DUSAGE_DYNAMIC; - - int tw; - int th; - plan.GetMipSize(0, &tw, &th); - - HRESULT hr; - if (plan.depth == 1) { - // We don't yet have mip generation, so clamp the number of levels to the ones we can load directly. - levels = std::min(plan.levelsToCreate, plan.levelsToLoad); - - LPDIRECT3DTEXTURE9 tex; - hr = device_->CreateTexture(tw, th, levels, usage, dstFmt, pool, &tex, nullptr); - texture = tex; - } else { - LPDIRECT3DVOLUMETEXTURE9 tex; - hr = device_->CreateVolumeTexture(tw, th, plan.depth, 1, usage, dstFmt, pool, &tex, nullptr); - texture = tex; - - levels = 1; - } - - if (FAILED(hr)) { - INFO_LOG(Log::G3D, "Failed to create D3D texture: %dx%d", tw, th); - ReleaseTexture(entry, true); - return; - } - - if (!texture) { - // What to do here? - return; - } - - if (plan.depth == 1) { - // Regular loop. - for (int i = 0; i < levels; i++) { - int dstLevel = i; - HRESULT result; - uint32_t lockFlag = dstLevel == 0 ? D3DLOCK_DISCARD : 0; // Can only discard the top level - D3DLOCKED_RECT rect{}; - - result = ((LPDIRECT3DTEXTURE9)texture)->LockRect(dstLevel, &rect, NULL, lockFlag); - if (FAILED(result)) { - ERROR_LOG(Log::G3D, "Failed to lock D3D 2D texture at level %d: %dx%d", i, plan.w, plan.h); - return; - } - uint8_t *data = (uint8_t *)rect.pBits; - int stride = rect.Pitch; - LoadTextureLevel(*entry, data, 0, stride, plan, (i == 0) ? plan.baseLevelSrc : i, FromD3D9Format(dstFmt), TexDecodeFlags{}); - ((LPDIRECT3DTEXTURE9)texture)->UnlockRect(dstLevel); - } - } else { - // 3D loop. - D3DLOCKED_BOX box; - HRESULT result = ((LPDIRECT3DVOLUMETEXTURE9)texture)->LockBox(0, &box, nullptr, D3DLOCK_DISCARD); - if (FAILED(result)) { - ERROR_LOG(Log::G3D, "Failed to lock D3D 2D texture: %dx%dx%d", plan.w, plan.h, plan.depth); - return; - } - - uint8_t *data = (uint8_t *)box.pBits; - int stride = box.RowPitch; - for (int i = 0; i < plan.depth; i++) { - LoadTextureLevel(*entry, data, 0, stride, plan, (i == 0) ? plan.baseLevelSrc : i, FromD3D9Format(dstFmt), TexDecodeFlags{}); - data += box.SlicePitch; - } - ((LPDIRECT3DVOLUMETEXTURE9)texture)->UnlockBox(0); - } - - // Signal that we support depth textures so use it as one. - if (plan.depth > 1) { - entry->status |= TexCacheEntry::STATUS_3D; - } - - if (plan.doReplace) { - entry->SetAlphaStatus(TexCacheEntry::TexStatus(plan.replaced->AlphaStatus())); - - if (!Draw::DataFormatIsBlockCompressed(plan.replaced->Format(), nullptr)) { - entry->status |= TexCacheEntry::STATUS_BGRA; - } - } else { - entry->status |= TexCacheEntry::STATUS_BGRA; - } -} - -D3DFORMAT TextureCacheDX9::GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const { - switch (format) { - case GE_TFMT_CLUT4: - case GE_TFMT_CLUT8: - case GE_TFMT_CLUT16: - case GE_TFMT_CLUT32: - return getClutDestFormat(clutFormat); - case GE_TFMT_4444: - return D3DFMT_A4R4G4B4; - case GE_TFMT_5551: - return D3DFMT_A1R5G5B5; - case GE_TFMT_5650: - return D3DFMT_R5G6B5; - case GE_TFMT_8888: - case GE_TFMT_DXT1: - case GE_TFMT_DXT3: - case GE_TFMT_DXT5: - default: - return D3DFMT_A8R8G8B8; - } -} - -bool TextureCacheDX9::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level, bool *isFramebuffer) { - SetTexture(); - if (!nextTexture_) { - return GetCurrentFramebufferTextureDebug(buffer, isFramebuffer); - } - - ApplyTexture(); - - ComPtr baseTex; - ComPtr tex; - ComPtr offscreen; - HRESULT hr; - - bool success = false; - hr = device_->GetTexture(0, &baseTex); - if (SUCCEEDED(hr) && baseTex != NULL) { - hr = baseTex.As(&tex); - if (SUCCEEDED(hr)) { - D3DSURFACE_DESC desc; - D3DLOCKED_RECT locked; - tex->GetLevelDesc(level, &desc); - RECT rect = { 0, 0, (LONG)desc.Width, (LONG)desc.Height }; - hr = tex->LockRect(level, &locked, &rect, D3DLOCK_READONLY); - - // If it fails, this means it's a render-to-texture, so we have to get creative. - if (FAILED(hr)) { - ComPtr renderTarget; - hr = tex->GetSurfaceLevel(level, &renderTarget); - if (renderTarget && SUCCEEDED(hr)) { - hr = device_->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &offscreen, NULL); - if (SUCCEEDED(hr)) { - hr = device_->GetRenderTargetData(renderTarget.Get(), offscreen.Get()); - if (SUCCEEDED(hr)) { - hr = offscreen->LockRect(&locked, &rect, D3DLOCK_READONLY); - } - } - } - *isFramebuffer = true; - } else { - *isFramebuffer = false; - } - - if (SUCCEEDED(hr)) { - GPUDebugBufferFormat fmt; - int pixelSize; - switch (desc.Format) { - case D3DFMT_A1R5G5B5: - fmt = gstate_c.bgraTexture ? GPU_DBG_FORMAT_5551 : GPU_DBG_FORMAT_5551_BGRA; - pixelSize = 2; - break; - case D3DFMT_A4R4G4B4: - fmt = gstate_c.bgraTexture ? GPU_DBG_FORMAT_4444 : GPU_DBG_FORMAT_4444_BGRA; - pixelSize = 2; - break; - case D3DFMT_R5G6B5: - fmt = gstate_c.bgraTexture ? GPU_DBG_FORMAT_565 : GPU_DBG_FORMAT_565_BGRA; - pixelSize = 2; - break; - case D3DFMT_A8R8G8B8: - fmt = gstate_c.bgraTexture ? GPU_DBG_FORMAT_8888 : GPU_DBG_FORMAT_8888_BGRA; - pixelSize = 4; - break; - default: - fmt = GPU_DBG_FORMAT_INVALID; - break; - } - - if (fmt != GPU_DBG_FORMAT_INVALID) { - buffer.Allocate(locked.Pitch / pixelSize, desc.Height, fmt, false); - memcpy(buffer.GetData(), locked.pBits, locked.Pitch * desc.Height); - success = true; - } else { - success = false; - } - if (offscreen) { - offscreen->UnlockRect(); - } else { - tex->UnlockRect(level); - } - } - } - } - - return success; -} - -void *TextureCacheDX9::GetNativeTextureView(const TexCacheEntry *entry, bool flat) const { - LPDIRECT3DBASETEXTURE9 tex = DxTex(entry); - return (void *)tex; -} diff --git a/GPU/Directx9/TextureCacheDX9.h b/GPU/Directx9/TextureCacheDX9.h deleted file mode 100644 index 31471fadff18..000000000000 --- a/GPU/Directx9/TextureCacheDX9.h +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) 2012- PPSSPP Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0 or later versions. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official git repository and contact information can be found at -// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. - -#pragma once - -#include -#include - -#include "GPU/GPU.h" -#include "GPU/GPUCommon.h" -#include "GPU/Common/TextureCacheCommon.h" - -struct VirtualFramebuffer; -class TextureShaderCache; - -class FramebufferManagerDX9; -class ShaderManagerDX9; - -class TextureCacheDX9 : public TextureCacheCommon { -public: - TextureCacheDX9(Draw::DrawContext *draw, Draw2D *draw2D); - ~TextureCacheDX9(); - - void StartFrame() override; - - void SetFramebufferManager(FramebufferManagerDX9 *fbManager); - - void ForgetLastTexture() override; - - bool GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level, bool *isFramebuffer) override; - - void DeviceLost() override { draw_ = nullptr; } - void DeviceRestore(Draw::DrawContext *draw) override { draw_ = draw; } - -protected: - void BindTexture(TexCacheEntry *entry) override; - void Unbind() override; - void ReleaseTexture(TexCacheEntry *entry, bool delete_them) override; - void BindAsClutTexture(Draw::Texture *tex, bool smooth) override; - void *GetNativeTextureView(const TexCacheEntry *entry, bool flat) const override; - -private: - void ApplySamplingParams(const SamplerCacheKey &key) override; - - D3DFORMAT GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const; - void UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple) override; - - void BuildTexture(TexCacheEntry *const entry) override; - - static LPDIRECT3DBASETEXTURE9 &DxTex(const TexCacheEntry *entry) { - return *(LPDIRECT3DBASETEXTURE9 *)&entry->texturePtr; - } - - Microsoft::WRL::ComPtr device_; - Microsoft::WRL::ComPtr deviceEx_; - - Microsoft::WRL::ComPtr pFramebufferVertexDecl; - - IDirect3DBaseTexture9 *lastBoundTexture = nullptr; - float maxAnisotropyLevel; - - FramebufferManagerDX9 *framebufferManagerDX9_; -}; - -static D3DFORMAT getClutDestFormat(GEPaletteFormat format); diff --git a/GPU/GPU.cpp b/GPU/GPU.cpp index 742d3705bf0e..a953a16e7b57 100644 --- a/GPU/GPU.cpp +++ b/GPU/GPU.cpp @@ -31,10 +31,6 @@ #include "GPU/Vulkan/GPU_Vulkan.h" #include "GPU/Software/SoftGpu.h" -#if PPSSPP_API(D3D9) -#include "GPU/Directx9/GPU_DX9.h" -#endif - #if PPSSPP_API(D3D11) #include "GPU/D3D11/GPU_D3D11.h" #endif @@ -86,13 +82,6 @@ bool GPU_Init(GraphicsContext *ctx, Draw::DrawContext *draw) { case GPUCORE_SOFTWARE: SetGPU(new SoftGPU(ctx, draw)); break; - case GPUCORE_DIRECTX9: -#if PPSSPP_API(D3D9) - SetGPU(new GPU_DX9(ctx, draw)); - break; -#else - return false; -#endif case GPUCORE_DIRECTX11: #if PPSSPP_API(D3D11) SetGPU(new GPU_D3D11(ctx, draw)); diff --git a/GPU/GPU.vcxproj b/GPU/GPU.vcxproj index bf0991683cee..61f4a8c03184 100644 --- a/GPU/GPU.vcxproj +++ b/GPU/GPU.vcxproj @@ -389,11 +389,6 @@ - - - - - @@ -538,12 +533,6 @@ - - - - - - @@ -693,4 +682,4 @@ - + \ No newline at end of file diff --git a/GPU/GPU.vcxproj.filters b/GPU/GPU.vcxproj.filters index 1529b974c13f..924eb98457de 100644 --- a/GPU/GPU.vcxproj.filters +++ b/GPU/GPU.vcxproj.filters @@ -10,9 +10,6 @@ {21783292-4dd7-447b-af93-356cd2eaa4d6} - - {88629970-4774-4122-b031-2128244b795c} - {0cbddc00-4aa3-41d0-bed2-a454d37f838e} @@ -60,18 +57,6 @@ GLES - - DirectX9 - - - DirectX9 - - - DirectX9 - - - DirectX9 - Common @@ -225,9 +210,6 @@ Common - - DirectX9 - Common @@ -314,21 +296,6 @@ GLES - - DirectX9 - - - DirectX9 - - - DirectX9 - - - DirectX9 - - - DirectX9 - Common @@ -491,9 +458,6 @@ Common - - DirectX9 - Common diff --git a/GPU/Software/SoftGpu.cpp b/GPU/Software/SoftGpu.cpp index fc6c1bb036e5..48c4fed21339 100644 --- a/GPU/Software/SoftGpu.cpp +++ b/GPU/Software/SoftGpu.cpp @@ -634,7 +634,6 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { case GPUBackend::OPENGL: outputFlags |= OutputFlags::BACKBUFFER_FLIPPED; break; - case GPUBackend::DIRECT3D9: case GPUBackend::DIRECT3D11: outputFlags |= OutputFlags::POSITION_FLIPPED; break; diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index 536d97f3a6df..1be92a7d0fb2 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -539,11 +539,6 @@ void SystemInfoScreen::CreateTabs() { if (GetGPUBackend() != GPUBackend::VULKAN) { gpuInfo->Add(new InfoItem(si->T("Driver Version"), System_GetProperty(SYSPROP_GPUDRIVER_VERSION))); } -#if !PPSSPP_PLATFORM(UWP) - if (GetGPUBackend() == GPUBackend::DIRECT3D9) { - gpuInfo->Add(new InfoItem(si->T("D3DCompiler Version"), StringFromFormat("%d", GetD3DCompilerVersion()))); - } -#endif #endif if (GetGPUBackend() == GPUBackend::OPENGL) { gpuInfo->Add(new InfoItem(si->T("Core Context"), gl_extensions.IsCoreContext ? di->T("Active") : di->T("Inactive"))); @@ -1178,14 +1173,13 @@ void TouchTestScreen::CreateViews() { root_->Add(theTwo); #if !PPSSPP_PLATFORM(UWP) - static const char *renderingBackend[] = { "OpenGL", "Direct3D 9", "Direct3D 11", "Vulkan" }; + static const char *renderingBackend[] = { "OpenGL", "(n/a)", "Direct3D 11", "Vulkan" }; PopupMultiChoice *renderingBackendChoice = root_->Add(new PopupMultiChoice(&g_Config.iGPUBackend, gr->T("Backend"), renderingBackend, (int)GPUBackend::OPENGL, ARRAY_SIZE(renderingBackend), I18NCat::GRAPHICS, screenManager())); renderingBackendChoice->OnChoice.Handle(this, &TouchTestScreen::OnRenderingBackend); if (!g_Config.IsBackendEnabled(GPUBackend::OPENGL)) renderingBackendChoice->HideChoice((int)GPUBackend::OPENGL); - if (!g_Config.IsBackendEnabled(GPUBackend::DIRECT3D9)) - renderingBackendChoice->HideChoice((int)GPUBackend::DIRECT3D9); + renderingBackendChoice->HideChoice(1); // previously D3D9 if (!g_Config.IsBackendEnabled(GPUBackend::DIRECT3D11)) renderingBackendChoice->HideChoice((int)GPUBackend::DIRECT3D11); if (!g_Config.IsBackendEnabled(GPUBackend::VULKAN)) diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index ca90bd13c15f..50641b26886c 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -322,9 +322,6 @@ void EmuScreen::bootGame(const Path &filename) { coreParam.gpuCore = GPUCORE_GLES; break; #endif - case GPUBackend::DIRECT3D9: - coreParam.gpuCore = GPUCORE_DIRECTX9; - break; case GPUBackend::VULKAN: coreParam.gpuCore = GPUCORE_VULKAN; break; diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 107c0ec8d96b..fcc08e803d1f 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -291,15 +291,11 @@ void GameSettingsScreen::CreateGraphicsSettings(UI::ViewGroup *graphicsSettings) #if !PPSSPP_PLATFORM(UWP) static const char *renderingBackend[] = { "OpenGL", "Direct3D 9", "Direct3D 11", "Vulkan" }; PopupMultiChoice *renderingBackendChoice = graphicsSettings->Add(new PopupMultiChoice(&g_Config.iGPUBackend, gr->T("Backend"), renderingBackend, (int)GPUBackend::OPENGL, ARRAY_SIZE(renderingBackend), I18NCat::GRAPHICS, screenManager())); - if (g_Config.iGPUBackend != (int)GPUBackend::DIRECT3D9 && !draw->GetDeviceCaps().supportsD3D9) { - renderingBackendChoice->HideChoice(1); - } + renderingBackendChoice->HideChoice(1); renderingBackendChoice->OnChoice.Handle(this, &GameSettingsScreen::OnRenderingBackend); if (!g_Config.IsBackendEnabled(GPUBackend::OPENGL)) renderingBackendChoice->HideChoice((int)GPUBackend::OPENGL); - if (!g_Config.IsBackendEnabled(GPUBackend::DIRECT3D9)) - renderingBackendChoice->HideChoice((int)GPUBackend::DIRECT3D9); if (!g_Config.IsBackendEnabled(GPUBackend::DIRECT3D11)) renderingBackendChoice->HideChoice((int)GPUBackend::DIRECT3D11); if (!g_Config.IsBackendEnabled(GPUBackend::VULKAN)) diff --git a/Windows/EmuThread.cpp b/Windows/EmuThread.cpp index 4b84983af567..09e75f673860 100644 --- a/Windows/EmuThread.cpp +++ b/Windows/EmuThread.cpp @@ -30,7 +30,6 @@ #include "Windows/GPU/WindowsGLContext.h" #endif #include "Windows/GPU/WindowsVulkanContext.h" -#include "Windows/GPU/D3D9Context.h" #include "Windows/GPU/D3D11Context.h" enum class EmuThreadState { @@ -173,9 +172,6 @@ bool CreateGraphicsBackend(std::string *error_message, GraphicsContext **ctx) { graphicsContext = new WindowsGLContext(); break; #endif - case (int)GPUBackend::DIRECT3D9: - graphicsContext = new D3D9Context(); - break; case (int)GPUBackend::DIRECT3D11: graphicsContext = new D3D11Context(); break; @@ -267,19 +263,15 @@ void MainThreadFunc() { const char *defaultErrorOpenGL = "Failed initializing graphics. Try upgrading your graphics drivers.\n\nWould you like to try switching to DirectX 9?\n\nError message:"; const char *defaultErrorDirect3D9 = "Failed initializing graphics. Try upgrading your graphics drivers and directx 9 runtime.\n\nWould you like to try switching to OpenGL?\n\nError message:"; std::string_view genericError; - GPUBackend nextBackend = GPUBackend::DIRECT3D9; + GPUBackend nextBackend = GPUBackend::VULKAN; switch (g_Config.iGPUBackend) { - case (int)GPUBackend::DIRECT3D9: - nextBackend = GPUBackend::OPENGL; - genericError = err->T("GenericDirect3D9Error", defaultErrorDirect3D9); - break; case (int)GPUBackend::VULKAN: nextBackend = GPUBackend::OPENGL; genericError = err->T("GenericVulkanError", defaultErrorVulkan); break; case (int)GPUBackend::OPENGL: default: - nextBackend = GPUBackend::DIRECT3D9; + nextBackend = GPUBackend::DIRECT3D11; genericError = err->T("GenericOpenGLError", defaultErrorOpenGL); break; } @@ -296,11 +288,6 @@ void MainThreadFunc() { g_Config.Save("save_graphics_fallback"); W32Util::ExitAndRestart(); - } else { - if (g_Config.iGPUBackend == (int)GPUBackend::DIRECT3D9) { - // Allow the user to download the DX9 runtime. - System_LaunchUrl(LaunchUrlType::BROWSER_URL, "https://www.microsoft.com/en-us/download/details.aspx?id=34429"); - } } // No safe way out without graphics. diff --git a/Windows/GPU/D3D11Context.cpp b/Windows/GPU/D3D11Context.cpp index 95be2cab218c..3b51208ef869 100644 --- a/Windows/GPU/D3D11Context.cpp +++ b/Windows/GPU/D3D11Context.cpp @@ -104,13 +104,13 @@ bool D3D11Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) { } if (FAILED(hr)) { - const char *defaultError = "Your GPU does not appear to support Direct3D 11.\n\nWould you like to try again using Direct3D 9 instead?"; + const char *defaultError = "Your GPU does not appear to support Direct3D 11.\n\nWould you like to try again using OpenGL instead?"; auto err = GetI18NCategory(I18NCat::ERRORS); std::wstring error; if (result == LoadD3D11Error::FAIL_NO_COMPILER) { - error = ConvertUTF8ToWString(err->T("D3D11CompilerMissing", "D3DCompiler_47.dll not found. Please install. Or press Yes to try again using Direct3D9 instead.")); + error = ConvertUTF8ToWString(err->T("D3D11CompilerMissing", "D3DCompiler_47.dll not found. Please install. Or press Yes to try again using OpenGL instead.")); } else if (result == LoadD3D11Error::FAIL_NO_D3D11) { error = ConvertUTF8ToWString(err->T("D3D11Missing", "Your operating system version does not include D3D11. Please run Windows Update.\n\nPress Yes to try again using Direct3D9 instead.")); } @@ -119,8 +119,8 @@ bool D3D11Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) { std::wstring title = ConvertUTF8ToWString(err->T("D3D11InitializationError", "Direct3D 11 initialization error")); bool yes = IDYES == MessageBox(hWnd_, error.c_str(), title.c_str(), MB_ICONERROR | MB_YESNO); if (yes) { - // Change the config to D3D9 and restart. - g_Config.iGPUBackend = (int)GPUBackend::DIRECT3D9; + // Change the config to OpenGL and restart. + g_Config.iGPUBackend = (int)GPUBackend::OPENGL; g_Config.sFailedGPUBackends.clear(); g_Config.Save("save_d3d9_fallback"); diff --git a/Windows/GPU/D3D9Context.cpp b/Windows/GPU/D3D9Context.cpp deleted file mode 100644 index cb4e76c9470c..000000000000 --- a/Windows/GPU/D3D9Context.cpp +++ /dev/null @@ -1,197 +0,0 @@ -#include "ppsspp_config.h" - -#include "Common/CommonWindows.h" -#include - -#include "Common/GPU/D3D9/D3D9StateCache.h" - -#include "Common/System/Display.h" -#include "Common/Data/Encoding/Utf8.h" -#include "Common/Data/Text/I18n.h" -#include "Common/Log.h" -#include "Common/OSVersion.h" - -#include "Core/Config.h" -#include "Core/ConfigValues.h" -#include "Core/System.h" -#include "Common/OSVersion.h" -#include "Windows/GPU/D3D9Context.h" -#include "Windows/W32Util/Misc.h" -#include "Common/GPU/thin3d.h" -#include "Common/GPU/thin3d_create.h" -#include "Common/GPU/D3D9/D3DCompilerLoader.h" - -typedef HRESULT (__stdcall *DIRECT3DCREATE9EX)(UINT, IDirect3D9Ex**); - -bool D3D9Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) { - bool windowed = true; - hWnd_ = wnd; - - // D3D9 has no need for display rotation. - g_display.rotation = DisplayRotation::ROTATE_0; - g_display.rot_matrix.setIdentity(); - - DIRECT3DCREATE9EX g_pfnCreate9ex; - - hD3D9_ = LoadLibrary(TEXT("d3d9.dll")); - if (!hD3D9_) { - ERROR_LOG(Log::G3D, "Missing d3d9.dll"); - *error_message = "D3D9.dll missing - try reinstalling DirectX."; - return false; - } - - bool result = LoadD3DCompilerDynamic(); - if (!result) { - *error_message = "D3DCompiler not found! Try reinstalling DirectX."; - return false; - } - - g_pfnCreate9ex = (DIRECT3DCREATE9EX)GetProcAddress(hD3D9_, "Direct3DCreate9Ex"); - has9Ex_ = (g_pfnCreate9ex != NULL) && IsVistaOrHigher(); - - if (has9Ex_) { - HRESULT result = g_pfnCreate9ex(D3D_SDK_VERSION, &d3dEx_); - d3d_ = d3dEx_; - if (FAILED(result)) { - FreeLibrary(hD3D9_); - *error_message = "D3D9Ex available but context creation failed. Try reinstalling DirectX."; - return false; - } - } else { - d3d_ = Direct3DCreate9(D3D_SDK_VERSION); - if (!d3d_) { - FreeLibrary(hD3D9_); - *error_message = "Failed to create D3D9 context. Try reinstalling DirectX."; - return false; - } - } - adapterId_ = D3DADAPTER_DEFAULT; - - D3DCAPS9 d3dCaps; - - D3DDISPLAYMODE d3ddm; - if (FAILED(d3d_->GetAdapterDisplayMode(adapterId_, &d3ddm))) { - *error_message = "GetAdapterDisplayMode failed"; - d3d_ = nullptr; - return false; - } - - if (FAILED(d3d_->GetDeviceCaps(adapterId_, D3DDEVTYPE_HAL, &d3dCaps))) { - *error_message = "GetDeviceCaps failed (?)"; - d3d_ = nullptr; - return false; - } - - HRESULT hr; - if (FAILED(hr = d3d_->CheckDeviceFormat(adapterId_, - D3DDEVTYPE_HAL, - d3ddm.Format, - D3DUSAGE_DEPTHSTENCIL, - D3DRTYPE_SURFACE, - D3DFMT_D24S8))) { - if (hr == D3DERR_NOTAVAILABLE) { - *error_message = "D24S8 depth/stencil not available"; - d3d_ = nullptr; - return false; - } - } - - DWORD dwBehaviorFlags = D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE; - if (d3dCaps.VertexProcessingCaps != 0) - dwBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING; - else - dwBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING; - - int xres, yres; - W32Util::GetWindowRes(hWnd_, &xres, &yres); - - presentParams_ = {}; - presentParams_.BackBufferWidth = xres; - presentParams_.BackBufferHeight = yres; - presentParams_.BackBufferFormat = d3ddm.Format; - presentParams_.MultiSampleType = D3DMULTISAMPLE_NONE; - presentParams_.SwapEffect = D3DSWAPEFFECT_DISCARD; - presentParams_.Windowed = windowed; - presentParams_.hDeviceWindow = wnd; - presentParams_.EnableAutoDepthStencil = true; - presentParams_.AutoDepthStencilFormat = D3DFMT_D24S8; - presentParams_.PresentationInterval = swapInterval_ == 1 ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE; - - if (has9Ex_) { - if (windowed && IsWin7OrHigher()) { - // This "new" flip mode should give higher performance but doesn't. - //pp.BackBufferCount = 2; - //pp.SwapEffect = D3DSWAPEFFECT_FLIPEX; - } - hr = d3dEx_->CreateDeviceEx(adapterId_, D3DDEVTYPE_HAL, wnd, dwBehaviorFlags, &presentParams_, NULL, &deviceEx_); - device_ = deviceEx_; - } else { - hr = d3d_->CreateDevice(adapterId_, D3DDEVTYPE_HAL, wnd, dwBehaviorFlags, &presentParams_, &device_); - } - - if (FAILED(hr)) { - *error_message = "Failed to create D3D device"; - d3d_ = nullptr; - return false; - } - - device_->BeginScene(); - pD3Ddevice9 = device_; - pD3DdeviceEx9 = deviceEx_; - - if (deviceEx_ && IsWin7OrHigher()) { - // TODO: This makes it slower? - //deviceEx->SetMaximumFrameLatency(1); - } - draw_ = Draw::T3DCreateDX9Context(d3d_.Get(), d3dEx_.Get(), adapterId_, device_.Get(), deviceEx_.Get()); - SetGPUBackend(GPUBackend::DIRECT3D9); - if (!draw_->CreatePresets()) { - // Shader compiler not installed? Return an error so we can fall back to GL. - device_ = nullptr; - d3d_ = nullptr; - *error_message = "DirectX9 runtime not correctly installed. Please install."; - return false; - } - if (draw_) - draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, 0, 0, nullptr); - return true; -} - -void D3D9Context::Resize() { - // This should only be called from the emu thread. - int xres, yres; - W32Util::GetWindowRes(hWnd_, &xres, &yres); - uint32_t newInterval = swapInterval_ == 1 ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE; - bool w_changed = presentParams_.BackBufferWidth != xres; - bool h_changed = presentParams_.BackBufferHeight != yres; - bool i_changed = presentParams_.PresentationInterval != newInterval; - - if (device_ && (w_changed || h_changed || i_changed)) { - draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, 0, 0, nullptr); - presentParams_.BackBufferWidth = xres; - presentParams_.BackBufferHeight = yres; - presentParams_.PresentationInterval = newInterval; - HRESULT hr = device_->Reset(&presentParams_); - if (FAILED(hr)) { - // Had to remove DXGetErrorStringA calls here because dxerr.lib is deprecated and will not link with VS 2015. - _assert_msg_(false, "Unable to reset D3D9 device"); - } - draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, 0, 0, nullptr); - } -} - -void D3D9Context::Shutdown() { - draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, 0, 0, nullptr); - delete draw_; - draw_ = nullptr; - device_->EndScene(); - device_ = nullptr; - d3d_ = nullptr; - UnloadD3DCompiler(); - pD3Ddevice9 = nullptr; - pD3DdeviceEx9 = nullptr; - device_ = nullptr; - hWnd_ = nullptr; - FreeLibrary(hD3D9_); - hD3D9_ = nullptr; -} diff --git a/Windows/GPU/D3D9Context.h b/Windows/GPU/D3D9Context.h deleted file mode 100644 index 23048abaac50..000000000000 --- a/Windows/GPU/D3D9Context.h +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) 2015- PPSSPP Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0 or later versions. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official git repository and contact information can be found at -// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. - -// Modelled on OpenD3DBase. Might make a cleaner interface later. - -#pragma once - -#include "Common/CommonWindows.h" -#include "Windows/GPU/WindowsGraphicsContext.h" -#include -#include - -namespace Draw { - class DrawContext; -} - -class D3D9Context : public WindowsGraphicsContext { -public: - D3D9Context() : draw_(nullptr), has9Ex_(false), d3d_(nullptr), d3dEx_(nullptr), adapterId_(-1), device_(nullptr), deviceEx_(nullptr), hDC_(nullptr), hWnd_(nullptr), hD3D9_(nullptr), presentParams_{} { - } - - bool Init(HINSTANCE hInst, HWND window, std::string *error_message) override; - void Shutdown() override; - - void Resize() override; - - Draw::DrawContext *GetDrawContext() override { return draw_; } - -private: - Draw::DrawContext *draw_; - bool has9Ex_; - Microsoft::WRL::ComPtr d3d_; - Microsoft::WRL::ComPtr d3dEx_; - int adapterId_; - Microsoft::WRL::ComPtr device_; - Microsoft::WRL::ComPtr deviceEx_; - HDC hDC_; // Private GDI Device Context - HWND hWnd_; // Holds Our Window Handle - HMODULE hD3D9_; - D3DPRESENT_PARAMETERS presentParams_; - int swapInterval_ = 0; -}; - diff --git a/Windows/GPU/WindowsGLContext.cpp b/Windows/GPU/WindowsGLContext.cpp index d0a649f18b7a..89192b79f8bd 100644 --- a/Windows/GPU/WindowsGLContext.cpp +++ b/Windows/GPU/WindowsGLContext.cpp @@ -270,10 +270,7 @@ bool WindowsGLContext::InitFromRenderThread(std::string *error_message) { if (yes) { // Change the config to D3D and restart. - const char *d3d9Or11 = "Direct3D 9? (Or no for Direct3D 11)"; - std::wstring whichD3D9 = ConvertUTF8ToWString(err->T("D3D9or11", d3d9Or11)); - bool d3d9 = IDYES == MessageBox(hWnd_, whichD3D9.c_str(), title.c_str(), MB_YESNO); - g_Config.iGPUBackend = d3d9 ? (int)GPUBackend::DIRECT3D9 : (int)GPUBackend::DIRECT3D11; + g_Config.iGPUBackend = (int)GPUBackend::DIRECT3D11; g_Config.sFailedGPUBackends.clear(); g_Config.Save("save_d3d11_fallback"); diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index 70f8d38713d9..7ff1b9113d9d 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -280,7 +280,6 @@ namespace MainWindow { // Skip window size 1x-4x.. TranslateMenuItem(menu, ID_OPTIONS_BACKEND_MENU); TranslateMenuItem(menu, ID_OPTIONS_DIRECT3D11); - TranslateMenuItem(menu, ID_OPTIONS_DIRECT3D9); TranslateMenuItem(menu, ID_OPTIONS_OPENGL); TranslateMenuItem(menu, ID_OPTIONS_VULKAN); @@ -689,12 +688,6 @@ namespace MainWindow { System_PostUIMessage(UIMessage::GPU_CONFIG_CHANGED); break; - case ID_OPTIONS_DIRECT3D9: - g_Config.iGPUBackend = (int)GPUBackend::DIRECT3D9; - g_Config.Save("gpu_choice"); - RestartApp(); - break; - case ID_OPTIONS_DIRECT3D11: g_Config.iGPUBackend = (int)GPUBackend::DIRECT3D11; g_Config.Save("gpu_choice"); @@ -1186,48 +1179,31 @@ namespace MainWindow { CheckMenuItem(menu, savestateSlot[i], MF_BYCOMMAND | ((i == g_Config.iCurrentStateSlot) ? MF_CHECKED : MF_UNCHECKED)); } - bool allowD3D9 = g_Config.IsBackendEnabled(GPUBackend::DIRECT3D9); bool allowD3D11 = g_Config.IsBackendEnabled(GPUBackend::DIRECT3D11); bool allowOpenGL = g_Config.IsBackendEnabled(GPUBackend::OPENGL); bool allowVulkan = g_Config.IsBackendEnabled(GPUBackend::VULKAN); switch (GetGPUBackend()) { - case GPUBackend::DIRECT3D9: - EnableMenuItem(menu, ID_OPTIONS_DIRECT3D9, MF_GRAYED); - EnableMenuItem(menu, ID_OPTIONS_DIRECT3D11, allowD3D11 ? MF_ENABLED : MF_GRAYED); - EnableMenuItem(menu, ID_OPTIONS_OPENGL, allowOpenGL ? MF_ENABLED : MF_GRAYED); - EnableMenuItem(menu, ID_OPTIONS_VULKAN, allowVulkan ? MF_ENABLED : MF_GRAYED); - CheckMenuItem(menu, ID_OPTIONS_DIRECT3D9, MF_CHECKED); - CheckMenuItem(menu, ID_OPTIONS_DIRECT3D11, MF_UNCHECKED); - CheckMenuItem(menu, ID_OPTIONS_OPENGL, MF_UNCHECKED); - CheckMenuItem(menu, ID_OPTIONS_VULKAN, MF_UNCHECKED); - break; case GPUBackend::OPENGL: - EnableMenuItem(menu, ID_OPTIONS_DIRECT3D9, allowD3D9 ? MF_ENABLED : MF_GRAYED); EnableMenuItem(menu, ID_OPTIONS_DIRECT3D11, allowD3D11 ? MF_ENABLED : MF_GRAYED); EnableMenuItem(menu, ID_OPTIONS_OPENGL, MF_GRAYED); EnableMenuItem(menu, ID_OPTIONS_VULKAN, allowVulkan ? MF_ENABLED : MF_GRAYED); - CheckMenuItem(menu, ID_OPTIONS_DIRECT3D9, MF_UNCHECKED); CheckMenuItem(menu, ID_OPTIONS_DIRECT3D11, MF_UNCHECKED); CheckMenuItem(menu, ID_OPTIONS_OPENGL, MF_CHECKED); CheckMenuItem(menu, ID_OPTIONS_VULKAN, MF_UNCHECKED); break; case GPUBackend::VULKAN: - EnableMenuItem(menu, ID_OPTIONS_DIRECT3D9, allowD3D9 ? MF_ENABLED : MF_GRAYED); EnableMenuItem(menu, ID_OPTIONS_DIRECT3D11, allowD3D11 ? MF_ENABLED : MF_GRAYED); EnableMenuItem(menu, ID_OPTIONS_OPENGL, allowOpenGL ? MF_ENABLED : MF_GRAYED); EnableMenuItem(menu, ID_OPTIONS_VULKAN, MF_GRAYED); - CheckMenuItem(menu, ID_OPTIONS_DIRECT3D9, MF_UNCHECKED); CheckMenuItem(menu, ID_OPTIONS_DIRECT3D11, MF_UNCHECKED); CheckMenuItem(menu, ID_OPTIONS_OPENGL, MF_UNCHECKED); CheckMenuItem(menu, ID_OPTIONS_VULKAN, MF_CHECKED); break; case GPUBackend::DIRECT3D11: - EnableMenuItem(menu, ID_OPTIONS_DIRECT3D9, allowD3D9 ? MF_ENABLED : MF_GRAYED); EnableMenuItem(menu, ID_OPTIONS_DIRECT3D11, MF_GRAYED); EnableMenuItem(menu, ID_OPTIONS_OPENGL, allowOpenGL ? MF_ENABLED : MF_GRAYED); EnableMenuItem(menu, ID_OPTIONS_VULKAN, allowVulkan ? MF_ENABLED : MF_GRAYED); - CheckMenuItem(menu, ID_OPTIONS_DIRECT3D9, MF_UNCHECKED); CheckMenuItem(menu, ID_OPTIONS_DIRECT3D11, MF_CHECKED); CheckMenuItem(menu, ID_OPTIONS_OPENGL, MF_UNCHECKED); CheckMenuItem(menu, ID_OPTIONS_VULKAN, MF_UNCHECKED); diff --git a/Windows/PPSSPP.vcxproj b/Windows/PPSSPP.vcxproj index 804b3cd32ef9..53f2fd06c66e 100644 --- a/Windows/PPSSPP.vcxproj +++ b/Windows/PPSSPP.vcxproj @@ -249,7 +249,7 @@ stdcpp17 - dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) ../ffmpeg/Windows/x86/lib true Windows @@ -289,7 +289,7 @@ stdcpp17 - dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) ../ffmpeg/Windows/x86_64/lib true $(OutDir)$(ProjectName).pdb @@ -325,7 +325,7 @@ stdcpp17 - dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies) + dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies) ../ffmpeg/Windows/aarch64/lib true $(OutDir)$(ProjectName).pdb @@ -359,7 +359,7 @@ stdcpp17 - dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies) + dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies) ../ffmpeg/Windows/arm/lib true $(OutDir)$(ProjectName).pdb @@ -397,7 +397,7 @@ stdcpp17 - dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) ../ffmpeg/Windows/x86/lib;%(AdditionalLibraryDirectories) $(OutDir)$(TargetName)$(TargetExt) true @@ -446,7 +446,7 @@ stdcpp17 - dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) ../ffmpeg/Windows/x86_64/lib;%(AdditionalLibraryDirectories) true Windows @@ -489,7 +489,7 @@ stdcpp17 - dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies) + dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies) ../ffmpeg/Windows/aarch64/lib;%(AdditionalLibraryDirectories) true Windows @@ -530,7 +530,7 @@ stdcpp17 - dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies) + dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies) ../ffmpeg/Windows/arm/lib;%(AdditionalLibraryDirectories) true Windows @@ -842,7 +842,6 @@ - @@ -1400,7 +1399,6 @@ - diff --git a/Windows/PPSSPP.vcxproj.filters b/Windows/PPSSPP.vcxproj.filters index 0b2ea0898d35..1a585b001dc4 100644 --- a/Windows/PPSSPP.vcxproj.filters +++ b/Windows/PPSSPP.vcxproj.filters @@ -175,9 +175,6 @@ Windows\UI - - Windows\System - Windows\System @@ -390,9 +387,6 @@ Windows\UI - - Windows\System - Windows\System @@ -592,12 +586,6 @@ Resource Files - - Resource Files - - - Resource Files - Resource Files @@ -856,4 +844,4 @@ Other Platforms\SDL - + \ No newline at end of file diff --git a/Windows/main.cpp b/Windows/main.cpp index dec7d3f5e165..62cda0d7fa31 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -1008,14 +1008,11 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin if (wideArgs[i].find(gpuBackend) != std::wstring::npos && wideArgs[i].size() > gpuBackend.size()) { const std::wstring restOfOption = wideArgs[i].substr(gpuBackend.size()); - // Force software rendering off, as picking directx9 or gles implies HW acceleration. - // Once software rendering supports Direct3D9/11, we can add more options for software, - // such as "software-gles", "software-d3d9", and "software-d3d11", or something similar. + // Force software rendering off, as picking gles implies HW acceleration. + // We could add more options for software such as "software-gles", + // "software-vulkan" and "software-d3d11", or something similar. // For now, software rendering force-activates OpenGL. - if (restOfOption == L"directx9") { - g_Config.iGPUBackend = (int)GPUBackend::DIRECT3D9; - g_Config.bSoftwareRendering = false; - } else if (restOfOption == L"directx11") { + if (restOfOption == L"directx11") { g_Config.iGPUBackend = (int)GPUBackend::DIRECT3D11; g_Config.bSoftwareRendering = false; } else if (restOfOption == L"gles") { diff --git a/Windows/ppsspp.rc b/Windows/ppsspp.rc index 8e551803f46b..f2a9db7aa5b9 100644 --- a/Windows/ppsspp.rc +++ b/Windows/ppsspp.rc @@ -624,7 +624,6 @@ BEGIN POPUP "Backend", ID_OPTIONS_BACKEND_MENU BEGIN - MENUITEM "Direct3D9", ID_OPTIONS_DIRECT3D9 MENUITEM "Direct3D11", ID_OPTIONS_DIRECT3D11 MENUITEM "OpenGL", ID_OPTIONS_OPENGL MENUITEM "Vulkan", ID_OPTIONS_VULKAN diff --git a/Windows/resource.h b/Windows/resource.h index da66e5d4863f..1819b56c3d85 100644 --- a/Windows/resource.h +++ b/Windows/resource.h @@ -272,7 +272,6 @@ #define ID_DEBUG_SAVESYMFILE 40151 #define ID_OPTIONS_BUFLINEARFILTER 40152 #define ID_OPTIONS_BUFNEARESTFILTER 40153 -#define ID_OPTIONS_DIRECT3D9 40154 #define ID_OPTIONS_OPENGL 40155 #define ID_EMULATION_ROTATION_H 40156 #define ID_EMULATION_ROTATION_V 40157 diff --git a/headless/Headless.cpp b/headless/Headless.cpp index 53f41c651656..8529164a54bb 100644 --- a/headless/Headless.cpp +++ b/headless/Headless.cpp @@ -399,8 +399,6 @@ int main(int argc, const char* argv[]) // There used to be a separate "null" rendering core - just use software. else if (!strcasecmp(gpuName, "software") || !strcasecmp(gpuName, "null")) gpuCore = GPUCORE_SOFTWARE; - else if (!strcasecmp(gpuName, "directx9")) - gpuCore = GPUCORE_DIRECTX9; else if (!strcasecmp(gpuName, "directx11")) gpuCore = GPUCORE_DIRECTX11; else if (!strcasecmp(gpuName, "vulkan")) diff --git a/headless/Headless.vcxproj b/headless/Headless.vcxproj index 8056042ad4fd..75589b6396af 100644 --- a/headless/Headless.vcxproj +++ b/headless/Headless.vcxproj @@ -191,7 +191,7 @@ Console true - winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) 0x00400000 false true @@ -225,7 +225,7 @@ Console true - winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) 0x00400000 false true @@ -258,7 +258,7 @@ Console true - winhttp.lib;ole32.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies) + winhttp.lib;ole32.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/aarch64/lib @@ -289,7 +289,7 @@ Console true - winhttp.lib;ole32.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies) + winhttp.lib;ole32.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/arm/lib @@ -323,7 +323,7 @@ true true true - winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) 0x00400000 false true @@ -362,7 +362,7 @@ true true true - winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) 0x00400000 false true @@ -400,7 +400,7 @@ true true true - winhttp.lib;ole32.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies) + winhttp.lib;ole32.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/aarch64/lib;%(AdditionalLibraryDirectories) @@ -435,7 +435,7 @@ true true true - winhttp.lib;ole32.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies) + winhttp.lib;ole32.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/arm/lib;%(AdditionalLibraryDirectories) @@ -455,7 +455,6 @@ - true true diff --git a/headless/Headless.vcxproj.filters b/headless/Headless.vcxproj.filters index 0cc2cc7b61bd..33fa39eb7646 100644 --- a/headless/Headless.vcxproj.filters +++ b/headless/Headless.vcxproj.filters @@ -4,9 +4,6 @@ - - Windows - Windows diff --git a/headless/WindowsHeadlessHost.cpp b/headless/WindowsHeadlessHost.cpp index 81e1795a95d3..70a9d6e0aac7 100644 --- a/headless/WindowsHeadlessHost.cpp +++ b/headless/WindowsHeadlessHost.cpp @@ -37,7 +37,6 @@ #if PPSSPP_API(ANY_GL) #include "Windows/GPU/WindowsGLContext.h" #endif -#include "Windows/GPU/D3D9Context.h" #include "Windows/GPU/D3D11Context.h" #include "Windows/GPU/WindowsVulkanContext.h" @@ -91,10 +90,6 @@ bool WindowsHeadlessHost::InitGraphics(std::string *error_message, GraphicsConte needRenderThread = true; break; #endif - case GPUCORE_DIRECTX9: - graphicsContext = new D3D9Context(); - break; - case GPUCORE_DIRECTX11: graphicsContext = new D3D11Context(); break; @@ -102,6 +97,9 @@ bool WindowsHeadlessHost::InitGraphics(std::string *error_message, GraphicsConte case GPUCORE_VULKAN: graphicsContext = new WindowsVulkanContext(); break; + default: + _assert_(false); + break; } if (graphicsContext->Init(NULL, hWnd, error_message)) { @@ -165,11 +163,4 @@ void WindowsHeadlessHost::ShutdownGraphics() { hWnd = NULL; } -void WindowsHeadlessHost::SwapBuffers() { - if (gpuCore_ == GPUCORE_DIRECTX9) { - MSG msg; - PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); - TranslateMessage(&msg); - DispatchMessage(&msg); - } -} +void WindowsHeadlessHost::SwapBuffers() {} diff --git a/libretro/LibretroGraphicsContext.h b/libretro/LibretroGraphicsContext.h index 96e7bbd69a1d..26c6c199d0a8 100644 --- a/libretro/LibretroGraphicsContext.h +++ b/libretro/LibretroGraphicsContext.h @@ -68,22 +68,6 @@ class LibretroHWRenderContext : public LibretroGraphicsContext { retro_hw_render_callback hw_render_ = {}; }; -#ifdef _WIN32 -class LibretroD3D9Context : public LibretroHWRenderContext { -public: - LibretroD3D9Context() : LibretroHWRenderContext(RETRO_HW_CONTEXT_DIRECT3D, 9) {} - bool Init() override { return false; } - - void CreateDrawContext() override { - draw_ = Draw::T3DCreateDX9Context(nullptr, nullptr, 0, nullptr, nullptr); - draw_->CreatePresets(); - } - - GPUCore GetGPUCore() override { return GPUCORE_DIRECTX9; } - const char *Ident() override { return "DirectX 9"; } -}; -#endif - class LibretroSoftwareContext : public LibretroGraphicsContext { public: LibretroSoftwareContext() {} diff --git a/libretro/Makefile b/libretro/Makefile index a4649fb585d4..ddc47d5702ec 100644 --- a/libretro/Makefile +++ b/libretro/Makefile @@ -398,14 +398,14 @@ else ifneq (,$(findstring windows_msvc2019,$(platform))) FFMPEGLIBDIR := $(FFMPEGDIR)/Windows/$(TARGET_ARCH)/lib FFMPEGLDFLAGS += -LIBPATH:$(FFMPEGLIBDIR) GL_LIB := opengl32.lib - LDFLAGS += ws2_32.lib user32.lib shell32.lib avcodec.lib avutil.lib swresample.lib swscale.lib avformat.lib advapi32.lib winmm.lib gdi32.lib d3d9.lib Iphlpapi.lib + LDFLAGS += ws2_32.lib user32.lib shell32.lib avcodec.lib avutil.lib swresample.lib swscale.lib avformat.lib advapi32.lib winmm.lib gdi32.lib Iphlpapi.lib # Windows else ifneq (,$(findstring win,$(platform))) TARGET := $(TARGET_NAME)_libretro.dll CFLAGS += -D_UNICODE -DUNICODE CXXFLAGS += -fpermissive -Wno-multichar -D_UNICODE -DUNICODE -DARMIPS_USE_STD_FILESYSTEM - LDFLAGS += -shared -Wl,--no-undefined -static-libgcc -static-libstdc++ -Wl,--version-script=link.T -lwinmm -lgdi32 -lwsock32 -lws2_32 -ld3d9 + LDFLAGS += -shared -Wl,--no-undefined -static-libgcc -static-libstdc++ -Wl,--version-script=link.T -lwinmm -lgdi32 -lwsock32 -lws2_32 GL_LIB := -lopengl32 PLATFORM_EXT = win32 FFMPEGINCFLAGS += -I$(FFMPEGDIR)/Windows/$(TARGET_ARCH)/include diff --git a/libretro/Makefile.common b/libretro/Makefile.common index 32f7f08d35bf..652fc5ef53ff 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -983,14 +983,6 @@ SOURCES_CXX += \ ifeq ($(PLATFORM_EXT), win32) -SOURCES_CXX += \ - $(GPUDIR)/Directx9/DrawEngineDX9.cpp \ - $(GPUDIR)/Directx9/FramebufferManagerDX9.cpp \ - $(GPUDIR)/Directx9/GPU_DX9.cpp \ - $(GPUDIR)/Directx9/ShaderManagerDX9.cpp \ - $(GPUDIR)/Directx9/StateMappingDX9.cpp \ - $(GPUDIR)/Directx9/TextureCacheDX9.cpp - SOURCES_CXX += \ $(GPUDIR)/D3D11/DrawEngineD3D11.cpp \ $(GPUDIR)/D3D11/FramebufferManagerD3D11.cpp \ @@ -1002,10 +994,6 @@ SOURCES_CXX += \ $(LIBRETRODIR)/LibretroD3D11Context.cpp SOURCES_CXX += \ - $(COMMONDIR)/GPU/D3D9/D3D9ShaderCompiler.cpp \ - $(COMMONDIR)/GPU/D3D9/D3D9StateCache.cpp \ - $(COMMONDIR)/GPU/D3D9/D3DCompilerLoader.cpp \ - $(COMMONDIR)/GPU/D3D9/thin3d_d3d9.cpp \ $(COMMONDIR)/GPU/D3D11/D3D11Loader.cpp \ $(COMMONDIR)/GPU/D3D11/thin3d_d3d11.cpp diff --git a/ppsspp_config.h b/ppsspp_config.h index 2a741dca3dc7..d38c4be25469 100644 --- a/ppsspp_config.h +++ b/ppsspp_config.h @@ -126,9 +126,5 @@ #endif #if PPSSPP_PLATFORM(WINDOWS) -#if !PPSSPP_PLATFORM(UWP) -#define PPSSPP_API_D3D9 1 -#endif #define PPSSPP_API_D3D11 1 #endif - diff --git a/unittest/TestShaderGenerators.cpp b/unittest/TestShaderGenerators.cpp index a53862a990cb..c4978484beb0 100644 --- a/unittest/TestShaderGenerators.cpp +++ b/unittest/TestShaderGenerators.cpp @@ -21,9 +21,6 @@ #include #include "GPU/D3D11/D3D11Util.h" #include "GPU/D3D11/D3D11Loader.h" - -#include "GPU/D3D9/D3DCompilerLoader.h" -#include "GPU/D3D9/D3D9ShaderCompiler.h" #endif static constexpr size_t CODE_BUFFER_SIZE = 32768; @@ -50,11 +47,6 @@ bool GenerateFShader(FShaderID id, char *buffer, ShaderLanguage lang, Draw::Bugs ShaderLanguageDesc compat(ShaderLanguage::GLSL_3xx); return GenerateFragmentShader(id, buffer, compat, bugs, &uniformMask, &flags, errorString); } - case ShaderLanguage::HLSL_D3D9: - { - ShaderLanguageDesc compat(ShaderLanguage::HLSL_D3D9); - return GenerateFragmentShader(id, buffer, compat, bugs, &uniformMask, &flags, errorString); - } case ShaderLanguage::HLSL_D3D11: { ShaderLanguageDesc compat(ShaderLanguage::HLSL_D3D11); @@ -88,11 +80,6 @@ bool GenerateVShader(VShaderID id, char *buffer, ShaderLanguage lang, Draw::Bugs ShaderLanguageDesc compat(ShaderLanguage::GLSL_3xx); return GenerateVertexShader(id, buffer, compat, bugs, &attrMask, &uniformMask, &flags, errorString); } - case ShaderLanguage::HLSL_D3D9: - { - ShaderLanguageDesc compat(ShaderLanguage::HLSL_D3D9); - return GenerateVertexShader(id, buffer, compat, bugs, &attrMask, &uniformMask, &flags, errorString); - } case ShaderLanguage::HLSL_D3D11: { ShaderLanguageDesc compat(ShaderLanguage::HLSL_D3D11); @@ -157,18 +144,6 @@ bool TestCompileShader(const char *buffer, ShaderLanguage lang, ShaderStage stag auto output = CompileShaderToBytecodeD3D11(buffer, strlen(buffer), programType, 0); return !output.empty(); } - case ShaderLanguage::HLSL_D3D9: - { - const char *programType = nullptr; - switch (stage) { - case ShaderStage::Vertex: programType = "vs_3_0"; break; - case ShaderStage::Fragment: programType = "ps_3_0"; break; - default: return false; - } - Microsoft::WRL::ComPtr blob; - HRESULT hr = CompileShaderToByteCodeD3D9(buffer, programType, errorMessage, &blob); - return SUCCEEDED(hr); - } #endif case ShaderLanguage::GLSL_VULKAN: @@ -211,7 +186,6 @@ void PrintDiff(const char *a, const char *b) { const char *ShaderLanguageToString(ShaderLanguage lang) { switch (lang) { case HLSL_D3D11: return "HLSL_D3D11"; - case HLSL_D3D9: return "HLSL_D3D9"; case GLSL_VULKAN: return "GLSL_VULKAN"; case GLSL_1xx: return "GLSL_1xx"; case GLSL_3xx: return "GLSL_3xx"; @@ -275,7 +249,6 @@ bool TestStencilShaders() { ShaderLanguage languages[] = { #if PPSSPP_PLATFORM(WINDOWS) - ShaderLanguage::HLSL_D3D9, ShaderLanguage::HLSL_D3D11, #endif ShaderLanguage::GLSL_VULKAN, @@ -331,7 +304,6 @@ bool TestDepalShaders() { ShaderLanguage languages[] = { #if PPSSPP_PLATFORM(WINDOWS) - ShaderLanguage::HLSL_D3D9, ShaderLanguage::HLSL_D3D11, #endif ShaderLanguage::GLSL_VULKAN, @@ -380,7 +352,6 @@ bool TestDepalShaders() { const ShaderLanguage languages[] = { #if PPSSPP_PLATFORM(WINDOWS) - ShaderLanguage::HLSL_D3D9, ShaderLanguage::HLSL_D3D11, #endif ShaderLanguage::GLSL_VULKAN, @@ -619,7 +590,6 @@ bool TestShaderGenerators() { #if PPSSPP_PLATFORM(WINDOWS) LoadD3D11(); init_glslang(); - LoadD3DCompilerDynamic(); #else init_glslang(); #endif diff --git a/unittest/UnitTests.vcxproj b/unittest/UnitTests.vcxproj index 47c860823389..ca98c12d1d7b 100644 --- a/unittest/UnitTests.vcxproj +++ b/unittest/UnitTests.vcxproj @@ -181,7 +181,7 @@ Console true - winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/x86/lib @@ -205,7 +205,7 @@ Console true - winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/x86_64/lib @@ -229,7 +229,7 @@ Console true - winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;%(AdditionalDependencies) + winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/aarch64/lib @@ -254,7 +254,7 @@ Console true - winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;%(AdditionalDependencies) + winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/arm/lib @@ -283,7 +283,7 @@ true true true - winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/x86/lib @@ -313,7 +313,7 @@ true true true - winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/x86_64/lib @@ -343,7 +343,7 @@ true true true - winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;%(AdditionalDependencies) + winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/aarch64/lib @@ -373,7 +373,7 @@ true true true - winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;%(AdditionalDependencies) + winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;%(AdditionalDependencies) /ignore:4049 /ignore:4217 %(AdditionalOptions) ../ffmpeg/Windows/arm/lib