mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-04-30 15:18:58 +02:00
[vulkan] Implenting layouts use for indexing descriptors
This commit is contained in:
parent
6190fcaaef
commit
2bac9cec32
7 changed files with 120 additions and 21 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||||
|
|
|
||||||
|
|
@ -30,23 +30,58 @@ public:
|
||||||
return device->IsKhrPushDescriptorSupported() &&
|
return device->IsKhrPushDescriptorSupported() &&
|
||||||
num_descriptors <= device->MaxPushDescriptors();
|
num_descriptors <= device->MaxPushDescriptors();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(crueter): utilize layout binding flags
|
|
||||||
vk::DescriptorSetLayout CreateDescriptorSetLayout(bool use_push_descriptor) const {
|
vk::DescriptorSetLayout CreateDescriptorSetLayout(bool use_push_descriptor) const {
|
||||||
if (bindings.empty()) {
|
if (bindings.empty()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variable_descriptor_count = 0;
|
||||||
|
binding_flags.clear();
|
||||||
|
|
||||||
|
VkDescriptorSetLayoutBindingFlagsCreateInfo binding_flags_ci{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
|
||||||
|
.pNext = nullptr,
|
||||||
|
.bindingCount = 0,
|
||||||
|
.pBindingFlags = nullptr,
|
||||||
|
};
|
||||||
|
|
||||||
|
const bool use_descriptor_indexing =
|
||||||
|
!use_push_descriptor && device->isExtDescriptorIndexingSupported();
|
||||||
|
const void* layout_next = nullptr;
|
||||||
|
if (use_descriptor_indexing) {
|
||||||
|
binding_flags.assign(bindings.size(), 0);
|
||||||
|
for (size_t i = 0; i < bindings.size(); ++i) {
|
||||||
|
if (bindings[i].descriptorCount > 1) {
|
||||||
|
binding_flags[i] |= VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bindings.back().descriptorCount > 1) {
|
||||||
|
binding_flags.back() |= VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT;
|
||||||
|
variable_descriptor_count = bindings.back().descriptorCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
binding_flags_ci.bindingCount = static_cast<u32>(binding_flags.size());
|
||||||
|
binding_flags_ci.pBindingFlags = binding_flags.data();
|
||||||
|
layout_next = &binding_flags_ci;
|
||||||
|
}
|
||||||
|
|
||||||
const VkDescriptorSetLayoutCreateFlags flags =
|
const VkDescriptorSetLayoutCreateFlags flags =
|
||||||
use_push_descriptor ? VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR : 0;
|
use_push_descriptor ? VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR : 0;
|
||||||
return device->GetLogical().CreateDescriptorSetLayout({
|
return device->GetLogical().CreateDescriptorSetLayout({
|
||||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
||||||
.pNext = nullptr,
|
.pNext = layout_next,
|
||||||
.flags = flags,
|
.flags = flags,
|
||||||
.bindingCount = static_cast<u32>(bindings.size()),
|
.bindingCount = static_cast<u32>(bindings.size()),
|
||||||
.pBindings = bindings.data(),
|
.pBindings = bindings.data(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 VariableDescriptorCount() const noexcept {
|
||||||
|
return variable_descriptor_count;
|
||||||
|
}
|
||||||
|
|
||||||
vk::DescriptorUpdateTemplate CreateTemplate(VkDescriptorSetLayout descriptor_set_layout,
|
vk::DescriptorUpdateTemplate CreateTemplate(VkDescriptorSetLayout descriptor_set_layout,
|
||||||
VkPipelineLayout pipeline_layout,
|
VkPipelineLayout pipeline_layout,
|
||||||
bool use_push_descriptor) const {
|
bool use_push_descriptor) const {
|
||||||
|
|
@ -134,8 +169,10 @@ private:
|
||||||
bool is_compute{};
|
bool is_compute{};
|
||||||
boost::container::small_vector<VkDescriptorSetLayoutBinding, 32> bindings;
|
boost::container::small_vector<VkDescriptorSetLayoutBinding, 32> bindings;
|
||||||
boost::container::small_vector<VkDescriptorUpdateTemplateEntry, 32> entries;
|
boost::container::small_vector<VkDescriptorUpdateTemplateEntry, 32> entries;
|
||||||
|
mutable boost::container::small_vector<VkDescriptorBindingFlags, 32> binding_flags;
|
||||||
u32 binding{};
|
u32 binding{};
|
||||||
u32 num_descriptors{};
|
u32 num_descriptors{};
|
||||||
|
mutable u32 variable_descriptor_count{};
|
||||||
size_t offset{};
|
size_t offset{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "video_core/renderer_vulkan/vk_texture_cache.h"
|
#include "video_core/renderer_vulkan/vk_texture_cache.h"
|
||||||
|
|
||||||
|
|
@ -237,9 +238,36 @@ ComputePass::ComputePass(const Device& device_, DescriptorPool& descriptor_pool,
|
||||||
vk::Span<VkPushConstantRange> push_constants, std::span<const u32> code,
|
vk::Span<VkPushConstantRange> push_constants, std::span<const u32> code,
|
||||||
std::optional<u32> optional_subgroup_size)
|
std::optional<u32> optional_subgroup_size)
|
||||||
: device{device_} {
|
: device{device_} {
|
||||||
|
u32 variable_descriptor_count{};
|
||||||
|
std::vector<VkDescriptorBindingFlags> binding_flags;
|
||||||
|
VkDescriptorSetLayoutBindingFlagsCreateInfo binding_flags_ci{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
|
||||||
|
.pNext = nullptr,
|
||||||
|
.bindingCount = 0,
|
||||||
|
.pBindingFlags = nullptr,
|
||||||
|
};
|
||||||
|
const bool use_descriptor_indexing = device.isExtDescriptorIndexingSupported();
|
||||||
|
const void* layout_next = nullptr;
|
||||||
|
if (use_descriptor_indexing && !bindings.empty()) {
|
||||||
|
binding_flags.assign(bindings.size(), 0);
|
||||||
|
for (size_t i = 0; i < bindings.size(); ++i) {
|
||||||
|
if (bindings[i].descriptorCount > 1) {
|
||||||
|
binding_flags[i] |= VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bindings.back().descriptorCount > 1) {
|
||||||
|
binding_flags.back() |= VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT;
|
||||||
|
variable_descriptor_count = bindings.back().descriptorCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
binding_flags_ci.bindingCount = static_cast<u32>(binding_flags.size());
|
||||||
|
binding_flags_ci.pBindingFlags = binding_flags.data();
|
||||||
|
layout_next = &binding_flags_ci;
|
||||||
|
}
|
||||||
|
|
||||||
descriptor_set_layout = device.GetLogical().CreateDescriptorSetLayout({
|
descriptor_set_layout = device.GetLogical().CreateDescriptorSetLayout({
|
||||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
||||||
.pNext = nullptr,
|
.pNext = layout_next,
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
.bindingCount = bindings.size(),
|
.bindingCount = bindings.size(),
|
||||||
.pBindings = bindings.data(),
|
.pBindings = bindings.data(),
|
||||||
|
|
@ -266,7 +294,8 @@ ComputePass::ComputePass(const Device& device_, DescriptorPool& descriptor_pool,
|
||||||
.pipelineLayout = *layout,
|
.pipelineLayout = *layout,
|
||||||
.set = 0,
|
.set = 0,
|
||||||
});
|
});
|
||||||
descriptor_allocator = descriptor_pool.Allocator(*descriptor_set_layout, bank_info);
|
descriptor_allocator =
|
||||||
|
descriptor_pool.Allocator(*descriptor_set_layout, bank_info, variable_descriptor_count);
|
||||||
}
|
}
|
||||||
if (code.empty()) {
|
if (code.empty()) {
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
||||||
|
|
@ -88,9 +88,10 @@ static void AllocatePool(const Device& device, DescriptorBank& bank) {
|
||||||
}
|
}
|
||||||
|
|
||||||
DescriptorAllocator::DescriptorAllocator(const Device& device_, MasterSemaphore& master_semaphore_,
|
DescriptorAllocator::DescriptorAllocator(const Device& device_, MasterSemaphore& master_semaphore_,
|
||||||
DescriptorBank& bank_, VkDescriptorSetLayout layout_)
|
DescriptorBank& bank_, VkDescriptorSetLayout layout_,
|
||||||
|
u32 variable_descriptor_count_)
|
||||||
: ResourcePool(master_semaphore_, SETS_GROW_RATE), device{&device_}, bank{&bank_},
|
: ResourcePool(master_semaphore_, SETS_GROW_RATE), device{&device_}, bank{&bank_},
|
||||||
layout{layout_} {}
|
layout{layout_}, variable_descriptor_count{variable_descriptor_count_} {}
|
||||||
|
|
||||||
VkDescriptorSet DescriptorAllocator::Commit() {
|
VkDescriptorSet DescriptorAllocator::Commit() {
|
||||||
const size_t index = CommitResource();
|
const size_t index = CommitResource();
|
||||||
|
|
@ -103,9 +104,25 @@ void DescriptorAllocator::Allocate(size_t begin, size_t end) {
|
||||||
|
|
||||||
vk::DescriptorSets DescriptorAllocator::AllocateDescriptors(size_t count) {
|
vk::DescriptorSets DescriptorAllocator::AllocateDescriptors(size_t count) {
|
||||||
const std::vector<VkDescriptorSetLayout> layouts(count, layout);
|
const std::vector<VkDescriptorSetLayout> layouts(count, layout);
|
||||||
|
|
||||||
|
std::vector<u32> variable_descriptor_counts;
|
||||||
|
VkDescriptorSetVariableDescriptorCountAllocateInfo variable_descriptor_count_info{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO,
|
||||||
|
.pNext = nullptr,
|
||||||
|
.descriptorSetCount = 0,
|
||||||
|
.pDescriptorCounts = nullptr,
|
||||||
|
};
|
||||||
|
const void* allocate_next = nullptr;
|
||||||
|
if (variable_descriptor_count != 0) {
|
||||||
|
variable_descriptor_counts.assign(count, variable_descriptor_count);
|
||||||
|
variable_descriptor_count_info.descriptorSetCount = static_cast<u32>(count);
|
||||||
|
variable_descriptor_count_info.pDescriptorCounts = variable_descriptor_counts.data();
|
||||||
|
allocate_next = &variable_descriptor_count_info;
|
||||||
|
}
|
||||||
|
|
||||||
VkDescriptorSetAllocateInfo allocate_info{
|
VkDescriptorSetAllocateInfo allocate_info{
|
||||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
||||||
.pNext = nullptr,
|
.pNext = allocate_next,
|
||||||
.descriptorPool = *bank->pools.back(),
|
.descriptorPool = *bank->pools.back(),
|
||||||
.descriptorSetCount = static_cast<u32>(count),
|
.descriptorSetCount = static_cast<u32>(count),
|
||||||
.pSetLayouts = layouts.data(),
|
.pSetLayouts = layouts.data(),
|
||||||
|
|
@ -131,18 +148,22 @@ DescriptorPool::DescriptorPool(const Device& device_, Scheduler& scheduler)
|
||||||
DescriptorPool::~DescriptorPool() = default;
|
DescriptorPool::~DescriptorPool() = default;
|
||||||
|
|
||||||
DescriptorAllocator DescriptorPool::Allocator(VkDescriptorSetLayout layout,
|
DescriptorAllocator DescriptorPool::Allocator(VkDescriptorSetLayout layout,
|
||||||
std::span<const Shader::Info> infos) {
|
std::span<const Shader::Info> infos,
|
||||||
return Allocator(layout, MakeBankInfo(infos));
|
u32 variable_descriptor_count) {
|
||||||
|
return Allocator(layout, MakeBankInfo(infos), variable_descriptor_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
DescriptorAllocator DescriptorPool::Allocator(VkDescriptorSetLayout layout,
|
DescriptorAllocator DescriptorPool::Allocator(VkDescriptorSetLayout layout,
|
||||||
const Shader::Info& info) {
|
const Shader::Info& info,
|
||||||
return Allocator(layout, MakeBankInfo(std::array{info}));
|
u32 variable_descriptor_count) {
|
||||||
|
return Allocator(layout, MakeBankInfo(std::array{info}), variable_descriptor_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
DescriptorAllocator DescriptorPool::Allocator(VkDescriptorSetLayout layout,
|
DescriptorAllocator DescriptorPool::Allocator(VkDescriptorSetLayout layout,
|
||||||
const DescriptorBankInfo& info) {
|
const DescriptorBankInfo& info,
|
||||||
return DescriptorAllocator(device, master_semaphore, Bank(info), layout);
|
u32 variable_descriptor_count) {
|
||||||
|
return DescriptorAllocator(device, master_semaphore, Bank(info), layout,
|
||||||
|
variable_descriptor_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
DescriptorBank& DescriptorPool::Bank(const DescriptorBankInfo& reqs) {
|
DescriptorBank& DescriptorPool::Bank(const DescriptorBankInfo& reqs) {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
@ -47,7 +50,8 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit DescriptorAllocator(const Device& device_, MasterSemaphore& master_semaphore_,
|
explicit DescriptorAllocator(const Device& device_, MasterSemaphore& master_semaphore_,
|
||||||
DescriptorBank& bank_, VkDescriptorSetLayout layout_);
|
DescriptorBank& bank_, VkDescriptorSetLayout layout_,
|
||||||
|
u32 variable_descriptor_count_);
|
||||||
|
|
||||||
void Allocate(size_t begin, size_t end) override;
|
void Allocate(size_t begin, size_t end) override;
|
||||||
|
|
||||||
|
|
@ -56,6 +60,7 @@ private:
|
||||||
const Device* device{};
|
const Device* device{};
|
||||||
DescriptorBank* bank{};
|
DescriptorBank* bank{};
|
||||||
VkDescriptorSetLayout layout{};
|
VkDescriptorSetLayout layout{};
|
||||||
|
u32 variable_descriptor_count{};
|
||||||
|
|
||||||
std::vector<vk::DescriptorSets> sets;
|
std::vector<vk::DescriptorSets> sets;
|
||||||
};
|
};
|
||||||
|
|
@ -69,9 +74,12 @@ public:
|
||||||
DescriptorPool(const DescriptorPool&) = delete;
|
DescriptorPool(const DescriptorPool&) = delete;
|
||||||
|
|
||||||
DescriptorAllocator Allocator(VkDescriptorSetLayout layout,
|
DescriptorAllocator Allocator(VkDescriptorSetLayout layout,
|
||||||
std::span<const Shader::Info> infos);
|
std::span<const Shader::Info> infos,
|
||||||
DescriptorAllocator Allocator(VkDescriptorSetLayout layout, const Shader::Info& info);
|
u32 variable_descriptor_count = 0);
|
||||||
DescriptorAllocator Allocator(VkDescriptorSetLayout layout, const DescriptorBankInfo& info);
|
DescriptorAllocator Allocator(VkDescriptorSetLayout layout, const Shader::Info& info,
|
||||||
|
u32 variable_descriptor_count = 0);
|
||||||
|
DescriptorAllocator Allocator(VkDescriptorSetLayout layout, const DescriptorBankInfo& info,
|
||||||
|
u32 variable_descriptor_count = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DescriptorBank& Bank(const DescriptorBankInfo& reqs);
|
DescriptorBank& Bank(const DescriptorBankInfo& reqs);
|
||||||
|
|
|
||||||
|
|
@ -273,7 +273,8 @@ GraphicsPipeline::GraphicsPipeline(
|
||||||
descriptor_set_layout = builder.CreateDescriptorSetLayout(uses_push_descriptor);
|
descriptor_set_layout = builder.CreateDescriptorSetLayout(uses_push_descriptor);
|
||||||
|
|
||||||
if (!uses_push_descriptor) {
|
if (!uses_push_descriptor) {
|
||||||
descriptor_allocator = descriptor_pool.Allocator(*descriptor_set_layout, stage_infos);
|
descriptor_allocator = descriptor_pool.Allocator(
|
||||||
|
*descriptor_set_layout, stage_infos, builder.VariableDescriptorCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
const VkDescriptorSetLayout set_layout{*descriptor_set_layout};
|
const VkDescriptorSetLayout set_layout{*descriptor_set_layout};
|
||||||
|
|
|
||||||
|
|
@ -475,6 +475,9 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
|
||||||
|
|
||||||
if (extensions.descriptor_indexing && Settings::values.descriptor_indexing.GetValue()) {
|
if (extensions.descriptor_indexing && Settings::values.descriptor_indexing.GetValue()) {
|
||||||
first_next = &descriptor_indexing;
|
first_next = &descriptor_indexing;
|
||||||
|
} else {
|
||||||
|
RemoveExtension(extensions.descriptor_indexing,
|
||||||
|
VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
is_blit_depth24_stencil8_supported = TestDepthStencilBlits(VK_FORMAT_D24_UNORM_S8_UINT);
|
is_blit_depth24_stencil8_supported = TestDepthStencilBlits(VK_FORMAT_D24_UNORM_S8_UINT);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue