mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-30 07:10:27 +01:00
anv: implement Wa_18020335297
Set some state and implement dummy draws whenever viewport pointer is being reprogrammed. Signed-off-by: Tapani Pälli <tapani.palli@intel.com> Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25987>
This commit is contained in:
parent
418299c120
commit
d3e3c30d36
3 changed files with 143 additions and 0 deletions
|
|
@ -3538,6 +3538,11 @@ struct anv_cmd_graphics_state {
|
|||
*/
|
||||
bool ds_write_state;
|
||||
|
||||
/**
|
||||
* State tracking for Wa_18020335297.
|
||||
*/
|
||||
bool viewport_set;
|
||||
|
||||
uint32_t n_occlusion_queries;
|
||||
|
||||
struct anv_gfx_dynamic_state dyn_state;
|
||||
|
|
|
|||
|
|
@ -3333,6 +3333,10 @@ genX(BeginCommandBuffer)(
|
|||
if (cmd_buffer->vk.level == VK_COMMAND_BUFFER_LEVEL_PRIMARY)
|
||||
cmd_buffer->usage_flags &= ~VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
|
||||
|
||||
/* Assume the viewport has already been set in primary command buffers. */
|
||||
if (cmd_buffer->vk.level == VK_COMMAND_BUFFER_LEVEL_SECONDARY)
|
||||
cmd_buffer->state.gfx.viewport_set = true;
|
||||
|
||||
trace_intel_begin_cmd_buffer(&cmd_buffer->trace);
|
||||
|
||||
if (anv_cmd_buffer_is_video_queue(cmd_buffer) ||
|
||||
|
|
@ -3730,6 +3734,8 @@ genX(CmdExecuteCommands)(
|
|||
if (secondary->state.depth_reg_mode != ANV_DEPTH_REG_MODE_UNKNOWN)
|
||||
container->state.depth_reg_mode = secondary->state.depth_reg_mode;
|
||||
#endif
|
||||
|
||||
container->state.gfx.viewport_set |= secondary->state.gfx.viewport_set;
|
||||
}
|
||||
|
||||
/* The secondary isn't counted in our VF cache tracking so we need to
|
||||
|
|
|
|||
|
|
@ -1299,6 +1299,80 @@ genX(cmd_buffer_flush_gfx_runtime_state)(struct anv_cmd_buffer *cmd_buffer)
|
|||
vk_dynamic_graphics_state_clear_dirty(&cmd_buffer->vk.dynamic_graphics_state);
|
||||
}
|
||||
|
||||
static void
|
||||
emit_wa_18020335297_dummy_draw(struct anv_cmd_buffer *cmd_buffer)
|
||||
{
|
||||
#if GFX_VERx10 >= 125
|
||||
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_VFG), vfg) {
|
||||
vfg.DistributionMode = RR_STRICT;
|
||||
}
|
||||
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_VF), vf) {
|
||||
vf.GeometryDistributionEnable = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if GFX_VER >= 12
|
||||
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_PRIMITIVE_REPLICATION), pr) {
|
||||
pr.ReplicaMask = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_RASTER), rr) {
|
||||
rr.CullMode = CULLMODE_NONE;
|
||||
rr.FrontFaceFillMode = FILL_MODE_SOLID;
|
||||
rr.BackFaceFillMode = FILL_MODE_SOLID;
|
||||
}
|
||||
|
||||
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_VF_STATISTICS), zero);
|
||||
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_VF_SGVS), zero);
|
||||
|
||||
#if GFX_VER >= 11
|
||||
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_VF_SGVS_2), zero);
|
||||
#endif
|
||||
|
||||
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_CLIP), clip) {
|
||||
clip.ClipEnable = true;
|
||||
clip.ClipMode = CLIPMODE_REJECT_ALL;
|
||||
}
|
||||
|
||||
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_VS), zero);
|
||||
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_GS), zero);
|
||||
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_HS), zero);
|
||||
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_TE), zero);
|
||||
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_DS), zero);
|
||||
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_STREAMOUT), zero);
|
||||
|
||||
uint32_t *vertex_elements = anv_batch_emitn(&cmd_buffer->batch, 1 + 2 * 2,
|
||||
GENX(3DSTATE_VERTEX_ELEMENTS));
|
||||
uint32_t *ve_pack_dest = &vertex_elements[1];
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
struct GENX(VERTEX_ELEMENT_STATE) element = {
|
||||
.Valid = true,
|
||||
.SourceElementFormat = ISL_FORMAT_R32G32B32A32_FLOAT,
|
||||
.Component0Control = VFCOMP_STORE_0,
|
||||
.Component1Control = VFCOMP_STORE_0,
|
||||
.Component2Control = i == 0 ? VFCOMP_STORE_0 : VFCOMP_STORE_1_FP,
|
||||
.Component3Control = i == 0 ? VFCOMP_STORE_0 : VFCOMP_STORE_1_FP,
|
||||
};
|
||||
GENX(VERTEX_ELEMENT_STATE_pack)(NULL, ve_pack_dest, &element);
|
||||
ve_pack_dest += GENX(VERTEX_ELEMENT_STATE_length);
|
||||
}
|
||||
|
||||
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_VF_TOPOLOGY), topo) {
|
||||
topo.PrimitiveTopologyType = _3DPRIM_TRILIST;
|
||||
}
|
||||
|
||||
/* Emit dummy draw per slice. */
|
||||
for (unsigned i = 0; i < cmd_buffer->device->info->num_slices; i++) {
|
||||
anv_batch_emit(&cmd_buffer->batch, GENX(3DPRIMITIVE), prim) {
|
||||
prim.VertexCountPerInstance = 3;
|
||||
prim.PrimitiveTopologyType = _3DPRIM_TRILIST;
|
||||
prim.InstanceCount = 1;
|
||||
prim.VertexAccessType = SEQUENTIAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* This function handles dirty state emission to the batch buffer.
|
||||
*/
|
||||
|
|
@ -1499,6 +1573,7 @@ cmd_buffer_gfx_state_emission(struct anv_cmd_buffer *cmd_buffer)
|
|||
GENX(3DSTATE_VIEWPORT_STATE_POINTERS_CC), cc) {
|
||||
cc.CCViewportPointer = cc_state.offset;
|
||||
}
|
||||
cmd_buffer->state.gfx.viewport_set = true;
|
||||
}
|
||||
|
||||
if (BITSET_TEST(hw_state->dirty, ANV_GFX_STATE_SCISSOR)) {
|
||||
|
|
@ -1918,6 +1993,63 @@ genX(cmd_buffer_flush_gfx_hw_state)(struct anv_cmd_buffer *cmd_buffer)
|
|||
BITSET_SET(hw_state->dirty, ANV_GFX_STATE_MULTISAMPLE);
|
||||
#endif
|
||||
|
||||
/* Wa_18020335297 - Apply the WA when viewport ptr is reprogrammed. */
|
||||
if (intel_needs_workaround(device->info, 18020335297) &&
|
||||
BITSET_TEST(hw_state->dirty, ANV_GFX_STATE_VIEWPORT_CC) &&
|
||||
cmd_buffer->state.gfx.viewport_set) {
|
||||
/* For mesh, we implement the WA using CS stall. This is for
|
||||
* simplicity and takes care of possible interaction with Wa_16014390852.
|
||||
*/
|
||||
if (anv_pipeline_is_mesh(pipeline)) {
|
||||
genx_batch_emit_pipe_control(&cmd_buffer->batch, device->info,
|
||||
_3D, ANV_PIPE_CS_STALL_BIT);
|
||||
} else {
|
||||
/* Mask off all instructions that we program. */
|
||||
BITSET_CLEAR(hw_state->dirty, ANV_GFX_STATE_VFG);
|
||||
BITSET_CLEAR(hw_state->dirty, ANV_GFX_STATE_VF);
|
||||
BITSET_CLEAR(hw_state->dirty, ANV_GFX_STATE_PRIMITIVE_REPLICATION);
|
||||
BITSET_CLEAR(hw_state->dirty, ANV_GFX_STATE_RASTER);
|
||||
BITSET_CLEAR(hw_state->dirty, ANV_GFX_STATE_VF_STATISTICS);
|
||||
BITSET_CLEAR(hw_state->dirty, ANV_GFX_STATE_VF_SGVS);
|
||||
BITSET_CLEAR(hw_state->dirty, ANV_GFX_STATE_VF_SGVS_2);
|
||||
BITSET_CLEAR(hw_state->dirty, ANV_GFX_STATE_CLIP);
|
||||
BITSET_CLEAR(hw_state->dirty, ANV_GFX_STATE_STREAMOUT);
|
||||
BITSET_CLEAR(hw_state->dirty, ANV_GFX_STATE_VERTEX_INPUT);
|
||||
BITSET_CLEAR(hw_state->dirty, ANV_GFX_STATE_VF_TOPOLOGY);
|
||||
|
||||
BITSET_CLEAR(hw_state->dirty, ANV_GFX_STATE_VS);
|
||||
BITSET_CLEAR(hw_state->dirty, ANV_GFX_STATE_GS);
|
||||
BITSET_CLEAR(hw_state->dirty, ANV_GFX_STATE_HS);
|
||||
BITSET_CLEAR(hw_state->dirty, ANV_GFX_STATE_TE);
|
||||
BITSET_CLEAR(hw_state->dirty, ANV_GFX_STATE_DS);
|
||||
|
||||
cmd_buffer_gfx_state_emission(cmd_buffer);
|
||||
|
||||
emit_wa_18020335297_dummy_draw(cmd_buffer);
|
||||
|
||||
/* Dirty all emitted WA state to make sure that current real
|
||||
* state is restored.
|
||||
*/
|
||||
BITSET_SET(hw_state->dirty, ANV_GFX_STATE_VFG);
|
||||
BITSET_SET(hw_state->dirty, ANV_GFX_STATE_VF);
|
||||
BITSET_SET(hw_state->dirty, ANV_GFX_STATE_PRIMITIVE_REPLICATION);
|
||||
BITSET_SET(hw_state->dirty, ANV_GFX_STATE_RASTER);
|
||||
BITSET_SET(hw_state->dirty, ANV_GFX_STATE_VF_STATISTICS);
|
||||
BITSET_SET(hw_state->dirty, ANV_GFX_STATE_VF_SGVS);
|
||||
BITSET_SET(hw_state->dirty, ANV_GFX_STATE_VF_SGVS_2);
|
||||
BITSET_SET(hw_state->dirty, ANV_GFX_STATE_CLIP);
|
||||
BITSET_SET(hw_state->dirty, ANV_GFX_STATE_STREAMOUT);
|
||||
BITSET_SET(hw_state->dirty, ANV_GFX_STATE_VERTEX_INPUT);
|
||||
BITSET_SET(hw_state->dirty, ANV_GFX_STATE_VF_TOPOLOGY);
|
||||
|
||||
BITSET_SET(hw_state->dirty, ANV_GFX_STATE_VS);
|
||||
BITSET_SET(hw_state->dirty, ANV_GFX_STATE_GS);
|
||||
BITSET_SET(hw_state->dirty, ANV_GFX_STATE_HS);
|
||||
BITSET_SET(hw_state->dirty, ANV_GFX_STATE_TE);
|
||||
BITSET_SET(hw_state->dirty, ANV_GFX_STATE_DS);
|
||||
}
|
||||
}
|
||||
|
||||
cmd_buffer_gfx_state_emission(cmd_buffer);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue