summaryrefslogtreecommitdiff
path: root/src/video_core/buffer_cache
diff options
context:
space:
mode:
authorGravatar liamwhite2023-01-04 21:20:00 -0500
committerGravatar GitHub2023-01-04 21:20:00 -0500
commitb78328f19a54964ef6874281d1a4d6b6ad1c34d9 (patch)
tree239947ad53a4a06c3641d58c5d6b8daf5b3dc16a /src/video_core/buffer_cache
parentMerge pull request #9518 from gidoly/revert-9504-pg2 (diff)
parentyuzu-ui: Add setting for disabling macro HLE (diff)
downloadyuzu-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.h76
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
206private: 215private:
@@ -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
679template <class P> 699template <class P>
@@ -823,6 +843,7 @@ bool BufferCache<P>::ShouldWaitAsyncFlushes() const noexcept {
823template <class P> 843template <class P>
824void BufferCache<P>::CommitAsyncFlushesHigh() { 844void 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
1044template <class P> 1065template <class P>
1066void 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
1078template <class P>
1045void BufferCache<P>::BindHostGraphicsUniformBuffers(size_t stage) { 1079void 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
1364template <class P> 1401template <class P>
1402void 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
1422template <class P>
1365void BufferCache<P>::UpdateUniformBuffers(size_t stage) { 1423void 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
2002template <class P>
2003std::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
2008template <class P>
2009std::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