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
30namespace 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 **/
39GeometryShaderAdjacencyTests::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 **/
54void 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 **/
71void 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 **/
133void 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 **/
181void 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 **/
229void 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 **/
280void 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 */
329void 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 **/
406void 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 **/
522void 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 = test_data.m_grid->m_line_segments[test_data.m_grid->m_n_segments - 1].m_point_end_adjacent->x;
548			pointPtr->y = test_data.m_grid->m_line_segments[test_data.m_grid->m_n_segments - 1].m_point_end_adjacent->y;
549		}
550		else
551		/* Intermediate points */
552		{
553			pointPtr->x = test_data.m_grid->m_line_segments[n - 1].m_point_start->x;
554			pointPtr->y = test_data.m_grid->m_line_segments[n - 1].m_point_start->y;
555		}
556	} /* for (all points) */
557}
558
559/** Generate Triangles data.
560 *
561 * @param test_data AdjacencyTestData instance to be filled with triangles data.
562 **/
563void GeometryShaderAdjacencyTests::createGridTriangles(AdjacencyTestData& test_data)
564{
565	const int	nTrianglesPerQuad = 2;
566	unsigned int nTriangles		   = m_grid_granulity * m_grid_granulity * nTrianglesPerQuad;
567
568	test_data.m_grid->m_triangles   = new AdjacencyGridTriangle[nTriangles];
569	test_data.m_grid->m_n_triangles = nTriangles;
570
571	for (unsigned int nQuad = 0; nQuad < (nTriangles / nTrianglesPerQuad); ++nQuad)
572	{
573		unsigned int quadTLX = (nQuad) % m_grid_granulity;
574		unsigned int quadTLY = (nQuad) / m_grid_granulity;
575
576		/* Grid is built off points row-by-row. */
577		AdjacencyGridPoint* pointTL = test_data.m_grid->m_points + (quadTLY * (m_grid_granulity + 1) + quadTLX);
578		AdjacencyGridPoint* pointTR = test_data.m_grid->m_points + (quadTLY * (m_grid_granulity + 1) + quadTLX + 1);
579		AdjacencyGridPoint* pointBL = test_data.m_grid->m_points + ((quadTLY + 1) * (m_grid_granulity + 1) + quadTLX);
580		AdjacencyGridPoint* pointBR =
581			test_data.m_grid->m_points + ((quadTLY + 1) * (m_grid_granulity + 1) + quadTLX + 1);
582
583		/* Note: In many cases, the adjacency data used below is not correct topologically-wise.
584		 *       However, since we're not doing any rendering, we're safe as long as unique data
585		 *       is used.
586		 */
587		test_data.m_grid->m_triangles[nQuad * nTrianglesPerQuad + 0].m_vertex_x			 = pointTL;
588		test_data.m_grid->m_triangles[nQuad * nTrianglesPerQuad + 0].m_vertex_x_adjacent = pointTR;
589		test_data.m_grid->m_triangles[nQuad * nTrianglesPerQuad + 0].m_vertex_y			 = pointBR;
590		test_data.m_grid->m_triangles[nQuad * nTrianglesPerQuad + 0].m_vertex_y_adjacent = pointBL;
591		test_data.m_grid->m_triangles[nQuad * nTrianglesPerQuad + 0].m_vertex_z			 = pointBL;
592		test_data.m_grid->m_triangles[nQuad * nTrianglesPerQuad + 0].m_vertex_z_adjacent = pointBR;
593
594		test_data.m_grid->m_triangles[nQuad * nTrianglesPerQuad + 1].m_vertex_x			 = pointTL;
595		test_data.m_grid->m_triangles[nQuad * nTrianglesPerQuad + 1].m_vertex_x_adjacent = pointTR;
596		test_data.m_grid->m_triangles[nQuad * nTrianglesPerQuad + 1].m_vertex_y			 = pointTR;
597		test_data.m_grid->m_triangles[nQuad * nTrianglesPerQuad + 1].m_vertex_y_adjacent = pointTL;
598		test_data.m_grid->m_triangles[nQuad * nTrianglesPerQuad + 1].m_vertex_z			 = pointBR;
599		test_data.m_grid->m_triangles[nQuad * nTrianglesPerQuad + 1].m_vertex_z_adjacent = pointBL;
600	}
601}
602
603/** Generate Triangle Strip data.
604 *
605 * @param test_data AdjacencyTestData instance to be filled with relevant data.
606 **/
607void GeometryShaderAdjacencyTests::createGridTriangleStrip(AdjacencyTestData& test_data)
608{
609	/* For simplicity, reuse adjacency data we have already defined for single triangles.
610	 * This does not make a correct topology, but our point is to verify that shaders
611	 * are fed valid values (as per spec), not to confirm rendering works correctly.
612	 */
613	const int nVerticesPerTriangleStripPrimitive = 6;
614
615	test_data.m_grid->m_triangle_strip.m_n_points =
616		test_data.m_grid->m_n_triangles * nVerticesPerTriangleStripPrimitive;
617	test_data.m_grid->m_triangle_strip.m_points = new AdjacencyGridPoint[test_data.m_grid->m_triangle_strip.m_n_points];
618
619	memset(test_data.m_grid->m_triangle_strip.m_points, 0,
620		   sizeof(AdjacencyGridPoint) * test_data.m_grid->m_triangle_strip.m_n_points);
621
622	for (unsigned int n = 0; n < test_data.m_grid->m_triangle_strip.m_n_points; ++n)
623	{
624		AdjacencyGridPoint*	pointPtr		 = test_data.m_grid->m_triangle_strip.m_points + n;
625		unsigned int		   triangleIndex = n / nVerticesPerTriangleStripPrimitive;
626		AdjacencyGridTriangle* trianglePtr   = test_data.m_grid->m_triangles + triangleIndex;
627
628		pointPtr->index = n;
629
630		switch (n % nVerticesPerTriangleStripPrimitive)
631		{
632		case 0:
633			pointPtr->x = trianglePtr->m_vertex_x->x;
634			pointPtr->y = trianglePtr->m_vertex_x->y;
635			break;
636		case 1:
637			pointPtr->x = trianglePtr->m_vertex_x_adjacent->x;
638			pointPtr->y = trianglePtr->m_vertex_x_adjacent->y;
639			break;
640		case 2:
641			pointPtr->x = trianglePtr->m_vertex_y->x;
642			pointPtr->y = trianglePtr->m_vertex_y->y;
643			break;
644		case 3:
645			pointPtr->x = trianglePtr->m_vertex_y_adjacent->x;
646			pointPtr->y = trianglePtr->m_vertex_y_adjacent->y;
647			break;
648		case 4:
649			pointPtr->x = trianglePtr->m_vertex_z->x;
650			pointPtr->y = trianglePtr->m_vertex_z->y;
651			break;
652		case 5:
653			pointPtr->x = trianglePtr->m_vertex_z_adjacent->x;
654			pointPtr->y = trianglePtr->m_vertex_z_adjacent->y;
655			break;
656		}
657	} /* for (all points) */
658}
659
660/** Set line vertex data used to be used by non-indiced draw calls.
661 *
662 * @param test_data AdjacencyTestData instance to be filled with relevant data.
663 **/
664void GeometryShaderAdjacencyTests::setLinePointsNonindiced(AdjacencyTestData& test_data)
665{
666	float* travellerExpectedAdjacencyGeometryPtr = 0;
667	float* travellerExpectedGeometryPtr			 = 0;
668	float* travellerPtr							 = 0;
669
670	/* Set buffer sizes */
671	test_data.m_n_vertices = test_data.m_grid->m_n_segments * 2 /* start + end points form a segment */;
672	test_data.m_geometry_bo_size =
673		static_cast<glw::GLuint>(test_data.m_n_vertices * m_n_components_output * sizeof(float));
674	test_data.m_vertex_data_bo_size = static_cast<glw::GLuint>(test_data.m_n_vertices * m_n_components_input *
675															   2 /* include adjacency info */ * sizeof(float));
676
677	/* Allocate memory for input and expected data */
678	test_data.m_expected_adjacency_geometry = new float[test_data.m_geometry_bo_size / sizeof(float)];
679	test_data.m_expected_geometry			= new float[test_data.m_geometry_bo_size / sizeof(float)];
680	test_data.m_vertex_data					= new float[test_data.m_vertex_data_bo_size / sizeof(float)];
681
682	travellerExpectedAdjacencyGeometryPtr = test_data.m_expected_adjacency_geometry;
683	travellerExpectedGeometryPtr		  = test_data.m_expected_geometry;
684	travellerPtr						  = test_data.m_vertex_data;
685
686	/* Set input and expected values */
687	for (unsigned int n = 0; n < test_data.m_grid->m_n_segments; ++n)
688	{
689		AdjacencyGridLineSegment* segmentPtr = test_data.m_grid->m_line_segments + n;
690
691		*travellerPtr = segmentPtr->m_point_start_adjacent->x;
692		++travellerPtr;
693		*travellerPtr = segmentPtr->m_point_start_adjacent->y;
694		++travellerPtr;
695		*travellerPtr = segmentPtr->m_point_start->x;
696		++travellerPtr;
697		*travellerPtr = segmentPtr->m_point_start->y;
698		++travellerPtr;
699		*travellerPtr = segmentPtr->m_point_end->x;
700		++travellerPtr;
701		*travellerPtr = segmentPtr->m_point_end->y;
702		++travellerPtr;
703		*travellerPtr = segmentPtr->m_point_end_adjacent->x;
704		++travellerPtr;
705		*travellerPtr = segmentPtr->m_point_end_adjacent->y;
706		++travellerPtr;
707
708		*travellerExpectedAdjacencyGeometryPtr = segmentPtr->m_point_start_adjacent->x;
709		++travellerExpectedAdjacencyGeometryPtr;
710		*travellerExpectedAdjacencyGeometryPtr = segmentPtr->m_point_start_adjacent->y;
711		++travellerExpectedAdjacencyGeometryPtr;
712		*travellerExpectedAdjacencyGeometryPtr = 0;
713		++travellerExpectedAdjacencyGeometryPtr;
714		*travellerExpectedAdjacencyGeometryPtr = 1;
715		++travellerExpectedAdjacencyGeometryPtr;
716		*travellerExpectedAdjacencyGeometryPtr = segmentPtr->m_point_end_adjacent->x;
717		++travellerExpectedAdjacencyGeometryPtr;
718		*travellerExpectedAdjacencyGeometryPtr = segmentPtr->m_point_end_adjacent->y;
719		++travellerExpectedAdjacencyGeometryPtr;
720		*travellerExpectedAdjacencyGeometryPtr = 0;
721		++travellerExpectedAdjacencyGeometryPtr;
722		*travellerExpectedAdjacencyGeometryPtr = 1;
723		++travellerExpectedAdjacencyGeometryPtr;
724
725		*travellerExpectedGeometryPtr = segmentPtr->m_point_start->x;
726		++travellerExpectedGeometryPtr;
727		*travellerExpectedGeometryPtr = segmentPtr->m_point_start->y;
728		++travellerExpectedGeometryPtr;
729		*travellerExpectedGeometryPtr = 0;
730		++travellerExpectedGeometryPtr;
731		*travellerExpectedGeometryPtr = 1;
732		++travellerExpectedGeometryPtr;
733		*travellerExpectedGeometryPtr = segmentPtr->m_point_end->x;
734		++travellerExpectedGeometryPtr;
735		*travellerExpectedGeometryPtr = segmentPtr->m_point_end->y;
736		++travellerExpectedGeometryPtr;
737		*travellerExpectedGeometryPtr = 0;
738		++travellerExpectedGeometryPtr;
739		*travellerExpectedGeometryPtr = 1;
740		++travellerExpectedGeometryPtr;
741	} /* for (all line segments) */
742}
743
744/** Set line vertex data used to be used by indiced draw calls.
745 *
746 * @param test_data AdjacencyTestData instance to be filled with relevant data.
747 **/
748void GeometryShaderAdjacencyTests::setLinePointsindiced(AdjacencyTestData& test_data)
749{
750	float*		  travellerExpectedAdjacencyGeometryPtr = 0;
751	float*		  travellerExpectedGeometryPtr			= 0;
752	unsigned int* travellerIndicesPtr					= 0;
753	float*		  travellerPtr							= 0;
754
755	/* Set buffer sizes */
756	test_data.m_n_vertices = test_data.m_grid->m_n_segments * 2 /* start + end points form a segment */;
757	test_data.m_geometry_bo_size =
758		static_cast<glw::GLuint>(test_data.m_n_vertices * m_n_components_output * sizeof(float));
759	test_data.m_vertex_data_bo_size =
760		static_cast<glw::GLuint>(test_data.m_grid->m_n_points * m_n_components_input * sizeof(float));
761	test_data.m_index_data_bo_size =
762		static_cast<glw::GLuint>(test_data.m_n_vertices * 2 /* include adjacency info */ * sizeof(unsigned int));
763
764	/* Allocate memory for input and expected data */
765	test_data.m_expected_adjacency_geometry = new float[test_data.m_geometry_bo_size / sizeof(float)];
766	test_data.m_expected_geometry			= new float[test_data.m_geometry_bo_size / sizeof(float)];
767	test_data.m_index_data					= new unsigned int[test_data.m_index_data_bo_size / sizeof(unsigned int)];
768	test_data.m_vertex_data					= new float[test_data.m_vertex_data_bo_size / sizeof(float)];
769
770	travellerExpectedAdjacencyGeometryPtr = test_data.m_expected_adjacency_geometry;
771	travellerExpectedGeometryPtr		  = test_data.m_expected_geometry;
772	travellerIndicesPtr					  = test_data.m_index_data;
773	travellerPtr						  = test_data.m_vertex_data;
774
775	/* Set input and expected values */
776	for (unsigned int n = 0; n < test_data.m_grid->m_n_points; ++n)
777	{
778		*travellerPtr = test_data.m_grid->m_points[n].x;
779		++travellerPtr;
780		*travellerPtr = test_data.m_grid->m_points[n].y;
781		++travellerPtr;
782	}
783
784	for (unsigned int n = 0; n < test_data.m_grid->m_n_segments; ++n)
785	{
786		AdjacencyGridLineSegment* segmentPtr = test_data.m_grid->m_line_segments + n;
787
788		*travellerIndicesPtr = segmentPtr->m_point_end_adjacent->index;
789		++travellerIndicesPtr;
790		*travellerIndicesPtr = segmentPtr->m_point_end->index;
791		++travellerIndicesPtr;
792		*travellerIndicesPtr = segmentPtr->m_point_start->index;
793		++travellerIndicesPtr;
794		*travellerIndicesPtr = segmentPtr->m_point_start_adjacent->index;
795		++travellerIndicesPtr;
796
797		*travellerExpectedAdjacencyGeometryPtr = segmentPtr->m_point_end_adjacent->x;
798		++travellerExpectedAdjacencyGeometryPtr;
799		*travellerExpectedAdjacencyGeometryPtr = segmentPtr->m_point_end_adjacent->y;
800		++travellerExpectedAdjacencyGeometryPtr;
801		*travellerExpectedAdjacencyGeometryPtr = 0;
802		++travellerExpectedAdjacencyGeometryPtr;
803		*travellerExpectedAdjacencyGeometryPtr = 1;
804		++travellerExpectedAdjacencyGeometryPtr;
805		*travellerExpectedAdjacencyGeometryPtr = segmentPtr->m_point_start_adjacent->x;
806		++travellerExpectedAdjacencyGeometryPtr;
807		*travellerExpectedAdjacencyGeometryPtr = segmentPtr->m_point_start_adjacent->y;
808		++travellerExpectedAdjacencyGeometryPtr;
809		*travellerExpectedAdjacencyGeometryPtr = 0;
810		++travellerExpectedAdjacencyGeometryPtr;
811		*travellerExpectedAdjacencyGeometryPtr = 1;
812		++travellerExpectedAdjacencyGeometryPtr;
813
814		*travellerExpectedGeometryPtr = segmentPtr->m_point_end->x;
815		++travellerExpectedGeometryPtr;
816		*travellerExpectedGeometryPtr = segmentPtr->m_point_end->y;
817		++travellerExpectedGeometryPtr;
818		*travellerExpectedGeometryPtr = 0;
819		++travellerExpectedGeometryPtr;
820		*travellerExpectedGeometryPtr = 1;
821		++travellerExpectedGeometryPtr;
822		*travellerExpectedGeometryPtr = segmentPtr->m_point_start->x;
823		++travellerExpectedGeometryPtr;
824		*travellerExpectedGeometryPtr = segmentPtr->m_point_start->y;
825		++travellerExpectedGeometryPtr;
826		*travellerExpectedGeometryPtr = 0;
827		++travellerExpectedGeometryPtr;
828		*travellerExpectedGeometryPtr = 1;
829		++travellerExpectedGeometryPtr;
830	} /* for (all line segments) */
831}
832
833/** Set line strip vertex data used to be used by non-indiced draw calls.
834 *
835 * @param test_data AdjacencyTestData instance to be filled with relevant data.
836 **/
837void GeometryShaderAdjacencyTests::setLineStripPointsNonindiced(AdjacencyTestData& test_data)
838{
839	float* travellerExpectedAdjacencyGeometryPtr = 0;
840	float* travellerExpectedGeometryPtr			 = 0;
841	float* travellerPtr							 = 0;
842
843	/* Set buffer sizes */
844	test_data.m_n_vertices		 = test_data.m_grid->m_line_strip.m_n_points;
845	test_data.m_geometry_bo_size = static_cast<glw::GLuint>((test_data.m_n_vertices - 3) * m_n_components_output *
846															2 /* start/end */ * sizeof(float));
847	test_data.m_vertex_data_bo_size =
848		static_cast<glw::GLuint>(test_data.m_n_vertices * m_n_components_input * sizeof(float));
849
850	/* Allocate memory for input and expected data */
851	test_data.m_expected_adjacency_geometry = new float[test_data.m_geometry_bo_size / sizeof(float)];
852	test_data.m_expected_geometry			= new float[test_data.m_geometry_bo_size / sizeof(float)];
853	test_data.m_vertex_data					= new float[test_data.m_vertex_data_bo_size / sizeof(float)];
854
855	travellerExpectedAdjacencyGeometryPtr = test_data.m_expected_adjacency_geometry;
856	travellerExpectedGeometryPtr		  = test_data.m_expected_geometry;
857	travellerPtr						  = test_data.m_vertex_data;
858
859	/* Set input and expected values */
860	for (unsigned int n = 0; n < test_data.m_n_vertices; ++n)
861	{
862		*travellerPtr = test_data.m_grid->m_line_strip.m_points[n].x;
863		++travellerPtr;
864		*travellerPtr = test_data.m_grid->m_line_strip.m_points[n].y;
865		++travellerPtr;
866	}
867
868	for (unsigned int n = 0; n < test_data.m_n_vertices - 3; ++n)
869	{
870		*travellerExpectedAdjacencyGeometryPtr = test_data.m_grid->m_line_strip.m_points[n].x;
871		++travellerExpectedAdjacencyGeometryPtr;
872		*travellerExpectedAdjacencyGeometryPtr = test_data.m_grid->m_line_strip.m_points[n].y;
873		++travellerExpectedAdjacencyGeometryPtr;
874		*travellerExpectedAdjacencyGeometryPtr = 0;
875		++travellerExpectedAdjacencyGeometryPtr;
876		*travellerExpectedAdjacencyGeometryPtr = 1;
877		++travellerExpectedAdjacencyGeometryPtr;
878		*travellerExpectedAdjacencyGeometryPtr = test_data.m_grid->m_line_strip.m_points[n + 3].x;
879		++travellerExpectedAdjacencyGeometryPtr;
880		*travellerExpectedAdjacencyGeometryPtr = test_data.m_grid->m_line_strip.m_points[n + 3].y;
881		++travellerExpectedAdjacencyGeometryPtr;
882		*travellerExpectedAdjacencyGeometryPtr = 0;
883		++travellerExpectedAdjacencyGeometryPtr;
884		*travellerExpectedAdjacencyGeometryPtr = 1;
885		++travellerExpectedAdjacencyGeometryPtr;
886
887		*travellerExpectedGeometryPtr = test_data.m_grid->m_line_strip.m_points[n + 1].x;
888		++travellerExpectedGeometryPtr;
889		*travellerExpectedGeometryPtr = test_data.m_grid->m_line_strip.m_points[n + 1].y;
890		++travellerExpectedGeometryPtr;
891		*travellerExpectedGeometryPtr = 0;
892		++travellerExpectedGeometryPtr;
893		*travellerExpectedGeometryPtr = 1;
894		++travellerExpectedGeometryPtr;
895		*travellerExpectedGeometryPtr = test_data.m_grid->m_line_strip.m_points[n + 2].x;
896		++travellerExpectedGeometryPtr;
897		*travellerExpectedGeometryPtr = test_data.m_grid->m_line_strip.m_points[n + 2].y;
898		++travellerExpectedGeometryPtr;
899		*travellerExpectedGeometryPtr = 0;
900		++travellerExpectedGeometryPtr;
901		*travellerExpectedGeometryPtr = 1;
902		++travellerExpectedGeometryPtr;
903	} /* for (all vertices (apart from the three last ones) ) */
904}
905
906/** Set line strip vertex data used to be used by indiced draw calls.
907 *
908 * @param test_data AdjacencyTestData instance to be filled with relevant data.
909 **/
910void GeometryShaderAdjacencyTests::setLineStripPointsIndiced(AdjacencyTestData& test_data)
911{
912
913	float*		  travellerExpectedAdjacencyGeometryPtr = 0;
914	float*		  travellerExpectedGeometryPtr			= 0;
915	unsigned int* travellerIndicesPtr					= 0;
916	float*		  travellerPtr							= 0;
917
918	/* Set buffer sizes */
919	test_data.m_n_vertices		 = test_data.m_grid->m_line_strip.m_n_points;
920	test_data.m_geometry_bo_size = static_cast<glw::GLuint>((test_data.m_n_vertices - 3) * m_n_components_output *
921															2 /* start/end */ * sizeof(float));
922	test_data.m_vertex_data_bo_size =
923		static_cast<glw::GLuint>(test_data.m_n_vertices * m_n_components_input * sizeof(float));
924	test_data.m_index_data_bo_size = static_cast<glw::GLuint>(test_data.m_n_vertices * sizeof(unsigned int));
925
926	/* Allocate memory for input and expected data */
927	test_data.m_expected_adjacency_geometry = new float[test_data.m_geometry_bo_size / sizeof(float)];
928	test_data.m_expected_geometry			= new float[test_data.m_geometry_bo_size / sizeof(float)];
929	test_data.m_index_data					= new unsigned int[test_data.m_index_data_bo_size / sizeof(unsigned int)];
930	test_data.m_vertex_data					= new float[test_data.m_vertex_data_bo_size / sizeof(float)];
931
932	travellerExpectedAdjacencyGeometryPtr = test_data.m_expected_adjacency_geometry;
933	travellerExpectedGeometryPtr		  = test_data.m_expected_geometry;
934	travellerIndicesPtr					  = test_data.m_index_data;
935	travellerPtr						  = test_data.m_vertex_data;
936
937	/* Set input and expected value s*/
938	for (unsigned int n = 0; n < test_data.m_n_vertices; ++n)
939	{
940		*travellerPtr = test_data.m_grid->m_line_strip.m_points[n].x;
941		++travellerPtr;
942		*travellerPtr = test_data.m_grid->m_line_strip.m_points[n].y;
943		++travellerPtr;
944	}
945
946	for (unsigned int n = 0; n < test_data.m_n_vertices; ++n)
947	{
948		*travellerIndicesPtr = (test_data.m_n_vertices - n - 1);
949		++travellerIndicesPtr;
950	}
951
952	for (unsigned int n = 0; n < test_data.m_n_vertices - 3; ++n)
953	{
954		AdjacencyGridPoint* pointN0 = test_data.m_grid->m_line_strip.m_points + test_data.m_index_data[n];
955		AdjacencyGridPoint* pointN1 = test_data.m_grid->m_line_strip.m_points + test_data.m_index_data[n + 1];
956		AdjacencyGridPoint* pointN2 = test_data.m_grid->m_line_strip.m_points + test_data.m_index_data[n + 2];
957		AdjacencyGridPoint* pointN3 = test_data.m_grid->m_line_strip.m_points + test_data.m_index_data[n + 3];
958
959		*travellerExpectedAdjacencyGeometryPtr = pointN0->x;
960		++travellerExpectedAdjacencyGeometryPtr;
961		*travellerExpectedAdjacencyGeometryPtr = pointN0->y;
962		++travellerExpectedAdjacencyGeometryPtr;
963		*travellerExpectedAdjacencyGeometryPtr = 0;
964		++travellerExpectedAdjacencyGeometryPtr;
965		*travellerExpectedAdjacencyGeometryPtr = 1;
966		++travellerExpectedAdjacencyGeometryPtr;
967		*travellerExpectedAdjacencyGeometryPtr = pointN3->x;
968		++travellerExpectedAdjacencyGeometryPtr;
969		*travellerExpectedAdjacencyGeometryPtr = pointN3->y;
970		++travellerExpectedAdjacencyGeometryPtr;
971		*travellerExpectedAdjacencyGeometryPtr = 0;
972		++travellerExpectedAdjacencyGeometryPtr;
973		*travellerExpectedAdjacencyGeometryPtr = 1;
974		++travellerExpectedAdjacencyGeometryPtr;
975
976		*travellerExpectedGeometryPtr = pointN1->x;
977		++travellerExpectedGeometryPtr;
978		*travellerExpectedGeometryPtr = pointN1->y;
979		++travellerExpectedGeometryPtr;
980		*travellerExpectedGeometryPtr = 0;
981		++travellerExpectedGeometryPtr;
982		*travellerExpectedGeometryPtr = 1;
983		++travellerExpectedGeometryPtr;
984		*travellerExpectedGeometryPtr = pointN2->x;
985		++travellerExpectedGeometryPtr;
986		*travellerExpectedGeometryPtr = pointN2->y;
987		++travellerExpectedGeometryPtr;
988		*travellerExpectedGeometryPtr = 0;
989		++travellerExpectedGeometryPtr;
990		*travellerExpectedGeometryPtr = 1;
991		++travellerExpectedGeometryPtr;
992	} /* for (all vertices apart from the three last ones) */
993}
994
995/** Set triangle vertex data used to be used by non-indiced draw calls.
996 *
997 * @param test_data AdjacencyTestData instance to be filled with relevant data.
998 **/
999void GeometryShaderAdjacencyTests::setTrianglePointsNonindiced(AdjacencyTestData& test_data)
1000{
1001	float* travellerExpectedAdjacencyGeometryPtr = NULL;
1002	float* travellerExpectedGeometryPtr			 = NULL;
1003	float* travellerPtr							 = NULL;
1004
1005	/* Set buffer sizes */
1006	test_data.m_n_vertices		 = test_data.m_grid->m_n_triangles * m_n_vertices_per_triangle;
1007	test_data.m_geometry_bo_size = static_cast<glw::GLuint>(
1008		test_data.m_grid->m_n_triangles * m_n_vertices_per_triangle * m_n_components_output * sizeof(float));
1009	test_data.m_vertex_data_bo_size = static_cast<glw::GLuint>(test_data.m_n_vertices * m_n_components_input *
1010															   sizeof(float) * 2); /* include adjacency info */
1011
1012	/* Allocate memory for input and expected data */
1013	test_data.m_expected_adjacency_geometry = new float[test_data.m_geometry_bo_size / sizeof(float)];
1014	test_data.m_expected_geometry			= new float[test_data.m_geometry_bo_size / sizeof(float)];
1015	test_data.m_vertex_data					= new float[test_data.m_vertex_data_bo_size / sizeof(float)];
1016
1017	travellerExpectedAdjacencyGeometryPtr = test_data.m_expected_adjacency_geometry;
1018	travellerExpectedGeometryPtr		  = test_data.m_expected_geometry;
1019	travellerPtr						  = test_data.m_vertex_data;
1020
1021	/* Set input and expected values */
1022	for (unsigned int n = 0; n < test_data.m_grid->m_n_triangles; ++n)
1023	{
1024		AdjacencyGridTriangle* trianglePtr = test_data.m_grid->m_triangles + n;
1025
1026		*travellerPtr = trianglePtr->m_vertex_x->x;
1027		++travellerPtr;
1028		*travellerPtr = trianglePtr->m_vertex_x->y;
1029		++travellerPtr;
1030		*travellerPtr = trianglePtr->m_vertex_x_adjacent->x;
1031		++travellerPtr;
1032		*travellerPtr = trianglePtr->m_vertex_x_adjacent->y;
1033		++travellerPtr;
1034		*travellerPtr = trianglePtr->m_vertex_y->x;
1035		++travellerPtr;
1036		*travellerPtr = trianglePtr->m_vertex_y->y;
1037		++travellerPtr;
1038		*travellerPtr = trianglePtr->m_vertex_y_adjacent->x;
1039		++travellerPtr;
1040		*travellerPtr = trianglePtr->m_vertex_y_adjacent->y;
1041		++travellerPtr;
1042		*travellerPtr = trianglePtr->m_vertex_z->x;
1043		++travellerPtr;
1044		*travellerPtr = trianglePtr->m_vertex_z->y;
1045		++travellerPtr;
1046		*travellerPtr = trianglePtr->m_vertex_z_adjacent->x;
1047		++travellerPtr;
1048		*travellerPtr = trianglePtr->m_vertex_z_adjacent->y;
1049		++travellerPtr;
1050
1051		*travellerExpectedAdjacencyGeometryPtr = trianglePtr->m_vertex_x_adjacent->x;
1052		++travellerExpectedAdjacencyGeometryPtr;
1053		*travellerExpectedAdjacencyGeometryPtr = trianglePtr->m_vertex_x_adjacent->y;
1054		++travellerExpectedAdjacencyGeometryPtr;
1055		*travellerExpectedAdjacencyGeometryPtr = 0;
1056		++travellerExpectedAdjacencyGeometryPtr;
1057		*travellerExpectedAdjacencyGeometryPtr = 1;
1058		++travellerExpectedAdjacencyGeometryPtr;
1059		*travellerExpectedAdjacencyGeometryPtr = trianglePtr->m_vertex_y_adjacent->x;
1060		++travellerExpectedAdjacencyGeometryPtr;
1061		*travellerExpectedAdjacencyGeometryPtr = trianglePtr->m_vertex_y_adjacent->y;
1062		++travellerExpectedAdjacencyGeometryPtr;
1063		*travellerExpectedAdjacencyGeometryPtr = 0;
1064		++travellerExpectedAdjacencyGeometryPtr;
1065		*travellerExpectedAdjacencyGeometryPtr = 1;
1066		++travellerExpectedAdjacencyGeometryPtr;
1067		*travellerExpectedAdjacencyGeometryPtr = trianglePtr->m_vertex_z_adjacent->x;
1068		++travellerExpectedAdjacencyGeometryPtr;
1069		*travellerExpectedAdjacencyGeometryPtr = trianglePtr->m_vertex_z_adjacent->y;
1070		++travellerExpectedAdjacencyGeometryPtr;
1071		*travellerExpectedAdjacencyGeometryPtr = 0;
1072		++travellerExpectedAdjacencyGeometryPtr;
1073		*travellerExpectedAdjacencyGeometryPtr = 1;
1074		++travellerExpectedAdjacencyGeometryPtr;
1075
1076		*travellerExpectedGeometryPtr = trianglePtr->m_vertex_x->x;
1077		++travellerExpectedGeometryPtr;
1078		*travellerExpectedGeometryPtr = trianglePtr->m_vertex_x->y;
1079		++travellerExpectedGeometryPtr;
1080		*travellerExpectedGeometryPtr = 0;
1081		++travellerExpectedGeometryPtr;
1082		*travellerExpectedGeometryPtr = 1;
1083		++travellerExpectedGeometryPtr;
1084		*travellerExpectedGeometryPtr = trianglePtr->m_vertex_y->x;
1085		++travellerExpectedGeometryPtr;
1086		*travellerExpectedGeometryPtr = trianglePtr->m_vertex_y->y;
1087		++travellerExpectedGeometryPtr;
1088		*travellerExpectedGeometryPtr = 0;
1089		++travellerExpectedGeometryPtr;
1090		*travellerExpectedGeometryPtr = 1;
1091		++travellerExpectedGeometryPtr;
1092		*travellerExpectedGeometryPtr = trianglePtr->m_vertex_z->x;
1093		++travellerExpectedGeometryPtr;
1094		*travellerExpectedGeometryPtr = trianglePtr->m_vertex_z->y;
1095		++travellerExpectedGeometryPtr;
1096		*travellerExpectedGeometryPtr = 0;
1097		++travellerExpectedGeometryPtr;
1098		*travellerExpectedGeometryPtr = 1;
1099		++travellerExpectedGeometryPtr;
1100	} /* for (all triangles) */
1101}
1102
1103/** Set triangle vertex data used to be used by indiced draw calls.
1104 *
1105 * @param test_data AdjacencyTestDatainstance to be filled with relevant data.
1106 **/
1107void GeometryShaderAdjacencyTests::setTrianglePointsIndiced(AdjacencyTestData& test_data)
1108{
1109	float*		  travellerExpectedAdjacencyGeometryPtr = 0;
1110	float*		  travellerExpectedGeometryPtr			= 0;
1111	unsigned int* travellerIndicesPtr					= 0;
1112	float*		  travellerPtr							= 0;
1113
1114	/* Set buffer sizes */
1115	test_data.m_n_vertices		 = test_data.m_grid->m_n_triangles * m_n_vertices_per_triangle;
1116	test_data.m_geometry_bo_size = static_cast<glw::GLuint>(
1117		test_data.m_grid->m_n_triangles * m_n_vertices_per_triangle * m_n_components_output * sizeof(float));
1118	test_data.m_vertex_data_bo_size =
1119		static_cast<glw::GLuint>(test_data.m_grid->m_n_points * m_n_components_input * sizeof(float));
1120	test_data.m_index_data_bo_size =
1121		static_cast<glw::GLuint>(test_data.m_n_vertices * sizeof(unsigned int) * 2); /* include adjacency info */
1122
1123	/* Allocate memory for input and expected data */
1124	test_data.m_expected_adjacency_geometry = new float[test_data.m_geometry_bo_size / sizeof(float)];
1125	test_data.m_expected_geometry			= new float[test_data.m_geometry_bo_size / sizeof(float)];
1126	test_data.m_index_data					= new unsigned int[test_data.m_index_data_bo_size / sizeof(unsigned int)];
1127	test_data.m_vertex_data					= new float[test_data.m_vertex_data_bo_size / sizeof(float)];
1128
1129	travellerExpectedAdjacencyGeometryPtr = test_data.m_expected_adjacency_geometry;
1130	travellerExpectedGeometryPtr		  = test_data.m_expected_geometry;
1131	travellerPtr						  = test_data.m_vertex_data;
1132	travellerIndicesPtr					  = test_data.m_index_data;
1133
1134	/* Set input and expected values */
1135	for (unsigned int n = 0; n < test_data.m_grid->m_n_points; ++n)
1136	{
1137		*travellerPtr = test_data.m_grid->m_points[n].x;
1138		++travellerPtr;
1139		*travellerPtr = test_data.m_grid->m_points[n].y;
1140		++travellerPtr;
1141	}
1142
1143	for (unsigned int n = 0; n < test_data.m_grid->m_n_triangles; ++n)
1144	{
1145		AdjacencyGridTriangle* trianglePtr = test_data.m_grid->m_triangles + (n + 1) % 2;
1146
1147		*travellerIndicesPtr = trianglePtr->m_vertex_x->index;
1148		++travellerIndicesPtr;
1149		*travellerIndicesPtr = trianglePtr->m_vertex_x_adjacent->index;
1150		++travellerIndicesPtr;
1151		*travellerIndicesPtr = trianglePtr->m_vertex_y->index;
1152		++travellerIndicesPtr;
1153		*travellerIndicesPtr = trianglePtr->m_vertex_y_adjacent->index;
1154		++travellerIndicesPtr;
1155		*travellerIndicesPtr = trianglePtr->m_vertex_z->index;
1156		++travellerIndicesPtr;
1157		*travellerIndicesPtr = trianglePtr->m_vertex_z_adjacent->index;
1158		++travellerIndicesPtr;
1159
1160		*travellerExpectedAdjacencyGeometryPtr = trianglePtr->m_vertex_x_adjacent->x;
1161		++travellerExpectedAdjacencyGeometryPtr;
1162		*travellerExpectedAdjacencyGeometryPtr = trianglePtr->m_vertex_x_adjacent->y;
1163		++travellerExpectedAdjacencyGeometryPtr;
1164		*travellerExpectedAdjacencyGeometryPtr = 0;
1165		++travellerExpectedAdjacencyGeometryPtr;
1166		*travellerExpectedAdjacencyGeometryPtr = 1;
1167		++travellerExpectedAdjacencyGeometryPtr;
1168		*travellerExpectedAdjacencyGeometryPtr = trianglePtr->m_vertex_y_adjacent->x;
1169		++travellerExpectedAdjacencyGeometryPtr;
1170		*travellerExpectedAdjacencyGeometryPtr = trianglePtr->m_vertex_y_adjacent->y;
1171		++travellerExpectedAdjacencyGeometryPtr;
1172		*travellerExpectedAdjacencyGeometryPtr = 0;
1173		++travellerExpectedAdjacencyGeometryPtr;
1174		*travellerExpectedAdjacencyGeometryPtr = 1;
1175		++travellerExpectedAdjacencyGeometryPtr;
1176		*travellerExpectedAdjacencyGeometryPtr = trianglePtr->m_vertex_z_adjacent->x;
1177		++travellerExpectedAdjacencyGeometryPtr;
1178		*travellerExpectedAdjacencyGeometryPtr = trianglePtr->m_vertex_z_adjacent->y;
1179		++travellerExpectedAdjacencyGeometryPtr;
1180		*travellerExpectedAdjacencyGeometryPtr = 0;
1181		++travellerExpectedAdjacencyGeometryPtr;
1182		*travellerExpectedAdjacencyGeometryPtr = 1;
1183		++travellerExpectedAdjacencyGeometryPtr;
1184
1185		*travellerExpectedGeometryPtr = trianglePtr->m_vertex_x->x;
1186		++travellerExpectedGeometryPtr;
1187		*travellerExpectedGeometryPtr = trianglePtr->m_vertex_x->y;
1188		++travellerExpectedGeometryPtr;
1189		*travellerExpectedGeometryPtr = 0;
1190		++travellerExpectedGeometryPtr;
1191		*travellerExpectedGeometryPtr = 1;
1192		++travellerExpectedGeometryPtr;
1193		*travellerExpectedGeometryPtr = trianglePtr->m_vertex_y->x;
1194		++travellerExpectedGeometryPtr;
1195		*travellerExpectedGeometryPtr = trianglePtr->m_vertex_y->y;
1196		++travellerExpectedGeometryPtr;
1197		*travellerExpectedGeometryPtr = 0;
1198		++travellerExpectedGeometryPtr;
1199		*travellerExpectedGeometryPtr = 1;
1200		++travellerExpectedGeometryPtr;
1201		*travellerExpectedGeometryPtr = trianglePtr->m_vertex_z->x;
1202		++travellerExpectedGeometryPtr;
1203		*travellerExpectedGeometryPtr = trianglePtr->m_vertex_z->y;
1204		++travellerExpectedGeometryPtr;
1205		*travellerExpectedGeometryPtr = 0;
1206		++travellerExpectedGeometryPtr;
1207		*travellerExpectedGeometryPtr = 1;
1208		++travellerExpectedGeometryPtr;
1209	} /* For (all triangles) */
1210}
1211
1212/** Set triangle strip vertex data used to be used by non-indiced draw calls.
1213 *
1214 * @param test_data AdjacencyTestData instance to be filled with relevant data.
1215 **/
1216void GeometryShaderAdjacencyTests::setTriangleStripPointsNonindiced(AdjacencyTestData& test_data)
1217{
1218	/* Generate ordered vertex GL_TRIANGLE_STRIP_ADJACENCY_EXT data for actual test.
1219	 *
1220	 * "In triangle strips with adjacency, n triangles are drawn where there are
1221	 *  2 * (n+2) + k vertices passed. k is either 0 or 1; if k is 1, the final
1222	 *  vertex is ignored. "
1223	 *
1224	 * implies: for k input vertices, floor((n - 4) / 2) triangles will be drawn.
1225	 */
1226	unsigned int nTriangles = (test_data.m_grid->m_triangle_strip.m_n_points - 4) / 2;
1227
1228	float* travellerExpectedAdjacencyGeometryPtr = 0;
1229	float* travellerExpectedGeometryPtr			 = 0;
1230	float* travellerPtr							 = 0;
1231
1232	/* Set buffer sizes */
1233	test_data.m_n_vertices = test_data.m_grid->m_triangle_strip.m_n_points;
1234	test_data.m_geometry_bo_size =
1235		static_cast<glw::GLuint>(nTriangles * m_n_components_output * 3 /* adjacent vertices */ * sizeof(float));
1236	test_data.m_vertex_data_bo_size =
1237		static_cast<glw::GLuint>(test_data.m_n_vertices * m_n_components_input * sizeof(float));
1238
1239	/* Allocate memory for input and expected data */
1240	test_data.m_expected_adjacency_geometry           = new float[test_data.m_geometry_bo_size / sizeof(float)];
1241	test_data.m_expected_geometry			          = new float[test_data.m_geometry_bo_size / sizeof(float)];
1242	test_data.m_alternate_expected_adjacency_geometry = new float[test_data.m_geometry_bo_size / sizeof(float)];
1243	test_data.m_alternate_expected_geometry			  = new float[test_data.m_geometry_bo_size / sizeof(float)];
1244	test_data.m_vertex_data					          = new float[test_data.m_vertex_data_bo_size / sizeof(float)];
1245
1246	travellerPtr						  = test_data.m_vertex_data;
1247
1248	/* Set input and expected values */
1249	for (unsigned int n = 0; n < test_data.m_n_vertices; ++n)
1250	{
1251		*travellerPtr = test_data.m_grid->m_triangle_strip.m_points[n].x;
1252		++travellerPtr;
1253		*travellerPtr = test_data.m_grid->m_triangle_strip.m_points[n].y;
1254		++travellerPtr;
1255	}
1256
1257	for (unsigned int j = 0; j < 2; ++j)
1258	{
1259		if (j == 0)
1260		{
1261			travellerExpectedAdjacencyGeometryPtr = test_data.m_expected_adjacency_geometry;
1262			travellerExpectedGeometryPtr		  = test_data.m_expected_geometry;
1263		}
1264		else
1265		{
1266			travellerExpectedAdjacencyGeometryPtr = test_data.m_alternate_expected_adjacency_geometry;
1267			travellerExpectedGeometryPtr		  = test_data.m_alternate_expected_geometry;
1268		}
1269		for (unsigned int n = 0; n < nTriangles; ++n)
1270		{
1271			/* Derived from per table 2.X1 from the spec */
1272			int vertexIndex[3]				= { -1, -1, -1 };
1273			int adjVertexIndex[3]			= { -1, -1, -1 };
1274
1275			if (n == 0)
1276			{
1277				/* first (i==0) */
1278				adjVertexIndex[0] = 2;
1279				adjVertexIndex[1] = 7;
1280				adjVertexIndex[2] = 4;
1281				vertexIndex[0]	= 1;
1282				vertexIndex[1]	= 3;
1283				vertexIndex[2]	= 5;
1284			}
1285			else if (n == nTriangles - 1)
1286			{
1287				if (n % 2 == 0)
1288				{
1289					/* last (i==n-1, i even) */
1290					adjVertexIndex[0] = 2 * n - 1;
1291					adjVertexIndex[1] = 2 * n + 6;
1292					adjVertexIndex[2] = 2 * n + 4;
1293					vertexIndex[0]	= 2 * n + 1;
1294					vertexIndex[1]	= 2 * n + 3;
1295					vertexIndex[2]	= 2 * n + 5;
1296				}
1297				else
1298				{
1299					/* last (i==n-1, i odd) */
1300					if (j == 0)
1301					{
1302						adjVertexIndex[0] = 2 * n - 1;
1303						adjVertexIndex[1] = 2 * n + 4;
1304						adjVertexIndex[2] = 2 * n + 6;
1305						vertexIndex[0]	  = 2 * n + 3;
1306						vertexIndex[1]	  = 2 * n + 1;
1307						vertexIndex[2]	  = 2 * n + 5;
1308					}
1309					else
1310					{
1311						adjVertexIndex[0] = 2 * n + 4;
1312						adjVertexIndex[1] = 2 * n + 6;
1313						adjVertexIndex[2] = 2 * n - 1;
1314						vertexIndex[0]	  = 2 * n + 1;
1315						vertexIndex[1]	  = 2 * n + 5;
1316						vertexIndex[2]	  = 2 * n + 3;
1317					}
1318				}
1319			}
1320			else
1321			{
1322				if (n % 2 == 0)
1323				{
1324					/* middle (i even) */
1325					adjVertexIndex[0] = 2 * n - 1;
1326					adjVertexIndex[1] = 2 * n + 7;
1327					adjVertexIndex[2] = 2 * n + 4;
1328					vertexIndex[0]	= 2 * n + 1;
1329					vertexIndex[1]	= 2 * n + 3;
1330					vertexIndex[2]	= 2 * n + 5;
1331				}
1332				else
1333				{
1334					/* middle (i odd) */
1335					if (j == 0)
1336					{
1337
1338						adjVertexIndex[0] = 2 * n - 1;
1339						adjVertexIndex[1] = 2 * n + 4;
1340						adjVertexIndex[2] = 2 * n + 7;
1341						vertexIndex[0]	  = 2 * n + 3;
1342						vertexIndex[1]	  = 2 * n + 1;
1343						vertexIndex[2]	  = 2 * n + 5;
1344					}
1345					else
1346					{
1347						adjVertexIndex[0] = 2 * n + 4;
1348						adjVertexIndex[1] = 2 * n + 7;
1349						adjVertexIndex[2] = 2 * n - 1;
1350						vertexIndex[0]    = 2 * n + 1;
1351						vertexIndex[1]    = 2 * n + 5;
1352						vertexIndex[2]    = 2 * n + 3;
1353					}
1354				}
1355			}
1356
1357			/* Spec assumes vertices are indexed from 1 */
1358			vertexIndex[0]--;
1359			vertexIndex[1]--;
1360			vertexIndex[2]--;
1361			adjVertexIndex[0]--;
1362			adjVertexIndex[1]--;
1363			adjVertexIndex[2]--;
1364
1365			*travellerExpectedAdjacencyGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[adjVertexIndex[0]].x;
1366			++travellerExpectedAdjacencyGeometryPtr;
1367			*travellerExpectedAdjacencyGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[adjVertexIndex[0]].y;
1368			++travellerExpectedAdjacencyGeometryPtr;
1369			*travellerExpectedAdjacencyGeometryPtr = 0;
1370			++travellerExpectedAdjacencyGeometryPtr;
1371			*travellerExpectedAdjacencyGeometryPtr = 1;
1372			++travellerExpectedAdjacencyGeometryPtr;
1373			*travellerExpectedAdjacencyGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[adjVertexIndex[1]].x;
1374			++travellerExpectedAdjacencyGeometryPtr;
1375			*travellerExpectedAdjacencyGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[adjVertexIndex[1]].y;
1376			++travellerExpectedAdjacencyGeometryPtr;
1377			*travellerExpectedAdjacencyGeometryPtr = 0;
1378			++travellerExpectedAdjacencyGeometryPtr;
1379			*travellerExpectedAdjacencyGeometryPtr = 1;
1380			++travellerExpectedAdjacencyGeometryPtr;
1381			*travellerExpectedAdjacencyGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[adjVertexIndex[2]].x;
1382			++travellerExpectedAdjacencyGeometryPtr;
1383			*travellerExpectedAdjacencyGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[adjVertexIndex[2]].y;
1384			++travellerExpectedAdjacencyGeometryPtr;
1385			*travellerExpectedAdjacencyGeometryPtr = 0;
1386			++travellerExpectedAdjacencyGeometryPtr;
1387			*travellerExpectedAdjacencyGeometryPtr = 1;
1388			++travellerExpectedAdjacencyGeometryPtr;
1389
1390			*travellerExpectedGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[vertexIndex[0]].x;
1391			++travellerExpectedGeometryPtr;
1392			*travellerExpectedGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[vertexIndex[0]].y;
1393			++travellerExpectedGeometryPtr;
1394			*travellerExpectedGeometryPtr = 0;
1395			++travellerExpectedGeometryPtr;
1396			*travellerExpectedGeometryPtr = 1;
1397			++travellerExpectedGeometryPtr;
1398			*travellerExpectedGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[vertexIndex[1]].x;
1399			++travellerExpectedGeometryPtr;
1400			*travellerExpectedGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[vertexIndex[1]].y;
1401			++travellerExpectedGeometryPtr;
1402			*travellerExpectedGeometryPtr = 0;
1403			++travellerExpectedGeometryPtr;
1404			*travellerExpectedGeometryPtr = 1;
1405			++travellerExpectedGeometryPtr;
1406			*travellerExpectedGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[vertexIndex[2]].x;
1407			++travellerExpectedGeometryPtr;
1408			*travellerExpectedGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[vertexIndex[2]].y;
1409			++travellerExpectedGeometryPtr;
1410			*travellerExpectedGeometryPtr = 0;
1411			++travellerExpectedGeometryPtr;
1412			*travellerExpectedGeometryPtr = 1;
1413			++travellerExpectedGeometryPtr;
1414		} /* for (all triangles) */
1415	}
1416}
1417
1418/** Set triangle strip vertex data used to be used by indiced draw calls.
1419 *
1420 * @param test_data AdjacencyTestData instance to be filled with relevant data.
1421 **/
1422void GeometryShaderAdjacencyTests::setTriangleStripPointsIndiced(AdjacencyTestData& test_data)
1423{
1424	unsigned int nTriangles = (test_data.m_grid->m_triangle_strip.m_n_points - 4) / 2;
1425
1426	float*		  travellerExpectedAdjacencyGeometryPtr = 0;
1427	float*		  travellerExpectedGeometryPtr			= 0;
1428	unsigned int* travellerIndicesPtr					= 0;
1429	float*		  travellerPtr							= 0;
1430
1431	/* Set buffer sizes */
1432	test_data.m_n_vertices = test_data.m_grid->m_triangle_strip.m_n_points;
1433	test_data.m_geometry_bo_size =
1434		static_cast<glw::GLuint>(nTriangles * m_n_components_output * 3 /* adjacent vertices */ * sizeof(float));
1435	test_data.m_vertex_data_bo_size =
1436		static_cast<glw::GLuint>(test_data.m_n_vertices * m_n_components_input * sizeof(float));
1437	test_data.m_index_data_bo_size = static_cast<glw::GLuint>(test_data.m_n_vertices * sizeof(unsigned int));
1438
1439	/* Allocate memory for input and expected data */
1440	test_data.m_expected_adjacency_geometry           = new float[test_data.m_geometry_bo_size / sizeof(float)];
1441	test_data.m_expected_geometry			          = new float[test_data.m_geometry_bo_size / sizeof(float)];
1442	test_data.m_alternate_expected_adjacency_geometry = new float[test_data.m_geometry_bo_size / sizeof(float)];
1443	test_data.m_alternate_expected_geometry			  = new float[test_data.m_geometry_bo_size / sizeof(float)];
1444	test_data.m_index_data					          = new unsigned int[test_data.m_index_data_bo_size / sizeof(unsigned int)];
1445	test_data.m_vertex_data					          = new float[test_data.m_vertex_data_bo_size / sizeof(float)];
1446
1447	travellerIndicesPtr					  = test_data.m_index_data;
1448	travellerPtr						  = test_data.m_vertex_data;
1449
1450	/* Set input and expected values */
1451	for (unsigned int n = 0; n < test_data.m_n_vertices; ++n)
1452	{
1453		*travellerIndicesPtr = (test_data.m_n_vertices - 1) - n;
1454		++travellerIndicesPtr;
1455	}
1456
1457	for (unsigned int n = 0; n < test_data.m_n_vertices; ++n)
1458	{
1459		*travellerPtr = test_data.m_grid->m_triangle_strip.m_points[n].x;
1460		++travellerPtr;
1461		*travellerPtr = test_data.m_grid->m_triangle_strip.m_points[n].y;
1462		++travellerPtr;
1463	}
1464
1465	for (unsigned int j = 0; j < 2; ++j)
1466	{
1467		if (j == 0)
1468		{
1469			travellerExpectedAdjacencyGeometryPtr = test_data.m_expected_adjacency_geometry;
1470			travellerExpectedGeometryPtr		  = test_data.m_expected_geometry;
1471		}
1472		else
1473		{
1474			travellerExpectedAdjacencyGeometryPtr = test_data.m_alternate_expected_adjacency_geometry;
1475			travellerExpectedGeometryPtr		  = test_data.m_alternate_expected_geometry;
1476		}
1477
1478		for (unsigned int n = 0; n < nTriangles; ++n)
1479		{
1480			/* Derived from per table 2.X1 from the spec */
1481			int vertexIndex[3]	= { -1, -1, -1 };
1482			int adjVertexIndex[3] = { -1, -1, -1 };
1483
1484			if (n == 0)
1485			{
1486				/* first (i==0) */
1487				adjVertexIndex[0] = 2;
1488				adjVertexIndex[1] = 7;
1489				adjVertexIndex[2] = 4;
1490				vertexIndex[0]	= 1;
1491				vertexIndex[1]	= 3;
1492				vertexIndex[2]	= 5;
1493			}
1494			else if (n == nTriangles - 1)
1495			{
1496				if (n % 2 == 0)
1497				{
1498					/* last (i==n-1, i even) */
1499					adjVertexIndex[0] = 2 * n - 1;
1500					adjVertexIndex[1] = 2 * n + 6;
1501					adjVertexIndex[2] = 2 * n + 4;
1502					vertexIndex[0]	= 2 * n + 1;
1503					vertexIndex[1]	= 2 * n + 3;
1504					vertexIndex[2]	= 2 * n + 5;
1505				}
1506				else
1507				{
1508					/* last (i==n-1, i odd) */
1509					if (j == 0)
1510					{
1511						adjVertexIndex[0] = 2 * n - 1;
1512						adjVertexIndex[1] = 2 * n + 4;
1513						adjVertexIndex[2] = 2 * n + 6;
1514						vertexIndex[0]	  = 2 * n + 3;
1515						vertexIndex[1]	  = 2 * n + 1;
1516						vertexIndex[2]	  = 2 * n + 5;
1517					}
1518					else
1519					{
1520						adjVertexIndex[0] = 2 * n + 4;
1521						adjVertexIndex[1] = 2 * n + 6;
1522						adjVertexIndex[2] = 2 * n - 1;
1523						vertexIndex[0]	  = 2 * n + 1;
1524						vertexIndex[1]	  = 2 * n + 5;
1525						vertexIndex[2]	  = 2 * n + 3;
1526					}
1527				}
1528			}
1529			else
1530			{
1531				if (n % 2 == 0)
1532				{
1533					/* middle (i even) */
1534					adjVertexIndex[0] = 2 * n - 1;
1535					adjVertexIndex[1] = 2 * n + 7;
1536					adjVertexIndex[2] = 2 * n + 4;
1537					vertexIndex[0]	= 2 * n + 1;
1538					vertexIndex[1]	= 2 * n + 3;
1539					vertexIndex[2]	= 2 * n + 5;
1540				}
1541				else
1542				{
1543					/* middle (i odd) */
1544					if (j == 0)
1545					{
1546						adjVertexIndex[0] = 2 * n - 1;
1547						adjVertexIndex[1] = 2 * n + 4;
1548						adjVertexIndex[2] = 2 * n + 7;
1549						vertexIndex[0]	  = 2 * n + 3;
1550						vertexIndex[1]	  = 2 * n + 1;
1551						vertexIndex[2]	  = 2 * n + 5;
1552					}
1553					else
1554					{
1555						adjVertexIndex[0] = 2 * n + 4;
1556						adjVertexIndex[1] = 2 * n + 7;
1557						adjVertexIndex[2] = 2 * n - 1;
1558						vertexIndex[0]	  = 2 * n + 1;
1559						vertexIndex[1]	  = 2 * n + 5;
1560						vertexIndex[2]	  = 2 * n + 3;
1561					}
1562				}
1563			}
1564
1565			/* Spec assumes vertices are indexed from 1 */
1566			vertexIndex[0]--;
1567			vertexIndex[1]--;
1568			vertexIndex[2]--;
1569			adjVertexIndex[0]--;
1570			adjVertexIndex[1]--;
1571			adjVertexIndex[2]--;
1572
1573			*travellerExpectedAdjacencyGeometryPtr =
1574				test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[adjVertexIndex[0]]].x;
1575			++travellerExpectedAdjacencyGeometryPtr;
1576			*travellerExpectedAdjacencyGeometryPtr =
1577				test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[adjVertexIndex[0]]].y;
1578			++travellerExpectedAdjacencyGeometryPtr;
1579			*travellerExpectedAdjacencyGeometryPtr = 0;
1580			++travellerExpectedAdjacencyGeometryPtr;
1581			*travellerExpectedAdjacencyGeometryPtr = 1;
1582			++travellerExpectedAdjacencyGeometryPtr;
1583			*travellerExpectedAdjacencyGeometryPtr =
1584				test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[adjVertexIndex[1]]].x;
1585			++travellerExpectedAdjacencyGeometryPtr;
1586			*travellerExpectedAdjacencyGeometryPtr =
1587				test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[adjVertexIndex[1]]].y;
1588			++travellerExpectedAdjacencyGeometryPtr;
1589			*travellerExpectedAdjacencyGeometryPtr = 0;
1590			++travellerExpectedAdjacencyGeometryPtr;
1591			*travellerExpectedAdjacencyGeometryPtr = 1;
1592			++travellerExpectedAdjacencyGeometryPtr;
1593			*travellerExpectedAdjacencyGeometryPtr =
1594				test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[adjVertexIndex[2]]].x;
1595			++travellerExpectedAdjacencyGeometryPtr;
1596			*travellerExpectedAdjacencyGeometryPtr =
1597				test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[adjVertexIndex[2]]].y;
1598			++travellerExpectedAdjacencyGeometryPtr;
1599			*travellerExpectedAdjacencyGeometryPtr = 0;
1600			++travellerExpectedAdjacencyGeometryPtr;
1601			*travellerExpectedAdjacencyGeometryPtr = 1;
1602			++travellerExpectedAdjacencyGeometryPtr;
1603
1604			*travellerExpectedGeometryPtr =
1605				test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[vertexIndex[0]]].x;
1606			++travellerExpectedGeometryPtr;
1607			*travellerExpectedGeometryPtr =
1608				test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[vertexIndex[0]]].y;
1609			++travellerExpectedGeometryPtr;
1610			*travellerExpectedGeometryPtr = 0;
1611			++travellerExpectedGeometryPtr;
1612			*travellerExpectedGeometryPtr = 1;
1613			++travellerExpectedGeometryPtr;
1614			*travellerExpectedGeometryPtr =
1615				test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[vertexIndex[1]]].x;
1616			++travellerExpectedGeometryPtr;
1617			*travellerExpectedGeometryPtr =
1618				test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[vertexIndex[1]]].y;
1619			++travellerExpectedGeometryPtr;
1620			*travellerExpectedGeometryPtr = 0;
1621			++travellerExpectedGeometryPtr;
1622			*travellerExpectedGeometryPtr = 1;
1623			++travellerExpectedGeometryPtr;
1624			*travellerExpectedGeometryPtr =
1625				test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[vertexIndex[2]]].x;
1626			++travellerExpectedGeometryPtr;
1627			*travellerExpectedGeometryPtr =
1628				test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[vertexIndex[2]]].y;
1629			++travellerExpectedGeometryPtr;
1630			*travellerExpectedGeometryPtr = 0;
1631			++travellerExpectedGeometryPtr;
1632			*travellerExpectedGeometryPtr = 1;
1633			++travellerExpectedGeometryPtr;
1634		} /* for (all triangles) */
1635	}
1636}
1637}
1638