Merge pull request #19951 from hrydgard/remove-dx9

Remove D3D9 support, to make future changes easier
This commit is contained in:
Henrik Rydgård
2025-06-10 15:29:10 +02:00
committed by GitHub
70 changed files with 89 additions and 5777 deletions
+4 -28
View File
@@ -604,12 +604,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
@@ -1516,7 +1510,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)
@@ -1875,21 +1869,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
@@ -1910,7 +1889,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
@@ -2693,8 +2672,7 @@ set(WindowsFiles
Windows/DSoundStream.h
Windows/EmuThread.cpp
Windows/EmuThread.h
Windows/GPU/D3D9Context.cpp
Windows/GPU/D3D9Context.h
Windows/GeDebugger/GeDebugger.cpp
Windows/GPU/D3D11Context.cpp
Windows/GPU/D3D11Context.h
Windows/GPU/WindowsGLContext.cpp
@@ -2743,7 +2721,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()
@@ -2800,8 +2778,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
-7
View File
@@ -500,9 +500,6 @@
<ClInclude Include="File\VFS\VFS.h" />
<ClInclude Include="File\VFS\ZipFileReader.h" />
<ClInclude Include="GPU\D3D11\D3D11Loader.h" />
<ClInclude Include="GPU\D3D9\D3DCompilerLoader.h" />
<ClInclude Include="GPU\D3D9\D3D9ShaderCompiler.h" />
<ClInclude Include="GPU\D3D9\D3D9StateCache.h" />
<ClInclude Include="GPU\DataFormat.h" />
<ClInclude Include="GPU\GPUBackendCommon.h" />
<ClInclude Include="GPU\MiscTypes.h" />
@@ -996,10 +993,6 @@
<ClCompile Include="File\VFS\ZipFileReader.cpp" />
<ClCompile Include="GPU\D3D11\D3D11Loader.cpp" />
<ClCompile Include="GPU\D3D11\thin3d_d3d11.cpp" />
<ClCompile Include="GPU\D3D9\D3DCompilerLoader.cpp" />
<ClCompile Include="GPU\D3D9\D3D9ShaderCompiler.cpp" />
<ClCompile Include="GPU\D3D9\D3D9StateCache.cpp" />
<ClCompile Include="GPU\D3D9\thin3d_d3d9.cpp" />
<ClCompile Include="GPU\GPUBackendCommon.cpp" />
<ClCompile Include="GPU\OpenGL\DataFormatGL.cpp" />
<ClCompile Include="GPU\OpenGL\gl3stub.c" />
-24
View File
@@ -250,15 +250,6 @@
<ClInclude Include="UI\ViewGroup.h">
<Filter>UI</Filter>
</ClInclude>
<ClInclude Include="GPU\D3D9\D3DCompilerLoader.h">
<Filter>GPU\D3D9</Filter>
</ClInclude>
<ClInclude Include="GPU\D3D9\D3D9ShaderCompiler.h">
<Filter>GPU\D3D9</Filter>
</ClInclude>
<ClInclude Include="GPU\D3D9\D3D9StateCache.h">
<Filter>GPU\D3D9</Filter>
</ClInclude>
<ClInclude Include="GPU\D3D11\D3D11Loader.h">
<Filter>GPU\D3D11</Filter>
</ClInclude>
@@ -923,21 +914,9 @@
<ClCompile Include="UI\ViewGroup.cpp">
<Filter>UI</Filter>
</ClCompile>
<ClCompile Include="GPU\D3D9\thin3d_d3d9.cpp">
<Filter>GPU\D3D9</Filter>
</ClCompile>
<ClCompile Include="GPU\D3D11\thin3d_d3d11.cpp">
<Filter>GPU\D3D11</Filter>
</ClCompile>
<ClCompile Include="GPU\D3D9\D3DCompilerLoader.cpp">
<Filter>GPU\D3D9</Filter>
</ClCompile>
<ClCompile Include="GPU\D3D9\D3D9ShaderCompiler.cpp">
<Filter>GPU\D3D9</Filter>
</ClCompile>
<ClCompile Include="GPU\D3D9\D3D9StateCache.cpp">
<Filter>GPU\D3D9</Filter>
</ClCompile>
<ClCompile Include="GPU\D3D11\D3D11Loader.cpp">
<Filter>GPU\D3D11</Filter>
</ClCompile>
@@ -1383,9 +1362,6 @@
<Filter Include="GPU">
<UniqueIdentifier>{3b448d70-d5c6-4732-96f0-29f3e101bfe8}</UniqueIdentifier>
</Filter>
<Filter Include="GPU\D3D9">
<UniqueIdentifier>{a1745de8-f61a-4f11-b715-705a8812862e}</UniqueIdentifier>
</Filter>
<Filter Include="GPU\D3D11">
<UniqueIdentifier>{8241d0c2-78c8-4fc6-9543-69042ec5eb54}</UniqueIdentifier>
</Filter>
+1 -8
View File
@@ -357,12 +357,6 @@ D3D11DrawContext::D3D11DrawContext(ComPtr<ID3D11Device> device, ComPtr<ID3D11Dev
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;
@@ -373,6 +367,7 @@ D3D11DrawContext::D3D11DrawContext(ComPtr<ID3D11Device> device, ComPtr<ID3D11Dev
}
}
#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{};
@@ -1650,7 +1645,6 @@ void D3D11DrawContext::CopyFramebufferImage(Framebuffer *srcfb, int level, int x
break;
case Aspect::NO_BIT:
case Aspect::STENCIL_BIT:
case Aspect::SURFACE_BIT:
case Aspect::VIEW_BIT:
case Aspect::FORMAT_BIT:
break;
@@ -1833,7 +1827,6 @@ bool D3D11DrawContext::CopyFramebufferToMemory(Framebuffer *src, Aspect channelB
}
break;
case Aspect::NO_BIT:
case Aspect::SURFACE_BIT:
case Aspect::VIEW_BIT:
case Aspect::FORMAT_BIT:
break;
-70
View File
@@ -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 <wrl/client.h>
using namespace Microsoft::WRL;
HRESULT CompileShaderToByteCodeD3D9(const char *code, const char *target, std::string *errorMessage, ID3DBlob **ppShaderCode) {
ComPtr<ID3DBlob> 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<ID3DBlob> 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<ID3DBlob> 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
-13
View File
@@ -1,13 +0,0 @@
#pragma once
#include "Common/CommonWindows.h"
#include "Common/GPU/D3D9/D3DCompilerLoader.h"
#include <initguid.h>
#include <string>
#include <d3d9.h>
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);
-64
View File
@@ -1,64 +0,0 @@
#ifdef _WIN32
#include "Common/GPU/D3D9/D3D9StateCache.h"
#include <wrl/client.h>
DirectXState dxstate;
Microsoft::WRL::ComPtr<IDirect3DDevice9> pD3Ddevice9;
Microsoft::WRL::ComPtr<IDirect3DDevice9Ex> 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
-402
View File
@@ -1,402 +0,0 @@
#pragma once
#include <cstring>
#include <wrl/client.h>
#include "Common/GPU/D3D9/D3D9ShaderCompiler.h"
// TODO: Get rid of these somehow.
extern Microsoft::WRL::ComPtr<IDirect3DDevice9> pD3Ddevice9;
extern Microsoft::WRL::ComPtr<IDirect3DDevice9Ex> pD3DdeviceEx9;
class DirectXState {
private:
template<D3DRENDERSTATETYPE cap, bool init>
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<D3DRENDERSTATETYPE state1, DWORD p1def>
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<D3DSAMPLERSTATETYPE state1, DWORD p1def>
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<D3DSAMPLERSTATETYPE state1, DWORD p1def>
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<D3DRENDERSTATETYPE state1, DWORD p1def, D3DRENDERSTATETYPE state2, DWORD p2def>
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<D3DRENDERSTATETYPE state1, DWORD p1def, D3DRENDERSTATETYPE state2, DWORD p2def, D3DRENDERSTATETYPE state3, DWORD p3def>
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<D3DRENDERSTATETYPE state1, DWORD p1def, D3DRENDERSTATETYPE state2, DWORD p2def, D3DRENDERSTATETYPE state3, DWORD p3def, D3DRENDERSTATETYPE state4, DWORD p4def>
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<D3DRS_ALPHABLENDENABLE, false> blend;
BoolState<D3DRS_SEPARATEALPHABLENDENABLE, false> blendSeparate;
DxState4<D3DRS_SRCBLEND, D3DBLEND_SRCALPHA, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA, D3DRS_SRCBLENDALPHA, D3DBLEND_ONE, D3DRS_DESTBLENDALPHA, D3DBLEND_ZERO> blendFunc;
DxState2<D3DRS_BLENDOP, D3DBLENDOP_ADD, D3DRS_BLENDOPALPHA, D3DBLENDOP_ADD> blendEquation;
SavedBlendFactor blendColor;
BoolState<D3DRS_SCISSORTESTENABLE, false> scissorTest;
DxState1<D3DRS_CULLMODE, D3DCULL_NONE> cullMode;
DxState1<D3DRS_SHADEMODE, D3DSHADE_GOURAUD> shadeMode;
DxState1<D3DRS_CLIPPLANEENABLE, 0> clipPlaneEnable;
BoolState<D3DRS_ZENABLE, false> depthTest;
DxState1<D3DRS_ALPHAFUNC, D3DCMP_ALWAYS> alphaTestFunc;
DxState1<D3DRS_ALPHAREF, 0> alphaTestRef;
BoolState<D3DRS_ALPHATESTENABLE, false> alphaTest;
DxState1<D3DRS_ZFUNC, D3DCMP_LESSEQUAL> depthFunc;
DxState1<D3DRS_ZWRITEENABLE, TRUE> depthWrite;
DxState1<D3DRS_COLORWRITEENABLE, 0xF> colorMask;
StateVp viewport;
StateScissor scissorRect;
BoolState<D3DRS_STENCILENABLE, false> stencilTest;
DxState3<D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP> stencilOp;
DxState1<D3DRS_STENCILFUNC, D3DCMP_ALWAYS> stencilFunc;
DxState1<D3DRS_STENCILREF, 0> stencilRef;
DxState1<D3DRS_STENCILWRITEMASK, 0xFFFFFFFF> stencilWriteMask;
DxState1<D3DRS_STENCILMASK, 0xFFFFFFFF> stencilCompareMask;
DxSampler0State1<D3DSAMP_MINFILTER, D3DTEXF_POINT> texMinFilter;
DxSampler0State1<D3DSAMP_MAGFILTER, D3DTEXF_POINT> texMagFilter;
DxSampler0State1<D3DSAMP_MIPFILTER, D3DTEXF_NONE> texMipFilter;
DxSampler0State1Float<D3DSAMP_MIPMAPLODBIAS, 0> texMipLodBias;
DxSampler0State1<D3DSAMP_MAXMIPLEVEL, 0> texMaxMipLevel;
DxSampler0State1<D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP> texAddressU;
DxSampler0State1<D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP> texAddressV;
DxSampler0State1<D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP> texAddressW;
};
#undef STATE1
#undef STATE2
extern DirectXState dxstate;
-56
View File
@@ -1,56 +0,0 @@
#include "ppsspp_config.h"
#include "Common/CommonWindows.h"
#include <D3Dcompiler.h>
#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);
}
-15
View File
@@ -1,15 +0,0 @@
#pragma once
#include "ppsspp_config.h"
#include "Common/CommonWindows.h"
#include <D3Dcompiler.h>
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();
File diff suppressed because it is too large Load Diff
-8
View File
@@ -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;
+4 -10
View File
@@ -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";
-1
View File
@@ -17,7 +17,6 @@ enum ShaderLanguage {
GLSL_1xx = 1,
GLSL_3xx = 2,
GLSL_VULKAN = 4,
HLSL_D3D9 = 8,
HLSL_D3D11 = 16,
};
+1 -30
View File
@@ -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);
+2 -57
View File
@@ -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<const char *> 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<InputDef> inputs, Slice<UniformDef> 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<InputDef> inputs, Slice<UniformDef> 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<UniformDef> uniforms, Slice<VaryingDef> 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<VaryingDef> 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<float4> %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:
-8
View File
@@ -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.
-63
View File
@@ -183,13 +183,6 @@ static const std::vector<ShaderSource> 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<ShaderSource> 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<ShaderSource> 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<ShaderSource> 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"(
-5
View File
@@ -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.
};
@@ -625,9 +624,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;
@@ -832,7 +828,6 @@ public:
// * 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.
-1
View File
@@ -28,7 +28,6 @@ namespace Draw {
DrawContext *T3DCreateGLContext(bool canChangeSwapInterval);
#ifdef _WIN32
DrawContext *T3DCreateDX9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, IDirect3DDevice9 *device, IDirect3DDevice9Ex *deviceEx);
DrawContext *T3DCreateD3D11Context(Microsoft::WRL::ComPtr<ID3D11Device> device, Microsoft::WRL::ComPtr<ID3D11DeviceContext> context, Microsoft::WRL::ComPtr<ID3D11Device1> device1, Microsoft::WRL::ComPtr<ID3D11DeviceContext1> context1, Microsoft::WRL::ComPtr<IDXGISwapChain> swapChain, D3D_FEATURE_LEVEL featureLevel, HWND hWnd, const std::vector<std::string> &adapterNames, int maxInflightFrames);
#endif
+5 -10
View File
@@ -80,8 +80,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:
@@ -94,8 +92,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")
@@ -533,11 +529,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";
@@ -574,7 +565,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
@@ -1243,6 +1234,10 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) {
}
}
if (iGPUBackend == 1) { // d3d9, no longer supported
iGPUBackend = 2; // d3d11
}
if (iMaxRecent > 0) {
g_recentFiles.Load(recent, iMaxRecent);
}
-1
View File
@@ -106,7 +106,6 @@ enum class ScreenshotMode {
// 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,
};
+4 -5
View File
@@ -24,11 +24,10 @@
#include "Core/Loaders.h"
enum GPUCore : int {
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 {
+1 -9
View File
@@ -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;
+5 -83
View File
@@ -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<vec4> 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");
}
+2 -2
View File
@@ -1528,7 +1528,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;
}
@@ -1695,7 +1695,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;
}
+1 -7
View File
@@ -493,7 +493,7 @@ Draw::Pipeline *PresentationCommon::CreatePipeline(std::vector<Draw::ShaderModul
Semantic pos = SEM_POSITION;
Semantic tc = SEM_TEXCOORD0;
// Shader translation marks these both as "TEXCOORDs" on HLSL...
if (postShader && (lang_ == HLSL_D3D11 || lang_ == HLSL_D3D9)) {
if (postShader && lang_ == HLSL_D3D11) {
pos = SEM_TEXCOORD0;
tc = SEM_TEXCOORD1;
}
@@ -681,12 +681,6 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u
FRect rc;
CalculateDisplayOutputRect(&rc, 480.0f, 272.0f, frame, uvRotation);
if (GetGPUBackend() == GPUBackend::DIRECT3D9) {
rc.x -= 0.5f;
// This is plus because the top is larger y.
rc.y += 0.5f;
}
// To make buffer updates easier, we use one array of verts.
int postVertsOffset = (int)sizeof(Vertex) * 4;
+1 -1
View File
@@ -38,7 +38,7 @@
// There's code here that simply expands transformed RECTANGLES into plain triangles.
// We're gonna have to keep software transforming RECTANGLES, unless we use a geom shader which we can't on OpenGL ES 2.0 or DX9.
// We're gonna have to keep software transforming RECTANGLES, unless we use a geom shader which we can't on OpenGL ES 2.0.
// Usually, though, these primitives don't use lighting etc so it's no biggie performance wise, but it would be nice to get rid of
// this code.
+1 -4
View File
@@ -2276,9 +2276,6 @@ void TextureCacheCommon::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer
!(texFormat == GE_TFMT_CLUT8 && framebuffer->fb_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;
@@ -3037,7 +3034,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);
}
+11 -87
View File
@@ -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<GELightType>(id.Bits(VS_BIT_LIGHT0_TYPE + 4 * i, 2));
GELightComputation comp = static_cast<GELightComputation>(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<TessWeight> tess_weights_u : register(t1);\n");
WRITE(p, "StructuredBuffer<TessWeight> 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");
-430
View File
@@ -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 <algorithm>
#include <wrl/client.h>
#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<IDirect3DVertexDeclaration9> 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<IDirect3DVertexDeclaration9> 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_->VertexType(), decOptions_.expandAllWeightsToFloat, applySkinInDecode_, pipelineState_);
ComPtr<IDirect3DVertexDeclaration9> 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_) {
DepthRasterSubmitRaw(prim, dec_, dec_->VertexType(), vertexCount);
}
} else {
const 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->VertexType(), 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
}
-106
View File
@@ -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 <d3d9.h>
#include <wrl/client.h>
#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<u32, Microsoft::WRL::ComPtr<IDirect3DVertexDeclaration9>> vertexDeclMap_;
// SimpleVertex
Microsoft::WRL::ComPtr<IDirect3DVertexDeclaration9> 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;
};
-77
View File
@@ -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 <d3d9.h>
#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;
}
-30
View File
@@ -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;
};
-152
View File
@@ -1,152 +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 <string>
#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.
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");
}
}
void GPU_DX9::FinishInitOnMainThread() {
textureCacheDX9_->InitDeviceObjects();
dxstate.Restore();
}
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()
);
}
-60
View File
@@ -1,60 +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 <string>
#include <vector>
#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);
void FinishInitOnMainThread() override;
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_;
};
-706
View File
@@ -1,706 +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 <cmath>
#include <map>
#include "Common/Data/Convert/SmallDataConvert.h"
#include "Common/Data/Encoding/Utf8.h"
#include "Common/Data/Text/I18n.h"
#include "Common/Math/lin/matrix4x4.h"
#include "Common/Math/math_util.h"
#include "Common/GPU/D3D9/D3D9ShaderCompiler.h"
#include "Common/GPU/thin3d.h"
#include "Common/System/OSD.h"
#include "Common/System/Display.h"
#include "Common/CommonTypes.h"
#include "Common/Log.h"
#include "Common/LogReporting.h"
#include "Common/StringUtils.h"
#include "Core/Config.h"
#include "GPU/Math3D.h"
#include "GPU/GPUState.h"
#include "GPU/ge_constants.h"
#include "GPU/Common/ShaderUniforms.h"
#include "GPU/Common/FragmentShaderGenerator.h"
#include "GPU/Directx9/ShaderManagerDX9.h"
#include "GPU/Directx9/DrawEngineDX9.h"
#include "GPU/Directx9/FramebufferManagerDX9.h"
using namespace Lin;
PSShader::PSShader(LPDIRECT3DDEVICE9 device, FShaderID id, const char *code) : id_(id) {
source_ = code;
#ifdef SHADERLOG
OutputDebugString(ConvertUTF8ToWString(code).c_str());
#endif
bool success;
std::string errorMessage;
success = CompilePixelShaderD3D9(device, code, &shader, &errorMessage);
if (!errorMessage.empty()) {
if (success) {
ERROR_LOG(Log::G3D, "Warnings in shader compilation!");
} else {
ERROR_LOG(Log::G3D, "Error in shader compilation!");
}
ERROR_LOG(Log::G3D, "Messages: %s", errorMessage.c_str());
ERROR_LOG(Log::G3D, "Shader source:\n%s", LineNumberString(code).c_str());
OutputDebugStringUTF8("Messages:\n");
OutputDebugStringUTF8(errorMessage.c_str());
Reporting::ReportMessage("D3D error in shader compilation: info: %s / code: %s", errorMessage.c_str(), code);
}
if (!success) {
failed_ = true;
shader = nullptr;
return;
} else {
VERBOSE_LOG(Log::G3D, "Compiled pixel shader:\n%s\n", (const char *)code);
}
}
PSShader::~PSShader() {
}
std::string PSShader::GetShaderString(DebugShaderStringType type) const {
switch (type) {
case SHADER_STRING_SOURCE_CODE:
return source_;
case SHADER_STRING_SHORT_DESC:
return FragmentShaderDesc(id_);
default:
return "N/A";
}
}
VSShader::VSShader(LPDIRECT3DDEVICE9 device, VShaderID id, const char *code, bool useHWTransform) : useHWTransform_(useHWTransform), id_(id) {
source_ = code;
#ifdef SHADERLOG
OutputDebugString(ConvertUTF8ToWString(code).c_str());
#endif
bool success;
std::string errorMessage;
success = CompileVertexShaderD3D9(device, code, &shader, &errorMessage);
if (!errorMessage.empty()) {
if (success) {
ERROR_LOG(Log::G3D, "Warnings in shader compilation!");
} else {
ERROR_LOG(Log::G3D, "Error in shader compilation!");
}
ERROR_LOG(Log::G3D, "Messages: %s", errorMessage.c_str());
ERROR_LOG(Log::G3D, "Shader source:\n%s", code);
OutputDebugStringUTF8("Messages:\n");
OutputDebugStringUTF8(errorMessage.c_str());
Reporting::ReportMessage("D3D error in shader compilation: info: %s / code: %s", errorMessage.c_str(), code);
}
if (!success) {
failed_ = true;
shader = nullptr;
return;
} else {
VERBOSE_LOG(Log::G3D, "Compiled vertex shader:\n%s\n", (const char *)code);
}
}
VSShader::~VSShader() {
}
std::string VSShader::GetShaderString(DebugShaderStringType type) const {
switch (type) {
case SHADER_STRING_SOURCE_CODE:
return source_;
case SHADER_STRING_SHORT_DESC:
return VertexShaderDesc(id_);
default:
return "N/A";
}
}
void ShaderManagerDX9::PSSetColorUniform3(int creg, u32 color) {
float f[4];
Uint8x3ToFloat4(f, color);
device_->SetPixelShaderConstantF(creg, f, 1);
}
void ShaderManagerDX9::PSSetColorUniform3Alpha255(int creg, u32 color, u8 alpha) {
const float col[4] = {
(float)((color & 0xFF)),
(float)((color & 0xFF00) >> 8),
(float)((color & 0xFF0000) >> 16),
(float)alpha,
};
device_->SetPixelShaderConstantF(creg, col, 1);
}
void ShaderManagerDX9::PSSetFloat(int creg, float value) {
const float f[4] = { value, 0.0f, 0.0f, 0.0f };
device_->SetPixelShaderConstantF(creg, f, 1);
}
void ShaderManagerDX9::PSSetFloatArray(int creg, const float *value, int count) {
float f[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
for (int i = 0; i < count; i++) {
f[i] = value[i];
}
device_->SetPixelShaderConstantF(creg, f, 1);
}
void ShaderManagerDX9::VSSetFloat(int creg, float value) {
const float f[4] = { value, 0.0f, 0.0f, 0.0f };
device_->SetVertexShaderConstantF(creg, f, 1);
}
void ShaderManagerDX9::VSSetFloatArray(int creg, const float *value, int count) {
float f[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
for (int i = 0; i < count; i++) {
f[i] = value[i];
}
device_->SetVertexShaderConstantF(creg, f, 1);
}
// Utility
void ShaderManagerDX9::VSSetColorUniform3(int creg, u32 color) {
float f[4];
Uint8x3ToFloat4(f, color);
device_->SetVertexShaderConstantF(creg, f, 1);
}
void ShaderManagerDX9::VSSetFloatUniform4(int creg, const float data[4]) {
device_->SetVertexShaderConstantF(creg, data, 1);
}
void ShaderManagerDX9::VSSetFloat24Uniform3(int creg, const u32 data[3]) {
float f[4];
ExpandFloat24x3ToFloat4(f, data);
device_->SetVertexShaderConstantF(creg, f, 1);
}
void ShaderManagerDX9::VSSetFloat24Uniform3Normalized(int creg, const u32 data[3]) {
float f[4];
ExpandFloat24x3ToFloat4AndNormalize(f, data);
device_->SetVertexShaderConstantF(creg, f, 1);
}
void ShaderManagerDX9::VSSetColorUniform3Alpha(int creg, u32 color, u8 alpha) {
float f[4];
Uint8x3ToFloat4_AlphaUint8(f, color, alpha);
device_->SetVertexShaderConstantF(creg, f, 1);
}
void ShaderManagerDX9::VSSetColorUniform3ExtraFloat(int creg, u32 color, float extra) {
const float col[4] = {
((color & 0xFF)) / 255.0f,
((color & 0xFF00) >> 8) / 255.0f,
((color & 0xFF0000) >> 16) / 255.0f,
extra
};
device_->SetVertexShaderConstantF(creg, col, 1);
}
void ShaderManagerDX9::VSSetMatrix4x3_3(int creg, const float *m4x3) {
float m3x4[12];
ConvertMatrix4x3To3x4Transposed(m3x4, m4x3);
device_->SetVertexShaderConstantF(creg, m3x4, 3);
}
void ShaderManagerDX9::VSSetMatrix(int creg, const float* pMatrix) {
device_->SetVertexShaderConstantF(creg, pMatrix, 4);
}
// Depth in ogl is between -1;1 we need between 0;1 and optionally reverse it
static void ConvertProjMatrixToD3D(Matrix4x4 &in, bool invertedX, bool invertedY) {
// Half pixel offset hack
float xoff = 1.0f / gstate_c.curRTRenderWidth;
if (invertedX) {
xoff = -gstate_c.vpXOffset - xoff;
} else {
xoff = gstate_c.vpXOffset - xoff;
}
float yoff = -1.0f / gstate_c.curRTRenderHeight;
if (invertedY) {
yoff = -gstate_c.vpYOffset - yoff;
} else {
yoff = gstate_c.vpYOffset - yoff;
}
const Vec3 trans(xoff, yoff, gstate_c.vpZOffset * 0.5f + 0.5f);
const Vec3 scale(gstate_c.vpWidthScale, gstate_c.vpHeightScale, gstate_c.vpDepthScale * 0.5f);
in.translateAndScale(trans, scale);
}
static void ConvertProjMatrixToD3DThrough(Matrix4x4 &in) {
float xoff = -1.0f / gstate_c.curRTRenderWidth;
float yoff = 1.0f / gstate_c.curRTRenderHeight;
in.translateAndScale(Vec3(xoff, yoff, 0.5f), Vec3(1.0f, 1.0f, 0.5f));
}
const uint64_t psUniforms = DIRTY_TEXENV | DIRTY_TEX_ALPHA_MUL | DIRTY_ALPHACOLORREF | DIRTY_ALPHACOLORMASK | DIRTY_FOGCOLOR | DIRTY_STENCILREPLACEVALUE | DIRTY_SHADERBLEND | DIRTY_TEXCLAMP | DIRTY_MIPBIAS;
void ShaderManagerDX9::PSUpdateUniforms(u64 dirtyUniforms) {
if (dirtyUniforms & DIRTY_TEXENV) {
PSSetColorUniform3(CONST_PS_TEXENV, gstate.texenvcolor);
}
if (dirtyUniforms & DIRTY_ALPHACOLORREF) {
PSSetColorUniform3Alpha255(CONST_PS_ALPHACOLORREF, gstate.getColorTestRef(), gstate.getAlphaTestRef() & gstate.getAlphaTestMask());
}
if (dirtyUniforms & DIRTY_ALPHACOLORMASK) {
PSSetColorUniform3Alpha255(CONST_PS_ALPHACOLORMASK, gstate.colortestmask, gstate.getAlphaTestMask());
}
if (dirtyUniforms & DIRTY_FOGCOLOR) {
PSSetColorUniform3(CONST_PS_FOGCOLOR, gstate.fogcolor);
}
if (dirtyUniforms & DIRTY_STENCILREPLACEVALUE) {
PSSetFloat(CONST_PS_STENCILREPLACE, (float)gstate.getStencilTestRef() * (1.0f / 255.0f));
}
if (dirtyUniforms & DIRTY_TEX_ALPHA_MUL) {
bool doTextureAlpha = gstate.isTextureAlphaUsed();
if (gstate_c.textureFullAlpha && gstate.getTextureFunction() != GE_TEXFUNC_REPLACE) {
doTextureAlpha = false;
}
// NOTE: Reversed value, more efficient in shader.
float noAlphaMul[2] = { doTextureAlpha ? 0.0f : 1.0f, gstate.isColorDoublingEnabled() ? 2.0f : 1.0f };
PSSetFloatArray(CONST_PS_TEX_NO_ALPHA_MUL, noAlphaMul, 2);
}
if (dirtyUniforms & DIRTY_SHADERBLEND) {
PSSetColorUniform3(CONST_PS_BLENDFIXA, gstate.getFixA());
PSSetColorUniform3(CONST_PS_BLENDFIXB, gstate.getFixB());
const float fbotexSize[2] = {
1.0f / (float)gstate_c.curRTRenderWidth,
1.0f / (float)gstate_c.curRTRenderHeight,
};
PSSetFloatArray(CONST_PS_FBOTEXSIZE, fbotexSize, 2);
}
if (dirtyUniforms & DIRTY_TEXCLAMP) {
const float invW = 1.0f / (float)gstate_c.curTextureWidth;
const float invH = 1.0f / (float)gstate_c.curTextureHeight;
const int w = gstate.getTextureWidth(0);
const int h = gstate.getTextureHeight(0);
const float widthFactor = (float)w * invW;
const float heightFactor = (float)h * invH;
// First wrap xy, then half texel xy (for clamp.)
const float texclamp[4] = {
widthFactor,
heightFactor,
invW * 0.5f,
invH * 0.5f,
};
const float texclampoff[2] = {
gstate_c.curTextureXOffset * invW,
gstate_c.curTextureYOffset * invH,
};
PSSetFloatArray(CONST_PS_TEXCLAMP, texclamp, 4);
PSSetFloatArray(CONST_PS_TEXCLAMPOFF, texclampoff, 2);
}
if (dirtyUniforms & DIRTY_MIPBIAS) {
float mipBias = (float)gstate.getTexLevelOffset16() * (1.0 / 16.0f);
// NOTE: This equation needs some adjustment in D3D9. Can't get it to look completely smooth :(
mipBias = (mipBias + 0.25f) / (float)(gstate.getTextureMaxLevel() + 1);
PSSetFloatArray(CONST_PS_MIPBIAS, &mipBias, 1);
}
}
const uint64_t vsUniforms = DIRTY_PROJMATRIX | DIRTY_PROJTHROUGHMATRIX | DIRTY_WORLDMATRIX | DIRTY_VIEWMATRIX | DIRTY_TEXMATRIX |
DIRTY_FOGCOEF | DIRTY_BONE_UNIFORMS | DIRTY_UVSCALEOFFSET | DIRTY_DEPTHRANGE | DIRTY_CULLRANGE |
DIRTY_AMBIENT | DIRTY_MATAMBIENTALPHA | DIRTY_MATSPECULAR | DIRTY_MATDIFFUSE | DIRTY_MATEMISSIVE | DIRTY_LIGHT0 | DIRTY_LIGHT1 | DIRTY_LIGHT2 | DIRTY_LIGHT3;
void ShaderManagerDX9::VSUpdateUniforms(u64 dirtyUniforms) {
// Update any dirty uniforms before we draw
if (dirtyUniforms & DIRTY_PROJMATRIX) {
Matrix4x4 flippedMatrix;
memcpy(&flippedMatrix, gstate.projMatrix, 16 * sizeof(float));
const bool invertedY = gstate_c.vpHeight < 0;
if (!invertedY) {
flippedMatrix[1] = -flippedMatrix[1];
flippedMatrix[5] = -flippedMatrix[5];
flippedMatrix[9] = -flippedMatrix[9];
flippedMatrix[13] = -flippedMatrix[13];
}
const bool invertedX = gstate_c.vpWidth < 0;
if (invertedX) {
flippedMatrix[0] = -flippedMatrix[0];
flippedMatrix[4] = -flippedMatrix[4];
flippedMatrix[8] = -flippedMatrix[8];
flippedMatrix[12] = -flippedMatrix[12];
}
ConvertProjMatrixToD3D(flippedMatrix, invertedX, invertedY);
VSSetMatrix(CONST_VS_PROJ, flippedMatrix.getReadPtr());
VSSetFloat(CONST_VS_ROTATION, 0); // We don't use this on any platform in D3D9.
}
if (dirtyUniforms & DIRTY_PROJTHROUGHMATRIX) {
Matrix4x4 proj_through;
proj_through.setOrtho(0.0f, gstate_c.curRTWidth, gstate_c.curRTHeight, 0, 0, 1);
ConvertProjMatrixToD3DThrough(proj_through);
VSSetMatrix(CONST_VS_PROJ_THROUGH, proj_through.getReadPtr());
}
// Transform
if (dirtyUniforms & DIRTY_WORLDMATRIX) {
VSSetMatrix4x3_3(CONST_VS_WORLD, gstate.worldMatrix);
}
if (dirtyUniforms & DIRTY_VIEWMATRIX) {
VSSetMatrix4x3_3(CONST_VS_VIEW, gstate.viewMatrix);
}
if (dirtyUniforms & DIRTY_TEXMATRIX) {
VSSetMatrix4x3_3(CONST_VS_TEXMTX, gstate.tgenMatrix);
}
if (dirtyUniforms & DIRTY_FOGCOEF) {
float fogcoef[2] = {
getFloat24(gstate.fog1),
getFloat24(gstate.fog2),
};
// The PSP just ignores infnan here (ignoring IEEE), so take it down to a valid float.
// Workaround for https://github.com/hrydgard/ppsspp/issues/5384#issuecomment-38365988
if (my_isnanorinf(fogcoef[0])) {
// Not really sure what a sensible value might be, but let's try 64k.
fogcoef[0] = std::signbit(fogcoef[0]) ? -65535.0f : 65535.0f;
}
if (my_isnanorinf(fogcoef[1])) {
fogcoef[1] = std::signbit(fogcoef[1]) ? -65535.0f : 65535.0f;
}
VSSetFloatArray(CONST_VS_FOGCOEF, fogcoef, 2);
}
// TODO: Could even set all bones in one go if they're all dirty.
#ifdef USE_BONE_ARRAY
if (u_bone != 0) {
float allBones[8 * 16];
bool allDirty = true;
for (int i = 0; i < numBones; i++) {
if (dirtyUniforms & (DIRTY_BONEMATRIX0 << i)) {
ConvertMatrix4x3To4x4(allBones + 16 * i, gstate.boneMatrix + 12 * i);
} else {
allDirty = false;
}
}
if (allDirty) {
// Set them all with one call
//glUniformMatrix4fv(u_bone, numBones, GL_FALSE, allBones);
} else {
// Set them one by one. Could try to coalesce two in a row etc but too lazy.
for (int i = 0; i < numBones; i++) {
if (dirtyUniforms & (DIRTY_BONEMATRIX0 << i)) {
//glUniformMatrix4fv(u_bone + i, 1, GL_FALSE, allBones + 16 * i);
}
}
}
}
#else
for (int i = 0; i < 8; i++) {
if (dirtyUniforms & (DIRTY_BONEMATRIX0 << i)) {
VSSetMatrix4x3_3(CONST_VS_BONE0 + 3 * i, gstate.boneMatrix + 12 * i);
}
}
#endif
// Texturing
if (dirtyUniforms & DIRTY_UVSCALEOFFSET) {
float widthFactor = 1.0f;
float heightFactor = 1.0f;
if (gstate_c.textureIsFramebuffer) {
const float invW = 1.0f / (float)gstate_c.curTextureWidth;
const float invH = 1.0f / (float)gstate_c.curTextureHeight;
const int w = gstate.getTextureWidth(0);
const int h = gstate.getTextureHeight(0);
widthFactor = (float)w * invW;
heightFactor = (float)h * invH;
}
float uvscaleoff[4];
uvscaleoff[0] = widthFactor;
uvscaleoff[1] = heightFactor;
uvscaleoff[2] = 0.0f;
uvscaleoff[3] = 0.0f;
VSSetFloatArray(CONST_VS_UVSCALEOFFSET, uvscaleoff, 4);
}
if (dirtyUniforms & DIRTY_DEPTHRANGE) {
// Depth is [0, 1] mapping to [minz, maxz], not too hard.
float vpZScale = gstate.getViewportZScale();
float vpZCenter = gstate.getViewportZCenter();
// These are just the reverse of the formulas in GPUStateUtils.
float halfActualZRange = InfToZero(gstate_c.vpDepthScale != 0.0f ? vpZScale / gstate_c.vpDepthScale : 0.0f);
float minz = -((gstate_c.vpZOffset * halfActualZRange) - vpZCenter) - halfActualZRange;
float viewZScale = halfActualZRange * 2.0f;
float viewZCenter = minz;
float reverseScale = InfToZero(gstate_c.vpDepthScale != 0.0f ? 2.0f * (1.0f / gstate_c.vpDepthScale) : 0.0f);
float reverseTranslate = gstate_c.vpZOffset * 0.5f + 0.5f;
float data[4] = { viewZScale, viewZCenter, reverseTranslate, reverseScale };
VSSetFloatUniform4(CONST_VS_DEPTHRANGE, data);
if (draw_->GetDeviceCaps().clipPlanesSupported >= 1) {
float clip[4] = { 0.0f, 0.0f, reverseScale, 1.0f - reverseTranslate * reverseScale };
// Well, not a uniform, but we treat it as one like other backends.
device_->SetClipPlane(0, clip);
}
}
if (dirtyUniforms & DIRTY_CULLRANGE) {
float minValues[4], maxValues[4];
CalcCullRange(minValues, maxValues, false, false);
VSSetFloatUniform4(CONST_VS_CULLRANGEMIN, minValues);
VSSetFloatUniform4(CONST_VS_CULLRANGEMAX, maxValues);
}
// Lighting
if (dirtyUniforms & DIRTY_AMBIENT) {
VSSetColorUniform3Alpha(CONST_VS_AMBIENT, gstate.ambientcolor, gstate.getAmbientA());
}
if (dirtyUniforms & DIRTY_MATAMBIENTALPHA) {
VSSetColorUniform3Alpha(CONST_VS_MATAMBIENTALPHA, gstate.materialambient, gstate.getMaterialAmbientA());
}
if (dirtyUniforms & DIRTY_MATDIFFUSE) {
VSSetColorUniform3(CONST_VS_MATDIFFUSE, gstate.materialdiffuse);
}
if (dirtyUniforms & DIRTY_MATEMISSIVE) {
VSSetColorUniform3(CONST_VS_MATEMISSIVE, gstate.materialemissive);
}
if (dirtyUniforms & DIRTY_MATSPECULAR) {
VSSetColorUniform3ExtraFloat(CONST_VS_MATSPECULAR, gstate.materialspecular, getFloat24(gstate.materialspecularcoef));
}
for (int i = 0; i < 4; i++) {
if (dirtyUniforms & (DIRTY_LIGHT0 << i)) {
if (gstate.isDirectionalLight(i)) {
VSSetFloat24Uniform3Normalized(CONST_VS_LIGHTPOS + i, &gstate.lpos[i * 3]);
} else {
VSSetFloat24Uniform3(CONST_VS_LIGHTPOS + i, &gstate.lpos[i * 3]);
}
VSSetFloat24Uniform3Normalized(CONST_VS_LIGHTDIR + i, &gstate.ldir[i * 3]);
VSSetFloat24Uniform3(CONST_VS_LIGHTATT + i, &gstate.latt[i * 3]);
float angle_spotCoef[4] = { getFloat24(gstate.lcutoff[i]), getFloat24(gstate.lconv[i]) };
VSSetFloatUniform4(CONST_VS_LIGHTANGLE_SPOTCOEF + i, angle_spotCoef);
VSSetColorUniform3(CONST_VS_LIGHTAMBIENT + i, gstate.lcolor[i * 3]);
VSSetColorUniform3(CONST_VS_LIGHTDIFFUSE + i, gstate.lcolor[i * 3 + 1]);
VSSetColorUniform3(CONST_VS_LIGHTSPECULAR + i, gstate.lcolor[i * 3 + 2]);
}
}
}
ShaderManagerDX9::ShaderManagerDX9(Draw::DrawContext *draw, LPDIRECT3DDEVICE9 device)
: ShaderManagerCommon(draw), device_(device) {
codeBuffer_ = new char[32768];
}
ShaderManagerDX9::~ShaderManagerDX9() {
delete [] codeBuffer_;
}
void ShaderManagerDX9::Clear() {
for (auto iter = fsCache_.begin(); iter != fsCache_.end(); ++iter) {
delete iter->second;
}
for (auto iter = vsCache_.begin(); iter != vsCache_.end(); ++iter) {
delete iter->second;
}
fsCache_.clear();
vsCache_.clear();
DirtyLastShader();
}
void ShaderManagerDX9::ClearShaders() {
Clear();
}
void ShaderManagerDX9::DirtyLastShader() {
// Forget the last shader ID
lastFSID_.set_invalid();
lastVSID_.set_invalid();
lastVShader_ = nullptr;
lastPShader_ = nullptr;
// TODO: Probably not necessary to dirty uniforms here on DX9.
gstate_c.Dirty(DIRTY_ALL_UNIFORMS | DIRTY_VERTEXSHADER_STATE | DIRTY_FRAGMENTSHADER_STATE);
}
VSShader *ShaderManagerDX9::ApplyShader(bool useHWTransform, bool useHWTessellation, u32 vertexType, bool weightsAsFloat, bool useSkinInDecode, const ComputedPipelineState &pipelineState) {
VShaderID VSID;
if (gstate_c.IsDirty(DIRTY_VERTEXSHADER_STATE)) {
gstate_c.Clean(DIRTY_VERTEXSHADER_STATE);
ComputeVertexShaderID(&VSID, vertexType, useHWTransform, useHWTessellation, weightsAsFloat, useSkinInDecode);
} else {
VSID = lastVSID_;
}
FShaderID FSID;
if (gstate_c.IsDirty(DIRTY_FRAGMENTSHADER_STATE)) {
gstate_c.Clean(DIRTY_FRAGMENTSHADER_STATE);
ComputeFragmentShaderID(&FSID, pipelineState, draw_->GetBugs());
} else {
FSID = lastFSID_;
}
// Just update uniforms if this is the same shader as last time.
if (lastVShader_ != nullptr && lastPShader_ != nullptr && VSID == lastVSID_ && FSID == lastFSID_) {
uint64_t dirtyUniforms = gstate_c.GetDirtyUniforms();
if (dirtyUniforms) {
if (dirtyUniforms & psUniforms)
PSUpdateUniforms(dirtyUniforms);
if (dirtyUniforms & vsUniforms)
VSUpdateUniforms(dirtyUniforms);
gstate_c.CleanUniforms();
}
return lastVShader_; // Already all set.
}
VSCache::iterator vsIter = vsCache_.find(VSID);
VSShader *vs = nullptr;
if (vsIter == vsCache_.end()) {
// Vertex shader not in cache. Let's compile it.
std::string genErrorString;
uint32_t attrMask;
uint64_t uniformMask;
VertexShaderFlags flags;
if (GenerateVertexShader(VSID, codeBuffer_, draw_->GetShaderLanguageDesc(), draw_->GetBugs(), &attrMask, &uniformMask, &flags, &genErrorString)) {
vs = new VSShader(device_, VSID, codeBuffer_, useHWTransform);
}
if (!vs || vs->Failed()) {
if (!vs) {
// TODO: Report this?
ERROR_LOG(Log::G3D, "Shader generation failed, falling back to software transform");
} else {
ERROR_LOG(Log::G3D, "Shader compilation failed, falling back to software transform");
}
if (!g_Config.bHideSlowWarnings) {
auto gr = GetI18NCategory(I18NCat::GRAPHICS);
g_OSD.Show(OSDType::MESSAGE_ERROR, gr->T("hardware transform error - falling back to software"), 2.5f);
}
delete vs;
ComputeVertexShaderID(&VSID, vertexType, false, false, weightsAsFloat, useSkinInDecode);
// TODO: Look for existing shader with the appropriate ID, use that instead of generating a new one - however, need to make sure
// that that shader ID is not used when computing the linked shader ID below, because then IDs won't match
// next time and we'll do this over and over...
// Can still work with software transform.
uint32_t attrMask;
uint64_t uniformMask;
bool success = GenerateVertexShader(VSID, codeBuffer_, draw_->GetShaderLanguageDesc(), draw_->GetBugs(), &attrMask, &uniformMask, &flags, &genErrorString);
_assert_(success);
vs = new VSShader(device_, VSID, codeBuffer_, false);
}
vsCache_[VSID] = vs;
} else {
vs = vsIter->second;
}
lastVSID_ = VSID;
FSCache::iterator fsIter = fsCache_.find(FSID);
PSShader *fs;
if (fsIter == fsCache_.end()) {
// Fragment shader not in cache. Let's compile it.
std::string errorString;
uint64_t uniformMask;
FragmentShaderFlags flags;
bool success = GenerateFragmentShader(FSID, codeBuffer_, draw_->GetShaderLanguageDesc(), draw_->GetBugs(), &uniformMask, &flags, &errorString);
// We're supposed to handle all possible cases.
_assert_(success);
fs = new PSShader(device_, FSID, codeBuffer_);
fsCache_[FSID] = fs;
} else {
fs = fsIter->second;
}
lastFSID_ = FSID;
uint64_t dirtyUniforms = gstate_c.GetDirtyUniforms();
if (dirtyUniforms) {
if (dirtyUniforms & psUniforms)
PSUpdateUniforms(dirtyUniforms);
if (dirtyUniforms & vsUniforms)
VSUpdateUniforms(dirtyUniforms);
gstate_c.CleanUniforms();
}
device_->SetPixelShader(fs->shader.Get());
device_->SetVertexShader(vs->shader.Get());
lastPShader_ = fs;
lastVShader_ = vs;
return vs;
}
std::vector<std::string> ShaderManagerDX9::DebugGetShaderIDs(DebugShaderType type) {
std::string id;
std::vector<std::string> ids;
switch (type) {
case SHADER_TYPE_VERTEX:
for (auto iter : vsCache_) {
iter.first.ToString(&id);
ids.push_back(id);
}
break;
case SHADER_TYPE_FRAGMENT:
for (auto iter : fsCache_) {
iter.first.ToString(&id);
ids.push_back(id);
}
break;
case SHADER_TYPE_GEOMETRY:
case SHADER_TYPE_PIPELINE:
case SHADER_TYPE_SAMPLER:
case SHADER_TYPE_TEXTURE:
case SHADER_TYPE_VERTEXLOADER:
break;
}
return ids;
}
std::string ShaderManagerDX9::DebugGetShaderString(std::string id, DebugShaderType type, DebugShaderStringType stringType) {
ShaderID shaderId;
shaderId.FromString(id);
switch (type) {
case SHADER_TYPE_VERTEX:
{
auto iter = vsCache_.find(VShaderID(shaderId));
if (iter == vsCache_.end()) {
return "";
}
return iter->second->GetShaderString(stringType);
}
case SHADER_TYPE_FRAGMENT:
{
auto iter = fsCache_.find(FShaderID(shaderId));
if (iter == fsCache_.end()) {
return "";
}
return iter->second->GetShaderString(stringType);
}
default:
return "N/A";
}
}
-131
View File
@@ -1,131 +0,0 @@
// Copyright (c) 2012- PPSSPP Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0 or later versions.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#pragma once
#include <map>
#include <cstdint>
#include <d3d9.h>
#include <wrl/client.h>
#include "Common/CommonTypes.h"
#include "GPU/Common/VertexShaderGenerator.h"
#include "GPU/Common/FragmentShaderGenerator.h"
#include "GPU/Common/ShaderCommon.h"
#include "GPU/Common/ShaderId.h"
#include "Common/Math/lin/matrix4x4.h"
class PSShader;
class VSShader;
// Real public interface
class PSShader {
public:
PSShader(LPDIRECT3DDEVICE9 device, FShaderID id, const char *code);
~PSShader();
const std::string &source() const { return source_; }
bool Failed() const { return failed_; }
std::string GetShaderString(DebugShaderStringType type) const;
Microsoft::WRL::ComPtr<IDirect3DPixelShader9> shader;
protected:
std::string source_;
bool failed_ = false;
FShaderID id_;
};
class VSShader {
public:
VSShader(LPDIRECT3DDEVICE9 device, VShaderID id, const char *code, bool useHWTransform);
~VSShader();
const std::string &source() const { return source_; }
bool Failed() const { return failed_; }
bool UseHWTransform() const { return useHWTransform_; }
std::string GetShaderString(DebugShaderStringType type) const;
Microsoft::WRL::ComPtr<IDirect3DVertexShader9> shader;
protected:
std::string source_;
bool failed_ = false;
bool useHWTransform_;
VShaderID id_;
};
class ShaderManagerDX9 : public ShaderManagerCommon {
public:
ShaderManagerDX9(Draw::DrawContext *draw, LPDIRECT3DDEVICE9 device);
~ShaderManagerDX9();
void ClearShaders() override;
VSShader *ApplyShader(bool useHWTransform, bool useHWTessellation, u32 vertexType, bool weightsAsFloat, bool useSkinInDecode, const ComputedPipelineState &pipelineState);
void DirtyLastShader() override;
int GetNumVertexShaders() const { return (int)vsCache_.size(); }
int GetNumFragmentShaders() const { return (int)fsCache_.size(); }
void DeviceLost() override { draw_ = nullptr; }
void DeviceRestore(Draw::DrawContext *draw) override { draw_ = draw; }
std::vector<std::string> DebugGetShaderIDs(DebugShaderType type) override;
std::string DebugGetShaderString(std::string id, DebugShaderType type, DebugShaderStringType stringType) override;
private:
void PSUpdateUniforms(u64 dirtyUniforms);
void VSUpdateUniforms(u64 dirtyUniforms);
inline void PSSetColorUniform3Alpha255(int creg, u32 color, u8 alpha);
inline void PSSetColorUniform3(int creg, u32 color);
inline void PSSetFloat(int creg, float value);
inline void PSSetFloatArray(int creg, const float *value, int count);
void VSSetMatrix4x3_3(int creg, const float *m4x3);
inline void VSSetColorUniform3(int creg, u32 color);
inline void VSSetColorUniform3ExtraFloat(int creg, u32 color, float extra);
inline void VSSetColorUniform3Alpha(int creg, u32 color, u8 alpha);
void VSSetMatrix(int creg, const float* pMatrix);
void VSSetFloat(int creg, float value);
void VSSetFloatArray(int creg, const float *value, int count);
void VSSetFloat24Uniform3(int creg, const u32 data[3]);
void VSSetFloat24Uniform3Normalized(int creg, const u32 data[3]);
void VSSetFloatUniform4(int creg, const float data[4]);
void Clear();
LPDIRECT3DDEVICE9 device_;
FShaderID lastFSID_;
VShaderID lastVSID_;
char *codeBuffer_;
VSShader *lastVShader_ = nullptr;
PSShader *lastPShader_ = nullptr;
typedef std::map<FShaderID, PSShader *> FSCache;
FSCache fsCache_;
typedef std::map<VShaderID, VSShader *> VSCache;
VSCache vsCache_;
};
-302
View File
@@ -1,302 +0,0 @@
// Copyright (c) 2012- PPSSPP Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0 or later versions.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include "Common/Profiler/Profiler.h"
#include "Common/GPU/D3D9/D3D9ShaderCompiler.h"
#include "Common/GPU/D3D9/D3D9StateCache.h"
#include "Core/System.h"
#include "Core/Config.h"
#include "GPU/Math3D.h"
#include "GPU/GPUState.h"
#include "GPU/ge_constants.h"
#include "GPU/Directx9/GPU_DX9.h"
#include "GPU/Directx9/ShaderManagerDX9.h"
#include "GPU/Directx9/TextureCacheDX9.h"
#include "GPU/Directx9/FramebufferManagerDX9.h"
static const D3DBLEND dxBlendFactorLookup[(size_t)BlendFactor::COUNT] = {
D3DBLEND_ZERO,
D3DBLEND_ONE,
D3DBLEND_SRCCOLOR,
D3DBLEND_INVSRCCOLOR,
D3DBLEND_DESTCOLOR,
D3DBLEND_INVDESTCOLOR,
D3DBLEND_SRCALPHA,
D3DBLEND_INVSRCALPHA,
D3DBLEND_DESTALPHA,
D3DBLEND_INVDESTALPHA,
D3DBLEND_BLENDFACTOR,
D3DBLEND_INVBLENDFACTOR,
D3DBLEND_BLENDFACTOR,
D3DBLEND_INVBLENDFACTOR,
#if 0 // TODO: Requires D3D9Ex
D3DBLEND_SRCCOLOR2,
D3DBLEND_INVSRCCOLOR2,
D3DBLEND_SRCCOLOR2,
D3DBLEND_INVSRCCOLOR2,
#else
D3DBLEND_FORCE_DWORD,
D3DBLEND_FORCE_DWORD,
#endif
D3DBLEND_FORCE_DWORD,
};
static const D3DBLENDOP dxBlendEqLookup[(size_t)BlendEq::COUNT] = {
D3DBLENDOP_ADD,
D3DBLENDOP_SUBTRACT,
D3DBLENDOP_REVSUBTRACT,
D3DBLENDOP_MIN,
D3DBLENDOP_MAX,
};
static const D3DCULL cullingMode[] = {
D3DCULL_CW,
D3DCULL_CCW,
};
static const D3DCMPFUNC ztests[] = {
D3DCMP_NEVER, D3DCMP_ALWAYS, D3DCMP_EQUAL, D3DCMP_NOTEQUAL,
D3DCMP_LESS, D3DCMP_LESSEQUAL, D3DCMP_GREATER, D3DCMP_GREATEREQUAL,
};
static const D3DSTENCILOP stencilOps[] = {
D3DSTENCILOP_KEEP,
D3DSTENCILOP_ZERO,
D3DSTENCILOP_REPLACE,
D3DSTENCILOP_INVERT,
D3DSTENCILOP_INCRSAT,
D3DSTENCILOP_DECRSAT,
D3DSTENCILOP_KEEP, // reserved
D3DSTENCILOP_KEEP, // reserved
};
void DrawEngineDX9::ApplyDrawState(int prim) {
if (!gstate_c.IsDirty(DIRTY_BLEND_STATE | DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE)) {
// nothing to do
return;
}
// At this point, we know if the vertices are full alpha or not.
// TODO: Set the nearest/linear here (since we correctly know if alpha/color tests are needed)?
if (!gstate.isModeClear()) {
textureCache_->ApplyTexture();
if (fboTexBindState_ == FBO_TEX_COPY_BIND_TEX) {
// Note that this is positions, not UVs, that we need the copy from.
framebufferManager_->BindFramebufferAsColorTexture(1, framebufferManager_->GetCurrentRenderVFB(), BINDFBCOLOR_MAY_COPY, 0);
// If we are rendering at a higher resolution, linear is probably best for the dest color.
device_->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
device_->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
fboTexBound_ = true;
fboTexBindState_ = FBO_TEX_NONE;
}
// TODO: Test texture?
}
bool useBufferedRendering = framebufferManager_->UseBufferedRendering();
if (gstate_c.IsDirty(DIRTY_BLEND_STATE)) {
if (gstate.isModeClear()) {
dxstate.blend.disable();
// Color Mask
u32 mask = 0;
if (gstate.isClearModeColorMask()) {
mask |= 7;
}
if (gstate.isClearModeAlphaMask()) {
mask |= 8;
}
dxstate.colorMask.set(mask);
} else {
pipelineState_.Convert(draw_->GetShaderLanguageDesc().bitwiseOps, gstate_c.Use(GPU_USE_SHADER_BLENDING));
GenericMaskState &maskState = pipelineState_.maskState;
GenericBlendState &blendState = pipelineState_.blendState;
// We ignore the logicState on D3D since there's no support, the emulation of it is blend-and-shader only.
if (pipelineState_.FramebufferRead()) {
ApplyFramebufferRead(&fboTexBindState_);
// The shader takes over the responsibility for blending, so recompute.
ApplyStencilReplaceAndLogicOpIgnoreBlend(blendState.replaceAlphaWithStencil, blendState);
if (fboTexBindState_ == FBO_TEX_COPY_BIND_TEX) {
// Note that this is positions, not UVs, that we need the copy from.
framebufferManager_->BindFramebufferAsColorTexture(1, framebufferManager_->GetCurrentRenderVFB(), BINDFBCOLOR_MAY_COPY | BINDFBCOLOR_UNCACHED, Draw::ALL_LAYERS);
// If we are rendering at a higher resolution, linear is probably best for the dest color.
device_->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
device_->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
fboTexBound_ = true;
fboTexBindState_ = FBO_TEX_NONE;
dirtyRequiresRecheck_ |= DIRTY_BLEND_STATE;
gstate_c.Dirty(DIRTY_BLEND_STATE);
} else if (fboTexBindState_ == FBO_TEX_READ_FRAMEBUFFER) {
// Not supported.
fboTexBindState_ = FBO_TEX_NONE;
}
dirtyRequiresRecheck_ |= DIRTY_FRAGMENTSHADER_STATE;
gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE);
} else {
if (fboTexBound_) {
dirtyRequiresRecheck_ |= DIRTY_FRAGMENTSHADER_STATE;
gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE);
fboTexBound_ = false;
}
}
if (blendState.blendEnabled) {
dxstate.blend.enable();
dxstate.blendSeparate.enable();
dxstate.blendEquation.set(dxBlendEqLookup[(size_t)blendState.eqColor], dxBlendEqLookup[(size_t)blendState.eqAlpha]);
dxstate.blendFunc.set(
dxBlendFactorLookup[(size_t)blendState.srcColor], dxBlendFactorLookup[(size_t)blendState.dstColor],
dxBlendFactorLookup[(size_t)blendState.srcAlpha], dxBlendFactorLookup[(size_t)blendState.dstAlpha]);
if (blendState.dirtyShaderBlendFixValues) {
dirtyRequiresRecheck_ |= DIRTY_SHADERBLEND;
gstate_c.Dirty(DIRTY_SHADERBLEND);
}
if (blendState.useBlendColor) {
dxstate.blendColor.setDWORD(blendState.blendColor);
}
} else {
dxstate.blend.disable();
}
dxstate.colorMask.set(maskState.channelMask);
}
}
if (gstate_c.IsDirty(DIRTY_RASTER_STATE)) {
bool wantCull = !gstate.isModeClear() && prim != GE_PRIM_RECTANGLES && prim > GE_PRIM_LINE_STRIP && gstate.isCullEnabled();
if (wantCull) {
if (gstate.getCullMode() == 1) {
dxstate.cullMode.set(D3DCULL_CCW);
} else {
dxstate.cullMode.set(D3DCULL_CW);
}
} else {
dxstate.cullMode.set(D3DCULL_NONE);
}
if (gstate.isModeClear()) {
// Well, probably doesn't matter...
dxstate.shadeMode.set(D3DSHADE_GOURAUD);
} else {
dxstate.shadeMode.set(gstate.getShadeMode() == GE_SHADE_GOURAUD ? D3DSHADE_GOURAUD : D3DSHADE_FLAT);
}
// We use fixed-function user clipping on D3D9, where available, for negative Z clipping.
if (draw_->GetDeviceCaps().clipPlanesSupported >= 1) {
bool wantClip = !gstate.isModeThrough() && gstate_c.submitType == SubmitType::DRAW;
dxstate.clipPlaneEnable.set(wantClip ? 1 : 0);
}
}
if (gstate_c.IsDirty(DIRTY_DEPTHSTENCIL_STATE)) {
GenericStencilFuncState stencilState;
ConvertStencilFuncState(stencilState);
// Set Stencil/Depth
if (gstate.isModeClear()) {
// Depth Test
dxstate.depthTest.enable();
dxstate.depthFunc.set(D3DCMP_ALWAYS);
dxstate.depthWrite.set(gstate.isClearModeDepthMask());
// Stencil Test
bool alphaMask = gstate.isClearModeAlphaMask();
if (alphaMask) {
dxstate.stencilTest.enable();
dxstate.stencilOp.set(D3DSTENCILOP_REPLACE, D3DSTENCILOP_REPLACE, D3DSTENCILOP_REPLACE);
dxstate.stencilFunc.set(D3DCMP_ALWAYS);
dxstate.stencilRef.set(0xFF);
dxstate.stencilCompareMask.set(0xFF);
dxstate.stencilWriteMask.set(stencilState.writeMask);
} else {
dxstate.stencilTest.disable();
}
} else {
// Depth Test
if (!IsDepthTestEffectivelyDisabled()) {
dxstate.depthTest.enable();
dxstate.depthFunc.set(ztests[gstate.getDepthTestFunction()]);
dxstate.depthWrite.set(gstate.isDepthWriteEnabled());
UpdateEverUsedEqualDepth(gstate.getDepthTestFunction());
} else {
dxstate.depthTest.disable();
}
// Stencil Test
if (stencilState.enabled) {
dxstate.stencilTest.enable();
dxstate.stencilFunc.set(ztests[stencilState.testFunc]);
dxstate.stencilRef.set(stencilState.testRef);
dxstate.stencilCompareMask.set(stencilState.testMask);
dxstate.stencilOp.set(stencilOps[stencilState.sFail], stencilOps[stencilState.zFail], stencilOps[stencilState.zPass]);
dxstate.stencilWriteMask.set(stencilState.writeMask);
// Nasty special case for Spongebob and similar where it tries to write zeros to alpha/stencil during
// depth-fail. We can't write to alpha then because the pixel is killed. However, we can invert the depth
// test and modify the alpha function...
if (SpongebobDepthInverseConditions(stencilState)) {
dxstate.blend.set(true);
dxstate.blendEquation.set(D3DBLENDOP_ADD, D3DBLENDOP_ADD);
dxstate.blendFunc.set(D3DBLEND_ZERO, D3DBLEND_ZERO, D3DBLEND_ZERO, D3DBLEND_ZERO);
dxstate.colorMask.set(8);
dxstate.depthFunc.set(D3DCMP_LESS);
dxstate.stencilFunc.set(D3DCMP_ALWAYS);
// Invert
dxstate.stencilOp.set(D3DSTENCILOP_ZERO, D3DSTENCILOP_KEEP, D3DSTENCILOP_ZERO);
dirtyRequiresRecheck_ |= DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE;
gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE);
}
} else {
dxstate.stencilTest.disable();
}
}
}
if (gstate_c.IsDirty(DIRTY_VIEWPORTSCISSOR_STATE)) {
ViewportAndScissor vpAndScissor;
ConvertViewportAndScissor(useBufferedRendering,
framebufferManager_->GetRenderWidth(), framebufferManager_->GetRenderHeight(),
framebufferManager_->GetTargetBufferWidth(), framebufferManager_->GetTargetBufferHeight(),
vpAndScissor);
UpdateCachedViewportState(vpAndScissor);
dxstate.scissorTest.enable();
dxstate.scissorRect.set(vpAndScissor.scissorX, vpAndScissor.scissorY, vpAndScissor.scissorX + vpAndScissor.scissorW, vpAndScissor.scissorY + vpAndScissor.scissorH);
float depthMin = vpAndScissor.depthRangeMin;
float depthMax = vpAndScissor.depthRangeMax;
dxstate.viewport.set(vpAndScissor.viewportX, vpAndScissor.viewportY, vpAndScissor.viewportW, vpAndScissor.viewportH, depthMin, depthMax);
}
gstate_c.Clean(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_BLEND_STATE);
gstate_c.Dirty(dirtyRequiresRecheck_);
dirtyRequiresRecheck_ = 0;
}
void DrawEngineDX9::ApplyDrawStateLate() {
// At this point, we know if the vertices are full alpha or not.
// TODO: Set the nearest/linear here (since we correctly know if alpha/color tests are needed)?
}
-4
View File
@@ -1,4 +0,0 @@
#pragma once
#include "helper/global.h"
#include "ext/native/gfx/dx_state.h"
-445
View File
@@ -1,445 +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 <algorithm>
#include <cstring>
#include <wrl/client.h>
#include "Common/TimeUtil.h"
#include "Core/MemMap.h"
#include "GPU/ge_constants.h"
#include "GPU/GPUState.h"
#include "GPU/Directx9/TextureCacheDX9.h"
#include "GPU/Directx9/FramebufferManagerDX9.h"
#include "GPU/Directx9/ShaderManagerDX9.h"
#include "Common/GPU/D3D9/D3D9StateCache.h"
#include "GPU/Common/TextureShaderCommon.h"
#include "GPU/Common/FramebufferManagerCommon.h"
#include "GPU/Common/TextureDecoder.h"
#include "Core/Config.h"
#include "ext/xxhash.h"
#include "Common/Math/math_util.h"
// NOTE: In the D3D backends, we flip R and B in the shaders, so while these look wrong, they're OK.
using Microsoft::WRL::ComPtr;
Draw::DataFormat FromD3D9Format(u32 fmt) {
switch (fmt) {
case D3DFMT_A4R4G4B4: return Draw::DataFormat::B4G4R4A4_UNORM_PACK16;
case D3DFMT_A1R5G5B5: return Draw::DataFormat::A1R5G5B5_UNORM_PACK16;
case D3DFMT_R5G6B5: return Draw::DataFormat::R5G6B5_UNORM_PACK16;
case D3DFMT_A8: return Draw::DataFormat::R8_UNORM;
case D3DFMT_A8R8G8B8: default: return Draw::DataFormat::R8G8B8A8_UNORM;
}
}
D3DFORMAT ToD3D9Format(Draw::DataFormat fmt) {
switch (fmt) {
case Draw::DataFormat::BC1_RGBA_UNORM_BLOCK: return D3DFMT_DXT1;
case Draw::DataFormat::BC2_UNORM_BLOCK: return D3DFMT_DXT3;
case Draw::DataFormat::BC3_UNORM_BLOCK: return D3DFMT_DXT5;
case Draw::DataFormat::R8G8B8A8_UNORM: return D3DFMT_A8R8G8B8;
default: _dbg_assert_(false); return D3DFMT_A8R8G8B8;
}
}
#define INVALID_TEX (LPDIRECT3DTEXTURE9)(-1)
static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = {
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
{ 0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
D3DDECL_END()
};
TextureCacheDX9::TextureCacheDX9(Draw::DrawContext *draw, Draw2D *draw2D)
: TextureCacheCommon(draw, draw2D) {
lastBoundTexture = INVALID_TEX;
device_ = (LPDIRECT3DDEVICE9)draw->GetNativeObject(Draw::NativeObject::DEVICE);
deviceEx_ = (LPDIRECT3DDEVICE9EX)draw->GetNativeObject(Draw::NativeObject::DEVICE_EX);
}
TextureCacheDX9::~TextureCacheDX9() {
Clear(true);
}
void TextureCacheDX9::InitDeviceObjects() {
D3DCAPS9 pCaps;
ZeroMemory(&pCaps, sizeof(pCaps));
HRESULT result = 0;
if (deviceEx_) {
result = deviceEx_->GetDeviceCaps(&pCaps);
} else {
result = device_->GetDeviceCaps(&pCaps);
}
if (FAILED(result)) {
WARN_LOG(Log::G3D, "Failed to get the device caps!");
maxAnisotropyLevel = 16;
} else {
maxAnisotropyLevel = pCaps.MaxAnisotropy;
}
nextTexture_ = nullptr;
device_->CreateVertexDeclaration(g_FramebufferVertexElements, &pFramebufferVertexDecl);
}
void TextureCacheDX9::SetFramebufferManager(FramebufferManagerDX9 *fbManager) {
framebufferManager_ = fbManager;
}
void TextureCacheDX9::ReleaseTexture(TexCacheEntry *entry, bool delete_them) {
LPDIRECT3DBASETEXTURE9 &texture = DxTex(entry);
if (texture) {
texture->Release();
texture = nullptr;
}
}
void TextureCacheDX9::ForgetLastTexture() {
lastBoundTexture = INVALID_TEX;
}
static D3DFORMAT getClutDestFormat(GEPaletteFormat format) {
switch (format) {
case GE_CMODE_16BIT_ABGR4444:
return D3DFMT_A4R4G4B4;
case GE_CMODE_16BIT_ABGR5551:
return D3DFMT_A1R5G5B5;
case GE_CMODE_16BIT_BGR5650:
return D3DFMT_R5G6B5;
case GE_CMODE_32BIT_ABGR8888:
return D3DFMT_A8R8G8B8;
}
// Should never be here !
return D3DFMT_A8R8G8B8;
}
void TextureCacheDX9::ApplySamplingParams(const SamplerCacheKey &key) {
D3DTEXTUREFILTERTYPE minFilt = (false ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR);
dxstate.texMinFilter.set(key.minFilt ? minFilt : D3DTEXF_POINT);
dxstate.texMipFilter.set(key.mipFilt ? D3DTEXF_LINEAR : D3DTEXF_POINT);
dxstate.texMagFilter.set(key.magFilt ? D3DTEXF_LINEAR : D3DTEXF_POINT);
// DX9 mip levels are .. odd. The "max level" sets the LARGEST mip to use.
// We can enforce only the top mip level by setting a massive negative lod bias.
if (!key.mipEnable) {
dxstate.texMaxMipLevel.set(0);
dxstate.texMipLodBias.set(-100.0f);
} else {
dxstate.texMipLodBias.set((float)key.lodBias / 256.0f);
dxstate.texMaxMipLevel.set(key.minLevel / 256);
}
dxstate.texAddressU.set(key.sClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP);
dxstate.texAddressV.set(key.tClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP);
}
void TextureCacheDX9::StartFrame() {
TextureCacheCommon::StartFrame();
if (gstate_c.Use(GPU_USE_ANISOTROPY)) {
// Just take the opportunity to set the global aniso level here, once per frame.
DWORD aniso = 1 << g_Config.iAnisotropyLevel;
DWORD anisotropyLevel = aniso > maxAnisotropyLevel ? maxAnisotropyLevel : aniso;
device_->SetSamplerState(0, D3DSAMP_MAXANISOTROPY, anisotropyLevel);
}
}
void TextureCacheDX9::UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple) {
const u32 clutBaseBytes = clutBase * (clutFormat == GE_CMODE_32BIT_ABGR8888 ? sizeof(u32) : sizeof(u16));
// Technically, these extra bytes weren't loaded, but hopefully it was loaded earlier.
// If not, we're going to hash random data, which hopefully doesn't cause a performance issue.
//
// TODO: Actually, this seems like a hack. The game can upload part of a CLUT and reference other data.
// clutTotalBytes_ is the last amount uploaded. We should hash clutMaxBytes_, but this will often hash
// unrelated old entries for small palettes.
// Adding clutBaseBytes may just be mitigating this for some usage patterns.
const u32 clutExtendedBytes = std::min(clutTotalBytes_ + clutBaseBytes, clutMaxBytes_);
if (replacer_.Enabled())
clutHash_ = XXH32((const char *)clutBufRaw_, clutExtendedBytes, 0xC0108888);
else
clutHash_ = XXH3_64bits((const char *)clutBufRaw_, clutExtendedBytes) & 0xFFFFFFFF;
clutBuf_ = clutBufRaw_;
// Special optimization: fonts typically draw clut4 with just alpha values in a single color.
clutAlphaLinear_ = false;
clutAlphaLinearColor_ = 0;
if (clutFormat == GE_CMODE_16BIT_ABGR4444 && clutIndexIsSimple) {
const u16_le *clut = GetCurrentClut<u16_le>();
clutAlphaLinear_ = true;
clutAlphaLinearColor_ = clut[15] & 0x0FFF;
for (int i = 0; i < 16; ++i) {
u16 step = clutAlphaLinearColor_ | (i << 12);
if (clut[i] != step) {
clutAlphaLinear_ = false;
break;
}
}
}
clutLastFormat_ = gstate.clutformat;
}
void TextureCacheDX9::BindTexture(TexCacheEntry *entry) {
if (!entry) {
device_->SetTexture(0, nullptr);
return;
}
IDirect3DBaseTexture9 *texture = DxTex(entry);
if (texture != lastBoundTexture) {
device_->SetTexture(0, texture);
lastBoundTexture = texture;
}
int maxLevel = (entry->status & TexCacheEntry::STATUS_NO_MIPS) ? 0 : entry->maxLevel;
SamplerCacheKey samplerKey = GetSamplingParams(maxLevel, entry);
ApplySamplingParams(samplerKey);
}
void TextureCacheDX9::Unbind() {
device_->SetTexture(0, nullptr);
ForgetLastTexture();
}
void TextureCacheDX9::BindAsClutTexture(Draw::Texture *tex, bool smooth) {
LPDIRECT3DBASETEXTURE9 clutTexture = (LPDIRECT3DBASETEXTURE9)draw_->GetNativeObject(Draw::NativeObject::TEXTURE_VIEW, tex);
device_->SetTexture(1, clutTexture);
device_->SetSamplerState(1, D3DSAMP_MINFILTER, smooth ? D3DTEXF_LINEAR : D3DTEXF_POINT);
device_->SetSamplerState(1, D3DSAMP_MAGFILTER, smooth ? D3DTEXF_LINEAR : D3DTEXF_POINT);
device_->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
}
void TextureCacheDX9::BuildTexture(TexCacheEntry *const entry) {
BuildTexturePlan plan;
if (!PrepareBuildTexture(plan, entry)) {
// We're screwed?
return;
}
D3DFORMAT dstFmt = GetDestFormat(GETextureFormat(entry->format), gstate.getClutPaletteFormat());
if (plan.doReplace) {
dstFmt = ToD3D9Format(plan.replaced->Format());
} else if (plan.scaleFactor > 1 || plan.saveTexture) {
dstFmt = D3DFMT_A8R8G8B8;
} else if (plan.decodeToClut8) {
dstFmt = D3DFMT_A8;
}
int levels;
LPDIRECT3DBASETEXTURE9 &texture = DxTex(entry);
D3DPOOL pool = D3DPOOL_DEFAULT;
int usage = D3DUSAGE_DYNAMIC;
int tw;
int th;
plan.GetMipSize(0, &tw, &th);
HRESULT hr;
if (plan.depth == 1) {
// We don't yet have mip generation, so clamp the number of levels to the ones we can load directly.
levels = std::min(plan.levelsToCreate, plan.levelsToLoad);
LPDIRECT3DTEXTURE9 tex;
hr = device_->CreateTexture(tw, th, levels, usage, dstFmt, pool, &tex, nullptr);
texture = tex;
} else {
LPDIRECT3DVOLUMETEXTURE9 tex;
hr = device_->CreateVolumeTexture(tw, th, plan.depth, 1, usage, dstFmt, pool, &tex, nullptr);
texture = tex;
levels = 1;
}
if (FAILED(hr)) {
INFO_LOG(Log::G3D, "Failed to create D3D texture: %dx%d", tw, th);
ReleaseTexture(entry, true);
return;
}
if (!texture) {
// What to do here?
return;
}
if (plan.depth == 1) {
// Regular loop.
for (int i = 0; i < levels; i++) {
int dstLevel = i;
HRESULT result;
uint32_t lockFlag = dstLevel == 0 ? D3DLOCK_DISCARD : 0; // Can only discard the top level
D3DLOCKED_RECT rect{};
result = ((LPDIRECT3DTEXTURE9)texture)->LockRect(dstLevel, &rect, NULL, lockFlag);
if (FAILED(result)) {
ERROR_LOG(Log::G3D, "Failed to lock D3D 2D texture at level %d: %dx%d", i, plan.w, plan.h);
return;
}
uint8_t *data = (uint8_t *)rect.pBits;
int stride = rect.Pitch;
LoadTextureLevel(*entry, data, 0, stride, plan, (i == 0) ? plan.baseLevelSrc : i, FromD3D9Format(dstFmt), TexDecodeFlags{});
((LPDIRECT3DTEXTURE9)texture)->UnlockRect(dstLevel);
}
} else {
// 3D loop.
D3DLOCKED_BOX box;
HRESULT result = ((LPDIRECT3DVOLUMETEXTURE9)texture)->LockBox(0, &box, nullptr, D3DLOCK_DISCARD);
if (FAILED(result)) {
ERROR_LOG(Log::G3D, "Failed to lock D3D 2D texture: %dx%dx%d", plan.w, plan.h, plan.depth);
return;
}
uint8_t *data = (uint8_t *)box.pBits;
int stride = box.RowPitch;
for (int i = 0; i < plan.depth; i++) {
LoadTextureLevel(*entry, data, 0, stride, plan, (i == 0) ? plan.baseLevelSrc : i, FromD3D9Format(dstFmt), TexDecodeFlags{});
data += box.SlicePitch;
}
((LPDIRECT3DVOLUMETEXTURE9)texture)->UnlockBox(0);
}
// Signal that we support depth textures so use it as one.
if (plan.depth > 1) {
entry->status |= TexCacheEntry::STATUS_3D;
}
if (plan.doReplace) {
entry->SetAlphaStatus(TexCacheEntry::TexStatus(plan.replaced->AlphaStatus()));
if (!Draw::DataFormatIsBlockCompressed(plan.replaced->Format(), nullptr)) {
entry->status |= TexCacheEntry::STATUS_BGRA;
}
} else {
entry->status |= TexCacheEntry::STATUS_BGRA;
}
}
D3DFORMAT TextureCacheDX9::GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const {
switch (format) {
case GE_TFMT_CLUT4:
case GE_TFMT_CLUT8:
case GE_TFMT_CLUT16:
case GE_TFMT_CLUT32:
return getClutDestFormat(clutFormat);
case GE_TFMT_4444:
return D3DFMT_A4R4G4B4;
case GE_TFMT_5551:
return D3DFMT_A1R5G5B5;
case GE_TFMT_5650:
return D3DFMT_R5G6B5;
case GE_TFMT_8888:
case GE_TFMT_DXT1:
case GE_TFMT_DXT3:
case GE_TFMT_DXT5:
default:
return D3DFMT_A8R8G8B8;
}
}
bool TextureCacheDX9::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level, bool *isFramebuffer) {
SetTexture();
if (!nextTexture_) {
return GetCurrentFramebufferTextureDebug(buffer, isFramebuffer);
}
ApplyTexture();
ComPtr<IDirect3DBaseTexture9> baseTex;
ComPtr<IDirect3DTexture9> tex;
ComPtr<IDirect3DSurface9> offscreen;
HRESULT hr;
bool success = false;
hr = device_->GetTexture(0, &baseTex);
if (SUCCEEDED(hr) && baseTex != NULL) {
hr = baseTex.As(&tex);
if (SUCCEEDED(hr)) {
D3DSURFACE_DESC desc;
D3DLOCKED_RECT locked;
tex->GetLevelDesc(level, &desc);
RECT rect = { 0, 0, (LONG)desc.Width, (LONG)desc.Height };
hr = tex->LockRect(level, &locked, &rect, D3DLOCK_READONLY);
// If it fails, this means it's a render-to-texture, so we have to get creative.
if (FAILED(hr)) {
ComPtr<IDirect3DSurface9> renderTarget;
hr = tex->GetSurfaceLevel(level, &renderTarget);
if (renderTarget && SUCCEEDED(hr)) {
hr = device_->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &offscreen, NULL);
if (SUCCEEDED(hr)) {
hr = device_->GetRenderTargetData(renderTarget.Get(), offscreen.Get());
if (SUCCEEDED(hr)) {
hr = offscreen->LockRect(&locked, &rect, D3DLOCK_READONLY);
}
}
}
*isFramebuffer = true;
} else {
*isFramebuffer = false;
}
if (SUCCEEDED(hr)) {
GPUDebugBufferFormat fmt;
int pixelSize;
switch (desc.Format) {
case D3DFMT_A1R5G5B5:
fmt = gstate_c.bgraTexture ? GPU_DBG_FORMAT_5551 : GPU_DBG_FORMAT_5551_BGRA;
pixelSize = 2;
break;
case D3DFMT_A4R4G4B4:
fmt = gstate_c.bgraTexture ? GPU_DBG_FORMAT_4444 : GPU_DBG_FORMAT_4444_BGRA;
pixelSize = 2;
break;
case D3DFMT_R5G6B5:
fmt = gstate_c.bgraTexture ? GPU_DBG_FORMAT_565 : GPU_DBG_FORMAT_565_BGRA;
pixelSize = 2;
break;
case D3DFMT_A8R8G8B8:
fmt = gstate_c.bgraTexture ? GPU_DBG_FORMAT_8888 : GPU_DBG_FORMAT_8888_BGRA;
pixelSize = 4;
break;
default:
fmt = GPU_DBG_FORMAT_INVALID;
break;
}
if (fmt != GPU_DBG_FORMAT_INVALID) {
buffer.Allocate(locked.Pitch / pixelSize, desc.Height, fmt, false);
memcpy(buffer.GetData(), locked.pBits, locked.Pitch * desc.Height);
success = true;
} else {
success = false;
}
if (offscreen) {
offscreen->UnlockRect();
} else {
tex->UnlockRect(level);
}
}
}
}
return success;
}
void *TextureCacheDX9::GetNativeTextureView(const TexCacheEntry *entry, bool flat) const {
LPDIRECT3DBASETEXTURE9 tex = DxTex(entry);
return (void *)tex;
}
-80
View File
@@ -1,80 +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 <d3d9.h>
#include <wrl/client.h>
#include "GPU/GPU.h"
#include "GPU/GPUCommon.h"
#include "GPU/Common/TextureCacheCommon.h"
struct VirtualFramebuffer;
class TextureShaderCache;
class FramebufferManagerDX9;
class ShaderManagerDX9;
class TextureCacheDX9 : public TextureCacheCommon {
public:
TextureCacheDX9(Draw::DrawContext *draw, Draw2D *draw2D);
~TextureCacheDX9();
void StartFrame() override;
void SetFramebufferManager(FramebufferManagerDX9 *fbManager);
void ForgetLastTexture() override;
bool GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level, bool *isFramebuffer) override;
void DeviceLost() override { draw_ = nullptr; }
void DeviceRestore(Draw::DrawContext *draw) override { draw_ = draw; }
void InitDeviceObjects();
protected:
void BindTexture(TexCacheEntry *entry) override;
void Unbind() override;
void ReleaseTexture(TexCacheEntry *entry, bool delete_them) override;
void BindAsClutTexture(Draw::Texture *tex, bool smooth) override;
void *GetNativeTextureView(const TexCacheEntry *entry, bool flat) const override;
private:
void ApplySamplingParams(const SamplerCacheKey &key) override;
D3DFORMAT GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const;
void UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple) override;
void BuildTexture(TexCacheEntry *const entry) override;
static LPDIRECT3DBASETEXTURE9 &DxTex(const TexCacheEntry *entry) {
return *(LPDIRECT3DBASETEXTURE9 *)&entry->texturePtr;
}
Microsoft::WRL::ComPtr<IDirect3DDevice9> device_;
Microsoft::WRL::ComPtr<IDirect3DDevice9Ex> deviceEx_;
Microsoft::WRL::ComPtr<IDirect3DVertexDeclaration9> pFramebufferVertexDecl;
IDirect3DBaseTexture9 *lastBoundTexture = nullptr;
float maxAnisotropyLevel;
FramebufferManagerDX9 *framebufferManagerDX9_ = nullptr;
};
static D3DFORMAT getClutDestFormat(GEPaletteFormat format);
-10
View File
@@ -31,10 +31,6 @@
#include "GPU/Vulkan/GPU_Vulkan.h"
#include "GPU/Software/SoftGpu.h"
#if PPSSPP_API(D3D9)
#include "GPU/Directx9/GPU_DX9.h"
#endif
#if PPSSPP_API(D3D11)
#include "GPU/D3D11/GPU_D3D11.h"
#endif
@@ -66,12 +62,6 @@ static GPUCommon *CreateGPUCore(GPUCore gpuCore, GraphicsContext *ctx, Draw::Dra
#endif
case GPUCORE_SOFTWARE:
return new SoftGPU(ctx, draw);
case GPUCORE_DIRECTX9:
#if PPSSPP_API(D3D9)
return new GPU_DX9(ctx, draw);
#else
return nullptr;
#endif
case GPUCORE_DIRECTX11:
#if PPSSPP_API(D3D11)
return new GPU_D3D11(ctx, draw);
+1 -12
View File
@@ -389,11 +389,6 @@
<ClInclude Include="Debugger\RecordFormat.h" />
<ClInclude Include="Debugger\State.h" />
<ClInclude Include="Debugger\Stepping.h" />
<ClInclude Include="Directx9\FramebufferManagerDX9.h" />
<ClInclude Include="Directx9\GPU_DX9.h" />
<ClInclude Include="Directx9\ShaderManagerDX9.h" />
<ClInclude Include="Directx9\TextureCacheDX9.h" />
<ClInclude Include="Directx9\DrawEngineDX9.h" />
<ClInclude Include="ge_constants.h" />
<ClInclude Include="GeDisasm.h" />
<ClInclude Include="GLES\FragmentTestCacheGLES.h">
@@ -538,12 +533,6 @@
<ClCompile Include="Debugger\Record.cpp" />
<ClCompile Include="Debugger\State.cpp" />
<ClCompile Include="Debugger\Stepping.cpp" />
<ClCompile Include="Directx9\FramebufferManagerDX9.cpp" />
<ClCompile Include="Directx9\GPU_DX9.cpp" />
<ClCompile Include="Directx9\ShaderManagerDX9.cpp" />
<ClCompile Include="Directx9\StateMappingDX9.cpp" />
<ClCompile Include="Directx9\TextureCacheDX9.cpp" />
<ClCompile Include="Directx9\DrawEngineDX9.cpp" />
<ClCompile Include="GeDisasm.cpp" />
<ClCompile Include="GeConstants.cpp" />
<ClCompile Include="GLES\FragmentTestCacheGLES.cpp">
@@ -693,4 +682,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>
-36
View File
@@ -10,9 +10,6 @@
<Filter Include="Common">
<UniqueIdentifier>{21783292-4dd7-447b-af93-356cd2eaa4d6}</UniqueIdentifier>
</Filter>
<Filter Include="DirectX9">
<UniqueIdentifier>{88629970-4774-4122-b031-2128244b795c}</UniqueIdentifier>
</Filter>
<Filter Include="Debugger">
<UniqueIdentifier>{0cbddc00-4aa3-41d0-bed2-a454d37f838e}</UniqueIdentifier>
</Filter>
@@ -60,18 +57,6 @@
<ClInclude Include="GLES\DrawEngineGLES.h">
<Filter>GLES</Filter>
</ClInclude>
<ClInclude Include="Directx9\GPU_DX9.h">
<Filter>DirectX9</Filter>
</ClInclude>
<ClInclude Include="Directx9\DrawEngineDX9.h">
<Filter>DirectX9</Filter>
</ClInclude>
<ClInclude Include="Directx9\TextureCacheDX9.h">
<Filter>DirectX9</Filter>
</ClInclude>
<ClInclude Include="Directx9\ShaderManagerDX9.h">
<Filter>DirectX9</Filter>
</ClInclude>
<ClInclude Include="Common\IndexGenerator.h">
<Filter>Common</Filter>
</ClInclude>
@@ -225,9 +210,6 @@
<ClInclude Include="Common\FramebufferManagerCommon.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="Directx9\FramebufferManagerDX9.h">
<Filter>DirectX9</Filter>
</ClInclude>
<ClInclude Include="ge_constants.h">
<Filter>Common</Filter>
</ClInclude>
@@ -314,21 +296,6 @@
<ClCompile Include="GLES\DrawEngineGLES.cpp">
<Filter>GLES</Filter>
</ClCompile>
<ClCompile Include="Directx9\GPU_DX9.cpp">
<Filter>DirectX9</Filter>
</ClCompile>
<ClCompile Include="Directx9\DrawEngineDX9.cpp">
<Filter>DirectX9</Filter>
</ClCompile>
<ClCompile Include="Directx9\TextureCacheDX9.cpp">
<Filter>DirectX9</Filter>
</ClCompile>
<ClCompile Include="Directx9\StateMappingDX9.cpp">
<Filter>DirectX9</Filter>
</ClCompile>
<ClCompile Include="Directx9\ShaderManagerDX9.cpp">
<Filter>DirectX9</Filter>
</ClCompile>
<ClCompile Include="Common\IndexGenerator.cpp">
<Filter>Common</Filter>
</ClCompile>
@@ -491,9 +458,6 @@
<ClCompile Include="Common\FramebufferManagerCommon.cpp">
<Filter>Common</Filter>
</ClCompile>
<ClCompile Include="Directx9\FramebufferManagerDX9.cpp">
<Filter>DirectX9</Filter>
</ClCompile>
<ClCompile Include="GeConstants.cpp">
<Filter>Common</Filter>
</ClCompile>
-1
View File
@@ -634,7 +634,6 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) {
case GPUBackend::OPENGL:
outputFlags |= OutputFlags::BACKBUFFER_FLIPPED;
break;
case GPUBackend::DIRECT3D9:
case GPUBackend::DIRECT3D11:
outputFlags |= OutputFlags::POSITION_FLIPPED;
break;
+2 -8
View File
@@ -607,11 +607,6 @@ void SystemInfoScreen::CreateDeviceInfoTab(UI::LinearLayout *deviceSpecs) {
if (GetGPUBackend() != GPUBackend::VULKAN) {
gpuInfo->Add(new InfoItem(si->T("Driver Version"), System_GetProperty(SYSPROP_GPUDRIVER_VERSION)));
}
#if !PPSSPP_PLATFORM(UWP)
if (GetGPUBackend() == GPUBackend::DIRECT3D9) {
gpuInfo->Add(new InfoItem(si->T("D3DCompiler Version"), StringFromFormat("%d", GetD3DCompilerVersion())));
}
#endif
#endif
if (GetGPUBackend() == GPUBackend::OPENGL) {
gpuInfo->Add(new InfoItem(si->T("Core Context"), gl_extensions.IsCoreContext ? di->T("Active") : di->T("Inactive")));
@@ -1282,14 +1277,13 @@ void TouchTestScreen::CreateViews() {
root_->Add(theTwo);
#if !PPSSPP_PLATFORM(UWP)
static const char *renderingBackend[] = { "OpenGL", "Direct3D 9", "Direct3D 11", "Vulkan" };
static const char *renderingBackend[] = { "OpenGL", "(n/a)", "Direct3D 11", "Vulkan" };
PopupMultiChoice *renderingBackendChoice = root_->Add(new PopupMultiChoice(&g_Config.iGPUBackend, gr->T("Backend"), renderingBackend, (int)GPUBackend::OPENGL, ARRAY_SIZE(renderingBackend), I18NCat::GRAPHICS, screenManager()));
renderingBackendChoice->OnChoice.Handle(this, &TouchTestScreen::OnRenderingBackend);
if (!g_Config.IsBackendEnabled(GPUBackend::OPENGL))
renderingBackendChoice->HideChoice((int)GPUBackend::OPENGL);
if (!g_Config.IsBackendEnabled(GPUBackend::DIRECT3D9))
renderingBackendChoice->HideChoice((int)GPUBackend::DIRECT3D9);
renderingBackendChoice->HideChoice(1); // previously D3D9
if (!g_Config.IsBackendEnabled(GPUBackend::DIRECT3D11))
renderingBackendChoice->HideChoice((int)GPUBackend::DIRECT3D11);
if (!g_Config.IsBackendEnabled(GPUBackend::VULKAN))
-3
View File
@@ -293,9 +293,6 @@ void EmuScreen::ProcessGameBoot(const Path &filename) {
coreParam.gpuCore = GPUCORE_GLES;
break;
#endif
case GPUBackend::DIRECT3D9:
coreParam.gpuCore = GPUCORE_DIRECTX9;
break;
case GPUBackend::VULKAN:
coreParam.gpuCore = GPUCORE_VULKAN;
break;
+1 -5
View File
@@ -265,15 +265,11 @@ void GameSettingsScreen::CreateGraphicsSettings(UI::ViewGroup *graphicsSettings)
#if !PPSSPP_PLATFORM(UWP)
static const char *renderingBackend[] = { "OpenGL", "Direct3D 9", "Direct3D 11", "Vulkan" };
PopupMultiChoice *renderingBackendChoice = graphicsSettings->Add(new PopupMultiChoice(&g_Config.iGPUBackend, gr->T("Backend"), renderingBackend, (int)GPUBackend::OPENGL, ARRAY_SIZE(renderingBackend), I18NCat::GRAPHICS, screenManager()));
if (g_Config.iGPUBackend != (int)GPUBackend::DIRECT3D9 && !draw->GetDeviceCaps().supportsD3D9) {
renderingBackendChoice->HideChoice(1);
}
renderingBackendChoice->HideChoice(1);
renderingBackendChoice->OnChoice.Handle(this, &GameSettingsScreen::OnRenderingBackend);
if (!g_Config.IsBackendEnabled(GPUBackend::OPENGL))
renderingBackendChoice->HideChoice((int)GPUBackend::OPENGL);
if (!g_Config.IsBackendEnabled(GPUBackend::DIRECT3D9))
renderingBackendChoice->HideChoice((int)GPUBackend::DIRECT3D9);
if (!g_Config.IsBackendEnabled(GPUBackend::DIRECT3D11))
renderingBackendChoice->HideChoice((int)GPUBackend::DIRECT3D11);
if (!g_Config.IsBackendEnabled(GPUBackend::VULKAN))
+2 -15
View File
@@ -30,7 +30,6 @@
#include "Windows/GPU/WindowsGLContext.h"
#endif
#include "Windows/GPU/WindowsVulkanContext.h"
#include "Windows/GPU/D3D9Context.h"
#include "Windows/GPU/D3D11Context.h"
enum class EmuThreadState {
@@ -132,9 +131,6 @@ bool CreateGraphicsBackend(std::string *error_message, GraphicsContext **ctx) {
graphicsContext = new WindowsGLContext();
break;
#endif
case (int)GPUBackend::DIRECT3D9:
graphicsContext = new D3D9Context();
break;
case (int)GPUBackend::DIRECT3D11:
graphicsContext = new D3D11Context();
break;
@@ -229,19 +225,15 @@ void MainThreadFunc() {
const char *defaultErrorOpenGL = "Failed initializing graphics. Try upgrading your graphics drivers.\n\nWould you like to try switching to DirectX 9?\n\nError message:";
const char *defaultErrorDirect3D9 = "Failed initializing graphics. Try upgrading your graphics drivers and directx 9 runtime.\n\nWould you like to try switching to OpenGL?\n\nError message:";
std::string_view genericError;
GPUBackend nextBackend = GPUBackend::DIRECT3D9;
GPUBackend nextBackend = GPUBackend::VULKAN;
switch (g_Config.iGPUBackend) {
case (int)GPUBackend::DIRECT3D9:
nextBackend = GPUBackend::OPENGL;
genericError = err->T("GenericDirect3D9Error", defaultErrorDirect3D9);
break;
case (int)GPUBackend::VULKAN:
nextBackend = GPUBackend::OPENGL;
genericError = err->T("GenericVulkanError", defaultErrorVulkan);
break;
case (int)GPUBackend::OPENGL:
default:
nextBackend = GPUBackend::DIRECT3D9;
nextBackend = GPUBackend::DIRECT3D11;
genericError = err->T("GenericOpenGLError", defaultErrorOpenGL);
break;
}
@@ -258,11 +250,6 @@ void MainThreadFunc() {
g_Config.Save("save_graphics_fallback");
W32Util::ExitAndRestart();
} else {
if (g_Config.iGPUBackend == (int)GPUBackend::DIRECT3D9) {
// Allow the user to download the DX9 runtime.
System_LaunchUrl(LaunchUrlType::BROWSER_URL, "https://www.microsoft.com/en-us/download/details.aspx?id=34429");
}
}
// No safe way out without graphics.
+4 -4
View File
@@ -104,13 +104,13 @@ bool D3D11Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
}
if (FAILED(hr)) {
const char *defaultError = "Your GPU does not appear to support Direct3D 11.\n\nWould you like to try again using Direct3D 9 instead?";
const char *defaultError = "Your GPU does not appear to support Direct3D 11.\n\nWould you like to try again using OpenGL instead?";
auto err = GetI18NCategory(I18NCat::ERRORS);
std::wstring error;
if (result == LoadD3D11Error::FAIL_NO_COMPILER) {
error = ConvertUTF8ToWString(err->T("D3D11CompilerMissing", "D3DCompiler_47.dll not found. Please install. Or press Yes to try again using Direct3D9 instead."));
error = ConvertUTF8ToWString(err->T("D3D11CompilerMissing", "D3DCompiler_47.dll not found. Please install. Or press Yes to try again using OpenGL instead."));
} else if (result == LoadD3D11Error::FAIL_NO_D3D11) {
error = ConvertUTF8ToWString(err->T("D3D11Missing", "Your operating system version does not include D3D11. Please run Windows Update.\n\nPress Yes to try again using Direct3D9 instead."));
}
@@ -119,8 +119,8 @@ bool D3D11Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
std::wstring title = ConvertUTF8ToWString(err->T("D3D11InitializationError", "Direct3D 11 initialization error"));
bool yes = IDYES == MessageBox(hWnd_, error.c_str(), title.c_str(), MB_ICONERROR | MB_YESNO);
if (yes) {
// Change the config to D3D9 and restart.
g_Config.iGPUBackend = (int)GPUBackend::DIRECT3D9;
// Change the config to OpenGL and restart.
g_Config.iGPUBackend = (int)GPUBackend::OPENGL;
g_Config.sFailedGPUBackends.clear();
g_Config.Save("save_d3d9_fallback");
-197
View File
@@ -1,197 +0,0 @@
#include "ppsspp_config.h"
#include "Common/CommonWindows.h"
#include <d3d9.h>
#include "Common/GPU/D3D9/D3D9StateCache.h"
#include "Common/System/Display.h"
#include "Common/Data/Encoding/Utf8.h"
#include "Common/Data/Text/I18n.h"
#include "Common/Log.h"
#include "Common/OSVersion.h"
#include "Core/Config.h"
#include "Core/ConfigValues.h"
#include "Core/System.h"
#include "Common/OSVersion.h"
#include "Windows/GPU/D3D9Context.h"
#include "Windows/W32Util/Misc.h"
#include "Common/GPU/thin3d.h"
#include "Common/GPU/thin3d_create.h"
#include "Common/GPU/D3D9/D3DCompilerLoader.h"
typedef HRESULT (__stdcall *DIRECT3DCREATE9EX)(UINT, IDirect3D9Ex**);
bool D3D9Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
bool windowed = true;
hWnd_ = wnd;
// D3D9 has no need for display rotation.
g_display.rotation = DisplayRotation::ROTATE_0;
g_display.rot_matrix.setIdentity();
DIRECT3DCREATE9EX g_pfnCreate9ex;
hD3D9_ = LoadLibrary(TEXT("d3d9.dll"));
if (!hD3D9_) {
ERROR_LOG(Log::G3D, "Missing d3d9.dll");
*error_message = "D3D9.dll missing - try reinstalling DirectX.";
return false;
}
bool result = LoadD3DCompilerDynamic();
if (!result) {
*error_message = "D3DCompiler not found! Try reinstalling DirectX.";
return false;
}
g_pfnCreate9ex = (DIRECT3DCREATE9EX)GetProcAddress(hD3D9_, "Direct3DCreate9Ex");
has9Ex_ = (g_pfnCreate9ex != NULL) && IsVistaOrHigher();
if (has9Ex_) {
HRESULT result = g_pfnCreate9ex(D3D_SDK_VERSION, &d3dEx_);
d3d_ = d3dEx_;
if (FAILED(result)) {
FreeLibrary(hD3D9_);
*error_message = "D3D9Ex available but context creation failed. Try reinstalling DirectX.";
return false;
}
} else {
d3d_ = Direct3DCreate9(D3D_SDK_VERSION);
if (!d3d_) {
FreeLibrary(hD3D9_);
*error_message = "Failed to create D3D9 context. Try reinstalling DirectX.";
return false;
}
}
adapterId_ = D3DADAPTER_DEFAULT;
D3DCAPS9 d3dCaps;
D3DDISPLAYMODE d3ddm;
if (FAILED(d3d_->GetAdapterDisplayMode(adapterId_, &d3ddm))) {
*error_message = "GetAdapterDisplayMode failed";
d3d_ = nullptr;
return false;
}
if (FAILED(d3d_->GetDeviceCaps(adapterId_, D3DDEVTYPE_HAL, &d3dCaps))) {
*error_message = "GetDeviceCaps failed (?)";
d3d_ = nullptr;
return false;
}
HRESULT hr;
if (FAILED(hr = d3d_->CheckDeviceFormat(adapterId_,
D3DDEVTYPE_HAL,
d3ddm.Format,
D3DUSAGE_DEPTHSTENCIL,
D3DRTYPE_SURFACE,
D3DFMT_D24S8))) {
if (hr == D3DERR_NOTAVAILABLE) {
*error_message = "D24S8 depth/stencil not available";
d3d_ = nullptr;
return false;
}
}
DWORD dwBehaviorFlags = D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE;
if (d3dCaps.VertexProcessingCaps != 0)
dwBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
else
dwBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
int xres, yres;
W32Util::GetWindowRes(hWnd_, &xres, &yres);
presentParams_ = {};
presentParams_.BackBufferWidth = xres;
presentParams_.BackBufferHeight = yres;
presentParams_.BackBufferFormat = d3ddm.Format;
presentParams_.MultiSampleType = D3DMULTISAMPLE_NONE;
presentParams_.SwapEffect = D3DSWAPEFFECT_DISCARD;
presentParams_.Windowed = windowed;
presentParams_.hDeviceWindow = wnd;
presentParams_.EnableAutoDepthStencil = true;
presentParams_.AutoDepthStencilFormat = D3DFMT_D24S8;
presentParams_.PresentationInterval = swapInterval_ == 1 ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
if (has9Ex_) {
if (windowed && IsWin7OrHigher()) {
// This "new" flip mode should give higher performance but doesn't.
//pp.BackBufferCount = 2;
//pp.SwapEffect = D3DSWAPEFFECT_FLIPEX;
}
hr = d3dEx_->CreateDeviceEx(adapterId_, D3DDEVTYPE_HAL, wnd, dwBehaviorFlags, &presentParams_, NULL, &deviceEx_);
device_ = deviceEx_;
} else {
hr = d3d_->CreateDevice(adapterId_, D3DDEVTYPE_HAL, wnd, dwBehaviorFlags, &presentParams_, &device_);
}
if (FAILED(hr)) {
*error_message = "Failed to create D3D device";
d3d_ = nullptr;
return false;
}
device_->BeginScene();
pD3Ddevice9 = device_;
pD3DdeviceEx9 = deviceEx_;
if (deviceEx_ && IsWin7OrHigher()) {
// TODO: This makes it slower?
//deviceEx->SetMaximumFrameLatency(1);
}
draw_ = Draw::T3DCreateDX9Context(d3d_.Get(), d3dEx_.Get(), adapterId_, device_.Get(), deviceEx_.Get());
SetGPUBackend(GPUBackend::DIRECT3D9);
if (!draw_->CreatePresets()) {
// Shader compiler not installed? Return an error so we can fall back to GL.
device_ = nullptr;
d3d_ = nullptr;
*error_message = "DirectX9 runtime not correctly installed. Please install.";
return false;
}
if (draw_)
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, 0, 0, nullptr);
return true;
}
void D3D9Context::Resize() {
// This should only be called from the emu thread.
int xres, yres;
W32Util::GetWindowRes(hWnd_, &xres, &yres);
uint32_t newInterval = swapInterval_ == 1 ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
bool w_changed = presentParams_.BackBufferWidth != xres;
bool h_changed = presentParams_.BackBufferHeight != yres;
bool i_changed = presentParams_.PresentationInterval != newInterval;
if (device_ && (w_changed || h_changed || i_changed)) {
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, 0, 0, nullptr);
presentParams_.BackBufferWidth = xres;
presentParams_.BackBufferHeight = yres;
presentParams_.PresentationInterval = newInterval;
HRESULT hr = device_->Reset(&presentParams_);
if (FAILED(hr)) {
// Had to remove DXGetErrorStringA calls here because dxerr.lib is deprecated and will not link with VS 2015.
_assert_msg_(false, "Unable to reset D3D9 device");
}
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, 0, 0, nullptr);
}
}
void D3D9Context::Shutdown() {
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, 0, 0, nullptr);
delete draw_;
draw_ = nullptr;
device_->EndScene();
device_ = nullptr;
d3d_ = nullptr;
UnloadD3DCompiler();
pD3Ddevice9 = nullptr;
pD3DdeviceEx9 = nullptr;
device_ = nullptr;
hWnd_ = nullptr;
FreeLibrary(hD3D9_);
hD3D9_ = nullptr;
}
-57
View File
@@ -1,57 +0,0 @@
// Copyright (c) 2015- PPSSPP Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0 or later versions.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
// Modelled on OpenD3DBase. Might make a cleaner interface later.
#pragma once
#include "Common/CommonWindows.h"
#include "Windows/GPU/WindowsGraphicsContext.h"
#include <d3d9.h>
#include <wrl/client.h>
namespace Draw {
class DrawContext;
}
class D3D9Context : public WindowsGraphicsContext {
public:
D3D9Context() : draw_(nullptr), has9Ex_(false), d3d_(nullptr), d3dEx_(nullptr), adapterId_(-1), device_(nullptr), deviceEx_(nullptr), hDC_(nullptr), hWnd_(nullptr), hD3D9_(nullptr), presentParams_{} {
}
bool Init(HINSTANCE hInst, HWND window, std::string *error_message) override;
void Shutdown() override;
void Resize() override;
Draw::DrawContext *GetDrawContext() override { return draw_; }
private:
Draw::DrawContext *draw_;
bool has9Ex_;
Microsoft::WRL::ComPtr<IDirect3D9> d3d_;
Microsoft::WRL::ComPtr<IDirect3D9Ex> d3dEx_;
int adapterId_;
Microsoft::WRL::ComPtr<IDirect3DDevice9> device_;
Microsoft::WRL::ComPtr<IDirect3DDevice9Ex> deviceEx_;
HDC hDC_; // Private GDI Device Context
HWND hWnd_; // Holds Our Window Handle
HMODULE hD3D9_;
D3DPRESENT_PARAMETERS presentParams_;
int swapInterval_ = 0;
};
+1 -4
View File
@@ -270,10 +270,7 @@ bool WindowsGLContext::InitFromRenderThread(std::string *error_message) {
if (yes) {
// Change the config to D3D and restart.
const char *d3d9Or11 = "Direct3D 9? (Or no for Direct3D 11)";
std::wstring whichD3D9 = ConvertUTF8ToWString(err->T("D3D9or11", d3d9Or11));
bool d3d9 = IDYES == MessageBox(hWnd_, whichD3D9.c_str(), title.c_str(), MB_YESNO);
g_Config.iGPUBackend = d3d9 ? (int)GPUBackend::DIRECT3D9 : (int)GPUBackend::DIRECT3D11;
g_Config.iGPUBackend = (int)GPUBackend::DIRECT3D11;
g_Config.sFailedGPUBackends.clear();
g_Config.Save("save_d3d11_fallback");
-24
View File
@@ -283,7 +283,6 @@ namespace MainWindow {
// Skip window size 1x-4x..
TranslateMenuItem(menu, ID_OPTIONS_BACKEND_MENU);
TranslateMenuItem(menu, ID_OPTIONS_DIRECT3D11);
TranslateMenuItem(menu, ID_OPTIONS_DIRECT3D9);
TranslateMenuItem(menu, ID_OPTIONS_OPENGL);
TranslateMenuItem(menu, ID_OPTIONS_VULKAN);
@@ -693,12 +692,6 @@ namespace MainWindow {
System_PostUIMessage(UIMessage::GPU_CONFIG_CHANGED);
break;
case ID_OPTIONS_DIRECT3D9:
g_Config.iGPUBackend = (int)GPUBackend::DIRECT3D9;
g_Config.Save("gpu_choice");
RestartApp();
break;
case ID_OPTIONS_DIRECT3D11:
g_Config.iGPUBackend = (int)GPUBackend::DIRECT3D11;
g_Config.Save("gpu_choice");
@@ -1194,48 +1187,31 @@ namespace MainWindow {
CheckMenuItem(menu, savestateSlot[i], MF_BYCOMMAND | ((i == g_Config.iCurrentStateSlot) ? MF_CHECKED : MF_UNCHECKED));
}
bool allowD3D9 = g_Config.IsBackendEnabled(GPUBackend::DIRECT3D9);
bool allowD3D11 = g_Config.IsBackendEnabled(GPUBackend::DIRECT3D11);
bool allowOpenGL = g_Config.IsBackendEnabled(GPUBackend::OPENGL);
bool allowVulkan = g_Config.IsBackendEnabled(GPUBackend::VULKAN);
switch (GetGPUBackend()) {
case GPUBackend::DIRECT3D9:
EnableMenuItem(menu, ID_OPTIONS_DIRECT3D9, MF_GRAYED);
EnableMenuItem(menu, ID_OPTIONS_DIRECT3D11, allowD3D11 ? MF_ENABLED : MF_GRAYED);
EnableMenuItem(menu, ID_OPTIONS_OPENGL, allowOpenGL ? MF_ENABLED : MF_GRAYED);
EnableMenuItem(menu, ID_OPTIONS_VULKAN, allowVulkan ? MF_ENABLED : MF_GRAYED);
CheckMenuItem(menu, ID_OPTIONS_DIRECT3D9, MF_CHECKED);
CheckMenuItem(menu, ID_OPTIONS_DIRECT3D11, MF_UNCHECKED);
CheckMenuItem(menu, ID_OPTIONS_OPENGL, MF_UNCHECKED);
CheckMenuItem(menu, ID_OPTIONS_VULKAN, MF_UNCHECKED);
break;
case GPUBackend::OPENGL:
EnableMenuItem(menu, ID_OPTIONS_DIRECT3D9, allowD3D9 ? MF_ENABLED : MF_GRAYED);
EnableMenuItem(menu, ID_OPTIONS_DIRECT3D11, allowD3D11 ? MF_ENABLED : MF_GRAYED);
EnableMenuItem(menu, ID_OPTIONS_OPENGL, MF_GRAYED);
EnableMenuItem(menu, ID_OPTIONS_VULKAN, allowVulkan ? MF_ENABLED : MF_GRAYED);
CheckMenuItem(menu, ID_OPTIONS_DIRECT3D9, MF_UNCHECKED);
CheckMenuItem(menu, ID_OPTIONS_DIRECT3D11, MF_UNCHECKED);
CheckMenuItem(menu, ID_OPTIONS_OPENGL, MF_CHECKED);
CheckMenuItem(menu, ID_OPTIONS_VULKAN, MF_UNCHECKED);
break;
case GPUBackend::VULKAN:
EnableMenuItem(menu, ID_OPTIONS_DIRECT3D9, allowD3D9 ? MF_ENABLED : MF_GRAYED);
EnableMenuItem(menu, ID_OPTIONS_DIRECT3D11, allowD3D11 ? MF_ENABLED : MF_GRAYED);
EnableMenuItem(menu, ID_OPTIONS_OPENGL, allowOpenGL ? MF_ENABLED : MF_GRAYED);
EnableMenuItem(menu, ID_OPTIONS_VULKAN, MF_GRAYED);
CheckMenuItem(menu, ID_OPTIONS_DIRECT3D9, MF_UNCHECKED);
CheckMenuItem(menu, ID_OPTIONS_DIRECT3D11, MF_UNCHECKED);
CheckMenuItem(menu, ID_OPTIONS_OPENGL, MF_UNCHECKED);
CheckMenuItem(menu, ID_OPTIONS_VULKAN, MF_CHECKED);
break;
case GPUBackend::DIRECT3D11:
EnableMenuItem(menu, ID_OPTIONS_DIRECT3D9, allowD3D9 ? MF_ENABLED : MF_GRAYED);
EnableMenuItem(menu, ID_OPTIONS_DIRECT3D11, MF_GRAYED);
EnableMenuItem(menu, ID_OPTIONS_OPENGL, allowOpenGL ? MF_ENABLED : MF_GRAYED);
EnableMenuItem(menu, ID_OPTIONS_VULKAN, allowVulkan ? MF_ENABLED : MF_GRAYED);
CheckMenuItem(menu, ID_OPTIONS_DIRECT3D9, MF_UNCHECKED);
CheckMenuItem(menu, ID_OPTIONS_DIRECT3D11, MF_CHECKED);
CheckMenuItem(menu, ID_OPTIONS_OPENGL, MF_UNCHECKED);
CheckMenuItem(menu, ID_OPTIONS_VULKAN, MF_UNCHECKED);
+9 -11
View File
@@ -249,7 +249,7 @@
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<AdditionalDependencies>wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>../ffmpeg/Windows/x86/lib</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
@@ -289,7 +289,7 @@
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<AdditionalDependencies>wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>../ffmpeg/Windows/x86_64/lib</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)$(ProjectName).pdb</ProgramDatabaseFile>
@@ -325,7 +325,7 @@
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<AdditionalDependencies>wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>../ffmpeg/Windows/aarch64/lib</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)$(ProjectName).pdb</ProgramDatabaseFile>
@@ -359,7 +359,7 @@
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<AdditionalDependencies>wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>../ffmpeg/Windows/arm/lib</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)$(ProjectName).pdb</ProgramDatabaseFile>
@@ -397,7 +397,7 @@
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<AdditionalDependencies>wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>../ffmpeg/Windows/x86/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
@@ -446,7 +446,7 @@
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<AdditionalDependencies>wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>../ffmpeg/Windows/x86_64/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
@@ -489,7 +489,7 @@
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<AdditionalDependencies>wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>../ffmpeg/Windows/aarch64/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
@@ -530,7 +530,7 @@
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<AdditionalDependencies>wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>wbemuuid.lib;dwmapi.lib;winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>../ffmpeg/Windows/arm/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
@@ -841,7 +841,6 @@
<ClCompile Include="CaptureDevice.cpp" />
<ClCompile Include="Debugger\WatchItemWindow.cpp" />
<ClCompile Include="GPU\D3D11Context.cpp" />
<ClCompile Include="GPU\D3D9Context.cpp" />
<ClCompile Include="Debugger\BreakpointWindow.cpp" />
<ClCompile Include="Debugger\EditSymbolsWindow.cpp" />
<ClCompile Include="Debugger\CtrlDisAsmView.cpp" />
@@ -1418,7 +1417,6 @@
<ClInclude Include="CaptureDevice.h" />
<ClInclude Include="Debugger\WatchItemWindow.h" />
<ClInclude Include="GPU\D3D11Context.h" />
<ClInclude Include="GPU\D3D9Context.h" />
<ClInclude Include="Debugger\BreakpointWindow.h" />
<ClInclude Include="Debugger\EditSymbolsWindow.h" />
<ClInclude Include="Debugger\CtrlDisAsmView.h" />
@@ -1792,4 +1790,4 @@
<UserProperties RESOURCE_FILE="DaSh.rc" />
</VisualStudio>
</ProjectExtensions>
</Project>
</Project>
-6
View File
@@ -172,9 +172,6 @@
<ClCompile Include="MainWindow.cpp">
<Filter>Windows\UI</Filter>
</ClCompile>
<ClCompile Include="GPU\D3D9Context.cpp">
<Filter>Windows\System</Filter>
</ClCompile>
<ClCompile Include="GPU\WindowsGLContext.cpp">
<Filter>Windows\System</Filter>
</ClCompile>
@@ -384,9 +381,6 @@
<ClInclude Include="MainWindow.h">
<Filter>Windows\UI</Filter>
</ClInclude>
<ClInclude Include="GPU\D3D9Context.h">
<Filter>Windows\System</Filter>
</ClInclude>
<ClInclude Include="GPU\WindowsGLContext.h">
<Filter>Windows\System</Filter>
</ClInclude>
+4 -7
View File
@@ -1037,14 +1037,11 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin
if (wideArgs[i].find(gpuBackend) != std::wstring::npos && wideArgs[i].size() > gpuBackend.size()) {
const std::wstring restOfOption = wideArgs[i].substr(gpuBackend.size());
// Force software rendering off, as picking directx9 or gles implies HW acceleration.
// Once software rendering supports Direct3D9/11, we can add more options for software,
// such as "software-gles", "software-d3d9", and "software-d3d11", or something similar.
// Force software rendering off, as picking gles implies HW acceleration.
// We could add more options for software such as "software-gles",
// "software-vulkan" and "software-d3d11", or something similar.
// For now, software rendering force-activates OpenGL.
if (restOfOption == L"directx9") {
g_Config.iGPUBackend = (int)GPUBackend::DIRECT3D9;
g_Config.bSoftwareRendering = false;
} else if (restOfOption == L"directx11") {
if (restOfOption == L"directx11") {
g_Config.iGPUBackend = (int)GPUBackend::DIRECT3D11;
g_Config.bSoftwareRendering = false;
} else if (restOfOption == L"gles") {
-1
View File
@@ -624,7 +624,6 @@ BEGIN
POPUP "Backend", ID_OPTIONS_BACKEND_MENU
BEGIN
MENUITEM "Direct3D9", ID_OPTIONS_DIRECT3D9
MENUITEM "Direct3D11", ID_OPTIONS_DIRECT3D11
MENUITEM "OpenGL", ID_OPTIONS_OPENGL
MENUITEM "Vulkan", ID_OPTIONS_VULKAN
-1
View File
@@ -272,7 +272,6 @@
#define ID_DEBUG_SAVESYMFILE 40151
#define ID_OPTIONS_BUFLINEARFILTER 40152
#define ID_OPTIONS_BUFNEARESTFILTER 40153
#define ID_OPTIONS_DIRECT3D9 40154
#define ID_OPTIONS_OPENGL 40155
#define ID_EMULATION_ROTATION_H 40156
#define ID_EMULATION_ROTATION_V 40157
-2
View File
@@ -411,8 +411,6 @@ int main(int argc, const char* argv[])
// There used to be a separate "null" rendering core - just use software.
else if (!strcasecmp(gpuName, "software") || !strcasecmp(gpuName, "null"))
gpuCore = GPUCORE_SOFTWARE;
else if (!strcasecmp(gpuName, "directx9"))
gpuCore = GPUCORE_DIRECTX9;
else if (!strcasecmp(gpuName, "directx11"))
gpuCore = GPUCORE_DIRECTX11;
else if (!strcasecmp(gpuName, "vulkan"))
+8 -9
View File
@@ -191,7 +191,7 @@
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<BaseAddress>0x00400000</BaseAddress>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<FixedBaseAddress>true</FixedBaseAddress>
@@ -225,7 +225,7 @@
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<BaseAddress>0x00400000</BaseAddress>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<FixedBaseAddress>true</FixedBaseAddress>
@@ -258,7 +258,7 @@
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>winhttp.lib;ole32.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>winhttp.lib;ole32.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>/ignore:4049 /ignore:4217 %(AdditionalOptions)</AdditionalOptions>
<AdditionalLibraryDirectories>../ffmpeg/Windows/aarch64/lib</AdditionalLibraryDirectories>
</Link>
@@ -289,7 +289,7 @@
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>winhttp.lib;ole32.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>winhttp.lib;ole32.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>/ignore:4049 /ignore:4217 %(AdditionalOptions)</AdditionalOptions>
<AdditionalLibraryDirectories>../ffmpeg/Windows/arm/lib</AdditionalLibraryDirectories>
</Link>
@@ -323,7 +323,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<BaseAddress>0x00400000</BaseAddress>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<FixedBaseAddress>true</FixedBaseAddress>
@@ -362,7 +362,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<BaseAddress>0x00400000</BaseAddress>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<FixedBaseAddress>true</FixedBaseAddress>
@@ -400,7 +400,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>winhttp.lib;ole32.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>winhttp.lib;ole32.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>/ignore:4049 /ignore:4217 %(AdditionalOptions)</AdditionalOptions>
<AdditionalLibraryDirectories>../ffmpeg/Windows/aarch64/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
@@ -435,7 +435,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>winhttp.lib;ole32.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>winhttp.lib;ole32.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>/ignore:4049 /ignore:4217 %(AdditionalOptions)</AdditionalOptions>
<AdditionalLibraryDirectories>../ffmpeg/Windows/arm/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
@@ -455,7 +455,6 @@
</ClCompile>
<ClCompile Include="..\Windows\CaptureDevice.cpp" />
<ClCompile Include="..\Windows\GPU\D3D11Context.cpp" />
<ClCompile Include="..\Windows\GPU\D3D9Context.cpp" />
<ClCompile Include="..\Windows\GPU\WindowsGLContext.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</ExcludedFromBuild>
-3
View File
@@ -4,9 +4,6 @@
<ClCompile Include="Headless.cpp" />
<ClCompile Include="Compare.cpp" />
<ClCompile Include="..\ext\glew\glew.c" />
<ClCompile Include="..\Windows\GPU\D3D9Context.cpp">
<Filter>Windows</Filter>
</ClCompile>
<ClCompile Include="..\Windows\GPU\WindowsGLContext.cpp">
<Filter>Windows</Filter>
</ClCompile>
+4 -13
View File
@@ -37,7 +37,6 @@
#if PPSSPP_API(ANY_GL)
#include "Windows/GPU/WindowsGLContext.h"
#endif
#include "Windows/GPU/D3D9Context.h"
#include "Windows/GPU/D3D11Context.h"
#include "Windows/GPU/WindowsVulkanContext.h"
@@ -91,10 +90,6 @@ bool WindowsHeadlessHost::InitGraphics(std::string *error_message, GraphicsConte
needRenderThread = true;
break;
#endif
case GPUCORE_DIRECTX9:
graphicsContext = new D3D9Context();
break;
case GPUCORE_DIRECTX11:
graphicsContext = new D3D11Context();
break;
@@ -102,6 +97,9 @@ bool WindowsHeadlessHost::InitGraphics(std::string *error_message, GraphicsConte
case GPUCORE_VULKAN:
graphicsContext = new WindowsVulkanContext();
break;
default:
_assert_(false);
break;
}
if (graphicsContext->Init(NULL, hWnd, error_message)) {
@@ -165,11 +163,4 @@ void WindowsHeadlessHost::ShutdownGraphics() {
hWnd = NULL;
}
void WindowsHeadlessHost::SwapBuffers() {
if (gpuCore_ == GPUCORE_DIRECTX9) {
MSG msg;
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
void WindowsHeadlessHost::SwapBuffers() {}
-16
View File
@@ -68,22 +68,6 @@ protected:
retro_hw_render_callback hw_render_ = {};
};
#ifdef _WIN32
class LibretroD3D9Context : public LibretroHWRenderContext {
public:
LibretroD3D9Context() : LibretroHWRenderContext(RETRO_HW_CONTEXT_DIRECT3D, 9) {}
bool Init() override { return false; }
void CreateDrawContext() override {
draw_ = Draw::T3DCreateDX9Context(nullptr, nullptr, 0, nullptr, nullptr);
draw_->CreatePresets();
}
GPUCore GetGPUCore() override { return GPUCORE_DIRECTX9; }
const char *Ident() override { return "DirectX 9"; }
};
#endif
class LibretroSoftwareContext : public LibretroGraphicsContext {
public:
LibretroSoftwareContext() {}
+2 -2
View File
@@ -398,14 +398,14 @@ else ifneq (,$(findstring windows_msvc2019,$(platform)))
FFMPEGLIBDIR := $(FFMPEGDIR)/Windows/$(TARGET_ARCH)/lib
FFMPEGLDFLAGS += -LIBPATH:$(FFMPEGLIBDIR)
GL_LIB := opengl32.lib
LDFLAGS += ws2_32.lib user32.lib shell32.lib avcodec.lib avutil.lib swresample.lib swscale.lib avformat.lib advapi32.lib winmm.lib gdi32.lib d3d9.lib Iphlpapi.lib
LDFLAGS += ws2_32.lib user32.lib shell32.lib avcodec.lib avutil.lib swresample.lib swscale.lib avformat.lib advapi32.lib winmm.lib gdi32.lib Iphlpapi.lib
# Windows
else ifneq (,$(findstring win,$(platform)))
TARGET := $(TARGET_NAME)_libretro.dll
CFLAGS += -D_UNICODE -DUNICODE
CXXFLAGS += -fpermissive -Wno-multichar -D_UNICODE -DUNICODE -DARMIPS_USE_STD_FILESYSTEM
LDFLAGS += -shared -Wl,--no-undefined -static-libgcc -static-libstdc++ -Wl,--version-script=link.T -lwinmm -lgdi32 -lwsock32 -lws2_32 -ld3d9
LDFLAGS += -shared -Wl,--no-undefined -static-libgcc -static-libstdc++ -Wl,--version-script=link.T -lwinmm -lgdi32 -lwsock32 -lws2_32
GL_LIB := -lopengl32
PLATFORM_EXT = win32
FFMPEGINCFLAGS += -I$(FFMPEGDIR)/Windows/$(TARGET_ARCH)/include
-12
View File
@@ -984,14 +984,6 @@ SOURCES_CXX += \
ifeq ($(PLATFORM_EXT), win32)
SOURCES_CXX += \
$(GPUDIR)/Directx9/DrawEngineDX9.cpp \
$(GPUDIR)/Directx9/FramebufferManagerDX9.cpp \
$(GPUDIR)/Directx9/GPU_DX9.cpp \
$(GPUDIR)/Directx9/ShaderManagerDX9.cpp \
$(GPUDIR)/Directx9/StateMappingDX9.cpp \
$(GPUDIR)/Directx9/TextureCacheDX9.cpp
SOURCES_CXX += \
$(GPUDIR)/D3D11/DrawEngineD3D11.cpp \
$(GPUDIR)/D3D11/FramebufferManagerD3D11.cpp \
@@ -1003,10 +995,6 @@ SOURCES_CXX += \
$(LIBRETRODIR)/LibretroD3D11Context.cpp
SOURCES_CXX += \
$(COMMONDIR)/GPU/D3D9/D3D9ShaderCompiler.cpp \
$(COMMONDIR)/GPU/D3D9/D3D9StateCache.cpp \
$(COMMONDIR)/GPU/D3D9/D3DCompilerLoader.cpp \
$(COMMONDIR)/GPU/D3D9/thin3d_d3d9.cpp \
$(COMMONDIR)/GPU/D3D11/D3D11Loader.cpp \
$(COMMONDIR)/GPU/D3D11/thin3d_d3d11.cpp
-4
View File
@@ -126,9 +126,5 @@
#endif
#if PPSSPP_PLATFORM(WINDOWS)
#if !PPSSPP_PLATFORM(UWP)
#define PPSSPP_API_D3D9 1
#endif
#define PPSSPP_API_D3D11 1
#endif
-30
View File
@@ -21,9 +21,6 @@
#include <wrl/client.h>
#include "GPU/D3D11/D3D11Util.h"
#include "GPU/D3D11/D3D11Loader.h"
#include "GPU/D3D9/D3DCompilerLoader.h"
#include "GPU/D3D9/D3D9ShaderCompiler.h"
#endif
static constexpr size_t CODE_BUFFER_SIZE = 32768;
@@ -50,11 +47,6 @@ bool GenerateFShader(FShaderID id, char *buffer, ShaderLanguage lang, Draw::Bugs
ShaderLanguageDesc compat(ShaderLanguage::GLSL_3xx);
return GenerateFragmentShader(id, buffer, compat, bugs, &uniformMask, &flags, errorString);
}
case ShaderLanguage::HLSL_D3D9:
{
ShaderLanguageDesc compat(ShaderLanguage::HLSL_D3D9);
return GenerateFragmentShader(id, buffer, compat, bugs, &uniformMask, &flags, errorString);
}
case ShaderLanguage::HLSL_D3D11:
{
ShaderLanguageDesc compat(ShaderLanguage::HLSL_D3D11);
@@ -88,11 +80,6 @@ bool GenerateVShader(VShaderID id, char *buffer, ShaderLanguage lang, Draw::Bugs
ShaderLanguageDesc compat(ShaderLanguage::GLSL_3xx);
return GenerateVertexShader(id, buffer, compat, bugs, &attrMask, &uniformMask, &flags, errorString);
}
case ShaderLanguage::HLSL_D3D9:
{
ShaderLanguageDesc compat(ShaderLanguage::HLSL_D3D9);
return GenerateVertexShader(id, buffer, compat, bugs, &attrMask, &uniformMask, &flags, errorString);
}
case ShaderLanguage::HLSL_D3D11:
{
ShaderLanguageDesc compat(ShaderLanguage::HLSL_D3D11);
@@ -157,18 +144,6 @@ bool TestCompileShader(const char *buffer, ShaderLanguage lang, ShaderStage stag
auto output = CompileShaderToBytecodeD3D11(buffer, strlen(buffer), programType, 0);
return !output.empty();
}
case ShaderLanguage::HLSL_D3D9:
{
const char *programType = nullptr;
switch (stage) {
case ShaderStage::Vertex: programType = "vs_3_0"; break;
case ShaderStage::Fragment: programType = "ps_3_0"; break;
default: return false;
}
Microsoft::WRL::ComPtr<ID3DBlob> blob;
HRESULT hr = CompileShaderToByteCodeD3D9(buffer, programType, errorMessage, &blob);
return SUCCEEDED(hr);
}
#endif
case ShaderLanguage::GLSL_VULKAN:
@@ -211,7 +186,6 @@ void PrintDiff(const char *a, const char *b) {
const char *ShaderLanguageToString(ShaderLanguage lang) {
switch (lang) {
case HLSL_D3D11: return "HLSL_D3D11";
case HLSL_D3D9: return "HLSL_D3D9";
case GLSL_VULKAN: return "GLSL_VULKAN";
case GLSL_1xx: return "GLSL_1xx";
case GLSL_3xx: return "GLSL_3xx";
@@ -275,7 +249,6 @@ bool TestStencilShaders() {
ShaderLanguage languages[] = {
#if PPSSPP_PLATFORM(WINDOWS)
ShaderLanguage::HLSL_D3D9,
ShaderLanguage::HLSL_D3D11,
#endif
ShaderLanguage::GLSL_VULKAN,
@@ -331,7 +304,6 @@ bool TestDepalShaders() {
ShaderLanguage languages[] = {
#if PPSSPP_PLATFORM(WINDOWS)
ShaderLanguage::HLSL_D3D9,
ShaderLanguage::HLSL_D3D11,
#endif
ShaderLanguage::GLSL_VULKAN,
@@ -380,7 +352,6 @@ bool TestDepalShaders() {
const ShaderLanguage languages[] = {
#if PPSSPP_PLATFORM(WINDOWS)
ShaderLanguage::HLSL_D3D9,
ShaderLanguage::HLSL_D3D11,
#endif
ShaderLanguage::GLSL_VULKAN,
@@ -619,7 +590,6 @@ bool TestShaderGenerators() {
#if PPSSPP_PLATFORM(WINDOWS)
LoadD3D11();
init_glslang();
LoadD3DCompilerDynamic();
#else
init_glslang();
#endif
+8 -8
View File
@@ -181,7 +181,7 @@
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>/ignore:4049 /ignore:4217 %(AdditionalOptions)</AdditionalOptions>
<AdditionalLibraryDirectories>../ffmpeg/Windows/x86/lib</AdditionalLibraryDirectories>
</Link>
@@ -205,7 +205,7 @@
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>/ignore:4049 /ignore:4217 %(AdditionalOptions)</AdditionalOptions>
<AdditionalLibraryDirectories>../ffmpeg/Windows/x86_64/lib</AdditionalLibraryDirectories>
</Link>
@@ -229,7 +229,7 @@
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>/ignore:4049 /ignore:4217 %(AdditionalOptions)</AdditionalOptions>
<AdditionalLibraryDirectories>../ffmpeg/Windows/aarch64/lib</AdditionalLibraryDirectories>
</Link>
@@ -254,7 +254,7 @@
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>/ignore:4049 /ignore:4217 %(AdditionalOptions)</AdditionalOptions>
<AdditionalLibraryDirectories>../ffmpeg/Windows/arm/lib</AdditionalLibraryDirectories>
</Link>
@@ -283,7 +283,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>/ignore:4049 /ignore:4217 %(AdditionalOptions)</AdditionalOptions>
<AdditionalLibraryDirectories>../ffmpeg/Windows/x86/lib</AdditionalLibraryDirectories>
</Link>
@@ -313,7 +313,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>/ignore:4049 /ignore:4217 %(AdditionalOptions)</AdditionalOptions>
<AdditionalLibraryDirectories>../ffmpeg/Windows/x86_64/lib</AdditionalLibraryDirectories>
</Link>
@@ -343,7 +343,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>/ignore:4049 /ignore:4217 %(AdditionalOptions)</AdditionalOptions>
<AdditionalLibraryDirectories>../ffmpeg/Windows/aarch64/lib</AdditionalLibraryDirectories>
</Link>
@@ -373,7 +373,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>/ignore:4049 /ignore:4217 %(AdditionalOptions)</AdditionalOptions>
<AdditionalLibraryDirectories>../ffmpeg/Windows/arm/lib</AdditionalLibraryDirectories>
</Link>