mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 09:08:10 +02:00
glsl: handle max_vertices/primitives for mesh shader
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com> Acked-by: Marek Olšák <marek.olsak@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36405>
This commit is contained in:
parent
de22e59231
commit
611370965f
6 changed files with 105 additions and 3 deletions
|
|
@ -681,6 +681,7 @@ struct ast_type_qualifier {
|
|||
/** GL_EXT_mesh_shader */
|
||||
unsigned task_payload:1;
|
||||
unsigned per_primitive:1;
|
||||
unsigned max_primitives:1;
|
||||
}
|
||||
/** \brief Set of flags, accessed by name. */
|
||||
q;
|
||||
|
|
@ -729,6 +730,9 @@ struct ast_type_qualifier {
|
|||
/** Maximum output vertices in GLSL 1.50 geometry shaders. */
|
||||
ast_layout_expression *max_vertices;
|
||||
|
||||
/** Maximum output primitives in mesh shader. */
|
||||
ast_layout_expression *max_primitives;
|
||||
|
||||
/** Stream in GLSL 1.50 geometry shaders. */
|
||||
ast_expression *stream;
|
||||
|
||||
|
|
|
|||
|
|
@ -354,6 +354,16 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc,
|
|||
}
|
||||
}
|
||||
|
||||
if (q.flags.q.max_primitives) {
|
||||
if (this->flags.q.max_primitives
|
||||
&& !is_single_layout_merge && !is_multiple_layouts_merge) {
|
||||
this->max_primitives->merge_qualifier(q.max_primitives);
|
||||
} else {
|
||||
this->flags.q.max_primitives = 1;
|
||||
this->max_primitives = q.max_primitives;
|
||||
}
|
||||
}
|
||||
|
||||
if (q.subroutine_list) {
|
||||
if (this->subroutine_list) {
|
||||
_mesa_glsl_error(loc, state,
|
||||
|
|
@ -603,6 +613,8 @@ ast_type_qualifier::validate_out_qualifier(YYLTYPE *loc,
|
|||
break;
|
||||
}
|
||||
}
|
||||
valid_out_mask.flags.q.max_vertices = 1;
|
||||
valid_out_mask.flags.q.max_primitives = 1;
|
||||
valid_out_mask.flags.q.prim_type = 1;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -972,6 +984,7 @@ ast_type_qualifier::validate_flags(YYLTYPE *loc,
|
|||
Q2(non_coherent, noncoherent);
|
||||
Q(task_payload);
|
||||
Q(per_primitive);
|
||||
Q(max_primitives);
|
||||
|
||||
#undef Q
|
||||
#undef Q2
|
||||
|
|
|
|||
|
|
@ -2567,6 +2567,8 @@ link_ms_inout_layout_qualifiers(struct gl_shader_program *prog,
|
|||
if (gl_prog->info.stage != MESA_SHADER_MESH)
|
||||
return;
|
||||
|
||||
int max_vertices = -1;
|
||||
int max_primitives = -1;
|
||||
enum mesa_prim prim_type = MESA_PRIM_UNKNOWN;
|
||||
|
||||
for (unsigned i = 0; i < num_shaders; i++) {
|
||||
|
|
@ -2581,6 +2583,28 @@ link_ms_inout_layout_qualifiers(struct gl_shader_program *prog,
|
|||
}
|
||||
prim_type = shader->info.Mesh.OutputType;
|
||||
}
|
||||
|
||||
if (shader->info.Mesh.MaxVertices != -1) {
|
||||
if (max_vertices != -1 &&
|
||||
max_vertices != shader->info.Mesh.MaxVertices) {
|
||||
linker_error(prog, "mesh shader defined with conflicting "
|
||||
"max_vertices count (%d and %d)\n",
|
||||
max_vertices, shader->info.Mesh.MaxVertices);
|
||||
return;
|
||||
}
|
||||
max_vertices = shader->info.Mesh.MaxVertices;
|
||||
}
|
||||
|
||||
if (shader->info.Mesh.MaxPrimitives != -1) {
|
||||
if (max_primitives != -1 &&
|
||||
max_primitives != shader->info.Mesh.MaxPrimitives) {
|
||||
linker_error(prog, "mesh shader defined with conflicting "
|
||||
"max_primitives count (%d and %d)\n",
|
||||
max_primitives, shader->info.Mesh.MaxPrimitives);
|
||||
return;
|
||||
}
|
||||
max_primitives = shader->info.Mesh.MaxPrimitives;
|
||||
}
|
||||
}
|
||||
|
||||
if (prim_type == MESA_PRIM_UNKNOWN) {
|
||||
|
|
@ -2589,6 +2613,20 @@ link_ms_inout_layout_qualifiers(struct gl_shader_program *prog,
|
|||
} else {
|
||||
gl_prog->nir->info.mesh.primitive_type = prim_type;
|
||||
}
|
||||
|
||||
if (max_vertices == -1) {
|
||||
linker_error(prog, "mesh shader didn't declare max_vertices\n");
|
||||
return;
|
||||
} else {
|
||||
gl_prog->nir->info.mesh.max_vertices_out = max_vertices;
|
||||
}
|
||||
|
||||
if (max_primitives == -1) {
|
||||
linker_error(prog, "mesh shader didn't declare max_primitives\n");
|
||||
return;
|
||||
} else {
|
||||
gl_prog->nir->info.mesh.max_primitives_out = max_primitives;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1816,10 +1816,18 @@ layout_qualifier_id:
|
|||
if (match_layout_qualifier("max_vertices", $1, state) == 0) {
|
||||
$$.flags.q.max_vertices = 1;
|
||||
$$.max_vertices = new(ctx) ast_layout_expression(@1, $3);
|
||||
if (!state->has_geometry_shader()) {
|
||||
if (!state->has_geometry_shader() && !state->EXT_mesh_shader_enable) {
|
||||
_mesa_glsl_error(& @3, state,
|
||||
"#version 150 max_vertices qualifier "
|
||||
"specified");
|
||||
"max_vertices qualifier specified");
|
||||
}
|
||||
}
|
||||
|
||||
if (match_layout_qualifier("max_primitives", $1, state) == 0) {
|
||||
$$.flags.q.max_primitives = 1;
|
||||
$$.max_primitives = new(ctx) ast_layout_expression(@1, $3);
|
||||
if (!state->EXT_mesh_shader_enable) {
|
||||
_mesa_glsl_error(& @3, state,
|
||||
"max_primitives qualifier specified");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2106,6 +2106,42 @@ set_shader_inout_layout(struct gl_shader *shader,
|
|||
} else {
|
||||
shader->info.Mesh.OutputType = MESA_PRIM_UNKNOWN;
|
||||
}
|
||||
|
||||
shader->info.Mesh.MaxVertices = -1;
|
||||
if (state->out_qualifier->flags.q.max_vertices) {
|
||||
unsigned qual_max_vertices;
|
||||
if (state->out_qualifier->max_vertices->
|
||||
process_qualifier_constant(state, "max_vertices",
|
||||
&qual_max_vertices, true)) {
|
||||
|
||||
if (qual_max_vertices > state->caps->mesh.max_mesh_output_vertices) {
|
||||
YYLTYPE loc = state->out_qualifier->max_vertices->get_location();
|
||||
_mesa_glsl_error(&loc, state,
|
||||
"maximum output vertices (%d) exceeds "
|
||||
"GL_MAX_MESH_OUTPUT_VERTICES_EXT",
|
||||
qual_max_vertices);
|
||||
}
|
||||
shader->info.Mesh.MaxVertices = qual_max_vertices;
|
||||
}
|
||||
}
|
||||
|
||||
shader->info.Mesh.MaxPrimitives = -1;
|
||||
if (state->out_qualifier->flags.q.max_primitives) {
|
||||
unsigned qual_max_primitives;
|
||||
if (state->out_qualifier->max_primitives->
|
||||
process_qualifier_constant(state, "max_primitives",
|
||||
&qual_max_primitives, true)) {
|
||||
|
||||
if (qual_max_primitives > state->caps->mesh.max_mesh_output_primitives) {
|
||||
YYLTYPE loc = state->out_qualifier->max_primitives->get_location();
|
||||
_mesa_glsl_error(&loc, state,
|
||||
"maximum output primitives (%d) exceeds "
|
||||
"GL_MAX_MESH_OUTPUT_PRIMITIVES_EXT",
|
||||
qual_max_primitives);
|
||||
}
|
||||
shader->info.Mesh.MaxPrimitives = qual_max_primitives;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -138,6 +138,9 @@ struct gl_shader_info
|
|||
*/
|
||||
struct {
|
||||
enum mesa_prim OutputType;
|
||||
|
||||
GLint MaxVertices;
|
||||
GLint MaxPrimitives;
|
||||
} Mesh;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue