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