• 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