Home | History | Annotate | Download | only in gpu_shader5
      1 /*-------------------------------------------------------------------------
      2  * OpenGL Conformance Test Suite
      3  * -----------------------------
      4  *
      5  * Copyright (c) 2014-2016 The Khronos Group Inc.
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  */ /*!
     20  * \file
     21  * \brief
     22  */ /*-------------------------------------------------------------------*/
     23 
     24 /*!
     25  * \file esextcGPUShader5AtomicCountersArrayIndexing.cpp
     26  * \brief GPUShader5 Atomic Counters Array Indexing (Test 3)
     27  */ /*-------------------------------------------------------------------*/
     28 
     29 #include "esextcGPUShader5AtomicCountersArrayIndexing.hpp"
     30 #include "gluContextInfo.hpp"
     31 #include "gluDefs.hpp"
     32 #include "glwEnums.hpp"
     33 #include "glwFunctions.hpp"
     34 #include "tcuTestLog.hpp"
     35 #include <cstring>
     36 
     37 namespace glcts
     38 {
     39 const glw::GLuint GPUShader5AtomicCountersArrayIndexing::m_atomic_counters_array_size = 4;
     40 
     41 /* Compute Shader code */
     42 const char* GPUShader5AtomicCountersArrayIndexing::m_compute_shader_code =
     43 	"${VERSION}\n"
     44 	"\n"
     45 	"${GPU_SHADER5_REQUIRE}\n"
     46 	"\n"
     47 	"layout (local_size_x = 2, local_size_y = 2) in;\n"
     48 	"layout (binding      = 0, offset       = 0) uniform atomic_uint counters[4];\n"
     49 	"\n"
     50 	"void main(void)\n"
     51 	"{\n"
     52 	"    for (uint index = 0u; index <= 3u; ++index)\n"
     53 	"    {\n"
     54 	"        for (uint iteration = 0u; iteration <= gl_LocalInvocationID.x * 2u + gl_LocalInvocationID.y; "
     55 	"++iteration)\n"
     56 	"        {\n"
     57 	"            atomicCounterIncrement( counters[index] );\n"
     58 	"        }\n"
     59 	"    }\n"
     60 	"}\n";
     61 
     62 /** Constructor
     63  *
     64  *  @param context     Test context
     65  *  @param name        Test case's name
     66  *  @param description Test case's description
     67  **/
     68 GPUShader5AtomicCountersArrayIndexing::GPUShader5AtomicCountersArrayIndexing(Context&			  context,
     69 																			 const ExtParameters& extParams,
     70 																			 const char* name, const char* description)
     71 	: TestCaseBase(context, extParams, name, description), m_buffer_id(0), m_compute_shader_id(0), m_program_id(0)
     72 {
     73 	/* Nothing to be done here */
     74 }
     75 
     76 /** Initializes GLES objects used during the test.
     77  *
     78  */
     79 void GPUShader5AtomicCountersArrayIndexing::initTest(void)
     80 {
     81 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
     82 
     83 	/* Check if gpu_shader5 extension is supported */
     84 	if (!m_is_gpu_shader5_supported)
     85 	{
     86 		throw tcu::NotSupportedError(GPU_SHADER5_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
     87 	}
     88 
     89 	/* Create program object from the supplied compute shader code */
     90 	m_program_id = gl.createProgram();
     91 	GLU_EXPECT_NO_ERROR(gl.getError(), "Creating program object failed");
     92 
     93 	m_compute_shader_id = gl.createShader(GL_COMPUTE_SHADER);
     94 	GLU_EXPECT_NO_ERROR(gl.getError(), "Creating compute shader object failed");
     95 
     96 	if (!buildProgram(m_program_id, m_compute_shader_id, 1, &m_compute_shader_code))
     97 	{
     98 		TCU_FAIL("Could not create program object!");
     99 	}
    100 
    101 	glw::GLuint bufferData[m_atomic_counters_array_size];
    102 	for (glw::GLuint index = 0; index < m_atomic_counters_array_size; ++index)
    103 	{
    104 		bufferData[index] = index;
    105 	}
    106 
    107 	gl.genBuffers(1, &m_buffer_id);
    108 	gl.bindBuffer(GL_ATOMIC_COUNTER_BUFFER, m_buffer_id);
    109 	gl.bufferData(GL_ATOMIC_COUNTER_BUFFER, m_atomic_counters_array_size * sizeof(glw::GLuint), bufferData,
    110 				  GL_DYNAMIC_COPY);
    111 	gl.bindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, m_buffer_id);
    112 
    113 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not setup buffer object!");
    114 }
    115 
    116 /** Executes the test.
    117  *
    118  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
    119  *
    120  *  Note the function throws exception should an error occur!
    121  *
    122  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
    123  **/
    124 tcu::TestNode::IterateResult GPUShader5AtomicCountersArrayIndexing::iterate(void)
    125 {
    126 	initTest();
    127 
    128 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    129 
    130 	/* Do the computations */
    131 	gl.useProgram(m_program_id);
    132 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not use program object!");
    133 
    134 	gl.dispatchCompute(10, /* num_groups_x */
    135 					   10, /* num_groups_y */
    136 					   1); /* num_groups_z */
    137 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to dispatch compute operation!");
    138 
    139 	/* Map the buffer object storage into user space */
    140 	glw::GLuint* bufferData =
    141 		(glw::GLuint*)gl.mapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, /* offset */
    142 										m_atomic_counters_array_size * sizeof(glw::GLuint), GL_MAP_READ_BIT);
    143 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to map buffer range to client space!");
    144 
    145 	/* Compare the result values with reference value */
    146 	const glw::GLuint expectedResult = 1000;
    147 
    148 	if (expectedResult != bufferData[0] || expectedResult + 1 != bufferData[1] || expectedResult + 2 != bufferData[2] ||
    149 		expectedResult + 3 != bufferData[3])
    150 	{
    151 		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid data rendered. Expected Data"
    152 						   << " (" << expectedResult << ", " << expectedResult << ", " << expectedResult << ", "
    153 						   << expectedResult << ") Result Data"
    154 						   << " (" << bufferData[0] << " ," << bufferData[1] << " ," << bufferData[2] << " ,"
    155 						   << bufferData[3] << ")" << tcu::TestLog::EndMessage;
    156 
    157 		gl.unmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
    158 		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unmap buffer!");
    159 
    160 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
    161 		return STOP;
    162 	}
    163 
    164 	gl.unmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
    165 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unmap buffer!");
    166 
    167 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    168 	return STOP;
    169 }
    170 
    171 /** Deinitializes GLES objects created during the test.
    172  *
    173  */
    174 void GPUShader5AtomicCountersArrayIndexing::deinit(void)
    175 {
    176 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    177 
    178 	/* Reset OpenGL ES state */
    179 	gl.useProgram(0);
    180 	gl.bindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0);
    181 
    182 	if (m_program_id != 0)
    183 	{
    184 		gl.deleteProgram(m_program_id);
    185 		m_program_id = 0;
    186 	}
    187 
    188 	if (m_compute_shader_id != 0)
    189 	{
    190 		gl.deleteShader(m_compute_shader_id);
    191 		m_compute_shader_id = 0;
    192 	}
    193 
    194 	if (m_buffer_id != 0)
    195 	{
    196 		gl.deleteBuffers(1, &m_buffer_id);
    197 		m_buffer_id = 0;
    198 	}
    199 
    200 	/* Release base class */
    201 	TestCaseBase::deinit();
    202 }
    203 
    204 } // namespace glcts
    205