mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-19 05:52:11 +01:00
[dxvk] Use new pipeline layout for barrier tracking and other things
This commit is contained in:
parent
d5e53d3271
commit
9be454fd3e
@ -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;
|
||||
|
||||
|
@ -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<DxvkPipelineLayout> m_layout;
|
||||
|
||||
alignas(CACHE_LINE_SIZE)
|
||||
dxvk::mutex m_mutex;
|
||||
|
@ -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<VK_PIPELINE_BIND_POINT_COMPUTE>(m_state.cp.pipeline->layout());
|
||||
this->updateResourceBindings<VK_PIPELINE_BIND_POINT_COMPUTE>(m_state.cp.pipeline->getBindings());
|
||||
|
||||
this->updateShaderDescriptorSetBinding<VK_PIPELINE_BIND_POINT_COMPUTE>(
|
||||
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<VK_PIPELINE_BIND_POINT_GRAPHICS>(m_state.gp.pipeline->layout());
|
||||
this->updateResourceBindings<VK_PIPELINE_BIND_POINT_GRAPHICS>(m_state.gp.pipeline->getBindings());
|
||||
|
||||
this->updateShaderDescriptorSetBinding<VK_PIPELINE_BIND_POINT_GRAPHICS>(
|
||||
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<DoEmit>(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<DoEmit>(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<DoEmit>(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<DoEmit>(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<DoEmit>(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<DoEmit>(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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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<DxvkPipelineLayout> m_layout;
|
||||
|
||||
uint32_t m_vsIn = 0;
|
||||
uint32_t m_fsOut = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user