1e5c31af7Sopenharmony_ci#ifndef _GL4CSPARSEBUFFERTESTS_HPP 2e5c31af7Sopenharmony_ci#define _GL4CSPARSEBUFFERTESTS_HPP 3e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 4e5c31af7Sopenharmony_ci * OpenGL Conformance Test Suite 5e5c31af7Sopenharmony_ci * ----------------------------- 6e5c31af7Sopenharmony_ci * 7e5c31af7Sopenharmony_ci * Copyright (c) 2015-2016 The Khronos Group Inc. 8e5c31af7Sopenharmony_ci * 9e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 10e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 11e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 14e5c31af7Sopenharmony_ci * 15e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 16e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 17e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 19e5c31af7Sopenharmony_ci * limitations under the License. 20e5c31af7Sopenharmony_ci * 21e5c31af7Sopenharmony_ci */ /*! 22e5c31af7Sopenharmony_ci * \file 23e5c31af7Sopenharmony_ci * \brief 24e5c31af7Sopenharmony_ci */ /*-------------------------------------------------------------------*/ 25e5c31af7Sopenharmony_ci 26e5c31af7Sopenharmony_ci/** 27e5c31af7Sopenharmony_ci */ /*! 28e5c31af7Sopenharmony_ci * \file gl4cSparseBufferTests.hpp 29e5c31af7Sopenharmony_ci * \brief Conformance tests for the GL_ARB_sparse_buffer functionality. 30e5c31af7Sopenharmony_ci */ /*-------------------------------------------------------------------*/ 31e5c31af7Sopenharmony_ci#include "glcTestCase.hpp" 32e5c31af7Sopenharmony_ci#include "glwDefs.hpp" 33e5c31af7Sopenharmony_ci#include "glwEnums.hpp" 34e5c31af7Sopenharmony_ci#include "tcuDefs.hpp" 35e5c31af7Sopenharmony_ci#include <vector> 36e5c31af7Sopenharmony_ci 37e5c31af7Sopenharmony_cinamespace gl4cts 38e5c31af7Sopenharmony_ci{ 39e5c31af7Sopenharmony_ci/** Utility functions, used across many sparse buffer conformance test classes. */ 40e5c31af7Sopenharmony_ciclass SparseBufferTestUtilities 41e5c31af7Sopenharmony_ci{ 42e5c31af7Sopenharmony_cipublic: 43e5c31af7Sopenharmony_ci /* Public methods */ 44e5c31af7Sopenharmony_ci static unsigned int alignOffset(const unsigned int& offset, const unsigned int& value); 45e5c31af7Sopenharmony_ci 46e5c31af7Sopenharmony_ci static glw::GLuint createComputeProgram(const glw::Functions& gl, const char** cs_body_parts, 47e5c31af7Sopenharmony_ci unsigned int n_cs_body_parts); 48e5c31af7Sopenharmony_ci 49e5c31af7Sopenharmony_ci static glw::GLuint createProgram(const glw::Functions& gl, const char** fs_body_parts, unsigned int n_fs_body_parts, 50e5c31af7Sopenharmony_ci const char** vs_body_parts, unsigned int n_vs_body_parts, 51e5c31af7Sopenharmony_ci const char** attribute_names, const unsigned int* attribute_locations, 52e5c31af7Sopenharmony_ci unsigned int n_attribute_properties, 53e5c31af7Sopenharmony_ci const glw::GLchar* const* tf_varyings = DE_NULL, unsigned int n_tf_varyings = 0, 54e5c31af7Sopenharmony_ci glw::GLenum tf_varying_mode = GL_NONE); 55e5c31af7Sopenharmony_ci 56e5c31af7Sopenharmony_ci static std::string getSparseBOFlagsString(glw::GLenum flags); 57e5c31af7Sopenharmony_ci}; 58e5c31af7Sopenharmony_ci 59e5c31af7Sopenharmony_ci/** * Verify glBufferPageCommitmentARB() returns GL_INVALID_ENUM if <target> is 60e5c31af7Sopenharmony_ci * set to GL_INTERLEAVED_ATTRIBS. 61e5c31af7Sopenharmony_ci * 62e5c31af7Sopenharmony_ci * * Verify glBufferStorage() throws a GL_INVALID_VALUE error if <flags> is 63e5c31af7Sopenharmony_ci * set to (GL_SPARSE_STORAGE_BIT_ARB | GL_MAP_READ_BIT) or 64e5c31af7Sopenharmony_ci * (GL_SPARSE_STORAGE_BIT_ARB | GL_MAP_WRITE_BIT). 65e5c31af7Sopenharmony_ci * 66e5c31af7Sopenharmony_ci * * Verify glBufferPageCommitmentARB() generates a GL_INVALID_OPERATION error if 67e5c31af7Sopenharmony_ci * it is called for an immutable BO, which has not been initialized with the 68e5c31af7Sopenharmony_ci * GL_SPARSE_STORAGE_BIT_ARB flag. 69e5c31af7Sopenharmony_ci * 70e5c31af7Sopenharmony_ci * * Verify glBufferPageCommitmentARB() issues a GL_INVALID_VALUE error if <offset> 71e5c31af7Sopenharmony_ci * is set to (0.5 * GL_SPARSE_BUFFER_PAGE_SIZE_ARB). Skip if the constant's value 72e5c31af7Sopenharmony_ci * is equal to 1. 73e5c31af7Sopenharmony_ci * 74e5c31af7Sopenharmony_ci * * Verify glBufferPageCommitmentARB() emits a GL_INVALID_VALUE error if <size> 75e5c31af7Sopenharmony_ci * is set to (0.5 * GL_SPARSE_BUFFER_PAGE_SIZE_ARB). Skip if the constant's value 76e5c31af7Sopenharmony_ci * is equal to 1. 77e5c31af7Sopenharmony_ci * 78e5c31af7Sopenharmony_ci * * Verify glBufferPageCommitmentARB() returns GL_INVALID_VALUE if <offset> is 79e5c31af7Sopenharmony_ci * set to -1, but all other arguments are valid. 80e5c31af7Sopenharmony_ci * 81e5c31af7Sopenharmony_ci * * Verify glBufferPageCommitmentARB() returns GL_INVALID_VALUE if <size> is 82e5c31af7Sopenharmony_ci * set to -1, but all other arguments are valid. 83e5c31af7Sopenharmony_ci * 84e5c31af7Sopenharmony_ci * * Verify glBufferPageCommitmentARB() returns GL_INVALID_VALUE if BO's size is 85e5c31af7Sopenharmony_ci * GL_SPARSE_BUFFER_PAGE_SIZE_ARB * 3, but the <offset> is set to 0 and <size> 86e5c31af7Sopenharmony_ci * argument used for the call is set to GL_SPARSE_BUFFER_PAGE_SIZE_ARB * 4. 87e5c31af7Sopenharmony_ci * 88e5c31af7Sopenharmony_ci * * Verify glBufferPageCommitmentARB() returns GL_INVALID_VALUE if BO's size is 89e5c31af7Sopenharmony_ci * GL_SPARSE_BUFFER_PAGE_SIZE_ARB * 3, but the <offset> is set to 90e5c31af7Sopenharmony_ci * GL_SPARSE_BUFFER_PAGE_SIZE_ARB * 1 and <size> argument used for the call 91e5c31af7Sopenharmony_ci * is set to GL_SPARSE_BUFFER_PAGE_SIZE_ARB * 3. 92e5c31af7Sopenharmony_ci * 93e5c31af7Sopenharmony_ci * * Verify that calling glMapBuffer() or glMapBufferRange() against a sparse 94e5c31af7Sopenharmony_ci * buffer generates a GL_INVALID_OPERATION error. 95e5c31af7Sopenharmony_ci **/ 96e5c31af7Sopenharmony_ciclass NegativeTests : public deqp::TestCase 97e5c31af7Sopenharmony_ci{ 98e5c31af7Sopenharmony_cipublic: 99e5c31af7Sopenharmony_ci /* Public methods */ 100e5c31af7Sopenharmony_ci NegativeTests(deqp::Context& context); 101e5c31af7Sopenharmony_ci 102e5c31af7Sopenharmony_ci void deinit(); 103e5c31af7Sopenharmony_ci void init(); 104e5c31af7Sopenharmony_ci tcu::TestNode::IterateResult iterate(); 105e5c31af7Sopenharmony_ci 106e5c31af7Sopenharmony_ciprivate: 107e5c31af7Sopenharmony_ci /* Private methods */ 108e5c31af7Sopenharmony_ci 109e5c31af7Sopenharmony_ci /* Private members */ 110e5c31af7Sopenharmony_ci glw::GLuint m_helper_bo_id; /* never allocated actual storage; bound to GL_ELEMENT_ARRAY_BUFFER */ 111e5c31af7Sopenharmony_ci glw::GLuint m_immutable_bo_id; /* bound to GL_COPY_READ_BUFFER */ 112e5c31af7Sopenharmony_ci const unsigned int m_immutable_bo_size; 113e5c31af7Sopenharmony_ci 114e5c31af7Sopenharmony_ci glw::GLuint m_sparse_bo_id; /* bound to GL_ARRAY_BUFFER */ 115e5c31af7Sopenharmony_ci}; 116e5c31af7Sopenharmony_ci 117e5c31af7Sopenharmony_ci/** 1. Make sure glGetBooleanv(), glGetDoublev(), glGetFloatv(), glGetIntegerv() 118e5c31af7Sopenharmony_ci * and glGetInteger64v() recognize the new GL_SPARSE_BUFFER_PAGE_SIZE_ARB 119e5c31af7Sopenharmony_ci * pname and return a value equal to or larger than 1, but no bigger than 65536 120e5c31af7Sopenharmony_ci */ 121e5c31af7Sopenharmony_ciclass PageSizeGetterTest : public deqp::TestCase 122e5c31af7Sopenharmony_ci{ 123e5c31af7Sopenharmony_cipublic: 124e5c31af7Sopenharmony_ci /* Public methods */ 125e5c31af7Sopenharmony_ci PageSizeGetterTest(deqp::Context& context); 126e5c31af7Sopenharmony_ci 127e5c31af7Sopenharmony_ci void deinit(); 128e5c31af7Sopenharmony_ci void init(); 129e5c31af7Sopenharmony_ci tcu::TestNode::IterateResult iterate(); 130e5c31af7Sopenharmony_ci}; 131e5c31af7Sopenharmony_ci 132e5c31af7Sopenharmony_ci/** Interface class for test case implementation for the functional test 2. */ 133e5c31af7Sopenharmony_ciclass BufferStorageTestCase 134e5c31af7Sopenharmony_ci{ 135e5c31af7Sopenharmony_cipublic: 136e5c31af7Sopenharmony_ci virtual ~BufferStorageTestCase() 137e5c31af7Sopenharmony_ci { 138e5c31af7Sopenharmony_ci } 139e5c31af7Sopenharmony_ci 140e5c31af7Sopenharmony_ci /* Public methods */ 141e5c31af7Sopenharmony_ci virtual void deinitTestCaseGlobal() = 0; 142e5c31af7Sopenharmony_ci virtual bool execute(glw::GLuint sparse_bo_storage_flags) = 0; 143e5c31af7Sopenharmony_ci virtual const char* getName() = 0; 144e5c31af7Sopenharmony_ci virtual bool initTestCaseGlobal() = 0; 145e5c31af7Sopenharmony_ci virtual bool initTestCaseIteration(glw::GLuint sparse_bo) = 0; 146e5c31af7Sopenharmony_ci 147e5c31af7Sopenharmony_ci virtual void deinitTestCaseIteration() 148e5c31af7Sopenharmony_ci { 149e5c31af7Sopenharmony_ci /* Stub by default */ 150e5c31af7Sopenharmony_ci } 151e5c31af7Sopenharmony_ci}; 152e5c31af7Sopenharmony_ci 153e5c31af7Sopenharmony_ci/** Implements the test case e for the test 2: 154e5c31af7Sopenharmony_ci * 155e5c31af7Sopenharmony_ci * e. Use the committed sparse buffer storage to store atomic counter values. 156e5c31af7Sopenharmony_ci * The vertex shader used for the test case should define as many ACs as 157e5c31af7Sopenharmony_ci * supported by the platform (GL_MAX_VERTEX_ATOMIC_COUNTERS). The condition, 158e5c31af7Sopenharmony_ci * under which each of the ACs should be incremented, can be based on 159e5c31af7Sopenharmony_ci * gl_VertexID's value (eg. increment AC0 if gl_VertexID % 2 == 0, increment 160e5c31af7Sopenharmony_ci * AC1 if gl_VertexID % 3 == 0, and so on). 161e5c31af7Sopenharmony_ci * 162e5c31af7Sopenharmony_ci * Use regular draw calls, issued consecutively for three times, for the 163e5c31af7Sopenharmony_ci * test. 164e5c31af7Sopenharmony_ci * Verify that both atomic counter buffer binding commands (glBindBufferBase() 165e5c31af7Sopenharmony_ci * and glBindBufferRange() ) work correctly. 166e5c31af7Sopenharmony_ci * 167e5c31af7Sopenharmony_ci * The test passes if the result values are correct. 168e5c31af7Sopenharmony_ci * 169e5c31af7Sopenharmony_ci * The test should run in two iterations: 170e5c31af7Sopenharmony_ci * a) All required pages are committed. 171e5c31af7Sopenharmony_ci * b) Only half of the pages are committed. If only a single page is needed, 172e5c31af7Sopenharmony_ci * de-commit that page before issuing the draw call. 173e5c31af7Sopenharmony_ci */ 174e5c31af7Sopenharmony_ciclass AtomicCounterBufferStorageTestCase : public BufferStorageTestCase 175e5c31af7Sopenharmony_ci{ 176e5c31af7Sopenharmony_cipublic: 177e5c31af7Sopenharmony_ci /* Public methods */ 178e5c31af7Sopenharmony_ci AtomicCounterBufferStorageTestCase(const glw::Functions& gl, tcu::TestContext& testContext, glw::GLint page_size, 179e5c31af7Sopenharmony_ci bool all_pages_committed); 180e5c31af7Sopenharmony_ci 181e5c31af7Sopenharmony_ci /* BufferStorageTestCase implementation */ 182e5c31af7Sopenharmony_ci void deinitTestCaseGlobal(); 183e5c31af7Sopenharmony_ci void deinitTestCaseIteration(); 184e5c31af7Sopenharmony_ci 185e5c31af7Sopenharmony_ci bool execute(glw::GLuint sparse_bo_storage_flags); 186e5c31af7Sopenharmony_ci bool initTestCaseGlobal(); 187e5c31af7Sopenharmony_ci bool initTestCaseIteration(glw::GLuint sparse_bo); 188e5c31af7Sopenharmony_ci 189e5c31af7Sopenharmony_ci const char* getName() 190e5c31af7Sopenharmony_ci { 191e5c31af7Sopenharmony_ci return "case e"; 192e5c31af7Sopenharmony_ci } 193e5c31af7Sopenharmony_ci 194e5c31af7Sopenharmony_ciprivate: 195e5c31af7Sopenharmony_ci /* Private fields */ 196e5c31af7Sopenharmony_ci bool m_all_pages_committed; 197e5c31af7Sopenharmony_ci const glw::Functions& m_gl; 198e5c31af7Sopenharmony_ci glw::GLint m_gl_atomic_counter_uniform_array_stride; 199e5c31af7Sopenharmony_ci glw::GLint m_gl_max_vertex_atomic_counters_value; 200e5c31af7Sopenharmony_ci glw::GLuint m_helper_bo; 201e5c31af7Sopenharmony_ci unsigned int m_helper_bo_size; 202e5c31af7Sopenharmony_ci unsigned int m_helper_bo_size_rounded; 203e5c31af7Sopenharmony_ci const unsigned int m_n_draw_calls; 204e5c31af7Sopenharmony_ci glw::GLint m_page_size; 205e5c31af7Sopenharmony_ci glw::GLuint m_po; 206e5c31af7Sopenharmony_ci glw::GLuint m_sparse_bo; 207e5c31af7Sopenharmony_ci unsigned int m_sparse_bo_data_size; 208e5c31af7Sopenharmony_ci unsigned int m_sparse_bo_data_size_rounded; /* aligned to page size */ 209e5c31af7Sopenharmony_ci unsigned int m_sparse_bo_data_start_offset; 210e5c31af7Sopenharmony_ci unsigned int m_sparse_bo_data_start_offset_rounded; /* <= m_sparse_bo_data_start_offset, aligned to page size */ 211e5c31af7Sopenharmony_ci tcu::TestContext& m_testCtx; 212e5c31af7Sopenharmony_ci glw::GLuint m_vao; 213e5c31af7Sopenharmony_ci}; 214e5c31af7Sopenharmony_ci 215e5c31af7Sopenharmony_ci/** Implements the test case f for the test 2: 216e5c31af7Sopenharmony_ci * 217e5c31af7Sopenharmony_ci * f. Use the committed sparse buffer storage as a backing for a buffer texture 218e5c31af7Sopenharmony_ci * object. A compute shader should inspect the contents of the texture and, 219e5c31af7Sopenharmony_ci * for invocation-specific texels, write out 1 to a SSBO if the fetched texel 220e5c31af7Sopenharmony_ci * was correct. Otherwise, it should write out 0. 221e5c31af7Sopenharmony_ci * 222e5c31af7Sopenharmony_ci * The shader storage block needs not be backed by a sparse buffer. 223e5c31af7Sopenharmony_ci * 224e5c31af7Sopenharmony_ci * As with previous cases, make sure both of the following scenarios are 225e5c31af7Sopenharmony_ci * tested: 226e5c31af7Sopenharmony_ci * 227e5c31af7Sopenharmony_ci * a) All required pages are committed. 228e5c31af7Sopenharmony_ci * b) Only half of the pages are committed. If only a single page is needed, 229e5c31af7Sopenharmony_ci * de-commit that page before issuing the dispatch call. 230e5c31af7Sopenharmony_ci * 231e5c31af7Sopenharmony_ci * Both glTexBuffer() and glTexBufferRange() should be tested. 232e5c31af7Sopenharmony_ci * 233e5c31af7Sopenharmony_ci */ 234e5c31af7Sopenharmony_ciclass BufferTextureStorageTestCase : public BufferStorageTestCase 235e5c31af7Sopenharmony_ci{ 236e5c31af7Sopenharmony_cipublic: 237e5c31af7Sopenharmony_ci /* Public methods */ 238e5c31af7Sopenharmony_ci BufferTextureStorageTestCase(const glw::Functions& gl, deqp::Context& context, tcu::TestContext& testContext, 239e5c31af7Sopenharmony_ci glw::GLint page_size); 240e5c31af7Sopenharmony_ci 241e5c31af7Sopenharmony_ci /* BufferStorageTestCase implementation */ 242e5c31af7Sopenharmony_ci void deinitTestCaseGlobal(); 243e5c31af7Sopenharmony_ci void deinitTestCaseIteration(); 244e5c31af7Sopenharmony_ci bool execute(glw::GLuint sparse_bo_storage_flags); 245e5c31af7Sopenharmony_ci bool initTestCaseGlobal(); 246e5c31af7Sopenharmony_ci bool initTestCaseIteration(glw::GLuint sparse_bo); 247e5c31af7Sopenharmony_ci 248e5c31af7Sopenharmony_ci const char* getName() 249e5c31af7Sopenharmony_ci { 250e5c31af7Sopenharmony_ci return "case f"; 251e5c31af7Sopenharmony_ci } 252e5c31af7Sopenharmony_ci 253e5c31af7Sopenharmony_ciprivate: 254e5c31af7Sopenharmony_ci /* Private fields */ 255e5c31af7Sopenharmony_ci const glw::Functions& m_gl; 256e5c31af7Sopenharmony_ci glw::GLuint m_helper_bo; 257e5c31af7Sopenharmony_ci unsigned char* m_helper_bo_data; 258e5c31af7Sopenharmony_ci unsigned int m_helper_bo_data_size; 259e5c31af7Sopenharmony_ci bool m_is_texture_buffer_range_supported; 260e5c31af7Sopenharmony_ci glw::GLint m_page_size; 261e5c31af7Sopenharmony_ci glw::GLuint m_po; 262e5c31af7Sopenharmony_ci const unsigned int m_po_local_wg_size; 263e5c31af7Sopenharmony_ci glw::GLuint m_sparse_bo; 264e5c31af7Sopenharmony_ci unsigned int m_sparse_bo_size; 265e5c31af7Sopenharmony_ci unsigned int m_sparse_bo_size_rounded; 266e5c31af7Sopenharmony_ci glw::GLuint m_ssbo; 267e5c31af7Sopenharmony_ci unsigned char* m_ssbo_zero_data; 268e5c31af7Sopenharmony_ci unsigned int m_ssbo_zero_data_size; 269e5c31af7Sopenharmony_ci tcu::TestContext& m_testCtx; 270e5c31af7Sopenharmony_ci glw::GLuint m_to; 271e5c31af7Sopenharmony_ci const unsigned int m_to_width; 272e5c31af7Sopenharmony_ci}; 273e5c31af7Sopenharmony_ci 274e5c31af7Sopenharmony_ci/** Implements the test case c for the test 2: 275e5c31af7Sopenharmony_ci * 276e5c31af7Sopenharmony_ci * c. Issue glClearBufferData() and glClearBufferSubData() calls 277e5c31af7Sopenharmony_ci * over a sparse buffer. Make sure that all committed pages, which should 278e5c31af7Sopenharmony_ci * have been affected by the calls, have been reset to the requested 279e5c31af7Sopenharmony_ci * values. 280e5c31af7Sopenharmony_ci * Try issuing glClearNamedBufferSubData() over a region, for which one 281e5c31af7Sopenharmony_ci * of the halves is committed, and the other is not. Make sure the former 282e5c31af7Sopenharmony_ci * has been touched, and that no crash has occurred. 283e5c31af7Sopenharmony_ci * 284e5c31af7Sopenharmony_ci */ 285e5c31af7Sopenharmony_ciclass ClearOpsBufferStorageTestCase : public BufferStorageTestCase 286e5c31af7Sopenharmony_ci{ 287e5c31af7Sopenharmony_cipublic: 288e5c31af7Sopenharmony_ci /* Public methods */ 289e5c31af7Sopenharmony_ci ClearOpsBufferStorageTestCase(const glw::Functions& gl, tcu::TestContext& testContext, glw::GLint page_size); 290e5c31af7Sopenharmony_ci 291e5c31af7Sopenharmony_ci /* BufferStorageTestCase implementation */ 292e5c31af7Sopenharmony_ci void deinitTestCaseGlobal(); 293e5c31af7Sopenharmony_ci void deinitTestCaseIteration(); 294e5c31af7Sopenharmony_ci bool execute(glw::GLuint sparse_bo_storage_flags); 295e5c31af7Sopenharmony_ci bool initTestCaseGlobal(); 296e5c31af7Sopenharmony_ci bool initTestCaseIteration(glw::GLuint sparse_bo); 297e5c31af7Sopenharmony_ci 298e5c31af7Sopenharmony_ci const char* getName() 299e5c31af7Sopenharmony_ci { 300e5c31af7Sopenharmony_ci return "case c"; 301e5c31af7Sopenharmony_ci } 302e5c31af7Sopenharmony_ci 303e5c31af7Sopenharmony_ciprivate: 304e5c31af7Sopenharmony_ci /* Private fields */ 305e5c31af7Sopenharmony_ci const glw::Functions& m_gl; 306e5c31af7Sopenharmony_ci glw::GLuint m_helper_bo; /* holds m_sparse_bo_size_rounded bytes */ 307e5c31af7Sopenharmony_ci unsigned char* m_initial_data; /* holds m_sparse_bo_size_rounded bytes */ 308e5c31af7Sopenharmony_ci unsigned int m_n_pages_to_use; 309e5c31af7Sopenharmony_ci glw::GLint m_page_size; 310e5c31af7Sopenharmony_ci glw::GLuint m_sparse_bo; 311e5c31af7Sopenharmony_ci unsigned int m_sparse_bo_size_rounded; 312e5c31af7Sopenharmony_ci tcu::TestContext& m_testCtx; 313e5c31af7Sopenharmony_ci}; 314e5c31af7Sopenharmony_ci 315e5c31af7Sopenharmony_ci/** Implements the test case g for the test 2: 316e5c31af7Sopenharmony_ci * 317e5c31af7Sopenharmony_ci * g. Verify copy operations work correctly for cases where: 318e5c31af7Sopenharmony_ci * 319e5c31af7Sopenharmony_ci * I) Destination and source are different sparse BOs. 320e5c31af7Sopenharmony_ci * II) Destination is a sparse buffer object, source is an immutable BO. 321e5c31af7Sopenharmony_ci * III) Destination is an immutable BO, source is a sparse BO. 322e5c31af7Sopenharmony_ci * IV) Destination and source are the same sparse BO, but refer to 323e5c31af7Sopenharmony_ci * different, non-overlapping memory regions. 324e5c31af7Sopenharmony_ci * 325e5c31af7Sopenharmony_ci * and 326e5c31af7Sopenharmony_ci * 327e5c31af7Sopenharmony_ci * *) All pages of the source region are not committed 328e5c31af7Sopenharmony_ci * **) Half of the pages of the source region is not committed 329e5c31af7Sopenharmony_ci * ***) None of the pages of the source region are committed. 330e5c31af7Sopenharmony_ci * 331e5c31af7Sopenharmony_ci * and 332e5c31af7Sopenharmony_ci * 333e5c31af7Sopenharmony_ci * +) All pages of the destination region are not committed 334e5c31af7Sopenharmony_ci * ++) Half of the pages of the destination region is not committed 335e5c31af7Sopenharmony_ci * +++) None of the pages of the destination region are committed. 336e5c31af7Sopenharmony_ci * 337e5c31af7Sopenharmony_ci * Test all combinations of I-IV, *-***, and +-+++ bearing in mind that: 338e5c31af7Sopenharmony_ci * 339e5c31af7Sopenharmony_ci * a) reads executed on non-committed memory regions return meaningless 340e5c31af7Sopenharmony_ci * values but MUST NOT crash GL 341e5c31af7Sopenharmony_ci * b) writes performed on non-committed memory regions are silently 342e5c31af7Sopenharmony_ci * ignored. 343e5c31af7Sopenharmony_ci */ 344e5c31af7Sopenharmony_ciclass CopyOpsBufferStorageTestCase : public BufferStorageTestCase 345e5c31af7Sopenharmony_ci{ 346e5c31af7Sopenharmony_cipublic: 347e5c31af7Sopenharmony_ci /* Public methods */ 348e5c31af7Sopenharmony_ci CopyOpsBufferStorageTestCase(const glw::Functions& gl, tcu::TestContext& testContext, glw::GLint page_size); 349e5c31af7Sopenharmony_ci 350e5c31af7Sopenharmony_ci /* BufferStorageTestCase implementation */ 351e5c31af7Sopenharmony_ci void deinitTestCaseGlobal(); 352e5c31af7Sopenharmony_ci void deinitTestCaseIteration(); 353e5c31af7Sopenharmony_ci bool execute(glw::GLuint sparse_bo_storage_flags); 354e5c31af7Sopenharmony_ci bool initTestCaseGlobal(); 355e5c31af7Sopenharmony_ci bool initTestCaseIteration(glw::GLuint sparse_bo); 356e5c31af7Sopenharmony_ci 357e5c31af7Sopenharmony_ci const char* getName() 358e5c31af7Sopenharmony_ci { 359e5c31af7Sopenharmony_ci return "case g"; 360e5c31af7Sopenharmony_ci } 361e5c31af7Sopenharmony_ci 362e5c31af7Sopenharmony_ciprivate: 363e5c31af7Sopenharmony_ci /* Private type definitions */ 364e5c31af7Sopenharmony_ci typedef struct _test_case 365e5c31af7Sopenharmony_ci { 366e5c31af7Sopenharmony_ci glw::GLint dst_bo_commit_size; 367e5c31af7Sopenharmony_ci glw::GLint dst_bo_commit_start_offset; 368e5c31af7Sopenharmony_ci glw::GLuint dst_bo_sparse_id; 369e5c31af7Sopenharmony_ci bool dst_bo_is_sparse; 370e5c31af7Sopenharmony_ci unsigned short* dst_bo_ref_data; 371e5c31af7Sopenharmony_ci glw::GLint dst_bo_start_offset; 372e5c31af7Sopenharmony_ci 373e5c31af7Sopenharmony_ci glw::GLint n_bytes_to_copy; 374e5c31af7Sopenharmony_ci 375e5c31af7Sopenharmony_ci glw::GLint src_bo_commit_size; 376e5c31af7Sopenharmony_ci glw::GLint src_bo_commit_start_offset; 377e5c31af7Sopenharmony_ci glw::GLuint src_bo_sparse_id; 378e5c31af7Sopenharmony_ci bool src_bo_is_sparse; 379e5c31af7Sopenharmony_ci unsigned short* src_bo_ref_data; 380e5c31af7Sopenharmony_ci glw::GLint src_bo_start_offset; 381e5c31af7Sopenharmony_ci } _test_case; 382e5c31af7Sopenharmony_ci 383e5c31af7Sopenharmony_ci typedef std::vector<_test_case> _test_cases; 384e5c31af7Sopenharmony_ci typedef _test_cases::const_iterator _test_cases_const_iterator; 385e5c31af7Sopenharmony_ci typedef _test_cases::iterator _test_cases_iterator; 386e5c31af7Sopenharmony_ci 387e5c31af7Sopenharmony_ci /* Private methods */ 388e5c31af7Sopenharmony_ci void initReferenceData(); 389e5c31af7Sopenharmony_ci void initTestCases(); 390e5c31af7Sopenharmony_ci 391e5c31af7Sopenharmony_ci /* Private fields */ 392e5c31af7Sopenharmony_ci const glw::Functions& m_gl; 393e5c31af7Sopenharmony_ci glw::GLuint m_helper_bo; 394e5c31af7Sopenharmony_ci glw::GLuint m_immutable_bo; 395e5c31af7Sopenharmony_ci glw::GLint m_page_size; 396e5c31af7Sopenharmony_ci unsigned short* m_ref_data[3]; /* [0] - immutable bo data, [1] - sparse bo[0] data, [2] - sparse bo[1] data. 397e5c31af7Sopenharmony_ci * 398e5c31af7Sopenharmony_ci * Each data buffer holds m_sparse_bo_size_rounded bytes. 399e5c31af7Sopenharmony_ci */ 400e5c31af7Sopenharmony_ci glw::GLuint m_sparse_bos[2]; /* [0] - provided by BufferStorageTest[0], [1] - managed by the test case */ 401e5c31af7Sopenharmony_ci unsigned int m_sparse_bo_size; 402e5c31af7Sopenharmony_ci unsigned int m_sparse_bo_size_rounded; 403e5c31af7Sopenharmony_ci _test_cases m_test_cases; 404e5c31af7Sopenharmony_ci tcu::TestContext& m_testCtx; 405e5c31af7Sopenharmony_ci}; 406e5c31af7Sopenharmony_ci 407e5c31af7Sopenharmony_ci/** Implements the test case h for the test 2: 408e5c31af7Sopenharmony_ci * 409e5c31af7Sopenharmony_ci * h. Verify indirect dispatch calls work correctly for the following cases: 410e5c31af7Sopenharmony_ci * 411e5c31af7Sopenharmony_ci * a) The arguments are taken from a committed memory page. 412e5c31af7Sopenharmony_ci * b) The arguments are taken from a de-committed memory page. We expect 413e5c31af7Sopenharmony_ci * the dispatch request to be silently ignored in this case. 414e5c31af7Sopenharmony_ci * c) Half of the arguments are taken from a committed memory page, 415e5c31af7Sopenharmony_ci * and the other half come from a de-committed memory page. Anticipated 416e5c31af7Sopenharmony_ci * result is as per b). 417e5c31af7Sopenharmony_ci * 418e5c31af7Sopenharmony_ci * Each spawned compute shader invocation should increment an atomic 419e5c31af7Sopenharmony_ci * counter. 420e5c31af7Sopenharmony_ci * 421e5c31af7Sopenharmony_ci */ 422e5c31af7Sopenharmony_ciclass IndirectDispatchBufferStorageTestCase : public BufferStorageTestCase 423e5c31af7Sopenharmony_ci{ 424e5c31af7Sopenharmony_cipublic: 425e5c31af7Sopenharmony_ci /* Public methods */ 426e5c31af7Sopenharmony_ci IndirectDispatchBufferStorageTestCase(const glw::Functions& gl, tcu::TestContext& testContext, 427e5c31af7Sopenharmony_ci glw::GLint page_size); 428e5c31af7Sopenharmony_ci 429e5c31af7Sopenharmony_ci /* BufferStorageTestCase implementation */ 430e5c31af7Sopenharmony_ci void deinitTestCaseGlobal(); 431e5c31af7Sopenharmony_ci void deinitTestCaseIteration(); 432e5c31af7Sopenharmony_ci bool execute(glw::GLuint sparse_bo_storage_flags); 433e5c31af7Sopenharmony_ci bool initTestCaseGlobal(); 434e5c31af7Sopenharmony_ci bool initTestCaseIteration(glw::GLuint sparse_bo); 435e5c31af7Sopenharmony_ci 436e5c31af7Sopenharmony_ci const char* getName() 437e5c31af7Sopenharmony_ci { 438e5c31af7Sopenharmony_ci return "case h"; 439e5c31af7Sopenharmony_ci } 440e5c31af7Sopenharmony_ci 441e5c31af7Sopenharmony_ciprivate: 442e5c31af7Sopenharmony_ci /* Private fields */ 443e5c31af7Sopenharmony_ci unsigned int m_dispatch_draw_call_args_start_offset; 444e5c31af7Sopenharmony_ci unsigned int m_expected_ac_value; 445e5c31af7Sopenharmony_ci const glw::Functions& m_gl; 446e5c31af7Sopenharmony_ci const unsigned int m_global_wg_size_x; 447e5c31af7Sopenharmony_ci glw::GLuint m_helper_bo; /* stores AC value + indirect dispatch call args */ 448e5c31af7Sopenharmony_ci const unsigned int m_local_wg_size_x; 449e5c31af7Sopenharmony_ci glw::GLint m_page_size; 450e5c31af7Sopenharmony_ci glw::GLuint m_po; 451e5c31af7Sopenharmony_ci glw::GLuint m_sparse_bo; 452e5c31af7Sopenharmony_ci unsigned int m_sparse_bo_size; 453e5c31af7Sopenharmony_ci unsigned int m_sparse_bo_size_rounded; 454e5c31af7Sopenharmony_ci tcu::TestContext& m_testCtx; 455e5c31af7Sopenharmony_ci}; 456e5c31af7Sopenharmony_ci 457e5c31af7Sopenharmony_ci/** Implements the test case d for the test 2: 458e5c31af7Sopenharmony_ci * 459e5c31af7Sopenharmony_ci * d. Issue glInvalidateBufferData() and glInvalidateBufferSubData() calls for 460e5c31af7Sopenharmony_ci * sparse buffers. For the *SubData() case, make sure you test both of 461e5c31af7Sopenharmony_ci * cases: 462e5c31af7Sopenharmony_ci * 463e5c31af7Sopenharmony_ci * * the whole touched region has been committed 464e5c31af7Sopenharmony_ci * * only half of the pages have physical backing. 465e5c31af7Sopenharmony_ci */ 466e5c31af7Sopenharmony_ciclass InvalidateBufferStorageTestCase : public BufferStorageTestCase 467e5c31af7Sopenharmony_ci{ 468e5c31af7Sopenharmony_cipublic: 469e5c31af7Sopenharmony_ci /* Public methods */ 470e5c31af7Sopenharmony_ci InvalidateBufferStorageTestCase(const glw::Functions& gl, tcu::TestContext& testContext, glw::GLint page_size); 471e5c31af7Sopenharmony_ci 472e5c31af7Sopenharmony_ci /* BufferStorageTestCase implementation */ 473e5c31af7Sopenharmony_ci void deinitTestCaseGlobal(); 474e5c31af7Sopenharmony_ci void deinitTestCaseIteration(); 475e5c31af7Sopenharmony_ci bool execute(glw::GLuint sparse_bo_storage_flags); 476e5c31af7Sopenharmony_ci bool initTestCaseGlobal(); 477e5c31af7Sopenharmony_ci bool initTestCaseIteration(glw::GLuint sparse_bo); 478e5c31af7Sopenharmony_ci 479e5c31af7Sopenharmony_ci const char* getName() 480e5c31af7Sopenharmony_ci { 481e5c31af7Sopenharmony_ci return "case d"; 482e5c31af7Sopenharmony_ci } 483e5c31af7Sopenharmony_ci 484e5c31af7Sopenharmony_ciprivate: 485e5c31af7Sopenharmony_ci /* Private fields */ 486e5c31af7Sopenharmony_ci const glw::Functions& m_gl; 487e5c31af7Sopenharmony_ci unsigned int m_n_pages_to_use; 488e5c31af7Sopenharmony_ci const glw::GLint m_page_size; 489e5c31af7Sopenharmony_ci glw::GLuint m_sparse_bo; 490e5c31af7Sopenharmony_ci unsigned int m_sparse_bo_size; 491e5c31af7Sopenharmony_ci unsigned int m_sparse_bo_size_rounded; 492e5c31af7Sopenharmony_ci}; 493e5c31af7Sopenharmony_ci 494e5c31af7Sopenharmony_ci/** Implement the test case k from CTS_ARB_sparse_buffer: 495e5c31af7Sopenharmony_ci * 496e5c31af7Sopenharmony_ci * k. Verify pixel pack functionality works correctly, when a sparse buffer 497e5c31af7Sopenharmony_ci * is bound to the pixel pack buffer binding point. Render a black-to-white 498e5c31af7Sopenharmony_ci * RGBA8 gradient and use glReadPixels() to read & verify the rendered 499e5c31af7Sopenharmony_ci * data. The color attachment should be of 1024x1024 resolution. 500e5c31af7Sopenharmony_ci * 501e5c31af7Sopenharmony_ci * Consider three scenarios: 502e5c31af7Sopenharmony_ci * 503e5c31af7Sopenharmony_ci * a) All pages, to which the data is to be written to, have been committed. 504e5c31af7Sopenharmony_ci * b) Use the same memory page commitment layout as proposed in b2. The 505e5c31af7Sopenharmony_ci * committed pages should contain correct data. Contents the pages 506e5c31af7Sopenharmony_ci * without the physical backing should not be verified. 507e5c31af7Sopenharmony_ci * c) No pages have been committed. The draw & read call should not crash 508e5c31af7Sopenharmony_ci * the driver, but the actual contents is of no relevance. 509e5c31af7Sopenharmony_ci * 510e5c31af7Sopenharmony_ci **/ 511e5c31af7Sopenharmony_ciclass PixelPackBufferStorageTestCase : public BufferStorageTestCase 512e5c31af7Sopenharmony_ci{ 513e5c31af7Sopenharmony_cipublic: 514e5c31af7Sopenharmony_ci /* Public methods */ 515e5c31af7Sopenharmony_ci PixelPackBufferStorageTestCase(const glw::Functions& gl, tcu::TestContext& testContext, glw::GLint page_size); 516e5c31af7Sopenharmony_ci 517e5c31af7Sopenharmony_ci /* BufferStorageTestCase implementation */ 518e5c31af7Sopenharmony_ci void deinitTestCaseGlobal(); 519e5c31af7Sopenharmony_ci void deinitTestCaseIteration(); 520e5c31af7Sopenharmony_ci bool execute(glw::GLuint sparse_bo_storage_flags); 521e5c31af7Sopenharmony_ci bool initTestCaseGlobal(); 522e5c31af7Sopenharmony_ci bool initTestCaseIteration(glw::GLuint sparse_bo); 523e5c31af7Sopenharmony_ci 524e5c31af7Sopenharmony_ci const char* getName() 525e5c31af7Sopenharmony_ci { 526e5c31af7Sopenharmony_ci return "case k"; 527e5c31af7Sopenharmony_ci } 528e5c31af7Sopenharmony_ci 529e5c31af7Sopenharmony_ciprivate: 530e5c31af7Sopenharmony_ci /* Private fields */ 531e5c31af7Sopenharmony_ci glw::GLuint m_color_rb; 532e5c31af7Sopenharmony_ci const unsigned int m_color_rb_height; 533e5c31af7Sopenharmony_ci const unsigned int m_color_rb_width; 534e5c31af7Sopenharmony_ci glw::GLuint m_fbo; 535e5c31af7Sopenharmony_ci const glw::Functions& m_gl; 536e5c31af7Sopenharmony_ci glw::GLuint m_helper_bo; 537e5c31af7Sopenharmony_ci glw::GLint m_page_size; 538e5c31af7Sopenharmony_ci glw::GLuint m_po; 539e5c31af7Sopenharmony_ci unsigned char* m_ref_data_ptr; 540e5c31af7Sopenharmony_ci unsigned int m_ref_data_size; 541e5c31af7Sopenharmony_ci glw::GLuint m_sparse_bo; 542e5c31af7Sopenharmony_ci unsigned int m_sparse_bo_size; 543e5c31af7Sopenharmony_ci unsigned int m_sparse_bo_size_rounded; 544e5c31af7Sopenharmony_ci tcu::TestContext& m_testCtx; 545e5c31af7Sopenharmony_ci glw::GLuint m_vao; 546e5c31af7Sopenharmony_ci}; 547e5c31af7Sopenharmony_ci 548e5c31af7Sopenharmony_ci/** Implements the test case l for the test 2: 549e5c31af7Sopenharmony_ci * 550e5c31af7Sopenharmony_ci * l. Verify pixel unpack functionality works correctly, when a sparse buffer 551e5c31af7Sopenharmony_ci * is bound to the pixel unpack buffer binding point. Use a black-to-white 552e5c31af7Sopenharmony_ci * gradient texture data for a glTexSubImage2D() call applied against an 553e5c31af7Sopenharmony_ci * immutable texture object's base mip-map. Read back the data with 554e5c31af7Sopenharmony_ci * a glGetTexImage() call and verify the contents is valid. 555e5c31af7Sopenharmony_ci * 556e5c31af7Sopenharmony_ci * Consider three scenarios: 557e5c31af7Sopenharmony_ci * 558e5c31af7Sopenharmony_ci * a) All pages, from which the texture data were read from, have been 559e5c31af7Sopenharmony_ci * committed at the glTexSubImage2D() call time. 560e5c31af7Sopenharmony_ci * b) Use the same memory page commitment layout as proposed in b2. The 561e5c31af7Sopenharmony_ci * test should only check contents of the committed memory pages. 562e5c31af7Sopenharmony_ci * c) No pages have been committed at the glTexSubImage2D() call time. 563e5c31af7Sopenharmony_ci * The upload & getter calls should not crash, but the returned 564e5c31af7Sopenharmony_ci * contents are irrelevant in this case. 565e5c31af7Sopenharmony_ci */ 566e5c31af7Sopenharmony_ciclass PixelUnpackBufferStorageTestCase : public BufferStorageTestCase 567e5c31af7Sopenharmony_ci{ 568e5c31af7Sopenharmony_cipublic: 569e5c31af7Sopenharmony_ci /* Public methods */ 570e5c31af7Sopenharmony_ci PixelUnpackBufferStorageTestCase(const glw::Functions& gl, tcu::TestContext& testContext, glw::GLint page_size); 571e5c31af7Sopenharmony_ci 572e5c31af7Sopenharmony_ci /* BufferStorageTestCase implementation */ 573e5c31af7Sopenharmony_ci void deinitTestCaseGlobal(); 574e5c31af7Sopenharmony_ci void deinitTestCaseIteration(); 575e5c31af7Sopenharmony_ci bool execute(glw::GLuint sparse_bo_storage_flags); 576e5c31af7Sopenharmony_ci bool initTestCaseGlobal(); 577e5c31af7Sopenharmony_ci bool initTestCaseIteration(glw::GLuint sparse_bo); 578e5c31af7Sopenharmony_ci 579e5c31af7Sopenharmony_ci const char* getName() 580e5c31af7Sopenharmony_ci { 581e5c31af7Sopenharmony_ci return "case l"; 582e5c31af7Sopenharmony_ci } 583e5c31af7Sopenharmony_ci 584e5c31af7Sopenharmony_ciprivate: 585e5c31af7Sopenharmony_ci /* Private fields */ 586e5c31af7Sopenharmony_ci const glw::Functions& m_gl; 587e5c31af7Sopenharmony_ci glw::GLuint m_helper_bo; 588e5c31af7Sopenharmony_ci glw::GLint m_page_size; 589e5c31af7Sopenharmony_ci unsigned char* m_read_data_ptr; 590e5c31af7Sopenharmony_ci glw::GLuint m_sparse_bo; 591e5c31af7Sopenharmony_ci unsigned int m_sparse_bo_size; 592e5c31af7Sopenharmony_ci unsigned int m_sparse_bo_size_rounded; 593e5c31af7Sopenharmony_ci tcu::TestContext& m_testCtx; 594e5c31af7Sopenharmony_ci unsigned char* m_texture_data_ptr; 595e5c31af7Sopenharmony_ci unsigned int m_texture_data_size; 596e5c31af7Sopenharmony_ci glw::GLuint m_to; 597e5c31af7Sopenharmony_ci unsigned char* m_to_data_zero; 598e5c31af7Sopenharmony_ci const unsigned int m_to_height; 599e5c31af7Sopenharmony_ci const unsigned int m_to_width; 600e5c31af7Sopenharmony_ci}; 601e5c31af7Sopenharmony_ci 602e5c31af7Sopenharmony_ci/** Implements test cases a1-a6 for the test 2: 603e5c31af7Sopenharmony_ci * 604e5c31af7Sopenharmony_ci * a1. Use the sparse buffer as a VBO. 605e5c31af7Sopenharmony_ci * 606e5c31af7Sopenharmony_ci * The render-target should be drawn a total of 100 x 100 green quads 607e5c31af7Sopenharmony_ci * (built of triangles). Fill the buffer with vertex data (use four 608e5c31af7Sopenharmony_ci * components, even though we need the rectangles to be rendered in 609e5c31af7Sopenharmony_ci * screen space, in order to assure that the data-set spans across 610e5c31af7Sopenharmony_ci * multiple pages by exceeding the maximum permitted page size of 64KB). 611e5c31af7Sopenharmony_ci * 612e5c31af7Sopenharmony_ci * The quads should be 5px in width & height, and be separated from each 613e5c31af7Sopenharmony_ci * other by a delta of 5px. 614e5c31af7Sopenharmony_ci * 615e5c31af7Sopenharmony_ci * Render the quads to a render-target of 1024x1024 resolution. 616e5c31af7Sopenharmony_ci * 617e5c31af7Sopenharmony_ci * All the pages, to which the vertex data has been submitted, should 618e5c31af7Sopenharmony_ci * be committed. The test case passes if the rendered data is correct. 619e5c31af7Sopenharmony_ci * 620e5c31af7Sopenharmony_ci * a2. Follow the same approach as described for a1. However, this time, 621e5c31af7Sopenharmony_ci * after the vertex data is uploaded, the test should de-commit all the 622e5c31af7Sopenharmony_ci * pages and attempt to do the draw call. 623e5c31af7Sopenharmony_ci * 624e5c31af7Sopenharmony_ci * The test passes if the GL implementation does not crash. Do not 625e5c31af7Sopenharmony_ci * validate the rendered data. 626e5c31af7Sopenharmony_ci * 627e5c31af7Sopenharmony_ci * a3. Follow the same approach as described for a1. However, this time, 628e5c31af7Sopenharmony_ci * make sure to also provide an IBO and issue an indexed draw call 629e5c31af7Sopenharmony_ci * (both ranged and non-ranged). All required VBO and IBO pages should 630e5c31af7Sopenharmony_ci * be committed. 631e5c31af7Sopenharmony_ci * 632e5c31af7Sopenharmony_ci * The pass condition described in a1 is not changed. 633e5c31af7Sopenharmony_ci * 634e5c31af7Sopenharmony_ci * a4. Follow the same approach as described for a2. However, this time, 635e5c31af7Sopenharmony_ci * after the vertex and index data is uploaded, the test should de-commit 636e5c31af7Sopenharmony_ci * pages storing both IBO and VBO data. Both draw calls should be issued 637e5c31af7Sopenharmony_ci * then. 638e5c31af7Sopenharmony_ci * 639e5c31af7Sopenharmony_ci * The pass condition described in a2 is not changed. 640e5c31af7Sopenharmony_ci * 641e5c31af7Sopenharmony_ci * a5. Follow the same approach as described for a1. Apply the following 642e5c31af7Sopenharmony_ci * change: 643e5c31af7Sopenharmony_ci * 644e5c31af7Sopenharmony_ci * - Each rectangle should now be assigned a color, exposed to the VS 645e5c31af7Sopenharmony_ci * via a Vertex Attribute Array. The color data should come from committed 646e5c31af7Sopenharmony_ci * sparse buffer pages. 647e5c31af7Sopenharmony_ci * 648e5c31af7Sopenharmony_ci * a6. Follow the same approach as described for a5. Apply the following 649e5c31af7Sopenharmony_ci * change: 650e5c31af7Sopenharmony_ci * 651e5c31af7Sopenharmony_ci * - De-commit color data, after it has been uploaded. Try to execute the 652e5c31af7Sopenharmony_ci * draw call. 653e5c31af7Sopenharmony_ci * 654e5c31af7Sopenharmony_ci * The test passes if the GL implementation does not crash. Do not 655e5c31af7Sopenharmony_ci * validate the rendered data. 656e5c31af7Sopenharmony_ci */ 657e5c31af7Sopenharmony_ciclass QuadsBufferStorageTestCase : public BufferStorageTestCase 658e5c31af7Sopenharmony_ci{ 659e5c31af7Sopenharmony_cipublic: 660e5c31af7Sopenharmony_ci /* Type definitions */ 661e5c31af7Sopenharmony_ci enum _ibo_usage 662e5c31af7Sopenharmony_ci { 663e5c31af7Sopenharmony_ci /* Use glDrawArrays() for the draw call */ 664e5c31af7Sopenharmony_ci IBO_USAGE_NONE, 665e5c31af7Sopenharmony_ci /* Use glDrawElements() for the draw call */ 666e5c31af7Sopenharmony_ci IBO_USAGE_INDEXED_DRAW_CALL, 667e5c31af7Sopenharmony_ci /* Use glDrawRangeElements() for the draw call */ 668e5c31af7Sopenharmony_ci IBO_USAGE_INDEXED_RANGED_DRAW_CALL 669e5c31af7Sopenharmony_ci }; 670e5c31af7Sopenharmony_ci 671e5c31af7Sopenharmony_ci /* Public methods */ 672e5c31af7Sopenharmony_ci QuadsBufferStorageTestCase(const glw::Functions& gl, tcu::TestContext& testContext, glw::GLint page_size, 673e5c31af7Sopenharmony_ci _ibo_usage ibo_usage, bool use_color_data); 674e5c31af7Sopenharmony_ci 675e5c31af7Sopenharmony_ci /* BufferStorageTestCase implementation */ 676e5c31af7Sopenharmony_ci void deinitTestCaseGlobal(); 677e5c31af7Sopenharmony_ci void deinitTestCaseIteration(); 678e5c31af7Sopenharmony_ci bool execute(glw::GLuint sparse_bo_storage_flags); 679e5c31af7Sopenharmony_ci bool initTestCaseGlobal(); 680e5c31af7Sopenharmony_ci bool initTestCaseIteration(glw::GLuint sparse_bo); 681e5c31af7Sopenharmony_ci 682e5c31af7Sopenharmony_ci const char* getName() 683e5c31af7Sopenharmony_ci { 684e5c31af7Sopenharmony_ci return (!m_use_color_data && m_ibo_usage == IBO_USAGE_NONE) ? 685e5c31af7Sopenharmony_ci "cases a1-a2" : 686e5c31af7Sopenharmony_ci (!m_use_color_data && m_ibo_usage != IBO_USAGE_NONE) ? 687e5c31af7Sopenharmony_ci "cases a3-a4" : 688e5c31af7Sopenharmony_ci (m_use_color_data && m_ibo_usage != IBO_USAGE_NONE) ? "casea a5-a6" : "?!"; 689e5c31af7Sopenharmony_ci } 690e5c31af7Sopenharmony_ci 691e5c31af7Sopenharmony_ciprivate: 692e5c31af7Sopenharmony_ci /* Private methods */ 693e5c31af7Sopenharmony_ci void createTestData(unsigned char** out_data, unsigned int* out_vbo_data_offset, unsigned int* out_ibo_data_offset, 694e5c31af7Sopenharmony_ci unsigned int* out_color_data_offset) const; 695e5c31af7Sopenharmony_ci 696e5c31af7Sopenharmony_ci void initHelperBO(); 697e5c31af7Sopenharmony_ci 698e5c31af7Sopenharmony_ci void initSparseBO(bool decommit_data_pages_after_upload, bool is_dynamic_storage); 699e5c31af7Sopenharmony_ci 700e5c31af7Sopenharmony_ci /* Private fields */ 701e5c31af7Sopenharmony_ci glw::GLuint m_attribute_color_location; 702e5c31af7Sopenharmony_ci glw::GLuint m_attribute_position_location; 703e5c31af7Sopenharmony_ci glw::GLuint m_color_data_offset; 704e5c31af7Sopenharmony_ci unsigned char* m_data; 705e5c31af7Sopenharmony_ci glw::GLuint m_data_size; /* ibo, vbo, color data */ 706e5c31af7Sopenharmony_ci glw::GLuint m_data_size_rounded; /* rounded up to page size */ 707e5c31af7Sopenharmony_ci glw::GLuint m_fbo; 708e5c31af7Sopenharmony_ci const glw::Functions& m_gl; 709e5c31af7Sopenharmony_ci glw::GLuint m_helper_bo; 710e5c31af7Sopenharmony_ci glw::GLuint m_ibo_data_offset; 711e5c31af7Sopenharmony_ci _ibo_usage m_ibo_usage; 712e5c31af7Sopenharmony_ci const unsigned int m_n_quad_delta_x; 713e5c31af7Sopenharmony_ci const unsigned int m_n_quad_delta_y; 714e5c31af7Sopenharmony_ci const unsigned int m_n_quad_height; 715e5c31af7Sopenharmony_ci const unsigned int m_n_quad_width; 716e5c31af7Sopenharmony_ci const unsigned int m_n_quads_x; 717e5c31af7Sopenharmony_ci const unsigned int m_n_quads_y; 718e5c31af7Sopenharmony_ci unsigned int m_n_vertices_to_draw; 719e5c31af7Sopenharmony_ci bool m_pages_committed; 720e5c31af7Sopenharmony_ci glw::GLuint m_po; 721e5c31af7Sopenharmony_ci glw::GLuint m_sparse_bo; 722e5c31af7Sopenharmony_ci tcu::TestContext& m_testCtx; 723e5c31af7Sopenharmony_ci glw::GLuint m_to; 724e5c31af7Sopenharmony_ci const unsigned int m_to_height; 725e5c31af7Sopenharmony_ci const unsigned int m_to_width; 726e5c31af7Sopenharmony_ci bool m_use_color_data; 727e5c31af7Sopenharmony_ci glw::GLuint m_vao; 728e5c31af7Sopenharmony_ci glw::GLuint m_vbo_data_offset; 729e5c31af7Sopenharmony_ci}; 730e5c31af7Sopenharmony_ci 731e5c31af7Sopenharmony_ci/** Implements test case m for the test 2: 732e5c31af7Sopenharmony_ci * 733e5c31af7Sopenharmony_ci * m. Verify query functionality works correctly, when a sparse buffer is bound 734e5c31af7Sopenharmony_ci * to the query buffer binding point. Render a number of triangles while 735e5c31af7Sopenharmony_ci * a GL_PRIMITIVES_GENERATED query is enabled and the BO is bound to the 736e5c31af7Sopenharmony_ci * GL_QUERY_BUFFER binding point. Read back the value of the query from 737e5c31af7Sopenharmony_ci * the BO and verify it is correct using glGetQueryObjectiv(), 738e5c31af7Sopenharmony_ci * glGetQueryObjectuiv(), glGetQueryObjecti64v() and glGetQueryObjectui64v() 739e5c31af7Sopenharmony_ci * functions. 740e5c31af7Sopenharmony_ci * 741e5c31af7Sopenharmony_ci * Consider two scenarios: 742e5c31af7Sopenharmony_ci * 743e5c31af7Sopenharmony_ci * a) The page holding the result value is committed. 744e5c31af7Sopenharmony_ci * b) The page holding the result value is NOT committed. In this case, 745e5c31af7Sopenharmony_ci * the draw call glGetQueryObjectuiv() and all the getter functions should 746e5c31af7Sopenharmony_ci * not crash, but the reported values are irrelevant. 747e5c31af7Sopenharmony_ci */ 748e5c31af7Sopenharmony_ciclass QueryBufferStorageTestCase : public BufferStorageTestCase 749e5c31af7Sopenharmony_ci{ 750e5c31af7Sopenharmony_cipublic: 751e5c31af7Sopenharmony_ci /* Public methods */ 752e5c31af7Sopenharmony_ci QueryBufferStorageTestCase(const glw::Functions& gl, tcu::TestContext& testContext, glw::GLint page_size); 753e5c31af7Sopenharmony_ci 754e5c31af7Sopenharmony_ci /* BufferStorageTestCase implementation */ 755e5c31af7Sopenharmony_ci void deinitTestCaseGlobal(); 756e5c31af7Sopenharmony_ci void deinitTestCaseIteration(); 757e5c31af7Sopenharmony_ci bool execute(glw::GLuint sparse_bo_storage_flags); 758e5c31af7Sopenharmony_ci bool initTestCaseGlobal(); 759e5c31af7Sopenharmony_ci bool initTestCaseIteration(glw::GLuint sparse_bo); 760e5c31af7Sopenharmony_ci 761e5c31af7Sopenharmony_ci const char* getName() 762e5c31af7Sopenharmony_ci { 763e5c31af7Sopenharmony_ci return "case m"; 764e5c31af7Sopenharmony_ci } 765e5c31af7Sopenharmony_ci 766e5c31af7Sopenharmony_ciprivate: 767e5c31af7Sopenharmony_ci /* Private fields */ 768e5c31af7Sopenharmony_ci const glw::Functions& m_gl; 769e5c31af7Sopenharmony_ci glw::GLuint m_helper_bo; 770e5c31af7Sopenharmony_ci const unsigned int m_n_triangles; 771e5c31af7Sopenharmony_ci glw::GLint m_page_size; 772e5c31af7Sopenharmony_ci glw::GLuint m_po; 773e5c31af7Sopenharmony_ci glw::GLuint m_qo; 774e5c31af7Sopenharmony_ci glw::GLuint m_sparse_bo; 775e5c31af7Sopenharmony_ci unsigned int m_sparse_bo_size; 776e5c31af7Sopenharmony_ci unsigned int m_sparse_bo_size_rounded; 777e5c31af7Sopenharmony_ci tcu::TestContext& m_testCtx; 778e5c31af7Sopenharmony_ci glw::GLuint m_vao; 779e5c31af7Sopenharmony_ci}; 780e5c31af7Sopenharmony_ci 781e5c31af7Sopenharmony_ci/** Implements test case i for the test 2: 782e5c31af7Sopenharmony_ci * 783e5c31af7Sopenharmony_ci * i. Verify a SSBO, holding an unsized array, accessed from a compute shader, 784e5c31af7Sopenharmony_ci * contains anticipated values. Each CS invocation should only fetch 785e5c31af7Sopenharmony_ci * a single invocation-specific value. If the value is found correct, it 786e5c31af7Sopenharmony_ci * should increment it. 787e5c31af7Sopenharmony_ci * 788e5c31af7Sopenharmony_ci * The test passes if all values accessed by the CS invocations are found 789e5c31af7Sopenharmony_ci * valid after the dispatch call. 790e5c31af7Sopenharmony_ci * 791e5c31af7Sopenharmony_ci * Make sure to test three scenarios: 792e5c31af7Sopenharmony_ci * 793e5c31af7Sopenharmony_ci * a) All values come from the committed memory pages. 794e5c31af7Sopenharmony_ci * b) Use the same memory page commitment layout as proposed in b2. Verify 795e5c31af7Sopenharmony_ci * only those values, which were available to the compute shader. 796e5c31af7Sopenharmony_ci * c) None of the value exposed via SSBO are backed by physical memory. 797e5c31af7Sopenharmony_ci * In this case, we do not really care about the outputs of the CS. 798e5c31af7Sopenharmony_ci * We only need to ensure that GL (or the GPU) does not crash. 799e5c31af7Sopenharmony_ci */ 800e5c31af7Sopenharmony_ciclass SSBOStorageTestCase : public BufferStorageTestCase 801e5c31af7Sopenharmony_ci{ 802e5c31af7Sopenharmony_cipublic: 803e5c31af7Sopenharmony_ci /* Public methods */ 804e5c31af7Sopenharmony_ci SSBOStorageTestCase(const glw::Functions& gl, tcu::TestContext& testContext, glw::GLint page_size); 805e5c31af7Sopenharmony_ci 806e5c31af7Sopenharmony_ci /* BufferStorageTestCase implementation */ 807e5c31af7Sopenharmony_ci void deinitTestCaseGlobal(); 808e5c31af7Sopenharmony_ci void deinitTestCaseIteration(); 809e5c31af7Sopenharmony_ci bool execute(glw::GLuint sparse_bo_storage_flags); 810e5c31af7Sopenharmony_ci bool initTestCaseGlobal(); 811e5c31af7Sopenharmony_ci bool initTestCaseIteration(glw::GLuint sparse_bo); 812e5c31af7Sopenharmony_ci 813e5c31af7Sopenharmony_ci const char* getName() 814e5c31af7Sopenharmony_ci { 815e5c31af7Sopenharmony_ci return "case i"; 816e5c31af7Sopenharmony_ci } 817e5c31af7Sopenharmony_ci 818e5c31af7Sopenharmony_ciprivate: 819e5c31af7Sopenharmony_ci /* Private fields */ 820e5c31af7Sopenharmony_ci const glw::Functions& m_gl; 821e5c31af7Sopenharmony_ci glw::GLuint m_helper_bo; /* holds m_sparse_bo_size bytes */ 822e5c31af7Sopenharmony_ci glw::GLint m_page_size; 823e5c31af7Sopenharmony_ci glw::GLuint m_po; 824e5c31af7Sopenharmony_ci const unsigned int m_po_local_wg_size; 825e5c31af7Sopenharmony_ci glw::GLuint m_result_bo; 826e5c31af7Sopenharmony_ci glw::GLuint m_sparse_bo; 827e5c31af7Sopenharmony_ci unsigned int m_sparse_bo_size; 828e5c31af7Sopenharmony_ci unsigned int m_sparse_bo_size_rounded; 829e5c31af7Sopenharmony_ci unsigned int* m_ssbo_data; /* holds m_sparse_bo_size bytes */ 830e5c31af7Sopenharmony_ci tcu::TestContext& m_testCtx; 831e5c31af7Sopenharmony_ci}; 832e5c31af7Sopenharmony_ci 833e5c31af7Sopenharmony_ci/** Implements test cases b1-b2 for the test 2: 834e5c31af7Sopenharmony_ci * 835e5c31af7Sopenharmony_ci * b1. Use a sparse buffer as a target for separate & interleaved transform 836e5c31af7Sopenharmony_ci * feed-back (in separate iterations). A sufficient number of pages should 837e5c31af7Sopenharmony_ci * have been committed prior to issuing any draw call. 838e5c31af7Sopenharmony_ci * 839e5c31af7Sopenharmony_ci * The vertex shader should output vertex ID & instance ID data to two 840e5c31af7Sopenharmony_ci * different output variables captured by the TF. 841e5c31af7Sopenharmony_ci * 842e5c31af7Sopenharmony_ci * The test should only pass if the generated output is correct. 843e5c31af7Sopenharmony_ci * 844e5c31af7Sopenharmony_ci * For the purpose of this test, use the following draw call types: 845e5c31af7Sopenharmony_ci * 846e5c31af7Sopenharmony_ci * * regular 847e5c31af7Sopenharmony_ci * * regular indirect 848e5c31af7Sopenharmony_ci * * regular indirect multi 849e5c31af7Sopenharmony_ci * * regular instanced 850e5c31af7Sopenharmony_ci * * regular instanced + base instance 851e5c31af7Sopenharmony_ci * * regular multi 852e5c31af7Sopenharmony_ci * * indexed 853e5c31af7Sopenharmony_ci * * indexed indirect 854e5c31af7Sopenharmony_ci * * indexed indirect multi 855e5c31af7Sopenharmony_ci * * indexed multi 856e5c31af7Sopenharmony_ci * * indexed multi + base vertex 857e5c31af7Sopenharmony_ci * * indexed + base vertex 858e5c31af7Sopenharmony_ci * * indexed + base vertex + base instance 859e5c31af7Sopenharmony_ci * * instanced indexed 860e5c31af7Sopenharmony_ci * * instanced indexed + base vertex 861e5c31af7Sopenharmony_ci * * instanced indexed + base vertex + base instance 862e5c31af7Sopenharmony_ci * 863e5c31af7Sopenharmony_ci * 864e5c31af7Sopenharmony_ci * b2. Follow the same approach as described for b1. However, the commitment 865e5c31af7Sopenharmony_ci * state of memory pages used for the TF process should be laid out in 866e5c31af7Sopenharmony_ci * the following order: 867e5c31af7Sopenharmony_ci * 868e5c31af7Sopenharmony_ci * 1st page: committed 869e5c31af7Sopenharmony_ci * 2nd page: NOT committed 870e5c31af7Sopenharmony_ci * ... 871e5c31af7Sopenharmony_ci * (2N) -th page: committed 872e5c31af7Sopenharmony_ci * (2N+1)-th page: NOT committed 873e5c31af7Sopenharmony_ci * 874e5c31af7Sopenharmony_ci * Make sure to use at least 4 memory pages in this test case. 875e5c31af7Sopenharmony_ci * 876e5c31af7Sopenharmony_ci * Execute the test as described in b1, and make sure the results stored 877e5c31af7Sopenharmony_ci * in the committed pages used by the TF process holds valid result data. 878e5c31af7Sopenharmony_ci */ 879e5c31af7Sopenharmony_ciclass TransformFeedbackBufferStorageTestCase : public BufferStorageTestCase 880e5c31af7Sopenharmony_ci{ 881e5c31af7Sopenharmony_cipublic: 882e5c31af7Sopenharmony_ci /* Type definitions */ 883e5c31af7Sopenharmony_ci enum _draw_call 884e5c31af7Sopenharmony_ci { 885e5c31af7Sopenharmony_ci /* glDrawElements() */ 886e5c31af7Sopenharmony_ci DRAW_CALL_INDEXED, 887e5c31af7Sopenharmony_ci /* glDrawElementsBaseVertex() */ 888e5c31af7Sopenharmony_ci DRAW_CALL_INDEXED_BASE_VERTEX, 889e5c31af7Sopenharmony_ci /* glDrawElementsIndirect() */ 890e5c31af7Sopenharmony_ci DRAW_CALL_INDEXED_INDIRECT, 891e5c31af7Sopenharmony_ci /* glMultiDrawElementIndirect() */ 892e5c31af7Sopenharmony_ci DRAW_CALL_INDEXED_INDIRECT_MULTI, 893e5c31af7Sopenharmony_ci /* glMultiDrawElements() */ 894e5c31af7Sopenharmony_ci DRAW_CALL_INDEXED_MULTI, 895e5c31af7Sopenharmony_ci /* glMultiDrawElementsBaseVertex() */ 896e5c31af7Sopenharmony_ci DRAW_CALL_INDEXED_MULTI_BASE_VERTEX, 897e5c31af7Sopenharmony_ci /* glDrawElementsInstanced() */ 898e5c31af7Sopenharmony_ci DRAW_CALL_INSTANCED_INDEXED, 899e5c31af7Sopenharmony_ci /* glDrawElementsInstancedBaseVertex() */ 900e5c31af7Sopenharmony_ci DRAW_CALL_INSTANCED_INDEXED_BASE_VERTEX, 901e5c31af7Sopenharmony_ci /* glDrawElementsInstancedBaseVertexBaseInstance() */ 902e5c31af7Sopenharmony_ci DRAW_CALL_INSTANCED_INDEXED_BASE_VERTEX_BASE_INSTANCE, 903e5c31af7Sopenharmony_ci /* glDrawArrays() */ 904e5c31af7Sopenharmony_ci DRAW_CALL_REGULAR, 905e5c31af7Sopenharmony_ci /* glDrawArraysIndirect() */ 906e5c31af7Sopenharmony_ci DRAW_CALL_REGULAR_INDIRECT, 907e5c31af7Sopenharmony_ci /* glMultiDrawArraysIndirect() */ 908e5c31af7Sopenharmony_ci DRAW_CALL_REGULAR_INDIRECT_MULTI, 909e5c31af7Sopenharmony_ci /* glDrawArraysInstanced() */ 910e5c31af7Sopenharmony_ci DRAW_CALL_REGULAR_INSTANCED, 911e5c31af7Sopenharmony_ci /* glDrawArraysInstancedBaseInstance() */ 912e5c31af7Sopenharmony_ci DRAW_CALL_REGULAR_INSTANCED_BASE_INSTANCE, 913e5c31af7Sopenharmony_ci /* glMultiDrawArrays() */ 914e5c31af7Sopenharmony_ci DRAW_CALL_REGULAR_MULTI, 915e5c31af7Sopenharmony_ci 916e5c31af7Sopenharmony_ci /* Always last */ 917e5c31af7Sopenharmony_ci DRAW_CALL_COUNT 918e5c31af7Sopenharmony_ci }; 919e5c31af7Sopenharmony_ci 920e5c31af7Sopenharmony_ci /* Public methods */ 921e5c31af7Sopenharmony_ci TransformFeedbackBufferStorageTestCase(const glw::Functions& gl, tcu::TestContext& testContext, 922e5c31af7Sopenharmony_ci glw::GLint page_size, bool all_pages_committed); 923e5c31af7Sopenharmony_ci 924e5c31af7Sopenharmony_ci /* BufferStorageTestCase implementation */ 925e5c31af7Sopenharmony_ci void deinitTestCaseGlobal(); 926e5c31af7Sopenharmony_ci bool execute(glw::GLuint sparse_bo_storage_flags); 927e5c31af7Sopenharmony_ci bool initTestCaseGlobal(); 928e5c31af7Sopenharmony_ci bool initTestCaseIteration(glw::GLuint sparse_bo); 929e5c31af7Sopenharmony_ci 930e5c31af7Sopenharmony_ci const char* getName() 931e5c31af7Sopenharmony_ci { 932e5c31af7Sopenharmony_ci return (m_all_pages_committed) ? "case b1" : "case b2"; 933e5c31af7Sopenharmony_ci } 934e5c31af7Sopenharmony_ci 935e5c31af7Sopenharmony_ciprivate: 936e5c31af7Sopenharmony_ci /* Private methods */ 937e5c31af7Sopenharmony_ci const char* getDrawCallTypeString(_draw_call draw_call); 938e5c31af7Sopenharmony_ci void initDataBO(); 939e5c31af7Sopenharmony_ci void initTestData(); 940e5c31af7Sopenharmony_ci 941e5c31af7Sopenharmony_ci /* Private fields */ 942e5c31af7Sopenharmony_ci bool m_all_pages_committed; 943e5c31af7Sopenharmony_ci glw::GLuint m_data_bo; 944e5c31af7Sopenharmony_ci unsigned int m_data_bo_index_data_offset; 945e5c31af7Sopenharmony_ci unsigned int m_data_bo_indexed_indirect_arg_offset; 946e5c31af7Sopenharmony_ci unsigned int m_data_bo_indexed_mdi_arg_offset; 947e5c31af7Sopenharmony_ci unsigned int m_data_bo_regular_indirect_arg_offset; 948e5c31af7Sopenharmony_ci unsigned int m_data_bo_regular_mdi_arg_offset; 949e5c31af7Sopenharmony_ci glw::GLuint m_data_bo_size; 950e5c31af7Sopenharmony_ci const unsigned int m_draw_call_baseInstance; 951e5c31af7Sopenharmony_ci const unsigned int m_draw_call_baseVertex; 952e5c31af7Sopenharmony_ci const unsigned int m_draw_call_first; 953e5c31af7Sopenharmony_ci const unsigned int m_draw_call_firstIndex; 954e5c31af7Sopenharmony_ci const glw::Functions& m_gl; 955e5c31af7Sopenharmony_ci glw::GLuint m_helper_bo; /* of m_result_bo_size size */ 956e5c31af7Sopenharmony_ci glw::GLuint* m_index_data; 957e5c31af7Sopenharmony_ci glw::GLuint m_index_data_size; 958e5c31af7Sopenharmony_ci glw::GLuint* m_indirect_arg_data; 959e5c31af7Sopenharmony_ci glw::GLuint m_indirect_arg_data_size; 960e5c31af7Sopenharmony_ci const unsigned int m_min_memory_page_span; 961e5c31af7Sopenharmony_ci glw::GLint m_multidrawcall_basevertex[2]; 962e5c31af7Sopenharmony_ci glw::GLsizei m_multidrawcall_count[2]; 963e5c31af7Sopenharmony_ci unsigned int m_multidrawcall_drawcount; 964e5c31af7Sopenharmony_ci glw::GLint m_multidrawcall_first[2]; 965e5c31af7Sopenharmony_ci glw::GLvoid* m_multidrawcall_index[2]; 966e5c31af7Sopenharmony_ci unsigned int m_multidrawcall_primcount; 967e5c31af7Sopenharmony_ci const unsigned int m_n_instances_to_test; 968e5c31af7Sopenharmony_ci unsigned int m_n_vertices_per_instance; 969e5c31af7Sopenharmony_ci glw::GLint m_page_size; 970e5c31af7Sopenharmony_ci glw::GLuint m_po_ia; /* interleave attribs TF */ 971e5c31af7Sopenharmony_ci glw::GLuint m_po_sa; /* separate attribs TF */ 972e5c31af7Sopenharmony_ci glw::GLuint m_result_bo; 973e5c31af7Sopenharmony_ci glw::GLuint m_result_bo_size; 974e5c31af7Sopenharmony_ci glw::GLuint m_result_bo_size_rounded; 975e5c31af7Sopenharmony_ci tcu::TestContext& m_testCtx; 976e5c31af7Sopenharmony_ci glw::GLuint m_vao; 977e5c31af7Sopenharmony_ci}; 978e5c31af7Sopenharmony_ci 979e5c31af7Sopenharmony_ci/** Implements test case j for the test 2: 980e5c31af7Sopenharmony_ci * 981e5c31af7Sopenharmony_ci * j. Verify an UBO, backed by a sparse buffer, accessed from a vertex shader, 982e5c31af7Sopenharmony_ci * holds values as expected. Each VS invocation should only check 983e5c31af7Sopenharmony_ci * an invocation-specific arrayed member item and set gl_Position to 984e5c31af7Sopenharmony_ci * vec4(1.0), if the retrieved value is valid. 985e5c31af7Sopenharmony_ci * 986e5c31af7Sopenharmony_ci * Make sure to test three scenarios as described for case i). 987e5c31af7Sopenharmony_ci */ 988e5c31af7Sopenharmony_ciclass UniformBufferStorageTestCase : public BufferStorageTestCase 989e5c31af7Sopenharmony_ci{ 990e5c31af7Sopenharmony_cipublic: 991e5c31af7Sopenharmony_ci /* Public methods */ 992e5c31af7Sopenharmony_ci UniformBufferStorageTestCase(const glw::Functions& gl, tcu::TestContext& testContext, glw::GLint page_size); 993e5c31af7Sopenharmony_ci 994e5c31af7Sopenharmony_ci /* BufferStorageTestCase implementation */ 995e5c31af7Sopenharmony_ci void deinitTestCaseGlobal(); 996e5c31af7Sopenharmony_ci void deinitTestCaseIteration(); 997e5c31af7Sopenharmony_ci bool execute(glw::GLuint sparse_bo_storage_flags); 998e5c31af7Sopenharmony_ci bool initTestCaseGlobal(); 999e5c31af7Sopenharmony_ci bool initTestCaseIteration(glw::GLuint sparse_bo); 1000e5c31af7Sopenharmony_ci 1001e5c31af7Sopenharmony_ci const char* getName() 1002e5c31af7Sopenharmony_ci { 1003e5c31af7Sopenharmony_ci return "case j"; 1004e5c31af7Sopenharmony_ci } 1005e5c31af7Sopenharmony_ci 1006e5c31af7Sopenharmony_ciprivate: 1007e5c31af7Sopenharmony_ci /* Private fields */ 1008e5c31af7Sopenharmony_ci const glw::Functions& m_gl; 1009e5c31af7Sopenharmony_ci glw::GLint m_gl_uniform_buffer_offset_alignment_value; 1010e5c31af7Sopenharmony_ci glw::GLuint m_helper_bo; 1011e5c31af7Sopenharmony_ci const unsigned int m_n_pages_to_use; 1012e5c31af7Sopenharmony_ci unsigned int m_n_ubo_uints; 1013e5c31af7Sopenharmony_ci glw::GLint m_page_size; 1014e5c31af7Sopenharmony_ci glw::GLuint m_po; 1015e5c31af7Sopenharmony_ci glw::GLuint m_sparse_bo; 1016e5c31af7Sopenharmony_ci unsigned int m_sparse_bo_data_size; 1017e5c31af7Sopenharmony_ci unsigned int m_sparse_bo_data_start_offset; 1018e5c31af7Sopenharmony_ci unsigned int m_sparse_bo_size; 1019e5c31af7Sopenharmony_ci unsigned int m_sparse_bo_size_rounded; 1020e5c31af7Sopenharmony_ci tcu::TestContext& m_testCtx; 1021e5c31af7Sopenharmony_ci glw::GLuint m_tf_bo; 1022e5c31af7Sopenharmony_ci unsigned char* m_ubo_data; 1023e5c31af7Sopenharmony_ci glw::GLuint m_vao; 1024e5c31af7Sopenharmony_ci}; 1025e5c31af7Sopenharmony_ci 1026e5c31af7Sopenharmony_ci/** Implements conformance test 2 from the test specification: 1027e5c31af7Sopenharmony_ci * 1028e5c31af7Sopenharmony_ci * 2. Make sure glBufferStorage() accepts the new GL_SPARSE_STORAGE_BIT_ARB flag 1029e5c31af7Sopenharmony_ci * in all valid flag combinations. For each such combination, allocate 1030e5c31af7Sopenharmony_ci * a sparse buffer of 1GB size and verify the following test cases work as 1031e5c31af7Sopenharmony_ci * expected. After all tests have been run for a particular flag combination, 1032e5c31af7Sopenharmony_ci * the sparse buffer should be deleted, and a new sparse buffer should be 1033e5c31af7Sopenharmony_ci * created, if there are any outstanding flag combinations. 1034e5c31af7Sopenharmony_ci * 1035e5c31af7Sopenharmony_ci * Test cases, whose verification behavior is incompatible with 1036e5c31af7Sopenharmony_ci * the requested flag combination should skip the validation part: 1037e5c31af7Sopenharmony_ci * 1038e5c31af7Sopenharmony_ci * (for test case descriptions, please check test case class prototypes) 1039e5c31af7Sopenharmony_ci */ 1040e5c31af7Sopenharmony_ciclass BufferStorageTest : public deqp::TestCase 1041e5c31af7Sopenharmony_ci{ 1042e5c31af7Sopenharmony_cipublic: 1043e5c31af7Sopenharmony_ci /* Public methods */ 1044e5c31af7Sopenharmony_ci BufferStorageTest(deqp::Context& context); 1045e5c31af7Sopenharmony_ci 1046e5c31af7Sopenharmony_ci void deinit(); 1047e5c31af7Sopenharmony_ci void init(); 1048e5c31af7Sopenharmony_ci tcu::TestNode::IterateResult iterate(); 1049e5c31af7Sopenharmony_ci 1050e5c31af7Sopenharmony_ciprivate: 1051e5c31af7Sopenharmony_ci /* Private type definitions */ 1052e5c31af7Sopenharmony_ci typedef std::vector<BufferStorageTestCase*> TestCasesVector; 1053e5c31af7Sopenharmony_ci typedef TestCasesVector::const_iterator TestCasesVectorConstIterator; 1054e5c31af7Sopenharmony_ci typedef TestCasesVector::iterator TestCasesVectorIterator; 1055e5c31af7Sopenharmony_ci 1056e5c31af7Sopenharmony_ci /* Private methods */ 1057e5c31af7Sopenharmony_ci void initTestCases(); 1058e5c31af7Sopenharmony_ci 1059e5c31af7Sopenharmony_ci /* Private members */ 1060e5c31af7Sopenharmony_ci glw::GLuint m_sparse_bo; 1061e5c31af7Sopenharmony_ci TestCasesVector m_testCases; 1062e5c31af7Sopenharmony_ci}; 1063e5c31af7Sopenharmony_ci 1064e5c31af7Sopenharmony_ci/** Test group which encapsulates all sparse buffer conformance tests */ 1065e5c31af7Sopenharmony_ciclass SparseBufferTests : public deqp::TestCaseGroup 1066e5c31af7Sopenharmony_ci{ 1067e5c31af7Sopenharmony_cipublic: 1068e5c31af7Sopenharmony_ci /* Public methods */ 1069e5c31af7Sopenharmony_ci SparseBufferTests(deqp::Context& context); 1070e5c31af7Sopenharmony_ci 1071e5c31af7Sopenharmony_ci void init(); 1072e5c31af7Sopenharmony_ci 1073e5c31af7Sopenharmony_ciprivate: 1074e5c31af7Sopenharmony_ci SparseBufferTests(const SparseBufferTests& other); 1075e5c31af7Sopenharmony_ci SparseBufferTests& operator=(const SparseBufferTests& other); 1076e5c31af7Sopenharmony_ci}; 1077e5c31af7Sopenharmony_ci 1078e5c31af7Sopenharmony_ci} /* glcts namespace */ 1079e5c31af7Sopenharmony_ci 1080e5c31af7Sopenharmony_ci#endif // _GL4CSPARSEBUFFERTESTS_HPP 1081