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