/*------------------------------------------------------------------------- * OpenGL Conformance Test Suite * ----------------------------- * * Copyright (c) 2014-2016 The Khronos Group Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ /*! * \file * \brief */ /*-------------------------------------------------------------------*/ #include "glcTestSubcase.hpp" #include "glwEnums.hpp" #include "glwFunctions.hpp" #include "tcuCommandLine.hpp" #include "tcuTestLog.hpp" namespace deqp { namespace { static Context* current_context; } GLWrapper::GLWrapper() : CallLogWrapper(current_context->getRenderContext().getFunctions(), current_context->getTestContext().getLog()) , m_context(*current_context) { } SubcaseBase::SubcaseBase() { } SubcaseBase::~SubcaseBase() { } long SubcaseBase::Setup() { return NO_ERROR; } long SubcaseBase::Cleanup() { return NO_ERROR; } std::string SubcaseBase::VertexShader() { return ""; } std::string SubcaseBase::VertexShader2() { return ""; } std::string SubcaseBase::TessControlShader() { return ""; } std::string SubcaseBase::TessControlShader2() { return ""; } std::string SubcaseBase::TessEvalShader() { return ""; } std::string SubcaseBase::TessEvalShader2() { return ""; } std::string SubcaseBase::GeometryShader() { return ""; } std::string SubcaseBase::GeometryShader2() { return ""; } std::string SubcaseBase::FragmentShader() { return ""; } std::string SubcaseBase::FragmentShader2() { return ""; } void WriteField(tcu::TestLog& log, const char* title, std::string message) { if (message == "") return; using namespace std; using tcu::TestLog; istringstream tokens(message); string line; log.startSection("Details", title); while (getline(tokens, line)) { log.writeMessage(line.c_str()); } log.endSection(); } void SubcaseBase::OutputNotSupported(std::string reason) { using tcu::TestLog; TestLog& log = m_context.getTestContext().getLog(); std::string msg = reason + ", test will not run."; std::istringstream tokens(msg); std::string line; log.startSection("Not supported", "Reason"); while (getline(tokens, line)) { log.writeMessage(line.c_str()); } log.endSection(); } void SubcaseBase::Documentation() { using namespace std; using tcu::TestLog; TestLog& log = m_context.getTestContext().getLog(); WriteField(log, "Title", Title()); WriteField(log, "Purpose", Purpose()); WriteField(log, "Method", Method()); WriteField(log, "Pass Criteria", PassCriteria()); //OpenGL fields string vsh = VertexShader(); if (!vsh.empty()) WriteField(log, "OpenGL vertex shader", vsh); string vsh2 = VertexShader2(); if (!vsh2.empty()) WriteField(log, "OpenGL vertex shader 2", vsh2); string tcsh = TessControlShader(); if (!tcsh.empty()) WriteField(log, "OpenGL tessellation control shader", tcsh); string tcsh2 = TessControlShader(); if (!tcsh2.empty()) WriteField(log, "OpenGL tessellation control shader 2", tcsh2); string tesh = TessControlShader(); if (!tesh.empty()) WriteField(log, "OpenGL tessellation evaluation shader", tesh); string tesh2 = TessControlShader(); if (!tesh2.empty()) WriteField(log, "OpenGL tessellation evaluation shader 2", tesh2); string gsh = GeometryShader(); if (!gsh.empty()) WriteField(log, "OpenGL geometry shader", gsh); string gsh2 = GeometryShader2(); if (!gsh2.empty()) WriteField(log, "OpenGL geometry shader 2", gsh2); string fsh = FragmentShader(); if (!fsh.empty()) WriteField(log, "OpenGL fragment shader", fsh); string fsh2 = FragmentShader2(); if (!fsh2.empty()) WriteField(log, "OpenGL fragment shader 2", fsh2); } TestSubcase::TestSubcase(Context& context, const char* name, SubcaseBase::SubcaseBasePtr (*factoryFunc)()) : TestCase(context, name, "") , m_factoryFunc(factoryFunc) , m_iterationCount(context.getTestContext().getCommandLine().getTestIterationCount()) { if (!m_iterationCount) m_iterationCount = 1; } TestSubcase::~TestSubcase(void) { } void TestSubcase::init(void) { } void TestSubcase::deinit(void) { } TestSubcase::IterateResult TestSubcase::iterate(void) { current_context = &m_context; using namespace std; using tcu::TestLog; TestLog& log = m_testCtx.getLog(); SubcaseBase::SubcaseBasePtr subcase = m_factoryFunc(); subcase->Documentation(); subcase->enableLogging(true); //Run subcase long subError = NO_ERROR; // test case setup try { subError = subcase->Setup(); if (subError == ERROR) log.writeMessage("Test Setup() failed"); } catch (const runtime_error& ex) { log.writeMessage(ex.what()); subError = ERROR; } catch (...) { log.writeMessage("Undefined exception."); subError = ERROR; } // test case run if (subError == NO_ERROR) { try { subError = subcase->Run(); if (subError == ERROR) log.writeMessage("Test Run() failed"); } catch (const runtime_error& ex) { log.writeMessage(ex.what()); subError = ERROR; } catch (...) { log.writeMessage("Undefined exception."); subError = ERROR; } } // test case cleanup try { if (subcase->Cleanup() == ERROR) { subError = ERROR; log.writeMessage("Test Cleanup() failed"); } } catch (const runtime_error& ex) { log.writeMessage(ex.what()); subError = ERROR; } catch (...) { log.writeMessage("Undefined exception."); subError = ERROR; } subcase->enableLogging(false); //check gl error state const glw::Functions& gl = m_context.getRenderContext().getFunctions(); glw::GLenum glError = gl.getError(); for (int i = 0; i < 100 && gl.getError(); ++i) ; if (glError != GL_NO_ERROR) { const char* name = glu::getErrorName(glError); if (name == DE_NULL) name = "UNKNOWN ERROR"; log << TestLog::Message << "After test execution glGetError() returned: " << name << ", forcing FAIL for subcase" << TestLog::EndMessage; subError = ERROR; } if (subError == ERROR) { m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); return STOP; } else if (subError == NOT_SUPPORTED) { m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported"); return STOP; } m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); if (--m_iterationCount) return CONTINUE; else return STOP; } }