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
38namespace deqp
39{
40namespace gls
41{
42namespace LifetimeTests
43{
44namespace details
45{
46
47using std::vector;
48using de::MovePtr;
49using de::Random;
50using tcu::Surface;
51using tcu::TestCaseGroup;
52using tcu::TestContext;
53using tcu::TestLog;
54using glu::CallLogWrapper;
55using glu::RenderContext;
56using namespace glw;
57
58typedef void		(CallLogWrapper::*BindFunc)		(GLenum target, GLuint name);
59typedef void		(CallLogWrapper::*GenFunc)		(GLsizei n, GLuint* names);
60typedef void		(CallLogWrapper::*DeleteFunc)	(GLsizei n, const GLuint* names);
61typedef GLboolean	(CallLogWrapper::*ExistsFunc)	(GLuint name);
62
63class Context
64{
65public:
66							Context				(const RenderContext& renderCtx,
67												 TestContext& testCtx)
68								: m_renderCtx	(renderCtx)
69								, m_testCtx		(testCtx) {}
70	const RenderContext&	getRenderContext	(void) const { return m_renderCtx; }
71	TestContext&			getTestContext		(void) const { return m_testCtx; }
72	const Functions&		gl					(void) const { return m_renderCtx.getFunctions(); }
73	TestLog&				log					(void) const { return m_testCtx.getLog(); }
74
75private:
76	const RenderContext&	m_renderCtx;
77	TestContext&			m_testCtx;
78};
79
80class ContextWrapper : public CallLogWrapper
81{
82public:
83	const Context&			getContext			(void) const { return m_ctx; }
84	const RenderContext&	getRenderContext	(void) const { return m_ctx.getRenderContext(); }
85	TestContext&			getTestContext		(void) const { return m_ctx.getTestContext(); }
86	const Functions&		gl					(void) const { return m_ctx.gl(); }
87	TestLog&				log					(void) const { return m_ctx.log(); }
88	void					enableLogging		(bool enable)
89	{
90		CallLogWrapper::enableLogging(enable);
91	}
92
93protected:
94							ContextWrapper				(const Context& ctx);
95	const Context			m_ctx;
96};
97
98class Binder : public ContextWrapper
99{
100public:
101	virtual				~Binder			(void) {}
102	virtual void		bind			(GLuint name) = 0;
103	virtual GLuint		getBinding		(void) = 0;
104	virtual bool		genRequired		(void) const { return true; }
105
106protected:
107						Binder			(const Context& ctx) : ContextWrapper(ctx) {}
108};
109
110class SimpleBinder : public Binder
111{
112public:
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);
126	bool				genRequired		(void) const { return m_genRequired; }
127
128private:
129	const BindFunc		m_bindFunc;
130	const GLenum		m_bindTarget;
131	const GLenum		m_bindingParam;
132	const bool			m_genRequired;
133};
134
135class Type : public ContextWrapper
136{
137public:
138	virtual					~Type			(void) {}
139	virtual GLuint			gen				(void) = 0;
140	virtual void			release			(GLuint name) = 0;
141	virtual bool			exists			(GLuint name) = 0;
142	virtual bool			isDeleteFlagged	(GLuint name) { DE_UNREF(name); return false; }
143	virtual Binder*			binder			(void) const { return DE_NULL; }
144	virtual const char*		getName			(void) const = 0;
145	virtual bool			nameLingers		(void) const { return false; }
146	virtual bool			genCreates		(void) const { return false; }
147
148protected:
149							Type			(const Context& ctx) : ContextWrapper(ctx) {}
150};
151
152class SimpleType : public Type
153{
154public:
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);
167	void			release		(GLuint name)		{ (this->*m_deleteFunc)(1, &name); }
168	bool			exists		(GLuint name)		{ return (this->*m_existsFunc)(name) != GL_FALSE; }
169	Binder*			binder		(void) const		{ return m_binder; }
170	const char*		getName		(void) const		{ return m_getName; }
171	bool			nameLingers	(void) const		{ return false; }
172	bool			genCreates	(void) const		{ return m_genCreates; }
173
174private:
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
183class ProgramType : public Type
184{
185public:
186					ProgramType		(const Context& ctx) : Type(ctx) {}
187	bool			nameLingers		(void) const	{ return true; }
188	bool			genCreates		(void) const	{ return true; }
189	const char*		getName			(void) const	{ return "program"; }
190	GLuint			gen				(void)			{ return glCreateProgram(); }
191	void			release			(GLuint name)	{ glDeleteProgram(name); }
192	bool			exists			(GLuint name)	{ return glIsProgram(name) != GL_FALSE; }
193	bool			isDeleteFlagged	(GLuint name);
194};
195
196class ShaderType : public Type
197{
198public:
199					ShaderType		(const Context& ctx) : Type(ctx) {}
200	bool			nameLingers		(void) const { return true; }
201	bool			genCreates		(void) const { return true; }
202	const char*		getName			(void) const { return "shader"; }
203	GLuint			gen				(void) { return glCreateShader(GL_FRAGMENT_SHADER); }
204	void			release			(GLuint name) { glDeleteShader(name); }
205	bool			exists			(GLuint name) { return glIsShader(name) != GL_FALSE; }
206	bool			isDeleteFlagged	(GLuint name);
207};
208
209class Attacher : public ContextWrapper
210{
211public:
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;
216	virtual bool		canAttachDeleted		(void) const { return true; }
217
218	Type&				getElementType			(void) const { return m_elementType; }
219	Type&				getContainerType		(void) const { return m_containerType; }
220	virtual				~Attacher				(void) {}
221
222protected:
223						Attacher				(const Context& ctx,
224												 Type& elementType, Type& containerType)
225							: ContextWrapper	(ctx)
226							, m_elementType		(elementType)
227							, m_containerType	(containerType) {}
228
229private:
230	Type&				m_elementType;
231	Type&				m_containerType;
232};
233
234class InputAttacher : public ContextWrapper
235{
236public:
237	Attacher&			getAttacher				(void) const { return m_attacher; }
238	virtual void		drawContainer			(GLuint container, Surface& dst) = 0;
239protected:
240						InputAttacher			(Attacher& attacher)
241							: ContextWrapper	(attacher.getContext())
242							, m_attacher		(attacher) {}
243	Attacher&			m_attacher;
244};
245
246class OutputAttacher : public ContextWrapper
247{
248public:
249	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;
252protected:
253						OutputAttacher			(Attacher& attacher)
254							: ContextWrapper	(attacher.getContext())
255							, m_attacher		(attacher) {}
256	Attacher&			m_attacher;
257};
258
259class Types : public ContextWrapper
260{
261public:
262									Types				(const Context& ctx)
263										: ContextWrapper(ctx) {}
264	virtual Type&					getProgramType		(void) = 0;
265	const vector<Type*>&			getTypes			(void) { return m_types; }
266	const vector<Attacher*>&		getAttachers		(void) { return m_attachers; }
267	const vector<InputAttacher*>&	getInputAttachers	(void) { return m_inAttachers; }
268	const vector<OutputAttacher*>&	getOutputAttachers	(void) { return m_outAttachers; }
269	virtual							~Types				(void) {}
270
271protected:
272	vector<Type*>					m_types;
273	vector<Attacher*>				m_attachers;
274	vector<InputAttacher*>			m_inAttachers;
275	vector<OutputAttacher*>			m_outAttachers;
276};
277
278class FboAttacher : public Attacher
279{
280public:
281	void			initAttachment		(GLuint seed, GLuint element);
282
283protected:
284					FboAttacher			(const Context& ctx,
285										 Type& elementType, Type& containerType)
286						: Attacher 		(ctx, elementType, containerType) {}
287	virtual void	initStorage			(void) = 0;
288};
289
290class FboInputAttacher : public InputAttacher
291{
292public:
293			FboInputAttacher		(FboAttacher& attacher)
294				: InputAttacher 	(attacher) {}
295	void	drawContainer			(GLuint container, Surface& dst);
296};
297
298class FboOutputAttacher : public OutputAttacher
299{
300public:
301			FboOutputAttacher			(FboAttacher& attacher)
302				: OutputAttacher 		(attacher) {}
303	void	setupContainer				(GLuint seed, GLuint container);
304	void	drawAttachment				(GLuint attachment, Surface& dst);
305};
306
307class TextureFboAttacher : public FboAttacher
308{
309public:
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
319class RboFboAttacher : public FboAttacher
320{
321public:
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
331class ShaderProgramAttacher : public Attacher
332{
333public:
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
344class ShaderProgramInputAttacher : public InputAttacher
345{
346public:
347			ShaderProgramInputAttacher	(Attacher& attacher)
348				: InputAttacher			(attacher) {}
349
350	void	drawContainer				(GLuint container, Surface& dst);
351};
352
353class ES2Types : public Types
354{
355public:
356								ES2Types		(const Context& ctx);
357	Type&						getProgramType	(void) { return m_programType; }
358
359protected:
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
380MovePtr<TestCaseGroup>	createGroup		(TestContext& testCtx, Type& type);
381void					addTestCases	(TestCaseGroup& group, Types& types);
382
383struct Rectangle
384{
385			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
396Rectangle	randomViewport	(const RenderContext& ctx, GLint maxWidth, GLint maxHeight,
397							 Random& rnd);
398void		setViewport		(const RenderContext& renderCtx, const Rectangle& rect);
399void		readRectangle	(const RenderContext& renderCtx, const Rectangle& rect,
400							 Surface& dst);
401
402} // details
403
404using details::BindFunc;
405using details::GenFunc;
406using details::DeleteFunc;
407using details::ExistsFunc;
408
409using details::Context;
410using details::Binder;
411using details::SimpleBinder;
412using details::Type;
413using details::SimpleType;
414using details::Attacher;
415using details::InputAttacher;
416using details::OutputAttacher;
417using details::Types;
418using details::ES2Types;
419
420using details::createGroup;
421using details::addTestCases;
422
423using details::Rectangle;
424using details::randomViewport;
425using details::setViewport;
426using details::readRectangle;
427
428} // LifetimeTests
429} // gls
430} // deqp
431
432#endif // _GLSLIFETIMETESTS_HPP
433