implement missing packet_disassembler code
This commit is contained in:
parent
43fd396db7
commit
ba7397952d
|
@ -57,6 +57,7 @@ bool PacketDisassembler::DisasmPacketType0(const uint8_t* base_ptr,
|
|||
|
||||
uint32_t base_index = (packet & 0x7FFF);
|
||||
uint32_t write_one_reg = (packet >> 15) & 0x1;
|
||||
out_info->actions.reserve(count);
|
||||
for (uint32_t m = 0; m < count; m++) {
|
||||
uint32_t reg_data = xe::load_and_swap<uint32_t>(ptr);
|
||||
uint32_t target_index = write_one_reg ? base_index : base_index + m;
|
||||
|
@ -77,7 +78,7 @@ bool PacketDisassembler::DisasmPacketType1(const uint8_t* base_ptr,
|
|||
|
||||
out_info->count = 1 + 2;
|
||||
auto ptr = base_ptr + 4;
|
||||
|
||||
out_info->actions.reserve(2);
|
||||
uint32_t reg_index_1 = packet & 0x7FF;
|
||||
uint32_t reg_index_2 = (packet >> 11) & 0x7FF;
|
||||
uint32_t reg_data_1 = xe::load_and_swap<uint32_t>(ptr);
|
||||
|
@ -118,12 +119,19 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
|
|||
out_info->predicated = true;
|
||||
}
|
||||
|
||||
using Type = PacketAction::Type;
|
||||
bool result = true;
|
||||
|
||||
auto& out_actions = out_info->actions;
|
||||
out_actions.reserve(1);
|
||||
switch (opcode) {
|
||||
case PM4_ME_INIT: {
|
||||
// initialize CP's micro-engine
|
||||
static const PacketTypeInfo op_info = {PacketCategory::kGeneric,
|
||||
"PM4_ME_INIT"};
|
||||
|
||||
out_actions.emplace_back(PacketAction::MeInit((uint32_t*)ptr, count));
|
||||
|
||||
out_info->type_info = &op_info;
|
||||
break;
|
||||
}
|
||||
|
@ -140,12 +148,11 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
|
|||
static const PacketTypeInfo op_info = {PacketCategory::kGeneric,
|
||||
"PM4_INTERRUPT"};
|
||||
out_info->type_info = &op_info;
|
||||
uint32_t cpu_mask = xe::load_and_swap<uint32_t>(ptr + 0);
|
||||
for (int n = 0; n < 6; n++) {
|
||||
if (cpu_mask & (1 << n)) {
|
||||
// graphics_system_->DispatchInterruptCallback(1, n);
|
||||
}
|
||||
}
|
||||
|
||||
PacketAction intaction;
|
||||
intaction.type = Type::kGenInterrupt;
|
||||
intaction.gen_interrupt.cpu_mask = xe::load_and_swap<uint32_t>(ptr + 0);
|
||||
out_actions.emplace_back(std::move(intaction));
|
||||
break;
|
||||
}
|
||||
case PM4_XE_SWAP: {
|
||||
|
@ -156,7 +163,13 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
|
|||
static const PacketTypeInfo op_info = {PacketCategory::kSwap,
|
||||
"PM4_XE_SWAP"};
|
||||
out_info->type_info = &op_info;
|
||||
uint32_t frontbuffer_ptr = xe::load_and_swap<uint32_t>(ptr + 0);
|
||||
|
||||
PacketAction xsa;
|
||||
xsa.type = Type::kXeSwap;
|
||||
xsa.xe_swap.frontbuffer_ptr = xe::load_and_swap<uint32_t>(ptr + 0);
|
||||
|
||||
out_actions.emplace_back(std::move(xsa));
|
||||
|
||||
break;
|
||||
}
|
||||
case PM4_INDIRECT_BUFFER:
|
||||
|
@ -165,8 +178,13 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
|
|||
static const PacketTypeInfo op_info = {PacketCategory::kGeneric,
|
||||
"PM4_INDIRECT_BUFFER"};
|
||||
out_info->type_info = &op_info;
|
||||
uint32_t list_ptr = xe::load_and_swap<uint32_t>(ptr + 0);
|
||||
uint32_t list_length = xe::load_and_swap<uint32_t>(ptr + 4);
|
||||
|
||||
PacketAction iba;
|
||||
iba.type = Type::kIndirBuffer;
|
||||
iba.indir_buffer.list_ptr = xe::load_and_swap<uint32_t>(ptr);
|
||||
iba.indir_buffer.list_length = xe::load_and_swap<uint32_t>(ptr + 4);
|
||||
out_actions.emplace_back(std::move(iba));
|
||||
|
||||
break;
|
||||
}
|
||||
case PM4_WAIT_REG_MEM: {
|
||||
|
@ -174,11 +192,18 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
|
|||
static const PacketTypeInfo op_info = {PacketCategory::kGeneric,
|
||||
"PM4_WAIT_REG_MEM"};
|
||||
out_info->type_info = &op_info;
|
||||
uint32_t wait_info = xe::load_and_swap<uint32_t>(ptr + 0);
|
||||
uint32_t poll_reg_addr = xe::load_and_swap<uint32_t>(ptr + 4);
|
||||
uint32_t ref = xe::load_and_swap<uint32_t>(ptr + 8);
|
||||
uint32_t mask = xe::load_and_swap<uint32_t>(ptr + 12);
|
||||
uint32_t wait = xe::load_and_swap<uint32_t>(ptr + 16);
|
||||
|
||||
PacketAction wait_action;
|
||||
wait_action.type = PacketAction::Type::kWaitRegMem;
|
||||
auto& wrm = wait_action.wait_reg_mem;
|
||||
wrm.wait_info = xe::load_and_swap<uint32_t>(ptr + 0);
|
||||
wrm.poll_reg_addr = xe::load_and_swap<uint32_t>(ptr + 4);
|
||||
wrm.ref = xe::load_and_swap<uint32_t>(ptr + 8);
|
||||
wrm.mask = xe::load_and_swap<uint32_t>(ptr + 12);
|
||||
wrm.wait = xe::load_and_swap<uint32_t>(ptr + 16);
|
||||
|
||||
out_actions.emplace_back(std::move(wait_action));
|
||||
|
||||
break;
|
||||
}
|
||||
case PM4_REG_RMW: {
|
||||
|
@ -187,9 +212,17 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
|
|||
static const PacketTypeInfo op_info = {PacketCategory::kGeneric,
|
||||
"PM4_REG_RMW"};
|
||||
out_info->type_info = &op_info;
|
||||
PacketAction rmw_action;
|
||||
rmw_action.type = PacketAction::Type::kRegRmw;
|
||||
auto& rmw = rmw_action.reg_rmw;
|
||||
|
||||
uint32_t rmw_info = xe::load_and_swap<uint32_t>(ptr + 0);
|
||||
uint32_t and_mask = xe::load_and_swap<uint32_t>(ptr + 4);
|
||||
uint32_t or_mask = xe::load_and_swap<uint32_t>(ptr + 8);
|
||||
|
||||
rmw.rmw_info = rmw_info;
|
||||
|
||||
rmw.and_mask = xe::load_and_swap<uint32_t>(ptr + 4);
|
||||
rmw.or_mask = xe::load_and_swap<uint32_t>(ptr + 8);
|
||||
out_actions.emplace_back(std::move(rmw_action));
|
||||
break;
|
||||
}
|
||||
case PM4_COND_WRITE: {
|
||||
|
@ -197,12 +230,19 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
|
|||
static const PacketTypeInfo op_info = {PacketCategory::kGeneric,
|
||||
"PM4_COND_WRITE"};
|
||||
out_info->type_info = &op_info;
|
||||
uint32_t wait_info = xe::load_and_swap<uint32_t>(ptr + 0);
|
||||
uint32_t poll_reg_addr = xe::load_and_swap<uint32_t>(ptr + 4);
|
||||
uint32_t ref = xe::load_and_swap<uint32_t>(ptr + 8);
|
||||
uint32_t mask = xe::load_and_swap<uint32_t>(ptr + 12);
|
||||
uint32_t write_reg_addr = xe::load_and_swap<uint32_t>(ptr + 16);
|
||||
uint32_t write_data = xe::load_and_swap<uint32_t>(ptr + 20);
|
||||
PacketAction cwr_action;
|
||||
cwr_action.type = PacketAction::Type::kCondWrite;
|
||||
|
||||
auto& cwr = cwr_action.cond_write;
|
||||
|
||||
cwr.wait_info = xe::load_and_swap<uint32_t>(ptr + 0);
|
||||
cwr.poll_reg_addr = xe::load_and_swap<uint32_t>(ptr + 4);
|
||||
cwr.ref = xe::load_and_swap<uint32_t>(ptr + 8);
|
||||
cwr.mask = xe::load_and_swap<uint32_t>(ptr + 12);
|
||||
cwr.write_reg_addr = xe::load_and_swap<uint32_t>(ptr + 16);
|
||||
cwr.write_data = xe::load_and_swap<uint32_t>(ptr + 20);
|
||||
|
||||
out_actions.emplace_back(std::move(cwr_action));
|
||||
break;
|
||||
}
|
||||
case PM4_EVENT_WRITE: {
|
||||
|
@ -210,7 +250,12 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
|
|||
static const PacketTypeInfo op_info = {PacketCategory::kGeneric,
|
||||
"PM4_EVENT_WRITE"};
|
||||
out_info->type_info = &op_info;
|
||||
uint32_t initiator = xe::load_and_swap<uint32_t>(ptr + 0);
|
||||
PacketAction evw_action;
|
||||
evw_action.type = Type::kEventWrite;
|
||||
evw_action.event_write.initiator = xe::load_and_swap<uint32_t>(ptr + 0);
|
||||
|
||||
out_actions.emplace_back(std::move(evw_action));
|
||||
|
||||
break;
|
||||
}
|
||||
case PM4_EVENT_WRITE_SHD: {
|
||||
|
@ -218,9 +263,15 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
|
|||
static const PacketTypeInfo op_info = {PacketCategory::kGeneric,
|
||||
"PM4_EVENT_WRITE_SHD"};
|
||||
out_info->type_info = &op_info;
|
||||
uint32_t initiator = xe::load_and_swap<uint32_t>(ptr + 0);
|
||||
uint32_t address = xe::load_and_swap<uint32_t>(ptr + 4);
|
||||
uint32_t value = xe::load_and_swap<uint32_t>(ptr + 8);
|
||||
PacketAction evws_action;
|
||||
evws_action.type = Type::kEventWriteSHD;
|
||||
auto& evws = evws_action.event_write_shd;
|
||||
|
||||
evws.initiator = xe::load_and_swap<uint32_t>(ptr + 0);
|
||||
evws.address = xe::load_and_swap<uint32_t>(ptr + 4);
|
||||
evws.value = xe::load_and_swap<uint32_t>(ptr + 8);
|
||||
|
||||
out_actions.emplace_back(std::move(evws_action));
|
||||
break;
|
||||
}
|
||||
case PM4_EVENT_WRITE_EXT: {
|
||||
|
@ -228,8 +279,17 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
|
|||
static const PacketTypeInfo op_info = {PacketCategory::kGeneric,
|
||||
"PM4_EVENT_WRITE_EXT"};
|
||||
out_info->type_info = &op_info;
|
||||
|
||||
PacketAction eve_action;
|
||||
eve_action.type = Type::kEventWriteExt;
|
||||
auto& eve = eve_action.event_write_ext;
|
||||
uint32_t unk0 = xe::load_and_swap<uint32_t>(ptr + 0);
|
||||
uint32_t unk1 = xe::load_and_swap<uint32_t>(ptr + 4);
|
||||
|
||||
eve.unk0 = unk0;
|
||||
eve.unk1 = unk1;
|
||||
out_actions.emplace_back(std::move(eve_action));
|
||||
|
||||
break;
|
||||
}
|
||||
case PM4_DRAW_INDX: {
|
||||
|
@ -243,6 +303,16 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
|
|||
uint32_t index_count = dword1 >> 16;
|
||||
auto prim_type = static_cast<xenos::PrimitiveType>(dword1 & 0x3F);
|
||||
uint32_t src_sel = (dword1 >> 6) & 0x3;
|
||||
|
||||
PacketAction di_action;
|
||||
di_action.type = Type::kDrawIndx;
|
||||
|
||||
auto& di = di_action.draw_indx;
|
||||
di.dword0 = dword0;
|
||||
di.dword1 = dword1;
|
||||
di.index_count = index_count;
|
||||
di.prim_type = prim_type;
|
||||
di.src_sel = src_sel;
|
||||
if (src_sel == 0x0) {
|
||||
// Indexed draw.
|
||||
uint32_t guest_base = xe::load_and_swap<uint32_t>(ptr + 8);
|
||||
|
@ -251,12 +321,18 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
|
|||
index_size &= 0x00FFFFFF;
|
||||
bool index_32bit = (dword1 >> 11) & 0x1;
|
||||
index_size *= index_32bit ? 4 : 2;
|
||||
di.index_size = index_size;
|
||||
di.guest_base = guest_base;
|
||||
di.endianness = endianness;
|
||||
|
||||
} else if (src_sel == 0x2) {
|
||||
// Auto draw.
|
||||
} else {
|
||||
// Unknown source select.
|
||||
assert_always();
|
||||
}
|
||||
out_actions.emplace_back(std::move(di_action));
|
||||
|
||||
break;
|
||||
}
|
||||
case PM4_DRAW_INDX_2: {
|
||||
|
@ -272,6 +348,24 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
|
|||
bool index_32bit = (dword0 >> 11) & 0x1;
|
||||
uint32_t indices_size = index_count * (index_32bit ? 4 : 2);
|
||||
auto index_ptr = ptr + 4;
|
||||
|
||||
PacketAction di2_action;
|
||||
di2_action.type = Type::kDrawIndx2;
|
||||
di2_action.words.reserve(index_count);
|
||||
auto& di2 = di2_action.draw_indx2;
|
||||
|
||||
di2.dword0 = dword0;
|
||||
di2.index_count = index_count;
|
||||
di2.indices_size = indices_size;
|
||||
di2.prim_type = prim_type;
|
||||
di2.src_sel = src_sel;
|
||||
|
||||
if (index_32bit) {
|
||||
di2_action.InjectBeWords((uint32_t*)index_ptr, index_count);
|
||||
} else {
|
||||
di2_action.InjectBeHalfwordsAsWords((uint16_t*)index_ptr, index_count);
|
||||
}
|
||||
out_actions.emplace_back(std::move(di2_action));
|
||||
break;
|
||||
}
|
||||
case PM4_SET_CONSTANT: {
|
||||
|
@ -305,10 +399,10 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
|
|||
result = false;
|
||||
break;
|
||||
}
|
||||
out_actions.reserve(count - 1);
|
||||
for (uint32_t n = 0; n < count - 1; n++, index++) {
|
||||
uint32_t data = xe::load_and_swap<uint32_t>(ptr + 4 + n * 4);
|
||||
out_info->actions.emplace_back(
|
||||
PacketAction::RegisterWrite(index, data));
|
||||
out_actions.emplace_back(PacketAction::RegisterWrite(index, data));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -318,10 +412,12 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
|
|||
out_info->type_info = &op_info;
|
||||
uint32_t offset_type = xe::load_and_swap<uint32_t>(ptr + 0);
|
||||
uint32_t index = offset_type & 0xFFFF;
|
||||
|
||||
out_actions.reserve(count - 1);
|
||||
|
||||
for (uint32_t n = 0; n < count - 1; n++, index++) {
|
||||
uint32_t data = xe::load_and_swap<uint32_t>(ptr + 4 + n * 4);
|
||||
out_info->actions.emplace_back(
|
||||
PacketAction::RegisterWrite(index, data));
|
||||
out_actions.emplace_back(PacketAction::RegisterWrite(index, data));
|
||||
}
|
||||
return true;
|
||||
break;
|
||||
|
@ -358,12 +454,13 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
|
|||
assert_always();
|
||||
return true;
|
||||
}
|
||||
out_actions.reserve(size_dwords);
|
||||
|
||||
for (uint32_t n = 0; n < size_dwords; n++, index++) {
|
||||
// Hrm, ?
|
||||
// xe::load_and_swap<uint32_t>(membase_ + GpuToCpu(address + n * 4));
|
||||
uint32_t data = 0xDEADBEEF;
|
||||
out_info->actions.emplace_back(
|
||||
PacketAction::RegisterWrite(index, data));
|
||||
out_actions.emplace_back(PacketAction::RegisterWrite(index, data));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -373,10 +470,12 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
|
|||
out_info->type_info = &op_info;
|
||||
uint32_t offset_type = xe::load_and_swap<uint32_t>(ptr + 0);
|
||||
uint32_t index = offset_type & 0xFFFF;
|
||||
|
||||
out_actions.reserve(count - 1);
|
||||
|
||||
for (uint32_t n = 0; n < count - 1; n++, index++) {
|
||||
uint32_t data = xe::load_and_swap<uint32_t>(ptr + 4 + n * 4);
|
||||
out_info->actions.emplace_back(
|
||||
PacketAction::RegisterWrite(index, data));
|
||||
out_actions.emplace_back(PacketAction::RegisterWrite(index, data));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -391,6 +490,17 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
|
|||
uint32_t start_size = xe::load_and_swap<uint32_t>(ptr + 4);
|
||||
uint32_t start = start_size >> 16;
|
||||
uint32_t size_dwords = start_size & 0xFFFF; // dwords
|
||||
|
||||
PacketAction iml_action;
|
||||
iml_action.type = Type::kImLoad;
|
||||
auto& iml = iml_action.im_load;
|
||||
iml.addr = addr;
|
||||
iml.shader_type = shader_type;
|
||||
iml.size_dwords = size_dwords;
|
||||
iml.start = start;
|
||||
|
||||
out_actions.emplace_back(std::move(iml_action));
|
||||
|
||||
assert_true(start == 0);
|
||||
break;
|
||||
}
|
||||
|
@ -405,6 +515,20 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
|
|||
uint32_t start_size = dword1;
|
||||
uint32_t start = start_size >> 16;
|
||||
uint32_t size_dwords = start_size & 0xFFFF; // dwords
|
||||
|
||||
PacketAction imi_action;
|
||||
imi_action.type = Type::kImLoadImmediate;
|
||||
imi_action.words.reserve(size_dwords);
|
||||
auto& imi = imi_action.im_load_imm;
|
||||
imi.shader_type = shader_type;
|
||||
imi.size_dwords = size_dwords;
|
||||
imi.start = start;
|
||||
|
||||
imi_action.InjectBeWords(reinterpret_cast<const uint32_t*>(ptr + 8),
|
||||
size_dwords);
|
||||
|
||||
out_actions.emplace_back(std::move(imi_action));
|
||||
|
||||
assert_true(start == 0);
|
||||
break;
|
||||
}
|
||||
|
@ -414,6 +538,12 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
|
|||
"PM4_INVALIDATE_STATE"};
|
||||
out_info->type_info = &op_info;
|
||||
uint32_t mask = xe::load_and_swap<uint32_t>(ptr + 0);
|
||||
|
||||
PacketAction inv_action;
|
||||
inv_action.type = Type::kInvalidateState;
|
||||
inv_action.invalidate_state.state_mask = mask;
|
||||
|
||||
out_actions.emplace_back(std::move(inv_action));
|
||||
break;
|
||||
}
|
||||
case PM4_SET_BIN_MASK_LO: {
|
||||
|
@ -422,7 +552,12 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
|
|||
out_info->type_info = &op_info;
|
||||
uint32_t value = xe::load_and_swap<uint32_t>(ptr);
|
||||
// bin_mask_ = (bin_mask_ & 0xFFFFFFFF00000000ull) | value;
|
||||
out_info->actions.emplace_back(PacketAction::SetBinMask(value));
|
||||
|
||||
PacketAction action;
|
||||
action.type = Type::kSetBinMaskLo;
|
||||
action.lohi_op.value = value;
|
||||
out_actions.emplace_back(std::move(action));
|
||||
|
||||
break;
|
||||
}
|
||||
case PM4_SET_BIN_MASK_HI: {
|
||||
|
@ -430,8 +565,11 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
|
|||
"PM4_SET_BIN_MASK_HI"};
|
||||
out_info->type_info = &op_info;
|
||||
uint32_t value = xe::load_and_swap<uint32_t>(ptr);
|
||||
// bin_mask_ =
|
||||
// (bin_mask_ & 0xFFFFFFFFull) | (static_cast<uint64_t>(value) << 32);
|
||||
|
||||
PacketAction action;
|
||||
action.type = Type::kSetBinMaskHi;
|
||||
action.lohi_op.value = value;
|
||||
out_actions.emplace_back(std::move(action));
|
||||
break;
|
||||
}
|
||||
case PM4_SET_BIN_SELECT_LO: {
|
||||
|
@ -439,8 +577,11 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
|
|||
"PM4_SET_BIN_SELECT_LO"};
|
||||
out_info->type_info = &op_info;
|
||||
uint32_t value = xe::load_and_swap<uint32_t>(ptr);
|
||||
// bin_select_ = (bin_select_ & 0xFFFFFFFF00000000ull) | value;
|
||||
out_info->actions.emplace_back(PacketAction::SetBinSelect(value));
|
||||
PacketAction action;
|
||||
action.type = Type::kSetBinSelectLo;
|
||||
action.lohi_op.value = value;
|
||||
out_actions.emplace_back(std::move(action));
|
||||
|
||||
break;
|
||||
}
|
||||
case PM4_SET_BIN_SELECT_HI: {
|
||||
|
@ -448,9 +589,82 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
|
|||
"PM4_SET_BIN_SELECT_HI"};
|
||||
out_info->type_info = &op_info;
|
||||
uint32_t value = xe::load_and_swap<uint32_t>(ptr);
|
||||
// bin_select_ =
|
||||
// (bin_select_ & 0xFFFFFFFFull) | (static_cast<uint64_t>(value) <<
|
||||
// 32);
|
||||
|
||||
PacketAction action;
|
||||
action.type = Type::kSetBinSelectHi;
|
||||
action.lohi_op.value = value;
|
||||
out_actions.emplace_back(std::move(action));
|
||||
break;
|
||||
}
|
||||
case PM4_CONTEXT_UPDATE: {
|
||||
uint32_t value = xe::load_and_swap<uint32_t>(ptr);
|
||||
PacketAction ctxu;
|
||||
ctxu.type = Type::kContextUpdate;
|
||||
ctxu.context_update.maybe_unused = value;
|
||||
out_actions.emplace_back(std::move(ctxu));
|
||||
break;
|
||||
}
|
||||
case PM4_WAIT_FOR_IDLE: {
|
||||
uint32_t value = xe::load_and_swap<uint32_t>(ptr);
|
||||
PacketAction wfi;
|
||||
wfi.type = Type::kWaitForIdle;
|
||||
wfi.wait_for_idle.probably_unused = value;
|
||||
out_actions.emplace_back(std::move(wfi));
|
||||
break;
|
||||
}
|
||||
|
||||
case PM4_VIZ_QUERY: {
|
||||
uint32_t value = xe::load_and_swap<uint32_t>(ptr);
|
||||
|
||||
PacketAction vzq;
|
||||
vzq.type = Type::kVizQuery;
|
||||
vzq.vizquery.dword0 = value;
|
||||
vzq.vizquery.id = value & 0x3F;
|
||||
vzq.vizquery.end = !!(value & 0x100);
|
||||
out_actions.emplace_back(std::move(vzq));
|
||||
break;
|
||||
}
|
||||
case PM4_EVENT_WRITE_ZPD: {
|
||||
uint32_t value = xe::load_and_swap<uint32_t>(ptr);
|
||||
|
||||
PacketAction evz;
|
||||
evz.type = Type::kEventWriteZPD;
|
||||
evz.event_write_zpd.initiator = value;
|
||||
out_actions.emplace_back(std::move(evz));
|
||||
break;
|
||||
}
|
||||
case PM4_MEM_WRITE: {
|
||||
PacketAction mwr;
|
||||
mwr.type = Type::kMemWrite;
|
||||
mwr.words.reserve(count - 1);
|
||||
|
||||
uint32_t write_addr = xe::load_and_swap<uint32_t>(ptr);
|
||||
auto endianness = static_cast<xenos::Endian>(write_addr & 0x3);
|
||||
auto addr = write_addr & ~0x3;
|
||||
|
||||
mwr.mem_write.addr = addr;
|
||||
mwr.mem_write.endianness = endianness;
|
||||
|
||||
// can't use injectbewords here, have to apply gpuswap to each element
|
||||
for (uint32_t i = 0; i < count - 1; i++) {
|
||||
uint32_t write_data = xe::load_and_swap<uint32_t>(&ptr[(i + 1) * 4]);
|
||||
write_data = GpuSwap(write_data, endianness);
|
||||
mwr.words.push_back(write_data);
|
||||
write_addr += 4;
|
||||
}
|
||||
|
||||
out_actions.emplace_back(std::move(mwr));
|
||||
break;
|
||||
}
|
||||
|
||||
case PM4_REG_TO_MEM: {
|
||||
PacketAction r2m;
|
||||
r2m.type = Type::kRegToMem;
|
||||
r2m.reg2mem.reg_addr = xe::load_and_swap<uint32_t>(ptr);
|
||||
uint32_t dword1 = xe::load_and_swap<uint32_t>(ptr + 4);
|
||||
r2m.reg2mem.endianness = static_cast<xenos::Endian>(dword1 & 0x3);
|
||||
r2m.reg2mem.mem_addr = dword1 & (~3U);
|
||||
out_actions.emplace_back(std::move(r2m));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue