summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_vulkan/vk_compute_pipeline.cpp3
-rw-r--r--src/video_core/renderer_vulkan/vk_descriptor_pool.cpp1
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp16
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp48
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.h16
-rw-r--r--src/video_core/renderer_vulkan/vk_shader_decompiler.cpp75
-rw-r--r--src/video_core/renderer_vulkan/vk_shader_decompiler.h9
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp4
8 files changed, 120 insertions, 52 deletions
diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp
index 8e1b46277..281bf9ac3 100644
--- a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp
+++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp
@@ -53,8 +53,9 @@ vk::DescriptorSetLayout VKComputePipeline::CreateDescriptorSetLayout() const {
53 }; 53 };
54 add_bindings(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, entries.const_buffers.size()); 54 add_bindings(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, entries.const_buffers.size());
55 add_bindings(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, entries.global_buffers.size()); 55 add_bindings(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, entries.global_buffers.size());
56 add_bindings(VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, entries.texel_buffers.size()); 56 add_bindings(VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, entries.uniform_texels.size());
57 add_bindings(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, entries.samplers.size()); 57 add_bindings(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, entries.samplers.size());
58 add_bindings(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, entries.storage_texels.size());
58 add_bindings(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, entries.images.size()); 59 add_bindings(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, entries.images.size());
59 60
60 VkDescriptorSetLayoutCreateInfo ci; 61 VkDescriptorSetLayoutCreateInfo ci;
diff --git a/src/video_core/renderer_vulkan/vk_descriptor_pool.cpp b/src/video_core/renderer_vulkan/vk_descriptor_pool.cpp
index 890fd52cf..9259b618d 100644
--- a/src/video_core/renderer_vulkan/vk_descriptor_pool.cpp
+++ b/src/video_core/renderer_vulkan/vk_descriptor_pool.cpp
@@ -42,6 +42,7 @@ vk::DescriptorPool* VKDescriptorPool::AllocateNewPool() {
42 {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, num_sets * 60}, 42 {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, num_sets * 60},
43 {VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, num_sets * 64}, 43 {VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, num_sets * 64},
44 {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, num_sets * 64}, 44 {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, num_sets * 64},
45 {VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, num_sets * 64},
45 {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, num_sets * 40}}; 46 {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, num_sets * 40}};
46 47
47 VkDescriptorPoolCreateInfo ci; 48 VkDescriptorPoolCreateInfo ci;
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index 65a1c6245..b8ccf164f 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -45,6 +45,7 @@ constexpr VkDescriptorType UNIFORM_BUFFER = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
45constexpr VkDescriptorType STORAGE_BUFFER = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; 45constexpr VkDescriptorType STORAGE_BUFFER = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
46constexpr VkDescriptorType UNIFORM_TEXEL_BUFFER = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; 46constexpr VkDescriptorType UNIFORM_TEXEL_BUFFER = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
47constexpr VkDescriptorType COMBINED_IMAGE_SAMPLER = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 47constexpr VkDescriptorType COMBINED_IMAGE_SAMPLER = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
48constexpr VkDescriptorType STORAGE_TEXEL_BUFFER = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
48constexpr VkDescriptorType STORAGE_IMAGE = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; 49constexpr VkDescriptorType STORAGE_IMAGE = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
49 50
50constexpr VideoCommon::Shader::CompilerSettings compiler_settings{ 51constexpr VideoCommon::Shader::CompilerSettings compiler_settings{
@@ -104,8 +105,9 @@ u32 FillDescriptorLayout(const ShaderEntries& entries,
104 u32 binding = base_binding; 105 u32 binding = base_binding;
105 AddBindings<UNIFORM_BUFFER>(bindings, binding, flags, entries.const_buffers); 106 AddBindings<UNIFORM_BUFFER>(bindings, binding, flags, entries.const_buffers);
106 AddBindings<STORAGE_BUFFER>(bindings, binding, flags, entries.global_buffers); 107 AddBindings<STORAGE_BUFFER>(bindings, binding, flags, entries.global_buffers);
107 AddBindings<UNIFORM_TEXEL_BUFFER>(bindings, binding, flags, entries.texel_buffers); 108 AddBindings<UNIFORM_TEXEL_BUFFER>(bindings, binding, flags, entries.uniform_texels);
108 AddBindings<COMBINED_IMAGE_SAMPLER>(bindings, binding, flags, entries.samplers); 109 AddBindings<COMBINED_IMAGE_SAMPLER>(bindings, binding, flags, entries.samplers);
110 AddBindings<STORAGE_TEXEL_BUFFER>(bindings, binding, flags, entries.storage_texels);
109 AddBindings<STORAGE_IMAGE>(bindings, binding, flags, entries.images); 111 AddBindings<STORAGE_IMAGE>(bindings, binding, flags, entries.images);
110 return binding; 112 return binding;
111} 113}
@@ -377,16 +379,17 @@ void AddEntry(std::vector<VkDescriptorUpdateTemplateEntry>& template_entries, u3
377 return; 379 return;
378 } 380 }
379 381
380 if constexpr (descriptor_type == UNIFORM_TEXEL_BUFFER) { 382 if constexpr (descriptor_type == UNIFORM_TEXEL_BUFFER ||
381 // Nvidia has a bug where updating multiple uniform texels at once causes the driver to 383 descriptor_type == STORAGE_TEXEL_BUFFER) {
382 // crash. 384 // Nvidia has a bug where updating multiple texels at once causes the driver to crash.
385 // Note: Fixed in driver Windows 443.24, Linux 440.66.15
383 for (u32 i = 0; i < count; ++i) { 386 for (u32 i = 0; i < count; ++i) {
384 VkDescriptorUpdateTemplateEntry& entry = template_entries.emplace_back(); 387 VkDescriptorUpdateTemplateEntry& entry = template_entries.emplace_back();
385 entry.dstBinding = binding + i; 388 entry.dstBinding = binding + i;
386 entry.dstArrayElement = 0; 389 entry.dstArrayElement = 0;
387 entry.descriptorCount = 1; 390 entry.descriptorCount = 1;
388 entry.descriptorType = descriptor_type; 391 entry.descriptorType = descriptor_type;
389 entry.offset = offset + i * entry_size; 392 entry.offset = static_cast<std::size_t>(offset + i * entry_size);
390 entry.stride = entry_size; 393 entry.stride = entry_size;
391 } 394 }
392 } else if (count > 0) { 395 } else if (count > 0) {
@@ -407,8 +410,9 @@ void FillDescriptorUpdateTemplateEntries(
407 std::vector<VkDescriptorUpdateTemplateEntryKHR>& template_entries) { 410 std::vector<VkDescriptorUpdateTemplateEntryKHR>& template_entries) {
408 AddEntry<UNIFORM_BUFFER>(template_entries, offset, binding, entries.const_buffers); 411 AddEntry<UNIFORM_BUFFER>(template_entries, offset, binding, entries.const_buffers);
409 AddEntry<STORAGE_BUFFER>(template_entries, offset, binding, entries.global_buffers); 412 AddEntry<STORAGE_BUFFER>(template_entries, offset, binding, entries.global_buffers);
410 AddEntry<UNIFORM_TEXEL_BUFFER>(template_entries, offset, binding, entries.texel_buffers); 413 AddEntry<UNIFORM_TEXEL_BUFFER>(template_entries, offset, binding, entries.uniform_texels);
411 AddEntry<COMBINED_IMAGE_SAMPLER>(template_entries, offset, binding, entries.samplers); 414 AddEntry<COMBINED_IMAGE_SAMPLER>(template_entries, offset, binding, entries.samplers);
415 AddEntry<STORAGE_TEXEL_BUFFER>(template_entries, offset, binding, entries.storage_texels);
412 AddEntry<STORAGE_IMAGE>(template_entries, offset, binding, entries.images); 416 AddEntry<STORAGE_IMAGE>(template_entries, offset, binding, entries.images);
413} 417}
414 418
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index a3d992ed3..b44b5237a 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -468,8 +468,9 @@ void RasterizerVulkan::DispatchCompute(GPUVAddr code_addr) {
468 const auto& entries = pipeline.GetEntries(); 468 const auto& entries = pipeline.GetEntries();
469 SetupComputeConstBuffers(entries); 469 SetupComputeConstBuffers(entries);
470 SetupComputeGlobalBuffers(entries); 470 SetupComputeGlobalBuffers(entries);
471 SetupComputeTexelBuffers(entries); 471 SetupComputeUniformTexels(entries);
472 SetupComputeTextures(entries); 472 SetupComputeTextures(entries);
473 SetupComputeStorageTexels(entries);
473 SetupComputeImages(entries); 474 SetupComputeImages(entries);
474 475
475 buffer_cache.Unmap(); 476 buffer_cache.Unmap();
@@ -787,8 +788,9 @@ void RasterizerVulkan::SetupShaderDescriptors(
787 const auto& entries = shader->GetEntries(); 788 const auto& entries = shader->GetEntries();
788 SetupGraphicsConstBuffers(entries, stage); 789 SetupGraphicsConstBuffers(entries, stage);
789 SetupGraphicsGlobalBuffers(entries, stage); 790 SetupGraphicsGlobalBuffers(entries, stage);
790 SetupGraphicsTexelBuffers(entries, stage); 791 SetupGraphicsUniformTexels(entries, stage);
791 SetupGraphicsTextures(entries, stage); 792 SetupGraphicsTextures(entries, stage);
793 SetupGraphicsStorageTexels(entries, stage);
792 SetupGraphicsImages(entries, stage); 794 SetupGraphicsImages(entries, stage);
793 } 795 }
794 texture_cache.GuardSamplers(false); 796 texture_cache.GuardSamplers(false);
@@ -976,12 +978,12 @@ void RasterizerVulkan::SetupGraphicsGlobalBuffers(const ShaderEntries& entries,
976 } 978 }
977} 979}
978 980
979void RasterizerVulkan::SetupGraphicsTexelBuffers(const ShaderEntries& entries, std::size_t stage) { 981void RasterizerVulkan::SetupGraphicsUniformTexels(const ShaderEntries& entries, std::size_t stage) {
980 MICROPROFILE_SCOPE(Vulkan_Textures); 982 MICROPROFILE_SCOPE(Vulkan_Textures);
981 const auto& gpu = system.GPU().Maxwell3D(); 983 const auto& gpu = system.GPU().Maxwell3D();
982 for (const auto& entry : entries.texel_buffers) { 984 for (const auto& entry : entries.uniform_texels) {
983 const auto image = GetTextureInfo(gpu, entry, stage).tic; 985 const auto image = GetTextureInfo(gpu, entry, stage).tic;
984 SetupTexelBuffer(image, entry); 986 SetupUniformTexels(image, entry);
985 } 987 }
986} 988}
987 989
@@ -996,6 +998,15 @@ void RasterizerVulkan::SetupGraphicsTextures(const ShaderEntries& entries, std::
996 } 998 }
997} 999}
998 1000
1001void RasterizerVulkan::SetupGraphicsStorageTexels(const ShaderEntries& entries, std::size_t stage) {
1002 MICROPROFILE_SCOPE(Vulkan_Textures);
1003 const auto& gpu = system.GPU().Maxwell3D();
1004 for (const auto& entry : entries.storage_texels) {
1005 const auto image = GetTextureInfo(gpu, entry, stage).tic;
1006 SetupStorageTexel(image, entry);
1007 }
1008}
1009
999void RasterizerVulkan::SetupGraphicsImages(const ShaderEntries& entries, std::size_t stage) { 1010void RasterizerVulkan::SetupGraphicsImages(const ShaderEntries& entries, std::size_t stage) {
1000 MICROPROFILE_SCOPE(Vulkan_Images); 1011 MICROPROFILE_SCOPE(Vulkan_Images);
1001 const auto& gpu = system.GPU().Maxwell3D(); 1012 const auto& gpu = system.GPU().Maxwell3D();
@@ -1028,12 +1039,12 @@ void RasterizerVulkan::SetupComputeGlobalBuffers(const ShaderEntries& entries) {
1028 } 1039 }
1029} 1040}
1030 1041
1031void RasterizerVulkan::SetupComputeTexelBuffers(const ShaderEntries& entries) { 1042void RasterizerVulkan::SetupComputeUniformTexels(const ShaderEntries& entries) {
1032 MICROPROFILE_SCOPE(Vulkan_Textures); 1043 MICROPROFILE_SCOPE(Vulkan_Textures);
1033 const auto& gpu = system.GPU().KeplerCompute(); 1044 const auto& gpu = system.GPU().KeplerCompute();
1034 for (const auto& entry : entries.texel_buffers) { 1045 for (const auto& entry : entries.uniform_texels) {
1035 const auto image = GetTextureInfo(gpu, entry, ComputeShaderIndex).tic; 1046 const auto image = GetTextureInfo(gpu, entry, ComputeShaderIndex).tic;
1036 SetupTexelBuffer(image, entry); 1047 SetupUniformTexels(image, entry);
1037 } 1048 }
1038} 1049}
1039 1050
@@ -1048,6 +1059,15 @@ void RasterizerVulkan::SetupComputeTextures(const ShaderEntries& entries) {
1048 } 1059 }
1049} 1060}
1050 1061
1062void RasterizerVulkan::SetupComputeStorageTexels(const ShaderEntries& entries) {
1063 MICROPROFILE_SCOPE(Vulkan_Textures);
1064 const auto& gpu = system.GPU().KeplerCompute();
1065 for (const auto& entry : entries.storage_texels) {
1066 const auto image = GetTextureInfo(gpu, entry, ComputeShaderIndex).tic;
1067 SetupStorageTexel(image, entry);
1068 }
1069}
1070
1051void RasterizerVulkan::SetupComputeImages(const ShaderEntries& entries) { 1071void RasterizerVulkan::SetupComputeImages(const ShaderEntries& entries) {
1052 MICROPROFILE_SCOPE(Vulkan_Images); 1072 MICROPROFILE_SCOPE(Vulkan_Images);
1053 const auto& gpu = system.GPU().KeplerCompute(); 1073 const auto& gpu = system.GPU().KeplerCompute();
@@ -1097,8 +1117,8 @@ void RasterizerVulkan::SetupGlobalBuffer(const GlobalBufferEntry& entry, GPUVAdd
1097 update_descriptor_queue.AddBuffer(buffer, offset, size); 1117 update_descriptor_queue.AddBuffer(buffer, offset, size);
1098} 1118}
1099 1119
1100void RasterizerVulkan::SetupTexelBuffer(const Tegra::Texture::TICEntry& tic, 1120void RasterizerVulkan::SetupUniformTexels(const Tegra::Texture::TICEntry& tic,
1101 const TexelBufferEntry& entry) { 1121 const UniformTexelEntry& entry) {
1102 const auto view = texture_cache.GetTextureSurface(tic, entry); 1122 const auto view = texture_cache.GetTextureSurface(tic, entry);
1103 ASSERT(view->IsBufferView()); 1123 ASSERT(view->IsBufferView());
1104 1124
@@ -1120,6 +1140,14 @@ void RasterizerVulkan::SetupTexture(const Tegra::Texture::FullTextureInfo& textu
1120 sampled_views.push_back(ImageView{std::move(view), image_layout}); 1140 sampled_views.push_back(ImageView{std::move(view), image_layout});
1121} 1141}
1122 1142
1143void RasterizerVulkan::SetupStorageTexel(const Tegra::Texture::TICEntry& tic,
1144 const StorageTexelEntry& entry) {
1145 const auto view = texture_cache.GetImageSurface(tic, entry);
1146 ASSERT(view->IsBufferView());
1147
1148 update_descriptor_queue.AddTexelBuffer(view->GetBufferView());
1149}
1150
1123void RasterizerVulkan::SetupImage(const Tegra::Texture::TICEntry& tic, const ImageEntry& entry) { 1151void RasterizerVulkan::SetupImage(const Tegra::Texture::TICEntry& tic, const ImageEntry& entry) {
1124 auto view = texture_cache.GetImageSurface(tic, entry); 1152 auto view = texture_cache.GetImageSurface(tic, entry);
1125 1153
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h
index 0ed0e48c6..04be37a5e 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.h
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.h
@@ -193,12 +193,15 @@ private:
193 /// Setup global buffers in the graphics pipeline. 193 /// Setup global buffers in the graphics pipeline.
194 void SetupGraphicsGlobalBuffers(const ShaderEntries& entries, std::size_t stage); 194 void SetupGraphicsGlobalBuffers(const ShaderEntries& entries, std::size_t stage);
195 195
196 /// Setup texel buffers in the graphics pipeline. 196 /// Setup uniform texels in the graphics pipeline.
197 void SetupGraphicsTexelBuffers(const ShaderEntries& entries, std::size_t stage); 197 void SetupGraphicsUniformTexels(const ShaderEntries& entries, std::size_t stage);
198 198
199 /// Setup textures in the graphics pipeline. 199 /// Setup textures in the graphics pipeline.
200 void SetupGraphicsTextures(const ShaderEntries& entries, std::size_t stage); 200 void SetupGraphicsTextures(const ShaderEntries& entries, std::size_t stage);
201 201
202 /// Setup storage texels in the graphics pipeline.
203 void SetupGraphicsStorageTexels(const ShaderEntries& entries, std::size_t stage);
204
202 /// Setup images in the graphics pipeline. 205 /// Setup images in the graphics pipeline.
203 void SetupGraphicsImages(const ShaderEntries& entries, std::size_t stage); 206 void SetupGraphicsImages(const ShaderEntries& entries, std::size_t stage);
204 207
@@ -209,11 +212,14 @@ private:
209 void SetupComputeGlobalBuffers(const ShaderEntries& entries); 212 void SetupComputeGlobalBuffers(const ShaderEntries& entries);
210 213
211 /// Setup texel buffers in the compute pipeline. 214 /// Setup texel buffers in the compute pipeline.
212 void SetupComputeTexelBuffers(const ShaderEntries& entries); 215 void SetupComputeUniformTexels(const ShaderEntries& entries);
213 216
214 /// Setup textures in the compute pipeline. 217 /// Setup textures in the compute pipeline.
215 void SetupComputeTextures(const ShaderEntries& entries); 218 void SetupComputeTextures(const ShaderEntries& entries);
216 219
220 /// Setup storage texels in the compute pipeline.
221 void SetupComputeStorageTexels(const ShaderEntries& entries);
222
217 /// Setup images in the compute pipeline. 223 /// Setup images in the compute pipeline.
218 void SetupComputeImages(const ShaderEntries& entries); 224 void SetupComputeImages(const ShaderEntries& entries);
219 225
@@ -222,10 +228,12 @@ private:
222 228
223 void SetupGlobalBuffer(const GlobalBufferEntry& entry, GPUVAddr address); 229 void SetupGlobalBuffer(const GlobalBufferEntry& entry, GPUVAddr address);
224 230
225 void SetupTexelBuffer(const Tegra::Texture::TICEntry& image, const TexelBufferEntry& entry); 231 void SetupUniformTexels(const Tegra::Texture::TICEntry& image, const UniformTexelEntry& entry);
226 232
227 void SetupTexture(const Tegra::Texture::FullTextureInfo& texture, const SamplerEntry& entry); 233 void SetupTexture(const Tegra::Texture::FullTextureInfo& texture, const SamplerEntry& entry);
228 234
235 void SetupStorageTexel(const Tegra::Texture::TICEntry& tic, const StorageTexelEntry& entry);
236
229 void SetupImage(const Tegra::Texture::TICEntry& tic, const ImageEntry& entry); 237 void SetupImage(const Tegra::Texture::TICEntry& tic, const ImageEntry& entry);
230 238
231 void UpdateViewportsState(Tegra::Engines::Maxwell3D::Regs& regs); 239 void UpdateViewportsState(Tegra::Engines::Maxwell3D::Regs& regs);
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
index a13e8baa7..b9128bd38 100644
--- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
+++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
@@ -400,8 +400,9 @@ private:
400 u32 binding = specialization.base_binding; 400 u32 binding = specialization.base_binding;
401 binding = DeclareConstantBuffers(binding); 401 binding = DeclareConstantBuffers(binding);
402 binding = DeclareGlobalBuffers(binding); 402 binding = DeclareGlobalBuffers(binding);
403 binding = DeclareTexelBuffers(binding); 403 binding = DeclareUniformTexels(binding);
404 binding = DeclareSamplers(binding); 404 binding = DeclareSamplers(binding);
405 binding = DeclareStorageTexels(binding);
405 binding = DeclareImages(binding); 406 binding = DeclareImages(binding);
406 407
407 const Id main = OpFunction(t_void, {}, TypeFunction(t_void)); 408 const Id main = OpFunction(t_void, {}, TypeFunction(t_void));
@@ -889,7 +890,7 @@ private:
889 return binding; 890 return binding;
890 } 891 }
891 892
892 u32 DeclareTexelBuffers(u32 binding) { 893 u32 DeclareUniformTexels(u32 binding) {
893 for (const auto& sampler : ir.GetSamplers()) { 894 for (const auto& sampler : ir.GetSamplers()) {
894 if (!sampler.is_buffer) { 895 if (!sampler.is_buffer) {
895 continue; 896 continue;
@@ -910,7 +911,7 @@ private:
910 Decorate(id, spv::Decoration::Binding, binding++); 911 Decorate(id, spv::Decoration::Binding, binding++);
911 Decorate(id, spv::Decoration::DescriptorSet, DESCRIPTOR_SET); 912 Decorate(id, spv::Decoration::DescriptorSet, DESCRIPTOR_SET);
912 913
913 texel_buffers.emplace(sampler.index, TexelBuffer{image_type, id}); 914 uniform_texels.emplace(sampler.index, TexelBuffer{image_type, id});
914 } 915 }
915 return binding; 916 return binding;
916 } 917 }
@@ -945,31 +946,48 @@ private:
945 return binding; 946 return binding;
946 } 947 }
947 948
948 u32 DeclareImages(u32 binding) { 949 u32 DeclareStorageTexels(u32 binding) {
949 for (const auto& image : ir.GetImages()) { 950 for (const auto& image : ir.GetImages()) {
950 const auto [dim, arrayed] = GetImageDim(image); 951 if (image.type != Tegra::Shader::ImageType::TextureBuffer) {
951 constexpr int depth = 0; 952 continue;
952 constexpr bool ms = false;
953 constexpr int sampled = 2; // This won't be accessed with a sampler
954 constexpr auto format = spv::ImageFormat::Unknown;
955 const Id image_type = TypeImage(t_uint, dim, depth, arrayed, ms, sampled, format, {});
956 const Id pointer_type = TypePointer(spv::StorageClass::UniformConstant, image_type);
957 const Id id = OpVariable(pointer_type, spv::StorageClass::UniformConstant);
958 AddGlobalVariable(Name(id, fmt::format("image_{}", image.index)));
959
960 Decorate(id, spv::Decoration::Binding, binding++);
961 Decorate(id, spv::Decoration::DescriptorSet, DESCRIPTOR_SET);
962 if (image.is_read && !image.is_written) {
963 Decorate(id, spv::Decoration::NonWritable);
964 } else if (image.is_written && !image.is_read) {
965 Decorate(id, spv::Decoration::NonReadable);
966 } 953 }
954 DeclareImage(image, binding);
955 }
956 return binding;
957 }
967 958
968 images.emplace(image.index, StorageImage{image_type, id}); 959 u32 DeclareImages(u32 binding) {
960 for (const auto& image : ir.GetImages()) {
961 if (image.type == Tegra::Shader::ImageType::TextureBuffer) {
962 continue;
963 }
964 DeclareImage(image, binding);
969 } 965 }
970 return binding; 966 return binding;
971 } 967 }
972 968
969 void DeclareImage(const Image& image, u32& binding) {
970 const auto [dim, arrayed] = GetImageDim(image);
971 constexpr int depth = 0;
972 constexpr bool ms = false;
973 constexpr int sampled = 2; // This won't be accessed with a sampler
974 constexpr auto format = spv::ImageFormat::Unknown;
975 const Id image_type = TypeImage(t_uint, dim, depth, arrayed, ms, sampled, format, {});
976 const Id pointer_type = TypePointer(spv::StorageClass::UniformConstant, image_type);
977 const Id id = OpVariable(pointer_type, spv::StorageClass::UniformConstant);
978 AddGlobalVariable(Name(id, fmt::format("image_{}", image.index)));
979
980 Decorate(id, spv::Decoration::Binding, binding++);
981 Decorate(id, spv::Decoration::DescriptorSet, DESCRIPTOR_SET);
982 if (image.is_read && !image.is_written) {
983 Decorate(id, spv::Decoration::NonWritable);
984 } else if (image.is_written && !image.is_read) {
985 Decorate(id, spv::Decoration::NonReadable);
986 }
987
988 images.emplace(image.index, StorageImage{image_type, id});
989 }
990
973 bool IsRenderTargetEnabled(u32 rt) const { 991 bool IsRenderTargetEnabled(u32 rt) const {
974 for (u32 component = 0; component < 4; ++component) { 992 for (u32 component = 0; component < 4; ++component) {
975 if (header.ps.IsColorComponentOutputEnabled(rt, component)) { 993 if (header.ps.IsColorComponentOutputEnabled(rt, component)) {
@@ -1674,7 +1692,7 @@ private:
1674 const auto& meta = std::get<MetaTexture>(operation.GetMeta()); 1692 const auto& meta = std::get<MetaTexture>(operation.GetMeta());
1675 const u32 index = meta.sampler.index; 1693 const u32 index = meta.sampler.index;
1676 if (meta.sampler.is_buffer) { 1694 if (meta.sampler.is_buffer) {
1677 const auto& entry = texel_buffers.at(index); 1695 const auto& entry = uniform_texels.at(index);
1678 return OpLoad(entry.image_type, entry.image); 1696 return OpLoad(entry.image_type, entry.image);
1679 } else { 1697 } else {
1680 const auto& entry = sampled_images.at(index); 1698 const auto& entry = sampled_images.at(index);
@@ -2794,15 +2812,16 @@ private:
2794 std::unordered_map<u8, GenericVaryingDescription> output_attributes; 2812 std::unordered_map<u8, GenericVaryingDescription> output_attributes;
2795 std::map<u32, Id> constant_buffers; 2813 std::map<u32, Id> constant_buffers;
2796 std::map<GlobalMemoryBase, Id> global_buffers; 2814 std::map<GlobalMemoryBase, Id> global_buffers;
2797 std::map<u32, TexelBuffer> texel_buffers; 2815 std::map<u32, TexelBuffer> uniform_texels;
2798 std::map<u32, SampledImage> sampled_images; 2816 std::map<u32, SampledImage> sampled_images;
2817 std::map<u32, TexelBuffer> storage_texels;
2799 std::map<u32, StorageImage> images; 2818 std::map<u32, StorageImage> images;
2800 2819
2820 std::array<Id, Maxwell::NumRenderTargets> frag_colors{};
2801 Id instance_index{}; 2821 Id instance_index{};
2802 Id vertex_index{}; 2822 Id vertex_index{};
2803 Id base_instance{}; 2823 Id base_instance{};
2804 Id base_vertex{}; 2824 Id base_vertex{};
2805 std::array<Id, Maxwell::NumRenderTargets> frag_colors{};
2806 Id frag_depth{}; 2825 Id frag_depth{};
2807 Id frag_coord{}; 2826 Id frag_coord{};
2808 Id front_facing{}; 2827 Id front_facing{};
@@ -3058,13 +3077,17 @@ ShaderEntries GenerateShaderEntries(const VideoCommon::Shader::ShaderIR& ir) {
3058 } 3077 }
3059 for (const auto& sampler : ir.GetSamplers()) { 3078 for (const auto& sampler : ir.GetSamplers()) {
3060 if (sampler.is_buffer) { 3079 if (sampler.is_buffer) {
3061 entries.texel_buffers.emplace_back(sampler); 3080 entries.uniform_texels.emplace_back(sampler);
3062 } else { 3081 } else {
3063 entries.samplers.emplace_back(sampler); 3082 entries.samplers.emplace_back(sampler);
3064 } 3083 }
3065 } 3084 }
3066 for (const auto& image : ir.GetImages()) { 3085 for (const auto& image : ir.GetImages()) {
3067 entries.images.emplace_back(image); 3086 if (image.type == Tegra::Shader::ImageType::TextureBuffer) {
3087 entries.storage_texels.emplace_back(image);
3088 } else {
3089 entries.images.emplace_back(image);
3090 }
3068 } 3091 }
3069 for (const auto& attribute : ir.GetInputAttributes()) { 3092 for (const auto& attribute : ir.GetInputAttributes()) {
3070 if (IsGenericAttribute(attribute)) { 3093 if (IsGenericAttribute(attribute)) {
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.h b/src/video_core/renderer_vulkan/vk_shader_decompiler.h
index b7af26388..2b0e90396 100644
--- a/src/video_core/renderer_vulkan/vk_shader_decompiler.h
+++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.h
@@ -21,8 +21,9 @@ class VKDevice;
21namespace Vulkan { 21namespace Vulkan {
22 22
23using Maxwell = Tegra::Engines::Maxwell3D::Regs; 23using Maxwell = Tegra::Engines::Maxwell3D::Regs;
24using TexelBufferEntry = VideoCommon::Shader::Sampler; 24using UniformTexelEntry = VideoCommon::Shader::Sampler;
25using SamplerEntry = VideoCommon::Shader::Sampler; 25using SamplerEntry = VideoCommon::Shader::Sampler;
26using StorageTexelEntry = VideoCommon::Shader::Image;
26using ImageEntry = VideoCommon::Shader::Image; 27using ImageEntry = VideoCommon::Shader::Image;
27 28
28constexpr u32 DESCRIPTOR_SET = 0; 29constexpr u32 DESCRIPTOR_SET = 0;
@@ -66,13 +67,15 @@ private:
66struct ShaderEntries { 67struct ShaderEntries {
67 u32 NumBindings() const { 68 u32 NumBindings() const {
68 return static_cast<u32>(const_buffers.size() + global_buffers.size() + 69 return static_cast<u32>(const_buffers.size() + global_buffers.size() +
69 texel_buffers.size() + samplers.size() + images.size()); 70 uniform_texels.size() + samplers.size() + storage_texels.size() +
71 images.size());
70 } 72 }
71 73
72 std::vector<ConstBufferEntry> const_buffers; 74 std::vector<ConstBufferEntry> const_buffers;
73 std::vector<GlobalBufferEntry> global_buffers; 75 std::vector<GlobalBufferEntry> global_buffers;
74 std::vector<TexelBufferEntry> texel_buffers; 76 std::vector<UniformTexelEntry> uniform_texels;
75 std::vector<SamplerEntry> samplers; 77 std::vector<SamplerEntry> samplers;
78 std::vector<StorageTexelEntry> storage_texels;
76 std::vector<ImageEntry> images; 79 std::vector<ImageEntry> images;
77 std::set<u32> attributes; 80 std::set<u32> attributes;
78 std::array<bool, Maxwell::NumClipDistances> clip_distances{}; 81 std::array<bool, Maxwell::NumClipDistances> clip_distances{};
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index 2f1d5021d..ea487b770 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -100,8 +100,8 @@ vk::Buffer CreateBuffer(const VKDevice& device, const SurfaceParams& params,
100 ci.pNext = nullptr; 100 ci.pNext = nullptr;
101 ci.flags = 0; 101 ci.flags = 0;
102 ci.size = static_cast<VkDeviceSize>(host_memory_size); 102 ci.size = static_cast<VkDeviceSize>(host_memory_size);
103 ci.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | 103 ci.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT |
104 VK_BUFFER_USAGE_TRANSFER_DST_BIT; 104 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
105 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 105 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
106 ci.queueFamilyIndexCount = 0; 106 ci.queueFamilyIndexCount = 0;
107 ci.pQueueFamilyIndices = nullptr; 107 ci.pQueueFamilyIndices = nullptr;