diff options
Diffstat (limited to 'src/video_core/buffer_cache')
| -rw-r--r-- | src/video_core/buffer_cache/buffer_cache.h | 53 |
1 files changed, 34 insertions, 19 deletions
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 29746f61d..6c92e4c30 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h | |||
| @@ -70,8 +70,8 @@ class BufferCache { | |||
| 70 | P::HAS_FULL_INDEX_AND_PRIMITIVE_SUPPORT; | 70 | P::HAS_FULL_INDEX_AND_PRIMITIVE_SUPPORT; |
| 71 | static constexpr bool NEEDS_BIND_UNIFORM_INDEX = P::NEEDS_BIND_UNIFORM_INDEX; | 71 | static constexpr bool NEEDS_BIND_UNIFORM_INDEX = P::NEEDS_BIND_UNIFORM_INDEX; |
| 72 | static constexpr bool NEEDS_BIND_STORAGE_INDEX = P::NEEDS_BIND_STORAGE_INDEX; | 72 | static constexpr bool NEEDS_BIND_STORAGE_INDEX = P::NEEDS_BIND_STORAGE_INDEX; |
| 73 | static constexpr bool NEEDS_BIND_TEXTURE_BUFFER_INDEX = P::NEEDS_BIND_TEXTURE_BUFFER_INDEX; | ||
| 74 | static constexpr bool USE_MEMORY_MAPS = P::USE_MEMORY_MAPS; | 73 | static constexpr bool USE_MEMORY_MAPS = P::USE_MEMORY_MAPS; |
| 74 | static constexpr bool SEPARATE_IMAGE_BUFFERS_BINDINGS = P::SEPARATE_IMAGE_BUFFER_BINDINGS; | ||
| 75 | 75 | ||
| 76 | static constexpr BufferId NULL_BUFFER_ID{0}; | 76 | static constexpr BufferId NULL_BUFFER_ID{0}; |
| 77 | 77 | ||
| @@ -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, bool is_written); | 157 | PixelFormat format, bool is_written, bool is_image); |
| 158 | 158 | ||
| 159 | void UnbindComputeStorageBuffers(); | 159 | void UnbindComputeStorageBuffers(); |
| 160 | 160 | ||
| @@ -164,7 +164,7 @@ public: | |||
| 164 | void UnbindComputeTextureBuffers(); | 164 | void UnbindComputeTextureBuffers(); |
| 165 | 165 | ||
| 166 | void BindComputeTextureBuffer(size_t tbo_index, GPUVAddr gpu_addr, u32 size, PixelFormat format, | 166 | void BindComputeTextureBuffer(size_t tbo_index, GPUVAddr gpu_addr, u32 size, PixelFormat format, |
| 167 | bool is_written); | 167 | bool is_written, bool is_image); |
| 168 | 168 | ||
| 169 | void FlushCachedWrites(); | 169 | void FlushCachedWrites(); |
| 170 | 170 | ||
| @@ -197,6 +197,7 @@ public: | |||
| 197 | [[nodiscard]] bool IsRegionCpuModified(VAddr addr, size_t size); | 197 | [[nodiscard]] bool IsRegionCpuModified(VAddr addr, size_t size); |
| 198 | 198 | ||
| 199 | std::mutex mutex; | 199 | std::mutex mutex; |
| 200 | Runtime& runtime; | ||
| 200 | 201 | ||
| 201 | private: | 202 | private: |
| 202 | template <typename Func> | 203 | template <typename Func> |
| @@ -366,7 +367,6 @@ private: | |||
| 366 | Tegra::Engines::KeplerCompute& kepler_compute; | 367 | Tegra::Engines::KeplerCompute& kepler_compute; |
| 367 | Tegra::MemoryManager& gpu_memory; | 368 | Tegra::MemoryManager& gpu_memory; |
| 368 | Core::Memory::Memory& cpu_memory; | 369 | Core::Memory::Memory& cpu_memory; |
| 369 | Runtime& runtime; | ||
| 370 | 370 | ||
| 371 | SlotVector<Buffer> slot_buffers; | 371 | SlotVector<Buffer> slot_buffers; |
| 372 | DelayedDestructionRing<Buffer, 8> delayed_destruction_ring; | 372 | DelayedDestructionRing<Buffer, 8> delayed_destruction_ring; |
| @@ -394,8 +394,10 @@ private: | |||
| 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 | std::array<u32, NUM_STAGES> written_texture_buffers{}; |
| 397 | std::array<u32, NUM_STAGES> image_texture_buffers{}; | ||
| 397 | u32 enabled_compute_texture_buffers = 0; | 398 | u32 enabled_compute_texture_buffers = 0; |
| 398 | u32 written_compute_texture_buffers = 0; | 399 | u32 written_compute_texture_buffers = 0; |
| 400 | u32 image_compute_texture_buffers = 0; | ||
| 399 | 401 | ||
| 400 | std::array<u32, NUM_STAGES> fast_bound_uniform_buffers{}; | 402 | std::array<u32, NUM_STAGES> fast_bound_uniform_buffers{}; |
| 401 | 403 | ||
| @@ -431,8 +433,8 @@ BufferCache<P>::BufferCache(VideoCore::RasterizerInterface& rasterizer_, | |||
| 431 | Tegra::Engines::KeplerCompute& kepler_compute_, | 433 | Tegra::Engines::KeplerCompute& kepler_compute_, |
| 432 | Tegra::MemoryManager& gpu_memory_, Core::Memory::Memory& cpu_memory_, | 434 | Tegra::MemoryManager& gpu_memory_, Core::Memory::Memory& cpu_memory_, |
| 433 | Runtime& runtime_) | 435 | Runtime& runtime_) |
| 434 | : rasterizer{rasterizer_}, maxwell3d{maxwell3d_}, kepler_compute{kepler_compute_}, | 436 | : runtime{runtime_}, rasterizer{rasterizer_}, maxwell3d{maxwell3d_}, |
| 435 | gpu_memory{gpu_memory_}, cpu_memory{cpu_memory_}, runtime{runtime_} { | 437 | kepler_compute{kepler_compute_}, gpu_memory{gpu_memory_}, cpu_memory{cpu_memory_} { |
| 436 | // Ensure the first slot is used for the null buffer | 438 | // Ensure the first slot is used for the null buffer |
| 437 | void(slot_buffers.insert(runtime, NullBufferParams{})); | 439 | void(slot_buffers.insert(runtime, NullBufferParams{})); |
| 438 | deletion_iterator = slot_buffers.end(); | 440 | deletion_iterator = slot_buffers.end(); |
| @@ -703,13 +705,18 @@ template <class P> | |||
| 703 | void BufferCache<P>::UnbindGraphicsTextureBuffers(size_t stage) { | 705 | void BufferCache<P>::UnbindGraphicsTextureBuffers(size_t stage) { |
| 704 | enabled_texture_buffers[stage] = 0; | 706 | enabled_texture_buffers[stage] = 0; |
| 705 | written_texture_buffers[stage] = 0; | 707 | written_texture_buffers[stage] = 0; |
| 708 | image_texture_buffers[stage] = 0; | ||
| 706 | } | 709 | } |
| 707 | 710 | ||
| 708 | template <class P> | 711 | template <class P> |
| 709 | void BufferCache<P>::BindGraphicsTextureBuffer(size_t stage, size_t tbo_index, GPUVAddr gpu_addr, | 712 | void BufferCache<P>::BindGraphicsTextureBuffer(size_t stage, size_t tbo_index, GPUVAddr gpu_addr, |
| 710 | u32 size, PixelFormat format, bool is_written) { | 713 | u32 size, PixelFormat format, bool is_written, |
| 714 | bool is_image) { | ||
| 711 | enabled_texture_buffers[stage] |= 1U << tbo_index; | 715 | enabled_texture_buffers[stage] |= 1U << tbo_index; |
| 712 | written_texture_buffers[stage] |= (is_written ? 1U : 0U) << tbo_index; | 716 | written_texture_buffers[stage] |= (is_written ? 1U : 0U) << tbo_index; |
| 717 | if constexpr (SEPARATE_IMAGE_BUFFERS_BINDINGS) { | ||
| 718 | image_texture_buffers[stage] |= (is_image ? 1U : 0U) << tbo_index; | ||
| 719 | } | ||
| 713 | texture_buffers[stage][tbo_index] = GetTextureBufferBinding(gpu_addr, size, format); | 720 | texture_buffers[stage][tbo_index] = GetTextureBufferBinding(gpu_addr, size, format); |
| 714 | } | 721 | } |
| 715 | 722 | ||
| @@ -717,6 +724,7 @@ template <class P> | |||
| 717 | void BufferCache<P>::UnbindComputeStorageBuffers() { | 724 | void BufferCache<P>::UnbindComputeStorageBuffers() { |
| 718 | enabled_compute_storage_buffers = 0; | 725 | enabled_compute_storage_buffers = 0; |
| 719 | written_compute_storage_buffers = 0; | 726 | written_compute_storage_buffers = 0; |
| 727 | image_compute_texture_buffers = 0; | ||
| 720 | } | 728 | } |
| 721 | 729 | ||
| 722 | template <class P> | 730 | template <class P> |
| @@ -737,13 +745,17 @@ template <class P> | |||
| 737 | void BufferCache<P>::UnbindComputeTextureBuffers() { | 745 | void BufferCache<P>::UnbindComputeTextureBuffers() { |
| 738 | enabled_compute_texture_buffers = 0; | 746 | enabled_compute_texture_buffers = 0; |
| 739 | written_compute_texture_buffers = 0; | 747 | written_compute_texture_buffers = 0; |
| 748 | image_compute_texture_buffers = 0; | ||
| 740 | } | 749 | } |
| 741 | 750 | ||
| 742 | template <class P> | 751 | template <class P> |
| 743 | void BufferCache<P>::BindComputeTextureBuffer(size_t tbo_index, GPUVAddr gpu_addr, u32 size, | 752 | void BufferCache<P>::BindComputeTextureBuffer(size_t tbo_index, GPUVAddr gpu_addr, u32 size, |
| 744 | PixelFormat format, bool is_written) { | 753 | PixelFormat format, bool is_written, bool is_image) { |
| 745 | enabled_compute_texture_buffers |= 1U << tbo_index; | 754 | enabled_compute_texture_buffers |= 1U << tbo_index; |
| 746 | written_compute_texture_buffers |= (is_written ? 1U : 0U) << tbo_index; | 755 | written_compute_texture_buffers |= (is_written ? 1U : 0U) << tbo_index; |
| 756 | if constexpr (SEPARATE_IMAGE_BUFFERS_BINDINGS) { | ||
| 757 | image_compute_texture_buffers |= (is_image ? 1U : 0U) << tbo_index; | ||
| 758 | } | ||
| 747 | compute_texture_buffers[tbo_index] = GetTextureBufferBinding(gpu_addr, size, format); | 759 | compute_texture_buffers[tbo_index] = GetTextureBufferBinding(gpu_addr, size, format); |
| 748 | } | 760 | } |
| 749 | 761 | ||
| @@ -1057,7 +1069,6 @@ void BufferCache<P>::BindHostGraphicsStorageBuffers(size_t stage) { | |||
| 1057 | 1069 | ||
| 1058 | template <class P> | 1070 | template <class P> |
| 1059 | void BufferCache<P>::BindHostGraphicsTextureBuffers(size_t stage) { | 1071 | void BufferCache<P>::BindHostGraphicsTextureBuffers(size_t stage) { |
| 1060 | u32 binding_index = 0; | ||
| 1061 | ForEachEnabledBit(enabled_texture_buffers[stage], [&](u32 index) { | 1072 | ForEachEnabledBit(enabled_texture_buffers[stage], [&](u32 index) { |
| 1062 | const TextureBufferBinding& binding = texture_buffers[stage][index]; | 1073 | const TextureBufferBinding& binding = texture_buffers[stage][index]; |
| 1063 | Buffer& buffer = slot_buffers[binding.buffer_id]; | 1074 | Buffer& buffer = slot_buffers[binding.buffer_id]; |
| @@ -1066,9 +1077,12 @@ void BufferCache<P>::BindHostGraphicsTextureBuffers(size_t stage) { | |||
| 1066 | 1077 | ||
| 1067 | const u32 offset = buffer.Offset(binding.cpu_addr); | 1078 | const u32 offset = buffer.Offset(binding.cpu_addr); |
| 1068 | const PixelFormat format = binding.format; | 1079 | const PixelFormat format = binding.format; |
| 1069 | if constexpr (NEEDS_BIND_TEXTURE_BUFFER_INDEX) { | 1080 | if constexpr (SEPARATE_IMAGE_BUFFERS_BINDINGS) { |
| 1070 | runtime.BindTextureBuffer(binding_index, buffer, offset, size, format); | 1081 | if (((image_texture_buffers[stage] >> index) & 1) != 0) { |
| 1071 | ++binding_index; | 1082 | runtime.BindImageBuffer(buffer, offset, size, format); |
| 1083 | } else { | ||
| 1084 | runtime.BindTextureBuffer(buffer, offset, size, format); | ||
| 1085 | } | ||
| 1072 | } else { | 1086 | } else { |
| 1073 | runtime.BindTextureBuffer(buffer, offset, size, format); | 1087 | runtime.BindTextureBuffer(buffer, offset, size, format); |
| 1074 | } | 1088 | } |
| @@ -1139,7 +1153,6 @@ void BufferCache<P>::BindHostComputeStorageBuffers() { | |||
| 1139 | 1153 | ||
| 1140 | template <class P> | 1154 | template <class P> |
| 1141 | void BufferCache<P>::BindHostComputeTextureBuffers() { | 1155 | void BufferCache<P>::BindHostComputeTextureBuffers() { |
| 1142 | u32 binding_index = 0; | ||
| 1143 | ForEachEnabledBit(enabled_compute_texture_buffers, [&](u32 index) { | 1156 | ForEachEnabledBit(enabled_compute_texture_buffers, [&](u32 index) { |
| 1144 | const TextureBufferBinding& binding = compute_texture_buffers[index]; | 1157 | const TextureBufferBinding& binding = compute_texture_buffers[index]; |
| 1145 | Buffer& buffer = slot_buffers[binding.buffer_id]; | 1158 | Buffer& buffer = slot_buffers[binding.buffer_id]; |
| @@ -1148,9 +1161,12 @@ void BufferCache<P>::BindHostComputeTextureBuffers() { | |||
| 1148 | 1161 | ||
| 1149 | const u32 offset = buffer.Offset(binding.cpu_addr); | 1162 | const u32 offset = buffer.Offset(binding.cpu_addr); |
| 1150 | const PixelFormat format = binding.format; | 1163 | const PixelFormat format = binding.format; |
| 1151 | if constexpr (NEEDS_BIND_TEXTURE_BUFFER_INDEX) { | 1164 | if constexpr (SEPARATE_IMAGE_BUFFERS_BINDINGS) { |
| 1152 | runtime.BindTextureBuffer(binding_index, buffer, offset, size, format); | 1165 | if (((image_compute_texture_buffers >> index) & 1) != 0) { |
| 1153 | ++binding_index; | 1166 | runtime.BindImageBuffer(buffer, offset, size, format); |
| 1167 | } else { | ||
| 1168 | runtime.BindTextureBuffer(buffer, offset, size, format); | ||
| 1169 | } | ||
| 1154 | } else { | 1170 | } else { |
| 1155 | runtime.BindTextureBuffer(buffer, offset, size, format); | 1171 | runtime.BindTextureBuffer(buffer, offset, size, format); |
| 1156 | } | 1172 | } |
| @@ -1339,11 +1355,10 @@ void BufferCache<P>::UpdateComputeStorageBuffers() { | |||
| 1339 | ForEachEnabledBit(enabled_compute_storage_buffers, [&](u32 index) { | 1355 | ForEachEnabledBit(enabled_compute_storage_buffers, [&](u32 index) { |
| 1340 | // Resolve buffer | 1356 | // Resolve buffer |
| 1341 | Binding& binding = compute_storage_buffers[index]; | 1357 | Binding& binding = compute_storage_buffers[index]; |
| 1342 | const BufferId buffer_id = FindBuffer(binding.cpu_addr, binding.size); | 1358 | binding.buffer_id = FindBuffer(binding.cpu_addr, binding.size); |
| 1343 | binding.buffer_id = buffer_id; | ||
| 1344 | // Mark as written if needed | 1359 | // Mark as written if needed |
| 1345 | if (((written_compute_storage_buffers >> index) & 1) != 0) { | 1360 | if (((written_compute_storage_buffers >> index) & 1) != 0) { |
| 1346 | MarkWrittenBuffer(buffer_id, binding.cpu_addr, binding.size); | 1361 | MarkWrittenBuffer(binding.buffer_id, binding.cpu_addr, binding.size); |
| 1347 | } | 1362 | } |
| 1348 | }); | 1363 | }); |
| 1349 | } | 1364 | } |