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