nvc0: fix clipping with scissors/viewport
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Sun, 19 Dec 2010 20:42:00 +0000 (21:42 +0100)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Sun, 19 Dec 2010 20:42:00 +0000 (21:42 +0100)
Also setup optional path to use proper primitive clipping instead,
which is probably slower.

src/gallium/drivers/nvc0/nvc0_state.c
src/gallium/drivers/nvc0/nvc0_state_validate.c
src/gallium/drivers/nvc0/nvc0_stateobj.h

index 8d293233b12adc9211c002ab7dec78fc98589daa..a462b543ad0b9c30f607430e5253dd0b68b2af26 100644 (file)
@@ -175,6 +175,10 @@ nvc0_rasterizer_state_create(struct pipe_context *pipe,
     if (!so)
         return NULL;
     so->pipe = *cso;
+
+#ifndef NVC0_SCISSORS_CLIPPING
+    SB_OUT_3D  (so, SCISSOR_ENABLE(0), cso->scissor);
+#endif
     
     SB_BEGIN_3D(so, SHADE_MODEL, 1);
     SB_DATA    (so, cso->flatshade ? NVC0_3D_SHADE_MODEL_FLAT :
index fe40d493d9ef9b0d07b547cdc99cf026a661ba8c..a1419bb310caac09cc61fab07ec6027bc41d78d2 100644 (file)
@@ -107,9 +107,11 @@ nvc0_validate_fb(struct nvc0_context *nvc0)
         OUT_RING  (chan, 0);
     }
 
+#ifndef NVC0_SCISSORS_CLIPPING
     BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2);
     OUT_RING  (chan, fb->width << 16);
     OUT_RING  (chan, fb->height << 16);
+#endif
 }
 
 static void
@@ -151,21 +153,44 @@ nvc0_validate_scissor(struct nvc0_context *nvc0)
 {
     struct nouveau_channel *chan = nvc0->screen->base.channel;
     struct pipe_scissor_state *s = &nvc0->scissor;
+#ifdef NVC0_SCISSORS_CLIPPING
+    struct pipe_viewport_state *vp = &nvc0->viewport;
+    int minx, maxx, miny, maxy;
 
-    if (!(nvc0->dirty & NVC0_NEW_SCISSOR) &&
-       nvc0->state.scissor == nvc0->rast->pipe.scissor)
+    if (!(nvc0->dirty &
+          (NVC0_NEW_SCISSOR | NVC0_NEW_VIEWPORT | NVC0_NEW_FRAMEBUFFER)) &&
+        nvc0->state.scissor == nvc0->rast->pipe.scissor)
        return;
     nvc0->state.scissor = nvc0->rast->pipe.scissor;
 
     if (nvc0->state.scissor) {
-       BEGIN_RING(chan, RING_3D(SCISSOR_HORIZ(0)), 2);
-       OUT_RING  (chan, (s->maxx << 16) | s->minx);
-       OUT_RING  (chan, (s->maxy << 16) | s->miny);
+       minx = s->minx;
+       maxx = s->maxx;
+       miny = s->miny;
+       maxy = s->maxy;
     } else {
-       BEGIN_RING(chan, RING_3D(SCISSOR_HORIZ(0)), 2);
-       OUT_RING  (chan, nvc0->framebuffer.width << 16);
-       OUT_RING  (chan, nvc0->framebuffer.height << 16);
+       minx = 0;
+       maxx = nvc0->framebuffer.width;
+       miny = 0;
+       maxy = nvc0->framebuffer.height;
     }
+
+    minx = MAX2(minx, (int)(vp->translate[0] - fabsf(vp->scale[0])));
+    maxx = MIN2(maxx, (int)(vp->translate[0] + fabsf(vp->scale[0])));
+    miny = MAX2(miny, (int)(vp->translate[1] - fabsf(vp->scale[1])));
+    maxy = MIN2(maxy, (int)(vp->translate[1] + fabsf(vp->scale[1])));
+
+    BEGIN_RING(chan, RING_3D(SCISSOR_HORIZ(0)), 2);
+    OUT_RING  (chan, (maxx << 16) | minx);
+    OUT_RING  (chan, (maxy << 16) | miny);
+    BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2);
+    OUT_RING  (chan, ((maxx - minx) << 16) | minx);
+    OUT_RING  (chan, ((maxy - miny) << 16) | miny);
+#else
+    BEGIN_RING(chan, RING_3D(SCISSOR_HORIZ(0)), 2);
+    OUT_RING  (chan, (s->maxx << 16) | s->minx);
+    OUT_RING  (chan, (s->maxy << 16) | s->miny);
+#endif
 }
 
 static void
