1
0
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:
Philip Rebohle 2022-06-15 20:01:17 +02:00
parent d5e53d3271
commit 9be454fd3e
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
6 changed files with 207 additions and 230 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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;