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]);
|
FIBER_ENTER(acb_task_name[vqid]);
|
||||||
auto& queue = asc_queues[{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());
|
auto base_addr = reinterpret_cast<VAddr>(acb.data());
|
||||||
|
size_t acb_size = acb.size_bytes();
|
||||||
while (!acb.empty()) {
|
while (!acb.empty()) {
|
||||||
ProcessCommands();
|
ProcessCommands();
|
||||||
|
|
||||||
@@ -919,8 +926,18 @@ Liverpool::Task Liverpool::ProcessCompute(std::span<const u32> acb, u32 vqid) {
|
|||||||
dma_data->src_sel == DmaDataSrc::MemoryUsingL2) &&
|
dma_data->src_sel == DmaDataSrc::MemoryUsingL2) &&
|
||||||
(dma_data->dst_sel == DmaDataDst::Memory ||
|
(dma_data->dst_sel == DmaDataDst::Memory ||
|
||||||
dma_data->dst_sel == DmaDataDst::MemoryUsingL2)) {
|
dma_data->dst_sel == DmaDataDst::MemoryUsingL2)) {
|
||||||
rasterizer->CopyBuffer(dma_data->DstAddress<VAddr>(), dma_data->SrcAddress<VAddr>(),
|
const u32 num_bytes = dma_data->NumBytes();
|
||||||
dma_data->NumBytes(), false, false);
|
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 {
|
} else {
|
||||||
UNREACHABLE_MSG("WriteData src_sel = {}, dst_sel = {}",
|
UNREACHABLE_MSG("WriteData src_sel = {}, dst_sel = {}",
|
||||||
u32(dma_data->src_sel.Value()), u32(dma_data->dst_sel.Value()));
|
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: {
|
case PM4ItOpcode::DispatchDirect: {
|
||||||
const auto* dispatch_direct = reinterpret_cast<const PM4CmdDispatchDirect*>(header);
|
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();
|
auto& cs_program = GetCsRegs();
|
||||||
cs_program.dim_x = dispatch_direct->dim_x;
|
cs_program.dim_x = dispatch_direct->dim_x;
|
||||||
cs_program.dim_y = dispatch_direct->dim_y;
|
cs_program.dim_y = dispatch_direct->dim_y;
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ union PM4Type3Header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
u32 NumWords() const {
|
u32 NumWords() const {
|
||||||
return count + 1;
|
return (count + 1) & 0x3fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 raw;
|
u32 raw;
|
||||||
|
|||||||
Reference in New Issue
Block a user