/**
 * Compute point size for each vertex from the vertex eye-space Z
 * coordinate and the point size attenuation factors.
 * Only done when point size attenuation is enabled and vertex program is
 * disabled.
 */
static GLboolean
run_point_stage(struct gl_context *ctx, struct tnl_pipeline_stage *stage)
{
   if (ctx->Point._Attenuated && !ctx->VertexProgram._Current) {
      struct point_stage_data *store = POINT_STAGE_DATA(stage);
      struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
      const GLfloat *eyeCoord = (GLfloat *) VB->EyePtr->data + 2;
      const GLint eyeCoordStride = VB->EyePtr->stride / sizeof(GLfloat);
      const GLfloat p0 = ctx->Point.Params[0];
      const GLfloat p1 = ctx->Point.Params[1];
      const GLfloat p2 = ctx->Point.Params[2];
      const GLfloat pointSize = ctx->Point.Size;
      GLfloat (*size)[4] = store->PointSize.data;
      GLuint i;

      for (i = 0; i < VB->Count; i++) {
         const GLfloat dist = FABSF(*eyeCoord);
         const GLfloat q = p0 + dist * (p1 + dist * p2);
         const GLfloat atten = (q != 0.0F) ? INV_SQRTF(q) : 1.0F;
         size[i][0] = pointSize * atten; /* clamping done in rasterization */
         eyeCoord += eyeCoordStride;
      }

      VB->AttribPtr[_TNL_ATTRIB_POINTSIZE] = &store->PointSize;
   }

   return GL_TRUE;
}
Beispiel #2
0
/**
 * Compute per-vertex fog blend factors from fog coordinates by
 * evaluating the GL_LINEAR, GL_EXP or GL_EXP2 fog function.
 * Fog coordinates are distances from the eye (typically between the
 * near and far clip plane distances).
 * Note the fog (eye Z) coords may be negative so we use ABS(z) below.
 * Fog blend factors are in the range [0,1].
 */
float
radeonComputeFogBlendFactor( struct gl_context *ctx, GLfloat fogcoord )
{
    GLfloat end  = ctx->Fog.End;
    GLfloat d, temp;
    const GLfloat z = FABSF(fogcoord);

    switch (ctx->Fog.Mode) {
    case GL_LINEAR:
        if (ctx->Fog.Start == ctx->Fog.End)
            d = 1.0F;
        else
            d = 1.0F / (ctx->Fog.End - ctx->Fog.Start);
        temp = (end - z) * d;
        return CLAMP(temp, 0.0F, 1.0F);
        break;
    case GL_EXP:
        d = ctx->Fog.Density;
        NEG_EXP( temp, d * z );
        return temp;
        break;
    case GL_EXP2:
        d = ctx->Fog.Density*ctx->Fog.Density;
        NEG_EXP( temp, d * z * z );
        return temp;
        break;
    default:
        _mesa_problem(ctx, "Bad fog mode in make_fog_coord");
        return 0;
    }
}
Beispiel #3
0
/**
 * Multiply a matrix with a general scaling matrix.
 *
 * \param mat matrix.
 * \param x x axis scale factor.
 * \param y y axis scale factor.
 * \param z z axis scale factor.
 *
 * Multiplies in-place the elements of \p mat by the scale factors. Checks if
 * the scales factors are roughly the same, marking the MAT_FLAG_UNIFORM_SCALE
 * flag, or MAT_FLAG_GENERAL_SCALE. Marks the MAT_DIRTY_TYPE and
 * MAT_DIRTY_INVERSE dirty flags.
 */
void
_math_matrix_scale( GLmatrix *mat, GLfloat x, GLfloat y, GLfloat z )
{
   GLfloat *m = mat->m;
   m[0] *= x;   m[4] *= y;   m[8]  *= z;
   m[1] *= x;   m[5] *= y;   m[9]  *= z;
   m[2] *= x;   m[6] *= y;   m[10] *= z;
   m[3] *= x;   m[7] *= y;   m[11] *= z;

   if (FABSF(x - y) < 1e-8 && FABSF(x - z) < 1e-8)
      mat->flags |= MAT_FLAG_UNIFORM_SCALE;
   else
      mat->flags |= MAT_FLAG_GENERAL_SCALE;

   mat->flags |= (MAT_DIRTY_TYPE |
		  MAT_DIRTY_INVERSE);
}
Beispiel #4
0
/**
 * Compute inverse of a general 3d transformation matrix.
 * 
 * \param mat pointer to a GLmatrix structure. The matrix inverse will be
 * stored in the GLmatrix::inv attribute.
 * 
 * \return GL_TRUE for success, GL_FALSE for failure (\p singular matrix).
 *
 * \author Adapted from graphics gems II.
 *
 * Calculates the inverse of the upper left by first calculating its
 * determinant and multiplying it to the symmetric adjust matrix of each
 * element. Finally deals with the translation part by transforming the
 * original translation vector using by the calculated submatrix inverse.
 */
