From fc47fb8f6cdd2a231bbb3982bd0aa70efc5dd019 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 26 Mar 2018 23:13:33 +0200 Subject: [PATCH] [dxvk] Do not create descriptor set layout/template if binding count is 0 Fixes a validation error in case an application renders geometry without any active shader resource slots. --- src/dxvk/dxvk_context.cpp | 22 ++++++------ src/dxvk/dxvk_pipelayout.cpp | 68 ++++++++++++++++++++---------------- 2 files changed, 49 insertions(+), 41 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 8eb8f5a8b..d17ca9bc7 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1604,16 +1604,18 @@ namespace dxvk { VkPipelineBindPoint bindPoint, const DxvkBindingState& bindingState, const Rc& layout) { - const VkDescriptorSet dset = - m_cmd->allocateDescriptorSet( - layout->descriptorSetLayout()); - - m_cmd->updateDescriptorSetWithTemplate( - dset, layout->descriptorTemplate(), - m_descInfos.data()); - - m_cmd->cmdBindDescriptorSet(bindPoint, - layout->pipelineLayout(), dset); + if (layout->bindingCount() != 0) { + const VkDescriptorSet dset = + m_cmd->allocateDescriptorSet( + layout->descriptorSetLayout()); + + m_cmd->updateDescriptorSetWithTemplate( + dset, layout->descriptorTemplate(), + m_descInfos.data()); + + m_cmd->cmdBindDescriptorSet(bindPoint, + layout->pipelineLayout(), dset); + } } diff --git a/src/dxvk/dxvk_pipelayout.cpp b/src/dxvk/dxvk_pipelayout.cpp index 0f4c98c28..bb38fa803 100644 --- a/src/dxvk/dxvk_pipelayout.cpp +++ b/src/dxvk/dxvk_pipelayout.cpp @@ -70,24 +70,27 @@ namespace dxvk { tEntries[i].stride = 0; } - // Create descriptor set layout - VkDescriptorSetLayoutCreateInfo dsetInfo; - dsetInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - dsetInfo.pNext = nullptr; - dsetInfo.flags = 0; - dsetInfo.bindingCount = bindings.size(); - dsetInfo.pBindings = bindings.data(); + // Create descriptor set layout. We do not need to + // create one if there are no active resource bindings. + if (bindingCount > 0) { + VkDescriptorSetLayoutCreateInfo dsetInfo; + dsetInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + dsetInfo.pNext = nullptr; + dsetInfo.flags = 0; + dsetInfo.bindingCount = bindings.size(); + dsetInfo.pBindings = bindings.data(); + + if (m_vkd->vkCreateDescriptorSetLayout(m_vkd->device(), + &dsetInfo, nullptr, &m_descriptorSetLayout) != VK_SUCCESS) + throw DxvkError("DxvkPipelineLayout: Failed to create descriptor set layout"); + } - if (m_vkd->vkCreateDescriptorSetLayout(m_vkd->device(), - &dsetInfo, nullptr, &m_descriptorSetLayout) != VK_SUCCESS) - throw DxvkError("DxvkPipelineLayout: Failed to create descriptor set layout"); - - // Create pipeline layout + // Create pipeline layout with the given descriptor set layout VkPipelineLayoutCreateInfo pipeInfo; pipeInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; pipeInfo.pNext = nullptr; pipeInfo.flags = 0; - pipeInfo.setLayoutCount = 1; + pipeInfo.setLayoutCount = bindingCount > 0 ? 1 : 0; pipeInfo.pSetLayouts = &m_descriptorSetLayout; pipeInfo.pushConstantRangeCount = 0; pipeInfo.pPushConstantRanges = nullptr; @@ -98,24 +101,27 @@ namespace dxvk { throw DxvkError("DxvkPipelineLayout: Failed to create pipeline layout"); } - // Create descriptor update template - VkDescriptorUpdateTemplateCreateInfoKHR templateInfo; - templateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR; - templateInfo.pNext = nullptr; - templateInfo.flags = 0; - templateInfo.descriptorUpdateEntryCount = tEntries.size(); - templateInfo.pDescriptorUpdateEntries = tEntries.data(); - templateInfo.templateType = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR; - templateInfo.descriptorSetLayout = m_descriptorSetLayout; - templateInfo.pipelineBindPoint = pipelineBindPoint; - templateInfo.pipelineLayout = m_pipelineLayout; - templateInfo.set = 0; - - if (m_vkd->vkCreateDescriptorUpdateTemplateKHR(m_vkd->device(), - &templateInfo, nullptr, &m_descriptorTemplate) != VK_SUCCESS) { - m_vkd->vkDestroyDescriptorSetLayout(m_vkd->device(), m_descriptorSetLayout, nullptr); - m_vkd->vkDestroyPipelineLayout(m_vkd->device(), m_pipelineLayout, nullptr); - throw DxvkError("DxvkPipelineLayout: Failed to create descriptor update template"); + // Create descriptor update template. If there are no active + // resource bindings, there won't be any descriptors to update. + if (bindingCount > 0) { + VkDescriptorUpdateTemplateCreateInfoKHR templateInfo; + templateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR; + templateInfo.pNext = nullptr; + templateInfo.flags = 0; + templateInfo.descriptorUpdateEntryCount = tEntries.size(); + templateInfo.pDescriptorUpdateEntries = tEntries.data(); + templateInfo.templateType = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR; + templateInfo.descriptorSetLayout = m_descriptorSetLayout; + templateInfo.pipelineBindPoint = pipelineBindPoint; + templateInfo.pipelineLayout = m_pipelineLayout; + templateInfo.set = 0; + + if (m_vkd->vkCreateDescriptorUpdateTemplateKHR( + m_vkd->device(), &templateInfo, nullptr, &m_descriptorTemplate) != VK_SUCCESS) { + m_vkd->vkDestroyDescriptorSetLayout(m_vkd->device(), m_descriptorSetLayout, nullptr); + m_vkd->vkDestroyPipelineLayout(m_vkd->device(), m_pipelineLayout, nullptr); + throw DxvkError("DxvkPipelineLayout: Failed to create descriptor update template"); + } } }