1e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * OpenGL Conformance Test Suite
3e5c31af7Sopenharmony_ci * -----------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright (c) 2017 The Khronos Group Inc.
6e5c31af7Sopenharmony_ci *
7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
10e5c31af7Sopenharmony_ci *
11e5c31af7Sopenharmony_ci *      http://www.apache.org/licenses/LICENSE-2.0
12e5c31af7Sopenharmony_ci *
13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
17e5c31af7Sopenharmony_ci * limitations under the License.
18e5c31af7Sopenharmony_ci *
19e5c31af7Sopenharmony_ci */ /*!
20e5c31af7Sopenharmony_ci * \file
21e5c31af7Sopenharmony_ci * \brief
22e5c31af7Sopenharmony_ci */ /*-------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci/**
25e5c31af7Sopenharmony_ci */ /*!
26e5c31af7Sopenharmony_ci * \file  gl4cShaderViewportLayerArrayTests.cpp
27e5c31af7Sopenharmony_ci * \brief Conformance tests for the ARB_shader_viewport_layer_array functionality.
28e5c31af7Sopenharmony_ci */ /*-------------------------------------------------------------------*/
29e5c31af7Sopenharmony_ci
30e5c31af7Sopenharmony_ci#include "gl4cShaderViewportLayerArrayTests.hpp"
31e5c31af7Sopenharmony_ci#include "gluContextInfo.hpp"
32e5c31af7Sopenharmony_ci#include "gluDefs.hpp"
33e5c31af7Sopenharmony_ci#include "gluDrawUtil.hpp"
34e5c31af7Sopenharmony_ci#include "gluObjectWrapper.hpp"
35e5c31af7Sopenharmony_ci#include "gluShaderProgram.hpp"
36e5c31af7Sopenharmony_ci#include "glwEnums.hpp"
37e5c31af7Sopenharmony_ci#include "glwFunctions.hpp"
38e5c31af7Sopenharmony_ci#include "tcuRenderTarget.hpp"
39e5c31af7Sopenharmony_ci
40e5c31af7Sopenharmony_ci#include <sstream>
41e5c31af7Sopenharmony_ci#include <string>
42e5c31af7Sopenharmony_ci#include <vector>
43e5c31af7Sopenharmony_ci
44e5c31af7Sopenharmony_ciusing namespace glw;
45e5c31af7Sopenharmony_ci
46e5c31af7Sopenharmony_cinamespace gl4cts
47e5c31af7Sopenharmony_ci{
48e5c31af7Sopenharmony_ci
49e5c31af7Sopenharmony_ciShaderViewportLayerArrayUtils::ShaderPipeline::ShaderPipeline(bool tessellationShader, bool geometryShader,
50e5c31af7Sopenharmony_ci															  int maxViewportsLayers, const std::string& varName)
51e5c31af7Sopenharmony_ci	: m_program(NULL)
52e5c31af7Sopenharmony_ci	, m_hasTessellationShader(tessellationShader)
53e5c31af7Sopenharmony_ci	, m_hasGeometryShader(geometryShader)
54e5c31af7Sopenharmony_ci	, m_viewportLayerOffset(m_hasGeometryShader ? OFFSET_GEOMETRY :
55e5c31af7Sopenharmony_ci												  m_hasTessellationShader ? OFFSET_TESSELLATION : OFFSET_VERTEX)
56e5c31af7Sopenharmony_ci	, m_varName(varName)
57e5c31af7Sopenharmony_ci{
58e5c31af7Sopenharmony_ci	m_vs = "#version 450 core\n"
59e5c31af7Sopenharmony_ci		   "#extension GL_ARB_shader_viewport_layer_array: require\n"
60e5c31af7Sopenharmony_ci		   "in highp vec2 inPosition;\n"
61e5c31af7Sopenharmony_ci		   "in int in<var_name>;\n"
62e5c31af7Sopenharmony_ci		   "in highp vec4 inColor;\n"
63e5c31af7Sopenharmony_ci		   "out int vs<var_name>;\n"
64e5c31af7Sopenharmony_ci		   "out highp vec3 vsPosition;\n"
65e5c31af7Sopenharmony_ci		   "out highp vec4 vsColor;\n"
66e5c31af7Sopenharmony_ci		   "void main()\n"
67e5c31af7Sopenharmony_ci		   "{\n"
68e5c31af7Sopenharmony_ci		   "	gl_Position = vec4(inPosition, 0.0, 1.0);\n"
69e5c31af7Sopenharmony_ci		   "	gl_<var_name> = (in<var_name> + <viewport_layer_offset>) % <viewport_layer_max>;\n"
70e5c31af7Sopenharmony_ci		   "	vs<var_name> = in<var_name>;\n"
71e5c31af7Sopenharmony_ci		   "	vsPosition = vec3(inPosition, 0.0);\n"
72e5c31af7Sopenharmony_ci		   "	vsColor = inColor;\n"
73e5c31af7Sopenharmony_ci		   "}\n";
74e5c31af7Sopenharmony_ci
75e5c31af7Sopenharmony_ci	m_tcs = "#version 450 core\n"
76e5c31af7Sopenharmony_ci			"layout(vertices = 3) out;\n"
77e5c31af7Sopenharmony_ci			"in highp vec3 vsPosition[];\n"
78e5c31af7Sopenharmony_ci			"in highp vec4 vsColor[];\n"
79e5c31af7Sopenharmony_ci			"in int vs<var_name>[];\n"
80e5c31af7Sopenharmony_ci			"out highp vec3 tcsPosition[];\n"
81e5c31af7Sopenharmony_ci			"out highp vec4 tcsColor[];\n"
82e5c31af7Sopenharmony_ci			"out int tcs<var_name>[];\n"
83e5c31af7Sopenharmony_ci			"void main()\n"
84e5c31af7Sopenharmony_ci			"{\n"
85e5c31af7Sopenharmony_ci			"	tcsPosition[gl_InvocationID] = vsPosition[gl_InvocationID];\n"
86e5c31af7Sopenharmony_ci			"	tcsColor[gl_InvocationID] = vsColor[gl_InvocationID];\n"
87e5c31af7Sopenharmony_ci			"	tcs<var_name>[gl_InvocationID] = vs<var_name>[gl_InvocationID];\n"
88e5c31af7Sopenharmony_ci			"	gl_TessLevelInner[0] = 3;\n"
89e5c31af7Sopenharmony_ci			"	gl_TessLevelOuter[0] = 3;\n"
90e5c31af7Sopenharmony_ci			"	gl_TessLevelOuter[1] = 3;\n"
91e5c31af7Sopenharmony_ci			"	gl_TessLevelOuter[2] = 3;\n"
92e5c31af7Sopenharmony_ci			"}\n";
93e5c31af7Sopenharmony_ci
94e5c31af7Sopenharmony_ci	m_tes = "#version 450 core\n"
95e5c31af7Sopenharmony_ci			"#extension GL_ARB_shader_viewport_layer_array: require\n"
96e5c31af7Sopenharmony_ci			"layout(triangles, equal_spacing, cw) in;\n"
97e5c31af7Sopenharmony_ci			"in highp vec3 tcsPosition[];\n"
98e5c31af7Sopenharmony_ci			"in highp vec4 tcsColor[];\n"
99e5c31af7Sopenharmony_ci			"in int tcs<var_name>[];\n"
100e5c31af7Sopenharmony_ci			"out highp vec4 tesColor;\n"
101e5c31af7Sopenharmony_ci			"out highp int tes<var_name>;\n"
102e5c31af7Sopenharmony_ci			"void main()\n"
103e5c31af7Sopenharmony_ci			"{\n"
104e5c31af7Sopenharmony_ci			"	vec3 p0 = gl_TessCoord.x * tcsPosition[0];\n"
105e5c31af7Sopenharmony_ci			"	vec3 p1 = gl_TessCoord.y * tcsPosition[1];\n"
106e5c31af7Sopenharmony_ci			"	vec3 p2 = gl_TessCoord.z * tcsPosition[2];\n"
107e5c31af7Sopenharmony_ci			"	tesColor = tcsColor[0];\n"
108e5c31af7Sopenharmony_ci			"	tes<var_name> = tcs<var_name>[0];\n"
109e5c31af7Sopenharmony_ci			"	gl_<var_name> = (tcs<var_name>[0] + <viewport_layer_offset>) % <viewport_layer_max>;\n"
110e5c31af7Sopenharmony_ci			"	gl_Position = vec4(normalize(p0 + p1 + p2), 1.0);\n"
111e5c31af7Sopenharmony_ci			"}\n";
112e5c31af7Sopenharmony_ci
113e5c31af7Sopenharmony_ci	m_gs = "#version 450 core\n"
114e5c31af7Sopenharmony_ci		   "#extension GL_ARB_shader_viewport_layer_array: require\n"
115e5c31af7Sopenharmony_ci		   "layout(triangles) in;\n"
116e5c31af7Sopenharmony_ci		   "layout(triangle_strip, max_vertices = 3) out;\n"
117e5c31af7Sopenharmony_ci		   "in highp vec4 tesColor[];\n"
118e5c31af7Sopenharmony_ci		   "in int tes<var_name>[];\n"
119e5c31af7Sopenharmony_ci		   "out highp vec4 gsColor;\n"
120e5c31af7Sopenharmony_ci		   "void main()\n"
121e5c31af7Sopenharmony_ci		   "{\n"
122e5c31af7Sopenharmony_ci		   "	for (int i = 0; i<3; i++)\n"
123e5c31af7Sopenharmony_ci		   "	{\n"
124e5c31af7Sopenharmony_ci		   "		gl_Position = gl_in[i].gl_Position;\n"
125e5c31af7Sopenharmony_ci		   "		gl_<var_name> = (tes<var_name>[i] + <viewport_layer_offset>) % <viewport_layer_max>;\n"
126e5c31af7Sopenharmony_ci		   "		gsColor = tesColor[i];\n"
127e5c31af7Sopenharmony_ci		   "		EmitVertex();\n"
128e5c31af7Sopenharmony_ci		   "	}\n"
129e5c31af7Sopenharmony_ci		   "	EndPrimitive();\n"
130e5c31af7Sopenharmony_ci		   "}\n";
131e5c31af7Sopenharmony_ci
132e5c31af7Sopenharmony_ci	m_fs = "#version 450 core\n"
133e5c31af7Sopenharmony_ci		   "in highp vec4 <input_color>;\n"
134e5c31af7Sopenharmony_ci		   "out vec4 finalOutColor;\n"
135e5c31af7Sopenharmony_ci		   "void main()\n"
136e5c31af7Sopenharmony_ci		   "{\n"
137e5c31af7Sopenharmony_ci		   "	finalOutColor = <input_color>;\n"
138e5c31af7Sopenharmony_ci		   "}\n";
139e5c31af7Sopenharmony_ci
140e5c31af7Sopenharmony_ci	this->adaptShaderToPipeline(m_vs, "<var_name>", varName);
141e5c31af7Sopenharmony_ci	this->adaptShaderToPipeline(m_vs, "<viewport_layer_offset>", OFFSET_VERTEX);
142e5c31af7Sopenharmony_ci	this->adaptShaderToPipeline(m_vs, "<viewport_layer_max>", maxViewportsLayers);
143e5c31af7Sopenharmony_ci
144e5c31af7Sopenharmony_ci	this->adaptShaderToPipeline(m_tes, "<var_name>", varName);
145e5c31af7Sopenharmony_ci	this->adaptShaderToPipeline(m_tes, "<viewport_layer_offset>", OFFSET_TESSELLATION);
146e5c31af7Sopenharmony_ci	this->adaptShaderToPipeline(m_tes, "<viewport_layer_max>", maxViewportsLayers);
147e5c31af7Sopenharmony_ci
148e5c31af7Sopenharmony_ci	this->adaptShaderToPipeline(m_tcs, "<var_name>", varName);
149e5c31af7Sopenharmony_ci
150e5c31af7Sopenharmony_ci	this->adaptShaderToPipeline(m_gs, "<var_name>", varName);
151e5c31af7Sopenharmony_ci	this->adaptShaderToPipeline(m_gs, "<viewport_layer_offset>", OFFSET_GEOMETRY);
152e5c31af7Sopenharmony_ci	this->adaptShaderToPipeline(m_gs, "<viewport_layer_max>", maxViewportsLayers);
153e5c31af7Sopenharmony_ci
154e5c31af7Sopenharmony_ci	this->adaptShaderToPipeline(m_fs, "<input_color>", "vsColor", "tesColor", "gsColor");
155e5c31af7Sopenharmony_ci}
156e5c31af7Sopenharmony_ci
157e5c31af7Sopenharmony_civoid ShaderViewportLayerArrayUtils::ShaderPipeline::adaptShaderToPipeline(std::string&		 shader,
158e5c31af7Sopenharmony_ci																		  const std::string& varKey,
159e5c31af7Sopenharmony_ci																		  const std::string& vsVersion,
160e5c31af7Sopenharmony_ci																		  const std::string& tesVersion,
161e5c31af7Sopenharmony_ci																		  const std::string& gsVersion)
162e5c31af7Sopenharmony_ci{
163e5c31af7Sopenharmony_ci	std::string varName = m_hasGeometryShader ? gsVersion : m_hasTessellationShader ? tesVersion : vsVersion;
164e5c31af7Sopenharmony_ci
165e5c31af7Sopenharmony_ci	size_t start = 0;
166e5c31af7Sopenharmony_ci	while ((start = shader.find(varKey, start)) != std::string::npos)
167e5c31af7Sopenharmony_ci	{
168e5c31af7Sopenharmony_ci		shader.replace(start, varKey.length(), varName);
169e5c31af7Sopenharmony_ci		start += varName.length();
170e5c31af7Sopenharmony_ci	}
171e5c31af7Sopenharmony_ci}
172e5c31af7Sopenharmony_ci
173e5c31af7Sopenharmony_civoid ShaderViewportLayerArrayUtils::ShaderPipeline::adaptShaderToPipeline(std::string&		 shader,
174e5c31af7Sopenharmony_ci																		  const std::string& varKey,
175e5c31af7Sopenharmony_ci																		  const std::string& value)
176e5c31af7Sopenharmony_ci{
177e5c31af7Sopenharmony_ci	this->adaptShaderToPipeline(shader, varKey, value, value, value);
178e5c31af7Sopenharmony_ci}
179e5c31af7Sopenharmony_ci
180e5c31af7Sopenharmony_civoid ShaderViewportLayerArrayUtils::ShaderPipeline::adaptShaderToPipeline(std::string&		 shader,
181e5c31af7Sopenharmony_ci																		  const std::string& varKey, int value)
182e5c31af7Sopenharmony_ci{
183e5c31af7Sopenharmony_ci	std::ostringstream valueStr;
184e5c31af7Sopenharmony_ci	valueStr << value;
185e5c31af7Sopenharmony_ci
186e5c31af7Sopenharmony_ci	this->adaptShaderToPipeline(shader, varKey, valueStr.str(), valueStr.str(), valueStr.str());
187e5c31af7Sopenharmony_ci}
188e5c31af7Sopenharmony_ci
189e5c31af7Sopenharmony_ciShaderViewportLayerArrayUtils::ShaderPipeline::~ShaderPipeline()
190e5c31af7Sopenharmony_ci{
191e5c31af7Sopenharmony_ci	if (m_program)
192e5c31af7Sopenharmony_ci	{
193e5c31af7Sopenharmony_ci		delete m_program;
194e5c31af7Sopenharmony_ci	}
195e5c31af7Sopenharmony_ci}
196e5c31af7Sopenharmony_ci
197e5c31af7Sopenharmony_civoid ShaderViewportLayerArrayUtils::ShaderPipeline::create(const glu::RenderContext& context)
198e5c31af7Sopenharmony_ci{
199e5c31af7Sopenharmony_ci	glu::ProgramSources sources;
200e5c31af7Sopenharmony_ci	sources.sources[glu::SHADERTYPE_VERTEX].push_back(m_vs);
201e5c31af7Sopenharmony_ci	if (m_hasTessellationShader)
202e5c31af7Sopenharmony_ci	{
203e5c31af7Sopenharmony_ci		sources.sources[glu::SHADERTYPE_TESSELLATION_CONTROL].push_back(m_tcs);
204e5c31af7Sopenharmony_ci		sources.sources[glu::SHADERTYPE_TESSELLATION_EVALUATION].push_back(m_tes);
205e5c31af7Sopenharmony_ci	}
206e5c31af7Sopenharmony_ci	if (m_hasGeometryShader)
207e5c31af7Sopenharmony_ci	{
208e5c31af7Sopenharmony_ci		sources.sources[glu::SHADERTYPE_GEOMETRY].push_back(m_gs);
209e5c31af7Sopenharmony_ci	}
210e5c31af7Sopenharmony_ci	sources.sources[glu::SHADERTYPE_FRAGMENT].push_back(m_fs);
211e5c31af7Sopenharmony_ci
212e5c31af7Sopenharmony_ci	m_program = new glu::ShaderProgram(context, sources);
213e5c31af7Sopenharmony_ci	if (!m_program->isOk())
214e5c31af7Sopenharmony_ci	{
215e5c31af7Sopenharmony_ci		TCU_FAIL("Shader compilation failed");
216e5c31af7Sopenharmony_ci	}
217e5c31af7Sopenharmony_ci}
218e5c31af7Sopenharmony_ci
219e5c31af7Sopenharmony_civoid ShaderViewportLayerArrayUtils::ShaderPipeline::use(const glu::RenderContext& context)
220e5c31af7Sopenharmony_ci{
221e5c31af7Sopenharmony_ci	const glw::Functions& gl = context.getFunctions();
222e5c31af7Sopenharmony_ci	gl.useProgram(m_program->getProgram());
223e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram failed");
224e5c31af7Sopenharmony_ci}
225e5c31af7Sopenharmony_ci
226e5c31af7Sopenharmony_civoid ShaderViewportLayerArrayUtils::renderQuad(const glu::RenderContext& context, ShaderPipeline& shaderPipeline,
227e5c31af7Sopenharmony_ci											   int viewportLayerIndex, tcu::Vec4 color)
228e5c31af7Sopenharmony_ci{
229e5c31af7Sopenharmony_ci	const glw::Functions& gl = context.getFunctions();
230e5c31af7Sopenharmony_ci
231e5c31af7Sopenharmony_ci	deUint16 const quadIndices[] = { 0, 1, 2, 2, 1, 3 };
232e5c31af7Sopenharmony_ci
233e5c31af7Sopenharmony_ci	float const position[] = { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f };
234e5c31af7Sopenharmony_ci
235e5c31af7Sopenharmony_ci	int const viewportLayerIndices[] = { viewportLayerIndex, viewportLayerIndex, viewportLayerIndex,
236e5c31af7Sopenharmony_ci										 viewportLayerIndex };
237e5c31af7Sopenharmony_ci
238e5c31af7Sopenharmony_ci	float const colors[] = { color.x(), color.y(), color.z(), color.w(), color.x(), color.y(), color.z(), color.w(),
239e5c31af7Sopenharmony_ci							 color.x(), color.y(), color.z(), color.w(), color.x(), color.y(), color.z(), color.w() };
240e5c31af7Sopenharmony_ci
241e5c31af7Sopenharmony_ci	std::string varName = "in";
242e5c31af7Sopenharmony_ci	varName += shaderPipeline.getVarName();
243e5c31af7Sopenharmony_ci
244e5c31af7Sopenharmony_ci	glu::VertexArrayBinding vertexArrays[] = { glu::va::Float("inPosition", 2, 4, 0, position),
245e5c31af7Sopenharmony_ci											   glu::va::Int32(varName, 1, 4, 0, viewportLayerIndices),
246e5c31af7Sopenharmony_ci											   glu::va::Float("inColor", 4, 4, 0, colors) };
247e5c31af7Sopenharmony_ci
248e5c31af7Sopenharmony_ci	shaderPipeline.use(context);
249e5c31af7Sopenharmony_ci
250e5c31af7Sopenharmony_ci	glu::PrimitiveList primitiveList = shaderPipeline.hasTessellationShader() ?
251e5c31af7Sopenharmony_ci										   glu::pr::Patches(DE_LENGTH_OF_ARRAY(quadIndices), quadIndices) :
252e5c31af7Sopenharmony_ci										   glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(quadIndices), quadIndices);
253e5c31af7Sopenharmony_ci
254e5c31af7Sopenharmony_ci	glu::draw(context, shaderPipeline.getShaderProgram()->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays,
255e5c31af7Sopenharmony_ci			  primitiveList, (glu::DrawUtilCallback*)DE_NULL);
256e5c31af7Sopenharmony_ci
257e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glu::draw error");
258e5c31af7Sopenharmony_ci}
259e5c31af7Sopenharmony_ci
260e5c31af7Sopenharmony_cibool ShaderViewportLayerArrayUtils::validateColor(tcu::Vec4 renderedColor, tcu::Vec4 referenceColor)
261e5c31af7Sopenharmony_ci{
262e5c31af7Sopenharmony_ci	const float epsilon = 1.1f / 31.0f; // Accommodate framebuffers with 5-bit channels.
263e5c31af7Sopenharmony_ci	return de::abs(renderedColor.x() - referenceColor.x()) < epsilon &&
264e5c31af7Sopenharmony_ci		   de::abs(renderedColor.y() - referenceColor.y()) < epsilon &&
265e5c31af7Sopenharmony_ci		   de::abs(renderedColor.z() - referenceColor.z()) < epsilon &&
266e5c31af7Sopenharmony_ci		   de::abs(renderedColor.w() - referenceColor.w()) < epsilon;
267e5c31af7Sopenharmony_ci}
268e5c31af7Sopenharmony_ci
269e5c31af7Sopenharmony_ciglw::GLint ShaderViewportIndexTestCase::createMaxViewports()
270e5c31af7Sopenharmony_ci{
271e5c31af7Sopenharmony_ci	const Functions&		gl			 = m_context.getRenderContext().getFunctions();
272e5c31af7Sopenharmony_ci	const tcu::RenderTarget renderTarget = m_context.getRenderContext().getRenderTarget();
273e5c31af7Sopenharmony_ci	const GLfloat			targetWidth  = (GLfloat)renderTarget.getWidth();
274e5c31af7Sopenharmony_ci
275e5c31af7Sopenharmony_ci	GLint maxViewports = 0;
276e5c31af7Sopenharmony_ci	gl.getIntegerv(GL_MAX_VIEWPORTS, &maxViewports);
277e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv error");
278e5c31af7Sopenharmony_ci
279e5c31af7Sopenharmony_ci	const int				  viewportDataSize = 4; // x + y + w + h
280e5c31af7Sopenharmony_ci	std::vector<glw::GLfloat> data(maxViewports * viewportDataSize);
281e5c31af7Sopenharmony_ci
282e5c31af7Sopenharmony_ci	GLfloat viewportWidth  = 16.0f;
283e5c31af7Sopenharmony_ci	GLfloat viewportHeight = 16.0f;
284e5c31af7Sopenharmony_ci
285e5c31af7Sopenharmony_ci	int currentX = 0;
286e5c31af7Sopenharmony_ci	int currentY = 0;
287e5c31af7Sopenharmony_ci	for (GLint i = 0; i < maxViewports; ++i)
288e5c31af7Sopenharmony_ci	{
289e5c31af7Sopenharmony_ci		GLfloat x = (GLfloat)currentX * viewportWidth;
290e5c31af7Sopenharmony_ci		if (x > (targetWidth - viewportWidth))
291e5c31af7Sopenharmony_ci		{
292e5c31af7Sopenharmony_ci			x		 = 0.0f;
293e5c31af7Sopenharmony_ci			currentX = 0;
294e5c31af7Sopenharmony_ci			currentY++;
295e5c31af7Sopenharmony_ci		}
296e5c31af7Sopenharmony_ci		GLfloat y = (GLfloat)currentY * viewportHeight;
297e5c31af7Sopenharmony_ci
298e5c31af7Sopenharmony_ci		data[i * viewportDataSize + 0] = x;
299e5c31af7Sopenharmony_ci		data[i * viewportDataSize + 1] = y;
300e5c31af7Sopenharmony_ci		data[i * viewportDataSize + 2] = viewportWidth;
301e5c31af7Sopenharmony_ci		data[i * viewportDataSize + 3] = viewportHeight;
302e5c31af7Sopenharmony_ci
303e5c31af7Sopenharmony_ci		m_viewportData.push_back(tcu::Vec4(x, y, viewportWidth, viewportHeight));
304e5c31af7Sopenharmony_ci
305e5c31af7Sopenharmony_ci		currentX++;
306e5c31af7Sopenharmony_ci	}
307e5c31af7Sopenharmony_ci
308e5c31af7Sopenharmony_ci	gl.viewportArrayv(0, maxViewports, data.data());
309e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "ViewportArrayv");
310e5c31af7Sopenharmony_ci
311e5c31af7Sopenharmony_ci	return maxViewports;
312e5c31af7Sopenharmony_ci}
313e5c31af7Sopenharmony_ci
314e5c31af7Sopenharmony_ci/** Constructor.
315e5c31af7Sopenharmony_ci*
316e5c31af7Sopenharmony_ci*  @param context Rendering context
317e5c31af7Sopenharmony_ci*/
318e5c31af7Sopenharmony_ciShaderViewportIndexTestCase::ShaderViewportIndexTestCase(deqp::Context& context)
319e5c31af7Sopenharmony_ci	: TestCase(context, "ShaderViewportIndexTestCase",
320e5c31af7Sopenharmony_ci			   "Implements gl_ViewportIndex tests described in CTS_ARB_shader_viewport_layer_array")
321e5c31af7Sopenharmony_ci	, m_maxViewports(0)
322e5c31af7Sopenharmony_ci	, m_currentViewport(0)
323e5c31af7Sopenharmony_ci{
324e5c31af7Sopenharmony_ci	m_isExtensionSupported = context.getContextInfo().isExtensionSupported("GL_ARB_shader_viewport_layer_array");
325e5c31af7Sopenharmony_ci}
326e5c31af7Sopenharmony_ci
327e5c31af7Sopenharmony_civoid ShaderViewportIndexTestCase::init()
328e5c31af7Sopenharmony_ci{
329e5c31af7Sopenharmony_ci	if (!m_isExtensionSupported)
330e5c31af7Sopenharmony_ci		return;
331e5c31af7Sopenharmony_ci
332e5c31af7Sopenharmony_ci	m_maxViewports = this->createMaxViewports();
333e5c31af7Sopenharmony_ci
334e5c31af7Sopenharmony_ci	m_shaderPipelines.push_back(
335e5c31af7Sopenharmony_ci		ShaderViewportLayerArrayUtils::ShaderPipeline(false, false, m_maxViewports, "ViewportIndex"));
336e5c31af7Sopenharmony_ci	m_shaderPipelines.push_back(
337e5c31af7Sopenharmony_ci		ShaderViewportLayerArrayUtils::ShaderPipeline(true, false, m_maxViewports, "ViewportIndex"));
338e5c31af7Sopenharmony_ci	m_shaderPipelines.push_back(
339e5c31af7Sopenharmony_ci		ShaderViewportLayerArrayUtils::ShaderPipeline(true, true, m_maxViewports, "ViewportIndex"));
340e5c31af7Sopenharmony_ci
341e5c31af7Sopenharmony_ci	for (ShaderPipelineIter iter = m_shaderPipelines.begin(); iter != m_shaderPipelines.end(); ++iter)
342e5c31af7Sopenharmony_ci	{
343e5c31af7Sopenharmony_ci		iter->create(m_context.getRenderContext());
344e5c31af7Sopenharmony_ci	}
345e5c31af7Sopenharmony_ci}
346e5c31af7Sopenharmony_ci
347e5c31af7Sopenharmony_civoid ShaderViewportIndexTestCase::deinit()
348e5c31af7Sopenharmony_ci{
349e5c31af7Sopenharmony_ci	const Functions&		gl			 = m_context.getRenderContext().getFunctions();
350e5c31af7Sopenharmony_ci	const tcu::RenderTarget renderTarget = m_context.getRenderContext().getRenderTarget();
351e5c31af7Sopenharmony_ci
352e5c31af7Sopenharmony_ci	gl.viewport(0, 0, renderTarget.getWidth(), renderTarget.getHeight());
353e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
354e5c31af7Sopenharmony_ci}
355e5c31af7Sopenharmony_ci
356e5c31af7Sopenharmony_ci/** Executes test iteration.
357e5c31af7Sopenharmony_ci *
358e5c31af7Sopenharmony_ci *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
359e5c31af7Sopenharmony_ci */
360e5c31af7Sopenharmony_citcu::TestNode::IterateResult ShaderViewportIndexTestCase::iterate()
361e5c31af7Sopenharmony_ci{
362e5c31af7Sopenharmony_ci	if (!m_isExtensionSupported)
363e5c31af7Sopenharmony_ci	{
364e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported");
365e5c31af7Sopenharmony_ci		return STOP;
366e5c31af7Sopenharmony_ci	}
367e5c31af7Sopenharmony_ci
368e5c31af7Sopenharmony_ci	const glw::Functions&	 gl			= m_context.getRenderContext().getFunctions();
369e5c31af7Sopenharmony_ci	const glu::RenderContext& renderContext = m_context.getRenderContext();
370e5c31af7Sopenharmony_ci
371e5c31af7Sopenharmony_ci	tcu::Vec4 renderColor((m_currentViewport + 1) / (float)m_maxViewports, 0.0f, 0.0f, 1.0f);
372e5c31af7Sopenharmony_ci	tcu::Vec4 backgroundColor(0.0f, 0.0f, 0.0f, 1.0f);
373e5c31af7Sopenharmony_ci
374e5c31af7Sopenharmony_ci	for (ShaderPipelineIter pipelineIter = m_shaderPipelines.begin(); pipelineIter != m_shaderPipelines.end();
375e5c31af7Sopenharmony_ci		 ++pipelineIter)
376e5c31af7Sopenharmony_ci	{
377e5c31af7Sopenharmony_ci		// rendering
378e5c31af7Sopenharmony_ci
379e5c31af7Sopenharmony_ci		gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
380e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "ClearColor");
381e5c31af7Sopenharmony_ci		gl.clear(GL_COLOR_BUFFER_BIT);
382e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "Clear");
383e5c31af7Sopenharmony_ci		ShaderViewportLayerArrayUtils::renderQuad(renderContext, *pipelineIter, m_currentViewport, renderColor);
384e5c31af7Sopenharmony_ci		gl.flush();
385e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "Flush");
386e5c31af7Sopenharmony_ci
387e5c31af7Sopenharmony_ci		// verification
388e5c31af7Sopenharmony_ci
389e5c31af7Sopenharmony_ci		std::vector<std::pair<tcu::Vec2, tcu::Vec4> > expectedPixels;
390e5c31af7Sopenharmony_ci
391e5c31af7Sopenharmony_ci		for (size_t i = 0; i < m_viewportData.size(); ++i)
392e5c31af7Sopenharmony_ci		{
393e5c31af7Sopenharmony_ci			tcu::Vec4 viewportData = m_viewportData[i];
394e5c31af7Sopenharmony_ci
395e5c31af7Sopenharmony_ci			int currentViewportWithOffset =
396e5c31af7Sopenharmony_ci				(m_currentViewport + pipelineIter->getViewportLayerOffset()) % m_maxViewports;
397e5c31af7Sopenharmony_ci
398e5c31af7Sopenharmony_ci			tcu::Vec2 center(viewportData.x() + viewportData.z() * 0.5f, viewportData.y() + viewportData.w() * 0.5f);
399e5c31af7Sopenharmony_ci
400e5c31af7Sopenharmony_ci			if (i == (unsigned int)currentViewportWithOffset)
401e5c31af7Sopenharmony_ci			{
402e5c31af7Sopenharmony_ci				expectedPixels.push_back(std::make_pair(center, renderColor));
403e5c31af7Sopenharmony_ci			}
404e5c31af7Sopenharmony_ci			else
405e5c31af7Sopenharmony_ci			{
406e5c31af7Sopenharmony_ci				expectedPixels.push_back(std::make_pair(center, backgroundColor));
407e5c31af7Sopenharmony_ci			}
408e5c31af7Sopenharmony_ci		}
409e5c31af7Sopenharmony_ci
410e5c31af7Sopenharmony_ci		for (size_t i = 0; i < expectedPixels.size(); ++i)
411e5c31af7Sopenharmony_ci		{
412e5c31af7Sopenharmony_ci			glw::GLfloat rgba[4] = { -1.f, -1.f, -1.f, -1.f };
413e5c31af7Sopenharmony_ci			gl.readPixels((glw::GLint)expectedPixels[i].first.x(), (glw::GLint)expectedPixels[i].first.y(), 1, 1,
414e5c31af7Sopenharmony_ci						  GL_RGBA, GL_FLOAT, rgba);
415e5c31af7Sopenharmony_ci			GLU_EXPECT_NO_ERROR(gl.getError(), "ReadPixels");
416e5c31af7Sopenharmony_ci			bool validationResult = ShaderViewportLayerArrayUtils::validateColor(
417e5c31af7Sopenharmony_ci				tcu::Vec4(rgba[0], rgba[1], rgba[2], rgba[3]), expectedPixels[i].second);
418e5c31af7Sopenharmony_ci			TCU_CHECK_MSG(validationResult, "Expected pixel color did not match rendered one.");
419e5c31af7Sopenharmony_ci		}
420e5c31af7Sopenharmony_ci	}
421e5c31af7Sopenharmony_ci
422e5c31af7Sopenharmony_ci	if (m_currentViewport < (m_maxViewports - 1))
423e5c31af7Sopenharmony_ci	{
424e5c31af7Sopenharmony_ci		m_currentViewport++;
425e5c31af7Sopenharmony_ci		return CONTINUE;
426e5c31af7Sopenharmony_ci	}
427e5c31af7Sopenharmony_ci
428e5c31af7Sopenharmony_ci	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
429e5c31af7Sopenharmony_ci	return STOP;
430e5c31af7Sopenharmony_ci}
431e5c31af7Sopenharmony_ci
432e5c31af7Sopenharmony_ciShaderLayerFramebufferTestCaseBase::ShaderLayerFramebufferTestCaseBase(deqp::Context& context, const char* name,
433e5c31af7Sopenharmony_ci																	   const char* description, bool layered)
434e5c31af7Sopenharmony_ci	: TestCase(context, name, description)
435e5c31af7Sopenharmony_ci	, m_layersNum(layered ? 4 : 1)
436e5c31af7Sopenharmony_ci	, m_fboSize(512)
437e5c31af7Sopenharmony_ci	, m_texture(0)
438e5c31af7Sopenharmony_ci	, m_mainFbo(0)
439e5c31af7Sopenharmony_ci	, m_currentLayer(0)
440e5c31af7Sopenharmony_ci{
441e5c31af7Sopenharmony_ci	m_isExtensionSupported = context.getContextInfo().isExtensionSupported("GL_ARB_shader_viewport_layer_array");
442e5c31af7Sopenharmony_ci}
443e5c31af7Sopenharmony_ci
444e5c31af7Sopenharmony_civoid ShaderLayerFramebufferTestCaseBase::init()
445e5c31af7Sopenharmony_ci{
446e5c31af7Sopenharmony_ci	if (!m_isExtensionSupported)
447e5c31af7Sopenharmony_ci		return;
448e5c31af7Sopenharmony_ci
449e5c31af7Sopenharmony_ci	const glw::Functions&	 gl			= m_context.getRenderContext().getFunctions();
450e5c31af7Sopenharmony_ci
451e5c31af7Sopenharmony_ci	this->createFBO();
452e5c31af7Sopenharmony_ci
453e5c31af7Sopenharmony_ci	m_shaderPipelines.push_back(ShaderViewportLayerArrayUtils::ShaderPipeline(false, false, m_layersNum, "Layer"));
454e5c31af7Sopenharmony_ci	m_shaderPipelines.push_back(ShaderViewportLayerArrayUtils::ShaderPipeline(true, false, m_layersNum, "Layer"));
455e5c31af7Sopenharmony_ci	m_shaderPipelines.push_back(ShaderViewportLayerArrayUtils::ShaderPipeline(true, true, m_layersNum, "Layer"));
456e5c31af7Sopenharmony_ci
457e5c31af7Sopenharmony_ci	for (ShaderPipelineIter iter = m_shaderPipelines.begin(); iter != m_shaderPipelines.end(); ++iter)
458e5c31af7Sopenharmony_ci	{
459e5c31af7Sopenharmony_ci		iter->create(m_context.getRenderContext());
460e5c31af7Sopenharmony_ci	}
461e5c31af7Sopenharmony_ci
462e5c31af7Sopenharmony_ci	gl.viewport(0, 0, m_fboSize, m_fboSize);
463e5c31af7Sopenharmony_ci}
464e5c31af7Sopenharmony_ci
465e5c31af7Sopenharmony_civoid ShaderLayerFramebufferTestCaseBase::deinit()
466e5c31af7Sopenharmony_ci{
467e5c31af7Sopenharmony_ci	const Functions&		gl			 = m_context.getRenderContext().getFunctions();
468e5c31af7Sopenharmony_ci	const tcu::RenderTarget renderTarget = m_context.getRenderContext().getRenderTarget();
469e5c31af7Sopenharmony_ci
470e5c31af7Sopenharmony_ci	gl.viewport(0, 0, renderTarget.getWidth(), renderTarget.getHeight());
471e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
472e5c31af7Sopenharmony_ci}
473e5c31af7Sopenharmony_ci
474e5c31af7Sopenharmony_ci
475e5c31af7Sopenharmony_citcu::TestNode::IterateResult ShaderLayerFramebufferTestCaseBase::iterate()
476e5c31af7Sopenharmony_ci{
477e5c31af7Sopenharmony_ci	if (!m_isExtensionSupported)
478e5c31af7Sopenharmony_ci	{
479e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported");
480e5c31af7Sopenharmony_ci		return STOP;
481e5c31af7Sopenharmony_ci	}
482e5c31af7Sopenharmony_ci
483e5c31af7Sopenharmony_ci	const glw::Functions&	 gl			= m_context.getRenderContext().getFunctions();
484e5c31af7Sopenharmony_ci	const glu::RenderContext& renderContext = m_context.getRenderContext();
485e5c31af7Sopenharmony_ci
486e5c31af7Sopenharmony_ci	tcu::Vec4 renderColor((m_currentLayer + 1) / (float)m_layersNum, 0.0f, 0.0f, 1.0f);
487e5c31af7Sopenharmony_ci
488e5c31af7Sopenharmony_ci	for (ShaderPipelineIter pipelineIter = m_shaderPipelines.begin(); pipelineIter != m_shaderPipelines.end();
489e5c31af7Sopenharmony_ci		 ++pipelineIter)
490e5c31af7Sopenharmony_ci	{
491e5c31af7Sopenharmony_ci		// bind main framebuffer (layered)
492e5c31af7Sopenharmony_ci		gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_mainFbo);
493e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
494e5c31af7Sopenharmony_ci
495e5c31af7Sopenharmony_ci		// render
496e5c31af7Sopenharmony_ci		gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
497e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "ClearColor");
498e5c31af7Sopenharmony_ci		gl.clear(GL_COLOR_BUFFER_BIT);
499e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "Clear");
500e5c31af7Sopenharmony_ci		ShaderViewportLayerArrayUtils::renderQuad(renderContext, *pipelineIter, m_currentLayer, renderColor);
501e5c31af7Sopenharmony_ci		gl.flush();
502e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "Flush");
503e5c31af7Sopenharmony_ci
504e5c31af7Sopenharmony_ci		// calculate layer offset (same value as gl_Layer in shader)
505e5c31af7Sopenharmony_ci		int currentLayerWithOffset = (m_currentLayer + pipelineIter->getViewportLayerOffset()) % m_layersNum;
506e5c31af7Sopenharmony_ci
507e5c31af7Sopenharmony_ci		// bind framebuffer of this layer
508e5c31af7Sopenharmony_ci		gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_fbos[currentLayerWithOffset]);
509e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer() call failed.");
510e5c31af7Sopenharmony_ci
511e5c31af7Sopenharmony_ci		// verification
512e5c31af7Sopenharmony_ci		glw::GLfloat rgba[4] = { -1.f, -1.f, -1.f, -1.f };
513e5c31af7Sopenharmony_ci		gl.readPixels(m_fboSize / 2, m_fboSize / 2, 1, 1, GL_RGBA, GL_FLOAT, rgba);
514e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "ReadPixels");
515e5c31af7Sopenharmony_ci		bool validationResult =
516e5c31af7Sopenharmony_ci			ShaderViewportLayerArrayUtils::validateColor(tcu::Vec4(rgba[0], rgba[1], rgba[2], rgba[3]), renderColor);
517e5c31af7Sopenharmony_ci
518e5c31af7Sopenharmony_ci		TCU_CHECK_MSG(validationResult, "Expected pixel color did not match rendered one.");
519e5c31af7Sopenharmony_ci	}
520e5c31af7Sopenharmony_ci
521e5c31af7Sopenharmony_ci	if (m_currentLayer < (m_layersNum - 1))
522e5c31af7Sopenharmony_ci	{
523e5c31af7Sopenharmony_ci		m_currentLayer++;
524e5c31af7Sopenharmony_ci		return CONTINUE;
525e5c31af7Sopenharmony_ci	}
526e5c31af7Sopenharmony_ci
527e5c31af7Sopenharmony_ci	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
528e5c31af7Sopenharmony_ci	return STOP;
529e5c31af7Sopenharmony_ci}
530e5c31af7Sopenharmony_ci
531e5c31af7Sopenharmony_ci/** Constructor.
532e5c31af7Sopenharmony_ci*
533e5c31af7Sopenharmony_ci*  @param context Rendering context
534e5c31af7Sopenharmony_ci*/
535e5c31af7Sopenharmony_ciShaderLayerFramebufferLayeredTestCase::ShaderLayerFramebufferLayeredTestCase(deqp::Context& context)
536e5c31af7Sopenharmony_ci	: ShaderLayerFramebufferTestCaseBase(
537e5c31af7Sopenharmony_ci		  context, "ShaderLayerFramebufferLayeredTestCase",
538e5c31af7Sopenharmony_ci		  "Implements gl_Layer tests for layered framebuffer described in CTS_ARB_shader_viewport_layer_array", true)
539e5c31af7Sopenharmony_ci{
540e5c31af7Sopenharmony_ci}
541e5c31af7Sopenharmony_ci
542e5c31af7Sopenharmony_civoid ShaderLayerFramebufferLayeredTestCase::createFBO()
543e5c31af7Sopenharmony_ci{
544e5c31af7Sopenharmony_ci	const Functions& gl = m_context.getRenderContext().getFunctions();
545e5c31af7Sopenharmony_ci
546e5c31af7Sopenharmony_ci	gl.genTextures(1, &m_texture);
547e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
548e5c31af7Sopenharmony_ci
549e5c31af7Sopenharmony_ci	gl.bindTexture(GL_TEXTURE_3D, m_texture);
550e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture() call failed.");
551e5c31af7Sopenharmony_ci
552e5c31af7Sopenharmony_ci	gl.texImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, m_fboSize, m_fboSize, m_layersNum, 0, GL_RGBA, GL_FLOAT, 0);
553e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "texImage3D() call failed.");
554e5c31af7Sopenharmony_ci
555e5c31af7Sopenharmony_ci	// create main FBO
556e5c31af7Sopenharmony_ci
557e5c31af7Sopenharmony_ci	gl.genFramebuffers(1, &m_mainFbo);
558e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "genFramebuffers() call failed.");
559e5c31af7Sopenharmony_ci	gl.bindFramebuffer(GL_FRAMEBUFFER, m_mainFbo);
560e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer() call failed.");
561e5c31af7Sopenharmony_ci	gl.framebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texture, 0);
562e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture() call failed.");
563e5c31af7Sopenharmony_ci
564e5c31af7Sopenharmony_ci	// create FBO for each layer
565e5c31af7Sopenharmony_ci
566e5c31af7Sopenharmony_ci	for (int i = 0; i < m_layersNum; ++i)
567e5c31af7Sopenharmony_ci	{
568e5c31af7Sopenharmony_ci		deUint32 layerFbo;
569e5c31af7Sopenharmony_ci
570e5c31af7Sopenharmony_ci		gl.genFramebuffers(1, &layerFbo);
571e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "genFramebuffers() call failed.");
572e5c31af7Sopenharmony_ci		gl.bindFramebuffer(GL_FRAMEBUFFER, layerFbo);
573e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer() call failed.");
574e5c31af7Sopenharmony_ci		gl.framebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texture, 0, i);
575e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTextureLayer() call failed.");
576e5c31af7Sopenharmony_ci
577e5c31af7Sopenharmony_ci		m_fbos.push_back(layerFbo);
578e5c31af7Sopenharmony_ci	}
579e5c31af7Sopenharmony_ci}
580e5c31af7Sopenharmony_ci
581e5c31af7Sopenharmony_civoid ShaderLayerFramebufferLayeredTestCase::deleteFBO()
582e5c31af7Sopenharmony_ci{
583e5c31af7Sopenharmony_ci	const Functions& gl = m_context.getRenderContext().getFunctions();
584e5c31af7Sopenharmony_ci
585e5c31af7Sopenharmony_ci	gl.deleteFramebuffers(1, &m_mainFbo);
586e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "DeleteFramebuffers");
587e5c31af7Sopenharmony_ci	for (int i = 0; i < m_layersNum; ++i)
588e5c31af7Sopenharmony_ci	{
589e5c31af7Sopenharmony_ci		gl.deleteFramebuffers(1, &(m_fbos[i]));
590e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "DeleteFramebuffers");
591e5c31af7Sopenharmony_ci	}
592e5c31af7Sopenharmony_ci	gl.deleteTextures(1, &m_texture);
593e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "DeleteTextures");
594e5c31af7Sopenharmony_ci}
595e5c31af7Sopenharmony_ci
596e5c31af7Sopenharmony_ci/** Constructor.
597e5c31af7Sopenharmony_ci*
598e5c31af7Sopenharmony_ci*  @param context Rendering context
599e5c31af7Sopenharmony_ci*/
600e5c31af7Sopenharmony_ciShaderLayerFramebufferNonLayeredTestCase::ShaderLayerFramebufferNonLayeredTestCase(deqp::Context& context)
601e5c31af7Sopenharmony_ci	: ShaderLayerFramebufferTestCaseBase(
602e5c31af7Sopenharmony_ci		  context, "ShaderLayerFramebufferNonLayeredTestCase",
603e5c31af7Sopenharmony_ci		  "Implements gl_Layer tests for non-layered framebuffer described in CTS_ARB_shader_viewport_layer_array",
604e5c31af7Sopenharmony_ci		  false)
605e5c31af7Sopenharmony_ci{
606e5c31af7Sopenharmony_ci}
607e5c31af7Sopenharmony_ci
608e5c31af7Sopenharmony_civoid ShaderLayerFramebufferNonLayeredTestCase::createFBO()
609e5c31af7Sopenharmony_ci{
610e5c31af7Sopenharmony_ci	const Functions& gl = m_context.getRenderContext().getFunctions();
611e5c31af7Sopenharmony_ci	deUint32		 tex;
612e5c31af7Sopenharmony_ci
613e5c31af7Sopenharmony_ci	gl.genTextures(1, &tex);
614e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
615e5c31af7Sopenharmony_ci
616e5c31af7Sopenharmony_ci	gl.bindTexture(GL_TEXTURE_2D, tex);
617e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture() call failed.");
618e5c31af7Sopenharmony_ci
619e5c31af7Sopenharmony_ci	gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_fboSize, m_fboSize, 0, GL_RGBA, GL_FLOAT, 0);
620e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "texImage2D() call failed.");
621e5c31af7Sopenharmony_ci
622e5c31af7Sopenharmony_ci	// create main FBO
623e5c31af7Sopenharmony_ci
624e5c31af7Sopenharmony_ci	gl.genFramebuffers(1, &m_mainFbo);
625e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "genFramebuffers() call failed.");
626e5c31af7Sopenharmony_ci	gl.bindFramebuffer(GL_FRAMEBUFFER, m_mainFbo);
627e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer() call failed.");
628e5c31af7Sopenharmony_ci	gl.framebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0);
629e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture() call failed.");
630e5c31af7Sopenharmony_ci
631e5c31af7Sopenharmony_ci	// main FBO is only layer
632e5c31af7Sopenharmony_ci
633e5c31af7Sopenharmony_ci	m_fbos.push_back(m_mainFbo);
634e5c31af7Sopenharmony_ci}
635e5c31af7Sopenharmony_ci
636e5c31af7Sopenharmony_civoid ShaderLayerFramebufferNonLayeredTestCase::deleteFBO()
637e5c31af7Sopenharmony_ci{
638e5c31af7Sopenharmony_ci	const Functions& gl = m_context.getRenderContext().getFunctions();
639e5c31af7Sopenharmony_ci
640e5c31af7Sopenharmony_ci	gl.deleteFramebuffers(1, &m_mainFbo);
641e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "DeleteFramebuffers");
642e5c31af7Sopenharmony_ci	gl.deleteTextures(1, &m_texture);
643e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "DeleteTextures");
644e5c31af7Sopenharmony_ci}
645e5c31af7Sopenharmony_ci
646e5c31af7Sopenharmony_ci/** Constructor.
647e5c31af7Sopenharmony_ci *
648e5c31af7Sopenharmony_ci *  @param context Rendering context.
649e5c31af7Sopenharmony_ci */
650e5c31af7Sopenharmony_ciShaderViewportLayerArray::ShaderViewportLayerArray(deqp::Context& context)
651e5c31af7Sopenharmony_ci	: TestCaseGroup(context, "shader_viewport_layer_array",
652e5c31af7Sopenharmony_ci					"Verify conformance of CTS_ARB_shader_viewport_layer_array implementation")
653e5c31af7Sopenharmony_ci{
654e5c31af7Sopenharmony_ci}
655e5c31af7Sopenharmony_ci
656e5c31af7Sopenharmony_ci/** Initializes the test group contents. */
657e5c31af7Sopenharmony_civoid ShaderViewportLayerArray::init()
658e5c31af7Sopenharmony_ci{
659e5c31af7Sopenharmony_ci	addChild(new ShaderViewportIndexTestCase(m_context));
660e5c31af7Sopenharmony_ci	addChild(new ShaderLayerFramebufferLayeredTestCase(m_context));
661e5c31af7Sopenharmony_ci	addChild(new ShaderLayerFramebufferNonLayeredTestCase(m_context));
662e5c31af7Sopenharmony_ci}
663e5c31af7Sopenharmony_ci} /* gl4cts namespace */
664