summaryrefslogtreecommitdiff
path: root/src/video_core/macro
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2022-11-09 17:58:10 +0100
committerGravatar Fernando Sahmkow2023-01-01 16:43:57 -0500
commitaad0cbf024fb8077a9b375a093c60a7e2ab1db3d (patch)
tree8c6a86c92ed8cedbafb5f34dd9f72283eaaf4342 /src/video_core/macro
parentMacroHLE: Add Index Buffer size estimation. (diff)
downloadyuzu-aad0cbf024fb8077a9b375a093c60a7e2ab1db3d.tar.gz
yuzu-aad0cbf024fb8077a9b375a093c60a7e2ab1db3d.tar.xz
yuzu-aad0cbf024fb8077a9b375a093c60a7e2ab1db3d.zip
MacroHLE: Add HLE replacement for base vertex and base instance.
Diffstat (limited to 'src/video_core/macro')
-rw-r--r--src/video_core/macro/macro_hle.cpp115
1 files changed, 56 insertions, 59 deletions
diff --git a/src/video_core/macro/macro_hle.cpp b/src/video_core/macro/macro_hle.cpp
index 93b6d42a4..638247e55 100644
--- a/src/video_core/macro/macro_hle.cpp
+++ b/src/video_core/macro/macro_hle.cpp
@@ -14,26 +14,29 @@
14#include "video_core/rasterizer_interface.h" 14#include "video_core/rasterizer_interface.h"
15 15
16namespace Tegra { 16namespace Tegra {
17
18using Maxwell = Engines::Maxwell3D;
19
17namespace { 20namespace {
18 21
19bool IsTopologySafe(Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology topology) { 22bool IsTopologySafe(Maxwell::Regs::PrimitiveTopology topology) {
20 switch (topology) { 23 switch (topology) {
21 case Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology::Points: 24 case Maxwell::Regs::PrimitiveTopology::Points:
22 case Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology::Lines: 25 case Maxwell::Regs::PrimitiveTopology::Lines:
23 case Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology::LineLoop: 26 case Maxwell::Regs::PrimitiveTopology::LineLoop:
24 case Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology::LineStrip: 27 case Maxwell::Regs::PrimitiveTopology::LineStrip:
25 case Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology::Triangles: 28 case Maxwell::Regs::PrimitiveTopology::Triangles:
26 case Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology::TriangleStrip: 29 case Maxwell::Regs::PrimitiveTopology::TriangleStrip:
27 case Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology::TriangleFan: 30 case Maxwell::Regs::PrimitiveTopology::TriangleFan:
28 case Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology::LinesAdjacency: 31 case Maxwell::Regs::PrimitiveTopology::LinesAdjacency:
29 case Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology::LineStripAdjacency: 32 case Maxwell::Regs::PrimitiveTopology::LineStripAdjacency:
30 case Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology::TrianglesAdjacency: 33 case Maxwell::Regs::PrimitiveTopology::TrianglesAdjacency:
31 case Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology::TriangleStripAdjacency: 34 case Maxwell::Regs::PrimitiveTopology::TriangleStripAdjacency:
32 case Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology::Patches: 35 case Maxwell::Regs::PrimitiveTopology::Patches:
33 return true; 36 return true;
34 case Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology::Quads: 37 case Maxwell::Regs::PrimitiveTopology::Quads:
35 case Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology::QuadStrip: 38 case Maxwell::Regs::PrimitiveTopology::QuadStrip:
36 case Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology::Polygon: 39 case Maxwell::Regs::PrimitiveTopology::Polygon:
37 default: 40 default:
38 return false; 41 return false;
39 } 42 }
@@ -82,8 +85,7 @@ public:
82 : HLEMacroImpl(maxwell3d_), extended(extended_) {} 85 : HLEMacroImpl(maxwell3d_), extended(extended_) {}
83 86
84 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override { 87 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override {
85 auto topology = 88 auto topology = static_cast<Maxwell::Regs::PrimitiveTopology>(parameters[0]);
86 static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[0]);
87 if (!IsTopologySafe(topology)) { 89 if (!IsTopologySafe(topology)) {
88 Fallback(parameters); 90 Fallback(parameters);
89 return; 91 return;
@@ -99,18 +101,16 @@ public:
99 params.stride = 0; 101 params.stride = 0;
100 102
101 if (extended) { 103 if (extended) {
102 maxwell3d.CallMethod(0x8e3, 0x640, true); 104 maxwell3d.engine_state = Maxwell::EngineHint::OnHLEMacro;
103 maxwell3d.CallMethod(0x8e4, parameters[4], true); 105 maxwell3d.setHLEReplacementName(0, 0x640, Maxwell::HLEReplaceName::BaseInstance);
104 } 106 }
105 107
106 maxwell3d.draw_manager->DrawArrayIndirect(topology); 108 maxwell3d.draw_manager->DrawArrayIndirect(topology);
107 109
108 if (extended) { 110 if (extended) {
109 maxwell3d.CallMethod(0x8e3, 0x640, true); 111 maxwell3d.engine_state = Maxwell::EngineHint::None;
110 maxwell3d.CallMethod(0x8e4, 0, true); 112 maxwell3d.replace_table.clear();
111 } 113 }
112 maxwell3d.regs.vertex_buffer.first = 0;
113 maxwell3d.regs.vertex_buffer.count = 0;
114 } 114 }
115 115
116private: 116private:
@@ -134,13 +134,18 @@ private:
134 134
135 const u32 base_instance = parameters[4]; 135 const u32 base_instance = parameters[4];
136 if (extended) { 136 if (extended) {
137 maxwell3d.CallMethod(0x8e3, 0x640, true); 137 maxwell3d.engine_state = Maxwell::EngineHint::OnHLEMacro;
138 maxwell3d.CallMethod(0x8e4, base_instance, true); 138 maxwell3d.setHLEReplacementName(0, 0x640, Maxwell::HLEReplaceName::BaseInstance);
139 } 139 }
140 140
141 maxwell3d.draw_manager->DrawArray( 141 maxwell3d.draw_manager->DrawArray(
142 static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[0]), 142 static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[0]),
143 vertex_first, vertex_count, base_instance, instance_count); 143 vertex_first, vertex_count, base_instance, instance_count);
144
145 if (extended) {
146 maxwell3d.engine_state = Maxwell::EngineHint::None;
147 maxwell3d.replace_table.clear();
148 }
144 } 149 }
145 150
146 bool extended; 151 bool extended;
@@ -151,8 +156,7 @@ public:
151 explicit HLE_DrawIndexedIndirect(Engines::Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {} 156 explicit HLE_DrawIndexedIndirect(Engines::Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {}
152 157
153 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override { 158 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override {
154 auto topology = 159 auto topology = static_cast<Maxwell::Regs::PrimitiveTopology>(parameters[0]);
155 static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[0]);
156 if (!IsTopologySafe(topology)) { 160 if (!IsTopologySafe(topology)) {
157 Fallback(parameters); 161 Fallback(parameters);
158 return; 162 return;
@@ -164,16 +168,12 @@ public:
164 minimum_limit = std::max(parameters[3], minimum_limit); 168 minimum_limit = std::max(parameters[3], minimum_limit);
165 } 169 }
166 const u32 estimate = static_cast<u32>(maxwell3d.EstimateIndexBufferSize()); 170 const u32 estimate = static_cast<u32>(maxwell3d.EstimateIndexBufferSize());
167 const u32 base_size = std::max(minimum_limit, estimate); 171 const u32 base_size = std::max<u32>(minimum_limit, estimate);
168 const u32 element_base = parameters[4];
169 const u32 base_instance = parameters[5];
170 maxwell3d.regs.index_buffer.first = 0;
171 maxwell3d.regs.index_buffer.count = base_size; // Use a fixed size, just for mapping
172 maxwell3d.regs.draw.topology.Assign(topology); 172 maxwell3d.regs.draw.topology.Assign(topology);
173 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; 173 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
174 maxwell3d.CallMethod(0x8e3, 0x640, true); 174 maxwell3d.engine_state = Maxwell::EngineHint::OnHLEMacro;
175 maxwell3d.CallMethod(0x8e4, element_base, true); 175 maxwell3d.setHLEReplacementName(0, 0x640, Maxwell::HLEReplaceName::BaseVertex);
176 maxwell3d.CallMethod(0x8e5, base_instance, true); 176 maxwell3d.setHLEReplacementName(0, 0x644, Maxwell::HLEReplaceName::BaseInstance);
177 auto& params = maxwell3d.draw_manager->GetIndirectParams(); 177 auto& params = maxwell3d.draw_manager->GetIndirectParams();
178 params.is_indexed = true; 178 params.is_indexed = true;
179 params.include_count = false; 179 params.include_count = false;
@@ -184,9 +184,8 @@ public:
184 params.stride = 0; 184 params.stride = 0;
185 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; 185 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
186 maxwell3d.draw_manager->DrawIndexedIndirect(topology, 0, base_size); 186 maxwell3d.draw_manager->DrawIndexedIndirect(topology, 0, base_size);
187 maxwell3d.CallMethod(0x8e3, 0x640, true); 187 maxwell3d.engine_state = Maxwell::EngineHint::None;
188 maxwell3d.CallMethod(0x8e4, 0x0, true); 188 maxwell3d.replace_table.clear();
189 maxwell3d.CallMethod(0x8e5, 0x0, true);
190 } 189 }
191 190
192private: 191private:
@@ -197,18 +196,17 @@ private:
197 const u32 base_instance = parameters[5]; 196 const u32 base_instance = parameters[5];
198 maxwell3d.regs.vertex_id_base = element_base; 197 maxwell3d.regs.vertex_id_base = element_base;
199 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; 198 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
200 maxwell3d.CallMethod(0x8e3, 0x640, true); 199 maxwell3d.engine_state = Maxwell::EngineHint::OnHLEMacro;
201 maxwell3d.CallMethod(0x8e4, element_base, true); 200 maxwell3d.setHLEReplacementName(0, 0x640, Maxwell::HLEReplaceName::BaseVertex);
202 maxwell3d.CallMethod(0x8e5, base_instance, true); 201 maxwell3d.setHLEReplacementName(0, 0x644, Maxwell::HLEReplaceName::BaseInstance);
203 202
204 maxwell3d.draw_manager->DrawIndex( 203 maxwell3d.draw_manager->DrawIndex(
205 static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[0]), 204 static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[0]),
206 parameters[3], parameters[1], element_base, base_instance, instance_count); 205 parameters[3], parameters[1], element_base, base_instance, instance_count);
207 206
208 maxwell3d.regs.vertex_id_base = 0x0; 207 maxwell3d.regs.vertex_id_base = 0x0;
209 maxwell3d.CallMethod(0x8e3, 0x640, true); 208 maxwell3d.engine_state = Maxwell::EngineHint::None;
210 maxwell3d.CallMethod(0x8e4, 0x0, true); 209 maxwell3d.replace_table.clear();
211 maxwell3d.CallMethod(0x8e5, 0x0, true);
212 } 210 }
213 211
214 u32 minimum_limit{1 << 18}; 212 u32 minimum_limit{1 << 18};
@@ -238,8 +236,7 @@ public:
238 : HLEMacroImpl(maxwell3d_) {} 236 : HLEMacroImpl(maxwell3d_) {}
239 237
240 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override { 238 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override {
241 const auto topology = 239 const auto topology = static_cast<Maxwell::Regs::PrimitiveTopology>(parameters[2]);
242 static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[2]);
243 if (!IsTopologySafe(topology)) { 240 if (!IsTopologySafe(topology)) {
244 Fallback(parameters); 241 Fallback(parameters);
245 return; 242 return;
@@ -277,9 +274,6 @@ public:
277 } 274 }
278 const u32 estimate = static_cast<u32>(maxwell3d.EstimateIndexBufferSize()); 275 const u32 estimate = static_cast<u32>(maxwell3d.EstimateIndexBufferSize());
279 const u32 base_size = std::max(minimum_limit, estimate); 276 const u32 base_size = std::max(minimum_limit, estimate);
280
281 maxwell3d.regs.index_buffer.first = 0;
282 maxwell3d.regs.index_buffer.count = std::max(highest_limit, base_size);
283 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; 277 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
284 auto& params = maxwell3d.draw_manager->GetIndirectParams(); 278 auto& params = maxwell3d.draw_manager->GetIndirectParams();
285 params.is_indexed = true; 279 params.is_indexed = true;
@@ -290,7 +284,12 @@ public:
290 params.max_draw_counts = draw_count; 284 params.max_draw_counts = draw_count;
291 params.stride = stride; 285 params.stride = stride;
292 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; 286 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
293 maxwell3d.draw_manager->DrawIndexedIndirect(topology, 0, highest_limit); 287 maxwell3d.engine_state = Maxwell::EngineHint::OnHLEMacro;
288 maxwell3d.setHLEReplacementName(0, 0x640, Maxwell::HLEReplaceName::BaseVertex);
289 maxwell3d.setHLEReplacementName(0, 0x644, Maxwell::HLEReplaceName::BaseInstance);
290 maxwell3d.draw_manager->DrawIndexedIndirect(topology, 0, base_size);
291 maxwell3d.engine_state = Maxwell::EngineHint::None;
292 maxwell3d.replace_table.clear();
294 } 293 }
295 294
296private: 295private:
@@ -299,9 +298,8 @@ private:
299 // Clean everything. 298 // Clean everything.
300 // Clean everything. 299 // Clean everything.
301 maxwell3d.regs.vertex_id_base = 0x0; 300 maxwell3d.regs.vertex_id_base = 0x0;
302 maxwell3d.CallMethod(0x8e3, 0x640, true); 301 maxwell3d.engine_state = Maxwell::EngineHint::None;
303 maxwell3d.CallMethod(0x8e4, 0x0, true); 302 maxwell3d.replace_table.clear();
304 maxwell3d.CallMethod(0x8e5, 0x0, true);
305 }); 303 });
306 maxwell3d.RefreshParameters(); 304 maxwell3d.RefreshParameters();
307 const u32 start_indirect = parameters[0]; 305 const u32 start_indirect = parameters[0];
@@ -310,8 +308,7 @@ private:
310 // Nothing to do. 308 // Nothing to do.
311 return; 309 return;
312 } 310 }
313 const auto topology = 311 const auto topology = static_cast<Maxwell::Regs::PrimitiveTopology>(parameters[2]);
314 static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[2]);
315 maxwell3d.regs.draw.topology.Assign(topology); 312 maxwell3d.regs.draw.topology.Assign(topology);
316 const u32 padding = parameters[3]; 313 const u32 padding = parameters[3];
317 const std::size_t max_draws = parameters[4]; 314 const std::size_t max_draws = parameters[4];
@@ -326,9 +323,9 @@ private:
326 const u32 base_vertex = parameters[base + 3]; 323 const u32 base_vertex = parameters[base + 3];
327 const u32 base_instance = parameters[base + 4]; 324 const u32 base_instance = parameters[base + 4];
328 maxwell3d.regs.vertex_id_base = base_vertex; 325 maxwell3d.regs.vertex_id_base = base_vertex;
329 maxwell3d.CallMethod(0x8e3, 0x640, true); 326 maxwell3d.engine_state = Maxwell::EngineHint::OnHLEMacro;
330 maxwell3d.CallMethod(0x8e4, base_vertex, true); 327 maxwell3d.setHLEReplacementName(0, 0x640, Maxwell::HLEReplaceName::BaseVertex);
331 maxwell3d.CallMethod(0x8e5, base_instance, true); 328 maxwell3d.setHLEReplacementName(0, 0x644, Maxwell::HLEReplaceName::BaseInstance);
332 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; 329 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
333 maxwell3d.draw_manager->DrawIndex(topology, parameters[base + 2], parameters[base], 330 maxwell3d.draw_manager->DrawIndex(topology, parameters[base + 2], parameters[base],
334 base_vertex, base_instance, parameters[base + 1]); 331 base_vertex, base_instance, parameters[base + 1]);