Fix atomic ssbo xor test am: f0fa05e898 am: 14cd264501 am: 6e80057a20 am: cae1fe52ac...
[platform/upstream/VK-GL-CTS.git] / modules / egl / teglNegativePartialUpdateTests.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program EGL Module
3  * ---------------------------------------
4  *
5  * Copyright 2015 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *       http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Test negative use case of KHR_partial_update
22  *//*--------------------------------------------------------------------*/
23
24 #include "teglNegativePartialUpdateTests.hpp"
25
26 #include "tcuTestLog.hpp"
27 #include "tcuSurface.hpp"
28
29 #include "egluCallLogWrapper.hpp"
30 #include "egluConfigFilter.hpp"
31 #include "egluNativeWindow.hpp"
32 #include "egluStrUtil.hpp"
33 #include "egluUnique.hpp"
34 #include "egluUtil.hpp"
35
36 #include "eglwLibrary.hpp"
37 #include "eglwEnums.hpp"
38
39 using namespace eglu;
40 using namespace eglw;
41 using tcu::TestLog;
42
43 namespace deqp
44 {
45 namespace egl
46 {
47 namespace
48 {
49
50 class NegativePartialUpdateTest : public TestCase
51 {
52 public:
53         enum SurfaceType
54         {
55                 SURFACETYPE_WINDOW = 0,
56                 SURFACETYPE_PBUFFER
57         };
58
59                                                                 NegativePartialUpdateTest               (EglTestContext& eglTestCtx, bool preserveBuffer, SurfaceType surfaceType, const char* name, const char* description);
60                                                                 ~NegativePartialUpdateTest              (void);
61         void                                            init                                                    (void);
62         void                                            deinit                                                  (void);
63         virtual IterateResult           iterate                                                 (void) = 0;
64
65 protected:
66         void                                            expectError                                             (eglw::EGLenum error);
67         void                                            expectBoolean                                   (EGLBoolean expected, EGLBoolean got);
68         inline void                                     expectTrue                                              (eglw::EGLBoolean got) { expectBoolean(EGL_TRUE, got); }
69         inline void                                     expectFalse                                             (eglw::EGLBoolean got) { expectBoolean(EGL_FALSE, got); }
70
71         const bool                                      m_preserveBuffer;
72         SurfaceType                                     m_surfaceType;
73         EGLDisplay                                      m_eglDisplay;
74         EGLConfig                                       m_eglConfig;
75         NativeWindow*                           m_window;
76         EGLSurface                                      m_eglSurface;
77         EGLContext                                      m_eglContext;
78 };
79
80 bool isWindow (const CandidateConfig& c)
81 {
82         return (c.surfaceType() & EGL_WINDOW_BIT) == EGL_WINDOW_BIT;
83 }
84
85 bool isPbuffer (const CandidateConfig& c)
86 {
87         return (c.surfaceType() & EGL_PBUFFER_BIT) == EGL_PBUFFER_BIT;
88 }
89
90 bool isES2Renderable (const CandidateConfig& c)
91 {
92         return (c.get(EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT) == EGL_OPENGL_ES2_BIT;
93 }
94
95 bool hasPreserveSwap (const CandidateConfig& c)
96 {
97         return (c.surfaceType() & EGL_SWAP_BEHAVIOR_PRESERVED_BIT) == EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
98 }
99
100 EGLConfig getEGLConfig (const Library& egl, EGLDisplay eglDisplay, NegativePartialUpdateTest::SurfaceType surfaceType, bool preserveBuffer)
101 {
102         FilterList filters;
103         if (surfaceType == NegativePartialUpdateTest::SURFACETYPE_WINDOW)
104                 filters << isWindow;
105         else if (surfaceType == NegativePartialUpdateTest::SURFACETYPE_PBUFFER)
106                 filters << isPbuffer;
107         else
108                 DE_FATAL("Invalid surfaceType");
109
110         filters << isES2Renderable;
111
112         if (preserveBuffer)
113                 filters << hasPreserveSwap;
114
115         return chooseSingleConfig(egl, eglDisplay, filters);
116 }
117
118 EGLContext initAndMakeCurrentEGLContext (const Library& egl, EGLDisplay eglDisplay, EGLSurface eglSurface, EGLConfig eglConfig, const EGLint* attribList)
119 {
120         EGLContext eglContext = EGL_NO_CONTEXT;
121
122         egl.bindAPI(EGL_OPENGL_ES_API);
123         eglContext = egl.createContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, attribList);
124         EGLU_CHECK_MSG(egl, "eglCreateContext");
125         TCU_CHECK(eglSurface != EGL_NO_SURFACE);
126         egl.makeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
127         EGLU_CHECK_MSG(egl, "eglMakeCurrent");
128
129         return eglContext;
130 }
131
132 NegativePartialUpdateTest::NegativePartialUpdateTest (EglTestContext& eglTestCtx, bool preserveBuffer, SurfaceType surfaceType, const char* name, const char* description)
133         : TestCase                      (eglTestCtx, name, description)
134         , m_preserveBuffer      (preserveBuffer)
135         , m_surfaceType         (surfaceType)
136         , m_eglDisplay          (EGL_NO_DISPLAY)
137         , m_window                      (DE_NULL)
138         , m_eglSurface          (EGL_NO_SURFACE)
139         , m_eglContext          (EGL_NO_CONTEXT)
140 {
141 }
142
143 NegativePartialUpdateTest::~NegativePartialUpdateTest (void)
144 {
145         deinit();
146 }
147
148 void NegativePartialUpdateTest::init (void)
149 {
150         const Library&          egl                                             = m_eglTestCtx.getLibrary();
151         static const EGLint     contextAttribList[]             = { EGL_CONTEXT_CLIENT_VERSION, 2,      EGL_NONE };
152         const int                       width                                   = 480;
153         const int                       height                                  = 480;
154
155         m_eglDisplay = getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
156
157         if (!hasExtension(egl, m_eglDisplay, "EGL_KHR_partial_update"))
158                 TCU_THROW(NotSupportedError, "EGL_KHR_partial_update is not supported");
159
160         m_eglConfig = getEGLConfig(egl, m_eglDisplay, m_surfaceType, m_preserveBuffer);
161
162         if (m_surfaceType == SURFACETYPE_PBUFFER)
163         {
164                 const EGLint pbufferAttribList[] = { EGL_WIDTH, width, EGL_HEIGHT, height, EGL_NONE };
165                 m_eglSurface = egl.createPbufferSurface(m_eglDisplay, m_eglConfig, pbufferAttribList);
166         }
167         else
168         {
169                 const NativeWindowFactory&      factory = selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
170                 m_window = factory.createWindow(&m_eglTestCtx.getNativeDisplay(), m_eglDisplay, m_eglConfig, DE_NULL,
171                                                                                 WindowParams(width, height, parseWindowVisibility(m_testCtx.getCommandLine())));
172                 m_eglSurface = createWindowSurface(m_eglTestCtx.getNativeDisplay(), *m_window, m_eglDisplay, m_eglConfig, DE_NULL);
173         }
174         m_eglContext = initAndMakeCurrentEGLContext(egl, m_eglDisplay, m_eglSurface, m_eglConfig, contextAttribList);
175 }
176
177 void NegativePartialUpdateTest::deinit (void)
178 {
179         const Library& egl = m_eglTestCtx.getLibrary();
180
181         if (m_eglContext != EGL_NO_CONTEXT)
182         {
183                 EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
184                 EGLU_CHECK_CALL(egl, destroyContext(m_eglDisplay, m_eglContext));
185                 m_eglContext = EGL_NO_CONTEXT;
186         }
187
188         if (m_eglSurface != EGL_NO_SURFACE)
189         {
190                 EGLU_CHECK_CALL(egl, destroySurface(m_eglDisplay, m_eglSurface));
191                 m_eglSurface = EGL_NO_SURFACE;
192         }
193
194         if (m_eglDisplay != EGL_NO_DISPLAY)
195         {
196                 EGLU_CHECK_CALL(egl, terminate(m_eglDisplay));
197                 m_eglDisplay = EGL_NO_DISPLAY;
198         }
199
200         delete m_window;
201         m_window = DE_NULL;
202 }
203
204 void NegativePartialUpdateTest::expectError (EGLenum expected)
205 {
206         const EGLenum err = m_eglTestCtx.getLibrary().getError();
207
208         if (err != expected)
209         {
210                 m_testCtx.getLog() << TestLog::Message << "// ERROR expected: " << eglu::getErrorStr(expected) << ", Got: " << eglu::getErrorStr(err) << TestLog::EndMessage;
211                 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
212                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid error");
213         }
214 }
215
216 void NegativePartialUpdateTest::expectBoolean (EGLBoolean expected, EGLBoolean got)
217 {
218         if (expected != got)
219         {
220                 m_testCtx.getLog() << TestLog::Message << "// ERROR expected: " << eglu::getBooleanStr(expected) <<  ", Got: " << eglu::getBooleanStr(got) << TestLog::EndMessage;
221                 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
222                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid value");
223         }
224 }
225
226 class NotPostableTest : public NegativePartialUpdateTest
227 {
228 public:
229                                                         NotPostableTest (EglTestContext& context);
230         TestCase::IterateResult iterate                 (void);
231 };
232
233 NotPostableTest::NotPostableTest (EglTestContext& context)
234         : NegativePartialUpdateTest (context, false, SURFACETYPE_PBUFFER, "not_postable_surface",  "Call setDamageRegion() on pbuffer")
235 {
236 }
237
238 TestCase::IterateResult NotPostableTest::iterate (void)
239 {
240         const Library&                  egl                             = m_eglTestCtx.getLibrary();
241         TestLog&                                log                             = m_testCtx.getLog();
242         CallLogWrapper                  wrapper                 (egl, log);
243         EGLint                                  damageRegion[]  = { 10, 10, 10, 10 };
244         int                                             bufferAge               = -1;
245
246         wrapper.enableLogging(true);
247         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
248         {
249                 tcu::ScopedLogSection(log, "Test1", "If the surface is pbuffer (not postable) --> EGL_BAD_MATCH");
250                 EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED));
251                 EGLU_CHECK_CALL(egl, querySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge));
252                 expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, DE_LENGTH_OF_ARRAY(damageRegion)/4));
253                 expectError(EGL_BAD_MATCH);
254         }
255
256         return STOP;
257 }
258
259 class NotCurrentSurfaceTest : public NegativePartialUpdateTest
260 {
261 public:
262                                                         NotCurrentSurfaceTest   (EglTestContext& context);
263         TestCase::IterateResult iterate                                 (void);
264 };
265
266 NotCurrentSurfaceTest::NotCurrentSurfaceTest (EglTestContext& context)
267         : NegativePartialUpdateTest (context, false, SURFACETYPE_WINDOW, "not_current_surface",  "Call setDamageRegion() on pbuffer")
268 {
269 }
270
271 TestCase::IterateResult NotCurrentSurfaceTest::iterate (void)
272 {
273         const int                                       impossibleBufferAge = -26084;
274         const Library&                          egl                                     = m_eglTestCtx.getLibrary();
275         const EGLConfig                         config                          = getEGLConfig(egl, m_eglDisplay, SURFACETYPE_PBUFFER, false);
276         const EGLint                            attribList[]            =
277         {
278                 EGL_WIDTH,      64,
279                 EGL_HEIGHT,     64,
280                 EGL_NONE
281         };
282         const eglu::UniqueSurface       dummyPbuffer            (egl, m_eglDisplay, egl.createPbufferSurface(m_eglDisplay, config, attribList));
283         TestLog&                                        log                                     = m_testCtx.getLog();
284         CallLogWrapper                          wrapper                         (egl, log);
285         EGLint                                          damageRegion[]          = { 10, 10, 10, 10 };
286         int                                                     bufferAge                       = impossibleBufferAge;
287
288         wrapper.enableLogging(true);
289         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
290         EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, *dummyPbuffer, *dummyPbuffer, m_eglContext));
291         {
292                 tcu::ScopedLogSection(log, "Test2.1", "If query buffer age on a surface that is not the current draw surface --> EGL_BAD_SURFACE");
293                 EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED));
294                 expectFalse(wrapper.eglQuerySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge));
295                 expectError(EGL_BAD_SURFACE);
296
297                 if (bufferAge != impossibleBufferAge)
298                 {
299                         log << tcu::TestLog::Message << "On failure, eglQuerySurface shouldn't change buffer age but buffer age has been changed to " << bufferAge << tcu::TestLog::EndMessage;
300                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail, bufferAge shouldn't be changed");
301                 }
302         }
303         {
304                 tcu::ScopedLogSection(log, "Test2.2", "If call setDamageRegion() on a surface that is not the current draw surface --> EGL_BAD_MATCH");
305                 expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, 1));
306                 expectError(EGL_BAD_MATCH);
307         }
308
309         EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
310         {
311                 tcu::ScopedLogSection(log, "Test3.1", "If query buffer age on a surface that is not the current draw surface --> EGL_BAD_SURFACE");
312                 EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED));
313                 expectFalse(wrapper.eglQuerySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge));
314                 expectError(EGL_BAD_SURFACE);
315
316                 if (bufferAge != impossibleBufferAge)
317                 {
318                         log << tcu::TestLog::Message << "On failure, eglQuerySurface shouldn't change buffer age but buffer age has been changed to " << bufferAge << tcu::TestLog::EndMessage;
319                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail, bufferAge shouldn't be changed");
320                 }
321         }
322         {
323                 tcu::ScopedLogSection(log, "Test3.2", "If call setDamageRegion() on a surface that is not the current draw surface --> EGL_BAD_MATCH");
324                 expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, 1));
325                 expectError(EGL_BAD_MATCH);
326         }
327
328         if (hasExtension(egl, m_eglDisplay, "EGL_KHR_surfaceless_context"))
329         {
330                 EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, m_eglContext));
331                 {
332                         tcu::ScopedLogSection(log, "Test4.1", "If query buffer age on a surface that is not the current draw surface --> EGL_BAD_SURFACE");
333                         EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED));
334                         expectFalse(wrapper.eglQuerySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge));
335                         expectError(EGL_BAD_SURFACE);
336
337                         if (bufferAge != impossibleBufferAge)
338                         {
339                                 log << tcu::TestLog::Message << "On failure, eglQuerySurface shouldn't change buffer age but buffer age has been changed to " << bufferAge << tcu::TestLog::EndMessage;
340                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail, bufferAge shouldn't be changed");
341                         }
342                 }
343                 {
344                         tcu::ScopedLogSection(log, "Test4.2", "If call setDamageRegion() on a surface that is not the current draw surface --> EGL_BAD_MATCH");
345                         expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, 1));
346                         expectError(EGL_BAD_MATCH);
347                 }
348         }
349
350         return STOP;
351 }
352
353 class BufferPreservedTest : public NegativePartialUpdateTest
354 {
355 public:
356                                                         BufferPreservedTest (EglTestContext& context);
357         TestCase::IterateResult iterate                         (void);
358 };
359
360 BufferPreservedTest::BufferPreservedTest (EglTestContext& context)
361         : NegativePartialUpdateTest (context, true, SURFACETYPE_WINDOW, "buffer_preserved",  "Call setDamageRegion() on pbuffer")
362 {
363 }
364
365 TestCase::IterateResult BufferPreservedTest::iterate (void)
366 {
367         const Library&                  egl                             = m_eglTestCtx.getLibrary();
368         TestLog&                                log                             = m_testCtx.getLog();
369         CallLogWrapper                  wrapper                 (egl, log);
370         EGLint                                  damageRegion[]  = { 10, 10, 10, 10 };
371         int                                             bufferAge               = -1;
372
373         wrapper.enableLogging(true);
374         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
375         {
376                 tcu::ScopedLogSection(log, "Test3", "If buffer_preserved --> EGL_BAD_MATCH");
377                 EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED));
378                 EGLU_CHECK_CALL(egl, querySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge));
379                 expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, DE_LENGTH_OF_ARRAY(damageRegion)/4));
380                 expectError(EGL_BAD_MATCH);
381         }
382
383         return STOP;
384 }
385
386 class SetTwiceTest : public NegativePartialUpdateTest
387 {
388 public:
389                                                         SetTwiceTest            (EglTestContext& context);
390         TestCase::IterateResult iterate                         (void);
391 };
392
393 SetTwiceTest::SetTwiceTest (EglTestContext& context)
394         : NegativePartialUpdateTest (context, false, SURFACETYPE_WINDOW, "set_damage_region_twice",  "Call setDamageRegion() twice")
395 {
396 }
397
398 TestCase::IterateResult SetTwiceTest::iterate (void)
399 {
400         const Library&                  egl                             = m_eglTestCtx.getLibrary();
401         TestLog&                                log                             = m_testCtx.getLog();
402         CallLogWrapper                  wrapper                 (egl, log);
403         EGLint                                  damageRegion[]  = { 10, 10, 10, 10 };
404         int                                             bufferAge               = -1;
405
406         wrapper.enableLogging(true);
407         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
408         {
409                 tcu::ScopedLogSection(log, "Test4", "If call setDamageRegion() twice --> EGL_BAD_ACCESS");
410                 EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED));
411                 EGLU_CHECK_CALL(egl, querySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge));
412                 expectTrue(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, DE_LENGTH_OF_ARRAY(damageRegion)/4));
413                 expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, DE_LENGTH_OF_ARRAY(damageRegion)/4));
414                 expectError(EGL_BAD_ACCESS);
415         }
416
417         return STOP;
418 }
419
420
421 class NoAgeTest : public NegativePartialUpdateTest
422 {
423 public:
424                                                         NoAgeTest                       (EglTestContext& context);
425         TestCase::IterateResult iterate                         (void);
426 };
427
428 NoAgeTest::NoAgeTest (EglTestContext& context)
429         : NegativePartialUpdateTest (context, false, SURFACETYPE_WINDOW, "set_damage_region_before_query_age",  "Call setDamageRegion() without querying buffer age")
430 {
431 }
432
433 TestCase::IterateResult NoAgeTest::iterate (void)
434 {
435         const Library&                  egl                             = m_eglTestCtx.getLibrary();
436         TestLog&                                log                             = m_testCtx.getLog();
437         CallLogWrapper                  wrapper                 (egl, log);
438         EGLint                                  damageRegion[]  = { 10, 10, 10, 10 };
439
440         wrapper.enableLogging(true);
441         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
442         {
443                 tcu::ScopedLogSection(log, "Test5", "If buffer age is not queried --> EGL_BAD_ACCESS");
444                 EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED));
445                 expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, DE_LENGTH_OF_ARRAY(damageRegion)/4));
446                 expectError(EGL_BAD_ACCESS);
447         }
448
449         return STOP;
450 }
451
452 class PassNullTest : public NegativePartialUpdateTest
453 {
454 public:
455                                                         PassNullTest                    (EglTestContext& context);
456         TestCase::IterateResult iterate                                 (void);
457 };
458
459 PassNullTest::PassNullTest (EglTestContext& context)
460         : NegativePartialUpdateTest (context, false, SURFACETYPE_WINDOW, "pass_null_0_as_params",  "Call setDamageRegion() with (NULL, 0)")
461 {
462 }
463
464 TestCase::IterateResult PassNullTest::iterate (void)
465 {
466         const Library&                  egl                             = m_eglTestCtx.getLibrary();
467         TestLog&                                log                             = m_testCtx.getLog();
468         CallLogWrapper                  wrapper                 (egl, log);
469         int                                             bufferAge               = -1;
470
471         wrapper.enableLogging(true);
472         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
473         {
474                 tcu::ScopedLogSection(log, "Test6", "If pass (null, 0) to setDamageRegion(), no error");
475                 EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED));
476                 EGLU_CHECK_CALL(egl, querySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge));
477                 expectTrue(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, DE_NULL, 0));
478                 expectError(EGL_SUCCESS);
479         }
480
481         return STOP;
482 }
483
484 class NotCurrentSurfaceTest2 : public NegativePartialUpdateTest
485 {
486 public:
487                                                         NotCurrentSurfaceTest2  (EglTestContext& context);
488         TestCase::IterateResult iterate                                 (void);
489 };
490
491 NotCurrentSurfaceTest2::NotCurrentSurfaceTest2 (EglTestContext& context)
492         : NegativePartialUpdateTest (context, false, SURFACETYPE_WINDOW, "not_current_surface2",  "Call setDamageRegion() on pbuffer")
493 {
494 }
495
496 TestCase::IterateResult NotCurrentSurfaceTest2::iterate (void)
497 {
498         const Library&                          egl                             = m_eglTestCtx.getLibrary();
499         const EGLConfig                         config                  = getEGLConfig(egl, m_eglDisplay, SURFACETYPE_PBUFFER, false);
500         const EGLint                            attribList[]    =
501         {
502                 EGL_WIDTH,      64,
503                 EGL_HEIGHT,     64,
504                 EGL_NONE
505         };
506         const eglu::UniqueSurface       dummyPbuffer    (egl, m_eglDisplay, egl.createPbufferSurface(m_eglDisplay, config, attribList));
507         TestLog&                                        log                             = m_testCtx.getLog();
508         CallLogWrapper                          wrapper                 (egl, log);
509         EGLint                                          damageRegion[]  = { 10, 10, 10, 10 };
510         int                                                     bufferAge               = -1;
511
512         wrapper.enableLogging(true);
513         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
514
515         EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED));
516         EGLU_CHECK_CALL(egl, querySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_KHR, &bufferAge));
517
518         {
519                 tcu::ScopedLogSection(log, "Test7", "If call setDamageRegion() on a surface that is not the current draw surface --> EGL_BAD_MATCH");
520                 EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, *dummyPbuffer, *dummyPbuffer, m_eglContext));
521                 expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, 1));
522                 expectError(EGL_BAD_MATCH);
523         }
524         {
525                 tcu::ScopedLogSection(log, "Test8", "If call setDamageRegion() on a surface that is not the current draw surface --> EGL_BAD_MATCH");
526                 EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
527                 expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, 1));
528                 expectError(EGL_BAD_MATCH);
529         }
530         if (hasExtension(egl, m_eglDisplay, "EGL_KHR_surfaceless_context"))
531         {
532                 tcu::ScopedLogSection(log, "Test9", "If call setDamageRegion() on a surface that is not the current draw surface --> EGL_BAD_MATCH");
533                 EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, m_eglContext));
534                 expectFalse(wrapper.eglSetDamageRegionKHR(m_eglDisplay, m_eglSurface, damageRegion, 1));
535                 expectError(EGL_BAD_MATCH);
536         }
537
538         return STOP;
539 }
540
541 } // anonymous
542
543 NegativePartialUpdateTests::NegativePartialUpdateTests (EglTestContext& eglTestCtx)
544         : TestCaseGroup(eglTestCtx, "negative_partial_update", "Negative partial update tests")
545 {
546 }
547
548 void NegativePartialUpdateTests::init (void)
549 {
550         addChild(new NotPostableTest(m_eglTestCtx));
551         addChild(new NotCurrentSurfaceTest(m_eglTestCtx));
552         addChild(new BufferPreservedTest(m_eglTestCtx));
553         addChild(new SetTwiceTest(m_eglTestCtx));
554         addChild(new NoAgeTest(m_eglTestCtx));
555         addChild(new PassNullTest(m_eglTestCtx));
556         addChild(new NotCurrentSurfaceTest2(m_eglTestCtx));
557 }
558
559 } // egl
560 } // deqp