1c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell/************************************************************************** 2c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * 3c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 4c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * All Rights Reserved. 5c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * 6c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a 7c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * copy of this software and associated documentation files (the 8c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * "Software"), to deal in the Software without restriction, including 9c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * without limitation the rights to use, copy, modify, merge, publish, 10c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * distribute, sub license, and/or sell copies of the Software, and to 11c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * permit persons to whom the Software is furnished to do so, subject to 12c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * the following conditions: 13c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * 14c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * The above copyright notice and this permission notice (including the 15c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * next paragraph) shall be included in all copies or substantial portions 16c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * of the Software. 17c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * 18c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * 26c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell **************************************************************************/ 27c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 28c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell/** 29c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * \brief Primitive rasterization/rendering (points, lines, triangles) 30c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * 31c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * \author Keith Whitwell <keith@tungstengraphics.com> 32c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * \author Brian Paul 33c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 34c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 35c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell#include "sp_context.h" 367925274da323d5a896b557181d4016e0391f026fBrian#include "sp_quad.h" 37ed6f41e2f467f5b9338320a96202c7dfd181422fBrian#include "sp_quad_pipe.h" 38492e61d94f68c3a4a515cab3cf227eed5b426bdfBrian Paul#include "sp_setup.h" 39c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell#include "sp_state.h" 4066ef96f6dc4cd898edb862e45965795fac46caedMichal Krol#include "draw/draw_context.h" 41c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell#include "draw/draw_vertex.h" 42c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell#include "pipe/p_shader_tokens.h" 439935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul#include "util/u_math.h" 444f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_memory.h" 459935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul 46c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 47c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell#define DEBUG_VERTS 0 48c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell#define DEBUG_FRAGS 0 49c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 506756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paul 51c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell/** 52c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Triangle edge info 53c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 54c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwellstruct edge { 55c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell float dx; /**< X(v1) - X(v0), used only during setup */ 56c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell float dy; /**< Y(v1) - Y(v0), used only during setup */ 57c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell float dxdy; /**< dx/dy */ 58c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell float sx, sy; /**< first sample point coord */ 59c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell int lines; /**< number of lines on this edge */ 60c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell}; 61c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 62ebe6160d7c9ccbddd8b1cc4b0e25b3d61c54293dMichal Krol 63b806c3056f17685c8e6214ce946cd282c656107aBrian Paul/** 64b806c3056f17685c8e6214ce946cd282c656107aBrian Paul * Max number of quads (2x2 pixel blocks) to process per batch. 65b806c3056f17685c8e6214ce946cd282c656107aBrian Paul * This can't be arbitrarily increased since we depend on some 32-bit 66b806c3056f17685c8e6214ce946cd282c656107aBrian Paul * bitmasks (two bits per quad). 67b806c3056f17685c8e6214ce946cd282c656107aBrian Paul */ 68a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell#define MAX_QUADS 16 69a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell 70c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 71c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell/** 726756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paul * Triangle setup info. 73c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Also used for line drawing (taking some liberties). 74c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 75c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwellstruct setup_context { 76c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell struct softpipe_context *softpipe; 77c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 78c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* Vertices are just an array of floats making up each attribute in 79c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * turn. Currently fixed at 4 floats, but should change in time. 80c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Codegen will help cope with this. 81c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 82c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const float (*vmax)[4]; 83c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const float (*vmid)[4]; 84c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const float (*vmin)[4]; 85c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const float (*vprovoke)[4]; 86c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 87c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell struct edge ebot; 88c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell struct edge etop; 89c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell struct edge emaj; 90c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 91c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell float oneoverarea; 92a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell int facing; 93a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell 94ca9c413647bf9efb5ed770e3a655bc758075aec7Michal Krol float pixel_offset; 95ca9c413647bf9efb5ed770e3a655bc758075aec7Michal Krol 96a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell struct quad_header quad[MAX_QUADS]; 97a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell struct quad_header *quad_ptrs[MAX_QUADS]; 98a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell unsigned count; 99c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 100c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell struct tgsi_interp_coef coef[PIPE_MAX_SHADER_INPUTS]; 101c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell struct tgsi_interp_coef posCoef; /* For Z, W */ 102c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 103c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell struct { 104c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell int left[2]; /**< [0] = row0, [1] = row1 */ 105c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell int right[2]; 106c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell int y; 107c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } span; 108c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 109c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell#if DEBUG_FRAGS 110c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell uint numFragsEmitted; /**< per primitive */ 111c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell uint numFragsWritten; /**< per primitive */ 112c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell#endif 1138e7326832a7420154fc0d526ac682494db1be160Keith Whitwell 1144ff1274e2312c7d9d8538dc443af500ec3b769cfKeith Whitwell unsigned cull_face; /* which faces cull */ 115f36123323c9d696fec6e54882242cab15247ab0dBrian Paul unsigned nr_vertex_attrs; 116c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell}; 117c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 118c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 119c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 120c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 121c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1228e7326832a7420154fc0d526ac682494db1be160Keith Whitwell 1238e7326832a7420154fc0d526ac682494db1be160Keith Whitwell 124c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell/** 125c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Clip setup->quad against the scissor/surface bounds. 126c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 127c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwellstatic INLINE void 1286756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paulquad_clip(struct setup_context *setup, struct quad_header *quad) 129c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell{ 130c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const struct pipe_scissor_state *cliprect = &setup->softpipe->cliprect; 131c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const int minx = (int) cliprect->minx; 132c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const int maxx = (int) cliprect->maxx; 133c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const int miny = (int) cliprect->miny; 134c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const int maxy = (int) cliprect->maxy; 135c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 13601f9e5120395f88bba8321e8639cac0bb9c85296Michal Krol if (quad->input.x0 >= maxx || 13701f9e5120395f88bba8321e8639cac0bb9c85296Michal Krol quad->input.y0 >= maxy || 13801f9e5120395f88bba8321e8639cac0bb9c85296Michal Krol quad->input.x0 + 1 < minx || 13901f9e5120395f88bba8321e8639cac0bb9c85296Michal Krol quad->input.y0 + 1 < miny) { 140c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* totally clipped */ 14101f9e5120395f88bba8321e8639cac0bb9c85296Michal Krol quad->inout.mask = 0x0; 142c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell return; 143c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 14401f9e5120395f88bba8321e8639cac0bb9c85296Michal Krol if (quad->input.x0 < minx) 14501f9e5120395f88bba8321e8639cac0bb9c85296Michal Krol quad->inout.mask &= (MASK_BOTTOM_RIGHT | MASK_TOP_RIGHT); 14601f9e5120395f88bba8321e8639cac0bb9c85296Michal Krol if (quad->input.y0 < miny) 14701f9e5120395f88bba8321e8639cac0bb9c85296Michal Krol quad->inout.mask &= (MASK_BOTTOM_LEFT | MASK_BOTTOM_RIGHT); 14801f9e5120395f88bba8321e8639cac0bb9c85296Michal Krol if (quad->input.x0 == maxx - 1) 14901f9e5120395f88bba8321e8639cac0bb9c85296Michal Krol quad->inout.mask &= (MASK_BOTTOM_LEFT | MASK_TOP_LEFT); 15001f9e5120395f88bba8321e8639cac0bb9c85296Michal Krol if (quad->input.y0 == maxy - 1) 15101f9e5120395f88bba8321e8639cac0bb9c85296Michal Krol quad->inout.mask &= (MASK_TOP_LEFT | MASK_TOP_RIGHT); 152c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell} 153c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 154c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 155c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell/** 156c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Emit a quad (pass to next stage) with clipping. 157c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 158c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwellstatic INLINE void 1596756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paulclip_emit_quad(struct setup_context *setup, struct quad_header *quad) 160c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell{ 161ebe6160d7c9ccbddd8b1cc4b0e25b3d61c54293dMichal Krol quad_clip( setup, quad ); 1626153a1c28f118be1a74ffee0e19c16fb83b5cab7Keith Whitwell 16301f9e5120395f88bba8321e8639cac0bb9c85296Michal Krol if (quad->inout.mask) { 164c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell struct softpipe_context *sp = setup->softpipe; 165ebe6160d7c9ccbddd8b1cc4b0e25b3d61c54293dMichal Krol 166098aa5f9abcda3fff1a40666cc8f150f046d8867Brian Paul#if DEBUG_FRAGS 167098aa5f9abcda3fff1a40666cc8f150f046d8867Brian Paul setup->numFragsEmitted += util_bitcount(quad->inout.mask); 168098aa5f9abcda3fff1a40666cc8f150f046d8867Brian Paul#endif 169098aa5f9abcda3fff1a40666cc8f150f046d8867Brian Paul 170ab9fb5167023a26566b53e98f206dd73a18000f3Keith Whitwell sp->quad.first->run( sp->quad.first, &quad, 1 ); 171c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 172c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell} 173c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 174ebe6160d7c9ccbddd8b1cc4b0e25b3d61c54293dMichal Krol 175c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 176c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell/** 177c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Given an X or Y coordinate, return the block/quad coordinate that it 178c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * belongs to. 179c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 1806756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paulstatic INLINE int 1816756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paulblock(int x) 182c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell{ 183a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell return x & ~(2-1); 184a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell} 185a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell 1866756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paul 1876756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paulstatic INLINE int 1886756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paulblock_x(int x) 189a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell{ 190a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell return x & ~(16-1); 191c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell} 192c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 193c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 194c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell/** 195c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Render a horizontal span of quads 196c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 1976756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paulstatic void 1986756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paulflush_spans(struct setup_context *setup) 199c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell{ 200b806c3056f17685c8e6214ce946cd282c656107aBrian Paul const int step = MAX_QUADS; 2016807b4f6b1fa6ef0412714622ff16fe9d1487a8eBrian const int xleft0 = setup->span.left[0]; 2026807b4f6b1fa6ef0412714622ff16fe9d1487a8eBrian const int xleft1 = setup->span.left[1]; 2036807b4f6b1fa6ef0412714622ff16fe9d1487a8eBrian const int xright0 = setup->span.right[0]; 2046807b4f6b1fa6ef0412714622ff16fe9d1487a8eBrian const int xright1 = setup->span.right[1]; 205a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell struct quad_stage *pipe = setup->softpipe->quad.first; 206a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell 20746b5ae71697fd04de103d628d30501fa1a4e59adBrian Paul const int minleft = block_x(MIN2(xleft0, xleft1)); 20846b5ae71697fd04de103d628d30501fa1a4e59adBrian Paul const int maxright = MAX2(xright0, xright1); 209c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell int x; 210c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 21146b5ae71697fd04de103d628d30501fa1a4e59adBrian Paul /* process quads in horizontal chunks of 16 */ 2120ed99f45529178c77e47838f226231ea1bc9b918Keith Whitwell for (x = minleft; x < maxright; x += step) { 2130ed99f45529178c77e47838f226231ea1bc9b918Keith Whitwell unsigned skip_left0 = CLAMP(xleft0 - x, 0, step); 2140ed99f45529178c77e47838f226231ea1bc9b918Keith Whitwell unsigned skip_left1 = CLAMP(xleft1 - x, 0, step); 2150ed99f45529178c77e47838f226231ea1bc9b918Keith Whitwell unsigned skip_right0 = CLAMP(x + step - xright0, 0, step); 2160ed99f45529178c77e47838f226231ea1bc9b918Keith Whitwell unsigned skip_right1 = CLAMP(x + step - xright1, 0, step); 2170ed99f45529178c77e47838f226231ea1bc9b918Keith Whitwell unsigned lx = x; 218a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell unsigned q = 0; 219a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell 2200ed99f45529178c77e47838f226231ea1bc9b918Keith Whitwell unsigned skipmask_left0 = (1U << skip_left0) - 1U; 2210ed99f45529178c77e47838f226231ea1bc9b918Keith Whitwell unsigned skipmask_left1 = (1U << skip_left1) - 1U; 2220ed99f45529178c77e47838f226231ea1bc9b918Keith Whitwell 2230ed99f45529178c77e47838f226231ea1bc9b918Keith Whitwell /* These calculations fail when step == 32 and skip_right == 0. 2240ed99f45529178c77e47838f226231ea1bc9b918Keith Whitwell */ 2250ed99f45529178c77e47838f226231ea1bc9b918Keith Whitwell unsigned skipmask_right0 = ~0U << (unsigned)(step - skip_right0); 2260ed99f45529178c77e47838f226231ea1bc9b918Keith Whitwell unsigned skipmask_right1 = ~0U << (unsigned)(step - skip_right1); 2270ed99f45529178c77e47838f226231ea1bc9b918Keith Whitwell 2280ed99f45529178c77e47838f226231ea1bc9b918Keith Whitwell unsigned mask0 = ~skipmask_left0 & ~skipmask_right0; 2290ed99f45529178c77e47838f226231ea1bc9b918Keith Whitwell unsigned mask1 = ~skipmask_left1 & ~skipmask_right1; 2300ed99f45529178c77e47838f226231ea1bc9b918Keith Whitwell 231a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell if (mask0 | mask1) { 232a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell do { 233a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell unsigned quadmask = (mask0 & 3) | ((mask1 & 3) << 2); 234a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell if (quadmask) { 235a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad[q].input.x0 = lx; 236a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad[q].input.y0 = setup->span.y; 237207764894b6d565568bc46722e4c239d839a62fcKeith Whitwell setup->quad[q].input.facing = setup->facing; 238a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad[q].inout.mask = quadmask; 239a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad_ptrs[q] = &setup->quad[q]; 240a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell q++; 241098aa5f9abcda3fff1a40666cc8f150f046d8867Brian Paul#if DEBUG_FRAGS 242098aa5f9abcda3fff1a40666cc8f150f046d8867Brian Paul setup->numFragsEmitted += util_bitcount(quadmask); 243098aa5f9abcda3fff1a40666cc8f150f046d8867Brian Paul#endif 244a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell } 245a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell mask0 >>= 2; 246a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell mask1 >>= 2; 247a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell lx += 2; 248a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell } while (mask0 | mask1); 249a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell 250a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell pipe->run( pipe, setup->quad_ptrs, q ); 2510ed99f45529178c77e47838f226231ea1bc9b918Keith Whitwell } 252c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 253c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 25473e7356385a703c214b35fbb29aaf3108764f033Keith Whitwell 255c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->span.y = 0; 256c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->span.right[0] = 0; 257c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->span.right[1] = 0; 2580ed99f45529178c77e47838f226231ea1bc9b918Keith Whitwell setup->span.left[0] = 1000000; /* greater than right[0] */ 2590ed99f45529178c77e47838f226231ea1bc9b918Keith Whitwell setup->span.left[1] = 1000000; /* greater than right[1] */ 260c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell} 261c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 2626807b4f6b1fa6ef0412714622ff16fe9d1487a8eBrian 263c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell#if DEBUG_VERTS 2646756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paulstatic void 2656756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paulprint_vertex(const struct setup_context *setup, 2666756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paul const float (*v)[4]) 267c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell{ 268c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell int i; 269f36123323c9d696fec6e54882242cab15247ab0dBrian Paul debug_printf(" Vertex: (%p)\n", (void *) v); 270f36123323c9d696fec6e54882242cab15247ab0dBrian Paul for (i = 0; i < setup->nr_vertex_attrs; i++) { 271b1ff7dac537947d412bf423a73e7eacd76f90d84Brian Paul debug_printf(" %d: %f %f %f %f\n", i, 272c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell v[i][0], v[i][1], v[i][2], v[i][3]); 273d0f28b6dd967cd74bafb37e1e203b5934981bed0Brian Paul if (util_is_inf_or_nan(v[i][0])) { 274d0f28b6dd967cd74bafb37e1e203b5934981bed0Brian Paul debug_printf(" NaN!\n"); 275d0f28b6dd967cd74bafb37e1e203b5934981bed0Brian Paul } 276c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 277c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell} 278c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell#endif 279c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 2806756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paul 2810fae7648987d8264f85a9b6b6d7f903bff82a0f0Brian Paul/** 282b86067c61072ef0e6804e7cf0f19a7ea43fc6aecBrian Paul * Sort the vertices from top to bottom order, setting up the triangle 283b86067c61072ef0e6804e7cf0f19a7ea43fc6aecBrian Paul * edge fields (ebot, emaj, etop). 2840fae7648987d8264f85a9b6b6d7f903bff82a0f0Brian Paul * \return FALSE if coords are inf/nan (cull the tri), TRUE otherwise 2850fae7648987d8264f85a9b6b6d7f903bff82a0f0Brian Paul */ 2866756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paulstatic boolean 2876756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paulsetup_sort_vertices(struct setup_context *setup, 2886756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paul float det, 2896756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paul const float (*v0)[4], 2906756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paul const float (*v1)[4], 2916756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paul const float (*v2)[4]) 292c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell{ 293cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul if (setup->softpipe->rasterizer->flatshade_first) 294cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul setup->vprovoke = v0; 295cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul else 296cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul setup->vprovoke = v2; 297c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 298c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* determine bottom to top order of vertices */ 299c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell { 300c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell float y0 = v0[0][1]; 301c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell float y1 = v1[0][1]; 302c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell float y2 = v2[0][1]; 303c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell if (y0 <= y1) { 304c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell if (y1 <= y2) { 305c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* y0<=y1<=y2 */ 306c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->vmin = v0; 307c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->vmid = v1; 308c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->vmax = v2; 309c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 310c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell else if (y2 <= y0) { 311c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* y2<=y0<=y1 */ 312c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->vmin = v2; 313c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->vmid = v0; 314c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->vmax = v1; 315c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 316c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell else { 317c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* y0<=y2<=y1 */ 318c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->vmin = v0; 319c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->vmid = v2; 320c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->vmax = v1; 321c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 322c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 323c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell else { 324c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell if (y0 <= y2) { 325c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* y1<=y0<=y2 */ 326c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->vmin = v1; 327c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->vmid = v0; 328c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->vmax = v2; 329c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 330c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell else if (y2 <= y1) { 331c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* y2<=y1<=y0 */ 332c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->vmin = v2; 333c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->vmid = v1; 334c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->vmax = v0; 335c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 336c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell else { 337c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* y1<=y2<=y0 */ 338c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->vmin = v1; 339c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->vmid = v2; 340c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->vmax = v0; 341c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 342c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 343c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 344c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 345c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->ebot.dx = setup->vmid[0][0] - setup->vmin[0][0]; 346c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->ebot.dy = setup->vmid[0][1] - setup->vmin[0][1]; 347c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->emaj.dx = setup->vmax[0][0] - setup->vmin[0][0]; 348c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->emaj.dy = setup->vmax[0][1] - setup->vmin[0][1]; 349c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->etop.dx = setup->vmax[0][0] - setup->vmid[0][0]; 350c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->etop.dy = setup->vmax[0][1] - setup->vmid[0][1]; 351c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 352c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* 353c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Compute triangle's area. Use 1/area to compute partial 354c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * derivatives of attributes later. 355c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * 356c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * The area will be the same as prim->det, but the sign may be 357c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * different depending on how the vertices get sorted above. 358c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * 359c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * To determine whether the primitive is front or back facing we 360c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * use the prim->det value because its sign is correct. 361c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 362c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell { 363c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const float area = (setup->emaj.dx * setup->ebot.dy - 364c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->ebot.dx * setup->emaj.dy); 365c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 366c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->oneoverarea = 1.0f / area; 3670fae7648987d8264f85a9b6b6d7f903bff82a0f0Brian Paul 368c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* 369c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell debug_printf("%s one-over-area %f area %f det %f\n", 370c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell __FUNCTION__, setup->oneoverarea, area, det ); 371c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 372d0f28b6dd967cd74bafb37e1e203b5934981bed0Brian Paul if (util_is_inf_or_nan(setup->oneoverarea)) 3730fae7648987d8264f85a9b6b6d7f903bff82a0f0Brian Paul return FALSE; 374c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 375c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 376c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* We need to know if this is a front or back-facing triangle for: 377c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * - the GLSL gl_FrontFacing fragment attribute (bool) 378c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * - two-sided stencil test 37910e4ec448e8011e8d446d83fc8bd61c7ba2d74beBrian Paul * 0 = front-facing, 1 = back-facing 380c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 381a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->facing = 3820bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell ((det < 0.0) ^ 3830bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell (setup->softpipe->rasterizer->front_ccw)); 384c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 3854ff1274e2312c7d9d8538dc443af500ec3b769cfKeith Whitwell { 3864ff1274e2312c7d9d8538dc443af500ec3b769cfKeith Whitwell unsigned face = setup->facing == 0 ? PIPE_FACE_FRONT : PIPE_FACE_BACK; 3874ff1274e2312c7d9d8538dc443af500ec3b769cfKeith Whitwell 3884ff1274e2312c7d9d8538dc443af500ec3b769cfKeith Whitwell if (face & setup->cull_face) 3894ff1274e2312c7d9d8538dc443af500ec3b769cfKeith Whitwell return FALSE; 3904ff1274e2312c7d9d8538dc443af500ec3b769cfKeith Whitwell } 3914ff1274e2312c7d9d8538dc443af500ec3b769cfKeith Whitwell 3924ff1274e2312c7d9d8538dc443af500ec3b769cfKeith Whitwell 393ca9c413647bf9efb5ed770e3a655bc758075aec7Michal Krol /* Prepare pixel offset for rasterisation: 394ca9c413647bf9efb5ed770e3a655bc758075aec7Michal Krol * - pixel center (0.5, 0.5) for GL, or 395ca9c413647bf9efb5ed770e3a655bc758075aec7Michal Krol * - assume (0.0, 0.0) for other APIs. 396ca9c413647bf9efb5ed770e3a655bc758075aec7Michal Krol */ 397ca9c413647bf9efb5ed770e3a655bc758075aec7Michal Krol if (setup->softpipe->rasterizer->gl_rasterization_rules) { 398ca9c413647bf9efb5ed770e3a655bc758075aec7Michal Krol setup->pixel_offset = 0.5f; 399ca9c413647bf9efb5ed770e3a655bc758075aec7Michal Krol } else { 400ca9c413647bf9efb5ed770e3a655bc758075aec7Michal Krol setup->pixel_offset = 0.0f; 401ca9c413647bf9efb5ed770e3a655bc758075aec7Michal Krol } 402ca9c413647bf9efb5ed770e3a655bc758075aec7Michal Krol 403c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell return TRUE; 404c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell} 405c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 406c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 4075fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol/* Apply cylindrical wrapping to v0, v1, v2 coordinates, if enabled. 4085fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol * Input coordinates must be in [0, 1] range, otherwise results are undefined. 4095fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol * Some combinations of coordinates produce invalid results, 4105fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol * but this behaviour is acceptable. 4115fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol */ 4125fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krolstatic void 4135fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Kroltri_apply_cylindrical_wrap(float v0, 4145fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol float v1, 4155fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol float v2, 4165fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol uint cylindrical_wrap, 4175fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol float output[3]) 4185fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol{ 4195fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol if (cylindrical_wrap) { 4205fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol float delta; 4215fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol 4225fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol delta = v1 - v0; 4235fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol if (delta > 0.5f) { 4245fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol v0 += 1.0f; 4255fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol } 4265fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol else if (delta < -0.5f) { 4275fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol v1 += 1.0f; 4285fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol } 4295fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol 4305fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol delta = v2 - v1; 4315fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol if (delta > 0.5f) { 4325fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol v1 += 1.0f; 4335fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol } 4345fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol else if (delta < -0.5f) { 4355fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol v2 += 1.0f; 4365fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol } 4375fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol 4385fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol delta = v0 - v2; 4395fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol if (delta > 0.5f) { 4405fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol v2 += 1.0f; 4415fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol } 4425fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol else if (delta < -0.5f) { 4435fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol v0 += 1.0f; 4445fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol } 4455fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol } 4465fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol 4475fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol output[0] = v0; 4485fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol output[1] = v1; 4495fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol output[2] = v2; 4505fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol} 4515fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol 4525fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol 453c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell/** 454c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Compute a0 for a constant-valued coefficient (GL_FLAT shading). 455c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * The value value comes from vertex[slot][i]. 456c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * The result will be put into setup->coef[slot].a0[i]. 457c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * \param slot which attribute slot 458c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * \param i which component of the slot (0..3) 459c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 4606756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paulstatic void 4616756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paulconst_coeff(struct setup_context *setup, 4626756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paul struct tgsi_interp_coef *coef, 4636756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paul uint vertSlot, uint i) 464c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell{ 465c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell assert(i <= 3); 466c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 467c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell coef->dadx[i] = 0; 468c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell coef->dady[i] = 0; 469c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 470c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* need provoking vertex info! 471c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 472c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell coef->a0[i] = setup->vprovoke[vertSlot][i]; 473c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell} 474c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 475c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 476c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell/** 477c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Compute a0, dadx and dady for a linearly interpolated coefficient, 478c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * for a triangle. 4795fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol * v[0], v[1] and v[2] are vmin, vmid and vmax, respectively. 480c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 4815fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krolstatic void 4825fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Kroltri_linear_coeff(struct setup_context *setup, 4835fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol struct tgsi_interp_coef *coef, 4845fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol uint i, 4855fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol const float v[3]) 486c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell{ 4875fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol float botda = v[1] - v[0]; 4885fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol float majda = v[2] - v[0]; 48900bd85e57437d91e227fa768527bc22e3814de1eMichal Krol float a = setup->ebot.dy * majda - botda * setup->emaj.dy; 49000bd85e57437d91e227fa768527bc22e3814de1eMichal Krol float b = setup->emaj.dx * botda - majda * setup->ebot.dx; 49100bd85e57437d91e227fa768527bc22e3814de1eMichal Krol float dadx = a * setup->oneoverarea; 49200bd85e57437d91e227fa768527bc22e3814de1eMichal Krol float dady = b * setup->oneoverarea; 493c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 494c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell assert(i <= 3); 495c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 496c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell coef->dadx[i] = dadx; 497c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell coef->dady[i] = dady; 498c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 499c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* calculate a0 as the value which would be sampled for the 500c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * fragment at (0,0), taking into account that we want to sample at 501ca9c413647bf9efb5ed770e3a655bc758075aec7Michal Krol * pixel centers, in other words (pixel_offset, pixel_offset). 502c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * 503c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * this is neat but unfortunately not a good way to do things for 504c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * triangles with very large values of dadx or dady as it will 505c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * result in the subtraction and re-addition from a0 of a very 506c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * large number, which means we'll end up loosing a lot of the 507c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * fractional bits and precision from a0. the way to fix this is 508c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * to define a0 as the sample at a pixel center somewhere near vmin 509c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * instead - i'll switch to this later. 510c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 5115fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol coef->a0[i] = (v[0] - 512ca9c413647bf9efb5ed770e3a655bc758075aec7Michal Krol (dadx * (setup->vmin[0][0] - setup->pixel_offset) + 513ca9c413647bf9efb5ed770e3a655bc758075aec7Michal Krol dady * (setup->vmin[0][1] - setup->pixel_offset))); 514c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 515c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* 516c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell debug_printf("attr[%d].%c: %f dx:%f dy:%f\n", 517c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell slot, "xyzw"[i], 518c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->coef[slot].a0[i], 519c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->coef[slot].dadx[i], 520c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->coef[slot].dady[i]); 521c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 522c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell} 523c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 524c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 525c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell/** 526c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Compute a0, dadx and dady for a perspective-corrected interpolant, 527c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * for a triangle. 528c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * We basically multiply the vertex value by 1/w before computing 529c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * the plane coefficients (a0, dadx, dady). 530c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Later, when we compute the value at a particular fragment position we'll 531c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * divide the interpolated value by the interpolated W at that fragment. 5325fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol * v[0], v[1] and v[2] are vmin, vmid and vmax, respectively. 533c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 5345fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krolstatic void 5355fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Kroltri_persp_coeff(struct setup_context *setup, 5365fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol struct tgsi_interp_coef *coef, 5375fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol uint i, 5385fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol const float v[3]) 539c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell{ 540c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* premultiply by 1/w (v[0][3] is always W): 541c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 5425fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol float mina = v[0] * setup->vmin[0][3]; 5435fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol float mida = v[1] * setup->vmid[0][3]; 5445fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol float maxa = v[2] * setup->vmax[0][3]; 545c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell float botda = mida - mina; 546c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell float majda = maxa - mina; 547c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell float a = setup->ebot.dy * majda - botda * setup->emaj.dy; 548c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell float b = setup->emaj.dx * botda - majda * setup->ebot.dx; 549c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell float dadx = a * setup->oneoverarea; 550c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell float dady = b * setup->oneoverarea; 551c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 552c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* 553c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell debug_printf("tri persp %d,%d: %f %f %f\n", vertSlot, i, 554c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->vmin[vertSlot][i], 555c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->vmid[vertSlot][i], 556c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->vmax[vertSlot][i] 557c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell ); 558c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 559c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell assert(i <= 3); 560c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 561c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell coef->dadx[i] = dadx; 562c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell coef->dady[i] = dady; 563c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell coef->a0[i] = (mina - 564ca9c413647bf9efb5ed770e3a655bc758075aec7Michal Krol (dadx * (setup->vmin[0][0] - setup->pixel_offset) + 565ca9c413647bf9efb5ed770e3a655bc758075aec7Michal Krol dady * (setup->vmin[0][1] - setup->pixel_offset))); 566c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell} 567c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 568c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 569c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell/** 570c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Special coefficient setup for gl_FragCoord. 571b2299d80b4278b8b6553d4e4da4d40d37881d76eLuca Barbieri * X and Y are trivial, though Y may have to be inverted for OpenGL. 572c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Z and W are copied from posCoef which should have already been computed. 573c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * We could do a bit less work if we'd examine gl_FragCoord's swizzle mask. 574c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 575c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwellstatic void 576c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwellsetup_fragcoord_coeff(struct setup_context *setup, uint slot) 577c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell{ 578c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul const struct tgsi_shader_info *fsInfo = &setup->softpipe->fs_variant->info; 579c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul 580c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /*X*/ 581c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul setup->coef[slot].a0[0] = fsInfo->pixel_center_integer ? 0.0 : 0.5; 582c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->coef[slot].dadx[0] = 1.0; 583c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->coef[slot].dady[0] = 0.0; 584c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /*Y*/ 585b2299d80b4278b8b6553d4e4da4d40d37881d76eLuca Barbieri setup->coef[slot].a0[1] = 586c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul (fsInfo->origin_lower_left ? setup->softpipe->framebuffer.height-1 : 0) 587c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul + (fsInfo->pixel_center_integer ? 0.0 : 0.5); 588c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->coef[slot].dadx[1] = 0.0; 589c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul setup->coef[slot].dady[1] = fsInfo->origin_lower_left ? -1.0 : 1.0; 590c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /*Z*/ 591c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->coef[slot].a0[2] = setup->posCoef.a0[2]; 592c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->coef[slot].dadx[2] = setup->posCoef.dadx[2]; 593c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->coef[slot].dady[2] = setup->posCoef.dady[2]; 594c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /*W*/ 595c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->coef[slot].a0[3] = setup->posCoef.a0[3]; 596c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->coef[slot].dadx[3] = setup->posCoef.dadx[3]; 597c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->coef[slot].dady[3] = setup->posCoef.dady[3]; 598c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell} 599c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 600c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 601c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 602c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell/** 603c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Compute the setup->coef[] array dadx, dady, a0 values. 604c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Must be called after setup->vmin,vmid,vmax,vprovoke are initialized. 605c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 6066756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paulstatic void 6076756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paulsetup_tri_coefficients(struct setup_context *setup) 608c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell{ 609c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell struct softpipe_context *softpipe = setup->softpipe; 610c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul const struct tgsi_shader_info *fsInfo = &setup->softpipe->fs_variant->info; 611c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe); 612c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell uint fragSlot; 6135fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol float v[3]; 614c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 615c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* z and w are done by linear interpolation: 616c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 6175fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol v[0] = setup->vmin[0][2]; 6185fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol v[1] = setup->vmid[0][2]; 6195fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol v[2] = setup->vmax[0][2]; 6205fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol tri_linear_coeff(setup, &setup->posCoef, 2, v); 6215fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol 6225fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol v[0] = setup->vmin[0][3]; 6235fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol v[1] = setup->vmid[0][3]; 6245fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol v[2] = setup->vmax[0][3]; 6255fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol tri_linear_coeff(setup, &setup->posCoef, 3, v); 626c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 627c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* setup interpolation for all the remaining attributes: 628c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 629c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul for (fragSlot = 0; fragSlot < fsInfo->num_inputs; fragSlot++) { 63053d4706c6c0922160f310834daaec5718ff1c511Keith Whitwell const uint vertSlot = vinfo->attrib[fragSlot].src_index; 631c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell uint j; 632c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 63353d4706c6c0922160f310834daaec5718ff1c511Keith Whitwell switch (vinfo->attrib[fragSlot].interp_mode) { 634c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell case INTERP_CONSTANT: 6356b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard for (j = 0; j < TGSI_NUM_CHANNELS; j++) 636c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); 637c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell break; 638c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell case INTERP_LINEAR: 6396b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard for (j = 0; j < TGSI_NUM_CHANNELS; j++) { 6405fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol tri_apply_cylindrical_wrap(setup->vmin[vertSlot][j], 6415fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol setup->vmid[vertSlot][j], 6425fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol setup->vmax[vertSlot][j], 643c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul fsInfo->input_cylindrical_wrap[fragSlot] & (1 << j), 6445fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol v); 6455fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol tri_linear_coeff(setup, &setup->coef[fragSlot], j, v); 6465fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol } 647c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell break; 648c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell case INTERP_PERSPECTIVE: 6496b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard for (j = 0; j < TGSI_NUM_CHANNELS; j++) { 6505fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol tri_apply_cylindrical_wrap(setup->vmin[vertSlot][j], 6515fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol setup->vmid[vertSlot][j], 6525fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol setup->vmax[vertSlot][j], 653c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul fsInfo->input_cylindrical_wrap[fragSlot] & (1 << j), 6545fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol v); 6555fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol tri_persp_coeff(setup, &setup->coef[fragSlot], j, v); 6565fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol } 657c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell break; 658c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell case INTERP_POS: 659c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup_fragcoord_coeff(setup, fragSlot); 660c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell break; 661c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell default: 662c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell assert(0); 663c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 664c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 665c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul if (fsInfo->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { 66610e4ec448e8011e8d446d83fc8bd61c7ba2d74beBrian Paul /* convert 0 to 1.0 and 1 to -1.0 */ 66710e4ec448e8011e8d446d83fc8bd61c7ba2d74beBrian Paul setup->coef[fragSlot].a0[0] = setup->facing * -2.0f + 1.0f; 6681c04731b8721850b6abb12a43a3eec616b850e86Zack Rusin setup->coef[fragSlot].dadx[0] = 0.0; 6691c04731b8721850b6abb12a43a3eec616b850e86Zack Rusin setup->coef[fragSlot].dady[0] = 0.0; 670c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 671c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 672c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell} 673c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 674c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 6756756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paulstatic void 6766756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paulsetup_tri_edges(struct setup_context *setup) 677c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell{ 678ca9c413647bf9efb5ed770e3a655bc758075aec7Michal Krol float vmin_x = setup->vmin[0][0] + setup->pixel_offset; 679ca9c413647bf9efb5ed770e3a655bc758075aec7Michal Krol float vmid_x = setup->vmid[0][0] + setup->pixel_offset; 680c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 681ca9c413647bf9efb5ed770e3a655bc758075aec7Michal Krol float vmin_y = setup->vmin[0][1] - setup->pixel_offset; 682ca9c413647bf9efb5ed770e3a655bc758075aec7Michal Krol float vmid_y = setup->vmid[0][1] - setup->pixel_offset; 683ca9c413647bf9efb5ed770e3a655bc758075aec7Michal Krol float vmax_y = setup->vmax[0][1] - setup->pixel_offset; 684c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 6859935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul setup->emaj.sy = ceilf(vmin_y); 6869935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul setup->emaj.lines = (int) ceilf(vmax_y - setup->emaj.sy); 687b3a68cdc6f4bf2c006aa01f8980536e8e520d62aArpad Borsos setup->emaj.dxdy = setup->emaj.dy ? setup->emaj.dx / setup->emaj.dy : .0f; 688c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->emaj.sx = vmin_x + (setup->emaj.sy - vmin_y) * setup->emaj.dxdy; 689c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 6909935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul setup->etop.sy = ceilf(vmid_y); 6919935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul setup->etop.lines = (int) ceilf(vmax_y - setup->etop.sy); 692b3a68cdc6f4bf2c006aa01f8980536e8e520d62aArpad Borsos setup->etop.dxdy = setup->etop.dy ? setup->etop.dx / setup->etop.dy : .0f; 693c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->etop.sx = vmid_x + (setup->etop.sy - vmid_y) * setup->etop.dxdy; 694c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 6959935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul setup->ebot.sy = ceilf(vmin_y); 6969935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul setup->ebot.lines = (int) ceilf(vmid_y - setup->ebot.sy); 697b3a68cdc6f4bf2c006aa01f8980536e8e520d62aArpad Borsos setup->ebot.dxdy = setup->ebot.dy ? setup->ebot.dx / setup->ebot.dy : .0f; 698c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->ebot.sx = vmin_x + (setup->ebot.sy - vmin_y) * setup->ebot.dxdy; 699c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell} 700c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 701c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 702c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell/** 703c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Render the upper or lower half of a triangle. 704c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Scissoring/cliprect is applied here too. 705c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 7066756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paulstatic void 7076756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paulsubtriangle(struct setup_context *setup, 7086756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paul struct edge *eleft, 7096756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paul struct edge *eright, 7106756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paul int lines) 711c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell{ 712c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const struct pipe_scissor_state *cliprect = &setup->softpipe->cliprect; 713c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const int minx = (int) cliprect->minx; 714c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const int maxx = (int) cliprect->maxx; 715c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const int miny = (int) cliprect->miny; 716c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const int maxy = (int) cliprect->maxy; 717c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell int y, start_y, finish_y; 718c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell int sy = (int)eleft->sy; 719c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 720c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell assert((int)eleft->sy == (int) eright->sy); 7214272c01fbfd42833e4e0937bed84e45fe5da52b9José Fonseca assert(lines >= 0); 722c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 723c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* clip top/bottom */ 724c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell start_y = sy; 725c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell if (start_y < miny) 726c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell start_y = miny; 727c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 7280ed99f45529178c77e47838f226231ea1bc9b918Keith Whitwell finish_y = sy + lines; 729c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell if (finish_y > maxy) 730c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell finish_y = maxy; 731c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 732c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell start_y -= sy; 733c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell finish_y -= sy; 734c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 735c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* 736c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell debug_printf("%s %d %d\n", __FUNCTION__, start_y, finish_y); 737c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 738c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 739c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell for (y = start_y; y < finish_y; y++) { 740c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 741c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* avoid accumulating adds as floats don't have the precision to 742c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * accurately iterate large triangle edges that way. luckily we 743c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * can just multiply these days. 744c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * 745c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * this is all drowned out by the attribute interpolation anyway. 746c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 747c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell int left = (int)(eleft->sx + y * eleft->dxdy); 748c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell int right = (int)(eright->sx + y * eright->dxdy); 749c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 750c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* clip left/right */ 751c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell if (left < minx) 752c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell left = minx; 753c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell if (right > maxx) 754c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell right = maxx; 755c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 756c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell if (left < right) { 757c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell int _y = sy + y; 758c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell if (block(_y) != setup->span.y) { 759c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell flush_spans(setup); 760c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->span.y = block(_y); 761c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 762c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 763c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->span.left[_y&1] = left; 764c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->span.right[_y&1] = right; 765c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 766c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 767c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 768c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 769c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* save the values so that emaj can be restarted: 770c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 771c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell eleft->sx += lines * eleft->dxdy; 772c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell eright->sx += lines * eright->dxdy; 773c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell eleft->sy += lines; 774c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell eright->sy += lines; 775c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell} 776c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 777c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 778c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell/** 779871d39ec8c168fa58d8758013e99da63fa58111dKeith Whitwell * Recalculate prim's determinant. This is needed as we don't have 780871d39ec8c168fa58d8758013e99da63fa58111dKeith Whitwell * get this information through the vbuf_render interface & we must 781871d39ec8c168fa58d8758013e99da63fa58111dKeith Whitwell * calculate it here. 782871d39ec8c168fa58d8758013e99da63fa58111dKeith Whitwell */ 783871d39ec8c168fa58d8758013e99da63fa58111dKeith Whitwellstatic float 7846756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paulcalc_det(const float (*v0)[4], 7856756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paul const float (*v1)[4], 7866756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paul const float (*v2)[4]) 787871d39ec8c168fa58d8758013e99da63fa58111dKeith Whitwell{ 788871d39ec8c168fa58d8758013e99da63fa58111dKeith Whitwell /* edge vectors e = v0 - v2, f = v1 - v2 */ 789871d39ec8c168fa58d8758013e99da63fa58111dKeith Whitwell const float ex = v0[0][0] - v2[0][0]; 790871d39ec8c168fa58d8758013e99da63fa58111dKeith Whitwell const float ey = v0[0][1] - v2[0][1]; 791871d39ec8c168fa58d8758013e99da63fa58111dKeith Whitwell const float fx = v1[0][0] - v2[0][0]; 792871d39ec8c168fa58d8758013e99da63fa58111dKeith Whitwell const float fy = v1[0][1] - v2[0][1]; 793871d39ec8c168fa58d8758013e99da63fa58111dKeith Whitwell 794871d39ec8c168fa58d8758013e99da63fa58111dKeith Whitwell /* det = cross(e,f).z */ 795871d39ec8c168fa58d8758013e99da63fa58111dKeith Whitwell return ex * fy - ey * fx; 796871d39ec8c168fa58d8758013e99da63fa58111dKeith Whitwell} 797871d39ec8c168fa58d8758013e99da63fa58111dKeith Whitwell 798871d39ec8c168fa58d8758013e99da63fa58111dKeith Whitwell 799871d39ec8c168fa58d8758013e99da63fa58111dKeith Whitwell/** 800c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Do setup for triangle rasterization, then render the triangle. 801c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 8026756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paulvoid 8036756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paulsp_setup_tri(struct setup_context *setup, 8046756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paul const float (*v0)[4], 8056756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paul const float (*v1)[4], 8066756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paul const float (*v2)[4]) 807c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell{ 8089002cdb48e65c063ea00e1cb4917d432b22ae0adKeith Whitwell float det; 809871d39ec8c168fa58d8758013e99da63fa58111dKeith Whitwell 81076d39f0c19ee0673b65d6ad09ab338c8b750251aBrian Paul#if DEBUG_VERTS 81176d39f0c19ee0673b65d6ad09ab338c8b750251aBrian Paul debug_printf("Setup triangle:\n"); 81276d39f0c19ee0673b65d6ad09ab338c8b750251aBrian Paul print_vertex(setup, v0); 81376d39f0c19ee0673b65d6ad09ab338c8b750251aBrian Paul print_vertex(setup, v1); 81476d39f0c19ee0673b65d6ad09ab338c8b750251aBrian Paul print_vertex(setup, v2); 81576d39f0c19ee0673b65d6ad09ab338c8b750251aBrian Paul#endif 81676d39f0c19ee0673b65d6ad09ab338c8b750251aBrian Paul 817ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie if (setup->softpipe->no_rast || setup->softpipe->rasterizer->rasterizer_discard) 818a5b87f249ef79b1a8d8b9dbe72879b7ac9eb133cKeith Whitwell return; 8199002cdb48e65c063ea00e1cb4917d432b22ae0adKeith Whitwell 8209002cdb48e65c063ea00e1cb4917d432b22ae0adKeith Whitwell det = calc_det(v0, v1, v2); 821c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* 822c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell debug_printf("%s\n", __FUNCTION__ ); 823c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 824c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 825c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell#if DEBUG_FRAGS 826c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->numFragsEmitted = 0; 827c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->numFragsWritten = 0; 828c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell#endif 829c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 8300fae7648987d8264f85a9b6b6d7f903bff82a0f0Brian Paul if (!setup_sort_vertices( setup, det, v0, v1, v2 )) 8310fae7648987d8264f85a9b6b6d7f903bff82a0f0Brian Paul return; 8324ff1274e2312c7d9d8538dc443af500ec3b769cfKeith Whitwell 833c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup_tri_coefficients( setup ); 834c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup_tri_edges( setup ); 835c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 836a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell assert(setup->softpipe->reduced_prim == PIPE_PRIM_TRIANGLES); 837c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 838c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->span.y = 0; 839c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->span.right[0] = 0; 840c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->span.right[1] = 0; 841c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* setup->span.z_mode = tri_z_mode( setup->ctx ); */ 842c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 843c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* init_constant_attribs( setup ); */ 844c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 845c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell if (setup->oneoverarea < 0.0) { 846c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* emaj on left: 847c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 848c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell subtriangle( setup, &setup->emaj, &setup->ebot, setup->ebot.lines ); 849c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell subtriangle( setup, &setup->emaj, &setup->etop, setup->etop.lines ); 850c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 851c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell else { 852c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* emaj on right: 853c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 854c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell subtriangle( setup, &setup->ebot, &setup->emaj, setup->ebot.lines ); 855c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell subtriangle( setup, &setup->etop, &setup->emaj, setup->etop.lines ); 856c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 857c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 858c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell flush_spans( setup ); 859c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 860c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell#if DEBUG_FRAGS 861c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell printf("Tri: %u frags emitted, %u written\n", 862c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->numFragsEmitted, 863c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->numFragsWritten); 864c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell#endif 865c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell} 866c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 867c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 8685fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol/* Apply cylindrical wrapping to v0, v1 coordinates, if enabled. 8695fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol * Input coordinates must be in [0, 1] range, otherwise results are undefined. 8705fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol */ 8715fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krolstatic void 8725fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krolline_apply_cylindrical_wrap(float v0, 8735fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol float v1, 8745fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol uint cylindrical_wrap, 8755fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol float output[2]) 8765fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol{ 8775fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol if (cylindrical_wrap) { 8785fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol float delta; 8795fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol 8805fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol delta = v1 - v0; 8815fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol if (delta > 0.5f) { 8825fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol v0 += 1.0f; 8835fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol } 8845fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol else if (delta < -0.5f) { 8855fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol v1 += 1.0f; 8865fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol } 8875fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol } 8885fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol 8895fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol output[0] = v0; 8905fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol output[1] = v1; 8915fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol} 8925fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol 893c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 894c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell/** 895c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Compute a0, dadx and dady for a linearly interpolated coefficient, 896c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * for a line. 8975fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol * v[0] and v[1] are vmin and vmax, respectively. 898c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 899c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwellstatic void 900492e61d94f68c3a4a515cab3cf227eed5b426bdfBrian Paulline_linear_coeff(const struct setup_context *setup, 901c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell struct tgsi_interp_coef *coef, 9025fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol uint i, 9035fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol const float v[2]) 904c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell{ 9055fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol const float da = v[1] - v[0]; 906c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const float dadx = da * setup->emaj.dx * setup->oneoverarea; 907c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const float dady = da * setup->emaj.dy * setup->oneoverarea; 908c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell coef->dadx[i] = dadx; 909c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell coef->dady[i] = dady; 9105fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol coef->a0[i] = (v[0] - 911ca9c413647bf9efb5ed770e3a655bc758075aec7Michal Krol (dadx * (setup->vmin[0][0] - setup->pixel_offset) + 912ca9c413647bf9efb5ed770e3a655bc758075aec7Michal Krol dady * (setup->vmin[0][1] - setup->pixel_offset))); 913c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell} 914c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 915c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 916c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell/** 917c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Compute a0, dadx and dady for a perspective-corrected interpolant, 918c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * for a line. 9195fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol * v[0] and v[1] are vmin and vmax, respectively. 920c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 921c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwellstatic void 922492e61d94f68c3a4a515cab3cf227eed5b426bdfBrian Paulline_persp_coeff(const struct setup_context *setup, 923492e61d94f68c3a4a515cab3cf227eed5b426bdfBrian Paul struct tgsi_interp_coef *coef, 9245fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol uint i, 9255fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol const float v[2]) 926c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell{ 9275fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol const float a0 = v[0] * setup->vmin[0][3]; 9285fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol const float a1 = v[1] * setup->vmax[0][3]; 929c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const float da = a1 - a0; 930c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const float dadx = da * setup->emaj.dx * setup->oneoverarea; 931c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const float dady = da * setup->emaj.dy * setup->oneoverarea; 932c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell coef->dadx[i] = dadx; 933c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell coef->dady[i] = dady; 934a1a441179bacdd33e83a48651c7a7a2cc4a8a665Brian Paul coef->a0[i] = (a0 - 935ca9c413647bf9efb5ed770e3a655bc758075aec7Michal Krol (dadx * (setup->vmin[0][0] - setup->pixel_offset) + 936ca9c413647bf9efb5ed770e3a655bc758075aec7Michal Krol dady * (setup->vmin[0][1] - setup->pixel_offset))); 937c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell} 938c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 939c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 940c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell/** 941c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Compute the setup->coef[] array dadx, dady, a0 values. 942c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Must be called after setup->vmin,vmax are initialized. 943c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 9446756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paulstatic boolean 945c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwellsetup_line_coefficients(struct setup_context *setup, 946c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const float (*v0)[4], 947c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const float (*v1)[4]) 948c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell{ 949c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell struct softpipe_context *softpipe = setup->softpipe; 950c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul const struct tgsi_shader_info *fsInfo = &setup->softpipe->fs_variant->info; 951c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe); 952c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell uint fragSlot; 9530fae7648987d8264f85a9b6b6d7f903bff82a0f0Brian Paul float area; 9545fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol float v[2]; 955c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 956c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* use setup->vmin, vmax to point to vertices */ 9576f26f8c750d087211e266e9a228d4c4db473c31fBrian Paul if (softpipe->rasterizer->flatshade_first) 9586f26f8c750d087211e266e9a228d4c4db473c31fBrian Paul setup->vprovoke = v0; 9596f26f8c750d087211e266e9a228d4c4db473c31fBrian Paul else 9606f26f8c750d087211e266e9a228d4c4db473c31fBrian Paul setup->vprovoke = v1; 961c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->vmin = v0; 962c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->vmax = v1; 963c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 964c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->emaj.dx = setup->vmax[0][0] - setup->vmin[0][0]; 965c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->emaj.dy = setup->vmax[0][1] - setup->vmin[0][1]; 9660fae7648987d8264f85a9b6b6d7f903bff82a0f0Brian Paul 9670fae7648987d8264f85a9b6b6d7f903bff82a0f0Brian Paul /* NOTE: this is not really area but something proportional to it */ 9680fae7648987d8264f85a9b6b6d7f903bff82a0f0Brian Paul area = setup->emaj.dx * setup->emaj.dx + setup->emaj.dy * setup->emaj.dy; 969d0f28b6dd967cd74bafb37e1e203b5934981bed0Brian Paul if (area == 0.0f || util_is_inf_or_nan(area)) 9700fae7648987d8264f85a9b6b6d7f903bff82a0f0Brian Paul return FALSE; 9710fae7648987d8264f85a9b6b6d7f903bff82a0f0Brian Paul setup->oneoverarea = 1.0f / area; 972c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 973c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* z and w are done by linear interpolation: 974c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 9755fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol v[0] = setup->vmin[0][2]; 9765fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol v[1] = setup->vmax[0][2]; 9775fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol line_linear_coeff(setup, &setup->posCoef, 2, v); 9785fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol 9795fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol v[0] = setup->vmin[0][3]; 9805fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol v[1] = setup->vmax[0][3]; 9815fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol line_linear_coeff(setup, &setup->posCoef, 3, v); 982c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 983c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* setup interpolation for all the remaining attributes: 984c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 985c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul for (fragSlot = 0; fragSlot < fsInfo->num_inputs; fragSlot++) { 98653d4706c6c0922160f310834daaec5718ff1c511Keith Whitwell const uint vertSlot = vinfo->attrib[fragSlot].src_index; 987c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell uint j; 988c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 98953d4706c6c0922160f310834daaec5718ff1c511Keith Whitwell switch (vinfo->attrib[fragSlot].interp_mode) { 990c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell case INTERP_CONSTANT: 9916b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard for (j = 0; j < TGSI_NUM_CHANNELS; j++) 992c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); 993c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell break; 994c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell case INTERP_LINEAR: 9956b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard for (j = 0; j < TGSI_NUM_CHANNELS; j++) { 9965fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol line_apply_cylindrical_wrap(setup->vmin[vertSlot][j], 9975fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol setup->vmax[vertSlot][j], 998c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul fsInfo->input_cylindrical_wrap[fragSlot] & (1 << j), 9995fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol v); 10005fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol line_linear_coeff(setup, &setup->coef[fragSlot], j, v); 10015fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol } 1002c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell break; 1003c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell case INTERP_PERSPECTIVE: 10046b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard for (j = 0; j < TGSI_NUM_CHANNELS; j++) { 10055fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol line_apply_cylindrical_wrap(setup->vmin[vertSlot][j], 10065fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol setup->vmax[vertSlot][j], 1007c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul fsInfo->input_cylindrical_wrap[fragSlot] & (1 << j), 10085fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol v); 10095fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol line_persp_coeff(setup, &setup->coef[fragSlot], j, v); 10105fbb62f761220a81ce7a0093bfe16ea5ea063d44Michal Krol } 1011c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell break; 1012c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell case INTERP_POS: 1013c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup_fragcoord_coeff(setup, fragSlot); 1014c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell break; 1015c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell default: 1016c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell assert(0); 1017c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1018c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1019c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul if (fsInfo->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { 102010e4ec448e8011e8d446d83fc8bd61c7ba2d74beBrian Paul /* convert 0 to 1.0 and 1 to -1.0 */ 102110e4ec448e8011e8d446d83fc8bd61c7ba2d74beBrian Paul setup->coef[fragSlot].a0[0] = setup->facing * -2.0f + 1.0f; 10221c04731b8721850b6abb12a43a3eec616b850e86Zack Rusin setup->coef[fragSlot].dadx[0] = 0.0; 10231c04731b8721850b6abb12a43a3eec616b850e86Zack Rusin setup->coef[fragSlot].dady[0] = 0.0; 1024c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1025c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 10260fae7648987d8264f85a9b6b6d7f903bff82a0f0Brian Paul return TRUE; 1027c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell} 1028c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1029c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1030c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell/** 1031c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Plot a pixel in a line segment. 1032c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 1033c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwellstatic INLINE void 1034c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwellplot(struct setup_context *setup, int x, int y) 1035c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell{ 1036c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const int iy = y & 1; 1037c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const int ix = x & 1; 1038c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const int quadX = x - ix; 1039c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const int quadY = y - iy; 1040c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const int mask = (1 << ix) << (2 * iy); 1041c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1042a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell if (quadX != setup->quad[0].input.x0 || 1043a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell quadY != setup->quad[0].input.y0) 1044c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell { 1045c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* flush prev quad, start new quad */ 1046c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1047a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell if (setup->quad[0].input.x0 != -1) 1048a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell clip_emit_quad( setup, &setup->quad[0] ); 1049c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1050a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad[0].input.x0 = quadX; 1051a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad[0].input.y0 = quadY; 1052a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad[0].inout.mask = 0x0; 1053c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1054c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1055a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad[0].inout.mask |= mask; 1056c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell} 1057c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1058c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1059c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell/** 1060c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Do setup for line rasterization, then render the line. 1061c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Single-pixel width, no stipple, etc. We rely on the 'draw' module 1062c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * to handle stippling and wide lines. 1063c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 1064c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwellvoid 10659a0ff33ad60cb63d430c4f93f6531f7aa2ec2ba8Brian Paulsp_setup_line(struct setup_context *setup, 10666756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paul const float (*v0)[4], 10676756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paul const float (*v1)[4]) 1068c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell{ 1069c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell int x0 = (int) v0[0][0]; 1070c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell int x1 = (int) v1[0][0]; 1071c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell int y0 = (int) v0[0][1]; 1072c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell int y1 = (int) v1[0][1]; 1073c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell int dx = x1 - x0; 1074c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell int dy = y1 - y0; 1075c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell int xstep, ystep; 1076c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 107776d39f0c19ee0673b65d6ad09ab338c8b750251aBrian Paul#if DEBUG_VERTS 107876d39f0c19ee0673b65d6ad09ab338c8b750251aBrian Paul debug_printf("Setup line:\n"); 107976d39f0c19ee0673b65d6ad09ab338c8b750251aBrian Paul print_vertex(setup, v0); 108076d39f0c19ee0673b65d6ad09ab338c8b750251aBrian Paul print_vertex(setup, v1); 108176d39f0c19ee0673b65d6ad09ab338c8b750251aBrian Paul#endif 108276d39f0c19ee0673b65d6ad09ab338c8b750251aBrian Paul 1083ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie if (setup->softpipe->no_rast || setup->softpipe->rasterizer->rasterizer_discard) 1084a5b87f249ef79b1a8d8b9dbe72879b7ac9eb133cKeith Whitwell return; 1085a5b87f249ef79b1a8d8b9dbe72879b7ac9eb133cKeith Whitwell 1086c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell if (dx == 0 && dy == 0) 1087c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell return; 1088c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 10890fae7648987d8264f85a9b6b6d7f903bff82a0f0Brian Paul if (!setup_line_coefficients(setup, v0, v1)) 10900fae7648987d8264f85a9b6b6d7f903bff82a0f0Brian Paul return; 10910fae7648987d8264f85a9b6b6d7f903bff82a0f0Brian Paul 10920fae7648987d8264f85a9b6b6d7f903bff82a0f0Brian Paul assert(v0[0][0] < 1.0e9); 10930fae7648987d8264f85a9b6b6d7f903bff82a0f0Brian Paul assert(v0[0][1] < 1.0e9); 10940fae7648987d8264f85a9b6b6d7f903bff82a0f0Brian Paul assert(v1[0][0] < 1.0e9); 10950fae7648987d8264f85a9b6b6d7f903bff82a0f0Brian Paul assert(v1[0][1] < 1.0e9); 1096c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1097c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell if (dx < 0) { 1098c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell dx = -dx; /* make positive */ 1099c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell xstep = -1; 1100c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1101c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell else { 1102c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell xstep = 1; 1103c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1104c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1105c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell if (dy < 0) { 1106c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell dy = -dy; /* make positive */ 1107c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell ystep = -1; 1108c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1109c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell else { 1110c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell ystep = 1; 1111c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1112c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1113c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell assert(dx >= 0); 1114c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell assert(dy >= 0); 1115a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell assert(setup->softpipe->reduced_prim == PIPE_PRIM_LINES); 1116a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell 1117a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad[0].input.x0 = setup->quad[0].input.y0 = -1; 1118a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad[0].inout.mask = 0x0; 1119c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1120c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* XXX temporary: set coverage to 1.0 so the line appears 1121c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * if AA mode happens to be enabled. 1122c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 1123a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad[0].input.coverage[0] = 1124a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad[0].input.coverage[1] = 1125a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad[0].input.coverage[2] = 1126a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad[0].input.coverage[3] = 1.0; 1127c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1128c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell if (dx > dy) { 1129c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /*** X-major line ***/ 1130c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell int i; 1131c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const int errorInc = dy + dy; 1132c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell int error = errorInc - dx; 1133c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const int errorDec = error - dx; 1134c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1135c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell for (i = 0; i < dx; i++) { 1136c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell plot(setup, x0, y0); 1137c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1138c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell x0 += xstep; 1139c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell if (error < 0) { 1140c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell error += errorInc; 1141c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1142c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell else { 1143c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell error += errorDec; 1144c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell y0 += ystep; 1145c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1146c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1147c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1148c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell else { 1149c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /*** Y-major line ***/ 1150c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell int i; 1151c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const int errorInc = dx + dx; 1152c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell int error = errorInc - dy; 1153c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const int errorDec = error - dy; 1154c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1155c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell for (i = 0; i < dy; i++) { 1156c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell plot(setup, x0, y0); 1157c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1158c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell y0 += ystep; 1159c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell if (error < 0) { 1160c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell error += errorInc; 1161c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1162c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell else { 1163c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell error += errorDec; 1164c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell x0 += xstep; 1165c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1166c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1167c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1168c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1169c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* draw final quad */ 1170a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell if (setup->quad[0].inout.mask) { 1171a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell clip_emit_quad( setup, &setup->quad[0] ); 1172c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1173c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell} 1174c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1175c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1176c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwellstatic void 1177492e61d94f68c3a4a515cab3cf227eed5b426bdfBrian Paulpoint_persp_coeff(const struct setup_context *setup, 1178c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const float (*vert)[4], 1179c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell struct tgsi_interp_coef *coef, 1180c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell uint vertSlot, uint i) 1181c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell{ 1182c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell assert(i <= 3); 1183c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell coef->dadx[i] = 0.0F; 1184c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell coef->dady[i] = 0.0F; 1185c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell coef->a0[i] = vert[vertSlot][i] * vert[0][3]; 1186c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell} 1187c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1188c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1189c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell/** 1190c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Do setup for point rasterization, then render the point. 1191c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Round or square points... 1192c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * XXX could optimize a lot for 1-pixel points. 1193c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 1194c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwellvoid 11956756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paulsp_setup_point(struct setup_context *setup, 11966756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paul const float (*v0)[4]) 1197c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell{ 1198c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell struct softpipe_context *softpipe = setup->softpipe; 1199c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul const struct tgsi_shader_info *fsInfo = &setup->softpipe->fs_variant->info; 1200c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const int sizeAttr = setup->softpipe->psize_slot; 1201c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const float size 1202c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell = sizeAttr > 0 ? v0[sizeAttr][0] 1203c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell : setup->softpipe->rasterizer->point_size; 1204c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const float halfSize = 0.5F * size; 1205c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const boolean round = (boolean) setup->softpipe->rasterizer->point_smooth; 1206c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const float x = v0[0][0]; /* Note: data[0] is always position */ 1207c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const float y = v0[0][1]; 1208c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe); 1209c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell uint fragSlot; 1210c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 121176d39f0c19ee0673b65d6ad09ab338c8b750251aBrian Paul#if DEBUG_VERTS 121276d39f0c19ee0673b65d6ad09ab338c8b750251aBrian Paul debug_printf("Setup point:\n"); 121376d39f0c19ee0673b65d6ad09ab338c8b750251aBrian Paul print_vertex(setup, v0); 121476d39f0c19ee0673b65d6ad09ab338c8b750251aBrian Paul#endif 1215a5b87f249ef79b1a8d8b9dbe72879b7ac9eb133cKeith Whitwell 1216ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie if (setup->softpipe->no_rast || setup->softpipe->rasterizer->rasterizer_discard) 1217a5b87f249ef79b1a8d8b9dbe72879b7ac9eb133cKeith Whitwell return; 1218a5b87f249ef79b1a8d8b9dbe72879b7ac9eb133cKeith Whitwell 1219a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell assert(setup->softpipe->reduced_prim == PIPE_PRIM_POINTS); 1220a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell 1221c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* For points, all interpolants are constant-valued. 1222c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * However, for point sprites, we'll need to setup texcoords appropriately. 1223c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * XXX: which coefficients are the texcoords??? 1224c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * We may do point sprites as textured quads... 1225c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * 1226c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * KW: We don't know which coefficients are texcoords - ultimately 1227c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * the choice of what interpolation mode to use for each attribute 1228c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * should be determined by the fragment program, using 1229c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * per-attribute declaration statements that include interpolation 1230c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * mode as a parameter. So either the fragment program will have 1231c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * to be adjusted for pointsprite vs normal point behaviour, or 1232c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * otherwise a special interpolation mode will have to be defined 1233c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * which matches the required behaviour for point sprites. But - 1234c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * the latter is not a feature of normal hardware, and as such 1235c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * probably should be ruled out on that basis. 1236c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 1237c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->vprovoke = v0; 1238c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1239c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* setup Z, W */ 1240c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const_coeff(setup, &setup->posCoef, 0, 2); 1241c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const_coeff(setup, &setup->posCoef, 0, 3); 1242c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1243c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul for (fragSlot = 0; fragSlot < fsInfo->num_inputs; fragSlot++) { 124453d4706c6c0922160f310834daaec5718ff1c511Keith Whitwell const uint vertSlot = vinfo->attrib[fragSlot].src_index; 1245c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell uint j; 1246c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 124753d4706c6c0922160f310834daaec5718ff1c511Keith Whitwell switch (vinfo->attrib[fragSlot].interp_mode) { 1248c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell case INTERP_CONSTANT: 1249c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* fall-through */ 1250c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell case INTERP_LINEAR: 12516b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard for (j = 0; j < TGSI_NUM_CHANNELS; j++) 1252c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); 1253c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell break; 1254c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell case INTERP_PERSPECTIVE: 12556b63e25b3d7a6ac0bd738c139ead0c7e7ad84368Tom Stellard for (j = 0; j < TGSI_NUM_CHANNELS; j++) 1256c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell point_persp_coeff(setup, setup->vprovoke, 1257c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell &setup->coef[fragSlot], vertSlot, j); 1258c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell break; 1259c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell case INTERP_POS: 1260c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup_fragcoord_coeff(setup, fragSlot); 1261c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell break; 1262c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell default: 1263c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell assert(0); 1264c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1265c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1266c534f11164bbecf25eb2b1e697f9511eceb0c86fBrian Paul if (fsInfo->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { 126710e4ec448e8011e8d446d83fc8bd61c7ba2d74beBrian Paul /* convert 0 to 1.0 and 1 to -1.0 */ 126810e4ec448e8011e8d446d83fc8bd61c7ba2d74beBrian Paul setup->coef[fragSlot].a0[0] = setup->facing * -2.0f + 1.0f; 12691c04731b8721850b6abb12a43a3eec616b850e86Zack Rusin setup->coef[fragSlot].dadx[0] = 0.0; 12701c04731b8721850b6abb12a43a3eec616b850e86Zack Rusin setup->coef[fragSlot].dady[0] = 0.0; 1271c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1272c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1273c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1274c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1275c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell if (halfSize <= 0.5 && !round) { 1276c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* special case for 1-pixel points */ 1277c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const int ix = ((int) x) & 1; 1278c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const int iy = ((int) y) & 1; 1279a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad[0].input.x0 = (int) x - ix; 1280a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad[0].input.y0 = (int) y - iy; 1281a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad[0].inout.mask = (1 << ix) << (2 * iy); 1282a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell clip_emit_quad( setup, &setup->quad[0] ); 1283c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1284c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell else { 1285c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell if (round) { 1286c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* rounded points */ 1287c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const int ixmin = block((int) (x - halfSize)); 1288c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const int ixmax = block((int) (x + halfSize)); 1289c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const int iymin = block((int) (y - halfSize)); 1290c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const int iymax = block((int) (y + halfSize)); 1291c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const float rmin = halfSize - 0.7071F; /* 0.7071 = sqrt(2)/2 */ 1292c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const float rmax = halfSize + 0.7071F; 1293c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const float rmin2 = MAX2(0.0F, rmin * rmin); 1294c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const float rmax2 = rmax * rmax; 1295c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const float cscale = 1.0F / (rmax2 - rmin2); 1296c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell int ix, iy; 1297c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1298c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell for (iy = iymin; iy <= iymax; iy += 2) { 1299c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell for (ix = ixmin; ix <= ixmax; ix += 2) { 1300c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell float dx, dy, dist2, cover; 1301c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1302a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad[0].inout.mask = 0x0; 1303c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1304c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell dx = (ix + 0.5f) - x; 1305c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell dy = (iy + 0.5f) - y; 1306c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell dist2 = dx * dx + dy * dy; 1307c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell if (dist2 <= rmax2) { 1308c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell cover = 1.0F - (dist2 - rmin2) * cscale; 1309a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad[0].input.coverage[QUAD_TOP_LEFT] = MIN2(cover, 1.0f); 1310a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad[0].inout.mask |= MASK_TOP_LEFT; 1311c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1312c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1313c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell dx = (ix + 1.5f) - x; 1314c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell dy = (iy + 0.5f) - y; 1315c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell dist2 = dx * dx + dy * dy; 1316c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell if (dist2 <= rmax2) { 1317c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell cover = 1.0F - (dist2 - rmin2) * cscale; 1318a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad[0].input.coverage[QUAD_TOP_RIGHT] = MIN2(cover, 1.0f); 1319a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad[0].inout.mask |= MASK_TOP_RIGHT; 1320c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1321c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1322c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell dx = (ix + 0.5f) - x; 1323c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell dy = (iy + 1.5f) - y; 1324c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell dist2 = dx * dx + dy * dy; 1325c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell if (dist2 <= rmax2) { 1326c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell cover = 1.0F - (dist2 - rmin2) * cscale; 1327a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad[0].input.coverage[QUAD_BOTTOM_LEFT] = MIN2(cover, 1.0f); 1328a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad[0].inout.mask |= MASK_BOTTOM_LEFT; 1329c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1330c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1331c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell dx = (ix + 1.5f) - x; 1332c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell dy = (iy + 1.5f) - y; 1333c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell dist2 = dx * dx + dy * dy; 1334c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell if (dist2 <= rmax2) { 1335c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell cover = 1.0F - (dist2 - rmin2) * cscale; 1336a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad[0].input.coverage[QUAD_BOTTOM_RIGHT] = MIN2(cover, 1.0f); 1337a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad[0].inout.mask |= MASK_BOTTOM_RIGHT; 1338c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1339c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1340a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell if (setup->quad[0].inout.mask) { 1341a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad[0].input.x0 = ix; 1342a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad[0].input.y0 = iy; 1343a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell clip_emit_quad( setup, &setup->quad[0] ); 1344c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1345c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1346c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1347c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1348c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell else { 1349c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* square points */ 1350c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const int xmin = (int) (x + 0.75 - halfSize); 1351c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const int ymin = (int) (y + 0.25 - halfSize); 1352c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const int xmax = xmin + (int) size; 1353c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const int ymax = ymin + (int) size; 1354c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* XXX could apply scissor to xmin,ymin,xmax,ymax now */ 1355c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const int ixmin = block(xmin); 1356c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const int ixmax = block(xmax - 1); 1357c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const int iymin = block(ymin); 1358c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell const int iymax = block(ymax - 1); 1359c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell int ix, iy; 1360c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1361c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* 1362c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell debug_printf("(%f, %f) -> X:%d..%d Y:%d..%d\n", x, y, xmin, xmax,ymin,ymax); 1363c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 1364c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell for (iy = iymin; iy <= iymax; iy += 2) { 1365c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell uint rowMask = 0xf; 1366c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell if (iy < ymin) { 1367c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* above the top edge */ 1368c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell rowMask &= (MASK_BOTTOM_LEFT | MASK_BOTTOM_RIGHT); 1369c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1370c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell if (iy + 1 >= ymax) { 1371c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* below the bottom edge */ 1372c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell rowMask &= (MASK_TOP_LEFT | MASK_TOP_RIGHT); 1373c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1374c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1375c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell for (ix = ixmin; ix <= ixmax; ix += 2) { 1376c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell uint mask = rowMask; 1377c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1378c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell if (ix < xmin) { 1379c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* fragment is past left edge of point, turn off left bits */ 1380c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell mask &= (MASK_BOTTOM_RIGHT | MASK_TOP_RIGHT); 1381c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1382c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell if (ix + 1 >= xmax) { 1383c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell /* past the right edge */ 1384c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell mask &= (MASK_BOTTOM_LEFT | MASK_TOP_LEFT); 1385c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1386c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1387a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad[0].inout.mask = mask; 1388a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad[0].input.x0 = ix; 1389a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad[0].input.y0 = iy; 1390a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell clip_emit_quad( setup, &setup->quad[0] ); 1391c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1392c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1393c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1394c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1395c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell} 1396c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 13976756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paul 13986756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paul/** 13996756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paul * Called by vbuf code just before we start buffering primitives. 14006756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paul */ 14016756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paulvoid 14026756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paulsp_setup_prepare(struct setup_context *setup) 1403c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell{ 1404c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell struct softpipe_context *sp = setup->softpipe; 1405c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1406c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell if (sp->dirty) { 140757aa597b3d5dac0fc59c05557dafec59e14e1019Brian Paul softpipe_update_derived(sp, sp->reduced_api_prim); 1408c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell } 1409c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1410f36123323c9d696fec6e54882242cab15247ab0dBrian Paul /* Note: nr_attrs is only used for debugging (vertex printing) */ 141189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin setup->nr_vertex_attrs = draw_num_shader_outputs(sp->draw); 1412f36123323c9d696fec6e54882242cab15247ab0dBrian Paul 14136153a1c28f118be1a74ffee0e19c16fb83b5cab7Keith Whitwell sp->quad.first->begin( sp->quad.first ); 14144ff1274e2312c7d9d8538dc443af500ec3b769cfKeith Whitwell 14154ff1274e2312c7d9d8538dc443af500ec3b769cfKeith Whitwell if (sp->reduced_api_prim == PIPE_PRIM_TRIANGLES && 14164ff1274e2312c7d9d8538dc443af500ec3b769cfKeith Whitwell sp->rasterizer->fill_front == PIPE_POLYGON_MODE_FILL && 14174ff1274e2312c7d9d8538dc443af500ec3b769cfKeith Whitwell sp->rasterizer->fill_back == PIPE_POLYGON_MODE_FILL) { 14184ff1274e2312c7d9d8538dc443af500ec3b769cfKeith Whitwell /* we'll do culling */ 14194ff1274e2312c7d9d8538dc443af500ec3b769cfKeith Whitwell setup->cull_face = sp->rasterizer->cull_face; 14204ff1274e2312c7d9d8538dc443af500ec3b769cfKeith Whitwell } 14214ff1274e2312c7d9d8538dc443af500ec3b769cfKeith Whitwell else { 14224ff1274e2312c7d9d8538dc443af500ec3b769cfKeith Whitwell /* 'draw' will do culling */ 14234ff1274e2312c7d9d8538dc443af500ec3b769cfKeith Whitwell setup->cull_face = PIPE_FACE_NONE; 14244ff1274e2312c7d9d8538dc443af500ec3b769cfKeith Whitwell } 1425c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell} 1426c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1427c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 14286756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paulvoid 14296756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paulsp_setup_destroy_context(struct setup_context *setup) 1430c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell{ 1431c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell FREE( setup ); 1432c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell} 1433c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1434c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1435c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell/** 1436c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Create a new primitive setup/render stage. 1437c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */ 14386756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paulstruct setup_context * 14396756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paulsp_setup_create_context(struct softpipe_context *softpipe) 1440c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell{ 1441c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell struct setup_context *setup = CALLOC_STRUCT(setup_context); 1442a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell unsigned i; 1443c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1444c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell setup->softpipe = softpipe; 1445c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 1446a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell for (i = 0; i < MAX_QUADS; i++) { 1447a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad[i].coef = setup->coef; 1448a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell setup->quad[i].posCoef = &setup->posCoef; 1449a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell } 1450c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell 14510ed99f45529178c77e47838f226231ea1bc9b918Keith Whitwell setup->span.left[0] = 1000000; /* greater than right[0] */ 14520ed99f45529178c77e47838f226231ea1bc9b918Keith Whitwell setup->span.left[1] = 1000000; /* greater than right[1] */ 14530ed99f45529178c77e47838f226231ea1bc9b918Keith Whitwell 1454c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell return setup; 1455c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell} 1456