mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	Add initial graphics debugger interface.
This commit is contained in:
		
							parent
							
								
									82d3260359
								
							
						
					
					
						commit
						31666632ca
					
				
					 4 changed files with 108 additions and 3 deletions
				
			
		|  | @ -16,6 +16,9 @@ | ||||||
| 
 | 
 | ||||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||||
| 
 | 
 | ||||||
|  | // Main graphics debugger object - TODO: Here is probably not the best place for this
 | ||||||
|  | GraphicsDebugger g_debugger; | ||||||
|  | 
 | ||||||
| /// GSP shared memory GX command buffer header
 | /// GSP shared memory GX command buffer header
 | ||||||
| union GX_CmdBufferHeader { | union GX_CmdBufferHeader { | ||||||
|     u32 hex; |     u32 hex; | ||||||
|  | @ -45,6 +48,9 @@ static inline u8* GX_GetCmdBufferPointer(u32 thread_id, u32 offset=0) { | ||||||
| /// Finishes execution of a GSP command
 | /// Finishes execution of a GSP command
 | ||||||
| void GX_FinishCommand(u32 thread_id) { | void GX_FinishCommand(u32 thread_id) { | ||||||
|     GX_CmdBufferHeader* header = (GX_CmdBufferHeader*)GX_GetCmdBufferPointer(thread_id); |     GX_CmdBufferHeader* header = (GX_CmdBufferHeader*)GX_GetCmdBufferPointer(thread_id); | ||||||
|  | 
 | ||||||
|  |     g_debugger.GXCommandProcessed(GX_GetCmdBufferPointer(thread_id, 0x20 + (header->index * 0x20))); | ||||||
|  | 
 | ||||||
|     header->number_commands = header->number_commands - 1; |     header->number_commands = header->number_commands - 1; | ||||||
|     // TODO: Increment header->index?
 |     // TODO: Increment header->index?
 | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										97
									
								
								src/video_core/gpu_debugger.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								src/video_core/gpu_debugger.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,97 @@ | ||||||
|  | // Copyright 2014 Citra Emulator Project
 | ||||||
|  | // Licensed under GPLv2
 | ||||||
|  | // Refer to the license.txt file included.
 | ||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <algorithm> | ||||||
|  | #include <functional> | ||||||
|  | #include <vector> | ||||||
|  | 
 | ||||||
|  | #include "common/log.h" | ||||||
|  | 
 | ||||||
|  | #include "core/hle/service/gsp.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class GraphicsDebugger | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |     // Base class for all objects which need to be notified about GPU events
 | ||||||
|  |     class DebuggerObserver | ||||||
|  |     { | ||||||
|  |     public: | ||||||
|  |         DebuggerObserver() : observed(nullptr) { } | ||||||
|  | 
 | ||||||
|  |         virtual ~DebuggerObserver() | ||||||
|  |         { | ||||||
|  |             if (observed) | ||||||
|  |                 observed->UnregisterObserver(this); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |         * Called when a GX command has been processed and is ready for being | ||||||
|  |         * read via GraphicsDebugger::ReadGXCommandHistory. | ||||||
|  |         * @param total_command_count Total number of commands in the GX history | ||||||
|  |         * @note All methods in this class are called from the GSP thread | ||||||
|  |         */ | ||||||
|  |         virtual void GXCommandProcessed(int total_command_count) | ||||||
|  |         { | ||||||
|  |             const GSP_GPU::GXCommand& cmd = observed->ReadGXCommandHistory(total_command_count-1); | ||||||
|  |             ERROR_LOG(GSP, "Received command: id=%x", cmd.id); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     protected: | ||||||
|  |         GraphicsDebugger* GetDebugger() | ||||||
|  |         { | ||||||
|  |             return observed; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     private: | ||||||
|  |         GraphicsDebugger* observed; | ||||||
|  |         bool in_destruction; | ||||||
|  | 
 | ||||||
|  |         friend class GraphicsDebugger; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     void GXCommandProcessed(u8* command_data) | ||||||
|  |     { | ||||||
|  |         gx_command_history.push_back(GSP_GPU::GXCommand()); | ||||||
|  |         GSP_GPU::GXCommand& cmd = gx_command_history[gx_command_history.size()-1]; | ||||||
|  | 
 | ||||||
|  |         const int cmd_length = sizeof(GSP_GPU::GXCommand); | ||||||
|  |         memcpy(cmd.data, command_data, cmd_length); | ||||||
|  | 
 | ||||||
|  |         ForEachObserver([this](DebuggerObserver* observer) { | ||||||
|  |                           observer->GXCommandProcessed(this->gx_command_history.size()); | ||||||
|  |                         } ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     const GSP_GPU::GXCommand& ReadGXCommandHistory(int index) const | ||||||
|  |     { | ||||||
|  |         // TODO: Is this thread-safe?
 | ||||||
|  |         return gx_command_history[index]; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void RegisterObserver(DebuggerObserver* observer) | ||||||
|  |     { | ||||||
|  |         // TODO: Check for duplicates
 | ||||||
|  |         observers.push_back(observer); | ||||||
|  |         observer->observed = this; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void UnregisterObserver(DebuggerObserver* observer) | ||||||
|  |     { | ||||||
|  |         std::remove(observers.begin(), observers.end(), observer); | ||||||
|  |         observer->observed = nullptr; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     void ForEachObserver(std::function<void (DebuggerObserver*)> func) | ||||||
|  |     { | ||||||
|  |         std::for_each(observers.begin(),observers.end(), func); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     std::vector<DebuggerObserver*> observers; | ||||||
|  | 
 | ||||||
|  |     std::vector<GSP_GPU::GXCommand> gx_command_history; | ||||||
|  | }; | ||||||
|  | @ -24,10 +24,11 @@ | ||||||
|     <ClCompile Include="video_core.cpp" /> |     <ClCompile Include="video_core.cpp" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|  |     <ClInclude Include="gpu_debugger.h" /> | ||||||
|     <ClInclude Include="renderer_base.h" /> |     <ClInclude Include="renderer_base.h" /> | ||||||
|     <ClInclude Include="renderer_opengl\renderer_opengl.h" /> |  | ||||||
|     <ClInclude Include="utils.h" /> |     <ClInclude Include="utils.h" /> | ||||||
|     <ClInclude Include="video_core.h" /> |     <ClInclude Include="video_core.h" /> | ||||||
|  |     <ClInclude Include="renderer_opengl\renderer_opengl.h" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <Text Include="CMakeLists.txt" /> |     <Text Include="CMakeLists.txt" /> | ||||||
|  |  | ||||||
|  | @ -16,6 +16,7 @@ | ||||||
|     <ClInclude Include="renderer_opengl\renderer_opengl.h"> |     <ClInclude Include="renderer_opengl\renderer_opengl.h"> | ||||||
|       <Filter>renderer_opengl</Filter> |       <Filter>renderer_opengl</Filter> | ||||||
|     </ClInclude> |     </ClInclude> | ||||||
|  |     <ClInclude Include="gpu_debugger.h" /> | ||||||
|     <ClInclude Include="renderer_base.h" /> |     <ClInclude Include="renderer_base.h" /> | ||||||
|     <ClInclude Include="utils.h" /> |     <ClInclude Include="utils.h" /> | ||||||
|     <ClInclude Include="video_core.h" /> |     <ClInclude Include="video_core.h" /> | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue