mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-28 11:19:21 +01: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:
parent
e14f7f4078
commit
84d1815707
@ -3410,16 +3410,13 @@ namespace dxvk {
|
||||
void D3D11CommonContext<ContextType>::ApplyDepthStencilState() {
|
||||
if (m_state.om.dsState != nullptr) {
|
||||
EmitCs([
|
||||
cDepthStencilState = m_state.om.dsState
|
||||
cState = m_state.om.dsState->GetState()
|
||||
] (DxvkContext* ctx) {
|
||||
cDepthStencilState->BindToContext(ctx);
|
||||
ctx->setDepthStencilState(cState);
|
||||
});
|
||||
} else {
|
||||
EmitCs([] (DxvkContext* ctx) {
|
||||
DxvkDepthStencilState dsState;
|
||||
InitDefaultDepthStencilState(&dsState);
|
||||
|
||||
ctx->setDepthStencilState(dsState);
|
||||
ctx->setDepthStencilState(InitDefaultDepthStencilState());
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -4728,9 +4725,6 @@ namespace dxvk {
|
||||
DxvkInputAssemblyState iaState;
|
||||
InitDefaultPrimitiveTopology(&iaState);
|
||||
|
||||
DxvkDepthStencilState dsState;
|
||||
InitDefaultDepthStencilState(&dsState);
|
||||
|
||||
DxvkRasterizerState rsState;
|
||||
InitDefaultRasterizerState(&rsState);
|
||||
|
||||
@ -4740,7 +4734,7 @@ namespace dxvk {
|
||||
InitDefaultBlendState(&cbState, &loState, &msState, D3D11_DEFAULT_SAMPLE_MASK);
|
||||
|
||||
ctx->setInputAssemblyState(iaState);
|
||||
ctx->setDepthStencilState(dsState);
|
||||
ctx->setDepthStencilState(InitDefaultDepthStencilState());
|
||||
ctx->setRasterizerState(rsState);
|
||||
ctx->setLogicOpState(loState);
|
||||
ctx->setMultisampleState(msState);
|
||||
@ -5809,23 +5803,12 @@ namespace dxvk {
|
||||
|
||||
|
||||
template<typename ContextType>
|
||||
void D3D11CommonContext<ContextType>::InitDefaultDepthStencilState(
|
||||
DxvkDepthStencilState* pDsState) {
|
||||
VkStencilOpState stencilOp;
|
||||
stencilOp.failOp = VK_STENCIL_OP_KEEP;
|
||||
stencilOp.passOp = VK_STENCIL_OP_KEEP;
|
||||
stencilOp.depthFailOp = VK_STENCIL_OP_KEEP;
|
||||
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;
|
||||
DxvkDepthStencilState D3D11CommonContext<ContextType>::InitDefaultDepthStencilState() {
|
||||
DxvkDepthStencilState dsState = { };
|
||||
dsState.setDepthTest(true);
|
||||
dsState.setDepthWrite(true);
|
||||
dsState.setDepthCompareOp(VK_COMPARE_OP_LESS);
|
||||
return dsState;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1149,8 +1149,7 @@ namespace dxvk {
|
||||
static void InitDefaultRasterizerState(
|
||||
DxvkRasterizerState* pRsState);
|
||||
|
||||
static void InitDefaultDepthStencilState(
|
||||
DxvkDepthStencilState* pDsState);
|
||||
static DxvkDepthStencilState InitDefaultDepthStencilState();
|
||||
|
||||
static void InitDefaultBlendState(
|
||||
DxvkBlendMode* pCbState,
|
||||
|
@ -8,12 +8,12 @@ namespace dxvk {
|
||||
const D3D11_DEPTH_STENCIL_DESC& desc)
|
||||
: D3D11StateObject<ID3D11DepthStencilState>(device),
|
||||
m_desc(desc), m_d3d10(this) {
|
||||
m_state.enableDepthTest = desc.DepthEnable;
|
||||
m_state.enableDepthWrite = desc.DepthWriteMask == D3D11_DEPTH_WRITE_MASK_ALL;
|
||||
m_state.enableStencilTest = desc.StencilEnable;
|
||||
m_state.depthCompareOp = DecodeCompareOp(desc.DepthFunc);
|
||||
m_state.stencilOpFront = DecodeStencilOpState(desc.FrontFace, desc);
|
||||
m_state.stencilOpBack = DecodeStencilOpState(desc.BackFace, desc);
|
||||
m_state.setDepthTest(desc.DepthEnable);
|
||||
m_state.setDepthWrite(desc.DepthWriteMask == D3D11_DEPTH_WRITE_MASK_ALL);
|
||||
m_state.setStencilTest(desc.StencilEnable);
|
||||
m_state.setDepthCompareOp(DecodeCompareOp(desc.DepthFunc));
|
||||
m_state.setStencilOpFront(DecodeStencilOpState(desc.FrontFace, 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) {
|
||||
if (pDesc->DepthEnable) {
|
||||
pDesc->DepthEnable = TRUE;
|
||||
@ -105,25 +100,20 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
VkStencilOpState D3D11DepthStencilState::DecodeStencilOpState(
|
||||
DxvkStencilOp D3D11DepthStencilState::DecodeStencilOpState(
|
||||
const D3D11_DEPTH_STENCILOP_DESC& StencilDesc,
|
||||
const D3D11_DEPTH_STENCIL_DESC& Desc) const {
|
||||
VkStencilOpState 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;
|
||||
|
||||
DxvkStencilOp result = { };
|
||||
|
||||
if (Desc.StencilEnable) {
|
||||
result.failOp = DecodeStencilOp(StencilDesc.StencilFailOp);
|
||||
result.passOp = DecodeStencilOp(StencilDesc.StencilPassOp);
|
||||
result.depthFailOp = DecodeStencilOp(StencilDesc.StencilDepthFailOp);
|
||||
result.compareOp = DecodeCompareOp(StencilDesc.StencilFunc);
|
||||
result.setFailOp(DecodeStencilOp(StencilDesc.StencilFailOp));
|
||||
result.setPassOp(DecodeStencilOp(StencilDesc.StencilPassOp));
|
||||
result.setDepthFailOp(DecodeStencilOp(StencilDesc.StencilDepthFailOp));
|
||||
result.setCompareOp(DecodeCompareOp(StencilDesc.StencilFunc));
|
||||
result.setCompareMask(Desc.StencilReadMask);
|
||||
result.setWriteMask(Desc.StencilWriteMask);
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -28,9 +28,11 @@ namespace dxvk {
|
||||
|
||||
void STDMETHODCALLTYPE GetDesc(
|
||||
D3D11_DEPTH_STENCIL_DESC* pDesc) final;
|
||||
|
||||
void BindToContext(DxvkContext* ctx);
|
||||
|
||||
|
||||
DxvkDepthStencilState GetState() const {
|
||||
return m_state;
|
||||
}
|
||||
|
||||
D3D10DepthStencilState* GetD3D10Iface() {
|
||||
return &m_d3d10;
|
||||
}
|
||||
@ -41,10 +43,10 @@ namespace dxvk {
|
||||
private:
|
||||
|
||||
D3D11_DEPTH_STENCIL_DESC m_desc;
|
||||
DxvkDepthStencilState m_state;
|
||||
DxvkDepthStencilState m_state = { };
|
||||
D3D10DepthStencilState m_d3d10;
|
||||
|
||||
VkStencilOpState DecodeStencilOpState(
|
||||
DxvkStencilOp DecodeStencilOpState(
|
||||
const D3D11_DEPTH_STENCILOP_DESC& StencilDesc,
|
||||
const D3D11_DEPTH_STENCIL_DESC& Desc) const;
|
||||
|
||||
|
@ -6917,35 +6917,36 @@ namespace dxvk {
|
||||
bool stencil = rs[D3DRS_STENCILENABLE];
|
||||
bool twoSidedStencil = stencil && rs[D3DRS_TWOSIDEDSTENCILMODE];
|
||||
|
||||
DxvkDepthStencilState state;
|
||||
state.enableDepthTest = rs[D3DRS_ZENABLE] != FALSE;
|
||||
state.enableDepthWrite = rs[D3DRS_ZWRITEENABLE] != FALSE;
|
||||
state.enableStencilTest = stencil;
|
||||
state.depthCompareOp = DecodeCompareOp(D3DCMPFUNC(rs[D3DRS_ZFUNC]));
|
||||
DxvkDepthStencilState state = { };
|
||||
state.setDepthTest(rs[D3DRS_ZENABLE]);
|
||||
state.setDepthWrite(rs[D3DRS_ZWRITEENABLE]);
|
||||
state.setStencilTest(stencil);
|
||||
state.setDepthCompareOp(DecodeCompareOp(D3DCMPFUNC(rs[D3DRS_ZFUNC])));
|
||||
|
||||
DxvkStencilOp frontOp = { };
|
||||
|
||||
if (stencil) {
|
||||
state.stencilOpFront.failOp = DecodeStencilOp(D3DSTENCILOP(rs[D3DRS_STENCILFAIL]));
|
||||
state.stencilOpFront.passOp = DecodeStencilOp(D3DSTENCILOP(rs[D3DRS_STENCILPASS]));
|
||||
state.stencilOpFront.depthFailOp = DecodeStencilOp(D3DSTENCILOP(rs[D3DRS_STENCILZFAIL]));
|
||||
state.stencilOpFront.compareOp = DecodeCompareOp(D3DCMPFUNC (rs[D3DRS_STENCILFUNC]));
|
||||
state.stencilOpFront.compareMask = uint32_t(rs[D3DRS_STENCILMASK]);
|
||||
state.stencilOpFront.writeMask = uint32_t(rs[D3DRS_STENCILWRITEMASK]);
|
||||
state.stencilOpFront.reference = 0;
|
||||
frontOp.setFailOp(DecodeStencilOp(D3DSTENCILOP(rs[D3DRS_STENCILFAIL])));
|
||||
frontOp.setPassOp(DecodeStencilOp(D3DSTENCILOP(rs[D3DRS_STENCILPASS])));
|
||||
frontOp.setDepthFailOp(DecodeStencilOp(D3DSTENCILOP(rs[D3DRS_STENCILZFAIL])));
|
||||
frontOp.setCompareOp(DecodeCompareOp(D3DCMPFUNC(rs[D3DRS_STENCILFUNC])));
|
||||
frontOp.setCompareMask(rs[D3DRS_STENCILMASK]);
|
||||
frontOp.setWriteMask(rs[D3DRS_STENCILWRITEMASK]);
|
||||
}
|
||||
else
|
||||
state.stencilOpFront = VkStencilOpState();
|
||||
|
||||
DxvkStencilOp backOp = frontOp;
|
||||
|
||||
if (twoSidedStencil) {
|
||||
state.stencilOpBack.failOp = DecodeStencilOp(D3DSTENCILOP(rs[D3DRS_CCW_STENCILFAIL]));
|
||||
state.stencilOpBack.passOp = DecodeStencilOp(D3DSTENCILOP(rs[D3DRS_CCW_STENCILPASS]));
|
||||
state.stencilOpBack.depthFailOp = DecodeStencilOp(D3DSTENCILOP(rs[D3DRS_CCW_STENCILZFAIL]));
|
||||
state.stencilOpBack.compareOp = DecodeCompareOp(D3DCMPFUNC (rs[D3DRS_CCW_STENCILFUNC]));
|
||||
state.stencilOpBack.compareMask = state.stencilOpFront.compareMask;
|
||||
state.stencilOpBack.writeMask = state.stencilOpFront.writeMask;
|
||||
state.stencilOpBack.reference = 0;
|
||||
backOp.setFailOp(DecodeStencilOp(D3DSTENCILOP(rs[D3DRS_CCW_STENCILFAIL])));
|
||||
backOp.setPassOp(DecodeStencilOp(D3DSTENCILOP(rs[D3DRS_CCW_STENCILPASS])));
|
||||
backOp.setDepthFailOp(DecodeStencilOp(D3DSTENCILOP(rs[D3DRS_CCW_STENCILZFAIL])));
|
||||
backOp.setCompareOp(DecodeCompareOp(D3DCMPFUNC(rs[D3DRS_CCW_STENCILFUNC])));
|
||||
backOp.setCompareMask(rs[D3DRS_STENCILMASK]);
|
||||
backOp.setWriteMask(rs[D3DRS_STENCILWRITEMASK]);
|
||||
}
|
||||
else
|
||||
state.stencilOpBack = state.stencilOpFront;
|
||||
|
||||
state.setStencilOpFront(frontOp);
|
||||
state.setStencilOpBack(backOp);
|
||||
|
||||
EmitCs([
|
||||
cState = state
|
||||
|
@ -141,20 +141,143 @@ namespace dxvk {
|
||||
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
|
||||
*
|
||||
* Defines the depth test and stencil
|
||||
* operations for the graphics pipeline.
|
||||
*/
|
||||
struct DxvkDepthStencilState {
|
||||
VkBool32 enableDepthTest;
|
||||
VkBool32 enableDepthWrite;
|
||||
VkBool32 enableStencilTest;
|
||||
VkCompareOp depthCompareOp;
|
||||
VkStencilOpState stencilOpFront;
|
||||
VkStencilOpState stencilOpBack;
|
||||
class DxvkDepthStencilState {
|
||||
|
||||
public:
|
||||
|
||||
bool depthTest() const {
|
||||
return m_enableDepthTest;
|
||||
}
|
||||
|
||||
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<DxvkVertexBinding, DxvkLimits::MaxNumVertexBindings> bindings;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2891,15 +2891,32 @@ namespace dxvk {
|
||||
|
||||
void DxvkContext::setDepthStencilState(const DxvkDepthStencilState& ds) {
|
||||
m_state.gp.state.ds = DxvkDsInfo(
|
||||
ds.enableDepthTest,
|
||||
ds.enableDepthWrite,
|
||||
ds.depthTest(),
|
||||
ds.depthWrite(),
|
||||
m_state.gp.state.ds.enableDepthBoundsTest(),
|
||||
ds.enableStencilTest,
|
||||
ds.depthCompareOp);
|
||||
|
||||
m_state.gp.state.dsFront = DxvkDsStencilOp(ds.stencilOpFront);
|
||||
m_state.gp.state.dsBack = DxvkDsStencilOp(ds.stencilOpBack);
|
||||
|
||||
ds.stencilTest(),
|
||||
ds.depthCompareOp());
|
||||
|
||||
DxvkStencilOp front = ds.stencilOpFront();
|
||||
|
||||
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(
|
||||
DxvkContextFlag::GpDirtyPipelineState,
|
||||
DxvkContextFlag::GpDirtyDepthStencilState);
|
||||
|
@ -400,14 +400,20 @@ namespace dxvk {
|
||||
|
||||
DxvkDsStencilOp() = default;
|
||||
|
||||
DxvkDsStencilOp(VkStencilOpState state)
|
||||
: m_failOp (uint32_t(state.failOp)),
|
||||
m_passOp (uint32_t(state.passOp)),
|
||||
m_depthFailOp (uint32_t(state.depthFailOp)),
|
||||
m_compareOp (uint32_t(state.compareOp)),
|
||||
DxvkDsStencilOp(
|
||||
VkStencilOp failOp,
|
||||
VkStencilOp passOp,
|
||||
VkStencilOp depthFailOp,
|
||||
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_compareMask (uint32_t(state.compareMask)),
|
||||
m_writeMask (uint32_t(state.writeMask)) { }
|
||||
m_compareMask (uint32_t(compareMask)),
|
||||
m_writeMask (uint32_t(writeMask)) { }
|
||||
|
||||
VkStencilOpState state(bool write) const {
|
||||
VkStencilOpState result;
|
||||
|
Loading…
x
Reference in New Issue
Block a user