Always convert colors to float before running a fragment shader/program.
authorBrian Paul <brian.paul@tungstengraphics.com>
Tue, 17 Oct 2006 22:23:32 +0000 (22:23 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Tue, 17 Oct 2006 22:23:32 +0000 (22:23 +0000)
src/mesa/swrast/s_arbshader.c
src/mesa/swrast/s_atifragshader.c
src/mesa/swrast/s_nvfragprog.c
src/mesa/swrast/s_span.c

index eeb5cd97ec19e16874d2df0fa1a83ac31cbf3982..9e41d7c673d2b6f2b6f250a533ae0e5de1263924 100644 (file)
@@ -43,6 +43,8 @@ _swrast_exec_arbshader(GLcontext *ctx, SWspan *span)
    struct gl2_program_intf **pro;
    GLuint i;
 
+   ASSERT(span->array->ChanType == GL_FLOAT);
+
    if (!ctx->ShaderObjects._FragmentShaderPresent)
       return;
 
@@ -57,6 +59,9 @@ _swrast_exec_arbshader(GLcontext *ctx, SWspan *span)
          GLuint j;
          GLboolean discard;
 
+         /*
+          * Load input attributes
+          */
          vec[0] = (GLfloat) span->x + i;
          vec[1] = (GLfloat) span->y;
          vec[2] = (GLfloat) span->array->z[i] / ctx->DrawBuffer->_DepthMaxF;
@@ -64,32 +69,22 @@ _swrast_exec_arbshader(GLcontext *ctx, SWspan *span)
          (**pro).UpdateFixedVarying(pro, SLANG_FRAGMENT_FIXED_FRAGCOORD, vec,
                                     0, 4 * sizeof(GLfloat), GL_TRUE);
 
-         vec[0] = CHAN_TO_FLOAT(span->array->rgba[i][RCOMP]);
-         vec[1] = CHAN_TO_FLOAT(span->array->rgba[i][GCOMP]);
-         vec[2] = CHAN_TO_FLOAT(span->array->rgba[i][BCOMP]);
-         vec[3] = CHAN_TO_FLOAT(span->array->rgba[i][ACOMP]);
-         (**pro).UpdateFixedVarying(pro, SLANG_FRAGMENT_FIXED_COLOR, vec, 0,
-                                    4 * sizeof(GLfloat), GL_TRUE);
-
-         vec[0] = CHAN_TO_FLOAT(span->array->spec[i][RCOMP]);
-         vec[1] = CHAN_TO_FLOAT(span->array->spec[i][GCOMP]);
-         vec[2] = CHAN_TO_FLOAT(span->array->spec[i][BCOMP]);
-         vec[3] = CHAN_TO_FLOAT(span->array->spec[i][ACOMP]);
+         (**pro).UpdateFixedVarying(pro, SLANG_FRAGMENT_FIXED_COLOR,
+                                    span->array->color.sz4.rgba[i],
+                                    0, 4 * sizeof(GLfloat), GL_TRUE);
+
          (**pro).UpdateFixedVarying(pro, SLANG_FRAGMENT_FIXED_SECONDARYCOLOR,
-                                    vec, 0, 4 * sizeof(GLfloat), GL_TRUE);
+                                    span->array->color.sz4.spec[i],
+                                    0, 4 * sizeof(GLfloat), GL_TRUE);
 
          for (j = 0; j < ctx->Const.MaxTextureCoordUnits; j++) {
-            vec[0] = span->array->texcoords[j][i][0];
-            vec[1] = span->array->texcoords[j][i][1];
-            vec[2] = span->array->texcoords[j][i][2];
-            vec[3] = span->array->texcoords[j][i][3];
             (**pro).UpdateFixedVarying(pro, SLANG_FRAGMENT_FIXED_TEXCOORD,
-                                       vec, j, 4 * sizeof(GLfloat), GL_TRUE);
+                                       span->array->texcoords[j][i],
+                                       j, 4 * sizeof(GLfloat), GL_TRUE);
          }
 
          for (j = 0; j < MAX_VARYING_VECTORS; j++) {
             GLuint k;
-
             for (k = 0; k < VARYINGS_PER_VECTOR; k++) {
                (**pro).UpdateVarying(pro, j * VARYINGS_PER_VECTOR + k,
                                      &span->array->varying[i][j][k],
@@ -99,6 +94,9 @@ _swrast_exec_arbshader(GLcontext *ctx, SWspan *span)
 
          _slang_exec_fragment_shader(pro);
 
+         /*
+          * Store results
+          */
          _slang_fetch_discard(pro, &discard);
          if (discard) {
             span->array->mask[i] = GL_FALSE;
@@ -107,10 +105,7 @@ _swrast_exec_arbshader(GLcontext *ctx, SWspan *span)
          else {
             (**pro).UpdateFixedVarying(pro, SLANG_FRAGMENT_FIXED_FRAGCOLOR,
                                        vec, 0, 4 * sizeof(GLfloat), GL_FALSE);
-            UNCLAMPED_FLOAT_TO_CHAN(span->array->rgba[i][RCOMP], vec[0]);
-            UNCLAMPED_FLOAT_TO_CHAN(span->array->rgba[i][GCOMP], vec[1]);
-            UNCLAMPED_FLOAT_TO_CHAN(span->array->rgba[i][BCOMP], vec[2]);
-            UNCLAMPED_FLOAT_TO_CHAN(span->array->rgba[i][ACOMP], vec[3]);
+            COPY_4V(span->array->color.sz4.rgba[i], vec);
          }
       }
    }
index 03f7a9db230fcaba366f12f8d092bee45feea95c..f195b6ee55981f173af91d0fb20564bd43142232 100644 (file)
@@ -574,36 +574,8 @@ init_machine(GLcontext * ctx, struct atifs_machine *machine,
         machine->Registers[i][j] = 0.0;
    }
 
-   if (span->array->ChanType == GL_UNSIGNED_BYTE) {
-      GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
-      GLubyte (*spec)[4] = span->array->color.sz1.spec;
-      inputs[ATI_FS_INPUT_PRIMARY][0] = UBYTE_TO_FLOAT(rgba[col][0]);
-      inputs[ATI_FS_INPUT_PRIMARY][1] = UBYTE_TO_FLOAT(rgba[col][1]);
-      inputs[ATI_FS_INPUT_PRIMARY][2] = UBYTE_TO_FLOAT(rgba[col][2]);
-      inputs[ATI_FS_INPUT_PRIMARY][3] = UBYTE_TO_FLOAT(rgba[col][3]); 
-      inputs[ATI_FS_INPUT_SECONDARY][0] = UBYTE_TO_FLOAT(spec[col][0]);
-      inputs[ATI_FS_INPUT_SECONDARY][1] = UBYTE_TO_FLOAT(spec[col][1]);
-      inputs[ATI_FS_INPUT_SECONDARY][2] = UBYTE_TO_FLOAT(spec[col][2]);
-      inputs[ATI_FS_INPUT_SECONDARY][3] = UBYTE_TO_FLOAT(spec[col][3]);
-  }
-   else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
-      GLushort (*rgba)[4] = span->array->color.sz2.rgba;
-      GLushort (*spec)[4] = span->array->color.sz2.spec;
-      inputs[ATI_FS_INPUT_PRIMARY][0] = USHORT_TO_FLOAT(rgba[col][0]);
-      inputs[ATI_FS_INPUT_PRIMARY][1] = USHORT_TO_FLOAT(rgba[col][1]);
-      inputs[ATI_FS_INPUT_PRIMARY][2] = USHORT_TO_FLOAT(rgba[col][2]);
-      inputs[ATI_FS_INPUT_PRIMARY][3] = USHORT_TO_FLOAT(rgba[col][3]);
-      inputs[ATI_FS_INPUT_SECONDARY][0] = USHORT_TO_FLOAT(spec[col][0]);
-      inputs[ATI_FS_INPUT_SECONDARY][1] = USHORT_TO_FLOAT(spec[col][1]);
-      inputs[ATI_FS_INPUT_SECONDARY][2] = USHORT_TO_FLOAT(spec[col][2]);
-      inputs[ATI_FS_INPUT_SECONDARY][3] = USHORT_TO_FLOAT(spec[col][3]);
-   }
-   else {
-      GLfloat (*rgba)[4] = span->array->color.sz4.rgba;
-      GLfloat (*spec)[4] = span->array->color.sz4.spec;
-      COPY_4V(inputs[ATI_FS_INPUT_PRIMARY], rgba[col]);
-      COPY_4V(inputs[ATI_FS_INPUT_SECONDARY], spec[col]);
-   }
+   COPY_4V(inputs[ATI_FS_INPUT_PRIMARY], span->array->color.sz4.rgba[col]);
+   COPY_4V(inputs[ATI_FS_INPUT_SECONDARY], span->array->color.sz4.spec[col]);
 }
 
 
@@ -618,6 +590,9 @@ _swrast_exec_fragment_shader(GLcontext * ctx, SWspan *span)
    struct atifs_machine machine;
    GLuint i;
 
+   /* incoming colors should be floats */
+   ASSERT(span->array->ChanType == GL_FLOAT);
+
    ctx->_CurrentProgram = GL_FRAGMENT_SHADER_ATI;
 
    for (i = 0; i < span->end; i++) {
@@ -632,26 +607,9 @@ _swrast_exec_fragment_shader(GLcontext * ctx, SWspan *span)
          /* store result color */
         {
            const GLfloat *colOut = machine.Registers[0];
-           /*fprintf(stderr,"outputs %f %f %f %f\n",
+            /*fprintf(stderr,"outputs %f %f %f %f\n",
               colOut[0], colOut[1], colOut[2], colOut[3]); */
-            if (span->array->ChanType == GL_UNSIGNED_BYTE) {
-               GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
-               UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][RCOMP], colOut[0]);
-               UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][GCOMP], colOut[1]);
-               UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][BCOMP], colOut[2]);
-               UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][ACOMP], colOut[3]);
-            }
-            else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
-               GLushort (*rgba)[4] = span->array->color.sz2.rgba;
-               UNCLAMPED_FLOAT_TO_USHORT(rgba[i][RCOMP], colOut[0]);
-               UNCLAMPED_FLOAT_TO_USHORT(rgba[i][GCOMP], colOut[1]);
-               UNCLAMPED_FLOAT_TO_USHORT(rgba[i][BCOMP], colOut[2]);
-               UNCLAMPED_FLOAT_TO_USHORT(rgba[i][ACOMP], colOut[3]);
-            }
-            else {
-               GLfloat (*rgba)[4] = span->array->color.sz4.rgba;
-               COPY_4V(rgba[i], colOut);
-            }
+            COPY_4V(span->array->color.sz4.rgba[i], colOut);
         }
       }
    }
index 3dc9fdde6f9dd543cfdb0b99296f47cf22268ee7..20fbd5060b91c422795ac71233e6d8af1e9bb544 100644 (file)
@@ -1466,47 +1466,14 @@ init_machine( GLcontext *ctx, struct fp_machine *machine,
       wpos[3] = span->w + col * span->dwdx;
    }
    if (inputsRead & (1 << FRAG_ATTRIB_COL0)) {
-      GLfloat *col0 = machine->Inputs[FRAG_ATTRIB_COL0];
       ASSERT(span->arrayMask & SPAN_RGBA);
-      if (span->array->ChanType == GL_UNSIGNED_BYTE) {
-         GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
-         col0[0] = UBYTE_TO_FLOAT(rgba[col][RCOMP]);
-         col0[1] = UBYTE_TO_FLOAT(rgba[col][GCOMP]);
-         col0[2] = UBYTE_TO_FLOAT(rgba[col][BCOMP]);
-         col0[3] = UBYTE_TO_FLOAT(rgba[col][ACOMP]);
-      }
-      else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
-         GLushort (*rgba)[4] = span->array->color.sz2.rgba;
-         col0[0] = USHORT_TO_FLOAT(rgba[col][RCOMP]);
-         col0[1] = USHORT_TO_FLOAT(rgba[col][GCOMP]);
-         col0[2] = USHORT_TO_FLOAT(rgba[col][BCOMP]);
-         col0[3] = USHORT_TO_FLOAT(rgba[col][ACOMP]);
-      }
-      else {
-         GLfloat (*rgba)[4] = span->array->color.sz4.rgba;
-         COPY_4V(col0, rgba[col]);
-      }
+      COPY_4V(machine->Inputs[FRAG_ATTRIB_COL0],
+              span->array->color.sz4.rgba[col]);
    }
    if (inputsRead & (1 << FRAG_ATTRIB_COL1)) {
-      GLfloat *col1 = machine->Inputs[FRAG_ATTRIB_COL1];
-      if (span->array->ChanType == GL_UNSIGNED_BYTE) {
-         GLubyte (*rgba)[4] = span->array->color.sz1.spec;
-         col1[0] = UBYTE_TO_FLOAT(rgba[col][RCOMP]);
-         col1[1] = UBYTE_TO_FLOAT(rgba[col][GCOMP]);
-         col1[2] = UBYTE_TO_FLOAT(rgba[col][BCOMP]);
-         col1[3] = UBYTE_TO_FLOAT(rgba[col][ACOMP]);
-      }
-      else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
-         GLushort (*rgba)[4] = span->array->color.sz2.spec;
-         col1[0] = USHORT_TO_FLOAT(rgba[col][RCOMP]);
-         col1[1] = USHORT_TO_FLOAT(rgba[col][GCOMP]);
-         col1[2] = USHORT_TO_FLOAT(rgba[col][BCOMP]);
-         col1[3] = USHORT_TO_FLOAT(rgba[col][ACOMP]);
-      }
-      else {
-         GLfloat (*rgba)[4] = span->array->color.sz4.spec;
-         COPY_4V(col1, rgba[col]);
-      }
+      ASSERT(span->arrayMask & SPAN_SPEC);
+      COPY_4V(machine->Inputs[FRAG_ATTRIB_COL1],
+              span->array->color.sz4.spec[col]);
    }
    if (inputsRead & (1 << FRAG_ATTRIB_FOGC)) {
       GLfloat *fogc = machine->Inputs[FRAG_ATTRIB_FOGC];
@@ -1554,29 +1521,11 @@ run_program(GLcontext *ctx, SWspan *span, GLuint start, GLuint end)
             span->writeAll = GL_FALSE;
          }
 
