mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-14 00:48:44 +01:00
[dxvk] Create full pipeline layout with INDEPENDENT_SETS_BIT
And use it to link pipelines as well as descriptor binding. Should fix issues related to descriptors.
This commit is contained in:
parent
b51d7a3cc0
commit
5e1569593a
@ -119,7 +119,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
VkComputePipelineCreateInfo info = { VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO };
|
VkComputePipelineCreateInfo info = { VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO };
|
||||||
info.stage = *stageInfo.getStageInfos();
|
info.stage = *stageInfo.getStageInfos();
|
||||||
info.layout = m_bindings->getPipelineLayout();
|
info.layout = m_bindings->getPipelineLayout(false);
|
||||||
info.basePipelineIndex = -1;
|
info.basePipelineIndex = -1;
|
||||||
|
|
||||||
// Time pipeline compilation for debugging purposes
|
// Time pipeline compilation for debugging purposes
|
||||||
|
@ -84,7 +84,8 @@ namespace dxvk {
|
|||||||
// before any draw or dispatch command is recorded.
|
// before any draw or dispatch command is recorded.
|
||||||
m_flags.clr(
|
m_flags.clr(
|
||||||
DxvkContextFlag::GpRenderPassBound,
|
DxvkContextFlag::GpRenderPassBound,
|
||||||
DxvkContextFlag::GpXfbActive);
|
DxvkContextFlag::GpXfbActive,
|
||||||
|
DxvkContextFlag::GpIndependentSets);
|
||||||
|
|
||||||
m_flags.set(
|
m_flags.set(
|
||||||
DxvkContextFlag::GpDirtyFramebuffer,
|
DxvkContextFlag::GpDirtyFramebuffer,
|
||||||
@ -3995,6 +3996,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
m_flags.set(
|
m_flags.set(
|
||||||
DxvkContextFlag::GpRenderPassBound,
|
DxvkContextFlag::GpRenderPassBound,
|
||||||
|
DxvkContextFlag::GpDirtyPipeline,
|
||||||
DxvkContextFlag::GpDirtyPipelineState,
|
DxvkContextFlag::GpDirtyPipelineState,
|
||||||
DxvkContextFlag::GpDirtyVertexBuffers,
|
DxvkContextFlag::GpDirtyVertexBuffers,
|
||||||
DxvkContextFlag::GpDirtyIndexBuffer,
|
DxvkContextFlag::GpDirtyIndexBuffer,
|
||||||
@ -4006,7 +4008,9 @@ namespace dxvk {
|
|||||||
DxvkContextFlag::GpDirtyDepthBounds,
|
DxvkContextFlag::GpDirtyDepthBounds,
|
||||||
DxvkContextFlag::DirtyPushConstants);
|
DxvkContextFlag::DirtyPushConstants);
|
||||||
|
|
||||||
m_flags.clr(DxvkContextFlag::GpRenderPassSuspended);
|
m_flags.clr(
|
||||||
|
DxvkContextFlag::GpRenderPassSuspended,
|
||||||
|
DxvkContextFlag::GpIndependentSets);
|
||||||
|
|
||||||
this->renderPassBindFramebuffer(
|
this->renderPassBindFramebuffer(
|
||||||
m_state.om.framebufferInfo,
|
m_state.om.framebufferInfo,
|
||||||
@ -4470,6 +4474,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
bool DxvkContext::updateGraphicsPipelineState(DxvkGlobalPipelineBarrier srcBarrier) {
|
bool DxvkContext::updateGraphicsPipelineState(DxvkGlobalPipelineBarrier srcBarrier) {
|
||||||
|
bool oldIndependentSets = m_flags.test(DxvkContextFlag::GpIndependentSets);
|
||||||
|
|
||||||
// Set up vertex buffer strides for active bindings
|
// Set up vertex buffer strides for active bindings
|
||||||
for (uint32_t i = 0; i < m_state.gp.state.il.bindingCount(); i++) {
|
for (uint32_t i = 0; i < m_state.gp.state.il.bindingCount(); i++) {
|
||||||
const uint32_t binding = m_state.gp.state.ilBindings[i].binding();
|
const uint32_t binding = m_state.gp.state.ilBindings[i].binding();
|
||||||
@ -4481,7 +4487,8 @@ namespace dxvk {
|
|||||||
m_flags.clr(DxvkContextFlag::GpDynamicBlendConstants,
|
m_flags.clr(DxvkContextFlag::GpDynamicBlendConstants,
|
||||||
DxvkContextFlag::GpDynamicDepthBias,
|
DxvkContextFlag::GpDynamicDepthBias,
|
||||||
DxvkContextFlag::GpDynamicDepthBounds,
|
DxvkContextFlag::GpDynamicDepthBounds,
|
||||||
DxvkContextFlag::GpDynamicStencilRef);
|
DxvkContextFlag::GpDynamicStencilRef,
|
||||||
|
DxvkContextFlag::GpIndependentSets);
|
||||||
|
|
||||||
m_flags.set(m_state.gp.state.useDynamicBlendConstants()
|
m_flags.set(m_state.gp.state.useDynamicBlendConstants()
|
||||||
? DxvkContextFlag::GpDynamicBlendConstants
|
? DxvkContextFlag::GpDynamicBlendConstants
|
||||||
@ -4533,8 +4540,16 @@ namespace dxvk {
|
|||||||
|
|
||||||
if (!m_state.gp.state.rs.depthBiasEnable())
|
if (!m_state.gp.state.rs.depthBiasEnable())
|
||||||
m_cmd->cmdSetDepthBias(0.0f, 0.0f, 0.0f);
|
m_cmd->cmdSetDepthBias(0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
m_flags.set(DxvkContextFlag::GpIndependentSets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If necessary, dirty descriptor sets due to layout incompatibilities
|
||||||
|
bool newIndependentSets = m_flags.test(DxvkContextFlag::GpIndependentSets);
|
||||||
|
|
||||||
|
if (newIndependentSets != oldIndependentSets)
|
||||||
|
m_descriptorState.dirtyStages(VK_SHADER_STAGE_ALL_GRAPHICS);
|
||||||
|
|
||||||
// Emit barrier based on pipeline properties, in order to avoid
|
// Emit barrier based on pipeline properties, in order to avoid
|
||||||
// accidental write-after-read hazards after the render pass.
|
// accidental write-after-read hazards after the render pass.
|
||||||
DxvkGlobalPipelineBarrier pipelineBarrier = m_state.gp.pipeline->getGlobalBarrier(m_state.gp.state);
|
DxvkGlobalPipelineBarrier pipelineBarrier = m_state.gp.pipeline->getGlobalBarrier(m_state.gp.state);
|
||||||
@ -4570,6 +4585,9 @@ namespace dxvk {
|
|||||||
// For 64-bit applications, using templates is slower on some drivers.
|
// For 64-bit applications, using templates is slower on some drivers.
|
||||||
constexpr bool useDescriptorTemplates = env::is32BitHostPlatform();
|
constexpr bool useDescriptorTemplates = env::is32BitHostPlatform();
|
||||||
|
|
||||||
|
bool independentSets = BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS
|
||||||
|
&& m_flags.test(DxvkContextFlag::GpIndependentSets);
|
||||||
|
|
||||||
uint32_t layoutSetMask = layout->getSetMask();
|
uint32_t layoutSetMask = layout->getSetMask();
|
||||||
uint32_t dirtySetMask = BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS
|
uint32_t dirtySetMask = BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS
|
||||||
? m_descriptorState.getDirtyGraphicsSets()
|
? m_descriptorState.getDirtyGraphicsSets()
|
||||||
@ -4752,7 +4770,7 @@ namespace dxvk {
|
|||||||
uint32_t firstSet = setIndex + 1 - bindCount;
|
uint32_t firstSet = setIndex + 1 - bindCount;
|
||||||
|
|
||||||
m_cmd->cmdBindDescriptorSets(BindPoint,
|
m_cmd->cmdBindDescriptorSets(BindPoint,
|
||||||
layout->getPipelineLayout(),
|
layout->getPipelineLayout(independentSets),
|
||||||
firstSet, bindCount, &sets[firstSet],
|
firstSet, bindCount, &sets[firstSet],
|
||||||
0, nullptr);
|
0, nullptr);
|
||||||
|
|
||||||
@ -5148,8 +5166,10 @@ namespace dxvk {
|
|||||||
if (!pushConstRange.size)
|
if (!pushConstRange.size)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Push constants should be compatible between complete and
|
||||||
|
// independent layouts, so always ask for the complete one
|
||||||
m_cmd->cmdPushConstants(
|
m_cmd->cmdPushConstants(
|
||||||
bindings->getPipelineLayout(),
|
bindings->getPipelineLayout(false),
|
||||||
pushConstRange.stageFlags,
|
pushConstRange.stageFlags,
|
||||||
pushConstRange.offset,
|
pushConstRange.offset,
|
||||||
pushConstRange.size,
|
pushConstRange.size,
|
||||||
|
@ -39,6 +39,7 @@ namespace dxvk {
|
|||||||
GpDynamicDepthBias, ///< Depth bias is dynamic
|
GpDynamicDepthBias, ///< Depth bias is dynamic
|
||||||
GpDynamicDepthBounds, ///< Depth bounds are dynamic
|
GpDynamicDepthBounds, ///< Depth bounds are dynamic
|
||||||
GpDynamicStencilRef, ///< Stencil reference is dynamic
|
GpDynamicStencilRef, ///< Stencil reference is dynamic
|
||||||
|
GpIndependentSets, ///< Graphics pipeline layout was created with independent sets
|
||||||
|
|
||||||
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
|
||||||
|
@ -164,14 +164,14 @@ namespace dxvk {
|
|||||||
|
|
||||||
DxvkDescriptorSetMap* DxvkDescriptorPool::getSetMap(
|
DxvkDescriptorSetMap* DxvkDescriptorPool::getSetMap(
|
||||||
const DxvkBindingLayoutObjects* layout) {
|
const DxvkBindingLayoutObjects* layout) {
|
||||||
auto pair = m_setMaps.find(layout->getPipelineLayout());
|
auto pair = m_setMaps.find(layout->getPipelineLayout(false));
|
||||||
if (likely(pair != m_setMaps.end())) {
|
if (likely(pair != m_setMaps.end())) {
|
||||||
return &pair->second;
|
return &pair->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto iter = m_setMaps.emplace(
|
auto iter = m_setMaps.emplace(
|
||||||
std::piecewise_construct,
|
std::piecewise_construct,
|
||||||
std::tuple(layout->getPipelineLayout()),
|
std::tuple(layout->getPipelineLayout(false)),
|
||||||
std::tuple());
|
std::tuple());
|
||||||
|
|
||||||
for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount; i++) {
|
for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount; i++) {
|
||||||
|
@ -702,6 +702,8 @@ namespace dxvk {
|
|||||||
libInfo.pLibraries = libraries.data();
|
libInfo.pLibraries = libraries.data();
|
||||||
|
|
||||||
VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &libInfo };
|
VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &libInfo };
|
||||||
|
info.layout = m_bindings->getPipelineLayout(true);
|
||||||
|
info.basePipelineIndex = -1;
|
||||||
|
|
||||||
VkPipeline pipeline = VK_NULL_HANDLE;
|
VkPipeline pipeline = VK_NULL_HANDLE;
|
||||||
|
|
||||||
@ -790,7 +792,7 @@ namespace dxvk {
|
|||||||
info.pDepthStencilState = &fsState.dsInfo;
|
info.pDepthStencilState = &fsState.dsInfo;
|
||||||
info.pColorBlendState = &foState.cbInfo;
|
info.pColorBlendState = &foState.cbInfo;
|
||||||
info.pDynamicState = &dyInfo;
|
info.pDynamicState = &dyInfo;
|
||||||
info.layout = m_bindings->getPipelineLayout();
|
info.layout = m_bindings->getPipelineLayout(false);
|
||||||
info.basePipelineIndex = -1;
|
info.basePipelineIndex = -1;
|
||||||
|
|
||||||
if (!prState.tsInfo.patchControlPoints)
|
if (!prState.tsInfo.patchControlPoints)
|
||||||
|
@ -323,29 +323,40 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create pipeline layout objects
|
||||||
VkPushConstantRange pushConst = m_layout.getPushConstantRange();
|
VkPushConstantRange pushConst = m_layout.getPushConstantRange();
|
||||||
|
|
||||||
VkPipelineLayoutCreateInfo pipelineLayoutInfo = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO };
|
VkPipelineLayoutCreateInfo pipelineLayoutInfo = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO };
|
||||||
pipelineLayoutInfo.setLayoutCount = setLayouts.size();
|
pipelineLayoutInfo.setLayoutCount = setLayouts.size();
|
||||||
pipelineLayoutInfo.pSetLayouts = setLayouts.data();
|
pipelineLayoutInfo.pSetLayouts = setLayouts.data();
|
||||||
|
|
||||||
if (m_layout.getSetMask() != (1u << DxvkDescriptorSets::SetCount) - 1)
|
|
||||||
pipelineLayoutInfo.flags = VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT;
|
|
||||||
|
|
||||||
if (pushConst.stageFlags && pushConst.size) {
|
if (pushConst.stageFlags && pushConst.size) {
|
||||||
pipelineLayoutInfo.pushConstantRangeCount = 1;
|
pipelineLayoutInfo.pushConstantRangeCount = 1;
|
||||||
pipelineLayoutInfo.pPushConstantRanges = &pushConst;
|
pipelineLayoutInfo.pPushConstantRanges = &pushConst;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vk->vkCreatePipelineLayout(vk->device(), &pipelineLayoutInfo, nullptr, &m_pipelineLayout))
|
// If the full set is defined, create a layout without INDEPENDENT_SET_BITS
|
||||||
|
if (m_layout.getSetMask() == (1u << DxvkDescriptorSets::SetCount) - 1) {
|
||||||
|
if (vk->vkCreatePipelineLayout(vk->device(), &pipelineLayoutInfo, nullptr, &m_completeLayout))
|
||||||
throw DxvkError("DxvkBindingLayoutObjects: Failed to create pipeline layout");
|
throw DxvkError("DxvkBindingLayoutObjects: Failed to create pipeline layout");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If graphics pipeline libraries are supported, also create a variand with the
|
||||||
|
// bit. It will be used to create shader-based libraries and link pipelines.
|
||||||
|
if (m_device->canUseGraphicsPipelineLibrary() && (m_layout.getStages() & VK_SHADER_STAGE_ALL_GRAPHICS)) {
|
||||||
|
pipelineLayoutInfo.flags = VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT;
|
||||||
|
|
||||||
|
if (vk->vkCreatePipelineLayout(vk->device(), &pipelineLayoutInfo, nullptr, &m_independentLayout))
|
||||||
|
throw DxvkError("DxvkBindingLayoutObjects: Failed to create pipeline layout");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DxvkBindingLayoutObjects::~DxvkBindingLayoutObjects() {
|
DxvkBindingLayoutObjects::~DxvkBindingLayoutObjects() {
|
||||||
auto vk = m_device->vkd();
|
auto vk = m_device->vkd();
|
||||||
|
|
||||||
vk->vkDestroyPipelineLayout(vk->device(), m_pipelineLayout, nullptr);
|
vk->vkDestroyPipelineLayout(vk->device(), m_completeLayout, nullptr);
|
||||||
|
vk->vkDestroyPipelineLayout(vk->device(), m_independentLayout, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -304,6 +304,14 @@ namespace dxvk {
|
|||||||
return m_pushConst;
|
return m_pushConst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Queries shader stages
|
||||||
|
* \returns Shader stages
|
||||||
|
*/
|
||||||
|
VkShaderStageFlags getStages() const {
|
||||||
|
return m_stages;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Queries defined descriptor set layouts
|
* \brief Queries defined descriptor set layouts
|
||||||
*
|
*
|
||||||
@ -433,10 +441,14 @@ namespace dxvk {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Retrieves pipeline layout
|
* \brief Retrieves pipeline layout
|
||||||
* \returns Pipeline layout
|
*
|
||||||
|
* \param [in] independent Request INDEPENDENT_SETS_BIT
|
||||||
|
* \returns Pipeline layout handle
|
||||||
*/
|
*/
|
||||||
VkPipelineLayout getPipelineLayout() const {
|
VkPipelineLayout getPipelineLayout(bool independent) const {
|
||||||
return m_pipelineLayout;
|
return independent
|
||||||
|
? m_independentLayout
|
||||||
|
: m_completeLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -468,7 +480,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
DxvkDevice* m_device;
|
DxvkDevice* m_device;
|
||||||
DxvkBindingLayout m_layout;
|
DxvkBindingLayout m_layout;
|
||||||
VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE;
|
VkPipelineLayout m_completeLayout = VK_NULL_HANDLE;
|
||||||
|
VkPipelineLayout m_independentLayout = VK_NULL_HANDLE;
|
||||||
|
|
||||||
uint32_t m_setMask = 0;
|
uint32_t m_setMask = 0;
|
||||||
|
|
||||||
|
@ -547,7 +547,7 @@ namespace dxvk {
|
|||||||
info.pViewportState = &vpInfo;
|
info.pViewportState = &vpInfo;
|
||||||
info.pRasterizationState = &rsInfo;
|
info.pRasterizationState = &rsInfo;
|
||||||
info.pDynamicState = &dyInfo;
|
info.pDynamicState = &dyInfo;
|
||||||
info.layout = m_layout->getPipelineLayout();
|
info.layout = m_layout->getPipelineLayout(true);
|
||||||
info.basePipelineIndex = -1;
|
info.basePipelineIndex = -1;
|
||||||
|
|
||||||
VkPipeline pipeline = VK_NULL_HANDLE;
|
VkPipeline pipeline = VK_NULL_HANDLE;
|
||||||
@ -625,7 +625,7 @@ namespace dxvk {
|
|||||||
info.pStages = stageInfo.getStageInfos();
|
info.pStages = stageInfo.getStageInfos();
|
||||||
info.pDepthStencilState = &dsInfo;
|
info.pDepthStencilState = &dsInfo;
|
||||||
info.pDynamicState = &dyInfo;
|
info.pDynamicState = &dyInfo;
|
||||||
info.layout = m_layout->getPipelineLayout();
|
info.layout = m_layout->getPipelineLayout(true);
|
||||||
info.basePipelineIndex = -1;
|
info.basePipelineIndex = -1;
|
||||||
|
|
||||||
if (m_shader && m_shader->flags().test(DxvkShaderFlag::HasSampleRateShading))
|
if (m_shader && m_shader->flags().test(DxvkShaderFlag::HasSampleRateShading))
|
||||||
@ -650,7 +650,7 @@ namespace dxvk {
|
|||||||
// Compile the compute pipeline as normal
|
// Compile the compute pipeline as normal
|
||||||
VkComputePipelineCreateInfo info = { VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO };
|
VkComputePipelineCreateInfo info = { VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO };
|
||||||
info.stage = *stageInfo.getStageInfos();
|
info.stage = *stageInfo.getStageInfos();
|
||||||
info.layout = m_layout->getPipelineLayout();
|
info.layout = m_layout->getPipelineLayout(false);
|
||||||
info.basePipelineIndex = -1;
|
info.basePipelineIndex = -1;
|
||||||
|
|
||||||
VkPipeline pipeline = VK_NULL_HANDLE;
|
VkPipeline pipeline = VK_NULL_HANDLE;
|
||||||
|
Loading…
Reference in New Issue
Block a user