From 9be454fd3e3bd11e4cbe37100e15a7435cee59be Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 15 Jun 2022 20:01:17 +0200 Subject: [PATCH] [dxvk] Use new pipeline layout for barrier tracking and other things --- src/dxvk/dxvk_compute.cpp | 21 +- src/dxvk/dxvk_compute.h | 5 +- src/dxvk/dxvk_context.cpp | 373 +++++++++++++++++----------------- src/dxvk/dxvk_context_state.h | 2 - src/dxvk/dxvk_graphics.cpp | 31 ++- src/dxvk/dxvk_graphics.h | 5 +- 6 files changed, 207 insertions(+), 230 deletions(-) diff --git a/src/dxvk/dxvk_compute.cpp b/src/dxvk/dxvk_compute.cpp index 7dba4f99a..9adb7d953 100644 --- a/src/dxvk/dxvk_compute.cpp +++ b/src/dxvk/dxvk_compute.cpp @@ -16,14 +16,7 @@ namespace dxvk { DxvkBindingLayoutObjects* layout) : m_vkd(pipeMgr->m_device->vkd()), m_pipeMgr(pipeMgr), m_shaders(std::move(shaders)), m_bindings(layout) { - m_shaders.cs->defineResourceSlots(m_slotMapping); - m_slotMapping.makeDescriptorsDynamic( - m_pipeMgr->m_device->options().maxNumDynamicUniformBuffers, - m_pipeMgr->m_device->options().maxNumDynamicStorageBuffers); - - m_layout = new DxvkPipelineLayout(m_vkd, - m_slotMapping, VK_PIPELINE_BIND_POINT_COMPUTE); } @@ -90,8 +83,14 @@ namespace dxvk { } DxvkSpecConstants specData; - for (uint32_t i = 0; i < m_layout->bindingCount(); i++) - specData.set(i, state.bsBindingMask.test(i), true); + uint32_t bindingIndex = 0; + + for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount; i++) { + for (uint32_t j = 0; j < m_bindings->layout().getBindingCount(i); j++) { + specData.set(bindingIndex, state.bsBindingMask.test(bindingIndex), true); + bindingIndex += 1; + } + } for (uint32_t i = 0; i < MaxNumSpecConstants; i++) specData.set(getSpecId(i), state.sc.specConstants[i], 0u); @@ -101,14 +100,14 @@ namespace dxvk { DxvkShaderModuleCreateInfo moduleInfo; moduleInfo.fsDualSrcBlend = false; - auto csm = m_shaders.cs->createShaderModule(m_vkd, m_slotMapping, moduleInfo); + auto csm = m_shaders.cs->createShaderModule(m_vkd, m_bindings, moduleInfo); VkComputePipelineCreateInfo info; info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; info.pNext = nullptr; info.flags = 0; info.stage = csm.stageInfo(&specInfo); - info.layout = m_layout->pipelineLayout(); + info.layout = m_bindings->getPipelineLayout(); info.basePipelineHandle = VK_NULL_HANDLE; info.basePipelineIndex = -1; diff --git a/src/dxvk/dxvk_compute.h b/src/dxvk/dxvk_compute.h index 74fd778e5..135b9616c 100644 --- a/src/dxvk/dxvk_compute.h +++ b/src/dxvk/dxvk_compute.h @@ -113,7 +113,7 @@ namespace dxvk { * \returns Pipeline layout */ DxvkPipelineLayout* layout() const { - return m_layout.ptr(); + return nullptr; } /** @@ -153,10 +153,7 @@ namespace dxvk { DxvkPipelineManager* m_pipeMgr; DxvkComputePipelineShaders m_shaders; - DxvkDescriptorSlotMapping m_slotMapping; - DxvkBindingLayoutObjects* m_bindings; - Rc m_layout; alignas(CACHE_LINE_SIZE) dxvk::mutex m_mutex; diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 7f2464082..d01add70e 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -158,15 +158,9 @@ namespace dxvk { else needsUpdate = m_rc[slot].bufferSlice.length() != buffer.length(); - if (likely(needsUpdate)) { - m_flags.set( - DxvkContextFlag::CpDirtyResources, - DxvkContextFlag::GpDirtyResources); - } else { - m_flags.set( - DxvkContextFlag::CpDirtyDescriptorBinding, - DxvkContextFlag::GpDirtyDescriptorBinding); - } + m_flags.set( + DxvkContextFlag::CpDirtyResources, + DxvkContextFlag::GpDirtyResources); m_rc[slot].bufferSlice = buffer; } @@ -1759,25 +1753,21 @@ namespace dxvk { ~(VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT); - if (usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) { - m_flags.set(prevSlice.handle == slice.handle - ? DxvkContextFlags(DxvkContextFlag::GpDirtyDescriptorBinding, - DxvkContextFlag::CpDirtyDescriptorBinding) - : DxvkContextFlags(DxvkContextFlag::GpDirtyResources, - DxvkContextFlag::CpDirtyResources)); - } + VkBufferUsageFlags resourceMask = + VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | + VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | + VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | + VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT; - // Fast early-out for uniform buffers, very common - if (likely(usage == VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)) - return; - - if (usage & (VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT - | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT - | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)) { + if (usage & resourceMask) { m_flags.set(DxvkContextFlag::GpDirtyResources, DxvkContextFlag::CpDirtyResources); } + // Fast early-out for resource buffers, very common + if (likely(!(usage & ~resourceMask))) + return; + if (usage & VK_BUFFER_USAGE_INDEX_BUFFER_BIT) m_flags.set(DxvkContextFlag::GpDirtyIndexBuffer); @@ -4037,7 +4027,7 @@ namespace dxvk { if (unlikely(m_state.cp.pipeline == nullptr)) return false; - if (m_state.cp.pipeline->layout()->pushConstRange().size) + if (m_state.cp.pipeline->getBindings()->layout().getPushConstantRange().size) m_flags.set(DxvkContextFlag::DirtyPushConstants); m_flags.clr(DxvkContextFlag::CpDirtyPipeline); @@ -4101,7 +4091,7 @@ namespace dxvk { this->spillRenderPass(true); } - if (m_state.gp.pipeline->layout()->pushConstRange().size) + if (m_state.gp.pipeline->getBindings()->layout().getPushConstantRange().size) m_flags.set(DxvkContextFlag::DirtyPushConstants); m_flags.clr(DxvkContextFlag::GpDirtyPipeline); @@ -4325,8 +4315,10 @@ namespace dxvk { // Create and populate descriptor set with the given descriptors sets[i] = allocateDescriptorSet(layout->getSetLayout(i)); - m_cmd->updateDescriptorSetWithTemplate(sets[i], - layout->getSetUpdateTemplate(i), descriptors.data()); + if (bindingCount) { + m_cmd->updateDescriptorSetWithTemplate(sets[i], + layout->getSetUpdateTemplate(i), descriptors.data()); + } bindingIndex += bindingCount; } @@ -4349,28 +4341,16 @@ namespace dxvk { void DxvkContext::updateComputeShaderResources() { - if ((m_flags.test(DxvkContextFlag::CpDirtyResources)) - || (m_state.cp.pipeline->layout()->hasStaticBufferBindings())) - this->updateShaderResources(m_state.cp.pipeline->layout()); + this->updateResourceBindings(m_state.cp.pipeline->getBindings()); - this->updateShaderDescriptorSetBinding( - m_cpSet, m_state.cp.pipeline->layout()); - - m_flags.clr(DxvkContextFlag::CpDirtyResources, - DxvkContextFlag::CpDirtyDescriptorBinding); + m_flags.clr(DxvkContextFlag::CpDirtyResources); } void DxvkContext::updateGraphicsShaderResources() { - if ((m_flags.test(DxvkContextFlag::GpDirtyResources)) - || (m_state.gp.pipeline->layout()->hasStaticBufferBindings())) - this->updateShaderResources(m_state.gp.pipeline->layout()); + this->updateResourceBindings(m_state.gp.pipeline->getBindings()); - this->updateShaderDescriptorSetBinding( - m_gpSet, m_state.gp.pipeline->layout()); - - m_flags.clr(DxvkContextFlag::GpDirtyResources, - DxvkContextFlag::GpDirtyDescriptorBinding); + m_flags.clr(DxvkContextFlag::GpDirtyResources); } @@ -4942,19 +4922,17 @@ namespace dxvk { void DxvkContext::updatePushConstants() { m_flags.clr(DxvkContextFlag::DirtyPushConstants); - auto layout = BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS - ? m_state.gp.pipeline->layout() - : m_state.cp.pipeline->layout(); + auto bindings = BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS + ? m_state.gp.pipeline->getBindings() + : m_state.cp.pipeline->getBindings(); - if (!layout) - return; - - VkPushConstantRange pushConstRange = layout->pushConstRange(); + VkPushConstantRange pushConstRange = bindings->layout().getPushConstantRange(); + if (!pushConstRange.size) return; m_cmd->cmdPushConstants( - layout->pipelineLayout(), + bindings->getPipelineLayout(), pushConstRange.stageFlags, pushConstRange.offset, pushConstRange.size, @@ -4970,9 +4948,7 @@ namespace dxvk { return false; } - if (m_flags.any( - DxvkContextFlag::CpDirtyResources, - DxvkContextFlag::CpDirtyDescriptorBinding)) + if (m_flags.test(DxvkContextFlag::CpDirtyResources)) this->updateComputeShaderResources(); if (m_flags.test(DxvkContextFlag::CpDirtyPipelineState)) { @@ -5014,9 +4990,7 @@ namespace dxvk { if (m_flags.test(DxvkContextFlag::GpDirtyVertexBuffers)) this->updateVertexBufferBindings(); - if (m_flags.any( - DxvkContextFlag::GpDirtyResources, - DxvkContextFlag::GpDirtyDescriptorBinding)) + if (m_flags.test(DxvkContextFlag::GpDirtyResources)) this->updateGraphicsShaderResources(); if (m_flags.test(DxvkContextFlag::GpDirtyPipelineState)) { @@ -5046,58 +5020,66 @@ namespace dxvk { void DxvkContext::commitComputeInitBarriers() { - auto layout = m_state.cp.pipeline->layout(); + const auto& layout = m_state.cp.pipeline->getBindings()->layout(); bool requiresBarrier = false; - for (uint32_t i = 0; i < layout->bindingCount() && !requiresBarrier; i++) { - if (m_state.cp.state.bsBindingMask.test(i)) { - const DxvkDescriptorSlot binding = layout->binding(i); - const DxvkShaderResourceSlot& slot = m_rc[binding.slot]; + uint32_t index = 0; - DxvkAccessFlags dstAccess = DxvkBarrierSet::getAccessTypes(binding.access); - DxvkAccessFlags srcAccess = 0; - - switch (binding.type) { - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: - srcAccess = m_execBarriers.getBufferAccess( - slot.bufferSlice.getSliceHandle()); - break; - - case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: - srcAccess = m_execBarriers.getBufferAccess( - slot.bufferView->getSliceHandle()); - break; + for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount && !requiresBarrier; i++) { + uint32_t bindingCount = layout.getBindingCount(i); + + for (uint32_t j = 0; j < bindingCount && !requiresBarrier; j++) { + if (m_state.cp.state.bsBindingMask.test(index + j)) { + const DxvkBindingInfo& binding = layout.getBinding(i, j); + const DxvkShaderResourceSlot& slot = m_rc[binding.resourceBinding]; + + DxvkAccessFlags dstAccess = DxvkBarrierSet::getAccessTypes(binding.access); + DxvkAccessFlags srcAccess = 0; - case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: - case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: - case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: - srcAccess = m_execBarriers.getImageAccess( - slot.imageView->image(), - slot.imageView->imageSubresources()); - break; + switch (binding.descriptorType) { + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: + srcAccess = m_execBarriers.getBufferAccess( + slot.bufferSlice.getSliceHandle()); + break; + + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + srcAccess = m_execBarriers.getBufferAccess( + slot.bufferView->getSliceHandle()); + break; + + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: + srcAccess = m_execBarriers.getImageAccess( + slot.imageView->image(), + slot.imageView->imageSubresources()); + break; - default: - /* nothing to do */; + default: + /* nothing to do */; + } + + if (srcAccess == 0) + continue; + + // Skip write-after-write barriers if explicitly requested + VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT + | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT; + + if ((m_barrierControl.test(DxvkBarrierControl::IgnoreWriteAfterWrite)) + && (!(m_execBarriers.getSrcStages() & ~stageMask)) + && ((srcAccess | dstAccess) == DxvkAccess::Write)) + continue; + + requiresBarrier = (srcAccess | dstAccess).test(DxvkAccess::Write); } - - if (srcAccess == 0) - continue; - - // Skip write-after-write barriers if explicitly requested - VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT - | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT; - - if ((m_barrierControl.test(DxvkBarrierControl::IgnoreWriteAfterWrite)) - && (!(m_execBarriers.getSrcStages() & ~stageMask)) - && ((srcAccess | dstAccess) == DxvkAccess::Write)) - continue; - - requiresBarrier = (srcAccess | dstAccess).test(DxvkAccess::Write); } + + index += bindingCount; } if (requiresBarrier) @@ -5106,53 +5088,60 @@ namespace dxvk { void DxvkContext::commitComputePostBarriers() { - auto layout = m_state.cp.pipeline->layout(); - - for (uint32_t i = 0; i < layout->bindingCount(); i++) { - if (m_state.cp.state.bsBindingMask.test(i)) { - const DxvkDescriptorSlot binding = layout->binding(i); - const DxvkShaderResourceSlot& slot = m_rc[binding.slot]; + const auto& layout = m_state.cp.pipeline->getBindings()->layout(); + uint32_t index = 0; - VkPipelineStageFlags stages = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; - VkAccessFlags access = binding.access; - - switch (binding.type) { - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: - m_execBarriers.accessBuffer( - slot.bufferSlice.getSliceHandle(), - stages, access, - slot.bufferSlice.bufferInfo().stages, - slot.bufferSlice.bufferInfo().access); - break; - - case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: - m_execBarriers.accessBuffer( - slot.bufferView->getSliceHandle(), - stages, access, - slot.bufferView->bufferInfo().stages, - slot.bufferView->bufferInfo().access); - break; + for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount; i++) { + uint32_t bindingCount = layout.getBindingCount(i); + + for (uint32_t j = 0; j < bindingCount; j++) { + if (m_state.cp.state.bsBindingMask.test(index + j)) { + const DxvkBindingInfo& binding = layout.getBinding(i, j); + const DxvkShaderResourceSlot& slot = m_rc[binding.resourceBinding]; + + VkPipelineStageFlags stages = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + VkAccessFlags access = binding.access; - case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: - case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: - case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: - m_execBarriers.accessImage( - slot.imageView->image(), - slot.imageView->imageSubresources(), - slot.imageView->imageInfo().layout, - stages, access, - slot.imageView->imageInfo().layout, - slot.imageView->imageInfo().stages, - slot.imageView->imageInfo().access); - break; + switch (binding.descriptorType) { + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: + m_execBarriers.accessBuffer( + slot.bufferSlice.getSliceHandle(), + stages, access, + slot.bufferSlice.bufferInfo().stages, + slot.bufferSlice.bufferInfo().access); + break; + + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + m_execBarriers.accessBuffer( + slot.bufferView->getSliceHandle(), + stages, access, + slot.bufferView->bufferInfo().stages, + slot.bufferView->bufferInfo().access); + break; + + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: + m_execBarriers.accessImage( + slot.imageView->image(), + slot.imageView->imageSubresources(), + slot.imageView->imageInfo().layout, + stages, access, + slot.imageView->imageInfo().layout, + slot.imageView->imageInfo().stages, + slot.imageView->imageInfo().access); + break; - default: - /* nothing to do */; + default: + /* nothing to do */; + } } } + + index += bindingCount; } } @@ -5162,8 +5151,6 @@ namespace dxvk { if (m_barrierControl.test(DxvkBarrierControl::IgnoreGraphicsBarriers)) return; - auto layout = m_state.gp.pipeline->layout(); - constexpr auto storageBufferAccess = VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT; constexpr auto storageImageAccess = VK_ACCESS_SHADER_WRITE_BIT; @@ -5241,56 +5228,62 @@ namespace dxvk { } // Check shader resources on every draw to handle WAW hazards - for (uint32_t i = 0; i < layout->bindingCount() && !requiresBarrier; i++) { - const DxvkDescriptorSlot binding = layout->binding(i); - const DxvkShaderResourceSlot& slot = m_rc[binding.slot]; + auto layout = m_state.gp.pipeline->getBindings()->layout(); - DxvkAccessFlags dstAccess = DxvkBarrierSet::getAccessTypes(binding.access); - DxvkAccessFlags srcAccess = 0; - - switch (binding.type) { - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: - if ((slot.bufferSlice.defined()) - && (slot.bufferSlice.bufferInfo().access & storageBufferAccess)) { - srcAccess = this->checkGfxBufferBarrier(slot.bufferSlice, - util::pipelineStages(binding.stages), binding.access); - } - break; + for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount; i++) { + uint32_t bindingCount = layout.getBindingCount(i); - case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: - if ((slot.bufferView != nullptr) - && (slot.bufferView->bufferInfo().access & storageBufferAccess)) { - srcAccess = this->checkGfxBufferBarrier(slot.bufferView->slice(), - util::pipelineStages(binding.stages), binding.access); - } - break; + for (uint32_t j = 0; j < bindingCount && !requiresBarrier; j++) { + const DxvkBindingInfo& binding = layout.getBinding(i, j); + const DxvkShaderResourceSlot& slot = m_rc[binding.resourceBinding]; - case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: - case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: - case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: - if ((slot.imageView != nullptr) - && (slot.imageView->imageInfo().access & storageImageAccess)) { - srcAccess = this->checkGfxImageBarrier(slot.imageView, - util::pipelineStages(binding.stages), binding.access); - } - break; + DxvkAccessFlags dstAccess = DxvkBarrierSet::getAccessTypes(binding.access); + DxvkAccessFlags srcAccess = 0; + + switch (binding.descriptorType) { + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: + if ((slot.bufferSlice.defined()) + && (slot.bufferSlice.bufferInfo().access & storageBufferAccess)) { + srcAccess = this->checkGfxBufferBarrier(slot.bufferSlice, + util::pipelineStages(binding.stages), binding.access); + } + break; - default: - /* nothing to do */; + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + if ((slot.bufferView != nullptr) + && (slot.bufferView->bufferInfo().access & storageBufferAccess)) { + srcAccess = this->checkGfxBufferBarrier(slot.bufferView->slice(), + util::pipelineStages(binding.stages), binding.access); + } + break; + + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: + if ((slot.imageView != nullptr) + && (slot.imageView->imageInfo().access & storageImageAccess)) { + srcAccess = this->checkGfxImageBarrier(slot.imageView, + util::pipelineStages(binding.stages), binding.access); + } + break; + + default: + /* nothing to do */; + } + + if (srcAccess == 0) + continue; + + // Skip write-after-write barriers if explicitly requested + if ((m_barrierControl.test(DxvkBarrierControl::IgnoreWriteAfterWrite)) + && ((srcAccess | dstAccess) == DxvkAccess::Write)) + continue; + + requiresBarrier = (srcAccess | dstAccess).test(DxvkAccess::Write); } - - if (srcAccess == 0) - continue; - - // Skip write-after-write barriers if explicitly requested - if ((m_barrierControl.test(DxvkBarrierControl::IgnoreWriteAfterWrite)) - && ((srcAccess | dstAccess) == DxvkAccess::Write)) - continue; - - requiresBarrier = (srcAccess | dstAccess).test(DxvkAccess::Write); } // External subpass dependencies serve as full memory diff --git a/src/dxvk/dxvk_context_state.h b/src/dxvk/dxvk_context_state.h index 27a6de587..b8bb46b8b 100644 --- a/src/dxvk/dxvk_context_state.h +++ b/src/dxvk/dxvk_context_state.h @@ -28,7 +28,6 @@ namespace dxvk { GpDirtyPipeline, ///< Graphics pipeline binding is out of date GpDirtyPipelineState, ///< Graphics pipeline needs to be recompiled GpDirtyResources, ///< Graphics pipeline resource bindings are out of date - GpDirtyDescriptorBinding, ///< Graphics descriptor set needs to be rebound GpDirtyVertexBuffers, ///< Vertex buffer bindings are out of date GpDirtyIndexBuffer, ///< Index buffer binding are out of date GpDirtyXfbBuffers, ///< Transform feedback buffer bindings are out of date @@ -45,7 +44,6 @@ namespace dxvk { CpDirtyPipeline, ///< Compute pipeline binding are out of date CpDirtyPipelineState, ///< Compute pipeline needs to be recompiled CpDirtyResources, ///< Compute pipeline resource bindings are out of date - CpDirtyDescriptorBinding, ///< Compute descriptor set needs to be rebound DirtyDrawBuffer, ///< Indirect argument buffer is dirty DirtyPushConstants, ///< Push constant data has changed diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 1b1b9f7df..b369a9e16 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -14,26 +14,13 @@ namespace dxvk { DxvkBindingLayoutObjects* layout) : m_vkd(pipeMgr->m_device->vkd()), m_pipeMgr(pipeMgr), m_shaders(std::move(shaders)), m_bindings(layout) { - if (m_shaders.vs != nullptr) m_shaders.vs ->defineResourceSlots(m_slotMapping); - if (m_shaders.tcs != nullptr) m_shaders.tcs->defineResourceSlots(m_slotMapping); - if (m_shaders.tes != nullptr) m_shaders.tes->defineResourceSlots(m_slotMapping); - if (m_shaders.gs != nullptr) m_shaders.gs ->defineResourceSlots(m_slotMapping); - if (m_shaders.fs != nullptr) m_shaders.fs ->defineResourceSlots(m_slotMapping); - - m_slotMapping.makeDescriptorsDynamic( - pipeMgr->m_device->options().maxNumDynamicUniformBuffers, - pipeMgr->m_device->options().maxNumDynamicStorageBuffers); - - m_layout = new DxvkPipelineLayout(m_vkd, - m_slotMapping, VK_PIPELINE_BIND_POINT_GRAPHICS); - m_vsIn = m_shaders.vs != nullptr ? m_shaders.vs->info().inputMask : 0; m_fsOut = m_shaders.fs != nullptr ? m_shaders.fs->info().outputMask : 0; if (m_shaders.gs != nullptr && m_shaders.gs->flags().test(DxvkShaderFlag::HasTransformFeedback)) m_flags.set(DxvkGraphicsPipelineFlag::HasTransformFeedback); - if (m_layout->getStorageDescriptorStages()) + if (layout->getAccessFlags() & VK_ACCESS_SHADER_WRITE_BIT) m_flags.set(DxvkGraphicsPipelineFlag::HasStorageDescriptors); m_common.msSampleShadingEnable = m_shaders.fs != nullptr && m_shaders.fs->flags().test(DxvkShaderFlag::HasSampleRateShading); @@ -166,9 +153,15 @@ namespace dxvk { // Set up some specialization constants DxvkSpecConstants specData; specData.set(uint32_t(DxvkSpecConstantId::RasterizerSampleCount), sampleCount, VK_SAMPLE_COUNT_1_BIT); - - for (uint32_t i = 0; i < m_layout->bindingCount(); i++) - specData.set(i, state.bsBindingMask.test(i), true); + + uint32_t bindingIndex = 0; + + for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount; i++) { + for (uint32_t j = 0; j < m_bindings->layout().getBindingCount(i); j++) { + specData.set(bindingIndex, state.bsBindingMask.test(bindingIndex), true); + bindingIndex += 1; + } + } for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { if ((m_fsOut & (1 << i)) != 0) { @@ -408,7 +401,7 @@ namespace dxvk { info.pDepthStencilState = &dsInfo; info.pColorBlendState = &cbInfo; info.pDynamicState = &dyInfo; - info.layout = m_layout->pipelineLayout(); + info.layout = m_bindings->getPipelineLayout(); info.renderPass = renderPass->getDefaultHandle(); info.subpass = 0; info.basePipelineHandle = VK_NULL_HANDLE; @@ -481,7 +474,7 @@ namespace dxvk { } info.undefinedInputs = (providedInputs & consumedInputs) ^ consumedInputs; - return shader->createShaderModule(m_vkd, m_slotMapping, info); + return shader->createShaderModule(m_vkd, m_bindings, info); } diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 1136a06d8..ed76b915d 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -179,7 +179,7 @@ namespace dxvk { * \returns Pipeline layout */ DxvkPipelineLayout* layout() const { - return m_layout.ptr(); + return nullptr; } /** @@ -236,10 +236,7 @@ namespace dxvk { DxvkPipelineManager* m_pipeMgr; DxvkGraphicsPipelineShaders m_shaders; - DxvkDescriptorSlotMapping m_slotMapping; - DxvkBindingLayoutObjects* m_bindings; - Rc m_layout; uint32_t m_vsIn = 0; uint32_t m_fsOut = 0;