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