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_VG
134 //API_GLES1
135
136 API_LAST
137 };
138
139 struct Operation
140 {
Operationdeqp::egl::Image::TestSpec::Operation141 Operation (int apiIndex_, const Action& action_) : apiIndex(apiIndex_), action(&action_) {}
142 int apiIndex;
143 const Action* action;
144 };
145
146 vector<ApiContext> contexts;
147 vector<Operation> operations;
148
149 };
150
151 class ImageApi
152 {
153 public:
154 ImageApi (const Library& egl, int contextId, EGLDisplay display, EGLSurface surface);
~ImageApi(void)155 virtual ~ImageApi (void) {}
156
157 protected:
158 const Library& m_egl;
159 int m_contextId;
160 EGLDisplay m_display;
161 EGLSurface m_surface;
162 };
163
ImageApi(const Library & egl,int contextId,EGLDisplay display,EGLSurface surface)164 ImageApi::ImageApi (const Library& egl, int contextId, EGLDisplay display, EGLSurface surface)
165 : m_egl (egl)
166 , m_contextId (contextId)
167 , m_display (display)
168 , m_surface (surface)
169 {
170 }
171
172 class GLES2ImageApi : public ImageApi, private glu::CallLogWrapper
173 {
174 public:
175 class GLES2Action : public Action
176 {
177 public:
178 bool invoke (ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const;
179 virtual bool invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const = 0;
180 };
181
182 class Create : public GLES2Action
183 {
184 public:
Create(MovePtr<ImageSource> imgSource)185 Create (MovePtr<ImageSource> imgSource) : m_imgSource(imgSource) {}
getRequiredExtension(void) const186 string getRequiredExtension (void) const { return m_imgSource->getRequiredExtension(); }
187 bool invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const;
getEffectiveFormat(void) const188 glw::GLenum getEffectiveFormat (void) const { return m_imgSource->getEffectiveFormat(); }
189
190 private:
191 UniquePtr<ImageSource> m_imgSource;
192 };
193
194 class Render : public GLES2Action
195 {
196 public:
getRequiredExtension(void) const197 string getRequiredExtension (void) const { return "GL_OES_EGL_image"; }
198 };
199
200 class RenderTexture2D : public Render { public: bool invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const; };
201 class RenderTextureCubemap : public Render { public: bool invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const; };
202 class RenderReadPixelsRenderbuffer : public Render { public: bool invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const; };
203 class RenderDepthbuffer : public Render { public: bool invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const; };
204 class RenderStencilbuffer : public Render { public: bool invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const; };
205 class RenderTryAll : public Render { public: bool invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const; };
206
207 class Modify : public GLES2Action
208 {
209 public:
getRequiredExtension(void) const210 string getRequiredExtension (void) const { return "GL_OES_EGL_image"; }
211 };
212
213 class ModifyTexSubImage : public Modify
214 {
215 public:
ModifyTexSubImage(GLenum format,GLenum type)216 ModifyTexSubImage (GLenum format, GLenum type) : m_format(format), m_type(type) {}
217 bool invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const;
getFormat(void) const218 GLenum getFormat (void) const { return m_format; }
getType(void) const219 GLenum getType (void) const { return m_type; }
220
221 private:
222 GLenum m_format;
223 GLenum m_type;
224 };
225
226 class ModifyRenderbuffer : public Modify
227 {
228 public:
229 bool invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const;
230
231 protected:
232 virtual void initializeRbo (GLES2ImageApi& api, GLuint rbo, tcu::Texture2D& ref) const = 0;
233 };
234
235 class ModifyRenderbufferClearColor : public ModifyRenderbuffer
236 {
237 public:
ModifyRenderbufferClearColor(tcu::Vec4 color)238 ModifyRenderbufferClearColor (tcu::Vec4 color) : m_color(color) {}
239
240 protected:
241 void initializeRbo (GLES2ImageApi& api, GLuint rbo, tcu::Texture2D& ref) const;
242
243 tcu::Vec4 m_color;
244 };
245
246 class ModifyRenderbufferClearDepth : public ModifyRenderbuffer
247 {
248 public:
ModifyRenderbufferClearDepth(GLfloat depth)249 ModifyRenderbufferClearDepth (GLfloat depth) : m_depth(depth) {}
250
251 protected:
252 void initializeRbo (GLES2ImageApi& api, GLuint rbo, tcu::Texture2D& ref) const;
253
254 GLfloat m_depth;
255 };
256
257 class ModifyRenderbufferClearStencil : public ModifyRenderbuffer
258 {
259 public:
ModifyRenderbufferClearStencil(GLint stencil)260 ModifyRenderbufferClearStencil (GLint stencil) : m_stencil(stencil) {}
261
262 protected:
263 void initializeRbo (GLES2ImageApi& api, GLuint rbo, tcu::Texture2D& ref) const;
264
265 GLint m_stencil;
266 };
267
268 GLES2ImageApi (const Library& egl, const glw::Functions& gl, int contextId, tcu::TestLog& log, EGLDisplay display, EGLSurface surface, EGLConfig config);
269 ~GLES2ImageApi (void);
270
271 private:
272 EGLContext m_context;
273 const glw::Functions& m_gl;
274
275 MovePtr<UniqueImage> createImage (const ImageSource& source, const ClientBuffer& buffer) const;
276 };
277
GLES2ImageApi(const Library & egl,const glw::Functions & gl,int contextId,tcu::TestLog & log,EGLDisplay display,EGLSurface surface,EGLConfig config)278 GLES2ImageApi::GLES2ImageApi (const Library& egl, const glw::Functions& gl, int contextId, tcu::TestLog& log, EGLDisplay display, EGLSurface surface, EGLConfig config)
279 : ImageApi (egl, contextId, display, surface)
280 , glu::CallLogWrapper (gl, log)
281 , m_context (DE_NULL)
282 , m_gl (gl)
283 {
284 const EGLint attriblist[] =
285 {
286 EGL_CONTEXT_CLIENT_VERSION, 2,
287 EGL_NONE
288 };
289
290 EGLint configId = -1;
291 EGLU_CHECK_CALL(m_egl, getConfigAttrib(m_display, config, EGL_CONFIG_ID, &configId));
292 getLog() << tcu::TestLog::Message << "Creating gles2 context with config id: " << configId << " context: " << m_contextId << tcu::TestLog::EndMessage;
293 egl.bindAPI(EGL_OPENGL_ES_API);
294 m_context = m_egl.createContext(m_display, config, EGL_NO_CONTEXT, attriblist);
295 EGLU_CHECK_MSG(m_egl, "Failed to create GLES2 context");
296
297 egl.makeCurrent(display, m_surface, m_surface, m_context);
298 EGLU_CHECK_MSG(m_egl, "Failed to make context current");
299 }
300
~GLES2ImageApi(void)301 GLES2ImageApi::~GLES2ImageApi (void)
302 {
303 m_egl.makeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
304 m_egl.destroyContext(m_display, m_context);
305 }
306
invoke(ImageApi & api,MovePtr<UniqueImage> & image,tcu::Texture2D & ref) const307 bool GLES2ImageApi::GLES2Action::invoke (ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const
308 {
309 GLES2ImageApi& gles2Api = dynamic_cast<GLES2ImageApi&>(api);
310
311 gles2Api.m_egl.makeCurrent(gles2Api.m_display, gles2Api.m_surface, gles2Api.m_surface, gles2Api.m_context);
312 return invokeGLES2(gles2Api, image, ref);
313 }
314
315
invokeGLES2(GLES2ImageApi & api,MovePtr<UniqueImage> & image,tcu::Texture2D & ref) const316 bool GLES2ImageApi::Create::invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const
317 {
318 de::UniquePtr<ClientBuffer> buffer (m_imgSource->createBuffer(api.m_egl, api.m_gl, &ref));
319
320 GLU_CHECK_GLW_CALL(api.m_gl, finish());
321
322 image = api.createImage(*m_imgSource, *buffer);
323 return true;
324 }
325
createImage(const ImageSource & source,const ClientBuffer & buffer) const326 MovePtr<UniqueImage> GLES2ImageApi::createImage (const ImageSource& source, const ClientBuffer& buffer) const
327 {
328 const EGLImageKHR image = source.createImage(m_egl, m_display, m_context, buffer.get());
329 return MovePtr<UniqueImage>(new UniqueImage(m_egl, m_display, image));
330 }
331
imageTargetTexture2D(const Library & egl,const glw::Functions & gl,GLeglImageOES img)332 static void imageTargetTexture2D (const Library& egl, const glw::Functions& gl, GLeglImageOES img)
333 {
334 gl.eglImageTargetTexture2DOES(GL_TEXTURE_2D, img);
335 {
336 const GLenum error = gl.getError();
337
338 if (error == GL_INVALID_OPERATION)
339 TCU_THROW(NotSupportedError, "Creating texture2D from EGLImage type not supported");
340
341 GLU_EXPECT_NO_ERROR(error, "glEGLImageTargetTexture2DOES()");
342 EGLU_CHECK_MSG(egl, "glEGLImageTargetTexture2DOES()");
343 }
344 }
345
imageTargetRenderbuffer(const Library & egl,const glw::Functions & gl,GLeglImageOES img)346 static void imageTargetRenderbuffer (const Library& egl, const glw::Functions& gl, GLeglImageOES img)
347 {
348 gl.eglImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, img);
349 {
350 const GLenum error = gl.getError();
351
352 if (error == GL_INVALID_OPERATION)
353 TCU_THROW(NotSupportedError, "Creating renderbuffer from EGLImage type not supported");
354
355 GLU_EXPECT_NO_ERROR(error, "glEGLImageTargetRenderbufferStorageOES()");
356 EGLU_CHECK_MSG(egl, "glEGLImageTargetRenderbufferStorageOES()");
357 }
358 }
359
framebufferRenderbuffer(const glw::Functions & gl,GLenum attachment,GLuint rbo)360 static void framebufferRenderbuffer (const glw::Functions& gl, GLenum attachment, GLuint rbo)
361 {
362 GLU_CHECK_GLW_CALL(gl, framebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, rbo));
363 TCU_CHECK_AND_THROW(NotSupportedError,
364 gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE,
365 ("EGLImage as " + string(glu::getFramebufferAttachmentName(attachment)) + " not supported").c_str());
366 }
367
368 static const float squareTriangleCoords[] =
369 {
370 -1.0, -1.0,
371 1.0, -1.0,
372 1.0, 1.0,
373
374 1.0, 1.0,
375 -1.0, 1.0,
376 -1.0, -1.0
377 };
378
invokeGLES2(GLES2ImageApi & api,MovePtr<UniqueImage> & img,tcu::Texture2D & reference) const379 bool GLES2ImageApi::RenderTexture2D::invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
380 {
381 const glw::Functions& gl = api.m_gl;
382 tcu::TestLog& log = api.getLog();
383 Texture srcTex (gl);
384
385 // Branch only taken in TryAll case
386 if (reference.getFormat().order == tcu::TextureFormat::DS || reference.getFormat().order == tcu::TextureFormat::D)
387 throw IllegalRendererException(); // Skip, GLES2 does not support sampling depth textures
388 if (reference.getFormat().order == tcu::TextureFormat::S)
389 throw IllegalRendererException(); // Skip, GLES2 does not support sampling stencil textures
390
391 gl.clearColor(0.0, 0.0, 0.0, 0.0);
392 gl.viewport(0, 0, reference.getWidth(), reference.getHeight());
393 gl.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
394 gl.disable(GL_DEPTH_TEST);
395
396 log << tcu::TestLog::Message << "Rendering EGLImage as GL_TEXTURE_2D in context: " << api.m_contextId << tcu::TestLog::EndMessage;
397 TCU_CHECK(**img != EGL_NO_IMAGE_KHR);
398
399 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, *srcTex));
400 imageTargetTexture2D(api.m_egl, gl, **img);
401
402 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
403 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
404 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
405 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
406
407 const char* const vertexShader =
408 "attribute highp vec2 a_coord;\n"
409 "varying mediump vec2 v_texCoord;\n"
410 "void main(void) {\n"
411 "\tv_texCoord = vec2((a_coord.x + 1.0) * 0.5, (a_coord.y + 1.0) * 0.5);\n"
412 "\tgl_Position = vec4(a_coord, -0.1, 1.0);\n"
413 "}\n";
414
415 const char* const fragmentShader =
416 "varying mediump vec2 v_texCoord;\n"
417 "uniform sampler2D u_sampler;\n"
418 "void main(void) {\n"
419 "\tmediump vec4 texColor = texture2D(u_sampler, v_texCoord);\n"
420 "\tgl_FragColor = vec4(texColor);\n"
421 "}";
422
423 Program program(gl, vertexShader, fragmentShader);
424 TCU_CHECK(program.isOk());
425
426 GLuint glProgram = program.getProgram();
427 GLU_CHECK_GLW_CALL(gl, useProgram(glProgram));
428
429 GLuint coordLoc = gl.getAttribLocation(glProgram, "a_coord");
430 TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute a_coord");
431
432 GLuint samplerLoc = gl.getUniformLocation(glProgram, "u_sampler");
433 TCU_CHECK_MSG((int)samplerLoc != (int)-1, "Couldn't find uniform u_sampler");
434
435 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, *srcTex));
436 GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc, 0));
437 GLU_CHECK_GLW_CALL(gl, enableVertexAttribArray(coordLoc));
438 GLU_CHECK_GLW_CALL(gl, vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, squareTriangleCoords));
439
440 GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6));
441 GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc));
442 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, 0));
443
444 tcu::Surface refSurface (reference.getWidth(), reference.getHeight());
445 tcu::Surface screen (reference.getWidth(), reference.getHeight());
446 GLU_CHECK_GLW_CALL(gl, readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr()));
447
448 tcu::copy(refSurface.getAccess(), reference.getLevel(0));
449
450 float threshold = 0.05f;
451 bool match = tcu::fuzzyCompare(log, "ComparisonResult", "Image comparison result", refSurface, screen, threshold, tcu::COMPARE_LOG_RESULT);
452
453 return match;
454 }
455
invokeGLES2(GLES2ImageApi & api,MovePtr<UniqueImage> & img,tcu::Texture2D & reference) const456 bool GLES2ImageApi::RenderDepthbuffer::invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
457 {
458 const glw::Functions& gl = api.m_gl;
459 tcu::TestLog& log = api.getLog();
460 Framebuffer framebuffer (gl);
461 Renderbuffer renderbufferColor (gl);
462 Renderbuffer renderbufferDepth (gl);
463 const tcu::RGBA compareThreshold (32, 32, 32, 32); // layer colors are far apart, large thresholds are ok
464
465 // Branch only taken in TryAll case
466 if (reference.getFormat().order != tcu::TextureFormat::DS && reference.getFormat().order != tcu::TextureFormat::D)
467 throw IllegalRendererException(); // Skip, interpreting non-depth data as depth data is not meaningful
468
469 log << tcu::TestLog::Message << "Rendering with depth buffer" << tcu::TestLog::EndMessage;
470
471 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, *framebuffer));
472
473 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbufferColor));
474 GLU_CHECK_GLW_CALL(gl, renderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, reference.getWidth(), reference.getHeight()));
475 framebufferRenderbuffer(gl, GL_COLOR_ATTACHMENT0, *renderbufferColor);
476
477 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbufferDepth));
478 imageTargetRenderbuffer(api.m_egl, gl, **img);
479 framebufferRenderbuffer(gl, GL_DEPTH_ATTACHMENT, *renderbufferDepth);
480 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, 0));
481
482 GLU_CHECK_GLW_CALL(gl, viewport(0, 0, reference.getWidth(), reference.getHeight()));
483
484 // Render
485 const char* vertexShader =
486 "attribute highp vec2 a_coord;\n"
487 "uniform highp float u_depth;\n"
488 "void main(void) {\n"
489 "\tgl_Position = vec4(a_coord, u_depth, 1.0);\n"
490 "}\n";
491
492 const char* fragmentShader =
493 "uniform mediump vec4 u_color;\n"
494 "void main(void) {\n"
495 "\tgl_FragColor = u_color;\n"
496 "}";
497
498 Program program(gl, vertexShader, fragmentShader);
499 TCU_CHECK(program.isOk());
500
501 GLuint glProgram = program.getProgram();
502 GLU_CHECK_GLW_CALL(gl, useProgram(glProgram));
503
504 GLuint coordLoc = gl.getAttribLocation(glProgram, "a_coord");
505 TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute a_coord");
506
507 GLuint colorLoc = gl.getUniformLocation(glProgram, "u_color");
508 TCU_CHECK_MSG((int)colorLoc != (int)-1, "Couldn't find uniform u_color");
509
510 GLuint depthLoc = gl.getUniformLocation(glProgram, "u_depth");
511 TCU_CHECK_MSG((int)depthLoc != (int)-1, "Couldn't find uniform u_depth");
512
513 GLU_CHECK_GLW_CALL(gl, clearColor(0.5f, 1.0f, 0.5f, 1.0f));
514 GLU_CHECK_GLW_CALL(gl, clear(GL_COLOR_BUFFER_BIT));
515
516 tcu::Vec4 depthLevelColors[] = {
517 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
518 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
519 tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),
520 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
521 tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f),
522
523 tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),
524 tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f),
525 tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f),
526 tcu::Vec4(0.0f, 0.5f, 0.0f, 1.0f),
527 tcu::Vec4(0.5f, 0.5f, 0.0f, 1.0f)
528 };
529
530 GLU_CHECK_GLW_CALL(gl, enableVertexAttribArray(coordLoc));
531 GLU_CHECK_GLW_CALL(gl, vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, squareTriangleCoords));
532
533 GLU_CHECK_GLW_CALL(gl, enable(GL_DEPTH_TEST));
534 GLU_CHECK_GLW_CALL(gl, depthFunc(GL_LESS));
535 GLU_CHECK_GLW_CALL(gl, depthMask(GL_FALSE));
536
537 for (int level = 0; level < DE_LENGTH_OF_ARRAY(depthLevelColors); level++)
538 {
539 const tcu::Vec4 color = depthLevelColors[level];
540 const float clipDepth = ((float)(level + 1) * 0.1f) * 2.0f - 1.0f; // depth in clip coords
541
542 GLU_CHECK_GLW_CALL(gl, uniform4f(colorLoc, color.x(), color.y(), color.z(), color.w()));
543 GLU_CHECK_GLW_CALL(gl, uniform1f(depthLoc, clipDepth));
544 GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6));
545 }
546
547 GLU_CHECK_GLW_CALL(gl, depthMask(GL_TRUE));
548 GLU_CHECK_GLW_CALL(gl, disable(GL_DEPTH_TEST));
549 GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc));
550
551 const ConstPixelBufferAccess& refAccess = reference.getLevel(0);
552 tcu::Surface screen (reference.getWidth(), reference.getHeight());
553 tcu::Surface referenceScreen (reference.getWidth(), reference.getHeight());
554
555 gl.readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr());
556
557 for (int y = 0; y < reference.getHeight(); y++)
558 {
559 for (int x = 0; x < reference.getWidth(); x++)
560 {
561 tcu::Vec4 result = tcu::Vec4(0.5f, 1.0f, 0.5f, 1.0f);
562
563 for (int level = 0; level < DE_LENGTH_OF_ARRAY(depthLevelColors); level++)
564 {
565 if ((float)(level + 1) * 0.1f < refAccess.getPixDepth(x, y))
566 result = depthLevelColors[level];
567 }
568
569 referenceScreen.getAccess().setPixel(result, x, y);
570 }
571 }
572
573 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, 0));
574 GLU_CHECK_GLW_CALL(gl, finish());
575
576 return tcu::pixelThresholdCompare(log, "Depth buffer rendering result", "Result from rendering with depth buffer", referenceScreen, screen, compareThreshold, tcu::COMPARE_LOG_RESULT);
577 }
578
invokeGLES2(GLES2ImageApi & api,MovePtr<UniqueImage> & img,tcu::Texture2D & reference) const579 bool GLES2ImageApi::RenderStencilbuffer::invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
580 {
581 // Branch only taken in TryAll case
582 if (reference.getFormat().order != tcu::TextureFormat::DS && reference.getFormat().order != tcu::TextureFormat::S)
583 throw IllegalRendererException(); // Skip, interpreting non-stencil data as stencil data is not meaningful
584
585 const glw::Functions& gl = api.m_gl;
586 tcu::TestLog& log = api.getLog();
587 Framebuffer framebuffer (gl);
588 Renderbuffer renderbufferColor (gl);
589 Renderbuffer renderbufferStencil (gl);
590 const tcu::RGBA compareThreshold (32, 32, 32, 32); // layer colors are far apart, large thresholds are ok
591 const deUint32 numStencilBits = tcu::getTextureFormatBitDepth(tcu::getEffectiveDepthStencilTextureFormat(reference.getLevel(0).getFormat(), tcu::Sampler::MODE_STENCIL)).x();
592 const deUint32 maxStencil = deBitMask32(0, numStencilBits);
593
594 log << tcu::TestLog::Message << "Rendering with stencil buffer" << tcu::TestLog::EndMessage;
595
596 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, *framebuffer));
597
598 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbufferColor));
599 GLU_CHECK_GLW_CALL(gl, renderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, reference.getWidth(), reference.getHeight()));
600 framebufferRenderbuffer(gl, GL_COLOR_ATTACHMENT0, *renderbufferColor);
601
602 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbufferStencil));
603 imageTargetRenderbuffer(api.m_egl, gl, **img);
604 framebufferRenderbuffer(gl, GL_STENCIL_ATTACHMENT, *renderbufferStencil);
605 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, 0));
606
607 GLU_CHECK_GLW_CALL(gl, viewport(0, 0, reference.getWidth(), reference.getHeight()));
608
609 // Render
610 const char* vertexShader =
611 "attribute highp vec2 a_coord;\n"
612 "void main(void) {\n"
613 "\tgl_Position = vec4(a_coord, 0.0, 1.0);\n"
614 "}\n";
615
616 const char* fragmentShader =
617 "uniform mediump vec4 u_color;\n"
618 "void main(void) {\n"
619 "\tgl_FragColor = u_color;\n"
620 "}";
621
622 Program program(gl, vertexShader, fragmentShader);
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, "a_coord");
629 TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute a_coord");
630
631 GLuint colorLoc = gl.getUniformLocation(glProgram, "u_color");
632 TCU_CHECK_MSG((int)colorLoc != (int)-1, "Couldn't find uniform u_color");
633
634 GLU_CHECK_GLW_CALL(gl, clearColor(0.5f, 1.0f, 0.5f, 1.0f));
635 GLU_CHECK_GLW_CALL(gl, clear(GL_COLOR_BUFFER_BIT));
636
637 tcu::Vec4 stencilLevelColors[] = {
638 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
639 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
640 tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),
641 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
642 tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f),
643
644 tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),
645 tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f),
646 tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f),
647 tcu::Vec4(0.0f, 0.5f, 0.0f, 1.0f),
648 tcu::Vec4(0.5f, 0.5f, 0.0f, 1.0f)
649 };
650
651 GLU_CHECK_GLW_CALL(gl, enableVertexAttribArray(coordLoc));
652 GLU_CHECK_GLW_CALL(gl, vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, squareTriangleCoords));
653
654 GLU_CHECK_GLW_CALL(gl, enable(GL_STENCIL_TEST));
655 GLU_CHECK_GLW_CALL(gl, stencilOp(GL_KEEP, GL_KEEP, GL_KEEP));
656
657 for (int level = 0; level < DE_LENGTH_OF_ARRAY(stencilLevelColors); level++)
658 {
659 const tcu::Vec4 color = stencilLevelColors[level];
660 const int stencil = (int)(((float)(level + 1) * 0.1f) * (float)maxStencil);
661
662 GLU_CHECK_GLW_CALL(gl, stencilFunc(GL_LESS, stencil, 0xFFFFFFFFu));
663 GLU_CHECK_GLW_CALL(gl, uniform4f(colorLoc, color.x(), color.y(), color.z(), color.w()));
664 GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6));
665 }
666
667 GLU_CHECK_GLW_CALL(gl, disable(GL_STENCIL_TEST));
668 GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc));
669
670 const ConstPixelBufferAccess& refAccess = reference.getLevel(0);
671 tcu::Surface screen (reference.getWidth(), reference.getHeight());
672 tcu::Surface referenceScreen (reference.getWidth(), reference.getHeight());
673
674 gl.readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr());
675
676 for (int y = 0; y < reference.getHeight(); y++)
677 for (int x = 0; x < reference.getWidth(); x++)
678 {
679 tcu::Vec4 result = tcu::Vec4(0.5f, 1.0f, 0.5f, 1.0f);
680
681 for (int level = 0; level < DE_LENGTH_OF_ARRAY(stencilLevelColors); level++)
682 {
683 const int levelStencil = (int)(((float)(level + 1) * 0.1f) * (float)maxStencil);
684 if (levelStencil < refAccess.getPixStencil(x, y))
685 result = stencilLevelColors[level];
686 }
687
688 referenceScreen.getAccess().setPixel(result, x, y);
689 }
690
691 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, 0));
692 GLU_CHECK_GLW_CALL(gl, finish());
693
694 return tcu::pixelThresholdCompare(log, "StencilResult", "Result from rendering with stencil buffer", referenceScreen, screen, compareThreshold, tcu::COMPARE_LOG_RESULT);
695 }
696
invokeGLES2(GLES2ImageApi & api,MovePtr<UniqueImage> & img,tcu::Texture2D & reference) const697 bool GLES2ImageApi::RenderReadPixelsRenderbuffer::invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
698 {
699 const glw::Functions& gl = api.m_gl;
700 const tcu::IVec4 bitDepth = tcu::getTextureFormatMantissaBitDepth(reference.getFormat());
701 const tcu::IVec4 threshold (2 * (tcu::IVec4(1) << (tcu::IVec4(8) - bitDepth)));
702 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)));
703 tcu::TestLog& log = api.getLog();
704 Framebuffer framebuffer (gl);
705 Renderbuffer renderbuffer (gl);
706 tcu::Surface screen (reference.getWidth(), reference.getHeight());
707 tcu::Surface refSurface (reference.getWidth(), reference.getHeight());
708
709 switch (glu::getInternalFormat(reference.getFormat()))
710 {
711 case GL_RGBA4:
712 case GL_RGB5_A1:
713 case GL_RGB565:
714 break;
715 default:
716 // Skip, not in the list of allowed render buffer formats for GLES2.
717 throw tcu::NotSupportedError("Image format not allowed for glReadPixels.");
718 break;
719 }
720
721 log << tcu::TestLog::Message << "Reading with ReadPixels from renderbuffer" << tcu::TestLog::EndMessage;
722
723 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, *framebuffer));
724 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbuffer));
725 imageTargetRenderbuffer(api.m_egl, gl, **img);
726
727 GLU_EXPECT_NO_ERROR(gl.getError(), "imageTargetRenderbuffer");
728 framebufferRenderbuffer(gl, GL_COLOR_ATTACHMENT0, *renderbuffer);
729 GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferRenderbuffer");
730
731 GLU_CHECK_GLW_CALL(gl, viewport(0, 0, reference.getWidth(), reference.getHeight()));
732
733 GLU_CHECK_GLW_CALL(gl, readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr()));
734
735 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, 0));
736 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, 0));
737 GLU_CHECK_GLW_CALL(gl, finish());
738
739 tcu::copy(refSurface.getAccess(), reference.getLevel(0));
740
741 return tcu::pixelThresholdCompare(log, "Renderbuffer read", "Result from reading renderbuffer", refSurface, screen, threshold8, tcu::COMPARE_LOG_RESULT);
742
743 }
744
invokeGLES2(GLES2ImageApi & api,MovePtr<UniqueImage> & img,tcu::Texture2D & reference) const745 bool GLES2ImageApi::RenderTryAll::invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
746 {
747 bool foundSupported = false;
748 tcu::TestLog& log = api.getLog();
749 GLES2ImageApi::RenderTexture2D renderTex2D;
750 GLES2ImageApi::RenderReadPixelsRenderbuffer renderReadPixels;
751 GLES2ImageApi::RenderDepthbuffer renderDepth;
752 GLES2ImageApi::RenderStencilbuffer renderStencil;
753 Action* actions[] = { &renderTex2D, &renderReadPixels, &renderDepth, &renderStencil };
754
755 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(actions); ++ndx)
756 {
757 try
758 {
759 if (!actions[ndx]->invoke(api, img, reference))
760 return false;
761
762 foundSupported = true;
763 }
764 catch (const tcu::NotSupportedError& error)
765 {
766 log << tcu::TestLog::Message << error.what() << tcu::TestLog::EndMessage;
767 }
768 catch (const IllegalRendererException&)
769 {
770 // not valid renderer
771 }
772 }
773
774 if (!foundSupported)
775 throw tcu::NotSupportedError("Rendering not supported", "", __FILE__, __LINE__);
776
777 return true;
778 }
779
invokeGLES2(GLES2ImageApi & api,MovePtr<UniqueImage> & img,tcu::Texture2D & reference) const780 bool GLES2ImageApi::ModifyTexSubImage::invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
781 {
782 const glw::Functions& gl = api.m_gl;
783 tcu::TestLog& log = api.getLog();
784 glu::Texture srcTex (gl);
785 const int xOffset = 8;
786 const int yOffset = 16;
787 const int xSize = de::clamp(16, 0, reference.getWidth() - xOffset);
788 const int ySize = de::clamp(16, 0, reference.getHeight() - yOffset);
789 tcu::Texture2D src (glu::mapGLTransferFormat(m_format, m_type), xSize, ySize);
790
791 log << tcu::TestLog::Message << "Modifying EGLImage with gl.texSubImage2D" << tcu::TestLog::EndMessage;
792
793 src.allocLevel(0);
794 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));
795
796 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, *srcTex));
797 imageTargetTexture2D(api.m_egl, gl, **img);
798 GLU_CHECK_GLW_CALL(gl, texSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, src.getWidth(), src.getHeight(), m_format, m_type, src.getLevel(0).getDataPtr()));
799 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, 0));
800 GLU_CHECK_GLW_CALL(gl, finish());
801
802 tcu::copy(tcu::getSubregion(reference.getLevel(0), xOffset, yOffset, 0, xSize, ySize, 1), src.getLevel(0));
803
804 return true;
805 }
806
invokeGLES2(GLES2ImageApi & api,MovePtr<UniqueImage> & img,tcu::Texture2D & reference) const807 bool GLES2ImageApi::ModifyRenderbuffer::invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
808 {
809 const glw::Functions& gl = api.m_gl;
810 tcu::TestLog& log = api.getLog();
811 glu::Framebuffer framebuffer (gl);
812 glu::Renderbuffer renderbuffer (gl);
813
814 log << tcu::TestLog::Message << "Modifying EGLImage with glClear to renderbuffer" << tcu::TestLog::EndMessage;
815
816 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, *framebuffer));
817 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbuffer));
818
819 imageTargetRenderbuffer(api.m_egl, gl, **img);
820
821 initializeRbo(api, *renderbuffer, reference);
822
823 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, 0));
824 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, 0));
825
826 GLU_CHECK_GLW_CALL(gl, finish());
827
828 return true;
829 }
830
initializeRbo(GLES2ImageApi & api,GLuint renderbuffer,tcu::Texture2D & reference) const831 void GLES2ImageApi::ModifyRenderbufferClearColor::initializeRbo (GLES2ImageApi& api, GLuint renderbuffer, tcu::Texture2D& reference) const
832 {
833 const glw::Functions& gl = api.m_gl;
834
835 framebufferRenderbuffer(gl, GL_COLOR_ATTACHMENT0, renderbuffer);
836
837 GLU_CHECK_GLW_CALL(gl, viewport(0, 0, reference.getWidth(), reference.getHeight()));
838 GLU_CHECK_GLW_CALL(gl, clearColor(m_color.x(), m_color.y(), m_color.z(), m_color.w()));
839 GLU_CHECK_GLW_CALL(gl, clear(GL_COLOR_BUFFER_BIT));
840
841 tcu::clear(reference.getLevel(0), m_color);
842 }
843
initializeRbo(GLES2ImageApi & api,GLuint renderbuffer,tcu::Texture2D & reference) const844 void GLES2ImageApi::ModifyRenderbufferClearDepth::initializeRbo (GLES2ImageApi& api, GLuint renderbuffer, tcu::Texture2D& reference) const
845 {
846 const glw::Functions& gl = api.m_gl;
847
848 framebufferRenderbuffer(gl, GL_DEPTH_ATTACHMENT, renderbuffer);
849
850 GLU_CHECK_GLW_CALL(gl, viewport(0, 0, reference.getWidth(), reference.getHeight()));
851 GLU_CHECK_GLW_CALL(gl, clearDepthf(m_depth));
852 GLU_CHECK_GLW_CALL(gl, clear(GL_DEPTH_BUFFER_BIT));
853
854 tcu::clearDepth(reference.getLevel(0), m_depth);
855 }
856
initializeRbo(GLES2ImageApi & api,GLuint renderbuffer,tcu::Texture2D & reference) const857 void GLES2ImageApi::ModifyRenderbufferClearStencil::initializeRbo (GLES2ImageApi& api, GLuint renderbuffer, tcu::Texture2D& reference) const
858 {
859 const glw::Functions& gl = api.m_gl;
860
861 framebufferRenderbuffer(gl, GL_STENCIL_ATTACHMENT, renderbuffer);
862
863 GLU_CHECK_GLW_CALL(gl, viewport(0, 0, reference.getWidth(), reference.getHeight()));
864 GLU_CHECK_GLW_CALL(gl, clearStencil(m_stencil));
865 GLU_CHECK_GLW_CALL(gl, clear(GL_STENCIL_BUFFER_BIT));
866
867 tcu::clearStencil(reference.getLevel(0), m_stencil);
868 }
869
870 class ImageFormatCase : public TestCase, private glu::CallLogWrapper
871 {
872 public:
873 ImageFormatCase (EglTestContext& eglTestCtx, const TestSpec& spec);
874 ~ImageFormatCase (void);
875
876 void init (void);
877 void deinit (void);
878 IterateResult iterate (void);
879 void checkExtensions (void);
880
881 private:
882 EGLConfig getConfig (void);
883
884 const TestSpec m_spec;
885
886 vector<ImageApi*> m_apiContexts;
887
888 EGLDisplay m_display;
889 eglu::NativeWindow* m_window;
890 EGLSurface m_surface;
891 EGLConfig m_config;
892 int m_curIter;
893 MovePtr<UniqueImage>m_img;
894 tcu::Texture2D m_refImg;
895 glw::Functions m_gl;
896 };
897
getConfig(void)898 EGLConfig ImageFormatCase::getConfig (void)
899 {
900 const EGLint attribList[] =
901 {
902 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
903 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
904 EGL_RED_SIZE, 8,
905 EGL_BLUE_SIZE, 8,
906 EGL_GREEN_SIZE, 8,
907 EGL_ALPHA_SIZE, 8,
908 EGL_DEPTH_SIZE, 8,
909 EGL_NONE
910 };
911
912 return eglu::chooseSingleConfig(m_eglTestCtx.getLibrary(), m_display, attribList);
913 }
914
ImageFormatCase(EglTestContext & eglTestCtx,const TestSpec & spec)915 ImageFormatCase::ImageFormatCase (EglTestContext& eglTestCtx, const TestSpec& spec)
916 : TestCase (eglTestCtx, spec.name.c_str(), spec.desc.c_str())
917 , glu::CallLogWrapper (m_gl, eglTestCtx.getTestContext().getLog())
918 , m_spec (spec)
919 , m_display (EGL_NO_DISPLAY)
920 , m_window (DE_NULL)
921 , m_surface (EGL_NO_SURFACE)
922 , m_config (0)
923 , m_curIter (0)
924 , m_refImg (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 1, 1)
925 {
926 }
927
~ImageFormatCase(void)928 ImageFormatCase::~ImageFormatCase (void)
929 {
930 deinit();
931 }
932
checkExtensions(void)933 void ImageFormatCase::checkExtensions (void)
934 {
935 const Library& egl = m_eglTestCtx.getLibrary();
936 const EGLDisplay dpy = m_display;
937 set<string> exts;
938 const vector<string> glExts = de::splitString((const char*) m_gl.getString(GL_EXTENSIONS));
939 const vector<string> eglExts = eglu::getDisplayExtensions(egl, dpy);
940
941 exts.insert(glExts.begin(), glExts.end());
942 exts.insert(eglExts.begin(), eglExts.end());
943
944 if (eglu::getVersion(egl, dpy) >= eglu::Version(1, 5))
945 {
946 // EGL 1.5 has built-in support for EGLImage and GL sources
947 exts.insert("EGL_KHR_image_base");
948 exts.insert("EGL_KHR_gl_texture_2D_image");
949 exts.insert("EGL_KHR_gl_texture_cubemap_image");
950 exts.insert("EGL_KHR_gl_renderbuffer_image");
951 }
952
953 if (!de::contains(exts, "EGL_KHR_image_base") && !de::contains(exts, "EGL_KHR_image"))
954 {
955 getLog() << tcu::TestLog::Message
956 << "EGL version is under 1.5 and neither EGL_KHR_image nor EGL_KHR_image_base is supported."
957 << "One should be supported."
958 << tcu::TestLog::EndMessage;
959 TCU_THROW(NotSupportedError, "Extension not supported: EGL_KHR_image_base");
960 }
961
962 for (int operationNdx = 0; operationNdx < (int)m_spec.operations.size(); operationNdx++)
963 {
964 const TestSpec::Operation& op = m_spec.operations[operationNdx];
965 const string ext = op.action->getRequiredExtension();
966
967 if (!de::contains(exts, ext))
968 TCU_THROW_EXPR(NotSupportedError, "Extension not supported", ext.c_str());
969 }
970 }
971
init(void)972 void ImageFormatCase::init (void)
973 {
974 const Library& egl = m_eglTestCtx.getLibrary();
975 const eglu::NativeWindowFactory& windowFactory = eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
976
977 try
978 {
979 m_display = eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
980 m_config = getConfig();
981 m_window = windowFactory.createWindow(&m_eglTestCtx.getNativeDisplay(), m_display, m_config, DE_NULL, eglu::WindowParams(480, 480, eglu::parseWindowVisibility(m_testCtx.getCommandLine())));
982 m_surface = eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *m_window, m_display, m_config, DE_NULL);
983
984 {
985 const char* extensions[] = { "GL_OES_EGL_image" };
986 m_eglTestCtx.initGLFunctions(&m_gl, glu::ApiType::es(2, 0), DE_LENGTH_OF_ARRAY(extensions), &extensions[0]);
987 }
988
989 for (int contextNdx = 0; contextNdx < (int)m_spec.contexts.size(); contextNdx++)
990 {
991 ImageApi* api = DE_NULL;
992 switch (m_spec.contexts[contextNdx])
993 {
994 case TestSpec::API_GLES2:
995 {
996 api = new GLES2ImageApi(egl, m_gl, contextNdx, getLog(), m_display, m_surface, m_config);
997 break;
998 }
999
1000 default:
1001 DE_ASSERT(false);
1002 break;
1003 }
1004 m_apiContexts.push_back(api);
1005 }
1006 checkExtensions();
1007 }
1008 catch (...)
1009 {
1010 deinit();
1011 throw;
1012 }
1013 }
1014
deinit(void)1015 void ImageFormatCase::deinit (void)
1016 {
1017 const Library& egl = m_eglTestCtx.getLibrary();
1018
1019 m_img.clear();
1020
1021 for (int contexNdx = 0 ; contexNdx < (int)m_apiContexts.size(); contexNdx++)
1022 delete m_apiContexts[contexNdx];
1023
1024 m_apiContexts.clear();
1025
1026 if (m_surface != EGL_NO_SURFACE)
1027 {
1028 egl.destroySurface(m_display, m_surface);
1029 m_surface = EGL_NO_SURFACE;
1030 }
1031
1032 delete m_window;
1033 m_window = DE_NULL;
1034
1035 if (m_display != EGL_NO_DISPLAY)
1036 {
1037 egl.terminate(m_display);
1038 m_display = EGL_NO_DISPLAY;
1039 }
1040 }
1041
iterate(void)1042 TestCase::IterateResult ImageFormatCase::iterate (void)
1043 {
1044 const TestSpec::Operation& op = m_spec.operations[m_curIter++];
1045 ImageApi& api = *m_apiContexts[op.apiIndex];
1046 const bool isOk = op.action->invoke(api, m_img, m_refImg);
1047
1048 if (isOk && m_curIter < (int)m_spec.operations.size())
1049 return CONTINUE;
1050 else if (isOk)
1051 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1052 else
1053 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1054
1055 return STOP;
1056 }
1057
1058 struct LabeledAction
1059 {
1060 string label;
1061 MovePtr<Action> action;
1062 };
1063
1064 // A simple vector mockup that we need because MovePtr isn't copy-constructible.
1065 struct LabeledActions
1066 {
LabeledActionsdeqp::egl::Image::LabeledActions1067 LabeledActions (void) : m_numActions(0){}
operator []deqp::egl::Image::LabeledActions1068 LabeledAction& operator[] (int ndx) { DE_ASSERT(0 <= ndx && ndx < m_numActions); return m_actions[ndx]; }
1069 void add (const string& label, MovePtr<Action> action);
sizedeqp::egl::Image::LabeledActions1070 int size (void) const { return m_numActions; }
1071 private:
1072 LabeledAction m_actions[64];
1073 int m_numActions;
1074 };
1075
add(const string & label,MovePtr<Action> action)1076 void LabeledActions::add (const string& label, MovePtr<Action> action)
1077 {
1078 DE_ASSERT(m_numActions < DE_LENGTH_OF_ARRAY(m_actions));
1079 m_actions[m_numActions].label = label;
1080 m_actions[m_numActions].action = action;
1081 ++m_numActions;
1082 }
1083
1084 class ImageTests : public TestCaseGroup
1085 {
1086 protected:
ImageTests(EglTestContext & eglTestCtx,const string & name,const string & desc)1087 ImageTests (EglTestContext& eglTestCtx, const string& name, const string& desc)
1088 : TestCaseGroup(eglTestCtx, name.c_str(), desc.c_str()) {}
1089
1090 void addCreateTexture (const string& name, EGLenum source, GLenum internalFormat, GLenum format, GLenum type);
1091 void addCreateRenderbuffer (const string& name, GLenum format);
1092 void addCreateAndroidNative (const string& name, GLenum format);
1093 void addCreateTexture2DActions (const string& prefix);
1094 void addCreateTextureCubemapActions (const string& suffix, GLenum internalFormat, GLenum format, GLenum type);
1095 void addCreateRenderbufferActions (void);
1096 void addCreateAndroidNativeActions (void);
1097
1098 LabeledActions m_createActions;
1099 };
1100
addCreateTexture(const string & name,EGLenum source,GLenum internalFormat,GLenum format,GLenum type)1101 void ImageTests::addCreateTexture (const string& name, EGLenum source, GLenum internalFormat, GLenum format, GLenum type)
1102 {
1103 m_createActions.add(name, MovePtr<Action>(new GLES2ImageApi::Create(createTextureImageSource(source, internalFormat, format, type))));
1104 }
1105
addCreateRenderbuffer(const string & name,GLenum format)1106 void ImageTests::addCreateRenderbuffer (const string& name, GLenum format)
1107 {
1108 m_createActions.add(name, MovePtr<Action>(new GLES2ImageApi::Create(createRenderbufferImageSource(format))));
1109 }
1110
addCreateAndroidNative(const string & name,GLenum format)1111 void ImageTests::addCreateAndroidNative (const string& name, GLenum format)
1112 {
1113 m_createActions.add(name, MovePtr<Action>(new GLES2ImageApi::Create(createAndroidNativeImageSource(format))));
1114 }
1115
addCreateTexture2DActions(const string & prefix)1116 void ImageTests::addCreateTexture2DActions (const string& prefix)
1117 {
1118 addCreateTexture(prefix + "rgb8", EGL_GL_TEXTURE_2D_KHR, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE);
1119 addCreateTexture(prefix + "rgb565", EGL_GL_TEXTURE_2D_KHR, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
1120 addCreateTexture(prefix + "rgba8", EGL_GL_TEXTURE_2D_KHR, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
1121 addCreateTexture(prefix + "rgb5_a1", EGL_GL_TEXTURE_2D_KHR, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
1122 addCreateTexture(prefix + "rgba4", EGL_GL_TEXTURE_2D_KHR, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
1123 }
1124
addCreateTextureCubemapActions(const string & suffix,GLenum internalFormat,GLenum format,GLenum type)1125 void ImageTests::addCreateTextureCubemapActions (const string& suffix, GLenum internalFormat, GLenum format, GLenum type)
1126 {
1127 addCreateTexture("cubemap_positive_x" + suffix, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR, internalFormat, format, type);
1128 addCreateTexture("cubemap_positive_y" + suffix, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR, internalFormat, format, type);
1129 addCreateTexture("cubemap_positive_z" + suffix, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR, internalFormat, format, type);
1130 addCreateTexture("cubemap_negative_x" + suffix, EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR, internalFormat, format, type);
1131 addCreateTexture("cubemap_negative_y" + suffix, EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR, internalFormat, format, type);
1132 addCreateTexture("cubemap_negative_z" + suffix, EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR, internalFormat, format, type);
1133 }
1134
addCreateRenderbufferActions(void)1135 void ImageTests::addCreateRenderbufferActions (void)
1136 {
1137 addCreateRenderbuffer("renderbuffer_rgba4", GL_RGBA4);
1138 addCreateRenderbuffer("renderbuffer_rgb5_a1", GL_RGB5_A1);
1139 addCreateRenderbuffer("renderbuffer_rgb565", GL_RGB565);
1140 addCreateRenderbuffer("renderbuffer_depth16", GL_DEPTH_COMPONENT16);
1141 addCreateRenderbuffer("renderbuffer_stencil", GL_STENCIL_INDEX8);
1142 }
1143
addCreateAndroidNativeActions(void)1144 void ImageTests::addCreateAndroidNativeActions (void)
1145 {
1146 addCreateAndroidNative("android_native_rgba4", GL_RGBA4);
1147 addCreateAndroidNative("android_native_rgb5_a1", GL_RGB5_A1);
1148 addCreateAndroidNative("android_native_rgb565", GL_RGB565);
1149 addCreateAndroidNative("android_native_rgb8", GL_RGB8);
1150 addCreateAndroidNative("android_native_rgba8", GL_RGBA8);
1151 addCreateAndroidNative("android_native_d16", GL_DEPTH_COMPONENT16);
1152 addCreateAndroidNative("android_native_d24", GL_DEPTH_COMPONENT24);
1153 addCreateAndroidNative("android_native_d24s8", GL_DEPTH24_STENCIL8);
1154 addCreateAndroidNative("android_native_d32f", GL_DEPTH_COMPONENT32F);
1155 addCreateAndroidNative("android_native_d32fs8", GL_DEPTH32F_STENCIL8);
1156 addCreateAndroidNative("android_native_rgb10a2", GL_RGB10_A2);
1157 addCreateAndroidNative("android_native_rgba16f", GL_RGBA16F);
1158 addCreateAndroidNative("android_native_s8", GL_STENCIL_INDEX8);
1159 }
1160
1161 class RenderTests : public ImageTests
1162 {
1163 protected:
RenderTests(EglTestContext & eglTestCtx,const string & name,const string & desc)1164 RenderTests (EglTestContext& eglTestCtx, const string& name, const string& desc)
1165 : ImageTests (eglTestCtx, name, desc) {}
1166
1167 void addRenderActions (void);
1168 LabeledActions m_renderActions;
1169 };
1170
addRenderActions(void)1171 void RenderTests::addRenderActions (void)
1172 {
1173 m_renderActions.add("texture", MovePtr<Action>(new GLES2ImageApi::RenderTexture2D()));
1174 m_renderActions.add("read_pixels", MovePtr<Action>(new GLES2ImageApi::RenderReadPixelsRenderbuffer()));
1175 m_renderActions.add("depth_buffer", MovePtr<Action>(new GLES2ImageApi::RenderDepthbuffer()));
1176 m_renderActions.add("stencil_buffer", MovePtr<Action>(new GLES2ImageApi::RenderStencilbuffer()));
1177 }
1178
1179 class SimpleCreationTests : public RenderTests
1180 {
1181 public:
SimpleCreationTests(EglTestContext & eglTestCtx,const string & name,const string & desc)1182 SimpleCreationTests (EglTestContext& eglTestCtx, const string& name, const string& desc) : RenderTests(eglTestCtx, name, desc) {}
1183 void init (void);
1184 };
1185
isDepthFormat(GLenum format)1186 bool isDepthFormat (GLenum format)
1187 {
1188 switch (format)
1189 {
1190 case GL_RGB:
1191 case GL_RGB8:
1192 case GL_RGB565:
1193 case GL_RGBA:
1194 case GL_RGBA4:
1195 case GL_RGBA8:
1196 case GL_RGB5_A1:
1197 case GL_RGB10_A2:
1198 case GL_RGBA16F:
1199 return false;
1200
1201 case GL_DEPTH_COMPONENT16:
1202 case GL_DEPTH_COMPONENT24:
1203 case GL_DEPTH_COMPONENT32:
1204 case GL_DEPTH_COMPONENT32F:
1205 case GL_DEPTH24_STENCIL8:
1206 case GL_DEPTH32F_STENCIL8:
1207 return true;
1208
1209 case GL_STENCIL_INDEX8:
1210 return false;
1211
1212 default:
1213 DE_ASSERT(false);
1214 return false;
1215 }
1216 }
1217
isStencilFormat(GLenum format)1218 bool isStencilFormat (GLenum format)
1219 {
1220 switch (format)
1221 {
1222 case GL_RGB:
1223 case GL_RGB8:
1224 case GL_RGB565:
1225 case GL_RGBA:
1226 case GL_RGBA4:
1227 case GL_RGBA8:
1228 case GL_RGB5_A1:
1229 case GL_RGB10_A2:
1230 case GL_RGBA16F:
1231 return false;
1232
1233 case GL_DEPTH_COMPONENT16:
1234 case GL_DEPTH_COMPONENT24:
1235 case GL_DEPTH_COMPONENT32:
1236 case GL_DEPTH_COMPONENT32F:
1237 return false;
1238
1239 case GL_STENCIL_INDEX8:
1240 case GL_DEPTH24_STENCIL8:
1241 case GL_DEPTH32F_STENCIL8:
1242 return true;
1243
1244 default:
1245 DE_ASSERT(false);
1246 return false;
1247 }
1248 }
1249
isCompatibleCreateAndRenderActions(const Action & create,const Action & render)1250 bool isCompatibleCreateAndRenderActions (const Action& create, const Action& render)
1251 {
1252 if (const GLES2ImageApi::Create* gles2Create = dynamic_cast<const GLES2ImageApi::Create*>(&create))
1253 {
1254 const GLenum createFormat = gles2Create->getEffectiveFormat();
1255
1256 if (dynamic_cast<const GLES2ImageApi::RenderTexture2D*>(&render))
1257 {
1258 // GLES2 does not have depth or stencil textures
1259 if (isDepthFormat(createFormat) || isStencilFormat(createFormat))
1260 return false;
1261 }
1262
1263 if (dynamic_cast<const GLES2ImageApi::RenderReadPixelsRenderbuffer*>(&render))
1264 {
1265 // GLES2 does not support readPixels for depth or stencil
1266 if (isDepthFormat(createFormat) || isStencilFormat(createFormat))
1267 return false;
1268 }
1269
1270 if (dynamic_cast<const GLES2ImageApi::RenderDepthbuffer*>(&render))
1271 {
1272 // Copying non-depth data to depth renderbuffer and expecting meaningful
1273 // results just doesn't make any sense.
1274 if (!isDepthFormat(createFormat))
1275 return false;
1276 }
1277
1278 if (dynamic_cast<const GLES2ImageApi::RenderStencilbuffer*>(&render))
1279 {
1280 // Copying non-stencil data to stencil renderbuffer and expecting meaningful
1281 // results just doesn't make any sense.
1282 if (!isStencilFormat(createFormat))
1283 return false;
1284 }
1285
1286 return true;
1287 }
1288 else
1289 DE_ASSERT(false);
1290
1291 return false;
1292 }
1293
init(void)1294 void SimpleCreationTests::init (void)
1295 {
1296 addCreateTexture2DActions("texture_");
1297 addCreateTextureCubemapActions("_rgba", GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
1298 addCreateTextureCubemapActions("_rgb", GL_RGB, GL_RGB, GL_UNSIGNED_BYTE);
1299 addCreateRenderbufferActions();
1300 addCreateAndroidNativeActions();
1301 addRenderActions();
1302
1303 for (int createNdx = 0; createNdx < m_createActions.size(); createNdx++)
1304 {
1305 const LabeledAction& createAction = m_createActions[createNdx];
1306
1307 for (int renderNdx = 0; renderNdx < m_renderActions.size(); renderNdx++)
1308 {
1309 const LabeledAction& renderAction = m_renderActions[renderNdx];
1310 TestSpec spec;
1311
1312 if (!isCompatibleCreateAndRenderActions(*createAction.action, *renderAction.action))
1313 continue;
1314
1315 spec.name = std::string("gles2_") + createAction.label + "_" + renderAction.label;
1316 spec.desc = spec.name;
1317 spec.contexts.push_back(TestSpec::API_GLES2);
1318 spec.operations.push_back(TestSpec::Operation(0, *createAction.action));
1319 spec.operations.push_back(TestSpec::Operation(0, *renderAction.action));
1320
1321 addChild(new ImageFormatCase(m_eglTestCtx, spec));
1322 }
1323 }
1324 }
1325
createSimpleCreationTests(EglTestContext & eglTestCtx,const string & name,const string & desc)1326 TestCaseGroup* createSimpleCreationTests (EglTestContext& eglTestCtx, const string& name, const string& desc)
1327 {
1328 return new SimpleCreationTests(eglTestCtx, name, desc);
1329 }
1330
isCompatibleFormats(GLenum createFormat,GLenum modifyFormat,GLenum modifyType)1331 bool isCompatibleFormats (GLenum createFormat, GLenum modifyFormat, GLenum modifyType)
1332 {
1333 switch (modifyFormat)
1334 {
1335 case GL_RGB:
1336 switch (modifyType)
1337 {
1338 case GL_UNSIGNED_BYTE:
1339 return createFormat == GL_RGB
1340 || createFormat == GL_RGB8
1341 || createFormat == GL_RGB565
1342 || createFormat == GL_SRGB8;
1343
1344 case GL_BYTE:
1345 return createFormat == GL_RGB8_SNORM;
1346
1347 case GL_UNSIGNED_SHORT_5_6_5:
1348 return createFormat == GL_RGB
1349 || createFormat == GL_RGB565;
1350
1351 case GL_UNSIGNED_INT_10F_11F_11F_REV:
1352 return createFormat == GL_R11F_G11F_B10F;
1353
1354 case GL_UNSIGNED_INT_5_9_9_9_REV:
1355 return createFormat == GL_RGB9_E5;
1356
1357 case GL_HALF_FLOAT:
1358 return createFormat == GL_RGB16F
1359 || createFormat == GL_R11F_G11F_B10F
1360 || createFormat == GL_RGB9_E5;
1361
1362 case GL_FLOAT:
1363 return createFormat == GL_RGB16F
1364 || createFormat == GL_RGB32F
1365 || createFormat == GL_R11F_G11F_B10F
1366 || createFormat == GL_RGB9_E5;
1367
1368 default:
1369 DE_FATAL("Unknown modify type");
1370 return false;
1371 }
1372
1373 case GL_RGBA:
1374 switch (modifyType)
1375 {
1376 case GL_UNSIGNED_BYTE:
1377 return createFormat == GL_RGBA8
1378 || createFormat == GL_RGB5_A1
1379 || createFormat == GL_RGBA4
1380 || createFormat == GL_SRGB8_ALPHA8
1381 || createFormat == GL_RGBA;
1382
1383 case GL_UNSIGNED_SHORT_4_4_4_4:
1384 return createFormat == GL_RGBA4
1385 || createFormat == GL_RGBA;
1386
1387 case GL_UNSIGNED_SHORT_5_5_5_1:
1388 return createFormat == GL_RGB5_A1
1389 || createFormat == GL_RGBA;
1390
1391 case GL_UNSIGNED_INT_2_10_10_10_REV:
1392 return createFormat == GL_RGB10_A2
1393 || createFormat == GL_RGB5_A1;
1394
1395 case GL_HALF_FLOAT:
1396 return createFormat == GL_RGBA16F;
1397
1398 case GL_FLOAT:
1399 return createFormat == GL_RGBA16F
1400 || createFormat == GL_RGBA32F;
1401
1402 default:
1403 DE_FATAL("Unknown modify type");
1404 return false;
1405 };
1406
1407 default:
1408 DE_FATAL("Unknown modify format");
1409 return false;
1410 }
1411 }
1412
isCompatibleCreateAndModifyActions(const Action & create,const Action & modify)1413 bool isCompatibleCreateAndModifyActions (const Action& create, const Action& modify)
1414 {
1415 if (const GLES2ImageApi::Create* gles2Create = dynamic_cast<const GLES2ImageApi::Create*>(&create))
1416 {
1417 const GLenum createFormat = gles2Create->getEffectiveFormat();
1418
1419 if (const GLES2ImageApi::ModifyTexSubImage* gles2TexSubImageModify = dynamic_cast<const GLES2ImageApi::ModifyTexSubImage*>(&modify))
1420 {
1421 const GLenum modifyFormat = gles2TexSubImageModify->getFormat();
1422 const GLenum modifyType = gles2TexSubImageModify->getType();
1423
1424 return isCompatibleFormats(createFormat, modifyFormat, modifyType);
1425 }
1426
1427 if (dynamic_cast<const GLES2ImageApi::ModifyRenderbufferClearColor*>(&modify))
1428 {
1429 // reintepreting color as non-color is not meaningful
1430 if (isDepthFormat(createFormat) || isStencilFormat(createFormat))
1431 return false;
1432 }
1433
1434 if (dynamic_cast<const GLES2ImageApi::ModifyRenderbufferClearDepth*>(&modify))
1435 {
1436 // reintepreting depth as non-depth is not meaningful
1437 if (!isDepthFormat(createFormat))
1438 return false;
1439 }
1440
1441 if (dynamic_cast<const GLES2ImageApi::ModifyRenderbufferClearStencil*>(&modify))
1442 {
1443 // reintepreting stencil as non-stencil is not meaningful
1444 if (!isStencilFormat(createFormat))
1445 return false;
1446 }
1447
1448 return true;
1449 }
1450 else
1451 DE_ASSERT(false);
1452
1453 return false;
1454 }
1455
1456 class MultiContextRenderTests : public RenderTests
1457 {
1458 public:
1459 MultiContextRenderTests (EglTestContext& eglTestCtx, const string& name, const string& desc);
1460 void init (void);
1461 void addClearActions (void);
1462 private:
1463 LabeledActions m_clearActions;
1464 };
1465
MultiContextRenderTests(EglTestContext & eglTestCtx,const string & name,const string & desc)1466 MultiContextRenderTests::MultiContextRenderTests (EglTestContext& eglTestCtx, const string& name, const string& desc)
1467 : RenderTests (eglTestCtx, name, desc)
1468 {
1469 }
1470
addClearActions(void)1471 void MultiContextRenderTests::addClearActions (void)
1472 {
1473 m_clearActions.add("clear_color", MovePtr<Action>(new GLES2ImageApi::ModifyRenderbufferClearColor(tcu::Vec4(0.8f, 0.2f, 0.9f, 1.0f))));
1474 m_clearActions.add("clear_depth", MovePtr<Action>(new GLES2ImageApi::ModifyRenderbufferClearDepth(0.75f)));
1475 m_clearActions.add("clear_stencil", MovePtr<Action>(new GLES2ImageApi::ModifyRenderbufferClearStencil(97)));
1476 }
1477
init(void)1478 void MultiContextRenderTests::init (void)
1479 {
1480 addCreateTexture2DActions("texture_");
1481 addCreateTextureCubemapActions("_rgba8", GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
1482 addCreateTextureCubemapActions("_rgb8", GL_RGB, GL_RGB, GL_UNSIGNED_BYTE);
1483 addCreateRenderbufferActions();
1484 addCreateAndroidNativeActions();
1485 addRenderActions();
1486 addClearActions();
1487
1488 for (int createNdx = 0; createNdx < m_createActions.size(); createNdx++)
1489 for (int renderNdx = 0; renderNdx < m_renderActions.size(); renderNdx++)
1490 for (int clearNdx = 0; clearNdx < m_clearActions.size(); clearNdx++)
1491 {
1492 const LabeledAction& createAction = m_createActions[createNdx];
1493 const LabeledAction& renderAction = m_renderActions[renderNdx];
1494 const LabeledAction& clearAction = m_clearActions[clearNdx];
1495 TestSpec spec;
1496
1497 if (!isCompatibleCreateAndRenderActions(*createAction.action, *renderAction.action))
1498 continue;
1499 if (!isCompatibleCreateAndModifyActions(*createAction.action, *clearAction.action))
1500 continue;
1501
1502 spec.name = std::string("gles2_") + createAction.label + "_" + renderAction.label;
1503
1504 const GLenum createFormat = dynamic_cast<const GLES2ImageApi::Create*>(createAction.action.get())->getEffectiveFormat();
1505 if (isDepthFormat(createFormat) && isStencilFormat(createFormat))
1506 {
1507 // Combined depth and stencil format. Add the clear action label to avoid test
1508 // name clashes.
1509 spec.name += std::string("_") + clearAction.label;
1510 }
1511
1512 spec.desc = spec.name;
1513
1514 spec.contexts.push_back(TestSpec::API_GLES2);
1515 spec.contexts.push_back(TestSpec::API_GLES2);
1516
1517 spec.operations.push_back(TestSpec::Operation(0, *createAction.action));
1518 spec.operations.push_back(TestSpec::Operation(0, *renderAction.action));
1519 spec.operations.push_back(TestSpec::Operation(0, *clearAction.action));
1520 spec.operations.push_back(TestSpec::Operation(1, *createAction.action));
1521 spec.operations.push_back(TestSpec::Operation(0, *renderAction.action));
1522 spec.operations.push_back(TestSpec::Operation(1, *renderAction.action));
1523
1524 addChild(new ImageFormatCase(m_eglTestCtx, spec));
1525 }
1526 }
1527
createMultiContextRenderTests(EglTestContext & eglTestCtx,const string & name,const string & desc)1528 TestCaseGroup* createMultiContextRenderTests (EglTestContext& eglTestCtx, const string& name, const string& desc)
1529 {
1530 return new MultiContextRenderTests(eglTestCtx, name, desc);
1531 }
1532
1533 class ModifyTests : public ImageTests
1534 {
1535 public:
ModifyTests(EglTestContext & eglTestCtx,const string & name,const string & desc)1536 ModifyTests (EglTestContext& eglTestCtx, const string& name, const string& desc)
1537 : ImageTests(eglTestCtx, name, desc) {}
1538
1539 void init (void);
1540
1541 protected:
1542 void addModifyActions(void);
1543
1544 LabeledActions m_modifyActions;
1545 GLES2ImageApi::RenderTryAll m_renderAction;
1546 };
1547
addModifyActions(void)1548 void ModifyTests::addModifyActions (void)
1549 {
1550 m_modifyActions.add("tex_subimage_rgb8", MovePtr<Action>(new GLES2ImageApi::ModifyTexSubImage(GL_RGB, GL_UNSIGNED_BYTE)));
1551 m_modifyActions.add("tex_subimage_rgb565", MovePtr<Action>(new GLES2ImageApi::ModifyTexSubImage(GL_RGB, GL_UNSIGNED_SHORT_5_6_5)));
1552 m_modifyActions.add("tex_subimage_rgba8", MovePtr<Action>(new GLES2ImageApi::ModifyTexSubImage(GL_RGBA, GL_UNSIGNED_BYTE)));
1553 m_modifyActions.add("tex_subimage_rgb5_a1", MovePtr<Action>(new GLES2ImageApi::ModifyTexSubImage(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1)));
1554 m_modifyActions.add("tex_subimage_rgba4", MovePtr<Action>(new GLES2ImageApi::ModifyTexSubImage(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4)));
1555
1556 m_modifyActions.add("renderbuffer_clear_color", MovePtr<Action>(new GLES2ImageApi::ModifyRenderbufferClearColor(tcu::Vec4(0.3f, 0.5f, 0.3f, 1.0f))));
1557 m_modifyActions.add("renderbuffer_clear_depth", MovePtr<Action>(new GLES2ImageApi::ModifyRenderbufferClearDepth(0.7f)));
1558 m_modifyActions.add("renderbuffer_clear_stencil", MovePtr<Action>(new GLES2ImageApi::ModifyRenderbufferClearStencil(78)));
1559 }
1560
init(void)1561 void ModifyTests::init (void)
1562 {
1563 addCreateTexture2DActions("tex_");
1564 addCreateRenderbufferActions();
1565 addCreateAndroidNativeActions();
1566 addModifyActions();
1567
1568 for (int createNdx = 0; createNdx < m_createActions.size(); createNdx++)
1569 {
1570 LabeledAction& createAction = m_createActions[createNdx];
1571
1572 for (int modifyNdx = 0; modifyNdx < m_modifyActions.size(); modifyNdx++)
1573 {
1574 LabeledAction& modifyAction = m_modifyActions[modifyNdx];
1575
1576 if (!isCompatibleCreateAndModifyActions(*createAction.action, *modifyAction.action))
1577 continue;
1578
1579 TestSpec spec;
1580 spec.name = createAction.label + "_" + modifyAction.label;
1581 spec.desc = "gles2_tex_sub_image";
1582
1583 spec.contexts.push_back(TestSpec::API_GLES2);
1584
1585 spec.operations.push_back(TestSpec::Operation(0, *createAction.action));
1586 spec.operations.push_back(TestSpec::Operation(0, m_renderAction));
1587 spec.operations.push_back(TestSpec::Operation(0, *modifyAction.action));
1588 spec.operations.push_back(TestSpec::Operation(0, m_renderAction));
1589
1590 addChild(new ImageFormatCase(m_eglTestCtx, spec));
1591 }
1592 }
1593 }
1594
createModifyTests(EglTestContext & eglTestCtx,const string & name,const string & desc)1595 TestCaseGroup* createModifyTests (EglTestContext& eglTestCtx, const string& name, const string& desc)
1596 {
1597 return new ModifyTests(eglTestCtx, name, desc);
1598 }
1599
1600 } // Image
1601 } // egl
1602 } // deqp
1603