diff options
Diffstat (limited to 'src/mesa/swrast/s_fragprog.c')
-rw-r--r-- | src/mesa/swrast/s_fragprog.c | 114 |
1 files changed, 77 insertions, 37 deletions
diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index 8eeb40f7c5..c6601f5593 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -33,6 +33,35 @@ /** + * Apply texture object's swizzle (X/Y/Z/W/0/1) to incoming 'texel' + * and return results in 'colorOut'. + */ +static INLINE void +swizzle_texel(const GLchan texel[4], GLfloat colorOut[4], GLuint swizzle) +{ + if (swizzle == SWIZZLE_NOOP) { + colorOut[0] = CHAN_TO_FLOAT(texel[0]); + colorOut[1] = CHAN_TO_FLOAT(texel[1]); + colorOut[2] = CHAN_TO_FLOAT(texel[2]); + colorOut[3] = CHAN_TO_FLOAT(texel[3]); + } + else { + GLfloat vector[6]; + vector[SWIZZLE_X] = CHAN_TO_FLOAT(texel[0]); + vector[SWIZZLE_Y] = CHAN_TO_FLOAT(texel[1]); + vector[SWIZZLE_Z] = CHAN_TO_FLOAT(texel[2]); + vector[SWIZZLE_W] = CHAN_TO_FLOAT(texel[3]); + vector[SWIZZLE_ZERO] = 0.0F; + vector[SWIZZLE_ONE] = 1.0F; + colorOut[0] = vector[GET_SWZ(swizzle, 0)]; + colorOut[1] = vector[GET_SWZ(swizzle, 1)]; + colorOut[2] = vector[GET_SWZ(swizzle, 2)]; + colorOut[3] = vector[GET_SWZ(swizzle, 3)]; + } +} + + +/** * Fetch a texel with given lod. * Called via machine->FetchTexelLod() */ @@ -40,19 +69,23 @@ static void fetch_texel_lod( GLcontext *ctx, const GLfloat texcoord[4], GLfloat lambda, GLuint unit, GLfloat color[4] ) { - GLchan rgba[4]; - SWcontext *swrast = SWRAST_CONTEXT(ctx); const struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current; - lambda = CLAMP(lambda, texObj->MinLod, texObj->MaxLod); + if (texObj) { + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLchan rgba[4]; + + lambda = CLAMP(lambda, texObj->MinLod, texObj->MaxLod); - /* XXX use a float-valued TextureSample routine here!!! */ - swrast->TextureSample[unit](ctx, texObj, 1, (const GLfloat (*)[4]) texcoord, - &lambda, &rgba); - color[0] = CHAN_TO_FLOAT(rgba[0]); - color[1] = CHAN_TO_FLOAT(rgba[1]); - color[2] = CHAN_TO_FLOAT(rgba[2]); - color[3] = CHAN_TO_FLOAT(rgba[3]); + /* XXX use a float-valued TextureSample routine here!!! */ + swrast->TextureSample[unit](ctx, texObj, 1, + (const GLfloat (*)[4]) texcoord, + &lambda, &rgba); + swizzle_texel(rgba, color, texObj->_Swizzle); + } + else { + ASSIGN_4V(color, 0.0F, 0.0F, 0.0F, 1.0F); + } } @@ -68,27 +101,33 @@ fetch_texel_deriv( GLcontext *ctx, const GLfloat texcoord[4], { SWcontext *swrast = SWRAST_CONTEXT(ctx); const struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current; - const struct gl_texture_image *texImg = texObj->Image[0][texObj->BaseLevel]; - const GLfloat texW = (GLfloat) texImg->WidthScale; - const GLfloat texH = (GLfloat) texImg->HeightScale; - GLchan rgba[4]; - - GLfloat lambda - = _swrast_compute_lambda(texdx[0], texdy[0], /* ds/dx, ds/dy */ - texdx[1], texdy[1], /* dt/dx, dt/dy */ - texdx[3], texdy[2], /* dq/dx, dq/dy */ - texW, texH, - texcoord[0], texcoord[1], texcoord[3], - 1.0F / texcoord[3]) + lodBias; - - lambda = CLAMP(lambda, texObj->MinLod, texObj->MaxLod); - - swrast->TextureSample[unit](ctx, texObj, 1, (const GLfloat (*)[4]) texcoord, - &lambda, &rgba); - color[0] = CHAN_TO_FLOAT(rgba[0]); - color[1] = CHAN_TO_FLOAT(rgba[1]); - color[2] = CHAN_TO_FLOAT(rgba[2]); - color[3] = CHAN_TO_FLOAT(rgba[3]); + + if (texObj) { + const struct gl_texture_image *texImg = + texObj->Image[0][texObj->BaseLevel]; + const GLfloat texW = (GLfloat) texImg->WidthScale; + const GLfloat texH = (GLfloat) texImg->HeightScale; + GLfloat lambda; + GLchan rgba[4]; + + lambda = _swrast_compute_lambda(texdx[0], texdy[0], /* ds/dx, ds/dy */ + texdx[1], texdy[1], /* dt/dx, dt/dy */ + texdx[3], texdy[2], /* dq/dx, dq/dy */ + texW, texH, + texcoord[0], texcoord[1], texcoord[3], + 1.0F / texcoord[3]) + lodBias; + + lambda = CLAMP(lambda, texObj->MinLod, texObj->MaxLod); + + /* XXX use a float-valued TextureSample routine here!!! */ + swrast->TextureSample[unit](ctx, texObj, 1, + (const GLfloat (*)[4]) texcoord, + &lambda, &rgba); + swizzle_texel(rgba, color, texObj->_Swizzle); + } + else { + ASSIGN_4V(color, 0.0F, 0.0F, 0.0F, 1.0F); + } } @@ -124,7 +163,8 @@ init_machine(GLcontext *ctx, struct gl_program_machine *machine, /* if running a GLSL program (not ARB_fragment_program) */ if (ctx->Shader.CurrentProgram) { /* Store front/back facing value in register FOGC.Y */ - machine->Attribs[FRAG_ATTRIB_FOGC][col][1] = (GLfloat) ctx->_Facing; + machine->Attribs[FRAG_ATTRIB_FOGC][col][1] = 1.0 - span->facing; + /* Note FOGC.ZW is gl_PointCoord if drawing a sprite */ } machine->CurElement = col; @@ -171,11 +211,11 @@ run_program(GLcontext *ctx, SWspan *span, GLuint start, GLuint end) * Note that colors beyond 0 and 1 will overwrite other * attributes, such as FOGC, TEX0, TEX1, etc. That's OK. */ - GLuint output; - for (output = 0; output < swrast->_NumColorOutputs; output++) { - if (outputsWritten & (1 << (FRAG_RESULT_DATA0 + output))) { - COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0+output][i], - machine->Outputs[FRAG_RESULT_DATA0 + output]); + GLuint buf; + for (buf = 0; buf < ctx->DrawBuffer->_NumColorDrawBuffers; buf++) { + if (outputsWritten & (1 << (FRAG_RESULT_DATA0 + buf))) { + COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0 + buf][i], + machine->Outputs[FRAG_RESULT_DATA0 + buf]); } } } |