static GLboolean invert_matrix_3d_general( GLmatrix *mat )
{
   const GLfloat *in = mat->m;
   GLfloat *out = mat->inv;
   GLfloat pos, neg, t;
   GLfloat det;

   /* Calculate the determinant of upper left 3x3 submatrix and
    * determine if the matrix is singular.
    */
   pos = neg = 0.0;
   t =  MAT(in,0,0) * MAT(in,1,1) * MAT(in,2,2);
   if (t >= 0.0) pos += t; else neg += t;

   t =  MAT(in,1,0) * MAT(in,2,1) * MAT(in,0,2);
   if (t >= 0.0) pos += t; else neg += t;

   t =  MAT(in,2,0) * MAT(in,0,1) * MAT(in,1,2);
   if (t >= 0.0) pos += t; else neg += t;

   t = -MAT(in,2,0) * MAT(in,1,1) * MAT(in,0,2);
   if (t >= 0.0) pos += t; else neg += t;

   t = -MAT(in,1,0) * MAT(in,0,1) * MAT(in,2,2);
   if (t >= 0.0) pos += t; else neg += t;

   t = -MAT(in,0,0) * MAT(in,2,1) * MAT(in,1,2);
   if (t >= 0.0) pos += t; else neg += t;

   det = pos + neg;

   if (FABSF(det) < 1e-25)
      return GL_FALSE;

   det = 1.0F / det;
   MAT(out,0,0) = (  (MAT(in,1,1)*MAT(in,2,2) - MAT(in,2,1)*MAT(in,1,2) )*det);
   MAT(out,0,1) = (- (MAT(in,0,1)*MAT(in,2,2) - MAT(in,2,1)*MAT(in,0,2) )*det);
   MAT(out,0,2) = (  (MAT(in,0,1)*MAT(in,1,2) - MAT(in,1,1)*MAT(in,0,2) )*det);
   MAT(out,1,0) = (- (MAT(in,1,0)*MAT(in,2,2) - MAT(in,2,0)*MAT(in,1,2) )*det);
   MAT(out,1,1) = (  (MAT(in,0,0)*MAT(in,2,2) - MAT(in,2,0)*MAT(in,0,2) )*det);
   MAT(out,1,2) = (- (MAT(in,0,0)*MAT(in,1,2) - MAT(in,1,0)*MAT(in,0,2) )*det);
   MAT(out,2,0) = (  (MAT(in,1,0)*MAT(in,2,1) - MAT(in,2,0)*MAT(in,1,1) )*det);
   MAT(out,2,1) = (- (MAT(in,0,0)*MAT(in,2,1) - MAT(in,2,0)*MAT(in,0,1) )*det);
   MAT(out,2,2) = (  (MAT(in,0,0)*MAT(in,1,1) - MAT(in,1,0)*MAT(in,0,1) )*det);

   /* Do the translation part */
   MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0) +
		     MAT(in,1,3) * MAT(out,0,1) +
		     MAT(in,2,3) * MAT(out,0,2) );
   MAT(out,1,3) = - (MAT(in,0,3) * MAT(out,1,0) +
		     MAT(in,1,3) * MAT(out,1,1) +
		     MAT(in,2,3) * MAT(out,1,2) );
   MAT(out,2,3) = - (MAT(in,0,3) * MAT(out,2,0) +
		     MAT(in,1,3) * MAT(out,2,1) +
		     MAT(in,2,3) * MAT(out,2,2) );

   return GL_TRUE;
}
Beispiel #5
0
/**
 * Compute per-vertex fog blend factors from fog coordinates by
 * evaluating the GL_LINEAR, GL_EXP or GL_EXP2 fog function.
 * Fog coordinates are distances from the eye (typically between the
 * near and far clip plane distances).
 * Note the fog (eye Z) coords may be negative so we use ABS(z) below.
 * Fog blend factors are in the range [0,1].
 */
