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