diff options
| author | 2022-11-09 17:58:10 +0100 | |
|---|---|---|
| committer | 2023-01-01 16:43:57 -0500 | |
| commit | aad0cbf024fb8077a9b375a093c60a7e2ab1db3d (patch) | |
| tree | 8c6a86c92ed8cedbafb5f34dd9f72283eaaf4342 /src/video_core/macro | |
| parent | MacroHLE: Add Index Buffer size estimation. (diff) | |
| download | yuzu-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.cpp | 115 |
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 | ||
| 16 | namespace Tegra { | 16 | namespace Tegra { |
| 17 | |||
| 18 | using Maxwell = Engines::Maxwell3D; | ||
| 19 | |||
| 17 | namespace { | 20 | namespace { |
| 18 | 21 | ||
| 19 | bool IsTopologySafe(Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology topology) { | 22 | bool 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 | ||
| 116 | private: | 116 | private: |
| @@ -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 | ||
| 192 | private: | 191 | private: |
| @@ -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 | ||
| 296 | private: | 295 | private: |
| @@ -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]); |