1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program EGL Module
3 * ---------------------------------------
4 *
5 * Copyright 2017 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 Robustness tests for KHR_robustness.
22 *//*--------------------------------------------------------------------*/
23
24 #include "teglRobustnessTests.hpp"
25
26 #include "tcuTestLog.hpp"
27 #include "tcuStringTemplate.hpp"
28
29 #include "egluConfigFilter.hpp"
30 #include "egluStrUtil.hpp"
31 #include "egluUtil.hpp"
32 #include "eglwLibrary.hpp"
33
34 #include "gluStrUtil.hpp"
35 #include "gluShaderProgram.hpp"
36 #include "gluDrawUtil.hpp"
37
38 #include "glwFunctions.hpp"
39 #include "glwEnums.hpp"
40
41 #include "deSTLUtil.hpp"
42 #include "deStringUtil.hpp"
43 #include "deThread.hpp"
44 #include "deSharedPtr.hpp"
45
46 #include <set>
47
48 using std::set;
49 using std::string;
50 using std::vector;
51 using tcu::TestLog;
52
53 using namespace eglw;
54
55 DE_STATIC_ASSERT(GL_RESET_NOTIFICATION_STRATEGY == 0x8256);
56 DE_STATIC_ASSERT(GL_LOSE_CONTEXT_ON_RESET == 0x8252);
57 DE_STATIC_ASSERT(GL_NO_RESET_NOTIFICATION == 0x8261);
58
59 namespace deqp
60 {
61 namespace egl
62 {
63 namespace
64 {
65
66 enum ContextResetType
67 {
68 CONTEXTRESETTYPE_SHADER_OOB,
69 CONTEXTRESETTYPE_FIXED_FUNC_OOB,
70 };
71
72 enum ShaderType
73 {
74 SHADERTYPE_VERT,
75 SHADERTYPE_FRAG,
76 SHADERTYPE_COMPUTE,
77 SHADERTYPE_VERT_AND_FRAG,
78 };
79
80 enum ReadWriteType
81 {
82 READWRITETYPE_READ,
83 READWRITETYPE_WRITE,
84 };
85
86 enum ResourceType
87 {
88 RESOURCETYPE_UBO,
89 RESOURCETYPE_SSBO,
90 RESOURCETYPE_LOCAL_ARRAY,
91 };
92
93 enum FixedFunctionType
94 {
95 FIXEDFUNCTIONTYPE_INDICES,
96 FIXEDFUNCTIONTYPE_VERTICES,
97 };
98
99 enum RobustAccessType
100 {
101 ROBUSTACCESS_TRUE,
102 ROBUSTACCESS_FALSE,
103 };
104
requireEGLExtension(const Library & egl,EGLDisplay eglDisplay,const char * requiredExtension)105 void requireEGLExtension(const Library &egl, EGLDisplay eglDisplay, const char *requiredExtension)
106 {
107 if (!eglu::hasExtension(egl, eglDisplay, requiredExtension))
108 TCU_THROW(NotSupportedError, (string(requiredExtension) + " not supported").c_str());
109 }
110
isWindow(const eglu::CandidateConfig & c)111 bool isWindow(const eglu::CandidateConfig &c)
112 {
113 return (c.surfaceType() & EGL_WINDOW_BIT) == EGL_WINDOW_BIT;
114 }
115
116 template <uint32_t Type>
renderable(const eglu::CandidateConfig & c)117 bool renderable(const eglu::CandidateConfig &c)
118 {
119 return (c.renderableType() & Type) == Type;
120 }
121
getRenderableFilter(uint32_t bits)122 eglu::ConfigFilter getRenderableFilter(uint32_t bits)
123 {
124 switch (bits)
125 {
126 case EGL_OPENGL_ES2_BIT:
127 return renderable<EGL_OPENGL_ES2_BIT>;
128 case EGL_OPENGL_ES3_BIT:
129 return renderable<EGL_OPENGL_ES3_BIT>;
130 case EGL_OPENGL_BIT:
131 return renderable<EGL_OPENGL_BIT>;
132 default:
133 DE_FATAL("Unknown EGL bitfied value");
134 return renderable<0>;
135 }
136 }
137
eglResetNotificationStrategyToString(EGLint strategy)138 const char *eglResetNotificationStrategyToString(EGLint strategy)
139 {
140 switch (strategy)
141 {
142 case EGL_NO_RESET_NOTIFICATION_KHR:
143 return "EGL_NO_RESET_NOTIFICATION_KHR";
144 case EGL_LOSE_CONTEXT_ON_RESET_KHR:
145 return "EGL_LOSE_CONTEXT_ON_RESET_KHR";
146 default:
147 return "<Unknown>";
148 }
149 }
150
logAttribList(const EglTestContext & eglTestCtx,const EGLint * attribList)151 void logAttribList(const EglTestContext &eglTestCtx, const EGLint *attribList)
152 {
153 const EGLint *iter = &(attribList[0]);
154 std::ostringstream attribListString;
155
156 while ((*iter) != EGL_NONE)
157 {
158 switch (*iter)
159 {
160 // case EGL_CONTEXT_CLIENT_VERSION:
161 case EGL_CONTEXT_MAJOR_VERSION_KHR:
162 iter++;
163 attribListString << "EGL_CONTEXT_CLIENT_VERSION, " << (*iter) << ", ";
164 iter++;
165 break;
166
167 case EGL_CONTEXT_MINOR_VERSION_KHR:
168 iter++;
169 attribListString << "EGL_CONTEXT_MINOR_VERSION_KHR, " << (*iter) << ", ";
170 iter++;
171 break;
172
173 case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
174 iter++;
175 attribListString << "EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, "
176 << eglResetNotificationStrategyToString(*iter) << ", ";
177 iter++;
178 break;
179
180 case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR:
181 iter++;
182 attribListString << "EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, "
183 << eglResetNotificationStrategyToString(*iter) << ", ";
184 iter++;
185 break;
186
187 case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
188 iter++;
189 attribListString << "EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, ";
190
191 if (*iter == EGL_FALSE || *iter == EGL_TRUE)
192 attribListString << (*iter ? "EGL_TRUE" : "EGL_FALSE") << ", ";
193 else
194 attribListString << (*iter) << ", ";
195 iter++;
196 break;
197
198 default:
199 DE_FATAL("Unsupported attribute");
200 }
201 }
202
203 attribListString << "EGL_NONE";
204 eglTestCtx.getTestContext().getLog() << TestLog::Message << "EGL attrib list: { " << attribListString.str()
205 << " }\n\n"
206 << TestLog::EndMessage;
207 }
208
209 class RobustnessTestCase : public TestCase
210 {
211 public:
212 class Params
213 {
214 public:
Params(void)215 Params(void)
216 {
217 }
218
219 Params(const string &name, const string &description, const RobustAccessType &robustAccessType,
220 const ContextResetType &contextResetType, const FixedFunctionType &fixedFunctionType);
221
222 Params(const string &name, const string &description, const RobustAccessType &robustAccessType,
223 const ContextResetType &contextResetType, const ShaderType &shaderType, const ResourceType &resourceType,
224 const ReadWriteType &readWriteType);
225
getName(void) const226 const string &getName(void) const
227 {
228 return m_name;
229 }
getDescription(void) const230 const string &getDescription(void) const
231 {
232 return m_description;
233 }
getContextResetType(void) const234 const ContextResetType &getContextResetType(void) const
235 {
236 return m_contextResetType;
237 }
getShaderType(void) const238 const ShaderType &getShaderType(void) const
239 {
240 return m_shaderType;
241 }
getResourceType(void) const242 const ResourceType &getResourceType(void) const
243 {
244 return m_resourceType;
245 }
getReadWriteType(void) const246 const ReadWriteType &getReadWriteType(void) const
247 {
248 return m_readWriteType;
249 }
getFixedFunctionType(void) const250 const FixedFunctionType &getFixedFunctionType(void) const
251 {
252 return m_fixedFunctionType;
253 }
getRobustAccessType(void) const254 const RobustAccessType &getRobustAccessType(void) const
255 {
256 return m_robustAccessType;
257 }
258
259 private:
260 string m_name;
261 string m_description;
262 RobustAccessType m_robustAccessType;
263 ContextResetType m_contextResetType;
264 ShaderType m_shaderType;
265 ResourceType m_resourceType;
266 ReadWriteType m_readWriteType;
267 FixedFunctionType m_fixedFunctionType;
268 };
269
270 RobustnessTestCase(EglTestContext &eglTestCtx, const char *name, const char *description);
271 RobustnessTestCase(EglTestContext &eglTestCtx, const char *name, const char *description, Params params);
272 ~RobustnessTestCase(void);
273
274 void checkRequiredEGLExtensions(const EGLint *attribList);
275
276 protected:
277 Params m_params;
278 EGLDisplay m_eglDisplay;
279 EGLConfig m_eglConfig;
280 EGLSurface m_eglSurface;
281
282 private:
283 void init(void);
284 void deinit(void);
285 void initEGLSurface(void);
286 EGLConfig getEGLConfig(void);
287
288 eglu::NativeWindow *m_window;
289 };
290
Params(const string & name,const string & description,const RobustAccessType & robustAccessType,const ContextResetType & contextResetType,const FixedFunctionType & fixedFunctionType)291 RobustnessTestCase::Params::Params(const string &name, const string &description,
292 const RobustAccessType &robustAccessType, const ContextResetType &contextResetType,
293 const FixedFunctionType &fixedFunctionType)
294 : m_name(name)
295 , m_description(description)
296 , m_robustAccessType(robustAccessType)
297 , m_contextResetType(contextResetType)
298 , m_fixedFunctionType(fixedFunctionType)
299 {
300 }
301
Params(const string & name,const string & description,const RobustAccessType & robustAccessType,const ContextResetType & contextResetType,const ShaderType & shaderType,const ResourceType & resourceType,const ReadWriteType & readWriteType)302 RobustnessTestCase::Params::Params(const string &name, const string &description,
303 const RobustAccessType &robustAccessType, const ContextResetType &contextResetType,
304 const ShaderType &shaderType, const ResourceType &resourceType,
305 const ReadWriteType &readWriteType)
306 : m_name(name)
307 , m_description(description)
308 , m_robustAccessType(robustAccessType)
309 , m_contextResetType(contextResetType)
310 , m_shaderType(shaderType)
311 , m_resourceType(resourceType)
312 , m_readWriteType(readWriteType)
313 {
314 }
315
RobustnessTestCase(EglTestContext & eglTestCtx,const char * name,const char * description)316 RobustnessTestCase::RobustnessTestCase(EglTestContext &eglTestCtx, const char *name, const char *description)
317 : TestCase(eglTestCtx, name, description)
318 , m_eglDisplay(EGL_NO_DISPLAY)
319 , m_eglConfig(0)
320 , m_eglSurface(EGL_NO_SURFACE)
321 , m_window(DE_NULL)
322 {
323 }
324
RobustnessTestCase(EglTestContext & eglTestCtx,const char * name,const char * description,Params params)325 RobustnessTestCase::RobustnessTestCase(EglTestContext &eglTestCtx, const char *name, const char *description,
326 Params params)
327 : TestCase(eglTestCtx, name, description)
328 , m_params(params)
329 , m_eglDisplay(EGL_NO_DISPLAY)
330 , m_eglConfig(0)
331 , m_eglSurface(EGL_NO_SURFACE)
332 , m_window(DE_NULL)
333 {
334 }
335
~RobustnessTestCase(void)336 RobustnessTestCase::~RobustnessTestCase(void)
337 {
338 deinit();
339 }
340
init(void)341 void RobustnessTestCase::init(void)
342 {
343 m_eglDisplay = eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
344 m_eglConfig = getEGLConfig();
345
346 initEGLSurface();
347 }
348
deinit(void)349 void RobustnessTestCase::deinit(void)
350 {
351 const Library &egl = m_eglTestCtx.getLibrary();
352
353 if (m_eglSurface != EGL_NO_SURFACE)
354 {
355 egl.destroySurface(m_eglDisplay, m_eglSurface);
356 m_eglSurface = EGL_NO_SURFACE;
357 }
358 if (m_eglDisplay != EGL_NO_DISPLAY)
359 {
360 egl.terminate(m_eglDisplay);
361 m_eglDisplay = EGL_NO_DISPLAY;
362 }
363
364 delete m_window;
365 m_window = DE_NULL;
366 }
367
getEGLConfig(void)368 EGLConfig RobustnessTestCase::getEGLConfig(void)
369 {
370 eglu::FilterList filters;
371 filters << isWindow << getRenderableFilter(EGL_OPENGL_ES3_BIT);
372 return eglu::chooseSingleConfig(m_eglTestCtx.getLibrary(), m_eglDisplay, filters);
373 }
374
initEGLSurface(void)375 void RobustnessTestCase::initEGLSurface(void)
376 {
377 EGLU_CHECK_CALL(m_eglTestCtx.getLibrary(), bindAPI(EGL_OPENGL_ES_API));
378
379 const eglu::NativeWindowFactory &factory =
380 eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
381
382 const eglu::WindowParams windowParams =
383 eglu::WindowParams(256, 256, eglu::parseWindowVisibility(m_testCtx.getCommandLine()));
384 m_window = factory.createWindow(&m_eglTestCtx.getNativeDisplay(), m_eglDisplay, m_eglConfig, DE_NULL, windowParams);
385 m_eglSurface =
386 eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *m_window, m_eglDisplay, m_eglConfig, DE_NULL);
387 }
388
paramsToApiType(const RobustnessTestCase::Params & params)389 glu::ApiType paramsToApiType(const RobustnessTestCase::Params ¶ms)
390 {
391 EGLint minorVersion = 0;
392 if (params.getShaderType() == SHADERTYPE_COMPUTE || params.getResourceType() == RESOURCETYPE_SSBO ||
393 params.getContextResetType() == CONTEXTRESETTYPE_SHADER_OOB)
394 {
395 minorVersion = 1;
396 }
397
398 return glu::ApiType::es(3, minorVersion);
399 }
400
checkRequiredEGLExtensions(const EGLint * attribList)401 void RobustnessTestCase::checkRequiredEGLExtensions(const EGLint *attribList)
402 {
403 set<string> requiredExtensions;
404 vector<string> extensions = eglu::getDisplayExtensions(m_eglTestCtx.getLibrary(), m_eglDisplay);
405
406 {
407 const EGLint *iter = attribList;
408
409 while ((*iter) != EGL_NONE)
410 {
411 switch (*iter)
412 {
413 case EGL_CONTEXT_MAJOR_VERSION_KHR:
414 iter++;
415 iter++;
416 break;
417
418 case EGL_CONTEXT_MINOR_VERSION_KHR:
419 iter++;
420 requiredExtensions.insert("EGL_KHR_create_context");
421 iter++;
422 break;
423
424 case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
425 case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
426 iter++;
427 requiredExtensions.insert("EGL_EXT_create_context_robustness");
428 iter++;
429 break;
430
431 default:
432 DE_ASSERT(false);
433 }
434 }
435 }
436
437 for (std::set<string>::const_iterator reqExt = requiredExtensions.begin(); reqExt != requiredExtensions.end();
438 ++reqExt)
439 {
440 if (!de::contains(extensions.begin(), extensions.end(), *reqExt))
441 {
442 const char *const extension = reqExt->c_str();
443 requireEGLExtension(m_eglTestCtx.getLibrary(), m_eglDisplay, extension);
444 }
445 }
446 }
447
checkRequiredGLSupport(const glw::Functions & gl,glu::ApiType requiredApi)448 void checkRequiredGLSupport(const glw::Functions &gl, glu::ApiType requiredApi)
449 {
450 if (!glu::hasExtension(gl, requiredApi, "GL_KHR_robustness") &&
451 !glu::hasExtension(gl, requiredApi, "GL_EXT_robustness"))
452 {
453 TCU_THROW(NotSupportedError, (string("GL_KHR_robustness and GL_EXT_robustness") + " not supported").c_str());
454 }
455 else
456 {
457 int realMinorVersion = 0;
458 gl.getIntegerv(GL_MINOR_VERSION, &realMinorVersion);
459 GLU_EXPECT_NO_ERROR(gl.getError(), "Get minor version failed");
460
461 if (realMinorVersion < requiredApi.getMinorVersion())
462 TCU_THROW(NotSupportedError, "Test case requires GLES 3.1");
463 }
464 }
465
checkGLSupportForParams(const glw::Functions & gl,const RobustnessTestCase::Params & params)466 void checkGLSupportForParams(const glw::Functions &gl, const RobustnessTestCase::Params ¶ms)
467 {
468 int minorVersion = 0;
469 if (params.getShaderType() == SHADERTYPE_COMPUTE || params.getResourceType() == RESOURCETYPE_SSBO ||
470 params.getContextResetType() == CONTEXTRESETTYPE_SHADER_OOB)
471 {
472 minorVersion = 1;
473 }
474 checkRequiredGLSupport(gl, glu::ApiType::es(3, minorVersion));
475 }
476
477 class RenderingContext
478 {
479 public:
480 RenderingContext(const EglTestContext &eglTestCtx, const EGLint *attribList, const EGLConfig &config,
481 const EGLDisplay &display, const EGLContext &sharedContext);
482 ~RenderingContext(void);
483
484 void initGLFunctions(glw::Functions *gl, const glu::ApiType apiType);
485 void makeCurrent(const EGLSurface &surface);
486 EGLContext getContext(void);
487
488 private:
489 const EglTestContext &m_eglTestCtx;
490 const EGLint *m_attribList;
491 const EGLConfig &m_config;
492 const EGLDisplay &m_display;
493 const Library &m_egl;
494
495 EGLContext m_context;
496
497 void createContext(const EGLConfig &sharedConfig);
498 void destroyContext(void);
499
500 RenderingContext(const RenderingContext &);
501 RenderingContext &operator=(const RenderingContext &);
502 };
503
RenderingContext(const EglTestContext & eglTestCtx,const EGLint * attribList,const EGLConfig & config,const EGLDisplay & display,const EGLContext & sharedContext)504 RenderingContext::RenderingContext(const EglTestContext &eglTestCtx, const EGLint *attribList, const EGLConfig &config,
505 const EGLDisplay &display, const EGLContext &sharedContext)
506 : m_eglTestCtx(eglTestCtx)
507 , m_attribList(attribList)
508 , m_config(config)
509 , m_display(display)
510 , m_egl(eglTestCtx.getLibrary())
511 , m_context(EGL_NO_CONTEXT)
512 {
513 logAttribList(eglTestCtx, m_attribList);
514 createContext(sharedContext);
515 }
516
~RenderingContext(void)517 RenderingContext::~RenderingContext(void)
518 {
519 destroyContext();
520 }
521
createContext(const EGLConfig & sharedContext)522 void RenderingContext::createContext(const EGLConfig &sharedContext)
523 {
524 m_context = m_egl.createContext(m_display, m_config, sharedContext, m_attribList);
525 EGLU_CHECK_MSG(m_egl, "eglCreateContext()");
526 }
527
destroyContext(void)528 void RenderingContext::destroyContext(void)
529 {
530 EGLU_CHECK_CALL(m_eglTestCtx.getLibrary(), makeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
531
532 if (m_context != EGL_NO_CONTEXT)
533 m_egl.destroyContext(m_display, m_context);
534 }
535
makeCurrent(const EGLSurface & surface)536 void RenderingContext::makeCurrent(const EGLSurface &surface)
537 {
538 EGLU_CHECK_CALL(m_egl, makeCurrent(m_display, surface, surface, m_context));
539 }
540
initGLFunctions(glw::Functions * gl,const glu::ApiType apiType)541 void RenderingContext::initGLFunctions(glw::Functions *gl, const glu::ApiType apiType)
542 {
543 // \todo [2017-03-23 pyry] Current version has 2 somewhat ugly hacks:
544 //
545 // 1) Core functions are loaded twice. We need glGetString(i) to query supported
546 // extensions to determine if we need to load EXT or KHR-suffixed robustness
547 // functions. This could be fixed by exposing glw::FunctionLoader in EglTestContext
548 // for example.
549 //
550 // 2) We assume that calling code will check for KHR_robustness or EXT_robustness
551 // support after calling initGLFunctions(). We could move the check here.
552
553 m_eglTestCtx.initGLFunctions(gl, apiType);
554
555 {
556 const char *const robustnessExt =
557 glu::hasExtension(*gl, apiType, "GL_KHR_robustness") ? "GL_KHR_robustness" : "GL_EXT_robustness";
558 const char *const extensions[] = {robustnessExt};
559
560 m_eglTestCtx.initGLFunctions(gl, apiType, DE_LENGTH_OF_ARRAY(extensions), &extensions[0]);
561 }
562 }
563
getContext(void)564 EGLContext RenderingContext::getContext(void)
565 {
566 return m_context;
567 }
568
569 class ContextReset
570 {
571 public:
572 ContextReset(glw::Functions &gl, tcu::TestLog &log, FixedFunctionType fixedFunctionType);
573 ContextReset(glw::Functions &gl, tcu::TestLog &log, ShaderType shaderType, ResourceType resourceType,
574 ReadWriteType readWriteType);
575
~ContextReset(void)576 virtual ~ContextReset(void)
577 {
578 }
579
580 virtual void setup(void) = 0;
581 virtual void draw(void) = 0;
582 virtual void teardown(void) = 0;
583
584 void finish(void);
585
586 glw::GLint getError(void);
587 glw::GLint getGraphicsResetStatus(void);
588
getSyncObject(void) const589 glw::GLsync getSyncObject(void) const
590 {
591 return m_sync;
592 }
getQueryID(void) const593 glw::GLuint getQueryID(void) const
594 {
595 return m_queryID;
596 }
597
598 glw::Functions &m_gl;
599 tcu::TestLog &m_log;
600 ShaderType m_shaderType;
601 ResourceType m_resourceType;
602 ReadWriteType m_readWriteType;
603 FixedFunctionType m_fixedFunctionType;
604
605 private:
606 ContextReset(const ContextReset &);
607 ContextReset &operator=(const ContextReset &);
608
609 glw::GLuint m_queryID;
610 glw::GLsync m_sync;
611 };
612
ContextReset(glw::Functions & gl,tcu::TestLog & log,FixedFunctionType fixedFunctionType)613 ContextReset::ContextReset(glw::Functions &gl, tcu::TestLog &log, FixedFunctionType fixedFunctionType)
614 : m_gl(gl)
615 , m_log(log)
616 , m_fixedFunctionType(fixedFunctionType)
617 {
618 }
619
ContextReset(glw::Functions & gl,tcu::TestLog & log,ShaderType shaderType,ResourceType resourceType,ReadWriteType readWriteType)620 ContextReset::ContextReset(glw::Functions &gl, tcu::TestLog &log, ShaderType shaderType, ResourceType resourceType,
621 ReadWriteType readWriteType)
622 : m_gl(gl)
623 , m_log(log)
624 , m_shaderType(shaderType)
625 , m_resourceType(resourceType)
626 , m_readWriteType(readWriteType)
627 {
628 }
629
finish(void)630 void ContextReset::finish(void)
631 {
632 GLU_CHECK_GLW_CALL(m_gl, finish());
633 }
634
getError(void)635 glw::GLint ContextReset::getError(void)
636 {
637 glw::GLint error;
638 error = m_gl.getError();
639
640 return error;
641 }
642
getGraphicsResetStatus(void)643 glw::GLint ContextReset::getGraphicsResetStatus(void)
644 {
645 glw::GLint resetStatus;
646 resetStatus = m_gl.getGraphicsResetStatus();
647
648 return resetStatus;
649 }
650
651 class FixedFunctionOOB : public ContextReset
652 {
653 public:
654 FixedFunctionOOB(glw::Functions &gl, tcu::TestLog &log, FixedFunctionType fixedFunctionType);
655 ~FixedFunctionOOB(void);
656
657 struct TestConfig
658 {
659 int textureWidth;
660 int textureHeight;
661 };
662
663 virtual void setup(void);
664 virtual void draw(void);
665 virtual void teardown(void);
666
667 private:
668 glu::ProgramSources genSources(void);
669 glw::GLuint m_coordinatesBuffer;
670 glw::GLint m_coordLocation;
671 };
672
FixedFunctionOOB(glw::Functions & gl,tcu::TestLog & log,FixedFunctionType fixedFunctionType)673 FixedFunctionOOB::FixedFunctionOOB(glw::Functions &gl, tcu::TestLog &log, FixedFunctionType fixedFunctionType)
674 : ContextReset(gl, log, fixedFunctionType)
675 , m_coordinatesBuffer(0)
676 , m_coordLocation(0)
677 {
678 }
679
~FixedFunctionOOB(void)680 FixedFunctionOOB::~FixedFunctionOOB(void)
681 {
682 try
683 {
684 // Reset GL_CONTEXT_LOST error before destroying resources
685 m_gl.getGraphicsResetStatus();
686 teardown();
687 }
688 catch (...)
689 {
690 // Ignore GL errors from teardown()
691 }
692 }
693
genSources(void)694 glu::ProgramSources FixedFunctionOOB::genSources(void)
695 {
696 const char *const vert = "#version 300 es\n"
697 "in highp vec4 a_position;\n"
698 "void main (void)\n"
699 "{\n"
700 " gl_Position = a_position;\n"
701 "}\n";
702
703 const char *const frag = "#version 300 es\n"
704 "layout(location = 0) out highp vec4 fragColor;\n"
705 "void main (void)\n"
706 "{\n"
707 " fragColor = vec4(1.0f);\n"
708 "}\n";
709
710 return glu::ProgramSources() << glu::VertexSource(vert) << glu::FragmentSource(frag);
711 }
712
setup(void)713 void FixedFunctionOOB::setup(void)
714 {
715 glu::ShaderProgram program(m_gl, genSources());
716
717 m_log << program;
718
719 if (!program.isOk())
720 TCU_FAIL("Failed to compile shader program");
721
722 GLU_CHECK_GLW_CALL(m_gl, useProgram(program.getProgram()));
723
724 const glw::GLfloat coords[] = {-1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f};
725
726 m_coordLocation = m_gl.getAttribLocation(program.getProgram(), "a_position");
727 GLU_CHECK_GLW_MSG(m_gl, "glGetAttribLocation()");
728 TCU_CHECK(m_coordLocation != (glw::GLint)-1);
729
730 // Load the vertex data
731 m_coordinatesBuffer = 0;
732 GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_coordinatesBuffer));
733 GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_ARRAY_BUFFER, m_coordinatesBuffer));
734 GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW));
735 GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(m_coordLocation));
736 GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(m_coordLocation, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL));
737 }
738
draw(void)739 void FixedFunctionOOB::draw(void)
740 {
741 const glw::GLint bad_indices[] = {0, 10, 100, 1000, 10000, 100000};
742
743 if (m_fixedFunctionType == FIXEDFUNCTIONTYPE_INDICES)
744 m_gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, bad_indices);
745 else if (m_fixedFunctionType == FIXEDFUNCTIONTYPE_VERTICES)
746 m_gl.drawArrays(GL_TRIANGLES, 0, 1000);
747 else
748 DE_FATAL("Unknown fixed function type");
749 }
750
teardown(void)751 void FixedFunctionOOB::teardown(void)
752 {
753 if (m_coordLocation)
754 {
755 GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(m_coordLocation));
756 m_coordLocation = 0;
757 }
758
759 if (m_coordinatesBuffer)
760 {
761 GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_coordinatesBuffer));
762 m_coordinatesBuffer = 0;
763 }
764
765 GLU_CHECK_GLW_CALL(m_gl, useProgram(0));
766 }
767
768 class ShadersOOB : public ContextReset
769 {
770 public:
771 ShadersOOB(glw::Functions &gl, tcu::TestLog &log, ShaderType shaderType, ResourceType resourceType,
772 ReadWriteType readWriteType);
773 ~ShadersOOB(void);
774
775 virtual void setup(void);
776 virtual void draw(void);
777 virtual void teardown(void);
778
779 private:
780 static const int s_numBindings = 3;
781
782 glw::GLuint m_coordinatesBuffer;
783 glw::GLint m_coordLocation;
784
785 bool m_isUBO;
786 bool m_isRead;
787 bool m_isLocalArray;
788 std::vector<glw::GLuint> m_buffers;
789
790 std::string genVertexShader(const std::string &shaderDecl, const std::string &shaderBody);
791 std::string genFragmentShader(const std::string &shaderDecl, const std::string &shaderBody);
792 std::string genComputeShader(const std::string &shaderDecl, const std::string &shaderBody);
793
794 glu::ProgramSources genNonComputeSource(void);
795 glu::ProgramSources genComputeSource(void);
796 glu::ProgramSources genSources(void);
797 };
798
ShadersOOB(glw::Functions & gl,tcu::TestLog & log,ShaderType shaderType,ResourceType resourceType,ReadWriteType readWriteType)799 ShadersOOB::ShadersOOB(glw::Functions &gl, tcu::TestLog &log, ShaderType shaderType, ResourceType resourceType,
800 ReadWriteType readWriteType)
801 : ContextReset(gl, log, shaderType, resourceType, readWriteType)
802 , m_coordinatesBuffer(0)
803 , m_coordLocation(0)
804 , m_buffers(s_numBindings, 0)
805 {
806 m_isUBO = (m_resourceType == RESOURCETYPE_UBO);
807 m_isLocalArray = (m_resourceType == RESOURCETYPE_LOCAL_ARRAY);
808 m_isRead = (m_readWriteType == READWRITETYPE_READ);
809 }
810
~ShadersOOB(void)811 ShadersOOB::~ShadersOOB(void)
812 {
813 try
814 {
815 // Reset GL_CONTEXT_LOST error before destroying resources
816 m_gl.getGraphicsResetStatus();
817 teardown();
818 }
819 catch (...)
820 {
821 // Ignore GL errors from teardown()
822 }
823 }
824
genVertexShader(const std::string & shaderDecl,const std::string & shaderBody)825 std::string ShadersOOB::genVertexShader(const std::string &shaderDecl, const std::string &shaderBody)
826 {
827 static const char *const s_simpleVertexShaderSource = "#version 310 es\n"
828 "in highp vec4 a_position;\n"
829 "void main (void)\n"
830 "{\n"
831 " gl_Position = a_position;\n"
832 "}\n";
833
834 switch (m_shaderType)
835 {
836 case SHADERTYPE_VERT:
837 case SHADERTYPE_VERT_AND_FRAG:
838 {
839 std::ostringstream vertexShaderSource;
840 vertexShaderSource << "#version 310 es\n"
841 << "in highp vec4 a_position;\n"
842 << "out highp vec4 v_color;\n"
843 << shaderDecl << "\n"
844 << "void main (void)\n"
845 << "{\n"
846 << " highp vec4 color = vec4(0.0f);\n"
847 << shaderBody << "\n"
848 << " v_color = color;\n"
849 << " gl_Position = a_position;\n"
850 << "}\n";
851
852 return vertexShaderSource.str();
853 }
854
855 case SHADERTYPE_FRAG:
856 return s_simpleVertexShaderSource;
857
858 default:
859 DE_FATAL("Unknown shader type");
860 return "";
861 }
862 }
863
genFragmentShader(const std::string & shaderDecl,const std::string & shaderBody)864 std::string ShadersOOB::genFragmentShader(const std::string &shaderDecl, const std::string &shaderBody)
865 {
866 static const char *const s_simpleFragmentShaderSource = "#version 310 es\n"
867 "in highp vec4 v_color;\n"
868 "layout(location = 0) out highp vec4 fragColor;\n"
869 "void main (void)\n"
870 "{\n"
871 " fragColor = v_color;\n"
872 "}\n";
873
874 switch (m_shaderType)
875 {
876 case SHADERTYPE_VERT:
877 return s_simpleFragmentShaderSource;
878
879 case SHADERTYPE_FRAG:
880 {
881 std::ostringstream fragmentShaderSource;
882 fragmentShaderSource << "#version 310 es\n"
883 << "layout(location = 0) out highp vec4 fragColor;\n"
884 << shaderDecl << "\n"
885 << "void main (void)\n"
886 << "{\n"
887 << " highp vec4 color = vec4(0.0f);\n"
888 << shaderBody << "\n"
889 << " fragColor = color;\n"
890 << "}\n";
891
892 return fragmentShaderSource.str();
893 }
894 case SHADERTYPE_VERT_AND_FRAG:
895 {
896 std::ostringstream fragmentShaderSource;
897 fragmentShaderSource << "#version 310 es\n"
898 << "in highp vec4 v_color;\n"
899 << "layout(location = 0) out highp vec4 fragColor;\n"
900 << shaderDecl << "\n"
901 << "void main (void)\n"
902 << "{\n"
903 << " highp vec4 color = vec4(0.0f);\n"
904 << shaderBody << "\n"
905 << " fragColor = color;\n"
906 << "}\n";
907
908 return fragmentShaderSource.str();
909 }
910
911 default:
912 DE_FATAL("Unknown shader type");
913 return "";
914 }
915 }
916
genComputeShader(const std::string & shaderDecl,const std::string & shaderBody)917 std::string ShadersOOB::genComputeShader(const std::string &shaderDecl, const std::string &shaderBody)
918 {
919 std::ostringstream computeShaderSource;
920
921 computeShaderSource << "#version 310 es\n"
922 << "layout(local_size_x = 1, local_size_y = 1) in;\n"
923 << "\n"
924 << "layout(binding = 0) buffer Output {\n"
925 << " highp vec4 values;\n"
926 << "} sb_out;\n"
927 << "\n"
928 << shaderDecl << "void main ()\n"
929 << "{\n"
930 << shaderBody << "}\n";
931
932 return computeShaderSource.str();
933 }
934
genNonComputeSource(void)935 glu::ProgramSources ShadersOOB::genNonComputeSource(void)
936 {
937 std::ostringstream shaderDecl;
938 std::ostringstream shaderBody;
939
940 shaderDecl << "uniform highp int u_index;\n";
941
942 if (m_isLocalArray)
943 {
944 const char *const readWriteStatement =
945 (m_isRead) ? " color.x = color_out[u_index];\n" : " color[u_index] = color_out[0];\n";
946
947 shaderBody << " highp float color_out[4] = float[4](0.25f, 0.5f, 0.75f, 1.0f);\n" << readWriteStatement;
948 }
949 else
950 {
951 const std::string resName = (m_isUBO) ? "ub_in" : "sb_in";
952
953 shaderDecl << "layout(std140, binding = 0) " << ((m_isUBO) ? "uniform" : "buffer") << " Block\n"
954 << "{\n"
955 << " highp float color_out[4];\n"
956 << "} " << resName << "[" << s_numBindings << "];\n";
957
958 const std::string readWriteStatement = (m_isRead) ? " color.x = " + resName + "[0].color_out[u_index];\n" :
959 " color[u_index] = " + resName + "[0].color_out[0];\n";
960
961 shaderBody << readWriteStatement;
962 }
963
964 return glu::ProgramSources() << glu::VertexSource(genVertexShader(shaderDecl.str(), shaderBody.str()))
965 << glu::FragmentSource(genFragmentShader(shaderDecl.str(), shaderBody.str()));
966 }
967
genComputeSource(void)968 glu::ProgramSources ShadersOOB::genComputeSource(void)
969 {
970 std::ostringstream shaderDecl;
971 std::ostringstream shaderBody;
972
973 shaderDecl << "uniform highp int u_index;\n";
974
975 shaderBody << " uvec3 size = gl_NumWorkGroups * gl_WorkGroupSize;\n"
976 << " uint groupNdx = size.x*gl_GlobalInvocationID.y + gl_GlobalInvocationID.x;\n";
977
978 if (m_isLocalArray)
979 {
980 const char *const readWriteStatement =
981 (m_isRead) ? " sb_out.values.x = values[u_index];\n" : " sb_out.values[u_index] = values.x;\n";
982
983 shaderBody << " highp vec4 values = vec4(1.0f, 0.0f, 3.0f, 2.0f) * float(groupNdx);\n" << readWriteStatement;
984 }
985 else
986 {
987 const std::string resName = (m_isUBO) ? "ub_in" : "sb_in";
988
989 shaderDecl << "layout(std140, binding = 1) " << ((m_isUBO) ? "uniform" : "buffer") << " Input\n"
990 << "{\n"
991 << " highp vec4 values;\n"
992 << "} " << resName << "[" << s_numBindings << "];\n";
993
994 std::string readWriteStatement =
995 (m_isRead) ? " sb_out.values.x = " + resName + "[0].values[u_index] * float(groupNdx);\n" :
996 " sb_out.values[u_index] = " + resName + "[0].values.x * float(groupNdx);\n";
997
998 shaderBody << readWriteStatement;
999 }
1000
1001 return glu::ProgramSources() << glu::ComputeSource(genComputeShader(shaderDecl.str(), shaderBody.str()));
1002 }
1003
genSources(void)1004 glu::ProgramSources ShadersOOB::genSources(void)
1005 {
1006 if (m_shaderType == SHADERTYPE_COMPUTE)
1007 return genComputeSource();
1008 else
1009 return genNonComputeSource();
1010 }
1011
setup(void)1012 void ShadersOOB::setup(void)
1013 {
1014 if (!m_isUBO && !m_isLocalArray && (m_shaderType != SHADERTYPE_COMPUTE))
1015 {
1016 // Check implementation limits for shader SSBO
1017 int shaderStorageBlockSupported = -1;
1018 const bool isVertex =
1019 (m_shaderType == SHADERTYPE_VERT || m_shaderType == SHADERTYPE_VERT_AND_FRAG) ? true : false;
1020 string shaderTypeStr =
1021 isVertex ? "GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS" : "GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS";
1022
1023 GLU_CHECK_GLW_CALL(
1024 m_gl, getIntegerv(isVertex ? GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS : GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS,
1025 &shaderStorageBlockSupported));
1026
1027 if (shaderStorageBlockSupported < (int)m_buffers.size())
1028 TCU_THROW(NotSupportedError,
1029 ("Test requires " + shaderTypeStr + " >= " + de::toString((int)m_buffers.size()) + ", got " +
1030 de::toString(shaderStorageBlockSupported))
1031 .c_str());
1032 }
1033
1034 glu::ShaderProgram program(m_gl, genSources());
1035
1036 m_log << program;
1037
1038 if (!program.isOk())
1039 TCU_FAIL("Failed to compile shader program");
1040
1041 GLU_CHECK_GLW_CALL(m_gl, useProgram(program.getProgram()));
1042
1043 const glw::GLint indexLocation = m_gl.getUniformLocation(program.getProgram(), "u_index");
1044 GLU_CHECK_GLW_MSG(m_gl, "glGetUniformLocation()");
1045 TCU_CHECK(indexLocation != (glw::GLint)-1);
1046
1047 const glw::GLint index = -1;
1048 GLU_CHECK_GLW_CALL(m_gl, uniform1i(indexLocation, index));
1049
1050 if (m_shaderType != SHADERTYPE_COMPUTE)
1051 {
1052 const glw::GLfloat coords[] = {-1.0f, -1.0f, +1.0f, -1.0f, +1.0f, +1.0f, -1.0f, +1.0f};
1053
1054 // Setup vertices position
1055 m_coordLocation = m_gl.getAttribLocation(program.getProgram(), "a_position");
1056 GLU_CHECK_GLW_MSG(m_gl, "glGetAttribLocation()");
1057 TCU_CHECK(m_coordLocation != (glw::GLint)-1);
1058
1059 // Load the vertex data
1060 m_coordinatesBuffer = 0;
1061 GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_coordinatesBuffer));
1062 GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_ARRAY_BUFFER, m_coordinatesBuffer));
1063 GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW));
1064 GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(m_coordLocation));
1065 GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(m_coordLocation, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL));
1066 }
1067
1068 // Create unused data for filling buffer objects
1069 const std::vector<tcu::Vec4> refValues(s_numBindings, tcu::Vec4(0.0f, 1.0f, 1.0f, 1.0f));
1070
1071 if (m_isLocalArray && m_shaderType == SHADERTYPE_COMPUTE)
1072 {
1073 // Setup output buffer
1074 GLU_CHECK_GLW_CALL(m_gl, genBuffers((glw::GLsizei)1u, &m_buffers[0]));
1075
1076 GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffers[0]));
1077 GLU_CHECK_GLW_CALL(m_gl,
1078 bufferData(GL_SHADER_STORAGE_BUFFER, sizeof(tcu::Vec4), &(refValues[0]), GL_STATIC_DRAW));
1079 GLU_CHECK_GLW_CALL(m_gl, bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffers[0]));
1080 }
1081 else if (!m_isLocalArray)
1082 {
1083 // Set up interface block of buffer bindings
1084 GLU_CHECK_GLW_CALL(m_gl, genBuffers((glw::GLsizei)m_buffers.size(), &m_buffers[0]));
1085
1086 for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
1087 {
1088 const glw::GLenum resType = m_isUBO && (m_shaderType != SHADERTYPE_COMPUTE || bufNdx != 0) ?
1089 GL_UNIFORM_BUFFER :
1090 GL_SHADER_STORAGE_BUFFER;
1091
1092 GLU_CHECK_GLW_CALL(m_gl, bindBuffer(resType, m_buffers[bufNdx]));
1093 GLU_CHECK_GLW_CALL(m_gl, bufferData(resType, sizeof(tcu::Vec4), &(refValues[bufNdx]), GL_STATIC_DRAW));
1094 GLU_CHECK_GLW_CALL(m_gl, bindBufferBase(resType, bufNdx, m_buffers[bufNdx]));
1095 }
1096 }
1097 }
1098
draw(void)1099 void ShadersOOB::draw(void)
1100 {
1101 if (m_shaderType == SHADERTYPE_COMPUTE)
1102 m_gl.dispatchCompute(1, 1, 1);
1103 else
1104 {
1105 const glw::GLuint indices[] = {0, 1, 2, 2, 3, 0};
1106 m_gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, indices);
1107 }
1108 }
1109
teardown(void)1110 void ShadersOOB::teardown(void)
1111 {
1112 if (m_shaderType != SHADERTYPE_COMPUTE)
1113 {
1114 if (m_coordLocation)
1115 {
1116 GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(m_coordLocation));
1117 m_coordLocation = 0;
1118 }
1119 }
1120
1121 if (m_coordinatesBuffer)
1122 {
1123 GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_coordinatesBuffer));
1124 m_coordinatesBuffer = 0;
1125 }
1126
1127 if (!m_isLocalArray)
1128 {
1129 if (!m_buffers.empty())
1130 {
1131 GLU_CHECK_GLW_CALL(m_gl, deleteBuffers((glw::GLsizei)m_buffers.size(), &m_buffers[0]));
1132 m_buffers.clear();
1133 }
1134 }
1135
1136 GLU_CHECK_GLW_CALL(m_gl, useProgram(0));
1137 }
1138
1139 class QueryRobustAccessCase : public RobustnessTestCase
1140 {
1141 public:
QueryRobustAccessCase(EglTestContext & eglTestCtx,const char * name,const char * description)1142 QueryRobustAccessCase(EglTestContext &eglTestCtx, const char *name, const char *description)
1143 : RobustnessTestCase(eglTestCtx, name, description)
1144 {
1145 }
1146
iterate(void)1147 TestCase::IterateResult iterate(void)
1148 {
1149 TestLog &log = m_testCtx.getLog();
1150
1151 log << tcu::TestLog::Message
1152 << "Check that after successfully creating a robust context the robust access query returned by "
1153 "glBooleanv() equals GL_TRUE\n\n"
1154 << tcu::TestLog::EndMessage;
1155
1156 const EGLint attribList[] = {EGL_CONTEXT_CLIENT_VERSION,
1157 3,
1158 EGL_CONTEXT_MINOR_VERSION_KHR,
1159 0,
1160 EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT,
1161 EGL_TRUE,
1162 EGL_NONE};
1163
1164 checkRequiredEGLExtensions(attribList);
1165
1166 RenderingContext context(m_eglTestCtx, attribList, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);
1167 context.makeCurrent(m_eglSurface);
1168
1169 glw::Functions gl;
1170 {
1171 const glu::ApiType apiType(3, 0, glu::PROFILE_ES);
1172 context.initGLFunctions(&gl, apiType);
1173 checkRequiredGLSupport(gl, apiType);
1174 }
1175
1176 uint8_t robustAccessGL;
1177 gl.getBooleanv(GL_CONTEXT_ROBUST_ACCESS_EXT, &robustAccessGL);
1178 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBooleanv()");
1179
1180 if (robustAccessGL != GL_TRUE)
1181 {
1182 log << TestLog::Message << "Invalid GL_CONTEXT_ROBUST_ACCESS returned by glGetBooleanv(). Got '"
1183 << robustAccessGL << "' expected GL_TRUE." << TestLog::EndMessage;
1184
1185 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1186 return STOP;
1187 }
1188
1189 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1190 return STOP;
1191 }
1192 };
1193
1194 class NoResetNotificationCase : public RobustnessTestCase
1195 {
1196 public:
NoResetNotificationCase(EglTestContext & eglTestCtx,const char * name,const char * description)1197 NoResetNotificationCase(EglTestContext &eglTestCtx, const char *name, const char *description)
1198 : RobustnessTestCase(eglTestCtx, name, description)
1199 {
1200 }
1201
iterate(void)1202 TestCase::IterateResult iterate(void)
1203 {
1204 TestLog &log = m_testCtx.getLog();
1205
1206 log << tcu::TestLog::Message
1207 << "Check the reset notification strategy returned by glGetIntegerv() equals GL_NO_RESET_NOTIFICATION\n\n"
1208 << tcu::TestLog::EndMessage;
1209
1210 const EGLint attribList[] = {EGL_CONTEXT_CLIENT_VERSION,
1211 3,
1212 EGL_CONTEXT_MINOR_VERSION_KHR,
1213 0,
1214 EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT,
1215 EGL_TRUE,
1216 EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
1217 EGL_NO_RESET_NOTIFICATION,
1218 EGL_NONE};
1219
1220 checkRequiredEGLExtensions(attribList);
1221
1222 RenderingContext context(m_eglTestCtx, attribList, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);
1223 context.makeCurrent(m_eglSurface);
1224
1225 glw::Functions gl;
1226 {
1227 const glu::ApiType apiType(3, 0, glu::PROFILE_ES);
1228 context.initGLFunctions(&gl, apiType);
1229 checkRequiredGLSupport(gl, apiType);
1230 }
1231
1232 uint8_t robustAccessGL;
1233 gl.getBooleanv(GL_CONTEXT_ROBUST_ACCESS_EXT, &robustAccessGL);
1234 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBooleanv()");
1235
1236 glw::GLint reset = 0;
1237 gl.getIntegerv(GL_RESET_NOTIFICATION_STRATEGY, &reset);
1238 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv()");
1239
1240 if (reset != GL_NO_RESET_NOTIFICATION)
1241 {
1242 log << tcu::TestLog::Message << "Test failed! glGetIntegerv() returned wrong value. ["
1243 << glu::getErrorStr(reset) << ", expected " << glu::getErrorStr(GL_NO_RESET_NOTIFICATION) << "]"
1244 << tcu::TestLog::EndMessage;
1245
1246 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1247 return STOP;
1248 }
1249
1250 GLU_CHECK_GLW_CALL(gl, getGraphicsResetStatus());
1251
1252 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1253 return STOP;
1254 }
1255 };
1256
1257 class LoseContextOnResetCase : public RobustnessTestCase
1258 {
1259 public:
LoseContextOnResetCase(EglTestContext & eglTestCtx,const char * name,const char * description)1260 LoseContextOnResetCase(EglTestContext &eglTestCtx, const char *name, const char *description)
1261 : RobustnessTestCase(eglTestCtx, name, description)
1262 {
1263 }
1264
iterate(void)1265 TestCase::IterateResult iterate(void)
1266 {
1267 TestLog &log = m_testCtx.getLog();
1268
1269 log << tcu::TestLog::Message
1270 << "Check the reset notification strategy returned by glGetIntegerv() equals GL_LOSE_CONTEXT_ON_RESET\n\n"
1271 << tcu::TestLog::EndMessage;
1272
1273 const EGLint attribList[] = {EGL_CONTEXT_CLIENT_VERSION,
1274 3,
1275 EGL_CONTEXT_MINOR_VERSION_KHR,
1276 0,
1277 EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT,
1278 EGL_TRUE,
1279 EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
1280 EGL_LOSE_CONTEXT_ON_RESET,
1281 EGL_NONE};
1282
1283 checkRequiredEGLExtensions(attribList);
1284
1285 RenderingContext context(m_eglTestCtx, attribList, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);
1286 context.makeCurrent(m_eglSurface);
1287
1288 glw::Functions gl;
1289 {
1290 const glu::ApiType apiType(3, 0, glu::PROFILE_ES);
1291 context.initGLFunctions(&gl, apiType);
1292 checkRequiredGLSupport(gl, apiType);
1293 }
1294 glw::GLint reset = 0;
1295 gl.getIntegerv(GL_RESET_NOTIFICATION_STRATEGY, &reset);
1296 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv()");
1297
1298 if (reset != GL_LOSE_CONTEXT_ON_RESET)
1299 {
1300 log << tcu::TestLog::Message << "Test failed! glGetIntegerv() returned wrong value. [" << reset
1301 << ", expected " << glu::getErrorStr(GL_LOSE_CONTEXT_ON_RESET) << "]" << tcu::TestLog::EndMessage;
1302
1303 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1304 return STOP;
1305 }
1306
1307 log << tcu::TestLog::Message << "Check the graphics reset status returned by glGetGraphicsResetStatus() "
1308 << "equals GL_NO_ERROR\n"
1309 << tcu::TestLog::EndMessage;
1310
1311 GLU_CHECK_GLW_CALL(gl, getGraphicsResetStatus());
1312
1313 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1314 return STOP;
1315 }
1316 };
1317
contextResetFactory(const RobustnessTestCase::Params params,glw::Functions & gl,tcu::TestLog & log)1318 de::SharedPtr<ContextReset> contextResetFactory(const RobustnessTestCase::Params params, glw::Functions &gl,
1319 tcu::TestLog &log)
1320 {
1321 if (params.getContextResetType() == CONTEXTRESETTYPE_FIXED_FUNC_OOB)
1322 return de::SharedPtr<ContextReset>(new FixedFunctionOOB(gl, log, params.getFixedFunctionType()));
1323
1324 if (params.getContextResetType() == CONTEXTRESETTYPE_SHADER_OOB)
1325 return de::SharedPtr<ContextReset>(
1326 new ShadersOOB(gl, log, params.getShaderType(), params.getResourceType(), params.getReadWriteType()));
1327 else
1328 {
1329 DE_FATAL("Unknown context reset type");
1330 return de::SharedPtr<ContextReset>(DE_NULL);
1331 }
1332 }
1333
1334 class ContextResetCase : public RobustnessTestCase
1335 {
1336
1337 public:
1338 ContextResetCase(EglTestContext &eglTestCtx, const char *name, const char *description, Params params);
~ContextResetCase(void)1339 virtual ~ContextResetCase(void)
1340 {
1341 }
1342
1343 virtual void provokeReset(de::SharedPtr<ContextReset> &contextReset) = 0;
1344 virtual void waitForReset(de::SharedPtr<ContextReset> &contextReset) = 0;
1345 virtual void passAndLog(de::SharedPtr<ContextReset> &contextReset) = 0;
1346
1347 TestCase::IterateResult iterate(void);
1348 void execute(glw::Functions &gl);
1349
1350 private:
1351 ContextResetCase(const ContextResetCase &);
1352 ContextResetCase &operator=(const ContextResetCase &);
1353 };
1354
ContextResetCase(EglTestContext & eglTestCtx,const char * name,const char * description,Params params)1355 ContextResetCase::ContextResetCase(EglTestContext &eglTestCtx, const char *name, const char *description, Params params)
1356 : RobustnessTestCase(eglTestCtx, name, description, params)
1357 {
1358 }
1359
iterate(void)1360 TestCase::IterateResult ContextResetCase::iterate(void)
1361 {
1362 glw::Functions gl;
1363
1364 const EGLint attribList[] = {EGL_CONTEXT_CLIENT_VERSION,
1365 3,
1366 EGL_CONTEXT_MINOR_VERSION_KHR,
1367 0,
1368 EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT,
1369 (m_params.getRobustAccessType() == ROBUSTACCESS_TRUE) ? EGL_TRUE : EGL_FALSE,
1370 EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
1371 EGL_LOSE_CONTEXT_ON_RESET,
1372 EGL_NONE};
1373
1374 checkRequiredEGLExtensions(attribList);
1375
1376 RenderingContext context(m_eglTestCtx, attribList, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);
1377 context.makeCurrent(m_eglSurface);
1378
1379 {
1380 const glu::ApiType apiType = paramsToApiType(m_params);
1381 context.initGLFunctions(&gl, apiType);
1382 checkGLSupportForParams(gl, m_params);
1383 }
1384
1385 execute(gl);
1386
1387 return STOP;
1388 }
1389
execute(glw::Functions & gl)1390 void ContextResetCase::execute(glw::Functions &gl)
1391 {
1392 de::SharedPtr<ContextReset> contextReset = contextResetFactory(m_params, gl, m_testCtx.getLog());
1393 glw::GLboolean isContextRobust = GL_FALSE;
1394
1395 GLU_CHECK_GLW_CALL(gl, getBooleanv(GL_CONTEXT_ROBUST_ACCESS_EXT, &isContextRobust));
1396 provokeReset(contextReset);
1397
1398 if (m_params.getContextResetType() == CONTEXTRESETTYPE_SHADER_OOB ||
1399 m_params.getContextResetType() == CONTEXTRESETTYPE_FIXED_FUNC_OOB)
1400 {
1401 try
1402 {
1403 waitForReset(contextReset);
1404 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Context was NOT lost. Test skipped");
1405 }
1406 catch (const glu::Error &error)
1407 {
1408 if (error.getError() == GL_CONTEXT_LOST)
1409 {
1410 if (isContextRobust)
1411 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL,
1412 "No context reset should of occurred GL_CONTEXT_ROBUST_ACCESS == TRUE");
1413 else
1414 passAndLog(contextReset);
1415 }
1416 else if (isContextRobust)
1417 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unknown error.");
1418 else
1419 {
1420 m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING,
1421 "Warning: glGetError() returned wrong value. Expected GL_CONTEXT_LOST");
1422
1423 m_testCtx.getLog() << tcu::TestLog::Message << "Warning: glGetError() returned wrong value ["
1424 << error.what() << ", expected " << glu::getErrorStr(GL_CONTEXT_LOST) << "]"
1425 << tcu::TestLog::EndMessage;
1426 }
1427 }
1428 }
1429 else
1430 DE_FATAL("Unknown context reset type");
1431 }
1432
1433 class BasicResetCase : public ContextResetCase
1434 {
1435 public:
BasicResetCase(EglTestContext & eglTestCtx,const char * name,const char * description,Params params)1436 BasicResetCase(EglTestContext &eglTestCtx, const char *name, const char *description, Params params)
1437 : ContextResetCase(eglTestCtx, name, description, params)
1438 {
1439 }
1440
provokeReset(de::SharedPtr<ContextReset> & contextReset)1441 virtual void provokeReset(de::SharedPtr<ContextReset> &contextReset)
1442 {
1443 m_testCtx.getLog() << tcu::TestLog::Message
1444 << "Check the graphics reset status returned by glGetGraphicsResetStatus() equals "
1445 << "GL_GUILTY_CONTEXT_RESET after a context reset\n\n"
1446 << tcu::TestLog::EndMessage;
1447
1448 contextReset->setup();
1449 contextReset->draw();
1450 }
1451
waitForReset(de::SharedPtr<ContextReset> & contextReset)1452 virtual void waitForReset(de::SharedPtr<ContextReset> &contextReset)
1453 {
1454 contextReset->teardown();
1455 contextReset->finish();
1456 }
1457
passAndLog(de::SharedPtr<ContextReset> & contextReset)1458 virtual void passAndLog(de::SharedPtr<ContextReset> &contextReset)
1459 {
1460 const glw::GLint status = contextReset->getGraphicsResetStatus();
1461
1462 if (status == GL_NO_ERROR)
1463 {
1464 m_testCtx.getLog() << tcu::TestLog::Message
1465 << "Test failed! glGetGraphicsResetStatus() returned wrong value ["
1466 << glu::getGraphicsResetStatusStr(status) << ", expected "
1467 << glu::getGraphicsResetStatusStr(GL_GUILTY_CONTEXT_RESET) << "]"
1468 << tcu::TestLog::EndMessage;
1469
1470 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1471 }
1472 else
1473 {
1474 if (contextReset->getError() != GL_NO_ERROR)
1475 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL,
1476 "Error flag not reset after calling getGraphicsResetStatus()");
1477 else
1478 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1479 }
1480 }
1481 };
1482
1483 class InvalidShareContextCase : public RobustnessTestCase
1484 {
1485 public:
InvalidShareContextCase(EglTestContext & eglTestCtx,const char * name,const char * description)1486 InvalidShareContextCase(EglTestContext &eglTestCtx, const char *name, const char *description)
1487 : RobustnessTestCase(eglTestCtx, name, description)
1488 {
1489 }
1490
iterate(void)1491 TestCase::IterateResult iterate(void)
1492 {
1493 TestLog &log = m_testCtx.getLog();
1494 const Library &egl = m_eglTestCtx.getLibrary();
1495 bool isOk = true;
1496
1497 log << tcu::TestLog::Message
1498 << "EGL_BAD_MATCH is generated if reset notification strategies do not match when creating shared "
1499 "contexts\n\n"
1500 << tcu::TestLog::EndMessage;
1501
1502 const EGLint attribListA[] = {EGL_CONTEXT_CLIENT_VERSION,
1503 3,
1504 EGL_CONTEXT_MINOR_VERSION_KHR,
1505 0,
1506 EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT,
1507 EGL_TRUE,
1508 EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
1509 EGL_NO_RESET_NOTIFICATION,
1510 EGL_NONE};
1511
1512 const EGLint attribListB[] = {EGL_CONTEXT_CLIENT_VERSION,
1513 3,
1514 EGL_CONTEXT_MINOR_VERSION_KHR,
1515 0,
1516 EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT,
1517 EGL_TRUE,
1518 EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
1519 EGL_LOSE_CONTEXT_ON_RESET,
1520 EGL_NONE};
1521
1522 checkRequiredEGLExtensions(attribListA);
1523
1524 log << tcu::TestLog::Message << "Create context A (share_context = EGL_NO_CONTEXT)" << tcu::TestLog::EndMessage;
1525 RenderingContext contextA(m_eglTestCtx, attribListA, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);
1526
1527 log << tcu::TestLog::Message << "Create context B (share_context = context A)" << tcu::TestLog::EndMessage;
1528 logAttribList(m_eglTestCtx, attribListB);
1529
1530 EGLContext contextB = egl.createContext(m_eglDisplay, m_eglConfig, contextA.getContext(), attribListB);
1531
1532 const EGLenum error = egl.getError();
1533 if (error != EGL_BAD_MATCH)
1534 {
1535 log << TestLog::Message << "Test failed! eglCreateContext() returned with error ["
1536 << eglu::getErrorStr(error) << ", expected " << eglu::getErrorStr(EGL_BAD_MATCH) << "]"
1537 << TestLog::EndMessage;
1538
1539 isOk = false;
1540 }
1541
1542 if (contextB != EGL_NO_CONTEXT)
1543 egl.destroyContext(m_eglDisplay, contextB);
1544
1545 if (isOk)
1546 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1547 else
1548 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1549
1550 return STOP;
1551 }
1552 };
1553
1554 class InvalidNotificationEnumCase : public RobustnessTestCase
1555 {
1556 public:
InvalidNotificationEnumCase(EglTestContext & eglTestCtx,const char * name,const char * description)1557 InvalidNotificationEnumCase(EglTestContext &eglTestCtx, const char *name, const char *description)
1558 : RobustnessTestCase(eglTestCtx, name, description)
1559 {
1560 }
1561
iterate(void)1562 TestCase::IterateResult iterate(void)
1563 {
1564 TestLog &log = m_testCtx.getLog();
1565 const Library &egl = m_eglTestCtx.getLibrary();
1566 bool isOk = true;
1567
1568 log << tcu::TestLog::Message
1569 << "EGL_BAD_ATTRIBUTE is generated if EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR is used with EGL "
1570 "versions <= 1.4\n\n"
1571 << tcu::TestLog::EndMessage;
1572
1573 const EGLint attribList[] = {EGL_CONTEXT_CLIENT_VERSION,
1574 3,
1575 EGL_CONTEXT_MINOR_VERSION_KHR,
1576 1,
1577 EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
1578 EGL_NO_RESET_NOTIFICATION,
1579 EGL_NONE};
1580
1581 if (eglu::getVersion(egl, m_eglDisplay) >= eglu::Version(1, 5))
1582 {
1583 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Test requires EGL version to be under 1.5");
1584 return STOP;
1585 }
1586
1587 logAttribList(m_eglTestCtx, attribList);
1588 EGLContext context = egl.createContext(m_eglDisplay, m_eglConfig, EGL_NO_CONTEXT, attribList);
1589
1590 const EGLenum error = egl.getError();
1591 if (error != EGL_BAD_ATTRIBUTE)
1592 {
1593 log << TestLog::Message << "Test failed! eglCreateContext() returned with error ["
1594 << eglu::getErrorStr(error) << ", expected " << eglu::getErrorStr(EGL_BAD_ATTRIBUTE) << "]"
1595 << TestLog::EndMessage;
1596
1597 isOk = false;
1598 }
1599
1600 if (context != EGL_NO_CONTEXT)
1601 egl.destroyContext(m_eglDisplay, context);
1602
1603 if (isOk)
1604 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1605 else
1606 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1607
1608 return STOP;
1609 }
1610 };
1611
1612 class InvalidContextCase : public RobustnessTestCase
1613 {
1614 public:
InvalidContextCase(EglTestContext & eglTestCtx,const char * name,const char * description)1615 InvalidContextCase(EglTestContext &eglTestCtx, const char *name, const char *description)
1616 : RobustnessTestCase(eglTestCtx, name, description)
1617 {
1618 }
1619
iterate(void)1620 TestCase::IterateResult iterate(void)
1621 {
1622 const Library &egl = m_eglTestCtx.getLibrary();
1623 TestLog &log = m_testCtx.getLog();
1624 bool isOk = true;
1625
1626 log << tcu::TestLog::Message
1627 << "EGL_BAD_ATTRIBUTE is generated if EXT_create_context_robustness is NOT supported but "
1628 "EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT is specified\n\n"
1629 << tcu::TestLog::EndMessage;
1630
1631 const EGLint attribList[] = {EGL_CONTEXT_CLIENT_VERSION,
1632 3,
1633 EGL_CONTEXT_MINOR_VERSION_KHR,
1634 0,
1635 EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
1636 EGL_LOSE_CONTEXT_ON_RESET,
1637 EGL_NONE};
1638
1639 if (eglu::hasExtension(egl, m_eglDisplay, "EGL_EXT_create_context_robustness"))
1640 {
1641 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED,
1642 "Test requires EGL_EXT_create_context_robustness to be unsupported");
1643 return STOP;
1644 }
1645
1646 logAttribList(m_eglTestCtx, attribList);
1647 EGLContext context = egl.createContext(m_eglDisplay, m_eglConfig, EGL_NO_CONTEXT, attribList);
1648
1649 const EGLenum error = egl.getError();
1650 if (error != EGL_BAD_ATTRIBUTE)
1651 {
1652 log << TestLog::Message << "Test failed! eglCreateContext() returned with error ["
1653 << eglu::getErrorStr(error) << ", expected " << eglu::getErrorStr(EGL_BAD_ATTRIBUTE) << "]"
1654 << TestLog::EndMessage;
1655
1656 isOk = false;
1657 }
1658
1659 if (context != EGL_NO_CONTEXT)
1660 egl.destroyContext(m_eglDisplay, context);
1661
1662 if (isOk)
1663 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1664 else
1665 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1666
1667 return STOP;
1668 }
1669 };
1670
1671 } // namespace
1672
1673 // Note: Tests limited to openGLES 3.1 contexts only
createRobustnessTests(EglTestContext & eglTestCtx)1674 TestCaseGroup *createRobustnessTests(EglTestContext &eglTestCtx)
1675 {
1676 de::MovePtr<TestCaseGroup> group(new TestCaseGroup(eglTestCtx, "robustness", "KHR_robustness tests"));
1677
1678 tcu::TestCaseGroup *const contextCreationTestGroup =
1679 new TestCaseGroup(eglTestCtx, "create_context", "Test valid context_creation attributes");
1680 tcu::TestCaseGroup *const contextResetTestGroup =
1681 new TestCaseGroup(eglTestCtx, "reset_context", "Test context resets scenarios");
1682 tcu::TestCaseGroup *const negativeContextTestGroup =
1683 new TestCaseGroup(eglTestCtx, "negative_context", "Test invalid context creation attributes");
1684
1685 tcu::TestCaseGroup *const shadersTestGroup =
1686 new TestCaseGroup(eglTestCtx, "shaders", "Shader specific context reset tests");
1687 tcu::TestCaseGroup *const fixedFunctionTestGroup = new TestCaseGroup(
1688 eglTestCtx, "fixed_function_pipeline", "Fixed function pipeline context reset tests with robust context");
1689 tcu::TestCaseGroup *const fixedFunctionNonRobustTestGroup =
1690 new TestCaseGroup(eglTestCtx, "fixed_function_pipeline_non_robust",
1691 "Fixed function pipeline context reset tests with non-robust context");
1692
1693 tcu::TestCaseGroup *const outOfBoundsTestGroup =
1694 new TestCaseGroup(eglTestCtx, "out_of_bounds", "Out of bounds access scenarios with robust context");
1695
1696 tcu::TestCaseGroup *const outOfBoundsNonRobustTestGroup = new TestCaseGroup(
1697 eglTestCtx, "out_of_bounds_non_robust", "Out of bounds access scenarios with non-robust context");
1698
1699 const string resetScenarioDescription = "query error states and reset notifications";
1700
1701 // out-of-bounds test cases
1702 {
1703 // robust context
1704 tcu::TestCaseGroup *const uboReadArrayResetTestGroup =
1705 new TestCaseGroup(eglTestCtx, "uniform_block", "Uniform Block Accesses");
1706 tcu::TestCaseGroup *const uboWriteArrayResetTestGroup =
1707 new TestCaseGroup(eglTestCtx, "uniform_block", "Uniform Block Accesses");
1708 tcu::TestCaseGroup *const ssboWriteArrayResetTestGroup =
1709 new TestCaseGroup(eglTestCtx, "shader_storage_block", "Shader Storage Block accesses");
1710 tcu::TestCaseGroup *const ssboReadArrayResetTestGroup =
1711 new TestCaseGroup(eglTestCtx, "shader_storage_block", "Shader Storage Block accesses");
1712 tcu::TestCaseGroup *const localWriteArrayResetTestGroup =
1713 new TestCaseGroup(eglTestCtx, "local_array", "Local array accesses");
1714 tcu::TestCaseGroup *const localReadArrayResetTestGroup =
1715 new TestCaseGroup(eglTestCtx, "local_array", "Local array accesses");
1716
1717 // non-robust context (internal use only)
1718 tcu::TestCaseGroup *const uboReadArrayResetNonRobustTestGroup =
1719 new TestCaseGroup(eglTestCtx, "uniform_block", "Uniform Block Accesses");
1720 tcu::TestCaseGroup *const uboWriteArrayResetNonRobustTestGroup =
1721 new TestCaseGroup(eglTestCtx, "uniform_block", "Uniform Block Accesses");
1722 tcu::TestCaseGroup *const ssboWriteArrayResetNonRobustTestGroup =
1723 new TestCaseGroup(eglTestCtx, "shader_storage_block", "Shader Storage Block accesses");
1724 tcu::TestCaseGroup *const ssboReadArrayResetNonRobustTestGroup =
1725 new TestCaseGroup(eglTestCtx, "shader_storage_block", "Shader Storage Block accesses");
1726 tcu::TestCaseGroup *const localWriteArrayResetNonRobustTestGroup =
1727 new TestCaseGroup(eglTestCtx, "local_array", "Local array accesses");
1728 tcu::TestCaseGroup *const localReadArrayResetNonRobustTestGroup =
1729 new TestCaseGroup(eglTestCtx, "local_array", "Local array accesses");
1730
1731 static const RobustnessTestCase::Params s_outOfBoundReadCases[] = {
1732 // ubo read only
1733 RobustnessTestCase::Params("vertex", "Provoke a context reset in vertex shader and ", ROBUSTACCESS_TRUE,
1734 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT, RESOURCETYPE_UBO,
1735 READWRITETYPE_READ),
1736 RobustnessTestCase::Params("fragment", "Provoke a context reset in fragment shader and ", ROBUSTACCESS_TRUE,
1737 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG, RESOURCETYPE_UBO,
1738 READWRITETYPE_READ),
1739 RobustnessTestCase::Params(
1740 "vertex_and_fragment", "Provoke a context reset in vertex and fragment shader and ", ROBUSTACCESS_TRUE,
1741 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG, RESOURCETYPE_UBO, READWRITETYPE_READ),
1742 RobustnessTestCase::Params("compute", "Provoke a context reset in compute shader and ", ROBUSTACCESS_TRUE,
1743 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE, RESOURCETYPE_UBO,
1744 READWRITETYPE_READ),
1745
1746 // ssbo read only
1747 RobustnessTestCase::Params("vertex", "Provoke a context reset in vertex shader and ", ROBUSTACCESS_TRUE,
1748 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT, RESOURCETYPE_SSBO,
1749 READWRITETYPE_READ),
1750 RobustnessTestCase::Params("fragment", "Provoke a context reset in fragment shader and ", ROBUSTACCESS_TRUE,
1751 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG, RESOURCETYPE_SSBO,
1752 READWRITETYPE_READ),
1753 RobustnessTestCase::Params(
1754 "vertex_and_fragment", "Provoke a context reset in vertex and fragment shader and ", ROBUSTACCESS_TRUE,
1755 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG, RESOURCETYPE_SSBO, READWRITETYPE_READ),
1756 RobustnessTestCase::Params("compute", "Provoke a context reset in compute shader and ", ROBUSTACCESS_TRUE,
1757 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE, RESOURCETYPE_SSBO,
1758 READWRITETYPE_READ),
1759
1760 // local array read only
1761 RobustnessTestCase::Params("vertex", "Provoke a context reset in vertex shader and ", ROBUSTACCESS_TRUE,
1762 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT, RESOURCETYPE_LOCAL_ARRAY,
1763 READWRITETYPE_READ),
1764 RobustnessTestCase::Params("fragment", "Provoke a context reset in fragment shader and ", ROBUSTACCESS_TRUE,
1765 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG, RESOURCETYPE_LOCAL_ARRAY,
1766 READWRITETYPE_READ),
1767 RobustnessTestCase::Params(
1768 "vertex_and_fragment", "Provoke a context reset in vertex and fragment shader and ", ROBUSTACCESS_TRUE,
1769 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG, RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ),
1770 RobustnessTestCase::Params("compute", "Provoke a context reset in compute shader and ", ROBUSTACCESS_TRUE,
1771 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE, RESOURCETYPE_LOCAL_ARRAY,
1772 READWRITETYPE_READ),
1773
1774 // ubo read only (non-robust)
1775 RobustnessTestCase::Params("vertex", "Provoke a context reset in vertex shader and ", ROBUSTACCESS_FALSE,
1776 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT, RESOURCETYPE_UBO,
1777 READWRITETYPE_READ),
1778 RobustnessTestCase::Params("fragment", "Provoke a context reset in fragment shader and ",
1779 ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,
1780 RESOURCETYPE_UBO, READWRITETYPE_READ),
1781 RobustnessTestCase::Params(
1782 "vertex_and_fragment", "Provoke a context reset in vertex and fragment shader and ", ROBUSTACCESS_FALSE,
1783 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG, RESOURCETYPE_UBO, READWRITETYPE_READ),
1784 RobustnessTestCase::Params("compute", "Provoke a context reset in compute shader and ", ROBUSTACCESS_FALSE,
1785 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE, RESOURCETYPE_UBO,
1786 READWRITETYPE_READ),
1787
1788 // ssbo read only (non-robust)
1789 RobustnessTestCase::Params("vertex", "Provoke a context reset in vertex shader and ", ROBUSTACCESS_FALSE,
1790 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT, RESOURCETYPE_SSBO,
1791 READWRITETYPE_READ),
1792 RobustnessTestCase::Params("fragment", "Provoke a context reset in fragment shader and ",
1793 ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,
1794 RESOURCETYPE_SSBO, READWRITETYPE_READ),
1795 RobustnessTestCase::Params(
1796 "vertex_and_fragment", "Provoke a context reset in vertex and fragment shader and ", ROBUSTACCESS_FALSE,
1797 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG, RESOURCETYPE_SSBO, READWRITETYPE_READ),
1798 RobustnessTestCase::Params("compute", "Provoke a context reset in compute shader and ", ROBUSTACCESS_FALSE,
1799 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE, RESOURCETYPE_SSBO,
1800 READWRITETYPE_READ),
1801
1802 // local array read only (non-robust)
1803 RobustnessTestCase::Params("vertex", "Provoke a context reset in vertex shader and ", ROBUSTACCESS_FALSE,
1804 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT, RESOURCETYPE_LOCAL_ARRAY,
1805 READWRITETYPE_READ),
1806 RobustnessTestCase::Params("fragment", "Provoke a context reset in fragment shader and ",
1807 ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,
1808 RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ),
1809 RobustnessTestCase::Params(
1810 "vertex_and_fragment", "Provoke a context reset in vertex and fragment shader and ", ROBUSTACCESS_FALSE,
1811 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG, RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ),
1812 RobustnessTestCase::Params("compute", "Provoke a context reset in compute shader and ", ROBUSTACCESS_FALSE,
1813 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE, RESOURCETYPE_LOCAL_ARRAY,
1814 READWRITETYPE_READ),
1815 };
1816
1817 for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_outOfBoundReadCases); ++testNdx)
1818 {
1819 const RobustnessTestCase::Params &test = s_outOfBoundReadCases[testNdx];
1820
1821 if (test.getResourceType() == RESOURCETYPE_UBO && test.getRobustAccessType() == ROBUSTACCESS_TRUE)
1822 uboReadArrayResetTestGroup->addChild(
1823 new BasicResetCase(eglTestCtx, test.getName().c_str(),
1824 (test.getDescription() + resetScenarioDescription).c_str(), test));
1825
1826 if (test.getResourceType() == RESOURCETYPE_UBO && test.getRobustAccessType() == ROBUSTACCESS_FALSE)
1827 uboReadArrayResetNonRobustTestGroup->addChild(
1828 new BasicResetCase(eglTestCtx, test.getName().c_str(),
1829 (test.getDescription() + resetScenarioDescription).c_str(), test));
1830
1831 if (test.getResourceType() == RESOURCETYPE_SSBO && test.getRobustAccessType() == ROBUSTACCESS_TRUE)
1832 ssboReadArrayResetTestGroup->addChild(
1833 new BasicResetCase(eglTestCtx, test.getName().c_str(),
1834 (test.getDescription() + resetScenarioDescription).c_str(), test));
1835
1836 if (test.getResourceType() == RESOURCETYPE_SSBO && test.getRobustAccessType() == ROBUSTACCESS_FALSE)
1837 ssboReadArrayResetNonRobustTestGroup->addChild(
1838 new BasicResetCase(eglTestCtx, test.getName().c_str(),
1839 (test.getDescription() + resetScenarioDescription).c_str(), test));
1840
1841 if (test.getResourceType() == RESOURCETYPE_LOCAL_ARRAY && test.getRobustAccessType() == ROBUSTACCESS_TRUE)
1842 localReadArrayResetTestGroup->addChild(
1843 new BasicResetCase(eglTestCtx, test.getName().c_str(),
1844 (test.getDescription() + resetScenarioDescription).c_str(), test));
1845
1846 if (test.getResourceType() == RESOURCETYPE_LOCAL_ARRAY && test.getRobustAccessType() == ROBUSTACCESS_FALSE)
1847 localReadArrayResetNonRobustTestGroup->addChild(
1848 new BasicResetCase(eglTestCtx, test.getName().c_str(),
1849 (test.getDescription() + resetScenarioDescription).c_str(), test));
1850 }
1851
1852 static const RobustnessTestCase::Params s_outOfBoundWriteCases[] = {
1853 // ubo write only
1854 RobustnessTestCase::Params("vertex", "Provoke a context reset in vertex shader and ", ROBUSTACCESS_TRUE,
1855 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT, RESOURCETYPE_UBO,
1856 READWRITETYPE_WRITE),
1857 RobustnessTestCase::Params("fragment", "Provoke a context reset in fragment shader and ", ROBUSTACCESS_TRUE,
1858 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG, RESOURCETYPE_UBO,
1859 READWRITETYPE_WRITE),
1860 RobustnessTestCase::Params(
1861 "vertex_and_fragment", "Provoke a context reset in vertex and fragment shader and ", ROBUSTACCESS_TRUE,
1862 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG, RESOURCETYPE_UBO, READWRITETYPE_WRITE),
1863 RobustnessTestCase::Params("compute", "Provoke a context reset in compute shader and ", ROBUSTACCESS_TRUE,
1864 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE, RESOURCETYPE_UBO,
1865 READWRITETYPE_WRITE),
1866
1867 // ssbo write only
1868 RobustnessTestCase::Params("vertex", "Provoke a context reset in vertex shader and ", ROBUSTACCESS_TRUE,
1869 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT, RESOURCETYPE_SSBO,
1870 READWRITETYPE_WRITE),
1871 RobustnessTestCase::Params("fragment", "Provoke a context reset in fragment shader and ", ROBUSTACCESS_TRUE,
1872 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG, RESOURCETYPE_SSBO,
1873 READWRITETYPE_WRITE),
1874 RobustnessTestCase::Params(
1875 "vertex_and_fragment", "Provoke a context reset in vertex and fragment shader and ", ROBUSTACCESS_TRUE,
1876 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG, RESOURCETYPE_SSBO, READWRITETYPE_WRITE),
1877 RobustnessTestCase::Params("compute", "Provoke a context reset in compute shader and ", ROBUSTACCESS_TRUE,
1878 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE, RESOURCETYPE_SSBO,
1879 READWRITETYPE_WRITE),
1880
1881 // local array write only
1882 RobustnessTestCase::Params("vertex", "Provoke a context reset in vertex shader and ", ROBUSTACCESS_TRUE,
1883 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT, RESOURCETYPE_LOCAL_ARRAY,
1884 READWRITETYPE_WRITE),
1885 RobustnessTestCase::Params("fragment", "Provoke a context reset in fragment shader and ", ROBUSTACCESS_TRUE,
1886 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG, RESOURCETYPE_LOCAL_ARRAY,
1887 READWRITETYPE_WRITE),
1888 RobustnessTestCase::Params(
1889 "vertex_and_fragment", "Provoke a context reset in vertex and fragment shader and ", ROBUSTACCESS_TRUE,
1890 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG, RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE),
1891 RobustnessTestCase::Params("compute", "Provoke a context reset in compute shader and ", ROBUSTACCESS_TRUE,
1892 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE, RESOURCETYPE_LOCAL_ARRAY,
1893 READWRITETYPE_WRITE),
1894
1895 // ubo write only (non-robust)
1896 RobustnessTestCase::Params("vertex", "Provoke a context reset in vertex shader and ", ROBUSTACCESS_FALSE,
1897 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT, RESOURCETYPE_UBO,
1898 READWRITETYPE_WRITE),
1899 RobustnessTestCase::Params("fragment", "Provoke a context reset in fragment shader and ",
1900 ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,
1901 RESOURCETYPE_UBO, READWRITETYPE_WRITE),
1902 RobustnessTestCase::Params(
1903 "vertex_and_fragment", "Provoke a context reset in vertex and fragment shader and ", ROBUSTACCESS_FALSE,
1904 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG, RESOURCETYPE_UBO, READWRITETYPE_WRITE),
1905 RobustnessTestCase::Params("compute", "Provoke a context reset in compute shader and ", ROBUSTACCESS_FALSE,
1906 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE, RESOURCETYPE_UBO,
1907 READWRITETYPE_WRITE),
1908
1909 // ssbo write only (non-robust)
1910 RobustnessTestCase::Params("vertex", "Provoke a context reset in vertex shader and ", ROBUSTACCESS_FALSE,
1911 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT, RESOURCETYPE_SSBO,
1912 READWRITETYPE_WRITE),
1913 RobustnessTestCase::Params("fragment", "Provoke a context reset in fragment shader and ",
1914 ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,
1915 RESOURCETYPE_SSBO, READWRITETYPE_WRITE),
1916 RobustnessTestCase::Params(
1917 "vertex_and_fragment", "Provoke a context reset in vertex and fragment shader and ", ROBUSTACCESS_FALSE,
1918 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG, RESOURCETYPE_SSBO, READWRITETYPE_WRITE),
1919 RobustnessTestCase::Params("compute", "Provoke a context reset in compute shader and ", ROBUSTACCESS_FALSE,
1920 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE, RESOURCETYPE_SSBO,
1921 READWRITETYPE_WRITE),
1922
1923 // local array write only (non-robust)
1924 RobustnessTestCase::Params("vertex", "Provoke a context reset in vertex shader and ", ROBUSTACCESS_FALSE,
1925 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT, RESOURCETYPE_LOCAL_ARRAY,
1926 READWRITETYPE_WRITE),
1927 RobustnessTestCase::Params("fragment", "Provoke a context reset in fragment shader and ",
1928 ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,
1929 RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE),
1930 RobustnessTestCase::Params(
1931 "vertex_and_fragment", "Provoke a context reset in vertex and fragment shader and ", ROBUSTACCESS_FALSE,
1932 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG, RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE),
1933 RobustnessTestCase::Params("compute", "Provoke a context reset in compute shader and ", ROBUSTACCESS_FALSE,
1934 CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE, RESOURCETYPE_LOCAL_ARRAY,
1935 READWRITETYPE_WRITE),
1936 };
1937
1938 for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_outOfBoundWriteCases); ++testNdx)
1939 {
1940 const RobustnessTestCase::Params &test = s_outOfBoundWriteCases[testNdx];
1941
1942 if (test.getResourceType() == RESOURCETYPE_UBO && test.getRobustAccessType() == ROBUSTACCESS_TRUE)
1943 uboWriteArrayResetTestGroup->addChild(
1944 new BasicResetCase(eglTestCtx, test.getName().c_str(),
1945 (test.getDescription() + resetScenarioDescription).c_str(), test));
1946
1947 if (test.getResourceType() == RESOURCETYPE_UBO && test.getRobustAccessType() == ROBUSTACCESS_FALSE)
1948 uboWriteArrayResetNonRobustTestGroup->addChild(
1949 new BasicResetCase(eglTestCtx, test.getName().c_str(),
1950 (test.getDescription() + resetScenarioDescription).c_str(), test));
1951
1952 if (test.getResourceType() == RESOURCETYPE_SSBO && test.getRobustAccessType() == ROBUSTACCESS_TRUE)
1953 ssboWriteArrayResetTestGroup->addChild(
1954 new BasicResetCase(eglTestCtx, test.getName().c_str(),
1955 (test.getDescription() + resetScenarioDescription).c_str(), test));
1956
1957 if (test.getResourceType() == RESOURCETYPE_SSBO && test.getRobustAccessType() == ROBUSTACCESS_FALSE)
1958 ssboWriteArrayResetNonRobustTestGroup->addChild(
1959 new BasicResetCase(eglTestCtx, test.getName().c_str(),
1960 (test.getDescription() + resetScenarioDescription).c_str(), test));
1961
1962 if (test.getResourceType() == RESOURCETYPE_LOCAL_ARRAY && test.getRobustAccessType() == ROBUSTACCESS_TRUE)
1963 localWriteArrayResetTestGroup->addChild(
1964 new BasicResetCase(eglTestCtx, test.getName().c_str(),
1965 (test.getDescription() + resetScenarioDescription).c_str(), test));
1966
1967 if (test.getResourceType() == RESOURCETYPE_LOCAL_ARRAY && test.getRobustAccessType() == ROBUSTACCESS_FALSE)
1968 localWriteArrayResetNonRobustTestGroup->addChild(
1969 new BasicResetCase(eglTestCtx, test.getName().c_str(),
1970 (test.getDescription() + resetScenarioDescription).c_str(), test));
1971 }
1972
1973 // robust Context
1974 tcu::TestCaseGroup *const outOfBoundsResetReadAccessTestGroup =
1975 new TestCaseGroup(eglTestCtx, "reads", "Out of bounds read accesses");
1976 tcu::TestCaseGroup *const outOfBoundsResetWriteAccessTestGroup =
1977 new TestCaseGroup(eglTestCtx, "writes", "Out of bounds write accesses");
1978
1979 outOfBoundsResetReadAccessTestGroup->addChild(uboReadArrayResetTestGroup);
1980 outOfBoundsResetReadAccessTestGroup->addChild(ssboReadArrayResetTestGroup);
1981 outOfBoundsResetReadAccessTestGroup->addChild(localReadArrayResetTestGroup);
1982
1983 outOfBoundsResetWriteAccessTestGroup->addChild(uboWriteArrayResetTestGroup);
1984 outOfBoundsResetWriteAccessTestGroup->addChild(ssboWriteArrayResetTestGroup);
1985 outOfBoundsResetWriteAccessTestGroup->addChild(localWriteArrayResetTestGroup);
1986
1987 tcu::TestCaseGroup *const outOfBoundsResetTestGroup = new TestCaseGroup(
1988 eglTestCtx, "reset_status", "Tests that query the reset status after a context reset has occurred");
1989
1990 outOfBoundsResetTestGroup->addChild(outOfBoundsResetReadAccessTestGroup);
1991 outOfBoundsResetTestGroup->addChild(outOfBoundsResetWriteAccessTestGroup);
1992
1993 outOfBoundsTestGroup->addChild(outOfBoundsResetTestGroup);
1994
1995 // non-robust Context (internal use only)
1996 tcu::TestCaseGroup *const outOfBoundsResetReadAccessNonRobustTestGroup =
1997 new TestCaseGroup(eglTestCtx, "reads", "Out of bounds read accesses");
1998 tcu::TestCaseGroup *const outOfBoundsResetWriteAccessNonRobustTestGroup =
1999 new TestCaseGroup(eglTestCtx, "writes", "Out of bounds write accesses");
2000
2001 outOfBoundsResetReadAccessNonRobustTestGroup->addChild(uboReadArrayResetNonRobustTestGroup);
2002 outOfBoundsResetReadAccessNonRobustTestGroup->addChild(ssboReadArrayResetNonRobustTestGroup);
2003 outOfBoundsResetReadAccessNonRobustTestGroup->addChild(localReadArrayResetNonRobustTestGroup);
2004
2005 outOfBoundsResetWriteAccessNonRobustTestGroup->addChild(uboWriteArrayResetNonRobustTestGroup);
2006 outOfBoundsResetWriteAccessNonRobustTestGroup->addChild(ssboWriteArrayResetNonRobustTestGroup);
2007 outOfBoundsResetWriteAccessNonRobustTestGroup->addChild(localWriteArrayResetNonRobustTestGroup);
2008
2009 tcu::TestCaseGroup *const outOfBoundsResetNonRobustTestGroup = new TestCaseGroup(
2010 eglTestCtx, "reset_status", "Tests that query the reset status after a context reset has occurred");
2011
2012 outOfBoundsResetNonRobustTestGroup->addChild(outOfBoundsResetReadAccessNonRobustTestGroup);
2013 outOfBoundsResetNonRobustTestGroup->addChild(outOfBoundsResetWriteAccessNonRobustTestGroup);
2014
2015 outOfBoundsNonRobustTestGroup->addChild(outOfBoundsResetNonRobustTestGroup);
2016 }
2017
2018 // fixed function test cases
2019 {
2020 // robust context
2021 tcu::TestCaseGroup *const fixedFunctionResetStatusTestGroup = new TestCaseGroup(
2022 eglTestCtx, "reset_status", "Tests that query the reset status after a context reset has occurred");
2023
2024 // non-robust context (internal use only)
2025 tcu::TestCaseGroup *const fixedFunctionResetStatusNonRobustTestGroup = new TestCaseGroup(
2026 eglTestCtx, "reset_status", "Tests that query the reset status after a context reset has occurred");
2027
2028 static const RobustnessTestCase::Params s_fixedFunctionPipelineCases[] = {
2029 RobustnessTestCase::Params("index_buffer_out_of_bounds",
2030 "Provoke context reset and query error states and reset notifications",
2031 ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_FIXED_FUNC_OOB, FIXEDFUNCTIONTYPE_INDICES),
2032 RobustnessTestCase::Params("vertex_buffer_out_of_bounds",
2033 "Provoke context reset and query error states and reset notifications",
2034 ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_FIXED_FUNC_OOB, FIXEDFUNCTIONTYPE_VERTICES),
2035
2036 RobustnessTestCase::Params("index_buffer_out_of_bounds",
2037 "Provoke context reset and query error states and reset notifications",
2038 ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_FIXED_FUNC_OOB, FIXEDFUNCTIONTYPE_INDICES),
2039 RobustnessTestCase::Params("vertex_buffer_out_of_bounds",
2040 "Provoke context reset and query error states and reset notifications",
2041 ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_FIXED_FUNC_OOB, FIXEDFUNCTIONTYPE_VERTICES),
2042 };
2043
2044 for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_fixedFunctionPipelineCases); ++testNdx)
2045 {
2046 const RobustnessTestCase::Params &test = s_fixedFunctionPipelineCases[testNdx];
2047 if (test.getRobustAccessType() == ROBUSTACCESS_TRUE)
2048 fixedFunctionResetStatusTestGroup->addChild(
2049 new BasicResetCase(eglTestCtx, test.getName().c_str(), test.getDescription().c_str(), test));
2050 else
2051 fixedFunctionResetStatusNonRobustTestGroup->addChild(
2052 new BasicResetCase(eglTestCtx, test.getName().c_str(), test.getDescription().c_str(), test));
2053 }
2054
2055 fixedFunctionTestGroup->addChild(fixedFunctionResetStatusTestGroup);
2056 fixedFunctionNonRobustTestGroup->addChild(fixedFunctionResetStatusNonRobustTestGroup);
2057 }
2058
2059 // context creation query cases
2060 {
2061 contextCreationTestGroup->addChild(new QueryRobustAccessCase(
2062 eglTestCtx, "query_robust_access", "Query robust access after successfully creating a robust context"));
2063 contextCreationTestGroup->addChild(
2064 new NoResetNotificationCase(eglTestCtx, "no_reset_notification",
2065 "Query reset notification strategy after specifying GL_NO_RESET_NOTIFICATION"));
2066 contextCreationTestGroup->addChild(
2067 new LoseContextOnResetCase(eglTestCtx, "lose_context_on_reset",
2068 "Query reset notification strategy after specifying GL_LOSE_CONTEXT_ON_RESET"));
2069 }
2070
2071 // invalid context creation cases
2072 {
2073 negativeContextTestGroup->addChild(
2074 new InvalidContextCase(eglTestCtx, "invalid_robust_context_creation",
2075 "Create a non-robust context but specify a reset notification strategy"));
2076 negativeContextTestGroup->addChild(
2077 new InvalidShareContextCase(eglTestCtx, "invalid_robust_shared_context_creation",
2078 "Create a context share group with conflicting reset notification strategies"));
2079 negativeContextTestGroup->addChild(new InvalidNotificationEnumCase(
2080 eglTestCtx, "invalid_notification_strategy_enum",
2081 "Create a robust context using EGL 1.5 only enum with EGL versions <= 1.4"));
2082 }
2083
2084 shadersTestGroup->addChild(outOfBoundsTestGroup);
2085 shadersTestGroup->addChild(outOfBoundsNonRobustTestGroup);
2086
2087 contextResetTestGroup->addChild(shadersTestGroup);
2088 contextResetTestGroup->addChild(fixedFunctionTestGroup);
2089 contextResetTestGroup->addChild(fixedFunctionNonRobustTestGroup);
2090
2091 group->addChild(contextCreationTestGroup);
2092 group->addChild(contextResetTestGroup);
2093 group->addChild(negativeContextTestGroup);
2094
2095 return group.release();
2096 }
2097
2098 } // namespace egl
2099 } // namespace deqp
2100