summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends
diff options
context:
space:
mode:
authorStenzek <stenzek@gmail.com>2018-02-22 19:40:09 +1000
committerStenzek <stenzek@gmail.com>2018-02-22 19:40:55 +1000
commit31111ef1432bc5d6d653fbef175e8ca3ac2c152d (patch)
tree626b03faaf6fca9ba778aca5f096ef43d83fadc0 /Source/Core/VideoBackends
parente18c7b1c335c23f850c3bf3662c2bff15eae6518 (diff)
D3D: Remove state stack from tracker, set explicitly instead
Diffstat (limited to 'Source/Core/VideoBackends')
-rw-r--r--Source/Core/VideoBackends/D3D/D3DState.cpp104
-rw-r--r--Source/Core/VideoBackends/D3D/D3DState.h71
-rw-r--r--Source/Core/VideoBackends/D3D/D3DUtil.cpp6
-rw-r--r--Source/Core/VideoBackends/D3D/Render.cpp43
4 files changed, 65 insertions, 159 deletions
diff --git a/Source/Core/VideoBackends/D3D/D3DState.cpp b/Source/Core/VideoBackends/D3D/D3DState.cpp
index 41412342cc..b779683fb8 100644
--- a/Source/Core/VideoBackends/D3D/D3DState.cpp
+++ b/Source/Core/VideoBackends/D3D/D3DState.cpp
@@ -20,97 +20,13 @@ namespace D3D
{
StateManager* stateman;
-template <typename T>
-AutoState<T>::AutoState(const T* object) : state(object)
-{
- ((IUnknown*)state)->AddRef();
-}
-
-template <typename T>
-AutoState<T>::AutoState(const AutoState<T>& source)
-{
- state = source.GetPtr();
- ((T*)state)->AddRef();
-}
-
-template <typename T>
-AutoState<T>::~AutoState()
-{
- if (state)
- ((T*)state)->Release();
- state = nullptr;
-}
-
-StateManager::StateManager()
- : m_currentBlendState(nullptr), m_currentDepthState(nullptr), m_currentRasterizerState(nullptr),
- m_dirtyFlags(~0u), m_pending(), m_current()
-{
-}
-
-void StateManager::PushBlendState(const ID3D11BlendState* state)
-{
- m_blendStates.push(AutoBlendState(state));
-}
-void StateManager::PushDepthState(const ID3D11DepthStencilState* state)
-{
- m_depthStates.push(AutoDepthStencilState(state));
-}
-void StateManager::PushRasterizerState(const ID3D11RasterizerState* state)
-{
- m_rasterizerStates.push(AutoRasterizerState(state));
-}
-void StateManager::PopBlendState()
-{
- m_blendStates.pop();
-}
-void StateManager::PopDepthState()
-{
- m_depthStates.pop();
-}
-void StateManager::PopRasterizerState()
-{
- m_rasterizerStates.pop();
-}
+StateManager::StateManager() = default;
+StateManager::~StateManager() = default;
void StateManager::Apply()
{
- if (!m_blendStates.empty())
- {
- if (m_currentBlendState != m_blendStates.top().GetPtr())
- {
- m_currentBlendState = (ID3D11BlendState*)m_blendStates.top().GetPtr();
- D3D::context->OMSetBlendState(m_currentBlendState, nullptr, 0xFFFFFFFF);
- }
- }
- else
- ERROR_LOG(VIDEO, "Tried to apply without blend state!");
-
- if (!m_depthStates.empty())
- {
- if (m_currentDepthState != m_depthStates.top().GetPtr())
- {
- m_currentDepthState = (ID3D11DepthStencilState*)m_depthStates.top().GetPtr();
- D3D::context->OMSetDepthStencilState(m_currentDepthState, 0);
- }
- }
- else
- ERROR_LOG(VIDEO, "Tried to apply without depth state!");
-
- if (!m_rasterizerStates.empty())
- {
- if (m_currentRasterizerState != m_rasterizerStates.top().GetPtr())
- {
- m_currentRasterizerState = (ID3D11RasterizerState*)m_rasterizerStates.top().GetPtr();
- D3D::context->RSSetState(m_currentRasterizerState);
- }
- }
- else
- ERROR_LOG(VIDEO, "Tried to apply without rasterizer state!");
-
if (!m_dirtyFlags)
- {
return;
- }
int textureMaskShift = LeastSignificantSetBit((u32)DirtyFlag_Texture0);
int samplerMaskShift = LeastSignificantSetBit((u32)DirtyFlag_Sampler0);
@@ -232,6 +148,22 @@ void StateManager::Apply()
}
}
+ if (m_dirtyFlags & DirtyFlag_BlendState)
+ {
+ D3D::context->OMSetBlendState(m_pending.blendState, nullptr, 0xFFFFFFFF);
+ m_current.blendState = m_pending.blendState;
+ }
+ if (m_dirtyFlags & DirtyFlag_DepthState)
+ {
+ D3D::context->OMSetDepthStencilState(m_pending.depthState, 0);
+ m_current.depthState = m_pending.depthState;
+ }
+ if (m_dirtyFlags & DirtyFlag_RasterizerState)
+ {
+ D3D::context->RSSetState(m_pending.rasterizerState);
+ m_current.rasterizerState = m_pending.rasterizerState;
+ }
+
m_dirtyFlags = 0;
}
diff --git a/Source/Core/VideoBackends/D3D/D3DState.h b/Source/Core/VideoBackends/D3D/D3DState.h
index f7565cae45..805ed8996b 100644
--- a/Source/Core/VideoBackends/D3D/D3DState.h
+++ b/Source/Core/VideoBackends/D3D/D3DState.h
@@ -6,7 +6,6 @@
#include <array>
#include <cstddef>
-#include <stack>
#include <unordered_map>
#include "Common/BitField.h"
@@ -14,10 +13,6 @@
#include "VideoBackends/D3D/D3DBase.h"
#include "VideoCommon/RenderState.h"
-struct ID3D11BlendState;
-struct ID3D11DepthStencilState;
-struct ID3D11RasterizerState;
-
namespace DX11
{
class StateCache
@@ -44,37 +39,35 @@ private:
namespace D3D
{
-template <typename T>
-class AutoState
+class StateManager
{
public:
- AutoState(const T* object);
- AutoState(const AutoState<T>& source);
- ~AutoState();
+ StateManager();
+ ~StateManager();
- const inline T* GetPtr() const { return state; }
-private:
- const T* state;
-};
+ void SetBlendState(ID3D11BlendState* state)
+ {
+ if (m_current.blendState != state)
+ m_dirtyFlags |= DirtyFlag_BlendState;
-typedef AutoState<ID3D11BlendState> AutoBlendState;
-typedef AutoState<ID3D11DepthStencilState> AutoDepthStencilState;
-typedef AutoState<ID3D11RasterizerState> AutoRasterizerState;
+ m_pending.blendState = state;
+ }
-class StateManager
-{
-public:
- StateManager();
+ void SetDepthState(ID3D11DepthStencilState* state)
+ {
+ if (m_current.depthState != state)
+ m_dirtyFlags |= DirtyFlag_DepthState;
- // call any of these to change the affected states
- void PushBlendState(const ID3D11BlendState* state);
- void PushDepthState(const ID3D11DepthStencilState* state);
- void PushRasterizerState(const ID3D11RasterizerState* state);
+ m_pending.depthState = state;
+ }
- // call these after drawing
- void PopBlendState();
- void PopDepthState();
- void PopRasterizerState();
+ void SetRasterizerState(ID3D11RasterizerState* state)
+ {
+ if (m_current.rasterizerState != state)
+ m_dirtyFlags |= DirtyFlag_RasterizerState;
+
+ m_pending.rasterizerState = state;
+ }
void SetTexture(size_t index, ID3D11ShaderResourceView* texture)
{
@@ -209,14 +202,6 @@ public:
void Apply();
private:
- std::stack<AutoBlendState> m_blendStates;
- std::stack<AutoDepthStencilState> m_depthStates;
- std::stack<AutoRasterizerState> m_rasterizerStates;
-
- ID3D11BlendState* m_currentBlendState;
- ID3D11DepthStencilState* m_currentDepthState;
- ID3D11RasterizerState* m_currentRasterizerState;
-
enum DirtyFlags
{
DirtyFlag_Texture0 = 1 << 0,
@@ -251,9 +236,12 @@ private:
DirtyFlag_ComputeShader = 1 << 25,
DirtyFlag_InputAssembler = 1 << 26,
+ DirtyFlag_BlendState = 1 << 27,
+ DirtyFlag_DepthState = 1 << 28,
+ DirtyFlag_RasterizerState = 1 << 29,
};
- u32 m_dirtyFlags;
+ u32 m_dirtyFlags = ~0u;
struct Resources
{
@@ -273,10 +261,13 @@ private:
ID3D11VertexShader* vertexShader;
ID3D11GeometryShader* geometryShader;
ID3D11ComputeShader* computeShader;
+ ID3D11BlendState* blendState;
+ ID3D11DepthStencilState* depthState;
+ ID3D11RasterizerState* rasterizerState;
};
- Resources m_pending;
- Resources m_current;
+ Resources m_pending = {};
+ Resources m_current = {};
};
extern StateManager* stateman;
diff --git a/Source/Core/VideoBackends/D3D/D3DUtil.cpp b/Source/Core/VideoBackends/D3D/D3DUtil.cpp
index bd95004bfe..138db0554b 100644
--- a/Source/Core/VideoBackends/D3D/D3DUtil.cpp
+++ b/Source/Core/VideoBackends/D3D/D3DUtil.cpp
@@ -406,8 +406,8 @@ int CD3DFont::DrawTextScaled(float x, float y, float size, float spacing, u32 dw
pVertices = (D3D::FONT2DVERTEX*)vbmap.pData;
// set general pipeline state
- D3D::stateman->PushBlendState(m_blendstate);
- D3D::stateman->PushRasterizerState(m_raststate);
+ D3D::stateman->SetBlendState(m_blendstate);
+ D3D::stateman->SetRasterizerState(m_raststate);
D3D::stateman->SetPixelShader(m_pshader);
D3D::stateman->SetVertexShader(m_vshader);
@@ -478,8 +478,6 @@ int CD3DFont::DrawTextScaled(float x, float y, float size, float spacing, u32 dw
D3D::stateman->Apply();
D3D::context->Draw(3 * dwNumTriangles, 0);
}
- D3D::stateman->PopBlendState();
- D3D::stateman->PopRasterizerState();
return S_OK;
}
diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp
index 0e8c822d23..77281ffa37 100644
--- a/Source/Core/VideoBackends/D3D/Render.cpp
+++ b/Source/Core/VideoBackends/D3D/Render.cpp
@@ -405,8 +405,8 @@ void Renderer::PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num
}
else // if (type == EFBAccessType::PokeZ)
{
- D3D::stateman->PushBlendState(m_clear_blend_states[3]);
- D3D::stateman->PushDepthState(m_clear_depth_states[1]);
+ D3D::stateman->SetBlendState(m_clear_blend_states[3]);
+ D3D::stateman->SetDepthState(m_clear_depth_states[1]);
D3D11_VIEWPORT vp =
CD3D11_VIEWPORT(0.0f, 0.0f, (float)GetTargetWidth(), (float)GetTargetHeight());
@@ -417,12 +417,6 @@ void Renderer::PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num
D3D::DrawEFBPokeQuads(type, points, num_points);
- if (type == EFBAccessType::PokeZ)
- {
- D3D::stateman->PopDepthState();
- D3D::stateman->PopBlendState();
- }
-
RestoreAPIState();
}
@@ -446,21 +440,21 @@ void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaE
ResetAPIState();
if (colorEnable && alphaEnable)
- D3D::stateman->PushBlendState(m_clear_blend_states[0]);
+ D3D::stateman->SetBlendState(m_clear_blend_states[0]);
else if (colorEnable)
- D3D::stateman->PushBlendState(m_clear_blend_states[1]);
+ D3D::stateman->SetBlendState(m_clear_blend_states[1]);
else if (alphaEnable)
- D3D::stateman->PushBlendState(m_clear_blend_states[2]);
+ D3D::stateman->SetBlendState(m_clear_blend_states[2]);
else
- D3D::stateman->PushBlendState(m_clear_blend_states[3]);
+ D3D::stateman->SetBlendState(m_clear_blend_states[3]);
// TODO: Should we enable Z testing here?
// if (!bpmem.zmode.testenable) D3D::stateman->PushDepthState(s_clear_depth_states[0]);
// else
if (zEnable)
- D3D::stateman->PushDepthState(m_clear_depth_states[1]);
+ D3D::stateman->SetDepthState(m_clear_depth_states[1]);
else /*if (!zEnable)*/
- D3D::stateman->PushDepthState(m_clear_depth_states[2]);
+ D3D::stateman->SetDepthState(m_clear_depth_states[2]);
// Update the view port for clearing the picture
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc);
@@ -474,9 +468,6 @@ void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaE
u32 rgbaColor = (color & 0xFF00FF00) | ((color >> 16) & 0xFF) | ((color << 16) & 0xFF0000);
D3D::drawClearQuad(rgbaColor, 1.0f - (z & 0xFFFFFF) / 16777216.0f);
- D3D::stateman->PopDepthState();
- D3D::stateman->PopBlendState();
-
RestoreAPIState();
}
@@ -646,26 +637,23 @@ void Renderer::UpdateBackbufferSize()
// ALWAYS call RestoreAPIState for each ResetAPIState call you're doing
void Renderer::ResetAPIState()
{
- D3D::stateman->PushBlendState(m_reset_blend_state);
- D3D::stateman->PushDepthState(m_reset_depth_state);
- D3D::stateman->PushRasterizerState(m_reset_rast_state);
+ D3D::stateman->SetBlendState(m_reset_blend_state);
+ D3D::stateman->SetDepthState(m_reset_depth_state);
+ D3D::stateman->SetRasterizerState(m_reset_rast_state);
}
void Renderer::RestoreAPIState()
{
// Gets us back into a more game-like state.
- D3D::stateman->PopBlendState();
- D3D::stateman->PopDepthState();
- D3D::stateman->PopRasterizerState();
BPFunctions::SetViewport();
BPFunctions::SetScissor();
}
void Renderer::ApplyState()
{
- 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->SetBlendState(m_state_cache.Get(m_gx_state.blend));
+ D3D::stateman->SetDepthState(m_state_cache.Get(m_gx_state.zmode));
+ D3D::stateman->SetRasterizerState(m_state_cache.Get(m_gx_state.raster));
D3D::stateman->SetPrimitiveTopology(
StateCache::GetPrimitiveTopology(m_gx_state.raster.primitive));
FramebufferManager::SetIntegerEFBRenderTarget(m_gx_state.blend.logicopenable);
@@ -683,9 +671,6 @@ void Renderer::ApplyState()
void Renderer::RestoreState()
{
- D3D::stateman->PopBlendState();
- D3D::stateman->PopDepthState();
- D3D::stateman->PopRasterizerState();
}
void Renderer::SetRasterizationState(const RasterizationState& state)