[dxvk] Make cull mode and front face dynamic state

This commit is contained in:
Philip Rebohle 2022-07-12 12:03:05 +02:00
parent 18d4a87333
commit d3c8d21047
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
3 changed files with 56 additions and 17 deletions

View File

@ -96,6 +96,7 @@ namespace dxvk {
DxvkContextFlag::GpDirtyXfbBuffers,
DxvkContextFlag::GpDirtyBlendConstants,
DxvkContextFlag::GpDirtyStencilRef,
DxvkContextFlag::GpDirtyRasterizerState,
DxvkContextFlag::GpDirtyViewport,
DxvkContextFlag::GpDirtyDepthBias,
DxvkContextFlag::GpDirtyDepthBounds,
@ -2421,16 +2422,29 @@ namespace dxvk {
void DxvkContext::setRasterizerState(const DxvkRasterizerState& rs) {
m_state.gp.state.rs = DxvkRsInfo(
rs.depthClipEnable,
rs.depthBiasEnable,
rs.polygonMode,
rs.cullMode,
rs.frontFace,
rs.sampleCount,
rs.conservativeMode);
if (m_state.dyn.cullMode != rs.cullMode || m_state.dyn.frontFace != rs.frontFace) {
m_state.dyn.cullMode = rs.cullMode;
m_state.dyn.frontFace = rs.frontFace;
m_flags.set(DxvkContextFlag::GpDirtyPipelineState);
m_flags.set(DxvkContextFlag::GpDirtyRasterizerState);
}
if (m_state.gp.state.rs.depthClipEnable() != rs.depthClipEnable
|| m_state.gp.state.rs.depthBiasEnable() != rs.depthBiasEnable
|| m_state.gp.state.rs.polygonMode() != rs.polygonMode
|| m_state.gp.state.rs.sampleCount() != rs.sampleCount
|| m_state.gp.state.rs.conservativeMode() != rs.conservativeMode) {
m_state.gp.state.rs = DxvkRsInfo(
rs.depthClipEnable,
rs.depthBiasEnable,
rs.polygonMode,
rs.cullMode,
rs.frontFace,
rs.sampleCount,
rs.conservativeMode);
m_flags.set(DxvkContextFlag::GpDirtyPipelineState);
}
}
@ -4003,6 +4017,7 @@ namespace dxvk {
DxvkContextFlag::GpDirtyXfbBuffers,
DxvkContextFlag::GpDirtyBlendConstants,
DxvkContextFlag::GpDirtyStencilRef,
DxvkContextFlag::GpDirtyRasterizerState,
DxvkContextFlag::GpDirtyViewport,
DxvkContextFlag::GpDirtyDepthBias,
DxvkContextFlag::GpDirtyDepthBounds,
@ -4428,6 +4443,7 @@ namespace dxvk {
DxvkContextFlag::GpDirtyXfbBuffers,
DxvkContextFlag::GpDirtyBlendConstants,
DxvkContextFlag::GpDirtyStencilRef,
DxvkContextFlag::GpDirtyRasterizerState,
DxvkContextFlag::GpDirtyViewport,
DxvkContextFlag::GpDirtyDepthBias,
DxvkContextFlag::GpDirtyDepthBounds);
@ -4488,6 +4504,7 @@ namespace dxvk {
DxvkContextFlag::GpDynamicDepthBias,
DxvkContextFlag::GpDynamicDepthBounds,
DxvkContextFlag::GpDynamicStencilRef,
DxvkContextFlag::GpDynamicRasterizerState,
DxvkContextFlag::GpIndependentSets);
m_flags.set(m_state.gp.state.useDynamicBlendConstants()
@ -4505,7 +4522,11 @@ namespace dxvk {
m_flags.set(m_state.gp.state.useDynamicStencilRef()
? DxvkContextFlag::GpDynamicStencilRef
: DxvkContextFlag::GpDirtyStencilRef);
m_flags.set((!m_state.gp.flags.test(DxvkGraphicsPipelineFlag::HasRasterizerDiscard))
? DxvkContextFlag::GpDynamicRasterizerState
: DxvkContextFlag::GpDirtyRasterizerState);
// Retrieve and bind actual Vulkan pipeline handle
auto pipelineInfo = m_state.gp.pipeline->getPipelineHandle(m_state.gp.state);
@ -4519,10 +4540,6 @@ namespace dxvk {
// For pipelines created from graphics pipeline libraries, we need
// to apply a bunch of dynamic state that is otherwise static
if (pipelineInfo.second == DxvkGraphicsPipelineType::BasePipeline) {
m_cmd->cmdSetRasterizerState(
m_state.gp.state.rs.cullMode(),
m_state.gp.state.rs.frontFace());
m_cmd->cmdSetDepthState(
m_state.gp.state.ds.enableDepthTest(),
m_state.gp.state.ds.enableDepthWrite(),
@ -4538,9 +4555,12 @@ namespace dxvk {
m_state.gp.state.ds.enableDepthBoundsTest());
}
if (!m_state.gp.state.rs.depthBiasEnable())
if (!m_flags.test(DxvkContextFlag::GpDynamicDepthBias))
m_cmd->cmdSetDepthBias(0.0f, 0.0f, 0.0f);
if (!m_flags.test(DxvkContextFlag::GpDynamicRasterizerState))
m_cmd->cmdSetRasterizerState(VK_CULL_MODE_FRONT_AND_BACK, VK_FRONT_FACE_CLOCKWISE);
m_flags.set(DxvkContextFlag::GpIndependentSets);
}
@ -5117,6 +5137,15 @@ namespace dxvk {
m_cmd->cmdSetScissor(m_state.vp.viewportCount, m_state.vp.scissorRects.data());
}
if (m_flags.all(DxvkContextFlag::GpDirtyRasterizerState,
DxvkContextFlag::GpDynamicRasterizerState)) {
m_flags.clr(DxvkContextFlag::GpDirtyRasterizerState);
m_cmd->cmdSetRasterizerState(
m_state.dyn.cullMode,
m_state.dyn.frontFace);
}
if (m_flags.all(DxvkContextFlag::GpDirtyBlendConstants,
DxvkContextFlag::GpDynamicBlendConstants)) {
m_flags.clr(DxvkContextFlag::GpDirtyBlendConstants);
@ -5255,7 +5284,8 @@ namespace dxvk {
DxvkContextFlag::GpDirtyBlendConstants,
DxvkContextFlag::GpDirtyStencilRef,
DxvkContextFlag::GpDirtyDepthBias,
DxvkContextFlag::GpDirtyDepthBounds))
DxvkContextFlag::GpDirtyDepthBounds,
DxvkContextFlag::GpDirtyRasterizerState))
this->updateDynamicState();
if (m_flags.test(DxvkContextFlag::DirtyPushConstants))

View File

@ -34,11 +34,13 @@ namespace dxvk {
GpDirtyDepthBias, ///< Depth bias has changed
GpDirtyDepthBounds, ///< Depth bounds have changed
GpDirtyStencilRef, ///< Stencil reference has changed
GpDirtyRasterizerState, ///< Cull mode and front face have changed
GpDirtyViewport, ///< Viewport state has changed
GpDynamicBlendConstants, ///< Blend constants are dynamic
GpDynamicDepthBias, ///< Depth bias is dynamic
GpDynamicDepthBounds, ///< Depth bounds are dynamic
GpDynamicStencilRef, ///< Stencil reference is dynamic
GpDynamicRasterizerState, ///< Cull mode and front face are dynamic
GpIndependentSets, ///< Graphics pipeline layout was created with independent sets
CpDirtyPipeline, ///< Compute pipeline binding are out of date
@ -135,6 +137,8 @@ namespace dxvk {
DxvkDepthBias depthBias = { 0.0f, 0.0f, 0.0f };
DxvkDepthBounds depthBounds = { false, 0.0f, 1.0f };
uint32_t stencilReference = 0;
VkCullModeFlags cullMode = VK_CULL_MODE_BACK_BIT;
VkFrontFace frontFace = VK_FRONT_FACE_CLOCKWISE;
};

View File

@ -768,7 +768,7 @@ namespace dxvk {
auto vk = m_device->vkd();
// Set up dynamic states as needed
std::array<VkDynamicState, 6> dynamicStates;
std::array<VkDynamicState, 8> dynamicStates;
uint32_t dynamicStateCount = 0;
dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT;
@ -786,6 +786,11 @@ namespace dxvk {
if (state.useDynamicStencilRef())
dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_STENCIL_REFERENCE;
if (!m_flags.test(DxvkGraphicsPipelineFlag::HasRasterizerDiscard)) {
dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_CULL_MODE_EXT;
dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_FRONT_FACE_EXT;
}
// Set up some specialization constants
DxvkSpecConstants specData;