• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  **/
GPUShader5AtomicCountersArrayIndexing(Context & context,const ExtParameters & extParams,const char * name,const char * description)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  */
initTest(void)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  **/
iterate(void)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  */
deinit(void)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