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 38 GLWrapper::GLWrapper() 39 : CallLogWrapper(current_context->getRenderContext().getFunctions(), current_context->getTestContext().getLog()) 40 , m_context(*current_context) 41 { 42 } 43 44 SubcaseBase::SubcaseBase() 45 { 46 } 47 48 SubcaseBase::~SubcaseBase() 49 { 50 } 51 52 long SubcaseBase::Setup() 53 { 54 return NO_ERROR; 55 } 56 57 long SubcaseBase::Cleanup() 58 { 59 return NO_ERROR; 60 } 61 62 std::string SubcaseBase::VertexShader() 63 { 64 return ""; 65 } 66 67 std::string SubcaseBase::VertexShader2() 68 { 69 return ""; 70 } 71 72 std::string SubcaseBase::TessControlShader() 73 { 74 return ""; 75 } 76 77 std::string SubcaseBase::TessControlShader2() 78 { 79 return ""; 80 } 81 82 std::string SubcaseBase::TessEvalShader() 83 { 84 return ""; 85 } 86 87 std::string SubcaseBase::TessEvalShader2() 88 { 89 return ""; 90 } 91 92 std::string SubcaseBase::GeometryShader() 93 { 94 return ""; 95 } 96 97 std::string SubcaseBase::GeometryShader2() 98 { 99 return ""; 100 } 101 102 std::string SubcaseBase::FragmentShader() 103 { 104 return ""; 105 } 106 107 std::string SubcaseBase::FragmentShader2() 108 { 109 return ""; 110 } 111 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 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 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 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 205 TestSubcase::~TestSubcase(void) 206 { 207 } 208 209 void TestSubcase::init(void) 210 { 211 } 212 213 void TestSubcase::deinit(void) 214 { 215 } 216 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