From da2cc5a6a03144567af68b07dbc0d3ecf6dc5e52 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 19 Dec 2017 01:08:48 +0100 Subject: [PATCH] [dxvk] Fixed resource binding with invalidated buffers When invalidating a constant buffer, the descriptor was not updated, which usually led to the wrong resource being used and could also cause crashes. This fix also includes resource tracking for shader resources on the graphics pipeline. The code needs to be made compatible with the compute pipeline as well. --- src/dxvk/dxvk_binding.h | 18 ++------ src/dxvk/dxvk_cmdlist.cpp | 6 +-- src/dxvk/dxvk_context.cpp | 86 ++++++++++++++++++++++---------------- src/dxvk/dxvk_pipelayout.h | 10 +++++ 4 files changed, 67 insertions(+), 53 deletions(-) diff --git a/src/dxvk/dxvk_binding.h b/src/dxvk/dxvk_binding.h index ef5ab367..aaacdc33 100644 --- a/src/dxvk/dxvk_binding.h +++ b/src/dxvk/dxvk_binding.h @@ -27,16 +27,7 @@ namespace dxvk { DxvkShaderResourceSlots() { } DxvkShaderResourceSlots(size_t n) { - m_resources .resize(n); - m_descriptors.resize(n); - } - - uint32_t descriptorCount() const { - return m_descriptors.size(); - } - - const DxvkDescriptorInfo* descriptors() const { - return m_descriptors.data(); + m_resources.resize(n); } const DxvkShaderResourceSlot& getShaderResource(uint32_t slot) const { @@ -45,16 +36,13 @@ namespace dxvk { void bindShaderResource( uint32_t slot, - const DxvkShaderResourceSlot& resource, - const DxvkDescriptorInfo& descriptor) { - m_resources .at(slot) = resource; - m_descriptors .at(slot) = descriptor; + const DxvkShaderResourceSlot& resource) { + m_resources.at(slot) = resource; } private: std::vector m_resources; - std::vector m_descriptors; }; diff --git a/src/dxvk/dxvk_cmdlist.cpp b/src/dxvk/dxvk_cmdlist.cpp index cb9b8383..c1447a08 100644 --- a/src/dxvk/dxvk_cmdlist.cpp +++ b/src/dxvk/dxvk_cmdlist.cpp @@ -120,9 +120,9 @@ namespace dxvk { curr.dstArrayElement = 0; curr.descriptorCount = 1; curr.descriptorType = binding.type; - curr.pImageInfo = &descriptorInfos[binding.slot].image; - curr.pBufferInfo = &descriptorInfos[binding.slot].buffer; - curr.pTexelBufferView = &descriptorInfos[binding.slot].texelBuffer; + curr.pImageInfo = &descriptorInfos[i].image; + curr.pBufferInfo = &descriptorInfos[i].buffer; + curr.pTexelBufferView = &descriptorInfos[i].texelBuffer; } m_vkd->vkUpdateDescriptorSets( diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 7972947f..7a5a5e02 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -81,12 +81,7 @@ namespace dxvk { DxvkShaderResourceSlot resource; resource.bufferSlice = buffer; - DxvkDescriptorInfo descriptor; - - if (buffer.handle() != VK_NULL_HANDLE) - descriptor.buffer = buffer.descriptorInfo(); - - rc->bindShaderResource(slot, resource, descriptor); + rc->bindShaderResource(slot, resource); } } @@ -103,12 +98,7 @@ namespace dxvk { DxvkShaderResourceSlot resource; resource.bufferView = bufferView; - DxvkDescriptorInfo descriptor; - - if (bufferView != nullptr) - descriptor.texelBuffer = bufferView->handle(); - - rc->bindShaderResource(slot, resource, descriptor); + rc->bindShaderResource(slot, resource); } } @@ -125,14 +115,7 @@ namespace dxvk { DxvkShaderResourceSlot resource; resource.imageView = image; - DxvkDescriptorInfo descriptor; - - if (image != nullptr) { - descriptor.image.imageView = image->handle(); - descriptor.image.imageLayout = image->imageInfo().layout; - } - - rc->bindShaderResource(slot, resource, descriptor); + rc->bindShaderResource(slot, resource); } } @@ -149,12 +132,7 @@ namespace dxvk { DxvkShaderResourceSlot resource; resource.sampler = sampler; - DxvkDescriptorInfo descriptor; - - if (sampler != nullptr) - descriptor.image.sampler = sampler->handle(); - - rc->bindShaderResource(slot, resource, descriptor); + rc->bindShaderResource(slot, resource); } } @@ -867,13 +845,13 @@ namespace dxvk { // TODO refcount used resources - m_cmd->bindResourceDescriptors( - VK_PIPELINE_BIND_POINT_COMPUTE, - layout->pipelineLayout(), - layout->descriptorSetLayout(), - layout->bindingCount(), - layout->bindings(), - m_cResources.descriptors()); +// m_cmd->bindResourceDescriptors( +// VK_PIPELINE_BIND_POINT_COMPUTE, +// layout->pipelineLayout(), +// layout->descriptorSetLayout(), +// layout->bindingCount(), +// layout->bindings(), +// m_cResources.descriptors()); } } @@ -884,13 +862,51 @@ namespace dxvk { auto layout = m_state.gp.pipeline->layout(); + // TODO recreate resource views if the underlying + // resource was marked as dirty after invalidation + // TODO move this into a separate method so that + // compute can use this code as well + std::vector descriptors; + + for (uint32_t i = 0; i < layout->bindingCount(); i++) { + const uint32_t slot = layout->binding(i).slot; + const auto& res = m_gResources.getShaderResource(slot); + + DxvkDescriptorInfo descriptor; + + if (res.sampler != nullptr) { + m_cmd->trackResource(res.sampler); + descriptor.image.sampler = res.sampler->handle(); + } + + if (res.imageView != nullptr) { + m_cmd->trackResource(res.imageView); + m_cmd->trackResource(res.imageView->image()); + descriptor.image.imageView = res.imageView->handle(); + descriptor.image.imageLayout = res.imageView->imageInfo().layout; + } + + if (res.bufferView != nullptr) { + m_cmd->trackResource(res.bufferView); + m_cmd->trackResource(res.bufferView->buffer()->resource()); + descriptor.texelBuffer = res.bufferView->handle(); + } + + if (res.bufferSlice.handle() != VK_NULL_HANDLE) { + m_cmd->trackResource(res.bufferSlice.buffer()->resource()); + descriptor.buffer = res.bufferSlice.descriptorInfo(); + } + + descriptors.push_back(descriptor); + } + m_cmd->bindResourceDescriptors( VK_PIPELINE_BIND_POINT_GRAPHICS, layout->pipelineLayout(), layout->descriptorSetLayout(), layout->bindingCount(), layout->bindings(), - m_gResources.descriptors()); + descriptors.data()); } } @@ -1073,7 +1089,7 @@ namespace dxvk { m_barriers.recordCommands(m_cmd); } - + DxvkShaderResourceSlots* DxvkContext::getShaderResourceSlots(VkPipelineBindPoint pipe) { switch (pipe) { case VK_PIPELINE_BIND_POINT_GRAPHICS: return &m_gResources; diff --git a/src/dxvk/dxvk_pipelayout.h b/src/dxvk/dxvk_pipelayout.h index 5419df58..273ab64c 100644 --- a/src/dxvk/dxvk_pipelayout.h +++ b/src/dxvk/dxvk_pipelayout.h @@ -108,6 +108,16 @@ namespace dxvk { return m_bindingSlots.size(); } + /** + * \brief Resource binding info + * + * \param [in] id Binding index + * \returns Resource binding info + */ + const DxvkDescriptorSlot& binding(uint32_t id) const { + return m_bindingSlots.at(id); + } + /** * \brief Resource binding info * \returns Resource binding info