diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 695ab56bb..3d7a30dad 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -134,11 +134,12 @@ namespace dxvk { } - void updateDescriptorSet( - uint32_t descriptorCount, - const VkWriteDescriptorSet* descriptorWrites) { - m_vkd->vkUpdateDescriptorSets(m_vkd->device(), - descriptorCount, descriptorWrites, 0, nullptr); + void updateDescriptorSetWithTemplate( + VkDescriptorSet descriptorSet, + VkDescriptorUpdateTemplateKHR descriptorTemplate, + const void* data) { + m_vkd->vkUpdateDescriptorSetWithTemplateKHR(m_vkd->device(), + descriptorSet, descriptorTemplate, data); } diff --git a/src/dxvk/dxvk_compute.cpp b/src/dxvk/dxvk_compute.cpp index 511a5aae6..e78927b92 100644 --- a/src/dxvk/dxvk_compute.cpp +++ b/src/dxvk/dxvk_compute.cpp @@ -26,7 +26,8 @@ namespace dxvk { m_layout = new DxvkPipelineLayout(m_vkd, slotMapping.bindingCount(), - slotMapping.bindingInfos()); + slotMapping.bindingInfos(), + VK_PIPELINE_BIND_POINT_COMPUTE); m_cs = cs->createShaderModule(m_vkd, slotMapping); } diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 929f1bf74..f879796f7 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -7,20 +7,7 @@ namespace dxvk { DxvkContext::DxvkContext(const Rc& device) - : m_device(device) { - for (uint32_t i = 0; i < m_descWrites.size(); i++) { - m_descWrites[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - m_descWrites[i].pNext = nullptr; - m_descWrites[i].dstSet = VK_NULL_HANDLE; - m_descWrites[i].dstBinding = i; - m_descWrites[i].dstArrayElement = 0; - m_descWrites[i].descriptorCount = 1; - m_descWrites[i].descriptorType = VkDescriptorType(0); - m_descWrites[i].pImageInfo = &m_descInfos[i].image; - m_descWrites[i].pBufferInfo = &m_descInfos[i].buffer; - m_descWrites[i].pTexelBufferView = &m_descInfos[i].texelBuffer; - } - } + : m_device(device) { } DxvkContext::~DxvkContext() { @@ -1620,13 +1607,10 @@ namespace dxvk { m_cmd->allocateDescriptorSet( layout->descriptorSetLayout()); - for (uint32_t i = 0; i < layout->bindingCount(); i++) { - m_descWrites[i].dstSet = dset; - m_descWrites[i].descriptorType = layout->binding(i).type; - } + m_cmd->updateDescriptorSetWithTemplate( + dset, layout->descriptorTemplate(), + m_descInfos.data()); - m_cmd->updateDescriptorSet( - layout->bindingCount(), m_descWrites.data()); m_cmd->cmdBindDescriptorSet(bindPoint, layout->pipelineLayout(), dset); } diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 61c6b2088..6a819ede2 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -578,7 +578,6 @@ namespace dxvk { std::array m_rc; std::array m_descInfos; - std::array m_descWrites; void renderPassBegin(); void renderPassEnd(); diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index 74108476e..d66379103 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -129,11 +129,12 @@ namespace dxvk { * used by DXVK if supported by the implementation. */ struct DxvkDeviceExtensions : public DxvkExtensionList { - DxvkExtension amdRasterizationOrder = { this, VK_AMD_RASTERIZATION_ORDER_EXTENSION_NAME, DxvkExtensionType::Optional }; - DxvkExtension khrMaintenance1 = { this, VK_KHR_MAINTENANCE1_EXTENSION_NAME, DxvkExtensionType::Required }; - DxvkExtension khrMaintenance2 = { this, VK_KHR_MAINTENANCE2_EXTENSION_NAME, DxvkExtensionType::Desired }; - DxvkExtension khrShaderDrawParameters = { this, VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME, DxvkExtensionType::Required }; - DxvkExtension khrSwapchain = { this, VK_KHR_SWAPCHAIN_EXTENSION_NAME, DxvkExtensionType::Required }; + DxvkExtension amdRasterizationOrder = { this, VK_AMD_RASTERIZATION_ORDER_EXTENSION_NAME, DxvkExtensionType::Optional }; + DxvkExtension khrDescriptorUpdateTemplate = { this, VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME, DxvkExtensionType::Required }; + DxvkExtension khrMaintenance1 = { this, VK_KHR_MAINTENANCE1_EXTENSION_NAME, DxvkExtensionType::Required }; + DxvkExtension khrMaintenance2 = { this, VK_KHR_MAINTENANCE2_EXTENSION_NAME, DxvkExtensionType::Desired }; + DxvkExtension khrShaderDrawParameters = { this, VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME, DxvkExtensionType::Required }; + DxvkExtension khrSwapchain = { this, VK_KHR_SWAPCHAIN_EXTENSION_NAME, DxvkExtensionType::Required }; }; } \ No newline at end of file diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index b5586bb12..769e05e29 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -52,7 +52,8 @@ namespace dxvk { m_layout = new DxvkPipelineLayout(m_vkd, slotMapping.bindingCount(), - slotMapping.bindingInfos()); + slotMapping.bindingInfos(), + VK_PIPELINE_BIND_POINT_GRAPHICS); if (vs != nullptr) m_vs = vs ->createShaderModule(m_vkd, slotMapping); if (tcs != nullptr) m_tcs = tcs->createShaderModule(m_vkd, slotMapping); diff --git a/src/dxvk/dxvk_pipelayout.cpp b/src/dxvk/dxvk_pipelayout.cpp index 80412fedc..0f4c98c28 100644 --- a/src/dxvk/dxvk_pipelayout.cpp +++ b/src/dxvk/dxvk_pipelayout.cpp @@ -1,5 +1,6 @@ #include +#include "dxvk_descriptor.h" #include "dxvk_pipelayout.h" namespace dxvk { @@ -44,26 +45,32 @@ namespace dxvk { DxvkPipelineLayout::DxvkPipelineLayout( const Rc& vkd, uint32_t bindingCount, - const DxvkDescriptorSlot* bindingInfos) - : m_vkd(vkd) { - - m_bindingSlots.resize(bindingCount); + const DxvkDescriptorSlot* bindingInfos, + VkPipelineBindPoint pipelineBindPoint) + : m_vkd(vkd), m_bindingSlots(bindingCount) { for (uint32_t i = 0; i < bindingCount; i++) m_bindingSlots[i] = bindingInfos[i]; - std::vector bindings; + std::vector bindings(bindingCount); + std::vector tEntries(bindingCount); for (uint32_t i = 0; i < bindingCount; i++) { - VkDescriptorSetLayoutBinding binding; - binding.binding = i; - binding.descriptorType = bindingInfos[i].type; - binding.descriptorCount = 1; - binding.stageFlags = bindingInfos[i].stages; - binding.pImmutableSamplers = nullptr; - bindings.push_back(binding); + bindings[i].binding = i; + bindings[i].descriptorType = bindingInfos[i].type; + bindings[i].descriptorCount = 1; + bindings[i].stageFlags = bindingInfos[i].stages; + bindings[i].pImmutableSamplers = nullptr; + + tEntries[i].dstBinding = i; + tEntries[i].dstArrayElement = 0; + tEntries[i].descriptorCount = 1; + tEntries[i].descriptorType = bindingInfos[i].type; + tEntries[i].offset = sizeof(DxvkDescriptorInfo) * i; + tEntries[i].stride = 0; } + // Create descriptor set layout VkDescriptorSetLayoutCreateInfo dsetInfo; dsetInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; dsetInfo.pNext = nullptr; @@ -75,6 +82,7 @@ namespace dxvk { &dsetInfo, nullptr, &m_descriptorSetLayout) != VK_SUCCESS) throw DxvkError("DxvkPipelineLayout: Failed to create descriptor set layout"); + // Create pipeline layout VkPipelineLayoutCreateInfo pipeInfo; pipeInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; pipeInfo.pNext = nullptr; @@ -85,24 +93,42 @@ namespace dxvk { pipeInfo.pPushConstantRanges = nullptr; if (m_vkd->vkCreatePipelineLayout(m_vkd->device(), - &pipeInfo, nullptr, &m_pipelineLayout) != VK_SUCCESS) { - m_vkd->vkDestroyDescriptorSetLayout( - m_vkd->device(), m_descriptorSetLayout, nullptr); + &pipeInfo, nullptr, &m_pipelineLayout) != VK_SUCCESS) { + m_vkd->vkDestroyDescriptorSetLayout(m_vkd->device(), m_descriptorSetLayout, nullptr); 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"); + } } DxvkPipelineLayout::~DxvkPipelineLayout() { - if (m_pipelineLayout != VK_NULL_HANDLE) { - m_vkd->vkDestroyPipelineLayout( - m_vkd->device(), m_pipelineLayout, nullptr); - } + m_vkd->vkDestroyDescriptorUpdateTemplateKHR( + m_vkd->device(), m_descriptorTemplate, nullptr); - if (m_descriptorSetLayout != VK_NULL_HANDLE) { - m_vkd->vkDestroyDescriptorSetLayout( - m_vkd->device(), m_descriptorSetLayout, nullptr); - } + m_vkd->vkDestroyPipelineLayout( + m_vkd->device(), m_pipelineLayout, nullptr); + + m_vkd->vkDestroyDescriptorSetLayout( + m_vkd->device(), m_descriptorSetLayout, nullptr); } } \ No newline at end of file diff --git a/src/dxvk/dxvk_pipelayout.h b/src/dxvk/dxvk_pipelayout.h index bee0df02a..e89a006ec 100644 --- a/src/dxvk/dxvk_pipelayout.h +++ b/src/dxvk/dxvk_pipelayout.h @@ -111,7 +111,8 @@ namespace dxvk { DxvkPipelineLayout( const Rc& vkd, uint32_t bindingCount, - const DxvkDescriptorSlot* bindingInfos); + const DxvkDescriptorSlot* bindingInfos, + VkPipelineBindPoint pipelineBindPoint); ~DxvkPipelineLayout(); @@ -157,12 +158,21 @@ namespace dxvk { return m_pipelineLayout; } + /** + * \brief Descriptor update template + * \returns Descriptor update template + */ + VkDescriptorUpdateTemplateKHR descriptorTemplate() const { + return m_descriptorTemplate; + } + private: - Rc m_vkd; + Rc m_vkd; - VkDescriptorSetLayout m_descriptorSetLayout = VK_NULL_HANDLE; - VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE; + VkDescriptorSetLayout m_descriptorSetLayout = VK_NULL_HANDLE; + VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE; + VkDescriptorUpdateTemplateKHR m_descriptorTemplate = VK_NULL_HANDLE; std::vector m_bindingSlots;