[Mesa-dev] [PATCH 1/8] draw: rework hanndling of non-existing outputs in emit code

eocallaghan at alterapraxis.com eocallaghan at alterapraxis.com
Mon Dec 21 22:16:35 PST 2015


Thanks for the most comprehensive cleanup Roland and fixing that
minor regression we discussed. Happy holiday's.

Reviewed-by: Edward O'Callaghan <eocallaghan at alterapraxis.com>

On 2015-12-22 14:00, sroland at vmware.com wrote:
> From: Roland Scheidegger <sroland at vmware.com>
> 
> Previously the code would just redirect requests for attributes which
> don't exist to use output 0. Rework this to output all zeros instead 
> which
> seems more useful - in particular some extensions like
> ARB_fragment_layer_viewport require 0 in the fs even if it wasn't 
> output by
> previous stages. That way, drivers don't have to special case this 
> depending
> if the vs/gs outputs some attribute or not.
> ---
>  src/gallium/auxiliary/draw/draw_pipe_vbuf.c | 52 
> +++++++++++++++++------------
>  src/gallium/auxiliary/draw/draw_pt_emit.c   | 12 +++++++
>  src/gallium/auxiliary/draw/draw_vertex.h    |  4 +--
>  3 files changed, 45 insertions(+), 23 deletions(-)
> 
> diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c
> b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c
> index f36706c..81c4fed 100644
> --- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c
> +++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c
> @@ -74,9 +74,10 @@ struct vbuf_stage {
>     unsigned max_indices;
>     unsigned nr_indices;
> 
> -   /* Cache point size somewhere it's address won't change:
> +   /* Cache point size somewhere its address won't change:
>      */
>     float point_size;
> +   float zero4[4];
> 
>     struct translate_cache *cache;
>  };
> @@ -205,6 +206,7 @@ vbuf_start_prim( struct vbuf_stage *vbuf, uint prim 
> )
>     struct translate_key hw_key;
>     unsigned dst_offset;
>     unsigned i;
> +   const struct vertex_info *vinfo;
> 
>     vbuf->render->set_primitive(vbuf->render, prim);
> 
> @@ -215,27 +217,33 @@ vbuf_start_prim( struct vbuf_stage *vbuf, uint 
> prim )
>      * state change.
>      */
>     vbuf->vinfo = vbuf->render->get_vertex_info(vbuf->render);
> -   vbuf->vertex_size = vbuf->vinfo->size * sizeof(float);
> +   vinfo = vbuf->vinfo;
> +   vbuf->vertex_size = vinfo->size * sizeof(float);
> 
>     /* Translate from pipeline vertices to hw vertices.
>      */
>     dst_offset = 0;
> 
> -   for (i = 0; i < vbuf->vinfo->num_attribs; i++) {
> +   for (i = 0; i < vinfo->num_attribs; i++) {
>        unsigned emit_sz = 0;
>        unsigned src_buffer = 0;
>        enum pipe_format output_format;
> -      unsigned src_offset = (vbuf->vinfo->attrib[i].src_index * 4 *
> sizeof(float) );
> +      unsigned src_offset = (vinfo->attrib[i].src_index * 4 * 
> sizeof(float) );
> 
> -      output_format = 
> draw_translate_vinfo_format(vbuf->vinfo->attrib[i].emit);
> -      emit_sz = 
> draw_translate_vinfo_size(vbuf->vinfo->attrib[i].emit);
> +      output_format = 
> draw_translate_vinfo_format(vinfo->attrib[i].emit);
> +      emit_sz = draw_translate_vinfo_size(vinfo->attrib[i].emit);
> 
>        /* doesn't handle EMIT_OMIT */
>        assert(emit_sz != 0);
> 
> -      if (vbuf->vinfo->attrib[i].emit == EMIT_1F_PSIZE) {
> -	 src_buffer = 1;
> -	 src_offset = 0;
> +      if (vinfo->attrib[i].emit == EMIT_1F_PSIZE) {
> +         src_buffer = 1;
> +         src_offset = 0;
> +      }
> +      else if (vinfo->attrib[i].src_index == 255) {
> +         /* elements which don't exist will get assigned zeros */
> +         src_buffer = 2;
> +         src_offset = 0;
>        }
> 
>        hw_key.element[i].type = TRANSLATE_ELEMENT_NORMAL;
> @@ -249,7 +257,7 @@ vbuf_start_prim( struct vbuf_stage *vbuf, uint prim 
> )
>        dst_offset += emit_sz;
>     }
> 
> -   hw_key.nr_elements = vbuf->vinfo->num_attribs;
> +   hw_key.nr_elements = vinfo->num_attribs;
>     hw_key.output_stride = vbuf->vertex_size;
> 
>     /* Don't bother with caching at this stage:
> @@ -261,6 +269,7 @@ vbuf_start_prim( struct vbuf_stage *vbuf, uint prim 
> )
>        vbuf->translate = translate_cache_find(vbuf->cache, &hw_key);
> 
>        vbuf->translate->set_buffer(vbuf->translate, 1,
> &vbuf->point_size, 0, ~0);
> +      vbuf->translate->set_buffer(vbuf->translate, 2, &vbuf->zero4[0], 
> 0, ~0);
>     }
> 
>     vbuf->point_size = vbuf->stage.draw->rasterizer->point_size;
> @@ -428,7 +437,7 @@ struct draw_stage *draw_vbuf_stage( struct
> draw_context *draw,
>     struct vbuf_stage *vbuf = CALLOC_STRUCT(vbuf_stage);
>     if (!vbuf)
>        goto fail;
> -
> +
>     vbuf->stage.draw = draw;
>     vbuf->stage.name = "vbuf";
>     vbuf->stage.point = vbuf_first_point;
> @@ -437,29 +446,30 @@ struct draw_stage *draw_vbuf_stage( struct
> draw_context *draw,
>     vbuf->stage.flush = vbuf_flush;
>     vbuf->stage.reset_stipple_counter = vbuf_reset_stipple_counter;
>     vbuf->stage.destroy = vbuf_destroy;
> -
> +
>     vbuf->render = render;
>     vbuf->max_indices = MIN2(render->max_indices, 
> UNDEFINED_VERTEX_ID-1);
> 
> -   vbuf->indices = (ushort *) align_malloc( vbuf->max_indices *
> -					    sizeof(vbuf->indices[0]),
> -					    16 );
> +   vbuf->indices = (ushort *) align_malloc(vbuf->max_indices *
> +                    sizeof(vbuf->indices[0]),
> +                    16);
>     if (!vbuf->indices)
>        goto fail;
> 
>     vbuf->cache = translate_cache_create();
> -   if (!vbuf->cache)
> +   if (!vbuf->cache)
>        goto fail;
> -
> -
> +
>     vbuf->vertices = NULL;
>     vbuf->vertex_ptr = vbuf->vertices;
> -
> +
> +   vbuf->zero4[0] = vbuf->zero4[1] = vbuf->zero4[2] = vbuf->zero4[3] = 
> 0.0f;
> +
>     return &vbuf->stage;
> 
> - fail:
> +fail:
>     if (vbuf)
>        vbuf_destroy(&vbuf->stage);
> -
> +
>     return NULL;
>  }
> diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c
> b/src/gallium/auxiliary/draw/draw_pt_emit.c
> index 0b9fab5..2fb7756 100644
> --- a/src/gallium/auxiliary/draw/draw_pt_emit.c
> +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c
> @@ -44,6 +44,9 @@ struct pt_emit {
>     unsigned prim;
> 
>     const struct vertex_info *vinfo;
> +
> +   float zero4[4];
> +
>  };
> 
> 
> @@ -92,6 +95,11 @@ draw_pt_emit_prepare(struct pt_emit *emit,
>           src_buffer = 1;
>           src_offset = 0;
>        }
> +      else if (vinfo->attrib[i].src_index == 255) {
> +         /* elements which don't exist will get assigned zeros */
> +         src_buffer = 2;
> +         src_offset = 0;
> +      }
> 
>        hw_key.element[i].type = TRANSLATE_ELEMENT_NORMAL;
>        hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
> @@ -111,6 +119,8 @@ draw_pt_emit_prepare(struct pt_emit *emit,
>         translate_key_compare(&emit->translate->key, &hw_key) != 0) {
>        translate_key_sanitize(&hw_key);
>        emit->translate = translate_cache_find(emit->cache, &hw_key);
> +
> +      emit->translate->set_buffer(emit->translate, 2, &emit->zero4[0], 
> 0, ~0);
>     }
> 
>     if (!vinfo->size)
> @@ -287,6 +297,8 @@ draw_pt_emit_create(struct draw_context *draw)
>        return NULL;
>     }
> 
> +   emit->zero4[0] = emit->zero4[1] = emit->zero4[2] = emit->zero4[3] = 
> 0.0f;
> +
>     return emit;
>  }
> 
> diff --git a/src/gallium/auxiliary/draw/draw_vertex.h
> b/src/gallium/auxiliary/draw/draw_vertex.h
> index ee11d2f..58aa00f 100644
> --- a/src/gallium/auxiliary/draw/draw_vertex.h
> +++ b/src/gallium/auxiliary/draw/draw_vertex.h
> @@ -130,9 +130,9 @@ draw_emit_vertex_attr(struct vertex_info *vinfo,
>     const uint n = vinfo->num_attribs;
> 
>     /* If the src_index is negative, meaning it hasn't been found
> -    * lets just redirect it to the first output slot */
> +    * we'll assign it all zeros later - set to 255 */
>     if (src_index < 0) {
> -      src_index = 0;
> +      src_index = 255;
>     }
> 
>     assert(n < Elements(vinfo->attrib));



More information about the mesa-dev mailing list