diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/command_processor.cpp | 25 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_3d.cpp | 14 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_3d.h | 17 | ||||
| -rw-r--r-- | src/video_core/gpu.h | 7 |
4 files changed, 23 insertions, 40 deletions
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index 26792a2bf..2eaece298 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp | |||
| @@ -24,9 +24,6 @@ namespace Tegra { | |||
| 24 | 24 | ||
| 25 | enum class BufferMethods { | 25 | enum class BufferMethods { |
| 26 | BindObject = 0, | 26 | BindObject = 0, |
| 27 | SetGraphMacroCode = 0x45, | ||
| 28 | SetGraphMacroCodeArg = 0x46, | ||
| 29 | SetGraphMacroEntry = 0x47, | ||
| 30 | CountBufferMethods = 0x40, | 27 | CountBufferMethods = 0x40, |
| 31 | }; | 28 | }; |
| 32 | 29 | ||
| @@ -36,28 +33,6 @@ void GPU::WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params) | |||
| 36 | "{:08X} remaining params {}", | 33 | "{:08X} remaining params {}", |
| 37 | method, subchannel, value, remaining_params); | 34 | method, subchannel, value, remaining_params); |
| 38 | 35 | ||
| 39 | if (method == static_cast<u32>(BufferMethods::SetGraphMacroEntry)) { | ||
| 40 | // Prepare to upload a new macro, reset the upload counter. | ||
| 41 | NGLOG_DEBUG(HW_GPU, "Uploading GPU macro {:08X}", value); | ||
| 42 | current_macro_entry = value; | ||
| 43 | current_macro_code.clear(); | ||
| 44 | return; | ||
| 45 | } | ||
| 46 | |||
| 47 | if (method == static_cast<u32>(BufferMethods::SetGraphMacroCodeArg)) { | ||
| 48 | // Append a new code word to the current macro. | ||
| 49 | current_macro_code.push_back(value); | ||
| 50 | |||
| 51 | // There are no more params remaining, submit the code to the 3D engine. | ||
| 52 | if (remaining_params == 0) { | ||
| 53 | maxwell_3d->SubmitMacroCode(current_macro_entry, std::move(current_macro_code)); | ||
| 54 | current_macro_entry = InvalidGraphMacroEntry; | ||
| 55 | current_macro_code.clear(); | ||
| 56 | } | ||
| 57 | |||
| 58 | return; | ||
| 59 | } | ||
| 60 | |||
| 61 | if (method == static_cast<u32>(BufferMethods::BindObject)) { | 36 | if (method == static_cast<u32>(BufferMethods::BindObject)) { |
| 62 | // Bind the current subchannel to the desired engine id. | 37 | // Bind the current subchannel to the desired engine id. |
| 63 | NGLOG_DEBUG(HW_GPU, "Binding subchannel {} to engine {}", subchannel, value); | 38 | NGLOG_DEBUG(HW_GPU, "Binding subchannel {} to engine {}", subchannel, value); |
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 2acbb9cd6..bc40f8d98 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp | |||
| @@ -22,10 +22,6 @@ constexpr u32 MacroRegistersStart = 0xE00; | |||
| 22 | Maxwell3D::Maxwell3D(MemoryManager& memory_manager) | 22 | Maxwell3D::Maxwell3D(MemoryManager& memory_manager) |
| 23 | : memory_manager(memory_manager), macro_interpreter(*this) {} | 23 | : memory_manager(memory_manager), macro_interpreter(*this) {} |
| 24 | 24 | ||
| 25 | void Maxwell3D::SubmitMacroCode(u32 entry, std::vector<u32> code) { | ||
| 26 | uploaded_macros[entry * 2 + MacroRegistersStart] = std::move(code); | ||
| 27 | } | ||
| 28 | |||
| 29 | void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) { | 25 | void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) { |
| 30 | auto macro_code = uploaded_macros.find(method); | 26 | auto macro_code = uploaded_macros.find(method); |
| 31 | // The requested macro must have been uploaded already. | 27 | // The requested macro must have been uploaded already. |
| @@ -75,6 +71,10 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) { | |||
| 75 | regs.reg_array[method] = value; | 71 | regs.reg_array[method] = value; |
| 76 | 72 | ||
| 77 | switch (method) { | 73 | switch (method) { |
| 74 | case MAXWELL3D_REG_INDEX(macros.data): { | ||
| 75 | ProcessMacroUpload(value); | ||
| 76 | break; | ||
| 77 | } | ||
| 78 | case MAXWELL3D_REG_INDEX(code_address.code_address_high): | 78 | case MAXWELL3D_REG_INDEX(code_address.code_address_high): |
| 79 | case MAXWELL3D_REG_INDEX(code_address.code_address_low): { | 79 | case MAXWELL3D_REG_INDEX(code_address.code_address_low): { |
| 80 | // Note: For some reason games (like Puyo Puyo Tetris) seem to write 0 to the CODE_ADDRESS | 80 | // Note: For some reason games (like Puyo Puyo Tetris) seem to write 0 to the CODE_ADDRESS |
| @@ -141,6 +141,12 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) { | |||
| 141 | } | 141 | } |
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | void Maxwell3D::ProcessMacroUpload(u32 data) { | ||
| 145 | // Store the uploaded macro code to interpret them when they're called. | ||
| 146 | auto& macro = uploaded_macros[regs.macros.entry * 2 + MacroRegistersStart]; | ||
| 147 | macro.push_back(data); | ||
| 148 | } | ||
| 149 | |||
| 144 | void Maxwell3D::ProcessQueryGet() { | 150 | void Maxwell3D::ProcessQueryGet() { |
| 145 | GPUVAddr sequence_address = regs.query.QueryAddress(); | 151 | GPUVAddr sequence_address = regs.query.QueryAddress(); |
| 146 | // Since the sequence address is given as a GPU VAddr, we have to convert it to an application | 152 | // Since the sequence address is given as a GPU VAddr, we have to convert it to an application |
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index a022665eb..8edc3cd38 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h | |||
| @@ -322,7 +322,15 @@ public: | |||
| 322 | 322 | ||
| 323 | union { | 323 | union { |
| 324 | struct { | 324 | struct { |
| 325 | INSERT_PADDING_WORDS(0x200); | 325 | INSERT_PADDING_WORDS(0x45); |
| 326 | |||
| 327 | struct { | ||
| 328 | INSERT_PADDING_WORDS(1); | ||
| 329 | u32 data; | ||
| 330 | u32 entry; | ||
| 331 | } macros; | ||
| 332 | |||
| 333 | INSERT_PADDING_WORDS(0x1B8); | ||
| 326 | 334 | ||
| 327 | struct { | 335 | struct { |
| 328 | u32 address_high; | 336 | u32 address_high; |
| @@ -637,9 +645,6 @@ public: | |||
| 637 | /// Write the value to the register identified by method. | 645 | /// Write the value to the register identified by method. |
| 638 | void WriteReg(u32 method, u32 value, u32 remaining_params); | 646 | void WriteReg(u32 method, u32 value, u32 remaining_params); |
| 639 | 647 | ||
| 640 | /// Uploads the code for a GPU macro program associated with the specified entry. | ||
| 641 | void SubmitMacroCode(u32 entry, std::vector<u32> code); | ||
| 642 | |||
| 643 | /// Returns a list of enabled textures for the specified shader stage. | 648 | /// Returns a list of enabled textures for the specified shader stage. |
| 644 | std::vector<Texture::FullTextureInfo> GetStageTextures(Regs::ShaderStage stage) const; | 649 | std::vector<Texture::FullTextureInfo> GetStageTextures(Regs::ShaderStage stage) const; |
| 645 | 650 | ||
| @@ -670,6 +675,9 @@ private: | |||
| 670 | */ | 675 | */ |
| 671 | void CallMacroMethod(u32 method, std::vector<u32> parameters); | 676 | void CallMacroMethod(u32 method, std::vector<u32> parameters); |
| 672 | 677 | ||
| 678 | /// Handles writes to the macro uploading registers. | ||
| 679 | void ProcessMacroUpload(u32 data); | ||
| 680 | |||
| 673 | /// Handles a write to the QUERY_GET register. | 681 | /// Handles a write to the QUERY_GET register. |
| 674 | void ProcessQueryGet(); | 682 | void ProcessQueryGet(); |
| 675 | 683 | ||
| @@ -687,6 +695,7 @@ private: | |||
| 687 | static_assert(offsetof(Maxwell3D::Regs, field_name) == position * 4, \ | 695 | static_assert(offsetof(Maxwell3D::Regs, field_name) == position * 4, \ |
| 688 | "Field " #field_name " has invalid position") | 696 | "Field " #field_name " has invalid position") |
| 689 | 697 | ||
| 698 | ASSERT_REG_POSITION(macros, 0x45); | ||
| 690 | ASSERT_REG_POSITION(rt, 0x200); | 699 | ASSERT_REG_POSITION(rt, 0x200); |
| 691 | ASSERT_REG_POSITION(viewport_transform[0], 0x280); | 700 | ASSERT_REG_POSITION(viewport_transform[0], 0x280); |
| 692 | ASSERT_REG_POSITION(viewport, 0x300); | 701 | ASSERT_REG_POSITION(viewport, 0x300); |
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index 2888daedc..7afa6aaef 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h | |||
| @@ -86,8 +86,6 @@ public: | |||
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | private: | 88 | private: |
| 89 | static constexpr u32 InvalidGraphMacroEntry = 0xFFFFFFFF; | ||
| 90 | |||
| 91 | /// Writes a single register in the engine bound to the specified subchannel | 89 | /// Writes a single register in the engine bound to the specified subchannel |
| 92 | void WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params); | 90 | void WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params); |
| 93 | 91 | ||
| @@ -100,11 +98,6 @@ private: | |||
| 100 | std::unique_ptr<Engines::Fermi2D> fermi_2d; | 98 | std::unique_ptr<Engines::Fermi2D> fermi_2d; |
| 101 | /// Compute engine | 99 | /// Compute engine |
| 102 | std::unique_ptr<Engines::MaxwellCompute> maxwell_compute; | 100 | std::unique_ptr<Engines::MaxwellCompute> maxwell_compute; |
| 103 | |||
| 104 | /// Entry of the macro that is currently being uploaded | ||
| 105 | u32 current_macro_entry = InvalidGraphMacroEntry; | ||
| 106 | /// Code being uploaded for the current macro | ||
| 107 | std::vector<u32> current_macro_code; | ||
| 108 | }; | 101 | }; |
| 109 | 102 | ||
| 110 | } // namespace Tegra | 103 | } // namespace Tegra |