From 1278a547f591a606a0d341df87652c34be7431db Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Mon, 4 May 2026 23:31:21 +0200 Subject: [PATCH] r600: replace TGSI TCS passthrough with NIR version We don't actually need to copy the vertex attributes because if no TCS shader was given by the user TES simply is pointed to the VS output in LDS that has the same layout the TCS shader would provide. v2: with the lowering of the relevant intrinsics in place use nir_create_passthrough_tcs_impl to create the passthrough shader (like suggested by Mareco and Emma) Signed-off-by: Gert Wollny --- src/gallium/drivers/r600/r600_state_common.c | 43 ++++++++------------ 1 file changed, 18 insertions(+), 25 deletions(-) diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index 74ba282bdab..a58796cfae0 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -19,9 +19,9 @@ #include "util/u_math.h" #include "tgsi/tgsi_parse.h" #include "tgsi/tgsi_scan.h" -#include "tgsi/tgsi_ureg.h" #include "nir.h" +#include "nir_builder.h" #include "nir/nir_to_tgsi_info.h" void r600_init_command_buffer(struct r600_command_buffer *cb, unsigned num_dw) @@ -1679,32 +1679,25 @@ static void r600_update_clip_state(struct r600_context *rctx, } } -static void r600_generate_fixed_func_tcs(struct r600_context *rctx) +/* The TCS passthrough shader only writes the tessellation levels, + * the IO doesn't need to be copied over, because TES gets handed the + * location of the VS outputs directly if this shader is used + * (see evergreen_setup_tess_constants) +*/ + +static struct r600_pipe_shader_selector * +r600_create_fixed_func_tcs_nir(struct r600_context *rctx) { - struct ureg_src const0, const1; - struct ureg_dst tessouter, tessinner; - struct ureg_program *ureg = ureg_create(MESA_SHADER_TESS_CTRL); + const struct nir_shader_compiler_options *options = + rctx->screen->b.b.nir_options[MESA_SHADER_TESS_CTRL]; - if (!ureg) - return; /* if we get here, we're screwed */ + struct pipe_shader_state state = { + .type = PIPE_SHADER_IR_NIR, + .ir.nir = nir_create_passthrough_tcs_impl(options, NULL, 0, 0) + }; - assert(!rctx->fixed_func_tcs_shader); - - ureg_DECL_constant2D(ureg, 0, 1, R600_BUFFER_INFO_CONST_BUFFER); - const0 = ureg_src_dimension(ureg_src_register(TGSI_FILE_CONSTANT, 0), - R600_BUFFER_INFO_CONST_BUFFER); - const1 = ureg_src_dimension(ureg_src_register(TGSI_FILE_CONSTANT, 1), - R600_BUFFER_INFO_CONST_BUFFER); - - tessouter = ureg_DECL_output(ureg, TGSI_SEMANTIC_TESSOUTER, 0); - tessinner = ureg_DECL_output(ureg, TGSI_SEMANTIC_TESSINNER, 0); - - ureg_MOV(ureg, tessouter, const0); - ureg_MOV(ureg, tessinner, const1); - ureg_END(ureg); - - rctx->fixed_func_tcs_shader = - ureg_create_shader_and_destroy(ureg, &rctx->b.b); + return (struct r600_pipe_shader_selector *) + rctx->b.b.create_tcs_state(&rctx->b.b, &state); } void r600_update_compressed_resource_state(struct r600_context *rctx, bool compute_only) @@ -1919,7 +1912,7 @@ static bool r600_update_derived_state(struct r600_context *rctx) UPDATE_SHADER(EG_HW_STAGE_HS, tcs); } else if (rctx->tes_shader) { if (!rctx->fixed_func_tcs_shader) { - r600_generate_fixed_func_tcs(rctx); + rctx->fixed_func_tcs_shader = r600_create_fixed_func_tcs_nir(rctx); if (!rctx->fixed_func_tcs_shader) return false;