1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES 3.1 Module 3 * ------------------------------------------------- 4 * 5 * Copyright 2015 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 Program State Query tests. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "es31fProgramStateQueryTests.hpp" 25 #include "es31fInfoLogQueryShared.hpp" 26 #include "glsStateQueryUtil.hpp" 27 #include "gluRenderContext.hpp" 28 #include "gluCallLogWrapper.hpp" 29 #include "gluContextInfo.hpp" 30 #include "gluObjectWrapper.hpp" 31 #include "gluShaderProgram.hpp" 32 #include "glwFunctions.hpp" 33 #include "glwEnums.hpp" 34 #include "tcuStringTemplate.hpp" 35 36 namespace deqp 37 { 38 39 using std::string; 40 using std::map; 41 42 namespace gles31 43 { 44 namespace Functional 45 { 46 namespace 47 { 48 49 using namespace gls::StateQueryUtil; 50 51 static const char* getVerifierSuffix (QueryType type) 52 { 53 switch (type) 54 { 55 case QUERY_PROGRAM_INTEGER_VEC3: 56 case QUERY_PROGRAM_INTEGER: 57 return "get_programiv"; 58 59 default: 60 DE_ASSERT(DE_FALSE); 61 return DE_NULL; 62 } 63 } 64 65 static std::string specializeShader(Context& context, const char* code) 66 { 67 const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(context.getRenderContext().getType()); 68 std::map<std::string, std::string> specializationMap; 69 70 specializationMap["GLSL_VERSION_DECL"] = glu::getGLSLVersionDeclaration(glslVersion); 71 72 if (glu::contextSupports(context.getRenderContext().getType(), glu::ApiType::es(3, 2))) 73 { 74 specializationMap["GEOMETRY_SHADER_REQUIRE"] = ""; 75 specializationMap["TESSELLATION_SHADER_REQUIRE"] = ""; 76 } 77 else 78 { 79 specializationMap["GEOMETRY_SHADER_REQUIRE"] = "#extension GL_EXT_geometry_shader : require"; 80 specializationMap["TESSELLATION_SHADER_REQUIRE"] = "#extension GL_EXT_tessellation_shader : require"; 81 } 82 83 return tcu::StringTemplate(code).specialize(specializationMap); 84 } 85 86 87 class GeometryShaderCase : public TestCase 88 { 89 public: 90 GeometryShaderCase (Context& context, QueryType verifier, const char* name, const char* desc); 91 IterateResult iterate (void); 92 93 private: 94 const QueryType m_verifier; 95 }; 96 97 GeometryShaderCase::GeometryShaderCase (Context& context, QueryType verifier, const char* name, const char* desc) 98 : TestCase (context, name, desc) 99 , m_verifier (verifier) 100 { 101 } 102 103 GeometryShaderCase::IterateResult GeometryShaderCase::iterate (void) 104 { 105 const bool supportsES32 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)); 106 107 if (!supportsES32 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")) 108 TCU_THROW(NotSupportedError, "Geometry shader tests require GL_EXT_geometry_shader extension or an OpenGL ES 3.2 or higher context."); 109 110 111 static const char* const s_vtxFragTemplate = "${GLSL_VERSION_DECL}\n" 112 "void main()\n" 113 "{\n" 114 "}\n"; 115 116 static const char* const s_geometryTemplate1 = "${GLSL_VERSION_DECL}\n" 117 "${GEOMETRY_SHADER_REQUIRE}\n" 118 "layout(triangles) in;" 119 "layout(triangle_strip, max_vertices = 3) out;\n" 120 "void main()\n" 121 "{\n" 122 " EndPrimitive();\n" 123 "}\n"; 124 125 static const char* const s_geometryTemplate2 = "${GLSL_VERSION_DECL}\n" 126 "${GEOMETRY_SHADER_REQUIRE}\n" 127 "layout(points) in;" 128 "layout(line_strip, max_vertices = 5) out;\n" 129 "void main()\n" 130 "{\n" 131 " EndPrimitive();\n" 132 "}\n"; 133 134 static const char* const s_geometryTemplate3 = "${GLSL_VERSION_DECL}\n" 135 "${GEOMETRY_SHADER_REQUIRE}\n" 136 "layout(points) in;" 137 "layout(points, max_vertices = 50) out;\n" 138 "void main()\n" 139 "{\n" 140 " EndPrimitive();\n" 141 "}\n"; 142 143 glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); 144 tcu::ResultCollector result (m_testCtx.getLog(), " // ERROR: "); 145 146 gl.enableLogging(true); 147 148 { 149 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Layout", "triangles in, triangle strip out, 3 vertices"); 150 glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() 151 << glu::VertexSource(specializeShader(m_context, s_vtxFragTemplate)) 152 << glu::FragmentSource(specializeShader(m_context, s_vtxFragTemplate)) 153 << glu::GeometrySource(specializeShader(m_context, s_geometryTemplate1))); 154 155 TCU_CHECK_MSG(program.isOk(), "Compile failed"); 156 157 m_testCtx.getLog() << program; 158 159 verifyStateProgramInteger(result, gl, program.getProgram(), GL_GEOMETRY_VERTICES_OUT, 3, m_verifier); 160 verifyStateProgramInteger(result, gl, program.getProgram(), GL_GEOMETRY_INPUT_TYPE, GL_TRIANGLES, m_verifier); 161 verifyStateProgramInteger(result, gl, program.getProgram(), GL_GEOMETRY_OUTPUT_TYPE, GL_TRIANGLE_STRIP, m_verifier); 162 verifyStateProgramInteger(result, gl, program.getProgram(), GL_GEOMETRY_SHADER_INVOCATIONS, 1, m_verifier); 163 } 164 165 { 166 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Layout", "points in, line strip out, 5 vertices"); 167 glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() 168 << glu::VertexSource(specializeShader(m_context, s_vtxFragTemplate)) 169 << glu::FragmentSource(specializeShader(m_context, s_vtxFragTemplate)) 170 << glu::GeometrySource(specializeShader(m_context, s_geometryTemplate2))); 171 172 TCU_CHECK_MSG(program.isOk(), "Compile failed"); 173 174 m_testCtx.getLog() << program; 175 176 verifyStateProgramInteger(result, gl, program.getProgram(), GL_GEOMETRY_VERTICES_OUT, 5, m_verifier); 177 verifyStateProgramInteger(result, gl, program.getProgram(), GL_GEOMETRY_INPUT_TYPE, GL_POINTS, m_verifier); 178 verifyStateProgramInteger(result, gl, program.getProgram(), GL_GEOMETRY_OUTPUT_TYPE, GL_LINE_STRIP, m_verifier); 179 } 180 181 { 182 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Layout", "points in, points out, 50 vertices"); 183 glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() 184 << glu::VertexSource(specializeShader(m_context, s_vtxFragTemplate)) 185 << glu::FragmentSource(specializeShader(m_context, s_vtxFragTemplate)) 186 << glu::GeometrySource(specializeShader(m_context, s_geometryTemplate3))); 187 188 TCU_CHECK_MSG(program.isOk(), "Compile failed"); 189 190 m_testCtx.getLog() << program; 191 192 verifyStateProgramInteger(result, gl, program.getProgram(), GL_GEOMETRY_VERTICES_OUT, 50, m_verifier); 193 verifyStateProgramInteger(result, gl, program.getProgram(), GL_GEOMETRY_INPUT_TYPE, GL_POINTS, m_verifier); 194 verifyStateProgramInteger(result, gl, program.getProgram(), GL_GEOMETRY_OUTPUT_TYPE, GL_POINTS, m_verifier); 195 } 196 197 result.setTestContextResult(m_testCtx); 198 return STOP; 199 } 200 201 class TessellationShaderCase : public TestCase 202 { 203 public: 204 TessellationShaderCase (Context& context, QueryType verifier, const char* name, const char* desc); 205 IterateResult iterate (void); 206 207 private: 208 const QueryType m_verifier; 209 }; 210 211 TessellationShaderCase::TessellationShaderCase (Context& context, QueryType verifier, const char* name, const char* desc) 212 : TestCase (context, name, desc) 213 , m_verifier (verifier) 214 { 215 } 216 217 TessellationShaderCase::IterateResult TessellationShaderCase::iterate (void) 218 { 219 const bool supportsES32 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)); 220 221 if (!supportsES32 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader")) 222 TCU_THROW(NotSupportedError, "Tessellation shader tests require GL_EXT_tessellation_shader extension or an OpenGL ES 3.2 or higher context."); 223 224 225 static const char* const s_vtxFragTemplate = "${GLSL_VERSION_DECL}\n" 226 "void main()\n" 227 "{\n" 228 "}\n"; 229 230 static const char* const s_tessCtrlTemplate1 = "${GLSL_VERSION_DECL}\n" 231 "${TESSELLATION_SHADER_REQUIRE}\n" 232 "layout(vertices = 3) out;\n" 233 "void main()\n" 234 "{\n" 235 "}\n"; 236 237 static const char* const s_tessEvalTemplate1 = "${GLSL_VERSION_DECL}\n" 238 "${TESSELLATION_SHADER_REQUIRE}\n" 239 "layout(triangles, equal_spacing, cw) in;\n" 240 "void main()\n" 241 "{\n" 242 "}\n"; 243 244 static const char* const s_tessCtrlTemplate2 = "${GLSL_VERSION_DECL}\n" 245 "${TESSELLATION_SHADER_REQUIRE}\n" 246 "layout(vertices = 5) out;\n" 247 "void main()\n" 248 "{\n" 249 "}\n"; 250 251 static const char* const s_tessEvalTemplate2 = "${GLSL_VERSION_DECL}\n" 252 "${TESSELLATION_SHADER_REQUIRE}\n" 253 "layout(quads, fractional_even_spacing, ccw) in;\n" 254 "void main()\n" 255 "{\n" 256 "}\n"; 257 258 static const char* const s_tessEvalTemplate3 = "${GLSL_VERSION_DECL}\n" 259 "${TESSELLATION_SHADER_REQUIRE}\n" 260 "layout(isolines, fractional_odd_spacing, ccw, point_mode) in;\n" 261 "void main()\n" 262 "{\n" 263 "}\n"; 264 265 glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); 266 tcu::ResultCollector result (m_testCtx.getLog(), " // ERROR: "); 267 268 gl.enableLogging(true); 269 270 { 271 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Query State", "3 vertices, triangles, equal_spacing, cw"); 272 glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() 273 << glu::VertexSource(specializeShader(m_context, s_vtxFragTemplate)) 274 << glu::FragmentSource(specializeShader(m_context, s_vtxFragTemplate)) 275 << glu::TessellationControlSource(specializeShader(m_context, s_tessCtrlTemplate1)) 276 << glu::TessellationEvaluationSource(specializeShader(m_context, s_tessEvalTemplate1))); 277 278 TCU_CHECK_MSG(program.isOk(), "Compile failed"); 279 280 m_testCtx.getLog() << program; 281 282 verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_CONTROL_OUTPUT_VERTICES, 3, m_verifier); 283 verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_GEN_MODE, GL_TRIANGLES, m_verifier); 284 verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_GEN_SPACING, GL_EQUAL, m_verifier); 285 verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_GEN_VERTEX_ORDER, GL_CW, m_verifier); 286 verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_GEN_POINT_MODE, GL_FALSE, m_verifier); 287 } 288 289 { 290 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Query State", "5 vertices, quads, fractional_even_spacing, ccw"); 291 glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() 292 << glu::VertexSource(specializeShader(m_context, s_vtxFragTemplate)) 293 << glu::FragmentSource(specializeShader(m_context, s_vtxFragTemplate)) 294 << glu::TessellationControlSource(specializeShader(m_context, s_tessCtrlTemplate2)) 295 << glu::TessellationEvaluationSource(specializeShader(m_context, s_tessEvalTemplate2))); 296 297 TCU_CHECK_MSG(program.isOk(), "Compile failed"); 298 299 m_testCtx.getLog() << program; 300 301 verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_CONTROL_OUTPUT_VERTICES, 5, m_verifier); 302 verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_GEN_MODE, GL_QUADS, m_verifier); 303 verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_GEN_SPACING, GL_FRACTIONAL_EVEN, m_verifier); 304 verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_GEN_VERTEX_ORDER, GL_CCW, m_verifier); 305 verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_GEN_POINT_MODE, GL_FALSE, m_verifier); 306 } 307 308 { 309 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Query State", "5 vertices, isolines, fractional_odd_spacing, ccw, point_mode"); 310 glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() 311 << glu::VertexSource(specializeShader(m_context, s_vtxFragTemplate)) 312 << glu::FragmentSource(specializeShader(m_context, s_vtxFragTemplate)) 313 << glu::TessellationControlSource(specializeShader(m_context, s_tessCtrlTemplate2)) 314 << glu::TessellationEvaluationSource(specializeShader(m_context, s_tessEvalTemplate3))); 315 316 TCU_CHECK_MSG(program.isOk(), "Compile failed"); 317 318 m_testCtx.getLog() << program; 319 320 verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_CONTROL_OUTPUT_VERTICES, 5, m_verifier); 321 verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_GEN_MODE, GL_ISOLINES, m_verifier); 322 verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_GEN_SPACING, GL_FRACTIONAL_ODD, m_verifier); 323 verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_GEN_VERTEX_ORDER, GL_CCW, m_verifier); 324 verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_GEN_POINT_MODE, GL_TRUE, m_verifier); 325 } 326 327 result.setTestContextResult(m_testCtx); 328 return STOP; 329 } 330 331 class ProgramSeparableCase : public TestCase 332 { 333 public: 334 ProgramSeparableCase (Context& context, QueryType verifier, const char* name, const char* desc); 335 IterateResult iterate (void); 336 337 private: 338 const QueryType m_verifier; 339 }; 340 341 ProgramSeparableCase::ProgramSeparableCase (Context& context, QueryType verifier, const char* name, const char* desc) 342 : TestCase (context, name, desc) 343 , m_verifier (verifier) 344 { 345 } 346 347 ProgramSeparableCase::IterateResult ProgramSeparableCase::iterate (void) 348 { 349 const string vtxTemplate = "${GLSL_VERSION_DECL}\n" 350 "out highp vec4 v_color;\n" 351 "void main()\n" 352 "{\n" 353 " gl_Position = vec4(float(gl_VertexID) * 0.5, float(gl_VertexID+1) * 0.5, 0.0, 1.0);\n" 354 " v_color = vec4(float(gl_VertexID), 1.0, 0.0, 1.0);\n" 355 "}\n"; 356 const string fragTemplate = "${GLSL_VERSION_DECL}\n" 357 "in highp vec4 v_color;\n" 358 "layout(location=0) out highp vec4 o_color;\n" 359 "void main()\n" 360 "{\n" 361 " o_color = v_color;\n" 362 "}\n"; 363 364 glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); 365 tcu::ResultCollector result (m_testCtx.getLog(), " // ERROR: "); 366 glu::Shader vtxShader (m_context.getRenderContext(), glu::SHADERTYPE_VERTEX); 367 glu::Shader frgShader (m_context.getRenderContext(), glu::SHADERTYPE_FRAGMENT); 368 369 const std::string vStr = specializeShader(m_context, vtxTemplate.c_str()); 370 const std::string fStr = specializeShader(m_context, fragTemplate.c_str()); 371 const char* const vtxSourcePtr = vStr.c_str(); 372 const char* const fragSourcePtr = fStr.c_str(); 373 374 vtxShader.setSources(1, &vtxSourcePtr, DE_NULL); 375 frgShader.setSources(1, &fragSourcePtr, DE_NULL); 376 377 vtxShader.compile(); 378 frgShader.compile(); 379 380 { 381 const tcu::ScopedLogSection section(m_testCtx.getLog(), "VtxShader", "Vertex shader"); 382 m_testCtx.getLog() << vtxShader; 383 } 384 385 { 386 const tcu::ScopedLogSection section(m_testCtx.getLog(), "FrgShader", "Fragment shader"); 387 m_testCtx.getLog() << frgShader; 388 } 389 390 TCU_CHECK_MSG(vtxShader.getCompileStatus() && frgShader.getCompileStatus(), "failed to build shaders"); 391 392 gl.enableLogging(true); 393 394 { 395 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Initial", "Initial"); 396 glu::Program program (m_context.getRenderContext()); 397 398 verifyStateProgramInteger(result, gl, program.getProgram(), GL_PROGRAM_SEPARABLE, 0, m_verifier); 399 } 400 401 { 402 const tcu::ScopedLogSection section (m_testCtx.getLog(), "SetFalse", "SetFalse"); 403 glu::Program program (m_context.getRenderContext()); 404 int linkStatus = 0; 405 406 gl.glAttachShader(program.getProgram(), vtxShader.getShader()); 407 gl.glAttachShader(program.getProgram(), frgShader.getShader()); 408 gl.glProgramParameteri(program.getProgram(), GL_PROGRAM_SEPARABLE, GL_FALSE); 409 gl.glLinkProgram(program.getProgram()); 410 GLU_EXPECT_NO_ERROR(gl.glGetError(), "setup program"); 411 412 gl.glGetProgramiv(program.getProgram(), GL_LINK_STATUS, &linkStatus); 413 GLU_EXPECT_NO_ERROR(gl.glGetError(), "query link status"); 414 415 TCU_CHECK_MSG(linkStatus == GL_TRUE, "failed to link program"); 416 417 verifyStateProgramInteger(result, gl, program.getProgram(), GL_PROGRAM_SEPARABLE, 0, m_verifier); 418 } 419 420 { 421 const tcu::ScopedLogSection section (m_testCtx.getLog(), "SetTrue", "SetTrue"); 422 glu::Program program (m_context.getRenderContext()); 423 int linkStatus = 0; 424 425 gl.glAttachShader(program.getProgram(), vtxShader.getShader()); 426 gl.glAttachShader(program.getProgram(), frgShader.getShader()); 427 gl.glProgramParameteri(program.getProgram(), GL_PROGRAM_SEPARABLE, GL_TRUE); 428 gl.glLinkProgram(program.getProgram()); 429 GLU_EXPECT_NO_ERROR(gl.glGetError(), "setup program"); 430 431 gl.glGetProgramiv(program.getProgram(), GL_LINK_STATUS, &linkStatus); 432 GLU_EXPECT_NO_ERROR(gl.glGetError(), "query link status"); 433 434 TCU_CHECK_MSG(linkStatus == GL_TRUE, "failed to link program"); 435 436 verifyStateProgramInteger(result, gl, program.getProgram(), GL_PROGRAM_SEPARABLE, GL_TRUE, m_verifier); 437 } 438 439 result.setTestContextResult(m_testCtx); 440 return STOP; 441 } 442 443 class ComputeWorkGroupSizeCase : public TestCase 444 { 445 public: 446 ComputeWorkGroupSizeCase (Context& context, QueryType verifier, const char* name, const char* desc); 447 IterateResult iterate (void); 448 449 private: 450 const QueryType m_verifier; 451 }; 452 453 ComputeWorkGroupSizeCase::ComputeWorkGroupSizeCase (Context& context, QueryType verifier, const char* name, const char* desc) 454 : TestCase (context, name, desc) 455 , m_verifier (verifier) 456 { 457 } 458 459 ComputeWorkGroupSizeCase::IterateResult ComputeWorkGroupSizeCase::iterate (void) 460 { 461 static const char* const s_computeTemplate1D = "${GLSL_VERSION_DECL}\n" 462 "layout (local_size_x = 3) in;\n" 463 "layout(binding = 0) buffer Output\n" 464 "{\n" 465 " highp float val;\n" 466 "} sb_out;\n" 467 "\n" 468 "void main (void)\n" 469 "{\n" 470 " sb_out.val = 1.0;\n" 471 "}\n"; 472 static const char* const s_computeTemplate2D = "${GLSL_VERSION_DECL}\n" 473 "layout (local_size_x = 3, local_size_y = 2) in;\n" 474 "layout(binding = 0) buffer Output\n" 475 "{\n" 476 " highp float val;\n" 477 "} sb_out;\n" 478 "\n" 479 "void main (void)\n" 480 "{\n" 481 " sb_out.val = 1.0;\n" 482 "}\n"; 483 static const char* const s_computeTemplate3D = "${GLSL_VERSION_DECL}\n" 484 "layout (local_size_x = 3, local_size_y = 2, local_size_z = 4) in;\n" 485 "layout(binding = 0) buffer Output\n" 486 "{\n" 487 " highp float val;\n" 488 "} sb_out;\n" 489 "\n" 490 "void main (void)\n" 491 "{\n" 492 " sb_out.val = 1.0;\n" 493 "}\n"; 494 495 glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); 496 tcu::ResultCollector result (m_testCtx.getLog(), " // ERROR: "); 497 498 gl.enableLogging(true); 499 500 { 501 const tcu::ScopedLogSection section (m_testCtx.getLog(), "OneDimensional", "1D"); 502 glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(specializeShader(m_context, s_computeTemplate1D))); 503 504 m_testCtx.getLog() << program; 505 506 TCU_CHECK_MSG(program.isOk(), "failed to build program"); 507 508 verifyStateProgramIntegerVec3(result, gl, program.getProgram(), GL_COMPUTE_WORK_GROUP_SIZE, tcu::IVec3(3, 1, 1), m_verifier); 509 } 510 511 { 512 const tcu::ScopedLogSection section (m_testCtx.getLog(), "TwoDimensional", "2D"); 513 glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(specializeShader(m_context, s_computeTemplate2D))); 514 515 m_testCtx.getLog() << program; 516 517 TCU_CHECK_MSG(program.isOk(), "failed to build program"); 518 519 verifyStateProgramIntegerVec3(result, gl, program.getProgram(), GL_COMPUTE_WORK_GROUP_SIZE, tcu::IVec3(3, 2, 1), m_verifier); 520 } 521 522 { 523 const tcu::ScopedLogSection section (m_testCtx.getLog(), "TreeDimensional", "3D"); 524 glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(specializeShader(m_context, s_computeTemplate3D))); 525 526 m_testCtx.getLog() << program; 527 528 TCU_CHECK_MSG(program.isOk(), "failed to build program"); 529 530 verifyStateProgramIntegerVec3(result, gl, program.getProgram(), GL_COMPUTE_WORK_GROUP_SIZE, tcu::IVec3(3, 2, 4), m_verifier); 531 } 532 533 result.setTestContextResult(m_testCtx); 534 return STOP; 535 } 536 537 class ActiveAtomicCounterBuffersCase : public TestCase 538 { 539 public: 540 ActiveAtomicCounterBuffersCase (Context& context, QueryType verifier, const char* name, const char* desc); 541 IterateResult iterate (void); 542 543 private: 544 const QueryType m_verifier; 545 }; 546 547 ActiveAtomicCounterBuffersCase::ActiveAtomicCounterBuffersCase (Context& context, QueryType verifier, const char* name, const char* desc) 548 : TestCase (context, name, desc) 549 , m_verifier (verifier) 550 { 551 } 552 553 ActiveAtomicCounterBuffersCase::IterateResult ActiveAtomicCounterBuffersCase::iterate (void) 554 { 555 static const char* const s_computeTemplate0 = "${GLSL_VERSION_DECL}\n" 556 "layout (local_size_x = 3) in;\n" 557 "layout(binding = 0) buffer Output\n" 558 "{\n" 559 " highp float val;\n" 560 "} sb_out;\n" 561 "\n" 562 "void main (void)\n" 563 "{\n" 564 " sb_out.val = 1.0;\n" 565 "}\n"; 566 static const char* const s_computeTemplate1 = "${GLSL_VERSION_DECL}\n" 567 "layout (local_size_x = 3) in;\n" 568 "layout(binding = 0) uniform highp atomic_uint u_counters[2];\n" 569 "layout(binding = 0) buffer Output\n" 570 "{\n" 571 " highp float val;\n" 572 "} sb_out;\n" 573 "\n" 574 "void main (void)\n" 575 "{\n" 576 " sb_out.val = float(atomicCounterIncrement(u_counters[0])) + float(atomicCounterIncrement(u_counters[1]));\n" 577 "}\n"; 578 579 glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); 580 tcu::ResultCollector result (m_testCtx.getLog(), " // ERROR: "); 581 582 gl.enableLogging(true); 583 584 { 585 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Initial", "Initial"); 586 glu::Program program (m_context.getRenderContext()); 587 588 verifyStateProgramInteger(result, gl, program.getProgram(), GL_ACTIVE_ATOMIC_COUNTER_BUFFERS, 0, m_verifier); 589 } 590 591 { 592 const tcu::ScopedLogSection section (m_testCtx.getLog(), "NoBuffers", "No buffers"); 593 glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(specializeShader(m_context, s_computeTemplate0))); 594 595 m_testCtx.getLog() << program; 596 597 TCU_CHECK_MSG(program.isOk(), "failed to build program"); 598 599 verifyStateProgramInteger(result, gl, program.getProgram(), GL_ACTIVE_ATOMIC_COUNTER_BUFFERS, 0, m_verifier); 600 } 601 602 { 603 const tcu::ScopedLogSection section (m_testCtx.getLog(), "OneBuffer", "One buffer"); 604 glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(specializeShader(m_context, s_computeTemplate1))); 605 606 m_testCtx.getLog() << program; 607 608 TCU_CHECK_MSG(program.isOk(), "failed to build program"); 609 610 verifyStateProgramInteger(result, gl, program.getProgram(), GL_ACTIVE_ATOMIC_COUNTER_BUFFERS, 1, m_verifier); 611 } 612 613 result.setTestContextResult(m_testCtx); 614 return STOP; 615 } 616 617 class ProgramLogCase : public TestCase 618 { 619 public: 620 enum BuildErrorType 621 { 622 BUILDERROR_VERTEX_FRAGMENT = 0, 623 BUILDERROR_COMPUTE, 624 BUILDERROR_GEOMETRY, 625 BUILDERROR_TESSELLATION, 626 }; 627 628 ProgramLogCase (Context& ctx, const char* name, const char* desc, BuildErrorType errorType); 629 630 private: 631 void init (void); 632 IterateResult iterate (void); 633 glu::ProgramSources getProgramSources (void) const; 634 635 const BuildErrorType m_buildErrorType; 636 }; 637 638 ProgramLogCase::ProgramLogCase (Context& ctx, const char* name, const char* desc, BuildErrorType errorType) 639 : TestCase (ctx, name, desc) 640 , m_buildErrorType (errorType) 641 { 642 } 643 644 void ProgramLogCase::init (void) 645 { 646 const bool supportsES32 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)); 647 648 switch (m_buildErrorType) 649 { 650 case BUILDERROR_VERTEX_FRAGMENT: 651 case BUILDERROR_COMPUTE: 652 break; 653 654 case BUILDERROR_GEOMETRY: 655 if (!supportsES32 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")) 656 TCU_THROW(NotSupportedError, "Test requires GL_EXT_geometry_shader extension"); 657 break; 658 659 case BUILDERROR_TESSELLATION: 660 if (!supportsES32 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader")) 661 TCU_THROW(NotSupportedError, "Test requires GL_EXT_tessellation_shader extension"); 662 break; 663 664 default: 665 DE_ASSERT(false); 666 break; 667 } 668 } 669 670 ProgramLogCase::IterateResult ProgramLogCase::iterate (void) 671 { 672 using gls::StateQueryUtil::StateQueryMemoryWriteGuard; 673 674 tcu::ResultCollector result (m_testCtx.getLog()); 675 glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); 676 glu::ShaderProgram program (m_context.getRenderContext(), getProgramSources()); 677 StateQueryMemoryWriteGuard<glw::GLint> logLen; 678 679 gl.enableLogging(true); 680 681 m_testCtx.getLog() << tcu::TestLog::Message << "Trying to link a broken program." << tcu::TestLog::EndMessage; 682 683 gl.glGetProgramiv(program.getProgram(), GL_INFO_LOG_LENGTH, &logLen); 684 logLen.verifyValidity(result); 685 686 if (logLen.verifyValidity(result)) 687 verifyInfoLogQuery(result, gl, logLen, program.getProgram(), &glu::CallLogWrapper::glGetProgramInfoLog, "glGetProgramInfoLog"); 688 689 result.setTestContextResult(m_testCtx); 690 return STOP; 691 } 692 693 glu::ProgramSources ProgramLogCase::getProgramSources (void) const 694 { 695 const char* const vertexTemplate1 = "${GLSL_VERSION_DECL}\n" 696 "in highp vec4 a_pos;\n" 697 "uniform highp vec4 u_uniform;\n" 698 "void main()\n" 699 "{\n" 700 " gl_Position = a_pos + u_uniform;\n" 701 "}\n"; 702 const char* const vertexTemplate2 = "${GLSL_VERSION_DECL}\n" 703 "in highp vec4 a_pos;\n" 704 "void main()\n" 705 "{\n" 706 " gl_Position = a_pos;\n" 707 "}\n"; 708 const char* const fragmentTemplate1 = "${GLSL_VERSION_DECL}\n" 709 "in highp vec4 v_missingVar;\n" 710 "uniform highp int u_uniform;\n" 711 "layout(location = 0) out mediump vec4 fragColor;\n" 712 "void main()\n" 713 "{\n" 714 " fragColor = v_missingVar + vec4(float(u_uniform));\n" 715 "}\n"; 716 717 const char* const fragmentTemplate2 = "${GLSL_VERSION_DECL}\n" 718 "layout(location = 0) out mediump vec4 fragColor;\n" 719 "void main()\n" 720 "{\n" 721 " fragColor = vec4(1.0);\n" 722 "}\n"; 723 const char* const computeTemplate1 = "${GLSL_VERSION_DECL}\n" 724 "layout (binding = 0) buffer IOBuffer { highp float buf_var; };\n" 725 "uniform highp vec4 u_uniform;\n" 726 "void main()\n" 727 "{\n" 728 " buf_var = u_uniform.x;\n" 729 "}\n"; 730 const char* const geometryTemplate1 = "${GLSL_VERSION_DECL}\n" 731 "${GEOMETRY_SHADER_REQUIRE}\n" 732 "layout(triangles) in;\n" 733 "layout(max_vertices=1, points) out;\n" 734 "in highp vec4 v_missingVar[];\n" 735 "uniform highp int u_uniform;\n" 736 "void main()\n" 737 "{\n" 738 " gl_Position = gl_in[0].gl_Position + v_missingVar[2] + vec4(float(u_uniform));\n" 739 " EmitVertex();\n" 740 "}\n"; 741 const char* const tessCtrlTemplate1 = "${GLSL_VERSION_DECL}\n" 742 "${TESSELLATION_SHADER_REQUIRE}\n" 743 "layout(vertices=2) out;" 744 "patch out highp vec2 vp_var;\n" 745 "void main()\n" 746 "{\n" 747 " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position\n" 748 " gl_TessLevelOuter[0] = 0.8;\n" 749 " gl_TessLevelOuter[1] = 0.8;\n" 750 " if (gl_InvocationID == 0)\n" 751 " vp_var = gl_in[gl_InvocationID].gl_Position.xy;\n" 752 "}\n"; 753 const char* const tessEvalTemplate1 = "${GLSL_VERSION_DECL}\n" 754 "${TESSELLATION_SHADER_REQUIRE}\n" 755 "layout(isolines) in;" 756 "in highp float vp_var[];\n" 757 "void main()\n" 758 "{\n" 759 " gl_Position = gl_in[gl_InvocationID].gl_Position + vec4(vp_var[1]);\n" 760 "}\n"; 761 762 switch (m_buildErrorType) 763 { 764 case BUILDERROR_VERTEX_FRAGMENT: 765 return glu::ProgramSources() 766 << glu::VertexSource(specializeShader(m_context, vertexTemplate1)) 767 << glu::FragmentSource(specializeShader(m_context, fragmentTemplate1)); 768 769 case BUILDERROR_COMPUTE: 770 return glu::ProgramSources() 771 << glu::ComputeSource(specializeShader(m_context, computeTemplate1)); 772 773 case BUILDERROR_GEOMETRY: 774 return glu::ProgramSources() 775 << glu::VertexSource(specializeShader(m_context, vertexTemplate1)) 776 << glu::GeometrySource(specializeShader(m_context, geometryTemplate1)) 777 << glu::FragmentSource(specializeShader(m_context, fragmentTemplate2)); 778 779 case BUILDERROR_TESSELLATION: 780 return glu::ProgramSources() 781 << glu::VertexSource(specializeShader(m_context, vertexTemplate2)) 782 << glu::TessellationControlSource(specializeShader(m_context, tessCtrlTemplate1)) 783 << glu::TessellationEvaluationSource(specializeShader(m_context, tessEvalTemplate1)) 784 << glu::FragmentSource(specializeShader(m_context, fragmentTemplate2)); 785 786 default: 787 DE_ASSERT(false); 788 return glu::ProgramSources(); 789 } 790 } 791 792 } // anonymous 793 794 ProgramStateQueryTests::ProgramStateQueryTests (Context& context) 795 : TestCaseGroup(context, "program", "Program State Query tests") 796 { 797 } 798 799 ProgramStateQueryTests::~ProgramStateQueryTests (void) 800 { 801 } 802 803 void ProgramStateQueryTests::init (void) 804 { 805 static const QueryType intVerifiers[] = 806 { 807 QUERY_PROGRAM_INTEGER, 808 }; 809 static const QueryType intVec3Verifiers[] = 810 { 811 QUERY_PROGRAM_INTEGER_VEC3, 812 }; 813 814 #define FOR_EACH_INT_VERIFIER(X) \ 815 for (int verifierNdx = 0; verifierNdx < DE_LENGTH_OF_ARRAY(intVerifiers); ++verifierNdx) \ 816 { \ 817 const char* verifierSuffix = getVerifierSuffix(intVerifiers[verifierNdx]); \ 818 const QueryType verifier = intVerifiers[verifierNdx]; \ 819 this->addChild(X); \ 820 } 821 822 #define FOR_EACH_VEC_VERIFIER(X) \ 823 for (int verifierNdx = 0; verifierNdx < DE_LENGTH_OF_ARRAY(intVec3Verifiers); ++verifierNdx) \ 824 { \ 825 const char* verifierSuffix = getVerifierSuffix(intVec3Verifiers[verifierNdx]); \ 826 const QueryType verifier = intVec3Verifiers[verifierNdx]; \ 827 this->addChild(X); \ 828 } 829 830 FOR_EACH_INT_VERIFIER(new ProgramSeparableCase (m_context, verifier, (std::string("program_separable_") + verifierSuffix).c_str(), "Test PROGRAM_SEPARABLE")); 831 FOR_EACH_VEC_VERIFIER(new ComputeWorkGroupSizeCase (m_context, verifier, (std::string("compute_work_group_size_") + verifierSuffix).c_str(), "Test COMPUTE_WORK_GROUP_SIZE")); 832 FOR_EACH_INT_VERIFIER(new ActiveAtomicCounterBuffersCase (m_context, verifier, (std::string("active_atomic_counter_buffers_") + verifierSuffix).c_str(), "Test ACTIVE_ATOMIC_COUNTER_BUFFERS")); 833 FOR_EACH_INT_VERIFIER(new GeometryShaderCase (m_context, verifier, (std::string("geometry_shader_state_") + verifierSuffix).c_str(), "Test Geometry Shader State")); 834 FOR_EACH_INT_VERIFIER(new TessellationShaderCase (m_context, verifier, (std::string("tesselation_shader_state_") + verifierSuffix).c_str(), "Test Tesselation Shader State")); 835 836 #undef FOR_EACH_INT_VERIFIER 837 #undef FOR_EACH_VEC_VERIFIER 838 839 // program info log tests 840 // \note, there exists similar tests in gles3 module. However, the gles31 could use a different 841 // shader compiler with different INFO_LOG bugs. 842 { 843 static const struct 844 { 845 const char* caseName; 846 ProgramLogCase::BuildErrorType caseType; 847 } shaderTypes[] = 848 { 849 { "info_log_vertex_fragment_link_fail", ProgramLogCase::BUILDERROR_VERTEX_FRAGMENT }, 850 { "info_log_compute_link_fail", ProgramLogCase::BUILDERROR_COMPUTE }, 851 { "info_log_geometry_link_fail", ProgramLogCase::BUILDERROR_GEOMETRY }, 852 { "info_log_tessellation_link_fail", ProgramLogCase::BUILDERROR_TESSELLATION }, 853 }; 854 855 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(shaderTypes); ++ndx) 856 addChild(new ProgramLogCase(m_context, shaderTypes[ndx].caseName, "", shaderTypes[ndx].caseType)); 857 } 858 } 859 860 } // Functional 861 } // gles31 862 } // deqp 863