OSDN Git Service

vc4: Fix accidental scissoring when scissor is disabled.
authorEric Anholt <eric@anholt.net>
Fri, 4 Dec 2015 21:41:50 +0000 (13:41 -0800)
committerEric Anholt <eric@anholt.net>
Sat, 5 Dec 2015 21:12:27 +0000 (13:12 -0800)
Even if the rasterizer has scissor disabled, we'll have whatever
vc4->scissor bounds were last set when someone set up a scissor, so we
shouldn't clip to them in that case.

Fixes piglit fbo-blit-rect, and a lot of MSAA tests once they're enabled.

src/gallium/drivers/vc4/vc4_emit.c

index ba064ff..8642638 100644 (file)
@@ -29,17 +29,35 @@ vc4_emit_state(struct pipe_context *pctx)
         struct vc4_context *vc4 = vc4_context(pctx);
 
         struct vc4_cl_out *bcl = cl_start(&vc4->bcl);
-        if (vc4->dirty & (VC4_DIRTY_SCISSOR | VC4_DIRTY_VIEWPORT)) {
+        if (vc4->dirty & (VC4_DIRTY_SCISSOR | VC4_DIRTY_VIEWPORT |
+                          VC4_DIRTY_RASTERIZER)) {
                 float *vpscale = vc4->viewport.scale;
                 float *vptranslate = vc4->viewport.translate;
                 float vp_minx = -fabsf(vpscale[0]) + vptranslate[0];
                 float vp_maxx = fabsf(vpscale[0]) + vptranslate[0];
                 float vp_miny = -fabsf(vpscale[1]) + vptranslate[1];
                 float vp_maxy = fabsf(vpscale[1]) + vptranslate[1];
-                uint32_t minx = MAX2(vc4->scissor.minx, vp_minx);
-                uint32_t miny = MAX2(vc4->scissor.miny, vp_miny);
-                uint32_t maxx = MIN2(vc4->scissor.maxx, vp_maxx);
-                uint32_t maxy = MIN2(vc4->scissor.maxy, vp_maxy);
+
+                /* Clip to the scissor if it's enabled, but still clip to the
+                 * drawable regardless since that controls where the binner
+                 * tries to put things.
+                 *
+                 * Additionally, always clip the rendering to the viewport,
+                 * since the hardware does guardband clipping, meaning
+                 * primitives would rasterize outside of the view volume.
+                 */
+                uint32_t minx, miny, maxx, maxy;
+                if (!vc4->rasterizer->base.scissor) {
+                        minx = MAX2(vp_minx, 0);
+                        miny = MAX2(vp_miny, 0);
+                        maxx = MIN2(vp_maxx, vc4->draw_width);
+                        maxy = MIN2(vp_maxy, vc4->draw_height);
+                } else {
+                        minx = MAX2(vp_minx, vc4->scissor.minx);
+                        miny = MAX2(vp_miny, vc4->scissor.miny);
+                        maxx = MIN2(vp_maxx, vc4->scissor.maxx);
+                        maxy = MIN2(vp_maxy, vc4->scissor.maxy);
+                }
 
                 cl_u8(&bcl, VC4_PACKET_CLIP_WINDOW);
                 cl_u16(&bcl, minx);