From d541cfcd05f9f7fb627f3fd3cbe7b07b624493e4 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Fri, 18 Jun 2010 23:33:07 +0000 Subject: [PATCH] DX11: Introduce a StateManager class, might improve performance a little. git-svn-id: http://dolphin-emu.googlecode.com/svn/trunk@5740 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Plugins/Plugin_VideoDX11/Src/D3DBase.cpp | 230 +-------------------- Source/Plugins/Plugin_VideoDX11/Src/D3DBase.h | 200 ++++++------------ Source/Plugins/Plugin_VideoDX11/Src/D3DTexture.cpp | 5 +- Source/Plugins/Plugin_VideoDX11/Src/D3DUtil.cpp | 10 +- .../Plugin_VideoDX11/Src/PixelShaderCache.cpp | 8 +- Source/Plugins/Plugin_VideoDX11/Src/Render.cpp | 29 ++- .../Plugins/Plugin_VideoDX11/Src/TextureCache.cpp | 9 +- .../Plugins/Plugin_VideoDX11/Src/VertexManager.cpp | 13 +- .../Plugin_VideoDX11/Src/VertexShaderCache.cpp | 4 +- 9 files changed, 114 insertions(+), 394 deletions(-) rewrite Source/Plugins/Plugin_VideoDX11/Src/D3DBase.h (60%) diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.cpp b/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.cpp index 57fd07d9d..d79da53e0 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.cpp @@ -49,232 +49,6 @@ unsigned int xres, yres; bool bFrameInProgress = false; -EmuGfxState::EmuGfxState() : vertexshader(NULL), vsbytecode(NULL), pixelshader(NULL), psbytecode(NULL) -{ - for (unsigned int k = 0;k < 8;k++) - { - float border[4] = {0.f, 0.f, 0.f, 0.f}; - shader_resources[k] = NULL; - samplerdesc[k] = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_LINEAR, D3D11_TEXTURE_ADDRESS_CLAMP, D3D11_TEXTURE_ADDRESS_CLAMP, D3D11_TEXTURE_ADDRESS_CLAMP, 0.f, 16, D3D11_COMPARISON_ALWAYS, border, -D3D11_FLOAT32_MAX, D3D11_FLOAT32_MAX); - } - - blenddesc.AlphaToCoverageEnable = FALSE; - blenddesc.IndependentBlendEnable = FALSE; - blenddesc.RenderTarget[0].BlendEnable = FALSE; - blenddesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; - blenddesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; - blenddesc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO; - blenddesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; - blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; - blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; - blenddesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; - - depthdesc.DepthEnable = TRUE; - depthdesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; - depthdesc.DepthFunc = D3D11_COMPARISON_LESS; - depthdesc.StencilEnable = FALSE; - depthdesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; - depthdesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; - - // this probably must be changed once multisampling support gets added - rastdesc = CD3D11_RASTERIZER_DESC(D3D11_FILL_SOLID, D3D11_CULL_NONE, false, 0, 0.f, 0, false, true, false, false); - - pscbuf = NULL; - vscbuf = NULL; - vshaderchanged = false; - inp_layout = NULL; - num_inp_elems = 0; - - pscbufchanged = false; - vscbufchanged = false; -} - -EmuGfxState::~EmuGfxState() -{ - for (unsigned int k = 0;k < 8;k++) - SAFE_RELEASE(shader_resources[k]) - - 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::SetShaderResource(int stage, ID3D11ShaderResourceView* srv) -{ - if (shader_resources[stage]) shader_resources[stage]->Release(); - shader_resources[stage] = srv; - if (srv) srv->AddRef(); -} - -void EmuGfxState::SetAlphaBlendEnable(bool enable) -{ - blenddesc.RenderTarget[0].BlendEnable = enable; -} - -void EmuGfxState::SetRenderTargetWriteMask(UINT8 mask) -{ - blenddesc.RenderTarget[0].RenderTargetWriteMask = mask; -} - -void EmuGfxState::ApplyState() -{ - HRESULT hr; - - // input layout (only needs to be updated if the vertex shader signature changed) - if (vshaderchanged) - { - if (inp_layout) inp_layout->Release(); - 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 - if (!vscbuf) - { - unsigned int size = ((sizeof(float)*952)&(~0xffff))+0x10000; // must be a multiple of 16 - D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(size, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); - hr = device->CreateBuffer(&cbdesc, NULL, &vscbuf); - CHECK(hr==S_OK, "Create vertex shader constant buffer (size=%u)", size); - SetDebugObjectName((ID3D11DeviceChild*)vscbuf, "a vertex shader constant buffer of EmuGfxState"); - } - if (vscbufchanged) - { - D3D11_MAPPED_SUBRESOURCE map; - context->Map(vscbuf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); - memcpy(map.pData, vsconstants, sizeof(vsconstants)); - context->Unmap(vscbuf, 0); - } - D3D::context->VSSetConstantBuffers(0, 1, &vscbuf); - - // pixel shader - if (!pscbuf) - { - unsigned int size = ((sizeof(float)*116)&(~0xffff))+0x10000; // must be a multiple of 16 - D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(size, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); - device->CreateBuffer(&cbdesc, NULL, &pscbuf); - CHECK(hr==S_OK, "Create pixel shader constant buffer (size=%u)", size); - SetDebugObjectName((ID3D11DeviceChild*)pscbuf, "a pixel shader constant buffer of EmuGfxState"); - } - if (pscbufchanged) - { - D3D11_MAPPED_SUBRESOURCE map; - context->Map(pscbuf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); - memcpy(map.pData, psconstants, sizeof(psconstants)); - context->Unmap(pscbuf, 0); - pscbufchanged = false; - } - D3D::context->PSSetConstantBuffers(0, 1, &pscbuf); - - ID3D11SamplerState* samplerstate[8]; - for (unsigned int stage = 0; stage < 8; stage++) - { - if (shader_resources[stage]) - { - hr = D3D::device->CreateSamplerState(&samplerdesc[stage], &samplerstate[stage]); - if (FAILED(hr)) PanicAlert("Fail %s %d, stage=%d\n", __FILE__, __LINE__, stage); - else SetDebugObjectName((ID3D11DeviceChild*)samplerstate[stage], "a sampler state of EmuGfxState"); - } - else samplerstate[stage] = NULL; - } - D3D::context->PSSetSamplers(0, 8, samplerstate); - for (unsigned int stage = 0; stage < 8; stage++) - SAFE_RELEASE(samplerstate[stage]); - - ID3D11BlendState* blstate; - hr = device->CreateBlendState(&blenddesc, &blstate); - if (FAILED(hr)) PanicAlert("Failed to create blend state at %s %d\n", __FILE__, __LINE__); - context->OMSetBlendState(blstate, NULL, 0xFFFFFFFF); - SetDebugObjectName((ID3D11DeviceChild*)blstate, "a blend state of EmuGfxState"); - blstate->Release(); - - rastdesc.FillMode = (g_ActiveConfig.bWireFrame) ? D3D11_FILL_WIREFRAME : D3D11_FILL_SOLID; - ID3D11RasterizerState* raststate; - hr = device->CreateRasterizerState(&rastdesc, &raststate); - if (FAILED(hr)) PanicAlert("Failed to create rasterizer state at %s %d\n", __FILE__, __LINE__); - SetDebugObjectName((ID3D11DeviceChild*)raststate, "a rasterizer state of EmuGfxState"); - context->RSSetState(raststate); - raststate->Release(); - - ID3D11DepthStencilState* depth_state; - hr = device->CreateDepthStencilState(&depthdesc, &depth_state); - if (SUCCEEDED(hr)) SetDebugObjectName((ID3D11DeviceChild*)depth_state, "a depth-stencil state of EmuGfxState"); - else PanicAlert("Failed to create depth state at %s %d\n", __FILE__, __LINE__); - context->OMSetDepthStencilState(depth_state, 0); - depth_state->Release(); - - context->PSSetShader(pixelshader, NULL, 0); - context->VSSetShader(vertexshader, NULL, 0); - context->PSSetShaderResources(0, 8, shader_resources); -} - -void EmuGfxState::AlphaPass() -{ - context->PSSetShader(pixelshader, NULL, 0); - - ID3D11BlendState* blstate; - D3D11_BLEND_DESC desc = blenddesc; - desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALPHA; - desc.RenderTarget[0].BlendEnable = FALSE; - HRESULT hr = device->CreateBlendState(&desc, &blstate); - if (FAILED(hr)) PanicAlert("Failed to create blend state at %s %d\n", __FILE__, __LINE__); - SetDebugObjectName((ID3D11DeviceChild*)blstate, "a blend state of EmuGfxState (created during alpha pass)"); - context->OMSetBlendState(blstate, NULL, 0xFFFFFFFF); - blstate->Release(); -} - -void EmuGfxState::ResetShaderResources() -{ - for (unsigned int k = 0;k < 8;k++) - SAFE_RELEASE(shader_resources[k]); -} - -EmuGfxState* gfxstate = NULL; - HRESULT Create(HWND wnd) { hWnd = wnd; @@ -372,6 +146,7 @@ HRESULT Create(HWND wnd) context->OMSetRenderTargets(1, &backbuf->GetRTV(), NULL); gfxstate = new EmuGfxState; + stateman = new StateManager; return S_OK; } @@ -380,8 +155,9 @@ void Close() // release all bound resources context->ClearState(); SAFE_RELEASE(backbuf); - if (gfxstate) delete gfxstate; SAFE_RELEASE(swapchain); + SAFE_DELETE(gfxstate); + SAFE_DELETE(stateman); context->Flush(); // immediately destroy device objects SAFE_RELEASE(context); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.h b/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.h dissimilarity index 60% index 8593927db..559180ab7 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DBase.h @@ -1,137 +1,63 @@ -// Copyright (C) 2003 Dolphin 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. - -// 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 SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - -#pragma once - -#include -#include "Common.h" -#include "D3DBlob.h" - -#define SAFE_RELEASE(x) { if (x) (x)->Release(); (x) = NULL; } -#define CHECK(cond, Message, ...) if (!(cond)) { PanicAlert(__FUNCTION__ "Failed in %s at line %d: " Message, __FILE__, __LINE__, __VA_ARGS__); } - -class D3DTexture2D; -namespace D3D -{ - -HRESULT Create(HWND wnd); -void Close(); - -extern ID3D11Device* device; -extern ID3D11DeviceContext* context; -extern IDXGISwapChain* swapchain; -extern bool bFrameInProgress; - -void Reset(); -bool BeginFrame(); -void EndFrame(); -void Present(); - -unsigned int GetBackBufferWidth(); -unsigned int GetBackBufferHeight(); -D3DTexture2D* &GetBackBuffer(); -const char* PixelShaderVersionString(); -const char* VertexShaderVersionString(); - -// Ihis function will assign a name to the given resource. -// The DirectX debug layer will make it easier to identify resources that way, -// e.g. when listing up all resources who have unreleased references. -inline void SetDebugObjectName(ID3D11DeviceChild* resource, const char* name) -{ -#if defined(_DEBUG) || defined(DEBUGFAST) - resource->SetPrivateData( WKPDID_D3DDebugObjectName, strlen(name), name); -#endif -} - -// stores the pipeline state to use when calling VertexManager::Flush() -class EmuGfxState -{ -public: - EmuGfxState(); - ~EmuGfxState(); - - void SetVShader(ID3D11VertexShader* shader, D3DBlob* bcode); - void SetPShader(ID3D11PixelShader* shader); - void SetInputElements(const D3D11_INPUT_ELEMENT_DESC* elems, UINT num); - void SetShaderResource(int stage, ID3D11ShaderResourceView* srv); - - void ApplyState(); // apply current state - void AlphaPass(); // only modify the current state to enable the alpha pass - void ResetShaderResources(); // disable all shader resources - - // blend state - void SetAlphaBlendEnable(bool enable); - void SetRenderTargetWriteMask(UINT8 mask); - void SetSrcBlend(D3D11_BLEND val) // TODO: Check whether e.g. the dest color check is needed here - { - blenddesc.RenderTarget[0].SrcBlend = val; - if (val == D3D11_BLEND_SRC_COLOR) blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA; - else if (val == D3D11_BLEND_INV_SRC_COLOR) blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; - else if (val == D3D11_BLEND_DEST_COLOR) blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_DEST_ALPHA; - else if (val == D3D11_BLEND_INV_DEST_COLOR) blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_DEST_ALPHA; - else blenddesc.RenderTarget[0].SrcBlendAlpha = val; - } - void SetDestBlend(D3D11_BLEND val) - { - blenddesc.RenderTarget[0].DestBlend = val; - if (val == D3D11_BLEND_SRC_COLOR) blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_SRC_ALPHA; - else if (val == D3D11_BLEND_INV_SRC_COLOR) blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; - else if (val == D3D11_BLEND_DEST_COLOR) blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_DEST_ALPHA; - else if (val == D3D11_BLEND_INV_DEST_COLOR) blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_DEST_ALPHA; - else blenddesc.RenderTarget[0].DestBlendAlpha = val; - } - void SetBlendOp(D3D11_BLEND_OP val) - { - blenddesc.RenderTarget[0].BlendOp = val; - blenddesc.RenderTarget[0].BlendOpAlpha = val; - } - - // sampler states - void SetSamplerFilter(DWORD stage, D3D11_FILTER filter) { samplerdesc[stage].Filter = filter; } - - // TODO: add methods for changing the other states instead of modifying them directly - - D3D11_SAMPLER_DESC samplerdesc[8]; - D3D11_RASTERIZER_DESC rastdesc; - D3D11_DEPTH_STENCIL_DESC depthdesc; - - float psconstants[116]; - float vsconstants[952]; - bool vscbufchanged; - 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; - - ID3D11ShaderResourceView* shader_resources[8]; - D3D11_BLEND_DESC blenddesc; -}; - -extern EmuGfxState* gfxstate; - -} // namespace +// Copyright (C) 2003 Dolphin 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. + +// 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 SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#pragma once + +#include +#include "Common.h" +#include "D3DBlob.h" +#include "GfxState.h" + +#define SAFE_RELEASE(x) { if (x) (x)->Release(); (x) = NULL; } +#define SAFE_DELETE(x) { if (x) delete (x); (x) = NULL; } +#define SAFE_DELETE_ARRAY(x) { if (x) delete[] (x); (x) = NULL; } +#define CHECK(cond, Message, ...) if (!(cond)) { PanicAlert(__FUNCTION__ "Failed in %s at line %d: " Message, __FILE__, __LINE__, __VA_ARGS__); } + +class D3DTexture2D; +namespace D3D +{ + +HRESULT Create(HWND wnd); +void Close(); + +extern ID3D11Device* device; +extern ID3D11DeviceContext* context; +extern IDXGISwapChain* swapchain; +extern bool bFrameInProgress; + +void Reset(); +bool BeginFrame(); +void EndFrame(); +void Present(); + +unsigned int GetBackBufferWidth(); +unsigned int GetBackBufferHeight(); +D3DTexture2D* &GetBackBuffer(); +const char* PixelShaderVersionString(); +const char* VertexShaderVersionString(); + +// Ihis function will assign a name to the given resource. +// The DirectX debug layer will make it easier to identify resources that way, +// e.g. when listing up all resources who have unreleased references. +inline void SetDebugObjectName(ID3D11DeviceChild* resource, const char* name) +{ +#if defined(_DEBUG) || defined(DEBUGFAST) + resource->SetPrivateData( WKPDID_D3DDebugObjectName, strlen(name), name); +#endif +} + +} // namespace diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DTexture.cpp b/Source/Plugins/Plugin_VideoDX11/Src/D3DTexture.cpp index 0aa209b3f..62f6af1a3 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/D3DTexture.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DTexture.cpp @@ -31,8 +31,7 @@ struct TexbufDeleter { ~TexbufDeleter() { - if (texbuf) delete[] texbuf; - texbuf = NULL; + SAFE_DELETE_ARRAY(texbuf); texbufsize = 0; } } texbufdeleter; @@ -55,7 +54,7 @@ void ReplaceTexture2D(ID3D11Texture2D* pTexture, const u8* buffer, unsigned int { if (texbufsize < 4*width*height) { - if (texbuf) delete[] texbuf; + SAFE_DELETE_ARRAY(texbuf); texbuf = new u8[4*width*height]; texbufsize = 4*width*height; } diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DUtil.cpp b/Source/Plugins/Plugin_VideoDX11/Src/D3DUtil.cpp index 0517e1bcd..6df6ed28c 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/D3DUtil.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DUtil.cpp @@ -316,8 +316,9 @@ int CD3DFont::DrawTextScaled(float x, float y, float scale, float spacing, u32 d // we now have a starting point float fStartX = sx; // set general pipeline state - D3D::context->OMSetBlendState(m_blendstate, NULL, 0xFFFFFFFF); - D3D::context->RSSetState(m_raststate); + D3D::stateman->PushBlendState(m_blendstate); + D3D::stateman->PushRasterizerState(m_raststate); + D3D::stateman->Apply(); D3D::context->PSSetShader(m_pshader, NULL, 0); D3D::context->VSSetShader(m_vshader, NULL, 0); @@ -380,6 +381,8 @@ int CD3DFont::DrawTextScaled(float x, float y, float scale, float spacing, u32 d D3D::context->Draw(3 * dwNumTriangles, 0); } D3D::gfxstate->SetShaderResource(0, NULL); + D3D::stateman->PopBlendState(); + D3D::stateman->PopRasterizerState(); return S_OK; } @@ -490,6 +493,7 @@ void drawShadedTexQuad(ID3D11ShaderResourceView* texture, D3D::context->PSSetShader(PShader, NULL, 0); D3D::context->PSSetShaderResources(0, 1, &texture); D3D::context->VSSetShader(Vshader, NULL, 0); + D3D::stateman->Apply(); D3D::context->Draw(4, 0); ID3D11ShaderResourceView* texres = NULL; @@ -546,6 +550,7 @@ void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture, context->PSSetSamplers(0, 1, &stsqsamplerstate); context->PSSetShader(PShader, NULL, 0); context->VSSetShader(Vshader, NULL, 0); + stateman->Apply(); context->Draw(4, 0); ID3D11ShaderResourceView* texres = NULL; @@ -589,6 +594,7 @@ void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexS UINT offset = 0; context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); context->IASetVertexBuffers(0, 1, &clearvb, &stride, &offset); + stateman->Apply(); context->Draw(4, 0); lastcol = Color; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp index 426a40900..f9ece8417 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp @@ -165,22 +165,22 @@ public: void PixelShaderCache::Init() { // used when drawing clear quads - s_ClearProgram = D3D::CompileAndCreatePixelShader(clear_program_code, strlen(clear_program_code)); + s_ClearProgram = D3D::CompileAndCreatePixelShader(clear_program_code, sizeof(clear_program_code)); CHECK(s_ClearProgram!=NULL, "Create clear pixel shader"); D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ClearProgram, "clear pixel shader"); // used when copying/resolving the color buffer - s_ColorCopyProgram = D3D::CompileAndCreatePixelShader(color_copy_program_code, strlen(color_copy_program_code)); + s_ColorCopyProgram = D3D::CompileAndCreatePixelShader(color_copy_program_code, sizeof(color_copy_program_code)); CHECK(s_ColorCopyProgram!=NULL, "Create color copy pixel shader"); D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ClearProgram, "color copy pixel shader"); // used for color conversion - s_ColorMatrixProgram = D3D::CompileAndCreatePixelShader(color_matrix_program_code, strlen(color_matrix_program_code)); + s_ColorMatrixProgram = D3D::CompileAndCreatePixelShader(color_matrix_program_code, sizeof(color_matrix_program_code)); CHECK(s_ColorMatrixProgram!=NULL, "Create color matrix pixel shader"); D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ClearProgram, "color matrix pixel shader"); // used for depth copy - s_DepthMatrixProgram = D3D::CompileAndCreatePixelShader(depth_matrix_program, strlen(depth_matrix_program)); + s_DepthMatrixProgram = D3D::CompileAndCreatePixelShader(depth_matrix_program, sizeof(depth_matrix_program)); CHECK(s_DepthMatrixProgram!=NULL, "Create depth matrix pixel shader"); D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ClearProgram, "depth matrix pixel shader"); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp index e0f94ade4..22e9aab20 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp @@ -81,6 +81,9 @@ ID3D11BlendState* resetblendstate = NULL; ID3D11DepthStencilState* resetdepthstate = NULL; ID3D11RasterizerState* resetraststate = NULL; +// used to make sure that we really Pop all states which got Pushed in ResetAPIState +unsigned int resets = 0; + // state translation lookup tables static const D3D11_BLEND d3dSrcFactors[8] = { @@ -365,6 +368,8 @@ bool Renderer::Init() D3D::context->OMSetRenderTargets(1, &FBManager.GetEFBColorTexture()->GetRTV(), FBManager.GetEFBDepthTexture()->GetDSV()); D3D::BeginFrame(); D3D::gfxstate->rastdesc.ScissorEnable = TRUE; + + resets = 0; return true; } @@ -756,13 +761,17 @@ void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaE 0.f, 1.f); D3D::context->RSSetViewports(1, &vp); + // always set the scissor in case it was set by the game and has not been reset - // TODO: Do we really need to set the scissor rect? Why not just disable scissor testing? D3D11_RECT sirc = CD3D11_RECT(targetRc.left, targetRc.top, targetRc.right, targetRc.bottom); D3D::context->RSSetScissorRects(1, &sirc); - D3D::context->OMSetDepthStencilState(cleardepthstates[zEnable], 0); - D3D::context->RSSetState(clearraststate); + + D3D::stateman->PushDepthState(cleardepthstates[zEnable]); + D3D::stateman->PushRasterizerState(clearraststate); D3D::drawClearQuad(color, (z & 0xFFFFFF) / float(0xFFFFFF),PixelShaderCache::GetClearProgram(),VertexShaderCache::GetClearVertexShader(), VertexShaderCache::GetClearInputLayout()); + + D3D::stateman->PopDepthState(); + D3D::stateman->PopRasterizerState(); UpdateViewport(); SetScissorRect(); } @@ -1011,15 +1020,22 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight) void Renderer::ResetAPIState() { - D3D::context->OMSetBlendState(resetblendstate, NULL, 0xFFFFFFFF); - D3D::context->OMSetDepthStencilState(resetdepthstate, 0); - D3D::context->RSSetState(resetraststate); + resets++; + D3D::stateman->PushBlendState(resetblendstate); + D3D::stateman->PushDepthState(resetdepthstate); + D3D::stateman->PushRasterizerState(resetraststate); } void Renderer::RestoreAPIState() { // TODO: How much of this is actually needed? // gets us back into a more game-like state. + for (;resets;--resets) + { + D3D::stateman->PopBlendState(); + D3D::stateman->PopDepthState(); + D3D::stateman->PopRasterizerState(); + } D3D::gfxstate->rastdesc.ScissorEnable = TRUE; UpdateViewport(); SetScissorRect(); @@ -1027,7 +1043,6 @@ void Renderer::RestoreAPIState() if (bpmem.zmode.updateenable) D3D::gfxstate->depthdesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; SetColorMask(); SetLogicOpMode(); - D3D::gfxstate->ApplyState(); } void Renderer::SetGenerationMode() diff --git a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp index d0848a4c5..6db655a6d 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp @@ -561,9 +561,9 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, boo // TODO: Use linear filtering if (bScaleByHalf), else use point filtering - D3D::context->OMSetBlendState(efbcopyblendstate, NULL, 0xffffffff); - D3D::context->RSSetState(efbcopyraststate); - D3D::context->OMSetDepthStencilState(efbcopydepthstate, 0); + D3D::stateman->PushBlendState(efbcopyblendstate); + D3D::stateman->PushRasterizerState(efbcopyraststate); + D3D::stateman->PushDepthState(efbcopydepthstate); D3D::context->OMSetRenderTargets(1, &tex->GetRTV(), NULL); D3D::drawShadedTexQuad( (bFromZBuffer) ? FBManager.GetEFBDepthTexture()->GetSRV() : FBManager.GetEFBColorTexture()->GetSRV(), @@ -573,5 +573,8 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, boo (bFromZBuffer) ? PixelShaderCache::GetDepthMatrixProgram() : PixelShaderCache::GetColorMatrixProgram(), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout()); D3D::context->OMSetRenderTargets(1, &FBManager.GetEFBColorTexture()->GetRTV(), FBManager.GetEFBDepthTexture()->GetDSV()); + D3D::stateman->PopBlendState(); + D3D::stateman->PopDepthState(); + D3D::stateman->PopRasterizerState(); Renderer::RestoreAPIState(); } diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp index 99882adf9..1a8db6308 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp @@ -152,15 +152,10 @@ void ResetBuffer() void Shutdown() { DestroyDeviceObjects(); - if (LocalVBuffer) delete[] LocalVBuffer; - if (TIBuffer) delete[] TIBuffer; - if (LIBuffer) delete[] LIBuffer; - if (PIBuffer) delete[] PIBuffer; - LocalVBuffer = NULL; - TIBuffer = NULL; - LIBuffer = NULL; - PIBuffer = NULL; - + SAFE_DELETE_ARRAY(LocalVBuffer); + SAFE_DELETE_ARRAY(TIBuffer); + SAFE_DELETE_ARRAY(LIBuffer); + SAFE_DELETE_ARRAY(PIBuffer); ResetBuffer(); } diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp index 1d05ab576..653ca1c92 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp @@ -143,7 +143,7 @@ void VertexShaderCache::Init() }; D3DBlob* blob; - D3D::CompileVertexShader(simple_shader_code, strlen(simple_shader_code), &blob); + D3D::CompileVertexShader(simple_shader_code, sizeof(simple_shader_code), &blob); D3D::device->CreateInputLayout(simpleelems, 2, blob->Data(), blob->Size(), &SimpleLayout); SimpleVertexShader = D3D::CreateVertexShaderFromByteCode(blob); if (SimpleLayout == NULL || SimpleVertexShader == NULL) PanicAlert("Failed to create simple vertex shader or input layout at %s %d\n", __FILE__, __LINE__); @@ -151,7 +151,7 @@ void VertexShaderCache::Init() D3D::SetDebugObjectName((ID3D11DeviceChild*)SimpleVertexShader, "simple vertex shader"); D3D::SetDebugObjectName((ID3D11DeviceChild*)SimpleLayout, "simple input layout"); - D3D::CompileVertexShader(clear_shader_code, (int)strlen(clear_shader_code), &blob); + D3D::CompileVertexShader(clear_shader_code, sizeof(clear_shader_code), &blob); D3D::device->CreateInputLayout(clearelems, 2, blob->Data(), blob->Size(), &ClearLayout); ClearVertexShader = D3D::CreateVertexShaderFromByteCode(blob); if (ClearLayout == NULL || ClearVertexShader == NULL) PanicAlert("Failed to create clear vertex shader or input layout at %s %d\n", __FILE__, __LINE__); -- 2.11.4.GIT