148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/*-------------------------------------------------------------------------
248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * OpenGL Conformance Test Suite
348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * -----------------------------
448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Copyright (c) 2014-2016 The Khronos Group Inc.
648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Licensed under the Apache License, Version 2.0 (the "License");
848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * you may not use this file except in compliance with the License.
948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * You may obtain a copy of the License at
1048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
1148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *      http://www.apache.org/licenses/LICENSE-2.0
1248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
1348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Unless required by applicable law or agreed to in writing, software
1448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * distributed under the License is distributed on an "AS IS" BASIS,
1548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * See the License for the specific language governing permissions and
1748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * limitations under the License.
1848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
1984322c9402f810da3cd80b52e9f9ef72150a9004Alexander Galazin */ /*!
2048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * \file
2148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * \brief
2284322c9402f810da3cd80b52e9f9ef72150a9004Alexander Galazin */ /*-------------------------------------------------------------------*/
2348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
2448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/*!
2548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * \file esextcGPUShader5AtomicCountersArrayIndexing.cpp
2648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * \brief GPUShader5 Atomic Counters Array Indexing (Test 3)
2784322c9402f810da3cd80b52e9f9ef72150a9004Alexander Galazin */ /*-------------------------------------------------------------------*/
2848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
2948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "esextcGPUShader5AtomicCountersArrayIndexing.hpp"
3048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "gluContextInfo.hpp"
3148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "gluDefs.hpp"
3248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "glwEnums.hpp"
3348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "glwFunctions.hpp"
3448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "tcuTestLog.hpp"
3548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include <cstring>
3648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
3748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosnamespace glcts
3848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
3948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosconst glw::GLuint GPUShader5AtomicCountersArrayIndexing::m_atomic_counters_array_size = 4;
4048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
4148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/* Compute Shader code */
4248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosconst char* GPUShader5AtomicCountersArrayIndexing::m_compute_shader_code =
4348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	"${VERSION}\n"
4448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	"\n"
4548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	"${GPU_SHADER5_REQUIRE}\n"
4648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	"\n"
4748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	"layout (local_size_x = 2, local_size_y = 2) in;\n"
4848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	"layout (binding      = 0, offset       = 0) uniform atomic_uint counters[4];\n"
4948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	"\n"
5048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	"void main(void)\n"
5148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	"{\n"
5248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	"    for (uint index = 0u; index <= 3u; ++index)\n"
5348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	"    {\n"
5448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	"        for (uint iteration = 0u; iteration <= gl_LocalInvocationID.x * 2u + gl_LocalInvocationID.y; "
5548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	"++iteration)\n"
5648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	"        {\n"
5748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	"            atomicCounterIncrement( counters[index] );\n"
5848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	"        }\n"
5948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	"    }\n"
6048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	"}\n";
6148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
6248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor
6348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
6448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *  @param context     Test context
6548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *  @param name        Test case's name
6648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *  @param description Test case's description
6748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
6848087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosGPUShader5AtomicCountersArrayIndexing::GPUShader5AtomicCountersArrayIndexing(Context&			  context,
6948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos																			 const ExtParameters& extParams,
7048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos																			 const char* name, const char* description)
7148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	: TestCaseBase(context, extParams, name, description), m_buffer_id(0), m_compute_shader_id(0), m_program_id(0)
7248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
7348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Nothing to be done here */
7448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
7548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
7648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Initializes GLES objects used during the test.
7748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
7848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */
7948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid GPUShader5AtomicCountersArrayIndexing::initTest(void)
8048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
8148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
8348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Check if gpu_shader5 extension is supported */
8448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (!m_is_gpu_shader5_supported)
8548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
8648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		throw tcu::NotSupportedError(GPU_SHADER5_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
8748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
8848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
8948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Create program object from the supplied compute shader code */
9048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_program_id = gl.createProgram();
9148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "Creating program object failed");
9248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
9348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_compute_shader_id = gl.createShader(GL_COMPUTE_SHADER);
9448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "Creating compute shader object failed");
9548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
9648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (!buildProgram(m_program_id, m_compute_shader_id, 1, &m_compute_shader_code))
9748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
9848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		TCU_FAIL("Could not create program object!");
9948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
10048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
10148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	glw::GLuint bufferData[m_atomic_counters_array_size];
10248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (glw::GLuint index = 0; index < m_atomic_counters_array_size; ++index)
10348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
10448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		bufferData[index] = index;
10548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
10648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
10748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.genBuffers(1, &m_buffer_id);
10848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindBuffer(GL_ATOMIC_COUNTER_BUFFER, m_buffer_id);
10948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bufferData(GL_ATOMIC_COUNTER_BUFFER, m_atomic_counters_array_size * sizeof(glw::GLuint), bufferData,
11048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				  GL_DYNAMIC_COPY);
11148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, m_buffer_id);
11248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
11348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not setup buffer object!");
11448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
11548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
11648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes the test.
11748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
11848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
11948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
12048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *  Note the function throws exception should an error occur!
12148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
12248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
12348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
12448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult GPUShader5AtomicCountersArrayIndexing::iterate(void)
12548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
12648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	initTest();
12748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
12848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
12948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
13048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Do the computations */
13148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.useProgram(m_program_id);
13248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not use program object!");
13348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
13448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.dispatchCompute(10, /* num_groups_x */
13548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					   10, /* num_groups_y */
13648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					   1); /* num_groups_z */
13748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to dispatch compute operation!");
13848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
13948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Map the buffer object storage into user space */
14048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	glw::GLuint* bufferData =
14148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		(glw::GLuint*)gl.mapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, /* offset */
14248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos										m_atomic_counters_array_size * sizeof(glw::GLuint), GL_MAP_READ_BIT);
14348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to map buffer range to client space!");
14448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
14548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Compare the result values with reference value */
14648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const glw::GLuint expectedResult = 1000;
14748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
14848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (expectedResult != bufferData[0] || expectedResult + 1 != bufferData[1] || expectedResult + 2 != bufferData[2] ||
14948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		expectedResult + 3 != bufferData[3])
15048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
15148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid data rendered. Expected Data"
15248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						   << " (" << expectedResult << ", " << expectedResult << ", " << expectedResult << ", "
15348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						   << expectedResult << ") Result Data"
15448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						   << " (" << bufferData[0] << " ," << bufferData[1] << " ," << bufferData[2] << " ,"
15548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						   << bufferData[3] << ")" << tcu::TestLog::EndMessage;
15648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
15748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.unmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
15848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unmap buffer!");
15948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
16048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
16148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		return STOP;
16248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
16348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
16448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.unmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
16548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unmap buffer!");
16648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
16748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
16848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	return STOP;
16948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
17048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
17148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Deinitializes GLES objects created during the test.
17248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
17348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */
17448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid GPUShader5AtomicCountersArrayIndexing::deinit(void)
17548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
17648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
17748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
17848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Reset OpenGL ES state */
17948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.useProgram(0);
18048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0);
18148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
18248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_program_id != 0)
18348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
18448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteProgram(m_program_id);
18548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		m_program_id = 0;
18648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
18748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
18848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_compute_shader_id != 0)
18948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
19048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteShader(m_compute_shader_id);
19148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		m_compute_shader_id = 0;
19248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
19348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
19448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_buffer_id != 0)
19548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
19648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteBuffers(1, &m_buffer_id);
19748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		m_buffer_id = 0;
19848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
19948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
20048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Release base class */
20148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	TestCaseBase::deinit();
20248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
20348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
20448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} // namespace glcts
205