summaryrefslogtreecommitdiff
path: root/src/video_core
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-04-14 21:36:36 -0300
committerGravatar ameerj2021-07-22 21:51:27 -0400
commit416e1b7441d34512fcb0ffed014daf7ca4bb62bd (patch)
treefa14781ad4969613919a8bcd68b887b9b7a98304 /src/video_core
parentspirv: Implement Layer stores (diff)
downloadyuzu-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.h24
-rw-r--r--src/video_core/renderer_vulkan/pipeline_helper.h2
-rw-r--r--src/video_core/renderer_vulkan/vk_compute_pipeline.cpp25
-rw-r--r--src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp31
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,
700template <class P> 702template <class P>
701void BufferCache<P>::UnbindGraphicsTextureBuffers(size_t stage) { 703void 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
705template <class P> 708template <class P>
706void BufferCache<P>::BindGraphicsTextureBuffer(size_t stage, size_t tbo_index, GPUVAddr gpu_addr, 709void 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,
732template <class P> 736template <class P>
733void BufferCache<P>::UnbindComputeTextureBuffers() { 737void 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
737template <class P> 742template <class P>
738void BufferCache<P>::BindComputeTextureBuffer(size_t tbo_index, GPUVAddr gpu_addr, u32 size, 743void 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