anv: implement Wa_14015814527 for task shaders

After using task shader, we need to emit a zero URB state and a
nullprim (empty pipe control) before rendering with primitives.

After this, a normal URB state needs to be returned, this will
happen when pipeline batch is emitted during pipeline switch.

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/20334>
This commit is contained in:
Tapani Pälli 2022-12-29 09:52:36 +02:00 committed by Marge Bot
parent 53d9b696e4
commit 97f2b60833
6 changed files with 76 additions and 0 deletions

View file

@ -83,6 +83,8 @@ void genX(flush_pipeline_select_3d)(struct anv_cmd_buffer *cmd_buffer);
void genX(flush_pipeline_select_gpgpu)(struct anv_cmd_buffer *cmd_buffer);
void genX(emit_pipeline_select)(struct anv_batch *batch, uint32_t pipeline);
void genX(apply_task_urb_workaround)(struct anv_cmd_buffer *cmd_buffer);
enum anv_pipe_bits
genX(emit_apply_pipe_flushes)(struct anv_batch *batch,
struct anv_device *device,

View file

@ -2571,6 +2571,7 @@ struct anv_cmd_graphics_state {
VkShaderStageFlags push_constant_stages;
uint32_t primitive_topology;
bool used_task_shader;
struct anv_buffer *index_buffer;
uint32_t index_type; /**< 3DSTATE_INDEX_BUFFER.IndexFormat */

View file

@ -294,6 +294,9 @@ blorp_exec_on_render(struct blorp_batch *batch,
genX(flush_pipeline_select_3d)(cmd_buffer);
/* Wa_14015814527 */
genX(apply_task_urb_workaround)(cmd_buffer);
/* Apply any outstanding flushes in case pipeline select haven't. */
genX(cmd_buffer_apply_pipe_flushes)(cmd_buffer);

View file

@ -3244,6 +3244,19 @@ genX(cmd_buffer_flush_gfx_state)(struct anv_cmd_buffer *cmd_buffer)
genX(flush_pipeline_select_3d)(cmd_buffer);
/* Wa_14015814527
*
* Apply task URB workaround when switching from task to primitive.
*/
if (cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_PIPELINE) {
if (anv_pipeline_is_primitive(pipeline)) {
genX(apply_task_urb_workaround)(cmd_buffer);
} else if (anv_pipeline_has_stage(cmd_buffer->state.gfx.pipeline,
MESA_SHADER_TASK)) {
cmd_buffer->state.gfx.used_task_shader = true;
}
}
/* Apply any pending pipeline flushes we may have. We want to apply them
* now because, if any of those flushes are for things like push constants,
* the GPU will read the state at weird times.
@ -3696,6 +3709,12 @@ genX(EndCommandBuffer)(
*/
genX(cmd_buffer_enable_pma_fix)(cmd_buffer, false);
/* Wa_14015814527
*
* Apply task URB workaround in the end of primary or secondary cmd_buffer.
*/
genX(apply_task_urb_workaround)(cmd_buffer);
genX(cmd_buffer_apply_pipe_flushes)(cmd_buffer);
emit_isp_disable(cmd_buffer);
@ -3729,6 +3748,12 @@ genX(CmdExecuteCommands)(
if (!primary->state.gfx.object_preemption)
genX(cmd_buffer_set_preemption)(primary, true);
/* Wa_14015814527
*
* Apply task URB workaround before secondary cmd buffers.
*/
genX(apply_task_urb_workaround)(primary);
/* The secondary command buffer doesn't know which textures etc. have been
* flushed prior to their execution. Apply those flushes now.
*/

View file

@ -298,6 +298,10 @@ genX(cmd_buffer_so_memcpy)(struct anv_cmd_buffer *cmd_buffer,
#if GFX_VER == 9
genX(cmd_buffer_set_binding_for_gfx8_vb_flush)(cmd_buffer, 32, src, size);
#endif
/* Wa_14015814527 */
genX(apply_task_urb_workaround)(cmd_buffer);
genX(cmd_buffer_apply_pipe_flushes)(cmd_buffer);
genX(flush_pipeline_select_3d)(cmd_buffer);

View file

@ -995,3 +995,44 @@ VkResult genX(CreateSampler)(
return VK_SUCCESS;
}
/* Wa_14015814527
*
* Check if task shader was utilized within cmd_buffer, if so
* commit empty URB states and null prim.
*/
void
genX(apply_task_urb_workaround)(struct anv_cmd_buffer *cmd_buffer)
{
#if GFX_VERx10 != 125
return;
#else
if (cmd_buffer->state.current_pipeline != _3D ||
!cmd_buffer->state.gfx.used_task_shader)
return;
cmd_buffer->state.gfx.used_task_shader = false;
/* Wa_14015821291 mentions that WA below is not required if we have
* a pipeline flush going on. It will get flushed during
* cmd_buffer_flush_state before draw.
*/
if ((cmd_buffer->state.pending_pipe_bits & ANV_PIPE_CS_STALL_BIT))
return;
for (int i = 0; i <= MESA_SHADER_GEOMETRY; i++) {
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_URB_VS), urb) {
urb._3DCommandSubOpcode += i;
}
}
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_URB_ALLOC_MESH), zero);
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_URB_ALLOC_TASK), zero);
/* Issue 'nullprim' to commit the state. */
anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
pc.PostSyncOperation = WriteImmediateData;
pc.Address = cmd_buffer->device->workaround_address;
}
#endif
}