From 5d571b068f5019fd9927fa03150fbafecf3d9bda Mon Sep 17 00:00:00 2001 From: iwubcode Date: Fri, 10 Feb 2023 19:10:55 -0600 Subject: [PATCH] VideoBackends: rework d3d11 to specify samplers/bound textures using a bitset with a constant size, instead of hardcoding each individual enumeration value --- Source/Core/VideoBackends/D3D/D3DState.cpp | 70 ++++++++---------- Source/Core/VideoBackends/D3D/D3DState.h | 86 +++++++++------------- 2 files changed, 68 insertions(+), 88 deletions(-) diff --git a/Source/Core/VideoBackends/D3D/D3DState.cpp b/Source/Core/VideoBackends/D3D/D3DState.cpp index 8ab1991e90..7beec54611 100644 --- a/Source/Core/VideoBackends/D3D/D3DState.cpp +++ b/Source/Core/VideoBackends/D3D/D3DState.cpp @@ -28,12 +28,12 @@ StateManager::~StateManager() = default; void StateManager::Apply() { - if (!m_dirtyFlags) + if (m_dirtyFlags.none()) return; // Framebuffer changes must occur before texture changes, otherwise the D3D runtime messes with // our bindings and sets them to null to prevent hazards. - if (m_dirtyFlags & DirtyFlag_Framebuffer) + if (m_dirtyFlags.test(DirtyFlag_Framebuffer)) { if (g_ActiveConfig.backend_info.bSupportsBBox) { @@ -56,11 +56,14 @@ void StateManager::Apply() m_current.use_integer_rtv = m_pending.use_integer_rtv; } - u32 dirtyConstants = m_dirtyFlags & (DirtyFlag_PixelConstants | DirtyFlag_VertexConstants | - DirtyFlag_GeometryConstants); - u32 dirtyShaders = - m_dirtyFlags & (DirtyFlag_PixelShader | DirtyFlag_VertexShader | DirtyFlag_GeometryShader); - u32 dirtyBuffers = m_dirtyFlags & (DirtyFlag_VertexBuffer | DirtyFlag_IndexBuffer); + const bool dirtyConstants = m_dirtyFlags.test(DirtyFlag_PixelConstants) || + m_dirtyFlags.test(DirtyFlag_VertexConstants) || + m_dirtyFlags.test(DirtyFlag_GeometryConstants); + const bool dirtyShaders = m_dirtyFlags.test(DirtyFlag_PixelShader) || + m_dirtyFlags.test(DirtyFlag_VertexShader) || + m_dirtyFlags.test(DirtyFlag_GeometryShader); + const bool dirtyBuffers = + m_dirtyFlags.test(DirtyFlag_VertexBuffer) || m_dirtyFlags.test(DirtyFlag_IndexBuffer); if (dirtyConstants) { @@ -87,7 +90,7 @@ void StateManager::Apply() } } - if (dirtyBuffers || (m_dirtyFlags & DirtyFlag_InputAssembler)) + if (dirtyBuffers || (m_dirtyFlags.test(DirtyFlag_InputAssembler))) { if (m_current.vertexBuffer != m_pending.vertexBuffer || m_current.vertexBufferStride != m_pending.vertexBufferStride || @@ -140,17 +143,17 @@ void StateManager::Apply() } } - if (m_dirtyFlags & DirtyFlag_BlendState) + if (m_dirtyFlags.test(DirtyFlag_BlendState)) { D3D::context->OMSetBlendState(m_pending.blendState, nullptr, 0xFFFFFFFF); m_current.blendState = m_pending.blendState; } - if (m_dirtyFlags & DirtyFlag_DepthState) + if (m_dirtyFlags.test(DirtyFlag_DepthState)) { D3D::context->OMSetDepthStencilState(m_pending.depthState, 0); m_current.depthState = m_pending.depthState; } - if (m_dirtyFlags & DirtyFlag_RasterizerState) + if (m_dirtyFlags.test(DirtyFlag_RasterizerState)) { D3D::context->RSSetState(m_pending.rasterizerState); m_current.rasterizerState = m_pending.rasterizerState; @@ -163,41 +166,32 @@ void StateManager::Apply() void StateManager::ApplyTextures() { - const int textureMaskShift = std::countr_zero((u32)DirtyFlag_Texture0); - const int samplerMaskShift = std::countr_zero((u32)DirtyFlag_Sampler0); - - u32 dirtyTextures = - (m_dirtyFlags & - (DirtyFlag_Texture0 | DirtyFlag_Texture1 | DirtyFlag_Texture2 | DirtyFlag_Texture3 | - DirtyFlag_Texture4 | DirtyFlag_Texture5 | DirtyFlag_Texture6 | DirtyFlag_Texture7)) >> - textureMaskShift; - u32 dirtySamplers = - (m_dirtyFlags & - (DirtyFlag_Sampler0 | DirtyFlag_Sampler1 | DirtyFlag_Sampler2 | DirtyFlag_Sampler3 | - DirtyFlag_Sampler4 | DirtyFlag_Sampler5 | DirtyFlag_Sampler6 | DirtyFlag_Sampler7)) >> - samplerMaskShift; - while (dirtyTextures) + for (u32 i = 0; i < VideoCommon::MAX_PIXEL_SHADER_SAMPLERS; i++) { - const int index = std::countr_zero(dirtyTextures); - if (m_current.textures[index] != m_pending.textures[index]) + const u32 flag = i; + if (m_dirtyFlags.test(flag)) { - D3D::context->PSSetShaderResources(index, 1, &m_pending.textures[index]); - m_current.textures[index] = m_pending.textures[index]; + if (m_current.textures[i] != m_pending.textures[i]) + { + D3D::context->PSSetShaderResources(i, 1, &m_pending.textures[i]); + m_current.textures[i] = m_pending.textures[i]; + } + m_dirtyFlags.reset(flag); } - - dirtyTextures &= ~(1 << index); } - while (dirtySamplers) + for (u32 i = 0; i < VideoCommon::MAX_PIXEL_SHADER_SAMPLERS; i++) { - const int index = std::countr_zero(dirtySamplers); - if (m_current.samplers[index] != m_pending.samplers[index]) + const u32 flag = i + VideoCommon::MAX_PIXEL_SHADER_SAMPLERS; + if (m_dirtyFlags.test(flag)) { - D3D::context->PSSetSamplers(index, 1, &m_pending.samplers[index]); - m_current.samplers[index] = m_pending.samplers[index]; + if (m_current.samplers[i] != m_pending.samplers[i]) + { + D3D::context->PSSetSamplers(i, 1, &m_pending.samplers[i]); + m_current.samplers[i] = m_pending.samplers[i]; + } + m_dirtyFlags.reset(flag); } - - dirtySamplers &= ~(1 << index); } } diff --git a/Source/Core/VideoBackends/D3D/D3DState.h b/Source/Core/VideoBackends/D3D/D3DState.h index 812fc778ae..eba58c2431 100644 --- a/Source/Core/VideoBackends/D3D/D3DState.h +++ b/Source/Core/VideoBackends/D3D/D3DState.h @@ -4,6 +4,7 @@ #pragma once #include +#include #include #include #include @@ -53,7 +54,7 @@ public: void SetBlendState(ID3D11BlendState* state) { if (m_current.blendState != state) - m_dirtyFlags |= DirtyFlag_BlendState; + m_dirtyFlags.set(DirtyFlag_BlendState); m_pending.blendState = state; } @@ -61,7 +62,7 @@ public: void SetDepthState(ID3D11DepthStencilState* state) { if (m_current.depthState != state) - m_dirtyFlags |= DirtyFlag_DepthState; + m_dirtyFlags.set(DirtyFlag_DepthState); m_pending.depthState = state; } @@ -69,7 +70,7 @@ public: void SetRasterizerState(ID3D11RasterizerState* state) { if (m_current.rasterizerState != state) - m_dirtyFlags |= DirtyFlag_RasterizerState; + m_dirtyFlags.set(DirtyFlag_RasterizerState); m_pending.rasterizerState = state; } @@ -77,7 +78,7 @@ public: void SetTexture(size_t index, ID3D11ShaderResourceView* texture) { if (m_current.textures[index] != texture) - m_dirtyFlags |= DirtyFlag_Texture0 << index; + m_dirtyFlags.set(DirtyFlag_Texture0 + index); m_pending.textures[index] = texture; } @@ -85,7 +86,7 @@ public: void SetSampler(size_t index, ID3D11SamplerState* sampler) { if (m_current.samplers[index] != sampler) - m_dirtyFlags |= DirtyFlag_Sampler0 << index; + m_dirtyFlags.set(DirtyFlag_Sampler0 + index); m_pending.samplers[index] = sampler; } @@ -93,7 +94,7 @@ public: void SetPixelConstants(ID3D11Buffer* buffer0, ID3D11Buffer* buffer1 = nullptr) { if (m_current.pixelConstants[0] != buffer0 || m_current.pixelConstants[1] != buffer1) - m_dirtyFlags |= DirtyFlag_PixelConstants; + m_dirtyFlags.set(DirtyFlag_PixelConstants); m_pending.pixelConstants[0] = buffer0; m_pending.pixelConstants[1] = buffer1; @@ -102,7 +103,7 @@ public: void SetVertexConstants(ID3D11Buffer* buffer) { if (m_current.vertexConstants != buffer) - m_dirtyFlags |= DirtyFlag_VertexConstants; + m_dirtyFlags.set(DirtyFlag_VertexConstants); m_pending.vertexConstants = buffer; } @@ -110,7 +111,7 @@ public: void SetGeometryConstants(ID3D11Buffer* buffer) { if (m_current.geometryConstants != buffer) - m_dirtyFlags |= DirtyFlag_GeometryConstants; + m_dirtyFlags.set(DirtyFlag_GeometryConstants); m_pending.geometryConstants = buffer; } @@ -119,7 +120,7 @@ public: { if (m_current.vertexBuffer != buffer || m_current.vertexBufferStride != stride || m_current.vertexBufferOffset != offset) - m_dirtyFlags |= DirtyFlag_VertexBuffer; + m_dirtyFlags.set(DirtyFlag_VertexBuffer); m_pending.vertexBuffer = buffer; m_pending.vertexBufferStride = stride; @@ -129,7 +130,7 @@ public: void SetIndexBuffer(ID3D11Buffer* buffer) { if (m_current.indexBuffer != buffer) - m_dirtyFlags |= DirtyFlag_IndexBuffer; + m_dirtyFlags.set(DirtyFlag_IndexBuffer); m_pending.indexBuffer = buffer; } @@ -137,7 +138,7 @@ public: void SetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY topology) { if (m_current.topology != topology) - m_dirtyFlags |= DirtyFlag_InputAssembler; + m_dirtyFlags.set(DirtyFlag_InputAssembler); m_pending.topology = topology; } @@ -145,7 +146,7 @@ public: void SetInputLayout(ID3D11InputLayout* layout) { if (m_current.inputLayout != layout) - m_dirtyFlags |= DirtyFlag_InputAssembler; + m_dirtyFlags.set(DirtyFlag_InputAssembler); m_pending.inputLayout = layout; } @@ -153,7 +154,7 @@ public: void SetPixelShader(ID3D11PixelShader* shader) { if (m_current.pixelShader != shader) - m_dirtyFlags |= DirtyFlag_PixelShader; + m_dirtyFlags.set(DirtyFlag_PixelShader); m_pending.pixelShader = shader; } @@ -169,7 +170,7 @@ public: void SetVertexShader(ID3D11VertexShader* shader) { if (m_current.vertexShader != shader) - m_dirtyFlags |= DirtyFlag_VertexShader; + m_dirtyFlags.set(DirtyFlag_VertexShader); m_pending.vertexShader = shader; } @@ -177,7 +178,7 @@ public: void SetGeometryShader(ID3D11GeometryShader* shader) { if (m_current.geometryShader != shader) - m_dirtyFlags |= DirtyFlag_GeometryShader; + m_dirtyFlags.set(DirtyFlag_GeometryShader); m_pending.geometryShader = shader; } @@ -185,7 +186,7 @@ public: void SetFramebuffer(DXFramebuffer* fb) { if (m_current.framebuffer != fb) - m_dirtyFlags |= DirtyFlag_Framebuffer; + m_dirtyFlags.set(DirtyFlag_Framebuffer); m_pending.framebuffer = fb; } @@ -193,7 +194,7 @@ public: void SetOMUAV(ID3D11UnorderedAccessView* uav) { if (m_current.uav != uav) - m_dirtyFlags |= DirtyFlag_Framebuffer; + m_dirtyFlags.set(DirtyFlag_Framebuffer); m_pending.uav = uav; } @@ -201,7 +202,7 @@ public: void SetIntegerRTV(bool enable) { if (m_current.use_integer_rtv != enable) - m_dirtyFlags |= DirtyFlag_Framebuffer; + m_dirtyFlags.set(DirtyFlag_Framebuffer); m_pending.use_integer_rtv = enable; } @@ -224,43 +225,28 @@ public: private: enum DirtyFlags { - DirtyFlag_Texture0 = 1 << 0, - DirtyFlag_Texture1 = 1 << 1, - DirtyFlag_Texture2 = 1 << 2, - DirtyFlag_Texture3 = 1 << 3, - DirtyFlag_Texture4 = 1 << 4, - DirtyFlag_Texture5 = 1 << 5, - DirtyFlag_Texture6 = 1 << 6, - DirtyFlag_Texture7 = 1 << 7, + DirtyFlag_Texture0 = 0, + DirtyFlag_Sampler0 = DirtyFlag_Texture0 + VideoCommon::MAX_PIXEL_SHADER_SAMPLERS, + DirtyFlag_PixelConstants = DirtyFlag_Sampler0 + VideoCommon::MAX_PIXEL_SHADER_SAMPLERS, + DirtyFlag_VertexConstants, + DirtyFlag_GeometryConstants, - DirtyFlag_Sampler0 = 1 << 8, - DirtyFlag_Sampler1 = 1 << 9, - DirtyFlag_Sampler2 = 1 << 10, - DirtyFlag_Sampler3 = 1 << 11, - DirtyFlag_Sampler4 = 1 << 12, - DirtyFlag_Sampler5 = 1 << 13, - DirtyFlag_Sampler6 = 1 << 14, - DirtyFlag_Sampler7 = 1 << 15, + DirtyFlag_VertexBuffer, + DirtyFlag_IndexBuffer, - DirtyFlag_PixelConstants = 1 << 16, - DirtyFlag_VertexConstants = 1 << 17, - DirtyFlag_GeometryConstants = 1 << 18, + DirtyFlag_PixelShader, + DirtyFlag_VertexShader, + DirtyFlag_GeometryShader, - DirtyFlag_VertexBuffer = 1 << 19, - DirtyFlag_IndexBuffer = 1 << 20, - - DirtyFlag_PixelShader = 1 << 21, - DirtyFlag_VertexShader = 1 << 22, - DirtyFlag_GeometryShader = 1 << 23, - - DirtyFlag_InputAssembler = 1 << 24, - DirtyFlag_BlendState = 1 << 25, - DirtyFlag_DepthState = 1 << 26, - DirtyFlag_RasterizerState = 1 << 27, - DirtyFlag_Framebuffer = 1 << 28 + DirtyFlag_InputAssembler, + DirtyFlag_BlendState, + DirtyFlag_DepthState, + DirtyFlag_RasterizerState, + DirtyFlag_Framebuffer, + DirtyFlag_Max }; - u32 m_dirtyFlags = ~0u; + std::bitset m_dirtyFlags; struct Resources {