diff options
| author | 2022-11-27 00:58:06 +0100 | |
|---|---|---|
| committer | 2023-01-01 16:43:57 -0500 | |
| commit | cb1497d0d7711a1c0e527aaa3e1dc3f95e5a6644 (patch) | |
| tree | 46e00278c6265ed501488e7c6f02fc4c12a6af6c | |
| parent | Revert Buffer cache changes and setup additional macros. (diff) | |
| download | yuzu-cb1497d0d7711a1c0e527aaa3e1dc3f95e5a6644.tar.gz yuzu-cb1497d0d7711a1c0e527aaa3e1dc3f95e5a6644.tar.xz yuzu-cb1497d0d7711a1c0e527aaa3e1dc3f95e5a6644.zip | |
DMAPusher: Improve collection of non executing methods
| -rw-r--r-- | src/video_core/dma_pusher.cpp | 6 | ||||
| -rw-r--r-- | src/video_core/engines/engine_interface.h | 21 | ||||
| -rw-r--r-- | src/video_core/engines/fermi_2d.cpp | 10 | ||||
| -rw-r--r-- | src/video_core/engines/fermi_2d.h | 2 | ||||
| -rw-r--r-- | src/video_core/engines/kepler_compute.cpp | 14 | ||||
| -rw-r--r-- | src/video_core/engines/kepler_compute.h | 2 | ||||
| -rw-r--r-- | src/video_core/engines/kepler_memory.cpp | 11 | ||||
| -rw-r--r-- | src/video_core/engines/kepler_memory.h | 2 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_3d.cpp | 94 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_3d.h | 4 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_dma.cpp | 12 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_dma.h | 2 | ||||
| -rw-r--r-- | src/video_core/macro/macro_hle.cpp | 3 |
13 files changed, 181 insertions, 2 deletions
diff --git a/src/video_core/dma_pusher.cpp b/src/video_core/dma_pusher.cpp index b3e9cb82e..551929824 100644 --- a/src/video_core/dma_pusher.cpp +++ b/src/video_core/dma_pusher.cpp | |||
| @@ -178,6 +178,11 @@ void DmaPusher::CallMethod(u32 argument) const { | |||
| 178 | }); | 178 | }); |
| 179 | } else { | 179 | } else { |
| 180 | auto subchannel = subchannels[dma_state.subchannel]; | 180 | auto subchannel = subchannels[dma_state.subchannel]; |
| 181 | if (!subchannel->execution_mask[dma_state.method]) [[likely]] { | ||
| 182 | subchannel->method_sink.emplace_back(dma_state.method, argument); | ||
| 183 | return; | ||
| 184 | } | ||
| 185 | subchannel->ConsumeSink(); | ||
| 181 | subchannel->current_dma_segment = dma_state.dma_get + dma_state.dma_word_offset; | 186 | subchannel->current_dma_segment = dma_state.dma_get + dma_state.dma_word_offset; |
| 182 | subchannel->CallMethod(dma_state.method, argument, dma_state.is_last_call); | 187 | subchannel->CallMethod(dma_state.method, argument, dma_state.is_last_call); |
| 183 | } | 188 | } |
| @@ -189,6 +194,7 @@ void DmaPusher::CallMultiMethod(const u32* base_start, u32 num_methods) const { | |||
| 189 | dma_state.method_count); | 194 | dma_state.method_count); |
| 190 | } else { | 195 | } else { |
| 191 | auto subchannel = subchannels[dma_state.subchannel]; | 196 | auto subchannel = subchannels[dma_state.subchannel]; |
| 197 | subchannel->ConsumeSink(); | ||
| 192 | subchannel->current_dma_segment = dma_state.dma_get + dma_state.dma_word_offset; | 198 | subchannel->current_dma_segment = dma_state.dma_get + dma_state.dma_word_offset; |
| 193 | subchannel->CallMultiMethod(dma_state.method, base_start, num_methods, | 199 | subchannel->CallMultiMethod(dma_state.method, base_start, num_methods, |
| 194 | dma_state.method_count); | 200 | dma_state.method_count); |
diff --git a/src/video_core/engines/engine_interface.h b/src/video_core/engines/engine_interface.h index 38f1abdc4..392322358 100644 --- a/src/video_core/engines/engine_interface.h +++ b/src/video_core/engines/engine_interface.h | |||
| @@ -3,6 +3,10 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include <bitset> | ||
| 7 | #include <limits> | ||
| 8 | #include <vector> | ||
| 9 | |||
| 6 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 7 | 11 | ||
| 8 | namespace Tegra::Engines { | 12 | namespace Tegra::Engines { |
| @@ -18,8 +22,25 @@ public: | |||
| 18 | virtual void CallMultiMethod(u32 method, const u32* base_start, u32 amount, | 22 | virtual void CallMultiMethod(u32 method, const u32* base_start, u32 amount, |
| 19 | u32 methods_pending) = 0; | 23 | u32 methods_pending) = 0; |
| 20 | 24 | ||
| 25 | void ConsumeSink() { | ||
| 26 | if (method_sink.empty()) { | ||
| 27 | return; | ||
| 28 | } | ||
| 29 | ConsumeSinkImpl(); | ||
| 30 | } | ||
| 31 | |||
| 32 | std::bitset<std::numeric_limits<u16>::max()> execution_mask{}; | ||
| 33 | std::vector<std::pair<u32, u32>> method_sink{}; | ||
| 21 | bool current_dirty{}; | 34 | bool current_dirty{}; |
| 22 | GPUVAddr current_dma_segment; | 35 | GPUVAddr current_dma_segment; |
| 36 | |||
| 37 | protected: | ||
| 38 | virtual void ConsumeSinkImpl() { | ||
| 39 | for (auto [method, value] : method_sink) { | ||
| 40 | CallMethod(method, value, true); | ||
| 41 | } | ||
| 42 | method_sink.clear(); | ||
| 43 | } | ||
| 23 | }; | 44 | }; |
| 24 | 45 | ||
| 25 | } // namespace Tegra::Engines | 46 | } // namespace Tegra::Engines |
diff --git a/src/video_core/engines/fermi_2d.cpp b/src/video_core/engines/fermi_2d.cpp index c6478ae85..e655e7254 100644 --- a/src/video_core/engines/fermi_2d.cpp +++ b/src/video_core/engines/fermi_2d.cpp | |||
| @@ -25,6 +25,9 @@ Fermi2D::Fermi2D(MemoryManager& memory_manager_) { | |||
| 25 | // Nvidia's OpenGL driver seems to assume these values | 25 | // Nvidia's OpenGL driver seems to assume these values |
| 26 | regs.src.depth = 1; | 26 | regs.src.depth = 1; |
| 27 | regs.dst.depth = 1; | 27 | regs.dst.depth = 1; |
| 28 | |||
| 29 | execution_mask.reset(); | ||
| 30 | execution_mask[FERMI2D_REG_INDEX(pixels_from_memory.src_y0) + 1] = true; | ||
| 28 | } | 31 | } |
| 29 | 32 | ||
| 30 | Fermi2D::~Fermi2D() = default; | 33 | Fermi2D::~Fermi2D() = default; |
| @@ -49,6 +52,13 @@ void Fermi2D::CallMultiMethod(u32 method, const u32* base_start, u32 amount, u32 | |||
| 49 | } | 52 | } |
| 50 | } | 53 | } |
| 51 | 54 | ||
| 55 | void Fermi2D::ConsumeSinkImpl() { | ||
| 56 | for (auto [method, value] : method_sink) { | ||
| 57 | regs.reg_array[method] = value; | ||
| 58 | } | ||
| 59 | method_sink.clear(); | ||
| 60 | } | ||
| 61 | |||
| 52 | void Fermi2D::Blit() { | 62 | void Fermi2D::Blit() { |
| 53 | MICROPROFILE_SCOPE(GPU_BlitEngine); | 63 | MICROPROFILE_SCOPE(GPU_BlitEngine); |
| 54 | LOG_DEBUG(HW_GPU, "called. source address=0x{:x}, destination address=0x{:x}", | 64 | LOG_DEBUG(HW_GPU, "called. source address=0x{:x}, destination address=0x{:x}", |
diff --git a/src/video_core/engines/fermi_2d.h b/src/video_core/engines/fermi_2d.h index 100b21bac..523fbdec2 100644 --- a/src/video_core/engines/fermi_2d.h +++ b/src/video_core/engines/fermi_2d.h | |||
| @@ -309,6 +309,8 @@ private: | |||
| 309 | /// Performs the copy from the source surface to the destination surface as configured in the | 309 | /// Performs the copy from the source surface to the destination surface as configured in the |
| 310 | /// registers. | 310 | /// registers. |
| 311 | void Blit(); | 311 | void Blit(); |
| 312 | |||
| 313 | void ConsumeSinkImpl() override; | ||
| 312 | }; | 314 | }; |
| 313 | 315 | ||
| 314 | #define ASSERT_REG_POSITION(field_name, position) \ | 316 | #define ASSERT_REG_POSITION(field_name, position) \ |
diff --git a/src/video_core/engines/kepler_compute.cpp b/src/video_core/engines/kepler_compute.cpp index e5c622155..601095f03 100644 --- a/src/video_core/engines/kepler_compute.cpp +++ b/src/video_core/engines/kepler_compute.cpp | |||
| @@ -14,7 +14,12 @@ | |||
| 14 | namespace Tegra::Engines { | 14 | namespace Tegra::Engines { |
| 15 | 15 | ||
| 16 | KeplerCompute::KeplerCompute(Core::System& system_, MemoryManager& memory_manager_) | 16 | KeplerCompute::KeplerCompute(Core::System& system_, MemoryManager& memory_manager_) |
| 17 | : system{system_}, memory_manager{memory_manager_}, upload_state{memory_manager, regs.upload} {} | 17 | : system{system_}, memory_manager{memory_manager_}, upload_state{memory_manager, regs.upload} { |
| 18 | execution_mask.reset(); | ||
| 19 | execution_mask[KEPLER_COMPUTE_REG_INDEX(exec_upload)] = true; | ||
| 20 | execution_mask[KEPLER_COMPUTE_REG_INDEX(data_upload)] = true; | ||
| 21 | execution_mask[KEPLER_COMPUTE_REG_INDEX(launch)] = true; | ||
| 22 | } | ||
| 18 | 23 | ||
| 19 | KeplerCompute::~KeplerCompute() = default; | 24 | KeplerCompute::~KeplerCompute() = default; |
| 20 | 25 | ||
| @@ -23,6 +28,13 @@ void KeplerCompute::BindRasterizer(VideoCore::RasterizerInterface* rasterizer_) | |||
| 23 | upload_state.BindRasterizer(rasterizer); | 28 | upload_state.BindRasterizer(rasterizer); |
| 24 | } | 29 | } |
| 25 | 30 | ||
| 31 | void KeplerCompute::ConsumeSinkImpl() { | ||
| 32 | for (auto [method, value] : method_sink) { | ||
| 33 | regs.reg_array[method] = value; | ||
| 34 | } | ||
| 35 | method_sink.clear(); | ||
| 36 | } | ||
| 37 | |||
| 26 | void KeplerCompute::CallMethod(u32 method, u32 method_argument, bool is_last_call) { | 38 | void KeplerCompute::CallMethod(u32 method, u32 method_argument, bool is_last_call) { |
| 27 | ASSERT_MSG(method < Regs::NUM_REGS, | 39 | ASSERT_MSG(method < Regs::NUM_REGS, |
| 28 | "Invalid KeplerCompute register, increase the size of the Regs structure"); | 40 | "Invalid KeplerCompute register, increase the size of the Regs structure"); |
diff --git a/src/video_core/engines/kepler_compute.h b/src/video_core/engines/kepler_compute.h index e154e3f06..2092e685f 100644 --- a/src/video_core/engines/kepler_compute.h +++ b/src/video_core/engines/kepler_compute.h | |||
| @@ -204,6 +204,8 @@ public: | |||
| 204 | private: | 204 | private: |
| 205 | void ProcessLaunch(); | 205 | void ProcessLaunch(); |
| 206 | 206 | ||
| 207 | void ConsumeSinkImpl() override; | ||
| 208 | |||
| 207 | /// Retrieves information about a specific TIC entry from the TIC buffer. | 209 | /// Retrieves information about a specific TIC entry from the TIC buffer. |
| 208 | Texture::TICEntry GetTICEntry(u32 tic_index) const; | 210 | Texture::TICEntry GetTICEntry(u32 tic_index) const; |
| 209 | 211 | ||
diff --git a/src/video_core/engines/kepler_memory.cpp b/src/video_core/engines/kepler_memory.cpp index 08045d1cf..c026801a3 100644 --- a/src/video_core/engines/kepler_memory.cpp +++ b/src/video_core/engines/kepler_memory.cpp | |||
| @@ -18,6 +18,17 @@ KeplerMemory::~KeplerMemory() = default; | |||
| 18 | 18 | ||
| 19 | void KeplerMemory::BindRasterizer(VideoCore::RasterizerInterface* rasterizer_) { | 19 | void KeplerMemory::BindRasterizer(VideoCore::RasterizerInterface* rasterizer_) { |
| 20 | upload_state.BindRasterizer(rasterizer_); | 20 | upload_state.BindRasterizer(rasterizer_); |
| 21 | |||
| 22 | execution_mask.reset(); | ||
| 23 | execution_mask[KEPLERMEMORY_REG_INDEX(exec)] = true; | ||
| 24 | execution_mask[KEPLERMEMORY_REG_INDEX(data)] = true; | ||
| 25 | } | ||
| 26 | |||
| 27 | void KeplerMemory::ConsumeSinkImpl() { | ||
| 28 | for (auto [method, value] : method_sink) { | ||
| 29 | regs.reg_array[method] = value; | ||
| 30 | } | ||
| 31 | method_sink.clear(); | ||
| 21 | } | 32 | } |
| 22 | 33 | ||
| 23 | void KeplerMemory::CallMethod(u32 method, u32 method_argument, bool is_last_call) { | 34 | void KeplerMemory::CallMethod(u32 method, u32 method_argument, bool is_last_call) { |
diff --git a/src/video_core/engines/kepler_memory.h b/src/video_core/engines/kepler_memory.h index 5fe7489f0..fb1eecbba 100644 --- a/src/video_core/engines/kepler_memory.h +++ b/src/video_core/engines/kepler_memory.h | |||
| @@ -73,6 +73,8 @@ public: | |||
| 73 | } regs{}; | 73 | } regs{}; |
| 74 | 74 | ||
| 75 | private: | 75 | private: |
| 76 | void ConsumeSinkImpl() override; | ||
| 77 | |||
| 76 | Core::System& system; | 78 | Core::System& system; |
| 77 | Upload::State upload_state; | 79 | Upload::State upload_state; |
| 78 | }; | 80 | }; |
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index bbe3202fe..d44a5cabf 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | #include <cstring> | 4 | #include <cstring> |
| 5 | #include <optional> | 5 | #include <optional> |
| 6 | #include "common/assert.h" | 6 | #include "common/assert.h" |
| 7 | #include "common/scope_exit.h" | ||
| 7 | #include "common/settings.h" | 8 | #include "common/settings.h" |
| 8 | #include "core/core.h" | 9 | #include "core/core.h" |
| 9 | #include "core/core_timing.h" | 10 | #include "core/core_timing.h" |
| @@ -30,6 +31,10 @@ Maxwell3D::Maxwell3D(Core::System& system_, MemoryManager& memory_manager_) | |||
| 30 | regs.upload} { | 31 | regs.upload} { |
| 31 | dirty.flags.flip(); | 32 | dirty.flags.flip(); |
| 32 | InitializeRegisterDefaults(); | 33 | InitializeRegisterDefaults(); |
| 34 | execution_mask.reset(); | ||
| 35 | for (size_t i = 0; i < execution_mask.size(); i++) { | ||
| 36 | execution_mask[i] = IsMethodExecutable(static_cast<u32>(i)); | ||
| 37 | } | ||
| 33 | } | 38 | } |
| 34 | 39 | ||
| 35 | Maxwell3D::~Maxwell3D() = default; | 40 | Maxwell3D::~Maxwell3D() = default; |
| @@ -123,6 +128,71 @@ void Maxwell3D::InitializeRegisterDefaults() { | |||
| 123 | shadow_state = regs; | 128 | shadow_state = regs; |
| 124 | } | 129 | } |
| 125 | 130 | ||
| 131 | bool Maxwell3D::IsMethodExecutable(u32 method) { | ||
| 132 | if (method >= MacroRegistersStart) { | ||
| 133 | return true; | ||
| 134 | } | ||
| 135 | switch (method) { | ||
| 136 | case MAXWELL3D_REG_INDEX(draw.end): | ||
| 137 | case MAXWELL3D_REG_INDEX(draw.begin): | ||
| 138 | case MAXWELL3D_REG_INDEX(vertex_buffer.first): | ||
| 139 | case MAXWELL3D_REG_INDEX(vertex_buffer.count): | ||
| 140 | case MAXWELL3D_REG_INDEX(index_buffer.first): | ||
| 141 | case MAXWELL3D_REG_INDEX(index_buffer.count): | ||
| 142 | case MAXWELL3D_REG_INDEX(draw_inline_index): | ||
| 143 | case MAXWELL3D_REG_INDEX(index_buffer32_subsequent): | ||
| 144 | case MAXWELL3D_REG_INDEX(index_buffer16_subsequent): | ||
| 145 | case MAXWELL3D_REG_INDEX(index_buffer8_subsequent): | ||
| 146 | case MAXWELL3D_REG_INDEX(index_buffer32_first): | ||
| 147 | case MAXWELL3D_REG_INDEX(index_buffer16_first): | ||
| 148 | case MAXWELL3D_REG_INDEX(index_buffer8_first): | ||
| 149 | case MAXWELL3D_REG_INDEX(inline_index_2x16.even): | ||
| 150 | case MAXWELL3D_REG_INDEX(inline_index_4x8.index0): | ||
| 151 | case MAXWELL3D_REG_INDEX(vertex_array_instance_first): | ||
| 152 | case MAXWELL3D_REG_INDEX(vertex_array_instance_subsequent): | ||
| 153 | case MAXWELL3D_REG_INDEX(wait_for_idle): | ||
| 154 | case MAXWELL3D_REG_INDEX(shadow_ram_control): | ||
| 155 | case MAXWELL3D_REG_INDEX(load_mme.instruction_ptr): | ||
| 156 | case MAXWELL3D_REG_INDEX(load_mme.instruction): | ||
| 157 | case MAXWELL3D_REG_INDEX(load_mme.start_address): | ||
| 158 | case MAXWELL3D_REG_INDEX(falcon[4]): | ||
| 159 | case MAXWELL3D_REG_INDEX(const_buffer.buffer): | ||
| 160 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 1: | ||
| 161 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 2: | ||
| 162 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 3: | ||
| 163 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 4: | ||
| 164 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 5: | ||
| 165 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 6: | ||
| 166 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 7: | ||
| 167 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 8: | ||
| 168 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 9: | ||
| 169 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 10: | ||
| 170 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 11: | ||
| 171 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 12: | ||
| 172 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 13: | ||
| 173 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 14: | ||
| 174 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 15: | ||
| 175 | case MAXWELL3D_REG_INDEX(bind_groups[0].raw_config): | ||
| 176 | case MAXWELL3D_REG_INDEX(bind_groups[1].raw_config): | ||
| 177 | case MAXWELL3D_REG_INDEX(bind_groups[2].raw_config): | ||
| 178 | case MAXWELL3D_REG_INDEX(bind_groups[3].raw_config): | ||
| 179 | case MAXWELL3D_REG_INDEX(bind_groups[4].raw_config): | ||
| 180 | case MAXWELL3D_REG_INDEX(topology_override): | ||
| 181 | case MAXWELL3D_REG_INDEX(clear_surface): | ||
| 182 | case MAXWELL3D_REG_INDEX(report_semaphore.query): | ||
| 183 | case MAXWELL3D_REG_INDEX(render_enable.mode): | ||
| 184 | case MAXWELL3D_REG_INDEX(clear_report_value): | ||
| 185 | case MAXWELL3D_REG_INDEX(sync_info): | ||
| 186 | case MAXWELL3D_REG_INDEX(launch_dma): | ||
| 187 | case MAXWELL3D_REG_INDEX(inline_data): | ||
| 188 | case MAXWELL3D_REG_INDEX(fragment_barrier): | ||
| 189 | case MAXWELL3D_REG_INDEX(tiled_cache_barrier): | ||
| 190 | return true; | ||
| 191 | default: | ||
| 192 | return false; | ||
| 193 | } | ||
| 194 | } | ||
| 195 | |||
| 126 | void Maxwell3D::ProcessMacro(u32 method, const u32* base_start, u32 amount, bool is_last_call) { | 196 | void Maxwell3D::ProcessMacro(u32 method, const u32* base_start, u32 amount, bool is_last_call) { |
| 127 | if (executing_macro == 0) { | 197 | if (executing_macro == 0) { |
| 128 | // A macro call must begin by writing the macro method's register, not its argument. | 198 | // A macro call must begin by writing the macro method's register, not its argument. |
| @@ -141,6 +211,7 @@ void Maxwell3D::ProcessMacro(u32 method, const u32* base_start, u32 amount, bool | |||
| 141 | 211 | ||
| 142 | // Call the macro when there are no more parameters in the command buffer | 212 | // Call the macro when there are no more parameters in the command buffer |
| 143 | if (is_last_call) { | 213 | if (is_last_call) { |
| 214 | ConsumeSink(); | ||
| 144 | CallMacroMethod(executing_macro, macro_params); | 215 | CallMacroMethod(executing_macro, macro_params); |
| 145 | macro_params.clear(); | 216 | macro_params.clear(); |
| 146 | macro_addresses.clear(); | 217 | macro_addresses.clear(); |
| @@ -214,6 +285,29 @@ u32 Maxwell3D::ProcessShadowRam(u32 method, u32 argument) { | |||
| 214 | return argument; | 285 | return argument; |
| 215 | } | 286 | } |
| 216 | 287 | ||
| 288 | void Maxwell3D::ConsumeSinkImpl() { | ||
| 289 | SCOPE_EXIT({ method_sink.clear(); }); | ||
| 290 | const auto control = shadow_state.shadow_ram_control; | ||
| 291 | if (control == Regs::ShadowRamControl::Track || | ||
| 292 | control == Regs::ShadowRamControl::TrackWithFilter) { | ||
| 293 | |||
| 294 | for (auto [method, value] : method_sink) { | ||
| 295 | shadow_state.reg_array[method] = value; | ||
| 296 | ProcessDirtyRegisters(method, value); | ||
| 297 | } | ||
| 298 | return; | ||
| 299 | } | ||
| 300 | if (control == Regs::ShadowRamControl::Replay) { | ||
| 301 | for (auto [method, value] : method_sink) { | ||
| 302 | ProcessDirtyRegisters(method, shadow_state.reg_array[method]); | ||
| 303 | } | ||
| 304 | return; | ||
| 305 | } | ||
| 306 | for (auto [method, value] : method_sink) { | ||
| 307 | ProcessDirtyRegisters(method, value); | ||
| 308 | } | ||
| 309 | } | ||
| 310 | |||
| 217 | void Maxwell3D::ProcessDirtyRegisters(u32 method, u32 argument) { | 311 | void Maxwell3D::ProcessDirtyRegisters(u32 method, u32 argument) { |
| 218 | if (regs.reg_array[method] == argument) { | 312 | if (regs.reg_array[method] == argument) { |
| 219 | return; | 313 | return; |
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index f0a379801..478ba4dc7 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h | |||
| @@ -3123,6 +3123,8 @@ private: | |||
| 3123 | 3123 | ||
| 3124 | void ProcessDirtyRegisters(u32 method, u32 argument); | 3124 | void ProcessDirtyRegisters(u32 method, u32 argument); |
| 3125 | 3125 | ||
| 3126 | void ConsumeSinkImpl() override; | ||
| 3127 | |||
| 3126 | void ProcessMethodCall(u32 method, u32 argument, u32 nonshadow_argument, bool is_last_call); | 3128 | void ProcessMethodCall(u32 method, u32 argument, u32 nonshadow_argument, bool is_last_call); |
| 3127 | 3129 | ||
| 3128 | /// Retrieves information about a specific TIC entry from the TIC buffer. | 3130 | /// Retrieves information about a specific TIC entry from the TIC buffer. |
| @@ -3172,6 +3174,8 @@ private: | |||
| 3172 | 3174 | ||
| 3173 | void RefreshParametersImpl(); | 3175 | void RefreshParametersImpl(); |
| 3174 | 3176 | ||
| 3177 | bool IsMethodExecutable(u32 method); | ||
| 3178 | |||
| 3175 | Core::System& system; | 3179 | Core::System& system; |
| 3176 | MemoryManager& memory_manager; | 3180 | MemoryManager& memory_manager; |
| 3177 | 3181 | ||
diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp index f73d7bf0f..01f70ea9e 100644 --- a/src/video_core/engines/maxwell_dma.cpp +++ b/src/video_core/engines/maxwell_dma.cpp | |||
| @@ -21,7 +21,10 @@ namespace Tegra::Engines { | |||
| 21 | using namespace Texture; | 21 | using namespace Texture; |
| 22 | 22 | ||
| 23 | MaxwellDMA::MaxwellDMA(Core::System& system_, MemoryManager& memory_manager_) | 23 | MaxwellDMA::MaxwellDMA(Core::System& system_, MemoryManager& memory_manager_) |
| 24 | : system{system_}, memory_manager{memory_manager_} {} | 24 | : system{system_}, memory_manager{memory_manager_} { |
| 25 | execution_mask.reset(); | ||
| 26 | execution_mask[offsetof(Regs, launch_dma) / sizeof(u32)] = true; | ||
| 27 | } | ||
| 25 | 28 | ||
| 26 | MaxwellDMA::~MaxwellDMA() = default; | 29 | MaxwellDMA::~MaxwellDMA() = default; |
| 27 | 30 | ||
| @@ -29,6 +32,13 @@ void MaxwellDMA::BindRasterizer(VideoCore::RasterizerInterface* rasterizer_) { | |||
| 29 | rasterizer = rasterizer_; | 32 | rasterizer = rasterizer_; |
| 30 | } | 33 | } |
| 31 | 34 | ||
| 35 | void MaxwellDMA::ConsumeSinkImpl() { | ||
| 36 | for (auto [method, value] : method_sink) { | ||
| 37 | regs.reg_array[method] = value; | ||
| 38 | } | ||
| 39 | method_sink.clear(); | ||
| 40 | } | ||
| 41 | |||
| 32 | void MaxwellDMA::CallMethod(u32 method, u32 method_argument, bool is_last_call) { | 42 | void MaxwellDMA::CallMethod(u32 method, u32 method_argument, bool is_last_call) { |
| 33 | ASSERT_MSG(method < NUM_REGS, "Invalid MaxwellDMA register"); | 43 | ASSERT_MSG(method < NUM_REGS, "Invalid MaxwellDMA register"); |
| 34 | 44 | ||
diff --git a/src/video_core/engines/maxwell_dma.h b/src/video_core/engines/maxwell_dma.h index c88191a61..0e594fa74 100644 --- a/src/video_core/engines/maxwell_dma.h +++ b/src/video_core/engines/maxwell_dma.h | |||
| @@ -231,6 +231,8 @@ private: | |||
| 231 | 231 | ||
| 232 | void ReleaseSemaphore(); | 232 | void ReleaseSemaphore(); |
| 233 | 233 | ||
| 234 | void ConsumeSinkImpl() override; | ||
| 235 | |||
| 234 | Core::System& system; | 236 | Core::System& system; |
| 235 | 237 | ||
| 236 | MemoryManager& memory_manager; | 238 | MemoryManager& memory_manager; |
diff --git a/src/video_core/macro/macro_hle.cpp b/src/video_core/macro/macro_hle.cpp index 3eac50975..294a338d2 100644 --- a/src/video_core/macro/macro_hle.cpp +++ b/src/video_core/macro/macro_hle.cpp | |||
| @@ -126,6 +126,7 @@ private: | |||
| 126 | 126 | ||
| 127 | const u32 vertex_first = parameters[3]; | 127 | const u32 vertex_first = parameters[3]; |
| 128 | const u32 vertex_count = parameters[1]; | 128 | const u32 vertex_count = parameters[1]; |
| 129 | |||
| 129 | 130 | ||
| 130 | if (maxwell3d.AnyParametersDirty() && | 131 | if (maxwell3d.AnyParametersDirty() && |
| 131 | maxwell3d.GetMaxCurrentVertices() < vertex_first + vertex_count) { | 132 | maxwell3d.GetMaxCurrentVertices() < vertex_first + vertex_count) { |
| @@ -135,6 +136,7 @@ private: | |||
| 135 | 136 | ||
| 136 | const u32 base_instance = parameters[4]; | 137 | const u32 base_instance = parameters[4]; |
| 137 | if (extended) { | 138 | if (extended) { |
| 139 | maxwell3d.regs.global_base_instance_index = base_instance; | ||
| 138 | maxwell3d.engine_state = Maxwell::EngineHint::OnHLEMacro; | 140 | maxwell3d.engine_state = Maxwell::EngineHint::OnHLEMacro; |
| 139 | maxwell3d.setHLEReplacementName(0, 0x640, Maxwell::HLEReplaceName::BaseInstance); | 141 | maxwell3d.setHLEReplacementName(0, 0x640, Maxwell::HLEReplaceName::BaseInstance); |
| 140 | } | 142 | } |
| @@ -144,6 +146,7 @@ private: | |||
| 144 | vertex_first, vertex_count, base_instance, instance_count); | 146 | vertex_first, vertex_count, base_instance, instance_count); |
| 145 | 147 | ||
| 146 | if (extended) { | 148 | if (extended) { |
| 149 | maxwell3d.regs.global_base_instance_index = 0; | ||
| 147 | maxwell3d.engine_state = Maxwell::EngineHint::None; | 150 | maxwell3d.engine_state = Maxwell::EngineHint::None; |
| 148 | maxwell3d.replace_table.clear(); | 151 | maxwell3d.replace_table.clear(); |
| 149 | } | 152 | } |