diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/shader_recompiler/backend/spirv/emit_context.cpp | 70 | ||||
| -rw-r--r-- | src/shader_recompiler/backend/spirv/emit_context.h | 7 | ||||
| -rw-r--r-- | src/shader_recompiler/backend/spirv/emit_spirv_image.cpp | 3 | ||||
| -rw-r--r-- | src/shader_recompiler/ir_opt/texture_pass.cpp | 19 | ||||
| -rw-r--r-- | src/shader_recompiler/shader_info.h | 10 | ||||
| -rw-r--r-- | src/video_core/buffer_cache/buffer_cache.h | 24 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/pipeline_helper.h | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_compute_pipeline.cpp | 25 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp | 31 |
9 files changed, 142 insertions, 49 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp index f96d5ae37..032cf5e03 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/emit_context.cpp | |||
| @@ -54,28 +54,30 @@ Id ImageType(EmitContext& ctx, const TextureDescriptor& desc) { | |||
| 54 | throw InvalidArgument("Invalid texture type {}", desc.type); | 54 | throw InvalidArgument("Invalid texture type {}", desc.type); |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | spv::ImageFormat GetImageFormat(ImageFormat format) { | ||
| 58 | switch (format) { | ||
| 59 | case ImageFormat::Typeless: | ||
| 60 | return spv::ImageFormat::Unknown; | ||
| 61 | case ImageFormat::R8_UINT: | ||
| 62 | return spv::ImageFormat::R8ui; | ||
| 63 | case ImageFormat::R8_SINT: | ||
| 64 | return spv::ImageFormat::R8i; | ||
| 65 | case ImageFormat::R16_UINT: | ||
| 66 | return spv::ImageFormat::R16ui; | ||
| 67 | case ImageFormat::R16_SINT: | ||
| 68 | return spv::ImageFormat::R16i; | ||
| 69 | case ImageFormat::R32_UINT: | ||
| 70 | return spv::ImageFormat::R32ui; | ||
| 71 | case ImageFormat::R32G32_UINT: | ||
| 72 | return spv::ImageFormat::Rg32ui; | ||
| 73 | case ImageFormat::R32G32B32A32_UINT: | ||
| 74 | return spv::ImageFormat::Rgba32ui; | ||
| 75 | } | ||
| 76 | throw InvalidArgument("Invalid image format {}", format); | ||
| 77 | } | ||
| 78 | |||
| 57 | Id ImageType(EmitContext& ctx, const ImageDescriptor& desc) { | 79 | Id ImageType(EmitContext& ctx, const ImageDescriptor& desc) { |
| 58 | const spv::ImageFormat format{[&] { | 80 | const spv::ImageFormat format{GetImageFormat(desc.format)}; |
| 59 | switch (desc.format) { | ||
| 60 | case ImageFormat::Typeless: | ||
| 61 | return spv::ImageFormat::Unknown; | ||
| 62 | case ImageFormat::R8_UINT: | ||
| 63 | return spv::ImageFormat::R8ui; | ||
| 64 | case ImageFormat::R8_SINT: | ||
| 65 | return spv::ImageFormat::R8i; | ||
| 66 | case ImageFormat::R16_UINT: | ||
| 67 | return spv::ImageFormat::R16ui; | ||
| 68 | case ImageFormat::R16_SINT: | ||
| 69 | return spv::ImageFormat::R16i; | ||
| 70 | case ImageFormat::R32_UINT: | ||
| 71 | return spv::ImageFormat::R32ui; | ||
| 72 | case ImageFormat::R32G32_UINT: | ||
| 73 | return spv::ImageFormat::Rg32ui; | ||
| 74 | case ImageFormat::R32G32B32A32_UINT: | ||
| 75 | return spv::ImageFormat::Rgba32ui; | ||
| 76 | } | ||
| 77 | throw InvalidArgument("Invalid image format {}", desc.format); | ||
| 78 | }()}; | ||
| 79 | const Id type{ctx.U32[1]}; | 81 | const Id type{ctx.U32[1]}; |
| 80 | switch (desc.type) { | 82 | switch (desc.type) { |
| 81 | case TextureType::Color1D: | 83 | case TextureType::Color1D: |
| @@ -388,6 +390,7 @@ EmitContext::EmitContext(const Profile& profile_, IR::Program& program, u32& bin | |||
| 388 | DefineConstantBuffers(program.info, binding); | 390 | DefineConstantBuffers(program.info, binding); |
| 389 | DefineStorageBuffers(program.info, binding); | 391 | DefineStorageBuffers(program.info, binding); |
| 390 | DefineTextureBuffers(program.info, binding); | 392 | DefineTextureBuffers(program.info, binding); |
| 393 | DefineImageBuffers(program.info, binding); | ||
| 391 | DefineTextures(program.info, binding); | 394 | DefineTextures(program.info, binding); |
| 392 | DefineImages(program.info, binding); | 395 | DefineImages(program.info, binding); |
| 393 | DefineAttributeMemAccess(program.info); | 396 | DefineAttributeMemAccess(program.info); |
| @@ -883,6 +886,31 @@ void EmitContext::DefineTextureBuffers(const Info& info, u32& binding) { | |||
| 883 | } | 886 | } |
| 884 | } | 887 | } |
| 885 | 888 | ||
| 889 | void EmitContext::DefineImageBuffers(const Info& info, u32& binding) { | ||
| 890 | image_buffers.reserve(info.image_buffer_descriptors.size()); | ||
| 891 | for (const ImageBufferDescriptor& desc : info.image_buffer_descriptors) { | ||
| 892 | if (desc.count != 1) { | ||
| 893 | throw NotImplementedException("Array of image buffers"); | ||
| 894 | } | ||
| 895 | const spv::ImageFormat format{GetImageFormat(desc.format)}; | ||
| 896 | const Id image_type{TypeImage(U32[4], spv::Dim::Buffer, false, false, false, 2, format)}; | ||
| 897 | const Id pointer_type{TypePointer(spv::StorageClass::UniformConstant, image_type)}; | ||
| 898 | const Id id{AddGlobalVariable(pointer_type, spv::StorageClass::UniformConstant)}; | ||
| 899 | Decorate(id, spv::Decoration::Binding, binding); | ||
| 900 | Decorate(id, spv::Decoration::DescriptorSet, 0U); | ||
| 901 | Name(id, fmt::format("imgbuf{}_{:02x}", desc.cbuf_index, desc.cbuf_offset)); | ||
| 902 | const ImageBufferDefinition def{ | ||
| 903 | .id = id, | ||
| 904 | .image_type = image_type, | ||
| 905 | }; | ||
| 906 | image_buffers.insert(image_buffers.end(), desc.count, def); | ||
| 907 | if (profile.supported_spirv >= 0x00010400) { | ||
| 908 | interfaces.push_back(id); | ||
| 909 | } | ||
| 910 | binding += desc.count; | ||
| 911 | } | ||
| 912 | } | ||
| 913 | |||
| 886 | void EmitContext::DefineTextures(const Info& info, u32& binding) { | 914 | void EmitContext::DefineTextures(const Info& info, u32& binding) { |
| 887 | textures.reserve(info.texture_descriptors.size()); | 915 | textures.reserve(info.texture_descriptors.size()); |
| 888 | for (const TextureDescriptor& desc : info.texture_descriptors) { | 916 | for (const TextureDescriptor& desc : info.texture_descriptors) { |
diff --git a/src/shader_recompiler/backend/spirv/emit_context.h b/src/shader_recompiler/backend/spirv/emit_context.h index 1f0d8be77..0da14d5f8 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.h +++ b/src/shader_recompiler/backend/spirv/emit_context.h | |||
| @@ -35,6 +35,11 @@ struct TextureDefinition { | |||
| 35 | Id image_type; | 35 | Id image_type; |
| 36 | }; | 36 | }; |
| 37 | 37 | ||
| 38 | struct ImageBufferDefinition { | ||
| 39 | Id id; | ||
| 40 | Id image_type; | ||
| 41 | }; | ||
| 42 | |||
| 38 | struct ImageDefinition { | 43 | struct ImageDefinition { |
| 39 | Id id; | 44 | Id id; |
| 40 | Id image_type; | 45 | Id image_type; |
| @@ -136,6 +141,7 @@ public: | |||
| 136 | std::array<UniformDefinitions, Info::MAX_CBUFS> cbufs{}; | 141 | std::array<UniformDefinitions, Info::MAX_CBUFS> cbufs{}; |
| 137 | std::array<StorageDefinitions, Info::MAX_SSBOS> ssbos{}; | 142 | std::array<StorageDefinitions, Info::MAX_SSBOS> ssbos{}; |
| 138 | std::vector<Id> texture_buffers; | 143 | std::vector<Id> texture_buffers; |
| 144 | std::vector<ImageBufferDefinition> image_buffers; | ||
| 139 | std::vector<TextureDefinition> textures; | 145 | std::vector<TextureDefinition> textures; |
| 140 | std::vector<ImageDefinition> images; | 146 | std::vector<ImageDefinition> images; |
| 141 | 147 | ||
| @@ -213,6 +219,7 @@ private: | |||
| 213 | void DefineConstantBuffers(const Info& info, u32& binding); | 219 | void DefineConstantBuffers(const Info& info, u32& binding); |
| 214 | void DefineStorageBuffers(const Info& info, u32& binding); | 220 | void DefineStorageBuffers(const Info& info, u32& binding); |
| 215 | void DefineTextureBuffers(const Info& info, u32& binding); | 221 | void DefineTextureBuffers(const Info& info, u32& binding); |
| 222 | void DefineImageBuffers(const Info& info, u32& binding); | ||
| 216 | void DefineTextures(const Info& info, u32& binding); | 223 | void DefineTextures(const Info& info, u32& binding); |
| 217 | void DefineImages(const Info& info, u32& binding); | 224 | void DefineImages(const Info& info, u32& binding); |
| 218 | void DefineAttributeMemAccess(const Info& info); | 225 | void DefineAttributeMemAccess(const Info& info); |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp index 17266ce77..c8d1d25b1 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp | |||
| @@ -149,7 +149,8 @@ Id Image(EmitContext& ctx, const IR::Value& index, IR::TextureInstInfo info) { | |||
| 149 | throw NotImplementedException("Indirect image indexing"); | 149 | throw NotImplementedException("Indirect image indexing"); |
| 150 | } | 150 | } |
| 151 | if (info.type == TextureType::Buffer) { | 151 | if (info.type == TextureType::Buffer) { |
| 152 | throw NotImplementedException("Image buffer"); | 152 | const ImageBufferDefinition def{ctx.image_buffers.at(index.U32())}; |
| 153 | return ctx.OpLoad(def.image_type, def.id); | ||
| 153 | } else { | 154 | } else { |
| 154 | const ImageDefinition def{ctx.images.at(index.U32())}; | 155 | const ImageDefinition def{ctx.images.at(index.U32())}; |
| 155 | return ctx.OpLoad(def.image_type, def.id); | 156 | return ctx.OpLoad(def.image_type, def.id); |
diff --git a/src/shader_recompiler/ir_opt/texture_pass.cpp b/src/shader_recompiler/ir_opt/texture_pass.cpp index a7b1fcfad..e1d5a2ce1 100644 --- a/src/shader_recompiler/ir_opt/texture_pass.cpp +++ b/src/shader_recompiler/ir_opt/texture_pass.cpp | |||
| @@ -158,9 +158,11 @@ TextureInst MakeInst(Environment& env, IR::Block* block, IR::Inst& inst) { | |||
| 158 | class Descriptors { | 158 | class Descriptors { |
| 159 | public: | 159 | public: |
| 160 | explicit Descriptors(TextureBufferDescriptors& texture_buffer_descriptors_, | 160 | explicit Descriptors(TextureBufferDescriptors& texture_buffer_descriptors_, |
| 161 | ImageBufferDescriptors& image_buffer_descriptors_, | ||
| 161 | TextureDescriptors& texture_descriptors_, | 162 | TextureDescriptors& texture_descriptors_, |
| 162 | ImageDescriptors& image_descriptors_) | 163 | ImageDescriptors& image_descriptors_) |
| 163 | : texture_buffer_descriptors{texture_buffer_descriptors_}, | 164 | : texture_buffer_descriptors{texture_buffer_descriptors_}, |
| 165 | image_buffer_descriptors{image_buffer_descriptors_}, | ||
| 164 | texture_descriptors{texture_descriptors_}, image_descriptors{image_descriptors_} {} | 166 | texture_descriptors{texture_descriptors_}, image_descriptors{image_descriptors_} {} |
| 165 | 167 | ||
| 166 | u32 Add(const TextureBufferDescriptor& desc) { | 168 | u32 Add(const TextureBufferDescriptor& desc) { |
| @@ -170,6 +172,13 @@ public: | |||
| 170 | }); | 172 | }); |
| 171 | } | 173 | } |
| 172 | 174 | ||
| 175 | u32 Add(const ImageBufferDescriptor& desc) { | ||
| 176 | return Add(image_buffer_descriptors, desc, [&desc](const auto& existing) { | ||
| 177 | return desc.format == existing.format && desc.cbuf_index == existing.cbuf_index && | ||
| 178 | desc.cbuf_offset == existing.cbuf_offset; | ||
| 179 | }); | ||
| 180 | } | ||
| 181 | |||
| 173 | u32 Add(const TextureDescriptor& desc) { | 182 | u32 Add(const TextureDescriptor& desc) { |
| 174 | return Add(texture_descriptors, desc, [&desc](const auto& existing) { | 183 | return Add(texture_descriptors, desc, [&desc](const auto& existing) { |
| 175 | return desc.cbuf_index == existing.cbuf_index && | 184 | return desc.cbuf_index == existing.cbuf_index && |
| @@ -200,6 +209,7 @@ private: | |||
| 200 | } | 209 | } |
| 201 | 210 | ||
| 202 | TextureBufferDescriptors& texture_buffer_descriptors; | 211 | TextureBufferDescriptors& texture_buffer_descriptors; |
| 212 | ImageBufferDescriptors& image_buffer_descriptors; | ||
| 203 | TextureDescriptors& texture_descriptors; | 213 | TextureDescriptors& texture_descriptors; |
| 204 | ImageDescriptors& image_descriptors; | 214 | ImageDescriptors& image_descriptors; |
| 205 | }; | 215 | }; |
| @@ -224,6 +234,7 @@ void TexturePass(Environment& env, IR::Program& program) { | |||
| 224 | }); | 234 | }); |
| 225 | Descriptors descriptors{ | 235 | Descriptors descriptors{ |
| 226 | program.info.texture_buffer_descriptors, | 236 | program.info.texture_buffer_descriptors, |
| 237 | program.info.image_buffer_descriptors, | ||
| 227 | program.info.texture_descriptors, | 238 | program.info.texture_descriptors, |
| 228 | program.info.image_descriptors, | 239 | program.info.image_descriptors, |
| 229 | }; | 240 | }; |
| @@ -261,7 +272,13 @@ void TexturePass(Environment& env, IR::Program& program) { | |||
| 261 | case IR::Opcode::ImageWrite: { | 272 | case IR::Opcode::ImageWrite: { |
| 262 | const bool is_written{inst->GetOpcode() == IR::Opcode::ImageWrite}; | 273 | const bool is_written{inst->GetOpcode() == IR::Opcode::ImageWrite}; |
| 263 | if (flags.type == TextureType::Buffer) { | 274 | if (flags.type == TextureType::Buffer) { |
| 264 | throw NotImplementedException("Image buffer"); | 275 | index = descriptors.Add(ImageBufferDescriptor{ |
| 276 | .format = flags.image_format, | ||
| 277 | .is_written = is_written, | ||
| 278 | .cbuf_index = cbuf.index, | ||
| 279 | .cbuf_offset = cbuf.offset, | ||
| 280 | .count = 1, | ||
| 281 | }); | ||
| 265 | } else { | 282 | } else { |
| 266 | index = descriptors.Add(ImageDescriptor{ | 283 | index = descriptors.Add(ImageDescriptor{ |
| 267 | .type = flags.type, | 284 | .type = flags.type, |
diff --git a/src/shader_recompiler/shader_info.h b/src/shader_recompiler/shader_info.h index e078b0fa1..336c6131a 100644 --- a/src/shader_recompiler/shader_info.h +++ b/src/shader_recompiler/shader_info.h | |||
| @@ -67,6 +67,15 @@ struct TextureBufferDescriptor { | |||
| 67 | }; | 67 | }; |
| 68 | using TextureBufferDescriptors = boost::container::small_vector<TextureBufferDescriptor, 6>; | 68 | using TextureBufferDescriptors = boost::container::small_vector<TextureBufferDescriptor, 6>; |
| 69 | 69 | ||
| 70 | struct ImageBufferDescriptor { | ||
| 71 | ImageFormat format; | ||
| 72 | bool is_written; | ||
| 73 | u32 cbuf_index; | ||
| 74 | u32 cbuf_offset; | ||
| 75 | u32 count; | ||
| 76 | }; | ||
| 77 | using ImageBufferDescriptors = boost::container::small_vector<ImageBufferDescriptor, 2>; | ||
| 78 | |||
| 70 | struct TextureDescriptor { | 79 | struct TextureDescriptor { |
| 71 | TextureType type; | 80 | TextureType type; |
| 72 | bool is_depth; | 81 | bool is_depth; |
| @@ -153,6 +162,7 @@ struct Info { | |||
| 153 | constant_buffer_descriptors; | 162 | constant_buffer_descriptors; |
| 154 | boost::container::static_vector<StorageBufferDescriptor, MAX_SSBOS> storage_buffers_descriptors; | 163 | boost::container::static_vector<StorageBufferDescriptor, MAX_SSBOS> storage_buffers_descriptors; |
| 155 | TextureBufferDescriptors texture_buffer_descriptors; | 164 | TextureBufferDescriptors texture_buffer_descriptors; |
| 165 | ImageBufferDescriptors image_buffer_descriptors; | ||
| 156 | TextureDescriptors texture_descriptors; | 166 | TextureDescriptors texture_descriptors; |
| 157 | ImageDescriptors image_descriptors; | 167 | ImageDescriptors image_descriptors; |
| 158 | }; | 168 | }; |
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 6701aab82..29746f61d 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h | |||
| @@ -154,7 +154,7 @@ public: | |||
| 154 | void UnbindGraphicsTextureBuffers(size_t stage); | 154 | void UnbindGraphicsTextureBuffers(size_t stage); |
| 155 | 155 | ||
| 156 | void BindGraphicsTextureBuffer(size_t stage, size_t tbo_index, GPUVAddr gpu_addr, u32 size, | 156 | void BindGraphicsTextureBuffer(size_t stage, size_t tbo_index, GPUVAddr gpu_addr, u32 size, |
| 157 | PixelFormat format); | 157 | PixelFormat format, bool is_written); |
| 158 | 158 | ||
| 159 | void UnbindComputeStorageBuffers(); | 159 | void UnbindComputeStorageBuffers(); |
| 160 | 160 | ||
| @@ -163,8 +163,8 @@ public: | |||
| 163 | 163 | ||
| 164 | void UnbindComputeTextureBuffers(); | 164 | void UnbindComputeTextureBuffers(); |
| 165 | 165 | ||
| 166 | void BindComputeTextureBuffer(size_t tbo_index, GPUVAddr gpu_addr, u32 size, | 166 | void BindComputeTextureBuffer(size_t tbo_index, GPUVAddr gpu_addr, u32 size, PixelFormat format, |
| 167 | PixelFormat format); | 167 | bool is_written); |
| 168 | 168 | ||
| 169 | void FlushCachedWrites(); | 169 | void FlushCachedWrites(); |
| 170 | 170 | ||
| @@ -393,7 +393,9 @@ private: | |||
| 393 | u32 written_compute_storage_buffers = 0; | 393 | u32 written_compute_storage_buffers = 0; |
| 394 | 394 | ||
| 395 | std::array<u32, NUM_STAGES> enabled_texture_buffers{}; | 395 | std::array<u32, NUM_STAGES> enabled_texture_buffers{}; |
| 396 | std::array<u32, NUM_STAGES> written_texture_buffers{}; | ||
| 396 | u32 enabled_compute_texture_buffers = 0; | 397 | u32 enabled_compute_texture_buffers = 0; |
| 398 | u32 written_compute_texture_buffers = 0; | ||
| 397 | 399 | ||
| 398 | std::array<u32, NUM_STAGES> fast_bound_uniform_buffers{}; | 400 | std::array<u32, NUM_STAGES> fast_bound_uniform_buffers{}; |
| 399 | 401 | ||
| @@ -700,12 +702,14 @@ void BufferCache<P>::BindGraphicsStorageBuffer(size_t stage, size_t ssbo_index, | |||
| 700 | template <class P> | 702 | template <class P> |
| 701 | void BufferCache<P>::UnbindGraphicsTextureBuffers(size_t stage) { | 703 | void BufferCache<P>::UnbindGraphicsTextureBuffers(size_t stage) { |
| 702 | enabled_texture_buffers[stage] = 0; | 704 | enabled_texture_buffers[stage] = 0; |
| 705 | written_texture_buffers[stage] = 0; | ||
| 703 | } | 706 | } |
| 704 | 707 | ||
| 705 | template <class P> | 708 | template <class P> |
| 706 | void BufferCache<P>::BindGraphicsTextureBuffer(size_t stage, size_t tbo_index, GPUVAddr gpu_addr, | 709 | void BufferCache<P>::BindGraphicsTextureBuffer(size_t stage, size_t tbo_index, GPUVAddr gpu_addr, |
| 707 | u32 size, PixelFormat format) { | 710 | u32 size, PixelFormat format, bool is_written) { |
| 708 | enabled_texture_buffers[stage] |= 1U << tbo_index; | 711 | enabled_texture_buffers[stage] |= 1U << tbo_index; |
| 712 | written_texture_buffers[stage] |= (is_written ? 1U : 0U) << tbo_index; | ||
| 709 | texture_buffers[stage][tbo_index] = GetTextureBufferBinding(gpu_addr, size, format); | 713 | texture_buffers[stage][tbo_index] = GetTextureBufferBinding(gpu_addr, size, format); |
| 710 | } | 714 | } |
| 711 | 715 | ||
| @@ -732,12 +736,14 @@ void BufferCache<P>::BindComputeStorageBuffer(size_t ssbo_index, u32 cbuf_index, | |||
| 732 | template <class P> | 736 | template <class P> |
| 733 | void BufferCache<P>::UnbindComputeTextureBuffers() { | 737 | void BufferCache<P>::UnbindComputeTextureBuffers() { |
| 734 | enabled_compute_texture_buffers = 0; | 738 | enabled_compute_texture_buffers = 0; |
| 739 | written_compute_texture_buffers = 0; | ||
| 735 | } | 740 | } |
| 736 | 741 | ||
| 737 | template <class P> | 742 | template <class P> |
| 738 | void BufferCache<P>::BindComputeTextureBuffer(size_t tbo_index, GPUVAddr gpu_addr, u32 size, | 743 | void BufferCache<P>::BindComputeTextureBuffer(size_t tbo_index, GPUVAddr gpu_addr, u32 size, |
| 739 | PixelFormat format) { | 744 | PixelFormat format, bool is_written) { |
| 740 | enabled_compute_texture_buffers |= 1U << tbo_index; | 745 | enabled_compute_texture_buffers |= 1U << tbo_index; |
| 746 | written_compute_texture_buffers |= (is_written ? 1U : 0U) << tbo_index; | ||
| 741 | compute_texture_buffers[tbo_index] = GetTextureBufferBinding(gpu_addr, size, format); | 747 | compute_texture_buffers[tbo_index] = GetTextureBufferBinding(gpu_addr, size, format); |
| 742 | } | 748 | } |
| 743 | 749 | ||
| @@ -1274,6 +1280,10 @@ void BufferCache<P>::UpdateTextureBuffers(size_t stage) { | |||
| 1274 | ForEachEnabledBit(enabled_texture_buffers[stage], [&](u32 index) { | 1280 | ForEachEnabledBit(enabled_texture_buffers[stage], [&](u32 index) { |
| 1275 | Binding& binding = texture_buffers[stage][index]; | 1281 | Binding& binding = texture_buffers[stage][index]; |
| 1276 | binding.buffer_id = FindBuffer(binding.cpu_addr, binding.size); | 1282 | binding.buffer_id = FindBuffer(binding.cpu_addr, binding.size); |
| 1283 | // Mark buffer as written if needed | ||
| 1284 | if (((written_texture_buffers[stage] >> index) & 1) != 0) { | ||
| 1285 | MarkWrittenBuffer(binding.buffer_id, binding.cpu_addr, binding.size); | ||
| 1286 | } | ||
| 1277 | }); | 1287 | }); |
| 1278 | } | 1288 | } |
| 1279 | 1289 | ||
| @@ -1343,6 +1353,10 @@ void BufferCache<P>::UpdateComputeTextureBuffers() { | |||
| 1343 | ForEachEnabledBit(enabled_compute_texture_buffers, [&](u32 index) { | 1353 | ForEachEnabledBit(enabled_compute_texture_buffers, [&](u32 index) { |
| 1344 | Binding& binding = compute_texture_buffers[index]; | 1354 | Binding& binding = compute_texture_buffers[index]; |
| 1345 | binding.buffer_id = FindBuffer(binding.cpu_addr, binding.size); | 1355 | binding.buffer_id = FindBuffer(binding.cpu_addr, binding.size); |
| 1356 | // Mark as written if needed | ||
| 1357 | if (((written_compute_texture_buffers >> index) & 1) != 0) { | ||
| 1358 | MarkWrittenBuffer(binding.buffer_id, binding.cpu_addr, binding.size); | ||
| 1359 | } | ||
| 1346 | }); | 1360 | }); |
| 1347 | } | 1361 | } |
| 1348 | 1362 | ||
diff --git a/src/video_core/renderer_vulkan/pipeline_helper.h b/src/video_core/renderer_vulkan/pipeline_helper.h index e2167dc4b..aaf9a735e 100644 --- a/src/video_core/renderer_vulkan/pipeline_helper.h +++ b/src/video_core/renderer_vulkan/pipeline_helper.h | |||
| @@ -88,6 +88,7 @@ public: | |||
| 88 | Add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, stage, info.constant_buffer_descriptors.size()); | 88 | Add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, stage, info.constant_buffer_descriptors.size()); |
| 89 | Add(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, stage, info.storage_buffers_descriptors.size()); | 89 | Add(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, stage, info.storage_buffers_descriptors.size()); |
| 90 | Add(VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, stage, info.texture_buffer_descriptors.size()); | 90 | Add(VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, stage, info.texture_buffer_descriptors.size()); |
| 91 | Add(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, stage, info.image_buffer_descriptors.size()); | ||
| 91 | Add(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, stage, info.texture_descriptors.size()); | 92 | Add(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, stage, info.texture_descriptors.size()); |
| 92 | Add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, stage, info.image_descriptors.size()); | 93 | Add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, stage, info.image_descriptors.size()); |
| 93 | } | 94 | } |
| @@ -126,6 +127,7 @@ inline void PushImageDescriptors(const Shader::Info& info, const VkSampler*& sam | |||
| 126 | const ImageId*& image_view_ids, TextureCache& texture_cache, | 127 | const ImageId*& image_view_ids, TextureCache& texture_cache, |
| 127 | VKUpdateDescriptorQueue& update_descriptor_queue) { | 128 | VKUpdateDescriptorQueue& update_descriptor_queue) { |
| 128 | image_view_ids += info.texture_buffer_descriptors.size(); | 129 | image_view_ids += info.texture_buffer_descriptors.size(); |
| 130 | image_view_ids += info.image_buffer_descriptors.size(); | ||
| 129 | for (const auto& desc : info.texture_descriptors) { | 131 | for (const auto& desc : info.texture_descriptors) { |
| 130 | const VkSampler sampler{*(samplers++)}; | 132 | const VkSampler sampler{*(samplers++)}; |
| 131 | ImageView& image_view{texture_cache.GetImageView(*(image_view_ids++))}; | 133 | ImageView& image_view{texture_cache.GetImageView(*(image_view_ids++))}; |
diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp index 3d690f335..3c907ec5a 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp | |||
| @@ -97,10 +97,12 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute, | |||
| 97 | const u32 raw_handle{gpu_memory.Read<u32>(addr)}; | 97 | const u32 raw_handle{gpu_memory.Read<u32>(addr)}; |
| 98 | return TextureHandle(raw_handle, via_header_index); | 98 | return TextureHandle(raw_handle, via_header_index); |
| 99 | }}; | 99 | }}; |
| 100 | for (const auto& desc : info.texture_buffer_descriptors) { | 100 | const auto add_image{[&](const auto& desc) { |
| 101 | const TextureHandle handle{read_handle(desc.cbuf_index, desc.cbuf_offset)}; | 101 | const TextureHandle handle{read_handle(desc.cbuf_index, desc.cbuf_offset)}; |
| 102 | image_view_indices.push_back(handle.image); | 102 | image_view_indices.push_back(handle.image); |
| 103 | } | 103 | }}; |
| 104 | std::ranges::for_each(info.texture_buffer_descriptors, add_image); | ||
| 105 | std::ranges::for_each(info.image_buffer_descriptors, add_image); | ||
| 104 | for (const auto& desc : info.texture_descriptors) { | 106 | for (const auto& desc : info.texture_descriptors) { |
| 105 | const TextureHandle handle{read_handle(desc.cbuf_index, desc.cbuf_offset)}; | 107 | const TextureHandle handle{read_handle(desc.cbuf_index, desc.cbuf_offset)}; |
| 106 | image_view_indices.push_back(handle.image); | 108 | image_view_indices.push_back(handle.image); |
| @@ -108,24 +110,29 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute, | |||
| 108 | Sampler* const sampler = texture_cache.GetComputeSampler(handle.sampler); | 110 | Sampler* const sampler = texture_cache.GetComputeSampler(handle.sampler); |
| 109 | samplers.push_back(sampler->Handle()); | 111 | samplers.push_back(sampler->Handle()); |
| 110 | } | 112 | } |
| 111 | for (const auto& desc : info.image_descriptors) { | 113 | std::ranges::for_each(info.image_descriptors, add_image); |
| 112 | const TextureHandle handle{read_handle(desc.cbuf_index, desc.cbuf_offset)}; | 114 | |
| 113 | image_view_indices.push_back(handle.image); | ||
| 114 | } | ||
| 115 | const std::span indices_span(image_view_indices.data(), image_view_indices.size()); | 115 | const std::span indices_span(image_view_indices.data(), image_view_indices.size()); |
| 116 | texture_cache.FillComputeImageViews(indices_span, image_view_ids); | 116 | texture_cache.FillComputeImageViews(indices_span, image_view_ids); |
| 117 | 117 | ||
| 118 | buffer_cache.UnbindComputeTextureBuffers(); | 118 | buffer_cache.UnbindComputeTextureBuffers(); |
| 119 | ImageId* texture_buffer_ids{image_view_ids.data()}; | 119 | ImageId* texture_buffer_ids{image_view_ids.data()}; |
| 120 | size_t index{}; | 120 | size_t index{}; |
| 121 | for (const auto& desc : info.texture_buffer_descriptors) { | 121 | const auto add_buffer{[&](const auto& desc) { |
| 122 | ASSERT(desc.count == 1); | 122 | ASSERT(desc.count == 1); |
| 123 | bool is_written{false}; | ||
| 124 | if constexpr (std::is_same_v<decltype(desc), const Shader::ImageBufferDescriptor&>) { | ||
| 125 | is_written = desc.is_written; | ||
| 126 | } | ||
| 123 | ImageView& image_view = texture_cache.GetImageView(*texture_buffer_ids); | 127 | ImageView& image_view = texture_cache.GetImageView(*texture_buffer_ids); |
| 124 | buffer_cache.BindComputeTextureBuffer(index, image_view.GpuAddr(), image_view.BufferSize(), | 128 | buffer_cache.BindComputeTextureBuffer(index, image_view.GpuAddr(), image_view.BufferSize(), |
| 125 | image_view.format); | 129 | image_view.format, is_written); |
| 126 | ++texture_buffer_ids; | 130 | ++texture_buffer_ids; |
| 127 | ++index; | 131 | ++index; |
| 128 | } | 132 | }}; |
| 133 | std::ranges::for_each(info.texture_buffer_descriptors, add_buffer); | ||
| 134 | std::ranges::for_each(info.image_buffer_descriptors, add_buffer); | ||
| 135 | |||
| 129 | buffer_cache.UpdateComputeBuffers(); | 136 | buffer_cache.UpdateComputeBuffers(); |
| 130 | buffer_cache.BindHostComputeBuffers(); | 137 | buffer_cache.BindHostComputeBuffers(); |
| 131 | 138 | ||
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 23c01f24e..84720a6f9 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp | |||
| @@ -175,10 +175,12 @@ void GraphicsPipeline::Configure(bool is_indexed) { | |||
| 175 | const u32 raw_handle{gpu_memory.Read<u32>(addr)}; | 175 | const u32 raw_handle{gpu_memory.Read<u32>(addr)}; |
| 176 | return TextureHandle(raw_handle, via_header_index); | 176 | return TextureHandle(raw_handle, via_header_index); |
| 177 | }}; | 177 | }}; |
| 178 | for (const auto& desc : info.texture_buffer_descriptors) { | 178 | const auto add_image{[&](const auto& desc) { |
| 179 | const TextureHandle handle{read_handle(desc.cbuf_index, desc.cbuf_offset)}; | 179 | const TextureHandle handle{read_handle(desc.cbuf_index, desc.cbuf_offset)}; |
| 180 | image_view_indices.push_back(handle.image); | 180 | image_view_indices.push_back(handle.image); |
| 181 | } | 181 | }}; |
| 182 | std::ranges::for_each(info.texture_buffer_descriptors, add_image); | ||
| 183 | std::ranges::for_each(info.image_buffer_descriptors, add_image); | ||
| 182 | for (const auto& desc : info.texture_descriptors) { | 184 | for (const auto& desc : info.texture_descriptors) { |
| 183 | const TextureHandle handle{read_handle(desc.cbuf_index, desc.cbuf_offset)}; | 185 | const TextureHandle handle{read_handle(desc.cbuf_index, desc.cbuf_offset)}; |
| 184 | image_view_indices.push_back(handle.image); | 186 | image_view_indices.push_back(handle.image); |
| @@ -186,28 +188,33 @@ void GraphicsPipeline::Configure(bool is_indexed) { | |||
| 186 | Sampler* const sampler{texture_cache.GetGraphicsSampler(handle.sampler)}; | 188 | Sampler* const sampler{texture_cache.GetGraphicsSampler(handle.sampler)}; |
| 187 | samplers.push_back(sampler->Handle()); | 189 | samplers.push_back(sampler->Handle()); |
| 188 | } | 190 | } |
| 189 | for (const auto& desc : info.image_descriptors) { | 191 | std::ranges::for_each(info.image_descriptors, add_image); |
| 190 | const TextureHandle handle{read_handle(desc.cbuf_index, desc.cbuf_offset)}; | ||
| 191 | image_view_indices.push_back(handle.image); | ||
| 192 | } | ||
| 193 | } | 192 | } |
| 194 | const std::span indices_span(image_view_indices.data(), image_view_indices.size()); | 193 | const std::span indices_span(image_view_indices.data(), image_view_indices.size()); |
| 195 | texture_cache.FillGraphicsImageViews(indices_span, image_view_ids); | 194 | texture_cache.FillGraphicsImageViews(indices_span, image_view_ids); |
| 196 | 195 | ||
| 197 | ImageId* texture_buffer_index{image_view_ids.data()}; | 196 | ImageId* texture_buffer_index{image_view_ids.data()}; |
| 198 | for (size_t stage = 0; stage < Maxwell::MaxShaderStage; ++stage) { | 197 | for (size_t stage = 0; stage < Maxwell::MaxShaderStage; ++stage) { |
| 199 | const Shader::Info& info{stage_infos[stage]}; | ||
| 200 | buffer_cache.UnbindGraphicsTextureBuffers(stage); | ||
| 201 | size_t index{}; | 198 | size_t index{}; |
| 202 | for (const auto& desc : info.texture_buffer_descriptors) { | 199 | const auto add_buffer{[&](const auto& desc) { |
| 203 | ASSERT(desc.count == 1); | 200 | ASSERT(desc.count == 1); |
| 204 | ImageView& image_view = texture_cache.GetImageView(*texture_buffer_index); | 201 | bool is_written{false}; |
| 202 | if constexpr (std::is_same_v<decltype(desc), const Shader::ImageBufferDescriptor&>) { | ||
| 203 | is_written = desc.is_written; | ||
| 204 | } | ||
| 205 | ImageView& image_view{texture_cache.GetImageView(*texture_buffer_index)}; | ||
| 205 | buffer_cache.BindGraphicsTextureBuffer(stage, index, image_view.GpuAddr(), | 206 | buffer_cache.BindGraphicsTextureBuffer(stage, index, image_view.GpuAddr(), |
| 206 | image_view.BufferSize(), image_view.format); | 207 | image_view.BufferSize(), image_view.format, |
| 208 | is_written); | ||
| 207 | ++index; | 209 | ++index; |
| 208 | ++texture_buffer_index; | 210 | ++texture_buffer_index; |
| 209 | } | 211 | }}; |
| 212 | const Shader::Info& info{stage_infos[stage]}; | ||
| 213 | buffer_cache.UnbindGraphicsTextureBuffers(stage); | ||
| 214 | std::ranges::for_each(info.texture_buffer_descriptors, add_buffer); | ||
| 215 | std::ranges::for_each(info.image_buffer_descriptors, add_buffer); | ||
| 210 | texture_buffer_index += info.texture_descriptors.size(); | 216 | texture_buffer_index += info.texture_descriptors.size(); |
| 217 | texture_buffer_index += info.image_descriptors.size(); | ||
| 211 | } | 218 | } |
| 212 | buffer_cache.UpdateGraphicsBuffers(is_indexed); | 219 | buffer_cache.UpdateGraphicsBuffers(is_indexed); |
| 213 | 220 | ||