diff --git a/src/d3d11/d3d11_blend.cpp b/src/d3d11/d3d11_blend.cpp index 1dfca8a18..ce1180418 100644 --- a/src/d3d11/d3d11_blend.cpp +++ b/src/d3d11/d3d11_blend.cpp @@ -27,8 +27,8 @@ namespace dxvk { if (desc.IndependentBlendEnable && desc.RenderTarget[0].LogicOpEnable) Logger::warn("D3D11: Per-target logic ops not supported"); - m_loState.enableLogicOp = desc.RenderTarget[0].LogicOpEnable; - m_loState.logicOp = DecodeLogicOp(desc.RenderTarget[0].LogicOp); + m_loState.setLogicOp(desc.RenderTarget[0].LogicOpEnable, + DecodeLogicOp(desc.RenderTarget[0].LogicOp)); } @@ -96,9 +96,6 @@ namespace dxvk { // blend mode array will be identical for (uint32_t i = 0; i < m_blendModes.size(); i++) ctx->setBlendMode(i, m_blendModes.at(i)); - - // Set up logic op state as well - ctx->setLogicOpState(m_loState); } diff --git a/src/d3d11/d3d11_blend.h b/src/d3d11/d3d11_blend.h index c6311b072..d20439464 100644 --- a/src/d3d11/d3d11_blend.h +++ b/src/d3d11/d3d11_blend.h @@ -38,6 +38,10 @@ namespace dxvk { return msState; } + DxvkLogicOpState GetLoState() const { + return m_loState; + } + void BindToContext( DxvkContext* ctx) const; @@ -57,10 +61,10 @@ namespace dxvk { std::array m_blendModes; DxvkMultisampleState m_msState = { }; - DxvkLogicOpState m_loState; + DxvkLogicOpState m_loState = { }; D3D10BlendState m_d3d10; - + static DxvkBlendMode DecodeBlendMode( const D3D11_RENDER_TARGET_BLEND_DESC1& BlendDesc); diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 162e75217..3ea1debb8 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -3381,25 +3381,26 @@ namespace dxvk { if (m_state.om.cbState != nullptr) { EmitCs([ cBlendState = m_state.om.cbState, - cMsState = m_state.om.cbState->GetMsState(m_state.om.sampleMask) + cMsState = m_state.om.cbState->GetMsState(m_state.om.sampleMask), + cLoState = m_state.om.cbState->GetLoState() ] (DxvkContext* ctx) { cBlendState->BindToContext(ctx); ctx->setMultisampleState(cMsState); + ctx->setLogicOpState(cLoState); }); } else { EmitCs([ cSampleMask = m_state.om.sampleMask ] (DxvkContext* ctx) { DxvkBlendMode cbState; - DxvkLogicOpState loState; - InitDefaultBlendState(&cbState, &loState); + InitDefaultBlendState(&cbState); for (uint32_t i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) ctx->setBlendMode(i, cbState); - ctx->setLogicOpState(loState); ctx->setMultisampleState(InitDefaultMultisampleState(cSampleMask)); + ctx->setLogicOpState(InitDefaultLogicOpState()); }); } } @@ -4740,13 +4741,12 @@ namespace dxvk { InitDefaultRasterizerState(&rsState); DxvkBlendMode cbState; - DxvkLogicOpState loState; - InitDefaultBlendState(&cbState, &loState); + InitDefaultBlendState(&cbState); ctx->setInputAssemblyState(iaState); ctx->setDepthStencilState(InitDefaultDepthStencilState()); ctx->setRasterizerState(rsState); - ctx->setLogicOpState(loState); + ctx->setLogicOpState(InitDefaultLogicOpState()); ctx->setMultisampleState(InitDefaultMultisampleState(D3D11_DEFAULT_SAMPLE_MASK)); for (uint32_t i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) @@ -5831,10 +5831,17 @@ namespace dxvk { } + template + DxvkLogicOpState D3D11CommonContext::InitDefaultLogicOpState() { + DxvkLogicOpState loState = { }; + loState.setLogicOp(false, VK_LOGIC_OP_NO_OP); + return loState; + } + + template void D3D11CommonContext::InitDefaultBlendState( - DxvkBlendMode* pCbState, - DxvkLogicOpState* pLoState) { + DxvkBlendMode* pCbState) { pCbState->enableBlending = VK_FALSE; pCbState->colorSrcFactor = VK_BLEND_FACTOR_ONE; pCbState->colorDstFactor = VK_BLEND_FACTOR_ZERO; @@ -5844,9 +5851,6 @@ namespace dxvk { pCbState->alphaBlendOp = VK_BLEND_OP_ADD; pCbState->writeMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; - - pLoState->enableLogicOp = VK_FALSE; - pLoState->logicOp = VK_LOGIC_OP_NO_OP; } // Explicitly instantiate here diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index de985892a..e91c6dd2f 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -1154,9 +1154,10 @@ namespace dxvk { static DxvkMultisampleState InitDefaultMultisampleState( UINT SampleMask); + static DxvkLogicOpState InitDefaultLogicOpState(); + static void InitDefaultBlendState( - DxvkBlendMode* pCbState, - DxvkLogicOpState* pLoState); + DxvkBlendMode* pCbState); template void EmitCs(Cmd&& command) { diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 7c2b165d4..697a56f04 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -82,9 +82,7 @@ namespace dxvk { ctx->beginRecording(cDevice->createCommandList()); // Disable logic op once and for all. - DxvkLogicOpState loState; - loState.enableLogicOp = VK_FALSE; - loState.logicOp = VK_LOGIC_OP_CLEAR; + DxvkLogicOpState loState = { }; ctx->setLogicOpState(loState); }); diff --git a/src/dxvk/dxvk_constant_state.h b/src/dxvk/dxvk_constant_state.h index 10bd122b4..74f21ff03 100644 --- a/src/dxvk/dxvk_constant_state.h +++ b/src/dxvk/dxvk_constant_state.h @@ -312,9 +312,29 @@ namespace dxvk { * \brief Logic op state * Defines a logic op. */ - struct DxvkLogicOpState { - VkBool32 enableLogicOp; - VkLogicOp logicOp; + class DxvkLogicOpState { + + public: + + bool logicOpEnable() const { + return m_logicOpEnable; + } + + VkLogicOp logicOp() const { + return VkLogicOp(m_logicOp); + } + + void setLogicOp(bool enable, VkLogicOp op) { + m_logicOpEnable = enable; + m_logicOp = uint8_t(op); + } + + private: + + uint8_t m_logicOpEnable : 1; + uint8_t m_logicOp : 4; + uint8_t m_reserved : 3; + }; diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 1f58e48ee..f19f71809 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -2812,8 +2812,8 @@ namespace dxvk { void DxvkContext::setLogicOpState(const DxvkLogicOpState& lo) { m_state.gp.state.om = DxvkOmInfo( - lo.enableLogicOp, - lo.logicOp, + lo.logicOpEnable(), + lo.logicOp(), m_state.gp.state.om.feedbackLoop()); m_flags.set(DxvkContextFlag::GpDirtyPipelineState);