1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-04-01 09:25:24 +02:00

[dxvk,d3d9,d3d11] Refactor multisample state object

This commit is contained in:
Philip Rebohle 2025-03-22 15:47:35 +01:00
parent 62339e6d1b
commit abb5db346c
7 changed files with 67 additions and 40 deletions

View File

@ -19,8 +19,8 @@ namespace dxvk {
} }
// Multisample state is part of the blend state in D3D11 // Multisample state is part of the blend state in D3D11
m_msState.sampleMask = 0; // Set during bind m_msState.setSampleMask(0u); // Set during bind
m_msState.enableAlphaToCoverage = desc.AlphaToCoverageEnable; m_msState.setAlphaToCoverage(desc.AlphaToCoverageEnable);
// Vulkan only supports a global logic op for the blend // Vulkan only supports a global logic op for the blend
// state, which might be problematic in some cases. // state, which might be problematic in some cases.
@ -90,19 +90,13 @@ namespace dxvk {
void D3D11BlendState::BindToContext( void D3D11BlendState::BindToContext(
DxvkContext* ctx, DxvkContext* ctx) const {
uint32_t sampleMask) const {
// We handled Independent Blend during object creation // We handled Independent Blend during object creation
// already, so if it is disabled, all elements in the // already, so if it is disabled, all elements in the
// blend mode array will be identical // blend mode array will be identical
for (uint32_t i = 0; i < m_blendModes.size(); i++) for (uint32_t i = 0; i < m_blendModes.size(); i++)
ctx->setBlendMode(i, m_blendModes.at(i)); ctx->setBlendMode(i, m_blendModes.at(i));
// The sample mask is dynamic state in D3D11
DxvkMultisampleState msState = m_msState;
msState.sampleMask = sampleMask;
ctx->setMultisampleState(msState);
// Set up logic op state as well // Set up logic op state as well
ctx->setLogicOpState(m_loState); ctx->setLogicOpState(m_loState);
} }

View File

@ -32,9 +32,14 @@ namespace dxvk {
void STDMETHODCALLTYPE GetDesc1( void STDMETHODCALLTYPE GetDesc1(
D3D11_BLEND_DESC1* pDesc) final; D3D11_BLEND_DESC1* pDesc) final;
DxvkMultisampleState GetMsState(uint32_t SampleMask) const {
DxvkMultisampleState msState = m_msState;
msState.setSampleMask(SampleMask);
return msState;
}
void BindToContext( void BindToContext(
DxvkContext* ctx, DxvkContext* ctx) const;
UINT sampleMask) const;
D3D10BlendState* GetD3D10Iface() { D3D10BlendState* GetD3D10Iface() {
return &m_d3d10; return &m_d3d10;
@ -51,7 +56,7 @@ namespace dxvk {
D3D11_BLEND_DESC1 m_desc; D3D11_BLEND_DESC1 m_desc;
std::array<DxvkBlendMode, 8> m_blendModes; std::array<DxvkBlendMode, 8> m_blendModes;
DxvkMultisampleState m_msState; DxvkMultisampleState m_msState = { };
DxvkLogicOpState m_loState; DxvkLogicOpState m_loState;
D3D10BlendState m_d3d10; D3D10BlendState m_d3d10;

View File

@ -3371,9 +3371,11 @@ namespace dxvk {
if (m_state.om.cbState != nullptr) { if (m_state.om.cbState != nullptr) {
EmitCs([ EmitCs([
cBlendState = m_state.om.cbState, cBlendState = m_state.om.cbState,
cSampleMask = m_state.om.sampleMask cMsState = m_state.om.cbState->GetMsState(m_state.om.sampleMask)
] (DxvkContext* ctx) { ] (DxvkContext* ctx) {
cBlendState->BindToContext(ctx, cSampleMask); cBlendState->BindToContext(ctx);
ctx->setMultisampleState(cMsState);
}); });
} else { } else {
EmitCs([ EmitCs([
@ -3381,14 +3383,13 @@ namespace dxvk {
] (DxvkContext* ctx) { ] (DxvkContext* ctx) {
DxvkBlendMode cbState; DxvkBlendMode cbState;
DxvkLogicOpState loState; DxvkLogicOpState loState;
DxvkMultisampleState msState; InitDefaultBlendState(&cbState, &loState);
InitDefaultBlendState(&cbState, &loState, &msState, cSampleMask);
for (uint32_t i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) for (uint32_t i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
ctx->setBlendMode(i, cbState); ctx->setBlendMode(i, cbState);
ctx->setLogicOpState(loState); ctx->setLogicOpState(loState);
ctx->setMultisampleState(msState); ctx->setMultisampleState(InitDefaultMultisampleState(cSampleMask));
}); });
} }
} }
@ -4730,14 +4731,13 @@ namespace dxvk {
DxvkBlendMode cbState; DxvkBlendMode cbState;
DxvkLogicOpState loState; DxvkLogicOpState loState;
DxvkMultisampleState msState; InitDefaultBlendState(&cbState, &loState);
InitDefaultBlendState(&cbState, &loState, &msState, D3D11_DEFAULT_SAMPLE_MASK);
ctx->setInputAssemblyState(iaState); ctx->setInputAssemblyState(iaState);
ctx->setDepthStencilState(InitDefaultDepthStencilState()); ctx->setDepthStencilState(InitDefaultDepthStencilState());
ctx->setRasterizerState(rsState); ctx->setRasterizerState(rsState);
ctx->setLogicOpState(loState); ctx->setLogicOpState(loState);
ctx->setMultisampleState(msState); ctx->setMultisampleState(InitDefaultMultisampleState(D3D11_DEFAULT_SAMPLE_MASK));
for (uint32_t i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) for (uint32_t i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
ctx->setBlendMode(i, cbState); ctx->setBlendMode(i, cbState);
@ -5812,12 +5812,19 @@ namespace dxvk {
} }
template<typename ContextType>
DxvkMultisampleState D3D11CommonContext<ContextType>::InitDefaultMultisampleState(
UINT SampleMask) {
DxvkMultisampleState msState = { };
msState.setSampleMask(SampleMask);
return msState;
}
template<typename ContextType> template<typename ContextType>
void D3D11CommonContext<ContextType>::InitDefaultBlendState( void D3D11CommonContext<ContextType>::InitDefaultBlendState(
DxvkBlendMode* pCbState, DxvkBlendMode* pCbState,
DxvkLogicOpState* pLoState, DxvkLogicOpState* pLoState) {
DxvkMultisampleState* pMsState,
UINT SampleMask) {
pCbState->enableBlending = VK_FALSE; pCbState->enableBlending = VK_FALSE;
pCbState->colorSrcFactor = VK_BLEND_FACTOR_ONE; pCbState->colorSrcFactor = VK_BLEND_FACTOR_ONE;
pCbState->colorDstFactor = VK_BLEND_FACTOR_ZERO; pCbState->colorDstFactor = VK_BLEND_FACTOR_ZERO;
@ -5830,9 +5837,6 @@ namespace dxvk {
pLoState->enableLogicOp = VK_FALSE; pLoState->enableLogicOp = VK_FALSE;
pLoState->logicOp = VK_LOGIC_OP_NO_OP; pLoState->logicOp = VK_LOGIC_OP_NO_OP;
pMsState->sampleMask = SampleMask;
pMsState->enableAlphaToCoverage = VK_FALSE;
} }
// Explicitly instantiate here // Explicitly instantiate here

View File

@ -1151,11 +1151,12 @@ namespace dxvk {
static DxvkDepthStencilState InitDefaultDepthStencilState(); static DxvkDepthStencilState InitDefaultDepthStencilState();
static DxvkMultisampleState InitDefaultMultisampleState(
UINT SampleMask);
static void InitDefaultBlendState( static void InitDefaultBlendState(
DxvkBlendMode* pCbState, DxvkBlendMode* pCbState,
DxvkLogicOpState* pLoState, DxvkLogicOpState* pLoState);
DxvkMultisampleState* pMsState,
UINT SampleMask);
template<bool AllowFlush = true, typename Cmd> template<bool AllowFlush = true, typename Cmd>
void EmitCs(Cmd&& command) { void EmitCs(Cmd&& command) {

View File

@ -6804,11 +6804,11 @@ namespace dxvk {
void D3D9DeviceEx::BindMultiSampleState() { void D3D9DeviceEx::BindMultiSampleState() {
m_flags.clr(D3D9DeviceFlag::DirtyMultiSampleState); m_flags.clr(D3D9DeviceFlag::DirtyMultiSampleState);
DxvkMultisampleState msState; DxvkMultisampleState msState = { };
msState.sampleMask = m_flags.test(D3D9DeviceFlag::ValidSampleMask) msState.setSampleMask(m_flags.test(D3D9DeviceFlag::ValidSampleMask)
? m_state.renderStates[D3DRS_MULTISAMPLEMASK] ? uint16_t(m_state.renderStates[D3DRS_MULTISAMPLEMASK])
: 0xffffffff; : uint16_t(0xffffu));
msState.enableAlphaToCoverage = IsAlphaToCoverageEnabled(); msState.setAlphaToCoverage(IsAlphaToCoverageEnabled());
EmitCs([ EmitCs([
cState = msState cState = msState

View File

@ -136,9 +136,32 @@ namespace dxvk {
* Defines how to handle certain * Defines how to handle certain
* aspects of multisampling. * aspects of multisampling.
*/ */
struct DxvkMultisampleState { class DxvkMultisampleState {
uint32_t sampleMask;
VkBool32 enableAlphaToCoverage; public:
uint16_t sampleMask() const {
return m_sampleMask;
}
bool alphaToCoverage() const {
return m_enableAlphaToCoverage;
}
void setSampleMask(uint16_t mask) {
m_sampleMask = mask;
}
void setAlphaToCoverage(bool alphaToCoverage) {
m_enableAlphaToCoverage = alphaToCoverage;
}
private:
uint16_t m_sampleMask;
uint16_t m_enableAlphaToCoverage : 1;
uint16_t m_reserved : 15;
}; };

View File

@ -2880,9 +2880,9 @@ namespace dxvk {
void DxvkContext::setMultisampleState(const DxvkMultisampleState& ms) { void DxvkContext::setMultisampleState(const DxvkMultisampleState& ms) {
m_state.gp.state.ms = DxvkMsInfo( m_state.gp.state.ms = DxvkMsInfo(
m_state.gp.state.ms.sampleCount(), m_state.gp.state.ms.sampleCount(),
ms.sampleMask, ms.sampleMask(),
ms.enableAlphaToCoverage); ms.alphaToCoverage());
m_flags.set( m_flags.set(
DxvkContextFlag::GpDirtyPipelineState, DxvkContextFlag::GpDirtyPipelineState,
DxvkContextFlag::GpDirtyMultisampleState); DxvkContextFlag::GpDirtyMultisampleState);