mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	GSP: Implement command 0x05, used for flushing caches
May fix additional texture caching issues. (Though mostly in homebrew, I haven't seen any commercial software use this to flush anything but command lists.)
This commit is contained in:
		
							parent
							
								
									5fdfd782cc
								
							
						
					
					
						commit
						1ed7f3e028
					
				
					 3 changed files with 36 additions and 15 deletions
				
			
		|  | @ -30,11 +30,11 @@ QVariant GPUCommandStreamItemModel::data(const QModelIndex& index, int role) con | ||||||
|     { |     { | ||||||
|         std::map<GSP_GPU::CommandId, const char*> command_names = { |         std::map<GSP_GPU::CommandId, const char*> command_names = { | ||||||
|             { GSP_GPU::CommandId::REQUEST_DMA, "REQUEST_DMA" }, |             { GSP_GPU::CommandId::REQUEST_DMA, "REQUEST_DMA" }, | ||||||
|             { GSP_GPU::CommandId::SET_COMMAND_LIST_FIRST, "SET_COMMAND_LIST_FIRST" }, |             { GSP_GPU::CommandId::SUBMIT_GPU_CMDLIST, "SUBMIT_GPU_CMDLIST" }, | ||||||
|             { GSP_GPU::CommandId::SET_MEMORY_FILL, "SET_MEMORY_FILL" }, |             { GSP_GPU::CommandId::SET_MEMORY_FILL, "SET_MEMORY_FILL" }, | ||||||
|             { GSP_GPU::CommandId::SET_DISPLAY_TRANSFER, "SET_DISPLAY_TRANSFER" }, |             { GSP_GPU::CommandId::SET_DISPLAY_TRANSFER, "SET_DISPLAY_TRANSFER" }, | ||||||
|             { GSP_GPU::CommandId::SET_TEXTURE_COPY, "SET_TEXTURE_COPY" }, |             { GSP_GPU::CommandId::SET_TEXTURE_COPY, "SET_TEXTURE_COPY" }, | ||||||
|             { GSP_GPU::CommandId::SET_COMMAND_LIST_LAST, "SET_COMMAND_LIST_LAST" } |             { GSP_GPU::CommandId::CACHE_FLUSH, "CACHE_FLUSH" }, | ||||||
|         }; |         }; | ||||||
|         const u32* command_data = reinterpret_cast<const u32*>(&command); |         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]) |         QString str = QString("%1 %2 %3 %4 %5 %6 %7 %8 %9").arg(command_names[command.id]) | ||||||
|  |  | ||||||
|  | @ -377,12 +377,16 @@ static void ExecuteCommand(const Command& command, u32 thread_id) { | ||||||
|                                                           command.dma_request.size); |                                                           command.dma_request.size); | ||||||
|         break; |         break; | ||||||
| 
 | 
 | ||||||
|     // ctrulib homebrew sends all relevant command list data with this command,
 |     // TODO: This will need some rework in the future. (why?)
 | ||||||
|     // hence we do all "interesting" stuff here and do nothing in SET_COMMAND_LIST_FIRST.
 |     case CommandId::SUBMIT_GPU_CMDLIST: | ||||||
|     // TODO: This will need some rework in the future.
 |  | ||||||
|     case CommandId::SET_COMMAND_LIST_LAST: |  | ||||||
|     { |     { | ||||||
|         auto& params = command.set_command_list_last; |         auto& params = command.submit_gpu_cmdlist; | ||||||
|  | 
 | ||||||
|  |         if (params.do_flush) { | ||||||
|  |             // This flag flushes the command list (params.address, params.size) from the cache.
 | ||||||
|  |             // Command lists are not processed by the hardware renderer, so we don't need to
 | ||||||
|  |             // actually flush them in Citra.
 | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(command_processor_config.address)), |         WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(command_processor_config.address)), | ||||||
|                 Memory::VirtualToPhysicalAddress(params.address) >> 3); |                 Memory::VirtualToPhysicalAddress(params.address) >> 3); | ||||||
|  | @ -391,6 +395,8 @@ static void ExecuteCommand(const Command& command, u32 thread_id) { | ||||||
|         // TODO: Not sure if we are supposed to always write this .. seems to trigger processing though
 |         // TODO: Not sure if we are supposed to always write this .. seems to trigger processing though
 | ||||||
|         WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(command_processor_config.trigger)), 1); |         WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(command_processor_config.trigger)), 1); | ||||||
| 
 | 
 | ||||||
