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 Basic Compute Shader Tests.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es31fAtomicCounterTests.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderProgram.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluObjectWrapper.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluRenderContext.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp"
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp"
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMemory.h"
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <vector>
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <string>
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace glw;
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog;
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles31
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass AtomicCounterTest : public TestCase
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum Operation
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		OPERATION_INC = (1<<0),
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		OPERATION_DEC = (1<<1),
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		OPERATION_GET = (1<<2)
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum OffsetType
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		OFFSETTYPE_NONE = 0,
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		OFFSETTYPE_BASIC,
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		OFFSETTYPE_REVERSE,
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		OFFSETTYPE_FIRST_AUTO,
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		OFFSETTYPE_DEFAULT_AUTO,
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		OFFSETTYPE_RESET_DEFAULT,
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		OFFSETTYPE_INVALID,
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		OFFSETTYPE_INVALID_OVERLAPPING,
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		OFFSETTYPE_INVALID_DEFAULT
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum BindingType
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		BINDINGTYPE_BASIC = 0,
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		BINDINGTYPE_INVALID,
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		BINDINGTYPE_INVALID_DEFAULT
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct TestSpec
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestSpec (void)
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: atomicCounterCount	(0)
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, operations			((Operation)0)
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, callCount				(0)
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, useBranches			(false)
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, threadCount			(0)
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, offsetType			(OFFSETTYPE_NONE)
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, bindingType			(BINDINGTYPE_BASIC)
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int			atomicCounterCount;
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Operation	operations;
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int			callCount;
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool		useBranches;
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int			threadCount;
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		OffsetType	offsetType;
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		BindingType	bindingType;
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						AtomicCounterTest		(Context& context, const char* name, const char* description, const TestSpec& spec);
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						~AtomicCounterTest		(void);
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				init						(void);
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				deinit						(void);
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult		iterate						(void);
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const TestSpec		m_spec;
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				checkAndLogCounterValues	(TestLog& log, const vector<deUint32>& counters) const;
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				checkAndLogCallValues		(TestLog& log, const vector<deUint32>& increments, const vector<deUint32>& decrements, const vector<deUint32>& preGets, const vector<deUint32>& postGets, const vector<deUint32>& gets) const;
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				splitBuffer					(const vector<deUint32>& buffer, vector<deUint32>& increments, vector<deUint32>& decrements, vector<deUint32>& preGets, vector<deUint32>& postGets, vector<deUint32>& gets) const;
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32			getInitialValue				(void) const { return m_spec.callCount * m_spec.threadCount + 1; }
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static string		generateShaderSource		(const TestSpec& spec);
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void			getCountersValues			(vector<deUint32>& counterValues, const vector<deUint32>& values, int ndx, int counterCount);
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static bool			checkRange					(TestLog& log, const vector<deUint32>& values, const vector<deUint32>& min, const vector<deUint32>& max);
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static bool			checkUniquenessAndLinearity	(TestLog& log, const vector<deUint32>& values);
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static bool			checkPath					(const vector<deUint32>& increments, const vector<deUint32>& decrements, int initialValue, const TestSpec& spec);
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					getOperationCount			(void) const;
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	AtomicCounterTest&	operator=					(const AtomicCounterTest&);
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						AtomicCounterTest			(const AtomicCounterTest&);
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint AtomicCounterTest::getOperationCount (void) const
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int count = 0;
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_spec.operations & OPERATION_INC)
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		count++;
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_spec.operations & OPERATION_DEC)
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		count++;
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_spec.operations == OPERATION_GET)
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		count++;
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_spec.operations & OPERATION_GET)
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		count += 2;
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return count;
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1543c827367444ee418f129b2c238299f49d3264554Jarkko PoyryAtomicCounterTest::AtomicCounterTest (Context& context, const char* name, const char* description, const TestSpec& spec)
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase	(context, name, description)
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_spec	(spec)
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1603c827367444ee418f129b2c238299f49d3264554Jarkko PoyryAtomicCounterTest::~AtomicCounterTest (void)
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid AtomicCounterTest::init (void)
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid AtomicCounterTest::deinit (void)
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring AtomicCounterTest::generateShaderSource (const TestSpec& spec)
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream src;
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	src
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<<  "#version 310 es\n"
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n";
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool wroteLayout = false;
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (spec.bindingType)
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case BINDINGTYPE_INVALID_DEFAULT:
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				src << "layout(binding=10000";
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				wroteLayout = true;
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// Do nothing
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (spec.offsetType)
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case OFFSETTYPE_DEFAULT_AUTO:
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (!wroteLayout)
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					src << "layout(binding=1, ";
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					src << ", ";
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				src << "offset=4";
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				wroteLayout = true;
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case OFFSETTYPE_RESET_DEFAULT:
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(spec.atomicCounterCount > 2);
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (!wroteLayout)
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					src << "layout(binding=1, ";
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					src << ", ";
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				src << "offset=" << (4 * spec.atomicCounterCount/2);
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				wroteLayout = true;
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case OFFSETTYPE_INVALID_DEFAULT:
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (!wroteLayout)
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					src << "layout(binding=1, ";
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					src << ", ";
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				src << "offset=1";
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				wroteLayout = true;
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// Do nothing
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (wroteLayout)
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			src << ") uniform atomic_uint;\n";
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	src
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	<< "layout(binding = 1, std430) buffer Output {\n";
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((spec.operations & OPERATION_GET) != 0 && spec.operations != OPERATION_GET)
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		src << "	uint preGet[" << spec.threadCount * spec.atomicCounterCount * spec.callCount << "];\n";
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((spec.operations & OPERATION_INC) != 0)
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		src << "	uint increment[" << spec.threadCount * spec.atomicCounterCount * spec.callCount << "];\n";
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((spec.operations & OPERATION_DEC) != 0)
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		src << "	uint decrement[" << spec.threadCount * spec.atomicCounterCount * spec.callCount << "];\n";
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((spec.operations & OPERATION_GET) != 0 && spec.operations != OPERATION_GET)
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		src << "	uint postGet[" << spec.threadCount * spec.atomicCounterCount * spec.callCount << "];\n";
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (spec.operations == OPERATION_GET)
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		src << "	uint get[" << spec.threadCount * spec.atomicCounterCount * spec.callCount << "];\n";
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	src << "} sb_in;\n\n";
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int counterNdx = 0; counterNdx < spec.atomicCounterCount; counterNdx++)
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool layoutStarted = false;
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (spec.offsetType == OFFSETTYPE_RESET_DEFAULT && counterNdx == spec.atomicCounterCount/2)
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			src << "layout(binding=1, offset=0) uniform atomic_uint;\n";
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (spec.bindingType)
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case BINDINGTYPE_BASIC:
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				layoutStarted = true;
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				src << "layout(binding=1";
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case BINDINGTYPE_INVALID:
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				layoutStarted = true;
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				src << "layout(binding=10000";
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case BINDINGTYPE_INVALID_DEFAULT:
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// Nothing
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(false);
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (spec.offsetType)
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case OFFSETTYPE_NONE:
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (layoutStarted)
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					src << ") ";
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				src << "uniform atomic_uint counter" << counterNdx << ";\n";
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case OFFSETTYPE_BASIC:
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (!layoutStarted)
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					src << "layout(";
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					src << ", ";
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				src << "offset=" << (counterNdx * 4) << ") uniform atomic_uint counter" << counterNdx << ";\n";
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case OFFSETTYPE_INVALID_DEFAULT:
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (layoutStarted)
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					src << ") ";
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				src << "uniform atomic_uint counter" << counterNdx << ";\n";
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case OFFSETTYPE_INVALID:
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (!layoutStarted)
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					src << "layout(";
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					src << ", ";
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				src << "offset=" << (1 + counterNdx * 2) << ") uniform atomic_uint counter" << counterNdx << ";\n";
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case OFFSETTYPE_INVALID_OVERLAPPING:
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (!layoutStarted)
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					src << "layout(";
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					src << ", ";
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				src << "offset=0) uniform atomic_uint counter" << counterNdx << ";\n";
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case OFFSETTYPE_REVERSE:
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (!layoutStarted)
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					src << "layout(";
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					src << ", ";
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				src << "offset=" << (spec.atomicCounterCount - counterNdx - 1) * 4 << ") uniform atomic_uint counter" << (spec.atomicCounterCount - counterNdx - 1) << ";\n";
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case OFFSETTYPE_FIRST_AUTO:
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(spec.atomicCounterCount > 2);
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (counterNdx + 1 == spec.atomicCounterCount)
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (!layoutStarted)
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						src << "layout(";
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					else
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						src << ", ";
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					src << "offset=0) uniform atomic_uint counter0;\n";
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else if (counterNdx == 0)
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (!layoutStarted)
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						src << "layout(";
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					else
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						src << ", ";
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					src << "offset=4) uniform atomic_uint counter1;\n";
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (layoutStarted)
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						src << ") ";
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					src << "uniform atomic_uint counter" << (counterNdx + 1) << ";\n";
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case OFFSETTYPE_DEFAULT_AUTO:
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (counterNdx + 1 == spec.atomicCounterCount)
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (!layoutStarted)
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						src << "layout(";
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					else
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						src << ", ";
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					src << "offset=0) uniform atomic_uint counter0;\n";
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (layoutStarted)
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						src << ") ";
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					src << "uniform atomic_uint counter" << (counterNdx + 1) << ";\n";
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case OFFSETTYPE_RESET_DEFAULT:
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (layoutStarted)
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					src << ") ";
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (counterNdx < spec.atomicCounterCount/2)
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					src << "uniform atomic_uint counter" << (counterNdx + spec.atomicCounterCount/2) << ";\n";
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					src << "uniform atomic_uint counter" << (counterNdx - spec.atomicCounterCount/2) << ";\n";
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(false);
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	src
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	<< "\n"
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	<< "void main (void)\n"
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	<< "{\n";
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (spec.callCount > 1)
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		src << "\tfor (uint i = 0u; i < " << spec.callCount << "u; i++)\n";
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	src
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	<< "\t{\n"
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	<< "\t\tuint id = (gl_GlobalInvocationID.x";
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (spec.callCount > 1)
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		src << " * "<< spec.callCount << "u";
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (spec.callCount > 1)
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		src << " + i)";
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		src << ")";
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if  (spec.atomicCounterCount > 1)
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		src << " * " << spec.atomicCounterCount << "u";
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	src << ";\n";
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int counterNdx = 0; counterNdx < spec.atomicCounterCount; counterNdx++)
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if ((spec.operations & OPERATION_GET) != 0 && spec.operations != OPERATION_GET)
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			src << "\t\tsb_in.preGet[id + " << counterNdx << "u] = atomicCounter(counter" << counterNdx << ");\n";
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (spec.useBranches && ((spec.operations & (OPERATION_INC|OPERATION_DEC)) == (OPERATION_INC|OPERATION_DEC)))
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			src
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "\t\tif (((gl_GlobalInvocationID.x" << (spec.callCount > 1 ? " + i" : "") << ") % 2u) == 0u)\n"
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "\t\t{\n"
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "\t\t\tsb_in.increment[id + " << counterNdx << "u] = atomicCounterIncrement(counter" << counterNdx << ");\n"
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "\t\t\tsb_in.decrement[id + " << counterNdx << "u] = uint(-1);\n"
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "\t\t}\n"
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "\t\telse\n"
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "\t\t{\n"
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "\t\t\tsb_in.decrement[id + " << counterNdx << "u] = atomicCounterDecrement(counter" << counterNdx << ") + 1u;\n"
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "\t\t\tsb_in.increment[id + " << counterNdx << "u] = uint(-1);\n"
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "\t\t}\n";
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if ((spec.operations & OPERATION_INC) != 0)
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (spec.useBranches)
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					src
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "\t\tif (((gl_GlobalInvocationID.x" << (spec.callCount > 1 ? " + i" : "") << ") % 2u) == 0u)\n"
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "\t\t{\n"
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "\t\t\tsb_in.increment[id + " << counterNdx << "u] = atomicCounterIncrement(counter" << counterNdx << ");\n"
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "\t\t}\n"
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "\t\telse\n"
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "\t\t{\n"
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "\t\t\tsb_in.increment[id + " << counterNdx << "u] = uint(-1);\n"
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "\t\t}\n";
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					src << "\t\tsb_in.increment[id + " << counterNdx << "u] = atomicCounterIncrement(counter" << counterNdx << ");\n";
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if ((spec.operations & OPERATION_DEC) != 0)
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (spec.useBranches)
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					src
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "\t\tif (((gl_GlobalInvocationID.x" << (spec.callCount > 1 ? " + i" : "") << ") % 2u) == 0u)\n"
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "\t\t{\n"
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "\t\t\tsb_in.decrement[id + " << counterNdx << "u] = atomicCounterDecrement(counter" << counterNdx << ") + 1u;\n"
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "\t\t}\n"
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "\t\telse\n"
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "\t\t{\n"
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "\t\t\tsb_in.decrement[id + " << counterNdx << "u] = uint(-1);\n"
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "\t\t}\n";
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					src << "\t\tsb_in.decrement[id + " << counterNdx << "u] = atomicCounterDecrement(counter" << counterNdx << ") + 1u;\n";
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if ((spec.operations & OPERATION_GET) != 0 && spec.operations != OPERATION_GET)
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			src << "\t\tsb_in.postGet[id + " << counterNdx << "u] = atomicCounter(counter" << counterNdx << ");\n";
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if ((spec.operations == OPERATION_GET) != 0)
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (spec.useBranches)
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				src
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "\t\tif (((gl_GlobalInvocationID.x" << (spec.callCount > 1 ? " + i" : "") << ") % 2u) == 0u)\n"
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "\t\t{\n"
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "\t\t\tsb_in.get[id + " << counterNdx << "u] = atomicCounter(counter" << counterNdx << ");\n"
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "\t\t}\n"
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "\t\telse\n"
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "\t\t{\n"
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "\t\t\tsb_in.get[id + " << counterNdx << "u] = uint(-1);\n"
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< "\t\t}\n";
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				src << "\t\tsb_in.get[id + " << counterNdx << "u] = atomicCounter(counter" << counterNdx << ");\n";
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	src
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	<< "\t}\n"
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	<< "}\n";
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return src.str();
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool AtomicCounterTest::checkAndLogCounterValues (TestLog& log, const vector<deUint32>& counters) const
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::ScopedLogSection	counterSection	(log, "Counter info", "Show initial value, current value and expected value of each counter.");
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					isOk			= true;
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check that atomic counters have sensible results
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int counterNdx = 0; counterNdx < (int)counters.size(); counterNdx++)
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint32	value			= counters[counterNdx];
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint32	initialValue	= getInitialValue();
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32		expectedValue	= (deUint32)-1;
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if ((m_spec.operations & OPERATION_INC) != 0 && (m_spec.operations & OPERATION_DEC) == 0)
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			expectedValue = initialValue + (m_spec.useBranches ? m_spec.threadCount*m_spec.callCount - m_spec.threadCount*m_spec.callCount/2 : m_spec.threadCount*m_spec.callCount);
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if ((m_spec.operations & OPERATION_INC) == 0 && (m_spec.operations & OPERATION_DEC) != 0)
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			expectedValue = initialValue - (m_spec.useBranches ? m_spec.threadCount*m_spec.callCount - m_spec.threadCount*m_spec.callCount/2 : m_spec.threadCount*m_spec.callCount);
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if ((m_spec.operations & OPERATION_INC) != 0 && (m_spec.operations & OPERATION_DEC) != 0)
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			expectedValue = initialValue + (m_spec.useBranches ? m_spec.threadCount*m_spec.callCount - m_spec.threadCount*m_spec.callCount/2 : 0) - (m_spec.useBranches ? m_spec.threadCount*m_spec.callCount/2 : 0);
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if ((m_spec.operations & OPERATION_INC) == 0 && (m_spec.operations & OPERATION_DEC) == 0)
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			expectedValue = initialValue;
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "atomic_uint counter" << counterNdx << " initial value: " << initialValue << ", value: " << value << ", expected: " << expectedValue << (value == expectedValue ? "" : ", failed!") << TestLog::EndMessage;
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (value != expectedValue)
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			isOk = false;
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return isOk;
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid AtomicCounterTest::splitBuffer (const vector<deUint32>& buffer, vector<deUint32>& increments, vector<deUint32>& decrements, vector<deUint32>& preGets, vector<deUint32>& postGets, vector<deUint32>& gets) const
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int bufferValueCount	= m_spec.callCount * m_spec.threadCount * m_spec.atomicCounterCount;
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int firstPreGet				= -1;
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int firstPostGet			= -1;
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int	firstGet				= -1;
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int firstInc				= -1;
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int firstDec				= -1;
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	increments.clear();
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	decrements.clear();
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	preGets.clear();
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	postGets.clear();
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gets.clear();
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_spec.operations == OPERATION_GET)
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		firstGet = 0;
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_spec.operations == OPERATION_INC)
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		firstInc = 0;
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_spec.operations == OPERATION_DEC)
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		firstDec = 0;
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_spec.operations == (OPERATION_GET|OPERATION_INC))
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		firstPreGet		= 0;
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		firstInc		= bufferValueCount;
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		firstPostGet	= bufferValueCount * 2;
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_spec.operations == (OPERATION_GET|OPERATION_DEC))
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		firstPreGet		= 0;
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		firstDec		= bufferValueCount;
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		firstPostGet	= bufferValueCount * 2;
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_spec.operations == (OPERATION_GET|OPERATION_DEC|OPERATION_INC))
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		firstPreGet		= 0;
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		firstInc		= bufferValueCount;
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		firstDec		= bufferValueCount * 2;
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		firstPostGet	= bufferValueCount * 3;
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_spec.operations == (OPERATION_DEC|OPERATION_INC))
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		firstInc		= 0;
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		firstDec		= bufferValueCount;
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(false);
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int threadNdx = 0; threadNdx < m_spec.threadCount; threadNdx++)
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int callNdx = 0; callNdx < m_spec.callCount; callNdx++)
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int counterNdx = 0; counterNdx < m_spec.atomicCounterCount; counterNdx++)
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int id = ((threadNdx * m_spec.callCount) + callNdx) * m_spec.atomicCounterCount + counterNdx;
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (firstInc != -1)
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					increments.push_back(buffer[firstInc + id]);
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (firstDec != -1)
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					decrements.push_back(buffer[firstDec + id]);
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (firstPreGet != -1)
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					preGets.push_back(buffer[firstPreGet + id]);
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (firstPostGet != -1)
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					postGets.push_back(buffer[firstPostGet + id]);
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (firstGet != -1)
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					gets.push_back(buffer[firstGet + id]);
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid AtomicCounterTest::getCountersValues (vector<deUint32>& counterValues, const vector<deUint32>& values, int ndx, int counterCount)
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	counterValues.resize(values.size()/counterCount, 0);
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(values.size() % counterCount == 0);
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int valueNdx = 0; valueNdx < (int)counterValues.size(); valueNdx++)
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		counterValues[valueNdx] = values[valueNdx * counterCount + ndx];
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool AtomicCounterTest::checkRange (TestLog& log, const vector<deUint32>& values, const vector<deUint32>& min, const vector<deUint32>& max)
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int failedCount = 0;
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(values.size() == min.size());
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(values.size() == max.size());
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int valueNdx = 0; valueNdx < (int)values.size(); valueNdx++)
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (values[valueNdx] != (deUint32)-1)
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!deInRange32(values[valueNdx], min[valueNdx], max[valueNdx]))
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (failedCount < 20)
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << TestLog::Message << "Value " << values[valueNdx] << " not in range [" << min[valueNdx] << ", " << max[valueNdx] << "]." << TestLog::EndMessage;
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				failedCount++;
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (failedCount > 20)
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Number of values not in range: " << failedCount << ", displaying first 20 values." << TestLog::EndMessage;
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return failedCount == 0;
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool AtomicCounterTest::checkUniquenessAndLinearity (TestLog& log, const vector<deUint32>& values)
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<deUint32>	counts;
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					failedCount	= 0;
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32			minValue	= (deUint32)-1;
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32			maxValue	= 0;
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!values.empty());
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int valueNdx = 0; valueNdx < (int)values.size(); valueNdx++)
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (values[valueNdx] != (deUint32)-1)
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			minValue = std::min(minValue, values[valueNdx]);
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			maxValue = std::max(maxValue, values[valueNdx]);
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	counts.resize(maxValue - minValue + 1, 0);
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int valueNdx = 0; valueNdx < (int)values.size(); valueNdx++)
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (values[valueNdx] != (deUint32)-1)
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			counts[values[valueNdx] - minValue]++;
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int countNdx = 0; countNdx < (int)counts.size(); countNdx++)
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (counts[countNdx] != 1)
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (failedCount < 20)
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "Value " << (minValue + countNdx) << " is not unique. Returned " << counts[countNdx] << " times." << TestLog::EndMessage;
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			failedCount++;
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (failedCount > 20)
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Number of values not unique: " << failedCount << ", displaying first 20 values." << TestLog::EndMessage;
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return failedCount == 0;
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool AtomicCounterTest::checkPath (const vector<deUint32>& increments, const vector<deUint32>& decrements, int initialValue, const TestSpec& spec)
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32		lastValue	= initialValue + (spec.useBranches ? spec.threadCount*spec.callCount - spec.threadCount*spec.callCount/2 : 0) - (spec.useBranches ? spec.threadCount*spec.callCount/2 : 0);
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				isOk		= true;
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<deUint32>	incrementCounts;
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<deUint32>	decrementCounts;
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32			minValue = 0xFFFFFFFFu;
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32			maxValue = 0;
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int valueNdx = 0; valueNdx < (int)increments.size(); valueNdx++)
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (increments[valueNdx] != (deUint32)-1)
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			minValue = std::min(minValue, increments[valueNdx]);
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			maxValue = std::max(maxValue, increments[valueNdx]);
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int valueNdx = 0; valueNdx < (int)decrements.size(); valueNdx++)
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (decrements[valueNdx] != (deUint32)-1)
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			minValue = std::min(minValue, decrements[valueNdx]);
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			maxValue = std::max(maxValue, decrements[valueNdx]);
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	minValue = std::min(minValue, (deUint32)initialValue);
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	maxValue = std::max(maxValue, (deUint32)initialValue);
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	incrementCounts.resize(maxValue - minValue + 1, 0);
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	decrementCounts.resize(maxValue - minValue + 1, 0);
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int valueNdx = 0; valueNdx < (int)increments.size(); valueNdx++)
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (increments[valueNdx] != (deUint32)-1)
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			incrementCounts[increments[valueNdx] - minValue]++;
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int valueNdx = 0; valueNdx < (int)decrements.size(); valueNdx++)
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (decrements[valueNdx] != (deUint32)-1)
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			decrementCounts[decrements[valueNdx] - minValue]++;
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int pos = initialValue - minValue;
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	while (incrementCounts[pos] + decrementCounts[pos] != 0)
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (incrementCounts[pos] > 0 && pos >= (int)(lastValue - minValue))
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// If can increment and incrementation would move us away from result value, increment
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			incrementCounts[pos]--;
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			pos++;
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (decrementCounts[pos] > 0)
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// If can, decrement
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			decrementCounts[pos]--;
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			pos--;
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (incrementCounts[pos] > 0)
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// If increment moves closer to result value and can't decrement, increment
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			incrementCounts[pos]--;
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			pos++;
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (pos < 0 || pos >= (int)incrementCounts.size())
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (minValue + pos != lastValue)
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		isOk = false;
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int valueNdx = 0; valueNdx < (int)incrementCounts.size(); valueNdx++)
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (incrementCounts[valueNdx] != 0)
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			isOk = false;
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int valueNdx = 0; valueNdx < (int)decrementCounts.size(); valueNdx++)
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (decrementCounts[valueNdx] != 0)
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			isOk = false;
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return isOk;
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool AtomicCounterTest::checkAndLogCallValues (TestLog& log, const vector<deUint32>& increments, const vector<deUint32>& decrements, const vector<deUint32>& preGets, const vector<deUint32>& postGets, const vector<deUint32>& gets) const
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool isOk = true;
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int counterNdx = 0; counterNdx < m_spec.atomicCounterCount; counterNdx++)
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<deUint32> counterIncrements;
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<deUint32> counterDecrements;
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<deUint32> counterPreGets;
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<deUint32> counterPostGets;
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<deUint32> counterGets;
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		getCountersValues(counterIncrements,	increments,	counterNdx, m_spec.atomicCounterCount);
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		getCountersValues(counterDecrements,	decrements,	counterNdx, m_spec.atomicCounterCount);
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		getCountersValues(counterPreGets,		preGets,	counterNdx, m_spec.atomicCounterCount);
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		getCountersValues(counterPostGets,		postGets,	counterNdx, m_spec.atomicCounterCount);
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		getCountersValues(counterGets,			gets,		counterNdx, m_spec.atomicCounterCount);
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_spec.operations == OPERATION_GET)
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::ScopedLogSection valueCheck(log, ("counter" + de::toString(counterNdx) + " value check").c_str(), ("Check that counter" + de::toString(counterNdx) + " values haven't changed.").c_str());
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int changedValues = 0;
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int valueNdx = 0; valueNdx < (int)gets.size(); valueNdx++)
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if ((!m_spec.useBranches || gets[valueNdx] != (deUint32)-1) && gets[valueNdx] != getInitialValue())
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (changedValues < 20)
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						log << TestLog::Message << "atomicCounter(counter" << counterNdx << ") returned " << gets[valueNdx] << " expected " << getInitialValue() << TestLog::EndMessage;
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					isOk = false;
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					changedValues++;
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (changedValues == 0)
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "All values returned by atomicCounter(counter" << counterNdx << ") match initial value " << getInitialValue() <<  "." << TestLog::EndMessage;
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (changedValues > 20)
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "Total number of invalid values returned by atomicCounter(counter" << counterNdx << ") " << changedValues << " displaying first 20 values." <<  TestLog::EndMessage;
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if ((m_spec.operations & (OPERATION_INC|OPERATION_DEC)) == (OPERATION_INC|OPERATION_DEC))
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::ScopedLogSection valueCheck(log, ("counter" + de::toString(counterNdx) + " path check").c_str(), ("Check that there is order in which counter" + de::toString(counterNdx) + " increments and decrements could have happened.").c_str());
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!checkPath(counterIncrements, counterDecrements, getInitialValue(), m_spec))
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				isOk = false;
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "No possible order of calls to atomicCounterIncrement(counter" << counterNdx << ") and atomicCounterDecrement(counter" << counterNdx << ") found." << TestLog::EndMessage;
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "Found possible order of calls to atomicCounterIncrement(counter" << counterNdx << ") and atomicCounterDecrement(counter" << counterNdx << ")." << TestLog::EndMessage;
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if ((m_spec.operations & OPERATION_INC) != 0)
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::ScopedLogSection uniquenesCheck(log, ("counter" + de::toString(counterNdx) + " check uniqueness and linearity").c_str(), ("Check that counter" + de::toString(counterNdx) + " returned only unique and linear values.").c_str());
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (!checkUniquenessAndLinearity(log, counterIncrements))
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					isOk = false;
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << TestLog::Message << "atomicCounterIncrement(counter" << counterNdx << ") returned non unique values." << TestLog::EndMessage;
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << TestLog::Message << "atomicCounterIncrement(counter" << counterNdx << ") returned only unique values." << TestLog::EndMessage;
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isOk && ((m_spec.operations & OPERATION_GET) != 0))
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::ScopedLogSection uniquenesCheck(log, ("counter" + de::toString(counterNdx) + " check range").c_str(), ("Check that counter" + de::toString(counterNdx) + " returned only values values between previous and next atomicCounter(counter" + de::toString(counterNdx) + ").").c_str());
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (!checkRange(log, counterIncrements, counterPreGets, counterPostGets))
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					isOk = false;
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << TestLog::Message << "atomicCounterIncrement(counter" << counterNdx << ") returned value that is not between previous and next call to atomicCounter(counter" << counterNdx << ")." << TestLog::EndMessage;
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << TestLog::Message << "atomicCounterIncrement(counter" << counterNdx << ") returned only values between previous and next call to atomicCounter(counter" << counterNdx << ")." << TestLog::EndMessage;
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if ((m_spec.operations & OPERATION_DEC) != 0)
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::ScopedLogSection uniquenesCheck(log, ("counter" + de::toString(counterNdx) + " check uniqueness and linearity").c_str(), ("Check that counter" + de::toString(counterNdx) + " returned only unique and linear values.").c_str());
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (!checkUniquenessAndLinearity(log, counterDecrements))
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					isOk = false;
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << TestLog::Message << "atomicCounterDecrement(counter" << counterNdx << ") returned non unique values." << TestLog::EndMessage;
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << TestLog::Message << "atomicCounterDecrement(counter" << counterNdx << ") returned only unique values." << TestLog::EndMessage;
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isOk && ((m_spec.operations & OPERATION_GET) != 0))
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::ScopedLogSection uniquenesCheck(log, ("counter" + de::toString(counterNdx) + " check range").c_str(), ("Check that counter" + de::toString(counterNdx) + " returned only values values between previous and next atomicCounter(counter" + de::toString(counterNdx) + ".").c_str());
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (!checkRange(log, counterDecrements, counterPostGets, counterPreGets))
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					isOk = false;
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << TestLog::Message << "atomicCounterDecrement(counter" << counterNdx << ") returned value that is not between previous and next call to atomicCounter(counter" << counterNdx << ")." << TestLog::EndMessage;
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << TestLog::Message << "atomicCounterDecrement(counter" << counterNdx << ") returned only values between previous and next call to atomicCounter(counter" << counterNdx << ")." << TestLog::EndMessage;
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return isOk;
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9153c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTestCase::IterateResult AtomicCounterTest::iterate (void)
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&		gl					= m_context.getRenderContext().getFunctions();
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&					log					= m_testCtx.getLog();
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::Buffer			counterBuffer		(m_context.getRenderContext());
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::Buffer			outputBuffer		(m_context.getRenderContext());
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::ShaderProgram	program				(m_context.getRenderContext(), glu::ProgramSources() << glu::ShaderSource(glu::SHADERTYPE_COMPUTE, generateShaderSource(m_spec)));
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deInt32				counterBufferSize	= m_spec.atomicCounterCount * 4;
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deInt32				ssoSize				= m_spec.atomicCounterCount * m_spec.callCount * m_spec.threadCount * 4 * getOperationCount();
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << program;
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_spec.offsetType == OFFSETTYPE_INVALID || m_spec.offsetType == OFFSETTYPE_INVALID_DEFAULT || m_spec.bindingType == BINDINGTYPE_INVALID || m_spec.bindingType == BINDINGTYPE_INVALID_DEFAULT || m_spec.offsetType == OFFSETTYPE_INVALID_OVERLAPPING)
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (program.isOk())
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Expected program to fail, but compilation passed." << TestLog::EndMessage;
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compile succeeded");
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return STOP;
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Compilation failed as expected." << TestLog::EndMessage;
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Compile failed");
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return STOP;
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (!program.isOk())
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Compile failed." << TestLog::EndMessage;
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compile failed");
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.useProgram(program.getProgram());
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create output buffer
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, *outputBuffer);
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bufferData(GL_SHADER_STORAGE_BUFFER, ssoSize, NULL, GL_STATIC_DRAW);
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create output buffer");
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create atomic counter buffer
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<deUint32> data(m_spec.atomicCounterCount, getInitialValue());
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, *counterBuffer);
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bufferData(GL_SHADER_STORAGE_BUFFER, counterBufferSize, &(data[0]), GL_STATIC_DRAW);
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create buffer for atomic counters");
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Bind output buffer
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, *outputBuffer);
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup output buffer");
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Bind atomic counter buffer
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 1, *counterBuffer);
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup atomic counter buffer");
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Dispath compute
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.dispatchCompute(m_spec.threadCount, 1, 1);
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute()");
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.finish();
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "glFinish()");
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<deUint32> output(ssoSize/4, 0);
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<deUint32> counters(m_spec.atomicCounterCount, 0);
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read back output buffer
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, *outputBuffer);
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		void* ptr = gl.mapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, (GLsizeiptr)(output.size() * sizeof(deUint32)), GL_MAP_READ_BIT);
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange()");
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMemcpy(&(output[0]), ptr, (int)output.size() * sizeof(deUint32));
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER))
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer()");
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK_MSG(false, "Mapped buffer corrupted");
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read back counter buffer
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, *counterBuffer);
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		void* ptr = gl.mapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, (GLsizeiptr)(counters.size() * sizeof(deUint32)), GL_MAP_READ_BIT);
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange()");
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMemcpy(&(counters[0]), ptr, (int)counters.size() * sizeof(deUint32));
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER))
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer()");
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK_MSG(false, "Mapped buffer corrupted");
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool isOk = true;
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!checkAndLogCounterValues(log, counters))
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		isOk = false;
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<deUint32> increments;
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<deUint32> decrements;
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<deUint32> preGets;
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<deUint32> postGets;
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<deUint32> gets;
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		splitBuffer(output, increments, decrements, preGets, postGets, gets);
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!checkAndLogCallValues(log, increments, decrements, preGets, postGets, gets))
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			isOk = false;
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isOk)
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring specToTestName (const AtomicCounterTest::TestSpec& spec)
10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream stream;
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	stream << spec.atomicCounterCount	<< (spec.atomicCounterCount == 1 ? "_counter" : "_counters");
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	stream << "_" << spec.callCount		<< (spec.callCount == 1 ? "_call" : "_calls");
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	stream << "_" << spec.threadCount	<< (spec.threadCount == 1 ? "_thread" : "_threads");
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return stream.str();
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring specToTestDescription (const AtomicCounterTest::TestSpec& spec)
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream	stream;
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				firstOperation = 0;
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	stream
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	<< "Test ";
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((spec.operations & AtomicCounterTest::OPERATION_GET) != 0)
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		stream << "atomicCounter()";
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		firstOperation = false;
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((spec.operations & AtomicCounterTest::OPERATION_INC) != 0)
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!firstOperation)
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			stream << ", ";
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		stream << " atomicCounterIncrement()";
10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		firstOperation = false;
10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((spec.operations & AtomicCounterTest::OPERATION_DEC) != 0)
10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!firstOperation)
10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			stream << ", ";
10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		stream << " atomicCounterDecrement()";
10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		firstOperation = false;
10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	stream << " calls with ";
10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (spec.useBranches)
10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		stream << " branches, ";
10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	stream << spec.atomicCounterCount << " atomic counters, " << spec.callCount << " calls and " << spec.threadCount << " threads.";
10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return stream.str();
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring operationToName (const AtomicCounterTest::Operation& operations, bool useBranch)
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream	stream;
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				first = true;
11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((operations & AtomicCounterTest::OPERATION_GET) != 0)
11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		stream << "get";
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		first = false;
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((operations & AtomicCounterTest::OPERATION_INC) != 0)
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!first)
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			stream << "_";
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		stream << "inc";
11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		first = false;
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((operations & AtomicCounterTest::OPERATION_DEC) != 0)
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!first)
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			stream << "_";
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		stream << "dec";
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		first = false;
11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (useBranch)
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		stream << "_branch";
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return stream.str();
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring operationToDescription (const AtomicCounterTest::Operation& operations, bool useBranch)
11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream	stream;
11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				firstOperation = 0;
11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	stream
11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	<< "Test ";
11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((operations & AtomicCounterTest::OPERATION_GET) != 0)
11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		stream << "atomicCounter()";
11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		firstOperation = false;
11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((operations & AtomicCounterTest::OPERATION_INC) != 0)
11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!firstOperation)
11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			stream << ", ";
11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		stream << " atomicCounterIncrement()";
11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		firstOperation = false;
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((operations & AtomicCounterTest::OPERATION_DEC) != 0)
11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!firstOperation)
11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			stream << ", ";
11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		stream << " atomicCounterDecrement()";
11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		firstOperation = false;
11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (useBranch)
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		stream << " calls with branches.";
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		stream << ".";
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return stream.str();
11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring layoutTypesToName (const AtomicCounterTest::BindingType& bindingType, const AtomicCounterTest::OffsetType& offsetType)
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream	stream;
11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (bindingType)
11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case AtomicCounterTest::BINDINGTYPE_BASIC:
11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Nothing
11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case AtomicCounterTest::BINDINGTYPE_INVALID:
11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			stream << "invalid_binding";
11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (bindingType != AtomicCounterTest::BINDINGTYPE_BASIC && offsetType != AtomicCounterTest::OFFSETTYPE_NONE)
11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		stream << "_";
11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (offsetType)
12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case AtomicCounterTest::OFFSETTYPE_BASIC:
12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			stream << "basic_offset";
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case AtomicCounterTest::OFFSETTYPE_REVERSE:
12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			stream << "reverse_offset";
12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case AtomicCounterTest::OFFSETTYPE_INVALID:
12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			stream << "invalid_offset";
12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case AtomicCounterTest::OFFSETTYPE_FIRST_AUTO:
12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			stream << "first_offset_set";
12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case AtomicCounterTest::OFFSETTYPE_DEFAULT_AUTO:
12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			stream << "default_offset_set";
12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case AtomicCounterTest::OFFSETTYPE_RESET_DEFAULT:
12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			stream << "reset_default_offset";
12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case AtomicCounterTest::OFFSETTYPE_NONE:
12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Do nothing
12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return stream.str();
12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring layoutTypesToDesc (const AtomicCounterTest::BindingType& bindingType, const AtomicCounterTest::OffsetType& offsetType)
12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream	stream;
12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (bindingType)
12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case AtomicCounterTest::BINDINGTYPE_BASIC:
12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			stream << "Test using atomic counters with explicit layout bindings and";
12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case AtomicCounterTest::BINDINGTYPE_INVALID:
12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			stream << "Test using atomic counters with invalid explicit layout bindings and";
12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case AtomicCounterTest::BINDINGTYPE_INVALID_DEFAULT:
12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			stream << "Test using atomic counters with invalid default layout binding and";
12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (offsetType)
12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case AtomicCounterTest::OFFSETTYPE_NONE:
12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			stream << " no explicit offsets.";
12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case AtomicCounterTest::OFFSETTYPE_BASIC:
12663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			stream << "explicit continuos offsets.";
12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case AtomicCounterTest::OFFSETTYPE_REVERSE:
12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			stream << "reversed explicit offsets.";
12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case AtomicCounterTest::OFFSETTYPE_INVALID:
12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			stream << "invalid explicit offsets.";
12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case AtomicCounterTest::OFFSETTYPE_FIRST_AUTO:
12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			stream << "only first counter with explicit offset.";
12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case AtomicCounterTest::OFFSETTYPE_DEFAULT_AUTO:
12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			stream << "default offset.";
12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case AtomicCounterTest::OFFSETTYPE_RESET_DEFAULT:
12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			stream << "default offset specified twice.";
12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return stream.str();
12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Anonymous
12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12983c827367444ee418f129b2c238299f49d3264554Jarkko PoyryAtomicCounterTests::AtomicCounterTests (Context& context)
12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup(context, "atomic_counter", "Atomic counter tests")
13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Runtime use tests
13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int counterCounts[] =
13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			1, 4, 8
13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int callCounts[] =
13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			1, 5, 100
13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int threadCounts[] =
13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			1, 10, 5000
13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const AtomicCounterTest::Operation operations[] =
13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			AtomicCounterTest::OPERATION_GET,
13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			AtomicCounterTest::OPERATION_INC,
13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			AtomicCounterTest::OPERATION_DEC,
13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			(AtomicCounterTest::Operation)(AtomicCounterTest::OPERATION_INC|AtomicCounterTest::OPERATION_GET),
13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			(AtomicCounterTest::Operation)(AtomicCounterTest::OPERATION_DEC|AtomicCounterTest::OPERATION_GET),
13263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			(AtomicCounterTest::Operation)(AtomicCounterTest::OPERATION_INC|AtomicCounterTest::OPERATION_DEC),
13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			(AtomicCounterTest::Operation)(AtomicCounterTest::OPERATION_INC|AtomicCounterTest::OPERATION_DEC|AtomicCounterTest::OPERATION_GET)
13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int operationNdx = 0; operationNdx < DE_LENGTH_OF_ARRAY(operations); operationNdx++)
13323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const AtomicCounterTest::Operation operation = operations[operationNdx];
13343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int branch = 0; branch < 2; branch++)
13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const bool useBranch = (branch == 1);
13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				TestCaseGroup* operationGroup = new TestCaseGroup(m_context, operationToName(operation, useBranch).c_str(), operationToDescription(operation, useBranch).c_str());
13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int counterCountNdx = 0; counterCountNdx < DE_LENGTH_OF_ARRAY(counterCounts); counterCountNdx++)
13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const int counterCount = counterCounts[counterCountNdx];
13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int callCountNdx = 0; callCountNdx < DE_LENGTH_OF_ARRAY(callCounts); callCountNdx++)
13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const int callCount = callCounts[callCountNdx];
13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						for (int threadCountNdx = 0; threadCountNdx < DE_LENGTH_OF_ARRAY(threadCounts); threadCountNdx++)
13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						{
13513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const int threadCount = threadCounts[threadCountNdx];
13523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							if (threadCount * callCount * counterCount > 10000)
13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								continue;
13553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							if (useBranch && threadCount * callCount == 1)
13573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								continue;
13583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							AtomicCounterTest::TestSpec spec;
13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							spec.atomicCounterCount = counterCount;
13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							spec.operations			= operation;
13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							spec.callCount			= callCount;
13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							spec.useBranches		= useBranch;
13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							spec.threadCount		= threadCount;
13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							spec.bindingType		= AtomicCounterTest::BINDINGTYPE_BASIC;
13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							spec.offsetType			= AtomicCounterTest::OFFSETTYPE_NONE;
13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							operationGroup->addChild(new AtomicCounterTest(m_context, specToTestName(spec).c_str(), specToTestDescription(spec).c_str(), spec));
13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						}
13713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				addChild(operationGroup);
13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* layoutGroup = new TestCaseGroup(m_context, "layout", "Layout qualifier tests.");
13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int counterCounts[]	= { 1, 8 };
13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int callCounts[]		= { 1, 5 };
13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int threadCounts[]	= { 1, 1000 };
13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const AtomicCounterTest::Operation operations[] =
13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			(AtomicCounterTest::Operation)(AtomicCounterTest::OPERATION_INC|AtomicCounterTest::OPERATION_GET),
13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			(AtomicCounterTest::Operation)(AtomicCounterTest::OPERATION_DEC|AtomicCounterTest::OPERATION_GET),
13903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			(AtomicCounterTest::Operation)(AtomicCounterTest::OPERATION_INC|AtomicCounterTest::OPERATION_DEC)
13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const AtomicCounterTest::OffsetType offsetTypes[] =
13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			AtomicCounterTest::OFFSETTYPE_REVERSE,
13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			AtomicCounterTest::OFFSETTYPE_FIRST_AUTO,
13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			AtomicCounterTest::OFFSETTYPE_DEFAULT_AUTO,
13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			AtomicCounterTest::OFFSETTYPE_RESET_DEFAULT
13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int offsetTypeNdx = 0; offsetTypeNdx < DE_LENGTH_OF_ARRAY(offsetTypes); offsetTypeNdx++)
14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const AtomicCounterTest::OffsetType offsetType = offsetTypes[offsetTypeNdx];
14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* layoutQualifierGroup = new TestCaseGroup(m_context, layoutTypesToName(AtomicCounterTest::BINDINGTYPE_BASIC, offsetType).c_str(), layoutTypesToDesc(AtomicCounterTest::BINDINGTYPE_BASIC, offsetType).c_str());
14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int operationNdx = 0; operationNdx < DE_LENGTH_OF_ARRAY(operations); operationNdx++)
14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
14093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const AtomicCounterTest::Operation operation = operations[operationNdx];
14103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				TestCaseGroup* operationGroup = new TestCaseGroup(m_context, operationToName(operation, false).c_str(), operationToDescription(operation, false).c_str());
14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int counterCountNdx = 0; counterCountNdx < DE_LENGTH_OF_ARRAY(counterCounts); counterCountNdx++)
14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const int counterCount = counterCounts[counterCountNdx];
14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (offsetType == AtomicCounterTest::OFFSETTYPE_FIRST_AUTO && counterCount < 3)
14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						continue;
14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (offsetType == AtomicCounterTest::OFFSETTYPE_DEFAULT_AUTO && counterCount < 2)
14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						continue;
14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (offsetType == AtomicCounterTest::OFFSETTYPE_RESET_DEFAULT && counterCount < 2)
14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						continue;
14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (offsetType == AtomicCounterTest::OFFSETTYPE_REVERSE && counterCount < 2)
14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						continue;
14283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int callCountNdx = 0; callCountNdx < DE_LENGTH_OF_ARRAY(callCounts); callCountNdx++)
14303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const int callCount = callCounts[callCountNdx];
14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						for (int threadCountNdx = 0; threadCountNdx < DE_LENGTH_OF_ARRAY(threadCounts); threadCountNdx++)
14343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						{
14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const int threadCount = threadCounts[threadCountNdx];
14363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							AtomicCounterTest::TestSpec spec;
14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							spec.atomicCounterCount = counterCount;
14403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							spec.operations			= operation;
14413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							spec.callCount			= callCount;
14423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							spec.useBranches		= false;
14433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							spec.threadCount		= threadCount;
14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							spec.bindingType		= AtomicCounterTest::BINDINGTYPE_BASIC;
14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							spec.offsetType			= offsetType;
14463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							operationGroup->addChild(new AtomicCounterTest(m_context, specToTestName(spec).c_str(), specToTestDescription(spec).c_str(), spec));
14483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						}
14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
14503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
14513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				layoutQualifierGroup->addChild(operationGroup);
14523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
14533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			layoutGroup->addChild(layoutQualifierGroup);
14543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* invalidGroup = new TestCaseGroup(m_context, "invalid", "Test invalid layouts");
14583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
14603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				AtomicCounterTest::TestSpec spec;
14613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.atomicCounterCount = 1;
14633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.operations			= AtomicCounterTest::OPERATION_INC;
14643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.callCount			= 1;
14653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.useBranches		= false;
14663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.threadCount		= 1;
14673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.bindingType		= AtomicCounterTest::BINDINGTYPE_INVALID;
14683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.offsetType			= AtomicCounterTest::OFFSETTYPE_NONE;
14693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				invalidGroup->addChild(new AtomicCounterTest(m_context, "invalid_binding", "Test layout qualifiers with invalid binding.", spec));
14713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
14723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
14743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				AtomicCounterTest::TestSpec spec;
14753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.atomicCounterCount = 1;
14773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.operations			= AtomicCounterTest::OPERATION_INC;
14783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.callCount			= 1;
14793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.useBranches		= false;
14803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.threadCount		= 1;
14813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.bindingType		= AtomicCounterTest::BINDINGTYPE_INVALID_DEFAULT;
14823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.offsetType			= AtomicCounterTest::OFFSETTYPE_NONE;
14833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				invalidGroup->addChild(new AtomicCounterTest(m_context, "invalid_default_binding", "Test layout qualifiers with invalid default binding.", spec));
14853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
14863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
14883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				AtomicCounterTest::TestSpec spec;
14893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.atomicCounterCount = 1;
14913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.operations			= AtomicCounterTest::OPERATION_INC;
14923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.callCount			= 1;
14933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.useBranches		= false;
14943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.threadCount		= 1;
14953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.bindingType		= AtomicCounterTest::BINDINGTYPE_BASIC;
14963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.offsetType			= AtomicCounterTest::OFFSETTYPE_INVALID;
14973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				invalidGroup->addChild(new AtomicCounterTest(m_context, "invalid_offset_align", "Test layout qualifiers with invalid alignment offset.", spec));
14993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
15023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				AtomicCounterTest::TestSpec spec;
15033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.atomicCounterCount = 2;
15053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.operations			= AtomicCounterTest::OPERATION_INC;
15063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.callCount			= 1;
15073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.useBranches		= false;
15083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.threadCount		= 1;
15093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.bindingType		= AtomicCounterTest::BINDINGTYPE_BASIC;
15103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.offsetType			= AtomicCounterTest::OFFSETTYPE_INVALID_OVERLAPPING;
15113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				invalidGroup->addChild(new AtomicCounterTest(m_context, "invalid_offset_overlap", "Test layout qualifiers with invalid overlapping offset.", spec));
15133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
15163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				AtomicCounterTest::TestSpec spec;
15173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.atomicCounterCount = 1;
15193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.operations			= AtomicCounterTest::OPERATION_INC;
15203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.callCount			= 1;
15213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.useBranches		= false;
15223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.threadCount		= 1;
15233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.bindingType		= AtomicCounterTest::BINDINGTYPE_BASIC;
15243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				spec.offsetType			= AtomicCounterTest::OFFSETTYPE_INVALID_DEFAULT;
15253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				invalidGroup->addChild(new AtomicCounterTest(m_context, "invalid_default_offset", "Test layout qualifiers with invalid default offset.", spec));
15273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			layoutGroup->addChild(invalidGroup);
15303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(layoutGroup);
15333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15363c827367444ee418f129b2c238299f49d3264554Jarkko PoyryAtomicCounterTests::~AtomicCounterTests (void)
15373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid AtomicCounterTests::init (void)
15413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional
15453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles31
15463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
1547