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 #include "glcTestSubcase.hpp"
25 #include "glwEnums.hpp"
26 #include "glwFunctions.hpp"
27 #include "tcuCommandLine.hpp"
28 #include "tcuTestLog.hpp"
29
30 namespace deqp
31 {
32
33 namespace
34 {
35 static Context* current_context;
36 }
37
GLWrapper()38 GLWrapper::GLWrapper()
39 : CallLogWrapper(current_context->getRenderContext().getFunctions(), current_context->getTestContext().getLog())
40 , m_context(*current_context)
41 {
42 }
43
SubcaseBase()44 SubcaseBase::SubcaseBase()
45 {
46 }
47
~SubcaseBase()48 SubcaseBase::~SubcaseBase()
49 {
50 }
51
Setup()52 long SubcaseBase::Setup()
53 {
54 return NO_ERROR;
55 }
56
Cleanup()57 long SubcaseBase::Cleanup()
58 {
59 return NO_ERROR;
60 }
61
VertexShader()62 std::string SubcaseBase::VertexShader()
63 {
64 return "";
65 }
66
VertexShader2()67 std::string SubcaseBase::VertexShader2()
68 {
69 return "";
70 }
71
TessControlShader()72 std::string SubcaseBase::TessControlShader()
73 {
74 return "";
75 }
76
TessControlShader2()77 std::string SubcaseBase::TessControlShader2()
78 {
79 return "";
80 }
81
TessEvalShader()82 std::string SubcaseBase::TessEvalShader()
83 {
84 return "";
85 }
86
TessEvalShader2()87 std::string SubcaseBase::TessEvalShader2()
88 {
89 return "";
90 }
91
GeometryShader()92 std::string SubcaseBase::GeometryShader()
93 {
94 return "";
95 }
96
GeometryShader2()97 std::string SubcaseBase::GeometryShader2()
98 {
99 return "";
100 }
101
FragmentShader()102 std::string SubcaseBase::FragmentShader()
103 {
104 return "";
105 }
106
FragmentShader2()107 std::string SubcaseBase::FragmentShader2()
108 {
109 return "";
110 }
111
WriteField(tcu::TestLog & log,const char * title,std::string message)112 void WriteField(tcu::TestLog& log, const char* title, std::string message)
113 {
114 if (message == "")
115 return;
116 using namespace std;
117 using tcu::TestLog;
118 istringstream tokens(message);
119 string line;
120 log.startSection("Details", title);
121 while (getline(tokens, line))
122 {
123 log.writeMessage(line.c_str());
124 }
125 log.endSection();
126 }
127
OutputNotSupported(std::string reason)128 void SubcaseBase::OutputNotSupported(std::string reason)
129 {
130 using tcu::TestLog;
131 TestLog& log = m_context.getTestContext().getLog();
132 std::string msg = reason + ", test will not run.";
133 std::istringstream tokens(msg);
134 std::string line;
135 log.startSection("Not supported", "Reason");
136 while (getline(tokens, line))
137 {
138 log.writeMessage(line.c_str());
139 }
140 log.endSection();
141 }
142
Documentation()143 void SubcaseBase::Documentation()
144 {
145 using namespace std;
146 using tcu::TestLog;
147 TestLog& log = m_context.getTestContext().getLog();
148
149 WriteField(log, "Title", Title());
150 WriteField(log, "Purpose", Purpose());
151 WriteField(log, "Method", Method());
152 WriteField(log, "Pass Criteria", PassCriteria());
153
154 //OpenGL fields
155 string vsh = VertexShader();
156 if (!vsh.empty())
157 WriteField(log, "OpenGL vertex shader", vsh);
158
159 string vsh2 = VertexShader2();
160 if (!vsh2.empty())
161 WriteField(log, "OpenGL vertex shader 2", vsh2);
162
163 string tcsh = TessControlShader();
164 if (!tcsh.empty())
165 WriteField(log, "OpenGL tessellation control shader", tcsh);
166
167 string tcsh2 = TessControlShader();
168 if (!tcsh2.empty())
169 WriteField(log, "OpenGL tessellation control shader 2", tcsh2);
170
171 string tesh = TessControlShader();
172 if (!tesh.empty())
173 WriteField(log, "OpenGL tessellation evaluation shader", tesh);
174
175 string tesh2 = TessControlShader();
176 if (!tesh2.empty())
177 WriteField(log, "OpenGL tessellation evaluation shader 2", tesh2);
178
179 string gsh = GeometryShader();
180 if (!gsh.empty())
181 WriteField(log, "OpenGL geometry shader", gsh);
182
183 string gsh2 = GeometryShader2();
184 if (!gsh2.empty())
185 WriteField(log, "OpenGL geometry shader 2", gsh2);
186
187 string fsh = FragmentShader();
188 if (!fsh.empty())
189 WriteField(log, "OpenGL fragment shader", fsh);
190
191 string fsh2 = FragmentShader2();
192 if (!fsh2.empty())
193 WriteField(log, "OpenGL fragment shader 2", fsh2);
194 }
195
TestSubcase(Context & context,const char * name,SubcaseBase::SubcaseBasePtr (* factoryFunc)())196 TestSubcase::TestSubcase(Context& context, const char* name, SubcaseBase::SubcaseBasePtr (*factoryFunc)())
197 : TestCase(context, name, "")
198 , m_factoryFunc(factoryFunc)
199 , m_iterationCount(context.getTestContext().getCommandLine().getTestIterationCount())
200 {
201 if (!m_iterationCount)
202 m_iterationCount = 1;
203 }
204
~TestSubcase(void)205 TestSubcase::~TestSubcase(void)
206 {
207 }
208
init(void)209 void TestSubcase::init(void)
210 {
211 }
212
deinit(void)213 void TestSubcase::deinit(void)
214 {
215 }
216
iterate(void)217 TestSubcase::IterateResult TestSubcase::iterate(void)
218 {
219 current_context = &m_context;
220 using namespace std;
221 using tcu::TestLog;
222 TestLog& log = m_testCtx.getLog();
223
224 SubcaseBase::SubcaseBasePtr subcase = m_factoryFunc();
225 subcase->Documentation();
226 subcase->enableLogging(true);
227 //Run subcase
228 long subError = NO_ERROR;
229 // test case setup
230 try
231 {
232 subError = subcase->Setup();
233 if (subError == ERROR)
234 log.writeMessage("Test Setup() failed");
235 }
236 catch (const runtime_error& ex)
237 {
238 log.writeMessage(ex.what());
239 subError = ERROR;
240 }
241 catch (...)
242 {
243 log.writeMessage("Undefined exception.");
244 subError = ERROR;
245 }
246
247 // test case run
248 if (subError == NO_ERROR)
249 {
250 try
251 {
252 subError = subcase->Run();
253 if (subError == ERROR)
254 log.writeMessage("Test Run() failed");
255 }
256 catch (const runtime_error& ex)
257 {
258 log.writeMessage(ex.what());
259 subError = ERROR;
260 }
261 catch (...)
262 {
263 log.writeMessage("Undefined exception.");
264 subError = ERROR;
265 }
266 }
267
268 // test case cleanup
269 try
270 {
271 if (subcase->Cleanup() == ERROR)
272 {
273 subError = ERROR;
274 log.writeMessage("Test Cleanup() failed");
275 }
276 }
277 catch (const runtime_error& ex)
278 {
279 log.writeMessage(ex.what());
280 subError = ERROR;
281 }
282 catch (...)
283 {
284 log.writeMessage("Undefined exception.");
285 subError = ERROR;
286 }
287 subcase->enableLogging(false);
288
289 //check gl error state
290 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
291 glw::GLenum glError = gl.getError();
292 for (int i = 0; i < 100 && gl.getError(); ++i)
293 ;
294 if (glError != GL_NO_ERROR)
295 {
296 const char* name = glu::getErrorName(glError);
297 if (name == DE_NULL)
298 name = "UNKNOWN ERROR";
299 log << TestLog::Message << "After test execution glGetError() returned: " << name
300 << ", forcing FAIL for subcase" << TestLog::EndMessage;
301 subError = ERROR;
302 }
303
304 if (subError == ERROR)
305 {
306 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
307 return STOP;
308 }
309 else if (subError == NOT_SUPPORTED)
310 {
311 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported");
312 return STOP;
313 }
314 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
315
316 if (--m_iterationCount)
317 return CONTINUE;
318 else
319 return STOP;
320 }
321 }
322