1 #ifndef _GLSLIFETIMETESTS_HPP
2 #define _GLSLIFETIMETESTS_HPP
3 /*-------------------------------------------------------------------------
4  * drawElements Quality Program OpenGL (ES) Module
5  * -----------------------------------------------
6  *
7  * Copyright 2014 The Android Open Source Project
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Common object lifetime tests.
24  *//*--------------------------------------------------------------------*/
25 
26 #include "deRandom.hpp"
27 #include "deUniquePtr.hpp"
28 #include "tcuSurface.hpp"
29 #include "tcuTestCase.hpp"
30 #include "tcuTestContext.hpp"
31 #include "gluCallLogWrapper.hpp"
32 #include "gluRenderContext.hpp"
33 #include "glwDefs.hpp"
34 #include "glwEnums.hpp"
35 
36 #include <vector>
37 
38 namespace deqp
39 {
40 namespace gls
41 {
42 namespace LifetimeTests
43 {
44 namespace details
45 {
46 
47 using std::vector;
48 using de::MovePtr;
49 using de::Random;
50 using tcu::Surface;
51 using tcu::TestCaseGroup;
52 using tcu::TestContext;
53 using tcu::TestLog;
54 using glu::CallLogWrapper;
55 using glu::RenderContext;
56 using namespace glw;
57 
58 typedef void		(CallLogWrapper::*BindFunc)		(GLenum target, GLuint name);
59 typedef void		(CallLogWrapper::*GenFunc)		(GLsizei n, GLuint* names);
60 typedef void		(CallLogWrapper::*DeleteFunc)	(GLsizei n, const GLuint* names);
61 typedef GLboolean	(CallLogWrapper::*ExistsFunc)	(GLuint name);
62 
63 class Context
64 {
65 public:
Context(const RenderContext & renderCtx,TestContext & testCtx)66 							Context				(const RenderContext& renderCtx,
67 												 TestContext& testCtx)
68 								: m_renderCtx	(renderCtx)
69 								, m_testCtx		(testCtx) {}
getRenderContext(void) const70 	const RenderContext&	getRenderContext	(void) const { return m_renderCtx; }
getTestContext(void) const71 	TestContext&			getTestContext		(void) const { return m_testCtx; }
gl(void) const72 	const Functions&		gl					(void) const { return m_renderCtx.getFunctions(); }
log(void) const73 	TestLog&				log					(void) const { return m_testCtx.getLog(); }
74 
75 private:
76 	const RenderContext&	m_renderCtx;
77 	TestContext&			m_testCtx;
78 };
79 
80 class ContextWrapper : public CallLogWrapper
81 {
82 public:
getContext(void) const83 	const Context&			getContext			(void) const { return m_ctx; }
getRenderContext(void) const84 	const RenderContext&	getRenderContext	(void) const { return m_ctx.getRenderContext(); }
getTestContext(void) const85 	TestContext&			getTestContext		(void) const { return m_ctx.getTestContext(); }
gl(void) const86 	const Functions&		gl					(void) const { return m_ctx.gl(); }
log(void) const87 	TestLog&				log					(void) const { return m_ctx.log(); }
enableLogging(bool enable)88 	void					enableLogging		(bool enable)
89 	{
90 		CallLogWrapper::enableLogging(enable);
91 	}
92 
93 protected:
94 							ContextWrapper				(const Context& ctx);
95 	const Context			m_ctx;
96 };
97 
98 class Binder : public ContextWrapper
99 {
100 public:
~Binder(void)101 	virtual				~Binder			(void) {}
102 	virtual void		bind			(GLuint name) = 0;
103 	virtual GLuint		getBinding		(void) = 0;
genRequired(void) const104 	virtual bool		genRequired		(void) const { return true; }
105 
106 protected:
Binder(const Context & ctx)107 						Binder			(const Context& ctx) : ContextWrapper(ctx) {}
108 };
109 
110 class SimpleBinder : public Binder
111 {
112 public:
SimpleBinder(const Context & ctx,BindFunc bindFunc,GLenum bindTarget,GLenum bindingParam,bool genRequired_=false)113 						SimpleBinder	(const Context& ctx,
114 										 BindFunc bindFunc,
115 										 GLenum bindTarget,
116 										 GLenum bindingParam,
117 										 bool genRequired_ = false)
118 							: Binder			(ctx)
119 							, m_bindFunc		(bindFunc)
120 							, m_bindTarget		(bindTarget)
121 							, m_bindingParam	(bindingParam)
122 							, m_genRequired		(genRequired_) {}
123 
124 	void				bind			(GLuint name);
125 	GLuint				getBinding		(void);
genRequired(void) const126 	bool				genRequired		(void) const { return m_genRequired; }
127 
128 private:
129 	const BindFunc		m_bindFunc;
130 	const GLenum		m_bindTarget;
131 	const GLenum		m_bindingParam;
132 	const bool			m_genRequired;
133 };
134 
135 class Type : public ContextWrapper
136 {
137 public:
~Type(void)138 	virtual					~Type			(void) {}
139 	virtual GLuint			gen				(void) = 0;
140 	virtual void			release			(GLuint name) = 0;
141 	virtual bool			exists			(GLuint name) = 0;
isDeleteFlagged(GLuint name)142 	virtual bool			isDeleteFlagged	(GLuint name) { DE_UNREF(name); return false; }
binder(void) const143 	virtual Binder*			binder			(void) const { return DE_NULL; }
144 	virtual const char*		getName			(void) const = 0;
nameLingers(void) const145 	virtual bool			nameLingers		(void) const { return false; }
genCreates(void) const146 	virtual bool			genCreates		(void) const { return false; }
147 
148 protected:
Type(const Context & ctx)149 							Type			(const Context& ctx) : ContextWrapper(ctx) {}
150 };
151 
152 class SimpleType : public Type
153 {
154 public:
SimpleType(const Context & ctx,const char * name,GenFunc genFunc,DeleteFunc deleteFunc,ExistsFunc existsFunc,Binder * binder_=DE_NULL,bool genCreates_=false)155 				SimpleType	(const Context& ctx, const char* name,
156 							 GenFunc genFunc, DeleteFunc deleteFunc, ExistsFunc existsFunc,
157 							 Binder* binder_ = DE_NULL, bool genCreates_ = false)
158 						: Type			(ctx)
159 						, m_getName		(name)
160 						, m_genFunc		(genFunc)
161 						, m_deleteFunc	(deleteFunc)
162 						, m_existsFunc	(existsFunc)
163 						, m_binder		(binder_)
164 						, m_genCreates	(genCreates_) {}
165 
166 	GLuint			gen 		(void);
release(GLuint name)167 	void			release		(GLuint name)		{ (this->*m_deleteFunc)(1, &name); }
exists(GLuint name)168 	bool			exists		(GLuint name)		{ return (this->*m_existsFunc)(name) != GL_FALSE; }
binder(void) const169 	Binder*			binder		(void) const		{ return m_binder; }
getName(void) const170 	const char*		getName		(void) const		{ return m_getName; }
nameLingers(void) const171 	bool			nameLingers	(void) const		{ return false; }
genCreates(void) const172 	bool			genCreates	(void) const		{ return m_genCreates; }
173 
174 private:
175 	const char* const	m_getName;
176 	const GenFunc		m_genFunc;
177 	const DeleteFunc	m_deleteFunc;
178 	const ExistsFunc	m_existsFunc;
179 	Binder* const		m_binder;
180 	const bool			m_genCreates;
181 };
182 
183 class ProgramType : public Type
184 {
185 public:
ProgramType(const Context & ctx)186 					ProgramType		(const Context& ctx) : Type(ctx) {}
nameLingers(void) const187 	bool			nameLingers		(void) const	{ return true; }
genCreates(void) const188 	bool			genCreates		(void) const	{ return true; }
getName(void) const189 	const char*		getName			(void) const	{ return "program"; }
gen(void)190 	GLuint			gen				(void)			{ return glCreateProgram(); }
release(GLuint name)191 	void			release			(GLuint name)	{ glDeleteProgram(name); }
exists(GLuint name)192 	bool			exists			(GLuint name)	{ return glIsProgram(name) != GL_FALSE; }
193 	bool			isDeleteFlagged	(GLuint name);
194 };
195 
196 class ShaderType : public Type
197 {
198 public:
ShaderType(const Context & ctx)199 					ShaderType		(const Context& ctx) : Type(ctx) {}
nameLingers(void) const200 	bool			nameLingers		(void) const { return true; }
genCreates(void) const201 	bool			genCreates		(void) const { return true; }
getName(void) const202 	const char*		getName			(void) const { return "shader"; }
gen(void)203 	GLuint			gen				(void) { return glCreateShader(GL_FRAGMENT_SHADER); }
release(GLuint name)204 	void			release			(GLuint name) { glDeleteShader(name); }
exists(GLuint name)205 	bool			exists			(GLuint name) { return glIsShader(name) != GL_FALSE; }
206 	bool			isDeleteFlagged	(GLuint name);
207 };
208 
209 class Attacher : public ContextWrapper
210 {
211 public:
212 	virtual void		initAttachment			(GLuint seed, GLuint attachment) = 0;
213 	virtual void		attach					(GLuint element, GLuint container) = 0;
214 	virtual void		detach					(GLuint element, GLuint container) = 0;
215 	virtual GLuint		getAttachment			(GLuint container) = 0;
canAttachDeleted(void) const216 	virtual bool		canAttachDeleted		(void) const { return true; }
217 
getElementType(void) const218 	Type&				getElementType			(void) const { return m_elementType; }
getContainerType(void) const219 	Type&				getContainerType		(void) const { return m_containerType; }
~Attacher(void)220 	virtual				~Attacher				(void) {}
221 
222 protected:
Attacher(const Context & ctx,Type & elementType,Type & containerType)223 						Attacher				(const Context& ctx,
224 												 Type& elementType, Type& containerType)
225 							: ContextWrapper	(ctx)
226 							, m_elementType		(elementType)
227 							, m_containerType	(containerType) {}
228 
229 private:
230 	Type&				m_elementType;
231 	Type&				m_containerType;
232 };
233 
234 class InputAttacher : public ContextWrapper
235 {
236 public:
getAttacher(void) const237 	Attacher&			getAttacher				(void) const { return m_attacher; }
238 	virtual void		drawContainer			(GLuint container, Surface& dst) = 0;
239 protected:
InputAttacher(Attacher & attacher)240 						InputAttacher			(Attacher& attacher)
241 							: ContextWrapper	(attacher.getContext())
242 							, m_attacher		(attacher) {}
243 	Attacher&			m_attacher;
244 };
245 
246 class OutputAttacher : public ContextWrapper
247 {
248 public:
getAttacher(void) const249 	Attacher&			getAttacher				(void) const { return m_attacher; }
250 	virtual void		setupContainer			(GLuint seed, GLuint container) = 0;
251 	virtual void		drawAttachment			(GLuint attachment, Surface& dst) = 0;
252 protected:
OutputAttacher(Attacher & attacher)253 						OutputAttacher			(Attacher& attacher)
254 							: ContextWrapper	(attacher.getContext())
255 							, m_attacher		(attacher) {}
256 	Attacher&			m_attacher;
257 };
258 
259 class Types : public ContextWrapper
260 {
261 public:
Types(const Context & ctx)262 									Types				(const Context& ctx)
263 										: ContextWrapper(ctx) {}
264 	virtual Type&					getProgramType		(void) = 0;
getTypes(void)265 	const vector<Type*>&			getTypes			(void) { return m_types; }
getAttachers(void)266 	const vector<Attacher*>&		getAttachers		(void) { return m_attachers; }
getInputAttachers(void)267 	const vector<InputAttacher*>&	getInputAttachers	(void) { return m_inAttachers; }
getOutputAttachers(void)268 	const vector<OutputAttacher*>&	getOutputAttachers	(void) { return m_outAttachers; }
~Types(void)269 	virtual							~Types				(void) {}
270 
271 protected:
272 	vector<Type*>					m_types;
273 	vector<Attacher*>				m_attachers;
274 	vector<InputAttacher*>			m_inAttachers;
275 	vector<OutputAttacher*>			m_outAttachers;
276 };
277 
278 class FboAttacher : public Attacher
279 {
280 public:
281 	void			initAttachment		(GLuint seed, GLuint element);
282 
283 protected:
FboAttacher(const Context & ctx,Type & elementType,Type & containerType)284 					FboAttacher			(const Context& ctx,
285 										 Type& elementType, Type& containerType)
286 						: Attacher 		(ctx, elementType, containerType) {}
287 	virtual void	initStorage			(void) = 0;
288 };
289 
290 class FboInputAttacher : public InputAttacher
291 {
292 public:
FboInputAttacher(FboAttacher & attacher)293 			FboInputAttacher		(FboAttacher& attacher)
294 				: InputAttacher 	(attacher) {}
295 	void	drawContainer			(GLuint container, Surface& dst);
296 };
297 
298 class FboOutputAttacher : public OutputAttacher
299 {
300 public:
FboOutputAttacher(FboAttacher & attacher)301 			FboOutputAttacher			(FboAttacher& attacher)
302 				: OutputAttacher 		(attacher) {}
303 	void	setupContainer				(GLuint seed, GLuint container);
304 	void	drawAttachment				(GLuint attachment, Surface& dst);
305 };
306 
307 class TextureFboAttacher : public FboAttacher
308 {
309 public:
TextureFboAttacher(const Context & ctx,Type & elementType,Type & containerType)310 			TextureFboAttacher	(const Context& ctx, Type& elementType, Type& containerType)
311 				: FboAttacher	(ctx, elementType, containerType) {}
312 
313 	void	initStorage			(void);
314 	void	attach				(GLuint element, GLuint container);
315 	void	detach				(GLuint element, GLuint container);
316 	GLuint	getAttachment		(GLuint container);
317 };
318 
319 class RboFboAttacher : public FboAttacher
320 {
321 public:
RboFboAttacher(const Context & ctx,Type & elementType,Type & containerType)322 			RboFboAttacher		(const Context& ctx, Type& elementType, Type& containerType)
323 				: FboAttacher	(ctx, elementType, containerType) {}
324 
325 	void	initStorage			(void);
326 	void	attach				(GLuint element, GLuint container);
327 	void	detach				(GLuint element, GLuint container);
328 	GLuint	getAttachment		(GLuint container);
329 };
330 
331 class ShaderProgramAttacher : public Attacher
332 {
333 public:
ShaderProgramAttacher(const Context & ctx,Type & elementType,Type & containerType)334 			ShaderProgramAttacher	(const Context& ctx,
335 									 Type& elementType, Type& containerType)
336 				: Attacher			(ctx, elementType, containerType) {}
337 
338 	void	initAttachment		(GLuint seed, GLuint element);
339 	void	attach				(GLuint element, GLuint container);
340 	void	detach				(GLuint element, GLuint container);
341 	GLuint	getAttachment		(GLuint container);
342 };
343 
344 class ShaderProgramInputAttacher : public InputAttacher
345 {
346 public:
ShaderProgramInputAttacher(Attacher & attacher)347 			ShaderProgramInputAttacher	(Attacher& attacher)
348 				: InputAttacher			(attacher) {}
349 
350 	void	drawContainer				(GLuint container, Surface& dst);
351 };
352 
353 class ES2Types : public Types
354 {
355 public:
356 								ES2Types		(const Context& ctx);
getProgramType(void)357 	Type&						getProgramType	(void) { return m_programType; }
358 
359 protected:
360 	SimpleBinder				m_bufferBind;
361 	SimpleType					m_bufferType;
362 	SimpleBinder				m_textureBind;
363 	SimpleType					m_textureType;
364 	SimpleBinder				m_rboBind;
365 	SimpleType					m_rboType;
366 	SimpleBinder				m_fboBind;
367 	SimpleType					m_fboType;
368 	ShaderType					m_shaderType;
369 	ProgramType					m_programType;
370 	TextureFboAttacher			m_texFboAtt;
371 	FboInputAttacher			m_texFboInAtt;
372 	FboOutputAttacher			m_texFboOutAtt;
373 	RboFboAttacher				m_rboFboAtt;
374 	FboInputAttacher			m_rboFboInAtt;
375 	FboOutputAttacher			m_rboFboOutAtt;
376 	ShaderProgramAttacher		m_shaderAtt;
377 	ShaderProgramInputAttacher	m_shaderInAtt;
378 };
379 
380 MovePtr<TestCaseGroup>	createGroup		(TestContext& testCtx, Type& type);
381 void					addTestCases	(TestCaseGroup& group, Types& types);
382 
383 struct Rectangle
384 {
Rectangledeqp::gls::LifetimeTests::details::Rectangle385 			Rectangle	(GLint x_, GLint y_, GLint width_, GLint height_)
386 				: x			(x_)
387 				, y			(y_)
388 				, width		(width_)
389 				, height	(height_) {}
390 	GLint	x;
391 	GLint	y;
392 	GLint	width;
393 	GLint	height;
394 };
395 
396 Rectangle	randomViewport	(const RenderContext& ctx, GLint maxWidth, GLint maxHeight,
397 							 Random& rnd);
398 void		setViewport		(const RenderContext& renderCtx, const Rectangle& rect);
399 void		readRectangle	(const RenderContext& renderCtx, const Rectangle& rect,
400 							 Surface& dst);
401 
402 } // details
403 
404 using details::BindFunc;
405 using details::GenFunc;
406 using details::DeleteFunc;
407 using details::ExistsFunc;
408 
409 using details::Context;
410 using details::Binder;
411 using details::SimpleBinder;
412 using details::Type;
413 using details::SimpleType;
414 using details::Attacher;
415 using details::InputAttacher;
416 using details::OutputAttacher;
417 using details::Types;
418 using details::ES2Types;
419 
420 using details::createGroup;
421 using details::addTestCases;
422 
423 using details::Rectangle;
424 using details::randomViewport;
425 using details::setViewport;
426 using details::readRectangle;
427 
428 } // LifetimeTests
429 } // gls
430 } // deqp
431 
432 #endif // _GLSLIFETIMETESTS_HPP
433