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