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.cpp137
-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, 143 insertions, 91 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 86328237e..d86c46412 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);
@@ -983,12 +985,12 @@ void RasterizerVulkan::SetupGraphicsGlobalBuffers(const ShaderEntries& entries,
983 } 985 }
984} 986}
985 987
986void RasterizerVulkan::SetupGraphicsTexelBuffers(const ShaderEntries& entries, std::size_t stage) { 988void RasterizerVulkan::SetupGraphicsUniformTexels(const ShaderEntries& entries, std::size_t stage) {
987 MICROPROFILE_SCOPE(Vulkan_Textures); 989 MICROPROFILE_SCOPE(Vulkan_Textures);
988 const auto& gpu = system.GPU().Maxwell3D(); 990 const auto& gpu = system.GPU().Maxwell3D();
989 for (const auto& entry : entries.texel_buffers) { 991 for (const auto& entry : entries.uniform_texels) {
990 const auto image = GetTextureInfo(gpu, entry, stage).tic; 992 const auto image = GetTextureInfo(gpu, entry, stage).tic;
991 SetupTexelBuffer(image, entry); 993 SetupUniformTexels(image, entry);
992 } 994 }
993} 995}
994 996
@@ -1003,6 +1005,15 @@ void RasterizerVulkan::SetupGraphicsTextures(const ShaderEntries& entries, std::
1003 } 1005 }
1004} 1006}
1005 1007
1008void RasterizerVulkan::SetupGraphicsStorageTexels(const ShaderEntries& entries, std::size_t stage) {
1009 MICROPROFILE_SCOPE(Vulkan_Textures);
1010 const auto& gpu = system.GPU().Maxwell3D();
1011 for (const auto& entry : entries.storage_texels) {
1012 const auto image = GetTextureInfo(gpu, entry, stage).tic;
1013 SetupStorageTexel(image, entry);
1014 }
1015}
1016
1006void RasterizerVulkan::SetupGraphicsImages(const ShaderEntries& entries, std::size_t stage) { 1017void RasterizerVulkan::SetupGraphicsImages(const ShaderEntries& entries, std::size_t stage) {
1007 MICROPROFILE_SCOPE(Vulkan_Images); 1018 MICROPROFILE_SCOPE(Vulkan_Images);
1008 const auto& gpu = system.GPU().Maxwell3D(); 1019 const auto& gpu = system.GPU().Maxwell3D();
@@ -1035,12 +1046,12 @@ void RasterizerVulkan::SetupComputeGlobalBuffers(const ShaderEntries& entries) {
1035 } 1046 }
1036} 1047}
1037 1048
1038void RasterizerVulkan::SetupComputeTexelBuffers(const ShaderEntries& entries) { 1049void RasterizerVulkan::SetupComputeUniformTexels(const ShaderEntries& entries) {
1039 MICROPROFILE_SCOPE(Vulkan_Textures); 1050 MICROPROFILE_SCOPE(Vulkan_Textures);
1040 const auto& gpu = system.GPU().KeplerCompute(); 1051 const auto& gpu = system.GPU().KeplerCompute();
1041 for (const auto& entry : entries.texel_buffers) { 1052 for (const auto& entry : entries.uniform_texels) {
1042 const auto image = GetTextureInfo(gpu, entry, ComputeShaderIndex).tic; 1053 const auto image = GetTextureInfo(gpu, entry, ComputeShaderIndex).tic;
1043 SetupTexelBuffer(image, entry); 1054 SetupUniformTexels(image, entry);
1044 } 1055 }
1045} 1056}
1046 1057
@@ -1055,6 +1066,15 @@ void RasterizerVulkan::SetupComputeTextures(const ShaderEntries& entries) {
1055 } 1066 }
1056} 1067}
1057 1068
1069void RasterizerVulkan::SetupComputeStorageTexels(const ShaderEntries& entries) {
1070 MICROPROFILE_SCOPE(Vulkan_Textures);
1071 const auto& gpu = system.GPU().KeplerCompute();
1072 for (const auto& entry : entries.storage_texels) {
1073 const auto image = GetTextureInfo(gpu, entry, ComputeShaderIndex).tic;
1074 SetupStorageTexel(image, entry);
1075 }
1076}
1077
1058void RasterizerVulkan::SetupComputeImages(const ShaderEntries& entries) { 1078void RasterizerVulkan::SetupComputeImages(const ShaderEntries& entries) {
1059 MICROPROFILE_SCOPE(Vulkan_Images); 1079 MICROPROFILE_SCOPE(Vulkan_Images);
1060 const auto& gpu = system.GPU().KeplerCompute(); 1080 const auto& gpu = system.GPU().KeplerCompute();
@@ -1104,8 +1124,8 @@ void RasterizerVulkan::SetupGlobalBuffer(const GlobalBufferEntry& entry, GPUVAdd
1104 update_descriptor_queue.AddBuffer(buffer, offset, size); 1124 update_descriptor_queue.AddBuffer(buffer, offset, size);
1105} 1125}
1106 1126
1107void RasterizerVulkan::SetupTexelBuffer(const Tegra::Texture::TICEntry& tic, 1127void RasterizerVulkan::SetupUniformTexels(const Tegra::Texture::TICEntry& tic,
1108 const TexelBufferEntry& entry) { 1128 const UniformTexelEntry& entry) {
1109 const auto view = texture_cache.GetTextureSurface(tic, entry); 1129 const auto view = texture_cache.GetTextureSurface(tic, entry);
1110 ASSERT(view->IsBufferView()); 1130 ASSERT(view->IsBufferView());
1111 1131
@@ -1127,6 +1147,14 @@ void RasterizerVulkan::SetupTexture(const Tegra::Texture::FullTextureInfo& textu
1127 sampled_views.push_back(ImageView{std::move(view), image_layout}); 1147 sampled_views.push_back(ImageView{std::move(view), image_layout});
1128} 1148}
1129 1149
1150void RasterizerVulkan::SetupStorageTexel(const Tegra::Texture::TICEntry& tic,
1151 const StorageTexelEntry& entry) {
1152 const auto view = texture_cache.GetImageSurface(tic, entry);
1153 ASSERT(view->IsBufferView());
1154
1155 update_descriptor_queue.AddTexelBuffer(view->GetBufferView());
1156}
1157
1130void RasterizerVulkan::SetupImage(const Tegra::Texture::TICEntry& tic, const ImageEntry& entry) { 1158void RasterizerVulkan::SetupImage(const Tegra::Texture::TICEntry& tic, const ImageEntry& entry) {
1131 auto view = texture_cache.GetImageSurface(tic, entry); 1159 auto view = texture_cache.GetImageSurface(tic, entry);
1132 1160
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..97429cc59 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 const auto format = image.is_atomic ? spv::ImageFormat::R32ui : 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)) {
@@ -1256,7 +1274,7 @@ private:
1256 } else { 1274 } else {
1257 UNREACHABLE_MSG("Unmanaged offset node type"); 1275 UNREACHABLE_MSG("Unmanaged offset node type");
1258 } 1276 }
1259 pointer = OpAccessChain(t_cbuf_float, buffer_id, Constant(t_uint, 0), buffer_index, 1277 pointer = OpAccessChain(t_cbuf_float, buffer_id, v_uint_zero, buffer_index,
1260 buffer_element); 1278 buffer_element);
1261 } 1279 }
1262 return {OpLoad(t_float, pointer), Type::Float}; 1280 return {OpLoad(t_float, pointer), Type::Float};
@@ -1611,7 +1629,7 @@ private:
1611 1629
1612 const Id result = OpIAddCarry(TypeStruct({t_uint, t_uint}), op_a, op_b); 1630 const Id result = OpIAddCarry(TypeStruct({t_uint, t_uint}), op_a, op_b);
1613 const Id carry = OpCompositeExtract(t_uint, result, 1); 1631 const Id carry = OpCompositeExtract(t_uint, result, 1);
1614 return {OpINotEqual(t_bool, carry, Constant(t_uint, 0)), Type::Bool}; 1632 return {OpINotEqual(t_bool, carry, v_uint_zero), Type::Bool};
1615 } 1633 }
1616 1634
1617 Expression LogicalAssign(Operation operation) { 1635 Expression LogicalAssign(Operation operation) {
@@ -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);
@@ -1951,39 +1969,20 @@ private:
1951 return {}; 1969 return {};
1952 } 1970 }
1953 1971
1954 Expression AtomicImageAdd(Operation operation) { 1972 template <Id (Module::*func)(Id, Id, Id, Id, Id)>
1955 UNIMPLEMENTED(); 1973 Expression AtomicImage(Operation operation) {
1956 return {}; 1974 const auto& meta{std::get<MetaImage>(operation.GetMeta())};
1957 } 1975 ASSERT(meta.values.size() == 1);
1958
1959 Expression AtomicImageMin(Operation operation) {
1960 UNIMPLEMENTED();
1961 return {};
1962 }
1963
1964 Expression AtomicImageMax(Operation operation) {
1965 UNIMPLEMENTED();
1966 return {};
1967 }
1968
1969 Expression AtomicImageAnd(Operation operation) {
1970 UNIMPLEMENTED();
1971 return {};
1972 }
1973
1974 Expression AtomicImageOr(Operation operation) {
1975 UNIMPLEMENTED();
1976 return {};
1977 }
1978 1976
1979 Expression AtomicImageXor(Operation operation) { 1977 const Id coordinate = GetCoordinates(operation, Type::Int);
1980 UNIMPLEMENTED(); 1978 const Id image = images.at(meta.image.index).image;
1981 return {}; 1979 const Id sample = v_uint_zero;
1982 } 1980 const Id pointer = OpImageTexelPointer(t_image_uint, image, coordinate, sample);
1983 1981
1984 Expression AtomicImageExchange(Operation operation) { 1982 const Id scope = Constant(t_uint, static_cast<u32>(spv::Scope::Device));
1985 UNIMPLEMENTED(); 1983 const Id semantics = v_uint_zero;
1986 return {}; 1984 const Id value = AsUint(Visit(meta.values[0]));
1985 return {(this->*func)(t_uint, pointer, scope, semantics, value), Type::Uint};
1987 } 1986 }
1988 1987
1989 template <Id (Module::*func)(Id, Id, Id, Id, Id)> 1988 template <Id (Module::*func)(Id, Id, Id, Id, Id)>
@@ -1998,7 +1997,7 @@ private:
1998 return {v_float_zero, Type::Float}; 1997 return {v_float_zero, Type::Float};
1999 } 1998 }
2000 const Id scope = Constant(t_uint, static_cast<u32>(spv::Scope::Device)); 1999 const Id scope = Constant(t_uint, static_cast<u32>(spv::Scope::Device));
2001 const Id semantics = Constant(t_uint, 0); 2000 const Id semantics = v_uint_zero;
2002 const Id value = AsUint(Visit(operation[1])); 2001 const Id value = AsUint(Visit(operation[1]));
2003 2002
2004 return {(this->*func)(t_uint, pointer, scope, semantics, value), Type::Uint}; 2003 return {(this->*func)(t_uint, pointer, scope, semantics, value), Type::Uint};
@@ -2622,11 +2621,11 @@ private:
2622 2621
2623 &SPIRVDecompiler::ImageLoad, 2622 &SPIRVDecompiler::ImageLoad,
2624 &SPIRVDecompiler::ImageStore, 2623 &SPIRVDecompiler::ImageStore,
2625 &SPIRVDecompiler::AtomicImageAdd, 2624 &SPIRVDecompiler::AtomicImage<&Module::OpAtomicIAdd>,
2626 &SPIRVDecompiler::AtomicImageAnd, 2625 &SPIRVDecompiler::AtomicImage<&Module::OpAtomicAnd>,
2627 &SPIRVDecompiler::AtomicImageOr, 2626 &SPIRVDecompiler::AtomicImage<&Module::OpAtomicOr>,
2628 &SPIRVDecompiler::AtomicImageXor, 2627 &SPIRVDecompiler::AtomicImage<&Module::OpAtomicXor>,
2629 &SPIRVDecompiler::AtomicImageExchange, 2628 &SPIRVDecompiler::AtomicImage<&Module::OpAtomicExchange>,
2630 2629
2631 &SPIRVDecompiler::Atomic<&Module::OpAtomicExchange>, 2630 &SPIRVDecompiler::Atomic<&Module::OpAtomicExchange>,
2632 &SPIRVDecompiler::Atomic<&Module::OpAtomicIAdd>, 2631 &SPIRVDecompiler::Atomic<&Module::OpAtomicIAdd>,
@@ -2768,8 +2767,11 @@ private:
2768 Decorate(TypeStruct(t_gmem_array), spv::Decoration::Block), 0, spv::Decoration::Offset, 0); 2767 Decorate(TypeStruct(t_gmem_array), spv::Decoration::Block), 0, spv::Decoration::Offset, 0);
2769 const Id t_gmem_ssbo = TypePointer(spv::StorageClass::StorageBuffer, t_gmem_struct); 2768 const Id t_gmem_ssbo = TypePointer(spv::StorageClass::StorageBuffer, t_gmem_struct);
2770 2769
2770 const Id t_image_uint = TypePointer(spv::StorageClass::Image, t_uint);
2771
2771 const Id v_float_zero = Constant(t_float, 0.0f); 2772 const Id v_float_zero = Constant(t_float, 0.0f);
2772 const Id v_float_one = Constant(t_float, 1.0f); 2773 const Id v_float_one = Constant(t_float, 1.0f);
2774 const Id v_uint_zero = Constant(t_uint, 0);
2773 2775
2774 // Nvidia uses these defaults for varyings (e.g. position and generic attributes) 2776 // Nvidia uses these defaults for varyings (e.g. position and generic attributes)
2775 const Id v_varying_default = 2777 const Id v_varying_default =
@@ -2794,15 +2796,16 @@ private:
2794 std::unordered_map<u8, GenericVaryingDescription> output_attributes; 2796 std::unordered_map<u8, GenericVaryingDescription> output_attributes;
2795 std::map<u32, Id> constant_buffers; 2797 std::map<u32, Id> constant_buffers;
2796 std::map<GlobalMemoryBase, Id> global_buffers; 2798 std::map<GlobalMemoryBase, Id> global_buffers;
2797 std::map<u32, TexelBuffer> texel_buffers; 2799 std::map<u32, TexelBuffer> uniform_texels;
2798 std::map<u32, SampledImage> sampled_images; 2800 std::map<u32, SampledImage> sampled_images;
2801 std::map<u32, TexelBuffer> storage_texels;
2799 std::map<u32, StorageImage> images; 2802 std::map<u32, StorageImage> images;
2800 2803
2804 std::array<Id, Maxwell::NumRenderTargets> frag_colors{};
2801 Id instance_index{}; 2805 Id instance_index{};
2802 Id vertex_index{}; 2806 Id vertex_index{};
2803 Id base_instance{}; 2807 Id base_instance{};
2804 Id base_vertex{}; 2808 Id base_vertex{};
2805 std::array<Id, Maxwell::NumRenderTargets> frag_colors{};
2806 Id frag_depth{}; 2809 Id frag_depth{};
2807 Id frag_coord{}; 2810 Id frag_coord{};
2808 Id front_facing{}; 2811 Id front_facing{};
@@ -3058,13 +3061,17 @@ ShaderEntries GenerateShaderEntries(const VideoCommon::Shader::ShaderIR& ir) {
3058 } 3061 }
3059 for (const auto& sampler : ir.GetSamplers()) { 3062 for (const auto& sampler : ir.GetSamplers()) {
3060 if (sampler.is_buffer) { 3063 if (sampler.is_buffer) {
3061 entries.texel_buffers.emplace_back(sampler); 3064 entries.uniform_texels.emplace_back(sampler);
3062 } else { 3065 } else {
3063 entries.samplers.emplace_back(sampler); 3066 entries.samplers.emplace_back(sampler);
3064 } 3067 }
3065 } 3068 }
3066 for (const auto& image : ir.GetImages()) { 3069 for (const auto& image : ir.GetImages()) {
3067 entries.images.emplace_back(image); 3070 if (image.type == Tegra::Shader::ImageType::TextureBuffer) {
3071 entries.storage_texels.emplace_back(image);
3072 } else {
3073 entries.images.emplace_back(image);
3074 }
3068 } 3075 }
3069 for (const auto& attribute : ir.GetInputAttributes()) { 3076 for (const auto& attribute : ir.GetInputAttributes()) {
3070 if (IsGenericAttribute(attribute)) { 3077 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;