diff options
Diffstat (limited to 'src/mesa/swrast/s_span.c')
-rw-r--r-- | src/mesa/swrast/s_span.c | 466 |
1 files changed, 359 insertions, 107 deletions
diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index 72b14ebf3af..8c4ee3e9099 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -149,62 +149,218 @@ _swrast_span_default_texcoords( GLcontext *ctx, struct sw_span *span ) } -/* Fill in the span.color.rgba array from the interpolation values */ +/** + * Interpolate colors to fill in the span->array->color array. + * \param specular if true, interpolate specular, else interpolate rgba. + */ static void -interpolate_colors(GLcontext *ctx, struct sw_span *span) +interpolate_colors(GLcontext *ctx, struct sw_span *span, GLboolean specular) { const GLuint n = span->end; - GLchan (*rgba)[4] = span->array->rgba; GLuint i; (void) ctx; - ASSERT((span->interpMask & SPAN_RGBA) && - !(span->arrayMask & SPAN_RGBA)); + if (!specular) { + ASSERT((span->interpMask & SPAN_RGBA) && + !(span->arrayMask & SPAN_RGBA)); + } if (span->interpMask & SPAN_FLAT) { /* constant color */ - GLchan color[4]; - color[RCOMP] = FixedToChan(span->red); - color[GCOMP] = FixedToChan(span->green); - color[BCOMP] = FixedToChan(span->blue); - color[ACOMP] = FixedToChan(span->alpha); - for (i = 0; i < n; i++) { - COPY_CHAN4(span->array->rgba[i], color); + switch (span->array->ChanType) { + case GL_UNSIGNED_BYTE: + { + GLubyte (*rgba)[4] = specular + ? span->array->color.sz1.spec : span->array->color.sz1.rgba; + GLubyte color[4]; + if (specular) { + color[RCOMP] = FixedToInt(span->specRed); + color[GCOMP] = FixedToInt(span->specGreen); + color[BCOMP] = FixedToInt(span->specBlue); + color[ACOMP] = 0; + } + else { + color[RCOMP] = FixedToInt(span->red); + color[GCOMP] = FixedToInt(span->green); + color[BCOMP] = FixedToInt(span->blue); + color[ACOMP] = FixedToInt(span->alpha); + } + for (i = 0; i < n; i++) { + COPY_4UBV(rgba[i], color); + } + } + break; + case GL_UNSIGNED_SHORT: + { + GLushort (*rgba)[4] = specular + ? span->array->color.sz2.spec : span->array->color.sz2.rgba; + GLushort color[4]; + if (specular) { + color[RCOMP] = FixedToInt(span->specRed); + color[GCOMP] = FixedToInt(span->specGreen); + color[BCOMP] = FixedToInt(span->specBlue); + color[ACOMP] = 0; + } + else { + color[RCOMP] = FixedToInt(span->red); + color[GCOMP] = FixedToInt(span->green); + color[BCOMP] = FixedToInt(span->blue); + color[ACOMP] = FixedToInt(span->alpha); + } + for (i = 0; i < n; i++) { + COPY_4V(rgba[i], color); + } + } + break; + case GL_FLOAT: + { + GLfloat (*rgba)[4] = specular ? + span->array->color.sz4.spec : span->array->color.sz4.rgba; + GLfloat color[4]; + ASSERT(CHAN_TYPE == GL_FLOAT); + if (specular) { + color[RCOMP] = span->specRed; + color[GCOMP] = span->specGreen; + color[BCOMP] = span->specBlue; + color[ACOMP] = 0.0F; + } + else { + color[RCOMP] = span->red; + color[GCOMP] = span->green; + color[BCOMP] = span->blue; + color[ACOMP] = span->alpha; + } + for (i = 0; i < n; i++) { + COPY_4V(rgba[i], color); + } + } + break; + default: + _mesa_problem(ctx, "bad datatype in interpolate_colors"); } } else { /* interpolate */ -#if CHAN_TYPE == GL_FLOAT - GLfloat r = span->red; - GLfloat g = span->green; - GLfloat b = span->blue; - GLfloat a = span->alpha; - const GLfloat dr = span->redStep; - const GLfloat dg = span->greenStep; - const GLfloat db = span->blueStep; - const GLfloat da = span->alphaStep; -#else - GLfixed r = span->red; - GLfixed g = span->green; - GLfixed b = span->blue; - GLfixed a = span->alpha; - const GLint dr = span->redStep; - const GLint dg = span->greenStep; - const GLint db = span->blueStep; - const GLint da = span->alphaStep; -#endif - for (i = 0; i < n; i++) { - rgba[i][RCOMP] = FixedToChan(r); - rgba[i][GCOMP] = FixedToChan(g); - rgba[i][BCOMP] = FixedToChan(b); - rgba[i][ACOMP] = FixedToChan(a); - r += dr; - g += dg; - b += db; - a += da; + switch (span->array->ChanType) { + case GL_UNSIGNED_BYTE: + { + GLubyte (*rgba)[4] = specular + ? span->array->color.sz1.spec : span->array->color.sz1.rgba; + GLfixed r, g, b, a; + GLint dr, dg, db, da; + if (specular) { + r = span->specRed; + g = span->specGreen; + b = span->specBlue; + a = 0; + dr = span->specRedStep; + dg = span->specGreenStep; + db = span->specBlueStep; + da = 0; + } + else { + r = span->red; + g = span->green; + b = span->blue; + a = span->alpha; + dr = span->redStep; + dg = span->greenStep; + db = span->blueStep; + da = span->alphaStep; + } + for (i = 0; i < n; i++) { + rgba[i][RCOMP] = FixedToChan(r); + rgba[i][GCOMP] = FixedToChan(g); + rgba[i][BCOMP] = FixedToChan(b); + rgba[i][ACOMP] = FixedToChan(a); + r += dr; + g += dg; + b += db; + a += da; + } + } + break; + case GL_UNSIGNED_SHORT: + { + GLushort (*rgba)[4] = specular + ? span->array->color.sz2.spec : span->array->color.sz2.rgba; + GLfixed r, g, b, a; + GLint dr, dg, db, da; + if (specular) { + r = span->specRed; + g = span->specGreen; + b = span->specBlue; + a = 0; + dr = span->specRedStep; + dg = span->specGreenStep; + db = span->specBlueStep; + da = 0; + } + else { + r = span->red; + g = span->green; + b = span->blue; + a = span->alpha; + dr = span->redStep; + dg = span->greenStep; + db = span->blueStep; + da = span->alphaStep; + } + for (i = 0; i < n; i++) { + rgba[i][RCOMP] = FixedToChan(r); + rgba[i][GCOMP] = FixedToChan(g); + rgba[i][BCOMP] = FixedToChan(b); + rgba[i][ACOMP] = FixedToChan(a); + r += dr; + g += dg; + b += db; + a += da; + } + } + break; + case GL_FLOAT: + { + GLfloat (*rgba)[4] = specular ? + span->array->color.sz4.spec : span->array->color.sz4.rgba; + GLfloat r, g, b, a, dr, dg, db, da; + if (specular) { + r = span->specRed; + g = span->specGreen; + b = span->specBlue; + a = 0.0F; + dr = span->specRedStep; + dg = span->specGreenStep; + db = span->specBlueStep; + da = 0.0F; + } + else { + r = span->red; + g = span->green; + b = span->blue; + a = span->alpha; + dr = span->redStep; + dg = span->greenStep; + db = span->blueStep; + da = span->alphaStep; + } + ASSERT(CHAN_TYPE == GL_FLOAT); + for (i = 0; i < n; i++) { + rgba[i][RCOMP] = r; + rgba[i][GCOMP] = g; + rgba[i][BCOMP] = b; + rgba[i][ACOMP] = a; + r += dr; + g += dg; + b += db; + a += da; + } + } + break; + default: + _mesa_problem(ctx, "bad datatype in interpolate_colors"); } } - span->arrayMask |= SPAN_RGBA; + span->arrayMask |= (specular ? SPAN_SPEC : SPAN_RGBA); } @@ -240,48 +396,6 @@ interpolate_indexes(GLcontext *ctx, struct sw_span *span) } -/* Fill in the span.->array->spec array from the interpolation values */ -static void -interpolate_specular(GLcontext *ctx, struct sw_span *span) -{ - (void) ctx; - if (span->interpMask & SPAN_FLAT) { - /* constant color */ - const GLchan r = FixedToChan(span->specRed); - const GLchan g = FixedToChan(span->specGreen); - const GLchan b = FixedToChan(span->specBlue); - GLuint i; - for (i = 0; i < span->end; i++) { - span->array->spec[i][RCOMP] = r; - span->array->spec[i][GCOMP] = g; - span->array->spec[i][BCOMP] = b; - } - } - else { - /* interpolate */ -#if CHAN_TYPE == GL_FLOAT - GLfloat r = span->specRed; - GLfloat g = span->specGreen; - GLfloat b = span->specBlue; -#else - GLfixed r = span->specRed; - GLfixed g = span->specGreen; - GLfixed b = span->specBlue; -#endif - GLuint i; - for (i = 0; i < span->end; i++) { - span->array->spec[i][RCOMP] = FixedToChan(r); - span->array->spec[i][GCOMP] = FixedToChan(g); - span->array->spec[i][BCOMP] = FixedToChan(b); - r += span->specRedStep; - g += span->specGreenStep; - b += span->specBlueStep; - } - } - span->arrayMask |= SPAN_SPEC; -} - - /* Fill in the span.array.fog values from the interpolation values */ static void interpolate_fog(const GLcontext *ctx, struct sw_span *span) @@ -1040,28 +1154,160 @@ _swrast_write_index_span( GLcontext *ctx, struct sw_span *span) * GL_LIGHT_MODEL_COLOR_CONTROL = GL_SEPARATE_SPECULAR_COLOR. */ static void -add_colors(GLuint n, GLchan rgba[][4], GLchan specular[][4] ) +add_specular(GLcontext *ctx, struct sw_span *span) { - GLuint i; - for (i = 0; i < n; i++) { -#if CHAN_TYPE == GL_FLOAT - /* no clamping */ - rgba[i][RCOMP] += specular[i][RCOMP]; - rgba[i][GCOMP] += specular[i][GCOMP]; - rgba[i][BCOMP] += specular[i][BCOMP]; -#else - GLint r = rgba[i][RCOMP] + specular[i][RCOMP]; - GLint g = rgba[i][GCOMP] + specular[i][GCOMP]; - GLint b = rgba[i][BCOMP] + specular[i][BCOMP]; - rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX); - rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX); - rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX); -#endif + switch (span->array->ChanType) { + case GL_UNSIGNED_BYTE: + { + GLubyte (*rgba)[4] = span->array->color.sz1.rgba; + GLubyte (*spec)[4] = span->array->color.sz1.spec; + GLuint i; + for (i = 0; i < span->end; i++) { + GLint r = rgba[i][RCOMP] + spec[i][RCOMP]; + GLint g = rgba[i][GCOMP] + spec[i][GCOMP]; + GLint b = rgba[i][BCOMP] + spec[i][BCOMP]; + GLint a = rgba[i][ACOMP] + spec[i][ACOMP]; + rgba[i][RCOMP] = MIN2(r, 255); + rgba[i][GCOMP] = MIN2(g, 255); + rgba[i][BCOMP] = MIN2(b, 255); + rgba[i][ACOMP] = MIN2(a, 255); + } + } + break; + case GL_UNSIGNED_SHORT: + { + GLushort (*rgba)[4] = span->array->color.sz2.rgba; + GLushort (*spec)[4] = span->array->color.sz2.spec; + GLuint i; + for (i = 0; i < span->end; i++) { + GLint r = rgba[i][RCOMP] + spec[i][RCOMP]; + GLint g = rgba[i][GCOMP] + spec[i][GCOMP]; + GLint b = rgba[i][BCOMP] + spec[i][BCOMP]; + GLint a = rgba[i][ACOMP] + spec[i][ACOMP]; + rgba[i][RCOMP] = MIN2(r, 65535); + rgba[i][GCOMP] = MIN2(g, 65535); + rgba[i][BCOMP] = MIN2(b, 65535); + rgba[i][ACOMP] = MIN2(a, 65535); + } + } + break; + case GL_FLOAT: + { + GLfloat (*rgba)[4] = span->array->color.sz4.rgba; + GLfloat (*spec)[4] = span->array->color.sz4.spec; + GLuint i; + for (i = 0; i < span->end; i++) { + rgba[i][RCOMP] += spec[i][RCOMP]; + rgba[i][GCOMP] += spec[i][GCOMP]; + rgba[i][BCOMP] += spec[i][BCOMP]; + rgba[i][ACOMP] += spec[i][ACOMP]; + } + } + break; + default: + _mesa_problem(ctx, "Invalid datatype in add_specular"); } } /** + * Convert the span's color arrays to the given type. + */ +static void +convert_color_type(GLcontext *ctx, struct sw_span *span, GLenum newType) +{ + const GLubyte *mask = span->array->mask; + GLubyte (*rgba1)[4] = span->array->color.sz1.rgba; + GLushort (*rgba2)[4] = span->array->color.sz2.rgba; + GLfloat (*rgba4)[4] = span->array->color.sz4.rgba; + + ASSERT(span->array->ChanType != newType); + + switch (span->array->ChanType) { + case GL_UNSIGNED_BYTE: + if (newType == GL_UNSIGNED_SHORT) { + GLuint i; + for (i = 0; i < span->end; i++) { + if (mask[i]) { + rgba2[i][RCOMP] = UBYTE_TO_USHORT(rgba1[i][RCOMP]); + rgba2[i][GCOMP] = UBYTE_TO_USHORT(rgba1[i][GCOMP]); + rgba2[i][BCOMP] = UBYTE_TO_USHORT(rgba1[i][BCOMP]); + rgba2[i][ACOMP] = UBYTE_TO_USHORT(rgba1[i][ACOMP]); + } + } + } + else { + GLuint i; + ASSERT(newType == GL_FLOAT); + for (i = 0; i < span->end; i++) { + if (mask[i]) { + rgba4[i][RCOMP] = UBYTE_TO_FLOAT(rgba1[i][RCOMP]); + rgba4[i][GCOMP] = UBYTE_TO_FLOAT(rgba1[i][GCOMP]); + rgba4[i][BCOMP] = UBYTE_TO_FLOAT(rgba1[i][BCOMP]); + rgba4[i][ACOMP] = UBYTE_TO_FLOAT(rgba1[i][ACOMP]); + } + } + } + break; + case GL_UNSIGNED_SHORT: + if (newType == GL_UNSIGNED_BYTE) { + GLuint i; + for (i = 0; i < span->end; i++) { + if (mask[i]) { + rgba1[i][RCOMP] = USHORT_TO_UBYTE(rgba2[i][RCOMP]); + rgba1[i][GCOMP] = USHORT_TO_UBYTE(rgba2[i][GCOMP]); + rgba1[i][BCOMP] = USHORT_TO_UBYTE(rgba2[i][BCOMP]); + rgba1[i][ACOMP] = USHORT_TO_UBYTE(rgba2[i][ACOMP]); + } + } + } + else { + GLuint i; + ASSERT(newType == GL_FLOAT); + for (i = 0; i < span->end; i++) { + if (mask[i]) { + rgba4[i][RCOMP] = USHORT_TO_FLOAT(rgba2[i][RCOMP]); + rgba4[i][GCOMP] = USHORT_TO_FLOAT(rgba2[i][GCOMP]); + rgba4[i][BCOMP] = USHORT_TO_FLOAT(rgba2[i][BCOMP]); + rgba4[i][ACOMP] = USHORT_TO_FLOAT(rgba2[i][ACOMP]); + } + } + } + break; + case GL_FLOAT: + if (newType == GL_UNSIGNED_BYTE) { + GLuint i; + for (i = 0; i < span->end; i++) { + if (mask[i]) { + UNCLAMPED_FLOAT_TO_UBYTE(rgba1[i][RCOMP], rgba4[i][RCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(rgba1[i][GCOMP], rgba4[i][GCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(rgba1[i][BCOMP], rgba4[i][BCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(rgba1[i][ACOMP], rgba4[i][ACOMP]); + } + } + } + else { + GLuint i; + ASSERT(newType == GL_UNSIGNED_SHORT); + for (i = 0; i < span->end; i++) { + if (mask[i]) { + UNCLAMPED_FLOAT_TO_USHORT(rgba2[i][RCOMP], rgba4[i][RCOMP]); + UNCLAMPED_FLOAT_TO_USHORT(rgba2[i][GCOMP], rgba4[i][GCOMP]); + UNCLAMPED_FLOAT_TO_USHORT(rgba2[i][BCOMP], rgba4[i][BCOMP]); + UNCLAMPED_FLOAT_TO_USHORT(rgba2[i][ACOMP], rgba4[i][ACOMP]); + } + } + } + break; + default: + _mesa_problem(ctx, "Invalid datatype in convert_color_type"); + } + span->array->ChanType = newType; +} + + + +/** * Apply all the per-fragment operations to a span. * This now includes texturing (_swrast_write_texture_span() is history). * This function may modify any of the array values in the span. @@ -1144,10 +1390,10 @@ _swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span) if (!deferredTexture) { /* Now we need the rgba array, fill it in if needed */ if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) - interpolate_colors(ctx, span); + interpolate_colors(ctx, span, GL_FALSE); if (span->interpMask & SPAN_SPEC) - interpolate_specular(ctx, span); + interpolate_colors(ctx, span, GL_TRUE); if (span->interpMask & SPAN_FOG) interpolate_fog(ctx, span); @@ -1232,10 +1478,10 @@ _swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span) if (deferredTexture) { /* Now we need the rgba array, fill it in if needed */ if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) - interpolate_colors(ctx, span); + interpolate_colors(ctx, span, GL_FALSE); if (span->interpMask & SPAN_SPEC) - interpolate_specular(ctx, span); + interpolate_colors(ctx, span, GL_TRUE); if (span->interpMask & SPAN_FOG) interpolate_fog(ctx, span); @@ -1264,10 +1510,10 @@ _swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span) (ctx->Light.Enabled && ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) { if (span->interpMask & SPAN_SPEC) { - interpolate_specular(ctx, span); + interpolate_colors(ctx, span, GL_TRUE); } if (span->arrayMask & SPAN_SPEC) { - add_colors( span->end, span->array->rgba, span->array->spec ); + add_specular(ctx, span); } else { /* We probably added the base/specular colors during the @@ -1316,14 +1562,20 @@ _swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span) GLchan rgbaSave[MAX_WIDTH][4]; GLuint buf; + if (numDrawBuffers > 0) { + if (fb->_ColorDrawBuffers[output][0]->DataType + != span->array->ChanType) { + convert_color_type(ctx, span, + fb->_ColorDrawBuffers[output][0]->DataType); + } + } + if (numDrawBuffers > 1) { /* save colors for second, third renderbuffer writes */ _mesa_memcpy(rgbaSave, span->array->rgba, 4 * span->end * sizeof(GLchan)); } - /* XXX check that span's ChanType == rb's DataType, convert if needed */ - for (buf = 0; buf < numDrawBuffers; buf++) { struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][buf]; ASSERT(rb->_BaseFormat == GL_RGBA); |