summaryrefslogtreecommitdiff
path: root/src/video_core/macro
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2023-01-03 10:01:25 -0500
committerGravatar Fernando Sahmkow2023-01-04 14:39:42 -0500
commita0c697124ced080f58866825e2e323e8682bbd7f (patch)
tree73830fc46134be10d7feffc3da11aa9f0ea58ffb /src/video_core/macro
parentTexture Cache: Implement async texture downloads. (diff)
downloadyuzu-a0c697124ced080f58866825e2e323e8682bbd7f.tar.gz
yuzu-a0c697124ced080f58866825e2e323e8682bbd7f.tar.xz
yuzu-a0c697124ced080f58866825e2e323e8682bbd7f.zip
Video_core: Address feedback
Diffstat (limited to 'src/video_core/macro')
-rw-r--r--src/video_core/macro/macro.cpp2
-rw-r--r--src/video_core/macro/macro_hle.cpp356
2 files changed, 249 insertions, 109 deletions
diff --git a/src/video_core/macro/macro.cpp b/src/video_core/macro/macro.cpp
index 49c47dafe..a96e8648c 100644
--- a/src/video_core/macro/macro.cpp
+++ b/src/video_core/macro/macro.cpp
@@ -23,7 +23,7 @@
23#include "video_core/macro/macro_jit_x64.h" 23#include "video_core/macro/macro_jit_x64.h"
24#endif 24#endif
25 25
26MICROPROFILE_DEFINE(MacroHLE, "GPU", "Execute macro hle", MP_RGB(128, 192, 192)); 26MICROPROFILE_DEFINE(MacroHLE, "GPU", "Execute macro HLE", MP_RGB(128, 192, 192));
27 27
28namespace Tegra { 28namespace Tegra {
29 29
diff --git a/src/video_core/macro/macro_hle.cpp b/src/video_core/macro/macro_hle.cpp
index c08b4abb3..a5476e795 100644
--- a/src/video_core/macro/macro_hle.cpp
+++ b/src/video_core/macro/macro_hle.cpp
@@ -1,5 +1,5 @@
1// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-3.0-or-later
3 3
4#include <array> 4#include <array>
5#include <vector> 5#include <vector>
@@ -15,28 +15,28 @@
15 15
16namespace Tegra { 16namespace Tegra {
17 17
18using Maxwell = Engines::Maxwell3D; 18using Maxwell3D = Engines::Maxwell3D;
19 19
20namespace { 20namespace {
21 21
22bool IsTopologySafe(Maxwell::Regs::PrimitiveTopology topology) { 22bool IsTopologySafe(Maxwell3D::Regs::PrimitiveTopology topology) {
23 switch (topology) { 23 switch (topology) {
24 case Maxwell::Regs::PrimitiveTopology::Points: 24 case Maxwell3D::Regs::PrimitiveTopology::Points:
25 case Maxwell::Regs::PrimitiveTopology::Lines: 25 case Maxwell3D::Regs::PrimitiveTopology::Lines:
26 case Maxwell::Regs::PrimitiveTopology::LineLoop: 26 case Maxwell3D::Regs::PrimitiveTopology::LineLoop:
27 case Maxwell::Regs::PrimitiveTopology::LineStrip: 27 case Maxwell3D::Regs::PrimitiveTopology::LineStrip:
28 case Maxwell::Regs::PrimitiveTopology::Triangles: 28 case Maxwell3D::Regs::PrimitiveTopology::Triangles:
29 case Maxwell::Regs::PrimitiveTopology::TriangleStrip: 29 case Maxwell3D::Regs::PrimitiveTopology::TriangleStrip:
30 case Maxwell::Regs::PrimitiveTopology::TriangleFan: 30 case Maxwell3D::Regs::PrimitiveTopology::TriangleFan:
31 case Maxwell::Regs::PrimitiveTopology::LinesAdjacency: 31 case Maxwell3D::Regs::PrimitiveTopology::LinesAdjacency:
32 case Maxwell::Regs::PrimitiveTopology::LineStripAdjacency: 32 case Maxwell3D::Regs::PrimitiveTopology::LineStripAdjacency:
33 case Maxwell::Regs::PrimitiveTopology::TrianglesAdjacency: 33 case Maxwell3D::Regs::PrimitiveTopology::TrianglesAdjacency:
34 case Maxwell::Regs::PrimitiveTopology::TriangleStripAdjacency: 34 case Maxwell3D::Regs::PrimitiveTopology::TriangleStripAdjacency:
35 case Maxwell::Regs::PrimitiveTopology::Patches: 35 case Maxwell3D::Regs::PrimitiveTopology::Patches:
36 return true; 36 return true;
37 case Maxwell::Regs::PrimitiveTopology::Quads: 37 case Maxwell3D::Regs::PrimitiveTopology::Quads:
38 case Maxwell::Regs::PrimitiveTopology::QuadStrip: 38 case Maxwell3D::Regs::PrimitiveTopology::QuadStrip:
39 case Maxwell::Regs::PrimitiveTopology::Polygon: 39 case Maxwell3D::Regs::PrimitiveTopology::Polygon:
40 default: 40 default:
41 return false; 41 return false;
42 } 42 }
@@ -44,34 +44,55 @@ bool IsTopologySafe(Maxwell::Regs::PrimitiveTopology topology) {
44 44
45class HLEMacroImpl : public CachedMacro { 45class HLEMacroImpl : public CachedMacro {
46public: 46public:
47 explicit HLEMacroImpl(Engines::Maxwell3D& maxwell3d_) : maxwell3d{maxwell3d_} {} 47 explicit HLEMacroImpl(Maxwell3D& maxwell3d_) : maxwell3d{maxwell3d_} {}
48 48
49protected: 49protected:
50 Engines::Maxwell3D& maxwell3d; 50 Maxwell3D& maxwell3d;
51}; 51};
52 52
53class HLE_771BB18C62444DA0 final : public HLEMacroImpl { 53class HLE_DrawArrays final : public HLEMacroImpl {
54public: 54public:
55 explicit HLE_771BB18C62444DA0(Engines::Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {} 55 explicit HLE_DrawArrays(Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {}
56 56
57 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override { 57 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override {
58 maxwell3d.RefreshParameters(); 58 maxwell3d.RefreshParameters();
59 const u32 instance_count = parameters[2] & maxwell3d.GetRegisterValue(0xD1B); 59
60 auto topology = static_cast<Maxwell3D::Regs::PrimitiveTopology>(parameters[0]);
61 maxwell3d.draw_manager->DrawArray(topology, parameters[1], parameters[2],
62 maxwell3d.regs.global_base_instance_index, 1);
63 }
64};
65
66class HLE_DrawIndexed final : public HLEMacroImpl {
67public:
68 explicit HLE_DrawIndexed(Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {}
69
70 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override {
71 maxwell3d.RefreshParameters();
72 maxwell3d.regs.index_buffer.start_addr_high = parameters[1];
73 maxwell3d.regs.index_buffer.start_addr_low = parameters[2];
74 maxwell3d.regs.index_buffer.format =
75 static_cast<Engines::Maxwell3D::Regs::IndexFormat>(parameters[3]);
60 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; 76 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
61 maxwell3d.draw_manager->DrawIndex( 77
62 static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[0] & 78 auto topology = static_cast<Maxwell3D::Regs::PrimitiveTopology>(parameters[0]);
63 0x3ffffff), 79 maxwell3d.draw_manager->DrawIndex(topology, 0, parameters[4],
64 parameters[4], parameters[1], parameters[3], parameters[5], instance_count); 80 maxwell3d.regs.global_base_vertex_index,
81 maxwell3d.regs.global_base_instance_index, 1);
65 } 82 }
66}; 83};
67 84
85/*
86 * @note: these macros have two versions, a normal and extended version, with the extended version
87 * also assigning the base vertex/instance.
88 */
89template <bool extended>
68class HLE_DrawArraysIndirect final : public HLEMacroImpl { 90class HLE_DrawArraysIndirect final : public HLEMacroImpl {
69public: 91public:
70 explicit HLE_DrawArraysIndirect(Engines::Maxwell3D& maxwell3d_, bool extended_ = false) 92 explicit HLE_DrawArraysIndirect(Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {}
71 : HLEMacroImpl(maxwell3d_), extended(extended_) {}
72 93
73 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override { 94 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override {
74 auto topology = static_cast<Maxwell::Regs::PrimitiveTopology>(parameters[0]); 95 auto topology = static_cast<Maxwell3D::Regs::PrimitiveTopology>(parameters[0]);
75 if (!maxwell3d.AnyParametersDirty() || !IsTopologySafe(topology)) { 96 if (!maxwell3d.AnyParametersDirty() || !IsTopologySafe(topology)) {
76 Fallback(parameters); 97 Fallback(parameters);
77 return; 98 return;
@@ -81,20 +102,21 @@ public:
81 params.is_indexed = false; 102 params.is_indexed = false;
82 params.include_count = false; 103 params.include_count = false;
83 params.count_start_address = 0; 104 params.count_start_address = 0;
84 params.indirect_start_address = maxwell3d.getMacroAddress(1); 105 params.indirect_start_address = maxwell3d.GetMacroAddress(1);
85 params.buffer_size = 4 * sizeof(u32); 106 params.buffer_size = 4 * sizeof(u32);
86 params.max_draw_counts = 1; 107 params.max_draw_counts = 1;
87 params.stride = 0; 108 params.stride = 0;
88 109
89 if (extended) { 110 if constexpr (extended) {
90 maxwell3d.engine_state = Maxwell::EngineHint::OnHLEMacro; 111 maxwell3d.engine_state = Maxwell3D::EngineHint::OnHLEMacro;
91 maxwell3d.setHLEReplacementName(0, 0x640, Maxwell::HLEReplaceName::BaseInstance); 112 maxwell3d.SetHLEReplacementAttributeType(
113 0, 0x640, Maxwell3D::HLEReplacementAttributeType::BaseInstance);
92 } 114 }
93 115
94 maxwell3d.draw_manager->DrawArrayIndirect(topology); 116 maxwell3d.draw_manager->DrawArrayIndirect(topology);
95 117
96 if (extended) { 118 if constexpr (extended) {
97 maxwell3d.engine_state = Maxwell::EngineHint::None; 119 maxwell3d.engine_state = Maxwell3D::EngineHint::None;
98 maxwell3d.replace_table.clear(); 120 maxwell3d.replace_table.clear();
99 } 121 }
100 } 122 }
@@ -103,14 +125,14 @@ private:
103 void Fallback(const std::vector<u32>& parameters) { 125 void Fallback(const std::vector<u32>& parameters) {
104 SCOPE_EXIT({ 126 SCOPE_EXIT({
105 if (extended) { 127 if (extended) {
106 maxwell3d.engine_state = Maxwell::EngineHint::None; 128 maxwell3d.engine_state = Maxwell3D::EngineHint::None;
107 maxwell3d.replace_table.clear(); 129 maxwell3d.replace_table.clear();
108 } 130 }
109 }); 131 });
110 maxwell3d.RefreshParameters(); 132 maxwell3d.RefreshParameters();
111 const u32 instance_count = (maxwell3d.GetRegisterValue(0xD1B) & parameters[2]); 133 const u32 instance_count = (maxwell3d.GetRegisterValue(0xD1B) & parameters[2]);
112 134
113 auto topology = static_cast<Maxwell::Regs::PrimitiveTopology>(parameters[0]); 135 auto topology = static_cast<Maxwell3D::Regs::PrimitiveTopology>(parameters[0]);
114 const u32 vertex_first = parameters[3]; 136 const u32 vertex_first = parameters[3];
115 const u32 vertex_count = parameters[1]; 137 const u32 vertex_count = parameters[1];
116 138
@@ -122,31 +144,35 @@ private:
122 } 144 }
123 145
124 const u32 base_instance = parameters[4]; 146 const u32 base_instance = parameters[4];
125 if (extended) { 147 if constexpr (extended) {
126 maxwell3d.regs.global_base_instance_index = base_instance; 148 maxwell3d.regs.global_base_instance_index = base_instance;
127 maxwell3d.engine_state = Maxwell::EngineHint::OnHLEMacro; 149 maxwell3d.engine_state = Maxwell3D::EngineHint::OnHLEMacro;
128 maxwell3d.setHLEReplacementName(0, 0x640, Maxwell::HLEReplaceName::BaseInstance); 150 maxwell3d.SetHLEReplacementAttributeType(
151 0, 0x640, Maxwell3D::HLEReplacementAttributeType::BaseInstance);
129 } 152 }
130 153
131 maxwell3d.draw_manager->DrawArray(topology, vertex_first, vertex_count, base_instance, 154 maxwell3d.draw_manager->DrawArray(topology, vertex_first, vertex_count, base_instance,
132 instance_count); 155 instance_count);
133 156
134 if (extended) { 157 if constexpr (extended) {
135 maxwell3d.regs.global_base_instance_index = 0; 158 maxwell3d.regs.global_base_instance_index = 0;
136 maxwell3d.engine_state = Maxwell::EngineHint::None; 159 maxwell3d.engine_state = Maxwell3D::EngineHint::None;
137 maxwell3d.replace_table.clear(); 160 maxwell3d.replace_table.clear();
138 } 161 }
139 } 162 }
140
141 bool extended;
142}; 163};
143 164
165/*
166 * @note: these macros have two versions, a normal and extended version, with the extended version
167 * also assigning the base vertex/instance.
168 */
169template <bool extended>
144class HLE_DrawIndexedIndirect final : public HLEMacroImpl { 170class HLE_DrawIndexedIndirect final : public HLEMacroImpl {
145public: 171public:
146 explicit HLE_DrawIndexedIndirect(Engines::Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {} 172 explicit HLE_DrawIndexedIndirect(Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {}
147 173
148 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override { 174 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override {
149 auto topology = static_cast<Maxwell::Regs::PrimitiveTopology>(parameters[0]); 175 auto topology = static_cast<Maxwell3D::Regs::PrimitiveTopology>(parameters[0]);
150 if (!maxwell3d.AnyParametersDirty() || !IsTopologySafe(topology)) { 176 if (!maxwell3d.AnyParametersDirty() || !IsTopologySafe(topology)) {
151 Fallback(parameters); 177 Fallback(parameters);
152 return; 178 return;
@@ -159,24 +185,30 @@ public:
159 maxwell3d.regs.global_base_vertex_index = element_base; 185 maxwell3d.regs.global_base_vertex_index = element_base;
160 maxwell3d.regs.global_base_instance_index = base_instance; 186 maxwell3d.regs.global_base_instance_index = base_instance;
161 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; 187 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
162 maxwell3d.engine_state = Maxwell::EngineHint::OnHLEMacro; 188 if constexpr (extended) {
163 maxwell3d.setHLEReplacementName(0, 0x640, Maxwell::HLEReplaceName::BaseVertex); 189 maxwell3d.engine_state = Maxwell3D::EngineHint::OnHLEMacro;
164 maxwell3d.setHLEReplacementName(0, 0x644, Maxwell::HLEReplaceName::BaseInstance); 190 maxwell3d.SetHLEReplacementAttributeType(
191 0, 0x640, Maxwell3D::HLEReplacementAttributeType::BaseVertex);
192 maxwell3d.SetHLEReplacementAttributeType(
193 0, 0x644, Maxwell3D::HLEReplacementAttributeType::BaseInstance);
194 }
165 auto& params = maxwell3d.draw_manager->GetIndirectParams(); 195 auto& params = maxwell3d.draw_manager->GetIndirectParams();
166 params.is_indexed = true; 196 params.is_indexed = true;
167 params.include_count = false; 197 params.include_count = false;
168 params.count_start_address = 0; 198 params.count_start_address = 0;
169 params.indirect_start_address = maxwell3d.getMacroAddress(1); 199 params.indirect_start_address = maxwell3d.GetMacroAddress(1);
170 params.buffer_size = 5 * sizeof(u32); 200 params.buffer_size = 5 * sizeof(u32);
171 params.max_draw_counts = 1; 201 params.max_draw_counts = 1;
172 params.stride = 0; 202 params.stride = 0;
173 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; 203 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
174 maxwell3d.draw_manager->DrawIndexedIndirect(topology, 0, estimate); 204 maxwell3d.draw_manager->DrawIndexedIndirect(topology, 0, estimate);
175 maxwell3d.engine_state = Maxwell::EngineHint::None;
176 maxwell3d.replace_table.clear();
177 maxwell3d.regs.vertex_id_base = 0x0; 205 maxwell3d.regs.vertex_id_base = 0x0;
178 maxwell3d.regs.global_base_vertex_index = 0x0; 206 maxwell3d.regs.global_base_vertex_index = 0x0;
179 maxwell3d.regs.global_base_instance_index = 0x0; 207 maxwell3d.regs.global_base_instance_index = 0x0;
208 if constexpr (extended) {
209 maxwell3d.engine_state = Maxwell3D::EngineHint::None;
210 maxwell3d.replace_table.clear();
211 }
180 } 212 }
181 213
182private: 214private:
@@ -189,31 +221,37 @@ private:
189 maxwell3d.regs.global_base_vertex_index = element_base; 221 maxwell3d.regs.global_base_vertex_index = element_base;
190 maxwell3d.regs.global_base_instance_index = base_instance; 222 maxwell3d.regs.global_base_instance_index = base_instance;
191 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; 223 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
192 maxwell3d.engine_state = Maxwell::EngineHint::OnHLEMacro; 224 if constexpr (extended) {
193 maxwell3d.setHLEReplacementName(0, 0x640, Maxwell::HLEReplaceName::BaseVertex); 225 maxwell3d.engine_state = Maxwell3D::EngineHint::OnHLEMacro;
194 maxwell3d.setHLEReplacementName(0, 0x644, Maxwell::HLEReplaceName::BaseInstance); 226 maxwell3d.SetHLEReplacementAttributeType(
227 0, 0x640, Maxwell3D::HLEReplacementAttributeType::BaseVertex);
228 maxwell3d.SetHLEReplacementAttributeType(
229 0, 0x644, Maxwell3D::HLEReplacementAttributeType::BaseInstance);
230 }
195 231
196 maxwell3d.draw_manager->DrawIndex( 232 maxwell3d.draw_manager->DrawIndex(
197 static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[0]), 233 static_cast<Tegra::Maxwell3D::Regs::PrimitiveTopology>(parameters[0]), parameters[3],
198 parameters[3], parameters[1], element_base, base_instance, instance_count); 234 parameters[1], element_base, base_instance, instance_count);
199 235
200 maxwell3d.regs.vertex_id_base = 0x0; 236 maxwell3d.regs.vertex_id_base = 0x0;
201 maxwell3d.regs.global_base_vertex_index = 0x0; 237 maxwell3d.regs.global_base_vertex_index = 0x0;
202 maxwell3d.regs.global_base_instance_index = 0x0; 238 maxwell3d.regs.global_base_instance_index = 0x0;
203 maxwell3d.engine_state = Maxwell::EngineHint::None; 239 if constexpr (extended) {
204 maxwell3d.replace_table.clear(); 240 maxwell3d.engine_state = Maxwell3D::EngineHint::None;
241 maxwell3d.replace_table.clear();
242 }
205 } 243 }
206}; 244};
207 245
208class HLE_MultiLayerClear final : public HLEMacroImpl { 246class HLE_MultiLayerClear final : public HLEMacroImpl {
209public: 247public:
210 explicit HLE_MultiLayerClear(Engines::Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {} 248 explicit HLE_MultiLayerClear(Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {}
211 249
212 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override { 250 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override {
213 maxwell3d.RefreshParameters(); 251 maxwell3d.RefreshParameters();
214 ASSERT(parameters.size() == 1); 252 ASSERT(parameters.size() == 1);
215 253
216 const Engines::Maxwell3D::Regs::ClearSurface clear_params{parameters[0]}; 254 const Maxwell3D::Regs::ClearSurface clear_params{parameters[0]};
217 const u32 rt_index = clear_params.RT; 255 const u32 rt_index = clear_params.RT;
218 const u32 num_layers = maxwell3d.regs.rt[rt_index].depth; 256 const u32 num_layers = maxwell3d.regs.rt[rt_index].depth;
219 ASSERT(clear_params.layer == 0); 257 ASSERT(clear_params.layer == 0);
@@ -225,11 +263,10 @@ public:
225 263
226class HLE_MultiDrawIndexedIndirectCount final : public HLEMacroImpl { 264class HLE_MultiDrawIndexedIndirectCount final : public HLEMacroImpl {
227public: 265public:
228 explicit HLE_MultiDrawIndexedIndirectCount(Engines::Maxwell3D& maxwell3d_) 266 explicit HLE_MultiDrawIndexedIndirectCount(Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {}
229 : HLEMacroImpl(maxwell3d_) {}
230 267
231 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override { 268 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override {
232 const auto topology = static_cast<Maxwell::Regs::PrimitiveTopology>(parameters[2]); 269 const auto topology = static_cast<Maxwell3D::Regs::PrimitiveTopology>(parameters[2]);
233 if (!IsTopologySafe(topology)) { 270 if (!IsTopologySafe(topology)) {
234 Fallback(parameters); 271 Fallback(parameters);
235 return; 272 return;
@@ -253,17 +290,21 @@ public:
253 auto& params = maxwell3d.draw_manager->GetIndirectParams(); 290 auto& params = maxwell3d.draw_manager->GetIndirectParams();
254 params.is_indexed = true; 291 params.is_indexed = true;
255 params.include_count = true; 292 params.include_count = true;
256 params.count_start_address = maxwell3d.getMacroAddress(4); 293 params.count_start_address = maxwell3d.GetMacroAddress(4);
257 params.indirect_start_address = maxwell3d.getMacroAddress(5); 294 params.indirect_start_address = maxwell3d.GetMacroAddress(5);
258 params.buffer_size = stride * draw_count; 295 params.buffer_size = stride * draw_count;
259 params.max_draw_counts = draw_count; 296 params.max_draw_counts = draw_count;
260 params.stride = stride; 297 params.stride = stride;
261 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; 298 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
262 maxwell3d.engine_state = Maxwell::EngineHint::OnHLEMacro; 299 maxwell3d.engine_state = Maxwell3D::EngineHint::OnHLEMacro;
263 maxwell3d.setHLEReplacementName(0, 0x640, Maxwell::HLEReplaceName::BaseVertex); 300 maxwell3d.SetHLEReplacementAttributeType(
264 maxwell3d.setHLEReplacementName(0, 0x644, Maxwell::HLEReplaceName::BaseInstance); 301 0, 0x640, Maxwell3D::HLEReplacementAttributeType::BaseVertex);
302 maxwell3d.SetHLEReplacementAttributeType(
303 0, 0x644, Maxwell3D::HLEReplacementAttributeType::BaseInstance);
304 maxwell3d.SetHLEReplacementAttributeType(0, 0x648,
305 Maxwell3D::HLEReplacementAttributeType::DrawID);
265 maxwell3d.draw_manager->DrawIndexedIndirect(topology, 0, estimate); 306 maxwell3d.draw_manager->DrawIndexedIndirect(topology, 0, estimate);
266 maxwell3d.engine_state = Maxwell::EngineHint::None; 307 maxwell3d.engine_state = Maxwell3D::EngineHint::None;
267 maxwell3d.replace_table.clear(); 308 maxwell3d.replace_table.clear();
268 } 309 }
269 310
@@ -271,9 +312,8 @@ private:
271 void Fallback(const std::vector<u32>& parameters) { 312 void Fallback(const std::vector<u32>& parameters) {
272 SCOPE_EXIT({ 313 SCOPE_EXIT({
273 // Clean everything. 314 // Clean everything.
274 // Clean everything.
275 maxwell3d.regs.vertex_id_base = 0x0; 315 maxwell3d.regs.vertex_id_base = 0x0;
276 maxwell3d.engine_state = Maxwell::EngineHint::None; 316 maxwell3d.engine_state = Maxwell3D::EngineHint::None;
277 maxwell3d.replace_table.clear(); 317 maxwell3d.replace_table.clear();
278 }); 318 });
279 maxwell3d.RefreshParameters(); 319 maxwell3d.RefreshParameters();
@@ -283,7 +323,7 @@ private:
283 // Nothing to do. 323 // Nothing to do.
284 return; 324 return;
285 } 325 }
286 const auto topology = static_cast<Maxwell::Regs::PrimitiveTopology>(parameters[2]); 326 const auto topology = static_cast<Maxwell3D::Regs::PrimitiveTopology>(parameters[2]);
287 const u32 padding = parameters[3]; 327 const u32 padding = parameters[3];
288 const std::size_t max_draws = parameters[4]; 328 const std::size_t max_draws = parameters[4];
289 329
@@ -297,9 +337,13 @@ private:
297 const u32 base_vertex = parameters[base + 3]; 337 const u32 base_vertex = parameters[base + 3];
298 const u32 base_instance = parameters[base + 4]; 338 const u32 base_instance = parameters[base + 4];
299 maxwell3d.regs.vertex_id_base = base_vertex; 339 maxwell3d.regs.vertex_id_base = base_vertex;
300 maxwell3d.engine_state = Maxwell::EngineHint::OnHLEMacro; 340 maxwell3d.engine_state = Maxwell3D::EngineHint::OnHLEMacro;
301 maxwell3d.setHLEReplacementName(0, 0x640, Maxwell::HLEReplaceName::BaseVertex); 341 maxwell3d.SetHLEReplacementAttributeType(
302 maxwell3d.setHLEReplacementName(0, 0x644, Maxwell::HLEReplaceName::BaseInstance); 342 0, 0x640, Maxwell3D::HLEReplacementAttributeType::BaseVertex);
343 maxwell3d.SetHLEReplacementAttributeType(
344 0, 0x644, Maxwell3D::HLEReplacementAttributeType::BaseInstance);
345 maxwell3d.CallMethod(0x8e3, 0x648, true);
346 maxwell3d.CallMethod(0x8e4, static_cast<u32>(index), true);
303 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; 347 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
304 maxwell3d.draw_manager->DrawIndex(topology, parameters[base + 2], parameters[base], 348 maxwell3d.draw_manager->DrawIndex(topology, parameters[base + 2], parameters[base],
305 base_vertex, base_instance, parameters[base + 1]); 349 base_vertex, base_instance, parameters[base + 1]);
@@ -309,7 +353,7 @@ private:
309 353
310class HLE_C713C83D8F63CCF3 final : public HLEMacroImpl { 354class HLE_C713C83D8F63CCF3 final : public HLEMacroImpl {
311public: 355public:
312 explicit HLE_C713C83D8F63CCF3(Engines::Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {} 356 explicit HLE_C713C83D8F63CCF3(Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {}
313 357
314 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override { 358 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override {
315 maxwell3d.RefreshParameters(); 359 maxwell3d.RefreshParameters();
@@ -325,7 +369,7 @@ public:
325 369
326class HLE_D7333D26E0A93EDE final : public HLEMacroImpl { 370class HLE_D7333D26E0A93EDE final : public HLEMacroImpl {
327public: 371public:
328 explicit HLE_D7333D26E0A93EDE(Engines::Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {} 372 explicit HLE_D7333D26E0A93EDE(Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {}
329 373
330 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override { 374 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override {
331 maxwell3d.RefreshParameters(); 375 maxwell3d.RefreshParameters();
@@ -341,7 +385,7 @@ public:
341 385
342class HLE_BindShader final : public HLEMacroImpl { 386class HLE_BindShader final : public HLEMacroImpl {
343public: 387public:
344 explicit HLE_BindShader(Engines::Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {} 388 explicit HLE_BindShader(Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {}
345 389
346 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override { 390 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override {
347 maxwell3d.RefreshParameters(); 391 maxwell3d.RefreshParameters();
@@ -371,7 +415,7 @@ public:
371 415
372class HLE_SetRasterBoundingBox final : public HLEMacroImpl { 416class HLE_SetRasterBoundingBox final : public HLEMacroImpl {
373public: 417public:
374 explicit HLE_SetRasterBoundingBox(Engines::Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {} 418 explicit HLE_SetRasterBoundingBox(Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {}
375 419
376 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override { 420 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override {
377 maxwell3d.RefreshParameters(); 421 maxwell3d.RefreshParameters();
@@ -384,60 +428,156 @@ public:
384 } 428 }
385}; 429};
386 430
431template <size_t base_size>
432class HLE_ClearConstBuffer final : public HLEMacroImpl {
433public:
434 explicit HLE_ClearConstBuffer(Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {}
435
436 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override {
437 maxwell3d.RefreshParameters();
438 static constexpr std::array<u32, base_size> zeroes{};
439 auto& regs = maxwell3d.regs;
440 regs.const_buffer.size = static_cast<u32>(base_size);
441 regs.const_buffer.address_high = parameters[0];
442 regs.const_buffer.address_low = parameters[1];
443 regs.const_buffer.offset = 0;
444 maxwell3d.ProcessCBMultiData(zeroes.data(), parameters[2] * 4);
445 }
446};
447
448class HLE_ClearMemory final : public HLEMacroImpl {
449public:
450 explicit HLE_ClearMemory(Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {}
451
452 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override {
453 maxwell3d.RefreshParameters();
454
455 const u32 needed_memory = parameters[2] / sizeof(u32);
456 if (needed_memory > zero_memory.size()) {
457 zero_memory.resize(needed_memory, 0);
458 }
459 auto& regs = maxwell3d.regs;
460 regs.upload.line_length_in = parameters[2];
461 regs.upload.line_count = 1;
462 regs.upload.dest.address_high = parameters[0];
463 regs.upload.dest.address_low = parameters[1];
464 maxwell3d.CallMethod(static_cast<size_t>(MAXWELL3D_REG_INDEX(launch_dma)), 0x1011, true);
465 maxwell3d.CallMultiMethod(static_cast<size_t>(MAXWELL3D_REG_INDEX(inline_data)),
466 zero_memory.data(), needed_memory, needed_memory);
467 }
468
469private:
470 std::vector<u32> zero_memory;
471};
472
473class HLE_TransformFeedbackSetup final : public HLEMacroImpl {
474public:
475 explicit HLE_TransformFeedbackSetup(Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {}
476
477 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override {
478 maxwell3d.RefreshParameters();
479
480 auto& regs = maxwell3d.regs;
481 regs.transform_feedback_enabled = 1;
482 regs.transform_feedback.buffers[0].start_offset = 0;
483 regs.transform_feedback.buffers[1].start_offset = 0;
484 regs.transform_feedback.buffers[2].start_offset = 0;
485 regs.transform_feedback.buffers[3].start_offset = 0;
486
487 regs.upload.line_length_in = 4;
488 regs.upload.line_count = 1;
489 regs.upload.dest.address_high = parameters[0];
490 regs.upload.dest.address_low = parameters[1];
491 maxwell3d.CallMethod(static_cast<size_t>(MAXWELL3D_REG_INDEX(launch_dma)), 0x1011, true);
492 maxwell3d.CallMethod(static_cast<size_t>(MAXWELL3D_REG_INDEX(inline_data)),
493 regs.transform_feedback.controls[0].stride, true);
494 }
495};
496
387} // Anonymous namespace 497} // Anonymous namespace
388 498
389HLEMacro::HLEMacro(Engines::Maxwell3D& maxwell3d_) : maxwell3d{maxwell3d_} { 499HLEMacro::HLEMacro(Maxwell3D& maxwell3d_) : maxwell3d{maxwell3d_} {
390 builders.emplace(0x771BB18C62444DA0ULL, 500 builders.emplace(0xDD6A7FA92A7D2674ULL,
391 std::function<std::unique_ptr<CachedMacro>(Engines::Maxwell3D&)>( 501 std::function<std::unique_ptr<CachedMacro>(Maxwell3D&)>(
392 [](Engines::Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> { 502 [](Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> {
393 return std::make_unique<HLE_771BB18C62444DA0>(maxwell3d__); 503 return std::make_unique<HLE_DrawArrays>(maxwell3d__);
394 })); 504 }));
395 builders.emplace(0x0D61FC9FAAC9FCADULL, 505 builders.emplace(0x0D61FC9FAAC9FCADULL,
396 std::function<std::unique_ptr<CachedMacro>(Engines::Maxwell3D&)>( 506 std::function<std::unique_ptr<CachedMacro>(Maxwell3D&)>(
397 [](Engines::Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> { 507 [](Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> {
398 return std::make_unique<HLE_DrawArraysIndirect>(maxwell3d__); 508 return std::make_unique<HLE_DrawArraysIndirect<false>>(maxwell3d__);
399 })); 509 }));
400 builders.emplace(0x8A4D173EB99A8603ULL, 510 builders.emplace(0x8A4D173EB99A8603ULL,
401 std::function<std::unique_ptr<CachedMacro>(Engines::Maxwell3D&)>( 511 std::function<std::unique_ptr<CachedMacro>(Maxwell3D&)>(
402 [](Engines::Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> { 512 [](Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> {
403 return std::make_unique<HLE_DrawArraysIndirect>(maxwell3d__, true); 513 return std::make_unique<HLE_DrawArraysIndirect<true>>(maxwell3d__);
514 }));
515 builders.emplace(0x2DB33AADB741839CULL,
516 std::function<std::unique_ptr<CachedMacro>(Maxwell3D&)>(
517 [](Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> {
518 return std::make_unique<HLE_DrawIndexed>(maxwell3d__);
519 }));
520 builders.emplace(0x771BB18C62444DA0ULL,
521 std::function<std::unique_ptr<CachedMacro>(Maxwell3D&)>(
522 [](Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> {
523 return std::make_unique<HLE_DrawIndexedIndirect<false>>(maxwell3d__);
404 })); 524 }));
405 builders.emplace(0x0217920100488FF7ULL, 525 builders.emplace(0x0217920100488FF7ULL,
406 std::function<std::unique_ptr<CachedMacro>(Engines::Maxwell3D&)>( 526 std::function<std::unique_ptr<CachedMacro>(Maxwell3D&)>(
407 [](Engines::Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> { 527 [](Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> {
408 return std::make_unique<HLE_DrawIndexedIndirect>(maxwell3d__); 528 return std::make_unique<HLE_DrawIndexedIndirect<true>>(maxwell3d__);
409 })); 529 }));
410 builders.emplace(0x3F5E74B9C9A50164ULL, 530 builders.emplace(0x3F5E74B9C9A50164ULL,
411 std::function<std::unique_ptr<CachedMacro>(Engines::Maxwell3D&)>( 531 std::function<std::unique_ptr<CachedMacro>(Maxwell3D&)>(
412 [](Engines::Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> { 532 [](Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> {
413 return std::make_unique<HLE_MultiDrawIndexedIndirectCount>( 533 return std::make_unique<HLE_MultiDrawIndexedIndirectCount>(
414 maxwell3d__); 534 maxwell3d__);
415 })); 535 }));
416 builders.emplace(0xEAD26C3E2109B06BULL, 536 builders.emplace(0xEAD26C3E2109B06BULL,
417 std::function<std::unique_ptr<CachedMacro>(Engines::Maxwell3D&)>( 537 std::function<std::unique_ptr<CachedMacro>(Maxwell3D&)>(
418 [](Engines::Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> { 538 [](Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> {
419 return std::make_unique<HLE_MultiLayerClear>(maxwell3d__); 539 return std::make_unique<HLE_MultiLayerClear>(maxwell3d__);
420 })); 540 }));
421 builders.emplace(0xC713C83D8F63CCF3ULL, 541 builders.emplace(0xC713C83D8F63CCF3ULL,
422 std::function<std::unique_ptr<CachedMacro>(Engines::Maxwell3D&)>( 542 std::function<std::unique_ptr<CachedMacro>(Maxwell3D&)>(
423 [](Engines::Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> { 543 [](Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> {
424 return std::make_unique<HLE_C713C83D8F63CCF3>(maxwell3d__); 544 return std::make_unique<HLE_C713C83D8F63CCF3>(maxwell3d__);
425 })); 545 }));
426 builders.emplace(0xD7333D26E0A93EDEULL, 546 builders.emplace(0xD7333D26E0A93EDEULL,
427 std::function<std::unique_ptr<CachedMacro>(Engines::Maxwell3D&)>( 547 std::function<std::unique_ptr<CachedMacro>(Maxwell3D&)>(
428 [](Engines::Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> { 548 [](Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> {
429 return std::make_unique<HLE_D7333D26E0A93EDE>(maxwell3d__); 549 return std::make_unique<HLE_D7333D26E0A93EDE>(maxwell3d__);
430 })); 550 }));
431 builders.emplace(0xEB29B2A09AA06D38ULL, 551 builders.emplace(0xEB29B2A09AA06D38ULL,
432 std::function<std::unique_ptr<CachedMacro>(Engines::Maxwell3D&)>( 552 std::function<std::unique_ptr<CachedMacro>(Maxwell3D&)>(
433 [](Engines::Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> { 553 [](Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> {
434 return std::make_unique<HLE_BindShader>(maxwell3d__); 554 return std::make_unique<HLE_BindShader>(maxwell3d__);
435 })); 555 }));
436 builders.emplace(0xDB1341DBEB4C8AF7ULL, 556 builders.emplace(0xDB1341DBEB4C8AF7ULL,
437 std::function<std::unique_ptr<CachedMacro>(Engines::Maxwell3D&)>( 557 std::function<std::unique_ptr<CachedMacro>(Maxwell3D&)>(
438 [](Engines::Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> { 558 [](Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> {
439 return std::make_unique<HLE_SetRasterBoundingBox>(maxwell3d__); 559 return std::make_unique<HLE_SetRasterBoundingBox>(maxwell3d__);
440 })); 560 }));
561 builders.emplace(0x6C97861D891EDf7EULL,
562 std::function<std::unique_ptr<CachedMacro>(Maxwell3D&)>(
563 [](Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> {
564 return std::make_unique<HLE_ClearConstBuffer<0x5F00>>(maxwell3d__);
565 }));
566 builders.emplace(0xD246FDDF3A6173D7ULL,
567 std::function<std::unique_ptr<CachedMacro>(Maxwell3D&)>(
568 [](Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> {
569 return std::make_unique<HLE_ClearConstBuffer<0x7000>>(maxwell3d__);
570 }));
571 builders.emplace(0xEE4D0004BEC8ECF4ULL,
572 std::function<std::unique_ptr<CachedMacro>(Maxwell3D&)>(
573 [](Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> {
574 return std::make_unique<HLE_ClearMemory>(maxwell3d__);
575 }));
576 builders.emplace(0xFC0CF27F5FFAA661ULL,
577 std::function<std::unique_ptr<CachedMacro>(Maxwell3D&)>(
578 [](Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> {
579 return std::make_unique<HLE_TransformFeedbackSetup>(maxwell3d__);
580 }));
441} 581}
442 582
443HLEMacro::~HLEMacro() = default; 583HLEMacro::~HLEMacro() = default;