• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef _ESEXTCTEXTUREBUFFEROPERATIONS_HPP
2 #define _ESEXTCTEXTUREBUFFEROPERATIONS_HPP
3 /*-------------------------------------------------------------------------
4  * OpenGL Conformance Test Suite
5  * -----------------------------
6  *
7  * Copyright (c) 2014-2016 The Khronos Group Inc.
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  */ /*!
22  * \file
23  * \brief
24  */ /*-------------------------------------------------------------------*/
25 
26 /*!
27  * \file  esextcTextureBufferOperations.hpp
28  * \brief Texture Buffer Operations (Test 1)
29  */ /*-------------------------------------------------------------------*/
30 
31 #include "../esextcTestCaseBase.hpp"
32 
33 namespace glcts
34 {
35 
36 /** Implementation of (Test 1) from CTS_EXT_texture_buffer. Description follows
37  *
38  *   Check whether texture data for the texture buffer can be specified in a number
39  *   of different ways:
40  *
41  *   1. via buffer object loads
42  *   2. via direct CPU writes
43  *   3. via framebuffer readbacks to pixel buffer objects
44  *   4. via transform feedback
45  *   5. via image store
46  *   6. via ssbo writes
47  *
48  *   Category: API, Functional Test.
49  *
50  *   The test should create a texture object and bind it to GL_TEXTURE_BUFFER_EXT
51  *   texture target at texture unit 0. It should also create buffer object
52  *   and bind it to TEXTURE_BUFFER_EXT target. Call glBufferData with NULL data
53  *   pointer to allocate storage for the buffer object. The size of the storage
54  *   should be equal to value(GL_MAX_COMPUTE_WORK_GROUP_SIZE, X axis) *
55  *   sizeof(GLint) * 4.
56  *
57  *   The buffer object should be used as texture buffer's data store by calling
58  *
59  *   TexBufferExt(TEXTURE_BUFFER_EXT, GL_RGBA32I, buffer_id );
60  *
61  *   The data for the buffer object should be specified in the following ways:
62  *
63  *   ---------------------------------------------------------------------------
64  *
65  *   1. Use glBufferSubData to fill buffer object's data store.
66  *   glBufferSubData should be given a pointer to data that will be copied into
67  *   the data store for initialization.
68  *
69  *   ---------------------------------------------------------------------------
70  *
71  *   2. Map the buffer object's data store to client's address space by using
72  *   glMapBufferRange function (map the whole data store). The data store should
73  *   then be filled with values up to the size of the data store.
74  *   The data store should be unmapped using glUnmapBuffer function.
75  *
76  *   ---------------------------------------------------------------------------
77  *
78  *   3. Create a framebuffer object and bind it to GL_DRAW_FRAMEBUFFER target.
79  *   Create a 2d texture object with size
80  *   value(GL_MAX_COMPUTE_WORK_GROUP_SIZE, X axis) x 1 and RGBA32I internal
81  *   format. Attach the texture object to framebuffer's GL_COLOR_ATTACHMENT0
82  *   attachment. Render to texture filling it completely with some predefined
83  *   integer values.
84  *
85  *   Bind the framebuffer object to GL_READ_FRAMEBUFFER target.
86  *
87  *   Bind the buffer object to GL_PIXEL_PACK_BUFFER target.
88  *
89  *   Set the alignment requirements by calling glPixelStorei(GL_UNPACK_ALIGNMENT,1)
90  *   and glPixelStorei(GL_PACK_ALIGNMENT,1).
91  *
92  *   Call glReadPixels(0, 0, value(GL_MAX_COMPUTE_WORK_GROUP_SIZE, X axis),
93  *                     1, GL_RGBA, GL_INT, 0).
94  *
95  *   Bind the buffer object once again to TEXTURE_BUFFER_EXT target.
96  *
97  *   ---------------------------------------------------------------------------
98  *
99  *   4. Write a vertex shader that declares in ivec4 inPosition and
100  *   out ivec4 outPosition variables and a matching fragment shader. The vertex
101  *   shader should assign the value of inPosition to outPosition. The buffer object
102  *   being a data source for the inPosition attribute should be filled with some
103  *   integer values. Configure transform feedback to capture value of outPosition.
104  *   Bind our texture buffer's buffer object as destination buffer for transform
105  *   feedback operations.
106  *
107  *   Execute a draw call.
108  *
109  *   ---------------------------------------------------------------------------
110  *
111  *   5. Write a compute shader that defines
112  *
113  *   layout(rgba32i, binding = 0) uniform highp iimageBuffer image_buffer;
114  *
115  *   The work group size should be equal to
116  *   value(GL_MAX_COMPUTE_WORK_GROUP_SIZE, X axis) x 1 x 1.
117  *
118  *   Bind the texture buffer to image unit 0.
119  *
120  *   In the compute shader execute:
121  *
122  *   imageStore(image_buffer, gl_LocalInvocationID.x, ivec4(gl_LocalInvocationID.x) );
123  *
124  *   Call:
125  *
126  *   glDispatchCompute(1, 1, 1);
127  *   glMemoryBarrier(TEXTURE_FETCH_BARRIER_BIT);
128  *
129  *   ---------------------------------------------------------------------------
130  *
131  *   6. Write a compute shader that defines
132  *
133  *   buffer ComputeSSBO
134  *   {
135  *     ivec4 value[];
136  *
137  *   } computeSSBO;
138  *
139  *   Work group size should be equal to
140  *   value(GL_MAX_COMPUTE_WORK_GROUP_SIZE, X axis) x 1 x 1.
141  *
142  *   Bind the buffer object to GL_SHADER_STORAGE_BUFFER target.
143  *
144  *   In the compute shader execute:
145  *
146  *   computeSSBO.value[gl_LocalInvocationID.x] = vec4(gl_LocalInvocationID.x);
147  *
148  *   Call:
149  *
150  *   glDispatchCompute(1, 1, 1);
151  *   glMemoryBarrier(TEXTURE_FETCH_BARRIER_BIT);
152  *
153  *   Bind the buffer object once again to TEXTURE_BUFFER_EXT target.
154  *
155  *   ---------------------------------------------------------------------------
156  *
157  *   The test checks whether data for the texture buffer has been correctly
158  *   specified in the above 6 different ways and if it can be accessed via imageLoad
159  *   and texelFetch. In the first phase we try to access the data via imageLoad in
160  *   a compute shader and in the second phase we try to access the same data
161  *   via texelFetch in a vertex shader.
162  *
163  *   For the first phase write a compute shader that defines
164  *
165  *   layout(rgba32i, binding = 0) uniform highp iimageBuffer image_buffer;
166  *
167  *   Bind the texture buffer to image unit 0.
168  *
169  *   Work group size should be equal to
170  *   value(GL_MAX_COMPUTE_WORK_GROUP_SIZE, X axis) x 1 x 1.
171  *
172  *   The shader should also define a shader storage buffer object
173  *
174  *   buffer ComputeSSBO
175  *   {
176  *     ivec4 value[];
177  *
178  *   } computeSSBO;
179  *
180  *   Initialize a buffer object to be assigned as ssbo data store. The size of
181  *   this buffer object's data store should be equal to the size of
182  *   the data store of the buffer object associated with texture buffer.
183  *
184  *   In the compute shader execute:
185  *
186  *   int index = int(gl_LocalInvocationID.x);
187  *
188  *   computeSSBO.value[index] = imageLoad( image_buffer, index);
189  *
190  *   Call:
191  *
192  *   glDispatchCompute(1, 1, 1);
193  *   glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
194  *
195  *   For each case compare the contents of the data store of ssbo's buffer object
196  *   with the values that this case should have written to the data store of the
197  *   texture buffer. This phase of the test passes if for each case we get equality.
198  *
199  *   For the second phase of the test write a vertex shader that defines
200  *
201  *   in  vec4  vs_position;
202  *   in  float vs_index;
203  *   out float fs_index;
204  *
205  *   The shader should execute the following operations:
206  *
207  *   gl_Position = vs_position;
208  *   fs_index    = vs_index;
209  *
210  *   Configure buffer object as data source for the vs_position attribute.
211  *   The buffer object should be filled with data:
212  *   (-1,-1,0,1), (1,-1,0,1), (-1,1,0,1), (1,1,0,1).
213  *
214  *   Configure buffer object as data source for the vs_index attribute.
215  *   The buffer object should be filled with data:
216  *   0.0f , 0.0f , value(GL_MAX_COMPUTE_WORK_GROUP_SIZE, X axis),
217  *   value(GL_MAX_COMPUTE_WORK_GROUP_SIZE, X axis).
218  *
219  *   Write a fragment shader that defines;
220  *
221  *   in float  fs_index;
222  *
223  *   uniform highp isamplerBuffer sampler_buffer;
224  *
225  *   layout(location = 0) out ivec4 color;
226  *
227  *   The shader should execute the following operations:
228  *
229  *   color = texelFetch( sampler_buffer, int(fs_index) );
230  *
231  *   Create a program from the above vertex shader and fragment shader and use it.
232  *
233  *   Bind the sampler_buffer location to texture unit 0.
234  *
235  *   The test should set up a FBO. A 2D texture of
236  *   value(GL_MAX_COMPUTE_WORK_GROUP_SIZE, X axis) x 1 resolution using
237  *   GL_RGBA32I internal format and GL_NEAREST magnification and
238  *   minification filter should be attached to its color attachment 0.
239  *
240  *   Execute a draw call glDrawArrays(GL_TRIANGLE_STRIP, 0, 4).
241  *
242  *   Use glReadPixels to read the texel data from the texture attached to color
243  *   attachment 0.
244  *
245  *   For each case compare the contents of retrieved texel data with the values
246  *   that this case should have written to the data store of the texture buffer.
247  *   This phase of the test passes if for each case we get equality.
248  */
249 
250 /* Base Class */
251 class TextureBufferOperations : public TestCaseBase
252 {
253 public:
254 	/* Public methods */
255 	TextureBufferOperations(Context& context, const ExtParameters& extParams, const char* name,
256 							const char* description);
257 
~TextureBufferOperations()258 	virtual ~TextureBufferOperations()
259 	{
260 	}
261 
262 	virtual void		  deinit(void);
263 	virtual IterateResult iterate(void);
264 
265 protected:
266 	/* Protected methods */
267 	void checkFramebufferStatus(glw::GLenum framebuffer);
268 	virtual void initTest(void);
269 	virtual void initializeBufferObjectData(void) = 0;
270 	virtual void fillBufferWithData(glw::GLint* buffer, glw::GLuint bufferLength);
271 
272 	/* Protected static constants */
273 	static const glw::GLuint m_n_vector_components;
274 
275 	/* Protected variables */
276 	glw::GLint m_n_vectors_in_buffer_texture;
277 
278 	glw::GLuint m_tb_bo_id;
279 	glw::GLuint m_texbuff_id;
280 
281 private:
282 	std::string getComputeShaderCode(void) const;
283 	std::string getFragmentShaderCode(void) const;
284 	std::string getVertexShaderCode(void) const;
285 
286 	void initFirstPhase(void);
287 	void initSecondPhase(void);
288 	void iterateFirstPhase(glw::GLint* result, glw::GLuint size);
289 	void iterateSecondPhase(glw::GLint* result);
290 	void deinitFirstPhase(void);
291 	void deinitSecondPhase(void);
292 
293 	glw::GLboolean verifyResults(glw::GLint* reference, glw::GLint* result, glw::GLuint size, const char* message);
294 
295 	/* Private variables */
296 	glw::GLuint m_cs_id;
297 	glw::GLuint m_po_cs_id;
298 	glw::GLuint m_ssbo_bo_id;
299 
300 	glw::GLuint m_fbo_id;
301 	glw::GLuint m_fs_id;
302 	glw::GLuint m_po_vs_fs_id;
303 	glw::GLuint m_to_id;
304 	glw::GLuint m_vao_id;
305 	glw::GLuint m_vbo_id;
306 	glw::GLuint m_vbo_indicies_id;
307 	glw::GLuint m_vs_id;
308 	glw::GLint  m_vertex_location;
309 	glw::GLint  m_index_location;
310 };
311 
312 /* Test Case 1 - buffer object loads */
313 class TextureBufferOperationsViaBufferObjectLoad : public TextureBufferOperations
314 {
315 public:
316 	/* Public methods */
317 	TextureBufferOperationsViaBufferObjectLoad(Context& context, const ExtParameters& extParams, const char* name,
318 											   const char* description);
319 
~TextureBufferOperationsViaBufferObjectLoad()320 	virtual ~TextureBufferOperationsViaBufferObjectLoad()
321 	{
322 	}
323 
324 protected:
325 	/* Protected methods */
326 	virtual void initializeBufferObjectData(void);
327 };
328 
329 /* Test Case 2 - direct CPU writes */
330 class TextureBufferOperationsViaCPUWrites : public TextureBufferOperations
331 {
332 public:
333 	/* Public methods */
334 	TextureBufferOperationsViaCPUWrites(Context& context, const ExtParameters& extParams, const char* name,
335 										const char* description);
336 
~TextureBufferOperationsViaCPUWrites()337 	virtual ~TextureBufferOperationsViaCPUWrites()
338 	{
339 	}
340 
341 protected:
342 	/* Protected methods */
343 	virtual void initializeBufferObjectData(void);
344 };
345 
346 /* Test Case 3 - framebuffer readbacks to pixel buffer objects */
347 class TextureBufferOperationsViaFrambufferReadBack : public TextureBufferOperations
348 {
349 public:
350 	/* Public methods */
351 	TextureBufferOperationsViaFrambufferReadBack(Context& context, const ExtParameters& extParams, const char* name,
352 												 const char* description);
353 
~TextureBufferOperationsViaFrambufferReadBack()354 	virtual ~TextureBufferOperationsViaFrambufferReadBack()
355 	{
356 	}
357 
358 	virtual void deinit(void);
359 
360 private:
361 	/* Private methods */
362 	virtual void initializeBufferObjectData(void);
363 	virtual void fillBufferWithData(glw::GLint* buffer, glw::GLuint bufferLength);
364 
365 	std::string getFBFragmentShaderCode() const;
366 	std::string getFBVertexShaderCode() const;
367 
368 	glw::GLuint m_fb_fbo_id;
369 	glw::GLuint m_fb_fs_id;
370 	glw::GLuint m_fb_po_id;
371 	glw::GLuint m_fb_to_id;
372 	glw::GLuint m_fb_vao_id;
373 	glw::GLuint m_fb_vbo_id;
374 	glw::GLuint m_fb_vs_id;
375 	glw::GLint  m_position_location;
376 };
377 
378 /* Test Case 4 - transform feedback */
379 class TextureBufferOperationsViaTransformFeedback : public TextureBufferOperations
380 {
381 public:
382 	/* Public methods */
383 	TextureBufferOperationsViaTransformFeedback(Context& context, const ExtParameters& extParams, const char* name,
384 												const char* description);
385 
~TextureBufferOperationsViaTransformFeedback()386 	virtual ~TextureBufferOperationsViaTransformFeedback()
387 	{
388 	}
389 
390 	virtual void deinit(void);
391 
392 private:
393 	/* Private methods */
394 	virtual void initializeBufferObjectData(void);
395 
396 	std::string getTFVertexShaderCode() const;
397 	std::string getTFFragmentShaderCode() const;
398 
399 	/* Private variables */
400 	glw::GLuint m_tf_fs_id;
401 	glw::GLuint m_tf_po_id;
402 	glw::GLuint m_tf_vao_id;
403 	glw::GLuint m_tf_vbo_id;
404 	glw::GLuint m_tf_vs_id;
405 	glw::GLint  m_position_location;
406 };
407 
408 /* Test Case 5 - image store */
409 class TextureBufferOperationsViaImageStore : public TextureBufferOperations
410 {
411 public:
412 	/* Public methods */
413 	TextureBufferOperationsViaImageStore(Context& context, const ExtParameters& extParams, const char* name,
414 										 const char* description);
415 
~TextureBufferOperationsViaImageStore()416 	virtual ~TextureBufferOperationsViaImageStore()
417 	{
418 	}
419 
420 	virtual void deinit(void);
421 
422 private:
423 	/* Private methods */
424 	virtual void initializeBufferObjectData(void);
425 	virtual void fillBufferWithData(glw::GLint* buffer, glw::GLuint bufferLength);
426 
427 	std::string getISComputeShaderCode() const;
428 
429 	/* Private Variables */
430 	glw::GLuint m_is_cs_id;
431 	glw::GLuint m_is_po_id;
432 
433 	/* Private static constants */
434 	static const glw::GLuint m_image_unit;
435 };
436 
437 /* Test Case 6 - ssbo writes */
438 class TextureBufferOperationsViaSSBOWrites : public TextureBufferOperations
439 {
440 public:
441 	/* Public methods */
442 	TextureBufferOperationsViaSSBOWrites(Context& context, const ExtParameters& extParams, const char* name,
443 										 const char* description);
444 
~TextureBufferOperationsViaSSBOWrites()445 	virtual ~TextureBufferOperationsViaSSBOWrites()
446 	{
447 	}
448 
449 	virtual void deinit(void);
450 
451 private:
452 	/* Private methods */
453 	virtual void initializeBufferObjectData(void);
454 	virtual void fillBufferWithData(glw::GLint* buffer, glw::GLuint bufferLength);
455 
456 	std::string getSSBOComputeShaderCode() const;
457 
458 	/* Private variables */
459 	glw::GLuint m_ssbo_cs_id;
460 	glw::GLuint m_ssbo_po_id;
461 };
462 
463 } // namespace glcts
464 
465 #endif // _ESEXTCTEXTUREBUFFEROPERATIONS_HPP
466