Home | History | Annotate | Download | only in geometry_shader
      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  **/
     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  **/
     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  **/
     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  **/
    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  **/
    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  **/
    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  **/
    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  */
    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  **/
    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  **/
    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  **/
    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  **/
    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  **/
    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  **/
    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  **/
    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  **/
    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  **/
    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  **/
   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  **/
   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  **/
   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