1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker * drawElements Quality Program OpenGL (ES) Module
3*35238bceSAndroid Build Coastguard Worker * -----------------------------------------------
4*35238bceSAndroid Build Coastguard Worker *
5*35238bceSAndroid Build Coastguard Worker * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker *
7*35238bceSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker *
11*35238bceSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker *
13*35238bceSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker *
19*35238bceSAndroid Build Coastguard Worker *//*!
20*35238bceSAndroid Build Coastguard Worker * \file
21*35238bceSAndroid Build Coastguard Worker * \brief Common object lifetime tests.
22*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker
24*35238bceSAndroid Build Coastguard Worker #include "glsLifetimeTests.hpp"
25*35238bceSAndroid Build Coastguard Worker
26*35238bceSAndroid Build Coastguard Worker #include "deString.h"
27*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "deSTLUtil.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "tcuRGBA.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "tcuImageCompare.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "tcuRenderTarget.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "tcuStringTemplate.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "gluDrawUtil.hpp"
36*35238bceSAndroid Build Coastguard Worker #include "gluObjectWrapper.hpp"
37*35238bceSAndroid Build Coastguard Worker #include "gluPixelTransfer.hpp"
38*35238bceSAndroid Build Coastguard Worker #include "gluShaderProgram.hpp"
39*35238bceSAndroid Build Coastguard Worker #include "gluDefs.hpp"
40*35238bceSAndroid Build Coastguard Worker #include "gluTextureUtil.hpp"
41*35238bceSAndroid Build Coastguard Worker #include "gluStrUtil.hpp"
42*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
43*35238bceSAndroid Build Coastguard Worker
44*35238bceSAndroid Build Coastguard Worker #include <vector>
45*35238bceSAndroid Build Coastguard Worker #include <map>
46*35238bceSAndroid Build Coastguard Worker #include <algorithm>
47*35238bceSAndroid Build Coastguard Worker #include <sstream>
48*35238bceSAndroid Build Coastguard Worker
49*35238bceSAndroid Build Coastguard Worker namespace deqp
50*35238bceSAndroid Build Coastguard Worker {
51*35238bceSAndroid Build Coastguard Worker namespace gls
52*35238bceSAndroid Build Coastguard Worker {
53*35238bceSAndroid Build Coastguard Worker namespace LifetimeTests
54*35238bceSAndroid Build Coastguard Worker {
55*35238bceSAndroid Build Coastguard Worker namespace details
56*35238bceSAndroid Build Coastguard Worker {
57*35238bceSAndroid Build Coastguard Worker
58*35238bceSAndroid Build Coastguard Worker using de::Random;
59*35238bceSAndroid Build Coastguard Worker using std::map;
60*35238bceSAndroid Build Coastguard Worker using std::ostringstream;
61*35238bceSAndroid Build Coastguard Worker using std::string;
62*35238bceSAndroid Build Coastguard Worker using tcu::RenderTarget;
63*35238bceSAndroid Build Coastguard Worker using tcu::RGBA;
64*35238bceSAndroid Build Coastguard Worker using tcu::StringTemplate;
65*35238bceSAndroid Build Coastguard Worker using tcu::TestCase;
66*35238bceSAndroid Build Coastguard Worker typedef TestCase::IterateResult IterateResult;
67*35238bceSAndroid Build Coastguard Worker using glu::Framebuffer;
68*35238bceSAndroid Build Coastguard Worker using glu::Program;
69*35238bceSAndroid Build Coastguard Worker using glu::Shader;
70*35238bceSAndroid Build Coastguard Worker using glu::SHADERTYPE_FRAGMENT;
71*35238bceSAndroid Build Coastguard Worker using glu::SHADERTYPE_VERTEX;
72*35238bceSAndroid Build Coastguard Worker using tcu::ScopedLogSection;
73*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
74*35238bceSAndroid Build Coastguard Worker using namespace glw;
75*35238bceSAndroid Build Coastguard Worker
76*35238bceSAndroid Build Coastguard Worker enum
77*35238bceSAndroid Build Coastguard Worker {
78*35238bceSAndroid Build Coastguard Worker VIEWPORT_SIZE = 128,
79*35238bceSAndroid Build Coastguard Worker FRAMEBUFFER_SIZE = 128
80*35238bceSAndroid Build Coastguard Worker };
81*35238bceSAndroid Build Coastguard Worker
getInteger(ContextWrapper & gl,GLenum queryParam)82*35238bceSAndroid Build Coastguard Worker GLint getInteger(ContextWrapper &gl, GLenum queryParam)
83*35238bceSAndroid Build Coastguard Worker {
84*35238bceSAndroid Build Coastguard Worker GLint ret = 0;
85*35238bceSAndroid Build Coastguard Worker GLU_CHECK_CALL_ERROR(gl.glGetIntegerv(queryParam, &ret), gl.glGetError());
86*35238bceSAndroid Build Coastguard Worker gl.log() << TestLog::Message << "// Single integer output: " << ret << TestLog::EndMessage;
87*35238bceSAndroid Build Coastguard Worker return ret;
88*35238bceSAndroid Build Coastguard Worker }
89*35238bceSAndroid Build Coastguard Worker
90*35238bceSAndroid Build Coastguard Worker #define GLSL100_SRC(BODY) ("#version 100\n" #BODY "\n")
91*35238bceSAndroid Build Coastguard Worker
92*35238bceSAndroid Build Coastguard Worker static const char *const s_vertexShaderSrc =
93*35238bceSAndroid Build Coastguard Worker GLSL100_SRC(attribute vec2 pos; void main() { gl_Position = vec4(pos.xy, 0.0, 1.0); });
94*35238bceSAndroid Build Coastguard Worker
95*35238bceSAndroid Build Coastguard Worker static const char *const s_fragmentShaderSrc = GLSL100_SRC(void main() { gl_FragColor = vec4(1.0); });
96*35238bceSAndroid Build Coastguard Worker
97*35238bceSAndroid Build Coastguard Worker class CheckedShader : public Shader
98*35238bceSAndroid Build Coastguard Worker {
99*35238bceSAndroid Build Coastguard Worker public:
CheckedShader(const RenderContext & renderCtx,glu::ShaderType type,const string & src)100*35238bceSAndroid Build Coastguard Worker CheckedShader(const RenderContext &renderCtx, glu::ShaderType type, const string &src) : Shader(renderCtx, type)
101*35238bceSAndroid Build Coastguard Worker {
102*35238bceSAndroid Build Coastguard Worker const char *const srcStr = src.c_str();
103*35238bceSAndroid Build Coastguard Worker setSources(1, &srcStr, DE_NULL);
104*35238bceSAndroid Build Coastguard Worker compile();
105*35238bceSAndroid Build Coastguard Worker TCU_CHECK(getCompileStatus());
106*35238bceSAndroid Build Coastguard Worker }
107*35238bceSAndroid Build Coastguard Worker };
108*35238bceSAndroid Build Coastguard Worker
109*35238bceSAndroid Build Coastguard Worker class CheckedProgram : public Program
110*35238bceSAndroid Build Coastguard Worker {
111*35238bceSAndroid Build Coastguard Worker public:
CheckedProgram(const RenderContext & renderCtx,GLuint vtxShader,GLuint fragShader)112*35238bceSAndroid Build Coastguard Worker CheckedProgram(const RenderContext &renderCtx, GLuint vtxShader, GLuint fragShader) : Program(renderCtx)
113*35238bceSAndroid Build Coastguard Worker {
114*35238bceSAndroid Build Coastguard Worker attachShader(vtxShader);
115*35238bceSAndroid Build Coastguard Worker attachShader(fragShader);
116*35238bceSAndroid Build Coastguard Worker link();
117*35238bceSAndroid Build Coastguard Worker TCU_CHECK(getLinkStatus());
118*35238bceSAndroid Build Coastguard Worker }
119*35238bceSAndroid Build Coastguard Worker };
120*35238bceSAndroid Build Coastguard Worker
ContextWrapper(const Context & ctx)121*35238bceSAndroid Build Coastguard Worker ContextWrapper::ContextWrapper(const Context &ctx) : CallLogWrapper(ctx.gl(), ctx.log()), m_ctx(ctx)
122*35238bceSAndroid Build Coastguard Worker {
123*35238bceSAndroid Build Coastguard Worker enableLogging(true);
124*35238bceSAndroid Build Coastguard Worker }
125*35238bceSAndroid Build Coastguard Worker
bind(GLuint name)126*35238bceSAndroid Build Coastguard Worker void SimpleBinder::bind(GLuint name)
127*35238bceSAndroid Build Coastguard Worker {
128*35238bceSAndroid Build Coastguard Worker (this->*m_bindFunc)(m_bindTarget, name);
129*35238bceSAndroid Build Coastguard Worker }
130*35238bceSAndroid Build Coastguard Worker
getBinding(void)131*35238bceSAndroid Build Coastguard Worker GLuint SimpleBinder::getBinding(void)
132*35238bceSAndroid Build Coastguard Worker {
133*35238bceSAndroid Build Coastguard Worker return getInteger(*this, m_bindingParam);
134*35238bceSAndroid Build Coastguard Worker }
135*35238bceSAndroid Build Coastguard Worker
gen(void)136*35238bceSAndroid Build Coastguard Worker GLuint SimpleType::gen(void)
137*35238bceSAndroid Build Coastguard Worker {
138*35238bceSAndroid Build Coastguard Worker GLuint ret;
139*35238bceSAndroid Build Coastguard Worker (this->*m_genFunc)(1, &ret);
140*35238bceSAndroid Build Coastguard Worker return ret;
141*35238bceSAndroid Build Coastguard Worker }
142*35238bceSAndroid Build Coastguard Worker
143*35238bceSAndroid Build Coastguard Worker class VertexArrayBinder : public SimpleBinder
144*35238bceSAndroid Build Coastguard Worker {
145*35238bceSAndroid Build Coastguard Worker public:
VertexArrayBinder(Context & ctx)146*35238bceSAndroid Build Coastguard Worker VertexArrayBinder(Context &ctx) : SimpleBinder(ctx, 0, GL_NONE, GL_VERTEX_ARRAY_BINDING, true)
147*35238bceSAndroid Build Coastguard Worker {
148*35238bceSAndroid Build Coastguard Worker }
bind(GLuint name)149*35238bceSAndroid Build Coastguard Worker void bind(GLuint name)
150*35238bceSAndroid Build Coastguard Worker {
151*35238bceSAndroid Build Coastguard Worker glBindVertexArray(name);
152*35238bceSAndroid Build Coastguard Worker }
153*35238bceSAndroid Build Coastguard Worker };
154*35238bceSAndroid Build Coastguard Worker
155*35238bceSAndroid Build Coastguard Worker class QueryBinder : public Binder
156*35238bceSAndroid Build Coastguard Worker {
157*35238bceSAndroid Build Coastguard Worker public:
QueryBinder(Context & ctx)158*35238bceSAndroid Build Coastguard Worker QueryBinder(Context &ctx) : Binder(ctx)
159*35238bceSAndroid Build Coastguard Worker {
160*35238bceSAndroid Build Coastguard Worker }
bind(GLuint name)161*35238bceSAndroid Build Coastguard Worker void bind(GLuint name)
162*35238bceSAndroid Build Coastguard Worker {
163*35238bceSAndroid Build Coastguard Worker if (name != 0)
164*35238bceSAndroid Build Coastguard Worker glBeginQuery(GL_ANY_SAMPLES_PASSED, name);
165*35238bceSAndroid Build Coastguard Worker else
166*35238bceSAndroid Build Coastguard Worker glEndQuery(GL_ANY_SAMPLES_PASSED);
167*35238bceSAndroid Build Coastguard Worker }
getBinding(void)168*35238bceSAndroid Build Coastguard Worker GLuint getBinding(void)
169*35238bceSAndroid Build Coastguard Worker {
170*35238bceSAndroid Build Coastguard Worker return 0;
171*35238bceSAndroid Build Coastguard Worker }
172*35238bceSAndroid Build Coastguard Worker };
173*35238bceSAndroid Build Coastguard Worker
isDeleteFlagged(GLuint name)174*35238bceSAndroid Build Coastguard Worker bool ProgramType::isDeleteFlagged(GLuint name)
175*35238bceSAndroid Build Coastguard Worker {
176*35238bceSAndroid Build Coastguard Worker GLint deleteFlagged = 0;
177*35238bceSAndroid Build Coastguard Worker glGetProgramiv(name, GL_DELETE_STATUS, &deleteFlagged);
178*35238bceSAndroid Build Coastguard Worker return deleteFlagged != 0;
179*35238bceSAndroid Build Coastguard Worker }
180*35238bceSAndroid Build Coastguard Worker
isDeleteFlagged(GLuint name)181*35238bceSAndroid Build Coastguard Worker bool ShaderType::isDeleteFlagged(GLuint name)
182*35238bceSAndroid Build Coastguard Worker {
183*35238bceSAndroid Build Coastguard Worker GLint deleteFlagged = 0;
184*35238bceSAndroid Build Coastguard Worker glGetShaderiv(name, GL_DELETE_STATUS, &deleteFlagged);
185*35238bceSAndroid Build Coastguard Worker return deleteFlagged != 0;
186*35238bceSAndroid Build Coastguard Worker }
187*35238bceSAndroid Build Coastguard Worker
setupFbo(const Context & ctx,GLuint seed,GLuint fbo)188*35238bceSAndroid Build Coastguard Worker void setupFbo(const Context &ctx, GLuint seed, GLuint fbo)
189*35238bceSAndroid Build Coastguard Worker {
190*35238bceSAndroid Build Coastguard Worker const Functions &gl = ctx.getRenderContext().getFunctions();
191*35238bceSAndroid Build Coastguard Worker
192*35238bceSAndroid Build Coastguard Worker GLU_CHECK_CALL_ERROR(gl.bindFramebuffer(GL_FRAMEBUFFER, fbo), gl.getError());
193*35238bceSAndroid Build Coastguard Worker
194*35238bceSAndroid Build Coastguard Worker if (seed == 0)
195*35238bceSAndroid Build Coastguard Worker {
196*35238bceSAndroid Build Coastguard Worker gl.clearColor(0.0, 0.0, 0.0, 1.0);
197*35238bceSAndroid Build Coastguard Worker GLU_CHECK_CALL_ERROR(gl.clear(GL_COLOR_BUFFER_BIT), gl.getError());
198*35238bceSAndroid Build Coastguard Worker }
199*35238bceSAndroid Build Coastguard Worker else
200*35238bceSAndroid Build Coastguard Worker {
201*35238bceSAndroid Build Coastguard Worker Random rnd(seed);
202*35238bceSAndroid Build Coastguard Worker const GLsizei width = rnd.getInt(0, FRAMEBUFFER_SIZE);
203*35238bceSAndroid Build Coastguard Worker const GLsizei height = rnd.getInt(0, FRAMEBUFFER_SIZE);
204*35238bceSAndroid Build Coastguard Worker const GLint x = rnd.getInt(0, FRAMEBUFFER_SIZE - width);
205*35238bceSAndroid Build Coastguard Worker const GLint y = rnd.getInt(0, FRAMEBUFFER_SIZE - height);
206*35238bceSAndroid Build Coastguard Worker const GLfloat r1 = rnd.getFloat();
207*35238bceSAndroid Build Coastguard Worker const GLfloat g1 = rnd.getFloat();
208*35238bceSAndroid Build Coastguard Worker const GLfloat b1 = rnd.getFloat();
209*35238bceSAndroid Build Coastguard Worker const GLfloat a1 = rnd.getFloat();
210*35238bceSAndroid Build Coastguard Worker const GLfloat r2 = rnd.getFloat();
211*35238bceSAndroid Build Coastguard Worker const GLfloat g2 = rnd.getFloat();
212*35238bceSAndroid Build Coastguard Worker const GLfloat b2 = rnd.getFloat();
213*35238bceSAndroid Build Coastguard Worker const GLfloat a2 = rnd.getFloat();
214*35238bceSAndroid Build Coastguard Worker
215*35238bceSAndroid Build Coastguard Worker GLU_CHECK_CALL_ERROR(gl.clearColor(r1, g1, b1, a1), gl.getError());
216*35238bceSAndroid Build Coastguard Worker GLU_CHECK_CALL_ERROR(gl.clear(GL_COLOR_BUFFER_BIT), gl.getError());
217*35238bceSAndroid Build Coastguard Worker gl.scissor(x, y, width, height);
218*35238bceSAndroid Build Coastguard Worker gl.enable(GL_SCISSOR_TEST);
219*35238bceSAndroid Build Coastguard Worker gl.clearColor(r2, g2, b2, a2);
220*35238bceSAndroid Build Coastguard Worker gl.clear(GL_COLOR_BUFFER_BIT);
221*35238bceSAndroid Build Coastguard Worker gl.disable(GL_SCISSOR_TEST);
222*35238bceSAndroid Build Coastguard Worker }
223*35238bceSAndroid Build Coastguard Worker
224*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
225*35238bceSAndroid Build Coastguard Worker GLU_CHECK_ERROR(gl.getError());
226*35238bceSAndroid Build Coastguard Worker }
227*35238bceSAndroid Build Coastguard Worker
drawFbo(const Context & ctx,GLuint fbo,Surface & dst)228*35238bceSAndroid Build Coastguard Worker void drawFbo(const Context &ctx, GLuint fbo, Surface &dst)
229*35238bceSAndroid Build Coastguard Worker {
230*35238bceSAndroid Build Coastguard Worker const RenderContext &renderCtx = ctx.getRenderContext();
231*35238bceSAndroid Build Coastguard Worker const Functions &gl = renderCtx.getFunctions();
232*35238bceSAndroid Build Coastguard Worker
233*35238bceSAndroid Build Coastguard Worker GLU_CHECK_CALL_ERROR(gl.bindFramebuffer(GL_FRAMEBUFFER, fbo), gl.getError());
234*35238bceSAndroid Build Coastguard Worker
235*35238bceSAndroid Build Coastguard Worker dst.setSize(FRAMEBUFFER_SIZE, FRAMEBUFFER_SIZE);
236*35238bceSAndroid Build Coastguard Worker glu::readPixels(renderCtx, 0, 0, dst.getAccess());
237*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Read pixels from framebuffer");
238*35238bceSAndroid Build Coastguard Worker
239*35238bceSAndroid Build Coastguard Worker GLU_CHECK_CALL_ERROR(gl.bindFramebuffer(GL_FRAMEBUFFER, 0), gl.getError());
240*35238bceSAndroid Build Coastguard Worker }
241*35238bceSAndroid Build Coastguard Worker
getFboAttachment(const Functions & gl,GLuint fbo,GLenum requiredType)242*35238bceSAndroid Build Coastguard Worker GLuint getFboAttachment(const Functions &gl, GLuint fbo, GLenum requiredType)
243*35238bceSAndroid Build Coastguard Worker {
244*35238bceSAndroid Build Coastguard Worker GLint type = 0, name = 0;
245*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
246*35238bceSAndroid Build Coastguard Worker GLU_CHECK_CALL_ERROR(gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
247*35238bceSAndroid Build Coastguard Worker GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &type),
248*35238bceSAndroid Build Coastguard Worker gl.getError());
249*35238bceSAndroid Build Coastguard Worker
250*35238bceSAndroid Build Coastguard Worker if (GLenum(type) != requiredType || GLenum(type) == GL_NONE)
251*35238bceSAndroid Build Coastguard Worker return 0;
252*35238bceSAndroid Build Coastguard Worker
253*35238bceSAndroid Build Coastguard Worker GLU_CHECK_CALL_ERROR(gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
254*35238bceSAndroid Build Coastguard Worker GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &name),
255*35238bceSAndroid Build Coastguard Worker gl.getError());
256*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
257*35238bceSAndroid Build Coastguard Worker GLU_CHECK_ERROR(gl.getError());
258*35238bceSAndroid Build Coastguard Worker
259*35238bceSAndroid Build Coastguard Worker return name;
260*35238bceSAndroid Build Coastguard Worker }
261*35238bceSAndroid Build Coastguard Worker
initAttachment(GLuint seed,GLuint element)262*35238bceSAndroid Build Coastguard Worker void FboAttacher::initAttachment(GLuint seed, GLuint element)
263*35238bceSAndroid Build Coastguard Worker {
264*35238bceSAndroid Build Coastguard Worker Binder &binder = *getElementType().binder();
265*35238bceSAndroid Build Coastguard Worker Framebuffer fbo(getRenderContext());
266*35238bceSAndroid Build Coastguard Worker
267*35238bceSAndroid Build Coastguard Worker enableLogging(false);
268*35238bceSAndroid Build Coastguard Worker
269*35238bceSAndroid Build Coastguard Worker binder.enableLogging(false);
270*35238bceSAndroid Build Coastguard Worker binder.bind(element);
271*35238bceSAndroid Build Coastguard Worker initStorage();
272*35238bceSAndroid Build Coastguard Worker binder.bind(0);
273*35238bceSAndroid Build Coastguard Worker binder.enableLogging(true);
274*35238bceSAndroid Build Coastguard Worker
275*35238bceSAndroid Build Coastguard Worker attach(element, *fbo);
276*35238bceSAndroid Build Coastguard Worker setupFbo(getContext(), seed, *fbo);
277*35238bceSAndroid Build Coastguard Worker detach(element, *fbo);
278*35238bceSAndroid Build Coastguard Worker
279*35238bceSAndroid Build Coastguard Worker enableLogging(true);
280*35238bceSAndroid Build Coastguard Worker
281*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "// Drew to " << getElementType().getName() << " " << element << " with seed " << seed
282*35238bceSAndroid Build Coastguard Worker << "." << TestLog::EndMessage;
283*35238bceSAndroid Build Coastguard Worker }
284*35238bceSAndroid Build Coastguard Worker
drawContainer(GLuint fbo,Surface & dst)285*35238bceSAndroid Build Coastguard Worker void FboInputAttacher::drawContainer(GLuint fbo, Surface &dst)
286*35238bceSAndroid Build Coastguard Worker {
287*35238bceSAndroid Build Coastguard Worker drawFbo(getContext(), fbo, dst);
288*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "// Read pixels from framebuffer " << fbo << " to output image."
289*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
290*35238bceSAndroid Build Coastguard Worker }
291*35238bceSAndroid Build Coastguard Worker
setupContainer(GLuint seed,GLuint fbo)292*35238bceSAndroid Build Coastguard Worker void FboOutputAttacher::setupContainer(GLuint seed, GLuint fbo)
293*35238bceSAndroid Build Coastguard Worker {
294*35238bceSAndroid Build Coastguard Worker setupFbo(getContext(), seed, fbo);
295*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "// Drew to framebuffer " << fbo << " with seed " << seed << "."
296*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
297*35238bceSAndroid Build Coastguard Worker }
298*35238bceSAndroid Build Coastguard Worker
drawAttachment(GLuint element,Surface & dst)299*35238bceSAndroid Build Coastguard Worker void FboOutputAttacher::drawAttachment(GLuint element, Surface &dst)
300*35238bceSAndroid Build Coastguard Worker {
301*35238bceSAndroid Build Coastguard Worker Framebuffer fbo(getRenderContext());
302*35238bceSAndroid Build Coastguard Worker m_attacher.enableLogging(false);
303*35238bceSAndroid Build Coastguard Worker m_attacher.attach(element, *fbo);
304*35238bceSAndroid Build Coastguard Worker drawFbo(getContext(), *fbo, dst);
305*35238bceSAndroid Build Coastguard Worker m_attacher.detach(element, *fbo);
306*35238bceSAndroid Build Coastguard Worker m_attacher.enableLogging(true);
307*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "// Read pixels from " << m_attacher.getElementType().getName() << " " << element
308*35238bceSAndroid Build Coastguard Worker << " to output image." << TestLog::EndMessage;
309*35238bceSAndroid Build Coastguard Worker GLU_CHECK_ERROR(gl().getError());
310*35238bceSAndroid Build Coastguard Worker }
311*35238bceSAndroid Build Coastguard Worker
attach(GLuint texture,GLuint fbo)312*35238bceSAndroid Build Coastguard Worker void TextureFboAttacher::attach(GLuint texture, GLuint fbo)
313*35238bceSAndroid Build Coastguard Worker {
314*35238bceSAndroid Build Coastguard Worker GLU_CHECK_CALL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, fbo), gl().getError());
315*35238bceSAndroid Build Coastguard Worker GLU_CHECK_CALL_ERROR(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0),
316*35238bceSAndroid Build Coastguard Worker gl().getError());
317*35238bceSAndroid Build Coastguard Worker GLU_CHECK_CALL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, 0), gl().getError());
318*35238bceSAndroid Build Coastguard Worker }
319*35238bceSAndroid Build Coastguard Worker
detach(GLuint texture,GLuint fbo)320*35238bceSAndroid Build Coastguard Worker void TextureFboAttacher::detach(GLuint texture, GLuint fbo)
321*35238bceSAndroid Build Coastguard Worker {
322*35238bceSAndroid Build Coastguard Worker DE_UNREF(texture);
323*35238bceSAndroid Build Coastguard Worker GLU_CHECK_CALL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, fbo), gl().getError());
324*35238bceSAndroid Build Coastguard Worker GLU_CHECK_CALL_ERROR(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0),
325*35238bceSAndroid Build Coastguard Worker gl().getError());
326*35238bceSAndroid Build Coastguard Worker GLU_CHECK_CALL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, 0), gl().getError());
327*35238bceSAndroid Build Coastguard Worker }
328*35238bceSAndroid Build Coastguard Worker
getAttachment(GLuint fbo)329*35238bceSAndroid Build Coastguard Worker GLuint TextureFboAttacher::getAttachment(GLuint fbo)
330*35238bceSAndroid Build Coastguard Worker {
331*35238bceSAndroid Build Coastguard Worker return getFboAttachment(gl(), fbo, GL_TEXTURE);
332*35238bceSAndroid Build Coastguard Worker }
333*35238bceSAndroid Build Coastguard Worker
isTextureFormatColorRenderable(const glu::RenderContext & renderCtx,const glu::TransferFormat & format)334*35238bceSAndroid Build Coastguard Worker static bool isTextureFormatColorRenderable(const glu::RenderContext &renderCtx, const glu::TransferFormat &format)
335*35238bceSAndroid Build Coastguard Worker {
336*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = renderCtx.getFunctions();
337*35238bceSAndroid Build Coastguard Worker uint32_t curFbo = ~0u;
338*35238bceSAndroid Build Coastguard Worker uint32_t curTex = ~0u;
339*35238bceSAndroid Build Coastguard Worker uint32_t testFbo = 0u;
340*35238bceSAndroid Build Coastguard Worker uint32_t testTex = 0u;
341*35238bceSAndroid Build Coastguard Worker GLenum status = GL_NONE;
342*35238bceSAndroid Build Coastguard Worker
343*35238bceSAndroid Build Coastguard Worker GLU_CHECK_GLW_CALL(gl, getIntegerv(GL_FRAMEBUFFER_BINDING, (int32_t *)&curFbo));
344*35238bceSAndroid Build Coastguard Worker GLU_CHECK_GLW_CALL(gl, getIntegerv(GL_TEXTURE_BINDING_2D, (int32_t *)&curTex));
345*35238bceSAndroid Build Coastguard Worker
346*35238bceSAndroid Build Coastguard Worker try
347*35238bceSAndroid Build Coastguard Worker {
348*35238bceSAndroid Build Coastguard Worker GLU_CHECK_GLW_CALL(gl, genTextures(1, &testTex));
349*35238bceSAndroid Build Coastguard Worker GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, testTex));
350*35238bceSAndroid Build Coastguard Worker GLU_CHECK_GLW_CALL(gl, texImage2D(GL_TEXTURE_2D, 0, format.format, FRAMEBUFFER_SIZE, FRAMEBUFFER_SIZE, 0,
351*35238bceSAndroid Build Coastguard Worker format.format, format.dataType, DE_NULL));
352*35238bceSAndroid Build Coastguard Worker
353*35238bceSAndroid Build Coastguard Worker GLU_CHECK_GLW_CALL(gl, genFramebuffers(1, &testFbo));
354*35238bceSAndroid Build Coastguard Worker GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, testFbo));
355*35238bceSAndroid Build Coastguard Worker GLU_CHECK_GLW_CALL(gl, framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, testTex, 0));
356*35238bceSAndroid Build Coastguard Worker
357*35238bceSAndroid Build Coastguard Worker status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
358*35238bceSAndroid Build Coastguard Worker GLU_CHECK_GLW_MSG(gl, "glCheckFramebufferStatus(GL_FRAMEBUFFER)");
359*35238bceSAndroid Build Coastguard Worker
360*35238bceSAndroid Build Coastguard Worker GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, curTex));
361*35238bceSAndroid Build Coastguard Worker GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, curFbo));
362*35238bceSAndroid Build Coastguard Worker
363*35238bceSAndroid Build Coastguard Worker GLU_CHECK_GLW_CALL(gl, deleteTextures(1, &testTex));
364*35238bceSAndroid Build Coastguard Worker GLU_CHECK_GLW_CALL(gl, deleteFramebuffers(1, &testFbo));
365*35238bceSAndroid Build Coastguard Worker }
366*35238bceSAndroid Build Coastguard Worker catch (...)
367*35238bceSAndroid Build Coastguard Worker {
368*35238bceSAndroid Build Coastguard Worker if (testTex != 0)
369*35238bceSAndroid Build Coastguard Worker gl.deleteTextures(1, &testTex);
370*35238bceSAndroid Build Coastguard Worker
371*35238bceSAndroid Build Coastguard Worker if (testFbo != 0)
372*35238bceSAndroid Build Coastguard Worker gl.deleteFramebuffers(1, &testFbo);
373*35238bceSAndroid Build Coastguard Worker
374*35238bceSAndroid Build Coastguard Worker throw;
375*35238bceSAndroid Build Coastguard Worker }
376*35238bceSAndroid Build Coastguard Worker
377*35238bceSAndroid Build Coastguard Worker if (status == GL_FRAMEBUFFER_COMPLETE)
378*35238bceSAndroid Build Coastguard Worker return true;
379*35238bceSAndroid Build Coastguard Worker else if (status == GL_FRAMEBUFFER_UNSUPPORTED)
380*35238bceSAndroid Build Coastguard Worker return false;
381*35238bceSAndroid Build Coastguard Worker else
382*35238bceSAndroid Build Coastguard Worker TCU_THROW(TestError, (std::string("glCheckFramebufferStatus() returned invalid result code ") +
383*35238bceSAndroid Build Coastguard Worker de::toString(glu::getFramebufferStatusStr(status)))
384*35238bceSAndroid Build Coastguard Worker .c_str());
385*35238bceSAndroid Build Coastguard Worker }
386*35238bceSAndroid Build Coastguard Worker
getRenderableColorTextureFormat(const glu::RenderContext & renderCtx)387*35238bceSAndroid Build Coastguard Worker static glu::TransferFormat getRenderableColorTextureFormat(const glu::RenderContext &renderCtx)
388*35238bceSAndroid Build Coastguard Worker {
389*35238bceSAndroid Build Coastguard Worker if (glu::contextSupports(renderCtx.getType(), glu::ApiType::es(3, 0)))
390*35238bceSAndroid Build Coastguard Worker return glu::TransferFormat(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
391*35238bceSAndroid Build Coastguard Worker
392*35238bceSAndroid Build Coastguard Worker {
393*35238bceSAndroid Build Coastguard Worker const glu::TransferFormat candidates[] = {
394*35238bceSAndroid Build Coastguard Worker glu::TransferFormat(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4),
395*35238bceSAndroid Build Coastguard Worker glu::TransferFormat(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1),
396*35238bceSAndroid Build Coastguard Worker glu::TransferFormat(GL_RGB, GL_UNSIGNED_SHORT_5_6_5),
397*35238bceSAndroid Build Coastguard Worker glu::TransferFormat(GL_RGBA, GL_UNSIGNED_BYTE),
398*35238bceSAndroid Build Coastguard Worker };
399*35238bceSAndroid Build Coastguard Worker
400*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(candidates); ++ndx)
401*35238bceSAndroid Build Coastguard Worker {
402*35238bceSAndroid Build Coastguard Worker if (isTextureFormatColorRenderable(renderCtx, candidates[ndx]))
403*35238bceSAndroid Build Coastguard Worker return candidates[ndx];
404*35238bceSAndroid Build Coastguard Worker }
405*35238bceSAndroid Build Coastguard Worker }
406*35238bceSAndroid Build Coastguard Worker
407*35238bceSAndroid Build Coastguard Worker return glu::TransferFormat(GL_NONE, GL_NONE);
408*35238bceSAndroid Build Coastguard Worker }
409*35238bceSAndroid Build Coastguard Worker
initStorage(void)410*35238bceSAndroid Build Coastguard Worker void TextureFboAttacher::initStorage(void)
411*35238bceSAndroid Build Coastguard Worker {
412*35238bceSAndroid Build Coastguard Worker const glu::TransferFormat format = getRenderableColorTextureFormat(getRenderContext());
413*35238bceSAndroid Build Coastguard Worker
414*35238bceSAndroid Build Coastguard Worker if (format.format == GL_NONE)
415*35238bceSAndroid Build Coastguard Worker TCU_THROW(NotSupportedError, "No renderable texture format found");
416*35238bceSAndroid Build Coastguard Worker
417*35238bceSAndroid Build Coastguard Worker GLU_CHECK_CALL_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, format.format, FRAMEBUFFER_SIZE, FRAMEBUFFER_SIZE, 0,
418*35238bceSAndroid Build Coastguard Worker format.format, format.dataType, DE_NULL),
419*35238bceSAndroid Build Coastguard Worker gl().getError());
420*35238bceSAndroid Build Coastguard Worker }
421*35238bceSAndroid Build Coastguard Worker
isRenderbufferFormatColorRenderable(const glu::RenderContext & renderCtx,const uint32_t format)422*35238bceSAndroid Build Coastguard Worker static bool isRenderbufferFormatColorRenderable(const glu::RenderContext &renderCtx, const uint32_t format)
423*35238bceSAndroid Build Coastguard Worker {
424*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = renderCtx.getFunctions();
425*35238bceSAndroid Build Coastguard Worker uint32_t curFbo = ~0u;
426*35238bceSAndroid Build Coastguard Worker uint32_t curRbo = ~0u;
427*35238bceSAndroid Build Coastguard Worker uint32_t testFbo = 0u;
428*35238bceSAndroid Build Coastguard Worker uint32_t testRbo = 0u;
429*35238bceSAndroid Build Coastguard Worker GLenum status = GL_NONE;
430*35238bceSAndroid Build Coastguard Worker
431*35238bceSAndroid Build Coastguard Worker GLU_CHECK_GLW_CALL(gl, getIntegerv(GL_FRAMEBUFFER_BINDING, (int32_t *)&curFbo));
432*35238bceSAndroid Build Coastguard Worker GLU_CHECK_GLW_CALL(gl, getIntegerv(GL_RENDERBUFFER_BINDING, (int32_t *)&curRbo));
433*35238bceSAndroid Build Coastguard Worker
434*35238bceSAndroid Build Coastguard Worker try
435*35238bceSAndroid Build Coastguard Worker {
436*35238bceSAndroid Build Coastguard Worker GLU_CHECK_GLW_CALL(gl, genRenderbuffers(1, &testRbo));
437*35238bceSAndroid Build Coastguard Worker GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, testRbo));
438*35238bceSAndroid Build Coastguard Worker GLU_CHECK_GLW_CALL(gl, renderbufferStorage(GL_RENDERBUFFER, format, FRAMEBUFFER_SIZE, FRAMEBUFFER_SIZE));
439*35238bceSAndroid Build Coastguard Worker
440*35238bceSAndroid Build Coastguard Worker GLU_CHECK_GLW_CALL(gl, genFramebuffers(1, &testFbo));
441*35238bceSAndroid Build Coastguard Worker GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, testFbo));
442*35238bceSAndroid Build Coastguard Worker GLU_CHECK_GLW_CALL(gl, framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, testRbo));
443*35238bceSAndroid Build Coastguard Worker
444*35238bceSAndroid Build Coastguard Worker status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
445*35238bceSAndroid Build Coastguard Worker GLU_CHECK_GLW_MSG(gl, "glCheckFramebufferStatus(GL_FRAMEBUFFER)");
446*35238bceSAndroid Build Coastguard Worker
447*35238bceSAndroid Build Coastguard Worker GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, curRbo));
448*35238bceSAndroid Build Coastguard Worker GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, curFbo));
449*35238bceSAndroid Build Coastguard Worker
450*35238bceSAndroid Build Coastguard Worker GLU_CHECK_GLW_CALL(gl, deleteRenderbuffers(1, &testRbo));
451*35238bceSAndroid Build Coastguard Worker GLU_CHECK_GLW_CALL(gl, deleteFramebuffers(1, &testFbo));
452*35238bceSAndroid Build Coastguard Worker }
453*35238bceSAndroid Build Coastguard Worker catch (...)
454*35238bceSAndroid Build Coastguard Worker {
455*35238bceSAndroid Build Coastguard Worker if (testRbo != 0)
456*35238bceSAndroid Build Coastguard Worker gl.deleteRenderbuffers(1, &testRbo);
457*35238bceSAndroid Build Coastguard Worker
458*35238bceSAndroid Build Coastguard Worker if (testFbo != 0)
459*35238bceSAndroid Build Coastguard Worker gl.deleteFramebuffers(1, &testFbo);
460*35238bceSAndroid Build Coastguard Worker
461*35238bceSAndroid Build Coastguard Worker throw;
462*35238bceSAndroid Build Coastguard Worker }
463*35238bceSAndroid Build Coastguard Worker
464*35238bceSAndroid Build Coastguard Worker if (status == GL_FRAMEBUFFER_COMPLETE)
465*35238bceSAndroid Build Coastguard Worker return true;
466*35238bceSAndroid Build Coastguard Worker else if (status == GL_FRAMEBUFFER_UNSUPPORTED)
467*35238bceSAndroid Build Coastguard Worker return false;
468*35238bceSAndroid Build Coastguard Worker else
469*35238bceSAndroid Build Coastguard Worker TCU_THROW(TestError, (std::string("glCheckFramebufferStatus() returned invalid result code ") +
470*35238bceSAndroid Build Coastguard Worker de::toString(glu::getFramebufferStatusStr(status)))
471*35238bceSAndroid Build Coastguard Worker .c_str());
472*35238bceSAndroid Build Coastguard Worker }
473*35238bceSAndroid Build Coastguard Worker
getRenderableColorRenderbufferFormat(const glu::RenderContext & renderCtx)474*35238bceSAndroid Build Coastguard Worker static uint32_t getRenderableColorRenderbufferFormat(const glu::RenderContext &renderCtx)
475*35238bceSAndroid Build Coastguard Worker {
476*35238bceSAndroid Build Coastguard Worker if (glu::contextSupports(renderCtx.getType(), glu::ApiType::es(3, 0)))
477*35238bceSAndroid Build Coastguard Worker return GL_RGBA4;
478*35238bceSAndroid Build Coastguard Worker
479*35238bceSAndroid Build Coastguard Worker {
480*35238bceSAndroid Build Coastguard Worker const uint32_t candidates[] = {
481*35238bceSAndroid Build Coastguard Worker GL_RGBA4,
482*35238bceSAndroid Build Coastguard Worker GL_RGB5_A1,
483*35238bceSAndroid Build Coastguard Worker GL_RGB565,
484*35238bceSAndroid Build Coastguard Worker };
485*35238bceSAndroid Build Coastguard Worker
486*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(candidates); ++ndx)
487*35238bceSAndroid Build Coastguard Worker {
488*35238bceSAndroid Build Coastguard Worker if (isRenderbufferFormatColorRenderable(renderCtx, candidates[ndx]))
489*35238bceSAndroid Build Coastguard Worker return candidates[ndx];
490*35238bceSAndroid Build Coastguard Worker }
491*35238bceSAndroid Build Coastguard Worker }
492*35238bceSAndroid Build Coastguard Worker
493*35238bceSAndroid Build Coastguard Worker return GL_NONE;
494*35238bceSAndroid Build Coastguard Worker }
495*35238bceSAndroid Build Coastguard Worker
initStorage(void)496*35238bceSAndroid Build Coastguard Worker void RboFboAttacher::initStorage(void)
497*35238bceSAndroid Build Coastguard Worker {
498*35238bceSAndroid Build Coastguard Worker const uint32_t format = getRenderableColorRenderbufferFormat(getRenderContext());
499*35238bceSAndroid Build Coastguard Worker
500*35238bceSAndroid Build Coastguard Worker if (format == GL_NONE)
501*35238bceSAndroid Build Coastguard Worker TCU_THROW(TestError, "No color-renderable renderbuffer format found");
502*35238bceSAndroid Build Coastguard Worker
503*35238bceSAndroid Build Coastguard Worker GLU_CHECK_CALL_ERROR(glRenderbufferStorage(GL_RENDERBUFFER, format, FRAMEBUFFER_SIZE, FRAMEBUFFER_SIZE),
504*35238bceSAndroid Build Coastguard Worker gl().getError());
505*35238bceSAndroid Build Coastguard Worker }
506*35238bceSAndroid Build Coastguard Worker
attach(GLuint rbo,GLuint fbo)507*35238bceSAndroid Build Coastguard Worker void RboFboAttacher::attach(GLuint rbo, GLuint fbo)
508*35238bceSAndroid Build Coastguard Worker {
509*35238bceSAndroid Build Coastguard Worker GLU_CHECK_CALL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, fbo), gl().getError());
510*35238bceSAndroid Build Coastguard Worker GLU_CHECK_CALL_ERROR(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo),
511*35238bceSAndroid Build Coastguard Worker gl().getError());
512*35238bceSAndroid Build Coastguard Worker GLU_CHECK_CALL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, 0), gl().getError());
513*35238bceSAndroid Build Coastguard Worker }
514*35238bceSAndroid Build Coastguard Worker
detach(GLuint rbo,GLuint fbo)515*35238bceSAndroid Build Coastguard Worker void RboFboAttacher::detach(GLuint rbo, GLuint fbo)
516*35238bceSAndroid Build Coastguard Worker {
517*35238bceSAndroid Build Coastguard Worker DE_UNREF(rbo);
518*35238bceSAndroid Build Coastguard Worker GLU_CHECK_CALL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, fbo), gl().getError());
519*35238bceSAndroid Build Coastguard Worker GLU_CHECK_CALL_ERROR(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0),
520*35238bceSAndroid Build Coastguard Worker gl().getError());
521*35238bceSAndroid Build Coastguard Worker GLU_CHECK_CALL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, 0), gl().getError());
522*35238bceSAndroid Build Coastguard Worker }
523*35238bceSAndroid Build Coastguard Worker
getAttachment(GLuint fbo)524*35238bceSAndroid Build Coastguard Worker GLuint RboFboAttacher::getAttachment(GLuint fbo)
525*35238bceSAndroid Build Coastguard Worker {
526*35238bceSAndroid Build Coastguard Worker return getFboAttachment(gl(), fbo, GL_RENDERBUFFER);
527*35238bceSAndroid Build Coastguard Worker }
528*35238bceSAndroid Build Coastguard Worker
529*35238bceSAndroid Build Coastguard Worker static const char *const s_fragmentShaderTemplate =
530*35238bceSAndroid Build Coastguard Worker GLSL100_SRC(void main() { gl_FragColor = vec4(${RED}, ${GREEN}, ${BLUE}, 1.0); });
531*35238bceSAndroid Build Coastguard Worker
initAttachment(GLuint seed,GLuint shader)532*35238bceSAndroid Build Coastguard Worker void ShaderProgramAttacher::initAttachment(GLuint seed, GLuint shader)
533*35238bceSAndroid Build Coastguard Worker {
534*35238bceSAndroid Build Coastguard Worker using de::floatToString;
535*35238bceSAndroid Build Coastguard Worker using de::insert;
536*35238bceSAndroid Build Coastguard Worker
537*35238bceSAndroid Build Coastguard Worker Random rnd(seed);
538*35238bceSAndroid Build Coastguard Worker map<string, string> params;
539*35238bceSAndroid Build Coastguard Worker const StringTemplate sourceTmpl(s_fragmentShaderTemplate);
540*35238bceSAndroid Build Coastguard Worker
541*35238bceSAndroid Build Coastguard Worker insert(params, "RED", floatToString(rnd.getFloat(), 4));
542*35238bceSAndroid Build Coastguard Worker insert(params, "GREEN", floatToString(rnd.getFloat(), 4));
543*35238bceSAndroid Build Coastguard Worker insert(params, "BLUE", floatToString(rnd.getFloat(), 4));
544*35238bceSAndroid Build Coastguard Worker
545*35238bceSAndroid Build Coastguard Worker {
546*35238bceSAndroid Build Coastguard Worker const string source = sourceTmpl.specialize(params);
547*35238bceSAndroid Build Coastguard Worker const char *const sourceStr = source.c_str();
548*35238bceSAndroid Build Coastguard Worker
549*35238bceSAndroid Build Coastguard Worker GLU_CHECK_CALL_ERROR(glShaderSource(shader, 1, &sourceStr, DE_NULL), gl().getError());
550*35238bceSAndroid Build Coastguard Worker GLU_CHECK_CALL_ERROR(glCompileShader(shader), gl().getError());
551*35238bceSAndroid Build Coastguard Worker
552*35238bceSAndroid Build Coastguard Worker {
553*35238bceSAndroid Build Coastguard Worker GLint compileStatus = 0;
554*35238bceSAndroid Build Coastguard Worker gl().getShaderiv(shader, GL_COMPILE_STATUS, &compileStatus);
555*35238bceSAndroid Build Coastguard Worker TCU_CHECK_MSG(compileStatus != 0, sourceStr);
556*35238bceSAndroid Build Coastguard Worker }
557*35238bceSAndroid Build Coastguard Worker }
558*35238bceSAndroid Build Coastguard Worker }
559*35238bceSAndroid Build Coastguard Worker
attach(GLuint shader,GLuint program)560*35238bceSAndroid Build Coastguard Worker void ShaderProgramAttacher::attach(GLuint shader, GLuint program)
561*35238bceSAndroid Build Coastguard Worker {
562*35238bceSAndroid Build Coastguard Worker GLU_CHECK_CALL_ERROR(glAttachShader(program, shader), gl().getError());
563*35238bceSAndroid Build Coastguard Worker }
564*35238bceSAndroid Build Coastguard Worker
detach(GLuint shader,GLuint program)565*35238bceSAndroid Build Coastguard Worker void ShaderProgramAttacher::detach(GLuint shader, GLuint program)
566*35238bceSAndroid Build Coastguard Worker {
567*35238bceSAndroid Build Coastguard Worker GLU_CHECK_CALL_ERROR(glDetachShader(program, shader), gl().getError());
568*35238bceSAndroid Build Coastguard Worker }
569*35238bceSAndroid Build Coastguard Worker
getAttachment(GLuint program)570*35238bceSAndroid Build Coastguard Worker GLuint ShaderProgramAttacher::getAttachment(GLuint program)
571*35238bceSAndroid Build Coastguard Worker {
572*35238bceSAndroid Build Coastguard Worker GLuint shaders[2] = {0, 0};
573*35238bceSAndroid Build Coastguard Worker const GLsizei shadersLen = DE_LENGTH_OF_ARRAY(shaders);
574*35238bceSAndroid Build Coastguard Worker GLsizei numShaders = 0;
575*35238bceSAndroid Build Coastguard Worker GLuint ret = 0;
576*35238bceSAndroid Build Coastguard Worker
577*35238bceSAndroid Build Coastguard Worker gl().getAttachedShaders(program, shadersLen, &numShaders, shaders);
578*35238bceSAndroid Build Coastguard Worker
579*35238bceSAndroid Build Coastguard Worker // There should ever be at most one attached shader in normal use, but if
580*35238bceSAndroid Build Coastguard Worker // something is wrong, the temporary vertex shader might not have been
581*35238bceSAndroid Build Coastguard Worker // detached properly, so let's find the fragment shader explicitly.
582*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < de::min<GLsizei>(shadersLen, numShaders); ++ndx)
583*35238bceSAndroid Build Coastguard Worker {
584*35238bceSAndroid Build Coastguard Worker GLint shaderType = GL_NONE;
585*35238bceSAndroid Build Coastguard Worker gl().getShaderiv(shaders[ndx], GL_SHADER_TYPE, &shaderType);
586*35238bceSAndroid Build Coastguard Worker
587*35238bceSAndroid Build Coastguard Worker if (shaderType == GL_FRAGMENT_SHADER)
588*35238bceSAndroid Build Coastguard Worker {
589*35238bceSAndroid Build Coastguard Worker ret = shaders[ndx];
590*35238bceSAndroid Build Coastguard Worker break;
591*35238bceSAndroid Build Coastguard Worker }
592*35238bceSAndroid Build Coastguard Worker }
593*35238bceSAndroid Build Coastguard Worker
594*35238bceSAndroid Build Coastguard Worker return ret;
595*35238bceSAndroid Build Coastguard Worker }
596*35238bceSAndroid Build Coastguard Worker
setViewport(const RenderContext & renderCtx,const Rectangle & rect)597*35238bceSAndroid Build Coastguard Worker void setViewport(const RenderContext &renderCtx, const Rectangle &rect)
598*35238bceSAndroid Build Coastguard Worker {
599*35238bceSAndroid Build Coastguard Worker renderCtx.getFunctions().viewport(rect.x, rect.y, rect.width, rect.height);
600*35238bceSAndroid Build Coastguard Worker }
601*35238bceSAndroid Build Coastguard Worker
readRectangle(const RenderContext & renderCtx,const Rectangle & rect,Surface & dst)602*35238bceSAndroid Build Coastguard Worker void readRectangle(const RenderContext &renderCtx, const Rectangle &rect, Surface &dst)
603*35238bceSAndroid Build Coastguard Worker {
604*35238bceSAndroid Build Coastguard Worker dst.setSize(rect.width, rect.height);
605*35238bceSAndroid Build Coastguard Worker glu::readPixels(renderCtx, rect.x, rect.y, dst.getAccess());
606*35238bceSAndroid Build Coastguard Worker }
607*35238bceSAndroid Build Coastguard Worker
randomViewport(const RenderContext & ctx,GLint maxWidth,GLint maxHeight,Random & rnd)608*35238bceSAndroid Build Coastguard Worker Rectangle randomViewport(const RenderContext &ctx, GLint maxWidth, GLint maxHeight, Random &rnd)
609*35238bceSAndroid Build Coastguard Worker {
610*35238bceSAndroid Build Coastguard Worker const RenderTarget &target = ctx.getRenderTarget();
611*35238bceSAndroid Build Coastguard Worker const GLint width = de::min(target.getWidth(), maxWidth);
612*35238bceSAndroid Build Coastguard Worker const GLint xOff = rnd.getInt(0, target.getWidth() - width);
613*35238bceSAndroid Build Coastguard Worker const GLint height = de::min(target.getHeight(), maxHeight);
614*35238bceSAndroid Build Coastguard Worker const GLint yOff = rnd.getInt(0, target.getHeight() - height);
615*35238bceSAndroid Build Coastguard Worker
616*35238bceSAndroid Build Coastguard Worker return Rectangle(xOff, yOff, width, height);
617*35238bceSAndroid Build Coastguard Worker }
618*35238bceSAndroid Build Coastguard Worker
drawContainer(GLuint program,Surface & dst)619*35238bceSAndroid Build Coastguard Worker void ShaderProgramInputAttacher::drawContainer(GLuint program, Surface &dst)
620*35238bceSAndroid Build Coastguard Worker {
621*35238bceSAndroid Build Coastguard Worker static const float s_vertices[6] = {-1.0, 0.0, 1.0, 1.0, 0.0, -1.0};
622*35238bceSAndroid Build Coastguard Worker Random rnd(program);
623*35238bceSAndroid Build Coastguard Worker CheckedShader vtxShader(getRenderContext(), SHADERTYPE_VERTEX, s_vertexShaderSrc);
624*35238bceSAndroid Build Coastguard Worker const Rectangle viewport = randomViewport(getRenderContext(), VIEWPORT_SIZE, VIEWPORT_SIZE, rnd);
625*35238bceSAndroid Build Coastguard Worker
626*35238bceSAndroid Build Coastguard Worker gl().attachShader(program, vtxShader.getShader());
627*35238bceSAndroid Build Coastguard Worker gl().linkProgram(program);
628*35238bceSAndroid Build Coastguard Worker
629*35238bceSAndroid Build Coastguard Worker {
630*35238bceSAndroid Build Coastguard Worker GLint linkStatus = 0;
631*35238bceSAndroid Build Coastguard Worker gl().getProgramiv(program, GL_LINK_STATUS, &linkStatus);
632*35238bceSAndroid Build Coastguard Worker TCU_CHECK(linkStatus != 0);
633*35238bceSAndroid Build Coastguard Worker }
634*35238bceSAndroid Build Coastguard Worker
635*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "// Attached a temporary vertex shader and linked program " << program
636*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
637*35238bceSAndroid Build Coastguard Worker
638*35238bceSAndroid Build Coastguard Worker setViewport(getRenderContext(), viewport);
639*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "// Positioned viewport randomly" << TestLog::EndMessage;
640*35238bceSAndroid Build Coastguard Worker
641*35238bceSAndroid Build Coastguard Worker glUseProgram(program);
642*35238bceSAndroid Build Coastguard Worker {
643*35238bceSAndroid Build Coastguard Worker GLint posLoc = gl().getAttribLocation(program, "pos");
644*35238bceSAndroid Build Coastguard Worker TCU_CHECK(posLoc >= 0);
645*35238bceSAndroid Build Coastguard Worker
646*35238bceSAndroid Build Coastguard Worker gl().enableVertexAttribArray(posLoc);
647*35238bceSAndroid Build Coastguard Worker
648*35238bceSAndroid Build Coastguard Worker gl().clearColor(0, 0, 0, 1);
649*35238bceSAndroid Build Coastguard Worker gl().clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
650*35238bceSAndroid Build Coastguard Worker gl().vertexAttribPointer(posLoc, 2, GL_FLOAT, GL_FALSE, 0, s_vertices);
651*35238bceSAndroid Build Coastguard Worker gl().drawArrays(GL_TRIANGLES, 0, 3);
652*35238bceSAndroid Build Coastguard Worker
653*35238bceSAndroid Build Coastguard Worker gl().disableVertexAttribArray(posLoc);
654*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "// Drew a fixed triangle" << TestLog::EndMessage;
655*35238bceSAndroid Build Coastguard Worker }
656*35238bceSAndroid Build Coastguard Worker glUseProgram(0);
657*35238bceSAndroid Build Coastguard Worker
658*35238bceSAndroid Build Coastguard Worker readRectangle(getRenderContext(), viewport, dst);
659*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "// Copied viewport to output image" << TestLog::EndMessage;
660*35238bceSAndroid Build Coastguard Worker
661*35238bceSAndroid Build Coastguard Worker gl().detachShader(program, vtxShader.getShader());
662*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "// Removed temporary vertex shader" << TestLog::EndMessage;
663*35238bceSAndroid Build Coastguard Worker }
664*35238bceSAndroid Build Coastguard Worker
ES2Types(const Context & ctx)665*35238bceSAndroid Build Coastguard Worker ES2Types::ES2Types(const Context &ctx)
666*35238bceSAndroid Build Coastguard Worker : Types(ctx)
667*35238bceSAndroid Build Coastguard Worker , m_bufferBind(ctx, &CallLogWrapper::glBindBuffer, GL_ARRAY_BUFFER, GL_ARRAY_BUFFER_BINDING)
668*35238bceSAndroid Build Coastguard Worker , m_bufferType(ctx, "buffer", &CallLogWrapper::glGenBuffers, &CallLogWrapper::glDeleteBuffers,
669*35238bceSAndroid Build Coastguard Worker &CallLogWrapper::glIsBuffer, &m_bufferBind)
670*35238bceSAndroid Build Coastguard Worker , m_textureBind(ctx, &CallLogWrapper::glBindTexture, GL_TEXTURE_2D, GL_TEXTURE_BINDING_2D)
671*35238bceSAndroid Build Coastguard Worker , m_textureType(ctx, "texture", &CallLogWrapper::glGenTextures, &CallLogWrapper::glDeleteTextures,
672*35238bceSAndroid Build Coastguard Worker &CallLogWrapper::glIsTexture, &m_textureBind)
673*35238bceSAndroid Build Coastguard Worker , m_rboBind(ctx, &CallLogWrapper::glBindRenderbuffer, GL_RENDERBUFFER, GL_RENDERBUFFER_BINDING)
674*35238bceSAndroid Build Coastguard Worker , m_rboType(ctx, "renderbuffer", &CallLogWrapper::glGenRenderbuffers, &CallLogWrapper::glDeleteRenderbuffers,
675*35238bceSAndroid Build Coastguard Worker &CallLogWrapper::glIsRenderbuffer, &m_rboBind)
676*35238bceSAndroid Build Coastguard Worker , m_fboBind(ctx, &CallLogWrapper::glBindFramebuffer, GL_FRAMEBUFFER, GL_FRAMEBUFFER_BINDING)
677*35238bceSAndroid Build Coastguard Worker , m_fboType(ctx, "framebuffer", &CallLogWrapper::glGenFramebuffers, &CallLogWrapper::glDeleteFramebuffers,
678*35238bceSAndroid Build Coastguard Worker &CallLogWrapper::glIsFramebuffer, &m_fboBind)
679*35238bceSAndroid Build Coastguard Worker , m_shaderType(ctx)
680*35238bceSAndroid Build Coastguard Worker , m_programType(ctx)
681*35238bceSAndroid Build Coastguard Worker , m_texFboAtt(ctx, m_textureType, m_fboType)
682*35238bceSAndroid Build Coastguard Worker , m_texFboInAtt(m_texFboAtt)
683*35238bceSAndroid Build Coastguard Worker , m_texFboOutAtt(m_texFboAtt)
684*35238bceSAndroid Build Coastguard Worker , m_rboFboAtt(ctx, m_rboType, m_fboType)
685*35238bceSAndroid Build Coastguard Worker , m_rboFboInAtt(m_rboFboAtt)
686*35238bceSAndroid Build Coastguard Worker , m_rboFboOutAtt(m_rboFboAtt)
687*35238bceSAndroid Build Coastguard Worker , m_shaderAtt(ctx, m_shaderType, m_programType)
688*35238bceSAndroid Build Coastguard Worker , m_shaderInAtt(m_shaderAtt)
689*35238bceSAndroid Build Coastguard Worker {
690*35238bceSAndroid Build Coastguard Worker Type *const types[] = {&m_bufferType, &m_textureType, &m_rboType, &m_fboType, &m_shaderType, &m_programType};
691*35238bceSAndroid Build Coastguard Worker m_types.insert(m_types.end(), DE_ARRAY_BEGIN(types), DE_ARRAY_END(types));
692*35238bceSAndroid Build Coastguard Worker
693*35238bceSAndroid Build Coastguard Worker m_attachers.push_back(&m_texFboAtt);
694*35238bceSAndroid Build Coastguard Worker m_attachers.push_back(&m_rboFboAtt);
695*35238bceSAndroid Build Coastguard Worker m_attachers.push_back(&m_shaderAtt);
696*35238bceSAndroid Build Coastguard Worker
697*35238bceSAndroid Build Coastguard Worker m_inAttachers.push_back(&m_texFboInAtt);
698*35238bceSAndroid Build Coastguard Worker m_inAttachers.push_back(&m_rboFboInAtt);
699*35238bceSAndroid Build Coastguard Worker m_inAttachers.push_back(&m_shaderInAtt);
700*35238bceSAndroid Build Coastguard Worker
701*35238bceSAndroid Build Coastguard Worker m_outAttachers.push_back(&m_texFboOutAtt);
702*35238bceSAndroid Build Coastguard Worker m_outAttachers.push_back(&m_rboFboOutAtt);
703*35238bceSAndroid Build Coastguard Worker }
704*35238bceSAndroid Build Coastguard Worker
705*35238bceSAndroid Build Coastguard Worker class Name
706*35238bceSAndroid Build Coastguard Worker {
707*35238bceSAndroid Build Coastguard Worker public:
Name(Type & type)708*35238bceSAndroid Build Coastguard Worker Name(Type &type) : m_type(type), m_name(type.gen())
709*35238bceSAndroid Build Coastguard Worker {
710*35238bceSAndroid Build Coastguard Worker }
Name(Type & type,GLuint name)711*35238bceSAndroid Build Coastguard Worker Name(Type &type, GLuint name) : m_type(type), m_name(name)
712*35238bceSAndroid Build Coastguard Worker {
713*35238bceSAndroid Build Coastguard Worker }
~Name(void)714*35238bceSAndroid Build Coastguard Worker ~Name(void)
715*35238bceSAndroid Build Coastguard Worker {
716*35238bceSAndroid Build Coastguard Worker m_type.release(m_name);
717*35238bceSAndroid Build Coastguard Worker }
operator *(void) const718*35238bceSAndroid Build Coastguard Worker GLuint operator*(void) const
719*35238bceSAndroid Build Coastguard Worker {
720*35238bceSAndroid Build Coastguard Worker return m_name;
721*35238bceSAndroid Build Coastguard Worker }
722*35238bceSAndroid Build Coastguard Worker
723*35238bceSAndroid Build Coastguard Worker private:
724*35238bceSAndroid Build Coastguard Worker Type &m_type;
725*35238bceSAndroid Build Coastguard Worker const GLuint m_name;
726*35238bceSAndroid Build Coastguard Worker };
727*35238bceSAndroid Build Coastguard Worker
728*35238bceSAndroid Build Coastguard Worker class ResultCollector
729*35238bceSAndroid Build Coastguard Worker {
730*35238bceSAndroid Build Coastguard Worker public:
731*35238bceSAndroid Build Coastguard Worker ResultCollector(TestContext &testCtx);
732*35238bceSAndroid Build Coastguard Worker bool check(bool cond, const char *msg);
733*35238bceSAndroid Build Coastguard Worker void fail(const char *msg);
734*35238bceSAndroid Build Coastguard Worker void warn(const char *msg);
735*35238bceSAndroid Build Coastguard Worker ~ResultCollector(void);
736*35238bceSAndroid Build Coastguard Worker
737*35238bceSAndroid Build Coastguard Worker private:
738*35238bceSAndroid Build Coastguard Worker void addResult(qpTestResult result, const char *msg);
739*35238bceSAndroid Build Coastguard Worker
740*35238bceSAndroid Build Coastguard Worker TestContext &m_testCtx;
741*35238bceSAndroid Build Coastguard Worker TestLog &m_log;
742*35238bceSAndroid Build Coastguard Worker qpTestResult m_result;
743*35238bceSAndroid Build Coastguard Worker const char *m_message;
744*35238bceSAndroid Build Coastguard Worker };
745*35238bceSAndroid Build Coastguard Worker
ResultCollector(TestContext & testCtx)746*35238bceSAndroid Build Coastguard Worker ResultCollector::ResultCollector(TestContext &testCtx)
747*35238bceSAndroid Build Coastguard Worker : m_testCtx(testCtx)
748*35238bceSAndroid Build Coastguard Worker , m_log(testCtx.getLog())
749*35238bceSAndroid Build Coastguard Worker , m_result(QP_TEST_RESULT_PASS)
750*35238bceSAndroid Build Coastguard Worker , m_message("Pass")
751*35238bceSAndroid Build Coastguard Worker {
752*35238bceSAndroid Build Coastguard Worker }
753*35238bceSAndroid Build Coastguard Worker
check(bool cond,const char * msg)754*35238bceSAndroid Build Coastguard Worker bool ResultCollector::check(bool cond, const char *msg)
755*35238bceSAndroid Build Coastguard Worker {
756*35238bceSAndroid Build Coastguard Worker if (!cond)
757*35238bceSAndroid Build Coastguard Worker fail(msg);
758*35238bceSAndroid Build Coastguard Worker return cond;
759*35238bceSAndroid Build Coastguard Worker }
760*35238bceSAndroid Build Coastguard Worker
addResult(qpTestResult result,const char * msg)761*35238bceSAndroid Build Coastguard Worker void ResultCollector::addResult(qpTestResult result, const char *msg)
762*35238bceSAndroid Build Coastguard Worker {
763*35238bceSAndroid Build Coastguard Worker m_log << TestLog::Message << "// Fail: " << msg << TestLog::EndMessage;
764*35238bceSAndroid Build Coastguard Worker if (m_result == QP_TEST_RESULT_PASS)
765*35238bceSAndroid Build Coastguard Worker {
766*35238bceSAndroid Build Coastguard Worker m_result = result;
767*35238bceSAndroid Build Coastguard Worker m_message = msg;
768*35238bceSAndroid Build Coastguard Worker }
769*35238bceSAndroid Build Coastguard Worker else
770*35238bceSAndroid Build Coastguard Worker {
771*35238bceSAndroid Build Coastguard Worker if (result == QP_TEST_RESULT_FAIL)
772*35238bceSAndroid Build Coastguard Worker m_result = result;
773*35238bceSAndroid Build Coastguard Worker m_message = "Multiple problems, see log for details";
774*35238bceSAndroid Build Coastguard Worker }
775*35238bceSAndroid Build Coastguard Worker }
776*35238bceSAndroid Build Coastguard Worker
fail(const char * msg)777*35238bceSAndroid Build Coastguard Worker void ResultCollector::fail(const char *msg)
778*35238bceSAndroid Build Coastguard Worker {
779*35238bceSAndroid Build Coastguard Worker addResult(QP_TEST_RESULT_FAIL, msg);
780*35238bceSAndroid Build Coastguard Worker }
781*35238bceSAndroid Build Coastguard Worker
warn(const char * msg)782*35238bceSAndroid Build Coastguard Worker void ResultCollector::warn(const char *msg)
783*35238bceSAndroid Build Coastguard Worker {
784*35238bceSAndroid Build Coastguard Worker addResult(QP_TEST_RESULT_QUALITY_WARNING, msg);
785*35238bceSAndroid Build Coastguard Worker }
786*35238bceSAndroid Build Coastguard Worker
~ResultCollector(void)787*35238bceSAndroid Build Coastguard Worker ResultCollector::~ResultCollector(void)
788*35238bceSAndroid Build Coastguard Worker {
789*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(m_result, m_message);
790*35238bceSAndroid Build Coastguard Worker }
791*35238bceSAndroid Build Coastguard Worker
792*35238bceSAndroid Build Coastguard Worker class TestBase : public TestCase, protected CallLogWrapper
793*35238bceSAndroid Build Coastguard Worker {
794*35238bceSAndroid Build Coastguard Worker protected:
795*35238bceSAndroid Build Coastguard Worker TestBase(const char *name, const char *description, const Context &ctx);
796*35238bceSAndroid Build Coastguard Worker
797*35238bceSAndroid Build Coastguard Worker // Copy ContextWrapper since MI (except for CallLogWrapper) is a no-no.
getContext(void) const798*35238bceSAndroid Build Coastguard Worker const Context &getContext(void) const
799*35238bceSAndroid Build Coastguard Worker {
800*35238bceSAndroid Build Coastguard Worker return m_ctx;
801*35238bceSAndroid Build Coastguard Worker }
getRenderContext(void) const802*35238bceSAndroid Build Coastguard Worker const RenderContext &getRenderContext(void) const
803*35238bceSAndroid Build Coastguard Worker {
804*35238bceSAndroid Build Coastguard Worker return m_ctx.getRenderContext();
805*35238bceSAndroid Build Coastguard Worker }
gl(void) const806*35238bceSAndroid Build Coastguard Worker const Functions &gl(void) const
807*35238bceSAndroid Build Coastguard Worker {
808*35238bceSAndroid Build Coastguard Worker return m_ctx.gl();
809*35238bceSAndroid Build Coastguard Worker }
log(void) const810*35238bceSAndroid Build Coastguard Worker TestLog &log(void) const
811*35238bceSAndroid Build Coastguard Worker {
812*35238bceSAndroid Build Coastguard Worker return m_ctx.log();
813*35238bceSAndroid Build Coastguard Worker }
814*35238bceSAndroid Build Coastguard Worker void init(void);
815*35238bceSAndroid Build Coastguard Worker
816*35238bceSAndroid Build Coastguard Worker Context m_ctx;
817*35238bceSAndroid Build Coastguard Worker Random m_rnd;
818*35238bceSAndroid Build Coastguard Worker };
819*35238bceSAndroid Build Coastguard Worker
TestBase(const char * name,const char * description,const Context & ctx)820*35238bceSAndroid Build Coastguard Worker TestBase::TestBase(const char *name, const char *description, const Context &ctx)
821*35238bceSAndroid Build Coastguard Worker : TestCase(ctx.getTestContext(), name, description)
822*35238bceSAndroid Build Coastguard Worker , CallLogWrapper(ctx.gl(), ctx.log())
823*35238bceSAndroid Build Coastguard Worker , m_ctx(ctx)
824*35238bceSAndroid Build Coastguard Worker , m_rnd(deStringHash(name))
825*35238bceSAndroid Build Coastguard Worker {
826*35238bceSAndroid Build Coastguard Worker enableLogging(true);
827*35238bceSAndroid Build Coastguard Worker }
828*35238bceSAndroid Build Coastguard Worker
init(void)829*35238bceSAndroid Build Coastguard Worker void TestBase::init(void)
830*35238bceSAndroid Build Coastguard Worker {
831*35238bceSAndroid Build Coastguard Worker m_rnd = Random(deStringHash(getName()));
832*35238bceSAndroid Build Coastguard Worker }
833*35238bceSAndroid Build Coastguard Worker
834*35238bceSAndroid Build Coastguard Worker class LifeTest : public TestBase
835*35238bceSAndroid Build Coastguard Worker {
836*35238bceSAndroid Build Coastguard Worker public:
837*35238bceSAndroid Build Coastguard Worker typedef void (LifeTest::*TestFunction)(void);
838*35238bceSAndroid Build Coastguard Worker
LifeTest(const char * name,const char * description,Type & type,TestFunction test)839*35238bceSAndroid Build Coastguard Worker LifeTest(const char *name, const char *description, Type &type, TestFunction test)
840*35238bceSAndroid Build Coastguard Worker : TestBase(name, description, type.getContext())
841*35238bceSAndroid Build Coastguard Worker , m_type(type)
842*35238bceSAndroid Build Coastguard Worker , m_test(test)
843*35238bceSAndroid Build Coastguard Worker {
844*35238bceSAndroid Build Coastguard Worker }
845*35238bceSAndroid Build Coastguard Worker
846*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
847*35238bceSAndroid Build Coastguard Worker
848*35238bceSAndroid Build Coastguard Worker void testGen(void);
849*35238bceSAndroid Build Coastguard Worker void testDelete(void);
850*35238bceSAndroid Build Coastguard Worker void testBind(void);
851*35238bceSAndroid Build Coastguard Worker void testDeleteBound(void);
852*35238bceSAndroid Build Coastguard Worker void testBindNoGen(void);
853*35238bceSAndroid Build Coastguard Worker void testDeleteUsed(void);
854*35238bceSAndroid Build Coastguard Worker
855*35238bceSAndroid Build Coastguard Worker private:
binder(void)856*35238bceSAndroid Build Coastguard Worker Binder &binder(void)
857*35238bceSAndroid Build Coastguard Worker {
858*35238bceSAndroid Build Coastguard Worker return *m_type.binder();
859*35238bceSAndroid Build Coastguard Worker }
860*35238bceSAndroid Build Coastguard Worker
861*35238bceSAndroid Build Coastguard Worker Type &m_type;
862*35238bceSAndroid Build Coastguard Worker TestFunction m_test;
863*35238bceSAndroid Build Coastguard Worker };
864*35238bceSAndroid Build Coastguard Worker
iterate(void)865*35238bceSAndroid Build Coastguard Worker IterateResult LifeTest::iterate(void)
866*35238bceSAndroid Build Coastguard Worker {
867*35238bceSAndroid Build Coastguard Worker (this->*m_test)();
868*35238bceSAndroid Build Coastguard Worker return STOP;
869*35238bceSAndroid Build Coastguard Worker }
870*35238bceSAndroid Build Coastguard Worker
testGen(void)871*35238bceSAndroid Build Coastguard Worker void LifeTest::testGen(void)
872*35238bceSAndroid Build Coastguard Worker {
873*35238bceSAndroid Build Coastguard Worker ResultCollector errors(getTestContext());
874*35238bceSAndroid Build Coastguard Worker Name name(m_type);
875*35238bceSAndroid Build Coastguard Worker
876*35238bceSAndroid Build Coastguard Worker if (m_type.genCreates())
877*35238bceSAndroid Build Coastguard Worker errors.check(m_type.exists(*name), "Gen* should have created an object, but didn't");
878*35238bceSAndroid Build Coastguard Worker else
879*35238bceSAndroid Build Coastguard Worker errors.check(!m_type.exists(*name), "Gen* should not have created an object, but did");
880*35238bceSAndroid Build Coastguard Worker }
881*35238bceSAndroid Build Coastguard Worker
testDelete(void)882*35238bceSAndroid Build Coastguard Worker void LifeTest::testDelete(void)
883*35238bceSAndroid Build Coastguard Worker {
884*35238bceSAndroid Build Coastguard Worker ResultCollector errors(getTestContext());
885*35238bceSAndroid Build Coastguard Worker GLuint name = m_type.gen();
886*35238bceSAndroid Build Coastguard Worker
887*35238bceSAndroid Build Coastguard Worker m_type.release(name);
888*35238bceSAndroid Build Coastguard Worker errors.check(!m_type.exists(name), "Object still exists after deletion");
889*35238bceSAndroid Build Coastguard Worker }
890*35238bceSAndroid Build Coastguard Worker
testBind(void)891*35238bceSAndroid Build Coastguard Worker void LifeTest::testBind(void)
892*35238bceSAndroid Build Coastguard Worker {
893*35238bceSAndroid Build Coastguard Worker ResultCollector errors(getTestContext());
894*35238bceSAndroid Build Coastguard Worker Name name(m_type);
895*35238bceSAndroid Build Coastguard Worker
896*35238bceSAndroid Build Coastguard Worker binder().bind(*name);
897*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl().getError(), "Bind failed");
898*35238bceSAndroid Build Coastguard Worker errors.check(m_type.exists(*name), "Object does not exist after binding");
899*35238bceSAndroid Build Coastguard Worker binder().bind(0);
900*35238bceSAndroid Build Coastguard Worker }
901*35238bceSAndroid Build Coastguard Worker
testDeleteBound(void)902*35238bceSAndroid Build Coastguard Worker void LifeTest::testDeleteBound(void)
903*35238bceSAndroid Build Coastguard Worker {
904*35238bceSAndroid Build Coastguard Worker const GLuint id = m_type.gen();
905*35238bceSAndroid Build Coastguard Worker ResultCollector errors(getTestContext());
906*35238bceSAndroid Build Coastguard Worker
907*35238bceSAndroid Build Coastguard Worker binder().bind(id);
908*35238bceSAndroid Build Coastguard Worker m_type.release(id);
909*35238bceSAndroid Build Coastguard Worker
910*35238bceSAndroid Build Coastguard Worker if (m_type.nameLingers())
911*35238bceSAndroid Build Coastguard Worker {
912*35238bceSAndroid Build Coastguard Worker errors.check(gl().getError() == GL_NO_ERROR, "Deleting bound object failed");
913*35238bceSAndroid Build Coastguard Worker errors.check(binder().getBinding() == id, "Deleting bound object did not retain binding");
914*35238bceSAndroid Build Coastguard Worker errors.check(m_type.exists(id), "Deleting bound object made its name invalid");
915*35238bceSAndroid Build Coastguard Worker errors.check(m_type.isDeleteFlagged(id), "Deleting bound object did not flag the object for deletion");
916*35238bceSAndroid Build Coastguard Worker binder().bind(0);
917*35238bceSAndroid Build Coastguard Worker }
918*35238bceSAndroid Build Coastguard Worker else
919*35238bceSAndroid Build Coastguard Worker {
920*35238bceSAndroid Build Coastguard Worker errors.check(gl().getError() == GL_NO_ERROR, "Deleting bound object failed");
921*35238bceSAndroid Build Coastguard Worker errors.check(binder().getBinding() == 0, "Deleting bound object did not remove binding");
922*35238bceSAndroid Build Coastguard Worker errors.check(!m_type.exists(id), "Deleting bound object did not make its name invalid");
923*35238bceSAndroid Build Coastguard Worker binder().bind(0);
924*35238bceSAndroid Build Coastguard Worker }
925*35238bceSAndroid Build Coastguard Worker
926*35238bceSAndroid Build Coastguard Worker errors.check(binder().getBinding() == 0, "Unbinding didn't remove binding");
927*35238bceSAndroid Build Coastguard Worker errors.check(!m_type.exists(id), "Name is still valid after deleting and unbinding");
928*35238bceSAndroid Build Coastguard Worker }
929*35238bceSAndroid Build Coastguard Worker
testBindNoGen(void)930*35238bceSAndroid Build Coastguard Worker void LifeTest::testBindNoGen(void)
931*35238bceSAndroid Build Coastguard Worker {
932*35238bceSAndroid Build Coastguard Worker ResultCollector errors(getTestContext());
933*35238bceSAndroid Build Coastguard Worker const GLuint id = m_rnd.getUint32();
934*35238bceSAndroid Build Coastguard Worker
935*35238bceSAndroid Build Coastguard Worker if (!errors.check(!m_type.exists(id), "Randomly chosen identifier already exists"))
936*35238bceSAndroid Build Coastguard Worker return;
937*35238bceSAndroid Build Coastguard Worker
938*35238bceSAndroid Build Coastguard Worker Name name(m_type, id);
939*35238bceSAndroid Build Coastguard Worker binder().bind(*name);
940*35238bceSAndroid Build Coastguard Worker
941*35238bceSAndroid Build Coastguard Worker if (binder().genRequired())
942*35238bceSAndroid Build Coastguard Worker {
943*35238bceSAndroid Build Coastguard Worker errors.check(glGetError() == GL_INVALID_OPERATION,
944*35238bceSAndroid Build Coastguard Worker "Did not fail when binding a name not generated by Gen* call");
945*35238bceSAndroid Build Coastguard Worker errors.check(!m_type.exists(*name), "Bind* created an object for a name not generated by a Gen* call");
946*35238bceSAndroid Build Coastguard Worker }
947*35238bceSAndroid Build Coastguard Worker else
948*35238bceSAndroid Build Coastguard Worker {
949*35238bceSAndroid Build Coastguard Worker errors.check(glGetError() == GL_NO_ERROR, "Failed when binding a name not generated by Gen* call");
950*35238bceSAndroid Build Coastguard Worker errors.check(m_type.exists(*name), "Object was not created by the Bind* call");
951*35238bceSAndroid Build Coastguard Worker }
952*35238bceSAndroid Build Coastguard Worker }
953*35238bceSAndroid Build Coastguard Worker
testDeleteUsed(void)954*35238bceSAndroid Build Coastguard Worker void LifeTest::testDeleteUsed(void)
955*35238bceSAndroid Build Coastguard Worker {
956*35238bceSAndroid Build Coastguard Worker ResultCollector errors(getTestContext());
957*35238bceSAndroid Build Coastguard Worker GLuint programId = 0;
958*35238bceSAndroid Build Coastguard Worker
959*35238bceSAndroid Build Coastguard Worker {
960*35238bceSAndroid Build Coastguard Worker CheckedShader vtxShader(getRenderContext(), SHADERTYPE_VERTEX, s_vertexShaderSrc);
961*35238bceSAndroid Build Coastguard Worker CheckedShader fragShader(getRenderContext(), SHADERTYPE_FRAGMENT, s_fragmentShaderSrc);
962*35238bceSAndroid Build Coastguard Worker CheckedProgram program(getRenderContext(), vtxShader.getShader(), fragShader.getShader());
963*35238bceSAndroid Build Coastguard Worker
964*35238bceSAndroid Build Coastguard Worker programId = program.getProgram();
965*35238bceSAndroid Build Coastguard Worker
966*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "// Created and linked program " << programId << TestLog::EndMessage;
967*35238bceSAndroid Build Coastguard Worker GLU_CHECK_CALL_ERROR(glUseProgram(programId), gl().getError());
968*35238bceSAndroid Build Coastguard Worker
969*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "// Deleted program " << programId << TestLog::EndMessage;
970*35238bceSAndroid Build Coastguard Worker }
971*35238bceSAndroid Build Coastguard Worker TCU_CHECK(glIsProgram(programId));
972*35238bceSAndroid Build Coastguard Worker {
973*35238bceSAndroid Build Coastguard Worker GLint deleteFlagged = 0;
974*35238bceSAndroid Build Coastguard Worker glGetProgramiv(programId, GL_DELETE_STATUS, &deleteFlagged);
975*35238bceSAndroid Build Coastguard Worker errors.check(deleteFlagged != 0, "Program object was not flagged as deleted");
976*35238bceSAndroid Build Coastguard Worker }
977*35238bceSAndroid Build Coastguard Worker GLU_CHECK_CALL_ERROR(glUseProgram(0), gl().getError());
978*35238bceSAndroid Build Coastguard Worker errors.check(!gl().isProgram(programId), "Deleted program name still valid after being made non-current");
979*35238bceSAndroid Build Coastguard Worker }
980*35238bceSAndroid Build Coastguard Worker
981*35238bceSAndroid Build Coastguard Worker class AttachmentTest : public TestBase
982*35238bceSAndroid Build Coastguard Worker {
983*35238bceSAndroid Build Coastguard Worker public:
984*35238bceSAndroid Build Coastguard Worker typedef void (AttachmentTest::*TestFunction)(void);
AttachmentTest(const char * name,const char * description,Attacher & attacher,TestFunction test)985*35238bceSAndroid Build Coastguard Worker AttachmentTest(const char *name, const char *description, Attacher &attacher, TestFunction test)
986*35238bceSAndroid Build Coastguard Worker : TestBase(name, description, attacher.getContext())
987*35238bceSAndroid Build Coastguard Worker , m_attacher(attacher)
988*35238bceSAndroid Build Coastguard Worker , m_test(test)
989*35238bceSAndroid Build Coastguard Worker {
990*35238bceSAndroid Build Coastguard Worker }
991*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
992*35238bceSAndroid Build Coastguard Worker
993*35238bceSAndroid Build Coastguard Worker void testDeletedNames(void);
994*35238bceSAndroid Build Coastguard Worker void testDeletedBinding(void);
995*35238bceSAndroid Build Coastguard Worker void testDeletedReattach(void);
996*35238bceSAndroid Build Coastguard Worker
997*35238bceSAndroid Build Coastguard Worker private:
998*35238bceSAndroid Build Coastguard Worker Attacher &m_attacher;
999*35238bceSAndroid Build Coastguard Worker const TestFunction m_test;
1000*35238bceSAndroid Build Coastguard Worker };
1001*35238bceSAndroid Build Coastguard Worker
iterate(void)1002*35238bceSAndroid Build Coastguard Worker IterateResult AttachmentTest::iterate(void)
1003*35238bceSAndroid Build Coastguard Worker {
1004*35238bceSAndroid Build Coastguard Worker (this->*m_test)();
1005*35238bceSAndroid Build Coastguard Worker return STOP;
1006*35238bceSAndroid Build Coastguard Worker }
1007*35238bceSAndroid Build Coastguard Worker
getAttachment(Attacher & attacher,GLuint container)1008*35238bceSAndroid Build Coastguard Worker GLuint getAttachment(Attacher &attacher, GLuint container)
1009*35238bceSAndroid Build Coastguard Worker {
1010*35238bceSAndroid Build Coastguard Worker const GLuint queriedAttachment = attacher.getAttachment(container);
1011*35238bceSAndroid Build Coastguard Worker attacher.log() << TestLog::Message << "// Result of query for " << attacher.getElementType().getName()
1012*35238bceSAndroid Build Coastguard Worker << " attached to " << attacher.getContainerType().getName() << " " << container << ": "
1013*35238bceSAndroid Build Coastguard Worker << queriedAttachment << "." << TestLog::EndMessage;
1014*35238bceSAndroid Build Coastguard Worker return queriedAttachment;
1015*35238bceSAndroid Build Coastguard Worker }
1016*35238bceSAndroid Build Coastguard Worker
testDeletedNames(void)1017*35238bceSAndroid Build Coastguard Worker void AttachmentTest::testDeletedNames(void)
1018*35238bceSAndroid Build Coastguard Worker {
1019*35238bceSAndroid Build Coastguard Worker Type &elemType = m_attacher.getElementType();
1020*35238bceSAndroid Build Coastguard Worker Type &containerType = m_attacher.getContainerType();
1021*35238bceSAndroid Build Coastguard Worker Name container(containerType);
1022*35238bceSAndroid Build Coastguard Worker ResultCollector errors(getTestContext());
1023*35238bceSAndroid Build Coastguard Worker GLuint elementId = 0;
1024*35238bceSAndroid Build Coastguard Worker
1025*35238bceSAndroid Build Coastguard Worker {
1026*35238bceSAndroid Build Coastguard Worker Name element(elemType);
1027*35238bceSAndroid Build Coastguard Worker elementId = *element;
1028*35238bceSAndroid Build Coastguard Worker m_attacher.initAttachment(0, *element);
1029*35238bceSAndroid Build Coastguard Worker m_attacher.attach(*element, *container);
1030*35238bceSAndroid Build Coastguard Worker errors.check(getAttachment(m_attacher, *container) == elementId,
1031*35238bceSAndroid Build Coastguard Worker "Attachment name not returned by query even before deletion.");
1032*35238bceSAndroid Build Coastguard Worker }
1033*35238bceSAndroid Build Coastguard Worker
1034*35238bceSAndroid Build Coastguard Worker // "Such a container or other context may continue using the object, and
1035*35238bceSAndroid Build Coastguard Worker // may still contain state identifying its name as being currently bound"
1036*35238bceSAndroid Build Coastguard Worker //
1037*35238bceSAndroid Build Coastguard Worker // We here interpret "may" to mean that whenever the container has a
1038*35238bceSAndroid Build Coastguard Worker // deleted object attached to it, a query will return that object's former
1039*35238bceSAndroid Build Coastguard Worker // name.
1040*35238bceSAndroid Build Coastguard Worker errors.check(getAttachment(m_attacher, *container) == elementId,
1041*35238bceSAndroid Build Coastguard Worker "Attachment name not returned by query after attachment was deleted.");
1042*35238bceSAndroid Build Coastguard Worker
1043*35238bceSAndroid Build Coastguard Worker if (elemType.nameLingers())
1044*35238bceSAndroid Build Coastguard Worker errors.check(elemType.exists(elementId), "Attached object name no longer valid after deletion.");
1045*35238bceSAndroid Build Coastguard Worker else
1046*35238bceSAndroid Build Coastguard Worker errors.check(!elemType.exists(elementId), "Attached object name still valid after deletion.");
1047*35238bceSAndroid Build Coastguard Worker
1048*35238bceSAndroid Build Coastguard Worker m_attacher.detach(elementId, *container);
1049*35238bceSAndroid Build Coastguard Worker errors.check(getAttachment(m_attacher, *container) == 0,
1050*35238bceSAndroid Build Coastguard Worker "Attachment name returned by query even after detachment.");
1051*35238bceSAndroid Build Coastguard Worker errors.check(!elemType.exists(elementId), "Deleted attached object name still usable after detachment.");
1052*35238bceSAndroid Build Coastguard Worker }
1053*35238bceSAndroid Build Coastguard Worker
1054*35238bceSAndroid Build Coastguard Worker class InputAttachmentTest : public TestBase
1055*35238bceSAndroid Build Coastguard Worker {
1056*35238bceSAndroid Build Coastguard Worker public:
InputAttachmentTest(const char * name,const char * description,InputAttacher & inputAttacher)1057*35238bceSAndroid Build Coastguard Worker InputAttachmentTest(const char *name, const char *description, InputAttacher &inputAttacher)
1058*35238bceSAndroid Build Coastguard Worker : TestBase(name, description, inputAttacher.getContext())
1059*35238bceSAndroid Build Coastguard Worker , m_inputAttacher(inputAttacher)
1060*35238bceSAndroid Build Coastguard Worker {
1061*35238bceSAndroid Build Coastguard Worker }
1062*35238bceSAndroid Build Coastguard Worker
1063*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
1064*35238bceSAndroid Build Coastguard Worker
1065*35238bceSAndroid Build Coastguard Worker private:
1066*35238bceSAndroid Build Coastguard Worker InputAttacher &m_inputAttacher;
1067*35238bceSAndroid Build Coastguard Worker };
1068*35238bceSAndroid Build Coastguard Worker
replaceName(Type & type,GLuint oldName,TestLog & log)1069*35238bceSAndroid Build Coastguard Worker GLuint replaceName(Type &type, GLuint oldName, TestLog &log)
1070*35238bceSAndroid Build Coastguard Worker {
1071*35238bceSAndroid Build Coastguard Worker const Binder *const binder = type.binder();
1072*35238bceSAndroid Build Coastguard Worker const bool genRequired = binder == DE_NULL || binder->genRequired();
1073*35238bceSAndroid Build Coastguard Worker
1074*35238bceSAndroid Build Coastguard Worker if (genRequired)
1075*35238bceSAndroid Build Coastguard Worker return type.gen();
1076*35238bceSAndroid Build Coastguard Worker
1077*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "// Type does not require Gen* for binding, reusing old id " << oldName << "."
1078*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
1079*35238bceSAndroid Build Coastguard Worker
1080*35238bceSAndroid Build Coastguard Worker return oldName;
1081*35238bceSAndroid Build Coastguard Worker }
1082*35238bceSAndroid Build Coastguard Worker
iterate(void)1083*35238bceSAndroid Build Coastguard Worker IterateResult InputAttachmentTest::iterate(void)
1084*35238bceSAndroid Build Coastguard Worker {
1085*35238bceSAndroid Build Coastguard Worker Attacher &attacher = m_inputAttacher.getAttacher();
1086*35238bceSAndroid Build Coastguard Worker Type &containerType = attacher.getContainerType();
1087*35238bceSAndroid Build Coastguard Worker Type &elementType = attacher.getElementType();
1088*35238bceSAndroid Build Coastguard Worker Name container(containerType);
1089*35238bceSAndroid Build Coastguard Worker GLuint elementId = 0;
1090*35238bceSAndroid Build Coastguard Worker const GLuint refSeed = m_rnd.getUint32();
1091*35238bceSAndroid Build Coastguard Worker const GLuint newSeed = m_rnd.getUint32();
1092*35238bceSAndroid Build Coastguard Worker ResultCollector errors(getTestContext());
1093*35238bceSAndroid Build Coastguard Worker
1094*35238bceSAndroid Build Coastguard Worker Surface refSurface; // Surface from drawing with refSeed-seeded attachment
1095*35238bceSAndroid Build Coastguard Worker Surface delSurface; // Surface from drawing with deleted refSeed attachment
1096*35238bceSAndroid Build Coastguard Worker Surface newSurface; // Surface from drawing with newSeed-seeded attachment
1097*35238bceSAndroid Build Coastguard Worker
1098*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "Testing if writing to a newly created object modifies a deleted attachment"
1099*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
1100*35238bceSAndroid Build Coastguard Worker
1101*35238bceSAndroid Build Coastguard Worker {
1102*35238bceSAndroid Build Coastguard Worker ScopedLogSection section(log(), "Write to original", "Writing to an original attachment");
1103*35238bceSAndroid Build Coastguard Worker const Name element(elementType);
1104*35238bceSAndroid Build Coastguard Worker
1105*35238bceSAndroid Build Coastguard Worker elementId = *element;
1106*35238bceSAndroid Build Coastguard Worker attacher.initAttachment(refSeed, elementId);
1107*35238bceSAndroid Build Coastguard Worker attacher.attach(elementId, *container);
1108*35238bceSAndroid Build Coastguard Worker m_inputAttacher.drawContainer(*container, refSurface);
1109*35238bceSAndroid Build Coastguard Worker // element gets deleted here
1110*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "// Deleting attachment";
1111*35238bceSAndroid Build Coastguard Worker }
1112*35238bceSAndroid Build Coastguard Worker {
1113*35238bceSAndroid Build Coastguard Worker ScopedLogSection section(log(), "Write to new", "Writing to a new attachment after deleting the original");
1114*35238bceSAndroid Build Coastguard Worker const GLuint newId = replaceName(elementType, elementId, log());
1115*35238bceSAndroid Build Coastguard Worker const Name newElement(elementType, newId);
1116*35238bceSAndroid Build Coastguard Worker
1117*35238bceSAndroid Build Coastguard Worker attacher.initAttachment(newSeed, newId);
1118*35238bceSAndroid Build Coastguard Worker
1119*35238bceSAndroid Build Coastguard Worker m_inputAttacher.drawContainer(*container, delSurface);
1120*35238bceSAndroid Build Coastguard Worker attacher.detach(elementId, *container);
1121*35238bceSAndroid Build Coastguard Worker
1122*35238bceSAndroid Build Coastguard Worker attacher.attach(newId, *container);
1123*35238bceSAndroid Build Coastguard Worker m_inputAttacher.drawContainer(*container, newSurface);
1124*35238bceSAndroid Build Coastguard Worker attacher.detach(newId, *container);
1125*35238bceSAndroid Build Coastguard Worker }
1126*35238bceSAndroid Build Coastguard Worker {
1127*35238bceSAndroid Build Coastguard Worker const bool surfacesMatch =
1128*35238bceSAndroid Build Coastguard Worker tcu::pixelThresholdCompare(log(), "Reading from deleted",
1129*35238bceSAndroid Build Coastguard Worker "Comparison result from reading from a container with a deleted attachment "
1130*35238bceSAndroid Build Coastguard Worker "before and after writing to a fresh object.",
1131*35238bceSAndroid Build Coastguard Worker refSurface, delSurface, RGBA(0, 0, 0, 0), tcu::COMPARE_LOG_RESULT);
1132*35238bceSAndroid Build Coastguard Worker
1133*35238bceSAndroid Build Coastguard Worker errors.check(surfacesMatch, "Writing to a fresh object modified the container with a deleted attachment.");
1134*35238bceSAndroid Build Coastguard Worker
1135*35238bceSAndroid Build Coastguard Worker if (!surfacesMatch)
1136*35238bceSAndroid Build Coastguard Worker log() << TestLog::Image("New attachment", "Container state after attached to the fresh object", newSurface);
1137*35238bceSAndroid Build Coastguard Worker }
1138*35238bceSAndroid Build Coastguard Worker
1139*35238bceSAndroid Build Coastguard Worker return STOP;
1140*35238bceSAndroid Build Coastguard Worker }
1141*35238bceSAndroid Build Coastguard Worker
1142*35238bceSAndroid Build Coastguard Worker class OutputAttachmentTest : public TestBase
1143*35238bceSAndroid Build Coastguard Worker {
1144*35238bceSAndroid Build Coastguard Worker public:
OutputAttachmentTest(const char * name,const char * description,OutputAttacher & outputAttacher)1145*35238bceSAndroid Build Coastguard Worker OutputAttachmentTest(const char *name, const char *description, OutputAttacher &outputAttacher)
1146*35238bceSAndroid Build Coastguard Worker : TestBase(name, description, outputAttacher.getContext())
1147*35238bceSAndroid Build Coastguard Worker , m_outputAttacher(outputAttacher)
1148*35238bceSAndroid Build Coastguard Worker {
1149*35238bceSAndroid Build Coastguard Worker }
1150*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
1151*35238bceSAndroid Build Coastguard Worker
1152*35238bceSAndroid Build Coastguard Worker private:
1153*35238bceSAndroid Build Coastguard Worker OutputAttacher &m_outputAttacher;
1154*35238bceSAndroid Build Coastguard Worker };
1155*35238bceSAndroid Build Coastguard Worker
iterate(void)1156*35238bceSAndroid Build Coastguard Worker IterateResult OutputAttachmentTest::iterate(void)
1157*35238bceSAndroid Build Coastguard Worker {
1158*35238bceSAndroid Build Coastguard Worker Attacher &attacher = m_outputAttacher.getAttacher();
1159*35238bceSAndroid Build Coastguard Worker Type &containerType = attacher.getContainerType();
1160*35238bceSAndroid Build Coastguard Worker Type &elementType = attacher.getElementType();
1161*35238bceSAndroid Build Coastguard Worker Name container(containerType);
1162*35238bceSAndroid Build Coastguard Worker GLuint elementId = 0;
1163*35238bceSAndroid Build Coastguard Worker const GLuint refSeed = m_rnd.getUint32();
1164*35238bceSAndroid Build Coastguard Worker const GLuint newSeed = m_rnd.getUint32();
1165*35238bceSAndroid Build Coastguard Worker ResultCollector errors(getTestContext());
1166*35238bceSAndroid Build Coastguard Worker Surface refSurface; // Surface drawn from attachment to refSeed container
1167*35238bceSAndroid Build Coastguard Worker Surface newSurface; // Surface drawn from attachment to newSeed container
1168*35238bceSAndroid Build Coastguard Worker Surface delSurface; // Like newSurface, after writing to a deleted attachment
1169*35238bceSAndroid Build Coastguard Worker
1170*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "Testing if writing to a container with a deleted attachment "
1171*35238bceSAndroid Build Coastguard Worker << "modifies a newly created object" << TestLog::EndMessage;
1172*35238bceSAndroid Build Coastguard Worker
1173*35238bceSAndroid Build Coastguard Worker {
1174*35238bceSAndroid Build Coastguard Worker ScopedLogSection section(log(), "Write to existing", "Writing to a container with an existing attachment");
1175*35238bceSAndroid Build Coastguard Worker const Name element(elementType);
1176*35238bceSAndroid Build Coastguard Worker
1177*35238bceSAndroid Build Coastguard Worker elementId = *element;
1178*35238bceSAndroid Build Coastguard Worker attacher.initAttachment(0, elementId);
1179*35238bceSAndroid Build Coastguard Worker attacher.attach(elementId, *container);
1180*35238bceSAndroid Build Coastguard Worker
1181*35238bceSAndroid Build Coastguard Worker // For reference purposes, make note of what refSeed looks like.
1182*35238bceSAndroid Build Coastguard Worker m_outputAttacher.setupContainer(refSeed, *container);
1183*35238bceSAndroid Build Coastguard Worker m_outputAttacher.drawAttachment(elementId, refSurface);
1184*35238bceSAndroid Build Coastguard Worker }
1185*35238bceSAndroid Build Coastguard Worker {
1186*35238bceSAndroid Build Coastguard Worker ScopedLogSection section(log(), "Write to deleted", "Writing to a container after deletion of attachment");
1187*35238bceSAndroid Build Coastguard Worker const GLuint newId = replaceName(elementType, elementId, log());
1188*35238bceSAndroid Build Coastguard Worker const Name newElement(elementType, newId);
1189*35238bceSAndroid Build Coastguard Worker
1190*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "Creating a new object " << newId << TestLog::EndMessage;
1191*35238bceSAndroid Build Coastguard Worker
1192*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "Recording state of new object before writing to container" << TestLog::EndMessage;
1193*35238bceSAndroid Build Coastguard Worker attacher.initAttachment(newSeed, newId);
1194*35238bceSAndroid Build Coastguard Worker m_outputAttacher.drawAttachment(newId, newSurface);
1195*35238bceSAndroid Build Coastguard Worker
1196*35238bceSAndroid Build Coastguard Worker log() << TestLog::Message << "Writing to container" << TestLog::EndMessage;
1197*35238bceSAndroid Build Coastguard Worker
1198*35238bceSAndroid Build Coastguard Worker // Now re-write refSeed to the container.
1199*35238bceSAndroid Build Coastguard Worker m_outputAttacher.setupContainer(refSeed, *container);
1200*35238bceSAndroid Build Coastguard Worker // Does it affect the newly created attachment object?
1201*35238bceSAndroid Build Coastguard Worker m_outputAttacher.drawAttachment(newId, delSurface);
1202*35238bceSAndroid Build Coastguard Worker }
1203*35238bceSAndroid Build Coastguard Worker attacher.detach(elementId, *container);
1204*35238bceSAndroid Build Coastguard Worker
1205*35238bceSAndroid Build Coastguard Worker const bool surfacesMatch =
1206*35238bceSAndroid Build Coastguard Worker tcu::pixelThresholdCompare(log(), "Writing to deleted",
1207*35238bceSAndroid Build Coastguard Worker "Comparison result from reading from a fresh object before and after "
1208*35238bceSAndroid Build Coastguard Worker "writing to a container with a deleted attachment",
1209*35238bceSAndroid Build Coastguard Worker newSurface, delSurface, RGBA(0, 0, 0, 0), tcu::COMPARE_LOG_RESULT);
1210*35238bceSAndroid Build Coastguard Worker
1211*35238bceSAndroid Build Coastguard Worker errors.check(surfacesMatch, "Writing to container with deleted attachment modified a new object.");
1212*35238bceSAndroid Build Coastguard Worker
1213*35238bceSAndroid Build Coastguard Worker if (!surfacesMatch)
1214*35238bceSAndroid Build Coastguard Worker log() << TestLog::Image("Original attachment",
1215*35238bceSAndroid Build Coastguard Worker "Result of container modification on original attachment before deletion.", refSurface);
1216*35238bceSAndroid Build Coastguard Worker return STOP;
1217*35238bceSAndroid Build Coastguard Worker }
1218*35238bceSAndroid Build Coastguard Worker
1219*35238bceSAndroid Build Coastguard Worker struct LifeTestSpec
1220*35238bceSAndroid Build Coastguard Worker {
1221*35238bceSAndroid Build Coastguard Worker const char *name;
1222*35238bceSAndroid Build Coastguard Worker LifeTest::TestFunction func;
1223*35238bceSAndroid Build Coastguard Worker bool needBind;
1224*35238bceSAndroid Build Coastguard Worker };
1225*35238bceSAndroid Build Coastguard Worker
createLifeTestGroup(TestContext & testCtx,const LifeTestSpec & spec,const vector<Type * > & types)1226*35238bceSAndroid Build Coastguard Worker MovePtr<TestCaseGroup> createLifeTestGroup(TestContext &testCtx, const LifeTestSpec &spec, const vector<Type *> &types)
1227*35238bceSAndroid Build Coastguard Worker {
1228*35238bceSAndroid Build Coastguard Worker MovePtr<TestCaseGroup> group(new TestCaseGroup(testCtx, spec.name, spec.name));
1229*35238bceSAndroid Build Coastguard Worker
1230*35238bceSAndroid Build Coastguard Worker for (vector<Type *>::const_iterator it = types.begin(); it != types.end(); ++it)
1231*35238bceSAndroid Build Coastguard Worker {
1232*35238bceSAndroid Build Coastguard Worker Type &type = **it;
1233*35238bceSAndroid Build Coastguard Worker const char *name = type.getName();
1234*35238bceSAndroid Build Coastguard Worker if (!spec.needBind || type.binder() != DE_NULL)
1235*35238bceSAndroid Build Coastguard Worker group->addChild(new LifeTest(name, name, type, spec.func));
1236*35238bceSAndroid Build Coastguard Worker }
1237*35238bceSAndroid Build Coastguard Worker
1238*35238bceSAndroid Build Coastguard Worker return group;
1239*35238bceSAndroid Build Coastguard Worker }
1240*35238bceSAndroid Build Coastguard Worker
1241*35238bceSAndroid Build Coastguard Worker static const LifeTestSpec s_lifeTests[] = {
1242*35238bceSAndroid Build Coastguard Worker {"gen", &LifeTest::testGen, false},
1243*35238bceSAndroid Build Coastguard Worker {"delete", &LifeTest::testDelete, false},
1244*35238bceSAndroid Build Coastguard Worker {"bind", &LifeTest::testBind, true},
1245*35238bceSAndroid Build Coastguard Worker {"delete_bound", &LifeTest::testDeleteBound, true},
1246*35238bceSAndroid Build Coastguard Worker {"bind_no_gen", &LifeTest::testBindNoGen, true},
1247*35238bceSAndroid Build Coastguard Worker };
1248*35238bceSAndroid Build Coastguard Worker
attacherName(Attacher & attacher)1249*35238bceSAndroid Build Coastguard Worker string attacherName(Attacher &attacher)
1250*35238bceSAndroid Build Coastguard Worker {
1251*35238bceSAndroid Build Coastguard Worker ostringstream os;
1252*35238bceSAndroid Build Coastguard Worker os << attacher.getElementType().getName() << "_" << attacher.getContainerType().getName();
1253*35238bceSAndroid Build Coastguard Worker return os.str();
1254*35238bceSAndroid Build Coastguard Worker }
1255*35238bceSAndroid Build Coastguard Worker
addTestCases(TestCaseGroup & group,Types & types)1256*35238bceSAndroid Build Coastguard Worker void addTestCases(TestCaseGroup &group, Types &types)
1257*35238bceSAndroid Build Coastguard Worker {
1258*35238bceSAndroid Build Coastguard Worker TestContext &testCtx = types.getTestContext();
1259*35238bceSAndroid Build Coastguard Worker
1260*35238bceSAndroid Build Coastguard Worker for (const LifeTestSpec *it = DE_ARRAY_BEGIN(s_lifeTests); it != DE_ARRAY_END(s_lifeTests); ++it)
1261*35238bceSAndroid Build Coastguard Worker group.addChild(createLifeTestGroup(testCtx, *it, types.getTypes()).release());
1262*35238bceSAndroid Build Coastguard Worker
1263*35238bceSAndroid Build Coastguard Worker {
1264*35238bceSAndroid Build Coastguard Worker TestCaseGroup *const delUsedGroup = new TestCaseGroup(testCtx, "delete_used", "Delete current program");
1265*35238bceSAndroid Build Coastguard Worker group.addChild(delUsedGroup);
1266*35238bceSAndroid Build Coastguard Worker
1267*35238bceSAndroid Build Coastguard Worker delUsedGroup->addChild(new LifeTest("program", "program", types.getProgramType(), &LifeTest::testDeleteUsed));
1268*35238bceSAndroid Build Coastguard Worker }
1269*35238bceSAndroid Build Coastguard Worker
1270*35238bceSAndroid Build Coastguard Worker {
1271*35238bceSAndroid Build Coastguard Worker TestCaseGroup *const attGroup = new TestCaseGroup(testCtx, "attach", "Attachment tests");
1272*35238bceSAndroid Build Coastguard Worker group.addChild(attGroup);
1273*35238bceSAndroid Build Coastguard Worker
1274*35238bceSAndroid Build Coastguard Worker {
1275*35238bceSAndroid Build Coastguard Worker TestCaseGroup *const nameGroup = new TestCaseGroup(testCtx, "deleted_name", "Name of deleted attachment");
1276*35238bceSAndroid Build Coastguard Worker attGroup->addChild(nameGroup);
1277*35238bceSAndroid Build Coastguard Worker
1278*35238bceSAndroid Build Coastguard Worker const vector<Attacher *> &atts = types.getAttachers();
1279*35238bceSAndroid Build Coastguard Worker for (vector<Attacher *>::const_iterator it = atts.begin(); it != atts.end(); ++it)
1280*35238bceSAndroid Build Coastguard Worker {
1281*35238bceSAndroid Build Coastguard Worker const string name = attacherName(**it);
1282*35238bceSAndroid Build Coastguard Worker nameGroup->addChild(
1283*35238bceSAndroid Build Coastguard Worker new AttachmentTest(name.c_str(), name.c_str(), **it, &AttachmentTest::testDeletedNames));
1284*35238bceSAndroid Build Coastguard Worker }
1285*35238bceSAndroid Build Coastguard Worker }
1286*35238bceSAndroid Build Coastguard Worker {
1287*35238bceSAndroid Build Coastguard Worker TestCaseGroup *inputGroup = new TestCaseGroup(testCtx, "deleted_input", "Input from deleted attachment");
1288*35238bceSAndroid Build Coastguard Worker attGroup->addChild(inputGroup);
1289*35238bceSAndroid Build Coastguard Worker
1290*35238bceSAndroid Build Coastguard Worker const vector<InputAttacher *> &inAtts = types.getInputAttachers();
1291*35238bceSAndroid Build Coastguard Worker for (vector<InputAttacher *>::const_iterator it = inAtts.begin(); it != inAtts.end(); ++it)
1292*35238bceSAndroid Build Coastguard Worker {
1293*35238bceSAndroid Build Coastguard Worker const string name = attacherName((*it)->getAttacher());
1294*35238bceSAndroid Build Coastguard Worker inputGroup->addChild(new InputAttachmentTest(name.c_str(), name.c_str(), **it));
1295*35238bceSAndroid Build Coastguard Worker }
1296*35238bceSAndroid Build Coastguard Worker }
1297*35238bceSAndroid Build Coastguard Worker {
1298*35238bceSAndroid Build Coastguard Worker TestCaseGroup *outputGroup = new TestCaseGroup(testCtx, "deleted_output", "Output to deleted attachment");
1299*35238bceSAndroid Build Coastguard Worker attGroup->addChild(outputGroup);
1300*35238bceSAndroid Build Coastguard Worker
1301*35238bceSAndroid Build Coastguard Worker const vector<OutputAttacher *> &outAtts = types.getOutputAttachers();
1302*35238bceSAndroid Build Coastguard Worker for (vector<OutputAttacher *>::const_iterator it = outAtts.begin(); it != outAtts.end(); ++it)
1303*35238bceSAndroid Build Coastguard Worker {
1304*35238bceSAndroid Build Coastguard Worker string name = attacherName((*it)->getAttacher());
1305*35238bceSAndroid Build Coastguard Worker outputGroup->addChild(new OutputAttachmentTest(name.c_str(), name.c_str(), **it));
1306*35238bceSAndroid Build Coastguard Worker }
1307*35238bceSAndroid Build Coastguard Worker }
1308*35238bceSAndroid Build Coastguard Worker }
1309*35238bceSAndroid Build Coastguard Worker }
1310*35238bceSAndroid Build Coastguard Worker
1311*35238bceSAndroid Build Coastguard Worker } // namespace details
1312*35238bceSAndroid Build Coastguard Worker } // namespace LifetimeTests
1313*35238bceSAndroid Build Coastguard Worker } // namespace gls
1314*35238bceSAndroid Build Coastguard Worker } // namespace deqp
1315