-         /* Store output registers */
-         {
-            const GLfloat *colOut = machine.Outputs[FRAG_RESULT_COLR];
-            if (span->array->ChanType == GL_UNSIGNED_BYTE) {
-               GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
-               UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][RCOMP], colOut[0]);
-               UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][GCOMP], colOut[1]);
-               UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][BCOMP], colOut[2]);
-               UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][ACOMP], colOut[3]);
-            }
-            else if (span->array->ChanType == GL_UNSIGNED_BYTE) {
-               GLushort (*rgba)[4] = span->array->color.sz2.rgba;
-               UNCLAMPED_FLOAT_TO_USHORT(rgba[i][RCOMP], colOut[0]);
-               UNCLAMPED_FLOAT_TO_USHORT(rgba[i][GCOMP], colOut[1]);
-               UNCLAMPED_FLOAT_TO_USHORT(rgba[i][BCOMP], colOut[2]);
-               UNCLAMPED_FLOAT_TO_USHORT(rgba[i][ACOMP], colOut[3]);
-            }
-            else {
-               GLfloat (*rgba)[4] = span->array->color.sz4.rgba;
-               COPY_4V(rgba[i], colOut);
-            }
-         }
-         /* depth value */
+         /* Store result color */
+         COPY_4V(span->array->color.sz4.rgba[i],
+                 machine.Outputs[FRAG_RESULT_COLR]);
+
+         /* Store result depth/z */
          if (program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) {
             const GLfloat depth = machine.Outputs[FRAG_RESULT_DEPR][2];
             if (depth <= 0.0)
@@ -1602,6 +1551,9 @@ _swrast_exec_fragment_program( GLcontext *ctx, SWspan *span )
 {
    const struct gl_fragment_program *program = ctx->FragmentProgram._Current;
 
+   /* incoming colors should be floats */
+   ASSERT(span->array->ChanType == GL_FLOAT);
+
    ctx->_CurrentProgram = GL_FRAGMENT_PROGRAM_ARB; /* or NV, doesn't matter */
 
    if (program->Base.Parameters) {
index cba867cf0a8010ea3b52d06217e6877971bbca09..040058fe86692e8f07f8ec5e0108a6fcca13636b 100644 (file)
@@ -1316,6 +1316,7 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    const GLbitfield origInterpMask = span->interpMask;
    const GLbitfield origArrayMask = span->arrayMask;
+   const GLenum chanType = span->array->ChanType;
    const GLboolean deferredTexture = !(ctx->Color.AlphaEnabled ||
                                        ctx->FragmentProgram._Enabled ||
                                        ctx->ShaderObjects._FragmentShaderPresent);
@@ -1393,6 +1394,23 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
       if (span->interpMask & SPAN_FOG)
          interpolate_fog(ctx, span);
 
+      /* use float colors if running a fragment program or shader */
+      if (ctx->ShaderObjects._FragmentShaderPresent ||
+          ctx->FragmentProgram._Enabled ||
+          ctx->ATIFragmentShader._Enabled) {
+         const GLenum oldType = span->array->ChanType;
+         /* work with float colors */
+         if (oldType != GL_FLOAT) {
+            GLvoid *src = (oldType == GL_UNSIGNED_BYTE)
+               ? (GLvoid *) span->array->color.sz1.rgba
+               : (GLvoid *) span->array->color.sz2.rgba;
+            _mesa_convert_colors(oldType, src,
+                                 GL_FLOAT, span->array->color.sz4.rgba,
+                                 span->end, span->array->mask);
+            span->array->ChanType = GL_FLOAT;
+         }
+      }
+
       /* Compute fragment colors with fragment program or texture lookups */
 #if FEATURE_ARB_fragment_shader
       if (ctx->ShaderObjects._FragmentShaderPresent) {
@@ -1416,8 +1434,7 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
       /* Do the alpha test */
       if (ctx->Color.AlphaEnabled) {
          if (!_swrast_alpha_test(ctx, span)) {
-            span->arrayMask = origArrayMask;
-           return;
+            goto end;
         }
       }
    }
@@ -1430,9 +1447,7 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
       if (ctx->Stencil.Enabled && ctx->DrawBuffer->Visual.stencilBits > 0) {
          /* Combined Z/stencil tests */
          if (!_swrast_stencil_and_ztest_span(ctx, span)) {
-            span->interpMask = origInterpMask;
-            span->arrayMask = origArrayMask;
-            return;
+            goto end;
          }
       }
       else if (ctx->DrawBuffer->Visual.depthBits > 0) {
@@ -1440,9 +1455,7 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
          ASSERT(ctx->Depth.Test);
          ASSERT(span->arrayMask & SPAN_Z);
          if (!_swrast_depth_test_span(ctx, span)) {
-            span->interpMask = origInterpMask;
-            span->arrayMask = origArrayMask;
-            return;
+            goto end;
          }
       }
    }
@@ -1461,9 +1474,7 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
     * the occlusion test.
     */
    if (colorMask == 0x0) {
-      span->interpMask = origInterpMask;
-      span->arrayMask = origArrayMask;
-      return;
+      goto end;
    }
 
    /* If we were able to defer fragment color computation to now, there's
@@ -1551,7 +1562,6 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
       const GLuint numDrawBuffers = fb->_NumColorDrawBuffers[output];
       GLchan rgbaSave[MAX_WIDTH][4];
       GLuint buf;
-      const GLenum chanType = span->array->ChanType; /* save */
 
       if (numDrawBuffers > 0) {
          if (fb->_ColorDrawBuffers[output][0]->DataType
@@ -1603,11 +1613,12 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
          }
       } /* for buf */
 
-      span->array->ChanType = chanType; /* restore */
    }
 
+end:
    span->interpMask = origInterpMask;
    span->arrayMask = origArrayMask;
+   span->array->ChanType = chanType; /* restore */
 }