From de22e5923138a7a807978db9d2127987df7d1556 Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Mon, 17 Feb 2025 17:10:47 +0800 Subject: [PATCH] glsl: handle mesh shader primitive type layout qualifier MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Ian Romanick Acked-by: Marek Olšák Part-of: --- src/compiler/glsl/ast_type.cpp | 17 ++++++++++++ src/compiler/glsl/gl_nir_linker.c | 35 ++++++++++++++++++++++++ src/compiler/glsl/glsl_parser.yy | 2 +- src/compiler/glsl/glsl_parser_extras.cpp | 9 ++++++ src/mesa/main/shader_types.h | 7 +++++ 5 files changed, 69 insertions(+), 1 deletion(-) diff --git a/src/compiler/glsl/ast_type.cpp b/src/compiler/glsl/ast_type.cpp index 0b9763f9421..6073ca4f175 100644 --- a/src/compiler/glsl/ast_type.cpp +++ b/src/compiler/glsl/ast_type.cpp @@ -588,6 +588,23 @@ ast_type_qualifier::validate_out_qualifier(YYLTYPE *loc, case MESA_SHADER_FRAGMENT: valid_out_mask.flags.q.blend_support = 1; break; + case MESA_SHADER_MESH: + if (this->flags.q.prim_type) { + /* Make sure this is a valid output primitive type. */ + switch (this->prim_type) { + case GL_POINTS: + case GL_LINES: + case GL_TRIANGLES: + break; + default: + r = false; + _mesa_glsl_error(loc, state, "invalid mesh shader output " + "primitive type"); + break; + } + } + valid_out_mask.flags.q.prim_type = 1; + break; default: r = false; _mesa_glsl_error(loc, state, diff --git a/src/compiler/glsl/gl_nir_linker.c b/src/compiler/glsl/gl_nir_linker.c index 22a28b79188..1a67316740f 100644 --- a/src/compiler/glsl/gl_nir_linker.c +++ b/src/compiler/glsl/gl_nir_linker.c @@ -2558,6 +2558,40 @@ link_cs_input_layout_qualifiers(struct gl_shader_program *prog, } +static void +link_ms_inout_layout_qualifiers(struct gl_shader_program *prog, + struct gl_program *gl_prog, + struct gl_shader **shader_list, + unsigned num_shaders) +{ + if (gl_prog->info.stage != MESA_SHADER_MESH) + return; + + enum mesa_prim prim_type = MESA_PRIM_UNKNOWN; + + for (unsigned i = 0; i < num_shaders; i++) { + struct gl_shader *shader = shader_list[i]; + + if (shader->info.Mesh.OutputType != MESA_PRIM_UNKNOWN) { + if (prim_type != MESA_PRIM_UNKNOWN && + prim_type != shader->info.Mesh.OutputType) { + linker_error(prog, "mesh shader defined with conflicting " + "output types\n"); + return; + } + prim_type = shader->info.Mesh.OutputType; + } + } + + if (prim_type == MESA_PRIM_UNKNOWN) { + linker_error(prog, "mesh shader didn't declare primitive output type\n"); + return; + } else { + gl_prog->nir->info.mesh.primitive_type = prim_type; + } +} + + /** * Combine a group of shaders for a single stage to generate a linked shader * @@ -2689,6 +2723,7 @@ link_intrastage_shaders(void *mem_ctx, link_tes_in_layout_qualifiers(prog, gl_prog, shader_list, num_shaders); link_gs_inout_layout_qualifiers(prog, gl_prog, shader_list, num_shaders); link_cs_input_layout_qualifiers(prog, gl_prog, shader_list, num_shaders); + link_ms_inout_layout_qualifiers(prog, gl_prog, shader_list, num_shaders); if (linked->Stage != MESA_SHADER_FRAGMENT) link_xfb_stride_layout_qualifiers(&ctx->Const, prog, shader_list, num_shaders); diff --git a/src/compiler/glsl/glsl_parser.yy b/src/compiler/glsl/glsl_parser.yy index 40d100b22ee..23d42309d18 100644 --- a/src/compiler/glsl/glsl_parser.yy +++ b/src/compiler/glsl/glsl_parser.yy @@ -1328,7 +1328,7 @@ layout_qualifier_id: } if ($$.flags.i && !state->has_geometry_shader() && - !state->has_tessellation_shader()) { + !state->has_tessellation_shader() && !state->EXT_mesh_shader_enable) { _mesa_glsl_error(& @1, state, "#version 150 layout " "qualifier `%s' used", $1); } diff --git a/src/compiler/glsl/glsl_parser_extras.cpp b/src/compiler/glsl/glsl_parser_extras.cpp index bfeae4f98ac..6242acd39cc 100644 --- a/src/compiler/glsl/glsl_parser_extras.cpp +++ b/src/compiler/glsl/glsl_parser_extras.cpp @@ -2099,6 +2099,15 @@ set_shader_inout_layout(struct gl_shader *shader, shader->BlendSupport = state->fs_blend_support; break; + case MESA_SHADER_MESH: + if (state->out_qualifier->flags.q.prim_type) { + shader->info.Mesh.OutputType = + gl_to_mesa_prim(state->out_qualifier->prim_type); + } else { + shader->info.Mesh.OutputType = MESA_PRIM_UNKNOWN; + } + break; + default: /* Nothing to do. */ break; diff --git a/src/mesa/main/shader_types.h b/src/mesa/main/shader_types.h index baf1b59b9e4..0c2d70ace9f 100644 --- a/src/mesa/main/shader_types.h +++ b/src/mesa/main/shader_types.h @@ -132,6 +132,13 @@ struct gl_shader_info */ enum gl_derivative_group DerivativeGroup; } Comp; + + /** + * Mesh shader state from EXT_mesh_shader + */ + struct { + enum mesa_prim OutputType; + } Mesh; }; /**