1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-03-28 02:19:26 +01:00

[dxvk,d3d9,d3d11] Refactor multisample state object

This commit is contained in:
Philip Rebohle 2025-03-22 15:47:35 +01:00
parent fe30ceb6f8
commit 9985f9fa7b
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
m_msState.sampleMask = 0; // Set during bind
m_msState.enableAlphaToCoverage = desc.AlphaToCoverageEnable;
m_msState.setSampleMask(0u); // Set during bind
m_msState.setAlphaToCoverage(desc.AlphaToCoverageEnable);
// Vulkan only supports a global logic op for the blend
// state, which might be problematic in some cases.
@ -90,19 +90,13 @@ namespace dxvk {
void D3D11BlendState::BindToContext(
DxvkContext* ctx,
uint32_t sampleMask) const {
DxvkContext* ctx) const {
// We handled Independent Blend during object creation
// already, so if it is disabled, all elements in the
// blend mode array will be identical
for (uint32_t i = 0; i < m_blendModes.size(); 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
ctx->setLogicOpState(m_loState);
}

View File

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

View File

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

View File

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

View File

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

View File

@ -136,9 +136,32 @@ namespace dxvk {
* Defines how to handle certain
* aspects of multisampling.
*/
struct DxvkMultisampleState {
uint32_t sampleMask;
VkBool32 enableAlphaToCoverage;
class DxvkMultisampleState {
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) {
m_state.gp.state.ms = DxvkMsInfo(
m_state.gp.state.ms.sampleCount(),
ms.sampleMask,
ms.enableAlphaToCoverage);
ms.sampleMask(),
ms.alphaToCoverage());
m_flags.set(
DxvkContextFlag::GpDirtyPipelineState,
DxvkContextFlag::GpDirtyMultisampleState);