1e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * drawElements Quality Program OpenGL ES 3.1 Module
3e5c31af7Sopenharmony_ci * -------------------------------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project
6e5c31af7Sopenharmony_ci *
7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
10e5c31af7Sopenharmony_ci *
11e5c31af7Sopenharmony_ci *      http://www.apache.org/licenses/LICENSE-2.0
12e5c31af7Sopenharmony_ci *
13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
17e5c31af7Sopenharmony_ci * limitations under the License.
18e5c31af7Sopenharmony_ci *
19e5c31af7Sopenharmony_ci *//*!
20e5c31af7Sopenharmony_ci * \file
21e5c31af7Sopenharmony_ci * \brief Framebuffer without attachments (GL_ARB_framebuffer_no_attachments) tests.
22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci#include "es31fFboNoAttachmentTests.hpp"
25e5c31af7Sopenharmony_ci
26e5c31af7Sopenharmony_ci#include "glwDefs.hpp"
27e5c31af7Sopenharmony_ci#include "glwEnums.hpp"
28e5c31af7Sopenharmony_ci#include "glwFunctions.hpp"
29e5c31af7Sopenharmony_ci
30e5c31af7Sopenharmony_ci#include "gluRenderContext.hpp"
31e5c31af7Sopenharmony_ci#include "gluDefs.hpp"
32e5c31af7Sopenharmony_ci#include "gluShaderProgram.hpp"
33e5c31af7Sopenharmony_ci
34e5c31af7Sopenharmony_ci#include "tcuTestContext.hpp"
35e5c31af7Sopenharmony_ci#include "tcuVectorType.hpp"
36e5c31af7Sopenharmony_ci#include "tcuVectorUtil.hpp"
37e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp"
38e5c31af7Sopenharmony_ci#include "tcuCommandLine.hpp"
39e5c31af7Sopenharmony_ci#include "tcuResultCollector.hpp"
40e5c31af7Sopenharmony_ci
41e5c31af7Sopenharmony_ci#include "deMemory.h"
42e5c31af7Sopenharmony_ci#include "deRandom.hpp"
43e5c31af7Sopenharmony_ci#include "deString.h"
44e5c31af7Sopenharmony_ci#include "deStringUtil.hpp"
45e5c31af7Sopenharmony_ci
46e5c31af7Sopenharmony_ci#include <string>
47e5c31af7Sopenharmony_ci#include <vector>
48e5c31af7Sopenharmony_ci
49e5c31af7Sopenharmony_cinamespace deqp
50e5c31af7Sopenharmony_ci{
51e5c31af7Sopenharmony_cinamespace gles31
52e5c31af7Sopenharmony_ci{
53e5c31af7Sopenharmony_cinamespace Functional
54e5c31af7Sopenharmony_ci{
55e5c31af7Sopenharmony_cinamespace
56e5c31af7Sopenharmony_ci{
57e5c31af7Sopenharmony_ci
58e5c31af7Sopenharmony_ciusing namespace glw;
59e5c31af7Sopenharmony_ci
60e5c31af7Sopenharmony_ciusing tcu::IVec2;
61e5c31af7Sopenharmony_ciusing tcu::TestLog;
62e5c31af7Sopenharmony_ci
63e5c31af7Sopenharmony_ciusing std::stringstream;
64e5c31af7Sopenharmony_ciusing std::string;
65e5c31af7Sopenharmony_ciusing std::vector;
66e5c31af7Sopenharmony_ci
67e5c31af7Sopenharmony_cibool checkFramebufferSize (TestLog& log, const glu::RenderContext& renderCtx, GLuint framebuffer, const IVec2& size)
68e5c31af7Sopenharmony_ci{
69e5c31af7Sopenharmony_ci	const glw::Functions&		gl				= renderCtx.getFunctions();
70e5c31af7Sopenharmony_ci
71e5c31af7Sopenharmony_ci	const char* const			vertexSource	= "#version 310 es\n"
72e5c31af7Sopenharmony_ci												  "in layout(location = 0) highp vec2 a_position;\n\n"
73e5c31af7Sopenharmony_ci												  "void main()\n"
74e5c31af7Sopenharmony_ci												  "{\n"
75e5c31af7Sopenharmony_ci												  "	gl_Position = vec4(a_position, 0.0, 1.0);\n"
76e5c31af7Sopenharmony_ci												  "}\n";
77e5c31af7Sopenharmony_ci
78e5c31af7Sopenharmony_ci	const char* const			fragmentSource	= "#version 310 es\n"
79e5c31af7Sopenharmony_ci												  "uniform layout(location = 0) highp ivec2 u_expectedSize;\n"
80e5c31af7Sopenharmony_ci												  "out layout(location = 0) mediump vec4 f_color;\n\n"
81e5c31af7Sopenharmony_ci												  "void main()\n"
82e5c31af7Sopenharmony_ci												  "{\n"
83e5c31af7Sopenharmony_ci												  "	if (ivec2(gl_FragCoord.xy) != u_expectedSize) discard;\n"
84e5c31af7Sopenharmony_ci												  "	f_color = vec4(1.0, 0.5, 0.25, 1.0);\n"
85e5c31af7Sopenharmony_ci												  "}\n";
86e5c31af7Sopenharmony_ci
87e5c31af7Sopenharmony_ci	const glu::ShaderProgram	program			(renderCtx, glu::makeVtxFragSources(vertexSource, fragmentSource));
88e5c31af7Sopenharmony_ci	GLuint						query			= 0;
89e5c31af7Sopenharmony_ci	GLuint						insidePassed	= 0;
90e5c31af7Sopenharmony_ci	GLuint						outsideXPassed	= 0;
91e5c31af7Sopenharmony_ci	GLuint						outsideYPassed	= 0;
92e5c31af7Sopenharmony_ci
93e5c31af7Sopenharmony_ci	if (!program.isOk())
94e5c31af7Sopenharmony_ci		log << program;
95e5c31af7Sopenharmony_ci
96e5c31af7Sopenharmony_ci	TCU_CHECK(program.isOk());
97e5c31af7Sopenharmony_ci
98e5c31af7Sopenharmony_ci	gl.useProgram(program.getProgram());
99e5c31af7Sopenharmony_ci	gl.enable(GL_DEPTH_TEST);
100e5c31af7Sopenharmony_ci	gl.depthFunc(GL_ALWAYS);
101e5c31af7Sopenharmony_ci	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
102e5c31af7Sopenharmony_ci	gl.viewport(0, 0, size.x()*2, size.y()*2); // Oversized viewport so that it will not accidentally limit us to the correct size
103e5c31af7Sopenharmony_ci
104e5c31af7Sopenharmony_ci	log << TestLog::Message << "Using " << size.x()*2 << "x" << size.y()*2 << " viewport" << TestLog::EndMessage;
105e5c31af7Sopenharmony_ci	log << TestLog::Message << "Discarding fragments outside pixel of interest" << TestLog::EndMessage;
106e5c31af7Sopenharmony_ci	log << TestLog::Message << "Using occlusion query to check for rendered fragments" << TestLog::EndMessage;
107e5c31af7Sopenharmony_ci
108e5c31af7Sopenharmony_ci	TCU_CHECK(gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
109e5c31af7Sopenharmony_ci
110e5c31af7Sopenharmony_ci	// Render
111e5c31af7Sopenharmony_ci	{
112e5c31af7Sopenharmony_ci		const float data[] =
113e5c31af7Sopenharmony_ci		{
114e5c31af7Sopenharmony_ci			 1.0f,  1.0f,
115e5c31af7Sopenharmony_ci			 1.0f, -1.0f,
116e5c31af7Sopenharmony_ci			-1.0f,  1.0f,
117e5c31af7Sopenharmony_ci			-1.0f,  1.0f,
118e5c31af7Sopenharmony_ci			 1.0f, -1.0f,
119e5c31af7Sopenharmony_ci			-1.0f, -1.0f,
120e5c31af7Sopenharmony_ci		};
121e5c31af7Sopenharmony_ci
122e5c31af7Sopenharmony_ci		GLuint vertexArray	= 0;
123e5c31af7Sopenharmony_ci		GLuint vertexBuffer	= 0;
124e5c31af7Sopenharmony_ci
125e5c31af7Sopenharmony_ci		gl.genQueries(1, &query);
126e5c31af7Sopenharmony_ci		gl.genVertexArrays(1, &vertexArray);
127e5c31af7Sopenharmony_ci		gl.bindVertexArray(vertexArray);
128e5c31af7Sopenharmony_ci
129e5c31af7Sopenharmony_ci		gl.genBuffers(1, &vertexBuffer);
130e5c31af7Sopenharmony_ci		gl.bindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
131e5c31af7Sopenharmony_ci		gl.bufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
132e5c31af7Sopenharmony_ci
133e5c31af7Sopenharmony_ci		gl.enableVertexAttribArray(0);
134e5c31af7Sopenharmony_ci		gl.vertexAttribPointer(0, 2, GL_FLOAT, false, 0, DE_NULL);
135e5c31af7Sopenharmony_ci
136e5c31af7Sopenharmony_ci		gl.uniform2i(0, size.x()-1, size.y()-1);
137e5c31af7Sopenharmony_ci		gl.beginQuery(GL_ANY_SAMPLES_PASSED, query);
138e5c31af7Sopenharmony_ci		gl.drawArrays(GL_TRIANGLES, 0, 6);
139e5c31af7Sopenharmony_ci		gl.endQuery(GL_ANY_SAMPLES_PASSED);
140e5c31af7Sopenharmony_ci		gl.getQueryObjectuiv(query, GL_QUERY_RESULT, &insidePassed);
141e5c31af7Sopenharmony_ci		log << TestLog::Message << "A fragment was not discarded at (" << size.x()-1 << ", " << size.y()-1 << "). "
142e5c31af7Sopenharmony_ci			<< "Occlusion query reports it was " << (insidePassed > 0 ? "rendered." : "not rendered") << TestLog::EndMessage;
143e5c31af7Sopenharmony_ci
144e5c31af7Sopenharmony_ci		gl.uniform2i(0, size.x(), size.y()-1);
145e5c31af7Sopenharmony_ci		gl.beginQuery(GL_ANY_SAMPLES_PASSED, query);
146e5c31af7Sopenharmony_ci		gl.drawArrays(GL_TRIANGLES, 0, 6);
147e5c31af7Sopenharmony_ci		gl.endQuery(GL_ANY_SAMPLES_PASSED);
148e5c31af7Sopenharmony_ci		gl.getQueryObjectuiv(query, GL_QUERY_RESULT, &outsideXPassed);
149e5c31af7Sopenharmony_ci		log << TestLog::Message << "A fragment was not discarded at (" << size.x() << ", " << size.y()-1 << "). "
150e5c31af7Sopenharmony_ci			<< "Occlusion query reports it was " << (outsideXPassed > 0 ? "rendered." : "not rendered") << TestLog::EndMessage;
151e5c31af7Sopenharmony_ci
152e5c31af7Sopenharmony_ci		gl.uniform2i(0, size.x()-1, size.y());
153e5c31af7Sopenharmony_ci		gl.beginQuery(GL_ANY_SAMPLES_PASSED, query);
154e5c31af7Sopenharmony_ci		gl.drawArrays(GL_TRIANGLES, 0, 6);
155e5c31af7Sopenharmony_ci		gl.endQuery(GL_ANY_SAMPLES_PASSED);
156e5c31af7Sopenharmony_ci		gl.getQueryObjectuiv(query, GL_QUERY_RESULT, &outsideYPassed);
157e5c31af7Sopenharmony_ci		log << TestLog::Message << "A fragment was not discarded at (" << size.x()-1 << ", " << size.y() << "). "
158e5c31af7Sopenharmony_ci			<< "Occlusion query reports it was " << (outsideYPassed > 0 ? "rendered." : "not rendered") << TestLog::EndMessage;
159e5c31af7Sopenharmony_ci
160e5c31af7Sopenharmony_ci		gl.disableVertexAttribArray(0);
161e5c31af7Sopenharmony_ci		gl.bindBuffer(GL_ARRAY_BUFFER, 0);
162e5c31af7Sopenharmony_ci		gl.bindVertexArray(0);
163e5c31af7Sopenharmony_ci		gl.deleteBuffers(1, &vertexBuffer);
164e5c31af7Sopenharmony_ci		gl.deleteVertexArrays(1, &vertexArray);
165e5c31af7Sopenharmony_ci	}
166e5c31af7Sopenharmony_ci
167e5c31af7Sopenharmony_ci	gl.deleteQueries(1, &query);
168e5c31af7Sopenharmony_ci
169e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "Query failed");
170e5c31af7Sopenharmony_ci
171e5c31af7Sopenharmony_ci	return insidePassed && !outsideXPassed && !outsideYPassed;
172e5c31af7Sopenharmony_ci}
173e5c31af7Sopenharmony_ci
174e5c31af7Sopenharmony_cibool checkFramebufferRenderable (TestLog& log, const glu::RenderContext& renderCtx, GLuint framebuffer, const IVec2& size)
175e5c31af7Sopenharmony_ci{
176e5c31af7Sopenharmony_ci	const glw::Functions&		gl				= renderCtx.getFunctions();
177e5c31af7Sopenharmony_ci
178e5c31af7Sopenharmony_ci	const char* const			vertexSource	= "#version 310 es\n"
179e5c31af7Sopenharmony_ci												  "in layout(location = 0) highp vec2 a_position;\n\n"
180e5c31af7Sopenharmony_ci												  "void main()\n"
181e5c31af7Sopenharmony_ci												  "{\n"
182e5c31af7Sopenharmony_ci												  "	gl_Position = vec4(a_position, 0.0, 1.0);\n"
183e5c31af7Sopenharmony_ci												  "}\n";
184e5c31af7Sopenharmony_ci
185e5c31af7Sopenharmony_ci	const char* const			fragmentSource	= "#version 310 es\n"
186e5c31af7Sopenharmony_ci												  "out layout(location = 0) mediump vec4 f_color;\n\n"
187e5c31af7Sopenharmony_ci												  "void main()\n"
188e5c31af7Sopenharmony_ci												  "{\n"
189e5c31af7Sopenharmony_ci												  "	f_color = vec4(1.0, 0.5, 0.25, 1.0);\n"
190e5c31af7Sopenharmony_ci												  "}\n";
191e5c31af7Sopenharmony_ci
192e5c31af7Sopenharmony_ci	const glu::ShaderProgram	program			(renderCtx, glu::makeVtxFragSources(vertexSource, fragmentSource));
193e5c31af7Sopenharmony_ci	GLuint						query			= 0;
194e5c31af7Sopenharmony_ci
195e5c31af7Sopenharmony_ci	if (!program.isOk())
196e5c31af7Sopenharmony_ci		log << program;
197e5c31af7Sopenharmony_ci
198e5c31af7Sopenharmony_ci	TCU_CHECK(program.isOk());
199e5c31af7Sopenharmony_ci
200e5c31af7Sopenharmony_ci	gl.useProgram(program.getProgram());
201e5c31af7Sopenharmony_ci	gl.enable(GL_DEPTH_TEST);
202e5c31af7Sopenharmony_ci	gl.depthFunc(GL_ALWAYS);
203e5c31af7Sopenharmony_ci	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
204e5c31af7Sopenharmony_ci	gl.viewport(0, 0, size.x(), size.y());
205e5c31af7Sopenharmony_ci
206e5c31af7Sopenharmony_ci	TCU_CHECK(gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
207e5c31af7Sopenharmony_ci
208e5c31af7Sopenharmony_ci	log << TestLog::Message << "Rendering full framebuffer quad with color ouput, verifying output presence with occlusion query" << TestLog::EndMessage;
209e5c31af7Sopenharmony_ci
210e5c31af7Sopenharmony_ci	// Render
211e5c31af7Sopenharmony_ci	{
212e5c31af7Sopenharmony_ci		const float data[] =
213e5c31af7Sopenharmony_ci		{
214e5c31af7Sopenharmony_ci			 1.0f,  1.0f,
215e5c31af7Sopenharmony_ci			 1.0f, -1.0f,
216e5c31af7Sopenharmony_ci			-1.0f,  1.0f,
217e5c31af7Sopenharmony_ci			-1.0f,  1.0f,
218e5c31af7Sopenharmony_ci			 1.0f, -1.0f,
219e5c31af7Sopenharmony_ci			-1.0f, -1.0f,
220e5c31af7Sopenharmony_ci		};
221e5c31af7Sopenharmony_ci
222e5c31af7Sopenharmony_ci		GLuint vertexArray	= 0;
223e5c31af7Sopenharmony_ci		GLuint vertexBuffer	= 0;
224e5c31af7Sopenharmony_ci
225e5c31af7Sopenharmony_ci		gl.genQueries(1, &query);
226e5c31af7Sopenharmony_ci		gl.genVertexArrays(1, &vertexArray);
227e5c31af7Sopenharmony_ci		gl.bindVertexArray(vertexArray);
228e5c31af7Sopenharmony_ci
229e5c31af7Sopenharmony_ci		gl.genBuffers(1, &vertexBuffer);
230e5c31af7Sopenharmony_ci		gl.bindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
231e5c31af7Sopenharmony_ci		gl.bufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
232e5c31af7Sopenharmony_ci
233e5c31af7Sopenharmony_ci		gl.enableVertexAttribArray(0);
234e5c31af7Sopenharmony_ci		gl.vertexAttribPointer(0, 2, GL_FLOAT, false, 0, DE_NULL);
235e5c31af7Sopenharmony_ci
236e5c31af7Sopenharmony_ci		gl.beginQuery(GL_ANY_SAMPLES_PASSED, query);
237e5c31af7Sopenharmony_ci		gl.drawArrays(GL_TRIANGLES, 0, 6);
238e5c31af7Sopenharmony_ci		gl.endQuery(GL_ANY_SAMPLES_PASSED);
239e5c31af7Sopenharmony_ci
240e5c31af7Sopenharmony_ci		gl.disableVertexAttribArray(0);
241e5c31af7Sopenharmony_ci		gl.bindBuffer(GL_ARRAY_BUFFER, 0);
242e5c31af7Sopenharmony_ci		gl.bindVertexArray(0);
243e5c31af7Sopenharmony_ci		gl.deleteBuffers(1, &vertexBuffer);
244e5c31af7Sopenharmony_ci		gl.deleteVertexArrays(1, &vertexArray);
245e5c31af7Sopenharmony_ci	}
246e5c31af7Sopenharmony_ci
247e5c31af7Sopenharmony_ci	// Read
248e5c31af7Sopenharmony_ci	{
249e5c31af7Sopenharmony_ci		GLuint passed = 0;
250e5c31af7Sopenharmony_ci
251e5c31af7Sopenharmony_ci		gl.getQueryObjectuiv(query, GL_QUERY_RESULT, &passed);
252e5c31af7Sopenharmony_ci		gl.deleteQueries(1, &query);
253e5c31af7Sopenharmony_ci
254e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "Query failed");
255e5c31af7Sopenharmony_ci
256e5c31af7Sopenharmony_ci		if (passed)
257e5c31af7Sopenharmony_ci			log << TestLog::Message << "Query passed" << TestLog::EndMessage;
258e5c31af7Sopenharmony_ci		else
259e5c31af7Sopenharmony_ci			log << TestLog::Message << "Query did not pass" << TestLog::EndMessage;
260e5c31af7Sopenharmony_ci
261e5c31af7Sopenharmony_ci		return passed != 0;
262e5c31af7Sopenharmony_ci	}
263e5c31af7Sopenharmony_ci}
264e5c31af7Sopenharmony_ci
265e5c31af7Sopenharmony_ciclass FramebufferCompletenessCase : public tcu::TestCase
266e5c31af7Sopenharmony_ci{
267e5c31af7Sopenharmony_cipublic:
268e5c31af7Sopenharmony_ci								FramebufferCompletenessCase		(tcu::TestContext&			testCtx,
269e5c31af7Sopenharmony_ci																 const glu::RenderContext&	renderCtx,
270e5c31af7Sopenharmony_ci																 const char*				name,
271e5c31af7Sopenharmony_ci																 const char*				desc);
272e5c31af7Sopenharmony_ci	virtual						~FramebufferCompletenessCase	 (void) {}
273e5c31af7Sopenharmony_ci	virtual IterateResult		iterate							(void);
274e5c31af7Sopenharmony_ci
275e5c31af7Sopenharmony_ciprivate:
276e5c31af7Sopenharmony_ci	const glu::RenderContext&	m_renderCtx;
277e5c31af7Sopenharmony_ci	tcu::ResultCollector		m_results;
278e5c31af7Sopenharmony_ci};
279e5c31af7Sopenharmony_ci
280e5c31af7Sopenharmony_ciFramebufferCompletenessCase::FramebufferCompletenessCase (tcu::TestContext&			testCtx,
281e5c31af7Sopenharmony_ci														  const glu::RenderContext&	renderCtx,
282e5c31af7Sopenharmony_ci														  const char*				name,
283e5c31af7Sopenharmony_ci														  const char*				desc)
284e5c31af7Sopenharmony_ci	: TestCase		(testCtx, name, desc)
285e5c31af7Sopenharmony_ci	, m_renderCtx	(renderCtx)
286e5c31af7Sopenharmony_ci{
287e5c31af7Sopenharmony_ci}
288e5c31af7Sopenharmony_ci
289e5c31af7Sopenharmony_ciFramebufferCompletenessCase::IterateResult FramebufferCompletenessCase::iterate (void)
290e5c31af7Sopenharmony_ci{
291e5c31af7Sopenharmony_ci	const glw::Functions&	gl			= m_renderCtx.getFunctions();
292e5c31af7Sopenharmony_ci	GLuint					framebuffer	= 0;
293e5c31af7Sopenharmony_ci
294e5c31af7Sopenharmony_ci	gl.genFramebuffers(1, &framebuffer);
295e5c31af7Sopenharmony_ci	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
296e5c31af7Sopenharmony_ci
297e5c31af7Sopenharmony_ci	m_results.check(gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, "Framebuffer was incorrectly reported as complete when it had no width, height or attachments");
298e5c31af7Sopenharmony_ci
299e5c31af7Sopenharmony_ci	gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 16);
300e5c31af7Sopenharmony_ci	m_results.check(gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, "Framebuffer was incorrectly reported as complete when it only had a width");
301e5c31af7Sopenharmony_ci
302e5c31af7Sopenharmony_ci	gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, 16);
303e5c31af7Sopenharmony_ci	m_results.check(gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, "Framebuffer not reported as complete when it had width and height set");
304e5c31af7Sopenharmony_ci
305e5c31af7Sopenharmony_ci	gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 0);
306e5c31af7Sopenharmony_ci	m_results.check(gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, "Framebuffer was incorrectly reported as complete when it only had a height");
307e5c31af7Sopenharmony_ci
308e5c31af7Sopenharmony_ci	gl.deleteFramebuffers(1, &framebuffer);
309e5c31af7Sopenharmony_ci
310e5c31af7Sopenharmony_ci	m_results.setTestContextResult(m_testCtx);
311e5c31af7Sopenharmony_ci	return STOP;
312e5c31af7Sopenharmony_ci}
313e5c31af7Sopenharmony_ci
314e5c31af7Sopenharmony_cistruct FboSpec
315e5c31af7Sopenharmony_ci{
316e5c31af7Sopenharmony_ci	int width;
317e5c31af7Sopenharmony_ci	int height;
318e5c31af7Sopenharmony_ci	int samples;
319e5c31af7Sopenharmony_ci
320e5c31af7Sopenharmony_ci	FboSpec(int width_, int height_, int samples_) : width(width_), height(height_), samples(samples_){}
321e5c31af7Sopenharmony_ci};
322e5c31af7Sopenharmony_ci
323e5c31af7Sopenharmony_ciclass SizeCase : public tcu::TestCase
324e5c31af7Sopenharmony_ci{
325e5c31af7Sopenharmony_cipublic:
326e5c31af7Sopenharmony_ci								SizeCase	(tcu::TestContext&			testCtx,
327e5c31af7Sopenharmony_ci											 const glu::RenderContext&	renderCtx,
328e5c31af7Sopenharmony_ci											 const char*				name,
329e5c31af7Sopenharmony_ci											 const char*				desc,
330e5c31af7Sopenharmony_ci											 const FboSpec&				spec);
331e5c31af7Sopenharmony_ci	virtual						~SizeCase	(void) {}
332e5c31af7Sopenharmony_ci
333e5c31af7Sopenharmony_ci	virtual IterateResult		iterate		(void);
334e5c31af7Sopenharmony_ci
335e5c31af7Sopenharmony_ci	enum
336e5c31af7Sopenharmony_ci	{
337e5c31af7Sopenharmony_ci		USE_MAXIMUM = -1
338e5c31af7Sopenharmony_ci	};
339e5c31af7Sopenharmony_ciprivate:
340e5c31af7Sopenharmony_ci	int							getWidth	(void) const;
341e5c31af7Sopenharmony_ci	int							getHeight	(void) const;
342e5c31af7Sopenharmony_ci	int							getSamples	(void) const;
343e5c31af7Sopenharmony_ci
344e5c31af7Sopenharmony_ci	const glu::RenderContext&	m_renderCtx;
345e5c31af7Sopenharmony_ci
346e5c31af7Sopenharmony_ci	const FboSpec				m_spec;
347e5c31af7Sopenharmony_ci};
348e5c31af7Sopenharmony_ci
349e5c31af7Sopenharmony_ciSizeCase::SizeCase (tcu::TestContext&			testCtx,
350e5c31af7Sopenharmony_ci					const glu::RenderContext&	renderCtx,
351e5c31af7Sopenharmony_ci					const char*					name,
352e5c31af7Sopenharmony_ci					const char*					desc,
353e5c31af7Sopenharmony_ci					const FboSpec&				spec)
354e5c31af7Sopenharmony_ci	: TestCase		(testCtx, name, desc)
355e5c31af7Sopenharmony_ci	, m_renderCtx	(renderCtx)
356e5c31af7Sopenharmony_ci	, m_spec		(spec)
357e5c31af7Sopenharmony_ci{
358e5c31af7Sopenharmony_ci}
359e5c31af7Sopenharmony_ci
360e5c31af7Sopenharmony_ciSizeCase::IterateResult SizeCase::iterate (void)
361e5c31af7Sopenharmony_ci{
362e5c31af7Sopenharmony_ci	const glw::Functions&	gl			= m_renderCtx.getFunctions();
363e5c31af7Sopenharmony_ci	TestLog&				log			= m_testCtx.getLog();
364e5c31af7Sopenharmony_ci	GLuint					framebuffer	= 0;
365e5c31af7Sopenharmony_ci	const int				width		= getWidth();
366e5c31af7Sopenharmony_ci	const int				height		= getHeight();
367e5c31af7Sopenharmony_ci	int						samples		= getSamples();
368e5c31af7Sopenharmony_ci
369e5c31af7Sopenharmony_ci	for (;;) {
370e5c31af7Sopenharmony_ci		gl.genFramebuffers(1, &framebuffer);
371e5c31af7Sopenharmony_ci		gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
372e5c31af7Sopenharmony_ci		gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, width);
373e5c31af7Sopenharmony_ci		gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, height);
374e5c31af7Sopenharmony_ci		gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_SAMPLES, samples);
375e5c31af7Sopenharmony_ci
376e5c31af7Sopenharmony_ci		GLenum status = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
377e5c31af7Sopenharmony_ci		if (status == GL_FRAMEBUFFER_COMPLETE)
378e5c31af7Sopenharmony_ci			break;
379e5c31af7Sopenharmony_ci		else
380e5c31af7Sopenharmony_ci		{
381e5c31af7Sopenharmony_ci			gl.deleteFramebuffers(1, &framebuffer);
382e5c31af7Sopenharmony_ci			framebuffer = 0;
383e5c31af7Sopenharmony_ci
384e5c31af7Sopenharmony_ci			if (status == GL_FRAMEBUFFER_UNSUPPORTED)
385e5c31af7Sopenharmony_ci				if (samples >= 2)
386e5c31af7Sopenharmony_ci					samples /= 2;
387e5c31af7Sopenharmony_ci				else
388e5c31af7Sopenharmony_ci					break;
389e5c31af7Sopenharmony_ci			else
390e5c31af7Sopenharmony_ci			{
391e5c31af7Sopenharmony_ci				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected no-attachment framebuffer status");
392e5c31af7Sopenharmony_ci				return STOP;
393e5c31af7Sopenharmony_ci			}
394e5c31af7Sopenharmony_ci		}
395e5c31af7Sopenharmony_ci	}
396e5c31af7Sopenharmony_ci	if (!framebuffer)
397e5c31af7Sopenharmony_ci	{
398e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unable to find a supported no-attachment framebuffer width/height/samples");
399e5c31af7Sopenharmony_ci		return STOP;
400e5c31af7Sopenharmony_ci	}
401e5c31af7Sopenharmony_ci
402e5c31af7Sopenharmony_ci	log << TestLog::Message << "Verifying " << width << "x" << height << " framebuffer with " << samples << "x multisampling" << TestLog::EndMessage;
403e5c31af7Sopenharmony_ci
404e5c31af7Sopenharmony_ci	if(checkFramebufferRenderable(log, m_renderCtx, framebuffer, IVec2(width, height)) && checkFramebufferSize(log, m_renderCtx, framebuffer, IVec2(width, height)))
405e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
406e5c31af7Sopenharmony_ci	else
407e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Framebuffer did not behave as expected");
408e5c31af7Sopenharmony_ci
409e5c31af7Sopenharmony_ci	gl.deleteFramebuffers(1, &framebuffer);
410e5c31af7Sopenharmony_ci
411e5c31af7Sopenharmony_ci	return STOP;
412e5c31af7Sopenharmony_ci}
413e5c31af7Sopenharmony_ci
414e5c31af7Sopenharmony_ciint SizeCase::getWidth (void) const
415e5c31af7Sopenharmony_ci{
416e5c31af7Sopenharmony_ci	if (m_spec.width != USE_MAXIMUM)
417e5c31af7Sopenharmony_ci		return m_spec.width;
418e5c31af7Sopenharmony_ci	else
419e5c31af7Sopenharmony_ci	{
420e5c31af7Sopenharmony_ci		const glw::Functions&	gl		= m_renderCtx.getFunctions();
421e5c31af7Sopenharmony_ci		GLint					width	= 0;
422e5c31af7Sopenharmony_ci
423e5c31af7Sopenharmony_ci		gl.getIntegerv(GL_MAX_FRAMEBUFFER_WIDTH, &width);
424e5c31af7Sopenharmony_ci
425e5c31af7Sopenharmony_ci		return width;
426e5c31af7Sopenharmony_ci	}
427e5c31af7Sopenharmony_ci}
428e5c31af7Sopenharmony_ci
429e5c31af7Sopenharmony_ciint SizeCase::getHeight (void) const
430e5c31af7Sopenharmony_ci{
431e5c31af7Sopenharmony_ci	if (m_spec.height != USE_MAXIMUM)
432e5c31af7Sopenharmony_ci		return m_spec.height;
433e5c31af7Sopenharmony_ci	else
434e5c31af7Sopenharmony_ci	{
435e5c31af7Sopenharmony_ci		const glw::Functions&	gl		= m_renderCtx.getFunctions();
436e5c31af7Sopenharmony_ci		GLint					height	= 0;
437e5c31af7Sopenharmony_ci
438e5c31af7Sopenharmony_ci		gl.getIntegerv(GL_MAX_FRAMEBUFFER_HEIGHT, &height);
439e5c31af7Sopenharmony_ci
440e5c31af7Sopenharmony_ci		return height;
441e5c31af7Sopenharmony_ci	}
442e5c31af7Sopenharmony_ci}
443e5c31af7Sopenharmony_ci
444e5c31af7Sopenharmony_ciint SizeCase::getSamples (void) const
445e5c31af7Sopenharmony_ci{
446e5c31af7Sopenharmony_ci	if (m_spec.samples != USE_MAXIMUM)
447e5c31af7Sopenharmony_ci		return m_spec.samples;
448e5c31af7Sopenharmony_ci	else
449e5c31af7Sopenharmony_ci	{
450e5c31af7Sopenharmony_ci		const glw::Functions&	gl		= m_renderCtx.getFunctions();
451e5c31af7Sopenharmony_ci		GLint					samples	= 0;
452e5c31af7Sopenharmony_ci
453e5c31af7Sopenharmony_ci		gl.getIntegerv(GL_MAX_FRAMEBUFFER_SAMPLES, &samples);
454e5c31af7Sopenharmony_ci
455e5c31af7Sopenharmony_ci		return samples;
456e5c31af7Sopenharmony_ci	}
457e5c31af7Sopenharmony_ci}
458e5c31af7Sopenharmony_ci
459e5c31af7Sopenharmony_ciclass AttachmentInteractionCase : public tcu::TestCase
460e5c31af7Sopenharmony_ci{
461e5c31af7Sopenharmony_cipublic:
462e5c31af7Sopenharmony_ci								AttachmentInteractionCase	(tcu::TestContext&			testCtx,
463e5c31af7Sopenharmony_ci															 const glu::RenderContext&	renderCtx,
464e5c31af7Sopenharmony_ci															 const char*				name,
465e5c31af7Sopenharmony_ci															 const char*				desc,
466e5c31af7Sopenharmony_ci															 const FboSpec&				defaultSpec,
467e5c31af7Sopenharmony_ci															 const FboSpec&				attachmentSpec);
468e5c31af7Sopenharmony_ci	virtual						~AttachmentInteractionCase	(void) {}
469e5c31af7Sopenharmony_ci
470e5c31af7Sopenharmony_ci	virtual IterateResult		iterate						(void);
471e5c31af7Sopenharmony_ci
472e5c31af7Sopenharmony_ciprivate:
473e5c31af7Sopenharmony_ci	const glu::RenderContext&	m_renderCtx;
474e5c31af7Sopenharmony_ci	const FboSpec				m_defaultSpec;
475e5c31af7Sopenharmony_ci	const FboSpec				m_attachmentSpec;
476e5c31af7Sopenharmony_ci};
477e5c31af7Sopenharmony_ci
478e5c31af7Sopenharmony_ciAttachmentInteractionCase::AttachmentInteractionCase (tcu::TestContext&			testCtx,
479e5c31af7Sopenharmony_ci													  const glu::RenderContext&	renderCtx,
480e5c31af7Sopenharmony_ci													  const char*				name,
481e5c31af7Sopenharmony_ci													  const char*				desc,
482e5c31af7Sopenharmony_ci													  const FboSpec&			defaultSpec,
483e5c31af7Sopenharmony_ci													  const FboSpec&			attachmentSpec)
484e5c31af7Sopenharmony_ci	: TestCase			(testCtx, name, desc)
485e5c31af7Sopenharmony_ci	, m_renderCtx		(renderCtx)
486e5c31af7Sopenharmony_ci	, m_defaultSpec		(defaultSpec)
487e5c31af7Sopenharmony_ci	, m_attachmentSpec	(attachmentSpec)
488e5c31af7Sopenharmony_ci{
489e5c31af7Sopenharmony_ci}
490e5c31af7Sopenharmony_ci
491e5c31af7Sopenharmony_ciAttachmentInteractionCase::IterateResult AttachmentInteractionCase::iterate (void)
492e5c31af7Sopenharmony_ci{
493e5c31af7Sopenharmony_ci	const glw::Functions&	gl			= m_renderCtx.getFunctions();
494e5c31af7Sopenharmony_ci	TestLog&				log			= m_testCtx.getLog();
495e5c31af7Sopenharmony_ci	GLuint					framebuffer	= 0;
496e5c31af7Sopenharmony_ci	GLuint					renderbuffer= 0;
497e5c31af7Sopenharmony_ci
498e5c31af7Sopenharmony_ci	gl.genFramebuffers(1, &framebuffer);
499e5c31af7Sopenharmony_ci	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
500e5c31af7Sopenharmony_ci	gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, m_defaultSpec.width);
501e5c31af7Sopenharmony_ci	gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, m_defaultSpec.height);
502e5c31af7Sopenharmony_ci	gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_SAMPLES, m_defaultSpec.samples);
503e5c31af7Sopenharmony_ci
504e5c31af7Sopenharmony_ci	gl.genRenderbuffers(1, &renderbuffer);
505e5c31af7Sopenharmony_ci	gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
506e5c31af7Sopenharmony_ci	gl.renderbufferStorageMultisample(GL_RENDERBUFFER, m_attachmentSpec.samples, GL_RGBA8, m_attachmentSpec.width, m_attachmentSpec.height);
507e5c31af7Sopenharmony_ci	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
508e5c31af7Sopenharmony_ci
509e5c31af7Sopenharmony_ci	log << TestLog::Message << "Verifying " << m_attachmentSpec.width << "x" << m_attachmentSpec.height << " framebuffer with " << m_attachmentSpec.samples << "x multisampling"
510e5c31af7Sopenharmony_ci		<< " and defaults set to " << m_defaultSpec.width << "x" << m_defaultSpec.height << " with " << m_defaultSpec.samples << "x multisampling" << TestLog::EndMessage;
511e5c31af7Sopenharmony_ci
512e5c31af7Sopenharmony_ci	if(checkFramebufferRenderable(log, m_renderCtx, framebuffer, IVec2(m_attachmentSpec.width, m_attachmentSpec.height))
513e5c31af7Sopenharmony_ci	   && checkFramebufferSize(log, m_renderCtx, framebuffer, IVec2(m_attachmentSpec.width, m_attachmentSpec.height)))
514e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
515e5c31af7Sopenharmony_ci	else
516e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Framebuffer did not behave as expected");
517e5c31af7Sopenharmony_ci
518e5c31af7Sopenharmony_ci	gl.deleteRenderbuffers(1, &renderbuffer);
519e5c31af7Sopenharmony_ci	gl.deleteFramebuffers(1, &framebuffer);
520e5c31af7Sopenharmony_ci
521e5c31af7Sopenharmony_ci	return STOP;
522e5c31af7Sopenharmony_ci}
523e5c31af7Sopenharmony_ci
524e5c31af7Sopenharmony_ci} // Anonymous
525e5c31af7Sopenharmony_ci
526e5c31af7Sopenharmony_citcu::TestCaseGroup* createFboNoAttachmentTests(Context& context)
527e5c31af7Sopenharmony_ci{
528e5c31af7Sopenharmony_ci	const glu::RenderContext&	renderCtx	= context.getRenderContext();
529e5c31af7Sopenharmony_ci	tcu::TestContext&			testCtx		= context.getTestContext();
530e5c31af7Sopenharmony_ci
531e5c31af7Sopenharmony_ci	const int					maxWidth	= 2048; // MAX_FRAMEBUFFER_WIDTH in ES 3.1
532e5c31af7Sopenharmony_ci	const int					maxHeight	= 2048; // MAX_FRAMEBUFFER_HEIGHT in ES 3.1
533e5c31af7Sopenharmony_ci	const int					maxSamples	= 4;
534e5c31af7Sopenharmony_ci
535e5c31af7Sopenharmony_ci	tcu::TestCaseGroup* const	root		= new tcu::TestCaseGroup(testCtx, "no_attachments", "Framebuffer without attachments");
536e5c31af7Sopenharmony_ci
537e5c31af7Sopenharmony_ci	// Size
538e5c31af7Sopenharmony_ci	{
539e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(testCtx, "size", "Basic functionality tests with varying default size");
540e5c31af7Sopenharmony_ci
541e5c31af7Sopenharmony_ci		root->addChild(group);
542e5c31af7Sopenharmony_ci
543e5c31af7Sopenharmony_ci		for (int width = 16; width <= maxWidth; width *= 4)
544e5c31af7Sopenharmony_ci		{
545e5c31af7Sopenharmony_ci			for (int height = 16; height <= maxHeight; height *= 4)
546e5c31af7Sopenharmony_ci			{
547e5c31af7Sopenharmony_ci				const FboSpec	spec (width, height, 0);
548e5c31af7Sopenharmony_ci				stringstream	name;
549e5c31af7Sopenharmony_ci
550e5c31af7Sopenharmony_ci				name << width << "x" << height;
551e5c31af7Sopenharmony_ci
552e5c31af7Sopenharmony_ci				group->addChild(new SizeCase(testCtx, renderCtx, name.str().c_str(), name.str().c_str(), spec));
553e5c31af7Sopenharmony_ci			}
554e5c31af7Sopenharmony_ci		}
555e5c31af7Sopenharmony_ci	}
556e5c31af7Sopenharmony_ci
557e5c31af7Sopenharmony_ci	// NPOT size
558e5c31af7Sopenharmony_ci	{
559e5c31af7Sopenharmony_ci		const FboSpec specs[] =
560e5c31af7Sopenharmony_ci		{
561e5c31af7Sopenharmony_ci			// Square
562e5c31af7Sopenharmony_ci			FboSpec(1,    1,    0),
563e5c31af7Sopenharmony_ci			FboSpec(3,    3,    0),
564e5c31af7Sopenharmony_ci			FboSpec(15,   15,   0),
565e5c31af7Sopenharmony_ci			FboSpec(17,   17,   0),
566e5c31af7Sopenharmony_ci			FboSpec(31,   31,   0),
567e5c31af7Sopenharmony_ci			FboSpec(33,   33,   0),
568e5c31af7Sopenharmony_ci			FboSpec(63,   63,   0),
569e5c31af7Sopenharmony_ci			FboSpec(65,   65,   0),
570e5c31af7Sopenharmony_ci			FboSpec(127,  127,  0),
571e5c31af7Sopenharmony_ci			FboSpec(129,  129,  0),
572e5c31af7Sopenharmony_ci			FboSpec(255,  255,  0),
573e5c31af7Sopenharmony_ci			FboSpec(257,  257,  0),
574e5c31af7Sopenharmony_ci			FboSpec(511,  511,  0),
575e5c31af7Sopenharmony_ci			FboSpec(513,  513,  0),
576e5c31af7Sopenharmony_ci			FboSpec(1023, 1023, 0),
577e5c31af7Sopenharmony_ci			FboSpec(1025, 1025, 0),
578e5c31af7Sopenharmony_ci			FboSpec(2047, 2047, 0),
579e5c31af7Sopenharmony_ci
580e5c31af7Sopenharmony_ci			// Non-square
581e5c31af7Sopenharmony_ci			FboSpec(15,   511,  0),
582e5c31af7Sopenharmony_ci			FboSpec(127,  15,   0),
583e5c31af7Sopenharmony_ci			FboSpec(129,  127,  0),
584e5c31af7Sopenharmony_ci			FboSpec(511,  127,  0),
585e5c31af7Sopenharmony_ci			FboSpec(2047, 1025, 0),
586e5c31af7Sopenharmony_ci		};
587e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(testCtx, "npot_size", "Basic functionality with Non-power-of-two size");
588e5c31af7Sopenharmony_ci
589e5c31af7Sopenharmony_ci		root->addChild(group);
590e5c31af7Sopenharmony_ci
591e5c31af7Sopenharmony_ci		for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(specs); caseNdx++)
592e5c31af7Sopenharmony_ci		{
593e5c31af7Sopenharmony_ci			const FboSpec&	spec = specs[caseNdx];
594e5c31af7Sopenharmony_ci			stringstream	name;
595e5c31af7Sopenharmony_ci
596e5c31af7Sopenharmony_ci			name << spec.width << "x" << spec.height;
597e5c31af7Sopenharmony_ci
598e5c31af7Sopenharmony_ci			group->addChild(new SizeCase(testCtx, renderCtx, name.str().c_str(), name.str().c_str(), spec));
599e5c31af7Sopenharmony_ci		}
600e5c31af7Sopenharmony_ci	}
601e5c31af7Sopenharmony_ci
602e5c31af7Sopenharmony_ci	// Multisample
603e5c31af7Sopenharmony_ci	{
604e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(testCtx, "multisample", "Basic functionality with multisampled fbo");
605e5c31af7Sopenharmony_ci
606e5c31af7Sopenharmony_ci		root->addChild(group);
607e5c31af7Sopenharmony_ci
608e5c31af7Sopenharmony_ci		for (int samples = 0; samples <= maxSamples; samples++)
609e5c31af7Sopenharmony_ci		{
610e5c31af7Sopenharmony_ci			const FboSpec	spec (128, 128, samples);
611e5c31af7Sopenharmony_ci			stringstream	name;
612e5c31af7Sopenharmony_ci
613e5c31af7Sopenharmony_ci			name << "samples" << samples;
614e5c31af7Sopenharmony_ci
615e5c31af7Sopenharmony_ci			group->addChild(new SizeCase(testCtx, renderCtx, name.str().c_str(), name.str().c_str(), spec));
616e5c31af7Sopenharmony_ci		}
617e5c31af7Sopenharmony_ci	}
618e5c31af7Sopenharmony_ci
619e5c31af7Sopenharmony_ci	// Randomized
620e5c31af7Sopenharmony_ci	{
621e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const	group	= new tcu::TestCaseGroup(testCtx, "random", "Randomized size & multisampling");
622e5c31af7Sopenharmony_ci		de::Random					rng		(0xF0E1E2D3 ^ testCtx.getCommandLine().getBaseSeed());
623e5c31af7Sopenharmony_ci
624e5c31af7Sopenharmony_ci		root->addChild(group);
625e5c31af7Sopenharmony_ci
626e5c31af7Sopenharmony_ci		for (int caseNdx = 0; caseNdx < 16; caseNdx++)
627e5c31af7Sopenharmony_ci		{
628e5c31af7Sopenharmony_ci			const int		width	= rng.getInt(1, maxWidth);
629e5c31af7Sopenharmony_ci			const int		height	= rng.getInt(1, maxHeight);
630e5c31af7Sopenharmony_ci			const int		samples = rng.getInt(0, maxSamples);
631e5c31af7Sopenharmony_ci			const FboSpec	spec	(width, height, samples);
632e5c31af7Sopenharmony_ci			const string	name	= de::toString(caseNdx);
633e5c31af7Sopenharmony_ci
634e5c31af7Sopenharmony_ci			group->addChild(new SizeCase(testCtx, renderCtx, name.c_str(), name.c_str(), spec));
635e5c31af7Sopenharmony_ci		}
636e5c31af7Sopenharmony_ci	}
637e5c31af7Sopenharmony_ci
638e5c31af7Sopenharmony_ci	// Normal fbo with defaults set
639e5c31af7Sopenharmony_ci	{
640e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(testCtx, "interaction", "Interaction of default parameters with normal fbo");
641e5c31af7Sopenharmony_ci
642e5c31af7Sopenharmony_ci		root->addChild(group);
643e5c31af7Sopenharmony_ci
644e5c31af7Sopenharmony_ci		const FboSpec specs[][2] =
645e5c31af7Sopenharmony_ci		{
646e5c31af7Sopenharmony_ci			{ FboSpec(256,  256,  0), FboSpec(128,  128,  1) },
647e5c31af7Sopenharmony_ci			{ FboSpec(256,  256,  1), FboSpec(128,  128,  0) },
648e5c31af7Sopenharmony_ci			{ FboSpec(256,  256,  0), FboSpec(512,  512,  2) },
649e5c31af7Sopenharmony_ci			{ FboSpec(256,  256,  2), FboSpec(128,  512,  0) },
650e5c31af7Sopenharmony_ci			{ FboSpec(127,  127,  0), FboSpec(129,  129,  0) },
651e5c31af7Sopenharmony_ci			{ FboSpec(17,   512,  4), FboSpec(16,   16,   2) },
652e5c31af7Sopenharmony_ci			{ FboSpec(2048, 2048, 4), FboSpec(1,    1,    0) },
653e5c31af7Sopenharmony_ci			{ FboSpec(1,    1,    0), FboSpec(2048, 2048, 4) },
654e5c31af7Sopenharmony_ci		};
655e5c31af7Sopenharmony_ci
656e5c31af7Sopenharmony_ci		for (int specNdx = 0; specNdx < DE_LENGTH_OF_ARRAY(specs); specNdx++)
657e5c31af7Sopenharmony_ci		{
658e5c31af7Sopenharmony_ci			const FboSpec& baseSpec = specs[specNdx][0];
659e5c31af7Sopenharmony_ci			const FboSpec& altSpec	= specs[specNdx][1];
660e5c31af7Sopenharmony_ci			stringstream baseSpecName, altSpecName;
661e5c31af7Sopenharmony_ci
662e5c31af7Sopenharmony_ci			baseSpecName << baseSpec.width << "x" << baseSpec.height << "ms" << baseSpec.samples;
663e5c31af7Sopenharmony_ci			altSpecName << altSpec.width << "x" << altSpec.height << "ms" << altSpec.samples;
664e5c31af7Sopenharmony_ci
665e5c31af7Sopenharmony_ci			{
666e5c31af7Sopenharmony_ci				const string name = baseSpecName.str() + "_default_" + altSpecName.str();
667e5c31af7Sopenharmony_ci
668e5c31af7Sopenharmony_ci				group->addChild(new AttachmentInteractionCase(testCtx, renderCtx, name.c_str(), name.c_str(), altSpec, baseSpec));
669e5c31af7Sopenharmony_ci			}
670e5c31af7Sopenharmony_ci		}
671e5c31af7Sopenharmony_ci	}
672e5c31af7Sopenharmony_ci
673e5c31af7Sopenharmony_ci	// Maximums
674e5c31af7Sopenharmony_ci	{
675e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const	group	= new tcu::TestCaseGroup(testCtx, "maximums", "Maximum dimensions");
676e5c31af7Sopenharmony_ci
677e5c31af7Sopenharmony_ci		root->addChild(group);
678e5c31af7Sopenharmony_ci		group->addChild(new SizeCase(testCtx, renderCtx, "width",	"Maximum width",		  FboSpec(SizeCase::USE_MAXIMUM,	128,					0)));
679e5c31af7Sopenharmony_ci		group->addChild(new SizeCase(testCtx, renderCtx, "height",	"Maximum height",		  FboSpec(128,						SizeCase::USE_MAXIMUM,  0)));
680e5c31af7Sopenharmony_ci		group->addChild(new SizeCase(testCtx, renderCtx, "size",	"Maximum size",			  FboSpec(SizeCase::USE_MAXIMUM,	SizeCase::USE_MAXIMUM,  0)));
681e5c31af7Sopenharmony_ci		group->addChild(new SizeCase(testCtx, renderCtx, "samples", "Maximum samples",		  FboSpec(128,						128,					SizeCase::USE_MAXIMUM)));
682e5c31af7Sopenharmony_ci		group->addChild(new SizeCase(testCtx, renderCtx, "all",		"Maximum size & samples", FboSpec(SizeCase::USE_MAXIMUM,	SizeCase::USE_MAXIMUM,  SizeCase::USE_MAXIMUM)));
683e5c31af7Sopenharmony_ci	}
684e5c31af7Sopenharmony_ci
685e5c31af7Sopenharmony_ci	return root;
686e5c31af7Sopenharmony_ci}
687e5c31af7Sopenharmony_ci
688e5c31af7Sopenharmony_citcu::TestCaseGroup* createFboNoAttachmentCompletenessTests(Context& context)
689e5c31af7Sopenharmony_ci{
690e5c31af7Sopenharmony_ci	TestCaseGroup* const group = new TestCaseGroup(context, "completeness", "Completeness tests");
691e5c31af7Sopenharmony_ci
692e5c31af7Sopenharmony_ci	group->addChild(new FramebufferCompletenessCase(context.getTestContext(), context.getRenderContext(), "no_attachments", "No attachments completeness"));
693e5c31af7Sopenharmony_ci
694e5c31af7Sopenharmony_ci	return group;
695e5c31af7Sopenharmony_ci}
696e5c31af7Sopenharmony_ci
697e5c31af7Sopenharmony_ci} // Functional
698e5c31af7Sopenharmony_ci} // gles31
699e5c31af7Sopenharmony_ci} // deqp
700