From 701dedcfad3001c1aecb2d714da1e22cc407a5ea Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sun, 25 Aug 2019 01:08:35 -0300 Subject: [PATCH] maxwell_3d: Avoid moving macro_params --- src/video_core/engines/maxwell_3d.cpp | 7 ++++--- src/video_core/engines/maxwell_3d.h | 3 ++- src/video_core/macro_interpreter.cpp | 18 +++++++++++++----- src/video_core/macro_interpreter.h | 8 +++++--- 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index f5158d219..c8c92757a 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -244,7 +244,7 @@ void Maxwell3D::InitDirtySettings() { dirty_pointers[MAXWELL3D_REG_INDEX(polygon_offset_clamp)] = polygon_offset_dirty_reg; } -void Maxwell3D::CallMacroMethod(u32 method, std::vector parameters) { +void Maxwell3D::CallMacroMethod(u32 method, std::size_t num_parameters, const u32* parameters) { // Reset the current macro. executing_macro = 0; @@ -252,7 +252,7 @@ void Maxwell3D::CallMacroMethod(u32 method, std::vector parameters) { const u32 entry = ((method - MacroRegistersStart) >> 1) % macro_positions.size(); // Execute the current macro. - macro_interpreter.Execute(macro_positions[entry], std::move(parameters)); + macro_interpreter.Execute(macro_positions[entry], num_parameters, parameters); } void Maxwell3D::CallMethod(const GPU::MethodCall& method_call) { @@ -289,7 +289,8 @@ void Maxwell3D::CallMethod(const GPU::MethodCall& method_call) { // Call the macro when there are no more parameters in the command buffer if (method_call.IsLastCall()) { - CallMacroMethod(executing_macro, std::move(macro_params)); + CallMacroMethod(executing_macro, macro_params.size(), macro_params.data()); + macro_params.clear(); } return; } diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 0184342a0..9e7b50327 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -1307,9 +1307,10 @@ private: /** * Call a macro on this engine. * @param method Method to call + * @param num_parameters Number of arguments * @param parameters Arguments to the method call */ - void CallMacroMethod(u32 method, std::vector parameters); + void CallMacroMethod(u32 method, std::size_t num_parameters, const u32* parameters); /// Handles writes to the macro uploading register. void ProcessMacroUpload(u32 data); diff --git a/src/video_core/macro_interpreter.cpp b/src/video_core/macro_interpreter.cpp index 9f59a2dc1..4e1cb98db 100644 --- a/src/video_core/macro_interpreter.cpp +++ b/src/video_core/macro_interpreter.cpp @@ -14,11 +14,18 @@ namespace Tegra { MacroInterpreter::MacroInterpreter(Engines::Maxwell3D& maxwell3d) : maxwell3d(maxwell3d) {} -void MacroInterpreter::Execute(u32 offset, std::vector parameters) { +void MacroInterpreter::Execute(u32 offset, std::size_t num_parameters, const u32* parameters) { MICROPROFILE_SCOPE(MacroInterp); Reset(); + registers[1] = parameters[0]; - this->parameters = std::move(parameters); + + if (num_parameters > parameters_capacity) { + parameters_capacity = num_parameters; + this->parameters = std::make_unique(num_parameters); + } + std::memcpy(this->parameters.get(), parameters, num_parameters * sizeof(u32)); + this->num_parameters = num_parameters; // Execute the code until we hit an exit condition. bool keep_executing = true; @@ -27,7 +34,7 @@ void MacroInterpreter::Execute(u32 offset, std::vector parameters) { } // Assert the the macro used all the input parameters - ASSERT(next_parameter_index == this->parameters.size()); + ASSERT(next_parameter_index == num_parameters); } void MacroInterpreter::Reset() { @@ -35,7 +42,7 @@ void MacroInterpreter::Reset() { pc = 0; delayed_pc = {}; method_address.raw = 0; - parameters.clear(); + num_parameters = 0; // The next parameter index starts at 1, because $r1 already has the value of the first // parameter. next_parameter_index = 1; @@ -229,7 +236,8 @@ void MacroInterpreter::ProcessResult(ResultOperation operation, u32 reg, u32 res } u32 MacroInterpreter::FetchParameter() { - return parameters.at(next_parameter_index++); + ASSERT(next_parameter_index < num_parameters); + return parameters[next_parameter_index++]; } u32 MacroInterpreter::GetRegister(u32 register_id) const { diff --git a/src/video_core/macro_interpreter.h b/src/video_core/macro_interpreter.h index cde360288..76b6a895b 100644 --- a/src/video_core/macro_interpreter.h +++ b/src/video_core/macro_interpreter.h @@ -25,7 +25,7 @@ public: * @param offset Offset to start execution at. * @param parameters The parameters of the macro. */ - void Execute(u32 offset, std::vector parameters); + void Execute(u32 offset, std::size_t num_parameters, const u32* parameters); private: enum class Operation : u32 { @@ -162,10 +162,12 @@ private: MethodAddress method_address = {}; /// Input parameters of the current macro. - std::vector parameters; + std::unique_ptr parameters; + std::size_t num_parameters = 0; + std::size_t parameters_capacity = 0; /// Index of the next parameter that will be fetched by the 'parm' instruction. u32 next_parameter_index = 0; - bool carry_flag{}; + bool carry_flag = false; }; } // namespace Tegra