Consolidate texture fetch code and use partial derivatives when possible.
authorBrian <brian.paul@tungstengraphics.com>
Fri, 23 Nov 2007 19:01:57 +0000 (12:01 -0700)
committerBrian <brian.paul@tungstengraphics.com>
Fri, 23 Nov 2007 19:01:57 +0000 (12:01 -0700)
src/mesa/shader/prog_execute.c
src/mesa/shader/prog_execute.h
src/mesa/swrast/s_fragprog.c

index 28d195d0ee95393db885dc8c4a0f73eeea7879fd..00a375078b44e0b59173a87065e4a77b7d65bdb7 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5.3
+ * Version:  7.0.3
  *
  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  *
@@ -46,9 +46,6 @@
 #include "shader/slang/slang_library_noise.h"
 
 
-/* See comments below for info about this */
-#define LAMBDA_ZERO 1
-
 /* debug predicate */
 #define DEBUG_PROG 0
 
@@ -302,6 +299,36 @@ fetch_vector1(const struct prog_src_register *source,
 }
 
 
+/**
+ * Fetch texel from texture.  Use partial derivatives when possible.
+ */
+static INLINE void
+fetch_texel(GLcontext *ctx,
+            const struct gl_program_machine *machine,
+            const struct prog_instruction *inst,
+            const GLfloat texcoord[4], GLfloat lodBias,
+            GLfloat color[4])
+{
+   /* Note: we only have the right derivatives for fragment input attribs.
+    */
+   if (machine->NumDeriv > 0 &&
+       inst->SrcReg[0].File == PROGRAM_INPUT &&
+       inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0 + inst->TexSrcUnit) {
+      /* simple texture fetch for which we should have derivatives */
+      GLuint attr = inst->SrcReg[0].Index;
+      machine->FetchTexelDeriv(ctx, texcoord,
+                               machine->DerivX[attr],
+                               machine->DerivY[attr],
+                               lodBias,
+                               inst->TexSrcUnit, color);
+   }
+   else {
+      machine->FetchTexelLod(ctx, texcoord, lodBias,
+                             inst->TexSrcUnit, color);
+   }
+}
+
+
 /**
  * Test value against zero and return GT, LT, EQ or UN if NaN.
  */
@@ -1306,33 +1333,18 @@ _mesa_execute_program(GLcontext * ctx,
          }
          break;
       case OPCODE_TEX:         /* Both ARB and NV frag prog */
-         /* Texel lookup */
+         /* Simple texel lookup */
          {
-            /* Note: only use the precomputed lambda value when we're
-             * sampling texture unit [K] with texcoord[K].
-             * Otherwise, the lambda value may have no relation to the
-             * instruction's texcoord or texture image.  Using the wrong
-             * lambda is usually bad news.
-             * The rest of the time, just use zero (until we get a more
-             * sophisticated way of computing lambda).
-             */
-            GLfloat coord[4], color[4], lambda;
-#if 0
-            if (inst->SrcReg[0].File == PROGRAM_INPUT &&
-                inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0 + inst->TexSrcUnit)
-               lambda = span->array->lambda[inst->TexSrcUnit][column];
-            else
-#endif
-               lambda = 0.0;
-            fetch_vector4(&inst->SrcReg[0], machine, coord);
-            machine->FetchTexelLod(ctx, coord, lambda, inst->TexSrcUnit,
-                                   color);
+            GLfloat texcoord[4], color[4];
+            fetch_vector4(&inst->SrcReg[0], machine, texcoord);
+
+            fetch_texel(ctx, machine, inst, texcoord, 0.0, color);
+
             if (DEBUG_PROG) {
-               printf("TEX (%g, %g, %g, %g) = texture[%d][%g, %g, %g, %g], "
-                      "lod %f\n",
+               printf("TEX (%g, %g, %g, %g) = texture[%d][%g, %g, %g, %g]\n",
                       color[0], color[1], color[2], color[3],
                       inst->TexSrcUnit,
-                      coord[0], coord[1], coord[2], coord[3], lambda);
+                      texcoord[0], texcoord[1], texcoord[2], texcoord[3]);
             }
             store_vector4(inst, machine, color);
          }
