mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-11 06:28:09 +02:00
glsl: Move interface block processing to glsl_parser_extras.cpp
No functional changes. Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
This commit is contained in:
parent
9c1f10b1bc
commit
3763a0e0a7
3 changed files with 128 additions and 126 deletions
|
|
@ -1172,4 +1172,9 @@ extern void
|
|||
check_builtin_array_max_size(const char *name, unsigned size,
|
||||
YYLTYPE loc, struct _mesa_glsl_parse_state *state);
|
||||
|
||||
extern void _mesa_ast_process_interface_block(YYLTYPE *locp,
|
||||
_mesa_glsl_parse_state *state,
|
||||
ast_interface_block *const block,
|
||||
const struct ast_type_qualifier q);
|
||||
|
||||
#endif /* AST_H */
|
||||
|
|
|
|||
|
|
@ -2634,132 +2634,7 @@ basic_interface_block:
|
|||
block->block_name = $2;
|
||||
block->declarations.push_degenerate_list_at_head(& $4->link);
|
||||
|
||||
if ($1.flags.q.buffer) {
|
||||
if (!state->has_shader_storage_buffer_objects()) {
|
||||
_mesa_glsl_error(& @1, state,
|
||||
"#version 430 / GL_ARB_shader_storage_buffer_object "
|
||||
"required for defining shader storage blocks");
|
||||
} else if (state->ARB_shader_storage_buffer_object_warn) {
|
||||
_mesa_glsl_warning(& @1, state,
|
||||
"#version 430 / GL_ARB_shader_storage_buffer_object "
|
||||
"required for defining shader storage blocks");
|
||||
}
|
||||
} else if ($1.flags.q.uniform) {
|
||||
if (!state->has_uniform_buffer_objects()) {
|
||||
_mesa_glsl_error(& @1, state,
|
||||
"#version 140 / GL_ARB_uniform_buffer_object "
|
||||
"required for defining uniform blocks");
|
||||
} else if (state->ARB_uniform_buffer_object_warn) {
|
||||
_mesa_glsl_warning(& @1, state,
|
||||
"#version 140 / GL_ARB_uniform_buffer_object "
|
||||
"required for defining uniform blocks");
|
||||
}
|
||||
} else {
|
||||
if (state->es_shader || state->language_version < 150) {
|
||||
_mesa_glsl_error(& @1, state,
|
||||
"#version 150 required for using "
|
||||
"interface blocks");
|
||||
}
|
||||
}
|
||||
|
||||
/* From the GLSL 1.50.11 spec, section 4.3.7 ("Interface Blocks"):
|
||||
* "It is illegal to have an input block in a vertex shader
|
||||
* or an output block in a fragment shader"
|
||||
*/
|
||||
if ((state->stage == MESA_SHADER_VERTEX) && $1.flags.q.in) {
|
||||
_mesa_glsl_error(& @1, state,
|
||||
"`in' interface block is not allowed for "
|
||||
"a vertex shader");
|
||||
} else if ((state->stage == MESA_SHADER_FRAGMENT) && $1.flags.q.out) {
|
||||
_mesa_glsl_error(& @1, state,
|
||||
"`out' interface block is not allowed for "
|
||||
"a fragment shader");
|
||||
}
|
||||
|
||||
/* Since block arrays require names, and both features are added in
|
||||
* the same language versions, we don't have to explicitly
|
||||
* version-check both things.
|
||||
*/
|
||||
if (block->instance_name != NULL) {
|
||||
state->check_version(150, 300, & @1, "interface blocks with "
|
||||
"an instance name are not allowed");
|
||||
}
|
||||
|
||||
uint64_t interface_type_mask;
|
||||
struct ast_type_qualifier temp_type_qualifier;
|
||||
|
||||
/* Get a bitmask containing only the in/out/uniform/buffer
|
||||
* flags, allowing us to ignore other irrelevant flags like
|
||||
* interpolation qualifiers.
|
||||
*/
|
||||
temp_type_qualifier.flags.i = 0;
|
||||
temp_type_qualifier.flags.q.uniform = true;
|
||||
temp_type_qualifier.flags.q.buffer = true;
|
||||
temp_type_qualifier.flags.q.in = true;
|
||||
temp_type_qualifier.flags.q.out = true;
|
||||
interface_type_mask = temp_type_qualifier.flags.i;
|
||||
|
||||
/* Get the block's interface qualifier. The interface_qualifier
|
||||
* production rule guarantees that only one bit will be set (and
|
||||
* it will be in/out/uniform).
|
||||
*/
|
||||
uint64_t block_interface_qualifier = $1.flags.i;
|
||||
|
||||
block->layout.flags.i |= block_interface_qualifier;
|
||||
|
||||
if (state->stage == MESA_SHADER_GEOMETRY &&
|
||||
state->has_explicit_attrib_stream()) {
|
||||
/* Assign global layout's stream value. */
|
||||
block->layout.flags.q.stream = 1;
|
||||
block->layout.flags.q.explicit_stream = 0;
|
||||
block->layout.stream = state->out_qualifier->stream;
|
||||
}
|
||||
|
||||
foreach_list_typed (ast_declarator_list, member, link, &block->declarations) {
|
||||
ast_type_qualifier& qualifier = member->type->qualifier;
|
||||
if ((qualifier.flags.i & interface_type_mask) == 0) {
|
||||
/* GLSLangSpec.1.50.11, 4.3.7 (Interface Blocks):
|
||||
* "If no optional qualifier is used in a member declaration, the
|
||||
* qualifier of the variable is just in, out, or uniform as declared
|
||||
* by interface-qualifier."
|
||||
*/
|
||||
qualifier.flags.i |= block_interface_qualifier;
|
||||
} else if ((qualifier.flags.i & interface_type_mask) !=
|
||||
block_interface_qualifier) {
|
||||
/* GLSLangSpec.1.50.11, 4.3.7 (Interface Blocks):
|
||||
* "If optional qualifiers are used, they can include interpolation
|
||||
* and storage qualifiers and they must declare an input, output,
|
||||
* or uniform variable consistent with the interface qualifier of
|
||||
* the block."
|
||||
*/
|
||||
_mesa_glsl_error(& @1, state,
|
||||
"uniform/in/out qualifier on "
|
||||
"interface block member does not match "
|
||||
"the interface block");
|
||||
}
|
||||
|
||||
/* From GLSL ES 3.0, chapter 4.3.7 "Interface Blocks":
|
||||
*
|
||||
* "GLSL ES 3.0 does not support interface blocks for shader inputs or
|
||||
* outputs."
|
||||
*
|
||||
* And from GLSL ES 3.0, chapter 4.6.1 "The invariant qualifier":.
|
||||
*
|
||||
* "Only variables output from a shader can be candidates for
|
||||
* invariance."
|
||||
*
|
||||
* From GLSL 4.40 and GLSL 1.50, section "Interface Blocks":
|
||||
*
|
||||
* "If optional qualifiers are used, they can include interpolation
|
||||
* qualifiers, auxiliary storage qualifiers, and storage qualifiers
|
||||
* and they must declare an input, output, or uniform member
|
||||
* consistent with the interface qualifier of the block"
|
||||
*/
|
||||
if (qualifier.flags.q.invariant)
|
||||
_mesa_glsl_error(&@1, state,
|
||||
"invariant qualifiers cannot be used "
|
||||
"with interface blocks members");
|
||||
}
|
||||
_mesa_ast_process_interface_block(& @1, state, block, $1);
|
||||
|
||||
$$ = block;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -859,6 +859,128 @@ _mesa_ast_set_aggregate_type(const glsl_type *type,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
_mesa_ast_process_interface_block(YYLTYPE *locp,
|
||||
_mesa_glsl_parse_state *state,
|
||||
ast_interface_block *const block,
|
||||
const struct ast_type_qualifier q)
|
||||
{
|
||||
if (q.flags.q.uniform) {
|
||||
if (!state->has_uniform_buffer_objects()) {
|
||||
_mesa_glsl_error(locp, state,
|
||||
"#version 140 / GL_ARB_uniform_buffer_object "
|
||||
"required for defining uniform blocks");
|
||||
} else if (state->ARB_uniform_buffer_object_warn) {
|
||||
_mesa_glsl_warning(locp, state,
|
||||
"#version 140 / GL_ARB_uniform_buffer_object "
|
||||
"required for defining uniform blocks");
|
||||
}
|
||||
} else {
|
||||
if (state->es_shader || state->language_version < 150) {
|
||||
_mesa_glsl_error(locp, state,
|
||||
"#version 150 required for using "
|
||||
"interface blocks");
|
||||
}
|
||||
}
|
||||
|
||||
/* From the GLSL 1.50.11 spec, section 4.3.7 ("Interface Blocks"):
|
||||
* "It is illegal to have an input block in a vertex shader
|
||||
* or an output block in a fragment shader"
|
||||
*/
|
||||
if ((state->stage == MESA_SHADER_VERTEX) && q.flags.q.in) {
|
||||
_mesa_glsl_error(locp, state,
|
||||
"`in' interface block is not allowed for "
|
||||
"a vertex shader");
|
||||
} else if ((state->stage == MESA_SHADER_FRAGMENT) && q.flags.q.out) {
|
||||
_mesa_glsl_error(locp, state,
|
||||
"`out' interface block is not allowed for "
|
||||
"a fragment shader");
|
||||
}
|
||||
|
||||
/* Since block arrays require names, and both features are added in
|
||||
* the same language versions, we don't have to explicitly
|
||||
* version-check both things.
|
||||
*/
|
||||
if (block->instance_name != NULL) {
|
||||
state->check_version(150, 300, locp, "interface blocks with "
|
||||
"an instance name are not allowed");
|
||||
}
|
||||
|
||||
uint64_t interface_type_mask;
|
||||
struct ast_type_qualifier temp_type_qualifier;
|
||||
|
||||
/* Get a bitmask containing only the in/out/uniform
|
||||
* flags, allowing us to ignore other irrelevant flags like
|
||||
* interpolation qualifiers.
|
||||
*/
|
||||
temp_type_qualifier.flags.i = 0;
|
||||
temp_type_qualifier.flags.q.uniform = true;
|
||||
temp_type_qualifier.flags.q.in = true;
|
||||
temp_type_qualifier.flags.q.out = true;
|
||||
interface_type_mask = temp_type_qualifier.flags.i;
|
||||
|
||||
/* Get the block's interface qualifier. The interface_qualifier
|
||||
* production rule guarantees that only one bit will be set (and
|
||||
* it will be in/out/uniform).
|
||||
*/
|
||||
uint64_t block_interface_qualifier = q.flags.i;
|
||||
|
||||
block->layout.flags.i |= block_interface_qualifier;
|
||||
|
||||
if (state->stage == MESA_SHADER_GEOMETRY &&
|
||||
state->has_explicit_attrib_stream()) {
|
||||
/* Assign global layout's stream value. */
|
||||
block->layout.flags.q.stream = 1;
|
||||
block->layout.flags.q.explicit_stream = 0;
|
||||
block->layout.stream = state->out_qualifier->stream;
|
||||
}
|
||||
|
||||
foreach_list_typed (ast_declarator_list, member, link, &block->declarations) {
|
||||
ast_type_qualifier& qualifier = member->type->qualifier;
|
||||
if ((qualifier.flags.i & interface_type_mask) == 0) {
|
||||
/* GLSLangSpec.1.50.11, 4.3.7 (Interface Blocks):
|
||||
* "If no optional qualifier is used in a member declaration, the
|
||||
* qualifier of the variable is just in, out, or uniform as declared
|
||||
* by interface-qualifier."
|
||||
*/
|
||||
qualifier.flags.i |= block_interface_qualifier;
|
||||
} else if ((qualifier.flags.i & interface_type_mask) !=
|
||||
block_interface_qualifier) {
|
||||
/* GLSLangSpec.1.50.11, 4.3.7 (Interface Blocks):
|
||||
* "If optional qualifiers are used, they can include interpolation
|
||||
* and storage qualifiers and they must declare an input, output,
|
||||
* or uniform variable consistent with the interface qualifier of
|
||||
* the block."
|
||||
*/
|
||||
_mesa_glsl_error(locp, state,
|
||||
"uniform/in/out qualifier on "
|
||||
"interface block member does not match "
|
||||
"the interface block");
|
||||
}
|
||||
|
||||
/* From GLSL ES 3.0, chapter 4.3.7 "Interface Blocks":
|
||||
*
|
||||
* "GLSL ES 3.0 does not support interface blocks for shader inputs or
|
||||
* outputs."
|
||||
*
|
||||
* And from GLSL ES 3.0, chapter 4.6.1 "The invariant qualifier":.
|
||||
*
|
||||
* "Only variables output from a shader can be candidates for
|
||||
* invariance."
|
||||
*
|
||||
* From GLSL 4.40 and GLSL 1.50, section "Interface Blocks":
|
||||
*
|
||||
* "If optional qualifiers are used, they can include interpolation
|
||||
* qualifiers, auxiliary storage qualifiers, and storage qualifiers
|
||||
* and they must declare an input, output, or uniform member
|
||||
* consistent with the interface qualifier of the block"
|
||||
*/
|
||||
if (qualifier.flags.q.invariant)
|
||||
_mesa_glsl_error(locp, state,
|
||||
"invariant qualifiers cannot be used "
|
||||
"with interface blocks members");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_mesa_ast_type_qualifier_print(const struct ast_type_qualifier *q)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue