• 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  esextcTextureBufferMAXSizeValidation.cpp
26  * \brief Texture Buffer Max Size Validation (Test 2)
27  */ /*-------------------------------------------------------------------*/
28 
29 #include "esextcTextureBufferMAXSizeValidation.hpp"
30 #include "gluContextInfo.hpp"
31 #include "gluDefs.hpp"
32 #include "glwEnums.hpp"
33 #include "glwFunctions.hpp"
34 #include "tcuTestLog.hpp"
35 #include <vector>
36 
37 namespace glcts
38 {
39 
40 /* Number of components in computeSSBO.outValue vector */
41 const glw::GLuint TextureBufferMAXSizeValidation::m_n_vec_components = 3;
42 
43 /** Constructor
44  *
45  *  @param context     Test context
46  *  @param name        Test case's name
47  *  @param description Test case's description
48  **/
TextureBufferMAXSizeValidation(Context & context,const ExtParameters & extParams,const char * name,const char * description)49 TextureBufferMAXSizeValidation::TextureBufferMAXSizeValidation(Context& context, const ExtParameters& extParams,
50 															   const char* name, const char* description)
51 	: TestCaseBase(context, extParams, name, description)
52 	, m_cs_id(0)
53 	, m_max_tex_buffer_size(0)
54 	, m_po_id(0)
55 	, m_ssbo_id(0)
56 	, m_tbo_id(0)
57 	, m_tbo_tex_id(0)
58 {
59 	/* Nothing to be done here */
60 }
61 
62 /** Initializes GLES objects used during the test.
63  *
64  */
initTest(void)65 void TextureBufferMAXSizeValidation::initTest(void)
66 {
67 	/* Check if texture buffer extension is supported */
68 	if (!m_is_texture_buffer_supported)
69 	{
70 		throw tcu::NotSupportedError(TEXTURE_BUFFER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
71 	}
72 
73 	/* Get GL entry points */
74 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
75 
76 	/* Query for the value of max texture buffer size */
77 	gl.getIntegerv(m_glExtTokens.MAX_TEXTURE_BUFFER_SIZE, &m_max_tex_buffer_size);
78 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error getting gl parameter value!");
79 
80 	/* Create texture buffer object*/
81 	gl.genBuffers(1, &m_tbo_id);
82 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating buffer object!");
83 	gl.bindBuffer(m_glExtTokens.TEXTURE_BUFFER, m_tbo_id);
84 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object!");
85 	gl.bufferData(m_glExtTokens.TEXTURE_BUFFER, m_max_tex_buffer_size * sizeof(glw::GLubyte), DE_NULL, GL_DYNAMIC_DRAW);
86 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating buffer object's data store!");
87 
88 	glw::GLubyte* buf = 0;
89 
90 	buf = (glw::GLubyte*)gl.mapBufferRange(m_glExtTokens.TEXTURE_BUFFER, 0,
91 										   m_max_tex_buffer_size * sizeof(glw::GLubyte), GL_MAP_WRITE_BIT);
92 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error mapping buffer object's data store to client's address space!");
93 
94 	for (glw::GLuint i = 0; i < (glw::GLuint)m_max_tex_buffer_size; ++i)
95 	{
96 		buf[i] = (glw::GLubyte)(i % 256);
97 	}
98 
99 	gl.unmapBuffer(m_glExtTokens.TEXTURE_BUFFER);
100 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error ummapping buffer object's data store from client's address space!");
101 
102 	/* Initialize texture buffer */
103 	gl.genTextures(1, &m_tbo_tex_id);
104 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating texture object!");
105 	gl.activeTexture(GL_TEXTURE0);
106 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error asetting active texture unit!");
107 	gl.bindTexture(m_glExtTokens.TEXTURE_BUFFER, m_tbo_tex_id);
108 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!");
109 
110 	gl.texBuffer(m_glExtTokens.TEXTURE_BUFFER, GL_R8UI, m_tbo_id);
111 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object as data store for texture buffer!");
112 
113 	/* Create program object */
114 	m_po_id = gl.createProgram();
115 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating program object!");
116 
117 	m_cs_id = gl.createShader(GL_COMPUTE_SHADER);
118 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating shader object!");
119 
120 	std::string csSource = getComputeShaderCode();
121 	const char* csCode   = csSource.c_str();
122 
123 	if (!buildProgram(m_po_id, m_cs_id, 1, &csCode))
124 	{
125 		TCU_FAIL("Could not create program from valid compute shader object!");
126 	}
127 
128 	/* Create Shader Storage Buffer Object */
129 	gl.genBuffers(1, &m_ssbo_id);
130 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating buffer object!");
131 	gl.bindBuffer(GL_ARRAY_BUFFER, m_ssbo_id);
132 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding  buffer object!");
133 	gl.bufferData(GL_ARRAY_BUFFER, m_n_vec_components * sizeof(glw::GLuint), 0, GL_DYNAMIC_COPY);
134 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating buffer object!");
135 }
136 
137 /** Returns Compute shader Code
138  *
139  * @return pointer to literal with Compute Shader Code
140  */
getComputeShaderCode()141 const char* TextureBufferMAXSizeValidation::getComputeShaderCode()
142 {
143 	const char* result =
144 		"${VERSION}\n"
145 		"\n"
146 		"${TEXTURE_BUFFER_REQUIRE}\n"
147 		"\n"
148 		"precision highp float;\n"
149 		"\n"
150 		"uniform highp usamplerBuffer sampler_buffer;\n"
151 		"\n"
152 		"buffer ComputeSSBO\n"
153 		"{\n"
154 		"    uvec3 outValue;\n"
155 		"} computeSSBO;\n"
156 		"\n"
157 		"layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
158 		"\n"
159 		"void main(void)\n"
160 		"{\n"
161 		"    computeSSBO.outValue.x = uint( textureSize(sampler_buffer) );\n"
162 		"    computeSSBO.outValue.y = uint( texelFetch (sampler_buffer, 0).x );\n"
163 		"    computeSSBO.outValue.z = uint( texelFetch (sampler_buffer, int(computeSSBO.outValue.x) - 1 ).x );\n"
164 		"}\n";
165 
166 	return result;
167 }
168 
169 /** Executes the test.
170  *
171  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
172  *
173  *  Note the function throws exception should an error occur!
174  *
175  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
176  **/
iterate(void)177 tcu::TestNode::IterateResult TextureBufferMAXSizeValidation::iterate(void)
178 {
179 	initTest();
180 
181 	/* Get GL entry points */
182 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
183 
184 	bool testResult = true;
185 
186 	glw::GLint textureOffset = -1;
187 
188 	gl.getTexLevelParameteriv(m_glExtTokens.TEXTURE_BUFFER, 0, m_glExtTokens.TEXTURE_BUFFER_OFFSET, &textureOffset);
189 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error getting texture buffer offset parameter value!");
190 
191 	/* Check if offset is equal to 0 */
192 	const int expectedOffset = 0;
193 
194 	if (expectedOffset != textureOffset)
195 	{
196 		m_testCtx.getLog() << tcu::TestLog::Message
197 						   << "Expected GL_TEXTURE_BUFFER_OFFSET_EXT parameter value : " << expectedOffset << "\n"
198 						   << "Result   GL_TEXTURE_BUFFER_OFFSET_EXT parameter value : " << textureOffset << "\n"
199 						   << tcu::TestLog::EndMessage;
200 		testResult = false;
201 	}
202 
203 	glw::GLint textureSize = 0;
204 
205 	gl.getTexLevelParameteriv(m_glExtTokens.TEXTURE_BUFFER, 0, m_glExtTokens.TEXTURE_BUFFER_SIZE, &textureSize);
206 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error getting texture buffer paramter value!");
207 
208 	/* Check if texture size is equal to m_max_tex_buffer_size * sizeof(glw::GLubyte) */
209 	glw::GLint expectedSize = static_cast<glw::GLint>(m_max_tex_buffer_size * sizeof(glw::GLubyte));
210 
211 	if (expectedSize != textureSize)
212 	{
213 		m_testCtx.getLog() << tcu::TestLog::Message
214 						   << "Expected GL_TEXTURE_BUFFER_SIZE_EXT parameter value : " << expectedSize << "\n"
215 						   << "Result   GL_TEXTURE_BUFFER_SIZE_EXT parameter value : " << textureSize << "\n"
216 						   << tcu::TestLog::EndMessage;
217 		testResult = false;
218 	}
219 
220 	gl.useProgram(m_po_id);
221 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting program!");
222 
223 	gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_ssbo_id);
224 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not bind buffer object to shader storage binding point!");
225 
226 	gl.activeTexture(GL_TEXTURE0);
227 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error activating texture unit!");
228 
229 	gl.bindTexture(m_glExtTokens.TEXTURE_BUFFER, m_tbo_tex_id);
230 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!");
231 
232 	glw::GLint location = gl.getUniformLocation(m_po_id, "sampler_buffer");
233 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error getting uniform location!");
234 
235 	gl.uniform1i(location, 0);
236 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting value for uniform location!");
237 
238 	gl.dispatchCompute(1, 1, 1);
239 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error running compute shader!");
240 
241 	gl.memoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
242 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting memory barrier!");
243 
244 	/* Get result data */
245 	glw::GLuint* result = (glw::GLuint*)gl.mapBufferRange(GL_SHADER_STORAGE_BUFFER, 0,
246 														  m_n_vec_components * sizeof(glw::GLuint), GL_MAP_READ_BIT);
247 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error mapping buffer object to client's address space!");
248 
249 	glw::GLuint expectedValue = (m_max_tex_buffer_size - 1) % 256;
250 	/* Log error if expected values and result data are not equal */
251 	if (result[0] != (glw::GLuint)m_max_tex_buffer_size || result[1] != 0 || result[2] != expectedValue)
252 	{
253 		m_testCtx.getLog() << tcu::TestLog::Message << "Result is different than expected\n"
254 						   << "Expected size:                            " << m_max_tex_buffer_size << "\n"
255 						   << "Result value  (textureSize):              " << result[0] << "\n"
256 						   << "Expected Value (for index 0)              " << 0 << "\n"
257 						   << "Result value                              " << result[1] << "\n"
258 						   << "ExpectedValue (for last index)            " << expectedValue << "\n"
259 						   << "Result value                              " << result[2] << "\n"
260 						   << tcu::TestLog::EndMessage;
261 
262 		testResult = false;
263 	}
264 
265 	if (testResult)
266 	{
267 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
268 	}
269 	else
270 	{
271 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
272 	}
273 
274 	gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER);
275 
276 	return STOP;
277 }
278 
279 /** Deinitializes GLES objects created during the test.
280  *
281  */
deinit(void)282 void TextureBufferMAXSizeValidation::deinit(void)
283 {
284 	/* Get GL entry points */
285 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
286 
287 	/* Reset GLES state */
288 	gl.useProgram(0);
289 	gl.bindBuffer(GL_ARRAY_BUFFER, 0);
290 	gl.bindBuffer(m_glExtTokens.TEXTURE_BUFFER, 0);
291 	gl.bindTexture(m_glExtTokens.TEXTURE_BUFFER, 0);
292 	gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0);
293 
294 	/* Delete GLES objects */
295 	if (0 != m_cs_id)
296 	{
297 		gl.deleteShader(m_cs_id);
298 		m_cs_id = 0;
299 	}
300 
301 	if (0 != m_po_id)
302 	{
303 		gl.deleteProgram(m_po_id);
304 		m_po_id = 0;
305 	}
306 
307 	if (0 != m_ssbo_id)
308 	{
309 		gl.deleteBuffers(1, &m_ssbo_id);
310 		m_ssbo_id = 0;
311 	}
312 
313 	if (0 != m_tbo_id)
314 	{
315 		gl.deleteBuffers(1, &m_tbo_id);
316 		m_tbo_id = 0;
317 	}
318 
319 	if (0 != m_tbo_tex_id)
320 	{
321 		gl.deleteTextures(1, &m_tbo_tex_id);
322 		m_tbo_tex_id = 0;
323 	}
324 
325 	/* Deinitialize base class */
326 	TestCaseBase::deinit();
327 }
328 
329 } // namespace glcts
330