Use glReadnPixels only if KHR_robustness is supported
[platform/upstream/VK-GL-CTS.git] / modules / egl / teglNativeCoordMappingTests.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program EGL Module
3  * ---------------------------------------
4  *
5  * Copyright 2014 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 Tests for mapping client coordinates to native surface coordinates
22  *//*--------------------------------------------------------------------*/
23
24 #include "teglNativeCoordMappingTests.hpp"
25
26 #include "teglSimpleConfigCase.hpp"
27
28 #include "tcuSurface.hpp"
29 #include "tcuTexture.hpp"
30
31 #include "egluNativeDisplay.hpp"
32 #include "egluNativeWindow.hpp"
33 #include "egluNativePixmap.hpp"
34 #include "egluUnique.hpp"
35 #include "egluUtil.hpp"
36
37 #include "eglwLibrary.hpp"
38 #include "eglwEnums.hpp"
39
40 #include "gluDefs.hpp"
41 #include "glwFunctions.hpp"
42 #include "glwEnums.hpp"
43
44 #include "tcuImageCompare.hpp"
45 #include "tcuTestLog.hpp"
46 #include "tcuTexture.hpp"
47 #include "tcuTextureUtil.hpp"
48
49 #include "deUniquePtr.hpp"
50 #include "deStringUtil.hpp"
51
52 #include "deThread.hpp"
53 #include "deMath.h"
54
55 #include <vector>
56 #include <string>
57
58 using tcu::TestLog;
59 using std::vector;
60 using std::string;
61
62 using namespace eglw;
63
64 namespace deqp
65 {
66 namespace egl
67 {
68 namespace
69 {
70
71 EGLContext createGLES2Context (const Library& egl, EGLDisplay display, EGLConfig config)
72 {
73         EGLContext              context                 = EGL_NO_CONTEXT;
74         const EGLint    attribList[]    =
75         {
76                 EGL_CONTEXT_CLIENT_VERSION, 2,
77                 EGL_NONE
78         };
79
80         EGLU_CHECK_CALL(egl, bindAPI(EGL_OPENGL_ES_API));
81
82         context = egl.createContext(display, config, EGL_NO_CONTEXT, attribList);
83         EGLU_CHECK_MSG(egl, "eglCreateContext() failed");
84         TCU_CHECK(context);
85
86         return context;
87 }
88
89 deUint32 createGLES2Program (const glw::Functions& gl, TestLog& log)
90 {
91         const char* const vertexShaderSource =
92         "attribute highp vec2 a_pos;\n"
93         "void main (void)\n"
94         "{\n"
95         "\tgl_Position = vec4(a_pos, 0.0, 1.0);\n"
96         "}";
97
98         const char* const fragmentShaderSource =
99         "void main (void)\n"
100         "{\n"
101         "\tgl_FragColor = vec4(1.0);\n"
102         "}";
103
104         deUint32        program                 = 0;
105         deUint32        vertexShader    = 0;
106         deUint32        fragmentShader  = 0;
107
108         deInt32         vertexCompileStatus;
109         string          vertexInfoLog;
110         deInt32         fragmentCompileStatus;
111         string          fragmentInfoLog;
112         deInt32         linkStatus;
113         string          programInfoLog;
114
115         try
116         {
117                 program                 = gl.createProgram();
118                 vertexShader    = gl.createShader(GL_VERTEX_SHADER);
119                 fragmentShader  = gl.createShader(GL_FRAGMENT_SHADER);
120
121                 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create shaders and program");
122
123                 gl.shaderSource(vertexShader, 1, &vertexShaderSource, DE_NULL);
124                 gl.compileShader(vertexShader);
125                 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup vertex shader");
126
127                 gl.shaderSource(fragmentShader, 1, &fragmentShaderSource, DE_NULL);
128                 gl.compileShader(fragmentShader);
129                 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup fragment shader");
130
131                 {
132                         deInt32         infoLogLength = 0;
133
134                         gl.getShaderiv(vertexShader, GL_COMPILE_STATUS, &vertexCompileStatus);
135                         gl.getShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &infoLogLength);
136
137                         vertexInfoLog.resize(infoLogLength, '\0');
138
139                         gl.getShaderInfoLog(vertexShader, (glw::GLsizei)vertexInfoLog.length(), &infoLogLength, &(vertexInfoLog[0]));
140                         GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to get vertex shader compile info");
141
142                         vertexInfoLog.resize(infoLogLength);
143                 }
144
145                 {
146                         deInt32         infoLogLength = 0;
147
148                         gl.getShaderiv(fragmentShader, GL_COMPILE_STATUS, &fragmentCompileStatus);
149                         gl.getShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &infoLogLength);
150
151                         fragmentInfoLog.resize(infoLogLength, '\0');
152
153                         gl.getShaderInfoLog(fragmentShader, (glw::GLsizei)fragmentInfoLog.length(), &infoLogLength, &(fragmentInfoLog[0]));
154                         GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to get fragment shader compile info");
155
156                         fragmentInfoLog.resize(infoLogLength);
157                 }
158
159                 gl.attachShader(program, vertexShader);
160                 gl.attachShader(program, fragmentShader);
161                 gl.linkProgram(program);
162                 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup program");
163
164                 {
165                         deInt32         infoLogLength = 0;
166
167                         gl.getProgramiv(program, GL_LINK_STATUS, &linkStatus);
168                         gl.getProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
169
170                         programInfoLog.resize(infoLogLength, '\0');
171
172                         gl.getProgramInfoLog(program, (glw::GLsizei)programInfoLog.length(), &infoLogLength, &(programInfoLog[0]));
173                         GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to get program link info");
174
175                         programInfoLog.resize(infoLogLength);
176                 }
177
178                 if (linkStatus == 0 || vertexCompileStatus == 0 || fragmentCompileStatus == 0)
179                 {
180
181                         log.startShaderProgram(linkStatus != 0, programInfoLog.c_str());
182
183                         log << TestLog::Shader(QP_SHADER_TYPE_VERTEX, vertexShaderSource, vertexCompileStatus != 0, vertexInfoLog);
184                         log << TestLog::Shader(QP_SHADER_TYPE_FRAGMENT, fragmentShaderSource, fragmentCompileStatus != 0, fragmentInfoLog);
185
186                         log.endShaderProgram();
187                 }
188
189                 gl.deleteShader(vertexShader);
190                 gl.deleteShader(fragmentShader);
191                 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to delete shaders");
192
193                 TCU_CHECK(linkStatus != 0 && vertexCompileStatus != 0 && fragmentCompileStatus != 0);
194         }
195         catch (...)
196         {
197                 if (program)
198                         gl.deleteProgram(program);
199
200                 if (vertexShader)
201                         gl.deleteShader(vertexShader);
202
203                 if (fragmentShader)
204                         gl.deleteShader(fragmentShader);
205
206                 throw;
207         }
208
209         return program;
210 }
211
212 void clear (const glw::Functions& gl, const tcu::Vec4& color, int x, int y, int width, int height)
213 {
214         gl.enable(GL_SCISSOR_TEST);
215         gl.scissor(x, y, width, height);
216         gl.clearColor(color.x(), color.y(), color.z(), color.w());
217         gl.clear(GL_COLOR_BUFFER_BIT);
218         GLU_EXPECT_NO_ERROR(gl.getError(), "Color clear failed");
219 }
220
221 tcu::Vec2 toGLCoord (int width, int height, int x, int y)
222 {
223         const float xf = ((2.0f * float(x)) / (float)width)  - 1.0f;
224         const float yf = ((2.0f * float(y)) / (float)height) - 1.0f;
225
226         return tcu::Vec2(xf, yf);
227 }
228
229 void render (const glw::Functions& gl, deUint32 program, int targetWidth, int targetHeight, int x, int y, int width, int height)
230 {
231         const tcu::Vec2 positions[] =
232         {
233                 toGLCoord(targetWidth, targetHeight, x,                 y),
234                 toGLCoord(targetWidth, targetHeight, x+width,   y),
235                 toGLCoord(targetWidth, targetHeight, x+width,   y+height),
236
237                 toGLCoord(targetWidth, targetHeight, x+width,   y+height),
238                 toGLCoord(targetWidth, targetHeight, x,                 y+height),
239                 toGLCoord(targetWidth, targetHeight, x,                 y)
240         };
241
242         deUint32 posLocation;
243
244         gl.useProgram(program);
245         posLocation     = gl.getAttribLocation(program, "a_pos");
246         gl.enableVertexAttribArray(posLocation);
247         gl.vertexAttribPointer(posLocation, 2, GL_FLOAT, GL_FALSE, 0, positions);
248         GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup shader program for rendering");
249
250         gl.viewport(0, 0, targetWidth, targetHeight);
251         gl.drawArrays(GL_TRIANGLES, 0, 6);
252         GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to render");
253 }
254
255 bool compareColor (const tcu::Vec4& a, const tcu::Vec4& b)
256 {
257         const float threshold = 0.005f;
258
259         return deFloatAbs(a.x() - b.x()) < threshold &&  deFloatAbs(a.y() - b.y()) < threshold && deFloatAbs(a.z() - b.z()) < threshold && deFloatAbs(a.w() - b.w()) < threshold;
260 }
261
262 bool validate (TestLog& log, const tcu::TextureLevel& result, int rectX, int rectY, int rectW, int rectH)
263 {
264         const tcu::Vec4         black           (0.0f, 0.0f, 0.0f, 1.0f);
265         const tcu::Vec4         white           (1.0f, 1.0f, 1.0f, 1.0f);
266         tcu::Surface            errorMask       (result.getWidth(), result.getHeight());
267         bool                            isOk            = true;
268
269         for (int y = 0; y < result.getHeight(); y++)
270         {
271                 for (int x = 0; x < result.getWidth(); x++)
272                 {
273                         const tcu::Vec4 resultColor = result.getAccess().getPixel(x, y);
274
275                         if (x > rectX && x < rectX + rectW - 1 && y > rectY && y < rectY + rectH - 1)
276                         {
277                                 if (!compareColor(resultColor, white))
278                                 {
279                                         errorMask.setPixel(x, y, tcu::RGBA(255, 0, 0, 255));
280                                         isOk = false;
281                                 }
282                                 else
283                                         errorMask.setPixel(x, y, tcu::RGBA(0, 255, 0, 255));
284                         }
285                         else if (x < rectX-1 || x > rectX + rectW || y < rectY-1 || y > rectY + rectH)
286                         {
287                                 if (!compareColor(resultColor, black))
288                                 {
289                                         errorMask.setPixel(x, y, tcu::RGBA(255, 0, 0, 255));
290                                         isOk = false;
291                                 }
292                                 else
293                                         errorMask.setPixel(x, y, tcu::RGBA(0, 255, 0, 255));
294                         }
295                         else
296                         {
297                                 // Pixel is close to edge of reference rectangle
298
299                                 if (!compareColor(resultColor, black) && !compareColor(resultColor, white))
300                                 {
301                                         errorMask.setPixel(x, y, tcu::RGBA(255, 0, 0, 255));
302                                         isOk = false;
303                                 }
304                                 else
305                                         errorMask.setPixel(x, y, tcu::RGBA(0, 255, 0, 255));
306                         }
307                 }
308         }
309
310         log << TestLog::Image("Result", "Result of rendering", result.getAccess());
311
312         if (!isOk)
313                 log << TestLog::Image("Error Mask", "Error Mask", errorMask.getAccess());
314
315         return isOk;
316 }
317
318 class NativeCoordMappingCase : public SimpleConfigCase
319 {
320 public:
321         enum NativeType
322         {
323                 NATIVETYPE_WINDOW = 0,
324                 NATIVETYPE_PIXMAP,
325                 NATIVETYPE_PBUFFER_COPY_TO_PIXMAP
326         };
327
328                                 NativeCoordMappingCase  (EglTestContext& eglTestCtx, const char* name, const char* description, bool render, NativeType nativeType, const eglu::FilterList& filters);
329                                 ~NativeCoordMappingCase (void);
330
331 private:
332         void            executeForConfig                (EGLDisplay display, EGLConfig config);
333
334         NativeType      m_nativeType;
335         bool            m_render;
336 };
337
338 NativeCoordMappingCase::NativeCoordMappingCase (EglTestContext& eglTestCtx, const char* name, const char* description, bool render, NativeType nativeType, const eglu::FilterList& filters)
339         : SimpleConfigCase      (eglTestCtx, name, description, filters)
340         , m_nativeType          (nativeType)
341         , m_render                      (render)
342 {
343 }
344
345 NativeCoordMappingCase::~NativeCoordMappingCase (void)
346 {
347         deinit();
348 }
349
350 void logConfigInfo (TestLog& log, const Library& egl, EGLDisplay display, EGLConfig config, NativeCoordMappingCase::NativeType nativeType, int waitFrames)
351 {
352         log << TestLog::Message << "EGL_RED_SIZE: "             << eglu::getConfigAttribInt(egl, display, config, EGL_RED_SIZE)         << TestLog::EndMessage;
353         log << TestLog::Message << "EGL_GREEN_SIZE: "   << eglu::getConfigAttribInt(egl, display, config, EGL_GREEN_SIZE)       << TestLog::EndMessage;
354         log << TestLog::Message << "EGL_BLUE_SIZE: "    << eglu::getConfigAttribInt(egl, display, config, EGL_BLUE_SIZE)        << TestLog::EndMessage;
355         log << TestLog::Message << "EGL_ALPHA_SIZE: "   << eglu::getConfigAttribInt(egl, display, config, EGL_ALPHA_SIZE)       << TestLog::EndMessage;
356         log << TestLog::Message << "EGL_DEPTH_SIZE: "   << eglu::getConfigAttribInt(egl, display, config, EGL_DEPTH_SIZE)       << TestLog::EndMessage;
357         log << TestLog::Message << "EGL_STENCIL_SIZE: " << eglu::getConfigAttribInt(egl, display, config, EGL_STENCIL_SIZE)     << TestLog::EndMessage;
358         log << TestLog::Message << "EGL_SAMPLES: "              << eglu::getConfigAttribInt(egl, display, config, EGL_SAMPLES)          << TestLog::EndMessage;
359
360         if (nativeType == NativeCoordMappingCase::NATIVETYPE_WINDOW)
361                 log << TestLog::Message << "Waiting " << waitFrames * 16 << "ms after eglSwapBuffers() and glFinish() for frame to become visible" << TestLog::EndMessage;
362 }
363
364 bool testNativeWindow (TestLog& log, eglu::NativeDisplay& nativeDisplay, eglu::NativeWindow& nativeWindow, EGLDisplay display, EGLContext context, EGLConfig config, const glw::Functions& gl, bool renderColor, int waitFrames)
365 {
366         const int                       rectX           = 8;
367         const int                       rectY           = 16;
368         const int                       rectW           = 64;
369         const int                       rectH           = 72;
370
371         const Library&          egl                     = nativeDisplay.getLibrary();
372         const tcu::IVec2        screenSize      = nativeWindow.getScreenSize();
373         eglu::UniqueSurface     surface         (egl, display, eglu::createWindowSurface(nativeDisplay, nativeWindow, display, config, DE_NULL));
374         const tcu::IVec2        surfaceSize = eglu::getSurfaceSize(egl, display, *surface);
375         deUint32                        program         = 0;
376         bool                            isOk            = true;
377         tcu::TextureLevel       result;
378
379         try
380         {
381                 EGLU_CHECK_CALL(egl, makeCurrent(display, *surface, *surface, context));
382
383                 if (renderColor)
384                         program = createGLES2Program(gl, log);
385
386                 clear(gl, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), 0, 0, surfaceSize.x(), surfaceSize.y());
387
388                 if (renderColor)
389                         render(gl, program, surfaceSize.x(), surfaceSize.y(), rectX, rectY, rectW, rectH);
390                 else
391                         clear(gl, tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), rectX, rectY, rectW, rectH);
392
393                 EGLU_CHECK_CALL(egl, swapBuffers(display, *surface));
394                 EGLU_CHECK_CALL(egl, waitClient());
395                 deSleep(waitFrames*16);
396                 nativeWindow.readScreenPixels(&result);
397
398                 if (!validate(log, result, rectX, screenSize.y() - rectY - rectH, rectW, rectH))
399                         isOk = false;
400
401                 EGLU_CHECK_CALL(egl, makeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
402         }
403         catch (...)
404         {
405                 if (program)
406                         gl.deleteProgram(program);
407                 throw;
408         }
409
410         return isOk;
411 }
412
413 bool testNativePixmap (TestLog& log, eglu::NativeDisplay& nativeDisplay, eglu::NativePixmap& nativePixmap, int width, int height, EGLDisplay display, EGLContext context, EGLConfig config, const glw::Functions& gl, bool renderColor)
414 {
415         const int                       rectX           = 8;
416         const int                       rectY           = 16;
417         const int                       rectW           = 64;
418         const int                       rectH           = 72;
419
420         const Library&          egl                     = nativeDisplay.getLibrary();
421         eglu::UniqueSurface     surface         (egl, display, eglu::createPixmapSurface(nativeDisplay, nativePixmap, display, config, DE_NULL));
422         deUint32                        program         = 0;
423         bool                            isOk            = true;
424         tcu::TextureLevel       result;
425
426         try
427         {
428                 EGLU_CHECK_CALL(egl, makeCurrent(display, *surface, *surface, context));
429
430                 if (renderColor)
431                         program = createGLES2Program(gl, log);
432
433                 clear(gl, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), 0, 0, width, height);
434
435                 if (renderColor)
436                         render(gl, program, width, height, rectX, rectY, rectW, rectH);
437                 else
438                         clear(gl, tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), rectX, rectY, rectW, rectH);
439
440                 EGLU_CHECK_CALL(egl, waitClient());
441                 nativePixmap.readPixels(&result);
442
443                 if (!validate(log, result, rectX, height - 1 - rectY - rectH, rectW, rectH))
444                         isOk = false;
445
446                 EGLU_CHECK_CALL(egl, makeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
447         }
448         catch (...)
449         {
450                 if (program)
451                         gl.deleteProgram(program);
452                 throw;
453         }
454
455         return isOk;
456 }
457
458 bool testNativePixmapCopy (TestLog& log, const Library& egl, eglu::NativePixmap& nativePixmap, int width, int height, EGLDisplay display, EGLContext context, EGLConfig config, const glw::Functions& gl, bool renderColor)
459 {
460         const int                       rectX           = 8;
461         const int                       rectY           = 16;
462         const int                       rectW           = 64;
463         const int                       rectH           = 72;
464
465         eglu::UniqueSurface     surface         (egl, display, egl.createPbufferSurface(display, config, DE_NULL));
466         deUint32                        program         = 0;
467         bool                            isOk            = true;
468         tcu::TextureLevel       result;
469
470         try
471         {
472                 EGLU_CHECK_CALL(egl, makeCurrent(display, *surface, *surface, context));
473
474                 if (renderColor)
475                         program = createGLES2Program(gl, log);
476
477                 clear(gl, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), 0, 0, width, height);
478
479                 if (renderColor)
480                         render(gl, program, width, height, rectX, rectY, rectW, rectH);
481                 else
482                         clear(gl, tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), rectX, rectY, rectW, rectH);
483
484                 EGLU_CHECK_CALL(egl, copyBuffers(display, *surface, nativePixmap.getLegacyNative()));
485                 EGLU_CHECK_CALL(egl, waitClient());
486                 nativePixmap.readPixels(&result);
487
488                 if (!validate(log, result, rectX, height - 1 - rectY, rectW, rectH))
489                         isOk = false;
490
491                 EGLU_CHECK_CALL(egl, makeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
492         }
493         catch (...)
494         {
495                 if (program)
496                         gl.deleteProgram(program);
497                 throw;
498         }
499
500         return isOk;
501 }
502
503 void NativeCoordMappingCase::executeForConfig (EGLDisplay display, EGLConfig config)
504 {
505         const Library&                                          egl                             = m_eglTestCtx.getLibrary();
506         const string                                            configIdStr             (de::toString(eglu::getConfigAttribInt(egl, display, config, EGL_CONFIG_ID)));
507         tcu::ScopedLogSection                           logSection              (m_testCtx.getLog(), ("Config ID " + configIdStr).c_str(), ("Config ID " + configIdStr).c_str());
508         const int                                                       waitFrames              = 5;
509         const int                                                       width                   = 128;
510         const int                                                       height                  = 128;
511         const eglu::NativeWindowFactory*        windowFactory;
512         const eglu::NativePixmapFactory*        pixmapFactory;
513
514         logConfigInfo(m_testCtx.getLog(), egl, display, config, m_nativeType, waitFrames);
515
516         try
517         {
518                 windowFactory = &eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
519
520                 if ((windowFactory->getCapabilities() & eglu::NativeWindow::CAPABILITY_READ_SCREEN_PIXELS) == 0)
521                         TCU_THROW(NotSupportedError, "Native window doesn't support readPixels()");
522         }
523         catch (const tcu::NotSupportedError&)
524         {
525                 if (m_nativeType == NATIVETYPE_WINDOW)
526                         throw;
527                 else
528                         windowFactory = DE_NULL;
529         }
530
531         try
532         {
533                 pixmapFactory = &eglu::selectNativePixmapFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
534
535                 if (m_nativeType == NATIVETYPE_PIXMAP)
536                 {
537                         if ((pixmapFactory->getCapabilities() & eglu::NativePixmap::CAPABILITY_READ_PIXELS) == 0)
538                                 TCU_THROW(NotSupportedError, "Native pixmap doesn't support readPixels()");
539                 }
540                 else if (m_nativeType == NATIVETYPE_PBUFFER_COPY_TO_PIXMAP)
541                 {
542                         if ((pixmapFactory->getCapabilities() & eglu::NativePixmap::CAPABILITY_READ_PIXELS) == 0 ||
543                                 (pixmapFactory->getCapabilities() & eglu::NativePixmap::CAPABILITY_CREATE_SURFACE_LEGACY) == 0)
544                                 TCU_THROW(NotSupportedError, "Native pixmap doesn't support readPixels() or legacy create surface");
545                 }
546         }
547         catch (const tcu::NotSupportedError&)
548         {
549                 if (m_nativeType == NATIVETYPE_PIXMAP || m_nativeType == NATIVETYPE_PBUFFER_COPY_TO_PIXMAP)
550                         throw;
551                 else
552                         pixmapFactory = DE_NULL;
553         }
554
555         DE_ASSERT(m_nativeType != NATIVETYPE_WINDOW || windowFactory);
556         DE_ASSERT((m_nativeType != NATIVETYPE_PIXMAP && m_nativeType != NATIVETYPE_PBUFFER_COPY_TO_PIXMAP) || pixmapFactory);
557
558         eglu::UniqueContext     context         (egl, display, createGLES2Context(egl, display, config));
559         glw::Functions                  gl;
560
561         m_eglTestCtx.initGLFunctions(&gl, glu::ApiType::es(2,0));
562
563         switch (m_nativeType)
564         {
565                 case NATIVETYPE_WINDOW:
566                 {
567                         de::UniquePtr<eglu::NativeWindow>       nativeWindow    (windowFactory->createWindow(&m_eglTestCtx.getNativeDisplay(), display, config, DE_NULL, eglu::WindowParams(width, height, eglu::WindowParams::VISIBILITY_VISIBLE)));
568
569                         if (!testNativeWindow(m_testCtx.getLog(), m_eglTestCtx.getNativeDisplay(), *nativeWindow, display, *context, config, gl, m_render, waitFrames))
570                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid color rendered");
571
572                         break;
573                 }
574
575                 case NATIVETYPE_PIXMAP:
576                 {
577                         de::UniquePtr<eglu::NativePixmap> nativePixmap          (pixmapFactory->createPixmap(&m_eglTestCtx.getNativeDisplay(), display, config, DE_NULL, width, height));
578
579                         if (!testNativePixmap(m_testCtx.getLog(), m_eglTestCtx.getNativeDisplay(), *nativePixmap, width, height, display, *context, config, gl, m_render))
580                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid color rendered");
581
582                         break;
583                 }
584
585                 case NATIVETYPE_PBUFFER_COPY_TO_PIXMAP:
586                 {
587                         de::UniquePtr<eglu::NativePixmap> nativePixmap          (pixmapFactory->createPixmap(&m_eglTestCtx.getNativeDisplay(), display, config, DE_NULL, width, height));
588
589                         if (!testNativePixmapCopy(m_testCtx.getLog(), egl, *nativePixmap, width, height, display, *context, config, gl, m_render))
590                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid color rendered");
591
592                         break;
593                 }
594
595                 default:
596                         DE_ASSERT(DE_FALSE);
597         }
598 }
599
600 template <deUint32 Type>
601 static bool surfaceType (const eglu::CandidateConfig& c)
602 {
603         return (c.surfaceType() & Type) == Type;
604 }
605
606 void addTestGroups (EglTestContext& eglTestCtx, TestCaseGroup* group, NativeCoordMappingCase::NativeType type)
607 {
608         eglu::FilterList baseFilters;
609
610         switch (type)
611         {
612                 case NativeCoordMappingCase::NATIVETYPE_WINDOW:
613                         baseFilters << surfaceType<EGL_WINDOW_BIT>;
614                         break;
615
616                 case NativeCoordMappingCase::NATIVETYPE_PIXMAP:
617                         baseFilters << surfaceType<EGL_PIXMAP_BIT>;
618                         break;
619
620                 case NativeCoordMappingCase::NATIVETYPE_PBUFFER_COPY_TO_PIXMAP:
621                         baseFilters << surfaceType<EGL_PBUFFER_BIT>;
622                         break;
623
624                 default:
625                         DE_ASSERT(DE_FALSE);
626         }
627
628         vector<NamedFilterList> filterLists;
629         getDefaultFilterLists(filterLists, baseFilters);
630
631         for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
632         {
633                 group->addChild(new NativeCoordMappingCase(eglTestCtx, (string(i->getName()) + "_clear").c_str(), i->getDescription(), false, type, *i));
634                 group->addChild(new NativeCoordMappingCase(eglTestCtx, (string(i->getName()) + "_render").c_str(), i->getDescription(), true, type, *i));
635         }
636 }
637
638 } // anonymous
639
640 NativeCoordMappingTests::NativeCoordMappingTests (EglTestContext& eglTestCtx)
641         : TestCaseGroup(eglTestCtx, "native_coord_mapping", "Tests for mapping client coordinates to native surface")
642 {
643 }
644
645 void NativeCoordMappingTests::init (void)
646 {
647         {
648                 TestCaseGroup* windowGroup = new TestCaseGroup(m_eglTestCtx, "native_window", "Tests for mapping client color to native window");
649                 addTestGroups(m_eglTestCtx, windowGroup, NativeCoordMappingCase::NATIVETYPE_WINDOW);
650                 addChild(windowGroup);
651         }
652
653         {
654                 TestCaseGroup* pixmapGroup = new TestCaseGroup(m_eglTestCtx, "native_pixmap", "Tests for mapping client color to native pixmap");
655                 addTestGroups(m_eglTestCtx, pixmapGroup, NativeCoordMappingCase::NATIVETYPE_PIXMAP);
656                 addChild(pixmapGroup);
657         }
658
659         {
660                 TestCaseGroup* pbufferGroup = new TestCaseGroup(m_eglTestCtx, "pbuffer_to_native_pixmap", "Tests for mapping client color to native pixmap with eglCopyBuffers()");
661                 addTestGroups(m_eglTestCtx, pbufferGroup, NativeCoordMappingCase::NATIVETYPE_PBUFFER_COPY_TO_PIXMAP);
662                 addChild(pbufferGroup);
663         }
664 }
665
666 } // egl
667 } // deqp