From 740d5bed77120aba4d815b5e2d28b109f214a800 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 10 Jun 2014 13:32:25 +1000 Subject: [PATCH] softpipe: add layered rendering support. This adds support for GL 3.2 layered rendering to softpipe. Reviewed-by: Roland Scheidegger Signed-off-by: Dave Airlie --- 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 ++-- .../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 +++++++++++++++++-- .../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 a56e8a8b2b9..aac35f7bf58 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 71853d25205..b29dad2ea95 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 ae7ecd0fe85..6c52c9071af 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 367218a91b7..bac40c013b3 100644 --- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c +++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c @@ -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]; 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 e7b70f7ea65..7128bf8486b 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 2d6f24a1980..7937e10ad8a 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 20b4b86e545..dc73910d18c 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.30.2