Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Mesa 3-D graphics library |
Gareth Hughes | 22144ab | 2001-03-12 00:48:37 +0000 | [diff] [blame] | 3 | * |
Brian | dd34fe8 | 2007-02-05 10:10:01 -0700 | [diff] [blame] | 4 | * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. |
Gareth Hughes | 22144ab | 2001-03-12 00:48:37 +0000 | [diff] [blame] | 5 | * |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 6 | * Permission is hereby granted, free of charge, to any person obtaining a |
| 7 | * copy of this software and associated documentation files (the "Software"), |
| 8 | * to deal in the Software without restriction, including without limitation |
| 9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| 10 | * and/or sell copies of the Software, and to permit persons to whom the |
| 11 | * Software is furnished to do so, subject to the following conditions: |
Gareth Hughes | 22144ab | 2001-03-12 00:48:37 +0000 | [diff] [blame] | 12 | * |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 13 | * The above copyright notice and this permission notice shall be included |
| 14 | * in all copies or substantial portions of the Software. |
Gareth Hughes | 22144ab | 2001-03-12 00:48:37 +0000 | [diff] [blame] | 15 | * |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| 17 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
Kenneth Graunke | 3d8d5b2 | 2013-04-21 13:46:48 -0700 | [diff] [blame] | 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
| 20 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
| 21 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
| 22 | * OTHER DEALINGS IN THE SOFTWARE. |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 23 | */ |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 24 | |
| 25 | /* |
| 26 | * Triangle Rasterizer Template |
| 27 | * |
| 28 | * This file is #include'd to generate custom triangle rasterizers. |
| 29 | * |
| 30 | * The following macros may be defined to indicate what auxillary information |
Michal Krol | bb38cad | 2006-04-11 11:41:11 +0000 | [diff] [blame] | 31 | * must be interpolated across the triangle: |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 32 | * INTERP_Z - if defined, interpolate integer Z values |
| 33 | * INTERP_RGB - if defined, interpolate integer RGB values |
| 34 | * INTERP_ALPHA - if defined, interpolate integer Alpha values |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 35 | * INTERP_INT_TEX - if defined, interpolate integer ST texcoords |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 36 | * (fast, simple 2-D texture mapping, without |
| 37 | * perspective correction) |
Brian | 8a8a5bd | 2007-04-24 16:16:25 -0600 | [diff] [blame] | 38 | * INTERP_ATTRIBS - if defined, interpolate arbitrary attribs (texcoords, |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 39 | * varying vars, etc) This also causes W to be |
| 40 | * computed for perspective correction). |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 41 | * |
| 42 | * When one can directly address pixels in the color buffer the following |
| 43 | * macros can be defined and used to compute pixel addresses during |
| 44 | * rasterization (see pRow): |
| 45 | * PIXEL_TYPE - the datatype of a pixel (GLubyte, GLushort, GLuint) |
| 46 | * BYTES_PER_ROW - number of bytes per row in the color buffer |
| 47 | * PIXEL_ADDRESS(X,Y) - returns the address of pixel at (X,Y) where |
| 48 | * Y==0 at bottom of screen and increases upward. |
| 49 | * |
| 50 | * Similarly, for direct depth buffer access, this type is used for depth |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 51 | * buffer addressing (see zRow): |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 52 | * DEPTH_TYPE - either GLushort or GLuint |
| 53 | * |
| 54 | * Optionally, one may provide one-time setup code per triangle: |
| 55 | * SETUP_CODE - code which is to be executed once per triangle |
Gareth Hughes | 22144ab | 2001-03-12 00:48:37 +0000 | [diff] [blame] | 56 | * |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 57 | * The following macro MUST be defined: |
Brian Paul | 9bf68ad | 2001-05-14 16:23:04 +0000 | [diff] [blame] | 58 | * RENDER_SPAN(span) - code to write a span of pixels. |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 59 | * |
| 60 | * This code was designed for the origin to be in the lower-left corner. |
| 61 | * |
| 62 | * Inspired by triangle rasterizer code written by Allen Akin. Thanks Allen! |
Brian Paul | 7c4a61c | 2004-02-15 16:21:07 +0000 | [diff] [blame] | 63 | * |
| 64 | * |
| 65 | * Some notes on rasterization accuracy: |
| 66 | * |
| 67 | * This code uses fixed point arithmetic (the GLfixed type) to iterate |
| 68 | * over the triangle edges and interpolate ancillary data (such as Z, |
| 69 | * color, secondary color, etc). The number of fractional bits in |
| 70 | * GLfixed and the value of SUB_PIXEL_BITS has a direct bearing on the |
| 71 | * accuracy of rasterization. |
| 72 | * |
| 73 | * If SUB_PIXEL_BITS=4 then we'll snap the vertices to the nearest |
| 74 | * 1/16 of a pixel. If we're walking up a long, nearly vertical edge |
| 75 | * (dx=1/16, dy=1024) we'll need 4 + 10 = 14 fractional bits in |
| 76 | * GLfixed to walk the edge without error. If the maximum viewport |
| 77 | * height is 4K pixels, then we'll need 4 + 12 = 16 fractional bits. |
| 78 | * |
| 79 | * Historically, Mesa has used 11 fractional bits in GLfixed, snaps |
| 80 | * vertices to 1/16 pixel and allowed a maximum viewport height of 2K |
| 81 | * pixels. 11 fractional bits is actually insufficient for accurately |
| 82 | * rasterizing some triangles. More recently, the maximum viewport |
| 83 | * height was increased to 4K pixels. Thus, Mesa should be using 16 |
| 84 | * fractional bits in GLfixed. Unfortunately, there may be some issues |
| 85 | * with setting FIXED_FRAC_BITS=16, such as multiplication overflow. |
| 86 | * This will have to be examined in some detail... |
| 87 | * |
| 88 | * For now, if you find rasterization errors, particularly with tall, |
| 89 | * sliver triangles, try increasing FIXED_FRAC_BITS and/or decreasing |
| 90 | * SUB_PIXEL_BITS. |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 91 | */ |
| 92 | |
Brian Paul | 84b4a3a | 2004-02-17 03:51:47 +0000 | [diff] [blame] | 93 | |
Brian Paul | ab68219 | 2015-02-24 15:23:22 -0700 | [diff] [blame] | 94 | #ifndef MAX_GLUINT |
Matt Turner | 89b140d | 2015-04-11 10:14:00 -0700 | [diff] [blame] | 95 | #define MAX_GLUINT 0xffffffffu |
Brian Paul | ab68219 | 2015-02-24 15:23:22 -0700 | [diff] [blame] | 96 | #endif |
| 97 | |
| 98 | |
Brian Paul | daeb005 | 2005-11-15 15:08:03 +0000 | [diff] [blame] | 99 | /* |
| 100 | * Some code we unfortunately need to prevent negative interpolated colors. |
| 101 | */ |
| 102 | #ifndef CLAMP_INTERPOLANT |
| 103 | #define CLAMP_INTERPOLANT(CHANNEL, CHANNELSTEP, LEN) \ |
| 104 | do { \ |
| 105 | GLfixed endVal = span.CHANNEL + (LEN) * span.CHANNELSTEP; \ |
| 106 | if (endVal < 0) { \ |
| 107 | span.CHANNEL -= endVal; \ |
| 108 | } \ |
| 109 | if (span.CHANNEL < 0) { \ |
| 110 | span.CHANNEL = 0; \ |
| 111 | } \ |
| 112 | } while (0) |
| 113 | #endif |
| 114 | |
| 115 | |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 116 | static void NAME(struct gl_context *ctx, const SWvertex *v0, |
Brian Paul | cdf2da3 | 2002-11-13 16:51:01 +0000 | [diff] [blame] | 117 | const SWvertex *v1, |
| 118 | const SWvertex *v2 ) |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 119 | { |
| 120 | typedef struct { |
Brian Paul | 84b4a3a | 2004-02-17 03:51:47 +0000 | [diff] [blame] | 121 | const SWvertex *v0, *v1; /* Y(v0) < Y(v1) */ |
Brian Paul | 84b4a3a | 2004-02-17 03:51:47 +0000 | [diff] [blame] | 122 | GLfloat dx; /* X(v1) - X(v0) */ |
| 123 | GLfloat dy; /* Y(v1) - Y(v0) */ |
| 124 | GLfloat dxdy; /* dx/dy */ |
| 125 | GLfixed fdxdy; /* dx/dy in fixed-point */ |
| 126 | GLfloat adjy; /* adjust from v[0]->fy to fsy, scaled */ |
Brian Paul | 84b4a3a | 2004-02-17 03:51:47 +0000 | [diff] [blame] | 127 | GLfixed fsx; /* first sample point x coord */ |
| 128 | GLfixed fsy; |
Brian Paul | 84b4a3a | 2004-02-17 03:51:47 +0000 | [diff] [blame] | 129 | GLfixed fx0; /* fixed pt X of lower endpoint */ |
Brian Paul | 7d05e48 | 2004-03-14 18:12:06 +0000 | [diff] [blame] | 130 | GLint lines; /* number of lines to be sampled on this edge */ |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 131 | } EdgeT; |
| 132 | |
Brian | dd34fe8 | 2007-02-05 10:10:01 -0700 | [diff] [blame] | 133 | const SWcontext *swrast = SWRAST_CONTEXT(ctx); |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 134 | #ifdef INTERP_Z |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 135 | const GLint depthBits = ctx->DrawBuffer->Visual.depthBits; |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 136 | const GLint fixedToDepthShift = depthBits <= 16 ? FIXED_SHIFT : 0; |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 137 | const GLfloat maxDepth = ctx->DrawBuffer->_DepthMaxF; |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 138 | #define FixedToDepth(F) ((F) >> fixedToDepthShift) |
| 139 | #endif |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 140 | EdgeT eMaj, eTop, eBot; |
| 141 | GLfloat oneOverArea; |
Brian Paul | a852378 | 2000-11-19 23:10:25 +0000 | [diff] [blame] | 142 | const SWvertex *vMin, *vMid, *vMax; /* Y(vMin)<=Y(vMid)<=Y(vMax) */ |
Brian | 02afd45 | 2007-12-04 14:06:10 -0700 | [diff] [blame] | 143 | GLfloat bf = SWRAST_CONTEXT(ctx)->_BackfaceSign; |
Brian Paul | 10d343f | 2002-10-17 15:26:38 +0000 | [diff] [blame] | 144 | const GLint snapMask = ~((FIXED_ONE / (1 << SUB_PIXEL_BITS)) - 1); /* for x/y coord snapping */ |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 145 | GLfixed vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy; |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 146 | |
Brian Paul | cdb27e8 | 2006-10-01 16:03:05 +0000 | [diff] [blame] | 147 | SWspan span; |
Brian Paul | 9bf68ad | 2001-05-14 16:23:04 +0000 | [diff] [blame] | 148 | |
Brian | dd34fe8 | 2007-02-05 10:10:01 -0700 | [diff] [blame] | 149 | (void) swrast; |
| 150 | |
Brian | f4b103d | 2007-06-29 21:52:18 -0600 | [diff] [blame] | 151 | INIT_SPAN(span, GL_POLYGON); |
Brian | f9c01c3 | 2007-04-04 09:30:28 -0600 | [diff] [blame] | 152 | span.y = 0; /* silence warnings */ |
Brian Paul | 2a182a9 | 2002-01-27 18:32:03 +0000 | [diff] [blame] | 153 | |
Brian Paul | 9bf68ad | 2001-05-14 16:23:04 +0000 | [diff] [blame] | 154 | #ifdef INTERP_Z |
| 155 | (void) fixedToDepthShift; |
| 156 | #endif |
| 157 | |
Brian Paul | 3ade8af | 2001-12-17 04:58:50 +0000 | [diff] [blame] | 158 | /* |
Marius Predut | d02942c | 2015-04-07 22:03:52 +0300 | [diff] [blame] | 159 | printf("%s()\n", __func__); |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 160 | printf(" %g, %g, %g\n", |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 161 | v0->attrib[VARYING_SLOT_POS][0], |
| 162 | v0->attrib[VARYING_SLOT_POS][1], |
| 163 | v0->attrib[VARYING_SLOT_POS][2]); |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 164 | printf(" %g, %g, %g\n", |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 165 | v1->attrib[VARYING_SLOT_POS][0], |
| 166 | v1->attrib[VARYING_SLOT_POS][1], |
| 167 | v1->attrib[VARYING_SLOT_POS][2]); |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 168 | printf(" %g, %g, %g\n", |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 169 | v2->attrib[VARYING_SLOT_POS][0], |
| 170 | v2->attrib[VARYING_SLOT_POS][1], |
| 171 | v2->attrib[VARYING_SLOT_POS][2]); |
Brian Paul | 3ade8af | 2001-12-17 04:58:50 +0000 | [diff] [blame] | 172 | */ |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 173 | |
Brian Paul | a2162e4 | 2001-06-12 14:18:58 +0000 | [diff] [blame] | 174 | /* Compute fixed point x,y coords w/ half-pixel offsets and snapping. |
| 175 | * And find the order of the 3 vertices along the Y axis. |
| 176 | */ |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 177 | { |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 178 | const GLfixed fy0 = FloatToFixed(v0->attrib[VARYING_SLOT_POS][1] - 0.5F) & snapMask; |
| 179 | const GLfixed fy1 = FloatToFixed(v1->attrib[VARYING_SLOT_POS][1] - 0.5F) & snapMask; |
| 180 | const GLfixed fy2 = FloatToFixed(v2->attrib[VARYING_SLOT_POS][1] - 0.5F) & snapMask; |
Brian Paul | a2162e4 | 2001-06-12 14:18:58 +0000 | [diff] [blame] | 181 | if (fy0 <= fy1) { |
Brian Paul | d22554d | 2001-09-13 21:54:29 +0000 | [diff] [blame] | 182 | if (fy1 <= fy2) { |
Brian Paul | a2162e4 | 2001-06-12 14:18:58 +0000 | [diff] [blame] | 183 | /* y0 <= y1 <= y2 */ |
Brian Paul | d22554d | 2001-09-13 21:54:29 +0000 | [diff] [blame] | 184 | vMin = v0; vMid = v1; vMax = v2; |
Brian Paul | a2162e4 | 2001-06-12 14:18:58 +0000 | [diff] [blame] | 185 | vMin_fy = fy0; vMid_fy = fy1; vMax_fy = fy2; |
Brian Paul | d22554d | 2001-09-13 21:54:29 +0000 | [diff] [blame] | 186 | } |
| 187 | else if (fy2 <= fy0) { |
Brian Paul | a2162e4 | 2001-06-12 14:18:58 +0000 | [diff] [blame] | 188 | /* y2 <= y0 <= y1 */ |
Brian Paul | d22554d | 2001-09-13 21:54:29 +0000 | [diff] [blame] | 189 | vMin = v2; vMid = v0; vMax = v1; |
Brian Paul | a2162e4 | 2001-06-12 14:18:58 +0000 | [diff] [blame] | 190 | vMin_fy = fy2; vMid_fy = fy0; vMax_fy = fy1; |
Brian Paul | d22554d | 2001-09-13 21:54:29 +0000 | [diff] [blame] | 191 | } |
| 192 | else { |
Brian Paul | a2162e4 | 2001-06-12 14:18:58 +0000 | [diff] [blame] | 193 | /* y0 <= y2 <= y1 */ |
Brian Paul | d22554d | 2001-09-13 21:54:29 +0000 | [diff] [blame] | 194 | vMin = v0; vMid = v2; vMax = v1; |
Brian Paul | a2162e4 | 2001-06-12 14:18:58 +0000 | [diff] [blame] | 195 | vMin_fy = fy0; vMid_fy = fy2; vMax_fy = fy1; |
| 196 | bf = -bf; |
Brian Paul | d22554d | 2001-09-13 21:54:29 +0000 | [diff] [blame] | 197 | } |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 198 | } |
| 199 | else { |
Brian Paul | d22554d | 2001-09-13 21:54:29 +0000 | [diff] [blame] | 200 | if (fy0 <= fy2) { |
Brian Paul | a2162e4 | 2001-06-12 14:18:58 +0000 | [diff] [blame] | 201 | /* y1 <= y0 <= y2 */ |
Brian Paul | d22554d | 2001-09-13 21:54:29 +0000 | [diff] [blame] | 202 | vMin = v1; vMid = v0; vMax = v2; |
Brian Paul | a2162e4 | 2001-06-12 14:18:58 +0000 | [diff] [blame] | 203 | vMin_fy = fy1; vMid_fy = fy0; vMax_fy = fy2; |
| 204 | bf = -bf; |
Brian Paul | d22554d | 2001-09-13 21:54:29 +0000 | [diff] [blame] | 205 | } |
| 206 | else if (fy2 <= fy1) { |
Brian Paul | a2162e4 | 2001-06-12 14:18:58 +0000 | [diff] [blame] | 207 | /* y2 <= y1 <= y0 */ |
Brian Paul | d22554d | 2001-09-13 21:54:29 +0000 | [diff] [blame] | 208 | vMin = v2; vMid = v1; vMax = v0; |
Brian Paul | a2162e4 | 2001-06-12 14:18:58 +0000 | [diff] [blame] | 209 | vMin_fy = fy2; vMid_fy = fy1; vMax_fy = fy0; |
| 210 | bf = -bf; |
Brian Paul | d22554d | 2001-09-13 21:54:29 +0000 | [diff] [blame] | 211 | } |
| 212 | else { |
Brian Paul | a2162e4 | 2001-06-12 14:18:58 +0000 | [diff] [blame] | 213 | /* y1 <= y2 <= y0 */ |
Brian Paul | d22554d | 2001-09-13 21:54:29 +0000 | [diff] [blame] | 214 | vMin = v1; vMid = v2; vMax = v0; |
Brian Paul | a2162e4 | 2001-06-12 14:18:58 +0000 | [diff] [blame] | 215 | vMin_fy = fy1; vMid_fy = fy2; vMax_fy = fy0; |
Brian Paul | d22554d | 2001-09-13 21:54:29 +0000 | [diff] [blame] | 216 | } |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 217 | } |
Brian Paul | a2162e4 | 2001-06-12 14:18:58 +0000 | [diff] [blame] | 218 | |
| 219 | /* fixed point X coords */ |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 220 | vMin_fx = FloatToFixed(vMin->attrib[VARYING_SLOT_POS][0] + 0.5F) & snapMask; |
| 221 | vMid_fx = FloatToFixed(vMid->attrib[VARYING_SLOT_POS][0] + 0.5F) & snapMask; |
| 222 | vMax_fx = FloatToFixed(vMax->attrib[VARYING_SLOT_POS][0] + 0.5F) & snapMask; |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 223 | } |
| 224 | |
| 225 | /* vertex/edge relationship */ |
| 226 | eMaj.v0 = vMin; eMaj.v1 = vMax; /*TODO: .v1's not needed */ |
| 227 | eTop.v0 = vMid; eTop.v1 = vMax; |
| 228 | eBot.v0 = vMin; eBot.v1 = vMid; |
| 229 | |
Brian Paul | a2162e4 | 2001-06-12 14:18:58 +0000 | [diff] [blame] | 230 | /* compute deltas for each edge: vertex[upper] - vertex[lower] */ |
| 231 | eMaj.dx = FixedToFloat(vMax_fx - vMin_fx); |
| 232 | eMaj.dy = FixedToFloat(vMax_fy - vMin_fy); |
| 233 | eTop.dx = FixedToFloat(vMax_fx - vMid_fx); |
| 234 | eTop.dy = FixedToFloat(vMax_fy - vMid_fy); |
| 235 | eBot.dx = FixedToFloat(vMid_fx - vMin_fx); |
| 236 | eBot.dy = FixedToFloat(vMid_fy - vMin_fy); |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 237 | |
Brian Paul | a2162e4 | 2001-06-12 14:18:58 +0000 | [diff] [blame] | 238 | /* compute area, oneOverArea and perform backface culling */ |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 239 | { |
| 240 | const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy; |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 241 | |
Brian Paul | 10d343f | 2002-10-17 15:26:38 +0000 | [diff] [blame] | 242 | if (IS_INF_OR_NAN(area) || area == 0.0F) |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 243 | return; |
| 244 | |
Matt Turner | 04aa8b5 | 2015-07-12 23:15:10 -0700 | [diff] [blame] | 245 | if (area * bf * swrast->_BackfaceCullSign < 0.0F) |
Brian | 02afd45 | 2007-12-04 14:06:10 -0700 | [diff] [blame] | 246 | return; |
| 247 | |
Brian Paul | ac3958e | 2001-07-14 16:05:44 +0000 | [diff] [blame] | 248 | oneOverArea = 1.0F / area; |
Brian | fcd7c37 | 2007-11-30 13:01:57 -0700 | [diff] [blame] | 249 | |
| 250 | /* 0 = front, 1 = back */ |
Brian | 02afd45 | 2007-12-04 14:06:10 -0700 | [diff] [blame] | 251 | span.facing = oneOverArea * bf > 0.0F; |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 252 | } |
| 253 | |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 254 | /* Edge setup. For a triangle strip these could be reused... */ |
| 255 | { |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 256 | eMaj.fsy = FixedCeil(vMin_fy); |
Brian Paul | 26d7295 | 2000-11-21 23:17:36 +0000 | [diff] [blame] | 257 | eMaj.lines = FixedToInt(FixedCeil(vMax_fy - eMaj.fsy)); |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 258 | if (eMaj.lines > 0) { |
Brian Paul | 84b4a3a | 2004-02-17 03:51:47 +0000 | [diff] [blame] | 259 | eMaj.dxdy = eMaj.dx / eMaj.dy; |
Brian Paul | 84b4a3a | 2004-02-17 03:51:47 +0000 | [diff] [blame] | 260 | eMaj.fdxdy = SignedFloatToFixed(eMaj.dxdy); |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 261 | eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy); /* SCALED! */ |
| 262 | eMaj.fx0 = vMin_fx; |
Brian Paul | 84b4a3a | 2004-02-17 03:51:47 +0000 | [diff] [blame] | 263 | eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * eMaj.dxdy); |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 264 | } |
| 265 | else { |
| 266 | return; /*CULLED*/ |
| 267 | } |
| 268 | |
| 269 | eTop.fsy = FixedCeil(vMid_fy); |
Brian Paul | 26d7295 | 2000-11-21 23:17:36 +0000 | [diff] [blame] | 270 | eTop.lines = FixedToInt(FixedCeil(vMax_fy - eTop.fsy)); |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 271 | if (eTop.lines > 0) { |
Brian Paul | 84b4a3a | 2004-02-17 03:51:47 +0000 | [diff] [blame] | 272 | eTop.dxdy = eTop.dx / eTop.dy; |
Brian Paul | 84b4a3a | 2004-02-17 03:51:47 +0000 | [diff] [blame] | 273 | eTop.fdxdy = SignedFloatToFixed(eTop.dxdy); |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 274 | eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */ |
| 275 | eTop.fx0 = vMid_fx; |
Brian Paul | 84b4a3a | 2004-02-17 03:51:47 +0000 | [diff] [blame] | 276 | eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * eTop.dxdy); |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 277 | } |
| 278 | |
| 279 | eBot.fsy = FixedCeil(vMin_fy); |
Brian Paul | 26d7295 | 2000-11-21 23:17:36 +0000 | [diff] [blame] | 280 | eBot.lines = FixedToInt(FixedCeil(vMid_fy - eBot.fsy)); |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 281 | if (eBot.lines > 0) { |
Brian Paul | 84b4a3a | 2004-02-17 03:51:47 +0000 | [diff] [blame] | 282 | eBot.dxdy = eBot.dx / eBot.dy; |
Brian Paul | 84b4a3a | 2004-02-17 03:51:47 +0000 | [diff] [blame] | 283 | eBot.fdxdy = SignedFloatToFixed(eBot.dxdy); |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 284 | eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy); /* SCALED! */ |
| 285 | eBot.fx0 = vMin_fx; |
Brian Paul | 84b4a3a | 2004-02-17 03:51:47 +0000 | [diff] [blame] | 286 | eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * eBot.dxdy); |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 287 | } |
| 288 | } |
| 289 | |
| 290 | /* |
| 291 | * Conceptually, we view a triangle as two subtriangles |
| 292 | * separated by a perfectly horizontal line. The edge that is |
| 293 | * intersected by this line is one with maximal absolute dy; we |
| 294 | * call it a ``major'' edge. The other two edges are the |
| 295 | * ``top'' edge (for the upper subtriangle) and the ``bottom'' |
| 296 | * edge (for the lower subtriangle). If either of these two |
| 297 | * edges is horizontal or very close to horizontal, the |
| 298 | * corresponding subtriangle might cover zero sample points; |
| 299 | * we take care to handle such cases, for performance as well |
| 300 | * as correctness. |
| 301 | * |
| 302 | * By stepping rasterization parameters along the major edge, |
| 303 | * we can avoid recomputing them at the discontinuity where |
| 304 | * the top and bottom edges meet. However, this forces us to |
Gareth Hughes | 22144ab | 2001-03-12 00:48:37 +0000 | [diff] [blame] | 305 | * be able to scan both left-to-right and right-to-left. |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 306 | * Also, we must determine whether the major edge is at the |
| 307 | * left or right side of the triangle. We do this by |
| 308 | * computing the magnitude of the cross-product of the major |
| 309 | * and top edges. Since this magnitude depends on the sine of |
| 310 | * the angle between the two edges, its sign tells us whether |
| 311 | * we turn to the left or to the right when travelling along |
| 312 | * the major edge to the top edge, and from this we infer |
| 313 | * whether the major edge is on the left or the right. |
| 314 | * |
| 315 | * Serendipitously, this cross-product magnitude is also a |
| 316 | * value we need to compute the iteration parameter |
| 317 | * derivatives for the triangle, and it can be used to perform |
| 318 | * backface culling because its sign tells us whether the |
| 319 | * triangle is clockwise or counterclockwise. In this code we |
| 320 | * refer to it as ``area'' because it's also proportional to |
| 321 | * the pixel area of the triangle. |
| 322 | */ |
| 323 | |
| 324 | { |
Brian Paul | d4cff4f | 2001-07-26 15:57:49 +0000 | [diff] [blame] | 325 | GLint scan_from_left_to_right; /* true if scanning left-to-right */ |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 326 | |
| 327 | /* |
| 328 | * Execute user-supplied setup code |
| 329 | */ |
| 330 | #ifdef SETUP_CODE |
| 331 | SETUP_CODE |
| 332 | #endif |
| 333 | |
Brian Paul | d4cff4f | 2001-07-26 15:57:49 +0000 | [diff] [blame] | 334 | scan_from_left_to_right = (oneOverArea < 0.0F); |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 335 | |
Brian Paul | 9bf68ad | 2001-05-14 16:23:04 +0000 | [diff] [blame] | 336 | |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 337 | /* compute d?/dx and d?/dy derivatives */ |
| 338 | #ifdef INTERP_Z |
Brian Paul | a4ac844 | 2002-08-07 15:18:42 +0000 | [diff] [blame] | 339 | span.interpMask |= SPAN_Z; |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 340 | { |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 341 | GLfloat eMaj_dz = vMax->attrib[VARYING_SLOT_POS][2] - vMin->attrib[VARYING_SLOT_POS][2]; |
| 342 | GLfloat eBot_dz = vMid->attrib[VARYING_SLOT_POS][2] - vMin->attrib[VARYING_SLOT_POS][2]; |
| 343 | span.attrStepX[VARYING_SLOT_POS][2] = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz); |
| 344 | if (span.attrStepX[VARYING_SLOT_POS][2] > maxDepth || |
| 345 | span.attrStepX[VARYING_SLOT_POS][2] < -maxDepth) { |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 346 | /* probably a sliver triangle */ |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 347 | span.attrStepX[VARYING_SLOT_POS][2] = 0.0; |
| 348 | span.attrStepY[VARYING_SLOT_POS][2] = 0.0; |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 349 | } |
| 350 | else { |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 351 | span.attrStepY[VARYING_SLOT_POS][2] = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx); |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 352 | } |
| 353 | if (depthBits <= 16) |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 354 | span.zStep = SignedFloatToFixed(span.attrStepX[VARYING_SLOT_POS][2]); |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 355 | else |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 356 | span.zStep = (GLint) span.attrStepX[VARYING_SLOT_POS][2]; |
Brian Paul | 54e92e8 | 2003-03-16 22:02:36 +0000 | [diff] [blame] | 357 | } |
| 358 | #endif |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 359 | #ifdef INTERP_RGB |
Brian Paul | a4ac844 | 2002-08-07 15:18:42 +0000 | [diff] [blame] | 360 | span.interpMask |= SPAN_RGBA; |
Brian Paul | d4cff4f | 2001-07-26 15:57:49 +0000 | [diff] [blame] | 361 | if (ctx->Light.ShadeModel == GL_SMOOTH) { |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 362 | GLfloat eMaj_dr = (GLfloat) (vMax->color[RCOMP] - vMin->color[RCOMP]); |
| 363 | GLfloat eBot_dr = (GLfloat) (vMid->color[RCOMP] - vMin->color[RCOMP]); |
| 364 | GLfloat eMaj_dg = (GLfloat) (vMax->color[GCOMP] - vMin->color[GCOMP]); |
| 365 | GLfloat eBot_dg = (GLfloat) (vMid->color[GCOMP] - vMin->color[GCOMP]); |
| 366 | GLfloat eMaj_db = (GLfloat) (vMax->color[BCOMP] - vMin->color[BCOMP]); |
| 367 | GLfloat eBot_db = (GLfloat) (vMid->color[BCOMP] - vMin->color[BCOMP]); |
Brian Paul | d4cff4f | 2001-07-26 15:57:49 +0000 | [diff] [blame] | 368 | # ifdef INTERP_ALPHA |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 369 | GLfloat eMaj_da = (GLfloat) (vMax->color[ACOMP] - vMin->color[ACOMP]); |
| 370 | GLfloat eBot_da = (GLfloat) (vMid->color[ACOMP] - vMin->color[ACOMP]); |
Brian Paul | d4cff4f | 2001-07-26 15:57:49 +0000 | [diff] [blame] | 371 | # endif |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 372 | span.attrStepX[VARYING_SLOT_COL0][0] = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr); |
| 373 | span.attrStepY[VARYING_SLOT_COL0][0] = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx); |
| 374 | span.attrStepX[VARYING_SLOT_COL0][1] = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg); |
| 375 | span.attrStepY[VARYING_SLOT_COL0][1] = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx); |
| 376 | span.attrStepX[VARYING_SLOT_COL0][2] = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db); |
| 377 | span.attrStepY[VARYING_SLOT_COL0][2] = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx); |
| 378 | span.redStep = SignedFloatToFixed(span.attrStepX[VARYING_SLOT_COL0][0]); |
| 379 | span.greenStep = SignedFloatToFixed(span.attrStepX[VARYING_SLOT_COL0][1]); |
| 380 | span.blueStep = SignedFloatToFixed(span.attrStepX[VARYING_SLOT_COL0][2]); |
Brian Paul | d4cff4f | 2001-07-26 15:57:49 +0000 | [diff] [blame] | 381 | # ifdef INTERP_ALPHA |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 382 | span.attrStepX[VARYING_SLOT_COL0][3] = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da); |
| 383 | span.attrStepY[VARYING_SLOT_COL0][3] = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx); |
| 384 | span.alphaStep = SignedFloatToFixed(span.attrStepX[VARYING_SLOT_COL0][3]); |
Brian Paul | dec3ed6 | 2003-03-16 18:42:13 +0000 | [diff] [blame] | 385 | # endif /* INTERP_ALPHA */ |
Brian Paul | d4cff4f | 2001-07-26 15:57:49 +0000 | [diff] [blame] | 386 | } |
| 387 | else { |
Matt Turner | bfcdb84 | 2015-02-20 20:18:47 -0800 | [diff] [blame] | 388 | assert(ctx->Light.ShadeModel == GL_FLAT); |
Brian Paul | a4ac844 | 2002-08-07 15:18:42 +0000 | [diff] [blame] | 389 | span.interpMask |= SPAN_FLAT; |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 390 | span.attrStepX[VARYING_SLOT_COL0][0] = span.attrStepY[VARYING_SLOT_COL0][0] = 0.0F; |
| 391 | span.attrStepX[VARYING_SLOT_COL0][1] = span.attrStepY[VARYING_SLOT_COL0][1] = 0.0F; |
| 392 | span.attrStepX[VARYING_SLOT_COL0][2] = span.attrStepY[VARYING_SLOT_COL0][2] = 0.0F; |
Karl Schultz | dc24230 | 2003-08-30 14:45:04 +0000 | [diff] [blame] | 393 | span.redStep = 0; |
| 394 | span.greenStep = 0; |
| 395 | span.blueStep = 0; |
Brian Paul | d4cff4f | 2001-07-26 15:57:49 +0000 | [diff] [blame] | 396 | # ifdef INTERP_ALPHA |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 397 | span.attrStepX[VARYING_SLOT_COL0][3] = span.attrStepY[VARYING_SLOT_COL0][3] = 0.0F; |
Karl Schultz | dc24230 | 2003-08-30 14:45:04 +0000 | [diff] [blame] | 398 | span.alphaStep = 0; |
Brian Paul | d4cff4f | 2001-07-26 15:57:49 +0000 | [diff] [blame] | 399 | # endif |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 400 | } |
Brian Paul | dec3ed6 | 2003-03-16 18:42:13 +0000 | [diff] [blame] | 401 | #endif /* INTERP_RGB */ |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 402 | #ifdef INTERP_INT_TEX |
| 403 | { |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 404 | GLfloat eMaj_ds = (vMax->attrib[VARYING_SLOT_TEX0][0] - vMin->attrib[VARYING_SLOT_TEX0][0]) * S_SCALE; |
| 405 | GLfloat eBot_ds = (vMid->attrib[VARYING_SLOT_TEX0][0] - vMin->attrib[VARYING_SLOT_TEX0][0]) * S_SCALE; |
| 406 | GLfloat eMaj_dt = (vMax->attrib[VARYING_SLOT_TEX0][1] - vMin->attrib[VARYING_SLOT_TEX0][1]) * T_SCALE; |
| 407 | GLfloat eBot_dt = (vMid->attrib[VARYING_SLOT_TEX0][1] - vMin->attrib[VARYING_SLOT_TEX0][1]) * T_SCALE; |
| 408 | span.attrStepX[VARYING_SLOT_TEX0][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds); |
| 409 | span.attrStepY[VARYING_SLOT_TEX0][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx); |
| 410 | span.attrStepX[VARYING_SLOT_TEX0][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt); |
| 411 | span.attrStepY[VARYING_SLOT_TEX0][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx); |
| 412 | span.intTexStep[0] = SignedFloatToFixed(span.attrStepX[VARYING_SLOT_TEX0][0]); |
| 413 | span.intTexStep[1] = SignedFloatToFixed(span.attrStepX[VARYING_SLOT_TEX0][1]); |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 414 | } |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 415 | #endif |
Brian | 8a8a5bd | 2007-04-24 16:16:25 -0600 | [diff] [blame] | 416 | #ifdef INTERP_ATTRIBS |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 417 | { |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 418 | /* attrib[VARYING_SLOT_POS][3] is 1/W */ |
| 419 | const GLfloat wMax = vMax->attrib[VARYING_SLOT_POS][3]; |
| 420 | const GLfloat wMin = vMin->attrib[VARYING_SLOT_POS][3]; |
| 421 | const GLfloat wMid = vMid->attrib[VARYING_SLOT_POS][3]; |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 422 | { |
| 423 | const GLfloat eMaj_dw = wMax - wMin; |
| 424 | const GLfloat eBot_dw = wMid - wMin; |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 425 | span.attrStepX[VARYING_SLOT_POS][3] = oneOverArea * (eMaj_dw * eBot.dy - eMaj.dy * eBot_dw); |
| 426 | span.attrStepY[VARYING_SLOT_POS][3] = oneOverArea * (eMaj.dx * eBot_dw - eMaj_dw * eBot.dx); |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 427 | } |
Brian | 0bdf216 | 2007-04-23 21:21:52 -0600 | [diff] [blame] | 428 | ATTRIB_LOOP_BEGIN |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 429 | if (swrast->_InterpMode[attr] == GL_FLAT) { |
| 430 | ASSIGN_4V(span.attrStepX[attr], 0.0, 0.0, 0.0, 0.0); |
| 431 | ASSIGN_4V(span.attrStepY[attr], 0.0, 0.0, 0.0, 0.0); |
| 432 | } |
| 433 | else { |
| 434 | GLuint c; |
| 435 | for (c = 0; c < 4; c++) { |
| 436 | GLfloat eMaj_da = vMax->attrib[attr][c] * wMax - vMin->attrib[attr][c] * wMin; |
| 437 | GLfloat eBot_da = vMid->attrib[attr][c] * wMid - vMin->attrib[attr][c] * wMin; |
| 438 | span.attrStepX[attr][c] = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da); |
| 439 | span.attrStepY[attr][c] = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx); |
| 440 | } |
| 441 | } |
Brian | 0bdf216 | 2007-04-23 21:21:52 -0600 | [diff] [blame] | 442 | ATTRIB_LOOP_END |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 443 | } |
| 444 | #endif |
| 445 | |
| 446 | /* |
| 447 | * We always sample at pixel centers. However, we avoid |
| 448 | * explicit half-pixel offsets in this code by incorporating |
| 449 | * the proper offset in each of x and y during the |
| 450 | * transformation to window coordinates. |
| 451 | * |
| 452 | * We also apply the usual rasterization rules to prevent |
| 453 | * cracks and overlaps. A pixel is considered inside a |
| 454 | * subtriangle if it meets all of four conditions: it is on or |
| 455 | * to the right of the left edge, strictly to the left of the |
| 456 | * right edge, on or below the top edge, and strictly above |
| 457 | * the bottom edge. (Some edges may be degenerate.) |
| 458 | * |
| 459 | * The following discussion assumes left-to-right scanning |
| 460 | * (that is, the major edge is on the left); the right-to-left |
| 461 | * case is a straightforward variation. |
| 462 | * |
| 463 | * We start by finding the half-integral y coordinate that is |
| 464 | * at or below the top of the triangle. This gives us the |
| 465 | * first scan line that could possibly contain pixels that are |
| 466 | * inside the triangle. |
| 467 | * |
| 468 | * Next we creep down the major edge until we reach that y, |
Gareth Hughes | 22144ab | 2001-03-12 00:48:37 +0000 | [diff] [blame] | 469 | * and compute the corresponding x coordinate on the edge. |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 470 | * Then we find the half-integral x that lies on or just |
| 471 | * inside the edge. This is the first pixel that might lie in |
| 472 | * the interior of the triangle. (We won't know for sure |
| 473 | * until we check the other edges.) |
| 474 | * |
| 475 | * As we rasterize the triangle, we'll step down the major |
| 476 | * edge. For each step in y, we'll move an integer number |
| 477 | * of steps in x. There are two possible x step sizes, which |
| 478 | * we'll call the ``inner'' step (guaranteed to land on the |
| 479 | * edge or inside it) and the ``outer'' step (guaranteed to |
| 480 | * land on the edge or outside it). The inner and outer steps |
| 481 | * differ by one. During rasterization we maintain an error |
| 482 | * term that indicates our distance from the true edge, and |
| 483 | * select either the inner step or the outer step, whichever |
| 484 | * gets us to the first pixel that falls inside the triangle. |
| 485 | * |
| 486 | * All parameters (z, red, etc.) as well as the buffer |
| 487 | * addresses for color and z have inner and outer step values, |
| 488 | * so that we can increment them appropriately. This method |
| 489 | * eliminates the need to adjust parameters by creeping a |
| 490 | * sub-pixel amount into the triangle at each scanline. |
| 491 | */ |
| 492 | |
| 493 | { |
Brian Paul | 7c4a61c | 2004-02-15 16:21:07 +0000 | [diff] [blame] | 494 | GLint subTriangle; |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 495 | GLfixed fxLeftEdge = 0, fxRightEdge = 0; |
| 496 | GLfixed fdxLeftEdge = 0, fdxRightEdge = 0; |
| 497 | GLfixed fError = 0, fdError = 0; |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 498 | #ifdef PIXEL_ADDRESS |
Brian Paul | c5a76cb | 2002-03-01 04:28:32 +0000 | [diff] [blame] | 499 | PIXEL_TYPE *pRow = NULL; |
Brian Paul | 7c4a61c | 2004-02-15 16:21:07 +0000 | [diff] [blame] | 500 | GLint dPRowOuter = 0, dPRowInner; /* offset in bytes */ |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 501 | #endif |
| 502 | #ifdef INTERP_Z |
| 503 | # ifdef DEPTH_TYPE |
Brian Paul | e4b2356 | 2005-05-04 20:11:35 +0000 | [diff] [blame] | 504 | struct gl_renderbuffer *zrb |
| 505 | = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; |
Brian Paul | c5a76cb | 2002-03-01 04:28:32 +0000 | [diff] [blame] | 506 | DEPTH_TYPE *zRow = NULL; |
Brian Paul | 7c4a61c | 2004-02-15 16:21:07 +0000 | [diff] [blame] | 507 | GLint dZRowOuter = 0, dZRowInner; /* offset in bytes */ |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 508 | # endif |
Brian Paul | 7265556 | 2005-09-20 04:34:29 +0000 | [diff] [blame] | 509 | GLuint zLeft = 0; |
| 510 | GLfixed fdzOuter = 0, fdzInner; |
Brian Paul | 54e92e8 | 2003-03-16 22:02:36 +0000 | [diff] [blame] | 511 | #endif |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 512 | #ifdef INTERP_RGB |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 513 | GLint rLeft = 0, fdrOuter = 0, fdrInner; |
| 514 | GLint gLeft = 0, fdgOuter = 0, fdgInner; |
| 515 | GLint bLeft = 0, fdbOuter = 0, fdbInner; |
Brian Paul | 9bf68ad | 2001-05-14 16:23:04 +0000 | [diff] [blame] | 516 | #endif |
| 517 | #ifdef INTERP_ALPHA |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 518 | GLint aLeft = 0, fdaOuter = 0, fdaInner; |
Brian Paul | 96385fa | 2001-07-14 17:53:04 +0000 | [diff] [blame] | 519 | #endif |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 520 | #ifdef INTERP_INT_TEX |
Brian Paul | 54e92e8 | 2003-03-16 22:02:36 +0000 | [diff] [blame] | 521 | GLfixed sLeft=0, dsOuter=0, dsInner; |
| 522 | GLfixed tLeft=0, dtOuter=0, dtInner; |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 523 | #endif |
Brian | 8a8a5bd | 2007-04-24 16:16:25 -0600 | [diff] [blame] | 524 | #ifdef INTERP_ATTRIBS |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 525 | GLfloat wLeft = 0, dwOuter = 0, dwInner; |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 526 | GLfloat attrLeft[VARYING_SLOT_MAX][4]; |
| 527 | GLfloat daOuter[VARYING_SLOT_MAX][4], daInner[VARYING_SLOT_MAX][4]; |
Michal Krol | bb38cad | 2006-04-11 11:41:11 +0000 | [diff] [blame] | 528 | #endif |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 529 | |
| 530 | for (subTriangle=0; subTriangle<=1; subTriangle++) { |
| 531 | EdgeT *eLeft, *eRight; |
| 532 | int setupLeft, setupRight; |
| 533 | int lines; |
| 534 | |
| 535 | if (subTriangle==0) { |
| 536 | /* bottom half */ |
Brian Paul | d4cff4f | 2001-07-26 15:57:49 +0000 | [diff] [blame] | 537 | if (scan_from_left_to_right) { |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 538 | eLeft = &eMaj; |
| 539 | eRight = &eBot; |
| 540 | lines = eRight->lines; |
| 541 | setupLeft = 1; |
| 542 | setupRight = 1; |
| 543 | } |
| 544 | else { |
| 545 | eLeft = &eBot; |
| 546 | eRight = &eMaj; |
| 547 | lines = eLeft->lines; |
| 548 | setupLeft = 1; |
| 549 | setupRight = 1; |
| 550 | } |
| 551 | } |
| 552 | else { |
| 553 | /* top half */ |
Brian Paul | d4cff4f | 2001-07-26 15:57:49 +0000 | [diff] [blame] | 554 | if (scan_from_left_to_right) { |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 555 | eLeft = &eMaj; |
| 556 | eRight = &eTop; |
| 557 | lines = eRight->lines; |
| 558 | setupLeft = 0; |
| 559 | setupRight = 1; |
| 560 | } |
| 561 | else { |
| 562 | eLeft = &eTop; |
| 563 | eRight = &eMaj; |
| 564 | lines = eLeft->lines; |
| 565 | setupLeft = 1; |
| 566 | setupRight = 0; |
| 567 | } |
| 568 | if (lines == 0) |
| 569 | return; |
| 570 | } |
| 571 | |
| 572 | if (setupLeft && eLeft->lines > 0) { |
Brian Paul | 7c4a61c | 2004-02-15 16:21:07 +0000 | [diff] [blame] | 573 | const SWvertex *vLower = eLeft->v0; |
Brian Paul | 7c4a61c | 2004-02-15 16:21:07 +0000 | [diff] [blame] | 574 | const GLfixed fsy = eLeft->fsy; |
Brian Paul | 7d05e48 | 2004-03-14 18:12:06 +0000 | [diff] [blame] | 575 | const GLfixed fsx = eLeft->fsx; /* no fractional part */ |
Brian Paul | 7c4a61c | 2004-02-15 16:21:07 +0000 | [diff] [blame] | 576 | const GLfixed fx = FixedCeil(fsx); /* no fractional part */ |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 577 | const GLfixed adjx = (GLfixed) (fx - eLeft->fx0); /* SCALED! */ |
| 578 | const GLfixed adjy = (GLfixed) eLeft->adjy; /* SCALED! */ |
Brian Paul | 7c4a61c | 2004-02-15 16:21:07 +0000 | [diff] [blame] | 579 | GLint idxOuter; |
| 580 | GLfloat dxOuter; |
Brian Paul | 84b4a3a | 2004-02-17 03:51:47 +0000 | [diff] [blame] | 581 | GLfixed fdxOuter; |
Brian Paul | 7c4a61c | 2004-02-15 16:21:07 +0000 | [diff] [blame] | 582 | |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 583 | fError = fx - fsx - FIXED_ONE; |
| 584 | fxLeftEdge = fsx - FIXED_EPSILON; |
| 585 | fdxLeftEdge = eLeft->fdxdy; |
| 586 | fdxOuter = FixedFloor(fdxLeftEdge - FIXED_EPSILON); |
| 587 | fdError = fdxOuter - fdxLeftEdge + FIXED_ONE; |
| 588 | idxOuter = FixedToInt(fdxOuter); |
Brian Paul | 7c4a61c | 2004-02-15 16:21:07 +0000 | [diff] [blame] | 589 | dxOuter = (GLfloat) idxOuter; |
Brian Paul | 7c4a61c | 2004-02-15 16:21:07 +0000 | [diff] [blame] | 590 | span.y = FixedToInt(fsy); |
| 591 | |
| 592 | /* silence warnings on some compilers */ |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 593 | (void) dxOuter; |
Brian Paul | 7c4a61c | 2004-02-15 16:21:07 +0000 | [diff] [blame] | 594 | (void) adjx; |
| 595 | (void) adjy; |
| 596 | (void) vLower; |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 597 | |
| 598 | #ifdef PIXEL_ADDRESS |
| 599 | { |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 600 | pRow = (PIXEL_TYPE *) PIXEL_ADDRESS(FixedToInt(fxLeftEdge), span.y); |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 601 | dPRowOuter = -((int)BYTES_PER_ROW) + idxOuter * sizeof(PIXEL_TYPE); |
| 602 | /* negative because Y=0 at bottom and increases upward */ |
| 603 | } |
| 604 | #endif |
| 605 | /* |
| 606 | * Now we need the set of parameter (z, color, etc.) values at |
Brian Paul | 7c4a61c | 2004-02-15 16:21:07 +0000 | [diff] [blame] | 607 | * the point (fx, fsy). This gives us properly-sampled parameter |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 608 | * values that we can step from pixel to pixel. Furthermore, |
| 609 | * although we might have intermediate results that overflow |
| 610 | * the normal parameter range when we step temporarily outside |
| 611 | * the triangle, we shouldn't overflow or underflow for any |
| 612 | * pixel that's actually inside the triangle. |
| 613 | */ |
| 614 | |
| 615 | #ifdef INTERP_Z |
| 616 | { |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 617 | GLfloat z0 = vLower->attrib[VARYING_SLOT_POS][2]; |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 618 | if (depthBits <= 16) { |
| 619 | /* interpolate fixed-pt values */ |
Brian | 9ab512a | 2007-02-02 11:01:01 -0700 | [diff] [blame] | 620 | GLfloat tmp = (z0 * FIXED_SCALE |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 621 | + span.attrStepX[VARYING_SLOT_POS][2] * adjx |
| 622 | + span.attrStepY[VARYING_SLOT_POS][2] * adjy) + FIXED_HALF; |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 623 | if (tmp < MAX_GLUINT / 2) |
Brian Paul | 54e92e8 | 2003-03-16 22:02:36 +0000 | [diff] [blame] | 624 | zLeft = (GLfixed) tmp; |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 625 | else |
Brian Paul | 54e92e8 | 2003-03-16 22:02:36 +0000 | [diff] [blame] | 626 | zLeft = MAX_GLUINT / 2; |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 627 | fdzOuter = SignedFloatToFixed(span.attrStepY[VARYING_SLOT_POS][2] + |
| 628 | dxOuter * span.attrStepX[VARYING_SLOT_POS][2]); |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 629 | } |
| 630 | else { |
Brian Paul | 7265556 | 2005-09-20 04:34:29 +0000 | [diff] [blame] | 631 | /* interpolate depth values w/out scaling */ |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 632 | zLeft = (GLuint) (z0 + span.attrStepX[VARYING_SLOT_POS][2] * FixedToFloat(adjx) |
| 633 | + span.attrStepY[VARYING_SLOT_POS][2] * FixedToFloat(adjy)); |
| 634 | fdzOuter = (GLint) (span.attrStepY[VARYING_SLOT_POS][2] + |
| 635 | dxOuter * span.attrStepX[VARYING_SLOT_POS][2]); |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 636 | } |
| 637 | # ifdef DEPTH_TYPE |
Brian Paul | 9bf68ad | 2001-05-14 16:23:04 +0000 | [diff] [blame] | 638 | zRow = (DEPTH_TYPE *) |
Brian Paul | 7cf2d75 | 2011-12-24 08:54:26 -0700 | [diff] [blame] | 639 | _swrast_pixel_address(zrb, FixedToInt(fxLeftEdge), span.y); |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 640 | dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(DEPTH_TYPE); |
| 641 | # endif |
| 642 | } |
Brian Paul | 95e02a2 | 2001-03-08 17:33:33 +0000 | [diff] [blame] | 643 | #endif |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 644 | #ifdef INTERP_RGB |
Brian Paul | d4cff4f | 2001-07-26 15:57:49 +0000 | [diff] [blame] | 645 | if (ctx->Light.ShadeModel == GL_SMOOTH) { |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 646 | rLeft = (GLint)(ChanToFixed(vLower->color[RCOMP]) |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 647 | + span.attrStepX[VARYING_SLOT_COL0][0] * adjx |
| 648 | + span.attrStepY[VARYING_SLOT_COL0][0] * adjy) + FIXED_HALF; |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 649 | gLeft = (GLint)(ChanToFixed(vLower->color[GCOMP]) |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 650 | + span.attrStepX[VARYING_SLOT_COL0][1] * adjx |
| 651 | + span.attrStepY[VARYING_SLOT_COL0][1] * adjy) + FIXED_HALF; |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 652 | bLeft = (GLint)(ChanToFixed(vLower->color[BCOMP]) |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 653 | + span.attrStepX[VARYING_SLOT_COL0][2] * adjx |
| 654 | + span.attrStepY[VARYING_SLOT_COL0][2] * adjy) + FIXED_HALF; |
| 655 | fdrOuter = SignedFloatToFixed(span.attrStepY[VARYING_SLOT_COL0][0] |
| 656 | + dxOuter * span.attrStepX[VARYING_SLOT_COL0][0]); |
| 657 | fdgOuter = SignedFloatToFixed(span.attrStepY[VARYING_SLOT_COL0][1] |
| 658 | + dxOuter * span.attrStepX[VARYING_SLOT_COL0][1]); |
| 659 | fdbOuter = SignedFloatToFixed(span.attrStepY[VARYING_SLOT_COL0][2] |
| 660 | + dxOuter * span.attrStepX[VARYING_SLOT_COL0][2]); |
Brian Paul | d4cff4f | 2001-07-26 15:57:49 +0000 | [diff] [blame] | 661 | # ifdef INTERP_ALPHA |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 662 | aLeft = (GLint)(ChanToFixed(vLower->color[ACOMP]) |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 663 | + span.attrStepX[VARYING_SLOT_COL0][3] * adjx |
| 664 | + span.attrStepY[VARYING_SLOT_COL0][3] * adjy) + FIXED_HALF; |
| 665 | fdaOuter = SignedFloatToFixed(span.attrStepY[VARYING_SLOT_COL0][3] |
| 666 | + dxOuter * span.attrStepX[VARYING_SLOT_COL0][3]); |
Brian Paul | d4cff4f | 2001-07-26 15:57:49 +0000 | [diff] [blame] | 667 | # endif |
| 668 | } |
| 669 | else { |
Matt Turner | bfcdb84 | 2015-02-20 20:18:47 -0800 | [diff] [blame] | 670 | assert(ctx->Light.ShadeModel == GL_FLAT); |
Brian Paul | 54e92e8 | 2003-03-16 22:02:36 +0000 | [diff] [blame] | 671 | rLeft = ChanToFixed(v2->color[RCOMP]); |
| 672 | gLeft = ChanToFixed(v2->color[GCOMP]); |
| 673 | bLeft = ChanToFixed(v2->color[BCOMP]); |
Brian Paul | d4cff4f | 2001-07-26 15:57:49 +0000 | [diff] [blame] | 674 | fdrOuter = fdgOuter = fdbOuter = 0; |
| 675 | # ifdef INTERP_ALPHA |
Brian Paul | 54e92e8 | 2003-03-16 22:02:36 +0000 | [diff] [blame] | 676 | aLeft = ChanToFixed(v2->color[ACOMP]); |
Brian Paul | d4cff4f | 2001-07-26 15:57:49 +0000 | [diff] [blame] | 677 | fdaOuter = 0; |
| 678 | # endif |
| 679 | } |
Brian Paul | daeb005 | 2005-11-15 15:08:03 +0000 | [diff] [blame] | 680 | #endif /* INTERP_RGB */ |
| 681 | |
Brian Paul | dec3ed6 | 2003-03-16 18:42:13 +0000 | [diff] [blame] | 682 | |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 683 | #ifdef INTERP_INT_TEX |
| 684 | { |
| 685 | GLfloat s0, t0; |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 686 | s0 = vLower->attrib[VARYING_SLOT_TEX0][0] * S_SCALE; |
| 687 | sLeft = (GLfixed)(s0 * FIXED_SCALE + span.attrStepX[VARYING_SLOT_TEX0][0] * adjx |
| 688 | + span.attrStepY[VARYING_SLOT_TEX0][0] * adjy) + FIXED_HALF; |
| 689 | dsOuter = SignedFloatToFixed(span.attrStepY[VARYING_SLOT_TEX0][0] |
| 690 | + dxOuter * span.attrStepX[VARYING_SLOT_TEX0][0]); |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 691 | |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 692 | t0 = vLower->attrib[VARYING_SLOT_TEX0][1] * T_SCALE; |
| 693 | tLeft = (GLfixed)(t0 * FIXED_SCALE + span.attrStepX[VARYING_SLOT_TEX0][1] * adjx |
| 694 | + span.attrStepY[VARYING_SLOT_TEX0][1] * adjy) + FIXED_HALF; |
| 695 | dtOuter = SignedFloatToFixed(span.attrStepY[VARYING_SLOT_TEX0][1] |
| 696 | + dxOuter * span.attrStepX[VARYING_SLOT_TEX0][1]); |
Brian Paul | d22554d | 2001-09-13 21:54:29 +0000 | [diff] [blame] | 697 | } |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 698 | #endif |
Brian | 8a8a5bd | 2007-04-24 16:16:25 -0600 | [diff] [blame] | 699 | #ifdef INTERP_ATTRIBS |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 700 | { |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 701 | const GLuint attr = VARYING_SLOT_POS; |
| 702 | wLeft = vLower->attrib[VARYING_SLOT_POS][3] |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 703 | + (span.attrStepX[attr][3] * adjx |
| 704 | + span.attrStepY[attr][3] * adjy) * (1.0F/FIXED_SCALE); |
| 705 | dwOuter = span.attrStepY[attr][3] + dxOuter * span.attrStepX[attr][3]; |
| 706 | } |
Brian | 0bdf216 | 2007-04-23 21:21:52 -0600 | [diff] [blame] | 707 | ATTRIB_LOOP_BEGIN |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 708 | const GLfloat invW = vLower->attrib[VARYING_SLOT_POS][3]; |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 709 | if (swrast->_InterpMode[attr] == GL_FLAT) { |
| 710 | GLuint c; |
| 711 | for (c = 0; c < 4; c++) { |
| 712 | attrLeft[attr][c] = v2->attrib[attr][c] * invW; |
| 713 | daOuter[attr][c] = 0.0; |
| 714 | } |
| 715 | } |
| 716 | else { |
| 717 | GLuint c; |
| 718 | for (c = 0; c < 4; c++) { |
| 719 | const GLfloat a = vLower->attrib[attr][c] * invW; |
| 720 | attrLeft[attr][c] = a + ( span.attrStepX[attr][c] * adjx |
| 721 | + span.attrStepY[attr][c] * adjy) * (1.0F/FIXED_SCALE); |
| 722 | daOuter[attr][c] = span.attrStepY[attr][c] + dxOuter * span.attrStepX[attr][c]; |
| 723 | } |
| 724 | } |
Brian | 0bdf216 | 2007-04-23 21:21:52 -0600 | [diff] [blame] | 725 | ATTRIB_LOOP_END |
Michal Krol | bb38cad | 2006-04-11 11:41:11 +0000 | [diff] [blame] | 726 | #endif |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 727 | } /*if setupLeft*/ |
| 728 | |
| 729 | |
| 730 | if (setupRight && eRight->lines>0) { |
| 731 | fxRightEdge = eRight->fsx - FIXED_EPSILON; |
| 732 | fdxRightEdge = eRight->fdxdy; |
| 733 | } |
| 734 | |
| 735 | if (lines==0) { |
| 736 | continue; |
| 737 | } |
| 738 | |
| 739 | |
| 740 | /* Rasterize setup */ |
| 741 | #ifdef PIXEL_ADDRESS |
| 742 | dPRowInner = dPRowOuter + sizeof(PIXEL_TYPE); |
| 743 | #endif |
| 744 | #ifdef INTERP_Z |
| 745 | # ifdef DEPTH_TYPE |
| 746 | dZRowInner = dZRowOuter + sizeof(DEPTH_TYPE); |
| 747 | # endif |
Brian Paul | a4ac844 | 2002-08-07 15:18:42 +0000 | [diff] [blame] | 748 | fdzInner = fdzOuter + span.zStep; |
Brian Paul | 95e02a2 | 2001-03-08 17:33:33 +0000 | [diff] [blame] | 749 | #endif |
Brian Paul | 05ad307 | 2004-02-15 17:45:17 +0000 | [diff] [blame] | 750 | #ifdef INTERP_RGB |
Brian Paul | a4ac844 | 2002-08-07 15:18:42 +0000 | [diff] [blame] | 751 | fdrInner = fdrOuter + span.redStep; |
| 752 | fdgInner = fdgOuter + span.greenStep; |
| 753 | fdbInner = fdbOuter + span.blueStep; |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 754 | #endif |
Brian Paul | 05ad307 | 2004-02-15 17:45:17 +0000 | [diff] [blame] | 755 | #ifdef INTERP_ALPHA |
Brian Paul | a4ac844 | 2002-08-07 15:18:42 +0000 | [diff] [blame] | 756 | fdaInner = fdaOuter + span.alphaStep; |
Brian Paul | 9bf68ad | 2001-05-14 16:23:04 +0000 | [diff] [blame] | 757 | #endif |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 758 | #ifdef INTERP_INT_TEX |
Brian Paul | 54e92e8 | 2003-03-16 22:02:36 +0000 | [diff] [blame] | 759 | dsInner = dsOuter + span.intTexStep[0]; |
| 760 | dtInner = dtOuter + span.intTexStep[1]; |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 761 | #endif |
Brian | 8a8a5bd | 2007-04-24 16:16:25 -0600 | [diff] [blame] | 762 | #ifdef INTERP_ATTRIBS |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 763 | dwInner = dwOuter + span.attrStepX[VARYING_SLOT_POS][3]; |
Brian | 0bdf216 | 2007-04-23 21:21:52 -0600 | [diff] [blame] | 764 | ATTRIB_LOOP_BEGIN |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 765 | GLuint c; |
| 766 | for (c = 0; c < 4; c++) { |
| 767 | daInner[attr][c] = daOuter[attr][c] + span.attrStepX[attr][c]; |
| 768 | } |
Brian | 0bdf216 | 2007-04-23 21:21:52 -0600 | [diff] [blame] | 769 | ATTRIB_LOOP_END |
Michal Krol | bb38cad | 2006-04-11 11:41:11 +0000 | [diff] [blame] | 770 | #endif |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 771 | |
Brian Paul | 9bf68ad | 2001-05-14 16:23:04 +0000 | [diff] [blame] | 772 | while (lines > 0) { |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 773 | /* initialize the span interpolants to the leftmost value */ |
| 774 | /* ff = fixed-pt fragment */ |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 775 | const GLint right = FixedToInt(fxRightEdge); |
| 776 | span.x = FixedToInt(fxLeftEdge); |
Brian Paul | a4ac844 | 2002-08-07 15:18:42 +0000 | [diff] [blame] | 777 | if (right <= span.x) |
| 778 | span.end = 0; |
Brian Paul | 9bf68ad | 2001-05-14 16:23:04 +0000 | [diff] [blame] | 779 | else |
Brian Paul | a4ac844 | 2002-08-07 15:18:42 +0000 | [diff] [blame] | 780 | span.end = right - span.x; |
Brian Paul | 9bf68ad | 2001-05-14 16:23:04 +0000 | [diff] [blame] | 781 | |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 782 | #ifdef INTERP_Z |
Brian Paul | 54e92e8 | 2003-03-16 22:02:36 +0000 | [diff] [blame] | 783 | span.z = zLeft; |
| 784 | #endif |
Brian Paul | 05ad307 | 2004-02-15 17:45:17 +0000 | [diff] [blame] | 785 | #ifdef INTERP_RGB |
Brian Paul | 54e92e8 | 2003-03-16 22:02:36 +0000 | [diff] [blame] | 786 | span.red = rLeft; |
| 787 | span.green = gLeft; |
| 788 | span.blue = bLeft; |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 789 | #endif |
Brian Paul | 05ad307 | 2004-02-15 17:45:17 +0000 | [diff] [blame] | 790 | #ifdef INTERP_ALPHA |
Brian Paul | 54e92e8 | 2003-03-16 22:02:36 +0000 | [diff] [blame] | 791 | span.alpha = aLeft; |
Brian Paul | 9bf68ad | 2001-05-14 16:23:04 +0000 | [diff] [blame] | 792 | #endif |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 793 | #ifdef INTERP_INT_TEX |
Brian Paul | 54e92e8 | 2003-03-16 22:02:36 +0000 | [diff] [blame] | 794 | span.intTex[0] = sLeft; |
| 795 | span.intTex[1] = tLeft; |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 796 | #endif |
Brian Paul | 9bf68ad | 2001-05-14 16:23:04 +0000 | [diff] [blame] | 797 | |
Brian | 8a8a5bd | 2007-04-24 16:16:25 -0600 | [diff] [blame] | 798 | #ifdef INTERP_ATTRIBS |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 799 | span.attrStart[VARYING_SLOT_POS][3] = wLeft; |
Brian | 0bdf216 | 2007-04-23 21:21:52 -0600 | [diff] [blame] | 800 | ATTRIB_LOOP_BEGIN |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 801 | GLuint c; |
| 802 | for (c = 0; c < 4; c++) { |
| 803 | span.attrStart[attr][c] = attrLeft[attr][c]; |
| 804 | } |
Brian | 0bdf216 | 2007-04-23 21:21:52 -0600 | [diff] [blame] | 805 | ATTRIB_LOOP_END |
Michal Krol | bb38cad | 2006-04-11 11:41:11 +0000 | [diff] [blame] | 806 | #endif |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 807 | |
Brian Paul | 9bf68ad | 2001-05-14 16:23:04 +0000 | [diff] [blame] | 808 | /* This is where we actually generate fragments */ |
Brian Paul | 7d3b260 | 2005-10-21 18:35:35 +0000 | [diff] [blame] | 809 | /* XXX the test for span.y > 0 _shouldn't_ be needed but |
| 810 | * it fixes a problem on 64-bit Opterons (bug 4842). |
| 811 | */ |
| 812 | if (span.end > 0 && span.y >= 0) { |
Brian Paul | daeb005 | 2005-11-15 15:08:03 +0000 | [diff] [blame] | 813 | const GLint len = span.end - 1; |
| 814 | (void) len; |
| 815 | #ifdef INTERP_RGB |
| 816 | CLAMP_INTERPOLANT(red, redStep, len); |
| 817 | CLAMP_INTERPOLANT(green, greenStep, len); |
| 818 | CLAMP_INTERPOLANT(blue, blueStep, len); |
| 819 | #endif |
| 820 | #ifdef INTERP_ALPHA |
| 821 | CLAMP_INTERPOLANT(alpha, alphaStep, len); |
| 822 | #endif |
Brian Paul | 9200232 | 2006-03-29 23:42:44 +0000 | [diff] [blame] | 823 | { |
| 824 | RENDER_SPAN( span ); |
| 825 | } |
Brian Paul | 9bf68ad | 2001-05-14 16:23:04 +0000 | [diff] [blame] | 826 | } |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 827 | |
| 828 | /* |
| 829 | * Advance to the next scan line. Compute the |
| 830 | * new edge coordinates, and adjust the |
| 831 | * pixel-center x coordinate so that it stays |
| 832 | * on or inside the major edge. |
| 833 | */ |
Brian Paul | 05ad307 | 2004-02-15 17:45:17 +0000 | [diff] [blame] | 834 | span.y++; |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 835 | lines--; |
| 836 | |
| 837 | fxLeftEdge += fdxLeftEdge; |
| 838 | fxRightEdge += fdxRightEdge; |
| 839 | |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 840 | fError += fdError; |
| 841 | if (fError >= 0) { |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 842 | fError -= FIXED_ONE; |
Brian Paul | 84b4a3a | 2004-02-17 03:51:47 +0000 | [diff] [blame] | 843 | |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 844 | #ifdef PIXEL_ADDRESS |
Brian Paul | 9bf68ad | 2001-05-14 16:23:04 +0000 | [diff] [blame] | 845 | pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowOuter); |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 846 | #endif |
| 847 | #ifdef INTERP_Z |
| 848 | # ifdef DEPTH_TYPE |
Brian Paul | 9bf68ad | 2001-05-14 16:23:04 +0000 | [diff] [blame] | 849 | zRow = (DEPTH_TYPE *) ((GLubyte *) zRow + dZRowOuter); |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 850 | # endif |
Brian Paul | 54e92e8 | 2003-03-16 22:02:36 +0000 | [diff] [blame] | 851 | zLeft += fdzOuter; |
| 852 | #endif |
Brian Paul | 05ad307 | 2004-02-15 17:45:17 +0000 | [diff] [blame] | 853 | #ifdef INTERP_RGB |
Brian Paul | 54e92e8 | 2003-03-16 22:02:36 +0000 | [diff] [blame] | 854 | rLeft += fdrOuter; |
| 855 | gLeft += fdgOuter; |
| 856 | bLeft += fdbOuter; |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 857 | #endif |
Brian Paul | 05ad307 | 2004-02-15 17:45:17 +0000 | [diff] [blame] | 858 | #ifdef INTERP_ALPHA |
Brian Paul | 54e92e8 | 2003-03-16 22:02:36 +0000 | [diff] [blame] | 859 | aLeft += fdaOuter; |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 860 | #endif |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 861 | #ifdef INTERP_INT_TEX |
Brian Paul | 54e92e8 | 2003-03-16 22:02:36 +0000 | [diff] [blame] | 862 | sLeft += dsOuter; |
| 863 | tLeft += dtOuter; |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 864 | #endif |
Brian | 8a8a5bd | 2007-04-24 16:16:25 -0600 | [diff] [blame] | 865 | #ifdef INTERP_ATTRIBS |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 866 | wLeft += dwOuter; |
Brian | 0bdf216 | 2007-04-23 21:21:52 -0600 | [diff] [blame] | 867 | ATTRIB_LOOP_BEGIN |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 868 | GLuint c; |
| 869 | for (c = 0; c < 4; c++) { |
| 870 | attrLeft[attr][c] += daOuter[attr][c]; |
| 871 | } |
Brian | 0bdf216 | 2007-04-23 21:21:52 -0600 | [diff] [blame] | 872 | ATTRIB_LOOP_END |
Michal Krol | bb38cad | 2006-04-11 11:41:11 +0000 | [diff] [blame] | 873 | #endif |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 874 | } |
| 875 | else { |
| 876 | #ifdef PIXEL_ADDRESS |
Brian Paul | 9bf68ad | 2001-05-14 16:23:04 +0000 | [diff] [blame] | 877 | pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowInner); |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 878 | #endif |
| 879 | #ifdef INTERP_Z |
| 880 | # ifdef DEPTH_TYPE |
Brian Paul | 9bf68ad | 2001-05-14 16:23:04 +0000 | [diff] [blame] | 881 | zRow = (DEPTH_TYPE *) ((GLubyte *) zRow + dZRowInner); |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 882 | # endif |
Brian Paul | 54e92e8 | 2003-03-16 22:02:36 +0000 | [diff] [blame] | 883 | zLeft += fdzInner; |
| 884 | #endif |
Brian Paul | 05ad307 | 2004-02-15 17:45:17 +0000 | [diff] [blame] | 885 | #ifdef INTERP_RGB |
Brian Paul | 54e92e8 | 2003-03-16 22:02:36 +0000 | [diff] [blame] | 886 | rLeft += fdrInner; |
| 887 | gLeft += fdgInner; |
| 888 | bLeft += fdbInner; |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 889 | #endif |
Brian Paul | 05ad307 | 2004-02-15 17:45:17 +0000 | [diff] [blame] | 890 | #ifdef INTERP_ALPHA |
Brian Paul | 54e92e8 | 2003-03-16 22:02:36 +0000 | [diff] [blame] | 891 | aLeft += fdaInner; |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 892 | #endif |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 893 | #ifdef INTERP_INT_TEX |
Brian Paul | 54e92e8 | 2003-03-16 22:02:36 +0000 | [diff] [blame] | 894 | sLeft += dsInner; |
| 895 | tLeft += dtInner; |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 896 | #endif |
Brian | 8a8a5bd | 2007-04-24 16:16:25 -0600 | [diff] [blame] | 897 | #ifdef INTERP_ATTRIBS |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 898 | wLeft += dwInner; |
Brian | 0bdf216 | 2007-04-23 21:21:52 -0600 | [diff] [blame] | 899 | ATTRIB_LOOP_BEGIN |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 900 | GLuint c; |
| 901 | for (c = 0; c < 4; c++) { |
| 902 | attrLeft[attr][c] += daInner[attr][c]; |
| 903 | } |
Brian | 0bdf216 | 2007-04-23 21:21:52 -0600 | [diff] [blame] | 904 | ATTRIB_LOOP_END |
Michal Krol | bb38cad | 2006-04-11 11:41:11 +0000 | [diff] [blame] | 905 | #endif |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 906 | } |
| 907 | } /*while lines>0*/ |
| 908 | |
| 909 | } /* for subTriangle */ |
| 910 | |
| 911 | } |
| 912 | } |
| 913 | } |
| 914 | |
| 915 | #undef SETUP_CODE |
Brian Paul | 9bf68ad | 2001-05-14 16:23:04 +0000 | [diff] [blame] | 916 | #undef RENDER_SPAN |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 917 | |
| 918 | #undef PIXEL_TYPE |
| 919 | #undef BYTES_PER_ROW |
| 920 | #undef PIXEL_ADDRESS |
Brian Paul | 2cbbd3d | 2005-04-22 02:56:21 +0000 | [diff] [blame] | 921 | #undef DEPTH_TYPE |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 922 | |
| 923 | #undef INTERP_Z |
| 924 | #undef INTERP_RGB |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 925 | #undef INTERP_ALPHA |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 926 | #undef INTERP_INT_TEX |
Brian | 8a8a5bd | 2007-04-24 16:16:25 -0600 | [diff] [blame] | 927 | #undef INTERP_ATTRIBS |
Keith Whitwell | e3a051e | 2000-10-31 18:00:04 +0000 | [diff] [blame] | 928 | |
| 929 | #undef S_SCALE |
| 930 | #undef T_SCALE |
| 931 | |
| 932 | #undef FixedToDepth |
| 933 | |
Brian Paul | cdf2da3 | 2002-11-13 16:51:01 +0000 | [diff] [blame] | 934 | #undef NAME |