lp_setup.c revision 80eb276630a194632d9eba1e2b107d678d0f0a4d
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 6580eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell#define MAX_QUADS 16 6680eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell 67946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 68946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 69946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Triangle setup info (derived from draw_stage). 70946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Also used for line drawing (taking some liberties). 71946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 72946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastruct setup_context { 73946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct llvmpipe_context *llvmpipe; 74946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 75946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* Vertices are just an array of floats making up each attribute in 76946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * turn. Currently fixed at 4 floats, but should change in time. 77946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Codegen will help cope with this. 78946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 79946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*vmax)[4]; 80946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*vmid)[4]; 81946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*vmin)[4]; 82946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*vprovoke)[4]; 83946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 84946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct edge ebot; 85946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct edge etop; 86946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct edge emaj; 87946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 88946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float oneoverarea; 8980eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell int facing; 9080eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell 9180eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell struct quad_header quad[MAX_QUADS]; 9280eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell struct quad_header *quad_ptrs[MAX_QUADS]; 9380eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell unsigned count; 94946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 95946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct tgsi_interp_coef coef[PIPE_MAX_SHADER_INPUTS]; 96946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct tgsi_interp_coef posCoef; /* For Z, W */ 97946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 98946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct { 99946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int left[2]; /**< [0] = row0, [1] = row1 */ 100946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int right[2]; 101946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int y; 102946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } span; 103946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 104946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#if DEBUG_FRAGS 105946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint numFragsEmitted; /**< per primitive */ 106946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint numFragsWritten; /**< per primitive */ 107946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#endif 108946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 109946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca unsigned winding; /* which winding to cull */ 110946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca}; 111946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 112946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 113946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 114946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 115946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 116946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Do triangle cull test using tri determinant (sign indicates orientation) 117946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * \return true if triangle is to be culled. 118946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 119946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic INLINE boolean 120946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecacull_tri(const struct setup_context *setup, float det) 121946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 122946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (det != 0) { 123946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* if (det < 0 then Z points toward camera and triangle is 124946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * counter-clockwise winding. 125946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 126946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca unsigned winding = (det < 0) ? PIPE_WINDING_CCW : PIPE_WINDING_CW; 127946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 128946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if ((winding & setup->winding) == 0) 129946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return FALSE; 130946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 131946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 132946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* Culled: 133946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 134946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return TRUE; 135946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 136946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 137946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 138946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 139946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 140946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Clip setup->quad against the scissor/surface bounds. 141946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 142946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic INLINE void 143946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecaquad_clip( struct setup_context *setup, struct quad_header *quad ) 144946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 145946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const struct pipe_scissor_state *cliprect = &setup->llvmpipe->cliprect; 146946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int minx = (int) cliprect->minx; 147946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int maxx = (int) cliprect->maxx; 148946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int miny = (int) cliprect->miny; 149946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int maxy = (int) cliprect->maxy; 150946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 151946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (quad->input.x0 >= maxx || 152946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca quad->input.y0 >= maxy || 153946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca quad->input.x0 + 1 < minx || 154946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca quad->input.y0 + 1 < miny) { 155946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* totally clipped */ 156946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca quad->inout.mask = 0x0; 157946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return; 158946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 159946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (quad->input.x0 < minx) 160946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca quad->inout.mask &= (MASK_BOTTOM_RIGHT | MASK_TOP_RIGHT); 161946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (quad->input.y0 < miny) 162946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca quad->inout.mask &= (MASK_BOTTOM_LEFT | MASK_BOTTOM_RIGHT); 163946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (quad->input.x0 == maxx - 1) 164946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca quad->inout.mask &= (MASK_BOTTOM_LEFT | MASK_TOP_LEFT); 165946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (quad->input.y0 == maxy - 1) 166946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca quad->inout.mask &= (MASK_TOP_LEFT | MASK_TOP_RIGHT); 167946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 168946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 169946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 170946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 171946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Emit a quad (pass to next stage) with clipping. 172946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 173946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic INLINE void 1744486012245c5f526059d3872ac3561f53705d1cfKeith Whitwellclip_emit_quad( struct setup_context *setup, struct quad_header *quad ) 175946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 176946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca quad_clip( setup, quad ); 1774486012245c5f526059d3872ac3561f53705d1cfKeith Whitwell 178946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (quad->inout.mask) { 179946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct llvmpipe_context *lp = setup->llvmpipe; 180946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 181bdbb4beb21876010b14785569a920fa65a67d1adKeith Whitwell lp->quad.first->run( lp->quad.first, &quad, 1 ); 182946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 183946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 184946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 185946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 186946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 187946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 188946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Given an X or Y coordinate, return the block/quad coordinate that it 189946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * belongs to. 190946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 191946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic INLINE int block( int x ) 192946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 19380eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell return x & ~(2-1); 19480eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell} 19580eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell 19680eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwellstatic INLINE int block_x( int x ) 19780eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell{ 19880eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell return x & ~(16-1); 199946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 200946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 201946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 202946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 203946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Render a horizontal span of quads 204946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 205946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void flush_spans( struct setup_context *setup ) 206946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 20780eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell const int step = 16; 208946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int xleft0 = setup->span.left[0]; 209946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int xleft1 = setup->span.left[1]; 210946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int xright0 = setup->span.right[0]; 211946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int xright1 = setup->span.right[1]; 21280eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell struct quad_stage *pipe = setup->llvmpipe->quad.first; 21380eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell 21408811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell 21580eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell int minleft = block_x(MIN2(xleft0, xleft1)); 21608811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell int maxright = MAX2(xright0, xright1); 217946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int x; 218946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 21908811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell for (x = minleft; x < maxright; x += step) { 22008811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned skip_left0 = CLAMP(xleft0 - x, 0, step); 22108811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned skip_left1 = CLAMP(xleft1 - x, 0, step); 22208811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned skip_right0 = CLAMP(x + step - xright0, 0, step); 22308811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned skip_right1 = CLAMP(x + step - xright1, 0, step); 22408811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned lx = x; 22580eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell unsigned q = 0; 22680eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell 22708811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned skipmask_left0 = (1U << skip_left0) - 1U; 22808811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned skipmask_left1 = (1U << skip_left1) - 1U; 22908811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell 23008811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell /* These calculations fail when step == 32 and skip_right == 0. 23108811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell */ 23208811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned skipmask_right0 = ~0U << (unsigned)(step - skip_right0); 23308811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned skipmask_right1 = ~0U << (unsigned)(step - skip_right1); 23408811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell 23508811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned mask0 = ~skipmask_left0 & ~skipmask_right0; 23608811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned mask1 = ~skipmask_left1 & ~skipmask_right1; 23708811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell 23880eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell if (mask0 | mask1) { 23980eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell do { 24080eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell unsigned quadmask = (mask0 & 3) | ((mask1 & 3) << 2); 24180eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell if (quadmask) { 24280eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[q].input.x0 = lx; 24380eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[q].input.y0 = setup->span.y; 24480eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[q].inout.mask = quadmask; 24580eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad_ptrs[q] = &setup->quad[q]; 24680eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell q++; 24780eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell } 24880eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell mask0 >>= 2; 24980eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell mask1 >>= 2; 25080eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell lx += 2; 25180eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell } while (mask0 | mask1); 25280eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell 25380eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell pipe->run( pipe, setup->quad_ptrs, q ); 25408811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell } 255946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 256946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 2570aa24fa36f7aea8e25c392eeeef6f9c108f09abaKeith Whitwell 258946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->span.y = 0; 259946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->span.right[0] = 0; 260946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->span.right[1] = 0; 26108811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell setup->span.left[0] = 1000000; /* greater than right[0] */ 26208811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell setup->span.left[1] = 1000000; /* greater than right[1] */ 263946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 264946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 265946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 266946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#if DEBUG_VERTS 267946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void print_vertex(const struct setup_context *setup, 268946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v)[4]) 269946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 270946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int i; 271946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf(" Vertex: (%p)\n", v); 27280eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell for (i = 0; i < setup->quad[0].nr_attrs; i++) { 273946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf(" %d: %f %f %f %f\n", i, 274946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca v[i][0], v[i][1], v[i][2], v[i][3]); 275946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (util_is_inf_or_nan(v[i][0])) { 276946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf(" NaN!\n"); 277946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 278946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 279946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 280946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#endif 281946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 282946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 283946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Sort the vertices from top to bottom order, setting up the triangle 284946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * edge fields (ebot, emaj, etop). 285946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * \return FALSE if coords are inf/nan (cull the tri), TRUE otherwise 286946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 287946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic boolean setup_sort_vertices( struct setup_context *setup, 288946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float det, 289946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v0)[4], 290946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v1)[4], 291946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v2)[4] ) 292946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 293946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vprovoke = v2; 294946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 295946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* determine bottom to top order of vertices */ 296946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca { 297946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float y0 = v0[0][1]; 298946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float y1 = v1[0][1]; 299946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float y2 = v2[0][1]; 300946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (y0 <= y1) { 301946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (y1 <= y2) { 302946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* y0<=y1<=y2 */ 303946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmin = v0; 304946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmid = v1; 305946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmax = v2; 306946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 307946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else if (y2 <= y0) { 308946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* y2<=y0<=y1 */ 309946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmin = v2; 310946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmid = v0; 311946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmax = v1; 312946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 313946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 314946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* y0<=y2<=y1 */ 315946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmin = v0; 316946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmid = v2; 317946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmax = v1; 318946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 319946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 320946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 321946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (y0 <= y2) { 322946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* y1<=y0<=y2 */ 323946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmin = v1; 324946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmid = v0; 325946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmax = v2; 326946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 327946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else if (y2 <= y1) { 328946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* y2<=y1<=y0 */ 329946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmin = v2; 330946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmid = v1; 331946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmax = v0; 332946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 333946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 334946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* y1<=y2<=y0 */ 335946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmin = v1; 336946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmid = v2; 337946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmax = v0; 338946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 339946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 340946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 341946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 342946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->ebot.dx = setup->vmid[0][0] - setup->vmin[0][0]; 343946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->ebot.dy = setup->vmid[0][1] - setup->vmin[0][1]; 344946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->emaj.dx = setup->vmax[0][0] - setup->vmin[0][0]; 345946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->emaj.dy = setup->vmax[0][1] - setup->vmin[0][1]; 346946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->etop.dx = setup->vmax[0][0] - setup->vmid[0][0]; 347946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->etop.dy = setup->vmax[0][1] - setup->vmid[0][1]; 348946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 349946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* 350946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Compute triangle's area. Use 1/area to compute partial 351946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * derivatives of attributes later. 352946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * 353946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * The area will be the same as prim->det, but the sign may be 354946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * different depending on how the vertices get sorted above. 355946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * 356946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * To determine whether the primitive is front or back facing we 357946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * use the prim->det value because its sign is correct. 358946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 359946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca { 360946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float area = (setup->emaj.dx * setup->ebot.dy - 361946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->ebot.dx * setup->emaj.dy); 362946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 363946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->oneoverarea = 1.0f / area; 364946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 365946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* 366946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf("%s one-over-area %f area %f det %f\n", 367946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca __FUNCTION__, setup->oneoverarea, area, det ); 368946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 369946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (util_is_inf_or_nan(setup->oneoverarea)) 370946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return FALSE; 371946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 372946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 373946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* We need to know if this is a front or back-facing triangle for: 374946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * - the GLSL gl_FrontFacing fragment attribute (bool) 375946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * - two-sided stencil test 376946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 37780eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->facing = 37880eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell ((det > 0.0) ^ 37980eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell (setup->llvmpipe->rasterizer->front_winding == PIPE_WINDING_CW)); 380946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 381946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return TRUE; 382946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 383946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 384946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 385946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 386946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Compute a0 for a constant-valued coefficient (GL_FLAT shading). 387946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * The value value comes from vertex[slot][i]. 388946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * The result will be put into setup->coef[slot].a0[i]. 389946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * \param slot which attribute slot 390946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * \param i which component of the slot (0..3) 391946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 392946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void const_coeff( struct setup_context *setup, 393946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct tgsi_interp_coef *coef, 394946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint vertSlot, uint i) 395946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 396946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(i <= 3); 397946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 398946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->dadx[i] = 0; 399946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->dady[i] = 0; 400946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 401946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* need provoking vertex info! 402946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 403946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->a0[i] = setup->vprovoke[vertSlot][i]; 404946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 405946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 406946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 407946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 408946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Compute a0, dadx and dady for a linearly interpolated coefficient, 409946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * for a triangle. 410946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 411946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void tri_linear_coeff( struct setup_context *setup, 412946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct tgsi_interp_coef *coef, 413946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint vertSlot, uint i) 414946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 415946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float botda = setup->vmid[vertSlot][i] - setup->vmin[vertSlot][i]; 416946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float majda = setup->vmax[vertSlot][i] - setup->vmin[vertSlot][i]; 417946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float a = setup->ebot.dy * majda - botda * setup->emaj.dy; 418946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float b = setup->emaj.dx * botda - majda * setup->ebot.dx; 419946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float dadx = a * setup->oneoverarea; 420946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float dady = b * setup->oneoverarea; 421946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 422946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(i <= 3); 423946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 424946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->dadx[i] = dadx; 425946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->dady[i] = dady; 426946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 427946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* calculate a0 as the value which would be sampled for the 428946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * fragment at (0,0), taking into account that we want to sample at 429946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * pixel centers, in other words (0.5, 0.5). 430946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * 431946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * this is neat but unfortunately not a good way to do things for 432946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * triangles with very large values of dadx or dady as it will 433946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * result in the subtraction and re-addition from a0 of a very 434946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * large number, which means we'll end up loosing a lot of the 435946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * fractional bits and precision from a0. the way to fix this is 436946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * to define a0 as the sample at a pixel center somewhere near vmin 437946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * instead - i'll switch to this later. 438946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 439946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->a0[i] = (setup->vmin[vertSlot][i] - 440946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca (dadx * (setup->vmin[0][0] - 0.5f) + 441946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dady * (setup->vmin[0][1] - 0.5f))); 442946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 443946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* 444946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf("attr[%d].%c: %f dx:%f dy:%f\n", 445946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca slot, "xyzw"[i], 446946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[slot].a0[i], 447946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[slot].dadx[i], 448946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[slot].dady[i]); 449946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 450946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 451946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 452946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 453946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 454946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Compute a0, dadx and dady for a perspective-corrected interpolant, 455946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * for a triangle. 456946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * We basically multiply the vertex value by 1/w before computing 457946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * the plane coefficients (a0, dadx, dady). 458946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Later, when we compute the value at a particular fragment position we'll 459946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * divide the interpolated value by the interpolated W at that fragment. 460946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 461946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void tri_persp_coeff( struct setup_context *setup, 462946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct tgsi_interp_coef *coef, 463946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint vertSlot, uint i) 464946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 465946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* premultiply by 1/w (v[0][3] is always W): 466946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 467946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float mina = setup->vmin[vertSlot][i] * setup->vmin[0][3]; 468946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float mida = setup->vmid[vertSlot][i] * setup->vmid[0][3]; 469946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float maxa = setup->vmax[vertSlot][i] * setup->vmax[0][3]; 470946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float botda = mida - mina; 471946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float majda = maxa - mina; 472946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float a = setup->ebot.dy * majda - botda * setup->emaj.dy; 473946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float b = setup->emaj.dx * botda - majda * setup->ebot.dx; 474946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float dadx = a * setup->oneoverarea; 475946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float dady = b * setup->oneoverarea; 476946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 477946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* 478946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf("tri persp %d,%d: %f %f %f\n", vertSlot, i, 479946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmin[vertSlot][i], 480946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmid[vertSlot][i], 481946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmax[vertSlot][i] 482946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca ); 483946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 484946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(i <= 3); 485946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 486946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->dadx[i] = dadx; 487946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->dady[i] = dady; 488946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->a0[i] = (mina - 489946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca (dadx * (setup->vmin[0][0] - 0.5f) + 490946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dady * (setup->vmin[0][1] - 0.5f))); 491946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 492946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 493946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 494946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 495946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Special coefficient setup for gl_FragCoord. 496946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * X and Y are trivial, though Y has to be inverted for OpenGL. 497946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Z and W are copied from posCoef which should have already been computed. 498946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * We could do a bit less work if we'd examine gl_FragCoord's swizzle mask. 499946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 500946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void 501946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecasetup_fragcoord_coeff(struct setup_context *setup, uint slot) 502946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 503946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /*X*/ 504946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[slot].a0[0] = 0; 505946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[slot].dadx[0] = 1.0; 506946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[slot].dady[0] = 0.0; 507946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /*Y*/ 508946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[slot].a0[1] = 0.0; 509946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[slot].dadx[1] = 0.0; 510946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[slot].dady[1] = 1.0; 511946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /*Z*/ 512946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[slot].a0[2] = setup->posCoef.a0[2]; 513946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[slot].dadx[2] = setup->posCoef.dadx[2]; 514946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[slot].dady[2] = setup->posCoef.dady[2]; 515946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /*W*/ 516946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[slot].a0[3] = setup->posCoef.a0[3]; 517946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[slot].dadx[3] = setup->posCoef.dadx[3]; 518946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[slot].dady[3] = setup->posCoef.dady[3]; 519946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 520946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 521946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 522946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 523946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 524946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Compute the setup->coef[] array dadx, dady, a0 values. 525946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Must be called after setup->vmin,vmid,vmax,vprovoke are initialized. 526946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 527946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void setup_tri_coefficients( struct setup_context *setup ) 528946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 529946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct llvmpipe_context *llvmpipe = setup->llvmpipe; 530946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const struct lp_fragment_shader *lpfs = llvmpipe->fs; 531946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const struct vertex_info *vinfo = llvmpipe_get_vertex_info(llvmpipe); 532946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint fragSlot; 533946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 534946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* z and w are done by linear interpolation: 535946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 536946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca tri_linear_coeff(setup, &setup->posCoef, 0, 2); 537946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca tri_linear_coeff(setup, &setup->posCoef, 0, 3); 538946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 539946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* setup interpolation for all the remaining attributes: 540946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 541946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (fragSlot = 0; fragSlot < lpfs->info.num_inputs; fragSlot++) { 542946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const uint vertSlot = vinfo->attrib[fragSlot].src_index; 543946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint j; 544946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 545946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca switch (vinfo->attrib[fragSlot].interp_mode) { 546946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_CONSTANT: 547946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (j = 0; j < NUM_CHANNELS; j++) 548946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); 549946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 550946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_LINEAR: 551946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (j = 0; j < NUM_CHANNELS; j++) 552946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca tri_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j); 553946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 554946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_PERSPECTIVE: 555946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (j = 0; j < NUM_CHANNELS; j++) 556946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca tri_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j); 557946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 558946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_POS: 559946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup_fragcoord_coeff(setup, fragSlot); 560946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 561946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca default: 562946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(0); 563946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 564946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 565946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (lpfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { 56680eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->coef[fragSlot].a0[0] = 1.0f - setup->facing; 567946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[fragSlot].dadx[0] = 0.0; 568946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[fragSlot].dady[0] = 0.0; 569946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 570946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 571946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 572946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 573946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 574946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 575946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void setup_tri_edges( struct setup_context *setup ) 576946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 577946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float vmin_x = setup->vmin[0][0] + 0.5f; 578946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float vmid_x = setup->vmid[0][0] + 0.5f; 579946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 580946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float vmin_y = setup->vmin[0][1] - 0.5f; 581946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float vmid_y = setup->vmid[0][1] - 0.5f; 582946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float vmax_y = setup->vmax[0][1] - 0.5f; 583946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 584946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->emaj.sy = ceilf(vmin_y); 585946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->emaj.lines = (int) ceilf(vmax_y - setup->emaj.sy); 586946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->emaj.dxdy = setup->emaj.dx / setup->emaj.dy; 587946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->emaj.sx = vmin_x + (setup->emaj.sy - vmin_y) * setup->emaj.dxdy; 588946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 589946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->etop.sy = ceilf(vmid_y); 590946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->etop.lines = (int) ceilf(vmax_y - setup->etop.sy); 591946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->etop.dxdy = setup->etop.dx / setup->etop.dy; 592946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->etop.sx = vmid_x + (setup->etop.sy - vmid_y) * setup->etop.dxdy; 593946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 594946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->ebot.sy = ceilf(vmin_y); 595946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->ebot.lines = (int) ceilf(vmid_y - setup->ebot.sy); 596946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->ebot.dxdy = setup->ebot.dx / setup->ebot.dy; 597946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->ebot.sx = vmin_x + (setup->ebot.sy - vmin_y) * setup->ebot.dxdy; 598946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 599946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 600946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 601946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 602946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Render the upper or lower half of a triangle. 603946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Scissoring/cliprect is applied here too. 604946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 605946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void subtriangle( struct setup_context *setup, 606946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct edge *eleft, 607946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct edge *eright, 608946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca unsigned lines ) 609946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 610946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const struct pipe_scissor_state *cliprect = &setup->llvmpipe->cliprect; 611946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int minx = (int) cliprect->minx; 612946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int maxx = (int) cliprect->maxx; 613946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int miny = (int) cliprect->miny; 614946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int maxy = (int) cliprect->maxy; 615946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int y, start_y, finish_y; 616946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int sy = (int)eleft->sy; 617946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 618946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert((int)eleft->sy == (int) eright->sy); 619946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 620946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* clip top/bottom */ 621946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca start_y = sy; 622946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (start_y < miny) 623946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca start_y = miny; 624946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 62508811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell finish_y = sy + lines; 626946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (finish_y > maxy) 627946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca finish_y = maxy; 628946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 629946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca start_y -= sy; 630946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca finish_y -= sy; 631946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 632946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* 633946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf("%s %d %d\n", __FUNCTION__, start_y, finish_y); 634946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 635946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 636946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (y = start_y; y < finish_y; y++) { 637946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 638946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* avoid accumulating adds as floats don't have the precision to 639946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * accurately iterate large triangle edges that way. luckily we 640946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * can just multiply these days. 641946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * 642946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * this is all drowned out by the attribute interpolation anyway. 643946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 644946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int left = (int)(eleft->sx + y * eleft->dxdy); 645946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int right = (int)(eright->sx + y * eright->dxdy); 646946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 647946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* clip left/right */ 648946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (left < minx) 649946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca left = minx; 650946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (right > maxx) 651946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca right = maxx; 652946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 653946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (left < right) { 654946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int _y = sy + y; 655946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (block(_y) != setup->span.y) { 656946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca flush_spans(setup); 657946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->span.y = block(_y); 658946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 659946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 660946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->span.left[_y&1] = left; 661946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->span.right[_y&1] = right; 662946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 663946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 664946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 665946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 666946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* save the values so that emaj can be restarted: 667946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 668946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca eleft->sx += lines * eleft->dxdy; 669946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca eright->sx += lines * eright->dxdy; 670946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca eleft->sy += lines; 671946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca eright->sy += lines; 672946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 673946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 674946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 675946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 676946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Recalculate prim's determinant. This is needed as we don't have 677946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * get this information through the vbuf_render interface & we must 678946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * calculate it here. 679946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 680946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic float 681946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecacalc_det( const float (*v0)[4], 682946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v1)[4], 683946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v2)[4] ) 684946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 685946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* edge vectors e = v0 - v2, f = v1 - v2 */ 686946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float ex = v0[0][0] - v2[0][0]; 687946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float ey = v0[0][1] - v2[0][1]; 688946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float fx = v1[0][0] - v2[0][0]; 689946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float fy = v1[0][1] - v2[0][1]; 690946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 691946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* det = cross(e,f).z */ 692946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return ex * fy - ey * fx; 693946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 694946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 695946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 696946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 697946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Do setup for triangle rasterization, then render the triangle. 698946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 699946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecavoid setup_tri( struct setup_context *setup, 700946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v0)[4], 701946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v1)[4], 702946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v2)[4] ) 703946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 704946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float det; 705946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 706946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#if DEBUG_VERTS 707946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf("Setup triangle:\n"); 708946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca print_vertex(setup, v0); 709946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca print_vertex(setup, v1); 710946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca print_vertex(setup, v2); 711946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#endif 712946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 713946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (setup->llvmpipe->no_rast) 714946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return; 715946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 716946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca det = calc_det(v0, v1, v2); 717946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* 718946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf("%s\n", __FUNCTION__ ); 719946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 720946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 721946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#if DEBUG_FRAGS 722946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->numFragsEmitted = 0; 723946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->numFragsWritten = 0; 724946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#endif 725946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 726946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (cull_tri( setup, det )) 727946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return; 728946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 729946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (!setup_sort_vertices( setup, det, v0, v1, v2 )) 730946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return; 731946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup_tri_coefficients( setup ); 732946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup_tri_edges( setup ); 733946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 73480eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell assert(setup->llvmpipe->reduced_prim == PIPE_PRIM_TRIANGLES); 735946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 736946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->span.y = 0; 737946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->span.right[0] = 0; 738946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->span.right[1] = 0; 739946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* setup->span.z_mode = tri_z_mode( setup->ctx ); */ 740946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 741946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* init_constant_attribs( setup ); */ 742946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 743946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (setup->oneoverarea < 0.0) { 744946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* emaj on left: 745946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 746946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca subtriangle( setup, &setup->emaj, &setup->ebot, setup->ebot.lines ); 747946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca subtriangle( setup, &setup->emaj, &setup->etop, setup->etop.lines ); 748946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 749946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 750946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* emaj on right: 751946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 752946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca subtriangle( setup, &setup->ebot, &setup->emaj, setup->ebot.lines ); 753946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca subtriangle( setup, &setup->etop, &setup->emaj, setup->etop.lines ); 754946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 755946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 756946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca flush_spans( setup ); 757946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 758946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#if DEBUG_FRAGS 759946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca printf("Tri: %u frags emitted, %u written\n", 760946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->numFragsEmitted, 761946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->numFragsWritten); 762946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#endif 763946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 764946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 765946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 766946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 767946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 768946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Compute a0, dadx and dady for a linearly interpolated coefficient, 769946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * for a line. 770946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 771946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void 772946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecaline_linear_coeff(const struct setup_context *setup, 773946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct tgsi_interp_coef *coef, 774946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint vertSlot, uint i) 775946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 776946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float da = setup->vmax[vertSlot][i] - setup->vmin[vertSlot][i]; 777946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float dadx = da * setup->emaj.dx * setup->oneoverarea; 778946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float dady = da * setup->emaj.dy * setup->oneoverarea; 779946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->dadx[i] = dadx; 780946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->dady[i] = dady; 781946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->a0[i] = (setup->vmin[vertSlot][i] - 782946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca (dadx * (setup->vmin[0][0] - 0.5f) + 783946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dady * (setup->vmin[0][1] - 0.5f))); 784946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 785946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 786946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 787946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 788946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Compute a0, dadx and dady for a perspective-corrected interpolant, 789946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * for a line. 790946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 791946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void 792946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecaline_persp_coeff(const struct setup_context *setup, 793946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct tgsi_interp_coef *coef, 794946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint vertSlot, uint i) 795946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 796946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* XXX double-check/verify this arithmetic */ 797946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float a0 = setup->vmin[vertSlot][i] * setup->vmin[0][3]; 798946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float a1 = setup->vmax[vertSlot][i] * setup->vmax[0][3]; 799946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float da = a1 - a0; 800946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float dadx = da * setup->emaj.dx * setup->oneoverarea; 801946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float dady = da * setup->emaj.dy * setup->oneoverarea; 802946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->dadx[i] = dadx; 803946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->dady[i] = dady; 804946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->a0[i] = (setup->vmin[vertSlot][i] - 805946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca (dadx * (setup->vmin[0][0] - 0.5f) + 806946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dady * (setup->vmin[0][1] - 0.5f))); 807946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 808946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 809946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 810946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 811946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Compute the setup->coef[] array dadx, dady, a0 values. 812946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Must be called after setup->vmin,vmax are initialized. 813946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 814946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic INLINE boolean 815946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecasetup_line_coefficients(struct setup_context *setup, 816946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v0)[4], 817946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v1)[4]) 818946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 819946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct llvmpipe_context *llvmpipe = setup->llvmpipe; 820946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const struct lp_fragment_shader *lpfs = llvmpipe->fs; 821946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const struct vertex_info *vinfo = llvmpipe_get_vertex_info(llvmpipe); 822946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint fragSlot; 823946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float area; 824946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 825946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* use setup->vmin, vmax to point to vertices */ 826946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (llvmpipe->rasterizer->flatshade_first) 827946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vprovoke = v0; 828946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else 829946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vprovoke = v1; 830946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmin = v0; 831946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmax = v1; 832946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 833946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->emaj.dx = setup->vmax[0][0] - setup->vmin[0][0]; 834946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->emaj.dy = setup->vmax[0][1] - setup->vmin[0][1]; 835946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 836946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* NOTE: this is not really area but something proportional to it */ 837946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca area = setup->emaj.dx * setup->emaj.dx + setup->emaj.dy * setup->emaj.dy; 838946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (area == 0.0f || util_is_inf_or_nan(area)) 839946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return FALSE; 840946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->oneoverarea = 1.0f / area; 841946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 842946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* z and w are done by linear interpolation: 843946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 844946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca line_linear_coeff(setup, &setup->posCoef, 0, 2); 845946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca line_linear_coeff(setup, &setup->posCoef, 0, 3); 846946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 847946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* setup interpolation for all the remaining attributes: 848946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 849946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (fragSlot = 0; fragSlot < lpfs->info.num_inputs; fragSlot++) { 850946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const uint vertSlot = vinfo->attrib[fragSlot].src_index; 851946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint j; 852946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 853946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca switch (vinfo->attrib[fragSlot].interp_mode) { 854946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_CONSTANT: 855946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (j = 0; j < NUM_CHANNELS; j++) 856946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); 857946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 858946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_LINEAR: 859946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (j = 0; j < NUM_CHANNELS; j++) 860946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca line_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j); 861946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 862946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_PERSPECTIVE: 863946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (j = 0; j < NUM_CHANNELS; j++) 864946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca line_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j); 865946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 866946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_POS: 867946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup_fragcoord_coeff(setup, fragSlot); 868946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 869946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca default: 870946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(0); 871946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 872946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 873946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (lpfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { 87480eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->coef[fragSlot].a0[0] = 1.0f - setup->facing; 875946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[fragSlot].dadx[0] = 0.0; 876946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[fragSlot].dady[0] = 0.0; 877946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 878946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 879946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return TRUE; 880946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 881946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 882946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 883946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 884946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Plot a pixel in a line segment. 885946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 886946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic INLINE void 887946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecaplot(struct setup_context *setup, int x, int y) 888946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 889946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int iy = y & 1; 890946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int ix = x & 1; 891946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int quadX = x - ix; 892946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int quadY = y - iy; 893946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int mask = (1 << ix) << (2 * iy); 894946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 89580eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell if (quadX != setup->quad[0].input.x0 || 89680eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell quadY != setup->quad[0].input.y0) 897946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca { 898946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* flush prev quad, start new quad */ 899946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 90080eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell if (setup->quad[0].input.x0 != -1) 90180eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell clip_emit_quad( setup, &setup->quad[0] ); 902946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 90380eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.x0 = quadX; 90480eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.y0 = quadY; 90580eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].inout.mask = 0x0; 906946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 907946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 90880eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].inout.mask |= mask; 909946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 910946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 911946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 912946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 913946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Do setup for line rasterization, then render the line. 914946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Single-pixel width, no stipple, etc. We rely on the 'draw' module 915946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * to handle stippling and wide lines. 916946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 917946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecavoid 918946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecasetup_line(struct setup_context *setup, 919946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v0)[4], 920946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v1)[4]) 921946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 922946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int x0 = (int) v0[0][0]; 923946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int x1 = (int) v1[0][0]; 924946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int y0 = (int) v0[0][1]; 925946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int y1 = (int) v1[0][1]; 926946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int dx = x1 - x0; 927946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int dy = y1 - y0; 928946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int xstep, ystep; 929946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 930946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#if DEBUG_VERTS 931946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf("Setup line:\n"); 932946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca print_vertex(setup, v0); 933946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca print_vertex(setup, v1); 934946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#endif 935946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 936946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (setup->llvmpipe->no_rast) 937946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return; 938946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 939946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (dx == 0 && dy == 0) 940946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return; 941946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 942946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (!setup_line_coefficients(setup, v0, v1)) 943946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return; 944946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 945946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(v0[0][0] < 1.0e9); 946946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(v0[0][1] < 1.0e9); 947946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(v1[0][0] < 1.0e9); 948946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(v1[0][1] < 1.0e9); 949946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 950946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (dx < 0) { 951946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dx = -dx; /* make positive */ 952946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca xstep = -1; 953946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 954946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 955946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca xstep = 1; 956946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 957946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 958946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (dy < 0) { 959946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dy = -dy; /* make positive */ 960946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca ystep = -1; 961946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 962946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 963946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca ystep = 1; 964946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 965946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 966946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(dx >= 0); 967946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(dy >= 0); 96880eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell assert(setup->llvmpipe->reduced_prim == PIPE_PRIM_LINES); 96980eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell 97080eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.x0 = setup->quad[0].input.y0 = -1; 97180eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].inout.mask = 0x0; 972946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 973946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* XXX temporary: set coverage to 1.0 so the line appears 974946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * if AA mode happens to be enabled. 975946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 97680eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.coverage[0] = 97780eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.coverage[1] = 97880eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.coverage[2] = 97980eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.coverage[3] = 1.0; 980946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 981946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (dx > dy) { 982946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /*** X-major line ***/ 983946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int i; 984946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int errorInc = dy + dy; 985946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int error = errorInc - dx; 986946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int errorDec = error - dx; 987946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 988946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (i = 0; i < dx; i++) { 989946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca plot(setup, x0, y0); 990946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 991946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca x0 += xstep; 992946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (error < 0) { 993946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca error += errorInc; 994946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 995946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 996946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca error += errorDec; 997946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca y0 += ystep; 998946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 999946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1000946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1001946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 1002946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /*** Y-major line ***/ 1003946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int i; 1004946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int errorInc = dx + dx; 1005946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int error = errorInc - dy; 1006946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int errorDec = error - dy; 1007946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1008946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (i = 0; i < dy; i++) { 1009946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca plot(setup, x0, y0); 1010946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1011946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca y0 += ystep; 1012946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (error < 0) { 1013946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca error += errorInc; 1014946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1015946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 1016946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca error += errorDec; 1017946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca x0 += xstep; 1018946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1019946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1020946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1021946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1022946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* draw final quad */ 102380eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell if (setup->quad[0].inout.mask) { 102480eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell clip_emit_quad( setup, &setup->quad[0] ); 1025946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1026946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 1027946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1028946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1029946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void 1030946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecapoint_persp_coeff(const struct setup_context *setup, 1031946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*vert)[4], 1032946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct tgsi_interp_coef *coef, 1033946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint vertSlot, uint i) 1034946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 1035946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(i <= 3); 1036946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->dadx[i] = 0.0F; 1037946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->dady[i] = 0.0F; 1038946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca coef->a0[i] = vert[vertSlot][i] * vert[0][3]; 1039946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 1040946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1041946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1042946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 1043946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Do setup for point rasterization, then render the point. 1044946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Round or square points... 1045946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * XXX could optimize a lot for 1-pixel points. 1046946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 1047946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecavoid 1048946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecasetup_point( struct setup_context *setup, 1049946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v0)[4] ) 1050946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 1051946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct llvmpipe_context *llvmpipe = setup->llvmpipe; 1052946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const struct lp_fragment_shader *lpfs = llvmpipe->fs; 1053946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int sizeAttr = setup->llvmpipe->psize_slot; 1054946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float size 1055946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca = sizeAttr > 0 ? v0[sizeAttr][0] 1056946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca : setup->llvmpipe->rasterizer->point_size; 1057946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float halfSize = 0.5F * size; 1058946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const boolean round = (boolean) setup->llvmpipe->rasterizer->point_smooth; 1059946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float x = v0[0][0]; /* Note: data[0] is always position */ 1060946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float y = v0[0][1]; 1061946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const struct vertex_info *vinfo = llvmpipe_get_vertex_info(llvmpipe); 1062946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint fragSlot; 1063946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1064946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#if DEBUG_VERTS 1065946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf("Setup point:\n"); 1066946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca print_vertex(setup, v0); 1067946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#endif 1068946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1069946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (llvmpipe->no_rast) 1070946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return; 1071946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 107280eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell assert(setup->llvmpipe->reduced_prim == PIPE_PRIM_POINTS); 107380eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell 1074946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* For points, all interpolants are constant-valued. 1075946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * However, for point sprites, we'll need to setup texcoords appropriately. 1076946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * XXX: which coefficients are the texcoords??? 1077946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * We may do point sprites as textured quads... 1078946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * 1079946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * KW: We don't know which coefficients are texcoords - ultimately 1080946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * the choice of what interpolation mode to use for each attribute 1081946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * should be determined by the fragment program, using 1082946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * per-attribute declaration statements that include interpolation 1083946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * mode as a parameter. So either the fragment program will have 1084946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * to be adjusted for pointsprite vs normal point behaviour, or 1085946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * otherwise a special interpolation mode will have to be defined 1086946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * which matches the required behaviour for point sprites. But - 1087946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * the latter is not a feature of normal hardware, and as such 1088946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * probably should be ruled out on that basis. 1089946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 1090946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vprovoke = v0; 1091946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1092946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* setup Z, W */ 1093946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const_coeff(setup, &setup->posCoef, 0, 2); 1094946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const_coeff(setup, &setup->posCoef, 0, 3); 1095946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1096946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (fragSlot = 0; fragSlot < lpfs->info.num_inputs; fragSlot++) { 1097946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const uint vertSlot = vinfo->attrib[fragSlot].src_index; 1098946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint j; 1099946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1100946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca switch (vinfo->attrib[fragSlot].interp_mode) { 1101946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_CONSTANT: 1102946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* fall-through */ 1103946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_LINEAR: 1104946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (j = 0; j < NUM_CHANNELS; j++) 1105946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); 1106946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 1107946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_PERSPECTIVE: 1108946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (j = 0; j < NUM_CHANNELS; j++) 1109946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca point_persp_coeff(setup, setup->vprovoke, 1110946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca &setup->coef[fragSlot], vertSlot, j); 1111946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 1112946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_POS: 1113946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup_fragcoord_coeff(setup, fragSlot); 1114946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 1115946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca default: 1116946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(0); 1117946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1118946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1119946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (lpfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { 112080eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->coef[fragSlot].a0[0] = 1.0f - setup->facing; 1121946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[fragSlot].dadx[0] = 0.0; 1122946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->coef[fragSlot].dady[0] = 0.0; 1123946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1124946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1125946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1126946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1127946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (halfSize <= 0.5 && !round) { 1128946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* special case for 1-pixel points */ 1129946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int ix = ((int) x) & 1; 1130946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int iy = ((int) y) & 1; 113180eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.x0 = (int) x - ix; 113280eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.y0 = (int) y - iy; 113380eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].inout.mask = (1 << ix) << (2 * iy); 113480eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell clip_emit_quad( setup, &setup->quad[0] ); 1135946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1136946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 1137946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (round) { 1138946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* rounded points */ 1139946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int ixmin = block((int) (x - halfSize)); 1140946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int ixmax = block((int) (x + halfSize)); 1141946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int iymin = block((int) (y - halfSize)); 1142946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int iymax = block((int) (y + halfSize)); 1143946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float rmin = halfSize - 0.7071F; /* 0.7071 = sqrt(2)/2 */ 1144946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float rmax = halfSize + 0.7071F; 1145946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float rmin2 = MAX2(0.0F, rmin * rmin); 1146946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float rmax2 = rmax * rmax; 1147946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float cscale = 1.0F / (rmax2 - rmin2); 1148946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int ix, iy; 1149946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1150946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (iy = iymin; iy <= iymax; iy += 2) { 1151946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (ix = ixmin; ix <= ixmax; ix += 2) { 1152946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float dx, dy, dist2, cover; 1153946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 115480eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].inout.mask = 0x0; 1155946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1156946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dx = (ix + 0.5f) - x; 1157946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dy = (iy + 0.5f) - y; 1158946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dist2 = dx * dx + dy * dy; 1159946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (dist2 <= rmax2) { 1160946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca cover = 1.0F - (dist2 - rmin2) * cscale; 116180eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.coverage[QUAD_TOP_LEFT] = MIN2(cover, 1.0f); 116280eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].inout.mask |= MASK_TOP_LEFT; 1163946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1164946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1165946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dx = (ix + 1.5f) - x; 1166946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dy = (iy + 0.5f) - y; 1167946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dist2 = dx * dx + dy * dy; 1168946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (dist2 <= rmax2) { 1169946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca cover = 1.0F - (dist2 - rmin2) * cscale; 117080eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.coverage[QUAD_TOP_RIGHT] = MIN2(cover, 1.0f); 117180eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].inout.mask |= MASK_TOP_RIGHT; 1172946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1173946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1174946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dx = (ix + 0.5f) - x; 1175946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dy = (iy + 1.5f) - y; 1176946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dist2 = dx * dx + dy * dy; 1177946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (dist2 <= rmax2) { 1178946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca cover = 1.0F - (dist2 - rmin2) * cscale; 117980eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.coverage[QUAD_BOTTOM_LEFT] = MIN2(cover, 1.0f); 118080eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].inout.mask |= MASK_BOTTOM_LEFT; 1181946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1182946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1183946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dx = (ix + 1.5f) - x; 1184946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dy = (iy + 1.5f) - y; 1185946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dist2 = dx * dx + dy * dy; 1186946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (dist2 <= rmax2) { 1187946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca cover = 1.0F - (dist2 - rmin2) * cscale; 118880eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.coverage[QUAD_BOTTOM_RIGHT] = MIN2(cover, 1.0f); 118980eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].inout.mask |= MASK_BOTTOM_RIGHT; 1190946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1191946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 119280eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell if (setup->quad[0].inout.mask) { 119380eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.x0 = ix; 119480eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.y0 = iy; 119580eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell clip_emit_quad( setup, &setup->quad[0] ); 1196946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1197946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1198946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1199946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1200946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 1201946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* square points */ 1202946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int xmin = (int) (x + 0.75 - halfSize); 1203946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int ymin = (int) (y + 0.25 - halfSize); 1204946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int xmax = xmin + (int) size; 1205946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int ymax = ymin + (int) size; 1206946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* XXX could apply scissor to xmin,ymin,xmax,ymax now */ 1207946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int ixmin = block(xmin); 1208946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int ixmax = block(xmax - 1); 1209946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int iymin = block(ymin); 1210946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int iymax = block(ymax - 1); 1211946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int ix, iy; 1212946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1213946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* 1214946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf("(%f, %f) -> X:%d..%d Y:%d..%d\n", x, y, xmin, xmax,ymin,ymax); 1215946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 1216946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (iy = iymin; iy <= iymax; iy += 2) { 1217946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint rowMask = 0xf; 1218946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (iy < ymin) { 1219946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* above the top edge */ 1220946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca rowMask &= (MASK_BOTTOM_LEFT | MASK_BOTTOM_RIGHT); 1221946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1222946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (iy + 1 >= ymax) { 1223946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* below the bottom edge */ 1224946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca rowMask &= (MASK_TOP_LEFT | MASK_TOP_RIGHT); 1225946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1226946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1227946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (ix = ixmin; ix <= ixmax; ix += 2) { 1228946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint mask = rowMask; 1229946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1230946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (ix < xmin) { 1231946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* fragment is past left edge of point, turn off left bits */ 1232946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca mask &= (MASK_BOTTOM_RIGHT | MASK_TOP_RIGHT); 1233946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1234946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (ix + 1 >= xmax) { 1235946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* past the right edge */ 1236946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca mask &= (MASK_BOTTOM_LEFT | MASK_TOP_LEFT); 1237946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1238946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 123980eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].inout.mask = mask; 124080eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.x0 = ix; 124180eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.y0 = iy; 124280eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell clip_emit_quad( setup, &setup->quad[0] ); 1243946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1244946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1245946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1246946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1247946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 1248946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1249946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecavoid setup_prepare( struct setup_context *setup ) 1250946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 1251946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct llvmpipe_context *lp = setup->llvmpipe; 1252946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1253946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (lp->dirty) { 1254946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca llvmpipe_update_derived(lp); 1255946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1256946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 12574486012245c5f526059d3872ac3561f53705d1cfKeith Whitwell lp->quad.first->begin( lp->quad.first ); 1258946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1259946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (lp->reduced_api_prim == PIPE_PRIM_TRIANGLES && 1260946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca lp->rasterizer->fill_cw == PIPE_POLYGON_MODE_FILL && 1261946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca lp->rasterizer->fill_ccw == PIPE_POLYGON_MODE_FILL) { 1262946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* we'll do culling */ 1263946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->winding = lp->rasterizer->cull_mode; 1264946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1265946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 1266946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* 'draw' will do culling */ 1267946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->winding = PIPE_WINDING_NONE; 1268946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1269946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 1270946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1271946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1272946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1273946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecavoid setup_destroy_context( struct setup_context *setup ) 1274946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 1275946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca FREE( setup ); 1276946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 1277946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1278946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1279946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 1280946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Create a new primitive setup/render stage. 1281946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 1282946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastruct setup_context *setup_create_context( struct llvmpipe_context *llvmpipe ) 1283946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 1284946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct setup_context *setup = CALLOC_STRUCT(setup_context); 128580eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell unsigned i; 1286946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1287946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->llvmpipe = llvmpipe; 1288946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 128980eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell for (i = 0; i < MAX_QUADS; i++) { 129080eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[i].coef = setup->coef; 129180eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[i].posCoef = &setup->posCoef; 129280eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell } 1293946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 129408811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell setup->span.left[0] = 1000000; /* greater than right[0] */ 129508811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell setup->span.left[1] = 1000000; /* greater than right[1] */ 129608811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell 1297946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return setup; 1298946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 1299946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1300