summaryrefslogtreecommitdiff
path: root/src/video_core/macro
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2022-02-09 15:00:05 +0100
committerGravatar Fernando Sahmkow2023-01-01 16:43:57 -0500
commita5a94f52ffcbf3119d272a9369021a213ea6dad2 (patch)
treeba6d42b142894d0f3f0ac34fb6ce491442bae8fd /src/video_core/macro
parentMerge pull request #9538 from merryhime/char-concat (diff)
downloadyuzu-a5a94f52ffcbf3119d272a9369021a213ea6dad2.tar.gz
yuzu-a5a94f52ffcbf3119d272a9369021a213ea6dad2.tar.xz
yuzu-a5a94f52ffcbf3119d272a9369021a213ea6dad2.zip
MacroHLE: Add MultidrawIndirect HLE Macro.
Diffstat (limited to 'src/video_core/macro')
-rw-r--r--src/video_core/macro/macro_hle.cpp53
1 files changed, 27 insertions, 26 deletions
diff --git a/src/video_core/macro/macro_hle.cpp b/src/video_core/macro/macro_hle.cpp
index 8549db2e4..1cc202cc7 100644
--- a/src/video_core/macro/macro_hle.cpp
+++ b/src/video_core/macro/macro_hle.cpp
@@ -53,42 +53,43 @@ void HLE_0217920100488FF7(Engines::Maxwell3D& maxwell3d, const std::vector<u32>&
53 53
54// Multidraw Indirect 54// Multidraw Indirect
55void HLE_3F5E74B9C9A50164(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& parameters) { 55void HLE_3F5E74B9C9A50164(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& parameters) {
56 SCOPE_EXIT({
57 // Clean everything.
58 maxwell3d.regs.vertex_id_base = 0x0;
59 maxwell3d.CallMethod(0x8e3, 0x640, true);
60 maxwell3d.CallMethod(0x8e4, 0x0, true);
61 maxwell3d.CallMethod(0x8e5, 0x0, true);
62 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
63 });
64 const u32 start_indirect = parameters[0]; 56 const u32 start_indirect = parameters[0];
65 const u32 end_indirect = parameters[1]; 57 const u32 end_indirect = parameters[1];
66 if (start_indirect >= end_indirect) { 58 if (start_indirect >= end_indirect) {
67 // Nothing to do. 59 // Nothing to do.
68 return; 60 return;
69 } 61 }
70 const u32 padding = parameters[3]; 62 const auto topology =
71 const std::size_t max_draws = parameters[4]; 63 static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[2]);
64 const u32 padding = parameters[3]; // padding is in words
72 65
66 // size of each indirect segment
73 const u32 indirect_words = 5 + padding; 67 const u32 indirect_words = 5 + padding;
74 const std::size_t first_draw = start_indirect; 68 const u32 stride = indirect_words * sizeof(u32);
75 const std::size_t effective_draws = end_indirect - start_indirect; 69 const GPUVAddr start_address = maxwell3d.current_dma_segment + 4 * sizeof(u32);
76 const std::size_t last_draw = start_indirect + std::min(effective_draws, max_draws); 70 const std::size_t draw_count = end_indirect - start_indirect;
77 71 u32 lowest_first = std::numeric_limits<u32>::max();
78 for (std::size_t index = first_draw; index < last_draw; index++) { 72 u32 highest_limit = std::numeric_limits<u32>::min();
73 for (std::size_t index = 0; index < draw_count; index++) {
79 const std::size_t base = index * indirect_words + 5; 74 const std::size_t base = index * indirect_words + 5;
80 const u32 base_vertex = parameters[base + 3]; 75 const u32 count = parameters[base];
81 const u32 base_instance = parameters[base + 4]; 76 const u32 first_index = parameters[base + 2];
82 maxwell3d.regs.vertex_id_base = base_vertex; 77 lowest_first = std::min(lowest_first, first_index);
83 maxwell3d.CallMethod(0x8e3, 0x640, true); 78 highest_limit = std::max(highest_limit, first_index + count);
84 maxwell3d.CallMethod(0x8e4, base_vertex, true);
85 maxwell3d.CallMethod(0x8e5, base_instance, true);
86 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
87 maxwell3d.draw_manager->DrawIndex(
88 static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[2]),
89 parameters[base + 2], parameters[base], base_vertex, base_instance,
90 parameters[base + 1]);
91 } 79 }
80
81 const u32 base_vertex = parameters[8];
82 const u32 base_instance = parameters[9];
83 maxwell3d.CallMethod(0x8e3, 0x640, true);
84 maxwell3d.CallMethod(0x8e4, base_vertex, true);
85 maxwell3d.CallMethod(0x8e5, base_instance, true);
86 auto& params = maxwell3d.draw_manager->GetIndirectParams();
87 params.start_address = start_address;
88 params.buffer_size = sizeof(u32) + stride * draw_count;
89 params.max_draw_counts = draw_count;
90 params.stride = stride;
91 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
92 maxwell3d.draw_manager->DrawIndexedIndirect(topology, 0, highest_limit);
92} 93}
93 94
94// Multi-layer Clear 95// Multi-layer Clear