mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-04 20:38:06 +02:00
glsl: handle PerPrimitiveEXT qualifier
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
b2e9a6d935
commit
6415cec230
17 changed files with 89 additions and 10 deletions
|
|
@ -680,6 +680,7 @@ struct ast_type_qualifier {
|
|||
|
||||
/** GL_EXT_mesh_shader */
|
||||
unsigned task_payload:1;
|
||||
unsigned per_primitive:1;
|
||||
}
|
||||
/** \brief Set of flags, accessed by name. */
|
||||
q;
|
||||
|
|
|
|||
|
|
@ -4413,6 +4413,28 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
|
|||
"with task and mesh shaders");
|
||||
}
|
||||
|
||||
if (qual->flags.q.per_primitive) {
|
||||
if (state->stage == MESA_SHADER_MESH) {
|
||||
if (var->data.mode != ir_var_shader_out) {
|
||||
_mesa_glsl_error(loc, state,
|
||||
"the perprimitiveEXT auxiliary storage qualifier can only be "
|
||||
"used on `out` variables with mesh shader");
|
||||
}
|
||||
} else if (state->stage == MESA_SHADER_FRAGMENT) {
|
||||
if (var->data.mode != ir_var_shader_in) {
|
||||
_mesa_glsl_error(loc, state,
|
||||
"the perprimitiveEXT auxiliary storage qualifier can only be "
|
||||
"used on `in` variables with fragment shader");
|
||||
}
|
||||
} else {
|
||||
_mesa_glsl_error(loc, state,
|
||||
"the perprimitiveEXT auxiliary storage qualifier can only be "
|
||||
"used with mesh and fragment shaders");
|
||||
}
|
||||
|
||||
var->data.per_primitive = 1;
|
||||
}
|
||||
|
||||
apply_image_qualifier_to_variable(qual, var, state, loc);
|
||||
}
|
||||
|
||||
|
|
@ -7732,6 +7754,7 @@ ast_process_struct_or_iface_block_members(ir_exec_list *instructions,
|
|||
fields[i].centroid = qual->flags.q.centroid ? 1 : 0;
|
||||
fields[i].sample = qual->flags.q.sample ? 1 : 0;
|
||||
fields[i].patch = qual->flags.q.patch ? 1 : 0;
|
||||
fields[i].per_primitive = qual->flags.q.per_primitive ? 1 : 0;
|
||||
fields[i].offset = -1;
|
||||
fields[i].explicit_xfb_buffer = explicit_xfb_buffer;
|
||||
fields[i].xfb_buffer = xfb_buffer;
|
||||
|
|
@ -8161,14 +8184,17 @@ ast_interface_block::hir(ir_exec_list *instructions,
|
|||
if (state->stage == MESA_SHADER_GEOMETRY) {
|
||||
allowed_blk_qualifiers.flags.q.stream = 1;
|
||||
allowed_blk_qualifiers.flags.q.explicit_stream = 1;
|
||||
}
|
||||
if (state->stage == MESA_SHADER_TESS_CTRL) {
|
||||
} else if (state->stage == MESA_SHADER_TESS_CTRL) {
|
||||
allowed_blk_qualifiers.flags.q.patch = 1;
|
||||
} else if (state->stage == MESA_SHADER_MESH) {
|
||||
allowed_blk_qualifiers.flags.q.per_primitive = 1;
|
||||
}
|
||||
} else {
|
||||
allowed_blk_qualifiers.flags.q.in = 1;
|
||||
if (state->stage == MESA_SHADER_TESS_EVAL) {
|
||||
allowed_blk_qualifiers.flags.q.patch = 1;
|
||||
} else if (state->stage == MESA_SHADER_FRAGMENT) {
|
||||
allowed_blk_qualifiers.flags.q.per_primitive = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8414,6 +8440,8 @@ ast_interface_block::hir(ir_exec_list *instructions,
|
|||
earlier_per_vertex->fields.structure[j].sample;
|
||||
fields[i].patch =
|
||||
earlier_per_vertex->fields.structure[j].patch;
|
||||
fields[i].per_primitive =
|
||||
earlier_per_vertex->fields.structure[j].per_primitive;
|
||||
fields[i].precision =
|
||||
earlier_per_vertex->fields.structure[j].precision;
|
||||
fields[i].explicit_xfb_buffer =
|
||||
|
|
@ -8660,6 +8688,7 @@ ast_interface_block::hir(ir_exec_list *instructions,
|
|||
var->data.read_only = true;
|
||||
|
||||
var->data.patch = this->layout.flags.q.patch;
|
||||
var->data.per_primitive = this->layout.flags.q.per_primitive;
|
||||
|
||||
if (state->stage == MESA_SHADER_GEOMETRY && var_mode == ir_var_shader_in)
|
||||
handle_geometry_shader_input_decl(state, loc, var);
|
||||
|
|
@ -8715,6 +8744,7 @@ ast_interface_block::hir(ir_exec_list *instructions,
|
|||
var->data.patch = fields[i].patch;
|
||||
var->data.stream = qual_stream;
|
||||
var->data.location = fields[i].location;
|
||||
var->data.per_primitive = fields[i].per_primitive;
|
||||
|
||||
if (fields[i].location != -1)
|
||||
var->data.explicit_location = true;
|
||||
|
|
|
|||
|
|
@ -107,7 +107,8 @@ ast_type_qualifier::has_auxiliary_storage() const
|
|||
{
|
||||
return this->flags.q.centroid
|
||||
|| this->flags.q.sample
|
||||
|| this->flags.q.patch;
|
||||
|| this->flags.q.patch
|
||||
|| this->flags.q.per_primitive;
|
||||
}
|
||||
|
||||
bool ast_type_qualifier::has_memory() const
|
||||
|
|
@ -295,6 +296,7 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc,
|
|||
input_layout_mask.flags.q.smooth = 1;
|
||||
input_layout_mask.flags.q.non_coherent = 1;
|
||||
input_layout_mask.flags.q.explicit_numviews = 1;
|
||||
input_layout_mask.flags.q.per_primitive = 1;
|
||||
|
||||
if (state->has_bindless()) {
|
||||
/* Allow to use image qualifiers with shader inputs/outputs. */
|
||||
|
|
@ -952,6 +954,7 @@ ast_type_qualifier::validate_flags(YYLTYPE *loc,
|
|||
Q(sample_interlock_unordered);
|
||||
Q2(non_coherent, noncoherent);
|
||||
Q(task_payload);
|
||||
Q(per_primitive);
|
||||
|
||||
#undef Q
|
||||
#undef Q2
|
||||
|
|
|
|||
|
|
@ -286,6 +286,9 @@ interstage_member_mismatch(struct gl_shader_program *prog,
|
|||
if (c->fields.structure[i].patch !=
|
||||
p->fields.structure[i].patch)
|
||||
return true;
|
||||
if (c->fields.structure[i].per_primitive !=
|
||||
p->fields.structure[i].per_primitive)
|
||||
return true;
|
||||
|
||||
/* From Section 4.5 (Interpolation Qualifiers) of the GLSL 4.40 spec:
|
||||
*
|
||||
|
|
|
|||
|
|
@ -689,6 +689,7 @@ create_shader_variable(struct gl_shader_program *shProg,
|
|||
out->interpolation = in->data.interpolation;
|
||||
out->precision = in->data.precision;
|
||||
out->explicit_location = in->data.explicit_location;
|
||||
out->per_primitive = in->data.per_primitive;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -289,6 +289,7 @@ lower_named_interface_blocks(struct gl_linked_shader *sh)
|
|||
new_var->data.centroid = field_data->centroid;
|
||||
new_var->data.sample = field_data->sample;
|
||||
new_var->data.patch = field_data->patch;
|
||||
new_var->data.per_primitive = field_data->per_primitive;
|
||||
new_var->data.stream = var->data.stream;
|
||||
new_var->data.how_declared = var->data.how_declared;
|
||||
new_var->data.from_named_ifc_block = 1;
|
||||
|
|
|
|||
|
|
@ -294,6 +294,7 @@ create_or_update_packed_varying(struct lower_packed_varyings_state *state,
|
|||
packed_var->data.centroid = unpacked_var->data.centroid;
|
||||
packed_var->data.sample = unpacked_var->data.sample;
|
||||
packed_var->data.patch = unpacked_var->data.patch;
|
||||
packed_var->data.per_primitive = unpacked_var->data.per_primitive;
|
||||
packed_var->data.interpolation = is_interpolation_flat ?
|
||||
(unsigned) INTERP_MODE_FLAT : unpacked_var->data.interpolation;
|
||||
packed_var->data.location = location;
|
||||
|
|
|
|||
|
|
@ -558,6 +558,13 @@ taskPayloadSharedEXT {
|
|||
return classify_identifier(yyextra, yytext, yyleng, yylval);
|
||||
}
|
||||
|
||||
perprimitiveEXT {
|
||||
if (yyextra->EXT_mesh_shader_enable)
|
||||
return PERPRIMITIVE;
|
||||
else
|
||||
return classify_identifier(yyextra, yytext, yyleng, yylval);
|
||||
}
|
||||
|
||||
struct return STRUCT;
|
||||
void return VOID_TOK;
|
||||
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ static bool match_layout_qualifier(const char *s1, const char *s2,
|
|||
%token IMAGE1DSHADOW IMAGE2DSHADOW IMAGE1DARRAYSHADOW IMAGE2DARRAYSHADOW
|
||||
%token COHERENT VOLATILE RESTRICT READONLY WRITEONLY
|
||||
%token SHARED
|
||||
%token TASKPAYLOAD
|
||||
%token TASKPAYLOAD PERPRIMITIVE
|
||||
%token STRUCT VOID_TOK WHILE
|
||||
%token <identifier> IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
|
||||
%type <identifier> any_identifier
|
||||
|
|
@ -2190,6 +2190,11 @@ auxiliary_storage_qualifier:
|
|||
memset(& $$, 0, sizeof($$));
|
||||
$$.flags.q.patch = 1;
|
||||
}
|
||||
| PERPRIMITIVE
|
||||
{
|
||||
memset(& $$, 0, sizeof($$));
|
||||
$$.flags.q.per_primitive = 1;
|
||||
}
|
||||
|
||||
storage_qualifier:
|
||||
CONST_TOK
|
||||
|
|
@ -2951,14 +2956,15 @@ interface_qualifier:
|
|||
}
|
||||
| auxiliary_storage_qualifier interface_qualifier
|
||||
{
|
||||
if (!$1.flags.q.patch) {
|
||||
if (!$1.flags.q.patch && !$1.flags.q.per_primitive) {
|
||||
_mesa_glsl_error(&@1, state, "invalid interface qualifier");
|
||||
}
|
||||
if ($2.has_auxiliary_storage()) {
|
||||
_mesa_glsl_error(&@1, state, "duplicate patch qualifier");
|
||||
_mesa_glsl_error(&@1, state, "duplicate auxiliary storage qualifier");
|
||||
}
|
||||
$$ = $2;
|
||||
$$.flags.q.patch = 1;
|
||||
$$.flags.q.patch = $1.flags.q.patch;
|
||||
$$.flags.q.per_primitive = $1.flags.q.per_primitive;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
|||
|
|
@ -1217,6 +1217,7 @@ _mesa_ast_process_interface_block(YYLTYPE *locp,
|
|||
temp_type_qualifier.flags.q.out = true;
|
||||
temp_type_qualifier.flags.q.buffer = true;
|
||||
temp_type_qualifier.flags.q.patch = true;
|
||||
temp_type_qualifier.flags.q.per_primitive = true;
|
||||
interface_type_mask = temp_type_qualifier.flags.i;
|
||||
|
||||
/* Get the block's interface qualifier. The interface_qualifier
|
||||
|
|
@ -1325,6 +1326,8 @@ _mesa_ast_type_qualifier_print(const struct ast_type_qualifier *q)
|
|||
printf("flat ");
|
||||
if (q->flags.q.noperspective)
|
||||
printf("noperspective ");
|
||||
if (q->flags.q.per_primitive)
|
||||
printf("per_primitive ");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -471,6 +471,7 @@ nir_visitor::visit(ir_variable *ir)
|
|||
var->data.max_array_access = ir->data.max_array_access;
|
||||
var->data.implicit_sized_array = ir->data.implicit_sized_array;
|
||||
var->data.from_ssbo_unsized_array = ir->data.from_ssbo_unsized_array;
|
||||
var->data.per_primitive = ir->data.per_primitive;
|
||||
|
||||
switch(ir->data.mode) {
|
||||
case ir_var_auto:
|
||||
|
|
|
|||
|
|
@ -2020,6 +2020,7 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *name,
|
|||
this->data.xfb_buffer = -1;
|
||||
this->data.xfb_stride = -1;
|
||||
this->data.implicit_conversion_prohibited = false;
|
||||
this->data.per_primitive = false;
|
||||
|
||||
this->interface_type = NULL;
|
||||
|
||||
|
|
@ -2115,6 +2116,7 @@ ir_function_signature::qualifiers_match(ir_exec_list *params)
|
|||
a->data.centroid != b->data.centroid ||
|
||||
a->data.sample != b->data.sample ||
|
||||
a->data.patch != b->data.patch ||
|
||||
a->data.per_primitive != b->data.per_primitive ||
|
||||
a->data.memory_read_only != b->data.memory_read_only ||
|
||||
a->data.memory_write_only != b->data.memory_write_only ||
|
||||
a->data.memory_coherent != b->data.memory_coherent ||
|
||||
|
|
|
|||
|
|
@ -858,6 +858,11 @@ public:
|
|||
*/
|
||||
unsigned implicit_conversion_prohibited:1;
|
||||
|
||||
/**
|
||||
* Non-zero if the variable is per-primitive as defined by EXT_mesh_shader
|
||||
*/
|
||||
unsigned per_primitive:1;
|
||||
|
||||
/**
|
||||
* Emit a warning if this variable is accessed.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -212,17 +212,18 @@ void ir_print_visitor::visit(ir_variable *ir)
|
|||
"shader_shared ", "task_payload ", "shader_in ", "shader_out ",
|
||||
"in ", "out ", "inout ",
|
||||
"const_in ", "sys ", "temporary " };
|
||||
const char *const per_primitive = (ir->data.per_primitive) ? "per_primitive " : "";
|
||||
STATIC_ASSERT(ARRAY_SIZE(mode) == ir_var_mode_count);
|
||||
const char *const interp[] = { "", "smooth", "flat", "noperspective", "explicit" };
|
||||
STATIC_ASSERT(ARRAY_SIZE(interp) == INTERP_MODE_COUNT);
|
||||
const char *const precision[] = { "", "highp ", "mediump ", "lowp "};
|
||||
|
||||
fprintf(f, "(%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s) ",
|
||||
fprintf(f, "(%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s) ",
|
||||
binding, loc, component, cent, bindless, bound,
|
||||
image_format, memory_read_only, memory_write_only,
|
||||
memory_coherent, memory_volatile, memory_restrict,
|
||||
samp, patc, inv, explicit_inv, prec, mode[ir->data.mode],
|
||||
stream,
|
||||
samp, patc, inv, explicit_inv, prec, per_primitive,
|
||||
mode[ir->data.mode], stream,
|
||||
interp[ir->data.interpolation], precision[ir->data.precision]);
|
||||
|
||||
glsl_print_type(f, ir->type);
|
||||
|
|
|
|||
|
|
@ -1506,6 +1506,9 @@ glsl_record_compare(const glsl_type *a, const glsl_type *b, bool match_name,
|
|||
if (a->fields.structure[i].xfb_stride
|
||||
!= b->fields.structure[i].xfb_stride)
|
||||
return false;
|
||||
if (a->fields.structure[i].per_primitive
|
||||
!= b->fields.structure[i].per_primitive)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -484,6 +484,12 @@ struct glsl_struct_field {
|
|||
unsigned explicit_xfb_buffer:1;
|
||||
|
||||
unsigned implicit_sized_array:1;
|
||||
|
||||
/**
|
||||
* For interface blocks, 1 if this variable is a per-primitive input or output
|
||||
* (as in ir_variable::patch). 0 otherwise.
|
||||
*/
|
||||
unsigned per_primitive:1;
|
||||
};
|
||||
unsigned flags;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1170,6 +1170,11 @@ struct gl_shader_variable
|
|||
* Precision qualifier.
|
||||
*/
|
||||
unsigned precision:2;
|
||||
|
||||
/**
|
||||
* Per-primitive qualifier
|
||||
*/
|
||||
unsigned per_primitive:1;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue