[GPU] Set VGT_DRAW_INITIATOR and use major mode from it
This commit is contained in:
@@ -1153,44 +1153,51 @@ bool CommandProcessor::ExecutePacketType3_DRAW_INDX(RingBuffer* reader,
|
||||
// ID = dword0 & 0x3F;
|
||||
// use = dword0 & 0x40;
|
||||
uint32_t dword0 = reader->ReadAndSwap<uint32_t>(); // viz query info
|
||||
uint32_t dword1 = reader->ReadAndSwap<uint32_t>();
|
||||
uint32_t index_count = dword1 >> 16;
|
||||
auto prim_type = static_cast<PrimitiveType>(dword1 & 0x3F);
|
||||
reg::VGT_DRAW_INITIATOR vgt_draw_initiator;
|
||||
vgt_draw_initiator.value = reader->ReadAndSwap<uint32_t>();
|
||||
WriteRegister(XE_GPU_REG_VGT_DRAW_INITIATOR, vgt_draw_initiator.value);
|
||||
|
||||
bool is_indexed = false;
|
||||
IndexBufferInfo index_buffer_info;
|
||||
uint32_t src_sel = (dword1 >> 6) & 0x3;
|
||||
if (src_sel == 0x0) {
|
||||
// DI_SRC_SEL_DMA
|
||||
// Indexed draw.
|
||||
is_indexed = true;
|
||||
index_buffer_info.guest_base = reader->ReadAndSwap<uint32_t>();
|
||||
uint32_t index_size = reader->ReadAndSwap<uint32_t>();
|
||||
index_buffer_info.endianness = static_cast<Endian>(index_size >> 30);
|
||||
index_size &= 0x00FFFFFF;
|
||||
bool index_32bit = (dword1 >> 11) & 0x1;
|
||||
index_buffer_info.format =
|
||||
index_32bit ? IndexFormat::kInt32 : IndexFormat::kInt16;
|
||||
index_size *= index_32bit ? 4 : 2;
|
||||
index_buffer_info.length = index_size;
|
||||
index_buffer_info.count = index_count;
|
||||
} else if (src_sel == 0x1) {
|
||||
// DI_SRC_SEL_IMMEDIATE
|
||||
assert_always();
|
||||
} else if (src_sel == 0x2) {
|
||||
// DI_SRC_SEL_AUTO_INDEX
|
||||
// Auto draw.
|
||||
index_buffer_info.guest_base = 0;
|
||||
index_buffer_info.length = 0;
|
||||
} else {
|
||||
// Invalid source select.
|
||||
assert_always();
|
||||
switch (vgt_draw_initiator.source_select) {
|
||||
case xenos::SourceSelect::kDMA: {
|
||||
// Indexed draw.
|
||||
is_indexed = true;
|
||||
index_buffer_info.guest_base = reader->ReadAndSwap<uint32_t>();
|
||||
uint32_t index_size = reader->ReadAndSwap<uint32_t>();
|
||||
index_buffer_info.endianness = static_cast<Endian>(index_size >> 30);
|
||||
index_size &= 0x00FFFFFF;
|
||||
index_buffer_info.format = vgt_draw_initiator.index_size;
|
||||
index_size *=
|
||||
(vgt_draw_initiator.index_size == IndexFormat::kInt32) ? 4 : 2;
|
||||
index_buffer_info.length = index_size;
|
||||
index_buffer_info.count = vgt_draw_initiator.num_indices;
|
||||
} break;
|
||||
case xenos::SourceSelect::kImmediate: {
|
||||
// TODO(Triang3l): VGT_IMMED_DATA.
|
||||
assert_always();
|
||||
} break;
|
||||
case xenos::SourceSelect::kAutoIndex: {
|
||||
// Auto draw.
|
||||
index_buffer_info.guest_base = 0;
|
||||
index_buffer_info.length = 0;
|
||||
} break;
|
||||
default: {
|
||||
// Invalid source select.
|
||||
assert_always();
|
||||
} break;
|
||||
}
|
||||
|
||||
bool success = IssueDraw(prim_type, index_count,
|
||||
is_indexed ? &index_buffer_info : nullptr);
|
||||
bool success =
|
||||
IssueDraw(vgt_draw_initiator.prim_type, vgt_draw_initiator.num_indices,
|
||||
is_indexed ? &index_buffer_info : nullptr,
|
||||
xenos::IsMajorModeExplicit(vgt_draw_initiator.major_mode,
|
||||
vgt_draw_initiator.prim_type));
|
||||
if (!success) {
|
||||
XELOGE("PM4_DRAW_INDX(%d, %d, %d): Failed in backend", index_count,
|
||||
prim_type, src_sel);
|
||||
XELOGE("PM4_DRAW_INDX(%d, %d, %d): Failed in backend",
|
||||
vgt_draw_initiator.num_indices,
|
||||
uint32_t(vgt_draw_initiator.prim_type),
|
||||
uint32_t(vgt_draw_initiator.source_select));
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -1200,21 +1207,27 @@ bool CommandProcessor::ExecutePacketType3_DRAW_INDX_2(RingBuffer* reader,
|
||||
uint32_t packet,
|
||||
uint32_t count) {
|
||||
// draw using supplied indices in packet
|
||||
uint32_t dword0 = reader->ReadAndSwap<uint32_t>();
|
||||
uint32_t index_count = dword0 >> 16;
|
||||
auto prim_type = static_cast<PrimitiveType>(dword0 & 0x3F);
|
||||
uint32_t src_sel = (dword0 >> 6) & 0x3;
|
||||
assert_true(src_sel == 0x2); // 'SrcSel=AutoIndex'
|
||||
reg::VGT_DRAW_INITIATOR vgt_draw_initiator;
|
||||
vgt_draw_initiator.value = reader->ReadAndSwap<uint32_t>();
|
||||
WriteRegister(XE_GPU_REG_VGT_DRAW_INITIATOR, vgt_draw_initiator.value);
|
||||
assert_true(vgt_draw_initiator.source_select ==
|
||||
xenos::SourceSelect::kAutoIndex);
|
||||
// Index buffer unused as automatic.
|
||||
// bool index_32bit = (dword0 >> 11) & 0x1;
|
||||
// uint32_t indices_size = index_count * (index_32bit ? 4 : 2);
|
||||
// uint32_t indices_size =
|
||||
// vgt_draw_initiator.num_indices *
|
||||
// (vgt_draw_initiator.index_size == IndexFormat::kInt32 ? 4 : 2);
|
||||
// uint32_t index_ptr = reader->ptr();
|
||||
// TODO(Triang3l): VGT_IMMED_DATA.
|
||||
reader->AdvanceRead((count - 1) * sizeof(uint32_t));
|
||||
|
||||
bool success = IssueDraw(prim_type, index_count, nullptr);
|
||||
bool success = IssueDraw(
|
||||
vgt_draw_initiator.prim_type, vgt_draw_initiator.num_indices, nullptr,
|
||||
xenos::IsMajorModeExplicit(vgt_draw_initiator.major_mode,
|
||||
vgt_draw_initiator.prim_type));
|
||||
if (!success) {
|
||||
XELOGE("PM4_DRAW_INDX_IMM(%d, %d): Failed in backend", index_count,
|
||||
prim_type);
|
||||
XELOGE("PM4_DRAW_INDX_IMM(%d, %d): Failed in backend",
|
||||
vgt_draw_initiator.num_indices,
|
||||
uint32_t(vgt_draw_initiator.prim_type));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user