1e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/* 2e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Mesa 3-D graphics library 322a374fc3fdf97a9cc50e9fdc24049c997e6896eBrian * Version: 7.0.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/* 27e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Antialiased Triangle Rasterizer Template 28e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * 29e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * This file is #include'd to generate custom AA triangle rasterizers. 30e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * NOTE: this code hasn't been optimized yet. That'll come after it 31e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * works correctly. 32e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * 33e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * The following macros may be defined to indicate what auxillary information 34e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * must be copmuted across the triangle: 35e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * DO_Z - if defined, compute Z values 36eca456b63d41700617987ba45a09e8f2168b9577Brian * DO_ATTRIBS - if defined, compute texcoords, varying, etc. 37e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 38e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 39f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg/*void triangle( struct gl_context *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint pv )*/ 40e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{ 41dd34fe8679fa200e55cfaf8e80bbecdecea084e3Brian const SWcontext *swrast = SWRAST_CONTEXT(ctx); 429e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat *p0 = v0->attrib[FRAG_ATTRIB_WPOS]; 439e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat *p1 = v1->attrib[FRAG_ATTRIB_WPOS]; 449e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat *p2 = v2->attrib[FRAG_ATTRIB_WPOS]; 45a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul const SWvertex *vMin, *vMid, *vMax; 46ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul GLint iyMin, iyMax; 47ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul GLfloat yMin, yMax; 48ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul GLboolean ltor; 49ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul GLfloat majDx, majDy; /* major (i.e. long) edge dx and dy */ 5010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 51cdb27e8242215271364602995d85607cfc06d441Brian Paul SWspan span; 5210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 53e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef DO_Z 5447cf442c1164b6b406117fccfb8b564602741ee3Brian Paul GLfloat zPlane[4]; 5580532da3bf2a83448c6f38c34dbaf32898acea2dBrian Paul#endif 5647cf442c1164b6b406117fccfb8b564602741ee3Brian Paul GLfloat rPlane[4], gPlane[4], bPlane[4], aPlane[4]; 57eca456b63d41700617987ba45a09e8f2168b9577Brian#if defined(DO_ATTRIBS) 589e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLfloat attrPlane[FRAG_ATTRIB_MAX][4][4]; 599e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLfloat wPlane[4]; /* win[3] */ 60e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif 61fcd7c37fd3d0f61cf6ac81170bc0b3fca64ad9bbBrian GLfloat bf = SWRAST_CONTEXT(ctx)->_BackfaceCullSign; 6210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 63dd34fe8679fa200e55cfaf8e80bbecdecea084e3Brian (void) swrast; 64dd34fe8679fa200e55cfaf8e80bbecdecea084e3Brian 65f4b103dc993491355ec3e3640d9cb060138175c2Brian INIT_SPAN(span, GL_POLYGON); 66f4b103dc993491355ec3e3640d9cb060138175c2Brian span.arrayMask = SPAN_COVERAGE; 672a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 68e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell /* determine bottom to top order of vertices */ 69e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell { 709e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLfloat y0 = v0->attrib[FRAG_ATTRIB_WPOS][1]; 719e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLfloat y1 = v1->attrib[FRAG_ATTRIB_WPOS][1]; 729e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLfloat y2 = v2->attrib[FRAG_ATTRIB_WPOS][1]; 73e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (y0 <= y1) { 74e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (y1 <= y2) { 75e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell vMin = v0; vMid = v1; vMax = v2; /* y0<=y1<=y2 */ 76e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 77e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else if (y2 <= y0) { 78e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell vMin = v2; vMid = v0; vMax = v1; /* y2<=y0<=y1 */ 79e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 80e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 81e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell vMin = v0; vMid = v2; vMax = v1; bf = -bf; /* y0<=y2<=y1 */ 82e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 83e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 84e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 85e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (y0 <= y2) { 86e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell vMin = v1; vMid = v0; vMax = v2; bf = -bf; /* y1<=y0<=y2 */ 87e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 88e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else if (y2 <= y1) { 89e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell vMin = v2; vMid = v1; vMax = v0; bf = -bf; /* y2<=y1<=y0 */ 90e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 91e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 92e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell vMin = v1; vMid = v2; vMax = v0; /* y1<=y2<=y0 */ 93e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 94e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 95e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 96e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 979e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian majDx = vMax->attrib[FRAG_ATTRIB_WPOS][0] - vMin->attrib[FRAG_ATTRIB_WPOS][0]; 989e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian majDy = vMax->attrib[FRAG_ATTRIB_WPOS][1] - vMin->attrib[FRAG_ATTRIB_WPOS][1]; 99ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul 100fcd7c37fd3d0f61cf6ac81170bc0b3fca64ad9bbBrian /* front/back-face determination and cullling */ 101ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul { 1029e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat botDx = vMid->attrib[FRAG_ATTRIB_WPOS][0] - vMin->attrib[FRAG_ATTRIB_WPOS][0]; 1039e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat botDy = vMid->attrib[FRAG_ATTRIB_WPOS][1] - vMin->attrib[FRAG_ATTRIB_WPOS][1]; 104ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul const GLfloat area = majDx * botDy - botDx * majDy; 105ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul /* Do backface culling */ 106ef4f5b391e560e535b25b372f797e41edeef09f1Keith Whitwell if (area * bf < 0 || area == 0 || IS_INF_OR_NAN(area)) 107ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul return; 10802de45dcedc38b0e4ceacba440bfc11930ec90bbBrian Paul ltor = (GLboolean) (area < 0.0F); 109fcd7c37fd3d0f61cf6ac81170bc0b3fca64ad9bbBrian 110fcd7c37fd3d0f61cf6ac81170bc0b3fca64ad9bbBrian span.facing = area * swrast->_BackfaceSign > 0.0F; 111ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul } 112e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 11380532da3bf2a83448c6f38c34dbaf32898acea2dBrian Paul /* Plane equation setup: 11480532da3bf2a83448c6f38c34dbaf32898acea2dBrian Paul * We evaluate plane equations at window (x,y) coordinates in order 11580532da3bf2a83448c6f38c34dbaf32898acea2dBrian Paul * to compute color, Z, fog, texcoords, etc. This isn't terribly 116ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul * efficient but it's easy and reliable. 11780532da3bf2a83448c6f38c34dbaf32898acea2dBrian Paul */ 118e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef DO_Z 119e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell compute_plane(p0, p1, p2, p0[2], p1[2], p2[2], zPlane); 12077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span.arrayMask |= SPAN_Z; 12180532da3bf2a83448c6f38c34dbaf32898acea2dBrian Paul#endif 122e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell if (ctx->Light.ShadeModel == GL_SMOOTH) { 1238f95d790daee7c012364d689e7d86524340469c1Brian Paul compute_plane(p0, p1, p2, v0->color[RCOMP], v1->color[RCOMP], v2->color[RCOMP], rPlane); 1248f95d790daee7c012364d689e7d86524340469c1Brian Paul compute_plane(p0, p1, p2, v0->color[GCOMP], v1->color[GCOMP], v2->color[GCOMP], gPlane); 1258f95d790daee7c012364d689e7d86524340469c1Brian Paul compute_plane(p0, p1, p2, v0->color[BCOMP], v1->color[BCOMP], v2->color[BCOMP], bPlane); 1268f95d790daee7c012364d689e7d86524340469c1Brian Paul compute_plane(p0, p1, p2, v0->color[ACOMP], v1->color[ACOMP], v2->color[ACOMP], aPlane); 127e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 128e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell else { 12958e991705392a2e17a1c8b034f4083a0adaf1943Keith Whitwell constant_plane(v2->color[RCOMP], rPlane); 13058e991705392a2e17a1c8b034f4083a0adaf1943Keith Whitwell constant_plane(v2->color[GCOMP], gPlane); 13158e991705392a2e17a1c8b034f4083a0adaf1943Keith Whitwell constant_plane(v2->color[BCOMP], bPlane); 13258e991705392a2e17a1c8b034f4083a0adaf1943Keith Whitwell constant_plane(v2->color[ACOMP], aPlane); 133e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 13477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul span.arrayMask |= SPAN_RGBA; 135eca456b63d41700617987ba45a09e8f2168b9577Brian#if defined(DO_ATTRIBS) 136e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell { 1379e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat invW0 = v0->attrib[FRAG_ATTRIB_WPOS][3]; 1389e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat invW1 = v1->attrib[FRAG_ATTRIB_WPOS][3]; 1399e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat invW2 = v2->attrib[FRAG_ATTRIB_WPOS][3]; 1409e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian compute_plane(p0, p1, p2, invW0, invW1, invW2, wPlane); 1419e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span.attrStepX[FRAG_ATTRIB_WPOS][3] = plane_dx(wPlane); 1429e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span.attrStepY[FRAG_ATTRIB_WPOS][3] = plane_dy(wPlane); 1430bdf216dd06d5136b8529297297aa962bab548c2Brian ATTRIB_LOOP_BEGIN 1449e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLuint c; 1459e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian if (swrast->_InterpMode[attr] == GL_FLAT) { 1469e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian for (c = 0; c < 4; c++) { 1479e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian constant_plane(v2->attrib[attr][c] * invW2, attrPlane[attr][c]); 1489e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 149e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 1500bdf216dd06d5136b8529297297aa962bab548c2Brian else { 1519e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian for (c = 0; c < 4; c++) { 1529e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat a0 = v0->attrib[attr][c] * invW0; 1539e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat a1 = v1->attrib[attr][c] * invW1; 1549e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat a2 = v2->attrib[attr][c] * invW2; 1559e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian compute_plane(p0, p1, p2, a0, a1, a2, attrPlane[attr][c]); 1569e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 1579e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 1589e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian for (c = 0; c < 4; c++) { 1599e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span.attrStepX[attr][c] = plane_dx(attrPlane[attr][c]); 1609e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian span.attrStepY[attr][c] = plane_dy(attrPlane[attr][c]); 1610bdf216dd06d5136b8529297297aa962bab548c2Brian } 1620bdf216dd06d5136b8529297297aa962bab548c2Brian ATTRIB_LOOP_END 163e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 164e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif 165e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 16680532da3bf2a83448c6f38c34dbaf32898acea2dBrian Paul /* Begin bottom-to-top scan over the triangle. 16780532da3bf2a83448c6f38c34dbaf32898acea2dBrian Paul * The long edge will either be on the left or right side of the 16880532da3bf2a83448c6f38c34dbaf32898acea2dBrian Paul * triangle. We always scan from the long edge toward the shorter 16980532da3bf2a83448c6f38c34dbaf32898acea2dBrian Paul * edges, stopping when we find that coverage = 0. If the long edge 17080532da3bf2a83448c6f38c34dbaf32898acea2dBrian Paul * is on the left we scan left-to-right. Else, we scan right-to-left. 17180532da3bf2a83448c6f38c34dbaf32898acea2dBrian Paul */ 1729e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian yMin = vMin->attrib[FRAG_ATTRIB_WPOS][1]; 1739e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian yMax = vMax->attrib[FRAG_ATTRIB_WPOS][1]; 174ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul iyMin = (GLint) yMin; 175ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul iyMax = (GLint) yMax + 1; 176ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul 177ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul if (ltor) { 178ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul /* scan left to right */ 1799e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat *pMin = vMin->attrib[FRAG_ATTRIB_WPOS]; 1809e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat *pMid = vMid->attrib[FRAG_ATTRIB_WPOS]; 1819e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat *pMax = vMax->attrib[FRAG_ATTRIB_WPOS]; 182ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul const GLfloat dxdy = majDx / majDy; 183ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul const GLfloat xAdj = dxdy < 0.0F ? -dxdy : 0.0F; 184470a7b48745d0e467973c9b9d751a8be4abec0e6Brian Paul GLint iy; 185e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger#ifdef _OPENMP 186e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger#pragma omp parallel for schedule(dynamic) private(iy) firstprivate(span) 187e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger#endif 188e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger for (iy = iyMin; iy < iyMax; iy++) { 189e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger GLfloat x = pMin[0] - (yMin - iy) * dxdy; 190ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul GLint ix, startX = (GLint) (x - xAdj); 191f1e236987829393c81dc86ea19cb49eefe190317Brian Paul GLuint count; 192e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell GLfloat coverage = 0.0F; 19310f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 194e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger#ifdef _OPENMP 195e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger /* each thread needs to use a different (global) SpanArrays variable */ 196e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger span.array = SWRAST_CONTEXT(ctx)->SpanArrays + omp_get_thread_num(); 197e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger#endif 198ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul /* skip over fragments with zero coverage */ 19947d88ef204b42a9220c6be3e98c92df9c9aa0860Brian Paul while (startX < SWRAST_MAX_WIDTH) { 200ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul coverage = compute_coveragef(pMin, pMid, pMax, startX, iy); 201ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul if (coverage > 0.0F) 202ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul break; 203ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul startX++; 204f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul } 205f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul 206ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul /* enter interior of triangle */ 207ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul ix = startX; 2089e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian 2099e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#if defined(DO_ATTRIBS) 2109e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* compute attributes at left-most fragment */ 211880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul span.attrStart[FRAG_ATTRIB_WPOS][3] = solve_plane(ix + 0.5F, iy + 0.5F, wPlane); 2129e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ATTRIB_LOOP_BEGIN 2139e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLuint c; 2149e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian for (c = 0; c < 4; c++) { 215880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul span.attrStart[attr][c] = solve_plane(ix + 0.5F, iy + 0.5F, attrPlane[attr][c]); 2169e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 2179e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ATTRIB_LOOP_END 2189e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#endif 2199e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian 220ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul count = 0; 221ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul while (coverage > 0.0F) { 222ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul /* (cx,cy) = center of fragment */ 223ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul const GLfloat cx = ix + 0.5F, cy = iy + 0.5F; 224cdb27e8242215271364602995d85607cfc06d441Brian Paul SWspanarrays *array = span.array; 22577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul array->coverage[count] = coverage; 226e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef DO_Z 22714570e6d7ccf43b228d09d6fc01a45b2ba31947bBrian Paul array->z[count] = (GLuint) solve_plane(cx, cy, zPlane); 22880532da3bf2a83448c6f38c34dbaf32898acea2dBrian Paul#endif 22977df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul array->rgba[count][RCOMP] = solve_plane_chan(cx, cy, rPlane); 23077df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul array->rgba[count][GCOMP] = solve_plane_chan(cx, cy, gPlane); 23177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul array->rgba[count][BCOMP] = solve_plane_chan(cx, cy, bPlane); 23277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul array->rgba[count][ACOMP] = solve_plane_chan(cx, cy, aPlane); 233ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul ix++; 234ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul count++; 235ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul coverage = compute_coveragef(pMin, pMid, pMax, ix, iy); 236ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul } 23710f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 238e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger if (ix > startX) { 239e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger span.x = startX; 240e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger span.y = iy; 241e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger span.end = (GLuint) ix - (GLuint) startX; 242e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger _swrast_write_rgba_span(ctx, &span); 243e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger } 244ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul } 245ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul } 246ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul else { 247ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul /* scan right to left */ 2489e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat *pMin = vMin->attrib[FRAG_ATTRIB_WPOS]; 2499e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat *pMid = vMid->attrib[FRAG_ATTRIB_WPOS]; 2509e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian const GLfloat *pMax = vMax->attrib[FRAG_ATTRIB_WPOS]; 251ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul const GLfloat dxdy = majDx / majDy; 252ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul const GLfloat xAdj = dxdy > 0 ? dxdy : 0.0F; 253ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul GLint iy; 254e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger#ifdef _OPENMP 255e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger#pragma omp parallel for schedule(dynamic) private(iy) firstprivate(span) 256e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger#endif 257e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger for (iy = iyMin; iy < iyMax; iy++) { 258e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger GLfloat x = pMin[0] - (yMin - iy) * dxdy; 259ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul GLint ix, left, startX = (GLint) (x + xAdj); 260ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul GLuint count, n; 261ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul GLfloat coverage = 0.0F; 26210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 263e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger#ifdef _OPENMP 264e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger /* each thread needs to use a different (global) SpanArrays variable */ 265e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger span.array = SWRAST_CONTEXT(ctx)->SpanArrays + omp_get_thread_num(); 266e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger#endif 267ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul /* make sure we're not past the window edge */ 268ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul if (startX >= ctx->DrawBuffer->_Xmax) { 269ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul startX = ctx->DrawBuffer->_Xmax - 1; 270ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul } 271d082417daeb3f8a35a490eb44b6c88463289fa5dBrian Paul 272ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul /* skip fragments with zero coverage */ 27322a374fc3fdf97a9cc50e9fdc24049c997e6896eBrian while (startX > 0) { 274ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul coverage = compute_coveragef(pMin, pMax, pMid, startX, iy); 275ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul if (coverage > 0.0F) 276ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul break; 277ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul startX--; 278ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul } 27910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 280ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul /* enter interior of triangle */ 281ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul ix = startX; 282ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul count = 0; 283ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul while (coverage > 0.0F) { 284ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul /* (cx,cy) = center of fragment */ 285ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul const GLfloat cx = ix + 0.5F, cy = iy + 0.5F; 286cdb27e8242215271364602995d85607cfc06d441Brian Paul SWspanarrays *array = span.array; 28722a374fc3fdf97a9cc50e9fdc24049c997e6896eBrian ASSERT(ix >= 0); 28877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul array->coverage[ix] = coverage; 289e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef DO_Z 29014570e6d7ccf43b228d09d6fc01a45b2ba31947bBrian Paul array->z[ix] = (GLuint) solve_plane(cx, cy, zPlane); 29180532da3bf2a83448c6f38c34dbaf32898acea2dBrian Paul#endif 29277df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul array->rgba[ix][RCOMP] = solve_plane_chan(cx, cy, rPlane); 29377df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul array->rgba[ix][GCOMP] = solve_plane_chan(cx, cy, gPlane); 29477df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul array->rgba[ix][BCOMP] = solve_plane_chan(cx, cy, bPlane); 29577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul array->rgba[ix][ACOMP] = solve_plane_chan(cx, cy, aPlane); 296ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul ix--; 297ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul count++; 298ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul coverage = compute_coveragef(pMin, pMax, pMid, ix, iy); 299e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 30010f30eb43835c57c00783390a02d72daf4f78e26Brian Paul 3019e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#if defined(DO_ATTRIBS) 3029e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian /* compute attributes at left-most fragment */ 303b30898f4ab533085d97a33638ad0a1cf9ddb1d67Karl Schultz span.attrStart[FRAG_ATTRIB_WPOS][3] = solve_plane(ix + 1.5F, iy + 0.5F, wPlane); 3049e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ATTRIB_LOOP_BEGIN 3059e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLuint c; 3069e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian for (c = 0; c < 4; c++) { 307b30898f4ab533085d97a33638ad0a1cf9ddb1d67Karl Schultz span.attrStart[attr][c] = solve_plane(ix + 1.5F, iy + 0.5F, attrPlane[attr][c]); 3089e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian } 3099e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian ATTRIB_LOOP_END 3109e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian#endif 3119e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian 312e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger if (startX > ix) { 313e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger n = (GLuint) startX - (GLuint) ix; 314ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul 315e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger left = ix + 1; 316f1e236987829393c81dc86ea19cb49eefe190317Brian Paul 317e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger /* shift all values to the left */ 318e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger /* XXX this is temporary */ 319e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger { 320e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger SWspanarrays *array = span.array; 321e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger GLint j; 322e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger for (j = 0; j < (GLint) n; j++) { 323e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger array->coverage[j] = array->coverage[j + left]; 324e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger COPY_CHAN4(array->rgba[j], array->rgba[j + left]); 325f1e236987829393c81dc86ea19cb49eefe190317Brian Paul#ifdef DO_Z 326e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger array->z[j] = array->z[j + left]; 327f1e236987829393c81dc86ea19cb49eefe190317Brian Paul#endif 328e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger } 329f1e236987829393c81dc86ea19cb49eefe190317Brian Paul } 3302a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul 331e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger span.x = left; 332e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger span.y = iy; 333e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger span.end = n; 334e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger _swrast_write_rgba_span(ctx, &span); 335e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger } 336ee6cf4c6b081dbad7366b80637718d068530d79cBrian Paul } 337e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell } 338e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell} 339e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 340e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 341e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#undef DO_Z 342eca456b63d41700617987ba45a09e8f2168b9577Brian#undef DO_ATTRIBS 343e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#undef DO_OCCLUSION_TEST 344