• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef _GL4CBUFFERSTORAGETESTS_HPP
2 #define _GL4CBUFFERSTORAGETESTS_HPP
3 /*-------------------------------------------------------------------------
4  * OpenGL Conformance Test Suite
5  * -----------------------------
6  *
7  * Copyright (c) 2015-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  gl4cBufferStorageTests.hpp
28  * \brief Declares test classes for "Buffer Storage" functionality.
29  */ /*-------------------------------------------------------------------*/
30 
31 #include "glcTestCase.hpp"
32 #include "glwDefs.hpp"
33 
34 namespace gl4cts
35 {
36 namespace BufferStorage
37 {
38 class Buffer;
39 
40 /** Implementation of test "Errors". Description follows:
41  *
42  * Verify that proper errors are generated:
43  * - INVALID_OPERATION is generated by BufferStorage when 0 is bound to
44  * <target>; Check all targets;
45  * - INVLIAD_OPERATION is generated by BufferStorage, NamedBufferStorage and
46  * BufferData if buffer already have immutable store;
47  * - INVALID_VALUE is generated by BufferStorage and NamedBufferStorage when
48  * <size> is less or equal to zero;
49  * - INVLAID_VALUE is generated by BufferStorage and NamedBufferStorage when
50  * <flags> contains MAP_PERSISTENT_BIT and neither MAP_READ_BIT nor
51  * MAP_WRITE_BIT;
52  * - INVALID_VALUE is generated by BufferStorage and NamedBufferStorage when
53  * <flags> contains MAP_COHERENT_BIT and no MAP_PERSISTENT_BIT;
54  * - INVALID_OPERATION is generated by MapBufferRange if any of:
55  *   * MAP_COHERENT_BIT,
56  *   * MAP_PERSISTENT_BIT,
57  *   * MAP_READ_BIT,
58  *   * MAP_WRITE_BIT
59  * is included in <access> and not in buffer's storage flags;
60  * - INVALID_OPERATION is generated by BufferSubData and NamedBufferSubData
61  * when buffer has immutable store but its flags does not include
62  * DYNAMIC_STORAGE.
63  **/
64 class ErrorsTest : public deqp::TestCase
65 {
66 public:
67 	/* Public methods */
68 	ErrorsTest(deqp::Context& context);
~ErrorsTest()69 	virtual ~ErrorsTest()
70 	{
71 	}
72 
73 	/* Public methods inherited from TestCase */
74 	virtual tcu::TestNode::IterateResult iterate(void);
75 
76 private:
77 	/* Private methods */
78 	void verifyError(glw::GLenum expected_error, const glw::GLchar* error_message, bool& out_test_result);
79 };
80 
81 /** Implementation of test "GetBufferParameter". Description follows:
82  *
83  * Verify that proper values are reported for buffers with immutable store.
84  *
85  * Steps:
86  * - prepare immutable buffer with tested set of <flags>;
87  * - inspect <param> BUFFER_STORAGE_FLAGS to verify that correct flags are
88  * reported;
89  * - inspect <param> BUFFER_IMMUTABLE_STORAGE to verify that TRUE is reported;
90  * - inspect <param> BUFFER_SIZE to verify that correct value is reported;
91  * - if tested flags set allows mapping, for each valid <access> set:
92  *   * execute MapBufferRange with given <access>
93  *   * inspect <param> BUFFER_ACCESS_FLAGS to verify that correct values are
94  *   reported;
95  * - delete buffer.
96  *
97  * Repeat steps for all valid combinations of flags for BufferStorage.
98  **/
99 class GetBufferParameterTest : public deqp::TestCase
100 {
101 public:
102 	/* Public methods */
103 	GetBufferParameterTest(deqp::Context& context);
~GetBufferParameterTest()104 	virtual ~GetBufferParameterTest()
105 	{
106 	}
107 
108 	/* Public methods inherited from TestCase */
109 	virtual tcu::TestNode::IterateResult iterate(void);
110 
111 private:
112 	/* Private types */
113 	struct testCase
114 	{
115 		testCase(glw::GLenum flags, glw::GLenum access);
116 
117 		glw::GLenum m_flags;
118 		glw::GLenum m_access;
119 	};
120 
121 	/* Private fields */
122 	std::vector<testCase> m_test_cases;
123 };
124 
125 /** Implementation of test "DynamicStorage". Description follows:
126  *
127  * Verify that:
128  * - server can update contents of immutable buffer when DYNAMIC_STORAGE_BIT is
129  * not set;
130  * - client cannot update contents of immutable buffer when DYNAMIC_STORAGE_BIT
131  * is not set;
132  * - client can update contents of immutable buffer when DYNAMIC_STORAGE_BIT is
133  * set.
134  *
135  * Steps:
136  * - prepare 64 bytes immutable buffer filled with value 1; Bind the buffer to
137  * COPY_READ_BUFFER;
138  * - prepare 64 bytes immutable buffer filled with value 2; Do not set
139  * DYNAMIC_STORAGE_BIT for <flags>; Bind the buffer to COPY_WRITE_BUFFER;
140  * - execute BufferSubData to update COPY_WRITE_BUFFER buffer with 64 bytes
141  * filled with value 3; INVLIAD_OPERATION error should be generated;
142  * - inspect contents of buffer to verify it is filled with 2;
143  * - execute CopyBufferSubData to transfer data from COPY_READ_BUFFER to
144  * COPY_WRITE_BUFFER; No error should be generated;
145  * - inspect contents of buffer to verify it is filled with 1;
146  * - delete buffer and create new one; This time <flags> should contain
147  * DYNAMIC_STORAGE_BIT; Bind the buffer to COPY_WRITE_BUFFER;
148  * - execute BufferSubData to update COPY_WRITE_BUFFER buffer with 64 bytes
149  * filled with value 3; No error should be generated;
150  * - inspect contents of buffer to verify it is filled with 3;
151  **/
152 class DynamicStorageTest : public deqp::TestCase
153 {
154 public:
155 	/* Public methods */
156 	DynamicStorageTest(deqp::Context& context);
~DynamicStorageTest()157 	virtual ~DynamicStorageTest()
158 	{
159 	}
160 
161 	/* Public methods inherited from TestCase */
162 	virtual tcu::TestNode::IterateResult iterate(void);
163 };
164 
165 /** Implementation of test "MapPersistentBufferSubData". Description follows:
166  *
167  * Verify that buffer mapped with MAP_PERSISTENT_BIT can be used by following
168  * operations:
169  * - BufferSubData,
170  * - NamedBufferSubData.
171  *
172  * Steps:
173  * - generate buffer and prepare its storage with BufferStorage; Use following
174  * flags MAP_PERSISTENT_BIT, MAP_READ_BIT and MAP_WRITE_BIT;
175  * Provide NULL as <data> and 64 as <size>;
176  * - bind buffer to ARRAY_BUFFER;
177  * - execute tested operation, to update whole buffer with incrementing values
178  * starting from 0; No error should be generated;
179  * - map buffer contents with MapBufferRange; <access> should contain
180  * MAP_PERSISTENT_BIT, MAP_READ_BIT and MAP_WRITE_BIT; Provide 16 as <offset>
181  * and <size>;
182  * - mapped region should contain values from 16 to 31;
183  * - execute tested operation, to update portions of buffer specified below;
184  * No error should be generated;
185  * - unmap buffer;
186  * - map buffer contents again, this time do not provide MAP_PERSISTENT_BIT;
187  * - execute tested operation to update regions specified below; It is expected
188  * that INVALID_OPERATION will be generated for cases that cross mapped region;
189  * No error should be generated for other cases.
190  *
191  * Repeat steps for all tested commands.
192  *
193  * Portions of buffer to be updated:
194  *
195  *   * before mapped region: <offset> 0,  <size> 16,
196  *   * after mapped region:  <offset> 32, <size> 16,
197  *   * at the beginning:     <offset> 8,  <size> 16,
198  *   * at the end:           <offset> 24, <size> 16,
199  *   * in the middle:        <offset> 12, <size> 8;
200  **/
201 class MapPersistentBufferSubDataTest : public deqp::TestCase
202 {
203 public:
204 	/* Public methods */
205 	MapPersistentBufferSubDataTest(deqp::Context& context);
~MapPersistentBufferSubDataTest()206 	virtual ~MapPersistentBufferSubDataTest()
207 	{
208 	}
209 
210 	/* Public methods inherited from TestCase */
211 	virtual tcu::TestNode::IterateResult iterate(void);
212 
213 private:
214 	/* Private types */
215 	struct testCase
216 	{
217 		glw::GLintptr   m_offset;
218 		glw::GLsizeiptr m_size;
219 		bool			m_cross_mapped_region;
220 	};
221 };
222 
223 /** Implementation of test "MapPersistentTexture". Description follows:
224  *
225  * Verify that buffer mapped with MAP_PERSISTENT_BIT can be used by following
226  * operations:
227  * - CompressedTexImage operations,
228  * - CompressedTexSubImage operations,
229  * - CompressedTextureSubImage operations,
230  * - TexImage operations,
231  * - TexSubImage operations.
232  *
233  * Steps:
234  * - generate buffer and prepare its storage with BufferStorage; Use following
235  * flags MAP_READ_BIT, MAP_WRITE_BIT and MAP_PERSISTENT_BIT; Provide data
236  * relevant for tested operation;
237  * - bind buffer to PIXEL_UNPACK_BUFFER;
238  * - prepare texture in a way that is relevant for tested operation;
239  * - execute tested operation, no error should be generated;
240  * - delete texture and prepare next one;
241  * - map buffer contents with MapBufferRange, <access> should contain
242  * MAP_PERSISTENT_BIT, MAP_READ_BIT and MAP_WRITE_BIT;
243  * - execute tested operation, no error should be generated;
244  * - delete texture and prepare next one;
245  * - unmap buffer
246  * - map buffer contents again, this time do not provide MAP_PERSISTENT_BIT;
247  * - execute tested operation, INVALID_OPERATION error should be generated.
248  *
249  * Repeat steps for all tested commands.
250  **/
251 class MapPersistentTextureTest : public deqp::TestCase
252 {
253 public:
254 	/* Public methods */
255 	MapPersistentTextureTest(deqp::Context& context);
256 
~MapPersistentTextureTest()257 	virtual ~MapPersistentTextureTest()
258 	{
259 	}
260 
261 	/* Public methods inherited from TestCase */
262 	virtual tcu::TestNode::IterateResult iterate(void);
263 
264 private:
265 	/* Private types */
266 	enum TESTED_OPERATION
267 	{
268 		OP_COMPRESSED_TEX_IMAGE = 0,
269 		OP_COMPRESSED_TEX_SUB_IMAGE,
270 		OP_COMPRESSED_TEXTURE_SUB_IMAGE,
271 		OP_TEX_IMAGE,
272 		OP_TEX_SUB_IMAGE,
273 
274 		TESTED_OPERATION_MAX
275 	};
276 
277 	void		getCompressedInfo();
278 	const char* getOperationName(TESTED_OPERATION operation);
279 
280 	bool verifyTestedOperation(TESTED_OPERATION operation, Buffer& buffer, glw::GLenum expected_error);
281 
282 	/* Private fields */
283 	glw::GLint m_compressed_image_size;
284 	glw::GLint m_compressed_internal_format;
285 };
286 
287 /** Implementation of test "MapPersistentReadPixels". Description follows:
288  *
289  * Verify that buffer mapped with MAP_PERSISTENT_BIT can be used by ReadPixels.
290  *
291  * Steps:
292  * - generate buffer and prepare its storage with BufferStorage; Use following
293  * flags MAP_PERSISTENT_BIT, MAP_READ_BIT and MAP_WRITE_BIT;
294  * Provide NULL as <data> and 64 as <size>;
295  * - bind buffer to PIXEL_PACK_BUFFER;
296  * - prepare 8x8 R8UI texture filled with unique values; Attach texture to FBO;
297  * - execute ReadPixels to transfer texture contents to buffer, no error should
298  * be generated;
299  * - update contents of texture with different image;
300  * - map buffer contents with MapBufferRange, <access> should contain
301  * MAP_PERSISTENT_BIT, MAP_READ_BIT and MAP_WRITE_BIT;
302  * - execute ReadPixels to transfer texture contents to buffer, no error should
303  * be generated;
304  * - execute MemoryBarrier with CLIENT_MAPPED_BUFFER_BARRIER_BIT and Finish;
305  * - inspect contents of mapped buffer, to verify that latest data transfer was
306  * successful;
307  * - unmap buffer
308  * - map buffer contents again, this time do not provide MAP_PERSISTENT_BIT;
309  * - execute ReadPixels to transfer texture contents to buffer,
310  * INVALID_OPERATION error should be generated.
311  **/
312 class MapPersistentReadPixelsTest : public deqp::TestCase
313 {
314 public:
315 	/* Public methods */
316 	MapPersistentReadPixelsTest(deqp::Context& context);
317 
~MapPersistentReadPixelsTest()318 	virtual ~MapPersistentReadPixelsTest()
319 	{
320 	}
321 
322 	/* Public methods inherited from TestCase */
323 	virtual tcu::TestNode::IterateResult iterate(void);
324 };
325 
326 /** Implementation of test "MapPersistentDispatch". Description follows:
327  *
328  * Test if dispatch operation can work with buffers mapped as
329  * MAP_PERSISTENT_BIT.
330  *
331  * Steps:
332  * - prepare program with compute shader that will:
333  *   * calculate sum gl_GlobalInvocationID.x elements of source buffer;
334  *   * store result in destination buffer at index gl_GlobalInvocationID.x;
335  * Contents of both buffers should be treated as unsigned integers;
336  * - prepare destination and source buffers as follows:
337  *   * both are immutable;
338  *   * both are 64 bytes long;
339  *   * destination is filled with 0;
340  *   * source is filled with specific unsigned integer values;
341  *   * both shall have MAP_COHERENT_BIT and MAP_PERSISTENT_BIT flags set;
342  *   * for source MAP_WRITE_BIT flag shall be set;
343  *   * for destination MAP_READ_BIT flag shall be set;
344  * - bind buffers to SHADER_STORAGE_BUFFER;
345  * - use MapBufferRange to map both buffers; <access> shall be set as follows:
346  *   * MAP_COHERENT_BIT and MAP_PERSISTENT_BIT flags set for both
347  *   * MAP_WRITE_BIT flag shall be set for source;
348  *   * MAP_READ_BIT flag shall be set for destination;
349  * - dispatch program for 16x1x1 groups;
350  * - execute Finish;
351  * - modify contents of source buffer via mapped memory;
352  * - inspect contents of destination buffer via mapped memory; It is expected
353  * that it will contain results based on original content of source buffer;
354  * - dispatch program for 16x1x1 groups;
355  * - execute Finish;
356  * - inspect contents of destination buffer via mapped memory; It is expected
357  * that it will contain results based on modified content of source buffer.
358  **/
359 class MapPersistentDispatchTest : public deqp::TestCase
360 {
361 public:
362 	/* Public methods */
363 	MapPersistentDispatchTest(deqp::Context& context);
364 
365 	MapPersistentDispatchTest(deqp::Context& context, const glw::GLchar* test_name,
366 							  const glw::GLchar* test_description);
367 
~MapPersistentDispatchTest()368 	virtual ~MapPersistentDispatchTest()
369 	{
370 	}
371 
372 	/* Public methods inherited from TestCase */
373 	virtual tcu::TestNode::IterateResult iterate(void);
374 };
375 
376 /** Implementation of test "MapPersistentFlush". Description follows:
377  *
378  * Test checks if FlushMappedBufferRange works correctly with persistent mapped
379  * buffers.
380  *
381  * Modify MapPersistenDispatch in the following aspects:
382  * - drop MAP_COHERENT_BIT for source buffer;
383  * - apply FlushMappedBufferRange to ensure that modifications of source buffer
384  * are visible to server.
385  **/
386 class MapPersistentFlushTest : public deqp::TestCase
387 {
388 public:
389 	/* Public methods */
390 	MapPersistentFlushTest(deqp::Context& context);
391 
~MapPersistentFlushTest()392 	virtual ~MapPersistentFlushTest()
393 	{
394 	}
395 
396 	/* Public methods inherited from TestCase */
397 	virtual tcu::TestNode::IterateResult iterate(void);
398 };
399 
400 /** Implementation of test "MapPersistentDraw". Description follows:
401  *
402  * Test if draw operation can work with buffers mapped as MAP_PERSISTENT_BIT.
403  *
404  * Steps:
405  * - prepare program consisting of vertex, geometry and fragment shader;
406  *   * vertex shader should output single varying "vs_gs_index" of type uint,
407  *   equal to gl_VertexID;
408  *   * geometry shader should:
409  *     - define single uniform buffer array "rectangles" with unspecified size;
410  *     Rectangles should have two vec2 fields: position and size;
411  *     - define single atomic_uint "atom_color";
412  *     - increment "atom_color" once per execution;
413  *     - output a quad that is placed at rectangles[vs_gs_index].position and
414  *     has size equal rectangles[vs_gs_index].size;
415  *     - define output float varying "gs_fs_color" equal to "atom_color" / 255;
416  *   * fragment shader should pass value of "gs_fs_color" varying to red
417  *   channel of output color;
418  * - prepare FBO with 16x16 RGBA8 texture as color 0 attachment filled with 0;
419  * - prepare immutable buffer with single unsigned integer bound to
420  * "atom_color";
421  * - prepare immutable buffer bound to "rectangles", with store for two sets of
422  * data (2 * 2 * sizeof(vec2));
423  * - make persistent mapping of both buffers for reads and writes;
424  * - modify "rectangles" buffer via mapped memory with the following two sets
425  *   * position [-0.5,-0.5], size [1.0,1.0],
426  *   * position [-0.25,-0.25], size [1.5,1.5];
427  * - modify "atom_color" buffer via mapped memory to value 1;
428  * - execute MemoryBarrier for CLIENT_MAPPED_BUFFER_BARRIER_BIT;
429  * - enable blending with functions ONE for both source and destination;
430  * - execute DrawArrays for two vertices;
431  * - execute MemoryBarrier for ALL_BARRIER_BITS and Finish;
432  * - inspect contents of:
433  *   * texture - to verify that pixel at 8,8 is filled with RGBA8(3,0,0,0),
434  *   * "atom_color" - to verify that it is equal to 3;
435  * - modify "rectangles" buffer via mapped memory with the following two sets
436  *   * position [-1.0,-1.0], size [0.5,0.5],
437  *   * position [0.5,0.5], size [0.5,0.5];
438  * - modify "atom_color" buffer via mapped memory to value 5;
439  * - execute MemoryBarrier for CLIENT_MAPPED_BUFFER_BARRIER_BIT;
440  * - execute DrawArrays for two vertices;
441  * - execute MemoryBarrier for ALL_BARRIER_BITS and Finish;
442  * - inspect contents of:
443  *   * texture - to verify that pixel at 8,8 is filled with RGBA8(3,0,0,0),
444  *   * "atom_color" - to verify that it is equal to 7;
445  *
446  *  OpenGL 4.5 Changes
447  *
448  *      The OpenGL 4.5 specification changed wording from:
449  *          "If MAP_COHERENT_BIT is not set and the client performs a write followed
450  *           by a call to the MemoryBarrier command with the CLIENT_MAPPED_BUFFER_BARRIER_BIT set,
451  *           then in subsequent commands the server will see the writes." (OpenGL 4.4, chapter 6.2)
452  *      to form:
453  *          "If MAP_COHERENT_BIT is not set and the client performs a write followed by
454  *           a call to one of the FlushMapped*BufferRange commands with a range including
455  *           the written range, then in subsequent commands the server will see the writes."
456  *          (OpenGL 4.5, chapter 6.2).
457  *      As a results writes to persistently mapped buffer shall be followed by FlushMapped*BufferRange
458  *      not the MemoryBarrier (MemoryBarrier only synchronizes form GPU to the CPU).
459  *
460  *      Steps:
461  *          Change MemoryBarrier to FlushMapped*BufferRange if context supports OpenGL 4.5 Core Profile.
462  *
463  **/
464 class MapPersistentDrawTest : public deqp::TestCase
465 {
466 public:
467 	/* Public methods */
468 	MapPersistentDrawTest(deqp::Context& context);
469 
~MapPersistentDrawTest()470 	virtual ~MapPersistentDrawTest()
471 	{
472 	}
473 
474 	/* Public methods inherited from TestCase */
475 	virtual tcu::TestNode::IterateResult iterate(void);
476 };
477 } /* BufferStorage */
478 
479 /** Group class for Buffer Storage conformance tests */
480 class BufferStorageTests : public deqp::TestCaseGroup
481 {
482 public:
483 	/* Public methods */
484 	BufferStorageTests(deqp::Context& context);
485 
~BufferStorageTests(void)486 	virtual ~BufferStorageTests(void)
487 	{
488 	}
489 
490 	virtual void init(void);
491 
492 private:
493 	/* Private methods */
494 	BufferStorageTests(const BufferStorageTests& other);
495 	BufferStorageTests& operator=(const BufferStorageTests& other);
496 };
497 
498 } /* gl4cts */
499 
500 #endif // _GL4CBUFFERSTORAGETESTS_HPP
501