1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program Tester Core
3 * ----------------------------------------
4 *
5 * Copyright 2014 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Test Log C++ Wrapper.
22 *//*--------------------------------------------------------------------*/
23
24 #include "deCommandLine.h"
25 #include "tcuTestLog.hpp"
26 #include "tcuTextureUtil.hpp"
27 #include "tcuSurface.hpp"
28 #include "deMath.h"
29
30 #include <limits>
31
32 namespace tcu
33 {
34
35 class LogWriteFailedError : public ResourceError
36 {
37 public:
LogWriteFailedError(void)38 LogWriteFailedError(void) : ResourceError("Writing to test log failed")
39 {
40 }
41 };
42
43 enum
44 {
45 MAX_IMAGE_SIZE_2D = 4096,
46 MAX_IMAGE_SIZE_3D = 128
47 };
48
49 // LogImage
50
LogImage(const std::string & name,const std::string & description,const Surface & surface,qpImageCompressionMode compression)51 LogImage::LogImage(const std::string &name, const std::string &description, const Surface &surface,
52 qpImageCompressionMode compression)
53 : m_name(name)
54 , m_description(description)
55 , m_access(surface.getAccess())
56 , m_scale(1.0f, 1.0f, 1.0f, 1.0f)
57 , m_bias(0.0f, 0.0f, 0.0f, 0.0f)
58 , m_compression(compression)
59 {
60 }
61
LogImage(const std::string & name,const std::string & description,const ConstPixelBufferAccess & access,qpImageCompressionMode compression)62 LogImage::LogImage(const std::string &name, const std::string &description, const ConstPixelBufferAccess &access,
63 qpImageCompressionMode compression)
64 : m_name(name)
65 , m_description(description)
66 , m_access(access)
67 , m_scale(1.0f, 1.0f, 1.0f, 1.0f)
68 , m_bias(0.0f, 0.0f, 0.0f, 0.0f)
69 , m_compression(compression)
70 {
71 // Simplify combined formats that only use a single channel
72 if (tcu::isCombinedDepthStencilType(m_access.getFormat().type))
73 {
74 if (m_access.getFormat().order == tcu::TextureFormat::D)
75 m_access = tcu::getEffectiveDepthStencilAccess(m_access, tcu::Sampler::MODE_DEPTH);
76 else if (m_access.getFormat().order == tcu::TextureFormat::S)
77 m_access = tcu::getEffectiveDepthStencilAccess(m_access, tcu::Sampler::MODE_STENCIL);
78 }
79
80 // Implicit scale and bias
81 if (m_access.getFormat().order != tcu::TextureFormat::DS)
82 computePixelScaleBias(m_access, m_scale, m_bias);
83 else
84 {
85 // Pack D and S bias and scale to R and G
86 const ConstPixelBufferAccess depthAccess =
87 tcu::getEffectiveDepthStencilAccess(m_access, tcu::Sampler::MODE_DEPTH);
88 const ConstPixelBufferAccess stencilAccess =
89 tcu::getEffectiveDepthStencilAccess(m_access, tcu::Sampler::MODE_STENCIL);
90 tcu::Vec4 depthScale;
91 tcu::Vec4 depthBias;
92 tcu::Vec4 stencilScale;
93 tcu::Vec4 stencilBias;
94
95 computePixelScaleBias(depthAccess, depthScale, depthBias);
96 computePixelScaleBias(stencilAccess, stencilScale, stencilBias);
97
98 m_scale = tcu::Vec4(depthScale.x(), stencilScale.x(), 0.0f, 0.0f);
99 m_bias = tcu::Vec4(depthBias.x(), stencilBias.x(), 0.0f, 0.0f);
100 }
101 }
102
LogImage(const std::string & name,const std::string & description,const ConstPixelBufferAccess & access,const Vec4 & scale,const Vec4 & bias,qpImageCompressionMode compression)103 LogImage::LogImage(const std::string &name, const std::string &description, const ConstPixelBufferAccess &access,
104 const Vec4 &scale, const Vec4 &bias, qpImageCompressionMode compression)
105 : m_name(name)
106 , m_description(description)
107 , m_access(access)
108 , m_scale(scale)
109 , m_bias(bias)
110 , m_compression(compression)
111 {
112 // Cannot set scale and bias of combined formats
113 DE_ASSERT(access.getFormat().order != tcu::TextureFormat::DS);
114
115 // Simplify access
116 if (tcu::isCombinedDepthStencilType(access.getFormat().type))
117 {
118 if (access.getFormat().order == tcu::TextureFormat::D)
119 m_access = tcu::getEffectiveDepthStencilAccess(access, tcu::Sampler::MODE_DEPTH);
120 if (access.getFormat().order == tcu::TextureFormat::S)
121 m_access = tcu::getEffectiveDepthStencilAccess(access, tcu::Sampler::MODE_STENCIL);
122 else
123 {
124 // Cannot log a DS format
125 DE_ASSERT(false);
126 return;
127 }
128 }
129 }
130
write(TestLog & log) const131 void LogImage::write(TestLog &log) const
132 {
133 if (m_access.getFormat().order != tcu::TextureFormat::DS)
134 log.writeImage(m_name.c_str(), m_description.c_str(), m_access, m_scale, m_bias, m_compression);
135 else
136 {
137 const ConstPixelBufferAccess depthAccess =
138 tcu::getEffectiveDepthStencilAccess(m_access, tcu::Sampler::MODE_DEPTH);
139 const ConstPixelBufferAccess stencilAccess =
140 tcu::getEffectiveDepthStencilAccess(m_access, tcu::Sampler::MODE_STENCIL);
141
142 log.startImageSet(m_name.c_str(), m_description.c_str());
143 log.writeImage("Depth", "Depth channel", depthAccess, m_scale.swizzle(0, 0, 0, 0), m_bias.swizzle(0, 0, 0, 0),
144 m_compression);
145 log.writeImage("Stencil", "Stencil channel", stencilAccess, m_scale.swizzle(1, 1, 1, 1),
146 m_bias.swizzle(1, 1, 1, 1), m_compression);
147 log.endImageSet();
148 }
149 }
150
151 // MessageBuilder
152
MessageBuilder(const MessageBuilder & other)153 MessageBuilder::MessageBuilder(const MessageBuilder &other) : m_log(other.m_log)
154 {
155 m_str.str(other.m_str.str());
156 }
157
operator =(const MessageBuilder & other)158 MessageBuilder &MessageBuilder::operator=(const MessageBuilder &other)
159 {
160 m_log = other.m_log;
161 m_str.str(other.m_str.str());
162 return *this;
163 }
164
operator <<(const TestLog::EndMessageToken &)165 TestLog &MessageBuilder::operator<<(const TestLog::EndMessageToken &)
166 {
167 m_log->writeMessage(m_str.str().c_str());
168 return *m_log;
169 }
170
171 // SampleBuilder
172
operator <<(const TestLog::EndSampleToken &)173 TestLog &SampleBuilder::operator<<(const TestLog::EndSampleToken &)
174 {
175 m_log->startSample();
176
177 for (std::vector<Value>::const_iterator val = m_values.begin(); val != m_values.end(); ++val)
178 {
179 if (val->type == Value::TYPE_FLOAT64)
180 m_log->writeSampleValue(val->value.float64);
181 else if (val->type == Value::TYPE_INT64)
182 m_log->writeSampleValue(val->value.int64);
183 else
184 DE_ASSERT(false);
185 }
186
187 m_log->endSample();
188
189 return *m_log;
190 }
191
192 // TestLog
193
TestLog(const char * fileName,uint32_t flags)194 TestLog::TestLog(const char *fileName, uint32_t flags)
195 : m_log(qpTestLog_createFileLog(fileName, flags))
196 , m_logSupressed(false)
197 {
198 if (!m_log)
199 throw ResourceError(std::string("Failed to open test log file '") + fileName + "'");
200 }
201
writeSessionInfo(std::string additionalInfo)202 void TestLog::writeSessionInfo(std::string additionalInfo)
203 {
204 qpTestLog_beginSession(m_log, additionalInfo.c_str());
205 }
206
~TestLog(void)207 TestLog::~TestLog(void)
208 {
209 qpTestLog_destroy(m_log);
210 }
211
writeMessage(const char * msgStr)212 void TestLog::writeMessage(const char *msgStr)
213 {
214 if (m_logSupressed)
215 return;
216 if (m_skipAdditionalDataInLog)
217 return;
218 if (qpTestLog_writeText(m_log, DE_NULL, DE_NULL, QP_KEY_TAG_NONE, msgStr) == false)
219 throw LogWriteFailedError();
220 }
221
startImageSet(const char * name,const char * description)222 void TestLog::startImageSet(const char *name, const char *description)
223 {
224 if (m_logSupressed)
225 return;
226 if (m_skipAdditionalDataInLog)
227 return;
228 if (qpTestLog_startImageSet(m_log, name, description) == false)
229 throw LogWriteFailedError();
230 }
231
endImageSet(void)232 void TestLog::endImageSet(void)
233 {
234 if (m_logSupressed)
235 return;
236 if (m_skipAdditionalDataInLog)
237 return;
238 if (qpTestLog_endImageSet(m_log) == false)
239 throw LogWriteFailedError();
240 }
241
242 template <int Size>
computeScaledSize(const Vector<int,Size> & imageSize,int maxSize)243 static Vector<int, Size> computeScaledSize(const Vector<int, Size> &imageSize, int maxSize)
244 {
245 bool allInRange = true;
246 for (int i = 0; i < Size; i++)
247 allInRange = allInRange && (imageSize[i] <= maxSize);
248
249 if (allInRange)
250 return imageSize;
251 else
252 {
253 float d = 1.0f;
254 for (int i = 0; i < Size; i++)
255 d = de::max(d, (float)imageSize[i] / (float)maxSize);
256
257 Vector<int, Size> res;
258 for (int i = 0; i < Size; i++)
259 res[i] = de::max(1, deRoundFloatToInt32((float)imageSize[i] / d));
260
261 return res;
262 }
263 }
264
writeImage(const char * name,const char * description,const ConstPixelBufferAccess & access,const Vec4 & pixelScale,const Vec4 & pixelBias,qpImageCompressionMode compressionMode)265 void TestLog::writeImage(const char *name, const char *description, const ConstPixelBufferAccess &access,
266 const Vec4 &pixelScale, const Vec4 &pixelBias, qpImageCompressionMode compressionMode)
267 {
268 if (m_logSupressed)
269 return;
270 if (m_skipAdditionalDataInLog)
271 return;
272 const TextureFormat &format = access.getFormat();
273 int width = access.getWidth();
274 int height = access.getHeight();
275 int depth = access.getDepth();
276
277 // Writing a combined image does not make sense
278 DE_ASSERT(!tcu::isCombinedDepthStencilType(access.getFormat().type));
279
280 // Do not bother with preprocessing if images are not stored
281 if ((qpTestLog_getLogFlags(m_log) & QP_TEST_LOG_EXCLUDE_IMAGES) != 0)
282 return;
283
284 if (depth == 1 && (format.type == TextureFormat::UNORM_INT8 || format.type == TextureFormat::UNSIGNED_INT8) &&
285 width <= MAX_IMAGE_SIZE_2D && height <= MAX_IMAGE_SIZE_2D &&
286 (format.order == TextureFormat::RGB || format.order == TextureFormat::RGBA) &&
287 access.getPixelPitch() == access.getFormat().getPixelSize() && pixelBias[0] == 0.0f && pixelBias[1] == 0.0f &&
288 pixelBias[2] == 0.0f && pixelBias[3] == 0.0f && pixelScale[0] == 1.0f && pixelScale[1] == 1.0f &&
289 pixelScale[2] == 1.0f && pixelScale[3] == 1.0f)
290 {
291 // Fast-path.
292 bool isRGBA = format.order == TextureFormat::RGBA;
293
294 writeImage(name, description, compressionMode, isRGBA ? QP_IMAGE_FORMAT_RGBA8888 : QP_IMAGE_FORMAT_RGB888,
295 width, height, access.getRowPitch(), access.getDataPtr());
296 }
297 else if (depth == 1)
298 {
299 Sampler sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::LINEAR,
300 Sampler::NEAREST);
301 IVec2 logImageSize = computeScaledSize(IVec2(width, height), MAX_IMAGE_SIZE_2D);
302 tcu::TextureLevel logImage(TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8), logImageSize.x(),
303 logImageSize.y(), 1);
304 PixelBufferAccess logImageAccess = logImage.getAccess();
305 std::ostringstream longDesc;
306
307 longDesc << description << " (p' = p * " << pixelScale << " + " << pixelBias << ")";
308
309 for (int y = 0; y < logImage.getHeight(); y++)
310 {
311 for (int x = 0; x < logImage.getWidth(); x++)
312 {
313 float yf = ((float)y + 0.5f) / (float)logImage.getHeight();
314 float xf = ((float)x + 0.5f) / (float)logImage.getWidth();
315 Vec4 s = access.sample2D(sampler, sampler.minFilter, xf, yf, 0) * pixelScale + pixelBias;
316
317 logImageAccess.setPixel(s, x, y);
318 }
319 }
320
321 writeImage(name, longDesc.str().c_str(), compressionMode, QP_IMAGE_FORMAT_RGBA8888, logImageAccess.getWidth(),
322 logImageAccess.getHeight(), logImageAccess.getRowPitch(), logImageAccess.getDataPtr());
323 }
324 else
325 {
326 // Isometric splat volume rendering.
327 const float blendFactor = 0.85f;
328 IVec3 scaledSize = computeScaledSize(IVec3(width, height, depth), MAX_IMAGE_SIZE_3D);
329 int w = scaledSize.x();
330 int h = scaledSize.y();
331 int d = scaledSize.z();
332 int logImageW = w + d - 1;
333 int logImageH = w + d + h;
334 std::vector<float> blendImage(logImageW * logImageH * 4, 0.0f);
335 PixelBufferAccess blendImageAccess(TextureFormat(TextureFormat::RGBA, TextureFormat::FLOAT), logImageW,
336 logImageH, 1, &blendImage[0]);
337 tcu::TextureLevel logImage(TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8), logImageW, logImageH,
338 1);
339 PixelBufferAccess logImageAccess = logImage.getAccess();
340 Sampler sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST,
341 Sampler::NEAREST);
342 std::ostringstream longDesc;
343
344 // \note Back-to-front.
345 for (int z = d - 1; z >= 0; z--)
346 {
347 for (int y = 0; y < h; y++)
348 {
349 for (int x = 0; x < w; x++)
350 {
351 int px = w - (x + 1) + z;
352 int py = (w + d + h) - (x + y + z + 1);
353
354 float xf = ((float)x + 0.5f) / (float)w;
355 float yf = ((float)y + 0.5f) / (float)h;
356 float zf = ((float)z + 0.5f) / (float)d;
357
358 Vec4 p = blendImageAccess.getPixel(px, py);
359 Vec4 s = access.sample3D(sampler, sampler.minFilter, xf, yf, zf);
360 Vec4 b = s + p * blendFactor;
361
362 blendImageAccess.setPixel(b, px, py);
363 }
364 }
365 }
366
367 // Scale blend image nicely.
368 longDesc << description << " (p' = p * " << pixelScale << " + " << pixelBias << ")";
369
370 // Write to final image.
371 tcu::clear(logImageAccess, tcu::IVec4(0x33, 0x66, 0x99, 0xff));
372
373 for (int z = 0; z < d; z++)
374 {
375 for (int y = 0; y < h; y++)
376 {
377 for (int x = 0; x < w; x++)
378 {
379 if (z != 0 && !(x == 0 || y == h - 1 || y == h - 2))
380 continue;
381
382 int px = w - (x + 1) + z;
383 int py = (w + d + h) - (x + y + z + 1);
384 Vec4 s = blendImageAccess.getPixel(px, py) * pixelScale + pixelBias;
385
386 logImageAccess.setPixel(s, px, py);
387 }
388 }
389 }
390
391 writeImage(name, longDesc.str().c_str(), compressionMode, QP_IMAGE_FORMAT_RGBA8888, logImageAccess.getWidth(),
392 logImageAccess.getHeight(), logImageAccess.getRowPitch(), logImageAccess.getDataPtr());
393 }
394 }
395
writeImage(const char * name,const char * description,qpImageCompressionMode compressionMode,qpImageFormat format,int width,int height,int stride,const void * data)396 void TestLog::writeImage(const char *name, const char *description, qpImageCompressionMode compressionMode,
397 qpImageFormat format, int width, int height, int stride, const void *data)
398 {
399 if (m_logSupressed)
400 return;
401 if (m_skipAdditionalDataInLog)
402 return;
403 if (qpTestLog_writeImage(m_log, name, description, compressionMode, format, width, height, stride, data) == false)
404 throw LogWriteFailedError();
405 }
406
startSection(const char * name,const char * description)407 void TestLog::startSection(const char *name, const char *description)
408 {
409 if (m_logSupressed)
410 return;
411 if (m_skipAdditionalDataInLog)
412 return;
413 if (qpTestLog_startSection(m_log, name, description) == false)
414 throw LogWriteFailedError();
415 }
416
endSection(void)417 void TestLog::endSection(void)
418 {
419 if (m_logSupressed)
420 return;
421 if (m_skipAdditionalDataInLog)
422 return;
423 if (qpTestLog_endSection(m_log) == false)
424 throw LogWriteFailedError();
425 }
426
startShaderProgram(bool linkOk,const char * linkInfoLog)427 void TestLog::startShaderProgram(bool linkOk, const char *linkInfoLog)
428 {
429 if (m_logSupressed)
430 return;
431 if (m_skipAdditionalDataInLog)
432 return;
433 if (qpTestLog_startShaderProgram(m_log, linkOk ? true : false, linkInfoLog) == false)
434 throw LogWriteFailedError();
435 }
436
endShaderProgram(void)437 void TestLog::endShaderProgram(void)
438 {
439 if (m_logSupressed)
440 return;
441 if (m_skipAdditionalDataInLog)
442 return;
443 if (qpTestLog_endShaderProgram(m_log) == false)
444 throw LogWriteFailedError();
445 }
446
writeShader(qpShaderType type,const char * source,bool compileOk,const char * infoLog)447 void TestLog::writeShader(qpShaderType type, const char *source, bool compileOk, const char *infoLog)
448 {
449 if (m_logSupressed)
450 return;
451 if (m_skipAdditionalDataInLog)
452 return;
453 if (qpTestLog_writeShader(m_log, type, source, compileOk ? true : false, infoLog) == false)
454 throw LogWriteFailedError();
455 }
456
writeSpirVAssemblySource(const char * source)457 void TestLog::writeSpirVAssemblySource(const char *source)
458 {
459 if (m_logSupressed)
460 return;
461 if (m_skipAdditionalDataInLog)
462 return;
463 if (qpTestLog_writeSpirVAssemblySource(m_log, source) == false)
464 throw LogWriteFailedError();
465 }
466
writeKernelSource(const char * source)467 void TestLog::writeKernelSource(const char *source)
468 {
469 if (m_logSupressed)
470 return;
471 if (m_skipAdditionalDataInLog)
472 return;
473 if (qpTestLog_writeKernelSource(m_log, source) == false)
474 throw LogWriteFailedError();
475 }
476
writeCompileInfo(const char * name,const char * description,bool compileOk,const char * infoLog)477 void TestLog::writeCompileInfo(const char *name, const char *description, bool compileOk, const char *infoLog)
478 {
479 if (m_logSupressed)
480 return;
481 if (m_skipAdditionalDataInLog)
482 return;
483 if (qpTestLog_writeCompileInfo(m_log, name, description, compileOk ? true : false, infoLog) == false)
484 throw LogWriteFailedError();
485 }
486
writeFloat(const char * name,const char * description,const char * unit,qpKeyValueTag tag,float value)487 void TestLog::writeFloat(const char *name, const char *description, const char *unit, qpKeyValueTag tag, float value)
488 {
489 if (m_logSupressed)
490 return;
491 if (m_skipAdditionalDataInLog)
492 return;
493 if (qpTestLog_writeFloat(m_log, name, description, unit, tag, value) == false)
494 throw LogWriteFailedError();
495 }
496
writeInteger(const char * name,const char * description,const char * unit,qpKeyValueTag tag,int64_t value)497 void TestLog::writeInteger(const char *name, const char *description, const char *unit, qpKeyValueTag tag,
498 int64_t value)
499 {
500 if (m_logSupressed)
501 return;
502 if (m_skipAdditionalDataInLog)
503 return;
504 if (qpTestLog_writeInteger(m_log, name, description, unit, tag, value) == false)
505 throw LogWriteFailedError();
506 }
507
startEglConfigSet(const char * name,const char * description)508 void TestLog::startEglConfigSet(const char *name, const char *description)
509 {
510 if (m_logSupressed)
511 return;
512 if (qpTestLog_startEglConfigSet(m_log, name, description) == false)
513 throw LogWriteFailedError();
514 }
515
writeEglConfig(const qpEglConfigInfo * config)516 void TestLog::writeEglConfig(const qpEglConfigInfo *config)
517 {
518 if (m_logSupressed)
519 return;
520 if (qpTestLog_writeEglConfig(m_log, config) == false)
521 throw LogWriteFailedError();
522 }
523
endEglConfigSet(void)524 void TestLog::endEglConfigSet(void)
525 {
526 if (m_logSupressed)
527 return;
528 if (qpTestLog_endEglConfigSet(m_log) == false)
529 throw LogWriteFailedError();
530 }
531
startCase(const char * testCasePath,qpTestCaseType testCaseType)532 void TestLog::startCase(const char *testCasePath, qpTestCaseType testCaseType)
533 {
534 if (m_logSupressed)
535 return;
536 if (qpTestLog_startCase(m_log, testCasePath, testCaseType) == false)
537 throw LogWriteFailedError();
538 // Check if the test is one of those we want to print fully in the log
539 m_skipAdditionalDataInLog = false;
540 if (qpTestLog_isCompact(m_log))
541 {
542 const std::string testCasePathStr = testCasePath;
543 if (testCasePathStr.rfind("dEQP-VK.info.") != 0 && testCasePathStr.rfind("dEQP-VK.api.info.") != 0 &&
544 testCasePathStr.rfind("dEQP-VK.api.version_check.") != 0)
545 {
546 // We can skip writing text, numbers, imagesets, etc.
547 m_skipAdditionalDataInLog = true;
548 }
549 }
550 }
551
endCase(qpTestResult result,const char * description)552 void TestLog::endCase(qpTestResult result, const char *description)
553 {
554 if (m_logSupressed)
555 return;
556 if (qpTestLog_endCase(m_log, result, description) == false)
557 throw LogWriteFailedError();
558 }
559
terminateCase(qpTestResult result)560 void TestLog::terminateCase(qpTestResult result)
561 {
562 if (m_logSupressed)
563 return;
564 if (qpTestLog_terminateCase(m_log, result) == false)
565 throw LogWriteFailedError();
566 }
567
startTestsCasesTime(void)568 void TestLog::startTestsCasesTime(void)
569 {
570 if (m_logSupressed)
571 return;
572 if (qpTestLog_startTestsCasesTime(m_log) == false)
573 throw LogWriteFailedError();
574 }
575
endTestsCasesTime(void)576 void TestLog::endTestsCasesTime(void)
577 {
578 if (m_logSupressed)
579 return;
580 if (qpTestLog_endTestsCasesTime(m_log) == false)
581 throw LogWriteFailedError();
582 }
583
startSampleList(const std::string & name,const std::string & description)584 void TestLog::startSampleList(const std::string &name, const std::string &description)
585 {
586 if (m_logSupressed)
587 return;
588 if (qpTestLog_startSampleList(m_log, name.c_str(), description.c_str()) == false)
589 throw LogWriteFailedError();
590 }
591
startSampleInfo(void)592 void TestLog::startSampleInfo(void)
593 {
594 if (m_logSupressed)
595 return;
596 if (qpTestLog_startSampleInfo(m_log) == false)
597 throw LogWriteFailedError();
598 }
599
writeValueInfo(const std::string & name,const std::string & description,const std::string & unit,qpSampleValueTag tag)600 void TestLog::writeValueInfo(const std::string &name, const std::string &description, const std::string &unit,
601 qpSampleValueTag tag)
602 {
603 if (m_logSupressed)
604 return;
605 if (qpTestLog_writeValueInfo(m_log, name.c_str(), description.c_str(), unit.empty() ? DE_NULL : unit.c_str(),
606 tag) == false)
607 throw LogWriteFailedError();
608 }
609
endSampleInfo(void)610 void TestLog::endSampleInfo(void)
611 {
612 if (m_logSupressed)
613 return;
614 if (qpTestLog_endSampleInfo(m_log) == false)
615 throw LogWriteFailedError();
616 }
617
startSample(void)618 void TestLog::startSample(void)
619 {
620 if (m_logSupressed)
621 return;
622 if (qpTestLog_startSample(m_log) == false)
623 throw LogWriteFailedError();
624 }
625
writeSampleValue(double value)626 void TestLog::writeSampleValue(double value)
627 {
628 if (m_logSupressed)
629 return;
630 if (qpTestLog_writeValueFloat(m_log, value) == false)
631 throw LogWriteFailedError();
632 }
633
writeSampleValue(int64_t value)634 void TestLog::writeSampleValue(int64_t value)
635 {
636 if (m_logSupressed)
637 return;
638 if (qpTestLog_writeValueInteger(m_log, value) == false)
639 throw LogWriteFailedError();
640 }
641
endSample(void)642 void TestLog::endSample(void)
643 {
644 if (m_logSupressed)
645 return;
646 if (qpTestLog_endSample(m_log) == false)
647 throw LogWriteFailedError();
648 }
649
endSampleList(void)650 void TestLog::endSampleList(void)
651 {
652 if (m_logSupressed)
653 return;
654 if (qpTestLog_endSampleList(m_log) == false)
655 throw LogWriteFailedError();
656 }
657
writeRaw(const char * rawContents)658 void TestLog::writeRaw(const char *rawContents)
659 {
660 if (m_logSupressed)
661 return;
662 qpTestLog_writeRaw(m_log, rawContents);
663 }
664
isShaderLoggingEnabled(void)665 bool TestLog::isShaderLoggingEnabled(void)
666 {
667 return (qpTestLog_getLogFlags(m_log) & QP_TEST_LOG_EXCLUDE_SHADER_SOURCES) == 0;
668 }
669
supressLogging(bool value)670 void TestLog::supressLogging(bool value)
671 {
672 m_logSupressed = value;
673 }
674
isSupressLogging(void)675 bool TestLog::isSupressLogging(void)
676 {
677 return m_logSupressed;
678 }
679
680 const TestLog::BeginMessageToken TestLog::Message = TestLog::BeginMessageToken();
681 const TestLog::EndMessageToken TestLog::EndMessage = TestLog::EndMessageToken();
682 const TestLog::EndImageSetToken TestLog::EndImageSet = TestLog::EndImageSetToken();
683 const TestLog::EndSectionToken TestLog::EndSection = TestLog::EndSectionToken();
684 const TestLog::EndShaderProgramToken TestLog::EndShaderProgram = TestLog::EndShaderProgramToken();
685 const TestLog::SampleInfoToken TestLog::SampleInfo = TestLog::SampleInfoToken();
686 const TestLog::EndSampleInfoToken TestLog::EndSampleInfo = TestLog::EndSampleInfoToken();
687 const TestLog::BeginSampleToken TestLog::Sample = TestLog::BeginSampleToken();
688 const TestLog::EndSampleToken TestLog::EndSample = TestLog::EndSampleToken();
689 const TestLog::EndSampleListToken TestLog::EndSampleList = TestLog::EndSampleListToken();
690
691 } // namespace tcu
692