[Mesa-dev] [PATCH 1/4] gallium: Add support for multiple viewports

Zack Rusin zackr at vmware.com
Thu May 23 13:33:40 PDT 2013


Gallium supported only a single viewport/scissor combination. This
commit changes the interface to allow us to add support for multiple
viewports/scissors.

Signed-off-by: Zack Rusin <zackr at vmware.com>
---
 src/gallium/auxiliary/cso_cache/cso_context.c   |   37 +++++++++++++++--------
 src/gallium/auxiliary/cso_cache/cso_context.h   |    9 +++---
 src/gallium/auxiliary/draw/draw_context.c       |    6 ++--
 src/gallium/auxiliary/draw/draw_context.h       |    5 +--
 src/gallium/auxiliary/hud/hud_context.c         |    6 ++--
 src/gallium/auxiliary/postprocess/pp_run.c      |    6 ++--
 src/gallium/auxiliary/tgsi/tgsi_scan.c          |    6 ++++
 src/gallium/auxiliary/tgsi/tgsi_scan.h          |    1 +
 src/gallium/auxiliary/tgsi/tgsi_strings.c       |    3 +-
 src/gallium/auxiliary/util/u_blit.c             |   12 ++++----
 src/gallium/auxiliary/util/u_blitter.c          |    8 ++---
 src/gallium/auxiliary/util/u_gen_mipmap.c       |    6 ++--
 src/gallium/auxiliary/vl/vl_compositor.c        |    4 +--
 src/gallium/auxiliary/vl/vl_idct.c              |    4 +--
 src/gallium/auxiliary/vl/vl_matrix_filter.c     |    2 +-
 src/gallium/auxiliary/vl/vl_mc.c                |    2 +-
 src/gallium/auxiliary/vl/vl_median_filter.c     |    2 +-
 src/gallium/auxiliary/vl/vl_zscan.c             |    2 +-
 src/gallium/docs/source/context.rst             |    8 +++--
 src/gallium/drivers/freedreno/freedreno_state.c |   10 +++---
 src/gallium/drivers/galahad/glhd_context.c      |   16 +++++-----
 src/gallium/drivers/i915/i915_state.c           |   12 +++++---
 src/gallium/drivers/identity/id_context.c       |   22 ++++++++------
 src/gallium/drivers/ilo/ilo_state.c             |   14 +++++----
 src/gallium/drivers/llvmpipe/lp_screen.c        |    2 ++
 src/gallium/drivers/llvmpipe/lp_state_clip.c    |   20 ++++++------
 src/gallium/drivers/noop/noop_state.c           |   14 +++++----
 src/gallium/drivers/nv30/nv30_draw.c            |    2 +-
 src/gallium/drivers/nv30/nv30_state.c           |   14 +++++----
 src/gallium/drivers/nv50/nv50_state.c           |   16 +++++-----
 src/gallium/drivers/nvc0/nvc0_state.c           |   14 +++++----
 src/gallium/drivers/r300/r300_context.c         |    2 +-
 src/gallium/drivers/r300/r300_state.c           |   16 +++++-----
 src/gallium/drivers/r600/evergreen_state.c      |    5 +--
 src/gallium/drivers/r600/r600_state.c           |    7 +++--
 src/gallium/drivers/r600/r600_state_common.c    |    9 +++---
 src/gallium/drivers/radeonsi/si_state.c         |   14 +++++----
 src/gallium/drivers/rbug/rbug_context.c         |   22 ++++++++------
 src/gallium/drivers/softpipe/sp_screen.c        |    2 ++
 src/gallium/drivers/softpipe/sp_state_clip.c    |   16 +++++-----
 src/gallium/drivers/svga/svga_pipe_misc.c       |   18 ++++++-----
 src/gallium/drivers/svga/svga_swtnl_state.c     |    2 +-
 src/gallium/drivers/trace/tr_context.c          |   28 +++++++++--------
 src/gallium/include/pipe/p_context.h            |   10 +++---
 src/gallium/include/pipe/p_defines.h            |    3 +-
 src/gallium/include/pipe/p_shader_tokens.h      |    3 +-
 src/gallium/include/pipe/p_state.h              |    1 +
 src/gallium/state_trackers/vega/renderer.c      |   10 +++---
 src/gallium/state_trackers/xa/xa_renderer.c     |    2 +-
 src/gallium/state_trackers/xorg/xorg_renderer.c |    2 +-
 src/gallium/tests/graw/fs-test.c                |    2 +-
 src/gallium/tests/graw/graw_util.h              |    2 +-
 src/gallium/tests/graw/gs-test.c                |    2 +-
 src/gallium/tests/graw/quad-sample.c            |    2 +-
 src/gallium/tests/graw/shader-leak.c            |    2 +-
 src/gallium/tests/graw/tri-gs.c                 |    2 +-
 src/gallium/tests/graw/tri-instanced.c          |    2 +-
 src/gallium/tests/graw/vs-test.c                |    2 +-
 src/gallium/tests/trivial/quad-tex.c            |    2 +-
 src/gallium/tests/trivial/tri.c                 |    2 +-
 src/mesa/state_tracker/st_atom_scissor.c        |    2 +-
 src/mesa/state_tracker/st_atom_viewport.c       |    2 +-
 src/mesa/state_tracker/st_cb_bitmap.c           |    6 ++--
 src/mesa/state_tracker/st_cb_clear.c            |    6 ++--
 src/mesa/state_tracker/st_cb_drawpixels.c       |    6 ++--
 src/mesa/state_tracker/st_cb_drawtex.c          |    6 ++--
 src/mesa/state_tracker/st_draw_feedback.c       |    2 +-
 67 files changed, 290 insertions(+), 217 deletions(-)

diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c
index e46f2ab..da7d1cf 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.c
+++ b/src/gallium/auxiliary/cso_cache/cso_context.c
@@ -115,8 +115,12 @@ struct cso_context {
    struct pipe_clip_state clip;
    struct pipe_clip_state clip_saved;
 
+   uint nr_viewports;
+   struct pipe_viewport_state vps[PIPE_MAX_VIEWPORTS];
+   uint nr_viewports_saved;
+   struct pipe_viewport_state vps_saved[PIPE_MAX_VIEWPORTS];
+   
    struct pipe_framebuffer_state fb, fb_saved;
-   struct pipe_viewport_state vp, vp_saved;
    struct pipe_blend_color blend_color;
    unsigned sample_mask, sample_mask_saved;
    struct pipe_stencil_ref stencil_ref, stencil_ref_saved;
@@ -647,26 +651,35 @@ void cso_restore_framebuffer(struct cso_context *ctx)
 }
 
 
