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

[dxvk,d3d9,d3d11] Refactor depth-stencil state object

No reason to pass 72 bytes around when we can do with 10.
This commit is contained in:
Philip Rebohle 2025-03-22 15:31:10 +01:00
parent e14f7f4078
commit 84d1815707
8 changed files with 229 additions and 108 deletions

View File

@ -3410,16 +3410,13 @@ namespace dxvk {
void D3D11CommonContext<ContextType>::ApplyDepthStencilState() { void D3D11CommonContext<ContextType>::ApplyDepthStencilState() {
if (m_state.om.dsState != nullptr) { if (m_state.om.dsState != nullptr) {
EmitCs([ EmitCs([
cDepthStencilState = m_state.om.dsState cState = m_state.om.dsState->GetState()
] (DxvkContext* ctx) { ] (DxvkContext* ctx) {
cDepthStencilState->BindToContext(ctx); ctx->setDepthStencilState(cState);
}); });
} else { } else {
EmitCs([] (DxvkContext* ctx) { EmitCs([] (DxvkContext* ctx) {
DxvkDepthStencilState dsState; ctx->setDepthStencilState(InitDefaultDepthStencilState());
InitDefaultDepthStencilState(&dsState);
ctx->setDepthStencilState(dsState);
}); });
} }
} }
@ -4728,9 +4725,6 @@ namespace dxvk {
DxvkInputAssemblyState iaState; DxvkInputAssemblyState iaState;
InitDefaultPrimitiveTopology(&iaState); InitDefaultPrimitiveTopology(&iaState);
DxvkDepthStencilState dsState;
InitDefaultDepthStencilState(&dsState);
DxvkRasterizerState rsState; DxvkRasterizerState rsState;
InitDefaultRasterizerState(&rsState); InitDefaultRasterizerState(&rsState);
@ -4740,7 +4734,7 @@ namespace dxvk {
InitDefaultBlendState(&cbState, &loState, &msState, D3D11_DEFAULT_SAMPLE_MASK); InitDefaultBlendState(&cbState, &loState, &msState, D3D11_DEFAULT_SAMPLE_MASK);
ctx->setInputAssemblyState(iaState); ctx->setInputAssemblyState(iaState);
ctx->setDepthStencilState(dsState); ctx->setDepthStencilState(InitDefaultDepthStencilState());
ctx->setRasterizerState(rsState); ctx->setRasterizerState(rsState);
ctx->setLogicOpState(loState); ctx->setLogicOpState(loState);
ctx->setMultisampleState(msState); ctx->setMultisampleState(msState);
@ -5809,23 +5803,12 @@ namespace dxvk {
template<typename ContextType> template<typename ContextType>
void D3D11CommonContext<ContextType>::InitDefaultDepthStencilState( DxvkDepthStencilState D3D11CommonContext<ContextType>::InitDefaultDepthStencilState() {
DxvkDepthStencilState* pDsState) { DxvkDepthStencilState dsState = { };
VkStencilOpState stencilOp; dsState.setDepthTest(true);
stencilOp.failOp = VK_STENCIL_OP_KEEP; dsState.setDepthWrite(true);
stencilOp.passOp = VK_STENCIL_OP_KEEP; dsState.setDepthCompareOp(VK_COMPARE_OP_LESS);
stencilOp.depthFailOp = VK_STENCIL_OP_KEEP; return dsState;
stencilOp.compareOp = VK_COMPARE_OP_ALWAYS;
stencilOp.compareMask = D3D11_DEFAULT_STENCIL_READ_MASK;
stencilOp.writeMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
stencilOp.reference = 0;
pDsState->enableDepthTest = VK_TRUE;
pDsState->enableDepthWrite = VK_TRUE;
pDsState->enableStencilTest = VK_FALSE;
pDsState->depthCompareOp = VK_COMPARE_OP_LESS;
pDsState->stencilOpFront = stencilOp;
pDsState->stencilOpBack = stencilOp;
} }

View File

@ -1149,8 +1149,7 @@ namespace dxvk {
static void InitDefaultRasterizerState( static void InitDefaultRasterizerState(
DxvkRasterizerState* pRsState); DxvkRasterizerState* pRsState);
static void InitDefaultDepthStencilState( static DxvkDepthStencilState InitDefaultDepthStencilState();
DxvkDepthStencilState* pDsState);
static void InitDefaultBlendState( static void InitDefaultBlendState(
DxvkBlendMode* pCbState, DxvkBlendMode* pCbState,

View File

@ -8,12 +8,12 @@ namespace dxvk {
const D3D11_DEPTH_STENCIL_DESC& desc) const D3D11_DEPTH_STENCIL_DESC& desc)
: D3D11StateObject<ID3D11DepthStencilState>(device), : D3D11StateObject<ID3D11DepthStencilState>(device),
m_desc(desc), m_d3d10(this) { m_desc(desc), m_d3d10(this) {
m_state.enableDepthTest = desc.DepthEnable; m_state.setDepthTest(desc.DepthEnable);
m_state.enableDepthWrite = desc.DepthWriteMask == D3D11_DEPTH_WRITE_MASK_ALL; m_state.setDepthWrite(desc.DepthWriteMask == D3D11_DEPTH_WRITE_MASK_ALL);
m_state.enableStencilTest = desc.StencilEnable; m_state.setStencilTest(desc.StencilEnable);
m_state.depthCompareOp = DecodeCompareOp(desc.DepthFunc); m_state.setDepthCompareOp(DecodeCompareOp(desc.DepthFunc));
m_state.stencilOpFront = DecodeStencilOpState(desc.FrontFace, desc); m_state.setStencilOpFront(DecodeStencilOpState(desc.FrontFace, desc));
m_state.stencilOpBack = DecodeStencilOpState(desc.BackFace, desc); m_state.setStencilOpBack(DecodeStencilOpState(desc.BackFace, desc));
} }
@ -55,11 +55,6 @@ namespace dxvk {
} }
void D3D11DepthStencilState::BindToContext(DxvkContext* ctx) {
ctx->setDepthStencilState(m_state);
}
HRESULT D3D11DepthStencilState::NormalizeDesc(D3D11_DEPTH_STENCIL_DESC* pDesc) { HRESULT D3D11DepthStencilState::NormalizeDesc(D3D11_DEPTH_STENCIL_DESC* pDesc) {
if (pDesc->DepthEnable) { if (pDesc->DepthEnable) {
pDesc->DepthEnable = TRUE; pDesc->DepthEnable = TRUE;
@ -105,25 +100,20 @@ namespace dxvk {
} }
VkStencilOpState D3D11DepthStencilState::DecodeStencilOpState( DxvkStencilOp D3D11DepthStencilState::DecodeStencilOpState(
const D3D11_DEPTH_STENCILOP_DESC& StencilDesc, const D3D11_DEPTH_STENCILOP_DESC& StencilDesc,
const D3D11_DEPTH_STENCIL_DESC& Desc) const { const D3D11_DEPTH_STENCIL_DESC& Desc) const {
VkStencilOpState result; DxvkStencilOp result = { };
result.failOp = VK_STENCIL_OP_KEEP;
result.passOp = VK_STENCIL_OP_KEEP;
result.depthFailOp = VK_STENCIL_OP_KEEP;
result.compareOp = VK_COMPARE_OP_ALWAYS;
result.compareMask = Desc.StencilReadMask;
result.writeMask = Desc.StencilWriteMask;
result.reference = 0;
if (Desc.StencilEnable) { if (Desc.StencilEnable) {
result.failOp = DecodeStencilOp(StencilDesc.StencilFailOp); result.setFailOp(DecodeStencilOp(StencilDesc.StencilFailOp));
result.passOp = DecodeStencilOp(StencilDesc.StencilPassOp); result.setPassOp(DecodeStencilOp(StencilDesc.StencilPassOp));
result.depthFailOp = DecodeStencilOp(StencilDesc.StencilDepthFailOp); result.setDepthFailOp(DecodeStencilOp(StencilDesc.StencilDepthFailOp));
result.compareOp = DecodeCompareOp(StencilDesc.StencilFunc); result.setCompareOp(DecodeCompareOp(StencilDesc.StencilFunc));
result.setCompareMask(Desc.StencilReadMask);
result.setWriteMask(Desc.StencilWriteMask);
} }
return result; return result;
} }

View File

@ -28,9 +28,11 @@ namespace dxvk {
void STDMETHODCALLTYPE GetDesc( void STDMETHODCALLTYPE GetDesc(
D3D11_DEPTH_STENCIL_DESC* pDesc) final; D3D11_DEPTH_STENCIL_DESC* pDesc) final;
void BindToContext(DxvkContext* ctx); DxvkDepthStencilState GetState() const {
return m_state;
}
D3D10DepthStencilState* GetD3D10Iface() { D3D10DepthStencilState* GetD3D10Iface() {
return &m_d3d10; return &m_d3d10;
} }
@ -41,10 +43,10 @@ namespace dxvk {
private: private:
D3D11_DEPTH_STENCIL_DESC m_desc; D3D11_DEPTH_STENCIL_DESC m_desc;
DxvkDepthStencilState m_state; DxvkDepthStencilState m_state = { };
D3D10DepthStencilState m_d3d10; D3D10DepthStencilState m_d3d10;
VkStencilOpState DecodeStencilOpState( DxvkStencilOp DecodeStencilOpState(
const D3D11_DEPTH_STENCILOP_DESC& StencilDesc, const D3D11_DEPTH_STENCILOP_DESC& StencilDesc,
const D3D11_DEPTH_STENCIL_DESC& Desc) const; const D3D11_DEPTH_STENCIL_DESC& Desc) const;

View File

@ -6917,35 +6917,36 @@ namespace dxvk {
bool stencil = rs[D3DRS_STENCILENABLE]; bool stencil = rs[D3DRS_STENCILENABLE];
bool twoSidedStencil = stencil && rs[D3DRS_TWOSIDEDSTENCILMODE]; bool twoSidedStencil = stencil && rs[D3DRS_TWOSIDEDSTENCILMODE];
DxvkDepthStencilState state; DxvkDepthStencilState state = { };
state.enableDepthTest = rs[D3DRS_ZENABLE] != FALSE; state.setDepthTest(rs[D3DRS_ZENABLE]);
state.enableDepthWrite = rs[D3DRS_ZWRITEENABLE] != FALSE; state.setDepthWrite(rs[D3DRS_ZWRITEENABLE]);
state.enableStencilTest = stencil; state.setStencilTest(stencil);
state.depthCompareOp = DecodeCompareOp(D3DCMPFUNC(rs[D3DRS_ZFUNC])); state.setDepthCompareOp(DecodeCompareOp(D3DCMPFUNC(rs[D3DRS_ZFUNC])));
DxvkStencilOp frontOp = { };
if (stencil) { if (stencil) {
state.stencilOpFront.failOp = DecodeStencilOp(D3DSTENCILOP(rs[D3DRS_STENCILFAIL])); frontOp.setFailOp(DecodeStencilOp(D3DSTENCILOP(rs[D3DRS_STENCILFAIL])));
state.stencilOpFront.passOp = DecodeStencilOp(D3DSTENCILOP(rs[D3DRS_STENCILPASS])); frontOp.setPassOp(DecodeStencilOp(D3DSTENCILOP(rs[D3DRS_STENCILPASS])));
state.stencilOpFront.depthFailOp = DecodeStencilOp(D3DSTENCILOP(rs[D3DRS_STENCILZFAIL])); frontOp.setDepthFailOp(DecodeStencilOp(D3DSTENCILOP(rs[D3DRS_STENCILZFAIL])));
state.stencilOpFront.compareOp = DecodeCompareOp(D3DCMPFUNC (rs[D3DRS_STENCILFUNC])); frontOp.setCompareOp(DecodeCompareOp(D3DCMPFUNC(rs[D3DRS_STENCILFUNC])));
state.stencilOpFront.compareMask = uint32_t(rs[D3DRS_STENCILMASK]); frontOp.setCompareMask(rs[D3DRS_STENCILMASK]);
state.stencilOpFront.writeMask = uint32_t(rs[D3DRS_STENCILWRITEMASK]); frontOp.setWriteMask(rs[D3DRS_STENCILWRITEMASK]);
state.stencilOpFront.reference = 0;
} }
else
state.stencilOpFront = VkStencilOpState(); DxvkStencilOp backOp = frontOp;
if (twoSidedStencil) { if (twoSidedStencil) {
state.stencilOpBack.failOp = DecodeStencilOp(D3DSTENCILOP(rs[D3DRS_CCW_STENCILFAIL])); backOp.setFailOp(DecodeStencilOp(D3DSTENCILOP(rs[D3DRS_CCW_STENCILFAIL])));
state.stencilOpBack.passOp = DecodeStencilOp(D3DSTENCILOP(rs[D3DRS_CCW_STENCILPASS])); backOp.setPassOp(DecodeStencilOp(D3DSTENCILOP(rs[D3DRS_CCW_STENCILPASS])));
state.stencilOpBack.depthFailOp = DecodeStencilOp(D3DSTENCILOP(rs[D3DRS_CCW_STENCILZFAIL])); backOp.setDepthFailOp(DecodeStencilOp(D3DSTENCILOP(rs[D3DRS_CCW_STENCILZFAIL])));
state.stencilOpBack.compareOp = DecodeCompareOp(D3DCMPFUNC (rs[D3DRS_CCW_STENCILFUNC])); backOp.setCompareOp(DecodeCompareOp(D3DCMPFUNC(rs[D3DRS_CCW_STENCILFUNC])));
state.stencilOpBack.compareMask = state.stencilOpFront.compareMask; backOp.setCompareMask(rs[D3DRS_STENCILMASK]);
state.stencilOpBack.writeMask = state.stencilOpFront.writeMask; backOp.setWriteMask(rs[D3DRS_STENCILWRITEMASK]);
state.stencilOpBack.reference = 0;
} }
else
state.stencilOpBack = state.stencilOpFront; state.setStencilOpFront(frontOp);
state.setStencilOpBack(backOp);
EmitCs([ EmitCs([
cState = state cState = state

View File

@ -141,20 +141,143 @@ namespace dxvk {
VkBool32 enableAlphaToCoverage; VkBool32 enableAlphaToCoverage;
}; };
/**
* \brief Stencil operation
*/
class DxvkStencilOp {
public:
VkStencilOp failOp() const {
return VkStencilOp(m_failOp);
}
VkStencilOp passOp() const {
return VkStencilOp(m_passOp);
}
VkStencilOp depthFailOp() const {
return VkStencilOp(m_depthFailOp);
}
VkCompareOp compareOp() const {
return VkCompareOp(m_compareOp);
}
uint8_t compareMask() const {
return m_compareMask;
}
uint8_t writeMask() const {
return m_writeMask;
}
void setFailOp(VkStencilOp op) {
m_failOp = uint16_t(op);
}
void setPassOp(VkStencilOp op) {
m_passOp = uint16_t(op);
}
void setDepthFailOp(VkStencilOp op) {
m_depthFailOp = uint16_t(op);
}
void setCompareOp(VkCompareOp op) {
m_compareOp = uint16_t(op);
}
void setCompareMask(uint8_t mask) {
m_compareMask = mask;
}
void setWriteMask(uint8_t mask) {
m_writeMask = mask;
}
private:
uint16_t m_failOp : 3;
uint16_t m_passOp : 3;
uint16_t m_depthFailOp : 3;
uint16_t m_compareOp : 3;
uint16_t m_reserved : 4;
uint8_t m_compareMask;
uint8_t m_writeMask;
};
/** /**
* \brief Depth-stencil state * \brief Depth-stencil state
* *
* Defines the depth test and stencil * Defines the depth test and stencil
* operations for the graphics pipeline. * operations for the graphics pipeline.
*/ */
struct DxvkDepthStencilState { class DxvkDepthStencilState {
VkBool32 enableDepthTest;
VkBool32 enableDepthWrite; public:
VkBool32 enableStencilTest;
VkCompareOp depthCompareOp; bool depthTest() const {
VkStencilOpState stencilOpFront; return m_enableDepthTest;
VkStencilOpState stencilOpBack; }
bool depthWrite() const {
return m_enableDepthWrite;
}
bool stencilTest() const {
return m_enableStencilTest;
}
VkCompareOp depthCompareOp() const {
return VkCompareOp(m_depthCompareOp);
}
DxvkStencilOp stencilOpFront() const {
return m_stencilOpFront;
}
DxvkStencilOp stencilOpBack() const {
return m_stencilOpBack;
}
void setDepthTest(bool depthTest) {
m_enableDepthTest = depthTest;
}
void setDepthWrite(bool depthWrite) {
m_enableDepthWrite = depthWrite;
}
void setStencilTest(bool stencilTest) {
m_enableStencilTest = stencilTest;
}
void setDepthCompareOp(VkCompareOp compareOp) {
m_depthCompareOp = uint16_t(compareOp);
}
void setStencilOpFront(DxvkStencilOp op) {
m_stencilOpFront = op;
}
void setStencilOpBack(DxvkStencilOp op) {
m_stencilOpBack = op;
}
private:
uint16_t m_enableDepthTest : 1;
uint16_t m_enableDepthWrite : 1;
uint16_t m_enableStencilTest : 1;
uint16_t m_depthCompareOp : 3;
uint16_t m_reserved : 10;
DxvkStencilOp m_stencilOpFront;
DxvkStencilOp m_stencilOpBack;
}; };
@ -227,5 +350,5 @@ namespace dxvk {
std::array<DxvkVertexAttribute, DxvkLimits::MaxNumVertexAttributes> attributes; std::array<DxvkVertexAttribute, DxvkLimits::MaxNumVertexAttributes> attributes;
std::array<DxvkVertexBinding, DxvkLimits::MaxNumVertexBindings> bindings; std::array<DxvkVertexBinding, DxvkLimits::MaxNumVertexBindings> bindings;
}; };
} }

View File

@ -2891,15 +2891,32 @@ namespace dxvk {
void DxvkContext::setDepthStencilState(const DxvkDepthStencilState& ds) { void DxvkContext::setDepthStencilState(const DxvkDepthStencilState& ds) {
m_state.gp.state.ds = DxvkDsInfo( m_state.gp.state.ds = DxvkDsInfo(
ds.enableDepthTest, ds.depthTest(),
ds.enableDepthWrite, ds.depthWrite(),
m_state.gp.state.ds.enableDepthBoundsTest(), m_state.gp.state.ds.enableDepthBoundsTest(),
ds.enableStencilTest, ds.stencilTest(),
ds.depthCompareOp); ds.depthCompareOp());
m_state.gp.state.dsFront = DxvkDsStencilOp(ds.stencilOpFront); DxvkStencilOp front = ds.stencilOpFront();
m_state.gp.state.dsBack = DxvkDsStencilOp(ds.stencilOpBack);
m_state.gp.state.dsFront = DxvkDsStencilOp(
front.failOp(),
front.passOp(),
front.depthFailOp(),
front.compareOp(),
front.compareMask(),
front.writeMask());
DxvkStencilOp back = ds.stencilOpBack();
m_state.gp.state.dsBack = DxvkDsStencilOp(
back.failOp(),
back.passOp(),
back.depthFailOp(),
back.compareOp(),
back.compareMask(),
back.writeMask());
m_flags.set( m_flags.set(
DxvkContextFlag::GpDirtyPipelineState, DxvkContextFlag::GpDirtyPipelineState,
DxvkContextFlag::GpDirtyDepthStencilState); DxvkContextFlag::GpDirtyDepthStencilState);

View File

@ -400,14 +400,20 @@ namespace dxvk {
DxvkDsStencilOp() = default; DxvkDsStencilOp() = default;
DxvkDsStencilOp(VkStencilOpState state) DxvkDsStencilOp(
: m_failOp (uint32_t(state.failOp)), VkStencilOp failOp,
m_passOp (uint32_t(state.passOp)), VkStencilOp passOp,
m_depthFailOp (uint32_t(state.depthFailOp)), VkStencilOp depthFailOp,
m_compareOp (uint32_t(state.compareOp)), VkCompareOp compareOp,
uint8_t compareMask,
uint8_t writeMask)
: m_failOp (uint32_t(failOp)),
m_passOp (uint32_t(passOp)),
m_depthFailOp (uint32_t(depthFailOp)),
m_compareOp (uint32_t(compareOp)),
m_reserved (0), m_reserved (0),
m_compareMask (uint32_t(state.compareMask)), m_compareMask (uint32_t(compareMask)),
m_writeMask (uint32_t(state.writeMask)) { } m_writeMask (uint32_t(writeMask)) { }
VkStencilOpState state(bool write) const { VkStencilOpState state(bool write) const {
VkStencilOpState result; VkStencilOpState result;