1 #ifndef _RRPRIMITIVEASSEMBLER_HPP
2 #define _RRPRIMITIVEASSEMBLER_HPP
3 /*-------------------------------------------------------------------------
4 * drawElements Quality Program Reference Renderer
5 * -----------------------------------------------
7 * Copyright 2014 The Android Open Source Project
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
23 * \brief Primitive assembler
24 *//*--------------------------------------------------------------------*/
27 #include "rrVertexPacket.hpp"
49 Triangle (VertexPacket* v0_, VertexPacket* v1_, VertexPacket* v2_, int provokingIndex_)
53 , provokingIndex (provokingIndex_)
57 VertexPacket* getProvokingVertex (void)
59 switch (provokingIndex)
75 } DE_WARN_UNUSED_TYPE;
79 template <typename Iterator>
80 static void exec (Iterator outputIterator, VertexPacket* const* vertices, size_t numVertices, rr::ProvokingVertex provokingConvention)
82 const int provokingOffset = (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (0) : (2);
84 for (size_t ndx = 0; ndx + 2 < numVertices; ndx += 3)
85 *(outputIterator++) = Triangle(vertices[ndx], vertices[ndx+1], vertices[ndx+2], provokingOffset);
88 static size_t getPrimitiveCount (size_t vertices)
92 } DE_WARN_UNUSED_TYPE;
96 template <typename Iterator>
97 static void exec (Iterator outputIterator, VertexPacket* const* vertices, size_t numVertices, rr::ProvokingVertex provokingConvention)
104 VertexPacket* vert0 = vertices[0];
105 VertexPacket* vert1 = vertices[1];
111 if (ndx >= numVertices)
114 *(outputIterator++) = Triangle(vert0, vert1, vertices[ndx], (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (0) : (2));
115 vert0 = vertices[ndx];
121 if (ndx >= numVertices)
124 *(outputIterator++) = Triangle(vert0, vert1, vertices[ndx], (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (1) : (2));
125 vert1 = vertices[ndx];
133 static size_t getPrimitiveCount (size_t vertices)
135 return (vertices < 3) ? (0) : (vertices - 2);
137 } DE_WARN_UNUSED_TYPE;
141 template <typename Iterator>
142 static void exec (Iterator outputIterator, VertexPacket* const* vertices, size_t numVertices, rr::ProvokingVertex provokingConvention)
144 if (numVertices == 0)
149 const int provokingOffset = (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (1) : (2);
150 VertexPacket* const first = vertices[0];
152 for (size_t ndx = 1; ndx + 1 < numVertices; ++ndx)
153 *(outputIterator++) = Triangle(first, vertices[ndx], vertices[ndx+1], provokingOffset);
157 static size_t getPrimitiveCount (size_t vertices)
159 return (vertices < 3) ? (0) : (vertices - 2);
161 } DE_WARN_UNUSED_TYPE;
173 , provokingIndex (-1)
177 Line (VertexPacket* v0_, VertexPacket* v1_, int provokingIndex_)
180 , provokingIndex (provokingIndex_)
184 VertexPacket* getProvokingVertex (void)
186 switch (provokingIndex)
200 } DE_WARN_UNUSED_TYPE;
204 template <typename Iterator>
205 static void exec (Iterator outputIterator, VertexPacket* const* vertices, size_t numVertices, rr::ProvokingVertex provokingConvention)
207 const int provokingOffset = (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (0) : (1);
209 for (size_t ndx = 0; ndx + 1 < numVertices; ndx += 2)
210 *(outputIterator++) = Line(vertices[ndx], vertices[ndx+1], provokingOffset);
213 static size_t getPrimitiveCount (size_t vertices)
217 } DE_WARN_UNUSED_TYPE;
221 template <typename Iterator>
222 static void exec (Iterator outputIterator, VertexPacket* const* vertices, size_t numVertices, rr::ProvokingVertex provokingConvention)
224 if (numVertices == 0)
229 VertexPacket* prev = vertices[0];
231 for (size_t ndx = 1; ndx < numVertices; ++ndx)
233 *(outputIterator++) = Line(prev, vertices[ndx], (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (0) : (1));
234 prev = vertices[ndx];
239 static size_t getPrimitiveCount (size_t vertices)
241 return (vertices < 2) ? (0) : (vertices - 1);
243 } DE_WARN_UNUSED_TYPE;
247 template <typename Iterator>
248 static void exec (Iterator outputIterator, VertexPacket* const* vertices, size_t numVertices, rr::ProvokingVertex provokingConvention)
255 VertexPacket* prev = vertices[0];
257 for (size_t ndx = 1; ndx < numVertices; ++ndx)
259 *(outputIterator++) = Line(prev, vertices[ndx], (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (0) : (1));
260 prev = vertices[ndx];
263 *(outputIterator++) = Line(prev, vertices[0], (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (0) : (1));
267 static size_t getPrimitiveCount (size_t vertices)
269 return (vertices < 2) ? (0) : (vertices);
271 } DE_WARN_UNUSED_TYPE;
285 Point (VertexPacket* v0_)
291 } DE_WARN_UNUSED_TYPE;
295 template <typename Iterator>
296 static void exec (Iterator outputIterator, VertexPacket* const* vertices, size_t numVertices, rr::ProvokingVertex provokingConvention)
298 DE_UNREF(provokingConvention);
300 for (size_t ndx = 0; ndx < numVertices; ++ndx)
301 *(outputIterator++) = Point(vertices[ndx]);
304 static size_t getPrimitiveCount (size_t vertices)
308 } DE_WARN_UNUSED_TYPE;
322 , provokingIndex (-1)
326 LineAdjacency (VertexPacket* v0_, VertexPacket* v1_, VertexPacket* v2_, VertexPacket* v3_, int provokingIndex_)
331 , provokingIndex (provokingIndex_)
335 VertexPacket* getProvokingVertex (void)
337 switch (provokingIndex)
353 } DE_WARN_UNUSED_TYPE;
355 struct LinesAdjacency
357 template <typename Iterator>
358 static void exec (Iterator outputIterator, VertexPacket* const* vertices, size_t numVertices, rr::ProvokingVertex provokingConvention)
360 const int provokingOffset = (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (1) : (2);
362 for (size_t ndx = 0; ndx + 3 < numVertices; ndx += 4)
363 *(outputIterator++) = LineAdjacency(vertices[ndx], vertices[ndx+1], vertices[ndx+2], vertices[ndx+3], provokingOffset);
366 static size_t getPrimitiveCount (size_t vertices)
370 } DE_WARN_UNUSED_TYPE;
372 struct LineStripAdjacency
374 template <typename Iterator>
375 static void exec (Iterator outputIterator, VertexPacket* const* vertices, size_t numVertices, rr::ProvokingVertex provokingConvention)
377 const int provokingOffset = (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (1) : (2);
379 for (size_t ndx = 0; ndx + 3 < numVertices; ++ndx)
380 *(outputIterator++) = LineAdjacency(vertices[ndx], vertices[ndx+1], vertices[ndx+2], vertices[ndx+3], provokingOffset);
383 static size_t getPrimitiveCount (size_t vertices)
385 return (vertices < 4) ? (0) : (vertices - 3);
387 } DE_WARN_UNUSED_TYPE;
389 struct TriangleAdjacency
396 TriangleAdjacency (void)
403 , provokingIndex (-1)
407 TriangleAdjacency (VertexPacket* v0_, VertexPacket* v1_, VertexPacket* v2_, VertexPacket* v3_, VertexPacket* v4_, VertexPacket* v5_, int provokingIndex_)
414 , provokingIndex (provokingIndex_)
418 VertexPacket* getProvokingVertex (void)
420 switch (provokingIndex)
432 VertexPacket* v1; //!< adjacent
434 VertexPacket* v3; //!< adjacent
436 VertexPacket* v5; //!< adjacent
439 } DE_WARN_UNUSED_TYPE;
441 struct TrianglesAdjacency
443 template <typename Iterator>
444 static void exec (Iterator outputIterator, VertexPacket* const* vertices, size_t numVertices, rr::ProvokingVertex provokingConvention)
446 const int provokingOffset = (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (0) : (4);
448 for (size_t ndx = 0; ndx + 5 < numVertices; ndx += 6)
449 *(outputIterator++) = TriangleAdjacency(vertices[ndx], vertices[ndx+1], vertices[ndx+2], vertices[ndx+3], vertices[ndx+4], vertices[ndx+5], provokingOffset);
452 static size_t getPrimitiveCount (size_t vertices)
456 } DE_WARN_UNUSED_TYPE;
458 struct TriangleStripAdjacency
460 template <typename Iterator>
461 static void exec (Iterator outputIterator, VertexPacket* const* vertices, size_t numVertices, rr::ProvokingVertex provokingConvention)
466 else if (numVertices < 8)
468 *(outputIterator++) = TriangleAdjacency(vertices[0], vertices[1], vertices[2], vertices[5], vertices[4], vertices[3], (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (0) : (4));
472 const size_t primitiveCount = getPrimitiveCount(numVertices);
476 *(outputIterator++) = TriangleAdjacency(vertices[0], vertices[1], vertices[2], vertices[6], vertices[4], vertices[3], (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (0) : (4));
479 for (i = 1; i + 1 < primitiveCount; ++i)
484 *(outputIterator++) = TriangleAdjacency(vertices[2*i+2], vertices[2*i-2], vertices[2*i+0], vertices[2*i+3], vertices[2*i+4], vertices[2*i+6], (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (2) : (4));
489 *(outputIterator++) = TriangleAdjacency(vertices[2*i+0], vertices[2*i-2], vertices[2*i+2], vertices[2*i+6], vertices[2*i+4], vertices[2*i+3], (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (0) : (4));
497 *(outputIterator++) = TriangleAdjacency(vertices[2*i+2], vertices[2*i-2], vertices[2*i+0], vertices[2*i+3], vertices[2*i+4], vertices[2*i+5], (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (2) : (4));
500 *(outputIterator++) = TriangleAdjacency(vertices[2*i+0], vertices[2*i-2], vertices[2*i+2], vertices[2*i+5], vertices[2*i+4], vertices[2*i+3], (provokingConvention == rr::PROVOKINGVERTEX_FIRST) ? (0) : (4));
504 static size_t getPrimitiveCount (size_t vertices)
506 return (vertices < 6) ? 0 : ((vertices - 4) / 2);
508 } DE_WARN_UNUSED_TYPE;
513 #endif // _RRPRIMITIVEASSEMBLER_HPP