1*35238bceSAndroid Build Coastguard Worker #ifndef _RRPRIMITIVEASSEMBLER_HPP 2*35238bceSAndroid Build Coastguard Worker #define _RRPRIMITIVEASSEMBLER_HPP 3*35238bceSAndroid Build Coastguard Worker /*------------------------------------------------------------------------- 4*35238bceSAndroid Build Coastguard Worker * drawElements Quality Program Reference Renderer 5*35238bceSAndroid Build Coastguard Worker * ----------------------------------------------- 6*35238bceSAndroid Build Coastguard Worker * 7*35238bceSAndroid Build Coastguard Worker * Copyright 2014 The Android Open Source Project 8*35238bceSAndroid Build Coastguard Worker * 9*35238bceSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 10*35238bceSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 11*35238bceSAndroid Build Coastguard Worker * You may obtain a copy of the License at 12*35238bceSAndroid Build Coastguard Worker * 13*35238bceSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 14*35238bceSAndroid Build Coastguard Worker * 15*35238bceSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 16*35238bceSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 17*35238bceSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18*35238bceSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 19*35238bceSAndroid Build Coastguard Worker * limitations under the License. 20*35238bceSAndroid Build Coastguard Worker * 21*35238bceSAndroid Build Coastguard Worker *//*! 22*35238bceSAndroid Build Coastguard Worker * \file 23*35238bceSAndroid Build Coastguard Worker * \brief Primitive assembler 24*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/ 25*35238bceSAndroid Build Coastguard Worker 26*35238bceSAndroid Build Coastguard Worker #include "rrDefs.hpp" 27*35238bceSAndroid Build Coastguard Worker #include "rrVertexPacket.hpp" 28*35238bceSAndroid Build Coastguard Worker 29*35238bceSAndroid Build Coastguard Worker namespace rr 30*35238bceSAndroid Build Coastguard Worker { 31*35238bceSAndroid Build Coastguard Worker namespace pa 32*35238bceSAndroid Build Coastguard Worker { 33*35238bceSAndroid Build Coastguard Worker 34*35238bceSAndroid Build Coastguard Worker struct Triangle 35*35238bceSAndroid Build Coastguard Worker { 36*35238bceSAndroid Build Coastguard Worker enum 37*35238bceSAndroid Build Coastguard Worker { 38*35238bceSAndroid Build Coastguard Worker NUM_VERTICES = 3 39*35238bceSAndroid Build Coastguard Worker }; 40*35238bceSAndroid Build Coastguard Worker Trianglerr::pa::Triangle41*35238bceSAndroid Build Coastguard Worker Triangle(void) : v0(DE_NULL), v1(DE_NULL), v2(DE_NULL), provokingIndex(-1) 42*35238bceSAndroid Build Coastguard Worker { 43*35238bceSAndroid Build Coastguard Worker } 44*35238bceSAndroid Build Coastguard Worker Trianglerr::pa::Triangle45*35238bceSAndroid Build Coastguard Worker Triangle(VertexPacket *v0_, VertexPacket *v1_, VertexPacket *v2_, int provokingIndex_) 46*35238bceSAndroid Build Coastguard Worker : v0(v0_) 47*35238bceSAndroid Build Coastguard Worker , v1(v1_) 48*35238bceSAndroid Build Coastguard Worker , v2(v2_) 49*35238bceSAndroid Build Coastguard Worker , provokingIndex(provokingIndex_) 50*35238bceSAndroid Build Coastguard Worker { 51*35238bceSAndroid Build Coastguard Worker } 52*35238bceSAndroid Build Coastguard Worker getProvokingVertexrr::pa::Triangle53*35238bceSAndroid Build Coastguard Worker VertexPacket *getProvokingVertex(void) 54*35238bceSAndroid Build Coastguard Worker { 55*35238bceSAndroid Build Coastguard Worker switch (provokingIndex) 56*35238bceSAndroid Build Coastguard Worker { 57*35238bceSAndroid Build Coastguard Worker case 0: 58*35238bceSAndroid Build Coastguard Worker return v0; 59*35238bceSAndroid Build Coastguard Worker case 1: 60*35238bceSAndroid Build Coastguard Worker return v1; 61*35238bceSAndroid Build Coastguard Worker case 2: 62*35238bceSAndroid Build Coastguard Worker return v2; 63*35238bceSAndroid Build Coastguard Worker default: 64*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false); 65*35238bceSAndroid Build Coastguard Worker return DE_NULL; 66*35238bceSAndroid Build Coastguard Worker } 67*35238bceSAndroid Build Coastguard Worker } 68*35238bceSAndroid Build Coastguard Worker 69*35238bceSAndroid Build Coastguard Worker VertexPacket *v0; 70*35238bceSAndroid Build Coastguard Worker VertexPacket *v1; 71*35238bceSAndroid Build Coastguard Worker VertexPacket *v2; 72*35238bceSAndroid Build Coastguard Worker 73*35238bceSAndroid Build Coastguard Worker int provokingIndex; 74*35238bceSAndroid Build Coastguard Worker } DE_WARN_UNUSED_TYPE; 75*35238bceSAndroid Build Coastguard Worker 76*35238bceSAndroid Build Coastguard Worker struct Triangles 77*35238bceSAndroid Build Coastguard Worker { 78*35238bceSAndroid Build Coastguard Worker template <typename Iterator> execrr::pa::Triangles79*35238bceSAndroid Build Coastguard Worker static void exec(Iterator outputIterator, VertexPacket *const *vertices, size_t numVertices, 80*35238bceSAndroid Build Coastguard Worker rr::ProvokingVertex provokingConvention) 81*35238bceSAndroid Build Coastguard Worker { 82*35238bceSAndroid Build Coastguard Worker const int provokingOffset = (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (0) : (2); 83*35238bceSAndroid Build Coastguard Worker 84*35238bceSAndroid Build Coastguard Worker for (size_t ndx = 0; ndx + 2 < numVertices; ndx += 3) 85*35238bceSAndroid Build Coastguard Worker *(outputIterator++) = Triangle(vertices[ndx], vertices[ndx + 1], vertices[ndx + 2], provokingOffset); 86*35238bceSAndroid Build Coastguard Worker } 87*35238bceSAndroid Build Coastguard Worker getPrimitiveCountrr::pa::Triangles88*35238bceSAndroid Build Coastguard Worker static size_t getPrimitiveCount(size_t vertices) 89*35238bceSAndroid Build Coastguard Worker { 90*35238bceSAndroid Build Coastguard Worker return vertices / 3; 91*35238bceSAndroid Build Coastguard Worker } 92*35238bceSAndroid Build Coastguard Worker } DE_WARN_UNUSED_TYPE; 93*35238bceSAndroid Build Coastguard Worker 94*35238bceSAndroid Build Coastguard Worker struct TriangleStrip 95*35238bceSAndroid Build Coastguard Worker { 96*35238bceSAndroid Build Coastguard Worker template <typename Iterator> execrr::pa::TriangleStrip97*35238bceSAndroid Build Coastguard Worker static void exec(Iterator outputIterator, VertexPacket *const *vertices, size_t numVertices, 98*35238bceSAndroid Build Coastguard Worker rr::ProvokingVertex provokingConvention) 99*35238bceSAndroid Build Coastguard Worker { 100*35238bceSAndroid Build Coastguard Worker if (numVertices < 3) 101*35238bceSAndroid Build Coastguard Worker { 102*35238bceSAndroid Build Coastguard Worker } 103*35238bceSAndroid Build Coastguard Worker else 104*35238bceSAndroid Build Coastguard Worker { 105*35238bceSAndroid Build Coastguard Worker VertexPacket *vert0 = vertices[0]; 106*35238bceSAndroid Build Coastguard Worker VertexPacket *vert1 = vertices[1]; 107*35238bceSAndroid Build Coastguard Worker size_t ndx = 2; 108*35238bceSAndroid Build Coastguard Worker 109*35238bceSAndroid Build Coastguard Worker for (;;) 110*35238bceSAndroid Build Coastguard Worker { 111*35238bceSAndroid Build Coastguard Worker { 112*35238bceSAndroid Build Coastguard Worker if (ndx >= numVertices) 113*35238bceSAndroid Build Coastguard Worker break; 114*35238bceSAndroid Build Coastguard Worker 115*35238bceSAndroid Build Coastguard Worker *(outputIterator++) = Triangle(vert0, vert1, vertices[ndx], 116*35238bceSAndroid Build Coastguard Worker (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (0) : (2)); 117*35238bceSAndroid Build Coastguard Worker vert0 = vertices[ndx]; 118*35238bceSAndroid Build Coastguard Worker 119*35238bceSAndroid Build Coastguard Worker ndx++; 120*35238bceSAndroid Build Coastguard Worker } 121*35238bceSAndroid Build Coastguard Worker 122*35238bceSAndroid Build Coastguard Worker { 123*35238bceSAndroid Build Coastguard Worker if (ndx >= numVertices) 124*35238bceSAndroid Build Coastguard Worker break; 125*35238bceSAndroid Build Coastguard Worker 126*35238bceSAndroid Build Coastguard Worker *(outputIterator++) = Triangle(vert0, vert1, vertices[ndx], 127*35238bceSAndroid Build Coastguard Worker (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (1) : (2)); 128*35238bceSAndroid Build Coastguard Worker vert1 = vertices[ndx]; 129*35238bceSAndroid Build Coastguard Worker 130*35238bceSAndroid Build Coastguard Worker ndx++; 131*35238bceSAndroid Build Coastguard Worker } 132*35238bceSAndroid Build Coastguard Worker } 133*35238bceSAndroid Build Coastguard Worker } 134*35238bceSAndroid Build Coastguard Worker } 135*35238bceSAndroid Build Coastguard Worker getPrimitiveCountrr::pa::TriangleStrip136*35238bceSAndroid Build Coastguard Worker static size_t getPrimitiveCount(size_t vertices) 137*35238bceSAndroid Build Coastguard Worker { 138*35238bceSAndroid Build Coastguard Worker return (vertices < 3) ? (0) : (vertices - 2); 139*35238bceSAndroid Build Coastguard Worker } 140*35238bceSAndroid Build Coastguard Worker } DE_WARN_UNUSED_TYPE; 141*35238bceSAndroid Build Coastguard Worker 142*35238bceSAndroid Build Coastguard Worker struct TriangleFan 143*35238bceSAndroid Build Coastguard Worker { 144*35238bceSAndroid Build Coastguard Worker template <typename Iterator> execrr::pa::TriangleFan145*35238bceSAndroid Build Coastguard Worker static void exec(Iterator outputIterator, VertexPacket *const *vertices, size_t numVertices, 146*35238bceSAndroid Build Coastguard Worker rr::ProvokingVertex provokingConvention) 147*35238bceSAndroid Build Coastguard Worker { 148*35238bceSAndroid Build Coastguard Worker if (numVertices == 0) 149*35238bceSAndroid Build Coastguard Worker { 150*35238bceSAndroid Build Coastguard Worker } 151*35238bceSAndroid Build Coastguard Worker else 152*35238bceSAndroid Build Coastguard Worker { 153*35238bceSAndroid Build Coastguard Worker const int provokingOffset = (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (1) : (2); 154*35238bceSAndroid Build Coastguard Worker VertexPacket *const first = vertices[0]; 155*35238bceSAndroid Build Coastguard Worker 156*35238bceSAndroid Build Coastguard Worker for (size_t ndx = 1; ndx + 1 < numVertices; ++ndx) 157*35238bceSAndroid Build Coastguard Worker *(outputIterator++) = Triangle(first, vertices[ndx], vertices[ndx + 1], provokingOffset); 158*35238bceSAndroid Build Coastguard Worker } 159*35238bceSAndroid Build Coastguard Worker } 160*35238bceSAndroid Build Coastguard Worker getPrimitiveCountrr::pa::TriangleFan161*35238bceSAndroid Build Coastguard Worker static size_t getPrimitiveCount(size_t vertices) 162*35238bceSAndroid Build Coastguard Worker { 163*35238bceSAndroid Build Coastguard Worker return (vertices < 3) ? (0) : (vertices - 2); 164*35238bceSAndroid Build Coastguard Worker } 165*35238bceSAndroid Build Coastguard Worker } DE_WARN_UNUSED_TYPE; 166*35238bceSAndroid Build Coastguard Worker 167*35238bceSAndroid Build Coastguard Worker struct Line 168*35238bceSAndroid Build Coastguard Worker { 169*35238bceSAndroid Build Coastguard Worker enum 170*35238bceSAndroid Build Coastguard Worker { 171*35238bceSAndroid Build Coastguard Worker NUM_VERTICES = 2 172*35238bceSAndroid Build Coastguard Worker }; 173*35238bceSAndroid Build Coastguard Worker Linerr::pa::Line174*35238bceSAndroid Build Coastguard Worker Line(void) : v0(DE_NULL), v1(DE_NULL), provokingIndex(-1) 175*35238bceSAndroid Build Coastguard Worker { 176*35238bceSAndroid Build Coastguard Worker } 177*35238bceSAndroid Build Coastguard Worker Linerr::pa::Line178*35238bceSAndroid Build Coastguard Worker Line(VertexPacket *v0_, VertexPacket *v1_, int provokingIndex_) : v0(v0_), v1(v1_), provokingIndex(provokingIndex_) 179*35238bceSAndroid Build Coastguard Worker { 180*35238bceSAndroid Build Coastguard Worker } 181*35238bceSAndroid Build Coastguard Worker getProvokingVertexrr::pa::Line182*35238bceSAndroid Build Coastguard Worker VertexPacket *getProvokingVertex(void) 183*35238bceSAndroid Build Coastguard Worker { 184*35238bceSAndroid Build Coastguard Worker switch (provokingIndex) 185*35238bceSAndroid Build Coastguard Worker { 186*35238bceSAndroid Build Coastguard Worker case 0: 187*35238bceSAndroid Build Coastguard Worker return v0; 188*35238bceSAndroid Build Coastguard Worker case 1: 189*35238bceSAndroid Build Coastguard Worker return v1; 190*35238bceSAndroid Build Coastguard Worker default: 191*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false); 192*35238bceSAndroid Build Coastguard Worker return DE_NULL; 193*35238bceSAndroid Build Coastguard Worker } 194*35238bceSAndroid Build Coastguard Worker } 195*35238bceSAndroid Build Coastguard Worker 196*35238bceSAndroid Build Coastguard Worker VertexPacket *v0; 197*35238bceSAndroid Build Coastguard Worker VertexPacket *v1; 198*35238bceSAndroid Build Coastguard Worker 199*35238bceSAndroid Build Coastguard Worker int provokingIndex; 200*35238bceSAndroid Build Coastguard Worker } DE_WARN_UNUSED_TYPE; 201*35238bceSAndroid Build Coastguard Worker 202*35238bceSAndroid Build Coastguard Worker struct Lines 203*35238bceSAndroid Build Coastguard Worker { 204*35238bceSAndroid Build Coastguard Worker template <typename Iterator> execrr::pa::Lines205*35238bceSAndroid Build Coastguard Worker static void exec(Iterator outputIterator, VertexPacket *const *vertices, size_t numVertices, 206*35238bceSAndroid Build Coastguard Worker rr::ProvokingVertex provokingConvention) 207*35238bceSAndroid Build Coastguard Worker { 208*35238bceSAndroid Build Coastguard Worker const int provokingOffset = (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (0) : (1); 209*35238bceSAndroid Build Coastguard Worker 210*35238bceSAndroid Build Coastguard Worker for (size_t ndx = 0; ndx + 1 < numVertices; ndx += 2) 211*35238bceSAndroid Build Coastguard Worker *(outputIterator++) = Line(vertices[ndx], vertices[ndx + 1], provokingOffset); 212*35238bceSAndroid Build Coastguard Worker } 213*35238bceSAndroid Build Coastguard Worker getPrimitiveCountrr::pa::Lines214*35238bceSAndroid Build Coastguard Worker static size_t getPrimitiveCount(size_t vertices) 215*35238bceSAndroid Build Coastguard Worker { 216*35238bceSAndroid Build Coastguard Worker return vertices / 2; 217*35238bceSAndroid Build Coastguard Worker } 218*35238bceSAndroid Build Coastguard Worker } DE_WARN_UNUSED_TYPE; 219*35238bceSAndroid Build Coastguard Worker 220*35238bceSAndroid Build Coastguard Worker struct LineStrip 221*35238bceSAndroid Build Coastguard Worker { 222*35238bceSAndroid Build Coastguard Worker template <typename Iterator> execrr::pa::LineStrip223*35238bceSAndroid Build Coastguard Worker static void exec(Iterator outputIterator, VertexPacket *const *vertices, size_t numVertices, 224*35238bceSAndroid Build Coastguard Worker rr::ProvokingVertex provokingConvention) 225*35238bceSAndroid Build Coastguard Worker { 226*35238bceSAndroid Build Coastguard Worker if (numVertices == 0) 227*35238bceSAndroid Build Coastguard Worker { 228*35238bceSAndroid Build Coastguard Worker } 229*35238bceSAndroid Build Coastguard Worker else 230*35238bceSAndroid Build Coastguard Worker { 231*35238bceSAndroid Build Coastguard Worker VertexPacket *prev = vertices[0]; 232*35238bceSAndroid Build Coastguard Worker 233*35238bceSAndroid Build Coastguard Worker for (size_t ndx = 1; ndx < numVertices; ++ndx) 234*35238bceSAndroid Build Coastguard Worker { 235*35238bceSAndroid Build Coastguard Worker *(outputIterator++) = 236*35238bceSAndroid Build Coastguard Worker Line(prev, vertices[ndx], (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (0) : (1)); 237*35238bceSAndroid Build Coastguard Worker prev = vertices[ndx]; 238*35238bceSAndroid Build Coastguard Worker } 239*35238bceSAndroid Build Coastguard Worker } 240*35238bceSAndroid Build Coastguard Worker } 241*35238bceSAndroid Build Coastguard Worker getPrimitiveCountrr::pa::LineStrip242*35238bceSAndroid Build Coastguard Worker static size_t getPrimitiveCount(size_t vertices) 243*35238bceSAndroid Build Coastguard Worker { 244*35238bceSAndroid Build Coastguard Worker return (vertices < 2) ? (0) : (vertices - 1); 245*35238bceSAndroid Build Coastguard Worker } 246*35238bceSAndroid Build Coastguard Worker } DE_WARN_UNUSED_TYPE; 247*35238bceSAndroid Build Coastguard Worker 248*35238bceSAndroid Build Coastguard Worker struct LineLoop 249*35238bceSAndroid Build Coastguard Worker { 250*35238bceSAndroid Build Coastguard Worker template <typename Iterator> execrr::pa::LineLoop251*35238bceSAndroid Build Coastguard Worker static void exec(Iterator outputIterator, VertexPacket *const *vertices, size_t numVertices, 252*35238bceSAndroid Build Coastguard Worker rr::ProvokingVertex provokingConvention) 253*35238bceSAndroid Build Coastguard Worker { 254*35238bceSAndroid Build Coastguard Worker if (numVertices < 2) 255*35238bceSAndroid Build Coastguard Worker { 256*35238bceSAndroid Build Coastguard Worker } 257*35238bceSAndroid Build Coastguard Worker else 258*35238bceSAndroid Build Coastguard Worker { 259*35238bceSAndroid Build Coastguard Worker VertexPacket *prev = vertices[0]; 260*35238bceSAndroid Build Coastguard Worker 261*35238bceSAndroid Build Coastguard Worker for (size_t ndx = 1; ndx < numVertices; ++ndx) 262*35238bceSAndroid Build Coastguard Worker { 263*35238bceSAndroid Build Coastguard Worker *(outputIterator++) = 264*35238bceSAndroid Build Coastguard Worker Line(prev, vertices[ndx], (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (0) : (1)); 265*35238bceSAndroid Build Coastguard Worker prev = vertices[ndx]; 266*35238bceSAndroid Build Coastguard Worker } 267*35238bceSAndroid Build Coastguard Worker 268*35238bceSAndroid Build Coastguard Worker *(outputIterator++) = 269*35238bceSAndroid Build Coastguard Worker Line(prev, vertices[0], (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (0) : (1)); 270*35238bceSAndroid Build Coastguard Worker } 271*35238bceSAndroid Build Coastguard Worker } 272*35238bceSAndroid Build Coastguard Worker getPrimitiveCountrr::pa::LineLoop273*35238bceSAndroid Build Coastguard Worker static size_t getPrimitiveCount(size_t vertices) 274*35238bceSAndroid Build Coastguard Worker { 275*35238bceSAndroid Build Coastguard Worker return (vertices < 2) ? (0) : (vertices); 276*35238bceSAndroid Build Coastguard Worker } 277*35238bceSAndroid Build Coastguard Worker } DE_WARN_UNUSED_TYPE; 278*35238bceSAndroid Build Coastguard Worker 279*35238bceSAndroid Build Coastguard Worker struct Point 280*35238bceSAndroid Build Coastguard Worker { 281*35238bceSAndroid Build Coastguard Worker enum 282*35238bceSAndroid Build Coastguard Worker { 283*35238bceSAndroid Build Coastguard Worker NUM_VERTICES = 1 284*35238bceSAndroid Build Coastguard Worker }; 285*35238bceSAndroid Build Coastguard Worker Pointrr::pa::Point286*35238bceSAndroid Build Coastguard Worker Point(void) : v0(DE_NULL) 287*35238bceSAndroid Build Coastguard Worker { 288*35238bceSAndroid Build Coastguard Worker } 289*35238bceSAndroid Build Coastguard Worker Pointrr::pa::Point290*35238bceSAndroid Build Coastguard Worker Point(VertexPacket *v0_) : v0(v0_) 291*35238bceSAndroid Build Coastguard Worker { 292*35238bceSAndroid Build Coastguard Worker } 293*35238bceSAndroid Build Coastguard Worker 294*35238bceSAndroid Build Coastguard Worker VertexPacket *v0; 295*35238bceSAndroid Build Coastguard Worker } DE_WARN_UNUSED_TYPE; 296*35238bceSAndroid Build Coastguard Worker 297*35238bceSAndroid Build Coastguard Worker struct Points 298*35238bceSAndroid Build Coastguard Worker { 299*35238bceSAndroid Build Coastguard Worker template <typename Iterator> execrr::pa::Points300*35238bceSAndroid Build Coastguard Worker static void exec(Iterator outputIterator, VertexPacket *const *vertices, size_t numVertices, 301*35238bceSAndroid Build Coastguard Worker rr::ProvokingVertex provokingConvention) 302*35238bceSAndroid Build Coastguard Worker { 303*35238bceSAndroid Build Coastguard Worker DE_UNREF(provokingConvention); 304*35238bceSAndroid Build Coastguard Worker 305*35238bceSAndroid Build Coastguard Worker for (size_t ndx = 0; ndx < numVertices; ++ndx) 306*35238bceSAndroid Build Coastguard Worker *(outputIterator++) = Point(vertices[ndx]); 307*35238bceSAndroid Build Coastguard Worker } 308*35238bceSAndroid Build Coastguard Worker getPrimitiveCountrr::pa::Points309*35238bceSAndroid Build Coastguard Worker static size_t getPrimitiveCount(size_t vertices) 310*35238bceSAndroid Build Coastguard Worker { 311*35238bceSAndroid Build Coastguard Worker return (vertices); 312*35238bceSAndroid Build Coastguard Worker } 313*35238bceSAndroid Build Coastguard Worker } DE_WARN_UNUSED_TYPE; 314*35238bceSAndroid Build Coastguard Worker 315*35238bceSAndroid Build Coastguard Worker struct LineAdjacency 316*35238bceSAndroid Build Coastguard Worker { 317*35238bceSAndroid Build Coastguard Worker enum 318*35238bceSAndroid Build Coastguard Worker { 319*35238bceSAndroid Build Coastguard Worker NUM_VERTICES = 4 320*35238bceSAndroid Build Coastguard Worker }; 321*35238bceSAndroid Build Coastguard Worker LineAdjacencyrr::pa::LineAdjacency322*35238bceSAndroid Build Coastguard Worker LineAdjacency(void) : v0(DE_NULL), v1(DE_NULL), v2(DE_NULL), v3(DE_NULL), provokingIndex(-1) 323*35238bceSAndroid Build Coastguard Worker { 324*35238bceSAndroid Build Coastguard Worker } 325*35238bceSAndroid Build Coastguard Worker LineAdjacencyrr::pa::LineAdjacency326*35238bceSAndroid Build Coastguard Worker LineAdjacency(VertexPacket *v0_, VertexPacket *v1_, VertexPacket *v2_, VertexPacket *v3_, int provokingIndex_) 327*35238bceSAndroid Build Coastguard Worker : v0(v0_) 328*35238bceSAndroid Build Coastguard Worker , v1(v1_) 329*35238bceSAndroid Build Coastguard Worker , v2(v2_) 330*35238bceSAndroid Build Coastguard Worker , v3(v3_) 331*35238bceSAndroid Build Coastguard Worker , provokingIndex(provokingIndex_) 332*35238bceSAndroid Build Coastguard Worker { 333*35238bceSAndroid Build Coastguard Worker } 334*35238bceSAndroid Build Coastguard Worker getProvokingVertexrr::pa::LineAdjacency335*35238bceSAndroid Build Coastguard Worker VertexPacket *getProvokingVertex(void) 336*35238bceSAndroid Build Coastguard Worker { 337*35238bceSAndroid Build Coastguard Worker switch (provokingIndex) 338*35238bceSAndroid Build Coastguard Worker { 339*35238bceSAndroid Build Coastguard Worker case 1: 340*35238bceSAndroid Build Coastguard Worker return v1; 341*35238bceSAndroid Build Coastguard Worker case 2: 342*35238bceSAndroid Build Coastguard Worker return v2; 343*35238bceSAndroid Build Coastguard Worker default: 344*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false); 345*35238bceSAndroid Build Coastguard Worker return DE_NULL; 346*35238bceSAndroid Build Coastguard Worker } 347*35238bceSAndroid Build Coastguard Worker } 348*35238bceSAndroid Build Coastguard Worker 349*35238bceSAndroid Build Coastguard Worker VertexPacket *v0; 350*35238bceSAndroid Build Coastguard Worker VertexPacket *v1; 351*35238bceSAndroid Build Coastguard Worker VertexPacket *v2; 352*35238bceSAndroid Build Coastguard Worker VertexPacket *v3; 353*35238bceSAndroid Build Coastguard Worker 354*35238bceSAndroid Build Coastguard Worker int provokingIndex; 355*35238bceSAndroid Build Coastguard Worker } DE_WARN_UNUSED_TYPE; 356*35238bceSAndroid Build Coastguard Worker 357*35238bceSAndroid Build Coastguard Worker struct LinesAdjacency 358*35238bceSAndroid Build Coastguard Worker { 359*35238bceSAndroid Build Coastguard Worker template <typename Iterator> execrr::pa::LinesAdjacency360*35238bceSAndroid Build Coastguard Worker static void exec(Iterator outputIterator, VertexPacket *const *vertices, size_t numVertices, 361*35238bceSAndroid Build Coastguard Worker rr::ProvokingVertex provokingConvention) 362*35238bceSAndroid Build Coastguard Worker { 363*35238bceSAndroid Build Coastguard Worker const int provokingOffset = (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (1) : (2); 364*35238bceSAndroid Build Coastguard Worker 365*35238bceSAndroid Build Coastguard Worker for (size_t ndx = 0; ndx + 3 < numVertices; ndx += 4) 366*35238bceSAndroid Build Coastguard Worker *(outputIterator++) = 367*35238bceSAndroid Build Coastguard Worker LineAdjacency(vertices[ndx], vertices[ndx + 1], vertices[ndx + 2], vertices[ndx + 3], provokingOffset); 368*35238bceSAndroid Build Coastguard Worker } 369*35238bceSAndroid Build Coastguard Worker getPrimitiveCountrr::pa::LinesAdjacency370*35238bceSAndroid Build Coastguard Worker static size_t getPrimitiveCount(size_t vertices) 371*35238bceSAndroid Build Coastguard Worker { 372*35238bceSAndroid Build Coastguard Worker return vertices / 4; 373*35238bceSAndroid Build Coastguard Worker } 374*35238bceSAndroid Build Coastguard Worker } DE_WARN_UNUSED_TYPE; 375*35238bceSAndroid Build Coastguard Worker 376*35238bceSAndroid Build Coastguard Worker struct LineStripAdjacency 377*35238bceSAndroid Build Coastguard Worker { 378*35238bceSAndroid Build Coastguard Worker template <typename Iterator> execrr::pa::LineStripAdjacency379*35238bceSAndroid Build Coastguard Worker static void exec(Iterator outputIterator, VertexPacket *const *vertices, size_t numVertices, 380*35238bceSAndroid Build Coastguard Worker rr::ProvokingVertex provokingConvention) 381*35238bceSAndroid Build Coastguard Worker { 382*35238bceSAndroid Build Coastguard Worker const int provokingOffset = (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (1) : (2); 383*35238bceSAndroid Build Coastguard Worker 384*35238bceSAndroid Build Coastguard Worker for (size_t ndx = 0; ndx + 3 < numVertices; ++ndx) 385*35238bceSAndroid Build Coastguard Worker *(outputIterator++) = 386*35238bceSAndroid Build Coastguard Worker LineAdjacency(vertices[ndx], vertices[ndx + 1], vertices[ndx + 2], vertices[ndx + 3], provokingOffset); 387*35238bceSAndroid Build Coastguard Worker } 388*35238bceSAndroid Build Coastguard Worker getPrimitiveCountrr::pa::LineStripAdjacency389*35238bceSAndroid Build Coastguard Worker static size_t getPrimitiveCount(size_t vertices) 390*35238bceSAndroid Build Coastguard Worker { 391*35238bceSAndroid Build Coastguard Worker return (vertices < 4) ? (0) : (vertices - 3); 392*35238bceSAndroid Build Coastguard Worker } 393*35238bceSAndroid Build Coastguard Worker } DE_WARN_UNUSED_TYPE; 394*35238bceSAndroid Build Coastguard Worker 395*35238bceSAndroid Build Coastguard Worker struct TriangleAdjacency 396*35238bceSAndroid Build Coastguard Worker { 397*35238bceSAndroid Build Coastguard Worker enum 398*35238bceSAndroid Build Coastguard Worker { 399*35238bceSAndroid Build Coastguard Worker NUM_VERTICES = 6 400*35238bceSAndroid Build Coastguard Worker }; 401*35238bceSAndroid Build Coastguard Worker TriangleAdjacencyrr::pa::TriangleAdjacency402*35238bceSAndroid Build Coastguard Worker TriangleAdjacency(void) 403*35238bceSAndroid Build Coastguard Worker : v0(DE_NULL) 404*35238bceSAndroid Build Coastguard Worker , v1(DE_NULL) 405*35238bceSAndroid Build Coastguard Worker , v2(DE_NULL) 406*35238bceSAndroid Build Coastguard Worker , v3(DE_NULL) 407*35238bceSAndroid Build Coastguard Worker , v4(DE_NULL) 408*35238bceSAndroid Build Coastguard Worker , v5(DE_NULL) 409*35238bceSAndroid Build Coastguard Worker , provokingIndex(-1) 410*35238bceSAndroid Build Coastguard Worker { 411*35238bceSAndroid Build Coastguard Worker } 412*35238bceSAndroid Build Coastguard Worker TriangleAdjacencyrr::pa::TriangleAdjacency413*35238bceSAndroid Build Coastguard Worker TriangleAdjacency(VertexPacket *v0_, VertexPacket *v1_, VertexPacket *v2_, VertexPacket *v3_, VertexPacket *v4_, 414*35238bceSAndroid Build Coastguard Worker VertexPacket *v5_, int provokingIndex_) 415*35238bceSAndroid Build Coastguard Worker : v0(v0_) 416*35238bceSAndroid Build Coastguard Worker , v1(v1_) 417*35238bceSAndroid Build Coastguard Worker , v2(v2_) 418*35238bceSAndroid Build Coastguard Worker , v3(v3_) 419*35238bceSAndroid Build Coastguard Worker , v4(v4_) 420*35238bceSAndroid Build Coastguard Worker , v5(v5_) 421*35238bceSAndroid Build Coastguard Worker , provokingIndex(provokingIndex_) 422*35238bceSAndroid Build Coastguard Worker { 423*35238bceSAndroid Build Coastguard Worker } 424*35238bceSAndroid Build Coastguard Worker getProvokingVertexrr::pa::TriangleAdjacency425*35238bceSAndroid Build Coastguard Worker VertexPacket *getProvokingVertex(void) 426*35238bceSAndroid Build Coastguard Worker { 427*35238bceSAndroid Build Coastguard Worker switch (provokingIndex) 428*35238bceSAndroid Build Coastguard Worker { 429*35238bceSAndroid Build Coastguard Worker case 0: 430*35238bceSAndroid Build Coastguard Worker return v0; 431*35238bceSAndroid Build Coastguard Worker case 2: 432*35238bceSAndroid Build Coastguard Worker return v2; 433*35238bceSAndroid Build Coastguard Worker case 4: 434*35238bceSAndroid Build Coastguard Worker return v4; 435*35238bceSAndroid Build Coastguard Worker default: 436*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false); 437*35238bceSAndroid Build Coastguard Worker return DE_NULL; 438*35238bceSAndroid Build Coastguard Worker } 439*35238bceSAndroid Build Coastguard Worker } 440*35238bceSAndroid Build Coastguard Worker 441*35238bceSAndroid Build Coastguard Worker VertexPacket *v0; 442*35238bceSAndroid Build Coastguard Worker VertexPacket *v1; //!< adjacent 443*35238bceSAndroid Build Coastguard Worker VertexPacket *v2; 444*35238bceSAndroid Build Coastguard Worker VertexPacket *v3; //!< adjacent 445*35238bceSAndroid Build Coastguard Worker VertexPacket *v4; 446*35238bceSAndroid Build Coastguard Worker VertexPacket *v5; //!< adjacent 447*35238bceSAndroid Build Coastguard Worker 448*35238bceSAndroid Build Coastguard Worker int provokingIndex; 449*35238bceSAndroid Build Coastguard Worker } DE_WARN_UNUSED_TYPE; 450*35238bceSAndroid Build Coastguard Worker 451*35238bceSAndroid Build Coastguard Worker struct TrianglesAdjacency 452*35238bceSAndroid Build Coastguard Worker { 453*35238bceSAndroid Build Coastguard Worker template <typename Iterator> execrr::pa::TrianglesAdjacency454*35238bceSAndroid Build Coastguard Worker static void exec(Iterator outputIterator, VertexPacket *const *vertices, size_t numVertices, 455*35238bceSAndroid Build Coastguard Worker rr::ProvokingVertex provokingConvention) 456*35238bceSAndroid Build Coastguard Worker { 457*35238bceSAndroid Build Coastguard Worker const int provokingOffset = (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (0) : (4); 458*35238bceSAndroid Build Coastguard Worker 459*35238bceSAndroid Build Coastguard Worker for (size_t ndx = 0; ndx + 5 < numVertices; ndx += 6) 460*35238bceSAndroid Build Coastguard Worker *(outputIterator++) = 461*35238bceSAndroid Build Coastguard Worker TriangleAdjacency(vertices[ndx], vertices[ndx + 1], vertices[ndx + 2], vertices[ndx + 3], 462*35238bceSAndroid Build Coastguard Worker vertices[ndx + 4], vertices[ndx + 5], provokingOffset); 463*35238bceSAndroid Build Coastguard Worker } 464*35238bceSAndroid Build Coastguard Worker getPrimitiveCountrr::pa::TrianglesAdjacency465*35238bceSAndroid Build Coastguard Worker static size_t getPrimitiveCount(size_t vertices) 466*35238bceSAndroid Build Coastguard Worker { 467*35238bceSAndroid Build Coastguard Worker return vertices / 6; 468*35238bceSAndroid Build Coastguard Worker } 469*35238bceSAndroid Build Coastguard Worker } DE_WARN_UNUSED_TYPE; 470*35238bceSAndroid Build Coastguard Worker 471*35238bceSAndroid Build Coastguard Worker struct TriangleStripAdjacency 472*35238bceSAndroid Build Coastguard Worker { 473*35238bceSAndroid Build Coastguard Worker template <typename Iterator> execrr::pa::TriangleStripAdjacency474*35238bceSAndroid Build Coastguard Worker static void exec(Iterator outputIterator, VertexPacket *const *vertices, size_t numVertices, 475*35238bceSAndroid Build Coastguard Worker rr::ProvokingVertex provokingConvention) 476*35238bceSAndroid Build Coastguard Worker { 477*35238bceSAndroid Build Coastguard Worker if (numVertices < 6) 478*35238bceSAndroid Build Coastguard Worker { 479*35238bceSAndroid Build Coastguard Worker } 480*35238bceSAndroid Build Coastguard Worker else if (numVertices < 8) 481*35238bceSAndroid Build Coastguard Worker { 482*35238bceSAndroid Build Coastguard Worker *(outputIterator++) = 483*35238bceSAndroid Build Coastguard Worker TriangleAdjacency(vertices[0], vertices[1], vertices[2], vertices[5], vertices[4], vertices[3], 484*35238bceSAndroid Build Coastguard Worker (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (0) : (4)); 485*35238bceSAndroid Build Coastguard Worker } 486*35238bceSAndroid Build Coastguard Worker else 487*35238bceSAndroid Build Coastguard Worker { 488*35238bceSAndroid Build Coastguard Worker const size_t primitiveCount = getPrimitiveCount(numVertices); 489*35238bceSAndroid Build Coastguard Worker size_t i; 490*35238bceSAndroid Build Coastguard Worker 491*35238bceSAndroid Build Coastguard Worker // first 492*35238bceSAndroid Build Coastguard Worker *(outputIterator++) = 493*35238bceSAndroid Build Coastguard Worker TriangleAdjacency(vertices[0], vertices[1], vertices[2], vertices[6], vertices[4], vertices[3], 494*35238bceSAndroid Build Coastguard Worker (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (0) : (4)); 495*35238bceSAndroid Build Coastguard Worker 496*35238bceSAndroid Build Coastguard Worker // middle 497*35238bceSAndroid Build Coastguard Worker for (i = 1; i + 1 < primitiveCount; ++i) 498*35238bceSAndroid Build Coastguard Worker { 499*35238bceSAndroid Build Coastguard Worker // odd 500*35238bceSAndroid Build Coastguard Worker if (i % 2 == 1) 501*35238bceSAndroid Build Coastguard Worker { 502*35238bceSAndroid Build Coastguard Worker *(outputIterator++) = 503*35238bceSAndroid Build Coastguard Worker TriangleAdjacency(vertices[2 * i + 2], vertices[2 * i - 2], vertices[2 * i + 0], 504*35238bceSAndroid Build Coastguard Worker vertices[2 * i + 3], vertices[2 * i + 4], vertices[2 * i + 6], 505*35238bceSAndroid Build Coastguard Worker (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (2) : (4)); 506*35238bceSAndroid Build Coastguard Worker } 507*35238bceSAndroid Build Coastguard Worker // even 508*35238bceSAndroid Build Coastguard Worker else 509*35238bceSAndroid Build Coastguard Worker { 510*35238bceSAndroid Build Coastguard Worker *(outputIterator++) = 511*35238bceSAndroid Build Coastguard Worker TriangleAdjacency(vertices[2 * i + 0], vertices[2 * i - 2], vertices[2 * i + 2], 512*35238bceSAndroid Build Coastguard Worker vertices[2 * i + 6], vertices[2 * i + 4], vertices[2 * i + 3], 513*35238bceSAndroid Build Coastguard Worker (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (0) : (4)); 514*35238bceSAndroid Build Coastguard Worker } 515*35238bceSAndroid Build Coastguard Worker } 516*35238bceSAndroid Build Coastguard Worker 517*35238bceSAndroid Build Coastguard Worker // last 518*35238bceSAndroid Build Coastguard Worker 519*35238bceSAndroid Build Coastguard Worker // odd 520*35238bceSAndroid Build Coastguard Worker if (i % 2 == 1) 521*35238bceSAndroid Build Coastguard Worker *(outputIterator++) = TriangleAdjacency(vertices[2 * i + 2], vertices[2 * i - 2], vertices[2 * i + 0], 522*35238bceSAndroid Build Coastguard Worker vertices[2 * i + 3], vertices[2 * i + 4], vertices[2 * i + 5], 523*35238bceSAndroid Build Coastguard Worker (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (2) : (4)); 524*35238bceSAndroid Build Coastguard Worker // even 525*35238bceSAndroid Build Coastguard Worker else 526*35238bceSAndroid Build Coastguard Worker *(outputIterator++) = TriangleAdjacency(vertices[2 * i + 0], vertices[2 * i - 2], vertices[2 * i + 2], 527*35238bceSAndroid Build Coastguard Worker vertices[2 * i + 5], vertices[2 * i + 4], vertices[2 * i + 3], 528*35238bceSAndroid Build Coastguard Worker (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (0) : (4)); 529*35238bceSAndroid Build Coastguard Worker } 530*35238bceSAndroid Build Coastguard Worker } 531*35238bceSAndroid Build Coastguard Worker getPrimitiveCountrr::pa::TriangleStripAdjacency532*35238bceSAndroid Build Coastguard Worker static size_t getPrimitiveCount(size_t vertices) 533*35238bceSAndroid Build Coastguard Worker { 534*35238bceSAndroid Build Coastguard Worker return (vertices < 6) ? 0 : ((vertices - 4) / 2); 535*35238bceSAndroid Build Coastguard Worker } 536*35238bceSAndroid Build Coastguard Worker } DE_WARN_UNUSED_TYPE; 537*35238bceSAndroid Build Coastguard Worker 538*35238bceSAndroid Build Coastguard Worker } // namespace pa 539*35238bceSAndroid Build Coastguard Worker } // namespace rr 540*35238bceSAndroid Build Coastguard Worker 541*35238bceSAndroid Build Coastguard Worker #endif // _RRPRIMITIVEASSEMBLER_HPP 542