1/*------------------------------------------------------------------------- 2 * OpenGL Conformance Test Suite 3 * ----------------------------- 4 * 5 * Copyright (c) 2014-2016 The Khronos Group Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 */ /*! 20 * \file 21 * \brief 22 */ /*-------------------------------------------------------------------*/ 23 24/** 25 */ /*! 26 * \file esextcDrawElementsBaseVertexTests.cpp 27 * \brief Implements conformance tests for "draw elements base vertex" functionality 28 * for both ES and GL. 29 */ /*-------------------------------------------------------------------*/ 30 31#include "esextcDrawElementsBaseVertexTests.hpp" 32#include "gluContextInfo.hpp" 33#include "gluDefs.hpp" 34#include "glwEnums.hpp" 35#include "glwFunctions.hpp" 36#include "tcuRenderTarget.hpp" 37#include "tcuTestLog.hpp" 38 39#include <string> 40#include <vector> 41 42namespace glcts 43{ 44/** Constructor. 45 * 46 * @param context Rendering context 47 * @param name Test name 48 * @param description Test description 49 */ 50DrawElementsBaseVertexTestBase::DrawElementsBaseVertexTestBase(glcts::Context& context, const ExtParameters& extParams, 51 const char* name, const char* description) 52 : TestCaseBase(context, extParams, name, description) 53 , m_is_draw_elements_base_vertex_supported(false) 54 , m_is_ext_multi_draw_arrays_supported(false) 55 , m_is_geometry_shader_supported(false) 56 , m_is_tessellation_shader_supported(false) 57 , m_is_vertex_attrib_binding_supported(false) 58 , m_bo_id(0) 59 , m_bo_id_2(0) 60 , m_fbo_id(0) 61 , m_fs_id(0) 62 , m_gs_id(0) 63 , m_po_id(0) 64 , m_po_color_attribute_location(-1) 65 , m_po_uses_gs_stage(false) 66 , m_po_uses_tc_te_stages(false) 67 , m_po_uses_vertex_attrib_binding(false) 68 , m_po_vertex_attribute_location(-1) 69 , m_tc_id(0) 70 , m_te_id(0) 71 , m_to_base_id(0) 72 , m_to_ref_id(0) 73 , m_vao_id(0) 74 , m_vs_id(0) 75 , m_bo_negative_data_index_size(-1) 76 , m_bo_negative_data_vertex_size(-1) 77 , m_draw_call_color_offset(DE_NULL) 78 , m_draw_call_index_offset(DE_NULL) 79 , m_draw_call_index2_offset(DE_NULL) 80 , m_draw_call_index3_offset(DE_NULL) 81 , m_draw_call_index4_offset(DE_NULL) 82 , m_draw_call_index5_offset(DE_NULL) 83 , m_draw_call_vertex_offset(DE_NULL) 84 , m_draw_call_vertex2_offset(DE_NULL) 85 , m_to_height(128) 86 , m_to_width(128) 87 , m_to_base_data(DE_NULL) 88 , m_to_ref_data(DE_NULL) 89{ 90 static const glw::GLuint functional_index_data[] = /* used for a number of Functional Tests */ 91 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22 }; 92 static const glw::GLuint functional2_index_data[] = /* used for Functional Test IV */ 93 { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 94 30, 31, 32, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; 95 static const glw::GLubyte functional3_index_data[] = /* used for Functional Test IX */ 96 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; 97 static const glw::GLushort functional4_index_data[] = /* used for Functional Test IX */ 98 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; 99 static const glw::GLuint functional5_index_data[] = /* used for Functional Test IX */ 100 { 2147483647 + 3u, /* 2^31 + 2 */ 101 2147483647 + 4u, 102 2147483647 + 5u, 103 2147483647 + 6u, 104 2147483647 + 7u, 105 2147483647 + 8u, 106 2147483647 + 9u, 107 2147483647 + 10u, 108 2147483647 + 11u, 109 2147483647 + 12u, 110 2147483647 + 13u, 111 2147483647 + 14u, 112 257, // regular draw call indices for ubyte ref image 113 258, 114 259, 115 260, 116 261, 117 262, 118 263, 119 264, 120 265, 121 266, 122 267, 123 268, 124 65537, // regular draw call indices for ushort ref image 125 65538, 126 65539, 127 65540, 128 65541, 129 65542, 130 65543, 131 65544, 132 65545, 133 65546, 134 65547, 135 65548, 136 0, // regular draw call indices for uint ref image 137 1, 138 2, 139 3, 140 4, 141 5, 142 6, 143 7, 144 8, 145 9, 146 10, 147 11 }; 148 static const glw::GLfloat functional_color_data[] = /* used for "vertex attrib binding" Functional Test */ 149 { 150 0.1f, 0.2f, 0.2f, 0.3f, 0.3f, 0.4f, 0.4f, 0.5f, 0.5f, 0.6f, 0.6f, 0.7f, 0.7f, 0.8f, 0.8f, 0.9f, 0.9f, 151 1.0f, 1.0f, 0.9f, 0.9f, 0.8f, 0.8f, 0.7f, 0.7f, 0.6f, 0.6f, 0.5f, 0.5f, 0.4f, 0.4f, 0.3f, 0.3f, 0.2f, 152 0.2f, 0.1f, 0.1f, 0.0f, 0.0f, 0.1f, 0.1f, 0.2f, 0.2f, 0.4f, 0.3f, 0.9f, 0.4f, 0.8f, 0.5f, 1.0f, 0.6f, 153 0.8f, 0.7f, 0.1f, 0.8f, 0.3f, 0.9f, 0.5f, 1.0f, 0.0f, 0.2f, 0.0f, 0.0f, 0.3f, 0.1f, 1.0f, 154 }; 155 static const glw::GLfloat functional_vertex_data[] = /* used by a number of Functional Tests */ 156 { 157 0.0f, 0.0f, -0.1f, -0.1f, 0.2f, 0.8f, -0.3f, -0.3f, 0.4f, -0.4f, 0.5f, 0.5f, -0.6f, 0.6f, 158 0.7f, -0.7f, -0.8f, 0.8f, 0.9f, -0.9f, -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, -0.9f, 0.1f, 159 0.8f, -0.2f, -0.7f, 0.3f, -0.6f, -0.4f, 0.5f, -0.5f, -0.4f, -0.6f, 0.3f, 0.7f, -0.2f, -0.8f, 160 -0.1f, -0.9f, 0.0f, 0.0f, 0.5f, 0.5f, -0.6f, 0.6f, 0.7f, -0.7f, -0.8f, 0.8f, 0.9f, -0.9f, 161 -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, -0.9f, 0.1f, 0.8f, -0.2f, 162 }; 163 static const glw::GLfloat functional2_vertex_data[] = /* used by a number of Functional Tests */ 164 { 165 -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.3f, 0.3f, 0.4f, 0.4f, 0.5f, 0.5f, 0.6f, 0.6f, 0.7f, 0.7f, 166 0.8f, 0.8f, 0.9f, 0.9f, 0.1f, 0.2f, 0.2f, 0.1f, 0.1f, 0.2f, 0.9f, 0.1f, 0.8f, 0.2f, 0.7f, 0.3f, 167 0.6f, 0.4f, 0.5f, 0.5f, 0.4f, 0.6f, 0.3f, 0.7f, 0.2f, 0.8f, 0.1f, 0.9f, 0.0f, 0.0f, 168 169 }; 170 static const glw::GLuint negative_index_data[] = { 0, 1, 2 }; 171 static const float negative_vertex_data[] = { -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 1.0f }; 172 173 m_bo_functional_data_color = functional_color_data; 174 m_bo_functional_data_color_size = sizeof(functional_color_data); 175 m_bo_functional_data_index = functional_index_data; 176 m_bo_functional_data_index_size = sizeof(functional_index_data); 177 m_bo_functional_data_vertex = functional_vertex_data; 178 m_bo_functional_data_vertex_size = sizeof(functional_vertex_data); 179 m_bo_functional2_data_index = functional2_index_data; 180 m_bo_functional2_data_index_size = sizeof(functional2_index_data); 181 m_bo_functional3_data_index = functional3_index_data; 182 m_bo_functional3_data_index_size = sizeof(functional3_index_data); 183 m_bo_functional4_data_index = functional4_index_data; 184 m_bo_functional4_data_index_size = sizeof(functional4_index_data); 185 m_bo_functional5_data_index = functional5_index_data; 186 m_bo_functional5_data_index_size = sizeof(functional5_index_data); 187 m_bo_functional2_data_vertex = functional2_vertex_data; 188 m_bo_functional2_data_vertex_size = sizeof(functional2_vertex_data); 189 m_bo_negative_data_index = negative_index_data; 190 m_bo_negative_data_index_size = sizeof(negative_index_data); 191 m_bo_negative_data_vertex = negative_vertex_data; 192 m_bo_negative_data_vertex_size = sizeof(negative_vertex_data); 193} 194 195/** Creates & initializes a number of shader objects, assigns user-provided 196 * code to relevant shader objects and compiles them. If all shaders are 197 * compiled successfully, they are later attached to a program object, id 198 * of which is stored in m_po_id. Finally, the program object is linked. 199 * 200 * If the compilation process or the linking process fails for any reason, 201 * the method throws a TestError exception. 202 * 203 * Fragment shader object ID is stored under m_fs_id. 204 * Geometry shader object ID is stored under m_gs_id. 205 * Tessellation control shader object ID is stored under m_tc_id. 206 * Tessellation evaluation shader object ID is stored under m_te_id. 207 * Vertex shader object ID is stored under m_vs_id. 208 * 209 * @param fs_code Code to use for the fragment shader. Must not be NULL. 210 * @param gs_code Code to use for the geometry shader. Can be NULL. 211 * @param tc_code Code to use for the tessellation control shader. Can be NULL. 212 * @param te_code Code to use for the tessellation evaluation shader. Can be NULL. 213 * @param vs_code Code to use for the vertex shader. Must not be NULL. 214 * 215 */ 216void DrawElementsBaseVertexTestBase::buildProgram(const char* fs_code, const char* vs_code, const char* tc_code, 217 const char* te_code, const char* gs_code) 218{ 219 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 220 221 /* Create program & shader objects */ 222 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER); 223 m_vs_id = gl.createShader(GL_VERTEX_SHADER); 224 225 if (tc_code != DE_NULL) 226 { 227 m_tc_id = gl.createShader(GL_TESS_CONTROL_SHADER); 228 } 229 230 if (te_code != DE_NULL) 231 { 232 m_te_id = gl.createShader(GL_TESS_EVALUATION_SHADER); 233 } 234 235 if (gs_code != DE_NULL) 236 { 237 m_gs_id = gl.createShader(GL_GEOMETRY_SHADER); 238 } 239 240 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed."); 241 242 m_po_id = gl.createProgram(); 243 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed."); 244 245 /* Assign source code to the shader objects */ 246 gl.shaderSource(m_fs_id, 1, /* count */ 247 &fs_code, DE_NULL); /* length */ 248 gl.shaderSource(m_vs_id, 1, /* count */ 249 &vs_code, DE_NULL); /* length */ 250 251 if (m_tc_id != 0) 252 { 253 gl.shaderSource(m_tc_id, 1, /* count */ 254 &tc_code, DE_NULL); /* length */ 255 } 256 257 if (m_te_id != 0) 258 { 259 gl.shaderSource(m_te_id, 1, /* count */ 260 &te_code, DE_NULL); /* length */ 261 } 262 263 if (m_gs_id != 0) 264 { 265 gl.shaderSource(m_gs_id, 1, /* count */ 266 &gs_code, DE_NULL); /* length */ 267 } 268 269 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call(s) failed."); 270 271 /* Try to compile the shaders */ 272 const glw::GLuint so_ids[] = { m_fs_id, m_vs_id, m_tc_id, m_te_id, m_gs_id }; 273 const unsigned int n_so_ids = sizeof(so_ids) / sizeof(so_ids[0]); 274 275 for (unsigned int n_so_id = 0; n_so_id < n_so_ids; ++n_so_id) 276 { 277 glw::GLint compile_status = GL_FALSE; 278 glw::GLuint so_id = so_ids[n_so_id]; 279 280 if (so_id != 0) 281 { 282 gl.compileShader(so_id); 283 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed"); 284 285 gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status); 286 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed."); 287 288 if (compile_status == GL_FALSE) 289 { 290 TCU_FAIL("Shader compilation failed"); 291 } /* if (compile_status == GL_FALSE) */ 292 } /* if (so_id != 0) */ 293 } /* for (all shader objects) */ 294 295 /* Attach the shaders to the program object */ 296 gl.attachShader(m_po_id, m_fs_id); 297 gl.attachShader(m_po_id, m_vs_id); 298 299 if (m_tc_id != 0) 300 { 301 gl.attachShader(m_po_id, m_tc_id); 302 } 303 304 if (m_te_id != 0) 305 { 306 gl.attachShader(m_po_id, m_te_id); 307 } 308 309 if (m_gs_id != 0) 310 { 311 gl.attachShader(m_po_id, m_gs_id); 312 } 313 314 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed."); 315 316 /* Set up TFO */ 317 const glw::GLchar* tf_varyings[] = { "gl_Position" }; 318 319 gl.transformFeedbackVaryings(m_po_id, 1, /* count */ 320 tf_varyings, GL_SEPARATE_ATTRIBS); 321 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call failed."); 322 323 /* Try to link the program object */ 324 glw::GLint link_status = GL_FALSE; 325 326 gl.linkProgram(m_po_id); 327 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed."); 328 329 gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status); 330 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed."); 331 332 if (link_status == GL_FALSE) 333 { 334 TCU_FAIL("Program linking failed."); 335 } 336 337 /* Retrieve attribute locations */ 338 m_po_color_attribute_location = 339 gl.getAttribLocation(m_po_id, "in_color"); /* != -1 only for "vertex attrib binding" tests */ 340 m_po_vertex_attribute_location = gl.getAttribLocation(m_po_id, "vertex"); 341 342 DE_ASSERT(m_po_vertex_attribute_location != -1); 343} 344 345/** Verifies contents of the base & reference textures. This method can work 346 * in two modes: 347 * 348 * a) If @param should_be_equal is true, the method will throw a TestError exception 349 * if the two textures are not a match. 350 * b) If @param should_be_equal is false, the method will throw a TestError exception 351 * if the two extures are a match. 352 * 353 * Furthermore, in order to verify that the basevertex & regular draw calls actually 354 * generated at least one sample, the method verifies that at least one texel in both 355 * of the textures has been modified. If all texels in any of the textures are found 356 * to be (0, 0, 0) (alpha channel is ignored), TestError exception will be generated. 357 * 358 * @param should_be_equal Please see description for more details. 359 **/ 360void DrawElementsBaseVertexTestBase::compareBaseAndReferenceTextures(bool should_be_equal) 361{ 362 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 363 364 /* Read contents of both base and reference textures */ 365 gl.framebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_to_base_id, 0); /* level */ 366 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed."); 367 368 gl.readPixels(0, /* x */ 369 0, /* y */ 370 m_to_width, m_to_height, GL_RGBA, GL_UNSIGNED_BYTE, m_to_base_data); 371 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed."); 372 373 gl.framebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_to_ref_id, 0); /* level */ 374 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed."); 375 gl.readPixels(0, /* x */ 376 0, /* y */ 377 m_to_width, m_to_height, GL_RGBA, GL_UNSIGNED_BYTE, m_to_ref_data); 378 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed."); 379 380 /* Both tests should be a match */ 381 const unsigned char* base_data_ptr = m_to_base_data; 382 bool all_base_rgb_texels_zero = true; 383 bool all_reference_rgb_texels_zero = true; 384 const unsigned int n_texels = m_to_width * m_to_height; 385 const unsigned char* ref_data_ptr = m_to_ref_data; 386 bool textures_identical = true; 387 388 for (unsigned int n_texel = 0; n_texel < n_texels; ++n_texel) 389 { 390 /* Verify something was rendered to one of the render-targets. Note we 391 * omit alpha channel, since the clear color is set to 0xFF by default */ 392 if (base_data_ptr[0] != 0 || base_data_ptr[1] != 0 || base_data_ptr[2] != 0) 393 { 394 all_base_rgb_texels_zero = false; 395 } 396 397 if (ref_data_ptr[0] != 0 || ref_data_ptr[1] != 0 || ref_data_ptr[2] != 0) 398 { 399 all_reference_rgb_texels_zero = false; 400 } 401 402 if (base_data_ptr[0] != ref_data_ptr[0] || base_data_ptr[1] != ref_data_ptr[1] || 403 base_data_ptr[2] != ref_data_ptr[2] || base_data_ptr[3] != ref_data_ptr[3]) 404 { 405 if (should_be_equal) 406 { 407 const unsigned int y = n_texel / m_to_width; 408 const unsigned int x = n_texel % m_to_width; 409 410 m_testCtx.getLog() << tcu::TestLog::Message << "Pixels at (" << x << ", " << y 411 << ") do not match. Found:" 412 << "(" << (unsigned int)base_data_ptr[0] << ", " << (unsigned int)base_data_ptr[1] 413 << ", " << (unsigned int)base_data_ptr[2] << ", " << (unsigned int)base_data_ptr[3] 414 << "), expected:" 415 << "(" << (unsigned int)ref_data_ptr[0] << ", " << (unsigned int)ref_data_ptr[1] 416 << ", " << (unsigned int)ref_data_ptr[2] << ", " << (unsigned int)ref_data_ptr[3] 417 << ")." << tcu::TestLog::EndMessage; 418 419 TCU_FAIL("Pixel mismatch"); 420 } 421 else 422 { 423 /* Base and reference textures are *not* identical. */ 424 textures_identical = false; 425 } 426 } 427 428 base_data_ptr += 4; /* components */ 429 ref_data_ptr += 4; /* components */ 430 } /* for (all texels) */ 431 432 if (all_base_rgb_texels_zero) 433 { 434 TCU_FAIL("Draw call used to render contents of the base texture did not change the texture"); 435 } 436 437 if (all_reference_rgb_texels_zero) 438 { 439 TCU_FAIL("Draw call used to render contents of the reference texture did not change the texture"); 440 } 441 442 if (!should_be_equal && textures_identical) 443 { 444 TCU_FAIL("Textures are a match, even though they should not be identical."); 445 } 446} 447 448/** Updates m_draw_call_color_offset, m_draw_call_index*_offset and m_draw_call_vertex*_offset 449 * members with valid values, depending on the input arguments. 450 * 451 * @param use_clientside_index_data true if client-side index data buffer is going to be 452 * used for the test-issued draw calls, false otherwise. 453 * @param use_clientside_vertex_data true if client-side color & vertex data buffer is going 454 * to be used for the test-issued draw calls, false 455 * otherwise. 456 */ 457void DrawElementsBaseVertexTestBase::computeVBODataOffsets(bool use_clientside_index_data, 458 bool use_clientside_vertex_data) 459{ 460 if (use_clientside_index_data) 461 { 462 m_draw_call_index_offset = m_bo_functional_data_index; 463 m_draw_call_index2_offset = m_bo_functional2_data_index; 464 m_draw_call_index3_offset = m_bo_functional3_data_index; 465 m_draw_call_index4_offset = m_bo_functional4_data_index; 466 m_draw_call_index5_offset = m_bo_functional5_data_index; 467 } 468 else 469 { 470 /* Note that these assignments correspond to how the buffer object storage is constructed. 471 * If you need to update these offsets, don't forget to update the glBufferSubData() calls 472 */ 473 m_draw_call_index_offset = 474 (const glw::GLuint*)(deUintptr)(m_bo_functional_data_vertex_size + m_bo_functional2_data_vertex_size); 475 m_draw_call_index2_offset = (const glw::GLuint*)(deUintptr)( 476 m_bo_functional_data_vertex_size + m_bo_functional2_data_vertex_size + m_bo_functional_data_index_size); 477 m_draw_call_index3_offset = 478 (const glw::GLubyte*)(deUintptr)(m_bo_functional_data_vertex_size + m_bo_functional2_data_vertex_size + 479 m_bo_functional_data_index_size + m_bo_functional2_data_index_size); 480 m_draw_call_index4_offset = (const glw::GLushort*)(deUintptr)( 481 m_bo_functional_data_vertex_size + m_bo_functional2_data_vertex_size + m_bo_functional_data_index_size + 482 m_bo_functional2_data_index_size + m_bo_functional3_data_index_size); 483 m_draw_call_index5_offset = (const glw::GLuint*)(deUintptr)( 484 m_bo_functional_data_vertex_size + m_bo_functional2_data_vertex_size + m_bo_functional_data_index_size + 485 m_bo_functional2_data_index_size + m_bo_functional3_data_index_size + m_bo_functional4_data_index_size); 486 } 487 488 if (use_clientside_vertex_data) 489 { 490 m_draw_call_color_offset = m_bo_functional_data_color; 491 m_draw_call_vertex_offset = m_bo_functional_data_vertex; 492 m_draw_call_vertex2_offset = m_bo_functional2_data_vertex; 493 } 494 else 495 { 496 /* Note: same observation as above holds. */ 497 m_draw_call_color_offset = (const glw::GLfloat*)(deUintptr)( 498 m_bo_functional_data_vertex_size + m_bo_functional2_data_vertex_size + m_bo_functional_data_index_size + 499 m_bo_functional2_data_index_size + m_bo_functional3_data_index_size + m_bo_functional4_data_index_size + 500 m_bo_functional5_data_index_size); 501 m_draw_call_vertex_offset = DE_NULL; 502 m_draw_call_vertex2_offset = (const glw::GLfloat*)(deUintptr)m_bo_functional_data_vertex_size; 503 } 504} 505 506void DrawElementsBaseVertexTestBase::deinit() 507{ 508 /* TCU_FAIL will skip the per test object de-initialization, we need to 509 * take care of it here 510 */ 511 deinitPerTestObjects(); 512} 513 514/** Deinitializes all ES objects created by the test. */ 515void DrawElementsBaseVertexTestBase::deinitPerTestObjects() 516{ 517 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 518 519 deinitProgramAndShaderObjects(); 520 521 if (m_bo_id != 0) 522 { 523 gl.deleteBuffers(1, &m_bo_id); 524 525 m_bo_id = 0; 526 } 527 528 if (m_bo_id_2 != 0) 529 { 530 gl.deleteBuffers(1, &m_bo_id_2); 531 532 m_bo_id_2 = 0; 533 } 534 535 if (m_fbo_id != 0) 536 { 537 gl.deleteFramebuffers(1, &m_fbo_id); 538 539 m_fbo_id = 0; 540 } 541 542 if (m_to_base_data != DE_NULL) 543 { 544 delete[] m_to_base_data; 545 546 m_to_base_data = DE_NULL; 547 } 548 549 if (m_to_base_id != 0) 550 { 551 gl.deleteTextures(1, &m_to_base_id); 552 553 m_to_base_id = 0; 554 } 555 556 if (m_to_ref_data != DE_NULL) 557 { 558 delete[] m_to_ref_data; 559 560 m_to_ref_data = DE_NULL; 561 } 562 563 if (m_to_ref_id != 0) 564 { 565 gl.deleteTextures(1, &m_to_ref_id); 566 567 m_to_ref_id = 0; 568 } 569 570 if (m_vao_id != 0) 571 { 572 gl.deleteVertexArrays(1, &m_vao_id); 573 574 m_vao_id = 0; 575 } 576 577 if (m_vs_id != 0) 578 { 579 gl.deleteShader(m_vs_id); 580 581 m_vs_id = 0; 582 } 583 584 /* Restore the default GL_PACK_ALIGNMENT setting */ 585 gl.pixelStorei(GL_PACK_ALIGNMENT, 4); 586} 587 588/** Deinitializes all program & shader objects that may have been initialized 589 * by the test. 590 */ 591void DrawElementsBaseVertexTestBase::deinitProgramAndShaderObjects() 592{ 593 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 594 595 if (m_fs_id != 0) 596 { 597 gl.deleteShader(m_fs_id); 598 599 m_fs_id = 0; 600 } 601 602 if (m_gs_id != 0) 603 { 604 gl.deleteShader(m_gs_id); 605 606 m_gs_id = 0; 607 } 608 609 if (m_po_id != 0) 610 { 611 gl.deleteProgram(m_po_id); 612 613 m_po_id = 0; 614 } 615 616 if (m_tc_id != 0) 617 { 618 gl.deleteShader(m_tc_id); 619 620 m_tc_id = 0; 621 } 622 623 if (m_te_id != 0) 624 { 625 gl.deleteShader(m_te_id); 626 627 m_te_id = 0; 628 } 629} 630 631/** Executes all test cases stored in m_test_cases. 632 * 633 * This method throws a TestError exception upon test failure. 634 **/ 635void DrawElementsBaseVertexTestBase::executeTestCases() 636{ 637 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 638 639 /* Iterate over all test cases */ 640 for (_test_cases_const_iterator test_cases_iterator = m_test_cases.begin(); 641 test_cases_iterator != m_test_cases.end(); ++test_cases_iterator) 642 { 643 const _test_case& test_case = *test_cases_iterator; 644 645 /* What is the size of a single index value? */ 646 unsigned int index_size = 0; 647 648 switch (test_case.index_type) 649 { 650 case GL_UNSIGNED_BYTE: 651 index_size = 1; 652 break; 653 case GL_UNSIGNED_SHORT: 654 index_size = 2; 655 break; 656 case GL_UNSIGNED_INT: 657 index_size = 4; 658 break; 659 660 default: 661 { 662 TCU_FAIL("Unrecognized index type"); 663 } 664 } /* switch (test_case.index_type) */ 665 666 /* Set up the work environment */ 667 setUpFunctionalTestObjects(test_case.use_clientside_vertex_data, test_case.use_clientside_index_data, 668 test_case.use_tessellation_shader_stage, test_case.use_geometry_shader_stage, 669 test_case.use_vertex_attrib_binding, test_case.use_overflow_test_vertices); 670 671 gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_to_base_id, 0); /* level */ 672 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed"); 673 674 gl.clear(GL_COLOR_BUFFER_BIT); 675 GLU_EXPECT_NO_ERROR(gl.getError(), "glClear() call failed."); 676 677 switch (test_case.function_type) 678 { 679 case FUNCTION_GL_DRAW_ELEMENTS_BASE_VERTEX: 680 { 681 gl.drawElementsBaseVertex(test_case.primitive_mode, 3, /* count */ 682 test_case.index_type, test_case.index_offset, test_case.basevertex); 683 684 break; 685 } 686 687 case FUNCTION_GL_DRAW_ELEMENTS_INSTANCED_BASE_VERTEX: 688 { 689 gl.drawElementsInstancedBaseVertex(test_case.primitive_mode, 3, /* count */ 690 test_case.index_type, test_case.index_offset, 3, /* instancecount */ 691 test_case.basevertex); 692 693 break; 694 } 695 696 case FUNCTION_GL_DRAW_RANGE_ELEMENTS_BASE_VERTEX: 697 { 698 gl.drawRangeElementsBaseVertex(test_case.primitive_mode, test_case.range_start, test_case.range_end, 699 3, /* count */ 700 test_case.index_type, test_case.index_offset, test_case.basevertex); 701 702 break; 703 } 704 705 case FUNCTION_GL_MULTI_DRAW_ELEMENTS_BASE_VERTEX: 706 { 707 const glw::GLint basevertex_array[] = { test_case.basevertex, test_case.basevertex, test_case.basevertex }; 708 709 gl.multiDrawElementsBaseVertex( 710 test_case.primitive_mode, test_case.multi_draw_call_count_array, test_case.index_type, 711 (const glw::GLvoid**)test_case.multi_draw_call_indices_array, 3, /* primcount */ 712 basevertex_array); 713 714 break; 715 } 716 717 default: 718 { 719 TCU_FAIL("Unsupported function index"); 720 } 721 } /* switch (n_function) */ 722 723 if (gl.getError() != GL_NO_ERROR) 724 { 725 std::stringstream error_sstream; 726 727 error_sstream << getFunctionName(test_case.function_type) << " call failed"; 728 TCU_FAIL(error_sstream.str().c_str()); 729 } 730 731 /* Now, render the same triangle using glDrawElements() to the reference texture */ 732 gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_to_ref_id, 0); /* level */ 733 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed"); 734 735 gl.clear(GL_COLOR_BUFFER_BIT); 736 GLU_EXPECT_NO_ERROR(gl.getError(), "glClear() call failed."); 737 738 glw::GLenum regular_draw_call_index_type = test_case.index_type; 739 if (test_case.regular_draw_call_index_type != 0) 740 { 741 /* Need to use a different index type for regular draw call */ 742 regular_draw_call_index_type = test_case.regular_draw_call_index_type; 743 744 switch (test_case.regular_draw_call_index_type) 745 { 746 case GL_UNSIGNED_BYTE: 747 index_size = 1; 748 break; 749 case GL_UNSIGNED_SHORT: 750 index_size = 2; 751 break; 752 case GL_UNSIGNED_INT: 753 index_size = 4; 754 break; 755 756 default: 757 { 758 TCU_FAIL("Unrecognized index type"); 759 } 760 } 761 } 762 763 glw::GLubyte* regular_draw_call_offset = 764 (glw::GLubyte*)test_case.index_offset + index_size * test_case.regular_draw_call_offset; 765 if (test_case.use_overflow_test_vertices) 766 { 767 /* Special case for overflow test */ 768 regular_draw_call_offset = (glw::GLubyte*)test_case.regular_draw_call_offset2; 769 } 770 771 switch (test_case.function_type) 772 { 773 case FUNCTION_GL_DRAW_ELEMENTS_BASE_VERTEX: /* pass-through */ 774 case FUNCTION_GL_DRAW_RANGE_ELEMENTS_BASE_VERTEX: 775 { 776 gl.drawElements(test_case.primitive_mode, 3, /* count */ 777 regular_draw_call_index_type, regular_draw_call_offset); /* as per test spec */ 778 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawElements() call failed"); 779 780 break; 781 } 782 783 case FUNCTION_GL_DRAW_ELEMENTS_INSTANCED_BASE_VERTEX: 784 { 785 gl.drawElementsInstanced(test_case.primitive_mode, 3, /* count */ 786 regular_draw_call_index_type, regular_draw_call_offset, 3); /* instancecount */ 787 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawElementsInstanced() call failed"); 788 789 break; 790 } 791 792 case FUNCTION_GL_MULTI_DRAW_ELEMENTS_BASE_VERTEX: 793 { 794 /* Normally we'd just use glMultiDrawElements() here but it's not a part 795 * of ES3.1 core spec and we're trying to avoid any dependencies in the test. 796 * No damage done under GL, either. 797 */ 798 for (unsigned int n_draw_call = 0; n_draw_call < 3; /* drawcount */ 799 ++n_draw_call) 800 { 801 gl.drawElements(test_case.primitive_mode, test_case.multi_draw_call_count_array[n_draw_call], 802 regular_draw_call_index_type, 803 (const glw::GLvoid*)test_case.regular_multi_draw_call_offseted_array[n_draw_call]); 804 805 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawElements() call failed."); 806 } 807 808 break; 809 } 810 811 default: 812 { 813 TCU_FAIL("Unrecognized function index"); 814 } 815 } /* switch (n_function) */ 816 817 /* Compare the two textures and make sure they are either a match or not, 818 * depending on whether basevertex values match the offsets used for regular 819 * draw calls. 820 */ 821 compareBaseAndReferenceTextures(test_case.should_base_texture_match_reference_texture); 822 823 /* ES Resources are allocated per test objects, we need to release them here */ 824 deinitPerTestObjects(); 825 } /* for (all test cases) */ 826} 827 828/* Returns name of the function represented by _function_type. 829 * 830 * @param function_type Function type to use for the query. 831 * 832 * @return As per description, or "[?]" (without the quotation marks) 833 * if @param function_type was not recognized. 834 */ 835std::string DrawElementsBaseVertexTestBase::getFunctionName(_function_type function_type) 836{ 837 std::string result = "[?]"; 838 839 switch (function_type) 840 { 841 case FUNCTION_GL_DRAW_ELEMENTS_BASE_VERTEX: 842 { 843 if (glu::isContextTypeES(m_context.getRenderContext().getType())) 844 { 845 result = "glDrawElementsBaseVertexEXT()"; 846 847 break; 848 } 849 else 850 { 851 result = "glDrawElementsBaseVertex()"; 852 853 break; 854 } 855 856 break; 857 } 858 859 case FUNCTION_GL_DRAW_ELEMENTS_INSTANCED_BASE_VERTEX: 860 { 861 if (glu::isContextTypeES(m_context.getRenderContext().getType())) 862 { 863 result = "glDrawElementsInstancedBaseVertexEXT()"; 864 865 break; 866 } 867 else 868 { 869 result = "glDrawElementsInstancedBaseVertex()"; 870 871 break; 872 } 873 874 break; 875 } 876 877 case FUNCTION_GL_DRAW_RANGE_ELEMENTS_BASE_VERTEX: 878 { 879 if (glu::isContextTypeES(m_context.getRenderContext().getType())) 880 { 881 result = "glDrawRangeElementsBaseVertexEXT()"; 882 883 break; 884 } 885 else 886 { 887 result = "glDrawRangeElementsBaseVertex()"; 888 889 break; 890 } 891 892 break; 893 } 894 895 case FUNCTION_GL_MULTI_DRAW_ELEMENTS_BASE_VERTEX: 896 { 897 if (glu::isContextTypeES(m_context.getRenderContext().getType())) 898 { 899 result = "glMultiDrawElementsBaseVertexEXT()"; 900 901 break; 902 } 903 else 904 { 905 result = "glMultiDrawElementsBaseVertex()"; 906 907 break; 908 } 909 910 break; 911 } 912 913 default: 914 { 915 TCU_FAIL("Unknown function type"); 916 917 break; 918 } 919 } /* switch (function_type) */ 920 921 return result; 922} 923 924/** Initializes extension-specific function pointers and caches information about 925 * extension availability. 926 * 927 * Function pointers for the following extensions are retrieved & stored: 928 * 929 * - GL_EXT_draw_elements_base_vertex (ES) or GL_ARB_draw_elements_base_vertex (GL) 930 * - GL_EXT_multi_draw_arrays (ES & GL) 931 * 932 * Availability of the following extensions is checked & cached: 933 * 934 * - GL_EXT_draw_elements_base_vertex (ES) or GL_ARB_draw_elements_base_vertex (GL) 935 * - GL_EXT_geometry_shader (ES) or GL_ARB_geometry_shader4 (GL) 936 * - GL_EXT_multi_draw_arrays (ES & GL) 937 * - GL_EXT_tessellation_shader (ES) or GL_ARB_tessellation_shader (GL) 938 */ 939void DrawElementsBaseVertexTestBase::init() 940{ 941 TestCaseBase::init(); 942 943 const glu::ContextInfo& context_info = m_context.getContextInfo(); 944 945 if ((glu::isContextTypeES(m_context.getRenderContext().getType()) && 946 (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) || 947 context_info.isExtensionSupported("GL_EXT_draw_elements_base_vertex"))) || 948 context_info.isExtensionSupported("GL_ARB_draw_elements_base_vertex")) 949 { 950#if defined(DE_DEBUG) && !defined(DE_COVERAGE_BUILD) 951 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 952#endif 953 954 m_is_draw_elements_base_vertex_supported = true; 955 956 DE_ASSERT(gl.drawElementsBaseVertex != NULL); 957 DE_ASSERT(gl.drawElementsInstancedBaseVertex != NULL); 958 DE_ASSERT(gl.drawRangeElementsBaseVertex != NULL); 959 960 /* NOTE: glMultiDrawElementsBaseVertex() is a part of the draw_elements_base_vertex extension in GL, 961 * but requires a separate extension under ES. 962 */ 963 if (!glu::isContextTypeES(m_context.getRenderContext().getType()) || 964 context_info.isExtensionSupported("GL_EXT_multi_draw_arrays")) 965 { 966 m_is_ext_multi_draw_arrays_supported = true; 967 968 DE_ASSERT(gl.multiDrawElementsBaseVertex != NULL); 969 } /* if (GL_EXT_multi_draw_arrays is supported or GL context is being tested) */ 970 971 if (glu::isContextTypeES(m_context.getRenderContext().getType())) 972 { 973 /* This conformance test needs to be adjusted in order to run under < ES3.1 contexts */ 974 DE_ASSERT(glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 1))); 975 } 976 else 977 { 978 m_is_vertex_attrib_binding_supported = context_info.isExtensionSupported("GL_ARB_vertex_attrib_binding"); 979 } 980 } /* if (GL_{ARB, EXT}_draw_elements_base_vertex is supported) */ 981 982 if ((glu::isContextTypeES(m_context.getRenderContext().getType()) && 983 (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) || 984 context_info.isExtensionSupported("GL_EXT_geometry_shader"))) || 985 context_info.isExtensionSupported("GL_ARB_geometry_shader4")) 986 { 987 m_is_geometry_shader_supported = true; 988 } 989 990 if ((glu::isContextTypeES(m_context.getRenderContext().getType()) && 991 (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) || 992 context_info.isExtensionSupported("GL_EXT_tessellation_shader"))) || 993 context_info.isExtensionSupported("GL_ARB_tessellation_shader")) 994 { 995 m_is_tessellation_shader_supported = true; 996 } 997 998 if (!m_is_draw_elements_base_vertex_supported) 999 { 1000 throw tcu::NotSupportedError("draw_elements_base_vertex functionality is not supported"); 1001 } 1002} 1003 1004/** Sets up all ES objects required to run a single functional test case iteration. 1005 * 1006 * @param use_clientside_vertex_data true if the test case requires client-side buffers to 1007 * back the color/vertex vertex attribute arrays; false 1008 * to use buffer object storage. 1009 * @param use_clientside_index_data true if the test case requires client-side buffers to 1010 * be used as index data source; false to use buffer object 1011 * storage. 1012 * @param use_tessellation_shader_stage true if the program object used for the test should include 1013 * tessellation control & evaluation shader stages; false to 1014 * not to include these shader stages in the pipeline. 1015 * @param use_geometry_shader_stage true if the program object used for the test should include 1016 * geometry shader stage; false to not to include the shader 1017 * stage in the pipeline. 1018 * @param use_vertex_attrib_binding true if vertex attribute bindings should be used for 1019 * vertex array object configuration. This also modifies the 1020 * vertex shader, so that instead of calculating vertex color 1021 * on a per-vertex basis, contents of the "color" input 1022 * will be used as a data source for the color data. 1023 * false to use a vertex attribute array configured with 1024 * a casual glVertexAttribPointer() call. 1025 * @param use_overflow_test_vertices true if using an especially large vertex array to test 1026 * overflow behavior. 1027 * 1028 * This method can throw an exception if any of the ES calls fail. 1029 **/ 1030void DrawElementsBaseVertexTestBase::setUpFunctionalTestObjects( 1031 bool use_clientside_vertex_data, bool use_clientside_index_data, bool use_tessellation_shader_stage, 1032 bool use_geometry_shader_stage, bool use_vertex_attrib_binding, bool use_overflow_test_vertices) 1033{ 1034 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1035 1036 /* Set up a texture object that we will use as a color attachment */ 1037 gl.genTextures(1, &m_to_base_id); 1038 gl.genTextures(1, &m_to_ref_id); 1039 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call(s) failed."); 1040 1041 const glw::GLuint to_ids[] = { m_to_base_id, m_to_ref_id }; 1042 const unsigned int n_to_ids = sizeof(to_ids) / sizeof(to_ids[0]); 1043 1044 for (unsigned int n_to_id = 0; n_to_id < n_to_ids; ++n_to_id) 1045 { 1046 gl.bindTexture(GL_TEXTURE_2D, to_ids[n_to_id]); 1047 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed."); 1048 1049 gl.texStorage2D(GL_TEXTURE_2D, 1, /* levels */ 1050 GL_RGBA8, m_to_width, m_to_height); 1051 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed."); 1052 } 1053 1054 /* Also set up some buffers we will use for data comparison */ 1055 m_to_base_data = new unsigned char[m_to_width * m_to_height * 4 /* components */]; 1056 m_to_ref_data = new unsigned char[m_to_width * m_to_height * 4 /* components */]; 1057 1058 /* Finally, for glReadPixels() operations, we need to make sure that pack alignment is set to 1 */ 1059 gl.pixelStorei(GL_PACK_ALIGNMENT, 1); 1060 GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei() call failed."); 1061 1062 /* Proceed with framebuffer object initialization. Since we will be rendering to different 1063 * render-targets, there's not much point in attaching any of the textures at this point. 1064 */ 1065 gl.genFramebuffers(1, &m_fbo_id); 1066 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed."); 1067 1068 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id); 1069 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebufer() call failed"); 1070 1071 gl.viewport(0, /* x */ 1072 0, /* y */ 1073 m_to_width, m_to_height); 1074 GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() call failed"); 1075 1076 /* Set up buffer object we will use for the draw calls. Use the data 1077 * from the test specification. 1078 * 1079 * NOTE: If you need to change the data layout here, make sure you also update 1080 * m_draw_call_color_offset, m_draw_call_index*_offset, and 1081 * m_draw_call_vertex*_offset setter calls elsewhere. 1082 **/ 1083 if (m_bo_id == 0) 1084 { 1085 unsigned int current_offset = 0; 1086 1087 gl.genBuffers(1, &m_bo_id); 1088 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed."); 1089 1090 gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id); 1091 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed."); 1092 1093 gl.bufferData(GL_ARRAY_BUFFER, 1094 m_bo_functional_data_index_size + m_bo_functional_data_vertex_size + 1095 m_bo_functional2_data_vertex_size + m_bo_functional2_data_index_size + 1096 m_bo_functional3_data_index_size + m_bo_functional4_data_index_size + 1097 m_bo_functional5_data_index_size + m_bo_functional_data_color_size, 1098 DE_NULL, /* data */ 1099 GL_STATIC_DRAW); 1100 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed."); 1101 1102 gl.bufferSubData(GL_ARRAY_BUFFER, current_offset, m_bo_functional_data_vertex_size, 1103 m_bo_functional_data_vertex); 1104 current_offset += m_bo_functional_data_vertex_size; 1105 1106 gl.bufferSubData(GL_ARRAY_BUFFER, current_offset, m_bo_functional2_data_vertex_size, 1107 m_bo_functional2_data_vertex); 1108 current_offset += m_bo_functional2_data_vertex_size; 1109 1110 gl.bufferSubData(GL_ARRAY_BUFFER, current_offset, m_bo_functional_data_index_size, m_bo_functional_data_index); 1111 current_offset += m_bo_functional_data_index_size; 1112 1113 gl.bufferSubData(GL_ARRAY_BUFFER, current_offset, m_bo_functional2_data_index_size, 1114 m_bo_functional2_data_index); 1115 current_offset += m_bo_functional2_data_index_size; 1116 1117 gl.bufferSubData(GL_ARRAY_BUFFER, current_offset, m_bo_functional3_data_index_size, 1118 m_bo_functional3_data_index); 1119 current_offset += m_bo_functional3_data_index_size; 1120 1121 gl.bufferSubData(GL_ARRAY_BUFFER, current_offset, m_bo_functional4_data_index_size, 1122 m_bo_functional4_data_index); 1123 current_offset += m_bo_functional4_data_index_size; 1124 1125 gl.bufferSubData(GL_ARRAY_BUFFER, current_offset, m_bo_functional5_data_index_size, 1126 m_bo_functional5_data_index); 1127 current_offset += m_bo_functional5_data_index_size; 1128 1129 gl.bufferSubData(GL_ARRAY_BUFFER, current_offset, m_bo_functional_data_color_size, m_bo_functional_data_color); 1130 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferSubData() call(s) failed."); 1131 } 1132 1133 if (use_overflow_test_vertices && m_bo_id_2 == 0) 1134 { 1135 /* Create a special buffer that only has vertex data in a few slots */ 1136 gl.genBuffers(1, &m_bo_id_2); 1137 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed"); 1138 1139 gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id_2); 1140 gl.bufferData(GL_ARRAY_BUFFER, 2 * 65550 * sizeof(glw::GLfloat), NULL, GL_STATIC_DRAW); 1141 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed"); 1142 1143 /* 1144 * Upload to offset 0: regular draw call indices for making sure ubyte 1145 * and ushort indices don't wrap around too early 1146 * Upload to offset 256: base draw call indices of type ubyte 1147 * Upload to offset 65536: base draw call indices of type ushort 1148 */ 1149 glw::GLfloat badVtx[] = { 0.9f, 0.9f, -0.9f, 0.9f, -0.9f, -0.9f, 0.9f, -0.9f, 0.9f, 0.9f, -0.9f, 0.9f, 1150 -0.9f, -0.9f, 0.9f, -0.9f, 0.9f, 0.9f, -0.9f, 0.9f, -0.9f, -0.9f, 0.9f, -0.9f }; 1151 gl.bufferSubData(GL_ARRAY_BUFFER, 0, sizeof(badVtx), badVtx); 1152 gl.bufferSubData(GL_ARRAY_BUFFER, 2 * 256 * sizeof(glw::GLfloat), 2 * 12 * sizeof(glw::GLfloat), 1153 m_bo_functional_data_vertex); 1154 gl.bufferSubData(GL_ARRAY_BUFFER, 2 * 65536 * sizeof(glw::GLfloat), 2 * 12 * sizeof(glw::GLfloat), 1155 m_bo_functional_data_vertex); 1156 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferSubData() call failed"); 1157 } 1158 1159 /* Set up the test program object */ 1160 if (m_po_id == 0 || m_po_uses_gs_stage != use_geometry_shader_stage || 1161 m_po_uses_tc_te_stages != use_tessellation_shader_stage || 1162 m_po_uses_vertex_attrib_binding != use_vertex_attrib_binding) 1163 1164 { 1165 static const char* functional_fs_code = "${VERSION}\n" 1166 "\n" 1167 "precision highp float;\n" 1168 "\n" 1169 "in vec4 FS_COLOR_INPUT_NAME;\n" 1170 "out vec4 result;\n" 1171 "\n" 1172 "void main()\n" 1173 "{\n" 1174 " result = FS_COLOR_INPUT_NAME;\n" 1175 "}\n"; 1176 static const char* functional_gs_code = "${VERSION}\n" 1177 "${GEOMETRY_SHADER_REQUIRE}\n" 1178 "\n" 1179 "layout(triangles) in;\n" 1180 "layout(triangle_strip, max_vertices = 3) out;\n" 1181 "\n" 1182 "in vec4 GS_COLOR_INPUT_NAME[];\n" 1183 "out vec4 FS_COLOR_INPUT_NAME;\n" 1184 "\n" 1185 "void main()\n" 1186 "{\n" 1187 " for (int n = 0; n < 3; ++n)\n" 1188 " {\n" 1189 " gl_Position = vec4(gl_in[n].gl_Position.x, " 1190 "-gl_in[n].gl_Position.y, gl_in[n].gl_Position.zw);\n" 1191 " FS_COLOR_INPUT_NAME = GS_COLOR_INPUT_NAME[n];\n" 1192 "\n" 1193 " EmitVertex();\n" 1194 " }\n" 1195 "\n" 1196 " EndPrimitive();\n" 1197 "}\n"; 1198 static const char* functional_tc_code = 1199 "${VERSION}\n" 1200 "${TESSELLATION_SHADER_REQUIRE}\n" 1201 "\n" 1202 "in vec4 TC_COLOR_INPUT_NAME[];\n" 1203 "out vec4 TE_COLOR_INPUT_NAME[];\n" 1204 "\n" 1205 "layout(vertices = 3) out;\n" 1206 "\n" 1207 "void main()\n" 1208 "{\n" 1209 " gl_out [gl_InvocationID].gl_Position = gl_in [gl_InvocationID].gl_Position;\n" 1210 " TE_COLOR_INPUT_NAME[gl_InvocationID] = TC_COLOR_INPUT_NAME[gl_InvocationID];\n" 1211 "\n" 1212 " gl_TessLevelInner[0] = 3.0;\n" 1213 " gl_TessLevelOuter[0] = 3.0;\n" 1214 " gl_TessLevelOuter[1] = 3.0;\n" 1215 " gl_TessLevelOuter[2] = 3.0;\n" 1216 "}\n"; 1217 static const char* functional_te_code = 1218 "${VERSION}\n" 1219 "\n" 1220 "${TESSELLATION_SHADER_REQUIRE}\n" 1221 "\n" 1222 "layout(triangles, equal_spacing, cw) in;\n" 1223 "\n" 1224 "in vec4 TE_COLOR_INPUT_NAME[];\n" 1225 "out vec4 TE_COLOR_OUTPUT_NAME;\n" 1226 "\n" 1227 "void main()\n" 1228 "{\n" 1229 " vec2 p1 = gl_in[0].gl_Position.xy;\n" 1230 " vec2 p2 = gl_in[1].gl_Position.xy;\n" 1231 " vec2 p3 = gl_in[2].gl_Position.xy;\n" 1232 "\n" 1233 " TE_COLOR_OUTPUT_NAME = TE_COLOR_INPUT_NAME[0] + TE_COLOR_INPUT_NAME[1] + TE_COLOR_INPUT_NAME[2];\n" 1234 " gl_Position = vec4(gl_TessCoord.x * p1.x + gl_TessCoord.y * p2.x + gl_TessCoord.z * p3.x,\n" 1235 " gl_TessCoord.x * p1.y + gl_TessCoord.y * p2.y + gl_TessCoord.z * p3.y,\n" 1236 " 0.0,\n" 1237 " 1.0);\n" 1238 "}\n"; 1239 static const char* functional_vs_code = "${VERSION}\n" 1240 "\n" 1241 "out vec4 VS_COLOR_OUTPUT_NAME;\n" 1242 "in vec4 vertex;\n" 1243 "\n" 1244 "OPTIONAL_USE_VERTEX_ATTRIB_BINDING_DEFINITIONS\n" 1245 "\n" 1246 "void main()\n" 1247 "{\n" 1248 " float vertex_id_float = float(gl_VertexID);\n" 1249 "\n" 1250 "#ifdef USE_VERTEX_ATTRIB_BINDING\n" 1251 " vec4 color = in_color;\n" 1252 "#else\n" 1253 " vec4 color = vec4(vertex_id_float / 7.0,\n" 1254 " vertex_id_float / 3.0,\n" 1255 " vertex_id_float / 17.0,\n" 1256 " 1.0);\n" 1257 "#endif\n" 1258 " float scale = (gl_InstanceID == 0) ? 1.0 :\n" 1259 " (gl_InstanceID == 1) ? 0.8 :\n" 1260 " 0.5;\n" 1261 "\n" 1262 " VS_COLOR_OUTPUT_NAME = color;\n" 1263 " gl_Position = vec4(vertex.xy * scale, vertex.zw);\n" 1264 "}\n"; 1265 1266 /* Release a program object if one has already been set up for the running test */ 1267 deinitProgramAndShaderObjects(); 1268 1269 /* Replace the tokens with actual variable names */ 1270 std::string fs_body = specializeShader(1, &functional_fs_code); 1271 std::string fs_color_input_name_token = "FS_COLOR_INPUT_NAME"; 1272 std::string fs_color_input_name_token_value; 1273 std::string gs_body = specializeShader(1, &functional_gs_code); 1274 std::string gs_color_input_name_token = "GS_COLOR_INPUT_NAME"; 1275 std::string gs_color_input_name_token_value; 1276 std::string tc_body = specializeShader(1, &functional_tc_code); 1277 std::string tc_color_input_name_token = "TC_COLOR_INPUT_NAME"; 1278 std::string tc_color_input_name_token_value; 1279 std::string te_body = specializeShader(1, &functional_te_code); 1280 std::string te_color_input_name_token = "TE_COLOR_INPUT_NAME"; 1281 std::string te_color_input_name_token_value; 1282 std::string te_color_output_name_token = "TE_COLOR_OUTPUT_NAME"; 1283 std::string te_color_output_name_token_value; 1284 std::string vs_body = specializeShader(1, &functional_vs_code); 1285 std::string vs_color_output_name_token = "VS_COLOR_OUTPUT_NAME"; 1286 std::string vs_color_output_name_token_value; 1287 std::string vs_optional_use_vertex_attrib_binding_definitions_token = 1288 "OPTIONAL_USE_VERTEX_ATTRIB_BINDING_DEFINITIONS"; 1289 std::string vs_optional_use_vertex_attrib_binding_definitions_token_value; 1290 1291 std::string* bodies[] = { &fs_body, &gs_body, &tc_body, &te_body, &vs_body }; 1292 const unsigned int n_bodies = sizeof(bodies) / sizeof(bodies[0]); 1293 1294 std::string* token_value_pairs[] = { &fs_color_input_name_token, 1295 &fs_color_input_name_token_value, 1296 &gs_color_input_name_token, 1297 &gs_color_input_name_token_value, 1298 &tc_color_input_name_token, 1299 &tc_color_input_name_token_value, 1300 &te_color_input_name_token, 1301 &te_color_input_name_token_value, 1302 &te_color_output_name_token, 1303 &te_color_output_name_token_value, 1304 &vs_color_output_name_token, 1305 &vs_color_output_name_token_value, 1306 &vs_optional_use_vertex_attrib_binding_definitions_token, 1307 &vs_optional_use_vertex_attrib_binding_definitions_token_value }; 1308 const unsigned int n_token_value_pairs = 1309 sizeof(token_value_pairs) / sizeof(token_value_pairs[0]) / 2 /* token+value */; 1310 1311 if (!use_tessellation_shader_stage) 1312 { 1313 if (!use_geometry_shader_stage) 1314 { 1315 /* Geometry & tessellation shader stages are not required. 1316 * 1317 * NOTE: This code-path is also used by Functional Test VII which verifies that 1318 * vertex attribute bindings work correctly with basevertex draw calls. 1319 * The test only uses FS & VS in its rendering pipeline and consumes a color 1320 * taken from an enabled vertex attribute array instead of a vector value 1321 * calculated in vertex shader stage, 1322 */ 1323 vs_color_output_name_token_value = "out_vs_color"; 1324 fs_color_input_name_token_value = vs_color_output_name_token_value; 1325 1326 if (use_vertex_attrib_binding) 1327 { 1328 vs_optional_use_vertex_attrib_binding_definitions_token_value = 1329 "#define USE_VERTEX_ATTRIB_BINDING\n" 1330 "in vec4 in_color;\n"; 1331 } 1332 } /* if (!use_geometry_shader_stage) */ 1333 else 1334 { 1335 /* Geometry shader stage is needed, but tessellation shader stage 1336 * can be skipped */ 1337 fs_color_input_name_token_value = "out_fs_color"; 1338 gs_color_input_name_token_value = "out_vs_color"; 1339 vs_color_output_name_token_value = "out_vs_color"; 1340 1341 DE_ASSERT(!use_vertex_attrib_binding); 1342 } 1343 } /* if (!use_tessellation_shader_stage) */ 1344 else 1345 { 1346 DE_ASSERT(!use_vertex_attrib_binding); 1347 1348 if (!use_geometry_shader_stage) 1349 { 1350 /* Tessellation shader stage is needed, but geometry shader stage 1351 * can be skipped */ 1352 fs_color_input_name_token_value = "out_fs_color"; 1353 tc_color_input_name_token_value = "out_vs_color"; 1354 te_color_input_name_token_value = "out_tc_color"; 1355 te_color_output_name_token_value = "out_fs_color"; 1356 vs_color_output_name_token_value = "out_vs_color"; 1357 } /* if (!use_geometry_shader_stage) */ 1358 else 1359 { 1360 /* Both tessellation and geometry shader stages are needed */ 1361 fs_color_input_name_token_value = "out_fs_color"; 1362 gs_color_input_name_token_value = "out_te_color"; 1363 tc_color_input_name_token_value = "out_vs_color"; 1364 te_color_input_name_token_value = "out_tc_color"; 1365 te_color_output_name_token_value = "out_te_color"; 1366 vs_color_output_name_token_value = "out_vs_color"; 1367 } 1368 } 1369 1370 for (unsigned int n_body = 0; n_body < n_bodies; ++n_body) 1371 { 1372 std::string* body_ptr = bodies[n_body]; 1373 1374 for (unsigned int n_token_value_pair = 0; n_token_value_pair < n_token_value_pairs; ++n_token_value_pair) 1375 { 1376 std::string token = *token_value_pairs[2 * n_token_value_pair + 0]; 1377 std::size_t token_location = std::string::npos; 1378 std::string value = *token_value_pairs[2 * n_token_value_pair + 1]; 1379 1380 while ((token_location = body_ptr->find(token)) != std::string::npos) 1381 { 1382 body_ptr->replace(token_location, token.length(), value); 1383 } /* while (tokens are found) */ 1384 } /* for (all token+value pairs) */ 1385 } /* for (all bodies) */ 1386 1387 /* Build the actual program */ 1388 buildProgram(fs_body.c_str(), vs_body.c_str(), use_tessellation_shader_stage ? tc_body.c_str() : DE_NULL, 1389 use_tessellation_shader_stage ? te_body.c_str() : DE_NULL, 1390 use_geometry_shader_stage ? gs_body.c_str() : DE_NULL); 1391 1392 m_po_uses_gs_stage = use_geometry_shader_stage; 1393 m_po_uses_tc_te_stages = use_tessellation_shader_stage; 1394 m_po_uses_vertex_attrib_binding = use_vertex_attrib_binding; 1395 } 1396 1397 /* Set up the vertex array object */ 1398 if (m_vao_id != 0) 1399 { 1400 gl.deleteVertexArrays(1, &m_vao_id); 1401 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteVertexArrays() call failed."); 1402 1403 m_vao_id = 0; 1404 } 1405 1406 if (!use_clientside_vertex_data) 1407 { 1408 gl.genVertexArrays(1, &m_vao_id); 1409 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed."); 1410 } 1411 gl.bindVertexArray(m_vao_id); 1412 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed."); 1413 1414 if (m_po_color_attribute_location != -1) 1415 { 1416 DE_ASSERT(use_vertex_attrib_binding); 1417 1418 gl.enableVertexAttribArray(m_po_color_attribute_location); 1419 } 1420 1421 gl.enableVertexAttribArray(m_po_vertex_attribute_location); 1422 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray() call(s) failed."); 1423 1424 /* Configure the VAO */ 1425 if (use_clientside_index_data) 1426 { 1427 gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 1428 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed."); 1429 } 1430 else 1431 { 1432 gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_bo_id); 1433 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed."); 1434 } 1435 1436 if (use_clientside_vertex_data) 1437 { 1438 gl.bindBuffer(GL_ARRAY_BUFFER, 0); 1439 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed."); 1440 } 1441 else 1442 { 1443 gl.bindBuffer(GL_ARRAY_BUFFER, use_overflow_test_vertices ? m_bo_id_2 : m_bo_id); 1444 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed."); 1445 } 1446 1447 if (!use_vertex_attrib_binding) 1448 { 1449 DE_ASSERT(m_po_color_attribute_location == -1); 1450 1451 gl.vertexAttribPointer(m_po_vertex_attribute_location, 2, /* size */ 1452 GL_FLOAT, GL_FALSE, /* normalized */ 1453 0, /* stride */ 1454 m_draw_call_vertex_offset); 1455 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer() call failed."); 1456 } /* if (!use_vertex_attrib_binding) */ 1457 else 1458 { 1459 DE_ASSERT(m_po_color_attribute_location != -1); 1460 DE_ASSERT(m_draw_call_vertex_offset < m_draw_call_color_offset); 1461 1462 gl.vertexAttribFormat(m_po_color_attribute_location, 2, /* size */ 1463 GL_FLOAT, /* type */ 1464 GL_FALSE, /* normalized */ 1465 (glw::GLuint)((const glw::GLubyte*)m_draw_call_color_offset - 1466 (const glw::GLubyte*)m_draw_call_vertex_offset)); 1467 gl.vertexAttribFormat(m_po_vertex_attribute_location, 2, /* size */ 1468 GL_FLOAT, /* type */ 1469 GL_FALSE, /* normalized */ 1470 0); /* relativeoffset */ 1471 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribFormat() call(s) failed."); 1472 1473 gl.vertexAttribBinding(m_po_color_attribute_location, 0); /* bindingindex */ 1474 gl.vertexAttribBinding(m_po_vertex_attribute_location, 0); /* bindingindex */ 1475 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribBinding() call(s) failed."); 1476 1477 gl.bindVertexBuffer(0, /* bindingindex */ 1478 (use_clientside_vertex_data) ? 0 : (use_overflow_test_vertices ? m_bo_id_2 : m_bo_id), 1479 (glw::GLintptr)m_draw_call_vertex_offset, sizeof(float) * 2); 1480 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexBuffer() call failed."); 1481 } 1482 1483 /* Bind the program object to the rendering context */ 1484 gl.useProgram(m_po_id); 1485 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed."); 1486} 1487 1488/** Sets up all ES objects required to run a single negative test case iteration. 1489 * 1490 * @param use_clientside_vertex_data true if the test case requires client-side buffers to 1491 * back the color/vertex vertex attribute arrays; false 1492 * to use buffer object storage. 1493 * @param use_clientside_index_data true if the test case requires client-side buffers to 1494 * be used as index data source; false to use buffer object 1495 * storage. 1496 */ 1497void DrawElementsBaseVertexTestBase::setUpNegativeTestObjects(bool use_clientside_vertex_data, 1498 bool use_clientside_index_data) 1499{ 1500 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1501 1502 /* Set up buffer object we will use for the draw calls. Use the data 1503 * from the test specification */ 1504 if (m_bo_id == 0) 1505 { 1506 gl.genBuffers(1, &m_bo_id); 1507 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed."); 1508 1509 gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id); 1510 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed."); 1511 1512 gl.bufferData(GL_ARRAY_BUFFER, m_bo_negative_data_index_size + m_bo_negative_data_vertex_size, 1513 DE_NULL, /* data */ 1514 GL_STATIC_DRAW); 1515 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed."); 1516 1517 gl.bufferSubData(GL_ARRAY_BUFFER, 0, /* offset */ 1518 m_bo_negative_data_vertex_size, m_bo_negative_data_vertex); 1519 gl.bufferSubData(GL_ARRAY_BUFFER, m_bo_negative_data_vertex_size, /* offset */ 1520 m_bo_negative_data_index_size, m_bo_negative_data_index); 1521 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferSubData() call(s) failed."); 1522 } 1523 1524 if (use_clientside_index_data) 1525 { 1526 m_draw_call_index_offset = m_bo_negative_data_index; 1527 } 1528 else 1529 { 1530 m_draw_call_index_offset = (const glw::GLuint*)(deUintptr)m_bo_negative_data_vertex_size; 1531 } 1532 1533 if (use_clientside_vertex_data) 1534 { 1535 m_draw_call_vertex_offset = m_bo_negative_data_vertex; 1536 } 1537 else 1538 { 1539 m_draw_call_vertex_offset = DE_NULL; 1540 } 1541 1542 /* Set up the test program object */ 1543 if (m_po_id == 0) 1544 { 1545 static const char* negative_fs_code = "${VERSION}\n" 1546 "precision highp float;\n" 1547 "\n" 1548 "out vec4 result;\n" 1549 "\n" 1550 "void main()\n" 1551 "{\n" 1552 " result = vec4(1.0);\n" 1553 "}\n"; 1554 static const char* negative_vs_code = "${VERSION}\n" 1555 "\n" 1556 "in vec4 vertex;\n" 1557 "\n" 1558 "void main()\n" 1559 "{\n" 1560 " gl_Position = vertex;\n" 1561 "}\n"; 1562 1563 std::string fs_specialized_code = specializeShader(1, &negative_fs_code); 1564 const char* fs_specialized_code_raw = fs_specialized_code.c_str(); 1565 std::string vs_specialized_code = specializeShader(1, &negative_vs_code); 1566 const char* vs_specialized_code_raw = vs_specialized_code.c_str(); 1567 1568 buildProgram(fs_specialized_code_raw, vs_specialized_code_raw, DE_NULL, /* tc_code */ 1569 DE_NULL, /* te_code */ 1570 DE_NULL); /* gs_code */ 1571 } 1572 1573 /* Set up a vertex array object */ 1574 if (m_vao_id == 0) 1575 { 1576 gl.genVertexArrays(1, &m_vao_id); 1577 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed."); 1578 1579 gl.bindVertexArray(m_vao_id); 1580 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed."); 1581 1582 gl.enableVertexAttribArray(m_po_vertex_attribute_location); 1583 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray() call failed."); 1584 } 1585 1586 /* Configure the VAO */ 1587 if (use_clientside_index_data) 1588 { 1589 gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 1590 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed."); 1591 } 1592 else 1593 { 1594 gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_bo_id); 1595 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed."); 1596 } 1597 1598 if (use_clientside_vertex_data) 1599 { 1600 gl.bindBuffer(GL_ARRAY_BUFFER, 0); 1601 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed."); 1602 1603 gl.bindVertexArray(0); 1604 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed."); 1605 } 1606 else 1607 { 1608 gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id); 1609 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed."); 1610 } 1611 1612 gl.vertexAttribPointer(m_po_vertex_attribute_location, 2, /* size */ 1613 GL_FLOAT, GL_FALSE, /* normalized */ 1614 0, /* stride */ 1615 m_draw_call_vertex_offset); 1616 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer() call failed."); 1617 1618 /* Bind the program object to the rendering context */ 1619 gl.useProgram(m_po_id); 1620 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed."); 1621} 1622 1623/** Constructor. 1624 * 1625 * @param context Rendering context handle. 1626 **/ 1627DrawElementsBaseVertexFunctionalCorrectBaseVertexBehavior::DrawElementsBaseVertexFunctionalCorrectBaseVertexBehavior( 1628 Context& context, const ExtParameters& extParams) 1629 : DrawElementsBaseVertexTestBase(context, extParams, "basevertex_behavior1", 1630 "Verifies basevertex draw calls work correctly for a number of " 1631 "different rendering pipeline and VAO configurations") 1632{ 1633 /* Left blank on purpose */ 1634} 1635 1636/** Sets up test case descriptors for the test instance. These will later be used 1637 * as input for DrawElementsBaseVertexTestBase::executeTestCases(), which performs 1638 * the actual testing. 1639 **/ 1640void DrawElementsBaseVertexFunctionalCorrectBaseVertexBehavior::setUpTestCases() 1641{ 1642 /* Set up test case descriptors */ 1643 const glw::GLint basevertex_values[] = { 10, 0 }; 1644 const unsigned int n_basevertex_values = sizeof(basevertex_values) / sizeof(basevertex_values[0]); 1645 1646 /* The test needs to be run in two iterations, using client-side memory and buffer object 1647 * for index data respectively 1648 */ 1649 for (int vao_iteration = 0; vao_iteration < 2; ++vao_iteration) 1650 { 1651 /* Skip client-side vertex array as gl_VertexID is undefined when no buffer bound to ARRAY_BUFFER 1652 * See section 11.1.3.9 in OpenGL ES 3.1 spec 1653 */ 1654 bool use_clientside_vertex_data = 0; 1655 bool use_clientside_index_data = ((vao_iteration & (1 << 0)) != 0); 1656 1657 /* OpenGL does not support client-side data. */ 1658 if (!glu::isContextTypeES(m_context.getRenderContext().getType())) 1659 { 1660 if (use_clientside_index_data || use_clientside_vertex_data) 1661 { 1662 continue; 1663 } 1664 } 1665 1666 /* Compute the offsets */ 1667 computeVBODataOffsets(use_clientside_index_data, use_clientside_vertex_data); 1668 1669 /* There are two index data sets we need to iterate over */ 1670 const glw::GLuint* index_offsets[] = { m_draw_call_index_offset, m_draw_call_index2_offset }; 1671 const unsigned int n_index_offsets = sizeof(index_offsets) / sizeof(index_offsets[0]); 1672 1673 for (unsigned int n_index_offset = 0; n_index_offset < n_index_offsets; ++n_index_offset) 1674 { 1675 const glw::GLuint* current_index_offset = index_offsets[n_index_offset]; 1676 1677 /* We need to test four different functions: 1678 * 1679 * a) glDrawElementsBaseVertex() (GL) 1680 * or glDrawElementsBaseVertexEXT() (ES) 1681 * b) glDrawRangeElementsBaseVertex() (GL) 1682 * or glDrawRangeElementsBaseVertexEXT() (ES) 1683 * c) glDrawElementsInstancedBaseVertex() (GL) 1684 * or glDrawElementsInstancedBaseVertexEXT() (ES) 1685 * d) glMultiDrawElementsBaseVertex() (GL) 1686 * or glMultiDrawElementsBaseVertexEXT() (ES) (if supported) 1687 **/ 1688 for (int n_function = 0; n_function < FUNCTION_COUNT; ++n_function) 1689 { 1690 /* Do not try to use the multi draw call if relevant extension is 1691 * not supported. */ 1692 if (!m_is_ext_multi_draw_arrays_supported && n_function == FUNCTION_GL_MULTI_DRAW_ELEMENTS_BASE_VERTEX) 1693 { 1694 continue; 1695 } 1696 1697 /* We need to run the test for a number of different basevertex values. */ 1698 for (unsigned int n_basevertex_value = 0; n_basevertex_value < n_basevertex_values; 1699 ++n_basevertex_value) 1700 { 1701 /* Finally, we want to verify that basevertex draw calls work correctly both when vertex attribute 1702 * bindings are enabled and disabled */ 1703 bool vertex_attrib_binding_statuses[] = { false, true }; 1704 unsigned int n_vertex_attrib_binding_statuses = 1705 sizeof(vertex_attrib_binding_statuses) / sizeof(vertex_attrib_binding_statuses[0]); 1706 1707 for (unsigned int n_vertex_attrib_binding_status = 0; 1708 n_vertex_attrib_binding_status < n_vertex_attrib_binding_statuses; 1709 ++n_vertex_attrib_binding_status) 1710 { 1711 bool use_vertex_attrib_binding = vertex_attrib_binding_statuses[n_vertex_attrib_binding_status]; 1712 1713 /* Under GL, "vertex attrib binding" functionality is only available if GL_ARB_vertex_attrib_binding 1714 * extension is supported. 1715 */ 1716 if (!m_is_vertex_attrib_binding_supported && use_vertex_attrib_binding) 1717 { 1718 continue; 1719 } 1720 1721 /* Prepare a few arrays so that we can handle the multi draw call and its emulated version.. */ 1722 const glw::GLsizei multi_draw_call_count_array[3] = { 3, 6, 3 }; 1723 const glw::GLuint* multi_draw_call_indices_array[3] = { 1724 (glw::GLuint*)(current_index_offset), (glw::GLuint*)(current_index_offset + 3), 1725 (glw::GLuint*)(current_index_offset + 9) 1726 }; 1727 1728 /* Reference texture should always reflect basevertex=10 behavior. */ 1729 const glw::GLuint regular_draw_call_offset = basevertex_values[0]; 1730 const glw::GLuint* regular_multi_draw_call_offseted_array[3] = { 1731 multi_draw_call_indices_array[0] + regular_draw_call_offset, 1732 multi_draw_call_indices_array[1] + regular_draw_call_offset, 1733 multi_draw_call_indices_array[2] + regular_draw_call_offset, 1734 }; 1735 1736 /* Construct the test case descriptor */ 1737 _test_case new_test_case; 1738 1739 new_test_case.basevertex = basevertex_values[n_basevertex_value]; 1740 new_test_case.function_type = (_function_type)n_function; 1741 new_test_case.index_offset = current_index_offset; 1742 new_test_case.range_start = n_index_offset == 0 ? 0 : 10; 1743 new_test_case.range_end = n_index_offset == 0 ? 22 : 32; 1744 new_test_case.index_type = GL_UNSIGNED_INT; 1745 new_test_case.primitive_mode = GL_TRIANGLES; 1746 new_test_case.regular_draw_call_offset = basevertex_values[0]; 1747 new_test_case.should_base_texture_match_reference_texture = 1748 ((glw::GLuint)new_test_case.basevertex == new_test_case.regular_draw_call_offset); 1749 new_test_case.use_clientside_index_data = use_clientside_index_data; 1750 new_test_case.use_clientside_vertex_data = use_clientside_vertex_data; 1751 new_test_case.use_geometry_shader_stage = false; 1752 new_test_case.use_tessellation_shader_stage = false; 1753 new_test_case.use_vertex_attrib_binding = use_vertex_attrib_binding; 1754 1755 memcpy(new_test_case.multi_draw_call_count_array, multi_draw_call_count_array, 1756 sizeof(multi_draw_call_count_array)); 1757 memcpy(new_test_case.multi_draw_call_indices_array, multi_draw_call_indices_array, 1758 sizeof(multi_draw_call_indices_array)); 1759 memcpy(new_test_case.regular_multi_draw_call_offseted_array, 1760 regular_multi_draw_call_offseted_array, sizeof(regular_multi_draw_call_offseted_array)); 1761 1762 m_test_cases.push_back(new_test_case); 1763 } /* for (all vertex_attrib_binding statuses) */ 1764 } /* for (all basevertex values) */ 1765 } /* for (all four functions) */ 1766 } /* for (all index data sets) */ 1767 } /* for (all VAO iterations) */ 1768} 1769 1770/** Executes test iteration. 1771 * 1772 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 1773 */ 1774tcu::TestNode::IterateResult DrawElementsBaseVertexFunctionalCorrectBaseVertexBehavior::iterate() 1775{ 1776 setUpTestCases(); 1777 executeTestCases(); 1778 1779 /* Test case passed */ 1780 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1781 1782 return STOP; 1783} 1784 1785/** Constructor. 1786 * 1787 * @param context Rendering context handle. 1788 **/ 1789DrawElementsBaseVertexFunctionalCorrectBaseVertexBehavior2::DrawElementsBaseVertexFunctionalCorrectBaseVertexBehavior2( 1790 Context& context, const ExtParameters& extParams) 1791 : DrawElementsBaseVertexTestBase(context, extParams, "basevertex_behavior2", 1792 "Verifies basevertex draw calls work correctly for a number of " 1793 "different rendering pipeline and VAO configurations. Uses slightly " 1794 "different data set than basevertex_behavior.") 1795{ 1796 /* Left blank on purpose */ 1797} 1798 1799/** Sets up test case descriptors for the test instance. These will later be used 1800 * as input for DrawElementsBaseVertexTestBase::executeTestCases(), which performs 1801 * the actual testing. 1802 **/ 1803void DrawElementsBaseVertexFunctionalCorrectBaseVertexBehavior2::setUpTestCases() 1804{ 1805 /* Set up test case descriptors */ 1806 const glw::GLint basevertex = 5; 1807 1808 /* The test needs to be run in two iterations, using client-side memory and buffer object 1809 * for index data respectively 1810 */ 1811 for (int vao_iteration = 0; vao_iteration < 2; ++vao_iteration) 1812 { 1813 /* Skip client-side vertex array as gl_VertexID is undefined when no buffer bound to ARRAY_BUFFER 1814 * See section 11.1.3.9 in OpenGL ES 3.1 spec 1815 */ 1816 bool use_clientside_vertex_data = 0; 1817 bool use_clientside_index_data = ((vao_iteration & (1 << 0)) != 0); 1818 1819 /* OpenGL does not support client-side data. */ 1820 if (!glu::isContextTypeES(m_context.getRenderContext().getType())) 1821 { 1822 if (use_clientside_index_data || use_clientside_vertex_data) 1823 { 1824 continue; 1825 } 1826 } 1827 1828 /* Compute the offsets */ 1829 computeVBODataOffsets(use_clientside_index_data, use_clientside_vertex_data); 1830 1831 /* We need to test four different functions: 1832 * 1833 * a) glDrawElementsBaseVertex() (GL) 1834 * or glDrawElementsBaseVertexEXT() (ES) 1835 * b) glDrawRangeElementsBaseVertex() (GL) 1836 * or glDrawRangeElementsBaseVertexEXT() (ES) 1837 * c) glDrawElementsInstancedBaseVertex() (GL) 1838 * or glDrawElementsInstancedBaseVertexEXT() (ES) 1839 * d) glMultiDrawElementsBaseVertex() (GL) 1840 * or glMultiDrawElementsBaseVertexEXT() (ES) (if supported) 1841 **/ 1842 for (int n_function = 0; n_function < FUNCTION_COUNT; ++n_function) 1843 { 1844 /* Do not try to use the multi draw call if relevant extension is 1845 * not supported. */ 1846 if (!m_is_ext_multi_draw_arrays_supported && n_function == FUNCTION_GL_MULTI_DRAW_ELEMENTS_BASE_VERTEX) 1847 { 1848 continue; 1849 } 1850 1851 /* Prepare a few arrays so that we can handle the multi draw call and its emulated version.. */ 1852 const glw::GLsizei multi_draw_call_count_array[3] = { 3, 6, 3 }; 1853 const glw::GLuint* multi_draw_call_indices_array[3] = { (glw::GLuint*)(m_draw_call_index_offset), 1854 (glw::GLuint*)(m_draw_call_index_offset + 3), 1855 (glw::GLuint*)(m_draw_call_index_offset + 9) }; 1856 1857 /* Reference texture should always reflect basevertex=10 behavior. */ 1858 const glw::GLuint regular_draw_call_offset = 0; 1859 const glw::GLuint* regular_multi_draw_call_offseted_array[3] = { 1860 multi_draw_call_indices_array[0] + regular_draw_call_offset, 1861 multi_draw_call_indices_array[1] + regular_draw_call_offset, 1862 multi_draw_call_indices_array[2] + regular_draw_call_offset, 1863 }; 1864 1865 /* Construct the test case descriptor */ 1866 _test_case new_test_case; 1867 1868 new_test_case.basevertex = basevertex; 1869 new_test_case.function_type = (_function_type)n_function; 1870 new_test_case.index_offset = m_draw_call_index_offset; 1871 new_test_case.range_start = 0; 1872 new_test_case.range_end = 22; 1873 new_test_case.index_type = GL_UNSIGNED_INT; 1874 new_test_case.primitive_mode = GL_TRIANGLES; 1875 new_test_case.regular_draw_call_offset = regular_draw_call_offset; 1876 new_test_case.should_base_texture_match_reference_texture = 1877 ((glw::GLuint)new_test_case.basevertex == new_test_case.regular_draw_call_offset); 1878 new_test_case.use_clientside_index_data = use_clientside_index_data; 1879 new_test_case.use_clientside_vertex_data = use_clientside_vertex_data; 1880 new_test_case.use_geometry_shader_stage = false; 1881 new_test_case.use_tessellation_shader_stage = false; 1882 new_test_case.use_vertex_attrib_binding = false; 1883 1884 memcpy(new_test_case.multi_draw_call_count_array, multi_draw_call_count_array, 1885 sizeof(multi_draw_call_count_array)); 1886 memcpy(new_test_case.multi_draw_call_indices_array, multi_draw_call_indices_array, 1887 sizeof(multi_draw_call_indices_array)); 1888 memcpy(new_test_case.regular_multi_draw_call_offseted_array, regular_multi_draw_call_offseted_array, 1889 sizeof(regular_multi_draw_call_offseted_array)); 1890 1891 m_test_cases.push_back(new_test_case); 1892 } /* for (all four functions) */ 1893 } /* for (all VAO iterations) */ 1894} 1895 1896/** Executes test iteration. 1897 * 1898 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 1899 */ 1900tcu::TestNode::IterateResult DrawElementsBaseVertexFunctionalCorrectBaseVertexBehavior2::iterate() 1901{ 1902 setUpTestCases(); 1903 executeTestCases(); 1904 1905 /* Test case passed */ 1906 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1907 1908 return STOP; 1909} 1910 1911/** Constructor. 1912 * 1913 * @param context Rendering context handle. 1914 **/ 1915DrawElementsBaseVertexFunctionalCorrectBaseVertexBehaviorUnderflow:: 1916 DrawElementsBaseVertexFunctionalCorrectBaseVertexBehaviorUnderflow(Context& context, const ExtParameters& extParams) 1917 : DrawElementsBaseVertexTestBase(context, extParams, "underflow", 1918 "Verifies basevertex draw calls work correctly for negative " 1919 "basevertex values") 1920{ 1921 /* Left blank on purpose */ 1922} 1923 1924/** Sets up test case descriptors for the test instance. These will later be used 1925 * as input for DrawElementsBaseVertexTestBase::executeTestCases(), which performs 1926 * the actual testing. 1927 **/ 1928void DrawElementsBaseVertexFunctionalCorrectBaseVertexBehaviorUnderflow::setUpTestCases() 1929{ 1930 /* Set up test case descriptors */ 1931 const glw::GLint basevertex = -10; 1932 1933 /* The test needs to be run in two iterations, using client-side memory and buffer object 1934 * for index data respectively 1935 */ 1936 for (int vao_iteration = 0; vao_iteration < 2; ++vao_iteration) 1937 { 1938 /* Skip client-side vertex array as gl_VertexID is undefined when no buffer bound to ARRAY_BUFFER 1939 * See section 11.1.3.9 in OpenGL ES 3.1 spec 1940 */ 1941 bool use_clientside_vertex_data = 0; 1942 bool use_clientside_index_data = ((vao_iteration & (1 << 0)) != 0); 1943 1944 /* OpenGL does not support client-side data. */ 1945 if (!glu::isContextTypeES(m_context.getRenderContext().getType())) 1946 { 1947 if (use_clientside_index_data || use_clientside_vertex_data) 1948 { 1949 continue; 1950 } 1951 } 1952 1953 /* Compute the offsets */ 1954 computeVBODataOffsets(use_clientside_index_data, use_clientside_vertex_data); 1955 1956 /* We need to test four different functions: 1957 * 1958 * a) glDrawElementsBaseVertex() (GL) 1959 * or glDrawElementsBaseVertexEXT() (ES) 1960 * b) glDrawRangeElementsBaseVertex() (GL) 1961 * or glDrawRangeElementsBaseVertexEXT() (ES) 1962 * c) glDrawElementsInstancedBaseVertex() (GL) 1963 * or glDrawElementsInstancedBaseVertexEXT() (ES) 1964 * d) glMultiDrawElementsBaseVertex() (GL) 1965 * or glMultiDrawElementsBaseVertexEXT() (ES) (if supported) 1966 **/ 1967 for (int n_function = 0; n_function < FUNCTION_COUNT; ++n_function) 1968 { 1969 /* Do not try to use the multi draw call if relevant extension is 1970 * not supported. */ 1971 if (!m_is_ext_multi_draw_arrays_supported && n_function == FUNCTION_GL_MULTI_DRAW_ELEMENTS_BASE_VERTEX) 1972 { 1973 continue; 1974 } 1975 1976 /* Prepare a few arrays so that we can handle the multi draw call and its emulated version.. */ 1977 unsigned int offset_from_10_to_0_index = 23; /* this offset moves us from the start index of 10 to a zero 1978 * index, given the second index data set we will be using. 1979 * Please see declaration of functional2_index_data if you 1980 * need to verify this by yourself. */ 1981 1982 const glw::GLsizei multi_draw_call_count_array[3] = { 3, 6, 3 }; 1983 const glw::GLuint* multi_draw_call_indices_array[3] = { (glw::GLuint*)(m_draw_call_index2_offset), 1984 (glw::GLuint*)(m_draw_call_index2_offset + 3), 1985 (glw::GLuint*)(m_draw_call_index2_offset + 9) }; 1986 const glw::GLuint* regular_multi_draw_call_offseted_array[3] = { 1987 multi_draw_call_indices_array[0] + offset_from_10_to_0_index, 1988 multi_draw_call_indices_array[1] + offset_from_10_to_0_index, 1989 multi_draw_call_indices_array[2] + offset_from_10_to_0_index, 1990 }; 1991 1992 /* Construct the test case descriptor */ 1993 _test_case new_test_case; 1994 1995 new_test_case.basevertex = basevertex; 1996 new_test_case.function_type = (_function_type)n_function; 1997 new_test_case.index_offset = m_draw_call_index2_offset; 1998 new_test_case.range_start = 10; 1999 new_test_case.range_end = 32; 2000 new_test_case.index_type = GL_UNSIGNED_INT; 2001 new_test_case.primitive_mode = GL_TRIANGLES; 2002 new_test_case.regular_draw_call_offset = offset_from_10_to_0_index; 2003 new_test_case.should_base_texture_match_reference_texture = true; 2004 new_test_case.use_clientside_index_data = use_clientside_index_data; 2005 new_test_case.use_clientside_vertex_data = use_clientside_vertex_data; 2006 new_test_case.use_geometry_shader_stage = false; 2007 new_test_case.use_tessellation_shader_stage = false; 2008 new_test_case.use_vertex_attrib_binding = false; 2009 2010 memcpy(new_test_case.multi_draw_call_count_array, multi_draw_call_count_array, 2011 sizeof(multi_draw_call_count_array)); 2012 memcpy(new_test_case.multi_draw_call_indices_array, multi_draw_call_indices_array, 2013 sizeof(multi_draw_call_indices_array)); 2014 memcpy(new_test_case.regular_multi_draw_call_offseted_array, regular_multi_draw_call_offseted_array, 2015 sizeof(regular_multi_draw_call_offseted_array)); 2016 2017 m_test_cases.push_back(new_test_case); 2018 } /* for (all four functions) */ 2019 } /* for (all VAO iterations) */ 2020} 2021 2022/** Executes test iteration. 2023 * 2024 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 2025 */ 2026tcu::TestNode::IterateResult DrawElementsBaseVertexFunctionalCorrectBaseVertexBehaviorUnderflow::iterate() 2027{ 2028 setUpTestCases(); 2029 executeTestCases(); 2030 2031 /* Test case passed */ 2032 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2033 2034 return STOP; 2035} 2036 2037/** Constructor. 2038 * 2039 * @param context Rendering context handle. 2040 **/ 2041DrawElementsBaseVertexFunctionalCorrectBaseVertexBehaviorOverflow:: 2042 DrawElementsBaseVertexFunctionalCorrectBaseVertexBehaviorOverflow(Context& context, const ExtParameters& extParams) 2043 : DrawElementsBaseVertexTestBase(context, extParams, "overflow", 2044 "Verifies basevertex draw calls work correctly for overflowing " 2045 "basevertex values") 2046{ 2047 /* Left blank on purpose */ 2048} 2049 2050/** Sets up test case descriptors for the test instance. These will later be used 2051 * as input for DrawElementsBaseVertexTestBase::executeTestCases(), which performs 2052 * the actual testing. 2053 **/ 2054void DrawElementsBaseVertexFunctionalCorrectBaseVertexBehaviorOverflow::setUpTestCases() 2055{ 2056 /* The test needs to be run in two iterations, using client-side memory and buffer object 2057 * for index data respectively 2058 */ 2059 for (int vao_iteration = 0; vao_iteration < 2; ++vao_iteration) 2060 { 2061 /* Skip client-side vertex array as gl_VertexID is undefined when no buffer bound to ARRAY_BUFFER 2062 * See section 11.1.3.9 in OpenGL ES 3.1 spec 2063 */ 2064 bool use_clientside_vertex_data = 0; 2065 bool use_clientside_index_data = ((vao_iteration & (1 << 0)) != 0); 2066 2067 /* OpenGL does not support client-side data. */ 2068 if (!glu::isContextTypeES(m_context.getRenderContext().getType())) 2069 { 2070 if (use_clientside_index_data || use_clientside_vertex_data) 2071 { 2072 continue; 2073 } 2074 } 2075 2076 /* Compute the offsets */ 2077 computeVBODataOffsets(use_clientside_index_data, use_clientside_vertex_data); 2078 2079 /* We need to test four different functions: 2080 * 2081 * a) glDrawElementsBaseVertex() (GL) 2082 * or glDrawElementsBaseVertexEXT() (ES) 2083 * b) glDrawRangeElementsBaseVertex() (GL) 2084 * or glDrawRangeElementsBaseVertexEXT() (ES) 2085 * c) glDrawElementsInstancedBaseVertex() (GL) 2086 * or glDrawElementsInstancedBaseVertexEXT() (ES) 2087 * d) glMultiDrawElementsBaseVertex() (GL) 2088 * or glMultiDrawElementsBaseVertexEXT() (ES) (if supported) 2089 **/ 2090 for (int n_function = 0; n_function < FUNCTION_COUNT; ++n_function) 2091 { 2092 /* Do not try to use the multi draw call if relevant extension is 2093 * not supported. */ 2094 if (!m_is_ext_multi_draw_arrays_supported && n_function == FUNCTION_GL_MULTI_DRAW_ELEMENTS_BASE_VERTEX) 2095 { 2096 continue; 2097 } 2098 2099 const glw::GLenum index_types[] = { GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT }; 2100 2101 const unsigned int n_index_types = sizeof(index_types) / sizeof(index_types[0]); 2102 2103 for (unsigned int n_index_type = 0; n_index_type < n_index_types; ++n_index_type) 2104 { 2105 2106 glw::GLint basevertex = -1; 2107 const glw::GLubyte* index_offset = NULL; 2108 int index_size = 0; 2109 glw::GLenum index_type = index_types[n_index_type]; 2110 glw::GLenum regular_draw_call_index_type = 0; 2111 int regular_draw_call_index_size = 0; 2112 glw::GLboolean use_overflow_test_vertices = false; 2113 2114 /* To meet requirements of tests IX.1-IX.2 and IX.3, we need to use two basevertex deltas. */ 2115 const glw::GLint basevertex_deltas[] = { 2116 0, /* IX.1-IX.2 */ 2117 1 /* IX.3 */ 2118 }; 2119 const unsigned int n_basevertex_deltas = sizeof(basevertex_deltas) / sizeof(basevertex_deltas[0]); 2120 2121 for (unsigned int n_basevertex_delta = 0; n_basevertex_delta < n_basevertex_deltas; 2122 ++n_basevertex_delta) 2123 { 2124 const glw::GLint basevertex_delta = basevertex_deltas[n_basevertex_delta]; 2125 glw::GLuint regular_draw_call_offset = 0; 2126 glw::GLuint* regular_draw_call_offset2 = NULL; 2127 glw::GLuint range_start = 0; 2128 glw::GLuint range_end = 0; 2129 bool shouldMatch; 2130 2131 switch (index_type) 2132 { 2133 /* 2134 * UBYTE base draw indices: 0, 1, 2 2135 * baseVertex: 256+0 2136 * regular draw indices: 0, 1, 2 2137 * expected result: ubyte indices should not wrap around at 8-bit width, 2138 * base draw result should not match regular draw result 2139 * 2140 * UBYTE base draw indices: 0, 1, 2 2141 * baseVertex: 256+1 2142 * regular draw indices: 257, 258, 259 (uint) 2143 * expected result: ubyte indices should be upconverted to 32-bit uint, 2144 * base draw result should match regular draw result 2145 */ 2146 case GL_UNSIGNED_BYTE: 2147 { 2148 basevertex = 256 + basevertex_delta; 2149 index_offset = (const glw::GLubyte*)m_draw_call_index3_offset; 2150 index_size = 1; 2151 range_start = 0; 2152 range_end = 2; 2153 regular_draw_call_index_type = (basevertex_delta == 0) ? GL_UNSIGNED_BYTE : GL_UNSIGNED_INT; 2154 regular_draw_call_index_size = (regular_draw_call_index_type == GL_UNSIGNED_BYTE) ? 1 : 4; 2155 regular_draw_call_offset2 = 2156 (basevertex_delta == 0) ? 2157 (glw::GLuint*)(m_draw_call_index3_offset) : 2158 (glw::GLuint*)(m_draw_call_index5_offset + 12); // 12th in functional5_index_data 2159 shouldMatch = (basevertex_delta == 1) ? true : false; 2160 use_overflow_test_vertices = true; 2161 break; 2162 } 2163 2164 /* 2165 * USHORT base draw indices: 0, 1, 2 2166 * baseVertex: 65536+0 2167 * regular draw indices: 0, 1, 2 2168 * expected result: ubyte indices should not wrap around at 16-bit width, 2169 * base draw result should not match regular draw result 2170 * 2171 * USHORT base draw indices: 0, 1, 2 2172 * baseVertex: 65536+1 2173 * regular draw indices: 65537, 65538, 65539 (uint) 2174 * expected result: ushort indices should be upconverted to 32-bit uint, 2175 * base draw result should match regular draw result 2176 */ 2177 case GL_UNSIGNED_SHORT: 2178 { 2179 basevertex = 65536 + basevertex_delta; 2180 index_offset = (const glw::GLubyte*)m_draw_call_index4_offset; 2181 index_size = 2; 2182 range_start = 0; 2183 range_end = 2; 2184 regular_draw_call_index_type = (basevertex_delta == 0) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT; 2185 regular_draw_call_index_size = (regular_draw_call_index_type == GL_UNSIGNED_SHORT) ? 2 : 4; 2186 regular_draw_call_offset2 = 2187 (basevertex_delta == 0) ? 2188 (glw::GLuint*)(m_draw_call_index4_offset) : 2189 (glw::GLuint*)(m_draw_call_index5_offset + 24); // 24th in functional5_index_data 2190 shouldMatch = (basevertex_delta == 1) ? true : false; 2191 use_overflow_test_vertices = true; 2192 break; 2193 } 2194 2195 /* 2196 * UINT base draw indices: 2^31+2, 2^31+3, 2^31+4 2197 * baseVertex: 2^31-2 2198 * regular draw indices: 0, 1, 2 2199 * expected result: uint indices should wrap to {0, 1, 2}, 2200 * base draw result should match regular draw result 2201 * 2202 * UINT base draw indices: 2^31+2, 2^31+3, 2^31+4 2203 * baseVertex: 2^31-1 2204 * regular draw indices: 0, 1, 2 2205 * expected result: uint indices should wrap to {1, 2, 3}, 2206 * base draw result should not match regular draw result 2207 */ 2208 case GL_UNSIGNED_INT: 2209 { 2210 basevertex = 2147483647 - 1 + basevertex_delta; 2211 index_offset = (const glw::GLubyte*)m_draw_call_index5_offset; 2212 index_size = 4; 2213 range_start = 2147483647 + 3u; // 2^31+2 2214 range_end = 2147483647 + 5u; // 2^31+4 2215 regular_draw_call_index_type = GL_UNSIGNED_INT; 2216 regular_draw_call_index_size = 4; 2217 regular_draw_call_offset = 36; // 36th in functional5_index_data 2218 shouldMatch = (basevertex_delta == 0) ? true : false; 2219 use_overflow_test_vertices = false; 2220 break; 2221 } 2222 2223 default: 2224 { 2225 TCU_FAIL("Unrecognized index type"); 2226 } 2227 } /* switch (index_type) */ 2228 2229 /* Prepare a few arrays so that we can handle the multi draw call and its emulated version.. */ 2230 const glw::GLsizei multi_draw_call_count_array[3] = { 3, 6, 3 }; 2231 const glw::GLubyte* multi_draw_call_indices_array[3] = { index_offset, 2232 index_offset + 3 * index_size, 2233 index_offset + 9 * index_size }; 2234 const glw::GLubyte* regular_multi_draw_call_offseted_array[3]; 2235 if (use_overflow_test_vertices) 2236 { 2237 regular_multi_draw_call_offseted_array[0] = (glw::GLubyte*)regular_draw_call_offset2; 2238 regular_multi_draw_call_offseted_array[1] = 2239 (glw::GLubyte*)regular_draw_call_offset2 + 3 * regular_draw_call_index_size; 2240 regular_multi_draw_call_offseted_array[2] = 2241 (glw::GLubyte*)regular_draw_call_offset2 + 9 * regular_draw_call_index_size; 2242 } 2243 else 2244 { 2245 regular_multi_draw_call_offseted_array[0] = 2246 multi_draw_call_indices_array[0] + index_size * regular_draw_call_offset; 2247 regular_multi_draw_call_offseted_array[1] = 2248 multi_draw_call_indices_array[1] + index_size * regular_draw_call_offset; 2249 regular_multi_draw_call_offseted_array[2] = 2250 multi_draw_call_indices_array[2] + index_size * regular_draw_call_offset; 2251 } 2252 2253 /* Construct the test case descriptor */ 2254 _test_case new_test_case; 2255 2256 new_test_case.basevertex = basevertex; 2257 new_test_case.function_type = (_function_type)n_function; 2258 new_test_case.index_offset = (const glw::GLuint*)index_offset; 2259 new_test_case.range_start = range_start; 2260 new_test_case.range_end = range_end; 2261 new_test_case.index_type = index_type; 2262 new_test_case.primitive_mode = GL_TRIANGLES; 2263 new_test_case.regular_draw_call_offset = regular_draw_call_offset; 2264 new_test_case.regular_draw_call_offset2 = regular_draw_call_offset2; 2265 new_test_case.regular_draw_call_index_type = regular_draw_call_index_type; 2266 new_test_case.should_base_texture_match_reference_texture = shouldMatch; 2267 new_test_case.use_clientside_index_data = use_clientside_index_data; 2268 new_test_case.use_clientside_vertex_data = use_clientside_vertex_data; 2269 new_test_case.use_geometry_shader_stage = false; 2270 new_test_case.use_tessellation_shader_stage = false; 2271 new_test_case.use_vertex_attrib_binding = false; 2272 new_test_case.use_overflow_test_vertices = use_overflow_test_vertices != GL_FALSE; 2273 2274 memcpy(new_test_case.multi_draw_call_count_array, multi_draw_call_count_array, 2275 sizeof(multi_draw_call_count_array)); 2276 memcpy(new_test_case.multi_draw_call_indices_array, multi_draw_call_indices_array, 2277 sizeof(multi_draw_call_indices_array)); 2278 memcpy(new_test_case.regular_multi_draw_call_offseted_array, regular_multi_draw_call_offseted_array, 2279 sizeof(regular_multi_draw_call_offseted_array)); 2280 2281 m_test_cases.push_back(new_test_case); 2282 } /* for (all basevertex deltas) */ 2283 } /* for (all index types) */ 2284 } /* for (all four functions) */ 2285 } /* for (all VAO iterations) */ 2286} 2287 2288/** Executes test iteration. 2289 * 2290 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 2291 */ 2292tcu::TestNode::IterateResult DrawElementsBaseVertexFunctionalCorrectBaseVertexBehaviorOverflow::iterate() 2293{ 2294 setUpTestCases(); 2295 executeTestCases(); 2296 2297 /* Test case passed */ 2298 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2299 2300 return STOP; 2301} 2302 2303/** Constructor. 2304 * 2305 * @param context Rendering context handle. 2306 **/ 2307DrawElementsBaseVertexFunctionalCorrectBaseVertexBehaviorAEPShaderStages:: 2308 DrawElementsBaseVertexFunctionalCorrectBaseVertexBehaviorAEPShaderStages(Context& context, 2309 const ExtParameters& extParams) 2310 : DrawElementsBaseVertexTestBase(context, extParams, "AEP_shader_stages", 2311 "Verifies basevertex draw calls work correctly when geometry & " 2312 "tessellation shader stages are used in the rendering pipeline.") 2313{ 2314 /* Left blank intentionally */ 2315} 2316 2317/** Sets up test case descriptors for the test instance. These will later be used 2318 * as input for DrawElementsBaseVertexTestBase::executeTestCases(), which performs 2319 * the actual testing. 2320 **/ 2321void DrawElementsBaseVertexFunctionalCorrectBaseVertexBehaviorAEPShaderStages::setUpTestCases() 2322{ 2323 /* Set up test case descriptors */ 2324 const glw::GLuint basevertex_values[] = { 2325 10, /* VI.1-VI.4 */ 2326 0 /* VI.5 */ 2327 }; 2328 const unsigned int n_basevertex_values = sizeof(basevertex_values) / sizeof(basevertex_values[0]); 2329 2330 /* The test needs to be run in two iterations, using client-side memory and buffer object 2331 * for index data respectively 2332 */ 2333 for (int vao_iteration = 0; vao_iteration < 2; ++vao_iteration) 2334 { 2335 /* Skip client-side vertex array as gl_VertexID is undefined when zero buffer is bound to ARRAY_BUFFER */ 2336 bool use_clientside_vertex_data = 0; 2337 bool use_clientside_index_data = ((vao_iteration & (1 << 0)) != 0); 2338 2339 /* OpenGL does not support client-side data. */ 2340 if (!glu::isContextTypeES(m_context.getRenderContext().getType())) 2341 { 2342 if (use_clientside_index_data || use_clientside_vertex_data) 2343 { 2344 continue; 2345 } 2346 } 2347 2348 /* Compute the offsets */ 2349 computeVBODataOffsets(use_clientside_index_data, use_clientside_vertex_data); 2350 2351 /* There are two index data sets we need to iterate over */ 2352 const glw::GLuint* index_offsets[] = { m_draw_call_index_offset, m_draw_call_index2_offset }; 2353 const unsigned int n_index_offsets = sizeof(index_offsets) / sizeof(index_offsets[0]); 2354 2355 for (unsigned int n_index_offset = 0; n_index_offset < n_index_offsets; ++n_index_offset) 2356 { 2357 const glw::GLuint* current_index_offset = index_offsets[n_index_offset]; 2358 2359 /* We need to test four different functions: 2360 * 2361 * a) glDrawElementsBaseVertex() (GL) 2362 * or glDrawElementsBaseVertexEXT() (ES) 2363 * b) glDrawRangeElementsBaseVertex() (GL) 2364 * or glDrawRangeElementsBaseVertexEXT() (ES) 2365 * c) glDrawElementsInstancedBaseVertex() (GL) 2366 * or glDrawElementsInstancedBaseVertexEXT() (ES) 2367 * d) glMultiDrawElementsBaseVertex() (GL) 2368 * or glMultiDrawElementsBaseVertexEXT() (ES) (if supported) 2369 **/ 2370 for (int n_function = 0; n_function < FUNCTION_COUNT; ++n_function) 2371 { 2372 /* Iterate over all basevertex values */ 2373 for (unsigned int n_basevertex_value = 0; n_basevertex_value < n_basevertex_values; 2374 ++n_basevertex_value) 2375 { 2376 2377 /* Iterate over all GS+(TC & TE) stage combinations */ 2378 for (unsigned int n_stage_combination = 0; n_stage_combination < 4; ++n_stage_combination) 2379 { 2380 bool should_include_gs = (n_stage_combination & 1) != 0; 2381 bool should_include_tc_te = (n_stage_combination & 2) != 0; 2382 2383 /* Skip iterations, for which we'd need to use extensions not supported 2384 * by the running implementation */ 2385 if (should_include_gs && !m_is_geometry_shader_supported) 2386 { 2387 continue; 2388 } 2389 2390 if (should_include_tc_te && !m_is_tessellation_shader_supported) 2391 { 2392 continue; 2393 } 2394 2395 /* Do not try to use the multi draw call if relevant extension is 2396 * not supported. */ 2397 if (!m_is_ext_multi_draw_arrays_supported && 2398 n_function == FUNCTION_GL_MULTI_DRAW_ELEMENTS_BASE_VERTEX) 2399 { 2400 continue; 2401 } 2402 2403 /* Prepare a few arrays so that we can handle the multi draw call and its emulated version.. */ 2404 const glw::GLsizei multi_draw_call_count_array[3] = { 3, 6, 3 }; 2405 const glw::GLuint* multi_draw_call_indices_array[3] = { 2406 (glw::GLuint*)(current_index_offset), (glw::GLuint*)(current_index_offset + 3), 2407 (glw::GLuint*)(current_index_offset + 9) 2408 }; 2409 2410 /* Reference texture should always reflect basevertex=10 behavior. */ 2411 const glw::GLuint regular_draw_call_offset = basevertex_values[0]; 2412 const glw::GLuint* regular_multi_draw_call_offseted_array[3] = { 2413 multi_draw_call_indices_array[0] + regular_draw_call_offset, 2414 multi_draw_call_indices_array[1] + regular_draw_call_offset, 2415 multi_draw_call_indices_array[2] + regular_draw_call_offset, 2416 }; 2417 2418 /* Construct the test case descriptor */ 2419 _test_case new_test_case; 2420 2421 new_test_case.basevertex = basevertex_values[n_basevertex_value]; 2422 new_test_case.function_type = (_function_type)n_function; 2423 new_test_case.index_offset = current_index_offset; 2424 new_test_case.range_start = n_index_offset == 0 ? 0 : 10; 2425 new_test_case.range_end = n_index_offset == 0 ? 22 : 32; 2426 new_test_case.index_type = GL_UNSIGNED_INT; 2427 new_test_case.primitive_mode = (should_include_tc_te) ? GL_PATCHES : GL_TRIANGLES; 2428 new_test_case.regular_draw_call_offset = regular_draw_call_offset; 2429 new_test_case.should_base_texture_match_reference_texture = 2430 ((glw::GLuint)new_test_case.basevertex == new_test_case.regular_draw_call_offset); 2431 new_test_case.use_clientside_index_data = use_clientside_index_data; 2432 new_test_case.use_clientside_vertex_data = use_clientside_vertex_data; 2433 new_test_case.use_geometry_shader_stage = should_include_gs; 2434 new_test_case.use_tessellation_shader_stage = should_include_tc_te; 2435 new_test_case.use_vertex_attrib_binding = false; 2436 2437 memcpy(new_test_case.multi_draw_call_count_array, multi_draw_call_count_array, 2438 sizeof(multi_draw_call_count_array)); 2439 memcpy(new_test_case.multi_draw_call_indices_array, multi_draw_call_indices_array, 2440 sizeof(multi_draw_call_indices_array)); 2441 memcpy(new_test_case.regular_multi_draw_call_offseted_array, 2442 regular_multi_draw_call_offseted_array, sizeof(regular_multi_draw_call_offseted_array)); 2443 2444 m_test_cases.push_back(new_test_case); 2445 } /* for (all shader stage combinations) */ 2446 } /* for (all basevertex values) */ 2447 } /* for (all four functions) */ 2448 } /* for (all index data sets) */ 2449 } /* for (all VAO iterations) */ 2450} 2451 2452/** Executes test iteration. 2453 * 2454 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 2455 */ 2456tcu::TestNode::IterateResult DrawElementsBaseVertexFunctionalCorrectBaseVertexBehaviorAEPShaderStages::iterate() 2457{ 2458 /* This test should not be run on implementations that don't support both tessellation and geometry 2459 * shader stages 2460 */ 2461 if (!m_is_geometry_shader_supported && !m_is_tessellation_shader_supported) 2462 { 2463 throw tcu::NotSupportedError("Geometry shader and tessellation shader functionality is not supported"); 2464 } 2465 2466 setUpTestCases(); 2467 executeTestCases(); 2468 2469 /* Test case passed */ 2470 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2471 2472 return STOP; 2473} 2474 2475/** Constructor. 2476 * 2477 * @param context Rendering context handle. 2478 **/ 2479DrawElementsBaseVertexNegativeActiveTransformFeedbackTest::DrawElementsBaseVertexNegativeActiveTransformFeedbackTest( 2480 Context& context, const ExtParameters& extParams) 2481 : DrawElementsBaseVertexTestBase(context, extParams, "valid_active_tf", 2482 "Tries to do \"base vertex\" draw calls while Transform Feedback is active") 2483 , m_bo_tf_result_id(0) 2484{ 2485 /* Left blank on purpose */ 2486} 2487 2488/** Deinitializes all ES objects per test case if test fails and exit through exception path */ 2489void DrawElementsBaseVertexNegativeActiveTransformFeedbackTest::deinit() 2490{ 2491 deinitPerTestObjects(); 2492} 2493 2494/** Deinitializes all ES objects that may have been created by the test */ 2495void DrawElementsBaseVertexNegativeActiveTransformFeedbackTest::deinitPerTestObjects() 2496{ 2497 /* Call the base class' deinitPerTestObjects() first. */ 2498 DrawElementsBaseVertexTestBase::deinitPerTestObjects(); 2499 2500 /* Proceed with internal deinitialization */ 2501 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2502 2503 if (m_bo_tf_result_id != 0) 2504 { 2505 gl.deleteBuffers(1, &m_bo_tf_result_id); 2506 2507 m_bo_tf_result_id = 0; 2508 } 2509} 2510 2511/** Initializes all ES objects used by the test. */ 2512void DrawElementsBaseVertexNegativeActiveTransformFeedbackTest::init() 2513{ 2514 /* Call the base class' init() first. */ 2515 DrawElementsBaseVertexTestBase::init(); 2516 2517 /* Proceed with internal initialization */ 2518 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2519 2520 gl.genBuffers(1, &m_bo_tf_result_id); 2521 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed"); 2522 2523 gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_tf_result_id); 2524 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed"); 2525 2526 gl.bufferData(GL_ARRAY_BUFFER, 3 /* count */ * sizeof(float) * 4 /* components used by gl_Position */, 2527 DE_NULL, /* data */ 2528 GL_STATIC_DRAW); 2529 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed."); 2530 2531 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, /* index */ 2532 m_bo_tf_result_id); 2533 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed"); 2534} 2535 2536/** Executes test iteration. 2537 * 2538 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 2539 */ 2540tcu::TestNode::IterateResult DrawElementsBaseVertexNegativeActiveTransformFeedbackTest::iterate() 2541{ 2542 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2543 2544 /* this test doesn't apply to OpenGL contexts */ 2545 if (!glu::isContextTypeES(m_context.getRenderContext().getType())) 2546 { 2547 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); 2548 return STOP; 2549 } 2550 2551 /* Set up the work environment */ 2552 setUpNegativeTestObjects(false, /* use_clientside_vertex_data */ 2553 false); /* use_clientside_index_data */ 2554 2555 /* Kick off transform feedback */ 2556 gl.beginTransformFeedback(GL_TRIANGLES); 2557 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed."); 2558 2559 /* Try to perform indiced draw calls which are invalid when TF is active. 2560 */ 2561 glw::GLenum error_code = GL_NONE; 2562 2563 gl.drawElementsBaseVertex(GL_TRIANGLES, 3, /* count */ 2564 GL_UNSIGNED_INT, m_draw_call_index_offset, 0); /* basevertex */ 2565 2566 error_code = gl.getError(); 2567 2568 /* The error for using DrawElements* commands while transform feedback is 2569 active is lifted in OES/EXT_geometry_shader. See issue 13 in the spec. 2570 */ 2571 glw::GLenum expected_error_code = m_is_geometry_shader_supported ? GL_NO_ERROR : GL_INVALID_OPERATION; 2572 2573 if (error_code != expected_error_code) 2574 { 2575 std::stringstream error_sstream; 2576 2577 error_sstream << "Invalid error code generated by " << getFunctionName(FUNCTION_GL_DRAW_ELEMENTS_BASE_VERTEX); 2578 2579 m_testCtx.getLog() << tcu::TestLog::Message << getFunctionName(FUNCTION_GL_DRAW_ELEMENTS_BASE_VERTEX) 2580 << " returned error code [" << error_code << "] instead of [" << expected_error_code << "]." 2581 << tcu::TestLog::EndMessage; 2582 2583 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, error_sstream.str().c_str()); 2584 2585 goto end; 2586 } 2587 2588 gl.drawElementsInstancedBaseVertex(GL_TRIANGLES, 3, /* count */ 2589 GL_UNSIGNED_INT, m_draw_call_index_offset, 1, /* instancecount */ 2590 0); /* basevertex */ 2591 2592 error_code = gl.getError(); 2593 if (error_code != expected_error_code) 2594 { 2595 std::stringstream error_sstream; 2596 2597 error_sstream << "Invalid error code generated by " 2598 << getFunctionName(FUNCTION_GL_DRAW_ELEMENTS_INSTANCED_BASE_VERTEX); 2599 2600 m_testCtx.getLog() << tcu::TestLog::Message << getFunctionName(FUNCTION_GL_DRAW_ELEMENTS_INSTANCED_BASE_VERTEX) 2601 << " returned error code [" << error_code << "] instead of [" << expected_error_code << "]." 2602 << tcu::TestLog::EndMessage; 2603 2604 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, error_sstream.str().c_str()); 2605 2606 goto end; 2607 } 2608 2609 gl.drawRangeElementsBaseVertex(GL_TRIANGLES, 0, 2, /* end */ 2610 3, /* count */ 2611 GL_UNSIGNED_INT, m_draw_call_index_offset, 0); /* basevertex */ 2612 2613 error_code = gl.getError(); 2614 if (error_code != expected_error_code) 2615 { 2616 std::stringstream error_sstream; 2617 2618 error_sstream << "Invalid error code generated by " 2619 << getFunctionName(FUNCTION_GL_DRAW_RANGE_ELEMENTS_BASE_VERTEX); 2620 2621 m_testCtx.getLog() << tcu::TestLog::Message << getFunctionName(FUNCTION_GL_DRAW_RANGE_ELEMENTS_BASE_VERTEX) 2622 << " returned error code [" << error_code << "] instead of [" << expected_error_code << "]." 2623 << tcu::TestLog::EndMessage; 2624 2625 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, error_sstream.str().c_str()); 2626 2627 goto end; 2628 } 2629 2630 /* Test case passed */ 2631 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2632 2633end: 2634 gl.endTransformFeedback(); 2635 return STOP; 2636} 2637 2638/** Constructor. 2639 * 2640 * @param context Rendering context handle. 2641 **/ 2642DrawElementsBaseVertexNegativeInvalidCountArgumentTest::DrawElementsBaseVertexNegativeInvalidCountArgumentTest( 2643 Context& context, const ExtParameters& extParams) 2644 : DrawElementsBaseVertexTestBase(context, extParams, "invalid_count_argument", 2645 "Tries to use invalid 'count' argument values for the \"base vertex\" draw calls") 2646{ 2647 /* Left blank on purpose */ 2648} 2649 2650/** Executes test iteration. 2651 * 2652 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 2653 */ 2654tcu::TestNode::IterateResult DrawElementsBaseVertexNegativeInvalidCountArgumentTest::iterate() 2655{ 2656 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2657 2658 /* The test needs to be run in four iterations, where for each iteration we configure the VAO 2659 * in a slightly different manner. 2660 */ 2661 for (int iteration = 0; iteration < 4; ++iteration) 2662 { 2663 bool use_clientside_index_data = ((iteration & (1 << 0)) != 0); 2664 bool use_clientside_vertex_data = ((iteration & (1 << 1)) != 0); 2665 2666 /* OpenGL does not support client-side data. */ 2667 if (!glu::isContextTypeES(m_context.getRenderContext().getType())) 2668 { 2669 if (use_clientside_index_data || use_clientside_vertex_data) 2670 { 2671 continue; 2672 } 2673 } 2674 2675 /* Set up the work environment */ 2676 setUpNegativeTestObjects(use_clientside_vertex_data, use_clientside_index_data); 2677 2678 /* Try to execute the invalid draw calls */ 2679 glw::GLenum error_code = GL_NONE; 2680 2681 gl.drawElementsBaseVertex(GL_TRIANGLES, -1, /* count */ 2682 GL_UNSIGNED_INT, (const glw::GLvoid*)m_draw_call_index_offset, 0); /* basevertex */ 2683 2684 error_code = gl.getError(); 2685 if (error_code != GL_INVALID_VALUE) 2686 { 2687 std::stringstream error_sstream; 2688 2689 error_sstream << "Invalid error code reported for an invalid " 2690 << getFunctionName(FUNCTION_GL_DRAW_ELEMENTS_BASE_VERTEX) << " call"; 2691 2692 m_testCtx.getLog() << tcu::TestLog::Message << error_sstream.str().c_str() 2693 << ": expected GL_INVALID_VALUE, got:" 2694 "[" 2695 << error_code << "]" << tcu::TestLog::EndMessage; 2696 2697 TCU_FAIL(error_sstream.str().c_str()); 2698 } 2699 2700 gl.drawRangeElementsBaseVertex(GL_TRIANGLES, /* mode */ 2701 -1, /* start */ 2702 2, /* end */ 2703 1, /* count */ 2704 GL_UNSIGNED_INT, (const glw::GLvoid*)m_draw_call_index_offset, 2705 0); /* basevertex */ 2706 2707 error_code = gl.getError(); 2708 if (error_code != GL_INVALID_VALUE) 2709 { 2710 std::stringstream error_sstream; 2711 2712 error_sstream << "Invalid error code reported for an invalid " 2713 << getFunctionName(FUNCTION_GL_DRAW_RANGE_ELEMENTS_BASE_VERTEX) << " call"; 2714 2715 m_testCtx.getLog() << tcu::TestLog::Message << error_sstream.str().c_str() 2716 << ": expected GL_INVALID_VALUE, got:" 2717 "[" 2718 << error_code << "]" << tcu::TestLog::EndMessage; 2719 2720 TCU_FAIL(error_sstream.str().c_str()); 2721 } 2722 2723 gl.drawElementsInstancedBaseVertex(GL_TRIANGLES, /* mode */ 2724 -1, /* count */ 2725 GL_UNSIGNED_INT, (const glw::GLvoid*)m_draw_call_index_offset, 2726 1, /* instancecount */ 2727 0); /* basevertex */ 2728 2729 error_code = gl.getError(); 2730 if (error_code != GL_INVALID_VALUE) 2731 { 2732 std::stringstream error_sstream; 2733 2734 error_sstream << "Invalid error code reported for an invalid " 2735 << getFunctionName(FUNCTION_GL_DRAW_ELEMENTS_INSTANCED_BASE_VERTEX) << " call"; 2736 2737 m_testCtx.getLog() << tcu::TestLog::Message << error_sstream.str().c_str() 2738 << ": expected GL_INVALID_VALUE, got:" 2739 "[" 2740 << error_code << "]" << tcu::TestLog::EndMessage; 2741 2742 TCU_FAIL(error_sstream.str().c_str()); 2743 } 2744 2745 if (m_is_ext_multi_draw_arrays_supported) 2746 { 2747 const glw::GLsizei count = -1; 2748 const glw::GLvoid* offsets[] = { (const glw::GLvoid*)m_draw_call_index_offset }; 2749 2750 gl.multiDrawElementsBaseVertex(GL_TRIANGLES, /* mode */ 2751 &count, GL_UNSIGNED_INT, offsets, 1, /* primcount */ 2752 0); /* basevertex */ 2753 2754 error_code = gl.getError(); 2755 if (error_code != GL_INVALID_VALUE) 2756 { 2757 std::stringstream error_sstream; 2758 2759 error_sstream << "Invalid error code reported for an invalid " 2760 << getFunctionName(FUNCTION_GL_MULTI_DRAW_ELEMENTS_BASE_VERTEX) << " call"; 2761 2762 m_testCtx.getLog() << tcu::TestLog::Message << error_sstream.str().c_str() 2763 << ": expected GL_INVALID_VALUE, got:" 2764 "[" 2765 << error_code << "]" << tcu::TestLog::EndMessage; 2766 2767 TCU_FAIL("Invalid error code reported for an invalid glMultiDrawElementsBaseVertexEXT() call."); 2768 } 2769 } /* if (m_is_ext_multi_draw_arrays_supported) */ 2770 } /* for (all iterations) */ 2771 2772 /* Test case passed */ 2773 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2774 2775 return STOP; 2776} 2777 2778/** Constructor. 2779 * 2780 * @param context Rendering context handle. 2781 **/ 2782DrawElementsBaseVertexNegativeInvalidInstanceCountArgumentTest:: 2783 DrawElementsBaseVertexNegativeInvalidInstanceCountArgumentTest(Context& context, const ExtParameters& extParams) 2784 : DrawElementsBaseVertexTestBase(context, extParams, "invalid_instancecount_argument", 2785 "Tries to use invalid 'instancecount' argument values for " 2786 "glDrawElementsInstancedBaseVertexEXT (ES) or " 2787 "glDrawElementsInstancedBaseVertex (GL) draw call") 2788{ 2789 /* Left blank on purpose */ 2790} 2791 2792/** Executes test iteration. 2793 * 2794 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 2795 */ 2796tcu::TestNode::IterateResult DrawElementsBaseVertexNegativeInvalidInstanceCountArgumentTest::iterate() 2797{ 2798 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2799 2800 /* The test needs to be run in four iterations, where for each iteration we configure the VAO 2801 * in a slightly different manner. 2802 */ 2803 for (int iteration = 0; iteration < 4; ++iteration) 2804 { 2805 bool use_clientside_index_data = ((iteration & (1 << 0)) != 0); 2806 bool use_clientside_vertex_data = ((iteration & (1 << 1)) != 0); 2807 2808 /* OpenGL does not support client-side data. */ 2809 if (!glu::isContextTypeES(m_context.getRenderContext().getType())) 2810 { 2811 if (use_clientside_index_data || use_clientside_vertex_data) 2812 { 2813 continue; 2814 } 2815 } 2816 2817 /* Set up the work environment */ 2818 setUpNegativeTestObjects(use_clientside_vertex_data, use_clientside_index_data); 2819 2820 /* Try to execute the invalid draw call */ 2821 glw::GLenum error_code = GL_NONE; 2822 2823 gl.drawElementsInstancedBaseVertex(GL_TRIANGLES, /* mode */ 2824 3, /* count */ 2825 GL_UNSIGNED_INT, (const glw::GLvoid*)m_draw_call_index_offset, 2826 -1, /* instancecount */ 2827 0); /* basevertex */ 2828 2829 error_code = gl.getError(); 2830 if (error_code != GL_INVALID_VALUE) 2831 { 2832 std::stringstream error_sstream; 2833 2834 error_sstream << "Invalid error code reported for an invalid " 2835 << getFunctionName(FUNCTION_GL_DRAW_ELEMENTS_INSTANCED_BASE_VERTEX) << " call"; 2836 2837 m_testCtx.getLog() << tcu::TestLog::Message << error_sstream.str().c_str() 2838 << ": expected GL_INVALID_VALUE, got:" 2839 "[" 2840 << error_code << "]" << tcu::TestLog::EndMessage; 2841 2842 TCU_FAIL(error_sstream.str().c_str()); 2843 } 2844 } /* for (all test iterations) */ 2845 2846 /* Test case passed */ 2847 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2848 2849 return STOP; 2850} 2851 2852/** Constructor. 2853 * 2854 * @param context Rendering context handle. 2855 **/ 2856DrawElementsBaseVertexNegativeInvalidModeArgumentTest::DrawElementsBaseVertexNegativeInvalidModeArgumentTest( 2857 Context& context, const ExtParameters& extParams) 2858 : DrawElementsBaseVertexTestBase(context, extParams, "invalid_mode_argument", 2859 "Tries to use invalid 'mode' argument values for the \"base vertex\" draw calls") 2860{ 2861 /* Left blank on purpose */ 2862} 2863 2864/** Executes test iteration. 2865 * 2866 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 2867 */ 2868tcu::TestNode::IterateResult DrawElementsBaseVertexNegativeInvalidModeArgumentTest::iterate() 2869{ 2870 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2871 2872 /* The test needs to be run in four iterations, where for each iteration we configure the VAO 2873 * in a slightly different manner. 2874 */ 2875 for (int iteration = 0; iteration < 4; ++iteration) 2876 { 2877 bool use_clientside_index_data = ((iteration & (1 << 0)) != 0); 2878 bool use_clientside_vertex_data = ((iteration & (1 << 1)) != 0); 2879 2880 /* OpenGL does not support client-side data. */ 2881 if (!glu::isContextTypeES(m_context.getRenderContext().getType())) 2882 { 2883 if (use_clientside_index_data || use_clientside_vertex_data) 2884 { 2885 continue; 2886 } 2887 } 2888 2889 /* Set up the work environment */ 2890 setUpNegativeTestObjects(use_clientside_vertex_data, use_clientside_index_data); 2891 2892 /* Try to execute the invalid draw calls */ 2893 glw::GLenum error_code = GL_NONE; 2894 2895 gl.drawElementsBaseVertex(GL_GREATER, /* mode */ 2896 3, /* count */ 2897 GL_UNSIGNED_INT, (const glw::GLvoid*)m_draw_call_index_offset, 0); /* basevertex */ 2898 2899 error_code = gl.getError(); 2900 if (error_code != GL_INVALID_ENUM) 2901 { 2902 std::stringstream error_sstream; 2903 2904 error_sstream << "Invalid error code reported for an invalid " 2905 << getFunctionName(FUNCTION_GL_DRAW_ELEMENTS_BASE_VERTEX) << " call"; 2906 2907 m_testCtx.getLog() << tcu::TestLog::Message << error_sstream.str().c_str() 2908 << ": expected GL_INVALID_ENUM, got:" 2909 "[" 2910 << error_code << "]" << tcu::TestLog::EndMessage; 2911 2912 TCU_FAIL(error_sstream.str().c_str()); 2913 } 2914 2915 gl.drawRangeElementsBaseVertex(GL_GREATER, /* mode */ 2916 0, /* start */ 2917 2, /* end */ 2918 3, /* count */ 2919 GL_UNSIGNED_INT, (const glw::GLvoid*)m_draw_call_index_offset, 2920 0); /* basevertex */ 2921 2922 error_code = gl.getError(); 2923 if (error_code != GL_INVALID_ENUM) 2924 { 2925 std::stringstream error_sstream; 2926 2927 error_sstream << "Invalid error code reported for an invalid " 2928 << getFunctionName(FUNCTION_GL_DRAW_RANGE_ELEMENTS_BASE_VERTEX) << " call"; 2929 2930 m_testCtx.getLog() << tcu::TestLog::Message << error_sstream.str().c_str() 2931 << ": expected GL_INVALID_ENUM, got:" 2932 "[" 2933 << error_code << "]" << tcu::TestLog::EndMessage; 2934 2935 TCU_FAIL(error_sstream.str().c_str()); 2936 } 2937 2938 gl.drawElementsInstancedBaseVertex(GL_GREATER, /* mode */ 2939 3, /* count */ 2940 GL_UNSIGNED_INT, (const glw::GLvoid*)m_draw_call_index_offset, 2941 1, /* instancecount */ 2942 0); /* basevertex */ 2943 2944 error_code = gl.getError(); 2945 if (error_code != GL_INVALID_ENUM) 2946 { 2947 std::stringstream error_sstream; 2948 2949 error_sstream << "Invalid error code reported for an invalid " 2950 << getFunctionName(FUNCTION_GL_DRAW_ELEMENTS_INSTANCED_BASE_VERTEX) << " call"; 2951 2952 m_testCtx.getLog() << tcu::TestLog::Message << error_sstream.str().c_str() 2953 << ": expected GL_INVALID_ENUM, got:" 2954 "[" 2955 << error_code << "]" << tcu::TestLog::EndMessage; 2956 2957 TCU_FAIL(error_sstream.str().c_str()); 2958 } 2959 2960 if (m_is_ext_multi_draw_arrays_supported) 2961 { 2962 const glw::GLsizei count = 3; 2963 const glw::GLvoid* offsets[] = { (const glw::GLvoid*)m_draw_call_index_offset }; 2964 2965 gl.multiDrawElementsBaseVertex(GL_GREATER, /* mode */ 2966 &count, GL_UNSIGNED_INT, offsets, 1, /* primcount */ 2967 0); /* basevertex */ 2968 2969 error_code = gl.getError(); 2970 if (error_code != GL_INVALID_ENUM) 2971 { 2972 std::stringstream error_sstream; 2973 2974 error_sstream << "Invalid error code reported for an invalid " 2975 << getFunctionName(FUNCTION_GL_MULTI_DRAW_ELEMENTS_BASE_VERTEX) << " call"; 2976 2977 m_testCtx.getLog() << tcu::TestLog::Message << error_sstream.str().c_str() 2978 << ": expected GL_INVALID_ENUM, got:" 2979 "[" 2980 << error_code << "]" << tcu::TestLog::EndMessage; 2981 2982 TCU_FAIL(error_sstream.str().c_str()); 2983 } 2984 } /* if (m_is_ext_multi_draw_arrays_supported) */ 2985 } /* for (all test iterations) */ 2986 2987 /* Test case passed */ 2988 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2989 2990 return STOP; 2991} 2992 2993/** Constructor. 2994 * 2995 * @param context Rendering context handle. 2996 **/ 2997DrawElementsBaseVertexNegativeInvalidPrimcountArgumentTest::DrawElementsBaseVertexNegativeInvalidPrimcountArgumentTest( 2998 Context& context, const ExtParameters& extParams) 2999 : DrawElementsBaseVertexTestBase( 3000 context, extParams, "invalid_primcount_argument", 3001 "Tries to use invalid 'primcount' argument values for the \"base vertex\" draw calls") 3002{ 3003 /* Left blank on purpose */ 3004} 3005 3006/** Executes test iteration. 3007 * 3008 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 3009 */ 3010tcu::TestNode::IterateResult DrawElementsBaseVertexNegativeInvalidPrimcountArgumentTest::iterate() 3011{ 3012 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3013 3014 /* This test requires presence of GL_EXT_multi_draw_arrays under ES contexts */ 3015 if (glu::isContextTypeES(m_context.getRenderContext().getType())) 3016 { 3017 if (!m_is_ext_multi_draw_arrays_supported) 3018 { 3019 throw tcu::NotSupportedError("GL_EXT_multi_draw_arrays is not supported"); 3020 } 3021 } 3022 3023 /* The test needs to be run in four iterations, where for each iteration we configure the VAO 3024 * in a slightly different manner. 3025 */ 3026 for (int iteration = 0; iteration < 4; ++iteration) 3027 { 3028 bool use_clientside_index_data = ((iteration & (1 << 0)) != 0); 3029 bool use_clientside_vertex_data = ((iteration & (1 << 1)) != 0); 3030 3031 /* OpenGL does not support client-side data. */ 3032 if (!glu::isContextTypeES(m_context.getRenderContext().getType())) 3033 { 3034 if (use_clientside_index_data || use_clientside_vertex_data) 3035 { 3036 continue; 3037 } 3038 } 3039 3040 /* Set up the work environment */ 3041 setUpNegativeTestObjects(use_clientside_vertex_data, use_clientside_index_data); 3042 3043 /* Perform the test */ 3044 const glw::GLsizei count = 3; 3045 glw::GLenum error_code = GL_NO_ERROR; 3046 const glw::GLvoid* offsets[] = { (const glw::GLvoid*)m_draw_call_index_offset }; 3047 3048 gl.multiDrawElementsBaseVertex(GL_TRIANGLES, /* mode */ 3049 &count, GL_UNSIGNED_INT, offsets, -1, /* primcount */ 3050 0); /* basevertex */ 3051 3052 error_code = gl.getError(); 3053 if (error_code != GL_INVALID_VALUE) 3054 { 3055 std::stringstream error_sstream; 3056 3057 error_sstream << "Invalid error code reported for an invalid " 3058 << getFunctionName(FUNCTION_GL_MULTI_DRAW_ELEMENTS_BASE_VERTEX) << " call"; 3059 3060 m_testCtx.getLog() << tcu::TestLog::Message << error_sstream.str().c_str() 3061 << ": expected GL_INVALID_VALUE, got:" 3062 "[" 3063 << error_code << "]" << tcu::TestLog::EndMessage; 3064 3065 TCU_FAIL(error_sstream.str().c_str()); 3066 } 3067 } /* for (all test iterations) */ 3068 3069 /* Test case passed */ 3070 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 3071 3072 return STOP; 3073} 3074 3075/** Constructor. 3076 * 3077 * @param context Rendering context handle. 3078 **/ 3079DrawElementsBaseVertexNegativeInvalidStartEndArgumentsTest::DrawElementsBaseVertexNegativeInvalidStartEndArgumentsTest( 3080 Context& context, const ExtParameters& extParams) 3081 : DrawElementsBaseVertexTestBase(context, extParams, "invalid_start_end_arguments", 3082 "Tries to use invalid 'start' and 'end' argument values for the " 3083 "glDrawRangeElementsBaseVertexEXT() (under ES) or " 3084 "glDrawRangeElementsBaseVertex() (under GL) draw call") 3085{ 3086 /* Left blank on purpose */ 3087} 3088 3089/** Executes test iteration. 3090 * 3091 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 3092 */ 3093tcu::TestNode::IterateResult DrawElementsBaseVertexNegativeInvalidStartEndArgumentsTest::iterate() 3094{ 3095 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3096 3097 /* The test needs to be run in four iterations, where for each iteration we configure the VAO 3098 * in a slightly different manner. 3099 */ 3100 for (int iteration = 0; iteration < 4; ++iteration) 3101 { 3102 bool use_clientside_index_data = ((iteration & (1 << 0)) != 0); 3103 bool use_clientside_vertex_data = ((iteration & (1 << 1)) != 0); 3104 3105 /* OpenGL does not support client-side data. */ 3106 if (!glu::isContextTypeES(m_context.getRenderContext().getType())) 3107 { 3108 if (use_clientside_index_data || use_clientside_vertex_data) 3109 { 3110 continue; 3111 } 3112 } 3113 3114 /* Set up the work environment */ 3115 setUpNegativeTestObjects(use_clientside_vertex_data, use_clientside_index_data); 3116 3117 /* Try to execute the invalid draw call */ 3118 glw::GLenum error_code = GL_NONE; 3119 3120 gl.drawRangeElementsBaseVertex(GL_TRIANGLES, /* mode */ 3121 3, /* start */ 3122 0, /* end */ 3123 3, /* count */ 3124 GL_UNSIGNED_INT, (const glw::GLvoid*)m_draw_call_index_offset, 3125 0); /* basevertex */ 3126 3127 error_code = gl.getError(); 3128 if (error_code != GL_INVALID_VALUE) 3129 { 3130 std::stringstream error_sstream; 3131 3132 error_sstream << "Invalid error code reported for an invalid " 3133 << getFunctionName(FUNCTION_GL_DRAW_RANGE_ELEMENTS_BASE_VERTEX) << " call"; 3134 3135 m_testCtx.getLog() << tcu::TestLog::Message << error_sstream.str().c_str() 3136 << ": expected GL_INVALID_VALUE, got:" 3137 "[" 3138 << error_code << "]" << tcu::TestLog::EndMessage; 3139 3140 TCU_FAIL(error_sstream.str().c_str()); 3141 } 3142 } /* for (all test iterations) */ 3143 3144 /* Test case passed */ 3145 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 3146 3147 return STOP; 3148} 3149 3150/** Constructor. 3151 * 3152 * @param context Rendering context handle. 3153 **/ 3154DrawElementsBaseVertexNegativeInvalidTypeArgumentTest::DrawElementsBaseVertexNegativeInvalidTypeArgumentTest( 3155 Context& context, const ExtParameters& extParams) 3156 : DrawElementsBaseVertexTestBase(context, extParams, "invalid_type_argument", 3157 "Tries to use invalid 'type' argument values for the \"base vertex\" draw calls") 3158{ 3159 /* Left blank on purpose */ 3160} 3161 3162/** Executes test iteration. 3163 * 3164 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 3165 */ 3166tcu::TestNode::IterateResult DrawElementsBaseVertexNegativeInvalidTypeArgumentTest::iterate() 3167{ 3168 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3169 3170 /* The test needs to be run in four iterations, where for each iteration we configure the VAO 3171 * in a slightly different manner. 3172 */ 3173 for (int iteration = 0; iteration < 4; ++iteration) 3174 { 3175 bool use_clientside_index_data = ((iteration & (1 << 0)) != 0); 3176 bool use_clientside_vertex_data = ((iteration & (1 << 1)) != 0); 3177 3178 /* OpenGL does not support client-side data. */ 3179 if (!glu::isContextTypeES(m_context.getRenderContext().getType())) 3180 { 3181 if (use_clientside_index_data || use_clientside_vertex_data) 3182 { 3183 continue; 3184 } 3185 } 3186 3187 /* Set up the work environment */ 3188 setUpNegativeTestObjects(use_clientside_vertex_data, use_clientside_index_data); 3189 3190 /* Try to execute the invalid draw calls */ 3191 glw::GLenum error_code = GL_NONE; 3192 3193 gl.drawElementsBaseVertex(GL_TRIANGLES, /* mode */ 3194 3, /* count */ 3195 GL_NONE, (const glw::GLvoid*)m_draw_call_index_offset, 0); /* basevertex */ 3196 3197 error_code = gl.getError(); 3198 if (error_code != GL_INVALID_ENUM) 3199 { 3200 std::stringstream error_sstream; 3201 3202 error_sstream << "Invalid error code reported for an invalid " 3203 << getFunctionName(FUNCTION_GL_DRAW_ELEMENTS_BASE_VERTEX) << " call"; 3204 3205 m_testCtx.getLog() << tcu::TestLog::Message << error_sstream.str().c_str() 3206 << ": expected GL_INVALID_ENUM, got:" 3207 "[" 3208 << error_code << "]" << tcu::TestLog::EndMessage; 3209 3210 TCU_FAIL(error_sstream.str().c_str()); 3211 } 3212 3213 gl.drawRangeElementsBaseVertex(GL_TRIANGLES, /* mode */ 3214 0, /* start */ 3215 2, /* end */ 3216 3, /* count */ 3217 GL_NONE, (const glw::GLvoid*)m_draw_call_index_offset, 0); /* basevertex */ 3218 3219 error_code = gl.getError(); 3220 if (error_code != GL_INVALID_ENUM) 3221 { 3222 std::stringstream error_sstream; 3223 3224 error_sstream << "Invalid error code reported for an invalid " 3225 << getFunctionName(FUNCTION_GL_DRAW_RANGE_ELEMENTS_BASE_VERTEX) << " call"; 3226 3227 m_testCtx.getLog() << tcu::TestLog::Message << error_sstream.str().c_str() 3228 << ": expected GL_INVALID_ENUM, got:" 3229 "[" 3230 << error_code << "]" << tcu::TestLog::EndMessage; 3231 3232 TCU_FAIL(error_sstream.str().c_str()); 3233 } 3234 3235 gl.drawElementsInstancedBaseVertex(GL_TRIANGLES, /* mode */ 3236 3, /* count */ 3237 GL_NONE, (const glw::GLvoid*)m_draw_call_index_offset, 1, /* instancecount */ 3238 0); /* basevertex */ 3239 3240 error_code = gl.getError(); 3241 if (error_code != GL_INVALID_ENUM) 3242 { 3243 std::stringstream error_sstream; 3244 3245 error_sstream << "Invalid error code reported for an invalid " 3246 << getFunctionName(FUNCTION_GL_DRAW_ELEMENTS_INSTANCED_BASE_VERTEX) << " call"; 3247 3248 m_testCtx.getLog() << tcu::TestLog::Message << error_sstream.str().c_str() 3249 << ": expected GL_INVALID_ENUM, got:" 3250 "[" 3251 << error_code << "]" << tcu::TestLog::EndMessage; 3252 3253 TCU_FAIL(error_sstream.str().c_str()); 3254 } 3255 3256 if (m_is_ext_multi_draw_arrays_supported) 3257 { 3258 const glw::GLsizei count = 3; 3259 const glw::GLvoid* offsets[] = { (const glw::GLvoid*)m_draw_call_index_offset }; 3260 3261 gl.multiDrawElementsBaseVertex(GL_TRIANGLES, /* mode */ 3262 &count, GL_NONE, offsets, 1, /* primcount */ 3263 0); /* basevertex */ 3264 3265 error_code = gl.getError(); 3266 if (error_code != GL_INVALID_ENUM) 3267 { 3268 std::stringstream error_sstream; 3269 3270 error_sstream << "Invalid error code reported for an invalid " 3271 << getFunctionName(FUNCTION_GL_MULTI_DRAW_ELEMENTS_BASE_VERTEX) << " call"; 3272 3273 m_testCtx.getLog() << tcu::TestLog::Message << error_sstream.str().c_str() 3274 << ": expected GL_INVALID_ENUM, got:" 3275 "[" 3276 << error_code << "]" << tcu::TestLog::EndMessage; 3277 3278 TCU_FAIL(error_sstream.str().c_str()); 3279 } 3280 } /* if (m_is_ext_multi_draw_arrays_supported) */ 3281 } /* for (all test iterations) */ 3282 3283 /* Test case passed */ 3284 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 3285 3286 return STOP; 3287} 3288 3289/** Constructor. 3290 * 3291 * @param context Rendering context handle. 3292 **/ 3293DrawElementsBaseVertexNegativeMappedBufferObjectsTest::DrawElementsBaseVertexNegativeMappedBufferObjectsTest( 3294 Context& context, const ExtParameters& extParams) 3295 : DrawElementsBaseVertexTestBase( 3296 context, extParams, "invalid_mapped_bos", 3297 "Tries to use mapped VBO and Index Buffer Object for the \"base vertex\" draw calls") 3298{ 3299 /* Left blank on purpose */ 3300} 3301 3302/** Executes test iteration. 3303 * 3304 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. 3305 */ 3306tcu::TestNode::IterateResult DrawElementsBaseVertexNegativeMappedBufferObjectsTest::iterate() 3307{ 3308 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3309 3310 /* The test needs to be run in four iterations, where for each iteration we configure the VAO 3311 * in a slightly different manner. 3312 */ 3313 for (int iteration = 0; iteration < 4; ++iteration) 3314 { 3315 bool use_clientside_index_data = ((iteration & (1 << 0)) != 0); 3316 bool use_clientside_vertex_data = ((iteration & (1 << 1)) != 0); 3317 3318 /* OpenGL does not support client-side data. */ 3319 if (!glu::isContextTypeES(m_context.getRenderContext().getType())) 3320 { 3321 if (use_clientside_index_data || use_clientside_vertex_data) 3322 { 3323 continue; 3324 } 3325 } 3326 3327 /* Skip the iteration where no array buffer is used */ 3328 if (use_clientside_vertex_data) 3329 { 3330 continue; 3331 } 3332 3333 /* Set up the work environment */ 3334 setUpNegativeTestObjects(use_clientside_vertex_data, use_clientside_index_data); 3335 3336 /* Map the buffer object into process space */ 3337 const glw::GLvoid* bo_ptr = gl.mapBufferRange(GL_ARRAY_BUFFER, 0, /* offset */ 3338 m_bo_negative_data_vertex_size, GL_MAP_READ_BIT); 3339 (void)bo_ptr; 3340 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange() call failed."); 3341 3342 /* Perform draw calls that would otherwise have been valid, if it 3343 * were not for the mapped VBO 3344 */ 3345 glw::GLenum error_code = GL_NONE; 3346 3347 gl.drawElementsBaseVertex(GL_TRIANGLES, 3, /* count */ 3348 GL_UNSIGNED_INT, m_draw_call_index_offset, 0); /* basevertex */ 3349 3350 error_code = gl.getError(); 3351 if (error_code != GL_INVALID_OPERATION) 3352 { 3353 std::stringstream error_sstream; 3354 3355 error_sstream << "Invalid error code generated by " 3356 << getFunctionName(FUNCTION_GL_DRAW_ELEMENTS_BASE_VERTEX); 3357 3358 m_testCtx.getLog() << tcu::TestLog::Message << getFunctionName(FUNCTION_GL_DRAW_ELEMENTS_BASE_VERTEX) 3359 << " returned error code [" << error_code << "] instead of GL_INVALID_OPERATION." 3360 << tcu::TestLog::EndMessage; 3361 3362 TCU_FAIL(error_sstream.str().c_str()); 3363 } /* if (error_code != GL_INVALID_OPERATION) */ 3364 3365 gl.drawElementsInstancedBaseVertex(GL_TRIANGLES, 3, /* count */ 3366 GL_UNSIGNED_INT, m_draw_call_index_offset, 1, /* instancecount */ 3367 0); /* basevertex */ 3368 3369 error_code = gl.getError(); 3370 if (error_code != GL_INVALID_OPERATION) 3371 { 3372 std::stringstream error_sstream; 3373 3374 error_sstream << "Invalid error code generated by " 3375 << getFunctionName(FUNCTION_GL_DRAW_ELEMENTS_INSTANCED_BASE_VERTEX); 3376 3377 m_testCtx.getLog() << tcu::TestLog::Message 3378 << getFunctionName(FUNCTION_GL_DRAW_ELEMENTS_INSTANCED_BASE_VERTEX) 3379 << " returned error code [" << error_code << "] instead of GL_INVALID_OPERATION." 3380 << tcu::TestLog::EndMessage; 3381 3382 TCU_FAIL(error_sstream.str().c_str()); 3383 } 3384 3385 gl.drawRangeElementsBaseVertex(GL_TRIANGLES, 0, 2, /* end */ 3386 3, /* count */ 3387 GL_UNSIGNED_INT, m_draw_call_index_offset, 0); /* basevertex */ 3388 3389 error_code = gl.getError(); 3390 if (error_code != GL_INVALID_OPERATION) 3391 { 3392 std::stringstream error_sstream; 3393 3394 error_sstream << "Invalid error code generated by " 3395 << getFunctionName(FUNCTION_GL_DRAW_RANGE_ELEMENTS_BASE_VERTEX); 3396 3397 m_testCtx.getLog() << tcu::TestLog::Message << getFunctionName(FUNCTION_GL_DRAW_RANGE_ELEMENTS_BASE_VERTEX) 3398 << " returned error code [" << error_code << "] instead of GL_INVALID_OPERATION." 3399 << tcu::TestLog::EndMessage; 3400 3401 TCU_FAIL(error_sstream.str().c_str()); 3402 } 3403 3404 /* Unmap the BO before we proceed */ 3405 gl.unmapBuffer(GL_ARRAY_BUFFER); 3406 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed"); 3407 3408 } /* for (all test iterations) */ 3409 3410 /* Test case passed */ 3411 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 3412 3413 return STOP; 3414} 3415 3416/** Constructor. 3417 * 3418 * @param context Rendering context. 3419 */ 3420DrawElementsBaseVertexTests::DrawElementsBaseVertexTests(glcts::Context& context, const ExtParameters& extParams) 3421 : TestCaseGroupBase(context, extParams, "draw_elements_base_vertex_tests", 3422 "Contains conformance tests that verify ES and GL implementation's support " 3423 "for GL_EXT_draw_elements_base_vertex (ES) and " 3424 "GL_ARB_draw_elements_base_vertex (GL) extensions.") 3425{ 3426} 3427 3428/** Initializes the test group contents. */ 3429void DrawElementsBaseVertexTests::init() 3430{ 3431 addChild(new DrawElementsBaseVertexFunctionalCorrectBaseVertexBehavior(m_context, m_extParams)); 3432 addChild(new DrawElementsBaseVertexFunctionalCorrectBaseVertexBehavior2(m_context, m_extParams)); 3433 addChild(new DrawElementsBaseVertexFunctionalCorrectBaseVertexBehaviorAEPShaderStages(m_context, m_extParams)); 3434 addChild(new DrawElementsBaseVertexFunctionalCorrectBaseVertexBehaviorUnderflow(m_context, m_extParams)); 3435 addChild(new DrawElementsBaseVertexFunctionalCorrectBaseVertexBehaviorOverflow(m_context, m_extParams)); 3436 addChild(new DrawElementsBaseVertexNegativeActiveTransformFeedbackTest(m_context, m_extParams)); 3437 addChild(new DrawElementsBaseVertexNegativeInvalidCountArgumentTest(m_context, m_extParams)); 3438 addChild(new DrawElementsBaseVertexNegativeInvalidInstanceCountArgumentTest(m_context, m_extParams)); 3439 addChild(new DrawElementsBaseVertexNegativeInvalidModeArgumentTest(m_context, m_extParams)); 3440 addChild(new DrawElementsBaseVertexNegativeInvalidPrimcountArgumentTest(m_context, m_extParams)); 3441 addChild(new DrawElementsBaseVertexNegativeInvalidStartEndArgumentsTest(m_context, m_extParams)); 3442 addChild(new DrawElementsBaseVertexNegativeInvalidTypeArgumentTest(m_context, m_extParams)); 3443 addChild(new DrawElementsBaseVertexNegativeMappedBufferObjectsTest(m_context, m_extParams)); 3444} 3445 3446} /* glcts namespace */ 3447