Home | History | Annotate | Download | only in texture_buffer
      1 /*-------------------------------------------------------------------------
      2  * OpenGL Conformance Test Suite
      3  * -----------------------------
      4  *
      5  * Copyright (c) 2014-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  esextcTextureBufferPrecision.hpp
     26  * \brief Texture Buffer Precision Qualifier (Test 10)
     27  */ /*-------------------------------------------------------------------*/
     28 
     29 #include "esextcTextureBufferPrecision.hpp"
     30 #include "gluContextInfo.hpp"
     31 #include "gluDefs.hpp"
     32 #include "gluShaderUtil.hpp"
     33 #include "glwEnums.hpp"
     34 #include "glwFunctions.hpp"
     35 #include "tcuTestLog.hpp"
     36 #include <cstring>
     37 #include <stddef.h>
     38 
     39 namespace glcts
     40 {
     41 /* Head of the compute shader. */
     42 const char* const TextureBufferPrecision::m_cs_code_head = "${VERSION}\n"
     43 														   "\n"
     44 														   "${TEXTURE_BUFFER_REQUIRE}\n"
     45 														   "\n";
     46 
     47 /* Variables declarations for the compute shader without usage of the precision qualifier. */
     48 const char* const TextureBufferPrecision::m_cs_code_declaration_without_precision[3] = {
     49 	"layout (r32f)  uniform  imageBuffer image_buffer;\n"
     50 	"\n"
     51 	"buffer ComputeSSBO\n"
     52 	"{\n"
     53 	"    float value;\n"
     54 	"} computeSSBO;\n",
     55 
     56 	"layout (r32i)  uniform iimageBuffer image_buffer;\n"
     57 	"\n"
     58 	"buffer ComputeSSBO\n"
     59 	"{\n"
     60 	"    int value;\n"
     61 	"} computeSSBO;\n",
     62 
     63 	"layout (r32ui) uniform uimageBuffer image_buffer;\n"
     64 	"\n"
     65 	"buffer ComputeSSBO\n"
     66 	"{\n"
     67 	"    uint value;\n"
     68 	"} computeSSBO;\n"
     69 };
     70 
     71 /* Variables declarations for the compute shader with usage of the precision qualifier. */
     72 const char* const TextureBufferPrecision::m_cs_code_declaration_with_precision[3] = {
     73 	"layout (r32f)  uniform highp  imageBuffer image_buffer;\n"
     74 	"\n"
     75 	"buffer ComputeSSBO\n"
     76 	"{\n"
     77 	"    float value;\n"
     78 	"} computeSSBO;\n",
     79 
     80 	"layout (r32i)  uniform highp iimageBuffer image_buffer;\n"
     81 	"\n"
     82 	"buffer ComputeSSBO\n"
     83 	"{\n"
     84 	"    int value;\n"
     85 	"} computeSSBO;\n",
     86 
     87 	"layout (r32ui) uniform highp uimageBuffer image_buffer;\n"
     88 	"\n"
     89 	"buffer ComputeSSBO\n"
     90 	"{\n"
     91 	"    uint value;\n"
     92 	"} computeSSBO;\n"
     93 };
     94 
     95 /* The default precision qualifier declarations for the compute shader. */
     96 const char* const TextureBufferPrecision::m_cs_code_global_precision[3] = { "precision highp  imageBuffer;\n",
     97 																			"precision highp iimageBuffer;\n",
     98 																			"precision highp uimageBuffer;\n" };
     99 
    100 /* The compute shader body. */
    101 const char* const TextureBufferPrecision::m_cs_code_body = "\n"
    102 														   "void main()\n"
    103 														   "{\n"
    104 														   "    computeSSBO.value = imageLoad(image_buffer, 0).x;\n"
    105 														   "}";
    106 
    107 /* Head of the fragment shader. */
    108 const char* const TextureBufferPrecision::m_fs_code_head = "${VERSION}\n"
    109 														   "\n"
    110 														   "${TEXTURE_BUFFER_REQUIRE}\n"
    111 														   "\n";
    112 
    113 /* Variables declarations for the fragment shader without usage of the precision qualifier. */
    114 const char* const TextureBufferPrecision::m_fs_code_declaration_without_precision[3] = {
    115 	"uniform  samplerBuffer sampler_buffer;\n"
    116 	"\n"
    117 	"layout(location = 0) out highp vec4 color;\n",
    118 
    119 	"uniform isamplerBuffer sampler_buffer;\n"
    120 	"\n"
    121 	"layout(location = 0) out highp ivec4 color;\n",
    122 
    123 	"uniform usamplerBuffer sampler_buffer;\n"
    124 	"\n"
    125 	"layout(location = 0) out highp uvec4 color;\n"
    126 };
    127 
    128 /* Variables declarations for the fragment shader with usage of the precision qualifier. */
    129 const char* const TextureBufferPrecision::m_fs_code_declaration_with_precision[3] = {
    130 	"uniform highp  samplerBuffer sampler_buffer;\n"
    131 	"\n"
    132 	"layout(location = 0) out highp vec4 color;\n",
    133 
    134 	"uniform highp isamplerBuffer sampler_buffer;\n"
    135 	"\n"
    136 	"layout(location = 0) out highp ivec4 color;\n",
    137 
    138 	"uniform highp usamplerBuffer sampler_buffer;\n"
    139 	"\n"
    140 	"layout(location = 0) out highp uvec4 color;\n",
    141 };
    142 
    143 /* The default precision qualifier declarations for the fragment shader. */
    144 const char* const TextureBufferPrecision::m_fs_code_global_precision[3] = {
    145 	"precision highp  samplerBuffer;\n", "precision highp isamplerBuffer;\n", "precision highp usamplerBuffer;\n",
    146 };
    147 
    148 /* The fragment shader body. */
    149 const char* const TextureBufferPrecision::m_fs_code_body = "\n"
    150 														   "void main()\n"
    151 														   "{\n"
    152 														   "    color = texelFetch( sampler_buffer, 0 );\n"
    153 														   "}";
    154 
    155 /** Constructor
    156  *
    157  * @param context     Test context
    158  * @param name        Test case's name
    159  * @param description Test case's description
    160  **/
    161 TextureBufferPrecision::TextureBufferPrecision(Context& context, const ExtParameters& extParams, const char* name,
    162 											   const char* description)
    163 	: TestCaseBase(context, extParams, name, description), m_po_id(0), m_sh_id(0)
    164 {
    165 	//Bug-15063 Only GLSL 4.50 supports opaque types
    166 	if (m_glslVersion >= glu::GLSL_VERSION_130)
    167 	{
    168 		m_glslVersion = glu::GLSL_VERSION_450;
    169 	}
    170 }
    171 
    172 /** Deinitializes GLES objects created during the test */
    173 void TextureBufferPrecision::deinit(void)
    174 {
    175 	/* Retrieve GLES entry points. */
    176 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    177 
    178 	/* Delete GLES objects */
    179 	if (m_po_id != 0)
    180 	{
    181 		gl.deleteProgram(m_po_id);
    182 		m_po_id = 0;
    183 	}
    184 
    185 	if (m_sh_id != 0)
    186 	{
    187 		gl.deleteShader(m_sh_id);
    188 		m_sh_id = 0;
    189 	}
    190 
    191 	/* Deinitialize base class */
    192 	TestCaseBase::deinit();
    193 }
    194 
    195 /** Check if the shader compiles.
    196  *
    197  *  Note the function throws exception should an error occur!
    198  *
    199  *  @param shader_type      GL shader type.
    200  *  @param sh_code_parts    Shader source parts
    201  *  @param parts_count      Shader source parts count
    202  *
    203  *  @return true if the shader compiles, return false otherwise.
    204  **/
    205 glw::GLboolean TextureBufferPrecision::verifyShaderCompilationStatus(glw::GLenum	   shader_type,
    206 																	 const char**	  sh_code_parts,
    207 																	 const glw::GLuint parts_count,
    208 																	 const glw::GLint  expected_status)
    209 {
    210 	/* Retrieve GLES entry points. */
    211 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    212 
    213 	glw::GLboolean test_passed = true;
    214 
    215 	m_po_id = gl.createProgram();
    216 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create program object");
    217 
    218 	m_sh_id = gl.createShader(shader_type);
    219 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object");
    220 
    221 	std::string shader_code		= specializeShader(parts_count, sh_code_parts);
    222 	const char* shader_code_ptr = shader_code.c_str();
    223 	gl.shaderSource(m_sh_id, 1, &shader_code_ptr, DE_NULL);
    224 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set shader source");
    225 
    226 	gl.compileShader(m_sh_id);
    227 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to perform compilation of shader object");
    228 
    229 	/* Retrieving compilation status */
    230 	glw::GLint compilation_status = GL_FALSE;
    231 	gl.getShaderiv(m_sh_id, GL_COMPILE_STATUS, &compilation_status);
    232 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not retrieve shader compilation status");
    233 
    234 	if (compilation_status != expected_status)
    235 	{
    236 		test_passed = false;
    237 
    238 		glw::GLsizei info_log_length = 0;
    239 		gl.getShaderiv(m_sh_id, GL_INFO_LOG_LENGTH, &info_log_length);
    240 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not get shader info log length");
    241 
    242 		if (info_log_length > 0)
    243 		{
    244 			glw::GLchar* info_log = new glw::GLchar[info_log_length];
    245 			memset(info_log, 0, info_log_length * sizeof(glw::GLchar));
    246 			gl.getShaderInfoLog(m_sh_id, info_log_length, DE_NULL, info_log);
    247 
    248 			m_testCtx.getLog() << tcu::TestLog::Message << "The following shader:\n\n"
    249 							   << shader_code << "\n\n did compile with result different than expected:\n"
    250 							   << expected_status << "\n\n Compilation info log: \n"
    251 							   << info_log << "\n"
    252 							   << tcu::TestLog::EndMessage;
    253 
    254 			delete[] info_log;
    255 
    256 			GLU_EXPECT_NO_ERROR(gl.getError(), "Could not get shader info log");
    257 		}
    258 	}
    259 
    260 	/* Clean up */
    261 	if (m_po_id != 0)
    262 	{
    263 		gl.deleteProgram(m_po_id);
    264 		m_po_id = 0;
    265 	}
    266 
    267 	if (m_sh_id != 0)
    268 	{
    269 		gl.deleteShader(m_sh_id);
    270 		m_sh_id = 0;
    271 	}
    272 
    273 	return test_passed;
    274 }
    275 
    276 /** Executes the test.
    277  *
    278  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
    279  *
    280  *  Note the function throws exception should an error occur!
    281  *
    282  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
    283  **/
    284 tcu::TestNode::IterateResult TextureBufferPrecision::iterate(void)
    285 {
    286 	/* Skip if required extensions are not supported. */
    287 	if (!m_is_texture_buffer_supported)
    288 	{
    289 		throw tcu::NotSupportedError(TEXTURE_BUFFER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
    290 	}
    291 
    292 	glu::ContextType contextType   = m_context.getRenderContext().getType();
    293 	glw::GLboolean   test_passed   = true;
    294 	glw::GLint		 expected_fail = glu::glslVersionIsES(m_glslVersion) ? GL_FALSE : GL_TRUE;
    295 
    296 	/* Default precision qualifiers for opaque types are not supported prior to GLSL 4.50. */
    297 	if (glu::contextSupports(contextType, glu::ApiType::core(4, 5)) ||
    298 		glu::contextSupports(contextType, glu::ApiType::es(3, 1)))
    299 	{
    300 		/* Compute Shader Tests */
    301 		for (glw::GLuint i = 0; i < 3; ++i) /* For each from the set {imageBuffer, iimageBuffer, uimageBuffer} */
    302 		{
    303 			const char* cs_code_without_precision[3] = { m_cs_code_head, m_cs_code_declaration_without_precision[i],
    304 														 m_cs_code_body };
    305 
    306 			const char* cs_code_with_precision[3] = { m_cs_code_head, m_cs_code_declaration_with_precision[i],
    307 													  m_cs_code_body };
    308 
    309 			const char* cs_code_with_global_precision[4] = { m_cs_code_head, m_cs_code_global_precision[i],
    310 															 m_cs_code_declaration_without_precision[i],
    311 															 m_cs_code_body };
    312 
    313 			test_passed =
    314 				verifyShaderCompilationStatus(GL_COMPUTE_SHADER, cs_code_without_precision, 3, expected_fail) &&
    315 				test_passed;
    316 			test_passed =
    317 				verifyShaderCompilationStatus(GL_COMPUTE_SHADER, cs_code_with_precision, 3, GL_TRUE) && test_passed;
    318 			test_passed = verifyShaderCompilationStatus(GL_COMPUTE_SHADER, cs_code_with_global_precision, 4, GL_TRUE) &&
    319 						  test_passed;
    320 		}
    321 	}
    322 
    323 	/* Fragment Shader Tests */
    324 	for (glw::GLuint i = 0; i < 3; ++i) /* For each from the set {samplerBuffer, isamplerBuffer, usamplerBuffer} */
    325 	{
    326 		const char* fs_code_without_precision[3] = { m_fs_code_head, m_fs_code_declaration_without_precision[i],
    327 													 m_fs_code_body };
    328 
    329 		const char* fs_code_with_precision[3] = { m_fs_code_head, m_fs_code_declaration_with_precision[i],
    330 												  m_fs_code_body };
    331 
    332 		const char* fs_code_with_global_precision[4] = { m_fs_code_head, m_fs_code_global_precision[i],
    333 														 m_fs_code_declaration_without_precision[i], m_fs_code_body };
    334 
    335 		test_passed = verifyShaderCompilationStatus(GL_FRAGMENT_SHADER, fs_code_without_precision, 3, expected_fail) &&
    336 					  test_passed;
    337 		test_passed =
    338 			verifyShaderCompilationStatus(GL_FRAGMENT_SHADER, fs_code_with_precision, 3, GL_TRUE) && test_passed;
    339 		test_passed =
    340 			verifyShaderCompilationStatus(GL_FRAGMENT_SHADER, fs_code_with_global_precision, 4, GL_TRUE) && test_passed;
    341 	}
    342 
    343 	if (test_passed)
    344 	{
    345 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    346 	}
    347 	else
    348 	{
    349 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
    350 	}
    351 
    352 	return STOP;
    353 }
    354 
    355 } /* namespace glcts */
    356