mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	GPU debugger: Add functionality to inspect command lists.
This commit is contained in:
		
							parent
							
								
									50b2b73be4
								
							
						
					
					
						commit
						5d62f5d92a
					
				
					 2 changed files with 57 additions and 1 deletions
				
			
		|  | @ -126,6 +126,10 @@ void TriggerCmdReqQueue(Service::Interface* self) { | ||||||
|         GPU::Write<u32>(GPU::Registers::CommandListAddress, cmd_buff[1] >> 3); |         GPU::Write<u32>(GPU::Registers::CommandListAddress, cmd_buff[1] >> 3); | ||||||
|         GPU::Write<u32>(GPU::Registers::CommandListSize, cmd_buff[2] >> 3); |         GPU::Write<u32>(GPU::Registers::CommandListSize, cmd_buff[2] >> 3); | ||||||
|         GPU::Write<u32>(GPU::Registers::ProcessCommandList, 1); // TODO: Not sure if we are supposed to always write this
 |         GPU::Write<u32>(GPU::Registers::ProcessCommandList, 1); // TODO: Not sure if we are supposed to always write this
 | ||||||
|  | 
 | ||||||
|  |         // TODO: Move this to GPU
 | ||||||
|  |         // TODO: Not sure what units the size is measured in
 | ||||||
|  |         g_debugger.CommandListCalled(cmd_buff[1], (u32*)Memory::GetPointer(cmd_buff[1]), cmd_buff[2]); | ||||||
|         break; |         break; | ||||||
| 
 | 
 | ||||||
|     case GXCommandId::SET_MEMORY_FILL: |     case GXCommandId::SET_MEMORY_FILL: | ||||||
|  |  | ||||||
|  | @ -11,11 +11,23 @@ | ||||||
| #include "common/log.h" | #include "common/log.h" | ||||||
| 
 | 
 | ||||||
| #include "core/hle/service/gsp.h" | #include "core/hle/service/gsp.h" | ||||||
| 
 | #include "pica.h" | ||||||
| 
 | 
 | ||||||
| class GraphicsDebugger | class GraphicsDebugger | ||||||
| { | { | ||||||
| public: | public: | ||||||
|  |     // A few utility structs used to expose data
 | ||||||
|  |     // A vector of commands represented by their raw byte sequence
 | ||||||
|  |     struct PicaCommand : public std::vector<u32> | ||||||
|  |     { | ||||||
|  |         Pica::CommandHeader& GetHeader() | ||||||
|  |         { | ||||||
|  |             return *(Pica::CommandHeader*)&(front()); | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     typedef std::vector<PicaCommand> PicaCommandList; | ||||||
|  | 
 | ||||||
|     // Base class for all objects which need to be notified about GPU events
 |     // Base class for all objects which need to be notified about GPU events
 | ||||||
|     class DebuggerObserver |     class DebuggerObserver | ||||||
|     { |     { | ||||||
|  | @ -40,6 +52,16 @@ public: | ||||||
|             ERROR_LOG(GSP, "Received command: id=%x", cmd.id); |             ERROR_LOG(GSP, "Received command: id=%x", cmd.id); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         /**
 | ||||||
|  |         * @param lst command list which triggered this call | ||||||
|  |         * @param is_new true if the command list was called for the first time | ||||||
|  |         * @todo figure out how to make sure called functions don't keep references around beyond their life time | ||||||
|  |         */ | ||||||
|  |         virtual void CommandListCalled(const PicaCommandList& lst, bool is_new) | ||||||
|  |         { | ||||||
|  |             ERROR_LOG(GSP, "Command list called: %d", (int)is_new); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|     protected: |     protected: | ||||||
|         GraphicsDebugger* GetDebugger() |         GraphicsDebugger* GetDebugger() | ||||||
|         { |         { | ||||||
|  | @ -66,12 +88,39 @@ public: | ||||||
|                         } ); |                         } ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     void CommandListCalled(u32 address, u32* command_list, u32 size_in_words) | ||||||
|  |     { | ||||||
|  |         // TODO: Decoding fun
 | ||||||
|  | 
 | ||||||
|  |         // For now, just treating the whole command list as a single command
 | ||||||
|  |         PicaCommandList cmdlist; | ||||||
|  |         cmdlist.push_back(PicaCommand()); | ||||||
|  |         auto& cmd = cmdlist[0]; | ||||||
|  |         cmd.reserve(size_in_words); | ||||||
|  |         std::copy(command_list, command_list+size_in_words, std::back_inserter(cmd)); | ||||||
|  | 
 | ||||||
|  |         auto obj = std::pair<u32,PicaCommandList>(address, cmdlist); | ||||||
|  |         auto it = std::find(command_lists.begin(), command_lists.end(), obj); | ||||||
|  |         bool is_new = (it == command_lists.end()); | ||||||
|  |         if (is_new) | ||||||
|  |             command_lists.push_back(obj); | ||||||
|  | 
 | ||||||
|  |         ForEachObserver([&](DebuggerObserver* observer) { | ||||||
|  |                             observer->CommandListCalled(obj.second, is_new); | ||||||
|  |                         } ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     const GSP_GPU::GXCommand& ReadGXCommandHistory(int index) const |     const GSP_GPU::GXCommand& ReadGXCommandHistory(int index) const | ||||||
|     { |     { | ||||||
|         // TODO: Is this thread-safe?
 |         // TODO: Is this thread-safe?
 | ||||||
|         return gx_command_history[index]; |         return gx_command_history[index]; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     const std::vector<std::pair<u32,PicaCommandList>>& GetCommandLists() const | ||||||
|  |     { | ||||||
|  |         return command_lists; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     void RegisterObserver(DebuggerObserver* observer) |     void RegisterObserver(DebuggerObserver* observer) | ||||||
|     { |     { | ||||||
|         // TODO: Check for duplicates
 |         // TODO: Check for duplicates
 | ||||||
|  | @ -94,4 +143,7 @@ private: | ||||||
|     std::vector<DebuggerObserver*> observers; |     std::vector<DebuggerObserver*> observers; | ||||||
| 
 | 
 | ||||||
|     std::vector<GSP_GPU::GXCommand> gx_command_history; |     std::vector<GSP_GPU::GXCommand> gx_command_history; | ||||||
|  | 
 | ||||||
|  |     // vector of pairs of command lists and their storage address
 | ||||||
|  |     std::vector<std::pair<u32,PicaCommandList>> command_lists; | ||||||
| }; | }; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue