From 52341b8b9c83044c2a49b7176aaa709111d099aa Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Sun, 1 Feb 2026 20:39:46 -0800 Subject: [PATCH] brw: Split EOT handling out of emit_urb_writes() The TES workaround code is still going to be needed even after we rework URB output handling for VS/TES/GS to use NIR intrinsics. For VS, we know at least one URB write will have been emitted at the end of the program, so we can just tag it. GS already handles EOT via emit_gs_thread_end(). Reviewed-by: Alyssa Rosenzweig Part-of: --- src/intel/compiler/brw/brw_compile_tes.cpp | 2 ++ src/intel/compiler/brw/brw_compile_vs.cpp | 3 +++ src/intel/compiler/brw/brw_shader.cpp | 21 ++++++++++++--------- src/intel/compiler/brw/brw_shader.h | 1 + 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/intel/compiler/brw/brw_compile_tes.cpp b/src/intel/compiler/brw/brw_compile_tes.cpp index efa8d82e865..44c4550772f 100644 --- a/src/intel/compiler/brw/brw_compile_tes.cpp +++ b/src/intel/compiler/brw/brw_compile_tes.cpp @@ -44,6 +44,8 @@ run_tes(brw_shader &s) brw_calculate_cfg(s); + s.emit_tes_terminate(); + brw_optimize(s); s.assign_curb_setup(); diff --git a/src/intel/compiler/brw/brw_compile_vs.cpp b/src/intel/compiler/brw/brw_compile_vs.cpp index 526d0091ae7..86cd321912a 100644 --- a/src/intel/compiler/brw/brw_compile_vs.cpp +++ b/src/intel/compiler/brw/brw_compile_vs.cpp @@ -218,6 +218,9 @@ run_vs(brw_shader &s) brw_calculate_cfg(s); + ASSERTED bool eot = s.mark_last_urb_write_with_eot(); + assert(eot); + brw_optimize(s); s.assign_curb_setup(); diff --git a/src/intel/compiler/brw/brw_shader.cpp b/src/intel/compiler/brw/brw_shader.cpp index e541a1c0585..482df008755 100644 --- a/src/intel/compiler/brw/brw_shader.cpp +++ b/src/intel/compiler/brw/brw_shader.cpp @@ -226,13 +226,6 @@ brw_shader::emit_urb_writes(const brw_reg &gs_vertex_count) brw_urb_inst *urb = abld.URB_WRITE(srcs, ARRAY_SIZE(srcs)); urb->components = length; - - /* For Wa_1805992985 one needs additional write in the end. */ - if (intel_needs_workaround(devinfo, 1805992985) && stage == MESA_SHADER_TESS_EVAL) - urb->eot = false; - else - urb->eot = slot == last_slot && stage != MESA_SHADER_GEOMETRY; - urb->offset = urb_offset * (devinfo->ver >= 20 ? 16 : 1); urb_offset = starting_urb_offset + slot + 1; length = 0; @@ -271,11 +264,16 @@ brw_shader::emit_urb_writes(const brw_reg &gs_vertex_count) srcs[URB_LOGICAL_SRC_DATA] = payload; brw_urb_inst *urb = bld.URB_WRITE(srcs, ARRAY_SIZE(srcs)); - urb->eot = true; urb->offset = devinfo->ver >= 20 ? 16 : 1; urb->components = 1; return; } +} + +void +brw_shader::emit_tes_terminate() +{ + assert(stage == MESA_SHADER_TESS_EVAL); /* Wa_1805992985: * @@ -283,8 +281,10 @@ brw_shader::emit_urb_writes(const brw_reg &gs_vertex_count) * send cycle, which is a urb write with an eot must be 4 phases long and * all 8 lanes must valid. */ - if (intel_needs_workaround(devinfo, 1805992985) && stage == MESA_SHADER_TESS_EVAL) { + if (intel_needs_workaround(devinfo, 1805992985)) { assert(dispatch_width == 8); + const brw_builder bld = brw_builder(this); + brw_reg urb_handle = tes_payload().urb_output; brw_reg uniform_urb_handle = retype(brw_allocate_vgrf_units(*this, 1), BRW_TYPE_UD); brw_reg uniform_mask = retype(brw_allocate_vgrf_units(*this, 1), BRW_TYPE_UD); brw_reg payload = retype(brw_allocate_vgrf_units(*this, 4), BRW_TYPE_UD); @@ -325,6 +325,9 @@ brw_shader::emit_urb_writes(const brw_reg &gs_vertex_count) urb->eot = true; urb->offset = 0; urb->components = 4; + } else { + ASSERTED bool eot = mark_last_urb_write_with_eot(); + assert(eot); } } diff --git a/src/intel/compiler/brw/brw_shader.h b/src/intel/compiler/brw/brw_shader.h index 4e7a514b45e..200bdf86aab 100644 --- a/src/intel/compiler/brw/brw_shader.h +++ b/src/intel/compiler/brw/brw_shader.h @@ -93,6 +93,7 @@ public: brw_reg gs_urb_channel_mask(const brw_reg &dword_index); brw_reg gs_urb_per_slot_dword_index(const brw_reg &vertex_count); bool mark_last_urb_write_with_eot(); + void emit_tes_terminate(); void emit_cs_terminate(); const struct brw_compiler *compiler;