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