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