|  |         // TODO(yuriks): Figure out the meaning of the `flags` field.
 | ||||||
|  | 
 | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -434,7 +440,6 @@ static void ExecuteCommand(const Command& command, u32 thread_id) { | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // TODO: Check if texture copies are implemented correctly..
 |  | ||||||
|     case CommandId::SET_TEXTURE_COPY: |     case CommandId::SET_TEXTURE_COPY: | ||||||
|     { |     { | ||||||
|         auto& params = command.texture_copy; |         auto& params = command.texture_copy; | ||||||
|  | @ -456,10 +461,15 @@ static void ExecuteCommand(const Command& command, u32 thread_id) { | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // TODO: Figure out what exactly SET_COMMAND_LIST_FIRST and SET_COMMAND_LIST_LAST
 |     case CommandId::CACHE_FLUSH: | ||||||
|     //       are supposed to do.
 |  | ||||||
|     case CommandId::SET_COMMAND_LIST_FIRST: |  | ||||||
|     { |     { | ||||||
|  |         for (auto& region : command.cache_flush.regions) { | ||||||
|  |             if (region.size == 0) | ||||||
|  |                 break; | ||||||
|  | 
 | ||||||
|  |             VideoCore::g_renderer->hw_rasterizer->NotifyFlush( | ||||||
|  |                 Memory::VirtualToPhysicalAddress(region.address), region.size); | ||||||
|  |         } | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -31,7 +31,8 @@ enum class InterruptId : u8 { | ||||||
| /// GSP command ID
 | /// GSP command ID
 | ||||||
| enum class CommandId : u32 { | enum class CommandId : u32 { | ||||||
|     REQUEST_DMA            = 0x00, |     REQUEST_DMA            = 0x00, | ||||||
|     SET_COMMAND_LIST_LAST  = 0x01, |     /// Submits a commandlist for execution by the GPU.
 | ||||||
|  |     SUBMIT_GPU_CMDLIST = 0x01, | ||||||
| 
 | 
 | ||||||
|     // Fills a given memory range with a particular value
 |     // Fills a given memory range with a particular value
 | ||||||
|     SET_MEMORY_FILL        = 0x02, |     SET_MEMORY_FILL        = 0x02, | ||||||
|  | @ -42,8 +43,8 @@ enum class CommandId : u32 { | ||||||
| 
 | 
 | ||||||
|     // Conceptionally similar to SET_DISPLAY_TRANSFER and presumable uses the same hardware path
 |     // Conceptionally similar to SET_DISPLAY_TRANSFER and presumable uses the same hardware path
 | ||||||
|     SET_TEXTURE_COPY       = 0x04, |     SET_TEXTURE_COPY       = 0x04, | ||||||
| 
 |     /// Flushes up to 3 cache regions in a single command.
 | ||||||
|     SET_COMMAND_LIST_FIRST = 0x05, |     CACHE_FLUSH = 0x05, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /// GSP thread interrupt relay queue
 | /// GSP thread interrupt relay queue
 | ||||||
|  | @ -106,7 +107,10 @@ struct Command { | ||||||
|         struct { |         struct { | ||||||
|             u32 address; |             u32 address; | ||||||
|             u32 size; |             u32 size; | ||||||
|         } set_command_list_last; |             u32 flags; | ||||||
|  |             u32 unused[3]; | ||||||
|  |             u32 do_flush; | ||||||
|  |         } submit_gpu_cmdlist; | ||||||
| 
 | 
 | ||||||
|         struct { |         struct { | ||||||
|             u32 start1; |             u32 start1; | ||||||
|  | @ -138,6 +142,13 @@ struct Command { | ||||||
|             u32 flags; |             u32 flags; | ||||||
|         } texture_copy; |         } texture_copy; | ||||||
| 
 | 
 | ||||||
|  |         struct { | ||||||
|  |             struct { | ||||||
|  |                 u32 address; | ||||||
|  |                 u32 size; | ||||||
|  |             } regions[3]; | ||||||
|  |         } cache_flush; | ||||||
|  | 
 | ||||||
|         u8 raw_data[0x1C]; |         u8 raw_data[0x1C]; | ||||||
|     }; |     }; | ||||||
| }; | }; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue