From 7ac8657432f2dad14c985ef3df3972cd126fc9d8 Mon Sep 17 00:00:00 2001 From: Subv Date: Sun, 18 Mar 2018 03:13:22 -0500 Subject: GPU: Macros are specific to the Maxwell3D engine, so handle them internally. --- src/video_core/command_processor.cpp | 29 ----------------------------- 1 file changed, 29 deletions(-) (limited to 'src/video_core/command_processor.cpp') diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index 26ba8c40b..1d578582e 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp @@ -64,35 +64,6 @@ void GPU::WriteReg(u32 method, u32 subchannel, u32 value) { } } -void GPU::CallMethod(u32 method, u32 subchannel, const std::vector& parameters) { - LOG_WARNING(HW_GPU, "Processing method %08X on subchannel %u num params %zu", method, - subchannel, parameters.size()); - - if (method < static_cast(BufferMethods::CountBufferMethods)) { - // TODO(Subv): Research and implement these methods. - LOG_ERROR(HW_GPU, "Special buffer methods other than Bind are not implemented"); - return; - } - - ASSERT(bound_engines.find(subchannel) != bound_engines.end()); - - const EngineID engine = bound_engines[subchannel]; - - switch (engine) { - case EngineID::FERMI_TWOD_A: - fermi_2d->CallMethod(method, parameters); - break; - case EngineID::MAXWELL_B: - maxwell_3d->CallMethod(method, parameters); - break; - case EngineID::MAXWELL_COMPUTE_B: - maxwell_compute->CallMethod(method, parameters); - break; - default: - UNIMPLEMENTED(); - } -} - void GPU::ProcessCommandList(GPUVAddr address, u32 size) { // TODO(Subv): PhysicalToVirtualAddress is a misnomer, it converts a GPU VAddr into an // application VAddr. -- cgit v1.2.3 From aa586fa26854cfe32b97aa99c2874945420bcfc4 Mon Sep 17 00:00:00 2001 From: Subv Date: Sun, 18 Mar 2018 04:17:10 -0500 Subject: GPU: Store uploaded GPU macros and keep track of the number of method parameters. --- src/video_core/command_processor.cpp | 56 ++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 15 deletions(-) (limited to 'src/video_core/command_processor.cpp') diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index 1d578582e..d4cdb4ab2 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp @@ -24,12 +24,37 @@ namespace Tegra { enum class BufferMethods { BindObject = 0, + SetGraphMacroCode = 0x45, + SetGraphMacroCodeArg = 0x46, + SetGraphMacroEntry = 0x47, CountBufferMethods = 0x100, }; -void GPU::WriteReg(u32 method, u32 subchannel, u32 value) { - LOG_WARNING(HW_GPU, "Processing method %08X on subchannel %u value %08X", method, subchannel, - value); +void GPU::WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params) { + LOG_WARNING(HW_GPU, "Processing method %08X on subchannel %u value %08X remaining params %u", + method, subchannel, value, remaining_params); + + if (method == static_cast(BufferMethods::SetGraphMacroEntry)) { + // Prepare to upload a new macro, reset the upload counter. + LOG_DEBUG(HW_GPU, "Uploading GPU macro %08X", value); + current_macro_entry = value; + current_macro_code.clear(); + return; + } + + if (method == static_cast(BufferMethods::SetGraphMacroCodeArg)) { + // Append a new code word to the current macro. + current_macro_code.push_back(value); + + // There are no more params remaining, submit the code to the 3D engine. + if (remaining_params == 0) { + maxwell_3d->SubmitMacroCode(current_macro_entry, std::move(current_macro_code)); + current_macro_entry = InvalidGraphMacroEntry; + current_macro_code.clear(); + } + + return; + } if (method == static_cast(BufferMethods::BindObject)) { // Bind the current subchannel to the desired engine id. @@ -54,7 +79,7 @@ void GPU::WriteReg(u32 method, u32 subchannel, u32 value) { fermi_2d->WriteReg(method, value); break; case EngineID::MAXWELL_B: - maxwell_3d->WriteReg(method, value); + maxwell_3d->WriteReg(method, value, remaining_params); break; case EngineID::MAXWELL_COMPUTE_B: maxwell_compute->WriteReg(method, value); @@ -78,7 +103,8 @@ void GPU::ProcessCommandList(GPUVAddr address, u32 size) { case SubmissionMode::Increasing: { // Increase the method value with each argument. for (unsigned i = 0; i < header.arg_count; ++i) { - WriteReg(header.method + i, header.subchannel, Memory::Read32(current_addr)); + WriteReg(header.method + i, header.subchannel, Memory::Read32(current_addr), + header.arg_count - i - 1); current_addr += sizeof(u32); } break; @@ -87,31 +113,31 @@ void GPU::ProcessCommandList(GPUVAddr address, u32 size) { case SubmissionMode::NonIncreasing: { // Use the same method value for all arguments. for (unsigned i = 0; i < header.arg_count; ++i) { - WriteReg(header.method, header.subchannel, Memory::Read32(current_addr)); + WriteReg(header.method, header.subchannel, Memory::Read32(current_addr), + header.arg_count - i - 1); current_addr += sizeof(u32); } break; } case SubmissionMode::IncreaseOnce: { ASSERT(header.arg_count.Value() >= 1); + // Use the original method for the first argument and then the next method for all other // arguments. + WriteReg(header.method, header.subchannel, Memory::Read32(current_addr), + header.arg_count - 1); + current_addr += sizeof(u32); - // Process this command as a method call instead of a register write. Gather - // all the parameters first and then pass them at once to the CallMethod function. - std::vector parameters(header.arg_count); - - for (unsigned i = 0; i < header.arg_count; ++i) { - parameters[i] = Memory::Read32(current_addr); + for (unsigned i = 1; i < header.arg_count; ++i) { + WriteReg(header.method + 1, header.subchannel, Memory::Read32(current_addr), + header.arg_count - i - 1); current_addr += sizeof(u32); } - - CallMethod(header.method, header.subchannel, parameters); break; } case SubmissionMode::Inline: { // The register value is stored in the bits 16-28 as an immediate - WriteReg(header.method, header.subchannel, header.inline_data); + WriteReg(header.method, header.subchannel, header.inline_data, 0); break; } default: -- cgit v1.2.3