softpipe: add layered rendering support.
authorDave Airlie <airlied@redhat.com>
Tue, 10 Jun 2014 03:32:25 +0000 (13:32 +1000)
committerDave Airlie <airlied@redhat.com>
Wed, 11 Jun 2014 02:20:30 +0000 (12:20 +1000)
This adds support for GL 3.2 layered rendering to softpipe.

Reviewed-by: Roland Scheidegger <sroland@vmware.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
src/gallium/drivers/softpipe/sp_context.h
src/gallium/drivers/softpipe/sp_quad.h
src/gallium/drivers/softpipe/sp_quad_blend.c
src/gallium/drivers/softpipe/sp_quad_depth_test.c
src/gallium/drivers/softpipe/sp_quad_depth_test_tmp.h
src/gallium/drivers/softpipe/sp_setup.c
src/gallium/drivers/softpipe/sp_state_derived.c

index a56e8a8b2b9e3bde762cffab754f6c024c556231..aac35f7bf584b6f3271176fb7e4abe3d7132273e 100644 (file)
@@ -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;
 
index 71853d25205c2ca6127b3aa6d843bb80eb2d8f6d..b29dad2ea957c4066dd524a1556c1431e2391eef 100644 (file)
@@ -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 */
index ae7ecd0fe856dfc6c8661fa24c8d61ce0a2fb306..6c52c9071af7f961e67f3b9939cbdf45092d27b5 100644 (file)
@@ -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];
index 367218a91b7954bed99f0f06a9c1b8d1d42ae39e..bac40c013b30e3d143d0403b3deffe5c54722eb4 100644 (file)
@@ -801,7 +801,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);
       data.clamp = !qs->softpipe->rasterizer->depth_clip;
 
       near_val = qs->softpipe->viewport.translate[2] - qs->softpipe->viewport.scale[2];
index e7b70f7ea6531e00627d0449cf164de4eb86bb80..7128bf8486b5449b7d4346d462080abbc3d10bb4 100644 (file)
@@ -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;
index 2d6f24a1980bf8aace01d12b003cecc7afed4439..7937e10ad8ac3fa33c0f1e6537ade1dd85e01470 100644 (file)
@@ -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 &&
index 20b4b86e545be9eeb13637dd7109316dc282fce7..dc73910d18c4dfc594673a0fd700f93f06b5febd 100644 (file)
@@ -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);
    }