lp_setup_line.c revision 5286dd701640976ffc328e8e85fb3830746851a1
1415b271b5100d64579690111bc8eb549866865a7Keith Whitwell/************************************************************************** 2415b271b5100d64579690111bc8eb549866865a7Keith Whitwell * 3415b271b5100d64579690111bc8eb549866865a7Keith Whitwell * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 4415b271b5100d64579690111bc8eb549866865a7Keith Whitwell * All Rights Reserved. 5415b271b5100d64579690111bc8eb549866865a7Keith Whitwell * 6415b271b5100d64579690111bc8eb549866865a7Keith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a 7415b271b5100d64579690111bc8eb549866865a7Keith Whitwell * copy of this software and associated documentation files (the 8415b271b5100d64579690111bc8eb549866865a7Keith Whitwell * "Software"), to deal in the Software without restriction, including 9415b271b5100d64579690111bc8eb549866865a7Keith Whitwell * without limitation the rights to use, copy, modify, merge, publish, 10415b271b5100d64579690111bc8eb549866865a7Keith Whitwell * distribute, sub license, and/or sell copies of the Software, and to 11415b271b5100d64579690111bc8eb549866865a7Keith Whitwell * permit persons to whom the Software is furnished to do so, subject to 12415b271b5100d64579690111bc8eb549866865a7Keith Whitwell * the following conditions: 13415b271b5100d64579690111bc8eb549866865a7Keith Whitwell * 14415b271b5100d64579690111bc8eb549866865a7Keith Whitwell * The above copyright notice and this permission notice (including the 15415b271b5100d64579690111bc8eb549866865a7Keith Whitwell * next paragraph) shall be included in all copies or substantial portions 16415b271b5100d64579690111bc8eb549866865a7Keith Whitwell * of the Software. 17415b271b5100d64579690111bc8eb549866865a7Keith Whitwell * 18415b271b5100d64579690111bc8eb549866865a7Keith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19415b271b5100d64579690111bc8eb549866865a7Keith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20415b271b5100d64579690111bc8eb549866865a7Keith Whitwell * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21415b271b5100d64579690111bc8eb549866865a7Keith Whitwell * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22415b271b5100d64579690111bc8eb549866865a7Keith Whitwell * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23415b271b5100d64579690111bc8eb549866865a7Keith Whitwell * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24415b271b5100d64579690111bc8eb549866865a7Keith Whitwell * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25415b271b5100d64579690111bc8eb549866865a7Keith Whitwell * 26415b271b5100d64579690111bc8eb549866865a7Keith Whitwell **************************************************************************/ 27415b271b5100d64579690111bc8eb549866865a7Keith Whitwell 28415b271b5100d64579690111bc8eb549866865a7Keith Whitwell/* 29415b271b5100d64579690111bc8eb549866865a7Keith Whitwell * Binning code for lines 30415b271b5100d64579690111bc8eb549866865a7Keith Whitwell */ 31415b271b5100d64579690111bc8eb549866865a7Keith Whitwell 325286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay#include "util/u_math.h" 335286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay#include "util/u_memory.h" 345286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay#include "lp_perf.h" 35415b271b5100d64579690111bc8eb549866865a7Keith Whitwell#include "lp_setup_context.h" 365286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay#include "lp_rast.h" 375286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay#include "lp_state_fs.h" 38415b271b5100d64579690111bc8eb549866865a7Keith Whitwell 395286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay#define NUM_CHANNELS 4 405286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 415286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 425286dd701640976ffc328e8e85fb3830746851a1Hui Qi Taystatic const int step_scissor_minx[16] = { 435286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 0, 1, 0, 1, 445286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 2, 3, 2, 3, 455286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 0, 1, 0, 1, 465286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 2, 3, 2, 3 475286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay}; 485286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 495286dd701640976ffc328e8e85fb3830746851a1Hui Qi Taystatic const int step_scissor_maxx[16] = { 505286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 0, -1, 0, -1, 515286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay -2, -3, -2, -3, 525286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 0, -1, 0, -1, 535286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay -2, -3, -2, -3 545286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay}; 555286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 565286dd701640976ffc328e8e85fb3830746851a1Hui Qi Taystatic const int step_scissor_miny[16] = { 575286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 0, 0, 1, 1, 585286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 0, 0, 1, 1, 595286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 2, 2, 3, 3, 605286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 2, 2, 3, 3 615286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay}; 625286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 635286dd701640976ffc328e8e85fb3830746851a1Hui Qi Taystatic const int step_scissor_maxy[16] = { 645286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 0, 0, -1, -1, 655286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 0, 0, -1, -1, 665286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay -2, -2, -3, -3, 675286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay -2, -2, -3, -3 685286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay}; 695286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 705286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 715286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 725286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay/** 735286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * Compute a0 for a constant-valued coefficient (GL_FLAT shading). 745286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay */ 755286dd701640976ffc328e8e85fb3830746851a1Hui Qi Taystatic void constant_coef( struct lp_setup_context *setup, 765286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay struct lp_rast_triangle *tri, 775286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay unsigned slot, 785286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay const float value, 795286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay unsigned i ) 805286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay{ 815286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay tri->inputs.a0[slot][i] = value; 825286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay tri->inputs.dadx[slot][i] = 0.0f; 835286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay tri->inputs.dady[slot][i] = 0.0f; 845286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay} 855286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 865286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 875286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay/** 885286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * Compute a0, dadx and dady for a linearly interpolated coefficient, 895286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * for a triangle. 905286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay */ 915286dd701640976ffc328e8e85fb3830746851a1Hui Qi Taystatic void linear_coef( struct lp_setup_context *setup, 925286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay struct lp_rast_triangle *tri, 935286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay float oneoverarea, 945286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay unsigned slot, 955286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay const float (*v1)[4], 965286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay const float (*v2)[4], 975286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay unsigned vert_attr, 985286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay unsigned i) 995286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay{ 1005286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay float a1 = v1[vert_attr][i]; 1015286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay float a2 = v2[vert_attr][i]; 1025286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 1035286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay float da21 = a1 - a2; 1045286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay float dadx = da21 * tri->dx * oneoverarea; 1055286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay float dady = da21 * tri->dy * oneoverarea; 1065286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 1075286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay tri->inputs.dadx[slot][i] = dadx; 1085286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay tri->inputs.dady[slot][i] = dady; 1095286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 1105286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay tri->inputs.a0[slot][i] = (a1 - 1115286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay (dadx * (v1[0][0] - setup->pixel_offset) + 1125286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay dady * (v1[0][1] - setup->pixel_offset))); 1135286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay} 1145286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 1155286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 1165286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay/** 1175286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * Compute a0, dadx and dady for a perspective-corrected interpolant, 1185286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * for a triangle. 1195286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * We basically multiply the vertex value by 1/w before computing 1205286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * the plane coefficients (a0, dadx, dady). 1215286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * Later, when we compute the value at a particular fragment position we'll 1225286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * divide the interpolated value by the interpolated W at that fragment. 1235286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay */ 1245286dd701640976ffc328e8e85fb3830746851a1Hui Qi Taystatic void perspective_coef( struct lp_setup_context *setup, 1255286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay struct lp_rast_triangle *tri, 1265286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay float oneoverarea, 1275286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay unsigned slot, 1285286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay const float (*v1)[4], 1295286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay const float (*v2)[4], 1305286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay unsigned vert_attr, 1315286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay unsigned i) 1325286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay{ 1335286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* premultiply by 1/w (v[0][3] is always 1/w): 1345286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay */ 1355286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay float a1 = v1[vert_attr][i] * v1[0][3]; 1365286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay float a2 = v2[vert_attr][i] * v2[0][3]; 1375286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 1385286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay float da21 = a1 - a2; 1395286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay float dadx = da21 * tri->dx * oneoverarea; 1405286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay float dady = da21 * tri->dy * oneoverarea; 1415286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 1425286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay tri->inputs.dadx[slot][i] = dadx; 1435286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay tri->inputs.dady[slot][i] = dady; 1445286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 1455286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay tri->inputs.a0[slot][i] = (a1 - 1465286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay (dadx * (v1[0][0] - setup->pixel_offset) + 1475286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay dady * (v1[0][1] - setup->pixel_offset))); 1485286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay} 1495286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 1505286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay/** 1515286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * Compute the tri->coef[] array dadx, dady, a0 values. 1525286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay */ 1535286dd701640976ffc328e8e85fb3830746851a1Hui Qi Taystatic void setup_line_coefficients( struct lp_setup_context *setup, 1545286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay struct lp_rast_triangle *tri, 1555286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay float oneoverarea, 1565286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay const float (*v1)[4], 1575286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay const float (*v2)[4]) 158415b271b5100d64579690111bc8eb549866865a7Keith Whitwell{ 1595286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay unsigned fragcoord_usage_mask = TGSI_WRITEMASK_XYZ; 1605286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay unsigned slot; 1615286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 1625286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* setup interpolation for all the remaining attributes: 1635286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay */ 1645286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay for (slot = 0; slot < setup->fs.nr_inputs; slot++) { 1655286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay unsigned vert_attr = setup->fs.input[slot].src_index; 1665286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay unsigned usage_mask = setup->fs.input[slot].usage_mask; 1675286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay unsigned i; 1685286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 1695286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay switch (setup->fs.input[slot].interp) { 1705286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay case LP_INTERP_CONSTANT: 1715286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay if (setup->flatshade_first) { 1725286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay for (i = 0; i < NUM_CHANNELS; i++) 1735286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay if (usage_mask & (1 << i)) 1745286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay constant_coef(setup, tri, slot+1, v1[vert_attr][i], i); 1755286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay } 1765286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay else { 1775286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay for (i = 0; i < NUM_CHANNELS; i++) 1785286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay if (usage_mask & (1 << i)) 1795286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay constant_coef(setup, tri, slot+1, v2[vert_attr][i], i); 1805286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay } 1815286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay break; 1825286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 1835286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay case LP_INTERP_LINEAR: 1845286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay for (i = 0; i < NUM_CHANNELS; i++) 1855286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay if (usage_mask & (1 << i)) 1865286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay linear_coef(setup, tri, oneoverarea, slot+1, v1, v2, vert_attr, i); 1875286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay break; 1885286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 1895286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay case LP_INTERP_PERSPECTIVE: 1905286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay for (i = 0; i < NUM_CHANNELS; i++) 1915286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay if (usage_mask & (1 << i)) 1925286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay perspective_coef(setup, tri, oneoverarea, slot+1, v1, v2, vert_attr, i); 1935286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay fragcoord_usage_mask |= TGSI_WRITEMASK_W; 1945286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay break; 1955286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 1965286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay case LP_INTERP_POSITION: 1975286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* 1985286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * The generated pixel interpolators will pick up the coeffs from 1995286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * slot 0, so all need to ensure that the usage mask is covers all 2005286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * usages. 2015286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay */ 2025286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay fragcoord_usage_mask |= usage_mask; 2035286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay break; 2045286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 2055286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay default: 2065286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay assert(0); 2075286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay } 2085286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay } 2095286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 2105286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* The internal position input is in slot zero: 2115286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay */ 2125286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay lp_setup_fragcoord_coef(setup, tri, oneoverarea, 0, v1, v2, v2, 2135286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay fragcoord_usage_mask); 214415b271b5100d64579690111bc8eb549866865a7Keith Whitwell} 215415b271b5100d64579690111bc8eb549866865a7Keith Whitwell 216415b271b5100d64579690111bc8eb549866865a7Keith Whitwell 2175286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 2185286dd701640976ffc328e8e85fb3830746851a1Hui Qi Taystatic INLINE int subpixel_snap( float a ) 219415b271b5100d64579690111bc8eb549866865a7Keith Whitwell{ 2205286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay return util_iround(FIXED_ONE * a); 2215286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay} 2225286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 2235286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 2245286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay/** 2255286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * Print line vertex attribs (for debug). 2265286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay */ 2275286dd701640976ffc328e8e85fb3830746851a1Hui Qi Taystatic void 2285286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tayprint_line(struct lp_setup_context *setup, 2295286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay const float (*v1)[4], 2305286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay const float (*v2)[4]) 2315286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay{ 2325286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay uint i; 2335286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 2345286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay debug_printf("llvmpipe line\n"); 2355286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay for (i = 0; i < 1 + setup->fs.nr_inputs; i++) { 2365286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay debug_printf(" v1[%d]: %f %f %f %f\n", i, 2375286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay v1[i][0], v1[i][1], v1[i][2], v1[i][3]); 2385286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay } 2395286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay for (i = 0; i < 1 + setup->fs.nr_inputs; i++) { 2405286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay debug_printf(" v2[%d]: %f %f %f %f\n", i, 2415286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay v2[i][0], v2[i][1], v2[i][2], v2[i][3]); 2425286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay } 2435286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay} 2445286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 2455286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 2465286dd701640976ffc328e8e85fb3830746851a1Hui Qi Taystatic void 2475286dd701640976ffc328e8e85fb3830746851a1Hui Qi Taylp_setup_line( struct lp_setup_context *setup, 2485286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay const float (*v1)[4], 2495286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay const float (*v2)[4]) 2505286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay{ 2515286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay struct lp_scene *scene = lp_setup_get_current_scene(setup); 2525286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay struct lp_rast_triangle *line; 2535286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay float oneoverarea; 2545286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay float half_width = setup->line_width / 2; 2555286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay int minx, maxx, miny, maxy; 2565286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay int ix0, ix1, iy0, iy1; 2575286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay unsigned tri_bytes; 2585286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay int x[4]; 2595286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay int y[4]; 2605286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay int i; 2615286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay int nr_planes = 4; 2625286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay boolean opaque; 2635286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 2645286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay if (0) 2655286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay print_line(setup, v1, v2); 2665286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 2675286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay if (setup->scissor_test) { 2685286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay nr_planes = 8; 2695286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay } 2705286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay else { 2715286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay nr_planes = 4; 2725286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay } 2735286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 2745286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line = lp_setup_alloc_triangle(scene, 2755286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay setup->fs.nr_inputs, 2765286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay nr_planes, 2775286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay &tri_bytes); 2785286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay if (!line) 2795286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay return; 2805286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 2815286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay#ifndef DEBUG 2825286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->v[0][0] = v1[0][0]; 2835286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->v[1][0] = v2[0][0]; 2845286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->v[0][1] = v1[0][1]; 2855286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->v[1][1] = v2[0][1]; 2865286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay#endif 2875286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 2885286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* pre-calculation(based on given vertices) to determine if line is 2895286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * more horizontal or more vertical 2905286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay */ 2915286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->dx = v1[0][0] - v2[0][0]; 2925286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->dy = v1[0][1] - v2[0][1]; 2935286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 2945286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* x-major line */ 2955286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay if (fabsf(line->dx) >= fabsf(line->dy)) { 2965286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay if (line->dx < 0) { 2975286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* if v2 is to the right of v1, swap pointers */ 2985286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay const float (*temp)[4] = v1; 2995286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay v1 = v2; 3005286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay v2 = temp; 3015286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->dx = -line->dx; 3025286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->dy = -line->dy; 3035286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay } 3045286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 3055286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* x/y positions in fixed point */ 3065286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay x[0] = subpixel_snap(v1[0][0] - setup->pixel_offset); 3075286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay x[1] = subpixel_snap(v2[0][0] - setup->pixel_offset); 3085286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay x[2] = subpixel_snap(v2[0][0] - setup->pixel_offset); 3095286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay x[3] = subpixel_snap(v1[0][0] - setup->pixel_offset); 3105286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 3115286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay y[0] = subpixel_snap(v1[0][1] - half_width - setup->pixel_offset); 3125286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay y[1] = subpixel_snap(v2[0][1] - half_width - setup->pixel_offset); 3135286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay y[2] = subpixel_snap(v2[0][1] + half_width - setup->pixel_offset); 3145286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay y[3] = subpixel_snap(v1[0][1] + half_width - setup->pixel_offset); 3155286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay } 3165286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay else{ 3175286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* y-major line */ 3185286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay if (line->dy > 0) { 3195286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* if v2 is on top of v1, swap pointers */ 3205286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay const float (*temp)[4] = v1; 3215286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay v1 = v2; 3225286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay v2 = temp; 3235286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->dx = -line->dx; 3245286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->dy = -line->dy; 3255286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay } 3265286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 3275286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay x[0] = subpixel_snap(v1[0][0] - half_width - setup->pixel_offset); 3285286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay x[1] = subpixel_snap(v2[0][0] - half_width - setup->pixel_offset); 3295286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay x[2] = subpixel_snap(v2[0][0] + half_width - setup->pixel_offset); 3305286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay x[3] = subpixel_snap(v1[0][0] + half_width - setup->pixel_offset); 3315286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 3325286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay y[0] = subpixel_snap(v1[0][1] - setup->pixel_offset); 3335286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay y[1] = subpixel_snap(v2[0][1] - setup->pixel_offset); 3345286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay y[2] = subpixel_snap(v2[0][1] - setup->pixel_offset); 3355286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay y[3] = subpixel_snap(v1[0][1] - setup->pixel_offset); 3365286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay } 3375286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 3385286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* calculate the deltas */ 3395286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[0].dcdy = x[0] - x[1]; 3405286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[1].dcdy = x[1] - x[2]; 3415286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[2].dcdy = x[2] - x[3]; 3425286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[3].dcdy = x[3] - x[0]; 3435286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 3445286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[0].dcdx = y[0] - y[1]; 3455286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[1].dcdx = y[1] - y[2]; 3465286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[2].dcdx = y[2] - y[3]; 3475286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[3].dcdx = y[3] - y[0]; 3485286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 3495286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 3505286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay LP_COUNT(nr_tris); 3515286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 3525286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 3535286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* Bounding rectangle (in pixels) */ 3545286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay { 3555286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* Yes this is necessary to accurately calculate bounding boxes 3565286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * with the two fill-conventions we support. GL (normally) ends 3575286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * up needing a bottom-left fill convention, which requires 3585286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * slightly different rounding. 3595286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay */ 3605286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay int adj = (setup->pixel_offset != 0) ? 1 : 0; 3615286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 3625286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay minx = (MIN4(x[0], x[1], x[2], x[3]) + (FIXED_ONE-1)) >> FIXED_ORDER; 3635286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay maxx = (MAX4(x[0], x[1], x[2], x[3]) + (FIXED_ONE-1)) >> FIXED_ORDER; 3645286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay miny = (MIN4(y[0], y[1], y[3], y[3]) + (FIXED_ONE-1) + adj) >> FIXED_ORDER; 3655286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay maxy = (MAX4(y[0], y[1], y[3], y[3]) + (FIXED_ONE-1) + adj) >> FIXED_ORDER; 3665286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay } 3675286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 3685286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay if (setup->scissor_test) { 3695286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay minx = MAX2(minx, setup->scissor.current.minx); 3705286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay maxx = MIN2(maxx, setup->scissor.current.maxx); 3715286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay miny = MAX2(miny, setup->scissor.current.miny); 3725286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay maxy = MIN2(maxy, setup->scissor.current.maxy); 3735286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay } 3745286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay else { 3755286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay minx = MAX2(minx, 0); 3765286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay miny = MAX2(miny, 0); 3775286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay maxx = MIN2(maxx, scene->fb.width); 3785286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay maxy = MIN2(maxy, scene->fb.height); 3795286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay } 3805286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 3815286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 3825286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay if (miny >= maxy || minx >= maxx) { 3835286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay lp_scene_putback_data( scene, tri_bytes ); 3845286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay return; 3855286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay } 3865286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 3875286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay oneoverarea = 1.0f / (line->dx * line->dx + line->dy * line->dy); 3885286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 3895286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* Setup parameter interpolants: 3905286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay */ 3915286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay setup_line_coefficients( setup, line, oneoverarea, v1, v2); 3925286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 3935286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay for (i = 0; i < 4; i++) { 3945286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay struct lp_rast_plane *plane = &line->plane[i]; 3955286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 3965286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* half-edge constants, will be interated over the whole render 3975286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * target. 3985286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay */ 3995286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay plane->c = plane->dcdx * x[i] - plane->dcdy * y[i]; 4005286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 4015286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 4025286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* correct for top-left vs. bottom-left fill convention. 4035286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * 4045286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * note that we're overloading gl_rasterization_rules to mean 4055286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * both (0.5,0.5) pixel centers *and* bottom-left filling 4065286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * convention. 4075286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * 4085286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * GL actually has a top-left filling convention, but GL's 4095286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * notion of "top" differs from gallium's... 4105286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * 4115286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * Also, sometimes (in FBO cases) GL will render upside down 4125286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * to its usual method, in which case it will probably want 4135286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * to use the opposite, top-left convention. 4145286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay */ 4155286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay if (plane->dcdx < 0) { 4165286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* both fill conventions want this - adjust for left edges */ 4175286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay plane->c++; 4185286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay } 4195286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay else if (plane->dcdx == 0) { 4205286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay if (setup->pixel_offset == 0) { 4215286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* correct for top-left fill convention: 4225286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay */ 4235286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay if (plane->dcdy > 0) plane->c++; 4245286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay } 4255286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay else { 4265286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* correct for bottom-left fill convention: 4275286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay */ 4285286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay if (plane->dcdy < 0) plane->c++; 4295286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay } 4305286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay } 4315286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 4325286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay plane->dcdx *= FIXED_ONE; 4335286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay plane->dcdy *= FIXED_ONE; 4345286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 4355286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* find trivial reject offsets for each edge for a single-pixel 4365286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * sized block. These will be scaled up at each recursive level to 4375286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * match the active blocksize. Scaling in this way works best if 4385286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * the blocks are square. 4395286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay */ 4405286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay plane->eo = 0; 4415286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay if (plane->dcdx < 0) plane->eo -= plane->dcdx; 4425286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay if (plane->dcdy > 0) plane->eo += plane->dcdy; 4435286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 4445286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* Calculate trivial accept offsets from the above. 4455286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay */ 4465286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay plane->ei = plane->dcdy - plane->dcdx - plane->eo; 4475286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 4485286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay plane->step = line->step[i]; 4495286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 4505286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* Fill in the inputs.step[][] arrays. 4515286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * We've manually unrolled some loops here. 4525286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay */ 4535286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay#define SETUP_STEP(j, x, y) \ 4545286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->step[i][j] = y * plane->dcdy - x * plane->dcdx 4555286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 4565286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay SETUP_STEP(0, 0, 0); 4575286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay SETUP_STEP(1, 1, 0); 4585286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay SETUP_STEP(2, 0, 1); 4595286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay SETUP_STEP(3, 1, 1); 4605286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 4615286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay SETUP_STEP(4, 2, 0); 4625286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay SETUP_STEP(5, 3, 0); 4635286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay SETUP_STEP(6, 2, 1); 4645286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay SETUP_STEP(7, 3, 1); 4655286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 4665286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay SETUP_STEP(8, 0, 2); 4675286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay SETUP_STEP(9, 1, 2); 4685286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay SETUP_STEP(10, 0, 3); 4695286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay SETUP_STEP(11, 1, 3); 4705286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 4715286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay SETUP_STEP(12, 2, 2); 4725286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay SETUP_STEP(13, 3, 2); 4735286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay SETUP_STEP(14, 2, 3); 4745286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay SETUP_STEP(15, 3, 3); 4755286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay#undef STEP 4765286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay } 4775286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 4785286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 4795286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* 4805286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * When rasterizing scissored tris, use the intersection of the 4815286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * triangle bounding box and the scissor rect to generate the 4825286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * scissor planes. 4835286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * 4845286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * This permits us to cut off the triangle "tails" that are present 4855286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * in the intermediate recursive levels caused when two of the 4865286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * triangles edges don't diverge quickly enough to trivially reject 4875286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * exterior blocks from the triangle. 4885286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * 4895286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * It's not really clear if it's worth worrying about these tails, 4905286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * but since we generate the planes for each scissored tri, it's 4915286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * free to trim them in this case. 4925286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * 4935286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * Note that otherwise, the scissor planes only vary in 'C' value, 4945286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * and even then only on state-changes. Could alternatively store 4955286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * these planes elsewhere. 4965286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay */ 4975286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay if (nr_planes == 8) { 4985286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[4].step = step_scissor_maxx; 4995286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[4].dcdx = 1; 5005286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[4].dcdy = 0; 5015286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[4].c = maxx; 5025286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[4].ei = -1; 5035286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[4].eo = 0; 5045286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 5055286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[5].step = step_scissor_miny; 5065286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[5].dcdx = 0; 5075286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[5].dcdy = 1; 5085286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[5].c = 1-miny; 5095286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[5].ei = 0; 5105286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[5].eo = 1; 5115286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 5125286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[6].step = step_scissor_maxy; 5135286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[6].dcdx = 0; 5145286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[6].dcdy = -1; 5155286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[6].c = maxy; 5165286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[6].ei = -1; 5175286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[6].eo = 0; 5185286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 5195286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[7].step = step_scissor_minx; 5205286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[7].dcdx = -1; 5215286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[7].dcdy = 0; 5225286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[7].c = 1-minx; 5235286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[7].ei = 0; 5245286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[7].eo = 1; 5255286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay } 5265286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 5275286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 5285286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* 5295286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * All fields of 'tri' are now set. The remaining code here is 5305286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * concerned with binning. 5315286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay */ 5325286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 5335286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* Convert to tile coordinates, and inclusive ranges: 5345286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay */ 5355286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay ix0 = minx / TILE_SIZE; 5365286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay iy0 = miny / TILE_SIZE; 5375286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay ix1 = (maxx-1) / TILE_SIZE; 5385286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay iy1 = (maxy-1) / TILE_SIZE; 5395286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 5405286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* 5415286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * Clamp to framebuffer size 5425286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay */ 5435286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay assert(ix0 == MAX2(ix0, 0)); 5445286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay assert(iy0 == MAX2(iy0, 0)); 5455286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay assert(ix1 == MIN2(ix1, scene->tiles_x - 1)); 5465286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay assert(iy1 == MIN2(iy1, scene->tiles_y - 1)); 5475286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 5485286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* Determine which tile(s) intersect the triangle's bounding box 5495286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay */ 5505286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay if (iy0 == iy1 && ix0 == ix1) 5515286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay { 5525286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* Triangle is contained in a single tile: 5535286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay */ 5545286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay lp_scene_bin_command( scene, ix0, iy0, 5555286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay lp_rast_tri_tab[nr_planes], 5565286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay lp_rast_arg_triangle(line, (1<<nr_planes)-1) ); 5575286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay } 5585286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay else 5595286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay { 5605286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay int c[8]; 5615286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay int ei[8]; 5625286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay int eo[8]; 5635286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay int xstep[8]; 5645286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay int ystep[8]; 5655286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay int x, y; 5665286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay int is_blit = -1; /* undetermined */ 5675286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 5685286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay for (i = 0; i < nr_planes; i++) { 5695286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay c[i] = (line->plane[i].c + 5705286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[i].dcdy * iy0 * TILE_SIZE - 5715286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay line->plane[i].dcdx * ix0 * TILE_SIZE); 5725286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 5735286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay ei[i] = line->plane[i].ei << TILE_ORDER; 5745286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay eo[i] = line->plane[i].eo << TILE_ORDER; 5755286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay xstep[i] = -(line->plane[i].dcdx << TILE_ORDER); 5765286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay ystep[i] = line->plane[i].dcdy << TILE_ORDER; 5775286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay } 5785286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 5795286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 5805286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 5815286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* Test tile-sized blocks against the triangle. 5825286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * Discard blocks fully outside the tri. If the block is fully 5835286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * contained inside the tri, bin an lp_rast_shade_tile command. 5845286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * Else, bin a lp_rast_triangle command. 5855286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay */ 5865286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay for (y = iy0; y <= iy1; y++) 5875286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay { 5885286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay boolean in = FALSE; /* are we inside the triangle? */ 5895286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay int cx[8]; 5905286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 5915286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay for (i = 0; i < nr_planes; i++) 5925286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay cx[i] = c[i]; 5935286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 5945286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay for (x = ix0; x <= ix1; x++) 5955286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay { 5965286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay int out = 0; 5975286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay int partial = 0; 5985286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 5995286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay for (i = 0; i < nr_planes; i++) { 6005286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay int planeout = cx[i] + eo[i]; 6015286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay int planepartial = cx[i] + ei[i] - 1; 6025286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay out |= (planeout >> 31); 6035286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay partial |= (planepartial >> 31) & (1<<i); 6045286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay } 6055286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay if (out) { 6065286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* do nothing */ 6075286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay if (in) 6085286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay break; /* exiting triangle, all done with this row */ 6095286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay LP_COUNT(nr_empty_64); 6105286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay } 6115286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay else if (partial) { 6125286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* Not trivially accepted by at least one plane - 6135286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay * rasterize/shade partial tile 6145286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay */ 6155286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay int count = util_bitcount(partial); 6165286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay in = TRUE; 6175286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay lp_scene_bin_command( scene, x, y, 6185286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay lp_rast_tri_tab[count], 6195286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay lp_rast_arg_triangle(line, partial) ); 6205286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 6215286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay LP_COUNT(nr_partially_covered_64); 6225286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay } 6235286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay else { 6245286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* triangle covers the whole tile- shade whole tile */ 6255286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay LP_COUNT(nr_fully_covered_64); 6265286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay in = TRUE; 6275286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* leverages on existing code in lp_setup_tri.c */ 6285286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay do_triangle_ccw_whole_tile(setup, scene, line, x, y, 6295286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay opaque, &is_blit); 6305286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay } 6315286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 6325286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* Iterate cx values across the region: 6335286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay */ 6345286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay for (i = 0; i < nr_planes; i++) 6355286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay cx[i] += xstep[i]; 6365286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay } 6375286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 6385286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay /* Iterate c values down the region: 6395286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay */ 6405286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay for (i = 0; i < nr_planes; i++) 6415286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay c[i] += ystep[i]; 6425286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay } 6435286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay } 6445286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay} 6455286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 6465286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay 6475286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tayvoid lp_setup_choose_line( struct lp_setup_context *setup ) 6485286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay{ 6495286dd701640976ffc328e8e85fb3830746851a1Hui Qi Tay setup->line = lp_setup_line; 650415b271b5100d64579690111bc8eb549866865a7Keith Whitwell} 651415b271b5100d64579690111bc8eb549866865a7Keith Whitwell 652415b271b5100d64579690111bc8eb549866865a7Keith Whitwell 653