gallium: Remove bypass_vs_clip_and_viewport from rasteriser state.
authorMichal Krol <michal@vmware.com>
Mon, 22 Feb 2010 20:36:22 +0000 (21:36 +0100)
committerMichal Krol <michal@vmware.com>
Mon, 22 Feb 2010 20:36:22 +0000 (21:36 +0100)
Needs testing.

25 files changed:
src/gallium/auxiliary/draw/draw_context.c
src/gallium/auxiliary/draw/draw_pt.c
src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c
src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
src/gallium/auxiliary/util/u_blit.c
src/gallium/auxiliary/util/u_blitter.c
src/gallium/auxiliary/util/u_dump_state.c
src/gallium/auxiliary/util/u_gen_mipmap.c
src/gallium/docs/source/cso/rasterizer.rst
src/gallium/drivers/nv30/nv30_context.h
src/gallium/drivers/nv30/nv30_state_viewport.c
src/gallium/drivers/nv40/nv40_context.h
src/gallium/drivers/nv40/nv40_state_viewport.c
src/gallium/drivers/nv50/nv50_context.h
src/gallium/drivers/nv50/nv50_state_validate.c
src/gallium/drivers/r300/r300_context.h
src/gallium/drivers/r300/r300_emit.c
src/gallium/drivers/r300/r300_state.c
src/gallium/drivers/r300/r300_state_derived.c
src/gallium/drivers/softpipe/sp_video_context.c
src/gallium/drivers/svga/svga_state_framebuffer.c
src/gallium/drivers/svga/svga_state_need_swtnl.c
src/gallium/drivers/trace/tr_dump_state.c
src/gallium/include/pipe/p_state.h
src/mesa/state_tracker/st_cb_clear.c

index d5ddc4a6a922c25cf1bb008f6284c601e9de4522..bb0988543f51fc94925aaec4cdf02174d96f0088 100644 (file)
@@ -128,9 +128,7 @@ void draw_set_rasterizer_state( struct draw_context *draw,
    draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
 
    draw->rasterizer = raster;
-   draw->bypass_clipping =
-      ((draw->rasterizer && draw->rasterizer->bypass_vs_clip_and_viewport) ||
-       draw->driver.bypass_clipping);
+   draw->bypass_clipping = draw->driver.bypass_clipping;
 }
 
 
@@ -140,9 +138,7 @@ void draw_set_driver_clipping( struct draw_context *draw,
    draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
 
    draw->driver.bypass_clipping = bypass_clipping;
-   draw->bypass_clipping =
-      ((draw->rasterizer && draw->rasterizer->bypass_vs_clip_and_viewport) ||
-       draw->driver.bypass_clipping);
+   draw->bypass_clipping = draw->driver.bypass_clipping;
 }
 
 
index 341353f6289002030ecdda2a78e859f42423cb66..6d90a6c42fde3be6f3faadaede06e2c3de66f19b 100644 (file)
@@ -87,9 +87,7 @@ draw_pt_arrays(struct draw_context *draw,
          opt |= PT_CLIPTEST;
       }
       
-      if (!draw->rasterizer->bypass_vs_clip_and_viewport) {
-         opt |= PT_SHADE;
-      }
+      opt |= PT_SHADE;
    }
       
    if (opt == 0) 
index c5dfbcfa3cb70802f2869a21db5ffc3e7a71642e..1aecb510777330e04a042433601e73c16c151e7f 100644 (file)
@@ -100,8 +100,7 @@ static void fse_prepare( struct draw_pt_middle_end *middle,
    fse->key.nr_elements = MAX2(fse->key.nr_outputs,     /* outputs - translate to hw format */
                                fse->key.nr_inputs);     /* inputs - fetch from api format */
 
-   fse->key.viewport = (!draw->rasterizer->bypass_vs_clip_and_viewport &&
-                        !draw->identity_viewport);
+   fse->key.viewport = !draw->identity_viewport;
    fse->key.clip = !draw->bypass_clipping;
    fse->key.const_vbuffers = 0;
 
index 56b69354b21503ae82034d9f310036a132aab063..da5106463a700f52a23ca0c9ee64276913267d9b 100644 (file)
@@ -96,8 +96,7 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
     */
    draw_pt_post_vs_prepare( fpme->post_vs,
                            (boolean)draw->bypass_clipping,
-                           (boolean)(draw->identity_viewport ||
-                           draw->rasterizer->bypass_vs_clip_and_viewport),
+                           (boolean)draw->identity_viewport,
                            (boolean)draw->rasterizer->gl_rasterization_rules,
                            (draw->vs.edgeflag_output ? true : false) );    
 
@@ -154,9 +153,7 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle,
                      (char *)pipeline_verts );
 
    /* Run the shader, note that this overwrites the data[] parts of
-    * the pipeline verts.  If there is no shader, eg if
-    * bypass_vs_clip_and_viewport, then the inputs == outputs, and are
-    * already in the correct place.
+    * the pipeline verts.
     */
    if (opt & PT_SHADE)
    {
@@ -239,9 +236,7 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle,
                              (char *)pipeline_verts );
 
    /* Run the shader, note that this overwrites the data[] parts of
-    * the pipeline verts.  If there is no shader, ie if
-    * bypass_vs_clip_and_viewport, then the inputs == outputs, and are
-    * already in the correct place.
+    * the pipeline verts.
     */
    if (opt & PT_SHADE)
    {
@@ -319,9 +314,7 @@ static boolean fetch_pipeline_linear_run_elts( struct draw_pt_middle_end *middle
                              (char *)pipeline_verts );
 
    /* Run the shader, note that this overwrites the data[] parts of
-    * the pipeline verts.  If there is no shader, ie if
-    * bypass_vs_clip_and_viewport, then the inputs == outputs, and are
-    * already in the correct place.
+    * the pipeline verts.
     */
    if (opt & PT_SHADE)
    {
index f0bc58a558fdcae04f589531aecbf5e85751f9ef..90a3230a0f55cc54300b411ba568bef76966540f 100644 (file)
@@ -101,7 +101,6 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso)
    memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer));
    ctx->rasterizer.front_winding = PIPE_WINDING_CW;
    ctx->rasterizer.cull_mode = PIPE_WINDING_NONE;
