lp_setup.c revision 4d2b0eb19e432f83845a55d552b5d1d61f040459
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_setup.h" 39946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#include "lp_state.h" 40946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#include "draw/draw_context.h" 41946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#include "draw/draw_private.h" 42946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#include "draw/draw_vertex.h" 43946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#include "pipe/p_shader_tokens.h" 44946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#include "pipe/p_thread.h" 45946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#include "util/u_math.h" 46946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#include "util/u_memory.h" 474d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca#include "lp_tile_cache.h" 483014919211b361817c5365f7cbb8d2ef8ca61234José Fonseca#include "lp_tile_soa.h" 49946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 50946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 51946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#define DEBUG_VERTS 0 52946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#define DEBUG_FRAGS 0 53946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 54946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 55946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Triangle edge info 56946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 57946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastruct edge { 58946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float dx; /**< X(v1) - X(v0), used only during setup */ 59946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float dy; /**< Y(v1) - Y(v0), used only during setup */ 60946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float dxdy; /**< dx/dy */ 61946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float sx, sy; /**< first sample point coord */ 62946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int lines; /**< number of lines on this edge */ 63946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca}; 64946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 65946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 6680eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell#define MAX_QUADS 16 6780eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell 68946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 69946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 70946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Triangle setup info (derived from draw_stage). 71946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Also used for line drawing (taking some liberties). 72946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 73946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastruct setup_context { 74946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct llvmpipe_context *llvmpipe; 75946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 76946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* Vertices are just an array of floats making up each attribute in 77946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * turn. Currently fixed at 4 floats, but should change in time. 78946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Codegen will help cope with this. 79946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 80946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*vmax)[4]; 81946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*vmid)[4]; 82946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*vmin)[4]; 83946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*vprovoke)[4]; 84946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 85946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct edge ebot; 86946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct edge etop; 87946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct edge emaj; 88946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 89946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float oneoverarea; 9080eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell int facing; 9180eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell 9280eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell struct quad_header quad[MAX_QUADS]; 9380eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell struct quad_header *quad_ptrs[MAX_QUADS]; 9480eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell unsigned count; 95946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 9617aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca struct quad_interp_coef coef; 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 1144d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca/** 1154d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca * Execute fragment shader for the four fragments in the quad. 1164d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca */ 1174d2b0eb19e432f83845a55d552b5d1d61f040459José Fonsecastatic void 1184d2b0eb19e432f83845a55d552b5d1d61f040459José Fonsecashade_quads(struct llvmpipe_context *llvmpipe, 1194d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca struct quad_header *quads[], 1204d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca unsigned nr) 1214d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca{ 1224d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca struct lp_fragment_shader *fs = llvmpipe->fs; 1234d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca void *constants; 1244d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca struct tgsi_sampler **samplers; 1254d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca struct quad_header *quad = quads[0]; 1264d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca const unsigned x = quad->input.x0; 1274d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca const unsigned y = quad->input.y0; 1284d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca uint8_t *tile = lp_get_cached_tile(llvmpipe->cbuf_cache[0], x, y); 1294d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca uint8_t *color; 1304d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca void *depth; 1314d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca uint32_t ALIGN16_ATTRIB mask[4][NUM_CHANNELS]; 1324d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca unsigned chan_index; 1334d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca unsigned q; 1344d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca 1354d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca assert(fs->current); 1364d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca if(!fs->current) 1374d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca return; 1384d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca 1394d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca /* Sanity checks */ 1404d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca assert(nr * QUAD_SIZE == TILE_VECTOR_HEIGHT * TILE_VECTOR_WIDTH); 1414d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca assert(x % TILE_VECTOR_WIDTH == 0); 1424d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca assert(y % TILE_VECTOR_HEIGHT == 0); 1434d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca for (q = 0; q < nr; ++q) { 1444d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca assert(quads[q]->input.x0 == x + q*2); 1454d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca assert(quads[q]->input.y0 == y); 1464d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca } 1474d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca 1484d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca /* mask */ 1494d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca for (q = 0; q < 4; ++q) 1504d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca for (chan_index = 0; chan_index < NUM_CHANNELS; ++chan_index) 1514d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca mask[q][chan_index] = quads[q]->inout.mask & (1 << chan_index) ? ~0 : 0; 1524d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca 1534d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca /* color buffer */ 1544d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca color = &TILE_PIXEL(tile, x & (TILE_SIZE-1), y & (TILE_SIZE-1), 0); 1554d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca 1564d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca /* depth buffer */ 1574d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca if(llvmpipe->zsbuf_map) { 1584d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca assert((x % 2) == 0); 1594d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca assert((y % 2) == 0); 1604d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca depth = llvmpipe->zsbuf_map + 1614d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca y*llvmpipe->zsbuf_transfer->stride + 1624d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca 2*x*llvmpipe->zsbuf_transfer->block.size; 1634d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca } 1644d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca else 1654d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca depth = NULL; 1664d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca 1674d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca constants = llvmpipe->mapped_constants[PIPE_SHADER_FRAGMENT]; 1684d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca samplers = (struct tgsi_sampler **)llvmpipe->tgsi.frag_samplers_list; 1694d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca /* TODO: blend color */ 1704d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca 1714d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca assert((((uintptr_t)mask) & 0xf) == 0); 1724d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca assert((((uintptr_t)depth) & 0xf) == 0); 1734d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca assert((((uintptr_t)color) & 0xf) == 0); 1744d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca assert((((uintptr_t)llvmpipe->blend_color) & 0xf) == 0); 1754d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca 1764d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca /* run shader */ 1774d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca fs->current->jit_function( x, 1784d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca y, 1794d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca quad->coef->a0, 1804d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca quad->coef->dadx, 1814d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca quad->coef->dady, 1824d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca constants, 1834d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca &mask[0][0], 1844d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca color, 1854d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca depth, 1864d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca samplers); 1874d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca} 1884d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca 1894d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca 1904d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca 191946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 192946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 193946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Do triangle cull test using tri determinant (sign indicates orientation) 194946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * \return true if triangle is to be culled. 195946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 196946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic INLINE boolean 197946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecacull_tri(const struct setup_context *setup, float det) 198946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 199946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (det != 0) { 200946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* if (det < 0 then Z points toward camera and triangle is 201946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * counter-clockwise winding. 202946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 203946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca unsigned winding = (det < 0) ? PIPE_WINDING_CCW : PIPE_WINDING_CW; 204946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 205946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if ((winding & setup->winding) == 0) 206946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return FALSE; 207946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 208946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 209946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* Culled: 210946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 211946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return TRUE; 212946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 213946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 214946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 215946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 216946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 217946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Clip setup->quad against the scissor/surface bounds. 218946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 219946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic INLINE void 220946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecaquad_clip( struct setup_context *setup, struct quad_header *quad ) 221946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 222946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const struct pipe_scissor_state *cliprect = &setup->llvmpipe->cliprect; 223946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int minx = (int) cliprect->minx; 224946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int maxx = (int) cliprect->maxx; 225946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int miny = (int) cliprect->miny; 226946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int maxy = (int) cliprect->maxy; 227946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 228946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (quad->input.x0 >= maxx || 229946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca quad->input.y0 >= maxy || 230946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca quad->input.x0 + 1 < minx || 231946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca quad->input.y0 + 1 < miny) { 232946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* totally clipped */ 233946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca quad->inout.mask = 0x0; 234946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return; 235946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 236946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (quad->input.x0 < minx) 237946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca quad->inout.mask &= (MASK_BOTTOM_RIGHT | MASK_TOP_RIGHT); 238946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (quad->input.y0 < miny) 239946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca quad->inout.mask &= (MASK_BOTTOM_LEFT | MASK_BOTTOM_RIGHT); 240946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (quad->input.x0 == maxx - 1) 241946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca quad->inout.mask &= (MASK_BOTTOM_LEFT | MASK_TOP_LEFT); 242946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (quad->input.y0 == maxy - 1) 243946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca quad->inout.mask &= (MASK_TOP_LEFT | MASK_TOP_RIGHT); 244946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 245946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 246946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 247946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 248946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 249946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Given an X or Y coordinate, return the block/quad coordinate that it 250946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * belongs to. 251946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 252946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic INLINE int block( int x ) 253946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 25480eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell return x & ~(2-1); 25580eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell} 25680eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell 25780eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwellstatic INLINE int block_x( int x ) 25880eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell{ 2593014919211b361817c5365f7cbb8d2ef8ca61234José Fonseca return x & ~(TILE_VECTOR_WIDTH - 1); 260946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 261946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 262946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 263946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 264b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca * Emit a quad (pass to next stage) with clipping. 265b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca */ 266b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonsecastatic INLINE void 267b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonsecaclip_emit_quad( struct setup_context *setup, struct quad_header *quad ) 268b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca{ 269b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca quad_clip( setup, quad ); 270b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca 271b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca if (quad->inout.mask) { 272b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca struct llvmpipe_context *lp = setup->llvmpipe; 273b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca 274b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca#if 1 275b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca /* XXX: The blender expects 4 quads. This is far from efficient, but 276b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca * until we codegenerate single-quad variants of the fragment pipeline 277b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca * we need this hack. */ 278b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca const unsigned nr_quads = TILE_VECTOR_HEIGHT*TILE_VECTOR_WIDTH/QUAD_SIZE; 279b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca struct quad_header quads[nr_quads]; 280b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca struct quad_header *quad_ptrs[nr_quads]; 281b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca int x0 = block_x(quad->input.x0); 282b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca unsigned i; 283b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca 284b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca for(i = 0; i < nr_quads; ++i) { 285b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca int x = x0 + 2*i; 286b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca if(x == quad->input.x0) 287b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca memcpy(&quads[i], quad, sizeof quads[i]); 288b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca else { 289b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca memset(&quads[i], 0, sizeof quads[i]); 290b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca quads[i].input.x0 = x; 291b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca quads[i].input.y0 = quad->input.y0; 292b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca quads[i].coef = quad->coef; 293b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca } 294b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca quad_ptrs[i] = &quads[i]; 295b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca } 296b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca 2974d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca shade_quads( lp, quad_ptrs, nr_quads ); 298b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca#else 2994d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca shade_quads( lp, &quad, 1 ); 300b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca#endif 301b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca } 302b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca} 303b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca 304b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca 305b9f2f01315646c3af92e64152f51a593b65a5ac7José Fonseca/** 306946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Render a horizontal span of quads 307946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 308946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void flush_spans( struct setup_context *setup ) 309946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 3103014919211b361817c5365f7cbb8d2ef8ca61234José Fonseca const int step = TILE_VECTOR_WIDTH; 311946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int xleft0 = setup->span.left[0]; 312946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int xleft1 = setup->span.left[1]; 313946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int xright0 = setup->span.right[0]; 314946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int xright1 = setup->span.right[1]; 31580eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell 31608811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell 31780eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell int minleft = block_x(MIN2(xleft0, xleft1)); 31808811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell int maxright = MAX2(xright0, xright1); 319946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int x; 320946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 32108811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell for (x = minleft; x < maxright; x += step) { 32208811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned skip_left0 = CLAMP(xleft0 - x, 0, step); 32308811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned skip_left1 = CLAMP(xleft1 - x, 0, step); 32408811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned skip_right0 = CLAMP(x + step - xright0, 0, step); 32508811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned skip_right1 = CLAMP(x + step - xright1, 0, step); 32608811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned lx = x; 3273014919211b361817c5365f7cbb8d2ef8ca61234José Fonseca const unsigned nr_quads = TILE_VECTOR_HEIGHT*TILE_VECTOR_WIDTH/QUAD_SIZE; 32880eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell unsigned q = 0; 32980eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell 33008811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned skipmask_left0 = (1U << skip_left0) - 1U; 33108811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned skipmask_left1 = (1U << skip_left1) - 1U; 33208811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell 33308811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell /* These calculations fail when step == 32 and skip_right == 0. 33408811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell */ 33508811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned skipmask_right0 = ~0U << (unsigned)(step - skip_right0); 33608811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned skipmask_right1 = ~0U << (unsigned)(step - skip_right1); 33708811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell 33808811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned mask0 = ~skipmask_left0 & ~skipmask_right0; 33908811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell unsigned mask1 = ~skipmask_left1 & ~skipmask_right1; 34008811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell 34180eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell if (mask0 | mask1) { 3423014919211b361817c5365f7cbb8d2ef8ca61234José Fonseca for(q = 0; q < nr_quads; ++q) { 34380eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell unsigned quadmask = (mask0 & 3) | ((mask1 & 3) << 2); 3443014919211b361817c5365f7cbb8d2ef8ca61234José Fonseca setup->quad[q].input.x0 = lx; 3453014919211b361817c5365f7cbb8d2ef8ca61234José Fonseca setup->quad[q].input.y0 = setup->span.y; 3463014919211b361817c5365f7cbb8d2ef8ca61234José Fonseca setup->quad[q].inout.mask = quadmask; 3473014919211b361817c5365f7cbb8d2ef8ca61234José Fonseca setup->quad_ptrs[q] = &setup->quad[q]; 34880eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell mask0 >>= 2; 34980eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell mask1 >>= 2; 35080eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell lx += 2; 3513014919211b361817c5365f7cbb8d2ef8ca61234José Fonseca } 3523014919211b361817c5365f7cbb8d2ef8ca61234José Fonseca assert(!(mask0 | mask1)); 35380eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell 3544d2b0eb19e432f83845a55d552b5d1d61f040459José Fonseca shade_quads(setup->llvmpipe, setup->quad_ptrs, nr_quads ); 35508811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell } 356946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 357946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 3580aa24fa36f7aea8e25c392eeeef6f9c108f09abaKeith Whitwell 359946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->span.y = 0; 360946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->span.right[0] = 0; 361946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->span.right[1] = 0; 36208811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell setup->span.left[0] = 1000000; /* greater than right[0] */ 36308811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell setup->span.left[1] = 1000000; /* greater than right[1] */ 364946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 365946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 366946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 367946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#if DEBUG_VERTS 368946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void print_vertex(const struct setup_context *setup, 369946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v)[4]) 370946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 371946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int i; 372946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf(" Vertex: (%p)\n", v); 37380eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell for (i = 0; i < setup->quad[0].nr_attrs; i++) { 374946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf(" %d: %f %f %f %f\n", i, 375946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca v[i][0], v[i][1], v[i][2], v[i][3]); 376946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (util_is_inf_or_nan(v[i][0])) { 377946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf(" NaN!\n"); 378946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 379946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 380946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 381946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#endif 382946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 383946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 384946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Sort the vertices from top to bottom order, setting up the triangle 385946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * edge fields (ebot, emaj, etop). 386946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * \return FALSE if coords are inf/nan (cull the tri), TRUE otherwise 387946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 388946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic boolean setup_sort_vertices( struct setup_context *setup, 389946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float det, 390946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v0)[4], 391946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v1)[4], 392946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v2)[4] ) 393946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 394946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vprovoke = v2; 395946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 396946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* determine bottom to top order of vertices */ 397946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca { 398946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float y0 = v0[0][1]; 399946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float y1 = v1[0][1]; 400946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float y2 = v2[0][1]; 401946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (y0 <= y1) { 402946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (y1 <= y2) { 403946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* y0<=y1<=y2 */ 404946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmin = v0; 405946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmid = v1; 406946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmax = v2; 407946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 408946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else if (y2 <= y0) { 409946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* y2<=y0<=y1 */ 410946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmin = v2; 411946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmid = v0; 412946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmax = v1; 413946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 414946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 415946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* y0<=y2<=y1 */ 416946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmin = v0; 417946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmid = v2; 418946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmax = v1; 419946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 420946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 421946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 422946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (y0 <= y2) { 423946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* y1<=y0<=y2 */ 424946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmin = v1; 425946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmid = v0; 426946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmax = v2; 427946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 428946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else if (y2 <= y1) { 429946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* y2<=y1<=y0 */ 430946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmin = v2; 431946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmid = v1; 432946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmax = v0; 433946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 434946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 435946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* y1<=y2<=y0 */ 436946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmin = v1; 437946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmid = v2; 438946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmax = v0; 439946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 440946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 441946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 442946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 443946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->ebot.dx = setup->vmid[0][0] - setup->vmin[0][0]; 444946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->ebot.dy = setup->vmid[0][1] - setup->vmin[0][1]; 445946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->emaj.dx = setup->vmax[0][0] - setup->vmin[0][0]; 446946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->emaj.dy = setup->vmax[0][1] - setup->vmin[0][1]; 447946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->etop.dx = setup->vmax[0][0] - setup->vmid[0][0]; 448946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->etop.dy = setup->vmax[0][1] - setup->vmid[0][1]; 449946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 450946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* 451946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Compute triangle's area. Use 1/area to compute partial 452946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * derivatives of attributes later. 453946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * 454946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * The area will be the same as prim->det, but the sign may be 455946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * different depending on how the vertices get sorted above. 456946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * 457946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * To determine whether the primitive is front or back facing we 458946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * use the prim->det value because its sign is correct. 459946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 460946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca { 461946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float area = (setup->emaj.dx * setup->ebot.dy - 462946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->ebot.dx * setup->emaj.dy); 463946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 464946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->oneoverarea = 1.0f / area; 465946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 466946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* 467946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf("%s one-over-area %f area %f det %f\n", 468946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca __FUNCTION__, setup->oneoverarea, area, det ); 469946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 470946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (util_is_inf_or_nan(setup->oneoverarea)) 471946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return FALSE; 472946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 473946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 474946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* We need to know if this is a front or back-facing triangle for: 475946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * - the GLSL gl_FrontFacing fragment attribute (bool) 476946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * - two-sided stencil test 477946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 47880eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->facing = 47980eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell ((det > 0.0) ^ 48080eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell (setup->llvmpipe->rasterizer->front_winding == PIPE_WINDING_CW)); 481946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 482946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return TRUE; 483946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 484946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 485946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 486946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 487946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Compute a0, dadx and dady for a linearly interpolated coefficient, 488946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * for a triangle. 489946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 49017aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonsecastatic void tri_pos_coeff( struct setup_context *setup, 49117aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca uint vertSlot, unsigned i) 492946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 493946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float botda = setup->vmid[vertSlot][i] - setup->vmin[vertSlot][i]; 494946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float majda = setup->vmax[vertSlot][i] - setup->vmin[vertSlot][i]; 495946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float a = setup->ebot.dy * majda - botda * setup->emaj.dy; 496946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float b = setup->emaj.dx * botda - majda * setup->ebot.dx; 497946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float dadx = a * setup->oneoverarea; 498946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float dady = b * setup->oneoverarea; 499946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 500946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(i <= 3); 501946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 50217baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.dadx[0][i] = dadx; 50317baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.dady[0][i] = dady; 504946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 505946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* calculate a0 as the value which would be sampled for the 506946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * fragment at (0,0), taking into account that we want to sample at 507946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * pixel centers, in other words (0.5, 0.5). 508946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * 509946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * this is neat but unfortunately not a good way to do things for 510946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * triangles with very large values of dadx or dady as it will 511946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * result in the subtraction and re-addition from a0 of a very 512946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * large number, which means we'll end up loosing a lot of the 513946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * fractional bits and precision from a0. the way to fix this is 514946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * to define a0 as the sample at a pixel center somewhere near vmin 515946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * instead - i'll switch to this later. 516946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 51717baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.a0[0][i] = (setup->vmin[vertSlot][i] - 51817aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca (dadx * (setup->vmin[0][0] - 0.5f) + 51917aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca dady * (setup->vmin[0][1] - 0.5f))); 520946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 521946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* 522946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf("attr[%d].%c: %f dx:%f dy:%f\n", 52317aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca slot, "xyzw"[i], 52417aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca setup->coef[slot].a0[i], 52517aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca setup->coef[slot].dadx[i], 52617aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca setup->coef[slot].dady[i]); 527946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 528946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 529946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 530946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 531946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 53217aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca * Compute a0 for a constant-valued coefficient (GL_FLAT shading). 53317aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca * The value value comes from vertex[slot][i]. 53417aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca * The result will be put into setup->coef[slot].a0[i]. 53517aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca * \param slot which attribute slot 53617aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca * \param i which component of the slot (0..3) 53717aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca */ 53817aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonsecastatic void const_pos_coeff( struct setup_context *setup, 53917aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca uint vertSlot, unsigned i) 54017aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca{ 54117baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.dadx[0][i] = 0; 54217baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.dady[0][i] = 0; 54317aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca 54417aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca /* need provoking vertex info! 54517aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca */ 54617baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.a0[0][i] = setup->vprovoke[vertSlot][i]; 54717aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca} 54817aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca 54917aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca 55017aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca/** 55117aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca * Compute a0 for a constant-valued coefficient (GL_FLAT shading). 55217aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca * The value value comes from vertex[slot][i]. 55317aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca * The result will be put into setup->coef[slot].a0[i]. 55417aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca * \param slot which attribute slot 55517aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca * \param i which component of the slot (0..3) 55617aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca */ 55717aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonsecastatic void const_coeff( struct setup_context *setup, 55817aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca unsigned attrib, 55917aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca uint vertSlot) 56017aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca{ 56117aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca unsigned i; 56217aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca for (i = 0; i < NUM_CHANNELS; ++i) { 56317baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.dadx[1 + attrib][i] = 0; 56417baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.dady[1 + attrib][i] = 0; 56517aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca 56617aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca /* need provoking vertex info! 56717aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca */ 56817baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.a0[1 + attrib][i] = setup->vprovoke[vertSlot][i]; 56917aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca } 57017aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca} 57117aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca 57217aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca 57317aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca/** 57417aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca * Compute a0, dadx and dady for a linearly interpolated coefficient, 57517aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca * for a triangle. 57617aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca */ 57717aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonsecastatic void tri_linear_coeff( struct setup_context *setup, 57817aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca unsigned attrib, 57917aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca uint vertSlot) 58017aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca{ 58117aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca unsigned i; 58217aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca for (i = 0; i < NUM_CHANNELS; ++i) { 58317aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca float botda = setup->vmid[vertSlot][i] - setup->vmin[vertSlot][i]; 58417aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca float majda = setup->vmax[vertSlot][i] - setup->vmin[vertSlot][i]; 58517aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca float a = setup->ebot.dy * majda - botda * setup->emaj.dy; 58617aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca float b = setup->emaj.dx * botda - majda * setup->ebot.dx; 58717aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca float dadx = a * setup->oneoverarea; 58817aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca float dady = b * setup->oneoverarea; 58917aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca 59017aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca assert(i <= 3); 59117aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca 59217baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.dadx[1 + attrib][i] = dadx; 59317baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.dady[1 + attrib][i] = dady; 59417aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca 59517aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca /* calculate a0 as the value which would be sampled for the 59617aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca * fragment at (0,0), taking into account that we want to sample at 59717aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca * pixel centers, in other words (0.5, 0.5). 59817aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca * 59917aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca * this is neat but unfortunately not a good way to do things for 60017aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca * triangles with very large values of dadx or dady as it will 60117aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca * result in the subtraction and re-addition from a0 of a very 60217aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca * large number, which means we'll end up loosing a lot of the 60317aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca * fractional bits and precision from a0. the way to fix this is 60417aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca * to define a0 as the sample at a pixel center somewhere near vmin 60517aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca * instead - i'll switch to this later. 60617aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca */ 60717baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.a0[1 + attrib][i] = (setup->vmin[vertSlot][i] - 60817aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca (dadx * (setup->vmin[0][0] - 0.5f) + 60917aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca dady * (setup->vmin[0][1] - 0.5f))); 61017aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca 61117aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca /* 61217aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca debug_printf("attr[%d].%c: %f dx:%f dy:%f\n", 61317aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca slot, "xyzw"[i], 61417aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca setup->coef[slot].a0[i], 61517aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca setup->coef[slot].dadx[i], 61617aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca setup->coef[slot].dady[i]); 61717aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca */ 61817aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca } 61917aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca} 62017aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca 62117aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca 62217aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca/** 623946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Compute a0, dadx and dady for a perspective-corrected interpolant, 624946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * for a triangle. 625946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * We basically multiply the vertex value by 1/w before computing 626946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * the plane coefficients (a0, dadx, dady). 627946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Later, when we compute the value at a particular fragment position we'll 628946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * divide the interpolated value by the interpolated W at that fragment. 629946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 630946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void tri_persp_coeff( struct setup_context *setup, 63117aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca unsigned attrib, 63217aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca uint vertSlot) 633946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 63417aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca unsigned i; 63517aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca for (i = 0; i < NUM_CHANNELS; ++i) { 63617aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca /* premultiply by 1/w (v[0][3] is always W): 63717aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca */ 63817aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca float mina = setup->vmin[vertSlot][i] * setup->vmin[0][3]; 63917aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca float mida = setup->vmid[vertSlot][i] * setup->vmid[0][3]; 64017aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca float maxa = setup->vmax[vertSlot][i] * setup->vmax[0][3]; 64117aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca float botda = mida - mina; 64217aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca float majda = maxa - mina; 64317aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca float a = setup->ebot.dy * majda - botda * setup->emaj.dy; 64417aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca float b = setup->emaj.dx * botda - majda * setup->ebot.dx; 64517aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca float dadx = a * setup->oneoverarea; 64617aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca float dady = b * setup->oneoverarea; 647946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 64817aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca /* 64917aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca debug_printf("tri persp %d,%d: %f %f %f\n", vertSlot, i, 65017aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca setup->vmin[vertSlot][i], 65117aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca setup->vmid[vertSlot][i], 65217aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca setup->vmax[vertSlot][i] 65317aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca ); 65417aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca */ 65517aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca assert(i <= 3); 656946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 65717baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.dadx[1 + attrib][i] = dadx; 65817baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.dady[1 + attrib][i] = dady; 65917baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.a0[1 + attrib][i] = (mina - 66017aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca (dadx * (setup->vmin[0][0] - 0.5f) + 66117aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca dady * (setup->vmin[0][1] - 0.5f))); 66217aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca } 663946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 664946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 665946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 666946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 667946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Special coefficient setup for gl_FragCoord. 668946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * X and Y are trivial, though Y has to be inverted for OpenGL. 669946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Z and W are copied from posCoef which should have already been computed. 670946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * We could do a bit less work if we'd examine gl_FragCoord's swizzle mask. 671946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 672946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void 673946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecasetup_fragcoord_coeff(struct setup_context *setup, uint slot) 674946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 675946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /*X*/ 67617baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.a0[1 + slot][0] = 0; 67717baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.dadx[1 + slot][0] = 1.0; 67817baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.dady[1 + slot][0] = 0.0; 679946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /*Y*/ 68017baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.a0[1 + slot][1] = 0.0; 68117baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.dadx[1 + slot][1] = 0.0; 68217baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.dady[1 + slot][1] = 1.0; 683946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /*Z*/ 68417baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.a0[1 + slot][2] = setup->coef.a0[0][2]; 68517baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.dadx[1 + slot][2] = setup->coef.dadx[0][2]; 68617baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.dady[1 + slot][2] = setup->coef.dady[0][2]; 687946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /*W*/ 68817baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.a0[1 + slot][3] = setup->coef.a0[0][3]; 68917baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.dadx[1 + slot][3] = setup->coef.dadx[0][3]; 69017baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.dady[1 + slot][3] = setup->coef.dady[0][3]; 691946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 692946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 693946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 694946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 695946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 696946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Compute the setup->coef[] array dadx, dady, a0 values. 697946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Must be called after setup->vmin,vmid,vmax,vprovoke are initialized. 698946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 699946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void setup_tri_coefficients( struct setup_context *setup ) 700946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 701946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct llvmpipe_context *llvmpipe = setup->llvmpipe; 702946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const struct lp_fragment_shader *lpfs = llvmpipe->fs; 703946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const struct vertex_info *vinfo = llvmpipe_get_vertex_info(llvmpipe); 704946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint fragSlot; 705946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 706946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* z and w are done by linear interpolation: 707946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 70817aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca tri_pos_coeff(setup, 0, 2); 70917aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca tri_pos_coeff(setup, 0, 3); 710946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 711946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* setup interpolation for all the remaining attributes: 712946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 713946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (fragSlot = 0; fragSlot < lpfs->info.num_inputs; fragSlot++) { 714946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const uint vertSlot = vinfo->attrib[fragSlot].src_index; 715946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 716946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca switch (vinfo->attrib[fragSlot].interp_mode) { 717946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_CONSTANT: 71817aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca const_coeff(setup, fragSlot, vertSlot); 719946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 720946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_LINEAR: 72117aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca tri_linear_coeff(setup, fragSlot, vertSlot); 722946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 723946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_PERSPECTIVE: 72417aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca tri_persp_coeff(setup, fragSlot, vertSlot); 725946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 726946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_POS: 727946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup_fragcoord_coeff(setup, fragSlot); 728946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 729946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca default: 730946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(0); 731946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 732946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 733946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (lpfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { 73417baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.a0[1 + fragSlot][0] = 1.0f - setup->facing; 73517baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.dadx[1 + fragSlot][0] = 0.0; 73617baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.dady[1 + fragSlot][0] = 0.0; 737946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 738946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 739946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 740946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 741946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 742946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 743946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void setup_tri_edges( struct setup_context *setup ) 744946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 745946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float vmin_x = setup->vmin[0][0] + 0.5f; 746946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float vmid_x = setup->vmid[0][0] + 0.5f; 747946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 748946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float vmin_y = setup->vmin[0][1] - 0.5f; 749946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float vmid_y = setup->vmid[0][1] - 0.5f; 750946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float vmax_y = setup->vmax[0][1] - 0.5f; 751946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 752946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->emaj.sy = ceilf(vmin_y); 753946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->emaj.lines = (int) ceilf(vmax_y - setup->emaj.sy); 754946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->emaj.dxdy = setup->emaj.dx / setup->emaj.dy; 755946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->emaj.sx = vmin_x + (setup->emaj.sy - vmin_y) * setup->emaj.dxdy; 756946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 757946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->etop.sy = ceilf(vmid_y); 758946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->etop.lines = (int) ceilf(vmax_y - setup->etop.sy); 759946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->etop.dxdy = setup->etop.dx / setup->etop.dy; 760946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->etop.sx = vmid_x + (setup->etop.sy - vmid_y) * setup->etop.dxdy; 761946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 762946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->ebot.sy = ceilf(vmin_y); 763946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->ebot.lines = (int) ceilf(vmid_y - setup->ebot.sy); 764946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->ebot.dxdy = setup->ebot.dx / setup->ebot.dy; 765946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->ebot.sx = vmin_x + (setup->ebot.sy - vmin_y) * setup->ebot.dxdy; 766946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 767946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 768946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 769946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 770946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Render the upper or lower half of a triangle. 771946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Scissoring/cliprect is applied here too. 772946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 773946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void subtriangle( struct setup_context *setup, 774946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct edge *eleft, 775946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct edge *eright, 776946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca unsigned lines ) 777946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 778946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const struct pipe_scissor_state *cliprect = &setup->llvmpipe->cliprect; 779946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int minx = (int) cliprect->minx; 780946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int maxx = (int) cliprect->maxx; 781946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int miny = (int) cliprect->miny; 782946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int maxy = (int) cliprect->maxy; 783946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int y, start_y, finish_y; 784946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int sy = (int)eleft->sy; 785946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 786946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert((int)eleft->sy == (int) eright->sy); 787946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 788946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* clip top/bottom */ 789946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca start_y = sy; 790946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (start_y < miny) 791946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca start_y = miny; 792946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 79308811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell finish_y = sy + lines; 794946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (finish_y > maxy) 795946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca finish_y = maxy; 796946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 797946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca start_y -= sy; 798946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca finish_y -= sy; 799946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 800946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* 801946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf("%s %d %d\n", __FUNCTION__, start_y, finish_y); 802946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 803946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 804946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (y = start_y; y < finish_y; y++) { 805946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 806946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* avoid accumulating adds as floats don't have the precision to 807946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * accurately iterate large triangle edges that way. luckily we 808946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * can just multiply these days. 809946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * 810946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * this is all drowned out by the attribute interpolation anyway. 811946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 812946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int left = (int)(eleft->sx + y * eleft->dxdy); 813946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int right = (int)(eright->sx + y * eright->dxdy); 814946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 815946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* clip left/right */ 816946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (left < minx) 817946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca left = minx; 818946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (right > maxx) 819946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca right = maxx; 820946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 821946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (left < right) { 822946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int _y = sy + y; 823946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (block(_y) != setup->span.y) { 824946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca flush_spans(setup); 825946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->span.y = block(_y); 826946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 827946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 828946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->span.left[_y&1] = left; 829946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->span.right[_y&1] = right; 830946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 831946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 832946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 833946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 834946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* save the values so that emaj can be restarted: 835946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 836946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca eleft->sx += lines * eleft->dxdy; 837946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca eright->sx += lines * eright->dxdy; 838946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca eleft->sy += lines; 839946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca eright->sy += lines; 840946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 841946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 842946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 843946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 844946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Recalculate prim's determinant. This is needed as we don't have 845946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * get this information through the vbuf_render interface & we must 846946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * calculate it here. 847946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 848946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic float 849946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecacalc_det( const float (*v0)[4], 850946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v1)[4], 851946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v2)[4] ) 852946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 853946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* edge vectors e = v0 - v2, f = v1 - v2 */ 854946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float ex = v0[0][0] - v2[0][0]; 855946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float ey = v0[0][1] - v2[0][1]; 856946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float fx = v1[0][0] - v2[0][0]; 857946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float fy = v1[0][1] - v2[0][1]; 858946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 859946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* det = cross(e,f).z */ 860946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return ex * fy - ey * fx; 861946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 862946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 863946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 864946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 865946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Do setup for triangle rasterization, then render the triangle. 866946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 867908d8d7a1b01214116e358d7641cc097212aeb50Brian Paulvoid llvmpipe_setup_tri( struct setup_context *setup, 868946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v0)[4], 869946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v1)[4], 870946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v2)[4] ) 871946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 872946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float det; 873946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 874946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#if DEBUG_VERTS 875946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf("Setup triangle:\n"); 876946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca print_vertex(setup, v0); 877946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca print_vertex(setup, v1); 878946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca print_vertex(setup, v2); 879946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#endif 880946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 881946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (setup->llvmpipe->no_rast) 882946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return; 883946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 884946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca det = calc_det(v0, v1, v2); 885946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* 886946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf("%s\n", __FUNCTION__ ); 887946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 888946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 889946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#if DEBUG_FRAGS 890946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->numFragsEmitted = 0; 891946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->numFragsWritten = 0; 892946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#endif 893946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 894946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (cull_tri( setup, det )) 895946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return; 896946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 897946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (!setup_sort_vertices( setup, det, v0, v1, v2 )) 898946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return; 899946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup_tri_coefficients( setup ); 900946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup_tri_edges( setup ); 901946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 90280eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell assert(setup->llvmpipe->reduced_prim == PIPE_PRIM_TRIANGLES); 903946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 904946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->span.y = 0; 905946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->span.right[0] = 0; 906946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->span.right[1] = 0; 907946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* setup->span.z_mode = tri_z_mode( setup->ctx ); */ 908946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 909946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* init_constant_attribs( setup ); */ 910946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 911946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (setup->oneoverarea < 0.0) { 912946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* emaj on left: 913946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 914946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca subtriangle( setup, &setup->emaj, &setup->ebot, setup->ebot.lines ); 915946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca subtriangle( setup, &setup->emaj, &setup->etop, setup->etop.lines ); 916946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 917946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 918946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* emaj on right: 919946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 920946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca subtriangle( setup, &setup->ebot, &setup->emaj, setup->ebot.lines ); 921946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca subtriangle( setup, &setup->etop, &setup->emaj, setup->etop.lines ); 922946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 923946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 924946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca flush_spans( setup ); 925946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 926946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#if DEBUG_FRAGS 927946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca printf("Tri: %u frags emitted, %u written\n", 928946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->numFragsEmitted, 929946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->numFragsWritten); 930946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#endif 931946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 932946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 933946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 934946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 935946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 936946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Compute a0, dadx and dady for a linearly interpolated coefficient, 937946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * for a line. 938946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 939946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void 94017aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonsecalinear_pos_coeff(struct setup_context *setup, 94117aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca uint vertSlot, uint i) 942946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 943946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float da = setup->vmax[vertSlot][i] - setup->vmin[vertSlot][i]; 944946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float dadx = da * setup->emaj.dx * setup->oneoverarea; 945946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float dady = da * setup->emaj.dy * setup->oneoverarea; 94617baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.dadx[0][i] = dadx; 94717baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.dady[0][i] = dady; 94817baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.a0[0][i] = (setup->vmin[vertSlot][i] - 94917aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca (dadx * (setup->vmin[0][0] - 0.5f) + 95017aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca dady * (setup->vmin[0][1] - 0.5f))); 95117aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca} 95217aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca 95317aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca 95417aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca/** 95517aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca * Compute a0, dadx and dady for a linearly interpolated coefficient, 95617aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca * for a line. 95717aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca */ 95817aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonsecastatic void 95917aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonsecaline_linear_coeff(struct setup_context *setup, 96017aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca unsigned attrib, 96117aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca uint vertSlot) 96217aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca{ 96317aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca unsigned i; 96417aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca for (i = 0; i < NUM_CHANNELS; ++i) { 96517aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca const float da = setup->vmax[vertSlot][i] - setup->vmin[vertSlot][i]; 96617aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca const float dadx = da * setup->emaj.dx * setup->oneoverarea; 96717aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca const float dady = da * setup->emaj.dy * setup->oneoverarea; 96817baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.dadx[1 + attrib][i] = dadx; 96917baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.dady[1 + attrib][i] = dady; 97017baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.a0[1 + attrib][i] = (setup->vmin[vertSlot][i] - 97117aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca (dadx * (setup->vmin[0][0] - 0.5f) + 97217aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca dady * (setup->vmin[0][1] - 0.5f))); 97317aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca } 974946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 975946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 976946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 977946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 978946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Compute a0, dadx and dady for a perspective-corrected interpolant, 979946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * for a line. 980946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 981946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void 98217aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonsecaline_persp_coeff(struct setup_context *setup, 98317aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca unsigned attrib, 98417aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca uint vertSlot) 985946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 98617aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca unsigned i; 98717aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca for (i = 0; i < NUM_CHANNELS; ++i) { 98817aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca /* XXX double-check/verify this arithmetic */ 98917aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca const float a0 = setup->vmin[vertSlot][i] * setup->vmin[0][3]; 99017aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca const float a1 = setup->vmax[vertSlot][i] * setup->vmax[0][3]; 99117aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca const float da = a1 - a0; 99217aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca const float dadx = da * setup->emaj.dx * setup->oneoverarea; 99317aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca const float dady = da * setup->emaj.dy * setup->oneoverarea; 99417baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.dadx[1 + attrib][i] = dadx; 99517baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.dady[1 + attrib][i] = dady; 99617baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.a0[1 + attrib][i] = (setup->vmin[vertSlot][i] - 99717aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca (dadx * (setup->vmin[0][0] - 0.5f) + 99817aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca dady * (setup->vmin[0][1] - 0.5f))); 99917aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca } 1000946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 1001946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1002946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1003946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 1004946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Compute the setup->coef[] array dadx, dady, a0 values. 1005946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Must be called after setup->vmin,vmax are initialized. 1006946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 1007946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic INLINE boolean 1008946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecasetup_line_coefficients(struct setup_context *setup, 1009946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v0)[4], 1010946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v1)[4]) 1011946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 1012946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct llvmpipe_context *llvmpipe = setup->llvmpipe; 1013946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const struct lp_fragment_shader *lpfs = llvmpipe->fs; 1014946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const struct vertex_info *vinfo = llvmpipe_get_vertex_info(llvmpipe); 1015946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint fragSlot; 1016946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float area; 1017946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1018946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* use setup->vmin, vmax to point to vertices */ 1019946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (llvmpipe->rasterizer->flatshade_first) 1020946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vprovoke = v0; 1021946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else 1022946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vprovoke = v1; 1023946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmin = v0; 1024946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vmax = v1; 1025946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1026946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->emaj.dx = setup->vmax[0][0] - setup->vmin[0][0]; 1027946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->emaj.dy = setup->vmax[0][1] - setup->vmin[0][1]; 1028946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1029946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* NOTE: this is not really area but something proportional to it */ 1030946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca area = setup->emaj.dx * setup->emaj.dx + setup->emaj.dy * setup->emaj.dy; 1031946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (area == 0.0f || util_is_inf_or_nan(area)) 1032946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return FALSE; 1033946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->oneoverarea = 1.0f / area; 1034946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1035946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* z and w are done by linear interpolation: 1036946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 103717aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca linear_pos_coeff(setup, 0, 2); 103817aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca linear_pos_coeff(setup, 0, 3); 1039946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1040946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* setup interpolation for all the remaining attributes: 1041946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 1042946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (fragSlot = 0; fragSlot < lpfs->info.num_inputs; fragSlot++) { 1043946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const uint vertSlot = vinfo->attrib[fragSlot].src_index; 1044946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1045946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca switch (vinfo->attrib[fragSlot].interp_mode) { 1046946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_CONSTANT: 104717aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca const_coeff(setup, fragSlot, vertSlot); 1048946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 1049946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_LINEAR: 105017aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca line_linear_coeff(setup, fragSlot, vertSlot); 1051946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 1052946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_PERSPECTIVE: 105317aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca line_persp_coeff(setup, fragSlot, vertSlot); 1054946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 1055946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_POS: 1056946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup_fragcoord_coeff(setup, fragSlot); 1057946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 1058946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca default: 1059946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(0); 1060946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1061946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1062946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (lpfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { 106317baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.a0[1 + fragSlot][0] = 1.0f - setup->facing; 106417baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.dadx[1 + fragSlot][0] = 0.0; 106517baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.dady[1 + fragSlot][0] = 0.0; 1066946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1067946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1068946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return TRUE; 1069946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 1070946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1071946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1072946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 1073946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Plot a pixel in a line segment. 1074946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 1075946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic INLINE void 1076946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecaplot(struct setup_context *setup, int x, int y) 1077946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 1078946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int iy = y & 1; 1079946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int ix = x & 1; 1080946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int quadX = x - ix; 1081946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int quadY = y - iy; 1082946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int mask = (1 << ix) << (2 * iy); 1083946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 108480eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell if (quadX != setup->quad[0].input.x0 || 108580eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell quadY != setup->quad[0].input.y0) 1086946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca { 1087946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* flush prev quad, start new quad */ 1088946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 108980eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell if (setup->quad[0].input.x0 != -1) 109080eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell clip_emit_quad( setup, &setup->quad[0] ); 1091946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 109280eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.x0 = quadX; 109380eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.y0 = quadY; 109480eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].inout.mask = 0x0; 1095946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1096946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 109780eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].inout.mask |= mask; 1098946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 1099946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1100946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1101946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 1102946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Do setup for line rasterization, then render the line. 1103946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Single-pixel width, no stipple, etc. We rely on the 'draw' module 1104946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * to handle stippling and wide lines. 1105946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 1106946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecavoid 1107908d8d7a1b01214116e358d7641cc097212aeb50Brian Paulllvmpipe_setup_line(struct setup_context *setup, 1108946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v0)[4], 1109946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v1)[4]) 1110946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 1111946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int x0 = (int) v0[0][0]; 1112946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int x1 = (int) v1[0][0]; 1113946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int y0 = (int) v0[0][1]; 1114946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int y1 = (int) v1[0][1]; 1115946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int dx = x1 - x0; 1116946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int dy = y1 - y0; 1117946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int xstep, ystep; 1118946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1119946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#if DEBUG_VERTS 1120946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf("Setup line:\n"); 1121946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca print_vertex(setup, v0); 1122946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca print_vertex(setup, v1); 1123946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#endif 1124946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1125946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (setup->llvmpipe->no_rast) 1126946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return; 1127946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1128946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (dx == 0 && dy == 0) 1129946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return; 1130946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1131946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (!setup_line_coefficients(setup, v0, v1)) 1132946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return; 1133946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1134946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(v0[0][0] < 1.0e9); 1135946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(v0[0][1] < 1.0e9); 1136946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(v1[0][0] < 1.0e9); 1137946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(v1[0][1] < 1.0e9); 1138946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1139946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (dx < 0) { 1140946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dx = -dx; /* make positive */ 1141946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca xstep = -1; 1142946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1143946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 1144946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca xstep = 1; 1145946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1146946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1147946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (dy < 0) { 1148946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dy = -dy; /* make positive */ 1149946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca ystep = -1; 1150946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1151946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 1152946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca ystep = 1; 1153946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1154946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1155946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(dx >= 0); 1156946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(dy >= 0); 115780eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell assert(setup->llvmpipe->reduced_prim == PIPE_PRIM_LINES); 115880eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell 115980eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.x0 = setup->quad[0].input.y0 = -1; 116080eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].inout.mask = 0x0; 1161946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1162946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* XXX temporary: set coverage to 1.0 so the line appears 1163946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * if AA mode happens to be enabled. 1164946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 116580eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.coverage[0] = 116680eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.coverage[1] = 116780eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.coverage[2] = 116880eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.coverage[3] = 1.0; 1169946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1170946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (dx > dy) { 1171946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /*** X-major line ***/ 1172946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int i; 1173946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int errorInc = dy + dy; 1174946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int error = errorInc - dx; 1175946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int errorDec = error - dx; 1176946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1177946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (i = 0; i < dx; i++) { 1178946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca plot(setup, x0, y0); 1179946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1180946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca x0 += xstep; 1181946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (error < 0) { 1182946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca error += errorInc; 1183946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1184946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 1185946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca error += errorDec; 1186946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca y0 += ystep; 1187946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1188946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1189946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1190946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 1191946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /*** Y-major line ***/ 1192946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int i; 1193946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int errorInc = dx + dx; 1194946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int error = errorInc - dy; 1195946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int errorDec = error - dy; 1196946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1197946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (i = 0; i < dy; i++) { 1198946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca plot(setup, x0, y0); 1199946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1200946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca y0 += ystep; 1201946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (error < 0) { 1202946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca error += errorInc; 1203946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1204946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 1205946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca error += errorDec; 1206946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca x0 += xstep; 1207946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1208946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1209946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1210946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1211946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* draw final quad */ 121280eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell if (setup->quad[0].inout.mask) { 121380eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell clip_emit_quad( setup, &setup->quad[0] ); 1214946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1215946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 1216946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1217946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1218946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecastatic void 121917aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonsecapoint_persp_coeff(struct setup_context *setup, 1220946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*vert)[4], 122117aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca unsigned attrib, 122217aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca uint vertSlot) 1223946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 122417aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca unsigned i; 122517aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca for(i = 0; i < NUM_CHANNELS; ++i) { 122617baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.dadx[1 + attrib][i] = 0.0F; 122717baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.dady[1 + attrib][i] = 0.0F; 122817baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.a0[1 + attrib][i] = vert[vertSlot][i] * vert[0][3]; 122917aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca } 1230946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 1231946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1232946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1233946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 1234946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Do setup for point rasterization, then render the point. 1235946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Round or square points... 1236946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * XXX could optimize a lot for 1-pixel points. 1237946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 1238946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonsecavoid 1239908d8d7a1b01214116e358d7641cc097212aeb50Brian Paulllvmpipe_setup_point( struct setup_context *setup, 1240946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float (*v0)[4] ) 1241946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 1242946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct llvmpipe_context *llvmpipe = setup->llvmpipe; 1243946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const struct lp_fragment_shader *lpfs = llvmpipe->fs; 1244946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int sizeAttr = setup->llvmpipe->psize_slot; 1245946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float size 1246946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca = sizeAttr > 0 ? v0[sizeAttr][0] 1247946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca : setup->llvmpipe->rasterizer->point_size; 1248946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float halfSize = 0.5F * size; 1249946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const boolean round = (boolean) setup->llvmpipe->rasterizer->point_smooth; 1250946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float x = v0[0][0]; /* Note: data[0] is always position */ 1251946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float y = v0[0][1]; 1252946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const struct vertex_info *vinfo = llvmpipe_get_vertex_info(llvmpipe); 1253946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint fragSlot; 1254946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1255946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#if DEBUG_VERTS 1256946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf("Setup point:\n"); 1257946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca print_vertex(setup, v0); 1258946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca#endif 1259946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1260946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (llvmpipe->no_rast) 1261946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return; 1262946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 126380eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell assert(setup->llvmpipe->reduced_prim == PIPE_PRIM_POINTS); 126480eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell 1265946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* For points, all interpolants are constant-valued. 1266946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * However, for point sprites, we'll need to setup texcoords appropriately. 1267946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * XXX: which coefficients are the texcoords??? 1268946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * We may do point sprites as textured quads... 1269946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * 1270946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * KW: We don't know which coefficients are texcoords - ultimately 1271946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * the choice of what interpolation mode to use for each attribute 1272946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * should be determined by the fragment program, using 1273946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * per-attribute declaration statements that include interpolation 1274946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * mode as a parameter. So either the fragment program will have 1275946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * to be adjusted for pointsprite vs normal point behaviour, or 1276946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * otherwise a special interpolation mode will have to be defined 1277946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * which matches the required behaviour for point sprites. But - 1278946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * the latter is not a feature of normal hardware, and as such 1279946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * probably should be ruled out on that basis. 1280946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 1281946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->vprovoke = v0; 1282946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1283946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* setup Z, W */ 128417aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca const_pos_coeff(setup, 0, 2); 128517aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca const_pos_coeff(setup, 0, 3); 1286946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1287946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (fragSlot = 0; fragSlot < lpfs->info.num_inputs; fragSlot++) { 1288946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const uint vertSlot = vinfo->attrib[fragSlot].src_index; 1289946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1290946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca switch (vinfo->attrib[fragSlot].interp_mode) { 1291946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_CONSTANT: 1292946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* fall-through */ 1293946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_LINEAR: 129417aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca const_coeff(setup, fragSlot, vertSlot); 1295946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 1296946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_PERSPECTIVE: 129717aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca point_persp_coeff(setup, setup->vprovoke, fragSlot, vertSlot); 1298946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 1299946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca case INTERP_POS: 1300946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup_fragcoord_coeff(setup, fragSlot); 1301946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca break; 1302946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca default: 1303946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca assert(0); 1304946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1305946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1306946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (lpfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { 130717baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.a0[1 + fragSlot][0] = 1.0f - setup->facing; 130817baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.dadx[1 + fragSlot][0] = 0.0; 130917baa01bfbebf71c68aebea5196ebcb313612038José Fonseca setup->coef.dady[1 + fragSlot][0] = 0.0; 1310946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1311946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1312946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1313946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1314946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (halfSize <= 0.5 && !round) { 1315946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* special case for 1-pixel points */ 1316946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int ix = ((int) x) & 1; 1317946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int iy = ((int) y) & 1; 131880eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.x0 = (int) x - ix; 131980eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.y0 = (int) y - iy; 132080eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].inout.mask = (1 << ix) << (2 * iy); 132180eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell clip_emit_quad( setup, &setup->quad[0] ); 1322946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1323946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 1324946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (round) { 1325946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* rounded points */ 1326946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int ixmin = block((int) (x - halfSize)); 1327946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int ixmax = block((int) (x + halfSize)); 1328946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int iymin = block((int) (y - halfSize)); 1329946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int iymax = block((int) (y + halfSize)); 1330946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float rmin = halfSize - 0.7071F; /* 0.7071 = sqrt(2)/2 */ 1331946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float rmax = halfSize + 0.7071F; 1332946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float rmin2 = MAX2(0.0F, rmin * rmin); 1333946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float rmax2 = rmax * rmax; 1334946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const float cscale = 1.0F / (rmax2 - rmin2); 1335946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int ix, iy; 1336946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1337946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (iy = iymin; iy <= iymax; iy += 2) { 1338946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (ix = ixmin; ix <= ixmax; ix += 2) { 1339946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca float dx, dy, dist2, cover; 1340946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 134180eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].inout.mask = 0x0; 1342946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1343946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dx = (ix + 0.5f) - x; 1344946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dy = (iy + 0.5f) - y; 1345946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dist2 = dx * dx + dy * dy; 1346946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (dist2 <= rmax2) { 1347946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca cover = 1.0F - (dist2 - rmin2) * cscale; 134880eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.coverage[QUAD_TOP_LEFT] = MIN2(cover, 1.0f); 134980eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].inout.mask |= MASK_TOP_LEFT; 1350946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1351946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1352946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dx = (ix + 1.5f) - x; 1353946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dy = (iy + 0.5f) - y; 1354946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dist2 = dx * dx + dy * dy; 1355946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (dist2 <= rmax2) { 1356946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca cover = 1.0F - (dist2 - rmin2) * cscale; 135780eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.coverage[QUAD_TOP_RIGHT] = MIN2(cover, 1.0f); 135880eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].inout.mask |= MASK_TOP_RIGHT; 1359946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1360946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1361946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dx = (ix + 0.5f) - x; 1362946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dy = (iy + 1.5f) - y; 1363946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dist2 = dx * dx + dy * dy; 1364946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (dist2 <= rmax2) { 1365946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca cover = 1.0F - (dist2 - rmin2) * cscale; 136680eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.coverage[QUAD_BOTTOM_LEFT] = MIN2(cover, 1.0f); 136780eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].inout.mask |= MASK_BOTTOM_LEFT; 1368946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1369946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1370946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dx = (ix + 1.5f) - x; 1371946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dy = (iy + 1.5f) - y; 1372946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca dist2 = dx * dx + dy * dy; 1373946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (dist2 <= rmax2) { 1374946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca cover = 1.0F - (dist2 - rmin2) * cscale; 137580eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.coverage[QUAD_BOTTOM_RIGHT] = MIN2(cover, 1.0f); 137680eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].inout.mask |= MASK_BOTTOM_RIGHT; 1377946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1378946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 137980eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell if (setup->quad[0].inout.mask) { 138080eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.x0 = ix; 138180eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.y0 = iy; 138280eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell clip_emit_quad( setup, &setup->quad[0] ); 1383946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1384946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1385946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1386946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1387946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 1388946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* square points */ 1389946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int xmin = (int) (x + 0.75 - halfSize); 1390946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int ymin = (int) (y + 0.25 - halfSize); 1391946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int xmax = xmin + (int) size; 1392946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int ymax = ymin + (int) size; 1393946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* XXX could apply scissor to xmin,ymin,xmax,ymax now */ 1394946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int ixmin = block(xmin); 1395946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int ixmax = block(xmax - 1); 1396946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int iymin = block(ymin); 1397946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca const int iymax = block(ymax - 1); 1398946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca int ix, iy; 1399946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1400946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* 1401946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca debug_printf("(%f, %f) -> X:%d..%d Y:%d..%d\n", x, y, xmin, xmax,ymin,ymax); 1402946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 1403946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (iy = iymin; iy <= iymax; iy += 2) { 1404946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint rowMask = 0xf; 1405946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (iy < ymin) { 1406946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* above the top edge */ 1407946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca rowMask &= (MASK_BOTTOM_LEFT | MASK_BOTTOM_RIGHT); 1408946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1409946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (iy + 1 >= ymax) { 1410946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* below the bottom edge */ 1411946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca rowMask &= (MASK_TOP_LEFT | MASK_TOP_RIGHT); 1412946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1413946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1414946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca for (ix = ixmin; ix <= ixmax; ix += 2) { 1415946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca uint mask = rowMask; 1416946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1417946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (ix < xmin) { 1418946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* fragment is past left edge of point, turn off left bits */ 1419946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca mask &= (MASK_BOTTOM_RIGHT | MASK_TOP_RIGHT); 1420946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1421946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (ix + 1 >= xmax) { 1422946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* past the right edge */ 1423946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca mask &= (MASK_BOTTOM_LEFT | MASK_TOP_LEFT); 1424946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1425946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 142680eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].inout.mask = mask; 142780eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.x0 = ix; 142880eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell setup->quad[0].input.y0 = iy; 142980eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell clip_emit_quad( setup, &setup->quad[0] ); 1430946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1431946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1432946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1433946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1434946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 1435946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1436908d8d7a1b01214116e358d7641cc097212aeb50Brian Paulvoid llvmpipe_setup_prepare( struct setup_context *setup ) 1437946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 1438946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca struct llvmpipe_context *lp = setup->llvmpipe; 1439946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1440946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (lp->dirty) { 1441946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca llvmpipe_update_derived(lp); 1442946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1443946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1444946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca if (lp->reduced_api_prim == PIPE_PRIM_TRIANGLES && 1445946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca lp->rasterizer->fill_cw == PIPE_POLYGON_MODE_FILL && 1446946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca lp->rasterizer->fill_ccw == PIPE_POLYGON_MODE_FILL) { 1447946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* we'll do culling */ 1448946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->winding = lp->rasterizer->cull_mode; 1449946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1450946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca else { 1451946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca /* 'draw' will do culling */ 1452946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->winding = PIPE_WINDING_NONE; 1453946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca } 1454946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 1455946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1456946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1457946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1458908d8d7a1b01214116e358d7641cc097212aeb50Brian Paulvoid llvmpipe_setup_destroy_context( struct setup_context *setup ) 1459946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 1460a22f87c99462fd83dc398f4c06fc6d9997e15dbaKeith Whitwell align_free( setup ); 1461946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 1462946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1463946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1464946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca/** 1465946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca * Create a new primitive setup/render stage. 1466946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca */ 1467908d8d7a1b01214116e358d7641cc097212aeb50Brian Paulstruct setup_context *llvmpipe_setup_create_context( struct llvmpipe_context *llvmpipe ) 1468946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca{ 1469a22f87c99462fd83dc398f4c06fc6d9997e15dbaKeith Whitwell struct setup_context *setup; 147080eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell unsigned i; 1471946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1472a22f87c99462fd83dc398f4c06fc6d9997e15dbaKeith Whitwell setup = align_malloc(sizeof(struct setup_context), 16); 1473a22f87c99462fd83dc398f4c06fc6d9997e15dbaKeith Whitwell if (!setup) 1474a22f87c99462fd83dc398f4c06fc6d9997e15dbaKeith Whitwell return NULL; 1475a22f87c99462fd83dc398f4c06fc6d9997e15dbaKeith Whitwell 1476a22f87c99462fd83dc398f4c06fc6d9997e15dbaKeith Whitwell memset(setup, 0, sizeof *setup); 1477946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca setup->llvmpipe = llvmpipe; 1478946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 147980eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell for (i = 0; i < MAX_QUADS; i++) { 148017aec9304ca86feac7ca29e17dda73a10cdd08a5José Fonseca setup->quad[i].coef = &setup->coef; 148180eb276630a194632d9eba1e2b107d678d0f0a4dKeith Whitwell } 1482946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 148308811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell setup->span.left[0] = 1000000; /* greater than right[0] */ 148408811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell setup->span.left[1] = 1000000; /* greater than right[1] */ 148508811032c2dd8f38d2ef65d7fd8794112e029b63Keith Whitwell 1486946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca return setup; 1487946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca} 1488946f432a08112148d743eb9faf6b27bb8cc7fa76José Fonseca 1489