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 "gl4cSyncTests.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 /* Timeout of the test in nanoseconds. */
     48 #define TEST_SYNC_WAIT_TIMEOUT 16000000000
     49 
     50 namespace gl4cts
     51 {
     52 namespace Sync
     53 {
     54 /****************************************** Tests Group ***********************************************/
     55 
     56 /** @brief Sync Tests Group constructor.
     57  *
     58  *  @param [in] context     OpenGL context.
     59  */
     60 Tests::Tests(deqp::Context& context) : TestCaseGroup(context, "sync", "Sync Tests Suite")
     61 {
     62 }
     63 
     64 /** @brief Sync Tests initializer. */
     65 void Tests::init()
     66 {
     67 	addChild(new Sync::FlushCommandsTest(m_context));
     68 }
     69 
     70 /*************************************** Flush Commands Test *******************************************/
     71 
     72 /** @brief Sync Flush Commands Test constructor.
     73  *
     74  *  @param [in] context     OpenGL context.
     75  */
     76 FlushCommandsTest::FlushCommandsTest(deqp::Context& context)
     77 	: deqp::TestCase(context, "flush_commands", "Sync Flush Commands Test")
     78 {
     79 	/* Intentionally left blank. */
     80 }
     81 
     82 /** @brief Iterate Sync Flush Commands Test cases.
     83  *
     84  *  @return Iteration result.
     85  */
     86 tcu::TestNode::IterateResult FlushCommandsTest::iterate()
     87 {
     88 	/* Shortcut for GL functionality. */
     89 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
     90 
     91 	/* Get context setup. */
     92 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
     93 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
     94 
     95 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
     96 	{
     97 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
     98 
     99 		return STOP;
    100 	}
    101 
    102 	/* Running tests. */
    103 	bool is_ok		= false;
    104 	bool is_error   = false;
    105 	bool is_timeout = false;
    106 
    107 	/* Test constants. */
    108 	static const glw::GLuint reference[2]   = { 3, 1415927 };
    109 	static const glw::GLuint reference_size = sizeof(reference);
    110 
    111 	/* Test objects. */
    112 	glw::GLuint buffer_src = 0;
    113 	glw::GLuint buffer_dst = 0;
    114 	glw::GLsync sync	   = 0;
    115 	glw::GLenum error	  = GL_NO_ERROR;
    116 
    117 	try
    118 	{
    119 		/* Prepare buffers. */
    120 		gl.createBuffers(1, &buffer_src);
    121 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers have failed");
    122 		gl.namedBufferData(buffer_src, reference_size, reference, GL_STATIC_COPY);
    123 		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData have failed");
    124 
    125 		gl.createBuffers(1, &buffer_dst);
    126 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers have failed");
    127 		gl.namedBufferStorage(buffer_dst, reference_size, NULL,
    128 							  GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
    129 		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferStorage have failed");
    130 
    131 		/* Map perisistently buffer range. */
    132 		glw::GLuint* data_dst = (glw::GLuint*)gl.mapNamedBufferRange(
    133 			buffer_dst, 0, reference_size, GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
    134 		GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBufferRange have failed");
    135 
    136 		/* Copy data from source to destination buffer */
    137 		gl.copyNamedBufferSubData(buffer_src, buffer_dst, 0, 0, reference_size);
    138 
    139 		if (GL_NO_ERROR != (error = gl.getError()))
    140 		{
    141 			gl.unmapNamedBuffer(buffer_dst);
    142 
    143 			GLU_EXPECT_NO_ERROR(error, "glCopyNamedBufferSubData have failed");
    144 		}
    145 
    146 		/* Create fence sync object. */
    147 		sync = gl.fenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
    148 
    149 		if (GL_NO_ERROR == (error = gl.getError()))
    150 		{
    151 			/* Wait until done. */
    152 			glw::GLenum wait_result = gl.clientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT, TEST_SYNC_WAIT_TIMEOUT);
    153 
    154 			/* Check for error. */
    155 			if (GL_NO_ERROR == (error = gl.getError()))
    156 			{
    157 				/* Check for timeout. */
    158 				if (GL_TIMEOUT_EXPIRED == wait_result)
    159 				{
    160 					m_context.getTestContext().getLog()
    161 						<< tcu::TestLog::Message
    162 						<< "ClientWaitSync with SYNC_FLUSH_COMMANDS_BIT flag has returned TIMEOUT_EXPIRED after "
    163 						<< TEST_SYNC_WAIT_TIMEOUT << " nanoseconds. Potentially test may not be done in finite time "
    164 													 "which is expected (OpenGL 4.5 Core Profile, Chapter 4.1.2)."
    165 						<< " However this cannot be proven in finite time. Test timeouts." << tcu::TestLog::EndMessage;
    166 
    167 					is_timeout = true;
    168 				} /* Check for proper wait result. */
    169 				else if ((GL_CONDITION_SATISFIED == wait_result) || (GL_ALREADY_SIGNALED == wait_result))
    170 				{
    171 					/* Compare destination buffer data with reference. */
    172 					if ((reference[0] == data_dst[0]) || (reference[1] == data_dst[1]))
    173 					{
    174 						is_ok = true;
    175 					}
    176 					else
    177 					{
    178 						m_context.getTestContext().getLog() << tcu::TestLog::Message << "Result data [" << data_dst[0]
    179 															<< ", " << data_dst[1] << "is not equal to the reference ["
    180 															<< reference[0] << ", " << reference[1] << "]. Tests fails."
    181 															<< tcu::TestLog::EndMessage;
    182 					}
    183 				}
    184 			}
    185 			else
    186 			{
    187 				m_context.getTestContext().getLog()
    188 					<< tcu::TestLog::Message << "ClientWaitSync unexpectedly generated error "
    189 					<< glu::getErrorStr(error) << ". Tests fails." << tcu::TestLog::EndMessage;
    190 			}
    191 		}
    192 
    193 		/* Unmapping. */
    194 		gl.unmapNamedBuffer(buffer_dst);
    195 		GLU_EXPECT_NO_ERROR(error, "glUnmapNamedBuffer have failed");
    196 	}
    197 	catch (...)
    198 	{
    199 		is_ok	= false;
    200 		is_error = true;
    201 	}
    202 
    203 	/* Cleanup. */
    204 	if (buffer_src)
    205 	{
    206 		gl.deleteBuffers(1, &buffer_src);
    207 	}
    208 
    209 	if (buffer_dst)
    210 	{
    211 		gl.deleteBuffers(1, &buffer_dst);
    212 	}
    213 
    214 	if (sync)
    215 	{
    216 		gl.deleteSync(sync);
    217 	}
    218 
    219 	/* Result's setup. */
    220 	if (is_timeout)
    221 	{
    222 		m_testCtx.setTestResult(
    223 			QP_TEST_RESULT_TIMEOUT,
    224 			"Timeout (Potentially, ClientWaitSync with SYNC_FLUSH_COMMANDS does not return in finite time).");
    225 	}
    226 	else
    227 	{
    228 		if (is_ok)
    229 		{
    230 			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    231 		}
    232 		else
    233 		{
    234 			if (is_error)
    235 			{
    236 				m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
    237 			}
    238 			else
    239 			{
    240 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
    241 			}
    242 		}
    243 	}
    244 
    245 	return STOP;
    246 }
    247 } /* Sync namespace */
    248 } /* gl4cts namespace */
    249