Browse Source

[vulkan] Implement push descriptors for compute pipelines (#3666)

Implements push descriptor for compute pipelines along with a bug fix, the increment logic was, offset += sizeof(DescriptorUpdateEntry);
This only advances the byte offset by a single descriptor slot, regardless of the array's size (descriptorCount).Now suppose if a shader utilized an array of descriptors (eg, layout(binding = 0) uniform sampler2D textures[4]) and if this happened to fit within the MaxPushDescriptors limit, the template would consume 4 * sizeof(DescriptorUpdateEntry) bytes, but the offset for the next binding would only advance by 1 slot.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3666
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: wildcard <wildcard@eden-emu.dev>
Co-committed-by: wildcard <wildcard@eden-emu.dev>
pull/3674/head
wildcard 2 days ago
committed by crueter
parent
commit
c682306788
No known key found for this signature in database GPG Key ID: 425ACD2D4830EBC6
  1. 8
      src/video_core/renderer_vulkan/pipeline_helper.h
  2. 24
      src/video_core/renderer_vulkan/vk_compute_pipeline.cpp
  3. 4
      src/video_core/renderer_vulkan/vk_compute_pipeline.h

8
src/video_core/renderer_vulkan/pipeline_helper.h

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@ -61,7 +64,8 @@ public:
.pDescriptorUpdateEntries = entries.data(), .pDescriptorUpdateEntries = entries.data(),
.templateType = type, .templateType = type,
.descriptorSetLayout = descriptor_set_layout, .descriptorSetLayout = descriptor_set_layout,
.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
.pipelineBindPoint =
is_compute ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS,
.pipelineLayout = pipeline_layout, .pipelineLayout = pipeline_layout,
.set = 0, .set = 0,
}); });
@ -122,7 +126,7 @@ private:
}); });
++binding; ++binding;
num_descriptors += descriptors[i].count; num_descriptors += descriptors[i].count;
offset += sizeof(DescriptorUpdateEntry);
offset += sizeof(DescriptorUpdateEntry) * descriptors[i].count;
} }
} }

24
src/video_core/renderer_vulkan/vk_compute_pipeline.cpp

@ -50,11 +50,14 @@ ComputePipeline::ComputePipeline(const Device& device_, vk::PipelineCache& pipel
DescriptorLayoutBuilder builder{device}; DescriptorLayoutBuilder builder{device};
builder.Add(info, VK_SHADER_STAGE_COMPUTE_BIT); builder.Add(info, VK_SHADER_STAGE_COMPUTE_BIT);
descriptor_set_layout = builder.CreateDescriptorSetLayout(false);
uses_push_descriptor = builder.CanUsePushDescriptor();
descriptor_set_layout = builder.CreateDescriptorSetLayout(uses_push_descriptor);
pipeline_layout = builder.CreatePipelineLayout(*descriptor_set_layout); pipeline_layout = builder.CreatePipelineLayout(*descriptor_set_layout);
descriptor_update_template = descriptor_update_template =
builder.CreateTemplate(*descriptor_set_layout, *pipeline_layout, false);
descriptor_allocator = descriptor_pool.Allocator(*descriptor_set_layout, info);
builder.CreateTemplate(*descriptor_set_layout, *pipeline_layout, uses_push_descriptor);
if (!uses_push_descriptor) {
descriptor_allocator = descriptor_pool.Allocator(*descriptor_set_layout, info);
}
const VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT subgroup_size_ci{ const VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT subgroup_size_ci{
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT, .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT,
.pNext = nullptr, .pNext = nullptr,
@ -241,11 +244,16 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute,
RESCALING_LAYOUT_WORDS_OFFSET, sizeof(rescaling_data), RESCALING_LAYOUT_WORDS_OFFSET, sizeof(rescaling_data),
rescaling_data.data()); rescaling_data.data());
} }
const VkDescriptorSet descriptor_set{descriptor_allocator.Commit()};
const vk::Device& dev{device.GetLogical()};
dev.UpdateDescriptorSet(descriptor_set, *descriptor_update_template, descriptor_data);
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline_layout, 0,
descriptor_set, nullptr);
if (uses_push_descriptor) {
cmdbuf.PushDescriptorSetWithTemplateKHR(*descriptor_update_template, *pipeline_layout,
0, descriptor_data);
} else {
const VkDescriptorSet descriptor_set{descriptor_allocator.Commit()};
const vk::Device& dev{device.GetLogical()};
dev.UpdateDescriptorSet(descriptor_set, *descriptor_update_template, descriptor_data);
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline_layout, 0,
descriptor_set, nullptr);
}
}); });
} }

4
src/video_core/renderer_vulkan/vk_compute_pipeline.h

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@ -55,6 +58,7 @@ private:
vk::ShaderModule spv_module; vk::ShaderModule spv_module;
vk::DescriptorSetLayout descriptor_set_layout; vk::DescriptorSetLayout descriptor_set_layout;
bool uses_push_descriptor{false};
DescriptorAllocator descriptor_allocator; DescriptorAllocator descriptor_allocator;
vk::PipelineLayout pipeline_layout; vk::PipelineLayout pipeline_layout;
vk::DescriptorUpdateTemplate descriptor_update_template; vk::DescriptorUpdateTemplate descriptor_update_template;

Loading…
Cancel
Save