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