diff options
| author | 2023-01-04 21:20:00 -0500 | |
|---|---|---|
| committer | 2023-01-04 21:20:00 -0500 | |
| commit | b78328f19a54964ef6874281d1a4d6b6ad1c34d9 (patch) | |
| tree | 239947ad53a4a06c3641d58c5d6b8daf5b3dc16a /src/video_core/buffer_cache | |
| parent | Merge pull request #9518 from gidoly/revert-9504-pg2 (diff) | |
| parent | yuzu-ui: Add setting for disabling macro HLE (diff) | |
| download | yuzu-b78328f19a54964ef6874281d1a4d6b6ad1c34d9.tar.gz yuzu-b78328f19a54964ef6874281d1a4d6b6ad1c34d9.tar.xz yuzu-b78328f19a54964ef6874281d1a4d6b6ad1c34d9.zip | |
Merge pull request #9501 from FernandoS27/yfc-rel-2
Yuzu Fried Chicken Part 1.5: MacroHLE Rework and Dynamic State
Diffstat (limited to 'src/video_core/buffer_cache')
| -rw-r--r-- | src/video_core/buffer_cache/buffer_cache.h | 76 |
1 files changed, 73 insertions, 3 deletions
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index f1c60d1f3..06fd40851 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h | |||
| @@ -200,7 +200,16 @@ public: | |||
| 200 | /// Return true when a CPU region is modified from the CPU | 200 | /// Return true when a CPU region is modified from the CPU |
| 201 | [[nodiscard]] bool IsRegionCpuModified(VAddr addr, size_t size); | 201 | [[nodiscard]] bool IsRegionCpuModified(VAddr addr, size_t size); |
| 202 | 202 | ||
| 203 | std::mutex mutex; | 203 | void SetDrawIndirect( |
| 204 | const Tegra::Engines::DrawManager::IndirectParams* current_draw_indirect_) { | ||
| 205 | current_draw_indirect = current_draw_indirect_; | ||
| 206 | } | ||
| 207 | |||
| 208 | [[nodiscard]] std::pair<Buffer*, u32> GetDrawIndirectCount(); | ||
| 209 | |||
| 210 | [[nodiscard]] std::pair<Buffer*, u32> GetDrawIndirectBuffer(); | ||
| 211 | |||
| 212 | std::recursive_mutex mutex; | ||
| 204 | Runtime& runtime; | 213 | Runtime& runtime; |
| 205 | 214 | ||
| 206 | private: | 215 | private: |
| @@ -272,6 +281,8 @@ private: | |||
| 272 | 281 | ||
| 273 | void BindHostVertexBuffers(); | 282 | void BindHostVertexBuffers(); |
| 274 | 283 | ||
| 284 | void BindHostDrawIndirectBuffers(); | ||
| 285 | |||
| 275 | void BindHostGraphicsUniformBuffers(size_t stage); | 286 | void BindHostGraphicsUniformBuffers(size_t stage); |
| 276 | 287 | ||
| 277 | void BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32 binding_index, bool needs_bind); | 288 | void BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32 binding_index, bool needs_bind); |
| @@ -298,6 +309,8 @@ private: | |||
| 298 | 309 | ||
| 299 | void UpdateVertexBuffer(u32 index); | 310 | void UpdateVertexBuffer(u32 index); |
| 300 | 311 | ||
| 312 | void UpdateDrawIndirect(); | ||
| 313 | |||
| 301 | void UpdateUniformBuffers(size_t stage); | 314 | void UpdateUniformBuffers(size_t stage); |
| 302 | 315 | ||
| 303 | void UpdateStorageBuffers(size_t stage); | 316 | void UpdateStorageBuffers(size_t stage); |
| @@ -372,6 +385,8 @@ private: | |||
| 372 | SlotVector<Buffer> slot_buffers; | 385 | SlotVector<Buffer> slot_buffers; |
| 373 | DelayedDestructionRing<Buffer, 8> delayed_destruction_ring; | 386 | DelayedDestructionRing<Buffer, 8> delayed_destruction_ring; |
| 374 | 387 | ||
| 388 | const Tegra::Engines::DrawManager::IndirectParams* current_draw_indirect{}; | ||
| 389 | |||
| 375 | u32 last_index_count = 0; | 390 | u32 last_index_count = 0; |
| 376 | 391 | ||
| 377 | Binding index_buffer; | 392 | Binding index_buffer; |
| @@ -380,6 +395,8 @@ private: | |||
| 380 | std::array<std::array<Binding, NUM_STORAGE_BUFFERS>, NUM_STAGES> storage_buffers; | 395 | std::array<std::array<Binding, NUM_STORAGE_BUFFERS>, NUM_STAGES> storage_buffers; |
| 381 | std::array<std::array<TextureBufferBinding, NUM_TEXTURE_BUFFERS>, NUM_STAGES> texture_buffers; | 396 | std::array<std::array<TextureBufferBinding, NUM_TEXTURE_BUFFERS>, NUM_STAGES> texture_buffers; |
| 382 | std::array<Binding, NUM_TRANSFORM_FEEDBACK_BUFFERS> transform_feedback_buffers; | 397 | std::array<Binding, NUM_TRANSFORM_FEEDBACK_BUFFERS> transform_feedback_buffers; |
| 398 | Binding count_buffer_binding; | ||
| 399 | Binding indirect_buffer_binding; | ||
| 383 | 400 | ||
| 384 | std::array<Binding, NUM_COMPUTE_UNIFORM_BUFFERS> compute_uniform_buffers; | 401 | std::array<Binding, NUM_COMPUTE_UNIFORM_BUFFERS> compute_uniform_buffers; |
| 385 | std::array<Binding, NUM_STORAGE_BUFFERS> compute_storage_buffers; | 402 | std::array<Binding, NUM_STORAGE_BUFFERS> compute_storage_buffers; |
| @@ -674,6 +691,9 @@ void BufferCache<P>::BindHostGeometryBuffers(bool is_indexed) { | |||
| 674 | } | 691 | } |
| 675 | BindHostVertexBuffers(); | 692 | BindHostVertexBuffers(); |
| 676 | BindHostTransformFeedbackBuffers(); | 693 | BindHostTransformFeedbackBuffers(); |
| 694 | if (current_draw_indirect) { | ||
| 695 | BindHostDrawIndirectBuffers(); | ||
| 696 | } | ||
| 677 | } | 697 | } |
| 678 | 698 | ||
| 679 | template <class P> | 699 | template <class P> |
| @@ -823,6 +843,7 @@ bool BufferCache<P>::ShouldWaitAsyncFlushes() const noexcept { | |||
| 823 | template <class P> | 843 | template <class P> |
| 824 | void BufferCache<P>::CommitAsyncFlushesHigh() { | 844 | void BufferCache<P>::CommitAsyncFlushesHigh() { |
| 825 | AccumulateFlushes(); | 845 | AccumulateFlushes(); |
| 846 | |||
| 826 | if (committed_ranges.empty()) { | 847 | if (committed_ranges.empty()) { |
| 827 | return; | 848 | return; |
| 828 | } | 849 | } |
| @@ -869,7 +890,7 @@ void BufferCache<P>::CommitAsyncFlushesHigh() { | |||
| 869 | buffer_id, | 890 | buffer_id, |
| 870 | }); | 891 | }); |
| 871 | // Align up to avoid cache conflicts | 892 | // Align up to avoid cache conflicts |
| 872 | constexpr u64 align = 256ULL; | 893 | constexpr u64 align = 8ULL; |
| 873 | constexpr u64 mask = ~(align - 1ULL); | 894 | constexpr u64 mask = ~(align - 1ULL); |
| 874 | total_size_bytes += (new_size + align - 1) & mask; | 895 | total_size_bytes += (new_size + align - 1) & mask; |
| 875 | largest_copy = std::max(largest_copy, new_size); | 896 | largest_copy = std::max(largest_copy, new_size); |
| @@ -1042,6 +1063,19 @@ void BufferCache<P>::BindHostVertexBuffers() { | |||
| 1042 | } | 1063 | } |
| 1043 | 1064 | ||
| 1044 | template <class P> | 1065 | template <class P> |
| 1066 | void BufferCache<P>::BindHostDrawIndirectBuffers() { | ||
| 1067 | const auto bind_buffer = [this](const Binding& binding) { | ||
| 1068 | Buffer& buffer = slot_buffers[binding.buffer_id]; | ||
| 1069 | TouchBuffer(buffer, binding.buffer_id); | ||
| 1070 | SynchronizeBuffer(buffer, binding.cpu_addr, binding.size); | ||
| 1071 | }; | ||
| 1072 | if (current_draw_indirect->include_count) { | ||
| 1073 | bind_buffer(count_buffer_binding); | ||
| 1074 | } | ||
| 1075 | bind_buffer(indirect_buffer_binding); | ||
| 1076 | } | ||
| 1077 | |||
| 1078 | template <class P> | ||
| 1045 | void BufferCache<P>::BindHostGraphicsUniformBuffers(size_t stage) { | 1079 | void BufferCache<P>::BindHostGraphicsUniformBuffers(size_t stage) { |
| 1046 | u32 dirty = ~0U; | 1080 | u32 dirty = ~0U; |
| 1047 | if constexpr (HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS) { | 1081 | if constexpr (HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS) { |
| @@ -1272,6 +1306,9 @@ void BufferCache<P>::DoUpdateGraphicsBuffers(bool is_indexed) { | |||
| 1272 | UpdateStorageBuffers(stage); | 1306 | UpdateStorageBuffers(stage); |
| 1273 | UpdateTextureBuffers(stage); | 1307 | UpdateTextureBuffers(stage); |
| 1274 | } | 1308 | } |
| 1309 | if (current_draw_indirect) { | ||
| 1310 | UpdateDrawIndirect(); | ||
| 1311 | } | ||
| 1275 | } while (has_deleted_buffers); | 1312 | } while (has_deleted_buffers); |
| 1276 | } | 1313 | } |
| 1277 | 1314 | ||
| @@ -1289,7 +1326,7 @@ void BufferCache<P>::UpdateIndexBuffer() { | |||
| 1289 | const auto& draw_state = maxwell3d->draw_manager->GetDrawState(); | 1326 | const auto& draw_state = maxwell3d->draw_manager->GetDrawState(); |
| 1290 | const auto& index_array = draw_state.index_buffer; | 1327 | const auto& index_array = draw_state.index_buffer; |
| 1291 | auto& flags = maxwell3d->dirty.flags; | 1328 | auto& flags = maxwell3d->dirty.flags; |
| 1292 | if (!flags[Dirty::IndexBuffer] && last_index_count == index_array.count) { | 1329 | if (!flags[Dirty::IndexBuffer]) { |
| 1293 | return; | 1330 | return; |
| 1294 | } | 1331 | } |
| 1295 | flags[Dirty::IndexBuffer] = false; | 1332 | flags[Dirty::IndexBuffer] = false; |
| @@ -1362,6 +1399,27 @@ void BufferCache<P>::UpdateVertexBuffer(u32 index) { | |||
| 1362 | } | 1399 | } |
| 1363 | 1400 | ||
| 1364 | template <class P> | 1401 | template <class P> |
| 1402 | void BufferCache<P>::UpdateDrawIndirect() { | ||
| 1403 | const auto update = [this](GPUVAddr gpu_addr, size_t size, Binding& binding) { | ||
| 1404 | const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr); | ||
| 1405 | if (!cpu_addr) { | ||
| 1406 | binding = NULL_BINDING; | ||
| 1407 | return; | ||
| 1408 | } | ||
| 1409 | binding = Binding{ | ||
| 1410 | .cpu_addr = *cpu_addr, | ||
| 1411 | .size = static_cast<u32>(size), | ||
| 1412 | .buffer_id = FindBuffer(*cpu_addr, static_cast<u32>(size)), | ||
| 1413 | }; | ||
| 1414 | }; | ||
| 1415 | if (current_draw_indirect->include_count) { | ||
| 1416 | update(current_draw_indirect->count_start_address, sizeof(u32), count_buffer_binding); | ||
| 1417 | } | ||
| 1418 | update(current_draw_indirect->indirect_start_address, current_draw_indirect->buffer_size, | ||
| 1419 | indirect_buffer_binding); | ||
| 1420 | } | ||
| 1421 | |||
| 1422 | template <class P> | ||
| 1365 | void BufferCache<P>::UpdateUniformBuffers(size_t stage) { | 1423 | void BufferCache<P>::UpdateUniformBuffers(size_t stage) { |
| 1366 | ForEachEnabledBit(enabled_uniform_buffer_masks[stage], [&](u32 index) { | 1424 | ForEachEnabledBit(enabled_uniform_buffer_masks[stage], [&](u32 index) { |
| 1367 | Binding& binding = uniform_buffers[stage][index]; | 1425 | Binding& binding = uniform_buffers[stage][index]; |
| @@ -1941,4 +1999,16 @@ bool BufferCache<P>::HasFastUniformBufferBound(size_t stage, u32 binding_index) | |||
| 1941 | } | 1999 | } |
| 1942 | } | 2000 | } |
| 1943 | 2001 | ||
| 2002 | template <class P> | ||
| 2003 | std::pair<typename BufferCache<P>::Buffer*, u32> BufferCache<P>::GetDrawIndirectCount() { | ||
| 2004 | auto& buffer = slot_buffers[count_buffer_binding.buffer_id]; | ||
| 2005 | return std::make_pair(&buffer, buffer.Offset(count_buffer_binding.cpu_addr)); | ||
| 2006 | } | ||
| 2007 | |||
| 2008 | template <class P> | ||
| 2009 | std::pair<typename BufferCache<P>::Buffer*, u32> BufferCache<P>::GetDrawIndirectBuffer() { | ||
| 2010 | auto& buffer = slot_buffers[indirect_buffer_binding.buffer_id]; | ||
| 2011 | return std::make_pair(&buffer, buffer.Offset(indirect_buffer_binding.cpu_addr)); | ||
| 2012 | } | ||
| 2013 | |||
| 1944 | } // namespace VideoCommon | 2014 | } // namespace VideoCommon |