From 798ec96e1447f8c21b4b774d3be9c50ed30a9318 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sat, 30 Sep 2017 16:19:16 +1000 Subject: [PATCH] D3D: Make state cache part of Renderer and not static --- Source/Core/VideoBackends/D3D/D3DState.cpp | 42 ++++++++------------ Source/Core/VideoBackends/D3D/D3DState.h | 5 +-- Source/Core/VideoBackends/D3D/Render.cpp | 45 ++++++++-------------- Source/Core/VideoBackends/D3D/Render.h | 13 +++++++ 4 files changed, 46 insertions(+), 59 deletions(-) diff --git a/Source/Core/VideoBackends/D3D/D3DState.cpp b/Source/Core/VideoBackends/D3D/D3DState.cpp index 5732ffd21b..41412342cc 100644 --- a/Source/Core/VideoBackends/D3D/D3DState.cpp +++ b/Source/Core/VideoBackends/D3D/D3DState.cpp @@ -263,6 +263,21 @@ void StateManager::SetTextureByMask(u32 textureSlotMask, ID3D11ShaderResourceVie } // namespace D3D +StateCache::~StateCache() +{ + for (auto& it : m_depth) + SAFE_RELEASE(it.second); + + for (auto& it : m_raster) + SAFE_RELEASE(it.second); + + for (auto& it : m_blend) + SAFE_RELEASE(it.second); + + for (auto& it : m_sampler) + SAFE_RELEASE(it.second); +} + ID3D11SamplerState* StateCache::Get(SamplerState state) { auto it = m_sampler.find(state.hex); @@ -471,33 +486,6 @@ ID3D11DepthStencilState* StateCache::Get(DepthState state) return res; } -void StateCache::Clear() -{ - for (auto it : m_depth) - { - SAFE_RELEASE(it.second); - } - m_depth.clear(); - - for (auto it : m_raster) - { - SAFE_RELEASE(it.second); - } - m_raster.clear(); - - for (auto it : m_blend) - { - SAFE_RELEASE(it.second); - } - m_blend.clear(); - - for (auto it : m_sampler) - { - SAFE_RELEASE(it.second); - } - m_sampler.clear(); -} - D3D11_PRIMITIVE_TOPOLOGY StateCache::GetPrimitiveTopology(PrimitiveType primitive) { static constexpr std::array primitives = { diff --git a/Source/Core/VideoBackends/D3D/D3DState.h b/Source/Core/VideoBackends/D3D/D3DState.h index 0c083f7c1b..6d2f72b17f 100644 --- a/Source/Core/VideoBackends/D3D/D3DState.h +++ b/Source/Core/VideoBackends/D3D/D3DState.h @@ -23,6 +23,8 @@ namespace DX11 class StateCache { public: + ~StateCache(); + // Get existing or create new render state. // Returned objects is owned by the cache and does not need to be released. ID3D11SamplerState* Get(SamplerState state); @@ -30,9 +32,6 @@ public: ID3D11RasterizerState* Get(RasterizationState state); ID3D11DepthStencilState* Get(DepthState state); - // Release all cached states and clear hash tables. - void Clear(); - // Convert RasterState primitive type to D3D11 primitive topology. static D3D11_PRIMITIVE_TOPOLOGY GetPrimitiveTopology(PrimitiveType primitive); diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp index 4fc2b1f084..41a48e9a8d 100644 --- a/Source/Core/VideoBackends/D3D/Render.cpp +++ b/Source/Core/VideoBackends/D3D/Render.cpp @@ -53,14 +53,6 @@ typedef struct _Nv_Stereo_Image_Header #define NVSTEREO_IMAGE_SIGNATURE 0x4433564e -struct GXPipelineState -{ - std::array samplers; - BlendingState blend; - DepthState zmode; - RasterizationState raster; -}; - static u32 s_last_multisamples = 1; static bool s_last_stereo_mode = false; static bool s_last_fullscreen_mode = false; @@ -74,9 +66,6 @@ static ID3D11RasterizerState* s_reset_rast_state = nullptr; static ID3D11Texture2D* s_screenshot_texture = nullptr; static D3DTexture2D* s_3d_vision_texture = nullptr; -static GXPipelineState s_gx_state; -static StateCache s_gx_state_cache; - static void SetupDeviceObjects() { HRESULT hr; @@ -173,8 +162,6 @@ static void TeardownDeviceObjects() SAFE_RELEASE(s_reset_rast_state); SAFE_RELEASE(s_screenshot_texture); SAFE_RELEASE(s_3d_vision_texture); - - s_gx_state_cache.Clear(); } static void Create3DVisionTexture(int width, int height) @@ -212,13 +199,13 @@ Renderer::Renderer() : ::Renderer(D3D::GetBackBufferWidth(), D3D::GetBackBufferH SetupDeviceObjects(); // Setup GX pipeline state - for (auto& sampler : s_gx_state.samplers) + for (auto& sampler : m_gx_state.samplers) sampler.hex = RenderState::GetPointSamplerState().hex; - s_gx_state.zmode.testenable = false; - s_gx_state.zmode.updateenable = false; - s_gx_state.zmode.func = ZMode::NEVER; - s_gx_state.raster.cullmode = GenMode::CULL_NONE; + m_gx_state.zmode.testenable = false; + m_gx_state.zmode.updateenable = false; + m_gx_state.zmode.func = ZMode::NEVER; + m_gx_state.raster.cullmode = GenMode::CULL_NONE; // Clear EFB textures constexpr std::array clear_color{{0.f, 0.f, 0.f, 1.f}}; @@ -600,7 +587,7 @@ void Renderer::ReinterpretPixelData(unsigned int convtype) void Renderer::SetBlendingState(const BlendingState& state) { - s_gx_state.blend.hex = state.hex; + m_gx_state.blend.hex = state.hex; } // This function has the final picture. We adjust the aspect ratio here. @@ -719,15 +706,15 @@ void Renderer::RestoreAPIState() void Renderer::ApplyState() { - D3D::stateman->PushBlendState(s_gx_state_cache.Get(s_gx_state.blend)); - D3D::stateman->PushDepthState(s_gx_state_cache.Get(s_gx_state.zmode)); - D3D::stateman->PushRasterizerState(s_gx_state_cache.Get(s_gx_state.raster)); + D3D::stateman->PushBlendState(m_state_cache.Get(m_gx_state.blend)); + D3D::stateman->PushDepthState(m_state_cache.Get(m_gx_state.zmode)); + D3D::stateman->PushRasterizerState(m_state_cache.Get(m_gx_state.raster)); D3D::stateman->SetPrimitiveTopology( - StateCache::GetPrimitiveTopology(s_gx_state.raster.primitive)); - FramebufferManager::SetIntegerEFBRenderTarget(s_gx_state.blend.logicopenable); + StateCache::GetPrimitiveTopology(m_gx_state.raster.primitive)); + FramebufferManager::SetIntegerEFBRenderTarget(m_gx_state.blend.logicopenable); - for (u32 stage = 0; stage < static_cast(s_gx_state.samplers.size()); stage++) - D3D::stateman->SetSampler(stage, s_gx_state_cache.Get(s_gx_state.samplers[stage])); + for (u32 stage = 0; stage < static_cast(m_gx_state.samplers.size()); stage++) + D3D::stateman->SetSampler(stage, m_state_cache.Get(m_gx_state.samplers[stage])); ID3D11Buffer* vertexConstants = VertexShaderCache::GetConstantBuffer(); @@ -746,17 +733,17 @@ void Renderer::RestoreState() void Renderer::SetRasterizationState(const RasterizationState& state) { - s_gx_state.raster.hex = state.hex; + m_gx_state.raster.hex = state.hex; } void Renderer::SetDepthState(const DepthState& state) { - s_gx_state.zmode.hex = state.hex; + m_gx_state.zmode.hex = state.hex; } void Renderer::SetSamplerState(u32 index, const SamplerState& state) { - s_gx_state.samplers[index].hex = state.hex; + m_gx_state.samplers[index].hex = state.hex; } void Renderer::SetInterlacingMode() diff --git a/Source/Core/VideoBackends/D3D/Render.h b/Source/Core/VideoBackends/D3D/Render.h index b35e0f9d20..340802f02f 100644 --- a/Source/Core/VideoBackends/D3D/Render.h +++ b/Source/Core/VideoBackends/D3D/Render.h @@ -5,6 +5,7 @@ #pragma once #include +#include "VideoBackends/D3D/D3DState.h" #include "VideoCommon/RenderBase.h" enum class EFBAccessType; @@ -19,6 +20,7 @@ public: Renderer(); ~Renderer() override; + StateCache& GetStateCache() { return m_state_cache; } void SetBlendingState(const BlendingState& state) override; void SetScissorRect(const EFBRectangle& rc) override; void SetRasterizationState(const RasterizationState& state) override; @@ -56,7 +58,18 @@ public: bool CheckForResize(); private: + struct GXPipelineState + { + std::array samplers; + BlendingState blend; + DepthState zmode; + RasterizationState raster; + }; + void BlitScreen(TargetRectangle src, TargetRectangle dst, D3DTexture2D* src_texture, u32 src_width, u32 src_height, float Gamma); + + StateCache m_state_cache; + GXPipelineState m_gx_state; }; }