diff --git a/src/graphics/guest_gpu/command_processor/pm4Handlers.cpp b/src/graphics/guest_gpu/command_processor/pm4Handlers.cpp index 5e4beadf7..3e3d15217 100644 --- a/src/graphics/guest_gpu/command_processor/pm4Handlers.cpp +++ b/src/graphics/guest_gpu/command_processor/pm4Handlers.cpp @@ -1917,17 +1917,23 @@ KYTY_CP_OP_PARSER(CpOpCopyData) { EXIT_NOT_IMPLEMENTED(cmd_id != KYTY_PM4(6, Pm4::IT_COPY_DATA, 0u)); - const uint32_t control = buffer[0]; - const uint32_t src_sel = ((control & 0xfu) << 1u) | ((control >> 30u) & 0x1u); - const uint32_t dst_sel = ((control >> 8u) & 0xfu) << 1u; - const uint8_t src_cache = static_cast((control >> 13u) & 0x3u); - const uint8_t dst_cache = static_cast((control >> 25u) & 0x3u); - const uint8_t write_confirm = static_cast((control >> 20u) & 0x1u); - const uint32_t num_bytes = ((control >> 16u) & 0x1u) != 0 ? 8u : 4u; - const uint64_t src = buffer[1] | (static_cast(buffer[2]) << 32u); - const uint64_t dst = buffer[3] | (static_cast(buffer[4]) << 32u); - if (src_sel == (9u << 1u)) { - if (dst_sel != (2u << 1u) || dst == 0 || (dst & (num_bytes - 1u)) != 0) { + const uint32_t control = buffer[0]; + const uint32_t src_sel = ((control & 0xfu) << 1u) | ((control >> 30u) & 0x1u); + const uint32_t dst_sel = ((control >> 8u) & 0xfu) << 1u; + const uint8_t src_cache = static_cast((control >> 13u) & 0x3u); + const uint8_t dst_cache = static_cast((control >> 25u) & 0x3u); + const uint8_t write_confirm = static_cast((control >> 20u) & 0x1u); + const uint32_t num_bytes = ((control >> 16u) & 0x1u) != 0 ? 8u : 4u; + const uint64_t src = buffer[1] | (static_cast(buffer[2]) << 32u); + const uint64_t dst = buffer[3] | (static_cast(buffer[4]) << 32u); + uint32_t reference_clock_dst = 0; + switch (src_sel) { + case 9u: reference_clock_dst = 2u; break; + case 18u: reference_clock_dst = 4u; break; + default: break; + } + if (reference_clock_dst != 0) { + if (dst_sel != reference_clock_dst || dst == 0 || (dst & (num_bytes - 1u)) != 0) { EXIT("unsupported reference-clock copyData, src_sel=0x%02" PRIx32 " dst_sel=0x%02" PRIx32 " dst=0x%016" PRIx64 " size=%u\n", src_sel, dst_sel, dst, num_bytes); diff --git a/src/graphics/guest_gpu/graphicsRun.cpp b/src/graphics/guest_gpu/graphicsRun.cpp index 648f932e5..8b367e232 100644 --- a/src/graphics/guest_gpu/graphicsRun.cpp +++ b/src/graphics/guest_gpu/graphicsRun.cpp @@ -407,11 +407,16 @@ void CommandProcessor::WriteData(uint32_t* dst, const uint32_t* src, uint32_t dw uint32_t write_control) { const uint32_t dst_sel = ((write_control >> 30u) & 0x1u) | ((write_control >> 7u) & 0x1eu); const uint32_t cache_policy = (write_control >> 25u) & 0x3u; - const uint32_t increment = (write_control >> 16u) & 0x1u; + const uint32_t increment = (write_control >> 16u) & 0x1u; const uint32_t write_confirm = (write_control >> 20u) & 0x1u; - if (dst_sel != 0 && dst_sel != 2 && dst_sel != 4 && dst_sel != 5) { - EXIT("unsupported writeData destination selector 0x%02" PRIx32 "\n", dst_sel); + switch (dst_sel) { + case 0: + case 2: + case 4: + case 5: + case 6: break; + default: EXIT("unsupported writeData destination selector 0x%02" PRIx32 "\n", dst_sel); } EXIT_NOT_IMPLEMENTED(increment != 0);