-   ctx->rasterizer.bypass_vs_clip_and_viewport = 1;
    ctx->rasterizer.gl_rasterization_rules = 1;
 
    /* samplers */
@@ -114,7 +113,6 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso)
    ctx->sampler.mag_img_filter = 0; /* set later */
    ctx->sampler.normalized_coords = 1;
 
-
    /* vertex shader - still required to provide the linkage between
     * fragment shader input semantics and vertex_element/buffers.
     */
@@ -407,6 +405,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
    cso_save_rasterizer(ctx->cso);
    cso_save_samplers(ctx->cso);
    cso_save_sampler_textures(ctx->cso);
+   cso_save_viewport(ctx->cso);
    cso_save_framebuffer(ctx->cso);
    cso_save_fragment_shader(ctx->cso);
    cso_save_vertex_shader(ctx->cso);
@@ -422,6 +421,17 @@ util_blit_pixels_writemask(struct blit_state *ctx,
    cso_single_sampler(ctx->cso, 0, &ctx->sampler);
    cso_single_sampler_done(ctx->cso);
 
+   /* viewport */
+   ctx->viewport.scale[0] = 0.5f * dst->width;
+   ctx->viewport.scale[1] = 0.5f * dst->height;
+   ctx->viewport.scale[2] = 1.0f;
+   ctx->viewport.scale[3] = 1.0f;
+   ctx->viewport.translate[0] = 0.5f * dst->width;
+   ctx->viewport.translate[1] = 0.5f * dst->height;
+   ctx->viewport.translate[2] = 0.0f;
+   ctx->viewport.translate[3] = 0.0f;
+   cso_set_viewport(ctx->cso, &ctx->viewport);
+
    /* texture */
    cso_set_sampler_textures(ctx->cso, 1, &tex);
 
@@ -461,6 +471,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
    cso_restore_rasterizer(ctx->cso);
    cso_restore_samplers(ctx->cso);
    cso_restore_sampler_textures(ctx->cso);
+   cso_restore_viewport(ctx->cso);
    cso_restore_framebuffer(ctx->cso);
    cso_restore_fragment_shader(ctx->cso);
    cso_restore_vertex_shader(ctx->cso);
index 18f8606818381180c127e1b1e56c9e93610c4307..50877f6b01a283c98bc7d62d2becfa40642d24bf 100644 (file)
@@ -160,7 +160,6 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
    memset(&rs_state, 0, sizeof(rs_state));
    rs_state.front_winding = PIPE_WINDING_CW;
    rs_state.cull_mode = PIPE_WINDING_NONE;
-   rs_state.bypass_vs_clip_and_viewport = 1;
    rs_state.gl_rasterization_rules = 1;
    rs_state.flatshade = 1;
    ctx->rs_state = pipe->create_rasterizer_state(pipe, &rs_state);
index eaf4ec90f254a08c59a12b641076368532bdd88b..ae7afd7311e608ddebd67b8c8505aec6d9fc6469 100644 (file)
@@ -318,7 +318,6 @@ util_dump_rasterizer_state(struct os_stream *stream, const struct pipe_rasterize
    util_dump_member(stream, uint, state, line_stipple_factor);
    util_dump_member(stream, uint, state, line_stipple_pattern);
    util_dump_member(stream, bool, state, line_last_pixel);
-   util_dump_member(stream, bool, state, bypass_vs_clip_and_viewport);
    util_dump_member(stream, bool, state, flatshade_first);
    util_dump_member(stream, bool, state, gl_rasterization_rules);
 
index 1d7329d422b8f1f748679c7a01fa4df27ca9b181..4f9ff1d96122359d751f79eaa2154d2f494153f6 100644 (file)
@@ -1296,7 +1296,6 @@ util_create_gen_mipmap(struct pipe_context *pipe,
    memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer));
    ctx->rasterizer.front_winding = PIPE_WINDING_CW;
    ctx->rasterizer.cull_mode = PIPE_WINDING_NONE;
-   ctx->rasterizer.bypass_vs_clip_and_viewport = 1;
    ctx->rasterizer.gl_rasterization_rules = 1;
 
    /* sampler state */
@@ -1361,25 +1360,25 @@ get_next_slot(struct gen_mipmap_state *ctx)
 static unsigned
 set_vertex_data(struct gen_mipmap_state *ctx,
                 enum pipe_texture_target tex_target,
-                uint face, float width, float height)
+                uint face)
 {
    unsigned offset;
 
    /* vert[0].position */
-   ctx->vertices[0][0][0] = 0.0f; /*x*/
-   ctx->vertices[0][0][1] = 0.0f; /*y*/
+   ctx->vertices[0][0][0] = -1.0f; /*x*/
+   ctx->vertices[0][0][1] = -1.0f; /*y*/
 
    /* vert[1].position */
-   ctx->vertices[1][0][0] = width;
-   ctx->vertices[1][0][1] = 0.0f;
+   ctx->vertices[1][0][0] = 1.0f;
+   ctx->vertices[1][0][1] = -1.0f;
 
    /* vert[2].position */
-   ctx->vertices[2][0][0] = width;
-   ctx->vertices[2][0][1] = height;
+   ctx->vertices[2][0][0] = 1.0f;
+   ctx->vertices[2][0][1] = 1.0f;
 
    /* vert[3].position */
-   ctx->vertices[3][0][0] = 0.0f;
-   ctx->vertices[3][0][1] = height;
+   ctx->vertices[3][0][0] = -1.0f;
+   ctx->vertices[3][0][1] = 1.0f;
 
    /* Setup vertex texcoords.  This is a little tricky for cube maps. */
    if (tex_target == PIPE_TEXTURE_CUBE) {
@@ -1499,6 +1498,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
    cso_save_framebuffer(ctx->cso);
    cso_save_fragment_shader(ctx->cso);
    cso_save_vertex_shader(ctx->cso);
+   cso_save_viewport(ctx->cso);
 
    /* bind our state */
    cso_set_blend(ctx->cso, &ctx->blend);
@@ -1522,6 +1522,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
     */
    for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
       const uint srcLevel = dstLevel - 1;
+      struct pipe_viewport_state vp;
 
       struct pipe_surface *surf = 
          screen->get_tex_surface(screen, pt, face, dstLevel, zslice,
@@ -1535,6 +1536,17 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
       fb.height = u_minify(pt->height0, dstLevel);
       cso_set_framebuffer(ctx->cso, &fb);
 
+      /* viewport */
+      vp.scale[0] = 0.5f * fb.width;
+      vp.scale[1] = 0.5f * fb.height;
+      vp.scale[2] = 1.0f;
+      vp.scale[3] = 1.0f;
+      vp.translate[0] = 0.5f * fb.width;
+      vp.translate[1] = 0.5f * fb.height;
+      vp.translate[2] = 0.0f;
+      vp.translate[3] = 0.0f;
+      cso_set_viewport(ctx->cso, &vp);
+
       /*
        * Setup sampler state
        * Note: we should only have to set the min/max LOD clamps to ensure
@@ -1549,12 +1561,10 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
 
       cso_set_sampler_textures(ctx->cso, 1, &pt);
 
-      /* quad coords in window coords (bypassing vs, clip and viewport) */
+      /* quad coords in clip coords */
       offset = set_vertex_data(ctx,
                                pt->target,
-                               face,
-                               (float) u_minify(pt->width0, dstLevel),
-                               (float) u_minify(pt->height0, dstLevel));
+                               face);
 
       util_draw_vertex_buffer(ctx->pipe, 
                               ctx->vbuf,
@@ -1578,4 +1588,5 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
    cso_restore_framebuffer(ctx->cso);
    cso_restore_fragment_shader(ctx->cso);
    cso_restore_vertex_shader(ctx->cso);
+   cso_restore_viewport(ctx->cso);
 }
index 24cc78c68ded6824a3cddcb973a03493234a68bf..ccd9136a2ebfbea41fede28117d043b0aa3309b4 100644 (file)
@@ -10,18 +10,6 @@ multisample state, scissoring and flat/smooth shading.
 Members
 -------
 
-bypass_vs_clip_and_viewport
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Whether the entire TCL pipeline should be bypassed. This implies that
-vertices are pre-transformed for the viewport, and will not be run
-through the vertex shader.
-
-.. note::
-   
-   Implementations may still clip away vertices that are not in the viewport
-   when this is set.
-
 flatshade
 ^^^^^^^^^
 
index ca3d6aca7faf6138c9f7db50b65371a3eb5e0bd6..ea259aadf359f28222d68a5f089098c2afab467e 100644 (file)
@@ -101,7 +101,6 @@ struct nv30_blend_state {
 struct nv30_state {
        unsigned scissor_enabled;
        unsigned stipple_enabled;
-       unsigned viewport_bypass;
        unsigned fp_samplers;
 
        uint64_t dirty;
index 2d7781292bdded0700ac0099689f18feab759d55..6fccd6b60e7585e099d3c570eae189c9703fa732 100644 (file)
@@ -5,55 +5,25 @@ nv30_state_viewport_validate(struct nv30_context *nv30)
 {
        struct pipe_viewport_state *vpt = &nv30->viewport;
        struct nouveau_stateobj *so;
-       unsigned bypass;
-
-       if (/*nv30->render_mode == HW &&*/
-           !nv30->rasterizer->pipe.bypass_vs_clip_and_viewport)
-               bypass = 0;
-       else
-               bypass = 1;
 
        if (nv30->state.hw[NV30_STATE_VIEWPORT] &&
-           (bypass || !(nv30->dirty & NV30_NEW_VIEWPORT)) &&
-           nv30->state.viewport_bypass == bypass)
+           !(nv30->dirty & NV30_NEW_VIEWPORT))
                return FALSE;
-       nv30->state.viewport_bypass = bypass;
 
        so = so_new(3, 10, 0);
-       if (!bypass) {
-               so_method(so, nv30->screen->rankine,
-                         NV34TCL_VIEWPORT_TRANSLATE_X, 8);
-               so_data  (so, fui(vpt->translate[0]));
-               so_data  (so, fui(vpt->translate[1]));
-               so_data  (so, fui(vpt->translate[2]));
-               so_data  (so, fui(vpt->translate[3]));
-               so_data  (so, fui(vpt->scale[0]));
-               so_data  (so, fui(vpt->scale[1]));
-               so_data  (so, fui(vpt->scale[2]));
-               so_data  (so, fui(vpt->scale[3]));
-/*             so_method(so, nv30->screen->rankine, 0x1d78, 1);
-               so_data  (so, 1);
-*/     } else {
-               so_method(so, nv30->screen->rankine,
-                         NV34TCL_VIEWPORT_TRANSLATE_X, 8);
-               so_data  (so, fui(0.0));
-               so_data  (so, fui(0.0));
-               so_data  (so, fui(0.0));
-               so_data  (so, fui(0.0));
-               so_data  (so, fui(1.0));
-               so_data  (so, fui(1.0));
-               so_data  (so, fui(1.0));
-               so_data  (so, fui(0.0));
-               /* Not entirely certain what this is yet.  The DDX uses this
-                * value also as it fixes rendering when you pass
-                * pre-transformed vertices to the GPU.  My best gusss is that
-                * this bypasses some culling/clipping stage.  Might be worth
-                * noting that points/lines are uneffected by whatever this
-                * value fixes, only filled polygons are effected.
-                */
-/*             so_method(so, nv30->screen->rankine, 0x1d78, 1);
-               so_data  (so, 0x110);
-*/     }
+       so_method(so, nv30->screen->rankine,
+                 NV34TCL_VIEWPORT_TRANSLATE_X, 8);
+       so_data  (so, fui(vpt->translate[0]));
+       so_data  (so, fui(vpt->translate[1]));
+       so_data  (so, fui(vpt->translate[2]));
+       so_data  (so, fui(vpt->translate[3]));
+       so_data  (so, fui(vpt->scale[0]));
+       so_data  (so, fui(vpt->scale[1]));
+       so_data  (so, fui(vpt->scale[2]));
+       so_data  (so, fui(vpt->scale[3]));
+/*     so_method(so, nv30->screen->rankine, 0x1d78, 1);
+       so_data  (so, 1);
+*/
        /* TODO/FIXME: never saw value 0x0110 in renouveau dumps, only 0x0001 */
        so_method(so, nv30->screen->rankine, 0x1d78, 1);
        so_data  (so, 1);
index 4861924dac7c30a9338de054a18e968125fc3082..97fb6a2ef947b4c1495979273e981efcfe07fe26 100644 (file)
@@ -101,7 +101,6 @@ struct nv40_blend_state {
 struct nv40_state {
        unsigned scissor_enabled;
        unsigned stipple_enabled;
-       unsigned viewport_bypass;
        unsigned fp_samplers;
 
        uint64_t dirty;
index 9919ba1d0b0dcd5e766181ebf5e67c5ad269c57e..3aacb00f996b3fbc46fdcd9a0d3cb3cccfd28296 100644 (file)
@@ -5,55 +5,24 @@ nv40_state_viewport_validate(struct nv40_context *nv40)
 {
        struct pipe_viewport_state *vpt = &nv40->viewport;
        struct nouveau_stateobj *so;
-       unsigned bypass;
-
-       if (nv40->render_mode == HW &&
-           !nv40->rasterizer->pipe.bypass_vs_clip_and_viewport)
-               bypass = 0;
-       else
-               bypass = 1;
 
        if (nv40->state.hw[NV40_STATE_VIEWPORT] &&
-           (bypass || !(nv40->dirty & NV40_NEW_VIEWPORT)) &&
-           nv40->state.viewport_bypass == bypass)
+           !(nv40->dirty & NV40_NEW_VIEWPORT))
                return FALSE;
-       nv40->state.viewport_bypass = bypass;
 
        so = so_new(2, 9, 0);
-       if (!bypass) {
-               so_method(so, nv40->screen->curie,
-                         NV40TCL_VIEWPORT_TRANSLATE_X, 8);
-               so_data  (so, fui(vpt->translate[0]));
-               so_data  (so, fui(vpt->translate[1]));
-               so_data  (so, fui(vpt->translate[2]));
-               so_data  (so, fui(vpt->translate[3]));
-               so_data  (so, fui(vpt->scale[0]));
-               so_data  (so, fui(vpt->scale[1]));
-               so_data  (so, fui(vpt->scale[2]));
-               so_data  (so, fui(vpt->scale[3]));
-               so_method(so, nv40->screen->curie, 0x1d78, 1);
-               so_data  (so, 1);
-       } else {
-               so_method(so, nv40->screen->curie,
-                         NV40TCL_VIEWPORT_TRANSLATE_X, 8);
-               so_data  (so, fui(0.0));
-               so_data  (so, fui(0.0));
-               so_data  (so, fui(0.0));
-               so_data  (so, fui(0.0));
-               so_data  (so, fui(1.0));
-               so_data  (so, fui(1.0));
-               so_data  (so, fui(1.0));
-               so_data  (so, fui(0.0));
-               /* Not entirely certain what this is yet.  The DDX uses this
-                * value also as it fixes rendering when you pass
-                * pre-transformed vertices to the GPU.  My best gusss is that
-                * this bypasses some culling/clipping stage.  Might be worth
-                * noting that points/lines are uneffected by whatever this
-                * value fixes, only filled polygons are effected.
-                */
-               so_method(so, nv40->screen->curie, 0x1d78, 1);
-               so_data  (so, 0x110);
-       }
+       so_method(so, nv40->screen->curie,
+                 NV40TCL_VIEWPORT_TRANSLATE_X, 8);
+       so_data  (so, fui(vpt->translate[0]));
+       so_data  (so, fui(vpt->translate[1]));
+       so_data  (so, fui(vpt->translate[2]));
+       so_data  (so, fui(vpt->translate[3]));
+       so_data  (so, fui(vpt->scale[0]));
+       so_data  (so, fui(vpt->scale[1]));
+       so_data  (so, fui(vpt->scale[2]));
+       so_data  (so, fui(vpt->scale[3]));
+       so_method(so, nv40->screen->curie, 0x1d78, 1);
+       so_data  (so, 1);
 
        so_ref(so, &nv40->state.hw[NV40_STATE_VIEWPORT]);
        so_ref(NULL, &so);
index b4de3e2ba574d7ca95d0537010cb40a9870af5b5..c540594b9495924359717ebfe3eb6be22ff2b65b 100644 (file)
@@ -127,7 +127,6 @@ struct nv50_state {
        struct nouveau_stateobj *scissor;
        unsigned scissor_enabled;
        struct nouveau_stateobj *viewport;
-       unsigned viewport_bypass;
        struct nouveau_stateobj *tsc_upload;
        struct nouveau_stateobj *tic_upload;
        unsigned miptree_nr[PIPE_SHADER_TYPES];
index efab94cab743b22df81045d7a8091afd8db4168d..a91b31015e2ab4dcd7f741eba8f59338acf38df0 100644 (file)
@@ -375,50 +375,32 @@ nv50_state_validate(struct nv50_context *nv50)
 scissor_uptodate:
 
        if (nv50->dirty & (NV50_NEW_VIEWPORT | NV50_NEW_RASTERIZER)) {
-               unsigned bypass;
-
-               if (!nv50->rasterizer->pipe.bypass_vs_clip_and_viewport)
-                       bypass = 0;
-               else
-                       bypass = 1;
-
                if (nv50->state.viewport &&
-                   (bypass || !(nv50->dirty & NV50_NEW_VIEWPORT)) &&
-                   nv50->state.viewport_bypass == bypass)
+                   !(nv50->dirty & NV50_NEW_VIEWPORT))
                        goto viewport_uptodate;
-               nv50->state.viewport_bypass = bypass;
 
                so = so_new(5, 9, 0);
-               if (!bypass) {
-                       so_method(so, tesla, NV50TCL_VIEWPORT_TRANSLATE_X(0), 3);
-                       so_data  (so, fui(nv50->viewport.translate[0]));
-                       so_data  (so, fui(nv50->viewport.translate[1]));
-                       so_data  (so, fui(nv50->viewport.translate[2]));
-                       so_method(so, tesla, NV50TCL_VIEWPORT_SCALE_X(0), 3);
-                       so_data  (so, fui(nv50->viewport.scale[0]));
-                       so_data  (so, fui(nv50->viewport.scale[1]));
-                       so_data  (so, fui(nv50->viewport.scale[2]));
-
-                       so_method(so, tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1);
-                       so_data  (so, 1);
-                       /* 0x0000 = remove whole primitive only (xyz)
-                        * 0x1018 = remove whole primitive only (xy), clamp z
-                        * 0x1080 = clip primitive (xyz)
-                        * 0x1098 = clip primitive (xy), clamp z
-                        */
-                       so_method(so, tesla, NV50TCL_VIEW_VOLUME_CLIP_CTRL, 1);
-                       so_data  (so, 0x1080);
-                       /* no idea what 0f90 does */
-                       so_method(so, tesla, 0x0f90, 1);
-                       so_data  (so, 0);
-               } else {
-                       so_method(so, tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1);
-                       so_data  (so, 0);
-                       so_method(so, tesla, NV50TCL_VIEW_VOLUME_CLIP_CTRL, 1);
-                       so_data  (so, 0x0000);
-                       so_method(so, tesla, 0x0f90, 1);
-                       so_data  (so, 1);
-               }
+               so_method(so, tesla, NV50TCL_VIEWPORT_TRANSLATE_X(0), 3);
+               so_data  (so, fui(nv50->viewport.translate[0]));
+               so_data  (so, fui(nv50->viewport.translate[1]));
+               so_data  (so, fui(nv50->viewport.translate[2]));
+               so_method(so, tesla, NV50TCL_VIEWPORT_SCALE_X(0), 3);
+               so_data  (so, fui(nv50->viewport.scale[0]));
+               so_data  (so, fui(nv50->viewport.scale[1]));
+               so_data  (so, fui(nv50->viewport.scale[2]));
+
+               so_method(so, tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1);
+               so_data  (so, 1);
+               /* 0x0000 = remove whole primitive only (xyz)
+                * 0x1018 = remove whole primitive only (xy), clamp z
+                * 0x1080 = clip primitive (xyz)
+                * 0x1098 = clip primitive (xy), clamp z
+                */
+               so_method(so, tesla, NV50TCL_VIEW_VOLUME_CLIP_CTRL, 1);
+               so_data  (so, 0x1080);
+               /* no idea what 0f90 does */
+               so_method(so, tesla, 0x0f90, 1);
+               so_data  (so, 0);
 
                so_ref(so, &nv50->state.viewport);
                so_ref(NULL, &so);
index 443af4ec2e346aa127e1222167c70f7b11ca24f9..2f056aafcbfaec64d194863a76c6b748ff3053ca 100644 (file)
@@ -337,8 +337,6 @@ struct r300_context {
     uint32_t dirty_state;
     /* Flag indicating whether or not the HW is dirty. */
     uint32_t dirty_hw;
-    /* Whether the TCL engine should be in bypass mode. */
-    boolean tcl_bypass;
     /* Whether polygon offset is enabled. */
     boolean polygon_offset_enabled;
     /* Z buffer bit depth. */
index f7dcd8dc52fae8622d5227ca0cfbb5a256750784..37ebe6c49df3913229cc318428fc95638d72d8ff 100644 (file)
@@ -170,23 +170,15 @@ static const float * get_shader_constant(
                     break;
 
                 case RC_STATE_R300_VIEWPORT_SCALE:
-                    if (r300->tcl_bypass) {
-                        vec[0] = 1;
-                        vec[1] = 1;
-                        vec[2] = 1;
-                    } else {
-                        vec[0] = viewport->xscale;
-                        vec[1] = viewport->yscale;
-                        vec[2] = viewport->zscale;
-                    }
+                    vec[0] = viewport->xscale;
+                    vec[1] = viewport->yscale;
+                    vec[2] = viewport->zscale;
                     break;
 
                 case RC_STATE_R300_VIEWPORT_OFFSET:
-                    if (!r300->tcl_bypass) {
-                        vec[0] = viewport->xoffset;
-                        vec[1] = viewport->yoffset;
-                        vec[2] = viewport->zoffset;
-                    }
+                    vec[0] = viewport->xoffset;
+                    vec[1] = viewport->yoffset;
+                    vec[2] = viewport->zoffset;
                     break;
 
                 default:
@@ -936,22 +928,16 @@ void r300_emit_viewport_state(struct r300_context* r300, void* state)
     struct r300_viewport_state* viewport = (struct r300_viewport_state*)state;
     CS_LOCALS(r300);
 
-    if (r300->tcl_bypass) {
-        BEGIN_CS(2);
-        OUT_CS_REG(R300_VAP_VTE_CNTL, 0);
-        END_CS;
-    } else {
-        BEGIN_CS(9);
-        OUT_CS_REG_SEQ(R300_SE_VPORT_XSCALE, 6);
-        OUT_CS_32F(viewport->xscale);
-        OUT_CS_32F(viewport->xoffset);
-        OUT_CS_32F(viewport->yscale);
-        OUT_CS_32F(viewport->yoffset);
-        OUT_CS_32F(viewport->zscale);
-        OUT_CS_32F(viewport->zoffset);
-        OUT_CS_REG(R300_VAP_VTE_CNTL, viewport->vte_control);
-        END_CS;
-    }
+    BEGIN_CS(9);
+    OUT_CS_REG_SEQ(R300_SE_VPORT_XSCALE, 6);
+    OUT_CS_32F(viewport->xscale);
+    OUT_CS_32F(viewport->xoffset);
+    OUT_CS_32F(viewport->yscale);
+    OUT_CS_32F(viewport->yoffset);
+    OUT_CS_32F(viewport->zscale);
+    OUT_CS_32F(viewport->zoffset);
+    OUT_CS_REG(R300_VAP_VTE_CNTL, viewport->vte_control);
+    END_CS;
 }
 
 void r300_emit_texture_count(struct r300_context* r300)
index 34bf81c1930cb05b0fa023fdd6904a4c208742f5..3550c69c46d7d37bf1191057d0220e25c509b71d 100644 (file)
@@ -711,8 +711,7 @@ static void* r300_create_rs_state(struct pipe_context* pipe,
 
     /* If bypassing TCL, or if no TCL engine is present, turn off the HW TCL.
      * Else, enable HW TCL and force Draw's TCL off. */
-    if (state->bypass_vs_clip_and_viewport ||
-            !r300screen->caps->has_tcl) {
+    if (!r300screen->caps->has_tcl) {
         rs->vap_control_status |= R300_VAP_TCL_BYPASS;
     }
 
@@ -824,10 +823,8 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
     }
 
     if (rs) {
-        r300->tcl_bypass = rs->rs.bypass_vs_clip_and_viewport;
         r300->polygon_offset_enabled = rs->rs.offset_cw || rs->rs.offset_ccw;
     } else {
-        r300->tcl_bypass = FALSE;
         r300->polygon_offset_enabled = FALSE;
     }
 
index 2cbce9210a7e35ae48205558297e66979935cba0..778eaaacd99942b7b3278ae64a308c4e999592d6 100644 (file)
@@ -114,13 +114,7 @@ static void r300_vertex_psc(struct r300_context* r300)
     int identity[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
     int* stream_tab;
 
-    /* If TCL is bypassed, map vertex streams to equivalent VS output
-     * locations. */
-    if (r300->tcl_bypass) {
-        stream_tab = r300->vs->stream_loc_notcl;
-    } else {
-        stream_tab = identity;
-    }
+    stream_tab = identity;
 
     /* Vertex shaders have no semantics on their inputs,
      * so PSC should just route stuff based on the vertex elements,
index 7a3a6361670391a6b35a145a4db3fc5c337bf64f..8e4867a904ea2868148eeb59ba30fc75272b23d2 100644 (file)
@@ -174,7 +174,6 @@ init_pipe_state(struct sp_mpeg12_context *ctx)
    rast.line_stipple_factor = 0;
    rast.line_stipple_pattern = 0;
    rast.line_last_pixel = 0;
-   rast.bypass_vs_clip_and_viewport = 0;
    rast.line_width = 1;
    rast.point_smooth = 0;
    rast.point_quad_rasterization = 0;
index b4cafb8f219f90f75f9d883a8b78bf28afde9902..4d0c06bd77e7dac7a8894470a9ca36d0818f6a89 100644 (file)
@@ -120,174 +120,153 @@ static int emit_viewport( struct svga_context *svga,
    float fb_width = svga->curr.framebuffer.width;
    float fb_height = svga->curr.framebuffer.height;
 
-   memset( &prescale, 0, sizeof(prescale) );
-
-   if (svga->curr.rast->templ.bypass_vs_clip_and_viewport) {
-
-      /* Avoid POSITIONT as it has a non trivial implementation outside the D3D
-       * API. Always generate a vertex shader.
-       */
-      rect.x = 0;
-      rect.y = 0;
-      rect.w = svga->curr.framebuffer.width;
-      rect.h = svga->curr.framebuffer.height;
-
-      prescale.scale[0] = 2.0 / (float)rect.w;
-      prescale.scale[1] = - 2.0 / (float)rect.h;
-      prescale.scale[2] = 1.0;
-      prescale.scale[3] = 1.0;
-      prescale.translate[0] = -1.0f;
-      prescale.translate[1] = 1.0f;
-      prescale.translate[2] = 0;
-      prescale.translate[3] = 0;
-      prescale.enabled = TRUE;
-   } else {
-
-      /* Examine gallium viewport transformation and produce a screen
-       * rectangle and possibly vertex shader pre-transformation to
-       * get the same results.
-       */
-      float fx =        viewport->scale[0] * -1.0 + viewport->translate[0];
-      float fy = flip * viewport->scale[1] * -1.0 + viewport->translate[1];
-      float fw =        viewport->scale[0] * 2; 
-      float fh = flip * viewport->scale[1] * 2; 
-
-      SVGA_DBG(DEBUG_VIEWPORT,
-               "\ninitial %f,%f %fx%f\n",
-               fx,
-               fy,
-               fw,
-               fh);
-
-      prescale.scale[0] = 1.0;
-      prescale.scale[1] = 1.0;
-      prescale.scale[2] = 1.0;
-      prescale.scale[3] = 1.0;
-      prescale.translate[0] = 0;
-      prescale.translate[1] = 0;
-      prescale.translate[2] = 0;
-      prescale.translate[3] = 0;
-      prescale.enabled = TRUE;
-
-
-
-      if (fw < 0) {
-         prescale.scale[0] *= -1.0;
-         prescale.translate[0] += -fw;
-         fw = -fw;
-         fx =        viewport->scale[0] * 1.0 + viewport->translate[0];
-      }
+   float fx =        viewport->scale[0] * -1.0 + viewport->translate[0];
+   float fy = flip * viewport->scale[1] * -1.0 + viewport->translate[1];
+   float fw =        viewport->scale[0] * 2; 
+   float fh = flip * viewport->scale[1] * 2; 
 
-      if (fh < 0) {
-         prescale.scale[1] *= -1.0;
-         prescale.translate[1] += -fh;
-         fh = -fh;
-         fy = flip * viewport->scale[1] * 1.0 + viewport->translate[1];
-      }
+   memset( &prescale, 0, sizeof(prescale) );
 
-      if (fx < 0) {
-         prescale.translate[0] += fx;
-         prescale.scale[0] *= fw / (fw + fx); 
-         fw += fx;
-         fx = 0;
-      }
+   /* Examine gallium viewport transformation and produce a screen
+    * rectangle and possibly vertex shader pre-transformation to
+    * get the same results.
+    */
 
-      if (fy < 0) {
-         prescale.translate[1] += fy;
-         prescale.scale[1] *= fh / (fh + fy); 
-         fh += fy;
-         fy = 0;
-      }
+   SVGA_DBG(DEBUG_VIEWPORT,
+            "\ninitial %f,%f %fx%f\n",
+            fx,
+            fy,
+            fw,
+            fh);
+
+   prescale.scale[0] = 1.0;
+   prescale.scale[1] = 1.0;
+   prescale.scale[2] = 1.0;
+   prescale.scale[3] = 1.0;
+   prescale.translate[0] = 0;
+   prescale.translate[1] = 0;
+   prescale.translate[2] = 0;
+   prescale.translate[3] = 0;
+   prescale.enabled = TRUE;
+
+
+
+   if (fw < 0) {
+      prescale.scale[0] *= -1.0;
+      prescale.translate[0] += -fw;
+      fw = -fw;
+      fx =        viewport->scale[0] * 1.0 + viewport->translate[0];
+   }
 
-      if (fx + fw > fb_width) {
-         prescale.scale[0] *= fw / (fb_width - fx); 
-         prescale.translate[0] -= fx * (fw / (fb_width - fx));
-         prescale.translate[0] += fx;
-         fw = fb_width - fx;
-         
-      }
+   if (fh < 0) {
+      prescale.scale[1] *= -1.0;
+      prescale.translate[1] += -fh;
+      fh = -fh;
+      fy = flip * viewport->scale[1] * 1.0 + viewport->translate[1];
+   }
 
-      if (fy + fh > fb_height) {
-         prescale.scale[1] *= fh / (fb_height - fy);
-         prescale.translate[1] -= fy * (fh / (fb_height - fy));
-         prescale.translate[1] += fy;
-         fh = fb_height - fy;
-      }
+   if (fx < 0) {
+      prescale.translate[0] += fx;
+      prescale.scale[0] *= fw / (fw + fx); 
+      fw += fx;
+      fx = 0;
+   }
 
-      if (fw < 0 || fh < 0) {
-         fw = fh = fx = fy = 0;
-         degenerate = TRUE;
-         goto out;
-      }
+   if (fy < 0) {
+      prescale.translate[1] += fy;
+      prescale.scale[1] *= fh / (fh + fy); 
+      fh += fy;
+      fy = 0;
+   }
 
+   if (fx + fw > fb_width) {
+      prescale.scale[0] *= fw / (fb_width - fx); 
+      prescale.translate[0] -= fx * (fw / (fb_width - fx));
+      prescale.translate[0] += fx;
+      fw = fb_width - fx;
+      
+   }
 
-      /* D3D viewport is integer space.  Convert fx,fy,etc. to
-       * integers.
-       *
-       * TODO: adjust pretranslate correct for any subpixel error
-       * introduced converting to integers.
-       */
-      rect.x = fx;
-      rect.y = fy;
-      rect.w = fw;
-      rect.h = fh;
+   if (fy + fh > fb_height) {
+      prescale.scale[1] *= fh / (fb_height - fy);
+      prescale.translate[1] -= fy * (fh / (fb_height - fy));
+      prescale.translate[1] += fy;
+      fh = fb_height - fy;
+   }
 
-      SVGA_DBG(DEBUG_VIEWPORT,
-               "viewport error %f,%f %fx%f\n",
-               fabs((float)rect.x - fx),
-               fabs((float)rect.y - fy),
-               fabs((float)rect.w - fw),
-               fabs((float)rect.h - fh));
+   if (fw < 0 || fh < 0) {
+      fw = fh = fx = fy = 0;
+      degenerate = TRUE;
+      goto out;
+   }
 
-      SVGA_DBG(DEBUG_VIEWPORT,
-               "viewport %d,%d %dx%d\n",
-               rect.x,
-               rect.y,
-               rect.w,
-               rect.h);
-      
 
-      /* Finally, to get GL rasterization rules, need to tweak the
-       * screen-space coordinates slightly relative to D3D which is
-       * what hardware implements natively.
-       */
-      if (svga->curr.rast->templ.gl_rasterization_rules) {
-         float adjust_x = 0.0;
-         float adjust_y = 0.0;
-
-         switch (svga->curr.reduced_prim) {
-         case PIPE_PRIM_LINES:
-            adjust_x = -0.5;
-            adjust_y = 0;
-            break;
-         case PIPE_PRIM_POINTS:
-         case PIPE_PRIM_TRIANGLES:
-            adjust_x = -0.375;
-            adjust_y = -0.5;
-            break;
-         }
-
-         prescale.translate[0] += adjust_x;
-         prescale.translate[1] += adjust_y;
-         prescale.translate[2] = 0.5; /* D3D clip space */
-         prescale.scale[2]     = 0.5; /* D3D clip space */
+   /* D3D viewport is integer space.  Convert fx,fy,etc. to
+    * integers.
+    *
+    * TODO: adjust pretranslate correct for any subpixel error
+    * introduced converting to integers.
+    */
+   rect.x = fx;
+   rect.y = fy;
+   rect.w = fw;
+   rect.h = fh;
+
+   SVGA_DBG(DEBUG_VIEWPORT,
+            "viewport error %f,%f %fx%f\n",
+            fabs((float)rect.x - fx),
+            fabs((float)rect.y - fy),
+            fabs((float)rect.w - fw),
+            fabs((float)rect.h - fh));
+
+   SVGA_DBG(DEBUG_VIEWPORT,
+            "viewport %d,%d %dx%d\n",
+            rect.x,
+            rect.y,
+            rect.w,
+            rect.h);
+
+
+   /* Finally, to get GL rasterization rules, need to tweak the
+    * screen-space coordinates slightly relative to D3D which is
+    * what hardware implements natively.
+    */
+   if (svga->curr.rast->templ.gl_rasterization_rules) {
+      float adjust_x = 0.0;
+      float adjust_y = 0.0;
+
+      switch (svga->curr.reduced_prim) {
+      case PIPE_PRIM_LINES:
+         adjust_x = -0.5;
+         adjust_y = 0;
+         break;
+      case PIPE_PRIM_POINTS:
+      case PIPE_PRIM_TRIANGLES:
+         adjust_x = -0.375;
+         adjust_y = -0.5;
+         break;
       }
 
+      prescale.translate[0] += adjust_x;
+      prescale.translate[1] += adjust_y;
+      prescale.translate[2] = 0.5; /* D3D clip space */
+      prescale.scale[2]     = 0.5; /* D3D clip space */
+   }
 
-      range_min = viewport->scale[2] * -1.0 + viewport->translate[2];
-      range_max = viewport->scale[2] *  1.0 + viewport->translate[2];
 
-      /* D3D (and by implication SVGA) doesn't like dealing with zmax
-       * less than zmin.  Detect that case, flip the depth range and
-       * invert our z-scale factor to achieve the same effect.
-       */
-      if (range_min > range_max) {
-         float range_tmp;
-         range_tmp = range_min; 
-         range_min = range_max; 
-         range_max = range_tmp;
-         prescale.scale[2]     = -prescale.scale[2];
-      }
+   range_min = viewport->scale[2] * -1.0 + viewport->translate[2];
+   range_max = viewport->scale[2] *  1.0 + viewport->translate[2];
+
+   /* D3D (and by implication SVGA) doesn't like dealing with zmax
+    * less than zmin.  Detect that case, flip the depth range and
+    * invert our z-scale factor to achieve the same effect.
+    */
+   if (range_min > range_max) {
+      float range_tmp;
+      range_tmp = range_min; 
+      range_min = range_max; 
+      range_max = range_tmp;
+      prescale.scale[2]     = -prescale.scale[2];
    }
 
    if (prescale.enabled) {
index dd13a89d24db35921a9ee6aae5f838e0eea40e95..a6ed18599c42f20abfa763c9a15a0290dc382ecf 100644 (file)
@@ -129,8 +129,7 @@ static int update_need_pipeline( struct svga_context *svga,
 
    /* SVGA_NEW_CLIP 
     */
-   if (!svga->curr.rast->templ.bypass_vs_clip_and_viewport &&
-       svga->curr.clip.nr) {
+   if (svga->curr.clip.nr) {
       SVGA_DBG(DEBUG_SWTNL, "%s: userclip\n", __FUNCTION__);
       need_pipeline = TRUE;
    }
index 6da186a655523b73f730a2816848ca3d60446765..f97d963dba6975864fc679a686e55797c649182e 100644 (file)
@@ -112,7 +112,6 @@ void trace_dump_rasterizer_state(const struct pipe_rasterizer_state *state)
    trace_dump_member(uint, state, line_stipple_factor);
    trace_dump_member(uint, state, line_stipple_pattern);
    trace_dump_member(bool, state, line_last_pixel);
-   trace_dump_member(bool, state, bypass_vs_clip_and_viewport);
    trace_dump_member(bool, state, flatshade_first);
    trace_dump_member(bool, state, gl_rasterization_rules);
 
index 5ac5c878135db10ae652438c1c5576cc6e626251..02558520bfe9e2ebe5b12febd45356a8c8ad8e8f 100644 (file)
@@ -113,16 +113,6 @@ struct pipe_rasterizer_state
    unsigned line_stipple_pattern:16;
    unsigned line_last_pixel:1;
 
-   /** 
-    * Vertex coordinates are pre-transformed to screen space.  Skip
-    * the vertex shader, clipping and viewport processing.  Note that
-    * a vertex shader is still needed though, to indicate the mapping
-    * from vertex elements to fragment shader input semantics.
-    *
-    * XXX: considered for removal.
-    */
-   unsigned bypass_vs_clip_and_viewport:1;
-
    /** 
     * Use the first vertex of a primitive as the provoking vertex for
     * flat shading.
index 898c32293d1fbc408c97108a845d4e1e4ae40d1a..5edab55ccabbbeb40516f8bdb8fcfcf3a60df29f 100644 (file)
@@ -65,9 +65,6 @@ st_init_clear(struct st_context *st)
    memset(&st->clear.raster, 0, sizeof(st->clear.raster));
    st->clear.raster.gl_rasterization_rules = 1;
 
-   /* rasterizer state: bypass vertex shader, clipping and viewport */
-   st->clear.raster.bypass_vs_clip_and_viewport = 1;
-
    /* fragment shader state: color pass-through program */
    st->clear.fs =
       util_make_fragment_passthrough_shader(pipe);
@@ -104,9 +101,7 @@ st_destroy_clear(struct st_context *st)
 
 /**
  * Draw a screen-aligned quadrilateral.
- * Coords are window coords with y=0=bottom.  These will be passed
- * through unmodified to the rasterizer as we have set
- * rasterizer->bypass_vs_clip_and_viewport.
+ * Coords are clip coords with y=0=bottom.
  */
 static void
 draw_quad(GLcontext *ctx,
@@ -192,18 +187,13 @@ clear_with_quad(GLcontext *ctx,
                 GLboolean color, GLboolean depth, GLboolean stencil)
 {
    struct st_context *st = ctx->st;
-   const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin;
-   const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax;
-   GLfloat y0, y1;
-
-   if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
-      y0 = (GLfloat) (ctx->DrawBuffer->Height - ctx->DrawBuffer->_Ymax);
-      y1 = (GLfloat) (ctx->DrawBuffer->Height - ctx->DrawBuffer->_Ymin);
-   }
-   else {
-      y0 = (GLfloat) ctx->DrawBuffer->_Ymin;
-      y1 = (GLfloat) ctx->DrawBuffer->_Ymax;
-   }
+   const struct gl_framebuffer *fb = ctx->DrawBuffer;
+   const GLfloat fb_width = (GLfloat) fb->Width;
+   const GLfloat fb_height = (GLfloat) fb->Height;
+   const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin / fb_width * 2.0f - 1.0f;
+   const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax / fb_width * 2.0f - 1.0f;
+   const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin / fb_height * 2.0f - 1.0f;
+   const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax / fb_height * 2.0f - 1.0f;
 
    /*
    printf("%s %s%s%s %f,%f %f,%f\n", __FUNCTION__, 
@@ -218,6 +208,7 @@ clear_with_quad(GLcontext *ctx,
    cso_save_stencil_ref(st->cso_context);
    cso_save_depth_stencil_alpha(st->cso_context);
    cso_save_rasterizer(st->cso_context);
+   cso_save_viewport(st->cso_context);
    cso_save_fragment_shader(st->cso_context);
    cso_save_vertex_shader(st->cso_context);
 
@@ -273,6 +264,21 @@ clear_with_quad(GLcontext *ctx,
 
    cso_set_rasterizer(st->cso_context, &st->clear.raster);
 
+   /* viewport state: viewport matching window dims */
+   {
+      const GLboolean invert = (st_fb_orientation(fb) == Y_0_TOP);
+      struct pipe_viewport_state vp;
+      vp.scale[0] = 0.5f * fb_width;
+      vp.scale[1] = fb_height * (invert ? -0.5f : 0.5f);
+      vp.scale[2] = 1.0f;
+      vp.scale[3] = 1.0f;
+      vp.translate[0] = 0.5f * fb_width;
+      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_fragment_shader_handle(st->cso_context, st->clear.fs);
    cso_set_vertex_shader_handle(st->cso_context, st->clear.vs);
 
@@ -284,9 +290,9 @@ clear_with_quad(GLcontext *ctx,
    cso_restore_stencil_ref(st->cso_context);
    cso_restore_depth_stencil_alpha(st->cso_context);
    cso_restore_rasterizer(st->cso_context);
+   cso_restore_viewport(st->cso_context);
    cso_restore_fragment_shader(st->cso_context);
    cso_restore_vertex_shader(st->cso_context);
-
 }