mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +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
					
				@ -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…
	
		Reference in New Issue
	
	Block a user