xref: /aosp_15_r20/external/deqp/external/openglcts/modules/gl/gl4cSyncTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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  */
Tests(deqp::Context & context)60 Tests::Tests(deqp::Context &context) : TestCaseGroup(context, "sync", "Sync Tests Suite")
61 {
62 }
63 
64 /** @brief Sync Tests initializer. */
init()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  */
FlushCommandsTest(deqp::Context & context)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  */
iterate()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
164                         << " nanoseconds. Potentially test may not be done in finite time "
165                            "which is expected (OpenGL 4.5 Core Profile, Chapter 4.1.2)."
166                         << " However this cannot be proven in finite time. Test timeouts." << tcu::TestLog::EndMessage;
167 
168                     is_timeout = true;
169                 } /* Check for proper wait result. */
170                 else if ((GL_CONDITION_SATISFIED == wait_result) || (GL_ALREADY_SIGNALED == wait_result))
171                 {
172                     /* Compare destination buffer data with reference. */
173                     if ((reference[0] == data_dst[0]) || (reference[1] == data_dst[1]))
174                     {
175                         is_ok = true;
176                     }
177                     else
178                     {
179                         m_context.getTestContext().getLog()
180                             << tcu::TestLog::Message << "Result data [" << data_dst[0] << ", " << data_dst[1]
181                             << "is not equal to the reference [" << reference[0] << ", " << reference[1]
182                             << "]. Tests fails." << tcu::TestLog::EndMessage;
183                     }
184                 }
185             }
186             else
187             {
188                 m_context.getTestContext().getLog()
189                     << tcu::TestLog::Message << "ClientWaitSync unexpectedly generated error "
190                     << glu::getErrorStr(error) << ". Tests fails." << tcu::TestLog::EndMessage;
191             }
192         }
193 
194         /* Unmapping. */
195         gl.unmapNamedBuffer(buffer_dst);
196         GLU_EXPECT_NO_ERROR(error, "glUnmapNamedBuffer have failed");
197     }
198     catch (...)
199     {
200         is_ok    = false;
201         is_error = true;
202     }
203 
204     /* Cleanup. */
205     if (buffer_src)
206     {
207         gl.deleteBuffers(1, &buffer_src);
208     }
209 
210     if (buffer_dst)
211     {
212         gl.deleteBuffers(1, &buffer_dst);
213     }
214 
215     if (sync)
216     {
217         gl.deleteSync(sync);
218     }
219 
220     /* Result's setup. */
221     if (is_timeout)
222     {
223         m_testCtx.setTestResult(
224             QP_TEST_RESULT_TIMEOUT,
225             "Timeout (Potentially, ClientWaitSync with SYNC_FLUSH_COMMANDS does not return in finite time).");
226     }
227     else
228     {
229         if (is_ok)
230         {
231             m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
232         }
233         else
234         {
235             if (is_error)
236             {
237                 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
238             }
239             else
240             {
241                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
242             }
243         }
244     }
245 
246     return STOP;
247 }
248 } // namespace Sync
249 } // namespace gl4cts
250