148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/*-------------------------------------------------------------------------
248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * OpenGL Conformance Test Suite
348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * -----------------------------
448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Copyright (c) 2014-2016 The Khronos Group Inc.
648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Licensed under the Apache License, Version 2.0 (the "License");
848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * you may not use this file except in compliance with the License.
948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * You may obtain a copy of the License at
1048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
1148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *      http://www.apache.org/licenses/LICENSE-2.0
1248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
1348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Unless required by applicable law or agreed to in writing, software
1448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * distributed under the License is distributed on an "AS IS" BASIS,
1548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * See the License for the specific language governing permissions and
1748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * limitations under the License.
1848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
1984322c9402f810da3cd80b52e9f9ef72150a9004Alexander Galazin */ /*!
2048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * \file
2148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * \brief
2284322c9402f810da3cd80b52e9f9ef72150a9004Alexander Galazin */ /*-------------------------------------------------------------------*/
2348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
2448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "esextcGeometryShaderLayeredFramebuffer.hpp"
2548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
2648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "gluContextInfo.hpp"
2748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "gluDefs.hpp"
2848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "glwEnums.hpp"
2948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "glwFunctions.hpp"
3048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "tcuTestLog.hpp"
3148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include <cstring>
3248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
3348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosnamespace glcts
3448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
3548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor
3648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
3748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context       Test context
3848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param name          Test case's name
3948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param description   Test case's desricption
4048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
4148087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosGeometryShaderLayeredFramebufferBlending::GeometryShaderLayeredFramebufferBlending(Context&				context,
4248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos																				   const ExtParameters& extParams,
4348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos																				   const char*			name,
4448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos																				   const char*			description)
4548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	: TestCaseBase(context, extParams, name, description)
4648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_fbo_id(0)
4748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_fs_id(0)
4848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_gs_id(0)
4948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_po_id(0)
5048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_read_fbo_id(0)
5148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_to_id(0)
5248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_vao_id(0)
5348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_vs_id(0)
5448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
5548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Left blank on purpose */
5648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
5748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
5848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Deinitializes GLES objects created during the test. */
5948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid GeometryShaderLayeredFramebufferBlending::deinit(void)
6048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
6148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
6348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Clean up */
6448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_fbo_id != 0)
6548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
6648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteFramebuffers(1, &m_fbo_id);
6748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
6848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
6948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_fs_id != 0)
7048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
7148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteShader(m_fs_id);
7248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
7348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
7448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_gs_id != 0)
7548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
7648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteShader(m_gs_id);
7748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
7848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
7948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_po_id != 0)
8048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
8148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteProgram(m_po_id);
8248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
8348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
8448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_read_fbo_id != 0)
8548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
8648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteFramebuffers(1, &m_read_fbo_id);
8748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
8848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
8948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_to_id != 0)
9048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
9148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteTextures(1, &m_to_id);
9248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
9348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
9448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_vao_id != 0)
9548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
9648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteVertexArrays(1, &m_vao_id);
9748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
9848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
9948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_vs_id != 0)
10048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
10148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteShader(m_vs_id);
10248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
10348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
10448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Release base class */
10548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	TestCaseBase::deinit();
10648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
10748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
10848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes the test.
10948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
11048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
11148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *  Note the function throws exception should an error occur!
11248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
11348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult GeometryShaderLayeredFramebufferBlending::iterate(void)
11448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
11548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/* Test-wide constants */
11648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#define N_TEXTURE_COMPONENTS (4)
11748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#define TEXTURE_DEPTH (4)
11848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#define TEXTURE_HEIGHT (4)
11948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#define TEXTURE_WIDTH (4)
12048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
12148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Fragment shader code */
12248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const char* fs_code = "${VERSION}\n"
12348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "\n"
12448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "precision highp float;\n"
12548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "\n"
12648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "out vec4 result;\n"
12748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "\n"
12848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "void main()\n"
12948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "{\n"
13048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "    result = vec4(0.2);\n"
13148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "}\n";
13248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
13348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Geometry shader code */
13448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const char* gs_code = "${VERSION}\n"
13548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "${GEOMETRY_SHADER_REQUIRE}\n"
13648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "\n"
13748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "layout(points)                          in;\n"
13848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "layout(triangle_strip, max_vertices=64) out;\n"
13948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "\n"
14048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "void main()\n"
14148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "{\n"
14248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "    for (int n = 0; n < 4; ++n)\n"
14348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "    {\n"
14448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        gl_Layer    = n;\n"
14548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        gl_Position = vec4(1, 1, 0, 1);\n"
14648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        EmitVertex();\n"
14748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "\n"
14848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        gl_Layer    = n;\n"
14948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        gl_Position = vec4(1, -1, 0, 1);\n"
15048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        EmitVertex();\n"
15148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "\n"
15248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        gl_Layer    = n;\n"
15348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        gl_Position = vec4(-1, 1, 0, 1);\n"
15448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        EmitVertex();\n"
15548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "\n"
15648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        gl_Layer    = n;\n"
15748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        gl_Position = vec4(-1, -1, 0, 1);\n"
15848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        EmitVertex();\n"
15948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "\n"
16048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        EndPrimitive();\n"
16148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "    }\n"
16248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "}\n";
16348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
16448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* General variables */
16548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const glw::Functions& gl		  = m_context.getRenderContext().getFunctions();
16648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned int		  n			  = 0;
16748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned int		  n_component = 0;
16848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned int		  n_layer	 = 0;
16948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned int		  n_slice	 = 0;
17048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned int		  x			  = 0;
17148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned int		  y			  = 0;
17248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
17348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned char buffer[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
17448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned char buffer_slice1[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
17548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned char buffer_slice2[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
17648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned char buffer_slice3[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
17748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned char buffer_slice4[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
17848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned char ref_buffer_slice1[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
17948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned char ref_buffer_slice2[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
18048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned char ref_buffer_slice3[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
18148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned char ref_buffer_slice4[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
18248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
18348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (!m_is_geometry_shader_extension_supported)
18448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
18548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
18648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
18748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
18848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set up shader objects */
18948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
19048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_gs_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
19148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
19248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
19348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not generate shader objects");
19448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
19548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set up program objects */
19648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_po_id = gl.createProgram();
19748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
19848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (!buildProgram(m_po_id, m_fs_id, 1 /* part */, &fs_code, m_gs_id, 1 /* part */, &gs_code, m_vs_id, 1 /* part */,
19948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					  &m_boilerplate_vs_code))
20048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
20148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		TCU_FAIL("Could not build program object");
20248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
20348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
20448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Prepare texture data we will use for each slice */
20548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (n = 0; n < TEXTURE_WIDTH * TEXTURE_HEIGHT; ++n)
20648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
20748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		unsigned char* slice_pixels_ptr[] = { buffer_slice1 + n * N_TEXTURE_COMPONENTS,
20848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos											  buffer_slice2 + n * N_TEXTURE_COMPONENTS,
20948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos											  buffer_slice3 + n * N_TEXTURE_COMPONENTS,
21048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos											  buffer_slice4 + n * N_TEXTURE_COMPONENTS };
21148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
21248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (n_slice = 0; n_slice < sizeof(slice_pixels_ptr) / sizeof(slice_pixels_ptr[0]); ++n_slice)
21348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
21448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			slice_pixels_ptr[n_slice][0] = 0;
21548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			slice_pixels_ptr[n_slice][1] = (unsigned char)(n_slice * 255 / 4);
21648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			slice_pixels_ptr[n_slice][2] = (unsigned char)(n_slice * 255 / 8);
21748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			slice_pixels_ptr[n_slice][3] = (unsigned char)(n_slice * 255 / 12);
21848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		} /* for (all slices) */
21948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}	 /* for (all pixels) */
22048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
22148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Calculate reference texture data we will later use when verifying the rendered data */
22248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (n = 0; n < TEXTURE_WIDTH * TEXTURE_HEIGHT; ++n)
22348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
22448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		unsigned char* ref_slice_pixels_ptr[] = { ref_buffer_slice1 + n * N_TEXTURE_COMPONENTS,
22548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos												  ref_buffer_slice2 + n * N_TEXTURE_COMPONENTS,
22648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos												  ref_buffer_slice3 + n * N_TEXTURE_COMPONENTS,
22748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos												  ref_buffer_slice4 + n * N_TEXTURE_COMPONENTS };
22848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
22948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		unsigned char* slice_pixels_ptr[] = { buffer_slice1 + n * N_TEXTURE_COMPONENTS,
23048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos											  buffer_slice2 + n * N_TEXTURE_COMPONENTS,
23148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos											  buffer_slice3 + n * N_TEXTURE_COMPONENTS,
23248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos											  buffer_slice4 + n * N_TEXTURE_COMPONENTS };
23348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
23448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (n_slice = 0; n_slice < sizeof(slice_pixels_ptr) / sizeof(slice_pixels_ptr[0]); ++n_slice)
23548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
23648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			unsigned char* ref_slice_ptr = ref_slice_pixels_ptr[n_slice];
23748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			unsigned char* slice_ptr	 = slice_pixels_ptr[n_slice];
23848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			float		   slice_rgba[]  = {
23948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				float(slice_ptr[0]) / 255.0f, /* convert to FP representation */
24048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				float(slice_ptr[1]) / 255.0f, /* convert to FP representation */
24148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				float(slice_ptr[2]) / 255.0f, /* convert to FP representation */
24248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				float(slice_ptr[3]) / 255.0f  /* convert to FP representation */
24348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			};
24448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
24548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			for (n_component = 0; n_component < N_TEXTURE_COMPONENTS; ++n_component)
24648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			{
24748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				float temp_component = slice_rgba[n_component] /* dst_color */ * slice_rgba[n_component] /* dst_color */
24848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos									   + 0.8f /* 1-src_color */ * 0.2f /* src_color */;
24948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
25048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				/* Clamp if necessary */
25148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				if (temp_component < 0)
25248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				{
25348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					temp_component = 0.0f;
25448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				}
25548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				else if (temp_component > 1)
25648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				{
25748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					temp_component = 1.0f;
25848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				}
25948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
26048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				/* Convert back to GL_RGBA8 */
26148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				ref_slice_ptr[n_component] = (unsigned char)(temp_component * 255.0f);
26248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			} /* for (all components) */
26348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}	 /* for (all slices) */
26448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}		  /* for (all pixels) */
26548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
26648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set up texture object used for the test */
26748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.genTextures(1, &m_to_id);
26848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindTexture(GL_TEXTURE_3D, m_to_id);
26948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.texStorage3D(GL_TEXTURE_3D, 1 /* levels */, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, TEXTURE_DEPTH);
27048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 0 /* zoffset */, TEXTURE_WIDTH,
27148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					 TEXTURE_HEIGHT, 1 /* depth */, GL_RGBA, GL_UNSIGNED_BYTE, buffer_slice1);
27248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 1 /* zoffset */, TEXTURE_WIDTH,
27348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					 TEXTURE_HEIGHT, 1 /* depth */, GL_RGBA, GL_UNSIGNED_BYTE, buffer_slice2);
27448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 2 /* zoffset */, TEXTURE_WIDTH,
27548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					 TEXTURE_HEIGHT, 1 /* depth */, GL_RGBA, GL_UNSIGNED_BYTE, buffer_slice3);
27648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 3 /* zoffset */, TEXTURE_WIDTH,
27748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					 TEXTURE_HEIGHT, 1 /* depth */, GL_RGBA, GL_UNSIGNED_BYTE, buffer_slice4);
27848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
27948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up texture object");
28048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
28148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set up framebuffer object used for the test */
28248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.genFramebuffers(1, &m_fbo_id);
28348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo_id);
28448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
28548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_to_id, 0 /* level */);
28648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
28748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up draw framebuffer");
28848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
28948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Generate and bind a vertex array object */
29048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.genVertexArrays(1, &m_vao_id);
29148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindVertexArray(m_vao_id);
29248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
29348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up vertex array object");
29448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
29548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set up blending */
29648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.blendFunc(GL_ONE_MINUS_SRC_COLOR, GL_DST_COLOR);
29748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.enable(GL_BLEND);
29848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
29948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Render */
30048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.useProgram(m_po_id);
30148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.viewport(0 /* x */, 0 /* y */, TEXTURE_WIDTH, TEXTURE_HEIGHT);
30248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
30348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
30448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
30548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "Draw call failed");
30648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
30748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Verify rendered data in the layers */
30848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.genFramebuffers(1, &m_read_fbo_id);
30948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_read_fbo_id);
31048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
31148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (n_layer = 0; n_layer < TEXTURE_DEPTH; ++n_layer)
31248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
31348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		bool has_layer_failed = false;
31448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
31548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const unsigned char* ref_buffer =
31648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			(n_layer == 0) ?
31748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				ref_buffer_slice1 :
31848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				(n_layer == 1) ? ref_buffer_slice2 : (n_layer == 2) ? ref_buffer_slice3 : ref_buffer_slice4;
31948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
32048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.framebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_to_id, 0 /* level */, n_layer);
32148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.readPixels(0 /* x */, 0 /* y */, TEXTURE_WIDTH, TEXTURE_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
32248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
32348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not read back pixel data!");
32448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
32548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (y = 0; y < TEXTURE_HEIGHT; ++y)
32648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
32748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			const unsigned int   pixel_size = N_TEXTURE_COMPONENTS;
32848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			const unsigned char* ref_row	= ref_buffer + y * pixel_size;
32948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			const unsigned char* row		= buffer + y * pixel_size;
33048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
33148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			for (x = 0; x < TEXTURE_WIDTH; ++x)
33248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			{
33348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#define EPSILON (1)
33448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
33548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				const unsigned char* data	 = row + x * pixel_size;
33648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				const unsigned char* ref_data = ref_row + x * pixel_size;
33748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
33848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				if (de::abs((int)data[0] - (int)ref_data[0]) > EPSILON ||
33948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					de::abs((int)data[1] - (int)ref_data[1]) > EPSILON ||
34048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					de::abs((int)data[2] - (int)ref_data[2]) > EPSILON ||
34148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					de::abs((int)data[3] - (int)ref_data[3]) > EPSILON)
34248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				{
34348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					m_testCtx.getLog() << tcu::TestLog::Message << "(layer=" << n_layer << " x=" << x << " y=" << y
34448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos									   << ") "
34548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos									   << "Reference value is different than the rendered data (epsilon > " << EPSILON
34648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos									   << "): "
34748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos									   << "(" << (unsigned int)ref_data[0] << ", " << (unsigned int)ref_data[1] << ", "
34848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos									   << (unsigned int)ref_data[2] << ", " << (unsigned int)ref_data[3] << ") vs "
34948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos									   << "(" << (unsigned int)data[0] << ", " << (unsigned int)data[1] << ", "
35048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos									   << (unsigned int)data[2] << ", " << (unsigned int)data[3] << ")."
35148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos									   << tcu::TestLog::EndMessage;
35248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
35348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					has_layer_failed = true;
35448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				} /* if (regions are different) */
35548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
35648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#undef EPSILON
35748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			} /* for (all pixels in a row) */
35848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}	 /* for (all rows) */
35948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
36048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		if (has_layer_failed)
36148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
36248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			TCU_FAIL("Pixel data comparison failed");
36348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
36448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	} /* for (all layers) */
36548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
36648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Done */
36748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
36848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	return STOP;
36948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
37048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#undef N_TEXTURE_COMPONENTS
37148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#undef TEXTURE_DEPTH
37248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#undef TEXTURE_HEIGHT
37348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#undef TEXTURE_WIDTH
37448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
37548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
37648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor
37748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
37848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context       Test context
37948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param name          Test case's name
38048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param description   Test case's description
38148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
38248087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosGeometryShaderLayeredFramebufferClear::GeometryShaderLayeredFramebufferClear(Context&			  context,
38348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos																			 const ExtParameters& extParams,
38448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos																			 const char* name, const char* description)
38548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	: TestCaseBase(context, extParams, name, description)
38648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_fbo_char_id(0)
38748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_fbo_int_id(0)
38848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_fbo_uint_id(0)
38948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_read_fbo_id(0)
39048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_to_rgba32i_id(0)
39148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_to_rgba32ui_id(0)
39248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_to_rgba8_id(0)
39348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
39448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Left blank on purpose */
39548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
39648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
39748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes the test.
39848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
39948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
40048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *  Note the function throws exception should an error occur!
40148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
40248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult GeometryShaderLayeredFramebufferClear::iterate(void)
40348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
40448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
40548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
40648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/* Test-wide definitions */
40748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#define N_TEXTURE_COMPONENTS (4)
40848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#define TEXTURE_DEPTH (4)
40948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#define TEXTURE_HEIGHT (4)
41048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#define TEXTURE_WIDTH (4)
41148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
41248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Type definitions */
41348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	typedef enum {
41448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Always first */
41548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		CLEAR_FIRST = 0,
41648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
41748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* glClear() */
41848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		CLEAR_PLAIN = CLEAR_FIRST,
41948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* glClearBufferfv() */
42048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		CLEAR_BUFFERFV,
42148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* glClearBufferiv() */
42248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		CLEAR_BUFFERIV,
42348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* glClearBufferuiv() */
42448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		CLEAR_BUFFERUIV,
42548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
42648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Always last */
42748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		CLEAR_COUNT
42848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	} _clear_type;
42948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
43048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* General variables */
43148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const glw::GLenum fbo_draw_buffer = GL_COLOR_ATTACHMENT0;
43248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
43348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	int n		= 0;
43448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	int n_layer = 0;
43548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	int x		= 0;
43648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	int y		= 0;
43748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
43848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned char buffer_char[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
43948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	int			  buffer_int[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
44048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned int  buffer_uint[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
44148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned char slice_1_data_char[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
44248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	int			  slice_1_data_int[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
44348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned int  slice_1_data_uint[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
44448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned char slice_2_data_char[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
44548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	int			  slice_2_data_int[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
44648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned int  slice_2_data_uint[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
44748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned char slice_3_data_char[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
44848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	int			  slice_3_data_int[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
44948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned int  slice_3_data_uint[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
45048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned char slice_4_data_char[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
45148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	int			  slice_4_data_int[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
45248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned int  slice_4_data_uint[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
45348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
45448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Only carry on if geometry shaders are supported */
45548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (!m_is_geometry_shader_extension_supported)
45648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
45748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
45848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
45948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
46048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set up slice data */
46148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	memset(slice_1_data_char, 0, sizeof(slice_1_data_char));
46248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	memset(slice_1_data_int, 0, sizeof(slice_1_data_int));
46348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	memset(slice_1_data_uint, 0, sizeof(slice_1_data_uint));
46448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	memset(slice_2_data_char, 0, sizeof(slice_2_data_char));
46548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	memset(slice_2_data_int, 0, sizeof(slice_2_data_int));
46648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	memset(slice_2_data_uint, 0, sizeof(slice_2_data_uint));
46748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	memset(slice_3_data_char, 0, sizeof(slice_3_data_char));
46848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	memset(slice_3_data_int, 0, sizeof(slice_3_data_int));
46948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	memset(slice_3_data_uint, 0, sizeof(slice_3_data_uint));
47048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	memset(slice_4_data_char, 0, sizeof(slice_4_data_char));
47148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	memset(slice_4_data_int, 0, sizeof(slice_4_data_int));
47248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	memset(slice_4_data_uint, 0, sizeof(slice_4_data_uint));
47348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
47448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (n = 0; n < 4 /* width */ * 4 /* height */; ++n)
47548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
47648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		slice_1_data_char[4 * n + 0] = 255;
47748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		slice_1_data_int[4 * n + 0]  = 255;
47848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		slice_1_data_uint[4 * n + 0] = 255;
47948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
48048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		slice_2_data_char[4 * n + 1] = 255;
48148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		slice_2_data_int[4 * n + 1]  = 255;
48248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		slice_2_data_uint[4 * n + 1] = 255;
48348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
48448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		slice_3_data_char[4 * n + 2] = 255;
48548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		slice_3_data_int[4 * n + 2]  = 255;
48648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		slice_3_data_uint[4 * n + 2] = 255;
48748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
48848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		slice_4_data_char[4 * n + 0] = 255;
48948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		slice_4_data_char[4 * n + 1] = 255;
49048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		slice_4_data_int[4 * n + 0]  = 255;
49148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		slice_4_data_int[4 * n + 1]  = 255;
49248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		slice_4_data_uint[4 * n + 0] = 255;
49348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		slice_4_data_uint[4 * n + 1] = 255;
49448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	} /* for (all pixels) */
49548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
49648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set up texture objects */
49748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.genTextures(1, &m_to_rgba8_id);
49848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.genTextures(1, &m_to_rgba32i_id);
49948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.genTextures(1, &m_to_rgba32ui_id);
50048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
50148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (n = 0; n < 3 /* textures */; ++n)
50248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
50348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		void* to_data_1 =
50448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			(n == 0) ? (void*)slice_1_data_char : (n == 1) ? (void*)slice_1_data_int : (void*)slice_1_data_uint;
50548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
50648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		void* to_data_2 =
50748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			(n == 0) ? (void*)slice_2_data_char : (n == 1) ? (void*)slice_2_data_int : (void*)slice_2_data_uint;
50848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
50948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		void* to_data_3 =
51048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			(n == 0) ? (void*)slice_3_data_char : (n == 1) ? (void*)slice_3_data_int : (void*)slice_3_data_uint;
51148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
51248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		void* to_data_4 =
51348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			(n == 0) ? (void*)slice_4_data_char : (n == 1) ? (void*)slice_4_data_int : (void*)slice_4_data_uint;
51448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
51548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		glw::GLenum to_format = (n == 0) ? GL_RGBA : (n == 1) ? GL_RGBA_INTEGER : GL_RGBA_INTEGER;
51648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
51748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		glw::GLenum to_internalformat = (n == 0) ? GL_RGBA8 : (n == 1) ? GL_RGBA32I : GL_RGBA32UI;
51848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
51948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		glw::GLuint to_id = (n == 0) ? m_to_rgba8_id : (n == 1) ? m_to_rgba32i_id : m_to_rgba32ui_id;
52048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
52148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		glw::GLenum to_type = (n == 0) ? GL_UNSIGNED_BYTE : (n == 1) ? GL_INT : GL_UNSIGNED_INT;
52248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
52348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindTexture(GL_TEXTURE_3D, to_id);
52448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
52548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texStorage3D(GL_TEXTURE_3D, 1 /* levels */, to_internalformat, TEXTURE_WIDTH, TEXTURE_HEIGHT, TEXTURE_DEPTH);
52648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
52748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 0 /* zoffset */, TEXTURE_WIDTH,
52848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						 TEXTURE_HEIGHT, 1 /* depth */, to_format, to_type, to_data_1);
52948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 1 /* zoffset */, TEXTURE_WIDTH,
53048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						 TEXTURE_HEIGHT, 1 /* depth */, to_format, to_type, to_data_2);
53148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 2 /* zoffset */, TEXTURE_WIDTH,
53248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						 TEXTURE_HEIGHT, 1 /* depth */, to_format, to_type, to_data_3);
53348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 3 /* zoffset */, TEXTURE_WIDTH,
53448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						 TEXTURE_HEIGHT, 1 /* depth */, to_format, to_type, to_data_4);
53548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
53648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
53748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
53848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
53948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
54048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not initialize texture object");
54148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	} /* for (all texture objects) */
54248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
54348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set up framebuffer object */
54448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.genFramebuffers(1, &m_fbo_char_id);
54548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.genFramebuffers(1, &m_fbo_int_id);
54648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.genFramebuffers(1, &m_fbo_uint_id);
54748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.genFramebuffers(1, &m_read_fbo_id);
54848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
54948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (n = 0; n < 3 /* framebuffers */; ++n)
55048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
55148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		glw::GLuint fbo_id = (n == 0) ? m_fbo_char_id : (n == 1) ? m_fbo_int_id : m_fbo_uint_id;
55248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
55348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		glw::GLuint to_id = (n == 0) ? m_to_rgba8_id : (n == 1) ? m_to_rgba32i_id : m_to_rgba32ui_id;
55448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
55548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_id);
55648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.drawBuffers(1, &fbo_draw_buffer);
55748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, to_id, 0 /* level */);
55848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
55948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not initialize framebuffer object");
56048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	} /* for (all framebuffers) */
56148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
56248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Try reading from the layered framebuffer. */
56348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_char_id);
56448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.readPixels(0 /* x */, 0 /* y */, TEXTURE_WIDTH, TEXTURE_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, buffer_char);
56548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
56648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Is the returned data an exact copy of what we've uploaded for layer zero? */
56748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (memcmp(buffer_char, slice_1_data_char, sizeof(slice_1_data_char)) != 0)
56848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
56948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		TCU_FAIL("Retrieved data is different from data uploaded for layer 0 of a layered framebuffer.");
57048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
57148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
57248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Iterate through all clear calls supported */
57348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
57448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (int current_test = static_cast<int>(CLEAR_FIRST); current_test < static_cast<int>(CLEAR_COUNT); current_test++)
57548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
57648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		void*				buffer				= NULL;
57748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const unsigned char clear_color_byte[]  = { 64, 128, 255, 32 };
57848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const float			clear_color_float[] = { 0.25f, 0.5f, 1.0f, 32.0f / 255.0f };
57948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const int			clear_color_int[]   = { 64, 128, 255, 32 };
58048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		glw::GLuint			fbo_id				= 0;
58148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		int					pixel_size			= 0;
58248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		void*				slice_1_data		= NULL;
58348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		void*				slice_2_data		= NULL;
58448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		void*				slice_3_data		= NULL;
58548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		void*				slice_4_data		= NULL;
58648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		glw::GLenum			to_format			= GL_NONE;
58748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		glw::GLuint			to_id				= 0;
58848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		glw::GLenum			to_type				= GL_NONE;
58948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
59048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		switch (static_cast<_clear_type>(current_test))
59148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
59248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		case CLEAR_BUFFERFV:
59348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		case CLEAR_PLAIN:
59448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
59548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			buffer		 = buffer_char;
59648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			fbo_id		 = m_fbo_char_id;
59748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			pixel_size   = N_TEXTURE_COMPONENTS;
59848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			slice_1_data = slice_1_data_char;
59948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			slice_2_data = slice_2_data_char;
60048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			slice_3_data = slice_3_data_char;
60148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			slice_4_data = slice_4_data_char;
60248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			to_format	= GL_RGBA;
60348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			to_id		 = m_to_rgba8_id;
60448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			to_type		 = GL_UNSIGNED_BYTE;
60548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
60648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			break;
60748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
60848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
60948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		case CLEAR_BUFFERIV:
61048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
61148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			buffer		 = (void*)buffer_int;
61248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			fbo_id		 = m_fbo_int_id;
61348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			pixel_size   = N_TEXTURE_COMPONENTS * sizeof(int);
61448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			slice_1_data = slice_1_data_int;
61548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			slice_2_data = slice_2_data_int;
61648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			slice_3_data = slice_3_data_int;
61748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			slice_4_data = slice_4_data_int;
61848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			to_format	= GL_RGBA_INTEGER;
61948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			to_id		 = m_to_rgba32i_id;
62048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			to_type		 = GL_INT;
62148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
62248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			break;
62348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
62448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
62548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		case CLEAR_BUFFERUIV:
62648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
62748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			buffer		 = (void*)buffer_uint;
62848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			fbo_id		 = m_fbo_uint_id;
62948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			pixel_size   = N_TEXTURE_COMPONENTS * sizeof(unsigned int);
63048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			slice_1_data = slice_1_data_uint;
63148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			slice_2_data = slice_2_data_uint;
63248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			slice_3_data = slice_3_data_uint;
63348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			slice_4_data = slice_4_data_uint;
63448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			to_format	= GL_RGBA_INTEGER;
63548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			to_id		 = m_to_rgba32ui_id;
63648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			to_type		 = GL_UNSIGNED_INT;
63748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
63848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			break;
63948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
64048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
64148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		default:
64248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
64348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			/* This location should never be reached */
64448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			TCU_FAIL("Execution flow failure");
64548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
64648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		} /* switch (current_test)*/
64748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
64848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Restore layer data just in case */
64948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindTexture(GL_TEXTURE_3D, to_id);
65048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 0 /* zoffset */, TEXTURE_WIDTH,
65148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						 TEXTURE_HEIGHT, 1 /* depth */, to_format, to_type, slice_1_data);
65248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 1 /* zoffset */, TEXTURE_WIDTH,
65348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						 TEXTURE_HEIGHT, 1 /* depth */, to_format, to_type, slice_2_data);
65448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 2 /* zoffset */, TEXTURE_WIDTH,
65548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						 TEXTURE_HEIGHT, 1 /* depth */, to_format, to_type, slice_3_data);
65648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 3 /* zoffset */, TEXTURE_WIDTH,
65748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						 TEXTURE_HEIGHT, 1 /* depth */, to_format, to_type, slice_4_data);
65848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
65948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage3D() call failed.");
66048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
66148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Issue requested clear call */
66248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindFramebuffer(GL_FRAMEBUFFER, fbo_id);
66348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
66448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		switch (current_test)
66548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
66648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		case CLEAR_PLAIN:
66748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
66848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			gl.clearColor(clear_color_float[0], clear_color_float[1], clear_color_float[2], clear_color_float[3]);
66948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			gl.clear(GL_COLOR_BUFFER_BIT);
67048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
67148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			break;
67248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
67348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
67448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		case CLEAR_BUFFERIV:
67548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
67648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			gl.clearBufferiv(GL_COLOR, 0 /* draw buffer index */, clear_color_int);
67748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
67848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			break;
67948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
68048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
68148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		case CLEAR_BUFFERUIV:
68248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
68348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			gl.clearBufferuiv(GL_COLOR, 0 /* draw buffer index */, (const glw::GLuint*)clear_color_int);
68448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
68548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			break;
68648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
68748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
68848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		case CLEAR_BUFFERFV:
68948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
69048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			gl.clearBufferfv(GL_COLOR, 0 /* draw buffer index */, clear_color_float);
69148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
69248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			break;
69348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
69448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
69548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		default:
69648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
69748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			/* This location should never be reached */
69848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			TCU_FAIL("Execution flow failure");
69948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
70048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		} /* switch (current_test) */
70148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
70248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Make sure no error was generated */
70348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "Clear call failed.");
70448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
70548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_read_fbo_id);
70648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create read framebuffer object!");
70748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
70848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Check the layer data after a clear call */
70948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (n_layer = 0; n_layer < TEXTURE_DEPTH; ++n_layer)
71048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
71148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			gl.framebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, to_id, 0 /* level */, n_layer);
71248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			gl.readPixels(0 /* x */, 0 /* y */, TEXTURE_WIDTH, TEXTURE_HEIGHT, to_format, to_type, buffer);
71348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
71448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed.");
71548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
71648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			/* If we requested an integer clear, the pixels we obtained should be reset to specific values.
71748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			 * If we asked for a FP-based clear, consider an epsilon. */
71848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			for (y = 0; y < TEXTURE_HEIGHT; ++y)
71948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			{
72048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				const int	  row_size = TEXTURE_WIDTH * pixel_size;
72148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				unsigned char* row		= (unsigned char*)buffer + y * row_size;
72248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
72348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				for (x = 0; x < TEXTURE_WIDTH; ++x)
72448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				{
72548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					if (current_test == CLEAR_BUFFERIV || current_test == CLEAR_BUFFERUIV)
72648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					{
72748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						unsigned int* pixel = (unsigned int*)(row + x * pixel_size);
72848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
72948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						if (memcmp(pixel, clear_color_int, sizeof(clear_color_int)) != 0)
73048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						{
73148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							/* Test fails at this point */
73248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							m_testCtx.getLog()
73348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos								<< tcu::TestLog::Message << "(x=" << x << " y=" << y << ") Reference pixel ["
73448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos								<< clear_color_byte[0] << ", " << clear_color_byte[1] << ", " << clear_color_byte[2]
73548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos								<< ", " << clear_color_byte[3] << "] is different from the one retrieved ["
73648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos								<< (int)pixel[0] << ", " << (int)pixel[1] << ", " << (int)pixel[2] << ", "
73748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos								<< (int)pixel[3] << "]" << tcu::TestLog::EndMessage;
73848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
73948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							TCU_FAIL("Data comparison failure");
74048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						} /* if (memcmp(pixel, clear_color_byte, sizeof(clear_color_byte) ) != 0) */
74148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					}	 /* if (current_test == CLEAR_BUFFERIV || current_test == CLEAR_BUFFERUIV) */
74248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					else
74348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					{
74448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#define EPSILON (1)
74548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
74648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						unsigned char* pixel = (unsigned char*)(row + x * pixel_size);
74748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
74848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						if (de::abs((int)pixel[0] - clear_color_int[0]) > EPSILON ||
74948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							de::abs((int)pixel[1] - clear_color_int[1]) > EPSILON ||
75048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							de::abs((int)pixel[2] - clear_color_int[2]) > EPSILON ||
75148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							de::abs((int)pixel[3] - clear_color_int[3]) > EPSILON)
75248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						{
75348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							/* Test fails at this point */
75448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							m_testCtx.getLog()
75548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos								<< tcu::TestLog::Message << "(x=" << x << " y=" << y << ") Reference pixel ["
75648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos								<< clear_color_byte[0] << ", " << clear_color_byte[1] << ", " << clear_color_byte[2]
75748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos								<< ", " << clear_color_byte[3] << "] is different from the one retrieved ["
75848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos								<< (int)pixel[0] << ", " << (int)pixel[1] << ", " << (int)pixel[2] << ", "
75948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos								<< (int)pixel[3] << "]" << tcu::TestLog::EndMessage;
76048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
76148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							TCU_FAIL("Data comparison failure");
76248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						} /* if (pixel component has exceeded an allowed epsilon) */
76348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
76448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#undef EPSILON
76548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					}
76648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				} /* for (all pixels) */
76748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			}	 /* for (all rows) */
76848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}		  /* for (all layers) */
76948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}			  /* for (all clear call types) */
77048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
77148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Done */
77248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
77348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	return STOP;
77448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
77548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#undef TEXTURE_DEPTH
77648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#undef TEXTURE_HEIGHT
77748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#undef TEXTURE_WIDTH
77848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
77948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
78048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Deinitializes GLES objects created during the test. */
78148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid GeometryShaderLayeredFramebufferClear::deinit(void)
78248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
78348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
78448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
78548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_fbo_char_id != 0)
78648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
78748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteFramebuffers(1, &m_fbo_char_id);
78848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
78948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
79048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_fbo_int_id != 0)
79148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
79248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteFramebuffers(1, &m_fbo_int_id);
79348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
79448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
79548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_fbo_uint_id != 0)
79648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
79748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteFramebuffers(1, &m_fbo_uint_id);
79848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
79948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
80048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_to_rgba32i_id != 0)
80148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
80248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteTextures(1, &m_to_rgba32i_id);
80348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
80448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
80548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_to_rgba32ui_id != 0)
80648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
80748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteTextures(1, &m_to_rgba32ui_id);
80848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
80948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
81048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_to_rgba8_id != 0)
81148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
81248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteTextures(1, &m_to_rgba8_id);
81348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
81448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
81548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_read_fbo_id != 0)
81648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
81748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteFramebuffers(1, &m_read_fbo_id);
81848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
81948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
82048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Release base class */
82148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	TestCaseBase::deinit();
82248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
82348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
82448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor
82548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
82648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context       Test context
82748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param name          Test case's name
82848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param description   Test case's desricption
82948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
83048087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosGeometryShaderLayeredFramebufferDepth::GeometryShaderLayeredFramebufferDepth(Context&			  context,
83148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos																			 const ExtParameters& extParams,
83248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos																			 const char* name, const char* description)
83348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	: TestCaseBase(context, extParams, name, description)
83448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_fbo_id(0)
83548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_fs_id(0)
83648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_gs_id(0)
83748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_po_id(0)
83848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_read_fbo_id(0)
83948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_to_a_id(0)
84048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_to_b_id(0)
84148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_vao_id(0)
84248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_vs_id(0)
84348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
84448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Left blank on purpose */
84548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
84648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
84748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Deinitializes GLES objects created during the test. */
84848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid GeometryShaderLayeredFramebufferDepth::deinit(void)
84948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
85048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
85148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
85248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Clean up */
85348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_fbo_id != 0)
85448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
85548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteFramebuffers(1, &m_fbo_id);
85648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
85748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
85848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_fs_id != 0)
85948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
86048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteShader(m_fs_id);
86148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
86248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
86348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_gs_id != 0)
86448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
86548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteShader(m_gs_id);
86648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
86748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
86848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_po_id != 0)
86948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
87048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteProgram(m_po_id);
87148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
87248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
87348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_read_fbo_id != 0)
87448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
87548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteFramebuffers(1, &m_read_fbo_id);
87648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
87748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
87848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_to_a_id != 0)
87948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
88048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteTextures(1, &m_to_a_id);
88148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
88248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
88348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_to_b_id != 0)
88448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
88548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteTextures(1, &m_to_b_id);
88648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
88748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
88848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_vao_id != 0)
88948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
89048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteVertexArrays(1, &m_vao_id);
89148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
89248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
89348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_vs_id != 0)
89448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
89548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteShader(m_vs_id);
89648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
89748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
89848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Release base class */
89948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	TestCaseBase::deinit();
90048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
90148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
90248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes the test.
90348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
90448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
90548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *  Note the function throws exception should an error occur!
90648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
90748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult GeometryShaderLayeredFramebufferDepth::iterate(void)
90848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
90948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* General variables */
91048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
91148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned int		  n  = 0;
91248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned int		  x  = 0;
91348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned int		  y  = 0;
91448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
91548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/* Test-wide definitions */
91648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#define N_TEXTURE_COMPONENTS (4)
91748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#define TEXTURE_DEPTH (4)
91848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#define TEXTURE_HEIGHT (4)
91948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#define TEXTURE_WIDTH (4)
92048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
92148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Fragment shader code */
92248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const char* fs_code = "${VERSION}\n"
92348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "\n"
92448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "precision highp float;\n"
92548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "\n"
92648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "out vec4 result;\n"
92748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "\n"
92848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "void main()\n"
92948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "{\n"
93048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "    result = vec4(1.0);\n"
93148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "}\n";
93248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
93348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const char* gs_code = "${VERSION}\n"
93448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "${GEOMETRY_SHADER_REQUIRE}\n"
93548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "\n"
93648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "layout(points)                          in;\n"
93748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "layout(triangle_strip, max_vertices=64) out;\n"
93848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "\n"
93948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "void main()\n"
94048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "{\n"
94148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "    for (int n = 0; n < 4; ++n)\n"
94248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "    {\n"
94348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        float depth = -1.0 + float(n) * 0.5;\n"
94448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "\n"
94548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        gl_Layer    = n;\n"
94648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        gl_Position = vec4(1, 1, depth, 1);\n"
94748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        EmitVertex();\n"
94848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "\n"
94948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        gl_Layer    = n;\n"
95048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        gl_Position = vec4(1, -1, depth, 1);\n"
95148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        EmitVertex();\n"
95248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "\n"
95348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        gl_Layer    = n;\n"
95448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        gl_Position = vec4(-1, 1, depth, 1);\n"
95548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        EmitVertex();\n"
95648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "\n"
95748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        gl_Layer    = n;\n"
95848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        gl_Position = vec4(-1, -1, depth, 1);\n"
95948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        EmitVertex();\n"
96048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "\n"
96148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        EndPrimitive();\n"
96248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "    }\n"
96348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "}\n";
96448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
96548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* This test should only run if EXT_geometry_shader is supported */
96648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (!m_is_geometry_shader_extension_supported)
96748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
96848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
96948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
97048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
97148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set up texture objects we will be using for the test */
97248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.genTextures(1, &m_to_a_id);
97348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.genTextures(1, &m_to_b_id);
97448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
97548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_to_a_id);
97648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1 /* levels */, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, TEXTURE_DEPTH);
97748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_to_b_id);
97848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1 /* levels */, GL_DEPTH_COMPONENT32F, TEXTURE_WIDTH, TEXTURE_HEIGHT,
97948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					TEXTURE_DEPTH);
98048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
98148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not initialize texture objects");
98248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
98348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set up framebuffer object we will use for the test */
98448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.genFramebuffers(1, &m_fbo_id);
98548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.genFramebuffers(1, &m_read_fbo_id);
98648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
98748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo_id);
98848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
98948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_to_a_id, 0 /* level */);
99048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, m_to_b_id, 0 /* level */);
99148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
99248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not initialize framebuffer object");
99348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
99448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
99548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
99648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		m_testCtx.getLog() << tcu::TestLog::Message
99748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						   << "Draw framebuffer is incomplete: " << gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER)
99848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						   << tcu::TestLog::EndMessage;
99948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
100048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		TCU_FAIL("Draw framebuffer is incomplete.");
100148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
100248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
100348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set up shader objects */
100448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
100548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_gs_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
100648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
100748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
100848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not initialize shader objects");
100948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
101048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set up program object */
101148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_po_id = gl.createProgram();
101248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
101348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (!buildProgram(m_po_id, m_fs_id, 1 /* part */, &fs_code, m_gs_id, 1 /* part */, &gs_code, m_vs_id, 1 /* part */,
101448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					  &m_boilerplate_vs_code))
101548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
101648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		TCU_FAIL("Could not build program object");
101748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
101848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
101948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set up vertex array object */
102048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.genVertexArrays(1, &m_vao_id);
102148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindVertexArray(m_vao_id);
102248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
102348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not bind vertex array object");
102448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
102548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Clear the depth attachment before we continue */
102648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.clearColor(0.0f /* red */, 0.0f /* green */, 0.0f /* blue */, 0.0f /* alpha */);
102748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.clearDepthf(0.5f);
102848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
102948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
103048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "Depth buffer clear operation failed");
103148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
103248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Render */
103348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.useProgram(m_po_id);
103448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.viewport(0 /* x */, 0 /* y */, TEXTURE_WIDTH, TEXTURE_HEIGHT);
103548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
103648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.enable(GL_DEPTH_TEST);
103748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
103848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
103948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "Rendering failed");
104048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
104148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Verify the output */
104248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_read_fbo_id);
104348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
104448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (n = 0; n < TEXTURE_DEPTH; ++n)
104548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
104648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		unsigned char buffer[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
104748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		unsigned char ref_color[4];
104848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
104948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Determine reference color */
105048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		if (n < 2)
105148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
105248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			memset(ref_color, 0xFF, sizeof(ref_color));
105348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
105448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		else
105548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
105648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			memset(ref_color, 0, sizeof(ref_color));
105748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
105848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
105948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Read the rendered layer data */
106048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.framebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_to_a_id, 0 /* level */, n);
106148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.readPixels(0 /* x */, 0 /* y */, TEXTURE_WIDTH, TEXTURE_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
106248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
106348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed");
106448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
106548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Compare all pixels against the reference value */
106648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (y = 0; y < TEXTURE_HEIGHT; ++y)
106748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
106848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			const unsigned int   pixel_size = N_TEXTURE_COMPONENTS;
106948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			const unsigned int   row_width  = TEXTURE_WIDTH * pixel_size;
107048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			const unsigned char* row_data   = buffer + y * row_width;
107148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
107248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			for (x = 0; x < TEXTURE_WIDTH; ++x)
107348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			{
107448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				const unsigned char* result = row_data + x * pixel_size;
107548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
107648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				if (memcmp(result, ref_color, sizeof(ref_color)) != 0)
107748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				{
107848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					m_testCtx.getLog() << tcu::TestLog::Message << "(x=" << x << " y=" << y << ") "
107948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos									   << "Reference value is different than the rendered data: "
108048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos									   << "(" << (unsigned int)ref_color[0] << ", " << (unsigned int)ref_color[1]
108148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos									   << ", " << (unsigned int)ref_color[2] << ", " << (unsigned int)ref_color[3]
108248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos									   << ") vs "
108348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos									   << "(" << (unsigned int)result[0] << ", " << (unsigned int)result[1] << ", "
108448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos									   << (unsigned int)result[2] << ", " << (unsigned int)result[3] << ")."
108548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos									   << tcu::TestLog::EndMessage;
108648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
108748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					TCU_FAIL("Rendered data mismatch");
108848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				} /* if (memcmp(row_data + x * pixel_size, ref_color, sizeof(ref_color) ) != 0)*/
108948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			}	 /* for (all pixels in a row) */
109048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}		  /* for (all rows) */
109148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}			  /* for (all layers) */
109248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
109348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Done */
109448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
109548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	return STOP;
109648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
109748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#undef N_TEXTURE_COMPONENTS
109848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#undef TEXTURE_DEPTH
109948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#undef TEXTURE_HEIGHT
110048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#undef TEXTURE_WIDTH
110148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
110248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
110348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor
110448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
110548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context       Test context
110648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param name          Test case's name
110748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param description   Test case's desricption
110848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
110948087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosGeometryShaderLayeredFramebufferStencil::GeometryShaderLayeredFramebufferStencil(Context&			  context,
111048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos																				 const ExtParameters& extParams,
111148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos																				 const char*		  name,
111248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos																				 const char*		  description)
111348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	: TestCaseBase(context, extParams, name, description)
111448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_fbo_id(0)
111548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_fs_id(0)
111648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_gs_id(0)
111748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_po_id(0)
111848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_to_a_id(0)
111948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_to_b_id(0)
112048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_vao_id(0)
112148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_vs_id(0)
112248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
112348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Left blank on purpose */
112448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
112548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
112648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Deinitializes GLES objects created during the test. */
112748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid GeometryShaderLayeredFramebufferStencil::deinit(void)
112848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
112948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
113048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
113148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Clean up */
113248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_fbo_id != 0)
113348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
113448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteFramebuffers(1, &m_fbo_id);
113548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
113648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
113748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_fs_id != 0)
113848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
113948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteShader(m_fs_id);
114048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
114148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
114248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_gs_id != 0)
114348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
114448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteShader(m_gs_id);
114548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
114648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
114748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_po_id != 0)
114848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
114948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteProgram(m_po_id);
115048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
115148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
115248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_to_a_id != 0)
115348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
115448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteTextures(1, &m_to_a_id);
115548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
115648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
115748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_to_b_id != 0)
115848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
115948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteTextures(1, &m_to_b_id);
116048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
116148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
116248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_vao_id != 0)
116348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
116448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteVertexArrays(1, &m_vao_id);
116548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
116648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
116748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_vs_id != 0)
116848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
116948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteShader(m_vs_id);
117048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
117148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
117248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Release base class */
117348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	TestCaseBase::deinit();
117448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
117548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
117648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes the test.
117748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
117848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
117948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *  Note the function throws exception should an error occur!
118048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
118148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult GeometryShaderLayeredFramebufferStencil::iterate(void)
118248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
118348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
118448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
118548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/* Test-wide definitions */
118648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#define N_TEXTURE_COMPONENTS (4)
118748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#define TEXTURE_DEPTH (4)
118848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#define TEXTURE_HEIGHT (4)
118948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#define TEXTURE_WIDTH (8)
119048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
119148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Fragment shader code */
119248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const char* fs_code = "${VERSION}\n"
119348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "\n"
119448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "precision highp float;\n"
119548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "\n"
119648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "out vec4 result;\n"
119748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "\n"
119848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "void main()\n"
119948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "{\n"
120048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "    result = vec4(1, 1, 1, 1);\n"
120148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "}\n";
120248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
120348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Geometry shader code */
120448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const char* gs_code = "${VERSION}\n"
120548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "${GEOMETRY_SHADER_REQUIRE}\n"
120648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "\n"
120748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "precision highp float;\n"
120848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "\n"
120948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "layout (points)                            in;\n"
121048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "layout (triangle_strip, max_vertices = 16) out;\n"
121148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "\n"
121248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "void main()\n"
121348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "{\n"
121448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "    for (int n = 0; n < 4; ++n)\n"
121548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "    {\n"
121648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        gl_Position = vec4(1, -1, 0, 1);\n"
121748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        gl_Layer    = n;\n"
121848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        EmitVertex();\n"
121948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "\n"
122048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        gl_Position = vec4(1,  1, 0, 1);\n"
122148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        gl_Layer    = n;\n"
122248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        EmitVertex();\n"
122348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "\n"
122448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        gl_Position = vec4(-1, -1, 0, 1);\n"
122548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        gl_Layer    = n;\n"
122648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        EmitVertex();\n"
122748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "\n"
122848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        gl_Position = vec4(-1,  1, 0, 1);\n"
122948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        gl_Layer    = n;\n"
123048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        EmitVertex();\n"
123148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "\n"
123248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "        EndPrimitive();\n"
123348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "    }\n"
123448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "\n"
123548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  "}\n";
123648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
123748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* General variables */
123848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	int n = 0;
123948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
124048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned char slice_null_data[TEXTURE_DEPTH * TEXTURE_WIDTH * TEXTURE_HEIGHT * 1 /* byte  per texel */] = { 0 };
124148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned char slice_1_data[TEXTURE_DEPTH * TEXTURE_WIDTH * TEXTURE_HEIGHT * 8 /* bytes per texel */]	= { 0 };
124248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned char slice_2_data[TEXTURE_DEPTH * TEXTURE_WIDTH * TEXTURE_HEIGHT * 8 /* bytes per texel */]	= { 0 };
124348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned char slice_3_data[TEXTURE_DEPTH * TEXTURE_WIDTH * TEXTURE_HEIGHT * 8 /* bytes per texel */]	= { 0 };
124448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	unsigned char slice_4_data[TEXTURE_DEPTH * TEXTURE_WIDTH * TEXTURE_HEIGHT * 8 /* bytes per texel */]	= { 0 };
124548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
124648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* This test should only run if EXT_geometry_shader is supported */
124748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (!m_is_geometry_shader_extension_supported)
124848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
124948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
125048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
125148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
125248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Create shader & program objects */
125348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
125448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_gs_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
125548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_po_id = gl.createProgram();
125648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
125748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
125848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader or program objects");
125948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
126048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Build test program object */
126148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (!buildProgram(m_po_id, m_fs_id, 1 /* parts */, &fs_code, m_gs_id, 1 /* parts */, &gs_code, m_vs_id,
126248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					  1 /* parts */, &m_boilerplate_vs_code))
126348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
126448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		TCU_FAIL("Could not build test program object");
126548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
126648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
126748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Generate and bind a vertex array object */
126848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.genVertexArrays(1, &m_vao_id);
126948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindVertexArray(m_vao_id);
127048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
127148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create & bind a vertex array object.");
127248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
127348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Configure slice data */
127448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (n = 0; n < TEXTURE_DEPTH * TEXTURE_WIDTH * TEXTURE_HEIGHT * 8 /* bytes per texel */; ++n)
127548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
127648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* We are okay with depth data being filled with glitch, but need the stencil data to be
127748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * as per test spec. To keep code simple, we do not differentiate between floating-point and
127848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * stencil part.
127948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 */
128048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		slice_1_data[n] = 2;
128148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		slice_2_data[n] = 1;
128248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
128348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Slices 3 and 4 should be filled with 0s */
128448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		slice_3_data[n] = 0;
128548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		slice_4_data[n] = 0;
128648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	} /* for (all pixels making up slices) */
128748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
128848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set up texture objects */
128948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.genTextures(1, &m_to_a_id);
129048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.genTextures(1, &m_to_b_id);
129148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
129248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_to_a_id);
129348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.texImage3D(GL_TEXTURE_2D_ARRAY, 0 /* level */, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, TEXTURE_DEPTH,
129448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				  0 /* border */, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
129548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
129648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 0 /* zoffset */,
129748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					 TEXTURE_WIDTH, TEXTURE_HEIGHT, 1 /* depth */, GL_RGBA, GL_UNSIGNED_BYTE, slice_null_data);
129848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 1 /* zoffset */,
129948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					 TEXTURE_WIDTH, TEXTURE_HEIGHT, 1 /* depth */, GL_RGBA, GL_UNSIGNED_BYTE, slice_null_data);
130048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 2 /* zoffset */,
130148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					 TEXTURE_WIDTH, TEXTURE_HEIGHT, 1 /* depth */, GL_RGBA, GL_UNSIGNED_BYTE, slice_null_data);
130248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 3 /* zoffset */,
130348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					 TEXTURE_WIDTH, TEXTURE_HEIGHT, 1 /* depth */, GL_RGBA, GL_UNSIGNED_BYTE, slice_null_data);
130448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
130548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up texture object A.");
130648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
130748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_to_b_id);
130848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.texImage3D(GL_TEXTURE_2D_ARRAY, 0 /* level */, GL_DEPTH32F_STENCIL8, TEXTURE_WIDTH, TEXTURE_HEIGHT,
130948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				  TEXTURE_DEPTH, 0 /* border */, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, NULL);
131048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
131148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 0 /* zoffset */,
131248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					 TEXTURE_WIDTH, TEXTURE_HEIGHT, 1 /* depth */, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
131348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					 slice_1_data);
131448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 1 /* zoffset */,
131548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					 TEXTURE_WIDTH, TEXTURE_HEIGHT, 1 /* depth */, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
131648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					 slice_2_data);
131748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 2 /* zoffset */,
131848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					 TEXTURE_WIDTH, TEXTURE_HEIGHT, 1 /* depth */, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
131948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					 slice_3_data);
132048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 3 /* zoffset */,
132148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					 TEXTURE_WIDTH, TEXTURE_HEIGHT, 1 /* depth */, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
132248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					 slice_4_data);
132348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
132448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up texture object B.");
132548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
132648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set up depth tests */
132748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.disable(GL_DEPTH_TEST);
132848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
132948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set up stencil tests */
133048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.enable(GL_STENCIL_TEST);
133148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.stencilFunc(GL_LESS, 0, /* reference value */ 0xFFFFFFFF /* mask */);
133248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
133348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set up framebuffer objects */
133448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.genFramebuffers(1, &m_fbo_id);
133548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo_id);
133648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
133748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_to_a_id, 0 /* level */);
133848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, m_to_b_id, 0 /* level */);
133948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
134048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up draw framebuffer.");
134148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
134248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Issue the draw call. */
134348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.useProgram(m_po_id);
134448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
134548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
134648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "Draw call failed.");
134748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
134848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Check the results */
134948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (n = 0; n < 4 /* layers */; ++n)
135048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
135148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		glw::GLenum   fbo_completeness													 = GL_NONE;
135248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		int			  m																	 = 0;
135348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		unsigned char ref_data[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS]	= { 0 };
135448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		unsigned char result_data[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS] = { 0 };
135548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		int			  x																	 = 0;
135648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		int			  y																	 = 0;
135748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
135848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Configure the read framebuffer */
135948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_id);
136048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
136148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.framebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_to_a_id, 0 /* level */, n);
136248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.framebufferTexture(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, 0 /* texture */, 0 /* level */);
136348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
136448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up read framebuffer.");
136548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
136648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Verify read framebuffer is considered complete */
136748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		fbo_completeness = gl.checkFramebufferStatus(GL_READ_FRAMEBUFFER);
136848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
136948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		if (fbo_completeness != GL_FRAMEBUFFER_COMPLETE)
137048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
137148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			m_testCtx.getLog() << tcu::TestLog::Message << "Read FBO is incomplete: "
137248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							   << "[" << fbo_completeness << "]" << tcu::TestLog::EndMessage;
137348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
137448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			TCU_FAIL("Read FBO is incomplete.");
137548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
137648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
137748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Build reference data */
137848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (m = 0; m < TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS; ++m)
137948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
138048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			if (n < 2)
138148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			{
138248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				ref_data[m] = 255;
138348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			}
138448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			else
138548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			{
138648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				ref_data[m] = 0;
138748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			}
138848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		} /* for (all reference pixels) */
138948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
139048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Read the rendered data */
139148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.readPixels(0 /* x */, 0 /* y */, TEXTURE_WIDTH, TEXTURE_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, result_data);
139248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
139348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() failed");
139448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
139548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (y = 0; y < TEXTURE_HEIGHT; ++y)
139648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
139748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			int			   pixel_size = N_TEXTURE_COMPONENTS;
139848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			int			   row_size   = pixel_size * TEXTURE_WIDTH;
139948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			unsigned char* ref_row	= ref_data + y * row_size;
140048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			unsigned char* result_row = result_data + y * row_size;
140148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
140248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			for (x = 0; x < TEXTURE_WIDTH; ++x)
140348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			{
140448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				if (memcmp(ref_row, result_row, pixel_size) != 0)
140548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				{
140648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					m_testCtx.getLog() << tcu::TestLog::Message << "(x=" << x << " y=" << y << "): Rendered data "
140748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos									   << "(" << result_row[0] << ", " << result_row[1] << ", " << result_row[2] << ", "
140848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos									   << result_row[3] << ")"
140948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos									   << " is different from reference data "
141048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos									   << "(" << ref_row[0] << ", " << ref_row[1] << ", " << ref_row[2] << ", "
141148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos									   << ref_row[3] << ")" << tcu::TestLog::EndMessage;
141248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
141348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					TCU_FAIL("Data comparison failed");
141448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				} /* if (memcmp(ref_row, result_row, pixel_size) != 0) */
141548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
141648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				ref_row += pixel_size;
141748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				result_row += pixel_size;
141848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			} /* for (all pixels in a row) */
141948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}	 /* for (all pixels) */
142048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}		  /* for (all layers) */
142148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
142248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Done */
142348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
142448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	return STOP;
142548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
142648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#undef N_TEXTURE_COMPONENTS
142748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#undef TEXTURE_DEPTH
142848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#undef TEXTURE_HEIGHT
142948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#undef TEXTURE_WIDTH
143048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
143148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
143248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} // namespace glcts
1433