s_triangle.c revision ecfaab88b2577bd0395bc05d75a036126806a9c4
1e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
2e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Mesa 3-D graphics library
38c7135ee14fb6f4d8b6e64d570daee3512c99438Brian Paul * Version:  7.3
422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
5dd34fe8679fa200e55cfaf8e80bbecdecea084e3Brian * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
7e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a
8e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * copy of this software and associated documentation files (the "Software"),
9e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * to deal in the Software without restriction, including without limitation
10e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * and/or sell copies of the Software, and to permit persons to whom the
12e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Software is furnished to do so, subject to the following conditions:
1322144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
14e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * The above copyright notice and this permission notice shall be included
15e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * in all copies or substantial portions of the Software.
1622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
17e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
24e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
25e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
26e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
27709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell * When the device driver doesn't implement triangle rasterization it
28709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell * can hook in _swrast_Triangle, which eventually calls one of these
2938f28665bf9fb5b2464738ca5074848ec2777ae1Gareth Hughes * functions to draw triangles.
30e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
31e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
32bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/glheader.h"
33bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/context.h"
34bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/colormac.h"
35bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/imports.h"
36bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/macros.h"
37f84573d039e3cc2bf11d8c15d59bd3255fd05b27Vinson Lee#include "main/mtypes.h"
38decc6e2a32ef49e673c081f30e19b8970155d887Brian Paul#include "main/state.h"
39ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/prog_instruction.h"
40e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
41e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_aatriangle.h"
42cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#include "s_context.h"
43cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#include "s_feedback.h"
44e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_span.h"
45cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#include "s_triangle.h"
469bf68ad963ba92b5d1e725f965979042495a5313Brian Paul
479bf68ad963ba92b5d1e725f965979042495a5313Brian Paul
488f4d66c5f893b49eb3973aa3b31a856314c045c7Brian Paul/**
498f4d66c5f893b49eb3973aa3b31a856314c045c7Brian Paul * Test if a triangle should be culled.  Used for feedback and selection mode.
508f4d66c5f893b49eb3973aa3b31a856314c045c7Brian Paul * \return GL_TRUE if the triangle is to be culled, GL_FALSE otherwise.
5177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul */
52230ebaff2aecdd9f2bf667889d54bfc3dd032bbeBrian PaulGLboolean
53f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_swrast_culltriangle( struct gl_context *ctx,
54230ebaff2aecdd9f2bf667889d54bfc3dd032bbeBrian Paul                      const SWvertex *v0,
55230ebaff2aecdd9f2bf667889d54bfc3dd032bbeBrian Paul                      const SWvertex *v1,
56230ebaff2aecdd9f2bf667889d54bfc3dd032bbeBrian Paul                      const SWvertex *v2 )
57e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
588f4d66c5f893b49eb3973aa3b31a856314c045c7Brian Paul   SWcontext *swrast = SWRAST_CONTEXT(ctx);
599e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   GLfloat ex = v1->attrib[FRAG_ATTRIB_WPOS][0] - v0->attrib[FRAG_ATTRIB_WPOS][0];
609e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   GLfloat ey = v1->attrib[FRAG_ATTRIB_WPOS][1] - v0->attrib[FRAG_ATTRIB_WPOS][1];
619e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   GLfloat fx = v2->attrib[FRAG_ATTRIB_WPOS][0] - v0->attrib[FRAG_ATTRIB_WPOS][0];
629e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   GLfloat fy = v2->attrib[FRAG_ATTRIB_WPOS][1] - v0->attrib[FRAG_ATTRIB_WPOS][1];
63e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLfloat c = ex*fy-ey*fx;
64e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
65a1d3855fb0c3969a32825d0b899076917d5ccce6Brian Paul   if (c * swrast->_BackfaceSign * swrast->_BackfaceCullSign <= 0.0F)
668f4d66c5f893b49eb3973aa3b31a856314c045c7Brian Paul      return GL_FALSE;
6722144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes
688f4d66c5f893b49eb3973aa3b31a856314c045c7Brian Paul   return GL_TRUE;
69e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
70e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
71e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
7295e02a210ed339ad20b0c16284dcdcf9af2dc755Brian Paul
73e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
74e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Render a flat-shaded RGBA triangle.
75e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
76cdf2da368d180205df3573697b51b8764048ad6eBrian Paul#define NAME flat_rgba_triangle
77e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define INTERP_Z 1
78f1e236987829393c81dc86ea19cb49eefe190317Brian Paul#define SETUP_CODE				\
7936a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul   ASSERT(ctx->Texture._EnabledCoordUnits == 0);\
807956292a765910077f50352d7cd0174e1e66d26cBrian Paul   ASSERT(ctx->Light.ShadeModel==GL_FLAT);	\
8177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   span.interpMask |= SPAN_RGBA;		\
8277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   span.red = ChanToFixed(v2->color[0]);	\
8377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   span.green = ChanToFixed(v2->color[1]);	\
8477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   span.blue = ChanToFixed(v2->color[2]);	\
8577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   span.alpha = ChanToFixed(v2->color[3]);	\
8677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   span.redStep = 0;				\
8777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   span.greenStep = 0;				\
8877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   span.blueStep = 0;				\
8977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   span.alphaStep = 0;
9045bc887da226403f2c41077e40ca38b6f60f1359Brian Paul#define RENDER_SPAN( span )  _swrast_write_rgba_span(ctx, &span);
91e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_tritemp.h"
92e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
93e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
94e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
95e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
96e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Render a smooth-shaded RGBA triangle.
97e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
98cdf2da368d180205df3573697b51b8764048ad6eBrian Paul#define NAME smooth_rgba_triangle
99e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define INTERP_Z 1
100e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define INTERP_RGB 1
101e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define INTERP_ALPHA 1
102733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul#define SETUP_CODE				\
103733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   {						\
104733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      /* texturing must be off */		\
10536a0a3252e1e20df69b53f70ba93bc74c4a4bf0eBrian Paul      ASSERT(ctx->Texture._EnabledCoordUnits == 0);	\
106733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul      ASSERT(ctx->Light.ShadeModel==GL_SMOOTH);	\
107733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   }
10845bc887da226403f2c41077e40ca38b6f60f1359Brian Paul#define RENDER_SPAN( span )  _swrast_write_rgba_span(ctx, &span);
109e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_tritemp.h"
110e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
111e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
112e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
113e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
114e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Render an RGB, GL_DECAL, textured triangle.
115e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Interpolate S,T only w/out mipmapping or perspective correction.
116e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *
1174003bde6fffc3e5b9e1a115ba952b988dffb099aBrian * No fog.  No depth testing.
118e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
119cdf2da368d180205df3573697b51b8764048ad6eBrian Paul#define NAME simple_textured_triangle
120e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define INTERP_INT_TEX 1
121e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define S_SCALE twidth
122e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define T_SCALE theight
1239bf68ad963ba92b5d1e725f965979042495a5313Brian Paul
124e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define SETUP_CODE							\
1252a077500a84819d1e6ac62e84ded130aa655c5e9Brian   struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];	\
1260103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   const struct gl_texture_object *obj = 				\
1279818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul      ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX];		\
1280103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   const struct gl_texture_image *texImg =				\
1290103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul      obj->Image[0][obj->BaseLevel];					\
1300103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   const GLfloat twidth = (GLfloat) texImg->Width;			\
1310103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   const GLfloat theight = (GLfloat) texImg->Height;			\
1320103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   const GLint twidth_log2 = texImg->WidthLog2;				\
1330103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   const GLubyte *texture = (const GLubyte *) texImg->Data;		\
1340103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   const GLint smask = texImg->Width - 1;				\
1350103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   const GLint tmask = texImg->Height - 1;				\
1360103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   ASSERT(texImg->TexFormat == MESA_FORMAT_RGB888);			\
1372a077500a84819d1e6ac62e84ded130aa655c5e9Brian   if (!rb || !texture) {						\
1388e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      return;								\
139e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
140e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
141920023240c2fc42675f318732b43bdc6f339113cBrian Paul#define RENDER_SPAN( span )						\
1429bf68ad963ba92b5d1e725f965979042495a5313Brian Paul   GLuint i;								\
1433fa7dbf368bb060220e9f78e666b00d6827166a6Brian Paul   GLubyte rgb[MAX_WIDTH][3];						\
14477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   span.intTex[0] -= FIXED_HALF; /* off-by-one error? */		\
14577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   span.intTex[1] -= FIXED_HALF;					\
14677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   for (i = 0; i < span.end; i++) {					\
14777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul      GLint s = FixedToInt(span.intTex[0]) & smask;			\
14877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul      GLint t = FixedToInt(span.intTex[1]) & tmask;			\
1499bf68ad963ba92b5d1e725f965979042495a5313Brian Paul      GLint pos = (t << twidth_log2) + s;				\
1509bf68ad963ba92b5d1e725f965979042495a5313Brian Paul      pos = pos + pos + pos;  /* multiply by 3 */			\
151086f9fc0e2aef27f54eda87c733685500555bf20Brian Paul      rgb[i][RCOMP] = texture[pos+2];					\
15257d705d5a939180bd992cad2f24d95c329b5b28cBrian Paul      rgb[i][GCOMP] = texture[pos+1];					\
153086f9fc0e2aef27f54eda87c733685500555bf20Brian Paul      rgb[i][BCOMP] = texture[pos+0];					\
15477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul      span.intTex[0] += span.intTexStep[0];				\
15577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul      span.intTex[1] += span.intTexStep[1];				\
1569bf68ad963ba92b5d1e725f965979042495a5313Brian Paul   }									\
15757d705d5a939180bd992cad2f24d95c329b5b28cBrian Paul   rb->PutRowRGB(ctx, rb, span.end, span.x, span.y, rgb, NULL);
158e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
159e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_tritemp.h"
160cdf2da368d180205df3573697b51b8764048ad6eBrian Paul
161e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
162e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
163e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
164e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Render an RGB, GL_DECAL, textured triangle.
165e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Interpolate S,T, GL_LESS depth test, w/out mipmapping or
166e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * perspective correction.
167e6e0ba781b0a6a1b8747cae49ca622a6a61b1bf8Brian Paul * Depth buffer bits must be <= sizeof(DEFAULT_SOFTWARE_DEPTH_TYPE)
16822144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
169e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * No fog.
170e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
171cdf2da368d180205df3573697b51b8764048ad6eBrian Paul#define NAME simple_z_textured_triangle
172e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define INTERP_Z 1
173e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
174e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define INTERP_INT_TEX 1
175e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define S_SCALE twidth
176e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define T_SCALE theight
1779bf68ad963ba92b5d1e725f965979042495a5313Brian Paul
178e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define SETUP_CODE							\
1792a077500a84819d1e6ac62e84ded130aa655c5e9Brian   struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];	\
1800103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   const struct gl_texture_object *obj = 				\
1819818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul      ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX];		\
1820103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   const struct gl_texture_image *texImg = 				\
1830103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul       obj->Image[0][obj->BaseLevel]; 					\
1840103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   const GLfloat twidth = (GLfloat) texImg->Width;			\
1850103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   const GLfloat theight = (GLfloat) texImg->Height;			\
1860103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   const GLint twidth_log2 = texImg->WidthLog2;				\
1870103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   const GLubyte *texture = (const GLubyte *) texImg->Data;		\
1880103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   const GLint smask = texImg->Width - 1;				\
1890103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   const GLint tmask = texImg->Height - 1;				\
1900103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   ASSERT(texImg->TexFormat == MESA_FORMAT_RGB888);			\
1912a077500a84819d1e6ac62e84ded130aa655c5e9Brian   if (!rb || !texture) {						\
1928e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      return;								\
193e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
194e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
195920023240c2fc42675f318732b43bdc6f339113cBrian Paul#define RENDER_SPAN( span )						\
1969bf68ad963ba92b5d1e725f965979042495a5313Brian Paul   GLuint i;				    				\
1973fa7dbf368bb060220e9f78e666b00d6827166a6Brian Paul   GLubyte rgb[MAX_WIDTH][3];						\
19877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   span.intTex[0] -= FIXED_HALF; /* off-by-one error? */		\
19977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   span.intTex[1] -= FIXED_HALF;					\
20077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   for (i = 0; i < span.end; i++) {					\
2013e37bafab0a339021354b9c78f983d05d433d735Brian Paul      const GLuint z = FixedToDepth(span.z);				\
2029bf68ad963ba92b5d1e725f965979042495a5313Brian Paul      if (z < zRow[i]) {						\
20377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         GLint s = FixedToInt(span.intTex[0]) & smask;			\
20477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         GLint t = FixedToInt(span.intTex[1]) & tmask;			\
2059bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         GLint pos = (t << twidth_log2) + s;				\
2069bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         pos = pos + pos + pos;  /* multiply by 3 */			\
207086f9fc0e2aef27f54eda87c733685500555bf20Brian Paul         rgb[i][RCOMP] = texture[pos+2];				\
20857d705d5a939180bd992cad2f24d95c329b5b28cBrian Paul         rgb[i][GCOMP] = texture[pos+1];				\
209086f9fc0e2aef27f54eda87c733685500555bf20Brian Paul         rgb[i][BCOMP] = texture[pos+0];				\
2109bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         zRow[i] = z;							\
21177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         span.array->mask[i] = 1;					\
2129bf68ad963ba92b5d1e725f965979042495a5313Brian Paul      }									\
2139bf68ad963ba92b5d1e725f965979042495a5313Brian Paul      else {								\
21477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul         span.array->mask[i] = 0;					\
2159bf68ad963ba92b5d1e725f965979042495a5313Brian Paul      }									\
21677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul      span.intTex[0] += span.intTexStep[0];				\
21777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul      span.intTex[1] += span.intTexStep[1];				\
21877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul      span.z += span.zStep;						\
2199bf68ad963ba92b5d1e725f965979042495a5313Brian Paul   }									\
22057d705d5a939180bd992cad2f24d95c329b5b28cBrian Paul   rb->PutRowRGB(ctx, rb, span.end, span.x, span.y, rgb, span.array->mask);
221e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
222e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_tritemp.h"
223cdf2da368d180205df3573697b51b8764048ad6eBrian Paul
224e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
225f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul#if CHAN_TYPE != GL_FLOAT
226e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
2279bf68ad963ba92b5d1e725f965979042495a5313Brian Paulstruct affine_info
228e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
2299bf68ad963ba92b5d1e725f965979042495a5313Brian Paul   GLenum filter;
2309bf68ad963ba92b5d1e725f965979042495a5313Brian Paul   GLenum format;
2319bf68ad963ba92b5d1e725f965979042495a5313Brian Paul   GLenum envmode;
2329bf68ad963ba92b5d1e725f965979042495a5313Brian Paul   GLint smask, tmask;
2339bf68ad963ba92b5d1e725f965979042495a5313Brian Paul   GLint twidth_log2;
2349bf68ad963ba92b5d1e725f965979042495a5313Brian Paul   const GLchan *texture;
235fd1727bd1064ee2323c924cb4002d4d9a89780bfBrian Paul   GLfixed er, eg, eb, ea;
2369bf68ad963ba92b5d1e725f965979042495a5313Brian Paul   GLint tbytesline, tsize;
2379bf68ad963ba92b5d1e725f965979042495a5313Brian Paul};
238cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell
2397152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul
240f138b977d09327445a8e9c8126c493c4487c1630Brian Paulstatic INLINE GLint
241f138b977d09327445a8e9c8126c493c4487c1630Brian Paulilerp(GLint t, GLint a, GLint b)
242f138b977d09327445a8e9c8126c493c4487c1630Brian Paul{
243f138b977d09327445a8e9c8126c493c4487c1630Brian Paul   return a + ((t * (b - a)) >> FIXED_SHIFT);
244f138b977d09327445a8e9c8126c493c4487c1630Brian Paul}
245f138b977d09327445a8e9c8126c493c4487c1630Brian Paul
246f138b977d09327445a8e9c8126c493c4487c1630Brian Paulstatic INLINE GLint
247f138b977d09327445a8e9c8126c493c4487c1630Brian Paulilerp_2d(GLint ia, GLint ib, GLint v00, GLint v10, GLint v01, GLint v11)
248f138b977d09327445a8e9c8126c493c4487c1630Brian Paul{
249f138b977d09327445a8e9c8126c493c4487c1630Brian Paul   const GLint temp0 = ilerp(ia, v00, v10);
250f138b977d09327445a8e9c8126c493c4487c1630Brian Paul   const GLint temp1 = ilerp(ia, v01, v11);
251f138b977d09327445a8e9c8126c493c4487c1630Brian Paul   return ilerp(ib, temp0, temp1);
252f138b977d09327445a8e9c8126c493c4487c1630Brian Paul}
253f138b977d09327445a8e9c8126c493c4487c1630Brian Paul
254f138b977d09327445a8e9c8126c493c4487c1630Brian Paul
2557152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul/* This function can handle GL_NEAREST or GL_LINEAR sampling of 2D RGB or RGBA
2567152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul * textures with GL_REPLACE, GL_MODULATE, GL_BLEND, GL_DECAL or GL_ADD
2577152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul * texture env modes.
2587152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul */
25971340e861edf35bfdeb536718cd230fc33c41ee2Brian Paulstatic INLINE void
260f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergaffine_span(struct gl_context *ctx, SWspan *span,
2619bf68ad963ba92b5d1e725f965979042495a5313Brian Paul            struct affine_info *info)
2629bf68ad963ba92b5d1e725f965979042495a5313Brian Paul{
2637152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul   GLchan sample[4];  /* the filtered texture sample */
26407e50058a5699fc9279de6bf5d1449d52ccdc476Brian Paul   const GLuint texEnableSave = ctx->Texture._EnabledCoordUnits;
2658c7135ee14fb6f4d8b6e64d570daee3512c99438Brian Paul
266fae7b778b81b686ef419f971064b5fe12fb4ead3Brian Paul   /* Instead of defining a function for each mode, a test is done
267fae7b778b81b686ef419f971064b5fe12fb4ead3Brian Paul    * between the outer and inner loops. This is to reduce code size
268fae7b778b81b686ef419f971064b5fe12fb4ead3Brian Paul    * and complexity. Observe that an optimizing compiler kills
269fae7b778b81b686ef419f971064b5fe12fb4ead3Brian Paul    * unused variables (for instance tf,sf,ti,si in case of GL_NEAREST).
270fae7b778b81b686ef419f971064b5fe12fb4ead3Brian Paul    */
271e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
2728c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul#define NEAREST_RGB		\
2738c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul   sample[RCOMP] = tex00[2];	\
2748c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul   sample[GCOMP] = tex00[1];	\
2758c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul   sample[BCOMP] = tex00[0];	\
2768c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul   sample[ACOMP] = CHAN_MAX;
277e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
2789bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#define LINEAR_RGB							\
2798c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul   sample[RCOMP] = ilerp_2d(sf, tf, tex00[2], tex01[2], tex10[2], tex11[2]);\
280f138b977d09327445a8e9c8126c493c4487c1630Brian Paul   sample[GCOMP] = ilerp_2d(sf, tf, tex00[1], tex01[1], tex10[1], tex11[1]);\
2818c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul   sample[BCOMP] = ilerp_2d(sf, tf, tex00[0], tex01[0], tex10[0], tex11[0]);\
282f138b977d09327445a8e9c8126c493c4487c1630Brian Paul   sample[ACOMP] = CHAN_MAX;
283bbf6a41d2fd4a3d54e6b5dea50bba24768c01eceBrian Paul
2848c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul#define NEAREST_RGBA  \
2858c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul   sample[RCOMP] = tex00[3];	\
2868c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul   sample[GCOMP] = tex00[2];	\
2878c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul   sample[BCOMP] = tex00[1];	\
2888c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul   sample[ACOMP] = tex00[0];
289e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
2909bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#define LINEAR_RGBA							\
2918c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul   sample[RCOMP] = ilerp_2d(sf, tf, tex00[3], tex01[3], tex10[3], tex11[3]);\
2928c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul   sample[GCOMP] = ilerp_2d(sf, tf, tex00[2], tex01[2], tex10[2], tex11[2]);\
2938c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul   sample[BCOMP] = ilerp_2d(sf, tf, tex00[1], tex01[1], tex10[1], tex11[1]);\
2948c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul   sample[ACOMP] = ilerp_2d(sf, tf, tex00[0], tex01[0], tex10[0], tex11[0])
295bbf6a41d2fd4a3d54e6b5dea50bba24768c01eceBrian Paul
296fd1727bd1064ee2323c924cb4002d4d9a89780bfBrian Paul#define MODULATE							  \
2977152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul   dest[RCOMP] = span->red   * (sample[RCOMP] + 1u) >> (FIXED_SHIFT + 8); \
2987152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul   dest[GCOMP] = span->green * (sample[GCOMP] + 1u) >> (FIXED_SHIFT + 8); \
2997152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul   dest[BCOMP] = span->blue  * (sample[BCOMP] + 1u) >> (FIXED_SHIFT + 8); \
3007152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul   dest[ACOMP] = span->alpha * (sample[ACOMP] + 1u) >> (FIXED_SHIFT + 8)
3019bf68ad963ba92b5d1e725f965979042495a5313Brian Paul
3029bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#define DECAL								\
3037152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul   dest[RCOMP] = ((CHAN_MAX - sample[ACOMP]) * span->red +		\
3047152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul               ((sample[ACOMP] + 1) * sample[RCOMP] << FIXED_SHIFT))	\
305bbf6a41d2fd4a3d54e6b5dea50bba24768c01eceBrian Paul               >> (FIXED_SHIFT + 8);					\
3067152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul   dest[GCOMP] = ((CHAN_MAX - sample[ACOMP]) * span->green +		\
3077152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul               ((sample[ACOMP] + 1) * sample[GCOMP] << FIXED_SHIFT))	\
308bbf6a41d2fd4a3d54e6b5dea50bba24768c01eceBrian Paul               >> (FIXED_SHIFT + 8);					\
3097152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul   dest[BCOMP] = ((CHAN_MAX - sample[ACOMP]) * span->blue +		\
3107152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul               ((sample[ACOMP] + 1) * sample[BCOMP] << FIXED_SHIFT))	\
311bbf6a41d2fd4a3d54e6b5dea50bba24768c01eceBrian Paul               >> (FIXED_SHIFT + 8);					\
312bbf6a41d2fd4a3d54e6b5dea50bba24768c01eceBrian Paul   dest[ACOMP] = FixedToInt(span->alpha)
3139bf68ad963ba92b5d1e725f965979042495a5313Brian Paul
3149bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#define BLEND								\
3157152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul   dest[RCOMP] = ((CHAN_MAX - sample[RCOMP]) * span->red		\
3167152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul               + (sample[RCOMP] + 1) * info->er) >> (FIXED_SHIFT + 8);	\
3177152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul   dest[GCOMP] = ((CHAN_MAX - sample[GCOMP]) * span->green		\
3187152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul               + (sample[GCOMP] + 1) * info->eg) >> (FIXED_SHIFT + 8);	\
3197152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul   dest[BCOMP] = ((CHAN_MAX - sample[BCOMP]) * span->blue		\
3207152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul               + (sample[BCOMP] + 1) * info->eb) >> (FIXED_SHIFT + 8);	\
3217152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul   dest[ACOMP] = span->alpha * (sample[ACOMP] + 1) >> (FIXED_SHIFT + 8)
322bbf6a41d2fd4a3d54e6b5dea50bba24768c01eceBrian Paul
3237152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul#define REPLACE  COPY_CHAN4(dest, sample)
324e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
3259bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#define ADD								\
3267152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul   {									\
3277152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul      GLint rSum = FixedToInt(span->red)   + (GLint) sample[RCOMP];	\
3287152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul      GLint gSum = FixedToInt(span->green) + (GLint) sample[GCOMP];	\
3297152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul      GLint bSum = FixedToInt(span->blue)  + (GLint) sample[BCOMP];	\
3307152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul      dest[RCOMP] = MIN2(rSum, CHAN_MAX);				\
3317152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul      dest[GCOMP] = MIN2(gSum, CHAN_MAX);				\
3327152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul      dest[BCOMP] = MIN2(bSum, CHAN_MAX);				\
3337152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul      dest[ACOMP] = span->alpha * (sample[ACOMP] + 1) >> (FIXED_SHIFT + 8); \
3347152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul  }
335e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
336e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/* shortcuts */
337e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
33835e5e89f5614ebb032479b02dec888563f829b30Brian Paul#define NEAREST_RGB_REPLACE		\
33935e5e89f5614ebb032479b02dec888563f829b30Brian Paul   NEAREST_RGB;				\
34035e5e89f5614ebb032479b02dec888563f829b30Brian Paul   dest[0] = sample[0];			\
34135e5e89f5614ebb032479b02dec888563f829b30Brian Paul   dest[1] = sample[1];			\
34235e5e89f5614ebb032479b02dec888563f829b30Brian Paul   dest[2] = sample[2];			\
34335e5e89f5614ebb032479b02dec888563f829b30Brian Paul   dest[3] = FixedToInt(span->alpha);
344e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
3458c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul#define NEAREST_RGBA_REPLACE  \
3468c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul   dest[RCOMP] = tex00[3]; \
3478c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul   dest[GCOMP] = tex00[2]; \
3488c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul   dest[BCOMP] = tex00[1]; \
3498c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul   dest[ACOMP] = tex00[0]
350e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
351f138b977d09327445a8e9c8126c493c4487c1630Brian Paul#define SPAN_NEAREST(DO_TEX, COMPS)					\
35257d6e1aebf1f850686a2c8d3a246fb388ec23979Brian Paul	for (i = 0; i < span->end; i++) {				\
35333170eeb185f5fe766374a749464497cdfab6931Brian Paul           /* Isn't it necessary to use FixedFloor below?? */		\
3549bf68ad963ba92b5d1e725f965979042495a5313Brian Paul           GLint s = FixedToInt(span->intTex[0]) & info->smask;		\
3559bf68ad963ba92b5d1e725f965979042495a5313Brian Paul           GLint t = FixedToInt(span->intTex[1]) & info->tmask;		\
3569bf68ad963ba92b5d1e725f965979042495a5313Brian Paul           GLint pos = (t << info->twidth_log2) + s;			\
357f138b977d09327445a8e9c8126c493c4487c1630Brian Paul           const GLchan *tex00 = info->texture + COMPS * pos;		\
3589bf68ad963ba92b5d1e725f965979042495a5313Brian Paul           DO_TEX;							\
3599bf68ad963ba92b5d1e725f965979042495a5313Brian Paul           span->red += span->redStep;					\
3609bf68ad963ba92b5d1e725f965979042495a5313Brian Paul	   span->green += span->greenStep;				\
3619bf68ad963ba92b5d1e725f965979042495a5313Brian Paul           span->blue += span->blueStep;				\
3629bf68ad963ba92b5d1e725f965979042495a5313Brian Paul	   span->alpha += span->alphaStep;				\
3639bf68ad963ba92b5d1e725f965979042495a5313Brian Paul	   span->intTex[0] += span->intTexStep[0];			\
3649bf68ad963ba92b5d1e725f965979042495a5313Brian Paul	   span->intTex[1] += span->intTexStep[1];			\
3659bf68ad963ba92b5d1e725f965979042495a5313Brian Paul           dest += 4;							\
366e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell	}
367e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
368f138b977d09327445a8e9c8126c493c4487c1630Brian Paul#define SPAN_LINEAR(DO_TEX, COMPS)					\
36957d6e1aebf1f850686a2c8d3a246fb388ec23979Brian Paul	for (i = 0; i < span->end; i++) {				\
37033170eeb185f5fe766374a749464497cdfab6931Brian Paul           /* Isn't it necessary to use FixedFloor below?? */		\
371f138b977d09327445a8e9c8126c493c4487c1630Brian Paul           const GLint s = FixedToInt(span->intTex[0]) & info->smask;	\
372f138b977d09327445a8e9c8126c493c4487c1630Brian Paul           const GLint t = FixedToInt(span->intTex[1]) & info->tmask;	\
373f138b977d09327445a8e9c8126c493c4487c1630Brian Paul           const GLfixed sf = span->intTex[0] & FIXED_FRAC_MASK;	\
374f138b977d09327445a8e9c8126c493c4487c1630Brian Paul           const GLfixed tf = span->intTex[1] & FIXED_FRAC_MASK;	\
375f138b977d09327445a8e9c8126c493c4487c1630Brian Paul           const GLint pos = (t << info->twidth_log2) + s;		\
376f138b977d09327445a8e9c8126c493c4487c1630Brian Paul           const GLchan *tex00 = info->texture + COMPS * pos;		\
3779bf68ad963ba92b5d1e725f965979042495a5313Brian Paul           const GLchan *tex10 = tex00 + info->tbytesline;		\
378f138b977d09327445a8e9c8126c493c4487c1630Brian Paul           const GLchan *tex01 = tex00 + COMPS;				\
379f138b977d09327445a8e9c8126c493c4487c1630Brian Paul           const GLchan *tex11 = tex10 + COMPS;				\
3809bf68ad963ba92b5d1e725f965979042495a5313Brian Paul           if (t == info->tmask) {					\
3819bf68ad963ba92b5d1e725f965979042495a5313Brian Paul              tex10 -= info->tsize;					\
3829bf68ad963ba92b5d1e725f965979042495a5313Brian Paul              tex11 -= info->tsize;					\
3839bf68ad963ba92b5d1e725f965979042495a5313Brian Paul           }								\
3849bf68ad963ba92b5d1e725f965979042495a5313Brian Paul           if (s == info->smask) {					\
3859bf68ad963ba92b5d1e725f965979042495a5313Brian Paul              tex01 -= info->tbytesline;				\
3869bf68ad963ba92b5d1e725f965979042495a5313Brian Paul              tex11 -= info->tbytesline;				\
3879bf68ad963ba92b5d1e725f965979042495a5313Brian Paul           }								\
3889bf68ad963ba92b5d1e725f965979042495a5313Brian Paul           DO_TEX;							\
3899bf68ad963ba92b5d1e725f965979042495a5313Brian Paul           span->red += span->redStep;					\
3909bf68ad963ba92b5d1e725f965979042495a5313Brian Paul	   span->green += span->greenStep;				\
3919bf68ad963ba92b5d1e725f965979042495a5313Brian Paul           span->blue += span->blueStep;				\
3929bf68ad963ba92b5d1e725f965979042495a5313Brian Paul	   span->alpha += span->alphaStep;				\
3939bf68ad963ba92b5d1e725f965979042495a5313Brian Paul	   span->intTex[0] += span->intTexStep[0];			\
3949bf68ad963ba92b5d1e725f965979042495a5313Brian Paul	   span->intTex[1] += span->intTexStep[1];			\
3959bf68ad963ba92b5d1e725f965979042495a5313Brian Paul           dest += 4;							\
396e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell	}
397e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
3989bf68ad963ba92b5d1e725f965979042495a5313Brian Paul
3999bf68ad963ba92b5d1e725f965979042495a5313Brian Paul   GLuint i;
40077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   GLchan *dest = span->array->rgba[0];
40157d6e1aebf1f850686a2c8d3a246fb388ec23979Brian Paul
40292ced46eaf1f389108ed8d3d788498d799f0b385Brian Paul   /* Disable tex units so they're not re-applied in swrast_write_rgba_span */
40307e50058a5699fc9279de6bf5d1449d52ccdc476Brian Paul   ctx->Texture._EnabledCoordUnits = 0x0;
40492ced46eaf1f389108ed8d3d788498d799f0b385Brian Paul
4059bf68ad963ba92b5d1e725f965979042495a5313Brian Paul   span->intTex[0] -= FIXED_HALF;
4069bf68ad963ba92b5d1e725f965979042495a5313Brian Paul   span->intTex[1] -= FIXED_HALF;
4079bf68ad963ba92b5d1e725f965979042495a5313Brian Paul   switch (info->filter) {
4089bf68ad963ba92b5d1e725f965979042495a5313Brian Paul   case GL_NEAREST:
4099bf68ad963ba92b5d1e725f965979042495a5313Brian Paul      switch (info->format) {
4108c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul      case MESA_FORMAT_RGB888:
4119bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         switch (info->envmode) {
4129bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         case GL_MODULATE:
41333170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_NEAREST(NEAREST_RGB;MODULATE,3);
4149bf68ad963ba92b5d1e725f965979042495a5313Brian Paul            break;
4159bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         case GL_DECAL:
4169bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         case GL_REPLACE:
41733170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_NEAREST(NEAREST_RGB_REPLACE,3);
4189bf68ad963ba92b5d1e725f965979042495a5313Brian Paul            break;
4199bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         case GL_BLEND:
42033170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_NEAREST(NEAREST_RGB;BLEND,3);
4219bf68ad963ba92b5d1e725f965979042495a5313Brian Paul            break;
4229bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         case GL_ADD:
42333170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_NEAREST(NEAREST_RGB;ADD,3);
4249bf68ad963ba92b5d1e725f965979042495a5313Brian Paul            break;
4259bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         default:
4264663bd50f1e2f219bd1b2a4d902b11b936512398Brian Paul            _mesa_problem(ctx, "bad tex env mode in SPAN_LINEAR");
4274663bd50f1e2f219bd1b2a4d902b11b936512398Brian Paul            return;
4289bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         }
4299bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         break;
4308c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul      case MESA_FORMAT_RGBA8888:
4319bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         switch(info->envmode) {
4329bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         case GL_MODULATE:
43333170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_NEAREST(NEAREST_RGBA;MODULATE,4);
4349bf68ad963ba92b5d1e725f965979042495a5313Brian Paul            break;
4359bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         case GL_DECAL:
43633170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_NEAREST(NEAREST_RGBA;DECAL,4);
4379bf68ad963ba92b5d1e725f965979042495a5313Brian Paul            break;
4389bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         case GL_BLEND:
43933170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_NEAREST(NEAREST_RGBA;BLEND,4);
4409bf68ad963ba92b5d1e725f965979042495a5313Brian Paul            break;
4419bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         case GL_ADD:
44233170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_NEAREST(NEAREST_RGBA;ADD,4);
4439bf68ad963ba92b5d1e725f965979042495a5313Brian Paul            break;
4449bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         case GL_REPLACE:
44533170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_NEAREST(NEAREST_RGBA_REPLACE,4);
4469bf68ad963ba92b5d1e725f965979042495a5313Brian Paul            break;
4479bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         default:
4484663bd50f1e2f219bd1b2a4d902b11b936512398Brian Paul            _mesa_problem(ctx, "bad tex env mode (2) in SPAN_LINEAR");
4494663bd50f1e2f219bd1b2a4d902b11b936512398Brian Paul            return;
4509bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         }
4519bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         break;
4529bf68ad963ba92b5d1e725f965979042495a5313Brian Paul      }
4539bf68ad963ba92b5d1e725f965979042495a5313Brian Paul      break;
4549bf68ad963ba92b5d1e725f965979042495a5313Brian Paul
4559bf68ad963ba92b5d1e725f965979042495a5313Brian Paul   case GL_LINEAR:
4569bf68ad963ba92b5d1e725f965979042495a5313Brian Paul      span->intTex[0] -= FIXED_HALF;
4579bf68ad963ba92b5d1e725f965979042495a5313Brian Paul      span->intTex[1] -= FIXED_HALF;
4589bf68ad963ba92b5d1e725f965979042495a5313Brian Paul      switch (info->format) {
4598c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul      case MESA_FORMAT_RGB888:
4609bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         switch (info->envmode) {
4619bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         case GL_MODULATE:
46233170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_LINEAR(LINEAR_RGB;MODULATE,3);
4639bf68ad963ba92b5d1e725f965979042495a5313Brian Paul            break;
4649bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         case GL_DECAL:
4659bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         case GL_REPLACE:
46633170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_LINEAR(LINEAR_RGB;REPLACE,3);
4679bf68ad963ba92b5d1e725f965979042495a5313Brian Paul            break;
4689bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         case GL_BLEND:
46933170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_LINEAR(LINEAR_RGB;BLEND,3);
4709bf68ad963ba92b5d1e725f965979042495a5313Brian Paul            break;
4719bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         case GL_ADD:
47233170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_LINEAR(LINEAR_RGB;ADD,3);
4739bf68ad963ba92b5d1e725f965979042495a5313Brian Paul            break;
4749bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         default:
4754663bd50f1e2f219bd1b2a4d902b11b936512398Brian Paul            _mesa_problem(ctx, "bad tex env mode (3) in SPAN_LINEAR");
4764663bd50f1e2f219bd1b2a4d902b11b936512398Brian Paul            return;
4779bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         }
4789bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         break;
4798c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul      case MESA_FORMAT_RGBA8888:
4809bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         switch (info->envmode) {
4819bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         case GL_MODULATE:
48233170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_LINEAR(LINEAR_RGBA;MODULATE,4);
4839bf68ad963ba92b5d1e725f965979042495a5313Brian Paul            break;
4849bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         case GL_DECAL:
48533170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_LINEAR(LINEAR_RGBA;DECAL,4);
4869bf68ad963ba92b5d1e725f965979042495a5313Brian Paul            break;
4879bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         case GL_BLEND:
48833170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_LINEAR(LINEAR_RGBA;BLEND,4);
4899bf68ad963ba92b5d1e725f965979042495a5313Brian Paul            break;
4909bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         case GL_ADD:
49133170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_LINEAR(LINEAR_RGBA;ADD,4);
4929bf68ad963ba92b5d1e725f965979042495a5313Brian Paul            break;
4939bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         case GL_REPLACE:
49433170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_LINEAR(LINEAR_RGBA;REPLACE,4);
4959bf68ad963ba92b5d1e725f965979042495a5313Brian Paul            break;
4969bf68ad963ba92b5d1e725f965979042495a5313Brian Paul         default:
4974663bd50f1e2f219bd1b2a4d902b11b936512398Brian Paul            _mesa_problem(ctx, "bad tex env mode (4) in SPAN_LINEAR");
4984663bd50f1e2f219bd1b2a4d902b11b936512398Brian Paul            return;
4994663bd50f1e2f219bd1b2a4d902b11b936512398Brian Paul         }
5004663bd50f1e2f219bd1b2a4d902b11b936512398Brian Paul         break;
5019bf68ad963ba92b5d1e725f965979042495a5313Brian Paul      }
5029bf68ad963ba92b5d1e725f965979042495a5313Brian Paul      break;
5039bf68ad963ba92b5d1e725f965979042495a5313Brian Paul   }
504733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul   span->interpMask &= ~SPAN_RGBA;
5052a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   ASSERT(span->arrayMask & SPAN_RGBA);
5068c7135ee14fb6f4d8b6e64d570daee3512c99438Brian Paul
50745bc887da226403f2c41077e40ca38b6f60f1359Brian Paul   _swrast_write_rgba_span(ctx, span);
508e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
5098c7135ee14fb6f4d8b6e64d570daee3512c99438Brian Paul   /* re-enable texture units */
51007e50058a5699fc9279de6bf5d1449d52ccdc476Brian Paul   ctx->Texture._EnabledCoordUnits = texEnableSave;
5118c7135ee14fb6f4d8b6e64d570daee3512c99438Brian Paul
51233170eeb185f5fe766374a749464497cdfab6931Brian Paul#undef SPAN_NEAREST
51333170eeb185f5fe766374a749464497cdfab6931Brian Paul#undef SPAN_LINEAR
514e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
515e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
516e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
517e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
518e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
5199bf68ad963ba92b5d1e725f965979042495a5313Brian Paul * Render an RGB/RGBA textured triangle without perspective correction.
5209bf68ad963ba92b5d1e725f965979042495a5313Brian Paul */
521cdf2da368d180205df3573697b51b8764048ad6eBrian Paul#define NAME affine_textured_triangle
5229bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#define INTERP_Z 1
5239bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#define INTERP_RGB 1
5249bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#define INTERP_ALPHA 1
5259bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#define INTERP_INT_TEX 1
5269bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#define S_SCALE twidth
5279bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#define T_SCALE theight
5289bf68ad963ba92b5d1e725f965979042495a5313Brian Paul
529571c8ecc8f9442fb8bbaa1f29b1d0d4f8e5b3cadBrian Paul#define SETUP_CODE							\
530571c8ecc8f9442fb8bbaa1f29b1d0d4f8e5b3cadBrian Paul   struct affine_info info;						\
5319bf68ad963ba92b5d1e725f965979042495a5313Brian Paul   struct gl_texture_unit *unit = ctx->Texture.Unit+0;			\
5320103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   const struct gl_texture_object *obj = 				\
5339818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul      ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX];		\
5340103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   const struct gl_texture_image *texImg = 				\
5350103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul      obj->Image[0][obj->BaseLevel]; 					\
5360103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   const GLfloat twidth = (GLfloat) texImg->Width;			\
5370103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   const GLfloat theight = (GLfloat) texImg->Height;			\
5380103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   info.texture = (const GLchan *) texImg->Data;			\
5390103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   info.twidth_log2 = texImg->WidthLog2;				\
5400103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   info.smask = texImg->Width - 1;					\
5410103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   info.tmask = texImg->Height - 1;					\
5420103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   info.format = texImg->TexFormat;					\
543ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   info.filter = obj->Sampler.MinFilter;				\
5449bf68ad963ba92b5d1e725f965979042495a5313Brian Paul   info.envmode = unit->EnvMode;					\
545555dc25c4c5a0991fb6846ccc263a195717512deVinson Lee   info.er = 0;					\
546555dc25c4c5a0991fb6846ccc263a195717512deVinson Lee   info.eg = 0;					\
547555dc25c4c5a0991fb6846ccc263a195717512deVinson Lee   info.eb = 0;					\
54877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   span.arrayMask |= SPAN_RGBA;						\
5499bf68ad963ba92b5d1e725f965979042495a5313Brian Paul									\
5509bf68ad963ba92b5d1e725f965979042495a5313Brian Paul   if (info.envmode == GL_BLEND) {					\
5519bf68ad963ba92b5d1e725f965979042495a5313Brian Paul      /* potential off-by-one error here? (1.0f -> 2048 -> 0) */	\
552fd1727bd1064ee2323c924cb4002d4d9a89780bfBrian Paul      info.er = FloatToFixed(unit->EnvColor[RCOMP] * CHAN_MAXF);	\
553fd1727bd1064ee2323c924cb4002d4d9a89780bfBrian Paul      info.eg = FloatToFixed(unit->EnvColor[GCOMP] * CHAN_MAXF);	\
554fd1727bd1064ee2323c924cb4002d4d9a89780bfBrian Paul      info.eb = FloatToFixed(unit->EnvColor[BCOMP] * CHAN_MAXF);	\
555fd1727bd1064ee2323c924cb4002d4d9a89780bfBrian Paul      info.ea = FloatToFixed(unit->EnvColor[ACOMP] * CHAN_MAXF);	\
5569bf68ad963ba92b5d1e725f965979042495a5313Brian Paul   }									\
5579bf68ad963ba92b5d1e725f965979042495a5313Brian Paul   if (!info.texture) {							\
5589bf68ad963ba92b5d1e725f965979042495a5313Brian Paul      /* this shouldn't happen */					\
5599bf68ad963ba92b5d1e725f965979042495a5313Brian Paul      return;								\
5609bf68ad963ba92b5d1e725f965979042495a5313Brian Paul   }									\
5619bf68ad963ba92b5d1e725f965979042495a5313Brian Paul									\
5629bf68ad963ba92b5d1e725f965979042495a5313Brian Paul   switch (info.format) {						\
5638c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul   case MESA_FORMAT_RGB888:						\
5640103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul      info.tbytesline = texImg->Width * 3;				\
5659bf68ad963ba92b5d1e725f965979042495a5313Brian Paul      break;								\
5668c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul   case MESA_FORMAT_RGBA8888:						\
5670103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul      info.tbytesline = texImg->Width * 4;				\
5689bf68ad963ba92b5d1e725f965979042495a5313Brian Paul      break;								\
5699bf68ad963ba92b5d1e725f965979042495a5313Brian Paul   default:								\
5709bf68ad963ba92b5d1e725f965979042495a5313Brian Paul      _mesa_problem(NULL, "Bad texture format in affine_texture_triangle");\
5719bf68ad963ba92b5d1e725f965979042495a5313Brian Paul      return;								\
5729bf68ad963ba92b5d1e725f965979042495a5313Brian Paul   }									\
5730103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   info.tsize = texImg->Height * info.tbytesline;
5749bf68ad963ba92b5d1e725f965979042495a5313Brian Paul
57577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul#define RENDER_SPAN( span )   affine_span(ctx, &span, &info);
5769bf68ad963ba92b5d1e725f965979042495a5313Brian Paul
5779bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#include "s_tritemp.h"
5789bf68ad963ba92b5d1e725f965979042495a5313Brian Paul
579f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul
5809bf68ad963ba92b5d1e725f965979042495a5313Brian Paul
58133170eeb185f5fe766374a749464497cdfab6931Brian Paulstruct persp_info
582e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
58333170eeb185f5fe766374a749464497cdfab6931Brian Paul   GLenum filter;
58433170eeb185f5fe766374a749464497cdfab6931Brian Paul   GLenum format;
58533170eeb185f5fe766374a749464497cdfab6931Brian Paul   GLenum envmode;
58633170eeb185f5fe766374a749464497cdfab6931Brian Paul   GLint smask, tmask;
58733170eeb185f5fe766374a749464497cdfab6931Brian Paul   GLint twidth_log2;
58833170eeb185f5fe766374a749464497cdfab6931Brian Paul   const GLchan *texture;
589fd1727bd1064ee2323c924cb4002d4d9a89780bfBrian Paul   GLfixed er, eg, eb, ea;   /* texture env color */
59033170eeb185f5fe766374a749464497cdfab6931Brian Paul   GLint tbytesline, tsize;
59133170eeb185f5fe766374a749464497cdfab6931Brian Paul};
592e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
593f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul
59471340e861edf35bfdeb536718cd230fc33c41ee2Brian Paulstatic INLINE void
595f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergfast_persp_span(struct gl_context *ctx, SWspan *span,
59633170eeb185f5fe766374a749464497cdfab6931Brian Paul		struct persp_info *info)
59733170eeb185f5fe766374a749464497cdfab6931Brian Paul{
5987152305e0a7d963f49c05bc530e495dc3ad82e3bBrian Paul   GLchan sample[4];  /* the filtered texture sample */
5999bf68ad963ba92b5d1e725f965979042495a5313Brian Paul
60033170eeb185f5fe766374a749464497cdfab6931Brian Paul  /* Instead of defining a function for each mode, a test is done
60133170eeb185f5fe766374a749464497cdfab6931Brian Paul   * between the outer and inner loops. This is to reduce code size
60233170eeb185f5fe766374a749464497cdfab6931Brian Paul   * and complexity. Observe that an optimizing compiler kills
60333170eeb185f5fe766374a749464497cdfab6931Brian Paul   * unused variables (for instance tf,sf,ti,si in case of GL_NEAREST).
60433170eeb185f5fe766374a749464497cdfab6931Brian Paul   */
60533170eeb185f5fe766374a749464497cdfab6931Brian Paul#define SPAN_NEAREST(DO_TEX,COMP)					\
60657d6e1aebf1f850686a2c8d3a246fb388ec23979Brian Paul	for (i = 0; i < span->end; i++) {				\
60733170eeb185f5fe766374a749464497cdfab6931Brian Paul           GLdouble invQ = tex_coord[2] ?				\
60833170eeb185f5fe766374a749464497cdfab6931Brian Paul                                 (1.0 / tex_coord[2]) : 1.0;            \
6097c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz           GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ);		\
6107c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz           GLfloat t_tmp = (GLfloat) (tex_coord[1] * invQ);		\
61133170eeb185f5fe766374a749464497cdfab6931Brian Paul           GLint s = IFLOOR(s_tmp) & info->smask;	        	\
61233170eeb185f5fe766374a749464497cdfab6931Brian Paul           GLint t = IFLOOR(t_tmp) & info->tmask;	        	\
61333170eeb185f5fe766374a749464497cdfab6931Brian Paul           GLint pos = (t << info->twidth_log2) + s;			\
61433170eeb185f5fe766374a749464497cdfab6931Brian Paul           const GLchan *tex00 = info->texture + COMP * pos;		\
61533170eeb185f5fe766374a749464497cdfab6931Brian Paul           DO_TEX;							\
61633170eeb185f5fe766374a749464497cdfab6931Brian Paul           span->red += span->redStep;					\
61733170eeb185f5fe766374a749464497cdfab6931Brian Paul	   span->green += span->greenStep;				\
61833170eeb185f5fe766374a749464497cdfab6931Brian Paul           span->blue += span->blueStep;				\
61933170eeb185f5fe766374a749464497cdfab6931Brian Paul	   span->alpha += span->alphaStep;				\
62033170eeb185f5fe766374a749464497cdfab6931Brian Paul	   tex_coord[0] += tex_step[0];					\
62133170eeb185f5fe766374a749464497cdfab6931Brian Paul	   tex_coord[1] += tex_step[1];					\
62233170eeb185f5fe766374a749464497cdfab6931Brian Paul	   tex_coord[2] += tex_step[2];					\
62333170eeb185f5fe766374a749464497cdfab6931Brian Paul           dest += 4;							\
62433170eeb185f5fe766374a749464497cdfab6931Brian Paul	}
625e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
62633170eeb185f5fe766374a749464497cdfab6931Brian Paul#define SPAN_LINEAR(DO_TEX,COMP)					\
62757d6e1aebf1f850686a2c8d3a246fb388ec23979Brian Paul	for (i = 0; i < span->end; i++) {				\
62833170eeb185f5fe766374a749464497cdfab6931Brian Paul           GLdouble invQ = tex_coord[2] ?				\
62933170eeb185f5fe766374a749464497cdfab6931Brian Paul                                 (1.0 / tex_coord[2]) : 1.0;            \
630f138b977d09327445a8e9c8126c493c4487c1630Brian Paul           const GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ);	\
631f138b977d09327445a8e9c8126c493c4487c1630Brian Paul           const GLfloat t_tmp = (GLfloat) (tex_coord[1] * invQ);	\
632f138b977d09327445a8e9c8126c493c4487c1630Brian Paul           const GLfixed s_fix = FloatToFixed(s_tmp) - FIXED_HALF;	\
633f138b977d09327445a8e9c8126c493c4487c1630Brian Paul           const GLfixed t_fix = FloatToFixed(t_tmp) - FIXED_HALF;      \
634f138b977d09327445a8e9c8126c493c4487c1630Brian Paul           const GLint s = FixedToInt(FixedFloor(s_fix)) & info->smask;	\
635f138b977d09327445a8e9c8126c493c4487c1630Brian Paul           const GLint t = FixedToInt(FixedFloor(t_fix)) & info->tmask;	\
636f138b977d09327445a8e9c8126c493c4487c1630Brian Paul           const GLfixed sf = s_fix & FIXED_FRAC_MASK;			\
637f138b977d09327445a8e9c8126c493c4487c1630Brian Paul           const GLfixed tf = t_fix & FIXED_FRAC_MASK;			\
638f138b977d09327445a8e9c8126c493c4487c1630Brian Paul           const GLint pos = (t << info->twidth_log2) + s;		\
63933170eeb185f5fe766374a749464497cdfab6931Brian Paul           const GLchan *tex00 = info->texture + COMP * pos;		\
64033170eeb185f5fe766374a749464497cdfab6931Brian Paul           const GLchan *tex10 = tex00 + info->tbytesline;		\
64133170eeb185f5fe766374a749464497cdfab6931Brian Paul           const GLchan *tex01 = tex00 + COMP;				\
64233170eeb185f5fe766374a749464497cdfab6931Brian Paul           const GLchan *tex11 = tex10 + COMP;				\
64333170eeb185f5fe766374a749464497cdfab6931Brian Paul           if (t == info->tmask) {					\
64433170eeb185f5fe766374a749464497cdfab6931Brian Paul              tex10 -= info->tsize;					\
64533170eeb185f5fe766374a749464497cdfab6931Brian Paul              tex11 -= info->tsize;					\
64633170eeb185f5fe766374a749464497cdfab6931Brian Paul           }								\
64733170eeb185f5fe766374a749464497cdfab6931Brian Paul           if (s == info->smask) {					\
64833170eeb185f5fe766374a749464497cdfab6931Brian Paul              tex01 -= info->tbytesline;				\
64933170eeb185f5fe766374a749464497cdfab6931Brian Paul              tex11 -= info->tbytesline;				\
65033170eeb185f5fe766374a749464497cdfab6931Brian Paul           }								\
65133170eeb185f5fe766374a749464497cdfab6931Brian Paul           DO_TEX;							\
65233170eeb185f5fe766374a749464497cdfab6931Brian Paul           span->red   += span->redStep;				\
65333170eeb185f5fe766374a749464497cdfab6931Brian Paul	   span->green += span->greenStep;				\
65433170eeb185f5fe766374a749464497cdfab6931Brian Paul           span->blue  += span->blueStep;				\
65533170eeb185f5fe766374a749464497cdfab6931Brian Paul	   span->alpha += span->alphaStep;				\
65633170eeb185f5fe766374a749464497cdfab6931Brian Paul	   tex_coord[0] += tex_step[0];					\
65733170eeb185f5fe766374a749464497cdfab6931Brian Paul	   tex_coord[1] += tex_step[1];					\
65833170eeb185f5fe766374a749464497cdfab6931Brian Paul	   tex_coord[2] += tex_step[2];					\
65933170eeb185f5fe766374a749464497cdfab6931Brian Paul           dest += 4;							\
66033170eeb185f5fe766374a749464497cdfab6931Brian Paul	}
661e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
66233170eeb185f5fe766374a749464497cdfab6931Brian Paul   GLuint i;
66333170eeb185f5fe766374a749464497cdfab6931Brian Paul   GLfloat tex_coord[3], tex_step[3];
66477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   GLchan *dest = span->array->rgba[0];
66557d6e1aebf1f850686a2c8d3a246fb388ec23979Brian Paul
66607e50058a5699fc9279de6bf5d1449d52ccdc476Brian Paul   const GLuint texEnableSave = ctx->Texture._EnabledCoordUnits;
66707e50058a5699fc9279de6bf5d1449d52ccdc476Brian Paul   ctx->Texture._EnabledCoordUnits = 0;
668a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul
6699ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian   tex_coord[0] = span->attrStart[FRAG_ATTRIB_TEX0][0]  * (info->smask + 1);
6709ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian   tex_step[0] = span->attrStepX[FRAG_ATTRIB_TEX0][0] * (info->smask + 1);
6719ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian   tex_coord[1] = span->attrStart[FRAG_ATTRIB_TEX0][1] * (info->tmask + 1);
6729ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian   tex_step[1] = span->attrStepX[FRAG_ATTRIB_TEX0][1] * (info->tmask + 1);
6739ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian   /* span->attrStart[FRAG_ATTRIB_TEX0][2] only if 3D-texturing, here only 2D */
6749ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian   tex_coord[2] = span->attrStart[FRAG_ATTRIB_TEX0][3];
6759ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian   tex_step[2] = span->attrStepX[FRAG_ATTRIB_TEX0][3];
676e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
67733170eeb185f5fe766374a749464497cdfab6931Brian Paul   switch (info->filter) {
67833170eeb185f5fe766374a749464497cdfab6931Brian Paul   case GL_NEAREST:
67933170eeb185f5fe766374a749464497cdfab6931Brian Paul      switch (info->format) {
6808c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul      case MESA_FORMAT_RGB888:
68133170eeb185f5fe766374a749464497cdfab6931Brian Paul         switch (info->envmode) {
68233170eeb185f5fe766374a749464497cdfab6931Brian Paul         case GL_MODULATE:
68333170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_NEAREST(NEAREST_RGB;MODULATE,3);
68433170eeb185f5fe766374a749464497cdfab6931Brian Paul            break;
68533170eeb185f5fe766374a749464497cdfab6931Brian Paul         case GL_DECAL:
68633170eeb185f5fe766374a749464497cdfab6931Brian Paul         case GL_REPLACE:
68733170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_NEAREST(NEAREST_RGB_REPLACE,3);
68833170eeb185f5fe766374a749464497cdfab6931Brian Paul            break;
68933170eeb185f5fe766374a749464497cdfab6931Brian Paul         case GL_BLEND:
69033170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_NEAREST(NEAREST_RGB;BLEND,3);
69133170eeb185f5fe766374a749464497cdfab6931Brian Paul            break;
69233170eeb185f5fe766374a749464497cdfab6931Brian Paul         case GL_ADD:
69333170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_NEAREST(NEAREST_RGB;ADD,3);
69433170eeb185f5fe766374a749464497cdfab6931Brian Paul            break;
69533170eeb185f5fe766374a749464497cdfab6931Brian Paul         default:
6964663bd50f1e2f219bd1b2a4d902b11b936512398Brian Paul            _mesa_problem(ctx, "bad tex env mode (5) in SPAN_LINEAR");
6974663bd50f1e2f219bd1b2a4d902b11b936512398Brian Paul            return;
69833170eeb185f5fe766374a749464497cdfab6931Brian Paul         }
69933170eeb185f5fe766374a749464497cdfab6931Brian Paul         break;
7008c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul      case MESA_FORMAT_RGBA8888:
70133170eeb185f5fe766374a749464497cdfab6931Brian Paul         switch(info->envmode) {
70233170eeb185f5fe766374a749464497cdfab6931Brian Paul         case GL_MODULATE:
70333170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_NEAREST(NEAREST_RGBA;MODULATE,4);
70433170eeb185f5fe766374a749464497cdfab6931Brian Paul            break;
70533170eeb185f5fe766374a749464497cdfab6931Brian Paul         case GL_DECAL:
70633170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_NEAREST(NEAREST_RGBA;DECAL,4);
70733170eeb185f5fe766374a749464497cdfab6931Brian Paul            break;
70833170eeb185f5fe766374a749464497cdfab6931Brian Paul         case GL_BLEND:
70933170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_NEAREST(NEAREST_RGBA;BLEND,4);
71033170eeb185f5fe766374a749464497cdfab6931Brian Paul            break;
71133170eeb185f5fe766374a749464497cdfab6931Brian Paul         case GL_ADD:
71233170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_NEAREST(NEAREST_RGBA;ADD,4);
71333170eeb185f5fe766374a749464497cdfab6931Brian Paul            break;
71433170eeb185f5fe766374a749464497cdfab6931Brian Paul         case GL_REPLACE:
71533170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_NEAREST(NEAREST_RGBA_REPLACE,4);
71633170eeb185f5fe766374a749464497cdfab6931Brian Paul            break;
71733170eeb185f5fe766374a749464497cdfab6931Brian Paul         default:
7184663bd50f1e2f219bd1b2a4d902b11b936512398Brian Paul            _mesa_problem(ctx, "bad tex env mode (6) in SPAN_LINEAR");
7194663bd50f1e2f219bd1b2a4d902b11b936512398Brian Paul            return;
72033170eeb185f5fe766374a749464497cdfab6931Brian Paul         }
72133170eeb185f5fe766374a749464497cdfab6931Brian Paul         break;
72233170eeb185f5fe766374a749464497cdfab6931Brian Paul      }
72333170eeb185f5fe766374a749464497cdfab6931Brian Paul      break;
72433170eeb185f5fe766374a749464497cdfab6931Brian Paul
72533170eeb185f5fe766374a749464497cdfab6931Brian Paul   case GL_LINEAR:
72633170eeb185f5fe766374a749464497cdfab6931Brian Paul      switch (info->format) {
7278c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul      case MESA_FORMAT_RGB888:
72833170eeb185f5fe766374a749464497cdfab6931Brian Paul         switch (info->envmode) {
72933170eeb185f5fe766374a749464497cdfab6931Brian Paul         case GL_MODULATE:
73033170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_LINEAR(LINEAR_RGB;MODULATE,3);
73133170eeb185f5fe766374a749464497cdfab6931Brian Paul            break;
73233170eeb185f5fe766374a749464497cdfab6931Brian Paul         case GL_DECAL:
73333170eeb185f5fe766374a749464497cdfab6931Brian Paul         case GL_REPLACE:
73433170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_LINEAR(LINEAR_RGB;REPLACE,3);
73533170eeb185f5fe766374a749464497cdfab6931Brian Paul            break;
73633170eeb185f5fe766374a749464497cdfab6931Brian Paul         case GL_BLEND:
73733170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_LINEAR(LINEAR_RGB;BLEND,3);
73833170eeb185f5fe766374a749464497cdfab6931Brian Paul            break;
73933170eeb185f5fe766374a749464497cdfab6931Brian Paul         case GL_ADD:
74033170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_LINEAR(LINEAR_RGB;ADD,3);
74133170eeb185f5fe766374a749464497cdfab6931Brian Paul            break;
74233170eeb185f5fe766374a749464497cdfab6931Brian Paul         default:
7434663bd50f1e2f219bd1b2a4d902b11b936512398Brian Paul            _mesa_problem(ctx, "bad tex env mode (7) in SPAN_LINEAR");
7444663bd50f1e2f219bd1b2a4d902b11b936512398Brian Paul            return;
74533170eeb185f5fe766374a749464497cdfab6931Brian Paul         }
74633170eeb185f5fe766374a749464497cdfab6931Brian Paul         break;
7478c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul      case MESA_FORMAT_RGBA8888:
74833170eeb185f5fe766374a749464497cdfab6931Brian Paul         switch (info->envmode) {
74933170eeb185f5fe766374a749464497cdfab6931Brian Paul         case GL_MODULATE:
75033170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_LINEAR(LINEAR_RGBA;MODULATE,4);
75133170eeb185f5fe766374a749464497cdfab6931Brian Paul            break;
75233170eeb185f5fe766374a749464497cdfab6931Brian Paul         case GL_DECAL:
75333170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_LINEAR(LINEAR_RGBA;DECAL,4);
75433170eeb185f5fe766374a749464497cdfab6931Brian Paul            break;
75533170eeb185f5fe766374a749464497cdfab6931Brian Paul         case GL_BLEND:
75633170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_LINEAR(LINEAR_RGBA;BLEND,4);
75733170eeb185f5fe766374a749464497cdfab6931Brian Paul            break;
75833170eeb185f5fe766374a749464497cdfab6931Brian Paul         case GL_ADD:
75933170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_LINEAR(LINEAR_RGBA;ADD,4);
76033170eeb185f5fe766374a749464497cdfab6931Brian Paul            break;
76133170eeb185f5fe766374a749464497cdfab6931Brian Paul         case GL_REPLACE:
76233170eeb185f5fe766374a749464497cdfab6931Brian Paul            SPAN_LINEAR(LINEAR_RGBA;REPLACE,4);
76333170eeb185f5fe766374a749464497cdfab6931Brian Paul            break;
76433170eeb185f5fe766374a749464497cdfab6931Brian Paul         default:
7654663bd50f1e2f219bd1b2a4d902b11b936512398Brian Paul            _mesa_problem(ctx, "bad tex env mode (8) in SPAN_LINEAR");
7664663bd50f1e2f219bd1b2a4d902b11b936512398Brian Paul            return;
76733170eeb185f5fe766374a749464497cdfab6931Brian Paul         }
76833170eeb185f5fe766374a749464497cdfab6931Brian Paul         break;
76933170eeb185f5fe766374a749464497cdfab6931Brian Paul      }
77033170eeb185f5fe766374a749464497cdfab6931Brian Paul      break;
771e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
77233170eeb185f5fe766374a749464497cdfab6931Brian Paul
7732a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul   ASSERT(span->arrayMask & SPAN_RGBA);
77445bc887da226403f2c41077e40ca38b6f60f1359Brian Paul   _swrast_write_rgba_span(ctx, span);
775e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
77633170eeb185f5fe766374a749464497cdfab6931Brian Paul#undef SPAN_NEAREST
77733170eeb185f5fe766374a749464497cdfab6931Brian Paul#undef SPAN_LINEAR
778a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul
779a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul   /* restore state */
78007e50058a5699fc9279de6bf5d1449d52ccdc476Brian Paul   ctx->Texture._EnabledCoordUnits = texEnableSave;
781e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
782e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
783e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
784e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
785e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Render an perspective corrected RGB/RGBA textured triangle.
786e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * The Q (aka V in Mesa) coordinate must be zero such that the divide
787e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * by interpolated Q/W comes out right.
788e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *
789e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
790cdf2da368d180205df3573697b51b8764048ad6eBrian Paul#define NAME persp_textured_triangle
791e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define INTERP_Z 1
792e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define INTERP_RGB 1
793e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define INTERP_ALPHA 1
7948a8a5bd104e8cd9362415db77d5f6a3945939589Brian#define INTERP_ATTRIBS 1
7959bf68ad963ba92b5d1e725f965979042495a5313Brian Paul
796571c8ecc8f9442fb8bbaa1f29b1d0d4f8e5b3cadBrian Paul#define SETUP_CODE							\
797571c8ecc8f9442fb8bbaa1f29b1d0d4f8e5b3cadBrian Paul   struct persp_info info;						\
7982ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul   const struct gl_texture_unit *unit = ctx->Texture.Unit+0;		\
7990103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   const struct gl_texture_object *obj = 				\
8009818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul      ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX];		\
8010103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   const struct gl_texture_image *texImg = 				\
8020103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul      obj->Image[0][obj->BaseLevel];			 		\
8030103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   info.texture = (const GLchan *) texImg->Data;			\
8040103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   info.twidth_log2 = texImg->WidthLog2;				\
8050103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   info.smask = texImg->Width - 1;					\
8060103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   info.tmask = texImg->Height - 1;					\
8070103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   info.format = texImg->TexFormat;					\
808ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   info.filter = obj->Sampler.MinFilter;				\
80933170eeb185f5fe766374a749464497cdfab6931Brian Paul   info.envmode = unit->EnvMode;					\
810555dc25c4c5a0991fb6846ccc263a195717512deVinson Lee   info.er = 0;					\
811555dc25c4c5a0991fb6846ccc263a195717512deVinson Lee   info.eg = 0;					\
812555dc25c4c5a0991fb6846ccc263a195717512deVinson Lee   info.eb = 0;					\
81333170eeb185f5fe766374a749464497cdfab6931Brian Paul									\
81433170eeb185f5fe766374a749464497cdfab6931Brian Paul   if (info.envmode == GL_BLEND) {					\
81533170eeb185f5fe766374a749464497cdfab6931Brian Paul      /* potential off-by-one error here? (1.0f -> 2048 -> 0) */	\
816fd1727bd1064ee2323c924cb4002d4d9a89780bfBrian Paul      info.er = FloatToFixed(unit->EnvColor[RCOMP] * CHAN_MAXF);	\
817fd1727bd1064ee2323c924cb4002d4d9a89780bfBrian Paul      info.eg = FloatToFixed(unit->EnvColor[GCOMP] * CHAN_MAXF);	\
818fd1727bd1064ee2323c924cb4002d4d9a89780bfBrian Paul      info.eb = FloatToFixed(unit->EnvColor[BCOMP] * CHAN_MAXF);	\
819fd1727bd1064ee2323c924cb4002d4d9a89780bfBrian Paul      info.ea = FloatToFixed(unit->EnvColor[ACOMP] * CHAN_MAXF);	\
82033170eeb185f5fe766374a749464497cdfab6931Brian Paul   }									\
82133170eeb185f5fe766374a749464497cdfab6931Brian Paul   if (!info.texture) {							\
82233170eeb185f5fe766374a749464497cdfab6931Brian Paul      /* this shouldn't happen */					\
8238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      return;								\
824e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }									\
82533170eeb185f5fe766374a749464497cdfab6931Brian Paul									\
82633170eeb185f5fe766374a749464497cdfab6931Brian Paul   switch (info.format) {						\
8278c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul   case MESA_FORMAT_RGB888:						\
8280103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul      info.tbytesline = texImg->Width * 3;				\
82933170eeb185f5fe766374a749464497cdfab6931Brian Paul      break;								\
8308c36ca707ca8879d6f888de7733ffb6b04ddc48aBrian Paul   case MESA_FORMAT_RGBA8888:						\
8310103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul      info.tbytesline = texImg->Width * 4;				\
83233170eeb185f5fe766374a749464497cdfab6931Brian Paul      break;								\
833e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   default:								\
834fae7b778b81b686ef419f971064b5fe12fb4ead3Brian Paul      _mesa_problem(NULL, "Bad texture format in persp_textured_triangle");\
83533170eeb185f5fe766374a749464497cdfab6931Brian Paul      return;								\
83633170eeb185f5fe766374a749464497cdfab6931Brian Paul   }									\
8370103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul   info.tsize = texImg->Height * info.tbytesline;
838e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
8397956292a765910077f50352d7cd0174e1e66d26cBrian Paul#define RENDER_SPAN( span )			\
84077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   span.interpMask &= ~SPAN_RGBA;		\
84177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   span.arrayMask |= SPAN_RGBA;			\
84277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   fast_persp_span(ctx, &span, &info);
843e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
844e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_tritemp.h"
845e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
8469e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#endif /*CHAN_TYPE != GL_FLOAT*/
847fae7b778b81b686ef419f971064b5fe12fb4ead3Brian Paul
8489bf68ad963ba92b5d1e725f965979042495a5313Brian Paul
8499bf68ad963ba92b5d1e725f965979042495a5313Brian Paul
8509bf68ad963ba92b5d1e725f965979042495a5313Brian Paul/*
8514003bde6fffc3e5b9e1a115ba952b988dffb099aBrian * Render an RGBA triangle with arbitrary attributes.
852e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
8534003bde6fffc3e5b9e1a115ba952b988dffb099aBrian#define NAME general_triangle
854e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define INTERP_Z 1
855e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define INTERP_RGB 1
856e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define INTERP_ALPHA 1
8578a8a5bd104e8cd9362415db77d5f6a3945939589Brian#define INTERP_ATTRIBS 1
858a803b0c891404dcd7c376e91f6a033cd4e42abc3Brian Paul#define RENDER_SPAN( span )   _swrast_write_rgba_span(ctx, &span);
859e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_tritemp.h"
860e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
861e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
862f1e236987829393c81dc86ea19cb49eefe190317Brian Paul
863e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
864b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul/*
865b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul * Special tri function for occlusion testing
866b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul */
867cdf2da368d180205df3573697b51b8764048ad6eBrian Paul#define NAME occlusion_zless_triangle
868e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define INTERP_Z 1
86923ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul#define SETUP_CODE							\
8701a5f1bdb428ea3ded1e77796590014f89fe78f77Brian Paul   struct gl_renderbuffer *rb = ctx->DrawBuffer->_DepthBuffer;		\
87123ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul   struct gl_query_object *q = ctx->Query.CurrentOcclusionObject;	\
87223ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul   ASSERT(ctx->Depth.Test);						\
87323ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul   ASSERT(!ctx->Depth.Mask);						\
87423ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul   ASSERT(ctx->Depth.Func == GL_LESS);					\
87523ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul   if (!q) {								\
87623ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul      return;								\
877cdf2da368d180205df3573697b51b8764048ad6eBrian Paul   }
8780349b4b2abac65f67a638a9f8bb5d1a3d48ddf95Brian Paul#define RENDER_SPAN( span )						\
87945e76d2665b38ba3787548310efc59e969124c01Brian Paul   if (rb->Format == MESA_FORMAT_Z16) {					\
8800349b4b2abac65f67a638a9f8bb5d1a3d48ddf95Brian Paul      GLuint i;								\
8810349b4b2abac65f67a638a9f8bb5d1a3d48ddf95Brian Paul      const GLushort *zRow = (const GLushort *)				\
882e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         rb->GetPointer(ctx, rb, span.x, span.y);			\
8830349b4b2abac65f67a638a9f8bb5d1a3d48ddf95Brian Paul      for (i = 0; i < span.end; i++) {					\
8843e37bafab0a339021354b9c78f983d05d433d735Brian Paul         GLuint z = FixedToDepth(span.z);				\
8850349b4b2abac65f67a638a9f8bb5d1a3d48ddf95Brian Paul         if (z < zRow[i]) {						\
88623ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul            q->Result++;						\
8870349b4b2abac65f67a638a9f8bb5d1a3d48ddf95Brian Paul         }								\
8880349b4b2abac65f67a638a9f8bb5d1a3d48ddf95Brian Paul         span.z += span.zStep;						\
8890349b4b2abac65f67a638a9f8bb5d1a3d48ddf95Brian Paul      }									\
8900349b4b2abac65f67a638a9f8bb5d1a3d48ddf95Brian Paul   }									\
8910349b4b2abac65f67a638a9f8bb5d1a3d48ddf95Brian Paul   else {								\
8920349b4b2abac65f67a638a9f8bb5d1a3d48ddf95Brian Paul      GLuint i;								\
8930349b4b2abac65f67a638a9f8bb5d1a3d48ddf95Brian Paul      const GLuint *zRow = (const GLuint *)				\
894e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         rb->GetPointer(ctx, rb, span.x, span.y);			\
8950349b4b2abac65f67a638a9f8bb5d1a3d48ddf95Brian Paul      for (i = 0; i < span.end; i++) {					\
896a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul         if ((GLuint)span.z < zRow[i]) {				\
89723ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul            q->Result++;						\
8980349b4b2abac65f67a638a9f8bb5d1a3d48ddf95Brian Paul         }								\
8990349b4b2abac65f67a638a9f8bb5d1a3d48ddf95Brian Paul         span.z += span.zStep;						\
9000349b4b2abac65f67a638a9f8bb5d1a3d48ddf95Brian Paul      }									\
901e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
902e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_tritemp.h"
903e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
904cdf2da368d180205df3573697b51b8764048ad6eBrian Paul
905cdf2da368d180205df3573697b51b8764048ad6eBrian Paul
906cdf2da368d180205df3573697b51b8764048ad6eBrian Paulstatic void
907f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnodraw_triangle( struct gl_context *ctx,
908cdf2da368d180205df3573697b51b8764048ad6eBrian Paul                 const SWvertex *v0,
909cdf2da368d180205df3573697b51b8764048ad6eBrian Paul                 const SWvertex *v1,
910cdf2da368d180205df3573697b51b8764048ad6eBrian Paul                 const SWvertex *v2 )
91147489c0721348d8f5e5f17b4af63b1c601045116Keith Whitwell{
91247489c0721348d8f5e5f17b4af63b1c601045116Keith Whitwell   (void) (ctx && v0 && v1 && v2);
91347489c0721348d8f5e5f17b4af63b1c601045116Keith Whitwell}
914e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
915f47efb5ab32534fc5c42b5bc88a6b24cb514ce53Brian Paul
916f47efb5ab32534fc5c42b5bc88a6b24cb514ce53Brian Paul/*
917f47efb5ab32534fc5c42b5bc88a6b24cb514ce53Brian Paul * This is used when separate specular color is enabled, but not
918fa6b2fba7ad0504a63ab262f602c6f50f336ca1bBrian Paul * texturing.  We add the specular color to the primary color,
919f47efb5ab32534fc5c42b5bc88a6b24cb514ce53Brian Paul * draw the triangle, then restore the original primary color.
920f47efb5ab32534fc5c42b5bc88a6b24cb514ce53Brian Paul * Inefficient, but seldom needed.
921f47efb5ab32534fc5c42b5bc88a6b24cb514ce53Brian Paul */
9229e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrianvoid
923f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_swrast_add_spec_terms_triangle(struct gl_context *ctx, const SWvertex *v0,
9249e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                                const SWvertex *v1, const SWvertex *v2)
92546b0988c673b28e072fd0cbf477632a9ab6f9f18Keith Whitwell{
92646b0988c673b28e072fd0cbf477632a9ab6f9f18Keith Whitwell   SWvertex *ncv0 = (SWvertex *)v0; /* drop const qualifier */
92746b0988c673b28e072fd0cbf477632a9ab6f9f18Keith Whitwell   SWvertex *ncv1 = (SWvertex *)v1;
92846b0988c673b28e072fd0cbf477632a9ab6f9f18Keith Whitwell   SWvertex *ncv2 = (SWvertex *)v2;
929f47efb5ab32534fc5c42b5bc88a6b24cb514ce53Brian Paul   GLfloat rSum, gSum, bSum;
9309e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   GLchan cSave[3][4];
9319e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian
932f47efb5ab32534fc5c42b5bc88a6b24cb514ce53Brian Paul   /* save original colors */
9339e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   COPY_CHAN4( cSave[0], ncv0->color );
9349e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   COPY_CHAN4( cSave[1], ncv1->color );
9359e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   COPY_CHAN4( cSave[2], ncv2->color );
936f47efb5ab32534fc5c42b5bc88a6b24cb514ce53Brian Paul   /* sum v0 */
9379e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   rSum = CHAN_TO_FLOAT(ncv0->color[0]) + ncv0->attrib[FRAG_ATTRIB_COL1][0];
9389e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   gSum = CHAN_TO_FLOAT(ncv0->color[1]) + ncv0->attrib[FRAG_ATTRIB_COL1][1];
9399e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   bSum = CHAN_TO_FLOAT(ncv0->color[2]) + ncv0->attrib[FRAG_ATTRIB_COL1][2];
9409e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[0], rSum);
9419e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[1], gSum);
9429e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[2], bSum);
943f47efb5ab32534fc5c42b5bc88a6b24cb514ce53Brian Paul   /* sum v1 */
9449e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   rSum = CHAN_TO_FLOAT(ncv1->color[0]) + ncv1->attrib[FRAG_ATTRIB_COL1][0];
9459e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   gSum = CHAN_TO_FLOAT(ncv1->color[1]) + ncv1->attrib[FRAG_ATTRIB_COL1][1];
9469e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   bSum = CHAN_TO_FLOAT(ncv1->color[2]) + ncv1->attrib[FRAG_ATTRIB_COL1][2];
9479e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[0], rSum);
9489e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[1], gSum);
9499e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[2], bSum);
950f47efb5ab32534fc5c42b5bc88a6b24cb514ce53Brian Paul   /* sum v2 */
9519e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   rSum = CHAN_TO_FLOAT(ncv2->color[0]) + ncv2->attrib[FRAG_ATTRIB_COL1][0];
9529e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   gSum = CHAN_TO_FLOAT(ncv2->color[1]) + ncv2->attrib[FRAG_ATTRIB_COL1][1];
9539e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   bSum = CHAN_TO_FLOAT(ncv2->color[2]) + ncv2->attrib[FRAG_ATTRIB_COL1][2];
9549e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   UNCLAMPED_FLOAT_TO_CHAN(ncv2->color[0], rSum);
9559e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   UNCLAMPED_FLOAT_TO_CHAN(ncv2->color[1], gSum);
9569e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   UNCLAMPED_FLOAT_TO_CHAN(ncv2->color[2], bSum);
957f47efb5ab32534fc5c42b5bc88a6b24cb514ce53Brian Paul   /* draw */
95846b0988c673b28e072fd0cbf477632a9ab6f9f18Keith Whitwell   SWRAST_CONTEXT(ctx)->SpecTriangle( ctx, ncv0, ncv1, ncv2 );
959f47efb5ab32534fc5c42b5bc88a6b24cb514ce53Brian Paul   /* restore original colors */
9609e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   COPY_CHAN4( ncv0->color, cSave[0] );
9619e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   COPY_CHAN4( ncv1->color, cSave[1] );
9629e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   COPY_CHAN4( ncv2->color, cSave[2] );
96346b0988c673b28e072fd0cbf477632a9ab6f9f18Keith Whitwell}
96446b0988c673b28e072fd0cbf477632a9ab6f9f18Keith Whitwell
965e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
966e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
967e9313a64c182701d22a5c6d2a82863c658e7424fBrian Paul#ifdef DEBUG
968e9313a64c182701d22a5c6d2a82863c658e7424fBrian Paul
969e9313a64c182701d22a5c6d2a82863c658e7424fBrian Paul/* record the current triangle function name */
970fd1727bd1064ee2323c924cb4002d4d9a89780bfBrian Paulconst char *_mesa_triFuncName = NULL;
971e9313a64c182701d22a5c6d2a82863c658e7424fBrian Paul
9722a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul#define USE(triFunc)				\
9732a182a98973edc9ecf2936b1288485bb2b3fa722Brian Pauldo {						\
9742a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul    _mesa_triFuncName = #triFunc;		\
9752a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul    /*printf("%s\n", _mesa_triFuncName);*/	\
9762a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul    swrast->Triangle = triFunc;			\
977e9313a64c182701d22a5c6d2a82863c658e7424fBrian Paul} while (0)
978e9313a64c182701d22a5c6d2a82863c658e7424fBrian Paul
979e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#else
980e9313a64c182701d22a5c6d2a82863c658e7424fBrian Paul
981e9313a64c182701d22a5c6d2a82863c658e7424fBrian Paul#define USE(triFunc)  swrast->Triangle = triFunc;
982e9313a64c182701d22a5c6d2a82863c658e7424fBrian Paul
983e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
984e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
985e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
986e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
987e9313a64c182701d22a5c6d2a82863c658e7424fBrian Paul
988e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
989e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Determine which triangle rendering function to use given the current
990e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * rendering context.
991e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *
992e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Please update the summary flag _SWRAST_NEW_TRIANGLE if you add or
993e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * remove tests to this code.
994e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
99522144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughesvoid
996f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_swrast_choose_triangle( struct gl_context *ctx )
997e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
998cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell   SWcontext *swrast = SWRAST_CONTEXT(ctx);
999e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
100038f28665bf9fb5b2464738ca5074848ec2777ae1Gareth Hughes   if (ctx->Polygon.CullFlag &&
100147489c0721348d8f5e5f17b4af63b1c601045116Keith Whitwell       ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) {
1002e9313a64c182701d22a5c6d2a82863c658e7424fBrian Paul      USE(nodraw_triangle);
100347489c0721348d8f5e5f17b4af63b1c601045116Keith Whitwell      return;
100447489c0721348d8f5e5f17b4af63b1c601045116Keith Whitwell   }
100547489c0721348d8f5e5f17b4af63b1c601045116Keith Whitwell
1006e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (ctx->RenderMode==GL_RENDER) {
1007e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1008e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (ctx->Polygon.SmoothFlag) {
100945bc887da226403f2c41077e40ca38b6f60f1359Brian Paul         _swrast_set_aa_triangle_function(ctx);
1010cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell         ASSERT(swrast->Triangle);
1011e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         return;
1012e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1013e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1014b17a722ca3989e8563ee04cb2939f4835f8a171eBrian Paul      /* special case for occlusion testing */
101523ffc3a85d6172f8a98d17d7f23610bab808d84eBrian Paul      if (ctx->Query.CurrentOcclusionObject &&
1016e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell          ctx->Depth.Test &&
1017e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell          ctx->Depth.Mask == GL_FALSE &&
1018e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell          ctx->Depth.Func == GL_LESS &&
101991e61f435a71436c209934a0ece165b540aba3e0Brian Paul          !ctx->Stencil._Enabled) {
10200ed9c4bc7affb7a6b9be5ff129815fccf8c3885dIan Romanick         if (ctx->Color.ColorMask[0][0] == 0 &&
10210ed9c4bc7affb7a6b9be5ff129815fccf8c3885dIan Romanick	     ctx->Color.ColorMask[0][1] == 0 &&
10220ed9c4bc7affb7a6b9be5ff129815fccf8c3885dIan Romanick	     ctx->Color.ColorMask[0][2] == 0 &&
10230ed9c4bc7affb7a6b9be5ff129815fccf8c3885dIan Romanick	     ctx->Color.ColorMask[0][3] == 0) {
1024e9313a64c182701d22a5c6d2a82863c658e7424fBrian Paul            USE(occlusion_zless_triangle);
1025e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            return;
1026e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
1027e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1028e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
10299e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian      /*
10309e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian       * XXX should examine swrast->_ActiveAttribMask to determine what
10319e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian       * needs to be interpolated.
10329e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian       */
103312ef1fbefcee964b715783d3ade6b69b2c699ed8Brian      if (ctx->Texture._EnabledCoordUnits ||
103412ef1fbefcee964b715783d3ade6b69b2c699ed8Brian          ctx->FragmentProgram._Current ||
10359e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian          ctx->ATIFragmentShader._Enabled ||
1036decc6e2a32ef49e673c081f30e19b8970155d887Brian Paul          _mesa_need_secondary_color(ctx) ||
10379e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian          swrast->_FogEnabled) {
1038e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* Ugh, we do a _lot_ of tests to pick the best textured tri func */
1039b7339d70237ffb460f158c61860ca225fec02e81Michal Krol         const struct gl_texture_object *texObj2D;
1040e9313a64c182701d22a5c6d2a82863c658e7424fBrian Paul         const struct gl_texture_image *texImg;
104138e3675d7dc6c373366e576e3ca1a1eb966e4dacBrian Paul         GLenum minFilter, magFilter, envMode;
10421f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul         gl_format format;
10439818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul         texObj2D = ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX];
10449818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul
104518fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell         texImg = texObj2D ? texObj2D->Image[0][texObj2D->BaseLevel] : NULL;
10460103d7a47a6f42d8bb7199b5bd55097e3b0b92a4Brian Paul         format = texImg ? texImg->TexFormat : MESA_FORMAT_NONE;
1047ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul         minFilter = texObj2D ? texObj2D->Sampler.MinFilter : GL_NONE;
1048ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul         magFilter = texObj2D ? texObj2D->Sampler.MagFilter : GL_NONE;
1049e9313a64c182701d22a5c6d2a82863c658e7424fBrian Paul         envMode = ctx->Texture.Unit[0].EnvMode;
1050e9313a64c182701d22a5c6d2a82863c658e7424fBrian Paul
1051c0fc0d4e5f5c246fc2459348a3d114b232d0c545Brian Paul         /* First see if we can use an optimized 2-D texture function */
10520349b4b2abac65f67a638a9f8bb5d1a3d48ddf95Brian Paul         if (ctx->Texture._EnabledCoordUnits == 0x1
105312ef1fbefcee964b715783d3ade6b69b2c699ed8Brian             && !ctx->FragmentProgram._Current
10546acf1e93a291511cfb20b0e2aeda6e71ceb62a62Michal Krol             && !ctx->ATIFragmentShader._Enabled
105588bb4b593576a2977b2fe36794bd4d3dbc72063eBrian Paul             && ctx->Texture._EnabledUnits == 0x1
10568afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul             && ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT
1057ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul             && texObj2D->Sampler.WrapS == GL_REPEAT
1058ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul             && texObj2D->Sampler.WrapT == GL_REPEAT
105954c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul             && texObj2D->_Swizzle == SWIZZLE_NOOP
106006f606ce5761e673fca3f6b1f7dd40dace8a9906Brian Paul             && texImg->_IsPowerOfTwo
10610349b4b2abac65f67a638a9f8bb5d1a3d48ddf95Brian Paul             && texImg->Border == 0
1062681b8c9d1ba06c8c82e687a5ced369b72e6b1eb9Brian Paul             && texImg->Width == texImg->RowStride
10633fa7dbf368bb060220e9f78e666b00d6827166a6Brian Paul             && (format == MESA_FORMAT_RGB888 || format == MESA_FORMAT_RGBA8888)
1064b7339d70237ffb460f158c61860ca225fec02e81Michal Krol             && minFilter == magFilter
1065b7339d70237ffb460f158c61860ca225fec02e81Michal Krol             && ctx->Light.Model.ColorControl == GL_SINGLE_COLOR
10669e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian             && !swrast->_FogEnabled
10672d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul             && ctx->Texture.Unit[0].EnvMode != GL_COMBINE_EXT
10682d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul             && ctx->Texture.Unit[0].EnvMode != GL_COMBINE4_NV) {
1069e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell	    if (ctx->Hint.PerspectiveCorrection==GL_FASTEST) {
1070e9313a64c182701d22a5c6d2a82863c658e7424fBrian Paul	       if (minFilter == GL_NEAREST
10713fa7dbf368bb060220e9f78e666b00d6827166a6Brian Paul		   && format == MESA_FORMAT_RGB888
1072e9313a64c182701d22a5c6d2a82863c658e7424fBrian Paul		   && (envMode == GL_REPLACE || envMode == GL_DECAL)
10739bf68ad963ba92b5d1e725f965979042495a5313Brian Paul		   && ((swrast->_RasterMask == (DEPTH_BIT | TEXTURE_BIT)
1074e9313a64c182701d22a5c6d2a82863c658e7424fBrian Paul			&& ctx->Depth.Func == GL_LESS
1075e9313a64c182701d22a5c6d2a82863c658e7424fBrian Paul			&& ctx->Depth.Mask == GL_TRUE)
10769bf68ad963ba92b5d1e725f965979042495a5313Brian Paul		       || swrast->_RasterMask == TEXTURE_BIT)
1077e6e0ba781b0a6a1b8747cae49ca622a6a61b1bf8Brian Paul		   && ctx->Polygon.StippleFlag == GL_FALSE
10789c4fd26bcab7e4a5bd97a56deff89b8ea0ae5f1dBrian Paul                   && ctx->DrawBuffer->Visual.depthBits <= 16) {
10799bf68ad963ba92b5d1e725f965979042495a5313Brian Paul		  if (swrast->_RasterMask == (DEPTH_BIT | TEXTURE_BIT)) {
1080e9313a64c182701d22a5c6d2a82863c658e7424fBrian Paul		     USE(simple_z_textured_triangle);
1081e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell		  }
1082e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell		  else {
1083e9313a64c182701d22a5c6d2a82863c658e7424fBrian Paul		     USE(simple_textured_triangle);
1084e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell		  }
1085e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell	       }
1086e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell	       else {
10879e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#if CHAN_BITS != 8
10884003bde6fffc3e5b9e1a115ba952b988dffb099aBrian                  USE(general_triangle);
108996385fa15569e25cd0977e678c0ff3bdab6ef316Brian Paul#else
109059b29516af2d4d8f83723559921a3709eb77a7d2Chia-I Wu                  if (format == MESA_FORMAT_RGBA8888 && !_mesa_little_endian()) {
1091086f9fc0e2aef27f54eda87c733685500555bf20Brian Paul                     /* We only handle RGBA8888 correctly on little endian
1092086f9fc0e2aef27f54eda87c733685500555bf20Brian Paul                      * in the optimized code above.
1093086f9fc0e2aef27f54eda87c733685500555bf20Brian Paul                      */
1094086f9fc0e2aef27f54eda87c733685500555bf20Brian Paul                     USE(general_triangle);
109559b29516af2d4d8f83723559921a3709eb77a7d2Chia-I Wu                  }
109659b29516af2d4d8f83723559921a3709eb77a7d2Chia-I Wu                  else {
1097086f9fc0e2aef27f54eda87c733685500555bf20Brian Paul                     USE(affine_textured_triangle);
109859b29516af2d4d8f83723559921a3709eb77a7d2Chia-I Wu                 }
1099f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul#endif
1100e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell	       }
1101e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell	    }
1102e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell	    else {
11039e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#if CHAN_BITS != 8
11044003bde6fffc3e5b9e1a115ba952b988dffb099aBrian               USE(general_triangle);
110596385fa15569e25cd0977e678c0ff3bdab6ef316Brian Paul#else
110696385fa15569e25cd0977e678c0ff3bdab6ef316Brian Paul               USE(persp_textured_triangle);
110796385fa15569e25cd0977e678c0ff3bdab6ef316Brian Paul#endif
1108e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell	    }
1109e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell	 }
1110e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         else {
111131f12f504e61cb2ad65b8890a68eb7154edcb64bBrian Paul            /* general case textured triangles */
11124003bde6fffc3e5b9e1a115ba952b988dffb099aBrian            USE(general_triangle);
1113e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
1114e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1115e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else {
11169e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         ASSERT(!swrast->_FogEnabled);
1117decc6e2a32ef49e673c081f30e19b8970155d887Brian Paul         ASSERT(!_mesa_need_secondary_color(ctx));
1118e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell	 if (ctx->Light.ShadeModel==GL_SMOOTH) {
1119e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell	    /* smooth shaded, no texturing, stippled or some raster ops */
11209e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#if CHAN_BITS != 8
11219e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               USE(general_triangle);
11229e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#else
11239e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               USE(smooth_rgba_triangle);
11249e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#endif
1125e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell	 }
1126e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell	 else {
1127e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell	    /* flat shaded, no texturing, stippled or some raster ops */
11289e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#if CHAN_BITS != 8
11299e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian            USE(general_triangle);
11309e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#else
113197693436a5740fb56c29fcd1cb0a1aa562349902Brian            USE(flat_rgba_triangle);
11329e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#endif
1133e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell	 }
1134e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
1135e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
1136e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else if (ctx->RenderMode==GL_FEEDBACK) {
113745bc887da226403f2c41077e40ca38b6f60f1359Brian Paul      USE(_swrast_feedback_triangle);
1138e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
1139e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
1140e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* GL_SELECT mode */
114145bc887da226403f2c41077e40ca38b6f60f1359Brian Paul      USE(_swrast_select_triangle);
1142e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
1143e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
1144