| #ifndef _GL4CBUFFERSTORAGETESTS_HPP |
| #define _GL4CBUFFERSTORAGETESTS_HPP |
| /*------------------------------------------------------------------------- |
| * OpenGL Conformance Test Suite |
| * ----------------------------- |
| * |
| * Copyright (c) 2015-2016 The Khronos Group Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| */ /*! |
| * \file |
| * \brief |
| */ /*-------------------------------------------------------------------*/ |
| |
| /** |
| * \file gl4cBufferStorageTests.hpp |
| * \brief Declares test classes for "Buffer Storage" functionality. |
| */ /*-------------------------------------------------------------------*/ |
| |
| #include "glcTestCase.hpp" |
| #include "glwDefs.hpp" |
| |
| namespace gl4cts |
| { |
| namespace BufferStorage |
| { |
| class Buffer; |
| |
| /** Implementation of test "Errors". Description follows: |
| * |
| * Verify that proper errors are generated: |
| * - INVALID_OPERATION is generated by BufferStorage when 0 is bound to |
| * <target>; Check all targets; |
| * - INVLIAD_OPERATION is generated by BufferStorage, NamedBufferStorage and |
| * BufferData if buffer already have immutable store; |
| * - INVALID_VALUE is generated by BufferStorage and NamedBufferStorage when |
| * <size> is less or equal to zero; |
| * - INVLAID_VALUE is generated by BufferStorage and NamedBufferStorage when |
| * <flags> contains MAP_PERSISTENT_BIT and neither MAP_READ_BIT nor |
| * MAP_WRITE_BIT; |
| * - INVALID_VALUE is generated by BufferStorage and NamedBufferStorage when |
| * <flags> contains MAP_COHERENT_BIT and no MAP_PERSISTENT_BIT; |
| * - INVALID_OPERATION is generated by MapBufferRange if any of: |
| * * MAP_COHERENT_BIT, |
| * * MAP_PERSISTENT_BIT, |
| * * MAP_READ_BIT, |
| * * MAP_WRITE_BIT |
| * is included in <access> and not in buffer's storage flags; |
| * - INVALID_OPERATION is generated by BufferSubData and NamedBufferSubData |
| * when buffer has immutable store but its flags does not include |
| * DYNAMIC_STORAGE. |
| **/ |
| class ErrorsTest : public deqp::TestCase |
| { |
| public: |
| /* Public methods */ |
| ErrorsTest(deqp::Context& context); |
| virtual ~ErrorsTest() |
| { |
| } |
| |
| /* Public methods inherited from TestCase */ |
| virtual tcu::TestNode::IterateResult iterate(void); |
| |
| private: |
| /* Private methods */ |
| void verifyError(glw::GLenum expected_error, const glw::GLchar* error_message, bool& out_test_result); |
| }; |
| |
| /** Implementation of test "GetBufferParameter". Description follows: |
| * |
| * Verify that proper values are reported for buffers with immutable store. |
| * |
| * Steps: |
| * - prepare immutable buffer with tested set of <flags>; |
| * - inspect <param> BUFFER_STORAGE_FLAGS to verify that correct flags are |
| * reported; |
| * - inspect <param> BUFFER_IMMUTABLE_STORAGE to verify that TRUE is reported; |
| * - inspect <param> BUFFER_SIZE to verify that correct value is reported; |
| * - if tested flags set allows mapping, for each valid <access> set: |
| * * execute MapBufferRange with given <access> |
| * * inspect <param> BUFFER_ACCESS_FLAGS to verify that correct values are |
| * reported; |
| * - delete buffer. |
| * |
| * Repeat steps for all valid combinations of flags for BufferStorage. |
| **/ |
| class GetBufferParameterTest : public deqp::TestCase |
| { |
| public: |
| /* Public methods */ |
| GetBufferParameterTest(deqp::Context& context); |
| virtual ~GetBufferParameterTest() |
| { |
| } |
| |
| /* Public methods inherited from TestCase */ |
| virtual tcu::TestNode::IterateResult iterate(void); |
| |
| private: |
| /* Private types */ |
| struct testCase |
| { |
| testCase(glw::GLenum flags, glw::GLenum access); |
| |
| glw::GLenum m_flags; |
| glw::GLenum m_access; |
| }; |
| |
| /* Private fields */ |
| std::vector<testCase> m_test_cases; |
| }; |
| |
| /** Implementation of test "DynamicStorage". Description follows: |
| * |
| * Verify that: |
| * - server can update contents of immutable buffer when DYNAMIC_STORAGE_BIT is |
| * not set; |
| * - client cannot update contents of immutable buffer when DYNAMIC_STORAGE_BIT |
| * is not set; |
| * - client can update contents of immutable buffer when DYNAMIC_STORAGE_BIT is |
| * set. |
| * |
| * Steps: |
| * - prepare 64 bytes immutable buffer filled with value 1; Bind the buffer to |
| * COPY_READ_BUFFER; |
| * - prepare 64 bytes immutable buffer filled with value 2; Do not set |
| * DYNAMIC_STORAGE_BIT for <flags>; Bind the buffer to COPY_WRITE_BUFFER; |
| * - execute BufferSubData to update COPY_WRITE_BUFFER buffer with 64 bytes |
| * filled with value 3; INVLIAD_OPERATION error should be generated; |
| * - inspect contents of buffer to verify it is filled with 2; |
| * - execute CopyBufferSubData to transfer data from COPY_READ_BUFFER to |
| * COPY_WRITE_BUFFER; No error should be generated; |
| * - inspect contents of buffer to verify it is filled with 1; |
| * - delete buffer and create new one; This time <flags> should contain |
| * DYNAMIC_STORAGE_BIT; Bind the buffer to COPY_WRITE_BUFFER; |
| * - execute BufferSubData to update COPY_WRITE_BUFFER buffer with 64 bytes |
| * filled with value 3; No error should be generated; |
| * - inspect contents of buffer to verify it is filled with 3; |
| **/ |
| class DynamicStorageTest : public deqp::TestCase |
| { |
| public: |
| /* Public methods */ |
| DynamicStorageTest(deqp::Context& context); |
| virtual ~DynamicStorageTest() |
| { |
| } |
| |
| /* Public methods inherited from TestCase */ |
| virtual tcu::TestNode::IterateResult iterate(void); |
| }; |
| |
| /** Implementation of test "MapPersistentBufferSubData". Description follows: |
| * |
| * Verify that buffer mapped with MAP_PERSISTENT_BIT can be used by following |
| * operations: |
| * - BufferSubData, |
| * - NamedBufferSubData. |
| * |
| * Steps: |
| * - generate buffer and prepare its storage with BufferStorage; Use following |
| * flags MAP_PERSISTENT_BIT, MAP_READ_BIT and MAP_WRITE_BIT; |
| * Provide NULL as <data> and 64 as <size>; |
| * - bind buffer to ARRAY_BUFFER; |
| * - execute tested operation, to update whole buffer with incrementing values |
| * starting from 0; No error should be generated; |
| * - map buffer contents with MapBufferRange; <access> should contain |
| * MAP_PERSISTENT_BIT, MAP_READ_BIT and MAP_WRITE_BIT; Provide 16 as <offset> |
| * and <size>; |
| * - mapped region should contain values from 16 to 31; |
| * - execute tested operation, to update portions of buffer specified below; |
| * No error should be generated; |
| * - unmap buffer; |
| * - map buffer contents again, this time do not provide MAP_PERSISTENT_BIT; |
| * - execute tested operation to update regions specified below; It is expected |
| * that INVALID_OPERATION will be generated for cases that cross mapped region; |
| * No error should be generated for other cases. |
| * |
| * Repeat steps for all tested commands. |
| * |
| * Portions of buffer to be updated: |
| * |
| * * before mapped region: <offset> 0, <size> 16, |
| * * after mapped region: <offset> 32, <size> 16, |
| * * at the beginning: <offset> 8, <size> 16, |
| * * at the end: <offset> 24, <size> 16, |
| * * in the middle: <offset> 12, <size> 8; |
| **/ |
| class MapPersistentBufferSubDataTest : public deqp::TestCase |
| { |
| public: |
| /* Public methods */ |
| MapPersistentBufferSubDataTest(deqp::Context& context); |
| virtual ~MapPersistentBufferSubDataTest() |
| { |
| } |
| |
| /* Public methods inherited from TestCase */ |
| virtual tcu::TestNode::IterateResult iterate(void); |
| |
| private: |
| /* Private types */ |
| struct testCase |
| { |
| glw::GLintptr m_offset; |
| glw::GLsizeiptr m_size; |
| bool m_cross_mapped_region; |
| }; |
| }; |
| |
| /** Implementation of test "MapPersistentTexture". Description follows: |
| * |
| * Verify that buffer mapped with MAP_PERSISTENT_BIT can be used by following |
| * operations: |
| * - CompressedTexImage operations, |
| * - CompressedTexSubImage operations, |
| * - CompressedTextureSubImage operations, |
| * - TexImage operations, |
| * - TexSubImage operations. |
| * |
| * Steps: |
| * - generate buffer and prepare its storage with BufferStorage; Use following |
| * flags MAP_READ_BIT, MAP_WRITE_BIT and MAP_PERSISTENT_BIT; Provide data |
| * relevant for tested operation; |
| * - bind buffer to PIXEL_UNPACK_BUFFER; |
| * - prepare texture in a way that is relevant for tested operation; |
| * - execute tested operation, no error should be generated; |
| * - delete texture and prepare next one; |
| * - map buffer contents with MapBufferRange, <access> should contain |
| * MAP_PERSISTENT_BIT, MAP_READ_BIT and MAP_WRITE_BIT; |
| * - execute tested operation, no error should be generated; |
| * - delete texture and prepare next one; |
| * - unmap buffer |
| * - map buffer contents again, this time do not provide MAP_PERSISTENT_BIT; |
| * - execute tested operation, INVALID_OPERATION error should be generated. |
| * |
| * Repeat steps for all tested commands. |
| **/ |
| class MapPersistentTextureTest : public deqp::TestCase |
| { |
| public: |
| /* Public methods */ |
| MapPersistentTextureTest(deqp::Context& context); |
| |
| virtual ~MapPersistentTextureTest() |
| { |
| } |
| |
| /* Public methods inherited from TestCase */ |
| virtual tcu::TestNode::IterateResult iterate(void); |
| |
| private: |
| /* Private types */ |
| enum TESTED_OPERATION |
| { |
| OP_COMPRESSED_TEX_IMAGE = 0, |
| OP_COMPRESSED_TEX_SUB_IMAGE, |
| OP_COMPRESSED_TEXTURE_SUB_IMAGE, |
| OP_TEX_IMAGE, |
| OP_TEX_SUB_IMAGE, |
| |
| TESTED_OPERATION_MAX |
| }; |
| |
| void getCompressedInfo(); |
| const char* getOperationName(TESTED_OPERATION operation); |
| |
| bool verifyTestedOperation(TESTED_OPERATION operation, Buffer& buffer, glw::GLenum expected_error); |
| |
| /* Private fields */ |
| glw::GLint m_compressed_image_size; |
| glw::GLint m_compressed_internal_format; |
| }; |
| |
| /** Implementation of test "MapPersistentReadPixels". Description follows: |
| * |
| * Verify that buffer mapped with MAP_PERSISTENT_BIT can be used by ReadPixels. |
| * |
| * Steps: |
| * - generate buffer and prepare its storage with BufferStorage; Use following |
| * flags MAP_PERSISTENT_BIT, MAP_READ_BIT and MAP_WRITE_BIT; |
| * Provide NULL as <data> and 64 as <size>; |
| * - bind buffer to PIXEL_PACK_BUFFER; |
| * - prepare 8x8 R8UI texture filled with unique values; Attach texture to FBO; |
| * - execute ReadPixels to transfer texture contents to buffer, no error should |
| * be generated; |
| * - update contents of texture with different image; |
| * - map buffer contents with MapBufferRange, <access> should contain |
| * MAP_PERSISTENT_BIT, MAP_READ_BIT and MAP_WRITE_BIT; |
| * - execute ReadPixels to transfer texture contents to buffer, no error should |
| * be generated; |
| * - execute MemoryBarrier with CLIENT_MAPPED_BUFFER_BARRIER_BIT and Finish; |
| * - inspect contents of mapped buffer, to verify that latest data transfer was |
| * successful; |
| * - unmap buffer |
| * - map buffer contents again, this time do not provide MAP_PERSISTENT_BIT; |
| * - execute ReadPixels to transfer texture contents to buffer, |
| * INVALID_OPERATION error should be generated. |
| **/ |
| class MapPersistentReadPixelsTest : public deqp::TestCase |
| { |
| public: |
| /* Public methods */ |
| MapPersistentReadPixelsTest(deqp::Context& context); |
| |
| virtual ~MapPersistentReadPixelsTest() |
| { |
| } |
| |
| /* Public methods inherited from TestCase */ |
| virtual tcu::TestNode::IterateResult iterate(void); |
| }; |
| |
| /** Implementation of test "MapPersistentDispatch". Description follows: |
| * |
| * Test if dispatch operation can work with buffers mapped as |
| * MAP_PERSISTENT_BIT. |
| * |
| * Steps: |
| * - prepare program with compute shader that will: |
| * * calculate sum gl_GlobalInvocationID.x elements of source buffer; |
| * * store result in destination buffer at index gl_GlobalInvocationID.x; |
| * Contents of both buffers should be treated as unsigned integers; |
| * - prepare destination and source buffers as follows: |
| * * both are immutable; |
| * * both are 64 bytes long; |
| * * destination is filled with 0; |
| * * source is filled with specific unsigned integer values; |
| * * both shall have MAP_COHERENT_BIT and MAP_PERSISTENT_BIT flags set; |
| * * for source MAP_WRITE_BIT flag shall be set; |
| * * for destination MAP_READ_BIT flag shall be set; |
| * - bind buffers to SHADER_STORAGE_BUFFER; |
| * - use MapBufferRange to map both buffers; <access> shall be set as follows: |
| * * MAP_COHERENT_BIT and MAP_PERSISTENT_BIT flags set for both |
| * * MAP_WRITE_BIT flag shall be set for source; |
| * * MAP_READ_BIT flag shall be set for destination; |
| * - dispatch program for 16x1x1 groups; |
| * - execute Finish; |
| * - modify contents of source buffer via mapped memory; |
| * - inspect contents of destination buffer via mapped memory; It is expected |
| * that it will contain results based on original content of source buffer; |
| * - dispatch program for 16x1x1 groups; |
| * - execute Finish; |
| * - inspect contents of destination buffer via mapped memory; It is expected |
| * that it will contain results based on modified content of source buffer. |
| **/ |
| class MapPersistentDispatchTest : public deqp::TestCase |
| { |
| public: |
| /* Public methods */ |
| MapPersistentDispatchTest(deqp::Context& context); |
| |
| MapPersistentDispatchTest(deqp::Context& context, const glw::GLchar* test_name, |
| const glw::GLchar* test_description); |
| |
| virtual ~MapPersistentDispatchTest() |
| { |
| } |
| |
| /* Public methods inherited from TestCase */ |
| virtual tcu::TestNode::IterateResult iterate(void); |
| }; |
| |
| /** Implementation of test "MapPersistentFlush". Description follows: |
| * |
| * Test checks if FlushMappedBufferRange works correctly with persistent mapped |
| * buffers. |
| * |
| * Modify MapPersistenDispatch in the following aspects: |
| * - drop MAP_COHERENT_BIT for source buffer; |
| * - apply FlushMappedBufferRange to ensure that modifications of source buffer |
| * are visible to server. |
| **/ |
| class MapPersistentFlushTest : public deqp::TestCase |
| { |
| public: |
| /* Public methods */ |
| MapPersistentFlushTest(deqp::Context& context); |
| |
| virtual ~MapPersistentFlushTest() |
| { |
| } |
| |
| /* Public methods inherited from TestCase */ |
| virtual tcu::TestNode::IterateResult iterate(void); |
| }; |
| |
| /** Implementation of test "MapPersistentDraw". Description follows: |
| * |
| * Test if draw operation can work with buffers mapped as MAP_PERSISTENT_BIT. |
| * |
| * Steps: |
| * - prepare program consisting of vertex, geometry and fragment shader; |
| * * vertex shader should output single varying "vs_gs_index" of type uint, |
| * equal to gl_VertexID; |
| * * geometry shader should: |
| * - define single uniform buffer array "rectangles" with unspecified size; |
| * Rectangles should have two vec2 fields: position and size; |
| * - define single atomic_uint "atom_color"; |
| * - increment "atom_color" once per execution; |
| * - output a quad that is placed at rectangles[vs_gs_index].position and |
| * has size equal rectangles[vs_gs_index].size; |
| * - define output float varying "gs_fs_color" equal to "atom_color" / 255; |
| * * fragment shader should pass value of "gs_fs_color" varying to red |
| * channel of output color; |
| * - prepare FBO with 16x16 RGBA8 texture as color 0 attachment filled with 0; |
| * - prepare immutable buffer with single unsigned integer bound to |
| * "atom_color"; |
| * - prepare immutable buffer bound to "rectangles", with store for two sets of |
| * data (2 * 2 * sizeof(vec2)); |
| * - make persistent mapping of both buffers for reads and writes; |
| * - modify "rectangles" buffer via mapped memory with the following two sets |
| * * position [-0.5,-0.5], size [1.0,1.0], |
| * * position [-0.25,-0.25], size [1.5,1.5]; |
| * - modify "atom_color" buffer via mapped memory to value 1; |
| * - execute MemoryBarrier for CLIENT_MAPPED_BUFFER_BARRIER_BIT; |
| * - enable blending with functions ONE for both source and destination; |
| * - execute DrawArrays for two vertices; |
| * - execute MemoryBarrier for ALL_BARRIER_BITS and Finish; |
| * - inspect contents of: |
| * * texture - to verify that pixel at 8,8 is filled with RGBA8(3,0,0,0), |
| * * "atom_color" - to verify that it is equal to 3; |
| * - modify "rectangles" buffer via mapped memory with the following two sets |
| * * position [-1.0,-1.0], size [0.5,0.5], |
| * * position [0.5,0.5], size [0.5,0.5]; |
| * - modify "atom_color" buffer via mapped memory to value 5; |
| * - execute MemoryBarrier for CLIENT_MAPPED_BUFFER_BARRIER_BIT; |
| * - execute DrawArrays for two vertices; |
| * - execute MemoryBarrier for ALL_BARRIER_BITS and Finish; |
| * - inspect contents of: |
| * * texture - to verify that pixel at 8,8 is filled with RGBA8(3,0,0,0), |
| * * "atom_color" - to verify that it is equal to 7; |
| * |
| * OpenGL 4.5 Changes |
| * |
| * The OpenGL 4.5 specification changed wording from: |
| * "If MAP_COHERENT_BIT is not set and the client performs a write followed |
| * by a call to the MemoryBarrier command with the CLIENT_MAPPED_BUFFER_BARRIER_BIT set, |
| * then in subsequent commands the server will see the writes." (OpenGL 4.4, chapter 6.2) |
| * to form: |
| * "If MAP_COHERENT_BIT is not set and the client performs a write followed by |
| * a call to one of the FlushMapped*BufferRange commands with a range including |
| * the written range, then in subsequent commands the server will see the writes." |
| * (OpenGL 4.5, chapter 6.2). |
| * As a results writes to persistently mapped buffer shall be followed by FlushMapped*BufferRange |
| * not the MemoryBarrier (MemoryBarrier only synchronizes form GPU to the CPU). |
| * |
| * Steps: |
| * Change MemoryBarrier to FlushMapped*BufferRange if context supports OpenGL 4.5 Core Profile. |
| * |
| **/ |
| class MapPersistentDrawTest : public deqp::TestCase |
| { |
| public: |
| /* Public methods */ |
| MapPersistentDrawTest(deqp::Context& context); |
| |
| virtual ~MapPersistentDrawTest() |
| { |
| } |
| |
| /* Public methods inherited from TestCase */ |
| virtual tcu::TestNode::IterateResult iterate(void); |
| }; |
| } /* BufferStorage */ |
| |
| /** Group class for Buffer Storage conformance tests */ |
| class BufferStorageTests : public deqp::TestCaseGroup |
| { |
| public: |
| /* Public methods */ |
| BufferStorageTests(deqp::Context& context); |
| |
| virtual ~BufferStorageTests(void) |
| { |
| } |
| |
| virtual void init(void); |
| |
| private: |
| /* Private methods */ |
| BufferStorageTests(const BufferStorageTests& other); |
| BufferStorageTests& operator=(const BufferStorageTests& other); |
| }; |
| |
| } /* gl4cts */ |
| |
| #endif // _GL4CBUFFERSTORAGETESTS_HPP |