From b950102233c9cd4143cb603b91ca71d6e30863f8 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 6 Aug 2022 01:44:56 +0200 Subject: [PATCH] [dxvk] Don't use MaxNumActiveBindings for descriptor updates --- src/dxvk/dxvk_context.cpp | 30 ++++++++++++++++++++---------- src/dxvk/dxvk_context.h | 7 +++++-- src/dxvk/dxvk_pipelayout.cpp | 4 +++- src/dxvk/dxvk_pipelayout.h | 9 +++++++++ 4 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 1169d31c..a747394f 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -21,16 +21,6 @@ namespace dxvk { // Init framebuffer info with default render pass in case // the app does not explicitly bind any render targets m_state.om.framebufferInfo = makeFramebufferInfo(m_state.om.renderTargets); - - for (uint32_t i = 0; i < MaxNumActiveBindings; i++) { - m_descriptorWrites[i] = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET }; - m_descriptorWrites[i].descriptorCount = 1; - m_descriptorWrites[i].descriptorType = VK_DESCRIPTOR_TYPE_MAX_ENUM; - m_descriptorWrites[i].pImageInfo = &m_descriptors[i].image; - m_descriptorWrites[i].pBufferInfo = &m_descriptors[i].buffer; - m_descriptorWrites[i].pTexelBufferView = &m_descriptors[i].texelBuffer; - } - m_descriptorManager = new DxvkDescriptorManager(device.ptr(), type); // Default destination barriers for graphics pipelines @@ -4661,6 +4651,10 @@ namespace dxvk { void DxvkContext::updateResourceBindings(const DxvkBindingLayoutObjects* layout) { const auto& bindings = layout->layout(); + // Ensure that the arrays we write descriptor info to are big enough + if (unlikely(layout->getBindingCount() > m_descriptors.size())) + this->resizeDescriptorArrays(layout->getBindingCount()); + // On 32-bit wine, vkUpdateDescriptorSets has significant overhead due // to struct conversion, so we should use descriptor update templates. // For 64-bit applications, using templates is slower on some drivers. @@ -5849,4 +5843,20 @@ namespace dxvk { return m_zeroBuffer; } + + void DxvkContext::resizeDescriptorArrays( + uint32_t bindingCount) { + m_descriptors.resize(bindingCount); + m_descriptorWrites.resize(bindingCount); + + for (uint32_t i = 0; i < bindingCount; i++) { + m_descriptorWrites[i] = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET }; + m_descriptorWrites[i].descriptorCount = 1; + m_descriptorWrites[i].descriptorType = VK_DESCRIPTOR_TYPE_MAX_ENUM; + m_descriptorWrites[i].pImageInfo = &m_descriptors[i].image; + m_descriptorWrites[i].pBufferInfo = &m_descriptors[i].buffer; + m_descriptorWrites[i].pTexelBufferView = &m_descriptors[i].texelBuffer; + } + } + } diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index c203f833..a716d31b 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1237,8 +1237,8 @@ namespace dxvk { std::vector m_deferredClears; - std::array m_descriptorWrites; - std::array m_descriptors; + std::vector m_descriptorWrites; + std::vector m_descriptors; std::array m_rc; std::array m_gpLookupCache = { }; @@ -1499,6 +1499,9 @@ namespace dxvk { Rc createZeroBuffer( VkDeviceSize size); + void resizeDescriptorArrays( + uint32_t bindingCount); + }; } diff --git a/src/dxvk/dxvk_pipelayout.cpp b/src/dxvk/dxvk_pipelayout.cpp index ef2cd26c..e112ea78 100644 --- a/src/dxvk/dxvk_pipelayout.cpp +++ b/src/dxvk/dxvk_pipelayout.cpp @@ -324,8 +324,10 @@ namespace dxvk { m_mapping.insert({ binding.resourceBinding, mapping }); } - if (bindingCount) + if (bindingCount) { + m_bindingCount += bindingCount; m_setMask |= 1u << i; + } } } diff --git a/src/dxvk/dxvk_pipelayout.h b/src/dxvk/dxvk_pipelayout.h index 4cfcf50f..1e8aa121 100644 --- a/src/dxvk/dxvk_pipelayout.h +++ b/src/dxvk/dxvk_pipelayout.h @@ -411,6 +411,14 @@ namespace dxvk { return m_layout; } + /** + * \brief Queries total number of bindings + * \returns Binding count in all sets + */ + uint32_t getBindingCount() const { + return m_bindingCount; + } + /** * \brief Queries active descriptor set mask * \returns Bit mask of non-empty descriptor sets @@ -483,6 +491,7 @@ namespace dxvk { VkPipelineLayout m_completeLayout = VK_NULL_HANDLE; VkPipelineLayout m_independentLayout = VK_NULL_HANDLE; + uint32_t m_bindingCount = 0; uint32_t m_setMask = 0; std::array m_bindingObjects = { };