@@ -1342,21 +1354,18 @@ _mesa_execute_program(GLcontext * ctx,
          {
             const struct gl_texture_unit *texUnit
                = &ctx->Texture.Unit[inst->TexSrcUnit];
-            GLfloat coord[4], color[4], lambda, bias;
-#if 0
-            if (inst->SrcReg[0].File == PROGRAM_INPUT &&
-                inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0 + inst->TexSrcUnit)
-               lambda = span->array->lambda[inst->TexSrcUnit][column];
-            else
-#endif
-               lambda = 0.0;
-            fetch_vector4(&inst->SrcReg[0], machine, coord);
-            /* coord[3] is the bias to add to lambda */
-            bias = texUnit->LodBias + coord[3];
-            if (texUnit->_Current)
-               bias += texUnit->_Current->LodBias;
-            machine->FetchTexelLod(ctx, coord, lambda + bias,
-                                   inst->TexSrcUnit, color);
+            GLfloat texcoord[4], color[4], lodBias;
+
+            fetch_vector4(&inst->SrcReg[0], machine, texcoord);
+
+            /* texcoord[3] is the bias to add to lambda */
+            lodBias = texUnit->LodBias + texcoord[3];
+            if (texUnit->_Current) {
+               lodBias += texUnit->_Current->LodBias;
+            }
+
+            fetch_texel(ctx, machine, inst, texcoord, lodBias, color);
+
             store_vector4(inst, machine, color);
          }
          break;
@@ -1368,6 +1377,7 @@ _mesa_execute_program(GLcontext * ctx,
             fetch_vector4(&inst->SrcReg[1], machine, dtdx);
             fetch_vector4(&inst->SrcReg[2], machine, dtdy);
             machine->FetchTexelDeriv(ctx, texcoord, dtdx, dtdy,
+                                     0.0, /* lodBias */
                                      inst->TexSrcUnit, color);
             store_vector4(inst, machine, color);
          }
@@ -1375,14 +1385,8 @@ _mesa_execute_program(GLcontext * ctx,
       case OPCODE_TXP:         /* GL_ARB_fragment_program only */
          /* Texture lookup w/ projective divide */
          {
-            GLfloat texcoord[4], color[4], lambda;
-#if 0
-            if (inst->SrcReg[0].File == PROGRAM_INPUT &&
-                inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0 + inst->TexSrcUnit)
-               lambda = span->array->lambda[inst->TexSrcUnit][column];
-            else
-#endif
-               lambda = 0.0;
+            GLfloat texcoord[4], color[4];
+
             fetch_vector4(&inst->SrcReg[0], machine, texcoord);
             /* Not so sure about this test - if texcoord[3] is
              * zero, we'd probably be fine except for an ASSERT in
@@ -1393,22 +1397,19 @@ _mesa_execute_program(GLcontext * ctx,
                texcoord[1] /= texcoord[3];
                texcoord[2] /= texcoord[3];
             }
-            machine->FetchTexelLod(ctx, texcoord, lambda,
-                                   inst->TexSrcUnit, color);
+
+            fetch_texel(ctx, machine, inst, texcoord, 0.0, color);
+
             store_vector4(inst, machine, color);
          }
          break;
       case OPCODE_TXP_NV:      /* GL_NV_fragment_program only */
-         /* Texture lookup w/ projective divide */
+         /* Texture lookup w/ projective divide, as above, but do not
+          * do the divide by w if sampling from a cube map.
+          */
          {
-            GLfloat texcoord[4], color[4], lambda;
-#if 0
-            if (inst->SrcReg[0].File == PROGRAM_INPUT &&
-                inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0 + inst->TexSrcUnit)
-               lambda = span->array->lambda[inst->TexSrcUnit][column];
-            else
-#endif
-               lambda = 0.0;
+            GLfloat texcoord[4], color[4];
+
             fetch_vector4(&inst->SrcReg[0], machine, texcoord);
             if (inst->TexSrcTarget != TEXTURE_CUBE_INDEX &&
                 texcoord[3] != 0.0) {
@@ -1416,8 +1417,9 @@ _mesa_execute_program(GLcontext * ctx,
                texcoord[1] /= texcoord[3];
                texcoord[2] /= texcoord[3];
             }
-            machine->FetchTexelLod(ctx, texcoord, lambda,
-                                   inst->TexSrcUnit, color);
+
+            fetch_texel(ctx, machine, inst, texcoord, 0.0, color);
+
             store_vector4(inst, machine, color);
          }
          break;
index be29eceedaa442e2d965836eb736241e45a93fd7..3ea0ba1565c645c399029b220e9cd620f4321ef5 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5.3
+ * Version:  7.0.3
  *
  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  *
@@ -32,6 +32,7 @@ typedef void (*FetchTexelLodFunc)(GLcontext *ctx, const GLfloat texcoord[4],
 typedef void (*FetchTexelDerivFunc)(GLcontext *ctx, const GLfloat texcoord[4],
                                     const GLfloat texdx[4],
                                     const GLfloat texdy[4],
+                                    GLfloat lodBias,
                                     GLuint unit, GLfloat color[4]);
 
 
index 474aab3aa266a0ced96d95a6166e887c9c3c9f8a..4067fd688674a6a23d2feb503db056dab77a97df 100644 (file)
@@ -46,8 +46,7 @@ fetch_texel( GLcontext *ctx, const GLfloat texcoord[4], GLfloat lambda,
    lambda = CLAMP(lambda, texObj->MinLod, texObj->MaxLod);
  
    /* XXX use a float-valued TextureSample routine here!!! */
-   swrast->TextureSample[unit](ctx, texObj,
-                               1, (const GLfloat (*)[4]) texcoord,
+   swrast->TextureSample[unit](ctx, texObj, 1, (const GLfloat (*)[4]) texcoord,
                                &lambda, &rgba);
    color[0] = CHAN_TO_FLOAT(rgba[0]);
    color[1] = CHAN_TO_FLOAT(rgba[1]);
@@ -63,7 +62,7 @@ fetch_texel( GLcontext *ctx, const GLfloat texcoord[4], GLfloat lambda,
 static void
 fetch_texel_deriv( GLcontext *ctx, const GLfloat texcoord[4],
                    const GLfloat texdx[4], const GLfloat texdy[4],
-                   GLuint unit, GLfloat color[4] )
+                   GLfloat lodBias, GLuint unit, GLfloat color[4] )
 {
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    const struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current;
@@ -72,15 +71,17 @@ fetch_texel_deriv( GLcontext *ctx, const GLfloat texcoord[4],
    const GLfloat texH = (GLfloat) texImg->HeightScale;
    GLchan rgba[4];
 
-   GLfloat lambda = _swrast_compute_lambda(texdx[0], texdy[0], /* ds/dx, ds/dy */
-                                         texdx[1], texdy[1], /* dt/dx, dt/dy */
-                                         texdx[3], texdy[2], /* dq/dx, dq/dy */
-                                         texW, texH,
-                                         texcoord[0], texcoord[1], texcoord[3],
-                                         1.0F / texcoord[3]);
+   GLfloat lambda
+      = _swrast_compute_lambda(texdx[0], texdy[0], /* ds/dx, ds/dy */
+                               texdx[1], texdy[1], /* dt/dx, dt/dy */
+                               texdx[3], texdy[2], /* dq/dx, dq/dy */
+                               texW, texH,
+                               texcoord[0], texcoord[1], texcoord[3],
+                               1.0F / texcoord[3]) + lodBias;
 
-   swrast->TextureSample[unit](ctx, ctx->Texture.Unit[unit]._Current,
-                               1, (const GLfloat (*)[4]) texcoord,
+   lambda = CLAMP(lambda, texObj->MinLod, texObj->MaxLod);
+
+   swrast->TextureSample[unit](ctx, texObj, 1, (const GLfloat (*)[4]) texcoord,
                                &lambda, &rgba);
    color[0] = CHAN_TO_FLOAT(rgba[0]);
    color[1] = CHAN_TO_FLOAT(rgba[1]);