1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES 3.1 Module 3 * ------------------------------------------------- 4 * 5 * Copyright 2016 The Android Open Source Project 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 Negative Shader Directive Tests 22 *//*--------------------------------------------------------------------*/ 23 24 #include "es31fNegativeShaderDirectiveTests.hpp" 25 26 #include "gluShaderProgram.hpp" 27 28 namespace deqp 29 { 30 namespace gles31 31 { 32 namespace Functional 33 { 34 namespace NegativeTestShared 35 { 36 namespace 37 { 38 39 enum ExpectResult 40 { 41 EXPECT_RESULT_PASS = 0, 42 EXPECT_RESULT_FAIL, 43 44 EXPECT_RESULT_LAST 45 }; 46 47 void verifyProgram(NegativeTestContext& ctx, glu::ProgramSources sources, ExpectResult expect) 48 { 49 DE_ASSERT(expect >= EXPECT_RESULT_PASS && expect < EXPECT_RESULT_LAST); 50 51 tcu::TestLog& log = ctx.getLog(); 52 const glu::ShaderProgram program (ctx.getRenderContext(), sources); 53 bool testFailed = false; 54 std::string message; 55 56 log << program; 57 58 if (expect == EXPECT_RESULT_PASS) 59 { 60 testFailed = !program.getProgramInfo().linkOk; 61 message = "Program did not link."; 62 } 63 else 64 { 65 testFailed = program.getProgramInfo().linkOk; 66 message = "Program was not expected to link."; 67 } 68 69 if (testFailed) 70 { 71 log << tcu::TestLog::Message << message << tcu::TestLog::EndMessage; 72 ctx.fail(message); 73 } 74 } 75 76 void verifyShader(NegativeTestContext& ctx, glu::ShaderType shaderType, std::string shaderSource, ExpectResult expect) 77 { 78 DE_ASSERT(expect >= EXPECT_RESULT_PASS && expect < EXPECT_RESULT_LAST); 79 80 tcu::TestLog& log = ctx.getLog(); 81 bool testFailed = false; 82 const char* const source = shaderSource.c_str(); 83 const int length = (int) shaderSource.size(); 84 glu::Shader shader (ctx.getRenderContext(), shaderType); 85 std::string message; 86 87 shader.setSources(1, &source, &length); 88 shader.compile(); 89 90 log << shader; 91 92 if (expect == EXPECT_RESULT_PASS) 93 { 94 testFailed = !shader.getCompileStatus(); 95 message = "Shader did not compile."; 96 } 97 else 98 { 99 testFailed = shader.getCompileStatus(); 100 message = "Shader was not expected to compile."; 101 } 102 103 if (testFailed) 104 { 105 log << tcu::TestLog::Message << message << tcu::TestLog::EndMessage; 106 ctx.fail(message); 107 } 108 } 109 110 void primitive_bounding_box (NegativeTestContext& ctx) 111 { 112 if (ctx.isShaderSupported(glu::SHADERTYPE_TESSELLATION_CONTROL)) 113 { 114 ctx.beginSection("GL_EXT_primitive_bounding_box features require enabling the extension in 310 es shaders."); 115 std::ostringstream source; 116 source << "#version 310 es\n" 117 "void main()\n" 118 "{\n" 119 " gl_BoundingBoxEXT[0] = vec4(0.0, 0.0, 0.0, 0.0);\n" 120 " gl_BoundingBoxEXT[1] = vec4(1.0, 1.0, 1.0, 1.0);\n" 121 "}\n"; 122 verifyShader(ctx, glu::SHADERTYPE_TESSELLATION_CONTROL, source.str(), EXPECT_RESULT_FAIL); 123 ctx.endSection(); 124 } 125 126 if (contextSupports(ctx.getRenderContext().getType() , glu::ApiType::es(3, 2))) 127 { 128 ctx.beginSection("gl_BoundingBox does not require the OES/EXT suffix in a 320 es shader."); 129 const std::string source = "#version 320 es\n" 130 "layout(vertices = 3) out;\n" 131 "void main()\n" 132 "{\n" 133 " gl_BoundingBox[0] = vec4(0.0, 0.0, 0.0, 0.0);\n" 134 " gl_BoundingBox[1] = vec4(0.0, 0.0, 0.0, 0.0);\n" 135 "}\n"; 136 verifyShader(ctx, glu::SHADERTYPE_TESSELLATION_CONTROL, source, EXPECT_RESULT_PASS); 137 ctx.endSection(); 138 } 139 } 140 141 void blend_equation_advanced (NegativeTestContext& ctx) 142 { 143 static const char* const s_qualifiers[] = 144 { 145 "blend_support_multiply", 146 "blend_support_screen", 147 "blend_support_overlay", 148 "blend_support_darken", 149 "blend_support_lighten", 150 "blend_support_colordodge", 151 "blend_support_colorburn", 152 "blend_support_hardlight", 153 "blend_support_softlight", 154 "blend_support_difference", 155 "blend_support_exclusion", 156 "blend_support_hsl_hue", 157 "blend_support_hsl_saturation", 158 "blend_support_hsl_color", 159 "blend_support_hsl_luminosity", 160 }; 161 162 ctx.beginSection("GL_KHR_blend_equation_advanced features require enabling the extension in 310 es shaders."); 163 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_qualifiers); ++ndx) 164 { 165 std::ostringstream source; 166 source << "#version 310 es\n" 167 "layout(" << s_qualifiers[ndx] << ") out;\n" 168 "void main()\n" 169 "{\n" 170 "}\n"; 171 verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL); 172 } 173 ctx.endSection(); 174 } 175 176 void sample_variables (NegativeTestContext& ctx) 177 { 178 TCU_CHECK_AND_THROW(NotSupportedError, contextSupports(ctx.getRenderContext().getType() , glu::ApiType::es(3, 2)), "Test requires a context version 3.2 or higher."); 179 180 static const char* const s_tests[] = 181 { 182 "int sampleId = gl_SampleID;", 183 "vec2 samplePos = gl_SamplePosition;", 184 "int sampleMaskIn0 = gl_SampleMaskIn[0];", 185 "int sampleMask0 = gl_SampleMask[0];", 186 "int numSamples = gl_NumSamples;", 187 }; 188 189 ctx.beginSection("GL_OES_sample_variables features require enabling the extension in 310 es shaders."); 190 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_tests); ++ndx) 191 { 192 std::ostringstream source; 193 source << "#version 310 es\n" 194 "precision mediump float;\n" 195 "void main()\n" 196 "{\n" 197 " " << s_tests[ndx] << "\n" 198 "}\n"; 199 verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL); 200 } 201 ctx.endSection(); 202 } 203 204 void shader_image_atomic (NegativeTestContext& ctx) 205 { 206 static const char* const s_tests[] = 207 { 208 "imageAtomicAdd(u_image, ivec2(1, 1), 1u);", 209 "imageAtomicMin(u_image, ivec2(1, 1), 1u);", 210 "imageAtomicMax(u_image, ivec2(1, 1), 1u);", 211 "imageAtomicAnd(u_image, ivec2(1, 1), 1u);", 212 "imageAtomicOr(u_image, ivec2(1, 1), 1u);", 213 "imageAtomicXor(u_image, ivec2(1, 1), 1u);", 214 "imageAtomicExchange(u_image, ivec2(1, 1), 1u);", 215 "imageAtomicCompSwap(u_image, ivec2(1, 1), 1u, 1u);", 216 }; 217 218 ctx.beginSection("GL_OES_shader_image_atomic features require enabling the extension in 310 es shaders."); 219 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_tests); ++ndx) 220 { 221 std::ostringstream source; 222 source << "#version 310 es\n" 223 "layout(binding=0, r32ui) coherent uniform highp uimage2D u_image;\n" 224 "precision mediump float;\n" 225 "void main()\n" 226 "{\n" 227 " " << s_tests[ndx] << "\n" 228 "}\n"; 229 verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL); 230 } 231 ctx.endSection(); 232 } 233 234 void shader_multisample_interpolation (NegativeTestContext& ctx) 235 { 236 static const char* const s_sampleTests[] = 237 { 238 "sample in highp float v_var;", 239 "sample out highp float v_var;" 240 }; 241 242 static const char* const s_interpolateAtTests[] = 243 { 244 "interpolateAtCentroid(interpolant);", 245 "interpolateAtSample(interpolant, 1);", 246 "interpolateAtOffset(interpolant, vec2(1.0, 0.0));" 247 }; 248 249 ctx.beginSection("GL_OES_shader_multisample_interpolation features require enabling the extension in 310 es shaders."); 250 ctx.beginSection("Test sample in/out qualifiers."); 251 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_sampleTests); ++ndx) 252 { 253 std::ostringstream source; 254 source << "#version 310 es\n" 255 " " << s_sampleTests[ndx] << "\n" 256 "precision mediump float;\n" 257 "void main()\n" 258 "{\n" 259 "}\n"; 260 verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL); 261 } 262 ctx.endSection(); 263 264 ctx.beginSection("Test interpolateAt* functions."); 265 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_sampleTests); ++ndx) 266 { 267 std::ostringstream source; 268 source << "#version 310 es\n" 269 "in mediump float interpolant;\n" 270 "precision mediump float;\n" 271 "void main()\n" 272 "{\n" 273 " " << s_interpolateAtTests[ndx] << "\n" 274 "}\n"; 275 verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL); 276 } 277 ctx.endSection(); 278 ctx.endSection(); 279 } 280 281 void texture_storage_multisample_2d_array (NegativeTestContext& ctx) 282 { 283 static const char* const s_samplerTypeTests[] = 284 { 285 "uniform mediump sampler2DMSArray u_sampler;", 286 "uniform mediump isampler2DMSArray u_sampler;", 287 "uniform mediump usampler2DMSArray u_sampler;", 288 }; 289 290 ctx.beginSection("GL_OES_texture_storage_multisample_2d_array features require enabling the extension in 310 es shaders."); 291 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_samplerTypeTests); ++ndx) 292 { 293 std::ostringstream source; 294 source << "#version 310 es\n" 295 " " << s_samplerTypeTests[ndx] << "\n" 296 "precision mediump float;\n" 297 "void main()\n" 298 "{\n" 299 "}\n"; 300 verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL); 301 } 302 ctx.endSection(); 303 } 304 305 void geometry_shader (NegativeTestContext& ctx) 306 { 307 if (ctx.isShaderSupported(glu::SHADERTYPE_GEOMETRY)) 308 { 309 const std::string simpleVtxFrag = "#version 310 es\n" 310 "void main()\n" 311 "{\n" 312 "}\n"; 313 const std::string geometry = "#version 310 es\n" 314 "layout(points, invocations = 1) in;\n" 315 "layout(points, max_vertices = 3) out;\n" 316 "precision mediump float;\n" 317 "void main()\n" 318 "{\n" 319 " EmitVertex();\n" 320 " EndPrimitive();\n" 321 "}\n"; 322 ctx.beginSection("GL_EXT_geometry_shader features require enabling the extension in 310 es shaders."); 323 verifyProgram(ctx, glu::ProgramSources() << glu::VertexSource(simpleVtxFrag) << glu::GeometrySource(geometry) << glu::FragmentSource(simpleVtxFrag), EXPECT_RESULT_FAIL); 324 ctx.endSection(); 325 } 326 } 327 328 void gpu_shader_5 (NegativeTestContext& ctx) 329 { 330 ctx.beginSection("GL_EXT_gpu_shader5 features require enabling the extension in 310 es shaders."); 331 ctx.beginSection("Testing the precise qualifier."); 332 { 333 std::ostringstream source; 334 source << "#version 310 es\n" 335 "void main()\n" 336 "{\n" 337 " int low = 0;\n" 338 " int high = 10;\n" 339 " precise int middle = low + ((high - low) / 2);\n" 340 "}\n"; 341 verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL); 342 } 343 ctx.endSection(); 344 345 ctx.beginSection("Testing fused multiply-add."); 346 { 347 std::ostringstream source; 348 source << "#version 310 es\n" 349 "in mediump float v_var;" 350 "void main()\n" 351 "{\n" 352 " float fmaResult = fma(v_var, v_var, v_var);" 353 "}\n"; 354 verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL); 355 } 356 ctx.endSection(); 357 358 ctx.beginSection("Testing textureGatherOffsets."); 359 { 360 std::ostringstream source; 361 source << "#version 310 es\n" 362 "uniform mediump sampler2D u_tex;\n" 363 "void main()\n" 364 "{\n" 365 " highp vec2 coords = vec2(0.0, 1.0);\n" 366 " const ivec2 offsets[4] = ivec2[](ivec2(0,0), ivec2(1, 0), ivec2(0, 1), ivec2(1, 1));\n" 367 " textureGatherOffsets(u_tex, coords, offsets);\n" 368 "}\n"; 369 verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL); 370 } 371 ctx.endSection(); 372 373 ctx.endSection(); 374 } 375 376 void shader_io_blocks (NegativeTestContext& ctx) 377 { 378 ctx.beginSection("GL_EXT_shader_io_blocks features require enabling the extension in 310 es shaders."); 379 { 380 std::ostringstream source; 381 source << "#version 310 es\n" 382 "in Data\n" 383 "{\n" 384 " mediump vec3 a;\n" 385 "} data;\n" 386 "void main()\n" 387 "{\n" 388 "}\n"; 389 verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL); 390 } 391 ctx.endSection(); 392 } 393 394 void tessellation_shader (NegativeTestContext& ctx) 395 { 396 if (ctx.isShaderSupported(glu::SHADERTYPE_TESSELLATION_CONTROL)) 397 { 398 const std::string simpleVtxFrag = "#version 310 es\n" 399 "void main()\n" 400 "{\n" 401 "}\n"; 402 const std::string tessControl = "#version 310 es\n" 403 "layout(vertices = 3) out;\n" 404 "void main()\n" 405 "{\n" 406 "}\n"; 407 const std::string tessEvaluation = "#version 310 es\n" 408 "layout(triangles, equal_spacing, cw) in;\n" 409 "void main()\n" 410 "{\n" 411 "}\n"; 412 ctx.beginSection("GL_EXT_tessellation_shader features require enabling the extension in 310 es shaders."); 413 glu::ProgramSources sources; 414 sources << glu::VertexSource(simpleVtxFrag) 415 << glu::TessellationControlSource(tessControl) 416 << glu::TessellationEvaluationSource(tessEvaluation) 417 << glu::FragmentSource(simpleVtxFrag); 418 verifyProgram(ctx, sources, EXPECT_RESULT_FAIL); 419 ctx.endSection(); 420 } 421 } 422 423 void texture_buffer (NegativeTestContext& ctx) 424 { 425 static const char* const s_samplerBufferTypes[] = 426 { 427 "uniform mediump samplerBuffer", 428 "uniform mediump isamplerBuffer", 429 "uniform mediump usamplerBuffer", 430 "layout(rgba32f) uniform mediump writeonly imageBuffer", 431 "layout(rgba32i) uniform mediump writeonly iimageBuffer", 432 "layout(rgba32ui) uniform mediump writeonly uimageBuffer" 433 }; 434 435 ctx.beginSection("GL_EXT_texture_buffer features require enabling the extension in 310 es shaders."); 436 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_samplerBufferTypes); ++ndx) 437 { 438 std::ostringstream source; 439 source << "#version 310 es\n" 440 "" << s_samplerBufferTypes[ndx] << " u_buffer;\n" 441 "void main()\n" 442 "{\n" 443 "}\n"; 444 verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL); 445 } 446 ctx.endSection(); 447 } 448 449 450 void texture_cube_map_array (NegativeTestContext& ctx) 451 { 452 static const char* const s_samplerCubeArrayTypes[] = 453 { 454 "uniform mediump samplerCubeArray", 455 "uniform mediump isamplerCubeArray", 456 "uniform mediump usamplerCubeArray", 457 "uniform mediump samplerCubeArrayShadow", 458 "layout(rgba32f) uniform mediump writeonly imageCubeArray", 459 "layout(rgba32i) uniform mediump writeonly iimageCubeArray", 460 "layout(rgba32ui) uniform mediump writeonly uimageCubeArray" 461 }; 462 463 ctx.beginSection("GL_EXT_texture_cube_map_array features require enabling the extension in 310 es shaders."); 464 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_samplerCubeArrayTypes); ++ndx) 465 { 466 std::ostringstream source; 467 source << "#version 310 es\n" 468 "" << s_samplerCubeArrayTypes[ndx] << " u_cube;\n" 469 "void main()\n" 470 "{\n" 471 "}\n"; 472 verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL); 473 } 474 ctx.endSection(); 475 } 476 477 } // anonymous 478 479 std::vector<FunctionContainer> getNegativeShaderDirectiveTestFunctions (void) 480 { 481 const FunctionContainer funcs[] = 482 { 483 {primitive_bounding_box, "primitive_bounding_box", "GL_EXT_primitive_bounding_box required in 310 es shaders to use AEP features. Version 320 es shaders do not require suffixes." }, 484 {blend_equation_advanced, "blend_equation_advanced", "GL_KHR_blend_equation_advanced is required in 310 es shaders to use AEP features" }, 485 {sample_variables, "sample_variables", "GL_OES_sample_variables is required in 310 es shaders to use AEP features" }, 486 {shader_image_atomic, "shader_image_atomic", "GL_OES_shader_image_atomic is required in 310 es shaders to use AEP features" }, 487 {shader_multisample_interpolation, "shader_multisample_interpolation", "GL_OES_shader_multisample_interpolation is required in 310 es shaders to use AEP features" }, 488 {texture_storage_multisample_2d_array, "texture_storage_multisample_2d_array", "GL_OES_texture_storage_multisample_2d_array is required in 310 es shaders to use AEP features" }, 489 {geometry_shader, "geometry_shader", "GL_EXT_geometry_shader is required in 310 es shaders to use AEP features" }, 490 {gpu_shader_5, "gpu_shader_5", "GL_EXT_gpu_shader5 is required in 310 es shaders to use AEP features" }, 491 {shader_io_blocks, "shader_io_blocks", "GL_EXT_shader_io_blocks is required in 310 es shaders to use AEP features" }, 492 {tessellation_shader, "tessellation_shader", "GL_EXT_tessellation_shader is required in 310 es shaders to use AEP features" }, 493 {texture_buffer, "texture_buffer", "GL_EXT_texture_buffer is required in 310 es shaders to use AEP features" }, 494 {texture_cube_map_array, "texture_cube_map_array", "GL_EXT_texture_cube_map_array is required in 310 es shaders to use AEP features" }, 495 }; 496 497 return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs)); 498 } 499 500 } // NegativeTestShared 501 } // Functional 502 } // gles31 503 } // deqp 504