nouveau: reindent nouveau_span.c
[mesa.git] / src / mesa / drivers / dri / nouveau / nv30_state.c
index e30dc8a37c360e6849a7e71b335b4b40d5cb818a..cd3ee9868805f8cab3c84f55391276caac72c541 100644 (file)
@@ -127,6 +127,11 @@ static void nv30ClearStencil(GLcontext *ctx, GLint s)
 static void nv30ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation)
 {
        nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+       if (NOUVEAU_CARD_USING_SHADERS)
+               return;
+
+       plane -= GL_CLIP_PLANE0;
        BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane), 4);
        OUT_RING_CACHEf(equation[0]);
        OUT_RING_CACHEf(equation[1]);
@@ -208,8 +213,14 @@ static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state)
                case GL_CLIP_PLANE3:
                case GL_CLIP_PLANE4:
                case GL_CLIP_PLANE5:
-                       BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1);
-                       OUT_RING_CACHE(state);
+                       if (NOUVEAU_CARD_USING_SHADERS) {
+                               nouveauShader *nvs = (nouveauShader *)ctx->VertexProgram._Current;
+                               if (nvs)
+                                       nvs->translated = GL_FALSE;
+                       } else {
+                               BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1);
+                               OUT_RING_CACHE(state);
+                       }
                        break;
                case GL_COLOR_LOGIC_OP:
                        BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 1);
@@ -233,6 +244,8 @@ static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state)
                        OUT_RING_CACHE(state);
                        break;
                case GL_FOG:
+                       if (NOUVEAU_CARD_USING_SHADERS)
+                               break;
                        BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_ENABLE, 1);
                        OUT_RING_CACHE(state);
                        break;
@@ -293,8 +306,10 @@ static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state)
 //             case GL_MAP2_VERTEX_4:
 //             case GL_MINMAX:
                case GL_NORMALIZE:
-                       BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1);
-                       OUT_RING_CACHE(state);
+                       if (nmesa->screen->card->type != NV_44) {
+                               BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1);
+                               OUT_RING_CACHE(state);
+                       }
                        break;
 //             case GL_POINT_SMOOTH:
                case GL_POLYGON_OFFSET_POINT:
@@ -346,17 +361,71 @@ static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state)
 static void nv30Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params)
 {
     nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+    if (NOUVEAU_CARD_USING_SHADERS)
+        return;
+
     switch(pname)
     {
-        case GL_FOG_MODE:
-            //BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_MODE, 1);
-            //OUT_RING_CACHE (params);
+    case GL_FOG_MODE:
+    {
+        int mode = 0;
+        /* The modes are different in GL and the card.  */
+        switch(ctx->Fog.Mode)
+        {
+        case GL_LINEAR:
+            mode = 0x804;
             break;
-            /* TODO: unsure about the rest.*/
-        default:
+        case GL_EXP:
+            mode = 0x802;
             break;
+        case GL_EXP2:
+            mode = 0x803;
+            break;
+        }
+       BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_MODE, 1);
+       OUT_RING_CACHE (mode);
+       break;
+    }
+    case GL_FOG_COLOR:
+    {
+       GLubyte c[4];
+       UNCLAMPED_FLOAT_TO_RGBA_CHAN(c,params);
+        BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_COLOR, 1);
+        /* nvidia ignores the alpha channel */
+       OUT_RING_CACHE(PACK_COLOR_8888_REV(c[0],c[1],c[2],c[3]));
+        break;
+    }
+    case GL_FOG_DENSITY:
+    case GL_FOG_START:
+    case GL_FOG_END:
+    {
+        GLfloat f=0., c=0.;
+        switch(ctx->Fog.Mode)
+        {
+        case GL_LINEAR:
+            f = -1.0/(ctx->Fog.End - ctx->Fog.Start);
+            c = ctx->Fog.Start/(ctx->Fog.End - ctx->Fog.Start) + 2.001953;
+            break;
+        case GL_EXP:
+            f = -0.090168*ctx->Fog.Density;
+            c = 1.5;
+        case GL_EXP2:
+            f = -0.212330*ctx->Fog.Density;
+            c = 1.5;
+        }
+        BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_LINEAR, 1);
+        OUT_RING_CACHE(f);
+        BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_CONSTANT, 1);
+        OUT_RING_CACHE(c);
+        BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_QUADRATIC, 1);
+        OUT_RING_CACHE(0); /* Is this always the same? */
+        break;
+    }
+//    case GL_FOG_COORD_SRC:
+    default:
+        break;
     }
