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