• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 = 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  **/
createGridTriangles(AdjacencyTestData & test_data)563 void 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  **/
createGridTriangleStrip(AdjacencyTestData & test_data)607 void 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  **/
setLinePointsNonindiced(AdjacencyTestData & test_data)664 void 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  **/
setLinePointsindiced(AdjacencyTestData & test_data)748 void 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  **/
setLineStripPointsNonindiced(AdjacencyTestData & test_data)837 void 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  **/
setLineStripPointsIndiced(AdjacencyTestData & test_data)910 void 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  **/
setTrianglePointsNonindiced(AdjacencyTestData & test_data)999 void 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  **/
setTrianglePointsIndiced(AdjacencyTestData & test_data)1107 void 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  **/
setTriangleStripPointsNonindiced(AdjacencyTestData & test_data)1216 void 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_vertex_data					= new float[test_data.m_vertex_data_bo_size / sizeof(float)];
1243 
1244 	travellerExpectedAdjacencyGeometryPtr = test_data.m_expected_adjacency_geometry;
1245 	travellerExpectedGeometryPtr		  = test_data.m_expected_geometry;
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 n = 0; n < nTriangles; ++n)
1258 	{
1259 		/* Derived from per table 2.X1 from the spec */
1260 		int vertexIndex[3]	= { -1, -1, -1 };
1261 		int adjVertexIndex[3] = { -1, -1, -1 };
1262 
1263 		if (n == 0)
1264 		{
1265 			/* first (i==0) */
1266 			adjVertexIndex[0] = 2;
1267 			adjVertexIndex[1] = 7;
1268 			adjVertexIndex[2] = 4;
1269 			vertexIndex[0]	= 1;
1270 			vertexIndex[1]	= 3;
1271 			vertexIndex[2]	= 5;
1272 		}
1273 		else if (n == nTriangles - 1)
1274 		{
1275 			if (n % 2 == 0)
1276 			{
1277 				/* last (i==n-1, i even) */
1278 				adjVertexIndex[0] = 2 * n - 1;
1279 				adjVertexIndex[1] = 2 * n + 6;
1280 				adjVertexIndex[2] = 2 * n + 4;
1281 				vertexIndex[0]	= 2 * n + 1;
1282 				vertexIndex[1]	= 2 * n + 3;
1283 				vertexIndex[2]	= 2 * n + 5;
1284 			}
1285 			else
1286 			{
1287 				/* last (i==n-1, i odd) */
1288 				adjVertexIndex[0] = 2 * n - 1;
1289 				adjVertexIndex[1] = 2 * n + 4;
1290 				adjVertexIndex[2] = 2 * n + 6;
1291 				vertexIndex[0]	= 2 * n + 3;
1292 				vertexIndex[1]	= 2 * n + 1;
1293 				vertexIndex[2]	= 2 * n + 5;
1294 			}
1295 		}
1296 		else
1297 		{
1298 			if (n % 2 == 0)
1299 			{
1300 				/* middle (i even) */
1301 				adjVertexIndex[0] = 2 * n - 1;
1302 				adjVertexIndex[1] = 2 * n + 7;
1303 				adjVertexIndex[2] = 2 * n + 4;
1304 				vertexIndex[0]	= 2 * n + 1;
1305 				vertexIndex[1]	= 2 * n + 3;
1306 				vertexIndex[2]	= 2 * n + 5;
1307 			}
1308 			else
1309 			{
1310 				/* middle (i odd) */
1311 				adjVertexIndex[0] = 2 * n - 1;
1312 				adjVertexIndex[1] = 2 * n + 4;
1313 				adjVertexIndex[2] = 2 * n + 7;
1314 				vertexIndex[0]	= 2 * n + 3;
1315 				vertexIndex[1]	= 2 * n + 1;
1316 				vertexIndex[2]	= 2 * n + 5;
1317 			}
1318 		}
1319 
1320 		/* Spec assumes vertices are indexed from 1 */
1321 		vertexIndex[0]--;
1322 		vertexIndex[1]--;
1323 		vertexIndex[2]--;
1324 		adjVertexIndex[0]--;
1325 		adjVertexIndex[1]--;
1326 		adjVertexIndex[2]--;
1327 
1328 		*travellerExpectedAdjacencyGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[adjVertexIndex[0]].x;
1329 		++travellerExpectedAdjacencyGeometryPtr;
1330 		*travellerExpectedAdjacencyGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[adjVertexIndex[0]].y;
1331 		++travellerExpectedAdjacencyGeometryPtr;
1332 		*travellerExpectedAdjacencyGeometryPtr = 0;
1333 		++travellerExpectedAdjacencyGeometryPtr;
1334 		*travellerExpectedAdjacencyGeometryPtr = 1;
1335 		++travellerExpectedAdjacencyGeometryPtr;
1336 		*travellerExpectedAdjacencyGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[adjVertexIndex[1]].x;
1337 		++travellerExpectedAdjacencyGeometryPtr;
1338 		*travellerExpectedAdjacencyGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[adjVertexIndex[1]].y;
1339 		++travellerExpectedAdjacencyGeometryPtr;
1340 		*travellerExpectedAdjacencyGeometryPtr = 0;
1341 		++travellerExpectedAdjacencyGeometryPtr;
1342 		*travellerExpectedAdjacencyGeometryPtr = 1;
1343 		++travellerExpectedAdjacencyGeometryPtr;
1344 		*travellerExpectedAdjacencyGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[adjVertexIndex[2]].x;
1345 		++travellerExpectedAdjacencyGeometryPtr;
1346 		*travellerExpectedAdjacencyGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[adjVertexIndex[2]].y;
1347 		++travellerExpectedAdjacencyGeometryPtr;
1348 		*travellerExpectedAdjacencyGeometryPtr = 0;
1349 		++travellerExpectedAdjacencyGeometryPtr;
1350 		*travellerExpectedAdjacencyGeometryPtr = 1;
1351 		++travellerExpectedAdjacencyGeometryPtr;
1352 
1353 		*travellerExpectedGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[vertexIndex[0]].x;
1354 		++travellerExpectedGeometryPtr;
1355 		*travellerExpectedGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[vertexIndex[0]].y;
1356 		++travellerExpectedGeometryPtr;
1357 		*travellerExpectedGeometryPtr = 0;
1358 		++travellerExpectedGeometryPtr;
1359 		*travellerExpectedGeometryPtr = 1;
1360 		++travellerExpectedGeometryPtr;
1361 		*travellerExpectedGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[vertexIndex[1]].x;
1362 		++travellerExpectedGeometryPtr;
1363 		*travellerExpectedGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[vertexIndex[1]].y;
1364 		++travellerExpectedGeometryPtr;
1365 		*travellerExpectedGeometryPtr = 0;
1366 		++travellerExpectedGeometryPtr;
1367 		*travellerExpectedGeometryPtr = 1;
1368 		++travellerExpectedGeometryPtr;
1369 		*travellerExpectedGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[vertexIndex[2]].x;
1370 		++travellerExpectedGeometryPtr;
1371 		*travellerExpectedGeometryPtr = test_data.m_grid->m_triangle_strip.m_points[vertexIndex[2]].y;
1372 		++travellerExpectedGeometryPtr;
1373 		*travellerExpectedGeometryPtr = 0;
1374 		++travellerExpectedGeometryPtr;
1375 		*travellerExpectedGeometryPtr = 1;
1376 		++travellerExpectedGeometryPtr;
1377 	} /* for (all triangles) */
1378 }
1379 
1380 /** Set triangle strip vertex data used to be used by indiced draw calls.
1381  *
1382  * @param test_data AdjacencyTestData instance to be filled with relevant data.
1383  **/
setTriangleStripPointsIndiced(AdjacencyTestData & test_data)1384 void GeometryShaderAdjacencyTests::setTriangleStripPointsIndiced(AdjacencyTestData& test_data)
1385 {
1386 	unsigned int nTriangles = (test_data.m_grid->m_triangle_strip.m_n_points - 4) / 2;
1387 
1388 	float*		  travellerExpectedAdjacencyGeometryPtr = 0;
1389 	float*		  travellerExpectedGeometryPtr			= 0;
1390 	unsigned int* travellerIndicesPtr					= 0;
1391 	float*		  travellerPtr							= 0;
1392 
1393 	/* Set buffer sizes */
1394 	test_data.m_n_vertices = test_data.m_grid->m_triangle_strip.m_n_points;
1395 	test_data.m_geometry_bo_size =
1396 		static_cast<glw::GLuint>(nTriangles * m_n_components_output * 3 /* adjacent vertices */ * sizeof(float));
1397 	test_data.m_vertex_data_bo_size =
1398 		static_cast<glw::GLuint>(test_data.m_n_vertices * m_n_components_input * sizeof(float));
1399 	test_data.m_index_data_bo_size = static_cast<glw::GLuint>(test_data.m_n_vertices * sizeof(unsigned int));
1400 
1401 	/* Allocate memory for input and expected data */
1402 	test_data.m_expected_adjacency_geometry = new float[test_data.m_geometry_bo_size / sizeof(float)];
1403 	test_data.m_expected_geometry			= new float[test_data.m_geometry_bo_size / sizeof(float)];
1404 	test_data.m_index_data					= new unsigned int[test_data.m_index_data_bo_size / sizeof(unsigned int)];
1405 	test_data.m_vertex_data					= new float[test_data.m_vertex_data_bo_size / sizeof(float)];
1406 
1407 	travellerExpectedAdjacencyGeometryPtr = test_data.m_expected_adjacency_geometry;
1408 	travellerExpectedGeometryPtr		  = test_data.m_expected_geometry;
1409 	travellerIndicesPtr					  = test_data.m_index_data;
1410 	travellerPtr						  = test_data.m_vertex_data;
1411 
1412 	/* Set input and expected values */
1413 	for (unsigned int n = 0; n < test_data.m_n_vertices; ++n)
1414 	{
1415 		*travellerIndicesPtr = (test_data.m_n_vertices - 1) - n;
1416 		++travellerIndicesPtr;
1417 	}
1418 
1419 	for (unsigned int n = 0; n < test_data.m_n_vertices; ++n)
1420 	{
1421 		*travellerPtr = test_data.m_grid->m_triangle_strip.m_points[n].x;
1422 		++travellerPtr;
1423 		*travellerPtr = test_data.m_grid->m_triangle_strip.m_points[n].y;
1424 		++travellerPtr;
1425 	}
1426 
1427 	for (unsigned int n = 0; n < nTriangles; ++n)
1428 	{
1429 		/* Derived from per table 2.X1 from the spec */
1430 		int vertexIndex[3]	= { -1, -1, -1 };
1431 		int adjVertexIndex[3] = { -1, -1, -1 };
1432 
1433 		if (n == 0)
1434 		{
1435 			/* first (i==0) */
1436 			adjVertexIndex[0] = 2;
1437 			adjVertexIndex[1] = 7;
1438 			adjVertexIndex[2] = 4;
1439 			vertexIndex[0]	= 1;
1440 			vertexIndex[1]	= 3;
1441 			vertexIndex[2]	= 5;
1442 		}
1443 		else if (n == nTriangles - 1)
1444 		{
1445 			if (n % 2 == 0)
1446 			{
1447 				/* last (i==n-1, i even) */
1448 				adjVertexIndex[0] = 2 * n - 1;
1449 				adjVertexIndex[1] = 2 * n + 6;
1450 				adjVertexIndex[2] = 2 * n + 4;
1451 				vertexIndex[0]	= 2 * n + 1;
1452 				vertexIndex[1]	= 2 * n + 3;
1453 				vertexIndex[2]	= 2 * n + 5;
1454 			}
1455 			else
1456 			{
1457 				/* last (i==n-1, i odd) */
1458 				adjVertexIndex[0] = 2 * n - 1;
1459 				adjVertexIndex[1] = 2 * n + 4;
1460 				adjVertexIndex[2] = 2 * n + 6;
1461 				vertexIndex[0]	= 2 * n + 3;
1462 				vertexIndex[1]	= 2 * n + 1;
1463 				vertexIndex[2]	= 2 * n + 5;
1464 			}
1465 		}
1466 		else
1467 		{
1468 			if (n % 2 == 0)
1469 			{
1470 				/* middle (i even) */
1471 				adjVertexIndex[0] = 2 * n - 1;
1472 				adjVertexIndex[1] = 2 * n + 7;
1473 				adjVertexIndex[2] = 2 * n + 4;
1474 				vertexIndex[0]	= 2 * n + 1;
1475 				vertexIndex[1]	= 2 * n + 3;
1476 				vertexIndex[2]	= 2 * n + 5;
1477 			}
1478 			else
1479 			{
1480 				/* middle (i odd) */
1481 				adjVertexIndex[0] = 2 * n - 1;
1482 				adjVertexIndex[1] = 2 * n + 4;
1483 				adjVertexIndex[2] = 2 * n + 7;
1484 				vertexIndex[0]	= 2 * n + 3;
1485 				vertexIndex[1]	= 2 * n + 1;
1486 				vertexIndex[2]	= 2 * n + 5;
1487 			}
1488 		}
1489 
1490 		/* Spec assumes vertices are indexed from 1 */
1491 		vertexIndex[0]--;
1492 		vertexIndex[1]--;
1493 		vertexIndex[2]--;
1494 		adjVertexIndex[0]--;
1495 		adjVertexIndex[1]--;
1496 		adjVertexIndex[2]--;
1497 
1498 		*travellerExpectedAdjacencyGeometryPtr =
1499 			test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[adjVertexIndex[0]]].x;
1500 		++travellerExpectedAdjacencyGeometryPtr;
1501 		*travellerExpectedAdjacencyGeometryPtr =
1502 			test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[adjVertexIndex[0]]].y;
1503 		++travellerExpectedAdjacencyGeometryPtr;
1504 		*travellerExpectedAdjacencyGeometryPtr = 0;
1505 		++travellerExpectedAdjacencyGeometryPtr;
1506 		*travellerExpectedAdjacencyGeometryPtr = 1;
1507 		++travellerExpectedAdjacencyGeometryPtr;
1508 		*travellerExpectedAdjacencyGeometryPtr =
1509 			test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[adjVertexIndex[1]]].x;
1510 		++travellerExpectedAdjacencyGeometryPtr;
1511 		*travellerExpectedAdjacencyGeometryPtr =
1512 			test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[adjVertexIndex[1]]].y;
1513 		++travellerExpectedAdjacencyGeometryPtr;
1514 		*travellerExpectedAdjacencyGeometryPtr = 0;
1515 		++travellerExpectedAdjacencyGeometryPtr;
1516 		*travellerExpectedAdjacencyGeometryPtr = 1;
1517 		++travellerExpectedAdjacencyGeometryPtr;
1518 		*travellerExpectedAdjacencyGeometryPtr =
1519 			test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[adjVertexIndex[2]]].x;
1520 		++travellerExpectedAdjacencyGeometryPtr;
1521 		*travellerExpectedAdjacencyGeometryPtr =
1522 			test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[adjVertexIndex[2]]].y;
1523 		++travellerExpectedAdjacencyGeometryPtr;
1524 		*travellerExpectedAdjacencyGeometryPtr = 0;
1525 		++travellerExpectedAdjacencyGeometryPtr;
1526 		*travellerExpectedAdjacencyGeometryPtr = 1;
1527 		++travellerExpectedAdjacencyGeometryPtr;
1528 
1529 		*travellerExpectedGeometryPtr =
1530 			test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[vertexIndex[0]]].x;
1531 		++travellerExpectedGeometryPtr;
1532 		*travellerExpectedGeometryPtr =
1533 			test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[vertexIndex[0]]].y;
1534 		++travellerExpectedGeometryPtr;
1535 		*travellerExpectedGeometryPtr = 0;
1536 		++travellerExpectedGeometryPtr;
1537 		*travellerExpectedGeometryPtr = 1;
1538 		++travellerExpectedGeometryPtr;
1539 		*travellerExpectedGeometryPtr =
1540 			test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[vertexIndex[1]]].x;
1541 		++travellerExpectedGeometryPtr;
1542 		*travellerExpectedGeometryPtr =
1543 			test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[vertexIndex[1]]].y;
1544 		++travellerExpectedGeometryPtr;
1545 		*travellerExpectedGeometryPtr = 0;
1546 		++travellerExpectedGeometryPtr;
1547 		*travellerExpectedGeometryPtr = 1;
1548 		++travellerExpectedGeometryPtr;
1549 		*travellerExpectedGeometryPtr =
1550 			test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[vertexIndex[2]]].x;
1551 		++travellerExpectedGeometryPtr;
1552 		*travellerExpectedGeometryPtr =
1553 			test_data.m_grid->m_triangle_strip.m_points[test_data.m_index_data[vertexIndex[2]]].y;
1554 		++travellerExpectedGeometryPtr;
1555 		*travellerExpectedGeometryPtr = 0;
1556 		++travellerExpectedGeometryPtr;
1557 		*travellerExpectedGeometryPtr = 1;
1558 		++travellerExpectedGeometryPtr;
1559 	} /* for (all triangles) */
1560 }
1561 }
1562