X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fswrast%2Fs_span.c;h=3d3ec57d3977310d66b5fd1179f085109a55cf6e;hb=267fb178844d3f17503dd0f921791f3ab059c4e7;hp=687c8eb0bf86da0bd12948919a5e01d1704e296d;hpb=a8ea1dacc63ac567498049e5756c247b9fec6cd9;p=mesa.git diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index 687c8eb0bf8..3d3ec57d397 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -33,7 +33,6 @@ #include "main/glheader.h" #include "main/colormac.h" -#include "main/context.h" #include "main/macros.h" #include "main/imports.h" #include "main/image.h" @@ -51,6 +50,7 @@ #include "s_stencil.h" #include "s_texcombine.h" +#include /** * Set default fragment attributes for the span using the @@ -58,7 +58,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*/ @@ -163,8 +163,9 @@ _swrast_span_default_attribs(GLcontext *ctx, SWspan *span) * Perspective correction will be done. The point/line/triangle function * should have computed attrStart/Step values for FRAG_ATTRIB_WPOS[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); @@ -175,7 +176,7 @@ interpolate_active_attribs(GLcontext *ctx, SWspan *span, GLbitfield attrMask) attrMask &= ~span->arrayAttribs; ATTRIB_LOOP_BEGIN - if (attrMask & (1 << attr)) { + if (attrMask & BITFIELD64_BIT(attr)) { const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; const GLfloat dv0dx = span->attrStepX[attr][0]; @@ -199,8 +200,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 } @@ -210,13 +211,13 @@ 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)); #endif @@ -300,7 +301,8 @@ interpolate_int_colors(GLcontext *ctx, SWspan *span) interpolate_active_attribs(ctx, span, FRAG_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; } @@ -309,7 +311,7 @@ interpolate_int_colors(GLcontext *ctx, SWspan *span) /** * Populate the FRAG_ATTRIB_COL0 array. */ -static INLINE void +static inline void interpolate_float_colors(SWspan *span) { GLfloat (*col0)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; @@ -371,7 +373,7 @@ 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; @@ -461,7 +463,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; @@ -490,10 +492,20 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) if (obj) { const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel]; - needLambda = (obj->MinFilter != obj->MagFilter) + const struct swrast_texture_image *swImg = + swrast_texture_image_const(img); + + needLambda = (obj->Sampler.MinFilter != obj->Sampler.MagFilter) || ctx->FragmentProgram._Current; - texW = img->WidthScale; - texH = img->HeightScale; + /* LOD is calculated directly in the ansiotropic filter, we can + * skip the normal lambda function as the result is ignored. + */ + if (obj->Sampler.MaxAnisotropy > 1.0 && + obj->Sampler.MinFilter == GL_LINEAR_MIPMAP_LINEAR) { + needLambda = GL_FALSE; + } + texW = swImg->WidthScale; + texH = swImg->HeightScale; } else { /* using a fragment program */ @@ -601,8 +613,8 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) /** * Fill in the arrays->attribs[FRAG_ATTRIB_WPOS] 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]; GLuint i; @@ -635,8 +647,8 @@ 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; @@ -680,8 +692,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; @@ -697,11 +709,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 { @@ -709,9 +723,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 */ @@ -763,7 +778,7 @@ 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)) { @@ -807,8 +822,8 @@ clip_span( GLcontext *ctx, SWspan *span ) * Only called during fixed-function operation. * Result is float color array (FRAG_ATTRIB_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; @@ -856,7 +871,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; @@ -890,7 +905,7 @@ 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]; @@ -911,7 +926,7 @@ 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 +static inline void convert_color_type(SWspan *span, GLenum newType, GLuint output) { GLvoid *src, *dst; @@ -951,26 +966,37 @@ 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; - } + /* This is a hack to work around drivers such as i965 that: + * + * - Set _MaintainTexEnvProgram to generate GLSL IR for + * fixed-function fragment processing. + * - Don't call _mesa_ir_link_shader to generate Mesa IR from + * the GLSL IR. + * - May use swrast to handle glDrawPixels. + * + * Since _mesa_ir_link_shader is never called, there is no Mesa IR + * to execute. Instead do regular fixed-function processing. + * + * It is also worth noting that the software fixed-function path is + * much faster than the software shader path. + */ + const bool use_fragment_program = + ctx->FragmentProgram._Current + && ctx->FragmentProgram._Current != ctx->FragmentProgram._TexEnvProgram; - if (ctx->FragmentProgram._Current || + if (use_fragment_program || ctx->ATIFragmentShader._Enabled) { /* programmable shading */ if (span->primitive == GL_BITMAP && span->array->ChanType != GL_FLOAT) { convert_color_type(span, GL_FLOAT, 0); } + else { + span->array->rgba = (void *) span->array->attribs[FRAG_ATTRIB_COL0]; + } + if (span->primitive != GL_POINT || (span->interpMask & SPAN_RGBA) || ctx->Point.PointSprite) { @@ -990,7 +1016,7 @@ shade_texture_span(GLcontext *ctx, SWspan *span) interpolate_wpos(ctx, span); /* Run fragment program/shader now */ - if (ctx->FragmentProgram._Current) { + if (use_fragment_program) { _swrast_exec_fragment_program(ctx, span); } else { @@ -1026,13 +1052,13 @@ 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 @@ -1222,9 +1248,22 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) 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); } + else { + if (rb->DataType == 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]; + } + } if (!multiFragOutputs && numBuffers > 1) { /* save colors for second, third renderbuffer writes */ @@ -1232,9 +1271,13 @@ _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) { @@ -1281,16 +1324,16 @@ 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) { + GLenum dstType = GL_FLOAT; const GLint bufWidth = (GLint) rb->Width; const GLint bufHeight = (GLint) rb->Height; @@ -1330,7 +1373,14 @@ _swrast_read_rgba_span( GLcontext *ctx, struct gl_renderbuffer *rb, ASSERT(rb); ASSERT(rb->GetRow); - ASSERT(rb->_BaseFormat == GL_RGB || rb->_BaseFormat == GL_RGBA); + 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, @@ -1355,7 +1405,7 @@ _swrast_read_rgba_span( GLcontext *ctx, struct gl_renderbuffer *rb, * values array. */ void -_swrast_get_values(GLcontext *ctx, struct gl_renderbuffer *rb, +_swrast_get_values(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, const GLint x[], const GLint y[], void *values, GLuint valueSize) { @@ -1386,47 +1436,12 @@ _swrast_get_values(GLcontext *ctx, struct gl_renderbuffer *rb, } -/** - * Wrapper for gl_renderbuffer::PutRow() which does clipping. - * \param valueSize size of each value (pixel) in bytes - */ -void -_swrast_put_row(GLcontext *ctx, struct gl_renderbuffer *rb, - GLuint count, GLint x, GLint y, - const 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 */ - - if ((GLint) (x + count) > (GLint) rb->Width) { - /* right clip */ - GLint clip = x + count - rb->Width; - count -= clip; - } - - if (x < 0) { - /* left clip */ - skip = -x; - x = 0; - 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, +_swrast_get_row(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, GLint x, GLint y, GLvoid *values, GLuint valueSize) { @@ -1461,7 +1476,7 @@ _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);