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