diff options
| author | 2023-01-03 10:01:25 -0500 | |
|---|---|---|
| committer | 2023-01-04 14:39:42 -0500 | |
| commit | a0c697124ced080f58866825e2e323e8682bbd7f (patch) | |
| tree | 73830fc46134be10d7feffc3da11aa9f0ea58ffb /src/video_core/macro | |
| parent | Texture Cache: Implement async texture downloads. (diff) | |
| download | yuzu-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.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/macro/macro_hle.cpp | 356 |
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 | ||
| 26 | MICROPROFILE_DEFINE(MacroHLE, "GPU", "Execute macro hle", MP_RGB(128, 192, 192)); | 26 | MICROPROFILE_DEFINE(MacroHLE, "GPU", "Execute macro HLE", MP_RGB(128, 192, 192)); |
| 27 | 27 | ||
| 28 | namespace Tegra { | 28 | namespace 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 | ||
| 16 | namespace Tegra { | 16 | namespace Tegra { |
| 17 | 17 | ||
| 18 | using Maxwell = Engines::Maxwell3D; | 18 | using Maxwell3D = Engines::Maxwell3D; |
| 19 | 19 | ||
| 20 | namespace { | 20 | namespace { |
| 21 | 21 | ||
| 22 | bool IsTopologySafe(Maxwell::Regs::PrimitiveTopology topology) { | 22 | bool 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 | ||
| 45 | class HLEMacroImpl : public CachedMacro { | 45 | class HLEMacroImpl : public CachedMacro { |
| 46 | public: | 46 | public: |
| 47 | explicit HLEMacroImpl(Engines::Maxwell3D& maxwell3d_) : maxwell3d{maxwell3d_} {} | 47 | explicit HLEMacroImpl(Maxwell3D& maxwell3d_) : maxwell3d{maxwell3d_} {} |
| 48 | 48 | ||
| 49 | protected: | 49 | protected: |
| 50 | Engines::Maxwell3D& maxwell3d; | 50 | Maxwell3D& maxwell3d; |
| 51 | }; | 51 | }; |
| 52 | 52 | ||
| 53 | class HLE_771BB18C62444DA0 final : public HLEMacroImpl { | 53 | class HLE_DrawArrays final : public HLEMacroImpl { |
| 54 | public: | 54 | public: |
| 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 | |||
| 66 | class HLE_DrawIndexed final : public HLEMacroImpl { | ||
| 67 | public: | ||
| 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 | */ | ||
| 89 | template <bool extended> | ||
| 68 | class HLE_DrawArraysIndirect final : public HLEMacroImpl { | 90 | class HLE_DrawArraysIndirect final : public HLEMacroImpl { |
| 69 | public: | 91 | public: |
| 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 | */ | ||
| 169 | template <bool extended> | ||
| 144 | class HLE_DrawIndexedIndirect final : public HLEMacroImpl { | 170 | class HLE_DrawIndexedIndirect final : public HLEMacroImpl { |
| 145 | public: | 171 | public: |
| 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 | ||
| 182 | private: | 214 | private: |
| @@ -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 | ||
| 208 | class HLE_MultiLayerClear final : public HLEMacroImpl { | 246 | class HLE_MultiLayerClear final : public HLEMacroImpl { |
| 209 | public: | 247 | public: |
| 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 | ||
| 226 | class HLE_MultiDrawIndexedIndirectCount final : public HLEMacroImpl { | 264 | class HLE_MultiDrawIndexedIndirectCount final : public HLEMacroImpl { |
| 227 | public: | 265 | public: |
| 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 | ||
| 310 | class HLE_C713C83D8F63CCF3 final : public HLEMacroImpl { | 354 | class HLE_C713C83D8F63CCF3 final : public HLEMacroImpl { |
| 311 | public: | 355 | public: |
| 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 | ||
| 326 | class HLE_D7333D26E0A93EDE final : public HLEMacroImpl { | 370 | class HLE_D7333D26E0A93EDE final : public HLEMacroImpl { |
| 327 | public: | 371 | public: |
| 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 | ||
| 342 | class HLE_BindShader final : public HLEMacroImpl { | 386 | class HLE_BindShader final : public HLEMacroImpl { |
| 343 | public: | 387 | public: |
| 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 | ||
| 372 | class HLE_SetRasterBoundingBox final : public HLEMacroImpl { | 416 | class HLE_SetRasterBoundingBox final : public HLEMacroImpl { |
| 373 | public: | 417 | public: |
| 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 | ||
| 431 | template <size_t base_size> | ||
| 432 | class HLE_ClearConstBuffer final : public HLEMacroImpl { | ||
| 433 | public: | ||
| 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 | |||
| 448 | class HLE_ClearMemory final : public HLEMacroImpl { | ||
| 449 | public: | ||
| 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 | |||
| 469 | private: | ||
| 470 | std::vector<u32> zero_memory; | ||
| 471 | }; | ||
| 472 | |||
| 473 | class HLE_TransformFeedbackSetup final : public HLEMacroImpl { | ||
| 474 | public: | ||
| 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 | ||
| 389 | HLEMacro::HLEMacro(Engines::Maxwell3D& maxwell3d_) : maxwell3d{maxwell3d_} { | 499 | HLEMacro::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 | ||
| 443 | HLEMacro::~HLEMacro() = default; | 583 | HLEMacro::~HLEMacro() = default; |