• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 Common utilities for EGL images.
22  *//*--------------------------------------------------------------------*/
23 
24 
25 #include "teglImageUtil.hpp"
26 
27 #include "tcuTexture.hpp"
28 #include "tcuTextureUtil.hpp"
29 
30 #include "egluGLUtil.hpp"
31 #include "egluNativeWindow.hpp"
32 #include "egluNativePixmap.hpp"
33 
34 #include "eglwLibrary.hpp"
35 #include "eglwEnums.hpp"
36 
37 #include "glwEnums.hpp"
38 
39 #include "gluObjectWrapper.hpp"
40 #include "gluTextureUtil.hpp"
41 
42 namespace deqp
43 {
44 namespace egl
45 {
46 namespace Image
47 {
48 
49 using std::string;
50 using std::vector;
51 
52 using de::UniquePtr;
53 using de::MovePtr;
54 
55 using tcu::TextureFormat;
56 using tcu::Texture2D;
57 using tcu::Vec4;
58 
59 using glu::Framebuffer;
60 using glu::Texture;
61 
62 using eglu::AttribMap;
63 using eglu::UniqueSurface;
64 using eglu::NativeDisplay;
65 using eglu::NativeWindow;
66 using eglu::NativePixmap;
67 using eglu::NativeDisplayFactory;
68 using eglu::NativeWindowFactory;
69 using eglu::NativePixmapFactory;
70 using eglu::WindowParams;
71 
72 using namespace glw;
73 using namespace eglw;
74 
75 enum {
76 	IMAGE_WIDTH		= 64,
77 	IMAGE_HEIGHT	= 64,
78 };
79 
80 
81 template <typename T>
82 struct NativeSurface : public ManagedSurface
83 {
84 public:
NativeSurfacedeqp::egl::Image::NativeSurface85 	explicit		NativeSurface	(MovePtr<UniqueSurface>	surface,
86 									 MovePtr<T>				native)
87 						: ManagedSurface	(surface)
88 						, m_native			(native) {}
89 
90 private:
91 	UniquePtr<T>	m_native;
92 };
93 
94 typedef NativeSurface<NativeWindow> NativeWindowSurface;
95 typedef NativeSurface<NativePixmap> NativePixmapSurface;
96 
createSurface(EglTestContext & eglTestCtx,EGLDisplay dpy,EGLConfig config,int width,int height)97 MovePtr<ManagedSurface> createSurface (EglTestContext& eglTestCtx, EGLDisplay dpy, EGLConfig config, int width, int height)
98 {
99 	const Library&				egl				= eglTestCtx.getLibrary();
100 	EGLint						surfaceTypeBits	= eglu::getConfigAttribInt(egl, dpy, config, EGL_SURFACE_TYPE);
101 	const NativeDisplayFactory&	displayFactory	= eglTestCtx.getNativeDisplayFactory();
102 	NativeDisplay&				nativeDisplay	= eglTestCtx.getNativeDisplay();
103 
104 	if (surfaceTypeBits & EGL_PBUFFER_BIT)
105 	{
106 		static const EGLint attribs[]	= { EGL_WIDTH, width, EGL_HEIGHT, height, EGL_NONE };
107 		const EGLSurface	surface		= egl.createPbufferSurface(dpy, config, attribs);
108 
109 		EGLU_CHECK_MSG(egl, "eglCreatePbufferSurface()");
110 
111 		return de::newMovePtr<ManagedSurface>(MovePtr<UniqueSurface>(new UniqueSurface(egl, dpy, surface)));
112 	}
113 	else if (surfaceTypeBits & EGL_WINDOW_BIT)
114 	{
115 		const NativeWindowFactory&	windowFactory	= selectNativeWindowFactory(displayFactory, eglTestCtx.getTestContext().getCommandLine());
116 
117 		MovePtr<NativeWindow>		window	(windowFactory.createWindow(&nativeDisplay, dpy, config, DE_NULL, WindowParams(width, height, WindowParams::VISIBILITY_DONT_CARE)));
118 		const EGLSurface			surface	= eglu::createWindowSurface(nativeDisplay, *window, dpy, config, DE_NULL);
119 
120 		return MovePtr<ManagedSurface>(new NativeWindowSurface(MovePtr<UniqueSurface>(new UniqueSurface(egl, dpy, surface)), window));
121 	}
122 	else if (surfaceTypeBits & EGL_PIXMAP_BIT)
123 	{
124 		const NativePixmapFactory&	pixmapFactory	= selectNativePixmapFactory(displayFactory, eglTestCtx.getTestContext().getCommandLine());
125 
126 		MovePtr<NativePixmap>	pixmap	(pixmapFactory.createPixmap(&nativeDisplay, dpy, config, DE_NULL, width, height));
127 		const EGLSurface		surface	= eglu::createPixmapSurface(eglTestCtx.getNativeDisplay(), *pixmap, dpy, config, DE_NULL);
128 
129 		return MovePtr<ManagedSurface>(new NativePixmapSurface(MovePtr<UniqueSurface>(new UniqueSurface(egl, dpy, surface)), pixmap));
130 	}
131 	else
132 		TCU_FAIL("No valid surface types supported in config");
133 }
134 
135 class GLClientBuffer : public ClientBuffer
136 {
get(void) const137 	EGLClientBuffer	get		(void) const { return reinterpret_cast<EGLClientBuffer>(static_cast<deUintptr>(getName())); }
138 
139 protected:
140 	virtual GLuint	getName	(void) const = 0;
141 };
142 
143 class TextureClientBuffer : public GLClientBuffer
144 {
145 public:
TextureClientBuffer(const glw::Functions & gl)146 						TextureClientBuffer	(const glw::Functions& gl) : m_texture (gl) {}
getName(void) const147 	GLuint				getName				(void) const { return *m_texture; }
148 
149 private:
150 	glu::Texture		m_texture;
151 };
152 
153 class GLImageSource : public ImageSource
154 {
155 public:
156 	EGLImageKHR			createImage			(const Library& egl, EGLDisplay dpy, EGLContext ctx, EGLClientBuffer clientBuffer) const;
157 
158 protected:
159 	virtual AttribMap	getCreateAttribs	(void) const = 0;
160 	virtual EGLenum		getSource			(void) const = 0;
161 };
162 
createImage(const Library & egl,EGLDisplay dpy,EGLContext ctx,EGLClientBuffer clientBuffer) const163 EGLImageKHR GLImageSource::createImage (const Library& egl, EGLDisplay dpy, EGLContext ctx, EGLClientBuffer clientBuffer) const
164 {
165 	AttribMap				attribMap	= getCreateAttribs();
166 
167 	attribMap[EGL_IMAGE_PRESERVED_KHR] = EGL_TRUE;
168 
169 	{
170 		const vector<EGLint>	attribs	= eglu::attribMapToList(attribMap);
171 		const EGLImageKHR		image	= egl.createImageKHR(dpy, ctx, getSource(),
172 															 clientBuffer, &attribs.front());
173 		EGLU_CHECK_MSG(egl, "eglCreateImageKHR()");
174 		return image;
175 	}
176 }
177 
178 class TextureImageSource : public GLImageSource
179 {
180 public:
TextureImageSource(GLenum internalFormat,GLenum format,GLenum type,bool useTexLevel0)181 							TextureImageSource	(GLenum internalFormat, GLenum format, GLenum type, bool useTexLevel0) : m_internalFormat(internalFormat), m_format(format), m_type(type), m_useTexLevel0(useTexLevel0) {}
182 	MovePtr<ClientBuffer>	createBuffer		(const eglw::Library& egl, const glw::Functions& gl, Texture2D* reference) const;
183 	GLenum					getEffectiveFormat	(void) const;
getInternalFormat(void) const184 	GLenum					getInternalFormat	(void) const { return m_internalFormat; }
185 
186 protected:
187 	AttribMap				getCreateAttribs	(void) const;
188 	virtual void			initTexture			(const glw::Functions& gl) const = 0;
189 	virtual GLenum			getGLTarget			(void) const = 0;
190 
191 	const GLenum			m_internalFormat;
192 	const GLenum			m_format;
193 	const GLenum			m_type;
194 	const bool				m_useTexLevel0;
195 };
196 
isSizedFormat(GLenum format)197 bool isSizedFormat (GLenum format)
198 {
199 	try
200 	{
201 		glu::mapGLInternalFormat(format);
202 		return true;
203 	}
204 	catch (const tcu::InternalError&)
205 	{
206 		return false;
207 	}
208 }
209 
getEffectiveFormat(GLenum format,GLenum type)210 GLenum getEffectiveFormat (GLenum format, GLenum type)
211 {
212 	return glu::getInternalFormat(glu::mapGLTransferFormat(format, type));
213 }
214 
getEffectiveFormat(void) const215 GLenum TextureImageSource::getEffectiveFormat (void) const
216 {
217 	if (isSizedFormat(m_internalFormat))
218 		return m_internalFormat;
219 	else
220 		return deqp::egl::Image::getEffectiveFormat(m_format, m_type);
221 }
222 
getCreateAttribs(void) const223 AttribMap TextureImageSource::getCreateAttribs (void) const
224 {
225 	AttribMap ret;
226 
227 	ret[EGL_GL_TEXTURE_LEVEL_KHR] = 0;
228 
229 	return ret;
230 }
231 
createBuffer(const eglw::Library & egl,const glw::Functions & gl,Texture2D * ref) const232 MovePtr<ClientBuffer> TextureImageSource::createBuffer (const eglw::Library& egl, const glw::Functions& gl, Texture2D* ref) const
233 {
234 	DE_UNREF(egl);
235 
236 	MovePtr<TextureClientBuffer>	clientBuffer	(new TextureClientBuffer(gl));
237 	const GLuint					texture			= clientBuffer->getName();
238 	const GLenum					target			= getGLTarget();
239 
240 	GLU_CHECK_GLW_CALL(gl, bindTexture(target, texture));
241 	initTexture(gl);
242 
243 	if (!m_useTexLevel0)
244 	{
245 		// Set minification filter to linear. This makes the texture complete.
246 		GLU_CHECK_GLW_CALL(gl, texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
247 	}
248 
249 	if (ref != DE_NULL)
250 	{
251 		GLenum		imgTarget	= eglu::getImageGLTarget(getSource());
252 
253 		*ref = Texture2D(glu::mapGLTransferFormat(m_format, m_type), IMAGE_WIDTH, IMAGE_HEIGHT);
254 		ref->allocLevel(0);
255 		tcu::fillWithComponentGradients(ref->getLevel(0),
256 										tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
257 										tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
258 
259 		GLU_CHECK_GLW_CALL(gl, texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
260 		GLU_CHECK_GLW_CALL(gl, texParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
261 		GLU_CHECK_GLW_CALL(gl, texParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
262 		GLU_CHECK_GLW_CALL(gl, texParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
263 
264 		GLU_CHECK_GLW_CALL(gl, texImage2D(imgTarget, 0, m_internalFormat, IMAGE_WIDTH, IMAGE_HEIGHT,
265 										  0, m_format, m_type, ref->getLevel(0).getDataPtr()));
266 	}
267 	GLU_CHECK_GLW_CALL(gl, bindTexture(target, 0));
268 	return MovePtr<ClientBuffer>(clientBuffer);
269 }
270 
271 class Texture2DImageSource : public TextureImageSource
272 {
273 public:
Texture2DImageSource(GLenum internalFormat,GLenum format,GLenum type,bool useTexLevel0)274 					Texture2DImageSource	(GLenum internalFormat, GLenum format, GLenum type, bool useTexLevel0) : TextureImageSource(internalFormat, format, type, useTexLevel0) {}
getSource(void) const275 	EGLenum			getSource				(void) const { return EGL_GL_TEXTURE_2D_KHR; }
getRequiredExtension(void) const276 	string			getRequiredExtension	(void) const { return "EGL_KHR_gl_texture_2D_image"; }
getGLTarget(void) const277 	GLenum			getGLTarget				(void) const { return GL_TEXTURE_2D; }
278 
279 protected:
280 	void			initTexture				(const glw::Functions& gl) const;
281 };
282 
initTexture(const glw::Functions & gl) const283 void Texture2DImageSource::initTexture (const glw::Functions& gl) const
284 {
285 	// Specify mipmap level 0
286 	GLU_CHECK_CALL_ERROR(gl.texImage2D(GL_TEXTURE_2D, 0, m_internalFormat, IMAGE_WIDTH, IMAGE_HEIGHT, 0, m_format, m_type, DE_NULL),
287 						 gl.getError());
288 }
289 
290 class TextureCubeMapImageSource : public TextureImageSource
291 {
292 public:
TextureCubeMapImageSource(EGLenum source,GLenum internalFormat,GLenum format,GLenum type,bool useTexLevel0)293 					TextureCubeMapImageSource	(EGLenum source, GLenum internalFormat, GLenum format, GLenum type, bool useTexLevel0) : TextureImageSource(internalFormat, format, type, useTexLevel0), m_source(source) {}
getSource(void) const294 	EGLenum			getSource					(void) const { return m_source; }
getRequiredExtension(void) const295 	string			getRequiredExtension		(void) const { return "EGL_KHR_gl_texture_cubemap_image"; }
getGLTarget(void) const296 	GLenum			getGLTarget					(void) const { return GL_TEXTURE_CUBE_MAP; }
297 
298 protected:
299 	void			initTexture					(const glw::Functions& gl) const;
300 
301 	EGLenum			m_source;
302 };
303 
initTexture(const glw::Functions & gl) const304 void TextureCubeMapImageSource::initTexture (const glw::Functions& gl) const
305 {
306 	// Specify mipmap level 0 for all faces
307 	static const GLenum faces[] =
308 	{
309 		GL_TEXTURE_CUBE_MAP_POSITIVE_X,
310 		GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
311 		GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
312 		GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
313 		GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
314 		GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
315 	};
316 
317 	for (int faceNdx = 0; faceNdx < DE_LENGTH_OF_ARRAY(faces); faceNdx++)
318 		GLU_CHECK_GLW_CALL(gl, texImage2D(faces[faceNdx], 0, m_internalFormat, IMAGE_WIDTH, IMAGE_HEIGHT, 0, m_format, m_type, DE_NULL));
319 }
320 
321 class RenderbufferClientBuffer : public GLClientBuffer
322 {
323 public:
RenderbufferClientBuffer(const glw::Functions & gl)324 						RenderbufferClientBuffer	(const glw::Functions& gl) : m_rbo (gl) {}
getName(void) const325 	GLuint				getName						(void) const { return *m_rbo; }
326 
327 private:
328 	glu::Renderbuffer	m_rbo;
329 };
330 
331 class RenderbufferImageSource : public GLImageSource
332 {
333 public:
RenderbufferImageSource(GLenum format)334 							RenderbufferImageSource	(GLenum format) : m_format(format) {}
335 
getRequiredExtension(void) const336 	string					getRequiredExtension	(void) const	{ return "EGL_KHR_gl_renderbuffer_image"; }
337 	MovePtr<ClientBuffer>	createBuffer			(const eglw::Library& egl, const glw::Functions& gl, Texture2D* reference) const;
getEffectiveFormat(void) const338 	GLenum					getEffectiveFormat		(void) const { return m_format; }
339 
340 protected:
getSource(void) const341 	EGLenum					getSource				(void) const	{ return EGL_GL_RENDERBUFFER_KHR; }
getCreateAttribs(void) const342 	AttribMap				getCreateAttribs		(void) const	{ return AttribMap(); }
343 
344 	GLenum					m_format;
345 };
346 
initializeStencilRbo(const glw::Functions & gl,GLuint rbo,Texture2D & ref)347 void initializeStencilRbo(const glw::Functions& gl, GLuint rbo, Texture2D& ref)
348 {
349 	static const deUint32 stencilValues[] =
350 	{
351 		0xBF688C11u,
352 		0xB43D2922u,
353 		0x055D5FFBu,
354 		0x9300655Eu,
355 		0x63BE0DF2u,
356 		0x0345C13Bu,
357 		0x1C184832u,
358 		0xD107040Fu,
359 		0x9B91569Fu,
360 		0x0F0CFDC7u,
361 	};
362 
363 	const deUint32 numStencilBits	= tcu::getTextureFormatBitDepth(tcu::getEffectiveDepthStencilTextureFormat(ref.getLevel(0).getFormat(), tcu::Sampler::MODE_STENCIL)).x();
364 	const deUint32 stencilMask		= deBitMask32(0, numStencilBits);
365 
366 	GLU_CHECK_GLW_CALL(gl, framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
367 												   GL_RENDERBUFFER, rbo));
368 	GLU_CHECK_GLW_CALL(gl, clearStencil(0));
369 	GLU_CHECK_GLW_CALL(gl, clear(GL_STENCIL_BUFFER_BIT));
370 	tcu::clearStencil(ref.getLevel(0), 0);
371 
372 	// create a pattern
373 	GLU_CHECK_GLW_CALL(gl, enable(GL_SCISSOR_TEST));
374 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(stencilValues); ++ndx)
375 	{
376 		const deUint32		stencil	= stencilValues[ndx] & stencilMask;
377 		const tcu::IVec2	size	= tcu::IVec2((int)((float)(DE_LENGTH_OF_ARRAY(stencilValues) - ndx) * ((float)ref.getWidth() / float(DE_LENGTH_OF_ARRAY(stencilValues)))),
378 												 (int)((float)(DE_LENGTH_OF_ARRAY(stencilValues) - ndx) * ((float)ref.getHeight() / float(DE_LENGTH_OF_ARRAY(stencilValues) + 4)))); // not symmetric
379 
380 		if (size.x() == 0 || size.y() == 0)
381 			break;
382 
383 		GLU_CHECK_GLW_CALL(gl, scissor(0, 0, size.x(), size.y()));
384 		GLU_CHECK_GLW_CALL(gl, clearStencil(stencil));
385 		GLU_CHECK_GLW_CALL(gl, clear(GL_STENCIL_BUFFER_BIT));
386 
387 		tcu::clearStencil(tcu::getSubregion(ref.getLevel(0), 0, 0, size.x(), size.y()), stencil);
388 	}
389 
390 	GLU_CHECK_GLW_CALL(gl, disable(GL_SCISSOR_TEST));
391 	GLU_CHECK_GLW_CALL(gl, framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
392 												   GL_RENDERBUFFER, 0));
393 }
394 
initializeDepthRbo(const glw::Functions & gl,GLuint rbo,Texture2D & ref)395 void initializeDepthRbo(const glw::Functions& gl, GLuint rbo, Texture2D& ref)
396 {
397 	const int NUM_STEPS = 13;
398 
399 	GLU_CHECK_GLW_CALL(gl, framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
400 												   GL_RENDERBUFFER, rbo));
401 
402 	GLU_CHECK_GLW_CALL(gl, clearDepthf(0.0f));
403 	GLU_CHECK_GLW_CALL(gl, clear(GL_DEPTH_BUFFER_BIT));
404 	tcu::clearDepth(ref.getLevel(0), 0.0f);
405 
406 	// create a pattern
407 	GLU_CHECK_GLW_CALL(gl, enable(GL_SCISSOR_TEST));
408 	for (int ndx = 0; ndx < NUM_STEPS; ++ndx)
409 	{
410 		const float			depth	= (float)ndx / float(NUM_STEPS);
411 		const tcu::IVec2	size	= tcu::IVec2((int)((float)(NUM_STEPS - ndx) * ((float)ref.getWidth() / float(NUM_STEPS))),
412 												 (int)((float)(NUM_STEPS - ndx) * ((float)ref.getHeight() / float(NUM_STEPS + 4)))); // not symmetric
413 
414 		if (size.x() == 0 || size.y() == 0)
415 			break;
416 
417 		GLU_CHECK_GLW_CALL(gl, scissor(0, 0, size.x(), size.y()));
418 		GLU_CHECK_GLW_CALL(gl, clearDepthf(depth));
419 		GLU_CHECK_GLW_CALL(gl, clear(GL_DEPTH_BUFFER_BIT));
420 
421 		tcu::clearDepth(tcu::getSubregion(ref.getLevel(0), 0, 0, size.x(), size.y()), depth);
422 	}
423 
424 	GLU_CHECK_GLW_CALL(gl, disable(GL_SCISSOR_TEST));
425 	GLU_CHECK_GLW_CALL(gl, framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
426 												   GL_RENDERBUFFER, 0));
427 
428 }
429 
initializeColorRbo(const glw::Functions & gl,GLuint rbo,Texture2D & ref)430 void initializeColorRbo(const glw::Functions& gl, GLuint rbo, Texture2D& ref)
431 {
432 	static const tcu::Vec4 colorValues[] =
433 	{
434 		tcu::Vec4(0.9f, 0.5f, 0.65f, 1.0f),
435 		tcu::Vec4(0.5f, 0.7f, 0.65f, 1.0f),
436 		tcu::Vec4(0.2f, 0.5f, 0.65f, 1.0f),
437 		tcu::Vec4(0.3f, 0.1f, 0.5f, 1.0f),
438 		tcu::Vec4(0.8f, 0.2f, 0.3f, 1.0f),
439 		tcu::Vec4(0.9f, 0.4f, 0.8f, 1.0f),
440 	};
441 
442 	GLU_CHECK_GLW_CALL(gl, framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
443 												   GL_RENDERBUFFER, rbo));
444 	GLU_CHECK_GLW_CALL(gl, clearColor(1.0f, 1.0f, 0.0f, 1.0f));
445 	GLU_CHECK_GLW_CALL(gl, clear(GL_COLOR_BUFFER_BIT));
446 	tcu::clear(ref.getLevel(0), Vec4(1.0f, 1.0f, 0.0f, 1.0f));
447 
448 	// create a pattern
449 	GLU_CHECK_GLW_CALL(gl, enable(GL_SCISSOR_TEST));
450 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorValues); ++ndx)
451 	{
452 		const tcu::IVec2	size	= tcu::IVec2((int)((float)(DE_LENGTH_OF_ARRAY(colorValues) - ndx) * ((float)ref.getWidth() / float(DE_LENGTH_OF_ARRAY(colorValues)))),
453 												 (int)((float)(DE_LENGTH_OF_ARRAY(colorValues) - ndx) * ((float)ref.getHeight() / float(DE_LENGTH_OF_ARRAY(colorValues) + 4)))); // not symmetric
454 
455 		if (size.x() == 0 || size.y() == 0)
456 			break;
457 
458 		GLU_CHECK_GLW_CALL(gl, scissor(0, 0, size.x(), size.y()));
459 		GLU_CHECK_GLW_CALL(gl, clearColor(colorValues[ndx].x(), colorValues[ndx].y(), colorValues[ndx].z(), colorValues[ndx].w()));
460 		GLU_CHECK_GLW_CALL(gl, clear(GL_COLOR_BUFFER_BIT));
461 
462 		tcu::clear(tcu::getSubregion(ref.getLevel(0), 0, 0, size.x(), size.y()), colorValues[ndx]);
463 	}
464 
465 	GLU_CHECK_GLW_CALL(gl, disable(GL_SCISSOR_TEST));
466 	GLU_CHECK_GLW_CALL(gl, framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
467 												   GL_RENDERBUFFER, 0));
468 }
469 
createBuffer(const eglw::Library & egl,const glw::Functions & gl,Texture2D * ref) const470 MovePtr<ClientBuffer> RenderbufferImageSource::createBuffer (const eglw::Library& egl, const glw::Functions& gl, Texture2D* ref) const
471 {
472 	DE_UNREF(egl);
473 
474 	MovePtr<RenderbufferClientBuffer>	buffer	(new RenderbufferClientBuffer(gl));
475 	const GLuint						rbo		= buffer->getName();
476 
477 	GLU_CHECK_CALL_ERROR(gl.bindRenderbuffer(GL_RENDERBUFFER, rbo), gl.getError());
478 
479 	// Specify storage.
480 	GLU_CHECK_CALL_ERROR(gl.renderbufferStorage(GL_RENDERBUFFER, m_format, 64, 64), gl.getError());
481 
482 	if (ref != DE_NULL)
483 	{
484 		Framebuffer			fbo			(gl);
485 		const TextureFormat	texFormat	= glu::mapGLInternalFormat(m_format);
486 
487 		*ref = tcu::Texture2D(texFormat, 64, 64);
488 		ref->allocLevel(0);
489 
490 		gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
491 		switch (m_format)
492 		{
493 			case GL_STENCIL_INDEX8:
494 				initializeStencilRbo(gl, rbo, *ref);
495 				break;
496 			case GL_DEPTH_COMPONENT16:
497 				initializeDepthRbo(gl, rbo, *ref);
498 				break;
499 			case GL_RGBA4:
500 				initializeColorRbo(gl, rbo, *ref);
501 				break;
502 			case GL_RGB5_A1:
503 				initializeColorRbo(gl, rbo, *ref);
504 				break;
505 			case GL_RGB565:
506 				initializeColorRbo(gl, rbo, *ref);
507 				break;
508 			default:
509 				DE_FATAL("Impossible");
510 		}
511 
512 		gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
513 	}
514 
515 	return MovePtr<ClientBuffer>(buffer);
516 }
517 
518 class UnsupportedImageSource : public ImageSource
519 {
520 public:
UnsupportedImageSource(const string & message,GLenum format,bool isYUV)521 							UnsupportedImageSource	(const string& message, GLenum format, bool isYUV) : m_message(message), m_format(format), m_isY8Cb8Cr8_420(isYUV) {}
getRequiredExtension(void) const522 	string					getRequiredExtension	(void) const { fail(); return ""; }
createBuffer(const eglw::Library & egl,const glw::Functions &,tcu::Texture2D *) const523 	MovePtr<ClientBuffer>	createBuffer			(const eglw::Library& egl, const glw::Functions&, tcu::Texture2D*) const { DE_UNREF(egl); fail(); return de::MovePtr<ClientBuffer>(); }
524 	EGLImageKHR				createImage				(const Library& egl, EGLDisplay dpy, EGLContext ctx, EGLClientBuffer clientBuffer) const;
getEffectiveFormat(void) const525 	GLenum					getEffectiveFormat		(void) const { return m_format; }
isYUVFormatImage(void) const526 	bool					isYUVFormatImage		(void) const {return m_isY8Cb8Cr8_420;};
527 private:
528 	const string			m_message;
529 	GLenum					m_format;
530 	bool					m_isY8Cb8Cr8_420;
fail(void) const531 	void					fail					(void) const { TCU_THROW(NotSupportedError, m_message.c_str()); }
532 };
533 
createImage(const Library &,EGLDisplay,EGLContext,EGLClientBuffer) const534 EGLImageKHR	UnsupportedImageSource::createImage (const Library&, EGLDisplay, EGLContext, EGLClientBuffer) const
535 {
536 	fail();
537 	return EGL_NO_IMAGE_KHR;
538 }
539 
createTextureImageSource(EGLenum source,GLenum internalFormat,GLenum format,GLenum type,bool useTexLevel0)540 MovePtr<ImageSource> createTextureImageSource (EGLenum source, GLenum internalFormat, GLenum format, GLenum type, bool useTexLevel0)
541 {
542 	if (source == EGL_GL_TEXTURE_2D_KHR)
543 		return MovePtr<ImageSource>(new Texture2DImageSource(internalFormat, format, type, useTexLevel0));
544 	else
545 		return MovePtr<ImageSource>(new TextureCubeMapImageSource(source, internalFormat, format, type, useTexLevel0));
546 }
547 
createRenderbufferImageSource(GLenum format)548 MovePtr<ImageSource> createRenderbufferImageSource (GLenum format)
549 {
550 	return MovePtr<ImageSource>(new RenderbufferImageSource(format));
551 }
552 
createUnsupportedImageSource(const string & message,GLenum format,bool isYUV)553 MovePtr<ImageSource> createUnsupportedImageSource (const string& message, GLenum format, bool isYUV)
554 {
555 	return MovePtr<ImageSource>(new UnsupportedImageSource(message, format, isYUV));
556 }
557 
558 } // Image
559 } // egl
560 } // deqp
561