GSP: Removed dumb GX prefixes to functions/structs in GSP namespace.
- Various other cleanups.
This commit is contained in:
		| @@ -25,16 +25,16 @@ QVariant GPUCommandStreamItemModel::data(const QModelIndex& index, int role) con | ||||
|         return QVariant(); | ||||
|  | ||||
|     int command_index = index.row(); | ||||
|     const GSP_GPU::GXCommand& command = GetDebugger()->ReadGXCommandHistory(command_index); | ||||
|     const GSP_GPU::Command& command = GetDebugger()->ReadGXCommandHistory(command_index); | ||||
|     if (role == Qt::DisplayRole) | ||||
|     { | ||||
|         std::map<GSP_GPU::GXCommandId, const char*> command_names = { | ||||
|             { GSP_GPU::GXCommandId::REQUEST_DMA, "REQUEST_DMA" }, | ||||
|             { GSP_GPU::GXCommandId::SET_COMMAND_LIST_FIRST, "SET_COMMAND_LIST_FIRST" }, | ||||
|             { GSP_GPU::GXCommandId::SET_MEMORY_FILL, "SET_MEMORY_FILL" }, | ||||
|             { GSP_GPU::GXCommandId::SET_DISPLAY_TRANSFER, "SET_DISPLAY_TRANSFER" }, | ||||
|             { GSP_GPU::GXCommandId::SET_TEXTURE_COPY, "SET_TEXTURE_COPY" }, | ||||
|             { GSP_GPU::GXCommandId::SET_COMMAND_LIST_LAST, "SET_COMMAND_LIST_LAST" } | ||||
|         std::map<GSP_GPU::CommandId, const char*> command_names = { | ||||
|             { GSP_GPU::CommandId::REQUEST_DMA, "REQUEST_DMA" }, | ||||
|             { GSP_GPU::CommandId::SET_COMMAND_LIST_FIRST, "SET_COMMAND_LIST_FIRST" }, | ||||
|             { GSP_GPU::CommandId::SET_MEMORY_FILL, "SET_MEMORY_FILL" }, | ||||
|             { GSP_GPU::CommandId::SET_DISPLAY_TRANSFER, "SET_DISPLAY_TRANSFER" }, | ||||
|             { GSP_GPU::CommandId::SET_TEXTURE_COPY, "SET_TEXTURE_COPY" }, | ||||
|             { GSP_GPU::CommandId::SET_COMMAND_LIST_LAST, "SET_COMMAND_LIST_LAST" } | ||||
|         }; | ||||
|         const u32* command_data = reinterpret_cast<const u32*>(&command); | ||||
|         QString str = QString("%1 %2 %3 %4 %5 %6 %7 %8 %9").arg(command_names[command.id]) | ||||
|   | ||||
| @@ -11,53 +11,13 @@ | ||||
| #include "core/hle/kernel/event.h" | ||||
| #include "core/hle/kernel/shared_memory.h" | ||||
| #include "core/hle/service/gsp.h" | ||||
|  | ||||
| #include "core/hw/gpu.h" | ||||
|  | ||||
| #include "video_core/gpu_debugger.h" | ||||
|  | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| // Main graphics debugger object - TODO: Here is probably not the best place for this | ||||
| GraphicsDebugger g_debugger; | ||||
|  | ||||
| /// GSP thread interrupt queue header | ||||
| struct GX_InterruptQueue { | ||||
|     union { | ||||
|         u32 hex; | ||||
|  | ||||
|         // Index of last interrupt in the queue | ||||
|         BitField<0,8,u32>   index; | ||||
|  | ||||
|         // Number of interrupts remaining to be processed by the userland code | ||||
|         BitField<8,8,u32>   number_interrupts; | ||||
|  | ||||
|         // Error code - zero on success, otherwise an error has occurred | ||||
|         BitField<16,8,u32>  error_code; | ||||
|     }; | ||||
|  | ||||
|     u32 unk0; | ||||
|     u32 unk1; | ||||
|  | ||||
|     GSP_GPU::GXInterruptId slot[0x34];   ///< Interrupt ID slots | ||||
| }; | ||||
|  | ||||
| /// GSP shared memory GX command buffer header | ||||
| union GX_CmdBufferHeader { | ||||
|     u32 hex; | ||||
|  | ||||
|     // Current command index. This index is updated by GSP module after loading the command data, | ||||
|     // right before the command is processed. When this index is updated by GSP module, the total | ||||
|     // commands field is decreased by one as well. | ||||
|     BitField<0,8,u32>   index; | ||||
|  | ||||
|     // Total commands to process, must not be value 0 when GSP module handles commands. This must be | ||||
|     // <=15 when writing a command to shared memory. This is incremented by the application when | ||||
|     // writing a command to shared memory, after increasing this value TriggerCmdReqQueue is only | ||||
|     // used if this field is value 1. | ||||
|     BitField<8,8,u32>   number_commands; | ||||
| }; | ||||
|  | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| // Namespace GSP_GPU | ||||
|  | ||||
| @@ -69,15 +29,15 @@ Handle g_shared_memory = 0; | ||||
| u32 g_thread_id = 1; | ||||
|  | ||||
| /// Gets a pointer to the start (header) of a command buffer in GSP shared memory | ||||
| static inline u8* GX_GetCmdBufferPointer(u32 thread_id, u32 offset=0) { | ||||
| static inline u8* GetCmdBufferPointer(u32 thread_id, u32 offset=0) { | ||||
|     if (0 == g_shared_memory) return nullptr; | ||||
|  | ||||
|     return Kernel::GetSharedMemoryPointer(g_shared_memory, 0x800 + (thread_id * 0x200) + offset); | ||||
| } | ||||
|  | ||||
| /// Gets a pointer to the start (header) of a command buffer in GSP shared memory | ||||
| static inline GX_InterruptQueue* GetInterruptQueue(u32 thread_id) { | ||||
|     return (GX_InterruptQueue*)Kernel::GetSharedMemoryPointer(g_shared_memory, sizeof(GX_InterruptQueue) * thread_id); | ||||
| static inline InterruptQueue* GetInterruptQueue(u32 thread_id) { | ||||
|     return (InterruptQueue*)Kernel::GetSharedMemoryPointer(g_shared_memory, sizeof(InterruptQueue) * thread_id); | ||||
| } | ||||
|  | ||||
| /// Write a GSP GPU hardware register | ||||
| @@ -166,7 +126,7 @@ void RegisterInterruptRelayQueue(Service::Interface* self) { | ||||
|  * Signals that the specified interrupt type has occurred to userland code | ||||
|  * @param interrupt_id ID of interrupt that is being signalled | ||||
|  */ | ||||
| void SignalInterrupt(GXInterruptId interrupt_id) { | ||||
| void SignalInterrupt(InterruptId interrupt_id) { | ||||
|     if (0 == GSP_GPU::g_event) { | ||||
|         WARN_LOG(GSP, "cannot synchronize until GSP event has been created!"); | ||||
|         return; | ||||
| @@ -176,7 +136,7 @@ void SignalInterrupt(GXInterruptId interrupt_id) { | ||||
|         return; | ||||
|     } | ||||
|     for (int thread_id = 0; thread_id < 0x4; ++thread_id) { | ||||
|         GX_InterruptQueue* interrupt_queue = GetInterruptQueue(thread_id); | ||||
|         InterruptQueue* interrupt_queue = GetInterruptQueue(thread_id); | ||||
|         interrupt_queue->number_interrupts = interrupt_queue->number_interrupts + 1; | ||||
|          | ||||
|         u8 next = interrupt_queue->index; | ||||
| @@ -190,24 +150,24 @@ void SignalInterrupt(GXInterruptId interrupt_id) { | ||||
| } | ||||
|  | ||||
| /// Executes the next GSP command | ||||
| void ExecuteCommand(int thread_id, int command_index) { | ||||
| void ExecuteCommand(u32 thread_id, u32 command_index) { | ||||
|  | ||||
|     // Utility function to convert register ID to address | ||||
|     auto WriteGPURegister = [](u32 id, u32 data) { | ||||
|         GPU::Write<u32>(0x1EF00000 + 4 * id, data); | ||||
|     }; | ||||
|  | ||||
|     GX_CmdBufferHeader* header = (GX_CmdBufferHeader*)GX_GetCmdBufferPointer(thread_id); | ||||
|     auto& command = *(const GXCommand*)GX_GetCmdBufferPointer(thread_id, (command_index + 1) * 0x20); | ||||
|     CmdBufferHeader* header = (CmdBufferHeader*)GetCmdBufferPointer(thread_id); | ||||
|     auto& command = *(const Command*)GetCmdBufferPointer(thread_id, (command_index + 1) * 0x20); | ||||
|  | ||||
|     g_debugger.GXCommandProcessed(GX_GetCmdBufferPointer(thread_id, 0x20 + (header->index * 0x20))); | ||||
|     g_debugger.GXCommandProcessed(GetCmdBufferPointer(thread_id, 0x20 + (header->index * 0x20))); | ||||
|  | ||||
|     NOTICE_LOG(GSP, "decoding command 0x%08X", (int)command.id.Value()); | ||||
|  | ||||
|     switch (command.id) { | ||||
|  | ||||
|     // GX request DMA - typically used for copying memory from GSP heap to VRAM | ||||
|     case GXCommandId::REQUEST_DMA: | ||||
|     case CommandId::REQUEST_DMA: | ||||
|         memcpy(Memory::GetPointer(command.dma_request.dest_address), | ||||
|                Memory::GetPointer(command.dma_request.source_address), | ||||
|                command.dma_request.size); | ||||
| @@ -216,7 +176,7 @@ void ExecuteCommand(int thread_id, int command_index) { | ||||
|     // ctrulib homebrew sends all relevant command list data with this command, | ||||
|     // hence we do all "interesting" stuff here and do nothing in SET_COMMAND_LIST_FIRST. | ||||
|     // TODO: This will need some rework in the future. | ||||
|     case GXCommandId::SET_COMMAND_LIST_LAST: | ||||
|     case CommandId::SET_COMMAND_LIST_LAST: | ||||
|     { | ||||
|         auto& params = command.set_command_list_last; | ||||
|         WriteGPURegister(GPU::Regs::CommandProcessor + 2, params.address >> 3); | ||||
| @@ -228,13 +188,13 @@ void ExecuteCommand(int thread_id, int command_index) { | ||||
|         g_debugger.CommandListCalled(params.address, | ||||
|                                      (u32*)Memory::GetPointer(params.address), | ||||
|                                      params.size); | ||||
|         SignalInterrupt(GXInterruptId::P3D); | ||||
|         SignalInterrupt(InterruptId::P3D); | ||||
|         break; | ||||
|     } | ||||
|  | ||||
|     // It's assumed that the two "blocks" behave equivalently. | ||||
|     // Presumably this is done simply to allow two memory fills to run in parallel. | ||||
|     case GXCommandId::SET_MEMORY_FILL: | ||||
|     case CommandId::SET_MEMORY_FILL: | ||||
|     { | ||||
|         auto& params = command.memory_fill; | ||||
|         WriteGPURegister(GPU::Regs::MemoryFill, params.start1 >> 3); | ||||
| @@ -250,18 +210,18 @@ void ExecuteCommand(int thread_id, int command_index) { | ||||
|     } | ||||
|  | ||||
|     // TODO: Check if texture copies are implemented correctly.. | ||||
|     case GXCommandId::SET_DISPLAY_TRANSFER: | ||||
|     case CommandId::SET_DISPLAY_TRANSFER: | ||||
|         // TODO(bunnei): Signalling all of these interrupts here is totally wrong, but it seems to | ||||
|         // work well enough for running demos. Need to figure out how these all work and trigger | ||||
|         // them correctly. | ||||
|         SignalInterrupt(GXInterruptId::PSC0); | ||||
|         SignalInterrupt(GXInterruptId::PSC1); | ||||
|         SignalInterrupt(GXInterruptId::PPF); | ||||
|         SignalInterrupt(GXInterruptId::P3D); | ||||
|         SignalInterrupt(GXInterruptId::DMA); | ||||
|         SignalInterrupt(InterruptId::PSC0); | ||||
|         SignalInterrupt(InterruptId::PSC1); | ||||
|         SignalInterrupt(InterruptId::PPF); | ||||
|         SignalInterrupt(InterruptId::P3D); | ||||
|         SignalInterrupt(InterruptId::DMA); | ||||
|         break; | ||||
|  | ||||
|     case GXCommandId::SET_TEXTURE_COPY: | ||||
|     case CommandId::SET_TEXTURE_COPY: | ||||
|     { | ||||
|         auto& params = command.image_copy; | ||||
|         WriteGPURegister(GPU::Regs::DisplayTransfer, params.in_buffer_address >> 3); | ||||
| @@ -278,7 +238,7 @@ void ExecuteCommand(int thread_id, int command_index) { | ||||
|  | ||||
|     // TODO: Figure out what exactly SET_COMMAND_LIST_FIRST and SET_COMMAND_LIST_LAST | ||||
|     //       are supposed to do. | ||||
|     case GXCommandId::SET_COMMAND_LIST_FIRST: | ||||
|     case CommandId::SET_COMMAND_LIST_FIRST: | ||||
|     { | ||||
|         break; | ||||
|     } | ||||
| @@ -294,11 +254,11 @@ void ExecuteCommand(int thread_id, int command_index) { | ||||
| void TriggerCmdReqQueue(Service::Interface* self) { | ||||
|  | ||||
|     // Iterate through each thread's command queue... | ||||
|     for (int thread_id = 0; thread_id < 0x4; ++thread_id) { | ||||
|         GX_CmdBufferHeader* header = (GX_CmdBufferHeader*)GX_GetCmdBufferPointer(thread_id); | ||||
|     for (u32 thread_id = 0; thread_id < 0x4; ++thread_id) { | ||||
|         CmdBufferHeader* header = (CmdBufferHeader*)GetCmdBufferPointer(thread_id); | ||||
|  | ||||
|         // Iterate through each command... | ||||
|         for (int command_index = 0; command_index < header->number_commands; ++command_index) { | ||||
|         for (u32 command_index = 0; command_index < header->number_commands; ++command_index) { | ||||
|             ExecuteCommand(thread_id, command_index); | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -12,7 +12,19 @@ | ||||
|  | ||||
| namespace GSP_GPU { | ||||
|  | ||||
| enum class GXCommandId : u32 { | ||||
| /// GSP interrupt ID | ||||
| enum class InterruptId : u8 { | ||||
|     PSC0    = 0x00, | ||||
|     PSC1    = 0x01, | ||||
|     PDC0    = 0x02, // Seems called every vertical screen line | ||||
|     PDC1    = 0x03, // Seems called every frame | ||||
|     PPF     = 0x04, | ||||
|     P3D     = 0x05, | ||||
|     DMA     = 0x06, | ||||
| }; | ||||
|  | ||||
| /// GSP command ID | ||||
| enum class CommandId : u32 { | ||||
|     REQUEST_DMA            = 0x00, | ||||
|     SET_COMMAND_LIST_LAST  = 0x01, | ||||
|  | ||||
| @@ -29,18 +41,47 @@ enum class GXCommandId : u32 { | ||||
|     SET_COMMAND_LIST_FIRST = 0x05, | ||||
| }; | ||||
|  | ||||
| enum class GXInterruptId : u8 { | ||||
|     PSC0    = 0x00, | ||||
|     PSC1    = 0x01, | ||||
|     PDC0    = 0x02, // Seems called every vertical screen line | ||||
|     PDC1    = 0x03, // Seems called every frame | ||||
|     PPF     = 0x04, | ||||
|     P3D     = 0x05, | ||||
|     DMA     = 0x06, | ||||
| /// GSP thread interrupt queue header | ||||
| struct InterruptQueue { | ||||
|     union { | ||||
|         u32 hex; | ||||
|  | ||||
|         // Index of last interrupt in the queue | ||||
|         BitField<0,8,u32>   index; | ||||
|  | ||||
|         // Number of interrupts remaining to be processed by the userland code | ||||
|         BitField<8,8,u32>   number_interrupts; | ||||
|  | ||||
|         // Error code - zero on success, otherwise an error has occurred | ||||
|         BitField<16,8,u32>  error_code; | ||||
|     }; | ||||
|  | ||||
|     u32 unk0; | ||||
|     u32 unk1; | ||||
|  | ||||
|     InterruptId slot[0x34];   ///< Interrupt ID slots | ||||
| }; | ||||
| static_assert(sizeof(InterruptQueue) == 0x40, "InterruptQueue struct has incorrect size"); | ||||
|  | ||||
| /// GSP shared memory GX command buffer header | ||||
| union CmdBufferHeader { | ||||
|     u32 hex; | ||||
|  | ||||
|     // Current command index. This index is updated by GSP module after loading the command data, | ||||
|     // right before the command is processed. When this index is updated by GSP module, the total | ||||
|     // commands field is decreased by one as well. | ||||
|     BitField<0,8,u32>   index; | ||||
|  | ||||
|     // Total commands to process, must not be value 0 when GSP module handles commands. This must be | ||||
|     // <=15 when writing a command to shared memory. This is incremented by the application when | ||||
|     // writing a command to shared memory, after increasing this value TriggerCmdReqQueue is only | ||||
|     // used if this field is value 1. | ||||
|     BitField<8,8,u32>   number_commands; | ||||
| }; | ||||
|  | ||||
| struct GXCommand { | ||||
|     BitField<0, 8, GXCommandId> id; | ||||
| /// GSP command | ||||
| struct Command { | ||||
|     BitField<0, 8, CommandId> id; | ||||
|  | ||||
|     union { | ||||
|         struct { | ||||
| @@ -74,7 +115,7 @@ struct GXCommand { | ||||
|         u8 raw_data[0x1C]; | ||||
|     }; | ||||
| }; | ||||
| static_assert(sizeof(GXCommand) == 0x20, "GXCommand struct has incorrect size"); | ||||
| static_assert(sizeof(Command) == 0x20, "Command struct has incorrect size"); | ||||
|  | ||||
| /// Interface to "srv:" service | ||||
| class Interface : public Service::Interface { | ||||
| @@ -98,6 +139,6 @@ public: | ||||
|  * Signals that the specified interrupt type has occurred to userland code | ||||
|  * @param interrupt_id ID of interrupt that is being signalled | ||||
|  */ | ||||
| void SignalInterrupt(GXInterruptId interrupt_id); | ||||
| void SignalInterrupt(InterruptId interrupt_id); | ||||
|  | ||||
| } // namespace | ||||
|   | ||||
| @@ -256,7 +256,7 @@ void Update() { | ||||
|  | ||||
|     // Synchronize line... | ||||
|     if ((current_ticks - g_last_ticks) >= GPU::kFrameTicks / 400) { | ||||
|         GSP_GPU::SignalInterrupt(GSP_GPU::GXInterruptId::PDC0); | ||||
|         GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PDC0); | ||||
|         g_cur_line++; | ||||
|         g_last_ticks = current_ticks; | ||||
|     } | ||||
| @@ -264,7 +264,7 @@ void Update() { | ||||
|     // Synchronize frame... | ||||
|     if (g_cur_line >= 400) { | ||||
|         g_cur_line = 0; | ||||
|         GSP_GPU::SignalInterrupt(GSP_GPU::GXInterruptId::PDC1); | ||||
|         GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PDC1); | ||||
|         VideoCore::g_renderer->SwapBuffers(); | ||||
|         Kernel::WaitCurrentThread(WAITTYPE_VBLANK); | ||||
|         HLE::Reschedule(__func__); | ||||
|   | ||||
| @@ -49,7 +49,7 @@ public: | ||||
|         */ | ||||
|         virtual void GXCommandProcessed(int total_command_count) | ||||
|         { | ||||
|             const GSP_GPU::GXCommand& cmd = observed->ReadGXCommandHistory(total_command_count-1); | ||||
|             const GSP_GPU::Command& cmd = observed->ReadGXCommandHistory(total_command_count-1); | ||||
|             ERROR_LOG(GSP, "Received command: id=%x", (int)cmd.id.Value()); | ||||
|         } | ||||
|  | ||||
| @@ -81,10 +81,10 @@ public: | ||||
|         if (observers.empty()) | ||||
|             return; | ||||
|  | ||||
|         gx_command_history.push_back(GSP_GPU::GXCommand()); | ||||
|         GSP_GPU::GXCommand& cmd = gx_command_history[gx_command_history.size()-1]; | ||||
|         gx_command_history.push_back(GSP_GPU::Command()); | ||||
|         GSP_GPU::Command& cmd = gx_command_history[gx_command_history.size()-1]; | ||||
|  | ||||
|         memcpy(&cmd, command_data, sizeof(GSP_GPU::GXCommand)); | ||||
|         memcpy(&cmd, command_data, sizeof(GSP_GPU::Command)); | ||||
|  | ||||
|         ForEachObserver([this](DebuggerObserver* observer) { | ||||
|                           observer->GXCommandProcessed(this->gx_command_history.size()); | ||||
| @@ -123,7 +123,7 @@ public: | ||||
|                         } ); | ||||
|     } | ||||
|  | ||||
|     const GSP_GPU::GXCommand& ReadGXCommandHistory(int index) const | ||||
|     const GSP_GPU::Command& ReadGXCommandHistory(int index) const | ||||
|     { | ||||
|         // TODO: Is this thread-safe? | ||||
|         return gx_command_history[index]; | ||||
| @@ -155,7 +155,7 @@ private: | ||||
|  | ||||
|     std::vector<DebuggerObserver*> observers; | ||||
|  | ||||
|     std::vector<GSP_GPU::GXCommand> gx_command_history; | ||||
|     std::vector<GSP_GPU::Command> gx_command_history; | ||||
|  | ||||
|     // vector of pairs of command lists and their storage address | ||||
|     std::vector<std::pair<u32,PicaCommandList>> command_lists; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user