1e5c31af7Sopenharmony_ci#ifndef _GL4CCOPYIMAGETESTS_HPP 2e5c31af7Sopenharmony_ci#define _GL4CCOPYIMAGETESTS_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 gl4cCopyImageTests.hpp 23e5c31af7Sopenharmony_ci * \brief CopyImageSubData functional tests. 24e5c31af7Sopenharmony_ci */ /*-------------------------------------------------------------------*/ 25e5c31af7Sopenharmony_ci 26e5c31af7Sopenharmony_ci#include "glcTestCase.hpp" 27e5c31af7Sopenharmony_ci#include "glwDefs.hpp" 28e5c31af7Sopenharmony_ci 29e5c31af7Sopenharmony_cinamespace gl4cts 30e5c31af7Sopenharmony_ci{ 31e5c31af7Sopenharmony_cinamespace CopyImage 32e5c31af7Sopenharmony_ci{ 33e5c31af7Sopenharmony_ci/** Implements functional test. Description follows: 34e5c31af7Sopenharmony_ci * 35e5c31af7Sopenharmony_ci * This test verifies that CopyImageSubData function works as expected. 36e5c31af7Sopenharmony_ci * 37e5c31af7Sopenharmony_ci * Steps: 38e5c31af7Sopenharmony_ci * - create source and destination image objects; 39e5c31af7Sopenharmony_ci * - fill both image objects with different content, also each pixel should 40e5c31af7Sopenharmony_ci * be unique; 41e5c31af7Sopenharmony_ci * - execute CopyImageSubData on both image objects, to copy region from 42e5c31af7Sopenharmony_ci * source image to a region in destination image; 43e5c31af7Sopenharmony_ci * - inspect content of both image objects; 44e5c31af7Sopenharmony_ci * 45e5c31af7Sopenharmony_ci * Test pass if: 46e5c31af7Sopenharmony_ci * - no part of destination image, that is outside of destination region, 47e5c31af7Sopenharmony_ci * was modified, 48e5c31af7Sopenharmony_ci * - destination region contains data from source region, 49e5c31af7Sopenharmony_ci * - source image contents were not modified. 50e5c31af7Sopenharmony_ci * 51e5c31af7Sopenharmony_ci * Use TexImage* routines to create textures. It is required that textures are 52e5c31af7Sopenharmony_ci * complete, therefore TEXTURE_BASE_LEVEL and TEXTURE_MAX_LEVEL have to be 53e5c31af7Sopenharmony_ci * updated with TexParameter manually. 54e5c31af7Sopenharmony_ci * 55e5c31af7Sopenharmony_ci * Use draw operation to update contents of Renderbuffers. 56e5c31af7Sopenharmony_ci * 57e5c31af7Sopenharmony_ci * Tested image dimensions should be NxM where N and M are <7:15>. 58e5c31af7Sopenharmony_ci * 59e5c31af7Sopenharmony_ci * Multi-layered targets should have twelve slices. 60e5c31af7Sopenharmony_ci * 61e5c31af7Sopenharmony_ci * Test with the following mipmap levels: 62e5c31af7Sopenharmony_ci * - 0, 63e5c31af7Sopenharmony_ci * - 1, 64e5c31af7Sopenharmony_ci * - 2. 65e5c31af7Sopenharmony_ci * 66e5c31af7Sopenharmony_ci * Test with the following region locations: 67e5c31af7Sopenharmony_ci * - all four corners, 68e5c31af7Sopenharmony_ci * - all four edge centres, 69e5c31af7Sopenharmony_ci * - image centre, 70e5c31af7Sopenharmony_ci * - whole image. 71e5c31af7Sopenharmony_ci * 72e5c31af7Sopenharmony_ci * Tested region dimensions should be NxN where N is <1:7>. Depth should be 73e5c31af7Sopenharmony_ci * selected so as to affect all image slices. In cases when one image has 74e5c31af7Sopenharmony_ci * single layer and second is multi-layered, than copy operation and inspection 75e5c31af7Sopenharmony_ci * must be repeated for each layer. 76e5c31af7Sopenharmony_ci * 77e5c31af7Sopenharmony_ci * This test should iterate over: 78e5c31af7Sopenharmony_ci * - all valid internal format combinations, 79e5c31af7Sopenharmony_ci * - all valid object target combinations, 80e5c31af7Sopenharmony_ci * - all mipmap level combinations, 81e5c31af7Sopenharmony_ci * - all image dimensions combinations, 82e5c31af7Sopenharmony_ci * - all valid copied regions combinations, 83e5c31af7Sopenharmony_ci * - all valid copied region dimensions combinations. 84e5c31af7Sopenharmony_ci * 85e5c31af7Sopenharmony_ci * Moreover this test should also execute CopyImageSubData to copy image to 86e5c31af7Sopenharmony_ci * itself. In this case it expected that source image will be modified. 87e5c31af7Sopenharmony_ci * 88e5c31af7Sopenharmony_ci * 89e5c31af7Sopenharmony_ci * Implementation notes 90e5c31af7Sopenharmony_ci * There are some configuration preprocessor flags available in cpp file. 91e5c31af7Sopenharmony_ci **/ 92e5c31af7Sopenharmony_ciclass FunctionalTest : public deqp::TestCase 93e5c31af7Sopenharmony_ci{ 94e5c31af7Sopenharmony_cipublic: 95e5c31af7Sopenharmony_ci FunctionalTest(deqp::Context& context); 96e5c31af7Sopenharmony_ci virtual ~FunctionalTest() 97e5c31af7Sopenharmony_ci { 98e5c31af7Sopenharmony_ci } 99e5c31af7Sopenharmony_ci 100e5c31af7Sopenharmony_ci /* Implementation of tcu::TestNode methods */ 101e5c31af7Sopenharmony_ci virtual IterateResult iterate(void); 102e5c31af7Sopenharmony_ci 103e5c31af7Sopenharmony_ciprivate: 104e5c31af7Sopenharmony_ci /* Private types */ 105e5c31af7Sopenharmony_ci struct targetDesc 106e5c31af7Sopenharmony_ci { 107e5c31af7Sopenharmony_ci glw::GLenum m_target; 108e5c31af7Sopenharmony_ci glw::GLuint m_width; 109e5c31af7Sopenharmony_ci glw::GLuint m_height; 110e5c31af7Sopenharmony_ci glw::GLuint m_level; 111e5c31af7Sopenharmony_ci glw::GLenum m_internal_format; 112e5c31af7Sopenharmony_ci glw::GLenum m_format; 113e5c31af7Sopenharmony_ci glw::GLenum m_type; 114e5c31af7Sopenharmony_ci }; 115e5c31af7Sopenharmony_ci 116e5c31af7Sopenharmony_ci struct testCase 117e5c31af7Sopenharmony_ci { 118e5c31af7Sopenharmony_ci targetDesc m_dst; 119e5c31af7Sopenharmony_ci glw::GLuint m_dst_x; 120e5c31af7Sopenharmony_ci glw::GLuint m_dst_y; 121e5c31af7Sopenharmony_ci targetDesc m_src; 122e5c31af7Sopenharmony_ci glw::GLuint m_src_x; 123e5c31af7Sopenharmony_ci glw::GLuint m_src_y; 124e5c31af7Sopenharmony_ci glw::GLuint m_width; 125e5c31af7Sopenharmony_ci glw::GLuint m_height; 126e5c31af7Sopenharmony_ci }; 127e5c31af7Sopenharmony_ci 128e5c31af7Sopenharmony_ci /* Private methods */ 129e5c31af7Sopenharmony_ci void calculateDimmensions(glw::GLenum target, glw::GLuint level, glw::GLuint width, glw::GLuint height, 130e5c31af7Sopenharmony_ci glw::GLuint* out_widths, glw::GLuint* out_heights, glw::GLuint* out_depths) const; 131e5c31af7Sopenharmony_ci 132e5c31af7Sopenharmony_ci void clean(); 133e5c31af7Sopenharmony_ci void cleanPixels(glw::GLubyte** pixels) const; 134e5c31af7Sopenharmony_ci 135e5c31af7Sopenharmony_ci bool compareImages(const targetDesc& left_desc, const glw::GLubyte* left_data, glw::GLuint left_x, 136e5c31af7Sopenharmony_ci glw::GLuint left_y, glw::GLuint left_layer, glw::GLuint left_level, const targetDesc& right_desc, 137e5c31af7Sopenharmony_ci const glw::GLubyte* right_data, glw::GLuint right_x, glw::GLuint right_y, 138e5c31af7Sopenharmony_ci glw::GLuint right_layer, glw::GLuint right_level, glw::GLuint region_width, 139e5c31af7Sopenharmony_ci glw::GLuint region_height) const; 140e5c31af7Sopenharmony_ci 141e5c31af7Sopenharmony_ci bool copyAndVerify(const testCase& test_case, const glw::GLubyte** dst_pixels, const glw::GLubyte** src_pixels); 142e5c31af7Sopenharmony_ci 143e5c31af7Sopenharmony_ci void getCleanRegions(const testCase& test_case, glw::GLuint dst_level, glw::GLuint out_corners[4][4], 144e5c31af7Sopenharmony_ci glw::GLuint& out_n_corners) const; 145e5c31af7Sopenharmony_ci 146e5c31af7Sopenharmony_ci void getPixels(glw::GLuint name, const targetDesc& desc, glw::GLuint level, glw::GLubyte* out_pixels) const; 147e5c31af7Sopenharmony_ci 148e5c31af7Sopenharmony_ci void prepareDstPxls(const targetDesc& desc, glw::GLubyte** out_pixels) const; 149e5c31af7Sopenharmony_ci 150e5c31af7Sopenharmony_ci void prepareSrcPxls(const targetDesc& desc, glw::GLenum dst_internal_format, glw::GLubyte** out_pixels) const; 151e5c31af7Sopenharmony_ci 152e5c31af7Sopenharmony_ci void prepareTestCases(glw::GLenum dst_internal_format, glw::GLenum dst_target, glw::GLenum src_internal_format, 153e5c31af7Sopenharmony_ci glw::GLenum src_target); 154e5c31af7Sopenharmony_ci 155e5c31af7Sopenharmony_ci glw::GLuint prepareTexture(const targetDesc& desc, const glw::GLubyte** pixels, glw::GLuint& out_buf_id); 156e5c31af7Sopenharmony_ci 157e5c31af7Sopenharmony_ci bool verify(const testCase& test_case, glw::GLuint dst_layer, const glw::GLubyte** dst_pixels, 158e5c31af7Sopenharmony_ci glw::GLuint src_layer, const glw::GLubyte** src_pixels, glw::GLuint depth); 159e5c31af7Sopenharmony_ci 160e5c31af7Sopenharmony_ci /* Private fields */ 161e5c31af7Sopenharmony_ci glw::GLuint m_dst_buf_name; 162e5c31af7Sopenharmony_ci glw::GLuint m_dst_tex_name; 163e5c31af7Sopenharmony_ci glw::GLuint m_rb_name; 164e5c31af7Sopenharmony_ci glw::GLuint m_src_buf_name; 165e5c31af7Sopenharmony_ci glw::GLuint m_src_tex_name; 166e5c31af7Sopenharmony_ci glw::GLuint m_test_case_index; 167e5c31af7Sopenharmony_ci std::vector<testCase> m_test_cases; 168e5c31af7Sopenharmony_ci}; 169e5c31af7Sopenharmony_ci 170e5c31af7Sopenharmony_ci/** Implements functional test. Description follows: 171e5c31af7Sopenharmony_ci * 172e5c31af7Sopenharmony_ci * Smoke test: 173e5c31af7Sopenharmony_ci * Tests if function CopyImageSubData accepts and works correctly with: 174e5c31af7Sopenharmony_ci * - all internal formats, 175e5c31af7Sopenharmony_ci * - all valid targets. 176e5c31af7Sopenharmony_ci * Point of the test is to check each internal format and target separately. 177e5c31af7Sopenharmony_ci * 178e5c31af7Sopenharmony_ci * Steps: 179e5c31af7Sopenharmony_ci * - create source and destination image objects using same format and 180e5c31af7Sopenharmony_ci * target for both; 181e5c31af7Sopenharmony_ci * - fill 0 level mipmap of both image objects with different content, also 182e5c31af7Sopenharmony_ci * each pixel should be unique; 183e5c31af7Sopenharmony_ci * - make both image objects complete; 184e5c31af7Sopenharmony_ci * - execute CopyImageSubData on both image objects, to copy contents from 185e5c31af7Sopenharmony_ci * source image to a destination image; 186e5c31af7Sopenharmony_ci * - inspect content of both image objects; 187e5c31af7Sopenharmony_ci * 188e5c31af7Sopenharmony_ci * Test pass if: 189e5c31af7Sopenharmony_ci * - destination image contains data from source image, 190e5c31af7Sopenharmony_ci * - source image contents were not modified. 191e5c31af7Sopenharmony_ci * 192e5c31af7Sopenharmony_ci * Repeat steps for all internal formats, using TEXTURE_2D target. 193e5c31af7Sopenharmony_ci * 194e5c31af7Sopenharmony_ci * Repeat steps for all valid targets, using RGBA32UI internal format. 195e5c31af7Sopenharmony_ci **/ 196e5c31af7Sopenharmony_ciclass SmokeTest : public deqp::TestCase 197e5c31af7Sopenharmony_ci{ 198e5c31af7Sopenharmony_cipublic: 199e5c31af7Sopenharmony_ci SmokeTest(deqp::Context& context); 200e5c31af7Sopenharmony_ci virtual ~SmokeTest() 201e5c31af7Sopenharmony_ci { 202e5c31af7Sopenharmony_ci } 203e5c31af7Sopenharmony_ci 204e5c31af7Sopenharmony_ci /* Implementation of tcu::TestNode methods */ 205e5c31af7Sopenharmony_ci virtual IterateResult iterate(void); 206e5c31af7Sopenharmony_ci 207e5c31af7Sopenharmony_ciprivate: 208e5c31af7Sopenharmony_ci /* Private types */ 209e5c31af7Sopenharmony_ci struct testCase 210e5c31af7Sopenharmony_ci { 211e5c31af7Sopenharmony_ci glw::GLenum m_target; 212e5c31af7Sopenharmony_ci glw::GLenum m_internal_format; 213e5c31af7Sopenharmony_ci glw::GLenum m_format; 214e5c31af7Sopenharmony_ci glw::GLenum m_type; 215e5c31af7Sopenharmony_ci }; 216e5c31af7Sopenharmony_ci 217e5c31af7Sopenharmony_ci /* Private methods */ 218e5c31af7Sopenharmony_ci void clean(); 219e5c31af7Sopenharmony_ci void cleanPixels(glw::GLubyte*& pixels) const; 220e5c31af7Sopenharmony_ci 221e5c31af7Sopenharmony_ci bool compareImages(const testCase& test_case, const glw::GLubyte* left_data, const glw::GLubyte* right_data) const; 222e5c31af7Sopenharmony_ci 223e5c31af7Sopenharmony_ci bool copyAndVerify(const testCase& test_case, const glw::GLubyte* src_pixels); 224e5c31af7Sopenharmony_ci 225e5c31af7Sopenharmony_ci void getPixels(glw::GLuint name, const testCase& test_case, glw::GLubyte* out_pixels) const; 226e5c31af7Sopenharmony_ci 227e5c31af7Sopenharmony_ci void prepareDstPxls(const testCase& test_case, glw::GLubyte*& out_pixels) const; 228e5c31af7Sopenharmony_ci 229e5c31af7Sopenharmony_ci void prepareSrcPxls(const testCase& test_case, glw::GLubyte*& out_pixels) const; 230e5c31af7Sopenharmony_ci 231e5c31af7Sopenharmony_ci glw::GLuint prepareTexture(const testCase& test_case, const glw::GLubyte* pixels, glw::GLuint& out_buf_id); 232e5c31af7Sopenharmony_ci 233e5c31af7Sopenharmony_ci bool verify(const testCase& test_case, const glw::GLubyte* src_pixels); 234e5c31af7Sopenharmony_ci 235e5c31af7Sopenharmony_ci /* Private fields */ 236e5c31af7Sopenharmony_ci glw::GLuint m_dst_buf_name; 237e5c31af7Sopenharmony_ci glw::GLuint m_dst_tex_name; 238e5c31af7Sopenharmony_ci glw::GLuint m_rb_name; 239e5c31af7Sopenharmony_ci glw::GLuint m_src_buf_name; 240e5c31af7Sopenharmony_ci glw::GLuint m_src_tex_name; 241e5c31af7Sopenharmony_ci glw::GLuint m_test_case_index; 242e5c31af7Sopenharmony_ci std::vector<testCase> m_test_cases; 243e5c31af7Sopenharmony_ci 244e5c31af7Sopenharmony_ci /* Constants */ 245e5c31af7Sopenharmony_ci static const glw::GLuint m_width; 246e5c31af7Sopenharmony_ci static const glw::GLuint m_height; 247e5c31af7Sopenharmony_ci static const glw::GLuint m_depth; 248e5c31af7Sopenharmony_ci}; 249e5c31af7Sopenharmony_ci 250e5c31af7Sopenharmony_ci/** Implements negative test A. Description follows: 251e5c31af7Sopenharmony_ci * 252e5c31af7Sopenharmony_ci * [A] 253e5c31af7Sopenharmony_ci * * Verify that GL_INVALID_ENUM error is generated if either <srcTarget> or 254e5c31af7Sopenharmony_ci * <dstTarget> is set to any of the proxy texture targets, GL_TEXTURE_BUFFER 255e5c31af7Sopenharmony_ci * or one of the cube-map face selectors. 256e5c31af7Sopenharmony_ci **/ 257e5c31af7Sopenharmony_ciclass InvalidTargetTest : public deqp::TestCase 258e5c31af7Sopenharmony_ci{ 259e5c31af7Sopenharmony_cipublic: 260e5c31af7Sopenharmony_ci InvalidTargetTest(deqp::Context& context); 261e5c31af7Sopenharmony_ci virtual ~InvalidTargetTest() 262e5c31af7Sopenharmony_ci { 263e5c31af7Sopenharmony_ci } 264e5c31af7Sopenharmony_ci 265e5c31af7Sopenharmony_ci /* Implementation of tcu::TestNode methods */ 266e5c31af7Sopenharmony_ci virtual IterateResult iterate(void); 267e5c31af7Sopenharmony_ci 268e5c31af7Sopenharmony_ciprivate: 269e5c31af7Sopenharmony_ci /* Private types */ 270e5c31af7Sopenharmony_ci struct testCase 271e5c31af7Sopenharmony_ci { 272e5c31af7Sopenharmony_ci glw::GLenum m_src_target; 273e5c31af7Sopenharmony_ci glw::GLenum m_dst_target; 274e5c31af7Sopenharmony_ci glw::GLenum m_expected_result; 275e5c31af7Sopenharmony_ci }; 276e5c31af7Sopenharmony_ci 277e5c31af7Sopenharmony_ci /* Private methods */ 278e5c31af7Sopenharmony_ci void clean(); 279e5c31af7Sopenharmony_ci 280e5c31af7Sopenharmony_ci /* Private fields */ 281e5c31af7Sopenharmony_ci glw::GLuint m_dst_buf_name; 282e5c31af7Sopenharmony_ci glw::GLuint m_dst_tex_name; 283e5c31af7Sopenharmony_ci glw::GLuint m_src_buf_name; 284e5c31af7Sopenharmony_ci glw::GLuint m_src_tex_name; 285e5c31af7Sopenharmony_ci glw::GLuint m_test_case_index; 286e5c31af7Sopenharmony_ci std::vector<testCase> m_test_cases; 287e5c31af7Sopenharmony_ci}; 288e5c31af7Sopenharmony_ci 289e5c31af7Sopenharmony_ci/** Implements negative test B. Description follows: 290e5c31af7Sopenharmony_ci * 291e5c31af7Sopenharmony_ci * [B] 292e5c31af7Sopenharmony_ci * * Verify that usage of a non-matching target for either the source or 293e5c31af7Sopenharmony_ci * destination objects results in a GL_INVALID_ENUM error. 294e5c31af7Sopenharmony_ci **/ 295e5c31af7Sopenharmony_ciclass TargetMismatchTest : public deqp::TestCase 296e5c31af7Sopenharmony_ci{ 297e5c31af7Sopenharmony_cipublic: 298e5c31af7Sopenharmony_ci TargetMismatchTest(deqp::Context& context); 299e5c31af7Sopenharmony_ci virtual ~TargetMismatchTest() 300e5c31af7Sopenharmony_ci { 301e5c31af7Sopenharmony_ci } 302e5c31af7Sopenharmony_ci 303e5c31af7Sopenharmony_ci /* Implementation of tcu::TestNode methods */ 304e5c31af7Sopenharmony_ci virtual IterateResult iterate(void); 305e5c31af7Sopenharmony_ci 306e5c31af7Sopenharmony_ciprivate: 307e5c31af7Sopenharmony_ci /* Private types */ 308e5c31af7Sopenharmony_ci struct testCase 309e5c31af7Sopenharmony_ci { 310e5c31af7Sopenharmony_ci glw::GLenum m_tex_target; 311e5c31af7Sopenharmony_ci glw::GLenum m_src_target; 312e5c31af7Sopenharmony_ci glw::GLenum m_dst_target; 313e5c31af7Sopenharmony_ci glw::GLenum m_expected_result; 314e5c31af7Sopenharmony_ci }; 315e5c31af7Sopenharmony_ci 316e5c31af7Sopenharmony_ci /* Private methods */ 317e5c31af7Sopenharmony_ci void clean(); 318e5c31af7Sopenharmony_ci 319e5c31af7Sopenharmony_ci /* Private fields */ 320e5c31af7Sopenharmony_ci glw::GLuint m_dst_buf_name; 321e5c31af7Sopenharmony_ci glw::GLuint m_dst_tex_name; 322e5c31af7Sopenharmony_ci glw::GLuint m_src_buf_name; 323e5c31af7Sopenharmony_ci glw::GLuint m_src_tex_name; 324e5c31af7Sopenharmony_ci glw::GLuint m_test_case_index; 325e5c31af7Sopenharmony_ci std::vector<testCase> m_test_cases; 326e5c31af7Sopenharmony_ci}; 327e5c31af7Sopenharmony_ci 328e5c31af7Sopenharmony_ci/** Implements negative test C. Description follows: 329e5c31af7Sopenharmony_ci * 330e5c31af7Sopenharmony_ci * [C] 331e5c31af7Sopenharmony_ci * * Verify that INVALID_OPERATION is generated when the texture provided 332e5c31af7Sopenharmony_ci * to CopyImageSubData is incomplete 333e5c31af7Sopenharmony_ci **/ 334e5c31af7Sopenharmony_ciclass IncompleteTexTest : public deqp::TestCase 335e5c31af7Sopenharmony_ci{ 336e5c31af7Sopenharmony_cipublic: 337e5c31af7Sopenharmony_ci IncompleteTexTest(deqp::Context& context); 338e5c31af7Sopenharmony_ci virtual ~IncompleteTexTest() 339e5c31af7Sopenharmony_ci { 340e5c31af7Sopenharmony_ci } 341e5c31af7Sopenharmony_ci 342e5c31af7Sopenharmony_ci /* Implementation of tcu::TestNode methods */ 343e5c31af7Sopenharmony_ci virtual IterateResult iterate(void); 344e5c31af7Sopenharmony_ci 345e5c31af7Sopenharmony_ciprivate: 346e5c31af7Sopenharmony_ci /* Private types */ 347e5c31af7Sopenharmony_ci struct testCase 348e5c31af7Sopenharmony_ci { 349e5c31af7Sopenharmony_ci glw::GLenum m_tex_target; 350e5c31af7Sopenharmony_ci bool m_is_dst_complete; 351e5c31af7Sopenharmony_ci bool m_is_src_complete; 352e5c31af7Sopenharmony_ci glw::GLenum m_expected_result; 353e5c31af7Sopenharmony_ci }; 354e5c31af7Sopenharmony_ci 355e5c31af7Sopenharmony_ci /* Private methods */ 356e5c31af7Sopenharmony_ci void clean(); 357e5c31af7Sopenharmony_ci 358e5c31af7Sopenharmony_ci /* Private fields */ 359e5c31af7Sopenharmony_ci glw::GLuint m_dst_buf_name; 360e5c31af7Sopenharmony_ci glw::GLuint m_dst_tex_name; 361e5c31af7Sopenharmony_ci glw::GLuint m_src_buf_name; 362e5c31af7Sopenharmony_ci glw::GLuint m_src_tex_name; 363e5c31af7Sopenharmony_ci glw::GLuint m_test_case_index; 364e5c31af7Sopenharmony_ci std::vector<testCase> m_test_cases; 365e5c31af7Sopenharmony_ci}; 366e5c31af7Sopenharmony_ci 367e5c31af7Sopenharmony_ci/** Implements negative test D. Description follows: 368e5c31af7Sopenharmony_ci * 369e5c31af7Sopenharmony_ci * [D] 370e5c31af7Sopenharmony_ci * * Verify that usage of source/destination objects, internal formats of which 371e5c31af7Sopenharmony_ci * are not compatible, results in GL_INVALID_OPERATION error. 372e5c31af7Sopenharmony_ci **/ 373e5c31af7Sopenharmony_ciclass IncompatibleFormatsTest : public deqp::TestCase 374e5c31af7Sopenharmony_ci{ 375e5c31af7Sopenharmony_cipublic: 376e5c31af7Sopenharmony_ci IncompatibleFormatsTest(deqp::Context& context); 377e5c31af7Sopenharmony_ci virtual ~IncompatibleFormatsTest() 378e5c31af7Sopenharmony_ci { 379e5c31af7Sopenharmony_ci } 380e5c31af7Sopenharmony_ci 381e5c31af7Sopenharmony_ci /* Implementation of tcu::TestNode methods */ 382e5c31af7Sopenharmony_ci virtual IterateResult iterate(void); 383e5c31af7Sopenharmony_ci 384e5c31af7Sopenharmony_ciprivate: 385e5c31af7Sopenharmony_ci /* Private types */ 386e5c31af7Sopenharmony_ci struct testCase 387e5c31af7Sopenharmony_ci { 388e5c31af7Sopenharmony_ci glw::GLenum m_tex_target; 389e5c31af7Sopenharmony_ci glw::GLenum m_dst_internal_format; 390e5c31af7Sopenharmony_ci glw::GLenum m_dst_format; 391e5c31af7Sopenharmony_ci glw::GLenum m_dst_type; 392e5c31af7Sopenharmony_ci glw::GLenum m_src_internal_format; 393e5c31af7Sopenharmony_ci glw::GLenum m_src_format; 394e5c31af7Sopenharmony_ci glw::GLenum m_src_type; 395e5c31af7Sopenharmony_ci glw::GLenum m_expected_result; 396e5c31af7Sopenharmony_ci }; 397e5c31af7Sopenharmony_ci 398e5c31af7Sopenharmony_ci /* Private methods */ 399e5c31af7Sopenharmony_ci void clean(); 400e5c31af7Sopenharmony_ci 401e5c31af7Sopenharmony_ci /* Private fields */ 402e5c31af7Sopenharmony_ci glw::GLuint m_dst_buf_name; 403e5c31af7Sopenharmony_ci glw::GLuint m_dst_tex_name; 404e5c31af7Sopenharmony_ci glw::GLuint m_src_buf_name; 405e5c31af7Sopenharmony_ci glw::GLuint m_src_tex_name; 406e5c31af7Sopenharmony_ci glw::GLuint m_test_case_index; 407e5c31af7Sopenharmony_ci std::vector<testCase> m_test_cases; 408e5c31af7Sopenharmony_ci}; 409e5c31af7Sopenharmony_ci 410e5c31af7Sopenharmony_ci/** Implements negative test E. Description follows: 411e5c31af7Sopenharmony_ci * 412e5c31af7Sopenharmony_ci * [E] 413e5c31af7Sopenharmony_ci * * Verify that usage of source/destination objects, internal formats of which 414e5c31af7Sopenharmony_ci * do not match in terms of number of samples they can hold, results in 415e5c31af7Sopenharmony_ci * GL_INVALID_OPERATION error. 416e5c31af7Sopenharmony_ci **/ 417e5c31af7Sopenharmony_ciclass SamplesMismatchTest : public deqp::TestCase 418e5c31af7Sopenharmony_ci{ 419e5c31af7Sopenharmony_cipublic: 420e5c31af7Sopenharmony_ci SamplesMismatchTest(deqp::Context& context); 421e5c31af7Sopenharmony_ci virtual ~SamplesMismatchTest() 422e5c31af7Sopenharmony_ci { 423e5c31af7Sopenharmony_ci } 424e5c31af7Sopenharmony_ci 425e5c31af7Sopenharmony_ci /* Implementation of tcu::TestNode methods */ 426e5c31af7Sopenharmony_ci virtual IterateResult iterate(void); 427e5c31af7Sopenharmony_ci 428e5c31af7Sopenharmony_ciprivate: 429e5c31af7Sopenharmony_ci /* Private types */ 430e5c31af7Sopenharmony_ci struct testCase 431e5c31af7Sopenharmony_ci { 432e5c31af7Sopenharmony_ci glw::GLenum m_src_target; 433e5c31af7Sopenharmony_ci glw::GLsizei m_src_n_samples; 434e5c31af7Sopenharmony_ci glw::GLenum m_dst_target; 435e5c31af7Sopenharmony_ci glw::GLsizei m_dst_n_samples; 436e5c31af7Sopenharmony_ci glw::GLenum m_expected_result; 437e5c31af7Sopenharmony_ci }; 438e5c31af7Sopenharmony_ci 439e5c31af7Sopenharmony_ci /* Private methods */ 440e5c31af7Sopenharmony_ci void clean(); 441e5c31af7Sopenharmony_ci 442e5c31af7Sopenharmony_ci /* Private fields */ 443e5c31af7Sopenharmony_ci glw::GLuint m_dst_tex_name; 444e5c31af7Sopenharmony_ci glw::GLuint m_src_tex_name; 445e5c31af7Sopenharmony_ci glw::GLuint m_test_case_index; 446e5c31af7Sopenharmony_ci std::vector<testCase> m_test_cases; 447e5c31af7Sopenharmony_ci}; 448e5c31af7Sopenharmony_ci 449e5c31af7Sopenharmony_ci/** Implements negative test F. Description follows: 450e5c31af7Sopenharmony_ci * 451e5c31af7Sopenharmony_ci * [F] 452e5c31af7Sopenharmony_ci * * Verify that usage of a pair of objects, one of which is defined by 453e5c31af7Sopenharmony_ci * compressed data and the other one has a non-compressed representation, 454e5c31af7Sopenharmony_ci * results in a GL_INVALID_OPERATION error, if the block size of compressed 455e5c31af7Sopenharmony_ci * image is not equal to the texel size of the compressed image. 456e5c31af7Sopenharmony_ci **/ 457e5c31af7Sopenharmony_ciclass IncompatibleFormatsCompressionTest : public deqp::TestCase 458e5c31af7Sopenharmony_ci{ 459e5c31af7Sopenharmony_cipublic: 460e5c31af7Sopenharmony_ci IncompatibleFormatsCompressionTest(deqp::Context& context); 461e5c31af7Sopenharmony_ci virtual ~IncompatibleFormatsCompressionTest() 462e5c31af7Sopenharmony_ci { 463e5c31af7Sopenharmony_ci } 464e5c31af7Sopenharmony_ci 465e5c31af7Sopenharmony_ci /* Implementation of tcu::TestNode methods */ 466e5c31af7Sopenharmony_ci virtual IterateResult iterate(void); 467e5c31af7Sopenharmony_ci 468e5c31af7Sopenharmony_ciprivate: 469e5c31af7Sopenharmony_ci /* Private types */ 470e5c31af7Sopenharmony_ci struct testCase 471e5c31af7Sopenharmony_ci { 472e5c31af7Sopenharmony_ci glw::GLenum m_tex_target; 473e5c31af7Sopenharmony_ci glw::GLenum m_dst_internal_format; 474e5c31af7Sopenharmony_ci glw::GLenum m_dst_format; 475e5c31af7Sopenharmony_ci glw::GLenum m_dst_type; 476e5c31af7Sopenharmony_ci glw::GLenum m_src_internal_format; 477e5c31af7Sopenharmony_ci glw::GLenum m_src_format; 478e5c31af7Sopenharmony_ci glw::GLenum m_src_type; 479e5c31af7Sopenharmony_ci glw::GLenum m_expected_result; 480e5c31af7Sopenharmony_ci }; 481e5c31af7Sopenharmony_ci 482e5c31af7Sopenharmony_ci /* Private methods */ 483e5c31af7Sopenharmony_ci void clean(); 484e5c31af7Sopenharmony_ci 485e5c31af7Sopenharmony_ci /* Private fields */ 486e5c31af7Sopenharmony_ci glw::GLuint m_dst_tex_name; 487e5c31af7Sopenharmony_ci glw::GLuint m_src_tex_name; 488e5c31af7Sopenharmony_ci glw::GLuint m_test_case_index; 489e5c31af7Sopenharmony_ci std::vector<testCase> m_test_cases; 490e5c31af7Sopenharmony_ci}; 491e5c31af7Sopenharmony_ci 492e5c31af7Sopenharmony_ci/** Implements negative test G. Description follows: 493e5c31af7Sopenharmony_ci * 494e5c31af7Sopenharmony_ci * [G] 495e5c31af7Sopenharmony_ci * * Verify that usage of an invalid <srcTarget> or <dstTarget> argument 496e5c31af7Sopenharmony_ci * generates GL_INVALID_VALUE error. For the purpose of the test, make sure 497e5c31af7Sopenharmony_ci * to iterate over the set of all objects that can be used as source or 498e5c31af7Sopenharmony_ci * destination objects. 499e5c31af7Sopenharmony_ci **/ 500e5c31af7Sopenharmony_ciclass InvalidObjectTest : public deqp::TestCase 501e5c31af7Sopenharmony_ci{ 502e5c31af7Sopenharmony_cipublic: 503e5c31af7Sopenharmony_ci InvalidObjectTest(deqp::Context& context); 504e5c31af7Sopenharmony_ci virtual ~InvalidObjectTest() 505e5c31af7Sopenharmony_ci { 506e5c31af7Sopenharmony_ci } 507e5c31af7Sopenharmony_ci 508e5c31af7Sopenharmony_ci /* Implementation of tcu::TestNode methods */ 509e5c31af7Sopenharmony_ci virtual IterateResult iterate(void); 510e5c31af7Sopenharmony_ci 511e5c31af7Sopenharmony_ciprivate: 512e5c31af7Sopenharmony_ci /* Private types */ 513e5c31af7Sopenharmony_ci struct testCase 514e5c31af7Sopenharmony_ci { 515e5c31af7Sopenharmony_ci glw::GLenum m_dst_target; 516e5c31af7Sopenharmony_ci bool m_dst_valid; 517e5c31af7Sopenharmony_ci glw::GLenum m_src_target; 518e5c31af7Sopenharmony_ci bool m_src_valid; 519e5c31af7Sopenharmony_ci glw::GLenum m_expected_result; 520e5c31af7Sopenharmony_ci }; 521e5c31af7Sopenharmony_ci 522e5c31af7Sopenharmony_ci /* Private methods */ 523e5c31af7Sopenharmony_ci void clean(); 524e5c31af7Sopenharmony_ci 525e5c31af7Sopenharmony_ci /* Private fields */ 526e5c31af7Sopenharmony_ci glw::GLuint m_dst_name; 527e5c31af7Sopenharmony_ci glw::GLuint m_src_name; 528e5c31af7Sopenharmony_ci glw::GLuint m_test_case_index; 529e5c31af7Sopenharmony_ci std::vector<testCase> m_test_cases; 530e5c31af7Sopenharmony_ci}; 531e5c31af7Sopenharmony_ci 532e5c31af7Sopenharmony_ci/** Implements negative test H. Description follows: 533e5c31af7Sopenharmony_ci * 534e5c31af7Sopenharmony_ci * [H] 535e5c31af7Sopenharmony_ci * * Make sure that GL_INVALID_VALUE error is generated if <level> argument 536e5c31af7Sopenharmony_ci * refers to a non-existent mip-map level for either the source or the 537e5c31af7Sopenharmony_ci * destination object. In particular, make sure that using any value other 538e5c31af7Sopenharmony_ci * than 0 for render-buffers is considered an erroneous action. 539e5c31af7Sopenharmony_ci **/ 540e5c31af7Sopenharmony_ciclass NonExistentMipMapTest : public deqp::TestCase 541e5c31af7Sopenharmony_ci{ 542e5c31af7Sopenharmony_cipublic: 543e5c31af7Sopenharmony_ci NonExistentMipMapTest(deqp::Context& context); 544e5c31af7Sopenharmony_ci virtual ~NonExistentMipMapTest() 545e5c31af7Sopenharmony_ci { 546e5c31af7Sopenharmony_ci } 547e5c31af7Sopenharmony_ci 548e5c31af7Sopenharmony_ci /* Implementation of tcu::TestNode methods */ 549e5c31af7Sopenharmony_ci virtual IterateResult iterate(void); 550e5c31af7Sopenharmony_ci 551e5c31af7Sopenharmony_ciprivate: 552e5c31af7Sopenharmony_ci /* Private types */ 553e5c31af7Sopenharmony_ci struct testCase 554e5c31af7Sopenharmony_ci { 555e5c31af7Sopenharmony_ci glw::GLenum m_tex_target; 556e5c31af7Sopenharmony_ci glw::GLuint m_src_level; 557e5c31af7Sopenharmony_ci glw::GLuint m_dst_level; 558e5c31af7Sopenharmony_ci glw::GLenum m_expected_result; 559e5c31af7Sopenharmony_ci }; 560e5c31af7Sopenharmony_ci 561e5c31af7Sopenharmony_ci /* Private methods */ 562e5c31af7Sopenharmony_ci void clean(); 563e5c31af7Sopenharmony_ci 564e5c31af7Sopenharmony_ci /* Private fields */ 565e5c31af7Sopenharmony_ci glw::GLuint m_dst_tex_name; 566e5c31af7Sopenharmony_ci glw::GLuint m_src_tex_name; 567e5c31af7Sopenharmony_ci glw::GLuint m_test_case_index; 568e5c31af7Sopenharmony_ci std::vector<testCase> m_test_cases; 569e5c31af7Sopenharmony_ci}; 570e5c31af7Sopenharmony_ci 571e5c31af7Sopenharmony_ci/** Implements negative test I. Description follows: 572e5c31af7Sopenharmony_ci * 573e5c31af7Sopenharmony_ci * [I] 574e5c31af7Sopenharmony_ci * * Make sure that using source/destination subregions that exceed the 575e5c31af7Sopenharmony_ci * boundaries of the relevant object generates a GL_INVALID_VALUE error. 576e5c31af7Sopenharmony_ci **/ 577e5c31af7Sopenharmony_ciclass ExceedingBoundariesTest : public deqp::TestCase 578e5c31af7Sopenharmony_ci{ 579e5c31af7Sopenharmony_cipublic: 580e5c31af7Sopenharmony_ci ExceedingBoundariesTest(deqp::Context& context); 581e5c31af7Sopenharmony_ci virtual ~ExceedingBoundariesTest() 582e5c31af7Sopenharmony_ci { 583e5c31af7Sopenharmony_ci } 584e5c31af7Sopenharmony_ci 585e5c31af7Sopenharmony_ci /* Implementation of tcu::TestNode methods */ 586e5c31af7Sopenharmony_ci virtual IterateResult iterate(void); 587e5c31af7Sopenharmony_ci 588e5c31af7Sopenharmony_ciprivate: 589e5c31af7Sopenharmony_ci /* Private types */ 590e5c31af7Sopenharmony_ci struct testCase 591e5c31af7Sopenharmony_ci { 592e5c31af7Sopenharmony_ci glw::GLenum m_tex_target; 593e5c31af7Sopenharmony_ci glw::GLuint m_depth; 594e5c31af7Sopenharmony_ci glw::GLuint m_height; 595e5c31af7Sopenharmony_ci glw::GLuint m_src_x; 596e5c31af7Sopenharmony_ci glw::GLuint m_src_y; 597e5c31af7Sopenharmony_ci glw::GLuint m_src_z; 598e5c31af7Sopenharmony_ci glw::GLuint m_dst_x; 599e5c31af7Sopenharmony_ci glw::GLuint m_dst_y; 600e5c31af7Sopenharmony_ci glw::GLuint m_dst_z; 601e5c31af7Sopenharmony_ci glw::GLenum m_expected_result; 602e5c31af7Sopenharmony_ci }; 603e5c31af7Sopenharmony_ci 604e5c31af7Sopenharmony_ci /* Private methods */ 605e5c31af7Sopenharmony_ci void clean(); 606e5c31af7Sopenharmony_ci 607e5c31af7Sopenharmony_ci /* Private fields */ 608e5c31af7Sopenharmony_ci glw::GLuint m_dst_tex_name; 609e5c31af7Sopenharmony_ci glw::GLuint m_src_tex_name; 610e5c31af7Sopenharmony_ci glw::GLuint m_test_case_index; 611e5c31af7Sopenharmony_ci std::vector<testCase> m_test_cases; 612e5c31af7Sopenharmony_ci 613e5c31af7Sopenharmony_ci /* Private constants */ 614e5c31af7Sopenharmony_ci static const glw::GLuint m_region_depth; 615e5c31af7Sopenharmony_ci static const glw::GLuint m_region_height; 616e5c31af7Sopenharmony_ci static const glw::GLuint m_region_width; 617e5c31af7Sopenharmony_ci}; 618e5c31af7Sopenharmony_ci 619e5c31af7Sopenharmony_ci/** Implements negative test J. Description follows: 620e5c31af7Sopenharmony_ci * 621e5c31af7Sopenharmony_ci * [J] 622e5c31af7Sopenharmony_ci * * Assume the source and/or the destination object(s) use(s) a compressed 623e5c31af7Sopenharmony_ci * internal format. Make sure that copy operations requested to operate on 624e5c31af7Sopenharmony_ci * subregions that do not meet the alignment constraints of the internal 625e5c31af7Sopenharmony_ci * format in question, generate GL_INVALID_VALUE error. 626e5c31af7Sopenharmony_ci **/ 627e5c31af7Sopenharmony_ciclass InvalidAlignmentTest : public deqp::TestCase 628e5c31af7Sopenharmony_ci{ 629e5c31af7Sopenharmony_cipublic: 630e5c31af7Sopenharmony_ci InvalidAlignmentTest(deqp::Context& context); 631e5c31af7Sopenharmony_ci virtual ~InvalidAlignmentTest() 632e5c31af7Sopenharmony_ci { 633e5c31af7Sopenharmony_ci } 634e5c31af7Sopenharmony_ci 635e5c31af7Sopenharmony_ci /* Implementation of tcu::TestNode methods */ 636e5c31af7Sopenharmony_ci virtual IterateResult iterate(void); 637e5c31af7Sopenharmony_ci 638e5c31af7Sopenharmony_ciprivate: 639e5c31af7Sopenharmony_ci /* Private types */ 640e5c31af7Sopenharmony_ci struct testCase 641e5c31af7Sopenharmony_ci { 642e5c31af7Sopenharmony_ci glw::GLuint m_height; 643e5c31af7Sopenharmony_ci glw::GLuint m_width; 644e5c31af7Sopenharmony_ci glw::GLuint m_src_x; 645e5c31af7Sopenharmony_ci glw::GLuint m_src_y; 646e5c31af7Sopenharmony_ci glw::GLuint m_dst_x; 647e5c31af7Sopenharmony_ci glw::GLuint m_dst_y; 648e5c31af7Sopenharmony_ci glw::GLenum m_expected_result; 649e5c31af7Sopenharmony_ci }; 650e5c31af7Sopenharmony_ci 651e5c31af7Sopenharmony_ci /* Private methods */ 652e5c31af7Sopenharmony_ci void clean(); 653e5c31af7Sopenharmony_ci 654e5c31af7Sopenharmony_ci /* Private fields */ 655e5c31af7Sopenharmony_ci glw::GLuint m_dst_tex_name; 656e5c31af7Sopenharmony_ci glw::GLuint m_src_tex_name; 657e5c31af7Sopenharmony_ci glw::GLuint m_test_case_index; 658e5c31af7Sopenharmony_ci std::vector<testCase> m_test_cases; 659e5c31af7Sopenharmony_ci}; 660e5c31af7Sopenharmony_ci 661e5c31af7Sopenharmony_ci/** Implements functional test. Description follows: 662e5c31af7Sopenharmony_ci * 663e5c31af7Sopenharmony_ci * [B] 664e5c31af7Sopenharmony_ci * 1. Create a single level integer texture, with BASE_LEVEL and MAX_LEVEL set to 0. 665e5c31af7Sopenharmony_ci * 2. Leave the mipmap filters at the default of GL_NEAREST_MIPMAP_LINEAR and GL_LINEAR. 666e5c31af7Sopenharmony_ci * 3. Do glCopyImageSubData to or from that texture. 667e5c31af7Sopenharmony_ci * 4. Make sure it succeeds and does not raise GL_INVALID_OPERATION. 668e5c31af7Sopenharmony_ci **/ 669e5c31af7Sopenharmony_ciclass IntegerTexTest : public deqp::TestCase 670e5c31af7Sopenharmony_ci{ 671e5c31af7Sopenharmony_cipublic: 672e5c31af7Sopenharmony_ci IntegerTexTest(deqp::Context& context); 673e5c31af7Sopenharmony_ci virtual ~IntegerTexTest() 674e5c31af7Sopenharmony_ci { 675e5c31af7Sopenharmony_ci } 676e5c31af7Sopenharmony_ci 677e5c31af7Sopenharmony_ci /* Implementation of tcu::TestNode methods */ 678e5c31af7Sopenharmony_ci virtual IterateResult iterate(void); 679e5c31af7Sopenharmony_ci 680e5c31af7Sopenharmony_ciprivate: 681e5c31af7Sopenharmony_ci /* Private types */ 682e5c31af7Sopenharmony_ci struct testCase 683e5c31af7Sopenharmony_ci { 684e5c31af7Sopenharmony_ci glw::GLint m_internal_format; 685e5c31af7Sopenharmony_ci glw::GLuint m_type; 686e5c31af7Sopenharmony_ci }; 687e5c31af7Sopenharmony_ci 688e5c31af7Sopenharmony_ci /* Private methods */ 689e5c31af7Sopenharmony_ci unsigned int createTexture(int width, int height, glw::GLint internalFormat, glw::GLuint type, const void* data, 690e5c31af7Sopenharmony_ci int minFilter, int magFilter); 691e5c31af7Sopenharmony_ci void clean(); 692e5c31af7Sopenharmony_ci 693e5c31af7Sopenharmony_ci /* Private fields */ 694e5c31af7Sopenharmony_ci glw::GLuint m_dst_buf_name; 695e5c31af7Sopenharmony_ci glw::GLuint m_dst_tex_name; 696e5c31af7Sopenharmony_ci glw::GLuint m_src_buf_name; 697e5c31af7Sopenharmony_ci glw::GLuint m_src_tex_name; 698e5c31af7Sopenharmony_ci glw::GLuint m_test_case_index; 699e5c31af7Sopenharmony_ci}; 700e5c31af7Sopenharmony_ci} 701e5c31af7Sopenharmony_ci 702e5c31af7Sopenharmony_ciclass CopyImageTests : public deqp::TestCaseGroup 703e5c31af7Sopenharmony_ci{ 704e5c31af7Sopenharmony_cipublic: 705e5c31af7Sopenharmony_ci CopyImageTests(deqp::Context& context); 706e5c31af7Sopenharmony_ci ~CopyImageTests(void); 707e5c31af7Sopenharmony_ci 708e5c31af7Sopenharmony_ci virtual void init(void); 709e5c31af7Sopenharmony_ci 710e5c31af7Sopenharmony_ciprivate: 711e5c31af7Sopenharmony_ci CopyImageTests(const CopyImageTests& other); 712e5c31af7Sopenharmony_ci CopyImageTests& operator=(const CopyImageTests& other); 713e5c31af7Sopenharmony_ci}; 714e5c31af7Sopenharmony_ci} /* namespace gl4cts */ 715e5c31af7Sopenharmony_ci 716e5c31af7Sopenharmony_ci#endif // _GL4CCOPYIMAGETESTS_HPP 717