1/*------------------------------------------------------------------------- 2 * OpenGL Conformance Test Suite 3 * ----------------------------- 4 * 5 * Copyright (c) 2015-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 * \file gl3TextureSwizzleTests.cpp 26 * \brief Implements conformance tests for "Texture Swizzle" functionality. 27 */ /*-------------------------------------------------------------------*/ 28 29#include "gl3cTextureSwizzleTests.hpp" 30#include "gluContextInfo.hpp" 31#include "gluStrUtil.hpp" 32#include "glwFunctions.hpp" 33#include "tcuFloat.hpp" 34#include "tcuTestLog.hpp" 35 36#include "deMath.h" 37#include <cmath> 38 39#define ENABLE_DEBUG 0 /* Selects if debug callback is installed */ 40#define FUNCTIONAL_TEST_ALL_FORMATS 1 /* Selects if all formats should be tested */ 41#define FUNCTIONAL_TEST_ALL_TARGETS 1 /* Selects if all targets should be tested */ 42#define FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES 0 /* Selects if all texture access routines should be tested */ 43#define FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS 0 /* Selects if all swizzle combinations should be tested */ 44 45namespace gl3cts 46{ 47namespace TextureSwizzle 48{ 49/* Static constants use by tests */ 50/* One and zero */ 51static const glw::GLhalf data_float16_one[] = { tcu::Float16(1.0).bits() }; 52static const glw::GLhalf data_float16_zero[] = { tcu::Float16(0.0).bits() }; 53static const glw::GLfloat data_float32_one[] = { 1.0f }; 54static const glw::GLfloat data_float32_zero[] = { 0.0f }; 55static const glw::GLbyte data_snorm8_zero[] = { 0 }; 56static const glw::GLbyte data_snorm8_one[] = { 127 }; 57static const glw::GLshort data_snorm16_one[] = { 32767 }; 58static const glw::GLshort data_snorm16_zero[] = { 0 }; 59static const glw::GLubyte data_unorm8_one[] = { 255 }; 60static const glw::GLubyte data_unorm8_zero[] = { 0 }; 61static const glw::GLushort data_unorm16_one[] = { 65535 }; 62static const glw::GLushort data_unorm16_zero[] = { 0 }; 63static const glw::GLbyte data_sint8_zero[] = { 0 }; 64static const glw::GLbyte data_sint8_one[] = { 1 }; 65static const glw::GLshort data_sint16_one[] = { 1 }; 66static const glw::GLshort data_sint16_zero[] = { 0 }; 67static const glw::GLint data_sint32_one[] = { 1 }; 68static const glw::GLint data_sint32_zero[] = { 0 }; 69static const glw::GLubyte data_uint8_one[] = { 1 }; 70static const glw::GLubyte data_uint8_zero[] = { 0 }; 71static const glw::GLushort data_uint16_one[] = { 1 }; 72static const glw::GLushort data_uint16_zero[] = { 0 }; 73static const glw::GLuint data_uint32_one[] = { 1 }; 74static const glw::GLuint data_uint32_zero[] = { 0 }; 75 76/* Source and expected data */ 77static const glw::GLubyte src_data_r8[] = { 123 }; 78static const glw::GLbyte src_data_r8_snorm[] = { -123 }; 79static const glw::GLushort src_data_r16[] = { 12345 }; 80static const glw::GLshort src_data_r16_snorm[] = { -12345 }; 81static const glw::GLubyte src_data_rg8[] = { 123, 231 }; 82static const glw::GLbyte src_data_rg8_snorm[] = { -123, -23 }; 83static const glw::GLushort src_data_rg16[] = { 12345, 54321 }; 84static const glw::GLshort src_data_rg16_snorm[] = { -12345, -23451 }; 85static const glw::GLubyte src_data_r3_g3_b2[] = { 236 }; /* 255, 109, 0 */ 86static const glw::GLushort src_data_rgb4[] = { 64832 }; /* 5_6_5: 255, 170, 0 */ 87static const glw::GLushort src_data_rgb5[] = { 64832 }; 88static const glw::GLubyte src_data_rgb8[] = { 3, 2, 1 }; 89static const glw::GLbyte src_data_rgb8_snorm[] = { -1, -2, -3 }; 90static const glw::GLushort src_data_rgb16[] = { 65535, 32767, 16383 }; 91static const glw::GLshort src_data_rgb16_snorm[] = { -32767, -16383, -8191 }; 92static const glw::GLushort src_data_rgba4[] = { 64005 }; /* 255, 170, 0, 85 */ 93static const glw::GLushort src_data_rgb5_a1[] = { 64852 }; 94static const glw::GLubyte src_data_rgba8[] = { 0, 64, 128, 255 }; 95static const glw::GLbyte src_data_rgba8_snorm[] = { -127, -63, -32, -16 }; 96static const glw::GLuint src_data_rgb10_a2[] = { 4291823615u }; 97static const glw::GLushort exp_data_rgb10_a2ui[] = { 1023, 256, 511, 3 }; 98static const glw::GLushort src_data_rgba16[] = { 65535, 32767, 16383, 8191 }; 99static const glw::GLshort src_data_rgba16_snorm[] = { -32767, -16383, -8191, -4091 }; 100static const glw::GLubyte exp_data_srgb8_alpha8[] = { 13, 1, 255, 32 }; /* See 4.5 core 8.24 */ 101static const glw::GLubyte src_data_srgb8_alpha8[] = { 64, 8, 255, 32 }; 102static const glw::GLhalf src_data_r16f[] = { tcu::Float16(1.0).bits() }; 103static const glw::GLhalf src_data_rg16f[] = { tcu::Float16(1.0).bits(), tcu::Float16(-1.0).bits() }; 104static const glw::GLhalf src_data_rgb16f[] = { tcu::Float16(1.0).bits(), tcu::Float16(-1.0).bits(), 105 tcu::Float16(2.0).bits() }; 106static const glw::GLhalf src_data_rgba16f[] = { tcu::Float16(1.0).bits(), tcu::Float16(-1.0).bits(), 107 tcu::Float16(2.0).bits(), tcu::Float16(-2.0).bits() }; 108static const glw::GLfloat src_data_r32f[] = { 1.0f }; 109static const glw::GLfloat src_data_rg32f[] = { 1.0f, -1.0f }; 110static const glw::GLfloat src_data_rgb32f[] = { 1.0f, -1.0f, 2.0f }; 111static const glw::GLfloat src_data_rgba32f[] = { 1.0f, -1.0f, 2.0f, -2.0f }; 112 113static const tcu::Float<deUint32, 5, 6, 15, tcu::FLOAT_SUPPORT_DENORM> r11f(0.5); 114static const tcu::Float<deUint32, 5, 6, 15, tcu::FLOAT_SUPPORT_DENORM> g11f(0.75); 115static const tcu::Float<deUint32, 5, 5, 15, tcu::FLOAT_SUPPORT_DENORM> b10f(0.25); 116 117static const glw::GLhalf exp_data_r11f_g11f_b10f[] = { tcu::Float16(0.5).bits(), tcu::Float16(0.75).bits(), 118 tcu::Float16(0.25).bits() }; 119static const glw::GLuint src_data_r11f_g11f_b10f[] = { (r11f.bits()) | (g11f.bits() << 11) | (b10f.bits() << 22) }; 120static const glw::GLfloat exp_data_rgb9_e5[] = { 31.0f, 23.0f, 32.0f }; 121static const glw::GLuint src_data_rgb9_e5[] = { 2885775608u }; 122static const glw::GLbyte src_data_r8i[] = { -127 }; 123static const glw::GLubyte src_data_r8ui[] = { 128 }; 124static const glw::GLshort src_data_r16i[] = { -32767 }; 125static const glw::GLushort src_data_r16ui[] = { 32768 }; 126static const glw::GLint src_data_r32i[] = { -1 }; 127static const glw::GLuint src_data_r32ui[] = { 1 }; 128static const glw::GLbyte src_data_rg8i[] = { -127, -126 }; 129static const glw::GLubyte src_data_rg8ui[] = { 128, 129 }; 130static const glw::GLshort src_data_rg16i[] = { -32767, -32766 }; 131static const glw::GLushort src_data_rg16ui[] = { 32768, 32769 }; 132static const glw::GLint src_data_rg32i[] = { -1, -2 }; 133static const glw::GLuint src_data_rg32ui[] = { 1, 2 }; 134static const glw::GLbyte src_data_rgb8i[] = { -127, -126, -125 }; 135static const glw::GLubyte src_data_rgb8ui[] = { 128, 129, 130 }; 136static const glw::GLshort src_data_rgb16i[] = { -32767, -32766, -32765 }; 137static const glw::GLushort src_data_rgb16ui[] = { 32768, 32769, 32770 }; 138static const glw::GLint src_data_rgb32i[] = { -1, -2, -3 }; 139static const glw::GLuint src_data_rgb32ui[] = { 1, 2, 3 }; 140static const glw::GLbyte src_data_rgba8i[] = { -127, -126, -125, -124 }; 141static const glw::GLubyte src_data_rgba8ui[] = { 128, 129, 130, 131 }; 142static const glw::GLshort src_data_rgba16i[] = { -32767, -32766, -32765, -32764 }; 143static const glw::GLushort src_data_rgba16ui[] = { 32768, 32769, 32770, 32771 }; 144static const glw::GLint src_data_rgba32i[] = { -1, -2, -3, -4 }; 145static const glw::GLuint src_data_rgba32ui[] = { 1, 2, 3, 4 }; 146static const glw::GLushort src_data_depth_component16[] = { 32768 }; 147static const glw::GLfloat exp_data_depth_component32[] = { 1.0f }; 148static const glw::GLuint src_data_depth_component32[] = { 4294967295u }; 149static const glw::GLfloat src_data_depth_component32f[] = { 0.75f }; 150static const glw::GLuint src_data_depth24_stencil8[] = { 4294967041u /* 1.0, 1 */ }; 151static const glw::GLuint src_data_depth32f_stencil8[] = { 1065353216, 1 /* 1.0f, 1 */ }; 152 153/* Texture channels */ 154static const glw::GLchar* channels[] = { "r", "g", "b", "a" }; 155 156/* Enumerations of cube map faces */ 157static const glw::GLenum cube_map_faces[] = { GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 158 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, GL_TEXTURE_CUBE_MAP_POSITIVE_X, 159 GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z }; 160static const size_t n_cube_map_faces = sizeof(cube_map_faces) / sizeof(cube_map_faces[0]); 161 162/* Swizzle states */ 163static const glw::GLenum states[] = { GL_TEXTURE_SWIZZLE_R, GL_TEXTURE_SWIZZLE_G, GL_TEXTURE_SWIZZLE_B, 164 GL_TEXTURE_SWIZZLE_A }; 165static const size_t n_states = sizeof(states) / sizeof(states[0]); 166 167/* Sampler descriptor */ 168struct _sampler 169{ 170 const glw::GLchar* m_basic_type; 171 const glw::GLchar* m_sampler_prefix; 172}; 173static const _sampler isampler = { "int", "i" }; 174static const _sampler usampler = { "uint", "u" }; 175static const _sampler sampler = { "float", "" }; 176 177/* Output channel descriptor */ 178struct _out_ch_desc 179{ 180 glw::GLenum m_internal_format; 181 const glw::GLvoid* m_expected_data; 182}; 183 184/* Output channel descriptors for one and zero */ 185static const _out_ch_desc zero_ch = { GL_ZERO, 0 }; 186static const _out_ch_desc one_ch = { GL_ONE, 0 }; 187static const _out_ch_desc float16_zero = { GL_R16F, data_float16_zero }; 188static const _out_ch_desc float16_one = { GL_R16F, data_float16_one }; 189static const _out_ch_desc float32_zero = { GL_R32F, data_float32_zero }; 190static const _out_ch_desc float32_one = { GL_R32F, data_float32_one }; 191static const _out_ch_desc sint8_zero = { GL_R8I, data_sint8_zero }; 192static const _out_ch_desc sint8_one = { GL_R8I, data_sint8_one }; 193static const _out_ch_desc sint16_zero = { GL_R16I, data_sint16_zero }; 194static const _out_ch_desc sint16_one = { GL_R16I, data_sint16_one }; 195static const _out_ch_desc sint32_zero = { GL_R32I, data_sint32_zero }; 196static const _out_ch_desc sint32_one = { GL_R32I, data_sint32_one }; 197static const _out_ch_desc snorm8_zero = { GL_R8_SNORM, data_snorm8_zero }; 198static const _out_ch_desc snorm8_one = { GL_R8_SNORM, data_snorm8_one }; 199static const _out_ch_desc snorm16_zero = { GL_R16_SNORM, data_snorm16_zero }; 200static const _out_ch_desc snorm16_one = { GL_R16_SNORM, data_snorm16_one }; 201static const _out_ch_desc uint8_zero = { GL_R8UI, data_uint8_zero }; 202static const _out_ch_desc uint8_one = { GL_R8UI, data_uint8_one }; 203static const _out_ch_desc uint16_zero = { GL_R16UI, data_uint16_zero }; 204static const _out_ch_desc uint16_one = { GL_R16UI, data_uint16_one }; 205static const _out_ch_desc uint32_zero = { GL_R32UI, data_uint32_zero }; 206static const _out_ch_desc uint32_one = { GL_R32UI, data_uint32_one }; 207static const _out_ch_desc unorm8_zero = { GL_R8, data_unorm8_zero }; 208static const _out_ch_desc unorm8_one = { GL_R8, data_unorm8_one }; 209static const _out_ch_desc unorm16_zero = { GL_R16, data_unorm16_zero }; 210static const _out_ch_desc unorm16_one = { GL_R16, data_unorm16_one }; 211 212/* Texture format descriptor. Maps texture format with output channel descriptors, source data and sampler descriptor */ 213struct _texture_format 214{ 215 const glu::ApiType m_minimum_gl_context; 216 glw::GLenum m_internal_format; 217 glw::GLenum m_format; 218 glw::GLenum m_type; 219 glw::GLenum m_ds_mode; 220 const _sampler& m_sampler; 221 _out_ch_desc m_red_ch; 222 _out_ch_desc m_green_ch; 223 _out_ch_desc m_blue_ch; 224 _out_ch_desc m_alpha_ch; 225 const glw::GLvoid* m_source_data; 226 const _out_ch_desc& m_zero_ch; 227 const _out_ch_desc& m_one_ch; 228}; 229static const _texture_format texture_formats[] = { 230 /* 0 */ { glu::ApiType::core(3, 0), 231 GL_R8, 232 GL_RED, 233 GL_UNSIGNED_BYTE, 234 GL_DEPTH_COMPONENT, 235 sampler, 236 { GL_R8, DE_NULL }, 237 zero_ch, 238 zero_ch, 239 one_ch, 240 src_data_r8, 241 unorm8_zero, 242 unorm8_one }, 243 { glu::ApiType::core(3, 1), 244 GL_R8_SNORM, 245 GL_RED, 246 GL_BYTE, 247 GL_DEPTH_COMPONENT, 248 sampler, 249 { GL_R8_SNORM, DE_NULL }, 250 zero_ch, 251 zero_ch, 252 one_ch, 253 src_data_r8_snorm, 254 snorm8_zero, 255 snorm8_one }, 256 { glu::ApiType::core(3, 0), 257 GL_R16, 258 GL_RED, 259 GL_UNSIGNED_SHORT, 260 GL_DEPTH_COMPONENT, 261 sampler, 262 { GL_R16, DE_NULL }, 263 zero_ch, 264 zero_ch, 265 one_ch, 266 src_data_r16, 267 unorm16_zero, 268 unorm16_one }, 269 { glu::ApiType::core(3, 1), 270 GL_R16_SNORM, 271 GL_RED, 272 GL_SHORT, 273 GL_DEPTH_COMPONENT, 274 sampler, 275 { GL_R16_SNORM, DE_NULL }, 276 zero_ch, 277 zero_ch, 278 one_ch, 279 src_data_r16_snorm, 280 snorm16_zero, 281 snorm16_one }, 282 { glu::ApiType::core(3, 0), 283 GL_RG8, 284 GL_RG, 285 GL_UNSIGNED_BYTE, 286 GL_DEPTH_COMPONENT, 287 sampler, 288 { GL_R8, DE_NULL }, 289 { GL_R8, DE_NULL }, 290 zero_ch, 291 one_ch, 292 src_data_rg8, 293 unorm8_zero, 294 unorm8_one }, 295 { glu::ApiType::core(3, 1), 296 GL_RG8_SNORM, 297 GL_RG, 298 GL_BYTE, 299 GL_DEPTH_COMPONENT, 300 sampler, 301 { GL_R8_SNORM, DE_NULL }, 302 { GL_R8_SNORM, DE_NULL }, 303 zero_ch, 304 one_ch, 305 src_data_rg8_snorm, 306 snorm8_zero, 307 snorm8_one }, 308 { glu::ApiType::core(3, 0), 309 GL_RG16, 310 GL_RG, 311 GL_UNSIGNED_SHORT, 312 GL_DEPTH_COMPONENT, 313 sampler, 314 { GL_R16, DE_NULL }, 315 { GL_R16, DE_NULL }, 316 zero_ch, 317 one_ch, 318 src_data_rg16, 319 unorm16_zero, 320 unorm16_one }, 321 { glu::ApiType::core(3, 1), 322 GL_RG16_SNORM, 323 GL_RG, 324 GL_SHORT, 325 GL_DEPTH_COMPONENT, 326 sampler, 327 { GL_R16_SNORM, DE_NULL }, 328 { GL_R16_SNORM, DE_NULL }, 329 zero_ch, 330 one_ch, 331 src_data_rg16_snorm, 332 snorm16_zero, 333 snorm16_one }, 334 /* 8 */ { glu::ApiType::core(4, 4), 335 GL_R3_G3_B2, 336 GL_RGB, 337 GL_UNSIGNED_BYTE_3_3_2, 338 GL_DEPTH_COMPONENT, 339 sampler, 340 { GL_R8, DE_NULL }, 341 { GL_R8, DE_NULL }, 342 { GL_R8, DE_NULL }, 343 one_ch, 344 src_data_r3_g3_b2, 345 unorm8_zero, 346 unorm8_one }, 347 { glu::ApiType::core(4, 4), 348 GL_RGB4, 349 GL_RGB, 350 GL_UNSIGNED_SHORT_5_6_5, 351 GL_DEPTH_COMPONENT, 352 sampler, 353 { GL_R8, DE_NULL }, 354 { GL_R8, DE_NULL }, 355 { GL_R8, DE_NULL }, 356 one_ch, 357 src_data_rgb4, 358 unorm8_zero, 359 unorm8_one }, 360 { glu::ApiType::core(4, 4), 361 GL_RGB5, 362 GL_RGB, 363 GL_UNSIGNED_SHORT_5_6_5, 364 GL_DEPTH_COMPONENT, 365 sampler, 366 { GL_R8, DE_NULL }, 367 { GL_R8, DE_NULL }, 368 { GL_R8, DE_NULL }, 369 one_ch, 370 src_data_rgb5, 371 unorm8_zero, 372 unorm8_one }, 373 { glu::ApiType::core(3, 0), 374 GL_RGB8, 375 GL_RGB, 376 GL_UNSIGNED_BYTE, 377 GL_DEPTH_COMPONENT, 378 sampler, 379 { GL_R8, DE_NULL }, 380 { GL_R8, DE_NULL }, 381 { GL_R8, DE_NULL }, 382 one_ch, 383 src_data_rgb8, 384 unorm8_zero, 385 unorm8_one }, 386 { glu::ApiType::core(3, 1), 387 GL_RGB8_SNORM, 388 GL_RGB, 389 GL_BYTE, 390 GL_DEPTH_COMPONENT, 391 sampler, 392 { GL_R8_SNORM, DE_NULL }, 393 { GL_R8_SNORM, DE_NULL }, 394 { GL_R8_SNORM, DE_NULL }, 395 one_ch, 396 src_data_rgb8_snorm, 397 snorm8_zero, 398 snorm8_one }, 399 { glu::ApiType::core(4, 4), 400 GL_RGB10, 401 GL_RGB, 402 GL_UNSIGNED_SHORT, 403 GL_DEPTH_COMPONENT, 404 sampler, 405 { GL_R16, DE_NULL }, 406 { GL_R16, DE_NULL }, 407 { GL_R16, DE_NULL }, 408 one_ch, 409 src_data_rgb16, 410 unorm16_zero, 411 unorm16_one }, 412 { glu::ApiType::core(4, 4), 413 GL_RGB12, 414 GL_RGB, 415 GL_UNSIGNED_SHORT, 416 GL_DEPTH_COMPONENT, 417 sampler, 418 { GL_R16, DE_NULL }, 419 { GL_R16, DE_NULL }, 420 { GL_R16, DE_NULL }, 421 one_ch, 422 src_data_rgb16, 423 unorm16_zero, 424 unorm16_one }, 425 { glu::ApiType::core(3, 0), 426 GL_RGB16, 427 GL_RGB, 428 GL_UNSIGNED_SHORT, 429 GL_DEPTH_COMPONENT, 430 sampler, 431 { GL_R16, DE_NULL }, 432 { GL_R16, DE_NULL }, 433 { GL_R16, DE_NULL }, 434 one_ch, 435 src_data_rgb16, 436 unorm16_zero, 437 unorm16_one }, 438 /* 16 */ { glu::ApiType::core(3, 1), 439 GL_RGB16_SNORM, 440 GL_RGB, 441 GL_SHORT, 442 GL_DEPTH_COMPONENT, 443 sampler, 444 { GL_R16_SNORM, DE_NULL }, 445 { GL_R16_SNORM, DE_NULL }, 446 { GL_R16_SNORM, DE_NULL }, 447 one_ch, 448 src_data_rgb16_snorm, 449 snorm16_zero, 450 snorm16_one }, 451 { glu::ApiType::core(4, 4), 452 GL_RGBA2, 453 GL_RGBA, 454 GL_UNSIGNED_SHORT_4_4_4_4, 455 GL_DEPTH_COMPONENT, 456 sampler, 457 { GL_R8, DE_NULL }, 458 { GL_R8, DE_NULL }, 459 { GL_R8, DE_NULL }, 460 { GL_R8, DE_NULL }, 461 src_data_rgba4, 462 unorm8_zero, 463 unorm8_one }, 464 { glu::ApiType::core(4, 2), 465 GL_RGBA4, 466 GL_RGBA, 467 GL_UNSIGNED_SHORT_4_4_4_4, 468 GL_DEPTH_COMPONENT, 469 sampler, 470 { GL_R8, DE_NULL }, 471 { GL_R8, DE_NULL }, 472 { GL_R8, DE_NULL }, 473 { GL_R8, DE_NULL }, 474 src_data_rgba4, 475 unorm8_zero, 476 unorm8_one }, 477 { glu::ApiType::core(4, 2), 478 GL_RGB5_A1, 479 GL_RGBA, 480 GL_UNSIGNED_SHORT_5_5_5_1, 481 GL_DEPTH_COMPONENT, 482 sampler, 483 { GL_R8, DE_NULL }, 484 { GL_R8, DE_NULL }, 485 { GL_R8, DE_NULL }, 486 { GL_R8, DE_NULL }, 487 src_data_rgb5_a1, 488 unorm8_zero, 489 unorm8_one }, 490 { glu::ApiType::core(3, 0), 491 GL_RGBA8, 492 GL_RGBA, 493 GL_UNSIGNED_BYTE, 494 GL_DEPTH_COMPONENT, 495 sampler, 496 { GL_R8, DE_NULL }, 497 { GL_R8, DE_NULL }, 498 { GL_R8, DE_NULL }, 499 { GL_R8, DE_NULL }, 500 src_data_rgba8, 501 unorm8_zero, 502 unorm8_one }, 503 { glu::ApiType::core(3, 1), 504 GL_RGBA8_SNORM, 505 GL_RGBA, 506 GL_BYTE, 507 GL_DEPTH_COMPONENT, 508 sampler, 509 { GL_R8_SNORM, DE_NULL }, 510 { GL_R8_SNORM, DE_NULL }, 511 { GL_R8_SNORM, DE_NULL }, 512 { GL_R8_SNORM, DE_NULL }, 513 src_data_rgba8_snorm, 514 snorm8_zero, 515 snorm8_one }, 516 { glu::ApiType::core(3, 0), 517 GL_RGB10_A2, 518 GL_RGBA, 519 GL_UNSIGNED_INT_10_10_10_2, 520 GL_DEPTH_COMPONENT, 521 sampler, 522 { GL_R16, DE_NULL }, 523 { GL_R16, DE_NULL }, 524 { GL_R16, DE_NULL }, 525 { GL_R16, DE_NULL }, 526 src_data_rgb10_a2, 527 unorm16_zero, 528 unorm16_one }, 529 { glu::ApiType::core(3, 3), 530 GL_RGB10_A2UI, 531 GL_RGBA_INTEGER, 532 GL_UNSIGNED_INT_10_10_10_2, 533 GL_DEPTH_COMPONENT, 534 usampler, 535 { GL_R16UI, exp_data_rgb10_a2ui + 0 }, 536 { GL_R16UI, exp_data_rgb10_a2ui + 1 }, 537 { GL_R16UI, exp_data_rgb10_a2ui + 2 }, 538 { GL_R16UI, exp_data_rgb10_a2ui + 3 }, 539 src_data_rgb10_a2, 540 uint16_zero, 541 uint16_one }, 542 /* 24 */ { glu::ApiType::core(4, 4), 543 GL_RGBA12, 544 GL_RGBA, 545 GL_UNSIGNED_SHORT, 546 GL_DEPTH_COMPONENT, 547 sampler, 548 { GL_R16, DE_NULL }, 549 { GL_R16, DE_NULL }, 550 { GL_R16, DE_NULL }, 551 { GL_R16, DE_NULL }, 552 src_data_rgba16, 553 unorm16_zero, 554 unorm16_one }, 555 { glu::ApiType::core(3, 0), 556 GL_RGBA16, 557 GL_RGBA, 558 GL_UNSIGNED_SHORT, 559 GL_DEPTH_COMPONENT, 560 sampler, 561 { GL_R16, DE_NULL }, 562 { GL_R16, DE_NULL }, 563 { GL_R16, DE_NULL }, 564 { GL_R16, DE_NULL }, 565 src_data_rgba16, 566 unorm16_zero, 567 unorm16_one }, 568 { glu::ApiType::core(3, 1), 569 GL_RGBA16_SNORM, 570 GL_RGBA, 571 GL_SHORT, 572 GL_DEPTH_COMPONENT, 573 sampler, 574 { GL_R16_SNORM, DE_NULL }, 575 { GL_R16_SNORM, DE_NULL }, 576 { GL_R16_SNORM, DE_NULL }, 577 { GL_R16_SNORM, src_data_rgba16_snorm + 3 }, 578 src_data_rgba16_snorm, 579 snorm16_zero, 580 snorm16_one }, 581 { glu::ApiType::core(3, 0), 582 GL_SRGB8, 583 GL_RGB, 584 GL_UNSIGNED_BYTE, 585 GL_DEPTH_COMPONENT, 586 sampler, 587 { GL_R8, exp_data_srgb8_alpha8 + 0 }, 588 { GL_R8, exp_data_srgb8_alpha8 + 1 }, 589 { GL_R8, exp_data_srgb8_alpha8 + 2 }, 590 one_ch, 591 src_data_srgb8_alpha8, 592 unorm8_zero, 593 unorm8_one }, 594 { glu::ApiType::core(3, 0), 595 GL_SRGB8_ALPHA8, 596 GL_RGBA, 597 GL_UNSIGNED_BYTE, 598 GL_DEPTH_COMPONENT, 599 sampler, 600 { GL_R8, exp_data_srgb8_alpha8 + 0 }, 601 { GL_R8, exp_data_srgb8_alpha8 + 1 }, 602 { GL_R8, exp_data_srgb8_alpha8 + 2 }, 603 { GL_R8, exp_data_srgb8_alpha8 + 3 }, 604 src_data_srgb8_alpha8, 605 unorm8_zero, 606 unorm8_one }, 607 { glu::ApiType::core(3, 0), 608 GL_R16F, 609 GL_RED, 610 GL_HALF_FLOAT, 611 GL_DEPTH_COMPONENT, 612 sampler, 613 { GL_R16F, src_data_r16f + 0 }, 614 zero_ch, 615 zero_ch, 616 one_ch, 617 src_data_r16f, 618 float16_zero, 619 float16_one }, 620 { glu::ApiType::core(3, 0), 621 GL_RG16F, 622 GL_RG, 623 GL_HALF_FLOAT, 624 GL_DEPTH_COMPONENT, 625 sampler, 626 { GL_R16F, src_data_rg16f + 0 }, 627 { GL_R16F, src_data_rg16f + 1 }, 628 zero_ch, 629 one_ch, 630 src_data_rg16f, 631 float16_zero, 632 float16_one }, 633 { glu::ApiType::core(3, 0), 634 GL_RGB16F, 635 GL_RGB, 636 GL_HALF_FLOAT, 637 GL_DEPTH_COMPONENT, 638 sampler, 639 { GL_R16F, src_data_rgb16f + 0 }, 640 { GL_R16F, src_data_rgb16f + 1 }, 641 { GL_R16F, src_data_rgb16f + 2 }, 642 one_ch, 643 src_data_rgb16f, 644 float16_zero, 645 float16_one }, 646 /* 32 */ { glu::ApiType::core(3, 0), 647 GL_RGBA16F, 648 GL_RGBA, 649 GL_HALF_FLOAT, 650 GL_DEPTH_COMPONENT, 651 sampler, 652 { GL_R16F, src_data_rgba16f + 0 }, 653 { GL_R16F, src_data_rgba16f + 1 }, 654 { GL_R16F, src_data_rgba16f + 2 }, 655 { GL_R16F, src_data_rgba16f + 3 }, 656 src_data_rgba16f, 657 float16_zero, 658 float16_one }, 659 { glu::ApiType::core(3, 0), 660 GL_R32F, 661 GL_RED, 662 GL_FLOAT, 663 GL_DEPTH_COMPONENT, 664 sampler, 665 { GL_R32F, src_data_r32f + 0 }, 666 zero_ch, 667 zero_ch, 668 one_ch, 669 src_data_r32f, 670 float32_zero, 671 float32_one }, 672 { glu::ApiType::core(3, 0), 673 GL_RG32F, 674 GL_RG, 675 GL_FLOAT, 676 GL_DEPTH_COMPONENT, 677 sampler, 678 { GL_R32F, src_data_rg32f + 0 }, 679 { GL_R32F, src_data_rg32f + 1 }, 680 zero_ch, 681 one_ch, 682 src_data_rg32f, 683 float32_zero, 684 float32_one }, 685 { glu::ApiType::core(3, 0), 686 GL_RGB32F, 687 GL_RGB, 688 GL_FLOAT, 689 GL_DEPTH_COMPONENT, 690 sampler, 691 { GL_R32F, src_data_rgb32f + 0 }, 692 { GL_R32F, src_data_rgb32f + 1 }, 693 { GL_R32F, src_data_rgb32f + 2 }, 694 one_ch, 695 src_data_rgb32f, 696 float32_zero, 697 float32_one }, 698 { glu::ApiType::core(3, 0), 699 GL_RGBA32F, 700 GL_RGBA, 701 GL_FLOAT, 702 GL_DEPTH_COMPONENT, 703 sampler, 704 { GL_R32F, src_data_rgba32f + 0 }, 705 { GL_R32F, src_data_rgba32f + 1 }, 706 { GL_R32F, src_data_rgba32f + 2 }, 707 { GL_R32F, src_data_rgba32f + 3 }, 708 src_data_rgba32f, 709 float32_zero, 710 float32_one }, 711 { glu::ApiType::core(3, 0), 712 GL_R11F_G11F_B10F, 713 GL_RGB, 714 GL_UNSIGNED_INT_10F_11F_11F_REV, 715 GL_DEPTH_COMPONENT, 716 sampler, 717 { GL_R16F, exp_data_r11f_g11f_b10f + 0 }, 718 { GL_R16F, exp_data_r11f_g11f_b10f + 1 }, 719 { GL_R16F, exp_data_r11f_g11f_b10f + 2 }, 720 one_ch, 721 src_data_r11f_g11f_b10f, 722 float16_zero, 723 float16_one }, 724 { glu::ApiType::core(3, 0), 725 GL_RGB9_E5, 726 GL_RGB, 727 GL_UNSIGNED_INT_5_9_9_9_REV, 728 GL_DEPTH_COMPONENT, 729 sampler, 730 { GL_R32F, exp_data_rgb9_e5 + 0 }, 731 { GL_R32F, exp_data_rgb9_e5 + 1 }, 732 { GL_R32F, exp_data_rgb9_e5 + 2 }, 733 one_ch, 734 src_data_rgb9_e5, 735 float32_zero, 736 float32_one }, 737 { glu::ApiType::core(3, 0), 738 GL_R8I, 739 GL_RED_INTEGER, 740 GL_BYTE, 741 GL_DEPTH_COMPONENT, 742 isampler, 743 { GL_R8I, src_data_r8i }, 744 zero_ch, 745 zero_ch, 746 one_ch, 747 src_data_r8i, 748 sint8_zero, 749 sint8_one }, 750 /* 40 */ { glu::ApiType::core(3, 0), 751 GL_R8UI, 752 GL_RED_INTEGER, 753 GL_UNSIGNED_BYTE, 754 GL_DEPTH_COMPONENT, 755 usampler, 756 { GL_R8UI, src_data_r8ui }, 757 zero_ch, 758 zero_ch, 759 one_ch, 760 src_data_r8ui, 761 uint8_zero, 762 uint8_one }, 763 { glu::ApiType::core(3, 0), 764 GL_R16I, 765 GL_RED_INTEGER, 766 GL_SHORT, 767 GL_DEPTH_COMPONENT, 768 isampler, 769 { GL_R16I, src_data_r16i }, 770 zero_ch, 771 zero_ch, 772 one_ch, 773 src_data_r16i, 774 sint16_zero, 775 sint16_one }, 776 { glu::ApiType::core(3, 0), 777 GL_R16UI, 778 GL_RED_INTEGER, 779 GL_UNSIGNED_SHORT, 780 GL_DEPTH_COMPONENT, 781 usampler, 782 { GL_R16UI, src_data_r16ui }, 783 zero_ch, 784 zero_ch, 785 one_ch, 786 src_data_r16ui, 787 uint16_zero, 788 uint16_one }, 789 { glu::ApiType::core(3, 0), 790 GL_R32I, 791 GL_RED_INTEGER, 792 GL_INT, 793 GL_DEPTH_COMPONENT, 794 isampler, 795 { GL_R32I, src_data_r32i }, 796 zero_ch, 797 zero_ch, 798 one_ch, 799 src_data_r32i, 800 sint32_zero, 801 sint32_one }, 802 { glu::ApiType::core(3, 0), 803 GL_R32UI, 804 GL_RED_INTEGER, 805 GL_UNSIGNED_INT, 806 GL_DEPTH_COMPONENT, 807 usampler, 808 { GL_R32UI, src_data_r32ui }, 809 zero_ch, 810 zero_ch, 811 one_ch, 812 src_data_r32ui, 813 uint32_zero, 814 uint32_one }, 815 { glu::ApiType::core(3, 0), 816 GL_RG8I, 817 GL_RG_INTEGER, 818 GL_BYTE, 819 GL_DEPTH_COMPONENT, 820 isampler, 821 { GL_R8I, src_data_rg8i + 0 }, 822 { GL_R8I, src_data_rg8i + 1 }, 823 zero_ch, 824 one_ch, 825 src_data_rg8i, 826 sint8_zero, 827 sint8_one }, 828 { glu::ApiType::core(3, 0), 829 GL_RG8UI, 830 GL_RG_INTEGER, 831 GL_UNSIGNED_BYTE, 832 GL_DEPTH_COMPONENT, 833 usampler, 834 { GL_R8UI, src_data_rg8ui + 0 }, 835 { GL_R8UI, src_data_rg8ui + 1 }, 836 zero_ch, 837 one_ch, 838 src_data_rg8ui, 839 uint8_zero, 840 uint8_one }, 841 { glu::ApiType::core(3, 0), 842 GL_RG16I, 843 GL_RG_INTEGER, 844 GL_SHORT, 845 GL_DEPTH_COMPONENT, 846 isampler, 847 { GL_R16I, src_data_rg16i + 0 }, 848 { GL_R16I, src_data_rg16i + 1 }, 849 zero_ch, 850 one_ch, 851 src_data_rg16i, 852 sint16_zero, 853 sint16_one }, 854 /* 48 */ { glu::ApiType::core(3, 0), 855 GL_RG16UI, 856 GL_RG_INTEGER, 857 GL_UNSIGNED_SHORT, 858 GL_DEPTH_COMPONENT, 859 usampler, 860 { GL_R16UI, src_data_rg16ui + 0 }, 861 { GL_R16UI, src_data_rg16ui + 1 }, 862 zero_ch, 863 one_ch, 864 src_data_rg16ui, 865 uint16_zero, 866 uint16_one }, 867 { glu::ApiType::core(3, 0), 868 GL_RG32I, 869 GL_RG_INTEGER, 870 GL_INT, 871 GL_DEPTH_COMPONENT, 872 isampler, 873 { GL_R32I, src_data_rg32i + 0 }, 874 { GL_R32I, src_data_rg32i + 1 }, 875 zero_ch, 876 one_ch, 877 src_data_rg32i, 878 sint32_zero, 879 sint32_one }, 880 { glu::ApiType::core(3, 0), 881 GL_RG32UI, 882 GL_RG_INTEGER, 883 GL_UNSIGNED_INT, 884 GL_DEPTH_COMPONENT, 885 usampler, 886 { GL_R32UI, src_data_rg32ui + 0 }, 887 { GL_R32UI, src_data_rg32ui + 1 }, 888 zero_ch, 889 one_ch, 890 src_data_rg32ui, 891 uint32_zero, 892 uint32_one }, 893 { glu::ApiType::core(3, 0), 894 GL_RGB8I, 895 GL_RGB_INTEGER, 896 GL_BYTE, 897 GL_DEPTH_COMPONENT, 898 isampler, 899 { GL_R8I, src_data_rgb8i + 0 }, 900 { GL_R8I, src_data_rgb8i + 1 }, 901 { GL_R8I, src_data_rgb8i + 2 }, 902 one_ch, 903 src_data_rgb8i, 904 sint8_zero, 905 sint8_one }, 906 { glu::ApiType::core(3, 0), 907 GL_RGB8UI, 908 GL_RGB_INTEGER, 909 GL_UNSIGNED_BYTE, 910 GL_DEPTH_COMPONENT, 911 usampler, 912 { GL_R8UI, src_data_rgb8ui + 0 }, 913 { GL_R8UI, src_data_rgb8ui + 1 }, 914 { GL_R8UI, src_data_rgb8ui + 2 }, 915 one_ch, 916 src_data_rgb8ui, 917 uint8_zero, 918 uint8_one }, 919 { glu::ApiType::core(3, 0), 920 GL_RGB16I, 921 GL_RGB_INTEGER, 922 GL_SHORT, 923 GL_DEPTH_COMPONENT, 924 isampler, 925 { GL_R16I, src_data_rgb16i + 0 }, 926 { GL_R16I, src_data_rgb16i + 1 }, 927 { GL_R16I, src_data_rgb16i + 2 }, 928 one_ch, 929 src_data_rgb16i, 930 sint16_zero, 931 sint16_one }, 932 { glu::ApiType::core(3, 0), 933 GL_RGB16UI, 934 GL_RGB_INTEGER, 935 GL_UNSIGNED_SHORT, 936 GL_DEPTH_COMPONENT, 937 usampler, 938 { GL_R16UI, src_data_rgb16ui + 0 }, 939 { GL_R16UI, src_data_rgb16ui + 1 }, 940 { GL_R16UI, src_data_rgb16ui + 2 }, 941 one_ch, 942 src_data_rgb16ui, 943 uint16_zero, 944 uint16_one }, 945 { glu::ApiType::core(3, 0), 946 GL_RGB32I, 947 GL_RGB_INTEGER, 948 GL_INT, 949 GL_DEPTH_COMPONENT, 950 isampler, 951 { GL_R32I, src_data_rgb32i + 0 }, 952 { GL_R32I, src_data_rgb32i + 1 }, 953 { GL_R32I, src_data_rgb32i + 2 }, 954 one_ch, 955 src_data_rgb32i, 956 sint32_zero, 957 sint32_one }, 958 /* 56 */ { glu::ApiType::core(3, 0), 959 GL_RGB32UI, 960 GL_RGB_INTEGER, 961 GL_UNSIGNED_INT, 962 GL_DEPTH_COMPONENT, 963 usampler, 964 { GL_R32UI, src_data_rgb32ui + 0 }, 965 { GL_R32UI, src_data_rgb32ui + 1 }, 966 { GL_R32UI, src_data_rgb32ui + 2 }, 967 one_ch, 968 src_data_rgb32ui, 969 uint32_zero, 970 uint32_one }, 971 { glu::ApiType::core(3, 0), 972 GL_RGBA8I, 973 GL_RGBA_INTEGER, 974 GL_BYTE, 975 GL_DEPTH_COMPONENT, 976 isampler, 977 { GL_R8I, src_data_rgba8i + 0 }, 978 { GL_R8I, src_data_rgba8i + 1 }, 979 { GL_R8I, src_data_rgba8i + 2 }, 980 { GL_R8I, src_data_rgba8i + 3 }, 981 src_data_rgba8i, 982 sint8_zero, 983 sint8_one }, 984 { glu::ApiType::core(3, 0), 985 GL_RGBA8UI, 986 GL_RGBA_INTEGER, 987 GL_UNSIGNED_BYTE, 988 GL_DEPTH_COMPONENT, 989 usampler, 990 { GL_R8UI, src_data_rgba8ui + 0 }, 991 { GL_R8UI, src_data_rgba8ui + 1 }, 992 { GL_R8UI, src_data_rgba8ui + 2 }, 993 { GL_R8UI, src_data_rgba8ui + 3 }, 994 src_data_rgba8ui, 995 uint8_zero, 996 uint8_one }, 997 { glu::ApiType::core(3, 0), 998 GL_RGBA16I, 999 GL_RGBA_INTEGER, 1000 GL_SHORT, 1001 GL_DEPTH_COMPONENT, 1002 isampler, 1003 { GL_R16I, src_data_rgba16i + 0 }, 1004 { GL_R16I, src_data_rgba16i + 1 }, 1005 { GL_R16I, src_data_rgba16i + 2 }, 1006 { GL_R16I, src_data_rgba16i + 3 }, 1007 src_data_rgba16i, 1008 sint16_zero, 1009 sint16_one }, 1010 { glu::ApiType::core(3, 0), 1011 GL_RGBA16UI, 1012 GL_RGBA_INTEGER, 1013 GL_UNSIGNED_SHORT, 1014 GL_DEPTH_COMPONENT, 1015 usampler, 1016 { GL_R16UI, src_data_rgba16ui + 0 }, 1017 { GL_R16UI, src_data_rgba16ui + 1 }, 1018 { GL_R16UI, src_data_rgba16ui + 2 }, 1019 { GL_R16UI, src_data_rgba16ui + 3 }, 1020 src_data_rgba16ui, 1021 uint16_zero, 1022 uint16_one }, 1023 { glu::ApiType::core(3, 0), 1024 GL_RGBA32I, 1025 GL_RGBA_INTEGER, 1026 GL_INT, 1027 GL_DEPTH_COMPONENT, 1028 isampler, 1029 { GL_R32I, src_data_rgba32i + 0 }, 1030 { GL_R32I, src_data_rgba32i + 1 }, 1031 { GL_R32I, src_data_rgba32i + 2 }, 1032 { GL_R32I, src_data_rgba32i + 3 }, 1033 src_data_rgba32i, 1034 sint32_zero, 1035 sint32_one }, 1036 { glu::ApiType::core(3, 0), 1037 GL_RGBA32UI, 1038 GL_RGBA_INTEGER, 1039 GL_UNSIGNED_INT, 1040 GL_DEPTH_COMPONENT, 1041 usampler, 1042 { GL_R32UI, src_data_rgba32ui + 0 }, 1043 { GL_R32UI, src_data_rgba32ui + 1 }, 1044 { GL_R32UI, src_data_rgba32ui + 2 }, 1045 { GL_R32UI, src_data_rgba32ui + 3 }, 1046 src_data_rgba32ui, 1047 uint32_zero, 1048 uint32_one }, 1049 { glu::ApiType::core(3, 0), 1050 GL_DEPTH_COMPONENT16, 1051 GL_DEPTH_COMPONENT, 1052 GL_UNSIGNED_SHORT, 1053 GL_DEPTH_COMPONENT, 1054 sampler, 1055 { GL_R16, src_data_depth_component16 }, 1056 zero_ch, 1057 zero_ch, 1058 one_ch, 1059 src_data_depth_component16, 1060 unorm16_zero, 1061 unorm16_one }, 1062 /* 64 */ { glu::ApiType::core(3, 0), 1063 GL_DEPTH_COMPONENT24, 1064 GL_DEPTH_COMPONENT, 1065 GL_UNSIGNED_INT, 1066 GL_DEPTH_COMPONENT, 1067 sampler, 1068 { GL_R32F, exp_data_depth_component32 }, 1069 zero_ch, 1070 zero_ch, 1071 one_ch, 1072 src_data_depth_component32, 1073 float32_zero, 1074 float32_one }, 1075 { glu::ApiType::core(3, 0), 1076 GL_DEPTH_COMPONENT32, 1077 GL_DEPTH_COMPONENT, 1078 GL_UNSIGNED_INT, 1079 GL_DEPTH_COMPONENT, 1080 sampler, 1081 { GL_R32F, exp_data_depth_component32 }, 1082 zero_ch, 1083 zero_ch, 1084 one_ch, 1085 src_data_depth_component32, 1086 float32_zero, 1087 float32_one }, 1088 { glu::ApiType::core(3, 0), 1089 GL_DEPTH_COMPONENT32F, 1090 GL_DEPTH_COMPONENT, 1091 GL_FLOAT, 1092 GL_DEPTH_COMPONENT, 1093 sampler, 1094 { GL_R32F, src_data_depth_component32f }, 1095 zero_ch, 1096 zero_ch, 1097 one_ch, 1098 src_data_depth_component32f, 1099 float32_zero, 1100 float32_one }, 1101 { glu::ApiType::core(3, 0), 1102 GL_DEPTH24_STENCIL8, 1103 GL_DEPTH_STENCIL, 1104 GL_UNSIGNED_INT_24_8, 1105 GL_DEPTH_COMPONENT, 1106 sampler, 1107 { GL_R32F, exp_data_depth_component32 }, 1108 zero_ch, 1109 zero_ch, 1110 one_ch, 1111 src_data_depth24_stencil8, 1112 float32_zero, 1113 float32_one }, 1114 { glu::ApiType::core(3, 0), 1115 GL_DEPTH32F_STENCIL8, 1116 GL_DEPTH_STENCIL, 1117 GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 1118 GL_DEPTH_COMPONENT, 1119 sampler, 1120 { GL_R32F, exp_data_depth_component32 }, 1121 zero_ch, 1122 zero_ch, 1123 one_ch, 1124 src_data_depth32f_stencil8, 1125 float32_zero, 1126 float32_one }, 1127 { glu::ApiType::core(4, 3), GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_STENCIL_INDEX, usampler, 1128 one_ch, zero_ch, zero_ch, one_ch, src_data_depth24_stencil8, uint8_zero, uint8_one }, 1129 { glu::ApiType::core(4, 3), GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 1130 GL_STENCIL_INDEX, usampler, one_ch, zero_ch, zero_ch, one_ch, src_data_depth32f_stencil8, uint8_zero, uint8_one } 1131}; 1132static const size_t n_texture_formats = sizeof(texture_formats) / sizeof(texture_formats[0]); 1133 1134/* Texture access routine descriptors */ 1135struct _texture_access 1136{ 1137 const glw::GLchar* m_name; 1138 size_t m_n_coordinates; 1139 bool m_use_derivaties; 1140 bool m_use_integral_coordinates; 1141 bool m_use_lod; 1142 bool m_use_offsets; 1143 bool m_support_multisampling; 1144}; 1145static const _texture_access texture_access[] = { { "texture", 0, false, false, false, false, false }, 1146 { "textureProj", 1, false, false, false, false, false }, 1147 { "textureLod", 0, false, false, true, false, false }, 1148 { "textureOffset", 0, false, false, false, true, false }, 1149 { "texelFetch", 0, false, true, true, false, true }, 1150 { "texelFetchOffset", 0, false, true, true, true, false }, 1151 { "textureProjOffset", 1, false, false, false, true, false }, 1152 { "textureLodOffset", 0, false, false, true, true, false }, 1153 { "textureProjLod", 1, false, false, true, false, false }, 1154 { "textureProjLodOffset", 1, false, false, true, true, false }, 1155 { "textureGrad", 0, true, false, false, false, false }, 1156 { "textureGradOffset", 0, true, false, false, true, false }, 1157 { "textureProjGrad", 1, true, false, false, false, false }, 1158 { "textureProjGradOffset", 1, true, false, false, true, false } }; 1159static const size_t n_texture_access = sizeof(texture_access) / sizeof(texture_access[0]); 1160 1161/* Texture target descriptor */ 1162struct _texture_target 1163{ 1164 size_t m_n_array_coordinates; 1165 size_t m_n_coordinates; 1166 size_t m_n_derivatives; 1167 const glw::GLchar* m_sampler_type; 1168 bool m_support_integral_coordinates; 1169 bool m_support_lod; 1170 bool m_support_offset; 1171 bool m_supports_proj; 1172 bool m_require_multisampling; 1173 glw::GLenum m_target; 1174}; 1175 1176static const _texture_target texture_targets[] = { 1177 { 0, 1, 1, "1D", true, true, true, true, false, GL_TEXTURE_1D }, 1178 { 0, 2, 2, "2D", true, true, true, true, false, GL_TEXTURE_2D }, 1179 { 0, 3, 3, "3D", true, true, true, true, false, GL_TEXTURE_3D }, 1180 { 1, 1, 1, "1DArray", true, true, true, false, false, GL_TEXTURE_1D_ARRAY }, 1181 { 1, 2, 2, "2DArray", true, true, true, false, false, GL_TEXTURE_2D_ARRAY }, 1182 { 0, 2, 2, "2DRect", true, false, true, true, false, GL_TEXTURE_RECTANGLE }, 1183 { 0, 3, 3, "Cube", false, true, false, false, false, GL_TEXTURE_CUBE_MAP }, 1184 { 0, 2, 2, "2DMS", true, false, true, true, true, GL_TEXTURE_2D_MULTISAMPLE }, 1185 { 1, 2, 2, "2DMSArray", true, false, true, true, true, GL_TEXTURE_2D_MULTISAMPLE_ARRAY }, 1186}; 1187static const size_t n_texture_targets = sizeof(texture_targets) / sizeof(texture_targets[0]); 1188 1189/* Swizzle valid values */ 1190static const glw::GLint valid_values[] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_ONE, GL_ZERO }; 1191static const size_t n_valid_values = sizeof(valid_values) / sizeof(valid_values[0]); 1192 1193/* Prototypes */ 1194const _out_ch_desc& get_descriptor_for_channel(const _texture_format& format, const size_t channel); 1195 1196#if ENABLE_DEBUG 1197 1198/** Debuging procedure. Logs parameters. 1199 * 1200 * @param source As specified in GL spec. 1201 * @param type As specified in GL spec. 1202 * @param id As specified in GL spec. 1203 * @param severity As specified in GL spec. 1204 * @param ignored 1205 * @param message As specified in GL spec. 1206 * @param info Pointer to instance of deqp::Context used by test. 1207 */ 1208void GLW_APIENTRY debug_proc(glw::GLenum source, glw::GLenum type, glw::GLuint id, glw::GLenum severity, 1209 glw::GLsizei /* length */, const glw::GLchar* message, void* info) 1210{ 1211 Context* ctx = (Context*)info; 1212 1213 const glw::GLchar* source_str = "Unknown"; 1214 const glw::GLchar* type_str = "Unknown"; 1215 const glw::GLchar* severity_str = "Unknown"; 1216 1217 switch (source) 1218 { 1219 case GL_DEBUG_SOURCE_API: 1220 source_str = "API"; 1221 break; 1222 case GL_DEBUG_SOURCE_APPLICATION: 1223 source_str = "APP"; 1224 break; 1225 case GL_DEBUG_SOURCE_OTHER: 1226 source_str = "OTR"; 1227 break; 1228 case GL_DEBUG_SOURCE_SHADER_COMPILER: 1229 source_str = "COM"; 1230 break; 1231 case GL_DEBUG_SOURCE_THIRD_PARTY: 1232 source_str = "3RD"; 1233 break; 1234 case GL_DEBUG_SOURCE_WINDOW_SYSTEM: 1235 source_str = "WS"; 1236 break; 1237 default: 1238 break; 1239 } 1240 1241 switch (type) 1242 { 1243 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: 1244 type_str = "DEPRECATED_BEHAVIOR"; 1245 break; 1246 case GL_DEBUG_TYPE_ERROR: 1247 type_str = "ERROR"; 1248 break; 1249 case GL_DEBUG_TYPE_MARKER: 1250 type_str = "MARKER"; 1251 break; 1252 case GL_DEBUG_TYPE_OTHER: 1253 type_str = "OTHER"; 1254 break; 1255 case GL_DEBUG_TYPE_PERFORMANCE: 1256 type_str = "PERFORMANCE"; 1257 break; 1258 case GL_DEBUG_TYPE_POP_GROUP: 1259 type_str = "POP_GROUP"; 1260 break; 1261 case GL_DEBUG_TYPE_PORTABILITY: 1262 type_str = "PORTABILITY"; 1263 break; 1264 case GL_DEBUG_TYPE_PUSH_GROUP: 1265 type_str = "PUSH_GROUP"; 1266 break; 1267 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: 1268 type_str = "UNDEFINED_BEHAVIOR"; 1269 break; 1270 default: 1271 break; 1272 } 1273 1274 switch (severity) 1275 { 1276 case GL_DEBUG_SEVERITY_HIGH: 1277 severity_str = "H"; 1278 break; 1279 case GL_DEBUG_SEVERITY_LOW: 1280 severity_str = "L"; 1281 break; 1282 case GL_DEBUG_SEVERITY_MEDIUM: 1283 severity_str = "M"; 1284 break; 1285 case GL_DEBUG_SEVERITY_NOTIFICATION: 1286 severity_str = "N"; 1287 break; 1288 default: 1289 break; 1290 } 1291 1292 ctx->getTestContext().getLog() << tcu::TestLog::Message << "DEBUG_INFO: " << std::setw(3) << source_str << "|" 1293 << severity_str << "|" << std::setw(18) << type_str << "|" << std::setw(12) << id 1294 << ": " << message << tcu::TestLog::EndMessage; 1295} 1296 1297#endif /* ENABLE_DEBUG */ 1298 1299/** Extracts value of each channel from source data of given format 1300 * 1301 * @param format_idx Index of format 1302 * @param out_ch_rgba Storage for values 1303 **/ 1304void calculate_values_from_source(size_t format_idx, double out_ch_rgba[4]) 1305{ 1306 const _texture_format& format = texture_formats[format_idx]; 1307 1308 /* */ 1309 double ch_rgba[4] = { 0.0, 0.0, 0.0, 0.0 }; 1310 double& ch_r = ch_rgba[0]; 1311 double& ch_g = ch_rgba[1]; 1312 double& ch_b = ch_rgba[2]; 1313 double& ch_a = ch_rgba[3]; 1314 size_t n_channels = 0; 1315 bool is_norm = true; 1316 1317 /* Select n_channels and is_norm */ 1318 switch (format.m_format) 1319 { 1320 case GL_RED_INTEGER: 1321 is_norm = false; 1322 /* fall through */ 1323 1324 case GL_RED: 1325 n_channels = 1; 1326 1327 break; 1328 1329 case GL_RG_INTEGER: 1330 is_norm = false; 1331 /* fall through */ 1332 1333 case GL_RG: 1334 n_channels = 2; 1335 1336 break; 1337 1338 case GL_RGB_INTEGER: 1339 is_norm = false; 1340 /* fall through */ 1341 1342 case GL_RGB: 1343 n_channels = 3; 1344 1345 break; 1346 1347 case GL_RGBA_INTEGER: 1348 is_norm = false; 1349 /* fall through */ 1350 1351 case GL_RGBA: 1352 n_channels = 4; 1353 1354 break; 1355 1356 default: 1357 TCU_FAIL("Unsupported format"); 1358 } 1359 1360 /* Calculate rgba values */ 1361 if ((GL_SRGB8 == format.m_internal_format) || (GL_SRGB8_ALPHA8 == format.m_internal_format)) 1362 { 1363 const glw::GLubyte* ptr = (const glw::GLubyte*)src_data_srgb8_alpha8; 1364 const glw::GLubyte r = ptr[0]; 1365 const glw::GLubyte g = ptr[1]; 1366 const glw::GLubyte b = ptr[2]; 1367 const glw::GLubyte a = ptr[3]; 1368 1369 ch_r = r; 1370 ch_g = g; 1371 ch_b = b; 1372 ch_a = a; 1373 1374 ch_r /= 255.0; 1375 ch_g /= 255.0; 1376 ch_b /= 255.0; 1377 ch_a /= 255.0; 1378 } 1379 else if (GL_UNSIGNED_BYTE_3_3_2 == format.m_type) 1380 { 1381 const glw::GLubyte* ptr = (const glw::GLubyte*)format.m_source_data; 1382 const glw::GLubyte r = (glw::GLubyte)((*ptr) >> 5); 1383 const glw::GLubyte g = ((*ptr) >> 2) & 7; 1384 const glw::GLubyte b = (*ptr) & 3; 1385 1386 ch_r = r; 1387 ch_g = g; 1388 ch_b = b; 1389 1390 ch_r /= 7.0; 1391 ch_g /= 7.0; 1392 ch_b /= 3.0; 1393 } 1394 else if (GL_UNSIGNED_SHORT_5_6_5 == format.m_type) 1395 { 1396 const glw::GLushort* ptr = (const glw::GLushort*)format.m_source_data; 1397 const glw::GLubyte r = (glw::GLubyte)((*ptr) >> 11); 1398 const glw::GLubyte g = (glw::GLubyte)((*ptr) >> 5) & 63; 1399 const glw::GLubyte b = (*ptr) & 31; 1400 1401 ch_r = r; 1402 ch_g = g; 1403 ch_b = b; 1404 1405 ch_r /= 31.0; 1406 ch_g /= 63.0; 1407 ch_b /= 31.0; 1408 } 1409 else if (GL_UNSIGNED_SHORT_4_4_4_4 == format.m_type) 1410 { 1411 const glw::GLushort* ptr = (const glw::GLushort*)format.m_source_data; 1412 const glw::GLubyte r = (glw::GLubyte)((*ptr) >> 12); 1413 const glw::GLubyte g = (glw::GLubyte)(((*ptr) >> 8) & 15); 1414 const glw::GLubyte b = (glw::GLubyte)(((*ptr) >> 4) & 15); 1415 const glw::GLubyte a = (glw::GLubyte)((*ptr) & 15); 1416 1417 ch_r = r; 1418 ch_g = g; 1419 ch_b = b; 1420 ch_a = a; 1421 1422 ch_r /= 15.0; 1423 ch_g /= 15.0; 1424 ch_b /= 15.0; 1425 ch_a /= 15.0; 1426 } 1427 else if (GL_UNSIGNED_SHORT_5_5_5_1 == format.m_type) 1428 { 1429 const glw::GLushort* ptr = (const glw::GLushort*)format.m_source_data; 1430 const glw::GLubyte r = (glw::GLubyte)((*ptr) >> 11); 1431 const glw::GLubyte g = ((*ptr) >> 6) & 31; 1432 const glw::GLubyte b = ((*ptr) >> 1) & 31; 1433 const glw::GLubyte a = (*ptr) & 1; 1434 1435 ch_r = r; 1436 ch_g = g; 1437 ch_b = b; 1438 ch_a = a; 1439 1440 ch_r /= 31.0; 1441 ch_g /= 31.0; 1442 ch_b /= 31.0; 1443 ch_a /= 1.0; 1444 } 1445 else if (GL_UNSIGNED_INT_10_10_10_2 == format.m_type) 1446 { 1447 const glw::GLuint* ptr = (const glw::GLuint*)format.m_source_data; 1448 const glw::GLushort r = (glw::GLushort)((*ptr) >> 22); 1449 const glw::GLushort g = ((*ptr) >> 12) & 1023; 1450 const glw::GLushort b = ((*ptr) >> 2) & 1023; 1451 const glw::GLushort a = (*ptr) & 3; 1452 1453 ch_r = r; 1454 ch_g = g; 1455 ch_b = b; 1456 ch_a = a; 1457 1458 if (true == is_norm) 1459 { 1460 ch_r /= 1023.0; 1461 ch_g /= 1023.0; 1462 ch_b /= 1023.0; 1463 ch_a /= 3.0; 1464 } 1465 } 1466 else if (GL_UNSIGNED_INT_10F_11F_11F_REV == format.m_type) 1467 { 1468 ch_r = r11f.asDouble(); 1469 ch_g = g11f.asDouble(); 1470 ch_b = b10f.asDouble(); 1471 } 1472 else if (GL_UNSIGNED_INT_5_9_9_9_REV == format.m_type) 1473 { 1474 TCU_FAIL("Not supported: GL_UNSIGNED_INT_5_9_9_9_REV"); 1475 } 1476 else if (GL_UNSIGNED_INT_24_8 == format.m_type) 1477 { 1478 TCU_FAIL("Not supported: GL_UNSIGNED_INT_24_8"); 1479 } 1480 else if (GL_FLOAT_32_UNSIGNED_INT_24_8_REV == format.m_type) 1481 { 1482 TCU_FAIL("Not supported: GL_FLOAT_32_UNSIGNED_INT_24_8_REV"); 1483 } 1484 else if (GL_BYTE == format.m_type) 1485 { 1486 const glw::GLbyte* ptr = (const glw::GLbyte*)format.m_source_data; 1487 1488 for (size_t i = 0; i < n_channels; ++i) 1489 { 1490 const glw::GLbyte val = ptr[i]; 1491 double& ch = ch_rgba[i]; 1492 1493 ch = val; 1494 if (true == is_norm) 1495 ch /= 127.0; 1496 } 1497 } 1498 else if (GL_UNSIGNED_BYTE == format.m_type) 1499 { 1500 const glw::GLubyte* ptr = (const glw::GLubyte*)format.m_source_data; 1501 1502 for (size_t i = 0; i < n_channels; ++i) 1503 { 1504 const glw::GLubyte val = ptr[i]; 1505 double& ch = ch_rgba[i]; 1506 1507 ch = val; 1508 if (true == is_norm) 1509 ch /= 255.0; 1510 } 1511 } 1512 else if (GL_SHORT == format.m_type) 1513 { 1514 const glw::GLshort* ptr = (const glw::GLshort*)format.m_source_data; 1515 1516 for (size_t i = 0; i < n_channels; ++i) 1517 { 1518 const glw::GLshort val = ptr[i]; 1519 double& ch = ch_rgba[i]; 1520 1521 ch = val; 1522 if (true == is_norm) 1523 ch /= 32767.0; 1524 } 1525 } 1526 else if (GL_UNSIGNED_SHORT == format.m_type) 1527 { 1528 const glw::GLushort* ptr = (const glw::GLushort*)format.m_source_data; 1529 1530 for (size_t i = 0; i < n_channels; ++i) 1531 { 1532 const glw::GLushort val = ptr[i]; 1533 double& ch = ch_rgba[i]; 1534 1535 ch = val; 1536 if (true == is_norm) 1537 ch /= 65535.0; 1538 } 1539 } 1540 else if (GL_INT == format.m_type) 1541 { 1542 const glw::GLint* ptr = (const glw::GLint*)format.m_source_data; 1543 1544 for (size_t i = 0; i < n_channels; ++i) 1545 { 1546 const glw::GLint val = ptr[i]; 1547 double& ch = ch_rgba[i]; 1548 1549 ch = val; 1550 if (true == is_norm) 1551 ch /= 2147483647.0; 1552 } 1553 } 1554 else if (GL_UNSIGNED_INT == format.m_type) 1555 { 1556 const glw::GLuint* ptr = (const glw::GLuint*)format.m_source_data; 1557 1558 for (size_t i = 0; i < n_channels; ++i) 1559 { 1560 const glw::GLuint val = ptr[i]; 1561 double& ch = ch_rgba[i]; 1562 1563 ch = val; 1564 if (true == is_norm) 1565 ch /= 4294967295.0; 1566 } 1567 } 1568 else if (GL_FLOAT == format.m_type) 1569 { 1570 const glw::GLfloat* ptr = (const glw::GLfloat*)format.m_source_data; 1571 1572 for (size_t i = 0; i < n_channels; ++i) 1573 { 1574 const glw::GLfloat val = ptr[i]; 1575 double& ch = ch_rgba[i]; 1576 1577 ch = val; 1578 } 1579 } 1580 else if (GL_HALF_FLOAT == format.m_type) 1581 { 1582 const glw::GLhalf* ptr = (const glw::GLhalf*)format.m_source_data; 1583 1584 for (size_t i = 0; i < n_channels; ++i) 1585 { 1586 const glw::GLhalf val = ptr[i]; 1587 double& ch = ch_rgba[i]; 1588 1589 tcu::Float16 f16(val); 1590 ch = f16.asDouble(); 1591 } 1592 } 1593 else 1594 { 1595 TCU_FAIL("Invalid enum"); 1596 } 1597 1598 /* Store results */ 1599 memcpy(out_ch_rgba, ch_rgba, 4 * sizeof(double)); 1600} 1601 1602/** Calculate maximum uint value for given size of storage 1603 * 1604 * @param size Size of storage in bits 1605 * 1606 * @return Calculated max 1607 **/ 1608double calculate_max_for_size(size_t size) 1609{ 1610 double power = pow(2.0, double(size)); 1611 1612 return power - 1.0; 1613} 1614 1615/** Converts from double to given T 1616 * 1617 * @tparam Requested type of value 1618 * 1619 * @param out_expected_data Storage for converted value 1620 * @param value Value to be converted 1621 **/ 1622template <typename T> 1623void convert(void* out_expected_data, double value) 1624{ 1625 T* ptr = (T*)out_expected_data; 1626 1627 *ptr = T(value); 1628} 1629 1630/** Calcualte range of expected values 1631 * 1632 * @param source_format_idx Index of source format 1633 * @param output_format_idx Index of output format 1634 * @param index_of_swizzled_channel Index of swizzled channel 1635 * @param source_size Size of source storage in bits 1636 * @param output_size Size of output storage in bits 1637 * @param out_expected_data_low Lowest acceptable value 1638 * @param out_expected_data_top Highest acceptable value 1639 * @param out_expected_data_size Number of bytes used to store out values 1640 **/ 1641void calculate_expected_value(size_t source_format_idx, size_t output_format_idx, size_t index_of_swizzled_channel, 1642 glw::GLint source_size, glw::GLint output_size, void* out_expected_data_low, 1643 void* out_expected_data_top, size_t& out_expected_data_size) 1644{ 1645 const _texture_format& output_format = texture_formats[output_format_idx]; 1646 const _texture_format& source_format = texture_formats[source_format_idx]; 1647 const _out_ch_desc& desc = get_descriptor_for_channel(source_format, index_of_swizzled_channel); 1648 const glw::GLvoid* expected_data = desc.m_expected_data; 1649 bool is_signed = false; 1650 double range_low = 0.0f; 1651 double range_top = 0.0f; 1652 size_t texel_size = 0; 1653 1654 /* Select range, texel size and is_signed */ 1655 switch (output_format.m_type) 1656 { 1657 case GL_BYTE: 1658 is_signed = true; 1659 1660 range_low = -127.0; 1661 range_top = 127.0; 1662 1663 texel_size = 1; 1664 1665 break; 1666 1667 case GL_UNSIGNED_BYTE: 1668 range_low = 0.0; 1669 range_top = 255.0; 1670 1671 texel_size = 1; 1672 1673 break; 1674 1675 case GL_SHORT: 1676 is_signed = true; 1677 1678 range_low = -32767.0; 1679 range_top = 32767.0; 1680 1681 texel_size = 2; 1682 1683 break; 1684 1685 case GL_UNSIGNED_SHORT: 1686 range_low = 0.0; 1687 range_top = 65535.0; 1688 1689 texel_size = 2; 1690 1691 break; 1692 1693 case GL_HALF_FLOAT: 1694 texel_size = 2; 1695 1696 /* Halfs are not calculated, range will not be used */ 1697 1698 break; 1699 1700 case GL_INT: 1701 is_signed = true; 1702 1703 range_low = -2147483647.0; 1704 range_top = 2147483647.0; 1705 1706 texel_size = 4; 1707 1708 break; 1709 1710 case GL_UNSIGNED_INT: 1711 range_low = 0.0; 1712 range_top = 4294967295.0; 1713 1714 texel_size = 4; 1715 1716 break; 1717 1718 case GL_FLOAT: 1719 texel_size = 4; 1720 1721 /* Float are not calculated, range will not be used */ 1722 1723 break; 1724 1725 default: 1726 TCU_FAIL("Invalid enum"); 1727 break; 1728 } 1729 1730 /* Signed formats use one bit less */ 1731 if (true == is_signed) 1732 { 1733 source_size -= 1; 1734 output_size -= 1; 1735 } 1736 1737 /* If expected data is hardcoded just copy data to low and top */ 1738 if (DE_NULL != expected_data) 1739 { 1740 memcpy(out_expected_data_top, expected_data, texel_size); 1741 memcpy(out_expected_data_low, expected_data, texel_size); 1742 out_expected_data_size = texel_size; 1743 } 1744 else 1745 { 1746 /* Get source values */ 1747 double ch_rgba[4]; 1748 calculate_values_from_source(source_format_idx, ch_rgba); 1749 1750 /* Calculate expected value */ 1751 const float max_internal = float(calculate_max_for_size(source_size)); 1752 const float max_output = float(calculate_max_for_size(output_size)); 1753 const float temp_internal = float(ch_rgba[index_of_swizzled_channel]) * max_internal; 1754 const float stor_internal_low = 1755 deFloatFloor(temp_internal - 1.0f); /* Offset by 1 to avoid rounding done by FPU */ 1756 const float stor_internal_top = 1757 deFloatCeil(temp_internal + 1.0f); /* Offset by 1 to avoid rounding done by FPU */ 1758 const float read_internal_low = stor_internal_low / max_internal; 1759 const float read_internal_top = stor_internal_top / max_internal; 1760 const float temp_output_low = read_internal_low * max_output; 1761 const float temp_output_top = read_internal_top * max_output; 1762 double stor_output_low = floor(temp_output_low); 1763 double stor_output_top = ceil(temp_output_top); 1764 1765 /* Clamp to limits of output format */ 1766 stor_output_low = de::clamp(stor_output_low, range_low, range_top); 1767 stor_output_top = de::clamp(stor_output_top, range_low, range_top); 1768 1769 /* Store resuts */ 1770 switch (output_format.m_type) 1771 { 1772 case GL_BYTE: 1773 convert<glw::GLbyte>(out_expected_data_low, stor_output_low); 1774 convert<glw::GLbyte>(out_expected_data_top, stor_output_top); 1775 break; 1776 case GL_UNSIGNED_BYTE: 1777 convert<glw::GLubyte>(out_expected_data_low, stor_output_low); 1778 convert<glw::GLubyte>(out_expected_data_top, stor_output_top); 1779 break; 1780 case GL_SHORT: 1781 convert<glw::GLshort>(out_expected_data_low, stor_output_low); 1782 convert<glw::GLshort>(out_expected_data_top, stor_output_top); 1783 break; 1784 case GL_UNSIGNED_SHORT: 1785 convert<glw::GLushort>(out_expected_data_low, stor_output_low); 1786 convert<glw::GLushort>(out_expected_data_top, stor_output_top); 1787 break; 1788 case GL_INT: 1789 convert<glw::GLint>(out_expected_data_low, stor_output_low); 1790 convert<glw::GLint>(out_expected_data_top, stor_output_top); 1791 break; 1792 case GL_UNSIGNED_INT: 1793 convert<glw::GLuint>(out_expected_data_low, stor_output_low); 1794 convert<glw::GLuint>(out_expected_data_top, stor_output_top); 1795 break; 1796 default: 1797 TCU_FAIL("Invalid enum"); 1798 break; 1799 } 1800 out_expected_data_size = texel_size; 1801 } 1802} 1803 1804/** Gets index of internal format in texture_fomrats 1805 * 1806 * @param internal_format Internal format to be found 1807 * 1808 * @return Found index. -1 when format is not available. 0 when GL_ZERO is requested. 1809 **/ 1810size_t get_index_of_format(glw::GLenum internal_format) 1811{ 1812 if (GL_ZERO == internal_format) 1813 { 1814 return 0; 1815 } 1816 1817 for (size_t i = 0; i < n_texture_formats; ++i) 1818 { 1819 if (texture_formats[i].m_internal_format == internal_format) 1820 { 1821 return i; 1822 } 1823 } 1824 1825 TCU_FAIL("Unknown internal format"); 1826 return -1; 1827} 1828 1829/** Gets index of target in texture_targets 1830 * 1831 * @param target target to be found 1832 * 1833 * @return Found index. -1 when format is not available. 0 when GL_ZERO is requested. 1834 **/ 1835size_t get_index_of_target(glw::GLenum target) 1836{ 1837 if (GL_ZERO == target) 1838 { 1839 return 0; 1840 } 1841 1842 for (size_t i = 0; i < n_texture_targets; ++i) 1843 { 1844 if (texture_targets[i].m_target == target) 1845 { 1846 return i; 1847 } 1848 } 1849 1850 TCU_FAIL("Unknown texture target"); 1851 return -1; 1852} 1853 1854/* Constants used by get_swizzled_channel_idx */ 1855static const size_t CHANNEL_INDEX_ONE = 4; 1856static const size_t CHANNEL_INDEX_ZERO = 5; 1857 1858/** Get index of channel that will be accessed after "swizzle" is applied 1859 * 1860 * @param channel_idx Index of channel before "swizzle" is applied 1861 * @param swizzle_set Set of swizzle states 1862 * 1863 * @return Index of "swizzled" channel 1864 */ 1865size_t get_swizzled_channel_idx(const size_t channel_idx, const glw::GLint swizzle_set[4]) 1866{ 1867 const glw::GLint swizzle = swizzle_set[channel_idx]; 1868 1869 size_t channel = 0; 1870 1871 switch (swizzle) 1872 { 1873 case GL_RED: 1874 channel = 0; 1875 break; 1876 case GL_GREEN: 1877 channel = 1; 1878 break; 1879 case GL_BLUE: 1880 channel = 2; 1881 break; 1882 case GL_ALPHA: 1883 channel = 3; 1884 break; 1885 case GL_ONE: 1886 channel = CHANNEL_INDEX_ONE; 1887 break; 1888 case GL_ZERO: 1889 channel = CHANNEL_INDEX_ZERO; 1890 break; 1891 default: 1892 TCU_FAIL("Invalid value"); 1893 break; 1894 } 1895 1896 return channel; 1897} 1898 1899/** Gets descriptor of output channel from texture format descriptor 1900 * 1901 * @param format Format descriptor 1902 * @param channel Index of "swizzled" channel 1903 * 1904 * @return Descriptor of output channel 1905 **/ 1906const _out_ch_desc& get_descriptor_for_channel(const _texture_format& format, const size_t channel) 1907{ 1908 const _out_ch_desc* desc = 0; 1909 1910 switch (channel) 1911 { 1912 case CHANNEL_INDEX_ONE: 1913 desc = &format.m_one_ch; 1914 break; 1915 case CHANNEL_INDEX_ZERO: 1916 desc = &format.m_zero_ch; 1917 break; 1918 case 0: 1919 desc = &format.m_red_ch; 1920 break; 1921 case 1: 1922 desc = &format.m_green_ch; 1923 break; 1924 case 2: 1925 desc = &format.m_blue_ch; 1926 break; 1927 case 3: 1928 desc = &format.m_alpha_ch; 1929 break; 1930 default: 1931 TCU_FAIL("Invalid value"); 1932 break; 1933 }; 1934 1935 switch (desc->m_internal_format) 1936 { 1937 case GL_ONE: 1938 desc = &format.m_one_ch; 1939 break; 1940 case GL_ZERO: 1941 desc = &format.m_zero_ch; 1942 break; 1943 default: 1944 break; 1945 } 1946 1947 return *desc; 1948} 1949 1950/** Gets internal_format of output channel for given texture format 1951 * 1952 * @param format Format descriptor 1953 * @param channel Index of "swizzled" channel 1954 * 1955 * @return Internal format 1956 **/ 1957glw::GLenum get_internal_format_for_channel(const _texture_format& format, const size_t channel) 1958{ 1959 return get_descriptor_for_channel(format, channel).m_internal_format; 1960} 1961 1962/** Constructor 1963 * 1964 * @param context Test context 1965 **/ 1966Utils::programInfo::programInfo(deqp::Context& context) 1967 : m_context(context), m_fragment_shader_id(0), m_program_object_id(0), m_vertex_shader_id(0) 1968{ 1969 /* Nothing to be done here */ 1970} 1971 1972/** Destructor 1973 * 1974 **/ 1975Utils::programInfo::~programInfo() 1976{ 1977 /* GL entry points */ 1978 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1979 1980 /* Make sure program object is no longer used by GL */ 1981 gl.useProgram(0); 1982 1983 /* Clean program object */ 1984 if (0 != m_program_object_id) 1985 { 1986 gl.deleteProgram(m_program_object_id); 1987 m_program_object_id = 0; 1988 } 1989 1990 /* Clean shaders */ 1991 if (0 != m_fragment_shader_id) 1992 { 1993 gl.deleteShader(m_fragment_shader_id); 1994 m_fragment_shader_id = 0; 1995 } 1996 1997 if (0 != m_vertex_shader_id) 1998 { 1999 gl.deleteShader(m_vertex_shader_id); 2000 m_vertex_shader_id = 0; 2001 } 2002} 2003 2004/** Build program 2005 * 2006 * @param fragment_shader_code Fragment shader source code 2007 * @param vertex_shader_code Vertex shader source code 2008 **/ 2009void Utils::programInfo::build(const glw::GLchar* fragment_shader_code, const glw::GLchar* vertex_shader_code) 2010{ 2011 /* GL entry points */ 2012 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2013 2014 /* Create shader objects and compile */ 2015 if (0 != fragment_shader_code) 2016 { 2017 m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER); 2018 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader"); 2019 2020 compile(m_fragment_shader_id, fragment_shader_code); 2021 } 2022 2023 if (0 != vertex_shader_code) 2024 { 2025 m_vertex_shader_id = gl.createShader(GL_VERTEX_SHADER); 2026 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader"); 2027 2028 compile(m_vertex_shader_id, vertex_shader_code); 2029 } 2030 2031 /* Create program object */ 2032 m_program_object_id = gl.createProgram(); 2033 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram"); 2034 2035 /* Link program */ 2036 link(); 2037} 2038 2039/** Compile shader 2040 * 2041 * @param shader_id Shader object id 2042 * @param shader_code Shader source code 2043 **/ 2044void Utils::programInfo::compile(glw::GLuint shader_id, const glw::GLchar* shader_code) const 2045{ 2046 /* GL entry points */ 2047 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2048 2049 /* Compilation status */ 2050 glw::GLint status = GL_FALSE; 2051 2052 /* Set source code */ 2053 gl.shaderSource(shader_id, 1 /* count */, &shader_code, 0); 2054 GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource"); 2055 2056 /* Compile */ 2057 gl.compileShader(shader_id); 2058 GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader"); 2059 2060 /* Get compilation status */ 2061 gl.getShaderiv(shader_id, GL_COMPILE_STATUS, &status); 2062 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv"); 2063 2064 /* Log compilation error */ 2065 if (GL_TRUE != status) 2066 { 2067 glw::GLint length = 0; 2068 std::vector<glw::GLchar> message; 2069 2070 /* Error log length */ 2071 gl.getShaderiv(shader_id, GL_INFO_LOG_LENGTH, &length); 2072 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv"); 2073 2074 /* Prepare storage */ 2075 message.resize(length); 2076 2077 /* Get error log */ 2078 gl.getShaderInfoLog(shader_id, length, 0, &message[0]); 2079 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog"); 2080 2081 /* Log */ 2082 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to compile shader:\n" 2083 << &message[0] << "\nShader source\n" 2084 << shader_code << tcu::TestLog::EndMessage; 2085 2086 TCU_FAIL("Failed to compile shader"); 2087 } 2088} 2089 2090/** Attach shaders and link program 2091 * 2092 **/ 2093void Utils::programInfo::link() const 2094{ 2095 /* GL entry points */ 2096 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2097 2098 /* Link status */ 2099 glw::GLint status = GL_FALSE; 2100 2101 /* Attach shaders */ 2102 if (0 != m_fragment_shader_id) 2103 { 2104 gl.attachShader(m_program_object_id, m_fragment_shader_id); 2105 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader"); 2106 } 2107 2108 if (0 != m_vertex_shader_id) 2109 { 2110 gl.attachShader(m_program_object_id, m_vertex_shader_id); 2111 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader"); 2112 } 2113 2114 /* Link */ 2115 gl.linkProgram(m_program_object_id); 2116 GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram"); 2117 2118 /* Get link status */ 2119 gl.getProgramiv(m_program_object_id, GL_LINK_STATUS, &status); 2120 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv"); 2121 2122 /* Log link error */ 2123 if (GL_TRUE != status) 2124 { 2125 glw::GLint length = 0; 2126 std::vector<glw::GLchar> message; 2127 2128 /* Get error log length */ 2129 gl.getProgramiv(m_program_object_id, GL_INFO_LOG_LENGTH, &length); 2130 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv"); 2131 2132 message.resize(length); 2133 2134 /* Get error log */ 2135 gl.getProgramInfoLog(m_program_object_id, length, 0, &message[0]); 2136 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog"); 2137 2138 /* Log */ 2139 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to link program:\n" 2140 << &message[0] << tcu::TestLog::EndMessage; 2141 2142 TCU_FAIL("Failed to link program"); 2143 } 2144} 2145 2146/** Replace first occurance of <token> with <text> in <string> starting at <search_posistion> 2147 * 2148 * @param token Token string 2149 * @param search_position Position at which find will start, it is updated to position at which replaced text ends 2150 * @param text String that will be used as replacement for <token> 2151 * @param string String to work on 2152 **/ 2153void Utils::replaceToken(const glw::GLchar* token, size_t& search_position, const glw::GLchar* text, 2154 std::string& string) 2155{ 2156 const size_t text_length = strlen(text); 2157 const size_t token_length = strlen(token); 2158 const size_t token_position = string.find(token, search_position); 2159 2160 string.replace(token_position, token_length, text, text_length); 2161 2162 search_position = token_position + text_length; 2163} 2164 2165/** Constructor. 2166 * 2167 * @param context Rendering context. 2168 **/ 2169APIErrorsTest::APIErrorsTest(deqp::Context& context) 2170 : TestCase(context, "api_errors", "Verifies that errors are generated as specified"), m_id(0) 2171{ 2172 /* Left blank intentionally */ 2173} 2174 2175/** Deinitialization **/ 2176void APIErrorsTest::deinit() 2177{ 2178 if (0 != m_id) 2179 { 2180 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2181 2182 gl.deleteTextures(1, &m_id); 2183 m_id = 0; 2184 } 2185} 2186 2187/** Executes test iteration. 2188 * 2189 * @return Returns STOP. 2190 */ 2191tcu::TestNode::IterateResult APIErrorsTest::iterate() 2192{ 2193 static const glw::GLint invalid_values[] = { 0x1902, 0x1907, -1, 2 }; 2194 static const size_t n_invalid_values = sizeof(invalid_values) / sizeof(invalid_values[0]); 2195 2196 /* */ 2197 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2198 2199 gl.genTextures(1, &m_id); 2200 GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures"); 2201 2202 gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_id); 2203 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 2204 2205 /* 2206 * - INVALID_ENUM is generated by TexParameter* routines when <pname> is 2207 * one of [TEXTURE_SWIZZLE_R, TEXTURE_SWIZZLE_G, TEXTURE_SWIZZLE_B, 2208 * TEXTURE_SWIZZLE_A] and <param> is not one of [RED, GREEN, BLUE, ALPHA, ZERO, 2209 * ONE]; 2210 */ 2211 for (size_t i = 0; i < n_states; ++i) 2212 { 2213 for (size_t j = 0; j < n_valid_values; ++j) 2214 { 2215 const glw::GLenum state = states[i]; 2216 const glw::GLint value = valid_values[j]; 2217 2218 gl.texParameteri(GL_TEXTURE_CUBE_MAP, state, value); 2219 verifyError(GL_NO_ERROR); 2220 } 2221 2222 for (size_t j = 0; j < n_invalid_values; ++j) 2223 { 2224 const glw::GLenum state = states[i]; 2225 const glw::GLint value = invalid_values[j]; 2226 2227 gl.texParameteri(GL_TEXTURE_CUBE_MAP, state, value); 2228 verifyError(GL_INVALID_ENUM); 2229 } 2230 } 2231 2232 /* 2233 * - INVALID_ENUM is generated by TexParameter*v routines when <pname> is 2234 * TEXTURE_SWIZZLE_RGBA and any of four values pointed by <param> is not one of 2235 * [RED, GREEN, BLUE, ALPHA, ZERO, ONE]. 2236 */ 2237 for (size_t i = 0; i < 4 /* number of channels */; ++i) 2238 { 2239 for (size_t j = 0; j < n_valid_values; ++j) 2240 { 2241 const glw::GLint value = valid_values[j]; 2242 2243 glw::GLint param[4] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA }; 2244 2245 param[i] = value; 2246 2247 gl.texParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_RGBA, param); 2248 verifyError(GL_NO_ERROR); 2249 } 2250 2251 for (size_t j = 0; j < n_invalid_values; ++j) 2252 { 2253 const glw::GLint value = invalid_values[j]; 2254 2255 glw::GLint param[4] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA }; 2256 2257 param[i] = value; 2258 2259 gl.texParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_RGBA, param); 2260 verifyError(GL_INVALID_ENUM); 2261 } 2262 } 2263 2264 /* Set result - exceptions are thrown in case of any error */ 2265 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2266 2267 /* Done */ 2268 return STOP; 2269} 2270 2271/** Verifies that proper error was generated 2272 * 2273 * @param expected_error 2274 **/ 2275void APIErrorsTest::verifyError(const glw::GLenum expected_error) 2276{ 2277 /* */ 2278 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2279 2280 const glw::GLenum error = gl.getError(); 2281 2282 if (expected_error != error) 2283 { 2284 TCU_FAIL("Got invalid error"); 2285 } 2286} 2287 2288/** Constructor. 2289 * 2290 * @param context Rendering context. 2291 **/ 2292IntialStateTest::IntialStateTest(deqp::Context& context) 2293 : TestCase(context, "intial_state", "Verifies that initial states are as specified"), m_id(0) 2294{ 2295 /* Left blank intentionally */ 2296} 2297 2298/** Deinitialization **/ 2299void IntialStateTest::deinit() 2300{ 2301 if (0 != m_id) 2302 { 2303 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2304 2305 gl.deleteTextures(1, &m_id); 2306 m_id = 0; 2307 } 2308} 2309 2310/** Executes test iteration. 2311 * 2312 * @return Returns STOP. 2313 */ 2314tcu::TestNode::IterateResult IntialStateTest::iterate() 2315{ 2316 /* */ 2317 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2318 2319 gl.genTextures(1, &m_id); 2320 GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures"); 2321 2322 for (size_t tex_tgt_idx = 0; tex_tgt_idx < n_texture_targets; ++tex_tgt_idx) 2323 { 2324 const glw::GLenum target = texture_targets[tex_tgt_idx].m_target; 2325 2326 gl.bindTexture(target, m_id); 2327 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 2328 2329 verifyValues(target); 2330 2331 deinit(); 2332 } 2333 2334 /* Set result - exceptions are thrown in case of any error */ 2335 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2336 2337 /* Done */ 2338 return STOP; 2339} 2340 2341/** Verifies that proper error was generated 2342 * 2343 * @param expected_error 2344 **/ 2345void IntialStateTest::verifyValues(const glw::GLenum texture_target) 2346{ 2347 /* */ 2348 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2349 2350 glw::GLint red = 0; 2351 glw::GLint green = 0; 2352 glw::GLint blue = 0; 2353 glw::GLint alpha = 0; 2354 glw::GLint param[4] = { 0 }; 2355 2356 gl.getTexParameterIiv(texture_target, GL_TEXTURE_SWIZZLE_R, &red); 2357 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexParameterIiv"); 2358 gl.getTexParameterIiv(texture_target, GL_TEXTURE_SWIZZLE_G, &green); 2359 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexParameterIiv"); 2360 gl.getTexParameterIiv(texture_target, GL_TEXTURE_SWIZZLE_B, &blue); 2361 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexParameterIiv"); 2362 gl.getTexParameterIiv(texture_target, GL_TEXTURE_SWIZZLE_A, &alpha); 2363 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexParameterIiv"); 2364 gl.getTexParameterIiv(texture_target, GL_TEXTURE_SWIZZLE_RGBA, param); 2365 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexParameterIiv"); 2366 2367 if (GL_RED != red) 2368 { 2369 TCU_FAIL("Got invalid initial state for TEXTURE_SWIZZLE_R"); 2370 } 2371 if (GL_GREEN != green) 2372 { 2373 TCU_FAIL("Got invalid initial state for TEXTURE_SWIZZLE_G"); 2374 } 2375 if (GL_BLUE != blue) 2376 { 2377 TCU_FAIL("Got invalid initial state for TEXTURE_SWIZZLE_B"); 2378 } 2379 if (GL_ALPHA != alpha) 2380 { 2381 TCU_FAIL("Got invalid initial state for TEXTURE_SWIZZLE_A"); 2382 } 2383 2384 if (GL_RED != param[0]) 2385 { 2386 TCU_FAIL("Got invalid initial red state for TEXTURE_SWIZZLE_RGBA"); 2387 } 2388 if (GL_GREEN != param[1]) 2389 { 2390 TCU_FAIL("Got invalid initial green state for TEXTURE_SWIZZLE_RGBA"); 2391 } 2392 if (GL_BLUE != param[2]) 2393 { 2394 TCU_FAIL("Got invalid initial blue state for TEXTURE_SWIZZLE_RGBA"); 2395 } 2396 if (GL_ALPHA != param[3]) 2397 { 2398 TCU_FAIL("Got invalid initial alpha state for TEXTURE_SWIZZLE_RGBA"); 2399 } 2400} 2401 2402/* Constants used by SmokeTest */ 2403const glw::GLsizei SmokeTest::m_depth = 1; 2404const glw::GLsizei SmokeTest::m_height = 1; 2405const glw::GLsizei SmokeTest::m_width = 1; 2406const glw::GLsizei SmokeTest::m_output_height = 8; 2407const glw::GLsizei SmokeTest::m_output_width = 8; 2408 2409/** Constructor. 2410 * 2411 * @param context Rendering context. 2412 **/ 2413SmokeTest::SmokeTest(deqp::Context& context) 2414 : TestCase(context, "smoke", "Verifies that all swizzle combinations work with all texture access routines") 2415 , m_is_ms_supported(false) 2416 , m_prepare_fbo_id(0) 2417 , m_out_tex_id(0) 2418 , m_source_tex_id(0) 2419 , m_test_fbo_id(0) 2420 , m_vao_id(0) 2421{ 2422 /* Left blank intentionally */ 2423} 2424 2425/** Constructor. 2426 * 2427 * @param context Rendering context. 2428 **/ 2429SmokeTest::SmokeTest(deqp::Context& context, const glw::GLchar* name, const glw::GLchar* description) 2430 : TestCase(context, name, description) 2431 , m_is_ms_supported(false) 2432 , m_prepare_fbo_id(0) 2433 , m_out_tex_id(0) 2434 , m_source_tex_id(0) 2435 , m_test_fbo_id(0) 2436 , m_vao_id(0) 2437{ 2438 /* Left blank intentionally */ 2439} 2440 2441/** Deinitialization **/ 2442void SmokeTest::deinit() 2443{ 2444 deinitTextures(); 2445 2446 if (m_prepare_fbo_id != 0) 2447 { 2448 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2449 gl.deleteFramebuffers(1, &m_prepare_fbo_id); 2450 2451 m_prepare_fbo_id = 0; 2452 } 2453 2454 if (m_test_fbo_id != 0) 2455 { 2456 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2457 gl.deleteFramebuffers(1, &m_test_fbo_id); 2458 2459 m_test_fbo_id = 0; 2460 } 2461 2462 if (m_vao_id != 0) 2463 { 2464 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2465 gl.deleteVertexArrays(1, &m_vao_id); 2466 2467 m_vao_id = 0; 2468 } 2469} 2470 2471/** Executes test iteration. 2472 * 2473 * @return Returns STOP. 2474 */ 2475tcu::TestNode::IterateResult SmokeTest::iterate() 2476{ 2477 static const glw::GLenum tested_format = GL_RGBA32UI; 2478 static const glw::GLenum tested_target = GL_TEXTURE_2D_ARRAY; 2479 2480 const size_t format_idx = get_index_of_format(tested_format); 2481 const size_t tgt_idx = get_index_of_target(tested_target); 2482 2483 glw::GLint source_channel_sizes[4] = { 0 }; 2484 2485 /* */ 2486 testInit(); 2487 2488 if (false == isTargetSupported(tgt_idx)) 2489 { 2490 throw tcu::NotSupportedError("Texture target is not support by implementation", "", __FILE__, __LINE__); 2491 } 2492 2493 /* Prepare and fill source texture */ 2494 prepareSourceTexture(format_idx, tgt_idx, source_channel_sizes); 2495 if (false == fillSourceTexture(format_idx, tgt_idx)) 2496 { 2497 TCU_FAIL("Failed to prepare source texture"); 2498 } 2499 2500 /* Iterate over all cases */ 2501 for (size_t access_idx = 0; access_idx < n_texture_access; ++access_idx) 2502 { 2503 /* Skip invalid cases */ 2504 if (false == isTargetSuppByAccess(access_idx, tgt_idx)) 2505 { 2506 continue; 2507 } 2508 2509 for (size_t r = 0; r < n_valid_values; ++r) 2510 { 2511 for (size_t g = 0; g < n_valid_values; ++g) 2512 { 2513 for (size_t b = 0; b < n_valid_values; ++b) 2514 { 2515 for (size_t a = 0; a < n_valid_values; ++a) 2516 { 2517 for (size_t channel_idx = 0; channel_idx < 4; ++channel_idx) 2518 { 2519 const testCase test_case = { channel_idx, 2520 format_idx, 2521 tgt_idx, 2522 access_idx, 2523 valid_values[r], 2524 valid_values[g], 2525 valid_values[b], 2526 valid_values[a], 2527 { source_channel_sizes[0], source_channel_sizes[1], 2528 source_channel_sizes[2], source_channel_sizes[3] } }; 2529 2530 executeTestCase(test_case); 2531 2532 deinitOutputTexture(); 2533 } /* iteration over channels */ 2534 } /* iteration over swizzle combinations */ 2535 } 2536 } 2537 } 2538 } /* iteration over access routines */ 2539 2540 /* Set result - exceptions are thrown in case of any error */ 2541 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2542 2543 /* Done */ 2544 return STOP; 2545} 2546 2547/** Deinitialization of output texture **/ 2548void SmokeTest::deinitOutputTexture() 2549{ 2550 if (m_out_tex_id != 0) 2551 { 2552 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2553 gl.deleteTextures(1, &m_out_tex_id); 2554 2555 m_out_tex_id = 0; 2556 } 2557} 2558 2559/** Deinitialization of textures **/ 2560void SmokeTest::deinitTextures() 2561{ 2562 deinitOutputTexture(); 2563 2564 if (m_source_tex_id != 0) 2565 { 2566 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2567 gl.deleteTextures(1, &m_source_tex_id); 2568 2569 m_source_tex_id = 0; 2570 } 2571} 2572 2573/** Captures and verifies contents of output texture 2574 * 2575 * @param test_case Test case instance 2576 * @param output_format_index Index of format used by output texture 2577 * @parma output_channel_size Size of storage used by output texture in bits 2578 * @param index_of_swizzled_channel Index of swizzled channel 2579 */ 2580void SmokeTest::captureAndVerify(const testCase& test_case, size_t output_format_index, glw::GLint output_channel_size, 2581 size_t index_of_swizzled_channel) 2582{ 2583 const _texture_format& output_format = texture_formats[output_format_index]; 2584 2585 /* */ 2586 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2587 2588 /* Storage for image data */ 2589 glw::GLubyte result_image[m_output_width * m_output_height * 4 /* channles */ * sizeof(glw::GLuint)]; 2590 2591 /* Get image data */ 2592 gl.bindTexture(GL_TEXTURE_2D, m_out_tex_id); 2593 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 2594 2595 gl.getTexImage(GL_TEXTURE_2D, 0 /* level */, output_format.m_format, output_format.m_type, result_image); 2596 GLU_EXPECT_NO_ERROR(gl.getError(), "getTexImage"); 2597 2598 /* Unbind output texture */ 2599 gl.bindTexture(GL_TEXTURE_2D, 0); 2600 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 2601 2602 /* Verification */ 2603 verifyOutputImage(test_case, output_format_index, output_channel_size, index_of_swizzled_channel, result_image); 2604} 2605 2606/** Draws four points 2607 * 2608 * @param target Target of source texture 2609 * @param texture_swizzle Set of texture swizzle values 2610 * @param use_rgba_enum If texture swizzle states should be set with RGBA enum or separe calls 2611 **/ 2612void SmokeTest::draw(glw::GLenum target, const glw::GLint* texture_swizzle, bool use_rgba_enum) 2613{ 2614 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2615 2616 /* Prepare source texture */ 2617 gl.activeTexture(GL_TEXTURE0); 2618 GLU_EXPECT_NO_ERROR(gl.getError(), "ActiveTexture"); 2619 2620 gl.bindTexture(target, m_source_tex_id); 2621 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 2622 2623 /* Set texture swizzle */ 2624 if (true == use_rgba_enum) 2625 { 2626 gl.texParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, texture_swizzle); 2627 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteriv"); 2628 } 2629 else 2630 { 2631 gl.texParameteri(target, GL_TEXTURE_SWIZZLE_R, texture_swizzle[0]); 2632 gl.texParameteri(target, GL_TEXTURE_SWIZZLE_G, texture_swizzle[1]); 2633 gl.texParameteri(target, GL_TEXTURE_SWIZZLE_B, texture_swizzle[2]); 2634 gl.texParameteri(target, GL_TEXTURE_SWIZZLE_A, texture_swizzle[3]); 2635 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri"); 2636 } 2637 2638 /* Clear */ 2639 gl.clear(GL_COLOR_BUFFER_BIT); 2640 GLU_EXPECT_NO_ERROR(gl.getError(), "Clear"); 2641 2642 /* Draw */ 2643 gl.drawArrays(GL_TRIANGLE_STRIP, 0 /* first */, 4 /* count */); 2644 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays"); 2645 2646 /* Revert texture swizzle */ 2647 gl.texParameteri(target, GL_TEXTURE_SWIZZLE_R, GL_RED); 2648 gl.texParameteri(target, GL_TEXTURE_SWIZZLE_G, GL_GREEN); 2649 gl.texParameteri(target, GL_TEXTURE_SWIZZLE_B, GL_BLUE); 2650 gl.texParameteri(target, GL_TEXTURE_SWIZZLE_A, GL_ALPHA); 2651 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri"); 2652 2653 /* Unbind source texture */ 2654 gl.bindTexture(target, 0); 2655 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 2656} 2657 2658/** Executes test case 2659 * 2660 * @param test_case Test case instance 2661 **/ 2662void SmokeTest::executeTestCase(const testCase& test_case) 2663{ 2664 const _texture_format& source_format = texture_formats[test_case.m_source_texture_format_index]; 2665 const glw::GLint red = test_case.m_texture_swizzle_red; 2666 const glw::GLint green = test_case.m_texture_swizzle_green; 2667 const glw::GLint blue = test_case.m_texture_swizzle_blue; 2668 const glw::GLint alpha = test_case.m_texture_swizzle_alpha; 2669 const glw::GLint param[4] = { red, green, blue, alpha }; 2670 const size_t channel = get_swizzled_channel_idx(test_case.m_channel_index, param); 2671 glw::GLint out_channel_size = 0; 2672 const glw::GLenum out_internal_format = get_internal_format_for_channel(source_format, channel); 2673 const size_t out_format_idx = get_index_of_format(out_internal_format); 2674 2675 /* */ 2676 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2677 2678 /* Prepare output */ 2679 prepareOutputTexture(out_format_idx); 2680 2681 gl.bindTexture(GL_TEXTURE_2D, m_out_tex_id); 2682 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 2683 2684 gl.bindFramebuffer(GL_FRAMEBUFFER, m_test_fbo_id); 2685 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer"); 2686 2687 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_out_tex_id, 0 /* level */); 2688 GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture2D"); 2689 2690 /* Set Viewport */ 2691 gl.viewport(0 /* x */, 0 /* y */, m_output_width, m_output_height); 2692 GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport"); 2693 2694 /* Get internal storage size of output texture */ 2695 gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0 /* level */, GL_TEXTURE_RED_SIZE, &out_channel_size); 2696 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv"); 2697 2698 /* Unbind output texture */ 2699 gl.bindTexture(GL_TEXTURE_2D, 0); 2700 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 2701 2702 prepareAndTestProgram(test_case, out_format_idx, out_channel_size, channel, true); 2703 prepareAndTestProgram(test_case, out_format_idx, out_channel_size, channel, false); 2704 2705 /* Unbind FBO */ 2706 gl.bindFramebuffer(GL_FRAMEBUFFER, 0); 2707 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer"); 2708} 2709 2710/** Fills source texture 2711 * 2712 * @param format_idx Index of format 2713 * @param target_idx Index of target 2714 * 2715 * @return True if operation was successful, false other wise 2716 **/ 2717bool SmokeTest::fillSourceTexture(size_t format_idx, size_t target_idx) 2718{ 2719 static const glw::GLuint rgba32ui[4] = { 0x3fffffff, 0x7fffffff, 0xbfffffff, 0xffffffff }; 2720 2721 const glw::GLenum target = texture_targets[target_idx].m_target; 2722 const _texture_format& texture_format = texture_formats[format_idx]; 2723 2724 /* */ 2725 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2726 const glw::GLvoid* data = 0; 2727 2728 /* Bind texture and FBO */ 2729 gl.bindTexture(target, m_source_tex_id); 2730 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 2731 2732 /* Set color */ 2733 switch (texture_format.m_internal_format) 2734 { 2735 case GL_RGBA32UI: 2736 data = (const glw::GLubyte*)rgba32ui; 2737 break; 2738 2739 default: 2740 TCU_FAIL("Invalid enum"); 2741 break; 2742 } 2743 2744 /* Attach texture */ 2745 switch (target) 2746 { 2747 case GL_TEXTURE_2D_ARRAY: 2748 gl.texSubImage3D(target, 0 /* level */, 0 /* x */, 0 /* y */, 0 /* z */, m_width, m_height, m_depth, 2749 texture_format.m_format, texture_format.m_type, data); 2750 break; 2751 2752 default: 2753 TCU_FAIL("Invalid enum"); 2754 break; 2755 } 2756 2757 /* Unbind */ 2758 gl.bindTexture(target, 0); 2759 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 2760 2761 /* Done */ 2762 return true; 2763} 2764 2765/** Gets source of fragment shader 2766 * 2767 * @param test_case Test case instance 2768 * @param output_format_index Index of output format 2769 * @param is_tested_stage Selects if fragment or vertex shader makes texture access 2770 * 2771 * @return Source of shader 2772 **/ 2773std::string SmokeTest::getFragmentShader(const testCase& test_case, size_t output_format_index, bool is_tested_stage) 2774{ 2775 static const glw::GLchar* fs_blank_template = "#version 330 core\n" 2776 "\n" 2777 "flat in BASIC_TYPE result;\n" 2778 "\n" 2779 "out BASIC_TYPE out_color;\n" 2780 "\n" 2781 "void main()\n" 2782 "{\n" 2783 " out_color = result;\n" 2784 "}\n" 2785 "\n"; 2786 2787 static const glw::GLchar* fs_test_template = "#version 330 core\n" 2788 "\n" 2789 "uniform PREFIXsamplerSAMPLER_TYPE sampler;\n" 2790 "\n" 2791 "out BASIC_TYPE out_color;\n" 2792 "\n" 2793 "void main()\n" 2794 "{\n" 2795 " BASIC_TYPE result = TEXTURE_ACCESS(sampler, ARGUMENTS).CHANNEL;\n" 2796 "\n" 2797 " out_color = result;\n" 2798 "}\n" 2799 "\n"; 2800 2801 /* */ 2802 const std::string& arguments = prepareArguments(test_case); 2803 const _texture_access& access = texture_access[test_case.m_texture_access_index]; 2804 const glw::GLchar* channel = channels[test_case.m_channel_index]; 2805 const _texture_format& output_format = texture_formats[output_format_index]; 2806 const _texture_format& source_format = texture_formats[test_case.m_source_texture_format_index]; 2807 const _texture_target& target = texture_targets[test_case.m_source_texture_target_index]; 2808 2809 std::string fs; 2810 size_t position = 0; 2811 2812 if (is_tested_stage) 2813 { 2814 fs = fs_test_template; 2815 2816 Utils::replaceToken("PREFIX", position, source_format.m_sampler.m_sampler_prefix, fs); 2817 Utils::replaceToken("SAMPLER_TYPE", position, target.m_sampler_type, fs); 2818 Utils::replaceToken("BASIC_TYPE", position, output_format.m_sampler.m_basic_type, fs); 2819 Utils::replaceToken("BASIC_TYPE", position, source_format.m_sampler.m_basic_type, fs); 2820 Utils::replaceToken("TEXTURE_ACCESS", position, access.m_name, fs); 2821 Utils::replaceToken("ARGUMENTS", position, arguments.c_str(), fs); 2822 Utils::replaceToken("CHANNEL", position, channel, fs); 2823 } 2824 else 2825 { 2826 fs = fs_blank_template; 2827 2828 Utils::replaceToken("BASIC_TYPE", position, source_format.m_sampler.m_basic_type, fs); 2829 Utils::replaceToken("BASIC_TYPE", position, output_format.m_sampler.m_basic_type, fs); 2830 } 2831 2832 return fs; 2833} 2834 2835/** Gets source of vertex shader 2836 * 2837 * @param test_case Test case instance 2838 * @param is_tested_stage Selects if vertex or fragment shader makes texture access 2839 * 2840 * @return Source of shader 2841 **/ 2842std::string SmokeTest::getVertexShader(const testCase& test_case, bool is_tested_stage) 2843{ 2844 static const glw::GLchar* vs_blank_template = "#version 330 core\n" 2845 "\n" 2846 "void main()\n" 2847 "{\n" 2848 " switch (gl_VertexID)\n" 2849 " {\n" 2850 " case 0: gl_Position = vec4(-1.0, 1.0, 0.0, 1.0); break; \n" 2851 " case 1: gl_Position = vec4( 1.0, 1.0, 0.0, 1.0); break; \n" 2852 " case 2: gl_Position = vec4(-1.0,-1.0, 0.0, 1.0); break; \n" 2853 " case 3: gl_Position = vec4( 1.0,-1.0, 0.0, 1.0); break; \n" 2854 " }\n" 2855 "}\n" 2856 "\n"; 2857 2858 static const glw::GLchar* vs_test_template = "#version 330 core\n" 2859 "\n" 2860 "uniform PREFIXsamplerSAMPLER_TYPE sampler;\n" 2861 "\n" 2862 "flat out BASIC_TYPE result;\n" 2863 "\n" 2864 "void main()\n" 2865 "{\n" 2866 " result = TEXTURE_ACCESS(sampler, ARGUMENTS).CHANNEL;\n" 2867 "\n" 2868 " switch (gl_VertexID)\n" 2869 " {\n" 2870 " case 0: gl_Position = vec4(-1.0, 1.0, 0.0, 1.0); break; \n" 2871 " case 1: gl_Position = vec4( 1.0, 1.0, 0.0, 1.0); break; \n" 2872 " case 2: gl_Position = vec4(-1.0,-1.0, 0.0, 1.0); break; \n" 2873 " case 3: gl_Position = vec4( 1.0,-1.0, 0.0, 1.0); break; \n" 2874 " }\n" 2875 "}\n" 2876 "\n"; 2877 2878 std::string vs; 2879 2880 if (is_tested_stage) 2881 { 2882 /* */ 2883 const std::string& arguments = prepareArguments(test_case); 2884 const _texture_access& access = texture_access[test_case.m_texture_access_index]; 2885 const glw::GLchar* channel = channels[test_case.m_channel_index]; 2886 const _texture_format& source_format = texture_formats[test_case.m_source_texture_format_index]; 2887 const _texture_target& target = texture_targets[test_case.m_source_texture_target_index]; 2888 2889 size_t position = 0; 2890 2891 vs = vs_test_template; 2892 2893 Utils::replaceToken("PREFIX", position, source_format.m_sampler.m_sampler_prefix, vs); 2894 Utils::replaceToken("SAMPLER_TYPE", position, target.m_sampler_type, vs); 2895 Utils::replaceToken("BASIC_TYPE", position, source_format.m_sampler.m_basic_type, vs); 2896 Utils::replaceToken("TEXTURE_ACCESS", position, access.m_name, vs); 2897 Utils::replaceToken("ARGUMENTS", position, arguments.c_str(), vs); 2898 Utils::replaceToken("CHANNEL", position, channel, vs); 2899 } 2900 else 2901 { 2902 vs = vs_blank_template; 2903 } 2904 2905 return vs; 2906} 2907 2908/** Check if target is supported 2909 * 2910 * @param target_idx Index of target 2911 * 2912 * @return true if target is supported, false otherwise 2913 **/ 2914bool SmokeTest::isTargetSupported(size_t target_idx) 2915{ 2916 const _texture_target& target = texture_targets[target_idx]; 2917 2918 bool is_supported = true; 2919 2920 switch (target.m_target) 2921 { 2922 case GL_TEXTURE_2D_MULTISAMPLE: 2923 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 2924 is_supported = m_is_ms_supported; 2925 break; 2926 2927 default: 2928 break; 2929 } 2930 2931 return is_supported; 2932} 2933 2934/** Check if target is supported by access routine 2935 * 2936 * @param access_idx Index of access routine 2937 * @param target_idx Index of target 2938 * 2939 * @return true if target is supported, false otherwise 2940 **/ 2941bool SmokeTest::isTargetSuppByAccess(size_t access_idx, size_t target_idx) 2942{ 2943 const _texture_access& access = texture_access[access_idx]; 2944 const _texture_target& source_target = texture_targets[target_idx]; 2945 2946 if ((false == source_target.m_support_integral_coordinates) && (true == access.m_use_integral_coordinates)) 2947 { 2948 /* Cases are not valid, texelFetch* is not supported by the target */ 2949 return false; 2950 } 2951 2952 if ((false == source_target.m_support_offset) && (true == access.m_use_offsets)) 2953 { 2954 /* Cases are not valid, texture*Offset is not supported by the target */ 2955 return false; 2956 } 2957 2958 if ((false == source_target.m_support_lod) && (true == access.m_use_lod)) 2959 { 2960 /* Access is one of texture*Lod* or texelFetch* */ 2961 /* Target is one of MS or rect */ 2962 2963 if ((true == source_target.m_require_multisampling) && (true == access.m_support_multisampling)) 2964 { 2965 /* texelFetch */ 2966 /* One of MS targets */ 2967 return true; 2968 } 2969 2970 /* Cases are not valid, either lod or sample is required but target does not supported that */ 2971 return false; 2972 } 2973 2974 if ((false == source_target.m_supports_proj) && (1 == access.m_n_coordinates)) 2975 { 2976 /* Cases are not valid, textureProj* is not supported by the target */ 2977 return false; 2978 } 2979 2980 if ((true == source_target.m_require_multisampling) && (false == access.m_support_multisampling)) 2981 { 2982 /* Cases are not valid, texelFetch* is not supported by the target */ 2983 return false; 2984 } 2985 2986 return true; 2987} 2988 2989/** Check if target is supported by format 2990 * 2991 * @param format_idx Index of format 2992 * @param target_idx Index of target 2993 * 2994 * @return true if target is supported, false otherwise 2995 **/ 2996bool SmokeTest::isTargetSuppByFormat(size_t format_idx, size_t target_idx) 2997{ 2998 const _texture_format& format = texture_formats[format_idx]; 2999 const _texture_target& source_target = texture_targets[target_idx]; 3000 3001 bool is_supported = true; 3002 3003 switch (format.m_internal_format) 3004 { 3005 case GL_DEPTH_COMPONENT16: 3006 case GL_DEPTH_COMPONENT24: 3007 case GL_DEPTH_COMPONENT32: 3008 case GL_DEPTH_COMPONENT32F: 3009 case GL_DEPTH24_STENCIL8: 3010 case GL_DEPTH32F_STENCIL8: 3011 switch (source_target.m_target) 3012 { 3013 case GL_TEXTURE_3D: 3014 case GL_TEXTURE_2D_MULTISAMPLE: 3015 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 3016 is_supported = false; 3017 break; 3018 default: 3019 break; 3020 } 3021 break; 3022 3023 case GL_RGB9_E5: 3024 switch (source_target.m_target) 3025 { 3026 case GL_TEXTURE_2D_MULTISAMPLE: 3027 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 3028 is_supported = false; 3029 break; 3030 default: 3031 break; 3032 } 3033 break; 3034 3035 default: 3036 break; 3037 } 3038 3039 return is_supported; 3040} 3041 3042/** Logs details of test case 3043 * 3044 * @parma test_case Test case instance 3045 **/ 3046void SmokeTest::logTestCaseDetials(const testCase& test_case) 3047{ 3048 const glw::GLenum target = texture_targets[test_case.m_source_texture_target_index].m_target; 3049 const _texture_format& source_format = texture_formats[test_case.m_source_texture_format_index]; 3050 const glw::GLint red = test_case.m_texture_swizzle_red; 3051 const glw::GLint green = test_case.m_texture_swizzle_green; 3052 const glw::GLint blue = test_case.m_texture_swizzle_blue; 3053 const glw::GLint alpha = test_case.m_texture_swizzle_alpha; 3054 const glw::GLint param[4] = { red, green, blue, alpha }; 3055 const size_t channel = get_swizzled_channel_idx(test_case.m_channel_index, param); 3056 const glw::GLenum out_internal_format = get_internal_format_for_channel(source_format, channel); 3057 const size_t out_format_idx = get_index_of_format(out_internal_format); 3058 const _texture_format& output_format = texture_formats[out_format_idx]; 3059 3060 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case details. Source texture: Target: " 3061 << glu::getTextureTargetStr(target) 3062 << ". Format: " << glu::getTextureFormatName(source_format.m_internal_format) 3063 << ", " << glu::getTextureFormatName(source_format.m_format) << ", " 3064 << glu::getTypeStr(source_format.m_type) 3065 << ", DS: " << glu::getTextureDepthStencilModeName(source_format.m_ds_mode) 3066 << ". Swizzle: [" << glu::getTextureSwizzleStr(red) << ", " 3067 << glu::getTextureSwizzleStr(green) << ", " << glu::getTextureSwizzleStr(blue) 3068 << ", " << glu::getTextureSwizzleStr(alpha) 3069 << "]. Channel: " << channels[test_case.m_channel_index] 3070 << ". Access: " << texture_access[test_case.m_texture_access_index].m_name 3071 << ". Output texture: Format: " 3072 << glu::getTextureFormatName(output_format.m_internal_format) << ", " 3073 << glu::getTextureFormatName(output_format.m_format) << ", " 3074 << glu::getTypeStr(output_format.m_type) << "." << tcu::TestLog::EndMessage; 3075} 3076 3077/** Prepares program then draws and verifies resutls for both ways of setting texture swizzle 3078 * 3079 * @param test_case Test case instance 3080 * @param output_format_index Index of format used by output texture 3081 * @parma output_channel_size Size of storage used by output texture in bits 3082 * @param index_of_swizzled_channel Index of swizzled channel 3083 * @param test_vertex_stage Selects if vertex or fragment shader should execute texture access 3084 **/ 3085void SmokeTest::prepareAndTestProgram(const testCase& test_case, size_t output_format_index, 3086 glw::GLint output_channel_size, size_t index_of_swizzled_channel, 3087 bool test_vertex_stage) 3088{ 3089 const _texture_target& source_target = texture_targets[test_case.m_source_texture_target_index]; 3090 const glw::GLint red = test_case.m_texture_swizzle_red; 3091 const glw::GLint green = test_case.m_texture_swizzle_green; 3092 const glw::GLint blue = test_case.m_texture_swizzle_blue; 3093 const glw::GLint alpha = test_case.m_texture_swizzle_alpha; 3094 const glw::GLint param[4] = { red, green, blue, alpha }; 3095 3096 /* */ 3097 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3098 3099 /* Prepare program */ 3100 const std::string& fs = getFragmentShader(test_case, output_format_index, !test_vertex_stage); 3101 const std::string& vs = getVertexShader(test_case, test_vertex_stage); 3102 3103 Utils::programInfo program(m_context); 3104 program.build(fs.c_str(), vs.c_str()); 3105 3106 gl.useProgram(program.m_program_object_id); 3107 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram"); 3108 3109 /* Prepare sampler */ 3110 glw::GLint location = gl.getUniformLocation(program.m_program_object_id, "sampler"); 3111 GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformLocation"); 3112 3113 if (-1 == location) 3114 { 3115 TCU_FAIL("Uniform is not available"); 3116 } 3117 3118 gl.uniform1i(location, 0 /* texture unit */); 3119 GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i"); 3120 3121 draw(source_target.m_target, param, false); 3122 captureAndVerify(test_case, output_format_index, output_channel_size, index_of_swizzled_channel); 3123 3124 draw(source_target.m_target, param, true); 3125 captureAndVerify(test_case, output_format_index, output_channel_size, index_of_swizzled_channel); 3126} 3127 3128/** Prepares arguments for texture access routine call 3129 * 3130 * @param test_case Test case instance 3131 * 3132 * @return Source code 3133 **/ 3134std::string SmokeTest::prepareArguments(const testCase& test_case) 3135{ 3136 const _texture_access& access = texture_access[test_case.m_texture_access_index]; 3137 const _texture_target& target = texture_targets[test_case.m_source_texture_target_index]; 3138 3139 std::string arguments = "COORDINATESLODDERIVATIVESOFFSETSSAMPLE"; 3140 const std::string& coordinates = prepareCoordinates(test_case); 3141 3142 size_t position = 0; 3143 3144 Utils::replaceToken("COORDINATES", position, coordinates.c_str(), arguments); 3145 3146 if ((true == access.m_use_lod) && (true == target.m_support_lod)) 3147 { 3148 Utils::replaceToken("LODDERIVATIVES", position, ", int(0)", arguments); 3149 } 3150 else if (true == access.m_use_derivaties) 3151 { 3152 const std::string& derivatives_0 = prepareDerivatives(test_case, 0); 3153 const std::string& derivatives_1 = prepareDerivatives(test_case, 1); 3154 const size_t start_pos = position; 3155 3156 Utils::replaceToken("LODDERIVATIVES", position, ", XXXXX, XXXXX", arguments); 3157 position = start_pos + 2; 3158 Utils::replaceToken("XXXXX", position, derivatives_0.c_str(), arguments); 3159 Utils::replaceToken("XXXXX", position, derivatives_1.c_str(), arguments); 3160 } 3161 else 3162 { 3163 Utils::replaceToken("LODDERIVATIVES", position, "", arguments); 3164 } 3165 3166 if (true == access.m_use_offsets) 3167 { 3168 const std::string& offsets = prepareOffsets(test_case); 3169 const size_t start_pos = position; 3170 3171 Utils::replaceToken("OFFSETS", position, ", XXXXX", arguments); 3172 position = start_pos + 2; 3173 Utils::replaceToken("XXXXX", position, offsets.c_str(), arguments); 3174 } 3175 else 3176 { 3177 Utils::replaceToken("OFFSETS", position, "", arguments); 3178 } 3179 3180 if ((true == target.m_require_multisampling) && (true == access.m_support_multisampling)) 3181 { 3182 const std::string& sample = prepareSample(); 3183 const size_t start_pos = position; 3184 3185 Utils::replaceToken("SAMPLE", position, ", XX", arguments); 3186 position = start_pos + 2; 3187 Utils::replaceToken("XX", position, sample.c_str(), arguments); 3188 } 3189 else 3190 { 3191 Utils::replaceToken("SAMPLE", position, "", arguments); 3192 } 3193 3194 return arguments; 3195} 3196 3197/** Prepares coordinate for texture access routine call 3198 * 3199 * @param test_case Test case instance 3200 * 3201 * @return Source code 3202 **/ 3203std::string SmokeTest::prepareCoordinates(const testCase& test_case) 3204{ 3205 const _texture_access& access = texture_access[test_case.m_texture_access_index]; 3206 const _texture_target& target = texture_targets[test_case.m_source_texture_target_index]; 3207 3208 const glw::GLchar* type = 0; 3209 3210 std::string coordinates = "TYPE(VAL_LIST)"; 3211 3212 if (false == access.m_use_integral_coordinates) 3213 { 3214 switch (access.m_n_coordinates + target.m_n_array_coordinates + target.m_n_coordinates) 3215 { 3216 case 1: 3217 type = "float"; 3218 break; 3219 case 2: 3220 type = "vec2"; 3221 break; 3222 case 3: 3223 type = "vec3"; 3224 break; 3225 case 4: 3226 type = "vec4"; 3227 break; 3228 default: 3229 TCU_FAIL("Invalid value"); 3230 break; 3231 } 3232 } 3233 else 3234 { 3235 switch (access.m_n_coordinates + target.m_n_array_coordinates + target.m_n_coordinates) 3236 { 3237 case 1: 3238 type = "int"; 3239 break; 3240 case 2: 3241 type = "ivec2"; 3242 break; 3243 case 3: 3244 type = "ivec3"; 3245 break; 3246 case 4: 3247 type = "ivec4"; 3248 break; 3249 default: 3250 TCU_FAIL("Invalid value"); 3251 break; 3252 } 3253 } 3254 3255 size_t position = 0; 3256 3257 Utils::replaceToken("TYPE", position, type, coordinates); 3258 3259 for (size_t i = 0; i < target.m_n_coordinates; ++i) 3260 { 3261 size_t start_position = position; 3262 3263 Utils::replaceToken("VAL_LIST", position, "0, VAL_LIST", coordinates); 3264 3265 position = start_position + 1; 3266 } 3267 3268 for (size_t i = 0; i < target.m_n_array_coordinates; ++i) 3269 { 3270 size_t start_position = position; 3271 3272 Utils::replaceToken("VAL_LIST", position, "0, VAL_LIST", coordinates); 3273 3274 position = start_position + 1; 3275 } 3276 3277 for (size_t i = 0; i < access.m_n_coordinates; ++i) 3278 { 3279 size_t start_position = position; 3280 3281 Utils::replaceToken("VAL_LIST", position, "1, VAL_LIST", coordinates); 3282 3283 position = start_position + 1; 3284 } 3285 3286 Utils::replaceToken(", VAL_LIST", position, "", coordinates); 3287 3288 return coordinates; 3289} 3290 3291/** Prepares derivatives for texture access routine call 3292 * 3293 * @param test_case Test case instance 3294 * 3295 * @return Source code 3296 **/ 3297std::string SmokeTest::prepareDerivatives(const testCase& test_case, size_t index) 3298{ 3299 const _texture_target& target = texture_targets[test_case.m_source_texture_target_index]; 3300 3301 const glw::GLchar* type = 0; 3302 3303 std::string derivatives = "TYPE(VAL_LIST)"; 3304 3305 switch (target.m_n_derivatives) 3306 { 3307 case 1: 3308 type = "float"; 3309 break; 3310 case 2: 3311 type = "vec2"; 3312 break; 3313 case 3: 3314 type = "vec3"; 3315 break; 3316 case 4: 3317 type = "vec4"; 3318 break; 3319 default: 3320 TCU_FAIL("Invalid value"); 3321 break; 3322 } 3323 3324 size_t position = 0; 3325 3326 Utils::replaceToken("TYPE", position, type, derivatives); 3327 3328 for (size_t i = 0; i < target.m_n_derivatives; ++i) 3329 { 3330 size_t start_position = position; 3331 3332 if (index == i) 3333 { 3334 Utils::replaceToken("VAL_LIST", position, "1.0, VAL_LIST", derivatives); 3335 } 3336 else 3337 { 3338 Utils::replaceToken("VAL_LIST", position, "0.0, VAL_LIST", derivatives); 3339 } 3340 3341 position = start_position + 1; 3342 } 3343 3344 Utils::replaceToken(", VAL_LIST", position, "", derivatives); 3345 3346 return derivatives; 3347} 3348 3349/** Prepares offsets for texture access routine call 3350 * 3351 * @param test_case Test case instance 3352 * 3353 * @return Source code 3354 **/ 3355std::string SmokeTest::prepareOffsets(const testCase& test_case) 3356{ 3357 const _texture_target& target = texture_targets[test_case.m_source_texture_target_index]; 3358 3359 const glw::GLchar* type = DE_NULL; 3360 3361 std::string offsets = "TYPE(VAL_LIST)"; 3362 3363 switch (target.m_n_derivatives) 3364 { 3365 case 1: 3366 type = "int"; 3367 break; 3368 case 2: 3369 type = "ivec2"; 3370 break; 3371 case 3: 3372 type = "ivec3"; 3373 break; 3374 case 4: 3375 type = "ivec4"; 3376 break; 3377 default: 3378 TCU_FAIL("Invalid value"); 3379 break; 3380 } 3381 3382 size_t position = 0; 3383 3384 Utils::replaceToken("TYPE", position, type, offsets); 3385 3386 for (size_t i = 0; i < target.m_n_coordinates; ++i) 3387 { 3388 size_t start_position = position; 3389 3390 Utils::replaceToken("VAL_LIST", position, "0, VAL_LIST", offsets); 3391 3392 position = start_position + 1; 3393 } 3394 3395 Utils::replaceToken(", VAL_LIST", position, "", offsets); 3396 3397 return offsets; 3398} 3399 3400/** Prepares output texture 3401 * 3402 * @param format_idx Index of texture format 3403 **/ 3404void SmokeTest::prepareOutputTexture(size_t format_idx) 3405{ 3406 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3407 3408 const _texture_format& format = texture_formats[format_idx]; 3409 3410 gl.genTextures(1, &m_out_tex_id); 3411 GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures"); 3412 3413 gl.bindTexture(GL_TEXTURE_2D, m_out_tex_id); 3414 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 3415 3416 gl.texImage2D(GL_TEXTURE_2D, 0 /* level */, format.m_internal_format, m_output_width, m_output_height, 3417 0 /* border */, format.m_format, format.m_type, 0 /* pixels */); 3418 GLU_EXPECT_NO_ERROR(gl.getError(), "TexImage2D"); 3419 3420 gl.bindTexture(GL_TEXTURE_2D, 0); 3421 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 3422} 3423 3424/** Prepares sample for texture access routine call 3425 * 3426 * @return Source code 3427 **/ 3428std::string SmokeTest::prepareSample() 3429{ 3430 glw::GLsizei samples = 1; 3431 std::stringstream stream; 3432 3433 /* Get max number of samples */ 3434 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3435 3436 gl.getIntegerv(GL_MAX_SAMPLES, &samples); 3437 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 3438 3439 stream << samples - 1; 3440 3441 return stream.str(); 3442} 3443 3444/** Prepares source texture 3445 * 3446 * @param format_idx Index of texture format 3447 * @param target_idx Index of texture target 3448 * @param out_sizes Sizes of storage used for texture channels 3449 **/ 3450void SmokeTest::prepareSourceTexture(size_t format_idx, size_t target_idx, glw::GLint out_sizes[4]) 3451{ 3452 static const glw::GLint border = 0; 3453 static const glw::GLint level = 0; 3454 3455 /* */ 3456 const glw::GLenum target = texture_targets[target_idx].m_target; 3457 const _texture_format& texture_format = texture_formats[format_idx]; 3458 3459 /* */ 3460 glw::GLenum error = 0; 3461 const glw::GLenum format = texture_format.m_format; 3462 const glw::GLchar* function_name = "unknown"; 3463 const glw::GLenum internal_format = texture_format.m_internal_format; 3464 glw::GLsizei samples = 1; 3465 glw::GLenum target_get_prm = target; 3466 const glw::GLenum type = texture_format.m_type; 3467 3468 /* */ 3469 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3470 3471 /* Get max number of samples */ 3472 gl.getIntegerv(GL_MAX_SAMPLES, &samples); 3473 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 3474 3475 /* Generate and bind */ 3476 gl.genTextures(1, &m_source_tex_id); 3477 GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures"); 3478 3479 gl.bindTexture(target, m_source_tex_id); 3480 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 3481 3482 /* Allocate storage */ 3483 switch (target) 3484 { 3485 case GL_TEXTURE_1D: 3486 3487 gl.texImage1D(target, level, internal_format, m_width, border, format, type, 0 /* pixels */); 3488 error = gl.getError(); 3489 function_name = "TexImage1D"; 3490 3491 break; 3492 3493 case GL_TEXTURE_1D_ARRAY: 3494 case GL_TEXTURE_2D: 3495 case GL_TEXTURE_RECTANGLE: 3496 gl.texImage2D(target, level, internal_format, m_width, m_height, border, format, type, 0 /* pixels */); 3497 error = gl.getError(); 3498 function_name = "TexImage2D"; 3499 3500 break; 3501 3502 case GL_TEXTURE_2D_ARRAY: 3503 case GL_TEXTURE_3D: 3504 gl.texImage3D(target, level, internal_format, m_width, m_height, m_depth, border, format, type, 0 /* pixels */); 3505 error = gl.getError(); 3506 function_name = "TexImage3D"; 3507 3508 break; 3509 3510 case GL_TEXTURE_CUBE_MAP: 3511 for (size_t i = 0; i < n_cube_map_faces; ++i) 3512 { 3513 gl.texImage2D(cube_map_faces[i], level, internal_format, m_width, m_height, border, format, type, 3514 0 /* pixels */); 3515 } 3516 error = gl.getError(); 3517 function_name = "TexImage2D"; 3518 3519 target_get_prm = cube_map_faces[0]; 3520 3521 break; 3522 3523 case GL_TEXTURE_2D_MULTISAMPLE: 3524 gl.texImage2DMultisample(target, samples, internal_format, m_width, m_height, 3525 GL_FALSE /* fixedsamplelocation */); 3526 error = gl.getError(); 3527 function_name = "TexImage2DMultisample"; 3528 3529 break; 3530 3531 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 3532 gl.texImage3DMultisample(target, samples, internal_format, m_width, m_height, m_depth, 3533 GL_FALSE /* fixedsamplelocation */); 3534 error = gl.getError(); 3535 function_name = "TexImage3DMultisample"; 3536 3537 break; 3538 3539 default: 3540 TCU_FAIL("Invalid enum"); 3541 break; 3542 } 3543 3544 /* Log error */ 3545 GLU_EXPECT_NO_ERROR(error, function_name); 3546 3547 /* Make texture complete and set ds texture mode */ 3548 if ((GL_TEXTURE_2D_MULTISAMPLE != target) && (GL_TEXTURE_2D_MULTISAMPLE_ARRAY != target) && 3549 (GL_TEXTURE_RECTANGLE != target)) 3550 { 3551 gl.texParameteri(target, GL_TEXTURE_BASE_LEVEL, 0); 3552 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri"); 3553 3554 gl.texParameteri(target, GL_TEXTURE_MAX_LEVEL, 0); 3555 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri"); 3556 3557 gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 3558 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri"); 3559 3560 gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 3561 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri"); 3562 } 3563 3564 if (texture_format.m_ds_mode == GL_STENCIL_INDEX) 3565 { 3566 gl.texParameteri(target, GL_DEPTH_STENCIL_TEXTURE_MODE, texture_format.m_ds_mode); 3567 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri"); 3568 } 3569 3570 /* Get internal storage sizes */ 3571 switch (internal_format) 3572 { 3573 case GL_DEPTH24_STENCIL8: 3574 case GL_DEPTH32F_STENCIL8: 3575 3576 gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_STENCIL_SIZE, out_sizes + 1); 3577 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv"); 3578 3579 /* Fall through */ 3580 3581 case GL_DEPTH_COMPONENT16: 3582 case GL_DEPTH_COMPONENT24: 3583 case GL_DEPTH_COMPONENT32: 3584 case GL_DEPTH_COMPONENT32F: 3585 3586 gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_DEPTH_SIZE, out_sizes + 0); 3587 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv"); 3588 3589 break; 3590 3591 default: 3592 3593 gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_RED_SIZE, out_sizes + 0); 3594 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv"); 3595 3596 gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_GREEN_SIZE, out_sizes + 1); 3597 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv"); 3598 3599 gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_BLUE_SIZE, out_sizes + 2); 3600 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv"); 3601 3602 gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_ALPHA_SIZE, out_sizes + 3); 3603 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv"); 3604 3605 break; 3606 } 3607 3608 /* Unbind texture */ 3609 gl.bindTexture(target, 0); 3610 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 3611} 3612 3613/** Initializes frame buffer and vertex array 3614 * 3615 **/ 3616void SmokeTest::testInit() 3617{ 3618 /* */ 3619 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3620 3621 glw::GLint major = 0; 3622 glw::GLint minor = 0; 3623 3624 gl.getIntegerv(GL_MAJOR_VERSION, &major); 3625 gl.getIntegerv(GL_MINOR_VERSION, &minor); 3626 3627 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 3628 3629 if (4 < major) 3630 { 3631 m_is_ms_supported = true; 3632 } 3633 else if (4 == major) 3634 { 3635 if (3 <= minor) 3636 { 3637 m_is_ms_supported = true; 3638 } 3639 } 3640 3641 /* Context is below 4.3 */ 3642 if (false == m_is_ms_supported) 3643 { 3644 m_is_ms_supported = m_context.getContextInfo().isExtensionSupported("GL_ARB_texture_storage_multisample"); 3645 } 3646 3647#if ENABLE_DEBUG 3648 3649 gl.debugMessageCallback(debug_proc, &m_context); 3650 GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback"); 3651 3652#endif /* ENABLE_DEBUG */ 3653 3654 /* Prepare FBOs */ 3655 gl.genFramebuffers(1, &m_prepare_fbo_id); 3656 GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers"); 3657 3658 gl.genFramebuffers(1, &m_test_fbo_id); 3659 GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers"); 3660 3661 /* Prepare blank VAO */ 3662 gl.genVertexArrays(1, &m_vao_id); 3663 GLU_EXPECT_NO_ERROR(gl.getError(), "genVertexArrays"); 3664 3665 gl.bindVertexArray(m_vao_id); 3666 GLU_EXPECT_NO_ERROR(gl.getError(), "bindVertexArray"); 3667} 3668 3669/** Verifies contents of output image 3670 * 3671 * @param test_case Test case instance 3672 * @param ignored 3673 * @param ignored 3674 * @param index_of_swizzled_channel Index of swizzled channel 3675 * @param data Image contents 3676 **/ 3677void SmokeTest::verifyOutputImage(const testCase& test_case, size_t /* output_format_index */, 3678 glw::GLint /* output_channel_size */, size_t index_of_swizzled_channel, 3679 const glw::GLubyte* data) 3680{ 3681 static const glw::GLuint rgba32ui[6] = { 0x3fffffff, 0x7fffffff, 0xbfffffff, 0xffffffff, 1, 0 }; 3682 3683 const _texture_format& source_format = texture_formats[test_case.m_source_texture_format_index]; 3684 3685 /* Set color */ 3686 switch (source_format.m_internal_format) 3687 { 3688 case GL_RGBA32UI: 3689 { 3690 glw::GLuint expected_value = rgba32ui[index_of_swizzled_channel]; 3691 const glw::GLuint* image = (glw::GLuint*)data; 3692 3693 for (size_t i = 0; i < m_output_width * m_output_height; ++i) 3694 { 3695 if (image[i] != expected_value) 3696 { 3697 TCU_FAIL("Found pixel with wrong value"); 3698 } 3699 } 3700 } 3701 break; 3702 3703 default: 3704 TCU_FAIL("Invalid enum"); 3705 break; 3706 } 3707} 3708 3709/** Constructor. 3710 * 3711 * @param context Rendering context. 3712 **/ 3713FunctionalTest::FunctionalTest(deqp::Context& context) 3714 : SmokeTest(context, "functional", 3715 "Verifies that swizzle is respected for textures of different formats and targets") 3716{ 3717 /* Left blank intentionally */ 3718} 3719 3720/** Executes test iteration. 3721 * 3722 * @return Returns STOP. 3723 */ 3724tcu::TestNode::IterateResult FunctionalTest::iterate() 3725{ 3726 3727#if FUNCTIONAL_TEST_ALL_FORMATS == 0 3728 3729 static const glw::GLenum tested_formats[] = { GL_R8, GL_R3_G3_B2, GL_RGBA16, GL_R11F_G11F_B10F, 3730 GL_RGB9_E5, GL_DEPTH32F_STENCIL8 }; 3731 static const size_t n_tested_formats = sizeof(tested_formats) / sizeof(tested_formats[0]); 3732 3733#endif /* FUNCTIONAL_TEST_ALL_FORMATS == 0 */ 3734 3735#if FUNCTIONAL_TEST_ALL_TARGETS == 0 3736 3737 static const glw::GLenum tested_targets[] = { GL_TEXTURE_1D, GL_TEXTURE_2D_MULTISAMPLE_ARRAY }; 3738 static const size_t n_tested_targets = sizeof(tested_targets) / sizeof(tested_targets[0]); 3739 3740#endif /* FUNCTIONAL_TEST_ALL_TARGETS == 0 */ 3741 3742#if FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES == 0 3743 3744 static const size_t access_idx = 4; /* 4 - index of "texelFetch" entry in texture_access_routines */ 3745 3746#endif /* FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES == 0 */ 3747 3748#if FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS == 0 3749 3750 static const size_t tested_swizzle_combinations[][4] = { { 3, 2, 1, 3751 0 }, /* values are indices of entries in valid_values */ 3752 { 5, 4, 0, 3 }, 3753 { 5, 5, 5, 5 }, 3754 { 4, 4, 4, 4 }, 3755 { 2, 2, 2, 2 } }; 3756 static const size_t n_tested_swizzle_combinations = 3757 sizeof(tested_swizzle_combinations) / sizeof(tested_swizzle_combinations[0]); 3758 3759#endif /* FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS == 0 */ 3760 3761 /* */ 3762 bool test_result = true; 3763 glw::GLint source_channel_sizes[4] = { 0 }; 3764 3765 /* */ 3766 testInit(); 3767 3768/* Iterate over all cases */ 3769 3770#if FUNCTIONAL_TEST_ALL_FORMATS 3771 3772 for (size_t format_idx = 0; format_idx < n_texture_formats; ++format_idx) 3773 { 3774 3775 /* Check that format is supported by context. */ 3776 if (!glu::contextSupports(m_context.getRenderContext().getType(), 3777 texture_formats[format_idx].m_minimum_gl_context)) 3778 { 3779 continue; 3780 } 3781 3782#else /* FUNCTIONAL_TEST_ALL_FORMATS */ 3783 3784 for (size_t tested_format_idx = 0; tested_format_idx < n_tested_formats; ++tested_format_idx) 3785 { 3786 const size_t format_idx = get_index_of_format(tested_formats[tested_format_idx]); 3787 3788#endif /* FUNCTIONAL_TEST_ALL_FORMATS */ 3789 3790#if FUNCTIONAL_TEST_ALL_TARGETS 3791 3792 for (size_t tgt_idx = 0; tgt_idx < n_texture_targets; ++tgt_idx) 3793 { 3794 3795#else /* FUNCTIONAL_TEST_ALL_TARGETS */ 3796 3797 for (size_t tested_tgt_idx = 0; tested_tgt_idx < n_tested_targets; ++tested_tgt_idx) 3798 { 3799 const size_t tgt_idx = get_index_of_target(tested_targets[tested_tgt_idx]); 3800 3801#endif /* FUNCTIONAL_TEST_ALL_TARGETS */ 3802 3803 /* Skip not supported targets */ 3804 if (false == isTargetSupported(tgt_idx)) 3805 { 3806 continue; 3807 } 3808 3809 /* Skip invalid cases */ 3810 if (false == isTargetSuppByFormat(format_idx, tgt_idx)) 3811 { 3812 continue; 3813 } 3814 3815 try 3816 { 3817 prepareSourceTexture(format_idx, tgt_idx, source_channel_sizes); 3818 3819 /* Skip formats not supported by FBO */ 3820 if (false == fillSourceTexture(format_idx, tgt_idx)) 3821 { 3822 deinitTextures(); 3823 continue; 3824 } 3825 3826#if FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES 3827 3828 for (size_t access_idx = 0; access_idx < n_texture_access; ++access_idx) 3829 { 3830 /* Skip invalid cases */ 3831 if (false == isTargetSuppByAccess(access_idx, tgt_idx)) 3832 { 3833 continue; 3834 } 3835#else /* FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES */ 3836 /* Skip invalid cases */ 3837 if (false == isTargetSuppByAccess(access_idx, tgt_idx)) 3838 { 3839 deinitTextures(); 3840 continue; 3841 } 3842#endif /* FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES */ 3843 3844#if FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS 3845 3846 for (size_t r = 0; r < n_valid_values; ++r) 3847 { 3848 for (size_t g = 0; g < n_valid_values; ++g) 3849 { 3850 for (size_t b = 0; b < n_valid_values; ++b) 3851 { 3852 for (size_t a = 0; a < n_valid_values; ++a) 3853 { 3854 3855#else /* FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS */ 3856 3857 for (size_t tested_swizzle_idx = 0; tested_swizzle_idx < n_tested_swizzle_combinations; 3858 ++tested_swizzle_idx) 3859 { 3860 const size_t r = tested_swizzle_combinations[tested_swizzle_idx][0]; 3861 const size_t g = tested_swizzle_combinations[tested_swizzle_idx][1]; 3862 const size_t b = tested_swizzle_combinations[tested_swizzle_idx][2]; 3863 const size_t a = tested_swizzle_combinations[tested_swizzle_idx][3]; 3864 3865#endif /* FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS */ 3866 3867 for (size_t channel_idx = 0; channel_idx < 4; ++channel_idx) 3868 { 3869 const testCase test_case = { channel_idx, 3870 format_idx, 3871 tgt_idx, 3872 access_idx, 3873 valid_values[r], 3874 valid_values[g], 3875 valid_values[b], 3876 valid_values[a], 3877 { source_channel_sizes[0], source_channel_sizes[1], 3878 source_channel_sizes[2], 3879 source_channel_sizes[3] } }; 3880 3881 executeTestCase(test_case); 3882 3883 deinitOutputTexture(); 3884 } /* iteration over channels */ 3885 3886#if FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS 3887 3888 /* iteration over swizzle combinations */ 3889 } 3890 } 3891 } 3892 } 3893 3894#else /* FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS */ 3895 3896 } /* iteration over swizzle combinations */ 3897 3898#endif /* FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS */ 3899 3900#if FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES 3901 3902 } /* iteration over access routines - only when enabled */ 3903 3904#endif /* FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES */ 3905 deinitTextures(); 3906 } /* try */ 3907 catch (wrongResults& exc) 3908 { 3909 logTestCaseDetials(exc.m_test_case); 3910 m_context.getTestContext().getLog() << tcu::TestLog::Message << exc.what() << tcu::TestLog::EndMessage; 3911 3912 test_result = false; 3913 deinitTextures(); 3914 } 3915 catch (...) 3916 { 3917 deinitTextures(); 3918 throw; 3919 } 3920 } /* iteration over texture targets */ 3921 3922 } /* iteration over texture formats */ 3923 3924 /* Set result */ 3925 if (true == test_result) 3926 { 3927 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 3928 } 3929 else 3930 { 3931 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 3932 } 3933 3934 /* Done */ 3935 return STOP; 3936} 3937 3938/** Fills multisampled source texture 3939 * 3940 * @param format_idx Index of format 3941 * @param target_idx Index of target 3942 * 3943 * @return True if operation was successful, false other wise 3944 **/ 3945bool FunctionalTest::fillMSTexture(size_t format_idx, size_t target_idx) 3946{ 3947 const glw::GLenum target = texture_targets[target_idx].m_target; 3948 3949 /* */ 3950 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3951 3952 /* Bind FBO */ 3953 gl.bindFramebuffer(GL_FRAMEBUFFER, m_prepare_fbo_id); 3954 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer"); 3955 3956 /* Attach texture */ 3957 switch (target) 3958 { 3959 case GL_TEXTURE_2D_MULTISAMPLE: 3960 3961 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, m_source_tex_id, 0 /* level */); 3962 GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture2D"); 3963 3964 break; 3965 3966 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 3967 3968 gl.framebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_source_tex_id, 0 /* level */, 0 /* layer */); 3969 GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture2D"); 3970 3971 break; 3972 3973 default: 3974 TCU_FAIL("Invalid enum"); 3975 break; 3976 } 3977 3978 /* Verify status */ 3979 const glw::GLenum status = gl.checkFramebufferStatus(GL_FRAMEBUFFER); 3980 GLU_EXPECT_NO_ERROR(gl.getError(), "CheckFramebufferStatus"); 3981 3982 if (GL_FRAMEBUFFER_UNSUPPORTED == status) 3983 { 3984 /* Unbind */ 3985 gl.bindFramebuffer(GL_FRAMEBUFFER, 0); 3986 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer"); 3987 3988 return false; 3989 } 3990 else if (GL_FRAMEBUFFER_COMPLETE != status) 3991 { 3992 TCU_FAIL("Framebuffer is incomplete. Format is supported"); 3993 } 3994 3995 /* Set Viewport */ 3996 gl.viewport(0 /* x */, 0 /* y */, m_output_width, m_output_height); 3997 GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport"); 3998 3999 Utils::programInfo program(m_context); 4000 prepareProgram(format_idx, program); 4001 4002 gl.useProgram(program.m_program_object_id); 4003 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram"); 4004 4005 /* Clear */ 4006 gl.clear(GL_COLOR_BUFFER_BIT); 4007 GLU_EXPECT_NO_ERROR(gl.getError(), "Clear"); 4008 4009 /* Draw */ 4010 gl.drawArrays(GL_TRIANGLE_STRIP, 0 /* first */, 4 /* count */); 4011 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays"); 4012 4013 /* Unbind FBO */ 4014 gl.bindFramebuffer(GL_FRAMEBUFFER, 0); 4015 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer"); 4016 4017 /* Done */ 4018 return true; 4019} 4020 4021/** Fills source texture 4022 * 4023 * @param format_idx Index of format 4024 * @param target_idx Index of target 4025 * 4026 * @return True if operation was successful, false other wise 4027 **/ 4028bool FunctionalTest::fillSourceTexture(size_t format_idx, size_t target_idx) 4029{ 4030 const glw::GLenum target = texture_targets[target_idx].m_target; 4031 const _texture_format& format = texture_formats[format_idx]; 4032 4033 /* */ 4034 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4035 4036 /* Result */ 4037 bool result = true; 4038 4039 /* Bind texture */ 4040 gl.bindTexture(target, m_source_tex_id); 4041 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 4042 4043 /* Attach texture */ 4044 switch (target) 4045 { 4046 case GL_TEXTURE_1D: 4047 gl.texSubImage1D(target, 0 /* level */, 0 /* x */, m_width, format.m_format, format.m_type, 4048 format.m_source_data); 4049 GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage1D"); 4050 4051 break; 4052 4053 case GL_TEXTURE_1D_ARRAY: 4054 case GL_TEXTURE_2D: 4055 case GL_TEXTURE_RECTANGLE: 4056 gl.texSubImage2D(target, 0 /* level */, 0 /* x */, 0 /* y */, m_width, m_height, format.m_format, format.m_type, 4057 format.m_source_data); 4058 GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D"); 4059 4060 break; 4061 4062 case GL_TEXTURE_2D_ARRAY: 4063 case GL_TEXTURE_3D: 4064 gl.texSubImage3D(target, 0 /* level */, 0 /* x */, 0 /* y */, 0 /* z */, m_width, m_height, m_depth, 4065 format.m_format, format.m_type, format.m_source_data); 4066 GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage3D"); 4067 4068 break; 4069 4070 case GL_TEXTURE_CUBE_MAP: 4071 for (size_t i = 0; i < n_cube_map_faces; ++i) 4072 { 4073 gl.texSubImage2D(cube_map_faces[i], 0 /* level */, 0 /* x */, 0 /* y */, m_width, m_height, format.m_format, 4074 format.m_type, format.m_source_data); 4075 GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D"); 4076 } 4077 4078 break; 4079 4080 case GL_TEXTURE_2D_MULTISAMPLE: 4081 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 4082 result = fillMSTexture(format_idx, target_idx); 4083 4084 break; 4085 4086 default: 4087 TCU_FAIL("Invalid enum"); 4088 break; 4089 } 4090 4091 /* Unbind */ 4092 gl.bindTexture(target, 0); 4093 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 4094 4095 /* Done */ 4096 return result; 4097} 4098 4099/** Prepares program used to fill multisampled texture 4100 * 4101 * @param format_idx Index of texture format 4102 * @param program Instance of program that will be prepared 4103 **/ 4104void FunctionalTest::prepareProgram(size_t format_idx, Utils::programInfo& program) 4105{ 4106 static const glw::GLchar* fs_template = "#version 330 core\n" 4107 "\n" 4108 "out PREFIXvec4 out_color;\n" 4109 "\n" 4110 "void main()\n" 4111 "{\n" 4112 " out_color = PREFIXvec4(VALUES);\n" 4113 "}\n" 4114 "\n"; 4115 4116 const _texture_format& format = texture_formats[format_idx]; 4117 const std::string& values = prepareValues(format_idx); 4118 const std::string& vs = getVertexShader(testCase(), false); /* Get blank VS */ 4119 4120 std::string fs = fs_template; 4121 size_t position = 0; 4122 4123 Utils::replaceToken("PREFIX", position, format.m_sampler.m_sampler_prefix, fs); 4124 Utils::replaceToken("PREFIX", position, format.m_sampler.m_sampler_prefix, fs); 4125 Utils::replaceToken("VALUES", position, values.c_str(), fs); 4126 4127 program.build(fs.c_str(), vs.c_str()); 4128} 4129 4130/** Prepares hardcoded values used by program to fill multisampled textures 4131 * 4132 * @param format_idx Index of texture format 4133 * 4134 * @return Shader source 4135 **/ 4136std::string FunctionalTest::prepareValues(size_t format_idx) 4137{ 4138 double ch_rgba[4] = { 0.0, 0.0, 0.0, 0.0 }; 4139 4140 calculate_values_from_source(format_idx, ch_rgba); 4141 4142 /* Prepare string */ 4143 std::stringstream stream; 4144 stream << ch_rgba[0] << ", " << ch_rgba[1] << ", " << ch_rgba[2] << ", " << ch_rgba[3]; 4145 4146 return stream.str(); 4147} 4148 4149/** Verifies if value is in <low:top> range 4150 * 4151 * @tparam T Type oo values 4152 * 4153 * @param value Value to check 4154 * @param low Lowest acceptable value 4155 * @param top Highest acceptable value 4156 * 4157 * @return true if value is in range, false otherwise 4158 **/ 4159template <typename T> 4160bool isInRange(const void* value, const void* low, const void* top) 4161{ 4162 const T* v_ptr = (const T*)value; 4163 const T* l_ptr = (const T*)low; 4164 const T* t_ptr = (const T*)top; 4165 4166 if ((*v_ptr > *t_ptr) || (*v_ptr < *l_ptr)) 4167 { 4168 return false; 4169 } 4170 4171 return true; 4172} 4173 4174/** Verifies contents of output image 4175 * 4176 * @param test_case Test case instance 4177 * @param output_format_index Index of format used by output texture 4178 * @parma output_channel_size Size of storage used by output texture in bits 4179 * @param index_of_swizzled_channel Index of swizzled channel 4180 * @param data Image contents 4181 **/ 4182void FunctionalTest::verifyOutputImage(const testCase& test_case, size_t output_format_index, 4183 glw::GLint output_channel_size, size_t index_of_swizzled_channel, 4184 const glw::GLubyte* data) 4185{ 4186 const _texture_format& output_format = texture_formats[output_format_index]; 4187 4188 glw::GLubyte expected_data_low[8] = { 0 }; 4189 glw::GLubyte expected_data_top[8] = { 0 }; 4190 size_t texel_size = 0; 4191 4192 calculate_expected_value(test_case.m_source_texture_format_index, output_format_index, index_of_swizzled_channel, 4193 test_case.m_texture_sizes[index_of_swizzled_channel], output_channel_size, 4194 expected_data_low, expected_data_top, texel_size); 4195 4196 for (size_t i = 0; i < m_output_height * m_output_width; ++i) 4197 { 4198 const size_t offset = i * texel_size; 4199 const glw::GLvoid* pointer = data + offset; 4200 4201 bool res = false; 4202 4203 switch (output_format.m_type) 4204 { 4205 case GL_BYTE: 4206 res = isInRange<glw::GLbyte>(pointer, expected_data_low, expected_data_top); 4207 break; 4208 case GL_UNSIGNED_BYTE: 4209 res = isInRange<glw::GLubyte>(pointer, expected_data_low, expected_data_top); 4210 break; 4211 case GL_SHORT: 4212 res = isInRange<glw::GLshort>(pointer, expected_data_low, expected_data_top); 4213 break; 4214 case GL_UNSIGNED_SHORT: 4215 res = isInRange<glw::GLushort>(pointer, expected_data_low, expected_data_top); 4216 break; 4217 case GL_HALF_FLOAT: 4218 res = isInRange<glw::GLbyte>(pointer, expected_data_low, expected_data_top); 4219 break; 4220 case GL_INT: 4221 res = isInRange<glw::GLint>(pointer, expected_data_low, expected_data_top); 4222 break; 4223 case GL_UNSIGNED_INT: 4224 res = isInRange<glw::GLhalf>(pointer, expected_data_low, expected_data_top); 4225 break; 4226 case GL_FLOAT: 4227 res = isInRange<glw::GLfloat>(pointer, expected_data_low, expected_data_top); 4228 break; 4229 default: 4230 TCU_FAIL("Invalid enum"); 4231 break; 4232 } 4233 4234 if (false == res) 4235 { 4236 throw wrongResults(test_case); 4237 } 4238 } 4239} 4240} 4241 4242/** Constructor. 4243 * 4244 * @param context Rendering context. 4245 **/ 4246TextureSwizzleTests::TextureSwizzleTests(deqp::Context& context) 4247 : TestCaseGroup(context, "texture_swizzle", "Verifies \"texture_swizzle\" functionality") 4248{ 4249 /* Left blank on purpose */ 4250} 4251 4252/** Initializes a texture_storage_multisample test group. 4253 * 4254 **/ 4255void TextureSwizzleTests::init(void) 4256{ 4257 addChild(new TextureSwizzle::APIErrorsTest(m_context)); 4258 addChild(new TextureSwizzle::IntialStateTest(m_context)); 4259 addChild(new TextureSwizzle::SmokeTest(m_context)); 4260 addChild(new TextureSwizzle::FunctionalTest(m_context)); 4261} 4262} /* glcts namespace */ 4263