1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-11 19:24:11 +01:00

[dxvk] Use minimal set of dynamic state

We don't need to enable blend constants for pipelines that don't
have blending enabled, etc. This helps reduce the number of API
calls slightly and may help the driver work more efficiently.
This commit is contained in:
Philip Rebohle 2019-01-16 20:55:41 +01:00
parent 190f114449
commit 422198952a
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
3 changed files with 59 additions and 20 deletions

View File

@ -2590,6 +2590,7 @@ namespace dxvk {
this->pauseTransformFeedback(); this->pauseTransformFeedback();
// Fix up vertex binding strides for unbound buffers
for (uint32_t i = 0; i < m_state.gp.state.ilBindingCount; i++) { for (uint32_t i = 0; i < m_state.gp.state.ilBindingCount; i++) {
const uint32_t binding = m_state.gp.state.ilBindings[i].binding; const uint32_t binding = m_state.gp.state.ilBindings[i].binding;
@ -2602,6 +2603,25 @@ namespace dxvk {
for (uint32_t i = m_state.gp.state.ilBindingCount; i < MaxNumVertexBindings; i++) for (uint32_t i = m_state.gp.state.ilBindingCount; i < MaxNumVertexBindings; i++)
m_state.gp.state.ilBindings[i].stride = 0; m_state.gp.state.ilBindings[i].stride = 0;
// Check which dynamic states need to be active. States that
// are not dynamic will be invalidated in the command buffer.
m_flags.clr(DxvkContextFlag::GpDynamicBlendConstants,
DxvkContextFlag::GpDynamicDepthBias,
DxvkContextFlag::GpDynamicStencilRef);
m_flags.set(m_state.gp.state.useDynamicBlendConstants()
? DxvkContextFlag::GpDynamicBlendConstants
: DxvkContextFlag::GpDirtyBlendConstants);
m_flags.set(m_state.gp.state.useDynamicDepthBias()
? DxvkContextFlag::GpDynamicDepthBias
: DxvkContextFlag::GpDirtyDepthBias);
m_flags.set(m_state.gp.state.useDynamicStencilRef()
? DxvkContextFlag::GpDynamicStencilRef
: DxvkContextFlag::GpDirtyStencilRef);
// Retrieve and bind actual Vulkan pipeline handle
m_gpActivePipeline = m_state.gp.pipeline != nullptr && m_state.om.framebuffer != nullptr m_gpActivePipeline = m_state.gp.pipeline != nullptr && m_state.om.framebuffer != nullptr
? m_state.gp.pipeline->getPipelineHandle(m_state.gp.state, ? m_state.gp.pipeline->getPipelineHandle(m_state.gp.state,
m_state.om.framebuffer->getRenderPass()) m_state.om.framebuffer->getRenderPass())
@ -3006,29 +3026,37 @@ namespace dxvk {
return; return;
if (m_flags.test(DxvkContextFlag::GpDirtyViewport)) { if (m_flags.test(DxvkContextFlag::GpDirtyViewport)) {
m_flags.clr(DxvkContextFlag::GpDirtyViewport);
uint32_t viewportCount = m_state.gp.state.rsViewportCount; uint32_t viewportCount = m_state.gp.state.rsViewportCount;
m_cmd->cmdSetViewport(0, viewportCount, m_state.vp.viewports.data()); m_cmd->cmdSetViewport(0, viewportCount, m_state.vp.viewports.data());
m_cmd->cmdSetScissor (0, viewportCount, m_state.vp.scissorRects.data()); m_cmd->cmdSetScissor (0, viewportCount, m_state.vp.scissorRects.data());
} }
if (m_flags.test(DxvkContextFlag::GpDirtyBlendConstants)) if (m_flags.all(DxvkContextFlag::GpDirtyBlendConstants,
DxvkContextFlag::GpDynamicBlendConstants)) {
m_flags.clr(DxvkContextFlag::GpDirtyBlendConstants);
m_cmd->cmdSetBlendConstants(&m_state.om.blendConstants.r); m_cmd->cmdSetBlendConstants(&m_state.om.blendConstants.r);
}
if (m_flags.test(DxvkContextFlag::GpDirtyStencilRef)) if (m_flags.all(DxvkContextFlag::GpDirtyStencilRef,
m_cmd->cmdSetStencilReference(VK_STENCIL_FRONT_AND_BACK, m_state.om.stencilReference); DxvkContextFlag::GpDynamicStencilRef)) {
m_flags.clr(DxvkContextFlag::GpDirtyStencilRef);
m_cmd->cmdSetStencilReference(
VK_STENCIL_FRONT_AND_BACK,
m_state.om.stencilReference);
}
if (m_flags.test(DxvkContextFlag::GpDirtyDepthBias)) { if (m_flags.all(DxvkContextFlag::GpDirtyDepthBias,
DxvkContextFlag::GpDynamicDepthBias)) {
m_flags.clr(DxvkContextFlag::GpDirtyDepthBias);
m_cmd->cmdSetDepthBias( m_cmd->cmdSetDepthBias(
m_state.ds.depthBiasConstant, m_state.ds.depthBiasConstant,
m_state.ds.depthBiasClamp, m_state.ds.depthBiasClamp,
m_state.ds.depthBiasSlope); m_state.ds.depthBiasSlope);
} }
m_flags.clr(
DxvkContextFlag::GpDirtyBlendConstants,
DxvkContextFlag::GpDirtyStencilRef,
DxvkContextFlag::GpDirtyViewport,
DxvkContextFlag::GpDirtyDepthBias);
} }

View File

@ -35,16 +35,19 @@ namespace dxvk {
GpDirtyXfbBuffers, ///< Transform feedback buffer bindings are out of date GpDirtyXfbBuffers, ///< Transform feedback buffer bindings are out of date
GpDirtyXfbCounters, ///< Counter buffer values are dirty GpDirtyXfbCounters, ///< Counter buffer values are dirty
GpDirtyBlendConstants, ///< Blend constants have changed GpDirtyBlendConstants, ///< Blend constants have changed
GpDirtyDepthBias, ///< Depth bias has changed
GpDirtyStencilRef, ///< Stencil reference has changed GpDirtyStencilRef, ///< Stencil reference has changed
GpDirtyViewport, ///< Viewport state has changed GpDirtyViewport, ///< Viewport state has changed
GpDirtyDepthBias, ///< Depth bias has changed GpDynamicBlendConstants, ///< Blend constants are dynamic
GpDynamicDepthBias, ///< Depth bias is dynamic
GpDynamicStencilRef, ///< Stencil reference is dynamic
CpDirtyPipeline, ///< Compute pipeline binding are out of date CpDirtyPipeline, ///< Compute pipeline binding are out of date
CpDirtyPipelineState, ///< Compute pipeline needs to be recompiled CpDirtyPipelineState, ///< Compute pipeline needs to be recompiled
CpDirtyResources, ///< Compute pipeline resource bindings are out of date CpDirtyResources, ///< Compute pipeline resource bindings are out of date
CpDirtyDescriptorOffsets, ///< Compute descriptor set needs to be rebound CpDirtyDescriptorOffsets, ///< Compute descriptor set needs to be rebound
CpDirtyDescriptorSet, ///< Compute descriptor set needs to be updated CpDirtyDescriptorSet, ///< Compute descriptor set needs to be updated
DirtyDrawBuffer, ///< Indirect argument buffer is dirty DirtyDrawBuffer, ///< Indirect argument buffer is dirty
}; };

View File

@ -177,13 +177,21 @@ namespace dxvk {
this->logPipelineState(LogLevel::Debug, state); this->logPipelineState(LogLevel::Debug, state);
} }
std::array<VkDynamicState, 5> dynamicStates = { // Set up dynamic states as needed
VK_DYNAMIC_STATE_VIEWPORT, std::array<VkDynamicState, 5> dynamicStates;
VK_DYNAMIC_STATE_SCISSOR, uint32_t dynamicStateCount = 0;
VK_DYNAMIC_STATE_DEPTH_BIAS,
VK_DYNAMIC_STATE_BLEND_CONSTANTS, dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_VIEWPORT;
VK_DYNAMIC_STATE_STENCIL_REFERENCE, dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_SCISSOR;
};
if (state.useDynamicDepthBias())
dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_BIAS;
if (state.useDynamicBlendConstants())
dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_BLEND_CONSTANTS;
if (state.useDynamicStencilRef())
dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_STENCIL_REFERENCE;
// Figure out the actual sample count to use // Figure out the actual sample count to use
VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT; VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
@ -366,7 +374,7 @@ namespace dxvk {
dyInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; dyInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
dyInfo.pNext = nullptr; dyInfo.pNext = nullptr;
dyInfo.flags = 0; dyInfo.flags = 0;
dyInfo.dynamicStateCount = dynamicStates.size(); dyInfo.dynamicStateCount = dynamicStateCount;
dyInfo.pDynamicStates = dynamicStates.data(); dyInfo.pDynamicStates = dynamicStates.data();
VkGraphicsPipelineCreateInfo info; VkGraphicsPipelineCreateInfo info;