[Mesa-dev] [PATCH] softpipe: implement some support for multiple viewports

Edward O'Callaghan eocallaghan at alterapraxis.com
Mon Dec 7 05:31:38 PST 2015


Mostly related to making sure the rasterizer can correctly
pick out the correct scissor box for the current viewport.

Signed-off-by: Edward O'Callaghan <eocallaghan at alterapraxis.com>
---
 src/gallium/drivers/softpipe/sp_context.h         |  7 +++-
 src/gallium/drivers/softpipe/sp_quad_depth_test.c |  4 +-
 src/gallium/drivers/softpipe/sp_state_clip.c      | 15 +++++---
 src/gallium/drivers/softpipe/sp_state_derived.c   | 45 ++++++++++++++++-------
 src/gallium/drivers/softpipe/sp_surface.c         |  4 +-
 5 files changed, 51 insertions(+), 24 deletions(-)

diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h
index 073b71a..e8a6f7e 100644
--- a/src/gallium/drivers/softpipe/sp_context.h
+++ b/src/gallium/drivers/softpipe/sp_context.h
@@ -79,10 +79,10 @@ struct softpipe_context {
    struct pipe_resource *constants[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS];
    struct pipe_framebuffer_state framebuffer;
    struct pipe_poly_stipple poly_stipple;
-   struct pipe_scissor_state scissor;
+   struct pipe_scissor_state scissors[PIPE_MAX_VIEWPORTS];
    struct pipe_sampler_view *sampler_views[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_SAMPLER_VIEWS];
 
-   struct pipe_viewport_state viewport;
+   struct pipe_viewport_state viewports[PIPE_MAX_VIEWPORTS];
    struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
    struct pipe_index_buffer index_buffer;
    struct pipe_resource *mapped_vs_tex[PIPE_MAX_SHADER_SAMPLER_VIEWS];
@@ -123,6 +123,9 @@ struct softpipe_context {
    /** Which vertex shader output slot contains point size */
    int psize_slot;
 
+   /** Which vertex shader output slot contains viewport index */
+   int viewport_index_slot;
+
    /** Which vertex shader output slot contains layer */
    int layer_slot;
 
diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c
index bac40c0..bf33648 100644
--- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c
+++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c
@@ -804,8 +804,8 @@ depth_test_quads_fallback(struct quad_stage *qs,
                                      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];
-      far_val = near_val + (qs->softpipe->viewport.scale[2] * 2.0);
+      near_val = qs->softpipe->viewports[0].translate[2] - qs->softpipe->viewports[0].scale[2];
+      far_val = near_val + (qs->softpipe->viewports[0].scale[2] * 2.0);
       data.minval = MIN2(near_val, far_val);
       data.maxval = MAX2(near_val, far_val);
 
diff --git a/src/gallium/drivers/softpipe/sp_state_clip.c b/src/gallium/drivers/softpipe/sp_state_clip.c
index 59c22c6..4de6296 100644
--- a/src/gallium/drivers/softpipe/sp_state_clip.c
+++ b/src/gallium/drivers/softpipe/sp_state_clip.c
@@ -47,15 +47,16 @@ static void
 softpipe_set_viewport_states(struct pipe_context *pipe,
                              unsigned start_slot,
                              unsigned num_viewports,
-                             const struct pipe_viewport_state *viewport)
+                             const struct pipe_viewport_state *viewports)
 {
    struct softpipe_context *softpipe = softpipe_context(pipe);
 
    /* pass the viewport info to the draw module */
    draw_set_viewport_states(softpipe->draw, start_slot, num_viewports,
-                            viewport);
+                            viewports);
 
-   softpipe->viewport = *viewport; /* struct copy */
+   memcpy(softpipe->viewports + start_slot, viewports,
+          sizeof(struct pipe_viewport_state) * num_viewports);
    softpipe->dirty |= SP_NEW_VIEWPORT;
 }
 
@@ -64,13 +65,17 @@ static void
 softpipe_set_scissor_states(struct pipe_context *pipe,
                             unsigned start_slot,
                             unsigned num_scissors,
-                            const struct pipe_scissor_state *scissor)
+                            const struct pipe_scissor_state *scissors)
 {
    struct softpipe_context *softpipe = softpipe_context(pipe);
 
    draw_flush(softpipe->draw);
 
-   softpipe->scissor = *scissor; /* struct copy */
+   debug_assert(start_slot < PIPE_MAX_VIEWPORTS);
+   debug_assert((start_slot + num_scissors) <= PIPE_MAX_VIEWPORTS);
+
+   memcpy(softpipe->scissors + start_slot, scissors,
+          sizeof(struct pipe_scissor_state) * num_scissors);
    softpipe->dirty |= SP_NEW_SCISSOR;
 }
 
diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c
index 2a6a6f4..d51fab1 100644
--- a/src/gallium/drivers/softpipe/sp_state_derived.c
+++ b/src/gallium/drivers/softpipe/sp_state_derived.c
@@ -64,6 +64,7 @@ struct vertex_info *
 softpipe_get_vertex_info(struct softpipe_context *softpipe)
 {
    struct vertex_info *vinfo = &softpipe->vertex_info;
+   int vs_index;
 
    if (vinfo->num_attribs == 0) {
       /* compute vertex layout now */
@@ -135,17 +136,35 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe)
          draw_emit_vertex_attr(vinfo, EMIT_4F, interp, src);
       }
 
-      softpipe->psize_slot = draw_find_shader_output(softpipe->draw,
-                                                 TGSI_SEMANTIC_PSIZE, 0);
-      if (softpipe->psize_slot >= 0) {
-         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT,
-                               softpipe->psize_slot);
+      /* Figure out if we need pointsize as well. */
+      vs_index = draw_find_shader_output(softpipe->draw,
+                                         TGSI_SEMANTIC_PSIZE, 0);
+
+      if (vs_index >= 0) {
+         softpipe->psize_slot = vinfo->num_attribs;
+         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index);
+      }
+
+      /* Figure out if we need viewport index */
+      vs_index = draw_find_shader_output(softpipe->draw,
+                                         TGSI_SEMANTIC_VIEWPORT_INDEX,
+                                         0);
+      if (vs_index >= 0) {
+         softpipe->viewport_index_slot = vinfo->num_attribs;
+         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index);
+      } else {
+         softpipe->viewport_index_slot = 0;
       }
 
-      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);
+      /* Figure out if we need layer */
+      vs_index = draw_find_shader_output(softpipe->draw,
+                                         TGSI_SEMANTIC_LAYER,
+                                         0);
+      if (vs_index >= 0) {
+         softpipe->layer_slot = vinfo->num_attribs;
+         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index);
+      } else {
+         softpipe->layer_slot = 0;
       }
 
       draw_compute_vertex_size(vinfo);
@@ -196,10 +215,10 @@ compute_cliprect(struct softpipe_context *sp)
        *
        * clip to scissor rect:
        */
-      sp->cliprect.minx = MAX2(sp->scissor.minx, 0);
-      sp->cliprect.miny = MAX2(sp->scissor.miny, 0);
-      sp->cliprect.maxx = MIN2(sp->scissor.maxx, surfWidth);
-      sp->cliprect.maxy = MIN2(sp->scissor.maxy, surfHeight);
+      sp->cliprect.minx = MAX2(sp->scissors[0].minx, 0);
+      sp->cliprect.miny = MAX2(sp->scissors[0].miny, 0);
+      sp->cliprect.maxx = MIN2(sp->scissors[0].maxx, surfWidth);
+      sp->cliprect.maxy = MIN2(sp->scissors[0].maxy, surfHeight);
    }
    else {
       /* clip to surface bounds */
diff --git a/src/gallium/drivers/softpipe/sp_surface.c b/src/gallium/drivers/softpipe/sp_surface.c
index 768e898..e2ecbdf 100644
--- a/src/gallium/drivers/softpipe/sp_surface.c
+++ b/src/gallium/drivers/softpipe/sp_surface.c
@@ -67,8 +67,8 @@ static void sp_blit(struct pipe_context *pipe,
    util_blitter_save_so_targets(sp->blitter, sp->num_so_targets,
                      (struct pipe_stream_output_target**)sp->so_targets);
    util_blitter_save_rasterizer(sp->blitter, sp->rasterizer);
-   util_blitter_save_viewport(sp->blitter, &sp->viewport);
-   util_blitter_save_scissor(sp->blitter, &sp->scissor);
+   util_blitter_save_viewport(sp->blitter, &sp->viewports[0]);
+   util_blitter_save_scissor(sp->blitter, &sp->scissors[0]);
    util_blitter_save_fragment_shader(sp->blitter, sp->fs);
    util_blitter_save_blend(sp->blitter, sp->blend);
    util_blitter_save_depth_stencil_alpha(sp->blitter, sp->depth_stencil);
-- 
2.5.0



More information about the mesa-dev mailing list