13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 3.1 Module
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * -------------------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Drawing tests.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es31fDrawTests.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMemory.h"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuRenderTarget.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVectorUtil.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "sglrGLContext.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glsDrawTest.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluStrUtil.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluPixelTransfer.hpp"
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluCallLogWrapper.hpp"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp"
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <set>
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles31
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum TestIterationType
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TYPE_DRAW_COUNT,		// !< test with 1, 5, and 25 primitives
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TYPE_INSTANCE_COUNT,	// !< test with 1, 4, and 11 instances
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TYPE_LAST
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* s_commonVertexShaderSource =		"#version 310 es\n"
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"in highp vec4 a_position;\n"
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"void main (void)\n"
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"{\n"
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"	gl_Position = a_position;\n"
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"}\n";
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* s_commonFragmentShaderSource	=	"#version 310 es\n"
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"layout(location = 0) out highp vec4 fragColor;\n"
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"void main (void)\n"
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"{\n"
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"	fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"}\n";
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* s_colorVertexShaderSource =		"#version 310 es\n"
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"in highp vec4 a_position;\n"
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"in highp vec4 a_color;\n"
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"out highp vec4 v_color;\n"
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"void main (void)\n"
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"{\n"
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"	gl_Position = a_position;\n"
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"	v_color = a_color;\n"
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"}\n";
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* s_colorFragmentShaderSource	=	"#version 310 es\n"
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"layout(location = 0) out highp vec4 fragColor;\n"
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"in highp vec4 v_color;\n"
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"void main (void)\n"
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"{\n"
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"	fragColor = v_color;\n"
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"}\n";
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct DrawElementsCommand
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 count;
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 primCount;
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 firstIndex;
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deInt32  baseVertex;
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 reservedMustBeZero;
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
953c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_STATIC_ASSERT(5 * sizeof(deUint32) == sizeof(DrawElementsCommand)); // tight packing
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct DrawArraysCommand
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 count;
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 primCount;
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 first;
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 reservedMustBeZero;
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1043c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_STATIC_ASSERT(4 * sizeof(deUint32) == sizeof(DrawArraysCommand)); // tight packing
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Verifies image contains only yellow or greeen, or a linear combination
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// of these colors.
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool verifyImageYellowGreen (const tcu::Surface& image, tcu::TestLog& log)
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using tcu::TestLog;
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::RGBA green		(0, 255, 0, 255);
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::RGBA yellow		(255, 255, 0, 255);
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int colorThreshold	= 20;
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface error			(image.getWidth(), image.getHeight());
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool isOk					= true;
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < image.getHeight(); y++)
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < image.getWidth(); x++)
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::RGBA pixel = image.getPixel(x, y);
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool pixelOk = true;
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Any pixel with !(G ~= 255) is faulty (not a linear combinations of green and yellow)
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (de::abs(pixel.getGreen() - 255) > colorThreshold)
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			pixelOk = false;
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Any pixel with !(B ~= 0) is faulty (not a linear combinations of green and yellow)
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (de::abs(pixel.getBlue() - 0) > colorThreshold)
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			pixelOk = false;
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		error.setPixel(x, y, (pixelOk) ? (tcu::RGBA(0, 255, 0, 255)) : (tcu::RGBA(255, 0, 0, 255)));
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		isOk = isOk && pixelOk;
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!isOk)
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Image verification failed." << TestLog::EndMessage;
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::ImageSet("Verfication result", "Result of rendering")
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::Image("Result",		"Result",		image)
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::Image("ErrorMask",	"Error mask",	error)
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::EndImageSet;
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::ImageSet("Verfication result", "Result of rendering")
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::Image("Result", "Result", image)
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::EndImageSet;
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return isOk;
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void addTestIterations (gls::DrawTest* test, gls::DrawTestSpec& spec, TestIterationType type)
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (type == TYPE_DRAW_COUNT)
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.primitiveCount = 1;
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		test->addIteration(spec, "draw count = 1");
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.primitiveCount = 5;
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		test->addIteration(spec, "draw count = 5");
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.primitiveCount = 25;
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		test->addIteration(spec, "draw count = 25");
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (type == TYPE_INSTANCE_COUNT)
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.instanceCount = 1;
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		test->addIteration(spec, "instance count = 1");
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.instanceCount = 4;
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		test->addIteration(spec, "instance count = 4");
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.instanceCount = 11;
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		test->addIteration(spec, "instance count = 11");
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(false);
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void genBasicSpec (gls::DrawTestSpec& spec, gls::DrawTestSpec::DrawMethod method)
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.apiType							= glu::ApiType::es(3,1);
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.primitive							= gls::DrawTestSpec::PRIMITIVE_TRIANGLES;
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.primitiveCount						= 5;
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.drawMethod							= method;
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.indexType							= gls::DrawTestSpec::INDEXTYPE_LAST;
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.indexPointerOffset					= 0;
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.indexStorage						= gls::DrawTestSpec::STORAGE_LAST;
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.first								= 0;
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.indexMin							= 0;
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.indexMax							= 0;
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.instanceCount						= 1;
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.indirectOffset						= 0;
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.attribs.resize(2);
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.attribs[0].inputType				= gls::DrawTestSpec::INPUTTYPE_FLOAT;
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.attribs[0].outputType				= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.attribs[0].storage					= gls::DrawTestSpec::STORAGE_BUFFER;
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.attribs[0].usage					= gls::DrawTestSpec::USAGE_STATIC_DRAW;
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.attribs[0].componentCount			= 4;
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.attribs[0].offset					= 0;
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.attribs[0].stride					= 0;
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.attribs[0].normalize				= false;
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.attribs[0].instanceDivisor			= 0;
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.attribs[0].useDefaultAttribute		= false;
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.attribs[1].inputType				= gls::DrawTestSpec::INPUTTYPE_FLOAT;
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.attribs[1].outputType				= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.attribs[1].storage					= gls::DrawTestSpec::STORAGE_BUFFER;
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.attribs[1].usage					= gls::DrawTestSpec::USAGE_STATIC_DRAW;
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.attribs[1].componentCount			= 2;
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.attribs[1].offset					= 0;
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.attribs[1].stride					= 0;
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.attribs[1].normalize				= false;
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.attribs[1].instanceDivisor			= 0;
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.attribs[1].useDefaultAttribute		= false;
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic std::string sizeToString (int size)
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (size < 1024)
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return de::toString(size) + " byte(s)";
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (size < 1024*1024)
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return de::toString(size / 1024) + " KB";
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return de::toString(size / 1024 / 1024) + " MB";
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass AttributeGroup : public TestCaseGroup
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									AttributeGroup	(Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod, gls::DrawTestSpec::Primitive primitive, gls::DrawTestSpec::IndexType indexType, gls::DrawTestSpec::Storage indexStorage);
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									~AttributeGroup	(void);
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void							init			(void);
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gls::DrawTestSpec::DrawMethod	m_method;
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gls::DrawTestSpec::Primitive	m_primitive;
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gls::DrawTestSpec::IndexType	m_indexType;
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gls::DrawTestSpec::Storage		m_indexStorage;
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2473c827367444ee418f129b2c238299f49d3264554Jarkko PoyryAttributeGroup::AttributeGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod, gls::DrawTestSpec::Primitive primitive, gls::DrawTestSpec::IndexType indexType, gls::DrawTestSpec::Storage indexStorage)
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup		(context, name, descr)
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_method			(drawMethod)
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_primitive		(primitive)
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_indexType		(indexType)
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_indexStorage	(indexStorage)
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2563c827367444ee418f129b2c238299f49d3264554Jarkko PoyryAttributeGroup::~AttributeGroup (void)
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid AttributeGroup::init (void)
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Single attribute
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTest*		test				= new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "single_attribute", "Single attribute array.");
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec	spec;
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.apiType							= glu::ApiType::es(3,1);
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.primitive							= m_primitive;
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.primitiveCount						= 5;
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.drawMethod							= m_method;
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.indexType							= m_indexType;
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.indexPointerOffset					= 0;
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.indexStorage						= m_indexStorage;
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.first								= 0;
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.indexMin							= 0;
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.indexMax							= 0;
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.instanceCount						= 1;
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.indirectOffset						= 0;
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs.resize(1);
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].inputType				= gls::DrawTestSpec::INPUTTYPE_FLOAT;
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].outputType				= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].storage					= gls::DrawTestSpec::STORAGE_BUFFER;
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].usage					= gls::DrawTestSpec::USAGE_STATIC_DRAW;
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].componentCount			= 2;
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].offset					= 0;
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].stride					= 0;
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].normalize				= false;
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].instanceDivisor			= 0;
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].useDefaultAttribute		= false;
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addTestIterations(test, spec, TYPE_DRAW_COUNT);
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		this->addChild(test);
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Multiple attribute
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTest*		test				= new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "multiple_attributes", "Multiple attribute arrays.");
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec	spec;
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.apiType							= glu::ApiType::es(3,1);
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.primitive							= m_primitive;
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.primitiveCount						= 5;
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.drawMethod							= m_method;
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.indexType							= m_indexType;
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.indexPointerOffset					= 0;
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.indexStorage						= m_indexStorage;
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.first								= 0;
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.indexMin							= 0;
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.indexMax							= 0;
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.instanceCount						= 1;
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.indirectOffset						= 0;
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs.resize(2);
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].inputType				= gls::DrawTestSpec::INPUTTYPE_FLOAT;
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].outputType				= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].storage					= gls::DrawTestSpec::STORAGE_BUFFER;
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].usage					= gls::DrawTestSpec::USAGE_STATIC_DRAW;
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].componentCount			= 4;
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].offset					= 0;
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].stride					= 0;
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].normalize				= false;
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].instanceDivisor			= 0;
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].useDefaultAttribute		= false;
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[1].inputType				= gls::DrawTestSpec::INPUTTYPE_FLOAT;
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[1].outputType				= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[1].storage					= gls::DrawTestSpec::STORAGE_BUFFER;
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[1].usage					= gls::DrawTestSpec::USAGE_STATIC_DRAW;
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[1].componentCount			= 2;
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[1].offset					= 0;
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[1].stride					= 0;
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[1].normalize				= false;
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[1].instanceDivisor			= 0;
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[1].useDefaultAttribute		= false;
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addTestIterations(test, spec, TYPE_DRAW_COUNT);
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		this->addChild(test);
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Multiple attribute, second one divided
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTest*		test					= new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "instanced_attributes", "Instanced attribute array.");
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec	spec;
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.apiType								= glu::ApiType::es(3,1);
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.primitive								= m_primitive;
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.primitiveCount							= 5;
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.drawMethod								= m_method;
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.indexType								= m_indexType;
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.indexPointerOffset						= 0;
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.indexStorage							= m_indexStorage;
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.first									= 0;
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.indexMin								= 0;
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.indexMax								= 0;
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.instanceCount							= 1;
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.indirectOffset							= 0;
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs.resize(3);
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].inputType					= gls::DrawTestSpec::INPUTTYPE_FLOAT;
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].outputType					= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].storage						= gls::DrawTestSpec::STORAGE_BUFFER;
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].usage						= gls::DrawTestSpec::USAGE_STATIC_DRAW;
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].componentCount				= 4;
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].offset						= 0;
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].stride						= 0;
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].normalize					= false;
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].instanceDivisor				= 0;
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].useDefaultAttribute			= false;
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Add another position component so the instances wont be drawn on each other
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[1].inputType					= gls::DrawTestSpec::INPUTTYPE_FLOAT;
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[1].outputType					= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[1].storage						= gls::DrawTestSpec::STORAGE_BUFFER;
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[1].usage						= gls::DrawTestSpec::USAGE_STATIC_DRAW;
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[1].componentCount				= 2;
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[1].offset						= 0;
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[1].stride						= 0;
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[1].normalize					= false;
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[1].instanceDivisor				= 1;
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[1].useDefaultAttribute			= false;
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[1].additionalPositionAttribute	= true;
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Instanced color
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[2].inputType					= gls::DrawTestSpec::INPUTTYPE_FLOAT;
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[2].outputType					= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[2].storage						= gls::DrawTestSpec::STORAGE_BUFFER;
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[2].usage						= gls::DrawTestSpec::USAGE_STATIC_DRAW;
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[2].componentCount				= 3;
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[2].offset						= 0;
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[2].stride						= 0;
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[2].normalize					= false;
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[2].instanceDivisor				= 1;
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[2].useDefaultAttribute			= false;
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addTestIterations(test, spec, TYPE_INSTANCE_COUNT);
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		this->addChild(test);
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Multiple attribute, second one default
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTest*		test				= new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "default_attribute", "Attribute specified with glVertexAttrib*.");
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec	spec;
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.apiType							= glu::ApiType::es(3,1);
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.primitive							= m_primitive;
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.primitiveCount						= 5;
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.drawMethod							= m_method;
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.indexType							= m_indexType;
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.indexPointerOffset					= 0;
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.indexStorage						= m_indexStorage;
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.first								= 0;
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.indexMin							= 0;
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.indexMax							= 0;
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.instanceCount						= 1;
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.indirectOffset						= 0;
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs.resize(2);
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].inputType				= gls::DrawTestSpec::INPUTTYPE_FLOAT;
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].outputType				= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].storage					= gls::DrawTestSpec::STORAGE_BUFFER;
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].usage					= gls::DrawTestSpec::USAGE_STATIC_DRAW;
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].componentCount			= 2;
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].offset					= 0;
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].stride					= 0;
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].normalize				= false;
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].instanceDivisor			= 0;
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.attribs[0].useDefaultAttribute		= false;
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		struct IOPair
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gls::DrawTestSpec::InputType  input;
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gls::DrawTestSpec::OutputType output;
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int							  componentCount;
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		} iopairs[] =
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ gls::DrawTestSpec::INPUTTYPE_FLOAT,        gls::DrawTestSpec::OUTPUTTYPE_VEC2,  4 },
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ gls::DrawTestSpec::INPUTTYPE_FLOAT,        gls::DrawTestSpec::OUTPUTTYPE_VEC4,  2 },
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ gls::DrawTestSpec::INPUTTYPE_INT,          gls::DrawTestSpec::OUTPUTTYPE_IVEC3, 4 },
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ gls::DrawTestSpec::INPUTTYPE_UNSIGNED_INT, gls::DrawTestSpec::OUTPUTTYPE_UVEC2, 4 },
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ioNdx = 0; ioNdx < DE_LENGTH_OF_ARRAY(iopairs); ++ioNdx)
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const std::string desc = gls::DrawTestSpec::inputTypeToString(iopairs[ioNdx].input) + de::toString(iopairs[ioNdx].componentCount) + " to " + gls::DrawTestSpec::outputTypeToString(iopairs[ioNdx].output);
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			spec.attribs[1].inputType			= iopairs[ioNdx].input;
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			spec.attribs[1].outputType			= iopairs[ioNdx].output;
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			spec.attribs[1].storage				= gls::DrawTestSpec::STORAGE_BUFFER;
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			spec.attribs[1].usage				= gls::DrawTestSpec::USAGE_STATIC_DRAW;
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			spec.attribs[1].componentCount		= iopairs[ioNdx].componentCount;
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			spec.attribs[1].offset				= 0;
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			spec.attribs[1].stride				= 0;
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			spec.attribs[1].normalize			= false;
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			spec.attribs[1].instanceDivisor		= 0;
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			spec.attribs[1].useDefaultAttribute	= true;
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			test->addIteration(spec, desc.c_str());
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		this->addChild(test);
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass IndexGroup : public TestCaseGroup
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									IndexGroup		(Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									~IndexGroup		(void);
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void							init			(void);
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gls::DrawTestSpec::DrawMethod	m_method;
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4843c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIndexGroup::IndexGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup		(context, name, descr)
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_method			(drawMethod)
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4903c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIndexGroup::~IndexGroup (void)
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid IndexGroup::init (void)
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct IndexTest
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::IndexType	type;
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int								offsets[3];
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const IndexTest tests[] =
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ gls::DrawTestSpec::INDEXTYPE_BYTE,	{ 0, 1, -1 } },
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ gls::DrawTestSpec::INDEXTYPE_SHORT,	{ 0, 2, -1 } },
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ gls::DrawTestSpec::INDEXTYPE_INT,		{ 0, 4, -1 } },
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gls::DrawTestSpec spec;
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	genBasicSpec(spec, m_method);
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.indexStorage = gls::DrawTestSpec::STORAGE_BUFFER;
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(tests); ++testNdx)
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const IndexTest&	indexTest	= tests[testNdx];
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string	name		= std::string("index_") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string	desc		= std::string("index ") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTest*		test		= new gls::DrawTest(m_testCtx, m_context.getRenderContext(), name.c_str(), desc.c_str());
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.indexType			= indexTest.type;
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int iterationNdx = 0; iterationNdx < DE_LENGTH_OF_ARRAY(indexTest.offsets) && indexTest.offsets[iterationNdx] != -1; ++iterationNdx)
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const std::string iterationDesc = std::string("first vertex ") + de::toString(indexTest.offsets[iterationNdx] / gls::DrawTestSpec::indexTypeSize(indexTest.type));
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			spec.indexPointerOffset	= indexTest.offsets[iterationNdx];
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			test->addIteration(spec, iterationDesc.c_str());
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(test);
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass BaseVertexGroup : public TestCaseGroup
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									BaseVertexGroup		(Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									~BaseVertexGroup	(void);
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void							init				(void);
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gls::DrawTestSpec::DrawMethod	m_method;
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5473c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBaseVertexGroup::BaseVertexGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup		(context, name, descr)
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_method			(drawMethod)
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5533c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBaseVertexGroup::~BaseVertexGroup (void)
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid BaseVertexGroup::init (void)
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct IndexTest
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool							positiveBase;
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::IndexType	type;
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int								baseVertex[2];
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const IndexTest tests[] =
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ true,  gls::DrawTestSpec::INDEXTYPE_BYTE,		{  1,  2 } },
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ true,  gls::DrawTestSpec::INDEXTYPE_SHORT,	{  1,  2 } },
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ true,  gls::DrawTestSpec::INDEXTYPE_INT,		{  1,  2 } },
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ false, gls::DrawTestSpec::INDEXTYPE_BYTE,		{ -1, -2 } },
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ false, gls::DrawTestSpec::INDEXTYPE_SHORT,	{ -1, -2 } },
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ false, gls::DrawTestSpec::INDEXTYPE_INT,		{ -1, -2 } },
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gls::DrawTestSpec spec;
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	genBasicSpec(spec, m_method);
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	spec.indexStorage = gls::DrawTestSpec::STORAGE_BUFFER;
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(tests); ++testNdx)
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const IndexTest&	indexTest	= tests[testNdx];
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string	name		= std::string("index_") + (indexTest.positiveBase ? "" : "neg_") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string	desc		= std::string("index ") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTest*		test		= new gls::DrawTest(m_testCtx, m_context.getRenderContext(), name.c_str(), desc.c_str());
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.indexType			= indexTest.type;
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int iterationNdx = 0; iterationNdx < DE_LENGTH_OF_ARRAY(indexTest.baseVertex); ++iterationNdx)
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const std::string iterationDesc = std::string("base vertex ") + de::toString(indexTest.baseVertex[iterationNdx]);
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			spec.baseVertex	= indexTest.baseVertex[iterationNdx];
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			test->addIteration(spec, iterationDesc.c_str());
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(test);
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass FirstGroup : public TestCaseGroup
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									FirstGroup		(Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									~FirstGroup		(void);
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void							init			(void);
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gls::DrawTestSpec::DrawMethod	m_method;
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6143c827367444ee418f129b2c238299f49d3264554Jarkko PoyryFirstGroup::FirstGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup		(context, name, descr)
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_method			(drawMethod)
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6203c827367444ee418f129b2c238299f49d3264554Jarkko PoyryFirstGroup::~FirstGroup (void)
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FirstGroup::init (void)
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int firsts[] =
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		1, 3, 17
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gls::DrawTestSpec spec;
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	genBasicSpec(spec, m_method);
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int firstNdx = 0; firstNdx < DE_LENGTH_OF_ARRAY(firsts); ++firstNdx)
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string	name = std::string("first_") + de::toString(firsts[firstNdx]);
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string	desc = std::string("first ") + de::toString(firsts[firstNdx]);
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTest*		test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), name.c_str(), desc.c_str());
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.first = firsts[firstNdx];
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addTestIterations(test, spec, TYPE_DRAW_COUNT);
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		this->addChild(test);
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass MethodGroup : public TestCaseGroup
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									MethodGroup			(Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									~MethodGroup		(void);
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void							init				(void);
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gls::DrawTestSpec::DrawMethod	m_method;
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6603c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMethodGroup::MethodGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup		(context, name, descr)
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_method			(drawMethod)
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6663c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMethodGroup::~MethodGroup (void)
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MethodGroup::init (void)
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool indexed		= (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INDIRECT);
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool hasFirst		= (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS_INDIRECT);
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const gls::DrawTestSpec::Primitive primitive[] =
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::PRIMITIVE_POINTS,
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::PRIMITIVE_TRIANGLES,
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN,
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP,
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::PRIMITIVE_LINES,
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::PRIMITIVE_LINE_STRIP,
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::PRIMITIVE_LINE_LOOP
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasFirst)
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// First-tests
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		this->addChild(new FirstGroup(m_context, "first", "First tests", m_method));
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (indexed)
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Index-tests
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		this->addChild(new IndexGroup(m_context, "indices", "Index tests", m_method));
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		this->addChild(new BaseVertexGroup(m_context, "base_vertex", "Base vertex tests", m_method));
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(primitive); ++ndx)
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string name = gls::DrawTestSpec::primitiveToString(primitive[ndx]);
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string desc = gls::DrawTestSpec::primitiveToString(primitive[ndx]);
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		this->addChild(new AttributeGroup(m_context, name.c_str(), desc.c_str(), m_method, primitive[ndx], gls::DrawTestSpec::INDEXTYPE_SHORT, gls::DrawTestSpec::STORAGE_BUFFER));
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass GridProgram : public sglr::ShaderProgram
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GridProgram		(void);
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void	shadeVertices	(const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const;
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void	shadeFragments	(rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const;
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7173c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGridProgram::GridProgram (void)
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: sglr::ShaderProgram(sglr::pdec::ShaderProgramDeclaration()
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							<< sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT)
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							<< sglr::pdec::VertexAttribute("a_offset", rr::GENERICVECTYPE_FLOAT)
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							<< sglr::pdec::VertexAttribute("a_color", rr::GENERICVECTYPE_FLOAT)
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							<< sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT)
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							<< sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT)
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							<< sglr::pdec::VertexSource("#version 310 es\n"
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														"in highp vec4 a_position;\n"
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														"in highp vec4 a_offset;\n"
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														"in highp vec4 a_color;\n"
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														"out highp vec4 v_color;\n"
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														"void main(void)\n"
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														"{\n"
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														"	gl_Position = a_position + a_offset;\n"
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														"	v_color = a_color;\n"
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														"}\n")
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							<< sglr::pdec::FragmentSource(
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														"#version 310 es\n"
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														"layout(location = 0) out highp vec4 dEQP_FragColor;\n"
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														"in highp vec4 v_color;\n"
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														"void main(void)\n"
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														"{\n"
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														"	dEQP_FragColor = v_color;\n"
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														"}\n"))
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid GridProgram::shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < numPackets; ++ndx)
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		packets[ndx]->position = rr::readVertexAttribFloat(inputs[0], packets[ndx]->instanceNdx, packets[ndx]->vertexNdx) + rr::readVertexAttribFloat(inputs[1], packets[ndx]->instanceNdx, packets[ndx]->vertexNdx);
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		packets[ndx]->outputs[0] = rr::readVertexAttribFloat(inputs[2], packets[ndx]->instanceNdx, packets[ndx]->vertexNdx);
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid GridProgram::shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, rr::readTriangleVarying<float>(packets[packetNdx], context, 0, fragNdx));
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass InstancedGridRenderTest : public TestCase
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					InstancedGridRenderTest		(Context& context, const char* name, const char* desc, int gridSide, bool useIndices);
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					~InstancedGridRenderTest	(void);
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult	iterate						(void);
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void			renderTo					(sglr::Context& ctx, sglr::ShaderProgram& program, tcu::Surface& dst);
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		m_gridSide;
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		m_useIndices;
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7763c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInstancedGridRenderTest::InstancedGridRenderTest (Context& context, const char* name, const char* desc, int gridSide, bool useIndices)
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase		(context, name, desc)
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_gridSide	(gridSide)
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_useIndices	(useIndices)
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7833c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInstancedGridRenderTest::~InstancedGridRenderTest (void)
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7873c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInstancedGridRenderTest::IterateResult InstancedGridRenderTest::iterate (void)
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int renderTargetWidth  = de::min(1024, m_context.getRenderTarget().getWidth());
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int renderTargetHeight = de::min(1024, m_context.getRenderTarget().getHeight());
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sglr::GLContext ctx		(m_context.getRenderContext(), m_testCtx.getLog(), sglr::GLCONTEXT_LOG_CALLS | sglr::GLCONTEXT_LOG_PROGRAMS, tcu::IVec4(0, 0, renderTargetWidth, renderTargetHeight));
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface	surface	(renderTargetWidth, renderTargetHeight);
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GridProgram		program;
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// render
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	renderTo(ctx, program, surface);
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// verify image
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note the green/yellow pattern is only for clarity. The test will only verify that all instances were drawn by looking for anything non-green/yellow.
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (verifyImageYellowGreen(surface, m_testCtx.getLog()))
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result image invalid");
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid InstancedGridRenderTest::renderTo (sglr::Context& ctx, sglr::ShaderProgram& program, tcu::Surface& dst)
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4 green	(0, 1, 0, 1);
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4 yellow	(1, 1, 0, 1);
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 vaoID			= 0;
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 positionBuf	= 0;
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 offsetBuf		= 0;
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 colorBuf		= 0;
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 indexBuf		= 0;
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 drawIndirectBuf= 0;
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 programID		= ctx.createProgram(&program);
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deInt32 posLocation		= ctx.getAttribLocation(programID, "a_position");
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deInt32 offsetLocation	= ctx.getAttribLocation(programID, "a_offset");
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deInt32 colorLocation	= ctx.getAttribLocation(programID, "a_color");
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float cellW	= 2.0f / m_gridSide;
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float cellH	= 2.0f / m_gridSide;
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4 vertexPositions[] =
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4(0,		0,		0, 1),
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4(cellW,	0,		0, 1),
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4(0,		cellH,	0, 1),
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4(0,		cellH,	0, 1),
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4(cellW,	0,		0, 1),
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4(cellW,	cellH,	0, 1),
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint16 indices[] =
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		0, 4, 3,
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		2, 1, 5
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<tcu::Vec4> offsets;
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < m_gridSide; ++x)
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < m_gridSide; ++y)
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		offsets.push_back(tcu::Vec4(x * cellW - 1.0f, y * cellW - 1.0f, 0, 0));
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<tcu::Vec4> colors;
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < m_gridSide; ++x)
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < m_gridSide; ++y)
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		colors.push_back(((x + y) % 2 == 0) ? (green) : (yellow));
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.genVertexArrays(1, &vaoID);
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.bindVertexArray(vaoID);
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.genBuffers(1, &positionBuf);
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.bindBuffer(GL_ARRAY_BUFFER, positionBuf);
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.bufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.vertexAttribDivisor(posLocation, 0);
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.enableVertexAttribArray(posLocation);
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.genBuffers(1, &offsetBuf);
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.bindBuffer(GL_ARRAY_BUFFER, offsetBuf);
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.bufferData(GL_ARRAY_BUFFER, offsets.size() * sizeof(tcu::Vec4), &offsets[0], GL_STATIC_DRAW);
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.vertexAttribPointer(offsetLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.vertexAttribDivisor(offsetLocation, 1);
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.enableVertexAttribArray(offsetLocation);
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.genBuffers(1, &colorBuf);
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.bindBuffer(GL_ARRAY_BUFFER, colorBuf);
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.bufferData(GL_ARRAY_BUFFER, colors.size() * sizeof(tcu::Vec4), &colors[0], GL_STATIC_DRAW);
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.vertexAttribPointer(colorLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.vertexAttribDivisor(colorLocation, 1);
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.enableVertexAttribArray(colorLocation);
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_useIndices)
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ctx.genBuffers(1, &indexBuf);
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ctx.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuf);
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ctx.bufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.genBuffers(1, &drawIndirectBuf);
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.bindBuffer(GL_DRAW_INDIRECT_BUFFER, drawIndirectBuf);
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_useIndices)
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DrawElementsCommand command;
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		command.count				= 6;
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		command.primCount			= m_gridSide * m_gridSide;
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		command.firstIndex			= 0;
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		command.baseVertex			= 0;
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		command.reservedMustBeZero	= 0;
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ctx.bufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(command), &command, GL_STATIC_DRAW);
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DrawArraysCommand command;
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		command.count				= 6;
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		command.primCount			= m_gridSide * m_gridSide;
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		command.first				= 0;
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		command.reservedMustBeZero	= 0;
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ctx.bufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(command), &command, GL_STATIC_DRAW);
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.clearColor(0, 0, 0, 1);
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.clear(GL_COLOR_BUFFER_BIT);
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.viewport(0, 0, dst.getWidth(), dst.getHeight());
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.useProgram(programID);
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_useIndices)
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ctx.drawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, DE_NULL);
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ctx.drawArraysIndirect(GL_TRIANGLES, DE_NULL);
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.useProgram(0);
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::checkError(ctx.getError(), "", __FILE__, __LINE__);
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.deleteBuffers(1, &drawIndirectBuf);
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_useIndices)
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ctx.deleteBuffers(1, &indexBuf);
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.deleteBuffers(1, &colorBuf);
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.deleteBuffers(1, &offsetBuf);
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.deleteBuffers(1, &positionBuf);
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.deleteVertexArrays(1, &vaoID);
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.deleteProgram(programID);
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.finish();
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.readPixels(dst, 0, 0, dst.getWidth(), dst.getHeight());
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::checkError(ctx.getError(), "", __FILE__, __LINE__);
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass InstancingGroup : public TestCaseGroup
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			InstancingGroup		(Context& context, const char* name, const char* descr);
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			~InstancingGroup	(void);
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void	init				(void);
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9483c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInstancingGroup::InstancingGroup (Context& context, const char* name, const char* descr)
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup	(context, name, descr)
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9533c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInstancingGroup::~InstancingGroup (void)
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid InstancingGroup::init (void)
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int gridWidths[] =
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		2,
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		5,
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		10,
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		32,
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		100,
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// drawArrays
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(gridWidths); ++ndx)
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string name = std::string("draw_arrays_indirect_grid_") + de::toString(gridWidths[ndx]) + "x" + de::toString(gridWidths[ndx]);
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string desc = std::string("DrawArraysIndirect, Grid size ") + de::toString(gridWidths[ndx]) + "x" + de::toString(gridWidths[ndx]);
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		this->addChild(new InstancedGridRenderTest(m_context, name.c_str(), desc.c_str(), gridWidths[ndx], false));
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// drawElements
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(gridWidths); ++ndx)
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string name = std::string("draw_elements_indirect_grid_") + de::toString(gridWidths[ndx]) + "x" + de::toString(gridWidths[ndx]);
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const std::string desc = std::string("DrawElementsIndirect, Grid size ") + de::toString(gridWidths[ndx]) + "x" + de::toString(gridWidths[ndx]);
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		this->addChild(new InstancedGridRenderTest(m_context, name.c_str(), desc.c_str(), gridWidths[ndx], true));
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ComputeShaderGeneratedCase : public TestCase
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum DrawMethod
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DRAWMETHOD_DRAWARRAYS,
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DRAWMETHOD_DRAWELEMENTS,
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DRAWMETHOD_LAST
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						ComputeShaderGeneratedCase	(Context& context, const char* name, const char* desc, DrawMethod method, bool computeCmd, bool computeData, bool computeIndices, int gridSize, int drawCallCount);
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						~ComputeShaderGeneratedCase	(void);
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				init						(void);
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				deinit						(void);
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult		iterate						(void);
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string			genComputeSource			(bool computeCmd, bool computeData, bool computeIndices) const;
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				createDrawCommand			(void);
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				createDrawData				(void);
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				createDrawIndices			(void);
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void		runComputeShader			(void) = 0;
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				renderTo					(tcu::Surface& image);
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32			calcDrawBufferSize			(void) const;
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32			calcIndexBufferSize			(void) const;
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const DrawMethod	m_drawMethod;
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool			m_computeCmd;
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool			m_computeData;
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool			m_computeIndices;
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int			m_commandSize;
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int			m_numDrawCmds;
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int			m_gridSize;
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glw::GLuint			m_cmdBufferID;
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glw::GLuint			m_dataBufferID;
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glw::GLuint			m_indexBufferID;
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::ShaderProgram*	m_shaderProgram;
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10333c827367444ee418f129b2c238299f49d3264554Jarkko PoyryComputeShaderGeneratedCase::ComputeShaderGeneratedCase (Context& context, const char* name, const char* desc, DrawMethod method, bool computeCmd, bool computeData, bool computeIndices, int gridSize, int drawCallCount)
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase			(context, name, desc)
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_drawMethod		(method)
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_computeCmd		(computeCmd)
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_computeData		(computeData)
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_computeIndices	(computeIndices)
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_commandSize		((method==DRAWMETHOD_DRAWARRAYS) ? (sizeof(DrawArraysCommand)) : (sizeof(DrawElementsCommand)))
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numDrawCmds		(drawCallCount)
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_gridSize		(gridSize)
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_cmdBufferID		(0)
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_dataBufferID	(0)
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_indexBufferID	(0)
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_shaderProgram	(DE_NULL)
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    const int triangleCount	= m_gridSize * m_gridSize * 2;
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(method < DRAWMETHOD_LAST);
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!computeIndices || method == DRAWMETHOD_DRAWELEMENTS);
10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(triangleCount % m_numDrawCmds == 0);
10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(triangleCount);
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10553c827367444ee418f129b2c238299f49d3264554Jarkko PoyryComputeShaderGeneratedCase::~ComputeShaderGeneratedCase (void)
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ComputeShaderGeneratedCase::init (void)
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// generate basic shader
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_shaderProgram = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(s_colorVertexShaderSource) << glu::FragmentSource(s_colorFragmentShaderSource));
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << *m_shaderProgram;
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!m_shaderProgram->isOk())
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::TestError("Failed to compile shader.");
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// gen buffers
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.genBuffers(1, &m_cmdBufferID);
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.genBuffers(1, &m_dataBufferID);
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.genBuffers(1, &m_indexBufferID);
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// check the SSBO buffers are of legal size
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1079271c2654cc44f23492888c7ef40c36c2fd810c77Jarkko Pöyry		const deUint64	drawBufferElementSize	= sizeof(tcu::Vec4);
1080271c2654cc44f23492888c7ef40c36c2fd810c77Jarkko Pöyry		const deUint64	indexBufferElementSize	= sizeof(deUint32);
1081271c2654cc44f23492888c7ef40c36c2fd810c77Jarkko Pöyry		const int		commandBufferSize		= m_commandSize * m_numDrawCmds;
1082271c2654cc44f23492888c7ef40c36c2fd810c77Jarkko Pöyry		deInt64			maxSSBOSize				= 0;
10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getInteger64v(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &maxSSBOSize);
10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1086271c2654cc44f23492888c7ef40c36c2fd810c77Jarkko Pöyry		if (m_computeData && (deUint64)calcDrawBufferSize()*drawBufferElementSize > (deUint64)maxSSBOSize)
10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError("GL_MAX_SHADER_STORAGE_BLOCK_SIZE is too small for vertex attrib buffers");
1088271c2654cc44f23492888c7ef40c36c2fd810c77Jarkko Pöyry		if (m_computeIndices && (deUint64)calcIndexBufferSize()*indexBufferElementSize > (deUint64)maxSSBOSize)
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError("GL_MAX_SHADER_STORAGE_BLOCK_SIZE is too small for index buffers");
1090271c2654cc44f23492888c7ef40c36c2fd810c77Jarkko Pöyry		if (m_computeCmd && (deUint64)commandBufferSize > (deUint64)maxSSBOSize)
10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError("GL_MAX_SHADER_STORAGE_BLOCK_SIZE is too small for command buffers");
10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ComputeShaderGeneratedCase::deinit (void)
10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_cmdBufferID)
10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_cmdBufferID);
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_cmdBufferID = 0;
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_dataBufferID)
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_dataBufferID);
11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_dataBufferID = 0;
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_indexBufferID)
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_indexBufferID);
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_indexBufferID = 0;
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_shaderProgram)
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete m_shaderProgram;
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_shaderProgram = DE_NULL;
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11203c827367444ee418f129b2c238299f49d3264554Jarkko PoyryComputeShaderGeneratedCase::IterateResult ComputeShaderGeneratedCase::iterate (void)
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				renderTargetWidth	= de::min(1024, m_context.getRenderTarget().getWidth());
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				renderTargetHeight	= de::min(1024, m_context.getRenderTarget().getHeight());
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface			surface				(renderTargetWidth, renderTargetHeight);
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << tcu::TestLog::Message << "Preparing to draw " << m_gridSize << " x " << m_gridSize << " grid." << tcu::TestLog::EndMessage;
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Gen command buffer
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!m_computeCmd)
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << tcu::TestLog::Message << "Uploading draw command buffer." << tcu::TestLog::EndMessage;
11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			createDrawCommand();
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Gen data buffer
11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!m_computeData)
11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << tcu::TestLog::Message << "Uploading draw data buffer." << tcu::TestLog::EndMessage;
11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			createDrawData();
11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Gen index buffer
11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!m_computeIndices && m_drawMethod == DRAWMETHOD_DRAWELEMENTS)
11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << tcu::TestLog::Message << "Uploading draw index buffer." << tcu::TestLog::EndMessage;
11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			createDrawIndices();
11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Run compute shader
11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog()
11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< tcu::TestLog::Message << "Filling following buffers using compute shader:\n"
11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< ((m_computeCmd)		? ("\tcommand buffer\n")	: (""))
11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< ((m_computeData)		? ("\tdata buffer\n")		: (""))
11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< ((m_computeIndices)	? ("\tindex buffer\n")		: (""))
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< tcu::TestLog::EndMessage;
11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			runComputeShader();
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Ensure data is written to the buffers before we try to read it
11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const glw::GLuint barriers = ((m_computeCmd)     ? (GL_COMMAND_BARRIER_BIT)             : (0)) |
11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										 ((m_computeData)    ? (GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT) : (0)) |
11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										 ((m_computeIndices) ? (GL_ELEMENT_ARRAY_BARRIER_BIT)       : (0));
11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << tcu::TestLog::Message << "Memory barrier. Barriers = " << glu::getMemoryBarrierFlagsStr(barriers) << tcu::TestLog::EndMessage;
11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.memoryBarrier(barriers);
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Draw from buffers
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Drawing from buffers with " << m_numDrawCmds << " draw call(s)." << tcu::TestLog::EndMessage;
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		renderTo(surface);
11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (glu::OutOfMemoryError&)
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Got GL_OUT_OF_MEMORY." << tcu::TestLog::EndMessage;
11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Got GL_OUT_OF_MEMORY");
11828d83d91e1b85fa69359aed7ea15358f770f9eb82Jarkko Pöyry		m_testCtx.setTerminateAfter(true); // Do not rely on implementation to be able to recover from OOM
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// verify image
11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note the green/yellow pattern is only for clarity. The test will only verify that all grid cells were drawn by looking for anything non-green/yellow.
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (verifyImageYellowGreen(surface, m_testCtx.getLog()))
11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result image invalid");
11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string ComputeShaderGeneratedCase::genComputeSource (bool computeCmd, bool computeData, bool computeIndices) const
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int cmdLayoutBinding				= 0;
11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int dataLayoutBinding				= (computeCmd) ? (1) : (0);
12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int indexLayoutBinding			= (computeCmd && computeData) ? (2) : (computeCmd || computeData) ? (1) : (0);
12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream buf;
12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	buf << "#version 310 es\n\n"
12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< "precision highp int;\n"
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< "precision highp float;\n\n";
12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (computeCmd && m_drawMethod==DRAWMETHOD_DRAWARRAYS)
12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf	<< "struct DrawArraysIndirectCommand {\n"
12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "    uint count;\n"
12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "    uint primCount;\n"
12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "    uint first;\n"
12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "    uint reservedMustBeZero;\n"
12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "};\n\n";
12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (computeCmd && m_drawMethod==DRAWMETHOD_DRAWELEMENTS)
12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf	<< "struct DrawElementsIndirectCommand {\n"
12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "    uint count;\n"
12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "    uint primCount;\n"
12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "    uint firstIndex;\n"
12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "    int  baseVertex;\n"
12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "    uint reservedMustBeZero;\n"
12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "};\n\n";
12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	buf << "layout(local_size_x = 1, local_size_y = 1) in;\n"
12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< "layout(std430) buffer;\n\n";
12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (computeCmd)
12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf	<< "layout(binding = " << cmdLayoutBinding << ") writeonly buffer CommandBuffer {\n"
12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "    " << ((m_drawMethod==DRAWMETHOD_DRAWARRAYS) ? ("DrawArraysIndirectCommand") : ("DrawElementsIndirectCommand")) << " commands[];\n"
12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "};\n";
12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (computeData)
12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf	<< "layout(binding = " << dataLayoutBinding << ") writeonly buffer DataBuffer {\n"
12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "    vec4 attribs[];\n"
12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "};\n";
12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (computeIndices)
12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf	<< "layout(binding = " << indexLayoutBinding << ") writeonly buffer IndexBuffer {\n"
12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "    uint indices[];\n"
12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "};\n";
12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	buf	<< "\n"
12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< "void main() {\n"
12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< "    const uint gridSize      = " << m_gridSize << "u;\n"
12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< "    const uint triangleCount = gridSize * gridSize * 2u;\n"
12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< "\n";
12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (computeCmd)
12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf	<< "    // command\n"
12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "    if (gl_GlobalInvocationID.x < " << m_numDrawCmds << "u && gl_GlobalInvocationID.y == 0u && gl_GlobalInvocationID.z == 0u) {\n"
12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "        const uint numDrawCallTris = triangleCount / " << m_numDrawCmds << "u;\n"
12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "        uint firstTri              = gl_GlobalInvocationID.x * numDrawCallTris;\n\n"
12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "        commands[gl_GlobalInvocationID.x].count                 = numDrawCallTris*3u;\n"
12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "        commands[gl_GlobalInvocationID.x].primCount             = 1u;\n";
12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_drawMethod==DRAWMETHOD_DRAWARRAYS)
12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			buf	<< "        commands[gl_GlobalInvocationID.x].first                 = firstTri*3u;\n";
12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (m_drawMethod==DRAWMETHOD_DRAWELEMENTS)
12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			buf	<< "        commands[gl_GlobalInvocationID.x].firstIndex            = firstTri*3u;\n";
12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			buf	<< "        commands[gl_GlobalInvocationID.x].baseVertex            = 0;\n";
12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf	<< "        commands[gl_GlobalInvocationID.x].reservedMustBeZero    = 0u;\n"
12663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "    }\n"
12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "\n";
12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (computeData)
12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf	<< "    // vertex attribs\n"
12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "    const vec4 yellow = vec4(1.0, 1.0, 0.0, 1.0);\n"
12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "    const vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n";
12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_drawMethod == DRAWMETHOD_DRAWARRAYS)
12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			buf	<< "    if (gl_GlobalInvocationID.x < gridSize && gl_GlobalInvocationID.y < gridSize && gl_GlobalInvocationID.z == 0u) {\n"
12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "        uint        y           = gl_GlobalInvocationID.x;\n"
12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "        uint        x           = gl_GlobalInvocationID.y;\n"
12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "        float       posX        = (float(x) / float(gridSize)) * 2.0 - 1.0;\n"
12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "        float       posY        = (float(y) / float(gridSize)) * 2.0 - 1.0;\n"
12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "        const float cellSize    = 2.0 / float(gridSize);\n"
12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "        vec4        color       = ((x + y)%2u != 0u) ? (yellow) : (green);\n"
12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "\n"
12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "        attribs[((y * gridSize + x) * 6u + 0u) * 2u + 0u] = vec4(posX,            posY,            0.0, 1.0);\n"
12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "        attribs[((y * gridSize + x) * 6u + 1u) * 2u + 0u] = vec4(posX + cellSize, posY,            0.0, 1.0);\n"
12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "        attribs[((y * gridSize + x) * 6u + 2u) * 2u + 0u] = vec4(posX + cellSize, posY + cellSize, 0.0, 1.0);\n"
12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "        attribs[((y * gridSize + x) * 6u + 3u) * 2u + 0u] = vec4(posX,            posY,            0.0, 1.0);\n"
12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "        attribs[((y * gridSize + x) * 6u + 4u) * 2u + 0u] = vec4(posX + cellSize, posY + cellSize, 0.0, 1.0);\n"
12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "        attribs[((y * gridSize + x) * 6u + 5u) * 2u + 0u] = vec4(posX,            posY + cellSize, 0.0, 1.0);\n"
12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "\n"
12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "        attribs[((y * gridSize + x) * 6u + 0u) * 2u + 1u] = color;\n"
12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "        attribs[((y * gridSize + x) * 6u + 1u) * 2u + 1u] = color;\n"
12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "        attribs[((y * gridSize + x) * 6u + 2u) * 2u + 1u] = color;\n"
12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "        attribs[((y * gridSize + x) * 6u + 3u) * 2u + 1u] = color;\n"
12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "        attribs[((y * gridSize + x) * 6u + 4u) * 2u + 1u] = color;\n"
12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "        attribs[((y * gridSize + x) * 6u + 5u) * 2u + 1u] = color;\n"
12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "    }\n";
13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (m_drawMethod == DRAWMETHOD_DRAWELEMENTS)
13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			buf	<< "    if (gl_GlobalInvocationID.x < gridSize+1u && gl_GlobalInvocationID.y < gridSize+1u && gl_GlobalInvocationID.z == 0u) {\n"
13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "        uint        y           = gl_GlobalInvocationID.x;\n"
13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "        uint        x           = gl_GlobalInvocationID.y;\n"
13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "        float       posX        = (float(x) / float(gridSize)) * 2.0 - 1.0;\n"
13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "        float       posY        = (float(y) / float(gridSize)) * 2.0 - 1.0;\n"
13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "\n"
13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "        attribs[(y * (gridSize+1u) + x) * 4u + 0u] = vec4(posX, posY, 0.0, 1.0);\n"
13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "        attribs[(y * (gridSize+1u) + x) * 4u + 1u] = green;\n"
13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "        attribs[(y * (gridSize+1u) + x) * 4u + 2u] = vec4(posX, posY, 0.0, 1.0);\n"
13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "        attribs[(y * (gridSize+1u) + x) * 4u + 3u] = yellow;\n"
13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "    }\n";
13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf << "\n";
13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (computeIndices)
13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf	<< "    // indices\n"
13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "    if (gl_GlobalInvocationID.x < gridSize && gl_GlobalInvocationID.y < gridSize && gl_GlobalInvocationID.z == 0u) {\n"
13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "        uint    y       = gl_GlobalInvocationID.x;\n"
13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "        uint    x       = gl_GlobalInvocationID.y;\n"
13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "        uint    color   = ((x + y)%2u);\n"
13263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "\n"
13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "        indices[(y * gridSize + x) * 6u + 0u] = ((y+0u) * (gridSize+1u) + (x+0u)) * 2u + color;\n"
13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "        indices[(y * gridSize + x) * 6u + 1u] = ((y+1u) * (gridSize+1u) + (x+0u)) * 2u + color;\n"
13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "        indices[(y * gridSize + x) * 6u + 2u] = ((y+1u) * (gridSize+1u) + (x+1u)) * 2u + color;\n"
13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "        indices[(y * gridSize + x) * 6u + 3u] = ((y+0u) * (gridSize+1u) + (x+0u)) * 2u + color;\n"
13313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "        indices[(y * gridSize + x) * 6u + 4u] = ((y+1u) * (gridSize+1u) + (x+1u)) * 2u + color;\n"
13323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "        indices[(y * gridSize + x) * 6u + 5u] = ((y+0u) * (gridSize+1u) + (x+1u)) * 2u + color;\n"
13333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "    }\n"
13343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "\n";
13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	buf	<< "}\n";
13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return buf.str();
13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ComputeShaderGeneratedCase::createDrawCommand (void)
13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				triangleCount	= m_gridSize * m_gridSize * 2;
13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32			numDrawCallTris	= triangleCount / m_numDrawCmds;
13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_drawMethod == DRAWMETHOD_DRAWARRAYS)
13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		std::vector<DrawArraysCommand> cmds;
13513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ndx = 0; ndx < m_numDrawCmds; ++ndx)
13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32				firstTri = ndx * numDrawCallTris;
13553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DrawArraysCommand			data;
13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			data.count					= numDrawCallTris*3;
13583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			data.primCount				= 1;
13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			data.first					= firstTri*3;
13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			data.reservedMustBeZero		= 0;
13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			cmds.push_back(data);
13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT((int)(sizeof(DrawArraysCommand)*cmds.size()) == m_numDrawCmds * m_commandSize);
13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindBuffer(GL_DRAW_INDIRECT_BUFFER, m_cmdBufferID);
13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bufferData(GL_DRAW_INDIRECT_BUFFER, (glw::GLsizeiptr)(sizeof(DrawArraysCommand)*cmds.size()), &cmds[0], GL_STATIC_DRAW);
13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_drawMethod == DRAWMETHOD_DRAWELEMENTS)
13713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		std::vector<DrawElementsCommand> cmds;
13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ndx = 0; ndx < m_numDrawCmds; ++ndx)
13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32			firstTri = ndx * numDrawCallTris;
13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DrawElementsCommand		data;
13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			data.count				= numDrawCallTris*3;
13803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			data.primCount			= 1;
13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			data.firstIndex			= firstTri*3;
13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			data.baseVertex			= 0;
13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			data.reservedMustBeZero	= 0;
13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			cmds.push_back(data);
13863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT((int)(sizeof(DrawElementsCommand)*cmds.size()) == m_numDrawCmds * m_commandSize);
13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindBuffer(GL_DRAW_INDIRECT_BUFFER, m_cmdBufferID);
13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bufferData(GL_DRAW_INDIRECT_BUFFER, (glw::GLsizeiptr)(sizeof(DrawElementsCommand)*cmds.size()), &cmds[0], GL_STATIC_DRAW);
13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(false);
13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::checkError(gl.getError(), "create draw command", __FILE__, __LINE__);
13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ComputeShaderGeneratedCase::createDrawData (void)
14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4			yellow	(1.0f, 1.0f, 0.0f, 1.0f);
14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4			green	(0.0f, 1.0f, 0.0f, 1.0f);
14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_drawMethod == DRAWMETHOD_DRAWARRAYS)
14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Store elements in the order they are drawn. Interleave color.
14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		std::vector<tcu::Vec4> buffer(m_gridSize*m_gridSize*6*2);
14093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(buffer.size() == calcDrawBufferSize());
14113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int y = 0; y < m_gridSize; ++y)
14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int x = 0; x < m_gridSize; ++x)
14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float 		posX		= (x / (float)m_gridSize) * 2.0f - 1.0f;
14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float 		posY		= (y / (float)m_gridSize) * 2.0f - 1.0f;
14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float			cellSize	= 2.0f / (float)m_gridSize;
14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::Vec4&	color		= ((x + y)%2) ? (yellow) : (green);
14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			buffer[((y * m_gridSize + x) * 6 + 0) * 2 + 0] = tcu::Vec4(posX,			posY,				0.0f, 1.0f);
14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			buffer[((y * m_gridSize + x) * 6 + 1) * 2 + 0] = tcu::Vec4(posX + cellSize,	posY,				0.0f, 1.0f);
14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			buffer[((y * m_gridSize + x) * 6 + 2) * 2 + 0] = tcu::Vec4(posX + cellSize,	posY + cellSize,	0.0f, 1.0f);
14233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			buffer[((y * m_gridSize + x) * 6 + 3) * 2 + 0] = tcu::Vec4(posX,			posY,				0.0f, 1.0f);
14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			buffer[((y * m_gridSize + x) * 6 + 4) * 2 + 0] = tcu::Vec4(posX + cellSize, posY + cellSize,	0.0f, 1.0f);
14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			buffer[((y * m_gridSize + x) * 6 + 5) * 2 + 0] = tcu::Vec4(posX,			posY + cellSize,	0.0f, 1.0f);
14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			buffer[((y * m_gridSize + x) * 6 + 0) * 2 + 1] = color;
14283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			buffer[((y * m_gridSize + x) * 6 + 1) * 2 + 1] = color;
14293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			buffer[((y * m_gridSize + x) * 6 + 2) * 2 + 1] = color;
14303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			buffer[((y * m_gridSize + x) * 6 + 3) * 2 + 1] = color;
14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			buffer[((y * m_gridSize + x) * 6 + 4) * 2 + 1] = color;
14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			buffer[((y * m_gridSize + x) * 6 + 5) * 2 + 1] = color;
14333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindBuffer(GL_ARRAY_BUFFER, m_dataBufferID);
14363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bufferData(GL_ARRAY_BUFFER, (int)(buffer.size() * sizeof(tcu::Vec4)), buffer[0].getPtr(), GL_STATIC_DRAW);
14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_drawMethod == DRAWMETHOD_DRAWELEMENTS)
14393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Elements are indexed by index buffer. Interleave color. Two vertices per position since 2 colors
14413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		std::vector<tcu::Vec4> buffer((m_gridSize+1)*(m_gridSize+1)*4);
14433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(buffer.size() == calcDrawBufferSize());
14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int y = 0; y < m_gridSize+1; ++y)
14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int x = 0; x < m_gridSize+1; ++x)
14483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float 		posX		= (x / (float)m_gridSize) * 2.0f - 1.0f;
14503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float 		posY		= (y / (float)m_gridSize) * 2.0f - 1.0f;
14513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			buffer[(y * (m_gridSize+1) + x) * 4 + 0] = tcu::Vec4(posX, posY, 0.0f, 1.0f);
14533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			buffer[(y * (m_gridSize+1) + x) * 4 + 1] = green;
14543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			buffer[(y * (m_gridSize+1) + x) * 4 + 2] = tcu::Vec4(posX, posY, 0.0f, 1.0f);
14553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			buffer[(y * (m_gridSize+1) + x) * 4 + 3] = yellow;
14563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindBuffer(GL_ARRAY_BUFFER, m_dataBufferID);
14593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bufferData(GL_ARRAY_BUFFER, (int)(buffer.size() * sizeof(tcu::Vec4)), buffer[0].getPtr(), GL_STATIC_DRAW);
14603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
14623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(false);
14633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::checkError(gl.getError(), "", __FILE__, __LINE__);
14653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ComputeShaderGeneratedCase::createDrawIndices (void)
14683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_drawMethod == DRAWMETHOD_DRAWELEMENTS);
14703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
14723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<deUint32>	buffer	(m_gridSize*m_gridSize*6);
14733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(buffer.size() == calcIndexBufferSize());
14753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < m_gridSize; ++y)
14773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < m_gridSize; ++x)
14783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int color = ((x + y)%2);
14803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buffer[(y * m_gridSize + x) * 6 + 0] = ((y+0) * (m_gridSize+1) + (x+0)) * 2 + color;
14823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buffer[(y * m_gridSize + x) * 6 + 1] = ((y+1) * (m_gridSize+1) + (x+0)) * 2 + color;
14833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buffer[(y * m_gridSize + x) * 6 + 2] = ((y+1) * (m_gridSize+1) + (x+1)) * 2 + color;
14843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buffer[(y * m_gridSize + x) * 6 + 3] = ((y+0) * (m_gridSize+1) + (x+0)) * 2 + color;
14853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buffer[(y * m_gridSize + x) * 6 + 4] = ((y+1) * (m_gridSize+1) + (x+1)) * 2 + color;
14863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buffer[(y * m_gridSize + x) * 6 + 5] = ((y+0) * (m_gridSize+1) + (x+1)) * 2 + color;
14873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBufferID);
14903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (int)(buffer.size() * sizeof(deUint32)), &buffer[0], GL_STATIC_DRAW);
14913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::checkError(gl.getError(), "", __FILE__, __LINE__);
14923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14943c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ComputeShaderGeneratedCase::renderTo (tcu::Surface& dst)
14953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
14973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deInt32			positionLoc = gl.getAttribLocation(m_shaderProgram->getProgram(), "a_position");
14983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deInt32			colorLoc	= gl.getAttribLocation(m_shaderProgram->getProgram(), "a_color");
14993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32				vaoID		= 0;
15003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.genVertexArrays(1, &vaoID);
15023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindVertexArray(vaoID);
15033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Setup buffers
15053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindBuffer(GL_ARRAY_BUFFER, m_dataBufferID);
15073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 8 * sizeof(float), DE_NULL);
15083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.vertexAttribPointer(colorLoc,    4, GL_FLOAT, GL_FALSE, 8 * sizeof(float), ((const deUint8*)DE_NULL) + 4*sizeof(float));
15093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.enableVertexAttribArray(positionLoc);
15103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.enableVertexAttribArray(colorLoc);
15113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(positionLoc != -1);
15133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(colorLoc != -1);
15143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_drawMethod == DRAWMETHOD_DRAWELEMENTS)
15163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBufferID);
15173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindBuffer(GL_DRAW_INDIRECT_BUFFER, m_cmdBufferID);
15193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// draw
15213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.clearColor(0, 0, 0, 1);
15233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.clear(GL_COLOR_BUFFER_BIT);
15243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.viewport(0, 0, dst.getWidth(), dst.getHeight());
15253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.useProgram(m_shaderProgram->getProgram());
15273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int drawCmdNdx = 0; drawCmdNdx < m_numDrawCmds; ++drawCmdNdx)
15283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const void* offset = ((deUint8*)DE_NULL) + drawCmdNdx*m_commandSize;
15303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_drawMethod == DRAWMETHOD_DRAWELEMENTS)
15323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.drawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, offset);
15333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (m_drawMethod == DRAWMETHOD_DRAWARRAYS)
15343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.drawArraysIndirect(GL_TRIANGLES, offset);
15353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
15363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
15373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.useProgram(0);
15393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// free
15413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.deleteVertexArrays(1, &vaoID);
154390563f0686a0925e19cc52251dd28d6ef81e9abaJarkko Pöyry	glu::checkError(gl.getError(), "", __FILE__, __LINE__);
15443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.finish();
154690563f0686a0925e19cc52251dd28d6ef81e9abaJarkko Pöyry	glu::checkError(gl.getError(), "", __FILE__, __LINE__);
15473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
154890563f0686a0925e19cc52251dd28d6ef81e9abaJarkko Pöyry	glu::readPixels(m_context.getRenderContext(), 0, 0, dst.getAccess());
15493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::checkError(gl.getError(), "", __FILE__, __LINE__);
15503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15523c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeUint32 ComputeShaderGeneratedCase::calcDrawBufferSize (void) const
15533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// returns size in "vec4"s
15553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_drawMethod == DRAWMETHOD_DRAWARRAYS)
15563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return m_gridSize*m_gridSize*6*2;
15573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_drawMethod == DRAWMETHOD_DRAWELEMENTS)
15583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return (m_gridSize+1)*(m_gridSize+1)*4;
15593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
15603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(DE_FALSE);
15613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return 0;
15633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15653c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeUint32 ComputeShaderGeneratedCase::calcIndexBufferSize (void) const
15663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_drawMethod == DRAWMETHOD_DRAWELEMENTS)
15683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return m_gridSize*m_gridSize*6;
15693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
15703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0;
15713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ComputeShaderGeneratedCombinedCase : public ComputeShaderGeneratedCase
15743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
15763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						ComputeShaderGeneratedCombinedCase	(Context& context, const char* name, const char* desc, DrawMethod method, bool computeCmd, bool computeData, bool computeIndices, int gridSize, int numDrawCalls);
15773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						~ComputeShaderGeneratedCombinedCase	(void);
15783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				init								(void);
15803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				deinit								(void);
15813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15823c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
15833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				runComputeShader					(void);
15843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::ShaderProgram*	m_computeProgram;
15863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
15873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15883c827367444ee418f129b2c238299f49d3264554Jarkko PoyryComputeShaderGeneratedCombinedCase::ComputeShaderGeneratedCombinedCase (Context& context, const char* name, const char* desc, DrawMethod method, bool computeCmd, bool computeData, bool computeIndices, int gridSize, int numDrawCalls)
15893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ComputeShaderGeneratedCase(context, name, desc, method, computeCmd, computeData, computeIndices, gridSize, numDrawCalls)
15903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_computeProgram			(DE_NULL)
15913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15943c827367444ee418f129b2c238299f49d3264554Jarkko PoyryComputeShaderGeneratedCombinedCase::~ComputeShaderGeneratedCombinedCase (void)
15953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
15973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15993c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ComputeShaderGeneratedCombinedCase::init (void)
16003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// generate compute shader
16023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_computeProgram = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(genComputeSource(m_computeCmd, m_computeData, m_computeIndices)));
16043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << *m_computeProgram;
16053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!m_computeProgram->isOk())
16073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::TestError("Failed to compile compute shader.");
16083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// init parent
16103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ComputeShaderGeneratedCase::init();
16113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16133c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ComputeShaderGeneratedCombinedCase::deinit (void)
16143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// deinit parent
16163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ComputeShaderGeneratedCase::deinit();
16173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_computeProgram)
16193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete m_computeProgram;
16213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_computeProgram = DE_NULL;
16223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16253c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ComputeShaderGeneratedCombinedCase::runComputeShader (void)
16263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl									= m_context.getRenderContext().getFunctions();
16283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool				indexed								= (m_drawMethod == DRAWMETHOD_DRAWELEMENTS);
16293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::IVec3		nullSize							(0, 0, 0);
16303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::IVec3		commandDispatchSize					= (m_computeCmd)				? (tcu::IVec3(m_numDrawCmds, 1, 1))				: (nullSize);
16313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::IVec3		drawElementsDataBufferDispatchSize	= (m_computeData)				? (tcu::IVec3(m_gridSize+1, m_gridSize+1, 1))	: (nullSize);
16323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::IVec3		drawArraysDataBufferDispatchSize	= (m_computeData)				? (tcu::IVec3(m_gridSize,   m_gridSize,   1))	: (nullSize);
16333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::IVec3		indexBufferDispatchSize				= (m_computeIndices && indexed)	? (tcu::IVec3(m_gridSize,   m_gridSize,   1))	: (nullSize);
16343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::IVec3		dataBufferDispatchSize				= (m_drawMethod == DRAWMETHOD_DRAWELEMENTS) ? (drawElementsDataBufferDispatchSize) : (drawArraysDataBufferDispatchSize);
16363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::IVec3		dispatchSize						= tcu::max(tcu::max(commandDispatchSize, dataBufferDispatchSize), indexBufferDispatchSize);
16373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.useProgram(m_computeProgram->getProgram());
16393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::checkError(gl.getError(), "use compute shader", __FILE__, __LINE__);
16403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// setup buffers
16423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_computeCmd)
16443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			bindingPoint	= 0;
16463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			bufferSize		= m_commandSize * m_numDrawCmds;
16473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Binding command buffer to binding point " << bindingPoint << tcu::TestLog::EndMessage;
16493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, bindingPoint, m_cmdBufferID);
16503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Allocating memory for command buffer, size " << sizeToString(bufferSize) << "." << tcu::TestLog::EndMessage;
16523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bufferData(GL_SHADER_STORAGE_BUFFER, bufferSize, DE_NULL, GL_DYNAMIC_DRAW);
16533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_computeData)
16563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			bindingPoint	= (m_computeCmd) ? (1) : (0);
16583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			bufferSize		= (int)(calcDrawBufferSize()*sizeof(tcu::Vec4));
16593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Binding data buffer to binding point " << bindingPoint << tcu::TestLog::EndMessage;
16613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, bindingPoint, m_dataBufferID);
16623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Allocating memory for data buffer, size " << sizeToString(bufferSize) << "." << tcu::TestLog::EndMessage;
16643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bufferData(GL_SHADER_STORAGE_BUFFER, bufferSize, DE_NULL, GL_DYNAMIC_DRAW);
16653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_computeIndices)
16683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			bindingPoint	= (m_computeCmd && m_computeData) ? (2) : (m_computeCmd || m_computeData) ? (1) : (0);
16703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			bufferSize		= (int)(calcIndexBufferSize()*sizeof(deUint32));
16713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Binding index buffer to binding point " << bindingPoint << tcu::TestLog::EndMessage;
16733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, bindingPoint, m_indexBufferID);
16743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Allocating memory for index buffer, size " << sizeToString(bufferSize) << "." << tcu::TestLog::EndMessage;
16763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bufferData(GL_SHADER_STORAGE_BUFFER, bufferSize, DE_NULL, GL_DYNAMIC_DRAW);
16773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::checkError(gl.getError(), "setup buffers", __FILE__, __LINE__);
16803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// calculate
16823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << tcu::TestLog::Message << "Dispatching compute, size = " << dispatchSize << tcu::TestLog::EndMessage;
16843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.dispatchCompute(dispatchSize.x(), dispatchSize.y(), dispatchSize.z());
16853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::checkError(gl.getError(), "calculate", __FILE__, __LINE__);
16873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16893c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ComputeShaderGeneratedSeparateCase : public ComputeShaderGeneratedCase
16903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
16923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						ComputeShaderGeneratedSeparateCase	(Context& context, const char* name, const char* desc, DrawMethod method, bool computeCmd, bool computeData, bool computeIndices, int gridSize, int numDrawCalls);
16933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						~ComputeShaderGeneratedSeparateCase	(void);
16943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				init								(void);
16963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				deinit								(void);
16973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16983c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
16993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string			genCmdComputeSource					(void);
17003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string			genDataComputeSource				(void);
17013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string			genIndexComputeSource				(void);
17023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				runComputeShader					(void);
17033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::ShaderProgram*	m_computeCmdProgram;
17053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::ShaderProgram*	m_computeDataProgram;
17063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::ShaderProgram*	m_computeIndicesProgram;
17073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
17083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17093c827367444ee418f129b2c238299f49d3264554Jarkko PoyryComputeShaderGeneratedSeparateCase::ComputeShaderGeneratedSeparateCase (Context& context, const char* name, const char* desc, DrawMethod method, bool computeCmd, bool computeData, bool computeIndices, int gridSize, int numDrawCalls)
17103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ComputeShaderGeneratedCase	(context, name, desc, method, computeCmd, computeData, computeIndices, gridSize, numDrawCalls)
17113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_computeCmdProgram			(DE_NULL)
17123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_computeDataProgram			(DE_NULL)
17133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_computeIndicesProgram		(DE_NULL)
17143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17173c827367444ee418f129b2c238299f49d3264554Jarkko PoyryComputeShaderGeneratedSeparateCase::~ComputeShaderGeneratedSeparateCase (void)
17183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
17203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17223c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ComputeShaderGeneratedSeparateCase::init (void)
17233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// generate cmd compute shader
17253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_computeCmd)
17273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_computeCmdProgram = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(genCmdComputeSource()));
17293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << *m_computeCmdProgram;
17303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!m_computeCmdProgram->isOk())
17323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::TestError("Failed to compile command compute shader.");
17333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// generate data compute shader
17363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_computeData)
17383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_computeDataProgram = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(genDataComputeSource()));
17403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << *m_computeDataProgram;
17413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!m_computeDataProgram->isOk())
17433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::TestError("Failed to compile data compute shader.");
17443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// generate index compute shader
17473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_computeIndices)
17493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_computeIndicesProgram = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(genIndexComputeSource()));
17513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << *m_computeIndicesProgram;
17523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!m_computeIndicesProgram->isOk())
17543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::TestError("Failed to compile data compute shader.");
17553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// init parent
17583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ComputeShaderGeneratedCase::init();
17593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ComputeShaderGeneratedSeparateCase::deinit (void)
17623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// deinit parent
17643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ComputeShaderGeneratedCase::deinit();
17653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_computeCmdProgram)
17673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete m_computeCmdProgram;
17693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_computeCmdProgram = DE_NULL;
17703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_computeDataProgram)
17723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete m_computeDataProgram;
17743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_computeDataProgram = DE_NULL;
17753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_computeIndicesProgram)
17773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete m_computeIndicesProgram;
17793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_computeIndicesProgram = DE_NULL;
17803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17833c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string ComputeShaderGeneratedSeparateCase::genCmdComputeSource (void)
17843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return ComputeShaderGeneratedCase::genComputeSource(true, false, false);
17863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17883c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string ComputeShaderGeneratedSeparateCase::genDataComputeSource (void)
17893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return ComputeShaderGeneratedCase::genComputeSource(false, true, false);
17913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17933c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string ComputeShaderGeneratedSeparateCase::genIndexComputeSource (void)
17943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return ComputeShaderGeneratedCase::genComputeSource(false, false, true);
17963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17983c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ComputeShaderGeneratedSeparateCase::runComputeShader (void)
17993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
18013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute command
18033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_computeCmd)
18053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				bindingPoint			= 0;
18073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::IVec3		commandDispatchSize		(m_numDrawCmds, 1, 1);
18083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				bufferSize				= m_commandSize * m_numDrawCmds;
18093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram(m_computeCmdProgram->getProgram());
18113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// setup buffers
18133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Binding command buffer to binding point " << bindingPoint << tcu::TestLog::EndMessage;
18153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, bindingPoint, m_cmdBufferID);
18163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Allocating memory for command buffer, size " << sizeToString(bufferSize) << "." << tcu::TestLog::EndMessage;
18183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bufferData(GL_SHADER_STORAGE_BUFFER, bufferSize, DE_NULL, GL_DYNAMIC_DRAW);
18193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// calculate
18213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Dispatching command compute, size = " << commandDispatchSize << tcu::TestLog::EndMessage;
18233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.dispatchCompute(commandDispatchSize.x(), commandDispatchSize.y(), commandDispatchSize.z());
18243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::checkError(gl.getError(), "calculate cmd", __FILE__, __LINE__);
18263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute data
18293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_computeData)
18313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				bindingPoint						= 0;
18333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::IVec3		drawElementsDataBufferDispatchSize	(m_gridSize+1, m_gridSize+1, 1);
18343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::IVec3		drawArraysDataBufferDispatchSize	(m_gridSize,   m_gridSize,   1);
18353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::IVec3		dataBufferDispatchSize				= (m_drawMethod == DRAWMETHOD_DRAWELEMENTS) ? (drawElementsDataBufferDispatchSize) : (drawArraysDataBufferDispatchSize);
18363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				bufferSize							= (int)(calcDrawBufferSize()*sizeof(tcu::Vec4));
18373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram(m_computeDataProgram->getProgram());
18393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// setup buffers
18413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Binding data buffer to binding point " << bindingPoint << tcu::TestLog::EndMessage;
18433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, bindingPoint, m_dataBufferID);
18443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Allocating memory for data buffer, size " << sizeToString(bufferSize) << "." << tcu::TestLog::EndMessage;
18463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bufferData(GL_SHADER_STORAGE_BUFFER, bufferSize, DE_NULL, GL_DYNAMIC_DRAW);
18473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// calculate
18493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Dispatching data compute, size = " << dataBufferDispatchSize << tcu::TestLog::EndMessage;
18513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.dispatchCompute(dataBufferDispatchSize.x(), dataBufferDispatchSize.y(), dataBufferDispatchSize.z());
18523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::checkError(gl.getError(), "calculate data", __FILE__, __LINE__);
18543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute indices
18573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_computeIndices)
18593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				bindingPoint				= 0;
18613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::IVec3		indexBufferDispatchSize		(m_gridSize, m_gridSize, 1);
18623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				bufferSize					= (int)(calcIndexBufferSize()*sizeof(deUint32));
18633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(m_drawMethod == DRAWMETHOD_DRAWELEMENTS);
18653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram(m_computeIndicesProgram->getProgram());
18673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// setup buffers
18693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Binding index buffer to binding point " << bindingPoint << tcu::TestLog::EndMessage;
18713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, bindingPoint, m_indexBufferID);
18723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Allocating memory for index buffer, size " << sizeToString(bufferSize) << "." << tcu::TestLog::EndMessage;
18743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bufferData(GL_SHADER_STORAGE_BUFFER, bufferSize, DE_NULL, GL_DYNAMIC_DRAW);
18753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// calculate
18773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Dispatching index compute, size = " << indexBufferDispatchSize << tcu::TestLog::EndMessage;
18793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.dispatchCompute(indexBufferDispatchSize.x(), indexBufferDispatchSize.y(), indexBufferDispatchSize.z());
18803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::checkError(gl.getError(), "calculate indices", __FILE__, __LINE__);
18823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::checkError(gl.getError(), "post dispatch", __FILE__, __LINE__);
18853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ComputeShaderGeneratedGroup : public TestCaseGroup
18883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18893c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
18903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ComputeShaderGeneratedGroup		(Context& context, const char* name, const char* descr);
18913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			~ComputeShaderGeneratedGroup	(void);
18923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void	init							(void);
18943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
18953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18963c827367444ee418f129b2c238299f49d3264554Jarkko PoyryComputeShaderGeneratedGroup::ComputeShaderGeneratedGroup (Context& context, const char* name, const char* descr)
18973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup	(context, name, descr)
18983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19013c827367444ee418f129b2c238299f49d3264554Jarkko PoyryComputeShaderGeneratedGroup::~ComputeShaderGeneratedGroup (void)
19023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19053c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ComputeShaderGeneratedGroup::init (void)
19063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					gridSize		= 8;
19083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* const	separateGroup	= new tcu::TestCaseGroup(m_testCtx, "separate", "Use separate compute shaders for each buffer");
19093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* const	combinedGroup	= new tcu::TestCaseGroup(m_testCtx, "combined", "Use combined compute shader for all buffers");
19103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* const	largeGroup		= new tcu::TestCaseGroup(m_testCtx, "large",   "Draw shapes with large buffers");
19113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	this->addChild(separateGroup);
19133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	this->addChild(combinedGroup);
19143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	this->addChild(largeGroup);
19153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// .separate
19173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		separateGroup->addChild(new ComputeShaderGeneratedSeparateCase(m_context, "drawarrays_compute_cmd",							"Command from compute shader",						ComputeShaderGeneratedCase::DRAWMETHOD_DRAWARRAYS,		true,	false,	false,	gridSize,	1));
19193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		separateGroup->addChild(new ComputeShaderGeneratedSeparateCase(m_context, "drawarrays_compute_data",						"Data from compute shader",							ComputeShaderGeneratedCase::DRAWMETHOD_DRAWARRAYS,		false,	true,	false,	gridSize,	1));
19203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		separateGroup->addChild(new ComputeShaderGeneratedSeparateCase(m_context, "drawarrays_compute_cmd_and_data",				"Command and data from compute shader",				ComputeShaderGeneratedCase::DRAWMETHOD_DRAWARRAYS,		true,	true,	false,	gridSize,	1));
19213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		separateGroup->addChild(new ComputeShaderGeneratedSeparateCase(m_context, "drawelements_compute_cmd",						"Command from compute shader",						ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS,	true,	false,	false,	gridSize,	1));
19233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		separateGroup->addChild(new ComputeShaderGeneratedSeparateCase(m_context, "drawelements_compute_data",						"Data from compute shader",							ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS,	false,	true,	false,	gridSize,	1));
19243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		separateGroup->addChild(new ComputeShaderGeneratedSeparateCase(m_context, "drawelements_compute_indices",					"Indices from compute shader",						ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS,	false,	false,	true,	gridSize,	1));
19253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		separateGroup->addChild(new ComputeShaderGeneratedSeparateCase(m_context, "drawelements_compute_cmd_and_data",				"Command and data from compute shader",				ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS,	true,	true,	false,	gridSize,	1));
19263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		separateGroup->addChild(new ComputeShaderGeneratedSeparateCase(m_context, "drawelements_compute_cmd_and_indices",			"Command and indices from compute shader",			ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS,	true,	false,	true,	gridSize,	1));
19273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		separateGroup->addChild(new ComputeShaderGeneratedSeparateCase(m_context, "drawelements_compute_data_and_indices",			"Data and indices from compute shader",				ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS,	false,	true,	true,	gridSize,	1));
19283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		separateGroup->addChild(new ComputeShaderGeneratedSeparateCase(m_context, "drawelements_compute_cmd_and_data_and_indices",	"Command, data and indices from compute shader",	ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS,	true,	true,	true,	gridSize,	1));
19293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// .combined
19323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		combinedGroup->addChild(new ComputeShaderGeneratedCombinedCase(m_context, "drawarrays_compute_cmd_and_data",				"Command and data from compute shader",				ComputeShaderGeneratedCase::DRAWMETHOD_DRAWARRAYS,		true,	true,	false,	gridSize,	1));
19343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		combinedGroup->addChild(new ComputeShaderGeneratedCombinedCase(m_context, "drawelements_compute_cmd_and_data",				"Command and data from compute shader",				ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS,	true,	true,	false,	gridSize,	1));
19353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		combinedGroup->addChild(new ComputeShaderGeneratedCombinedCase(m_context, "drawelements_compute_cmd_and_indices",			"Command and indices from compute shader",			ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS,	true,	false,	true,	gridSize,	1));
19363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		combinedGroup->addChild(new ComputeShaderGeneratedCombinedCase(m_context, "drawelements_compute_data_and_indices",			"Data and indices from compute shader",				ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS,	false,	true,	true,	gridSize,	1));
19373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		combinedGroup->addChild(new ComputeShaderGeneratedCombinedCase(m_context, "drawelements_compute_cmd_and_data_and_indices",	"Command, data and indices from compute shader",	ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS,	true,	true,	true,	gridSize,	1));
19383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// .large
19413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		struct TestSpec
19433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int gridSize;
19453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int numDrawCommands;
19463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
19473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		struct TestMethod
19483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ComputeShaderGeneratedCase::DrawMethod method;
19503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool                                   separateCompute;
19513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
19523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const TestSpec specs[] =
19543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 100,	1 },		// !< drawArrays array size ~ 1.9 MB
19563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 200,	1 },		// !< drawArrays array size ~ 7.7 MB
19573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 500,	1 },		// !< drawArrays array size ~ 48 MB
19583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 1000,	1 },		// !< drawArrays array size ~ 192 MB
19593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 1200,	1 },		// !< drawArrays array size ~ 277 MB
19603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 1500,	1 },		// !< drawArrays array size ~ 430 MB
19613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 100,	8 },		// !< drawArrays array size ~ 1.9 MB
19633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 200,	8 },		// !< drawArrays array size ~ 7.7 MB
19643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 500,	8 },		// !< drawArrays array size ~ 48 MB
19653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 1000,	8 },		// !< drawArrays array size ~ 192 MB
19663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 1200,	8 },		// !< drawArrays array size ~ 277 MB
19673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 1500,	8 },		// !< drawArrays array size ~ 430 MB
19683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 100,	200  },		// !< 50 cells per draw call
19703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 200,	800  },		// !< 50 cells per draw call
19713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 500,	2500 },		// !< 100 cells per draw call
19723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 1000,	5000 },		// !< 250 cells per draw call
19733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
19743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const TestMethod methods[] =
19753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ ComputeShaderGeneratedCase::DRAWMETHOD_DRAWARRAYS,	true	},
19773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ ComputeShaderGeneratedCase::DRAWMETHOD_DRAWARRAYS,	false	},
19783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS,	true	},
19793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS,	false	},
19803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
19813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int methodNdx = 0; methodNdx < DE_LENGTH_OF_ARRAY(methods); ++methodNdx)
19833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int specNdx = 0; specNdx < DE_LENGTH_OF_ARRAY(specs); ++specNdx)
19843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const std::string name = std::string("")
19863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									+ ((methods[methodNdx].method == ComputeShaderGeneratedCase::DRAWMETHOD_DRAWARRAYS) ? ("drawarrays") : ("drawelements"))
19873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									+ ((methods[methodNdx].separateCompute) ? ("_separate") : ("_combined"))
19883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									+ "_grid_" + de::toString(specs[specNdx].gridSize) + "x" + de::toString(specs[specNdx].gridSize)
19893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									+ "_drawcount_" + de::toString(specs[specNdx].numDrawCommands);
19903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const std::string desc = std::string("Draw grid with ")
19923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									+ ((methods[methodNdx].method == ComputeShaderGeneratedCase::DRAWMETHOD_DRAWARRAYS) ? ("drawarrays indirect") : ("drawelements indirect"))
19933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									+ " calculating buffers in " + ((methods[methodNdx].separateCompute) ? ("separate") : ("combined")) + " compute shader."
19943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									+ " Grid size is " + de::toString(specs[specNdx].gridSize) + "x" + de::toString(specs[specNdx].gridSize)
19953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									+ ", draw count is "  + de::toString(specs[specNdx].numDrawCommands);
19963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool computeIndices = (methods[methodNdx].method == ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS);
19983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (methods[methodNdx].separateCompute)
20003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				largeGroup->addChild(new ComputeShaderGeneratedSeparateCase(m_context, name.c_str(), desc.c_str(), methods[methodNdx].method, false, true, computeIndices, specs[specNdx].gridSize, specs[specNdx].numDrawCommands));
20013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
20023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				largeGroup->addChild(new ComputeShaderGeneratedCombinedCase(m_context, name.c_str(), desc.c_str(), methods[methodNdx].method, false, true, computeIndices, specs[specNdx].gridSize, specs[specNdx].numDrawCommands));
20033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
20043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20073c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass RandomGroup : public TestCaseGroup
20083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20093c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
20103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RandomGroup		(Context& context, const char* name, const char* descr);
20113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			~RandomGroup	(void);
20123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void	init			(void);
20143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
20153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20163c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int SIZE>
20173c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct UniformWeightArray
20183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float weights[SIZE];
20203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	UniformWeightArray (void)
20223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i=0; i<SIZE; ++i)
20243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			weights[i] = 1.0f;
20253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
20273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20283c827367444ee418f129b2c238299f49d3264554Jarkko PoyryRandomGroup::RandomGroup (Context& context, const char* name, const char* descr)
20293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup	(context, name, descr)
20303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20333c827367444ee418f129b2c238299f49d3264554Jarkko PoyryRandomGroup::~RandomGroup (void)
20343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid RandomGroup::init (void)
20383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	numAttempts				= 100;
20403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	attribCounts[]			= { 1,   2,   5 };
20423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	attribWeights[]			= { 30, 10,   1 };
20433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	primitiveCounts[]		= { 1,   5,  64 };
20443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	primitiveCountWeights[]	= { 20, 10,   1 };
20453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	indexOffsets[]			= { 0,   7,  13 };
20463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	indexOffsetWeights[]	= { 20, 20,   1 };
20473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	firsts[]				= { 0,   7,  13 };
20483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	firstWeights[]			= { 20, 20,   1 };
20493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	instanceCounts[]		= { 1,   2,  16,  17 };
20513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	instanceWeights[]		= { 20, 10,   5,   1 };
20523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	indexMins[]				= { 0,   1,   3,   8 };
20533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	indexMaxs[]				= { 4,   8, 128, 257 };
20543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	indexWeights[]			= { 50, 50,  50,  50 };
20553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	offsets[]				= { 0,   1,   5,  12 };
20563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	offsetWeights[]			= { 50, 10,  10,  10 };
20573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	strides[]				= { 0,   7,  16,  17 };
20583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	strideWeights[]			= { 50, 10,  10,  10 };
20593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	instanceDivisors[]		= { 0,   1,   3, 129 };
20603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	instanceDivisorWeights[]= { 70, 30,  10,  10 };
20613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	indirectOffsets[]		= { 0,   1,   2 };
20633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float indirectOffsetWeigths[]	= { 2,   1,   1 };
20643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	baseVertices[]			= { 0,   1,  -2,   4,  3 };
20653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float baseVertexWeigths[]		= { 4,   1,   1,   1,  1 };
20663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gls::DrawTestSpec::Primitive primitives[] =
20683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::PRIMITIVE_POINTS,
20703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::PRIMITIVE_TRIANGLES,
20713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN,
20723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP,
20733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::PRIMITIVE_LINES,
20743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::PRIMITIVE_LINE_STRIP,
20753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::PRIMITIVE_LINE_LOOP
20763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
20773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const UniformWeightArray<DE_LENGTH_OF_ARRAY(primitives)> primitiveWeights;
20783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gls::DrawTestSpec::DrawMethod drawMethods[] =
20803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS_INDIRECT,
20823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INDIRECT,
20833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
20843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const UniformWeightArray<DE_LENGTH_OF_ARRAY(drawMethods)> drawMethodWeights;
20853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gls::DrawTestSpec::IndexType indexTypes[] =
20873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::INDEXTYPE_BYTE,
20893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::INDEXTYPE_SHORT,
20903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::INDEXTYPE_INT,
20913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
20923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const UniformWeightArray<DE_LENGTH_OF_ARRAY(indexTypes)> indexTypeWeights;
20933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gls::DrawTestSpec::InputType inputTypes[] =
20953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::INPUTTYPE_FLOAT,
20973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::INPUTTYPE_FIXED,
20983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::INPUTTYPE_BYTE,
20993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::INPUTTYPE_SHORT,
21003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE,
21013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT,
21023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::INPUTTYPE_INT,
21033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::INPUTTYPE_UNSIGNED_INT,
21043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::INPUTTYPE_HALF,
21053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10,
21063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::INPUTTYPE_INT_2_10_10_10,
21073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
21083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const UniformWeightArray<DE_LENGTH_OF_ARRAY(inputTypes)> inputTypeWeights;
21093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gls::DrawTestSpec::OutputType outputTypes[] =
21113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::OUTPUTTYPE_FLOAT,
21133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::OUTPUTTYPE_VEC2,
21143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::OUTPUTTYPE_VEC3,
21153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::OUTPUTTYPE_VEC4,
21163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::OUTPUTTYPE_INT,
21173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::OUTPUTTYPE_UINT,
21183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::OUTPUTTYPE_IVEC2,
21193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::OUTPUTTYPE_IVEC3,
21203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::OUTPUTTYPE_IVEC4,
21213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::OUTPUTTYPE_UVEC2,
21223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::OUTPUTTYPE_UVEC3,
21233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::OUTPUTTYPE_UVEC4,
21243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
21253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const UniformWeightArray<DE_LENGTH_OF_ARRAY(outputTypes)> outputTypeWeights;
21263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gls::DrawTestSpec::Usage usages[] =
21283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::USAGE_DYNAMIC_DRAW,
21303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::USAGE_STATIC_DRAW,
21313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::USAGE_STREAM_DRAW,
21323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::USAGE_STREAM_READ,
21333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::USAGE_STREAM_COPY,
21343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::USAGE_STATIC_READ,
21353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::USAGE_STATIC_COPY,
21363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::USAGE_DYNAMIC_READ,
21373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec::USAGE_DYNAMIC_COPY,
21383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
21393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const UniformWeightArray<DE_LENGTH_OF_ARRAY(usages)> usageWeights;
21403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::set<deUint32>	insertedHashes;
21423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	size_t				insertedCount = 0;
21433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < numAttempts; ++ndx)
21453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::Random random(0xc551393 + ndx); // random does not depend on previous cases
21473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int					attributeCount = random.chooseWeighted<int, const int*, const float*>(DE_ARRAY_BEGIN(attribCounts), DE_ARRAY_END(attribCounts), attribWeights);
21493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int					drawCommandSize;
21503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::DrawTestSpec	spec;
21513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.apiType				= glu::ApiType::es(3,1);
21533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.primitive				= random.chooseWeighted<gls::DrawTestSpec::Primitive>	(DE_ARRAY_BEGIN(primitives),		DE_ARRAY_END(primitives),		primitiveWeights.weights);
21543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.primitiveCount			= random.chooseWeighted<int, const int*, const float*>	(DE_ARRAY_BEGIN(primitiveCounts),	DE_ARRAY_END(primitiveCounts),	primitiveCountWeights);
21553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.drawMethod				= random.chooseWeighted<gls::DrawTestSpec::DrawMethod>	(DE_ARRAY_BEGIN(drawMethods),		DE_ARRAY_END(drawMethods),		drawMethodWeights.weights);
21563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (spec.drawMethod == gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS_INDIRECT)
21583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			drawCommandSize = sizeof(deUint32[4]);
21593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (spec.drawMethod == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INDIRECT)
21603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			drawCommandSize = sizeof(deUint32[5]);
21613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
21623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
21643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return;
21653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.indexType				= random.chooseWeighted<gls::DrawTestSpec::IndexType>	(DE_ARRAY_BEGIN(indexTypes),		DE_ARRAY_END(indexTypes),		indexTypeWeights.weights);
21683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.indexPointerOffset		= random.chooseWeighted<int, const int*, const float*>	(DE_ARRAY_BEGIN(indexOffsets),		DE_ARRAY_END(indexOffsets),		indexOffsetWeights);
21693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.indexStorage			= gls::DrawTestSpec::STORAGE_BUFFER;
21703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.first					= random.chooseWeighted<int, const int*, const float*>	(DE_ARRAY_BEGIN(firsts),			DE_ARRAY_END(firsts),			firstWeights);
21713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.indexMin				= random.chooseWeighted<int, const int*, const float*>	(DE_ARRAY_BEGIN(indexMins),			DE_ARRAY_END(indexMins),		indexWeights);
21723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.indexMax				= random.chooseWeighted<int, const int*, const float*>	(DE_ARRAY_BEGIN(indexMaxs),			DE_ARRAY_END(indexMaxs),		indexWeights);
21733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.instanceCount			= random.chooseWeighted<int, const int*, const float*>	(DE_ARRAY_BEGIN(instanceCounts),	DE_ARRAY_END(instanceCounts),	instanceWeights);
21743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.indirectOffset			= random.chooseWeighted<int, const int*, const float*>	(DE_ARRAY_BEGIN(indirectOffsets),	DE_ARRAY_END(indirectOffsets),	indirectOffsetWeigths) * drawCommandSize;
21753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		spec.baseVertex				= random.chooseWeighted<int, const int*, const float*>	(DE_ARRAY_BEGIN(baseVertices),		DE_ARRAY_END(baseVertices),		baseVertexWeigths);
21763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// check spec is legal
21783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!spec.valid())
21793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
21803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int attrNdx = 0; attrNdx < attributeCount;)
21823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool valid;
21843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gls::DrawTestSpec::AttributeSpec attribSpec;
21853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			attribSpec.inputType			= random.chooseWeighted<gls::DrawTestSpec::InputType>	(DE_ARRAY_BEGIN(inputTypes),		DE_ARRAY_END(inputTypes),		inputTypeWeights.weights);
21873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			attribSpec.outputType			= random.chooseWeighted<gls::DrawTestSpec::OutputType>	(DE_ARRAY_BEGIN(outputTypes),		DE_ARRAY_END(outputTypes),		outputTypeWeights.weights);
21883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			attribSpec.storage				= gls::DrawTestSpec::STORAGE_BUFFER;
21893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			attribSpec.usage				= random.chooseWeighted<gls::DrawTestSpec::Usage>		(DE_ARRAY_BEGIN(usages),			DE_ARRAY_END(usages),			usageWeights.weights);
21903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			attribSpec.componentCount		= random.getInt(1, 4);
21913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			attribSpec.offset				= random.chooseWeighted<int, const int*, const float*>(DE_ARRAY_BEGIN(offsets), DE_ARRAY_END(offsets), offsetWeights);
21923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			attribSpec.stride				= random.chooseWeighted<int, const int*, const float*>(DE_ARRAY_BEGIN(strides), DE_ARRAY_END(strides), strideWeights);
21933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			attribSpec.normalize			= random.getBool();
21943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			attribSpec.instanceDivisor		= random.chooseWeighted<int, const int*, const float*>(DE_ARRAY_BEGIN(instanceDivisors), DE_ARRAY_END(instanceDivisors), instanceDivisorWeights);
21953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			attribSpec.useDefaultAttribute	= random.getBool();
21963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// check spec is legal
21983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			valid = attribSpec.valid(spec.apiType);
21993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// we do not want interleaved elements. (Might result in some weird floating point values)
22013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (attribSpec.stride && attribSpec.componentCount * gls::DrawTestSpec::inputTypeSize(attribSpec.inputType) > attribSpec.stride)
22023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				valid = false;
22033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// try again if not valid
22053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (valid)
22063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
22073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.attribs.push_back(attribSpec);
22083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				++attrNdx;
22093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
22103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Do not collapse all vertex positions to a single positions
22133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (spec.primitive != gls::DrawTestSpec::PRIMITIVE_POINTS)
22143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			spec.attribs[0].instanceDivisor = 0;
22153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Is render result meaningful?
22173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Only one vertex
22193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (spec.drawMethod == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED && spec.indexMin == spec.indexMax && spec.primitive != gls::DrawTestSpec::PRIMITIVE_POINTS)
22203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				continue;
22213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (spec.attribs[0].useDefaultAttribute && spec.primitive != gls::DrawTestSpec::PRIMITIVE_POINTS)
22223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				continue;
22233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Triangle only on one axis
22253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (spec.primitive == gls::DrawTestSpec::PRIMITIVE_TRIANGLES || spec.primitive == gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN || spec.primitive == gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP)
22263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
22273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (spec.attribs[0].componentCount == 1)
22283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					continue;
22293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (spec.attribs[0].outputType == gls::DrawTestSpec::OUTPUTTYPE_FLOAT || spec.attribs[0].outputType == gls::DrawTestSpec::OUTPUTTYPE_INT || spec.attribs[0].outputType == gls::DrawTestSpec::OUTPUTTYPE_UINT)
22303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					continue;
22313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (spec.drawMethod == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED && (spec.indexMax - spec.indexMin) < 2)
22323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					continue;
22333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
22343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Add case
22373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32 hash = spec.hash();
22393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int attrNdx = 0; attrNdx < attributeCount; ++attrNdx)
22403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				hash = (hash << 2) ^ (deUint32)spec.attribs[attrNdx].hash();
22413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (insertedHashes.find(hash) == insertedHashes.end())
22433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
22443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// Only aligned cases
22453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (spec.isCompatibilityTest() != gls::DrawTestSpec::COMPATIBILITY_UNALIGNED_OFFSET &&
22463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					spec.isCompatibilityTest() != gls::DrawTestSpec::COMPATIBILITY_UNALIGNED_STRIDE)
22473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					this->addChild(new gls::DrawTest(m_testCtx, m_context.getRenderContext(), spec, de::toString(insertedCount).c_str(), spec.getDesc().c_str()));
22483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				insertedHashes.insert(hash);
22493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				++insertedCount;
22513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
22523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
22543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass BadCommandBufferCase : public TestCase
22573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22583c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
22593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum
22603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
22613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CommandSize = 20
22623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
22633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					BadCommandBufferCase	(Context& context, const char* name, const char* desc, deUint32 alignment, deUint32 bufferSize, bool writeCommandToBuffer, deUint32 m_expectedError);
22653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					~BadCommandBufferCase	(void);
22663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult	iterate					(void);
22683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
22703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32	m_alignment;
22713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32	m_bufferSize;
22723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		m_writeCommandToBuffer;
22733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32	m_expectedError;
22743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
22753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22763c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBadCommandBufferCase::BadCommandBufferCase (Context& context, const char* name, const char* desc, deUint32 alignment, deUint32 bufferSize, bool writeCommandToBuffer, deUint32 expectedError)
22773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase					(context, name, desc)
22783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_alignment				(alignment)
22793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_bufferSize				(bufferSize)
22803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_writeCommandToBuffer	(writeCommandToBuffer)
22813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_expectedError			(expectedError)
22823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22853c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBadCommandBufferCase::~BadCommandBufferCase (void)
22863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22893c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBadCommandBufferCase::IterateResult	BadCommandBufferCase::iterate (void)
22903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4 vertexPositions[] =
22923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
22933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4(0,	0,		0, 1),
22943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4(1,	0,		0, 1),
22953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4(0,	1,		0, 1),
22963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
22973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint16 indices[] =
22993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		0, 2, 1,
23013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
23023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT(CommandSize == sizeof(DrawElementsCommand));
23043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sglr::GLContext gl(m_context.getRenderContext(), m_testCtx.getLog(), sglr::GLCONTEXT_LOG_CALLS, tcu::IVec4(0, 0, 1, 1));
23063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 vaoID			= 0;
23083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 positionBuf	= 0;
23093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 indexBuf		= 0;
23103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 drawIndirectBuf= 0;
23113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 error;
23123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::ShaderProgram	program			(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(s_commonVertexShaderSource) << glu::FragmentSource(s_commonFragmentShaderSource));
23143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32			programID		= program.getProgram();
23153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deInt32				posLocation		= gl.getAttribLocation(programID, "a_position");
23163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DrawElementsCommand drawCommand;
23183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawCommand.count				= 3;
23193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawCommand.primCount			= 1;
23203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawCommand.firstIndex			= 0;
23213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawCommand.baseVertex			= 0;
23223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawCommand.reservedMustBeZero	= 0;
23233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<deInt8> drawCommandBuffer;
23253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawCommandBuffer.resize(m_bufferSize);
23263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMemset(&drawCommandBuffer[0], 0, (int)drawCommandBuffer.size());
23283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_writeCommandToBuffer)
23303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(drawCommandBuffer.size() >= sizeof(drawCommand) + m_alignment);
23323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMemcpy(&drawCommandBuffer[m_alignment], &drawCommand, sizeof(drawCommand));
23333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
23343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::checkError(gl.getError(), "", __FILE__, __LINE__);
23363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.genVertexArrays(1, &vaoID);
23373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindVertexArray(vaoID);
23383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.genBuffers(1, &positionBuf);
23403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindBuffer(GL_ARRAY_BUFFER, positionBuf);
23413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
23423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
23433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.vertexAttribDivisor(posLocation, 0);
23443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.enableVertexAttribArray(posLocation);
23453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::checkError(gl.getError(), "", __FILE__, __LINE__);
23463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.genBuffers(1, &indexBuf);
23483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuf);
23493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
23503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::checkError(gl.getError(), "", __FILE__, __LINE__);
23513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.genBuffers(1, &drawIndirectBuf);
23533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindBuffer(GL_DRAW_INDIRECT_BUFFER, drawIndirectBuf);
23543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bufferData(GL_DRAW_INDIRECT_BUFFER, drawCommandBuffer.size(), &drawCommandBuffer[0], GL_STATIC_DRAW);
23553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::checkError(gl.getError(), "", __FILE__, __LINE__);
23563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.viewport(0, 0, 1, 1);
23583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.useProgram(programID);
23603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.drawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (const void*)(deUintptr)m_alignment);
23613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	error = gl.getError();
23633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.useProgram(0);
23653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.deleteBuffers(1, &drawIndirectBuf);
23673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.deleteBuffers(1, &indexBuf);
23683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.deleteBuffers(1, &positionBuf);
23693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.deleteVertexArrays(1, &vaoID);
23703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << tcu::TestLog::Message << "drawElementsIndirect generated " << glu::getErrorStr(error) << ", expecting " << glu::getErrorStr(m_expectedError) << "." << tcu::TestLog::EndMessage;
23723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (error == m_expectedError)
23743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
23753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
23763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "\tUnexpected error." << tcu::TestLog::EndMessage;
23783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unexpected error.");
23793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
23803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
23823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass BadAlignmentCase : public BadCommandBufferCase
23853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23863c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
23873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					BadAlignmentCase	(Context& context, const char* name, const char* desc, deUint32 alignment);
23883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					~BadAlignmentCase	(void);
23893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
23903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23913c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBadAlignmentCase::BadAlignmentCase (Context& context, const char* name, const char* desc, deUint32 alignment)
23923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: BadCommandBufferCase(context, name, desc, alignment, CommandSize+alignment, true, GL_INVALID_VALUE)
23933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23963c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBadAlignmentCase::~BadAlignmentCase (void)
23973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24003c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass BadBufferRangeCase : public BadCommandBufferCase
24013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24023c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
24033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					BadBufferRangeCase	(Context& context, const char* name, const char* desc, deUint32 offset);
24043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					~BadBufferRangeCase	(void);
24053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
24063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24073c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBadBufferRangeCase::BadBufferRangeCase (Context& context, const char* name, const char* desc, deUint32 offset)
24083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: BadCommandBufferCase(context, name, desc, offset, CommandSize, false, GL_INVALID_OPERATION)
24093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24123c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBadBufferRangeCase::~BadBufferRangeCase (void)
24133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24163c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass BadStateCase : public TestCase
24173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24183c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
24193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum CaseType
24203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASE_CLIENT_BUFFER_VERTEXATTR = 0,
24223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASE_CLIENT_BUFFER_COMMAND,
24233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASE_DEFAULT_VAO,
24243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASE_CLIENT_LAST
24263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
24273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						BadStateCase	(Context& context, const char* name, const char* desc, CaseType type);
24293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						~BadStateCase	(void);
24303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				init			(void);
24323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				deinit			(void);
24333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult		iterate			(void);
24343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
24363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CaseType		m_caseType;
24373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
24383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24393c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBadStateCase::BadStateCase (Context& context, const char* name, const char* desc, CaseType type)
24403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase			(context, name, desc)
24413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_caseType		(type)
24423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(type < CASE_CLIENT_LAST);
24443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24463c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBadStateCase::~BadStateCase (void)
24473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
24493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid BadStateCase::init (void)
24523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid BadStateCase::deinit (void)
24563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24593c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBadStateCase::IterateResult BadStateCase::iterate (void)
24603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4 vertexPositions[] =
24623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
24643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
24653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
24663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
24673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint16 indices[] =
24693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		0, 2, 1,
24713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
24723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sglr::GLContext gl(m_context.getRenderContext(), m_testCtx.getLog(), sglr::GLCONTEXT_LOG_CALLS, tcu::IVec4(0, 0, 1, 1));
24743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32			error;
24763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::ShaderProgram	program			(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(s_commonVertexShaderSource) << glu::FragmentSource(s_commonFragmentShaderSource));
24773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32			vaoID			= 0;
24783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32			dataBufferID	= 0;
24793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32			indexBufferID	= 0;
24803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32			cmdBufferID		= 0;
24813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32		programID		= program.getProgram();
24833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deInt32		posLocation		= gl.getAttribLocation(programID, "a_position");
24843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DrawElementsCommand drawCommand;
24863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawCommand.count				= 3;
24873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawCommand.primCount			= 1;
24883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawCommand.firstIndex			= 0;
24893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawCommand.baseVertex			= 0;
24903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawCommand.reservedMustBeZero	= 0;
24913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::checkError(gl.getError(), "", __FILE__, __LINE__);
24933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_caseType == CASE_CLIENT_BUFFER_VERTEXATTR)
24953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \note We use default VAO since we use client pointers. Trying indirect draw with default VAO is also an error. => This test does two illegal operations
24973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, vertexPositions);
24993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enableVertexAttribArray(posLocation);
25003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::checkError(gl.getError(), "", __FILE__, __LINE__);
25013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
25023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_caseType == CASE_CLIENT_BUFFER_COMMAND)
25033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.genVertexArrays(1, &vaoID);
25053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindVertexArray(vaoID);
25063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.genBuffers(1, &dataBufferID);
25083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindBuffer(GL_ARRAY_BUFFER, dataBufferID);
25093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
25103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
25113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enableVertexAttribArray(posLocation);
25123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::checkError(gl.getError(), "", __FILE__, __LINE__);
25133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
25143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_caseType == CASE_DEFAULT_VAO)
25153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.genBuffers(1, &dataBufferID);
25173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindBuffer(GL_ARRAY_BUFFER, dataBufferID);
25183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
25193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
25203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.enableVertexAttribArray(posLocation);
25213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::checkError(gl.getError(), "", __FILE__, __LINE__);
25223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
25233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
25243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(DE_FALSE);
25253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.genBuffers(1, &indexBufferID);
25273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
25283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
25293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::checkError(gl.getError(), "", __FILE__, __LINE__);
25303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_caseType != CASE_CLIENT_BUFFER_COMMAND)
25323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.genBuffers(1, &cmdBufferID);
25343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindBuffer(GL_DRAW_INDIRECT_BUFFER, cmdBufferID);
25353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(drawCommand), &drawCommand, GL_STATIC_DRAW);
25363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::checkError(gl.getError(), "", __FILE__, __LINE__);
25373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
25383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.viewport(0, 0, 1, 1);
25403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.useProgram(programID);
25423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.drawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (m_caseType != CASE_CLIENT_BUFFER_COMMAND) ? (DE_NULL) : (&drawCommand));
25433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	error = gl.getError();
25453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindVertexArray(0);
25473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.useProgram(0);
25483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (error == GL_INVALID_OPERATION)
25503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
25513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
25523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Unexpected error. Expected GL_INVALID_OPERATION, got " << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
25543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unexpected error.");
25553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
25563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
25583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
25593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass BadDrawModeCase : public TestCase
25613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
25623c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
25633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum DrawType
25643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DRAW_ARRAYS = 0,
25663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DRAW_ELEMENTS,
25673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DRAW_ELEMENTS_BAD_INDEX,
25683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DRAW_LAST
25703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
25713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						BadDrawModeCase	(Context& context, const char* name, const char* desc, DrawType type);
25733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						~BadDrawModeCase(void);
25743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				init			(void);
25763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				deinit			(void);
25773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult		iterate			(void);
25783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25793c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
25803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const DrawType		m_drawType;
25813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
25823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25833c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBadDrawModeCase::BadDrawModeCase (Context& context, const char* name, const char* desc, DrawType type)
25843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase			(context, name, desc)
25853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_drawType		(type)
25863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
25873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(type < DRAW_LAST);
25883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
25893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25903c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBadDrawModeCase::~BadDrawModeCase (void)
25913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
25923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
25933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
25943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25953c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid BadDrawModeCase::init (void)
25963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
25973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
25983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25993c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid BadDrawModeCase::deinit (void)
26003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26033c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBadDrawModeCase::IterateResult BadDrawModeCase::iterate (void)
26043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4 vertexPositions[] =
26063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
26073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
26083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
26093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
26103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
26113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint16 indices[] =
26133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
26143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		0, 2, 1,
26153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
26163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26178852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	sglr::GLContext		gl				(m_context.getRenderContext(), m_testCtx.getLog(), sglr::GLCONTEXT_LOG_CALLS, tcu::IVec4(0, 0, 1, 1));
26183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32			error;
26203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::ShaderProgram	program			(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(s_commonVertexShaderSource) << glu::FragmentSource(s_commonFragmentShaderSource));
26213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32			vaoID			= 0;
26223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32			dataBufferID	= 0;
26233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32			indexBufferID	= 0;
26243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32			cmdBufferID		= 0;
26253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32		programID		= program.getProgram();
26273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deInt32		posLocation		= gl.getAttribLocation(programID, "a_position");
26283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::GLenum	mode			= (m_drawType == DRAW_ELEMENTS_BAD_INDEX) ? (GL_TRIANGLES) : (0x123);
26293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::GLenum	indexType		= (m_drawType == DRAW_ELEMENTS_BAD_INDEX) ? (0x123) : (GL_UNSIGNED_SHORT);
26303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::checkError(gl.getError(), "", __FILE__, __LINE__);
26323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// vao
26343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.genVertexArrays(1, &vaoID);
26363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindVertexArray(vaoID);
26373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// va
26393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.genBuffers(1, &dataBufferID);
26413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindBuffer(GL_ARRAY_BUFFER, dataBufferID);
26423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
26433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
26443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.enableVertexAttribArray(posLocation);
26453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::checkError(gl.getError(), "", __FILE__, __LINE__);
26463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// index
26483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26498852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	if (m_drawType == DRAW_ELEMENTS || m_drawType == DRAW_ELEMENTS_BAD_INDEX)
26503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
26513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.genBuffers(1, &indexBufferID);
26523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
26533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
26543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::checkError(gl.getError(), "", __FILE__, __LINE__);
26553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
26563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// cmd
26583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.genBuffers(1, &cmdBufferID);
26603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindBuffer(GL_DRAW_INDIRECT_BUFFER, cmdBufferID);
26613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_drawType == DRAW_ELEMENTS || m_drawType == DRAW_ELEMENTS_BAD_INDEX)
26623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
26633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DrawElementsCommand drawCommand;
26643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		drawCommand.count				= 3;
26653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		drawCommand.primCount			= 1;
26663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		drawCommand.firstIndex			= 0;
26673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		drawCommand.baseVertex			= 0;
26683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		drawCommand.reservedMustBeZero	= 0;
26693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(drawCommand), &drawCommand, GL_STATIC_DRAW);
26713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
26723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_drawType == DRAW_ARRAYS)
26733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
26743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DrawArraysCommand drawCommand;
26753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		drawCommand.count				= 3;
26763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		drawCommand.primCount			= 1;
26773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		drawCommand.first				= 0;
26783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		drawCommand.reservedMustBeZero	= 0;
26793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(drawCommand), &drawCommand, GL_STATIC_DRAW);
26813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
26823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
26833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(DE_FALSE);
26843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::checkError(gl.getError(), "", __FILE__, __LINE__);
26853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.viewport(0, 0, 1, 1);
26873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.useProgram(programID);
26883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_drawType == DRAW_ELEMENTS || m_drawType == DRAW_ELEMENTS_BAD_INDEX)
26893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.drawElementsIndirect(mode, indexType, DE_NULL);
26903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_drawType == DRAW_ARRAYS)
26913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.drawArraysIndirect(mode, DE_NULL);
26923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
26933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(DE_FALSE);
26943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	error = gl.getError();
26963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.useProgram(0);
26973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (error == GL_INVALID_ENUM)
26993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
27003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
27013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
27023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << tcu::TestLog::Message << "Unexpected error. Expected GL_INVALID_ENUM, got " << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
27033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unexpected error.");
27043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
27053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
27073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27093c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass NegativeGroup : public TestCaseGroup
27103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27113c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
27123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			NegativeGroup	(Context& context, const char* name, const char* descr);
27133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			~NegativeGroup	(void);
27143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void	init			(void);
27163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
27173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27183c827367444ee418f129b2c238299f49d3264554Jarkko PoyryNegativeGroup::NegativeGroup (Context& context, const char* name, const char* descr)
27193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup	(context, name, descr)
27203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27233c827367444ee418f129b2c238299f49d3264554Jarkko PoyryNegativeGroup::~NegativeGroup (void)
27243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27273c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid NegativeGroup::init (void)
27283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// invalid alignment
27303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new BadAlignmentCase	(m_context, "command_bad_alignment_1",								"Bad command alignment",					1));
27313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new BadAlignmentCase	(m_context, "command_bad_alignment_2",								"Bad command alignment",					2));
27323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new BadAlignmentCase	(m_context, "command_bad_alignment_3",								"Bad command alignment",					3));
27333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// command only partially or not at all in the buffer
27353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new BadBufferRangeCase	(m_context, "command_offset_partially_in_buffer",					"Command not fully in the buffer range",	BadBufferRangeCase::CommandSize - 16));
27363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new BadBufferRangeCase	(m_context, "command_offset_not_in_buffer",							"Command not in the buffer range",			BadBufferRangeCase::CommandSize));
27373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new BadBufferRangeCase	(m_context, "command_offset_not_in_buffer_unsigned32_wrap",			"Command not in the buffer range",			0xFFFFFFFC));
27383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new BadBufferRangeCase	(m_context, "command_offset_not_in_buffer_signed32_wrap",			"Command not in the buffer range",			0x7FFFFFFC));
27393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// use with client data and default vao
27413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new BadStateCase		(m_context, "client_vertex_attrib_array",							"Vertex attrib array in the client memory",	BadStateCase::CASE_CLIENT_BUFFER_VERTEXATTR));
27423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new BadStateCase		(m_context, "client_command_array",									"Command array in the client memory",		BadStateCase::CASE_CLIENT_BUFFER_COMMAND));
27433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new BadStateCase		(m_context, "default_vao",											"Use with default vao",						BadStateCase::CASE_DEFAULT_VAO));
27443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// invalid mode & type
27463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new BadDrawModeCase	(m_context, "invalid_mode_draw_arrays",								"Call DrawArraysIndirect with bad mode",	BadDrawModeCase::DRAW_ARRAYS));
27473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new BadDrawModeCase	(m_context, "invalid_mode_draw_elements",							"Call DrawelementsIndirect with bad mode",	BadDrawModeCase::DRAW_ELEMENTS));
27483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(new BadDrawModeCase	(m_context, "invalid_type_draw_elements",							"Call DrawelementsIndirect with bad type",	BadDrawModeCase::DRAW_ELEMENTS_BAD_INDEX));
27493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
27523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27533c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDrawTests::DrawTests (Context& context)
27543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup(context, "draw_indirect", "Indirect drawing tests")
27553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27583c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDrawTests::~DrawTests (void)
27593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid DrawTests::init (void)
27633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Basic
27653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
27663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const gls::DrawTestSpec::DrawMethod basicMethods[] =
27673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
27683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS_INDIRECT,
27693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INDIRECT,
27703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
27713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(basicMethods); ++ndx)
27733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
27743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const std::string name = gls::DrawTestSpec::drawMethodToString(basicMethods[ndx]);
27753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const std::string desc = gls::DrawTestSpec::drawMethodToString(basicMethods[ndx]);
27763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			this->addChild(new MethodGroup(m_context, name.c_str(), desc.c_str(), basicMethods[ndx]));
27783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
27793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
27803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// extreme instancing
27823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	this->addChild(new InstancingGroup(m_context, "instancing", "draw tests with a large instance count."));
27843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// compute shader generated commands
27863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	this->addChild(new ComputeShaderGeneratedGroup(m_context, "compute_interop", "draw tests with a draw command generated in compute shader."));
27883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Random
27903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	this->addChild(new RandomGroup(m_context, "random", "random draw commands."));
27923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// negative
27943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	this->addChild(new NegativeGroup(m_context, "negative", "invalid draw commands with defined error codes."));
27963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional
27993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles31
28003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
2801