X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fswrast%2Fs_span.c;h=dcb2db01e6d09c204ce444195eb1b73fd1380125;hb=34fe561895bed253070b7dadaa86b4473ad7b51a;hp=8931cdec1bc4569ba111ddc840eb84b83e8582b3;hpb=c8e714df013cdf360602f9cc96d26cb732b19a32;p=mesa.git diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index 8931cdec1bc..dcb2db01e6d 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -1,6 +1,5 @@ /* * Mesa 3-D graphics library - * Version: 7.5 * * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. * Copyright (C) 2009 VMware, Inc. All Rights Reserved. @@ -18,9 +17,10 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. */ @@ -31,11 +31,18 @@ * \author Brian Paul */ +#include "c99_math.h" +#include "main/errors.h" #include "main/glheader.h" -#include "main/colormac.h" +#include "main/format_pack.h" +#include "main/format_unpack.h" #include "main/macros.h" -#include "main/imports.h" + #include "main/image.h" +#include "main/samplerobj.h" +#include "main/state.h" +#include "main/stencil.h" +#include "main/teximage.h" #include "s_atifragshader.h" #include "s_alpha.h" @@ -50,6 +57,7 @@ #include "s_stencil.h" #include "s_texcombine.h" +#include /** * Set default fragment attributes for the span using the @@ -57,7 +65,7 @@ * and glBitmap. */ void -_swrast_span_default_attribs(GLcontext *ctx, SWspan *span) +_swrast_span_default_attribs(struct gl_context *ctx, SWspan *span) { GLchan r, g, b, a; /* Z*/ @@ -66,7 +74,7 @@ _swrast_span_default_attribs(GLcontext *ctx, SWspan *span) if (ctx->DrawBuffer->Visual.depthBits <= 16) span->z = FloatToFixed(ctx->Current.RasterPos[2] * depthMax + 0.5F); else { - GLfloat tmpf = ctx->Current.RasterPos[2] * depthMax; + GLfloat tmpf = ctx->Current.RasterPos[2] * depthMax; tmpf = MIN2(tmpf, depthMax); span->z = (GLint)tmpf; } @@ -75,9 +83,9 @@ _swrast_span_default_attribs(GLcontext *ctx, SWspan *span) } /* W (for perspective correction) */ - span->attrStart[FRAG_ATTRIB_WPOS][3] = 1.0; - span->attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0; - span->attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0; + span->attrStart[VARYING_SLOT_POS][3] = 1.0; + span->attrStepX[VARYING_SLOT_POS][3] = 0.0; + span->attrStepY[VARYING_SLOT_POS][3] = 0.0; /* primary color, or color index */ UNCLAMPED_FLOAT_TO_CHAN(r, ctx->Current.RasterColor[0]); @@ -101,16 +109,16 @@ _swrast_span_default_attribs(GLcontext *ctx, SWspan *span) span->alphaStep = 0; span->interpMask |= SPAN_RGBA; - COPY_4V(span->attrStart[FRAG_ATTRIB_COL0], ctx->Current.RasterColor); - ASSIGN_4V(span->attrStepX[FRAG_ATTRIB_COL0], 0.0, 0.0, 0.0, 0.0); - ASSIGN_4V(span->attrStepY[FRAG_ATTRIB_COL0], 0.0, 0.0, 0.0, 0.0); + COPY_4V(span->attrStart[VARYING_SLOT_COL0], ctx->Current.RasterColor); + ASSIGN_4V(span->attrStepX[VARYING_SLOT_COL0], 0.0, 0.0, 0.0, 0.0); + ASSIGN_4V(span->attrStepY[VARYING_SLOT_COL0], 0.0, 0.0, 0.0, 0.0); /* Secondary color */ if (ctx->Light.Enabled || ctx->Fog.ColorSumEnabled) { - COPY_4V(span->attrStart[FRAG_ATTRIB_COL1], ctx->Current.RasterSecondaryColor); - ASSIGN_4V(span->attrStepX[FRAG_ATTRIB_COL1], 0.0, 0.0, 0.0, 0.0); - ASSIGN_4V(span->attrStepY[FRAG_ATTRIB_COL1], 0.0, 0.0, 0.0, 0.0); + COPY_4V(span->attrStart[VARYING_SLOT_COL1], ctx->Current.RasterSecondaryColor); + ASSIGN_4V(span->attrStepX[VARYING_SLOT_COL1], 0.0, 0.0, 0.0, 0.0); + ASSIGN_4V(span->attrStepY[VARYING_SLOT_COL1], 0.0, 0.0, 0.0, 0.0); } /* fog */ @@ -125,18 +133,19 @@ _swrast_span_default_attribs(GLcontext *ctx, SWspan *span) /* fog blend factor should be computed from fogcoord now */ fogVal = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance); } - span->attrStart[FRAG_ATTRIB_FOGC][0] = fogVal; - span->attrStepX[FRAG_ATTRIB_FOGC][0] = 0.0; - span->attrStepY[FRAG_ATTRIB_FOGC][0] = 0.0; + span->attrStart[VARYING_SLOT_FOGC][0] = fogVal; + span->attrStepX[VARYING_SLOT_FOGC][0] = 0.0; + span->attrStepY[VARYING_SLOT_FOGC][0] = 0.0; } /* texcoords */ { GLuint i; for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { - const GLuint attr = FRAG_ATTRIB_TEX0 + i; + const GLuint attr = VARYING_SLOT_TEX0 + i; const GLfloat *tc = ctx->Current.RasterTexCoords[i]; - if (ctx->FragmentProgram._Current || ctx->ATIFragmentShader._Enabled) { + if (_swrast_use_fragment_program(ctx) || + _mesa_ati_fragment_shader_enabled(ctx)) { COPY_4V(span->attrStart[attr], tc); } else if (tc[3] > 0.0F) { @@ -160,10 +169,11 @@ _swrast_span_default_attribs(GLcontext *ctx, SWspan *span) * Interpolate the active attributes (and'd with attrMask) to * fill in span->array->attribs[]. * Perspective correction will be done. The point/line/triangle function - * should have computed attrStart/Step values for FRAG_ATTRIB_WPOS[3]! + * should have computed attrStart/Step values for VARYING_SLOT_POS[3]! */ -static INLINE void -interpolate_active_attribs(GLcontext *ctx, SWspan *span, GLbitfield attrMask) +static inline void +interpolate_active_attribs(struct gl_context *ctx, SWspan *span, + GLbitfield64 attrMask) { const SWcontext *swrast = SWRAST_CONTEXT(ctx); @@ -174,9 +184,9 @@ interpolate_active_attribs(GLcontext *ctx, SWspan *span, GLbitfield attrMask) attrMask &= ~span->arrayAttribs; ATTRIB_LOOP_BEGIN - if (attrMask & (1 << attr)) { - const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; - GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; + if (attrMask & BITFIELD64_BIT(attr)) { + const GLfloat dwdx = span->attrStepX[VARYING_SLOT_POS][3]; + GLfloat w = span->attrStart[VARYING_SLOT_POS][3]; const GLfloat dv0dx = span->attrStepX[attr][0]; const GLfloat dv1dx = span->attrStepX[attr][1]; const GLfloat dv2dx = span->attrStepX[attr][2]; @@ -198,8 +208,8 @@ interpolate_active_attribs(GLcontext *ctx, SWspan *span, GLbitfield attrMask) v3 += dv3dx; w += dwdx; } - ASSERT((span->arrayAttribs & (1 << attr)) == 0); - span->arrayAttribs |= (1 << attr); + assert((span->arrayAttribs & BITFIELD64_BIT(attr)) == 0); + span->arrayAttribs |= BITFIELD64_BIT(attr); } ATTRIB_LOOP_END } @@ -209,14 +219,14 @@ interpolate_active_attribs(GLcontext *ctx, SWspan *span, GLbitfield attrMask) * Interpolate primary colors to fill in the span->array->rgba8 (or rgb16) * color array. */ -static INLINE void -interpolate_int_colors(GLcontext *ctx, SWspan *span) +static inline void +interpolate_int_colors(struct gl_context *ctx, SWspan *span) { +#if CHAN_BITS != 32 const GLuint n = span->end; GLuint i; -#if CHAN_BITS != 32 - ASSERT(!(span->arrayMask & SPAN_RGBA)); + assert(!(span->arrayMask & SPAN_RGBA)); #endif switch (span->array->ChanType) { @@ -296,26 +306,27 @@ interpolate_int_colors(GLcontext *ctx, SWspan *span) break; #endif case GL_FLOAT: - interpolate_active_attribs(ctx, span, FRAG_BIT_COL0); + interpolate_active_attribs(ctx, span, VARYING_BIT_COL0); break; default: - _mesa_problem(NULL, "bad datatype in interpolate_int_colors"); + _mesa_problem(ctx, "bad datatype 0x%x in interpolate_int_colors", + span->array->ChanType); } span->arrayMask |= SPAN_RGBA; } /** - * Populate the FRAG_ATTRIB_COL0 array. + * Populate the VARYING_SLOT_COL0 array. */ -static INLINE void +static inline void interpolate_float_colors(SWspan *span) { - GLfloat (*col0)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; + GLfloat (*col0)[4] = span->array->attribs[VARYING_SLOT_COL0]; const GLuint n = span->end; GLuint i; - assert(!(span->arrayAttribs & FRAG_BIT_COL0)); + assert(!(span->arrayAttribs & VARYING_BIT_COL0)); if (span->arrayMask & SPAN_RGBA) { /* convert array of int colors */ @@ -328,7 +339,7 @@ interpolate_float_colors(SWspan *span) } else { /* interpolate red/green/blue/alpha to get float colors */ - ASSERT(span->interpMask & SPAN_RGBA); + assert(span->interpMask & SPAN_RGBA); if (span->interpMask & SPAN_FLAT) { GLfloat r = FixedToFloat(span->red); GLfloat g = FixedToFloat(span->green); @@ -360,7 +371,7 @@ interpolate_float_colors(SWspan *span) } } - span->arrayAttribs |= FRAG_BIT_COL0; + span->arrayAttribs |= VARYING_BIT_COL0; span->array->ChanType = GL_FLOAT; } @@ -370,16 +381,16 @@ interpolate_float_colors(SWspan *span) * Fill in the span.zArray array from the span->z, zStep values. */ void -_swrast_span_interpolate_z( const GLcontext *ctx, SWspan *span ) +_swrast_span_interpolate_z( const struct gl_context *ctx, SWspan *span ) { const GLuint n = span->end; GLuint i; - ASSERT(!(span->arrayMask & SPAN_Z)); + assert(!(span->arrayMask & SPAN_Z)); if (ctx->DrawBuffer->Visual.depthBits <= 16) { GLfixed zval = span->z; - GLuint *z = span->array->z; + GLuint *z = span->array->z; for (i = 0; i < n; i++) { z[i] = FixedToInt(zval); zval += span->zStep; @@ -412,10 +423,10 @@ _swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, GLfloat dvdx = texH * ((t + dtdx) / (q + dqdx) - t * invQ); GLfloat dudy = texW * ((s + dsdy) / (q + dqdy) - s * invQ); GLfloat dvdy = texH * ((t + dtdy) / (q + dqdy) - t * invQ); - GLfloat x = SQRTF(dudx * dudx + dvdx * dvdx); - GLfloat y = SQRTF(dudy * dudy + dvdy * dvdy); + GLfloat x = sqrtf(dudx * dudx + dvdx * dvdx); + GLfloat y = sqrtf(dudy * dudy + dvdy * dvdy); GLfloat rho = MAX2(x, y); - GLfloat lambda = LOG2(rho); + GLfloat lambda = log2f(rho); return lambda; } @@ -435,21 +446,21 @@ _swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, GLfloat dsdy2 = (s + dsdy) / (q + dqdy) - s * invQ; GLfloat dtdy2 = (t + dtdy) / (q + dqdy) - t * invQ; GLfloat maxU, maxV, rho, lambda; - dsdx2 = FABSF(dsdx2); - dsdy2 = FABSF(dsdy2); - dtdx2 = FABSF(dtdx2); - dtdy2 = FABSF(dtdy2); + dsdx2 = fabsf(dsdx2); + dsdy2 = fabsf(dsdy2); + dtdx2 = fabsf(dtdx2); + dtdy2 = fabsf(dtdy2); maxU = MAX2(dsdx2, dsdy2) * texW; maxV = MAX2(dtdx2, dtdy2) * texH; rho = MAX2(maxU, maxV); - lambda = LOG2(rho); + lambda = logf2(rho); return lambda; } #endif /** - * Fill in the span.array->attrib[FRAG_ATTRIB_TEXn] arrays from the + * Fill in the span.array->attrib[VARYING_SLOT_TEXn] arrays from the * using the attrStart/Step values. * * This function only used during fixed-function fragment processing. @@ -460,7 +471,7 @@ _swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, * texels with (s/q, t/q, r/q). */ static void -interpolate_texcoords(GLcontext *ctx, SWspan *span) +interpolate_texcoords(struct gl_context *ctx, SWspan *span) { const GLuint maxUnit = (ctx->Texture._EnabledCoordUnits > 1) ? ctx->Const.MaxTextureUnits : 1; @@ -469,7 +480,7 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) /* XXX CoordUnits vs. ImageUnits */ for (u = 0; u < maxUnit; u++) { if (ctx->Texture._EnabledCoordUnits & (1 << u)) { - const GLuint attr = FRAG_ATTRIB_TEX0 + u; + const GLuint attr = VARYING_SLOT_TEX0 + u; const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current; GLfloat texW, texH; GLboolean needLambda; @@ -488,11 +499,22 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) GLfloat q = span->attrStart[attr][3] + span->leftClip * dqdx; if (obj) { - const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel]; - needLambda = (obj->MinFilter != obj->MagFilter) - || ctx->FragmentProgram._Current; - texW = img->WidthScale; - texH = img->HeightScale; + const struct gl_texture_image *img = _mesa_base_tex_image(obj); + const struct swrast_texture_image *swImg = + swrast_texture_image_const(img); + const struct gl_sampler_object *samp = _mesa_get_samplerobj(ctx, u); + + needLambda = (samp->MinFilter != samp->MagFilter) + || _swrast_use_fragment_program(ctx); + /* LOD is calculated directly in the ansiotropic filter, we can + * skip the normal lambda function as the result is ignored. + */ + if (samp->MaxAnisotropy > 1.0F && + samp->MinFilter == GL_LINEAR_MIPMAP_LINEAR) { + needLambda = GL_FALSE; + } + texW = swImg->WidthScale; + texH = swImg->HeightScale; } else { /* using a fragment program */ @@ -503,11 +525,11 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) if (needLambda) { GLuint i; - if (ctx->FragmentProgram._Current - || ctx->ATIFragmentShader._Enabled) { + if (_swrast_use_fragment_program(ctx) + || _mesa_ati_fragment_shader_enabled(ctx)) { /* do perspective correction but don't divide s, t, r by q */ - const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; - GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3] + span->leftClip * dwdx; + const GLfloat dwdx = span->attrStepX[VARYING_SLOT_POS][3]; + GLfloat w = span->attrStart[VARYING_SLOT_POS][3] + span->leftClip * dwdx; for (i = 0; i < span->end; i++) { const GLfloat invW = 1.0F / w; texcoord[i][0] = s * invW; @@ -544,11 +566,11 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) } else { GLuint i; - if (ctx->FragmentProgram._Current || - ctx->ATIFragmentShader._Enabled) { + if (_swrast_use_fragment_program(ctx) || + _mesa_ati_fragment_shader_enabled(ctx)) { /* do perspective correction but don't divide s, t, r by q */ - const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; - GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3] + span->leftClip * dwdx; + const GLfloat dwdx = span->attrStepX[VARYING_SLOT_POS][3]; + GLfloat w = span->attrStart[VARYING_SLOT_POS][3] + span->leftClip * dwdx; for (i = 0; i < span->end; i++) { const GLfloat invW = 1.0F / w; texcoord[i][0] = s * invW; @@ -598,12 +620,12 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) /** - * Fill in the arrays->attribs[FRAG_ATTRIB_WPOS] array. + * Fill in the arrays->attribs[VARYING_SLOT_POS] array. */ -static INLINE void -interpolate_wpos(GLcontext *ctx, SWspan *span) +static inline void +interpolate_wpos(struct gl_context *ctx, SWspan *span) { - GLfloat (*wpos)[4] = span->array->attribs[FRAG_ATTRIB_WPOS]; + GLfloat (*wpos)[4] = span->array->attribs[VARYING_SLOT_POS]; GLuint i; const GLfloat zScale = 1.0F / ctx->DrawBuffer->_DepthMaxF; GLfloat w, dw; @@ -621,8 +643,8 @@ interpolate_wpos(GLcontext *ctx, SWspan *span) } } - dw = span->attrStepX[FRAG_ATTRIB_WPOS][3]; - w = span->attrStart[FRAG_ATTRIB_WPOS][3] + span->leftClip * dw; + dw = span->attrStepX[VARYING_SLOT_POS][3]; + w = span->attrStart[VARYING_SLOT_POS][3] + span->leftClip * dw; for (i = 0; i < span->end; i++) { wpos[i][2] = (GLfloat) span->array->z[i] * zScale; wpos[i][3] = w; @@ -634,12 +656,12 @@ interpolate_wpos(GLcontext *ctx, SWspan *span) /** * Apply the current polygon stipple pattern to a span of pixels. */ -static INLINE void -stipple_polygon_span(GLcontext *ctx, SWspan *span) +static inline void +stipple_polygon_span(struct gl_context *ctx, SWspan *span) { GLubyte *mask = span->array->mask; - ASSERT(ctx->Polygon.StippleFlag); + assert(ctx->Polygon.StippleFlag); if (span->arrayMask & SPAN_XY) { /* arrays of x/y pixel coords */ @@ -679,8 +701,8 @@ stipple_polygon_span(GLcontext *ctx, SWspan *span) * Return: GL_TRUE some pixels still visible * GL_FALSE nothing visible */ -static INLINE GLuint -clip_span( GLcontext *ctx, SWspan *span ) +static inline GLuint +clip_span( struct gl_context *ctx, SWspan *span ) { const GLint xmin = ctx->DrawBuffer->_Xmin; const GLint xmax = ctx->DrawBuffer->_Xmax; @@ -696,11 +718,13 @@ clip_span( GLcontext *ctx, SWspan *span ) const GLint n = span->end; GLubyte *mask = span->array->mask; GLint i; + GLuint passed = 0; if (span->arrayMask & SPAN_MASK) { /* note: using & intead of && to reduce branches */ for (i = 0; i < n; i++) { mask[i] &= (x[i] >= xmin) & (x[i] < xmax) & (y[i] >= ymin) & (y[i] < ymax); + passed += mask[i]; } } else { @@ -708,9 +732,10 @@ clip_span( GLcontext *ctx, SWspan *span ) for (i = 0; i < n; i++) { mask[i] = (x[i] >= xmin) & (x[i] < xmax) & (y[i] >= ymin) & (y[i] < ymax); + passed += mask[i]; } } - return GL_TRUE; /* some pixels visible */ + return passed > 0; } else { /* horizontal span of pixels */ @@ -726,7 +751,7 @@ clip_span( GLcontext *ctx, SWspan *span ) /* Clip to right */ if (x + n > xmax) { - ASSERT(x < xmax); + assert(x < xmax); n = span->end = xmax - x; } @@ -735,16 +760,16 @@ clip_span( GLcontext *ctx, SWspan *span ) const GLint leftClip = xmin - x; GLuint i; - ASSERT(leftClip > 0); - ASSERT(x + n > xmin); + assert(leftClip > 0); + assert(x + n > xmin); /* Clip 'leftClip' pixels from the left side. * The span->leftClip field will be applied when we interpolate * fragment attributes. * For arrays of values, shift them left. */ - for (i = 0; i < FRAG_ATTRIB_MAX; i++) { - if (span->interpMask & (1 << i)) { + for (i = 0; i < VARYING_SLOT_MAX; i++) { + if (span->interpMask & (1u << i)) { GLuint j; for (j = 0; j < 4; j++) { span->attrStart[i][j] += leftClip * span->attrStepX[i][j]; @@ -762,10 +787,10 @@ clip_span( GLcontext *ctx, SWspan *span ) span->intTex[1] += leftClip * span->intTexStep[1]; #define SHIFT_ARRAY(ARRAY, SHIFT, LEN) \ - memcpy(ARRAY, ARRAY + (SHIFT), (LEN) * sizeof(ARRAY[0])) + memmove(ARRAY, ARRAY + (SHIFT), (LEN) * sizeof(ARRAY[0])) - for (i = 0; i < FRAG_ATTRIB_MAX; i++) { - if (span->arrayAttribs & (1 << i)) { + for (i = 0; i < VARYING_SLOT_MAX; i++) { + if (span->arrayAttribs & BITFIELD64_BIT(i)) { /* shift array elements left by 'leftClip' */ SHIFT_ARRAY(span->array->attribs[i], leftClip, n - leftClip); } @@ -791,10 +816,10 @@ clip_span( GLcontext *ctx, SWspan *span ) span->writeAll = GL_FALSE; } - ASSERT(span->x >= xmin); - ASSERT(span->x + span->end <= xmax); - ASSERT(span->y >= ymin); - ASSERT(span->y < ymax); + assert(span->x >= xmin); + assert(span->x + span->end <= xmax); + assert(span->y >= ymin); + assert(span->y < ymax); return GL_TRUE; /* some pixels visible */ } @@ -804,41 +829,41 @@ clip_span( GLcontext *ctx, SWspan *span ) /** * Add specular colors to primary colors. * Only called during fixed-function operation. - * Result is float color array (FRAG_ATTRIB_COL0). + * Result is float color array (VARYING_SLOT_COL0). */ -static INLINE void -add_specular(GLcontext *ctx, SWspan *span) +static inline void +add_specular(struct gl_context *ctx, SWspan *span) { const SWcontext *swrast = SWRAST_CONTEXT(ctx); const GLubyte *mask = span->array->mask; - GLfloat (*col0)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; - GLfloat (*col1)[4] = span->array->attribs[FRAG_ATTRIB_COL1]; + GLfloat (*col0)[4] = span->array->attribs[VARYING_SLOT_COL0]; + GLfloat (*col1)[4] = span->array->attribs[VARYING_SLOT_COL1]; GLuint i; - ASSERT(!ctx->FragmentProgram._Current); - ASSERT(span->arrayMask & SPAN_RGBA); - ASSERT(swrast->_ActiveAttribMask & FRAG_BIT_COL1); + assert(!_swrast_use_fragment_program(ctx)); + assert(span->arrayMask & SPAN_RGBA); + assert(swrast->_ActiveAttribMask & VARYING_BIT_COL1); (void) swrast; /* silence warning */ if (span->array->ChanType == GL_FLOAT) { - if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) { - interpolate_active_attribs(ctx, span, FRAG_BIT_COL0); + if ((span->arrayAttribs & VARYING_BIT_COL0) == 0) { + interpolate_active_attribs(ctx, span, VARYING_BIT_COL0); } } else { /* need float colors */ - if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) { + if ((span->arrayAttribs & VARYING_BIT_COL0) == 0) { interpolate_float_colors(span); } } - if ((span->arrayAttribs & FRAG_BIT_COL1) == 0) { + if ((span->arrayAttribs & VARYING_BIT_COL1) == 0) { /* XXX could avoid this and interpolate COL1 in the loop below */ - interpolate_active_attribs(ctx, span, FRAG_BIT_COL1); + interpolate_active_attribs(ctx, span, VARYING_BIT_COL1); } - ASSERT(span->arrayAttribs & FRAG_BIT_COL0); - ASSERT(span->arrayAttribs & FRAG_BIT_COL1); + assert(span->arrayAttribs & VARYING_BIT_COL0); + assert(span->arrayAttribs & VARYING_BIT_COL1); for (i = 0; i < span->end; i++) { if (mask[i]) { @@ -855,7 +880,7 @@ add_specular(GLcontext *ctx, SWspan *span) /** * Apply antialiasing coverage value to alpha values. */ -static INLINE void +static inline void apply_aa_coverage(SWspan *span) { const GLfloat *coverage = span->array->coverage; @@ -864,20 +889,20 @@ apply_aa_coverage(SWspan *span) GLubyte (*rgba)[4] = span->array->rgba8; for (i = 0; i < span->end; i++) { const GLfloat a = rgba[i][ACOMP] * coverage[i]; - rgba[i][ACOMP] = (GLubyte) CLAMP(a, 0.0, 255.0); - ASSERT(coverage[i] >= 0.0); - ASSERT(coverage[i] <= 1.0); + rgba[i][ACOMP] = (GLubyte) CLAMP(a, 0.0F, 255.0F); + assert(coverage[i] >= 0.0F); + assert(coverage[i] <= 1.0F); } } else if (span->array->ChanType == GL_UNSIGNED_SHORT) { GLushort (*rgba)[4] = span->array->rgba16; for (i = 0; i < span->end; i++) { const GLfloat a = rgba[i][ACOMP] * coverage[i]; - rgba[i][ACOMP] = (GLushort) CLAMP(a, 0.0, 65535.0); + rgba[i][ACOMP] = (GLushort) CLAMP(a, 0.0F, 65535.0F); } } else { - GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; + GLfloat (*rgba)[4] = span->array->attribs[VARYING_SLOT_COL0]; for (i = 0; i < span->end; i++) { rgba[i][ACOMP] = rgba[i][ACOMP] * coverage[i]; /* clamp later */ @@ -889,12 +914,12 @@ apply_aa_coverage(SWspan *span) /** * Clamp span's float colors to [0,1] */ -static INLINE void +static inline void clamp_colors(SWspan *span) { - GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; + GLfloat (*rgba)[4] = span->array->attribs[VARYING_SLOT_COL0]; GLuint i; - ASSERT(span->array->ChanType == GL_FLOAT); + assert(span->array->ChanType == GL_FLOAT); for (i = 0; i < span->end; i++) { rgba[i][RCOMP] = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F); rgba[i][GCOMP] = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F); @@ -910,20 +935,20 @@ clamp_colors(SWspan *span) * program that writes to gl_FragData[1] or higher. * \param output which fragment program color output is being processed */ -static INLINE void -convert_color_type(SWspan *span, GLenum newType, GLuint output) +static inline void +convert_color_type(SWspan *span, GLenum srcType, GLenum newType, GLuint output) { GLvoid *src, *dst; - if (output > 0 || span->array->ChanType == GL_FLOAT) { - src = span->array->attribs[FRAG_ATTRIB_COL0 + output]; + if (output > 0 || srcType == GL_FLOAT) { + src = span->array->attribs[VARYING_SLOT_COL0 + output]; span->array->ChanType = GL_FLOAT; } - else if (span->array->ChanType == GL_UNSIGNED_BYTE) { + else if (srcType == GL_UNSIGNED_BYTE) { src = span->array->rgba8; } else { - ASSERT(span->array->ChanType == GL_UNSIGNED_SHORT); + assert(srcType == GL_UNSIGNED_SHORT); src = span->array->rgba16; } @@ -934,7 +959,7 @@ convert_color_type(SWspan *span, GLenum newType, GLuint output) dst = span->array->rgba16; } else { - dst = span->array->attribs[FRAG_ATTRIB_COL0]; + dst = span->array->attribs[VARYING_SLOT_COL0]; } _mesa_convert_colors(span->array->ChanType, src, @@ -950,28 +975,17 @@ convert_color_type(SWspan *span, GLenum newType, GLuint output) /** * Apply fragment shader, fragment program or normal texturing to span. */ -static INLINE void -shade_texture_span(GLcontext *ctx, SWspan *span) +static inline void +shade_texture_span(struct gl_context *ctx, SWspan *span) { - GLbitfield inputsRead; - - /* Determine which fragment attributes are actually needed */ - if (ctx->FragmentProgram._Current) { - inputsRead = ctx->FragmentProgram._Current->Base.InputsRead; - } - else { - /* XXX we could be a bit smarter about this */ - inputsRead = ~0; - } - - if (ctx->FragmentProgram._Current || - ctx->ATIFragmentShader._Enabled) { + if (_swrast_use_fragment_program(ctx) || + _mesa_ati_fragment_shader_enabled(ctx)) { /* programmable shading */ if (span->primitive == GL_BITMAP && span->array->ChanType != GL_FLOAT) { - convert_color_type(span, GL_FLOAT, 0); + convert_color_type(span, span->array->ChanType, GL_FLOAT, 0); } else { - span->array->rgba = (void *) span->array->attribs[FRAG_ATTRIB_COL0]; + span->array->rgba = (void *) span->array->attribs[VARYING_SLOT_COL0]; } if (span->primitive != GL_POINT || @@ -986,18 +1000,18 @@ shade_texture_span(GLcontext *ctx, SWspan *span) _swrast_span_interpolate_z (ctx, span); #if 0 - if (inputsRead & FRAG_BIT_WPOS) + if (inputsRead & VARYING_BIT_POS) #else /* XXX always interpolate wpos so that DDX/DDY work */ #endif interpolate_wpos(ctx, span); /* Run fragment program/shader now */ - if (ctx->FragmentProgram._Current) { + if (_swrast_use_fragment_program(ctx)) { _swrast_exec_fragment_program(ctx, span); } else { - ASSERT(ctx->ATIFragmentShader._Enabled); + assert(_mesa_ati_fragment_shader_enabled(ctx)); _swrast_exec_fragment_shader(ctx, span); } } @@ -1005,14 +1019,14 @@ shade_texture_span(GLcontext *ctx, SWspan *span) /* conventional texturing */ #if CHAN_BITS == 32 - if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) { + if ((span->arrayAttribs & VARYING_BIT_COL0) == 0) { interpolate_int_colors(ctx, span); } #else if (!(span->arrayMask & SPAN_RGBA)) interpolate_int_colors(ctx, span); #endif - if ((span->arrayAttribs & FRAG_BITS_TEX_ANY) == 0x0) + if ((span->arrayAttribs & VARYING_BITS_TEX_ANY) == 0x0) interpolate_texcoords(ctx, span); _swrast_texture_span(ctx, span); @@ -1020,6 +1034,94 @@ shade_texture_span(GLcontext *ctx, SWspan *span) } +/** Put colors at x/y locations into a renderbuffer */ +static void +put_values(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLenum datatype, + GLuint count, const GLint x[], const GLint y[], + const void *values, const GLubyte *mask) +{ + mesa_pack_ubyte_rgba_func pack_ubyte = NULL; + mesa_pack_float_rgba_func pack_float = NULL; + GLuint i; + + if (datatype == GL_UNSIGNED_BYTE) + pack_ubyte = _mesa_get_pack_ubyte_rgba_function(rb->Format); + else + pack_float = _mesa_get_pack_float_rgba_function(rb->Format); + + for (i = 0; i < count; i++) { + if (mask[i]) { + GLubyte *dst = _swrast_pixel_address(rb, x[i], y[i]); + + if (datatype == GL_UNSIGNED_BYTE) { + pack_ubyte((const GLubyte *) values + 4 * i, dst); + } + else { + assert(datatype == GL_FLOAT); + pack_float((const GLfloat *) values + 4 * i, dst); + } + } + } +} + + +/** Put row of colors into renderbuffer */ +void +_swrast_put_row(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLenum datatype, + GLuint count, GLint x, GLint y, + const void *values, const GLubyte *mask) +{ + GLubyte *dst = _swrast_pixel_address(rb, x, y); + + if (!mask) { + if (datatype == GL_UNSIGNED_BYTE) { + _mesa_pack_ubyte_rgba_row(rb->Format, count, + (const GLubyte (*)[4]) values, dst); + } + else { + assert(datatype == GL_FLOAT); + _mesa_pack_float_rgba_row(rb->Format, count, + (const GLfloat (*)[4]) values, dst); + } + } + else { + const GLuint bpp = _mesa_get_format_bytes(rb->Format); + GLuint i, runLen, runStart; + /* We can't pass a 'mask' array to the _mesa_pack_rgba_row() functions + * so look for runs where mask=1... + */ + runLen = runStart = 0; + for (i = 0; i < count; i++) { + if (mask[i]) { + if (runLen == 0) + runStart = i; + runLen++; + } + + if (!mask[i] || i == count - 1) { + /* might be the end of a run of pixels */ + if (runLen > 0) { + if (datatype == GL_UNSIGNED_BYTE) { + _mesa_pack_ubyte_rgba_row(rb->Format, runLen, + (const GLubyte (*)[4]) values + runStart, + dst + runStart * bpp); + } + else { + assert(datatype == GL_FLOAT); + _mesa_pack_float_rgba_row(rb->Format, runLen, + (const GLfloat (*)[4]) values + runStart, + dst + runStart * bpp); + } + runLen = 0; + } + } + } + } +} + + /** * Apply all the per-fragment operations to a span. @@ -1029,26 +1131,25 @@ shade_texture_span(GLcontext *ctx, SWspan *span) * to their original values before returning. */ void -_swrast_write_rgba_span( GLcontext *ctx, SWspan *span) +_swrast_write_rgba_span( struct gl_context *ctx, SWspan *span) { const SWcontext *swrast = SWRAST_CONTEXT(ctx); - const GLuint *colorMask = (GLuint *) ctx->Color.ColorMask; const GLbitfield origInterpMask = span->interpMask; const GLbitfield origArrayMask = span->arrayMask; - const GLbitfield origArrayAttribs = span->arrayAttribs; + const GLbitfield64 origArrayAttribs = span->arrayAttribs; const GLenum origChanType = span->array->ChanType; void * const origRgba = span->array->rgba; - const GLboolean shader = (ctx->FragmentProgram._Current - || ctx->ATIFragmentShader._Enabled); + const GLboolean shader = (_swrast_use_fragment_program(ctx) + || _mesa_ati_fragment_shader_enabled(ctx)); const GLboolean shaderOrTexture = shader || ctx->Texture._EnabledCoordUnits; struct gl_framebuffer *fb = ctx->DrawBuffer; /* - printf("%s() interp 0x%x array 0x%x\n", __FUNCTION__, + printf("%s() interp 0x%x array 0x%x\n", __func__, span->interpMask, span->arrayMask); */ - ASSERT(span->primitive == GL_POINT || + assert(span->primitive == GL_POINT || span->primitive == GL_LINE || span->primitive == GL_POLYGON || span->primitive == GL_BITMAP); @@ -1068,7 +1169,7 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) return; } - ASSERT(span->end <= MAX_WIDTH); + assert(span->end <= SWRAST_MAX_WIDTH); /* Depth bounds test */ if (ctx->Depth.BoundsTest && fb->Visual.depthBits > 0) { @@ -1114,14 +1215,14 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) } /* Stencil and Z testing */ - if (ctx->Stencil._Enabled || ctx->Depth.Test) { + if (_mesa_stencil_is_enabled(ctx) || ctx->Depth.Test) { if (!(span->arrayMask & SPAN_Z)) _swrast_span_interpolate_z(ctx, span); - if (ctx->Transform.DepthClamp) + if (ctx->Transform.DepthClampNear && ctx->Transform.DepthClampFar) _swrast_depth_clamp_span(ctx, span); - if (ctx->Stencil._Enabled) { + if (_mesa_stencil_is_enabled(ctx)) { /* Combined Z/stencil tests */ if (!_swrast_stencil_and_ztest_span(ctx, span)) { /* all fragments failed test */ @@ -1130,8 +1231,8 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) } else if (fb->Visual.depthBits > 0) { /* Just regular depth testing */ - ASSERT(ctx->Depth.Test); - ASSERT(span->arrayMask & SPAN_Z); + assert(ctx->Depth.Test); + assert(span->arrayMask & SPAN_Z); if (!_swrast_depth_test_span(ctx, span)) { /* all fragments failed test */ goto end; @@ -1150,7 +1251,8 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) /* We had to wait until now to check for glColorMask(0,0,0,0) because of * the occlusion test. */ - if (fb->_NumColorDrawBuffers == 1 && colorMask[0] == 0x0) { + if (fb->_NumColorDrawBuffers == 1 && + !GET_COLORMASK(ctx->Color.ColorMask, 0)) { /* no colors to write */ goto end; } @@ -1164,8 +1266,8 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) } #if CHAN_BITS == 32 - if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) { - interpolate_active_attribs(ctx, span, FRAG_BIT_COL0); + if ((span->arrayAttribs & VARYING_BIT_COL0) == 0) { + interpolate_active_attribs(ctx, span, VARYING_BIT_COL0); } #else if ((span->arrayMask & SPAN_RGBA) == 0) { @@ -1173,7 +1275,7 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) } #endif - ASSERT(span->arrayMask & SPAN_RGBA); + assert(span->arrayMask & SPAN_RGBA); if (span->primitive == GL_BITMAP || !swrast->SpecularVertexAdd) { /* Add primary and specular (diffuse + specular) colors */ @@ -1211,9 +1313,12 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) */ { const GLuint numBuffers = fb->_NumColorDrawBuffers; - const struct gl_fragment_program *fp = ctx->FragmentProgram._Current; - const GLboolean multiFragOutputs = - (fp && fp->Base.OutputsWritten >= (1 << FRAG_RESULT_DATA0)); + const struct gl_program *fp = ctx->FragmentProgram._Current; + const GLboolean multiFragOutputs = + _swrast_use_fragment_program(ctx) + && fp->info.outputs_written >= (1 << FRAG_RESULT_DATA0); + /* Save srcColorType because convert_color_type() can change it */ + const GLenum srcColorType = span->array->ChanType; GLuint buf; for (buf = 0; buf < numBuffers; buf++) { @@ -1222,23 +1327,26 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) /* color[fragOutput] will be written to buffer[buf] */ if (rb) { - GLchan rgbaSave[MAX_WIDTH][4]; - const GLuint fragOutput = multiFragOutputs ? buf : 0; - - /* set span->array->rgba to colors for render buffer's datatype */ - if (rb->DataType != span->array->ChanType || fragOutput > 0) { - convert_color_type(span, rb->DataType, fragOutput); + /* re-use one of the attribute array buffers for rgbaSave */ + GLchan (*rgbaSave)[4] = (GLchan (*)[4]) span->array->attribs[0]; + struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); + const GLenum dstColorType = srb->ColorType; + + assert(dstColorType == GL_UNSIGNED_BYTE || + dstColorType == GL_FLOAT); + + /* set span->array->rgba to colors for renderbuffer's datatype */ + if (srcColorType != dstColorType) { + convert_color_type(span, srcColorType, dstColorType, + multiFragOutputs ? buf : 0); } else { - if (rb->DataType == GL_UNSIGNED_BYTE) { + if (srcColorType == GL_UNSIGNED_BYTE) { span->array->rgba = span->array->rgba8; } - else if (rb->DataType == GL_UNSIGNED_SHORT) { - span->array->rgba = (void *) span->array->rgba16; - } else { span->array->rgba = (void *) - span->array->attribs[FRAG_ATTRIB_COL0]; + span->array->attribs[VARYING_SLOT_COL0]; } } @@ -1248,32 +1356,37 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) 4 * span->end * sizeof(GLchan)); } - ASSERT(rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB); + assert(rb->_BaseFormat == GL_RGBA || + rb->_BaseFormat == GL_RGB || + rb->_BaseFormat == GL_RED || + rb->_BaseFormat == GL_RG || + rb->_BaseFormat == GL_ALPHA); - if (ctx->Color._LogicOpEnabled) { + if (ctx->Color.ColorLogicOpEnabled) { _swrast_logicop_rgba_span(ctx, rb, span); } else if ((ctx->Color.BlendEnabled >> buf) & 1) { _swrast_blend_span(ctx, rb, span); } - if (colorMask[buf] != 0xffffffff) { + if (GET_COLORMASK(ctx->Color.ColorMask, buf) != 0xf) { _swrast_mask_rgba_span(ctx, rb, span, buf); } if (span->arrayMask & SPAN_XY) { /* array of pixel coords */ - ASSERT(rb->PutValues); - rb->PutValues(ctx, rb, span->end, - span->array->x, span->array->y, - span->array->rgba, span->array->mask); + put_values(ctx, rb, + span->array->ChanType, span->end, + span->array->x, span->array->y, + span->array->rgba, span->array->mask); } else { /* horizontal run of pixels */ - ASSERT(rb->PutRow); - rb->PutRow(ctx, rb, span->end, span->x, span->y, - span->array->rgba, - span->writeAll ? NULL: span->array->mask); + _swrast_put_row(ctx, rb, + span->array->ChanType, + span->end, span->x, span->y, + span->array->rgba, + span->writeAll ? NULL: span->array->mask); } if (!multiFragOutputs && numBuffers > 1) { @@ -1297,16 +1410,17 @@ end: /** - * Read RGBA pixels from a renderbuffer. Clipping will be done to prevent - * reading ouside the buffer's boundaries. - * \param dstType datatype for returned colors + * Read float RGBA pixels from a renderbuffer. Clipping will be done to + * prevent reading ouside the buffer's boundaries. * \param rgba the returned colors */ void -_swrast_read_rgba_span( GLcontext *ctx, struct gl_renderbuffer *rb, - GLuint n, GLint x, GLint y, GLenum dstType, +_swrast_read_rgba_span( struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, GLvoid *rgba) { + struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); + GLenum dstType = GL_FLOAT; const GLint bufWidth = (GLint) rb->Width; const GLint bufHeight = (GLint) rb->Height; @@ -1317,6 +1431,8 @@ _swrast_read_rgba_span( GLcontext *ctx, struct gl_renderbuffer *rb, } else { GLint skip, length; + GLubyte *src; + if (x < 0) { /* left edge clipping */ skip = -x; @@ -1344,74 +1460,80 @@ _swrast_read_rgba_span( GLcontext *ctx, struct gl_renderbuffer *rb, length = (GLint) n; } - ASSERT(rb); - ASSERT(rb->GetRow); - ASSERT(rb->_BaseFormat == GL_RGB || rb->_BaseFormat == GL_RGBA); + assert(rb); + assert(rb->_BaseFormat == GL_RGBA || + rb->_BaseFormat == GL_RGB || + rb->_BaseFormat == GL_RG || + rb->_BaseFormat == GL_RED || + rb->_BaseFormat == GL_LUMINANCE || + rb->_BaseFormat == GL_INTENSITY || + rb->_BaseFormat == GL_LUMINANCE_ALPHA || + rb->_BaseFormat == GL_ALPHA); - if (rb->DataType == dstType) { - rb->GetRow(ctx, rb, length, x + skip, y, - (GLubyte *) rgba + skip * RGBA_PIXEL_SIZE(rb->DataType)); + assert(srb->Map); + (void) srb; /* silence unused var warning */ + + src = _swrast_pixel_address(rb, x + skip, y); + + if (dstType == GL_UNSIGNED_BYTE) { + _mesa_unpack_ubyte_rgba_row(rb->Format, length, src, + (GLubyte (*)[4]) rgba + skip); + } + else if (dstType == GL_FLOAT) { + _mesa_unpack_rgba_row(rb->Format, length, src, + (GLfloat (*)[4]) rgba + skip); } else { - GLuint temp[MAX_WIDTH * 4]; - rb->GetRow(ctx, rb, length, x + skip, y, temp); - _mesa_convert_colors(rb->DataType, temp, - dstType, (GLubyte *) rgba + skip * RGBA_PIXEL_SIZE(dstType), - length, NULL); + _mesa_problem(ctx, "unexpected type in _swrast_read_rgba_span()"); } } } /** - * Wrapper for gl_renderbuffer::GetValues() which does clipping to avoid - * reading values outside the buffer bounds. - * We can use this for reading any format/type of renderbuffer. - * \param valueSize is the size in bytes of each value (pixel) put into the - * values array. + * Get colors at x/y positions with clipping. + * \param type type of values to return */ -void -_swrast_get_values(GLcontext *ctx, struct gl_renderbuffer *rb, - GLuint count, const GLint x[], const GLint y[], - void *values, GLuint valueSize) +static void +get_values(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, const GLint x[], const GLint y[], + void *values, GLenum type) { - GLuint i, inCount = 0, inStart = 0; + GLuint i; for (i = 0; i < count; i++) { if (x[i] >= 0 && y[i] >= 0 && x[i] < (GLint) rb->Width && y[i] < (GLint) rb->Height) { /* inside */ - if (inCount == 0) - inStart = i; - inCount++; - } - else { - if (inCount > 0) { - /* read [inStart, inStart + inCount) */ - rb->GetValues(ctx, rb, inCount, x + inStart, y + inStart, - (GLubyte *) values + inStart * valueSize); - inCount = 0; + const GLubyte *src = _swrast_pixel_address(rb, x[i], y[i]); + + if (type == GL_UNSIGNED_BYTE) { + _mesa_unpack_ubyte_rgba_row(rb->Format, 1, src, + (GLubyte (*)[4]) values + i); + } + else if (type == GL_FLOAT) { + _mesa_unpack_rgba_row(rb->Format, 1, src, + (GLfloat (*)[4]) values + i); + } + else { + _mesa_problem(ctx, "unexpected type in get_values()"); } } } - if (inCount > 0) { - /* read last values */ - rb->GetValues(ctx, rb, inCount, x + inStart, y + inStart, - (GLubyte *) values + inStart * valueSize); - } } /** - * Wrapper for gl_renderbuffer::PutRow() which does clipping. - * \param valueSize size of each value (pixel) in bytes + * Get row of colors with clipping. + * \param type type of values to return */ -void -_swrast_put_row(GLcontext *ctx, struct gl_renderbuffer *rb, - GLuint count, GLint x, GLint y, - const GLvoid *values, GLuint valueSize) +static void +get_row(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, GLint x, GLint y, + GLvoid *values, GLenum type) { GLint skip = 0; + GLubyte *src; if (y < 0 || y >= (GLint) rb->Height) return; /* above or below */ @@ -1419,7 +1541,7 @@ _swrast_put_row(GLcontext *ctx, struct gl_renderbuffer *rb, if (x + (GLint) count <= 0 || x >= (GLint) rb->Width) return; /* entirely left or right */ - if ((GLint) (x + count) > (GLint) rb->Width) { + if (x + count > rb->Width) { /* right clip */ GLint clip = x + count - rb->Width; count -= clip; @@ -1432,42 +1554,19 @@ _swrast_put_row(GLcontext *ctx, struct gl_renderbuffer *rb, count -= skip; } - rb->PutRow(ctx, rb, count, x, y, - (const GLubyte *) values + skip * valueSize, NULL); -} - - -/** - * Wrapper for gl_renderbuffer::GetRow() which does clipping. - * \param valueSize size of each value (pixel) in bytes - */ -void -_swrast_get_row(GLcontext *ctx, struct gl_renderbuffer *rb, - GLuint count, GLint x, GLint y, - GLvoid *values, GLuint valueSize) -{ - GLint skip = 0; - - if (y < 0 || y >= (GLint) rb->Height) - return; /* above or below */ - - if (x + (GLint) count <= 0 || x >= (GLint) rb->Width) - return; /* entirely left or right */ + src = _swrast_pixel_address(rb, x, y); - if (x + count > rb->Width) { - /* right clip */ - GLint clip = x + count - rb->Width; - count -= clip; + if (type == GL_UNSIGNED_BYTE) { + _mesa_unpack_ubyte_rgba_row(rb->Format, count, src, + (GLubyte (*)[4]) values + skip); } - - if (x < 0) { - /* left clip */ - skip = -x; - x = 0; - count -= skip; + else if (type == GL_FLOAT) { + _mesa_unpack_rgba_row(rb->Format, count, src, + (GLfloat (*)[4]) values + skip); + } + else { + _mesa_problem(ctx, "unexpected type in get_row()"); } - - rb->GetRow(ctx, rb, count, x, y, (GLubyte *) values + skip * valueSize); } @@ -1477,23 +1576,22 @@ _swrast_get_row(GLcontext *ctx, struct gl_renderbuffer *rb, * \return pointer to the colors we read. */ void * -_swrast_get_dest_rgba(GLcontext *ctx, struct gl_renderbuffer *rb, +_swrast_get_dest_rgba(struct gl_context *ctx, struct gl_renderbuffer *rb, SWspan *span) { - const GLuint pixelSize = RGBA_PIXEL_SIZE(span->array->ChanType); void *rbPixels; /* Point rbPixels to a temporary space */ - rbPixels = span->array->attribs[FRAG_ATTRIB_MAX - 1]; + rbPixels = span->array->attribs[VARYING_SLOT_MAX - 1]; /* Get destination values from renderbuffer */ if (span->arrayMask & SPAN_XY) { - _swrast_get_values(ctx, rb, span->end, span->array->x, span->array->y, - rbPixels, pixelSize); + get_values(ctx, rb, span->end, span->array->x, span->array->y, + rbPixels, span->array->ChanType); } else { - _swrast_get_row(ctx, rb, span->end, span->x, span->y, - rbPixels, pixelSize); + get_row(ctx, rb, span->end, span->x, span->y, + rbPixels, span->array->ChanType); } return rbPixels;