[Mesa-dev] [PATCH 03/11] mesa: Strip arrayness from interface block names in some IO validation
Timothy Arceri
timothy.arceri at collabora.com
Wed Jun 15 03:34:33 UTC 2016
On Tue, 2016-06-14 at 19:01 -0700, Ian Romanick wrote:
> From: Ian Romanick <ian.d.romanick at intel.com>
>
> Outputs from the vertex shader need to be able to match
> per-vertex-arrayed inputs of later stages. Acomplish this by
> stripping
> one level of arrayness from the names and types of outputs going to a
> per-vertex-arrayed stage.
>
> Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96358
> Cc: "12.0" <mesa-stable at lists.freedesktop.org>
> Cc: Gregory Hainaut <gregory.hainaut at gmail.com>
> Cc: Ilia Mirkin <imirkin at alum.mit.edu>
> ---
> src/mesa/main/shader_query.cpp | 98
> ++++++++++++++++++++++++++++++++++++++----
> 1 file changed, 90 insertions(+), 8 deletions(-)
>
> diff --git a/src/mesa/main/shader_query.cpp
> b/src/mesa/main/shader_query.cpp
> index 5956ce4..b2e53fb 100644
> --- a/src/mesa/main/shader_query.cpp
> +++ b/src/mesa/main/shader_query.cpp
> @@ -1385,13 +1385,24 @@ _mesa_get_program_resourceiv(struct
> gl_shader_program *shProg,
>
> static bool
> validate_io(struct gl_shader_program *producer,
> - struct gl_shader_program *consumer)
> + struct gl_shader_program *consumer,
> + gl_shader_stage producer_stage,
> + gl_shader_stage consumer_stage)
> {
> if (producer == consumer)
> return true;
>
> + const bool nonarray_stage_to_array_stage =
> + producer_stage == MESA_SHADER_VERTEX &&
> + (consumer_stage == MESA_SHADER_GEOMETRY ||
> + consumer_stage == MESA_SHADER_TESS_CTRL ||
> + consumer_stage == MESA_SHADER_TESS_EVAL);
TESS_EVAL->GEOM ?
> +
> bool valid = true;
>
> + void *name_buffer = NULL;
> + size_t name_buffer_size = 0;
> +
> gl_shader_variable const **outputs =
> (gl_shader_variable const **) calloc(producer-
> >NumProgramResourceList,
> sizeof(gl_shader_variable
> *));
> @@ -1463,11 +1474,52 @@ validate_io(struct gl_shader_program
> *producer,
> }
> }
> } else {
> + char *consumer_name = consumer_var->name;
> +
> + if (nonarray_stage_to_array_stage &&
> + consumer_var->interface_type != NULL &&
> + consumer_var->interface_type->is_array() &&
> + !is_gl_identifier(consumer_var->name)) {
> + const size_t name_len = strlen(consumer_var->name);
> +
> + if (name_len >= name_buffer_size) {
> + free(name_buffer);
> +
> + name_buffer_size = name_len + 1;
> + name_buffer = malloc(name_buffer_size);
> + if (name_buffer == NULL) {
> + valid = false;
> + goto out;
> + }
> + }
> +
> + consumer_name = (char *) name_buffer;
> +
> + char *s = strchr(consumer_var->name, '[');
> + if (s == NULL) {
> + valid = false;
> + goto out;
> + }
> +
> + char *t = strchr(s, ']');
> + if (t == NULL) {
> + valid = false;
> + goto out;
> + }
> +
> + assert(t[1] == '.' || t[1] == '[');
> +
> + const ptrdiff_t base_name_len = s - consumer_var->name;
> +
> + memcpy(consumer_name, consumer_var->name,
> base_name_len);
> + strcpy(consumer_name + base_name_len, t + 1);
> + }
> +
> for (unsigned j = 0; j < num_outputs; j++) {
> const gl_shader_variable *const var = outputs[j];
>
> if (!var->explicit_location &&
> - strcmp(consumer_var->name, var->name) == 0) {
> + strcmp(consumer_name, var->name) == 0) {
> producer_var = var;
> match_index = j;
> break;
> @@ -1529,25 +1581,53 @@ validate_io(struct gl_shader_program
> *producer,
> * Note that location mismatches are detected by the loops
> above that
> * find the producer variable that goes with the consumer
> variable.
> */
> - if (producer_var->type != consumer_var->type ||
> - producer_var->interpolation != consumer_var->interpolation
> ||
> - producer_var->precision != consumer_var->precision) {
> + if (nonarray_stage_to_array_stage) {
> + if (!consumer_var->type->is_array() ||
> + consumer_var->type->fields.array != producer_var->type)
> {
> + valid = false;
> + goto out;
> + }
> +
> + if (consumer_var->interface_type != NULL) {
> + if (!consumer_var->interface_type->is_array() ||
> + consumer_var->interface_type->fields.array !=
> producer_var->interface_type) {
> + valid = false;
> + goto out;
> + }
> + } else if (producer_var->interface_type != NULL) {
> + valid = false;
> + goto out;
> + }
> + } else {
> + if (producer_var->type != consumer_var->type) {
> + valid = false;
> + goto out;
> + }
> +
> + if (producer_var->interface_type != consumer_var-
> >interface_type) {
> + valid = false;
> + goto out;
> + }
> + }
> +
> + if (producer_var->interpolation != consumer_var-
> >interpolation) {
> valid = false;
> goto out;
> }
>
> - if (producer_var->outermost_struct_type != consumer_var-
> >outermost_struct_type) {
> + if (producer_var->precision != consumer_var->precision) {
> valid = false;
> goto out;
> }
>
> - if (producer_var->interface_type != consumer_var-
> >interface_type) {
> + if (producer_var->outermost_struct_type != consumer_var-
> >outermost_struct_type) {
> valid = false;
> goto out;
> }
> }
>
> out:
> + free(name_buffer);
> free(outputs);
> return valid && num_outputs == 0;
> }
> @@ -1579,7 +1659,9 @@ _mesa_validate_pipeline_io(struct
> gl_pipeline_object *pipeline)
> if (shProg[idx]->_LinkedShaders[idx]->Stage ==
> MESA_SHADER_COMPUTE)
> break;
>
> - if (!validate_io(shProg[prev], shProg[idx]))
> + if (!validate_io(shProg[prev], shProg[idx],
> + shProg[prev]->_LinkedShaders[prev]->Stage,
> + shProg[idx]->_LinkedShaders[idx]->Stage))
> return false;
>
> prev = idx;
More information about the mesa-dev
mailing list