547 lines
16 KiB
C++
547 lines
16 KiB
C++
#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);
|
|
|
|
void writeSessionInfo (std::string additionalInfo = "");
|
|
|
|
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 startTestsCasesTime (void);
|
|
void endTestsCasesTime (void);
|
|
|
|
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);
|
|
|
|
bool isShaderLoggingEnabled (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
|