lp_setup.c revision bdbb4beb21876010b14785569a920fa65a67d1ad
1946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/************************************************************************** 2946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * 3946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 4946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * All Rights Reserved. 5946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * 6946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Permission is hereby granted, free of charge, to any person obtaining a 7946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * copy of this software and associated documentation files (the 8946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * "Software"), to deal in the Software without restriction, including 9946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * without limitation the rights to use, copy, modify, merge, publish, 10946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * distribute, sub license, and/or sell copies of the Software, and to 11946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * permit persons to whom the Software is furnished to do so, subject to 12946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * the following conditions: 13946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * 14946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * The above copyright notice and this permission notice (including the 15946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * next paragraph) shall be included in all copies or substantial portions 16946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * of the Software. 17946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * 18946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * 26946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca **************************************************************************/ 27946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 28946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 29946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * \brief Primitive rasterization/rendering (points, lines, triangles) 30946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * 31946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * \author Keith Whitwell <keith@tungstengraphics.com> 32946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * \author Brian Paul 33946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 34946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 35946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#include "lp_context.h" 36946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#include "lp_prim_setup.h" 37946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#include "lp_quad.h" 38946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#include "lp_quad_pipe.h" 39946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#include "lp_setup.h" 40946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#include "lp_state.h" 41946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#include "draw/draw_context.h" 42946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#include "draw/draw_private.h" 43946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#include "draw/draw_vertex.h" 44946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#include "pipe/p_shader_tokens.h" 45946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#include "pipe/p_thread.h" 46946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#include "util/u_math.h" 47946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#include "util/u_memory.h" 48946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 49946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 50946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#define DEBUG_VERTS 0 51946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#define DEBUG_FRAGS 0 52946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 53946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 54946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Triangle edge info 55946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 56946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastruct edge { 57946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float dx; /**< X(v1) - X(v0), used only during setup */ 58946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float dy; /**< Y(v1) - Y(v0), used only during setup */ 59946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float dxdy; /**< dx/dy */ 60946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float sx, sy; /**< first sample point coord */ 61946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int lines; /**< number of lines on this edge */ 62946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca}; 63946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 64946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 65946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 66946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 67946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Triangle setup info (derived from draw_stage). 68946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Also used for line drawing (taking some liberties). 69946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 70946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastruct setup_context { 71946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct llvmpipe_context *llvmpipe; 72946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 73946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* Vertices are just an array of floats making up each attribute in 74946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * turn. Currently fixed at 4 floats, but should change in time. 75946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Codegen will help cope with this. 76946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 77946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*vmax)[4]; 78946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*vmid)[4]; 79946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*vmin)[4]; 80946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*vprovoke)[4]; 81946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 82946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct edge ebot; 83946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct edge etop; 84946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct edge emaj; 85946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 86946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float oneoverarea; 87946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 88946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct tgsi_interp_coef coef[PIPE_MAX_SHADER_INPUTS]; 89946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct tgsi_interp_coef posCoef; /* For Z, W */ 90946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct quad_header quad; 91946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 92946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct { 93946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int left[2]; /**< [0] = row0, [1] = row1 */ 94946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int right[2]; 95946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int y; 96946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } span; 97946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 98946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#if DEBUG_FRAGS 99946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint numFragsEmitted; /**< per primitive */ 100946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint numFragsWritten; /**< per primitive */ 101946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#endif 102946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 103946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca unsigned winding; /* which winding to cull */ 104946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca}; 105946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 106946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 107946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 108946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 109946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 110946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Do triangle cull test using tri determinant (sign indicates orientation) 111946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * \return true if triangle is to be culled. 112946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 113946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic INLINE boolean 114946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecacull_tri(const struct setup_context *setup, float det) 115946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 116946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (det != 0) { 117946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* if (det < 0 then Z points toward camera and triangle is 118946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * counter-clockwise winding. 119946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 120946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca unsigned winding = (det < 0) ? PIPE_WINDING_CCW : PIPE_WINDING_CW; 121946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 122946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if ((winding & setup->winding) == 0) 123946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return FALSE; 124946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 125946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 126946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* Culled: 127946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 128946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return TRUE; 129946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 130946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 131946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 132946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 133946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 134946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Clip setup->quad against the scissor/surface bounds. 135946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 136946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic INLINE void 137946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecaquad_clip( struct setup_context *setup, struct quad_header *quad ) 138946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 139946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const struct pipe_scissor_state *cliprect = &setup->llvmpipe->cliprect; 140946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int minx = (int) cliprect->minx; 141946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int maxx = (int) cliprect->maxx; 142946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int miny = (int) cliprect->miny; 143946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int maxy = (int) cliprect->maxy; 144946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 145946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (quad->input.x0 >= maxx || 146946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca quad->input.y0 >= maxy || 147946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca quad->input.x0 + 1 < minx || 148946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca quad->input.y0 + 1 < miny) { 149946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* totally clipped */ 150946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca quad->inout.mask = 0x0; 151946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return; 152946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 153946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (quad->input.x0 < minx) 154946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca quad->inout.mask &= (MASK_BOTTOM_RIGHT | MASK_TOP_RIGHT); 155946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (quad->input.y0 < miny) 156946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca quad->inout.mask &= (MASK_BOTTOM_LEFT | MASK_BOTTOM_RIGHT); 157946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (quad->input.x0 == maxx - 1) 158946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca quad->inout.mask &= (MASK_BOTTOM_LEFT | MASK_TOP_LEFT); 159946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (quad->input.y0 == maxy - 1) 160946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca quad->inout.mask &= (MASK_TOP_LEFT | MASK_TOP_RIGHT); 161946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 162946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 163946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 164946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 165946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Emit a quad (pass to next stage) with clipping. 166946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 167946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic INLINE void 1684486012245c5f526059d3872ac3561f53705d1cfKeith Whitwellclip_emit_quad( struct setup_context *setup, struct quad_header *quad ) 169946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 170946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca quad_clip( setup, quad ); 1714486012245c5f526059d3872ac3561f53705d1cfKeith Whitwell 172946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (quad->inout.mask) { 173946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct llvmpipe_context *lp = setup->llvmpipe; 174946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 175bdbb4beb21876010b14785569a920fa65a67d1adKeith Whitwell lp->quad.first->run( lp->quad.first, &quad, 1 ); 176946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 177946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 178946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 179946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 180946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Emit a quad (pass to next stage). No clipping is done. 181946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 182946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic INLINE void 183946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecaemit_quad( struct setup_context *setup, struct quad_header *quad, uint thread ) 184946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 185946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct llvmpipe_context *lp = setup->llvmpipe; 186946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#if DEBUG_FRAGS 187946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint mask = quad->inout.mask; 188946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#endif 189946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 190946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#if DEBUG_FRAGS 191946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (mask & 1) setup->numFragsEmitted++; 192946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (mask & 2) setup->numFragsEmitted++; 193946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (mask & 4) setup->numFragsEmitted++; 194946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (mask & 8) setup->numFragsEmitted++; 195946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#endif 196bdbb4beb21876010b14785569a920fa65a67d1adKeith Whitwell lp->quad.first->run( lp->quad.first, &quad, 1 ); 197946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#if DEBUG_FRAGS 198946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca mask = quad->inout.mask; 199946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (mask & 1) setup->numFragsWritten++; 200946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (mask & 2) setup->numFragsWritten++; 201946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (mask & 4) setup->numFragsWritten++; 202946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (mask & 8) setup->numFragsWritten++; 203946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#endif 204946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 205946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 206946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 2074486012245c5f526059d3872ac3561f53705d1cfKeith Whitwell#define EMIT_QUAD(setup,x,y,qmask) \ 2084486012245c5f526059d3872ac3561f53705d1cfKeith Whitwelldo { \ 2094486012245c5f526059d3872ac3561f53705d1cfKeith Whitwell setup->quad.input.x0 = x; \ 2104486012245c5f526059d3872ac3561f53705d1cfKeith Whitwell setup->quad.input.y0 = y; \ 2114486012245c5f526059d3872ac3561f53705d1cfKeith Whitwell setup->quad.inout.mask = qmask; \ 2124486012245c5f526059d3872ac3561f53705d1cfKeith Whitwell emit_quad( setup, &setup->quad, 0 ); \ 2134486012245c5f526059d3872ac3561f53705d1cfKeith Whitwell} while (0) 214946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 215946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 216946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 217946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Given an X or Y coordinate, return the block/quad coordinate that it 218946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * belongs to. 219946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 220946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic INLINE int block( int x ) 221946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 222946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return x & ~1; 223946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 224946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 225946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 226946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 227946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Render a horizontal span of quads 228946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 229946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void flush_spans( struct setup_context *setup ) 230946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 23108811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell const int step = 30; 232946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int xleft0 = setup->span.left[0]; 233946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int xleft1 = setup->span.left[1]; 234946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int xright0 = setup->span.right[0]; 235946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int xright1 = setup->span.right[1]; 23608811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell 23708811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell int minleft = block(MIN2(xleft0, xleft1)); 23808811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell int maxright = MAX2(xright0, xright1); 239946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int x; 240946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 24108811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell for (x = minleft; x < maxright; x += step) { 24208811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned skip_left0 = CLAMP(xleft0 - x, 0, step); 24308811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned skip_left1 = CLAMP(xleft1 - x, 0, step); 24408811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned skip_right0 = CLAMP(x + step - xright0, 0, step); 24508811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned skip_right1 = CLAMP(x + step - xright1, 0, step); 24608811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned lx = x; 24708811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell 24808811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned skipmask_left0 = (1U << skip_left0) - 1U; 24908811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned skipmask_left1 = (1U << skip_left1) - 1U; 25008811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell 25108811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell /* These calculations fail when step == 32 and skip_right == 0. 25208811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell */ 25308811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned skipmask_right0 = ~0U << (unsigned)(step - skip_right0); 25408811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned skipmask_right1 = ~0U << (unsigned)(step - skip_right1); 25508811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell 25608811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned mask0 = ~skipmask_left0 & ~skipmask_right0; 25708811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned mask1 = ~skipmask_left1 & ~skipmask_right1; 25808811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell 25908811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell while (mask0 | mask1) { 26008811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned quadmask = (mask0 & 3) | ((mask1 & 3) << 2); 26108811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell if (quadmask) 26208811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell EMIT_QUAD( setup, lx, setup->span.y, quadmask ); 26308811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell mask0 >>= 2; 26408811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell mask1 >>= 2; 26508811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell lx += 2; 26608811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell } 267946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 268946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 2690aa24fa36f7aea8e25c392eeeef6f9c108f09abaKeith Whitwell 270946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->span.y = 0; 271946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->span.right[0] = 0; 272946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->span.right[1] = 0; 27308811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell setup->span.left[0] = 1000000; /* greater than right[0] */ 27408811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell setup->span.left[1] = 1000000; /* greater than right[1] */ 275946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 276946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 277946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 278946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#if DEBUG_VERTS 279946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void print_vertex(const struct setup_context *setup, 280946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v)[4]) 281946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 282946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int i; 283946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf(" Vertex: (%p)\n", v); 284946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (i = 0; i < setup->quad.nr_attrs; i++) { 285946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf(" %d: %f %f %f %f\n", i, 286946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca v[i][0], v[i][1], v[i][2], v[i][3]); 287946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (util_is_inf_or_nan(v[i][0])) { 288946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf(" NaN!\n"); 289946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 290946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 291946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 292946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#endif 293946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 294946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 295946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Sort the vertices from top to bottom order, setting up the triangle 296946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * edge fields (ebot, emaj, etop). 297946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * \return FALSE if coords are inf/nan (cull the tri), TRUE otherwise 298946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 299946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic boolean setup_sort_vertices( struct setup_context *setup, 300946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float det, 301946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v0)[4], 302946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v1)[4], 303946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v2)[4] ) 304946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 305946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vprovoke = v2; 306946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 307946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* determine bottom to top order of vertices */ 308946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca { 309946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float y0 = v0[0][1]; 310946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float y1 = v1[0][1]; 311946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float y2 = v2[0][1]; 312946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (y0 <= y1) { 313946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (y1 <= y2) { 314946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* y0<=y1<=y2 */ 315946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmin = v0; 316946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmid = v1; 317946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmax = v2; 318946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 319946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else if (y2 <= y0) { 320946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* y2<=y0<=y1 */ 321946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmin = v2; 322946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmid = v0; 323946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmax = v1; 324946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 325946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 326946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* y0<=y2<=y1 */ 327946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmin = v0; 328946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmid = v2; 329946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmax = v1; 330946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 331946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 332946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 333946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (y0 <= y2) { 334946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* y1<=y0<=y2 */ 335946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmin = v1; 336946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmid = v0; 337946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmax = v2; 338946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 339946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else if (y2 <= y1) { 340946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* y2<=y1<=y0 */ 341946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmin = v2; 342946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmid = v1; 343946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmax = v0; 344946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 345946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 346946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* y1<=y2<=y0 */ 347946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmin = v1; 348946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmid = v2; 349946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmax = v0; 350946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 351946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 352946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 353946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 354946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->ebot.dx = setup->vmid[0][0] - setup->vmin[0][0]; 355946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->ebot.dy = setup->vmid[0][1] - setup->vmin[0][1]; 356946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->emaj.dx = setup->vmax[0][0] - setup->vmin[0][0]; 357946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->emaj.dy = setup->vmax[0][1] - setup->vmin[0][1]; 358946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->etop.dx = setup->vmax[0][0] - setup->vmid[0][0]; 359946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->etop.dy = setup->vmax[0][1] - setup->vmid[0][1]; 360946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 361946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* 362946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Compute triangle's area. Use 1/area to compute partial 363946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * derivatives of attributes later. 364946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * 365946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * The area will be the same as prim->det, but the sign may be 366946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * different depending on how the vertices get sorted above. 367946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * 368946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * To determine whether the primitive is front or back facing we 369946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * use the prim->det value because its sign is correct. 370946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 371946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca { 372946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float area = (setup->emaj.dx * setup->ebot.dy - 373946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->ebot.dx * setup->emaj.dy); 374946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 375946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->oneoverarea = 1.0f / area; 376946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 377946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* 378946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf("%s one-over-area %f area %f det %f\n", 379946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca __FUNCTION__, setup->oneoverarea, area, det ); 380946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 381946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (util_is_inf_or_nan(setup->oneoverarea)) 382946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return FALSE; 383946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 384946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 385946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* We need to know if this is a front or back-facing triangle for: 386946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * - the GLSL gl_FrontFacing fragment attribute (bool) 387946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * - two-sided stencil test 388946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 389946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.input.facing = (det > 0.0) ^ (setup->llvmpipe->rasterizer->front_winding == PIPE_WINDING_CW); 390946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 391946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return TRUE; 392946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 393946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 394946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 395946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 396946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Compute a0 for a constant-valued coefficient (GL_FLAT shading). 397946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * The value value comes from vertex[slot][i]. 398946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * The result will be put into setup->coef[slot].a0[i]. 399946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * \param slot which attribute slot 400946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * \param i which component of the slot (0..3) 401946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 402946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void const_coeff( struct setup_context *setup, 403946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct tgsi_interp_coef *coef, 404946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint vertSlot, uint i) 405946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 406946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(i <= 3); 407946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 408946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->dadx[i] = 0; 409946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->dady[i] = 0; 410946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 411946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* need provoking vertex info! 412946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 413946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->a0[i] = setup->vprovoke[vertSlot][i]; 414946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 415946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 416946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 417946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 418946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Compute a0, dadx and dady for a linearly interpolated coefficient, 419946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * for a triangle. 420946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 421946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void tri_linear_coeff( struct setup_context *setup, 422946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct tgsi_interp_coef *coef, 423946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint vertSlot, uint i) 424946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 425946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float botda = setup->vmid[vertSlot][i] - setup->vmin[vertSlot][i]; 426946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float majda = setup->vmax[vertSlot][i] - setup->vmin[vertSlot][i]; 427946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float a = setup->ebot.dy * majda - botda * setup->emaj.dy; 428946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float b = setup->emaj.dx * botda - majda * setup->ebot.dx; 429946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float dadx = a * setup->oneoverarea; 430946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float dady = b * setup->oneoverarea; 431946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 432946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(i <= 3); 433946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 434946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->dadx[i] = dadx; 435946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->dady[i] = dady; 436946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 437946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* calculate a0 as the value which would be sampled for the 438946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * fragment at (0,0), taking into account that we want to sample at 439946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * pixel centers, in other words (0.5, 0.5). 440946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * 441946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * this is neat but unfortunately not a good way to do things for 442946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * triangles with very large values of dadx or dady as it will 443946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * result in the subtraction and re-addition from a0 of a very 444946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * large number, which means we'll end up loosing a lot of the 445946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * fractional bits and precision from a0. the way to fix this is 446946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * to define a0 as the sample at a pixel center somewhere near vmin 447946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * instead - i'll switch to this later. 448946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 449946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->a0[i] = (setup->vmin[vertSlot][i] - 450946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca (dadx * (setup->vmin[0][0] - 0.5f) + 451946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dady * (setup->vmin[0][1] - 0.5f))); 452946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 453946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* 454946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf("attr[%d].%c: %f dx:%f dy:%f\n", 455946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca slot, "xyzw"[i], 456946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[slot].a0[i], 457946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[slot].dadx[i], 458946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[slot].dady[i]); 459946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 460946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 461946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 462946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 463946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 464946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Compute a0, dadx and dady for a perspective-corrected interpolant, 465946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * for a triangle. 466946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * We basically multiply the vertex value by 1/w before computing 467946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * the plane coefficients (a0, dadx, dady). 468946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Later, when we compute the value at a particular fragment position we'll 469946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * divide the interpolated value by the interpolated W at that fragment. 470946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 471946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void tri_persp_coeff( struct setup_context *setup, 472946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct tgsi_interp_coef *coef, 473946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint vertSlot, uint i) 474946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 475946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* premultiply by 1/w (v[0][3] is always W): 476946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 477946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float mina = setup->vmin[vertSlot][i] * setup->vmin[0][3]; 478946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float mida = setup->vmid[vertSlot][i] * setup->vmid[0][3]; 479946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float maxa = setup->vmax[vertSlot][i] * setup->vmax[0][3]; 480946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float botda = mida - mina; 481946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float majda = maxa - mina; 482946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float a = setup->ebot.dy * majda - botda * setup->emaj.dy; 483946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float b = setup->emaj.dx * botda - majda * setup->ebot.dx; 484946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float dadx = a * setup->oneoverarea; 485946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float dady = b * setup->oneoverarea; 486946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 487946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* 488946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf("tri persp %d,%d: %f %f %f\n", vertSlot, i, 489946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmin[vertSlot][i], 490946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmid[vertSlot][i], 491946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmax[vertSlot][i] 492946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca ); 493946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 494946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(i <= 3); 495946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 496946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->dadx[i] = dadx; 497946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->dady[i] = dady; 498946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->a0[i] = (mina - 499946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca (dadx * (setup->vmin[0][0] - 0.5f) + 500946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dady * (setup->vmin[0][1] - 0.5f))); 501946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 502946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 503946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 504946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 505946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Special coefficient setup for gl_FragCoord. 506946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * X and Y are trivial, though Y has to be inverted for OpenGL. 507946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Z and W are copied from posCoef which should have already been computed. 508946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * We could do a bit less work if we'd examine gl_FragCoord's swizzle mask. 509946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 510946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void 511946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecasetup_fragcoord_coeff(struct setup_context *setup, uint slot) 512946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 513946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /*X*/ 514946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[slot].a0[0] = 0; 515946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[slot].dadx[0] = 1.0; 516946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[slot].dady[0] = 0.0; 517946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /*Y*/ 518946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[slot].a0[1] = 0.0; 519946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[slot].dadx[1] = 0.0; 520946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[slot].dady[1] = 1.0; 521946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /*Z*/ 522946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[slot].a0[2] = setup->posCoef.a0[2]; 523946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[slot].dadx[2] = setup->posCoef.dadx[2]; 524946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[slot].dady[2] = setup->posCoef.dady[2]; 525946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /*W*/ 526946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[slot].a0[3] = setup->posCoef.a0[3]; 527946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[slot].dadx[3] = setup->posCoef.dadx[3]; 528946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[slot].dady[3] = setup->posCoef.dady[3]; 529946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 530946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 531946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 532946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 533946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 534946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Compute the setup->coef[] array dadx, dady, a0 values. 535946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Must be called after setup->vmin,vmid,vmax,vprovoke are initialized. 536946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 537946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void setup_tri_coefficients( struct setup_context *setup ) 538946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 539946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct llvmpipe_context *llvmpipe = setup->llvmpipe; 540946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const struct lp_fragment_shader *lpfs = llvmpipe->fs; 541946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const struct vertex_info *vinfo = llvmpipe_get_vertex_info(llvmpipe); 542946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint fragSlot; 543946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 544946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* z and w are done by linear interpolation: 545946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 546946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca tri_linear_coeff(setup, &setup->posCoef, 0, 2); 547946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca tri_linear_coeff(setup, &setup->posCoef, 0, 3); 548946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 549946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* setup interpolation for all the remaining attributes: 550946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 551946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (fragSlot = 0; fragSlot < lpfs->info.num_inputs; fragSlot++) { 552946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const uint vertSlot = vinfo->attrib[fragSlot].src_index; 553946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint j; 554946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 555946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca switch (vinfo->attrib[fragSlot].interp_mode) { 556946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_CONSTANT: 557946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (j = 0; j < NUM_CHANNELS; j++) 558946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); 559946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 560946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_LINEAR: 561946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (j = 0; j < NUM_CHANNELS; j++) 562946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca tri_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j); 563946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 564946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_PERSPECTIVE: 565946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (j = 0; j < NUM_CHANNELS; j++) 566946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca tri_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j); 567946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 568946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_POS: 569946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup_fragcoord_coeff(setup, fragSlot); 570946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 571946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca default: 572946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(0); 573946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 574946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 575946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (lpfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { 576946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[fragSlot].a0[0] = 1.0f - setup->quad.input.facing; 577946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[fragSlot].dadx[0] = 0.0; 578946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[fragSlot].dady[0] = 0.0; 579946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 580946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 581946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 582946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 583946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 584946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 585946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void setup_tri_edges( struct setup_context *setup ) 586946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 587946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float vmin_x = setup->vmin[0][0] + 0.5f; 588946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float vmid_x = setup->vmid[0][0] + 0.5f; 589946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 590946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float vmin_y = setup->vmin[0][1] - 0.5f; 591946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float vmid_y = setup->vmid[0][1] - 0.5f; 592946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float vmax_y = setup->vmax[0][1] - 0.5f; 593946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 594946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->emaj.sy = ceilf(vmin_y); 595946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->emaj.lines = (int) ceilf(vmax_y - setup->emaj.sy); 596946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->emaj.dxdy = setup->emaj.dx / setup->emaj.dy; 597946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->emaj.sx = vmin_x + (setup->emaj.sy - vmin_y) * setup->emaj.dxdy; 598946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 599946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->etop.sy = ceilf(vmid_y); 600946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->etop.lines = (int) ceilf(vmax_y - setup->etop.sy); 601946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->etop.dxdy = setup->etop.dx / setup->etop.dy; 602946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->etop.sx = vmid_x + (setup->etop.sy - vmid_y) * setup->etop.dxdy; 603946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 604946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->ebot.sy = ceilf(vmin_y); 605946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->ebot.lines = (int) ceilf(vmid_y - setup->ebot.sy); 606946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->ebot.dxdy = setup->ebot.dx / setup->ebot.dy; 607946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->ebot.sx = vmin_x + (setup->ebot.sy - vmin_y) * setup->ebot.dxdy; 608946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 609946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 610946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 611946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 612946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Render the upper or lower half of a triangle. 613946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Scissoring/cliprect is applied here too. 614946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 615946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void subtriangle( struct setup_context *setup, 616946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct edge *eleft, 617946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct edge *eright, 618946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca unsigned lines ) 619946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 620946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const struct pipe_scissor_state *cliprect = &setup->llvmpipe->cliprect; 621946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int minx = (int) cliprect->minx; 622946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int maxx = (int) cliprect->maxx; 623946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int miny = (int) cliprect->miny; 624946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int maxy = (int) cliprect->maxy; 625946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int y, start_y, finish_y; 626946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int sy = (int)eleft->sy; 627946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 628946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert((int)eleft->sy == (int) eright->sy); 629946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 630946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* clip top/bottom */ 631946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca start_y = sy; 632946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (start_y < miny) 633946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca start_y = miny; 634946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 63508811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell finish_y = sy + lines; 636946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (finish_y > maxy) 637946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca finish_y = maxy; 638946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 639946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca start_y -= sy; 640946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca finish_y -= sy; 641946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 642946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* 643946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf("%s %d %d\n", __FUNCTION__, start_y, finish_y); 644946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 645946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 646946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (y = start_y; y < finish_y; y++) { 647946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 648946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* avoid accumulating adds as floats don't have the precision to 649946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * accurately iterate large triangle edges that way. luckily we 650946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * can just multiply these days. 651946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * 652946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * this is all drowned out by the attribute interpolation anyway. 653946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 654946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int left = (int)(eleft->sx + y * eleft->dxdy); 655946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int right = (int)(eright->sx + y * eright->dxdy); 656946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 657946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* clip left/right */ 658946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (left < minx) 659946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca left = minx; 660946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (right > maxx) 661946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca right = maxx; 662946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 663946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (left < right) { 664946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int _y = sy + y; 665946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (block(_y) != setup->span.y) { 666946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca flush_spans(setup); 667946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->span.y = block(_y); 668946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 669946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 670946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->span.left[_y&1] = left; 671946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->span.right[_y&1] = right; 672946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 673946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 674946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 675946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 676946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* save the values so that emaj can be restarted: 677946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 678946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca eleft->sx += lines * eleft->dxdy; 679946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca eright->sx += lines * eright->dxdy; 680946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca eleft->sy += lines; 681946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca eright->sy += lines; 682946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 683946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 684946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 685946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 686946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Recalculate prim's determinant. This is needed as we don't have 687946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * get this information through the vbuf_render interface & we must 688946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * calculate it here. 689946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 690946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic float 691946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecacalc_det( const float (*v0)[4], 692946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v1)[4], 693946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v2)[4] ) 694946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 695946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* edge vectors e = v0 - v2, f = v1 - v2 */ 696946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float ex = v0[0][0] - v2[0][0]; 697946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float ey = v0[0][1] - v2[0][1]; 698946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float fx = v1[0][0] - v2[0][0]; 699946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float fy = v1[0][1] - v2[0][1]; 700946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 701946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* det = cross(e,f).z */ 702946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return ex * fy - ey * fx; 703946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 704946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 705946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 706946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 707946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Do setup for triangle rasterization, then render the triangle. 708946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 709946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecavoid setup_tri( struct setup_context *setup, 710946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v0)[4], 711946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v1)[4], 712946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v2)[4] ) 713946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 714946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float det; 715946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 716946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#if DEBUG_VERTS 717946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf("Setup triangle:\n"); 718946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca print_vertex(setup, v0); 719946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca print_vertex(setup, v1); 720946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca print_vertex(setup, v2); 721946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#endif 722946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 723946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (setup->llvmpipe->no_rast) 724946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return; 725946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 726946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca det = calc_det(v0, v1, v2); 727946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* 728946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf("%s\n", __FUNCTION__ ); 729946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 730946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 731946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#if DEBUG_FRAGS 732946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->numFragsEmitted = 0; 733946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->numFragsWritten = 0; 734946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#endif 735946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 736946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (cull_tri( setup, det )) 737946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return; 738946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 739946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (!setup_sort_vertices( setup, det, v0, v1, v2 )) 740946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return; 741946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup_tri_coefficients( setup ); 742946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup_tri_edges( setup ); 743946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 744946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.input.prim = QUAD_PRIM_TRI; 745946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 746946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->span.y = 0; 747946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->span.right[0] = 0; 748946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->span.right[1] = 0; 749946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* setup->span.z_mode = tri_z_mode( setup->ctx ); */ 750946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 751946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* init_constant_attribs( setup ); */ 752946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 753946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (setup->oneoverarea < 0.0) { 754946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* emaj on left: 755946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 756946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca subtriangle( setup, &setup->emaj, &setup->ebot, setup->ebot.lines ); 757946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca subtriangle( setup, &setup->emaj, &setup->etop, setup->etop.lines ); 758946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 759946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 760946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* emaj on right: 761946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 762946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca subtriangle( setup, &setup->ebot, &setup->emaj, setup->ebot.lines ); 763946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca subtriangle( setup, &setup->etop, &setup->emaj, setup->etop.lines ); 764946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 765946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 766946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca flush_spans( setup ); 767946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 768946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#if DEBUG_FRAGS 769946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca printf("Tri: %u frags emitted, %u written\n", 770946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->numFragsEmitted, 771946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->numFragsWritten); 772946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#endif 773946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 774946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 775946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 776946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 777946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 778946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Compute a0, dadx and dady for a linearly interpolated coefficient, 779946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * for a line. 780946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 781946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void 782946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecaline_linear_coeff(const struct setup_context *setup, 783946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct tgsi_interp_coef *coef, 784946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint vertSlot, uint i) 785946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 786946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float da = setup->vmax[vertSlot][i] - setup->vmin[vertSlot][i]; 787946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float dadx = da * setup->emaj.dx * setup->oneoverarea; 788946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float dady = da * setup->emaj.dy * setup->oneoverarea; 789946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->dadx[i] = dadx; 790946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->dady[i] = dady; 791946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->a0[i] = (setup->vmin[vertSlot][i] - 792946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca (dadx * (setup->vmin[0][0] - 0.5f) + 793946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dady * (setup->vmin[0][1] - 0.5f))); 794946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 795946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 796946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 797946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 798946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Compute a0, dadx and dady for a perspective-corrected interpolant, 799946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * for a line. 800946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 801946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void 802946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecaline_persp_coeff(const struct setup_context *setup, 803946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct tgsi_interp_coef *coef, 804946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint vertSlot, uint i) 805946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 806946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* XXX double-check/verify this arithmetic */ 807946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float a0 = setup->vmin[vertSlot][i] * setup->vmin[0][3]; 808946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float a1 = setup->vmax[vertSlot][i] * setup->vmax[0][3]; 809946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float da = a1 - a0; 810946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float dadx = da * setup->emaj.dx * setup->oneoverarea; 811946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float dady = da * setup->emaj.dy * setup->oneoverarea; 812946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->dadx[i] = dadx; 813946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->dady[i] = dady; 814946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->a0[i] = (setup->vmin[vertSlot][i] - 815946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca (dadx * (setup->vmin[0][0] - 0.5f) + 816946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dady * (setup->vmin[0][1] - 0.5f))); 817946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 818946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 819946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 820946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 821946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Compute the setup->coef[] array dadx, dady, a0 values. 822946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Must be called after setup->vmin,vmax are initialized. 823946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 824946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic INLINE boolean 825946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecasetup_line_coefficients(struct setup_context *setup, 826946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v0)[4], 827946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v1)[4]) 828946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 829946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct llvmpipe_context *llvmpipe = setup->llvmpipe; 830946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const struct lp_fragment_shader *lpfs = llvmpipe->fs; 831946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const struct vertex_info *vinfo = llvmpipe_get_vertex_info(llvmpipe); 832946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint fragSlot; 833946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float area; 834946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 835946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* use setup->vmin, vmax to point to vertices */ 836946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (llvmpipe->rasterizer->flatshade_first) 837946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vprovoke = v0; 838946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else 839946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vprovoke = v1; 840946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmin = v0; 841946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmax = v1; 842946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 843946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->emaj.dx = setup->vmax[0][0] - setup->vmin[0][0]; 844946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->emaj.dy = setup->vmax[0][1] - setup->vmin[0][1]; 845946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 846946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* NOTE: this is not really area but something proportional to it */ 847946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca area = setup->emaj.dx * setup->emaj.dx + setup->emaj.dy * setup->emaj.dy; 848946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (area == 0.0f || util_is_inf_or_nan(area)) 849946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return FALSE; 850946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->oneoverarea = 1.0f / area; 851946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 852946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* z and w are done by linear interpolation: 853946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 854946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca line_linear_coeff(setup, &setup->posCoef, 0, 2); 855946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca line_linear_coeff(setup, &setup->posCoef, 0, 3); 856946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 857946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* setup interpolation for all the remaining attributes: 858946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 859946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (fragSlot = 0; fragSlot < lpfs->info.num_inputs; fragSlot++) { 860946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const uint vertSlot = vinfo->attrib[fragSlot].src_index; 861946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint j; 862946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 863946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca switch (vinfo->attrib[fragSlot].interp_mode) { 864946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_CONSTANT: 865946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (j = 0; j < NUM_CHANNELS; j++) 866946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); 867946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 868946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_LINEAR: 869946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (j = 0; j < NUM_CHANNELS; j++) 870946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca line_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j); 871946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 872946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_PERSPECTIVE: 873946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (j = 0; j < NUM_CHANNELS; j++) 874946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca line_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j); 875946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 876946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_POS: 877946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup_fragcoord_coeff(setup, fragSlot); 878946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 879946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca default: 880946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(0); 881946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 882946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 883946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (lpfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { 884946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[fragSlot].a0[0] = 1.0f - setup->quad.input.facing; 885946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[fragSlot].dadx[0] = 0.0; 886946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[fragSlot].dady[0] = 0.0; 887946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 888946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 889946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return TRUE; 890946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 891946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 892946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 893946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 894946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Plot a pixel in a line segment. 895946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 896946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic INLINE void 897946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecaplot(struct setup_context *setup, int x, int y) 898946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 899946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int iy = y & 1; 900946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int ix = x & 1; 901946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int quadX = x - ix; 902946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int quadY = y - iy; 903946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int mask = (1 << ix) << (2 * iy); 904946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 905946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (quadX != setup->quad.input.x0 || 906946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca quadY != setup->quad.input.y0) 907946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca { 908946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* flush prev quad, start new quad */ 909946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 910946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (setup->quad.input.x0 != -1) 9114486012245c5f526059d3872ac3561f53705d1cfKeith Whitwell clip_emit_quad( setup, &setup->quad ); 912946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 913946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.input.x0 = quadX; 914946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.input.y0 = quadY; 915946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.inout.mask = 0x0; 916946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 917946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 918946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.inout.mask |= mask; 919946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 920946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 921946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 922946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 923946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Do setup for line rasterization, then render the line. 924946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Single-pixel width, no stipple, etc. We rely on the 'draw' module 925946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * to handle stippling and wide lines. 926946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 927946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecavoid 928946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecasetup_line(struct setup_context *setup, 929946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v0)[4], 930946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v1)[4]) 931946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 932946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int x0 = (int) v0[0][0]; 933946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int x1 = (int) v1[0][0]; 934946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int y0 = (int) v0[0][1]; 935946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int y1 = (int) v1[0][1]; 936946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int dx = x1 - x0; 937946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int dy = y1 - y0; 938946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int xstep, ystep; 939946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 940946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#if DEBUG_VERTS 941946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf("Setup line:\n"); 942946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca print_vertex(setup, v0); 943946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca print_vertex(setup, v1); 944946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#endif 945946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 946946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (setup->llvmpipe->no_rast) 947946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return; 948946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 949946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (dx == 0 && dy == 0) 950946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return; 951946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 952946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (!setup_line_coefficients(setup, v0, v1)) 953946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return; 954946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 955946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(v0[0][0] < 1.0e9); 956946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(v0[0][1] < 1.0e9); 957946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(v1[0][0] < 1.0e9); 958946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(v1[0][1] < 1.0e9); 959946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 960946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (dx < 0) { 961946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dx = -dx; /* make positive */ 962946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca xstep = -1; 963946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 964946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 965946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca xstep = 1; 966946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 967946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 968946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (dy < 0) { 969946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dy = -dy; /* make positive */ 970946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca ystep = -1; 971946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 972946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 973946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca ystep = 1; 974946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 975946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 976946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(dx >= 0); 977946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(dy >= 0); 978946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 979946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.input.x0 = setup->quad.input.y0 = -1; 980946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.inout.mask = 0x0; 981946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.input.prim = QUAD_PRIM_LINE; 982946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* XXX temporary: set coverage to 1.0 so the line appears 983946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * if AA mode happens to be enabled. 984946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 985946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.input.coverage[0] = 986946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.input.coverage[1] = 987946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.input.coverage[2] = 988946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.input.coverage[3] = 1.0; 989946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 990946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (dx > dy) { 991946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /*** X-major line ***/ 992946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int i; 993946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int errorInc = dy + dy; 994946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int error = errorInc - dx; 995946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int errorDec = error - dx; 996946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 997946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (i = 0; i < dx; i++) { 998946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca plot(setup, x0, y0); 999946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1000946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca x0 += xstep; 1001946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (error < 0) { 1002946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca error += errorInc; 1003946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1004946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 1005946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca error += errorDec; 1006946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca y0 += ystep; 1007946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1008946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1009946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1010946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 1011946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /*** Y-major line ***/ 1012946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int i; 1013946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int errorInc = dx + dx; 1014946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int error = errorInc - dy; 1015946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int errorDec = error - dy; 1016946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1017946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (i = 0; i < dy; i++) { 1018946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca plot(setup, x0, y0); 1019946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1020946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca y0 += ystep; 1021946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (error < 0) { 1022946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca error += errorInc; 1023946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1024946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 1025946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca error += errorDec; 1026946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca x0 += xstep; 1027946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1028946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1029946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1030946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1031946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* draw final quad */ 1032946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (setup->quad.inout.mask) { 10334486012245c5f526059d3872ac3561f53705d1cfKeith Whitwell clip_emit_quad( setup, &setup->quad ); 1034946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1035946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 1036946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1037946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1038946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void 1039946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecapoint_persp_coeff(const struct setup_context *setup, 1040946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*vert)[4], 1041946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct tgsi_interp_coef *coef, 1042946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint vertSlot, uint i) 1043946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 1044946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(i <= 3); 1045946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->dadx[i] = 0.0F; 1046946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->dady[i] = 0.0F; 1047946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->a0[i] = vert[vertSlot][i] * vert[0][3]; 1048946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 1049946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1050946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1051946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 1052946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Do setup for point rasterization, then render the point. 1053946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Round or square points... 1054946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * XXX could optimize a lot for 1-pixel points. 1055946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 1056946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecavoid 1057946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecasetup_point( struct setup_context *setup, 1058946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v0)[4] ) 1059946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 1060946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct llvmpipe_context *llvmpipe = setup->llvmpipe; 1061946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const struct lp_fragment_shader *lpfs = llvmpipe->fs; 1062946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int sizeAttr = setup->llvmpipe->psize_slot; 1063946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float size 1064946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca = sizeAttr > 0 ? v0[sizeAttr][0] 1065946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca : setup->llvmpipe->rasterizer->point_size; 1066946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float halfSize = 0.5F * size; 1067946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const boolean round = (boolean) setup->llvmpipe->rasterizer->point_smooth; 1068946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float x = v0[0][0]; /* Note: data[0] is always position */ 1069946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float y = v0[0][1]; 1070946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const struct vertex_info *vinfo = llvmpipe_get_vertex_info(llvmpipe); 1071946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint fragSlot; 1072946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1073946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#if DEBUG_VERTS 1074946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf("Setup point:\n"); 1075946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca print_vertex(setup, v0); 1076946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#endif 1077946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1078946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (llvmpipe->no_rast) 1079946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return; 1080946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1081946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* For points, all interpolants are constant-valued. 1082946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * However, for point sprites, we'll need to setup texcoords appropriately. 1083946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * XXX: which coefficients are the texcoords??? 1084946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * We may do point sprites as textured quads... 1085946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * 1086946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * KW: We don't know which coefficients are texcoords - ultimately 1087946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * the choice of what interpolation mode to use for each attribute 1088946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * should be determined by the fragment program, using 1089946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * per-attribute declaration statements that include interpolation 1090946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * mode as a parameter. So either the fragment program will have 1091946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * to be adjusted for pointsprite vs normal point behaviour, or 1092946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * otherwise a special interpolation mode will have to be defined 1093946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * which matches the required behaviour for point sprites. But - 1094946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * the latter is not a feature of normal hardware, and as such 1095946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * probably should be ruled out on that basis. 1096946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 1097946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vprovoke = v0; 1098946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1099946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* setup Z, W */ 1100946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const_coeff(setup, &setup->posCoef, 0, 2); 1101946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const_coeff(setup, &setup->posCoef, 0, 3); 1102946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1103946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (fragSlot = 0; fragSlot < lpfs->info.num_inputs; fragSlot++) { 1104946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const uint vertSlot = vinfo->attrib[fragSlot].src_index; 1105946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint j; 1106946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1107946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca switch (vinfo->attrib[fragSlot].interp_mode) { 1108946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_CONSTANT: 1109946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* fall-through */ 1110946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_LINEAR: 1111946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (j = 0; j < NUM_CHANNELS; j++) 1112946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); 1113946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 1114946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_PERSPECTIVE: 1115946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (j = 0; j < NUM_CHANNELS; j++) 1116946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca point_persp_coeff(setup, setup->vprovoke, 1117946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca &setup->coef[fragSlot], vertSlot, j); 1118946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 1119946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_POS: 1120946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup_fragcoord_coeff(setup, fragSlot); 1121946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 1122946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca default: 1123946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(0); 1124946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1125946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1126946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (lpfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { 1127946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[fragSlot].a0[0] = 1.0f - setup->quad.input.facing; 1128946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[fragSlot].dadx[0] = 0.0; 1129946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[fragSlot].dady[0] = 0.0; 1130946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1131946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1132946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1133946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.input.prim = QUAD_PRIM_POINT; 1134946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1135946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (halfSize <= 0.5 && !round) { 1136946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* special case for 1-pixel points */ 1137946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int ix = ((int) x) & 1; 1138946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int iy = ((int) y) & 1; 1139946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.input.x0 = (int) x - ix; 1140946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.input.y0 = (int) y - iy; 1141946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.inout.mask = (1 << ix) << (2 * iy); 11424486012245c5f526059d3872ac3561f53705d1cfKeith Whitwell clip_emit_quad( setup, &setup->quad ); 1143946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1144946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 1145946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (round) { 1146946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* rounded points */ 1147946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int ixmin = block((int) (x - halfSize)); 1148946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int ixmax = block((int) (x + halfSize)); 1149946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int iymin = block((int) (y - halfSize)); 1150946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int iymax = block((int) (y + halfSize)); 1151946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float rmin = halfSize - 0.7071F; /* 0.7071 = sqrt(2)/2 */ 1152946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float rmax = halfSize + 0.7071F; 1153946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float rmin2 = MAX2(0.0F, rmin * rmin); 1154946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float rmax2 = rmax * rmax; 1155946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float cscale = 1.0F / (rmax2 - rmin2); 1156946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int ix, iy; 1157946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1158946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (iy = iymin; iy <= iymax; iy += 2) { 1159946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (ix = ixmin; ix <= ixmax; ix += 2) { 1160946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float dx, dy, dist2, cover; 1161946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1162946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.inout.mask = 0x0; 1163946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1164946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dx = (ix + 0.5f) - x; 1165946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dy = (iy + 0.5f) - y; 1166946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dist2 = dx * dx + dy * dy; 1167946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (dist2 <= rmax2) { 1168946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca cover = 1.0F - (dist2 - rmin2) * cscale; 1169946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.input.coverage[QUAD_TOP_LEFT] = MIN2(cover, 1.0f); 1170946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.inout.mask |= MASK_TOP_LEFT; 1171946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1172946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1173946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dx = (ix + 1.5f) - x; 1174946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dy = (iy + 0.5f) - y; 1175946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dist2 = dx * dx + dy * dy; 1176946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (dist2 <= rmax2) { 1177946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca cover = 1.0F - (dist2 - rmin2) * cscale; 1178946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.input.coverage[QUAD_TOP_RIGHT] = MIN2(cover, 1.0f); 1179946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.inout.mask |= MASK_TOP_RIGHT; 1180946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1181946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1182946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dx = (ix + 0.5f) - x; 1183946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dy = (iy + 1.5f) - y; 1184946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dist2 = dx * dx + dy * dy; 1185946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (dist2 <= rmax2) { 1186946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca cover = 1.0F - (dist2 - rmin2) * cscale; 1187946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.input.coverage[QUAD_BOTTOM_LEFT] = MIN2(cover, 1.0f); 1188946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.inout.mask |= MASK_BOTTOM_LEFT; 1189946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1190946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1191946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dx = (ix + 1.5f) - x; 1192946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dy = (iy + 1.5f) - y; 1193946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dist2 = dx * dx + dy * dy; 1194946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (dist2 <= rmax2) { 1195946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca cover = 1.0F - (dist2 - rmin2) * cscale; 1196946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.input.coverage[QUAD_BOTTOM_RIGHT] = MIN2(cover, 1.0f); 1197946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.inout.mask |= MASK_BOTTOM_RIGHT; 1198946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1199946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1200946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (setup->quad.inout.mask) { 1201946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.input.x0 = ix; 1202946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.input.y0 = iy; 12034486012245c5f526059d3872ac3561f53705d1cfKeith Whitwell clip_emit_quad( setup, &setup->quad ); 1204946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1205946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1206946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1207946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1208946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 1209946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* square points */ 1210946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int xmin = (int) (x + 0.75 - halfSize); 1211946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int ymin = (int) (y + 0.25 - halfSize); 1212946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int xmax = xmin + (int) size; 1213946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int ymax = ymin + (int) size; 1214946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* XXX could apply scissor to xmin,ymin,xmax,ymax now */ 1215946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int ixmin = block(xmin); 1216946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int ixmax = block(xmax - 1); 1217946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int iymin = block(ymin); 1218946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int iymax = block(ymax - 1); 1219946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int ix, iy; 1220946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1221946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* 1222946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf("(%f, %f) -> X:%d..%d Y:%d..%d\n", x, y, xmin, xmax,ymin,ymax); 1223946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 1224946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (iy = iymin; iy <= iymax; iy += 2) { 1225946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint rowMask = 0xf; 1226946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (iy < ymin) { 1227946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* above the top edge */ 1228946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca rowMask &= (MASK_BOTTOM_LEFT | MASK_BOTTOM_RIGHT); 1229946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1230946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (iy + 1 >= ymax) { 1231946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* below the bottom edge */ 1232946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca rowMask &= (MASK_TOP_LEFT | MASK_TOP_RIGHT); 1233946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1234946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1235946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (ix = ixmin; ix <= ixmax; ix += 2) { 1236946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint mask = rowMask; 1237946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1238946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (ix < xmin) { 1239946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* fragment is past left edge of point, turn off left bits */ 1240946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca mask &= (MASK_BOTTOM_RIGHT | MASK_TOP_RIGHT); 1241946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1242946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (ix + 1 >= xmax) { 1243946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* past the right edge */ 1244946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca mask &= (MASK_BOTTOM_LEFT | MASK_TOP_LEFT); 1245946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1246946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1247946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.inout.mask = mask; 1248946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.input.x0 = ix; 1249946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.input.y0 = iy; 12504486012245c5f526059d3872ac3561f53705d1cfKeith Whitwell clip_emit_quad( setup, &setup->quad ); 1251946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1252946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1253946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1254946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1255946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 1256946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1257946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecavoid setup_prepare( struct setup_context *setup ) 1258946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 1259946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct llvmpipe_context *lp = setup->llvmpipe; 1260946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1261946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (lp->dirty) { 1262946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca llvmpipe_update_derived(lp); 1263946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1264946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1265946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* Note: nr_attrs is only used for debugging (vertex printing) */ 1266946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.nr_attrs = draw_num_vs_outputs(lp->draw); 1267946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 12684486012245c5f526059d3872ac3561f53705d1cfKeith Whitwell lp->quad.first->begin( lp->quad.first ); 1269946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1270946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (lp->reduced_api_prim == PIPE_PRIM_TRIANGLES && 1271946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca lp->rasterizer->fill_cw == PIPE_POLYGON_MODE_FILL && 1272946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca lp->rasterizer->fill_ccw == PIPE_POLYGON_MODE_FILL) { 1273946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* we'll do culling */ 1274946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->winding = lp->rasterizer->cull_mode; 1275946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1276946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 1277946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* 'draw' will do culling */ 1278946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->winding = PIPE_WINDING_NONE; 1279946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1280946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 1281946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1282946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1283946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1284946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecavoid setup_destroy_context( struct setup_context *setup ) 1285946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 1286946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca FREE( setup ); 1287946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 1288946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1289946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1290946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 1291946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Create a new primitive setup/render stage. 1292946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 1293946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastruct setup_context *setup_create_context( struct llvmpipe_context *llvmpipe ) 1294946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 1295946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct setup_context *setup = CALLOC_STRUCT(setup_context); 1296946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1297946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->llvmpipe = llvmpipe; 1298946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1299946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.coef = setup->coef; 1300946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->quad.posCoef = &setup->posCoef; 1301946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 130208811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell setup->span.left[0] = 1000000; /* greater than right[0] */ 130308811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell setup->span.left[1] = 1000000; /* greater than right[1] */ 130408811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell 1305946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return setup; 1306946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 1307946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1308