13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program Tester Core
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ----------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Test Log C++ Wrapper.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTextureUtil.hpp"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuSurface.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMath.h"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <limits>
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace tcu
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass LogWriteFailedError : public ResourceError
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LogWriteFailedError (void) : ResourceError("Writing to test log failed") {}
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAX_IMAGE_SIZE_2D		= 4096,
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAX_IMAGE_SIZE_3D		= 128
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// LogImage
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
483c827367444ee418f129b2c238299f49d3264554Jarkko PoyryLogImage::LogImage (const std::string& name, const std::string& description, const Surface& surface, qpImageCompressionMode compression)
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_name		(name)
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_description	(description)
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_access		(surface.getAccess())
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_scale		(1.0f, 1.0f, 1.0f, 1.0f)
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_bias		(0.0f, 0.0f, 0.0f, 0.0f)
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_compression	(compression)
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
583c827367444ee418f129b2c238299f49d3264554Jarkko PoyryLogImage::LogImage (const std::string& name, const std::string& description, const ConstPixelBufferAccess& access, qpImageCompressionMode compression)
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_name		(name)
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_description	(description)
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_access		(access)
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_scale		(1.0f, 1.0f, 1.0f, 1.0f)
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_bias		(0.0f, 0.0f, 0.0f, 0.0f)
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_compression	(compression)
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	computePixelScaleBias(access, m_scale, m_bias);
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// MessageBuilder
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
713c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMessageBuilder::MessageBuilder (const MessageBuilder& other)
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_log(other.m_log)
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_str.str(other.m_str.str());
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
773c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMessageBuilder& MessageBuilder::operator= (const MessageBuilder& other)
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_log = other.m_log;
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_str.str(other.m_str.str());
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
843c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTestLog& MessageBuilder::operator<< (const TestLog::EndMessageToken&)
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_log->writeMessage(m_str.str().c_str());
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *m_log;
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// SampleBuilder
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
923c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTestLog& SampleBuilder::operator<< (const TestLog::EndSampleToken&)
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_log->startSample();
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (std::vector<Value>::const_iterator val = m_values.begin(); val != m_values.end(); ++val)
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (val->type == Value::TYPE_FLOAT64)
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_log->writeSampleValue(val->value.float64);
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (val->type == Value::TYPE_INT64)
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_log->writeSampleValue(val->value.int64);
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_log->endSample();
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *m_log;
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TestLog
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1133c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTestLog::TestLog (const char* fileName, deUint32 flags)
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_log(qpTestLog_createFileLog(fileName, flags))
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!m_log)
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw ResourceError(std::string("Failed to open test log file '") + fileName + "'");
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1203c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTestLog::~TestLog (void)
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	qpTestLog_destroy(m_log);
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestLog::writeMessage (const char* msgStr)
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (qpTestLog_writeText(m_log, DE_NULL, DE_NULL, QP_KEY_TAG_LAST, msgStr) == DE_FALSE)
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw LogWriteFailedError();
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestLog::startImageSet (const char* name, const char* description)
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (qpTestLog_startImageSet(m_log, name, description) == DE_FALSE)
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw LogWriteFailedError();
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestLog::endImageSet (void)
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (qpTestLog_endImageSet(m_log) == DE_FALSE)
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw LogWriteFailedError();
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int Size>
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vector<int, Size> computeScaledSize (const Vector<int, Size>& imageSize, int maxSize)
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool allInRange = true;
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < Size; i++)
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		allInRange = allInRange && (imageSize[i] <= maxSize);
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (allInRange)
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return imageSize;
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float d = 1.0f;
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < Size; i++)
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			d = de::max(d, (float)imageSize[i] / (float)maxSize);
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vector<int, Size> res;
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < Size; i++)
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			res[i] = deRoundFloatToInt32((float)imageSize[i] / d);
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return res;
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestLog::writeImage (const char* name, const char* description, const ConstPixelBufferAccess& access, const Vec4& pixelScale, const Vec4& pixelBias, qpImageCompressionMode compressionMode)
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const TextureFormat&	format		= access.getFormat();
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						width		= access.getWidth();
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						height		= access.getHeight();
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						depth		= access.getDepth();
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (depth == 1 && format.type == TextureFormat::UNORM_INT8 &&
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		width <= MAX_IMAGE_SIZE_2D && height <= MAX_IMAGE_SIZE_2D &&
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(format.order == TextureFormat::RGB || format.order == TextureFormat::RGBA)
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		&& pixelBias[0] == 0.0f && pixelBias[1] == 0.0f && pixelBias[2] == 0.0f && pixelBias[3] == 0.0f
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		&& pixelScale[0] == 1.0f && pixelScale[1] == 1.0f && pixelScale[2] == 1.0f && pixelScale[3] == 1.0f)
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Fast-path.
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool isRGBA = format.order == TextureFormat::RGBA;
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		writeImage(name, description, compressionMode,
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				   isRGBA ? QP_IMAGE_FORMAT_RGBA8888 : QP_IMAGE_FORMAT_RGB888,
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				   width, height, access.getRowPitch(), access.getDataPtr());
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (depth == 1)
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Sampler				sampler			(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::LINEAR, Sampler::NEAREST);
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2				logImageSize	= computeScaledSize(IVec2(width, height), MAX_IMAGE_SIZE_2D);
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TextureLevel	logImage		(TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8), logImageSize.x(), logImageSize.y(), 1);
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PixelBufferAccess	logImageAccess	= logImage.getAccess();
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		std::ostringstream	longDesc;
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		longDesc << description << " (p' = p * " << pixelScale << " + " << pixelBias << ")";
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int y = 0; y < logImage.getHeight(); y++)
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int x = 0; x < logImage.getWidth(); x++)
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float	yf	= ((float)y + 0.5f) / (float)logImage.getHeight();
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float	xf	= ((float)x + 0.5f) / (float)logImage.getWidth();
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				Vec4	s	= access.sample2D(sampler, sampler.minFilter, xf, yf, 0)*pixelScale + pixelBias;
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				logImageAccess.setPixel(s, x, y);
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		writeImage(name, longDesc.str().c_str(), compressionMode, QP_IMAGE_FORMAT_RGBA8888,
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				   logImageAccess.getWidth(), logImageAccess.getHeight(), logImageAccess.getRowPitch(),
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				   logImageAccess.getDataPtr());
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Isometric splat volume rendering.
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float			blendFactor			= 0.85f;
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec3				scaledSize			= computeScaledSize(IVec3(width, height, depth), MAX_IMAGE_SIZE_3D);
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int					w					= scaledSize.x();
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int					h					= scaledSize.y();
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int					d					= scaledSize.z();
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int					logImageW			= w+d - 1;
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int					logImageH			= w+d+h;
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		std::vector<float>	blendImage			(logImageW*logImageH*4, 0.0f);
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PixelBufferAccess	blendImageAccess	(TextureFormat(TextureFormat::RGBA, TextureFormat::FLOAT), logImageW, logImageH, 1, &blendImage[0]);
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TextureLevel	logImage			(TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8), logImageW, logImageH, 1);
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PixelBufferAccess	logImageAccess		= logImage.getAccess();
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Sampler				sampler				(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST, Sampler::NEAREST);
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		std::ostringstream	longDesc;
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \note Back-to-front.
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int z = d-1; z >= 0; z--)
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int y = 0; y < h; y++)
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int x = 0; x < w; x++)
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					int		px	= w - (x + 1) + z;
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					int		py	= (w + d + h) - (x + y + z + 1);
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					float	xf	= ((float)x + 0.5f) / (float)w;
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					float	yf	= ((float)y + 0.5f) / (float)h;
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					float	zf	= ((float)z + 0.5f) / (float)d;
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					Vec4	p	= blendImageAccess.getPixel(px, py);
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					Vec4	s	= access.sample3D(sampler, sampler.minFilter, xf, yf, zf);
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					Vec4	b	= s + p*blendFactor;
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					blendImageAccess.setPixel(b, px, py);
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Scale blend image nicely.
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		longDesc << description << " (p' = p * " << pixelScale << " + " << pixelBias << ")";
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Write to final image.
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::clear(logImageAccess, tcu::IVec4(0x33, 0x66, 0x99, 0xff));
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int z = 0; z < d; z++)
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int y = 0; y < h; y++)
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int x = 0; x < w; x++)
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (z != 0 && !(x == 0 || y == h-1 || y == h-2))
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						continue;
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					int		px	= w - (x + 1) + z;
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					int		py	= (w + d + h) - (x + y + z + 1);
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					Vec4	s	= blendImageAccess.getPixel(px, py)*pixelScale + pixelBias;
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					logImageAccess.setPixel(s, px, py);
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		writeImage(name, longDesc.str().c_str(), compressionMode, QP_IMAGE_FORMAT_RGBA8888,
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				   logImageAccess.getWidth(), logImageAccess.getHeight(), logImageAccess.getRowPitch(),
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				   logImageAccess.getDataPtr());
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestLog::writeImage (const char* name, const char* description, qpImageCompressionMode compressionMode, qpImageFormat format, int width, int height, int stride, const void* data)
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (qpTestLog_writeImage(m_log, name, description, compressionMode, format, width, height, stride, data) == DE_FALSE)
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw LogWriteFailedError();
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestLog::startSection (const char* name, const char* description)
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (qpTestLog_startSection(m_log, name, description) == DE_FALSE)
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw LogWriteFailedError();
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestLog::endSection (void)
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (qpTestLog_endSection(m_log) == DE_FALSE)
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw LogWriteFailedError();
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestLog::startShaderProgram (bool linkOk, const char* linkInfoLog)
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (qpTestLog_startShaderProgram(m_log, linkOk?DE_TRUE:DE_FALSE, linkInfoLog) == DE_FALSE)
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw LogWriteFailedError();
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestLog::endShaderProgram (void)
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (qpTestLog_endShaderProgram(m_log) == DE_FALSE)
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw LogWriteFailedError();
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestLog::writeShader (qpShaderType type, const char* source, bool compileOk, const char* infoLog)
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (qpTestLog_writeShader(m_log, type, source, compileOk?DE_TRUE:DE_FALSE, infoLog) == DE_FALSE)
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw LogWriteFailedError();
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestLog::writeKernelSource (const char* source)
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (qpTestLog_writeKernelSource(m_log, source) == DE_FALSE)
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw LogWriteFailedError();
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestLog::writeCompileInfo (const char* name, const char* description, bool compileOk, const char* infoLog)
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (qpTestLog_writeCompileInfo(m_log, name, description, compileOk ? DE_TRUE : DE_FALSE, infoLog) == DE_FALSE)
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw LogWriteFailedError();
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestLog::writeFloat (const char* name, const char* description, const char* unit, qpKeyValueTag tag, float value)
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (qpTestLog_writeFloat(m_log, name, description, unit, tag, value) == DE_FALSE)
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw LogWriteFailedError();
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestLog::writeInteger (const char* name, const char* description, const char* unit, qpKeyValueTag tag, deInt64 value)
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (qpTestLog_writeInteger(m_log, name, description, unit, tag, value) == DE_FALSE)
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw LogWriteFailedError();
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestLog::startEglConfigSet (const char* name, const char* description)
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (qpTestLog_startEglConfigSet(m_log, name, description) == DE_FALSE)
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw LogWriteFailedError();
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestLog::writeEglConfig (const qpEglConfigInfo* config)
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (qpTestLog_writeEglConfig(m_log, config) == DE_FALSE)
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw LogWriteFailedError();
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestLog::endEglConfigSet (void)
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (qpTestLog_endEglConfigSet(m_log) == DE_FALSE)
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw LogWriteFailedError();
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestLog::startCase (const char* testCasePath, qpTestCaseType testCaseType)
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (qpTestLog_startCase(m_log, testCasePath, testCaseType) == DE_FALSE)
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw LogWriteFailedError();
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestLog::endCase (qpTestResult result, const char* description)
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (qpTestLog_endCase(m_log, result, description) == DE_FALSE)
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw LogWriteFailedError();
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestLog::terminateCase (qpTestResult result)
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (qpTestLog_terminateCase(m_log, result) == DE_FALSE)
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw LogWriteFailedError();
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestLog::startSampleList (const std::string& name, const std::string& description)
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (qpTestLog_startSampleList(m_log, name.c_str(), description.c_str()) == DE_FALSE)
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw LogWriteFailedError();
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestLog::startSampleInfo (void)
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (qpTestLog_startSampleInfo(m_log) == DE_FALSE)
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw LogWriteFailedError();
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestLog::writeValueInfo (const std::string& name, const std::string& description, const std::string& unit, qpSampleValueTag tag)
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (qpTestLog_writeValueInfo(m_log, name.c_str(), description.c_str(), unit.empty() ? DE_NULL : unit.c_str(), tag) == DE_FALSE)
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw LogWriteFailedError();
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestLog::endSampleInfo (void)
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (qpTestLog_endSampleInfo(m_log) == DE_FALSE)
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw LogWriteFailedError();
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestLog::startSample (void)
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (qpTestLog_startSample(m_log) == DE_FALSE)
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw LogWriteFailedError();
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestLog::writeSampleValue (double value)
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (qpTestLog_writeValueFloat(m_log, value) == DE_FALSE)
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw LogWriteFailedError();
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestLog::writeSampleValue (deInt64 value)
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (qpTestLog_writeValueInteger(m_log, value) == DE_FALSE)
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw LogWriteFailedError();
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestLog::endSample (void)
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (qpTestLog_endSample(m_log) == DE_FALSE)
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw LogWriteFailedError();
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TestLog::endSampleList (void)
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (qpTestLog_endSampleList(m_log) == DE_FALSE)
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw LogWriteFailedError();
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst TestLog::BeginMessageToken		TestLog::Message			= TestLog::BeginMessageToken();
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst TestLog::EndMessageToken			TestLog::EndMessage			= TestLog::EndMessageToken();
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst TestLog::EndImageSetToken			TestLog::EndImageSet		= TestLog::EndImageSetToken();
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst TestLog::EndSectionToken			TestLog::EndSection			= TestLog::EndSectionToken();
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst TestLog::EndShaderProgramToken	TestLog::EndShaderProgram	= TestLog::EndShaderProgramToken();
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst TestLog::SampleInfoToken			TestLog::SampleInfo			= TestLog::SampleInfoToken();
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst TestLog::EndSampleInfoToken		TestLog::EndSampleInfo		= TestLog::EndSampleInfoToken();
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst TestLog::BeginSampleToken			TestLog::Sample				= TestLog::BeginSampleToken();
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst TestLog::EndSampleToken			TestLog::EndSample			= TestLog::EndSampleToken();
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst TestLog::EndSampleListToken		TestLog::EndSampleList		= TestLog::EndSampleListToken();
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // tcu
444