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();
// Fix up vertex binding strides for unbound buffers
for (uint32_t i = 0; i < m_state.gp.state.ilBindingCount; i++) {
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++)
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_state.gp.pipeline->getPipelineHandle(m_state.gp.state,
m_state.om.framebuffer->getRenderPass())
@ -3006,29 +3026,37 @@ namespace dxvk {
return;
if (m_flags.test(DxvkContextFlag::GpDirtyViewport)) {
m_flags.clr(DxvkContextFlag::GpDirtyViewport);
uint32_t viewportCount = m_state.gp.state.rsViewportCount;
m_cmd->cmdSetViewport(0, viewportCount, m_state.vp.viewports.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);
}
if (m_flags.test(DxvkContextFlag::GpDirtyStencilRef))
m_cmd->cmdSetStencilReference(VK_STENCIL_FRONT_AND_BACK, m_state.om.stencilReference);
if (m_flags.all(DxvkContextFlag::GpDirtyStencilRef,
DxvkContextFlag::GpDynamicStencilRef)) {
m_flags.clr(DxvkContextFlag::GpDirtyStencilRef);
m_cmd->cmdSetStencilReference(
VK_STENCIL_FRONT_AND_BACK,
m_state.om.stencilReference);
}
if (m_flags.all(DxvkContextFlag::GpDirtyDepthBias,
DxvkContextFlag::GpDynamicDepthBias)) {
m_flags.clr(DxvkContextFlag::GpDirtyDepthBias);
if (m_flags.test(DxvkContextFlag::GpDirtyDepthBias)) {
m_cmd->cmdSetDepthBias(
m_state.ds.depthBiasConstant,
m_state.ds.depthBiasClamp,
m_state.ds.depthBiasSlope);
}
m_flags.clr(
DxvkContextFlag::GpDirtyBlendConstants,
DxvkContextFlag::GpDirtyStencilRef,
DxvkContextFlag::GpDirtyViewport,
DxvkContextFlag::GpDirtyDepthBias);
}

View File

@ -35,9 +35,12 @@ namespace dxvk {
GpDirtyXfbBuffers, ///< Transform feedback buffer bindings are out of date
GpDirtyXfbCounters, ///< Counter buffer values are dirty
GpDirtyBlendConstants, ///< Blend constants have changed
GpDirtyDepthBias, ///< Depth bias has changed
GpDirtyStencilRef, ///< Stencil reference 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
CpDirtyPipelineState, ///< Compute pipeline needs to be recompiled

View File

@ -177,13 +177,21 @@ namespace dxvk {
this->logPipelineState(LogLevel::Debug, state);
}
std::array<VkDynamicState, 5> dynamicStates = {
VK_DYNAMIC_STATE_VIEWPORT,
VK_DYNAMIC_STATE_SCISSOR,
VK_DYNAMIC_STATE_DEPTH_BIAS,
VK_DYNAMIC_STATE_BLEND_CONSTANTS,
VK_DYNAMIC_STATE_STENCIL_REFERENCE,
};
// Set up dynamic states as needed
std::array<VkDynamicState, 5> dynamicStates;
uint32_t dynamicStateCount = 0;
dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_VIEWPORT;
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
VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
@ -366,7 +374,7 @@ namespace dxvk {
dyInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
dyInfo.pNext = nullptr;
dyInfo.flags = 0;
dyInfo.dynamicStateCount = dynamicStates.size();
dyInfo.dynamicStateCount = dynamicStateCount;
dyInfo.pDynamicStates = dynamicStates.data();
VkGraphicsPipelineCreateInfo info;