defer depth clear

This commit is contained in:
Asuka 2022-07-12 01:09:08 +08:00
parent 22c80b116c
commit 7c1e7b4b9a
7 changed files with 54 additions and 69 deletions

View file

@ -345,20 +345,12 @@ namespace sce::Gnm
void GnmCommandBufferDraw::setDepthClearValue(float clearValue)
{
if (m_state.gp.om.dsClear.depthValue.depthStencil.depth != clearValue)
{
m_state.gp.om.dsClear.depthValue.depthStencil.depth = clearValue;
m_flags.set(GnmContextFlag::DirtyDepthStencilClear);
}
m_state.gp.om.dsClear.valueD.depth = clearValue;
}
void GnmCommandBufferDraw::setStencilClearValue(uint8_t clearValue)
{
if (m_state.gp.om.dsClear.stencilValue.depthStencil.stencil != clearValue)
{
m_state.gp.om.dsClear.stencilValue.depthStencil.stencil = clearValue;
m_flags.set(GnmContextFlag::DirtyDepthStencilClear);
}
m_state.gp.om.dsClear.valueS.stencil = clearValue;
}
void GnmCommandBufferDraw::setRenderTargetMask(uint32_t mask)
@ -438,7 +430,7 @@ namespace sce::Gnm
// so we need to disable depth write to protect
// the cleared value not touched.
VkBool32 depthWrite = depthControl.zWrite &&
!m_state.gp.om.dsClear.enableDepthClear;
!m_state.gp.om.dsClear.clearD;
if (dirty)
{
ds.enableDepthTest = depthControl.depthEnable;
@ -477,6 +469,9 @@ namespace sce::Gnm
// regardless of the value of
// VkPipelineDepthStencilStateCreateInfo::depthWriteEnable
// TODO:
// Support stencil
if (m_state.gp.om.dsState.enableDepthWrite != depthWrite)
{
m_state.gp.om.dsState.enableDepthWrite = depthWrite;
@ -484,10 +479,14 @@ namespace sce::Gnm
}
bool clearDepth = (!depthWrite);
if (m_state.gp.om.dsClear.enableDepthClear != clearDepth)
m_state.gp.om.dsClear.clearD = VkBool32(clearDepth);
if (clearDepth)
{
m_state.gp.om.dsClear.enableDepthClear = clearDepth;
m_flags.set(GnmContextFlag::DirtyDepthStencilClear);
m_flags.set(GnmContextFlag::ClearDepthStencil);
}
else
{
m_flags.clr(GnmContextFlag::ClearDepthStencil);
}
}
@ -1194,11 +1193,6 @@ namespace sce::Gnm
applyDepthStencilState();
}
if (m_flags.test(GnmContextFlag::DirtyDepthStencilClear))
{
applyDepthStencilClear();
}
if (m_flags.test(GnmContextFlag::DirtyRasterizerState))
{
applyRasterizerState();
@ -1244,12 +1238,27 @@ namespace sce::Gnm
m_flags.clr(GnmContextFlag::DirtyDepthStencilState);
}
void GnmCommandBufferDraw::applyDepthStencilClear()
void GnmCommandBufferDraw::clearDepthStencil(
const vlt::Rc<vlt::VltImageView>& view)
{
m_context->setDepthStencilClear(
m_state.gp.om.dsClear);
VkImageAspectFlags clearAspects = 0;
if (m_state.gp.om.dsClear.clearD)
{
clearAspects |= VK_IMAGE_ASPECT_DEPTH_BIT;
}
m_flags.clr(GnmContextFlag::DirtyDepthStencilClear);
if (m_state.gp.om.dsClear.clearS)
{
clearAspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
}
VkClearValue clearValue = { .depthStencil = m_state.gp.om.dsClear.valueD };
m_context->clearRenderTarget(view,
clearAspects,
clearValue);
m_flags.clr(GnmContextFlag::ClearDepthStencil);
}
void GnmCommandBufferDraw::applyStencilRef()
@ -1291,6 +1300,11 @@ namespace sce::Gnm
m_context->bindRenderTargets(targets);
m_flags.clr(GnmContextFlag::DirtyRenderTargets);
if (m_flags.test(GnmContextFlag::ClearDepthStencil))
{
clearDepthStencil(targets.depth.view);
}
}
void GnmCommandBufferDraw::initDefaultRenderState()
@ -1492,4 +1506,5 @@ namespace sce::Gnm
return depthView;
}
} // namespace sce::Gnm

View file

