From d047168d81cfeb39a98f3ae16416872facc6237c Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Sun, 19 Dec 2010 21:42:00 +0100 Subject: [PATCH] nvc0: fix clipping with scissors/viewport Also setup optional path to use proper primitive clipping instead, which is probably slower. --- src/gallium/drivers/nvc0/nvc0_state.c | 4 ++ src/gallium/drivers/nvc0/nvc0_state_validate.c | 59 +++++++++++++++++++++----- src/gallium/drivers/nvc0/nvc0_stateobj.h | 4 +- 3 files changed, 56 insertions(+), 11 deletions(-) diff --git a/src/gallium/drivers/nvc0/nvc0_state.c b/src/gallium/drivers/nvc0/nvc0_state.c index 8d29323..a462b54 100644 --- a/src/gallium/drivers/nvc0/nvc0_state.c +++ b/src/gallium/drivers/nvc0/nvc0_state.c @@ -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 : diff --git a/src/gallium/drivers/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nvc0/nvc0_state_validate.c index fe40d49..a1419bb 100644 --- a/src/gallium/drivers/nvc0/nvc0_state_validate.c +++ b/src/gallium/drivers/nvc0/nvc0_state_validate.c @@ -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 }, diff --git a/src/gallium/drivers/nvc0/nvc0_stateobj.h b/src/gallium/drivers/nvc0/nvc0_stateobj.h index 41084f3..67674d4 100644 --- a/src/gallium/drivers/nvc0/nvc0_stateobj.h +++ b/src/gallium/drivers/nvc0/nvc0_stateobj.h @@ -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 { -- 2.7.4