diff options
| -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 | |||
| 30 | { | 30 | { |
| 31 | std::map<GSP_GPU::CommandId, const char*> command_names = { | 31 | std::map<GSP_GPU::CommandId, const char*> command_names = { |
| 32 | { GSP_GPU::CommandId::REQUEST_DMA, "REQUEST_DMA" }, | 32 | { GSP_GPU::CommandId::REQUEST_DMA, "REQUEST_DMA" }, |
| 33 | { GSP_GPU::CommandId::SET_COMMAND_LIST_FIRST, "SET_COMMAND_LIST_FIRST" }, | 33 | { GSP_GPU::CommandId::SUBMIT_GPU_CMDLIST, "SUBMIT_GPU_CMDLIST" }, |
| 34 | { GSP_GPU::CommandId::SET_MEMORY_FILL, "SET_MEMORY_FILL" }, | 34 | { GSP_GPU::CommandId::SET_MEMORY_FILL, "SET_MEMORY_FILL" }, |
| 35 | { GSP_GPU::CommandId::SET_DISPLAY_TRANSFER, "SET_DISPLAY_TRANSFER" }, | 35 | { GSP_GPU::CommandId::SET_DISPLAY_TRANSFER, "SET_DISPLAY_TRANSFER" }, |
| 36 | { GSP_GPU::CommandId::SET_TEXTURE_COPY, "SET_TEXTURE_COPY" }, | 36 | { GSP_GPU::CommandId::SET_TEXTURE_COPY, "SET_TEXTURE_COPY" }, |
| 37 | { GSP_GPU::CommandId::SET_COMMAND_LIST_LAST, "SET_COMMAND_LIST_LAST" } | 37 | { GSP_GPU::CommandId::CACHE_FLUSH, "CACHE_FLUSH" }, |
| 38 | }; | 38 | }; |
| 39 | const u32* command_data = reinterpret_cast<const u32*>(&command); | 39 | const u32* command_data = reinterpret_cast<const u32*>(&command); |
| 40 | QString str = QString("%1 %2 %3 %4 %5 %6 %7 %8 %9").arg(command_names[command.id]) | 40 | 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) { | |||
| 377 | command.dma_request.size); | 377 | command.dma_request.size); |
| 378 | break; | 378 | break; |
| 379 | 379 | ||
| 380 | // ctrulib homebrew sends all relevant command list data with this command, | 380 | // TODO: This will need some rework in the future. (why?) |
| 381 | // hence we do all "interesting" stuff here and do nothing in SET_COMMAND_LIST_FIRST. | 381 | case CommandId::SUBMIT_GPU_CMDLIST: |
| 382 | // TODO: This will need some rework in the future. | ||
| 383 | case CommandId::SET_COMMAND_LIST_LAST: | ||
| 384 | { | 382 | { |
| 385 | auto& params = command.set_command_list_last; | 383 | auto& params = command.submit_gpu_cmdlist; |
| 384 | |||
| 385 | if (params.do_flush) { | ||
| 386 | // This flag flushes the command list (params.address, params.size) from the cache. | ||
| 387 | // Command lists are not processed by the hardware renderer, so we don't need to | ||
| 388 | // actually flush them in Citra. | ||
| 389 | } | ||
| 386 | 390 | ||
| 387 | WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(command_processor_config.address)), | 391 | WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(command_processor_config.address)), |
| 388 | Memory::VirtualToPhysicalAddress(params.address) >> 3); | 392 | Memory::VirtualToPhysicalAddress(params.address) >> 3); |
| @@ -391,6 +395,8 @@ static void ExecuteCommand(const Command& command, u32 thread_id) { | |||
| 391 | // TODO: Not sure if we are supposed to always write this .. seems to trigger processing though | 395 | // TODO: Not sure if we are supposed to always write this .. seems to trigger processing though |
| 392 | WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(command_processor_config.trigger)), 1); | 396 | WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(command_processor_config.trigger)), 1); |
| 393 | 397 | ||
| 398 | // TODO(yuriks): Figure out the meaning of the `flags` field. | ||
| 399 | |||
| 394 | break; | 400 | break; |
| 395 | } | 401 | } |
| 396 | 402 | ||
| @@ -434,7 +440,6 @@ static void ExecuteCommand(const Command& command, u32 thread_id) { | |||
| 434 | break; | 440 | break; |
| 435 | } | 441 | } |
| 436 | 442 | ||
| 437 | // TODO: Check if texture copies are implemented correctly.. | ||
| 438 | case CommandId::SET_TEXTURE_COPY: | 443 | case CommandId::SET_TEXTURE_COPY: |
| 439 | { | 444 | { |
| 440 | auto& params = command.texture_copy; | 445 | auto& params = command.texture_copy; |
| @@ -456,10 +461,15 @@ static void ExecuteCommand(const Command& command, u32 thread_id) { | |||
| 456 | break; | 461 | break; |
| 457 | } | 462 | } |
| 458 | 463 | ||
| 459 | // TODO: Figure out what exactly SET_COMMAND_LIST_FIRST and SET_COMMAND_LIST_LAST | 464 | case CommandId::CACHE_FLUSH: |
| 460 | // are supposed to do. | ||
| 461 | case CommandId::SET_COMMAND_LIST_FIRST: | ||
| 462 | { | 465 | { |
| 466 | for (auto& region : command.cache_flush.regions) { | ||
| 467 | if (region.size == 0) | ||
| 468 | break; | ||
| 469 | |||
| 470 | VideoCore::g_renderer->hw_rasterizer->NotifyFlush( | ||
| 471 | Memory::VirtualToPhysicalAddress(region.address), region.size); | ||
| 472 | } | ||
| 463 | break; | 473 | break; |
| 464 | } | 474 | } |
| 465 | 475 | ||
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 { | |||
| 31 | /// GSP command ID | 31 | /// GSP command ID |
| 32 | enum class CommandId : u32 { | 32 | enum class CommandId : u32 { |
| 33 | REQUEST_DMA = 0x00, | 33 | REQUEST_DMA = 0x00, |
| 34 | SET_COMMAND_LIST_LAST = 0x01, | 34 | /// Submits a commandlist for execution by the GPU. |
| 35 | SUBMIT_GPU_CMDLIST = 0x01, | ||
| 35 | 36 | ||
| 36 | // Fills a given memory range with a particular value | 37 | // Fills a given memory range with a particular value |
| 37 | SET_MEMORY_FILL = 0x02, | 38 | SET_MEMORY_FILL = 0x02, |
| @@ -42,8 +43,8 @@ enum class CommandId : u32 { | |||
| 42 | 43 | ||
| 43 | // Conceptionally similar to SET_DISPLAY_TRANSFER and presumable uses the same hardware path | 44 | // Conceptionally similar to SET_DISPLAY_TRANSFER and presumable uses the same hardware path |
| 44 | SET_TEXTURE_COPY = 0x04, | 45 | SET_TEXTURE_COPY = 0x04, |
| 45 | 46 | /// Flushes up to 3 cache regions in a single command. | |
| 46 | SET_COMMAND_LIST_FIRST = 0x05, | 47 | CACHE_FLUSH = 0x05, |
| 47 | }; | 48 | }; |
| 48 | 49 | ||
| 49 | /// GSP thread interrupt relay queue | 50 | /// GSP thread interrupt relay queue |
| @@ -106,7 +107,10 @@ struct Command { | |||
| 106 | struct { | 107 | struct { |
| 107 | u32 address; | 108 | u32 address; |
| 108 | u32 size; | 109 | u32 size; |
| 109 | } set_command_list_last; | 110 | u32 flags; |
| 111 | u32 unused[3]; | ||
| 112 | u32 do_flush; | ||
| 113 | } submit_gpu_cmdlist; | ||
| 110 | 114 | ||
| 111 | struct { | 115 | struct { |
| 112 | u32 start1; | 116 | u32 start1; |
| @@ -138,6 +142,13 @@ struct Command { | |||
| 138 | u32 flags; | 142 | u32 flags; |
| 139 | } texture_copy; | 143 | } texture_copy; |
| 140 | 144 | ||
| 145 | struct { | ||
| 146 | struct { | ||
| 147 | u32 address; | ||
| 148 | u32 size; | ||
| 149 | } regions[3]; | ||
| 150 | } cache_flush; | ||
| 151 | |||
| 141 | u8 raw_data[0x1C]; | 152 | u8 raw_data[0x1C]; |
| 142 | }; | 153 | }; |
| 143 | }; | 154 | }; |