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 EGL image tests.
22 *//*--------------------------------------------------------------------*/
23
24 #include "teglImageFormatTests.hpp"
25
26 #include "deStringUtil.hpp"
27 #include "deSTLUtil.hpp"
28
29 #include "tcuTestLog.hpp"
30 #include "tcuSurface.hpp"
31 #include "tcuTexture.hpp"
32 #include "tcuTextureUtil.hpp"
33 #include "tcuImageCompare.hpp"
34 #include "tcuCommandLine.hpp"
35
36 #include "egluNativeDisplay.hpp"
37 #include "egluNativeWindow.hpp"
38 #include "egluNativePixmap.hpp"
39 #include "egluConfigFilter.hpp"
40 #include "egluUnique.hpp"
41 #include "egluUtil.hpp"
42
43 #include "eglwLibrary.hpp"
44 #include "eglwEnums.hpp"
45
46 #include "gluCallLogWrapper.hpp"
47 #include "gluShaderProgram.hpp"
48 #include "gluStrUtil.hpp"
49 #include "gluTexture.hpp"
50 #include "gluPixelTransfer.hpp"
51 #include "gluObjectWrapper.hpp"
52 #include "gluTextureUtil.hpp"
53
54 #include "glwEnums.hpp"
55 #include "glwFunctions.hpp"
56
57 #include "teglImageUtil.hpp"
58 #include "teglAndroidUtil.hpp"
59
60 #include <vector>
61 #include <string>
62 #include <set>
63
64 using std::set;
65 using std::string;
66 using std::vector;
67
68 using de::MovePtr;
69 using de::UniquePtr;
70
71 using glu::Framebuffer;
72 using glu::Renderbuffer;
73 using glu::Texture;
74
75 using eglu::UniqueImage;
76
77 using tcu::ConstPixelBufferAccess;
78
79 using namespace glw;
80 using namespace eglw;
81
82 namespace deqp
83 {
84 namespace egl
85 {
86
87 namespace
88 {
89
programSources(const string & vertexSource,const string & fragmentSource)90 glu::ProgramSources programSources(const string &vertexSource, const string &fragmentSource)
91 {
92 glu::ProgramSources sources;
93
94 sources << glu::VertexSource(vertexSource) << glu::FragmentSource(fragmentSource);
95
96 return sources;
97 }
98
99 class Program : public glu::ShaderProgram
100 {
101 public:
Program(const glw::Functions & gl,const char * vertexSource,const char * fragmentSource)102 Program(const glw::Functions &gl, const char *vertexSource, const char *fragmentSource)
103 : glu::ShaderProgram(gl, programSources(vertexSource, fragmentSource))
104 {
105 }
106 };
107
108 } // namespace
109
110 namespace Image
111 {
112
113 class ImageApi;
114
115 class IllegalRendererException : public std::exception
116 {
117 };
118
119 class Action
120 {
121 public:
~Action(void)122 virtual ~Action(void)
123 {
124 }
125 virtual bool invoke(ImageApi &api, MovePtr<UniqueImage> &image, tcu::Texture2D &refImg) const = 0;
126 virtual string getRequiredExtension(void) const = 0;
127 };
128
129 struct TestSpec
130 {
131 std::string name;
132 std::string desc;
133
134 enum ApiContext
135 {
136 API_GLES2 = 0,
137 API_GLES3,
138 //API_VG
139 //API_GLES1
140
141 API_LAST
142 };
143
144 struct Operation
145 {
Operationdeqp::egl::Image::TestSpec::Operation146 Operation(int apiIndex_, const Action &action_) : apiIndex(apiIndex_), action(&action_)
147 {
148 }
149 int apiIndex;
150 const Action *action;
151 };
152
153 vector<ApiContext> contexts;
154 vector<Operation> operations;
155 };
156
157 class ImageApi
158 {
159 public:
160 ImageApi(const Library &egl, int contextId, EGLDisplay display, EGLSurface surface);
~ImageApi(void)161 virtual ~ImageApi(void)
162 {
163 }
164
165 protected:
166 const Library &m_egl;
167 int m_contextId;
168 EGLDisplay m_display;
169 EGLSurface m_surface;
170 };
171
ImageApi(const Library & egl,int contextId,EGLDisplay display,EGLSurface surface)172 ImageApi::ImageApi(const Library &egl, int contextId, EGLDisplay display, EGLSurface surface)
173 : m_egl(egl)
174 , m_contextId(contextId)
175 , m_display(display)
176 , m_surface(surface)
177 {
178 }
179
180 class GLESImageApi : public ImageApi, private glu::CallLogWrapper
181 {
182 public:
183 class GLESAction : public Action
184 {
185 public:
186 bool invoke(ImageApi &api, MovePtr<UniqueImage> &image, tcu::Texture2D &ref) const;
187 virtual bool invokeGLES(GLESImageApi &api, MovePtr<UniqueImage> &image, tcu::Texture2D &ref) const = 0;
188 };
189
190 class Create : public GLESAction
191 {
192 public:
Create(MovePtr<ImageSource> imgSource,uint32_t numLayers=1u)193 Create(MovePtr<ImageSource> imgSource, uint32_t numLayers = 1u) : m_imgSource(imgSource), m_numLayers(numLayers)
194 {
195 }
getRequiredExtension(void) const196 string getRequiredExtension(void) const
197 {
198 return m_imgSource->getRequiredExtension();
199 }
200 bool invokeGLES(GLESImageApi &api, MovePtr<UniqueImage> &image, tcu::Texture2D &ref) const;
getNumLayers(void) const201 uint32_t getNumLayers(void) const
202 {
203 return m_numLayers;
204 }
getEffectiveFormat(void) const205 glw::GLenum getEffectiveFormat(void) const
206 {
207 return m_imgSource->getEffectiveFormat();
208 }
isYUVFormatImage(void) const209 bool isYUVFormatImage(void) const
210 {
211 return m_imgSource->isYUVFormatImage();
212 }
213
214 private:
215 UniquePtr<ImageSource> m_imgSource;
216 uint32_t m_numLayers;
217 };
218
219 class Render : public GLESAction
220 {
221 public:
getRequiredExtension(void) const222 virtual string getRequiredExtension(void) const
223 {
224 return "GL_OES_EGL_image";
225 }
226 };
227
228 class RenderTexture2D : public Render
229 {
230 public:
231 bool invokeGLES(GLESImageApi &api, MovePtr<UniqueImage> &image, tcu::Texture2D &ref) const override;
232 };
233 class RenderTextureCubemap : public Render
234 {
235 public:
236 bool invokeGLES(GLESImageApi &api, MovePtr<UniqueImage> &image, tcu::Texture2D &ref) const override;
237 };
238 class RenderReadPixelsRenderbuffer : public Render
239 {
240 public:
241 bool invokeGLES(GLESImageApi &api, MovePtr<UniqueImage> &image, tcu::Texture2D &ref) const override;
242 };
243 class RenderDepthbuffer : public Render
244 {
245 public:
246 bool invokeGLES(GLESImageApi &api, MovePtr<UniqueImage> &image, tcu::Texture2D &ref) const override;
247 };
248 class RenderStencilbuffer : public Render
249 {
250 public:
251 bool invokeGLES(GLESImageApi &api, MovePtr<UniqueImage> &image, tcu::Texture2D &ref) const override;
252 };
253 class RenderTryAll : public Render
254 {
255 public:
256 bool invokeGLES(GLESImageApi &api, MovePtr<UniqueImage> &image, tcu::Texture2D &ref) const override;
257 };
258
259 class RenderTexture2DArray : public Render
260 {
261 public:
262 bool invokeGLES(GLESImageApi &api, MovePtr<UniqueImage> &image, tcu::Texture2D &ref) const override;
getRequiredExtension(void) const263 string getRequiredExtension(void) const override
264 {
265 return "GL_EXT_EGL_image_array";
266 }
267 };
268
269 class RenderExternalTexture : public Render
270 {
271 public:
272 bool invokeGLES(GLESImageApi &api, MovePtr<UniqueImage> &image, tcu::Texture2D &ref) const override;
getRequiredExtension(void) const273 string getRequiredExtension(void) const override
274 {
275 return "GL_OES_EGL_image_external";
276 }
277 };
278
279 class RenderExternalTextureSamplerArray : public Render
280 {
281 public:
282 bool invokeGLES(GLESImageApi &api, MovePtr<UniqueImage> &image, tcu::Texture2D &ref) const override;
getRequiredExtension(void) const283 string getRequiredExtension(void) const override
284 {
285 return "GL_OES_EGL_image_external";
286 }
287 };
288 class RenderYUVTexture : public Render
289 {
290 public:
291 bool invokeGLES(GLESImageApi &api, MovePtr<UniqueImage> &image, tcu::Texture2D &ref) const override;
getRequiredExtension(void) const292 string getRequiredExtension(void) const override
293 {
294 return "GL_EXT_YUV_target";
295 }
296 };
297 class RenderSampleTexture2DArray : public RenderTexture2DArray
298 {
299 public:
300 bool invokeGLES(GLESImageApi &api, MovePtr<UniqueImage> &image, tcu::Texture2D &ref) const override;
getRequiredExtension(void) const301 string getRequiredExtension(void) const override
302 {
303 return "GL_EXT_EGL_image_array";
304 }
305 };
306 class Modify : public GLESAction
307 {
308 public:
getRequiredExtension(void) const309 string getRequiredExtension(void) const
310 {
311 return "GL_OES_EGL_image";
312 }
313 };
314
315 class ModifyTexSubImage : public Modify
316 {
317 public:
ModifyTexSubImage(GLenum format,GLenum type)318 ModifyTexSubImage(GLenum format, GLenum type) : m_format(format), m_type(type)
319 {
320 }
321 bool invokeGLES(GLESImageApi &api, MovePtr<UniqueImage> &image, tcu::Texture2D &ref) const;
getFormat(void) const322 GLenum getFormat(void) const
323 {
324 return m_format;
325 }
getType(void) const326 GLenum getType(void) const
327 {
328 return m_type;
329 }
330
331 private:
332 GLenum m_format;
333 GLenum m_type;
334 };
335
336 class ModifyRenderbuffer : public Modify
337 {
338 public:
339 bool invokeGLES(GLESImageApi &api, MovePtr<UniqueImage> &image, tcu::Texture2D &ref) const;
340
341 protected:
342 virtual void initializeRbo(GLESImageApi &api, GLuint rbo, tcu::Texture2D &ref) const = 0;
343 };
344
345 class ModifyRenderbufferClearColor : public ModifyRenderbuffer
346 {
347 public:
ModifyRenderbufferClearColor(tcu::Vec4 color)348 ModifyRenderbufferClearColor(tcu::Vec4 color) : m_color(color)
349 {
350 }
351
352 protected:
353 void initializeRbo(GLESImageApi &api, GLuint rbo, tcu::Texture2D &ref) const;
354
355 tcu::Vec4 m_color;
356 };
357
358 class ModifyRenderbufferClearDepth : public ModifyRenderbuffer
359 {
360 public:
ModifyRenderbufferClearDepth(GLfloat depth)361 ModifyRenderbufferClearDepth(GLfloat depth) : m_depth(depth)
362 {
363 }
364
365 protected:
366 void initializeRbo(GLESImageApi &api, GLuint rbo, tcu::Texture2D &ref) const;
367
368 GLfloat m_depth;
369 };
370
371 class ModifyRenderbufferClearStencil : public ModifyRenderbuffer
372 {
373 public:
ModifyRenderbufferClearStencil(GLint stencil)374 ModifyRenderbufferClearStencil(GLint stencil) : m_stencil(stencil)
375 {
376 }
377
378 protected:
379 void initializeRbo(GLESImageApi &api, GLuint rbo, tcu::Texture2D &ref) const;
380
381 GLint m_stencil;
382 };
383
384 GLESImageApi(const Library &egl, const glw::Functions &gl, int contextId, tcu::TestLog &log, EGLDisplay display,
385 EGLSurface surface, EGLConfig config, EGLint apiVersion);
386 ~GLESImageApi(void);
387
388 private:
389 EGLContext m_context;
390 const glw::Functions &m_gl;
391
392 MovePtr<UniqueImage> createImage(const ImageSource &source, const ClientBuffer &buffer) const;
393 };
394
GLESImageApi(const Library & egl,const glw::Functions & gl,int contextId,tcu::TestLog & log,EGLDisplay display,EGLSurface surface,EGLConfig config,EGLint apiVersion)395 GLESImageApi::GLESImageApi(const Library &egl, const glw::Functions &gl, int contextId, tcu::TestLog &log,
396 EGLDisplay display, EGLSurface surface, EGLConfig config, EGLint apiVersion)
397 : ImageApi(egl, contextId, display, surface)
398 , glu::CallLogWrapper(gl, log)
399 , m_context(DE_NULL)
400 , m_gl(gl)
401 {
402 const EGLint attriblist[] = {EGL_CONTEXT_CLIENT_VERSION, apiVersion, EGL_NONE};
403
404 EGLint configId = -1;
405 EGLU_CHECK_CALL(m_egl, getConfigAttrib(m_display, config, EGL_CONFIG_ID, &configId));
406 getLog() << tcu::TestLog::Message << "Creating gles" << apiVersion << " context with config id: " << configId
407 << " context: " << m_contextId << tcu::TestLog::EndMessage;
408 egl.bindAPI(EGL_OPENGL_ES_API);
409 m_context = m_egl.createContext(m_display, config, EGL_NO_CONTEXT, attriblist);
410 EGLU_CHECK_MSG(m_egl, "Failed to create GLES context");
411
412 egl.makeCurrent(display, m_surface, m_surface, m_context);
413 EGLU_CHECK_MSG(m_egl, "Failed to make context current");
414 }
415
~GLESImageApi(void)416 GLESImageApi::~GLESImageApi(void)
417 {
418 m_egl.makeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
419 m_egl.destroyContext(m_display, m_context);
420 }
421
invoke(ImageApi & api,MovePtr<UniqueImage> & image,tcu::Texture2D & ref) const422 bool GLESImageApi::GLESAction::invoke(ImageApi &api, MovePtr<UniqueImage> &image, tcu::Texture2D &ref) const
423 {
424 GLESImageApi &glesApi = dynamic_cast<GLESImageApi &>(api);
425
426 glesApi.m_egl.makeCurrent(glesApi.m_display, glesApi.m_surface, glesApi.m_surface, glesApi.m_context);
427 return invokeGLES(glesApi, image, ref);
428 }
429
invokeGLES(GLESImageApi & api,MovePtr<UniqueImage> & image,tcu::Texture2D & ref) const430 bool GLESImageApi::Create::invokeGLES(GLESImageApi &api, MovePtr<UniqueImage> &image, tcu::Texture2D &ref) const
431 {
432 de::UniquePtr<ClientBuffer> buffer(m_imgSource->createBuffer(api.m_egl, api.m_gl, &ref));
433
434 GLU_CHECK_GLW_CALL(api.m_gl, finish());
435
436 image = api.createImage(*m_imgSource, *buffer);
437 return true;
438 }
439
createImage(const ImageSource & source,const ClientBuffer & buffer) const440 MovePtr<UniqueImage> GLESImageApi::createImage(const ImageSource &source, const ClientBuffer &buffer) const
441 {
442 const EGLImageKHR image = source.createImage(m_egl, m_display, m_context, buffer.get());
443 return MovePtr<UniqueImage>(new UniqueImage(m_egl, m_display, image));
444 }
445
imageTargetTexture2D(const Library & egl,const glw::Functions & gl,GLeglImageOES img)446 static void imageTargetTexture2D(const Library &egl, const glw::Functions &gl, GLeglImageOES img)
447 {
448 gl.eglImageTargetTexture2DOES(GL_TEXTURE_2D, img);
449 {
450 const GLenum error = gl.getError();
451
452 if (error == GL_INVALID_OPERATION)
453 TCU_THROW(NotSupportedError, "Creating texture2D from EGLImage type not supported");
454
455 GLU_EXPECT_NO_ERROR(error, "glEGLImageTargetTexture2DOES()");
456 EGLU_CHECK_MSG(egl, "glEGLImageTargetTexture2DOES()");
457 }
458 }
459
imageTargetExternalTexture(const Library & egl,const glw::Functions & gl,GLeglImageOES img)460 static void imageTargetExternalTexture(const Library &egl, const glw::Functions &gl, GLeglImageOES img)
461 {
462 gl.eglImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, img);
463 {
464 const GLenum error = gl.getError();
465
466 if (error == GL_INVALID_OPERATION)
467 TCU_THROW(NotSupportedError, "Creating external texture from EGLImage type not supported");
468
469 GLU_EXPECT_NO_ERROR(error, "glEGLImageTargetTexture2DOES()");
470 EGLU_CHECK_MSG(egl, "glEGLImageTargetTexture2DOES()");
471 }
472 }
473
imageTargetTexture2DArray(const Library & egl,const glw::Functions & gl,GLeglImageOES img)474 static void imageTargetTexture2DArray(const Library &egl, const glw::Functions &gl, GLeglImageOES img)
475 {
476 gl.eglImageTargetTexture2DOES(GL_TEXTURE_2D_ARRAY, img);
477 {
478 const GLenum error = gl.getError();
479
480 if (error == GL_INVALID_OPERATION)
481 TCU_THROW(NotSupportedError, "Creating texture2D array from EGLImage type not supported");
482
483 GLU_EXPECT_NO_ERROR(error, "glEGLImageTargetTexture2DOES()");
484 EGLU_CHECK_MSG(egl, "glEGLImageTargetTexture2DOES()");
485 }
486 }
487
imageTargetRenderbuffer(const Library & egl,const glw::Functions & gl,GLeglImageOES img)488 static void imageTargetRenderbuffer(const Library &egl, const glw::Functions &gl, GLeglImageOES img)
489 {
490 gl.eglImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, img);
491 {
492 const GLenum error = gl.getError();
493
494 if (error == GL_INVALID_OPERATION)
495 TCU_THROW(NotSupportedError, "Creating renderbuffer from EGLImage type not supported");
496
497 GLU_EXPECT_NO_ERROR(error, "glEGLImageTargetRenderbufferStorageOES()");
498 EGLU_CHECK_MSG(egl, "glEGLImageTargetRenderbufferStorageOES()");
499 }
500 }
501
framebufferRenderbuffer(const glw::Functions & gl,GLenum attachment,GLuint rbo)502 static void framebufferRenderbuffer(const glw::Functions &gl, GLenum attachment, GLuint rbo)
503 {
504 GLU_CHECK_GLW_CALL(gl, framebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, rbo));
505 TCU_CHECK_AND_THROW(
506 NotSupportedError, gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE,
507 ("EGLImage as " + string(glu::getFramebufferAttachmentName(attachment)) + " not supported").c_str());
508 }
509
getSupportedExtensions(tcu::TestLog & log,const Library & egl,const EGLDisplay dpy,const glw::Functions gl)510 static set<string> getSupportedExtensions(tcu::TestLog &log, const Library &egl, const EGLDisplay dpy,
511 const glw::Functions gl)
512 {
513 set<string> exts;
514 const vector<string> glExts = de::splitString((const char *)gl.getString(GL_EXTENSIONS));
515 const vector<string> eglExts = eglu::getDisplayExtensions(egl, dpy);
516
517 exts.insert(glExts.begin(), glExts.end());
518 exts.insert(eglExts.begin(), eglExts.end());
519
520 if (eglu::getVersion(egl, dpy) >= eglu::Version(1, 5))
521 {
522 // EGL 1.5 has built-in support for EGLImage and GL sources
523 exts.insert("EGL_KHR_image_base");
524 exts.insert("EGL_KHR_gl_texture_2D_image");
525 exts.insert("EGL_KHR_gl_texture_cubemap_image");
526 exts.insert("EGL_KHR_gl_renderbuffer_image");
527 }
528
529 if (!de::contains(exts, "EGL_KHR_image_base") && !de::contains(exts, "EGL_KHR_image"))
530 {
531 log << tcu::TestLog::Message
532 << "EGL version is under 1.5 and neither EGL_KHR_image nor EGL_KHR_image_base is supported."
533 << "One should be supported." << tcu::TestLog::EndMessage;
534 TCU_THROW(NotSupportedError, "Extension not supported: EGL_KHR_image_base");
535 }
536
537 return exts;
538 }
539
540 static const float squareTriangleCoords[] = {-1.0, -1.0, 1.0, -1.0, 1.0, 1.0,
541
542 1.0, 1.0, -1.0, 1.0, -1.0, -1.0};
543
invokeGLES(GLESImageApi & api,MovePtr<UniqueImage> & img,tcu::Texture2D & reference) const544 bool GLESImageApi::RenderTexture2D::invokeGLES(GLESImageApi &api, MovePtr<UniqueImage> &img,
545 tcu::Texture2D &reference) const
546 {
547 const glw::Functions &gl = api.m_gl;
548 tcu::TestLog &log = api.getLog();
549 Texture srcTex(gl);
550
551 // Branch only taken in TryAll case
552 if (reference.getFormat().order == tcu::TextureFormat::DS || reference.getFormat().order == tcu::TextureFormat::D)
553 throw IllegalRendererException(); // Skip, GLES does not support sampling depth textures
554 if (reference.getFormat().order == tcu::TextureFormat::S)
555 throw IllegalRendererException(); // Skip, GLES does not support sampling stencil textures
556
557 gl.clearColor(0.0, 0.0, 0.0, 0.0);
558 gl.viewport(0, 0, reference.getWidth(), reference.getHeight());
559 gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
560 gl.disable(GL_DEPTH_TEST);
561
562 log << tcu::TestLog::Message << "Rendering EGLImage as GL_TEXTURE_2D in context: " << api.m_contextId
563 << tcu::TestLog::EndMessage;
564 TCU_CHECK(**img != EGL_NO_IMAGE_KHR);
565
566 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, *srcTex));
567 imageTargetTexture2D(api.m_egl, gl, **img);
568
569 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
570 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
571 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
572 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
573
574 const char *const vertexShader = "attribute highp vec2 a_coord;\n"
575 "varying mediump vec2 v_texCoord;\n"
576 "void main(void) {\n"
577 "\tv_texCoord = vec2((a_coord.x + 1.0) * 0.5, (a_coord.y + 1.0) * 0.5);\n"
578 "\tgl_Position = vec4(a_coord, -0.1, 1.0);\n"
579 "}\n";
580
581 const char *const fragmentShader = "varying mediump vec2 v_texCoord;\n"
582 "uniform sampler2D u_sampler;\n"
583 "void main(void) {\n"
584 "\tmediump vec4 texColor = texture2D(u_sampler, v_texCoord);\n"
585 "\tgl_FragColor = vec4(texColor);\n"
586 "}";
587
588 Program program(gl, vertexShader, fragmentShader);
589 TCU_CHECK(program.isOk());
590
591 GLuint glProgram = program.getProgram();
592 GLU_CHECK_GLW_CALL(gl, useProgram(glProgram));
593
594 GLuint coordLoc = gl.getAttribLocation(glProgram, "a_coord");
595 TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute a_coord");
596
597 GLuint samplerLoc = gl.getUniformLocation(glProgram, "u_sampler");
598 TCU_CHECK_MSG((int)samplerLoc != (int)-1, "Couldn't find uniform u_sampler");
599
600 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, *srcTex));
601 GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc, 0));
602 GLU_CHECK_GLW_CALL(gl, enableVertexAttribArray(coordLoc));
603 GLU_CHECK_GLW_CALL(gl, vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, squareTriangleCoords));
604
605 GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6));
606 GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc));
607 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, 0));
608
609 tcu::Surface refSurface(reference.getWidth(), reference.getHeight());
610 tcu::Surface screen(reference.getWidth(), reference.getHeight());
611 GLU_CHECK_GLW_CALL(gl, readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
612 screen.getAccess().getDataPtr()));
613
614 tcu::copy(refSurface.getAccess(), reference.getLevel(0));
615
616 float threshold = 0.05f;
617 bool match = tcu::fuzzyCompare(log, "ComparisonResult", "Image comparison result", refSurface, screen, threshold,
618 tcu::COMPARE_LOG_RESULT);
619
620 return match;
621 }
622
623 // Renders using a single layer from a texture array.
invokeGLES(GLESImageApi & api,MovePtr<UniqueImage> & img,tcu::Texture2D & reference) const624 bool GLESImageApi::RenderTexture2DArray::invokeGLES(GLESImageApi &api, MovePtr<UniqueImage> &img,
625 tcu::Texture2D &reference) const
626 {
627 const glw::Functions &gl = api.m_gl;
628 tcu::TestLog &log = api.getLog();
629 Texture srcTex(gl);
630
631 gl.clearColor(0.0, 0.0, 0.0, 0.0);
632 gl.viewport(0, 0, reference.getWidth(), reference.getHeight());
633 gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
634 gl.disable(GL_DEPTH_TEST);
635
636 log << tcu::TestLog::Message << "Rendering EGLImage as GL_TEXTURE_2D_ARRAY in context: " << api.m_contextId
637 << tcu::TestLog::EndMessage;
638 TCU_CHECK(**img != EGL_NO_IMAGE_KHR);
639
640 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D_ARRAY, *srcTex));
641 imageTargetTexture2DArray(api.m_egl, gl, **img);
642
643 glu::TransferFormat transferFormat = glu::getTransferFormat(reference.getFormat());
644 // Initializes layer 1.
645 GLU_CHECK_GLW_CALL(gl, texSubImage3D(GL_TEXTURE_2D_ARRAY,
646 0, // Mipmap level
647 0, // X offset
648 0, // Y offset
649 1, // Z offset (layer)
650 reference.getWidth(), // Width
651 reference.getHeight(), // Height
652 1u, // Depth
653 transferFormat.format, // Format
654 transferFormat.dataType, // Type
655 reference.getLevel(0).getDataPtr())); // Pixel data
656
657 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
658 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
659 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
660 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
661
662 const char *const vertexShader = "#version 300 es\n"
663 "precision highp int;\n"
664 "precision highp float;\n"
665 "layout(location = 0) in vec2 pos_in;\n"
666 "out vec2 texcoord;\n"
667 "void main()\n"
668 "{\n"
669 " gl_Position = vec4(pos_in, -0.1, 1.0);\n"
670 " texcoord = vec2((pos_in.x + 1.0) * 0.5, (pos_in.y + 1.0) * 0.5);\n"
671 "}\n";
672
673 const char *const fragmentShader = "#version 300 es\n"
674 "precision highp int;\n"
675 "precision highp float;\n"
676 "in vec2 texcoord;\n"
677 "layout(location = 0) out vec4 color_out;\n"
678 "uniform highp sampler2DArray tex_sampler;\n"
679 "void main()\n"
680 "{\n"
681 // Samples layer 1.
682 " color_out = texture(tex_sampler, vec3(texcoord, 1));\n"
683 "}\n";
684
685 Program program(gl, vertexShader, fragmentShader);
686
687 if (!program.isOk())
688 {
689 log << tcu::TestLog::Message << "Shader build failed.\n"
690 << "Vertex: " << program.getShaderInfo(glu::SHADERTYPE_VERTEX).infoLog << "\n"
691 << vertexShader << "\n"
692 << "Fragment: " << program.getShaderInfo(glu::SHADERTYPE_FRAGMENT).infoLog << "\n"
693 << fragmentShader << "\n"
694 << "Program: " << program.getProgramInfo().infoLog << tcu::TestLog::EndMessage;
695 }
696
697 TCU_CHECK(program.isOk());
698
699 GLuint glProgram = program.getProgram();
700 GLU_CHECK_GLW_CALL(gl, useProgram(glProgram));
701
702 GLuint coordLoc = gl.getAttribLocation(glProgram, "pos_in");
703 TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute pos_in");
704
705 GLuint samplerLoc = gl.getUniformLocation(glProgram, "tex_sampler");
706 TCU_CHECK_MSG((int)samplerLoc != (int)-1, "Couldn't find uniform tex_sampler");
707
708 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D_ARRAY, *srcTex));
709 GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc, 0));
710 GLU_CHECK_GLW_CALL(gl, enableVertexAttribArray(coordLoc));
711 GLU_CHECK_GLW_CALL(gl, vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, squareTriangleCoords));
712
713 GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6));
714 GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc));
715
716 tcu::Surface refSurface(reference.getWidth(), reference.getHeight());
717 tcu::Surface screen(reference.getWidth(), reference.getHeight());
718 GLU_CHECK_GLW_CALL(gl, readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
719 screen.getAccess().getDataPtr()));
720
721 tcu::copy(refSurface.getAccess(), reference.getLevel(0));
722
723 float threshold = 0.05f;
724 bool match = tcu::fuzzyCompare(log, "ComparisonResult", "Image comparison result", refSurface, screen, threshold,
725 tcu::COMPARE_LOG_RESULT);
726
727 return match;
728 }
729
730 //Texture2D array can be both rendered and sampled as a texture.
invokeGLES(GLESImageApi & api,MovePtr<UniqueImage> & img,tcu::Texture2D & reference) const731 bool GLESImageApi::RenderSampleTexture2DArray::invokeGLES(GLESImageApi &api, MovePtr<UniqueImage> &img,
732 tcu::Texture2D &reference) const
733 {
734 const glw::Functions &gl = api.m_gl;
735 tcu::TestLog &log = api.getLog();
736 Texture srcTex(gl);
737 Texture srcTexArray(gl);
738
739 gl.clearColor(0.0, 0.0, 0.0, 0.0);
740 gl.viewport(0, 0, reference.getWidth(), reference.getHeight());
741 gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
742 gl.disable(GL_DEPTH_TEST);
743
744 log << tcu::TestLog::Message
745 << "Rendering and sampling EGLImage as GL_TEXTURE_2D_ARRAY in context: " << api.m_contextId
746 << tcu::TestLog::EndMessage;
747 TCU_CHECK(**img != EGL_NO_IMAGE_KHR);
748
749 glu::TransferFormat transferFormat = glu::getTransferFormat(reference.getFormat());
750 uint32_t internalForat = glu::getInternalFormat(reference.getFormat());
751 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, *srcTex));
752 GLU_CHECK_GLW_CALL(gl, texImage2D(GL_TEXTURE_2D,
753 0, // Level
754 internalForat, // Internal format
755 reference.getWidth(), // Width
756 reference.getHeight(), // Height
757 0, // Border
758 transferFormat.format, // Format
759 transferFormat.dataType, // Type
760 reference.getLevel(0).getDataPtr())); // Pixel data
761
762 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
763 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
764 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
765 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
766
767 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D_ARRAY, *srcTexArray));
768 imageTargetTexture2DArray(api.m_egl, gl, **img);
769
770 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
771 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
772 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
773 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
774
775 /* Create FBO and attach source texture layer 0 */
776 glu::Framebuffer fbo(gl);
777 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, *fbo));
778 GLU_CHECK_GLW_CALL(gl, framebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, *srcTexArray, 0, 0));
779
780 const char *const vertexShader0 = "attribute highp vec2 a_coord;\n"
781 "varying mediump vec2 v_texCoord;\n"
782 "void main(void) {\n"
783 "\tv_texCoord = vec2((a_coord.x + 1.0) * 0.5, (a_coord.y + 1.0) * 0.5);\n"
784 "\tgl_Position = vec4(a_coord, -0.1, 1.0);\n"
785 "}\n";
786
787 const char *const fragmentShader0 = "varying mediump vec2 v_texCoord;\n"
788 "uniform sampler2D u_sampler;\n"
789 "void main(void) {\n"
790 "\tmediump vec4 texColor = texture2D(u_sampler, v_texCoord);\n"
791 "\tgl_FragColor = vec4(texColor);\n"
792 "}";
793
794 Program program0(gl, vertexShader0, fragmentShader0);
795 if (!program0.isOk())
796 {
797 log << tcu::TestLog::Message << "Shader build failed.\n"
798 << "Vertex: " << program0.getShaderInfo(glu::SHADERTYPE_VERTEX).infoLog << "\n"
799 << vertexShader0 << "\n"
800 << "Fragment: " << program0.getShaderInfo(glu::SHADERTYPE_FRAGMENT).infoLog << "\n"
801 << fragmentShader0 << "\n"
802 << "Program: " << program0.getProgramInfo().infoLog << tcu::TestLog::EndMessage;
803 }
804
805 TCU_CHECK(program0.isOk());
806
807 GLuint glProgram0 = program0.getProgram();
808 GLU_CHECK_GLW_CALL(gl, useProgram(glProgram0));
809
810 GLuint coordLoc = gl.getAttribLocation(glProgram0, "a_coord");
811 TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute a_coord");
812 GLuint samplerLoc = gl.getUniformLocation(glProgram0, "u_sampler");
813 TCU_CHECK_MSG((int)samplerLoc != (int)-1, "Couldn't find uniform u_sampler");
814 GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc, 0));
815
816 GLU_CHECK_GLW_CALL(gl, enableVertexAttribArray(coordLoc));
817 GLU_CHECK_GLW_CALL(gl, vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, squareTriangleCoords));
818 GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6));
819 GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc));
820
821 tcu::Surface refSurface0(reference.getWidth(), reference.getHeight());
822 tcu::Surface screen0(reference.getWidth(), reference.getHeight());
823 GLU_CHECK_GLW_CALL(gl, readPixels(0, 0, screen0.getWidth(), screen0.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
824 screen0.getAccess().getDataPtr()));
825
826 tcu::copy(refSurface0.getAccess(), reference.getLevel(0));
827
828 float threshold = 0.01f;
829 bool match = tcu::fuzzyCompare(log, "ComparisonResult", "Image comparison result", refSurface0, screen0, threshold,
830 tcu::COMPARE_LOG_RESULT);
831
832 if (match == false)
833 return match;
834
835 /* Bind texture to FBO. */
836 GLU_CHECK_GLW_CALL(gl, framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *srcTex, 0));
837
838 const char *const vertexShader = "#version 300 es\n"
839 "precision highp int;\n"
840 "precision highp float;\n"
841 "layout(location = 0) in vec2 pos_in;\n"
842 "out vec2 texcoord;\n"
843 "void main()\n"
844 "{\n"
845 " gl_Position = vec4(pos_in, -0.1, 1.0);\n"
846 " texcoord = vec2((pos_in.x + 1.0) * 0.5, (pos_in.y + 1.0) * 0.5);\n"
847 "}\n";
848
849 const char *const fragmentShader = "#version 300 es\n"
850 "precision highp int;\n"
851 "precision highp float;\n"
852 "in vec2 texcoord;\n"
853 "layout(location = 0) out vec4 color_out;\n"
854 "uniform highp sampler2DArray tex_sampler;\n"
855 "void main()\n"
856 "{\n"
857 // Samples layer 0.
858 " color_out = texture(tex_sampler, vec3(texcoord, 0));\n"
859 "}\n";
860
861 Program program(gl, vertexShader, fragmentShader);
862
863 if (!program.isOk())
864 {
865 log << tcu::TestLog::Message << "Shader build failed.\n"
866 << "Vertex: " << program.getShaderInfo(glu::SHADERTYPE_VERTEX).infoLog << "\n"
867 << vertexShader << "\n"
868 << "Fragment: " << program.getShaderInfo(glu::SHADERTYPE_FRAGMENT).infoLog << "\n"
869 << fragmentShader << "\n"
870 << "Program: " << program.getProgramInfo().infoLog << tcu::TestLog::EndMessage;
871 }
872
873 TCU_CHECK(program.isOk());
874
875 GLuint glProgram = program.getProgram();
876 GLU_CHECK_GLW_CALL(gl, useProgram(glProgram));
877
878 coordLoc = gl.getAttribLocation(glProgram, "pos_in");
879 TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute pos_in");
880
881 samplerLoc = gl.getUniformLocation(glProgram, "tex_sampler");
882 TCU_CHECK_MSG((int)samplerLoc != (int)-1, "Couldn't find uniform tex_sampler");
883
884 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D_ARRAY, *srcTexArray));
885 GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc, 0));
886 GLU_CHECK_GLW_CALL(gl, enableVertexAttribArray(coordLoc));
887 GLU_CHECK_GLW_CALL(gl, vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, squareTriangleCoords));
888
889 GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6));
890 GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc));
891 GLU_CHECK_GLW_CALL(gl, finish());
892
893 tcu::Surface refSurface(reference.getWidth(), reference.getHeight());
894 tcu::Surface screen(reference.getWidth(), reference.getHeight());
895 GLU_CHECK_GLW_CALL(gl, readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
896 screen.getAccess().getDataPtr()));
897
898 tcu::copy(refSurface.getAccess(), reference.getLevel(0));
899
900 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, 0));
901
902 threshold = 0.01f;
903 match = tcu::fuzzyCompare(log, "ComparisonResult", "Image comparison result", refSurface, screen, threshold,
904 tcu::COMPARE_LOG_RESULT);
905 return match;
906 }
907
invokeGLES(GLESImageApi & api,MovePtr<UniqueImage> & img,tcu::Texture2D & reference) const908 bool GLESImageApi::RenderExternalTexture::invokeGLES(GLESImageApi &api, MovePtr<UniqueImage> &img,
909 tcu::Texture2D &reference) const
910 {
911 const glw::Functions &gl = api.m_gl;
912 tcu::TestLog &log = api.getLog();
913 Texture srcTex(gl);
914
915 // Branch only taken in TryAll case
916 if (reference.getFormat().order == tcu::TextureFormat::DS || reference.getFormat().order == tcu::TextureFormat::D)
917 throw IllegalRendererException(); // Skip, GLES2 does not support sampling depth textures
918 if (reference.getFormat().order == tcu::TextureFormat::S)
919 throw IllegalRendererException(); // Skip, GLES2 does not support sampling stencil textures
920
921 gl.clearColor(0.0, 0.0, 0.0, 0.0);
922 gl.viewport(0, 0, reference.getWidth(), reference.getHeight());
923 gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
924 gl.disable(GL_DEPTH_TEST);
925
926 log << tcu::TestLog::Message << "Rendering EGLImage as GL_TEXTURE_EXTERNAL_OES in context: " << api.m_contextId
927 << tcu::TestLog::EndMessage;
928 TCU_CHECK(**img != EGL_NO_IMAGE_KHR);
929
930 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, *srcTex));
931 imageTargetExternalTexture(api.m_egl, gl, **img);
932
933 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
934 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
935 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
936 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
937
938 const char *const vertexShader = "attribute highp vec2 a_coord;\n"
939 "varying mediump vec2 v_texCoord;\n"
940 "void main(void) {\n"
941 "\tv_texCoord = vec2((a_coord.x + 1.0) * 0.5, (a_coord.y + 1.0) * 0.5);\n"
942 "\tgl_Position = vec4(a_coord, -0.1, 1.0);\n"
943 "}\n";
944
945 const char *const fragmentShader = "#extension GL_OES_EGL_image_external : require\n"
946 "varying mediump vec2 v_texCoord;\n"
947 "uniform samplerExternalOES u_sampler;\n"
948 "void main(void) {\n"
949 "\tmediump vec4 texColor = texture2D(u_sampler, v_texCoord);\n"
950 "\tgl_FragColor = vec4(texColor);\n"
951 "}";
952
953 Program program(gl, vertexShader, fragmentShader);
954 TCU_CHECK(program.isOk());
955
956 GLuint glProgram = program.getProgram();
957 GLU_CHECK_GLW_CALL(gl, useProgram(glProgram));
958
959 GLuint coordLoc = gl.getAttribLocation(glProgram, "a_coord");
960 TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute a_coord");
961
962 GLuint samplerLoc = gl.getUniformLocation(glProgram, "u_sampler");
963 TCU_CHECK_MSG((int)samplerLoc != (int)-1, "Couldn't find uniform u_sampler");
964
965 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, *srcTex));
966 GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc, 0));
967 GLU_CHECK_GLW_CALL(gl, enableVertexAttribArray(coordLoc));
968 GLU_CHECK_GLW_CALL(gl, vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, squareTriangleCoords));
969
970 GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6));
971 GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc));
972 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, 0));
973
974 tcu::Surface refSurface(reference.getWidth(), reference.getHeight());
975 tcu::Surface screen(reference.getWidth(), reference.getHeight());
976 GLU_CHECK_GLW_CALL(gl, readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
977 screen.getAccess().getDataPtr()));
978
979 tcu::copy(refSurface.getAccess(), reference.getLevel(0));
980
981 float threshold = 0.05f;
982 bool match = tcu::fuzzyCompare(log, "ComparisonResult", "Image comparison result", refSurface, screen, threshold,
983 tcu::COMPARE_LOG_RESULT);
984
985 return match;
986 }
987
invokeGLES(GLESImageApi & api,MovePtr<UniqueImage> & img,tcu::Texture2D & reference) const988 bool GLESImageApi::RenderYUVTexture::invokeGLES(GLESImageApi &api, MovePtr<UniqueImage> &img,
989 tcu::Texture2D &reference) const
990 {
991 const glw::Functions &gl = api.m_gl;
992 tcu::TestLog &log = api.getLog();
993 Texture srcTex(gl);
994
995 DE_ASSERT(reference.isYUVTextureUsed());
996
997 gl.clearColor(0.0, 0.0, 0.0, 0.0);
998 gl.viewport(0, 0, reference.getWidth(), reference.getHeight());
999 gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1000 gl.disable(GL_DEPTH_TEST);
1001
1002 log << tcu::TestLog::Message << "Rendering EGLImage as GL_TEXTURE_EXTERNAL_OES in context: " << api.m_contextId
1003 << tcu::TestLog::EndMessage;
1004 TCU_CHECK(**img != EGL_NO_IMAGE_KHR);
1005 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, *srcTex));
1006 imageTargetExternalTexture(api.m_egl, gl, **img);
1007 {
1008 /* init YUV texture with glClear, clear color value in YUV color space */
1009 glu::Framebuffer fbo(gl);
1010 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, *fbo));
1011 GLU_CHECK_GLW_CALL(
1012 gl, framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_EXTERNAL_OES, *srcTex, 0));
1013 const tcu::Vec4 colorValues[] = {
1014 tcu::Vec4(0.9f, 0.5f, 0.65f, 1.0f), tcu::Vec4(0.5f, 0.7f, 0.65f, 1.0f), tcu::Vec4(0.2f, 0.5f, 0.65f, 1.0f),
1015 tcu::Vec4(0.3f, 0.1f, 0.5f, 1.0f), tcu::Vec4(0.8f, 0.2f, 0.3f, 1.0f), tcu::Vec4(0.9f, 0.4f, 0.8f, 1.0f),
1016 };
1017 tcu::clear(reference.getLevel(0), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
1018 GLU_CHECK_GLW_CALL(gl, enable(GL_SCISSOR_TEST));
1019 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorValues); ++ndx)
1020 {
1021 const tcu::IVec2 size =
1022 tcu::IVec2((int)((float)(DE_LENGTH_OF_ARRAY(colorValues) - ndx) *
1023 ((float)reference.getWidth() / float(DE_LENGTH_OF_ARRAY(colorValues)))),
1024 (int)((float)(DE_LENGTH_OF_ARRAY(colorValues) - ndx) *
1025 ((float)reference.getHeight() / float(DE_LENGTH_OF_ARRAY(colorValues)))));
1026
1027 if (size.x() == 0 || size.y() == 0)
1028 break;
1029 GLU_CHECK_GLW_CALL(gl, scissor(0, 0, size.x(), size.y()));
1030
1031 GLU_CHECK_GLW_CALL(
1032 gl, clearColor(colorValues[ndx].x(), colorValues[ndx].y(), colorValues[ndx].z(), colorValues[ndx].w()));
1033 GLU_CHECK_GLW_CALL(gl, clear(GL_COLOR_BUFFER_BIT));
1034 GLU_CHECK_GLW_CALL(gl, finish());
1035 uint8_t tmp[4] = {"0"};
1036 GLU_CHECK_GLW_CALL(gl, readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void *)tmp));
1037 tcu::clear(tcu::getSubregion(reference.getLevel(0), 0, 0, size.x(), size.y()),
1038 tcu::Vec4(tmp[0] / (255.0f), tmp[1] / (255.0f), tmp[2] / (255.0f), tmp[3] / (255.0f)));
1039 }
1040 GLU_CHECK_GLW_CALL(gl, disable(GL_SCISSOR_TEST));
1041 GLU_CHECK_GLW_CALL(gl,
1042 framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_EXTERNAL_OES, 0, 0));
1043 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, 0));
1044 GLU_CHECK_GLW_CALL(gl, finish());
1045 }
1046
1047 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
1048 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
1049 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
1050 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
1051
1052 const char *const vertexShader = "attribute highp vec2 a_coord;\n"
1053 "varying mediump vec2 v_texCoord;\n"
1054 "void main(void) {\n"
1055 "\tv_texCoord = vec2((a_coord.x + 1.0) * 0.5, (a_coord.y + 1.0) * 0.5);\n"
1056 "\tgl_Position = vec4(a_coord, -0.1, 1.0);\n"
1057 "}\n";
1058
1059 const char *const fragmentShader = "#extension GL_OES_EGL_image_external : require\n"
1060 "varying mediump vec2 v_texCoord;\n"
1061 "uniform samplerExternalOES u_sampler;\n"
1062 "void main(void) {\n"
1063 "\tmediump vec4 texColor = texture2D(u_sampler, v_texCoord);\n"
1064 "\tgl_FragColor = vec4(texColor);\n"
1065 "}";
1066
1067 Program program(gl, vertexShader, fragmentShader);
1068 TCU_CHECK(program.isOk());
1069
1070 GLuint glProgram = program.getProgram();
1071 GLU_CHECK_GLW_CALL(gl, useProgram(glProgram));
1072
1073 GLuint coordLoc = gl.getAttribLocation(glProgram, "a_coord");
1074 TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute a_coord");
1075
1076 GLuint samplerLoc = gl.getUniformLocation(glProgram, "u_sampler");
1077 TCU_CHECK_MSG((int)samplerLoc != (int)-1, "Couldn't find uniform u_sampler");
1078
1079 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, *srcTex));
1080 GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc, 0));
1081 GLU_CHECK_GLW_CALL(gl, enableVertexAttribArray(coordLoc));
1082 GLU_CHECK_GLW_CALL(gl, vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, squareTriangleCoords));
1083
1084 GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6));
1085 GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc));
1086 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, 0));
1087
1088 tcu::Surface refSurface(reference.getWidth(), reference.getHeight());
1089 tcu::Surface screen(reference.getWidth(), reference.getHeight());
1090 GLU_CHECK_GLW_CALL(gl, readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
1091 screen.getAccess().getDataPtr()));
1092
1093 tcu::copy(refSurface.getAccess(), reference.getLevel(0));
1094
1095 float threshold = 0.05f;
1096 bool match = tcu::fuzzyCompare(log, "ComparisonResult", "Image comparison result", refSurface, screen, threshold,
1097 tcu::COMPARE_LOG_RESULT);
1098
1099 return match;
1100 }
1101
invokeGLES(GLESImageApi & api,MovePtr<UniqueImage> & img,tcu::Texture2D & reference) const1102 bool GLESImageApi::RenderExternalTextureSamplerArray::invokeGLES(GLESImageApi &api, MovePtr<UniqueImage> &img,
1103 tcu::Texture2D &reference) const
1104 {
1105 const glw::Functions &gl = api.m_gl;
1106 tcu::TestLog &log = api.getLog();
1107 Texture srcTex(gl);
1108
1109 // Branch only taken in TryAll case
1110 if (reference.getFormat().order == tcu::TextureFormat::DS || reference.getFormat().order == tcu::TextureFormat::D)
1111 throw IllegalRendererException(); // Skip, GLES2 does not support sampling depth textures
1112 if (reference.getFormat().order == tcu::TextureFormat::S)
1113 throw IllegalRendererException(); // Skip, GLES2 does not support sampling stencil textures
1114
1115 gl.clearColor(0.0, 0.0, 0.0, 0.0);
1116 gl.viewport(0, 0, reference.getWidth(), reference.getHeight());
1117 gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1118 gl.disable(GL_DEPTH_TEST);
1119
1120 log << tcu::TestLog::Message
1121 << "Rendering EGLImage as GL_TEXTURE_EXTERNAL_OES using sampler array in context: " << api.m_contextId
1122 << tcu::TestLog::EndMessage;
1123 TCU_CHECK(**img != EGL_NO_IMAGE_KHR);
1124
1125 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, *srcTex));
1126 imageTargetExternalTexture(api.m_egl, gl, **img);
1127
1128 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
1129 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
1130 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
1131 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
1132
1133 // Texture not associated with an external texture will return (0, 0, 0, 1) when sampled.
1134 GLuint emptyTex;
1135 gl.genTextures(1, &emptyTex);
1136 gl.activeTexture(GL_TEXTURE1);
1137 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, emptyTex));
1138
1139 const char *const vertexShader = "attribute highp vec2 a_coord;\n"
1140 "varying mediump vec2 v_texCoord;\n"
1141 "void main(void) {\n"
1142 "\tv_texCoord = vec2((a_coord.x + 1.0) * 0.5, (a_coord.y + 1.0) * 0.5);\n"
1143 "\tgl_Position = vec4(a_coord, -0.1, 1.0);\n"
1144 "}\n";
1145
1146 const char *const fragmentShader = "#extension GL_OES_EGL_image_external : require\n"
1147 "varying mediump vec2 v_texCoord;\n"
1148 "uniform samplerExternalOES u_sampler[4];\n"
1149 "void main(void) {\n"
1150 "\tmediump vec4 texColor = texture2D(u_sampler[2], v_texCoord);\n"
1151 "\t//These will sample (0, 0, 0, 1) and should not affect the results.\n"
1152 "\ttexColor += texture2D(u_sampler[0], v_texCoord) - vec4(0, 0, 0, 1);\n"
1153 "\ttexColor += texture2D(u_sampler[1], v_texCoord) - vec4(0, 0, 0, 1);\n"
1154 "\ttexColor += texture2D(u_sampler[3], v_texCoord) - vec4(0, 0, 0, 1);\n"
1155 "\tgl_FragColor = vec4(texColor);\n"
1156 "}";
1157
1158 Program program(gl, vertexShader, fragmentShader);
1159 TCU_CHECK(program.isOk());
1160
1161 GLuint glProgram = program.getProgram();
1162 GLU_CHECK_GLW_CALL(gl, useProgram(glProgram));
1163
1164 GLuint coordLoc = gl.getAttribLocation(glProgram, "a_coord");
1165 TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute a_coord");
1166
1167 GLuint samplerLoc0 = gl.getUniformLocation(glProgram, "u_sampler[0]");
1168 TCU_CHECK_MSG((int)samplerLoc0 != (int)-1, "Couldn't find uniform u_sampler[0]");
1169 GLuint samplerLoc1 = gl.getUniformLocation(glProgram, "u_sampler[1]");
1170 TCU_CHECK_MSG((int)samplerLoc1 != (int)-1, "Couldn't find uniform u_sampler[1]");
1171 GLuint samplerLoc2 = gl.getUniformLocation(glProgram, "u_sampler[2]");
1172 TCU_CHECK_MSG((int)samplerLoc2 != (int)-1, "Couldn't find uniform u_sampler[2]");
1173 GLuint samplerLoc3 = gl.getUniformLocation(glProgram, "u_sampler[3]");
1174 TCU_CHECK_MSG((int)samplerLoc3 != (int)-1, "Couldn't find uniform u_sampler[3]");
1175
1176 gl.activeTexture(GL_TEXTURE0);
1177 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, *srcTex));
1178 // One sampler reads a gradient and others opaque black.
1179 GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc0, 1));
1180 GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc1, 1));
1181 GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc2, 0));
1182 GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc3, 1));
1183 GLU_CHECK_GLW_CALL(gl, enableVertexAttribArray(coordLoc));
1184 GLU_CHECK_GLW_CALL(gl, vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, squareTriangleCoords));
1185
1186 GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6));
1187 GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc));
1188 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, 0));
1189 gl.activeTexture(GL_TEXTURE1);
1190 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, 0));
1191 gl.deleteTextures(1, &emptyTex);
1192 gl.activeTexture(GL_TEXTURE0);
1193
1194 tcu::Surface refSurface(reference.getWidth(), reference.getHeight());
1195 tcu::Surface screen(reference.getWidth(), reference.getHeight());
1196 GLU_CHECK_GLW_CALL(gl, readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
1197 screen.getAccess().getDataPtr()));
1198
1199 tcu::copy(refSurface.getAccess(), reference.getLevel(0));
1200
1201 float threshold = 0.05f;
1202 bool match = tcu::fuzzyCompare(log, "ComparisonResult", "Image comparison result", refSurface, screen, threshold,
1203 tcu::COMPARE_LOG_RESULT);
1204
1205 return match;
1206 }
1207
invokeGLES(GLESImageApi & api,MovePtr<UniqueImage> & img,tcu::Texture2D & reference) const1208 bool GLESImageApi::RenderDepthbuffer::invokeGLES(GLESImageApi &api, MovePtr<UniqueImage> &img,
1209 tcu::Texture2D &reference) const
1210 {
1211 const glw::Functions &gl = api.m_gl;
1212 tcu::TestLog &log = api.getLog();
1213 Framebuffer framebuffer(gl);
1214 Renderbuffer renderbufferColor(gl);
1215 Renderbuffer renderbufferDepth(gl);
1216 const tcu::RGBA compareThreshold(32, 32, 32, 32); // layer colors are far apart, large thresholds are ok
1217
1218 // Branch only taken in TryAll case
1219 if (reference.getFormat().order != tcu::TextureFormat::DS && reference.getFormat().order != tcu::TextureFormat::D)
1220 throw IllegalRendererException(); // Skip, interpreting non-depth data as depth data is not meaningful
1221
1222 log << tcu::TestLog::Message << "Rendering with depth buffer" << tcu::TestLog::EndMessage;
1223
1224 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, *framebuffer));
1225
1226 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbufferColor));
1227 GLU_CHECK_GLW_CALL(gl, renderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, reference.getWidth(), reference.getHeight()));
1228 framebufferRenderbuffer(gl, GL_COLOR_ATTACHMENT0, *renderbufferColor);
1229
1230 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbufferDepth));
1231 imageTargetRenderbuffer(api.m_egl, gl, **img);
1232 framebufferRenderbuffer(gl, GL_DEPTH_ATTACHMENT, *renderbufferDepth);
1233 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, 0));
1234
1235 GLU_CHECK_GLW_CALL(gl, viewport(0, 0, reference.getWidth(), reference.getHeight()));
1236
1237 // Render
1238 const char *vertexShader = "attribute highp vec2 a_coord;\n"
1239 "uniform highp float u_depth;\n"
1240 "void main(void) {\n"
1241 "\tgl_Position = vec4(a_coord, u_depth, 1.0);\n"
1242 "}\n";
1243
1244 const char *fragmentShader = "uniform mediump vec4 u_color;\n"
1245 "void main(void) {\n"
1246 "\tgl_FragColor = u_color;\n"
1247 "}";
1248
1249 Program program(gl, vertexShader, fragmentShader);
1250 TCU_CHECK(program.isOk());
1251
1252 GLuint glProgram = program.getProgram();
1253 GLU_CHECK_GLW_CALL(gl, useProgram(glProgram));
1254
1255 GLuint coordLoc = gl.getAttribLocation(glProgram, "a_coord");
1256 TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute a_coord");
1257
1258 GLuint colorLoc = gl.getUniformLocation(glProgram, "u_color");
1259 TCU_CHECK_MSG((int)colorLoc != (int)-1, "Couldn't find uniform u_color");
1260
1261 GLuint depthLoc = gl.getUniformLocation(glProgram, "u_depth");
1262 TCU_CHECK_MSG((int)depthLoc != (int)-1, "Couldn't find uniform u_depth");
1263
1264 GLU_CHECK_GLW_CALL(gl, clearColor(0.5f, 1.0f, 0.5f, 1.0f));
1265 GLU_CHECK_GLW_CALL(gl, clear(GL_COLOR_BUFFER_BIT));
1266
1267 tcu::Vec4 depthLevelColors[] = {
1268 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),
1269 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f),
1270
1271 tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f),
1272 tcu::Vec4(0.0f, 0.5f, 0.0f, 1.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 1.0f)};
1273
1274 GLU_CHECK_GLW_CALL(gl, enableVertexAttribArray(coordLoc));
1275 GLU_CHECK_GLW_CALL(gl, vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, squareTriangleCoords));
1276
1277 GLU_CHECK_GLW_CALL(gl, enable(GL_DEPTH_TEST));
1278 GLU_CHECK_GLW_CALL(gl, depthFunc(GL_LESS));
1279 GLU_CHECK_GLW_CALL(gl, depthMask(GL_FALSE));
1280
1281 for (int level = 0; level < DE_LENGTH_OF_ARRAY(depthLevelColors); level++)
1282 {
1283 const tcu::Vec4 color = depthLevelColors[level];
1284 const float clipDepth = ((float)(level + 1) * 0.1f) * 2.0f - 1.0f; // depth in clip coords
1285
1286 GLU_CHECK_GLW_CALL(gl, uniform4f(colorLoc, color.x(), color.y(), color.z(), color.w()));
1287 GLU_CHECK_GLW_CALL(gl, uniform1f(depthLoc, clipDepth));
1288 GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6));
1289 }
1290
1291 GLU_CHECK_GLW_CALL(gl, depthMask(GL_TRUE));
1292 GLU_CHECK_GLW_CALL(gl, disable(GL_DEPTH_TEST));
1293 GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc));
1294
1295 const ConstPixelBufferAccess &refAccess = reference.getLevel(0);
1296 tcu::Surface screen(reference.getWidth(), reference.getHeight());
1297 tcu::Surface referenceScreen(reference.getWidth(), reference.getHeight());
1298
1299 gl.readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
1300 screen.getAccess().getDataPtr());
1301
1302 tcu::Texture2D tmpDepth(refAccess.getFormat(), 1, 1);
1303 tmpDepth.allocLevel(0);
1304 for (int y = 0; y < reference.getHeight(); y++)
1305 {
1306 for (int x = 0; x < reference.getWidth(); x++)
1307 {
1308 tcu::Vec4 result = tcu::Vec4(0.5f, 1.0f, 0.5f, 1.0f);
1309
1310 for (int level = 0; level < DE_LENGTH_OF_ARRAY(depthLevelColors); level++)
1311 {
1312 tcu::clearDepth(tmpDepth.getLevel(0), (float)(level + 1) * 0.1f);
1313 if (tmpDepth.getLevel(0).getPixDepth(0, 0) < refAccess.getPixDepth(x, y))
1314 result = depthLevelColors[level];
1315 }
1316
1317 referenceScreen.getAccess().setPixel(result, x, y);
1318 }
1319 }
1320
1321 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, 0));
1322 GLU_CHECK_GLW_CALL(gl, finish());
1323
1324 return tcu::pixelThresholdCompare(log, "Depth buffer rendering result", "Result from rendering with depth buffer",
1325 referenceScreen, screen, compareThreshold, tcu::COMPARE_LOG_RESULT);
1326 }
1327
invokeGLES(GLESImageApi & api,MovePtr<UniqueImage> & img,tcu::Texture2D & reference) const1328 bool GLESImageApi::RenderStencilbuffer::invokeGLES(GLESImageApi &api, MovePtr<UniqueImage> &img,
1329 tcu::Texture2D &reference) const
1330 {
1331 // Branch only taken in TryAll case
1332 if (reference.getFormat().order != tcu::TextureFormat::DS && reference.getFormat().order != tcu::TextureFormat::S)
1333 throw IllegalRendererException(); // Skip, interpreting non-stencil data as stencil data is not meaningful
1334
1335 const glw::Functions &gl = api.m_gl;
1336 tcu::TestLog &log = api.getLog();
1337 Framebuffer framebuffer(gl);
1338 Renderbuffer renderbufferColor(gl);
1339 Renderbuffer renderbufferStencil(gl);
1340 const tcu::RGBA compareThreshold(32, 32, 32, 32); // layer colors are far apart, large thresholds are ok
1341 const uint32_t numStencilBits =
1342 tcu::getTextureFormatBitDepth(
1343 tcu::getEffectiveDepthStencilTextureFormat(reference.getLevel(0).getFormat(), tcu::Sampler::MODE_STENCIL))
1344 .x();
1345 const uint32_t maxStencil = deBitMask32(0, numStencilBits);
1346
1347 log << tcu::TestLog::Message << "Rendering with stencil buffer" << tcu::TestLog::EndMessage;
1348
1349 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, *framebuffer));
1350
1351 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbufferColor));
1352 GLU_CHECK_GLW_CALL(gl, renderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, reference.getWidth(), reference.getHeight()));
1353 framebufferRenderbuffer(gl, GL_COLOR_ATTACHMENT0, *renderbufferColor);
1354
1355 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbufferStencil));
1356 imageTargetRenderbuffer(api.m_egl, gl, **img);
1357 framebufferRenderbuffer(gl, GL_STENCIL_ATTACHMENT, *renderbufferStencil);
1358 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, 0));
1359
1360 GLU_CHECK_GLW_CALL(gl, viewport(0, 0, reference.getWidth(), reference.getHeight()));
1361
1362 // Render
1363 const char *vertexShader = "attribute highp vec2 a_coord;\n"
1364 "void main(void) {\n"
1365 "\tgl_Position = vec4(a_coord, 0.0, 1.0);\n"
1366 "}\n";
1367
1368 const char *fragmentShader = "uniform mediump vec4 u_color;\n"
1369 "void main(void) {\n"
1370 "\tgl_FragColor = u_color;\n"
1371 "}";
1372
1373 Program program(gl, vertexShader, fragmentShader);
1374 TCU_CHECK(program.isOk());
1375
1376 GLuint glProgram = program.getProgram();
1377 GLU_CHECK_GLW_CALL(gl, useProgram(glProgram));
1378
1379 GLuint coordLoc = gl.getAttribLocation(glProgram, "a_coord");
1380 TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute a_coord");
1381
1382 GLuint colorLoc = gl.getUniformLocation(glProgram, "u_color");
1383 TCU_CHECK_MSG((int)colorLoc != (int)-1, "Couldn't find uniform u_color");
1384
1385 GLU_CHECK_GLW_CALL(gl, clearColor(0.5f, 1.0f, 0.5f, 1.0f));
1386 GLU_CHECK_GLW_CALL(gl, clear(GL_COLOR_BUFFER_BIT));
1387
1388 tcu::Vec4 stencilLevelColors[] = {
1389 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),
1390 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f),
1391
1392 tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f),
1393 tcu::Vec4(0.0f, 0.5f, 0.0f, 1.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 1.0f)};
1394
1395 GLU_CHECK_GLW_CALL(gl, enableVertexAttribArray(coordLoc));
1396 GLU_CHECK_GLW_CALL(gl, vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, squareTriangleCoords));
1397
1398 GLU_CHECK_GLW_CALL(gl, enable(GL_STENCIL_TEST));
1399 GLU_CHECK_GLW_CALL(gl, stencilOp(GL_KEEP, GL_KEEP, GL_KEEP));
1400
1401 for (int level = 0; level < DE_LENGTH_OF_ARRAY(stencilLevelColors); level++)
1402 {
1403 const tcu::Vec4 color = stencilLevelColors[level];
1404 const int stencil = (int)(((float)(level + 1) * 0.1f) * (float)maxStencil);
1405
1406 GLU_CHECK_GLW_CALL(gl, stencilFunc(GL_LESS, stencil, 0xFFFFFFFFu));
1407 GLU_CHECK_GLW_CALL(gl, uniform4f(colorLoc, color.x(), color.y(), color.z(), color.w()));
1408 GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6));
1409 }
1410
1411 GLU_CHECK_GLW_CALL(gl, disable(GL_STENCIL_TEST));
1412 GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc));
1413
1414 const ConstPixelBufferAccess &refAccess = reference.getLevel(0);
1415 tcu::Surface screen(reference.getWidth(), reference.getHeight());
1416 tcu::Surface referenceScreen(reference.getWidth(), reference.getHeight());
1417
1418 gl.readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
1419 screen.getAccess().getDataPtr());
1420
1421 for (int y = 0; y < reference.getHeight(); y++)
1422 for (int x = 0; x < reference.getWidth(); x++)
1423 {
1424 tcu::Vec4 result = tcu::Vec4(0.5f, 1.0f, 0.5f, 1.0f);
1425
1426 for (int level = 0; level < DE_LENGTH_OF_ARRAY(stencilLevelColors); level++)
1427 {
1428 const int levelStencil = (int)(((float)(level + 1) * 0.1f) * (float)maxStencil);
1429 if (levelStencil < refAccess.getPixStencil(x, y))
1430 result = stencilLevelColors[level];
1431 }
1432
1433 referenceScreen.getAccess().setPixel(result, x, y);
1434 }
1435
1436 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, 0));
1437 GLU_CHECK_GLW_CALL(gl, finish());
1438
1439 return tcu::pixelThresholdCompare(log, "StencilResult", "Result from rendering with stencil buffer",
1440 referenceScreen, screen, compareThreshold, tcu::COMPARE_LOG_RESULT);
1441 }
1442
invokeGLES(GLESImageApi & api,MovePtr<UniqueImage> & img,tcu::Texture2D & reference) const1443 bool GLESImageApi::RenderReadPixelsRenderbuffer::invokeGLES(GLESImageApi &api, MovePtr<UniqueImage> &img,
1444 tcu::Texture2D &reference) const
1445 {
1446 switch (glu::getInternalFormat(reference.getFormat()))
1447 {
1448 case GL_RGBA4:
1449 case GL_RGB5_A1:
1450 case GL_RGB565:
1451 break;
1452 default:
1453 // Skip, not in the list of allowed render buffer formats for GLES.
1454 throw tcu::NotSupportedError("Image format not allowed for glReadPixels.");
1455 }
1456
1457 const glw::Functions &gl = api.m_gl;
1458 const tcu::IVec4 bitDepth = tcu::getTextureFormatMantissaBitDepth(reference.getFormat());
1459 const tcu::IVec4 threshold(2 * (tcu::IVec4(1) << (tcu::IVec4(8) - bitDepth)));
1460 const tcu::RGBA threshold8((uint8_t)(de::clamp(threshold[0], 0, 255)), (uint8_t)(de::clamp(threshold[1], 0, 255)),
1461 (uint8_t)(de::clamp(threshold[2], 0, 255)), (uint8_t)(de::clamp(threshold[3], 0, 255)));
1462 tcu::TestLog &log = api.getLog();
1463 Framebuffer framebuffer(gl);
1464 Renderbuffer renderbuffer(gl);
1465 tcu::Surface screen(reference.getWidth(), reference.getHeight());
1466 tcu::Surface refSurface(reference.getWidth(), reference.getHeight());
1467
1468 log << tcu::TestLog::Message << "Reading with ReadPixels from renderbuffer" << tcu::TestLog::EndMessage;
1469
1470 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, *framebuffer));
1471 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbuffer));
1472 imageTargetRenderbuffer(api.m_egl, gl, **img);
1473
1474 GLU_EXPECT_NO_ERROR(gl.getError(), "imageTargetRenderbuffer");
1475 framebufferRenderbuffer(gl, GL_COLOR_ATTACHMENT0, *renderbuffer);
1476 GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferRenderbuffer");
1477
1478 GLU_CHECK_GLW_CALL(gl, viewport(0, 0, reference.getWidth(), reference.getHeight()));
1479
1480 GLU_CHECK_GLW_CALL(gl, readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
1481 screen.getAccess().getDataPtr()));
1482
1483 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, 0));
1484 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, 0));
1485 GLU_CHECK_GLW_CALL(gl, finish());
1486
1487 tcu::copy(refSurface.getAccess(), reference.getLevel(0));
1488
1489 return tcu::pixelThresholdCompare(log, "Renderbuffer read", "Result from reading renderbuffer", refSurface, screen,
1490 threshold8, tcu::COMPARE_LOG_RESULT);
1491 }
1492
invokeGLES(GLESImageApi & api,MovePtr<UniqueImage> & img,tcu::Texture2D & reference) const1493 bool GLESImageApi::RenderTryAll::invokeGLES(GLESImageApi &api, MovePtr<UniqueImage> &img,
1494 tcu::Texture2D &reference) const
1495 {
1496 bool foundSupported = false;
1497 tcu::TestLog &log = api.getLog();
1498 GLESImageApi::RenderTexture2D renderTex2D;
1499 GLESImageApi::RenderExternalTexture renderExternal;
1500 GLESImageApi::RenderExternalTextureSamplerArray renderExternalSamplerArray;
1501 GLESImageApi::RenderReadPixelsRenderbuffer renderReadPixels;
1502 GLESImageApi::RenderDepthbuffer renderDepth;
1503 GLESImageApi::RenderStencilbuffer renderStencil;
1504 Action *actions[] = {&renderTex2D, &renderExternal, &renderExternalSamplerArray,
1505 &renderReadPixels, &renderDepth, &renderStencil};
1506 set<string> exts = getSupportedExtensions(log, api.m_egl, api.m_display, api.m_gl);
1507
1508 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(actions); ++ndx)
1509 {
1510 try
1511 {
1512 const string ext = actions[ndx]->getRequiredExtension();
1513
1514 if (!de::contains(exts, ext))
1515 TCU_THROW_EXPR(NotSupportedError, "Extension not supported", ext.c_str());
1516
1517 if (!actions[ndx]->invoke(api, img, reference))
1518 return false;
1519
1520 foundSupported = true;
1521 }
1522 catch (const tcu::NotSupportedError &error)
1523 {
1524 log << tcu::TestLog::Message << error.what() << tcu::TestLog::EndMessage;
1525 }
1526 catch (const IllegalRendererException &)
1527 {
1528 // not valid renderer
1529 }
1530 }
1531
1532 if (!foundSupported)
1533 throw tcu::NotSupportedError("Rendering not supported", "", __FILE__, __LINE__);
1534
1535 return true;
1536 }
1537
invokeGLES(GLESImageApi & api,MovePtr<UniqueImage> & img,tcu::Texture2D & reference) const1538 bool GLESImageApi::ModifyTexSubImage::invokeGLES(GLESImageApi &api, MovePtr<UniqueImage> &img,
1539 tcu::Texture2D &reference) const
1540 {
1541 const glw::Functions &gl = api.m_gl;
1542 tcu::TestLog &log = api.getLog();
1543 glu::Texture srcTex(gl);
1544 const int xOffset = 8;
1545 const int yOffset = 16;
1546 const int xSize = de::clamp(16, 0, reference.getWidth() - xOffset);
1547 const int ySize = de::clamp(16, 0, reference.getHeight() - yOffset);
1548 tcu::Texture2D src(glu::mapGLTransferFormat(m_format, m_type), xSize, ySize);
1549
1550 log << tcu::TestLog::Message << "Modifying EGLImage with gl.texSubImage2D" << tcu::TestLog::EndMessage;
1551
1552 src.allocLevel(0);
1553 tcu::fillWithComponentGradients(src.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
1554 tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
1555
1556 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, *srcTex));
1557 imageTargetTexture2D(api.m_egl, gl, **img);
1558 GLU_CHECK_GLW_CALL(gl, texSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, src.getWidth(), src.getHeight(), m_format,
1559 m_type, src.getLevel(0).getDataPtr()));
1560 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, 0));
1561 GLU_CHECK_GLW_CALL(gl, finish());
1562
1563 tcu::copy(tcu::getSubregion(reference.getLevel(0), xOffset, yOffset, 0, xSize, ySize, 1), src.getLevel(0));
1564
1565 return true;
1566 }
1567
invokeGLES(GLESImageApi & api,MovePtr<UniqueImage> & img,tcu::Texture2D & reference) const1568 bool GLESImageApi::ModifyRenderbuffer::invokeGLES(GLESImageApi &api, MovePtr<UniqueImage> &img,
1569 tcu::Texture2D &reference) const
1570 {
1571 const glw::Functions &gl = api.m_gl;
1572 tcu::TestLog &log = api.getLog();
1573 glu::Framebuffer framebuffer(gl);
1574 glu::Renderbuffer renderbuffer(gl);
1575
1576 log << tcu::TestLog::Message << "Modifying EGLImage with glClear to renderbuffer" << tcu::TestLog::EndMessage;
1577
1578 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, *framebuffer));
1579 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbuffer));
1580
1581 imageTargetRenderbuffer(api.m_egl, gl, **img);
1582
1583 initializeRbo(api, *renderbuffer, reference);
1584
1585 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, 0));
1586 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, 0));
1587
1588 GLU_CHECK_GLW_CALL(gl, finish());
1589
1590 return true;
1591 }
1592
initializeRbo(GLESImageApi & api,GLuint renderbuffer,tcu::Texture2D & reference) const1593 void GLESImageApi::ModifyRenderbufferClearColor::initializeRbo(GLESImageApi &api, GLuint renderbuffer,
1594 tcu::Texture2D &reference) const
1595 {
1596 const glw::Functions &gl = api.m_gl;
1597
1598 framebufferRenderbuffer(gl, GL_COLOR_ATTACHMENT0, renderbuffer);
1599
1600 GLU_CHECK_GLW_CALL(gl, viewport(0, 0, reference.getWidth(), reference.getHeight()));
1601 GLU_CHECK_GLW_CALL(gl, clearColor(m_color.x(), m_color.y(), m_color.z(), m_color.w()));
1602 GLU_CHECK_GLW_CALL(gl, clear(GL_COLOR_BUFFER_BIT));
1603
1604 tcu::clear(reference.getLevel(0), m_color);
1605 }
1606
initializeRbo(GLESImageApi & api,GLuint renderbuffer,tcu::Texture2D & reference) const1607 void GLESImageApi::ModifyRenderbufferClearDepth::initializeRbo(GLESImageApi &api, GLuint renderbuffer,
1608 tcu::Texture2D &reference) const
1609 {
1610 const glw::Functions &gl = api.m_gl;
1611
1612 framebufferRenderbuffer(gl, GL_DEPTH_ATTACHMENT, renderbuffer);
1613
1614 GLU_CHECK_GLW_CALL(gl, viewport(0, 0, reference.getWidth(), reference.getHeight()));
1615 GLU_CHECK_GLW_CALL(gl, clearDepthf(m_depth));
1616 GLU_CHECK_GLW_CALL(gl, clear(GL_DEPTH_BUFFER_BIT));
1617
1618 tcu::clearDepth(reference.getLevel(0), m_depth);
1619 }
1620
initializeRbo(GLESImageApi & api,GLuint renderbuffer,tcu::Texture2D & reference) const1621 void GLESImageApi::ModifyRenderbufferClearStencil::initializeRbo(GLESImageApi &api, GLuint renderbuffer,
1622 tcu::Texture2D &reference) const
1623 {
1624 const glw::Functions &gl = api.m_gl;
1625
1626 framebufferRenderbuffer(gl, GL_STENCIL_ATTACHMENT, renderbuffer);
1627
1628 GLU_CHECK_GLW_CALL(gl, viewport(0, 0, reference.getWidth(), reference.getHeight()));
1629 GLU_CHECK_GLW_CALL(gl, clearStencil(m_stencil));
1630 GLU_CHECK_GLW_CALL(gl, clear(GL_STENCIL_BUFFER_BIT));
1631
1632 tcu::clearStencil(reference.getLevel(0), m_stencil);
1633 }
1634
1635 class ImageFormatCase : public TestCase, private glu::CallLogWrapper
1636 {
1637 public:
1638 ImageFormatCase(EglTestContext &eglTestCtx, const TestSpec &spec);
1639 ~ImageFormatCase(void);
1640
1641 void init(void);
1642 void deinit(void);
1643 IterateResult iterate(void);
1644 void checkExtensions(void);
1645
1646 private:
1647 EGLConfig getConfig(void);
1648
1649 const TestSpec m_spec;
1650
1651 vector<ImageApi *> m_apiContexts;
1652
1653 EGLDisplay m_display;
1654 eglu::NativeWindow *m_window;
1655 EGLSurface m_surface;
1656 EGLConfig m_config;
1657 int m_curIter;
1658 MovePtr<UniqueImage> m_img;
1659 tcu::Texture2D m_refImg;
1660 glw::Functions m_gl;
1661 };
1662
getConfig(void)1663 EGLConfig ImageFormatCase::getConfig(void)
1664 {
1665 const GLint glesApi = m_spec.contexts[0] == TestSpec::API_GLES3 ? EGL_OPENGL_ES3_BIT : EGL_OPENGL_ES2_BIT;
1666 const EGLint attribList[] = {EGL_RENDERABLE_TYPE, glesApi, EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
1667 EGL_RED_SIZE, 8, EGL_BLUE_SIZE, 8,
1668 EGL_GREEN_SIZE, 8, EGL_ALPHA_SIZE, 8,
1669 EGL_DEPTH_SIZE, 8, EGL_NONE};
1670
1671 return eglu::chooseSingleConfig(m_eglTestCtx.getLibrary(), m_display, attribList);
1672 }
1673
ImageFormatCase(EglTestContext & eglTestCtx,const TestSpec & spec)1674 ImageFormatCase::ImageFormatCase(EglTestContext &eglTestCtx, const TestSpec &spec)
1675 : TestCase(eglTestCtx, spec.name.c_str(), spec.desc.c_str())
1676 , glu::CallLogWrapper(m_gl, eglTestCtx.getTestContext().getLog())
1677 , m_spec(spec)
1678 , m_display(EGL_NO_DISPLAY)
1679 , m_window(DE_NULL)
1680 , m_surface(EGL_NO_SURFACE)
1681 , m_config(0)
1682 , m_curIter(0)
1683 , m_refImg(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 1, 1)
1684 {
1685 }
1686
~ImageFormatCase(void)1687 ImageFormatCase::~ImageFormatCase(void)
1688 {
1689 deinit();
1690 }
1691
checkExtensions(void)1692 void ImageFormatCase::checkExtensions(void)
1693 {
1694 set<string> exts = getSupportedExtensions(getLog(), m_eglTestCtx.getLibrary(), m_display, m_gl);
1695
1696 for (int operationNdx = 0; operationNdx < (int)m_spec.operations.size(); operationNdx++)
1697 {
1698 const TestSpec::Operation &op = m_spec.operations[operationNdx];
1699 const string ext = op.action->getRequiredExtension();
1700
1701 if (!de::contains(exts, ext))
1702 TCU_THROW_EXPR(NotSupportedError, "Extension not supported", ext.c_str());
1703 }
1704 }
1705
init(void)1706 void ImageFormatCase::init(void)
1707 {
1708 const Library &egl = m_eglTestCtx.getLibrary();
1709 const eglu::NativeWindowFactory &windowFactory =
1710 eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
1711
1712 try
1713 {
1714 m_display = eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
1715
1716 // GLES3 requires either EGL 1.5 or EGL_KHR_create_context extension.
1717 if (m_spec.contexts[0] == TestSpec::API_GLES3 && eglu::getVersion(egl, m_display) < eglu::Version(1, 5))
1718 {
1719 set<string> exts;
1720 const vector<string> eglExts = eglu::getDisplayExtensions(egl, m_display);
1721 exts.insert(eglExts.begin(), eglExts.end());
1722
1723 if (!de::contains(exts, "EGL_KHR_create_context"))
1724 {
1725 getLog() << tcu::TestLog::Message << "EGL version is under 1.5 and the test is using OpenGL ES 3.2."
1726 << "This requires EGL_KHR_create_context extension." << tcu::TestLog::EndMessage;
1727 TCU_THROW(NotSupportedError, "Extension not supported: EGL_KHR_create_context");
1728 }
1729 }
1730
1731 m_config = getConfig();
1732 m_window = windowFactory.createWindow(
1733 &m_eglTestCtx.getNativeDisplay(), m_display, m_config, DE_NULL,
1734 eglu::WindowParams(480, 480, eglu::parseWindowVisibility(m_testCtx.getCommandLine())));
1735 m_surface = eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *m_window, m_display, m_config, DE_NULL);
1736
1737 {
1738 const char *extensions[] = {"GL_OES_EGL_image"};
1739 int major = 2;
1740 int minor = 0;
1741
1742 if (m_spec.contexts[0] == TestSpec::API_GLES3)
1743 {
1744 major = 3;
1745 minor = 2;
1746 }
1747 m_eglTestCtx.initGLFunctions(&m_gl, glu::ApiType::es(major, minor), DE_LENGTH_OF_ARRAY(extensions),
1748 &extensions[0]);
1749 }
1750
1751 for (int contextNdx = 0; contextNdx < (int)m_spec.contexts.size(); contextNdx++)
1752 {
1753 ImageApi *api = DE_NULL;
1754 switch (m_spec.contexts[contextNdx])
1755 {
1756 case TestSpec::API_GLES2:
1757 {
1758 api = new GLESImageApi(egl, m_gl, contextNdx, getLog(), m_display, m_surface, m_config, 2);
1759 break;
1760 }
1761
1762 case TestSpec::API_GLES3:
1763 {
1764 api = new GLESImageApi(egl, m_gl, contextNdx, getLog(), m_display, m_surface, m_config, 3);
1765 break;
1766 }
1767
1768 default:
1769 DE_ASSERT(false);
1770 break;
1771 }
1772 m_apiContexts.push_back(api);
1773 }
1774 checkExtensions();
1775 }
1776 catch (...)
1777 {
1778 deinit();
1779 throw;
1780 }
1781 }
1782
deinit(void)1783 void ImageFormatCase::deinit(void)
1784 {
1785 const Library &egl = m_eglTestCtx.getLibrary();
1786
1787 m_img.clear();
1788
1789 for (int contexNdx = 0; contexNdx < (int)m_apiContexts.size(); contexNdx++)
1790 delete m_apiContexts[contexNdx];
1791
1792 m_apiContexts.clear();
1793
1794 if (m_surface != EGL_NO_SURFACE)
1795 {
1796 egl.destroySurface(m_display, m_surface);
1797 m_surface = EGL_NO_SURFACE;
1798 }
1799
1800 delete m_window;
1801 m_window = DE_NULL;
1802
1803 if (m_display != EGL_NO_DISPLAY)
1804 {
1805 egl.terminate(m_display);
1806 m_display = EGL_NO_DISPLAY;
1807 }
1808 }
1809
iterate(void)1810 TestCase::IterateResult ImageFormatCase::iterate(void)
1811 {
1812 const TestSpec::Operation &op = m_spec.operations[m_curIter++];
1813 ImageApi &api = *m_apiContexts[op.apiIndex];
1814 const bool isOk = op.action->invoke(api, m_img, m_refImg);
1815
1816 if (isOk && m_curIter < (int)m_spec.operations.size())
1817 return CONTINUE;
1818 else if (isOk)
1819 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1820 else
1821 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1822
1823 return STOP;
1824 }
1825
1826 struct LabeledAction
1827 {
1828 string label;
1829 MovePtr<Action> action;
1830 };
1831
1832 // A simple vector mockup that we need because MovePtr isn't copy-constructible.
1833 struct LabeledActions
1834 {
LabeledActionsdeqp::egl::Image::LabeledActions1835 LabeledActions(void) : m_numActions(0)
1836 {
1837 }
operator []deqp::egl::Image::LabeledActions1838 LabeledAction &operator[](int ndx)
1839 {
1840 DE_ASSERT(0 <= ndx && ndx < m_numActions);
1841 return m_actions[ndx];
1842 }
1843 void add(const string &label, MovePtr<Action> action);
sizedeqp::egl::Image::LabeledActions1844 int size(void) const
1845 {
1846 return m_numActions;
1847 }
1848
1849 private:
1850 LabeledAction m_actions[64];
1851 int m_numActions;
1852 };
1853
add(const string & label,MovePtr<Action> action)1854 void LabeledActions::add(const string &label, MovePtr<Action> action)
1855 {
1856 DE_ASSERT(m_numActions < DE_LENGTH_OF_ARRAY(m_actions));
1857 m_actions[m_numActions].label = label;
1858 m_actions[m_numActions].action = action;
1859 ++m_numActions;
1860 }
1861
1862 class ImageTests : public TestCaseGroup
1863 {
1864 protected:
ImageTests(EglTestContext & eglTestCtx,const string & name,const string & desc)1865 ImageTests(EglTestContext &eglTestCtx, const string &name, const string &desc)
1866 : TestCaseGroup(eglTestCtx, name.c_str(), desc.c_str())
1867 {
1868 }
1869
1870 void addCreateTexture(const string &name, EGLenum source, GLenum internalFormat, GLenum format, GLenum type);
1871 void addCreateRenderbuffer(const string &name, GLenum format);
1872 void addCreateAndroidNative(const string &name, GLenum format, bool isYUV);
1873 void addCreateAndroidNativeArray(const string &name, GLenum format, uint32_t numLayers);
1874 void addCreateTexture2DActions(const string &prefix);
1875 void addCreateTextureCubemapActions(const string &suffix, GLenum internalFormat, GLenum format, GLenum type);
1876 void addCreateRenderbufferActions(void);
1877 void addCreateAndroidNativeActions(void);
1878
1879 LabeledActions m_createActions;
1880 };
1881
addCreateTexture(const string & name,EGLenum source,GLenum internalFormat,GLenum format,GLenum type)1882 void ImageTests::addCreateTexture(const string &name, EGLenum source, GLenum internalFormat, GLenum format, GLenum type)
1883 {
1884 m_createActions.add(name, MovePtr<Action>(new GLESImageApi::Create(
1885 createTextureImageSource(source, internalFormat, format, type))));
1886 }
1887
addCreateRenderbuffer(const string & name,GLenum format)1888 void ImageTests::addCreateRenderbuffer(const string &name, GLenum format)
1889 {
1890 m_createActions.add(name, MovePtr<Action>(new GLESImageApi::Create(createRenderbufferImageSource(format))));
1891 }
1892
addCreateAndroidNative(const string & name,GLenum format,bool isYUV=false)1893 void ImageTests::addCreateAndroidNative(const string &name, GLenum format, bool isYUV = false)
1894 {
1895 m_createActions.add(name,
1896 MovePtr<Action>(new GLESImageApi::Create(createAndroidNativeImageSource(format, 1u, isYUV))));
1897 }
1898
addCreateAndroidNativeArray(const string & name,GLenum format,uint32_t numLayers)1899 void ImageTests::addCreateAndroidNativeArray(const string &name, GLenum format, uint32_t numLayers)
1900 {
1901 m_createActions.add(name, MovePtr<Action>(new GLESImageApi::Create(
1902 createAndroidNativeImageSource(format, numLayers, false), numLayers)));
1903 }
1904
addCreateTexture2DActions(const string & prefix)1905 void ImageTests::addCreateTexture2DActions(const string &prefix)
1906 {
1907 addCreateTexture(prefix + "rgb8", EGL_GL_TEXTURE_2D_KHR, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE);
1908 addCreateTexture(prefix + "rgb565", EGL_GL_TEXTURE_2D_KHR, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
1909 addCreateTexture(prefix + "rgba8", EGL_GL_TEXTURE_2D_KHR, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
1910 addCreateTexture(prefix + "rgb5_a1", EGL_GL_TEXTURE_2D_KHR, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
1911 addCreateTexture(prefix + "rgba4", EGL_GL_TEXTURE_2D_KHR, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
1912 }
1913
addCreateTextureCubemapActions(const string & suffix,GLenum internalFormat,GLenum format,GLenum type)1914 void ImageTests::addCreateTextureCubemapActions(const string &suffix, GLenum internalFormat, GLenum format, GLenum type)
1915 {
1916 addCreateTexture("cubemap_positive_x" + suffix, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR, internalFormat, format,
1917 type);
1918 addCreateTexture("cubemap_positive_y" + suffix, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR, internalFormat, format,
1919 type);
1920 addCreateTexture("cubemap_positive_z" + suffix, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR, internalFormat, format,
1921 type);
1922 addCreateTexture("cubemap_negative_x" + suffix, EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR, internalFormat, format,
1923 type);
1924 addCreateTexture("cubemap_negative_y" + suffix, EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR, internalFormat, format,
1925 type);
1926 addCreateTexture("cubemap_negative_z" + suffix, EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR, internalFormat, format,
1927 type);
1928 }
1929
addCreateRenderbufferActions(void)1930 void ImageTests::addCreateRenderbufferActions(void)
1931 {
1932 addCreateRenderbuffer("renderbuffer_rgba4", GL_RGBA4);
1933 addCreateRenderbuffer("renderbuffer_rgb5_a1", GL_RGB5_A1);
1934 addCreateRenderbuffer("renderbuffer_rgb565", GL_RGB565);
1935 addCreateRenderbuffer("renderbuffer_depth16", GL_DEPTH_COMPONENT16);
1936 addCreateRenderbuffer("renderbuffer_stencil", GL_STENCIL_INDEX8);
1937 }
1938
addCreateAndroidNativeActions(void)1939 void ImageTests::addCreateAndroidNativeActions(void)
1940 {
1941 addCreateAndroidNative("android_native_rgba4", GL_RGBA4);
1942 addCreateAndroidNative("android_native_rgb5_a1", GL_RGB5_A1);
1943 addCreateAndroidNative("android_native_rgb565", GL_RGB565);
1944 addCreateAndroidNative("android_native_rgb8", GL_RGB8);
1945 addCreateAndroidNative("android_native_rgba8", GL_RGBA8);
1946 addCreateAndroidNative("android_native_d16", GL_DEPTH_COMPONENT16);
1947 addCreateAndroidNative("android_native_d24", GL_DEPTH_COMPONENT24);
1948 addCreateAndroidNative("android_native_d24s8", GL_DEPTH24_STENCIL8);
1949 addCreateAndroidNative("android_native_d32f", GL_DEPTH_COMPONENT32F);
1950 addCreateAndroidNative("android_native_d32fs8", GL_DEPTH32F_STENCIL8);
1951 addCreateAndroidNative("android_native_rgb10a2", GL_RGB10_A2);
1952 addCreateAndroidNative("android_native_rgba16f", GL_RGBA16F);
1953 addCreateAndroidNative("android_native_s8", GL_STENCIL_INDEX8);
1954 addCreateAndroidNative("android_native_yuv420", GL_RGBA8, true);
1955
1956 addCreateAndroidNativeArray("android_native_array_rgba4", GL_RGBA4, 4u);
1957 addCreateAndroidNativeArray("android_native_array_rgb5_a1", GL_RGB5_A1, 4u);
1958 addCreateAndroidNativeArray("android_native_array_rgb565", GL_RGB565, 4u);
1959 addCreateAndroidNativeArray("android_native_array_rgb8", GL_RGB8, 4u);
1960 addCreateAndroidNativeArray("android_native_array_rgba8", GL_RGBA8, 4u);
1961 }
1962
1963 class RenderTests : public ImageTests
1964 {
1965 protected:
RenderTests(EglTestContext & eglTestCtx,const string & name,const string & desc)1966 RenderTests(EglTestContext &eglTestCtx, const string &name, const string &desc) : ImageTests(eglTestCtx, name, desc)
1967 {
1968 }
1969
1970 void addRenderActions(void);
1971 LabeledActions m_renderActions;
1972 };
1973
addRenderActions(void)1974 void RenderTests::addRenderActions(void)
1975 {
1976 m_renderActions.add("texture", MovePtr<Action>(new GLESImageApi::RenderTexture2D()));
1977 m_renderActions.add("texture_array", MovePtr<Action>(new GLESImageApi::RenderTexture2DArray()));
1978 m_renderActions.add("read_pixels", MovePtr<Action>(new GLESImageApi::RenderReadPixelsRenderbuffer()));
1979 m_renderActions.add("depth_buffer", MovePtr<Action>(new GLESImageApi::RenderDepthbuffer()));
1980 m_renderActions.add("stencil_buffer", MovePtr<Action>(new GLESImageApi::RenderStencilbuffer()));
1981 m_renderActions.add("yuv_texture", MovePtr<Action>(new GLESImageApi::RenderYUVTexture()));
1982 m_renderActions.add("render_sample_texture_array", MovePtr<Action>(new GLESImageApi::RenderSampleTexture2DArray()));
1983 }
1984
1985 class SimpleCreationTests : public RenderTests
1986 {
1987 public:
SimpleCreationTests(EglTestContext & eglTestCtx,const string & name,const string & desc)1988 SimpleCreationTests(EglTestContext &eglTestCtx, const string &name, const string &desc)
1989 : RenderTests(eglTestCtx, name, desc)
1990 {
1991 }
1992 void init(void);
1993 };
1994
isDepthFormat(GLenum format)1995 bool isDepthFormat(GLenum format)
1996 {
1997 switch (format)
1998 {
1999 case GL_RGB:
2000 case GL_RGB8:
2001 case GL_RGB565:
2002 case GL_RGBA:
2003 case GL_RGBA4:
2004 case GL_RGBA8:
2005 case GL_RGB5_A1:
2006 case GL_RGB10_A2:
2007 case GL_RGBA16F:
2008 return false;
2009
2010 case GL_DEPTH_COMPONENT16:
2011 case GL_DEPTH_COMPONENT24:
2012 case GL_DEPTH_COMPONENT32:
2013 case GL_DEPTH_COMPONENT32F:
2014 case GL_DEPTH24_STENCIL8:
2015 case GL_DEPTH32F_STENCIL8:
2016 return true;
2017
2018 case GL_STENCIL_INDEX8:
2019 return false;
2020
2021 default:
2022 DE_ASSERT(false);
2023 return false;
2024 }
2025 }
2026
isStencilFormat(GLenum format)2027 bool isStencilFormat(GLenum format)
2028 {
2029 switch (format)
2030 {
2031 case GL_RGB:
2032 case GL_RGB8:
2033 case GL_RGB565:
2034 case GL_RGBA:
2035 case GL_RGBA4:
2036 case GL_RGBA8:
2037 case GL_RGB5_A1:
2038 case GL_RGB10_A2:
2039 case GL_RGBA16F:
2040 return false;
2041
2042 case GL_DEPTH_COMPONENT16:
2043 case GL_DEPTH_COMPONENT24:
2044 case GL_DEPTH_COMPONENT32:
2045 case GL_DEPTH_COMPONENT32F:
2046 return false;
2047
2048 case GL_STENCIL_INDEX8:
2049 case GL_DEPTH24_STENCIL8:
2050 case GL_DEPTH32F_STENCIL8:
2051 return true;
2052
2053 default:
2054 DE_ASSERT(false);
2055 return false;
2056 }
2057 }
2058
isCompatibleCreateAndRenderActions(const Action & create,const Action & render)2059 bool isCompatibleCreateAndRenderActions(const Action &create, const Action &render)
2060 {
2061 if (const GLESImageApi::Create *glesCreate = dynamic_cast<const GLESImageApi::Create *>(&create))
2062 {
2063 bool yuvFormatTest = glesCreate->isYUVFormatImage();
2064 // this path only for none-yuv format tests
2065 if (!yuvFormatTest)
2066 {
2067 const GLenum createFormat = glesCreate->getEffectiveFormat();
2068
2069 if (dynamic_cast<const GLESImageApi::RenderTexture2DArray *>(&render))
2070 {
2071 // Makes sense only for texture arrays.
2072 if (glesCreate->getNumLayers() <= 1u)
2073 return false;
2074 }
2075 else if (glesCreate->getNumLayers() != 1u)
2076 {
2077 // Skip other render actions for texture arrays.
2078 return false;
2079 }
2080
2081 if (dynamic_cast<const GLESImageApi::RenderTexture2D *>(&render))
2082 {
2083 // GLES does not have depth or stencil textures
2084 if (isDepthFormat(createFormat) || isStencilFormat(createFormat))
2085 return false;
2086 }
2087
2088 if (dynamic_cast<const GLESImageApi::RenderReadPixelsRenderbuffer *>(&render))
2089 {
2090 // GLES does not support readPixels for depth or stencil.
2091 if (isDepthFormat(createFormat) || isStencilFormat(createFormat))
2092 return false;
2093 }
2094
2095 if (dynamic_cast<const GLESImageApi::RenderDepthbuffer *>(&render))
2096 {
2097 // Copying non-depth data to depth renderbuffer and expecting meaningful
2098 // results just doesn't make any sense.
2099 if (!isDepthFormat(createFormat))
2100 return false;
2101 }
2102
2103 if (dynamic_cast<const GLESImageApi::RenderStencilbuffer *>(&render))
2104 {
2105 // Copying non-stencil data to stencil renderbuffer and expecting meaningful
2106 // results just doesn't make any sense.
2107 if (!isStencilFormat(createFormat))
2108 return false;
2109 }
2110
2111 if (dynamic_cast<const GLESImageApi::RenderYUVTexture *>(&render))
2112 {
2113 // In yuv path rendering with non-yuv format native buffer and expecting meaningful
2114 // results just doesn't make any sense
2115 return false;
2116 }
2117
2118 return true;
2119 }
2120 else if (dynamic_cast<const GLESImageApi::RenderYUVTexture *>(&render))
2121 {
2122 return true;
2123 }
2124 }
2125 else
2126 DE_ASSERT(false);
2127
2128 return false;
2129 }
2130
init(void)2131 void SimpleCreationTests::init(void)
2132 {
2133 addCreateTexture2DActions("texture_");
2134 addCreateTextureCubemapActions("_rgba", GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
2135 addCreateTextureCubemapActions("_rgb", GL_RGB, GL_RGB, GL_UNSIGNED_BYTE);
2136 addCreateRenderbufferActions();
2137 addCreateAndroidNativeActions();
2138 addRenderActions();
2139
2140 for (int createNdx = 0; createNdx < m_createActions.size(); createNdx++)
2141 {
2142 const LabeledAction &createAction = m_createActions[createNdx];
2143
2144 for (int renderNdx = 0; renderNdx < m_renderActions.size(); renderNdx++)
2145 {
2146 const LabeledAction &renderAction = m_renderActions[renderNdx];
2147 TestSpec spec;
2148
2149 if (!isCompatibleCreateAndRenderActions(*createAction.action, *renderAction.action))
2150 continue;
2151
2152 if (dynamic_cast<const GLESImageApi::RenderTexture2DArray *>(renderAction.action.get()) ||
2153 dynamic_cast<const GLESImageApi::RenderYUVTexture *>(renderAction.action.get()) ||
2154 dynamic_cast<const GLESImageApi::RenderSampleTexture2DArray *>(renderAction.action.get()))
2155 {
2156 // Texture array tests require GLES3.
2157 spec.name = std::string("gles3_") + createAction.label + "_" + renderAction.label;
2158 spec.contexts.push_back(TestSpec::API_GLES3);
2159 }
2160 else
2161 {
2162 spec.name = std::string("gles2_") + createAction.label + "_" + renderAction.label;
2163 spec.contexts.push_back(TestSpec::API_GLES2);
2164 }
2165
2166 spec.desc = spec.name;
2167 spec.operations.push_back(TestSpec::Operation(0, *createAction.action));
2168 spec.operations.push_back(TestSpec::Operation(0, *renderAction.action));
2169
2170 addChild(new ImageFormatCase(m_eglTestCtx, spec));
2171 }
2172 }
2173 }
2174
createSimpleCreationTests(EglTestContext & eglTestCtx,const string & name,const string & desc)2175 TestCaseGroup *createSimpleCreationTests(EglTestContext &eglTestCtx, const string &name, const string &desc)
2176 {
2177 return new SimpleCreationTests(eglTestCtx, name, desc);
2178 }
2179
isCompatibleFormats(GLenum createFormat,GLenum modifyFormat,GLenum modifyType)2180 bool isCompatibleFormats(GLenum createFormat, GLenum modifyFormat, GLenum modifyType)
2181 {
2182 switch (modifyFormat)
2183 {
2184 case GL_RGB:
2185 switch (modifyType)
2186 {
2187 case GL_UNSIGNED_BYTE:
2188 return createFormat == GL_RGB || createFormat == GL_RGB8 || createFormat == GL_RGB565 ||
2189 createFormat == GL_SRGB8;
2190
2191 case GL_BYTE:
2192 return createFormat == GL_RGB8_SNORM;
2193
2194 case GL_UNSIGNED_SHORT_5_6_5:
2195 return createFormat == GL_RGB || createFormat == GL_RGB565;
2196
2197 case GL_UNSIGNED_INT_10F_11F_11F_REV:
2198 return createFormat == GL_R11F_G11F_B10F;
2199
2200 case GL_UNSIGNED_INT_5_9_9_9_REV:
2201 return createFormat == GL_RGB9_E5;
2202
2203 case GL_HALF_FLOAT:
2204 return createFormat == GL_RGB16F || createFormat == GL_R11F_G11F_B10F || createFormat == GL_RGB9_E5;
2205
2206 case GL_FLOAT:
2207 return createFormat == GL_RGB16F || createFormat == GL_RGB32F || createFormat == GL_R11F_G11F_B10F ||
2208 createFormat == GL_RGB9_E5;
2209
2210 default:
2211 DE_FATAL("Unknown modify type");
2212 return false;
2213 }
2214
2215 case GL_RGBA:
2216 switch (modifyType)
2217 {
2218 case GL_UNSIGNED_BYTE:
2219 return createFormat == GL_RGBA8 || createFormat == GL_RGB5_A1 || createFormat == GL_RGBA4 ||
2220 createFormat == GL_SRGB8_ALPHA8 || createFormat == GL_RGBA;
2221
2222 case GL_UNSIGNED_SHORT_4_4_4_4:
2223 return createFormat == GL_RGBA4 || createFormat == GL_RGBA;
2224
2225 case GL_UNSIGNED_SHORT_5_5_5_1:
2226 return createFormat == GL_RGB5_A1 || createFormat == GL_RGBA;
2227
2228 case GL_UNSIGNED_INT_2_10_10_10_REV:
2229 return createFormat == GL_RGB10_A2 || createFormat == GL_RGB5_A1;
2230
2231 case GL_HALF_FLOAT:
2232 return createFormat == GL_RGBA16F;
2233
2234 case GL_FLOAT:
2235 return createFormat == GL_RGBA16F || createFormat == GL_RGBA32F;
2236
2237 default:
2238 DE_FATAL("Unknown modify type");
2239 return false;
2240 }
2241
2242 default:
2243 DE_FATAL("Unknown modify format");
2244 return false;
2245 }
2246 }
2247
isCompatibleCreateAndModifyActions(const Action & create,const Action & modify)2248 bool isCompatibleCreateAndModifyActions(const Action &create, const Action &modify)
2249 {
2250 if (const GLESImageApi::Create *glesCreate = dynamic_cast<const GLESImageApi::Create *>(&create))
2251 {
2252 // No modify tests for texture arrays.
2253 if (glesCreate->getNumLayers() > 1u)
2254 return false;
2255 // No modify tests for yuv format image.
2256 if (glesCreate->isYUVFormatImage())
2257 return false;
2258
2259 const GLenum createFormat = glesCreate->getEffectiveFormat();
2260
2261 if (const GLESImageApi::ModifyTexSubImage *glesTexSubImageModify =
2262 dynamic_cast<const GLESImageApi::ModifyTexSubImage *>(&modify))
2263 {
2264 const GLenum modifyFormat = glesTexSubImageModify->getFormat();
2265 const GLenum modifyType = glesTexSubImageModify->getType();
2266
2267 return isCompatibleFormats(createFormat, modifyFormat, modifyType);
2268 }
2269
2270 if (dynamic_cast<const GLESImageApi::ModifyRenderbufferClearColor *>(&modify))
2271 {
2272 // reintepreting color as non-color is not meaningful
2273 if (isDepthFormat(createFormat) || isStencilFormat(createFormat))
2274 return false;
2275 }
2276
2277 if (dynamic_cast<const GLESImageApi::ModifyRenderbufferClearDepth *>(&modify))
2278 {
2279 // reintepreting depth as non-depth is not meaningful
2280 if (!isDepthFormat(createFormat))
2281 return false;
2282 }
2283
2284 if (dynamic_cast<const GLESImageApi::ModifyRenderbufferClearStencil *>(&modify))
2285 {
2286 // reintepreting stencil as non-stencil is not meaningful
2287 if (!isStencilFormat(createFormat))
2288 return false;
2289 }
2290
2291 return true;
2292 }
2293 else
2294 DE_ASSERT(false);
2295
2296 return false;
2297 }
2298
2299 class MultiContextRenderTests : public RenderTests
2300 {
2301 public:
2302 MultiContextRenderTests(EglTestContext &eglTestCtx, const string &name, const string &desc);
2303 void init(void);
2304 void addClearActions(void);
2305
2306 private:
2307 LabeledActions m_clearActions;
2308 };
2309
MultiContextRenderTests(EglTestContext & eglTestCtx,const string & name,const string & desc)2310 MultiContextRenderTests::MultiContextRenderTests(EglTestContext &eglTestCtx, const string &name, const string &desc)
2311 : RenderTests(eglTestCtx, name, desc)
2312 {
2313 }
2314
addClearActions(void)2315 void MultiContextRenderTests::addClearActions(void)
2316 {
2317 m_clearActions.add("clear_color", MovePtr<Action>(new GLESImageApi::ModifyRenderbufferClearColor(
2318 tcu::Vec4(0.8f, 0.2f, 0.9f, 1.0f))));
2319 m_clearActions.add("clear_depth", MovePtr<Action>(new GLESImageApi::ModifyRenderbufferClearDepth(0.75f)));
2320 m_clearActions.add("clear_stencil", MovePtr<Action>(new GLESImageApi::ModifyRenderbufferClearStencil(97)));
2321 }
2322
init(void)2323 void MultiContextRenderTests::init(void)
2324 {
2325 addCreateTexture2DActions("texture_");
2326 addCreateTextureCubemapActions("_rgba8", GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
2327 addCreateTextureCubemapActions("_rgb8", GL_RGB, GL_RGB, GL_UNSIGNED_BYTE);
2328 addCreateRenderbufferActions();
2329 addCreateAndroidNativeActions();
2330 addRenderActions();
2331 addClearActions();
2332
2333 for (int createNdx = 0; createNdx < m_createActions.size(); createNdx++)
2334 for (int renderNdx = 0; renderNdx < m_renderActions.size(); renderNdx++)
2335 for (int clearNdx = 0; clearNdx < m_clearActions.size(); clearNdx++)
2336 {
2337 const LabeledAction &createAction = m_createActions[createNdx];
2338 const LabeledAction &renderAction = m_renderActions[renderNdx];
2339 const LabeledAction &clearAction = m_clearActions[clearNdx];
2340 TestSpec spec;
2341
2342 if (!isCompatibleCreateAndRenderActions(*createAction.action, *renderAction.action))
2343 continue;
2344 if (!isCompatibleCreateAndModifyActions(*createAction.action, *clearAction.action))
2345 continue;
2346
2347 spec.name = std::string("gles2_") + createAction.label + "_" + renderAction.label;
2348
2349 const GLESImageApi::Create *glesCreate =
2350 dynamic_cast<const GLESImageApi::Create *>(createAction.action.get());
2351
2352 if (!glesCreate)
2353 DE_FATAL("Dynamic casting to GLESImageApi::Create* failed");
2354
2355 const GLenum createFormat = glesCreate->getEffectiveFormat();
2356
2357 if (isDepthFormat(createFormat) && isStencilFormat(createFormat))
2358 {
2359 // Combined depth and stencil format. Add the clear action label to avoid test
2360 // name clashes.
2361 spec.name += std::string("_") + clearAction.label;
2362 }
2363
2364 spec.desc = spec.name;
2365
2366 spec.contexts.push_back(TestSpec::API_GLES2);
2367 spec.contexts.push_back(TestSpec::API_GLES2);
2368
2369 spec.operations.push_back(TestSpec::Operation(0, *createAction.action));
2370 spec.operations.push_back(TestSpec::Operation(0, *renderAction.action));
2371 spec.operations.push_back(TestSpec::Operation(0, *clearAction.action));
2372 spec.operations.push_back(TestSpec::Operation(1, *createAction.action));
2373 spec.operations.push_back(TestSpec::Operation(0, *renderAction.action));
2374 spec.operations.push_back(TestSpec::Operation(1, *renderAction.action));
2375
2376 addChild(new ImageFormatCase(m_eglTestCtx, spec));
2377 }
2378 }
2379
createMultiContextRenderTests(EglTestContext & eglTestCtx,const string & name,const string & desc)2380 TestCaseGroup *createMultiContextRenderTests(EglTestContext &eglTestCtx, const string &name, const string &desc)
2381 {
2382 return new MultiContextRenderTests(eglTestCtx, name, desc);
2383 }
2384
2385 class ModifyTests : public ImageTests
2386 {
2387 public:
ModifyTests(EglTestContext & eglTestCtx,const string & name,const string & desc)2388 ModifyTests(EglTestContext &eglTestCtx, const string &name, const string &desc) : ImageTests(eglTestCtx, name, desc)
2389 {
2390 }
2391
2392 void init(void);
2393
2394 protected:
2395 void addModifyActions(void);
2396
2397 LabeledActions m_modifyActions;
2398 GLESImageApi::RenderTryAll m_renderAction;
2399 };
2400
addModifyActions(void)2401 void ModifyTests::addModifyActions(void)
2402 {
2403 m_modifyActions.add("tex_subimage_rgb8",
2404 MovePtr<Action>(new GLESImageApi::ModifyTexSubImage(GL_RGB, GL_UNSIGNED_BYTE)));
2405 m_modifyActions.add("tex_subimage_rgb565",
2406 MovePtr<Action>(new GLESImageApi::ModifyTexSubImage(GL_RGB, GL_UNSIGNED_SHORT_5_6_5)));
2407 m_modifyActions.add("tex_subimage_rgba8",
2408 MovePtr<Action>(new GLESImageApi::ModifyTexSubImage(GL_RGBA, GL_UNSIGNED_BYTE)));
2409 m_modifyActions.add("tex_subimage_rgb5_a1",
2410 MovePtr<Action>(new GLESImageApi::ModifyTexSubImage(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1)));
2411 m_modifyActions.add("tex_subimage_rgba4",
2412 MovePtr<Action>(new GLESImageApi::ModifyTexSubImage(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4)));
2413
2414 m_modifyActions.add("renderbuffer_clear_color", MovePtr<Action>(new GLESImageApi::ModifyRenderbufferClearColor(
2415 tcu::Vec4(0.4f, 0.5f, 0.6f, 1.0f))));
2416 m_modifyActions.add("renderbuffer_clear_depth",
2417 MovePtr<Action>(new GLESImageApi::ModifyRenderbufferClearDepth(0.7f)));
2418 m_modifyActions.add("renderbuffer_clear_stencil",
2419 MovePtr<Action>(new GLESImageApi::ModifyRenderbufferClearStencil(78)));
2420 }
2421
init(void)2422 void ModifyTests::init(void)
2423 {
2424 addCreateTexture2DActions("tex_");
2425 addCreateRenderbufferActions();
2426 addCreateAndroidNativeActions();
2427 addModifyActions();
2428
2429 for (int createNdx = 0; createNdx < m_createActions.size(); createNdx++)
2430 {
2431 LabeledAction &createAction = m_createActions[createNdx];
2432
2433 for (int modifyNdx = 0; modifyNdx < m_modifyActions.size(); modifyNdx++)
2434 {
2435 LabeledAction &modifyAction = m_modifyActions[modifyNdx];
2436
2437 if (!isCompatibleCreateAndModifyActions(*createAction.action, *modifyAction.action))
2438 continue;
2439
2440 TestSpec spec;
2441 spec.name = createAction.label + "_" + modifyAction.label;
2442 spec.desc = "gles2_tex_sub_image";
2443
2444 spec.contexts.push_back(TestSpec::API_GLES2);
2445
2446 spec.operations.push_back(TestSpec::Operation(0, *createAction.action));
2447 spec.operations.push_back(TestSpec::Operation(0, m_renderAction));
2448 spec.operations.push_back(TestSpec::Operation(0, *modifyAction.action));
2449 spec.operations.push_back(TestSpec::Operation(0, m_renderAction));
2450
2451 addChild(new ImageFormatCase(m_eglTestCtx, spec));
2452 }
2453 }
2454 }
2455
createModifyTests(EglTestContext & eglTestCtx,const string & name,const string & desc)2456 TestCaseGroup *createModifyTests(EglTestContext &eglTestCtx, const string &name, const string &desc)
2457 {
2458 return new ModifyTests(eglTestCtx, name, desc);
2459 }
2460
2461 } // namespace Image
2462 } // namespace egl
2463 } // namespace deqp
2464