static void
compute_fog_blend_factors(GLcontext *ctx, GLvector4f *out, const GLvector4f *in)
{
   GLfloat end  = ctx->Fog.End;
   GLfloat *v = in->start;
   GLuint stride = in->stride;
   GLuint n = in->count;
   GLfloat (*data)[4] = out->data;
   GLfloat d;
   GLuint i;

   out->count = in->count;

   switch (ctx->Fog.Mode) {
   case GL_LINEAR:
      if (ctx->Fog.Start == ctx->Fog.End)
         d = 1.0F;
      else
         d = 1.0F / (ctx->Fog.End - ctx->Fog.Start);
      for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride)) {
         const GLfloat z = FABSF(*v);
         GLfloat f = (end - z) * d;
	 data[i][0] = CLAMP(f, 0.0F, 1.0F);
      }
      break;
   case GL_EXP:
      d = ctx->Fog.Density;
      for ( i = 0 ; i < n ; i++, STRIDE_F(v,stride)) {
         const GLfloat z = FABSF(*v);
         NEG_EXP( data[i][0], d * z );
      }
      break;
   case GL_EXP2:
      d = ctx->Fog.Density*ctx->Fog.Density;
      for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride)) {
         const GLfloat z = FABSF(*v);
         NEG_EXP( data[i][0], d * z * z );
      }
      break;
   default:
      _mesa_problem(ctx, "Bad fog mode in make_fog_coord");
      return;
   }
}
Beispiel #6
0
GLfloat
_swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
                     GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH,
                     GLfloat s, GLfloat t, GLfloat q, GLfloat invQ)
{
   GLfloat dsdx2 = (s + dsdx) / (q + dqdx) - s * invQ;
   GLfloat dtdx2 = (t + dtdx) / (q + dqdx) - t * invQ;
   GLfloat dsdy2 = (s + dsdy) / (q + dqdy) - s * invQ;
   GLfloat dtdy2 = (t + dtdy) / (q + dqdy) - t * invQ;
   GLfloat maxU, maxV, rho, lambda;
   dsdx2 = FABSF(dsdx2);
   dsdy2 = FABSF(dsdy2);
   dtdx2 = FABSF(dtdx2);
   dtdy2 = FABSF(dtdy2);
   maxU = MAX2(dsdx2, dsdy2) * texW;
   maxV = MAX2(dtdx2, dtdy2) * texH;
   rho = MAX2(maxU, maxV);
   lambda = LOG2(rho);
   return lambda;
}
Beispiel #7
0
DLLEXPORT float rootnf(float x, int y)
{
    int y_odd  = (y&1);
    int y_even = !y_odd;
    int y_neg  = (y<0);
    int x_neg  = (x<0);

    if (y == 0) return NANF;
    if (EXPF(x) == 0)  /* Flush denormalized input to zero */
        return (y > 0) ? 0.0f : (y_even ? INFF : copysign(INFF, x));
    if (y == 1) return x;
    if (ISNEGINFF(x) && y_even) return NANF;
    if (ISINFF(x)) return y_neg ? copysign(0.0f, x) : x;
    if (ISANYZEROF(x) && y_odd && y_neg) return copysign(INFF, x);

    int negresult = 0;
    if (x_neg && y_odd) { negresult = 1; x = FABSF(x); }

    float result =  powf(x, reciprocalf(y));
    if (negresult) result = -result;
    return result;
}
Beispiel #8
0
ENTRYPOINT void
draw_braid(ModeInfo * mi)
{
	Display    *display = MI_DISPLAY(mi);
	Window      window = MI_WINDOW(mi);
	int         num_points = 500;
	float       t_inc;
	float       theta, psi;
	float       t, r_diff;
	int         i, s;
	float       x_1, y_1, x_2, y_2, r1, r2;
	float       color, color_use = 0.0, color_inc;
	braidtype  *braid;

	if (braids == NULL)
		return;
	braid = &braids[MI_SCREEN(mi)];

#ifdef STANDALONE
    if (braid->eraser) {
      braid->eraser = erase_window (MI_DISPLAY(mi), MI_WINDOW(mi), braid->eraser);
      return;
    }
#endif

	MI_IS_DRAWN(mi) = True;
	XSetLineAttributes(display, MI_GC(mi), braid->linewidth,
			   LineSolid,
			   (braid->linewidth <= 3 ? CapButt : CapRound),
			   JoinMiter);

	theta = (2.0 * M_PI) / (float) (braid->braidlength);
	t_inc = (2.0 * M_PI) / (float) num_points;
	color_inc = (float) MI_NPIXELS(mi) * braid->color_direction /
		(float) num_points;
	braid->startcolor += SPINRATE * color_inc;
	if (((int) braid->startcolor) >= MI_NPIXELS(mi))
		braid->startcolor = 0.0;

	r_diff = (braid->max_radius - braid->min_radius) / (float) (braid->nstrands);

	color = braid->startcolor;
	psi = 0.0;
	for (i = 0; i < braid->braidlength; i++) {
		psi += theta;
		for (t = 0.0; t < theta; t += t_inc) {
#ifdef COLORROUND
			color += color_inc;
			if (((int) color) >= MI_NPIXELS(mi))
				color = 0.0;
			color_use = color;
#endif
			for (s = 0; s < braid->nstrands; s++) {
				if (ABS(braid->braidword[i]) == s)
					continue;
				if (ABS(braid->braidword[i]) - 1 == s) {
					/* crosSINFg */
#ifdef COLORCOMP
					if (MI_NPIXELS(mi) > 2) {
						color_use = color + SPINRATE *
							braid->components[applywordbackto(braid, s, i)] +
							(psi + t) / 2.0 / M_PI * (float) MI_NPIXELS(mi);
						while (((int) color_use) >= MI_NPIXELS(mi))
							color_use -= (float) MI_NPIXELS(mi);
						while (((int) color_use) < 0)
							color_use += (float) MI_NPIXELS(mi);
					}
#endif
#ifdef COLORROUND
					if (MI_NPIXELS(mi) > 2) {
						color_use += SPINRATE * color_inc;
						while (((int) color_use) >= MI_NPIXELS(mi))
							color_use -= (float) MI_NPIXELS(mi);
					}
#endif
					r1 = braid->min_radius + r_diff * (float) (s);
					r2 = braid->min_radius + r_diff * (float) (s + 1);
					if (braid->braidword[i] > 0 ||
					    (FABSF(t - theta / 2.0) > theta / 7.0)) {
						x_1 = ((0.5 * (1.0 + SINF(t / theta * M_PI - M_PI_2)) * r2 +
							0.5 * (1.0 + SINF((theta - t) / theta * M_PI - M_PI_2)) * r1)) *
							COSF(t + psi) + braid->center_x;
						y_1 = ((0.5 * (1.0 + SINF(t / theta * M_PI - M_PI_2)) * r2 +
							0.5 * (1.0 + SINF((theta - t) / theta * M_PI - M_PI_2)) * r1)) *
							SINF(t + psi) + braid->center_y;
						x_2 = ((0.5 * (1.0 + SINF((t + t_inc) / theta * M_PI - M_PI_2)) * r2 +
							0.5 * (1.0 + SINF((theta - t - t_inc) / theta * M_PI - M_PI_2)) * r1)) *
							COSF(t + t_inc + psi) + braid->center_x;
						y_2 = ((0.5 * (1.0 + SINF((t + t_inc) / theta * M_PI - M_PI_2)) * r2 +
							0.5 * (1.0 + SINF((theta - t - t_inc) / theta * M_PI - M_PI_2)) * r1)) *
							SINF(t + t_inc + psi) + braid->center_y;
						if (MI_NPIXELS(mi) > 2)
							XSetForeground(display, MI_GC(mi), MI_PIXEL(mi, (int) color_use));
						else
							XSetForeground(display, MI_GC(mi), MI_WHITE_PIXEL(mi));

						XDrawLine(display, window, MI_GC(mi),
							  (int) (x_1), (int) (y_1), (int) (x_2), (int) (y_2));
					}
#ifdef COLORCOMP
					if (MI_NPIXELS(mi) > 2) {
						color_use = color + SPINRATE *
							braid->components[applywordbackto(braid, s + 1, i)] +
							(psi + t) / 2.0 / M_PI * (float) MI_NPIXELS(mi);
						while (((int) color_use) >= MI_NPIXELS(mi))
							color_use -= (float) MI_NPIXELS(mi);
						while (((int) color_use) < 0)
							color_use += (float) MI_NPIXELS(mi);
					}
#endif
					if (braid->braidword[i] < 0 ||
					    (FABSF(t - theta / 2.0) > theta / 7.0)) {
						x_1 = ((0.5 * (1.0 + SINF(t / theta * M_PI - M_PI_2)) * r1 +
							0.5 * (1.0 + SINF((theta - t) / theta * M_PI - M_PI_2)) * r2)) *
							COSF(t + psi) + braid->center_x;
						y_1 = ((0.5 * (1.0 + SINF(t / theta * M_PI - M_PI_2)) * r1 +
							0.5 * (1.0 + SINF((theta - t) / theta * M_PI - M_PI_2)) * r2)) *
							SINF(t + psi) + braid->center_y;
						x_2 = ((0.5 * (1.0 + SINF((t + t_inc) / theta * M_PI - M_PI_2)) * r1 +
							0.5 * (1.0 + SINF((theta - t - t_inc) / theta * M_PI - M_PI_2)) * r2)) *
							COSF(t + t_inc + psi) + braid->center_x;
						y_2 = ((0.5 * (1.0 + SINF((t + t_inc) / theta * M_PI - M_PI_2)) * r1 +
							0.5 * (1.0 + SINF((theta - t - t_inc) / theta * M_PI - M_PI_2)) * r2)) *
							SINF(t + t_inc + psi) + braid->center_y;
						if (MI_NPIXELS(mi) > 2)
							XSetForeground(display, MI_GC(mi), MI_PIXEL(mi, (int) color_use));
						else
							XSetForeground(display, MI_GC(mi), MI_WHITE_PIXEL(mi));

						XDrawLine(display, window, MI_GC(mi),
							  (int) (x_1), (int) (y_1), (int) (x_2), (int) (y_2));
					}
				} else {
					/* no crosSINFg */
#ifdef COLORCOMP
					if (MI_NPIXELS(mi) > 2) {
						color_use = color + SPINRATE *
							braid->components[applywordbackto(braid, s, i)] +
							(psi + t) / 2.0 / M_PI * (float) MI_NPIXELS(mi);
						while (((int) color_use) >= MI_NPIXELS(mi))
							color_use -= (float) MI_NPIXELS(mi);
						while (((int) color_use) < 0)
							color_use += (float) MI_NPIXELS(mi);
					}
#endif
#ifdef COLORROUND
					if (MI_NPIXELS(mi) > 2) {
						color_use += SPINRATE * color_inc;
						while (((int) color_use) >= MI_NPIXELS(mi))
							color_use -= (float) MI_NPIXELS(mi);
					}
#endif
					r1 = braid->min_radius + r_diff * (float) (s);
					x_1 = r1 * COSF(t + psi) + braid->center_x;
					y_1 = r1 * SINF(t + psi) + braid->center_y;
					x_2 = r1 * COSF(t + t_inc + psi) + braid->center_x;
					y_2 = r1 * SINF(t + t_inc + psi) + braid->center_y;
					if (MI_NPIXELS(mi) > 2)
						XSetForeground(display, MI_GC(mi), MI_PIXEL(mi, (int) color_use));
					else
						XSetForeground(display, MI_GC(mi), MI_WHITE_PIXEL(mi));

					XDrawLine(display, window, MI_GC(mi),
						  (int) (x_1), (int) (y_1), (int) (x_2), (int) (y_2));
				}
			}
		}
	}
	XSetLineAttributes(display, MI_GC(mi), 1, LineSolid, CapNotLast, JoinRound);

	if (++braid->age > MI_CYCLES(mi)) {
#ifdef STANDALONE
      braid->eraser = erase_window (MI_DISPLAY(mi), MI_WINDOW(mi), braid->eraser);
#endif
		init_braid(mi);
	}
}
Beispiel #9
0
/**
 * Compute inverse of 4x4 transformation matrix.
 * 
 * \param mat pointer to a GLmatrix structure. The matrix inverse will be
 * stored in the GLmatrix::inv attribute.
 * 
 * \return GL_TRUE for success, GL_FALSE for failure (\p singular matrix).
 * 
 * \author
 * Code contributed by Jacques Leroy [email protected]
 *
 * Calculates the inverse matrix by performing the gaussian matrix reduction
 * with partial pivoting followed by back/substitution with the loops manually
 * unrolled.
 */
