1e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * OpenGL Conformance Test Suite
3e5c31af7Sopenharmony_ci * -----------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright (c) 2015-2016 The Khronos Group Inc.
6e5c31af7Sopenharmony_ci *
7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
10e5c31af7Sopenharmony_ci *
11e5c31af7Sopenharmony_ci *      http://www.apache.org/licenses/LICENSE-2.0
12e5c31af7Sopenharmony_ci *
13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
17e5c31af7Sopenharmony_ci * limitations under the License.
18e5c31af7Sopenharmony_ci *
19e5c31af7Sopenharmony_ci */ /*!
20e5c31af7Sopenharmony_ci * \file
21e5c31af7Sopenharmony_ci * \brief
22e5c31af7Sopenharmony_ci */ /*-------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci/**
25e5c31af7Sopenharmony_ci * \file  gl4cSyncTests.cpp
26e5c31af7Sopenharmony_ci * \brief Declares test classes for synchronization functionality.
27e5c31af7Sopenharmony_ci */ /*-------------------------------------------------------------------*/
28e5c31af7Sopenharmony_ci
29e5c31af7Sopenharmony_ci#include "gl4cIncompleteTextureAccessTests.hpp"
30e5c31af7Sopenharmony_ci
31e5c31af7Sopenharmony_ci#include "deSharedPtr.hpp"
32e5c31af7Sopenharmony_ci
33e5c31af7Sopenharmony_ci#include "gluContextInfo.hpp"
34e5c31af7Sopenharmony_ci#include "gluDefs.hpp"
35e5c31af7Sopenharmony_ci#include "gluPixelTransfer.hpp"
36e5c31af7Sopenharmony_ci#include "gluStrUtil.hpp"
37e5c31af7Sopenharmony_ci
38e5c31af7Sopenharmony_ci#include "tcuFuzzyImageCompare.hpp"
39e5c31af7Sopenharmony_ci#include "tcuImageCompare.hpp"
40e5c31af7Sopenharmony_ci#include "tcuRenderTarget.hpp"
41e5c31af7Sopenharmony_ci#include "tcuSurface.hpp"
42e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp"
43e5c31af7Sopenharmony_ci
44e5c31af7Sopenharmony_ci#include "glw.h"
45e5c31af7Sopenharmony_ci#include "glwFunctions.hpp"
46e5c31af7Sopenharmony_ci
47e5c31af7Sopenharmony_cinamespace gl4cts
48e5c31af7Sopenharmony_ci{
49e5c31af7Sopenharmony_cinamespace IncompleteTextureAccess
50e5c31af7Sopenharmony_ci{
51e5c31af7Sopenharmony_ci/****************************************** Incomplete Texture Access Tests Group ***********************************************/
52e5c31af7Sopenharmony_ci
53e5c31af7Sopenharmony_ci/** @brief Incomplete Texture Access Tests Group constructor.
54e5c31af7Sopenharmony_ci *
55e5c31af7Sopenharmony_ci *  @param [in] context     OpenGL context.
56e5c31af7Sopenharmony_ci */
57e5c31af7Sopenharmony_ciTests::Tests(deqp::Context& context)
58e5c31af7Sopenharmony_ci	: TestCaseGroup(context, "incomplete_texture_access", "Incomplete Texture Access Tests Suite")
59e5c31af7Sopenharmony_ci{
60e5c31af7Sopenharmony_ci}
61e5c31af7Sopenharmony_ci
62e5c31af7Sopenharmony_ci/** @brief Incomplete Texture Access Tests initializer. */
63e5c31af7Sopenharmony_civoid Tests::init()
64e5c31af7Sopenharmony_ci{
65e5c31af7Sopenharmony_ci	addChild(new IncompleteTextureAccess::SamplerTest(m_context));
66e5c31af7Sopenharmony_ci}
67e5c31af7Sopenharmony_ci
68e5c31af7Sopenharmony_ci/*************************************** Sampler Incomplete Texture Access Test Test *******************************************/
69e5c31af7Sopenharmony_ci
70e5c31af7Sopenharmony_ci/** @brief Sampler Incomplete Texture Access Test constructor.
71e5c31af7Sopenharmony_ci *
72e5c31af7Sopenharmony_ci *  @param [in] context     OpenGL context.
73e5c31af7Sopenharmony_ci */
74e5c31af7Sopenharmony_ciSamplerTest::SamplerTest(deqp::Context& context)
75e5c31af7Sopenharmony_ci	: deqp::TestCase(context, "sampler", "Fetch using sampler test"), m_po(0), m_to(0), m_fbo(0), m_rbo(0), m_vao(0)
76e5c31af7Sopenharmony_ci{
77e5c31af7Sopenharmony_ci	/* Intentionally left blank. */
78e5c31af7Sopenharmony_ci}
79e5c31af7Sopenharmony_ci
80e5c31af7Sopenharmony_ci/** @brief Iterate Incomplete Texture Access Test cases.
81e5c31af7Sopenharmony_ci *
82e5c31af7Sopenharmony_ci *  @return Iteration result.
83e5c31af7Sopenharmony_ci */
84e5c31af7Sopenharmony_citcu::TestNode::IterateResult SamplerTest::iterate()
85e5c31af7Sopenharmony_ci{
86e5c31af7Sopenharmony_ci	/* Get context setup. */
87e5c31af7Sopenharmony_ci	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
88e5c31af7Sopenharmony_ci
89e5c31af7Sopenharmony_ci	if (!is_at_least_gl_45)
90e5c31af7Sopenharmony_ci	{
91e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
92e5c31af7Sopenharmony_ci
93e5c31af7Sopenharmony_ci		return STOP;
94e5c31af7Sopenharmony_ci	}
95e5c31af7Sopenharmony_ci
96e5c31af7Sopenharmony_ci	/* Running tests. */
97e5c31af7Sopenharmony_ci	bool is_ok	= true;
98e5c31af7Sopenharmony_ci	bool is_error = false;
99e5c31af7Sopenharmony_ci
100e5c31af7Sopenharmony_ci	try
101e5c31af7Sopenharmony_ci	{
102e5c31af7Sopenharmony_ci		PrepareFramebuffer();
103e5c31af7Sopenharmony_ci		PrepareVertexArrays();
104e5c31af7Sopenharmony_ci
105e5c31af7Sopenharmony_ci		for (glw::GLuint i = 0; i < s_configurations_count; ++i)
106e5c31af7Sopenharmony_ci		{
107e5c31af7Sopenharmony_ci			PrepareProgram(s_configurations[i]);
108e5c31af7Sopenharmony_ci			PrepareTexture(s_configurations[i]);
109e5c31af7Sopenharmony_ci
110e5c31af7Sopenharmony_ci			Draw();
111e5c31af7Sopenharmony_ci
112e5c31af7Sopenharmony_ci			if (!Check(s_configurations[i]))
113e5c31af7Sopenharmony_ci			{
114e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog()
115e5c31af7Sopenharmony_ci					<< tcu::TestLog::Message << "Incomplete texture sampler access test failed with sampler "
116e5c31af7Sopenharmony_ci					<< s_configurations[i].sampler_template << "." << tcu::TestLog::EndMessage;
117e5c31af7Sopenharmony_ci
118e5c31af7Sopenharmony_ci				is_ok = false;
119e5c31af7Sopenharmony_ci			}
120e5c31af7Sopenharmony_ci
121e5c31af7Sopenharmony_ci			CleanCase();
122e5c31af7Sopenharmony_ci		}
123e5c31af7Sopenharmony_ci	}
124e5c31af7Sopenharmony_ci	catch (...)
125e5c31af7Sopenharmony_ci	{
126e5c31af7Sopenharmony_ci		is_ok	= false;
127e5c31af7Sopenharmony_ci		is_error = true;
128e5c31af7Sopenharmony_ci	}
129e5c31af7Sopenharmony_ci
130e5c31af7Sopenharmony_ci	/* Cleanup. */
131e5c31af7Sopenharmony_ci	CleanCase();
132e5c31af7Sopenharmony_ci	CleanTest();
133e5c31af7Sopenharmony_ci
134e5c31af7Sopenharmony_ci	/* Result's setup. */
135e5c31af7Sopenharmony_ci	if (is_ok)
136e5c31af7Sopenharmony_ci	{
137e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
138e5c31af7Sopenharmony_ci	}
139e5c31af7Sopenharmony_ci	else
140e5c31af7Sopenharmony_ci	{
141e5c31af7Sopenharmony_ci		if (is_error)
142e5c31af7Sopenharmony_ci		{
143e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
144e5c31af7Sopenharmony_ci		}
145e5c31af7Sopenharmony_ci		else
146e5c31af7Sopenharmony_ci		{
147e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
148e5c31af7Sopenharmony_ci		}
149e5c31af7Sopenharmony_ci	}
150e5c31af7Sopenharmony_ci
151e5c31af7Sopenharmony_ci	return STOP;
152e5c31af7Sopenharmony_ci}
153e5c31af7Sopenharmony_ci
154e5c31af7Sopenharmony_civoid SamplerTest::PrepareProgram(Configuration configuration)
155e5c31af7Sopenharmony_ci{
156e5c31af7Sopenharmony_ci	/* Shortcut for GL functionality */
157e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
158e5c31af7Sopenharmony_ci
159e5c31af7Sopenharmony_ci	struct Shader
160e5c31af7Sopenharmony_ci	{
161e5c31af7Sopenharmony_ci		glw::GLchar const* source[5];
162e5c31af7Sopenharmony_ci		glw::GLsizei const count;
163e5c31af7Sopenharmony_ci		glw::GLenum const  type;
164e5c31af7Sopenharmony_ci		glw::GLuint		   id;
165e5c31af7Sopenharmony_ci	} shader[] = { { { s_vertex_shader, NULL, NULL, NULL, NULL }, 1, GL_VERTEX_SHADER, 0 },
166e5c31af7Sopenharmony_ci				   { { s_fragment_shader_head, configuration.sampler_template, s_fragment_shader_body,
167e5c31af7Sopenharmony_ci					   configuration.fetch_template, s_fragment_shader_tail },
168e5c31af7Sopenharmony_ci					 5,
169e5c31af7Sopenharmony_ci					 GL_FRAGMENT_SHADER,
170e5c31af7Sopenharmony_ci					 0 } };
171e5c31af7Sopenharmony_ci
172e5c31af7Sopenharmony_ci	glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);
173e5c31af7Sopenharmony_ci
174e5c31af7Sopenharmony_ci	try
175e5c31af7Sopenharmony_ci	{
176e5c31af7Sopenharmony_ci		/* Create program. */
177e5c31af7Sopenharmony_ci		m_po = gl.createProgram();
178e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
179e5c31af7Sopenharmony_ci
180e5c31af7Sopenharmony_ci		/* Shader compilation. */
181e5c31af7Sopenharmony_ci
182e5c31af7Sopenharmony_ci		for (glw::GLuint i = 0; i < shader_count; ++i)
183e5c31af7Sopenharmony_ci		{
184e5c31af7Sopenharmony_ci			{
185e5c31af7Sopenharmony_ci				shader[i].id = gl.createShader(shader[i].type);
186e5c31af7Sopenharmony_ci
187e5c31af7Sopenharmony_ci				GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
188e5c31af7Sopenharmony_ci
189e5c31af7Sopenharmony_ci				gl.attachShader(m_po, shader[i].id);
190e5c31af7Sopenharmony_ci
191e5c31af7Sopenharmony_ci				GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
192e5c31af7Sopenharmony_ci
193e5c31af7Sopenharmony_ci				gl.shaderSource(shader[i].id, shader[i].count, shader[i].source, NULL);
194e5c31af7Sopenharmony_ci
195e5c31af7Sopenharmony_ci				GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
196e5c31af7Sopenharmony_ci
197e5c31af7Sopenharmony_ci				gl.compileShader(shader[i].id);
198e5c31af7Sopenharmony_ci
199e5c31af7Sopenharmony_ci				GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
200e5c31af7Sopenharmony_ci
201e5c31af7Sopenharmony_ci				glw::GLint status = GL_FALSE;
202e5c31af7Sopenharmony_ci
203e5c31af7Sopenharmony_ci				gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
204e5c31af7Sopenharmony_ci				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
205e5c31af7Sopenharmony_ci
206e5c31af7Sopenharmony_ci				if (GL_FALSE == status)
207e5c31af7Sopenharmony_ci				{
208e5c31af7Sopenharmony_ci					glw::GLint log_size = 0;
209e5c31af7Sopenharmony_ci					gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
210e5c31af7Sopenharmony_ci					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
211e5c31af7Sopenharmony_ci
212e5c31af7Sopenharmony_ci					glw::GLchar* log_text = new glw::GLchar[log_size];
213e5c31af7Sopenharmony_ci
214e5c31af7Sopenharmony_ci					gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);
215e5c31af7Sopenharmony_ci
216e5c31af7Sopenharmony_ci					m_context.getTestContext().getLog()
217e5c31af7Sopenharmony_ci						<< tcu::TestLog::Message << "Shader compilation has failed.\n"
218e5c31af7Sopenharmony_ci						<< "Shader type: " << glu::getShaderTypeStr(shader[i].type) << "\n"
219e5c31af7Sopenharmony_ci						<< "Shader compilation error log:\n"
220e5c31af7Sopenharmony_ci						<< log_text << "\n"
221e5c31af7Sopenharmony_ci						<< "Shader source code:\n"
222e5c31af7Sopenharmony_ci						<< shader[i].source[0] << (shader[i].source[1] ? shader[i].source[1] : "")
223e5c31af7Sopenharmony_ci						<< (shader[i].source[2] ? shader[i].source[2] : "")
224e5c31af7Sopenharmony_ci						<< (shader[i].source[3] ? shader[i].source[3] : "")
225e5c31af7Sopenharmony_ci						<< (shader[i].source[4] ? shader[i].source[4] : "") << "\n"
226e5c31af7Sopenharmony_ci						<< tcu::TestLog::EndMessage;
227e5c31af7Sopenharmony_ci
228e5c31af7Sopenharmony_ci					delete[] log_text;
229e5c31af7Sopenharmony_ci
230e5c31af7Sopenharmony_ci					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");
231e5c31af7Sopenharmony_ci
232e5c31af7Sopenharmony_ci					throw 0;
233e5c31af7Sopenharmony_ci				}
234e5c31af7Sopenharmony_ci			}
235e5c31af7Sopenharmony_ci		}
236e5c31af7Sopenharmony_ci
237e5c31af7Sopenharmony_ci		/* Link. */
238e5c31af7Sopenharmony_ci		gl.linkProgram(m_po);
239e5c31af7Sopenharmony_ci
240e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
241e5c31af7Sopenharmony_ci
242e5c31af7Sopenharmony_ci		glw::GLint status = GL_FALSE;
243e5c31af7Sopenharmony_ci
244e5c31af7Sopenharmony_ci		gl.getProgramiv(m_po, GL_LINK_STATUS, &status);
245e5c31af7Sopenharmony_ci
246e5c31af7Sopenharmony_ci		if (GL_TRUE == status)
247e5c31af7Sopenharmony_ci		{
248e5c31af7Sopenharmony_ci			for (glw::GLuint i = 0; i < shader_count; ++i)
249e5c31af7Sopenharmony_ci			{
250e5c31af7Sopenharmony_ci				if (shader[i].id)
251e5c31af7Sopenharmony_ci				{
252e5c31af7Sopenharmony_ci					gl.detachShader(m_po, shader[i].id);
253e5c31af7Sopenharmony_ci
254e5c31af7Sopenharmony_ci					GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
255e5c31af7Sopenharmony_ci				}
256e5c31af7Sopenharmony_ci			}
257e5c31af7Sopenharmony_ci		}
258e5c31af7Sopenharmony_ci		else
259e5c31af7Sopenharmony_ci		{
260e5c31af7Sopenharmony_ci			glw::GLint log_size = 0;
261e5c31af7Sopenharmony_ci
262e5c31af7Sopenharmony_ci			gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);
263e5c31af7Sopenharmony_ci
264e5c31af7Sopenharmony_ci			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
265e5c31af7Sopenharmony_ci
266e5c31af7Sopenharmony_ci			glw::GLchar* log_text = new glw::GLchar[log_size];
267e5c31af7Sopenharmony_ci
268e5c31af7Sopenharmony_ci			gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);
269e5c31af7Sopenharmony_ci
270e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
271e5c31af7Sopenharmony_ci												<< log_text << "\n"
272e5c31af7Sopenharmony_ci												<< tcu::TestLog::EndMessage;
273e5c31af7Sopenharmony_ci
274e5c31af7Sopenharmony_ci			delete[] log_text;
275e5c31af7Sopenharmony_ci
276e5c31af7Sopenharmony_ci			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");
277e5c31af7Sopenharmony_ci
278e5c31af7Sopenharmony_ci			throw 0;
279e5c31af7Sopenharmony_ci		}
280e5c31af7Sopenharmony_ci	}
281e5c31af7Sopenharmony_ci	catch (...)
282e5c31af7Sopenharmony_ci	{
283e5c31af7Sopenharmony_ci		if (m_po)
284e5c31af7Sopenharmony_ci		{
285e5c31af7Sopenharmony_ci			gl.deleteProgram(m_po);
286e5c31af7Sopenharmony_ci
287e5c31af7Sopenharmony_ci			m_po = 0;
288e5c31af7Sopenharmony_ci		}
289e5c31af7Sopenharmony_ci	}
290e5c31af7Sopenharmony_ci
291e5c31af7Sopenharmony_ci	for (glw::GLuint i = 0; i < shader_count; ++i)
292e5c31af7Sopenharmony_ci	{
293e5c31af7Sopenharmony_ci		if (0 != shader[i].id)
294e5c31af7Sopenharmony_ci		{
295e5c31af7Sopenharmony_ci			gl.deleteShader(shader[i].id);
296e5c31af7Sopenharmony_ci
297e5c31af7Sopenharmony_ci			shader[i].id = 0;
298e5c31af7Sopenharmony_ci		}
299e5c31af7Sopenharmony_ci	}
300e5c31af7Sopenharmony_ci
301e5c31af7Sopenharmony_ci	if (0 == m_po)
302e5c31af7Sopenharmony_ci	{
303e5c31af7Sopenharmony_ci		throw 0;
304e5c31af7Sopenharmony_ci	}
305e5c31af7Sopenharmony_ci	else
306e5c31af7Sopenharmony_ci	{
307e5c31af7Sopenharmony_ci		gl.useProgram(m_po);
308e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "glUsePrograms has failed");
309e5c31af7Sopenharmony_ci	}
310e5c31af7Sopenharmony_ci}
311e5c31af7Sopenharmony_ci
312e5c31af7Sopenharmony_civoid SamplerTest::PrepareTexture(Configuration configuration)
313e5c31af7Sopenharmony_ci{
314e5c31af7Sopenharmony_ci	/* Shortcut for GL functionality. */
315e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
316e5c31af7Sopenharmony_ci
317e5c31af7Sopenharmony_ci	if (m_to)
318e5c31af7Sopenharmony_ci	{
319e5c31af7Sopenharmony_ci		throw 0;
320e5c31af7Sopenharmony_ci	}
321e5c31af7Sopenharmony_ci
322e5c31af7Sopenharmony_ci	gl.genTextures(1, &m_to);
323e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
324e5c31af7Sopenharmony_ci
325e5c31af7Sopenharmony_ci	gl.bindTexture(configuration.texture_target, m_to);
326e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
327e5c31af7Sopenharmony_ci
328e5c31af7Sopenharmony_ci	if (configuration.is_shadow)
329e5c31af7Sopenharmony_ci	{
330e5c31af7Sopenharmony_ci		gl.texParameteri(configuration.texture_target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
331e5c31af7Sopenharmony_ci		gl.texParameteri(configuration.texture_target, GL_TEXTURE_COMPARE_FUNC, GL_NEVER);
332e5c31af7Sopenharmony_ci	}
333e5c31af7Sopenharmony_ci	else
334e5c31af7Sopenharmony_ci	{
335e5c31af7Sopenharmony_ci		gl.texParameteri(configuration.texture_target, GL_TEXTURE_COMPARE_MODE, GL_NONE);
336e5c31af7Sopenharmony_ci	}
337e5c31af7Sopenharmony_ci}
338e5c31af7Sopenharmony_ci
339e5c31af7Sopenharmony_civoid SamplerTest::PrepareFramebuffer()
340e5c31af7Sopenharmony_ci{
341e5c31af7Sopenharmony_ci	/* Shortcut for GL functionality. */
342e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
343e5c31af7Sopenharmony_ci
344e5c31af7Sopenharmony_ci	/* Quick checks. */
345e5c31af7Sopenharmony_ci	if (m_fbo || m_rbo)
346e5c31af7Sopenharmony_ci	{
347e5c31af7Sopenharmony_ci		throw 0;
348e5c31af7Sopenharmony_ci	}
349e5c31af7Sopenharmony_ci
350e5c31af7Sopenharmony_ci	/* Framebuffer creation. */
351e5c31af7Sopenharmony_ci	gl.genFramebuffers(1, &m_fbo);
352e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
353e5c31af7Sopenharmony_ci
354e5c31af7Sopenharmony_ci	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
355e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
356e5c31af7Sopenharmony_ci
357e5c31af7Sopenharmony_ci	gl.genRenderbuffers(1, &m_rbo);
358e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");
359e5c31af7Sopenharmony_ci
360e5c31af7Sopenharmony_ci	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo);
361e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer has failed");
362e5c31af7Sopenharmony_ci
363e5c31af7Sopenharmony_ci	gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F, 1 /* x size */, 1 /* y size */);
364e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
365e5c31af7Sopenharmony_ci
366e5c31af7Sopenharmony_ci	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo);
367e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
368e5c31af7Sopenharmony_ci
369e5c31af7Sopenharmony_ci	/* Quick checks. */
370e5c31af7Sopenharmony_ci	if (GL_FRAMEBUFFER_COMPLETE != gl.checkFramebufferStatus(GL_FRAMEBUFFER))
371e5c31af7Sopenharmony_ci	{
372e5c31af7Sopenharmony_ci		throw 0;
373e5c31af7Sopenharmony_ci	}
374e5c31af7Sopenharmony_ci}
375e5c31af7Sopenharmony_ci
376e5c31af7Sopenharmony_civoid SamplerTest::PrepareVertexArrays()
377e5c31af7Sopenharmony_ci{
378e5c31af7Sopenharmony_ci	/* Shortcut for GL functionality. */
379e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
380e5c31af7Sopenharmony_ci
381e5c31af7Sopenharmony_ci	/* Quick checks.*/
382e5c31af7Sopenharmony_ci	if (m_vao)
383e5c31af7Sopenharmony_ci	{
384e5c31af7Sopenharmony_ci		throw 0;
385e5c31af7Sopenharmony_ci	}
386e5c31af7Sopenharmony_ci
387e5c31af7Sopenharmony_ci	/* Empty vao creation. */
388e5c31af7Sopenharmony_ci	gl.genVertexArrays(1, &m_vao);
389e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "gGenVertexArrays has failed");
390e5c31af7Sopenharmony_ci
391e5c31af7Sopenharmony_ci	gl.bindVertexArray(m_vao);
392e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "gBindVertexArrays has failed");
393e5c31af7Sopenharmony_ci}
394e5c31af7Sopenharmony_ci
395e5c31af7Sopenharmony_civoid SamplerTest::Draw()
396e5c31af7Sopenharmony_ci{
397e5c31af7Sopenharmony_ci	/* Shortcut for GL functionality. */
398e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
399e5c31af7Sopenharmony_ci
400e5c31af7Sopenharmony_ci	/* Draw setup. */
401e5c31af7Sopenharmony_ci	gl.activeTexture(GL_TEXTURE0);
402e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture has failed");
403e5c31af7Sopenharmony_ci
404e5c31af7Sopenharmony_ci	gl.uniform1i(gl.getUniformLocation(m_po, "texture_input"), 0);
405e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i has failed");
406e5c31af7Sopenharmony_ci
407e5c31af7Sopenharmony_ci	/* Draw. */
408e5c31af7Sopenharmony_ci	gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
409e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays has failed");
410e5c31af7Sopenharmony_ci}
411e5c31af7Sopenharmony_ci
412e5c31af7Sopenharmony_cibool SamplerTest::Check(Configuration configuration)
413e5c31af7Sopenharmony_ci{
414e5c31af7Sopenharmony_ci	/* Shortcut for GL functionality. */
415e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
416e5c31af7Sopenharmony_ci
417e5c31af7Sopenharmony_ci	/* Return storage. */
418e5c31af7Sopenharmony_ci	glw::GLfloat result[4] = { 7.f, 7.f, 7.f, 7.f };
419e5c31af7Sopenharmony_ci
420e5c31af7Sopenharmony_ci	/* Fetch. */
421e5c31af7Sopenharmony_ci	gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, result);
422e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels has failed");
423e5c31af7Sopenharmony_ci
424e5c31af7Sopenharmony_ci	/* Comparison. */
425e5c31af7Sopenharmony_ci	for (glw::GLuint i = 0; i < 4 /* # components */; ++i)
426e5c31af7Sopenharmony_ci	{
427e5c31af7Sopenharmony_ci		if (de::abs(configuration.expected_result[i] - result[i]) > 0.0125 /* precision */)
428e5c31af7Sopenharmony_ci		{
429e5c31af7Sopenharmony_ci			/* Fail.*/
430e5c31af7Sopenharmony_ci			return false;
431e5c31af7Sopenharmony_ci		}
432e5c31af7Sopenharmony_ci	}
433e5c31af7Sopenharmony_ci
434e5c31af7Sopenharmony_ci	/* Comparsion passed.*/
435e5c31af7Sopenharmony_ci	return true;
436e5c31af7Sopenharmony_ci}
437e5c31af7Sopenharmony_ci
438e5c31af7Sopenharmony_civoid SamplerTest::CleanCase()
439e5c31af7Sopenharmony_ci{
440e5c31af7Sopenharmony_ci	/* Shortcut for GL functionality. */
441e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
442e5c31af7Sopenharmony_ci
443e5c31af7Sopenharmony_ci	/* Program cleanup. */
444e5c31af7Sopenharmony_ci	if (m_po)
445e5c31af7Sopenharmony_ci	{
446e5c31af7Sopenharmony_ci		gl.deleteProgram(m_po);
447e5c31af7Sopenharmony_ci
448e5c31af7Sopenharmony_ci		m_po = 0;
449e5c31af7Sopenharmony_ci	}
450e5c31af7Sopenharmony_ci
451e5c31af7Sopenharmony_ci	/* Texture cleanup. */
452e5c31af7Sopenharmony_ci	if (m_to)
453e5c31af7Sopenharmony_ci	{
454e5c31af7Sopenharmony_ci		gl.deleteTextures(1, &m_to);
455e5c31af7Sopenharmony_ci
456e5c31af7Sopenharmony_ci		m_to = 0;
457e5c31af7Sopenharmony_ci	}
458e5c31af7Sopenharmony_ci
459e5c31af7Sopenharmony_ci	/* Errors cleanup. */
460e5c31af7Sopenharmony_ci	while (gl.getError())
461e5c31af7Sopenharmony_ci		;
462e5c31af7Sopenharmony_ci}
463e5c31af7Sopenharmony_ci
464e5c31af7Sopenharmony_civoid SamplerTest::CleanTest()
465e5c31af7Sopenharmony_ci{
466e5c31af7Sopenharmony_ci	/* Shortcut for GL functionality. */
467e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
468e5c31af7Sopenharmony_ci
469e5c31af7Sopenharmony_ci	/* Framebuffer cleanup. */
470e5c31af7Sopenharmony_ci	if (m_fbo)
471e5c31af7Sopenharmony_ci	{
472e5c31af7Sopenharmony_ci		gl.deleteFramebuffers(1, &m_fbo);
473e5c31af7Sopenharmony_ci
474e5c31af7Sopenharmony_ci		m_fbo = 0;
475e5c31af7Sopenharmony_ci	}
476e5c31af7Sopenharmony_ci
477e5c31af7Sopenharmony_ci	/* Renderbuffer cleanup. */
478e5c31af7Sopenharmony_ci	if (m_rbo)
479e5c31af7Sopenharmony_ci	{
480e5c31af7Sopenharmony_ci		gl.deleteRenderbuffers(1, &m_rbo);
481e5c31af7Sopenharmony_ci
482e5c31af7Sopenharmony_ci		m_rbo = 0;
483e5c31af7Sopenharmony_ci	}
484e5c31af7Sopenharmony_ci
485e5c31af7Sopenharmony_ci	/* Vertex arrays cleanup. */
486e5c31af7Sopenharmony_ci	if (m_vao)
487e5c31af7Sopenharmony_ci	{
488e5c31af7Sopenharmony_ci		gl.deleteVertexArrays(1, &m_vao);
489e5c31af7Sopenharmony_ci
490e5c31af7Sopenharmony_ci		m_vao = 0;
491e5c31af7Sopenharmony_ci	}
492e5c31af7Sopenharmony_ci
493e5c31af7Sopenharmony_ci	/* Errors cleanup. */
494e5c31af7Sopenharmony_ci	while (gl.getError())
495e5c31af7Sopenharmony_ci		;
496e5c31af7Sopenharmony_ci}
497e5c31af7Sopenharmony_ci
498e5c31af7Sopenharmony_ciconst struct SamplerTest::Configuration SamplerTest::s_configurations[] = {
499e5c31af7Sopenharmony_ci	/* regular floating point sampling */
500e5c31af7Sopenharmony_ci	{ GL_TEXTURE_1D, "sampler1D", "texture(texture_input, 0.0)", { 0.f, 0.f, 0.f, 1.f }, false },
501e5c31af7Sopenharmony_ci	{ GL_TEXTURE_2D, "sampler2D", "texture(texture_input, vec2(0.0))", { 0.f, 0.f, 0.f, 1.f }, false },
502e5c31af7Sopenharmony_ci	{ GL_TEXTURE_3D, "sampler3D", "texture(texture_input, vec3(0.0))", { 0.f, 0.f, 0.f, 1.f }, false },
503e5c31af7Sopenharmony_ci	{ GL_TEXTURE_CUBE_MAP, "samplerCube", "texture(texture_input, vec3(0.0))", { 0.f, 0.f, 0.f, 1.f }, false },
504e5c31af7Sopenharmony_ci	{ GL_TEXTURE_RECTANGLE, "sampler2DRect", "texture(texture_input, vec2(0.0))", { 0.f, 0.f, 0.f, 1.f }, false },
505e5c31af7Sopenharmony_ci	{ GL_TEXTURE_1D_ARRAY, "sampler1DArray", "texture(texture_input, vec2(0.0))", { 0.f, 0.f, 0.f, 1.f }, false },
506e5c31af7Sopenharmony_ci	{ GL_TEXTURE_2D_ARRAY, "sampler2DArray", "texture(texture_input, vec3(0.0))", { 0.f, 0.f, 0.f, 1.f }, false },
507e5c31af7Sopenharmony_ci	{ GL_TEXTURE_CUBE_MAP_ARRAY, "samplerCubeArray", "texture(texture_input, vec4(0.0))", { 0.f, 0.f, 0.f, 1.f }, false },
508e5c31af7Sopenharmony_ci
509e5c31af7Sopenharmony_ci	/* Shadow textures. */
510e5c31af7Sopenharmony_ci	{ GL_TEXTURE_1D,
511e5c31af7Sopenharmony_ci	  "sampler1DShadow",
512e5c31af7Sopenharmony_ci	  "vec4(texture(texture_input, vec3(0.0)), 0.0, 0.0, 0.0)",
513e5c31af7Sopenharmony_ci	  { 0.f, 0.f, 0.f, 0.f }, true },
514e5c31af7Sopenharmony_ci	{ GL_TEXTURE_2D,
515e5c31af7Sopenharmony_ci	  "sampler2DShadow",
516e5c31af7Sopenharmony_ci	  "vec4(texture(texture_input, vec3(0.0)), 0.0, 0.0, 0.0)",
517e5c31af7Sopenharmony_ci	  { 0.f, 0.f, 0.f, 0.f }, true },
518e5c31af7Sopenharmony_ci	{ GL_TEXTURE_CUBE_MAP,
519e5c31af7Sopenharmony_ci	  "samplerCubeShadow",
520e5c31af7Sopenharmony_ci	  "vec4(texture(texture_input, vec4(0.0)), 0.0, 0.0, 0.0)",
521e5c31af7Sopenharmony_ci	  { 0.f, 0.f, 0.f, 0.f }, true },
522e5c31af7Sopenharmony_ci	{ GL_TEXTURE_RECTANGLE,
523e5c31af7Sopenharmony_ci	  "sampler2DRectShadow",
524e5c31af7Sopenharmony_ci	  "vec4(texture(texture_input, vec3(0.0)), 0.0, 0.0, 0.0)",
525e5c31af7Sopenharmony_ci	  { 0.f, 0.f, 0.f, 0.f }, true },
526e5c31af7Sopenharmony_ci	{ GL_TEXTURE_1D_ARRAY,
527e5c31af7Sopenharmony_ci	  "sampler1DArrayShadow",
528e5c31af7Sopenharmony_ci	  "vec4(texture(texture_input, vec3(0.0)), 0.0, 0.0, 0.0)",
529e5c31af7Sopenharmony_ci	  { 0.f, 0.f, 0.f, 0.f }, true },
530e5c31af7Sopenharmony_ci	{ GL_TEXTURE_2D_ARRAY,
531e5c31af7Sopenharmony_ci	  "sampler2DArrayShadow",
532e5c31af7Sopenharmony_ci	  "vec4(texture(texture_input, vec4(0.0)), 0.0, 0.0, 0.0)",
533e5c31af7Sopenharmony_ci	  { 0.f, 0.f, 0.f, 0.f }, true },
534e5c31af7Sopenharmony_ci	{ GL_TEXTURE_CUBE_MAP_ARRAY,
535e5c31af7Sopenharmony_ci	  "samplerCubeArrayShadow",
536e5c31af7Sopenharmony_ci	  "vec4(texture(texture_input, vec4(0.0), 1.0), 0.0, 0.0, 0.0)",
537e5c31af7Sopenharmony_ci	  { 0.f, 0.f, 0.f, 0.f }, true }
538e5c31af7Sopenharmony_ci};
539e5c31af7Sopenharmony_ci
540e5c31af7Sopenharmony_ciconst glw::GLuint SamplerTest::s_configurations_count = sizeof(s_configurations) / sizeof(s_configurations[0]);
541e5c31af7Sopenharmony_ci
542e5c31af7Sopenharmony_ciconst glw::GLchar* SamplerTest::s_vertex_shader = "#version 450\n"
543e5c31af7Sopenharmony_ci												  "\n"
544e5c31af7Sopenharmony_ci												  "void main()\n"
545e5c31af7Sopenharmony_ci												  "{\n"
546e5c31af7Sopenharmony_ci												  "    switch(gl_VertexID)\n"
547e5c31af7Sopenharmony_ci												  "    {\n"
548e5c31af7Sopenharmony_ci												  "        case 0:\n"
549e5c31af7Sopenharmony_ci												  "            gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
550e5c31af7Sopenharmony_ci												  "            break;\n"
551e5c31af7Sopenharmony_ci												  "        case 1:\n"
552e5c31af7Sopenharmony_ci												  "            gl_Position = vec4( 1.0, 1.0, 0.0, 1.0);\n"
553e5c31af7Sopenharmony_ci												  "            break;\n"
554e5c31af7Sopenharmony_ci												  "        case 2:\n"
555e5c31af7Sopenharmony_ci												  "            gl_Position = vec4(-1.0,-1.0, 0.0, 1.0);\n"
556e5c31af7Sopenharmony_ci												  "            break;\n"
557e5c31af7Sopenharmony_ci												  "        case 3:\n"
558e5c31af7Sopenharmony_ci												  "            gl_Position = vec4( 1.0,-1.0, 0.0, 1.0);\n"
559e5c31af7Sopenharmony_ci												  "            break;\n"
560e5c31af7Sopenharmony_ci												  "    }\n"
561e5c31af7Sopenharmony_ci												  "}\n";
562e5c31af7Sopenharmony_ci
563e5c31af7Sopenharmony_ciconst glw::GLchar* SamplerTest::s_fragment_shader_head = "#version 450\n"
564e5c31af7Sopenharmony_ci														 "\n"
565e5c31af7Sopenharmony_ci														 "uniform ";
566e5c31af7Sopenharmony_ci
567e5c31af7Sopenharmony_ciconst glw::GLchar* SamplerTest::s_fragment_shader_body = " texture_input;\n"
568e5c31af7Sopenharmony_ci														 "out vec4 texture_output;\n"
569e5c31af7Sopenharmony_ci														 "\n"
570e5c31af7Sopenharmony_ci														 "void main()\n"
571e5c31af7Sopenharmony_ci														 "{\n"
572e5c31af7Sopenharmony_ci														 "    texture_output = ";
573e5c31af7Sopenharmony_ci
574e5c31af7Sopenharmony_ciconst glw::GLchar* SamplerTest::s_fragment_shader_tail = ";\n"
575e5c31af7Sopenharmony_ci														 "}\n";
576e5c31af7Sopenharmony_ci
577e5c31af7Sopenharmony_ci} /* IncompleteTextureAccess namespace */
578e5c31af7Sopenharmony_ci} /* gl4cts namespace */
579