Explorar el Código

Merge pull request #1123 from yuriks/gsp-flush

GSP: Implement command 0x05, used for flushing caches
Yuri Kunde Schlesner hace 11 años
padre
commit
b3af7aad9e

+ 2 - 2
src/citra_qt/debugger/graphics.cpp

@@ -30,11 +30,11 @@ QVariant GPUCommandStreamItemModel::data(const QModelIndex& index, int role) con
     {
         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::SUBMIT_GPU_CMDLIST, "SUBMIT_GPU_CMDLIST" },
             { 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" }
+            { GSP_GPU::CommandId::CACHE_FLUSH, "CACHE_FLUSH" },
         };
         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])

+ 19 - 9
src/core/hle/service/gsp_gpu.cpp

@@ -377,12 +377,16 @@ static void ExecuteCommand(const Command& command, u32 thread_id) {
                                                           command.dma_request.size);
         break;
 
-    // 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 CommandId::SET_COMMAND_LIST_LAST:
+    // TODO: This will need some rework in the future. (why?)
+    case CommandId::SUBMIT_GPU_CMDLIST:
     {
-        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)),
                 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
         WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(command_processor_config.trigger)), 1);
 
+        // TODO(yuriks): Figure out the meaning of the `flags` field.
+
         break;
     }
 
@@ -434,7 +440,6 @@ static void ExecuteCommand(const Command& command, u32 thread_id) {
         break;
     }
 
-    // TODO: Check if texture copies are implemented correctly..
     case CommandId::SET_TEXTURE_COPY:
     {
         auto& params = command.texture_copy;
@@ -456,10 +461,15 @@ static void ExecuteCommand(const Command& command, u32 thread_id) {
         break;
     }
 
-    // TODO: Figure out what exactly SET_COMMAND_LIST_FIRST and SET_COMMAND_LIST_LAST
-    //       are supposed to do.
-    case CommandId::SET_COMMAND_LIST_FIRST:
+    case CommandId::CACHE_FLUSH:
     {
+        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;
     }
 

+ 15 - 4
src/core/hle/service/gsp_gpu.h

@@ -31,7 +31,8 @@ enum class InterruptId : u8 {
 /// GSP command ID
 enum class CommandId : u32 {
     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
     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
     SET_TEXTURE_COPY       = 0x04,
-
-    SET_COMMAND_LIST_FIRST = 0x05,
+    /// Flushes up to 3 cache regions in a single command.
+    CACHE_FLUSH = 0x05,
 };
 
 /// GSP thread interrupt relay queue
@@ -106,7 +107,10 @@ struct Command {
         struct {
             u32 address;
             u32 size;
-        } set_command_list_last;
+            u32 flags;
+            u32 unused[3];
+            u32 do_flush;
+        } submit_gpu_cmdlist;
 
         struct {
             u32 start1;
@@ -138,6 +142,13 @@ struct Command {
             u32 flags;
         } texture_copy;
 
+        struct {
+            struct {
+                u32 address;
+                u32 size;
+            } regions[3];
+        } cache_flush;
+
         u8 raw_data[0x1C];
     };
 };