@@ -181,6 +206,12 @@ nvc0_validate_viewport(struct nvc0_context *nvc0)
     OUT_RINGf (chan, nvc0->viewport.scale[0]);
     OUT_RINGf (chan, nvc0->viewport.scale[1]);
     OUT_RINGf (chan, nvc0->viewport.scale[2]);
+
+#ifdef NVC0_SCISSORS_CLIPPING
+    BEGIN_RING(chan, RING_3D(DEPTH_RANGE_NEAR(0)), 2);
+    OUT_RINGf (chan, nvc0->viewport.translate[2] - nvc0->viewport.scale[2]);
+    OUT_RINGf (chan, nvc0->viewport.translate[2] + nvc0->viewport.scale[2]);
+#endif
 }
 
 static void
@@ -190,6 +221,9 @@ nvc0_validate_clip(struct nvc0_context *nvc0)
    uint32_t clip;
 
    clip = nvc0->clip.depth_clamp ? 0x201a : 0x0002;
+#ifndef NVC0_SCISSORS_CLIPPING
+   clip |= 0x1080;
+#endif
 
    BEGIN_RING(chan, RING_3D(VIEW_VOLUME_CLIP_CTRL), 1);
    OUT_RING  (chan, clip);
@@ -342,8 +376,13 @@ static struct state_validate {
     { nvc0_validate_blend_colour,  NVC0_NEW_BLEND_COLOUR },
     { nvc0_validate_stencil_ref,   NVC0_NEW_STENCIL_REF },
     { nvc0_validate_stipple,       NVC0_NEW_STIPPLE },
-    { nvc0_validate_scissor,       NVC0_NEW_SCISSOR | NVC0_NEW_FRAMEBUFFER |
-                                   NVC0_NEW_RASTERIZER },
+#ifdef NVC0_SCISSORS_CLIPPING
+    { nvc0_validate_scissor,       NVC0_NEW_SCISSOR | NVC0_NEW_VIEWPORT |
+                                   NVC0_NEW_RASTERIZER |
+                                   NVC0_NEW_FRAMEBUFFER },
+#else
+    { nvc0_validate_scissor,       NVC0_NEW_SCISSOR },
+#endif
     { nvc0_validate_viewport,      NVC0_NEW_VIEWPORT },
     { nvc0_validate_clip,          NVC0_NEW_CLIP },
     { nvc0_vertprog_validate,      NVC0_NEW_VERTPROG },
index 41084f369452c75dfb9c87942106aabf1ff0b807..67674d4093fa69d0ad086a76fb3bfc3c73162744 100644 (file)
@@ -4,6 +4,8 @@
 
 #include "pipe/p_state.h"
 
+#define NVC0_SCISSORS_CLIPPING
+
 #define SB_BEGIN_3D(so, m, s)                                                  \
    (so)->state[(so)->size++] =                                                 \
       (0x2 << 28) | ((s) << 16) | (NVC0_SUBCH_3D << 13) | ((NVC0_3D_##m) >> 2)
@@ -46,7 +48,7 @@ nvc0_tic_entry(struct pipe_sampler_view *view)
 struct nvc0_rasterizer_stateobj {
    struct pipe_rasterizer_state pipe;
    int size;
-   uint32_t state[42];
+   uint32_t state[43];
 };
 
 struct nvc0_zsa_stateobj {