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