diff options
| author | Yuri Kunde Schlesner <yuriks@yuriks.net> | 2015-09-14 17:00:45 -0300 | 
|---|---|---|
| committer | Yuri Kunde Schlesner <yuriks@yuriks.net> | 2015-09-14 17:00:45 -0300 | 
| commit | b3af7aad9e37ee49feb9ff4e34ed4314f7ed644b (patch) | |
| tree | ac792d257440cf78d0c0bdf2e515da5fc4943bff | |
| parent | d6e56b8c88b46f4f85f44b26bff00422e31a6e57 (diff) | |
| parent | 1ed7f3e0281de29fd99f7d4802fcc5a1906930f8 (diff) | |
Merge pull request #1123 from yuriks/gsp-flush
GSP: Implement command 0x05, used for flushing caches
| -rw-r--r-- | src/citra_qt/debugger/graphics.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/service/gsp_gpu.cpp | 28 | ||||
| -rw-r--r-- | src/core/hle/service/gsp_gpu.h | 19 | 
3 files changed, 36 insertions, 15 deletions
| diff --git a/src/citra_qt/debugger/graphics.cpp b/src/citra_qt/debugger/graphics.cpp index 8008f914c..eccd619ba 100644 --- a/src/citra_qt/debugger/graphics.cpp +++ b/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]) diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp index c3d0d28a5..481da0c9f 100644 --- a/src/core/hle/service/gsp_gpu.cpp +++ b/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;      } diff --git a/src/core/hle/service/gsp_gpu.h b/src/core/hle/service/gsp_gpu.h index 8bcb30ad1..0e2f7a21e 100644 --- a/src/core/hle/service/gsp_gpu.h +++ b/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];      };  }; | 
