Handle PM4 type-2 packets (#556)
* video_core: handle PM4 type-2 packets * video_core: rewrite pm4 comand type handling into a switch statement
This commit is contained in:
parent
e4254ebdaa
commit
c37679154e
|
@ -175,11 +175,17 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
||||||
while (!dcb.empty()) {
|
while (!dcb.empty()) {
|
||||||
const auto* header = reinterpret_cast<const PM4Header*>(dcb.data());
|
const auto* header = reinterpret_cast<const PM4Header*>(dcb.data());
|
||||||
const u32 type = header->type;
|
const u32 type = header->type;
|
||||||
if (type != 3) {
|
|
||||||
// No other types of packets were spotted so far
|
|
||||||
UNREACHABLE_MSG("Invalid PM4 type {}", type);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
UNREACHABLE_MSG("Unsupported PM4 type {}", type);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
// Type-2 packet are used for padding purposes
|
||||||
|
dcb = dcb.subspan(1);
|
||||||
|
continue;
|
||||||
|
case 3:
|
||||||
const u32 count = header->type3.NumWords();
|
const u32 count = header->type3.NumWords();
|
||||||
const PM4ItOpcode opcode = header->type3.opcode;
|
const PM4ItOpcode opcode = header->type3.opcode;
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
|
@ -235,10 +241,10 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
||||||
|
|
||||||
// In the case of HW, render target memory has alignment as color block operates on
|
// In the case of HW, render target memory has alignment as color block operates on
|
||||||
// tiles. There is no information of actual resource extents stored in CB context
|
// tiles. There is no information of actual resource extents stored in CB context
|
||||||
// regs, so any deduction of it from slices/pitch will lead to a larger surface created.
|
// regs, so any deduction of it from slices/pitch will lead to a larger surface
|
||||||
// The same applies to the depth targets. Fortunately, the guest always sends
|
// created. The same applies to the depth targets. Fortunately, the guest always
|
||||||
// a trailing NOP packet right after the context regs setup, so we can use the heuristic
|
// sends a trailing NOP packet right after the context regs setup, so we can use the
|
||||||
// below and extract the hint to determine actual resource dims.
|
// heuristic below and extract the hint to determine actual resource dims.
|
||||||
|
|
||||||
switch (reg_addr) {
|
switch (reg_addr) {
|
||||||
case ContextRegs::CbColor0Base:
|
case ContextRegs::CbColor0Base:
|
||||||
|
@ -271,7 +277,8 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
||||||
case ContextRegs::CbColor5Cmask:
|
case ContextRegs::CbColor5Cmask:
|
||||||
case ContextRegs::CbColor6Cmask:
|
case ContextRegs::CbColor6Cmask:
|
||||||
case ContextRegs::CbColor7Cmask: {
|
case ContextRegs::CbColor7Cmask: {
|
||||||
const auto col_buf_id = (reg_addr - ContextRegs::CbColor0Cmask) /
|
const auto col_buf_id =
|
||||||
|
(reg_addr - ContextRegs::CbColor0Cmask) /
|
||||||
(ContextRegs::CbColor1Cmask - ContextRegs::CbColor0Cmask);
|
(ContextRegs::CbColor1Cmask - ContextRegs::CbColor0Cmask);
|
||||||
ASSERT(col_buf_id < NumColorBuffers);
|
ASSERT(col_buf_id < NumColorBuffers);
|
||||||
|
|
||||||
|
@ -306,8 +313,8 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
||||||
}
|
}
|
||||||
case PM4ItOpcode::SetUconfigReg: {
|
case PM4ItOpcode::SetUconfigReg: {
|
||||||
const auto* set_data = reinterpret_cast<const PM4CmdSetData*>(header);
|
const auto* set_data = reinterpret_cast<const PM4CmdSetData*>(header);
|
||||||
std::memcpy(®s.reg_array[UconfigRegWordOffset + set_data->reg_offset], header + 2,
|
std::memcpy(®s.reg_array[UconfigRegWordOffset + set_data->reg_offset],
|
||||||
(count - 1) * sizeof(u32));
|
header + 2, (count - 1) * sizeof(u32));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PM4ItOpcode::IndexType: {
|
case PM4ItOpcode::IndexType: {
|
||||||
|
@ -332,13 +339,15 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PM4ItOpcode::DrawIndexOffset2: {
|
case PM4ItOpcode::DrawIndexOffset2: {
|
||||||
const auto* draw_index_off = reinterpret_cast<const PM4CmdDrawIndexOffset2*>(header);
|
const auto* draw_index_off =
|
||||||
|
reinterpret_cast<const PM4CmdDrawIndexOffset2*>(header);
|
||||||
regs.max_index_size = draw_index_off->max_size;
|
regs.max_index_size = draw_index_off->max_size;
|
||||||
regs.num_indices = draw_index_off->index_count;
|
regs.num_indices = draw_index_off->index_count;
|
||||||
regs.draw_initiator = draw_index_off->draw_initiator;
|
regs.draw_initiator = draw_index_off->draw_initiator;
|
||||||
if (rasterizer) {
|
if (rasterizer) {
|
||||||
const auto cmd_address = reinterpret_cast<const void*>(header);
|
const auto cmd_address = reinterpret_cast<const void*>(header);
|
||||||
rasterizer->ScopeMarkerBegin(fmt::format("dcb:{}:DrawIndexOffset2", cmd_address));
|
rasterizer->ScopeMarkerBegin(
|
||||||
|
fmt::format("dcb:{}:DrawIndexOffset2", cmd_address));
|
||||||
rasterizer->Breadcrumb(u64(cmd_address));
|
rasterizer->Breadcrumb(u64(cmd_address));
|
||||||
rasterizer->Draw(true, draw_index_off->index_offset);
|
rasterizer->Draw(true, draw_index_off->index_offset);
|
||||||
rasterizer->ScopeMarkerEnd();
|
rasterizer->ScopeMarkerEnd();
|
||||||
|
@ -463,6 +472,8 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
||||||
static_cast<u32>(opcode), count);
|
static_cast<u32>(opcode), count);
|
||||||
}
|
}
|
||||||
dcb = dcb.subspan(header->type3.NumWords() + 1);
|
dcb = dcb.subspan(header->type3.NumWords() + 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ce_task.handle) {
|
if (ce_task.handle) {
|
||||||
|
|
Loading…
Reference in New Issue