-
 }
    
 static void nv30Hint(GLcontext *ctx, GLenum target, GLenum mode)
@@ -367,6 +436,7 @@ static void nv30Hint(GLcontext *ctx, GLenum target, GLenum mode)
 // void (*IndexMask)(GLcontext *ctx, GLuint mask);
 
 enum {
+       SPOTLIGHT_NO_UPDATE,
        SPOTLIGHT_UPDATE_EXPONENT,
        SPOTLIGHT_UPDATE_DIRECTION,
        SPOTLIGHT_UPDATE_ALL
@@ -377,7 +447,7 @@ static void nv30Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa
        nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
        GLint p = light - GL_LIGHT0;
        struct gl_light *l = &ctx->Light.Light[p];
-       int spotlightUpdate = -1;
+       int spotlight_update = SPOTLIGHT_NO_UPDATE;
 
        if (NOUVEAU_CARD_USING_SHADERS)
           return;
@@ -410,13 +480,13 @@ static void nv30Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa
                        OUT_RING_CACHEf(params[2]);
                        break;
                case GL_SPOT_DIRECTION:
-                       spotlightUpdate = SPOTLIGHT_UPDATE_DIRECTION;
+                       spotlight_update = SPOTLIGHT_UPDATE_DIRECTION;
                        break;
                case GL_SPOT_EXPONENT:
-                       spotlightUpdate = SPOTLIGHT_UPDATE_EXPONENT;
+                       spotlight_update = SPOTLIGHT_UPDATE_EXPONENT;
                        break;
                case GL_SPOT_CUTOFF:
-                       spotlightUpdate = SPOTLIGHT_UPDATE_ALL;
+                       spotlight_update = SPOTLIGHT_UPDATE_ALL;
                        break;
                case GL_CONSTANT_ATTENUATION:
                        BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(p), 1);
@@ -434,13 +504,14 @@ static void nv30Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa
                        break;
        }
 
-       switch(spotlightUpdate) {
+       switch(spotlight_update) {
                case SPOTLIGHT_UPDATE_DIRECTION:
                        {
                                GLfloat x,y,z;
-                               x = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[0];
-                               y = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[1];
-                               z = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[2];
+                               GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0);
+                               x = spot_light_coef_a * l->_NormDirection[0];
+                               y = spot_light_coef_a * l->_NormDirection[1];
+                               z = spot_light_coef_a * l->_NormDirection[2];
                                BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(p), 3);
                                OUT_RING_CACHEf(x);
                                OUT_RING_CACHEf(y);
@@ -462,13 +533,14 @@ static void nv30Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa
                case SPOTLIGHT_UPDATE_ALL:
                        {
                                GLfloat cc,lc,qc, x,y,z, c;
+                               GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0);
                                cc = 1.0;       /* FIXME: These need to be correctly computed */
                                lc = 0.0;
                                qc = 2.0;
-                               x = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[0];
-                               y = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[1];
-                               z = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[2];
-                               c = -2.0 * (0.5 + l->_CosCutoff);
+                               x = spot_light_coef_a * l->_NormDirection[0];
+                               y = spot_light_coef_a * l->_NormDirection[1];
+                               z = spot_light_coef_a * l->_NormDirection[2];
+                               c = spot_light_coef_a + 1.0;
                                BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 7);
                                OUT_RING_CACHEf(cc);
                                OUT_RING_CACHEf(lc);
@@ -500,7 +572,7 @@ static void nv30LineWidth(GLcontext *ctx, GLfloat width)
        nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
        GLubyte ubWidth;
 
-       CLAMPED_FLOAT_TO_UBYTE(ubWidth, width);
+       ubWidth = (GLubyte)(width * 8.0) & 0xFF;
 
        BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LINE_WIDTH_SMOOTH, 1);
        OUT_RING_CACHE(ubWidth);