static GLboolean invert_matrix_general( GLmatrix *mat )
{
   const GLfloat *m = mat->m;
   GLfloat *out = mat->inv;
   GLfloat wtmp[4][8];
   GLfloat m0, m1, m2, m3, s;
   GLfloat *r0, *r1, *r2, *r3;

   r0 = wtmp[0], r1 = wtmp[1], r2 = wtmp[2], r3 = wtmp[3];

   r0[0] = MAT(m,0,0), r0[1] = MAT(m,0,1),
   r0[2] = MAT(m,0,2), r0[3] = MAT(m,0,3),
   r0[4] = 1.0, r0[5] = r0[6] = r0[7] = 0.0,

   r1[0] = MAT(m,1,0), r1[1] = MAT(m,1,1),
   r1[2] = MAT(m,1,2), r1[3] = MAT(m,1,3),
   r1[5] = 1.0, r1[4] = r1[6] = r1[7] = 0.0,

   r2[0] = MAT(m,2,0), r2[1] = MAT(m,2,1),
   r2[2] = MAT(m,2,2), r2[3] = MAT(m,2,3),
   r2[6] = 1.0, r2[4] = r2[5] = r2[7] = 0.0,

   r3[0] = MAT(m,3,0), r3[1] = MAT(m,3,1),
   r3[2] = MAT(m,3,2), r3[3] = MAT(m,3,3),
   r3[7] = 1.0, r3[4] = r3[5] = r3[6] = 0.0;

   /* choose pivot - or die */
   if (FABSF(r3[0])>FABSF(r2[0])) SWAP_ROWS(r3, r2);
   if (FABSF(r2[0])>FABSF(r1[0])) SWAP_ROWS(r2, r1);
   if (FABSF(r1[0])>FABSF(r0[0])) SWAP_ROWS(r1, r0);
   if (0.0 == r0[0])  return GL_FALSE;

   /* eliminate first variable     */
   m1 = r1[0]/r0[0]; m2 = r2[0]/r0[0]; m3 = r3[0]/r0[0];
   s = r0[1]; r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s;
   s = r0[2]; r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s;
   s = r0[3]; r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s;
   s = r0[4];
   if (s != 0.0) { r1[4] -= m1 * s; r2[4] -= m2 * s; r3[4] -= m3 * s; }
   s = r0[5];
   if (s != 0.0) { r1[5] -= m1 * s; r2[5] -= m2 * s; r3[5] -= m3 * s; }
   s = r0[6];
   if (s != 0.0) { r1[6] -= m1 * s; r2[6] -= m2 * s; r3[6] -= m3 * s; }
   s = r0[7];
   if (s != 0.0) { r1[7] -= m1 * s; r2[7] -= m2 * s; r3[7] -= m3 * s; }

   /* choose pivot - or die */
   if (FABSF(r3[1])>FABSF(r2[1])) SWAP_ROWS(r3, r2);
   if (FABSF(r2[1])>FABSF(r1[1])) SWAP_ROWS(r2, r1);
   if (0.0 == r1[1])  return GL_FALSE;

   /* eliminate second variable */
   m2 = r2[1]/r1[1]; m3 = r3[1]/r1[1];
   r2[2] -= m2 * r1[2]; r3[2] -= m3 * r1[2];
   r2[3] -= m2 * r1[3]; r3[3] -= m3 * r1[3];
   s = r1[4]; if (0.0 != s) { r2[4] -= m2 * s; r3[4] -= m3 * s; }
   s = r1[5]; if (0.0 != s) { r2[5] -= m2 * s; r3[5] -= m3 * s; }
   s = r1[6]; if (0.0 != s) { r2[6] -= m2 * s; r3[6] -= m3 * s; }
   s = r1[7]; if (0.0 != s) { r2[7] -= m2 * s; r3[7] -= m3 * s; }

   /* choose pivot - or die */
   if (FABSF(r3[2])>FABSF(r2[2])) SWAP_ROWS(r3, r2);
   if (0.0 == r2[2])  return GL_FALSE;

   /* eliminate third variable */
   m3 = r3[2]/r2[2];
   r3[3] -= m3 * r2[3], r3[4] -= m3 * r2[4],
   r3[5] -= m3 * r2[5], r3[6] -= m3 * r2[6],
   r3[7] -= m3 * r2[7];

   /* last check */
   if (0.0 == r3[3]) return GL_FALSE;

   s = 1.0F/r3[3];             /* now back substitute row 3 */
   r3[4] *= s; r3[5] *= s; r3[6] *= s; r3[7] *= s;

   m2 = r2[3];                 /* now back substitute row 2 */
   s  = 1.0F/r2[2];
   r2[4] = s * (r2[4] - r3[4] * m2), r2[5] = s * (r2[5] - r3[5] * m2),
   r2[6] = s * (r2[6] - r3[6] * m2), r2[7] = s * (r2[7] - r3[7] * m2);
   m1 = r1[3];
   r1[4] -= r3[4] * m1, r1[5] -= r3[5] * m1,
   r1[6] -= r3[6] * m1, r1[7] -= r3[7] * m1;
   m0 = r0[3];
   r0[4] -= r3[4] * m0, r0[5] -= r3[5] * m0,
   r0[6] -= r3[6] * m0, r0[7] -= r3[7] * m0;

   m1 = r1[2];                 /* now back substitute row 1 */
   s  = 1.0F/r1[1];
   r1[4] = s * (r1[4] - r2[4] * m1), r1[5] = s * (r1[5] - r2[5] * m1),
   r1[6] = s * (r1[6] - r2[6] * m1), r1[7] = s * (r1[7] - r2[7] * m1);
   m0 = r0[2];
   r0[4] -= r2[4] * m0, r0[5] -= r2[5] * m0,
   r0[6] -= r2[6] * m0, r0[7] -= r2[7] * m0;

   m0 = r0[1];                 /* now back substitute row 0 */
   s  = 1.0F/r0[0];
   r0[4] = s * (r0[4] - r1[4] * m0), r0[5] = s * (r0[5] - r1[5] * m0),
   r0[6] = s * (r0[6] - r1[6] * m0), r0[7] = s * (r0[7] - r1[7] * m0);

   MAT(out,0,0) = r0[4]; MAT(out,0,1) = r0[5],
   MAT(out,0,2) = r0[6]; MAT(out,0,3) = r0[7],
   MAT(out,1,0) = r1[4]; MAT(out,1,1) = r1[5],
   MAT(out,1,2) = r1[6]; MAT(out,1,3) = r1[7],
   MAT(out,2,0) = r2[4]; MAT(out,2,1) = r2[5],
   MAT(out,2,2) = r2[6]; MAT(out,2,3) = r2[7],
   MAT(out,3,0) = r3[4]; MAT(out,3,1) = r3[5],
   MAT(out,3,2) = r3[6]; MAT(out,3,3) = r3[7];

   return GL_TRUE;
}
Beispiel #10
0
/*
 * As above, but write stencil values.
 */
