Merge pull request #4110 from ReinUsesLisp/direct-upload-sets
vk_update_descriptor: Upload descriptor sets data directly
This commit is contained in:
		| @@ -1154,7 +1154,7 @@ void RasterizerVulkan::SetupTexture(const Tegra::Texture::FullTextureInfo& textu | |||||||
|     const auto sampler = sampler_cache.GetSampler(texture.tsc); |     const auto sampler = sampler_cache.GetSampler(texture.tsc); | ||||||
|     update_descriptor_queue.AddSampledImage(sampler, image_view); |     update_descriptor_queue.AddSampledImage(sampler, image_view); | ||||||
|  |  | ||||||
|     const auto image_layout = update_descriptor_queue.GetLastImageLayout(); |     VkImageLayout* const image_layout = update_descriptor_queue.LastImageLayout(); | ||||||
|     *image_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; |     *image_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; | ||||||
|     sampled_views.push_back(ImageView{std::move(view), image_layout}); |     sampled_views.push_back(ImageView{std::move(view), image_layout}); | ||||||
| } | } | ||||||
| @@ -1180,7 +1180,7 @@ void RasterizerVulkan::SetupImage(const Tegra::Texture::TICEntry& tic, const Ima | |||||||
|         view->GetImageView(tic.x_source, tic.y_source, tic.z_source, tic.w_source); |         view->GetImageView(tic.x_source, tic.y_source, tic.z_source, tic.w_source); | ||||||
|     update_descriptor_queue.AddImage(image_view); |     update_descriptor_queue.AddImage(image_view); | ||||||
|  |  | ||||||
|     const auto image_layout = update_descriptor_queue.GetLastImageLayout(); |     VkImageLayout* const image_layout = update_descriptor_queue.LastImageLayout(); | ||||||
|     *image_layout = VK_IMAGE_LAYOUT_GENERAL; |     *image_layout = VK_IMAGE_LAYOUT_GENERAL; | ||||||
|     image_views.push_back(ImageView{std::move(view), image_layout}); |     image_views.push_back(ImageView{std::move(view), image_layout}); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -24,35 +24,25 @@ void VKUpdateDescriptorQueue::TickFrame() { | |||||||
| } | } | ||||||
|  |  | ||||||
| void VKUpdateDescriptorQueue::Acquire() { | void VKUpdateDescriptorQueue::Acquire() { | ||||||
|     entries.clear(); |     // Minimum number of entries required. | ||||||
| } |     // This is the maximum number of entries a single draw call migth use. | ||||||
|  |     static constexpr std::size_t MIN_ENTRIES = 0x400; | ||||||
|  |  | ||||||
| void VKUpdateDescriptorQueue::Send(VkDescriptorUpdateTemplateKHR update_template, |     if (payload.size() + MIN_ENTRIES >= payload.max_size()) { | ||||||
|                                    VkDescriptorSet set) { |  | ||||||
|     if (payload.size() + entries.size() >= payload.max_size()) { |  | ||||||
|         LOG_WARNING(Render_Vulkan, "Payload overflow, waiting for worker thread"); |         LOG_WARNING(Render_Vulkan, "Payload overflow, waiting for worker thread"); | ||||||
|         scheduler.WaitWorker(); |         scheduler.WaitWorker(); | ||||||
|         payload.clear(); |         payload.clear(); | ||||||
|     } |     } | ||||||
|  |     upload_start = &*payload.end(); | ||||||
|  | } | ||||||
|  |  | ||||||
|     // TODO(Rodrigo): Rework to write the payload directly | void VKUpdateDescriptorQueue::Send(VkDescriptorUpdateTemplateKHR update_template, | ||||||
|     const auto payload_start = payload.data() + payload.size(); |                                    VkDescriptorSet set) { | ||||||
|     for (const auto& entry : entries) { |     const void* const data = upload_start; | ||||||
|         if (const auto image = std::get_if<VkDescriptorImageInfo>(&entry)) { |     const vk::Device* const logical = &device.GetLogical(); | ||||||
|             payload.push_back(*image); |     scheduler.Record([data, logical, set, update_template](vk::CommandBuffer) { | ||||||
|         } else if (const auto buffer = std::get_if<VkDescriptorBufferInfo>(&entry)) { |         logical->UpdateDescriptorSet(set, update_template, data); | ||||||
|             payload.push_back(*buffer); |     }); | ||||||
|         } else if (const auto texel = std::get_if<VkBufferView>(&entry)) { |  | ||||||
|             payload.push_back(*texel); |  | ||||||
|         } else { |  | ||||||
|             UNREACHABLE(); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     scheduler.Record( |  | ||||||
|         [payload_start, set, update_template, logical = &device.GetLogical()](vk::CommandBuffer) { |  | ||||||
|             logical->UpdateDescriptorSet(set, update_template, payload_start); |  | ||||||
|         }); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| } // namespace Vulkan | } // namespace Vulkan | ||||||
|   | |||||||
| @@ -15,17 +15,13 @@ namespace Vulkan { | |||||||
| class VKDevice; | class VKDevice; | ||||||
| class VKScheduler; | class VKScheduler; | ||||||
|  |  | ||||||
| class DescriptorUpdateEntry { | struct DescriptorUpdateEntry { | ||||||
| public: |     DescriptorUpdateEntry(VkDescriptorImageInfo image_) : image{image_} {} | ||||||
|     explicit DescriptorUpdateEntry() {} |  | ||||||
|  |  | ||||||
|     DescriptorUpdateEntry(VkDescriptorImageInfo image) : image{image} {} |     DescriptorUpdateEntry(VkDescriptorBufferInfo buffer_) : buffer{buffer_} {} | ||||||
|  |  | ||||||
|     DescriptorUpdateEntry(VkDescriptorBufferInfo buffer) : buffer{buffer} {} |     DescriptorUpdateEntry(VkBufferView texel_buffer_) : texel_buffer{texel_buffer_} {} | ||||||
|  |  | ||||||
|     DescriptorUpdateEntry(VkBufferView texel_buffer) : texel_buffer{texel_buffer} {} |  | ||||||
|  |  | ||||||
| private: |  | ||||||
|     union { |     union { | ||||||
|         VkDescriptorImageInfo image; |         VkDescriptorImageInfo image; | ||||||
|         VkDescriptorBufferInfo buffer; |         VkDescriptorBufferInfo buffer; | ||||||
| @@ -45,32 +41,34 @@ public: | |||||||
|     void Send(VkDescriptorUpdateTemplateKHR update_template, VkDescriptorSet set); |     void Send(VkDescriptorUpdateTemplateKHR update_template, VkDescriptorSet set); | ||||||
|  |  | ||||||
|     void AddSampledImage(VkSampler sampler, VkImageView image_view) { |     void AddSampledImage(VkSampler sampler, VkImageView image_view) { | ||||||
|         entries.emplace_back(VkDescriptorImageInfo{sampler, image_view, {}}); |         payload.emplace_back(VkDescriptorImageInfo{sampler, image_view, {}}); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void AddImage(VkImageView image_view) { |     void AddImage(VkImageView image_view) { | ||||||
|         entries.emplace_back(VkDescriptorImageInfo{{}, image_view, {}}); |         payload.emplace_back(VkDescriptorImageInfo{{}, image_view, {}}); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void AddBuffer(VkBuffer buffer, u64 offset, std::size_t size) { |     void AddBuffer(VkBuffer buffer, u64 offset, std::size_t size) { | ||||||
|         entries.emplace_back(VkDescriptorBufferInfo{buffer, offset, size}); |         payload.emplace_back(VkDescriptorBufferInfo{buffer, offset, size}); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void AddTexelBuffer(VkBufferView texel_buffer) { |     void AddTexelBuffer(VkBufferView texel_buffer) { | ||||||
|         entries.emplace_back(texel_buffer); |         payload.emplace_back(texel_buffer); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     VkImageLayout* GetLastImageLayout() { |     VkImageLayout* LastImageLayout() { | ||||||
|         return &std::get<VkDescriptorImageInfo>(entries.back()).imageLayout; |         return &payload.back().image.imageLayout; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     const VkImageLayout* LastImageLayout() const { | ||||||
|  |         return &payload.back().image.imageLayout; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     using Variant = std::variant<VkDescriptorImageInfo, VkDescriptorBufferInfo, VkBufferView>; |  | ||||||
|  |  | ||||||
|     const VKDevice& device; |     const VKDevice& device; | ||||||
|     VKScheduler& scheduler; |     VKScheduler& scheduler; | ||||||
|  |  | ||||||
|     boost::container::static_vector<Variant, 0x400> entries; |     const DescriptorUpdateEntry* upload_start = nullptr; | ||||||
|     boost::container::static_vector<DescriptorUpdateEntry, 0x10000> payload; |     boost::container::static_vector<DescriptorUpdateEntry, 0x10000> payload; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Rodrigo Locatti
					Rodrigo Locatti