xref: /aosp_15_r20/external/deqp/framework/common/tcuTestLog.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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>
48 class LogNumber;
49 
50 /*--------------------------------------------------------------------*//*!
51  * \brief Test log
52  *
53  * TestLog provides convinient C++ API for logging. The API has been designed
54  * around stream operators much like STL iostream library. The following
55  * examples demonstrate how to use TestLog.
56  *
57  * \code
58  * TestLog& log = m_testCtx.getLog();
59  *
60  * // Write message to log.
61  * log << TestLog::Message << "Hello, World!" << TestLog::EndMessage;
62  * int myNumber = 3;
63  * log << TestLog::Message << "Diff is " << myNumber << TestLog::EndMessage;
64  *
65  * // Write image
66  * Surface myImage(256, 256);
67  * log << TestLog::Image("TestImage", "My test image", myImage);
68  *
69  * // Multiple commands can be combined:
70  * log << TestLog::Section("Details", "Test case details")
71  *     << TestLog::Message << "Here be dragons" << TestLog::EndMessage
72  *     << TestLog::ImageSet("Result", "Result images")
73  *     << TestLog::Image("ImageA", "Image A", imageA)
74  *     << TestLog::Image("ImageB", "Image B", imageB)
75  *     << TestLog::EndImageSet << TestLog::EndSection;
76  * \endcode
77  *//*--------------------------------------------------------------------*/
78 class TestLog
79 {
80 public:
81     // Tokens
82     static const class BeginMessageToken
83     {
84     } Message;
85     static const class EndMessageToken
86     {
87     } EndMessage;
88     static const class EndImageSetToken
89     {
90     } EndImageSet;
91     static const class EndSectionToken
92     {
93     } EndSection;
94     static const class EndShaderProgramToken
95     {
96     } EndShaderProgram;
97     static const class SampleInfoToken
98     {
99     } SampleInfo;
100     static const class EndSampleInfoToken
101     {
102     } EndSampleInfo;
103     static const class BeginSampleToken
104     {
105     } Sample;
106     static const class EndSampleToken
107     {
108     } EndSample;
109     static const class EndSampleListToken
110     {
111     } EndSampleList;
112 
113     // Typedefs.
114     typedef LogImageSet ImageSet;
115     typedef LogImage Image;
116     typedef LogSection Section;
117     typedef LogShaderProgram ShaderProgram;
118     typedef LogShader Shader;
119     typedef LogSpirVAssemblySource SpirVAssemblySource;
120     typedef LogKernelSource KernelSource;
121     typedef LogSampleList SampleList;
122     typedef LogValueInfo ValueInfo;
123     typedef LogNumber<float> Float;
124     typedef LogNumber<int64_t> Integer;
125 
126     explicit TestLog(const char *fileName, uint32_t flags = 0);
127     ~TestLog(void);
128 
129     void writeSessionInfo(std::string additionalInfo = "");
130 
131     MessageBuilder operator<<(const BeginMessageToken &);
132     MessageBuilder message(void);
133 
134     TestLog &operator<<(const ImageSet &imageSet);
135     TestLog &operator<<(const Image &image);
136     TestLog &operator<<(const EndImageSetToken &);
137 
138     TestLog &operator<<(const Section &section);
139     TestLog &operator<<(const EndSectionToken &);
140 
141     TestLog &operator<<(const ShaderProgram &shaderProgram);
142     TestLog &operator<<(const EndShaderProgramToken &);
143     TestLog &operator<<(const Shader &shader);
144     TestLog &operator<<(const SpirVAssemblySource &module);
145 
146     TestLog &operator<<(const KernelSource &kernelSrc);
147 
148     template <typename T>
149     TestLog &operator<<(const LogNumber<T> &number);
150 
151     TestLog &operator<<(const SampleList &sampleList);
152     TestLog &operator<<(const SampleInfoToken &);
153     TestLog &operator<<(const ValueInfo &valueInfo);
154     TestLog &operator<<(const EndSampleInfoToken &);
155     SampleBuilder operator<<(const BeginSampleToken &);
156     TestLog &operator<<(const EndSampleListToken &);
157 
158     // Raw api
159     void writeMessage(const char *message);
160 
161     void startImageSet(const char *name, const char *description);
162     void endImageSet(void);
163     void writeImage(const char *name, const char *description, const ConstPixelBufferAccess &surface, const Vec4 &scale,
164                     const Vec4 &bias, qpImageCompressionMode compressionMode = QP_IMAGE_COMPRESSION_MODE_BEST);
165     void writeImage(const char *name, const char *description, qpImageCompressionMode compressionMode,
166                     qpImageFormat format, int width, int height, int stride, const void *data);
167 
168     void startSection(const char *name, const char *description);
169     void endSection(void);
170 
171     void startShaderProgram(bool linkOk, const char *linkInfoLog);
172     void endShaderProgram(void);
173     void writeShader(qpShaderType type, const char *source, bool compileOk, const char *infoLog);
174     void writeSpirVAssemblySource(const char *source);
175     void writeKernelSource(const char *source);
176     void writeCompileInfo(const char *name, const char *description, bool compileOk, const char *infoLog);
177 
178     void writeFloat(const char *name, const char *description, const char *unit, qpKeyValueTag tag, float value);
179     void writeInteger(const char *name, const char *description, const char *unit, qpKeyValueTag tag, int64_t value);
180 
181     void startEglConfigSet(const char *name, const char *description);
182     void writeEglConfig(const qpEglConfigInfo *config);
183     void endEglConfigSet(void);
184 
185     void startCase(const char *testCasePath, qpTestCaseType testCaseType);
186     void endCase(qpTestResult result, const char *description);
187     void terminateCase(qpTestResult result);
188 
189     void startTestsCasesTime(void);
190     void endTestsCasesTime(void);
191 
192     void startSampleList(const std::string &name, const std::string &description);
193     void startSampleInfo(void);
194     void writeValueInfo(const std::string &name, const std::string &description, const std::string &unit,
195                         qpSampleValueTag tag);
196     void endSampleInfo(void);
197     void startSample(void);
198     void writeSampleValue(double value);
199     void writeSampleValue(int64_t value);
200     void endSample(void);
201     void endSampleList(void);
202 
203     void writeRaw(const char *rawContents);
204 
205     bool isShaderLoggingEnabled(void);
206 
207     void supressLogging(bool value);
208     bool isSupressLogging(void);
209 
210 private:
211     TestLog(const TestLog &other);            // Not allowed!
212     TestLog &operator=(const TestLog &other); // Not allowed!
213 
214     qpTestLog *m_log;
215     bool m_logSupressed;
216     bool m_skipAdditionalDataInLog;
217 };
218 
219 class MessageBuilder
220 {
221 public:
MessageBuilder(TestLog * log)222     explicit MessageBuilder(TestLog *log) : m_log(log)
223     {
224     }
~MessageBuilder(void)225     ~MessageBuilder(void)
226     {
227     }
228 
toString(void) const229     std::string toString(void) const
230     {
231         return m_str.str();
232     }
233 
234     TestLog &operator<<(const TestLog::EndMessageToken &);
235 
236     template <typename T>
237     MessageBuilder &operator<<(const T &value);
238 
239     MessageBuilder(const MessageBuilder &other);
240     MessageBuilder &operator=(const MessageBuilder &other);
241 
242 private:
243     TestLog *m_log;
244     std::ostringstream m_str;
245 };
246 
247 class SampleBuilder
248 {
249 public:
SampleBuilder(TestLog * log)250     SampleBuilder(TestLog *log) : m_log(log)
251     {
252     }
253 
operator <<(int v)254     SampleBuilder &operator<<(int v)
255     {
256         m_values.push_back(Value((int64_t)v));
257         return *this;
258     }
operator <<(int64_t v)259     SampleBuilder &operator<<(int64_t v)
260     {
261         m_values.push_back(Value(v));
262         return *this;
263     }
operator <<(float v)264     SampleBuilder &operator<<(float v)
265     {
266         m_values.push_back(Value((double)v));
267         return *this;
268     }
operator <<(double v)269     SampleBuilder &operator<<(double v)
270     {
271         m_values.push_back(Value(v));
272         return *this;
273     }
274 
275     TestLog &operator<<(const TestLog::EndSampleToken &);
276 
277 private:
278     struct Value
279     {
280         enum Type
281         {
282             TYPE_INT64 = 0,
283             TYPE_FLOAT64,
284             TYPE_LAST
285         };
286 
287         Type type;
288         union
289         {
290             int64_t int64;
291             double float64;
292         } value;
293 
Valuetcu::SampleBuilder::Value294         Value(void) : type(TYPE_LAST)
295         {
296             value.int64 = 0;
297         }
Valuetcu::SampleBuilder::Value298         Value(double v) : type(TYPE_FLOAT64)
299         {
300             value.float64 = v;
301         }
Valuetcu::SampleBuilder::Value302         Value(int64_t v) : type(TYPE_INT64)
303         {
304             value.int64 = v;
305         }
306     };
307 
308     TestLog *m_log;
309     std::vector<Value> m_values;
310 };
311 
312 class LogImageSet
313 {
314 public:
LogImageSet(const std::string & name,const std::string & description)315     LogImageSet(const std::string &name, const std::string &description) : m_name(name), m_description(description)
316     {
317     }
318 
319     void write(TestLog &log) const;
320 
321 private:
322     std::string m_name;
323     std::string m_description;
324 };
325 
326 // \note Doesn't take copy of surface contents
327 class LogImage
328 {
329 public:
330     LogImage(const std::string &name, const std::string &description, const Surface &surface,
331              qpImageCompressionMode compression = QP_IMAGE_COMPRESSION_MODE_BEST);
332 
333     LogImage(const std::string &name, const std::string &description, const ConstPixelBufferAccess &access,
334              qpImageCompressionMode compression = QP_IMAGE_COMPRESSION_MODE_BEST);
335 
336     LogImage(const std::string &name, const std::string &description, const ConstPixelBufferAccess &access,
337              const Vec4 &scale, const Vec4 &bias, qpImageCompressionMode compression = QP_IMAGE_COMPRESSION_MODE_BEST);
338 
339     void write(TestLog &log) const;
340 
341 private:
342     std::string m_name;
343     std::string m_description;
344     ConstPixelBufferAccess m_access;
345     Vec4 m_scale;
346     Vec4 m_bias;
347     qpImageCompressionMode m_compression;
348 };
349 
350 class LogSection
351 {
352 public:
LogSection(const std::string & name,const std::string & description)353     LogSection(const std::string &name, const std::string &description) : m_name(name), m_description(description)
354     {
355     }
356 
357     void write(TestLog &log) const;
358 
359 private:
360     std::string m_name;
361     std::string m_description;
362 };
363 
364 class LogShaderProgram
365 {
366 public:
LogShaderProgram(bool linkOk,const std::string & linkInfoLog)367     LogShaderProgram(bool linkOk, const std::string &linkInfoLog) : m_linkOk(linkOk), m_linkInfoLog(linkInfoLog)
368     {
369     }
370 
371     void write(TestLog &log) const;
372 
373 private:
374     bool m_linkOk;
375     std::string m_linkInfoLog;
376 };
377 
378 class LogShader
379 {
380 public:
LogShader(qpShaderType type,const std::string & source,bool compileOk,const std::string & infoLog)381     LogShader(qpShaderType type, const std::string &source, bool compileOk, const std::string &infoLog)
382         : m_type(type)
383         , m_source(source)
384         , m_compileOk(compileOk)
385         , m_infoLog(infoLog)
386     {
387     }
388 
389     void write(TestLog &log) const;
390 
391 private:
392     qpShaderType m_type;
393     std::string m_source;
394     bool m_compileOk;
395     std::string m_infoLog;
396 };
397 
398 class LogSpirVAssemblySource
399 {
400 public:
LogSpirVAssemblySource(const std::string & source)401     LogSpirVAssemblySource(const std::string &source) : m_source(source)
402     {
403     }
404 
405     void write(TestLog &log) const;
406 
407 private:
408     std::string m_source;
409 };
410 
411 class LogKernelSource
412 {
413 public:
LogKernelSource(const std::string & source)414     explicit LogKernelSource(const std::string &source) : m_source(source)
415     {
416     }
417 
418     void write(TestLog &log) const;
419 
420 private:
421     std::string m_source;
422 };
423 
424 class LogSampleList
425 {
426 public:
LogSampleList(const std::string & name,const std::string & description)427     LogSampleList(const std::string &name, const std::string &description) : m_name(name), m_description(description)
428     {
429     }
430 
431     void write(TestLog &log) const;
432 
433 private:
434     std::string m_name;
435     std::string m_description;
436 };
437 
438 class LogValueInfo
439 {
440 public:
LogValueInfo(const std::string & name,const std::string & description,const std::string & unit,qpSampleValueTag tag)441     LogValueInfo(const std::string &name, const std::string &description, const std::string &unit, qpSampleValueTag tag)
442         : m_name(name)
443         , m_description(description)
444         , m_unit(unit)
445         , m_tag(tag)
446     {
447     }
448 
449     void write(TestLog &log) const;
450 
451 private:
452     std::string m_name;
453     std::string m_description;
454     std::string m_unit;
455     qpSampleValueTag m_tag;
456 };
457 
458 template <typename T>
459 class LogNumber
460 {
461 public:
LogNumber(const std::string & name,const std::string & desc,const std::string & unit,qpKeyValueTag tag,T value)462     LogNumber(const std::string &name, const std::string &desc, const std::string &unit, qpKeyValueTag tag, T value)
463         : m_name(name)
464         , m_desc(desc)
465         , m_unit(unit)
466         , m_tag(tag)
467         , m_value(value)
468     {
469     }
470 
471     void write(TestLog &log) const;
472 
473 private:
474     std::string m_name;
475     std::string m_desc;
476     std::string m_unit;
477     qpKeyValueTag m_tag;
478     T m_value;
479 };
480 
481 // Section helper that closes section when leaving scope.
482 class ScopedLogSection
483 {
484 public:
ScopedLogSection(TestLog & log,const std::string & name,const std::string & description)485     ScopedLogSection(TestLog &log, const std::string &name, const std::string &description) : m_log(log)
486     {
487         m_log << TestLog::Section(name, description);
488     }
489 
~ScopedLogSection(void)490     ~ScopedLogSection(void)
491     {
492         m_log << TestLog::EndSection;
493     }
494 
495 private:
496     TestLog &m_log;
497 };
498 
499 // TestLog stream operators.
500 
operator <<(const ImageSet & imageSet)501 inline TestLog &TestLog::operator<<(const ImageSet &imageSet)
502 {
503     imageSet.write(*this);
504     return *this;
505 }
operator <<(const Image & image)506 inline TestLog &TestLog::operator<<(const Image &image)
507 {
508     image.write(*this);
509     return *this;
510 }
operator <<(const EndImageSetToken &)511 inline TestLog &TestLog::operator<<(const EndImageSetToken &)
512 {
513     endImageSet();
514     return *this;
515 }
operator <<(const Section & section)516 inline TestLog &TestLog::operator<<(const Section &section)
517 {
518     section.write(*this);
519     return *this;
520 }
operator <<(const EndSectionToken &)521 inline TestLog &TestLog::operator<<(const EndSectionToken &)
522 {
523     endSection();
524     return *this;
525 }
operator <<(const ShaderProgram & shaderProg)526 inline TestLog &TestLog::operator<<(const ShaderProgram &shaderProg)
527 {
528     shaderProg.write(*this);
529     return *this;
530 }
operator <<(const EndShaderProgramToken &)531 inline TestLog &TestLog::operator<<(const EndShaderProgramToken &)
532 {
533     endShaderProgram();
534     return *this;
535 }
operator <<(const Shader & shader)536 inline TestLog &TestLog::operator<<(const Shader &shader)
537 {
538     shader.write(*this);
539     return *this;
540 }
operator <<(const SpirVAssemblySource & module)541 inline TestLog &TestLog::operator<<(const SpirVAssemblySource &module)
542 {
543     module.write(*this);
544     return *this;
545 }
operator <<(const KernelSource & kernelSrc)546 inline TestLog &TestLog::operator<<(const KernelSource &kernelSrc)
547 {
548     kernelSrc.write(*this);
549     return *this;
550 }
operator <<(const SampleList & sampleList)551 inline TestLog &TestLog::operator<<(const SampleList &sampleList)
552 {
553     sampleList.write(*this);
554     return *this;
555 }
operator <<(const SampleInfoToken &)556 inline TestLog &TestLog::operator<<(const SampleInfoToken &)
557 {
558     startSampleInfo();
559     return *this;
560 }
operator <<(const ValueInfo & valueInfo)561 inline TestLog &TestLog::operator<<(const ValueInfo &valueInfo)
562 {
563     valueInfo.write(*this);
564     return *this;
565 }
operator <<(const EndSampleInfoToken &)566 inline TestLog &TestLog::operator<<(const EndSampleInfoToken &)
567 {
568     endSampleInfo();
569     return *this;
570 }
operator <<(const EndSampleListToken &)571 inline TestLog &TestLog::operator<<(const EndSampleListToken &)
572 {
573     endSampleList();
574     return *this;
575 }
576 
577 template <typename T>
operator <<(const LogNumber<T> & number)578 inline TestLog &TestLog::operator<<(const LogNumber<T> &number)
579 {
580     number.write(*this);
581     return *this;
582 }
583 
operator <<(TestLog & log,const std::exception & e)584 inline TestLog &operator<<(TestLog &log, const std::exception &e)
585 {
586     // \todo [2012-10-18 pyry] Print type info?
587     return log << TestLog::Message << e.what() << TestLog::EndMessage;
588 }
589 
590 // Utility class inline implementations.
591 
592 template <typename T>
operator <<(const T & value)593 inline MessageBuilder &MessageBuilder::operator<<(const T &value)
594 {
595     // Overload stream operator to implement custom format
596     m_str << value;
597     return *this;
598 }
599 
operator <<(const BeginMessageToken &)600 inline MessageBuilder TestLog::operator<<(const BeginMessageToken &)
601 {
602     return MessageBuilder(this);
603 }
604 
message(void)605 inline MessageBuilder TestLog::message(void)
606 {
607     return MessageBuilder(this);
608 }
609 
operator <<(const BeginSampleToken &)610 inline SampleBuilder TestLog::operator<<(const BeginSampleToken &)
611 {
612     return SampleBuilder(this);
613 }
614 
write(TestLog & log) const615 inline void LogImageSet::write(TestLog &log) const
616 {
617     log.startImageSet(m_name.c_str(), m_description.c_str());
618 }
619 
write(TestLog & log) const620 inline void LogSection::write(TestLog &log) const
621 {
622     log.startSection(m_name.c_str(), m_description.c_str());
623 }
624 
write(TestLog & log) const625 inline void LogShaderProgram::write(TestLog &log) const
626 {
627     log.startShaderProgram(m_linkOk, m_linkInfoLog.c_str());
628 }
629 
write(TestLog & log) const630 inline void LogShader::write(TestLog &log) const
631 {
632     log.writeShader(m_type, m_source.c_str(), m_compileOk, m_infoLog.c_str());
633 }
634 
write(TestLog & log) const635 inline void LogSpirVAssemblySource::write(TestLog &log) const
636 {
637     log.writeSpirVAssemblySource(m_source.c_str());
638 }
639 
write(TestLog & log) const640 inline void LogKernelSource::write(TestLog &log) const
641 {
642     log.writeKernelSource(m_source.c_str());
643 }
644 
write(TestLog & log) const645 inline void LogSampleList::write(TestLog &log) const
646 {
647     log.startSampleList(m_name, m_description);
648 }
649 
write(TestLog & log) const650 inline void LogValueInfo::write(TestLog &log) const
651 {
652     log.writeValueInfo(m_name, m_description, m_unit, m_tag);
653 }
654 
655 template <>
write(TestLog & log) const656 inline void LogNumber<float>::write(TestLog &log) const
657 {
658     log.writeFloat(m_name.c_str(), m_desc.c_str(), m_unit.c_str(), m_tag, m_value);
659 }
660 
661 template <>
write(TestLog & log) const662 inline void LogNumber<int64_t>::write(TestLog &log) const
663 {
664     log.writeInteger(m_name.c_str(), m_desc.c_str(), m_unit.c_str(), m_tag, m_value);
665 }
666 
667 } // namespace tcu
668 
669 #endif // _TCUTESTLOG_HPP
670