diff --git a/Source/Core/VideoCommon/Src/NativeVertexFormat.h b/Source/Core/VideoCommon/Src/NativeVertexFormat.h index 7492dcaee0..8bd522e482 100644 --- a/Source/Core/VideoCommon/Src/NativeVertexFormat.h +++ b/Source/Core/VideoCommon/Src/NativeVertexFormat.h @@ -94,7 +94,7 @@ public: virtual ~NativeVertexFormat() {} virtual void Initialize(const PortableVertexDeclaration &vtx_decl) = 0; - virtual void SetupVertexPointers() const = 0; + virtual void SetupVertexPointers() = 0; virtual void EnableComponents(u32 components) {} int GetVertexStride() const { return vertex_stride; } diff --git a/Source/Plugins/Plugin_VideoDX11/Src/GfxState.cpp b/Source/Plugins/Plugin_VideoDX11/Src/GfxState.cpp index b17e9569ad..f3591ee361 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/GfxState.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/GfxState.cpp @@ -17,6 +17,7 @@ #include "VideoConfig.h" #include "GfxState.h" +#include "VertexShaderCache.h" namespace D3D { @@ -24,13 +25,10 @@ namespace D3D EmuGfxState* gfxstate; StateManager* stateman; -EmuGfxState::EmuGfxState() : vertexshader(NULL), vsbytecode(NULL), pixelshader(NULL), psbytecode(NULL), apply_called(false) +EmuGfxState::EmuGfxState() : apply_called(false) { pscbuf = NULL; vscbuf = NULL; - vshaderchanged = false; - inp_layout = NULL; - num_inp_elems = 0; pscbufchanged = false; vscbufchanged = false; @@ -38,66 +36,14 @@ EmuGfxState::EmuGfxState() : vertexshader(NULL), vsbytecode(NULL), pixelshader(N EmuGfxState::~EmuGfxState() { - SAFE_RELEASE(vsbytecode); - SAFE_RELEASE(psbytecode); - SAFE_RELEASE(vertexshader); - SAFE_RELEASE(pixelshader); - SAFE_RELEASE(pscbuf); SAFE_RELEASE(vscbuf); - - SAFE_RELEASE(inp_layout); -} - -// TODO: No need to store the whole bytecode, signature might be enough (?) -void EmuGfxState::SetVShader(ID3D11VertexShader* shader, D3DBlob* bcode) -{ - // TODO: vshaderchanged actually just needs to be true if the signature changed - if (bcode && vsbytecode != bcode) vshaderchanged = true; - SAFE_RELEASE(vsbytecode); - SAFE_RELEASE(vertexshader); - - if (shader && bcode) - { - vertexshader = shader; - shader->AddRef(); - vsbytecode = bcode; - bcode->AddRef(); - } - else if (shader || bcode) - { - PanicAlert("Invalid parameters!\n"); - } -} - -void EmuGfxState::SetPShader(ID3D11PixelShader* shader) -{ - if (pixelshader) pixelshader->Release(); - pixelshader = shader; - if (shader) shader->AddRef(); -} - -void EmuGfxState::SetInputElements(const D3D11_INPUT_ELEMENT_DESC* elems, UINT num) -{ - num_inp_elems = num; - memcpy(inp_elems, elems, num*sizeof(D3D11_INPUT_ELEMENT_DESC)); } void EmuGfxState::ApplyState() { HRESULT hr; - // input layout (only needs to be updated if the vertex shader signature changed) - if (vshaderchanged) - { - SAFE_RELEASE(inp_layout); - hr = D3D::device->CreateInputLayout(inp_elems, num_inp_elems, vsbytecode->Data(), vsbytecode->Size(), &inp_layout); - if (FAILED(hr)) PanicAlert("Failed to create input layout, %s %d\n", __FILE__, __LINE__); - SetDebugObjectName((ID3D11DeviceChild*)inp_layout, "an input layout of EmuGfxState"); - vshaderchanged = false; - } - D3D::context->IASetInputLayout(inp_layout); - // vertex shader // TODO: divide the global variables of the generated shaders into about 5 constant buffers // TODO: improve interaction between EmuGfxState and global state management, so that we don't need to set the constant buffers every time @@ -138,9 +84,6 @@ void EmuGfxState::ApplyState() } D3D::context->PSSetConstantBuffers(0, 1, &pscbuf); - context->PSSetShader(pixelshader, NULL, 0); - context->VSSetShader(vertexshader, NULL, 0); - apply_called = true; } diff --git a/Source/Plugins/Plugin_VideoDX11/Src/GfxState.h b/Source/Plugins/Plugin_VideoDX11/Src/GfxState.h index 62a1bd6d7f..35d11189b1 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/GfxState.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/GfxState.h @@ -33,10 +33,6 @@ public: EmuGfxState(); ~EmuGfxState(); - void SetVShader(ID3D11VertexShader* shader, D3DBlob* bcode); - void SetPShader(ID3D11PixelShader* shader); - void SetInputElements(const D3D11_INPUT_ELEMENT_DESC* elems, UINT num); - void ApplyState(); // apply current state void Reset(); @@ -47,19 +43,9 @@ public: bool pscbufchanged; private: - ID3D11VertexShader* vertexshader; - D3DBlob* vsbytecode; - ID3D11PixelShader* pixelshader; - D3DBlob* psbytecode; - bool vshaderchanged; - ID3D11Buffer* vscbuf; ID3D11Buffer* pscbuf; - ID3D11InputLayout* inp_layout; - D3D11_INPUT_ELEMENT_DESC inp_elems[32]; - int num_inp_elems; - bool apply_called; }; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/NativeVertexFormat.cpp b/Source/Plugins/Plugin_VideoDX11/Src/NativeVertexFormat.cpp index 3c5396aa8a..59f24c4280 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/NativeVertexFormat.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/NativeVertexFormat.cpp @@ -27,16 +27,22 @@ #include "CPMemory.h" #include "NativeVertexFormat.h" #include "VertexManager.h" +#include "VertexShaderCache.h" class D3DVertexFormat : public NativeVertexFormat { D3D11_INPUT_ELEMENT_DESC m_elems[32]; UINT m_num_elems; + D3DBlob* m_vs_bytecode; + ID3D11InputLayout* m_layout; + public: - D3DVertexFormat() : m_num_elems(0) {} + D3DVertexFormat() : m_num_elems(0), m_vs_bytecode(NULL), m_layout(NULL) {} + ~D3DVertexFormat() { SAFE_RELEASE(m_vs_bytecode); SAFE_RELEASE(m_layout); } + void Initialize(const PortableVertexDeclaration &_vtx_decl); - void SetupVertexPointers() const; + void SetupVertexPointers(); }; namespace DX11 @@ -140,7 +146,19 @@ void D3DVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl) } } -void D3DVertexFormat::SetupVertexPointers() const +void D3DVertexFormat::SetupVertexPointers() { - D3D::gfxstate->SetInputElements(m_elems, m_num_elems); + if (m_vs_bytecode != VertexShaderCache::GetActiveShaderBytecode()) + { + SAFE_RELEASE(m_vs_bytecode); + SAFE_RELEASE(m_layout); + + m_vs_bytecode = VertexShaderCache::GetActiveShaderBytecode(); + m_vs_bytecode->AddRef(); + + HRESULT hr = D3D::device->CreateInputLayout(m_elems, m_num_elems, m_vs_bytecode->Data(), m_vs_bytecode->Size(), &m_layout); + if (FAILED(hr)) PanicAlert("Failed to create input layout, %s %d\n", __FILE__, __LINE__); + D3D::SetDebugObjectName((ID3D11DeviceChild*)m_layout, "input layout used to emulate the GX pipeline"); + } + D3D::context->IASetInputLayout(m_layout); } diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp index e8d9037986..23e01af3bf 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp @@ -348,7 +348,6 @@ bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components) const PSCacheEntry &entry = iter->second; last_entry = &entry; - D3D::gfxstate->SetPShader(entry.shader); GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE,true); return (entry.shader != NULL); } @@ -369,7 +368,6 @@ bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components) g_ps_disk_cache.Sync(); bool result = InsertByteCode(uid, pbytecode->Data(), pbytecode->Size()); - D3D::gfxstate->SetPShader(last_entry->shader); pbytecode->Release(); GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); return result; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.h b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.h index 4eab0d8ecb..3ff52fc23a 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.h @@ -32,9 +32,11 @@ public: static void Init(); static void Clear(); static void Shutdown(); - static bool SetShader(DSTALPHA_MODE dstAlphaMode, u32 components); + static bool SetShader(DSTALPHA_MODE dstAlphaMode, u32 components); // TODO: Should be renamed to LoadShader static bool InsertByteCode(const PIXELSHADERUID &uid, const void* bytecode, unsigned int bytecodelen); + static ID3D11PixelShader* GetActiveShader() { return last_entry->shader; } + static ID3D11PixelShader* GetColorMatrixProgram(bool multisampled); static ID3D11PixelShader* GetColorCopyProgram(bool multisampled); static ID3D11PixelShader* GetDepthMatrixProgram(bool multisampled); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp index 713dd707d0..fb26f3b759 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp @@ -1190,7 +1190,7 @@ void Renderer::ApplyState(bool bUseDstAlpha) hr = D3D::device->CreateBlendState(&gx_state.blenddc, &blstate); if (FAILED(hr)) PanicAlert("Failed to create blend state at %s %d\n", __FILE__, __LINE__); D3D::stateman->PushBlendState(blstate); - D3D::SetDebugObjectName((ID3D11DeviceChild*)blstate, "a blend state of EmuGfxState"); + D3D::SetDebugObjectName((ID3D11DeviceChild*)blstate, "blend state used to emulate the GX pipeline"); SAFE_RELEASE(blstate); ID3D11DepthStencilState* depth_state; @@ -1233,6 +1233,9 @@ void Renderer::ApplyState(bool bUseDstAlpha) SetBlendMode(false); SetLogicOpMode(); } + + D3D::context->PSSetShader(PixelShaderCache::GetActiveShader(), NULL, 0); + D3D::context->VSSetShader(VertexShaderCache::GetActiveShader(), NULL, 0); } void Renderer::RestoreState() diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp index 8706d27280..a5fe2dbaa0 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp @@ -225,7 +225,6 @@ bool VertexShaderCache::SetShader(u32 components) const VSCacheEntry &entry = iter->second; last_entry = &entry; - if (entry.shader) D3D::gfxstate->SetVShader(entry.shader, iter->second.bytecode); GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); return (entry.shader != NULL); } @@ -245,7 +244,6 @@ bool VertexShaderCache::SetShader(u32 components) g_vs_disk_cache.Sync(); bool result = InsertByteCode(uid, pbytecode); - D3D::gfxstate->SetVShader(last_entry->shader, last_entry->bytecode); pbytecode->Release(); GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); return result; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.h b/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.h index cb24bc4926..a44ccda1df 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.h @@ -28,7 +28,10 @@ public: static void Init(); static void Clear(); static void Shutdown(); - static bool SetShader(u32 components); + static bool SetShader(u32 components); // TODO: Should be renamed to LoadShader + + static ID3D11VertexShader* GetActiveShader() { return last_entry->shader; } + static D3DBlob* GetActiveShaderBytecode() { return last_entry->bytecode; } static ID3D11VertexShader* GetSimpleVertexShader(); static ID3D11VertexShader* GetClearVertexShader(); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/NativeVertexFormat.cpp b/Source/Plugins/Plugin_VideoDX9/Src/NativeVertexFormat.cpp index a05883bab1..1c21a95887 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/NativeVertexFormat.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/NativeVertexFormat.cpp @@ -36,7 +36,7 @@ public: D3DVertexFormat() : d3d_decl(NULL) {} ~D3DVertexFormat(); virtual void Initialize(const PortableVertexDeclaration &_vtx_decl); - virtual void SetupVertexPointers() const; + virtual void SetupVertexPointers(); #if defined(_DEBUG) || defined(DEBUGFAST) D3DVERTEXELEMENT9 elements[32]; @@ -185,7 +185,7 @@ void D3DVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl) #endif } -void D3DVertexFormat::SetupVertexPointers() const +void D3DVertexFormat::SetupVertexPointers() { if (d3d_decl) D3D::SetVertexDeclaration(d3d_decl); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp b/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp index effa3981d5..0df2e5faa7 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp @@ -64,7 +64,7 @@ public: ~GLVertexFormat(); virtual void Initialize(const PortableVertexDeclaration &_vtx_decl); - virtual void SetupVertexPointers() const; + virtual void SetupVertexPointers(); virtual void EnableComponents(u32 components); }; @@ -180,7 +180,7 @@ void GLVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl) this->vtx_decl = _vtx_decl; } -void GLVertexFormat::SetupVertexPointers() const { +void GLVertexFormat::SetupVertexPointers() { // Cast a pointer to compiled code to a pointer to a function taking no parameters, through a (void *) cast first to // get around type checking errors, and call it. #ifdef USE_JIT