diff options
Diffstat (limited to '')
-rw-r--r-- | src/video_core/renderer_vulkan/pipeline_helper.h | 73 |
1 files changed, 62 insertions, 11 deletions
diff --git a/src/video_core/renderer_vulkan/pipeline_helper.h b/src/video_core/renderer_vulkan/pipeline_helper.h index 4847db6b6..11c160570 100644 --- a/src/video_core/renderer_vulkan/pipeline_helper.h +++ b/src/video_core/renderer_vulkan/pipeline_helper.h @@ -10,6 +10,7 @@ #include "common/assert.h" #include "common/common_types.h" +#include "shader_recompiler/backend/spirv/emit_spirv.h" #include "shader_recompiler/shader_info.h" #include "video_core/renderer_vulkan/vk_texture_cache.h" #include "video_core/renderer_vulkan/vk_update_descriptor.h" @@ -20,6 +21,8 @@ namespace Vulkan { +using Shader::Backend::SPIRV::NUM_TEXTURE_AND_IMAGE_SCALING_WORDS; + class DescriptorLayoutBuilder { public: DescriptorLayoutBuilder(const Device& device_) : device{&device_} {} @@ -68,18 +71,28 @@ public: } vk::PipelineLayout CreatePipelineLayout(VkDescriptorSetLayout descriptor_set_layout) const { + using Shader::Backend::SPIRV::RescalingLayout; + const u32 size_offset = is_compute ? sizeof(RescalingLayout::down_factor) : 0u; + const VkPushConstantRange range{ + .stageFlags = static_cast<VkShaderStageFlags>( + is_compute ? VK_SHADER_STAGE_COMPUTE_BIT : VK_SHADER_STAGE_ALL_GRAPHICS), + .offset = 0, + .size = static_cast<u32>(sizeof(RescalingLayout)) - size_offset, + }; return device->GetLogical().CreatePipelineLayout({ .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, .pNext = nullptr, .flags = 0, .setLayoutCount = descriptor_set_layout ? 1U : 0U, .pSetLayouts = bindings.empty() ? nullptr : &descriptor_set_layout, - .pushConstantRangeCount = 0, - .pPushConstantRanges = nullptr, + .pushConstantRangeCount = 1, + .pPushConstantRanges = &range, }); } void Add(const Shader::Info& info, VkShaderStageFlags stage) { + is_compute |= (stage & VK_SHADER_STAGE_COMPUTE_BIT) != 0; + Add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, stage, info.constant_buffer_descriptors); Add(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, stage, info.storage_buffers_descriptors); Add(VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, stage, info.texture_buffer_descriptors); @@ -115,6 +128,7 @@ private: } const Device* device{}; + bool is_compute{}; boost::container::small_vector<VkDescriptorSetLayoutBinding, 32> bindings; boost::container::small_vector<VkDescriptorUpdateTemplateEntryKHR, 32> entries; u32 binding{}; @@ -122,31 +136,68 @@ private: size_t offset{}; }; -inline void PushImageDescriptors(const Shader::Info& info, const VkSampler*& samplers, - const ImageId*& image_view_ids, TextureCache& texture_cache, - VKUpdateDescriptorQueue& update_descriptor_queue) { - for (const auto& desc : info.texture_buffer_descriptors) { - image_view_ids += desc.count; +class RescalingPushConstant { +public: + explicit RescalingPushConstant() noexcept {} + + void PushTexture(bool is_rescaled) noexcept { + *texture_ptr |= is_rescaled ? texture_bit : 0u; + texture_bit <<= 1u; + if (texture_bit == 0u) { + texture_bit = 1u; + ++texture_ptr; + } } - for (const auto& desc : info.image_buffer_descriptors) { - image_view_ids += desc.count; + + void PushImage(bool is_rescaled) noexcept { + *image_ptr |= is_rescaled ? image_bit : 0u; + image_bit <<= 1u; + if (image_bit == 0u) { + image_bit = 1u; + ++image_ptr; + } } + + const std::array<u32, NUM_TEXTURE_AND_IMAGE_SCALING_WORDS>& Data() const noexcept { + return words; + } + +private: + std::array<u32, NUM_TEXTURE_AND_IMAGE_SCALING_WORDS> words{}; + u32* texture_ptr{words.data()}; + u32* image_ptr{words.data() + Shader::Backend::SPIRV::NUM_TEXTURE_SCALING_WORDS}; + u32 texture_bit{1u}; + u32 image_bit{1u}; +}; + +inline void PushImageDescriptors(TextureCache& texture_cache, + VKUpdateDescriptorQueue& update_descriptor_queue, + const Shader::Info& info, RescalingPushConstant& rescaling, + const VkSampler*& samplers, + const VideoCommon::ImageViewInOut*& views) { + const u32 num_texture_buffers = Shader::NumDescriptors(info.texture_buffer_descriptors); + const u32 num_image_buffers = Shader::NumDescriptors(info.image_buffer_descriptors); + views += num_texture_buffers; + views += num_image_buffers; for (const auto& desc : info.texture_descriptors) { for (u32 index = 0; index < desc.count; ++index) { + const VideoCommon::ImageViewId image_view_id{(views++)->id}; const VkSampler sampler{*(samplers++)}; - ImageView& image_view{texture_cache.GetImageView(*(image_view_ids++))}; + ImageView& image_view{texture_cache.GetImageView(image_view_id)}; const VkImageView vk_image_view{image_view.Handle(desc.type)}; update_descriptor_queue.AddSampledImage(vk_image_view, sampler); + rescaling.PushTexture(texture_cache.IsRescaling(image_view)); } } for (const auto& desc : info.image_descriptors) { for (u32 index = 0; index < desc.count; ++index) { - ImageView& image_view{texture_cache.GetImageView(*(image_view_ids++))}; + ImageView& image_view{texture_cache.GetImageView((views++)->id)}; if (desc.is_written) { texture_cache.MarkModification(image_view.image_id); } const VkImageView vk_image_view{image_view.StorageView(desc.type, desc.format)}; update_descriptor_queue.AddImage(vk_image_view); + rescaling.PushImage(texture_cache.IsRescaling(image_view)); } } } |