[Mesa-dev] [PATCH v2] anv: fix bug when using component qualifier in FS outputs

Samuel Iglesias Gonsálvez siglesias at igalia.com
Tue Nov 28 10:06:30 UTC 2017


This patch is still unreviewed.

Sam

On Wed, 2017-11-15 at 07:39 +0100, Samuel Iglesias Gonsálvez wrote:
> We can write to the same output but in different components, like
> in this example:
> 
> layout(location = 0, component = 0) out ivec2 dEQP_FragColor_0;
> layout(location = 0, component = 2) out ivec2 dEQP_FragColor_1;
> 
> Therefore, they are not two different outputs but only one.
> 
> Fixes:
> 
> dEQP-VK.glsl.440.linkage.varying.component.frag_out.*
> 
> Signed-off-by: Samuel Iglesias Gonsálvez <siglesias at igalia.com>
> ---
>  src/compiler/shader_enums.h     |  1 +
>  src/intel/vulkan/anv_pipeline.c | 46 +++++++++++++++++++++++++++--
> ------------
>  2 files changed, 32 insertions(+), 15 deletions(-)
> 
> diff --git a/src/compiler/shader_enums.h
> b/src/compiler/shader_enums.h
> index 9d229d4199e..90729dbfd96 100644
> --- a/src/compiler/shader_enums.h
> +++ b/src/compiler/shader_enums.h
> @@ -603,6 +603,7 @@ typedef enum
>     FRAG_RESULT_DATA5,
>     FRAG_RESULT_DATA6,
>     FRAG_RESULT_DATA7,
> +   FRAG_RESULT_MAX, /**< Number of fragment program results */
>  } gl_frag_result;
>  
>  const char *gl_frag_result_name(gl_frag_result result);
> diff --git a/src/intel/vulkan/anv_pipeline.c
> b/src/intel/vulkan/anv_pipeline.c
> index 907b24a758d..92cfc2898f5 100644
> --- a/src/intel/vulkan/anv_pipeline.c
> +++ b/src/intel/vulkan/anv_pipeline.c
> @@ -870,30 +870,28 @@ anv_pipeline_compile_fs(struct anv_pipeline
> *pipeline,
>        }
>  
>        unsigned num_rts = 0;
> -      struct anv_pipeline_binding rt_bindings[8];
> +      const int max_rt = FRAG_RESULT_MAX - FRAG_RESULT_DATA0;
> +      struct anv_pipeline_binding rt_bindings[max_rt];
>        nir_function_impl *impl = nir_shader_get_entrypoint(nir);
> +      int rt_to_bindings[max_rt];
> +      memset(rt_to_bindings, -1, sizeof(int) * max_rt);
> +
> +      /* Set new, compacted, location */
>        nir_foreach_variable_safe(var, &nir->outputs) {
>           if (var->data.location < FRAG_RESULT_DATA0)
>              continue;
>  
>           unsigned rt = var->data.location - FRAG_RESULT_DATA0;
> -         if (rt >= key.nr_color_regions) {
> -            /* Out-of-bounds, throw it away */
> -            var->data.mode = nir_var_local;
> -            exec_node_remove(&var->node);
> -            exec_list_push_tail(&impl->locals, &var->node);
> +         if (rt_to_bindings[rt] != -1 || rt >= key.nr_color_regions)
>              continue;
> -         }
> -
> -         /* Give it a new, compacted, location */
> -         var->data.location = FRAG_RESULT_DATA0 + num_rts;
> -
> -         unsigned array_len =
> +         const unsigned array_len =
>              glsl_type_is_array(var->type) ? glsl_get_length(var-
> >type) : 1;
> -         assert(num_rts + array_len <= 8);
> +         assert(num_rts + array_len <= max_rt);
> +
> +         rt_to_bindings[rt] = num_rts;
>  
>           for (unsigned i = 0; i < array_len; i++) {
> -            rt_bindings[num_rts + i] = (struct anv_pipeline_binding)
> {
> +            rt_bindings[rt_to_bindings[rt] + i] = (struct
> anv_pipeline_binding) {
>                 .set = ANV_DESCRIPTOR_SET_COLOR_ATTACHMENTS,
>                 .binding = 0,
>                 .index = rt + i,
> @@ -903,6 +901,24 @@ anv_pipeline_compile_fs(struct anv_pipeline
> *pipeline,
>           num_rts += array_len;
>        }
>  
> +      nir_foreach_variable_safe(var, &nir->outputs) {
> +         if (var->data.location < FRAG_RESULT_DATA0)
> +            continue;
> +
> +         unsigned rt = var->data.location - FRAG_RESULT_DATA0;
> +         if (rt >= key.nr_color_regions) {
> +            /* Out-of-bounds, throw it away */
> +            var->data.mode = nir_var_local;
> +            exec_node_remove(&var->node);
> +            exec_list_push_tail(&impl->locals, &var->node);
> +            continue;
> +         }
> +
> +         /* Give it the new location */
> +         assert(rt_to_bindings[rt] != -1);
> +         var->data.location = rt_to_bindings[rt] +
> FRAG_RESULT_DATA0;
> +      }
> +
>        if (num_rts == 0) {
>           /* If we have no render targets, we need a null render
> target */
>           rt_bindings[0] = (struct anv_pipeline_binding) {
> @@ -913,7 +929,7 @@ anv_pipeline_compile_fs(struct anv_pipeline
> *pipeline,
>           num_rts = 1;
>        }
>  
> -      assert(num_rts <= 8);
> +      assert(num_rts <= max_rt);
>        map.surface_to_descriptor -= num_rts;
>        map.surface_count += num_rts;
>        assert(map.surface_count <= 256);


More information about the mesa-dev mailing list