Merge "Fix color change verification in dithering tests" into nougat-cts-dev am:...
[platform/upstream/VK-GL-CTS.git] / modules / gles3 / functional / es3fSyncTests.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.0 Module
3  * -------------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
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 Sync tests.
22  *//*--------------------------------------------------------------------*/
23
24 #include "es3fSyncTests.hpp"
25
26 #include "tcuTestLog.hpp"
27 #include "tcuVector.hpp"
28 #include "gluShaderProgram.hpp"
29 #include "gluCallLogWrapper.hpp"
30 #include "gluRenderContext.hpp"
31 #include "glwEnums.hpp"
32 #include "deRandom.hpp"
33 #include "deStringUtil.hpp"
34 #include "deString.h"
35
36 #include <vector>
37
38 using tcu::TestLog;
39
40 namespace deqp
41 {
42 namespace gles3
43 {
44 namespace Functional
45 {
46
47 using namespace glw; // GL types
48
49 static const int        NUM_CASE_ITERATIONS = 5;
50
51 enum WaitCommand
52 {
53         COMMAND_WAIT_SYNC                       = 1 << 0,
54         COMMAND_CLIENT_WAIT_SYNC        = 1 << 1
55 };
56
57 enum CaseOptions
58 {
59         CASE_FLUSH_BEFORE_WAIT  = 1 << 0,
60         CASE_FINISH_BEFORE_WAIT = 1 << 1
61 };
62
63 class FenceSyncCase : public TestCase, private glu::CallLogWrapper
64 {
65 public:
66                                                 FenceSyncCase           (Context& context, const char* name, const char* description, int numPrimitives, deUint32 waitCommand, deUint32 waitFlags, deUint64 timeout, deUint32 options);
67                                                 ~FenceSyncCase          (void);
68
69         void                            init                            (void);
70         void                            deinit                          (void);
71         IterateResult           iterate                         (void);
72
73 private:
74                                                 FenceSyncCase           (const FenceSyncCase& other);
75         FenceSyncCase&          operator=                       (const FenceSyncCase& other);
76
77         int                                     m_numPrimitives;
78         deUint32                        m_waitCommand;
79         deUint32                        m_waitFlags;
80         deUint64                        m_timeout;
81         deUint32                        m_caseOptions;
82
83         glu::ShaderProgram*     m_program;
84         GLsync                          m_syncObject;
85         int                                     m_iterNdx;
86         de::Random                      m_rnd;
87 };
88
89 FenceSyncCase::FenceSyncCase (Context& context, const char* name, const char* description, int numPrimitives, deUint32 waitCommand, deUint32 waitFlags, deUint64 timeout, deUint32 options)
90         : TestCase                              (context, name, description)
91         , CallLogWrapper                (context.getRenderContext().getFunctions(), context.getTestContext().getLog())
92         , m_numPrimitives               (numPrimitives)
93         , m_waitCommand                 (waitCommand)
94         , m_waitFlags                   (waitFlags)
95         , m_timeout                             (timeout)
96         , m_caseOptions                 (options)
97         , m_program                             (DE_NULL)
98         , m_syncObject                  (DE_NULL)
99         , m_iterNdx                             (0)
100         , m_rnd                                 (deStringHash(name))
101 {
102 }
103
104 FenceSyncCase::~FenceSyncCase (void)
105 {
106         FenceSyncCase::deinit();
107 }
108
109 static void generateVertices (std::vector<float>& dst, int numPrimitives, de::Random& rnd)
110 {
111         int numVertices = 3*numPrimitives;
112         dst.resize(numVertices * 4);
113
114         for (int i = 0; i < numVertices; i++)
115         {
116                 dst[i*4    ] = rnd.getFloat(-1.0f, 1.0f);       // x
117                 dst[i*4 + 1] = rnd.getFloat(-1.0f, 1.0f);       // y
118                 dst[i*4 + 2] = rnd.getFloat( 0.0f, 1.0f);       // z
119                 dst[i*4 + 3] = 1.0f;                                            // w
120         }
121 }
122
123 void FenceSyncCase::init (void)
124 {
125         const char*     vertShaderSource =
126                                 "#version 300 es\n"
127                                 "layout(location = 0) in mediump vec4 a_position;\n"
128                                 "\n"
129                                 "void main (void)\n"
130                                 "{\n"
131                                 "       gl_Position = a_position;\n"
132                                 "}\n";
133
134         const char* fragShaderSource =
135                                 "#version 300 es\n"
136                                 "layout(location = 0) out mediump vec4 o_color;\n"
137                                 "\n"
138                                 "void main (void)\n"
139                                 "{\n"
140                                 "       o_color = vec4(0.25, 0.5, 0.75, 1.0);\n"
141                                 "}\n";
142
143         DE_ASSERT(!m_program);
144         m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(vertShaderSource, fragShaderSource));
145
146         if (!m_program->isOk())
147         {
148                 m_testCtx.getLog() << *m_program;
149                 TCU_FAIL("Failed to compile shader program");
150         }
151
152         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); // Initialize test result to pass.
153         GLU_CHECK_MSG("Case initialization finished");
154 }
155
156 void FenceSyncCase::deinit (void)
157 {
158         if (m_program)
159         {
160                 delete m_program;
161                 m_program = DE_NULL;
162         }
163
164         if (m_syncObject)
165         {
166                 glDeleteSync(m_syncObject);
167                 m_syncObject = DE_NULL;
168         }
169 }
170
171 FenceSyncCase::IterateResult FenceSyncCase::iterate (void)
172 {
173         TestLog&                                        log                     = m_testCtx.getLog();
174         std::vector<float>                      vertices;
175         bool                                            testOk          = true;
176
177         std::string                                     header          = "Case iteration " + de::toString(m_iterNdx+1) + " / " + de::toString(NUM_CASE_ITERATIONS);
178         const tcu::ScopedLogSection     section         (log, header, header);
179
180         enableLogging(true);
181
182         DE_ASSERT               (m_program);
183         glUseProgram    (m_program->getProgram());
184         glEnable                (GL_DEPTH_TEST);
185         glClearColor    (0.3f, 0.3f, 0.3f, 1.0f);
186         glClearDepthf   (1.0f);
187         glClear                 (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
188
189         // Generate vertices
190
191         glEnableVertexAttribArray (0);
192         generateVertices                  (vertices, m_numPrimitives, m_rnd);
193         glVertexAttribPointer     (0, 4, GL_FLOAT, GL_FALSE, 0, &vertices[0]);
194
195         // Draw
196
197         glDrawArrays(GL_TRIANGLES, 0, (int)vertices.size() / 4);
198         log << TestLog::Message << "// Primitives drawn." << TestLog::EndMessage;
199
200         // Create sync object
201
202         m_syncObject = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
203         GLU_CHECK_MSG ("Sync object created");
204         log << TestLog::Message << "// Sync object created." << TestLog::EndMessage;
205
206         if (m_caseOptions & CASE_FLUSH_BEFORE_WAIT)
207                 glFlush();
208         if (m_caseOptions & CASE_FINISH_BEFORE_WAIT)
209                 glFinish();
210
211         // Wait for sync object
212
213         GLenum waitValue = 0;
214
215         if (m_waitCommand & COMMAND_WAIT_SYNC)
216         {
217                 DE_ASSERT(m_timeout == GL_TIMEOUT_IGNORED);
218                 DE_ASSERT(m_waitFlags == 0);
219                 glWaitSync(m_syncObject, m_waitFlags, m_timeout);
220                 GLU_CHECK_MSG ("glWaitSync called");
221                 log << TestLog::Message << "// Wait command glWaitSync called with GL_TIMEOUT_IGNORED." << TestLog::EndMessage;
222         }
223         if (m_waitCommand & COMMAND_CLIENT_WAIT_SYNC)
224         {
225                 waitValue = glClientWaitSync(m_syncObject, m_waitFlags, m_timeout);
226                 GLU_CHECK_MSG ("glClientWaitSync called");
227                 log << TestLog::Message << "// glClientWaitSync return value:" << TestLog::EndMessage;
228                 switch (waitValue)
229                 {
230                         case GL_ALREADY_SIGNALED:        log << TestLog::Message << "// GL_ALREADY_SIGNALED"    << TestLog::EndMessage; break;
231                         case GL_TIMEOUT_EXPIRED:         log << TestLog::Message << "// GL_TIMEOUT_EXPIRED"             << TestLog::EndMessage; break;
232                         case GL_CONDITION_SATISFIED: log << TestLog::Message << "// GL_CONDITION_SATISFIED"     << TestLog::EndMessage; break;
233                         case GL_WAIT_FAILED:             log << TestLog::Message << "// GL_WAIT_FAILED"                 << TestLog::EndMessage; testOk = false; break;
234                         default:                                         TCU_FAIL("// Illegal return value!");
235                 }
236         }
237
238         glFinish();
239
240         if (m_caseOptions & CASE_FINISH_BEFORE_WAIT && waitValue != GL_ALREADY_SIGNALED)
241         {
242                 testOk = false;
243                 log << TestLog::Message << "// Expected glClientWaitSync to return GL_ALREADY_SIGNALED." << TestLog::EndMessage;
244         }
245
246         // Delete sync object
247
248         if (m_syncObject)
249         {
250                 glDeleteSync(m_syncObject);
251                 m_syncObject = DE_NULL;
252                 GLU_CHECK_MSG ("Sync object deleted");
253                 log << TestLog::Message << "// Sync object deleted." << TestLog::EndMessage;
254         }
255
256         // Evaluate test result
257
258         log << TestLog::Message << "// Test result: " << (testOk ? "Passed!" : "Failed!") << TestLog::EndMessage;
259
260         if (!testOk)
261         {
262                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
263                 return STOP;
264         }
265
266         log << TestLog::Message << "// Sync objects created and deleted successfully." << TestLog::EndMessage;
267
268         return (++m_iterNdx < NUM_CASE_ITERATIONS) ? CONTINUE : STOP;
269 }
270
271 SyncTests::SyncTests (Context& context)
272         : TestCaseGroup(context, "fence_sync", "Fence Sync Tests")
273 {
274 }
275
276 SyncTests::~SyncTests (void)
277 {
278 }
279
280 void SyncTests::init (void)
281 {
282         // Fence sync tests.
283
284         addChild(new FenceSyncCase(m_context, "wait_sync_smalldraw",    "",     10,             COMMAND_WAIT_SYNC,      0, GL_TIMEOUT_IGNORED,  0));
285         addChild(new FenceSyncCase(m_context, "wait_sync_largedraw",    "",     10000,  COMMAND_WAIT_SYNC,      0, GL_TIMEOUT_IGNORED,  0));
286
287         addChild(new FenceSyncCase(m_context, "client_wait_sync_smalldraw",                     "",     10,             COMMAND_CLIENT_WAIT_SYNC,       0, 0,   0));
288         addChild(new FenceSyncCase(m_context, "client_wait_sync_largedraw",                     "",     10000,  COMMAND_CLIENT_WAIT_SYNC,       0, 0,   0));
289         addChild(new FenceSyncCase(m_context, "client_wait_sync_timeout_smalldraw",     "",     10,             COMMAND_CLIENT_WAIT_SYNC,       0, 10,  0));
290         addChild(new FenceSyncCase(m_context, "client_wait_sync_timeout_largedraw",     "",     10000,  COMMAND_CLIENT_WAIT_SYNC,       0, 10,  0));
291
292         addChild(new FenceSyncCase(m_context, "client_wait_sync_flush_auto",    "",     10000, COMMAND_CLIENT_WAIT_SYNC,        GL_SYNC_FLUSH_COMMANDS_BIT, 0,  0));
293         addChild(new FenceSyncCase(m_context, "client_wait_sync_flush_manual",  "",     10000, COMMAND_CLIENT_WAIT_SYNC,        0,                                                      0,      CASE_FLUSH_BEFORE_WAIT));
294         addChild(new FenceSyncCase(m_context, "client_wait_sync_noflush",               "",     10000, COMMAND_CLIENT_WAIT_SYNC,        0,                                                      0,      0));
295         addChild(new FenceSyncCase(m_context, "client_wait_sync_finish",                "",     10000, COMMAND_CLIENT_WAIT_SYNC,        0,                                                      0,      CASE_FINISH_BEFORE_WAIT));
296 }
297
298 } // Functional
299 } // gles3
300 } // deqp