nouveau: NV30_TCL viewport/scissor fixes
authorBen Skeggs <skeggsb@gmail.com>
Fri, 8 Jun 2007 03:27:57 +0000 (13:27 +1000)
committerBen Skeggs <skeggsb@gmail.com>
Fri, 29 Jun 2007 04:28:39 +0000 (14:28 +1000)
src/mesa/drivers/dri/nouveau/nouveau_buffers.c
src/mesa/drivers/dri/nouveau/nouveau_context.h
src/mesa/drivers/dri/nouveau/nouveau_state.c
src/mesa/drivers/dri/nouveau/nv30_state.c

index b54f68f4023e89da23110fcaeae75348d5b0cd7c..e3968bd02fc2c301576ac4e542a37fa11fab9e56 100644 (file)
@@ -299,6 +299,8 @@ nouveau_cliprects_drawable_set(nouveauContextPtr nmesa,
    nmesa->pClipRects   = dPriv->pClipRects;
    nmesa->drawX                = dPriv->x;
    nmesa->drawY                = dPriv->y;
+   nmesa->drawW                = dPriv->w;
+   nmesa->drawH                = dPriv->h;
 }
 
 static void
@@ -313,6 +315,8 @@ nouveau_cliprects_renderbuffer_set(nouveauContextPtr nmesa,
    nmesa->osClipRect.y2        = nrb->mesa.Height;
    nmesa->drawX                = 0;
    nmesa->drawY                = 0;
+   nmesa->drawW                = nrb->mesa.Width;
+   nmesa->drawH                = nrb->mesa.Height;
 }
 
 void
index 87e4479da341092a3bf853ecc776ba6e399cc5d6..53f3393676fe76055aa30262dbc1d388e16c4afa 100644 (file)
@@ -150,7 +150,7 @@ typedef struct nouveau_context {
        GLuint numClipRects;
        drm_clip_rect_t *pClipRects;
        drm_clip_rect_t osClipRect;
-       GLuint drawX, drawY;
+       GLuint drawX, drawY, drawW, drawH;
 
        /* The rendering context information */
        GLenum current_primitive; /* the current primitive enum */
index e9fd188d73e9105c34778bec554b31ca5bcfdbfe..7cb805902a7553708aae3e217e530743f94444f0 100644 (file)
@@ -60,14 +60,14 @@ static void nouveauCalcViewport(GLcontext *ctx)
     nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
     const GLfloat *v = ctx->Viewport._WindowMap.m;
     GLfloat *m = nmesa->viewport.m;
-    GLfloat xoffset = nmesa->drawX, yoffset = nmesa->drawY;
+    GLfloat xoffset = nmesa->drawX, yoffset = nmesa->drawY + nmesa->drawH;
   
     nmesa->depth_scale = 1.0 / ctx->DrawBuffer->_DepthMaxF;
 
     m[MAT_SX] =   v[MAT_SX];
     m[MAT_TX] =   v[MAT_TX] + xoffset + SUBPIXEL_X;
     m[MAT_SY] = - v[MAT_SY];
-    m[MAT_TY] =   v[MAT_TY] + yoffset + SUBPIXEL_Y;
+    m[MAT_TY] = (-v[MAT_TY]) + yoffset + SUBPIXEL_Y;
     m[MAT_SZ] =   v[MAT_SZ] * nmesa->depth_scale;
     m[MAT_TZ] =   v[MAT_TZ] * nmesa->depth_scale;
 
index ad21fa2730281dd4dc37cc60e58c18f1ea0c3068..d329071d1eec34da4994bdac4c85ff15093a8be9 100644 (file)
@@ -639,25 +639,45 @@ void (*ReadBuffer)( GLcontext *ctx, GLenum buffer );
 /** Set rasterization mode */
 void (*RenderMode)(GLcontext *ctx, GLenum mode );
 
+/* Translate GL coords to window coords, clamping w/h to the
+ * dimensions of the window.
+ */
+static void nv30WindowCoords(nouveauContextPtr nmesa,
+                            GLuint x, GLuint y, GLuint w, GLuint h,
+                            GLuint *wX, GLuint *wY, GLuint *wW, GLuint *wH)
+{
+       if ((x+w) > nmesa->drawW)
+               w = nmesa->drawW - x;
+       (*wX) = x + nmesa->drawX;
+       (*wW) = w;
+
+       if ((y+h) > nmesa->drawH)
+               h = nmesa->drawH - y;
+       (*wY) = (nmesa->drawH - y) - h + nmesa->drawY;
+       (*wH) = h;
+}
+
 /** Define the scissor box */
 static void nv30Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
 {
         nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+       GLuint wX, wY, wW, wH;
 
        /* There's no scissor enable bit, so adjust the scissor to cover the
         * maximum draw buffer bounds
         */
        if (!ctx->Scissor.Enabled) {
-          x = y = 0;
-          w = h = 4095;
+          wX = nmesa->drawX;
+          wY = nmesa->drawY;
+          wW = nmesa->drawW;
+          wH = nmesa->drawH;
        } else {
-          x += nmesa->drawX;
-          y += nmesa->drawY;
+          nv30WindowCoords(nmesa, x, y, w, h, &wX, &wY, &wW, &wH);
        }
 
         BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS, 2);
-        OUT_RING_CACHE(((w) << 16) | x);
-        OUT_RING_CACHE(((h) << 16) | y);
+        OUT_RING_CACHE  ((wW << 16) | wX);
+        OUT_RING_CACHE  ((wH << 16) | wY);
 }
 
 /** Select flat or smooth shading */
@@ -751,19 +771,21 @@ static void nv30WindowMoved(nouveauContextPtr nmesa)
 {
        GLcontext *ctx = nmesa->glCtx;
        GLfloat *v = nmesa->viewport.m;
-       GLuint w = ctx->Viewport.Width;
-       GLuint h = ctx->Viewport.Height;
-       GLuint x = ctx->Viewport.X + nmesa->drawX;
-       GLuint y = ctx->Viewport.Y + nmesa->drawY;
+       GLuint wX, wY, wW, wH;
 
+       nv30WindowCoords(nmesa, ctx->Viewport.X, ctx->Viewport.Y, 
+                               ctx->Viewport.Width, ctx->Viewport.Height,
+                               &wX, &wY, &wW, &wH);
         BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_DIMS_0, 2);
-        OUT_RING_CACHE((w << 16) | x);
-        OUT_RING_CACHE((h << 16) | y);
+        OUT_RING_CACHE  ((wW << 16) | wX);
+        OUT_RING_CACHE  ((wH << 16) | wY);
+
        /* something to do with clears, possibly doesn't belong here */
        BEGIN_RING_CACHE(NvSub3D,
              NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_OFS0, 2);
-        OUT_RING_CACHE(((w+x) << 16) | x);
-        OUT_RING_CACHE(((h+y) << 16) | y);
+        OUT_RING_CACHE(((nmesa->drawX + nmesa->drawW) << 16) | nmesa->drawX);
+        OUT_RING_CACHE(((nmesa->drawY + nmesa->drawH) << 16) | nmesa->drawY);
+
        /* viewport transform */
        BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_OX, 8);
        OUT_RING_CACHEf (v[MAT_TX]);