diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp index b0298cbb0..11d2a1dde 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp @@ -208,6 +208,9 @@ void DefineEntryPoint(const IR::Program& program, EmitContext& ctx, Id main) { if (info.uses_group_quad) { ctx.AddCapability(spv::Capability::GroupNonUniformQuad); } + if (info.uses_group_ballot) { + ctx.AddCapability(spv::Capability::GroupNonUniformBallot); + } switch (program.info.stage) { case Stage::Compute: { const std::array workgroup_size{ctx.runtime_info.cs_info.workgroup_size}; diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp index 5dc7c1a4d..2d13d09f0 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp @@ -27,7 +27,8 @@ Id EmitReadFirstLane(EmitContext& ctx, Id value) { } Id EmitReadLane(EmitContext& ctx, Id value, u32 lane) { - return ctx.OpGroupNonUniformBroadcast(ctx.U32[1], SubgroupScope(ctx), value, ctx.ConstU32(lane)); + return ctx.OpGroupNonUniformBroadcast(ctx.U32[1], SubgroupScope(ctx), value, + ctx.ConstU32(lane)); } Id EmitWriteLane(EmitContext& ctx, Id value, Id write_value, u32 lane) { diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp index b65cbdf46..8554f8615 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp @@ -324,16 +324,18 @@ void EmitContext::DefineOutputs() { void EmitContext::DefinePushDataBlock() { // Create push constants block for instance steps rates - const Id struct_type{Name(TypeStruct(U32[1], U32[1], U32[4], U32[4]), "AuxData")}; + const Id struct_type{Name(TypeStruct(U32[1], U32[1], U32[4], U32[4], U32[4]), "AuxData")}; Decorate(struct_type, spv::Decoration::Block); MemberName(struct_type, 0, "sr0"); MemberName(struct_type, 1, "sr1"); MemberName(struct_type, 2, "buf_offsets0"); MemberName(struct_type, 3, "buf_offsets1"); + MemberName(struct_type, 4, "buf_offsets2"); MemberDecorate(struct_type, 0, spv::Decoration::Offset, 0U); MemberDecorate(struct_type, 1, spv::Decoration::Offset, 4U); MemberDecorate(struct_type, 2, spv::Decoration::Offset, 8U); MemberDecorate(struct_type, 3, spv::Decoration::Offset, 24U); + MemberDecorate(struct_type, 4, spv::Decoration::Offset, 40U); push_data_block = DefineVar(struct_type, spv::StorageClass::PushConstant); Name(push_data_block, "push_data"); interfaces.push_back(push_data_block); diff --git a/src/shader_recompiler/info.h b/src/shader_recompiler/info.h index 0184a7f63..9af7386a4 100644 --- a/src/shader_recompiler/info.h +++ b/src/shader_recompiler/info.h @@ -89,7 +89,7 @@ struct PushData { u32 step0; u32 step1; - std::array buf_offsets; + std::array buf_offsets; void AddOffset(u32 binding, u32 offset) { ASSERT(offset < 256 && binding < buf_offsets.size()); @@ -166,6 +166,7 @@ struct Info { bool has_image_query{}; bool uses_lane_id{}; bool uses_group_quad{}; + bool uses_group_ballot{}; bool uses_shared{}; bool uses_fp16{}; bool uses_step_rates{}; diff --git a/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp b/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp index aa5d39ae8..47bc82f40 100644 --- a/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp +++ b/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp @@ -223,12 +223,8 @@ public: u32 Add(const SamplerResource& desc) { const u32 index{Add(sampler_resources, desc, [this, &desc](const auto& existing) { - if (desc.sgpr_base == existing.sgpr_base && - desc.dword_offset == existing.dword_offset) { - return true; - } - // Samplers with different bindings might still be the same. - return existing.GetSharp(info) == desc.GetSharp(info); + return desc.sgpr_base == existing.sgpr_base && + desc.dword_offset == existing.dword_offset; })}; return index; } diff --git a/src/shader_recompiler/ir/passes/shader_info_collection_pass.cpp b/src/shader_recompiler/ir/passes/shader_info_collection_pass.cpp index 5ce024b43..7835ef1a9 100644 --- a/src/shader_recompiler/ir/passes/shader_info_collection_pass.cpp +++ b/src/shader_recompiler/ir/passes/shader_info_collection_pass.cpp @@ -39,6 +39,9 @@ void Visit(Info& info, IR::Inst& inst) { case IR::Opcode::QuadShuffle: info.uses_group_quad = true; break; + case IR::Opcode::ReadLane: + info.uses_group_ballot = true; + break; case IR::Opcode::Discard: case IR::Opcode::DiscardCond: info.has_discard = true; diff --git a/src/video_core/buffer_cache/buffer_cache.cpp b/src/video_core/buffer_cache/buffer_cache.cpp index 86af05bf1..f1cf8136e 100644 --- a/src/video_core/buffer_cache/buffer_cache.cpp +++ b/src/video_core/buffer_cache/buffer_cache.cpp @@ -577,9 +577,6 @@ bool BufferCache::SynchronizeBufferFromImage(Buffer& buffer, VAddr device_addr, return false; } Image& image = texture_cache.GetImage(image_id); - if (image.info.guest_size_bytes > size) { - return false; - } boost::container::small_vector copies; u32 offset = buffer.Offset(image.cpu_addr); const u32 num_layers = image.info.resources.layers; @@ -589,6 +586,9 @@ bool BufferCache::SynchronizeBufferFromImage(Buffer& buffer, VAddr device_addr, const u32 depth = image.info.props.is_volume ? std::max(image.info.size.depth >> m, 1u) : 1u; const auto& [mip_size, mip_pitch, mip_height, mip_ofs] = image.info.mips_layout[m]; + if (offset + (mip_ofs * num_layers) > buffer.SizeBytes()) { + break; + } copies.push_back({ .bufferOffset = offset, .bufferRowLength = static_cast(mip_pitch), @@ -604,11 +604,13 @@ bool BufferCache::SynchronizeBufferFromImage(Buffer& buffer, VAddr device_addr, }); offset += mip_ofs * num_layers; } - scheduler.EndRendering(); - image.Transit(vk::ImageLayout::eTransferSrcOptimal, vk::AccessFlagBits::eTransferRead); - const auto cmdbuf = scheduler.CommandBuffer(); - cmdbuf.copyImageToBuffer(image.image, vk::ImageLayout::eTransferSrcOptimal, buffer.buffer, - copies); + if (!copies.empty()) { + scheduler.EndRendering(); + image.Transit(vk::ImageLayout::eTransferSrcOptimal, vk::AccessFlagBits::eTransferRead); + const auto cmdbuf = scheduler.CommandBuffer(); + cmdbuf.copyImageToBuffer(image.image, vk::ImageLayout::eTransferSrcOptimal, buffer.buffer, + copies); + } return true; } diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp index ebbe44537..96358bf67 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp @@ -12,9 +12,11 @@ namespace Vulkan { ComputePipeline::ComputePipeline(const Instance& instance_, Scheduler& scheduler_, - vk::PipelineCache pipeline_cache, u64 compute_key_, - const Shader::Info& info_, vk::ShaderModule module) - : instance{instance_}, scheduler{scheduler_}, compute_key{compute_key_}, info{&info_} { + DescriptorHeap& desc_heap_, vk::PipelineCache pipeline_cache, + u64 compute_key_, const Shader::Info& info_, + vk::ShaderModule module) + : instance{instance_}, scheduler{scheduler_}, desc_heap{desc_heap_}, compute_key{compute_key_}, + info{&info_} { const vk::PipelineShaderStageCreateInfo shader_ci = { .stage = vk::ShaderStageFlagBits::eCompute, .module = module, @@ -66,8 +68,12 @@ ComputePipeline::ComputePipeline(const Instance& instance_, Scheduler& scheduler .size = sizeof(Shader::PushData), }; + uses_push_descriptors = binding < instance.MaxPushDescriptors(); + const auto flags = uses_push_descriptors + ? vk::DescriptorSetLayoutCreateFlagBits::ePushDescriptorKHR + : vk::DescriptorSetLayoutCreateFlagBits{}; const vk::DescriptorSetLayoutCreateInfo desc_layout_ci = { - .flags = vk::DescriptorSetLayoutCreateFlagBits::ePushDescriptorKHR, + .flags = flags, .bindingCount = static_cast(bindings.size()), .pBindings = bindings.data(), }; @@ -265,9 +271,21 @@ bool ComputePipeline::BindResources(VideoCore::BufferCache& buffer_cache, cmdbuf.pipelineBarrier2(dependencies); } + if (uses_push_descriptors) { + cmdbuf.pushDescriptorSetKHR(vk::PipelineBindPoint::eCompute, *pipeline_layout, 0, + set_writes); + } else { + const auto desc_set = desc_heap.Commit(*desc_layout); + for (auto& set_write : set_writes) { + set_write.dstSet = desc_set; + } + instance.GetDevice().updateDescriptorSets(set_writes, {}); + cmdbuf.bindDescriptorSets(vk::PipelineBindPoint::eCompute, *pipeline_layout, 0, desc_set, + {}); + } + cmdbuf.pushConstants(*pipeline_layout, vk::ShaderStageFlagBits::eCompute, 0u, sizeof(push_data), &push_data); - cmdbuf.pushDescriptorSetKHR(vk::PipelineBindPoint::eCompute, *pipeline_layout, 0, set_writes); return true; } diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.h b/src/video_core/renderer_vulkan/vk_compute_pipeline.h index 54eaf6532..8a6213a29 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pipeline.h +++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.h @@ -16,12 +16,13 @@ namespace Vulkan { class Instance; class Scheduler; +class DescriptorHeap; class ComputePipeline { public: explicit ComputePipeline(const Instance& instance, Scheduler& scheduler, - vk::PipelineCache pipeline_cache, u64 compute_key, - const Shader::Info& info, vk::ShaderModule module); + DescriptorHeap& desc_heap, vk::PipelineCache pipeline_cache, + u64 compute_key, const Shader::Info& info, vk::ShaderModule module); ~ComputePipeline(); [[nodiscard]] vk::Pipeline Handle() const noexcept { @@ -34,11 +35,13 @@ public: private: const Instance& instance; Scheduler& scheduler; + DescriptorHeap& desc_heap; vk::UniquePipeline pipeline; vk::UniquePipelineLayout pipeline_layout; vk::UniqueDescriptorSetLayout desc_layout; u64 compute_key; const Shader::Info* info; + bool uses_push_descriptors{}; }; } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index a548b70a4..5550c4112 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -17,11 +17,11 @@ namespace Vulkan { GraphicsPipeline::GraphicsPipeline(const Instance& instance_, Scheduler& scheduler_, - const GraphicsPipelineKey& key_, + DescriptorHeap& desc_heap_, const GraphicsPipelineKey& key_, vk::PipelineCache pipeline_cache, std::span infos, std::span modules) - : instance{instance_}, scheduler{scheduler_}, key{key_} { + : instance{instance_}, scheduler{scheduler_}, desc_heap{desc_heap_}, key{key_} { const vk::Device device = instance.GetDevice(); std::ranges::copy(infos, stages.begin()); BuildDescSetLayout(); @@ -343,8 +343,12 @@ void GraphicsPipeline::BuildDescSetLayout() { }); } } + uses_push_descriptors = binding < instance.MaxPushDescriptors(); + const auto flags = uses_push_descriptors + ? vk::DescriptorSetLayoutCreateFlagBits::ePushDescriptorKHR + : vk::DescriptorSetLayoutCreateFlagBits{}; const vk::DescriptorSetLayoutCreateInfo desc_layout_ci = { - .flags = vk::DescriptorSetLayoutCreateFlagBits::ePushDescriptorKHR, + .flags = flags, .bindingCount = static_cast(bindings.size()), .pBindings = bindings.data(), }; @@ -510,8 +514,18 @@ void GraphicsPipeline::BindResources(const Liverpool::Regs& regs, } if (!set_writes.empty()) { - cmdbuf.pushDescriptorSetKHR(vk::PipelineBindPoint::eGraphics, *pipeline_layout, 0, - set_writes); + if (uses_push_descriptors) { + cmdbuf.pushDescriptorSetKHR(vk::PipelineBindPoint::eGraphics, *pipeline_layout, 0, + set_writes); + } else { + const auto desc_set = desc_heap.Commit(*desc_layout); + for (auto& set_write : set_writes) { + set_write.dstSet = desc_set; + } + instance.GetDevice().updateDescriptorSets(set_writes, {}); + cmdbuf.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, *pipeline_layout, 0, + desc_set, {}); + } } cmdbuf.pushConstants(*pipeline_layout, vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment, 0U, diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h index c06ddd204..345c7ebee 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h @@ -19,6 +19,7 @@ static constexpr u32 MaxShaderStages = 5; class Instance; class Scheduler; +class DescriptorHeap; using Liverpool = AmdGpu::Liverpool; @@ -59,7 +60,8 @@ struct GraphicsPipelineKey { class GraphicsPipeline { public: explicit GraphicsPipeline(const Instance& instance, Scheduler& scheduler, - const GraphicsPipelineKey& key, vk::PipelineCache pipeline_cache, + DescriptorHeap& desc_heap, const GraphicsPipelineKey& key, + vk::PipelineCache pipeline_cache, std::span stages, std::span modules); ~GraphicsPipeline(); @@ -98,11 +100,13 @@ private: private: const Instance& instance; Scheduler& scheduler; + DescriptorHeap& desc_heap; vk::UniquePipeline pipeline; vk::UniquePipelineLayout pipeline_layout; vk::UniqueDescriptorSetLayout desc_layout; std::array stages{}; GraphicsPipelineKey key; + bool uses_push_descriptors{}; }; } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/vk_instance.cpp b/src/video_core/renderer_vulkan/vk_instance.cpp index a19ee1c76..769a808e1 100644 --- a/src/video_core/renderer_vulkan/vk_instance.cpp +++ b/src/video_core/renderer_vulkan/vk_instance.cpp @@ -176,8 +176,10 @@ bool Instance::CreateDevice() { vk::PhysicalDevicePortabilitySubsetFeaturesKHR>(); const vk::StructureChain properties_chain = physical_device.getProperties2< vk::PhysicalDeviceProperties2, vk::PhysicalDevicePortabilitySubsetPropertiesKHR, - vk::PhysicalDeviceExternalMemoryHostPropertiesEXT, vk::PhysicalDeviceVulkan11Properties>(); + vk::PhysicalDeviceExternalMemoryHostPropertiesEXT, vk::PhysicalDeviceVulkan11Properties, + vk::PhysicalDevicePushDescriptorPropertiesKHR>(); subgroup_size = properties_chain.get().subgroupSize; + push_descriptor_props = properties_chain.get(); LOG_INFO(Render_Vulkan, "Physical device subgroup size {}", subgroup_size); features = feature_chain.get().features; diff --git a/src/video_core/renderer_vulkan/vk_instance.h b/src/video_core/renderer_vulkan/vk_instance.h index 523109554..a64c77a57 100644 --- a/src/video_core/renderer_vulkan/vk_instance.h +++ b/src/video_core/renderer_vulkan/vk_instance.h @@ -207,6 +207,11 @@ public: return properties.limits.maxTexelBufferElements; } + /// Returns the maximum number of push descriptors. + u32 MaxPushDescriptors() const { + return push_descriptor_props.maxPushDescriptors; + } + /// Returns true if shaders can declare the ClipDistance attribute bool IsShaderClipDistanceSupported() const { return features.shaderClipDistance; @@ -242,6 +247,7 @@ private: vk::PhysicalDevice physical_device; vk::UniqueDevice device; vk::PhysicalDeviceProperties properties; + vk::PhysicalDevicePushDescriptorPropertiesKHR push_descriptor_props; vk::PhysicalDeviceFeatures features; vk::DriverIdKHR driver_id; vk::UniqueDebugUtilsMessengerEXT debug_callback{}; diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index b4b256bb0..2bfbd8a8f 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -20,6 +20,15 @@ namespace Vulkan { using Shader::VsOutput; +constexpr static std::array DescriptorHeapSizes = { + vk::DescriptorPoolSize{vk::DescriptorType::eUniformBuffer, 8192}, + vk::DescriptorPoolSize{vk::DescriptorType::eStorageBuffer, 1024}, + vk::DescriptorPoolSize{vk::DescriptorType::eUniformTexelBuffer, 128}, + vk::DescriptorPoolSize{vk::DescriptorType::eStorageTexelBuffer, 128}, + vk::DescriptorPoolSize{vk::DescriptorType::eSampledImage, 8192}, + vk::DescriptorPoolSize{vk::DescriptorType::eSampler, 1024}, +}; + [[nodiscard]] inline u64 HashCombine(const u64 seed, const u64 hash) { return seed ^ (hash + 0x9e3779b9 + (seed << 6) + (seed >> 2)); } @@ -120,7 +129,8 @@ Shader::RuntimeInfo PipelineCache::BuildRuntimeInfo(Shader::Stage stage) { PipelineCache::PipelineCache(const Instance& instance_, Scheduler& scheduler_, AmdGpu::Liverpool* liverpool_) - : instance{instance_}, scheduler{scheduler_}, liverpool{liverpool_} { + : instance{instance_}, scheduler{scheduler_}, liverpool{liverpool_}, + desc_heap{instance, scheduler.GetMasterSemaphore(), DescriptorHeapSizes} { profile = Shader::Profile{ .supported_spirv = instance.ApiVersion() >= VK_API_VERSION_1_3 ? 0x00010600U : 0x00010500U, .subgroup_size = instance.SubgroupSize(), @@ -153,8 +163,8 @@ const GraphicsPipeline* PipelineCache::GetGraphicsPipeline() { } const auto [it, is_new] = graphics_pipelines.try_emplace(graphics_key); if (is_new) { - it.value() = std::make_unique(instance, scheduler, graphics_key, - *pipeline_cache, infos, modules); + it.value() = std::make_unique( + instance, scheduler, desc_heap, graphics_key, *pipeline_cache, infos, modules); } const GraphicsPipeline* pipeline = it->second.get(); return pipeline; @@ -166,8 +176,8 @@ const ComputePipeline* PipelineCache::GetComputePipeline() { } const auto [it, is_new] = compute_pipelines.try_emplace(compute_key); if (is_new) { - it.value() = std::make_unique(instance, scheduler, *pipeline_cache, - compute_key, *infos[0], modules[0]); + it.value() = std::make_unique( + instance, scheduler, desc_heap, *pipeline_cache, compute_key, *infos[0], modules[0]); } const ComputePipeline* pipeline = it->second.get(); return pipeline; diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.h b/src/video_core/renderer_vulkan/vk_pipeline_cache.h index 96e2cd043..92dcf8262 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.h +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.h @@ -9,6 +9,7 @@ #include "shader_recompiler/specialization.h" #include "video_core/renderer_vulkan/vk_compute_pipeline.h" #include "video_core/renderer_vulkan/vk_graphics_pipeline.h" +#include "video_core/renderer_vulkan/vk_resource_pool.h" namespace Shader { struct Info; @@ -66,6 +67,7 @@ private: const Instance& instance; Scheduler& scheduler; AmdGpu::Liverpool* liverpool; + DescriptorHeap desc_heap; vk::UniquePipelineCache pipeline_cache; vk::UniquePipelineLayout pipeline_layout; Shader::Profile profile{}; diff --git a/src/video_core/renderer_vulkan/vk_platform.cpp b/src/video_core/renderer_vulkan/vk_platform.cpp index feadda96c..4724b6038 100644 --- a/src/video_core/renderer_vulkan/vk_platform.cpp +++ b/src/video_core/renderer_vulkan/vk_platform.cpp @@ -43,6 +43,7 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL DebugUtilsCallback( case 0x609a13b: // Vertex attribute at location not consumed by shader case 0xc81ad50e: case 0xb7c39078: + case 0x30b6e267: // TODO remove this case 0x32868fde: // vkCreateBufferView(): pCreateInfo->range does not equal VK_WHOLE_SIZE case 0x92d66fc1: // `pMultisampleState is NULL` for depth only passes (confirmed VL error) return VK_FALSE; diff --git a/src/video_core/renderer_vulkan/vk_resource_pool.cpp b/src/video_core/renderer_vulkan/vk_resource_pool.cpp index f9f2ae0a0..61004f859 100644 --- a/src/video_core/renderer_vulkan/vk_resource_pool.cpp +++ b/src/video_core/renderer_vulkan/vk_resource_pool.cpp @@ -106,31 +106,10 @@ vk::CommandBuffer CommandPool::Commit() { constexpr u32 DESCRIPTOR_SET_BATCH = 32; DescriptorHeap::DescriptorHeap(const Instance& instance, MasterSemaphore* master_semaphore, - std::span bindings, + std::span pool_sizes_, u32 descriptor_heap_count_) : ResourcePool{master_semaphore, DESCRIPTOR_SET_BATCH}, device{instance.GetDevice()}, - descriptor_heap_count{descriptor_heap_count_} { - // Create descriptor set layout. - const vk::DescriptorSetLayoutCreateInfo layout_ci = { - .bindingCount = static_cast(bindings.size()), - .pBindings = bindings.data(), - }; - descriptor_set_layout = device.createDescriptorSetLayoutUnique(layout_ci); - if (instance.HasDebuggingToolAttached()) { - SetObjectName(device, *descriptor_set_layout, "DescriptorSetLayout"); - } - - // Build descriptor set pool counts. - std::unordered_map descriptor_type_counts; - for (const auto& binding : bindings) { - descriptor_type_counts[binding.descriptorType] += binding.descriptorCount; - } - for (const auto& [type, count] : descriptor_type_counts) { - auto& pool_size = pool_sizes.emplace_back(); - pool_size.descriptorCount = count * descriptor_heap_count; - pool_size.type = type; - } - + descriptor_heap_count{descriptor_heap_count_}, pool_sizes{pool_sizes_} { // Create descriptor pool AppendDescriptorPool(); } @@ -143,7 +122,7 @@ void DescriptorHeap::Allocate(std::size_t begin, std::size_t end) { hashes.resize(end); std::array layouts; - layouts.fill(*descriptor_set_layout); + layouts.fill(descriptor_set_layout); u32 current_pool = 0; vk::DescriptorSetAllocateInfo alloc_info = { @@ -171,7 +150,8 @@ void DescriptorHeap::Allocate(std::size_t begin, std::size_t end) { } } -vk::DescriptorSet DescriptorHeap::Commit() { +vk::DescriptorSet DescriptorHeap::Commit(vk::DescriptorSetLayout set_layout) { + this->descriptor_set_layout = set_layout; const std::size_t index = CommitResource(); return descriptor_sets[index]; } diff --git a/src/video_core/renderer_vulkan/vk_resource_pool.h b/src/video_core/renderer_vulkan/vk_resource_pool.h index b138b9693..00a600c10 100644 --- a/src/video_core/renderer_vulkan/vk_resource_pool.h +++ b/src/video_core/renderer_vulkan/vk_resource_pool.h @@ -65,26 +65,22 @@ private: class DescriptorHeap final : public ResourcePool { public: explicit DescriptorHeap(const Instance& instance, MasterSemaphore* master_semaphore, - std::span bindings, + std::span pool_sizes, u32 descriptor_heap_count = 1024); ~DescriptorHeap() override; - const vk::DescriptorSetLayout& Layout() const { - return *descriptor_set_layout; - } - void Allocate(std::size_t begin, std::size_t end) override; - vk::DescriptorSet Commit(); + vk::DescriptorSet Commit(vk::DescriptorSetLayout set_layout); private: void AppendDescriptorPool(); private: vk::Device device; - vk::UniqueDescriptorSetLayout descriptor_set_layout; + vk::DescriptorSetLayout descriptor_set_layout; u32 descriptor_heap_count; - std::vector pool_sizes; + std::span pool_sizes; std::vector pools; std::vector descriptor_sets; std::vector hashes;