1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
5 * Copyright (c) 2017 The Khronos Group Inc.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 * \file glcRobustnessTests.cpp
21 * \brief Conformance tests for the Robustness feature functionality.
22 */ /*-------------------------------------------------------------------*/
24 #include "glcRobustnessTests.hpp"
25 #include "deSharedPtr.hpp"
26 #include "glcRobustBufferAccessBehaviorTests.hpp"
27 #include "gluContextInfo.hpp"
28 #include "gluPlatform.hpp"
29 #include "gluRenderContext.hpp"
30 #include "glwEnums.hpp"
31 #include "glwFunctions.hpp"
32 #include "tcuCommandLine.hpp"
33 #include "tcuTestLog.hpp"
37 using namespace deqp::RobustBufferAccessBehavior;
42 namespace ResetNotificationStrategy
45 class RobustnessBase : public tcu::TestCase
48 RobustnessBase(tcu::TestContext& testCtx, const char* name, const char* description, glu::ApiType apiType);
50 glu::RenderContext* createRobustContext(glu::ResetNotificationStrategy reset);
53 glu::ApiType m_ApiType;
56 RobustnessBase::RobustnessBase(tcu::TestContext& testCtx, const char* name, const char* description,
58 : tcu::TestCase(testCtx, name, description), m_ApiType(apiType)
62 glu::RenderContext* RobustnessBase::createRobustContext(glu::ResetNotificationStrategy reset)
64 /* Create test context to verify if GL_KHR_robustness extension is available */
66 deqp::Context context(m_testCtx, glu::ContextType(m_ApiType));
67 if (!context.getContextInfo().isExtensionSupported("GL_KHR_robustness") &&
68 !contextSupports(context.getRenderContext().getType(), glu::ApiType::es(3, 2)))
70 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED,
71 "GL_KHR_robustness extension not supported");
76 glu::RenderConfig renderCfg(glu::ContextType(m_ApiType, glu::CONTEXT_ROBUST));
77 const tcu::CommandLine& commandLine = m_testCtx.getCommandLine();
78 glu::parseRenderConfig(&renderCfg, commandLine);
80 if (commandLine.getSurfaceType() == tcu::SURFACETYPE_WINDOW)
81 renderCfg.resetNotificationStrategy = reset;
83 throw tcu::NotSupportedError("Test not supported in non-windowed context");
85 /* Try to create core/es robusness context */
86 return createRenderContext(m_testCtx.getPlatform(), commandLine, renderCfg);
89 class NoResetNotificationCase : public RobustnessBase
91 typedef glw::GLenum(GLW_APIENTRY* PFNGLGETGRAPHICSRESETSTATUS)();
94 NoResetNotificationCase(tcu::TestContext& testCtx, const char* name, const char* description, glu::ApiType apiType)
95 : RobustnessBase(testCtx, name, description, apiType)
99 virtual IterateResult iterate(void)
101 glu::ResetNotificationStrategy strategy = glu::RESET_NOTIFICATION_STRATEGY_NO_RESET_NOTIFICATION;
102 de::SharedPtr<glu::RenderContext> robustContext(createRobustContext(strategy));
103 if (!robustContext.get())
106 PFNGLGETGRAPHICSRESETSTATUS pGetGraphicsResetStatus =
107 (PFNGLGETGRAPHICSRESETSTATUS)robustContext->getProcAddress("glGetGraphicsResetStatus");
109 if (DE_NULL == pGetGraphicsResetStatus)
111 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR,
112 "Pointer to function glGetGraphicsResetStatus is NULL.");
116 glw::GLint reset = 0;
118 const glw::Functions& gl = robustContext->getFunctions();
119 gl.getIntegerv(GL_RESET_NOTIFICATION_STRATEGY, &reset);
120 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv");
122 if (reset != GL_NO_RESET_NOTIFICATION)
124 m_testCtx.getLog() << tcu::TestLog::Message << "Test failed! glGet returned wrong value [" << reset
125 << ", expected " << GL_NO_RESET_NOTIFICATION << "]." << tcu::TestLog::EndMessage;
127 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
131 glw::GLint status = pGetGraphicsResetStatus();
132 if (status != GL_NO_ERROR)
134 m_testCtx.getLog() << tcu::TestLog::Message
135 << "Test failed! glGetGraphicsResetStatus returned wrong value [" << status
136 << ", expected " << GL_NO_ERROR << "]." << tcu::TestLog::EndMessage;
138 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
142 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
147 class LoseContextOnResetCase : public RobustnessBase
150 LoseContextOnResetCase(tcu::TestContext& testCtx, const char* name, const char* description, glu::ApiType apiType)
151 : RobustnessBase(testCtx, name, description, apiType)
155 virtual IterateResult iterate(void)
157 glu::ResetNotificationStrategy strategy = glu::RESET_NOTIFICATION_STRATEGY_LOSE_CONTEXT_ON_RESET;
158 de::SharedPtr<glu::RenderContext> robustContext(createRobustContext(strategy));
159 if (!robustContext.get())
162 glw::GLint reset = 0;
164 const glw::Functions& gl = robustContext->getFunctions();
165 gl.getIntegerv(GL_RESET_NOTIFICATION_STRATEGY, &reset);
166 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv");
168 if (reset != GL_LOSE_CONTEXT_ON_RESET)
170 m_testCtx.getLog() << tcu::TestLog::Message << "Test failed! glGet returned wrong value [" << reset
171 << ", expected " << GL_LOSE_CONTEXT_ON_RESET << "]." << tcu::TestLog::EndMessage;
173 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
177 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
182 } // ResetNotificationStrategy namespace
184 namespace RobustBufferAccessBehavior
187 static deqp::Context* createContext(tcu::TestContext& testCtx, glu::ApiType apiType)
189 deqp::Context* context = new deqp::Context(testCtx, glu::ContextType(apiType));
192 testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Pointer to context is NULL.");
196 if (!(contextSupports(context->getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
197 (context->getContextInfo().isExtensionSupported("GL_KHR_robustness") &&
198 context->getContextInfo().isExtensionSupported("GL_KHR_robust_buffer_access_behavior"))))
200 testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
208 /** Implementation of test GetnUniformTest. Description follows:
210 * This test verifies if read uniform variables to the buffer with bufSize less than expected result with GL_INVALID_OPERATION error;
212 class GetnUniformTest : public tcu::TestCase
216 GetnUniformTest(tcu::TestContext& testCtx, glu::ApiType apiType);
217 virtual ~GetnUniformTest()
221 /* Public methods inherited from TestCase */
222 virtual tcu::TestNode::IterateResult iterate(void);
225 /* Private methods */
226 std::string getComputeShader(bool glslES320);
228 bool verifyResult(const void* inputData, const void* resultData, int size, const char* method);
229 bool verifyError(glw::GLint error, glw::GLint expectedError, const char* method);
231 glu::ApiType m_ApiType;
236 * @param context Test context
238 GetnUniformTest::GetnUniformTest(tcu::TestContext& testCtx, glu::ApiType apiType)
239 : tcu::TestCase(testCtx, "getnuniform", "Verifies if read uniform variables to the buffer with bufSize less than "
240 "expected result with GL_INVALID_OPERATION")
243 /* Nothing to be done here */
248 * @return tcu::TestNode::STOP
250 tcu::TestNode::IterateResult GetnUniformTest::iterate()
252 de::SharedPtr<deqp::Context> context(createContext(m_testCtx, m_ApiType));
256 /* GL funtion pointers. */
257 typedef void(GLW_APIENTRY * PFNGLGETNUNIFORMFV)(glw::GLuint program, glw::GLint location, glw::GLsizei bufSize,
258 glw::GLfloat * params);
259 typedef void(GLW_APIENTRY * PFNGLGETNUNIFORMIV)(glw::GLuint program, glw::GLint location, glw::GLsizei bufSize,
260 glw::GLint * params);
261 typedef void(GLW_APIENTRY * PFNGLGETNUNIFORMUIV)(glw::GLuint program, glw::GLint location, glw::GLsizei bufSize,
262 glw::GLuint * params);
264 /* Function pointers need to be grabbed only for GL4.5 but it is done also for ES for consistency */
265 glu::RenderContext& renderContext = context->getRenderContext();
266 PFNGLGETNUNIFORMFV pGetnUniformfv = (PFNGLGETNUNIFORMFV)renderContext.getProcAddress("glGetnUniformfv");
267 PFNGLGETNUNIFORMIV pGetnUniformiv = (PFNGLGETNUNIFORMIV)renderContext.getProcAddress("glGetnUniformiv");
268 PFNGLGETNUNIFORMUIV pGetnUniformuiv = (PFNGLGETNUNIFORMUIV)renderContext.getProcAddress("glGetnUniformuiv");
270 if ((DE_NULL == pGetnUniformfv) || (DE_NULL == pGetnUniformiv) || (DE_NULL == pGetnUniformuiv))
272 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Pointer to function glGetnUniform* is NULL.");
276 const Functions& gl = renderContext.getFunctions();
278 const GLfloat input4f[] = { 1.0f, 5.4f, 3.14159f, 1.28f };
279 const GLint input3i[] = { 10, -20, -30 };
280 const GLuint input4ui[] = { 10, 20, 30, 40 };
282 /* Test result indicator */
283 bool test_result = true;
285 /* Iterate over all cases */
286 Program program(*context);
289 bool glslES320 = contextSupports(renderContext.getType(), glu::ApiType::es(3, 2));
290 const std::string& cs = getComputeShader(glslES320);
292 /* Shaders initialization */
293 program.Init(cs /* cs */, "" /* fs */, "" /* gs */, "" /* tcs */, "" /* tes */, "" /* vs */);
296 /* For gl4.5 use shader storage buffer */
300 gl.genBuffers(1, &buf);
301 GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");
303 gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buf);
304 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferBase");
306 gl.bufferData(GL_SHADER_STORAGE_BUFFER, 16, DE_NULL, GL_STREAM_DRAW);
307 GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData");
310 /* passing uniform values */
311 gl.programUniform4fv(program.m_id, 11, 1, input4f);
312 GLU_EXPECT_NO_ERROR(gl.getError(), "ProgramUniform4fv");
314 gl.programUniform3iv(program.m_id, 12, 1, input3i);
315 GLU_EXPECT_NO_ERROR(gl.getError(), "ProgramUniform3iv");
317 gl.programUniform4uiv(program.m_id, 13, 1, input4ui);
318 GLU_EXPECT_NO_ERROR(gl.getError(), "ProgramUniform4uiv");
320 gl.dispatchCompute(1, 1, 1);
321 GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
323 /* veryfing gfetnUniform error messages */
328 pGetnUniformfv(program.m_id, 11, sizeof(GLfloat) * 4, result4f);
329 test_result = test_result &&
330 verifyResult((void*)input4f, (void*)result4f, sizeof(GLfloat) * 4, "getnUniformfv [false negative]");
331 test_result = test_result && verifyError(gl.getError(), GL_NO_ERROR, "getnUniformfv [false negative]");
333 pGetnUniformfv(program.m_id, 11, sizeof(GLfloat) * 3, result4f);
334 test_result = test_result && verifyError(gl.getError(), GL_INVALID_OPERATION, "getnUniformfv [false positive]");
336 pGetnUniformiv(program.m_id, 12, sizeof(GLint) * 3, result3i);
337 test_result = test_result &&
338 verifyResult((void*)input3i, (void*)result3i, sizeof(GLint) * 3, "getnUniformiv [false negative]");
339 test_result = test_result && verifyError(gl.getError(), GL_NO_ERROR, "getnUniformiv [false negative]");
341 pGetnUniformiv(program.m_id, 12, sizeof(GLint) * 2, result3i);
342 test_result = test_result && verifyError(gl.getError(), GL_INVALID_OPERATION, "getnUniformiv [false positive]");
344 pGetnUniformuiv(program.m_id, 13, sizeof(GLuint) * 4, result4ui);
345 test_result = test_result && verifyResult((void*)input4ui, (void*)result4ui, sizeof(GLuint) * 4,
346 "getnUniformuiv [false negative]");
347 test_result = test_result && verifyError(gl.getError(), GL_NO_ERROR, "getnUniformuiv [false negative]");
349 pGetnUniformuiv(program.m_id, 13, sizeof(GLuint) * 3, result4ui);
350 test_result = test_result && verifyError(gl.getError(), GL_INVALID_OPERATION, "getnUniformuiv [false positive]");
353 if (true == test_result)
355 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
359 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
364 gl.deleteBuffers(1, &buf);
368 return tcu::TestNode::STOP;
371 std::string GetnUniformTest::getComputeShader(bool glslES320)
373 std::stringstream shader;
374 shader << "#version " << (glslES320 ? "320 es\n" : "450\n");
375 shader << "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
376 "layout (location = 11) uniform vec4 inputf;\n"
377 "layout (location = 12) uniform ivec3 inputi;\n"
378 "layout (location = 13) uniform uvec4 inputu;\n";
381 shader << "shared float valuef;\n"
382 "shared int valuei;\n"
383 "shared uint valueu;\n";
387 shader << "layout (std140, binding = 0) buffer ssbo {"
393 shader << "void main()\n"
395 " valuef = inputf.r + inputf.g + inputf.b + inputf.a;\n"
396 " valuei = inputi.r + inputi.g + inputi.b;\n"
397 " valueu = inputu.r + inputu.g + inputu.b + inputu.a;\n"
403 bool GetnUniformTest::verifyResult(const void* inputData, const void* resultData, int size, const char* method)
405 int diff = memcmp(inputData, resultData, size);
408 m_testCtx.getLog() << tcu::TestLog::Message << "Test failed! " << method << " result is not as expected."
409 << tcu::TestLog::EndMessage;
417 bool GetnUniformTest::verifyError(GLint error, GLint expectedError, const char* method)
419 if (error != expectedError)
421 m_testCtx.getLog() << tcu::TestLog::Message << "Test failed! " << method << " throws unexpected error ["
422 << error << "]." << tcu::TestLog::EndMessage;
430 /** Implementation of test ReadnPixelsTest. Description follows:
432 * This test verifies if read pixels to the buffer with bufSize less than expected result with GL_INVALID_OPERATION error;
434 class ReadnPixelsTest : public tcu::TestCase
438 ReadnPixelsTest(tcu::TestContext& testCtx, glu::ApiType apiType);
439 virtual ~ReadnPixelsTest()
443 /* Public methods inherited from TestCase */
444 virtual tcu::TestNode::IterateResult iterate(void);
447 /* Private methods */
448 void cleanTexture(deqp::Context& context, glw::GLuint texture_id);
449 bool verifyResults(deqp::Context& context);
450 bool verifyError(glw::GLint error, glw::GLint expectedError, const char* method);
452 glu::ApiType m_ApiType;
457 * @param context Test context
459 ReadnPixelsTest::ReadnPixelsTest(tcu::TestContext& testCtx, glu::ApiType apiType)
460 : tcu::TestCase(testCtx, "readnpixels",
461 "Verifies if read pixels to the buffer with bufSize less than expected result "
462 "with GL_INVALID_OPERATION error")
465 /* Nothing to be done here */
470 * @return tcu::TestNode::STOP
472 tcu::TestNode::IterateResult ReadnPixelsTest::iterate()
474 de::SharedPtr<deqp::Context> context(createContext(m_testCtx, m_ApiType));
478 /* GL funtion pointers. */
479 typedef void(GLW_APIENTRY * PFNGLREADNPIXELS)(glw::GLint x, glw::GLint y, glw::GLsizei width, glw::GLsizei height,
480 glw::GLenum format, glw::GLenum type, glw::GLsizei bufSize,
483 PFNGLREADNPIXELS pReadnPixels = (PFNGLREADNPIXELS)context->getRenderContext().getProcAddress("glReadnPixels");
485 if (DE_NULL == pReadnPixels)
487 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Pointer to function glReadnPixels is NULL.");
491 static const GLuint elements[] = {
492 0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 5, 0, 5, 6, 0, 6, 7, 0, 7, 8, 0, 8, 1,
495 static const GLfloat vertices[] = {
496 0.0f, 0.0f, 0.0f, 1.0f, /* 0 */
497 -1.0f, 0.0f, 0.0f, 1.0f, /* 1 */
498 -1.0f, 1.0f, 0.0f, 1.0f, /* 2 */
499 0.0f, 1.0f, 0.0f, 1.0f, /* 3 */
500 1.0f, 1.0f, 0.0f, 1.0f, /* 4 */
501 1.0f, 0.0f, 0.0f, 1.0f, /* 5 */
502 1.0f, -1.0f, 0.0f, 1.0f, /* 6 */
503 0.0f, -1.0f, 0.0f, 1.0f, /* 7 */
504 -1.0f, -1.0f, 0.0f, 1.0f, /* 8 */
507 bool glslES320 = contextSupports(context->getRenderContext().getType(), glu::ApiType::es(3, 2));
508 std::string fs("#version ");
509 fs += (glslES320 ? "320 es\n" : "450\n");
510 fs += "layout (location = 0) out lowp uvec4 out_fs_color;\n"
514 " out_fs_color = uvec4(1, 0, 0, 1);\n"
518 std::string vs("#version ");
519 vs += (glslES320 ? "320 es\n" : "450\n");
520 vs += "layout (location = 0) in vec4 in_vs_position;\n"
524 " gl_Position = in_vs_position;\n"
528 static const GLuint height = 8;
529 static const GLuint width = 8;
530 static const GLuint n_vertices = 24;
532 /* GL entry points */
533 const Functions& gl = context->getRenderContext().getFunctions();
535 /* Test case objects */
536 Program program(*context);
537 Texture texture(*context);
538 Buffer elements_buffer(*context);
539 Buffer vertices_buffer(*context);
540 VertexArray vao(*context);
542 /* Vertex array initialization */
543 VertexArray::Generate(gl, vao.m_id);
544 VertexArray::Bind(gl, vao.m_id);
546 /* Texture initialization */
547 Texture::Generate(gl, texture.m_id);
548 Texture::Bind(gl, texture.m_id, GL_TEXTURE_2D);
549 Texture::Storage(gl, GL_TEXTURE_2D, 1, GL_R8UI, width, height, 0);
550 Texture::Bind(gl, 0, GL_TEXTURE_2D);
552 /* Framebuffer initialization */
554 gl.genFramebuffers(1, &fbo);
555 GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
556 gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
557 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
558 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture.m_id, 0);
559 GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture2D");
561 /* Buffers initialization */
562 elements_buffer.InitData(GL_ELEMENT_ARRAY_BUFFER, GL_DYNAMIC_DRAW, sizeof(elements), elements);
563 vertices_buffer.InitData(GL_ARRAY_BUFFER, GL_DYNAMIC_DRAW, sizeof(vertices), vertices);
565 /* Shaders initialization */
566 program.Init("" /* cs */, fs, "" /* gs */, "" /* tcs */, "" /* tes */, vs);
567 Program::Use(gl, program.m_id);
569 /* Vertex buffer initialization */
570 vertices_buffer.Bind();
571 gl.bindVertexBuffer(0 /* bindindex = location */, vertices_buffer.m_id, 0 /* offset */, 16 /* stride */);
572 gl.vertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 16, NULL);
573 gl.enableVertexAttribArray(0 /* location */);
575 /* Binding elements/indices buffer */
576 elements_buffer.Bind();
578 cleanTexture(*context, texture.m_id);
580 gl.drawElements(GL_TRIANGLES, n_vertices, GL_UNSIGNED_INT, 0 /* indices */);
581 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElements");
584 if (verifyResults(*context))
586 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
590 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
594 return tcu::TestNode::STOP;
597 /** Fill texture with value 128
599 * @param texture_id Id of texture
601 void ReadnPixelsTest::cleanTexture(deqp::Context& context, glw::GLuint texture_id)
603 static const GLuint height = 8;
604 static const GLuint width = 8;
606 const Functions& gl = context.getRenderContext().getFunctions();
608 GLubyte pixels[width * height];
609 for (GLuint i = 0; i < width * height; ++i)
614 Texture::Bind(gl, texture_id, GL_TEXTURE_2D);
616 Texture::SubImage(gl, GL_TEXTURE_2D, 0 /* level */, 0 /* x */, 0 /* y */, 0 /* z */, width, height, 0 /* depth */,
617 GL_RED_INTEGER, GL_UNSIGNED_BYTE, pixels);
620 Texture::Bind(gl, 0, GL_TEXTURE_2D);
623 /** Verifies glReadnPixels results
625 * @return true when glReadnPixels , false otherwise
627 bool ReadnPixelsTest::verifyResults(deqp::Context& context)
629 static const GLuint height = 8;
630 static const GLuint width = 8;
631 static const GLuint pixel_size = 4 * sizeof(GLuint);
633 const Functions& gl = context.getRenderContext().getFunctions();
635 //Valid buffer size test
636 const GLint bufSizeValid = width * height * pixel_size;
637 GLubyte pixelsValid[bufSizeValid];
639 gl.readnPixels(0, 0, width, height, GL_RGBA_INTEGER, GL_UNSIGNED_INT, bufSizeValid, pixelsValid);
640 GLU_EXPECT_NO_ERROR(gl.getError(), "ReadnPixels");
642 //Verify glReadnPixels result
643 for (unsigned int i = 0; i < width * height; ++i)
645 const size_t offset = i * pixel_size;
646 const GLuint value = *(GLuint*)(pixelsValid + offset);
650 context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid pixel value: " << value
651 << ". Offset: " << offset << tcu::TestLog::EndMessage;
656 //Invalid buffer size test
657 const GLint bufSizeInvalid = width * height * pixel_size - 1;
658 GLubyte pixelsInvalid[bufSizeInvalid];
660 gl.readnPixels(0, 0, width, height, GL_RGBA_INTEGER, GL_UNSIGNED_INT, bufSizeInvalid, pixelsInvalid);
661 if (!verifyError(gl.getError(), GL_INVALID_OPERATION, "ReadnPixels [false positive]"))
667 /** Verify operation errors
669 * @param error OpenGL ES error code
670 * @param expectedError Expected error code
671 * @param method Method name marker
673 * @return true when error is as expected, false otherwise
675 bool ReadnPixelsTest::verifyError(GLint error, GLint expectedError, const char* method)
677 if (error != expectedError)
679 m_testCtx.getLog() << tcu::TestLog::Message << "Test failed! " << method << " throws unexpected error ["
680 << error << "]." << tcu::TestLog::EndMessage;
688 } // RobustBufferAccessBehavior namespace
690 RobustnessTests::RobustnessTests(tcu::TestContext& testCtx, glu::ApiType apiType)
691 : tcu::TestCaseGroup(testCtx, "robustness",
692 "Verifies API coverage and functionality of GL_KHR_robustness extension.")
697 void RobustnessTests::init(void)
699 tcu::TestCaseGroup::init();
703 addChild(new ResetNotificationStrategy::NoResetNotificationCase(
704 m_testCtx, "no_reset_notification", "Verifies if NO_RESET_NOTIFICATION strategy works as expected.",
706 addChild(new ResetNotificationStrategy::LoseContextOnResetCase(
707 m_testCtx, "lose_context_on_reset", "Verifies if LOSE_CONTEXT_ON_RESET strategy works as expected.",
710 addChild(new RobustBufferAccessBehavior::GetnUniformTest(m_testCtx, m_ApiType));
711 addChild(new RobustBufferAccessBehavior::ReadnPixelsTest(m_testCtx, m_ApiType));
716 tcu::TestCaseGroup::deinit();