1e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * OpenGL Conformance Test Suite
3e5c31af7Sopenharmony_ci * -----------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright (c) 2021 Google Inc.
6e5c31af7Sopenharmony_ci * Copyright (c) 2021 The Khronos Group Inc.
7e5c31af7Sopenharmony_ci *
8e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
9e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
10e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
11e5c31af7Sopenharmony_ci *
12e5c31af7Sopenharmony_ci *      http://www.apache.org/licenses/LICENSE-2.0
13e5c31af7Sopenharmony_ci *
14e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
15e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
16e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
18e5c31af7Sopenharmony_ci * limitations under the License.
19e5c31af7Sopenharmony_ci *
20e5c31af7Sopenharmony_ci *//*!
21e5c31af7Sopenharmony_ci * \file glcFramebuffercompleteness.cpp
22e5c31af7Sopenharmony_ci * \brief Tests for OpenGL ES frame buffer completeness
23e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/
24e5c31af7Sopenharmony_ci#include "glcFramebufferCompleteness.hpp"
25e5c31af7Sopenharmony_ci#include "deInt32.h"
26e5c31af7Sopenharmony_ci#include "gluDefs.hpp"
27e5c31af7Sopenharmony_ci#include "gluContextInfo.hpp"
28e5c31af7Sopenharmony_ci#include "glwEnums.hpp"
29e5c31af7Sopenharmony_ci#include "glwFunctions.hpp"
30e5c31af7Sopenharmony_ci#include "tcuStringTemplate.hpp"
31e5c31af7Sopenharmony_ci
32e5c31af7Sopenharmony_ci#include <algorithm>
33e5c31af7Sopenharmony_ci#include <functional>
34e5c31af7Sopenharmony_ci#include <map>
35e5c31af7Sopenharmony_ci#include <memory>
36e5c31af7Sopenharmony_ci#include <sstream>
37e5c31af7Sopenharmony_ci#include <string>
38e5c31af7Sopenharmony_ci#include <vector>
39e5c31af7Sopenharmony_ci
40e5c31af7Sopenharmony_cinamespace glcts
41e5c31af7Sopenharmony_ci{
42e5c31af7Sopenharmony_cinamespace
43e5c31af7Sopenharmony_ci{
44e5c31af7Sopenharmony_ci
45e5c31af7Sopenharmony_ciusing namespace glw;
46e5c31af7Sopenharmony_ciusing namespace std;
47e5c31af7Sopenharmony_ci
48e5c31af7Sopenharmony_cistruct TestContext
49e5c31af7Sopenharmony_ci{
50e5c31af7Sopenharmony_ci	const glu::RenderContext&	renderContext;
51e5c31af7Sopenharmony_ci	const glw::Functions&		gl;
52e5c31af7Sopenharmony_ci	vector<GLuint>&				fboIds;
53e5c31af7Sopenharmony_ci	vector<GLuint>&				texIds;
54e5c31af7Sopenharmony_ci	vector<GLuint>&				rboIds;
55e5c31af7Sopenharmony_ci
56e5c31af7Sopenharmony_ci	void texParameteri					(GLuint texId, GLenum target, GLenum pname, GLint parameter);
57e5c31af7Sopenharmony_ci	void bindTexture					(GLenum target, GLuint texId);
58e5c31af7Sopenharmony_ci	void texImage2D						(GLenum target, GLuint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border,
59e5c31af7Sopenharmony_ci										 GLenum format, GLenum type, const void* data);
60e5c31af7Sopenharmony_ci	void texImage2D						(GLuint texId, GLenum target, GLuint level, GLint internalFormat, GLsizei width, GLsizei height,
61e5c31af7Sopenharmony_ci										 GLint border, GLenum format, GLenum type, const void* data);
62e5c31af7Sopenharmony_ci	void texImage3D						(GLuint texId, GLenum target, GLuint level, GLint internalFormat, GLsizei width, GLsizei height,
63e5c31af7Sopenharmony_ci										 GLsizei depth, GLint border, GLenum format, GLenum type, const void* data);
64e5c31af7Sopenharmony_ci	void renderbufferStorage			(GLuint rboId, GLenum target, GLenum internalFormat, GLsizei width, GLsizei height);
65e5c31af7Sopenharmony_ci	void renderbufferStorageMultisample	(GLuint rboId, GLenum target, GLsizei samples, GLenum internalFormat,
66e5c31af7Sopenharmony_ci										 GLsizei width, GLsizei height);
67e5c31af7Sopenharmony_ci	void bindFramebuffer				(GLenum target, GLuint fboId);
68e5c31af7Sopenharmony_ci	void framebufferTexture2D			(GLenum target, GLenum attachment, GLenum textarget, GLuint texId, GLint level);
69e5c31af7Sopenharmony_ci	void framebufferTextureLayer		(GLenum target, GLenum attachment, GLuint texId, GLint level, GLint layer);
70e5c31af7Sopenharmony_ci	void framebufferRenderbuffer		(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint rboId);
71e5c31af7Sopenharmony_ci};
72e5c31af7Sopenharmony_ci
73e5c31af7Sopenharmony_civoid TestContext::texParameteri(GLuint texId, GLenum target, GLenum pname, GLint parameter)
74e5c31af7Sopenharmony_ci{
75e5c31af7Sopenharmony_ci	bindTexture(target, texId);
76e5c31af7Sopenharmony_ci	gl.texParameteri(target, pname, parameter);
77e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() failed");
78e5c31af7Sopenharmony_ci	bindTexture(target, 0);
79e5c31af7Sopenharmony_ci}
80e5c31af7Sopenharmony_ci
81e5c31af7Sopenharmony_civoid TestContext::bindTexture(GLenum target, GLuint texId)
82e5c31af7Sopenharmony_ci{
83e5c31af7Sopenharmony_ci	gl.bindTexture(target, texId);
84e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed");
85e5c31af7Sopenharmony_ci}
86e5c31af7Sopenharmony_ci
87e5c31af7Sopenharmony_civoid TestContext::texImage2D(GLenum target, GLuint level, GLint internalFormat, GLsizei width, GLsizei height,
88e5c31af7Sopenharmony_ci							 GLint border, GLenum format, GLenum type, const void* data)
89e5c31af7Sopenharmony_ci{
90e5c31af7Sopenharmony_ci	gl.texImage2D(target, level, internalFormat, width, height, border, format, type, data);
91e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D() failed");
92e5c31af7Sopenharmony_ci}
93e5c31af7Sopenharmony_ci
94e5c31af7Sopenharmony_civoid TestContext::texImage2D(GLuint texId, GLenum target, GLuint level, GLint internalFormat, GLsizei width,
95e5c31af7Sopenharmony_ci							 GLsizei height, GLint border, GLenum format, GLenum type, const void* data)
96e5c31af7Sopenharmony_ci{
97e5c31af7Sopenharmony_ci	bindTexture(target, texId);
98e5c31af7Sopenharmony_ci	texImage2D(target, level, internalFormat, width, height, border, format, type, data);
99e5c31af7Sopenharmony_ci	bindTexture(target, 0);
100e5c31af7Sopenharmony_ci}
101e5c31af7Sopenharmony_ci
102e5c31af7Sopenharmony_civoid TestContext::texImage3D(GLuint texId, GLenum target, GLuint level, GLint internalFormat, GLsizei width,
103e5c31af7Sopenharmony_ci							 GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* data)
104e5c31af7Sopenharmony_ci{
105e5c31af7Sopenharmony_ci	bindTexture(target, texId);
106e5c31af7Sopenharmony_ci	gl.texImage3D(target, level, internalFormat, width, height, depth, border, format, type, data);
107e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage3D() failed");
108e5c31af7Sopenharmony_ci	bindTexture(target, 0);
109e5c31af7Sopenharmony_ci}
110e5c31af7Sopenharmony_ci
111e5c31af7Sopenharmony_civoid TestContext::renderbufferStorage(GLuint rboId, GLenum target, GLenum internalFormat, GLsizei width, GLsizei height)
112e5c31af7Sopenharmony_ci{
113e5c31af7Sopenharmony_ci	gl.bindRenderbuffer(GL_RENDERBUFFER, rboId);
114e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer() failed");
115e5c31af7Sopenharmony_ci	gl.renderbufferStorage(target, internalFormat, width, height);
116e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage() failed");
117e5c31af7Sopenharmony_ci	gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
118e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer() failed");
119e5c31af7Sopenharmony_ci}
120e5c31af7Sopenharmony_ci
121e5c31af7Sopenharmony_civoid TestContext::renderbufferStorageMultisample(GLuint rboId, GLenum target, GLsizei samples, GLenum internalFormat,
122e5c31af7Sopenharmony_ci												 GLsizei width, GLsizei height)
123e5c31af7Sopenharmony_ci{
124e5c31af7Sopenharmony_ci	gl.bindRenderbuffer(GL_RENDERBUFFER, rboId);
125e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer() failed");
126e5c31af7Sopenharmony_ci	gl.renderbufferStorageMultisample(target, samples, internalFormat, width, height);
127e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorageMultisample() failed");
128e5c31af7Sopenharmony_ci	gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
129e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer() failed");
130e5c31af7Sopenharmony_ci}
131e5c31af7Sopenharmony_ci
132e5c31af7Sopenharmony_civoid TestContext::bindFramebuffer(GLenum target, GLuint fboId)
133e5c31af7Sopenharmony_ci{
134e5c31af7Sopenharmony_ci	gl.bindFramebuffer(target, fboId);
135e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() failed");
136e5c31af7Sopenharmony_ci}
137e5c31af7Sopenharmony_ci
138e5c31af7Sopenharmony_civoid TestContext::framebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texId, GLint level)
139e5c31af7Sopenharmony_ci{
140e5c31af7Sopenharmony_ci	gl.framebufferTexture2D(target, attachment, textarget, texId, level);
141e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() failed");
142e5c31af7Sopenharmony_ci}
143e5c31af7Sopenharmony_ci
144e5c31af7Sopenharmony_civoid TestContext::framebufferTextureLayer(GLenum target, GLenum attachment, GLuint texId, GLint level, GLint layer)
145e5c31af7Sopenharmony_ci{
146e5c31af7Sopenharmony_ci	gl.framebufferTextureLayer(target, attachment, texId, level, layer);
147e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTextureLayer() failed");
148e5c31af7Sopenharmony_ci}
149e5c31af7Sopenharmony_ci
150e5c31af7Sopenharmony_civoid TestContext::framebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint rboId)
151e5c31af7Sopenharmony_ci{
152e5c31af7Sopenharmony_ci	gl.framebufferRenderbuffer(target, attachment, renderbuffertarget, rboId);
153e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer() failed");
154e5c31af7Sopenharmony_ci}
155e5c31af7Sopenharmony_ci
156e5c31af7Sopenharmony_citypedef function<GLenum(const glu::ContextInfo& contextInfo)>		ExpectedStatusFn;
157e5c31af7Sopenharmony_citypedef function<void(TestContext& context)>						TestFn;
158e5c31af7Sopenharmony_ci
159e5c31af7Sopenharmony_ciExpectedStatusFn expectedStatusConstant(GLenum expectedStatus)
160e5c31af7Sopenharmony_ci{
161e5c31af7Sopenharmony_ci	return [expectedStatus] (const glu::ContextInfo&) { return expectedStatus; };
162e5c31af7Sopenharmony_ci}
163e5c31af7Sopenharmony_ci
164e5c31af7Sopenharmony_ciExpectedStatusFn expectedStatusWithExtension(const string& extension, GLenum statusIfSupported, GLenum statusIfNotSupported)
165e5c31af7Sopenharmony_ci{
166e5c31af7Sopenharmony_ci	return [extension, statusIfSupported, statusIfNotSupported](const glu::ContextInfo &contextInfo)
167e5c31af7Sopenharmony_ci	{
168e5c31af7Sopenharmony_ci		if (contextInfo.isExtensionSupported(extension.c_str()))
169e5c31af7Sopenharmony_ci			return statusIfSupported;
170e5c31af7Sopenharmony_ci		else
171e5c31af7Sopenharmony_ci			return statusIfNotSupported;
172e5c31af7Sopenharmony_ci	};
173e5c31af7Sopenharmony_ci}
174e5c31af7Sopenharmony_ci
175e5c31af7Sopenharmony_cistruct TestStep
176e5c31af7Sopenharmony_ci{
177e5c31af7Sopenharmony_ci	TestFn				testFn;
178e5c31af7Sopenharmony_ci	ExpectedStatusFn	expectedFbStatus;
179e5c31af7Sopenharmony_ci};
180e5c31af7Sopenharmony_ci
181e5c31af7Sopenharmony_citypedef function<void(vector<TestStep>&, TestContext& context)>		StepsGeneratorFn;
182e5c31af7Sopenharmony_ci
183e5c31af7Sopenharmony_cistruct ExtensionEntry
184e5c31af7Sopenharmony_ci{
185e5c31af7Sopenharmony_ci	string				name;
186e5c31af7Sopenharmony_ci	bool				supportedStatus;
187e5c31af7Sopenharmony_ci};
188e5c31af7Sopenharmony_ci
189e5c31af7Sopenharmony_cistruct TestParams
190e5c31af7Sopenharmony_ci{
191e5c31af7Sopenharmony_ci	string					name;
192e5c31af7Sopenharmony_ci	string					description;
193e5c31af7Sopenharmony_ci	glu::ApiType			apiType;
194e5c31af7Sopenharmony_ci	size_t					numFboIds;
195e5c31af7Sopenharmony_ci	size_t					numTexIds;
196e5c31af7Sopenharmony_ci	size_t					numRboIds;
197e5c31af7Sopenharmony_ci	vector<TestStep>		initialSteps;
198e5c31af7Sopenharmony_ci	StepsGeneratorFn		stepsGenerator;
199e5c31af7Sopenharmony_ci};
200e5c31af7Sopenharmony_ci
201e5c31af7Sopenharmony_ciconst GLuint			TEXTURE_WIDTH			= 16;
202e5c31af7Sopenharmony_ciconst GLuint			TEXTURE_HEIGHT			= 16;
203e5c31af7Sopenharmony_ciconst GLuint			TEXTURE_DEPTH			= 16;
204e5c31af7Sopenharmony_ci
205e5c31af7Sopenharmony_cistatic const GLenum		cubemapTextureTargets[]	=
206e5c31af7Sopenharmony_ci{
207e5c31af7Sopenharmony_ci	GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_X,
208e5c31af7Sopenharmony_ci	GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
209e5c31af7Sopenharmony_ci	GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, GL_TEXTURE_CUBE_MAP_POSITIVE_Z
210e5c31af7Sopenharmony_ci};
211e5c31af7Sopenharmony_ci
212e5c31af7Sopenharmony_ciconst glu::ApiType		apiES30					= glu::ApiType::es(3, 0);
213e5c31af7Sopenharmony_ciconst glu::ApiType		apiES31					= glu::ApiType::es(3, 1);
214e5c31af7Sopenharmony_ciconst glu::ApiType		apiES32					= glu::ApiType::es(3, 2);
215e5c31af7Sopenharmony_ci
216e5c31af7Sopenharmony_cibool isDifferentRboSampleCountsSupported(TestContext& testContext, GLint& maxSamples)
217e5c31af7Sopenharmony_ci{
218e5c31af7Sopenharmony_ci	const auto&	gl				= testContext.gl;
219e5c31af7Sopenharmony_ci	gl.getIntegerv(GL_MAX_SAMPLES, &maxSamples);
220e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed");
221e5c31af7Sopenharmony_ci
222e5c31af7Sopenharmony_ci	if (maxSamples < 4)
223e5c31af7Sopenharmony_ci		TCU_FAIL("GL_MAX_SAMPLES needs to be >= 4");
224e5c31af7Sopenharmony_ci
225e5c31af7Sopenharmony_ci	testContext.renderbufferStorageMultisample(testContext.rboIds[0], GL_RENDERBUFFER, 1, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT);
226e5c31af7Sopenharmony_ci	gl.bindRenderbuffer(GL_RENDERBUFFER, testContext.rboIds[0]);
227e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer() failed");
228e5c31af7Sopenharmony_ci
229e5c31af7Sopenharmony_ci	GLint		minSamplesRbo;
230e5c31af7Sopenharmony_ci	gl.getRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &minSamplesRbo);
231e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "getRenderbufferParameteriv() failed");
232e5c31af7Sopenharmony_ci	gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
233e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer() failed");
234e5c31af7Sopenharmony_ci
235e5c31af7Sopenharmony_ci	return minSamplesRbo < maxSamples;
236e5c31af7Sopenharmony_ci}
237e5c31af7Sopenharmony_ci
238e5c31af7Sopenharmony_cibool isDifferentTextureSampleCountsSupported(TestContext& testContext, GLint& maxSamples)
239e5c31af7Sopenharmony_ci{
240e5c31af7Sopenharmony_ci	if (glu::contextSupports(testContext.renderContext.getType(), apiES31))
241e5c31af7Sopenharmony_ci	{
242e5c31af7Sopenharmony_ci		const auto&	gl				= testContext.gl;
243e5c31af7Sopenharmony_ci		GLint	maxColorSamples;
244e5c31af7Sopenharmony_ci		gl.getIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &maxColorSamples);
245e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed");
246e5c31af7Sopenharmony_ci
247e5c31af7Sopenharmony_ci		GLint	maxDepthSamples;
248e5c31af7Sopenharmony_ci		gl.getIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &maxDepthSamples);
249e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed");
250e5c31af7Sopenharmony_ci
251e5c31af7Sopenharmony_ci		maxSamples = min(maxColorSamples, maxDepthSamples);
252e5c31af7Sopenharmony_ci
253e5c31af7Sopenharmony_ci		GLuint	tempTexId;
254e5c31af7Sopenharmony_ci		gl.genTextures(1, &tempTexId);
255e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
256e5c31af7Sopenharmony_ci
257e5c31af7Sopenharmony_ci		testContext.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, tempTexId);
258e5c31af7Sopenharmony_ci		gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, GL_TRUE);
259e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample() failed");
260e5c31af7Sopenharmony_ci
261e5c31af7Sopenharmony_ci		GLint	minSamplesTex;
262e5c31af7Sopenharmony_ci		gl.getTexLevelParameteriv(GL_TEXTURE_2D_MULTISAMPLE, 0, GL_TEXTURE_SAMPLES, &minSamplesTex);
263e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv() failed");
264e5c31af7Sopenharmony_ci
265e5c31af7Sopenharmony_ci		testContext.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
266e5c31af7Sopenharmony_ci		gl.deleteTextures(1, &tempTexId);
267e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() failed");
268e5c31af7Sopenharmony_ci
269e5c31af7Sopenharmony_ci		return minSamplesTex < maxSamples;
270e5c31af7Sopenharmony_ci	}
271e5c31af7Sopenharmony_ci	return false;
272e5c31af7Sopenharmony_ci}
273e5c31af7Sopenharmony_ci
274e5c31af7Sopenharmony_ci/* Tests are defined as ordered series of steps that each expect a specific current framebuffer status
275e5c31af7Sopenharmony_ci   after being executed. A new TestContext instance (parameter) is created for each test but all steps
276e5c31af7Sopenharmony_ci   within a test use the same context. No code in addition to the framebuffer status check is executed
277e5c31af7Sopenharmony_ci   between steps. */
278e5c31af7Sopenharmony_ciconst TestParams		tests[]					=
279e5c31af7Sopenharmony_ci{
280e5c31af7Sopenharmony_ci	{
281e5c31af7Sopenharmony_ci		"incomplete_missing_attachment",														// string					name
282e5c31af7Sopenharmony_ci		"No attachments",																		// string					description
283e5c31af7Sopenharmony_ci		apiES30,																				// glu::ApiType				apiType
284e5c31af7Sopenharmony_ci		1,																						// size_t					numFboIds
285e5c31af7Sopenharmony_ci		0,																						// size_t					numTexIds
286e5c31af7Sopenharmony_ci		0,																						// size_t					numRboIds
287e5c31af7Sopenharmony_ci		{																						// vector<TestStep>			initialSteps
288e5c31af7Sopenharmony_ci			{
289e5c31af7Sopenharmony_ci				[](TestContext& context) {
290e5c31af7Sopenharmony_ci					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
291e5c31af7Sopenharmony_ci				},
292e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
293e5c31af7Sopenharmony_ci			}
294e5c31af7Sopenharmony_ci		},
295e5c31af7Sopenharmony_ci		DE_NULL,																				// StepsGeneratorFn			stepsGenerator
296e5c31af7Sopenharmony_ci	},
297e5c31af7Sopenharmony_ci	{
298e5c31af7Sopenharmony_ci		"incomplete_image_zero_width",															// string					name
299e5c31af7Sopenharmony_ci		"Zero width attachment image",															// string					description
300e5c31af7Sopenharmony_ci		apiES30,																				// glu::ApiType				apiType
301e5c31af7Sopenharmony_ci		1,																						// size_t					numFboIds
302e5c31af7Sopenharmony_ci		1,																						// size_t					numTexIds
303e5c31af7Sopenharmony_ci		0,																						// size_t					numRboIds
304e5c31af7Sopenharmony_ci		{																						// vector<TestStep>			initialSteps
305e5c31af7Sopenharmony_ci			{
306e5c31af7Sopenharmony_ci				[](TestContext& context)
307e5c31af7Sopenharmony_ci				{
308e5c31af7Sopenharmony_ci					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
309e5c31af7Sopenharmony_ci				},
310e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
311e5c31af7Sopenharmony_ci			},
312e5c31af7Sopenharmony_ci			{
313e5c31af7Sopenharmony_ci				[](TestContext& context)
314e5c31af7Sopenharmony_ci				{
315e5c31af7Sopenharmony_ci					context.texImage2D(context.texIds[0], GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, 0, TEXTURE_HEIGHT, 0,
316e5c31af7Sopenharmony_ci									   GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, DE_NULL);
317e5c31af7Sopenharmony_ci					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, context.texIds[0], 0);
318e5c31af7Sopenharmony_ci				},
319e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
320e5c31af7Sopenharmony_ci			}
321e5c31af7Sopenharmony_ci		},
322e5c31af7Sopenharmony_ci		DE_NULL,																				// StepsGeneratorFn			stepsGenerator
323e5c31af7Sopenharmony_ci	},
324e5c31af7Sopenharmony_ci	{
325e5c31af7Sopenharmony_ci		"incomplete_image_zero_height",															// string					name
326e5c31af7Sopenharmony_ci		"Zero height attachment image",															// string					description
327e5c31af7Sopenharmony_ci		apiES30,																				// glu::ApiType				apiType
328e5c31af7Sopenharmony_ci		1,																						// size_t					numFboIds
329e5c31af7Sopenharmony_ci		1,																						// size_t					numTexIds
330e5c31af7Sopenharmony_ci		0,																						// size_t					numRboIds
331e5c31af7Sopenharmony_ci		{																						// vector<TestStep>			initialSteps
332e5c31af7Sopenharmony_ci			{
333e5c31af7Sopenharmony_ci				[](TestContext& context)
334e5c31af7Sopenharmony_ci				{
335e5c31af7Sopenharmony_ci					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
336e5c31af7Sopenharmony_ci				},
337e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
338e5c31af7Sopenharmony_ci			},
339e5c31af7Sopenharmony_ci			{
340e5c31af7Sopenharmony_ci				[](TestContext& context)
341e5c31af7Sopenharmony_ci				{
342e5c31af7Sopenharmony_ci					context.texImage2D(context.texIds[0], GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, 0, TEXTURE_WIDTH, 0,
343e5c31af7Sopenharmony_ci									   GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, DE_NULL);
344e5c31af7Sopenharmony_ci					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, context.texIds[0], 0);
345e5c31af7Sopenharmony_ci				},
346e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
347e5c31af7Sopenharmony_ci			}
348e5c31af7Sopenharmony_ci		},
349e5c31af7Sopenharmony_ci		DE_NULL,																				// StepsGeneratorFn			stepsGenerator
350e5c31af7Sopenharmony_ci	},
351e5c31af7Sopenharmony_ci	{
352e5c31af7Sopenharmony_ci		"incomplete_texture_3d_layer_oob",														// string					name
353e5c31af7Sopenharmony_ci		"3D texture layer out of bounds",														// string					description
354e5c31af7Sopenharmony_ci		apiES30,																				// glu::ApiType				apiType
355e5c31af7Sopenharmony_ci		1,																						// size_t					numFboIds
356e5c31af7Sopenharmony_ci		1,																						// size_t					numTexIds
357e5c31af7Sopenharmony_ci		0,																						// size_t					numRboIds
358e5c31af7Sopenharmony_ci		{																						// vector<TestStep>			initialSteps
359e5c31af7Sopenharmony_ci			{
360e5c31af7Sopenharmony_ci				[](TestContext& context)
361e5c31af7Sopenharmony_ci				{
362e5c31af7Sopenharmony_ci					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
363e5c31af7Sopenharmony_ci				},
364e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
365e5c31af7Sopenharmony_ci			},
366e5c31af7Sopenharmony_ci			{
367e5c31af7Sopenharmony_ci				[](TestContext& context)
368e5c31af7Sopenharmony_ci				{
369e5c31af7Sopenharmony_ci					context.texImage3D(context.texIds[0], GL_TEXTURE_3D, 0, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT,
370e5c31af7Sopenharmony_ci									   TEXTURE_DEPTH, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
371e5c31af7Sopenharmony_ci					context.framebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, context.texIds[0], 0,
372e5c31af7Sopenharmony_ci													TEXTURE_DEPTH + 1);
373e5c31af7Sopenharmony_ci				},
374e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
375e5c31af7Sopenharmony_ci			}
376e5c31af7Sopenharmony_ci		},
377e5c31af7Sopenharmony_ci		DE_NULL,																				// StepsGeneratorFn			stepsGenerator
378e5c31af7Sopenharmony_ci	},
379e5c31af7Sopenharmony_ci	{
380e5c31af7Sopenharmony_ci		"incomplete_texture_2d_layer_oob",														// string					name
381e5c31af7Sopenharmony_ci		"2D texture layer out of bounds",														// string					description
382e5c31af7Sopenharmony_ci		apiES30,																				// glu::ApiType				apiType
383e5c31af7Sopenharmony_ci		1,																						// size_t					numFboIds
384e5c31af7Sopenharmony_ci		1,																						// size_t					numTexIds
385e5c31af7Sopenharmony_ci		0,																						// size_t					numRboIds
386e5c31af7Sopenharmony_ci		{																						// vector<TestStep>			initialSteps
387e5c31af7Sopenharmony_ci			{
388e5c31af7Sopenharmony_ci				[](TestContext& context)
389e5c31af7Sopenharmony_ci				{
390e5c31af7Sopenharmony_ci					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
391e5c31af7Sopenharmony_ci				},
392e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
393e5c31af7Sopenharmony_ci			},
394e5c31af7Sopenharmony_ci			{
395e5c31af7Sopenharmony_ci				[](TestContext& context)
396e5c31af7Sopenharmony_ci				{
397e5c31af7Sopenharmony_ci					context.texImage2D(context.texIds[0], GL_TEXTURE_2D, 0, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0,
398e5c31af7Sopenharmony_ci									   GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
399e5c31af7Sopenharmony_ci					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, context.texIds[0], 1);
400e5c31af7Sopenharmony_ci				},
401e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
402e5c31af7Sopenharmony_ci			}
403e5c31af7Sopenharmony_ci		},
404e5c31af7Sopenharmony_ci		DE_NULL,																				// StepsGeneratorFn			stepsGenerator
405e5c31af7Sopenharmony_ci	},
406e5c31af7Sopenharmony_ci	{
407e5c31af7Sopenharmony_ci		"incomplete_texture_2d_mm_layer_oob",													// string					name
408e5c31af7Sopenharmony_ci		"2D mipmapped texture layer out of bounds",												// string					description
409e5c31af7Sopenharmony_ci		apiES30,																				// glu::ApiType				apiType
410e5c31af7Sopenharmony_ci		1,																						// size_t					numFboIds
411e5c31af7Sopenharmony_ci		1,																						// size_t					numTexIds
412e5c31af7Sopenharmony_ci		0,																						// size_t					numRboIds
413e5c31af7Sopenharmony_ci		{																						// vector<TestStep>			initialSteps
414e5c31af7Sopenharmony_ci			{
415e5c31af7Sopenharmony_ci				[](TestContext& context)
416e5c31af7Sopenharmony_ci				{
417e5c31af7Sopenharmony_ci					context.texParameteri(context.texIds[0], GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
418e5c31af7Sopenharmony_ci										  GL_LINEAR_MIPMAP_LINEAR);
419e5c31af7Sopenharmony_ci					context.texParameteri(context.texIds[0], GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
420e5c31af7Sopenharmony_ci					context.texImage2D(context.texIds[0], GL_TEXTURE_2D, 1, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0,
421e5c31af7Sopenharmony_ci									   GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
422e5c31af7Sopenharmony_ci					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
423e5c31af7Sopenharmony_ci				},
424e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
425e5c31af7Sopenharmony_ci			},
426e5c31af7Sopenharmony_ci			{
427e5c31af7Sopenharmony_ci				[](TestContext& context)
428e5c31af7Sopenharmony_ci				{
429e5c31af7Sopenharmony_ci					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, context.texIds[0], 0);
430e5c31af7Sopenharmony_ci				},
431e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
432e5c31af7Sopenharmony_ci			},
433e5c31af7Sopenharmony_ci			{
434e5c31af7Sopenharmony_ci				[](TestContext& context)
435e5c31af7Sopenharmony_ci				{
436e5c31af7Sopenharmony_ci					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, context.texIds[0], 1);
437e5c31af7Sopenharmony_ci				},
438e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
439e5c31af7Sopenharmony_ci			},
440e5c31af7Sopenharmony_ci			{
441e5c31af7Sopenharmony_ci				[](TestContext& context)
442e5c31af7Sopenharmony_ci				{
443e5c31af7Sopenharmony_ci					const deUint32 maxMipmapLevel = deLog2Floor32(de::max(TEXTURE_WIDTH, TEXTURE_HEIGHT));
444e5c31af7Sopenharmony_ci					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, context.texIds[0],
445e5c31af7Sopenharmony_ci												 maxMipmapLevel + 2);
446e5c31af7Sopenharmony_ci				},
447e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
448e5c31af7Sopenharmony_ci			},
449e5c31af7Sopenharmony_ci		},
450e5c31af7Sopenharmony_ci		DE_NULL,																				// StepsGeneratorFn			stepsGenerator
451e5c31af7Sopenharmony_ci	},
452e5c31af7Sopenharmony_ci	{
453e5c31af7Sopenharmony_ci		"mutable_nbl_texture_expect_mipmap_complete",											// string					name
454e5c31af7Sopenharmony_ci		"Mutable non base level texture as framebuffer attachment must be mipmap complete",		// string					description
455e5c31af7Sopenharmony_ci		apiES30,																				// glu::ApiType				apiType
456e5c31af7Sopenharmony_ci		1,																						// size_t					numFboIds
457e5c31af7Sopenharmony_ci		1,																						// size_t					numTexIds
458e5c31af7Sopenharmony_ci		0,																						// size_t					numRboIds
459e5c31af7Sopenharmony_ci		{																						// vector<TestStep>			initialSteps
460e5c31af7Sopenharmony_ci			{
461e5c31af7Sopenharmony_ci				[](TestContext& context)
462e5c31af7Sopenharmony_ci				{
463e5c31af7Sopenharmony_ci					DE_ASSERT(TEXTURE_WIDTH >= 8 && TEXTURE_HEIGHT >= 8);
464e5c31af7Sopenharmony_ci
465e5c31af7Sopenharmony_ci					context.texImage2D(context.texIds[0], GL_TEXTURE_2D, 0, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0,
466e5c31af7Sopenharmony_ci									   GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
467e5c31af7Sopenharmony_ci					context.texImage2D(context.texIds[0], GL_TEXTURE_2D, 1, GL_RGBA8, TEXTURE_WIDTH >> 1,
468e5c31af7Sopenharmony_ci									   TEXTURE_HEIGHT >> 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
469e5c31af7Sopenharmony_ci					context.texImage2D(context.texIds[0], GL_TEXTURE_2D, 3, GL_RGBA8, TEXTURE_WIDTH >> 3,
470e5c31af7Sopenharmony_ci									   TEXTURE_HEIGHT >> 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
471e5c31af7Sopenharmony_ci					context.texParameteri(context.texIds[0], GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 3);
472e5c31af7Sopenharmony_ci					context.texParameteri(context.texIds[0], GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
473e5c31af7Sopenharmony_ci					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
474e5c31af7Sopenharmony_ci				},
475e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
476e5c31af7Sopenharmony_ci			},
477e5c31af7Sopenharmony_ci			{
478e5c31af7Sopenharmony_ci				[](TestContext& context)
479e5c31af7Sopenharmony_ci				{
480e5c31af7Sopenharmony_ci					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, context.texIds[0], 1);
481e5c31af7Sopenharmony_ci				},
482e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
483e5c31af7Sopenharmony_ci			},
484e5c31af7Sopenharmony_ci			{
485e5c31af7Sopenharmony_ci				[](TestContext& context)
486e5c31af7Sopenharmony_ci				{
487e5c31af7Sopenharmony_ci					context.texImage2D(context.texIds[0], GL_TEXTURE_2D, 2, GL_RGBA8, TEXTURE_WIDTH >> 2,
488e5c31af7Sopenharmony_ci									   TEXTURE_HEIGHT >> 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
489e5c31af7Sopenharmony_ci				},
490e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
491e5c31af7Sopenharmony_ci			}
492e5c31af7Sopenharmony_ci		},
493e5c31af7Sopenharmony_ci		DE_NULL,																				// StepsGeneratorFn			stepsGenerator
494e5c31af7Sopenharmony_ci	},
495e5c31af7Sopenharmony_ci	{
496e5c31af7Sopenharmony_ci		"mutable_nbl_texture_expect_cube_complete",												// string					name
497e5c31af7Sopenharmony_ci		"Mutable non base level texture as framebuffer attachment must be cube complete",		// string					description
498e5c31af7Sopenharmony_ci		apiES30,																				// glu::ApiType				apiType
499e5c31af7Sopenharmony_ci		1,																						// size_t					numFboIds
500e5c31af7Sopenharmony_ci		1,																						// size_t					numTexIds
501e5c31af7Sopenharmony_ci		0,																						// size_t					numRboIds
502e5c31af7Sopenharmony_ci		{																						// vector<TestStep>			initialSteps
503e5c31af7Sopenharmony_ci			{
504e5c31af7Sopenharmony_ci				[](TestContext& context)
505e5c31af7Sopenharmony_ci				{
506e5c31af7Sopenharmony_ci					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
507e5c31af7Sopenharmony_ci				},
508e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
509e5c31af7Sopenharmony_ci			},
510e5c31af7Sopenharmony_ci			{
511e5c31af7Sopenharmony_ci				[](TestContext& context)
512e5c31af7Sopenharmony_ci				{
513e5c31af7Sopenharmony_ci					context.texParameteri(context.texIds[0], GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 1);
514e5c31af7Sopenharmony_ci					context.texParameteri(context.texIds[0], GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
515e5c31af7Sopenharmony_ci
516e5c31af7Sopenharmony_ci					context.bindTexture(GL_TEXTURE_CUBE_MAP, context.texIds[0]);
517e5c31af7Sopenharmony_ci					for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(cubemapTextureTargets); ++i)
518e5c31af7Sopenharmony_ci					{
519e5c31af7Sopenharmony_ci						if (i % 2)
520e5c31af7Sopenharmony_ci							continue;
521e5c31af7Sopenharmony_ci						context.texImage2D(cubemapTextureTargets[i], 0, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, GL_RGBA,
522e5c31af7Sopenharmony_ci										   GL_UNSIGNED_BYTE, DE_NULL);
523e5c31af7Sopenharmony_ci						context.texImage2D(cubemapTextureTargets[i], 1, GL_RGBA8, TEXTURE_WIDTH >> 1, TEXTURE_HEIGHT >> 1, 0, GL_RGBA,
524e5c31af7Sopenharmony_ci										   GL_UNSIGNED_BYTE, DE_NULL);
525e5c31af7Sopenharmony_ci					}
526e5c31af7Sopenharmony_ci					context.bindTexture(GL_TEXTURE_CUBE_MAP, 0);
527e5c31af7Sopenharmony_ci
528e5c31af7Sopenharmony_ci					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, cubemapTextureTargets[0],
529e5c31af7Sopenharmony_ci												 context.texIds[0], 1);
530e5c31af7Sopenharmony_ci				},
531e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
532e5c31af7Sopenharmony_ci			},
533e5c31af7Sopenharmony_ci			{
534e5c31af7Sopenharmony_ci				[](TestContext& context)
535e5c31af7Sopenharmony_ci				{
536e5c31af7Sopenharmony_ci					context.bindTexture(GL_TEXTURE_CUBE_MAP, context.texIds[0]);
537e5c31af7Sopenharmony_ci					for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(cubemapTextureTargets); ++i)
538e5c31af7Sopenharmony_ci					{
539e5c31af7Sopenharmony_ci						if (i % 2 == 0)
540e5c31af7Sopenharmony_ci							continue;
541e5c31af7Sopenharmony_ci						context.texImage2D(cubemapTextureTargets[i], 0, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, GL_RGBA,
542e5c31af7Sopenharmony_ci										   GL_UNSIGNED_BYTE, DE_NULL);
543e5c31af7Sopenharmony_ci						context.texImage2D(cubemapTextureTargets[i], 1, GL_RGBA8, TEXTURE_WIDTH >> 1, TEXTURE_HEIGHT >> 1, 0, GL_RGBA,
544e5c31af7Sopenharmony_ci										   GL_UNSIGNED_BYTE, DE_NULL);
545e5c31af7Sopenharmony_ci					}
546e5c31af7Sopenharmony_ci					context.bindTexture(GL_TEXTURE_CUBE_MAP, 0);
547e5c31af7Sopenharmony_ci				},
548e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
549e5c31af7Sopenharmony_ci			}
550e5c31af7Sopenharmony_ci		},
551e5c31af7Sopenharmony_ci		DE_NULL,																				// StepsGeneratorFn			stepsGenerator
552e5c31af7Sopenharmony_ci	},
553e5c31af7Sopenharmony_ci	{
554e5c31af7Sopenharmony_ci		"expect_renderable_internal_format",													// string					name
555e5c31af7Sopenharmony_ci		"Color/Depth/Stencil attachment texture must have a color/depth/stencil"				// string					description
556e5c31af7Sopenharmony_ci		" renderable internal format",
557e5c31af7Sopenharmony_ci		apiES30,																				// glu::ApiType				apiType
558e5c31af7Sopenharmony_ci		1,																						// size_t					numFboIds
559e5c31af7Sopenharmony_ci		3,																						// size_t					numTexIds
560e5c31af7Sopenharmony_ci		0,																						// size_t					numRboIds
561e5c31af7Sopenharmony_ci		{																						// vector<TestStep>			initialSteps
562e5c31af7Sopenharmony_ci			{
563e5c31af7Sopenharmony_ci				[](TestContext& context)
564e5c31af7Sopenharmony_ci				{
565e5c31af7Sopenharmony_ci					context.texImage2D(context.texIds[0], GL_TEXTURE_2D, 0, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0,
566e5c31af7Sopenharmony_ci									   GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
567e5c31af7Sopenharmony_ci					context.texImage2D(context.texIds[1], GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, TEXTURE_WIDTH,
568e5c31af7Sopenharmony_ci									   TEXTURE_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, DE_NULL);
569e5c31af7Sopenharmony_ci					context.texImage2D(context.texIds[2], GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, TEXTURE_WIDTH, TEXTURE_HEIGHT,
570e5c31af7Sopenharmony_ci									   0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, DE_NULL);
571e5c31af7Sopenharmony_ci					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
572e5c31af7Sopenharmony_ci				},
573e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
574e5c31af7Sopenharmony_ci			},
575e5c31af7Sopenharmony_ci			{
576e5c31af7Sopenharmony_ci				[](TestContext& context)
577e5c31af7Sopenharmony_ci				{
578e5c31af7Sopenharmony_ci					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, context.texIds[0], 0);
579e5c31af7Sopenharmony_ci				},
580e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
581e5c31af7Sopenharmony_ci			},
582e5c31af7Sopenharmony_ci			{
583e5c31af7Sopenharmony_ci				[](TestContext& context)
584e5c31af7Sopenharmony_ci				{
585e5c31af7Sopenharmony_ci					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, context.texIds[1], 0);
586e5c31af7Sopenharmony_ci				},
587e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
588e5c31af7Sopenharmony_ci			},
589e5c31af7Sopenharmony_ci			{
590e5c31af7Sopenharmony_ci				[](TestContext& context)
591e5c31af7Sopenharmony_ci				{
592e5c31af7Sopenharmony_ci					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, context.texIds[0], 0);
593e5c31af7Sopenharmony_ci				},
594e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
595e5c31af7Sopenharmony_ci			},
596e5c31af7Sopenharmony_ci			{
597e5c31af7Sopenharmony_ci				[](TestContext& context)
598e5c31af7Sopenharmony_ci				{
599e5c31af7Sopenharmony_ci					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, context.texIds[2], 0);
600e5c31af7Sopenharmony_ci				},
601e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
602e5c31af7Sopenharmony_ci			}
603e5c31af7Sopenharmony_ci		},
604e5c31af7Sopenharmony_ci		[](vector<TestStep>& steps, TestContext& testContext)									// StepsGeneratorFn			stepsGenerator
605e5c31af7Sopenharmony_ci		{
606e5c31af7Sopenharmony_ci			GLint	maxColorAttachmentsCount;
607e5c31af7Sopenharmony_ci			testContext.gl.getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxColorAttachmentsCount);
608e5c31af7Sopenharmony_ci			GLU_EXPECT_NO_ERROR(testContext.gl.getError(), "glGetInteger() failed");
609e5c31af7Sopenharmony_ci
610e5c31af7Sopenharmony_ci			steps.reserve(steps.size() + 2 * maxColorAttachmentsCount);
611e5c31af7Sopenharmony_ci			for (GLint i = 0; i < maxColorAttachmentsCount; ++i)
612e5c31af7Sopenharmony_ci			{
613e5c31af7Sopenharmony_ci				steps.push_back(
614e5c31af7Sopenharmony_ci					{
615e5c31af7Sopenharmony_ci						[i](TestContext& context)
616e5c31af7Sopenharmony_ci						{
617e5c31af7Sopenharmony_ci							context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D,
618e5c31af7Sopenharmony_ci														 context.texIds[1], 0);
619e5c31af7Sopenharmony_ci						},
620e5c31af7Sopenharmony_ci						expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
621e5c31af7Sopenharmony_ci					});
622e5c31af7Sopenharmony_ci				steps.push_back(
623e5c31af7Sopenharmony_ci					{
624e5c31af7Sopenharmony_ci						[i](TestContext& context)
625e5c31af7Sopenharmony_ci						{
626e5c31af7Sopenharmony_ci							context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D,
627e5c31af7Sopenharmony_ci														 context.texIds[0], 0);
628e5c31af7Sopenharmony_ci						},
629e5c31af7Sopenharmony_ci						expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
630e5c31af7Sopenharmony_ci					});
631e5c31af7Sopenharmony_ci			}
632e5c31af7Sopenharmony_ci		},
633e5c31af7Sopenharmony_ci	},
634e5c31af7Sopenharmony_ci	{
635e5c31af7Sopenharmony_ci		"all_rbos_expect_same_numsamples",														// string					name
636e5c31af7Sopenharmony_ci		"Same value of FRAMEBUFFER_SAMPLES for all attached render buffers",					// string					description
637e5c31af7Sopenharmony_ci		apiES30,																				// glu::ApiType				apiType
638e5c31af7Sopenharmony_ci		1,																						// size_t					numFboIds
639e5c31af7Sopenharmony_ci		0,																						// size_t					numTexIds
640e5c31af7Sopenharmony_ci		2,																						// size_t					numRboIds
641e5c31af7Sopenharmony_ci		{},																						// vector<TestStep>			initialSteps
642e5c31af7Sopenharmony_ci		[](vector<TestStep>& steps, TestContext& testContext)									// StepsGeneratorFn			stepsGenerator
643e5c31af7Sopenharmony_ci		{
644e5c31af7Sopenharmony_ci			GLint	maxSamples;
645e5c31af7Sopenharmony_ci			if (!isDifferentRboSampleCountsSupported(testContext, maxSamples))
646e5c31af7Sopenharmony_ci				return;
647e5c31af7Sopenharmony_ci
648e5c31af7Sopenharmony_ci			steps.push_back(
649e5c31af7Sopenharmony_ci				{
650e5c31af7Sopenharmony_ci					[](TestContext& context)
651e5c31af7Sopenharmony_ci					{
652e5c31af7Sopenharmony_ci						context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
653e5c31af7Sopenharmony_ci					},
654e5c31af7Sopenharmony_ci					expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
655e5c31af7Sopenharmony_ci				});
656e5c31af7Sopenharmony_ci			steps.push_back(
657e5c31af7Sopenharmony_ci				{
658e5c31af7Sopenharmony_ci					[](TestContext& context)
659e5c31af7Sopenharmony_ci					{
660e5c31af7Sopenharmony_ci						context.renderbufferStorage(context.rboIds[0], GL_RENDERBUFFER, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT);
661e5c31af7Sopenharmony_ci						context.renderbufferStorage(context.rboIds[1], GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, TEXTURE_WIDTH,
662e5c31af7Sopenharmony_ci													TEXTURE_HEIGHT);
663e5c31af7Sopenharmony_ci
664e5c31af7Sopenharmony_ci						context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
665e5c31af7Sopenharmony_ci														context.rboIds[0]);
666e5c31af7Sopenharmony_ci						context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
667e5c31af7Sopenharmony_ci														context.rboIds[1]);
668e5c31af7Sopenharmony_ci					},
669e5c31af7Sopenharmony_ci					expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
670e5c31af7Sopenharmony_ci				});
671e5c31af7Sopenharmony_ci			steps.push_back(
672e5c31af7Sopenharmony_ci				{
673e5c31af7Sopenharmony_ci					[maxSamples](TestContext& context)
674e5c31af7Sopenharmony_ci					{
675e5c31af7Sopenharmony_ci						context.renderbufferStorageMultisample(context.rboIds[0], GL_RENDERBUFFER, maxSamples, GL_RGBA8, TEXTURE_WIDTH,
676e5c31af7Sopenharmony_ci															   TEXTURE_HEIGHT);
677e5c31af7Sopenharmony_ci						context.renderbufferStorageMultisample(context.rboIds[1], GL_RENDERBUFFER, 1, GL_DEPTH24_STENCIL8,
678e5c31af7Sopenharmony_ci															   TEXTURE_WIDTH, TEXTURE_HEIGHT);
679e5c31af7Sopenharmony_ci					},
680e5c31af7Sopenharmony_ci					expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
681e5c31af7Sopenharmony_ci				});
682e5c31af7Sopenharmony_ci		},
683e5c31af7Sopenharmony_ci	},
684e5c31af7Sopenharmony_ci	{
685e5c31af7Sopenharmony_ci		"rbo_and_texture_expect_zero_numsamples",												// string					name
686e5c31af7Sopenharmony_ci		"When using mixed renderbuffer and texture attachments, the value of"					// string					description
687e5c31af7Sopenharmony_ci		" FRAMEBUFFER_SAMPLES needs to be zero for all attached renderbuffers",
688e5c31af7Sopenharmony_ci		apiES30,																				// glu::ApiType				apiType
689e5c31af7Sopenharmony_ci		1,																						// size_t					numFboIds
690e5c31af7Sopenharmony_ci		2,																						// size_t					numTexIds
691e5c31af7Sopenharmony_ci		2,																						// size_t	u				numRboIds
692e5c31af7Sopenharmony_ci		{																						// vector<TestStep>			initialSteps
693e5c31af7Sopenharmony_ci			{
694e5c31af7Sopenharmony_ci				[](TestContext& context)
695e5c31af7Sopenharmony_ci				{
696e5c31af7Sopenharmony_ci					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
697e5c31af7Sopenharmony_ci				},
698e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
699e5c31af7Sopenharmony_ci			},
700e5c31af7Sopenharmony_ci			{
701e5c31af7Sopenharmony_ci				[](TestContext& context)
702e5c31af7Sopenharmony_ci				{
703e5c31af7Sopenharmony_ci					context.renderbufferStorage(context.rboIds[0], GL_RENDERBUFFER, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT);
704e5c31af7Sopenharmony_ci					context.texImage2D(context.texIds[1], GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, TEXTURE_WIDTH,
705e5c31af7Sopenharmony_ci									   TEXTURE_HEIGHT, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, DE_NULL);
706e5c31af7Sopenharmony_ci
707e5c31af7Sopenharmony_ci					context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
708e5c31af7Sopenharmony_ci													context.rboIds[0]);
709e5c31af7Sopenharmony_ci					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
710e5c31af7Sopenharmony_ci												 context.texIds[1], 0);
711e5c31af7Sopenharmony_ci				},
712e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
713e5c31af7Sopenharmony_ci			},
714e5c31af7Sopenharmony_ci			{
715e5c31af7Sopenharmony_ci				[](TestContext& context)
716e5c31af7Sopenharmony_ci				{
717e5c31af7Sopenharmony_ci					context.renderbufferStorage(context.rboIds[1], GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, TEXTURE_WIDTH,
718e5c31af7Sopenharmony_ci												TEXTURE_HEIGHT);
719e5c31af7Sopenharmony_ci					context.texImage2D(context.texIds[0], GL_TEXTURE_2D, 0, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0,
720e5c31af7Sopenharmony_ci									   GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
721e5c31af7Sopenharmony_ci
722e5c31af7Sopenharmony_ci					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, context.texIds[0], 0);
723e5c31af7Sopenharmony_ci					context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
724e5c31af7Sopenharmony_ci													context.rboIds[1]);
725e5c31af7Sopenharmony_ci				},
726e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
727e5c31af7Sopenharmony_ci			},
728e5c31af7Sopenharmony_ci			{
729e5c31af7Sopenharmony_ci				[](TestContext& context)
730e5c31af7Sopenharmony_ci				{
731e5c31af7Sopenharmony_ci					context.renderbufferStorageMultisample(context.rboIds[1], GL_RENDERBUFFER, 2, GL_DEPTH24_STENCIL8,
732e5c31af7Sopenharmony_ci														   TEXTURE_WIDTH, TEXTURE_HEIGHT);
733e5c31af7Sopenharmony_ci				},
734e5c31af7Sopenharmony_ci				expectedStatusWithExtension("GL_NV_framebuffer_mixed_samples", GL_FRAMEBUFFER_COMPLETE, GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
735e5c31af7Sopenharmony_ci			},
736e5c31af7Sopenharmony_ci			{
737e5c31af7Sopenharmony_ci				[](TestContext& context)
738e5c31af7Sopenharmony_ci				{
739e5c31af7Sopenharmony_ci					context.renderbufferStorageMultisample(context.rboIds[0], GL_RENDERBUFFER, 3, GL_RGBA8, TEXTURE_WIDTH,
740e5c31af7Sopenharmony_ci														   TEXTURE_HEIGHT);
741e5c31af7Sopenharmony_ci
742e5c31af7Sopenharmony_ci					context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
743e5c31af7Sopenharmony_ci													context.rboIds[0]);
744e5c31af7Sopenharmony_ci					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
745e5c31af7Sopenharmony_ci												 context.texIds[1], 0);
746e5c31af7Sopenharmony_ci				},
747e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
748e5c31af7Sopenharmony_ci			},
749e5c31af7Sopenharmony_ci			{
750e5c31af7Sopenharmony_ci				[](TestContext& context)
751e5c31af7Sopenharmony_ci				{
752e5c31af7Sopenharmony_ci					context.renderbufferStorageMultisample(context.rboIds[0], GL_RENDERBUFFER, 0, GL_RGBA8, TEXTURE_WIDTH,
753e5c31af7Sopenharmony_ci														   TEXTURE_HEIGHT);
754e5c31af7Sopenharmony_ci				},
755e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
756e5c31af7Sopenharmony_ci			}
757e5c31af7Sopenharmony_ci		},
758e5c31af7Sopenharmony_ci		DE_NULL,																				// StepsGeneratorFn			stepsGenerator
759e5c31af7Sopenharmony_ci	},
760e5c31af7Sopenharmony_ci	{
761e5c31af7Sopenharmony_ci		"expect_equal_numsamples",																// string					name
762e5c31af7Sopenharmony_ci		"The value of samples for each attached target must be equal",							// string					description
763e5c31af7Sopenharmony_ci		apiES31,																				// glu::ApiType				apiType
764e5c31af7Sopenharmony_ci		1,																						// size_t					numFboIds
765e5c31af7Sopenharmony_ci		4,																						// size_t					numTexIds
766e5c31af7Sopenharmony_ci		2,																						// size_t					numRboIds
767e5c31af7Sopenharmony_ci		{},																						// vector<TestStep>			initialSteps
768e5c31af7Sopenharmony_ci		[](vector<TestStep>& steps, TestContext& testContext)									// StepsGeneratorFn			stepsGenerator
769e5c31af7Sopenharmony_ci		{
770e5c31af7Sopenharmony_ci			GLint	maxRboSamples, maxTextureSamples;
771e5c31af7Sopenharmony_ci			if (!isDifferentRboSampleCountsSupported(testContext, maxRboSamples) || !isDifferentTextureSampleCountsSupported(testContext, maxTextureSamples))
772e5c31af7Sopenharmony_ci				return;
773e5c31af7Sopenharmony_ci
774e5c31af7Sopenharmony_ci			steps.push_back(
775e5c31af7Sopenharmony_ci				{
776e5c31af7Sopenharmony_ci					[maxRboSamples, maxTextureSamples](TestContext& context)
777e5c31af7Sopenharmony_ci					{
778e5c31af7Sopenharmony_ci						// Set up textures and renderbuffers for all following steps, complete = (tex0, rbo1) or (tex1, rbo0) */
779e5c31af7Sopenharmony_ci						context.renderbufferStorageMultisample(context.rboIds[0], GL_RENDERBUFFER, maxRboSamples, GL_RGBA8,
780e5c31af7Sopenharmony_ci															   TEXTURE_WIDTH, TEXTURE_HEIGHT);
781e5c31af7Sopenharmony_ci						context.renderbufferStorageMultisample(context.rboIds[1], GL_RENDERBUFFER, 1, GL_DEPTH24_STENCIL8,
782e5c31af7Sopenharmony_ci															   TEXTURE_WIDTH, TEXTURE_HEIGHT);
783e5c31af7Sopenharmony_ci
784e5c31af7Sopenharmony_ci						const auto&	gl	= context.gl;
785e5c31af7Sopenharmony_ci						context.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, context.texIds[0]);
786e5c31af7Sopenharmony_ci						gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, GL_TRUE);
787e5c31af7Sopenharmony_ci						GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample() failed");
788e5c31af7Sopenharmony_ci
789e5c31af7Sopenharmony_ci						context.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, context.texIds[1]);
790e5c31af7Sopenharmony_ci						gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_DEPTH24_STENCIL8, TEXTURE_WIDTH, TEXTURE_HEIGHT, GL_TRUE);
791e5c31af7Sopenharmony_ci						GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample() failed");
792e5c31af7Sopenharmony_ci
793e5c31af7Sopenharmony_ci						context.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, context.texIds[2]);
794e5c31af7Sopenharmony_ci						gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, maxTextureSamples, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, GL_TRUE);
795e5c31af7Sopenharmony_ci						GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample() failed");
796e5c31af7Sopenharmony_ci
797e5c31af7Sopenharmony_ci						context.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, context.texIds[3]);
798e5c31af7Sopenharmony_ci						gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, maxTextureSamples, GL_DEPTH24_STENCIL8, TEXTURE_WIDTH, TEXTURE_HEIGHT, GL_TRUE);
799e5c31af7Sopenharmony_ci						GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample() failed");
800e5c31af7Sopenharmony_ci
801e5c31af7Sopenharmony_ci						context.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
802e5c31af7Sopenharmony_ci
803e5c31af7Sopenharmony_ci						// Framebuffer binding for rest of this test
804e5c31af7Sopenharmony_ci						context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
805e5c31af7Sopenharmony_ci					},
806e5c31af7Sopenharmony_ci					expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
807e5c31af7Sopenharmony_ci				});
808e5c31af7Sopenharmony_ci			steps.push_back(
809e5c31af7Sopenharmony_ci				{
810e5c31af7Sopenharmony_ci					[](TestContext& context)
811e5c31af7Sopenharmony_ci					{
812e5c31af7Sopenharmony_ci						context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
813e5c31af7Sopenharmony_ci													 context.texIds[0], 0);
814e5c31af7Sopenharmony_ci						context.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE,
815e5c31af7Sopenharmony_ci													 context.texIds[1], 0);
816e5c31af7Sopenharmony_ci					},
817e5c31af7Sopenharmony_ci					expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
818e5c31af7Sopenharmony_ci				});
819e5c31af7Sopenharmony_ci			steps.push_back(
820e5c31af7Sopenharmony_ci				{
821e5c31af7Sopenharmony_ci					[](TestContext& context)
822e5c31af7Sopenharmony_ci					{
823e5c31af7Sopenharmony_ci						context.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE,
824e5c31af7Sopenharmony_ci													 context.texIds[3], 0);
825e5c31af7Sopenharmony_ci					},
826e5c31af7Sopenharmony_ci					expectedStatusWithExtension("GL_NV_framebuffer_mixed_samples", GL_FRAMEBUFFER_COMPLETE, GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
827e5c31af7Sopenharmony_ci				});
828e5c31af7Sopenharmony_ci			steps.push_back(
829e5c31af7Sopenharmony_ci				{
830e5c31af7Sopenharmony_ci					[](TestContext& context)
831e5c31af7Sopenharmony_ci					{
832e5c31af7Sopenharmony_ci						context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
833e5c31af7Sopenharmony_ci														context.rboIds[1]);
834e5c31af7Sopenharmony_ci					},
835e5c31af7Sopenharmony_ci					expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
836e5c31af7Sopenharmony_ci				});
837e5c31af7Sopenharmony_ci			steps.push_back(
838e5c31af7Sopenharmony_ci				{
839e5c31af7Sopenharmony_ci					[](TestContext& context)
840e5c31af7Sopenharmony_ci					{
841e5c31af7Sopenharmony_ci						context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
842e5c31af7Sopenharmony_ci														context.rboIds[0]);
843e5c31af7Sopenharmony_ci					},
844e5c31af7Sopenharmony_ci					expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
845e5c31af7Sopenharmony_ci				});
846e5c31af7Sopenharmony_ci			steps.push_back(
847e5c31af7Sopenharmony_ci				{
848e5c31af7Sopenharmony_ci					[](TestContext& context)
849e5c31af7Sopenharmony_ci					{
850e5c31af7Sopenharmony_ci						context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
851e5c31af7Sopenharmony_ci													 context.texIds[2], 0);
852e5c31af7Sopenharmony_ci						context.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE,
853e5c31af7Sopenharmony_ci													 context.texIds[3], 0);
854e5c31af7Sopenharmony_ci					},
855e5c31af7Sopenharmony_ci					expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
856e5c31af7Sopenharmony_ci				});
857e5c31af7Sopenharmony_ci			steps.push_back(
858e5c31af7Sopenharmony_ci				{
859e5c31af7Sopenharmony_ci					[](TestContext& context)
860e5c31af7Sopenharmony_ci					{
861e5c31af7Sopenharmony_ci						const auto&	gl	= context.gl;
862e5c31af7Sopenharmony_ci						gl.deleteTextures(1, &context.texIds[0]);
863e5c31af7Sopenharmony_ci						GLU_EXPECT_NO_ERROR(context.gl.getError(), "glDeleteTextures() failed");
864e5c31af7Sopenharmony_ci						gl.genTextures(1, &context.texIds[0]);
865e5c31af7Sopenharmony_ci						GLU_EXPECT_NO_ERROR(context.gl.getError(), "glGenTextures() failed");
866e5c31af7Sopenharmony_ci						context.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, context.texIds[0]);
867e5c31af7Sopenharmony_ci						gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, GL_FALSE);
868e5c31af7Sopenharmony_ci						GLU_EXPECT_NO_ERROR(context.gl.getError(), "glTexStorage2DMultisample() failed");
869e5c31af7Sopenharmony_ci						context.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
870e5c31af7Sopenharmony_ci						context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
871e5c31af7Sopenharmony_ci													 context.texIds[0], 0);
872e5c31af7Sopenharmony_ci						context.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE,
873e5c31af7Sopenharmony_ci													 context.texIds[1], 0);
874e5c31af7Sopenharmony_ci					},
875e5c31af7Sopenharmony_ci					expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
876e5c31af7Sopenharmony_ci				});
877e5c31af7Sopenharmony_ci		},																						// StepsGeneratorFn			stepsGenerator
878e5c31af7Sopenharmony_ci	},
879e5c31af7Sopenharmony_ci	{
880e5c31af7Sopenharmony_ci		"status_tracking",																		// string					name
881e5c31af7Sopenharmony_ci		"Modifying framebuffer attached objects correctly updates the fbo status",				// string					description
882e5c31af7Sopenharmony_ci		apiES30,																				// glu::ApiType				apiType
883e5c31af7Sopenharmony_ci		3,																						// size_t					numFboIds
884e5c31af7Sopenharmony_ci		2,																						// size_t					numTexIds
885e5c31af7Sopenharmony_ci		1,																						// size_t					numRboIds
886e5c31af7Sopenharmony_ci		{																						// vector<TestStep>			initialSteps
887e5c31af7Sopenharmony_ci			{
888e5c31af7Sopenharmony_ci				// Initial status -> missing_attachment
889e5c31af7Sopenharmony_ci				[](TestContext& context)
890e5c31af7Sopenharmony_ci				{
891e5c31af7Sopenharmony_ci					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
892e5c31af7Sopenharmony_ci				},
893e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
894e5c31af7Sopenharmony_ci			},
895e5c31af7Sopenharmony_ci			{
896e5c31af7Sopenharmony_ci				// Allocate and attach texture -> complete
897e5c31af7Sopenharmony_ci				[](TestContext& context)
898e5c31af7Sopenharmony_ci				{
899e5c31af7Sopenharmony_ci					context.texImage2D(context.texIds[0], GL_TEXTURE_2D, 0, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0,
900e5c31af7Sopenharmony_ci									   GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
901e5c31af7Sopenharmony_ci					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, context.texIds[0], 0);
902e5c31af7Sopenharmony_ci				},
903e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
904e5c31af7Sopenharmony_ci			},
905e5c31af7Sopenharmony_ci			{
906e5c31af7Sopenharmony_ci				// Detach texture from fbo -> missing_attachment
907e5c31af7Sopenharmony_ci				[](TestContext& context)
908e5c31af7Sopenharmony_ci				{
909e5c31af7Sopenharmony_ci					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
910e5c31af7Sopenharmony_ci				},
911e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
912e5c31af7Sopenharmony_ci			},
913e5c31af7Sopenharmony_ci			{
914e5c31af7Sopenharmony_ci				// Allocate and attach renderbuffer -> complete
915e5c31af7Sopenharmony_ci				[](TestContext& context)
916e5c31af7Sopenharmony_ci				{
917e5c31af7Sopenharmony_ci					context.renderbufferStorage(context.rboIds[0], GL_RENDERBUFFER, GL_RGBA8, TEXTURE_WIDTH,
918e5c31af7Sopenharmony_ci												TEXTURE_HEIGHT);
919e5c31af7Sopenharmony_ci					context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
920e5c31af7Sopenharmony_ci													context.rboIds[0]);
921e5c31af7Sopenharmony_ci				},
922e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
923e5c31af7Sopenharmony_ci			},
924e5c31af7Sopenharmony_ci			{
925e5c31af7Sopenharmony_ci				// Detach renderbuffer -> incomplete
926e5c31af7Sopenharmony_ci				[](TestContext& context)
927e5c31af7Sopenharmony_ci				{
928e5c31af7Sopenharmony_ci					context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0);
929e5c31af7Sopenharmony_ci				},
930e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
931e5c31af7Sopenharmony_ci			},
932e5c31af7Sopenharmony_ci			{
933e5c31af7Sopenharmony_ci				// Switch to incomplete fb -> missing_attachment
934e5c31af7Sopenharmony_ci				[](TestContext& context)
935e5c31af7Sopenharmony_ci				{
936e5c31af7Sopenharmony_ci					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[1]);
937e5c31af7Sopenharmony_ci				},
938e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
939e5c31af7Sopenharmony_ci			},
940e5c31af7Sopenharmony_ci			{
941e5c31af7Sopenharmony_ci				// Attach texture to fbo -> complete
942e5c31af7Sopenharmony_ci				[](TestContext& context)
943e5c31af7Sopenharmony_ci				{
944e5c31af7Sopenharmony_ci					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, context.texIds[0], 0);
945e5c31af7Sopenharmony_ci				},
946e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
947e5c31af7Sopenharmony_ci			},
948e5c31af7Sopenharmony_ci			{
949e5c31af7Sopenharmony_ci				// Change image format of attached texture -> incomplete_attachment
950e5c31af7Sopenharmony_ci				[](TestContext& context)
951e5c31af7Sopenharmony_ci				{
952e5c31af7Sopenharmony_ci					context.texImage2D(context.texIds[0], GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, TEXTURE_WIDTH,
953e5c31af7Sopenharmony_ci									   TEXTURE_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, DE_NULL);
954e5c31af7Sopenharmony_ci				},
955e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
956e5c31af7Sopenharmony_ci			},
957e5c31af7Sopenharmony_ci			{
958e5c31af7Sopenharmony_ci				// Change image format (tex storage) -> complete
959e5c31af7Sopenharmony_ci				[](TestContext& context)
960e5c31af7Sopenharmony_ci				{
961e5c31af7Sopenharmony_ci					context.bindTexture(GL_TEXTURE_2D, context.texIds[0]);
962e5c31af7Sopenharmony_ci					context.gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT);
963e5c31af7Sopenharmony_ci					GLU_EXPECT_NO_ERROR(context.gl.getError(), "glTexStorage2D() failed");
964e5c31af7Sopenharmony_ci					context.bindTexture(GL_TEXTURE_2D, 0);
965e5c31af7Sopenharmony_ci				},
966e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
967e5c31af7Sopenharmony_ci			},
968e5c31af7Sopenharmony_ci			{
969e5c31af7Sopenharmony_ci				// Delete image -> missing_attachment
970e5c31af7Sopenharmony_ci				[](TestContext& context)
971e5c31af7Sopenharmony_ci				{
972e5c31af7Sopenharmony_ci					context.gl.deleteTextures(1, &context.texIds[0]);
973e5c31af7Sopenharmony_ci					GLU_EXPECT_NO_ERROR(context.gl.getError(), "glDeleteTextures() failed");
974e5c31af7Sopenharmony_ci					context.texIds.erase(context.texIds.begin());
975e5c31af7Sopenharmony_ci				},
976e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
977e5c31af7Sopenharmony_ci			},
978e5c31af7Sopenharmony_ci			{
979e5c31af7Sopenharmony_ci				// Recreate image in wrong format, attach to color attachment -> incomplete_attachment
980e5c31af7Sopenharmony_ci				[](TestContext& context)
981e5c31af7Sopenharmony_ci				{
982e5c31af7Sopenharmony_ci					const auto&	gl		= context.gl;
983e5c31af7Sopenharmony_ci					GLuint		texId;
984e5c31af7Sopenharmony_ci					gl.genTextures(1, &texId);
985e5c31af7Sopenharmony_ci					GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
986e5c31af7Sopenharmony_ci					context.texIds.push_back(texId);
987e5c31af7Sopenharmony_ci
988e5c31af7Sopenharmony_ci					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
989e5c31af7Sopenharmony_ci					context.texImage2D(context.texIds[0], GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, TEXTURE_WIDTH,
990e5c31af7Sopenharmony_ci									   TEXTURE_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, DE_NULL);
991e5c31af7Sopenharmony_ci					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, context.texIds[0], 0);
992e5c31af7Sopenharmony_ci				},
993e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
994e5c31af7Sopenharmony_ci			},
995e5c31af7Sopenharmony_ci			{
996e5c31af7Sopenharmony_ci				// Format to rgba8 using copyTexImage2D from compatible fbo -> framebuffer_complete
997e5c31af7Sopenharmony_ci				[](TestContext& context)
998e5c31af7Sopenharmony_ci				{
999e5c31af7Sopenharmony_ci					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[2]);
1000e5c31af7Sopenharmony_ci					context.texImage2D(context.texIds[1], GL_TEXTURE_2D, 0, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1001e5c31af7Sopenharmony_ci					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, context.texIds[1], 0);
1002e5c31af7Sopenharmony_ci
1003e5c31af7Sopenharmony_ci					context.bindTexture(GL_TEXTURE_2D, context.texIds[0]);
1004e5c31af7Sopenharmony_ci					const auto&	gl	= context.gl;
1005e5c31af7Sopenharmony_ci					gl.copyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0);
1006e5c31af7Sopenharmony_ci					GLU_EXPECT_NO_ERROR(gl.getError(), "glCopyTexImage2D() failed");
1007e5c31af7Sopenharmony_ci
1008e5c31af7Sopenharmony_ci					context.bindTexture(GL_TEXTURE_2D, 0);
1009e5c31af7Sopenharmony_ci					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
1010e5c31af7Sopenharmony_ci				},
1011e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
1012e5c31af7Sopenharmony_ci			},
1013e5c31af7Sopenharmony_ci			{
1014e5c31af7Sopenharmony_ci				// Change currently attached texture's format to compressed tex image -> incomplete_attachment (non color renderable)
1015e5c31af7Sopenharmony_ci				[](TestContext& context)
1016e5c31af7Sopenharmony_ci				{
1017e5c31af7Sopenharmony_ci					DE_ASSERT(TEXTURE_WIDTH == 16 && TEXTURE_HEIGHT == 16);
1018e5c31af7Sopenharmony_ci					static const glw::GLubyte textureDataETC2[] = // 16x16 all black RGBA8 texture in ETC2 format
1019e5c31af7Sopenharmony_ci					{
1020e5c31af7Sopenharmony_ci						0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00,
1021e5c31af7Sopenharmony_ci						0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00,
1022e5c31af7Sopenharmony_ci						0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00,
1023e5c31af7Sopenharmony_ci						0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00,
1024e5c31af7Sopenharmony_ci						0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00,
1025e5c31af7Sopenharmony_ci						0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00,
1026e5c31af7Sopenharmony_ci						0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00,
1027e5c31af7Sopenharmony_ci						0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00,
1028e5c31af7Sopenharmony_ci						0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00,
1029e5c31af7Sopenharmony_ci						0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00,
1030e5c31af7Sopenharmony_ci						0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00,
1031e5c31af7Sopenharmony_ci						0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00,
1032e5c31af7Sopenharmony_ci						0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00,
1033e5c31af7Sopenharmony_ci						0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00,
1034e5c31af7Sopenharmony_ci						0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00,
1035e5c31af7Sopenharmony_ci						0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00
1036e5c31af7Sopenharmony_ci					};
1037e5c31af7Sopenharmony_ci					const auto&	gl	= context.gl;
1038e5c31af7Sopenharmony_ci					context.bindTexture(GL_TEXTURE_2D, context.texIds[0]);
1039e5c31af7Sopenharmony_ci
1040e5c31af7Sopenharmony_ci					gl.compressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA8_ETC2_EAC, TEXTURE_WIDTH, TEXTURE_HEIGHT,
1041e5c31af7Sopenharmony_ci											0, DE_LENGTH_OF_ARRAY(textureDataETC2), textureDataETC2);
1042e5c31af7Sopenharmony_ci					GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage2D() failed");
1043e5c31af7Sopenharmony_ci
1044e5c31af7Sopenharmony_ci					context.bindTexture(GL_TEXTURE_2D, 0);
1045e5c31af7Sopenharmony_ci				},
1046e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
1047e5c31af7Sopenharmony_ci			},
1048e5c31af7Sopenharmony_ci			{
1049e5c31af7Sopenharmony_ci				// Re-attach rbo0 -> complete
1050e5c31af7Sopenharmony_ci				[](TestContext& context)
1051e5c31af7Sopenharmony_ci				{
1052e5c31af7Sopenharmony_ci					context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
1053e5c31af7Sopenharmony_ci													context.rboIds[0]);
1054e5c31af7Sopenharmony_ci				},
1055e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
1056e5c31af7Sopenharmony_ci			},
1057e5c31af7Sopenharmony_ci			{
1058e5c31af7Sopenharmony_ci				// Rbo storage to non renderable format -> incomplete_attachment
1059e5c31af7Sopenharmony_ci				[](TestContext& context)
1060e5c31af7Sopenharmony_ci				{
1061e5c31af7Sopenharmony_ci					context.renderbufferStorage(context.rboIds[0], GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, TEXTURE_WIDTH,
1062e5c31af7Sopenharmony_ci												TEXTURE_HEIGHT);
1063e5c31af7Sopenharmony_ci				},
1064e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
1065e5c31af7Sopenharmony_ci			},
1066e5c31af7Sopenharmony_ci			{
1067e5c31af7Sopenharmony_ci				// Delete rbo -> missing_attachment
1068e5c31af7Sopenharmony_ci				[](TestContext& context)
1069e5c31af7Sopenharmony_ci				{
1070e5c31af7Sopenharmony_ci					context.gl.deleteRenderbuffers(1, &context.rboIds[0]);
1071e5c31af7Sopenharmony_ci					GLU_EXPECT_NO_ERROR(context.gl.getError(), "glDeleteRenderbuffers() failed");
1072e5c31af7Sopenharmony_ci					context.rboIds.erase(context.rboIds.begin());
1073e5c31af7Sopenharmony_ci				},
1074e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
1075e5c31af7Sopenharmony_ci			}
1076e5c31af7Sopenharmony_ci		},
1077e5c31af7Sopenharmony_ci		DE_NULL,																				// StepsGeneratorFn			stepsGenerator
1078e5c31af7Sopenharmony_ci	},
1079e5c31af7Sopenharmony_ci	{
1080e5c31af7Sopenharmony_ci		"mutable_texture_missing_attachment_level",												// string					name
1081e5c31af7Sopenharmony_ci		"Attaching a mutable texture with undefined image for attachment level"
1082e5c31af7Sopenharmony_ci		" should be invalid",																	// string					description
1083e5c31af7Sopenharmony_ci		apiES30,																				// glu::ApiType				apiType
1084e5c31af7Sopenharmony_ci		1,																						// size_t					numFboIds
1085e5c31af7Sopenharmony_ci		1,																						// size_t					numTexIds
1086e5c31af7Sopenharmony_ci		0,																						// size_t					numRboIds
1087e5c31af7Sopenharmony_ci		{},																						// vector<TestStep>			initialSteps
1088e5c31af7Sopenharmony_ci		[](vector<TestStep>& steps, TestContext&)												// StepsGeneratorFn			stepsGenerator
1089e5c31af7Sopenharmony_ci		{
1090e5c31af7Sopenharmony_ci			DE_ASSERT(TEXTURE_WIDTH >= 16 && TEXTURE_HEIGHT >= 16);
1091e5c31af7Sopenharmony_ci			steps.push_back(
1092e5c31af7Sopenharmony_ci				{
1093e5c31af7Sopenharmony_ci					[](TestContext& context)
1094e5c31af7Sopenharmony_ci					{
1095e5c31af7Sopenharmony_ci						context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
1096e5c31af7Sopenharmony_ci					},
1097e5c31af7Sopenharmony_ci					expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
1098e5c31af7Sopenharmony_ci				});
1099e5c31af7Sopenharmony_ci			steps.push_back(
1100e5c31af7Sopenharmony_ci				{
1101e5c31af7Sopenharmony_ci					[](TestContext& context)
1102e5c31af7Sopenharmony_ci					{
1103e5c31af7Sopenharmony_ci
1104e5c31af7Sopenharmony_ci						context.texParameteri(context.texIds[0], GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1105e5c31af7Sopenharmony_ci						context.texImage2D(context.texIds[0], GL_TEXTURE_2D, 0, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0,
1106e5c31af7Sopenharmony_ci										   GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
1107e5c31af7Sopenharmony_ci						context.texImage2D(context.texIds[0], GL_TEXTURE_2D, 1, GL_RGBA8, TEXTURE_WIDTH >> 1, TEXTURE_HEIGHT >> 1, 0,
1108e5c31af7Sopenharmony_ci										   GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
1109e5c31af7Sopenharmony_ci						context.texImage2D(context.texIds[0], GL_TEXTURE_2D, 3, GL_RGBA8, TEXTURE_WIDTH >> 3, TEXTURE_HEIGHT >> 3, 0,
1110e5c31af7Sopenharmony_ci										   GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
1111e5c31af7Sopenharmony_ci
1112e5c31af7Sopenharmony_ci						context.texParameteri(context.texIds[0], GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
1113e5c31af7Sopenharmony_ci
1114e5c31af7Sopenharmony_ci						context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, context.texIds[0], 2);
1115e5c31af7Sopenharmony_ci					},
1116e5c31af7Sopenharmony_ci					expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
1117e5c31af7Sopenharmony_ci				});
1118e5c31af7Sopenharmony_ci		}
1119e5c31af7Sopenharmony_ci	},
1120e5c31af7Sopenharmony_ci	{
1121e5c31af7Sopenharmony_ci		"immutable_texture_any_level_as_attachment",											// string					name
1122e5c31af7Sopenharmony_ci		"Any level of immutable texture as attachment should be valid",							// string					description
1123e5c31af7Sopenharmony_ci		apiES30,																				// glu::ApiType				apiType
1124e5c31af7Sopenharmony_ci		1,																						// size_t					numFboIds
1125e5c31af7Sopenharmony_ci		1,																						// size_t					numTexIds
1126e5c31af7Sopenharmony_ci		0,																						// size_t					numRboIds
1127e5c31af7Sopenharmony_ci		{},																						// vector<TestStep>			initialSteps
1128e5c31af7Sopenharmony_ci		[](vector<TestStep>& steps, TestContext&)												// StepsGeneratorFn			stepsGenerator
1129e5c31af7Sopenharmony_ci		{
1130e5c31af7Sopenharmony_ci			DE_ASSERT(TEXTURE_WIDTH >= 8 && TEXTURE_HEIGHT >= 8);
1131e5c31af7Sopenharmony_ci			steps.push_back(
1132e5c31af7Sopenharmony_ci				{
1133e5c31af7Sopenharmony_ci					[](TestContext& context)
1134e5c31af7Sopenharmony_ci					{
1135e5c31af7Sopenharmony_ci						context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
1136e5c31af7Sopenharmony_ci					},
1137e5c31af7Sopenharmony_ci					expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
1138e5c31af7Sopenharmony_ci				});
1139e5c31af7Sopenharmony_ci			steps.push_back(
1140e5c31af7Sopenharmony_ci				{
1141e5c31af7Sopenharmony_ci					[](TestContext& context)
1142e5c31af7Sopenharmony_ci					{
1143e5c31af7Sopenharmony_ci						context.texParameteri(context.texIds[0], GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1144e5c31af7Sopenharmony_ci						context.bindTexture(GL_TEXTURE_2D, context.texIds[0]);
1145e5c31af7Sopenharmony_ci						const auto&	gl	= context.gl;
1146e5c31af7Sopenharmony_ci						gl.texStorage2D(GL_TEXTURE_2D, 3, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT);
1147e5c31af7Sopenharmony_ci						GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() failed");
1148e5c31af7Sopenharmony_ci						context.bindTexture(GL_TEXTURE_2D, 0);
1149e5c31af7Sopenharmony_ci
1150e5c31af7Sopenharmony_ci						context.texParameteri(context.texIds[0], GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
1151e5c31af7Sopenharmony_ci
1152e5c31af7Sopenharmony_ci						context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, context.texIds[0], 2);
1153e5c31af7Sopenharmony_ci					},
1154e5c31af7Sopenharmony_ci					expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE),
1155e5c31af7Sopenharmony_ci				});
1156e5c31af7Sopenharmony_ci			steps.push_back(
1157e5c31af7Sopenharmony_ci				{
1158e5c31af7Sopenharmony_ci					[](TestContext& context)
1159e5c31af7Sopenharmony_ci					{
1160e5c31af7Sopenharmony_ci						context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, context.texIds[0], 1);
1161e5c31af7Sopenharmony_ci					},
1162e5c31af7Sopenharmony_ci					expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE),
1163e5c31af7Sopenharmony_ci				});
1164e5c31af7Sopenharmony_ci			steps.push_back(
1165e5c31af7Sopenharmony_ci				{
1166e5c31af7Sopenharmony_ci					[](TestContext& context)
1167e5c31af7Sopenharmony_ci					{
1168e5c31af7Sopenharmony_ci						context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, context.texIds[0], 0);
1169e5c31af7Sopenharmony_ci					},
1170e5c31af7Sopenharmony_ci					expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE),
1171e5c31af7Sopenharmony_ci				});
1172e5c31af7Sopenharmony_ci		}
1173e5c31af7Sopenharmony_ci	},
1174e5c31af7Sopenharmony_ci	{
1175e5c31af7Sopenharmony_ci		"cube_map_layered_attachment_valid_size_and_format",									// string					name
1176e5c31af7Sopenharmony_ci		"Cube map attachment with images of same size, same format and square should be valid",	// string					description
1177e5c31af7Sopenharmony_ci		apiES32,																				// glu::ApiType				apiType
1178e5c31af7Sopenharmony_ci		1,																						// size_t					numFboIds
1179e5c31af7Sopenharmony_ci		1,																						// size_t					numTexIds
1180e5c31af7Sopenharmony_ci		0,																						// size_t					numRboIds
1181e5c31af7Sopenharmony_ci		{																						// vector<TestStep>			initialSteps
1182e5c31af7Sopenharmony_ci			{
1183e5c31af7Sopenharmony_ci				[](TestContext& context)
1184e5c31af7Sopenharmony_ci				{
1185e5c31af7Sopenharmony_ci					context.bindTexture(GL_TEXTURE_CUBE_MAP, context.texIds[0]);
1186e5c31af7Sopenharmony_ci					for(const auto target : cubemapTextureTargets)
1187e5c31af7Sopenharmony_ci						context.texImage2D(target, 0, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1188e5c31af7Sopenharmony_ci					context.bindTexture(GL_TEXTURE_CUBE_MAP, 0);
1189e5c31af7Sopenharmony_ci
1190e5c31af7Sopenharmony_ci					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
1191e5c31af7Sopenharmony_ci					context.gl.framebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, context.texIds[0], 0);
1192e5c31af7Sopenharmony_ci					GLU_EXPECT_NO_ERROR(context.gl.getError(), "glFramebufferTexture() failed");
1193e5c31af7Sopenharmony_ci				},
1194e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE),
1195e5c31af7Sopenharmony_ci			}
1196e5c31af7Sopenharmony_ci		},
1197e5c31af7Sopenharmony_ci		DE_NULL,																				// StepsGeneratorFn			stepsGenerator
1198e5c31af7Sopenharmony_ci	},
1199e5c31af7Sopenharmony_ci	{
1200e5c31af7Sopenharmony_ci		"cube_map_layered_attachment_different_formats",										// string					name
1201e5c31af7Sopenharmony_ci		"Cube map attachment with images of the same size, square but different formats"
1202e5c31af7Sopenharmony_ci		" should be incomplete",																// string					description
1203e5c31af7Sopenharmony_ci		apiES32,																				// glu::ApiType				apiType
1204e5c31af7Sopenharmony_ci		1,																						// size_t					numFboIds
1205e5c31af7Sopenharmony_ci		1,																						// size_t					numTexIds
1206e5c31af7Sopenharmony_ci		0,																						// size_t					numRboIds
1207e5c31af7Sopenharmony_ci		{																						// vector<TestStep>			initialSteps
1208e5c31af7Sopenharmony_ci			{
1209e5c31af7Sopenharmony_ci				[](TestContext& context)
1210e5c31af7Sopenharmony_ci				{
1211e5c31af7Sopenharmony_ci					context.bindTexture(GL_TEXTURE_CUBE_MAP, context.texIds[0]);
1212e5c31af7Sopenharmony_ci					for(size_t i = 0; i < DE_LENGTH_OF_ARRAY(cubemapTextureTargets); ++i)
1213e5c31af7Sopenharmony_ci						context.texImage2D(cubemapTextureTargets[i], 0, (i % 2) ? GL_RGBA8 : GL_RGB8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, (i % 2) ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, 0);
1214e5c31af7Sopenharmony_ci					context.bindTexture(GL_TEXTURE_CUBE_MAP, 0);
1215e5c31af7Sopenharmony_ci
1216e5c31af7Sopenharmony_ci					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
1217e5c31af7Sopenharmony_ci					context.gl.framebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, context.texIds[0], 0);
1218e5c31af7Sopenharmony_ci					GLU_EXPECT_NO_ERROR(context.gl.getError(), "glFramebufferTexture() failed");
1219e5c31af7Sopenharmony_ci				},
1220e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
1221e5c31af7Sopenharmony_ci			},
1222e5c31af7Sopenharmony_ci			{
1223e5c31af7Sopenharmony_ci				[](TestContext& context)
1224e5c31af7Sopenharmony_ci				{
1225e5c31af7Sopenharmony_ci					context.bindTexture(GL_TEXTURE_CUBE_MAP, context.texIds[0]);
1226e5c31af7Sopenharmony_ci					for(size_t i = 0; i < DE_LENGTH_OF_ARRAY(cubemapTextureTargets); ++i)
1227e5c31af7Sopenharmony_ci						context.texImage2D(cubemapTextureTargets[i], 0, (i % 2) ? GL_RGBA8 : GL_SRGB8_ALPHA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1228e5c31af7Sopenharmony_ci					context.bindTexture(GL_TEXTURE_CUBE_MAP, 0);
1229e5c31af7Sopenharmony_ci
1230e5c31af7Sopenharmony_ci					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
1231e5c31af7Sopenharmony_ci					context.gl.framebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, context.texIds[0], 0);
1232e5c31af7Sopenharmony_ci					GLU_EXPECT_NO_ERROR(context.gl.getError(), "glFramebufferTexture() failed");
1233e5c31af7Sopenharmony_ci				},
1234e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
1235e5c31af7Sopenharmony_ci			}
1236e5c31af7Sopenharmony_ci		},
1237e5c31af7Sopenharmony_ci		DE_NULL,																				// StepsGeneratorFn			stepsGenerator
1238e5c31af7Sopenharmony_ci	},
1239e5c31af7Sopenharmony_ci	{
1240e5c31af7Sopenharmony_ci		"cube_map_layered_attachment_different_sizes",											// string					name
1241e5c31af7Sopenharmony_ci		"Cube map with images of different sizes, same format and all square should"
1242e5c31af7Sopenharmony_ci		" be incomplete",																		// string					description
1243e5c31af7Sopenharmony_ci		apiES32,																				// glu::ApiType				apiType
1244e5c31af7Sopenharmony_ci		1,																						// size_t					numFboIds
1245e5c31af7Sopenharmony_ci		1,																						// size_t					numTexIds
1246e5c31af7Sopenharmony_ci		0,																						// size_t					numRboIds
1247e5c31af7Sopenharmony_ci		{																						// vector<TestStep>			initialSteps
1248e5c31af7Sopenharmony_ci			{
1249e5c31af7Sopenharmony_ci				[](TestContext& context)
1250e5c31af7Sopenharmony_ci				{
1251e5c31af7Sopenharmony_ci					context.bindTexture(GL_TEXTURE_CUBE_MAP, context.texIds[0]);
1252e5c31af7Sopenharmony_ci					for(size_t i = 0; i < DE_LENGTH_OF_ARRAY(cubemapTextureTargets); ++i)
1253e5c31af7Sopenharmony_ci						context.texImage2D(cubemapTextureTargets[i], 0, GL_RGBA8, (i % 2) ? TEXTURE_WIDTH : TEXTURE_WIDTH / 2, (i % 2) ? TEXTURE_HEIGHT : TEXTURE_HEIGHT / 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1254e5c31af7Sopenharmony_ci					context.bindTexture(GL_TEXTURE_CUBE_MAP, 0);
1255e5c31af7Sopenharmony_ci
1256e5c31af7Sopenharmony_ci					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
1257e5c31af7Sopenharmony_ci					context.gl.framebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, context.texIds[0], 0);
1258e5c31af7Sopenharmony_ci					GLU_EXPECT_NO_ERROR(context.gl.getError(), "glFramebufferTexture() failed");
1259e5c31af7Sopenharmony_ci				},
1260e5c31af7Sopenharmony_ci				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
1261e5c31af7Sopenharmony_ci			},
1262e5c31af7Sopenharmony_ci		},
1263e5c31af7Sopenharmony_ci		DE_NULL,																				// StepsGeneratorFn			stepsGenerator
1264e5c31af7Sopenharmony_ci	}
1265e5c31af7Sopenharmony_ci};
1266e5c31af7Sopenharmony_ci
1267e5c31af7Sopenharmony_ciclass FramebufferCompletenessTestCase : public deqp::TestCase
1268e5c31af7Sopenharmony_ci{
1269e5c31af7Sopenharmony_cipublic:
1270e5c31af7Sopenharmony_ci	FramebufferCompletenessTestCase				(deqp::Context& context, const TestParams& params);
1271e5c31af7Sopenharmony_ci	virtual ~FramebufferCompletenessTestCase	();
1272e5c31af7Sopenharmony_ci
1273e5c31af7Sopenharmony_ci	virtual void			init				(void);
1274e5c31af7Sopenharmony_ci	virtual void			deinit				(void);
1275e5c31af7Sopenharmony_ci	TestNode::IterateResult iterate				(void);
1276e5c31af7Sopenharmony_ci
1277e5c31af7Sopenharmony_ciprivate:
1278e5c31af7Sopenharmony_ci	bool verifyFramebufferStatus				(const glw::Functions& gl, const ExpectedStatusFn expectedStatusFn, const size_t stepIndex);
1279e5c31af7Sopenharmony_ci
1280e5c31af7Sopenharmony_ci	const TestParams		m_params;
1281e5c31af7Sopenharmony_ci	vector<GLuint>			m_fboIds;
1282e5c31af7Sopenharmony_ci	vector<GLuint>			m_texIds;
1283e5c31af7Sopenharmony_ci	vector<GLuint>			m_rboIds;
1284e5c31af7Sopenharmony_ci};
1285e5c31af7Sopenharmony_ci
1286e5c31af7Sopenharmony_ciFramebufferCompletenessTestCase::FramebufferCompletenessTestCase(deqp::Context& context, const TestParams& params)
1287e5c31af7Sopenharmony_ci	: deqp::TestCase(context, params.name.c_str(), params.description.c_str()), m_params(params)
1288e5c31af7Sopenharmony_ci{
1289e5c31af7Sopenharmony_ci}
1290e5c31af7Sopenharmony_ci
1291e5c31af7Sopenharmony_ciFramebufferCompletenessTestCase::~FramebufferCompletenessTestCase()
1292e5c31af7Sopenharmony_ci{
1293e5c31af7Sopenharmony_ci}
1294e5c31af7Sopenharmony_ci
1295e5c31af7Sopenharmony_civoid FramebufferCompletenessTestCase::init(void)
1296e5c31af7Sopenharmony_ci{
1297e5c31af7Sopenharmony_ci	const auto& renderContext	= m_context.getRenderContext();
1298e5c31af7Sopenharmony_ci	const auto& gl				= renderContext.getFunctions();
1299e5c31af7Sopenharmony_ci
1300e5c31af7Sopenharmony_ci	if (m_params.numFboIds > 0)
1301e5c31af7Sopenharmony_ci	{
1302e5c31af7Sopenharmony_ci		m_fboIds.resize(m_params.numFboIds);
1303e5c31af7Sopenharmony_ci		gl.genFramebuffers(m_params.numFboIds, m_fboIds.data());
1304e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() failed");
1305e5c31af7Sopenharmony_ci	}
1306e5c31af7Sopenharmony_ci	if (m_params.numTexIds > 0)
1307e5c31af7Sopenharmony_ci	{
1308e5c31af7Sopenharmony_ci		m_texIds.resize(m_params.numTexIds);
1309e5c31af7Sopenharmony_ci		gl.genTextures(m_params.numTexIds, m_texIds.data());
1310e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
1311e5c31af7Sopenharmony_ci	}
1312e5c31af7Sopenharmony_ci	if (m_params.numRboIds > 0)
1313e5c31af7Sopenharmony_ci	{
1314e5c31af7Sopenharmony_ci		m_rboIds.resize(m_params.numRboIds);
1315e5c31af7Sopenharmony_ci		gl.genRenderbuffers(m_params.numRboIds, m_rboIds.data());
1316e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers() failed");
1317e5c31af7Sopenharmony_ci	}
1318e5c31af7Sopenharmony_ci}
1319e5c31af7Sopenharmony_ci
1320e5c31af7Sopenharmony_civoid FramebufferCompletenessTestCase::deinit(void)
1321e5c31af7Sopenharmony_ci{
1322e5c31af7Sopenharmony_ci	const auto& renderContext	= m_context.getRenderContext();
1323e5c31af7Sopenharmony_ci	const auto& gl				= renderContext.getFunctions();
1324e5c31af7Sopenharmony_ci
1325e5c31af7Sopenharmony_ci	if (!m_rboIds.empty())
1326e5c31af7Sopenharmony_ci	{
1327e5c31af7Sopenharmony_ci		gl.deleteRenderbuffers(m_params.numRboIds, m_rboIds.data());
1328e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteRenderbuffers() failed");
1329e5c31af7Sopenharmony_ci		m_rboIds.clear();
1330e5c31af7Sopenharmony_ci	}
1331e5c31af7Sopenharmony_ci	if (!m_texIds.empty())
1332e5c31af7Sopenharmony_ci	{
1333e5c31af7Sopenharmony_ci		gl.deleteTextures(m_params.numTexIds, m_texIds.data());
1334e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() failed");
1335e5c31af7Sopenharmony_ci		m_texIds.clear();
1336e5c31af7Sopenharmony_ci	}
1337e5c31af7Sopenharmony_ci	if (!m_fboIds.empty())
1338e5c31af7Sopenharmony_ci	{
1339e5c31af7Sopenharmony_ci		gl.deleteFramebuffers(m_params.numFboIds, m_fboIds.data());
1340e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteFramebufers() failed");
1341e5c31af7Sopenharmony_ci		m_fboIds.clear();
1342e5c31af7Sopenharmony_ci	}
1343e5c31af7Sopenharmony_ci}
1344e5c31af7Sopenharmony_ci
1345e5c31af7Sopenharmony_citcu::TestNode::IterateResult FramebufferCompletenessTestCase::iterate(void)
1346e5c31af7Sopenharmony_ci{
1347e5c31af7Sopenharmony_ci	const auto& renderContext	= m_context.getRenderContext();
1348e5c31af7Sopenharmony_ci	const auto& gl				= renderContext.getFunctions();
1349e5c31af7Sopenharmony_ci	TestContext context			=
1350e5c31af7Sopenharmony_ci	{
1351e5c31af7Sopenharmony_ci		renderContext,	// const glu::RenderContext&	renderContext
1352e5c31af7Sopenharmony_ci		gl,				// const glw::Functions&		gl
1353e5c31af7Sopenharmony_ci		m_fboIds,		// vector<GLuint>&				fboIds
1354e5c31af7Sopenharmony_ci		m_texIds,		// vector<GLuint>&				texIds
1355e5c31af7Sopenharmony_ci		m_rboIds		// vector<GLuint>&				rboIds
1356e5c31af7Sopenharmony_ci	};
1357e5c31af7Sopenharmony_ci	auto steps = vector<TestStep>(m_params.initialSteps);
1358e5c31af7Sopenharmony_ci	if (m_params.stepsGenerator != DE_NULL)
1359e5c31af7Sopenharmony_ci		m_params.stepsGenerator(steps, context);
1360e5c31af7Sopenharmony_ci
1361e5c31af7Sopenharmony_ci	if (steps.empty())
1362e5c31af7Sopenharmony_ci	{
1363e5c31af7Sopenharmony_ci		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
1364e5c31af7Sopenharmony_ci		return STOP;
1365e5c31af7Sopenharmony_ci	}
1366e5c31af7Sopenharmony_ci
1367e5c31af7Sopenharmony_ci	size_t stepIndex = 0;
1368e5c31af7Sopenharmony_ci	for (const auto& step : steps)
1369e5c31af7Sopenharmony_ci	{
1370e5c31af7Sopenharmony_ci		step.testFn(context);
1371e5c31af7Sopenharmony_ci
1372e5c31af7Sopenharmony_ci		if (!verifyFramebufferStatus(gl, step.expectedFbStatus, stepIndex++))
1373e5c31af7Sopenharmony_ci			return STOP;
1374e5c31af7Sopenharmony_ci	}
1375e5c31af7Sopenharmony_ci	return STOP;
1376e5c31af7Sopenharmony_ci}
1377e5c31af7Sopenharmony_ci
1378e5c31af7Sopenharmony_cibool FramebufferCompletenessTestCase::verifyFramebufferStatus(const glw::Functions& gl, const ExpectedStatusFn expectedStatusFn,
1379e5c31af7Sopenharmony_ci												  const size_t stepIndex)
1380e5c31af7Sopenharmony_ci{
1381e5c31af7Sopenharmony_ci	static const map<GLenum, string>	statusNames	=
1382e5c31af7Sopenharmony_ci	{
1383e5c31af7Sopenharmony_ci		{ GL_FRAMEBUFFER_COMPLETE						, "GL_FRAMEBUFFER_COMPLETE" },
1384e5c31af7Sopenharmony_ci		{ GL_FRAMEBUFFER_UNDEFINED						, "GL_FRAMEBUFFER_UNDEFINED" },
1385e5c31af7Sopenharmony_ci		{ GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT			, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT" },
1386e5c31af7Sopenharmony_ci		{ GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT	, "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT" },
1387e5c31af7Sopenharmony_ci		{ GL_FRAMEBUFFER_UNSUPPORTED					, "GL_FRAMEBUFFER_UNSUPPORTED" },
1388e5c31af7Sopenharmony_ci		{ GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE			, "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE" },
1389e5c31af7Sopenharmony_ci		{ GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS			, "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS" }
1390e5c31af7Sopenharmony_ci	};
1391e5c31af7Sopenharmony_ci	const auto expectedStatus	= expectedStatusFn(m_context.getContextInfo());
1392e5c31af7Sopenharmony_ci	const auto fboStatus		= gl.checkFramebufferStatus(GL_FRAMEBUFFER);
1393e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glCheckFramebufferStatus() failed");
1394e5c31af7Sopenharmony_ci	if (fboStatus != expectedStatus)
1395e5c31af7Sopenharmony_ci	{
1396e5c31af7Sopenharmony_ci		ostringstream					msg;
1397e5c31af7Sopenharmony_ci		const auto&						fboStatusName		= statusNames.find(fboStatus);
1398e5c31af7Sopenharmony_ci		const auto&						expectedStatusName	= statusNames.find(expectedStatus);
1399e5c31af7Sopenharmony_ci		msg << "Frame buffer status ("
1400e5c31af7Sopenharmony_ci			<< ((fboStatusName != statusNames.end()) ? fboStatusName->second : std::to_string(fboStatus))
1401e5c31af7Sopenharmony_ci			<< ") does not match the expected status ("
1402e5c31af7Sopenharmony_ci			<< ((expectedStatusName != statusNames.end()) ? expectedStatusName->second : std::to_string(expectedStatus))
1403e5c31af7Sopenharmony_ci			<< ") after step " << stepIndex;
1404e5c31af7Sopenharmony_ci		TCU_FAIL(msg.str().c_str());
1405e5c31af7Sopenharmony_ci		return false;
1406e5c31af7Sopenharmony_ci	}
1407e5c31af7Sopenharmony_ci	m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
1408e5c31af7Sopenharmony_ci	return true;
1409e5c31af7Sopenharmony_ci}
1410e5c31af7Sopenharmony_ci
1411e5c31af7Sopenharmony_ci} // namespace
1412e5c31af7Sopenharmony_ci
1413e5c31af7Sopenharmony_ciFramebufferCompletenessTests::FramebufferCompletenessTests(deqp::Context& context)
1414e5c31af7Sopenharmony_ci	: deqp::TestCaseGroup(context, "framebuffer_completeness", "Tests for frame buffer completeness")
1415e5c31af7Sopenharmony_ci{
1416e5c31af7Sopenharmony_ci}
1417e5c31af7Sopenharmony_ci
1418e5c31af7Sopenharmony_civoid FramebufferCompletenessTests::init(void)
1419e5c31af7Sopenharmony_ci{
1420e5c31af7Sopenharmony_ci	const auto& renderContext	= m_context.getRenderContext();
1421e5c31af7Sopenharmony_ci	for (const auto& test : tests)
1422e5c31af7Sopenharmony_ci	{
1423e5c31af7Sopenharmony_ci		if (!glu::contextSupports(renderContext.getType(), test.apiType))
1424e5c31af7Sopenharmony_ci			continue;
1425e5c31af7Sopenharmony_ci
1426e5c31af7Sopenharmony_ci		addChild(new FramebufferCompletenessTestCase(m_context, test));
1427e5c31af7Sopenharmony_ci	}
1428e5c31af7Sopenharmony_ci}
1429e5c31af7Sopenharmony_ci
1430e5c31af7Sopenharmony_ci} // namespace es3cts
1431