-void cso_set_viewport(struct cso_context *ctx,
-                      const struct pipe_viewport_state *vp)
+void cso_set_viewports(struct cso_context *ctx,
+                       unsigned nr_viewports,
+                       const struct pipe_viewport_state *vps)
 {
-   if (memcmp(&ctx->vp, vp, sizeof(*vp))) {
-      ctx->vp = *vp;
-      ctx->pipe->set_viewport_state(ctx->pipe, vp);
+   if (nr_viewports != ctx->nr_viewports ||
+       memcmp(ctx->vps, vps, sizeof(*vps) * nr_viewports)) {
+      ctx->nr_viewports = nr_viewports;
+      memcpy(ctx->vps, vps, sizeof(*vps) * nr_viewports);
+      ctx->pipe->set_viewport_states(ctx->pipe, nr_viewports, vps);
    }
 }
 
-void cso_save_viewport(struct cso_context *ctx)
+void cso_save_viewports(struct cso_context *ctx)
 {
-   ctx->vp_saved = ctx->vp;
+   ctx->nr_viewports_saved = ctx->nr_viewports;   
+   memcpy(ctx->vps_saved, ctx->vps,
+          sizeof(struct pipe_viewport_state) * ctx->nr_viewports);
 }
 
 
-void cso_restore_viewport(struct cso_context *ctx)
+void cso_restore_viewports(struct cso_context *ctx)
 {
-   if (memcmp(&ctx->vp, &ctx->vp_saved, sizeof(ctx->vp))) {
-      ctx->vp = ctx->vp_saved;
-      ctx->pipe->set_viewport_state(ctx->pipe, &ctx->vp);
+   if (ctx->nr_viewports != ctx->nr_viewports_saved ||
+       memcmp(ctx->vps, ctx->vps_saved,
+              sizeof(struct pipe_viewport_state) * ctx->nr_viewports_saved)) {
+      ctx->nr_viewports =  ctx->nr_viewports_saved;
+      memcpy(ctx->vps, ctx->vps_saved,
+             sizeof(struct pipe_viewport_state) * ctx->nr_viewports);
+      ctx->pipe->set_viewport_states(ctx->pipe, ctx->nr_viewports, ctx->vps);
    }
 }
 
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h
index 20ab4ef..1ecb2eb 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.h
+++ b/src/gallium/auxiliary/cso_cache/cso_context.h
@@ -151,10 +151,11 @@ void cso_save_framebuffer(struct cso_context *cso);
 void cso_restore_framebuffer(struct cso_context *cso);
 
 
-void cso_set_viewport(struct cso_context *cso,
-                      const struct pipe_viewport_state *vp);
-void cso_save_viewport(struct cso_context *cso);
-void cso_restore_viewport(struct cso_context *cso);
+void cso_set_viewports(struct cso_context *cso,
+                       unsigned nr_vps,
+                       const struct pipe_viewport_state *vps);
+void cso_save_viewports(struct cso_context *cso);
+void cso_restore_viewports(struct cso_context *cso);
 
 
 void cso_set_blend_color(struct cso_context *cso,
diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
index 7819038..ed642c5 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -311,9 +311,11 @@ void draw_set_clip_state( struct draw_context *draw,
 /**
  * Set the draw module's viewport state.
  */
-void draw_set_viewport_state( struct draw_context *draw,
-                              const struct pipe_viewport_state *viewport )
+void draw_set_viewport_states( struct draw_context *draw,
+                               unsigned num_viewports,
+                               const struct pipe_viewport_state *vps )
 {
+   const struct pipe_viewport_state *viewport = vps;
    draw_do_flush(draw, DRAW_FLUSH_PARAMETER_CHANGE);
    draw->viewport = *viewport; /* struct copy */
    draw->identity_viewport = (viewport->scale[0] == 1.0f &&
diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h
index 47bad0d..b761d23 100644
--- a/src/gallium/auxiliary/draw/draw_context.h
+++ b/src/gallium/auxiliary/draw/draw_context.h
@@ -71,8 +71,9 @@ void draw_destroy( struct draw_context *draw );
 
 void draw_flush(struct draw_context *draw);
 
-void draw_set_viewport_state( struct draw_context *draw,
-                              const struct pipe_viewport_state *viewport );
+void draw_set_viewport_states( struct draw_context *draw,
+                               unsigned num_viewports,
+                               const struct pipe_viewport_state *viewports );
 
 void draw_set_clip_state( struct draw_context *pipe,
                           const struct pipe_clip_state *clip );
diff --git a/src/gallium/auxiliary/hud/hud_context.c b/src/gallium/auxiliary/hud/hud_context.c
index de032b6..6702a60 100644
--- a/src/gallium/auxiliary/hud/hud_context.c
+++ b/src/gallium/auxiliary/hud/hud_context.c
@@ -416,7 +416,7 @@ hud_draw(struct hud_context *hud, struct pipe_resource *tex)
    cso_save_sampler_views(cso, PIPE_SHADER_FRAGMENT);
    cso_save_samplers(cso, PIPE_SHADER_FRAGMENT);
    cso_save_rasterizer(cso);
-   cso_save_viewport(cso);
+   cso_save_viewports(cso);
    cso_save_stream_outputs(cso);
    cso_save_geometry_shader(cso);
    cso_save_vertex_shader(cso);
@@ -451,7 +451,7 @@ hud_draw(struct hud_context *hud, struct pipe_resource *tex)
    cso_set_blend(cso, &hud->alpha_blend);
    cso_set_depth_stencil_alpha(cso, &hud->dsa);
    cso_set_rasterizer(cso, &hud->rasterizer);
-   cso_set_viewport(cso, &viewport);
+   cso_set_viewports(cso, 1, &viewport);
    cso_set_stream_outputs(cso, 0, NULL, 0);
    cso_set_geometry_shader_handle(cso, NULL);
    cso_set_vertex_shader_handle(cso, hud->vs);
@@ -542,7 +542,7 @@ hud_draw(struct hud_context *hud, struct pipe_resource *tex)
    cso_restore_sampler_views(cso, PIPE_SHADER_FRAGMENT);
    cso_restore_samplers(cso, PIPE_SHADER_FRAGMENT);
    cso_restore_rasterizer(cso);
-   cso_restore_viewport(cso);
+   cso_restore_viewports(cso);
    cso_restore_stream_outputs(cso);
    cso_restore_geometry_shader(cso);
    cso_restore_vertex_shader(cso);
diff --git a/src/gallium/auxiliary/postprocess/pp_run.c b/src/gallium/auxiliary/postprocess/pp_run.c
index 8b3f451..6aeab2c 100644
--- a/src/gallium/auxiliary/postprocess/pp_run.c
+++ b/src/gallium/auxiliary/postprocess/pp_run.c
@@ -80,7 +80,7 @@ pp_run(struct pp_queue_t *ppq, struct pipe_resource *in,
    cso_save_stream_outputs(cso);
    cso_save_vertex_elements(cso);
    cso_save_vertex_shader(cso);
-   cso_save_viewport(cso);
+   cso_save_viewports(cso);
    cso_save_aux_vertex_buffer_slot(cso);
    cso_save_constant_buffer_slot0(cso, PIPE_SHADER_VERTEX);
    cso_save_constant_buffer_slot0(cso, PIPE_SHADER_FRAGMENT);
@@ -141,7 +141,7 @@ pp_run(struct pp_queue_t *ppq, struct pipe_resource *in,
    cso_restore_stream_outputs(cso);
    cso_restore_vertex_elements(cso);
    cso_restore_vertex_shader(cso);
-   cso_restore_viewport(cso);
+   cso_restore_viewports(cso);
    cso_restore_aux_vertex_buffer_slot(cso);
    cso_restore_constant_buffer_slot0(cso, PIPE_SHADER_VERTEX);
    cso_restore_constant_buffer_slot0(cso, PIPE_SHADER_FRAGMENT);
@@ -215,7 +215,7 @@ pp_filter_misc_state(struct program *p)
    cso_set_blend(p->cso, &p->blend);
    cso_set_depth_stencil_alpha(p->cso, &p->depthstencil);
    cso_set_rasterizer(p->cso, &p->rasterizer);
-   cso_set_viewport(p->cso, &p->viewport);
+   cso_set_viewports(p->cso, 1, &p->viewport);
 
    cso_set_vertex_elements(p->cso, 2, p->velem);
 }
diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.c b/src/gallium/auxiliary/tgsi/tgsi_scan.c
index bd79405..0230267 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_scan.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_scan.c
@@ -211,6 +211,12 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
                       fulldecl->Semantic.Name == TGSI_SEMANTIC_EDGEFLAG) {
                      info->writes_edgeflag = TRUE;
                   }
+
+                  if (procType == TGSI_PROCESSOR_GEOMETRY &&
+                      fulldecl->Semantic.Name ==
+                      TGSI_SEMANTIC_VIEWPORT_INDEX) {
+                     info->writes_viewport_index = TRUE;
+                  }
                }
 
              }
diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.h b/src/gallium/auxiliary/tgsi/tgsi_scan.h
index 9debc34..676abf0 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_scan.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_scan.h
@@ -75,6 +75,7 @@ struct tgsi_shader_info
    boolean origin_lower_left;
    boolean pixel_center_integer;
    boolean color0_writes_all_cbufs;
+   boolean writes_viewport_index;
 
    unsigned num_written_clipdistance;
    /**
diff --git a/src/gallium/auxiliary/tgsi/tgsi_strings.c b/src/gallium/auxiliary/tgsi/tgsi_strings.c
index 95a5ade..6abf927 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_strings.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_strings.c
@@ -78,7 +78,8 @@ const char *tgsi_semantic_names[TGSI_SEMANTIC_COUNT] =
    "BLOCK_SIZE",
    "THREAD_ID",
    "TEXCOORD",
-   "PCOORD"
+   "PCOORD",
+   "VIEWPORT_INDEX"
 };
 
 const char *tgsi_texture_names[TGSI_TEXTURE_COUNT] =
diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
index cda66d1..b562ae8 100644
--- a/src/gallium/auxiliary/util/u_blit.c
+++ b/src/gallium/auxiliary/util/u_blit.c
@@ -660,7 +660,7 @@ util_blit_pixels(struct blit_state *ctx,
    cso_save_samplers(ctx->cso, PIPE_SHADER_FRAGMENT);
    cso_save_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT);
    cso_save_stream_outputs(ctx->cso);
-   cso_save_viewport(ctx->cso);
+   cso_save_viewports(ctx->cso);
    cso_save_framebuffer(ctx->cso);
    cso_save_fragment_shader(ctx->cso);
    cso_save_vertex_shader(ctx->cso);
@@ -751,7 +751,7 @@ util_blit_pixels(struct blit_state *ctx,
    ctx->viewport.translate[1] = 0.5f * dst_surface->height;
    ctx->viewport.translate[2] = 0.5f;
    ctx->viewport.translate[3] = 0.0f;
-   cso_set_viewport(ctx->cso, &ctx->viewport);
+   cso_set_viewports(ctx->cso, 1, &ctx->viewport);
 
    set_vertex_shader(ctx);
    cso_set_geometry_shader_handle(ctx->cso, NULL);
@@ -794,7 +794,7 @@ util_blit_pixels(struct blit_state *ctx,
    cso_restore_sample_mask(ctx->cso);
    cso_restore_samplers(ctx->cso, PIPE_SHADER_FRAGMENT);
    cso_restore_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT);
-   cso_restore_viewport(ctx->cso);
+   cso_restore_viewports(ctx->cso);
    cso_restore_framebuffer(ctx->cso);
    cso_restore_fragment_shader(ctx->cso);
    cso_restore_vertex_shader(ctx->cso);
@@ -869,7 +869,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
    cso_save_samplers(ctx->cso, PIPE_SHADER_FRAGMENT);
    cso_save_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT);
    cso_save_stream_outputs(ctx->cso);
-   cso_save_viewport(ctx->cso);
+   cso_save_viewports(ctx->cso);
    cso_save_framebuffer(ctx->cso);
    cso_save_fragment_shader(ctx->cso);
    cso_save_vertex_shader(ctx->cso);
@@ -901,7 +901,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
    ctx->viewport.translate[1] = 0.5f * dst->height;
    ctx->viewport.translate[2] = 0.5f;
    ctx->viewport.translate[3] = 0.0f;
-   cso_set_viewport(ctx->cso, &ctx->viewport);
+   cso_set_viewports(ctx->cso, 1, &ctx->viewport);
 
    /* texture */
    cso_set_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT, 1, &src_sampler_view);
@@ -943,7 +943,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
    cso_restore_sample_mask(ctx->cso);
    cso_restore_samplers(ctx->cso, PIPE_SHADER_FRAGMENT);
    cso_restore_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT);
-   cso_restore_viewport(ctx->cso);
+   cso_restore_viewports(ctx->cso);
    cso_restore_framebuffer(ctx->cso);
    cso_restore_fragment_shader(ctx->cso);
    cso_restore_vertex_shader(ctx->cso);
diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c
index 2acc5af..e985376 100644
--- a/src/gallium/auxiliary/util/u_blitter.c
+++ b/src/gallium/auxiliary/util/u_blitter.c
@@ -504,7 +504,7 @@ static void blitter_restore_fragment_states(struct blitter_context_priv *ctx)
    /* XXX check whether these are saved and whether they need to be restored
     * (depending on the operation) */
    pipe->set_stencil_ref(pipe, &ctx->base.saved_stencil_ref);
-   pipe->set_viewport_state(pipe, &ctx->base.saved_viewport);
+   pipe->set_viewport_states(pipe, 1, &ctx->base.saved_viewport);
 }
 
 static void blitter_check_saved_fb_state(struct blitter_context_priv *ctx)
@@ -599,7 +599,7 @@ static void blitter_set_rectangle(struct blitter_context_priv *ctx,
    ctx->viewport.translate[1] = 0.5f * ctx->dst_height;
    ctx->viewport.translate[2] = 0.0f;
    ctx->viewport.translate[3] = 0.0f;
-   ctx->base.pipe->set_viewport_state(ctx->base.pipe, &ctx->viewport);
+   ctx->base.pipe->set_viewport_states(ctx->base.pipe, 1, &ctx->viewport);
 }
 
 static void blitter_set_clear_color(struct blitter_context_priv *ctx,
@@ -1401,7 +1401,7 @@ void util_blitter_blit_generic(struct blitter_context *blitter,
 
    pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
    if (scissor) {
-      pipe->set_scissor_state(pipe, scissor);
+      pipe->set_scissor_states(pipe, 1, scissor);
    }
 
    blitter_set_common_draw_rect_state(ctx, scissor != NULL);
@@ -1496,7 +1496,7 @@ void util_blitter_blit_generic(struct blitter_context *blitter,
    blitter_restore_textures(ctx);
    blitter_restore_fb_state(ctx);
    if (scissor) {
-      pipe->set_scissor_state(pipe, &ctx->base.saved_scissor);
+      pipe->set_scissor_states(pipe, 1, &ctx->base.saved_scissor);
    }
    blitter_restore_render_cond(ctx);
    blitter_unset_running_flag(ctx);
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c
index 7974b1d..c852bc2 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.c
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.c
@@ -1564,7 +1564,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
    cso_save_fragment_shader(ctx->cso);
    cso_save_vertex_shader(ctx->cso);
    cso_save_geometry_shader(ctx->cso);
-   cso_save_viewport(ctx->cso);
+   cso_save_viewports(ctx->cso);
    cso_save_vertex_elements(ctx->cso);
    cso_save_aux_vertex_buffer_slot(ctx->cso);
    cso_save_render_condition(ctx->cso);
@@ -1648,7 +1648,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
          vp.translate[1] = 0.5f * fb.height;
          vp.translate[2] = 0.0f;
          vp.translate[3] = 0.0f;
-         cso_set_viewport(ctx->cso, &vp);
+         cso_set_viewports(ctx->cso, 1, &vp);
 
          /*
           * Setup sampler state
@@ -1695,7 +1695,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
    cso_restore_fragment_shader(ctx->cso);
    cso_restore_vertex_shader(ctx->cso);
    cso_restore_geometry_shader(ctx->cso);
-   cso_restore_viewport(ctx->cso);
+   cso_restore_viewports(ctx->cso);
    cso_restore_vertex_elements(ctx->cso);
    cso_restore_stream_outputs(ctx->cso);
    cso_restore_aux_vertex_buffer_slot(ctx->cso);
diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c
index 62f593a..a1d72bd 100644
--- a/src/gallium/auxiliary/vl/vl_compositor.c
+++ b/src/gallium/auxiliary/vl/vl_compositor.c
@@ -723,7 +723,7 @@ draw_layers(struct vl_compositor *c, struct vl_compositor_state *s, struct u_rec
          void *blend = layer->blend ? layer->blend : i ? c->blend_add : c->blend_clear;
 
          c->pipe->bind_blend_state(c->pipe, blend);
-         c->pipe->set_viewport_state(c->pipe, &layer->viewport);
+         c->pipe->set_viewport_states(c->pipe, 1, &layer->viewport);
          c->pipe->bind_fs_state(c->pipe, layer->fs);
          c->pipe->bind_fragment_sampler_states(c->pipe, num_sampler_views, layer->samplers);
          c->pipe->set_fragment_sampler_views(c->pipe, num_sampler_views, samplers);
@@ -1014,7 +1014,7 @@ vl_compositor_render(struct vl_compositor_state *s,
       dirty_area->x1 = dirty_area->y1 = MIN_DIRTY;
    }
 
-   c->pipe->set_scissor_state(c->pipe, &s->scissor);
+   c->pipe->set_scissor_states(c->pipe, 1, &s->scissor);
    c->pipe->set_framebuffer_state(c->pipe, &c->fb_state);
    c->pipe->bind_vs_state(c->pipe, c->vs);
    c->pipe->set_vertex_buffers(c->pipe, 0, 1, &c->vertex_buf);
diff --git a/src/gallium/auxiliary/vl/vl_idct.c b/src/gallium/auxiliary/vl/vl_idct.c
index bd73dfd..70a823a 100644
--- a/src/gallium/auxiliary/vl/vl_idct.c
+++ b/src/gallium/auxiliary/vl/vl_idct.c
@@ -830,14 +830,14 @@ vl_idct_flush(struct vl_idct *idct, struct vl_idct_buffer *buffer, unsigned num_
 
    /* mismatch control */
    idct->pipe->set_framebuffer_state(idct->pipe, &buffer->fb_state_mismatch);
-   idct->pipe->set_viewport_state(idct->pipe, &buffer->viewport_mismatch);
+   idct->pipe->set_viewport_states(idct->pipe, 1, &buffer->viewport_mismatch);
    idct->pipe->bind_vs_state(idct->pipe, idct->vs_mismatch);
    idct->pipe->bind_fs_state(idct->pipe, idct->fs_mismatch);
    util_draw_arrays_instanced(idct->pipe, PIPE_PRIM_POINTS, 0, 1, 0, num_instances);
 
    /* first stage */
    idct->pipe->set_framebuffer_state(idct->pipe, &buffer->fb_state);
-   idct->pipe->set_viewport_state(idct->pipe, &buffer->viewport);
+   idct->pipe->set_viewport_states(idct->pipe, 1, &buffer->viewport);
    idct->pipe->bind_vs_state(idct->pipe, idct->vs);
    idct->pipe->bind_fs_state(idct->pipe, idct->fs);
    util_draw_arrays_instanced(idct->pipe, PIPE_PRIM_QUADS, 0, 4, 0, num_instances);
diff --git a/src/gallium/auxiliary/vl/vl_matrix_filter.c b/src/gallium/auxiliary/vl/vl_matrix_filter.c
index cda90ff..4f2d125 100644
--- a/src/gallium/auxiliary/vl/vl_matrix_filter.c
+++ b/src/gallium/auxiliary/vl/vl_matrix_filter.c
@@ -311,7 +311,7 @@ vl_matrix_filter_render(struct vl_matrix_filter *filter,
    filter->pipe->bind_vs_state(filter->pipe, filter->vs);
    filter->pipe->bind_fs_state(filter->pipe, filter->fs);
    filter->pipe->set_framebuffer_state(filter->pipe, &fb_state);
-   filter->pipe->set_viewport_state(filter->pipe, &viewport);
+   filter->pipe->set_viewport_states(filter->pipe, 1, &viewport);
    filter->pipe->set_vertex_buffers(filter->pipe, 0, 1, &filter->quad);
    filter->pipe->bind_vertex_elements_state(filter->pipe, filter->ves);
 
diff --git a/src/gallium/auxiliary/vl/vl_mc.c b/src/gallium/auxiliary/vl/vl_mc.c
index b427209..f90018d 100644
--- a/src/gallium/auxiliary/vl/vl_mc.c
+++ b/src/gallium/auxiliary/vl/vl_mc.c
@@ -600,7 +600,7 @@ prepare_pipe_4_rendering(struct vl_mc *renderer, struct vl_mc_buffer *buffer, un
       renderer->pipe->bind_blend_state(renderer->pipe, renderer->blend_clear[mask]);
 
    renderer->pipe->set_framebuffer_state(renderer->pipe, &buffer->fb_state);
-   renderer->pipe->set_viewport_state(renderer->pipe, &buffer->viewport);
+   renderer->pipe->set_viewport_states(renderer->pipe, 1, &buffer->viewport);
 }
 
 void
diff --git a/src/gallium/auxiliary/vl/vl_median_filter.c b/src/gallium/auxiliary/vl/vl_median_filter.c
index 2db1479..51657bb 100644
--- a/src/gallium/auxiliary/vl/vl_median_filter.c
+++ b/src/gallium/auxiliary/vl/vl_median_filter.c
@@ -390,7 +390,7 @@ vl_median_filter_render(struct vl_median_filter *filter,
    filter->pipe->bind_vs_state(filter->pipe, filter->vs);
    filter->pipe->bind_fs_state(filter->pipe, filter->fs);
    filter->pipe->set_framebuffer_state(filter->pipe, &fb_state);
-   filter->pipe->set_viewport_state(filter->pipe, &viewport);
+   filter->pipe->set_viewport_states(filter->pipe, 1, &viewport);
    filter->pipe->set_vertex_buffers(filter->pipe, 0, 1, &filter->quad);
    filter->pipe->bind_vertex_elements_state(filter->pipe, filter->ves);
 
diff --git a/src/gallium/auxiliary/vl/vl_zscan.c b/src/gallium/auxiliary/vl/vl_zscan.c
index 262fb0d..1125d44 100644
--- a/src/gallium/auxiliary/vl/vl_zscan.c
+++ b/src/gallium/auxiliary/vl/vl_zscan.c
@@ -576,7 +576,7 @@ vl_zscan_render(struct vl_zscan *zscan, struct vl_zscan_buffer *buffer, unsigned
    zscan->pipe->bind_blend_state(zscan->pipe, zscan->blend);
    zscan->pipe->bind_fragment_sampler_states(zscan->pipe, 3, zscan->samplers);
    zscan->pipe->set_framebuffer_state(zscan->pipe, &buffer->fb_state);
-   zscan->pipe->set_viewport_state(zscan->pipe, &buffer->viewport);
+   zscan->pipe->set_viewport_states(zscan->pipe, 1, &buffer->viewport);
    zscan->pipe->set_fragment_sampler_views(zscan->pipe, 3, &buffer->src);
    zscan->pipe->bind_vs_state(zscan->pipe, zscan->vs);
    zscan->pipe->bind_fs_state(zscan->pipe, zscan->fs);
diff --git a/src/gallium/docs/source/context.rst b/src/gallium/docs/source/context.rst
index 2cc1848..679772f 100644
--- a/src/gallium/docs/source/context.rst
+++ b/src/gallium/docs/source/context.rst
@@ -68,13 +68,15 @@ objects. They all follow simple, one-method binding calls, e.g.
 * ``set_sample_mask``
 * ``set_clip_state``
 * ``set_polygon_stipple``
-* ``set_scissor_state`` sets the bounds for the scissor test, which culls
+* ``set_scissor_states`` sets the bounds for the scissor test, which culls
   pixels before blending to render targets. If the :ref:`Rasterizer` does
   not have the scissor test enabled, then the scissor bounds never need to
   be set since they will not be used.  Note that scissor xmin and ymin are
   inclusive, but  xmax and ymax are exclusive.  The inclusive ranges in x
-  and y would be [xmin..xmax-1] and [ymin..ymax-1].
-* ``set_viewport_state``
+  and y would be [xmin..xmax-1] and [ymin..ymax-1]. The number of scissors
+  should be the same as the number of set viewports and can be up to
+  PIPE_MAX_VIEWPORTS.
+* ``set_viewport_states``
 
 
 Sampler Views
diff --git a/src/gallium/drivers/freedreno/freedreno_state.c b/src/gallium/drivers/freedreno/freedreno_state.c
index dcac624..6435e22 100644
--- a/src/gallium/drivers/freedreno/freedreno_state.c
+++ b/src/gallium/drivers/freedreno/freedreno_state.c
@@ -147,7 +147,8 @@ fd_set_polygon_stipple(struct pipe_context *pctx,
 }
 
 static void
-fd_set_scissor_state(struct pipe_context *pctx,
+fd_set_scissor_states(struct pipe_context *pctx,
+                      unsigned num_scissors,
 		const struct pipe_scissor_state *scissor)
 {
 	struct fd_context *ctx = fd_context(pctx);
@@ -157,7 +158,8 @@ fd_set_scissor_state(struct pipe_context *pctx,
 }
 
 static void
-fd_set_viewport_state(struct pipe_context *pctx,
+fd_set_viewport_states(struct pipe_context *pctx,
+                      unsigned num_viewports,
 		const struct pipe_viewport_state *viewport)
 {
 	struct fd_context *ctx = fd_context(pctx);
@@ -223,8 +225,8 @@ fd_state_init(struct pipe_context *pctx)
 	pctx->set_constant_buffer = fd_set_constant_buffer;
 	pctx->set_framebuffer_state = fd_set_framebuffer_state;
 	pctx->set_polygon_stipple = fd_set_polygon_stipple;
-	pctx->set_scissor_state = fd_set_scissor_state;
-	pctx->set_viewport_state = fd_set_viewport_state;
+	pctx->set_scissor_states = fd_set_scissor_states;
+	pctx->set_viewport_states = fd_set_viewport_states;
 
 	pctx->set_vertex_buffers = fd_set_vertex_buffers;
 	pctx->set_index_buffer = fd_set_index_buffer;
diff --git a/src/gallium/drivers/galahad/glhd_context.c b/src/gallium/drivers/galahad/glhd_context.c
index a73a3ad..849c12e 100644
--- a/src/gallium/drivers/galahad/glhd_context.c
+++ b/src/gallium/drivers/galahad/glhd_context.c
@@ -524,25 +524,27 @@ galahad_context_set_polygon_stipple(struct pipe_context *_pipe,
 }
 
 static void
-galahad_context_set_scissor_state(struct pipe_context *_pipe,
+galahad_context_set_scissor_states(struct pipe_context *_pipe,
+                                   unsigned num_scissors,
                            const struct pipe_scissor_state *scissor)
 {
    struct galahad_context *glhd_pipe = galahad_context(_pipe);
    struct pipe_context *pipe = glhd_pipe->pipe;
 
-   pipe->set_scissor_state(pipe,
+   pipe->set_scissor_states(pipe, num_scissors,
                            scissor);
 }
 
 static void
-galahad_context_set_viewport_state(struct pipe_context *_pipe,
+galahad_context_set_viewport_states(struct pipe_context *_pipe,
+                                    unsigned num_viewports,
                             const struct pipe_viewport_state *viewport)
 {
    struct galahad_context *glhd_pipe = galahad_context(_pipe);
    struct pipe_context *pipe = glhd_pipe->pipe;
 
-   pipe->set_viewport_state(pipe,
-                            viewport);
+   pipe->set_viewport_states(pipe, num_viewports,
+                             viewport);
 }
 
 static void
@@ -1077,8 +1079,8 @@ galahad_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
    GLHD_PIPE_INIT(set_constant_buffer);
    GLHD_PIPE_INIT(set_framebuffer_state);
    GLHD_PIPE_INIT(set_polygon_stipple);
-   GLHD_PIPE_INIT(set_scissor_state);
-   GLHD_PIPE_INIT(set_viewport_state);
+   GLHD_PIPE_INIT(set_scissor_states);
+   GLHD_PIPE_INIT(set_viewport_states);
    GLHD_PIPE_INIT(set_fragment_sampler_views);
    GLHD_PIPE_INIT(set_vertex_sampler_views);
    GLHD_PIPE_INIT(set_geometry_sampler_views);
diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c
index 4a4faa5..cdd293d 100644
--- a/src/gallium/drivers/i915/i915_state.c
+++ b/src/gallium/drivers/i915/i915_state.c
@@ -534,7 +534,8 @@ static void i915_delete_depth_stencil_state(struct pipe_context *pipe,
 }
 
 
-static void i915_set_scissor_state( struct pipe_context *pipe,
+static void i915_set_scissor_states( struct pipe_context *pipe,
+                                     unsigned num_scissors,
                                  const struct pipe_scissor_state *scissor )
 {
    struct i915_context *i915 = i915_context(pipe);
@@ -825,7 +826,8 @@ static void i915_set_clip_state( struct pipe_context *pipe,
 /* Called when driver state tracker notices changes to the viewport
  * matrix:
  */
-static void i915_set_viewport_state( struct pipe_context *pipe,
+static void i915_set_viewport_states( struct pipe_context *pipe,
+                                      unsigned num_viewports,
 				     const struct pipe_viewport_state *viewport )
 {
    struct i915_context *i915 = i915_context(pipe);
@@ -833,7 +835,7 @@ static void i915_set_viewport_state( struct pipe_context *pipe,
    i915->viewport = *viewport; /* struct copy */
 
    /* pass the viewport info to the draw module */
-   draw_set_viewport_state(i915->draw, &i915->viewport);
+   draw_set_viewport_states(i915->draw, num_viewports, &i915->viewport);
 
    i915->dirty |= I915_NEW_VIEWPORT;
 }
@@ -1040,12 +1042,12 @@ i915_init_state_functions( struct i915_context *i915 )
    i915->base.set_framebuffer_state = i915_set_framebuffer_state;
 
    i915->base.set_polygon_stipple = i915_set_polygon_stipple;
-   i915->base.set_scissor_state = i915_set_scissor_state;
+   i915->base.set_scissor_states = i915_set_scissor_states;
    i915->base.set_fragment_sampler_views = i915_set_fragment_sampler_views;
    i915->base.set_vertex_sampler_views = i915_set_vertex_sampler_views;
    i915->base.create_sampler_view = i915_create_sampler_view;
    i915->base.sampler_view_destroy = i915_sampler_view_destroy;
-   i915->base.set_viewport_state = i915_set_viewport_state;
+   i915->base.set_viewport_states = i915_set_viewport_states;
    i915->base.set_vertex_buffers = i915_set_vertex_buffers;
    i915->base.set_index_buffer = i915_set_index_buffer;
 }
diff --git a/src/gallium/drivers/identity/id_context.c b/src/gallium/drivers/identity/id_context.c
index 0eff6c9..7d672c8 100644
--- a/src/gallium/drivers/identity/id_context.c
+++ b/src/gallium/drivers/identity/id_context.c
@@ -486,25 +486,27 @@ identity_set_polygon_stipple(struct pipe_context *_pipe,
 }
 
 static void
-identity_set_scissor_state(struct pipe_context *_pipe,
-                           const struct pipe_scissor_state *scissor)
+identity_set_scissor_states(struct pipe_context *_pipe,
+                            unsigned num_scissors,
+                            const struct pipe_scissor_state *scissor)
 {
    struct identity_context *id_pipe = identity_context(_pipe);
    struct pipe_context *pipe = id_pipe->pipe;
 
-   pipe->set_scissor_state(pipe,
-                           scissor);
+   pipe->set_scissor_states(pipe, num_scissors,
+                            scissor);
 }
 
 static void
-identity_set_viewport_state(struct pipe_context *_pipe,
-                            const struct pipe_viewport_state *viewport)
+identity_set_viewport_states(struct pipe_context *_pipe,
+                             unsigned num_viewports,
+                             const struct pipe_viewport_state *viewport)
 {
    struct identity_context *id_pipe = identity_context(_pipe);
    struct pipe_context *pipe = id_pipe->pipe;
 
-   pipe->set_viewport_state(pipe,
-                            viewport);
+   pipe->set_viewport_states(pipe, num_viewports,
+                             viewport);
 }
 
 static void
@@ -914,8 +916,8 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
    id_pipe->base.set_constant_buffer = identity_set_constant_buffer;
    id_pipe->base.set_framebuffer_state = identity_set_framebuffer_state;
    id_pipe->base.set_polygon_stipple = identity_set_polygon_stipple;
-   id_pipe->base.set_scissor_state = identity_set_scissor_state;
-   id_pipe->base.set_viewport_state = identity_set_viewport_state;
+   id_pipe->base.set_scissor_states = identity_set_scissor_states;
+   id_pipe->base.set_viewport_states = identity_set_viewport_states;
    id_pipe->base.set_fragment_sampler_views = identity_set_fragment_sampler_views;
    id_pipe->base.set_vertex_sampler_views = identity_set_vertex_sampler_views;
    id_pipe->base.set_vertex_buffers = identity_set_vertex_buffers;
diff --git a/src/gallium/drivers/ilo/ilo_state.c b/src/gallium/drivers/ilo/ilo_state.c
index 8443a2c..0ec3dc1 100644
--- a/src/gallium/drivers/ilo/ilo_state.c
+++ b/src/gallium/drivers/ilo/ilo_state.c
@@ -563,8 +563,9 @@ ilo_set_polygon_stipple(struct pipe_context *pipe,
 }
 
 static void
-ilo_set_scissor_state(struct pipe_context *pipe,
-                      const struct pipe_scissor_state *state)
+ilo_set_scissor_states(struct pipe_context *pipe,
+                       unsigned num_scissors,
+                       const struct pipe_scissor_state *state)
 {
    struct ilo_context *ilo = ilo_context(pipe);
 
@@ -574,8 +575,9 @@ ilo_set_scissor_state(struct pipe_context *pipe,
 }
 
 static void
-ilo_set_viewport_state(struct pipe_context *pipe,
-                       const struct pipe_viewport_state *state)
+ilo_set_viewport_states(struct pipe_context *pipe,
+                        unsigned num_viewports,
+                        const struct pipe_viewport_state *state)
 {
    struct ilo_context *ilo = ilo_context(pipe);
 
@@ -992,8 +994,8 @@ ilo_init_state_functions(struct ilo_context *ilo)
    ilo->base.set_constant_buffer = ilo_set_constant_buffer;
    ilo->base.set_framebuffer_state = ilo_set_framebuffer_state;
    ilo->base.set_polygon_stipple = ilo_set_polygon_stipple;
-   ilo->base.set_scissor_state = ilo_set_scissor_state;
-   ilo->base.set_viewport_state = ilo_set_viewport_state;
+   ilo->base.set_scissor_states = ilo_set_scissor_states;
+   ilo->base.set_viewport_states = ilo_set_viewport_states;
    ilo->base.set_fragment_sampler_views = ilo_set_fragment_sampler_views;
    ilo->base.set_vertex_sampler_views = ilo_set_vertex_sampler_views;
    ilo->base.set_geometry_sampler_views = ilo_set_geometry_sampler_views;
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
index 073d751..712b7c6 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -230,6 +230,8 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
       return 1;
    case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
       return 0;
+   case PIPE_CAP_MULTIPLE_VIEWPORTS:
+      return 0;
    }
    /* should only get here on unhandled cases */
    debug_printf("Unexpected PIPE_CAP %d query\n", param);
diff --git a/src/gallium/drivers/llvmpipe/lp_state_clip.c b/src/gallium/drivers/llvmpipe/lp_state_clip.c
index 32ae079..ed47e5e 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_clip.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_clip.c
@@ -44,28 +44,30 @@ llvmpipe_set_clip_state(struct pipe_context *pipe,
 
 
 static void
-llvmpipe_set_viewport_state(struct pipe_context *pipe,
-                            const struct pipe_viewport_state *viewport)
+llvmpipe_set_viewport_states(struct pipe_context *pipe,
+                             unsigned num_viewports,
+                             const struct pipe_viewport_state *viewports)
 {
    struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
 
    /* pass the viewport info to the draw module */
-   draw_set_viewport_state(llvmpipe->draw, viewport);
+   draw_set_viewport_states(llvmpipe->draw, num_viewports, viewports);
 
-   llvmpipe->viewport = *viewport; /* struct copy */
+   llvmpipe->viewport = *viewports; /* struct copy */
    llvmpipe->dirty |= LP_NEW_VIEWPORT;
 }
 
 
 static void
-llvmpipe_set_scissor_state(struct pipe_context *pipe,
-                           const struct pipe_scissor_state *scissor)
+llvmpipe_set_scissor_states(struct pipe_context *pipe,
+                            unsigned num_scissors,
+                            const struct pipe_scissor_state *scissors)
 {
    struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
 
    draw_flush(llvmpipe->draw);
 
-   llvmpipe->scissor = *scissor; /* struct copy */
+   llvmpipe->scissor = *scissors; /* struct copy */
    llvmpipe->dirty |= LP_NEW_SCISSOR;
 }
 
@@ -89,6 +91,6 @@ llvmpipe_init_clip_funcs(struct llvmpipe_context *llvmpipe)
 {
    llvmpipe->pipe.set_clip_state = llvmpipe_set_clip_state;
    llvmpipe->pipe.set_polygon_stipple = llvmpipe_set_polygon_stipple;
-   llvmpipe->pipe.set_scissor_state = llvmpipe_set_scissor_state;
-   llvmpipe->pipe.set_viewport_state = llvmpipe_set_viewport_state;
+   llvmpipe->pipe.set_scissor_states = llvmpipe_set_scissor_states;
+   llvmpipe->pipe.set_viewport_states = llvmpipe_set_viewport_states;
 }
diff --git a/src/gallium/drivers/noop/noop_state.c b/src/gallium/drivers/noop/noop_state.c
index f56ff59..ceef623 100644
--- a/src/gallium/drivers/noop/noop_state.c
+++ b/src/gallium/drivers/noop/noop_state.c
@@ -152,8 +152,9 @@ static void noop_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask
 {
 }
 
-static void noop_set_scissor_state(struct pipe_context *ctx,
-					const struct pipe_scissor_state *state)
+static void noop_set_scissor_states(struct pipe_context *ctx,
+                                    unsigned num_scissors,
+                                    const struct pipe_scissor_state *state)
 {
 }
 
@@ -162,8 +163,9 @@ static void noop_set_stencil_ref(struct pipe_context *ctx,
 {
 }
 
-static void noop_set_viewport_state(struct pipe_context *ctx,
-					const struct pipe_viewport_state *state)
+static void noop_set_viewport_states(struct pipe_context *ctx,
+                                     unsigned num_viewports,
+                                     const struct pipe_viewport_state *state)
 {
 }
 
@@ -311,12 +313,12 @@ void noop_init_state_functions(struct pipe_context *ctx)
 	ctx->set_framebuffer_state = noop_set_framebuffer_state;
 	ctx->set_polygon_stipple = noop_set_polygon_stipple;
 	ctx->set_sample_mask = noop_set_sample_mask;
-	ctx->set_scissor_state = noop_set_scissor_state;
+	ctx->set_scissor_states = noop_set_scissor_states;
 	ctx->set_stencil_ref = noop_set_stencil_ref;
 	ctx->set_vertex_buffers = noop_set_vertex_buffers;
 	ctx->set_index_buffer = noop_set_index_buffer;
 	ctx->set_vertex_sampler_views = noop_set_vs_sampler_view;
-	ctx->set_viewport_state = noop_set_viewport_state;
+	ctx->set_viewport_states = noop_set_viewport_states;
 	ctx->sampler_view_destroy = noop_sampler_view_destroy;
 	ctx->surface_destroy = noop_surface_destroy;
 	ctx->draw_vbo = noop_draw_vbo;
diff --git a/src/gallium/drivers/nv30/nv30_draw.c b/src/gallium/drivers/nv30/nv30_draw.c
index e0a1628..ebc701e 100644
--- a/src/gallium/drivers/nv30/nv30_draw.c
+++ b/src/gallium/drivers/nv30/nv30_draw.c
@@ -373,7 +373,7 @@ nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
    nv30_render_validate(nv30);
 
    if (nv30->draw_dirty & NV30_NEW_VIEWPORT)
-      draw_set_viewport_state(draw, &nv30->viewport);
+      draw_set_viewport_states(draw, 1, &nv30->viewport);
    if (nv30->draw_dirty & NV30_NEW_RASTERIZER)
       draw_set_rasterizer_state(draw, &nv30->rast->pipe, NULL);
    if (nv30->draw_dirty & NV30_NEW_CLIP)
diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c
index 2a80974..e13daf0 100644
--- a/src/gallium/drivers/nv30/nv30_state.c
+++ b/src/gallium/drivers/nv30/nv30_state.c
@@ -373,8 +373,9 @@ nv30_set_polygon_stipple(struct pipe_context *pipe,
 }
 
 static void
-nv30_set_scissor_state(struct pipe_context *pipe,
-                       const struct pipe_scissor_state *scissor)
+nv30_set_scissor_states(struct pipe_context *pipe,
+                        unsigned num_viewports,
+                        const struct pipe_scissor_state *scissor)
 {
     struct nv30_context *nv30 = nv30_context(pipe);
 
@@ -383,8 +384,9 @@ nv30_set_scissor_state(struct pipe_context *pipe,
 }
 
 static void
-nv30_set_viewport_state(struct pipe_context *pipe,
-                        const struct pipe_viewport_state *vpt)
+nv30_set_viewport_states(struct pipe_context *pipe,
+                         unsigned num_viewports,
+                         const struct pipe_viewport_state *vpt)
 {
     struct nv30_context *nv30 = nv30_context(pipe);
 
@@ -446,8 +448,8 @@ nv30_state_init(struct pipe_context *pipe)
    pipe->set_constant_buffer = nv30_set_constant_buffer;
    pipe->set_framebuffer_state = nv30_set_framebuffer_state;
    pipe->set_polygon_stipple = nv30_set_polygon_stipple;
-   pipe->set_scissor_state = nv30_set_scissor_state;
-   pipe->set_viewport_state = nv30_set_viewport_state;
+   pipe->set_scissor_states = nv30_set_scissor_states;
+   pipe->set_viewport_states = nv30_set_viewport_states;
 
    pipe->set_vertex_buffers = nv30_set_vertex_buffers;
    pipe->set_index_buffer = nv30_set_index_buffer;
diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c
index ffabf4c..83d3db1 100644
--- a/src/gallium/drivers/nv50/nv50_state.c
+++ b/src/gallium/drivers/nv50/nv50_state.c
@@ -871,8 +871,9 @@ nv50_set_polygon_stipple(struct pipe_context *pipe,
 }
 
 static void
-nv50_set_scissor_state(struct pipe_context *pipe,
-                       const struct pipe_scissor_state *scissor)
+nv50_set_scissor_states(struct pipe_context *pipe,
+                        unsigned num_scissors,
+                        const struct pipe_scissor_state *scissor)
 {
    struct nv50_context *nv50 = nv50_context(pipe);
 
@@ -881,12 +882,13 @@ nv50_set_scissor_state(struct pipe_context *pipe,
 }
 
 static void
-nv50_set_viewport_state(struct pipe_context *pipe,
-                        const struct pipe_viewport_state *vpt)
+nv50_set_viewport_states(struct pipe_context *pipe,
+                         unsigned num_viewports,
+                         const struct pipe_viewport_state *vpt)
 {
    struct nv50_context *nv50 = nv50_context(pipe);
 
-   nv50->viewport = *vpt;
+   nv50->viewport = vpt[0];
    nv50->dirty |= NV50_NEW_VIEWPORT;
 }
 
@@ -1090,8 +1092,8 @@ nv50_init_state_functions(struct nv50_context *nv50)
    pipe->set_constant_buffer = nv50_set_constant_buffer;
    pipe->set_framebuffer_state = nv50_set_framebuffer_state;
    pipe->set_polygon_stipple = nv50_set_polygon_stipple;
-   pipe->set_scissor_state = nv50_set_scissor_state;
-   pipe->set_viewport_state = nv50_set_viewport_state;
+   pipe->set_scissor_states = nv50_set_scissor_states;
+   pipe->set_viewport_states = nv50_set_viewport_states;
 
    pipe->create_vertex_elements_state = nv50_vertex_state_create;
    pipe->delete_vertex_elements_state = nv50_vertex_state_delete;
diff --git a/src/gallium/drivers/nvc0/nvc0_state.c b/src/gallium/drivers/nvc0/nvc0_state.c
index 9adc99c..96c86b1 100644
--- a/src/gallium/drivers/nvc0/nvc0_state.c
+++ b/src/gallium/drivers/nvc0/nvc0_state.c
@@ -903,8 +903,9 @@ nvc0_set_polygon_stipple(struct pipe_context *pipe,
 }
 
 static void
-nvc0_set_scissor_state(struct pipe_context *pipe,
-                       const struct pipe_scissor_state *scissor)
+nvc0_set_scissor_states(struct pipe_context *pipe,
+                        unsigned num_scissors,
+                        const struct pipe_scissor_state *scissor)
 {
     struct nvc0_context *nvc0 = nvc0_context(pipe);
 
@@ -913,8 +914,9 @@ nvc0_set_scissor_state(struct pipe_context *pipe,
 }
 
 static void
-nvc0_set_viewport_state(struct pipe_context *pipe,
-                        const struct pipe_viewport_state *vpt)
+nvc0_set_viewport_states(struct pipe_context *pipe,
+                         unsigned num_viewports,
+                         const struct pipe_viewport_state *vpt)
 {
     struct nvc0_context *nvc0 = nvc0_context(pipe);
 
@@ -1223,8 +1225,8 @@ nvc0_init_state_functions(struct nvc0_context *nvc0)
    pipe->set_constant_buffer = nvc0_set_constant_buffer;
    pipe->set_framebuffer_state = nvc0_set_framebuffer_state;
    pipe->set_polygon_stipple = nvc0_set_polygon_stipple;
-   pipe->set_scissor_state = nvc0_set_scissor_state;
-   pipe->set_viewport_state = nvc0_set_viewport_state;
+   pipe->set_scissor_states = nvc0_set_scissor_states;
+   pipe->set_viewport_states = nvc0_set_viewport_states;
 
    pipe->create_vertex_elements_state = nvc0_vertex_state_create;
    pipe->delete_vertex_elements_state = nvc0_vertex_state_delete;
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index ba1859b..443a9a6 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -275,7 +275,7 @@ static void r300_init_states(struct pipe_context *pipe)
 
     pipe->set_blend_color(pipe, &bc);
     pipe->set_clip_state(pipe, &cs);
-    pipe->set_scissor_state(pipe, &ss);
+    pipe->set_scissor_states(pipe, 1, &ss);
     pipe->set_sample_mask(pipe, ~0);
 
     /* Initialize the GPU flush. */
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 36d510d..410cf66 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -1722,8 +1722,9 @@ static void r300_set_sample_mask(struct pipe_context *pipe,
     r300_mark_atom_dirty(r300, &r300->sample_mask);
 }
 
-static void r300_set_scissor_state(struct pipe_context* pipe,
-                                   const struct pipe_scissor_state* state)
+static void r300_set_scissor_states(struct pipe_context* pipe,
+                                    unsigned num_scissors,
+                                    const struct pipe_scissor_state* state)
 {
     struct r300_context* r300 = r300_context(pipe);
 
@@ -1733,8 +1734,9 @@ static void r300_set_scissor_state(struct pipe_context* pipe,
     r300_mark_atom_dirty(r300, &r300->scissor_state);
 }
 
-static void r300_set_viewport_state(struct pipe_context* pipe,
-                                    const struct pipe_viewport_state* state)
+static void r300_set_viewport_states(struct pipe_context* pipe,
+                                     unsigned num_viewports,
+                                     const struct pipe_viewport_state* state)
 {
     struct r300_context* r300 = r300_context(pipe);
     struct r300_viewport_state* viewport =
@@ -1743,7 +1745,7 @@ static void r300_set_viewport_state(struct pipe_context* pipe,
     r300->viewport = *state;
 
     if (r300->draw) {
-        draw_set_viewport_state(r300->draw, state);
+        draw_set_viewport_states(r300->draw, num_viewports, state);
         viewport->vte_control = R300_VTX_XY_FMT | R300_VTX_Z_FMT;
         return;
     }
@@ -2162,9 +2164,9 @@ void r300_init_state_functions(struct r300_context* r300)
     r300->context.create_sampler_view = r300_create_sampler_view;
     r300->context.sampler_view_destroy = r300_sampler_view_destroy;
 
-    r300->context.set_scissor_state = r300_set_scissor_state;
+    r300->context.set_scissor_states = r300_set_scissor_states;
 
-    r300->context.set_viewport_state = r300_set_viewport_state;
+    r300->context.set_viewport_states = r300_set_viewport_states;
 
     if (r300->screen->caps.has_tcl) {
         r300->context.set_vertex_buffers = r300_set_vertex_buffers_hwtcl;
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index f49c595..3b66252 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -1309,7 +1309,8 @@ static void evergreen_get_scissor_rect(struct r600_context *rctx,
 	*br = S_028244_BR_X(br_x) | S_028244_BR_Y(br_y);
 }
 
-static void evergreen_set_scissor_state(struct pipe_context *ctx,
+static void evergreen_set_scissor_states(struct pipe_context *ctx,
+                                         unsigned num_scissors,
 					const struct pipe_scissor_state *state)
 {
 	struct r600_context *rctx = (struct r600_context *)ctx;
@@ -3860,7 +3861,7 @@ void evergreen_init_state_functions(struct r600_context *rctx)
 	rctx->context.create_sampler_view = evergreen_create_sampler_view;
 	rctx->context.set_framebuffer_state = evergreen_set_framebuffer_state;
 	rctx->context.set_polygon_stipple = evergreen_set_polygon_stipple;
-	rctx->context.set_scissor_state = evergreen_set_scissor_state;
+	rctx->context.set_scissor_states = evergreen_set_scissor_states;
 
 	if (rctx->chip_class == EVERGREEN)
                 rctx->context.get_sample_position = evergreen_get_sample_position;
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index f0e3675..4a838a5 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -1215,8 +1215,9 @@ static void r600_emit_scissor_state(struct r600_context *rctx, struct r600_atom
 	}
 }
 
-static void r600_set_scissor_state(struct pipe_context *ctx,
-				   const struct pipe_scissor_state *state)
+static void r600_set_scissor_states(struct pipe_context *ctx,
+                                    unsigned num_scissors,
+                                    const struct pipe_scissor_state *state)
 {
 	struct r600_context *rctx = (struct r600_context *)ctx;
 
@@ -3252,7 +3253,7 @@ void r600_init_state_functions(struct r600_context *rctx)
 	rctx->context.create_sampler_view = r600_create_sampler_view;
 	rctx->context.set_framebuffer_state = r600_set_framebuffer_state;
 	rctx->context.set_polygon_stipple = r600_set_polygon_stipple;
-	rctx->context.set_scissor_state = r600_set_scissor_state;
+	rctx->context.set_scissor_states = r600_set_scissor_states;
 
 	rctx->context.get_sample_position = r600_get_sample_position;
 }
diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
index fbac576..eec2e51 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -660,8 +660,9 @@ static void r600_set_ps_sampler_views(struct pipe_context *ctx, unsigned count,
 	r600_set_sampler_views(ctx, PIPE_SHADER_FRAGMENT, 0, count, views);
 }
 
-static void r600_set_viewport_state(struct pipe_context *ctx,
-				    const struct pipe_viewport_state *state)
+static void r600_set_viewport_states(struct pipe_context *ctx,
+                                     unsigned num_viewports,
+                                     const struct pipe_viewport_state *state)
 {
 	struct r600_context *rctx = (struct r600_context *)ctx;
 
@@ -1547,7 +1548,7 @@ void r600_draw_rectangle(struct blitter_context *blitter,
 	viewport.translate[1] = 0.0f;
 	viewport.translate[2] = 0.0f;
 	viewport.translate[3] = 0.0f;
-	rctx->context.set_viewport_state(&rctx->context, &viewport);
+	rctx->context.set_viewport_states(&rctx->context, 1, &viewport);
 
 	/* Upload vertices. The hw rectangle has only 3 vertices,
 	 * I guess the 4th one is derived from the first 3.
@@ -1750,7 +1751,7 @@ void r600_init_common_state_functions(struct r600_context *rctx)
 	rctx->context.set_constant_buffer = r600_set_constant_buffer;
 	rctx->context.set_sample_mask = r600_set_sample_mask;
 	rctx->context.set_stencil_ref = r600_set_pipe_stencil_ref;
-	rctx->context.set_viewport_state = r600_set_viewport_state;
+	rctx->context.set_viewport_states = r600_set_viewport_states;
 	rctx->context.set_vertex_buffers = r600_set_vertex_buffers;
 	rctx->context.set_index_buffer = r600_set_index_buffer;
 	rctx->context.set_fragment_sampler_views = r600_set_ps_sampler_views;
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index ed95b1d..86e981f 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -252,8 +252,9 @@ static void si_set_clip_state(struct pipe_context *ctx,
 	si_pm4_set_state(rctx, clip, pm4);
 }
 
-static void si_set_scissor_state(struct pipe_context *ctx,
-				 const struct pipe_scissor_state *state)
+static void si_set_scissor_states(struct pipe_context *ctx,
+                                  unsigned num_scissors,
+                                  const struct pipe_scissor_state *state)
 {
 	struct r600_context *rctx = (struct r600_context *)ctx;
 	struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
@@ -276,8 +277,9 @@ static void si_set_scissor_state(struct pipe_context *ctx,
 	si_pm4_set_state(rctx, scissor, pm4);
 }
 
-static void si_set_viewport_state(struct pipe_context *ctx,
-				  const struct pipe_viewport_state *state)
+static void si_set_viewport_states(struct pipe_context *ctx,
+                                   unsigned num_viewports,
+                                   const struct pipe_viewport_state *state)
 {
 	struct r600_context *rctx = (struct r600_context *)ctx;
 	struct si_state_viewport *viewport = CALLOC_STRUCT(si_state_viewport);
@@ -2695,8 +2697,8 @@ void si_init_state_functions(struct r600_context *rctx)
 	rctx->custom_dsa_flush_inplace = si_create_db_flush_dsa(rctx, false, false);
 
 	rctx->context.set_clip_state = si_set_clip_state;
-	rctx->context.set_scissor_state = si_set_scissor_state;
-	rctx->context.set_viewport_state = si_set_viewport_state;
+	rctx->context.set_scissor_states = si_set_scissor_states;
+	rctx->context.set_viewport_states = si_set_viewport_states;
 	rctx->context.set_stencil_ref = si_set_pipe_stencil_ref;
 
 	rctx->context.set_framebuffer_state = si_set_framebuffer_state;
diff --git a/src/gallium/drivers/rbug/rbug_context.c b/src/gallium/drivers/rbug/rbug_context.c
index bf939b9..27b32f5 100644
--- a/src/gallium/drivers/rbug/rbug_context.c
+++ b/src/gallium/drivers/rbug/rbug_context.c
@@ -693,28 +693,30 @@ rbug_set_polygon_stipple(struct pipe_context *_pipe,
 }
 
 static void
-rbug_set_scissor_state(struct pipe_context *_pipe,
-                       const struct pipe_scissor_state *scissor)
+rbug_set_scissor_states(struct pipe_context *_pipe,
+                        unsigned num_scissors,
+                        const struct pipe_scissor_state *scissor)
 {
    struct rbug_context *rb_pipe = rbug_context(_pipe);
    struct pipe_context *pipe = rb_pipe->pipe;
 
    pipe_mutex_lock(rb_pipe->call_mutex);
-   pipe->set_scissor_state(pipe,
-                           scissor);
+   pipe->set_scissor_states(pipe, num_scissors,
+                            scissor);
    pipe_mutex_unlock(rb_pipe->call_mutex);
 }
 
 static void
-rbug_set_viewport_state(struct pipe_context *_pipe,
-                        const struct pipe_viewport_state *viewport)
+rbug_set_viewport_states(struct pipe_context *_pipe,
+                         unsigned num_viewports,
+                         const struct pipe_viewport_state *viewport)
 {
    struct rbug_context *rb_pipe = rbug_context(_pipe);
    struct pipe_context *pipe = rb_pipe->pipe;
 
    pipe_mutex_lock(rb_pipe->call_mutex);
-   pipe->set_viewport_state(pipe,
-                            viewport);
+   pipe->set_viewport_states(pipe, num_viewports,
+                             viewport);
    pipe_mutex_unlock(rb_pipe->call_mutex);
 }
 
@@ -1171,8 +1173,8 @@ rbug_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
    rb_pipe->base.set_constant_buffer = rbug_set_constant_buffer;
    rb_pipe->base.set_framebuffer_state = rbug_set_framebuffer_state;
    rb_pipe->base.set_polygon_stipple = rbug_set_polygon_stipple;
-   rb_pipe->base.set_scissor_state = rbug_set_scissor_state;
-   rb_pipe->base.set_viewport_state = rbug_set_viewport_state;
+   rb_pipe->base.set_scissor_states = rbug_set_scissor_states;
+   rb_pipe->base.set_viewport_states = rbug_set_viewport_states;
    rb_pipe->base.set_fragment_sampler_views = rbug_set_fragment_sampler_views;
    rb_pipe->base.set_vertex_sampler_views = rbug_set_vertex_sampler_views;
    rb_pipe->base.set_vertex_buffers = rbug_set_vertex_buffers;
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index fe5de17..a2cc0ce 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -182,6 +182,8 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_TGSI_TEXCOORD:
    case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
       return 0;
+   case PIPE_CAP_MULTIPLE_VIEWPORTS:
+      return 0;
    }
    /* should only get here on unhandled cases */
    debug_printf("Unexpected PIPE_CAP %d query\n", param);
diff --git a/src/gallium/drivers/softpipe/sp_state_clip.c b/src/gallium/drivers/softpipe/sp_state_clip.c
index f3a4c23..1eb90be 100644
--- a/src/gallium/drivers/softpipe/sp_state_clip.c
+++ b/src/gallium/drivers/softpipe/sp_state_clip.c
@@ -44,13 +44,14 @@ softpipe_set_clip_state(struct pipe_context *pipe,
 
 
 static void
-softpipe_set_viewport_state(struct pipe_context *pipe,
-                            const struct pipe_viewport_state *viewport)
+softpipe_set_viewport_states(struct pipe_context *pipe,
+                             unsigned num_viewports,
+                             const struct pipe_viewport_state *viewport)
 {
    struct softpipe_context *softpipe = softpipe_context(pipe);
 
    /* pass the viewport info to the draw module */
-   draw_set_viewport_state(softpipe->draw, viewport);
+   draw_set_viewport_states(softpipe->draw, num_viewports, viewport);
 
    softpipe->viewport = *viewport; /* struct copy */
    softpipe->dirty |= SP_NEW_VIEWPORT;
@@ -58,8 +59,9 @@ softpipe_set_viewport_state(struct pipe_context *pipe,
 
 
 static void
-softpipe_set_scissor_state(struct pipe_context *pipe,
-                           const struct pipe_scissor_state *scissor)
+softpipe_set_scissor_states(struct pipe_context *pipe,
+                            unsigned num_scissors,
+                            const struct pipe_scissor_state *scissor)
 {
    struct softpipe_context *softpipe = softpipe_context(pipe);
 
@@ -87,7 +89,7 @@ void
 softpipe_init_clip_funcs(struct pipe_context *pipe)
 {
    pipe->set_clip_state = softpipe_set_clip_state;
-   pipe->set_viewport_state = softpipe_set_viewport_state;
-   pipe->set_scissor_state = softpipe_set_scissor_state;
+   pipe->set_viewport_states = softpipe_set_viewport_states;
+   pipe->set_scissor_states = softpipe_set_scissor_states;
    pipe->set_polygon_stipple = softpipe_set_polygon_stipple;
 }
diff --git a/src/gallium/drivers/svga/svga_pipe_misc.c b/src/gallium/drivers/svga/svga_pipe_misc.c
index 7884b6d..60aab9b 100644
--- a/src/gallium/drivers/svga/svga_pipe_misc.c
+++ b/src/gallium/drivers/svga/svga_pipe_misc.c
@@ -31,12 +31,13 @@
 #include "svga_surface.h"
 
 
-static void svga_set_scissor_state( struct pipe_context *pipe,
-                                 const struct pipe_scissor_state *scissor )
+static void svga_set_scissor_states( struct pipe_context *pipe,
+                                     unsigned num_scissors,
+                                     const struct pipe_scissor_state *scissors )
 {
    struct svga_context *svga = svga_context(pipe);
 
-   memcpy( &svga->curr.scissor, scissor, sizeof(*scissor) );
+   memcpy( &svga->curr.scissor, scissors, sizeof(*scissors) );
    svga->dirty |= SVGA_NEW_SCISSOR;
 }
 
@@ -161,12 +162,13 @@ static void svga_set_clip_state( struct pipe_context *pipe,
 /* Called when driver state tracker notices changes to the viewport
  * matrix:
  */
-static void svga_set_viewport_state( struct pipe_context *pipe,
-				     const struct pipe_viewport_state *viewport )
+static void svga_set_viewport_states( struct pipe_context *pipe,
+                                      unsigned num_viewports,
+                                      const struct pipe_viewport_state *viewports )
 {
    struct svga_context *svga = svga_context(pipe);
 
-   svga->curr.viewport = *viewport; /* struct copy */
+   svga->curr.viewport = *viewports; /* struct copy */
 
    svga->dirty |= SVGA_NEW_VIEWPORT;
 }
@@ -175,11 +177,11 @@ static void svga_set_viewport_state( struct pipe_context *pipe,
 
 void svga_init_misc_functions( struct svga_context *svga )
 {
-   svga->pipe.set_scissor_state = svga_set_scissor_state;
+   svga->pipe.set_scissor_states = svga_set_scissor_states;
    svga->pipe.set_polygon_stipple = svga_set_polygon_stipple;
    svga->pipe.set_framebuffer_state = svga_set_framebuffer_state;
    svga->pipe.set_clip_state = svga_set_clip_state;
-   svga->pipe.set_viewport_state = svga_set_viewport_state;
+   svga->pipe.set_viewport_states = svga_set_viewport_states;
 }
 
 
diff --git a/src/gallium/drivers/svga/svga_swtnl_state.c b/src/gallium/drivers/svga/svga_swtnl_state.c
index dea3a26..085e6fb 100644
--- a/src/gallium/drivers/svga/svga_swtnl_state.c
+++ b/src/gallium/drivers/svga/svga_swtnl_state.c
@@ -80,7 +80,7 @@ static void set_draw_viewport( struct svga_context *svga )
    vp.translate[0] += adjx;
    vp.translate[1] += adjy;
 
-   draw_set_viewport_state(svga->swtnl.draw, &vp);
+   draw_set_viewport_states(svga->swtnl.draw, 1, &vp);
 }
 
 static enum pipe_error
diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c
index 962b15e..6a00c4e 100644
--- a/src/gallium/drivers/trace/tr_context.c
+++ b/src/gallium/drivers/trace/tr_context.c
@@ -765,36 +765,40 @@ trace_context_set_polygon_stipple(struct pipe_context *_pipe,
 
 
 static INLINE void
-trace_context_set_scissor_state(struct pipe_context *_pipe,
-                                const struct pipe_scissor_state *state)
+trace_context_set_scissor_states(struct pipe_context *_pipe,
+                                 unsigned num_scissors,
+                                 const struct pipe_scissor_state *states)
 {
    struct trace_context *tr_ctx = trace_context(_pipe);
    struct pipe_context *pipe = tr_ctx->pipe;
 
-   trace_dump_call_begin("pipe_context", "set_scissor_state");
+   trace_dump_call_begin("pipe_context", "set_scissor_states");
 
    trace_dump_arg(ptr, pipe);
-   trace_dump_arg(scissor_state, state);
+   trace_dump_arg(uint, num_scissors);
+   trace_dump_arg(scissor_state, states);
 
-   pipe->set_scissor_state(pipe, state);
+   pipe->set_scissor_states(pipe, num_scissors, states);
 
    trace_dump_call_end();
 }
 
 
 static INLINE void
-trace_context_set_viewport_state(struct pipe_context *_pipe,
-                                 const struct pipe_viewport_state *state)
+trace_context_set_viewport_states(struct pipe_context *_pipe,
+                                  unsigned num_viewports,
+                                  const struct pipe_viewport_state *states)
 {
    struct trace_context *tr_ctx = trace_context(_pipe);
    struct pipe_context *pipe = tr_ctx->pipe;
 
-   trace_dump_call_begin("pipe_context", "set_viewport_state");
+   trace_dump_call_begin("pipe_context", "set_viewport_states");
 
    trace_dump_arg(ptr, pipe);
-   trace_dump_arg(viewport_state, state);
+   trace_dump_arg(uint, num_viewports);
+   trace_dump_arg(viewport_state, states);
 
-   pipe->set_viewport_state(pipe, state);
+   pipe->set_viewport_states(pipe, num_viewports, states);
 
    trace_dump_call_end();
 }
@@ -1576,8 +1580,8 @@ trace_context_create(struct trace_screen *tr_scr,
    TR_CTX_INIT(set_constant_buffer);
    TR_CTX_INIT(set_framebuffer_state);
    TR_CTX_INIT(set_polygon_stipple);
-   TR_CTX_INIT(set_scissor_state);
-   TR_CTX_INIT(set_viewport_state);
+   TR_CTX_INIT(set_scissor_states);
+   TR_CTX_INIT(set_viewport_states);
    TR_CTX_INIT(set_fragment_sampler_views);
    TR_CTX_INIT(set_vertex_sampler_views);
    TR_CTX_INIT(set_geometry_sampler_views);
diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h
index d1130bc..eaaa043 100644
--- a/src/gallium/include/pipe/p_context.h
+++ b/src/gallium/include/pipe/p_context.h
@@ -211,11 +211,13 @@ struct pipe_context {
    void (*set_polygon_stipple)( struct pipe_context *,
 				const struct pipe_poly_stipple * );
 
-   void (*set_scissor_state)( struct pipe_context *,
-                              const struct pipe_scissor_state * );
+   void (*set_scissor_states)( struct pipe_context *,
+                               unsigned num_scissors,
+                               const struct pipe_scissor_state * );
 
-   void (*set_viewport_state)( struct pipe_context *,
-                               const struct pipe_viewport_state * );
+   void (*set_viewport_states)( struct pipe_context *,
+                                unsigned num_viewports,
+                                const struct pipe_viewport_state *);
 
    void (*set_fragment_sampler_views)(struct pipe_context *,
                                       unsigned num_views,
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index bb86968..00f0a37 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -507,7 +507,8 @@ enum pipe_cap {
    PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER = 80,
    PIPE_CAP_QUERY_PIPELINE_STATISTICS = 81,
    PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK = 82,
-   PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE = 83
+   PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE = 83,
+   PIPE_CAP_MULTIPLE_VIEWPORTS = 84
 };
 
 #define PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50 (1 << 0)
diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h
index 50de2d3..b33cf1d 100644
--- a/src/gallium/include/pipe/p_shader_tokens.h
+++ b/src/gallium/include/pipe/p_shader_tokens.h
@@ -164,7 +164,8 @@ struct tgsi_declaration_interp
 #define TGSI_SEMANTIC_THREAD_ID  18 /**< block-relative id of the current thread */
 #define TGSI_SEMANTIC_TEXCOORD   19 /**< texture or sprite coordinates */
 #define TGSI_SEMANTIC_PCOORD     20 /**< point sprite coordinate */
-#define TGSI_SEMANTIC_COUNT      21 /**< number of semantic values */
+#define TGSI_SEMANTIC_VIEWPORT_INDEX 21 /**< viewport index */
+#define TGSI_SEMANTIC_COUNT      22 /**< number of semantic values */
 
 struct tgsi_declaration_semantic
 {
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index 262078d..ff0aac7 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -65,6 +65,7 @@ extern "C" {
 #define PIPE_MAX_TEXTURE_LEVELS   16
 #define PIPE_MAX_SO_BUFFERS        4
 #define PIPE_MAX_SO_OUTPUTS       64
+#define PIPE_MAX_VIEWPORTS        16
 
 
 struct pipe_reference
diff --git a/src/gallium/state_trackers/vega/renderer.c b/src/gallium/state_trackers/vega/renderer.c
index b823278..ec944db 100644
--- a/src/gallium/state_trackers/vega/renderer.c
+++ b/src/gallium/state_trackers/vega/renderer.c
@@ -353,7 +353,7 @@ static void vg_set_viewport(struct renderer *r,
    viewport.translate[2] = 0.0;
    viewport.translate[3] = 0.0;
 
-   cso_set_viewport(r->cso, &viewport);
+   cso_set_viewports(r->cso, 1, &viewport);
 }
 
 /**
@@ -590,7 +590,7 @@ VGboolean renderer_copy_begin(struct renderer *renderer,
       return VG_FALSE;
 
    cso_save_framebuffer(renderer->cso);
-   cso_save_viewport(renderer->cso);
+   cso_save_viewports(renderer->cso);
    cso_save_blend(renderer->cso);
    cso_save_samplers(renderer->cso, PIPE_SHADER_FRAGMENT);
    cso_save_sampler_views(renderer->cso, PIPE_SHADER_FRAGMENT);
@@ -644,7 +644,7 @@ void renderer_copy_end(struct renderer *renderer)
    assert(renderer->state == RENDERER_STATE_COPY);
 
    cso_restore_framebuffer(renderer->cso);
-   cso_restore_viewport(renderer->cso);
+   cso_restore_viewports(renderer->cso);
    cso_restore_blend(renderer->cso);
    cso_restore_samplers(renderer->cso, PIPE_SHADER_FRAGMENT);
    cso_restore_sampler_views(renderer->cso, PIPE_SHADER_FRAGMENT);
@@ -877,7 +877,7 @@ VGboolean renderer_filter_begin(struct renderer *renderer,
       return VG_FALSE;
 
    cso_save_framebuffer(renderer->cso);
-   cso_save_viewport(renderer->cso);
+   cso_save_viewports(renderer->cso);
    cso_save_blend(renderer->cso);
 
    /* set the image as the target */
@@ -956,7 +956,7 @@ void renderer_filter_end(struct renderer *renderer)
    }
 
    cso_restore_framebuffer(renderer->cso);
-   cso_restore_viewport(renderer->cso);
+   cso_restore_viewports(renderer->cso);
    cso_restore_blend(renderer->cso);
    cso_restore_fragment_shader(renderer->cso);
 
diff --git a/src/gallium/state_trackers/xa/xa_renderer.c b/src/gallium/state_trackers/xa/xa_renderer.c
index b775509..72ff9b3 100644
--- a/src/gallium/state_trackers/xa/xa_renderer.c
+++ b/src/gallium/state_trackers/xa/xa_renderer.c
@@ -367,7 +367,7 @@ renderer_bind_destination(struct xa_context *r,
     }
 
     cso_set_framebuffer(r->cso, &fb);
-    cso_set_viewport(r->cso, &viewport);
+    cso_set_viewports(r->cso, 1, &viewport);
 }
 
 void
diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.c b/src/gallium/state_trackers/xorg/xorg_renderer.c
index 563e7e7..9dcf510 100644
--- a/src/gallium/state_trackers/xorg/xorg_renderer.c
+++ b/src/gallium/state_trackers/xorg/xorg_renderer.c
@@ -368,7 +368,7 @@ void renderer_bind_destination(struct xorg_renderer *r,
    }
 
    cso_set_framebuffer(r->cso, &fb);
-   cso_set_viewport(r->cso, &viewport);
+   cso_set_viewports(r->cso, 1, &viewport);
 }
 
 
diff --git a/src/gallium/tests/graw/fs-test.c b/src/gallium/tests/graw/fs-test.c
index e59377f..85bef65 100644
--- a/src/gallium/tests/graw/fs-test.c
+++ b/src/gallium/tests/graw/fs-test.c
@@ -150,7 +150,7 @@ static void set_viewport( float x, float y,
    vp.translate[2] = half_depth + z;
    vp.translate[3] = 0.0f;
 
-   ctx->set_viewport_state( ctx, &vp );
+   ctx->set_viewport_states( ctx, 1, &vp );
 }
 
 static void set_vertices( void )
diff --git a/src/gallium/tests/graw/graw_util.h b/src/gallium/tests/graw/graw_util.h
index febdf44..3636202 100644
--- a/src/gallium/tests/graw/graw_util.h
+++ b/src/gallium/tests/graw/graw_util.h
@@ -203,7 +203,7 @@ graw_util_viewport(struct graw_info *info,
    vp.translate[2] = half_depth + z;
    vp.translate[3] = 0.0f;
 
-   info->ctx->set_viewport_state(info->ctx, &vp);
+   info->ctx->set_viewport_states(info->ctx, 1, &vp);
 }
 
 
diff --git a/src/gallium/tests/graw/gs-test.c b/src/gallium/tests/graw/gs-test.c
index 351a772..66bc4c0 100644
--- a/src/gallium/tests/graw/gs-test.c
+++ b/src/gallium/tests/graw/gs-test.c
@@ -225,7 +225,7 @@ static void set_viewport( float x, float y,
    vp.translate[2] = half_depth + z;
    vp.translate[3] = 0.0f;
 
-   ctx->set_viewport_state( ctx, &vp );
+   ctx->set_viewport_states( ctx, 1, &vp );
 }
 
 static void set_vertices( void )
diff --git a/src/gallium/tests/graw/quad-sample.c b/src/gallium/tests/graw/quad-sample.c
index dd2865d..7003ab6 100644
--- a/src/gallium/tests/graw/quad-sample.c
+++ b/src/gallium/tests/graw/quad-sample.c
@@ -78,7 +78,7 @@ static void set_viewport( float x, float y,
    vp.translate[2] = half_depth + z;
    vp.translate[3] = 0.0f;
 
-   ctx->set_viewport_state( ctx, &vp );
+   ctx->set_viewport_states( ctx, 1, &vp );
 }
 
 static void set_vertices( void )
diff --git a/src/gallium/tests/graw/shader-leak.c b/src/gallium/tests/graw/shader-leak.c
index 9c6e0eb..b27435e 100644
--- a/src/gallium/tests/graw/shader-leak.c
+++ b/src/gallium/tests/graw/shader-leak.c
@@ -68,7 +68,7 @@ static void set_viewport( float x, float y,
    vp.translate[2] = half_depth + z;
    vp.translate[3] = 0.0f;
 
-   ctx->set_viewport_state( ctx, &vp );
+   ctx->set_viewport_states( ctx, 1, &vp );
 }
 
 static void set_vertices( void )
diff --git a/src/gallium/tests/graw/tri-gs.c b/src/gallium/tests/graw/tri-gs.c
index 03b5234..30be50f 100644
--- a/src/gallium/tests/graw/tri-gs.c
+++ b/src/gallium/tests/graw/tri-gs.c
@@ -69,7 +69,7 @@ static void set_viewport( float x, float y,
    vp.translate[2] = half_depth + z;
    vp.translate[3] = 0.0f;
 
-   ctx->set_viewport_state( ctx, &vp );
+   ctx->set_viewport_states( ctx, 1, &vp );
 }
 
 static void set_vertices( void )
diff --git a/src/gallium/tests/graw/tri-instanced.c b/src/gallium/tests/graw/tri-instanced.c
index 901ac86..89bd760 100644
--- a/src/gallium/tests/graw/tri-instanced.c
+++ b/src/gallium/tests/graw/tri-instanced.c
@@ -98,7 +98,7 @@ static void set_viewport( float x, float y,
    vp.translate[2] = half_depth + z;
    vp.translate[3] = 0.0f;
 
-   ctx->set_viewport_state( ctx, &vp );
+   ctx->set_viewport_states( ctx, 1, &vp );
 }
 
 
diff --git a/src/gallium/tests/graw/vs-test.c b/src/gallium/tests/graw/vs-test.c
index 1ab6732..26995e5 100644
--- a/src/gallium/tests/graw/vs-test.c
+++ b/src/gallium/tests/graw/vs-test.c
@@ -136,7 +136,7 @@ static void set_viewport( float x, float y,
    vp.translate[2] = half_depth + z;
    vp.translate[3] = 0.0f;
 
-   ctx->set_viewport_state( ctx, &vp );
+   ctx->set_viewport_states( ctx, 1, &vp );
 }
 
 static void set_vertices( void )
diff --git a/src/gallium/tests/trivial/quad-tex.c b/src/gallium/tests/trivial/quad-tex.c
index 5ed741b..88eef70 100644
--- a/src/gallium/tests/trivial/quad-tex.c
+++ b/src/gallium/tests/trivial/quad-tex.c
@@ -312,7 +312,7 @@ static void draw(struct program *p)
 	cso_set_blend(p->cso, &p->blend);
 	cso_set_depth_stencil_alpha(p->cso, &p->depthstencil);
 	cso_set_rasterizer(p->cso, &p->rasterizer);
-	cso_set_viewport(p->cso, &p->viewport);
+	cso_set_viewports(p->cso, 1, &p->viewport);
 
 	/* sampler */
 	cso_single_sampler(p->cso, PIPE_SHADER_FRAGMENT, 0, &p->sampler);
diff --git a/src/gallium/tests/trivial/tri.c b/src/gallium/tests/trivial/tri.c
index 9131bb5..dc09b05 100644
--- a/src/gallium/tests/trivial/tri.c
+++ b/src/gallium/tests/trivial/tri.c
@@ -253,7 +253,7 @@ static void draw(struct program *p)
 	cso_set_blend(p->cso, &p->blend);
 	cso_set_depth_stencil_alpha(p->cso, &p->depthstencil);
 	cso_set_rasterizer(p->cso, &p->rasterizer);
-	cso_set_viewport(p->cso, &p->viewport);
+	cso_set_viewports(p->cso, 1, &p->viewport);
 
 	/* shaders */
 	cso_set_fragment_shader_handle(p->cso, p->fs);
diff --git a/src/mesa/state_tracker/st_atom_scissor.c b/src/mesa/state_tracker/st_atom_scissor.c
index eb13877..5b4bd2a 100644
--- a/src/mesa/state_tracker/st_atom_scissor.c
+++ b/src/mesa/state_tracker/st_atom_scissor.c
@@ -86,7 +86,7 @@ update_scissor( struct st_context *st )
    if (memcmp(&scissor, &st->state.scissor, sizeof(scissor)) != 0) {
       /* state has changed */
       st->state.scissor = scissor;  /* struct copy */
-      st->pipe->set_scissor_state(st->pipe, &scissor); /* activate */
+      st->pipe->set_scissor_states(st->pipe, 1, &scissor); /* activate */
    }
 }
 
diff --git a/src/mesa/state_tracker/st_atom_viewport.c b/src/mesa/state_tracker/st_atom_viewport.c
index 133cc49..5d3214b 100644
--- a/src/mesa/state_tracker/st_atom_viewport.c
+++ b/src/mesa/state_tracker/st_atom_viewport.c
@@ -79,7 +79,7 @@ update_viewport( struct st_context *st )
       st->state.viewport.translate[2] = half_depth + z;
       st->state.viewport.translate[3] = 0.0;
 
-      cso_set_viewport(st->cso_context, &st->state.viewport);
+      cso_set_viewports(st->cso_context, 1, &st->state.viewport);
    }
 }
 
diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c
index e96f4b3..ed82b3c 100644
--- a/src/mesa/state_tracker/st_cb_bitmap.c
+++ b/src/mesa/state_tracker/st_cb_bitmap.c
@@ -448,7 +448,7 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
    cso_save_rasterizer(cso);
    cso_save_samplers(cso, PIPE_SHADER_FRAGMENT);
    cso_save_sampler_views(cso, PIPE_SHADER_FRAGMENT);
-   cso_save_viewport(cso);
+   cso_save_viewports(cso);
    cso_save_fragment_shader(cso);
    cso_save_stream_outputs(cso);
    cso_save_vertex_shader(cso);
@@ -509,7 +509,7 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
       vp.translate[1] = 0.5f * height;
       vp.translate[2] = 0.5f;
       vp.translate[3] = 0.0f;
-      cso_set_viewport(cso, &vp);
+      cso_set_viewports(cso, 1, &vp);
    }
 
    cso_set_vertex_elements(cso, 3, st->velems_util_draw);
@@ -535,7 +535,7 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
    cso_restore_rasterizer(cso);
    cso_restore_samplers(cso, PIPE_SHADER_FRAGMENT);
    cso_restore_sampler_views(cso, PIPE_SHADER_FRAGMENT);
-   cso_restore_viewport(cso);
+   cso_restore_viewports(cso);
    cso_restore_fragment_shader(cso);
    cso_restore_vertex_shader(cso);
    cso_restore_geometry_shader(cso);
diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c
index 566f4a7..0a0ee48 100644
--- a/src/mesa/state_tracker/st_cb_clear.c
+++ b/src/mesa/state_tracker/st_cb_clear.c
@@ -220,7 +220,7 @@ clear_with_quad(struct gl_context *ctx,
    cso_save_depth_stencil_alpha(st->cso_context);
    cso_save_rasterizer(st->cso_context);
    cso_save_sample_mask(st->cso_context);
-   cso_save_viewport(st->cso_context);
+   cso_save_viewports(st->cso_context);
    cso_save_fragment_shader(st->cso_context);
    cso_save_stream_outputs(st->cso_context);
    cso_save_vertex_shader(st->cso_context);
@@ -300,7 +300,7 @@ clear_with_quad(struct gl_context *ctx,
       vp.translate[1] = 0.5f * fb_height;
       vp.translate[2] = 0.0f;
       vp.translate[3] = 0.0f;
-      cso_set_viewport(st->cso_context, &vp);
+      cso_set_viewports(st->cso_context, 1, &vp);
    }
 
    set_fragment_shader(st);
@@ -326,7 +326,7 @@ clear_with_quad(struct gl_context *ctx,
    cso_restore_depth_stencil_alpha(st->cso_context);
    cso_restore_rasterizer(st->cso_context);
    cso_restore_sample_mask(st->cso_context);
-   cso_restore_viewport(st->cso_context);
+   cso_restore_viewports(st->cso_context);
    cso_restore_fragment_shader(st->cso_context);
    cso_restore_vertex_shader(st->cso_context);
    cso_restore_geometry_shader(st->cso_context);
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index 68359e8..f5f01ea 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -690,7 +690,7 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
    assert(height <= maxSize);
 
    cso_save_rasterizer(cso);
-   cso_save_viewport(cso);
+   cso_save_viewports(cso);
    cso_save_samplers(cso, PIPE_SHADER_FRAGMENT);
    cso_save_sampler_views(cso, PIPE_SHADER_FRAGMENT);
    cso_save_fragment_shader(cso);
@@ -784,7 +784,7 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
       vp.translate[1] = 0.5f * h;
       vp.translate[2] = 0.5f;
       vp.translate[3] = 0.0f;
-      cso_set_viewport(cso, &vp);
+      cso_set_viewports(cso, 1, &vp);
    }
 
    cso_set_vertex_elements(cso, 3, st->velems_util_draw);
@@ -816,7 +816,7 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
 
    /* restore state */
    cso_restore_rasterizer(cso);
-   cso_restore_viewport(cso);
+   cso_restore_viewports(cso);
    cso_restore_samplers(cso, PIPE_SHADER_FRAGMENT);
    cso_restore_sampler_views(cso, PIPE_SHADER_FRAGMENT);
    cso_restore_fragment_shader(cso);
diff --git a/src/mesa/state_tracker/st_cb_drawtex.c b/src/mesa/state_tracker/st_cb_drawtex.c
index 2cc200e..08fca1c 100644
--- a/src/mesa/state_tracker/st_cb_drawtex.c
+++ b/src/mesa/state_tracker/st_cb_drawtex.c
@@ -223,7 +223,7 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,
    }
 
 
-   cso_save_viewport(cso);
+   cso_save_viewports(cso);
    cso_save_stream_outputs(cso);
    cso_save_vertex_shader(cso);
    cso_save_geometry_shader(cso);
@@ -261,7 +261,7 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,
       vp.translate[1] = 0.5f * height;
       vp.translate[2] = 0.0f;
       vp.translate[3] = 0.0f;
-      cso_set_viewport(cso, &vp);
+      cso_set_viewports(cso, 1, &vp);
    }
 
 
@@ -276,7 +276,7 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,
    pipe_resource_reference(&vbuffer, NULL);
 
    /* restore state */
-   cso_restore_viewport(cso);
+   cso_restore_viewports(cso);
    cso_restore_vertex_shader(cso);
    cso_restore_geometry_shader(cso);
    cso_restore_vertex_elements(cso);
diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c
index fe66b99..9654c7d 100644
--- a/src/mesa/state_tracker/st_draw_feedback.c
+++ b/src/mesa/state_tracker/st_draw_feedback.c
@@ -133,7 +133,7 @@ st_feedback_draw_vbo(struct gl_context *ctx,
     * code sends state updates to the pipe, not to our private draw module.
     */
    assert(draw);
-   draw_set_viewport_state(draw, &st->state.viewport);
+   draw_set_viewport_states(draw, 1, &st->state.viewport);
    draw_set_clip_state(draw, &st->state.clip);
    draw_set_rasterizer_state(draw, &st->state.rasterizer, NULL);
    draw_bind_vertex_shader(draw, st->vp_variant->draw_shader);
-- 
1.7.10.4


More information about the mesa-dev mailing list