@@ -567,30 +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);
-       nouveau_renderbuffer *nrb;
-
-       /* Adjust offsets if drawing to a window */
-       nrb = nouveau_current_draw_buffer(ctx);
-       if (nrb && nrb->map) {
-          x += nrb->dPriv->x;
-          y += nrb->dPriv->y;
-       }
+       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 {
+          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 */
@@ -671,36 +758,34 @@ void (*TexParameter)(GLcontext *ctx, GLenum target,
 static void nv30TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat)
 {
         nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
-        BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_TX_MATRIX(unit, 0), 16);
-        /*XXX: This SHOULD work.*/
-        OUT_RING_CACHEp(mat->m, 16);
+
+       if (!NOUVEAU_CARD_USING_SHADERS) {
+               BEGIN_RING_CACHE(NvSub3D,
+                                NV30_TCL_PRIMITIVE_3D_TX_MATRIX(unit, 0), 16);
+               /*XXX: This SHOULD work.*/
+               OUT_RING_CACHEp(mat->m, 16);
+       }
 }
 
 static void nv30WindowMoved(nouveauContextPtr nmesa)
 {
        GLcontext *ctx = nmesa->glCtx;
-       nouveau_renderbuffer *nrb;
        GLfloat *v = nmesa->viewport.m;
-       GLuint w = ctx->Viewport.Width;
-       GLuint h = ctx->Viewport.Height;
-       GLuint x = ctx->Viewport.X;
-       GLuint y = ctx->Viewport.Y;
-
-       /* Adjust offsets if drawing to a window */
-       nrb = nouveau_current_draw_buffer(ctx);
-       if (nrb && nrb->map) {
-          x += nrb->dPriv->x;
-          y += nrb->dPriv->y;
-       }
+       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]);
@@ -718,8 +803,67 @@ static void nv30WindowMoved(nouveauContextPtr nmesa)
 
 static GLboolean nv30InitCard(nouveauContextPtr nmesa)
 {
-       /* Need some love.. */
-       return GL_FALSE;
+       int i;
+       nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D);
+
+       BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT1, 3);
+       OUT_RING(NvDmaFB);
+       OUT_RING(NvDmaTT);
+        OUT_RING(NvDmaFB);
+       BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT8, 1);
+       OUT_RING(NvDmaFB);
+       BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT4, 2);
+       OUT_RING(NvDmaFB);
+       OUT_RING(NvDmaFB);
+        BEGIN_RING_SIZE(NvSub3D, 0x1b0, 1); /* SET_OBJECT8B*/
+        OUT_RING(NvDmaFB);
+
+        for(i = 0x2c8; i <= 0x2fc; i += 4)
+        {
+            BEGIN_RING_SIZE(NvSub3D, i, 1);
+            OUT_RING(0x0);
+        }
+
+       BEGIN_RING_SIZE(NvSub3D, 0x0220, 1);
+       OUT_RING(1);
+
+       BEGIN_RING_SIZE(NvSub3D, 0x03b0, 1);
+       OUT_RING(0x00100000);
+       BEGIN_RING_SIZE(NvSub3D, 0x1454, 1);
+       OUT_RING(0);
+       BEGIN_RING_SIZE(NvSub3D, 0x1d80, 1);
+       OUT_RING(3);
+       
+       /* NEW */
+               BEGIN_RING_SIZE(NvSub3D, 0x1e98, 1);
+        OUT_RING(0);
+        BEGIN_RING_SIZE(NvSub3D, 0x17e0, 3);
+        OUT_RING(0);
+        OUT_RING(0);
+        OUT_RING(0x3f800000);
+        BEGIN_RING_SIZE(NvSub3D, 0x1f80, 16);
+        OUT_RING(0); OUT_RING(0); OUT_RING(0); OUT_RING(0); 
+        OUT_RING(0); OUT_RING(0); OUT_RING(0); OUT_RING(0); 
+        OUT_RING(0x0000ffff);
+        OUT_RING(0); OUT_RING(0); OUT_RING(0); OUT_RING(0); 
+        OUT_RING(0); OUT_RING(0); OUT_RING(0); 
+/*
+        BEGIN_RING_SIZE(NvSub3D, 0x100, 2);
+        OUT_RING(0);
+        OUT_RING(0);
+*/
+        BEGIN_RING_SIZE(NvSub3D, 0x120, 3);
+        OUT_RING(0);
+        OUT_RING(1);
+        OUT_RING(2);
+
+        BEGIN_RING_SIZE(NvSub3D, 0x1d88, 1);
+        OUT_RING(0x00001200);
+
+       BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_RC_ENABLE, 1);
+       OUT_RING       (0);
+
+       return GL_TRUE;
 }
 
 static GLboolean nv40InitCard(nouveauContextPtr nmesa)
@@ -736,51 +880,67 @@ static GLboolean nv40InitCard(nouveauContextPtr nmesa)
        OUT_RING(NvDmaFB);
        BEGIN_RING_SIZE(NvSub3D, 0x0220, 1);
        OUT_RING(1);
