diff options
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; | |||
| 45 | constexpr VkDescriptorType STORAGE_BUFFER = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; | 45 | constexpr VkDescriptorType STORAGE_BUFFER = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; |
| 46 | constexpr VkDescriptorType UNIFORM_TEXEL_BUFFER = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; | 46 | constexpr VkDescriptorType UNIFORM_TEXEL_BUFFER = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; |
| 47 | constexpr VkDescriptorType COMBINED_IMAGE_SAMPLER = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; | 47 | constexpr VkDescriptorType COMBINED_IMAGE_SAMPLER = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; |
| 48 | constexpr VkDescriptorType STORAGE_TEXEL_BUFFER = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; | ||
| 48 | constexpr VkDescriptorType STORAGE_IMAGE = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; | 49 | constexpr VkDescriptorType STORAGE_IMAGE = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; |
| 49 | 50 | ||
| 50 | constexpr VideoCommon::Shader::CompilerSettings compiler_settings{ | 51 | constexpr 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 | ||
| 979 | void RasterizerVulkan::SetupGraphicsTexelBuffers(const ShaderEntries& entries, std::size_t stage) { | 981 | void 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 | ||
| 1001 | void 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 | |||
| 999 | void RasterizerVulkan::SetupGraphicsImages(const ShaderEntries& entries, std::size_t stage) { | 1010 | void 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 | ||
| 1031 | void RasterizerVulkan::SetupComputeTexelBuffers(const ShaderEntries& entries) { | 1042 | void 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 | ||
| 1062 | void 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 | |||
| 1051 | void RasterizerVulkan::SetupComputeImages(const ShaderEntries& entries) { | 1071 | void 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 | ||
| 1100 | void RasterizerVulkan::SetupTexelBuffer(const Tegra::Texture::TICEntry& tic, | 1120 | void 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 | ||
| 1143 | void 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 | |||
| 1123 | void RasterizerVulkan::SetupImage(const Tegra::Texture::TICEntry& tic, const ImageEntry& entry) { | 1151 | void 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; | |||
| 21 | namespace Vulkan { | 21 | namespace Vulkan { |
| 22 | 22 | ||
| 23 | using Maxwell = Tegra::Engines::Maxwell3D::Regs; | 23 | using Maxwell = Tegra::Engines::Maxwell3D::Regs; |
| 24 | using TexelBufferEntry = VideoCommon::Shader::Sampler; | 24 | using UniformTexelEntry = VideoCommon::Shader::Sampler; |
| 25 | using SamplerEntry = VideoCommon::Shader::Sampler; | 25 | using SamplerEntry = VideoCommon::Shader::Sampler; |
| 26 | using StorageTexelEntry = VideoCommon::Shader::Image; | ||
| 26 | using ImageEntry = VideoCommon::Shader::Image; | 27 | using ImageEntry = VideoCommon::Shader::Image; |
| 27 | 28 | ||
| 28 | constexpr u32 DESCRIPTOR_SET = 0; | 29 | constexpr u32 DESCRIPTOR_SET = 0; |
| @@ -66,13 +67,15 @@ private: | |||
| 66 | struct ShaderEntries { | 67 | struct 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; |