diff options
| author | 2021-04-14 21:36:36 -0300 | |
|---|---|---|
| committer | 2021-07-22 21:51:27 -0400 | |
| commit | 416e1b7441d34512fcb0ffed014daf7ca4bb62bd (patch) | |
| tree | fa14781ad4969613919a8bcd68b887b9b7a98304 /src/video_core | |
| parent | spirv: Implement Layer stores (diff) | |
| download | yuzu-416e1b7441d34512fcb0ffed014daf7ca4bb62bd.tar.gz yuzu-416e1b7441d34512fcb0ffed014daf7ca4bb62bd.tar.xz yuzu-416e1b7441d34512fcb0ffed014daf7ca4bb62bd.zip | |
spirv: Implement image buffers
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/buffer_cache/buffer_cache.h | 24 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/pipeline_helper.h | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_compute_pipeline.cpp | 25 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp | 31 |
4 files changed, 56 insertions, 26 deletions
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 6701aab82..29746f61d 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h | |||
| @@ -154,7 +154,7 @@ public: | |||
| 154 | void UnbindGraphicsTextureBuffers(size_t stage); | 154 | void UnbindGraphicsTextureBuffers(size_t stage); |
| 155 | 155 | ||
| 156 | void BindGraphicsTextureBuffer(size_t stage, size_t tbo_index, GPUVAddr gpu_addr, u32 size, | 156 | void BindGraphicsTextureBuffer(size_t stage, size_t tbo_index, GPUVAddr gpu_addr, u32 size, |
| 157 | PixelFormat format); | 157 | PixelFormat format, bool is_written); |
| 158 | 158 | ||
| 159 | void UnbindComputeStorageBuffers(); | 159 | void UnbindComputeStorageBuffers(); |
| 160 | 160 | ||
| @@ -163,8 +163,8 @@ public: | |||
| 163 | 163 | ||
| 164 | void UnbindComputeTextureBuffers(); | 164 | void UnbindComputeTextureBuffers(); |
| 165 | 165 | ||
| 166 | void BindComputeTextureBuffer(size_t tbo_index, GPUVAddr gpu_addr, u32 size, | 166 | void BindComputeTextureBuffer(size_t tbo_index, GPUVAddr gpu_addr, u32 size, PixelFormat format, |
| 167 | PixelFormat format); | 167 | bool is_written); |
| 168 | 168 | ||
| 169 | void FlushCachedWrites(); | 169 | void FlushCachedWrites(); |
| 170 | 170 | ||
| @@ -393,7 +393,9 @@ private: | |||
| 393 | u32 written_compute_storage_buffers = 0; | 393 | u32 written_compute_storage_buffers = 0; |
| 394 | 394 | ||
| 395 | std::array<u32, NUM_STAGES> enabled_texture_buffers{}; | 395 | std::array<u32, NUM_STAGES> enabled_texture_buffers{}; |
| 396 | std::array<u32, NUM_STAGES> written_texture_buffers{}; | ||
| 396 | u32 enabled_compute_texture_buffers = 0; | 397 | u32 enabled_compute_texture_buffers = 0; |
| 398 | u32 written_compute_texture_buffers = 0; | ||
| 397 | 399 | ||
| 398 | std::array<u32, NUM_STAGES> fast_bound_uniform_buffers{}; | 400 | std::array<u32, NUM_STAGES> fast_bound_uniform_buffers{}; |
| 399 | 401 | ||
| @@ -700,12 +702,14 @@ void BufferCache<P>::BindGraphicsStorageBuffer(size_t stage, size_t ssbo_index, | |||
| 700 | template <class P> | 702 | template <class P> |
| 701 | void BufferCache<P>::UnbindGraphicsTextureBuffers(size_t stage) { | 703 | void BufferCache<P>::UnbindGraphicsTextureBuffers(size_t stage) { |
| 702 | enabled_texture_buffers[stage] = 0; | 704 | enabled_texture_buffers[stage] = 0; |
| 705 | written_texture_buffers[stage] = 0; | ||
| 703 | } | 706 | } |
| 704 | 707 | ||
| 705 | template <class P> | 708 | template <class P> |
| 706 | void BufferCache<P>::BindGraphicsTextureBuffer(size_t stage, size_t tbo_index, GPUVAddr gpu_addr, | 709 | void BufferCache<P>::BindGraphicsTextureBuffer(size_t stage, size_t tbo_index, GPUVAddr gpu_addr, |
| 707 | u32 size, PixelFormat format) { | 710 | u32 size, PixelFormat format, bool is_written) { |
| 708 | enabled_texture_buffers[stage] |= 1U << tbo_index; | 711 | enabled_texture_buffers[stage] |= 1U << tbo_index; |
| 712 | written_texture_buffers[stage] |= (is_written ? 1U : 0U) << tbo_index; | ||
| 709 | texture_buffers[stage][tbo_index] = GetTextureBufferBinding(gpu_addr, size, format); | 713 | texture_buffers[stage][tbo_index] = GetTextureBufferBinding(gpu_addr, size, format); |
| 710 | } | 714 | } |
| 711 | 715 | ||
| @@ -732,12 +736,14 @@ void BufferCache<P>::BindComputeStorageBuffer(size_t ssbo_index, u32 cbuf_index, | |||
| 732 | template <class P> | 736 | template <class P> |
| 733 | void BufferCache<P>::UnbindComputeTextureBuffers() { | 737 | void BufferCache<P>::UnbindComputeTextureBuffers() { |
| 734 | enabled_compute_texture_buffers = 0; | 738 | enabled_compute_texture_buffers = 0; |
| 739 | written_compute_texture_buffers = 0; | ||
| 735 | } | 740 | } |
| 736 | 741 | ||
| 737 | template <class P> | 742 | template <class P> |
| 738 | void BufferCache<P>::BindComputeTextureBuffer(size_t tbo_index, GPUVAddr gpu_addr, u32 size, | 743 | void BufferCache<P>::BindComputeTextureBuffer(size_t tbo_index, GPUVAddr gpu_addr, u32 size, |
| 739 | PixelFormat format) { | 744 | PixelFormat format, bool is_written) { |
| 740 | enabled_compute_texture_buffers |= 1U << tbo_index; | 745 | enabled_compute_texture_buffers |= 1U << tbo_index; |
| 746 | written_compute_texture_buffers |= (is_written ? 1U : 0U) << tbo_index; | ||
| 741 | compute_texture_buffers[tbo_index] = GetTextureBufferBinding(gpu_addr, size, format); | 747 | compute_texture_buffers[tbo_index] = GetTextureBufferBinding(gpu_addr, size, format); |
| 742 | } | 748 | } |
| 743 | 749 | ||
| @@ -1274,6 +1280,10 @@ void BufferCache<P>::UpdateTextureBuffers(size_t stage) { | |||
| 1274 | ForEachEnabledBit(enabled_texture_buffers[stage], [&](u32 index) { | 1280 | ForEachEnabledBit(enabled_texture_buffers[stage], [&](u32 index) { |
| 1275 | Binding& binding = texture_buffers[stage][index]; | 1281 | Binding& binding = texture_buffers[stage][index]; |
| 1276 | binding.buffer_id = FindBuffer(binding.cpu_addr, binding.size); | 1282 | binding.buffer_id = FindBuffer(binding.cpu_addr, binding.size); |
| 1283 | // Mark buffer as written if needed | ||
| 1284 | if (((written_texture_buffers[stage] >> index) & 1) != 0) { | ||
| 1285 | MarkWrittenBuffer(binding.buffer_id, binding.cpu_addr, binding.size); | ||
| 1286 | } | ||
| 1277 | }); | 1287 | }); |
| 1278 | } | 1288 | } |
| 1279 | 1289 | ||
| @@ -1343,6 +1353,10 @@ void BufferCache<P>::UpdateComputeTextureBuffers() { | |||
| 1343 | ForEachEnabledBit(enabled_compute_texture_buffers, [&](u32 index) { | 1353 | ForEachEnabledBit(enabled_compute_texture_buffers, [&](u32 index) { |
| 1344 | Binding& binding = compute_texture_buffers[index]; | 1354 | Binding& binding = compute_texture_buffers[index]; |
| 1345 | binding.buffer_id = FindBuffer(binding.cpu_addr, binding.size); | 1355 | binding.buffer_id = FindBuffer(binding.cpu_addr, binding.size); |
| 1356 | // Mark as written if needed | ||
| 1357 | if (((written_compute_texture_buffers >> index) & 1) != 0) { | ||
| 1358 | MarkWrittenBuffer(binding.buffer_id, binding.cpu_addr, binding.size); | ||
| 1359 | } | ||
| 1346 | }); | 1360 | }); |
| 1347 | } | 1361 | } |
| 1348 | 1362 | ||
diff --git a/src/video_core/renderer_vulkan/pipeline_helper.h b/src/video_core/renderer_vulkan/pipeline_helper.h index e2167dc4b..aaf9a735e 100644 --- a/src/video_core/renderer_vulkan/pipeline_helper.h +++ b/src/video_core/renderer_vulkan/pipeline_helper.h | |||
| @@ -88,6 +88,7 @@ public: | |||
| 88 | Add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, stage, info.constant_buffer_descriptors.size()); | 88 | Add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, stage, info.constant_buffer_descriptors.size()); |
| 89 | Add(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, stage, info.storage_buffers_descriptors.size()); | 89 | Add(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, stage, info.storage_buffers_descriptors.size()); |
| 90 | Add(VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, stage, info.texture_buffer_descriptors.size()); | 90 | Add(VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, stage, info.texture_buffer_descriptors.size()); |
| 91 | Add(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, stage, info.image_buffer_descriptors.size()); | ||
| 91 | Add(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, stage, info.texture_descriptors.size()); | 92 | Add(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, stage, info.texture_descriptors.size()); |
| 92 | Add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, stage, info.image_descriptors.size()); | 93 | Add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, stage, info.image_descriptors.size()); |
| 93 | } | 94 | } |
| @@ -126,6 +127,7 @@ inline void PushImageDescriptors(const Shader::Info& info, const VkSampler*& sam | |||
| 126 | const ImageId*& image_view_ids, TextureCache& texture_cache, | 127 | const ImageId*& image_view_ids, TextureCache& texture_cache, |
| 127 | VKUpdateDescriptorQueue& update_descriptor_queue) { | 128 | VKUpdateDescriptorQueue& update_descriptor_queue) { |
| 128 | image_view_ids += info.texture_buffer_descriptors.size(); | 129 | image_view_ids += info.texture_buffer_descriptors.size(); |
| 130 | image_view_ids += info.image_buffer_descriptors.size(); | ||
| 129 | for (const auto& desc : info.texture_descriptors) { | 131 | for (const auto& desc : info.texture_descriptors) { |
| 130 | const VkSampler sampler{*(samplers++)}; | 132 | const VkSampler sampler{*(samplers++)}; |
| 131 | ImageView& image_view{texture_cache.GetImageView(*(image_view_ids++))}; | 133 | ImageView& image_view{texture_cache.GetImageView(*(image_view_ids++))}; |
diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp index 3d690f335..3c907ec5a 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp | |||
| @@ -97,10 +97,12 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute, | |||
| 97 | const u32 raw_handle{gpu_memory.Read<u32>(addr)}; | 97 | const u32 raw_handle{gpu_memory.Read<u32>(addr)}; |
| 98 | return TextureHandle(raw_handle, via_header_index); | 98 | return TextureHandle(raw_handle, via_header_index); |
| 99 | }}; | 99 | }}; |
| 100 | for (const auto& desc : info.texture_buffer_descriptors) { | 100 | const auto add_image{[&](const auto& desc) { |
| 101 | const TextureHandle handle{read_handle(desc.cbuf_index, desc.cbuf_offset)}; | 101 | const TextureHandle handle{read_handle(desc.cbuf_index, desc.cbuf_offset)}; |
| 102 | image_view_indices.push_back(handle.image); | 102 | image_view_indices.push_back(handle.image); |
| 103 | } | 103 | }}; |
| 104 | std::ranges::for_each(info.texture_buffer_descriptors, add_image); | ||
| 105 | std::ranges::for_each(info.image_buffer_descriptors, add_image); | ||
| 104 | for (const auto& desc : info.texture_descriptors) { | 106 | for (const auto& desc : info.texture_descriptors) { |
| 105 | const TextureHandle handle{read_handle(desc.cbuf_index, desc.cbuf_offset)}; | 107 | const TextureHandle handle{read_handle(desc.cbuf_index, desc.cbuf_offset)}; |
| 106 | image_view_indices.push_back(handle.image); | 108 | image_view_indices.push_back(handle.image); |
| @@ -108,24 +110,29 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute, | |||
| 108 | Sampler* const sampler = texture_cache.GetComputeSampler(handle.sampler); | 110 | Sampler* const sampler = texture_cache.GetComputeSampler(handle.sampler); |
| 109 | samplers.push_back(sampler->Handle()); | 111 | samplers.push_back(sampler->Handle()); |
| 110 | } | 112 | } |
| 111 | for (const auto& desc : info.image_descriptors) { | 113 | std::ranges::for_each(info.image_descriptors, add_image); |
| 112 | const TextureHandle handle{read_handle(desc.cbuf_index, desc.cbuf_offset)}; | 114 | |
| 113 | image_view_indices.push_back(handle.image); | ||
| 114 | } | ||
| 115 | const std::span indices_span(image_view_indices.data(), image_view_indices.size()); | 115 | const std::span indices_span(image_view_indices.data(), image_view_indices.size()); |
| 116 | texture_cache.FillComputeImageViews(indices_span, image_view_ids); | 116 | texture_cache.FillComputeImageViews(indices_span, image_view_ids); |
| 117 | 117 | ||
| 118 | buffer_cache.UnbindComputeTextureBuffers(); | 118 | buffer_cache.UnbindComputeTextureBuffers(); |
| 119 | ImageId* texture_buffer_ids{image_view_ids.data()}; | 119 | ImageId* texture_buffer_ids{image_view_ids.data()}; |
| 120 | size_t index{}; | 120 | size_t index{}; |
| 121 | for (const auto& desc : info.texture_buffer_descriptors) { | 121 | const auto add_buffer{[&](const auto& desc) { |
| 122 | ASSERT(desc.count == 1); | 122 | ASSERT(desc.count == 1); |
| 123 | bool is_written{false}; | ||
| 124 | if constexpr (std::is_same_v<decltype(desc), const Shader::ImageBufferDescriptor&>) { | ||
| 125 | is_written = desc.is_written; | ||
| 126 | } | ||
| 123 | ImageView& image_view = texture_cache.GetImageView(*texture_buffer_ids); | 127 | ImageView& image_view = texture_cache.GetImageView(*texture_buffer_ids); |
| 124 | buffer_cache.BindComputeTextureBuffer(index, image_view.GpuAddr(), image_view.BufferSize(), | 128 | buffer_cache.BindComputeTextureBuffer(index, image_view.GpuAddr(), image_view.BufferSize(), |
| 125 | image_view.format); | 129 | image_view.format, is_written); |
| 126 | ++texture_buffer_ids; | 130 | ++texture_buffer_ids; |
| 127 | ++index; | 131 | ++index; |
| 128 | } | 132 | }}; |
| 133 | std::ranges::for_each(info.texture_buffer_descriptors, add_buffer); | ||
| 134 | std::ranges::for_each(info.image_buffer_descriptors, add_buffer); | ||
| 135 | |||
| 129 | buffer_cache.UpdateComputeBuffers(); | 136 | buffer_cache.UpdateComputeBuffers(); |
| 130 | buffer_cache.BindHostComputeBuffers(); | 137 | buffer_cache.BindHostComputeBuffers(); |
| 131 | 138 | ||
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 23c01f24e..84720a6f9 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp | |||
| @@ -175,10 +175,12 @@ void GraphicsPipeline::Configure(bool is_indexed) { | |||
| 175 | const u32 raw_handle{gpu_memory.Read<u32>(addr)}; | 175 | const u32 raw_handle{gpu_memory.Read<u32>(addr)}; |
| 176 | return TextureHandle(raw_handle, via_header_index); | 176 | return TextureHandle(raw_handle, via_header_index); |
| 177 | }}; | 177 | }}; |
| 178 | for (const auto& desc : info.texture_buffer_descriptors) { | 178 | const auto add_image{[&](const auto& desc) { |
| 179 | const TextureHandle handle{read_handle(desc.cbuf_index, desc.cbuf_offset)}; | 179 | const TextureHandle handle{read_handle(desc.cbuf_index, desc.cbuf_offset)}; |
| 180 | image_view_indices.push_back(handle.image); | 180 | image_view_indices.push_back(handle.image); |
| 181 | } | 181 | }}; |
| 182 | std::ranges::for_each(info.texture_buffer_descriptors, add_image); | ||
| 183 | std::ranges::for_each(info.image_buffer_descriptors, add_image); | ||
| 182 | for (const auto& desc : info.texture_descriptors) { | 184 | for (const auto& desc : info.texture_descriptors) { |
| 183 | const TextureHandle handle{read_handle(desc.cbuf_index, desc.cbuf_offset)}; | 185 | const TextureHandle handle{read_handle(desc.cbuf_index, desc.cbuf_offset)}; |
| 184 | image_view_indices.push_back(handle.image); | 186 | image_view_indices.push_back(handle.image); |
| @@ -186,28 +188,33 @@ void GraphicsPipeline::Configure(bool is_indexed) { | |||
| 186 | Sampler* const sampler{texture_cache.GetGraphicsSampler(handle.sampler)}; | 188 | Sampler* const sampler{texture_cache.GetGraphicsSampler(handle.sampler)}; |
| 187 | samplers.push_back(sampler->Handle()); | 189 | samplers.push_back(sampler->Handle()); |
| 188 | } | 190 | } |
| 189 | for (const auto& desc : info.image_descriptors) { | 191 | std::ranges::for_each(info.image_descriptors, add_image); |
| 190 | const TextureHandle handle{read_handle(desc.cbuf_index, desc.cbuf_offset)}; | ||
| 191 | image_view_indices.push_back(handle.image); | ||
| 192 | } | ||
| 193 | } | 192 | } |
| 194 | const std::span indices_span(image_view_indices.data(), image_view_indices.size()); | 193 | const std::span indices_span(image_view_indices.data(), image_view_indices.size()); |
| 195 | texture_cache.FillGraphicsImageViews(indices_span, image_view_ids); | 194 | texture_cache.FillGraphicsImageViews(indices_span, image_view_ids); |
| 196 | 195 | ||
| 197 | ImageId* texture_buffer_index{image_view_ids.data()}; | 196 | ImageId* texture_buffer_index{image_view_ids.data()}; |
| 198 | for (size_t stage = 0; stage < Maxwell::MaxShaderStage; ++stage) { | 197 | for (size_t stage = 0; stage < Maxwell::MaxShaderStage; ++stage) { |
| 199 | const Shader::Info& info{stage_infos[stage]}; | ||
| 200 | buffer_cache.UnbindGraphicsTextureBuffers(stage); | ||
| 201 | size_t index{}; | 198 | size_t index{}; |
| 202 | for (const auto& desc : info.texture_buffer_descriptors) { | 199 | const auto add_buffer{[&](const auto& desc) { |
| 203 | ASSERT(desc.count == 1); | 200 | ASSERT(desc.count == 1); |
| 204 | ImageView& image_view = texture_cache.GetImageView(*texture_buffer_index); | 201 | bool is_written{false}; |
| 202 | if constexpr (std::is_same_v<decltype(desc), const Shader::ImageBufferDescriptor&>) { | ||
| 203 | is_written = desc.is_written; | ||
| 204 | } | ||
| 205 | ImageView& image_view{texture_cache.GetImageView(*texture_buffer_index)}; | ||
| 205 | buffer_cache.BindGraphicsTextureBuffer(stage, index, image_view.GpuAddr(), | 206 | buffer_cache.BindGraphicsTextureBuffer(stage, index, image_view.GpuAddr(), |
| 206 | image_view.BufferSize(), image_view.format); | 207 | image_view.BufferSize(), image_view.format, |
| 208 | is_written); | ||
| 207 | ++index; | 209 | ++index; |
| 208 | ++texture_buffer_index; | 210 | ++texture_buffer_index; |
| 209 | } | 211 | }}; |
| 212 | const Shader::Info& info{stage_infos[stage]}; | ||
| 213 | buffer_cache.UnbindGraphicsTextureBuffers(stage); | ||
| 214 | std::ranges::for_each(info.texture_buffer_descriptors, add_buffer); | ||
| 215 | std::ranges::for_each(info.image_buffer_descriptors, add_buffer); | ||
| 210 | texture_buffer_index += info.texture_descriptors.size(); | 216 | texture_buffer_index += info.texture_descriptors.size(); |
| 217 | texture_buffer_index += info.image_descriptors.size(); | ||
| 211 | } | 218 | } |
| 212 | buffer_cache.UpdateGraphicsBuffers(is_indexed); | 219 | buffer_cache.UpdateGraphicsBuffers(is_indexed); |
| 213 | 220 | ||