[GPU] Skip viz-query geometry (if marked).
Document research about viz queries. v2: Remove viz status unions and move comments to register definitions. Add contributors to TODOs. v3: Comment out unused variables. Add TODO for correctly dropping draw calls with memexport. Register comment formatting.
This commit is contained in:
parent
b06138b464
commit
f6dc9ad517
|
@ -1179,9 +1179,11 @@ bool CommandProcessor::ExecutePacketType3_DRAW_INDX(RingBuffer* reader,
|
|||
// initiate fetch of index buffer and draw
|
||||
// if dword0 != 0, this is a conditional draw based on viz query.
|
||||
// This ID matches the one issued in PM4_VIZ_QUERY
|
||||
// ID = dword0 & 0x3F;
|
||||
// use = dword0 & 0x40;
|
||||
uint32_t dword0 = reader->ReadAndSwap<uint32_t>(); // viz query info
|
||||
// uint32_t viz_id = dword0 & 0x3F;
|
||||
// when true, render conditionally based on query result
|
||||
// uint32_t viz_use = dword0 & 0x100;
|
||||
|
||||
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);
|
||||
|
@ -1218,6 +1220,14 @@ bool CommandProcessor::ExecutePacketType3_DRAW_INDX(RingBuffer* reader,
|
|||
} break;
|
||||
}
|
||||
|
||||
auto viz_query = register_file_->Get<reg::PA_SC_VIZ_QUERY>();
|
||||
if (viz_query.viz_query_ena && viz_query.kill_pix_post_hi_z) {
|
||||
// TODO(Triang3l): Don't drop the draw call completely if the vertex shader
|
||||
// has memexport.
|
||||
// TODO(Triang3l || JoelLinn): Handle this properly in the render backends.
|
||||
return true;
|
||||
}
|
||||
|
||||
bool success =
|
||||
IssueDraw(vgt_draw_initiator.prim_type, vgt_draw_initiator.num_indices,
|
||||
is_indexed ? &index_buffer_info : nullptr,
|
||||
|
@ -1251,6 +1261,14 @@ bool CommandProcessor::ExecutePacketType3_DRAW_INDX_2(RingBuffer* reader,
|
|||
// TODO(Triang3l): VGT_IMMED_DATA.
|
||||
reader->AdvanceRead((count - 1) * sizeof(uint32_t));
|
||||
|
||||
auto viz_query = register_file_->Get<reg::PA_SC_VIZ_QUERY>();
|
||||
if (viz_query.viz_query_ena && viz_query.kill_pix_post_hi_z) {
|
||||
// TODO(Triang3l): Don't drop the draw call completely if the vertex shader
|
||||
// has memexport.
|
||||
// TODO(Triang3l || JoelLinn): Handle this properly in the render backends.
|
||||
return true;
|
||||
}
|
||||
|
||||
bool success = IssueDraw(
|
||||
vgt_draw_initiator.prim_type, vgt_draw_initiator.num_indices, nullptr,
|
||||
xenos::IsMajorModeExplicit(vgt_draw_initiator.major_mode,
|
||||
|
@ -1447,15 +1465,26 @@ bool CommandProcessor::ExecutePacketType3_VIZ_QUERY(RingBuffer* reader,
|
|||
uint32_t dword0 = reader->ReadAndSwap<uint32_t>();
|
||||
|
||||
uint32_t id = dword0 & 0x3F;
|
||||
uint32_t end = dword0 & 0x80;
|
||||
uint32_t end = dword0 & 0x100;
|
||||
if (!end) {
|
||||
// begin a new viz query @ id
|
||||
// On hardware this clears the internal state of the scan converter (which
|
||||
// is different to the register)
|
||||
WriteRegister(XE_GPU_REG_VGT_EVENT_INITIATOR, VIZQUERY_START);
|
||||
XELOGGPU("Begin viz query ID {:02X}", id);
|
||||
} else {
|
||||
// end the viz query
|
||||
WriteRegister(XE_GPU_REG_VGT_EVENT_INITIATOR, VIZQUERY_END);
|
||||
XELOGGPU("End viz query ID {:02X}", id);
|
||||
// The scan converter writes the internal result back to the register here.
|
||||
// We just fake it and say it was visible in case it is read back.
|
||||
if (id < 32) {
|
||||
register_file_->values[XE_GPU_REG_PA_SC_VIZ_QUERY_STATUS_0].u32 |=
|
||||
uint32_t(1) << id;
|
||||
} else {
|
||||
register_file_->values[XE_GPU_REG_PA_SC_VIZ_QUERY_STATUS_1].u32 |=
|
||||
uint32_t(1) << (id - 32);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -40,6 +40,12 @@ XE_GPU_REGISTER(0x0A2F, kDword, COHER_SIZE_HOST)
|
|||
XE_GPU_REGISTER(0x0A30, kDword, COHER_BASE_HOST)
|
||||
XE_GPU_REGISTER(0x0A31, kDword, COHER_STATUS_HOST)
|
||||
|
||||
// Status flags of viz queries, doesn't seem to be read back by d3d
|
||||
// queries 0x00 to 0x1f (be), bit set when visible
|
||||
XE_GPU_REGISTER(0x0C44, kDword, PA_SC_VIZ_QUERY_STATUS_0)
|
||||
// queries 0x20 to 0x3f (be)
|
||||
XE_GPU_REGISTER(0x0C45, kDword, PA_SC_VIZ_QUERY_STATUS_1)
|
||||
|
||||
XE_GPU_REGISTER(0x0D00, kDword, SQ_GPR_MANAGEMENT)
|
||||
XE_GPU_REGISTER(0x0D01, kDword, SQ_FLOW_CONTROL)
|
||||
XE_GPU_REGISTER(0x0D02, kDword, SQ_INST_STORE_MANAGMENT)
|
||||
|
@ -57,7 +63,8 @@ XE_GPU_REGISTER(0x0E42, kDword, UNKNOWN_0E42)
|
|||
XE_GPU_REGISTER(0x0F01, kDword, RB_BC_CONTROL)
|
||||
XE_GPU_REGISTER(0x0F02, kDword, RB_EDRAM_INFO)
|
||||
|
||||
// D1*, LUT, and AVIVO registers taken from libxenon and https://www.x.org/docs/AMD/old/RRG-216M56-03oOEM.pdf
|
||||
// D1*, LUT, and AVIVO registers taken from libxenon and
|
||||
// https://www.x.org/docs/AMD/old/RRG-216M56-03oOEM.pdf
|
||||
XE_GPU_REGISTER(0x1838, kDword, D1MODE_MASTER_UPDATE_LOCK)
|
||||
|
||||
XE_GPU_REGISTER(0x1841, kDword, D1GRPH_CONTROL)
|
||||
|
|
|
@ -289,12 +289,16 @@ union PA_SC_MPASS_PS_CNTL {
|
|||
static constexpr Register register_index = XE_GPU_REG_PA_SC_MPASS_PS_CNTL;
|
||||
};
|
||||
|
||||
// Scanline converter viz query
|
||||
// Scanline converter viz query, used by D3D for gpu side conditional rendering
|
||||
union PA_SC_VIZ_QUERY {
|
||||
struct {
|
||||
// the visibility of draws should be evaluated
|
||||
uint32_t viz_query_ena : 1; // +0
|
||||
uint32_t viz_query_id : 6; // +1
|
||||
uint32_t kill_pix_post_early_z : 1; // +7
|
||||
// discard geometry after test (but use for testing)
|
||||
uint32_t kill_pix_post_hi_z : 1; // +7
|
||||
// not used with d3d
|
||||
uint32_t kill_pix_detail_mask : 1; // +8
|
||||
};
|
||||
uint32_t value;
|
||||
static constexpr Register register_index = XE_GPU_REG_PA_SC_VIZ_QUERY;
|
||||
|
|
Loading…
Reference in New Issue