[Mesa-dev] [PATCH 3/8] softpipe: add layered rendering support.

Roland Scheidegger sroland at vmware.com
Tue Jun 10 06:57:02 PDT 2014


Am 10.06.2014 07:57, schrieb Dave Airlie:
> From: Dave Airlie <airlied at redhat.com>
> 
> This adds support for GL 3.2 layered rendering to softpipe.
> 
> Signed-off-by: Dave Airlie <airlied at redhat.com>
> ---
>  src/gallium/drivers/softpipe/sp_context.h          |  3 ++
>  src/gallium/drivers/softpipe/sp_quad.h             |  1 +
>  src/gallium/drivers/softpipe/sp_quad_blend.c       |  8 ++---
>  src/gallium/drivers/softpipe/sp_quad_depth_test.c  |  2 +-
>  .../drivers/softpipe/sp_quad_depth_test_tmp.h      |  2 +-
>  src/gallium/drivers/softpipe/sp_setup.c            | 42 ++++++++++++++++++++--
>  src/gallium/drivers/softpipe/sp_state_derived.c    |  6 ++++
>  7 files changed, 55 insertions(+), 9 deletions(-)
> 
> diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h
> index a56e8a8..aac35f7 100644
> --- a/src/gallium/drivers/softpipe/sp_context.h
> +++ b/src/gallium/drivers/softpipe/sp_context.h
> @@ -121,6 +121,9 @@ struct softpipe_context {
>     /** Which vertex shader output slot contains point size */
>     int psize_slot;
>  
> +   /** Which vertex shader output slot contains layer */
> +   int layer_slot;
> +
>     /** The reduced version of the primitive supplied by the state tracker */
>     unsigned reduced_api_prim;
>  
> diff --git a/src/gallium/drivers/softpipe/sp_quad.h b/src/gallium/drivers/softpipe/sp_quad.h
> index 71853d2..b29dad2 100644
> --- a/src/gallium/drivers/softpipe/sp_quad.h
> +++ b/src/gallium/drivers/softpipe/sp_quad.h
> @@ -62,6 +62,7 @@
>  struct quad_header_input
>  {
>     int x0, y0;                /**< quad window pos, always even */
> +   unsigned layer;
>     float coverage[TGSI_QUAD_SIZE]; /**< fragment coverage for antialiasing */
>     unsigned facing:1;         /**< Front (0) or back (1) facing? */
>     unsigned prim:2;           /**< QUAD_PRIM_POINT, LINE, TRI */
> diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c b/src/gallium/drivers/softpipe/sp_quad_blend.c
> index ae7ecd0..6c52c90 100644
> --- a/src/gallium/drivers/softpipe/sp_quad_blend.c
> +++ b/src/gallium/drivers/softpipe/sp_quad_blend.c
> @@ -935,7 +935,7 @@ blend_fallback(struct quad_stage *qs,
>           struct softpipe_cached_tile *tile
>              = sp_get_cached_tile(softpipe->cbuf_cache[cbuf],
>                                   quads[0]->input.x0, 
> -                                 quads[0]->input.y0, 0);
> +                                 quads[0]->input.y0, quads[0]->input.layer);
>           const boolean clamp = bqs->clamp[cbuf];
>           const float *blend_color;
>           const boolean dual_source_blend = util_blend_state_is_dual(blend, cbuf);
> @@ -1038,7 +1038,7 @@ blend_single_add_src_alpha_inv_src_alpha(struct quad_stage *qs,
>     struct softpipe_cached_tile *tile
>        = sp_get_cached_tile(qs->softpipe->cbuf_cache[0],
>                             quads[0]->input.x0, 
> -                           quads[0]->input.y0, 0);
> +                           quads[0]->input.y0, quads[0]->input.layer);
>  
>     for (q = 0; q < nr; q++) {
>        struct quad_header *quad = quads[q];
> @@ -1112,7 +1112,7 @@ blend_single_add_one_one(struct quad_stage *qs,
>     struct softpipe_cached_tile *tile
>        = sp_get_cached_tile(qs->softpipe->cbuf_cache[0],
>                             quads[0]->input.x0, 
> -                           quads[0]->input.y0, 0);
> +                           quads[0]->input.y0, quads[0]->input.layer);
>  
>     for (q = 0; q < nr; q++) {
>        struct quad_header *quad = quads[q];
> @@ -1180,7 +1180,7 @@ single_output_color(struct quad_stage *qs,
>     struct softpipe_cached_tile *tile
>        = sp_get_cached_tile(qs->softpipe->cbuf_cache[0],
>                             quads[0]->input.x0, 
> -                           quads[0]->input.y0, 0);
> +                           quads[0]->input.y0, quads[0]->input.layer);
>  
>     for (q = 0; q < nr; q++) {
>        struct quad_header *quad = quads[q];
> diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c
> index d758521..12d2d11 100644
> --- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c
> +++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c
> @@ -806,7 +806,7 @@ depth_test_quads_fallback(struct quad_stage *qs,
>        data.format = data.ps->format;
>        data.tile = sp_get_cached_tile(qs->softpipe->zsbuf_cache, 
>                                       quads[0]->input.x0, 
> -                                     quads[0]->input.y0, 0);
> +                                     quads[0]->input.y0, quads[0]->input.layer);
>  
>        for (i = 0; i < nr; i++) {
>           get_depth_stencil_values(&data, quads[i]);
> diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test_tmp.h b/src/gallium/drivers/softpipe/sp_quad_depth_test_tmp.h
> index e7b70f7..7128bf8 100644
> --- a/src/gallium/drivers/softpipe/sp_quad_depth_test_tmp.h
> +++ b/src/gallium/drivers/softpipe/sp_quad_depth_test_tmp.h
> @@ -71,7 +71,7 @@ NAME(struct quad_stage *qs,
>  
>     depth_step = (ushort)(dzdx * scale);
>  
> -   tile = sp_get_cached_tile(qs->softpipe->zsbuf_cache, ix, iy, 0);
> +   tile = sp_get_cached_tile(qs->softpipe->zsbuf_cache, ix, iy, quads[0]->input.layer);
>  
>     for (i = 0; i < nr; i++) {
>        const unsigned outmask = quads[i]->inout.mask;
> diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c
> index 2d6f24a..7937e10 100644
> --- a/src/gallium/drivers/softpipe/sp_setup.c
> +++ b/src/gallium/drivers/softpipe/sp_setup.c
> @@ -92,6 +92,7 @@ struct setup_context {
>     int facing;
>  
>     float pixel_offset;
> +   unsigned max_layer;
>  
>     struct quad_header quad[MAX_QUADS];
>     struct quad_header *quad_ptrs[MAX_QUADS];
> @@ -801,7 +802,7 @@ sp_setup_tri(struct setup_context *setup,
>               const float (*v2)[4])
>  {
>     float det;
> -
> +   uint layer = 0;
>  #if DEBUG_VERTS
>     debug_printf("Setup triangle:\n");
>     print_vertex(setup, v0);
> @@ -834,6 +835,11 @@ sp_setup_tri(struct setup_context *setup,
>     setup->span.right[0] = 0;
>     setup->span.right[1] = 0;
>     /*   setup->span.z_mode = tri_z_mode( setup->ctx ); */
> +   if (setup->softpipe->layer_slot > 0) {
> +      layer = *(unsigned *)v1[setup->softpipe->layer_slot];
> +      layer = MIN2(layer, setup->max_layer);
> +   }
> +   setup->quad[0].input.layer = layer;
>  
>     /*   init_constant_attribs( setup ); */
>  
> @@ -1072,6 +1078,7 @@ sp_setup_line(struct setup_context *setup,
>     int dx = x1 - x0;
>     int dy = y1 - y0;
>     int xstep, ystep;
> +   uint layer = 0;
>  
>  #if DEBUG_VERTS
>     debug_printf("Setup line:\n");
> @@ -1115,6 +1122,11 @@ sp_setup_line(struct setup_context *setup,
>  
>     setup->quad[0].input.x0 = setup->quad[0].input.y0 = -1;
>     setup->quad[0].inout.mask = 0x0;
> +   if (setup->softpipe->layer_slot > 0) {
> +      layer = *(unsigned *)v1[setup->softpipe->layer_slot];
> +      layer = MIN2(layer, setup->max_layer);
> +   }
> +   setup->quad[0].input.layer = layer;
>  
>     /* XXX temporary: set coverage to 1.0 so the line appears
>      * if AA mode happens to be enabled.
> @@ -1206,7 +1218,7 @@ sp_setup_point(struct setup_context *setup,
>     const float y = v0[0][1];
>     const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe);
>     uint fragSlot;
> -
> +   uint layer = 0;
>  #if DEBUG_VERTS
>     debug_printf("Setup point:\n");
>     print_vertex(setup, v0);
> @@ -1217,6 +1229,12 @@ sp_setup_point(struct setup_context *setup,
>  
>     assert(setup->softpipe->reduced_prim == PIPE_PRIM_POINTS);
>  
> +   if (setup->softpipe->layer_slot > 0) {
> +      layer = *(unsigned *)v0[setup->softpipe->layer_slot];
> +      layer = MIN2(layer, setup->max_layer);
> +   }
> +   setup->quad[0].input.layer = layer;
> +
>     /* For points, all interpolants are constant-valued.
>      * However, for point sprites, we'll need to setup texcoords appropriately.
>      * XXX: which coefficients are the texcoords???
> @@ -1401,7 +1419,8 @@ void
>  sp_setup_prepare(struct setup_context *setup)
>  {
>     struct softpipe_context *sp = setup->softpipe;
> -
> +   int i;
> +   unsigned max_layer = ~0;
>     if (sp->dirty) {
>        softpipe_update_derived(sp, sp->reduced_api_prim);
>     }
> @@ -1409,6 +1428,23 @@ sp_setup_prepare(struct setup_context *setup)
>     /* Note: nr_attrs is only used for debugging (vertex printing) */
>     setup->nr_vertex_attrs = draw_num_shader_outputs(sp->draw);
>  
> +   /*
> +    * Determine how many layers the fb has (used for clamping layer value).
> +    * OpenGL (but not d3d10) permits different amount of layers per rt, however
> +    * results are undefined if layer exceeds the amount of layers of ANY
> +    * attachment hence don't need separate per cbuf and zsbuf max.
> +    */
> +   for (i = 0; i < setup->softpipe->framebuffer.nr_cbufs; i++) {
> +      struct pipe_surface *cbuf = setup->softpipe->framebuffer.cbufs[i];
> +      if (cbuf) {
> +         max_layer = MIN2(max_layer,
> +                          cbuf->u.tex.last_layer - cbuf->u.tex.first_layer);
> +
> +      }
> +   }
> +
> +   setup->max_layer = max_layer;
> +
>     sp->quad.first->begin( sp->quad.first );
>  
>     if (sp->reduced_api_prim == PIPE_PRIM_TRIANGLES &&
> diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c
> index 20b4b86..dc73910 100644
> --- a/src/gallium/drivers/softpipe/sp_state_derived.c
> +++ b/src/gallium/drivers/softpipe/sp_state_derived.c
> @@ -142,6 +142,12 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe)
>                                 softpipe->psize_slot);
>        }
>  
> +      softpipe->layer_slot = draw_find_shader_output(softpipe->draw,
> +                                         TGSI_SEMANTIC_LAYER, 0);
> +      if (softpipe->layer_slot >= 0) {
> +         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, softpipe->layer_slot);
> +      }
> +
>        draw_compute_vertex_size(vinfo);
>     }
>  
> 

2/8 and 3/8 look good to me.

Roland


More information about the mesa-dev mailing list