mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-01-31 00:55:19 +01:00
video_core: Small readback optimization (#3941)
* pm4_cmds: Handle nop packet overflow * liverpool: Detect DispatchDirect patches and promote to DispatchIndirect * clang.. * log removed --------- Co-authored-by: georgemoralis <giorgosmrls@gmail.com>
This commit is contained in:
@@ -830,7 +830,14 @@ Liverpool::Task Liverpool::ProcessCompute(std::span<const u32> acb, u32 vqid) {
|
||||
FIBER_ENTER(acb_task_name[vqid]);
|
||||
auto& queue = asc_queues[{vqid}];
|
||||
|
||||
struct IndirectPatch {
|
||||
const PM4Header* header;
|
||||
VAddr indirect_addr;
|
||||
};
|
||||
boost::container::small_vector<IndirectPatch, 4> indirect_patches;
|
||||
|
||||
auto base_addr = reinterpret_cast<VAddr>(acb.data());
|
||||
size_t acb_size = acb.size_bytes();
|
||||
while (!acb.empty()) {
|
||||
ProcessCommands();
|
||||
|
||||
@@ -919,8 +926,18 @@ Liverpool::Task Liverpool::ProcessCompute(std::span<const u32> acb, u32 vqid) {
|
||||
dma_data->src_sel == DmaDataSrc::MemoryUsingL2) &&
|
||||
(dma_data->dst_sel == DmaDataDst::Memory ||
|
||||
dma_data->dst_sel == DmaDataDst::MemoryUsingL2)) {
|
||||
rasterizer->CopyBuffer(dma_data->DstAddress<VAddr>(), dma_data->SrcAddress<VAddr>(),
|
||||
dma_data->NumBytes(), false, false);
|
||||
const u32 num_bytes = dma_data->NumBytes();
|
||||
const VAddr src_addr = dma_data->SrcAddress<VAddr>();
|
||||
const VAddr dst_addr = dma_data->DstAddress<VAddr>();
|
||||
const PM4Header* header =
|
||||
reinterpret_cast<const PM4Header*>(dst_addr - sizeof(PM4Header));
|
||||
if (dst_addr >= base_addr && dst_addr < base_addr + acb_size &&
|
||||
num_bytes == sizeof(PM4CmdDispatchIndirect::GroupDimensions) &&
|
||||
header->type == 3 && header->type3.opcode == PM4ItOpcode::DispatchDirect) {
|
||||
indirect_patches.emplace_back(header, src_addr);
|
||||
} else {
|
||||
rasterizer->CopyBuffer(dst_addr, src_addr, num_bytes, false, false);
|
||||
}
|
||||
} else {
|
||||
UNREACHABLE_MSG("WriteData src_sel = {}, dst_sel = {}",
|
||||
u32(dma_data->src_sel.Value()), u32(dma_data->dst_sel.Value()));
|
||||
@@ -964,6 +981,12 @@ Liverpool::Task Liverpool::ProcessCompute(std::span<const u32> acb, u32 vqid) {
|
||||
}
|
||||
case PM4ItOpcode::DispatchDirect: {
|
||||
const auto* dispatch_direct = reinterpret_cast<const PM4CmdDispatchDirect*>(header);
|
||||
if (auto it = std::ranges::find(indirect_patches, header, &IndirectPatch::header);
|
||||
it != indirect_patches.end()) {
|
||||
const auto size = sizeof(PM4CmdDispatchIndirect::GroupDimensions);
|
||||
rasterizer->DispatchIndirect(it->indirect_addr, 0, size);
|
||||
break;
|
||||
}
|
||||
auto& cs_program = GetCsRegs();
|
||||
cs_program.dim_x = dispatch_direct->dim_x;
|
||||
cs_program.dim_y = dispatch_direct->dim_y;
|
||||
|
||||
@@ -50,7 +50,7 @@ union PM4Type3Header {
|
||||
}
|
||||
|
||||
u32 NumWords() const {
|
||||
return count + 1;
|
||||
return (count + 1) & 0x3fff;
|
||||
}
|
||||
|
||||
u32 raw;
|
||||
|
||||
Reference in New Issue
Block a user