s_fragprog.c revision ced6f76404ff1a6713c85edff17551f82c33cc24
1b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru/* 2b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * Mesa 3-D graphics library 3b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * Version: 6.5.2 4b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * 5b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. 6b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * 7b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * Permission is hereby granted, free of charge, to any person obtaining a 8b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * copy of this software and associated documentation files (the "Software"), 9b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * to deal in the Software without restriction, including without limitation 10b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * and/or sell copies of the Software, and to permit persons to whom the 12b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * Software is furnished to do so, subject to the following conditions: 13b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * 14b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * The above copyright notice and this permission notice shall be included 15b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * in all copies or substantial portions of the Software. 16b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * 17b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru */ 24b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 25b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "glheader.h" 26b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "colormac.h" 27b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "context.h" 28b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "prog_instruction.h" 29b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 30b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "s_fragprog.h" 31b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "s_span.h" 32b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 33b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 34b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru/** 35b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * Fetch a texel. 36b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru */ 37b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void 38b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querufetch_texel( GLcontext *ctx, const GLfloat texcoord[4], GLfloat lambda, 39b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru GLuint unit, GLfloat color[4] ) 40b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru{ 41b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru GLchan rgba[4]; 42b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru SWcontext *swrast = SWRAST_CONTEXT(ctx); 43b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 44b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* XXX use a float-valued TextureSample routine here!!! */ 45b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru swrast->TextureSample[unit](ctx, ctx->Texture.Unit[unit]._Current, 46b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1, (const GLfloat (*)[4]) texcoord, 47b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru &lambda, &rgba); 48b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru color[0] = CHAN_TO_FLOAT(rgba[0]); 49b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru color[1] = CHAN_TO_FLOAT(rgba[1]); 50b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru color[2] = CHAN_TO_FLOAT(rgba[2]); 51b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru color[3] = CHAN_TO_FLOAT(rgba[3]); 52b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 53b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 54b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 55b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru/** 56b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * Fetch a texel with the given partial derivatives to compute a level 57b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * of detail in the mipmap. 58b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru */ 59b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void 60b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querufetch_texel_deriv( GLcontext *ctx, const GLfloat texcoord[4], 61b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const GLfloat texdx[4], const GLfloat texdy[4], 62b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru GLuint unit, GLfloat color[4] ) 63b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru{ 64b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru SWcontext *swrast = SWRAST_CONTEXT(ctx); 65b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current; 66b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const struct gl_texture_image *texImg = texObj->Image[0][texObj->BaseLevel]; 67b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const GLfloat texW = (GLfloat) texImg->WidthScale; 68b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const GLfloat texH = (GLfloat) texImg->HeightScale; 69b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru GLchan rgba[4]; 70b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 71b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru GLfloat lambda = _swrast_compute_lambda(texdx[0], texdy[0], /* ds/dx, ds/dy */ 72b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru texdx[1], texdy[1], /* dt/dx, dt/dy */ 73b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru texdx[3], texdy[2], /* dq/dx, dq/dy */ 74b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru texW, texH, 75b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru texcoord[0], texcoord[1], texcoord[3], 76b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1.0F / texcoord[3]); 77b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 78b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru swrast->TextureSample[unit](ctx, ctx->Texture.Unit[unit]._Current, 79b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1, (const GLfloat (*)[4]) texcoord, 80b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru &lambda, &rgba); 81b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru color[0] = CHAN_TO_FLOAT(rgba[0]); 82b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru color[1] = CHAN_TO_FLOAT(rgba[1]); 83b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru color[2] = CHAN_TO_FLOAT(rgba[2]); 84b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru color[3] = CHAN_TO_FLOAT(rgba[3]); 85b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 86b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 87b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 88b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru/** 89b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * Initialize the virtual fragment program machine state prior to running 90b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * fragment program on a fragment. This involves initializing the input 91b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * registers, condition codes, etc. 92b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * \param machine the virtual machine state to init 93b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * \param program the fragment program we're about to run 94b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * \param span the span of pixels we'll operate on 95b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * \param col which element (column) of the span we'll operate on 96b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru */ 97b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void 98b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruinit_machine(GLcontext *ctx, struct gl_program_machine *machine, 99b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const struct gl_fragment_program *program, 100b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const SWspan *span, GLuint col) 101b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru{ 102b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru GLuint inputsRead = program->Base.InputsRead; 103b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 104b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (ctx->FragmentProgram.CallbackEnabled) 105b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru inputsRead = ~0; 106b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 107b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (program->Base.Target == GL_FRAGMENT_PROGRAM_NV) { 108b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* Clear temporary registers (undefined for ARB_f_p) */ 109b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru _mesa_bzero(machine->Temporaries, 110b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru MAX_PROGRAM_TEMPS * 4 * sizeof(GLfloat)); 111b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 112b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 113b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* Setup pointer to input attributes */ 114b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru machine->Attribs = span->array->attribs; 115b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 116b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* Store front/back facing value in register FOGC.Y */ 117b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru machine->Attribs[FRAG_ATTRIB_FOGC][col][1] = (GLfloat) ctx->_Facing; 118b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 119b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru machine->CurElement = col; 120b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 121b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* init condition codes */ 122b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru machine->CondCodes[0] = COND_EQ; 123b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru machine->CondCodes[1] = COND_EQ; 124b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru machine->CondCodes[2] = COND_EQ; 125b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru machine->CondCodes[3] = COND_EQ; 126b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 127b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* init call stack */ 128b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru machine->StackDepth = 0; 129b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 130b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru machine->FetchTexelLod = fetch_texel; 131b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru machine->FetchTexelDeriv = fetch_texel_deriv; 132b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 133b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 134b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 135b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru/** 136b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * Run fragment program on the pixels in span from 'start' to 'end' - 1. 137b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru */ 138b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void 139b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querurun_program(GLcontext *ctx, SWspan *span, GLuint start, GLuint end) 140b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru{ 141b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru SWcontext *swrast = SWRAST_CONTEXT(ctx); 142b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const struct gl_fragment_program *program = ctx->FragmentProgram._Current; 143b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const GLbitfield outputsWritten = program->Base.OutputsWritten; 144b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru struct gl_program_machine *machine = &swrast->FragProgMachine; 145b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru GLuint i; 146b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 147b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru for (i = start; i < end; i++) { 148b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (span->array->mask[i]) { 149b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru init_machine(ctx, machine, program, span, i); 150b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 151b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (_mesa_execute_program(ctx, &program->Base, machine)) { 152b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 153b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* Store result color */ 154b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (outputsWritten & (1 << FRAG_RESULT_COLR)) { 155b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0][i], 156b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru machine->Outputs[FRAG_RESULT_COLR]); 157b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 158b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru else { 159b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* Multiple drawbuffers / render targets 160b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * Note that colors beyond 0 and 1 will overwrite other 161b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * attributes, such as FOGC, TEX0, TEX1, etc. That's OK. 162b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru */ 163b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru GLuint output; 164b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru for (output = 0; output < swrast->_NumColorOutputs; output++) { 165b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (outputsWritten & (1 << (FRAG_RESULT_DATA0 + output))) { 166b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0+output][i], 167b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru machine->Outputs[FRAG_RESULT_DATA0 + output]); 168b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 169b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 170b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 171b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 172b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* Store result depth/z */ 173b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (outputsWritten & (1 << FRAG_RESULT_DEPR)) { 174b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const GLfloat depth = machine->Outputs[FRAG_RESULT_DEPR][2]; 175b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (depth <= 0.0) 176b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru span->array->z[i] = 0; 177b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru else if (depth >= 1.0) 178b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru span->array->z[i] = ctx->DrawBuffer->_DepthMax; 179 else 180 span->array->z[i] = IROUND(depth * ctx->DrawBuffer->_DepthMaxF); 181 } 182 } 183 else { 184 /* killed fragment */ 185 span->array->mask[i] = GL_FALSE; 186 span->writeAll = GL_FALSE; 187 } 188 } 189 } 190} 191 192 193/** 194 * Execute the current fragment program for all the fragments 195 * in the given span. 196 */ 197void 198_swrast_exec_fragment_program( GLcontext *ctx, SWspan *span ) 199{ 200 const struct gl_fragment_program *program = ctx->FragmentProgram._Current; 201 202 /* incoming colors should be floats */ 203 if (program->Base.InputsRead & FRAG_BIT_COL0) { 204 ASSERT(span->array->ChanType == GL_FLOAT); 205 } 206 207 ctx->_CurrentProgram = GL_FRAGMENT_PROGRAM_ARB; /* or NV, doesn't matter */ 208 209 run_program(ctx, span, 0, span->end); 210 211 if (program->Base.OutputsWritten & (1 << FRAG_RESULT_COLR)) { 212 span->interpMask &= ~SPAN_RGBA; 213 span->arrayMask |= SPAN_RGBA; 214 } 215 216 if (program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) { 217 span->interpMask &= ~SPAN_Z; 218 span->arrayMask |= SPAN_Z; 219 } 220 221 ctx->_CurrentProgram = 0; 222} 223 224