/** * Apply texture mapping to a span of fragments. */ void _swrast_texture_span( struct gl_context *ctx, SWspan *span ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); float4_array primary_rgba; if (!swrast->TexelBuffer) { #ifdef _OPENMP const GLint maxThreads = omp_get_max_threads(); #else const GLint maxThreads = 1; #endif /* TexelBuffer is also global and normally shared by all SWspan * instances; when running with multiple threads, create one per * thread. */ swrast->TexelBuffer = (GLfloat *) MALLOC(maxThreads * MAX_WIDTH * 4 * sizeof(GLfloat)); if (!swrast->TexelBuffer) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture_combine"); return; } } primary_rgba = (float4_array) malloc(span->end * 4 * sizeof(GLfloat)); if (!primary_rgba) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture_span"); return; } ASSERT(span->end <= MAX_WIDTH); /* * Save copy of the incoming fragment colors (the GL_PRIMARY_COLOR) */ if (swrast->_TextureCombinePrimary) { GLuint i; for (i = 0; i < span->end; i++) { primary_rgba[i][RCOMP] = CHAN_TO_FLOAT(span->array->rgba[i][RCOMP]); primary_rgba[i][GCOMP] = CHAN_TO_FLOAT(span->array->rgba[i][GCOMP]); primary_rgba[i][BCOMP] = CHAN_TO_FLOAT(span->array->rgba[i][BCOMP]); primary_rgba[i][ACOMP] = CHAN_TO_FLOAT(span->array->rgba[i][ACOMP]); } } /* * Must do all texture sampling before combining in order to * accomodate GL_ARB_texture_env_crossbar. */ { const struct gl_texture_unit *texUnit = &ctx->Texture.Unit; if (texUnit->_ReallyEnabled) { const GLfloat (*texcoords)[4] = (const GLfloat (*)[4]) span->array->attribs[FRAG_ATTRIB_TEX]; const struct gl_texture_object *curObj = texUnit->_Current; GLfloat *lambda = span->array->lambda; float4_array texels = get_texel_array(swrast); if (curObj->Sampler.MaxAnisotropy > 1.0 && curObj->Sampler.MinFilter == GL_LINEAR_MIPMAP_LINEAR) { /* sample_lambda_2d_aniso is beeing used as texture_sample_func, * it requires the current SWspan *span as an additional parameter. * In order to keep the same function signature, the unused lambda * parameter will be modified to actually contain the SWspan pointer. * This is a Hack. To make it right, the texture_sample_func * signature and all implementing functions need to be modified. */ /* "hide" SWspan struct; cast to (GLfloat *) to suppress warning */ lambda = (GLfloat *)span; } /* Sample the texture (span->end = number of fragments) */ swrast->TextureSample( ctx, texUnit->_Current, span->end, texcoords, lambda, texels ); } } /* * OK, now apply the texture (aka texture combine/blend). * We modify the span->color.rgba values. */ if (ctx->Texture.Unit._ReallyEnabled) texture_combine(ctx, primary_rgba, swrast->TexelBuffer, span); free(primary_rgba); }