1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2014-2016 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */ /*!
20  * \file
21  * \brief
22  */ /*-------------------------------------------------------------------*/
23 
24 #include "glwEnums.inl"
25 
26 #include "deMath.h"
27 #include "esextcGeometryShaderAdjacencyTests.hpp"
28 #include <cstring>
29 
30 namespace glcts
31 {
32 
33 /** Constructor
34  *
35  * @param context       Test context
36  * @param name          Test case's name
37  * @param description   Test case's description
38  **/
GeometryShaderAdjacencyTests(Context & context,const ExtParameters & extParams,const char * name,const char * description)39 GeometryShaderAdjacencyTests::GeometryShaderAdjacencyTests(Context &context, const ExtParameters &extParams,
40                                                            const char *name, const char *description)
41     : TestCaseGroupBase(context, extParams, name, description)
42     , m_grid_granulity(1)
43     , m_n_components_input(2)
44     , m_n_components_output(4)
45     , m_n_line_segments(4)
46     , m_n_vertices_per_triangle(3)
47 {
48     /* Nothing to be done here */
49 }
50 
51 /** Deinitializes tests data
52  *
53  **/
deinit(void)54 void GeometryShaderAdjacencyTests::deinit(void)
55 {
56     for (std::vector<AdjacencyTestData *>::iterator it = m_tests_data.begin(); it != m_tests_data.end(); ++it)
57     {
58         delete *it;
59         *it = NULL;
60     }
61 
62     m_tests_data.clear();
63 
64     /* Call base class' deinit() function. */
65     glcts::TestCaseGroupBase::deinit();
66 }
67 
68 /** Initializes tests data
69  *
70  **/
init(void)71 void GeometryShaderAdjacencyTests::init(void)
72 {
73     /* Tests for GL_LINES_ADJACENCY_EXT */
74 
75     /* Test 2.1 Non indiced Data */
76     m_tests_data.push_back(new AdjacencyTestData());
77     configureTestDataLines(*m_tests_data.back(), true, false);
78     addChild(new GeometryShaderAdjacency(getContext(), m_extParams, "adjacency_non_indiced_lines",
79                                          "Test 2.1 non indiced", *m_tests_data.back()));
80     /* Test 2.1 indiced Data */
81     m_tests_data.push_back(new AdjacencyTestData());
82     configureTestDataLines(*m_tests_data.back(), true, true);
83     addChild(new GeometryShaderAdjacency(getContext(), m_extParams, "adjacency_indiced_lines", "Test 2.1 indiced",
84                                          *m_tests_data.back()));
85 
86     /* Tests for GL_LINE_STRIP_ADJACENCY_EXT */
87 
88     /* Test 2.3 Non indiced Data */
89     m_tests_data.push_back(new AdjacencyTestData());
90     configureTestDataLineStrip(*m_tests_data.back(), true, false);
91     addChild(new GeometryShaderAdjacency(getContext(), m_extParams, "adjacency_non_indiced_line_strip",
92                                          "Test 2.3 non indiced", *m_tests_data.back()));
93     /* Test 2.3 indiced Data */
94     m_tests_data.push_back(new AdjacencyTestData());
95     configureTestDataLineStrip(*m_tests_data.back(), true, true);
96     addChild(new GeometryShaderAdjacency(getContext(), m_extParams, "adjacency_indiced_line_strip", "Test 2.3 indiced",
97                                          *m_tests_data.back()));
98 
99     /* Tests for GL_TRIANGLES_ADJACENCY_EXT */
100 
101     /* Test 2.5 Non indiced Data */
102     m_tests_data.push_back(new AdjacencyTestData());
103     configureTestDataTriangles(*m_tests_data.back(), true, false);
104     addChild(new GeometryShaderAdjacency(getContext(), m_extParams, "adjacency_non_indiced_triangles",
105                                          "Test 2.5 non indiced", *m_tests_data.back()));
106     /* Test 2.5 indiced Data */
107     m_tests_data.push_back(new AdjacencyTestData());
108     configureTestDataTriangles(*m_tests_data.back(), true, true);
109     addChild(new GeometryShaderAdjacency(getContext(), m_extParams, "adjacency_indiced_triangles", "Test 2.5 indiced",
110                                          *m_tests_data.back()));
111 
112     /* Tests for GL_TRIANGLE_STRIP_ADJACENCY_EXT */
113 
114     /* Test 2.7 Non indiced Data */
115     m_tests_data.push_back(new AdjacencyTestData());
116     configureTestDataTriangleStrip(*m_tests_data.back(), true, false);
117     addChild(new GeometryShaderAdjacency(getContext(), m_extParams, "adjacency_non_indiced_triangle_strip",
118                                          "Test 2.7 non indiced", *m_tests_data.back()));
119     /* Test 2.7 indiced Data */
120     m_tests_data.push_back(new AdjacencyTestData());
121     configureTestDataTriangleStrip(*m_tests_data.back(), true, true);
122     addChild(new GeometryShaderAdjacency(getContext(), m_extParams, "adjacency_indiced_triangle_strip",
123                                          "Test 2.7 indiced", *m_tests_data.back()));
124 }
125 
126 /** Configure Test Data for GL_LINES_ADJACENCY_EXT drawing mode
127  *
128  *  @param testData reference to AdjacencyTestData instance to be configured
129  *                  accordingly;
130  *  @param withGS   if true, geometry shader code will be attached to test data;
131  *  @param indiced  if true, indices will be stored in testData.
132  **/
configureTestDataLines(AdjacencyTestData & test_data,bool withGS,bool indiced)133 void GeometryShaderAdjacencyTests::configureTestDataLines(AdjacencyTestData &test_data, bool withGS, bool indiced)
134 {
135     static const char *gsCode = "${VERSION}\n"
136                                 "\n"
137                                 "${GEOMETRY_SHADER_REQUIRE}\n"
138                                 "\n"
139                                 "precision highp float;\n"
140                                 "\n"
141                                 "layout(lines_adjacency)            in;\n"
142                                 "layout(line_strip, max_vertices=2) out;\n"
143                                 "\n"
144                                 "layout(location = 0) out vec4 out_adjacent_geometry;\n"
145                                 "layout(location = 1) out vec4 out_geometry;\n"
146                                 "\n"
147                                 "void main()\n"
148                                 "{\n"
149                                 "    out_adjacent_geometry = gl_in[0].gl_Position;\n"
150                                 "    out_geometry          = gl_in[1].gl_Position;\n"
151                                 "    EmitVertex();\n"
152                                 "    out_adjacent_geometry = gl_in[3].gl_Position;\n"
153                                 "    out_geometry          = gl_in[2].gl_Position;\n"
154                                 "    EmitVertex();\n"
155                                 "    EndPrimitive();\n"
156                                 "}\n";
157 
158     test_data.m_gs_code = (withGS) ? gsCode : 0;
159     test_data.m_mode    = GL_LINES_ADJACENCY_EXT;
160     test_data.m_tf_mode = GL_LINES;
161 
162     createGrid(test_data);
163 
164     if (indiced)
165     {
166         setLinePointsindiced(test_data);
167     }
168     else
169     {
170         setLinePointsNonindiced(test_data);
171     }
172 }
173 
174 /** Configure Test Data for GL_LINE_STRIP_ADJACENCY_EXT drawing mode
175  *
176  * @param testData reference to AdjacencyTestData instance to be configured
177  *                  accordingly;
178  * @param withGS   if true geometry shader code will be attached to test data;
179  * @param indiced  if true indices will be stored in testData.
180  **/
configureTestDataLineStrip(AdjacencyTestData & test_data,bool withGS,bool indiced)181 void GeometryShaderAdjacencyTests::configureTestDataLineStrip(AdjacencyTestData &test_data, bool withGS, bool indiced)
182 {
183     static const char *gsCode = "${VERSION}\n"
184                                 "\n"
185                                 "${GEOMETRY_SHADER_REQUIRE}\n"
186                                 "\n"
187                                 "precision highp float;\n"
188                                 "\n"
189                                 "layout(lines_adjacency)            in;\n"
190                                 "layout(line_strip, max_vertices=2) out;\n"
191                                 "\n"
192                                 "out vec4 out_adjacent_geometry;\n"
193                                 "out vec4 out_geometry;\n"
194                                 "\n"
195                                 "void main()\n"
196                                 "{\n"
197                                 "    out_adjacent_geometry = gl_in[0].gl_Position;\n"
198                                 "    out_geometry          = gl_in[1].gl_Position;\n"
199                                 "    EmitVertex();\n"
200                                 "    out_adjacent_geometry = gl_in[3].gl_Position;\n"
201                                 "    out_geometry          = gl_in[2].gl_Position;\n"
202                                 "    EmitVertex();\n"
203                                 "    EndPrimitive();\n"
204                                 "}\n";
205 
206     test_data.m_gs_code = (withGS) ? gsCode : 0;
207     test_data.m_mode    = GL_LINE_STRIP_ADJACENCY_EXT;
208     test_data.m_tf_mode = GL_LINES;
209 
210     createGrid(test_data);
211 
212     if (indiced)
213     {
214         setLineStripPointsIndiced(test_data);
215     }
216     else
217     {
218         setLineStripPointsNonindiced(test_data);
219     }
220 }
221 
222 /** Configure Test Data for GL_TRIANGLES_ADJACENCY_EXT drawing mode
223  *
224  * @param testData reference to AdjacencyTestData instance to be configured
225  *                  accordingly;
226  * @param withGS   if true geometry shader code will be attached to test data;
227  * @param indiced  if true indices will be stored in testData.
228  **/
configureTestDataTriangles(AdjacencyTestData & test_data,bool withGS,bool indiced)229 void GeometryShaderAdjacencyTests::configureTestDataTriangles(AdjacencyTestData &test_data, bool withGS, bool indiced)
230 {
231     static const char *gsCode = "${VERSION}\n"
232                                 "\n"
233                                 "${GEOMETRY_SHADER_REQUIRE}\n"
234                                 "\n"
235                                 "precision highp float;\n"
236                                 "\n"
237                                 "layout(triangles_adjacency)            in;\n"
238                                 "layout(triangle_strip, max_vertices=3) out;\n"
239                                 "\n"
240                                 "out vec4 out_adjacent_geometry;\n"
241                                 "out vec4 out_geometry;\n"
242                                 "\n"
243                                 "void main()\n"
244                                 "{\n"
245                                 "    out_adjacent_geometry = gl_in[1].gl_Position;\n"
246                                 "    out_geometry          = gl_in[0].gl_Position;\n"
247                                 "    EmitVertex();\n"
248                                 "    out_adjacent_geometry = gl_in[3].gl_Position;\n"
249                                 "    out_geometry          = gl_in[2].gl_Position;\n"
250                                 "    EmitVertex();\n"
251                                 "    out_adjacent_geometry = gl_in[5].gl_Position;\n"
252                                 "    out_geometry          = gl_in[4].gl_Position;\n"
253                                 "    EmitVertex();\n"
254                                 "    EndPrimitive();\n"
255                                 "}\n";
256 
257     test_data.m_gs_code = (withGS) ? gsCode : 0;
258     test_data.m_mode    = GL_TRIANGLES_ADJACENCY_EXT;
259     test_data.m_tf_mode = GL_TRIANGLES;
260 
261     createGrid(test_data);
262 
263     if (indiced)
264     {
265         setTrianglePointsIndiced(test_data);
266     }
267     else
268     {
269         setTrianglePointsNonindiced(test_data);
270     }
271 }
272 
273 /** Configure Test Data for GL_TRIANGLE_STRIP_ADJACENCY_EXT drawing mode
274  *
275  * @param testData reference to AdjacencyTestData instance to be configured
276  *                  accordingly;
277  * @param withGS   if true geometry shader code will be attached to test data;
278  * @param indiced  if true indices will be stored in test_data.
279  **/
configureTestDataTriangleStrip(AdjacencyTestData & test_data,bool withGS,bool indiced)280 void GeometryShaderAdjacencyTests::configureTestDataTriangleStrip(AdjacencyTestData &test_data, bool withGS,
281                                                                   bool indiced)
282 {
283     static const char *gsCode = "${VERSION}\n"
284                                 "\n"
285                                 "${GEOMETRY_SHADER_REQUIRE}\n"
286                                 "\n"
287                                 "precision highp float;\n"
288                                 "\n"
289                                 "layout(triangles_adjacency)            in;\n"
290                                 "layout(triangle_strip, max_vertices=3) out;\n"
291                                 "\n"
292                                 "out vec4 out_adjacent_geometry;\n"
293                                 "out vec4 out_geometry;\n"
294                                 "\n"
295                                 "void main()\n"
296                                 "{\n"
297                                 "    out_adjacent_geometry = gl_in[1].gl_Position;\n"
298                                 "    out_geometry          = gl_in[0].gl_Position;\n"
299                                 "    EmitVertex();\n"
300                                 "    out_adjacent_geometry = gl_in[3].gl_Position;\n"
301                                 "    out_geometry          = gl_in[2].gl_Position;\n"
302                                 "    EmitVertex();\n"
303                                 "    out_adjacent_geometry = gl_in[5].gl_Position;\n"
304                                 "    out_geometry          = gl_in[4].gl_Position;\n"
305                                 "    EmitVertex();\n"
306                                 "    EndPrimitive();\n"
307                                 "}\n";
308 
309     test_data.m_gs_code = (withGS) ? gsCode : 0;
310     test_data.m_mode    = GL_TRIANGLE_STRIP_ADJACENCY_EXT;
311     test_data.m_tf_mode = GL_TRIANGLES;
312 
313     createGrid(test_data);
314 
315     if (indiced)
316     {
317         setTriangleStripPointsIndiced(test_data);
318     }
319     else
320     {
321         setTriangleStripPointsNonindiced(test_data);
322     }
323 }
324 
325 /** Create vertex grid for the test instance.
326  *
327  * @param test_data AdjacencyTestData instance to be filled with grid data.
328  */
createGrid(AdjacencyTestData & test_data)329 void GeometryShaderAdjacencyTests::createGrid(AdjacencyTestData &test_data)
330 {
331     /* Create a grid object */
332     test_data.m_grid = new AdjacencyGrid;
333 
334     /* Allocate space for grid elements */
335     test_data.m_grid->m_n_points = (m_grid_granulity + 1) * (m_grid_granulity + 1);
336     test_data.m_grid->m_line_segments =
337         new AdjacencyGridLineSegment[m_n_line_segments * m_grid_granulity * m_grid_granulity];
338     test_data.m_grid->m_points = new AdjacencyGridPoint[test_data.m_grid->m_n_points];
339 
340     /* Generate points */
341     float dx            = 1.0f / static_cast<float>(m_grid_granulity);
342     float dy            = 1.0f / static_cast<float>(m_grid_granulity);
343     unsigned int nPoint = 0;
344 
345     for (unsigned int y = 0; y < m_grid_granulity + 1; ++y)
346     {
347         for (unsigned int x = 0; x < m_grid_granulity + 1; ++x, ++nPoint)
348         {
349             test_data.m_grid->m_points[nPoint].index = nPoint;
350             test_data.m_grid->m_points[nPoint].x     = dx * static_cast<float>(x);
351             test_data.m_grid->m_points[nPoint].y     = dy * static_cast<float>(y);
352         }
353     }
354 
355     switch (test_data.m_mode)
356     {
357     case GL_LINES_ADJACENCY_EXT:
358     {
359         /* Generate line segment data*/
360         createGridLineSegments(test_data);
361 
362         break;
363     }
364 
365     case GL_LINE_STRIP_ADJACENCY_EXT:
366     {
367         /* Line strip data generation requires line segment data to be present */
368         createGridLineSegments(test_data);
369 
370         /* Generate line strip data */
371         createGridLineStrip(test_data);
372 
373         break;
374     }
375 
376     case GL_TRIANGLES_ADJACENCY_EXT:
377     {
378         /* Generate triangles data */
379         createGridTriangles(test_data);
380 
381         break;
382     }
383 
384     case GL_TRIANGLE_STRIP_ADJACENCY_EXT:
385     {
386         /* Triangle strip data generation requires triangle data to be present */
387         createGridTriangles(test_data);
388 
389         /* Generate triangle strip data */
390         createGridTriangleStrip(test_data);
391 
392         break;
393     }
394 
395     default:
396     {
397         TCU_FAIL("Unrecognized test mode");
398     }
399     }
400 }
401 
402 /** Generate Line segment data.
403  *
404  * @param test_data AdjacencyTestData instance to be filled with line segment data.
405  **/
createGridLineSegments(AdjacencyTestData & test_data)406 void GeometryShaderAdjacencyTests::createGridLineSegments(AdjacencyTestData &test_data)
407 {
408     /* Generate line segments.
409      *
410      * For simplicity, we consider all possible line segments for the grid. If a given line segment
411      * is already stored, it is discarded.
412      */
413     unsigned int nAddedSegments = 0;
414 
415     for (unsigned int nPoint = 0; nPoint < m_grid_granulity * m_grid_granulity; ++nPoint)
416     {
417         AdjacencyGridPoint *pointTL = test_data.m_grid->m_points + nPoint;
418         AdjacencyGridPoint *pointTR = 0;
419         AdjacencyGridPoint *pointBL = 0;
420         AdjacencyGridPoint *pointBR = 0;
421 
422         /* Retrieve neighbor point instances */
423         pointTR = test_data.m_grid->m_points + nPoint + 1;
424         pointBL = test_data.m_grid->m_points + m_grid_granulity + 1;
425         pointBR = test_data.m_grid->m_points + m_grid_granulity + 2;
426 
427         /* For each quad, we need to to add at most 4 line segments.
428          *
429          * NOTE: Adjacent points are determined in later stage.
430          **/
431         AdjacencyGridLineSegment *candidateSegments = new AdjacencyGridLineSegment[m_n_line_segments];
432 
433         candidateSegments[0].m_point_start = pointTL;
434         candidateSegments[0].m_point_end   = pointTR;
435         candidateSegments[1].m_point_start = pointTR;
436         candidateSegments[1].m_point_end   = pointBR;
437         candidateSegments[2].m_point_start = pointBR;
438         candidateSegments[2].m_point_end   = pointBL;
439         candidateSegments[3].m_point_start = pointBL;
440         candidateSegments[3].m_point_end   = pointTL;
441 
442         for (unsigned int nSegment = 0; nSegment < m_n_line_segments; ++nSegment)
443         {
444             bool alreadyAdded                             = false;
445             AdjacencyGridLineSegment *candidateSegmentPtr = candidateSegments + nSegment;
446 
447             for (unsigned int n = 0; n < nAddedSegments; ++n)
448             {
449                 AdjacencyGridLineSegment *segmentPtr = test_data.m_grid->m_line_segments + n;
450 
451                 /* Do not pay attention to direction of the line segment */
452                 if ((segmentPtr->m_point_end == candidateSegmentPtr->m_point_end ||
453                      segmentPtr->m_point_end == candidateSegmentPtr->m_point_start) &&
454                     (segmentPtr->m_point_start == candidateSegmentPtr->m_point_end ||
455                      segmentPtr->m_point_start == candidateSegmentPtr->m_point_start))
456                 {
457                     alreadyAdded = true;
458 
459                     break;
460                 }
461             }
462 
463             /* If not already added, store in the array */
464             if (!alreadyAdded)
465             {
466                 test_data.m_grid->m_line_segments[nAddedSegments].m_point_end   = candidateSegmentPtr->m_point_end;
467                 test_data.m_grid->m_line_segments[nAddedSegments].m_point_start = candidateSegmentPtr->m_point_start;
468 
469                 ++nAddedSegments;
470             }
471         } /* for (all line segments) */
472 
473         delete[] candidateSegments;
474         candidateSegments = DE_NULL;
475     } /* for (all grid points) */
476 
477     test_data.m_grid->m_n_segments = nAddedSegments;
478 
479     /* Determine adjacent points for line segments */
480     for (unsigned int nSegment = 0; nSegment < nAddedSegments; ++nSegment)
481     {
482         float endToAdjacentPointDelta        = 2.0f * static_cast<float>(m_grid_granulity);
483         AdjacencyGridLineSegment *segmentPtr = test_data.m_grid->m_line_segments + nSegment;
484         float startToAdjacentPointDelta      = 2.0f * static_cast<float>(m_grid_granulity);
485 
486         /* For start and end points, find an adjacent vertex that is not a part of the considered line segment */
487         for (unsigned int nPoint = 0; nPoint < test_data.m_grid->m_n_points; ++nPoint)
488         {
489             AdjacencyGridPoint *pointPtr = test_data.m_grid->m_points + nPoint;
490 
491             if (pointPtr != segmentPtr->m_point_end && pointPtr != segmentPtr->m_point_start)
492             {
493                 float deltaStart = deFloatSqrt(
494                     (segmentPtr->m_point_start->x - pointPtr->x) * (segmentPtr->m_point_start->x - pointPtr->x) +
495                     (segmentPtr->m_point_start->y - pointPtr->y) * (segmentPtr->m_point_start->y - pointPtr->y));
496                 float deltaEnd = deFloatSqrt(
497                     (segmentPtr->m_point_end->x - pointPtr->x) * (segmentPtr->m_point_end->x - pointPtr->x) +
498                     (segmentPtr->m_point_end->y - pointPtr->y) * (segmentPtr->m_point_end->y - pointPtr->y));
499 
500                 if (deltaStart < startToAdjacentPointDelta)
501                 {
502                     /* New adjacent point found for start point */
503                     segmentPtr->m_point_start_adjacent = pointPtr;
504                     startToAdjacentPointDelta          = deltaStart;
505                 }
506 
507                 if (deltaEnd < endToAdjacentPointDelta)
508                 {
509                     /* New adjacent point found for end point */
510                     segmentPtr->m_point_end_adjacent = pointPtr;
511                     endToAdjacentPointDelta          = deltaEnd;
512                 }
513             } /* if (point found) */
514         }     /* for (all points) */
515     }         /* for (all line segments) */
516 }
517 
518 /** Generate Line Strip data
519  *
520  * @param test_data AdjacencyTestData instance ot be filled with line strip data.
521  **/
createGridLineStrip(AdjacencyTestData & test_data)522 void GeometryShaderAdjacencyTests::createGridLineStrip(AdjacencyTestData &test_data)
523 {
524     /* Add 2 extra point for adjacency start+end points */
525     test_data.m_grid->m_line_strip.m_n_points = test_data.m_grid->m_n_points + 2;
526     test_data.m_grid->m_line_strip.m_points   = new AdjacencyGridPoint[test_data.m_grid->m_line_strip.m_n_points];
527 
528     memset(test_data.m_grid->m_line_strip.m_points, 0,
529            sizeof(AdjacencyGridPoint) * test_data.m_grid->m_line_strip.m_n_points);
530 
531     for (unsigned int n = 0; n < test_data.m_grid->m_line_strip.m_n_points; ++n)
532     {
533         AdjacencyGridPoint *pointPtr = test_data.m_grid->m_line_strip.m_points + n;
534 
535         pointPtr->index = n;
536 
537         /* If this is a start point, use any of the adjacent points */
538         if (n == 0)
539         {
540             pointPtr->x = test_data.m_grid->m_line_segments[0].m_point_start_adjacent->x;
541             pointPtr->y = test_data.m_grid->m_line_segments[0].m_point_start_adjacent->y;
542         }
543         else
544             /* Last point should be handled analogously */
545             if (n == (test_data.m_grid->m_line_strip.m_n_points - 1))
546             {
547                 pointPtr->x =
548                     test_data.m_grid->m_line_segments[test_data.m_grid->m_n_segments - 1].m_point_end_adjacent->x;
549                 pointPtr->y =
550                     test_data.m_grid->m_line_segments[test_data.m_grid->m_n_segments - 1].m_point_end_adjacent->y;
551             }
552             else
553             /* Intermediate points */
554             {
555                 pointPtr->x = test_data.m_grid->m_line_segments[n - 1].m_point_start->x;
556                 pointPtr->y = test_data.m_grid->m_line_segments[n - 1].m_point_start->y;
557             }
558     } /* for (all points) */
559 }
560 
561 /** Generate Triangles data.
562  *
563  * @param test_data AdjacencyTestData instance to be filled with triangles data.
564  **/
createGridTriangles(AdjacencyTestData & test_data)565 void GeometryShaderAdjacencyTests::createGridTriangles(AdjacencyTestData &test_data)
566 {
567     const int nTrianglesPerQuad = 2;
568     unsigned int nTriangles     = m_grid_granulity * m_grid_granulity * nTrianglesPerQuad;
569 
570     test_data.m_grid->m_triangles   = new AdjacencyGridTriangle[nTriangles];
571     test_data.m_grid->m_n_triangles = nTriangles;
572 
573     for (unsigned int nQuad = 0; nQuad < (nTriangles / nTrianglesPerQuad); ++nQuad)
574     {
575         unsigned int quadTLX = (nQuad) % m_grid_granulity;
576         unsigned int quadTLY = (nQuad) / m_grid_granulity;
577 
578         /* Grid is built off points row-by-row. */
579         AdjacencyGridPoint *pointTL = test_data.m_grid->m_points + (quadTLY * (m_grid_granulity + 1) + quadTLX);
580         AdjacencyGridPoint *pointTR = test_data.m_grid->m_points + (quadTLY * (m_grid_granulity + 1) + quadTLX + 1);
581         AdjacencyGridPoint *pointBL = test_data.m_grid->m_points + ((quadTLY + 1) * (m_grid_granulity + 1) + quadTLX);
582         AdjacencyGridPoint *pointBR =
583             test_data.m_grid->m_points + ((quadTLY + 1) * (m_grid_granulity + 1) + quadTLX + 1);
584 
585         /* Note: In many cases, the adjacency data used below is not correct topologically-wise.
586          *       However, since we're not doing any rendering, we're safe as long as unique data
587          *       is used.
588          */
589         test_data.m_grid->m_triangles[nQuad * nTrianglesPerQuad + 0].m_vertex_x          = pointTL;
590         test_data.m_grid->m_triangles[nQuad * nTrianglesPerQuad + 0].m_vertex_x_adjacent = pointTR;
591         test_data.m_grid->m_triangles[nQuad * nTrianglesPerQuad + 0].m_vertex_y          = pointBR;
592         test_data.m_grid->m_triangles[nQuad * nTrianglesPerQuad + 0].m_vertex_y_adjacent = pointBL;
593         test_data.m_grid->m_triangles[nQuad * nTrianglesPerQuad + 0].m_vertex_z          = pointBL;
594         test_data.m_grid->m_triangles[nQuad * nTrianglesPerQuad + 0].m_vertex_z_adjacent = pointBR;
595 
596         test_data.m_grid->m_triangles[nQuad * nTrianglesPerQuad + 1].m_vertex_x          = pointTL;
597         test_data.m_grid->m_triangles[nQuad * nTrianglesPerQuad + 1].m_vertex_x_adjacent = pointTR;
598         test_data.m_grid->m_triangles[nQuad * nTrianglesPerQuad + 1].m_vertex_y          = pointTR;
599         test_data.m_grid->m_triangles[nQuad * nTrianglesPerQuad + 1].m_vertex_y_adjacent = pointTL;
600         test_data.m_grid->m_triangles[nQuad * nTrianglesPerQuad + 1].m_vertex_z          = pointBR;
601         test_data.m_grid->m_triangles[nQuad * nTrianglesPerQuad + 1].m_vertex_z_adjacent = pointBL;
602     }
603 }
604 
605 /** Generate Triangle Strip data.
606  *
607  * @param test_data AdjacencyTestData instance to be filled with relevant data.
608  **/
createGridTriangleStrip(AdjacencyTestData & test_data)609 void GeometryShaderAdjacencyTests::createGridTriangleStrip(AdjacencyTestData &test_data)
610 {
611     /* For simplicity, reuse adjacency data we have already defined for single triangles.
612      * This does not make a correct topology, but our point is to verify that shaders
613      * are fed valid values (as per spec), not to confirm rendering works correctly.
614      */
615     const int nVerticesPerTriangleStripPrimitive = 6;
616 
617     test_data.m_grid->m_triangle_strip.m_n_points =
618         test_data.m_grid->m_n_triangles * nVerticesPerTriangleStripPrimitive;
619     test_data.m_grid->m_triangle_strip.m_points = new AdjacencyGridPoint[test_data.m_grid->m_triangle_strip.m_n_points];
620 
621     memset(test_data.m_grid->m_triangle_strip.m_points, 0,
622            sizeof(AdjacencyGridPoint) * test_data.m_grid->m_triangle_strip.m_n_points);
623 
624     for (unsigned int n = 0; n < test_data.m_grid->m_triangle_strip.m_n_points; ++n)
625     {
626         AdjacencyGridPoint *pointPtr       = test_data.m_grid->m_triangle_strip.m_points + n;
627         unsigned int triangleIndex         = n / nVerticesPerTriangleStripPrimitive;
628         AdjacencyGridTriangle *trianglePtr = test_data.m_grid->m_triangles + triangleIndex;
629 
630         pointPtr->index = n;
631 
632         switch (n % nVerticesPerTriangleStripPrimitive)
633         {
634         case 0:
635             pointPtr->x = trianglePtr->m_vertex_x->x;
636             pointPtr->y = trianglePtr->m_vertex_x->y;
637             break;
638         case 1:
639             pointPtr->x = trianglePtr->m_vertex_x_adjacent->x;
640             pointPtr->y = trianglePtr->m_vertex_x_adjacent->y;
641             break;
642         case 2:
643             pointPtr->x = trianglePtr->m_vertex_y->x;
644             pointPtr->y = trianglePtr->m_vertex_y->y;
645             break;
646         case 3:
647             pointPtr->x = trianglePtr->m_vertex_y_adjacent->x;
648             pointPtr->y = trianglePtr->m_vertex_y_adjacent->y;
649             break;
650         case 4:
651             pointPtr->x = trianglePtr->m_vertex_z->x;
652             pointPtr->y = trianglePtr->m_vertex_z->y;
653             break;
654         case 5:
655             pointPtr->x = trianglePtr->m_vertex_z_adjacent->x;
656             pointPtr->y = trianglePtr->m_vertex_z_adjacent->y;
657             break;
658         }
659     } /* for (all points) */
660 }
661 
662 /** Set line vertex data used to be used by non-indiced draw calls.
663  *
664  * @param test_data AdjacencyTestData instance to be filled with relevant data.
665  **/
setLinePointsNonindiced(AdjacencyTestData & test_data)666 void GeometryShaderAdjacencyTests::setLinePointsNonindiced(AdjacencyTestData &test_data)
667 {
668     float *travellerExpectedAdjacencyGeometryPtr = 0;
669     float *travellerExpectedGeometryPtr          = 0;
670     float *travellerPtr                          = 0;
671 
672     /* Set buffer sizes */
673     test_data.m_n_vertices = test_data.m_grid->m_n_segments * 2 /* start + end points form a segment */;
674     test_data.m_geometry_bo_size =
675         static_cast<glw::GLuint>(test_data.m_n_vertices * m_n_components_output * sizeof(float));
676     test_data.m_vertex_data_bo_size = static_cast<glw::GLuint>(test_data.m_n_vertices * m_n_components_input *
677                                                                2 /* include adjacency info */ * sizeof(float));
678 
679     /* Allocate memory for input and expected data */
680     test_data.m_expected_adjacency_geometry = new float[test_data.m_geometry_bo_size / sizeof(float)];
681     test_data.m_expected_geometry           = new float[test_data.m_geometry_bo_size / sizeof(float)];
682     test_data.m_vertex_data                 = new float[test_data.m_vertex_data_bo_size / sizeof(float)];
683 
684     travellerExpectedAdjacencyGeometryPtr = test_data.m_expected_adjacency_geometry;
685     travellerExpectedGeometryPtr          = test_data.m_expected_geometry;
686     travellerPtr                          = test_data.m_vertex_data;
687 
688     /* Set input and expected values */
689     for (unsigned int n = 0; n < test_data.m_grid->m_n_segments; ++n)
690     {
691         AdjacencyGridLineSegment *segmentPtr = test_data.m_grid->m_line_segments + n;
692 
693         *travellerPtr = segmentPtr->m_point_start_adjacent->x;
694         ++travellerPtr;
695         *travellerPtr = segmentPtr->m_point_start_adjacent->y;
696         ++travellerPtr;
697         *travellerPtr = segmentPtr->m_point_start->x;
698         ++travellerPtr;
699         *travellerPtr = segmentPtr->m_point_start->y;
700         ++travellerPtr;
701         *travellerPtr = segmentPtr->m_point_end->x;
702         ++travellerPtr;
703         *travellerPtr = segmentPtr->m_point_end->y;
704         ++travellerPtr;
705         *travellerPtr = segmentPtr->m_point_end_adjacent->x;
706         ++travellerPtr;
707         *travellerPtr = segmentPtr->m_point_end_adjacent->y;
708         ++travellerPtr;
709 
710         *travellerExpectedAdjacencyGeometryPtr = segmentPtr->m_point_start_adjacent->x;
711         ++travellerExpectedAdjacencyGeometryPtr;
712         *travellerExpectedAdjacencyGeometryPtr = segmentPtr->m_point_start_adjacent->y;
713         ++travellerExpectedAdjacencyGeometryPtr;
714         *travellerExpectedAdjacencyGeometryPtr = 0;
715         ++travellerExpectedAdjacencyGeometryPtr;
716         *travellerExpectedAdjacencyGeometryPtr = 1;
717         ++travellerExpectedAdjacencyGeometryPtr;
718         *travellerExpectedAdjacencyGeometryPtr = segmentPtr->m_point_end_adjacent->x;
719         ++travellerExpectedAdjacencyGeometryPtr;
720         *travellerExpectedAdjacencyGeometryPtr = segmentPtr->m_point_end_adjacent->y;
721         ++travellerExpectedAdjacencyGeometryPtr;
722         *travellerExpectedAdjacencyGeometryPtr = 0;
723         ++travellerExpectedAdjacencyGeometryPtr;
724         *travellerExpectedAdjacencyGeometryPtr = 1;
725         ++travellerExpectedAdjacencyGeometryPtr;
726 
727         *travellerExpectedGeometryPtr = segmentPtr->m_point_start->x;
728         ++travellerExpectedGeometryPtr;
729         *travellerExpectedGeometryPtr = segmentPtr->m_point_start->y;
730         ++travellerExpectedGeometryPtr;
731         *travellerExpectedGeometryPtr = 0;
732         ++travellerExpectedGeometryPtr;
733         *travellerExpectedGeometryPtr = 1;
734         ++travellerExpectedGeometryPtr;
735         *travellerExpectedGeometryPtr = segmentPtr->m_point_end->x;
736         ++travellerExpectedGeometryPtr;
737         *travellerExpectedGeometryPtr = segmentPtr->m_point_end->y;
738         ++travellerExpectedGeometryPtr;
739         *travellerExpectedGeometryPtr = 0;
740         ++travellerExpectedGeometryPtr;
741         *travellerExpectedGeometryPtr = 1;
742         ++travellerExpectedGeometryPtr;
743     } /* for (all line segments) */
744 }
745 
746 /** Set line vertex data used to be used by indiced draw calls.
747  *
748  * @param test_data AdjacencyTestData instance to be filled with relevant data.
749  **/
setLinePointsindiced(AdjacencyTestData & test_data)750 void GeometryShaderAdjacencyTests::setLinePointsindiced(AdjacencyTestData &test_data)
751 {
752     float *travellerExpectedAdjacencyGeometryPtr = 0;
753     float *travellerExpectedGeometryPtr          = 0;
754     unsigned int *travellerIndicesPtr            = 0;
755     float *travellerPtr                          = 0;
756 
757     /* Set buffer sizes */
758     test_data.m_n_vertices = test_data.m_grid->m_n_segments * 2 /* start + end points form a segment */;
759     test_data.m_geometry_bo_size =
760         static_cast<glw::GLuint>(test_data.m_n_vertices * m_n_components_output * sizeof(float));
761     test_data.m_vertex_data_bo_size =
762         static_cast<glw::GLuint>(test_data.m_grid->m_n_points * m_n_components_input * sizeof(float));
763     test_data.m_index_data_bo_size =
764         static_cast<glw::GLuint>(test_data.m_n_vertices * 2 /* include adjacency info */ * sizeof(unsigned int));
765 
766     /* Allocate memory for input and expected data */
767     test_data.m_expected_adjacency_geometry = new float[test_data.m_geometry_bo_size / sizeof(float)];
768     test_data.m_expected_geometry           = new float[test_data.m_geometry_bo_size / sizeof(float)];
769     test_data.m_index_data                  = new unsigned int[test_data.m_index_data_bo_size / sizeof(unsigned int)];
770     test_data.m_vertex_data                 = new float[test_data.m_vertex_data_bo_size / sizeof(float)];
771 
772     travellerExpectedAdjacencyGeometryPtr = test_data.m_expected_adjacency_geometry;
773     travellerExpectedGeometryPtr          = test_data.m_expected_geometry;
774     travellerIndicesPtr                   = test_data.m_index_data;
775     travellerPtr                          = test_data.m_vertex_data;
776 
777     /* Set input and expected values */
778     for (unsigned int n = 0; n < test_data.m_grid->m_n_points; ++n)
779     {
780         *travellerPtr = test_data.m_grid->m_points[n].x;
781         ++travellerPtr;
782         *travellerPtr = test_data.m_grid->m_points[n].y;
783         ++travellerPtr;
784     }
785 
786     for (unsigned int n = 0; n < test_data.m_grid->m_n_segments; ++n)
787     {
788         AdjacencyGridLineSegment *segmentPtr = test_data.m_grid->m_line_segments + n;
789 
790         *travellerIndicesPtr = segmentPtr->m_point_end_adjacent->index;
791         ++travellerIndicesPtr;
792         *travellerIndicesPtr = segmentPtr->m_point_end->index;
793         ++travellerIndicesPtr;
794         *travellerIndicesPtr = segmentPtr->m_point_start->index;
795         ++travellerIndicesPtr;
796         *travellerIndicesPtr = segmentPtr->m_point_start_adjacent->index;
797         ++travellerIndicesPtr;
798 
799         *travellerExpectedAdjacencyGeometryPtr = segmentPtr->m_point_end_adjacent->x;
800         ++travellerExpectedAdjacencyGeometryPtr;
801         *travellerExpectedAdjacencyGeometryPtr = segmentPtr->m_point_end_adjacent->y;
802         ++travellerExpectedAdjacencyGeometryPtr;
803         *travellerExpectedAdjacencyGeometryPtr = 0;
804         ++travellerExpectedAdjacencyGeometryPtr;
805         *travellerExpectedAdjacencyGeometryPtr = 1;
806         ++travellerExpectedAdjacencyGeometryPtr;
807         *travellerExpectedAdjacencyGeometryPtr = segmentPtr->m_point_start_adjacent->x;
808         ++travellerExpectedAdjacencyGeometryPtr;
809         *travellerExpectedAdjacencyGeometryPtr = segmentPtr->m_point_start_adjacent->y;
810         ++travellerExpectedAdjacencyGeometryPtr;
811         *travellerExpectedAdjacencyGeometryPtr = 0;
812         ++travellerExpectedAdjacencyGeometryPtr;
813         *travellerExpectedAdjacencyGeometryPtr = 1;
814         ++travellerExpectedAdjacencyGeometryPtr;
815 
816         *travellerExpectedGeometryPtr = segmentPtr->m_point_end->x;
817         ++travellerExpectedGeometryPtr;
818         *travellerExpectedGeometryPtr = segmentPtr->m_point_end->y;
819         ++travellerExpectedGeometryPtr;
820         *travellerExpectedGeometryPtr = 0;
821         ++travellerExpectedGeometryPtr;
822         *travellerExpectedGeometryPtr = 1;
823         ++travellerExpectedGeometryPtr;
824         *travellerExpectedGeometryPtr = segmentPtr->m_point_start->x;
825         ++travellerExpectedGeometryPtr;
826         *travellerExpectedGeometryPtr = segmentPtr->m_point_start->y;
827         ++travellerExpectedGeometryPtr;
828         *travellerExpectedGeometryPtr = 0;
829         ++travellerExpectedGeometryPtr;
830         *travellerExpectedGeometryPtr = 1;
831         ++travellerExpectedGeometryPtr;
832     } /* for (all line segments) */
833 }
834 
835 /** Set line strip vertex data used to be used by non-indiced draw calls.
836  *
837  * @param test_data AdjacencyTestData instance to be filled with relevant data.
838  **/
setLineStripPointsNonindiced(AdjacencyTestData & test_data)839 void GeometryShaderAdjacencyTests::setLineStripPointsNonindiced(AdjacencyTestData &test_data)
840 {
841     float *travellerExpectedAdjacencyGeometryPtr = 0;
842     float *travellerExpectedGeometryPtr          = 0;
843     float *travellerPtr                          = 0;
844 
845     /* Set buffer sizes */
846     test_data.m_n_vertices       = test_data.m_grid->m_line_strip.m_n_points;
847     test_data.m_geometry_bo_size = static_cast<glw::GLuint>((test_data.m_n_vertices - 3) * m_n_components_output *
848                                                             2 /* start/end */ * sizeof(float));
849     test_data.m_vertex_data_bo_size =
850         static_cast<glw::GLuint>(test_data.m_n_vertices * m_n_components_input * sizeof(float));
851 
852     /* Allocate memory for input and expected data */
853     test_data.m_expected_adjacency_geometry = new float[test_data.m_geometry_bo_size / sizeof(float)];
854     test_data.m_expected_geometry           = new float[test_data.m_geometry_bo_size / sizeof(float)];
855     test_data.m_vertex_data                 = new float[test_data.m_vertex_data_bo_size / sizeof(float)];
856 
857     travellerExpectedAdjacencyGeometryPtr = test_data.m_expected_adjacency_geometry;
858     travellerExpectedGeometryPtr          = test_data.m_expected_geometry;
859     travellerPtr                          = test_data.m_vertex_data;
860 
861     /* Set input and expected values */
862     for (unsigned int n = 0; n < test_data.m_n_vertices; ++n)
863     {
864         *travellerPtr = test_data.m_grid->m_line_strip.m_points[n].x;
865         ++travellerPtr;
866         *travellerPtr = test_data.m_grid->m_line_strip.m_points[n].y;
867         ++travellerPtr;
868     }
869 
870     for (unsigned int n = 0; n < test_data.m_n_vertices - 3; ++n)
871     {
872         *travellerExpectedAdjacencyGeometryPtr = test_data.m_grid->m_line_strip.m_points[n].x;
873         ++travellerExpectedAdjacencyGeometryPtr;
874         *travellerExpectedAdjacencyGeometryPtr = test_data.m_grid->m_line_strip.m_points[n].y;
875         ++travellerExpectedAdjacencyGeometryPtr;
876         *travellerExpectedAdjacencyGeometryPtr = 0;
877         ++travellerExpectedAdjacencyGeometryPtr;
878         *travellerExpectedAdjacencyGeometryPtr = 1;
879         ++travellerExpectedAdjacencyGeometryPtr;
880         *travellerExpectedAdjacencyGeometryPtr = test_data.m_grid->m_line_strip.m_points[n + 3].x;
881         ++travellerExpectedAdjacencyGeometryPtr;
882         *travellerExpectedAdjacencyGeometryPtr = test_data.m_grid->m_line_strip.m_points[n + 3].y;
883         ++travellerExpectedAdjacencyGeometryPtr;
884         *travellerExpectedAdjacencyGeometryPtr = 0;
885         ++travellerExpectedAdjacencyGeometryPtr;
886         *travellerExpectedAdjacencyGeometryPtr = 1;
887         ++travellerExpectedAdjacencyGeometryPtr;
888 
889         *travellerExpectedGeometryPtr = test_data.m_grid->m_line_strip.m_points[n + 1].x;
890         ++travellerExpectedGeometryPtr;
891         *travellerExpectedGeometryPtr = test_data.m_grid->m_line_strip.m_points[n + 1].y;
892         ++travellerExpectedGeometryPtr;
893         *travellerExpectedGeometryPtr = 0;
894         ++travellerExpectedGeometryPtr;
895         *travellerExpectedGeometryPtr = 1;
896         ++travellerExpectedGeometryPtr;
897         *travellerExpectedGeometryPtr = test_data.m_grid->m_line_strip.m_points[n + 2].x;
898         ++travellerExpectedGeometryPtr;
899         *travellerExpectedGeometryPtr = test_data.m_grid->m_line_strip.m_points[n + 2].y;
900         ++travellerExpectedGeometryPtr;
901         *travellerExpectedGeometryPtr = 0;
902         ++travellerExpectedGeometryPtr;
903         *travellerExpectedGeometryPtr = 1;
904         ++travellerExpectedGeometryPtr;
905     } /* for (all vertices (apart from the three last ones) ) */
906 }
907 
908 /** Set line strip vertex data used to be used by indiced draw calls.
909  *
910  * @param test_data AdjacencyTestData instance to be filled with relevant data.
911  **/
setLineStripPointsIndiced(AdjacencyTestData & test_data)912 void GeometryShaderAdjacencyTests::setLineStripPointsIndiced(AdjacencyTestData &test_data)
913 {
914 
915     float *travellerExpectedAdjacencyGeometryPtr = 0;
916     float *travellerExpectedGeometryPtr          = 0;
917     unsigned int *travellerIndicesPtr            = 0;
918     float *travellerPtr                          = 0;
919 
920     /* Set buffer sizes */
921     test_data.m_n_vertices       = test_data.m_grid->m_line_strip.m_n_points;
922     test_data.m_geometry_bo_size = static_cast<glw::GLuint>((test_data.m_n_vertices - 3) * m_n_components_output *
923                                                             2 /* start/end */ * sizeof(float));
924     test_data.m_vertex_data_bo_size =
925         static_cast<glw::GLuint>(test_data.m_n_vertices * m_n_components_input * sizeof(float));
926     test_data.m_index_data_bo_size = static_cast<glw::GLuint>(test_data.m_n_vertices * sizeof(unsigned int));
927 
928     /* Allocate memory for input and expected data */
929     test_data.m_expected_adjacency_geometry = new float[test_data.m_geometry_bo_size / sizeof(float)];
930     test_data.m_expected_geometry           = new float[test_data.m_geometry_bo_size / sizeof(float)];
931     test_data.m_index_data                  = new unsigned int[test_data.m_index_data_bo_size / sizeof(unsigned int)];
932     test_data.m_vertex_data                 = new float[test_data.m_vertex_data_bo_size / sizeof(float)];
933 
934     travellerExpectedAdjacencyGeometryPtr = test_data.m_expected_adjacency_geometry;
935     travellerExpectedGeometryPtr          = test_data.m_expected_geometry;
936     travellerIndicesPtr                   = test_data.m_index_data;
937     travellerPtr                          = test_data.m_vertex_data;
938 
939     /* Set input and expected value s*/
940     for (unsigned int n = 0; n < test_data.m_n_vertices; ++n)
941     {
942         *travellerPtr = test_data.m_grid->m_line_strip.m_points[n].x;
943         ++travellerPtr;
944         *travellerPtr = test_data.m_grid->m_line_strip.m_points[n].y;
945         ++travellerPtr;
946     }
947 
948     for (unsigned int n = 0; n < test_data.m_n_vertices; ++n)
949     {
950         *travellerIndicesPtr = (test_data.m_n_vertices - n - 1);
951         ++travellerIndicesPtr;
952     }
953 
954     for (unsigned int n = 0; n < test_data.m_n_vertices - 3; ++n)
955     {
956         AdjacencyGridPoint *pointN0 = test_data.m_grid->m_line_strip.m_points + test_data.m_index_data[n];
957         AdjacencyGridPoint *pointN1 = test_data.m_grid->m_line_strip.m_points + test_data.m_index_data[n + 1];
958         AdjacencyGridPoint *pointN2 = test_data.m_grid->m_line_strip.m_points + test_data.m_index_data[n + 2];
959         AdjacencyGridPoint *pointN3 = test_data.m_grid->m_line_strip.m_points + test_data.m_index_data[n + 3];
960 
961         *travellerExpectedAdjacencyGeometryPtr = pointN0->x;
962         ++travellerExpectedAdjacencyGeometryPtr;
963         *travellerExpectedAdjacencyGeometryPtr = pointN0->y;
964         ++travellerExpectedAdjacencyGeometryPtr;
965         *travellerExpectedAdjacencyGeometryPtr = 0;
966         ++travellerExpectedAdjacencyGeometryPtr;
967         *travellerExpectedAdjacencyGeometryPtr = 1;
968         ++travellerExpectedAdjacencyGeometryPtr;
969         *travellerExpectedAdjacencyGeometryPtr = pointN3->x;
970         ++travellerExpectedAdjacencyGeometryPtr;
971         *travellerExpectedAdjacencyGeometryPtr = pointN3->y;
972         ++travellerExpectedAdjacencyGeometryPtr;
973         *travellerExpectedAdjacencyGeometryPtr = 0;
974         ++travellerExpectedAdjacencyGeometryPtr;
975         *travellerExpectedAdjacencyGeometryPtr = 1;
976         ++travellerExpectedAdjacencyGeometryPtr;
977 
978         *travellerExpectedGeometryPtr = pointN1->x;
979         ++travellerExpectedGeometryPtr;
980         *travellerExpectedGeometryPtr = pointN1->y;
981         ++travellerExpectedGeometryPtr;
982         *travellerExpectedGeometryPtr = 0;
983         ++travellerExpectedGeometryPtr;
984         *travellerExpectedGeometryPtr = 1;
985         ++travellerExpectedGeometryPtr;
986         *travellerExpectedGeometryPtr = pointN2->x;
987         ++travellerExpectedGeometryPtr;
988         *travellerExpectedGeometryPtr = pointN2->y;
989         ++travellerExpectedGeometryPtr;
990         *travellerExpectedGeometryPtr = 0;
991         ++travellerExpectedGeometryPtr;
992         *travellerExpectedGeometryPtr = 1;
993         ++travellerExpectedGeometryPtr;
994     } /* for (all vertices apart from the three last ones) */
995 }
996 
997 /** Set triangle vertex data used to be used by non-indiced draw calls.
998  *
999  * @param test_data AdjacencyTestData instance to be filled with relevant data.
1000  **/
setTrianglePointsNonindiced(AdjacencyTestData & test_data)1001 void GeometryShaderAdjacencyTests::setTrianglePointsNonindiced(AdjacencyTestData &test_data)
1002 {
1003     float *travellerExpectedAdjacencyGeometryPtr = NULL;
1004     float *travellerExpectedGeometryPtr          = NULL;
1005     float *travellerPtr                          = NULL;
1006 
1007     /* Set buffer sizes */
1008     test_data.m_n_vertices       = test_data.m_grid->m_n_triangles * m_n_vertices_per_triangle;
1009     test_data.m_geometry_bo_size = static_cast<glw::GLuint>(
1010         test_data.m_grid->m_n_triangles * m_n_vertices_per_triangle * m_n_components_output * sizeof(float));
1011     test_data.m_vertex_data_bo_size = static_cast<glw::GLuint>(test_data.m_n_vertices * m_n_components_input *
1012                                                                sizeof(float) * 2); /* include adjacency info */
1013 
1014     /* Allocate memory for input and expected data */
1015     test_data.m_expected_adjacency_geometry = new float[test_data.m_geometry_bo_size / sizeof(float)];
1016     test_data.m_expected_geometry           = new float[test_data.m_geometry_bo_size / sizeof(float)];
1017     test_data.m_vertex_data                 = new float[test_data.m_vertex_data_bo_size / sizeof(float)];
1018 
1019     travellerExpectedAdjacencyGeometryPtr = test_data.m_expected_adjacency_geometry;
1020     travellerExpectedGeometryPtr          = test_data.m_expected_geometry;
1021     travellerPtr                          = test_data.m_vertex_data;
1022 
1023     /* Set input and expected values */
1024     for (unsigned int n = 0; n < test_data.m_grid->m_n_triangles; ++n)
1025     {
1026         AdjacencyGridTriangle *trianglePtr = test_data.m_grid->m_triangles + n;
1027 
1028         *travellerPtr = trianglePtr->m_vertex_x->x;
1029         ++travellerPtr;
1030         *travellerPtr = trianglePtr->m_vertex_x->y;
1031         ++travellerPtr;
1032         *travellerPtr = trianglePtr->m_vertex_x_adjacent->x;
1033         ++travellerPtr;
1034         *travellerPtr = trianglePtr->m_vertex_x_adjacent->y;
1035         ++travellerPtr;
1036         *travellerPtr = trianglePtr->m_vertex_y->x;
1037         ++travellerPtr;
1038         *travellerPtr = trianglePtr->m_vertex_y->y;
1039         ++travellerPtr;
1040         *travellerPtr = trianglePtr->m_vertex_y_adjacent->x;
1041         ++travellerPtr;
1042         *travellerPtr = trianglePtr->m_vertex_y_adjacent->y;
1043         ++travellerPtr;
1044         *travellerPtr = trianglePtr->m_vertex_z->x;
1045         ++travellerPtr;
1046         *travellerPtr = trianglePtr->m_vertex_z->y;
1047         ++travellerPtr;
1048         *travellerPtr = trianglePtr->m_vertex_z_adjacent->x;
1049         ++travellerPtr;
1050         *travellerPtr = trianglePtr->m_vertex_z_adjacent->y;
1051         ++travellerPtr;
1052 
1053         *travellerExpectedAdjacencyGeometryPtr = trianglePtr->m_vertex_x_adjacent->x;
1054         ++travellerExpectedAdjacencyGeometryPtr;
1055         *travellerExpectedAdjacencyGeometryPtr = trianglePtr->m_vertex_x_adjacent->y;
1056         ++travellerExpectedAdjacencyGeometryPtr;
1057         *travellerExpectedAdjacencyGeometryPtr = 0;
1058         ++travellerExpectedAdjacencyGeometryPtr;
1059         *travellerExpectedAdjacencyGeometryPtr = 1;
1060         ++travellerExpectedAdjacencyGeometryPtr;
1061         *travellerExpectedAdjacencyGeometryPtr = trianglePtr->m_vertex_y_adjacent->x;
1062         ++travellerExpectedAdjacencyGeometryPtr;
1063         *travellerExpectedAdjacencyGeometryPtr = trianglePtr->m_vertex_y_adjacent->y;
1064         ++travellerExpectedAdjacencyGeometryPtr;
1065         *travellerExpectedAdjacencyGeometryPtr = 0;
1066         ++travellerExpectedAdjacencyGeometryPtr;
1067         *travellerExpectedAdjacencyGeometryPtr = 1;
1068         ++travellerExpectedAdjacencyGeometryPtr;
1069         *travellerExpectedAdjacencyGeometryPtr = trianglePtr->m_vertex_z_adjacent->x;
1070         ++travellerExpectedAdjacencyGeometryPtr;
1071         *travellerExpectedAdjacencyGeometryPtr = trianglePtr->m_vertex_z_adjacent->y;
1072         ++travellerExpectedAdjacencyGeometryPtr;
1073         *travellerExpectedAdjacencyGeometryPtr = 0;
1074         ++travellerExpectedAdjacencyGeometryPtr;
1075         *travellerExpectedAdjacencyGeometryPtr = 1;
1076         ++travellerExpectedAdjacencyGeometryPtr;
1077 
1078         *travellerExpectedGeometryPtr = trianglePtr->m_vertex_x->x;
1079         ++travellerExpectedGeometryPtr;
1080         *travellerExpectedGeometryPtr = trianglePtr->m_vertex_x->y;
1081         ++travellerExpectedGeometryPtr;
1082         *travellerExpectedGeometryPtr = 0;
1083         ++travellerExpectedGeometryPtr;
1084         *travellerExpectedGeometryPtr = 1;
1085         ++travellerExpectedGeometryPtr;
1086         *travellerExpectedGeometryPtr = trianglePtr->m_vertex_y->x;
1087         ++travellerExpectedGeometryPtr;
1088         *travellerExpectedGeometryPtr = trianglePtr->m_vertex_y->y;
1089         ++travellerExpectedGeometryPtr;
1090         *travellerExpectedGeometryPtr = 0;
1091         ++travellerExpectedGeometryPtr;
1092         *travellerExpectedGeometryPtr = 1;
1093         ++travellerExpectedGeometryPtr;
1094         *travellerExpectedGeometryPtr = trianglePtr->m_vertex_z->x;
1095         ++travellerExpectedGeometryPtr;
1096         *travellerExpectedGeometryPtr = trianglePtr->m_vertex_z->y;
1097         ++travellerExpectedGeometryPtr;
1098         *travellerExpectedGeometryPtr = 0;
1099         ++travellerExpectedGeometryPtr;
1100         *travellerExpectedGeometryPtr = 1;
1101         ++travellerExpectedGeometryPtr;
1102     } /* for (all triangles) */
1103 }
1104 
1105 /** Set triangle vertex data used to be used by indiced draw calls.
1106  *
1107  * @param test_data AdjacencyTestDatainstance to be filled with relevant data.
1108  **/
setTrianglePointsIndiced(AdjacencyTestData & test_data)1109 void GeometryShaderAdjacencyTests::setTrianglePointsIndiced(AdjacencyTestData &test_data)
1110 {
1111     float *travellerExpectedAdjacencyGeometryPtr = 0;
1112     float *travellerExpectedGeometryPtr          = 0;
1113     unsigned int *travellerIndicesPtr            = 0;
1114     float *travellerPtr                          = 0;
1115 
1116     /* Set buffer sizes */
1117     test_data.m_n_vertices       = test_data.m_grid->m_n_triangles * m_n_vertices_per_triangle;
1118     test_data.m_geometry_bo_size = static_cast<glw::GLuint>(
1119         test_data.m_grid->m_n_triangles * m_n_vertices_per_triangle * m_n_components_output * sizeof(float));
1120     test_data.m_vertex_data_bo_size =
1121         static_cast<glw::GLuint>(test_data.m_grid->m_n_points * m_n_components_input * sizeof(float));
1122     test_data.m_index_data_bo_size =
1123         static_cast<glw::GLuint>(test_data.m_n_vertices * sizeof(unsigned int) * 2); /* include adjacency info */
1124 
1125     /* Allocate memory for input and expected data */
1126     test_data.m_expected_adjacency_geometry = new float[test_data.m_geometry_bo_size / sizeof(float)];
1127     test_data.m_expected_geometry           = new float[test_data.m_geometry_bo_size / sizeof(float)];
1128     test_data.m_index_data                  = new unsigned int[test_data.m_index_data_bo_size / sizeof(unsigned int)];
1129     test_data.m_vertex_data                 = new float[test_data.m_vertex_data_bo_size / sizeof(float)];
1130 
1131     travellerExpectedAdjacencyGeometryPtr = test_data.m_expected_adjacency_geometry;
1132     travellerExpectedGeometryPtr          = test_data.m_expected_geometry;
1133     travellerPtr                          = test_data.m_vertex_data;
1134     travellerIndicesPtr                   = test_data.m_index_data;
1135 
1136     /* Set input and expected values */
1137     for (unsigned int n = 0; n < test_data.m_grid->m_n_points; ++n)
1138     {
1139         *travellerPtr = test_data.m_grid->m_points[n].x;
1140         ++travellerPtr;
1141         *travellerPtr = test_data.m_grid->m_points[n].y;
1142         ++travellerPtr;
1143     }
1144 
1145     for (unsigned int n = 0; n < test_data.m_grid->m_n_triangles; ++n)
1146     {
1147         AdjacencyGridTriangle *trianglePtr = test_data.m_grid->m_triangles + (n + 1) % 2;
1148 
1149         *travellerIndicesPtr = trianglePtr->m_vertex_x->index;
1150         ++travellerIndicesPtr;
1151         *travellerIndicesPtr = trianglePtr->m_vertex_x_adjacent->index;
1152         ++travellerIndicesPtr;
1153         *travellerIndicesPtr = trianglePtr->m_vertex_y->index;
1154         ++travellerIndicesPtr;
1155         *travellerIndicesPtr = trianglePtr->m_vertex_y_adjacent->index;
1156         ++travellerIndicesPtr;
1157         *travellerIndicesPtr = trianglePtr->m_vertex_z->index;
1158         ++travellerIndicesPtr;
1159         *travellerIndicesPtr = trianglePtr->m_vertex_z_adjacent->index;
1160         ++travellerIndicesPtr;
1161 
1162         *travellerExpectedAdjacencyGeometryPtr = trianglePtr->m_vertex_x_adjacent->x;
1163         ++travellerExpectedAdjacencyGeometryPtr;
1164         *travellerExpectedAdjacencyGeometryPtr = trianglePtr->m_vertex_x_adjacent->y;
1165         ++travellerExpectedAdjacencyGeometryPtr;
1166         *travellerExpectedAdjacencyGeometryPtr = 0;
1167         ++travellerExpectedAdjacencyGeometryPtr;
1168         *travellerExpectedAdjacencyGeometryPtr = 1;
1169         ++travellerExpectedAdjacencyGeometryPtr;
1170         *travellerExpectedAdjacencyGeometryPtr = trianglePtr->m_vertex_y_adjacent->x;
1171         ++travellerExpectedAdjacencyGeometryPtr;
1172         *travellerExpectedAdjacencyGeometryPtr = trianglePtr->m_vertex_y_adjacent->y;
1173         ++travellerExpectedAdjacencyGeometryPtr;
1174         *travellerExpectedAdjacencyGeometryPtr = 0;
1175         ++travellerExpectedAdjacencyGeometryPtr;
1176         *travellerExpectedAdjacencyGeometryPtr = 1;
1177         ++travellerExpectedAdjacencyGeometryPtr;
1178         *travellerExpectedAdjacencyGeometryPtr = trianglePtr->m_vertex_z_adjacent->x;
1179         ++travellerExpectedAdjacencyGeometryPtr;
1180         *travellerExpectedAdjacencyGeometryPtr = trianglePtr->m_vertex_z_adjacent->y;
1181         ++travellerExpectedAdjacencyGeometryPtr;
1182         *travellerExpectedAdjacencyGeometryPtr = 0;
1183         ++travellerExpectedAdjacencyGeometryPtr;
1184         *travellerExpectedAdjacencyGeometryPtr = 1;
1185         ++travellerExpectedAdjacencyGeometryPtr;
1186 
1187         *travellerExpectedGeometryPtr = trianglePtr->m_vertex_x->x;
1188         ++travellerExpectedGeometryPtr;
1189         *travellerExpectedGeometryPtr = trianglePtr->m_vertex_x->y;
1190         ++travellerExpectedGeometryPtr;
1191         *travellerExpectedGeometryPtr = 0;
1192         ++travellerExpectedGeometryPtr;
1193         *travellerExpectedGeometryPtr = 1;
1194         ++travellerExpectedGeometryPtr;
1195         *travellerExpectedGeometryPtr = trianglePtr->m_vertex_y->x;
1196         ++travellerExpectedGeometryPtr;
1197         *travellerExpectedGeometryPtr = trianglePtr->m_vertex_y->y;
1198         ++travellerExpectedGeometryPtr;
1199         *travellerExpectedGeometryPtr = 0;
1200         ++travellerExpectedGeometryPtr;
1201         *travellerExpectedGeometryPtr = 1;
1202         ++travellerExpectedGeometryPtr;
1203         *travellerExpectedGeometryPtr = trianglePtr->m_vertex_z->x;
1204         ++travellerExpectedGeometryPtr;
1205         *travellerExpectedGeometryPtr = trianglePtr->m_vertex_z->y;
1206         ++travellerExpectedGeometryPtr;
1207         *travellerExpectedGeometryPtr = 0;
1208         ++travellerExpectedGeometryPtr;
1209         *travellerExpectedGeometryPtr = 1;
1210         ++travellerExpectedGeometryPtr;
1211     } /* For (all triangles) */
1212 }
1213 
1214 /** Set triangle strip vertex data used to be used by non-indiced draw calls.
1215  *
1216  * @param test_data AdjacencyTestData instance to be filled with relevant data.
1217  **/
setTriangleStripPointsNonindiced(AdjacencyTestData & test_data)1218 void GeometryShaderAdjacencyTests::setTriangleStripPointsNonindiced(AdjacencyTestData &test_data)
1219 {
1220     /* Generate ordered vertex GL_TRIANGLE_STRIP_ADJACENCY_EXT data for actual test.
1221      *
1222      * "In triangle strips with adjacency, n triangles are drawn where there are
1223      *  2 * (n+2) + k vertices passed. k is either 0 or 1; if k is 1, the final
1224      *  vertex is ignored. "
1225      *
1226      * implies: for k input vertices, floor((n - 4) / 2) triangles will be drawn.
1227      */
1228     unsigned int nTriangles = (test_data.m_grid->m_triangle_strip.m_n_points - 4) / 2;
1229 
1230     float *travellerExpectedAdjacencyGeometryPtr = 0;
1231     float *travellerExpectedGeometryPtr          = 0;
1232     float *travellerPtr                          = 0;
1233 
1234     /* Set buffer sizes */
1235     test_data.m_n_vertices = test_data.m_grid->m_triangle_strip.m_n_points;
1236     test_data.m_geometry_bo_size =
1237         static_cast<glw::GLuint>(nTriangles * m_n_components_output * 3 /* adjacent vertices */ * sizeof(float));
1238     test_data.m_vertex_data_bo_size =
1239         static_cast<glw::GLuint>(test_data.m_n_vertices * m_n_components_input * sizeof(float));
1240 
1241     /* Allocate memory for input and expected data */
1242     test_data.m_expected_adjacency_geometry           = new float[test_data.m_geometry_bo_size / sizeof(float)];
1243     test_data.m_expected_geometry                     = new float[test_data.m_geometry_bo_size / sizeof(float)];
1244     test_data.m_alternate_expected_adjacency_geometry = new float[test_data.m_geometry_bo_size / sizeof(float)];
1245     test_data.m_alternate_expected_geometry           = new float[test_data.m_geometry_bo_size / sizeof(float)];
1246     test_data.m_vertex_data                           = new float[test_data.m_vertex_data_bo_size / sizeof(float)];
1247 
1248     travellerPtr = test_data.m_vertex_data;
1249 
1250     /* Set input and expected values */
1251     for (unsigned int n = 0; n < test_data.m_n_vertices; ++n)
1252     {
1253         *travellerPtr = test_data.m_grid->m_triangle_strip.m_points[n].x;
1254         ++travellerPtr;
1255         *travellerPtr = test_data.m_grid->m_triangle_strip.m_points[n].y;
1256         ++travellerPtr;
1257     }
1258 
1259     for (unsigned int j = 0; j < 2; ++j)
1260     {
1261         if (j == 0)
1262         {
1263             travellerExpectedAdjacencyGeometryPtr = test_data.m_expected_adjacency_geometry;
1264             travellerExpectedGeometryPtr          = test_data.m_expected_geometry;
1265         }
1266         else
1267         {
1268             travellerExpectedAdjacencyGeometryPtr = test_data.m_alternate_expected_adjacency_geometry;
1269             travellerExpectedGeometryPtr          = test_data.m_alternate_expected_geometry;
1270         }
1271         for (unsigned int n = 0; n < nTriangles; ++n)
1272         {
1273             /* Derived from per table 2.X1 from the spec */
1274             int vertexIndex[3]    = {-1, -1, -1};
1275             int adjVertexIndex[3] = {-1, -1, -1};
1276 
1277             if (n == 0)
1278             {
1279                 /* first (i==0) */
1280                 adjVertexIndex[0] = 2;
1281                 adjVertexIndex[1] = 7;
1282                 adjVertexIndex[2] = 4;
1283                 vertexIndex[0]    = 1;
1284                 vertexIndex[1]    = 3;
1285                 vertexIndex[2]    = 5;
1286             }
1287             else if (n == nTriangles - 1)
1288             {
1289                 if (n % 2 == 0)
1290                 {
1291                     /* last (i==n-1, i even) */
1292                     adjVertexIndex[0] = 2 * n - 1;
1293                     adjVertexIndex[1] = 2 * n + 6;
1294                     adjVertexIndex[2] = 2 * n + 4;
1295                     vertexIndex[0]    = 2 * n + 1;
1296                     vertexIndex[1]    = 2 * n + 3;
1297                     vertexIndex[2]    = 2 * n + 5;
1298                 }
1299                 else
1300                 {
1301                     /* last (i==n-1, i odd) */
1302                     if (j == 0)
1303                     {
1304                         adjVertexIndex[0] = 2 * n - 1;
1305                         adjVertexIndex[1] = 2 * n + 4;
1306                         adjVertexIndex[2] = 2 * n + 6;
1307                         vertexIndex[0]    = 2 * n + 3;
1308                         vertexIndex[1]    = 2 * n + 1;
1309                         vertexIndex[2]    = 2 * n + 5;
1310                     }
1311                     else
1312                     {
1313                         adjVertexIndex[0] = 2 * n + 4;
1314                         adjVertexIndex[1] = 2 * n + 6;
1315                         adjVertexIndex[2] = 2 * n - 1;
1316                         vertexIndex[0]    = 2 * n + 1;
1317                         vertexIndex[1]    = 2 * n + 5;
1318                         vertexIndex[2]    = 2 * n + 3;
1319                     }
1320                 }
1321             }
1322             else
1323             {
1324                 if (n % 2 == 0)
1325                 {
1326                     /* middle (i even) */
1327                     adjVertexIndex[0] = 2 * n - 1;
1328                     adjVertexIndex[1] = 2 * n + 7;
1329                     adjVertexIndex[2] = 2 * n + 4;
1330                     vertexIndex[0]    = 2 * n + 1;
1331                     vertexIndex[1]    = 2 * n + 3;
1332                     vertexIndex[2]    = 2 * n + 5;
1333                 }
1334                 else
1335                 {
1336                     /* middle (i odd) */
1337                     if (j == 0)
1338                     {
1339 
1340                         adjVertexIndex[0] = 2 * n - 1;
1341                         adjVertexIndex[1] = 2 * n + 4;
1342                         adjVertexIndex[2] = 2 * n + 7;
1343                         vertexIndex[0]    = 2 * n + 3;
1344                         vertexIndex[1]    = 2 * n + 1;
1345                         vertexIndex[2]    = 2 * n + 5;
1346                     }
1347                     else
1348                     {
1349                         adjVertexIndex[0] = 2 * n + 4;
1350                         adjVertexIndex[1] = 2 * n + 7;
1351                         adjVertexIndex[2] = 2 * n - 1;
1352                         vertexIndex[0]    = 2 * n + 1;
1353                         vertexIndex[1]    = 2 * n + 5;
1354                         vertexIndex[2]    = 2 * n + 3;
1355                     }
1356                 }
1357             }
1358 
1359             /* Spec assumes vertices are indexed from 1 */
1360             vertexIndex[0]--;
1361             vertexIndex[1]--;
1362             vertexIndex[2]--;
1363             adjVertexIndex[0]--;
1364             adjVertexIndex[1]--;
1365             adjVertexIndex[2]--;
1366 
1367             *travellerExpectedAdjacencyGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[adjVertexIndex[0]].x;
1368             ++travellerExpectedAdjacencyGeometryPtr;
1369             *travellerExpectedAdjacencyGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[adjVertexIndex[0]].y;
1370             ++travellerExpectedAdjacencyGeometryPtr;
1371             *travellerExpectedAdjacencyGeometryPtr = 0;
1372             ++travellerExpectedAdjacencyGeometryPtr;
1373             *travellerExpectedAdjacencyGeometryPtr = 1;
1374             ++travellerExpectedAdjacencyGeometryPtr;
1375             *travellerExpectedAdjacencyGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[adjVertexIndex[1]].x;
1376             ++travellerExpectedAdjacencyGeometryPtr;
1377             *travellerExpectedAdjacencyGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[adjVertexIndex[1]].y;
1378             ++travellerExpectedAdjacencyGeometryPtr;
1379             *travellerExpectedAdjacencyGeometryPtr = 0;
1380             ++travellerExpectedAdjacencyGeometryPtr;
1381             *travellerExpectedAdjacencyGeometryPtr = 1;
1382             ++travellerExpectedAdjacencyGeometryPtr;
1383             *travellerExpectedAdjacencyGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[adjVertexIndex[2]].x;
1384             ++travellerExpectedAdjacencyGeometryPtr;
1385             *travellerExpectedAdjacencyGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[adjVertexIndex[2]].y;
1386             ++travellerExpectedAdjacencyGeometryPtr;
1387             *travellerExpectedAdjacencyGeometryPtr = 0;
1388             ++travellerExpectedAdjacencyGeometryPtr;
1389             *travellerExpectedAdjacencyGeometryPtr = 1;
1390             ++travellerExpectedAdjacencyGeometryPtr;
1391 
1392             *travellerExpectedGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[vertexIndex[0]].x;
1393             ++travellerExpectedGeometryPtr;
1394             *travellerExpectedGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[vertexIndex[0]].y;
1395             ++travellerExpectedGeometryPtr;
1396             *travellerExpectedGeometryPtr = 0;
1397             ++travellerExpectedGeometryPtr;
1398             *travellerExpectedGeometryPtr = 1;
1399             ++travellerExpectedGeometryPtr;
1400             *travellerExpectedGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[vertexIndex[1]].x;
1401             ++travellerExpectedGeometryPtr;
1402             *travellerExpectedGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[vertexIndex[1]].y;
1403             ++travellerExpectedGeometryPtr;
1404             *travellerExpectedGeometryPtr = 0;
1405             ++travellerExpectedGeometryPtr;
1406             *travellerExpectedGeometryPtr = 1;
1407             ++travellerExpectedGeometryPtr;
1408             *travellerExpectedGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[vertexIndex[2]].x;
1409             ++travellerExpectedGeometryPtr;
1410             *travellerExpectedGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[vertexIndex[2]].y;
1411             ++travellerExpectedGeometryPtr;
1412             *travellerExpectedGeometryPtr = 0;
1413             ++travellerExpectedGeometryPtr;
1414             *travellerExpectedGeometryPtr = 1;
1415             ++travellerExpectedGeometryPtr;
1416         } /* for (all triangles) */
1417     }
1418 }
1419 
1420 /** Set triangle strip vertex data used to be used by indiced draw calls.
1421  *
1422  * @param test_data AdjacencyTestData instance to be filled with relevant data.
1423  **/
setTriangleStripPointsIndiced(AdjacencyTestData & test_data)1424 void GeometryShaderAdjacencyTests::setTriangleStripPointsIndiced(AdjacencyTestData &test_data)
1425 {
1426     unsigned int nTriangles = (test_data.m_grid->m_triangle_strip.m_n_points - 4) / 2;
1427 
1428     float *travellerExpectedAdjacencyGeometryPtr = 0;
1429     float *travellerExpectedGeometryPtr          = 0;
1430     unsigned int *travellerIndicesPtr            = 0;
1431     float *travellerPtr                          = 0;
1432 
1433     /* Set buffer sizes */
1434     test_data.m_n_vertices = test_data.m_grid->m_triangle_strip.m_n_points;
1435     test_data.m_geometry_bo_size =
1436         static_cast<glw::GLuint>(nTriangles * m_n_components_output * 3 /* adjacent vertices */ * sizeof(float));
1437     test_data.m_vertex_data_bo_size =
1438         static_cast<glw::GLuint>(test_data.m_n_vertices * m_n_components_input * sizeof(float));
1439     test_data.m_index_data_bo_size = static_cast<glw::GLuint>(test_data.m_n_vertices * sizeof(unsigned int));
1440 
1441     /* Allocate memory for input and expected data */
1442     test_data.m_expected_adjacency_geometry           = new float[test_data.m_geometry_bo_size / sizeof(float)];
1443     test_data.m_expected_geometry                     = new float[test_data.m_geometry_bo_size / sizeof(float)];
1444     test_data.m_alternate_expected_adjacency_geometry = new float[test_data.m_geometry_bo_size / sizeof(float)];
1445     test_data.m_alternate_expected_geometry           = new float[test_data.m_geometry_bo_size / sizeof(float)];
1446     test_data.m_index_data  = new unsigned int[test_data.m_index_data_bo_size / sizeof(unsigned int)];
1447     test_data.m_vertex_data = new float[test_data.m_vertex_data_bo_size / sizeof(float)];
1448 
1449     travellerIndicesPtr = test_data.m_index_data;
1450     travellerPtr        = test_data.m_vertex_data;
1451 
1452     /* Set input and expected values */
1453     for (unsigned int n = 0; n < test_data.m_n_vertices; ++n)
1454     {
1455         *travellerIndicesPtr = (test_data.m_n_vertices - 1) - n;
1456         ++travellerIndicesPtr;
1457     }
1458 
1459     for (unsigned int n = 0; n < test_data.m_n_vertices; ++n)
1460     {
1461         *travellerPtr = test_data.m_grid->m_triangle_strip.m_points[n].x;
1462         ++travellerPtr;
1463         *travellerPtr = test_data.m_grid->m_triangle_strip.m_points[n].y;
1464         ++travellerPtr;
1465     }
1466 
1467     for (unsigned int j = 0; j < 2; ++j)
1468     {
1469         if (j == 0)
1470         {
1471             travellerExpectedAdjacencyGeometryPtr = test_data.m_expected_adjacency_geometry;
1472             travellerExpectedGeometryPtr          = test_data.m_expected_geometry;
1473         }
1474         else
1475         {
1476             travellerExpectedAdjacencyGeometryPtr = test_data.m_alternate_expected_adjacency_geometry;
1477             travellerExpectedGeometryPtr          = test_data.m_alternate_expected_geometry;
1478         }
1479 
1480         for (unsigned int n = 0; n < nTriangles; ++n)
1481         {
1482             /* Derived from per table 2.X1 from the spec */
1483             int vertexIndex[3]    = {-1, -1, -1};
1484             int adjVertexIndex[3] = {-1, -1, -1};
1485 
1486             if (n == 0)
1487             {
1488                 /* first (i==0) */
1489                 adjVertexIndex[0] = 2;
1490                 adjVertexIndex[1] = 7;
1491                 adjVertexIndex[2] = 4;
1492                 vertexIndex[0]    = 1;
1493                 vertexIndex[1]    = 3;
1494                 vertexIndex[2]    = 5;
1495             }
1496             else if (n == nTriangles - 1)
1497             {
1498                 if (n % 2 == 0)
1499                 {
1500                     /* last (i==n-1, i even) */
1501                     adjVertexIndex[0] = 2 * n - 1;
1502                     adjVertexIndex[1] = 2 * n + 6;
1503                     adjVertexIndex[2] = 2 * n + 4;
1504                     vertexIndex[0]    = 2 * n + 1;
1505                     vertexIndex[1]    = 2 * n + 3;
1506                     vertexIndex[2]    = 2 * n + 5;
1507                 }
1508                 else
1509                 {
1510                     /* last (i==n-1, i odd) */
1511                     if (j == 0)
1512                     {
1513                         adjVertexIndex[0] = 2 * n - 1;
1514                         adjVertexIndex[1] = 2 * n + 4;
1515                         adjVertexIndex[2] = 2 * n + 6;
1516                         vertexIndex[0]    = 2 * n + 3;
1517                         vertexIndex[1]    = 2 * n + 1;
1518                         vertexIndex[2]    = 2 * n + 5;
1519                     }
1520                     else
1521                     {
1522                         adjVertexIndex[0] = 2 * n + 4;
1523                         adjVertexIndex[1] = 2 * n + 6;
1524                         adjVertexIndex[2] = 2 * n - 1;
1525                         vertexIndex[0]    = 2 * n + 1;
1526                         vertexIndex[1]    = 2 * n + 5;
1527                         vertexIndex[2]    = 2 * n + 3;
1528                     }
1529                 }
1530             }
1531             else
1532             {
1533                 if (n % 2 == 0)
1534                 {
1535                     /* middle (i even) */
1536                     adjVertexIndex[0] = 2 * n - 1;
1537                     adjVertexIndex[1] = 2 * n + 7;
1538                     adjVertexIndex[2] = 2 * n + 4;
1539                     vertexIndex[0]    = 2 * n + 1;
1540                     vertexIndex[1]    = 2 * n + 3;
1541                     vertexIndex[2]    = 2 * n + 5;
1542                 }
1543                 else
1544                 {
1545                     /* middle (i odd) */
1546                     if (j == 0)
1547                     {
1548                         adjVertexIndex[0] = 2 * n - 1;
1549                         adjVertexIndex[1] = 2 * n + 4;
1550                         adjVertexIndex[2] = 2 * n + 7;
1551                         vertexIndex[0]    = 2 * n + 3;
1552                         vertexIndex[1]    = 2 * n + 1;
1553                         vertexIndex[2]    = 2 * n + 5;
1554                     }
1555                     else
1556                     {
1557                         adjVertexIndex[0] = 2 * n + 4;
1558                         adjVertexIndex[1] = 2 * n + 7;
1559                         adjVertexIndex[2] = 2 * n - 1;
1560                         vertexIndex[0]    = 2 * n + 1;
1561                         vertexIndex[1]    = 2 * n + 5;
1562                         vertexIndex[2]    = 2 * n + 3;
1563                     }
1564                 }
1565             }
1566 
1567             /* Spec assumes vertices are indexed from 1 */
1568             vertexIndex[0]--;
1569             vertexIndex[1]--;
1570             vertexIndex[2]--;
1571             adjVertexIndex[0]--;
1572             adjVertexIndex[1]--;
1573             adjVertexIndex[2]--;
1574 
1575             *travellerExpectedAdjacencyGeometryPtr =
1576                 test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[adjVertexIndex[0]]].x;
1577             ++travellerExpectedAdjacencyGeometryPtr;
1578             *travellerExpectedAdjacencyGeometryPtr =
1579                 test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[adjVertexIndex[0]]].y;
1580             ++travellerExpectedAdjacencyGeometryPtr;
1581             *travellerExpectedAdjacencyGeometryPtr = 0;
1582             ++travellerExpectedAdjacencyGeometryPtr;
1583             *travellerExpectedAdjacencyGeometryPtr = 1;
1584             ++travellerExpectedAdjacencyGeometryPtr;
1585             *travellerExpectedAdjacencyGeometryPtr =
1586                 test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[adjVertexIndex[1]]].x;
1587             ++travellerExpectedAdjacencyGeometryPtr;
1588             *travellerExpectedAdjacencyGeometryPtr =
1589                 test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[adjVertexIndex[1]]].y;
1590             ++travellerExpectedAdjacencyGeometryPtr;
1591             *travellerExpectedAdjacencyGeometryPtr = 0;
1592             ++travellerExpectedAdjacencyGeometryPtr;
1593             *travellerExpectedAdjacencyGeometryPtr = 1;
1594             ++travellerExpectedAdjacencyGeometryPtr;
1595             *travellerExpectedAdjacencyGeometryPtr =
1596                 test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[adjVertexIndex[2]]].x;
1597             ++travellerExpectedAdjacencyGeometryPtr;
1598             *travellerExpectedAdjacencyGeometryPtr =
1599                 test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[adjVertexIndex[2]]].y;
1600             ++travellerExpectedAdjacencyGeometryPtr;
1601             *travellerExpectedAdjacencyGeometryPtr = 0;
1602             ++travellerExpectedAdjacencyGeometryPtr;
1603             *travellerExpectedAdjacencyGeometryPtr = 1;
1604             ++travellerExpectedAdjacencyGeometryPtr;
1605 
1606             *travellerExpectedGeometryPtr =
1607                 test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[vertexIndex[0]]].x;
1608             ++travellerExpectedGeometryPtr;
1609             *travellerExpectedGeometryPtr =
1610                 test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[vertexIndex[0]]].y;
1611             ++travellerExpectedGeometryPtr;
1612             *travellerExpectedGeometryPtr = 0;
1613             ++travellerExpectedGeometryPtr;
1614             *travellerExpectedGeometryPtr = 1;
1615             ++travellerExpectedGeometryPtr;
1616             *travellerExpectedGeometryPtr =
1617                 test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[vertexIndex[1]]].x;
1618             ++travellerExpectedGeometryPtr;
1619             *travellerExpectedGeometryPtr =
1620                 test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[vertexIndex[1]]].y;
1621             ++travellerExpectedGeometryPtr;
1622             *travellerExpectedGeometryPtr = 0;
1623             ++travellerExpectedGeometryPtr;
1624             *travellerExpectedGeometryPtr = 1;
1625             ++travellerExpectedGeometryPtr;
1626             *travellerExpectedGeometryPtr =
1627                 test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[vertexIndex[2]]].x;
1628             ++travellerExpectedGeometryPtr;
1629             *travellerExpectedGeometryPtr =
1630                 test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[vertexIndex[2]]].y;
1631             ++travellerExpectedGeometryPtr;
1632             *travellerExpectedGeometryPtr = 0;
1633             ++travellerExpectedGeometryPtr;
1634             *travellerExpectedGeometryPtr = 1;
1635             ++travellerExpectedGeometryPtr;
1636         } /* for (all triangles) */
1637     }
1638 }
1639 } // namespace glcts
1640