blob: a5c27347af55a3590c3154c01921b0d9ddc79774 [file] [log] [blame]
#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