diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/macro/macro_hle.cpp | 63 |
1 files changed, 62 insertions, 1 deletions
diff --git a/src/video_core/macro/macro_hle.cpp b/src/video_core/macro/macro_hle.cpp index 58382755b..cabe8dcbf 100644 --- a/src/video_core/macro/macro_hle.cpp +++ b/src/video_core/macro/macro_hle.cpp | |||
| @@ -3,6 +3,8 @@ | |||
| 3 | 3 | ||
| 4 | #include <array> | 4 | #include <array> |
| 5 | #include <vector> | 5 | #include <vector> |
| 6 | #include "common/scope_exit.h" | ||
| 7 | #include "video_core/dirty_flags.h" | ||
| 6 | #include "video_core/engines/maxwell_3d.h" | 8 | #include "video_core/engines/maxwell_3d.h" |
| 7 | #include "video_core/macro/macro.h" | 9 | #include "video_core/macro/macro.h" |
| 8 | #include "video_core/macro/macro_hle.h" | 10 | #include "video_core/macro/macro_hle.h" |
| @@ -58,6 +60,7 @@ void HLE_0217920100488FF7(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& | |||
| 58 | maxwell3d.regs.index_array.first = parameters[3]; | 60 | maxwell3d.regs.index_array.first = parameters[3]; |
| 59 | maxwell3d.regs.reg_array[0x446] = element_base; // vertex id base? | 61 | maxwell3d.regs.reg_array[0x446] = element_base; // vertex id base? |
| 60 | maxwell3d.regs.index_array.count = parameters[1]; | 62 | maxwell3d.regs.index_array.count = parameters[1]; |
| 63 | maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; | ||
| 61 | maxwell3d.regs.vb_element_base = element_base; | 64 | maxwell3d.regs.vb_element_base = element_base; |
| 62 | maxwell3d.regs.vb_base_instance = base_instance; | 65 | maxwell3d.regs.vb_base_instance = base_instance; |
| 63 | maxwell3d.mme_draw.instance_count = instance_count; | 66 | maxwell3d.mme_draw.instance_count = instance_count; |
| @@ -80,10 +83,67 @@ void HLE_0217920100488FF7(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& | |||
| 80 | maxwell3d.mme_draw.current_mode = Engines::Maxwell3D::MMEDrawMode::Undefined; | 83 | maxwell3d.mme_draw.current_mode = Engines::Maxwell3D::MMEDrawMode::Undefined; |
| 81 | } | 84 | } |
| 82 | 85 | ||
| 83 | constexpr std::array<std::pair<u64, HLEFunction>, 3> hle_funcs{{ | 86 | // Multidraw Indirect |
| 87 | void HLE_3F5E74B9C9A50164(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& parameters) { | ||
| 88 | SCOPE_EXIT({ | ||
| 89 | // Clean everything. | ||
| 90 | maxwell3d.regs.reg_array[0x446] = 0x0; // vertex id base? | ||
| 91 | maxwell3d.regs.index_array.count = 0; | ||
| 92 | maxwell3d.regs.vb_element_base = 0x0; | ||
| 93 | maxwell3d.regs.vb_base_instance = 0x0; | ||
| 94 | maxwell3d.mme_draw.instance_count = 0; | ||
| 95 | maxwell3d.CallMethodFromMME(0x8e3, 0x640); | ||
| 96 | maxwell3d.CallMethodFromMME(0x8e4, 0x0); | ||
| 97 | maxwell3d.CallMethodFromMME(0x8e5, 0x0); | ||
| 98 | maxwell3d.mme_draw.current_mode = Engines::Maxwell3D::MMEDrawMode::Undefined; | ||
| 99 | maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; | ||
| 100 | }); | ||
| 101 | const u32 start_indirect = parameters[0]; | ||
| 102 | const u32 end_indirect = parameters[1]; | ||
| 103 | if (start_indirect >= end_indirect) { | ||
| 104 | // Nothing to do. | ||
| 105 | return; | ||
| 106 | } | ||
| 107 | const auto topology = | ||
| 108 | static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[2]); | ||
| 109 | maxwell3d.regs.draw.topology.Assign(topology); | ||
| 110 | const u32 padding = parameters[3]; | ||
| 111 | const std::size_t max_draws = parameters[4]; | ||
| 112 | |||
| 113 | const u32 indirect_words = 5 + padding; | ||
| 114 | const std::size_t first_draw = start_indirect; | ||
| 115 | const std::size_t effective_draws = end_indirect - start_indirect; | ||
| 116 | const std::size_t last_draw = start_indirect + std::min(effective_draws, max_draws); | ||
| 117 | |||
| 118 | for (std::size_t index = first_draw; index < last_draw; index++) { | ||
| 119 | const std::size_t base = index * indirect_words + 5; | ||
| 120 | const u32 num_vertices = parameters[base]; | ||
| 121 | const u32 instance_count = parameters[base + 1]; | ||
| 122 | const u32 first_index = parameters[base + 2]; | ||
| 123 | const u32 base_vertex = parameters[base + 3]; | ||
| 124 | const u32 base_instance = parameters[base + 4]; | ||
| 125 | maxwell3d.regs.index_array.first = first_index; | ||
| 126 | maxwell3d.regs.reg_array[0x446] = base_vertex; | ||
| 127 | maxwell3d.regs.index_array.count = num_vertices; | ||
| 128 | maxwell3d.regs.vb_element_base = base_vertex; | ||
| 129 | maxwell3d.regs.vb_base_instance = base_instance; | ||
| 130 | maxwell3d.mme_draw.instance_count = instance_count; | ||
| 131 | maxwell3d.CallMethodFromMME(0x8e3, 0x640); | ||
| 132 | maxwell3d.CallMethodFromMME(0x8e4, base_vertex); | ||
| 133 | maxwell3d.CallMethodFromMME(0x8e5, base_instance); | ||
| 134 | maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; | ||
| 135 | if (maxwell3d.ShouldExecute()) { | ||
| 136 | maxwell3d.Rasterizer().Draw(true, true); | ||
| 137 | } | ||
| 138 | maxwell3d.mme_draw.current_mode = Engines::Maxwell3D::MMEDrawMode::Undefined; | ||
| 139 | } | ||
| 140 | } | ||
| 141 | |||
| 142 | constexpr std::array<std::pair<u64, HLEFunction>, 4> hle_funcs{{ | ||
| 84 | {0x771BB18C62444DA0, &HLE_771BB18C62444DA0}, | 143 | {0x771BB18C62444DA0, &HLE_771BB18C62444DA0}, |
| 85 | {0x0D61FC9FAAC9FCAD, &HLE_0D61FC9FAAC9FCAD}, | 144 | {0x0D61FC9FAAC9FCAD, &HLE_0D61FC9FAAC9FCAD}, |
| 86 | {0x0217920100488FF7, &HLE_0217920100488FF7}, | 145 | {0x0217920100488FF7, &HLE_0217920100488FF7}, |
| 146 | {0x3F5E74B9C9A50164, &HLE_3F5E74B9C9A50164}, | ||
| 87 | }}; | 147 | }}; |
| 88 | 148 | ||
| 89 | class HLEMacroImpl final : public CachedMacro { | 149 | class HLEMacroImpl final : public CachedMacro { |
| @@ -99,6 +159,7 @@ private: | |||
| 99 | Engines::Maxwell3D& maxwell3d; | 159 | Engines::Maxwell3D& maxwell3d; |
| 100 | HLEFunction func; | 160 | HLEFunction func; |
| 101 | }; | 161 | }; |
| 162 | |||
| 102 | } // Anonymous namespace | 163 | } // Anonymous namespace |
| 103 | 164 | ||
| 104 | HLEMacro::HLEMacro(Engines::Maxwell3D& maxwell3d_) : maxwell3d{maxwell3d_} {} | 165 | HLEMacro::HLEMacro(Engines::Maxwell3D& maxwell3d_) : maxwell3d{maxwell3d_} {} |