@ -197,6 +197,9 @@ namespace sce::Gnm
bool isDepth,
const Texture* tsharp) override;
void clearDepthStencil(
const vlt::Rc<vlt::VltImageView>& view);
void applyRenderState();
void applyPrimitiveTopology();
@ -207,8 +210,6 @@ namespace sce::Gnm
void applyDepthStencilState();
void applyDepthStencilClear();
void applyStencilRef();
void applyRasterizerState();

View file

@ -40,7 +40,8 @@ namespace sce::Gnm
DirtyRenderTargets,
DirtyBlendState,
DirtyDepthStencilState,
DirtyDepthStencilClear,
ClearDepthStencil,
};
using GnmContextFlags = util::Flags<GnmContextFlag>;
@ -78,14 +79,22 @@ namespace sce::Gnm
DepthRenderTarget depth;
};
struct GnmDepthStencilClear
{
VkBool32 clearD;
VkBool32 clearS;
VkClearDepthStencilValue valueD;
VkClearDepthStencilValue valueS;
};
struct GnmOutputMergerState
{
GnmRenderTargets targets;
GnmDepthStencilClear dsClear;
vlt::VltDepthStencilState dsState;
vlt::VltMultisampleState msState;
vlt::VltLogicOpState loState;
vlt::VltDepthStencilClear dsClear;
std::array<vlt::VltBlendMode, MaxNumRenderTargets> blendModes;
float blendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };

View file

@ -142,20 +142,6 @@ namespace sce::vlt
VkStencilOpState stencilOpBack;
};
/**
* \brief Depth-stencil clear
*
* Defines the depth and stencil
* clear values and state
*/
struct VltDepthStencilClear
{
VkBool32 enableDepthClear;
VkClearValue depthValue;
VkBool32 enableStencilClear;
VkClearValue stencilValue;
};
/**
* \brief Logic op state
* Defines a logic op.

View file

@ -40,7 +40,6 @@ namespace sce::vlt
m_flags.set(
VltContextFlag::GpDirtyFramebuffer,
VltContextFlag::GpDirtyFramebufferState,
VltContextFlag::GpDirtyPipeline,
VltContextFlag::GpDirtyPipelineState,
VltContextFlag::GpDirtyResources,
@ -478,8 +477,7 @@ namespace sce::vlt
template <bool Indexed, bool Indirect>
bool VltContext::commitGraphicsState()
{
if (m_flags.test(VltContextFlag::GpDirtyFramebuffer) ||
m_flags.test(VltContextFlag::GpDirtyFramebufferState))
if (m_flags.test(VltContextFlag::GpDirtyFramebuffer))
{
this->updateFramebuffer();
}
@ -832,22 +830,6 @@ namespace sce::vlt
m_flags.set(VltContextFlag::GpDirtyPipelineState);
}
void VltContext::setDepthStencilClear(
const VltDepthStencilClear& dsClear)
{
m_state.cb.renderPassOps.depthOps.loadOpD = dsClear.enableDepthClear
? VK_ATTACHMENT_LOAD_OP_CLEAR
: VK_ATTACHMENT_LOAD_OP_LOAD;
m_state.cb.renderPassOps.depthOps.loadOpS = dsClear.enableStencilClear
? VK_ATTACHMENT_LOAD_OP_CLEAR
: VK_ATTACHMENT_LOAD_OP_LOAD;
m_state.cb.renderPassOps.depthOps.clearValue = dsClear.depthValue.depthStencil;
m_flags.set(VltContextFlag::GpDirtyFramebufferState);
}
void VltContext::setLogicOpState(
const VltLogicOpState& lo)
{

View file

@ -202,13 +202,6 @@ namespace sce::vlt
const VltDepthStencilState& ds);
/**
* \brief Sets depth stencil clear
* \param [in] ds New state object
*/
void setDepthStencilClear(
const VltDepthStencilClear& dsClear);
/**
* \brief Sets logic op state
* \param [in] lo New state object
*/

View file

@ -24,7 +24,6 @@ namespace sce::vlt
GpCondActive, ///< Conditional rendering is enabled
GpXfbActive, ///< Transform feedback is enabled
GpDirtyFramebuffer, ///< Framebuffer binding is out of date
GpDirtyFramebufferState, ///< Framebuffer ops and clear values needs to be update
GpDirtyPipeline, ///< Graphics pipeline binding is out of date
GpDirtyPipelineState, ///< Graphics pipeline needs to be recompiled
GpDirtyResources, ///< Graphics pipeline resource bindings are out of date