+
+       BEGIN_RING_SIZE(NvSub3D, 0x1ea4, 3);
+       OUT_RING(0x00000010);
+       OUT_RING(0x01000100);
+       OUT_RING(0xff800006);
+       BEGIN_RING_SIZE(NvSub3D, 0x1fc4, 1);
+       OUT_RING(0x06144321);
        BEGIN_RING_SIZE(NvSub3D, 0x1fc8, 2);
        OUT_RING(0xedcba987);
        OUT_RING(0x00000021);
-       BEGIN_RING_SIZE(NvSub3D, 0x1d60, 1);
-       OUT_RING(0x03008000);
+       BEGIN_RING_SIZE(NvSub3D, 0x1fd0, 1);
+       OUT_RING(0x00171615);
+       BEGIN_RING_SIZE(NvSub3D, 0x1fd4, 1);
+       OUT_RING(0x001b1a19);
+
+       BEGIN_RING_SIZE(NvSub3D, 0x1ef8, 1);
+       OUT_RING(0x0020ffff);
+       BEGIN_RING_SIZE(NvSub3D, 0x1d64, 1);
+       OUT_RING(0x00d30000);
+       BEGIN_RING_SIZE(NvSub3D, 0x1e94, 1);
+       OUT_RING(0x00000001);
 
        return GL_TRUE;
 }
 
-static GLboolean nv30BindBuffers(nouveauContextPtr nmesa, int num_color,
-                                nouveau_renderbuffer **color,
-                                nouveau_renderbuffer *depth)
-{
-   nouveau_renderbuffer *nrb;
-   GLuint x, y, w, h;
-
-   /* Adjust offsets if drawing to a window */
-   nrb = nouveau_current_draw_buffer(nmesa->glCtx);
-   w = nrb->mesa.Width;
-   h = nrb->mesa.Height;
-   if (nrb && nrb->map) {
-      x = nrb->dPriv->x;
-      y = nrb->dPriv->y;
-   } else {
-      x = 0;
-      y = 0;
-   }
-
-   if (num_color != 1)
-      return GL_FALSE;
-   BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_DIM0, 5);
-   OUT_RING        (((w+x)<<16)|x);
-   OUT_RING        (((h+y)<<16)|y);
-   OUT_RING        (0x148);
-   OUT_RING        (color[0]->pitch);
-   OUT_RING        (color[0]->offset);
-
-   if (depth) {
-      BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_OFFSET, 1);
-      OUT_RING        (depth->offset);
-      BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH, 1);
-      OUT_RING        (depth->pitch);
-   }
-
-   return GL_TRUE;
+static GLboolean
+nv30BindBuffers(nouveauContextPtr nmesa, int num_color,
+               nouveau_renderbuffer_t **color, nouveau_renderbuffer_t *depth)
+{
+       GLuint x, y, w, h;
+
+       w = color[0]->mesa.Width;
+       h = color[0]->mesa.Height;
+       x = nmesa->drawX;
+       y = nmesa->drawY;
+
+       if (num_color != 1)
+               return GL_FALSE;
+       BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_DIM0, 5);
+       OUT_RING        (((w+x)<<16)|x);
+       OUT_RING        (((h+y)<<16)|y);
+       if (color[0]->mesa._ActualFormat == GL_RGBA8)
+               OUT_RING        (0x148);
+       else
+               OUT_RING        (0x143);
+       if (nmesa->screen->card->type >= NV_40)
+               OUT_RING        (color[0]->pitch);
+       else
+               OUT_RING        (color[0]->pitch | (depth ? (depth->pitch << 16): 0));
+       OUT_RING        (color[0]->offset);
+
+       if (depth) {
+               BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_OFFSET, 1);
+               OUT_RING        (depth->offset);
+               if (nmesa->screen->card->type >= NV_40) {
+                       BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH, 1);
+                       OUT_RING        (depth->pitch);
+               }
+       }
+
+       return GL_TRUE;
 }
 
 void nv30InitStateFuncs(GLcontext *ctx, struct dd_function_table *func)
@@ -802,6 +962,7 @@ void nv30InitStateFuncs(GLcontext *ctx, struct dd_function_table *func)
        func->FrontFace                 = nv30FrontFace;
        func->DepthFunc                 = nv30DepthFunc;
        func->DepthMask                 = nv30DepthMask;
+       func->DepthRange                = nv30DepthRange;
        func->Enable                    = nv30Enable;
        func->Fogfv                     = nv30Fogfv;
        func->Hint                      = nv30Hint;