void
_swrast_write_zoomed_stencil_span( GLcontext *ctx,
                                 GLuint n, GLint x, GLint y,
                                 const GLstencil stencil[], GLint y0,
                                 GLint skipPixels )
{
   GLint m;
   GLint r0, r1, row, r;
   GLint i, j, skipcol;
   GLstencil zstencil[MAX_WIDTH];  /* zoomed stencil values */
   GLint maxwidth = MIN2( ctx->DrawBuffer->Width, MAX_WIDTH );

   (void) skipPixels;  /* XXX this shouldn't be ignored */

   /* compute width of output row */
   m = (GLint) FABSF( n * ctx->Pixel.ZoomX );
   if (m==0) {
      return;
   }
   if (ctx->Pixel.ZoomX<0.0) {
      /* adjust x coordinate for left/right mirroring */
      x = x - m;
   }

   /* compute which rows to draw */
   row = y - y0;
   r0 = y0 + (GLint) (row * ctx->Pixel.ZoomY);
   r1 = y0 + (GLint) ((row+1) * ctx->Pixel.ZoomY);
   if (r0==r1) {
      return;
   }
   else if (r1<r0) {
      GLint rtmp = r1;
      r1 = r0;
      r0 = rtmp;
   }

   /* return early if r0...r1 is above or below window */
   if (r0<0 && r1<0) {
      /* below window */
      return;
   }
   if (r0 >= (GLint) ctx->DrawBuffer->Height &&
       r1 >= (GLint) ctx->DrawBuffer->Height) {
      /* above window */
      return;
   }

   /* check if left edge is outside window */
   skipcol = 0;
   if (x<0) {
      skipcol = -x;
      m += x;
   }
   /* make sure span isn't too long or short */
   if (m>maxwidth) {
      m = maxwidth;
   }
   else if (m<=0) {
      return;
   }

   ASSERT( m <= MAX_WIDTH );

   /* zoom the span horizontally */
   if (ctx->Pixel.ZoomX==-1.0F) {
      /* n==m */
      for (j=0;j<m;j++) {
         i = n - (j+skipcol) - 1;
         zstencil[j] = stencil[i];
      }
   }
   else {
      GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
      for (j=0;j<m;j++) {
         i = (GLint) ((j+skipcol) * xscale);
         if (i<0)  i = n + i - 1;
         zstencil[j] = stencil[i];
      }
   }

   /* write the span */
   for (r=r0; r<r1; r++) {
      _swrast_write_stencil_span( ctx, m, x+skipcol, r, zstencil );
   }
}
Beispiel #11
0
static GLboolean
run_fog_stage(struct gl_context *ctx, struct tnl_pipeline_stage *stage)
{
   TNLcontext *tnl = TNL_CONTEXT(ctx);
   struct vertex_buffer *VB = &tnl->vb;
   struct fog_stage_data *store = FOG_STAGE_DATA(stage);
   GLvector4f *input;


   if (!ctx->Fog.Enabled)
      return GL_TRUE;

   if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT && !ctx->VertexProgram._Current) {
      GLuint i;
      GLfloat *coord;
      /* Fog is computed from vertex or fragment Z values */
      /* source = VB->AttribPtr[_TNL_ATTRIB_POS] or VB->EyePtr coords */
      /* dest = VB->AttribPtr[_TNL_ATTRIB_FOG] = fog stage private storage */
      VB->AttribPtr[_TNL_ATTRIB_FOG] = &store->fogcoord;

      if (!ctx->_NeedEyeCoords) {
         /* compute fog coords from object coords */
	 const GLfloat *m = ctx->ModelviewMatrixStack.Top->m;
	 GLfloat plane[4];

	 /* Use this to store calculated eye z values:
	  */
	 input = &store->fogcoord;

	 plane[0] = m[2];
	 plane[1] = m[6];
	 plane[2] = m[10];
	 plane[3] = m[14];
	 /* Full eye coords weren't required, just calculate the
	  * eye Z values.
	  */
	 _mesa_dotprod_tab[VB->AttribPtr[_TNL_ATTRIB_POS]->size]
	    ( (GLfloat *) input->data,
	      4 * sizeof(GLfloat),
	      VB->AttribPtr[_TNL_ATTRIB_POS], plane );

	 input->count = VB->AttribPtr[_TNL_ATTRIB_POS]->count;

	 /* make sure coords are really positive
	    NOTE should avoid going through array twice */
	 coord = input->start;
	 for (i = 0; i < input->count; i++) {
	    *coord = FABSF(*coord);
	    STRIDE_F(coord, input->stride);
	 }
      }
      else {
         /* fog coordinates = eye Z coordinates - need to copy for ABS */
	 input = &store->fogcoord;

	 if (VB->EyePtr->size < 2)
	    _mesa_vector4f_clean_elem( VB->EyePtr, VB->Count, 2 );

	 input->stride = 4 * sizeof(GLfloat);
	 input->count = VB->EyePtr->count;
	 coord = VB->EyePtr->start;
	 for (i = 0 ; i < VB->EyePtr->count; i++) {
	    input->data[i][0] = FABSF(coord[2]);
	    STRIDE_F(coord, VB->EyePtr->stride);
	 }
      }
   }
   else {
      /* use glFogCoord() coordinates */
      input = VB->AttribPtr[_TNL_ATTRIB_FOG];  /* source data */

      /* input->count may be one if glFogCoord was only called once
       * before glBegin.  But we need to compute fog for all vertices.
       */
      input->count = VB->AttribPtr[_TNL_ATTRIB_POS]->count;

      VB->AttribPtr[_TNL_ATTRIB_FOG] = &store->fogcoord;  /* dest data */
   }

   if (tnl->_DoVertexFog) {
      /* compute blend factors from fog coordinates */
      compute_fog_blend_factors( ctx, VB->AttribPtr[_TNL_ATTRIB_FOG], input );
   }
   else {
      /* results = incoming fog coords (compute fog per-fragment later) */
      VB->AttribPtr[_TNL_ATTRIB_FOG] = input;
   }

   return GL_TRUE;
}
Beispiel #12
0
/**
 * Execute the given vertex program
 */
