Path: blob/21.2-virgl/src/gallium/auxiliary/draw/draw_decompose_tmp.h
4565 views
/*1* Mesa 3-D graphics library2*3* Copyright 2008 VMware, Inc.4* Copyright (C) 2010 LunarG Inc.5*6* Permission is hereby granted, free of charge, to any person obtaining a7* copy of this software and associated documentation files (the "Software"),8* to deal in the Software without restriction, including without limitation9* the rights to use, copy, modify, merge, publish, distribute, sublicense,10* and/or sell copies of the Software, and to permit persons to whom the11* Software is furnished to do so, subject to the following conditions:12*13* The above copyright notice and this permission notice shall be included14* in all copies or substantial portions of the Software.15*16* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR17* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,18* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL19* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER20* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING21* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER22* DEALINGS IN THE SOFTWARE.23*24* Authors:25* Keith Whitwell <[email protected]>26* Chia-I Wu <[email protected]>27*/2829/* these macros are optional */30#ifndef LOCAL_VARS31#define LOCAL_VARS32#endif33#ifndef FUNC_ENTER34#define FUNC_ENTER do {} while (0)35#endif36#ifndef FUNC_EXIT37#define FUNC_EXIT do {} while (0)38#endif39#ifndef LINE_ADJ40#define LINE_ADJ(flags, a0, i0, i1, a1) LINE(flags, i0, i1)41#endif42#ifndef TRIANGLE_ADJ43#define TRIANGLE_ADJ(flags, i0, a0, i1, a1, i2, a2) TRIANGLE(flags, i0, i1, i2)44#endif4546static void47FUNC(FUNC_VARS)48{49unsigned idx[6], i;50ushort flags;51LOCAL_VARS5253FUNC_ENTER;5455/* prim, prim_flags, count, and last_vertex_last should have been defined */56if (0) {57debug_printf("%s: prim 0x%x, prim_flags 0x%x, count %d, last_vertex_last %d\n",58__FUNCTION__, prim, prim_flags, count, last_vertex_last);59}6061switch (prim) {62case PIPE_PRIM_POINTS:63for (i = 0; i < count; i++) {64idx[0] = GET_ELT(i);65POINT(idx[0]);66}67break;6869case PIPE_PRIM_LINES:70flags = DRAW_PIPE_RESET_STIPPLE;71for (i = 0; i + 1 < count; i += 2) {72idx[0] = GET_ELT(i);73idx[1] = GET_ELT(i + 1);74LINE(flags, idx[0], idx[1]);75}76break;7778case PIPE_PRIM_LINE_LOOP:79case PIPE_PRIM_LINE_STRIP:80if (count >= 2) {81flags = (prim_flags & DRAW_SPLIT_BEFORE) ? 0 : DRAW_PIPE_RESET_STIPPLE;82idx[1] = GET_ELT(0);83idx[2] = idx[1];8485for (i = 1; i < count; i++, flags = 0) {86idx[0] = idx[1];87idx[1] = GET_ELT(i);88LINE(flags, idx[0], idx[1]);89}90/* close the loop */91if (prim == PIPE_PRIM_LINE_LOOP && !prim_flags)92LINE(flags, idx[1], idx[2]);93}94break;9596case PIPE_PRIM_TRIANGLES:97flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL;98for (i = 0; i + 2 < count; i += 3) {99idx[0] = GET_ELT(i);100idx[1] = GET_ELT(i + 1);101idx[2] = GET_ELT(i + 2);102TRIANGLE(flags, idx[0], idx[1], idx[2]);103}104break;105106case PIPE_PRIM_TRIANGLE_STRIP:107if (count >= 3) {108flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL;109idx[1] = GET_ELT(0);110idx[2] = GET_ELT(1);111112if (last_vertex_last) {113for (i = 0; i + 2 < count; i++) {114idx[0] = idx[1];115idx[1] = idx[2];116idx[2] = GET_ELT(i + 2);117/* always emit idx[2] last */118if (i & 1)119TRIANGLE(flags, idx[1], idx[0], idx[2]);120else121TRIANGLE(flags, idx[0], idx[1], idx[2]);122}123}124else {125for (i = 0; i + 2 < count; i++) {126idx[0] = idx[1];127idx[1] = idx[2];128idx[2] = GET_ELT(i + 2);129/* always emit idx[0] first */130if (i & 1)131TRIANGLE(flags, idx[0], idx[2], idx[1]);132else133TRIANGLE(flags, idx[0], idx[1], idx[2]);134}135}136}137break;138139case PIPE_PRIM_TRIANGLE_FAN:140if (count >= 3) {141flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL;142idx[0] = GET_ELT(0);143idx[2] = GET_ELT(1);144145/* idx[0] is neither the first nor the last vertex */146if (last_vertex_last) {147for (i = 0; i + 2 < count; i++) {148idx[1] = idx[2];149idx[2] = GET_ELT(i + 2);150/* always emit idx[2] last */151TRIANGLE(flags, idx[0], idx[1], idx[2]);152}153}154else {155for (i = 0; i + 2 < count; i++) {156idx[1] = idx[2];157idx[2] = GET_ELT(i + 2);158/* always emit idx[1] first */159TRIANGLE(flags, idx[1], idx[2], idx[0]);160}161}162}163break;164165case PIPE_PRIM_QUADS:166if (last_vertex_last) {167for (i = 0; i + 3 < count; i += 4) {168idx[0] = GET_ELT(i);169idx[1] = GET_ELT(i + 1);170idx[2] = GET_ELT(i + 2);171idx[3] = GET_ELT(i + 3);172173flags = DRAW_PIPE_RESET_STIPPLE |174DRAW_PIPE_EDGE_FLAG_0 |175DRAW_PIPE_EDGE_FLAG_2;176/* always emit idx[3] last */177TRIANGLE(flags, idx[0], idx[1], idx[3]);178179flags = DRAW_PIPE_EDGE_FLAG_0 |180DRAW_PIPE_EDGE_FLAG_1;181TRIANGLE(flags, idx[1], idx[2], idx[3]);182}183}184else {185for (i = 0; i + 3 < count; i += 4) {186idx[0] = GET_ELT(i);187idx[1] = GET_ELT(i + 1);188idx[2] = GET_ELT(i + 2);189idx[3] = GET_ELT(i + 3);190191flags = DRAW_PIPE_RESET_STIPPLE |192DRAW_PIPE_EDGE_FLAG_0 |193DRAW_PIPE_EDGE_FLAG_1;194/* always emit idx[3] / idx[0] first */195if (quads_flatshade_last)196TRIANGLE(flags, idx[3], idx[0], idx[1]);197else198TRIANGLE(flags, idx[0], idx[1], idx[2]);199200flags = DRAW_PIPE_EDGE_FLAG_1 |201DRAW_PIPE_EDGE_FLAG_2;202if (quads_flatshade_last)203TRIANGLE(flags, idx[3], idx[1], idx[2]);204else205TRIANGLE(flags, idx[0], idx[2], idx[3]);206}207}208break;209210case PIPE_PRIM_QUAD_STRIP:211if (count >= 4) {212idx[2] = GET_ELT(0);213idx[3] = GET_ELT(1);214215if (last_vertex_last) {216for (i = 0; i + 3 < count; i += 2) {217idx[0] = idx[2];218idx[1] = idx[3];219idx[2] = GET_ELT(i + 2);220idx[3] = GET_ELT(i + 3);221222/* always emit idx[3] last */223flags = DRAW_PIPE_RESET_STIPPLE |224DRAW_PIPE_EDGE_FLAG_0 |225DRAW_PIPE_EDGE_FLAG_2;226TRIANGLE(flags, idx[2], idx[0], idx[3]);227228flags = DRAW_PIPE_EDGE_FLAG_0 |229DRAW_PIPE_EDGE_FLAG_1;230TRIANGLE(flags, idx[0], idx[1], idx[3]);231}232}233else {234for (i = 0; i + 3 < count; i += 2) {235idx[0] = idx[2];236idx[1] = idx[3];237idx[2] = GET_ELT(i + 2);238idx[3] = GET_ELT(i + 3);239240flags = DRAW_PIPE_RESET_STIPPLE |241DRAW_PIPE_EDGE_FLAG_0 |242DRAW_PIPE_EDGE_FLAG_1;243/* always emit idx[3] / idx[0 first */244if (quads_flatshade_last)245TRIANGLE(flags, idx[3], idx[2], idx[0]);246else247TRIANGLE(flags, idx[0], idx[3], idx[2]);248249flags = DRAW_PIPE_EDGE_FLAG_1 |250DRAW_PIPE_EDGE_FLAG_2;251if (quads_flatshade_last)252TRIANGLE(flags, idx[3], idx[0], idx[1]);253else254TRIANGLE(flags, idx[0], idx[1], idx[3]);255}256}257}258break;259260case PIPE_PRIM_POLYGON:261if (count >= 3) {262ushort edge_next, edge_finish;263264if (last_vertex_last) {265flags = (DRAW_PIPE_RESET_STIPPLE |266DRAW_PIPE_EDGE_FLAG_0);267if (!(prim_flags & DRAW_SPLIT_BEFORE))268flags |= DRAW_PIPE_EDGE_FLAG_2;269270edge_next = DRAW_PIPE_EDGE_FLAG_0;271edge_finish =272(prim_flags & DRAW_SPLIT_AFTER) ? 0 : DRAW_PIPE_EDGE_FLAG_1;273}274else {275flags = (DRAW_PIPE_RESET_STIPPLE |276DRAW_PIPE_EDGE_FLAG_1);277if (!(prim_flags & DRAW_SPLIT_BEFORE))278flags |= DRAW_PIPE_EDGE_FLAG_0;279280edge_next = DRAW_PIPE_EDGE_FLAG_1;281edge_finish =282(prim_flags & DRAW_SPLIT_AFTER) ? 0 : DRAW_PIPE_EDGE_FLAG_2;283}284285idx[0] = GET_ELT(0);286idx[2] = GET_ELT(1);287288for (i = 0; i + 2 < count; i++, flags = edge_next) {289idx[1] = idx[2];290idx[2] = GET_ELT(i + 2);291292if (i + 3 == count)293flags |= edge_finish;294295/* idx[0] is both the first and the last vertex */296if (last_vertex_last)297TRIANGLE(flags, idx[1], idx[2], idx[0]);298else299TRIANGLE(flags, idx[0], idx[1], idx[2]);300}301}302break;303304case PIPE_PRIM_LINES_ADJACENCY:305flags = DRAW_PIPE_RESET_STIPPLE;306for (i = 0; i + 3 < count; i += 4) {307idx[0] = GET_ELT(i);308idx[1] = GET_ELT(i + 1);309idx[2] = GET_ELT(i + 2);310idx[3] = GET_ELT(i + 3);311LINE_ADJ(flags, idx[0], idx[1], idx[2], idx[3]);312}313break;314315case PIPE_PRIM_LINE_STRIP_ADJACENCY:316if (count >= 4) {317flags = (prim_flags & DRAW_SPLIT_BEFORE) ? 0 : DRAW_PIPE_RESET_STIPPLE;318idx[1] = GET_ELT(0);319idx[2] = GET_ELT(1);320idx[3] = GET_ELT(2);321322for (i = 1; i + 2 < count; i++, flags = 0) {323idx[0] = idx[1];324idx[1] = idx[2];325idx[2] = idx[3];326idx[3] = GET_ELT(i + 2);327LINE_ADJ(flags, idx[0], idx[1], idx[2], idx[3]);328}329}330break;331332case PIPE_PRIM_TRIANGLES_ADJACENCY:333flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL;334for (i = 0; i + 5 < count; i += 6) {335idx[0] = GET_ELT(i);336idx[1] = GET_ELT(i + 1);337idx[2] = GET_ELT(i + 2);338idx[3] = GET_ELT(i + 3);339idx[4] = GET_ELT(i + 4);340idx[5] = GET_ELT(i + 5);341TRIANGLE_ADJ(flags, idx[0], idx[1], idx[2], idx[3], idx[4], idx[5]);342}343break;344345case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:346if (count >= 6) {347flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL;348idx[0] = GET_ELT(1);349idx[2] = GET_ELT(0);350idx[4] = GET_ELT(2);351idx[3] = GET_ELT(4);352353/*354* The vertices of the i-th triangle are stored in355* idx[0,2,4] = { 2*i, 2*i+2, 2*i+4 };356*357* The adjacent vertices are stored in358* idx[1,3,5] = { 2*i-2, 2*i+6, 2*i+3 }.359*360* However, there are two exceptions:361*362* For the first triangle, idx[1] = 1;363* For the last triangle, idx[3] = 2*i+5.364*/365if (last_vertex_last) {366for (i = 0; i + 5 < count; i += 2) {367idx[1] = idx[0];368369idx[0] = idx[2];370idx[2] = idx[4];371idx[4] = idx[3];372373idx[3] = GET_ELT(i + ((i + 7 < count) ? 6 : 5));374idx[5] = GET_ELT(i + 3);375376/*377* alternate the first two vertices (idx[0] and idx[2]) and the378* corresponding adjacent vertices (idx[3] and idx[5]) to have379* the correct orientation380*/381if (i & 2) {382TRIANGLE_ADJ(flags,383idx[2], idx[1], idx[0], idx[5], idx[4], idx[3]);384}385else {386TRIANGLE_ADJ(flags,387idx[0], idx[1], idx[2], idx[3], idx[4], idx[5]);388}389}390}391else {392for (i = 0; i + 5 < count; i += 2) {393idx[1] = idx[0];394395idx[0] = idx[2];396idx[2] = idx[4];397idx[4] = idx[3];398399idx[3] = GET_ELT(i + ((i + 7 < count) ? 6 : 5));400idx[5] = GET_ELT(i + 3);401402/*403* alternate the last two vertices (idx[2] and idx[4]) and the404* corresponding adjacent vertices (idx[1] and idx[5]) to have405* the correct orientation406*/407if (i & 2) {408TRIANGLE_ADJ(flags,409idx[0], idx[5], idx[4], idx[3], idx[2], idx[1]);410}411else {412TRIANGLE_ADJ(flags,413idx[0], idx[1], idx[2], idx[3], idx[4], idx[5]);414}415}416}417}418break;419420default:421assert(0);422break;423}424425FUNC_EXIT;426}427428#undef LOCAL_VARS429#undef FUNC_ENTER430#undef FUNC_EXIT431#undef LINE_ADJ432#undef TRIANGLE_ADJ433434#undef FUNC435#undef FUNC_VARS436#undef GET_ELT437#undef POINT438#undef LINE439#undef TRIANGLE440441442