You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
540 lines
16 KiB
540 lines
16 KiB
#ifndef _TCUTESTLOG_HPP |
|
#define _TCUTESTLOG_HPP |
|
/*------------------------------------------------------------------------- |
|
* drawElements Quality Program Tester Core |
|
* ---------------------------------------- |
|
* |
|
* Copyright 2014 The Android Open Source Project |
|
* |
|
* 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 Test Log C++ Wrapper. |
|
*//*--------------------------------------------------------------------*/ |
|
|
|
#include "tcuDefs.hpp" |
|
#include "qpTestLog.h" |
|
#include "tcuTexture.hpp" |
|
|
|
#include <sstream> |
|
|
|
namespace tcu |
|
{ |
|
|
|
class Surface; |
|
class MessageBuilder; |
|
class LogImageSet; |
|
class LogImage; |
|
class LogSection; |
|
class LogShaderProgram; |
|
class LogShader; |
|
class LogSpirVAssemblySource; |
|
class LogKernelSource; |
|
class LogSampleList; |
|
class LogValueInfo; |
|
class SampleBuilder; |
|
template<typename T> class LogNumber; |
|
|
|
/*--------------------------------------------------------------------*//*! |
|
* \brief Test log |
|
* |
|
* TestLog provides convinient C++ API for logging. The API has been designed |
|
* around stream operators much like STL iostream library. The following |
|
* examples demonstrate how to use TestLog. |
|
* |
|
* \code |
|
* TestLog& log = m_testCtx.getLog(); |
|
* |
|
* // Write message to log. |
|
* log << TestLog::Message << "Hello, World!" << TestLog::EndMessage; |
|
* int myNumber = 3; |
|
* log << TestLog::Message << "Diff is " << myNumber << TestLog::EndMessage; |
|
* |
|
* // Write image |
|
* Surface myImage(256, 256); |
|
* log << TestLog::Image("TestImage", "My test image", myImage); |
|
* |
|
* // Multiple commands can be combined: |
|
* log << TestLog::Section("Details", "Test case details") |
|
* << TestLog::Message << "Here be dragons" << TestLog::EndMessage |
|
* << TestLog::ImageSet("Result", "Result images") |
|
* << TestLog::Image("ImageA", "Image A", imageA) |
|
* << TestLog::Image("ImageB", "Image B", imageB) |
|
* << TestLog::EndImageSet << TestLog::EndSection; |
|
* \endcode |
|
*//*--------------------------------------------------------------------*/ |
|
class TestLog |
|
{ |
|
public: |
|
// Tokens |
|
static const class BeginMessageToken {} Message; |
|
static const class EndMessageToken {} EndMessage; |
|
static const class EndImageSetToken {} EndImageSet; |
|
static const class EndSectionToken {} EndSection; |
|
static const class EndShaderProgramToken {} EndShaderProgram; |
|
static const class SampleInfoToken {} SampleInfo; |
|
static const class EndSampleInfoToken {} EndSampleInfo; |
|
static const class BeginSampleToken {} Sample; |
|
static const class EndSampleToken {} EndSample; |
|
static const class EndSampleListToken {} EndSampleList; |
|
|
|
// Typedefs. |
|
typedef LogImageSet ImageSet; |
|
typedef LogImage Image; |
|
typedef LogSection Section; |
|
typedef LogShaderProgram ShaderProgram; |
|
typedef LogShader Shader; |
|
typedef LogSpirVAssemblySource SpirVAssemblySource; |
|
typedef LogKernelSource KernelSource; |
|
typedef LogSampleList SampleList; |
|
typedef LogValueInfo ValueInfo; |
|
typedef LogNumber<float> Float; |
|
typedef LogNumber<deInt64> Integer; |
|
|
|
explicit TestLog (const char* fileName, deUint32 flags = 0); |
|
~TestLog (void); |
|
|
|
MessageBuilder operator<< (const BeginMessageToken&); |
|
MessageBuilder message (void); |
|
|
|
TestLog& operator<< (const ImageSet& imageSet); |
|
TestLog& operator<< (const Image& image); |
|
TestLog& operator<< (const EndImageSetToken&); |
|
|
|
TestLog& operator<< (const Section& section); |
|
TestLog& operator<< (const EndSectionToken&); |
|
|
|
TestLog& operator<< (const ShaderProgram& shaderProgram); |
|
TestLog& operator<< (const EndShaderProgramToken&); |
|
TestLog& operator<< (const Shader& shader); |
|
TestLog& operator<< (const SpirVAssemblySource& module); |
|
|
|
TestLog& operator<< (const KernelSource& kernelSrc); |
|
|
|
template<typename T> |
|
TestLog& operator<< (const LogNumber<T>& number); |
|
|
|
TestLog& operator<< (const SampleList& sampleList); |
|
TestLog& operator<< (const SampleInfoToken&); |
|
TestLog& operator<< (const ValueInfo& valueInfo); |
|
TestLog& operator<< (const EndSampleInfoToken&); |
|
SampleBuilder operator<< (const BeginSampleToken&); |
|
TestLog& operator<< (const EndSampleListToken&); |
|
|
|
// Raw api |
|
void writeMessage (const char* message); |
|
|
|
void startImageSet (const char* name, const char* description); |
|
void endImageSet (void); |
|
void writeImage (const char* name, const char* description, const ConstPixelBufferAccess& surface, const Vec4& scale, const Vec4& bias, qpImageCompressionMode compressionMode = QP_IMAGE_COMPRESSION_MODE_BEST); |
|
void writeImage (const char* name, const char* description, qpImageCompressionMode compressionMode, qpImageFormat format, int width, int height, int stride, const void* data); |
|
|
|
void startSection (const char* name, const char* description); |
|
void endSection (void); |
|
|
|
void startShaderProgram (bool linkOk, const char* linkInfoLog); |
|
void endShaderProgram (void); |
|
void writeShader (qpShaderType type, const char* source, bool compileOk, const char* infoLog); |
|
void writeSpirVAssemblySource(const char* source); |
|
void writeKernelSource (const char* source); |
|
void writeCompileInfo (const char* name, const char* description, bool compileOk, const char* infoLog); |
|
|
|
void writeFloat (const char* name, const char* description, const char* unit, qpKeyValueTag tag, float value); |
|
void writeInteger (const char* name, const char* description, const char* unit, qpKeyValueTag tag, deInt64 value); |
|
|
|
void startEglConfigSet (const char* name, const char* description); |
|
void writeEglConfig (const qpEglConfigInfo* config); |
|
void endEglConfigSet (void); |
|
|
|
void startCase (const char* testCasePath, qpTestCaseType testCaseType); |
|
void endCase (qpTestResult result, const char* description); |
|
void terminateCase (qpTestResult result); |
|
|
|
void startSampleList (const std::string& name, const std::string& description); |
|
void startSampleInfo (void); |
|
void writeValueInfo (const std::string& name, const std::string& description, const std::string& unit, qpSampleValueTag tag); |
|
void endSampleInfo (void); |
|
void startSample (void); |
|
void writeSampleValue (double value); |
|
void writeSampleValue (deInt64 value); |
|
void endSample (void); |
|
void endSampleList (void); |
|
|
|
private: |
|
TestLog (const TestLog& other); // Not allowed! |
|
TestLog& operator= (const TestLog& other); // Not allowed! |
|
|
|
qpTestLog* m_log; |
|
}; |
|
|
|
class MessageBuilder |
|
{ |
|
public: |
|
explicit MessageBuilder (TestLog* log) : m_log(log) {} |
|
~MessageBuilder (void) {} |
|
|
|
std::string toString (void) const { return m_str.str(); } |
|
|
|
TestLog& operator<< (const TestLog::EndMessageToken&); |
|
|
|
template <typename T> |
|
MessageBuilder& operator<< (const T& value); |
|
|
|
MessageBuilder (const MessageBuilder& other); |
|
MessageBuilder& operator= (const MessageBuilder& other); |
|
|
|
private: |
|
TestLog* m_log; |
|
std::ostringstream m_str; |
|
}; |
|
|
|
class SampleBuilder |
|
{ |
|
public: |
|
SampleBuilder (TestLog* log) : m_log(log) {} |
|
|
|
SampleBuilder& operator<< (int v) { m_values.push_back(Value((deInt64)v)); return *this; } |
|
SampleBuilder& operator<< (deInt64 v) { m_values.push_back(Value(v)); return *this; } |
|
SampleBuilder& operator<< (float v) { m_values.push_back(Value((double)v)); return *this; } |
|
SampleBuilder& operator<< (double v) { m_values.push_back(Value(v)); return *this; } |
|
|
|
TestLog& operator<< (const TestLog::EndSampleToken&); |
|
|
|
private: |
|
struct Value |
|
{ |
|
enum Type { TYPE_INT64 = 0, TYPE_FLOAT64, TYPE_LAST }; |
|
|
|
Type type; |
|
union |
|
{ |
|
deInt64 int64; |
|
double float64; |
|
} value; |
|
|
|
Value (void) : type(TYPE_LAST) { value.int64 = 0; } |
|
Value (double v) : type(TYPE_FLOAT64) { value.float64 = v; } |
|
Value (deInt64 v) : type(TYPE_INT64) { value.int64 = v; } |
|
}; |
|
|
|
TestLog* m_log; |
|
std::vector<Value> m_values; |
|
}; |
|
|
|
class LogImageSet |
|
{ |
|
public: |
|
LogImageSet (const std::string& name, const std::string& description) |
|
: m_name (name) |
|
, m_description (description) |
|
{ |
|
} |
|
|
|
void write (TestLog& log) const; |
|
|
|
private: |
|
std::string m_name; |
|
std::string m_description; |
|
}; |
|
|
|
// \note Doesn't take copy of surface contents |
|
class LogImage |
|
{ |
|
public: |
|
LogImage (const std::string& name, const std::string& description, const Surface& surface, qpImageCompressionMode compression = QP_IMAGE_COMPRESSION_MODE_BEST); |
|
|
|
LogImage (const std::string& name, const std::string& description, const ConstPixelBufferAccess& access, qpImageCompressionMode compression = QP_IMAGE_COMPRESSION_MODE_BEST); |
|
|
|
LogImage (const std::string& name, const std::string& description, const ConstPixelBufferAccess& access, const Vec4& scale, const Vec4& bias, qpImageCompressionMode compression = QP_IMAGE_COMPRESSION_MODE_BEST); |
|
|
|
void write (TestLog& log) const; |
|
|
|
private: |
|
std::string m_name; |
|
std::string m_description; |
|
ConstPixelBufferAccess m_access; |
|
Vec4 m_scale; |
|
Vec4 m_bias; |
|
qpImageCompressionMode m_compression; |
|
}; |
|
|
|
class LogSection |
|
{ |
|
public: |
|
LogSection (const std::string& name, const std::string& description) |
|
: m_name (name) |
|
, m_description (description) |
|
{ |
|
} |
|
|
|
void write (TestLog& log) const; |
|
|
|
private: |
|
std::string m_name; |
|
std::string m_description; |
|
}; |
|
|
|
class LogShaderProgram |
|
{ |
|
public: |
|
LogShaderProgram (bool linkOk, const std::string& linkInfoLog) |
|
: m_linkOk (linkOk) |
|
, m_linkInfoLog (linkInfoLog) |
|
{ |
|
} |
|
|
|
void write (TestLog& log) const; |
|
|
|
private: |
|
bool m_linkOk; |
|
std::string m_linkInfoLog; |
|
}; |
|
|
|
class LogShader |
|
{ |
|
public: |
|
LogShader (qpShaderType type, const std::string& source, bool compileOk, const std::string& infoLog) |
|
: m_type (type) |
|
, m_source (source) |
|
, m_compileOk (compileOk) |
|
, m_infoLog (infoLog) |
|
{ |
|
} |
|
|
|
void write (TestLog& log) const; |
|
|
|
private: |
|
qpShaderType m_type; |
|
std::string m_source; |
|
bool m_compileOk; |
|
std::string m_infoLog; |
|
}; |
|
|
|
class LogSpirVAssemblySource |
|
{ |
|
public: |
|
LogSpirVAssemblySource (const std::string& source) |
|
: m_source (source) |
|
{ |
|
} |
|
|
|
void write (TestLog& log) const; |
|
|
|
private: |
|
std::string m_source; |
|
}; |
|
|
|
class LogKernelSource |
|
{ |
|
public: |
|
explicit LogKernelSource (const std::string& source) |
|
: m_source(source) |
|
{ |
|
} |
|
|
|
void write (TestLog& log) const; |
|
|
|
private: |
|
std::string m_source; |
|
}; |
|
|
|
class LogSampleList |
|
{ |
|
public: |
|
LogSampleList (const std::string& name, const std::string& description) |
|
: m_name (name) |
|
, m_description (description) |
|
{ |
|
} |
|
|
|
void write (TestLog& log) const; |
|
|
|
private: |
|
std::string m_name; |
|
std::string m_description; |
|
}; |
|
|
|
class LogValueInfo |
|
{ |
|
public: |
|
LogValueInfo (const std::string& name, const std::string& description, const std::string& unit, qpSampleValueTag tag) |
|
: m_name (name) |
|
, m_description (description) |
|
, m_unit (unit) |
|
, m_tag (tag) |
|
{ |
|
} |
|
|
|
void write (TestLog& log) const; |
|
|
|
private: |
|
std::string m_name; |
|
std::string m_description; |
|
std::string m_unit; |
|
qpSampleValueTag m_tag; |
|
}; |
|
|
|
template<typename T> |
|
class LogNumber |
|
{ |
|
public: |
|
LogNumber (const std::string& name, const std::string& desc, const std::string& unit, qpKeyValueTag tag, T value) |
|
: m_name (name) |
|
, m_desc (desc) |
|
, m_unit (unit) |
|
, m_tag (tag) |
|
, m_value (value) |
|
{ |
|
} |
|
|
|
void write (TestLog& log) const; |
|
|
|
private: |
|
std::string m_name; |
|
std::string m_desc; |
|
std::string m_unit; |
|
qpKeyValueTag m_tag; |
|
T m_value; |
|
}; |
|
|
|
// Section helper that closes section when leaving scope. |
|
class ScopedLogSection |
|
{ |
|
public: |
|
ScopedLogSection (TestLog& log, const std::string& name, const std::string& description) |
|
: m_log(log) |
|
{ |
|
m_log << TestLog::Section(name, description); |
|
} |
|
|
|
~ScopedLogSection (void) |
|
{ |
|
m_log << TestLog::EndSection; |
|
} |
|
|
|
private: |
|
TestLog& m_log; |
|
}; |
|
|
|
// TestLog stream operators. |
|
|
|
inline TestLog& TestLog::operator<< (const ImageSet& imageSet) { imageSet.write(*this); return *this; } |
|
inline TestLog& TestLog::operator<< (const Image& image) { image.write(*this); return *this; } |
|
inline TestLog& TestLog::operator<< (const EndImageSetToken&) { endImageSet(); return *this; } |
|
inline TestLog& TestLog::operator<< (const Section& section) { section.write(*this); return *this; } |
|
inline TestLog& TestLog::operator<< (const EndSectionToken&) { endSection(); return *this; } |
|
inline TestLog& TestLog::operator<< (const ShaderProgram& shaderProg) { shaderProg.write(*this); return *this; } |
|
inline TestLog& TestLog::operator<< (const EndShaderProgramToken&) { endShaderProgram(); return *this; } |
|
inline TestLog& TestLog::operator<< (const Shader& shader) { shader.write(*this); return *this; } |
|
inline TestLog& TestLog::operator<< (const SpirVAssemblySource& module) { module.write(*this); return *this; } |
|
inline TestLog& TestLog::operator<< (const KernelSource& kernelSrc) { kernelSrc.write(*this); return *this; } |
|
inline TestLog& TestLog::operator<< (const SampleList& sampleList) { sampleList.write(*this); return *this; } |
|
inline TestLog& TestLog::operator<< (const SampleInfoToken&) { startSampleInfo(); return *this; } |
|
inline TestLog& TestLog::operator<< (const ValueInfo& valueInfo) { valueInfo.write(*this); return *this; } |
|
inline TestLog& TestLog::operator<< (const EndSampleInfoToken&) { endSampleInfo(); return *this; } |
|
inline TestLog& TestLog::operator<< (const EndSampleListToken&) { endSampleList(); return *this; } |
|
|
|
template<typename T> |
|
inline TestLog& TestLog::operator<< (const LogNumber<T>& number) |
|
{ |
|
number.write(*this); |
|
return *this; |
|
} |
|
|
|
inline TestLog& operator<< (TestLog& log, const std::exception& e) |
|
{ |
|
// \todo [2012-10-18 pyry] Print type info? |
|
return log << TestLog::Message << e.what() << TestLog::EndMessage; |
|
} |
|
|
|
// Utility class inline implementations. |
|
|
|
template <typename T> |
|
inline MessageBuilder& MessageBuilder::operator<< (const T& value) |
|
{ |
|
// Overload stream operator to implement custom format |
|
m_str << value; |
|
return *this; |
|
} |
|
|
|
inline MessageBuilder TestLog::operator<< (const BeginMessageToken&) |
|
{ |
|
return MessageBuilder(this); |
|
} |
|
|
|
inline MessageBuilder TestLog::message (void) |
|
{ |
|
return MessageBuilder(this); |
|
} |
|
|
|
inline SampleBuilder TestLog::operator<< (const BeginSampleToken&) |
|
{ |
|
return SampleBuilder(this); |
|
} |
|
|
|
inline void LogImageSet::write (TestLog& log) const |
|
{ |
|
log.startImageSet(m_name.c_str(), m_description.c_str()); |
|
} |
|
|
|
inline void LogSection::write (TestLog& log) const |
|
{ |
|
log.startSection(m_name.c_str(), m_description.c_str()); |
|
} |
|
|
|
inline void LogShaderProgram::write (TestLog& log) const |
|
{ |
|
log.startShaderProgram(m_linkOk, m_linkInfoLog.c_str()); |
|
} |
|
|
|
inline void LogShader::write (TestLog& log) const |
|
{ |
|
log.writeShader(m_type, m_source.c_str(), m_compileOk, m_infoLog.c_str()); |
|
} |
|
|
|
inline void LogSpirVAssemblySource::write (TestLog& log) const |
|
{ |
|
log.writeSpirVAssemblySource(m_source.c_str()); |
|
} |
|
|
|
inline void LogKernelSource::write (TestLog& log) const |
|
{ |
|
log.writeKernelSource(m_source.c_str()); |
|
} |
|
|
|
inline void LogSampleList::write (TestLog& log) const |
|
{ |
|
log.startSampleList(m_name, m_description); |
|
} |
|
|
|
inline void LogValueInfo::write (TestLog& log) const |
|
{ |
|
log.writeValueInfo(m_name, m_description, m_unit, m_tag); |
|
} |
|
|
|
template<> |
|
inline void LogNumber<float>::write (TestLog& log) const |
|
{ |
|
log.writeFloat(m_name.c_str(), m_desc.c_str(), m_unit.c_str(), m_tag, m_value); |
|
} |
|
|
|
template<> |
|
inline void LogNumber<deInt64>::write (TestLog& log) const |
|
{ |
|
log.writeInteger(m_name.c_str(), m_desc.c_str(), m_unit.c_str(), m_tag, m_value); |
|
} |
|
|
|
} // tcu |
|
|
|
#endif // _TCUTESTLOG_HPP
|
|
|