void
_mesa_exec_vertex_program(GLcontext *ctx, const struct vertex_program *program)
{
   struct vertex_program_state *state = &ctx->VertexProgram;
   const struct vp_instruction *inst;

   ctx->_CurrentProgram = GL_VERTEX_PROGRAM_ARB; /* or NV, doesn't matter */

   /* If the program is position invariant, multiply the input
    * position and the MVP matrix and stick it into the output pos slot
    */
   if (ctx->VertexProgram.Current->IsPositionInvariant) {
      TRANSFORM_POINT( ctx->VertexProgram.Outputs[0], 
                       ctx->_ModelProjectMatrix.m, 
                       ctx->VertexProgram.Inputs[0]);

      /* XXX: This could go elsewhere */
      ctx->VertexProgram.Current->OutputsWritten |= 0x1;
   }

   for (inst = program->Instructions; /*inst->Opcode != VP_OPCODE_END*/; inst++) {

      if (ctx->VertexProgram.CallbackEnabled &&
          ctx->VertexProgram.Callback) {
         ctx->VertexProgram.CurrentPosition = inst->StringPos;
         ctx->VertexProgram.Callback(program->Base.Target,
                                     ctx->VertexProgram.CallbackData);
      }

      switch (inst->Opcode) {
         case VP_OPCODE_MOV:
            {
               GLfloat t[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               store_vector4( &inst->DstReg, state, t );
            }
            break;
         case VP_OPCODE_LIT:
            {
               const GLfloat epsilon = 1.0e-5F; /* XXX fix? */
               GLfloat t[4], lit[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               if (t[3] < -(128.0F - epsilon))
                   t[3] = - (128.0F - epsilon);
               else if (t[3] > 128.0F - epsilon)
                  t[3] = 128.0F - epsilon;
               if (t[0] < 0.0)
                  t[0] = 0.0;
               if (t[1] < 0.0)
                  t[1] = 0.0;
               lit[0] = 1.0;
               lit[1] = t[0];
               lit[2] = (t[0] > 0.0) ? (GLfloat) exp(t[3] * log(t[1])) : 0.0F;
               lit[3] = 1.0;
               store_vector4( &inst->DstReg, state, lit );
            }
            break;
         case VP_OPCODE_RCP:
            {
               GLfloat t[4];
               fetch_vector1( &inst->SrcReg[0], state, t );
               if (t[0] != 1.0F)
                  t[0] = 1.0F / t[0];  /* div by zero is infinity! */
               t[1] = t[2] = t[3] = t[0];
               store_vector4( &inst->DstReg, state, t );
            }
            break;
         case VP_OPCODE_RSQ:
            {
               GLfloat t[4];
               fetch_vector1( &inst->SrcReg[0], state, t );
               t[0] = INV_SQRTF(FABSF(t[0]));
               t[1] = t[2] = t[3] = t[0];
               store_vector4( &inst->DstReg, state, t );
            }
            break;
         case VP_OPCODE_EXP:
            {
               GLfloat t[4], q[4], floor_t0;
               fetch_vector1( &inst->SrcReg[0], state, t );
               floor_t0 = (float) floor(t[0]);
               if (floor_t0 > FLT_MAX_EXP) {
                  SET_POS_INFINITY(q[0]);
                  SET_POS_INFINITY(q[2]);
               }
               else if (floor_t0 < FLT_MIN_EXP) {
                  q[0] = 0.0F;
                  q[2] = 0.0F;
               }
               else {
#ifdef USE_IEEE
                  GLint ii = (GLint) floor_t0;
                  ii = (ii < 23) + 0x3f800000;
                  SET_FLOAT_BITS(q[0], ii);
                  q[0] = *((GLfloat *) &ii);
#else
                  q[0] = (GLfloat) pow(2.0, floor_t0);
#endif
                  q[2] = (GLfloat) (q[0] * LOG2(q[1]));
               }
               q[1] = t[0] - floor_t0;
               q[3] = 1.0F;
               store_vector4( &inst->DstReg, state, q );
            }
            break;
         case VP_OPCODE_LOG:
            {
               GLfloat t[4], q[4], abs_t0;
               fetch_vector1( &inst->SrcReg[0], state, t );
               abs_t0 = (GLfloat) fabs(t[0]);
               if (abs_t0 != 0.0F) {
                  /* Since we really can't handle infinite values on VMS
                   * like other OSes we'll use __MAXFLOAT to represent
                   * infinity.  This may need some tweaking.
                   */
#ifdef VMS
                  if (abs_t0 == __MAXFLOAT)
#else
                  if (IS_INF_OR_NAN(abs_t0))
#endif
                  {
                     SET_POS_INFINITY(q[0]);
                     q[1] = 1.0F;
                     SET_POS_INFINITY(q[2]);
                  }
                  else {
                     int exponent;
                     double mantissa = frexp(t[0], &exponent);
                     q[0] = (GLfloat) (exponent - 1);
                     q[1] = (GLfloat) (2.0 * mantissa); /* map [.5, 1) -> [1, 2) */
                     q[2] = (GLfloat) (q[0] + LOG2(q[1]));
                  }
                  }
               else {
                  SET_NEG_INFINITY(q[0]);
                  q[1] = 1.0F;
                  SET_NEG_INFINITY(q[2]);
               }
               q[3] = 1.0;
               store_vector4( &inst->DstReg, state, q );
            }
            break;
         case VP_OPCODE_MUL:
            {
               GLfloat t[4], u[4], prod[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               fetch_vector4( &inst->SrcReg[1], state, u );
               prod[0] = t[0] * u[0];
               prod[1] = t[1] * u[1];
               prod[2] = t[2] * u[2];
               prod[3] = t[3] * u[3];
               store_vector4( &inst->DstReg, state, prod );
            }
            break;
         case VP_OPCODE_ADD:
            {
               GLfloat t[4], u[4], sum[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               fetch_vector4( &inst->SrcReg[1], state, u );
               sum[0] = t[0] + u[0];
               sum[1] = t[1] + u[1];
               sum[2] = t[2] + u[2];
               sum[3] = t[3] + u[3];
               store_vector4( &inst->DstReg, state, sum );
            }
            break;
         case VP_OPCODE_DP3:
            {
               GLfloat t[4], u[4], dot[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               fetch_vector4( &inst->SrcReg[1], state, u );
               dot[0] = t[0] * u[0] + t[1] * u[1] + t[2] * u[2];
               dot[1] = dot[2] = dot[3] = dot[0];
               store_vector4( &inst->DstReg, state, dot );
            }
            break;
         case VP_OPCODE_DP4:
            {
               GLfloat t[4], u[4], dot[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               fetch_vector4( &inst->SrcReg[1], state, u );
               dot[0] = t[0] * u[0] + t[1] * u[1] + t[2] * u[2] + t[3] * u[3];
               dot[1] = dot[2] = dot[3] = dot[0];
               store_vector4( &inst->DstReg, state, dot );
            }
            break;
         case VP_OPCODE_DST:
            {
               GLfloat t[4], u[4], dst[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               fetch_vector4( &inst->SrcReg[1], state, u );
               dst[0] = 1.0F;
               dst[1] = t[1] * u[1];
               dst[2] = t[2];
               dst[3] = u[3];
               store_vector4( &inst->DstReg, state, dst );
            }
            break;
         case VP_OPCODE_MIN:
            {
               GLfloat t[4], u[4], min[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               fetch_vector4( &inst->SrcReg[1], state, u );
               min[0] = (t[0] < u[0]) ? t[0] : u[0];
               min[1] = (t[1] < u[1]) ? t[1] : u[1];
               min[2] = (t[2] < u[2]) ? t[2] : u[2];
               min[3] = (t[3] < u[3]) ? t[3] : u[3];
               store_vector4( &inst->DstReg, state, min );
            }
            break;
         case VP_OPCODE_MAX:
            {
               GLfloat t[4], u[4], max[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               fetch_vector4( &inst->SrcReg[1], state, u );
               max[0] = (t[0] > u[0]) ? t[0] : u[0];
               max[1] = (t[1] > u[1]) ? t[1] : u[1];
               max[2] = (t[2] > u[2]) ? t[2] : u[2];
               max[3] = (t[3] > u[3]) ? t[3] : u[3];
               store_vector4( &inst->DstReg, state, max );
            }
            break;
         case VP_OPCODE_SLT:
            {
               GLfloat t[4], u[4], slt[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               fetch_vector4( &inst->SrcReg[1], state, u );
               slt[0] = (t[0] < u[0]) ? 1.0F : 0.0F;
               slt[1] = (t[1] < u[1]) ? 1.0F : 0.0F;
               slt[2] = (t[2] < u[2]) ? 1.0F : 0.0F;
               slt[3] = (t[3] < u[3]) ? 1.0F : 0.0F;
               store_vector4( &inst->DstReg, state, slt );
            }
            break;
         case VP_OPCODE_SGE:
            {
               GLfloat t[4], u[4], sge[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               fetch_vector4( &inst->SrcReg[1], state, u );
               sge[0] = (t[0] >= u[0]) ? 1.0F : 0.0F;
               sge[1] = (t[1] >= u[1]) ? 1.0F : 0.0F;
               sge[2] = (t[2] >= u[2]) ? 1.0F : 0.0F;
               sge[3] = (t[3] >= u[3]) ? 1.0F : 0.0F;
               store_vector4( &inst->DstReg, state, sge );
            }
            break;
         case VP_OPCODE_MAD:
            {
               GLfloat t[4], u[4], v[4], sum[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               fetch_vector4( &inst->SrcReg[1], state, u );
               fetch_vector4( &inst->SrcReg[2], state, v );
               sum[0] = t[0] * u[0] + v[0];
               sum[1] = t[1] * u[1] + v[1];
               sum[2] = t[2] * u[2] + v[2];
               sum[3] = t[3] * u[3] + v[3];
               store_vector4( &inst->DstReg, state, sum );
            }
            break;
         case VP_OPCODE_ARL:
            {
               GLfloat t[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               state->AddressReg[0] = (GLint) floor(t[0]);
            }
            break;
         case VP_OPCODE_DPH:
            {
               GLfloat t[4], u[4], dot[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               fetch_vector4( &inst->SrcReg[1], state, u );
               dot[0] = t[0] * u[0] + t[1] * u[1] + t[2] * u[2] + u[3];
               dot[1] = dot[2] = dot[3] = dot[0];
               store_vector4( &inst->DstReg, state, dot );
            }
            break;
         case VP_OPCODE_RCC:
            {
               GLfloat t[4], u;
               fetch_vector1( &inst->SrcReg[0], state, t );
               if (t[0] == 1.0F)
                  u = 1.0F;
               else
                  u = 1.0F / t[0];
               if (u > 0.0F) {
                  if (u > 1.884467e+019F) {
                     u = 1.884467e+019F;  /* IEEE 32-bit binary value 0x5F800000 */
                  }
                  else if (u < 5.42101e-020F) {
                     u = 5.42101e-020F;   /* IEEE 32-bit binary value 0x1F800000 */
                  }
               }
               else {
                  if (u < -1.884467e+019F) {
                     u = -1.884467e+019F; /* IEEE 32-bit binary value 0xDF800000 */
                  }
                  else if (u > -5.42101e-020F) {
                     u = -5.42101e-020F;  /* IEEE 32-bit binary value 0x9F800000 */
                  }
               }
               t[0] = t[1] = t[2] = t[3] = u;
               store_vector4( &inst->DstReg, state, t );
            }
            break;
         case VP_OPCODE_SUB: /* GL_NV_vertex_program1_1 */
            {
               GLfloat t[4], u[4], sum[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               fetch_vector4( &inst->SrcReg[1], state, u );
               sum[0] = t[0] - u[0];
               sum[1] = t[1] - u[1];
               sum[2] = t[2] - u[2];
               sum[3] = t[3] - u[3];
               store_vector4( &inst->DstReg, state, sum );
            }
            break;
         case VP_OPCODE_ABS: /* GL_NV_vertex_program1_1 */
            {
               GLfloat t[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               if (t[0] < 0.0)  t[0] = -t[0];
               if (t[1] < 0.0)  t[1] = -t[1];
               if (t[2] < 0.0)  t[2] = -t[2];
               if (t[3] < 0.0)  t[3] = -t[3];
               store_vector4( &inst->DstReg, state, t );
            }
            break;
         case VP_OPCODE_FLR: /* GL_ARB_vertex_program */
            {
               GLfloat t[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               t[0] = FLOORF(t[0]);
               t[1] = FLOORF(t[1]);
               t[2] = FLOORF(t[2]);
               t[3] = FLOORF(t[3]);
               store_vector4( &inst->DstReg, state, t );
            }
            break;
         case VP_OPCODE_FRC: /* GL_ARB_vertex_program */
            {
               GLfloat t[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               t[0] = t[0] - FLOORF(t[0]);
               t[1] = t[1] - FLOORF(t[1]);
               t[2] = t[2] - FLOORF(t[2]);
               t[3] = t[3] - FLOORF(t[3]);
               store_vector4( &inst->DstReg, state, t );
            }
            break;
         case VP_OPCODE_EX2: /* GL_ARB_vertex_program */
            {
               GLfloat t[4];
               fetch_vector1( &inst->SrcReg[0], state, t );
               t[0] = t[1] = t[2] = t[3] = (GLfloat)_mesa_pow(2.0, t[0]);
               store_vector4( &inst->DstReg, state, t );
            }
            break;
         case VP_OPCODE_LG2: /* GL_ARB_vertex_program */
            {
               GLfloat t[4];
               fetch_vector1( &inst->SrcReg[0], state, t );
               t[0] = t[1] = t[2] = t[3] = LOG2(t[0]);
               store_vector4( &inst->DstReg, state, t );
            }
            break;
         case VP_OPCODE_POW: /* GL_ARB_vertex_program */
            {
               GLfloat t[4], u[4];
               fetch_vector1( &inst->SrcReg[0], state, t );
               fetch_vector1( &inst->SrcReg[1], state, u );
               t[0] = t[1] = t[2] = t[3] = (GLfloat)_mesa_pow(t[0], u[0]);
               store_vector4( &inst->DstReg, state, t );
            }
            break;
         case VP_OPCODE_XPD: /* GL_ARB_vertex_program */
            {
               GLfloat t[4], u[4], cross[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               fetch_vector4( &inst->SrcReg[1], state, u );
               cross[0] = t[1] * u[2] - t[2] * u[1];
               cross[1] = t[2] * u[0] - t[0] * u[2];
               cross[2] = t[0] * u[1] - t[1] * u[0];
               store_vector4( &inst->DstReg, state, cross );
            }
            break;
         case VP_OPCODE_SWZ: /* GL_ARB_vertex_program */
            {
               const struct vp_src_register *source = &inst->SrcReg[0];
               const GLfloat *src = get_register_pointer(source, state);
               GLfloat result[4];
               GLuint i;

               /* do extended swizzling here */
               for (i = 0; i < 3; i++) {
                  if (source->Swizzle[i] == SWIZZLE_ZERO)
                     result[i] = 0.0;
                  else if (source->Swizzle[i] == SWIZZLE_ONE)
                     result[i] = -1.0;
                  else
                     result[i] = -src[source->Swizzle[i]];
                  if (source->Negate)
                     result[i] = -result[i];
               }
               store_vector4( &inst->DstReg, state, result );
            }
            break;

         case VP_OPCODE_END:
            ctx->_CurrentProgram = 0;
            return;
         default:
            /* bad instruction opcode */
            _mesa_problem(ctx, "Bad VP Opcode in _mesa_exec_vertex_program");
            ctx->_CurrentProgram = 0;
            return;
      } /* switch */
   } /* for */

   ctx->_CurrentProgram = 0;
}