Merge upstream-vulkan-cts-1.0-dev into master
[platform/upstream/VK-GL-CTS.git] / framework / common / tcuTestLog.hpp
1 #ifndef _TCUTESTLOG_HPP
2 #define _TCUTESTLOG_HPP
3 /*-------------------------------------------------------------------------
4  * drawElements Quality Program Tester Core
5  * ----------------------------------------
6  *
7  * Copyright 2014 The Android Open Source Project
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Test Log C++ Wrapper.
24  *//*--------------------------------------------------------------------*/
25
26 #include "tcuDefs.hpp"
27 #include "qpTestLog.h"
28 #include "tcuTexture.hpp"
29
30 #include <sstream>
31
32 namespace tcu
33 {
34
35 class Surface;
36 class MessageBuilder;
37 class LogImageSet;
38 class LogImage;
39 class LogSection;
40 class LogShaderProgram;
41 class LogShader;
42 class LogSpirVAssemblySource;
43 class LogKernelSource;
44 class LogSampleList;
45 class LogValueInfo;
46 class SampleBuilder;
47 template<typename T> class LogNumber;
48
49 /*--------------------------------------------------------------------*//*!
50  * \brief Test log
51  *
52  * TestLog provides convinient C++ API for logging. The API has been designed
53  * around stream operators much like STL iostream library. The following
54  * examples demonstrate how to use TestLog.
55  *
56  * \code
57  * TestLog& log = m_testCtx.getLog();
58  *
59  * // Write message to log.
60  * log << TestLog::Message << "Hello, World!" << TestLog::EndMessage;
61  * int myNumber = 3;
62  * log << TestLog::Message << "Diff is " << myNumber << TestLog::EndMessage;
63  *
64  * // Write image
65  * Surface myImage(256, 256);
66  * log << TestLog::Image("TestImage", "My test image", myImage);
67  *
68  * // Multiple commands can be combined:
69  * log << TestLog::Section("Details", "Test case details")
70  *     << TestLog::Message << "Here be dragons" << TestLog::EndMessage
71  *     << TestLog::ImageSet("Result", "Result images")
72  *     << TestLog::Image("ImageA", "Image A", imageA)
73  *     << TestLog::Image("ImageB", "Image B", imageB)
74  *     << TestLog::EndImageSet << TestLog::EndSection;
75  * \endcode
76  *//*--------------------------------------------------------------------*/
77 class TestLog
78 {
79 public:
80         // Tokens
81         static const class BeginMessageToken {}                 Message;
82         static const class EndMessageToken {}                   EndMessage;
83         static const class EndImageSetToken {}                  EndImageSet;
84         static const class EndSectionToken {}                   EndSection;
85         static const class EndShaderProgramToken {}             EndShaderProgram;
86         static const class SampleInfoToken {}                   SampleInfo;
87         static const class EndSampleInfoToken {}                EndSampleInfo;
88         static const class BeginSampleToken {}                  Sample;
89         static const class EndSampleToken {}                    EndSample;
90         static const class EndSampleListToken {}                EndSampleList;
91
92         // Typedefs.
93         typedef LogImageSet                             ImageSet;
94         typedef LogImage                                Image;
95         typedef LogSection                              Section;
96         typedef LogShaderProgram                ShaderProgram;
97         typedef LogShader                               Shader;
98         typedef LogSpirVAssemblySource  SpirVAssemblySource;
99         typedef LogKernelSource                 KernelSource;
100         typedef LogSampleList                   SampleList;
101         typedef LogValueInfo                    ValueInfo;
102         typedef LogNumber<float>                Float;
103         typedef LogNumber<deInt64>              Integer;
104
105         explicit                        TestLog                                 (const char* fileName, deUint32 flags = 0);
106                                                 ~TestLog                                (void);
107
108         MessageBuilder          operator<<                              (const BeginMessageToken&);
109         MessageBuilder          message                                 (void);
110
111         TestLog&                        operator<<                              (const ImageSet& imageSet);
112         TestLog&                        operator<<                              (const Image& image);
113         TestLog&                        operator<<                              (const EndImageSetToken&);
114
115         TestLog&                        operator<<                              (const Section& section);
116         TestLog&                        operator<<                              (const EndSectionToken&);
117
118         TestLog&                        operator<<                              (const ShaderProgram& shaderProgram);
119         TestLog&                        operator<<                              (const EndShaderProgramToken&);
120         TestLog&                        operator<<                              (const Shader& shader);
121         TestLog&                        operator<<                              (const SpirVAssemblySource& module);
122
123         TestLog&                        operator<<                              (const KernelSource& kernelSrc);
124
125         template<typename T>
126         TestLog&                        operator<<                              (const LogNumber<T>& number);
127
128         TestLog&                        operator<<                              (const SampleList& sampleList);
129         TestLog&                        operator<<                              (const SampleInfoToken&);
130         TestLog&                        operator<<                              (const ValueInfo& valueInfo);
131         TestLog&                        operator<<                              (const EndSampleInfoToken&);
132         SampleBuilder           operator<<                              (const BeginSampleToken&);
133         TestLog&                        operator<<                              (const EndSampleListToken&);
134
135         // Raw api
136         void                            writeMessage                    (const char* message);
137
138         void                            startImageSet                   (const char* name, const char* description);
139         void                            endImageSet                             (void);
140         void                            writeImage                              (const char* name, const char* description, const ConstPixelBufferAccess& surface, const Vec4& scale, const Vec4& bias, qpImageCompressionMode compressionMode = QP_IMAGE_COMPRESSION_MODE_BEST);
141         void                            writeImage                              (const char* name, const char* description, qpImageCompressionMode compressionMode, qpImageFormat format, int width, int height, int stride, const void* data);
142
143         void                            startSection                    (const char* name, const char* description);
144         void                            endSection                              (void);
145
146         void                            startShaderProgram              (bool linkOk, const char* linkInfoLog);
147         void                            endShaderProgram                (void);
148         void                            writeShader                             (qpShaderType type, const char* source, bool compileOk, const char* infoLog);
149         void                            writeSpirVAssemblySource(const char* source);
150         void                            writeKernelSource               (const char* source);
151         void                            writeCompileInfo                (const char* name, const char* description, bool compileOk, const char* infoLog);
152
153         void                            writeFloat                              (const char* name, const char* description, const char* unit, qpKeyValueTag tag, float value);
154         void                            writeInteger                    (const char* name, const char* description, const char* unit, qpKeyValueTag tag, deInt64 value);
155
156         void                            startEglConfigSet               (const char* name, const char* description);
157         void                            writeEglConfig                  (const qpEglConfigInfo* config);
158         void                            endEglConfigSet                 (void);
159
160         void                            startCase                               (const char* testCasePath, qpTestCaseType testCaseType);
161         void                            endCase                                 (qpTestResult result, const char* description);
162         void                            terminateCase                   (qpTestResult result);
163
164         void                            startSampleList                 (const std::string& name, const std::string& description);
165         void                            startSampleInfo                 (void);
166         void                            writeValueInfo                  (const std::string& name, const std::string& description, const std::string& unit, qpSampleValueTag tag);
167         void                            endSampleInfo                   (void);
168         void                            startSample                             (void);
169         void                            writeSampleValue                (double value);
170         void                            writeSampleValue                (deInt64 value);
171         void                            endSample                               (void);
172         void                            endSampleList                   (void);
173
174 private:
175                                                 TestLog                                 (const TestLog& other); // Not allowed!
176         TestLog&                        operator=                               (const TestLog& other); // Not allowed!
177
178         qpTestLog*                      m_log;
179 };
180
181 class MessageBuilder
182 {
183 public:
184         explicit                                MessageBuilder          (TestLog* log) : m_log(log) {}
185                                                         ~MessageBuilder         (void) {}
186
187         std::string                             toString                        (void) const { return m_str.str(); }
188
189         TestLog&                                operator<<                      (const TestLog::EndMessageToken&);
190
191         template <typename T>
192         MessageBuilder&                 operator<<                      (const T& value);
193
194                                                         MessageBuilder          (const MessageBuilder& other);
195         MessageBuilder&                 operator=                       (const MessageBuilder& other);
196
197 private:
198         TestLog*                                m_log;
199         std::ostringstream              m_str;
200 };
201
202 class SampleBuilder
203 {
204 public:
205                                                         SampleBuilder           (TestLog* log) : m_log(log) {}
206
207         SampleBuilder&                  operator<<                      (int v)         { m_values.push_back(Value((deInt64)v));        return *this; }
208         SampleBuilder&                  operator<<                      (deInt64 v)     { m_values.push_back(Value(v));                         return *this; }
209         SampleBuilder&                  operator<<                      (float v)       { m_values.push_back(Value((double)v));         return *this; }
210         SampleBuilder&                  operator<<                      (double v)      { m_values.push_back(Value(v));                         return *this; }
211
212         TestLog&                                operator<<                      (const TestLog::EndSampleToken&);
213
214 private:
215         struct Value
216         {
217                 enum Type { TYPE_INT64 = 0, TYPE_FLOAT64, TYPE_LAST };
218
219                 Type    type;
220                 union
221                 {
222                         deInt64         int64;
223                         double          float64;
224                 } value;
225
226                 Value (void)            : type(TYPE_LAST)               { value.int64 = 0;              }
227                 Value (double v)        : type(TYPE_FLOAT64)    { value.float64 = v;    }
228                 Value (deInt64 v)       : type(TYPE_INT64)              { value.int64 = v;              }
229         };
230
231         TestLog*                                m_log;
232         std::vector<Value>              m_values;
233 };
234
235 class LogImageSet
236 {
237 public:
238         LogImageSet (const std::string& name, const std::string& description)
239                 : m_name                (name)
240                 , m_description (description)
241         {
242         }
243
244         void write (TestLog& log) const;
245
246 private:
247         std::string             m_name;
248         std::string             m_description;
249 };
250
251 // \note Doesn't take copy of surface contents
252 class LogImage
253 {
254 public:
255         LogImage (const std::string& name, const std::string& description, const Surface& surface, qpImageCompressionMode compression = QP_IMAGE_COMPRESSION_MODE_BEST);
256
257         LogImage (const std::string& name, const std::string& description, const ConstPixelBufferAccess& access, qpImageCompressionMode compression = QP_IMAGE_COMPRESSION_MODE_BEST);
258
259         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);
260
261         void write (TestLog& log) const;
262
263 private:
264         std::string                             m_name;
265         std::string                             m_description;
266         ConstPixelBufferAccess  m_access;
267         Vec4                                    m_scale;
268         Vec4                                    m_bias;
269         qpImageCompressionMode  m_compression;
270 };
271
272 class LogSection
273 {
274 public:
275         LogSection (const std::string& name, const std::string& description)
276                 : m_name                (name)
277                 , m_description (description)
278         {
279         }
280
281         void write (TestLog& log) const;
282
283 private:
284         std::string             m_name;
285         std::string             m_description;
286 };
287
288 class LogShaderProgram
289 {
290 public:
291         LogShaderProgram (bool linkOk, const std::string& linkInfoLog)
292                 : m_linkOk              (linkOk)
293                 , m_linkInfoLog (linkInfoLog)
294         {
295         }
296
297         void write (TestLog& log) const;
298
299 private:
300         bool                    m_linkOk;
301         std::string             m_linkInfoLog;
302 };
303
304 class LogShader
305 {
306 public:
307         LogShader (qpShaderType type, const std::string& source, bool compileOk, const std::string& infoLog)
308                 : m_type                (type)
309                 , m_source              (source)
310                 , m_compileOk   (compileOk)
311                 , m_infoLog             (infoLog)
312         {
313         }
314
315         void write (TestLog& log) const;
316
317 private:
318         qpShaderType    m_type;
319         std::string             m_source;
320         bool                    m_compileOk;
321         std::string             m_infoLog;
322 };
323
324 class LogSpirVAssemblySource
325 {
326 public:
327         LogSpirVAssemblySource (const std::string& source)
328                 : m_source              (source)
329         {
330         }
331
332         void write (TestLog& log) const;
333
334 private:
335         std::string             m_source;
336 };
337
338 class LogKernelSource
339 {
340 public:
341         explicit LogKernelSource (const std::string& source)
342                 : m_source(source)
343         {
344         }
345
346         void write (TestLog& log) const;
347
348 private:
349         std::string     m_source;
350 };
351
352 class LogSampleList
353 {
354 public:
355         LogSampleList (const std::string& name, const std::string& description)
356                 : m_name                (name)
357                 , m_description (description)
358         {
359         }
360
361         void write (TestLog& log) const;
362
363 private:
364         std::string             m_name;
365         std::string             m_description;
366 };
367
368 class LogValueInfo
369 {
370 public:
371         LogValueInfo (const std::string& name, const std::string& description, const std::string& unit, qpSampleValueTag tag)
372                 : m_name                (name)
373                 , m_description (description)
374                 , m_unit                (unit)
375                 , m_tag                 (tag)
376         {
377         }
378
379         void write (TestLog& log) const;
380
381 private:
382         std::string                     m_name;
383         std::string                     m_description;
384         std::string                     m_unit;
385         qpSampleValueTag        m_tag;
386 };
387
388 template<typename T>
389 class LogNumber
390 {
391 public:
392         LogNumber (const std::string& name, const std::string& desc, const std::string& unit, qpKeyValueTag tag, T value)
393                 : m_name        (name)
394                 , m_desc        (desc)
395                 , m_unit        (unit)
396                 , m_tag         (tag)
397                 , m_value       (value)
398         {
399         }
400
401         void write (TestLog& log) const;
402
403 private:
404         std::string             m_name;
405         std::string             m_desc;
406         std::string             m_unit;
407         qpKeyValueTag   m_tag;
408         T                               m_value;
409 };
410
411 // Section helper that closes section when leaving scope.
412 class ScopedLogSection
413 {
414 public:
415         ScopedLogSection (TestLog& log, const std::string& name, const std::string& description)
416                 : m_log(log)
417         {
418                 m_log << TestLog::Section(name, description);
419         }
420
421         ~ScopedLogSection (void)
422         {
423                 m_log << TestLog::EndSection;
424         }
425
426 private:
427         TestLog& m_log;
428 };
429
430 // TestLog stream operators.
431
432 inline TestLog& TestLog::operator<< (const ImageSet& imageSet)                  { imageSet.write(*this);        return *this;   }
433 inline TestLog& TestLog::operator<< (const Image& image)                                { image.write(*this);           return *this;   }
434 inline TestLog& TestLog::operator<< (const EndImageSetToken&)                   { endImageSet();                        return *this;   }
435 inline TestLog& TestLog::operator<< (const Section& section)                    { section.write(*this);         return *this;   }
436 inline TestLog& TestLog::operator<< (const EndSectionToken&)                    { endSection();                         return *this;   }
437 inline TestLog& TestLog::operator<< (const ShaderProgram& shaderProg)   { shaderProg.write(*this);      return *this;   }
438 inline TestLog& TestLog::operator<< (const EndShaderProgramToken&)              { endShaderProgram();           return *this;   }
439 inline TestLog& TestLog::operator<< (const Shader& shader)                              { shader.write(*this);          return *this;   }
440 inline TestLog& TestLog::operator<< (const SpirVAssemblySource& module) { module.write(*this);          return *this;   }
441 inline TestLog& TestLog::operator<< (const KernelSource& kernelSrc)             { kernelSrc.write(*this);       return *this;   }
442 inline TestLog& TestLog::operator<<     (const SampleList& sampleList)          { sampleList.write(*this);      return *this;   }
443 inline TestLog& TestLog::operator<<     (const SampleInfoToken&)                        { startSampleInfo();            return *this;   }
444 inline TestLog& TestLog::operator<<     (const ValueInfo& valueInfo)            { valueInfo.write(*this);       return *this;   }
445 inline TestLog& TestLog::operator<<     (const EndSampleInfoToken&)                     { endSampleInfo();                      return *this;   }
446 inline TestLog& TestLog::operator<<     (const EndSampleListToken&)                     { endSampleList();                      return *this;   }
447
448 template<typename T>
449 inline TestLog& TestLog::operator<< (const LogNumber<T>& number)
450 {
451         number.write(*this);
452         return *this;
453 }
454
455 inline TestLog& operator<< (TestLog& log, const std::exception& e)
456 {
457         // \todo [2012-10-18 pyry] Print type info?
458         return log << TestLog::Message << e.what() << TestLog::EndMessage;
459 }
460
461 // Utility class inline implementations.
462
463 template <typename T>
464 inline MessageBuilder& MessageBuilder::operator<< (const T& value)
465 {
466         // Overload stream operator to implement custom format
467         m_str << value;
468         return *this;
469 }
470
471 inline MessageBuilder TestLog::operator<< (const BeginMessageToken&)
472 {
473         return MessageBuilder(this);
474 }
475
476 inline MessageBuilder TestLog::message (void)
477 {
478         return MessageBuilder(this);
479 }
480
481 inline SampleBuilder TestLog::operator<< (const BeginSampleToken&)
482 {
483         return SampleBuilder(this);
484 }
485
486 inline void LogImageSet::write (TestLog& log) const
487 {
488         log.startImageSet(m_name.c_str(), m_description.c_str());
489 }
490
491 inline void LogSection::write (TestLog& log) const
492 {
493         log.startSection(m_name.c_str(), m_description.c_str());
494 }
495
496 inline void LogShaderProgram::write (TestLog& log) const
497 {
498         log.startShaderProgram(m_linkOk, m_linkInfoLog.c_str());
499 }
500
501 inline void LogShader::write (TestLog& log) const
502 {
503         log.writeShader(m_type, m_source.c_str(), m_compileOk, m_infoLog.c_str());
504 }
505
506 inline void LogSpirVAssemblySource::write (TestLog& log) const
507 {
508         log.writeSpirVAssemblySource(m_source.c_str());
509 }
510
511 inline void LogKernelSource::write (TestLog& log) const
512 {
513         log.writeKernelSource(m_source.c_str());
514 }
515
516 inline void LogSampleList::write (TestLog& log) const
517 {
518         log.startSampleList(m_name, m_description);
519 }
520
521 inline void LogValueInfo::write (TestLog& log) const
522 {
523         log.writeValueInfo(m_name, m_description, m_unit, m_tag);
524 }
525
526 template<>
527 inline void LogNumber<float>::write (TestLog& log) const
528 {
529         log.writeFloat(m_name.c_str(), m_desc.c_str(), m_unit.c_str(), m_tag, m_value);
530 }
531
532 template<>
533 inline void LogNumber<deInt64>::write (TestLog& log) const
534 {
535         log.writeInteger(m_name.c_str(), m_desc.c_str(), m_unit.c_str(), m_tag, m_value);
536 }
537
538 } // tcu
539
540 #endif // _TCUTESTLOG_HPP