/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.0 Module
 * -------------------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Buffer data upload performance tests.
 *//*--------------------------------------------------------------------*/

#include "es3pBufferDataUploadTests.hpp"
#include "glsCalibration.hpp"
#include "tcuTestLog.hpp"
#include "tcuVectorUtil.hpp"
#include "tcuSurface.hpp"
#include "tcuCPUWarmup.hpp"
#include "tcuRenderTarget.hpp"
#include "gluRenderContext.hpp"
#include "gluShaderProgram.hpp"
#include "gluStrUtil.hpp"
#include "gluPixelTransfer.hpp"
#include "gluObjectWrapper.hpp"
#include "glwFunctions.hpp"
#include "glwEnums.hpp"
#include "deClock.h"
#include "deMath.h"
#include "deStringUtil.hpp"
#include "deRandom.hpp"
#include "deMemory.h"
#include "deThread.h"
#include "deMeta.hpp"

#include <algorithm>
#include <iomanip>
#include <limits>

namespace deqp
{
namespace gles3
{
namespace Performance
{
namespace
{

using gls::theilSenSiegelLinearRegression;
using gls::LineParametersWithConfidence;
using de::meta::EnableIf;
using de::meta::Not;

static const char* const s_minimalVertexShader =	"#version 300 es\n"
													"in highp vec4 a_position;\n"
													"void main (void)\n"
													"{\n"
													"	gl_Position = a_position;\n"
													"}\n";

static const char* const s_minimalFragnentShader =	"#version 300 es\n"
													"layout(location = 0) out mediump vec4 dEQP_FragColor;\n"
													"void main (void)\n"
													"{\n"
													"	dEQP_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
													"}\n";

static const char* const s_colorVertexShader =		"#version 300 es\n"
													"in highp vec4 a_position;\n"
													"in highp vec4 a_color;\n"
													"out highp vec4 v_color;\n"
													"void main (void)\n"
													"{\n"
													"	gl_Position = a_position;\n"
													"	v_color = a_color;\n"
													"}\n";

static const char* const s_colorFragmentShader =	"#version 300 es\n"
													"layout(location = 0) out mediump vec4 dEQP_FragColor;\n"
													"in mediump vec4 v_color;\n"
													"void main (void)\n"
													"{\n"
													"	dEQP_FragColor = v_color;\n"
													"}\n";

struct SingleOperationDuration
{
	deUint64 totalDuration;
	deUint64 fitResponseDuration; // used for fitting
};

struct MapBufferRangeDuration
{
	deUint64 mapDuration;
	deUint64 unmapDuration;
	deUint64 writeDuration;
	deUint64 allocDuration;
	deUint64 totalDuration;

	deUint64 fitResponseDuration;
};

struct MapBufferRangeDurationNoAlloc
{
	deUint64 mapDuration;
	deUint64 unmapDuration;
	deUint64 writeDuration;
	deUint64 totalDuration;

	deUint64 fitResponseDuration;
};

struct MapBufferRangeFlushDuration
{
	deUint64 mapDuration;
	deUint64 unmapDuration;
	deUint64 writeDuration;
	deUint64 flushDuration;
	deUint64 allocDuration;
	deUint64 totalDuration;

	deUint64 fitResponseDuration;
};

struct MapBufferRangeFlushDurationNoAlloc
{
	deUint64 mapDuration;
	deUint64 unmapDuration;
	deUint64 writeDuration;
	deUint64 flushDuration;
	deUint64 totalDuration;

	deUint64 fitResponseDuration;
};

struct RenderReadDuration
{
	deUint64 renderDuration;
	deUint64 readDuration;
	deUint64 renderReadDuration;
	deUint64 totalDuration;

	deUint64 fitResponseDuration;
};

struct UnrelatedUploadRenderReadDuration
{
	deUint64 renderDuration;
	deUint64 readDuration;
	deUint64 renderReadDuration;
	deUint64 totalDuration;

	deUint64 fitResponseDuration;
};

struct UploadRenderReadDuration
{
	deUint64 uploadDuration;
	deUint64 renderDuration;
	deUint64 readDuration;
	deUint64 totalDuration;
	deUint64 renderReadDuration;

	deUint64 fitResponseDuration;
};

struct UploadRenderReadDurationWithUnrelatedUploadSize
{
	deUint64 uploadDuration;
	deUint64 renderDuration;
	deUint64 readDuration;
	deUint64 totalDuration;
	deUint64 renderReadDuration;

	deUint64 fitResponseDuration;
};

struct RenderUploadRenderReadDuration
{
	deUint64 firstRenderDuration;
	deUint64 uploadDuration;
	deUint64 secondRenderDuration;
	deUint64 readDuration;
	deUint64 totalDuration;
	deUint64 renderReadDuration;

	deUint64 fitResponseDuration;
};

template <typename SampleT>
struct UploadSampleResult
{
	typedef SampleT SampleType;

	int			bufferSize;
	int			allocatedSize;
	int			writtenSize;
	SampleType	duration;
};

template <typename SampleT>
struct RenderSampleResult
{
	typedef SampleT SampleType;

	int			uploadedDataSize;
	int			renderDataSize;
	int			unrelatedDataSize;
	int			numVertices;
	SampleT		duration;
};

struct SingleOperationStatistics
{
	float minTime;
	float maxTime;
	float medianTime;
	float min2DecileTime;		// !< minimum value in the 2nd decile
	float max9DecileTime;		// !< maximum value in the 9th decile
};

struct SingleCallStatistics
{
	SingleOperationStatistics	result;

	float						medianRate;
	float						maxDiffTime;
	float						maxDiff9DecileTime;
	float						medianDiffTime;

	float						maxRelDiffTime;
	float						max9DecileRelDiffTime;
	float						medianRelDiffTime;
};

struct MapCallStatistics
{
	SingleOperationStatistics	map;
	SingleOperationStatistics	unmap;
	SingleOperationStatistics	write;
	SingleOperationStatistics	alloc;
	SingleOperationStatistics	result;

	float						medianRate;
	float						maxDiffTime;
	float						maxDiff9DecileTime;
	float						medianDiffTime;

	float						maxRelDiffTime;
	float						max9DecileRelDiffTime;
	float						medianRelDiffTime;
};

struct MapFlushCallStatistics
{
	SingleOperationStatistics	map;
	SingleOperationStatistics	unmap;
	SingleOperationStatistics	write;
	SingleOperationStatistics	flush;
	SingleOperationStatistics	alloc;
	SingleOperationStatistics	result;

	float						medianRate;
	float						maxDiffTime;
	float						maxDiff9DecileTime;
	float						medianDiffTime;

	float						maxRelDiffTime;
	float						max9DecileRelDiffTime;
	float						medianRelDiffTime;
};

struct RenderReadStatistics
{
	SingleOperationStatistics	render;
	SingleOperationStatistics	read;
	SingleOperationStatistics	result;
	SingleOperationStatistics	total;

	float						medianRate;
	float						maxDiffTime;
	float						maxDiff9DecileTime;
	float						medianDiffTime;

	float						maxRelDiffTime;
	float						max9DecileRelDiffTime;
	float						medianRelDiffTime;
};

struct UploadRenderReadStatistics
{
	SingleOperationStatistics	upload;
	SingleOperationStatistics	render;
	SingleOperationStatistics	read;
	SingleOperationStatistics	result;
	SingleOperationStatistics	total;

	float						medianRate;
	float						maxDiffTime;
	float						maxDiff9DecileTime;
	float						medianDiffTime;

	float						maxRelDiffTime;
	float						max9DecileRelDiffTime;
	float						medianRelDiffTime;
};

struct RenderUploadRenderReadStatistics
{
	SingleOperationStatistics	firstRender;
	SingleOperationStatistics	upload;
	SingleOperationStatistics	secondRender;
	SingleOperationStatistics	read;
	SingleOperationStatistics	result;
	SingleOperationStatistics	total;

	float						medianRate;
	float						maxDiffTime;
	float						maxDiff9DecileTime;
	float						medianDiffTime;

	float						maxRelDiffTime;
	float						max9DecileRelDiffTime;
	float						medianRelDiffTime;
};

template <typename T>
struct SampleTypeTraits
{
};

template <>
struct SampleTypeTraits<SingleOperationDuration>
{
	typedef SingleCallStatistics StatsType;

	enum { HAS_MAP_STATS		= 0	};
	enum { HAS_UNMAP_STATS		= 0	};
	enum { HAS_WRITE_STATS		= 0	};
	enum { HAS_FLUSH_STATS		= 0	};
	enum { HAS_ALLOC_STATS		= 0	};
	enum { LOG_CONTRIBUTIONS	= 0	};
};

template <>
struct SampleTypeTraits<MapBufferRangeDuration>
{
	typedef MapCallStatistics StatsType;

	enum { HAS_MAP_STATS		= 1	};
	enum { HAS_UNMAP_STATS		= 1	};
	enum { HAS_WRITE_STATS		= 1	};
	enum { HAS_FLUSH_STATS		= 0	};
	enum { HAS_ALLOC_STATS		= 1	};
	enum { LOG_CONTRIBUTIONS	= 1	};
};

template <>
struct SampleTypeTraits<MapBufferRangeDurationNoAlloc>
{
	typedef MapCallStatistics StatsType;

	enum { HAS_MAP_STATS		= 1	};
	enum { HAS_UNMAP_STATS		= 1	};
	enum { HAS_WRITE_STATS		= 1	};
	enum { HAS_FLUSH_STATS		= 0	};
	enum { HAS_ALLOC_STATS		= 0	};
	enum { LOG_CONTRIBUTIONS	= 1	};
};

template <>
struct SampleTypeTraits<MapBufferRangeFlushDuration>
{
	typedef MapFlushCallStatistics StatsType;

	enum { HAS_MAP_STATS		= 1	};
	enum { HAS_UNMAP_STATS		= 1	};
	enum { HAS_WRITE_STATS		= 1	};
	enum { HAS_FLUSH_STATS		= 1	};
	enum { HAS_ALLOC_STATS		= 1	};
	enum { LOG_CONTRIBUTIONS	= 1	};
};

template <>
struct SampleTypeTraits<MapBufferRangeFlushDurationNoAlloc>
{
	typedef MapFlushCallStatistics StatsType;

	enum { HAS_MAP_STATS		= 1	};
	enum { HAS_UNMAP_STATS		= 1	};
	enum { HAS_WRITE_STATS		= 1	};
	enum { HAS_FLUSH_STATS		= 1	};
	enum { HAS_ALLOC_STATS		= 0	};
	enum { LOG_CONTRIBUTIONS	= 1	};
};

template <>
struct SampleTypeTraits<RenderReadDuration>
{
	typedef RenderReadStatistics StatsType;

	enum { HAS_RENDER_STATS			= 1	};
	enum { HAS_READ_STATS			= 1	};
	enum { HAS_UPLOAD_STATS			= 0	};
	enum { HAS_TOTAL_STATS			= 1	};
	enum { HAS_FIRST_RENDER_STATS	= 0	};
	enum { HAS_SECOND_RENDER_STATS	= 0	};

	enum { LOG_CONTRIBUTIONS	= 1	};
};

template <>
struct SampleTypeTraits<UnrelatedUploadRenderReadDuration>
{
	typedef RenderReadStatistics StatsType;

	enum { HAS_RENDER_STATS			= 1	};
	enum { HAS_READ_STATS			= 1	};
	enum { HAS_UPLOAD_STATS			= 0	};
	enum { HAS_TOTAL_STATS			= 1	};
	enum { HAS_FIRST_RENDER_STATS	= 0	};
	enum { HAS_SECOND_RENDER_STATS	= 0	};

	enum { LOG_CONTRIBUTIONS	= 1	};
};

template <>
struct SampleTypeTraits<UploadRenderReadDuration>
{
	typedef UploadRenderReadStatistics StatsType;

	enum { HAS_RENDER_STATS			= 1	};
	enum { HAS_READ_STATS			= 1	};
	enum { HAS_UPLOAD_STATS			= 1	};
	enum { HAS_TOTAL_STATS			= 1	};
	enum { HAS_FIRST_RENDER_STATS	= 0	};
	enum { HAS_SECOND_RENDER_STATS	= 0	};

	enum { LOG_CONTRIBUTIONS			= 1	};
	enum { LOG_UNRELATED_UPLOAD_SIZE	= 0 };
};

template <>
struct SampleTypeTraits<UploadRenderReadDurationWithUnrelatedUploadSize>
{
	typedef UploadRenderReadStatistics StatsType;

	enum { HAS_RENDER_STATS			= 1	};
	enum { HAS_READ_STATS			= 1	};
	enum { HAS_UPLOAD_STATS			= 1	};
	enum { HAS_TOTAL_STATS			= 1	};
	enum { HAS_FIRST_RENDER_STATS	= 0	};
	enum { HAS_SECOND_RENDER_STATS	= 0	};

	enum { LOG_CONTRIBUTIONS			= 1	};
	enum { LOG_UNRELATED_UPLOAD_SIZE	= 1 };
};

template <>
struct SampleTypeTraits<RenderUploadRenderReadDuration>
{
	typedef RenderUploadRenderReadStatistics StatsType;

	enum { HAS_RENDER_STATS			= 0	};
	enum { HAS_READ_STATS			= 1	};
	enum { HAS_UPLOAD_STATS			= 1	};
	enum { HAS_TOTAL_STATS			= 1	};
	enum { HAS_FIRST_RENDER_STATS	= 1	};
	enum { HAS_SECOND_RENDER_STATS	= 1	};

	enum { LOG_CONTRIBUTIONS			= 1	};
	enum { LOG_UNRELATED_UPLOAD_SIZE	= 1 };
};

struct UploadSampleAnalyzeResult
{
	float transferRateMedian;
	float transferRateAtRange;
	float transferRateAtInfinity;
};

struct RenderSampleAnalyzeResult
{
	float renderRateMedian;
	float renderRateAtRange;
	float renderRateAtInfinity;
};

class UnmapFailureError : public std::exception
{
public:
	UnmapFailureError (void) : std::exception() {}
};

static std::string getHumanReadableByteSize (int numBytes)
{
	std::ostringstream buf;

	if (numBytes < 1024)
		buf << numBytes << " byte(s)";
	else if (numBytes < 1024 * 1024)
		buf << de::floatToString((float)numBytes/1024.0f, 1) << " KiB";
	else
		buf << de::floatToString((float)numBytes/1024.0f/1024.0f, 1) << " MiB";

	return buf.str();
}

static deUint64 medianTimeMemcpy (void* dst, const void* src, int numBytes)
{
	// Time used by memcpy is assumed to be asymptotically linear

	// With large numBytes, the probability of context switch or other random
	// event is high. Apply memcpy in parts and report how much time would
	// memcpy have used with the median transfer rate.

	// Less than 1MiB, no need to do anything special
	if (numBytes < 1048576)
	{
		deUint64 startTime;
		deUint64 endTime;

		deYield();

		startTime = deGetMicroseconds();
		deMemcpy(dst, src, numBytes);
		endTime = deGetMicroseconds();

		return endTime - startTime;
	}
	else
	{
		// Do memcpy in multiple parts

		const int	numSections		= 5;
		const int	sectionAlign	= 16;

		int			sectionStarts[numSections+1];
		int			sectionLens[numSections];
		deUint64	sectionTimes[numSections];
		deUint64	medianTime;
		deUint64	bestTime		= 0;

		for (int sectionNdx = 0; sectionNdx < numSections; ++sectionNdx)
			sectionStarts[sectionNdx] = deAlign32((numBytes * sectionNdx / numSections), sectionAlign);
		sectionStarts[numSections] = numBytes;

		for (int sectionNdx = 0; sectionNdx < numSections; ++sectionNdx)
			sectionLens[sectionNdx] = sectionStarts[sectionNdx+1] - sectionStarts[sectionNdx];

		// Memcpy is usually called after mapbuffer range which may take
		// a lot of time. To prevent power management from kicking in during
		// copy, warm up more.
		{
			deYield();
			tcu::warmupCPU();
			deYield();
		}

		for (int sectionNdx = 0; sectionNdx < numSections; ++sectionNdx)
		{
			deUint64 startTime;
			deUint64 endTime;

			startTime = deGetMicroseconds();
			deMemcpy((deUint8*)dst + sectionStarts[sectionNdx], (const deUint8*)src + sectionStarts[sectionNdx], sectionLens[sectionNdx]);
			endTime = deGetMicroseconds();

			sectionTimes[sectionNdx] = endTime - startTime;

			if (!bestTime || sectionTimes[sectionNdx] < bestTime)
				bestTime = sectionTimes[sectionNdx];

			// Detect if write takes 50% longer than it should, and warm up if that happened
			if (sectionNdx != numSections-1 && (float)sectionTimes[sectionNdx] > 1.5f * (float)bestTime)
			{
				deYield();
				tcu::warmupCPU();
				deYield();
			}
		}

		std::sort(sectionTimes, sectionTimes + numSections);

		if ((numSections % 2) == 0)
			medianTime = (sectionTimes[numSections / 2 - 1] + sectionTimes[numSections / 2]) / 2;
		else
			medianTime = sectionTimes[numSections / 2];

		return medianTime*numSections;
	}
}

static float busyworkCalculation (float initial, int workSize)
{
	float	a = initial;
	int		b = 123;

	for (int ndx = 0; ndx < workSize; ++ndx)
	{
		a = deFloatCos(a + (float)b);
		b = (b + 63) % 107 + de::abs((int)(a*10.0f));
	}

	return a + (float)b;
}

static void busyWait (int microseconds)
{
	const deUint64	maxSingleWaitTime	= 1000; // 1ms
	const deUint64	endTime				= deGetMicroseconds() + microseconds;
	float			unused				= *tcu::warmupCPUInternal::g_unused.m_v;
	int				workSize			= 500;

	// exponentially increase work, cap to 1ms
	while (deGetMicroseconds() < endTime)
	{
		const deUint64	startTime		= deGetMicroseconds();
		deUint64		totalTime;

		unused = busyworkCalculation(unused, workSize);

		totalTime = deGetMicroseconds() - startTime;

		if (totalTime >= maxSingleWaitTime)
			break;
		else
			workSize *= 2;
	}

	// "wait"
	while (deGetMicroseconds() < endTime)
		unused = busyworkCalculation(unused, workSize);

	*tcu::warmupCPUInternal::g_unused.m_v = unused;
}

// Sample from given values using linear interpolation at a given position as if values were laid to range [0, 1]
template <typename T>
static float linearSample (const std::vector<T>& values, float position)
{
	DE_ASSERT(position >= 0.0f);
	DE_ASSERT(position <= 1.0f);

	const float	floatNdx			= (float)(values.size() - 1) * position;
	const int	lowerNdx			= (int)deFloatFloor(floatNdx);
	const int	higherNdx			= lowerNdx + 1;
	const float	interpolationFactor = floatNdx - (float)lowerNdx;

	DE_ASSERT(lowerNdx >= 0 && lowerNdx < (int)values.size());
	DE_ASSERT(higherNdx >= 0 && higherNdx < (int)values.size());
	DE_ASSERT(interpolationFactor >= 0 && interpolationFactor < 1.0f);

	return tcu::mix((float)values[lowerNdx], (float)values[higherNdx], interpolationFactor);
}

template <typename T>
SingleOperationStatistics calculateSingleOperationStatistics (const std::vector<T>& samples, deUint64 T::SampleType::*target)
{
	SingleOperationStatistics	stats;
	std::vector<deUint64>		values(samples.size());

	for (int ndx = 0; ndx < (int)samples.size(); ++ndx)
		values[ndx] = samples[ndx].duration.*target;

	std::sort(values.begin(), values.end());

	stats.minTime			= (float)values.front();
	stats.maxTime			= (float)values.back();
	stats.medianTime		= linearSample(values, 0.5f);
	stats.min2DecileTime	= linearSample(values, 0.1f);
	stats.max9DecileTime	= linearSample(values, 0.9f);

	return stats;
}

template <typename StatisticsType, typename SampleType>
void calculateBasicStatistics (StatisticsType& stats, const LineParametersWithConfidence& fit, const std::vector<SampleType>& samples, int SampleType::*predictor)
{
	std::vector<deUint64> values(samples.size());

	for (int ndx = 0; ndx < (int)samples.size(); ++ndx)
		values[ndx] = samples[ndx].duration.fitResponseDuration;

	// median rate
	{
		std::vector<float> processingRates(samples.size());

		for (int ndx = 0; ndx < (int)samples.size(); ++ndx)
		{
			const float timeInSeconds = (float)values[ndx] / 1000.0f / 1000.0f;
			processingRates[ndx] = (float)(samples[ndx].*predictor) / timeInSeconds;
		}

		std::sort(processingRates.begin(), processingRates.end());

		stats.medianRate = linearSample(processingRates, 0.5f);
	}

	// results compared to the approximation
	{
		std::vector<float> timeDiffs(samples.size());

		for (int ndx = 0; ndx < (int)samples.size(); ++ndx)
		{
			const float prediction	= (float)(samples[ndx].*predictor) * fit.coefficient + fit.offset;
			const float actual		= (float)values[ndx];
			timeDiffs[ndx] = actual - prediction;
		}
		std::sort(timeDiffs.begin(), timeDiffs.end());

		stats.maxDiffTime			= timeDiffs.back();
		stats.maxDiff9DecileTime	= linearSample(timeDiffs, 0.9f);
		stats.medianDiffTime		= linearSample(timeDiffs, 0.5f);
	}

	// relative comparison to the approximation
	{
		std::vector<float> relativeDiffs(samples.size());

		for (int ndx = 0; ndx < (int)samples.size(); ++ndx)
		{
			const float prediction	= (float)(samples[ndx].*predictor) * fit.coefficient + fit.offset;
			const float actual		= (float)values[ndx];

			// Ignore cases where we predict negative times, or if
			// ratio would be (nearly) infinite: ignore if predicted
			// time is less than 1 microsecond
			if (prediction < 1.0f)
				relativeDiffs[ndx] = 0.0f;
			else
				relativeDiffs[ndx] = (actual - prediction) / prediction;
		}
		std::sort(relativeDiffs.begin(), relativeDiffs.end());

		stats.maxRelDiffTime		= relativeDiffs.back();
		stats.max9DecileRelDiffTime	= linearSample(relativeDiffs, 0.9f);
		stats.medianRelDiffTime		= linearSample(relativeDiffs, 0.5f);
	}

	// values calculated using sorted timings

	std::sort(values.begin(), values.end());

	stats.result.minTime = (float)values.front();
	stats.result.maxTime = (float)values.back();
	stats.result.medianTime = linearSample(values, 0.5f);
	stats.result.min2DecileTime = linearSample(values, 0.1f);
	stats.result.max9DecileTime = linearSample(values, 0.9f);
}

template <typename StatisticsType, typename SampleType>
void calculateBasicTransferStatistics (StatisticsType& stats, const LineParametersWithConfidence& fit, const std::vector<SampleType>& samples)
{
	calculateBasicStatistics(stats, fit, samples, &SampleType::writtenSize);
}

template <typename StatisticsType, typename SampleType>
void calculateBasicRenderStatistics (StatisticsType& stats, const LineParametersWithConfidence& fit, const std::vector<SampleType>& samples)
{
	calculateBasicStatistics(stats, fit, samples, &SampleType::renderDataSize);
}

static SingleCallStatistics calculateSampleStatistics (const LineParametersWithConfidence& fit, const std::vector<UploadSampleResult<SingleOperationDuration> >& samples)
{
	SingleCallStatistics stats;

	calculateBasicTransferStatistics(stats, fit, samples);

	return stats;
}

static MapCallStatistics calculateSampleStatistics (const LineParametersWithConfidence& fit, const std::vector<UploadSampleResult<MapBufferRangeDuration> >& samples)
{
	MapCallStatistics stats;

	calculateBasicTransferStatistics(stats, fit, samples);

	stats.map	= calculateSingleOperationStatistics(samples, &MapBufferRangeDuration::mapDuration);
	stats.unmap	= calculateSingleOperationStatistics(samples, &MapBufferRangeDuration::unmapDuration);
	stats.write	= calculateSingleOperationStatistics(samples, &MapBufferRangeDuration::writeDuration);
	stats.alloc	= calculateSingleOperationStatistics(samples, &MapBufferRangeDuration::allocDuration);

	return stats;
}

static MapFlushCallStatistics calculateSampleStatistics (const LineParametersWithConfidence& fit, const std::vector<UploadSampleResult<MapBufferRangeFlushDuration> >& samples)
{
	MapFlushCallStatistics stats;

	calculateBasicTransferStatistics(stats, fit, samples);

	stats.map	= calculateSingleOperationStatistics(samples, &MapBufferRangeFlushDuration::mapDuration);
	stats.unmap	= calculateSingleOperationStatistics(samples, &MapBufferRangeFlushDuration::unmapDuration);
	stats.write	= calculateSingleOperationStatistics(samples, &MapBufferRangeFlushDuration::writeDuration);
	stats.flush	= calculateSingleOperationStatistics(samples, &MapBufferRangeFlushDuration::flushDuration);
	stats.alloc	= calculateSingleOperationStatistics(samples, &MapBufferRangeFlushDuration::allocDuration);

	return stats;
}

static MapCallStatistics calculateSampleStatistics (const LineParametersWithConfidence& fit, const std::vector<UploadSampleResult<MapBufferRangeDurationNoAlloc> >& samples)
{
	MapCallStatistics stats;

	calculateBasicTransferStatistics(stats, fit, samples);

	stats.map	= calculateSingleOperationStatistics(samples, &MapBufferRangeDurationNoAlloc::mapDuration);
	stats.unmap	= calculateSingleOperationStatistics(samples, &MapBufferRangeDurationNoAlloc::unmapDuration);
	stats.write	= calculateSingleOperationStatistics(samples, &MapBufferRangeDurationNoAlloc::writeDuration);

	return stats;
}

static MapFlushCallStatistics calculateSampleStatistics (const LineParametersWithConfidence& fit, const std::vector<UploadSampleResult<MapBufferRangeFlushDurationNoAlloc> >& samples)
{
	MapFlushCallStatistics stats;

	calculateBasicTransferStatistics(stats, fit, samples);

	stats.map	= calculateSingleOperationStatistics(samples, &MapBufferRangeFlushDurationNoAlloc::mapDuration);
	stats.unmap	= calculateSingleOperationStatistics(samples, &MapBufferRangeFlushDurationNoAlloc::unmapDuration);
	stats.write	= calculateSingleOperationStatistics(samples, &MapBufferRangeFlushDurationNoAlloc::writeDuration);
	stats.flush	= calculateSingleOperationStatistics(samples, &MapBufferRangeFlushDurationNoAlloc::flushDuration);

	return stats;
}

static RenderReadStatistics calculateSampleStatistics (const LineParametersWithConfidence& fit, const std::vector<RenderSampleResult<RenderReadDuration> >& samples)
{
	RenderReadStatistics stats;

	calculateBasicRenderStatistics(stats, fit, samples);

	stats.render	= calculateSingleOperationStatistics(samples, &RenderReadDuration::renderDuration);
	stats.read		= calculateSingleOperationStatistics(samples, &RenderReadDuration::readDuration);
	stats.total		= calculateSingleOperationStatistics(samples, &RenderReadDuration::totalDuration);

	return stats;
}

static RenderReadStatistics calculateSampleStatistics (const LineParametersWithConfidence& fit, const std::vector<RenderSampleResult<UnrelatedUploadRenderReadDuration> >& samples)
{
	RenderReadStatistics stats;

	calculateBasicRenderStatistics(stats, fit, samples);

	stats.render	= calculateSingleOperationStatistics(samples, &UnrelatedUploadRenderReadDuration::renderDuration);
	stats.read		= calculateSingleOperationStatistics(samples, &UnrelatedUploadRenderReadDuration::readDuration);
	stats.total		= calculateSingleOperationStatistics(samples, &UnrelatedUploadRenderReadDuration::totalDuration);

	return stats;
}

static UploadRenderReadStatistics calculateSampleStatistics (const LineParametersWithConfidence& fit, const std::vector<RenderSampleResult<UploadRenderReadDuration> >& samples)
{
	UploadRenderReadStatistics stats;

	calculateBasicRenderStatistics(stats, fit, samples);

	stats.upload	= calculateSingleOperationStatistics(samples, &UploadRenderReadDuration::uploadDuration);
	stats.render	= calculateSingleOperationStatistics(samples, &UploadRenderReadDuration::renderDuration);
	stats.read		= calculateSingleOperationStatistics(samples, &UploadRenderReadDuration::readDuration);
	stats.total		= calculateSingleOperationStatistics(samples, &UploadRenderReadDuration::totalDuration);

	return stats;
}

static UploadRenderReadStatistics calculateSampleStatistics (const LineParametersWithConfidence& fit, const std::vector<RenderSampleResult<UploadRenderReadDurationWithUnrelatedUploadSize> >& samples)
{
	UploadRenderReadStatistics stats;

	calculateBasicRenderStatistics(stats, fit, samples);

	stats.upload	= calculateSingleOperationStatistics(samples, &UploadRenderReadDurationWithUnrelatedUploadSize::uploadDuration);
	stats.render	= calculateSingleOperationStatistics(samples, &UploadRenderReadDurationWithUnrelatedUploadSize::renderDuration);
	stats.read		= calculateSingleOperationStatistics(samples, &UploadRenderReadDurationWithUnrelatedUploadSize::readDuration);
	stats.total		= calculateSingleOperationStatistics(samples, &UploadRenderReadDurationWithUnrelatedUploadSize::totalDuration);

	return stats;
}

static RenderUploadRenderReadStatistics calculateSampleStatistics (const LineParametersWithConfidence& fit, const std::vector<RenderSampleResult<RenderUploadRenderReadDuration> >& samples)
{
	RenderUploadRenderReadStatistics stats;

	calculateBasicRenderStatistics(stats, fit, samples);

	stats.firstRender	= calculateSingleOperationStatistics(samples, &RenderUploadRenderReadDuration::firstRenderDuration);
	stats.upload		= calculateSingleOperationStatistics(samples, &RenderUploadRenderReadDuration::uploadDuration);
	stats.secondRender	= calculateSingleOperationStatistics(samples, &RenderUploadRenderReadDuration::secondRenderDuration);
	stats.read			= calculateSingleOperationStatistics(samples, &RenderUploadRenderReadDuration::readDuration);
	stats.total			= calculateSingleOperationStatistics(samples, &RenderUploadRenderReadDuration::totalDuration);

	return stats;
}

template <typename DurationType>
static LineParametersWithConfidence fitLineToSamples (const std::vector<UploadSampleResult<DurationType> >& samples, int beginNdx, int endNdx, int step, deUint64 DurationType::*target = &DurationType::fitResponseDuration)
{
	std::vector<tcu::Vec2> samplePoints;

	for (int sampleNdx = beginNdx; sampleNdx < endNdx; sampleNdx += step)
	{
		tcu::Vec2 point;

		point.x() = (float)(samples[sampleNdx].writtenSize);
		point.y() = (float)(samples[sampleNdx].duration.*target);

		samplePoints.push_back(point);
	}

	return theilSenSiegelLinearRegression(samplePoints, 0.6f);
}

template <typename DurationType>
static LineParametersWithConfidence fitLineToSamples (const std::vector<RenderSampleResult<DurationType> >& samples, int beginNdx, int endNdx, int step, deUint64 DurationType::*target = &DurationType::fitResponseDuration)
{
	std::vector<tcu::Vec2> samplePoints;

	for (int sampleNdx = beginNdx; sampleNdx < endNdx; sampleNdx += step)
	{
		tcu::Vec2 point;

		point.x() = (float)(samples[sampleNdx].renderDataSize);
		point.y() = (float)(samples[sampleNdx].duration.*target);

		samplePoints.push_back(point);
	}

	return theilSenSiegelLinearRegression(samplePoints, 0.6f);
}

template <typename T>
static LineParametersWithConfidence fitLineToSamples (const std::vector<T>& samples, int beginNdx, int endNdx, deUint64 T::SampleType::*target = &T::SampleType::fitResponseDuration)
{
	return fitLineToSamples(samples, beginNdx, endNdx, 1, target);
}

template <typename T>
static LineParametersWithConfidence fitLineToSamples (const std::vector<T>& samples, deUint64 T::SampleType::*target = &T::SampleType::fitResponseDuration)
{
	return fitLineToSamples(samples, 0, (int)samples.size(), target);
}

static float getAreaBetweenLines (float xmin, float xmax, float lineAOffset, float lineACoefficient, float lineBOffset, float lineBCoefficient)
{
	const float lineAMin		= lineAOffset + lineACoefficient * xmin;
	const float lineAMax		= lineAOffset + lineACoefficient * xmax;
	const float lineBMin		= lineBOffset + lineBCoefficient * xmin;
	const float lineBMax		= lineBOffset + lineBCoefficient * xmax;
	const bool	aOverBAtBegin	= (lineAMin > lineBMin);
	const bool	aOverBAtEnd		= (lineAMax > lineBMax);

	if (aOverBAtBegin == aOverBAtEnd)
	{
		// lines do not intersect

		const float midpoint	= (xmin + xmax) / 2.0f;
		const float width		= (xmax - xmin);

		const float lineAHeight	= lineAOffset + lineACoefficient * midpoint;
		const float lineBHeight	= lineBOffset + lineBCoefficient * midpoint;

		return width * de::abs(lineAHeight - lineBHeight);
	}
	else
	{

		// lines intersect

		const float approachCoeffient	= de::abs(lineACoefficient - lineBCoefficient);
		const float epsilon				= 0.0001f;
		const float leftHeight			= de::abs(lineAMin - lineBMin);
		const float rightHeight			= de::abs(lineAMax - lineBMax);

		if (approachCoeffient < epsilon)
			return 0.0f;

		return (0.5f * leftHeight * (leftHeight / approachCoeffient)) + (0.5f * rightHeight * (rightHeight / approachCoeffient));
	}
}

template <typename T>
static float calculateSampleFitLinearity (const std::vector<T>& samples, int T::*predictor)
{
	// Compare the fitted line of first half of the samples to the fitted line of
	// the second half of the samples. Calculate a AABB that fully contains every
	// sample's x component and both fit lines in this range. Calculate the ratio
	// of the area between the lines and the AABB.

	const float				epsilon				= 1.e-6f;
	const int				midPoint			= (int)samples.size() / 2;
	const LineParametersWithConfidence	startApproximation	= fitLineToSamples(samples, 0, midPoint, &T::SampleType::fitResponseDuration);
	const LineParametersWithConfidence	endApproximation	= fitLineToSamples(samples, midPoint, (int)samples.size(), &T::SampleType::fitResponseDuration);

	const float				aabbMinX			= (float)(samples.front().*predictor);
	const float				aabbMinY			= de::min(startApproximation.offset + startApproximation.coefficient*aabbMinX, endApproximation.offset + endApproximation.coefficient*aabbMinX);
	const float				aabbMaxX			= (float)(samples.back().*predictor);
	const float				aabbMaxY			= de::max(startApproximation.offset + startApproximation.coefficient*aabbMaxX, endApproximation.offset + endApproximation.coefficient*aabbMaxX);

	const float				aabbArea			= (aabbMaxX - aabbMinX) * (aabbMaxY - aabbMinY);
	const float				areaBetweenLines	= getAreaBetweenLines(aabbMinX, aabbMaxX, startApproximation.offset, startApproximation.coefficient, endApproximation.offset, endApproximation.coefficient);
	const float				errorAreaRatio		= (aabbArea < epsilon) ? (1.0f) : (areaBetweenLines / aabbArea);

	return de::clamp(1.0f - errorAreaRatio, 0.0f, 1.0f);
}

template <typename DurationType>
static float calculateSampleFitLinearity (const std::vector<UploadSampleResult<DurationType> >& samples)
{
	return calculateSampleFitLinearity(samples, &UploadSampleResult<DurationType>::writtenSize);
}

template <typename DurationType>
static float calculateSampleFitLinearity (const std::vector<RenderSampleResult<DurationType> >& samples)
{
	return calculateSampleFitLinearity(samples, &RenderSampleResult<DurationType>::renderDataSize);
}

template <typename T>
static float calculateSampleTemporalStability (const std::vector<T>& samples, int T::*predictor)
{
	// Samples are sampled in the following order: 1) even samples (in random order) 2) odd samples (in random order)
	// Compare the fitted line of even samples to the fitted line of the odd samples. Calculate a AABB that fully
	// contains every sample's x component and both fit lines in this range. Calculate the ratio of the area between
	// the lines and the AABB.

	const float				epsilon				= 1.e-6f;
	const LineParametersWithConfidence	evenApproximation	= fitLineToSamples(samples, 0, (int)samples.size(), 2, &T::SampleType::fitResponseDuration);
	const LineParametersWithConfidence	oddApproximation	= fitLineToSamples(samples, 1, (int)samples.size(), 2, &T::SampleType::fitResponseDuration);

	const float				aabbMinX			= (float)(samples.front().*predictor);
	const float				aabbMinY			= de::min(evenApproximation.offset + evenApproximation.coefficient*aabbMinX, oddApproximation.offset + oddApproximation.coefficient*aabbMinX);
	const float				aabbMaxX			= (float)(samples.back().*predictor);
	const float				aabbMaxY			= de::max(evenApproximation.offset + evenApproximation.coefficient*aabbMaxX, oddApproximation.offset + oddApproximation.coefficient*aabbMaxX);

	const float				aabbArea			= (aabbMaxX - aabbMinX) * (aabbMaxY - aabbMinY);
	const float				areaBetweenLines	= getAreaBetweenLines(aabbMinX, aabbMaxX, evenApproximation.offset, evenApproximation.coefficient, oddApproximation.offset, oddApproximation.coefficient);
	const float				errorAreaRatio		= (aabbArea < epsilon) ? (1.0f) : (areaBetweenLines / aabbArea);

	return de::clamp(1.0f - errorAreaRatio, 0.0f, 1.0f);
}

template <typename DurationType>
static float calculateSampleTemporalStability (const std::vector<UploadSampleResult<DurationType> >& samples)
{
	return calculateSampleTemporalStability(samples, &UploadSampleResult<DurationType>::writtenSize);
}

template <typename DurationType>
static float calculateSampleTemporalStability (const std::vector<RenderSampleResult<DurationType> >& samples)
{
	return calculateSampleTemporalStability(samples, &RenderSampleResult<DurationType>::renderDataSize);
}

template <typename DurationType>
static void bucketizeSamplesUniformly (const std::vector<UploadSampleResult<DurationType> >& samples, std::vector<UploadSampleResult<DurationType> >* buckets, int numBuckets, int& minBufferSize, int& maxBufferSize)
{
	minBufferSize = 0;
	maxBufferSize = 0;

	for (int sampleNdx = 0; sampleNdx < (int)samples.size(); ++sampleNdx)
	{
		DE_ASSERT(samples[sampleNdx].allocatedSize != 0);

		if (!minBufferSize || samples[sampleNdx].allocatedSize < minBufferSize)
			minBufferSize = samples[sampleNdx].allocatedSize;
		if (!maxBufferSize || samples[sampleNdx].allocatedSize > maxBufferSize)
			maxBufferSize = samples[sampleNdx].allocatedSize;
	}

	for (int sampleNdx = 0; sampleNdx < (int)samples.size(); ++sampleNdx)
	{
		const float bucketNdxFloat	= (float)(samples[sampleNdx].allocatedSize - minBufferSize) / (float)(maxBufferSize - minBufferSize) * (float)numBuckets;
		const int bucketNdx			= de::clamp((int)deFloatFloor(bucketNdxFloat), 0, numBuckets-1);

		buckets[bucketNdx].push_back(samples[sampleNdx]);
	}
}

template <typename SampleType>
static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_MAP_STATS>::Type logMapRangeStats (tcu::TestLog& log, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
	log	<< tcu::TestLog::Float("MapRangeMin", "MapRange: Min time", "us", QP_KEY_TAG_TIME, stats.map.minTime)
		<< tcu::TestLog::Float("MapRangeMax", "MapRange: Max time", "us", QP_KEY_TAG_TIME, stats.map.maxTime)
		<< tcu::TestLog::Float("MapRangeMin90", "MapRange: 90%-Min time", "us", QP_KEY_TAG_TIME, stats.map.min2DecileTime)
		<< tcu::TestLog::Float("MapRangeMax90", "MapRange: 90%-Max time", "us", QP_KEY_TAG_TIME, stats.map.max9DecileTime)
		<< tcu::TestLog::Float("MapRangeMedian", "MapRange: Median time", "us", QP_KEY_TAG_TIME, stats.map.medianTime);
}

template <typename SampleType>
static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_UNMAP_STATS>::Type logUnmapStats (tcu::TestLog& log, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
	log	<< tcu::TestLog::Float("UnmapMin", "Unmap: Min time", "us", QP_KEY_TAG_TIME, stats.unmap.minTime)
		<< tcu::TestLog::Float("UnmapMax", "Unmap: Max time", "us", QP_KEY_TAG_TIME, stats.unmap.maxTime)
		<< tcu::TestLog::Float("UnmapMin90", "Unmap: 90%-Min time", "us", QP_KEY_TAG_TIME, stats.unmap.min2DecileTime)
		<< tcu::TestLog::Float("UnmapMax90", "Unmap: 90%-Max time", "us", QP_KEY_TAG_TIME, stats.unmap.max9DecileTime)
		<< tcu::TestLog::Float("UnmapMedian", "Unmap: Median time", "us", QP_KEY_TAG_TIME, stats.unmap.medianTime);
}

template <typename SampleType>
static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_WRITE_STATS>::Type logWriteStats (tcu::TestLog& log, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
	log	<< tcu::TestLog::Float("WriteMin", "Write: Min time", "us", QP_KEY_TAG_TIME, stats.write.minTime)
		<< tcu::TestLog::Float("WriteMax", "Write: Max time", "us", QP_KEY_TAG_TIME, stats.write.maxTime)
		<< tcu::TestLog::Float("WriteMin90", "Write: 90%-Min time", "us", QP_KEY_TAG_TIME, stats.write.min2DecileTime)
		<< tcu::TestLog::Float("WriteMax90", "Write: 90%-Max time", "us", QP_KEY_TAG_TIME, stats.write.max9DecileTime)
		<< tcu::TestLog::Float("WriteMedian", "Write: Median time", "us", QP_KEY_TAG_TIME, stats.write.medianTime);
}

template <typename SampleType>
static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_FLUSH_STATS>::Type logFlushStats (tcu::TestLog& log, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
	log	<< tcu::TestLog::Float("FlushMin", "Flush: Min time", "us", QP_KEY_TAG_TIME, stats.flush.minTime)
		<< tcu::TestLog::Float("FlushMax", "Flush: Max time", "us", QP_KEY_TAG_TIME, stats.flush.maxTime)
		<< tcu::TestLog::Float("FlushMin90", "Flush: 90%-Min time", "us", QP_KEY_TAG_TIME, stats.flush.min2DecileTime)
		<< tcu::TestLog::Float("FlushMax90", "Flush: 90%-Max time", "us", QP_KEY_TAG_TIME, stats.flush.max9DecileTime)
		<< tcu::TestLog::Float("FlushMedian", "Flush: Median time", "us", QP_KEY_TAG_TIME, stats.flush.medianTime);
}

template <typename SampleType>
static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_ALLOC_STATS>::Type logAllocStats (tcu::TestLog& log, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
	log	<< tcu::TestLog::Float("AllocMin", "Alloc: Min time", "us", QP_KEY_TAG_TIME, stats.alloc.minTime)
		<< tcu::TestLog::Float("AllocMax", "Alloc: Max time", "us", QP_KEY_TAG_TIME, stats.alloc.maxTime)
		<< tcu::TestLog::Float("AllocMin90", "Alloc: 90%-Min time", "us", QP_KEY_TAG_TIME, stats.alloc.min2DecileTime)
		<< tcu::TestLog::Float("AllocMax90", "Alloc: 90%-Max time", "us", QP_KEY_TAG_TIME, stats.alloc.max9DecileTime)
		<< tcu::TestLog::Float("AllocMedian", "Alloc: Median time", "us", QP_KEY_TAG_TIME, stats.alloc.medianTime);
}

template <typename SampleType>
static typename EnableIf<void, Not<SampleTypeTraits<SampleType>::HAS_MAP_STATS>::Value>::Type logMapRangeStats (tcu::TestLog& log, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
	DE_UNREF(log);
	DE_UNREF(stats);
}

template <typename SampleType>
static typename EnableIf<void, Not<SampleTypeTraits<SampleType>::HAS_UNMAP_STATS>::Value>::Type logUnmapStats (tcu::TestLog& log, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
	DE_UNREF(log);
	DE_UNREF(stats);
}

template <typename SampleType>
static typename EnableIf<void, Not<SampleTypeTraits<SampleType>::HAS_WRITE_STATS>::Value>::Type logWriteStats (tcu::TestLog& log, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
	DE_UNREF(log);
	DE_UNREF(stats);
}

template <typename SampleType>
static typename EnableIf<void, Not<SampleTypeTraits<SampleType>::HAS_FLUSH_STATS>::Value>::Type logFlushStats (tcu::TestLog& log, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
	DE_UNREF(log);
	DE_UNREF(stats);
}

template <typename SampleType>
static typename EnableIf<void, Not<SampleTypeTraits<SampleType>::HAS_ALLOC_STATS>::Value>::Type logAllocStats (tcu::TestLog& log, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
	DE_UNREF(log);
	DE_UNREF(stats);
}

template <typename SampleType>
static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_MAP_STATS>::Type logMapContribution (tcu::TestLog& log, const std::vector<UploadSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
	const LineParametersWithConfidence contributionFitting = fitLineToSamples(samples, &SampleType::mapDuration);
	log	<< tcu::TestLog::Float("MapConstantCost", "Map: Approximated contant cost", "us", QP_KEY_TAG_TIME, contributionFitting.offset)
		<< tcu::TestLog::Float("MapLinearCost", "Map: Approximated linear cost", "us / MB", QP_KEY_TAG_TIME, contributionFitting.coefficient * 1024.0f * 1024.0f)
		<< tcu::TestLog::Float("MapMedianCost", "Map: Median cost", "us", QP_KEY_TAG_TIME, stats.map.medianTime);
}

template <typename SampleType>
static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_UNMAP_STATS>::Type logUnmapContribution (tcu::TestLog& log, const std::vector<UploadSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
	const LineParametersWithConfidence contributionFitting = fitLineToSamples(samples, &SampleType::unmapDuration);
	log	<< tcu::TestLog::Float("UnmapConstantCost", "Unmap: Approximated contant cost", "us", QP_KEY_TAG_TIME, contributionFitting.offset)
		<< tcu::TestLog::Float("UnmapLinearCost", "Unmap: Approximated linear cost", "us / MB", QP_KEY_TAG_TIME, contributionFitting.coefficient * 1024.0f * 1024.0f)
		<< tcu::TestLog::Float("UnmapMedianCost", "Unmap: Median cost", "us", QP_KEY_TAG_TIME, stats.unmap.medianTime);
}

template <typename SampleType>
static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_WRITE_STATS>::Type logWriteContribution (tcu::TestLog& log, const std::vector<UploadSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
	const LineParametersWithConfidence contributionFitting = fitLineToSamples(samples, &SampleType::writeDuration);
	log	<< tcu::TestLog::Float("WriteConstantCost", "Write: Approximated contant cost", "us", QP_KEY_TAG_TIME, contributionFitting.offset)
		<< tcu::TestLog::Float("WriteLinearCost", "Write: Approximated linear cost", "us / MB", QP_KEY_TAG_TIME, contributionFitting.coefficient * 1024.0f * 1024.0f)
		<< tcu::TestLog::Float("WriteMedianCost", "Write: Median cost", "us", QP_KEY_TAG_TIME, stats.write.medianTime);
}

template <typename SampleType>
static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_FLUSH_STATS>::Type logFlushContribution (tcu::TestLog& log, const std::vector<UploadSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
	const LineParametersWithConfidence contributionFitting = fitLineToSamples(samples, &SampleType::flushDuration);
	log	<< tcu::TestLog::Float("FlushConstantCost", "Flush: Approximated contant cost", "us", QP_KEY_TAG_TIME, contributionFitting.offset)
		<< tcu::TestLog::Float("FlushLinearCost", "Flush: Approximated linear cost", "us / MB", QP_KEY_TAG_TIME, contributionFitting.coefficient * 1024.0f * 1024.0f)
		<< tcu::TestLog::Float("FlushMedianCost", "Flush: Median cost", "us", QP_KEY_TAG_TIME, stats.flush.medianTime);
}

template <typename SampleType>
static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_ALLOC_STATS>::Type logAllocContribution (tcu::TestLog& log, const std::vector<UploadSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
	const LineParametersWithConfidence contributionFitting = fitLineToSamples(samples, &SampleType::allocDuration);
	log	<< tcu::TestLog::Float("AllocConstantCost", "Alloc: Approximated contant cost", "us", QP_KEY_TAG_TIME, contributionFitting.offset)
		<< tcu::TestLog::Float("AllocLinearCost", "Alloc: Approximated linear cost", "us / MB", QP_KEY_TAG_TIME, contributionFitting.coefficient * 1024.0f * 1024.0f)
		<< tcu::TestLog::Float("AllocMedianCost", "Alloc: Median cost", "us", QP_KEY_TAG_TIME, stats.alloc.medianTime);
}

template <typename SampleType>
static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_RENDER_STATS>::Type logRenderContribution (tcu::TestLog& log, const std::vector<RenderSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
	const LineParametersWithConfidence contributionFitting = fitLineToSamples(samples, &SampleType::renderDuration);
	log	<< tcu::TestLog::Float("DrawCallConstantCost", "DrawCall: Approximated contant cost", "us", QP_KEY_TAG_TIME, contributionFitting.offset)
		<< tcu::TestLog::Float("DrawCallLinearCost", "DrawCall: Approximated linear cost", "us / MB", QP_KEY_TAG_TIME, contributionFitting.coefficient * 1024.0f * 1024.0f)
		<< tcu::TestLog::Float("DrawCallMedianCost", "DrawCall: Median cost", "us", QP_KEY_TAG_TIME, stats.render.medianTime);
}

template <typename SampleType>
static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_READ_STATS>::Type logReadContribution (tcu::TestLog& log, const std::vector<RenderSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
	const LineParametersWithConfidence contributionFitting = fitLineToSamples(samples, &SampleType::readDuration);
	log	<< tcu::TestLog::Float("ReadConstantCost", "Read: Approximated contant cost", "us", QP_KEY_TAG_TIME, contributionFitting.offset)
		<< tcu::TestLog::Float("ReadLinearCost", "Read: Approximated linear cost", "us / MB", QP_KEY_TAG_TIME, contributionFitting.coefficient * 1024.0f * 1024.0f)
		<< tcu::TestLog::Float("ReadMedianCost", "Read: Median cost", "us", QP_KEY_TAG_TIME, stats.read.medianTime);
}

template <typename SampleType>
static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_UPLOAD_STATS>::Type logUploadContribution (tcu::TestLog& log, const std::vector<RenderSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
	const LineParametersWithConfidence contributionFitting = fitLineToSamples(samples, &SampleType::uploadDuration);
	log	<< tcu::TestLog::Float("UploadConstantCost", "Upload: Approximated contant cost", "us", QP_KEY_TAG_TIME, contributionFitting.offset)
		<< tcu::TestLog::Float("UploadLinearCost", "Upload: Approximated linear cost", "us / MB", QP_KEY_TAG_TIME, contributionFitting.coefficient * 1024.0f * 1024.0f)
		<< tcu::TestLog::Float("UploadMedianCost", "Upload: Median cost", "us", QP_KEY_TAG_TIME, stats.upload.medianTime);
}

template <typename SampleType>
static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_TOTAL_STATS>::Type logTotalContribution (tcu::TestLog& log, const std::vector<RenderSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
	const LineParametersWithConfidence contributionFitting = fitLineToSamples(samples, &SampleType::totalDuration);
	log	<< tcu::TestLog::Float("TotalConstantCost", "Total: Approximated contant cost", "us", QP_KEY_TAG_TIME, contributionFitting.offset)
		<< tcu::TestLog::Float("TotalLinearCost", "Total: Approximated linear cost", "us / MB", QP_KEY_TAG_TIME, contributionFitting.coefficient * 1024.0f * 1024.0f)
		<< tcu::TestLog::Float("TotalMedianCost", "Total: Median cost", "us", QP_KEY_TAG_TIME, stats.total.medianTime);
}

template <typename SampleType>
static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_FIRST_RENDER_STATS>::Type logFirstRenderContribution (tcu::TestLog& log, const std::vector<RenderSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
	const LineParametersWithConfidence contributionFitting = fitLineToSamples(samples, &SampleType::firstRenderDuration);
	log	<< tcu::TestLog::Float("FirstDrawCallConstantCost", "First DrawCall: Approximated contant cost", "us", QP_KEY_TAG_TIME, contributionFitting.offset)
		<< tcu::TestLog::Float("FirstDrawCallLinearCost", "First DrawCall: Approximated linear cost", "us / MB", QP_KEY_TAG_TIME, contributionFitting.coefficient * 1024.0f * 1024.0f)
		<< tcu::TestLog::Float("FirstDrawCallMedianCost", "First DrawCall: Median cost", "us", QP_KEY_TAG_TIME, stats.firstRender.medianTime);
}

template <typename SampleType>
static typename EnableIf<void, SampleTypeTraits<SampleType>::HAS_SECOND_RENDER_STATS>::Type logSecondRenderContribution (tcu::TestLog& log, const std::vector<RenderSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
	const LineParametersWithConfidence contributionFitting = fitLineToSamples(samples, &SampleType::secondRenderDuration);
	log	<< tcu::TestLog::Float("SecondDrawCallConstantCost", "Second DrawCall: Approximated contant cost", "us", QP_KEY_TAG_TIME, contributionFitting.offset)
		<< tcu::TestLog::Float("SecondDrawCallLinearCost", "Second DrawCall: Approximated linear cost", "us / MB", QP_KEY_TAG_TIME, contributionFitting.coefficient * 1024.0f * 1024.0f)
		<< tcu::TestLog::Float("SecondDrawCallMedianCost", "Second DrawCall: Median cost", "us", QP_KEY_TAG_TIME, stats.secondRender.medianTime);
}

template <typename SampleType>
static typename EnableIf<void, Not<SampleTypeTraits<SampleType>::HAS_MAP_STATS>::Value>::Type logMapContribution (tcu::TestLog& log, const std::vector<UploadSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
	DE_UNREF(log);
	DE_UNREF(samples);
	DE_UNREF(stats);
}

template <typename SampleType>
static typename EnableIf<void, Not<SampleTypeTraits<SampleType>::HAS_UNMAP_STATS>::Value>::Type logUnmapContribution (tcu::TestLog& log, const std::vector<UploadSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
	DE_UNREF(log);
	DE_UNREF(samples);
	DE_UNREF(stats);
}

template <typename SampleType>
static typename EnableIf<void, Not<SampleTypeTraits<SampleType>::HAS_WRITE_STATS>::Value>::Type logWriteContribution (tcu::TestLog& log, const std::vector<UploadSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
	DE_UNREF(log);
	DE_UNREF(samples);
	DE_UNREF(stats);
}

template <typename SampleType>
static typename EnableIf<void, Not<SampleTypeTraits<SampleType>::HAS_FLUSH_STATS>::Value>::Type logFlushContribution (tcu::TestLog& log, const std::vector<UploadSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
	DE_UNREF(log);
	DE_UNREF(samples);
	DE_UNREF(stats);
}

template <typename SampleType>
static typename EnableIf<void, Not<SampleTypeTraits<SampleType>::HAS_ALLOC_STATS>::Value>::Type logAllocContribution (tcu::TestLog& log, const std::vector<UploadSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
	DE_UNREF(log);
	DE_UNREF(samples);
	DE_UNREF(stats);
}

template <typename SampleType>
static typename EnableIf<void, Not<SampleTypeTraits<SampleType>::HAS_RENDER_STATS>::Value>::Type logRenderContribution (tcu::TestLog& log, const std::vector<RenderSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
	DE_UNREF(log);
	DE_UNREF(samples);
	DE_UNREF(stats);
}

template <typename SampleType>
static typename EnableIf<void, Not<SampleTypeTraits<SampleType>::HAS_READ_STATS>::Value>::Type logReadContribution (tcu::TestLog& log, const std::vector<RenderSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
	DE_UNREF(log);
	DE_UNREF(samples);
	DE_UNREF(stats);
}

template <typename SampleType>
static typename EnableIf<void, Not<SampleTypeTraits<SampleType>::HAS_UPLOAD_STATS>::Value>::Type logUploadContribution (tcu::TestLog& log, const std::vector<RenderSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
	DE_UNREF(log);
	DE_UNREF(samples);
	DE_UNREF(stats);
}

template <typename SampleType>
static typename EnableIf<void, Not<SampleTypeTraits<SampleType>::HAS_TOTAL_STATS>::Value>::Type logTotalContribution (tcu::TestLog& log, const std::vector<RenderSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
	DE_UNREF(log);
	DE_UNREF(samples);
	DE_UNREF(stats);
}

template <typename SampleType>
static typename EnableIf<void, Not<SampleTypeTraits<SampleType>::HAS_FIRST_RENDER_STATS>::Value>::Type logFirstRenderContribution (tcu::TestLog& log, const std::vector<RenderSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
	DE_UNREF(log);
	DE_UNREF(samples);
	DE_UNREF(stats);
}

template <typename SampleType>
static typename EnableIf<void, Not<SampleTypeTraits<SampleType>::HAS_SECOND_RENDER_STATS>::Value>::Type logSecondRenderContribution (tcu::TestLog& log, const std::vector<RenderSampleResult<SampleType> >& samples, const typename SampleTypeTraits<SampleType>::StatsType& stats)
{
	DE_UNREF(log);
	DE_UNREF(samples);
	DE_UNREF(stats);
}

void logSampleList (tcu::TestLog& log, const LineParametersWithConfidence& theilSenFitting, const std::vector<UploadSampleResult<SingleOperationDuration> >& samples)
{
	log << tcu::TestLog::SampleList("Samples", "Samples")
		<< tcu::TestLog::SampleInfo
		<< tcu::TestLog::ValueInfo("WrittenSize",		"Written size",			"bytes",	QP_SAMPLE_VALUE_TAG_PREDICTOR)
		<< tcu::TestLog::ValueInfo("BufferSize",		"Buffer size",			"bytes",	QP_SAMPLE_VALUE_TAG_PREDICTOR)
		<< tcu::TestLog::ValueInfo("UploadTime",		"Upload time",			"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("FitResidual",		"Fit residual",			"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::EndSampleInfo;

	for (int sampleNdx = 0; sampleNdx < (int)samples.size(); ++sampleNdx)
	{
		const float fitResidual = (float)samples[sampleNdx].duration.fitResponseDuration - (theilSenFitting.offset + theilSenFitting.coefficient * (float)samples[sampleNdx].writtenSize);
		log	<< tcu::TestLog::Sample
			<< samples[sampleNdx].writtenSize
			<< samples[sampleNdx].bufferSize
			<< (int)samples[sampleNdx].duration.totalDuration
			<< fitResidual
			<< tcu::TestLog::EndSample;
	}

	log << tcu::TestLog::EndSampleList;
}

void logSampleList (tcu::TestLog& log, const LineParametersWithConfidence& theilSenFitting, const std::vector<UploadSampleResult<MapBufferRangeDuration> >& samples)
{
	log << tcu::TestLog::SampleList("Samples", "Samples")
		<< tcu::TestLog::SampleInfo
		<< tcu::TestLog::ValueInfo("WrittenSize",		"Written size",			"bytes",	QP_SAMPLE_VALUE_TAG_PREDICTOR)
		<< tcu::TestLog::ValueInfo("BufferSize",		"Buffer size",			"bytes",	QP_SAMPLE_VALUE_TAG_PREDICTOR)
		<< tcu::TestLog::ValueInfo("TotalTime",			"Total time",			"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("AllocTime",			"Alloc time",			"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("MapTime",			"Map time",				"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("UnmapTime",			"Unmap time",			"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("WriteTime",			"Write time",			"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("FitResidual",		"Fit residual",			"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::EndSampleInfo;

	for (int sampleNdx = 0; sampleNdx < (int)samples.size(); ++sampleNdx)
	{
		const float fitResidual = (float)samples[sampleNdx].duration.fitResponseDuration - (theilSenFitting.offset + theilSenFitting.coefficient * (float)samples[sampleNdx].writtenSize);
		log	<< tcu::TestLog::Sample
			<< samples[sampleNdx].writtenSize
			<< samples[sampleNdx].bufferSize
			<< (int)samples[sampleNdx].duration.totalDuration
			<< (int)samples[sampleNdx].duration.allocDuration
			<< (int)samples[sampleNdx].duration.mapDuration
			<< (int)samples[sampleNdx].duration.unmapDuration
			<< (int)samples[sampleNdx].duration.writeDuration
			<< fitResidual
			<< tcu::TestLog::EndSample;
	}

	log << tcu::TestLog::EndSampleList;
}

void logSampleList (tcu::TestLog& log, const LineParametersWithConfidence& theilSenFitting, const std::vector<UploadSampleResult<MapBufferRangeDurationNoAlloc> >& samples)
{
	log << tcu::TestLog::SampleList("Samples", "Samples")
		<< tcu::TestLog::SampleInfo
		<< tcu::TestLog::ValueInfo("WrittenSize",		"Written size",			"bytes",	QP_SAMPLE_VALUE_TAG_PREDICTOR)
		<< tcu::TestLog::ValueInfo("BufferSize",		"Buffer size",			"bytes",	QP_SAMPLE_VALUE_TAG_PREDICTOR)
		<< tcu::TestLog::ValueInfo("TotalTime",			"Total time",			"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("MapTime",			"Map time",				"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("UnmapTime",			"Unmap time",			"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("WriteTime",			"Write time",			"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("FitResidual",		"Fit residual",			"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::EndSampleInfo;

	for (int sampleNdx = 0; sampleNdx < (int)samples.size(); ++sampleNdx)
	{
		const float fitResidual = (float)samples[sampleNdx].duration.fitResponseDuration - (theilSenFitting.offset + theilSenFitting.coefficient * (float)samples[sampleNdx].writtenSize);
		log	<< tcu::TestLog::Sample
			<< samples[sampleNdx].writtenSize
			<< samples[sampleNdx].bufferSize
			<< (int)samples[sampleNdx].duration.totalDuration
			<< (int)samples[sampleNdx].duration.mapDuration
			<< (int)samples[sampleNdx].duration.unmapDuration
			<< (int)samples[sampleNdx].duration.writeDuration
			<< fitResidual
			<< tcu::TestLog::EndSample;
	}

	log << tcu::TestLog::EndSampleList;
}

void logSampleList (tcu::TestLog& log, const LineParametersWithConfidence& theilSenFitting, const std::vector<UploadSampleResult<MapBufferRangeFlushDuration> >& samples)
{
	log << tcu::TestLog::SampleList("Samples", "Samples")
		<< tcu::TestLog::SampleInfo
		<< tcu::TestLog::ValueInfo("WrittenSize",		"Written size",			"bytes",	QP_SAMPLE_VALUE_TAG_PREDICTOR)
		<< tcu::TestLog::ValueInfo("BufferSize",		"Buffer size",			"bytes",	QP_SAMPLE_VALUE_TAG_PREDICTOR)
		<< tcu::TestLog::ValueInfo("TotalTime",			"Total time",			"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("AllocTime",			"Alloc time",			"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("MapTime",			"Map time",				"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("UnmapTime",			"Unmap time",			"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("WriteTime",			"Write time",			"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("FlushTime",			"Flush time",			"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("FitResidual",		"Fit residual",			"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::EndSampleInfo;

	for (int sampleNdx = 0; sampleNdx < (int)samples.size(); ++sampleNdx)
	{
		const float fitResidual = (float)samples[sampleNdx].duration.fitResponseDuration - (theilSenFitting.offset + theilSenFitting.coefficient * (float)samples[sampleNdx].writtenSize);
		log	<< tcu::TestLog::Sample
			<< samples[sampleNdx].writtenSize
			<< samples[sampleNdx].bufferSize
			<< (int)samples[sampleNdx].duration.totalDuration
			<< (int)samples[sampleNdx].duration.allocDuration
			<< (int)samples[sampleNdx].duration.mapDuration
			<< (int)samples[sampleNdx].duration.unmapDuration
			<< (int)samples[sampleNdx].duration.writeDuration
			<< (int)samples[sampleNdx].duration.flushDuration
			<< fitResidual
			<< tcu::TestLog::EndSample;
	}

	log << tcu::TestLog::EndSampleList;
}

void logSampleList (tcu::TestLog& log, const LineParametersWithConfidence& theilSenFitting, const std::vector<UploadSampleResult<MapBufferRangeFlushDurationNoAlloc> >& samples)
{
	log << tcu::TestLog::SampleList("Samples", "Samples")
		<< tcu::TestLog::SampleInfo
		<< tcu::TestLog::ValueInfo("WrittenSize",		"Written size",			"bytes",	QP_SAMPLE_VALUE_TAG_PREDICTOR)
		<< tcu::TestLog::ValueInfo("BufferSize",		"Buffer size",			"bytes",	QP_SAMPLE_VALUE_TAG_PREDICTOR)
		<< tcu::TestLog::ValueInfo("TotalTime",			"Total time",			"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("MapTime",			"Map time",				"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("UnmapTime",			"Unmap time",			"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("WriteTime",			"Write time",			"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("FlushTime",			"Flush time",			"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("FitResidual",		"Fit residual",			"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::EndSampleInfo;

	for (int sampleNdx = 0; sampleNdx < (int)samples.size(); ++sampleNdx)
	{
		const float fitResidual = (float)samples[sampleNdx].duration.fitResponseDuration - (theilSenFitting.offset + theilSenFitting.coefficient * (float)samples[sampleNdx].writtenSize);
		log	<< tcu::TestLog::Sample
			<< samples[sampleNdx].writtenSize
			<< samples[sampleNdx].bufferSize
			<< (int)samples[sampleNdx].duration.totalDuration
			<< (int)samples[sampleNdx].duration.mapDuration
			<< (int)samples[sampleNdx].duration.unmapDuration
			<< (int)samples[sampleNdx].duration.writeDuration
			<< (int)samples[sampleNdx].duration.flushDuration
			<< fitResidual
			<< tcu::TestLog::EndSample;
	}

	log << tcu::TestLog::EndSampleList;
}

void logSampleList (tcu::TestLog& log, const LineParametersWithConfidence& theilSenFitting, const std::vector<RenderSampleResult<RenderReadDuration> >& samples)
{
	log << tcu::TestLog::SampleList("Samples", "Samples")
		<< tcu::TestLog::SampleInfo
		<< tcu::TestLog::ValueInfo("DataSize",			"Data processed",		"bytes",	QP_SAMPLE_VALUE_TAG_PREDICTOR)
		<< tcu::TestLog::ValueInfo("VertexCount",		"Number of vertices",	"vertices",	QP_SAMPLE_VALUE_TAG_PREDICTOR)
		<< tcu::TestLog::ValueInfo("TotalTime",			"Total time",			"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("DrawCallTime",		"Draw call time",		"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("ReadTime",			"ReadPixels time",		"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("FitResidual",		"Fit residual",			"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::EndSampleInfo;

	for (int sampleNdx = 0; sampleNdx < (int)samples.size(); ++sampleNdx)
	{
		const float fitResidual = (float)samples[sampleNdx].duration.fitResponseDuration - (theilSenFitting.offset + theilSenFitting.coefficient * (float)samples[sampleNdx].renderDataSize);
		log	<< tcu::TestLog::Sample
			<< samples[sampleNdx].renderDataSize
			<< samples[sampleNdx].numVertices
			<< (int)samples[sampleNdx].duration.renderReadDuration
			<< (int)samples[sampleNdx].duration.renderDuration
			<< (int)samples[sampleNdx].duration.readDuration
			<< fitResidual
			<< tcu::TestLog::EndSample;
	}

	log << tcu::TestLog::EndSampleList;
}

void logSampleList (tcu::TestLog& log, const LineParametersWithConfidence& theilSenFitting, const std::vector<RenderSampleResult<UnrelatedUploadRenderReadDuration> >& samples)
{
	log << tcu::TestLog::SampleList("Samples", "Samples")
		<< tcu::TestLog::SampleInfo
		<< tcu::TestLog::ValueInfo("DataSize",				"Data processed",			"bytes",	QP_SAMPLE_VALUE_TAG_PREDICTOR)
		<< tcu::TestLog::ValueInfo("VertexCount",			"Number of vertices",		"vertices",	QP_SAMPLE_VALUE_TAG_PREDICTOR)
		<< tcu::TestLog::ValueInfo("UnrelatedUploadSize",	"Unrelated upload size",	"bytes",	QP_SAMPLE_VALUE_TAG_PREDICTOR)
		<< tcu::TestLog::ValueInfo("TotalTime",				"Total time",				"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("DrawCallTime",			"Draw call time",			"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("ReadTime",				"ReadPixels time",			"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("FitResidual",			"Fit residual",				"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::EndSampleInfo;

	for (int sampleNdx = 0; sampleNdx < (int)samples.size(); ++sampleNdx)
	{
		const float fitResidual = (float)samples[sampleNdx].duration.fitResponseDuration - (theilSenFitting.offset + theilSenFitting.coefficient * (float)samples[sampleNdx].renderDataSize);
		log	<< tcu::TestLog::Sample
			<< samples[sampleNdx].renderDataSize
			<< samples[sampleNdx].numVertices
			<< samples[sampleNdx].unrelatedDataSize
			<< (int)samples[sampleNdx].duration.renderReadDuration
			<< (int)samples[sampleNdx].duration.renderDuration
			<< (int)samples[sampleNdx].duration.readDuration
			<< fitResidual
			<< tcu::TestLog::EndSample;
	}

	log << tcu::TestLog::EndSampleList;
}

void logSampleList (tcu::TestLog& log, const LineParametersWithConfidence& theilSenFitting, const std::vector<RenderSampleResult<UploadRenderReadDuration> >& samples)
{
	log << tcu::TestLog::SampleList("Samples", "Samples")
		<< tcu::TestLog::SampleInfo
		<< tcu::TestLog::ValueInfo("DataSize",			"Data processed",					"bytes",	QP_SAMPLE_VALUE_TAG_PREDICTOR)
		<< tcu::TestLog::ValueInfo("UploadSize",		"Data uploaded",					"bytes",	QP_SAMPLE_VALUE_TAG_PREDICTOR)
		<< tcu::TestLog::ValueInfo("VertexCount",		"Number of vertices",				"vertices",	QP_SAMPLE_VALUE_TAG_PREDICTOR)
		<< tcu::TestLog::ValueInfo("DrawReadTime",		"Draw call and ReadPixels time",	"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("TotalTime",			"Total time",						"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("Upload time",		"Upload time",						"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("DrawCallTime",		"Draw call time",					"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("ReadTime",			"ReadPixels time",					"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("FitResidual",		"Fit residual",						"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::EndSampleInfo;

	for (int sampleNdx = 0; sampleNdx < (int)samples.size(); ++sampleNdx)
	{
		const float fitResidual = (float)samples[sampleNdx].duration.fitResponseDuration - (theilSenFitting.offset + theilSenFitting.coefficient * (float)samples[sampleNdx].renderDataSize);
		log	<< tcu::TestLog::Sample
			<< samples[sampleNdx].renderDataSize
			<< samples[sampleNdx].uploadedDataSize
			<< samples[sampleNdx].numVertices
			<< (int)samples[sampleNdx].duration.renderReadDuration
			<< (int)samples[sampleNdx].duration.totalDuration
			<< (int)samples[sampleNdx].duration.uploadDuration
			<< (int)samples[sampleNdx].duration.renderDuration
			<< (int)samples[sampleNdx].duration.readDuration
			<< fitResidual
			<< tcu::TestLog::EndSample;
	}

	log << tcu::TestLog::EndSampleList;
}

void logSampleList (tcu::TestLog& log, const LineParametersWithConfidence& theilSenFitting, const std::vector<RenderSampleResult<UploadRenderReadDurationWithUnrelatedUploadSize> >& samples)
{
	log << tcu::TestLog::SampleList("Samples", "Samples")
		<< tcu::TestLog::SampleInfo
		<< tcu::TestLog::ValueInfo("DataSize",				"Data processed",					"bytes",	QP_SAMPLE_VALUE_TAG_PREDICTOR)
		<< tcu::TestLog::ValueInfo("UploadSize",			"Data uploaded",					"bytes",	QP_SAMPLE_VALUE_TAG_PREDICTOR)
		<< tcu::TestLog::ValueInfo("VertexCount",			"Number of vertices",				"vertices",	QP_SAMPLE_VALUE_TAG_PREDICTOR)
		<< tcu::TestLog::ValueInfo("UnrelatedUploadSize",	"Unrelated upload size",			"bytes",	QP_SAMPLE_VALUE_TAG_PREDICTOR)
		<< tcu::TestLog::ValueInfo("DrawReadTime",			"Draw call and ReadPixels time",	"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("TotalTime",				"Total time",						"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("Upload time",			"Upload time",						"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("DrawCallTime",			"Draw call time",					"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("ReadTime",				"ReadPixels time",					"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("FitResidual",			"Fit residual",						"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::EndSampleInfo;

	for (int sampleNdx = 0; sampleNdx < (int)samples.size(); ++sampleNdx)
	{
		const float fitResidual = (float)samples[sampleNdx].duration.fitResponseDuration - (theilSenFitting.offset + theilSenFitting.coefficient * (float)samples[sampleNdx].renderDataSize);
		log	<< tcu::TestLog::Sample
			<< samples[sampleNdx].renderDataSize
			<< samples[sampleNdx].uploadedDataSize
			<< samples[sampleNdx].numVertices
			<< samples[sampleNdx].unrelatedDataSize
			<< (int)samples[sampleNdx].duration.renderReadDuration
			<< (int)samples[sampleNdx].duration.totalDuration
			<< (int)samples[sampleNdx].duration.uploadDuration
			<< (int)samples[sampleNdx].duration.renderDuration
			<< (int)samples[sampleNdx].duration.readDuration
			<< fitResidual
			<< tcu::TestLog::EndSample;
	}

	log << tcu::TestLog::EndSampleList;
}

void logSampleList (tcu::TestLog& log, const LineParametersWithConfidence& theilSenFitting, const std::vector<RenderSampleResult<RenderUploadRenderReadDuration> >& samples)
{
	log << tcu::TestLog::SampleList("Samples", "Samples")
		<< tcu::TestLog::SampleInfo
		<< tcu::TestLog::ValueInfo("DataSize",				"Data processed",						"bytes",	QP_SAMPLE_VALUE_TAG_PREDICTOR)
		<< tcu::TestLog::ValueInfo("UploadSize",			"Data uploaded",						"bytes",	QP_SAMPLE_VALUE_TAG_PREDICTOR)
		<< tcu::TestLog::ValueInfo("VertexCount",			"Number of vertices",					"vertices",	QP_SAMPLE_VALUE_TAG_PREDICTOR)
		<< tcu::TestLog::ValueInfo("DrawReadTime",			"Second draw call and ReadPixels time",	"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("TotalTime",				"Total time",							"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("FirstDrawCallTime",		"First draw call time",					"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("Upload time",			"Upload time",							"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("SecondDrawCallTime",	"Second draw call time",				"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("ReadTime",				"ReadPixels time",						"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("FitResidual",			"Fit residual",							"us",		QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::EndSampleInfo;

	for (int sampleNdx = 0; sampleNdx < (int)samples.size(); ++sampleNdx)
	{
		const float fitResidual = (float)samples[sampleNdx].duration.fitResponseDuration - (theilSenFitting.offset + theilSenFitting.coefficient * (float)samples[sampleNdx].renderDataSize);
		log	<< tcu::TestLog::Sample
			<< samples[sampleNdx].renderDataSize
			<< samples[sampleNdx].uploadedDataSize
			<< samples[sampleNdx].numVertices
			<< (int)samples[sampleNdx].duration.renderReadDuration
			<< (int)samples[sampleNdx].duration.totalDuration
			<< (int)samples[sampleNdx].duration.firstRenderDuration
			<< (int)samples[sampleNdx].duration.uploadDuration
			<< (int)samples[sampleNdx].duration.secondRenderDuration
			<< (int)samples[sampleNdx].duration.readDuration
			<< fitResidual
			<< tcu::TestLog::EndSample;
	}

	log << tcu::TestLog::EndSampleList;
}

template <typename SampleType>
static UploadSampleAnalyzeResult analyzeSampleResults (tcu::TestLog& log, const std::vector<UploadSampleResult<SampleType> >& samples, bool logBucketPerformance)
{
	// Assume data is linear with some outliers, fit a line
	const LineParametersWithConfidence						theilSenFitting						= fitLineToSamples(samples);
	const typename SampleTypeTraits<SampleType>::StatsType	resultStats							= calculateSampleStatistics(theilSenFitting, samples);
	float													approximatedTransferRate;
	float													approximatedTransferRateNoConstant;

	// Output raw samples
	{
		const tcu::ScopedLogSection	section(log, "Samples", "Samples");
		logSampleList(log, theilSenFitting, samples);
	}

	// Calculate results for different ranges
	if (logBucketPerformance)
	{
		const int										numBuckets				= 4;
		int												minBufferSize			= 0;
		int												maxBufferSize			= 0;
		std::vector<UploadSampleResult<SampleType> >	buckets[numBuckets];

		bucketizeSamplesUniformly(samples, &buckets[0], numBuckets, minBufferSize, maxBufferSize);

		for (int bucketNdx = 0; bucketNdx < numBuckets; ++bucketNdx)
		{
			if (buckets[bucketNdx].empty())
				continue;

			// Print a nice result summary

			const int												bucketRangeMin	= minBufferSize + (int)(((float) bucketNdx    / (float)numBuckets) * (float)(maxBufferSize - minBufferSize));
			const int												bucketRangeMax	= minBufferSize + (int)(((float)(bucketNdx+1) / (float)numBuckets) * (float)(maxBufferSize - minBufferSize));
			const typename SampleTypeTraits<SampleType>::StatsType	stats			= calculateSampleStatistics(theilSenFitting, buckets[bucketNdx]);
			const tcu::ScopedLogSection								section			(log, "BufferSizeRange", std::string("Transfer performance with buffer size in range [").append(getHumanReadableByteSize(bucketRangeMin).append(", ").append(getHumanReadableByteSize(bucketRangeMax).append("]"))));

			logMapRangeStats<SampleType>(log, stats);
			logUnmapStats<SampleType>(log, stats);
			logWriteStats<SampleType>(log, stats);
			logFlushStats<SampleType>(log, stats);
			logAllocStats<SampleType>(log, stats);

			log	<< tcu::TestLog::Float("Min", "Total: Min time", "us", QP_KEY_TAG_TIME, stats.result.minTime)
				<< tcu::TestLog::Float("Max", "Total: Max time", "us", QP_KEY_TAG_TIME, stats.result.maxTime)
				<< tcu::TestLog::Float("Min90", "Total: 90%-Min time", "us", QP_KEY_TAG_TIME, stats.result.min2DecileTime)
				<< tcu::TestLog::Float("Max90", "Total: 90%-Max time", "us", QP_KEY_TAG_TIME, stats.result.max9DecileTime)
				<< tcu::TestLog::Float("Median", "Total: Median time", "us", QP_KEY_TAG_TIME, stats.result.medianTime)
				<< tcu::TestLog::Float("MedianTransfer", "Median transfer rate", "MB / s", QP_KEY_TAG_PERFORMANCE, stats.medianRate / 1024.0f / 1024.0f)
				<< tcu::TestLog::Float("MaxDiff", "Max difference to approximated", "us", QP_KEY_TAG_TIME, stats.maxDiffTime)
				<< tcu::TestLog::Float("Max90Diff", "90%-Max difference to approximated", "us", QP_KEY_TAG_TIME, stats.maxDiff9DecileTime)
				<< tcu::TestLog::Float("MedianDiff", "Median difference to approximated", "us", QP_KEY_TAG_TIME, stats.medianDiffTime)
				<< tcu::TestLog::Float("MaxRelDiff", "Max relative difference to approximated", "%", QP_KEY_TAG_NONE, stats.maxRelDiffTime * 100.0f)
				<< tcu::TestLog::Float("Max90RelDiff", "90%-Max relative difference to approximated", "%", QP_KEY_TAG_NONE, stats.max9DecileRelDiffTime * 100.0f)
				<< tcu::TestLog::Float("MedianRelDiff", "Median relative difference to approximated", "%", QP_KEY_TAG_NONE, stats.medianRelDiffTime * 100.0f);
		}
	}

	// Contributions
	if (SampleTypeTraits<SampleType>::LOG_CONTRIBUTIONS)
	{
		const tcu::ScopedLogSection	section(log, "Contribution", "Contributions");

		logMapContribution(log, samples, resultStats);
		logUnmapContribution(log, samples, resultStats);
		logWriteContribution(log, samples, resultStats);
		logFlushContribution(log, samples, resultStats);
		logAllocContribution(log, samples, resultStats);
	}

	// Print results
	{
		const tcu::ScopedLogSection	section(log, "Results", "Results");

		const int	medianBufferSize					= (samples.front().bufferSize + samples.back().bufferSize) / 2;
		const float	approximatedTransferTime			= (theilSenFitting.offset + theilSenFitting.coefficient * (float)medianBufferSize) / 1000.0f / 1000.0f;
		const float	approximatedTransferTimeNoConstant	= (theilSenFitting.coefficient * (float)medianBufferSize) / 1000.0f / 1000.0f;
		const float	sampleLinearity						= calculateSampleFitLinearity(samples);
		const float	sampleTemporalStability				= calculateSampleTemporalStability(samples);

		approximatedTransferRateNoConstant				= (float)medianBufferSize / approximatedTransferTimeNoConstant;
		approximatedTransferRate						= (float)medianBufferSize / approximatedTransferTime;

		log	<< tcu::TestLog::Float("ResultLinearity", "Sample linearity", "%", QP_KEY_TAG_QUALITY, sampleLinearity * 100.0f)
			<< tcu::TestLog::Float("SampleTemporalStability", "Sample temporal stability", "%", QP_KEY_TAG_QUALITY, sampleTemporalStability * 100.0f)
			<< tcu::TestLog::Float("ApproximatedConstantCost", "Approximated contant cost", "us", QP_KEY_TAG_TIME, theilSenFitting.offset)
			<< tcu::TestLog::Float("ApproximatedConstantCostConfidence60Lower", "Approximated contant cost 60% confidence lower limit", "us", QP_KEY_TAG_TIME, theilSenFitting.offsetConfidenceLower)
			<< tcu::TestLog::Float("ApproximatedConstantCostConfidence60Upper", "Approximated contant cost 60% confidence upper limit", "us", QP_KEY_TAG_TIME, theilSenFitting.offsetConfidenceUpper)
			<< tcu::TestLog::Float("ApproximatedLinearCost", "Approximated linear cost", "us / MB", QP_KEY_TAG_TIME, theilSenFitting.coefficient * 1024.0f * 1024.0f)
			<< tcu::TestLog::Float("ApproximatedLinearCostConfidence60Lower", "Approximated linear cost 60% confidence lower limit", "us / MB", QP_KEY_TAG_TIME, theilSenFitting.coefficientConfidenceLower * 1024.0f * 1024.0f)
			<< tcu::TestLog::Float("ApproximatedLinearCostConfidence60Upper", "Approximated linear cost 60% confidence upper limit", "us / MB", QP_KEY_TAG_TIME, theilSenFitting.coefficientConfidenceUpper * 1024.0f * 1024.0f)
			<< tcu::TestLog::Float("ApproximatedTransferRate", "Approximated transfer rate", "MB / s", QP_KEY_TAG_PERFORMANCE, approximatedTransferRate / 1024.0f / 1024.0f)
			<< tcu::TestLog::Float("ApproximatedTransferRateNoConstant", "Approximated transfer rate without constant cost", "MB / s", QP_KEY_TAG_PERFORMANCE, approximatedTransferRateNoConstant / 1024.0f / 1024.0f)
			<< tcu::TestLog::Float("SampleMedianTime", "Median sample time", "us", QP_KEY_TAG_TIME, resultStats.result.medianTime)
			<< tcu::TestLog::Float("SampleMedianTransfer", "Median transfer rate", "MB / s", QP_KEY_TAG_PERFORMANCE, resultStats.medianRate / 1024.0f / 1024.0f);
	}

	// return approximated transfer rate
	{
		UploadSampleAnalyzeResult result;

		result.transferRateMedian = resultStats.medianRate;
		result.transferRateAtRange = approximatedTransferRate;
		result.transferRateAtInfinity = approximatedTransferRateNoConstant;

		return result;
	}
}

template <typename SampleType>
static RenderSampleAnalyzeResult analyzeSampleResults (tcu::TestLog& log, const std::vector<RenderSampleResult<SampleType> >& samples)
{
	// Assume data is linear with some outliers, fit a line
	const LineParametersWithConfidence						theilSenFitting						= fitLineToSamples(samples);
	const typename SampleTypeTraits<SampleType>::StatsType	resultStats							= calculateSampleStatistics(theilSenFitting, samples);
	float													approximatedProcessingRate;
	float													approximatedProcessingRateNoConstant;

	// output raw samples
	{
		const tcu::ScopedLogSection	section(log, "Samples", "Samples");
		logSampleList(log, theilSenFitting, samples);
	}

	// Contributions
	if (SampleTypeTraits<SampleType>::LOG_CONTRIBUTIONS)
	{
		const tcu::ScopedLogSection	section(log, "Contribution", "Contributions");

		logFirstRenderContribution(log, samples, resultStats);
		logUploadContribution(log, samples, resultStats);
		logRenderContribution(log, samples, resultStats);
		logSecondRenderContribution(log, samples, resultStats);
		logReadContribution(log, samples, resultStats);
		logTotalContribution(log, samples, resultStats);
	}

	// print results
	{
		const tcu::ScopedLogSection	section(log, "Results", "Results");

		const int	medianDataSize						= (samples.front().renderDataSize + samples.back().renderDataSize) / 2;
		const float	approximatedRenderTime				= (theilSenFitting.offset + theilSenFitting.coefficient * (float)medianDataSize) / 1000.0f / 1000.0f;
		const float	approximatedRenderTimeNoConstant	= (theilSenFitting.coefficient * (float)medianDataSize) / 1000.0f / 1000.0f;
		const float	sampleLinearity						= calculateSampleFitLinearity(samples);
		const float	sampleTemporalStability				= calculateSampleTemporalStability(samples);

		approximatedProcessingRateNoConstant			= (float)medianDataSize / approximatedRenderTimeNoConstant;
		approximatedProcessingRate						= (float)medianDataSize / approximatedRenderTime;

		log	<< tcu::TestLog::Float("ResultLinearity", "Sample linearity", "%", QP_KEY_TAG_QUALITY, sampleLinearity * 100.0f)
			<< tcu::TestLog::Float("SampleTemporalStability", "Sample temporal stability", "%", QP_KEY_TAG_QUALITY, sampleTemporalStability * 100.0f)
			<< tcu::TestLog::Float("ApproximatedConstantCost", "Approximated contant cost", "us", QP_KEY_TAG_TIME, theilSenFitting.offset)
			<< tcu::TestLog::Float("ApproximatedConstantCostConfidence60Lower", "Approximated contant cost 60% confidence lower limit", "us", QP_KEY_TAG_TIME, theilSenFitting.offsetConfidenceLower)
			<< tcu::TestLog::Float("ApproximatedConstantCostConfidence60Upper", "Approximated contant cost 60% confidence upper limit", "us", QP_KEY_TAG_TIME, theilSenFitting.offsetConfidenceUpper)
			<< tcu::TestLog::Float("ApproximatedLinearCost", "Approximated linear cost", "us / MB", QP_KEY_TAG_TIME, theilSenFitting.coefficient * 1024.0f * 1024.0f)
			<< tcu::TestLog::Float("ApproximatedLinearCostConfidence60Lower", "Approximated linear cost 60% confidence lower limit", "us / MB", QP_KEY_TAG_TIME, theilSenFitting.coefficientConfidenceLower * 1024.0f * 1024.0f)
			<< tcu::TestLog::Float("ApproximatedLinearCostConfidence60Upper", "Approximated linear cost 60% confidence upper limit", "us / MB", QP_KEY_TAG_TIME, theilSenFitting.coefficientConfidenceUpper * 1024.0f * 1024.0f)
			<< tcu::TestLog::Float("ApproximatedProcessRate", "Approximated processing rate", "MB / s", QP_KEY_TAG_PERFORMANCE, approximatedProcessingRate / 1024.0f / 1024.0f)
			<< tcu::TestLog::Float("ApproximatedProcessRateNoConstant", "Approximated processing rate without constant cost", "MB / s", QP_KEY_TAG_PERFORMANCE, approximatedProcessingRateNoConstant / 1024.0f / 1024.0f)
			<< tcu::TestLog::Float("SampleMedianTime", "Median sample time", "us", QP_KEY_TAG_TIME, resultStats.result.medianTime)
			<< tcu::TestLog::Float("SampleMedianProcess", "Median processing rate", "MB / s", QP_KEY_TAG_PERFORMANCE, resultStats.medianRate / 1024.0f / 1024.0f);
	}

	// return approximated render rate
	{
		RenderSampleAnalyzeResult result;

		result.renderRateMedian		= resultStats.medianRate;
		result.renderRateAtRange	= approximatedProcessingRate;
		result.renderRateAtInfinity = approximatedProcessingRateNoConstant;

		return result;
	}
	return RenderSampleAnalyzeResult();
}

static void generateTwoPassRandomIterationOrder (std::vector<int>& iterationOrder, int numSamples)
{
	de::Random	rnd			(0xabc);
	const int	midPoint	= (numSamples+1) / 2;		// !< ceil(m_numSamples / 2)

	DE_ASSERT((int)iterationOrder.size() == numSamples);

	// Two "passes" over range, randomize order in both passes
	// This allows to us detect if iterations are not independent
	// (first run and later run samples differ significantly?)

	for (int sampleNdx = 0; sampleNdx < midPoint; ++sampleNdx)
		iterationOrder[sampleNdx] = sampleNdx * 2;
	for (int sampleNdx = midPoint; sampleNdx < numSamples; ++sampleNdx)
		iterationOrder[sampleNdx] = (sampleNdx - midPoint) * 2 + 1;

	for (int ndx = 0; ndx < midPoint; ++ndx)
		std::swap(iterationOrder[ndx], iterationOrder[rnd.getInt(0, midPoint - 1)]);
	for (int ndx = midPoint; ndx < (int)iterationOrder.size(); ++ndx)
		std::swap(iterationOrder[ndx], iterationOrder[rnd.getInt(midPoint, (int)iterationOrder.size()-1)]);
}

template <typename SampleType>
class BasicBufferCase : public TestCase
{
public:

	enum Flags
	{
		FLAG_ALLOCATE_LARGER_BUFFER = 0x01,
	};
							BasicBufferCase		(Context& context, const char* name, const char* desc, int bufferSizeMin, int bufferSizeMax, int numSamples, int flags);
							~BasicBufferCase	(void);

	virtual void			init				(void);
	virtual void			deinit				(void);

protected:
	IterateResult			iterate				(void);

	virtual bool			runSample			(int iteration, UploadSampleResult<SampleType>& sample) = 0;
	virtual void			logAndSetTestResult	(const std::vector<UploadSampleResult<SampleType> >& results) = 0;

	void					disableGLWarmup		(void);
	void					waitGLResults		(void);

	enum
	{
		UNUSED_RENDER_AREA_SIZE = 32
	};

	glu::ShaderProgram*		m_minimalProgram;
	deInt32					m_minimalProgramPosLoc;
	deUint32				m_bufferID;

	const int				m_numSamples;
	const int				m_bufferSizeMin;
	const int				m_bufferSizeMax;
	const bool				m_allocateLargerBuffer;

private:
	int						m_iteration;
	std::vector<int>		m_iterationOrder;
	std::vector<UploadSampleResult<SampleType> > m_results;

	bool					m_useGL;
	int						m_bufferRandomizerTimer;
};

template <typename SampleType>
BasicBufferCase<SampleType>::BasicBufferCase (Context& context, const char* name, const char* desc, int bufferSizeMin, int bufferSizeMax, int numSamples, int flags)
	: TestCase					(context, tcu::NODETYPE_PERFORMANCE, name, desc)
	, m_minimalProgram			(DE_NULL)
	, m_minimalProgramPosLoc	(-1)
	, m_bufferID				(0)
	, m_numSamples				(numSamples)
	, m_bufferSizeMin			(bufferSizeMin)
	, m_bufferSizeMax			(bufferSizeMax)
	, m_allocateLargerBuffer	((flags & FLAG_ALLOCATE_LARGER_BUFFER) != 0)
	, m_iteration				(0)
	, m_iterationOrder			(numSamples)
	, m_results					(numSamples)
	, m_useGL					(true)
	, m_bufferRandomizerTimer	(0)
{
	// "randomize" iteration order. Deterministic, patternless
	generateTwoPassRandomIterationOrder(m_iterationOrder, m_numSamples);

	// choose buffer sizes
	for (int sampleNdx = 0; sampleNdx < m_numSamples; ++sampleNdx)
	{
		const int rawBufferSize			= (int)deFloatFloor((float)bufferSizeMin + (float)(bufferSizeMax - bufferSizeMin) * ((float)(sampleNdx + 1) / (float)m_numSamples));
		const int bufferSize			= deAlign32(rawBufferSize, 16);
		const int allocatedBufferSize	= deAlign32((m_allocateLargerBuffer) ? ((int)((float)bufferSize * 1.5f)) : (bufferSize), 16);

		m_results[sampleNdx].bufferSize		= bufferSize;
		m_results[sampleNdx].allocatedSize	= allocatedBufferSize;
		m_results[sampleNdx].writtenSize	= -1;
	}
}

template <typename SampleType>
BasicBufferCase<SampleType>::~BasicBufferCase (void)
{
	deinit();
}

template <typename SampleType>
void BasicBufferCase<SampleType>::init (void)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (!m_useGL)
		return;

	// \note Viewport size is not checked, it won't matter if the render target actually is smaller than UNUSED_RENDER_AREA_SIZE

	// minimal shader

	m_minimalProgram = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(s_minimalVertexShader) << glu::FragmentSource(s_minimalFragnentShader));
	if (!m_minimalProgram->isOk())
	{
		m_testCtx.getLog() << *m_minimalProgram;
		throw tcu::TestError("failed to build shader program");
	}

	m_minimalProgramPosLoc = gl.getAttribLocation(m_minimalProgram->getProgram(), "a_position");
	if (m_minimalProgramPosLoc == -1)
		throw tcu::TestError("a_position location was -1");
}

template <typename SampleType>
void BasicBufferCase<SampleType>::deinit (void)
{
	if (m_bufferID)
	{
		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_bufferID);
		m_bufferID = 0;
	}

	delete m_minimalProgram;
	m_minimalProgram = DE_NULL;
}

template <typename SampleType>
TestCase::IterateResult BasicBufferCase<SampleType>::iterate (void)
{
	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
	static bool				buffersWarmedUp	= false;

	static const deUint32	usages[] =
	{
		GL_STREAM_DRAW, GL_STREAM_READ, GL_STREAM_COPY,
		GL_STATIC_DRAW, GL_STATIC_READ, GL_STATIC_COPY,
		GL_DYNAMIC_DRAW, GL_DYNAMIC_READ, GL_DYNAMIC_COPY,
	};

	// Allocate some random sized buffers and remove them to
	// make sure the first samples too have some buffers removed
	// just before their allocation. This is only needed by the
	// the first test.

	if (m_useGL && !buffersWarmedUp)
	{
		const int					numRandomBuffers				= 6;
		const int					numRepeats						= 10;
		const int					maxBufferSize					= 16777216;
		const std::vector<deUint8>	zeroData						(maxBufferSize, 0x00);
		de::Random					rnd								(0x1234);
		deUint32					bufferIDs[numRandomBuffers]		= {0};

		gl.useProgram(m_minimalProgram->getProgram());
		gl.viewport(0, 0, UNUSED_RENDER_AREA_SIZE, UNUSED_RENDER_AREA_SIZE);
		gl.enableVertexAttribArray(m_minimalProgramPosLoc);

		for (int ndx = 0; ndx < numRepeats; ++ndx)
		{
			// Create buffer and maybe draw from it
			for (int randomBufferNdx = 0; randomBufferNdx < numRandomBuffers; ++randomBufferNdx)
			{
				const int		randomSize	= deAlign32(rnd.getInt(1, maxBufferSize), 4*4);
				const deUint32	usage		= usages[rnd.getUint32() % (deUint32)DE_LENGTH_OF_ARRAY(usages)];

				gl.genBuffers(1, &bufferIDs[randomBufferNdx]);
				gl.bindBuffer(GL_ARRAY_BUFFER, bufferIDs[randomBufferNdx]);
				gl.bufferData(GL_ARRAY_BUFFER, randomSize, &zeroData[0], usage);

				if (rnd.getBool())
				{
					gl.vertexAttribPointer(m_minimalProgramPosLoc, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
					gl.drawArrays(GL_POINTS, 0, 1);
					gl.drawArrays(GL_POINTS, randomSize / (int)sizeof(float[4]) - 1, 1);
				}
			}

			for (int randomBufferNdx = 0; randomBufferNdx < numRandomBuffers; ++randomBufferNdx)
				gl.deleteBuffers(1, &bufferIDs[randomBufferNdx]);

			waitGLResults();
			GLU_EXPECT_NO_ERROR(gl.getError(), "Buffer gen");

			m_testCtx.touchWatchdog();
		}

		buffersWarmedUp = true;
		return CONTINUE;
	}
	else if (m_useGL && m_bufferRandomizerTimer++ % 8 == 0)
	{
		// Do some random buffer operations to every now and then
		// to make sure the previous test iterations won't affect
		// following test runs.

		const int					numRandomBuffers				= 3;
		const int					maxBufferSize					= 16777216;
		const std::vector<deUint8>	zeroData						(maxBufferSize, 0x00);
		de::Random					rnd								(0x1234 + 0xabc * m_bufferRandomizerTimer);

		// BufferData
		{
			deUint32 bufferIDs[numRandomBuffers] = {0};

			for (int randomBufferNdx = 0; randomBufferNdx < numRandomBuffers; ++randomBufferNdx)
			{
				const int		randomSize	= deAlign32(rnd.getInt(1, maxBufferSize), 4*4);
				const deUint32	usage		= usages[rnd.getUint32() % (deUint32)DE_LENGTH_OF_ARRAY(usages)];

				gl.genBuffers(1, &bufferIDs[randomBufferNdx]);
				gl.bindBuffer(GL_ARRAY_BUFFER, bufferIDs[randomBufferNdx]);
				gl.bufferData(GL_ARRAY_BUFFER, randomSize, &zeroData[0], usage);
			}

			for (int randomBufferNdx = 0; randomBufferNdx < numRandomBuffers; ++randomBufferNdx)
				gl.deleteBuffers(1, &bufferIDs[randomBufferNdx]);
		}

		GLU_EXPECT_NO_ERROR(gl.getError(), "buffer ops");

		// Do some memory mappings
		{
			deUint32 bufferIDs[numRandomBuffers] = {0};

			for (int randomBufferNdx = 0; randomBufferNdx < numRandomBuffers; ++randomBufferNdx)
			{
				const int		randomSize	= deAlign32(rnd.getInt(1, maxBufferSize), 4*4);
				const deUint32	usage		= usages[rnd.getUint32() % (deUint32)DE_LENGTH_OF_ARRAY(usages)];
				void*			ptr;

				gl.genBuffers(1, &bufferIDs[randomBufferNdx]);
				gl.bindBuffer(GL_ARRAY_BUFFER, bufferIDs[randomBufferNdx]);
				gl.bufferData(GL_ARRAY_BUFFER, randomSize, &zeroData[0], usage);

				gl.vertexAttribPointer(m_minimalProgramPosLoc, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
				gl.drawArrays(GL_POINTS, 0, 1);
				gl.drawArrays(GL_POINTS, randomSize / (int)sizeof(float[4]) - 1, 1);

				if (rnd.getBool())
					waitGLResults();

				ptr = gl.mapBufferRange(GL_ARRAY_BUFFER, 0, randomSize, GL_MAP_WRITE_BIT);
				if (ptr)
				{
					medianTimeMemcpy(ptr, &zeroData[0], randomSize);
					gl.unmapBuffer(GL_ARRAY_BUFFER);
				}
			}

			for (int randomBufferNdx = 0; randomBufferNdx < numRandomBuffers; ++randomBufferNdx)
				gl.deleteBuffers(1, &bufferIDs[randomBufferNdx]);

			waitGLResults();
		}

		GLU_EXPECT_NO_ERROR(gl.getError(), "buffer maps");
		return CONTINUE;
	}
	else
	{
		const int	currentIteration	= m_iteration;
		const int	sampleNdx			= m_iterationOrder[currentIteration];
		const bool	sampleRunSuccessful	= runSample(currentIteration, m_results[sampleNdx]);

		GLU_EXPECT_NO_ERROR(gl.getError(), "post runSample()");

		// Retry failed samples
		if (!sampleRunSuccessful)
			return CONTINUE;

		if (++m_iteration >= m_numSamples)
		{
			logAndSetTestResult(m_results);
			return STOP;
		}
		else
			return CONTINUE;
	}
}

template <typename SampleType>
void BasicBufferCase<SampleType>::disableGLWarmup (void)
{
	m_useGL = false;
}

template <typename SampleType>
void BasicBufferCase<SampleType>::waitGLResults (void)
{
	tcu::Surface unusedSurface(UNUSED_RENDER_AREA_SIZE, UNUSED_RENDER_AREA_SIZE);
	glu::readPixels(m_context.getRenderContext(), 0, 0, unusedSurface.getAccess());
}

template <typename SampleType>
class BasicUploadCase : public BasicBufferCase<SampleType>
{
public:
	enum CaseType
	{
		CASE_NO_BUFFERS = 0,
		CASE_NEW_BUFFER,
		CASE_UNSPECIFIED_BUFFER,
		CASE_SPECIFIED_BUFFER,
		CASE_USED_BUFFER,
		CASE_USED_LARGER_BUFFER,

		CASE_LAST
	};

	enum CaseFlags
	{
		FLAG_DONT_LOG_BUFFER_INFO				= 0x01,
		FLAG_RESULT_BUFFER_UNSPECIFIED_CONTENT	= 0x02,
	};

	enum ResultType
	{
		RESULT_MEDIAN_TRANSFER_RATE = 0,
		RESULT_ASYMPTOTIC_TRANSFER_RATE,
	};

						BasicUploadCase		(Context& context,
											 const char* name,
											 const char* desc,
											 int bufferSizeMin,
											 int bufferSizeMax,
											 int numSamples,
											 deUint32 bufferUsage,
											 CaseType caseType,
											 ResultType resultType,
											 int flags = 0);

						~BasicUploadCase	(void);

	virtual void		init				(void);
	virtual void		deinit				(void);

private:
	bool				runSample			(int iteration, UploadSampleResult<SampleType>& sample);
	void				createBuffer		(int bufferSize, int iteration);
	void				deleteBuffer		(int bufferSize);
	void				useBuffer			(int bufferSize);

	virtual void		testBufferUpload	(UploadSampleResult<SampleType>& result, int writeSize) = 0;
	void				logAndSetTestResult	(const std::vector<UploadSampleResult<SampleType> >& results);

	deUint32			m_unusedBufferID;

protected:
	const CaseType		m_caseType;
	const ResultType	m_resultType;
	const deUint32		m_bufferUsage;
	const bool			m_logBufferInfo;
	const bool			m_bufferUnspecifiedContent;
	std::vector<deUint8> m_zeroData;

	using BasicBufferCase<SampleType>::m_testCtx;
	using BasicBufferCase<SampleType>::m_context;

	using BasicBufferCase<SampleType>::UNUSED_RENDER_AREA_SIZE;
	using BasicBufferCase<SampleType>::m_minimalProgram;
	using BasicBufferCase<SampleType>::m_minimalProgramPosLoc;
	using BasicBufferCase<SampleType>::m_bufferID;
	using BasicBufferCase<SampleType>::m_numSamples;
	using BasicBufferCase<SampleType>::m_bufferSizeMin;
	using BasicBufferCase<SampleType>::m_bufferSizeMax;
	using BasicBufferCase<SampleType>::m_allocateLargerBuffer;
};

template <typename SampleType>
BasicUploadCase<SampleType>::BasicUploadCase (Context& context, const char* name, const char* desc, int bufferSizeMin, int bufferSizeMax, int numSamples, deUint32 bufferUsage, CaseType caseType, ResultType resultType, int flags)
	: BasicBufferCase<SampleType>	(context, name, desc, bufferSizeMin, bufferSizeMax, numSamples, (caseType == CASE_USED_LARGER_BUFFER) ? (BasicBufferCase<SampleType>::FLAG_ALLOCATE_LARGER_BUFFER) : (0))
	, m_unusedBufferID				(0)
	, m_caseType					(caseType)
	, m_resultType					(resultType)
	, m_bufferUsage					(bufferUsage)
	, m_logBufferInfo				((flags & FLAG_DONT_LOG_BUFFER_INFO) == 0)
	, m_bufferUnspecifiedContent	((flags & FLAG_RESULT_BUFFER_UNSPECIFIED_CONTENT) != 0)
	, m_zeroData					()
{
	DE_ASSERT(m_caseType < CASE_LAST);
}

template <typename SampleType>
BasicUploadCase<SampleType>::~BasicUploadCase (void)
{
	deinit();
}

template <typename SampleType>
void BasicUploadCase<SampleType>::init (void)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	BasicBufferCase<SampleType>::init();

	// zero buffer as upload source
	m_zeroData.resize(m_bufferSizeMax, 0x00);

	// unused buffer

	gl.genBuffers(1, &m_unusedBufferID);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Gen buf");

	// log basic info

	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Testing performance with " << m_numSamples << " test samples. Sample order is randomized. All samples at even positions (first = 0) are tested before samples at odd positions.\n"
		<< "Buffer sizes are in range [" << getHumanReadableByteSize(m_bufferSizeMin) << ", " << getHumanReadableByteSize(m_bufferSizeMax) << "]."
		<< tcu::TestLog::EndMessage;

	if (m_logBufferInfo)
	{
		switch (m_caseType)
		{
			case CASE_NO_BUFFERS:
				break;

			case CASE_NEW_BUFFER:
				m_testCtx.getLog() << tcu::TestLog::Message << "Target buffer is generated but not specified (i.e glBufferData() not called)." << tcu::TestLog::EndMessage;
				break;

			case CASE_UNSPECIFIED_BUFFER:
				m_testCtx.getLog() << tcu::TestLog::Message << "Target buffer is allocated with glBufferData(NULL)." << tcu::TestLog::EndMessage;
				break;

			case CASE_SPECIFIED_BUFFER:
				m_testCtx.getLog() << tcu::TestLog::Message << "Target buffer contents are specified prior testing with glBufferData(data)." << tcu::TestLog::EndMessage;
				break;

			case CASE_USED_BUFFER:
				m_testCtx.getLog() << tcu::TestLog::Message << "Target buffer has been used in drawing before testing." << tcu::TestLog::EndMessage;
				break;

			case CASE_USED_LARGER_BUFFER:
				m_testCtx.getLog() << tcu::TestLog::Message << "Target buffer is larger and has been used in drawing before testing." << tcu::TestLog::EndMessage;
				break;

			default:
				DE_ASSERT(false);
				break;
		}
	}

	if (m_resultType == RESULT_MEDIAN_TRANSFER_RATE)
		m_testCtx.getLog() << tcu::TestLog::Message << "Test result is the median transfer rate of the test samples." << tcu::TestLog::EndMessage;
	else if (m_resultType == RESULT_ASYMPTOTIC_TRANSFER_RATE)
		m_testCtx.getLog() << tcu::TestLog::Message << "Test result is the asymptotic transfer rate as the buffer size approaches infinity." << tcu::TestLog::EndMessage;
	else
		DE_ASSERT(false);
}

template <typename SampleType>
void BasicUploadCase<SampleType>::deinit (void)
{
	if (m_unusedBufferID)
	{
		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_unusedBufferID);
		m_unusedBufferID = 0;
	}

	m_zeroData = std::vector<deUint8>();

	BasicBufferCase<SampleType>::deinit();
}

template <typename SampleType>
bool BasicUploadCase<SampleType>::runSample (int iteration, UploadSampleResult<SampleType>& sample)
{
	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
	const int				allocatedBufferSize	= sample.allocatedSize;
	const int				bufferSize			= sample.bufferSize;

	if (m_caseType != CASE_NO_BUFFERS)
		createBuffer(iteration, allocatedBufferSize);

	// warmup CPU before the test to make sure the power management governor
	// keeps us in the "high performance" mode
	{
		deYield();
		tcu::warmupCPU();
		deYield();
	}

	testBufferUpload(sample, bufferSize);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Buffer upload sample");

	if (m_caseType != CASE_NO_BUFFERS)
		deleteBuffer(bufferSize);

	return true;
}

template <typename SampleType>
void BasicUploadCase<SampleType>::createBuffer (int iteration, int bufferSize)
{
	DE_ASSERT(!m_bufferID);
	DE_ASSERT(m_caseType != CASE_NO_BUFFERS);

	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	// create buffer

	if (m_caseType == CASE_NO_BUFFERS)
		return;

	// create empty buffer

	gl.genBuffers(1, &m_bufferID);
	gl.bindBuffer(GL_ARRAY_BUFFER, m_bufferID);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Buffer gen");

	if (m_caseType == CASE_NEW_BUFFER)
	{
		// upload something else first, this should reduce noise in samples

		de::Random					rng				(0xbadc * iteration);
		const int					sizeDelta		= rng.getInt(0, 2097140);
		const int					unusedUploadSize = deAlign32(1048576 + sizeDelta, 4*4); // Vary buffer size to make sure it is always reallocated
		const std::vector<deUint8>	unusedData		(unusedUploadSize, 0x20);

		gl.bindBuffer(GL_ARRAY_BUFFER, m_unusedBufferID);
		gl.bufferData(GL_ARRAY_BUFFER, unusedUploadSize, &unusedData[0], m_bufferUsage);

		// make sure upload won't interfere with the test
		useBuffer(unusedUploadSize);

		// don't kill the buffer so that the following upload cannot potentially reuse the buffer

		return;
	}

	// specify it

	if (m_caseType == CASE_UNSPECIFIED_BUFFER)
		gl.bufferData(GL_ARRAY_BUFFER, bufferSize, DE_NULL, m_bufferUsage);
	else
	{
		const std::vector<deUint8> unusedData(bufferSize, 0x20);
		gl.bufferData(GL_ARRAY_BUFFER, bufferSize, &unusedData[0], m_bufferUsage);
	}

	if (m_caseType == CASE_UNSPECIFIED_BUFFER || m_caseType == CASE_SPECIFIED_BUFFER)
		return;

	// use it and make sure it is uploaded

	useBuffer(bufferSize);
	DE_ASSERT(m_caseType == CASE_USED_BUFFER || m_caseType == CASE_USED_LARGER_BUFFER);
}

template <typename SampleType>
void BasicUploadCase<SampleType>::deleteBuffer (int bufferSize)
{
	DE_ASSERT(m_bufferID);
	DE_ASSERT(m_caseType != CASE_NO_BUFFERS);

	// render from the buffer to make sure it actually made it to the gpu. This is to
	// make sure that if the upload actually happens later or is happening right now in
	// the background, it will not interfere with further test runs

	// if buffer contains unspecified content, sourcing data from it results in undefined
	// results, possibly including program termination. Specify all data to prevent such
	// case from happening

	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.bindBuffer(GL_ARRAY_BUFFER, m_bufferID);

	if (m_bufferUnspecifiedContent)
	{
		const std::vector<deUint8> unusedData(bufferSize, 0x20);
		gl.bufferData(GL_ARRAY_BUFFER, bufferSize, &unusedData[0], m_bufferUsage);

		GLU_EXPECT_NO_ERROR(gl.getError(), "re-specify buffer");
	}

	useBuffer(bufferSize);

	gl.deleteBuffers(1, &m_bufferID);
	m_bufferID = 0;
}

template <typename SampleType>
void BasicUploadCase<SampleType>::useBuffer (int bufferSize)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.useProgram(m_minimalProgram->getProgram());

	gl.viewport(0, 0, UNUSED_RENDER_AREA_SIZE, UNUSED_RENDER_AREA_SIZE);
	gl.vertexAttribPointer(m_minimalProgramPosLoc, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
	gl.enableVertexAttribArray(m_minimalProgramPosLoc);

	// use whole buffer to make sure buffer is uploaded by drawing first and last
	DE_ASSERT(bufferSize % (int)sizeof(float[4]) == 0);
	gl.drawArrays(GL_POINTS, 0, 1);
	gl.drawArrays(GL_POINTS, bufferSize / (int)sizeof(float[4]) - 1, 1);

	BasicBufferCase<SampleType>::waitGLResults();
}

template <typename SampleType>
void BasicUploadCase<SampleType>::logAndSetTestResult (const std::vector<UploadSampleResult<SampleType> >& results)
{
	const UploadSampleAnalyzeResult	analysis	= analyzeSampleResults(m_testCtx.getLog(), results, true);

	// with small buffers, report the median transfer rate of the samples
	// with large buffers, report the expected preformance of infinitely large buffers
	const float						rate		= (m_resultType == RESULT_ASYMPTOTIC_TRANSFER_RATE) ? (analysis.transferRateAtInfinity) : (analysis.transferRateMedian);

	if (rate == std::numeric_limits<float>::infinity())
	{
		// sample times are 1) invalid or 2) timer resolution too low
		// report speed 0 bytes / s since real value cannot be determined
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::floatToString(0.0f, 2).c_str());
	}
	else
	{
		// report transfer rate in MB / s
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::floatToString(rate / 1024.0f / 1024.0f, 2).c_str());
	}
}

class ReferenceMemcpyCase : public BasicUploadCase<SingleOperationDuration>
{
public:
				ReferenceMemcpyCase		(Context& ctx, const char* name, const char* desc, int minBufferSize, int maxBufferSize, int numSamples, bool largeBuffersCase);
				~ReferenceMemcpyCase	(void);

	void		init					(void);
	void		deinit					(void);
private:
	void		testBufferUpload		(UploadSampleResult<SingleOperationDuration>& result, int bufferSize);

	std::vector<deUint8> m_dstBuf;
};

ReferenceMemcpyCase::ReferenceMemcpyCase (Context& ctx, const char* name, const char* desc, int minBufferSize, int maxBufferSize, int numSamples, bool largeBuffersCase)
	: BasicUploadCase<SingleOperationDuration>	(ctx, name, desc, minBufferSize, maxBufferSize, numSamples, 0, CASE_NO_BUFFERS, (largeBuffersCase) ? (RESULT_ASYMPTOTIC_TRANSFER_RATE) : (RESULT_MEDIAN_TRANSFER_RATE))
	, m_dstBuf									()
{
	disableGLWarmup();
}

ReferenceMemcpyCase::~ReferenceMemcpyCase (void)
{
}

void ReferenceMemcpyCase::init (void)
{
	// Describe what the test tries to do
	m_testCtx.getLog() << tcu::TestLog::Message << "Testing performance of memcpy()." << tcu::TestLog::EndMessage;

	m_dstBuf.resize(m_bufferSizeMax, 0x00);

	BasicUploadCase<SingleOperationDuration>::init();
}

void ReferenceMemcpyCase::deinit (void)
{
	m_dstBuf = std::vector<deUint8>();
	BasicUploadCase<SingleOperationDuration>::deinit();
}

void ReferenceMemcpyCase::testBufferUpload (UploadSampleResult<SingleOperationDuration>& result, int bufferSize)
{
	// write
	result.duration.totalDuration = medianTimeMemcpy(&m_dstBuf[0], &m_zeroData[0], bufferSize);
	result.duration.fitResponseDuration = result.duration.totalDuration;

	result.writtenSize = bufferSize;
}

class BufferDataUploadCase : public BasicUploadCase<SingleOperationDuration>
{
public:
				BufferDataUploadCase	(Context& ctx, const char* name, const char* desc, int minBufferSize, int maxBufferSize, int numSamples, deUint32 bufferUsage, CaseType caseType);
				~BufferDataUploadCase	(void);

	void		init					(void);
private:
	void		testBufferUpload		(UploadSampleResult<SingleOperationDuration>& result, int bufferSize);
};

BufferDataUploadCase::BufferDataUploadCase (Context& ctx, const char* name, const char* desc, int minBufferSize, int maxBufferSize, int numSamples, deUint32 bufferUsage, CaseType caseType)
	: BasicUploadCase<SingleOperationDuration>(ctx, name, desc, minBufferSize, maxBufferSize, numSamples, bufferUsage, caseType, RESULT_MEDIAN_TRANSFER_RATE)
{
}

BufferDataUploadCase::~BufferDataUploadCase (void)
{
}

void BufferDataUploadCase::init (void)
{
	// Describe what the test tries to do
	m_testCtx.getLog() << tcu::TestLog::Message << "Testing glBufferData() function." << tcu::TestLog::EndMessage;

	BasicUploadCase<SingleOperationDuration>::init();
}

void BufferDataUploadCase::testBufferUpload (UploadSampleResult<SingleOperationDuration>& result, int bufferSize)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.bindBuffer(GL_ARRAY_BUFFER, m_bufferID);

	// upload
	{
		deUint64 startTime;
		deUint64 endTime;

		startTime = deGetMicroseconds();
		gl.bufferData(GL_ARRAY_BUFFER, bufferSize, &m_zeroData[0], m_bufferUsage);
		endTime = deGetMicroseconds();

		result.duration.totalDuration = endTime - startTime;
		result.duration.fitResponseDuration = result.duration.totalDuration;
		result.writtenSize = bufferSize;
	}
}

class BufferSubDataUploadCase : public BasicUploadCase<SingleOperationDuration>
{
public:
	enum Flags
	{
		FLAG_FULL_UPLOAD			= 0x01,
		FLAG_PARTIAL_UPLOAD			= 0x02,
		FLAG_INVALIDATE_BEFORE_USE	= 0x04,
	};

				BufferSubDataUploadCase		(Context& ctx, const char* name, const char* desc, int minBufferSize, int maxBufferSize, int numSamples, deUint32 bufferUsage, CaseType parentCase, int flags);
				~BufferSubDataUploadCase	(void);

	void		init						(void);
private:
	void		testBufferUpload			(UploadSampleResult<SingleOperationDuration>& result, int bufferSize);

	const bool	m_fullUpload;
	const bool	m_invalidateBeforeUse;
};

BufferSubDataUploadCase::BufferSubDataUploadCase (Context& ctx, const char* name, const char* desc, int minBufferSize, int maxBufferSize, int numSamples, deUint32 bufferUsage, CaseType parentCase, int flags)
	: BasicUploadCase<SingleOperationDuration>	(ctx, name, desc, minBufferSize, maxBufferSize, numSamples, bufferUsage, parentCase, RESULT_MEDIAN_TRANSFER_RATE)
	, m_fullUpload								((flags & FLAG_FULL_UPLOAD) != 0)
	, m_invalidateBeforeUse						((flags & FLAG_INVALIDATE_BEFORE_USE) != 0)
{
	DE_ASSERT((flags & (FLAG_FULL_UPLOAD | FLAG_PARTIAL_UPLOAD)) != 0);
	DE_ASSERT((flags & (FLAG_FULL_UPLOAD | FLAG_PARTIAL_UPLOAD)) != (FLAG_FULL_UPLOAD | FLAG_PARTIAL_UPLOAD));
}

BufferSubDataUploadCase::~BufferSubDataUploadCase (void)
{
}

void BufferSubDataUploadCase::init (void)
{
	// Describe what the test tries to do
	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Testing glBufferSubData() function call performance. "
		<< ((m_fullUpload) ? ("The whole buffer is updated with glBufferSubData. ") : ("Half of the buffer data is updated with glBufferSubData. "))
		<< ((m_invalidateBeforeUse) ? ("The buffer is cleared with glBufferData(..., NULL) before glBufferSubData upload.") : ("")) << "\n"
		<< tcu::TestLog::EndMessage;

	BasicUploadCase<SingleOperationDuration>::init();
}

void BufferSubDataUploadCase::testBufferUpload (UploadSampleResult<SingleOperationDuration>& result, int bufferSize)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.bindBuffer(GL_ARRAY_BUFFER, m_bufferID);

	// "invalidate", upload null
	if (m_invalidateBeforeUse)
		gl.bufferData(GL_ARRAY_BUFFER, bufferSize, DE_NULL, m_bufferUsage);

	// upload
	{
		deUint64 startTime;
		deUint64 endTime;

		startTime = deGetMicroseconds();

		if (m_fullUpload)
			gl.bufferSubData(GL_ARRAY_BUFFER, 0, bufferSize, &m_zeroData[0]);
		else
		{
			// upload to buffer center
			gl.bufferSubData(GL_ARRAY_BUFFER, bufferSize / 4, bufferSize / 2, &m_zeroData[0]);
		}

		endTime = deGetMicroseconds();

		result.duration.totalDuration = endTime - startTime;
		result.duration.fitResponseDuration = result.duration.totalDuration;

		if (m_fullUpload)
			result.writtenSize = bufferSize;
		else
			result.writtenSize = bufferSize / 2;
	}
}

class MapBufferRangeCase : public BasicUploadCase<MapBufferRangeDuration>
{
public:
	enum Flags
	{
		FLAG_PARTIAL						= 0x01,
		FLAG_MANUAL_INVALIDATION			= 0x02,
		FLAG_USE_UNUSED_UNSPECIFIED_BUFFER	= 0x04,
		FLAG_USE_UNUSED_SPECIFIED_BUFFER	= 0x08,
	};

					MapBufferRangeCase			(Context& ctx, const char* name, const char* desc, int minBufferSize, int maxBufferSize, int numSamples, deUint32 bufferUsage, deUint32 mapFlags, int caseFlags);
					~MapBufferRangeCase			(void);

	void			init						(void);
private:
	static CaseType getBaseCaseType				(int caseFlags);
	static int		getBaseFlags				(deUint32 mapFlags, int caseFlags);

	void			testBufferUpload			(UploadSampleResult<MapBufferRangeDuration>& result, int bufferSize);
	void			attemptBufferMap			(UploadSampleResult<MapBufferRangeDuration>& result, int bufferSize);

	const bool		m_manualInvalidation;
	const bool		m_fullUpload;
	const bool		m_useUnusedUnspecifiedBuffer;
	const bool		m_useUnusedSpecifiedBuffer;
	const deUint32	m_mapFlags;
	int				m_unmapFailures;
};

MapBufferRangeCase::MapBufferRangeCase (Context& ctx, const char* name, const char* desc, int minBufferSize, int maxBufferSize, int numSamples, deUint32 bufferUsage, deUint32 mapFlags, int caseFlags)
	: BasicUploadCase<MapBufferRangeDuration>	(ctx, name, desc, minBufferSize, maxBufferSize, numSamples, bufferUsage, getBaseCaseType(caseFlags), RESULT_MEDIAN_TRANSFER_RATE, getBaseFlags(mapFlags, caseFlags))
	, m_manualInvalidation						((caseFlags&FLAG_MANUAL_INVALIDATION) != 0)
	, m_fullUpload								((caseFlags&FLAG_PARTIAL) == 0)
	, m_useUnusedUnspecifiedBuffer				((caseFlags&FLAG_USE_UNUSED_UNSPECIFIED_BUFFER) != 0)
	, m_useUnusedSpecifiedBuffer				((caseFlags&FLAG_USE_UNUSED_SPECIFIED_BUFFER) != 0)
	, m_mapFlags								(mapFlags)
	, m_unmapFailures							(0)
{
	DE_ASSERT(!(m_useUnusedUnspecifiedBuffer && m_useUnusedSpecifiedBuffer));
	DE_ASSERT(!((m_useUnusedUnspecifiedBuffer || m_useUnusedSpecifiedBuffer) && m_manualInvalidation));
}

MapBufferRangeCase::~MapBufferRangeCase (void)
{
}

void MapBufferRangeCase::init (void)
{
	// Describe what the test tries to do
	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Testing glMapBufferRange() and glUnmapBuffer() function call performance.\n"
		<< ((m_fullUpload) ? ("The whole buffer is mapped.") : ("Half of the buffer is mapped.")) << "\n"
		<< ((m_useUnusedUnspecifiedBuffer) ? ("The buffer has not been used before mapping and is allocated with unspecified contents.\n") : (""))
		<< ((m_useUnusedSpecifiedBuffer) ? ("The buffer has not been used before mapping and is allocated with specified contents.\n") : (""))
		<< ((!m_useUnusedSpecifiedBuffer && !m_useUnusedUnspecifiedBuffer) ? ("The buffer has previously been used in a drawing operation.\n") : (""))
		<< ((m_manualInvalidation) ? ("The buffer is cleared with glBufferData(..., NULL) before mapping.\n") : (""))
		<< "Map bits:\n"
		<< ((m_mapFlags & GL_MAP_WRITE_BIT) ? ("\tGL_MAP_WRITE_BIT\n") : (""))
		<< ((m_mapFlags & GL_MAP_READ_BIT) ? ("\tGL_MAP_READ_BIT\n") : (""))
		<< ((m_mapFlags & GL_MAP_INVALIDATE_RANGE_BIT) ? ("\tGL_MAP_INVALIDATE_RANGE_BIT\n") : (""))
		<< ((m_mapFlags & GL_MAP_INVALIDATE_BUFFER_BIT) ? ("\tGL_MAP_INVALIDATE_BUFFER_BIT\n") : (""))
		<< ((m_mapFlags & GL_MAP_UNSYNCHRONIZED_BIT) ? ("\tGL_MAP_UNSYNCHRONIZED_BIT\n") : (""))
		<< tcu::TestLog::EndMessage;

	BasicUploadCase<MapBufferRangeDuration>::init();
}

MapBufferRangeCase::CaseType MapBufferRangeCase::getBaseCaseType (int caseFlags)
{
	if ((caseFlags & FLAG_USE_UNUSED_UNSPECIFIED_BUFFER) == 0 && (caseFlags & FLAG_USE_UNUSED_SPECIFIED_BUFFER) == 0)
		return CASE_USED_BUFFER;
	else
		return CASE_NEW_BUFFER;
}

int MapBufferRangeCase::getBaseFlags (deUint32 mapFlags, int caseFlags)
{
	int flags = FLAG_DONT_LOG_BUFFER_INFO;

	// If buffer contains unspecified data when it is sourced (i.e drawn)
	// results are undefined, and system errors may occur. Signal parent
	// class to take this into account
	if (caseFlags & FLAG_PARTIAL)
	{
		if ((mapFlags & GL_MAP_INVALIDATE_BUFFER_BIT) != 0			||
			(caseFlags & FLAG_MANUAL_INVALIDATION) != 0				||
			(caseFlags & FLAG_USE_UNUSED_UNSPECIFIED_BUFFER) != 0)
		{
			flags |= FLAG_RESULT_BUFFER_UNSPECIFIED_CONTENT;
		}
	}

	return flags;
}

void MapBufferRangeCase::testBufferUpload (UploadSampleResult<MapBufferRangeDuration>& result, int bufferSize)
{
	const int unmapFailureThreshold = 4;

	for (; m_unmapFailures < unmapFailureThreshold; ++m_unmapFailures)
	{
		try
		{
			attemptBufferMap(result, bufferSize);
			return;
		}
		catch (UnmapFailureError&)
		{
		}
	}

	throw tcu::TestError("Unmapping failures exceeded limit");
}

void MapBufferRangeCase::attemptBufferMap (UploadSampleResult<MapBufferRangeDuration>& result, int bufferSize)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.bindBuffer(GL_ARRAY_BUFFER, m_bufferID);

	if (m_fullUpload)
		result.writtenSize = bufferSize;
	else
		result.writtenSize = bufferSize / 2;

	// Create unused buffer

	if (m_manualInvalidation || m_useUnusedUnspecifiedBuffer)
	{
		deUint64 startTime;
		deUint64 endTime;

		// "invalidate" or allocate, upload null
		startTime = deGetMicroseconds();
		gl.bufferData(GL_ARRAY_BUFFER, bufferSize, DE_NULL, m_bufferUsage);
		endTime = deGetMicroseconds();

		result.duration.allocDuration = endTime - startTime;
	}
	else if (m_useUnusedSpecifiedBuffer)
	{
		deUint64 startTime;
		deUint64 endTime;

		// Specify buffer contents
		startTime = deGetMicroseconds();
		gl.bufferData(GL_ARRAY_BUFFER, bufferSize, &m_zeroData[0], m_bufferUsage);
		endTime = deGetMicroseconds();

		result.duration.allocDuration = endTime - startTime;
	}
	else
	{
		// No alloc, no time
		result.duration.allocDuration = 0;
	}

	// upload
	{
		void* mapPtr;

		// Map
		{
			deUint64 startTime;
			deUint64 endTime;

			startTime = deGetMicroseconds();
			if (m_fullUpload)
				mapPtr = gl.mapBufferRange(GL_ARRAY_BUFFER, 0, result.writtenSize, m_mapFlags);
			else
			{
				// upload to buffer center
				mapPtr = gl.mapBufferRange(GL_ARRAY_BUFFER, bufferSize / 4, result.writtenSize, m_mapFlags);
			}
			endTime = deGetMicroseconds();

			if (!mapPtr)
				throw tcu::Exception("MapBufferRange returned NULL");

			result.duration.mapDuration = endTime - startTime;
		}

		// Write
		{
			result.duration.writeDuration = medianTimeMemcpy(mapPtr, &m_zeroData[0], result.writtenSize);
		}

		// Unmap
		{
			deUint64		startTime;
			deUint64		endTime;
			glw::GLboolean	unmapSuccessful;

			startTime = deGetMicroseconds();
			unmapSuccessful = gl.unmapBuffer(GL_ARRAY_BUFFER);
			endTime = deGetMicroseconds();

			// if unmapping fails, just try again later
			if (!unmapSuccessful)
				throw UnmapFailureError();

			result.duration.unmapDuration = endTime - startTime;
		}

		result.duration.totalDuration = result.duration.mapDuration + result.duration.writeDuration + result.duration.unmapDuration + result.duration.allocDuration;
		result.duration.fitResponseDuration = result.duration.totalDuration;
	}
}

class MapBufferRangeFlushCase : public BasicUploadCase<MapBufferRangeFlushDuration>
{
public:
	enum Flags
	{
		FLAG_PARTIAL						= 0x01,
		FLAG_FLUSH_IN_PARTS					= 0x02,
		FLAG_USE_UNUSED_UNSPECIFIED_BUFFER	= 0x04,
		FLAG_USE_UNUSED_SPECIFIED_BUFFER	= 0x08,
		FLAG_FLUSH_PARTIAL					= 0x10,
	};

					MapBufferRangeFlushCase		(Context& ctx, const char* name, const char* desc, int minBufferSize, int maxBufferSize, int numSamples, deUint32 bufferUsage, deUint32 mapFlags, int caseFlags);
					~MapBufferRangeFlushCase	(void);

	void			init						(void);
private:
	static CaseType getBaseCaseType				(int caseFlags);
	static int		getBaseFlags				(deUint32 mapFlags, int caseFlags);

	void			testBufferUpload			(UploadSampleResult<MapBufferRangeFlushDuration>& result, int bufferSize);
	void			attemptBufferMap			(UploadSampleResult<MapBufferRangeFlushDuration>& result, int bufferSize);

	const bool		m_fullUpload;
	const bool		m_flushInParts;
	const bool		m_flushPartial;
	const bool		m_useUnusedUnspecifiedBuffer;
	const bool		m_useUnusedSpecifiedBuffer;
	const deUint32	m_mapFlags;
	int				m_unmapFailures;
};

MapBufferRangeFlushCase::MapBufferRangeFlushCase (Context& ctx, const char* name, const char* desc, int minBufferSize, int maxBufferSize, int numSamples, deUint32 bufferUsage, deUint32 mapFlags, int caseFlags)
	: BasicUploadCase<MapBufferRangeFlushDuration>	(ctx, name, desc, minBufferSize, maxBufferSize, numSamples, bufferUsage, getBaseCaseType(caseFlags), RESULT_MEDIAN_TRANSFER_RATE, getBaseFlags(mapFlags, caseFlags))
	, m_fullUpload									((caseFlags&FLAG_PARTIAL) == 0)
	, m_flushInParts								((caseFlags&FLAG_FLUSH_IN_PARTS) != 0)
	, m_flushPartial								((caseFlags&FLAG_FLUSH_PARTIAL) != 0)
	, m_useUnusedUnspecifiedBuffer					((caseFlags&FLAG_USE_UNUSED_UNSPECIFIED_BUFFER) != 0)
	, m_useUnusedSpecifiedBuffer					((caseFlags&FLAG_USE_UNUSED_SPECIFIED_BUFFER) != 0)
	, m_mapFlags									(mapFlags)
	, m_unmapFailures								(0)
{
	DE_ASSERT(!(m_flushPartial && m_flushInParts));
	DE_ASSERT(!(m_flushPartial && !m_fullUpload));
}

MapBufferRangeFlushCase::~MapBufferRangeFlushCase (void)
{
}

void MapBufferRangeFlushCase::init (void)
{
	// Describe what the test tries to do
	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Testing glMapBufferRange(), glFlushMappedBufferRange() and glUnmapBuffer() function call performance.\n"
		<< ((m_fullUpload) ? ("The whole buffer is mapped.") : ("Half of the buffer is mapped.")) << "\n"
		<< ((m_flushInParts) ?
			("The mapped range is partitioned to 4 subranges and each partition is flushed separately.") :
			(m_flushPartial) ?
				("Half of the buffer range is flushed.") :
				("The whole mapped range is flushed in one flush call.")) << "\n"
		<< ((m_useUnusedUnspecifiedBuffer) ? ("The buffer has not been used before mapping and is allocated with unspecified contents.\n") : (""))
		<< ((m_useUnusedSpecifiedBuffer) ? ("The buffer has not been used before mapping and is allocated with specified contents.\n") : (""))
		<< ((!m_useUnusedSpecifiedBuffer && !m_useUnusedUnspecifiedBuffer) ? ("The buffer has previously been used in a drawing operation.\n") : (""))
		<< "Map bits:\n"
		<< ((m_mapFlags & GL_MAP_WRITE_BIT) ? ("\tGL_MAP_WRITE_BIT\n") : (""))
		<< ((m_mapFlags & GL_MAP_READ_BIT) ? ("\tGL_MAP_READ_BIT\n") : (""))
		<< ((m_mapFlags & GL_MAP_INVALIDATE_RANGE_BIT) ? ("\tGL_MAP_INVALIDATE_RANGE_BIT\n") : (""))
		<< ((m_mapFlags & GL_MAP_INVALIDATE_BUFFER_BIT) ? ("\tGL_MAP_INVALIDATE_BUFFER_BIT\n") : (""))
		<< ((m_mapFlags & GL_MAP_UNSYNCHRONIZED_BIT) ? ("\tGL_MAP_UNSYNCHRONIZED_BIT\n") : (""))
		<< ((m_mapFlags & GL_MAP_FLUSH_EXPLICIT_BIT) ? ("\tGL_MAP_FLUSH_EXPLICIT_BIT\n") : (""))
		<< tcu::TestLog::EndMessage;

	BasicUploadCase<MapBufferRangeFlushDuration>::init();
}

MapBufferRangeFlushCase::CaseType MapBufferRangeFlushCase::getBaseCaseType (int caseFlags)
{
	if ((caseFlags & FLAG_USE_UNUSED_UNSPECIFIED_BUFFER) == 0 && (caseFlags & FLAG_USE_UNUSED_SPECIFIED_BUFFER) == 0)
		return CASE_USED_BUFFER;
	else
		return CASE_NEW_BUFFER;
}

int MapBufferRangeFlushCase::getBaseFlags (deUint32 mapFlags, int caseFlags)
{
	int flags = FLAG_DONT_LOG_BUFFER_INFO;

	// If buffer contains unspecified data when it is sourced (i.e drawn)
	// results are undefined, and system errors may occur. Signal parent
	// class to take this into account
	if (caseFlags & FLAG_PARTIAL)
	{
		if ((mapFlags & GL_MAP_INVALIDATE_BUFFER_BIT) != 0			||
			(caseFlags & FLAG_USE_UNUSED_UNSPECIFIED_BUFFER) != 0	||
			(caseFlags & FLAG_FLUSH_PARTIAL) != 0)
		{
			flags |= FLAG_RESULT_BUFFER_UNSPECIFIED_CONTENT;
		}
	}

	return flags;
}

void MapBufferRangeFlushCase::testBufferUpload (UploadSampleResult<MapBufferRangeFlushDuration>& result, int bufferSize)
{
	const int unmapFailureThreshold = 4;

	for (; m_unmapFailures < unmapFailureThreshold; ++m_unmapFailures)
	{
		try
		{
			attemptBufferMap(result, bufferSize);
			return;
		}
		catch (UnmapFailureError&)
		{
		}
	}

	throw tcu::TestError("Unmapping failures exceeded limit");
}

void MapBufferRangeFlushCase::attemptBufferMap (UploadSampleResult<MapBufferRangeFlushDuration>& result, int bufferSize)
{
	const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
	const int				mappedSize	= (m_fullUpload) ? (bufferSize) : (bufferSize / 2);

	if (m_fullUpload && !m_flushPartial)
		result.writtenSize = bufferSize;
	else
		result.writtenSize = bufferSize / 2;

	gl.bindBuffer(GL_ARRAY_BUFFER, m_bufferID);

	// Create unused buffer

	if (m_useUnusedUnspecifiedBuffer)
	{
		deUint64 startTime;
		deUint64 endTime;

		// Don't specify contents
		startTime = deGetMicroseconds();
		gl.bufferData(GL_ARRAY_BUFFER, bufferSize, DE_NULL, m_bufferUsage);
		endTime = deGetMicroseconds();

		result.duration.allocDuration = endTime - startTime;
	}
	else if (m_useUnusedSpecifiedBuffer)
	{
		deUint64 startTime;
		deUint64 endTime;

		// Specify buffer contents
		startTime = deGetMicroseconds();
		gl.bufferData(GL_ARRAY_BUFFER, bufferSize, &m_zeroData[0], m_bufferUsage);
		endTime = deGetMicroseconds();

		result.duration.allocDuration = endTime - startTime;
	}
	else
	{
		// No alloc, no time
		result.duration.allocDuration = 0;
	}

	// upload
	{
		void* mapPtr;

		// Map
		{
			deUint64 startTime;
			deUint64 endTime;

			startTime = deGetMicroseconds();
			if (m_fullUpload)
				mapPtr = gl.mapBufferRange(GL_ARRAY_BUFFER, 0, mappedSize, m_mapFlags);
			else
			{
				// upload to buffer center
				mapPtr = gl.mapBufferRange(GL_ARRAY_BUFFER, bufferSize / 4, mappedSize, m_mapFlags);
			}
			endTime = deGetMicroseconds();

			if (!mapPtr)
				throw tcu::Exception("MapBufferRange returned NULL");

			result.duration.mapDuration = endTime - startTime;
		}

		// Write
		{
			if (!m_flushPartial)
				result.duration.writeDuration = medianTimeMemcpy(mapPtr, &m_zeroData[0], result.writtenSize);
			else
				result.duration.writeDuration = medianTimeMemcpy((deUint8*)mapPtr + bufferSize / 4, &m_zeroData[0], result.writtenSize);
		}

		// Flush
		{
			deUint64	startTime;
			deUint64	endTime;

			startTime = deGetMicroseconds();

			if (m_flushPartial)
				gl.flushMappedBufferRange(GL_ARRAY_BUFFER, mappedSize/4, mappedSize/2);
			else if (!m_flushInParts)
				gl.flushMappedBufferRange(GL_ARRAY_BUFFER, 0, mappedSize);
			else
			{
				const int p1 = 0;
				const int p2 = mappedSize / 3;
				const int p3 = mappedSize / 2;
				const int p4 = mappedSize * 2 / 4;
				const int p5 = mappedSize;

				// flush in mixed order
				gl.flushMappedBufferRange(GL_ARRAY_BUFFER, p2,	p3-p2);
				gl.flushMappedBufferRange(GL_ARRAY_BUFFER, p1,	p2-p1);
				gl.flushMappedBufferRange(GL_ARRAY_BUFFER, p4,	p5-p4);
				gl.flushMappedBufferRange(GL_ARRAY_BUFFER, p3,	p4-p3);
			}

			endTime = deGetMicroseconds();

			result.duration.flushDuration = endTime - startTime;
		}

		// Unmap
		{
			deUint64		startTime;
			deUint64		endTime;
			glw::GLboolean	unmapSuccessful;

			startTime = deGetMicroseconds();
			unmapSuccessful = gl.unmapBuffer(GL_ARRAY_BUFFER);
			endTime = deGetMicroseconds();

			// if unmapping fails, just try again later
			if (!unmapSuccessful)
				throw UnmapFailureError();

			result.duration.unmapDuration = endTime - startTime;
		}

		result.duration.totalDuration = result.duration.mapDuration + result.duration.writeDuration + result.duration.flushDuration + result.duration.unmapDuration + result.duration.allocDuration;
		result.duration.fitResponseDuration = result.duration.totalDuration;
	}
}

template <typename SampleType>
class ModifyAfterBasicCase : public BasicBufferCase<SampleType>
{
public:
						ModifyAfterBasicCase	(Context& context, const char* name, const char* description, int bufferSizeMin, int bufferSizeMax, deUint32 usage, bool bufferUnspecifiedAfterTest);
						~ModifyAfterBasicCase	(void);

	void				init					(void);
	void				deinit					(void);

protected:
	void				drawBufferRange			(int begin, int end);

private:
	enum
	{
		NUM_SAMPLES = 20,
	};


	bool				runSample				(int iteration, UploadSampleResult<SampleType>& sample);
	bool				prepareAndRunTest		(int iteration, UploadSampleResult<SampleType>& result, int bufferSize);
	void				logAndSetTestResult		(const std::vector<UploadSampleResult<SampleType> >& results);

	virtual void		testWithBufferSize		(UploadSampleResult<SampleType>& result, int bufferSize) = 0;

	int					m_unmappingErrors;

protected:
	const bool			m_bufferUnspecifiedAfterTest;
	const deUint32		m_bufferUsage;
	std::vector<deUint8> m_zeroData;

	using BasicBufferCase<SampleType>::m_testCtx;
	using BasicBufferCase<SampleType>::m_context;

	using BasicBufferCase<SampleType>::UNUSED_RENDER_AREA_SIZE;
	using BasicBufferCase<SampleType>::m_minimalProgram;
	using BasicBufferCase<SampleType>::m_minimalProgramPosLoc;
	using BasicBufferCase<SampleType>::m_bufferID;
	using BasicBufferCase<SampleType>::m_numSamples;
	using BasicBufferCase<SampleType>::m_bufferSizeMin;
	using BasicBufferCase<SampleType>::m_bufferSizeMax;
	using BasicBufferCase<SampleType>::m_allocateLargerBuffer;
};

template <typename SampleType>
ModifyAfterBasicCase<SampleType>::ModifyAfterBasicCase (Context& context, const char* name, const char* description, int bufferSizeMin, int bufferSizeMax, deUint32 usage, bool bufferUnspecifiedAfterTest)
	: BasicBufferCase<SampleType>	(context, name, description, bufferSizeMin, bufferSizeMax, NUM_SAMPLES, 0)
	, m_unmappingErrors				(0)
	, m_bufferUnspecifiedAfterTest	(bufferUnspecifiedAfterTest)
	, m_bufferUsage					(usage)
	, m_zeroData					()
{
}

template <typename SampleType>
ModifyAfterBasicCase<SampleType>::~ModifyAfterBasicCase (void)
{
	BasicBufferCase<SampleType>::deinit();
}

template <typename SampleType>
void ModifyAfterBasicCase<SampleType>::init (void)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	// init parent

	BasicBufferCase<SampleType>::init();

	// upload source
	m_zeroData.resize(m_bufferSizeMax, 0x00);

	// log basic info

	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Testing performance with " << (int)NUM_SAMPLES << " test samples. Sample order is randomized. All samples at even positions (first = 0) are tested before samples at odd positions.\n"
		<< "Buffer sizes are in range [" << getHumanReadableByteSize(m_bufferSizeMin) << ", " << getHumanReadableByteSize(m_bufferSizeMax) << "]."
		<< tcu::TestLog::EndMessage;

	// log which transfer rate is the test result and buffer info

	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Test result is the median transfer rate of the test samples.\n"
		<< "Buffer usage = " << glu::getUsageName(m_bufferUsage)
		<< tcu::TestLog::EndMessage;

	// Set state for drawing so that we don't have to change these during the iteration
	{
		gl.useProgram(m_minimalProgram->getProgram());
		gl.viewport(0, 0, UNUSED_RENDER_AREA_SIZE, UNUSED_RENDER_AREA_SIZE);
		gl.enableVertexAttribArray(m_minimalProgramPosLoc);
	}
}

template <typename SampleType>
void ModifyAfterBasicCase<SampleType>::deinit (void)
{
	m_zeroData = std::vector<deUint8>();

	BasicBufferCase<SampleType>::deinit();
}

template <typename SampleType>
void ModifyAfterBasicCase<SampleType>::drawBufferRange (int begin, int end)
{
	DE_ASSERT(begin % (int)sizeof(float[4]) == 0);
	DE_ASSERT(end % (int)sizeof(float[4]) == 0);

	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	// use given range
	gl.drawArrays(GL_POINTS, begin / (int)sizeof(float[4]), 1);
	gl.drawArrays(GL_POINTS, end / (int)sizeof(float[4]) - 1, 1);
}

template <typename SampleType>
bool ModifyAfterBasicCase<SampleType>::runSample (int iteration, UploadSampleResult<SampleType>& sample)
{
	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
	const int				bufferSize			= sample.bufferSize;
	bool					testOk;

	testOk = prepareAndRunTest(iteration, sample, bufferSize);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Buffer upload sample");

	if (!testOk)
	{
		const int unmapFailureThreshold = 4;

		// only unmapping error can cause iteration failure
		if (++m_unmappingErrors >= unmapFailureThreshold)
			throw tcu::TestError("Too many unmapping errors, cannot continue.");

		// just try again
		return false;
	}

	return true;
}

template <typename SampleType>
bool ModifyAfterBasicCase<SampleType>::prepareAndRunTest (int iteration, UploadSampleResult<SampleType>& result, int bufferSize)
{
	DE_UNREF(iteration);

	DE_ASSERT(!m_bufferID);
	DE_ASSERT(deIsAligned32(bufferSize, 4*4)); // aligned to vec4

	const glw::Functions&		gl				= m_context.getRenderContext().getFunctions();
	bool						testRunOk		= true;
	bool						unmappingFailed	= false;

	// Upload initial buffer to the GPU...
	gl.genBuffers(1, &m_bufferID);
	gl.bindBuffer(GL_ARRAY_BUFFER, m_bufferID);
	gl.bufferData(GL_ARRAY_BUFFER, bufferSize, &m_zeroData[0], m_bufferUsage);

	// ...use it...
	gl.vertexAttribPointer(m_minimalProgramPosLoc, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
	drawBufferRange(0, bufferSize);

	// ..and make sure it is uploaded
	BasicBufferCase<SampleType>::waitGLResults();

	// warmup CPU before the test to make sure the power management governor
	// keeps us in the "high performance" mode
	{
		deYield();
		tcu::warmupCPU();
		deYield();
	}

	// test
	try
	{
		// buffer is uploaded to the GPU. Draw from it.
		drawBufferRange(0, bufferSize);

		// and test upload
		testWithBufferSize(result, bufferSize);
	}
	catch (UnmapFailureError&)
	{
		testRunOk = false;
		unmappingFailed = true;
	}

	// clean up: make sure buffer is not in upload queue and delete it

	// sourcing unspecified data causes undefined results, possibly program termination
	if (m_bufferUnspecifiedAfterTest || unmappingFailed)
		gl.bufferData(GL_ARRAY_BUFFER, bufferSize, &m_zeroData[0], m_bufferUsage);

	drawBufferRange(0, bufferSize);
	BasicBufferCase<SampleType>::waitGLResults();

	gl.deleteBuffers(1, &m_bufferID);
	m_bufferID = 0;

	return testRunOk;
}

template <typename SampleType>
void ModifyAfterBasicCase<SampleType>::logAndSetTestResult (const std::vector<UploadSampleResult<SampleType> >& results)
{
	const UploadSampleAnalyzeResult analysis = analyzeSampleResults(m_testCtx.getLog(), results, false);

	// Return median transfer rate of the samples

	if (analysis.transferRateMedian == std::numeric_limits<float>::infinity())
	{
		// sample times are 1) invalid or 2) timer resolution too low
		// report speed 0 bytes / s since real value cannot be determined
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::floatToString(0.0f, 2).c_str());
	}
	else
	{
		// report transfer rate in MB / s
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::floatToString(analysis.transferRateMedian / 1024.0f / 1024.0f, 2).c_str());
	}
}

class ModifyAfterWithBufferDataCase : public ModifyAfterBasicCase<SingleOperationDuration>
{
public:

	enum CaseFlags
	{
		FLAG_RESPECIFY_SIZE		= 0x1,
		FLAG_UPLOAD_REPEATED	= 0x2,
	};

					ModifyAfterWithBufferDataCase	(Context& context, const char* name, const char* desc, int bufferSizeMin, int bufferSizeMax, deUint32 usage, int flags);
					~ModifyAfterWithBufferDataCase	(void);

	void			init							(void);
	void			deinit							(void);
private:
	void			testWithBufferSize				(UploadSampleResult<SingleOperationDuration>& result, int bufferSize);

	enum
	{
		NUM_REPEATS = 2
	};

	const bool		m_respecifySize;
	const bool		m_repeatedUpload;
	const float		m_sizeDifferenceFactor;
};

ModifyAfterWithBufferDataCase::ModifyAfterWithBufferDataCase (Context& context, const char* name, const char* desc, int bufferSizeMin, int bufferSizeMax, deUint32 usage, int flags)
	: ModifyAfterBasicCase<SingleOperationDuration> (context, name, desc, bufferSizeMin, bufferSizeMax, usage, false)
	, m_respecifySize								((flags & FLAG_RESPECIFY_SIZE) != 0)
	, m_repeatedUpload								((flags & FLAG_UPLOAD_REPEATED) != 0)
	, m_sizeDifferenceFactor						(1.3f)
{
	DE_ASSERT(!(m_repeatedUpload && m_respecifySize));
}

ModifyAfterWithBufferDataCase::~ModifyAfterWithBufferDataCase (void)
{
	deinit();
}

void ModifyAfterWithBufferDataCase::init (void)
{
	// Log the purpose of the test

	if (m_repeatedUpload)
		m_testCtx.getLog() << tcu::TestLog::Message << "Testing performance of BufferData() command after \"specify buffer contents - draw buffer\" command pair is repeated " << (int)NUM_REPEATS << " times." << tcu::TestLog::EndMessage;
	else
		m_testCtx.getLog() << tcu::TestLog::Message << "Testing performance of BufferData() command after a draw command that sources data from the target buffer." << tcu::TestLog::EndMessage;

	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< ((m_respecifySize) ?
			("Buffer size is increased and contents are modified with BufferData().\n") :
			("Buffer contents are modified with BufferData().\n"))
		<< tcu::TestLog::EndMessage;

	// init parent
	ModifyAfterBasicCase<SingleOperationDuration>::init();

	// make sure our zeroBuffer is large enough
	if (m_respecifySize)
	{
		const int largerBufferSize = deAlign32((int)((float)m_bufferSizeMax * m_sizeDifferenceFactor), 4*4);
		m_zeroData.resize(largerBufferSize, 0x00);
	}
}

void ModifyAfterWithBufferDataCase::deinit (void)
{
	ModifyAfterBasicCase<SingleOperationDuration>::deinit();
}

void ModifyAfterWithBufferDataCase::testWithBufferSize (UploadSampleResult<SingleOperationDuration>& result, int bufferSize)
{
	// always draw the same amount to make compares between cases sensible
	const int					drawStart			= deAlign32(bufferSize / 4, 4*4);
	const int					drawEnd				= deAlign32(bufferSize * 3 / 4, 4*4);

	const glw::Functions&		gl					= m_context.getRenderContext().getFunctions();
	const int					largerBufferSize	= deAlign32((int)((float)bufferSize * m_sizeDifferenceFactor), 4*4);
	const int					newBufferSize		= (m_respecifySize) ? (largerBufferSize) : (bufferSize);
	deUint64					startTime;
	deUint64					endTime;

	// repeat upload-draw
	if (m_repeatedUpload)
	{
		for (int repeatNdx = 0; repeatNdx < NUM_REPEATS; ++repeatNdx)
		{
			gl.bufferData(GL_ARRAY_BUFFER, newBufferSize, &m_zeroData[0], m_bufferUsage);
			drawBufferRange(drawStart, drawEnd);
		}
	}

	// test upload
	startTime = deGetMicroseconds();
	gl.bufferData(GL_ARRAY_BUFFER, newBufferSize, &m_zeroData[0], m_bufferUsage);
	endTime = deGetMicroseconds();

	result.duration.totalDuration = endTime - startTime;
	result.duration.fitResponseDuration = result.duration.totalDuration;
	result.writtenSize = newBufferSize;
}

class ModifyAfterWithBufferSubDataCase : public ModifyAfterBasicCase<SingleOperationDuration>
{
public:

	enum CaseFlags
	{
		FLAG_PARTIAL			= 0x1,
		FLAG_UPLOAD_REPEATED	= 0x2,
	};

					ModifyAfterWithBufferSubDataCase	(Context& context, const char* name, const char* desc, int bufferSizeMin, int bufferSizeMax, deUint32 usage, int flags);
					~ModifyAfterWithBufferSubDataCase	(void);

	void			init								(void);
	void			deinit								(void);
private:
	void			testWithBufferSize					(UploadSampleResult<SingleOperationDuration>& result, int bufferSize);

	enum
	{
		NUM_REPEATS = 2
	};

	const bool		m_partialUpload;
	const bool		m_repeatedUpload;
};

ModifyAfterWithBufferSubDataCase::ModifyAfterWithBufferSubDataCase (Context& context, const char* name, const char* desc, int bufferSizeMin, int bufferSizeMax, deUint32 usage, int flags)
	: ModifyAfterBasicCase<SingleOperationDuration>	(context, name, desc, bufferSizeMin, bufferSizeMax, usage, false)
	, m_partialUpload								((flags & FLAG_PARTIAL) != 0)
	, m_repeatedUpload								((flags & FLAG_UPLOAD_REPEATED) != 0)
{
}

ModifyAfterWithBufferSubDataCase::~ModifyAfterWithBufferSubDataCase (void)
{
	deinit();
}

void ModifyAfterWithBufferSubDataCase::init (void)
{
	// Log the purpose of the test

	if (m_repeatedUpload)
		m_testCtx.getLog() << tcu::TestLog::Message << "Testing performance of BufferSubData() command after \"specify buffer contents - draw buffer\" command pair is repeated " << (int)NUM_REPEATS << " times." << tcu::TestLog::EndMessage;
	else
		m_testCtx.getLog() << tcu::TestLog::Message << "Testing performance of BufferSubData() command after a draw command that sources data from the target buffer." << tcu::TestLog::EndMessage;

	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< ((m_partialUpload) ?
			("Half of the buffer contents are modified.\n") :
			("Buffer contents are fully respecified.\n"))
		<< tcu::TestLog::EndMessage;

	ModifyAfterBasicCase<SingleOperationDuration>::init();
}

void ModifyAfterWithBufferSubDataCase::deinit (void)
{
	ModifyAfterBasicCase<SingleOperationDuration>::deinit();
}

void ModifyAfterWithBufferSubDataCase::testWithBufferSize (UploadSampleResult<SingleOperationDuration>& result, int bufferSize)
{
	// always draw the same amount to make compares between cases sensible
	const int					drawStart			= deAlign32(bufferSize / 4, 4*4);
	const int					drawEnd				= deAlign32(bufferSize * 3 / 4, 4*4);

	const glw::Functions&		gl					= m_context.getRenderContext().getFunctions();
	const int					subdataOffset		= deAlign32((m_partialUpload) ? (bufferSize / 4) : (0), 4*4);
	const int					subdataSize			= deAlign32((m_partialUpload) ? (bufferSize / 2) : (bufferSize), 4*4);
	deUint64					startTime;
	deUint64					endTime;

	// make upload-draw stream
	if (m_repeatedUpload)
	{
		for (int repeatNdx = 0; repeatNdx < NUM_REPEATS; ++repeatNdx)
		{
			gl.bufferSubData(GL_ARRAY_BUFFER, subdataOffset, subdataSize, &m_zeroData[0]);
			drawBufferRange(drawStart, drawEnd);
		}
	}

	// test upload
	startTime = deGetMicroseconds();
	gl.bufferSubData(GL_ARRAY_BUFFER, subdataOffset, subdataSize, &m_zeroData[0]);
	endTime = deGetMicroseconds();

	result.duration.totalDuration = endTime - startTime;
	result.duration.fitResponseDuration = result.duration.totalDuration;
	result.writtenSize = subdataSize;
}

class ModifyAfterWithMapBufferRangeCase : public ModifyAfterBasicCase<MapBufferRangeDurationNoAlloc>
{
public:

	enum CaseFlags
	{
		FLAG_PARTIAL = 0x1,
	};

					ModifyAfterWithMapBufferRangeCase	(Context& context, const char* name, const char* desc, int bufferSizeMin, int bufferSizeMax, deUint32 usage, int flags, deUint32 glMapFlags);
					~ModifyAfterWithMapBufferRangeCase	(void);

	void			init								(void);
	void			deinit								(void);
private:
	static bool		isBufferUnspecifiedAfterUpload		(int flags, deUint32 mapFlags);
	void			testWithBufferSize					(UploadSampleResult<MapBufferRangeDurationNoAlloc>& result, int bufferSize);

	const bool		m_partialUpload;
	const deUint32	m_mapFlags;
};

ModifyAfterWithMapBufferRangeCase::ModifyAfterWithMapBufferRangeCase (Context& context, const char* name, const char* desc, int bufferSizeMin, int bufferSizeMax, deUint32 usage, int flags, deUint32 glMapFlags)
	: ModifyAfterBasicCase<MapBufferRangeDurationNoAlloc>	(context, name, desc, bufferSizeMin, bufferSizeMax, usage, isBufferUnspecifiedAfterUpload(flags, glMapFlags))
	, m_partialUpload										((flags & FLAG_PARTIAL) != 0)
	, m_mapFlags											(glMapFlags)
{
}

ModifyAfterWithMapBufferRangeCase::~ModifyAfterWithMapBufferRangeCase (void)
{
	deinit();
}

void ModifyAfterWithMapBufferRangeCase::init (void)
{
	// Log the purpose of the test

	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Testing performance of MapBufferRange() command after a draw command that sources data from the target buffer.\n"
		<< ((m_partialUpload) ?
			("Half of the buffer is mapped.\n") :
			("Whole buffer is mapped.\n"))
		<< "Map bits:\n"
		<< ((m_mapFlags & GL_MAP_WRITE_BIT) ? ("\tGL_MAP_WRITE_BIT\n") : (""))
		<< ((m_mapFlags & GL_MAP_READ_BIT) ? ("\tGL_MAP_READ_BIT\n") : (""))
		<< ((m_mapFlags & GL_MAP_INVALIDATE_RANGE_BIT) ? ("\tGL_MAP_INVALIDATE_RANGE_BIT\n") : (""))
		<< ((m_mapFlags & GL_MAP_INVALIDATE_BUFFER_BIT) ? ("\tGL_MAP_INVALIDATE_BUFFER_BIT\n") : (""))
		<< ((m_mapFlags & GL_MAP_UNSYNCHRONIZED_BIT) ? ("\tGL_MAP_UNSYNCHRONIZED_BIT\n") : (""))
		<< ((m_mapFlags & GL_MAP_FLUSH_EXPLICIT_BIT) ? ("\tGL_MAP_FLUSH_EXPLICIT_BIT\n") : (""))
		<< tcu::TestLog::EndMessage;

	ModifyAfterBasicCase<MapBufferRangeDurationNoAlloc>::init();
}

void ModifyAfterWithMapBufferRangeCase::deinit (void)
{
	ModifyAfterBasicCase<MapBufferRangeDurationNoAlloc>::deinit();
}

bool ModifyAfterWithMapBufferRangeCase::isBufferUnspecifiedAfterUpload (int flags, deUint32 mapFlags)
{
	if ((flags & FLAG_PARTIAL) != 0 && ((mapFlags & GL_MAP_INVALIDATE_BUFFER_BIT) != 0))
		return true;

	return false;
}

void ModifyAfterWithMapBufferRangeCase::testWithBufferSize (UploadSampleResult<MapBufferRangeDurationNoAlloc>& result, int bufferSize)
{
	const glw::Functions&		gl					= m_context.getRenderContext().getFunctions();
	const int					subdataOffset		= deAlign32((m_partialUpload) ? (bufferSize / 4) : (0), 4*4);
	const int					subdataSize			= deAlign32((m_partialUpload) ? (bufferSize / 2) : (bufferSize), 4*4);
	void*						mapPtr;

	// map
	{
		deUint64 startTime;
		deUint64 endTime;

		startTime = deGetMicroseconds();
		mapPtr = gl.mapBufferRange(GL_ARRAY_BUFFER, subdataOffset, subdataSize, m_mapFlags);
		endTime = deGetMicroseconds();

		if (!mapPtr)
			throw tcu::TestError("mapBufferRange returned null");

		result.duration.mapDuration = endTime - startTime;
	}

	// write
	{
		result.duration.writeDuration = medianTimeMemcpy(mapPtr, &m_zeroData[0], subdataSize);
	}

	// unmap
	{
		deUint64		startTime;
		deUint64		endTime;
		glw::GLboolean	unmapSucceeded;

		startTime = deGetMicroseconds();
		unmapSucceeded = gl.unmapBuffer(GL_ARRAY_BUFFER);
		endTime = deGetMicroseconds();

		if (unmapSucceeded != GL_TRUE)
			throw UnmapFailureError();

		result.duration.unmapDuration = endTime - startTime;
	}

	result.duration.totalDuration = result.duration.mapDuration + result.duration.writeDuration + result.duration.unmapDuration;
	result.duration.fitResponseDuration = result.duration.totalDuration;
	result.writtenSize = subdataSize;
}

class ModifyAfterWithMapBufferFlushCase : public ModifyAfterBasicCase<MapBufferRangeFlushDurationNoAlloc>
{
public:

	enum CaseFlags
	{
		FLAG_PARTIAL = 0x1,
	};

					ModifyAfterWithMapBufferFlushCase	(Context& context, const char* name, const char* desc, int bufferSizeMin, int bufferSizeMax, deUint32 usage, int flags, deUint32 glMapFlags);
					~ModifyAfterWithMapBufferFlushCase	(void);

	void			init								(void);
	void			deinit								(void);
private:
	static bool		isBufferUnspecifiedAfterUpload		(int flags, deUint32 mapFlags);
	void			testWithBufferSize					(UploadSampleResult<MapBufferRangeFlushDurationNoAlloc>& result, int bufferSize);

	const bool		m_partialUpload;
	const deUint32	m_mapFlags;
};

ModifyAfterWithMapBufferFlushCase::ModifyAfterWithMapBufferFlushCase (Context& context, const char* name, const char* desc, int bufferSizeMin, int bufferSizeMax, deUint32 usage, int flags, deUint32 glMapFlags)
	: ModifyAfterBasicCase<MapBufferRangeFlushDurationNoAlloc>	(context, name, desc, bufferSizeMin, bufferSizeMax, usage, isBufferUnspecifiedAfterUpload(flags, glMapFlags))
	, m_partialUpload											((flags & FLAG_PARTIAL) != 0)
	, m_mapFlags												(glMapFlags)
{
}

ModifyAfterWithMapBufferFlushCase::~ModifyAfterWithMapBufferFlushCase (void)
{
	deinit();
}

void ModifyAfterWithMapBufferFlushCase::init (void)
{
	// Log the purpose of the test

	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Testing performance of MapBufferRange() command after a draw command that sources data from the target buffer.\n"
		<< ((m_partialUpload) ?
			("Half of the buffer is mapped.\n") :
			("Whole buffer is mapped.\n"))
		<< "Map bits:\n"
		<< ((m_mapFlags & GL_MAP_WRITE_BIT) ? ("\tGL_MAP_WRITE_BIT\n") : (""))
		<< ((m_mapFlags & GL_MAP_READ_BIT) ? ("\tGL_MAP_READ_BIT\n") : (""))
		<< ((m_mapFlags & GL_MAP_INVALIDATE_RANGE_BIT) ? ("\tGL_MAP_INVALIDATE_RANGE_BIT\n") : (""))
		<< ((m_mapFlags & GL_MAP_INVALIDATE_BUFFER_BIT) ? ("\tGL_MAP_INVALIDATE_BUFFER_BIT\n") : (""))
		<< ((m_mapFlags & GL_MAP_UNSYNCHRONIZED_BIT) ? ("\tGL_MAP_UNSYNCHRONIZED_BIT\n") : (""))
		<< ((m_mapFlags & GL_MAP_FLUSH_EXPLICIT_BIT) ? ("\tGL_MAP_FLUSH_EXPLICIT_BIT\n") : (""))
		<< tcu::TestLog::EndMessage;

	ModifyAfterBasicCase<MapBufferRangeFlushDurationNoAlloc>::init();
}

void ModifyAfterWithMapBufferFlushCase::deinit (void)
{
	ModifyAfterBasicCase<MapBufferRangeFlushDurationNoAlloc>::deinit();
}

bool ModifyAfterWithMapBufferFlushCase::isBufferUnspecifiedAfterUpload (int flags, deUint32 mapFlags)
{
	if ((flags & FLAG_PARTIAL) != 0 && ((mapFlags & GL_MAP_INVALIDATE_BUFFER_BIT) != 0))
		return true;

	return false;
}

void ModifyAfterWithMapBufferFlushCase::testWithBufferSize (UploadSampleResult<MapBufferRangeFlushDurationNoAlloc>& result, int bufferSize)
{
	const glw::Functions&		gl					= m_context.getRenderContext().getFunctions();
	const int					subdataOffset		= deAlign32((m_partialUpload) ? (bufferSize / 4) : (0), 4*4);
	const int					subdataSize			= deAlign32((m_partialUpload) ? (bufferSize / 2) : (bufferSize), 4*4);
	void*						mapPtr;

	// map
	{
		deUint64 startTime;
		deUint64 endTime;

		startTime = deGetMicroseconds();
		mapPtr = gl.mapBufferRange(GL_ARRAY_BUFFER, subdataOffset, subdataSize, m_mapFlags);
		endTime = deGetMicroseconds();

		if (!mapPtr)
			throw tcu::TestError("mapBufferRange returned null");

		result.duration.mapDuration = endTime - startTime;
	}

	// write
	{
		result.duration.writeDuration = medianTimeMemcpy(mapPtr, &m_zeroData[0], subdataSize);
	}

	// flush
	{
		deUint64 startTime;
		deUint64 endTime;

		startTime = deGetMicroseconds();
		gl.flushMappedBufferRange(GL_ARRAY_BUFFER, 0, subdataSize);
		endTime = deGetMicroseconds();

		result.duration.flushDuration = endTime - startTime;
	}

	// unmap
	{
		deUint64		startTime;
		deUint64		endTime;
		glw::GLboolean	unmapSucceeded;

		startTime = deGetMicroseconds();
		unmapSucceeded = gl.unmapBuffer(GL_ARRAY_BUFFER);
		endTime = deGetMicroseconds();

		if (unmapSucceeded != GL_TRUE)
			throw UnmapFailureError();

		result.duration.unmapDuration = endTime - startTime;
	}

	result.duration.totalDuration = result.duration.mapDuration + result.duration.writeDuration + result.duration.unmapDuration + result.duration.flushDuration;
	result.duration.fitResponseDuration = result.duration.totalDuration;
	result.writtenSize = subdataSize;
}

enum DrawMethod
{
	DRAWMETHOD_DRAW_ARRAYS = 0,
	DRAWMETHOD_DRAW_ELEMENTS,

	DRAWMETHOD_LAST
};

enum TargetBuffer
{
	TARGETBUFFER_VERTEX = 0,
	TARGETBUFFER_INDEX,

	TARGETBUFFER_LAST
};

enum BufferState
{
	BUFFERSTATE_NEW = 0,
	BUFFERSTATE_EXISTING,

	BUFFERSTATE_LAST
};

enum UploadMethod
{
	UPLOADMETHOD_BUFFER_DATA = 0,
	UPLOADMETHOD_BUFFER_SUB_DATA,
	UPLOADMETHOD_MAP_BUFFER_RANGE,

	UPLOADMETHOD_LAST
};

enum UnrelatedBufferType
{
	UNRELATEDBUFFERTYPE_NONE = 0,
	UNRELATEDBUFFERTYPE_VERTEX,

	UNRELATEDBUFFERTYPE_LAST
};

enum UploadRange
{
	UPLOADRANGE_FULL = 0,
	UPLOADRANGE_PARTIAL,

	UPLOADRANGE_LAST
};

struct LayeredGridSpec
{
	int gridWidth;
	int gridHeight;
	int gridLayers;
};

static int getLayeredGridNumVertices (const LayeredGridSpec& scene)
{
	return scene.gridWidth * scene.gridHeight * scene.gridLayers * 6;
}

static void generateLayeredGridVertexAttribData4C4V (std::vector<tcu::Vec4>& vertexData, const LayeredGridSpec& scene)
{
	// interleave color & vertex data
	const tcu::Vec4 green	(0.0f, 1.0f, 0.0f, 0.7f);
	const tcu::Vec4 yellow	(1.0f, 1.0f, 0.0f, 0.8f);

	vertexData.resize(getLayeredGridNumVertices(scene) * 2);

	for (int cellY = 0; cellY < scene.gridHeight; ++cellY)
	for (int cellX = 0; cellX < scene.gridWidth; ++cellX)
	for (int cellZ = 0; cellZ < scene.gridLayers; ++cellZ)
	{
		const tcu::Vec4	color		= (((cellX + cellY + cellZ) % 2) == 0) ? (green) : (yellow);
		const float		cellLeft	= (float(cellX  ) / (float)scene.gridWidth  - 0.5f) * 2.0f;
		const float		cellRight	= (float(cellX+1) / (float)scene.gridWidth  - 0.5f) * 2.0f;
		const float		cellTop		= (float(cellY+1) / (float)scene.gridHeight - 0.5f) * 2.0f;
		const float		cellBottom	= (float(cellY  ) / (float)scene.gridHeight - 0.5f) * 2.0f;

		vertexData[(cellY * scene.gridWidth * scene.gridLayers + cellX * scene.gridLayers + cellZ) * 12 +  0] = color;
		vertexData[(cellY * scene.gridWidth * scene.gridLayers + cellX * scene.gridLayers + cellZ) * 12 +  1] = tcu::Vec4(cellLeft, cellTop, 0.0f, 1.0f);

		vertexData[(cellY * scene.gridWidth * scene.gridLayers + cellX * scene.gridLayers + cellZ) * 12 +  2] = color;
		vertexData[(cellY * scene.gridWidth * scene.gridLayers + cellX * scene.gridLayers + cellZ) * 12 +  3] = tcu::Vec4(cellLeft, cellBottom, 0.0f, 1.0f);

		vertexData[(cellY * scene.gridWidth * scene.gridLayers + cellX * scene.gridLayers + cellZ) * 12 +  4] = color;
		vertexData[(cellY * scene.gridWidth * scene.gridLayers + cellX * scene.gridLayers + cellZ) * 12 +  5] = tcu::Vec4(cellRight, cellBottom, 0.0f, 1.0f);

		vertexData[(cellY * scene.gridWidth * scene.gridLayers + cellX * scene.gridLayers + cellZ) * 12 +  6] = color;
		vertexData[(cellY * scene.gridWidth * scene.gridLayers + cellX * scene.gridLayers + cellZ) * 12 +  7] = tcu::Vec4(cellLeft, cellTop, 0.0f, 1.0f);

		vertexData[(cellY * scene.gridWidth * scene.gridLayers + cellX * scene.gridLayers + cellZ) * 12 +  8] = color;
		vertexData[(cellY * scene.gridWidth * scene.gridLayers + cellX * scene.gridLayers + cellZ) * 12 +  9] = tcu::Vec4(cellRight, cellBottom, 0.0f, 1.0f);

		vertexData[(cellY * scene.gridWidth * scene.gridLayers + cellX * scene.gridLayers + cellZ) * 12 + 10] = color;
		vertexData[(cellY * scene.gridWidth * scene.gridLayers + cellX * scene.gridLayers + cellZ) * 12 + 11] = tcu::Vec4(cellRight, cellTop, 0.0f, 1.0f);
	}
}

static void generateLayeredGridIndexData (std::vector<deUint32>& indexData, const LayeredGridSpec& scene)
{
	indexData.resize(getLayeredGridNumVertices(scene) * 2);

	for (int ndx = 0; ndx < scene.gridLayers * scene.gridHeight * scene.gridWidth * 6; ++ndx)
		indexData[ndx] = ndx;
}

class RenderPerformanceTestBase : public TestCase
{
public:
							RenderPerformanceTestBase	(Context& context, const char* name, const char* description);
							~RenderPerformanceTestBase	(void);

protected:
	void					init						(void);
	void					deinit						(void);

	void					waitGLResults				(void) const;
	void					setupVertexAttribs			(void) const;

	enum
	{
		RENDER_AREA_SIZE = 128
	};

private:
	glu::ShaderProgram*		m_renderProgram;
	int						m_colorLoc;
	int						m_positionLoc;
};

RenderPerformanceTestBase::RenderPerformanceTestBase (Context& context, const char* name, const char* description)
	: TestCase			(context, tcu::NODETYPE_PERFORMANCE, name, description)
	, m_renderProgram	(DE_NULL)
	, m_colorLoc		(0)
	, m_positionLoc		(0)
{
}

RenderPerformanceTestBase::~RenderPerformanceTestBase (void)
{
	deinit();
}

void RenderPerformanceTestBase::init (void)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	m_renderProgram = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(s_colorVertexShader) << glu::FragmentSource(s_colorFragmentShader));
	if (!m_renderProgram->isOk())
	{
		m_testCtx.getLog() << *m_renderProgram;
		throw tcu::TestError("could not build program");
	}

	m_colorLoc = gl.getAttribLocation(m_renderProgram->getProgram(), "a_color");
	m_positionLoc = gl.getAttribLocation(m_renderProgram->getProgram(), "a_position");

	if (m_colorLoc == -1)
		throw tcu::TestError("Location of attribute a_color was -1");
	if (m_positionLoc == -1)
		throw tcu::TestError("Location of attribute a_position was -1");
}

void RenderPerformanceTestBase::deinit (void)
{
	delete m_renderProgram;
	m_renderProgram = DE_NULL;
}

void RenderPerformanceTestBase::setupVertexAttribs (void) const
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	// buffers are bound

	gl.enableVertexAttribArray(m_colorLoc);
	gl.enableVertexAttribArray(m_positionLoc);

	gl.vertexAttribPointer(m_colorLoc,    4, GL_FLOAT, GL_FALSE, (glw::GLsizei)(8 * sizeof(float)), glu::BufferOffsetAsPointer(0 * sizeof(tcu::Vec4)));
	gl.vertexAttribPointer(m_positionLoc, 4, GL_FLOAT, GL_FALSE, (glw::GLsizei)(8 * sizeof(float)), glu::BufferOffsetAsPointer(1 * sizeof(tcu::Vec4)));

	gl.useProgram(m_renderProgram->getProgram());

	GLU_EXPECT_NO_ERROR(gl.getError(), "set up rendering");
}

void RenderPerformanceTestBase::waitGLResults (void) const
{
	tcu::Surface unusedSurface(RENDER_AREA_SIZE, RENDER_AREA_SIZE);
	glu::readPixels(m_context.getRenderContext(), 0, 0, unusedSurface.getAccess());
}

template <typename SampleType>
class RenderCase : public RenderPerformanceTestBase
{
public:
									RenderCase						(Context& context, const char* name, const char* description, DrawMethod drawMethod);
									~RenderCase						(void);

protected:
	void							init							(void);
	void							deinit							(void);

private:
	IterateResult					iterate							(void);

protected:
	struct SampleResult
	{
		LayeredGridSpec					scene;
		RenderSampleResult<SampleType>	result;
	};

	int								getMinWorkloadSize				(void) const;
	int								getMaxWorkloadSize				(void) const;
	int								getMinWorkloadDataSize			(void) const;
	int								getMaxWorkloadDataSize			(void) const;
	int								getVertexDataSize				(void) const;
	int								getNumSamples					(void) const;
	void							uploadScene						(const LayeredGridSpec& scene);

	virtual void					runSample						(SampleResult& sample) = 0;
	virtual void					logAndSetTestResult				(const std::vector<SampleResult>& results);

	void							mapResultsToRenderRateFormat	(std::vector<RenderSampleResult<SampleType> >& dst, const std::vector<SampleResult>& src) const;

	const DrawMethod				m_drawMethod;

private:
	glw::GLuint						m_attributeBufferID;
	glw::GLuint						m_indexBufferID;
	int								m_iterationNdx;
	std::vector<int>				m_iterationOrder;
	std::vector<SampleResult>		m_results;
	int								m_numUnmapFailures;
};

template <typename SampleType>
RenderCase<SampleType>::RenderCase (Context& context, const char* name, const char* description, DrawMethod drawMethod)
	: RenderPerformanceTestBase	(context, name, description)
	, m_drawMethod				(drawMethod)
	, m_attributeBufferID		(0)
	, m_indexBufferID			(0)
	, m_iterationNdx			(0)
	, m_numUnmapFailures		(0)
{
	DE_ASSERT(drawMethod < DRAWMETHOD_LAST);
}

template <typename SampleType>
RenderCase<SampleType>::~RenderCase (void)
{
	deinit();
}

template <typename SampleType>
void RenderCase<SampleType>::init (void)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	RenderPerformanceTestBase::init();

	// requirements

	if (m_context.getRenderTarget().getWidth() < RENDER_AREA_SIZE ||
		m_context.getRenderTarget().getHeight() < RENDER_AREA_SIZE)
		throw tcu::NotSupportedError("Test case requires " + de::toString<int>(RENDER_AREA_SIZE) + "x" + de::toString<int>(RENDER_AREA_SIZE) + " render target");

	// gl state

	gl.viewport(0, 0, RENDER_AREA_SIZE, RENDER_AREA_SIZE);

	// enable bleding to prevent grid layers from being discarded
	gl.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	gl.blendEquation(GL_FUNC_ADD);
	gl.enable(GL_BLEND);

	// generate iterations

	{
		const int gridSizes[] = { 20, 26, 32, 38, 44, 50, 56, 62, 68, 74, 80,  86,  92,  98,  104, 110, 116, 122, 128 };

		for (int gridNdx = 0; gridNdx < DE_LENGTH_OF_ARRAY(gridSizes); ++gridNdx)
		{
			m_results.push_back(SampleResult());

			m_results.back().scene.gridHeight = gridSizes[gridNdx];
			m_results.back().scene.gridWidth = gridSizes[gridNdx];
			m_results.back().scene.gridLayers = 5;

			m_results.back().result.numVertices = getLayeredGridNumVertices(m_results.back().scene);

			// test cases set these, initialize to unused values
			m_results.back().result.renderDataSize = -1;
			m_results.back().result.uploadedDataSize = -1;
			m_results.back().result.unrelatedDataSize = -1;
		}
	}

	// randomize iteration order
	{
		m_iterationOrder.resize(m_results.size());
		generateTwoPassRandomIterationOrder(m_iterationOrder, (int)m_iterationOrder.size());
	}
}

template <typename SampleType>
void RenderCase<SampleType>::deinit (void)
{
	RenderPerformanceTestBase::deinit();

	if (m_attributeBufferID)
	{
		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_attributeBufferID);
		m_attributeBufferID = 0;
	}

	if (m_indexBufferID)
	{
		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_indexBufferID);
		m_indexBufferID = 0;
	}
}

template <typename SampleType>
typename RenderCase<SampleType>::IterateResult RenderCase<SampleType>::iterate (void)
{
	const int		unmapFailureThreshold	= 3;
	const int		currentIteration		= m_iterationNdx;
	const int		currentConfigNdx		= m_iterationOrder[currentIteration];
	SampleResult&	currentSample			= m_results[currentConfigNdx];

	try
	{
		runSample(currentSample);
		++m_iterationNdx;
	}
	catch (const UnmapFailureError& ex)
	{
		DE_UNREF(ex);
		++m_numUnmapFailures;
	}

	if (m_numUnmapFailures > unmapFailureThreshold)
		throw tcu::TestError("Got too many unmap errors");

	if (m_iterationNdx < (int)m_iterationOrder.size())
		return CONTINUE;

	logAndSetTestResult(m_results);
	return STOP;
}

template <typename SampleType>
int RenderCase<SampleType>::getMinWorkloadSize (void) const
{
	int result = getLayeredGridNumVertices(m_results[0].scene);

	for (int ndx = 1; ndx < (int)m_results.size(); ++ndx)
	{
		const int workloadSize = getLayeredGridNumVertices(m_results[ndx].scene);
		result = de::min(result, workloadSize);
	}

	return result;
}

template <typename SampleType>
int RenderCase<SampleType>::getMaxWorkloadSize (void) const
{
	int result = getLayeredGridNumVertices(m_results[0].scene);

	for (int ndx = 1; ndx < (int)m_results.size(); ++ndx)
	{
		const int workloadSize = getLayeredGridNumVertices(m_results[ndx].scene);
		result = de::max(result, workloadSize);
	}

	return result;
}

template <typename SampleType>
int RenderCase<SampleType>::getMinWorkloadDataSize (void) const
{
	return getMinWorkloadSize() * getVertexDataSize();
}

template <typename SampleType>
int RenderCase<SampleType>::getMaxWorkloadDataSize (void) const
{
	return getMaxWorkloadSize() * getVertexDataSize();
}

template <typename SampleType>
int RenderCase<SampleType>::getVertexDataSize (void) const
{
	const int numVectors	= 2;
	const int vec4Size		= 4 * sizeof(float);

	return numVectors * vec4Size;
}

template <typename SampleType>
int RenderCase<SampleType>::getNumSamples (void) const
{
	return (int)m_results.size();
}

template <typename SampleType>
void RenderCase<SampleType>::uploadScene (const LayeredGridSpec& scene)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	// vertex buffer
	{
		std::vector<tcu::Vec4> vertexData;

		generateLayeredGridVertexAttribData4C4V(vertexData, scene);

		if (m_attributeBufferID == 0)
			gl.genBuffers(1, &m_attributeBufferID);
		gl.bindBuffer(GL_ARRAY_BUFFER, m_attributeBufferID);
		gl.bufferData(GL_ARRAY_BUFFER, (int)(vertexData.size() * sizeof(tcu::Vec4)), &vertexData[0], GL_STATIC_DRAW);
	}

	// index buffer
	if (m_drawMethod == DRAWMETHOD_DRAW_ELEMENTS)
	{
		std::vector<deUint32> indexData;

		generateLayeredGridIndexData(indexData, scene);

		if (m_indexBufferID == 0)
			gl.genBuffers(1, &m_indexBufferID);
		gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBufferID);
		gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (int)(indexData.size() * sizeof(deUint32)), &indexData[0], GL_STATIC_DRAW);
	}

	GLU_EXPECT_NO_ERROR(gl.getError(), "create buffers");
}

template <typename SampleType>
void RenderCase<SampleType>::logAndSetTestResult (const std::vector<SampleResult>& results)
{
	std::vector<RenderSampleResult<SampleType> > mappedResults;

	mapResultsToRenderRateFormat(mappedResults, results);

	{
		const RenderSampleAnalyzeResult	analysis	= analyzeSampleResults(m_testCtx.getLog(), mappedResults);
		const float						rate		= analysis.renderRateAtRange;

		if (rate == std::numeric_limits<float>::infinity())
		{
			// sample times are 1) invalid or 2) timer resolution too low
			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::floatToString(0.0f, 2).c_str());
		}
		else
		{
			// report transfer rate in millions of MiB/s
			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::floatToString(rate / 1024.0f / 1024.0f, 2).c_str());
		}
	}
}

template <typename SampleType>
void RenderCase<SampleType>::mapResultsToRenderRateFormat (std::vector<RenderSampleResult<SampleType> >& dst, const std::vector<SampleResult>& src) const
{
	dst.resize(src.size());

	for (int ndx = 0; ndx < (int)src.size(); ++ndx)
		dst[ndx] = src[ndx].result;
}

class ReferenceRenderTimeCase : public RenderCase<RenderReadDuration>
{
public:
			ReferenceRenderTimeCase		(Context& context, const char* name, const char* description, DrawMethod drawMethod);

private:
	void	init						(void);
	void	runSample					(SampleResult& sample);
};

ReferenceRenderTimeCase::ReferenceRenderTimeCase (Context& context, const char* name, const char* description, DrawMethod drawMethod)
	: RenderCase<RenderReadDuration>	(context, name, description, drawMethod)
{
}

void ReferenceRenderTimeCase::init (void)
{
	const char* const targetFunctionName = (m_drawMethod == DRAWMETHOD_DRAW_ARRAYS) ? ("drawArrays") : ("drawElements");

	// init parent
	RenderCase<RenderReadDuration>::init();

	// log
	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Measuring the time used in " << targetFunctionName << " and readPixels call with different rendering workloads.\n"
		<< getNumSamples() << " test samples. Sample order is randomized.\n"
		<< "All samples at even positions (first = 0) are tested before samples at odd positions.\n"
		<< "Generated workload is multiple viewport-covering grids with varying number of cells, each cell is two separate triangles.\n"
		<< "Workload sizes are in the range ["
			<< getMinWorkloadSize() << ",  "
			<< getMaxWorkloadSize() << "] vertices (["
			<< getHumanReadableByteSize(getMinWorkloadDataSize()) << ","
			<< getHumanReadableByteSize(getMaxWorkloadDataSize()) << "] to be processed).\n"
		<< "Test result is the approximated total processing rate in MiB / s.\n"
		<< ((m_drawMethod == DRAWMETHOD_DRAW_ELEMENTS) ? ("Note that index array size is not included in the processed size.\n") : (""))
		<< "Note! Test result should only be used as a baseline reference result for buffer.data_upload.* test group results."
		<< tcu::TestLog::EndMessage;
}

void ReferenceRenderTimeCase::runSample (SampleResult& sample)
{
	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
	tcu::Surface			resultSurface	(RENDER_AREA_SIZE, RENDER_AREA_SIZE);
	const int				numVertices		= getLayeredGridNumVertices(sample.scene);
	const glu::Buffer		arrayBuffer		(m_context.getRenderContext());
	const glu::Buffer		indexBuffer		(m_context.getRenderContext());
	std::vector<tcu::Vec4>	vertexData;
	std::vector<deUint32>	indexData;
	deUint64				startTime;
	deUint64				endTime;

	// generate and upload buffers

	generateLayeredGridVertexAttribData4C4V(vertexData, sample.scene);
	gl.bindBuffer(GL_ARRAY_BUFFER, *arrayBuffer);
	gl.bufferData(GL_ARRAY_BUFFER, (int)(vertexData.size() * sizeof(tcu::Vec4)), &vertexData[0], GL_STATIC_DRAW);

	if (m_drawMethod == DRAWMETHOD_DRAW_ELEMENTS)
	{
		generateLayeredGridIndexData(indexData, sample.scene);
		gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, *indexBuffer);
		gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (int)(indexData.size() * sizeof(deUint32)), &indexData[0], GL_STATIC_DRAW);
	}

	setupVertexAttribs();

	// make sure data is uploaded

	if (m_drawMethod == DRAWMETHOD_DRAW_ARRAYS)
		gl.drawArrays(GL_TRIANGLES, 0, numVertices);
	else if (m_drawMethod == DRAWMETHOD_DRAW_ELEMENTS)
		gl.drawElements(GL_TRIANGLES, numVertices, GL_UNSIGNED_INT, DE_NULL);
	else
		DE_ASSERT(false);
	waitGLResults();

	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
	gl.clear(GL_COLOR_BUFFER_BIT);
	waitGLResults();

	tcu::warmupCPU();

	// Measure both draw and associated readpixels
	{
		startTime = deGetMicroseconds();

		if (m_drawMethod == DRAWMETHOD_DRAW_ARRAYS)
			gl.drawArrays(GL_TRIANGLES, 0, numVertices);
		else if (m_drawMethod == DRAWMETHOD_DRAW_ELEMENTS)
			gl.drawElements(GL_TRIANGLES, numVertices, GL_UNSIGNED_INT, DE_NULL);
		else
			DE_ASSERT(false);

		endTime = deGetMicroseconds();

		sample.result.duration.renderDuration = endTime - startTime;
	}

	{
		startTime = deGetMicroseconds();
		glu::readPixels(m_context.getRenderContext(), 0, 0, resultSurface.getAccess());
		endTime = deGetMicroseconds();

		sample.result.duration.readDuration = endTime - startTime;
	}

	sample.result.renderDataSize = getVertexDataSize() * sample.result.numVertices;
	sample.result.uploadedDataSize = 0;
	sample.result.unrelatedDataSize = 0;
	sample.result.duration.renderReadDuration = sample.result.duration.renderDuration + sample.result.duration.readDuration;
	sample.result.duration.totalDuration = sample.result.duration.renderDuration + sample.result.duration.readDuration;
	sample.result.duration.fitResponseDuration = sample.result.duration.renderReadDuration;
}

class UnrelatedUploadRenderTimeCase : public RenderCase<UnrelatedUploadRenderReadDuration>
{
public:
									UnrelatedUploadRenderTimeCase	(Context& context, const char* name, const char* description, DrawMethod drawMethod, UploadMethod unrelatedUploadMethod);

private:
	void							init							(void);
	void							runSample						(SampleResult& sample);

	const UploadMethod				m_unrelatedUploadMethod;
};

UnrelatedUploadRenderTimeCase::UnrelatedUploadRenderTimeCase (Context& context, const char* name, const char* description, DrawMethod drawMethod, UploadMethod unrelatedUploadMethod)
	: RenderCase<UnrelatedUploadRenderReadDuration>	(context, name, description, drawMethod)
	, m_unrelatedUploadMethod						(unrelatedUploadMethod)
{
	DE_ASSERT(m_unrelatedUploadMethod < UPLOADMETHOD_LAST);
}

void UnrelatedUploadRenderTimeCase::init (void)
{
	const char* const	targetFunctionName	= (m_drawMethod == DRAWMETHOD_DRAW_ARRAYS) ? ("drawArrays") : ("drawElements");
	tcu::MessageBuilder	message				(&m_testCtx.getLog());

	// init parent
	RenderCase<UnrelatedUploadRenderReadDuration>::init();

	// log

	message
		<< "Measuring the time used in " << targetFunctionName << " and readPixels call with different rendering workloads.\n"
		<< "Uploading an unrelated buffer just before issuing the rendering command with "
			<< ((m_unrelatedUploadMethod != UPLOADMETHOD_BUFFER_DATA)		? ("bufferData")		:
				(m_unrelatedUploadMethod != UPLOADMETHOD_BUFFER_SUB_DATA)	? ("bufferSubData")		:
				(m_unrelatedUploadMethod != UPLOADMETHOD_MAP_BUFFER_RANGE)	? ("mapBufferRange")	:
				((const char*)DE_NULL))
			<< ".\n"
		<< getNumSamples() << " test samples. Sample order is randomized.\n"
		<< "All samples at even positions (first = 0) are tested before samples at odd positions.\n"
		<< "Generated workload is multiple viewport-covering grids with varying number of cells, each cell is two separate triangles.\n"
		<< "Workload sizes are in the range ["
			<< getMinWorkloadSize() << ",  "
			<< getMaxWorkloadSize() << "] vertices (["
			<< getHumanReadableByteSize(getMinWorkloadDataSize()) << ","
			<< getHumanReadableByteSize(getMaxWorkloadDataSize()) << "] to be processed).\n"
		<< "Unrelated upload sizes are in the range ["
			<< getHumanReadableByteSize(getMinWorkloadDataSize()) << ", "
			<< getHumanReadableByteSize(getMaxWorkloadDataSize()) << "]\n"
		<< "Test result is the approximated total processing rate in MiB / s.\n"
		<< ((m_drawMethod == DRAWMETHOD_DRAW_ELEMENTS) ? ("Note that index array size is not included in the processed size.\n") : (""))
		<< "Note that the data size and the time used in the unrelated upload is not included in the results.\n"
		<< "Note! Test result may not be useful as is but instead should be compared against the reference.* group and upload_and_draw.*_and_unrelated_upload group results.\n"
		<< tcu::TestLog::EndMessage;
}

void UnrelatedUploadRenderTimeCase::runSample (SampleResult& sample)
{
	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
	tcu::Surface			resultSurface		(RENDER_AREA_SIZE, RENDER_AREA_SIZE);
	const int				numVertices			= getLayeredGridNumVertices(sample.scene);
	const glu::Buffer		arrayBuffer			(m_context.getRenderContext());
	const glu::Buffer		indexBuffer			(m_context.getRenderContext());
	const glu::Buffer		unrelatedBuffer		(m_context.getRenderContext());
	int						unrelatedUploadSize	= -1;
	int						renderUploadSize;
	std::vector<tcu::Vec4>	vertexData;
	std::vector<deUint32>	indexData;
	deUint64				startTime;
	deUint64				endTime;

	// generate and upload buffers

	generateLayeredGridVertexAttribData4C4V(vertexData, sample.scene);
	renderUploadSize = (int)(vertexData.size() * sizeof(tcu::Vec4));

	gl.bindBuffer(GL_ARRAY_BUFFER, *arrayBuffer);
	gl.bufferData(GL_ARRAY_BUFFER, renderUploadSize, &vertexData[0], GL_STATIC_DRAW);

	if (m_drawMethod == DRAWMETHOD_DRAW_ELEMENTS)
	{
		generateLayeredGridIndexData(indexData, sample.scene);
		gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, *indexBuffer);
		gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (int)(indexData.size() * sizeof(deUint32)), &indexData[0], GL_STATIC_DRAW);
	}

	setupVertexAttribs();

	// make sure data is uploaded

	if (m_drawMethod == DRAWMETHOD_DRAW_ARRAYS)
		gl.drawArrays(GL_TRIANGLES, 0, numVertices);
	else if (m_drawMethod == DRAWMETHOD_DRAW_ELEMENTS)
		gl.drawElements(GL_TRIANGLES, numVertices, GL_UNSIGNED_INT, DE_NULL);
	else
		DE_ASSERT(false);
	waitGLResults();

	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
	gl.clear(GL_COLOR_BUFFER_BIT);
	waitGLResults();

	tcu::warmupCPU();

	// Unrelated upload
	if (m_unrelatedUploadMethod == UPLOADMETHOD_BUFFER_DATA)
	{
		unrelatedUploadSize = (int)(vertexData.size() * sizeof(tcu::Vec4));

		gl.bindBuffer(GL_ARRAY_BUFFER, *unrelatedBuffer);
		gl.bufferData(GL_ARRAY_BUFFER, unrelatedUploadSize, &vertexData[0], GL_STATIC_DRAW);
	}
	else if (m_unrelatedUploadMethod == UPLOADMETHOD_BUFFER_SUB_DATA)
	{
		unrelatedUploadSize = (int)(vertexData.size() * sizeof(tcu::Vec4));

		gl.bindBuffer(GL_ARRAY_BUFFER, *unrelatedBuffer);
		gl.bufferData(GL_ARRAY_BUFFER, unrelatedUploadSize, DE_NULL, GL_STATIC_DRAW);
		gl.bufferSubData(GL_ARRAY_BUFFER, 0, unrelatedUploadSize, &vertexData[0]);
	}
	else if (m_unrelatedUploadMethod == UPLOADMETHOD_MAP_BUFFER_RANGE)
	{
		void*			mapPtr;
		glw::GLboolean	unmapSuccessful;

		unrelatedUploadSize = (int)(vertexData.size() * sizeof(tcu::Vec4));

		gl.bindBuffer(GL_ARRAY_BUFFER, *unrelatedBuffer);
		gl.bufferData(GL_ARRAY_BUFFER, unrelatedUploadSize, DE_NULL, GL_STATIC_DRAW);

		mapPtr = gl.mapBufferRange(GL_ARRAY_BUFFER, 0, unrelatedUploadSize, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
		if (!mapPtr)
			throw tcu::Exception("MapBufferRange returned NULL");

		deMemcpy(mapPtr, &vertexData[0], unrelatedUploadSize);

		// if unmapping fails, just try again later
		unmapSuccessful = gl.unmapBuffer(GL_ARRAY_BUFFER);
		if (!unmapSuccessful)
			throw UnmapFailureError();
	}
	else
		DE_ASSERT(false);

	DE_ASSERT(unrelatedUploadSize != -1);

	// Measure both draw and associated readpixels
	{
		startTime = deGetMicroseconds();

		if (m_drawMethod == DRAWMETHOD_DRAW_ARRAYS)
			gl.drawArrays(GL_TRIANGLES, 0, numVertices);
		else if (m_drawMethod == DRAWMETHOD_DRAW_ELEMENTS)
			gl.drawElements(GL_TRIANGLES, numVertices, GL_UNSIGNED_INT, DE_NULL);
		else
			DE_ASSERT(false);

		endTime = deGetMicroseconds();

		sample.result.duration.renderDuration = endTime - startTime;
	}

	{
		startTime = deGetMicroseconds();
		glu::readPixels(m_context.getRenderContext(), 0, 0, resultSurface.getAccess());
		endTime = deGetMicroseconds();

		sample.result.duration.readDuration = endTime - startTime;
	}

	sample.result.renderDataSize = getVertexDataSize() * sample.result.numVertices;
	sample.result.uploadedDataSize = renderUploadSize;
	sample.result.unrelatedDataSize = unrelatedUploadSize;
	sample.result.duration.renderReadDuration = sample.result.duration.renderDuration + sample.result.duration.readDuration;
	sample.result.duration.totalDuration = sample.result.duration.renderDuration + sample.result.duration.readDuration;
	sample.result.duration.fitResponseDuration = sample.result.duration.renderReadDuration;
}

class ReferenceReadPixelsTimeCase : public TestCase
{
public:
					ReferenceReadPixelsTimeCase		(Context& context, const char* name, const char* description);

private:
	void			init							(void);
	IterateResult	iterate							(void);
	void			logAndSetTestResult				(void);

	enum
	{
		RENDER_AREA_SIZE = 128
	};

	const int			m_numSamples;
	int					m_sampleNdx;
	std::vector<int>	m_samples;
};

ReferenceReadPixelsTimeCase::ReferenceReadPixelsTimeCase (Context& context, const char* name, const char* description)
	: TestCase		(context, tcu::NODETYPE_PERFORMANCE, name, description)
	, m_numSamples	(20)
	, m_sampleNdx	(0)
	, m_samples		(m_numSamples)
{
}

void ReferenceReadPixelsTimeCase::init (void)
{
	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Measuring the time used in a single readPixels call with " << m_numSamples << " test samples.\n"
		<< "Test result is the median of the samples in microseconds.\n"
		<< "Note! Test result should only be used as a baseline reference result for buffer.data_upload.* test group results."
		<< tcu::TestLog::EndMessage;
}

ReferenceReadPixelsTimeCase::IterateResult ReferenceReadPixelsTimeCase::iterate (void)
{
	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
	tcu::Surface			resultSurface	(RENDER_AREA_SIZE, RENDER_AREA_SIZE);
	deUint64				startTime;
	deUint64				endTime;

	deYield();
	tcu::warmupCPU();
	deYield();

	// "Render" something and wait for it
	gl.clearColor(0.0f, 1.0f, float(m_sampleNdx) / float(m_numSamples), 1.0f);
	gl.clear(GL_COLOR_BUFFER_BIT);

	// wait for results
	glu::readPixels(m_context.getRenderContext(), 0, 0, resultSurface.getAccess());

	// measure time used in readPixels
	startTime = deGetMicroseconds();
	glu::readPixels(m_context.getRenderContext(), 0, 0, resultSurface.getAccess());
	endTime = deGetMicroseconds();

	m_samples[m_sampleNdx] = (int)(endTime - startTime);

	if (++m_sampleNdx < m_numSamples)
		return CONTINUE;

	logAndSetTestResult();
	return STOP;
}

void ReferenceReadPixelsTimeCase::logAndSetTestResult (void)
{
	// Log sample list
	{
		m_testCtx.getLog()
			<< tcu::TestLog::SampleList("Samples", "Samples")
			<< tcu::TestLog::SampleInfo
			<< tcu::TestLog::ValueInfo("ReadTime", "ReadPixels time", "us", QP_SAMPLE_VALUE_TAG_RESPONSE)
			<< tcu::TestLog::EndSampleInfo;

		for (int sampleNdx = 0; sampleNdx < (int)m_samples.size(); ++sampleNdx)
			m_testCtx.getLog()
				<< tcu::TestLog::Sample
				<< m_samples[sampleNdx]
				<< tcu::TestLog::EndSample;

		m_testCtx.getLog() << tcu::TestLog::EndSampleList;
	}

	// Log median
	{
		float median;
		float limit60Low;
		float limit60Up;

		std::sort(m_samples.begin(), m_samples.end());
		median		= linearSample(m_samples, 0.5f);
		limit60Low	= linearSample(m_samples, 0.2f);
		limit60Up	= linearSample(m_samples, 0.8f);

		m_testCtx.getLog()
			<< tcu::TestLog::Float("Median", "Median", "us", QP_KEY_TAG_TIME, median)
			<< tcu::TestLog::Message
			<< "60 % of samples within range:\n"
			<< tcu::TestLog::EndMessage
			<< tcu::TestLog::Float("Low60Range", "Lower", "us", QP_KEY_TAG_TIME, limit60Low)
			<< tcu::TestLog::Float("High60Range", "Upper", "us", QP_KEY_TAG_TIME, limit60Up);

		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::floatToString(median, 2).c_str());
	}
}

template <typename SampleType>
class GenericUploadRenderTimeCase : public RenderCase<SampleType>
{
public:
	typedef typename RenderCase<SampleType>::SampleResult SampleResult;

							GenericUploadRenderTimeCase	(Context&				context,
														 const char*			name,
														 const char*			description,
														 DrawMethod				method,
														 TargetBuffer			targetBuffer,
														 UploadMethod			uploadMethod,
														 BufferState			bufferState,
														 UploadRange			uploadRange,
														 UnrelatedBufferType	unrelatedBufferType);

private:
	void						init					(void);
	void						runSample				(SampleResult& sample);

	using RenderCase<SampleType>::RENDER_AREA_SIZE;

	const TargetBuffer			m_targetBuffer;
	const BufferState			m_bufferState;
	const UploadMethod			m_uploadMethod;
	const UnrelatedBufferType	m_unrelatedBufferType;
	const UploadRange			m_uploadRange;

	using RenderCase<SampleType>::m_context;
	using RenderCase<SampleType>::m_testCtx;
	using RenderCase<SampleType>::m_drawMethod;
};

template <typename SampleType>
GenericUploadRenderTimeCase<SampleType>::GenericUploadRenderTimeCase (Context&				context,
																	  const char*			name,
																	  const char*			description,
																	  DrawMethod			method,
																	  TargetBuffer			targetBuffer,
																	  UploadMethod			uploadMethod,
																	  BufferState			bufferState,
																	  UploadRange			uploadRange,
																	  UnrelatedBufferType	unrelatedBufferType)
	: RenderCase<SampleType>	(context, name, description, method)
	, m_targetBuffer			(targetBuffer)
	, m_bufferState				(bufferState)
	, m_uploadMethod			(uploadMethod)
	, m_unrelatedBufferType		(unrelatedBufferType)
	, m_uploadRange				(uploadRange)
{
	DE_ASSERT(m_targetBuffer < TARGETBUFFER_LAST);
	DE_ASSERT(m_bufferState < BUFFERSTATE_LAST);
	DE_ASSERT(m_uploadMethod < UPLOADMETHOD_LAST);
	DE_ASSERT(m_unrelatedBufferType < UNRELATEDBUFFERTYPE_LAST);
	DE_ASSERT(m_uploadRange < UPLOADRANGE_LAST);
}

template <typename SampleType>
void GenericUploadRenderTimeCase<SampleType>::init (void)
{
	// init parent
	RenderCase<SampleType>::init();

	// log
	{
		const char* const	targetFunctionName		= (m_drawMethod == DRAWMETHOD_DRAW_ARRAYS) ? ("drawArrays") : ("drawElements");
		const int			perVertexSize			= (m_targetBuffer == TARGETBUFFER_INDEX) ? ((int)sizeof(deUint32)) : ((int)sizeof(tcu::Vec4[2]));
		const int			fullMinUploadSize		= RenderCase<SampleType>::getMinWorkloadSize() * perVertexSize;
		const int			fullMaxUploadSize		= RenderCase<SampleType>::getMaxWorkloadSize() * perVertexSize;
		const int			minUploadSize			= (m_uploadRange == UPLOADRANGE_FULL) ? (fullMinUploadSize) : (deAlign32(fullMinUploadSize/2, 4));
		const int			maxUploadSize			= (m_uploadRange == UPLOADRANGE_FULL) ? (fullMaxUploadSize) : (deAlign32(fullMaxUploadSize/2, 4));
		const int			minUnrelatedUploadSize	= RenderCase<SampleType>::getMinWorkloadSize() * (int)sizeof(tcu::Vec4[2]);
		const int			maxUnrelatedUploadSize	= RenderCase<SampleType>::getMaxWorkloadSize() * (int)sizeof(tcu::Vec4[2]);

		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Measuring the time used in " << targetFunctionName << " and readPixels call with different rendering workloads.\n"
			<< "The "
				<< ((m_targetBuffer == TARGETBUFFER_INDEX) ? ("index") : ("vertex attrib"))
				<< " buffer "
				<< ((m_bufferState == BUFFERSTATE_NEW) ? ("") : ("contents "))
				<< "sourced by the rendering command "
				<< ((m_bufferState == BUFFERSTATE_NEW)		? ("is uploaded ") :
					(m_uploadRange == UPLOADRANGE_FULL)		? ("are specified ") :
					(m_uploadRange == UPLOADRANGE_PARTIAL)	? ("are updated (partial upload) ") :
					((const char*)DE_NULL))
				<< "just before issuing the rendering command.\n"
			<< ((m_bufferState == BUFFERSTATE_EXISTING) ? ("The buffer has been used in rendering.\n") : ("The buffer is generated just before uploading.\n"))
			<< "Buffer "
				<< ((m_bufferState == BUFFERSTATE_NEW)		? ("is uploaded") :
					(m_uploadRange == UPLOADRANGE_FULL)		? ("contents are specified") :
					(m_uploadRange == UPLOADRANGE_PARTIAL)	? ("contents are partially updated") :
					((const char*)DE_NULL))
				<< " with "
				<< ((m_uploadMethod == UPLOADMETHOD_BUFFER_DATA) ? ("bufferData") : (m_uploadMethod == UPLOADMETHOD_BUFFER_SUB_DATA) ? ("bufferSubData") : ("mapBufferRange"))
				<< " command. Usage of the target buffer is DYNAMIC_DRAW.\n"
			<< ((m_uploadMethod == UPLOADMETHOD_MAP_BUFFER_RANGE) ? ("Mapping buffer with bits MAP_WRITE_BIT | MAP_INVALIDATE_RANGE_BIT | MAP_INVALIDATE_BUFFER_BIT | MAP_UNSYNCHRONIZED_BIT\n") : (""))
			<< ((m_unrelatedBufferType == UNRELATEDBUFFERTYPE_VERTEX) ? ("Uploading an unrelated buffer just before issuing the rendering command with bufferData.\n") : (""))
			<< RenderCase<SampleType>::getNumSamples() << " test samples. Sample order is randomized.\n"
			<< "All samples at even positions (first = 0) are tested before samples at odd positions.\n"
			<< "Generated workload is multiple viewport-covering grids with varying number of cells, each cell is two separate triangles.\n"
			<< "Workload sizes are in the range ["
				<< RenderCase<SampleType>::getMinWorkloadSize() << ",  "
				<< RenderCase<SampleType>::getMaxWorkloadSize() << "] vertices "
				<< "(["
				<< getHumanReadableByteSize(RenderCase<SampleType>::getMinWorkloadDataSize()) << ","
				<< getHumanReadableByteSize(RenderCase<SampleType>::getMaxWorkloadDataSize()) << "] to be processed).\n"
			<< "Upload sizes are in the range ["
				<< getHumanReadableByteSize(minUploadSize) << ","
				<< getHumanReadableByteSize(maxUploadSize) << "].\n"
			<< ((m_drawMethod == DRAWMETHOD_DRAW_ELEMENTS) ?
				("Unrelated upload sizes are in the range [" + getHumanReadableByteSize(minUnrelatedUploadSize) + ", " + getHumanReadableByteSize(maxUnrelatedUploadSize) + "]\n") :
				(""))
			<< "Test result is the approximated processing rate in MiB / s.\n"
			<< "Note that while upload time is measured, the time used is not included in the results.\n"
			<< ((m_unrelatedBufferType == UNRELATEDBUFFERTYPE_VERTEX) ? ("Note that the data size and the time used in the unrelated upload is not included in the results.\n") : (""))
			<< ((m_drawMethod == DRAWMETHOD_DRAW_ELEMENTS) ? ("Note that index array size is not included in the processed size.\n") : (""))
			<< "Note! Test result may not be useful as is but instead should be compared against the reference.* group and other upload_and_draw.* group results.\n"
			<< tcu::TestLog::EndMessage;
	}
}

template <typename SampleType>
void GenericUploadRenderTimeCase<SampleType>::runSample (SampleResult& sample)
{
	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
	const glu::Buffer		arrayBuffer			(m_context.getRenderContext());
	const glu::Buffer		indexBuffer			(m_context.getRenderContext());
	const glu::Buffer		unrelatedBuffer		(m_context.getRenderContext());
	const int				numVertices			= getLayeredGridNumVertices(sample.scene);
	tcu::Surface			resultSurface		(RENDER_AREA_SIZE, RENDER_AREA_SIZE);
	deUint64				startTime;
	deUint64				endTime;
	std::vector<tcu::Vec4>	vertexData;
	std::vector<deUint32>	indexData;

	// create data

	generateLayeredGridVertexAttribData4C4V(vertexData, sample.scene);
	if (m_drawMethod == DRAWMETHOD_DRAW_ELEMENTS)
		generateLayeredGridIndexData(indexData, sample.scene);

	gl.bindBuffer(GL_ARRAY_BUFFER, *arrayBuffer);
	gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, *indexBuffer);
	RenderCase<SampleType>::setupVertexAttribs();

	// target should be an exisiting buffer? Draw from it once to make sure it exists on the gpu

	if (m_drawMethod == DRAWMETHOD_DRAW_ARRAYS && m_bufferState == BUFFERSTATE_EXISTING)
	{
		gl.bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(vertexData.size() * sizeof(tcu::Vec4)), &vertexData[0], GL_DYNAMIC_DRAW);
		gl.drawArrays(GL_TRIANGLES, 0, numVertices);
	}
	else if (m_drawMethod == DRAWMETHOD_DRAW_ARRAYS && m_bufferState == BUFFERSTATE_NEW)
	{
		// do not touch the vertex buffer
	}
	else if (m_drawMethod == DRAWMETHOD_DRAW_ELEMENTS && m_bufferState == BUFFERSTATE_EXISTING)
	{
		// hint that the target buffer will be modified soon
		const glw::GLenum vertexDataUsage	= (m_targetBuffer == TARGETBUFFER_VERTEX) ? (GL_DYNAMIC_DRAW) : (GL_STATIC_DRAW);
		const glw::GLenum indexDataUsage	= (m_targetBuffer == TARGETBUFFER_INDEX) ? (GL_DYNAMIC_DRAW) : (GL_STATIC_DRAW);

		gl.bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(vertexData.size() * sizeof(tcu::Vec4)), &vertexData[0], vertexDataUsage);
		gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (glw::GLsizeiptr)(indexData.size() * sizeof(deUint32)), &indexData[0], indexDataUsage);
		gl.drawElements(GL_TRIANGLES, numVertices, GL_UNSIGNED_INT, DE_NULL);
	}
	else if (m_drawMethod == DRAWMETHOD_DRAW_ELEMENTS && m_bufferState == BUFFERSTATE_NEW)
	{
		if (m_targetBuffer == TARGETBUFFER_VERTEX)
		{
			// make the index buffer present on the gpu
			// use another vertex buffer to keep original buffer in unused state
			const glu::Buffer vertexCopyBuffer(m_context.getRenderContext());

			gl.bindBuffer(GL_ARRAY_BUFFER, *vertexCopyBuffer);
			RenderCase<SampleType>::setupVertexAttribs();

			gl.bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(vertexData.size() * sizeof(tcu::Vec4)), &vertexData[0], GL_STATIC_DRAW);
			gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (glw::GLsizeiptr)(indexData.size() * sizeof(deUint32)), &indexData[0], GL_STATIC_DRAW);
			gl.drawElements(GL_TRIANGLES, numVertices, GL_UNSIGNED_INT, DE_NULL);

			// restore original state
			gl.bindBuffer(GL_ARRAY_BUFFER, *arrayBuffer);
			RenderCase<SampleType>::setupVertexAttribs();
		}
		else if (m_targetBuffer == TARGETBUFFER_INDEX)
		{
			// make the vertex buffer present on the gpu
			gl.bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(vertexData.size() * sizeof(tcu::Vec4)), &vertexData[0], GL_STATIC_DRAW);
			gl.drawArrays(GL_TRIANGLES, 0, numVertices);
		}
		else
			DE_ASSERT(false);
	}
	else
		DE_ASSERT(false);

	RenderCase<SampleType>::waitGLResults();
	GLU_EXPECT_NO_ERROR(gl.getError(), "post buffer prepare");

	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
	gl.clear(GL_COLOR_BUFFER_BIT);
	RenderCase<SampleType>::waitGLResults();

	tcu::warmupCPU();

	// upload

	{
		glw::GLenum		target;
		glw::GLsizeiptr	size;
		glw::GLintptr	offset = 0;
		const void*		source;

		if (m_targetBuffer == TARGETBUFFER_VERTEX && m_uploadRange == UPLOADRANGE_FULL)
		{
			target	= GL_ARRAY_BUFFER;
			size	= (glw::GLsizeiptr)(vertexData.size() * sizeof(tcu::Vec4));
			source	= &vertexData[0];
		}
		else if (m_targetBuffer == TARGETBUFFER_INDEX && m_uploadRange == UPLOADRANGE_FULL)
		{
			target	= GL_ELEMENT_ARRAY_BUFFER;
			size	= (glw::GLsizeiptr)(indexData.size() * sizeof(deUint32));
			source	= &indexData[0];
		}
		else if (m_targetBuffer == TARGETBUFFER_VERTEX && m_uploadRange == UPLOADRANGE_PARTIAL)
		{
			DE_ASSERT(m_bufferState == BUFFERSTATE_EXISTING);

			target	= GL_ARRAY_BUFFER;
			size	= (glw::GLsizeiptr)deAlign32((int)(vertexData.size() * sizeof(tcu::Vec4)) / 2, 4);
			offset	= (glw::GLintptr)deAlign32((int)size / 2, 4);
			source	= (const deUint8*)&vertexData[0] + offset;
		}
		else if (m_targetBuffer == TARGETBUFFER_INDEX && m_uploadRange == UPLOADRANGE_PARTIAL)
		{
			DE_ASSERT(m_bufferState == BUFFERSTATE_EXISTING);

			// upload to 25% - 75% range
			target	= GL_ELEMENT_ARRAY_BUFFER;
			size	= (glw::GLsizeiptr)deAlign32((deInt32)(indexData.size() * sizeof(deUint32)) / 2, 4);
			offset	= (glw::GLintptr)deAlign32((int)size / 2, 4);
			source	= (const deUint8*)&indexData[0] + offset;
		}
		else
		{
			DE_ASSERT(false);
			return;
		}

		startTime = deGetMicroseconds();

		if (m_uploadMethod == UPLOADMETHOD_BUFFER_DATA)
			gl.bufferData(target, size, source, GL_DYNAMIC_DRAW);
		else if (m_uploadMethod == UPLOADMETHOD_BUFFER_SUB_DATA)
		{
			// create buffer storage
			if (m_bufferState == BUFFERSTATE_NEW)
				gl.bufferData(target, size, DE_NULL, GL_DYNAMIC_DRAW);
			gl.bufferSubData(target, offset, size, source);
		}
		else if (m_uploadMethod == UPLOADMETHOD_MAP_BUFFER_RANGE)
		{
			void*			mapPtr;
			glw::GLboolean	unmapSuccessful;

			// create buffer storage
			if (m_bufferState == BUFFERSTATE_NEW)
				gl.bufferData(target, size, DE_NULL, GL_DYNAMIC_DRAW);

			mapPtr = gl.mapBufferRange(target, offset, size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
			if (!mapPtr)
				throw tcu::Exception("MapBufferRange returned NULL");

			deMemcpy(mapPtr, source, (int)size);

			// if unmapping fails, just try again later
			unmapSuccessful = gl.unmapBuffer(target);
			if (!unmapSuccessful)
				throw UnmapFailureError();
		}
		else
			DE_ASSERT(false);

		endTime = deGetMicroseconds();

		sample.result.uploadedDataSize = (int)size;
		sample.result.duration.uploadDuration = endTime - startTime;
	}

	// unrelated
	if (m_unrelatedBufferType == UNRELATEDBUFFERTYPE_VERTEX)
	{
		const int unrelatedUploadSize = (int)(vertexData.size() * sizeof(tcu::Vec4));

		gl.bindBuffer(GL_ARRAY_BUFFER, *unrelatedBuffer);
		gl.bufferData(GL_ARRAY_BUFFER, unrelatedUploadSize, &vertexData[0], GL_STATIC_DRAW);
		// Attibute pointers are not modified, no need restore state

		sample.result.unrelatedDataSize = unrelatedUploadSize;
	}

	// draw
	{
		startTime = deGetMicroseconds();

		if (m_drawMethod == DRAWMETHOD_DRAW_ARRAYS)
			gl.drawArrays(GL_TRIANGLES, 0, numVertices);
		else if (m_drawMethod == DRAWMETHOD_DRAW_ELEMENTS)
			gl.drawElements(GL_TRIANGLES, numVertices, GL_UNSIGNED_INT, DE_NULL);
		else
			DE_ASSERT(false);

		endTime = deGetMicroseconds();

		sample.result.duration.renderDuration = endTime - startTime;
	}

	// read
	{
		startTime = deGetMicroseconds();
		glu::readPixels(m_context.getRenderContext(), 0, 0, resultSurface.getAccess());
		endTime = deGetMicroseconds();

		sample.result.duration.readDuration = endTime - startTime;
	}

	// set results

	sample.result.renderDataSize = RenderCase<SampleType>::getVertexDataSize() * sample.result.numVertices;

	sample.result.duration.renderReadDuration = sample.result.duration.renderDuration + sample.result.duration.readDuration;
	sample.result.duration.totalDuration = sample.result.duration.uploadDuration + sample.result.duration.renderDuration + sample.result.duration.readDuration;
	sample.result.duration.fitResponseDuration = sample.result.duration.renderReadDuration;
}

class BufferInUseRenderTimeCase : public RenderCase<RenderUploadRenderReadDuration>
{
public:
	enum MapFlags
	{
		MAPFLAG_NONE = 0,
		MAPFLAG_INVALIDATE_BUFFER,
		MAPFLAG_INVALIDATE_RANGE,

		MAPFLAG_LAST
	};
	enum UploadBufferTarget
	{
		UPLOADBUFFERTARGET_DIFFERENT_BUFFER = 0,
		UPLOADBUFFERTARGET_SAME_BUFFER,

		UPLOADBUFFERTARGET_LAST
	};
								BufferInUseRenderTimeCase	(Context&			context,
															 const char*		name,
															 const char*		description,
															 DrawMethod			method,
															 MapFlags			mapFlags,
															 TargetBuffer		targetBuffer,
															 UploadMethod		uploadMethod,
															 UploadRange		uploadRange,
															 UploadBufferTarget	uploadTarget);

private:
	void						init						(void);
	void						runSample					(SampleResult& sample);

	const TargetBuffer			m_targetBuffer;
	const UploadMethod			m_uploadMethod;
	const UploadRange			m_uploadRange;
	const MapFlags				m_mapFlags;
	const UploadBufferTarget	m_uploadBufferTarget;
};

BufferInUseRenderTimeCase::BufferInUseRenderTimeCase (Context&				context,
													  const char*			name,
													  const char*			description,
													  DrawMethod			method,
													  MapFlags				mapFlags,
													  TargetBuffer			targetBuffer,
													  UploadMethod			uploadMethod,
													  UploadRange			uploadRange,
													  UploadBufferTarget	uploadTarget)
	: RenderCase<RenderUploadRenderReadDuration>	(context, name, description, method)
	, m_targetBuffer								(targetBuffer)
	, m_uploadMethod								(uploadMethod)
	, m_uploadRange									(uploadRange)
	, m_mapFlags									(mapFlags)
	, m_uploadBufferTarget							(uploadTarget)
{
	DE_ASSERT(m_targetBuffer < TARGETBUFFER_LAST);
	DE_ASSERT(m_uploadMethod < UPLOADMETHOD_LAST);
	DE_ASSERT(m_uploadRange < UPLOADRANGE_LAST);
	DE_ASSERT(m_mapFlags < MAPFLAG_LAST);
	DE_ASSERT(m_uploadBufferTarget < UPLOADBUFFERTARGET_LAST);
}

void BufferInUseRenderTimeCase::init (void)
{
	RenderCase<RenderUploadRenderReadDuration>::init();

	// log
	{
		const char* const	targetFunctionName		= (m_drawMethod == DRAWMETHOD_DRAW_ARRAYS) ? ("drawArrays") : ("drawElements");
		const char* const	uploadFunctionName		= (m_uploadMethod == UPLOADMETHOD_BUFFER_DATA) ? ("bufferData") : (m_uploadMethod == UPLOADMETHOD_BUFFER_SUB_DATA) ? ("bufferSubData") : ("mapBufferRange");
		const bool			isReferenceCase			= (m_uploadBufferTarget == UPLOADBUFFERTARGET_DIFFERENT_BUFFER);
		tcu::MessageBuilder	message					(&m_testCtx.getLog());

		message	<< "Measuring the time used in " << targetFunctionName << " call, a buffer upload, "
				<< targetFunctionName << " call using the uploaded buffer and readPixels call with different upload sizes.\n";

		if (isReferenceCase)
			message << "Rendering:\n"
					<< "    before test: create and use buffers B and C\n"
					<< "    first draw: render using buffer B\n"
					<< ((m_uploadRange == UPLOADRANGE_FULL)		? ("    upload: respecify buffer C contents\n")	:
						(m_uploadRange == UPLOADRANGE_PARTIAL)	? ("    upload: modify buffer C contents\n")	:
						((const char*)DE_NULL))
					<< "    second draw: render using buffer C\n"
					<< "    read: readPixels\n";
		else
			message << "Rendering:\n"
					<< "    before test: create and use buffer B\n"
					<< "    first draw: render using buffer B\n"
					<< ((m_uploadRange == UPLOADRANGE_FULL)		? ("    upload: respecify buffer B contents\n")	:
						(m_uploadRange == UPLOADRANGE_PARTIAL)	? ("    upload: modify buffer B contents\n")	:
						((const char*)DE_NULL))
					<< "    second draw: render using buffer B\n"
					<< "    read: readPixels\n";

		message	<< "Uploading using " << uploadFunctionName
					<< ((m_mapFlags == MAPFLAG_INVALIDATE_RANGE)	? (", flags = MAP_WRITE_BIT | MAP_INVALIDATE_RANGE_BIT")	:
						(m_mapFlags == MAPFLAG_INVALIDATE_BUFFER)	? (", flags = MAP_WRITE_BIT | MAP_INVALIDATE_BUFFER_BIT")	:
						(m_mapFlags == MAPFLAG_NONE)				? ("")														:
						((const char*)DE_NULL))
					<< "\n"
				<< getNumSamples() << " test samples. Sample order is randomized.\n"
				<< "All samples at even positions (first = 0) are tested before samples at odd positions.\n"
				<< "Workload sizes are in the range ["
					<< getMinWorkloadSize() << ",  "
					<< getMaxWorkloadSize() << "] vertices "
					<< "(["
					<< getHumanReadableByteSize(getMinWorkloadDataSize()) << ","
					<< getHumanReadableByteSize(getMaxWorkloadDataSize()) << "] to be processed).\n"
				<< "Test result is the approximated processing rate in MiB / s of the second draw call and the readPixels call.\n";

		if (isReferenceCase)
			message	<< "Note! Test result should only be used as a baseline reference result for buffer.render_after_upload.draw_modify_draw test group results.";
		else
			message	<< "Note! Test result may not be useful as is but instead should be compared against the buffer.render_after_upload.reference.draw_upload_draw group results.\n";

		message << tcu::TestLog::EndMessage;
	}
}

void BufferInUseRenderTimeCase::runSample (SampleResult& sample)
{
	const glw::Functions&	gl						= m_context.getRenderContext().getFunctions();
	const glu::Buffer		arrayBuffer				(m_context.getRenderContext());
	const glu::Buffer		indexBuffer				(m_context.getRenderContext());
	const glu::Buffer		alternativeUploadBuffer	(m_context.getRenderContext());
	const int				numVertices				= getLayeredGridNumVertices(sample.scene);
	tcu::Surface			resultSurface			(RENDER_AREA_SIZE, RENDER_AREA_SIZE);
	deUint64				startTime;
	deUint64				endTime;
	std::vector<tcu::Vec4>	vertexData;
	std::vector<deUint32>	indexData;

	// create data

	generateLayeredGridVertexAttribData4C4V(vertexData, sample.scene);
	if (m_drawMethod == DRAWMETHOD_DRAW_ELEMENTS)
		generateLayeredGridIndexData(indexData, sample.scene);

	// make buffers used

	gl.bindBuffer(GL_ARRAY_BUFFER, *arrayBuffer);
	gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, *indexBuffer);
	setupVertexAttribs();

	if (m_drawMethod == DRAWMETHOD_DRAW_ARRAYS)
	{
		gl.bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(vertexData.size() * sizeof(tcu::Vec4)), &vertexData[0], GL_STREAM_DRAW);
		gl.drawArrays(GL_TRIANGLES, 0, numVertices);
	}
	else if (m_drawMethod == DRAWMETHOD_DRAW_ELEMENTS)
	{
		gl.bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(vertexData.size() * sizeof(tcu::Vec4)), &vertexData[0], GL_STREAM_DRAW);
		gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (glw::GLsizeiptr)(indexData.size() * sizeof(deUint32)), &indexData[0], GL_STREAM_DRAW);
		gl.drawElements(GL_TRIANGLES, numVertices, GL_UNSIGNED_INT, DE_NULL);
	}
	else
		DE_ASSERT(false);

	// another pair of buffers for reference case
	if (m_uploadBufferTarget == UPLOADBUFFERTARGET_DIFFERENT_BUFFER)
	{
		if (m_targetBuffer == TARGETBUFFER_VERTEX)
		{
			gl.bindBuffer(GL_ARRAY_BUFFER, *alternativeUploadBuffer);
			gl.bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(vertexData.size() * sizeof(tcu::Vec4)), &vertexData[0], GL_STREAM_DRAW);

			setupVertexAttribs();
			gl.drawArrays(GL_TRIANGLES, 0, numVertices);
		}
		else if (m_targetBuffer == TARGETBUFFER_INDEX)
		{
			gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, *alternativeUploadBuffer);
			gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (glw::GLsizeiptr)(indexData.size() * sizeof(deUint32)), &indexData[0], GL_STREAM_DRAW);
			gl.drawElements(GL_TRIANGLES, numVertices, GL_UNSIGNED_INT, DE_NULL);
		}
		else
			DE_ASSERT(false);

		// restore state
		gl.bindBuffer(GL_ARRAY_BUFFER, *arrayBuffer);
		gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, *indexBuffer);
		setupVertexAttribs();
	}

	waitGLResults();
	GLU_EXPECT_NO_ERROR(gl.getError(), "post buffer prepare");

	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
	gl.clear(GL_COLOR_BUFFER_BIT);
	waitGLResults();

	tcu::warmupCPU();

	// first draw
	{
		startTime = deGetMicroseconds();

		if (m_drawMethod == DRAWMETHOD_DRAW_ARRAYS)
			gl.drawArrays(GL_TRIANGLES, 0, numVertices);
		else if (m_drawMethod == DRAWMETHOD_DRAW_ELEMENTS)
			gl.drawElements(GL_TRIANGLES, numVertices, GL_UNSIGNED_INT, DE_NULL);
		else
			DE_ASSERT(false);

		endTime = deGetMicroseconds();

		sample.result.duration.firstRenderDuration = endTime - startTime;
	}

	// upload
	{
		glw::GLenum		target;
		glw::GLsizeiptr	size;
		glw::GLintptr	offset = 0;
		const void*		source;

		if (m_targetBuffer == TARGETBUFFER_VERTEX && m_uploadRange == UPLOADRANGE_FULL)
		{
			target	= GL_ARRAY_BUFFER;
			size	= (glw::GLsizeiptr)(vertexData.size() * sizeof(tcu::Vec4));
			source	= &vertexData[0];
		}
		else if (m_targetBuffer == TARGETBUFFER_INDEX && m_uploadRange == UPLOADRANGE_FULL)
		{
			target	= GL_ELEMENT_ARRAY_BUFFER;
			size	= (glw::GLsizeiptr)(indexData.size() * sizeof(deUint32));
			source	= &indexData[0];
		}
		else if (m_targetBuffer == TARGETBUFFER_VERTEX && m_uploadRange == UPLOADRANGE_PARTIAL)
		{
			target	= GL_ARRAY_BUFFER;
			size	= (glw::GLsizeiptr)deAlign32((int)(vertexData.size() * sizeof(tcu::Vec4)) / 2, 4);
			offset	= (glw::GLintptr)deAlign32((int)size / 2, 4);
			source	= (const deUint8*)&vertexData[0] + offset;
		}
		else if (m_targetBuffer == TARGETBUFFER_INDEX && m_uploadRange == UPLOADRANGE_PARTIAL)
		{
			// upload to 25% - 75% range
			target	= GL_ELEMENT_ARRAY_BUFFER;
			size	= (glw::GLsizeiptr)deAlign32((deInt32)(indexData.size() * sizeof(deUint32)) / 2, 4);
			offset	= (glw::GLintptr)deAlign32((int)size / 2, 4);
			source	= (const deUint8*)&indexData[0] + offset;
		}
		else
		{
			DE_ASSERT(false);
			return;
		}

		// reference case? don't modify the buffer in use
		if (m_uploadBufferTarget == UPLOADBUFFERTARGET_DIFFERENT_BUFFER)
			gl.bindBuffer(target, *alternativeUploadBuffer);

		startTime = deGetMicroseconds();

		if (m_uploadMethod == UPLOADMETHOD_BUFFER_DATA)
			gl.bufferData(target, size, source, GL_STREAM_DRAW);
		else if (m_uploadMethod == UPLOADMETHOD_BUFFER_SUB_DATA)
			gl.bufferSubData(target, offset, size, source);
		else if (m_uploadMethod == UPLOADMETHOD_MAP_BUFFER_RANGE)
		{
			const int		mapFlags	= (m_mapFlags == MAPFLAG_INVALIDATE_BUFFER)	? (GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT)	:
										  (m_mapFlags == MAPFLAG_INVALIDATE_RANGE)	? (GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT)	:
										  (-1);
			void*			mapPtr;
			glw::GLboolean	unmapSuccessful;

			mapPtr = gl.mapBufferRange(target, offset, size, mapFlags);
			if (!mapPtr)
				throw tcu::Exception("MapBufferRange returned NULL");

			deMemcpy(mapPtr, source, (int)size);

			// if unmapping fails, just try again later
			unmapSuccessful = gl.unmapBuffer(target);
			if (!unmapSuccessful)
				throw UnmapFailureError();
		}
		else
			DE_ASSERT(false);

		endTime = deGetMicroseconds();

		sample.result.uploadedDataSize = (int)size;
		sample.result.duration.uploadDuration = endTime - startTime;
	}

	// second draw
	{
		// Source vertex data from alternative buffer in refernce case
		if (m_uploadBufferTarget == UPLOADBUFFERTARGET_DIFFERENT_BUFFER && m_targetBuffer == TARGETBUFFER_VERTEX)
			setupVertexAttribs();

		startTime = deGetMicroseconds();

		if (m_drawMethod == DRAWMETHOD_DRAW_ARRAYS)
			gl.drawArrays(GL_TRIANGLES, 0, numVertices);
		else if (m_drawMethod == DRAWMETHOD_DRAW_ELEMENTS)
			gl.drawElements(GL_TRIANGLES, numVertices, GL_UNSIGNED_INT, DE_NULL);
		else
			DE_ASSERT(false);

		endTime = deGetMicroseconds();

		sample.result.duration.secondRenderDuration = endTime - startTime;
	}

	// read
	{
		startTime = deGetMicroseconds();
		glu::readPixels(m_context.getRenderContext(), 0, 0, resultSurface.getAccess());
		endTime = deGetMicroseconds();

		sample.result.duration.readDuration = endTime - startTime;
	}

	// set results

	sample.result.renderDataSize = getVertexDataSize() * sample.result.numVertices;

	sample.result.duration.renderReadDuration	= sample.result.duration.secondRenderDuration + sample.result.duration.readDuration;
	sample.result.duration.totalDuration		= sample.result.duration.firstRenderDuration +
												  sample.result.duration.uploadDuration +
												  sample.result.duration.secondRenderDuration +
												  sample.result.duration.readDuration;
	sample.result.duration.fitResponseDuration	= sample.result.duration.renderReadDuration;
}

class UploadWaitDrawCase : public RenderPerformanceTestBase
{
public:
	struct Sample
	{
		int			numFrames;
		deUint64	uploadCallEndTime;
	};
	struct Result
	{
		deUint64	uploadDuration;
		deUint64	renderDuration;
		deUint64	readDuration;
		deUint64	renderReadDuration;

		deUint64	timeBeforeUse;
	};

							UploadWaitDrawCase				(Context&		context,
															 const char*	name,
															 const char*	description,
															 DrawMethod		drawMethod,
															 TargetBuffer	targetBuffer,
															 UploadMethod	uploadMethod,
															 BufferState	bufferState);
							~UploadWaitDrawCase				(void);

private:
	void					init							(void);
	void					deinit							(void);
	IterateResult			iterate							(void);

	void					uploadBuffer					(Sample& sample, Result& result);
	void					drawFromBuffer					(Sample& sample, Result& result);
	void					reuseAndDeleteBuffer			(void);
	void					logAndSetTestResult				(void);
	void					logSamples						(void);
	void					drawMisc						(void);
	int						findStabilizationSample			(deUint64 (Result::*target), const char* description);
	bool					checkSampleTemporalStability	(deUint64 (Result::*target), const char* description);

	const DrawMethod		m_drawMethod;
	const TargetBuffer		m_targetBuffer;
	const UploadMethod		m_uploadMethod;
	const BufferState		m_bufferState;

	const int				m_numSamplesPerSwap;
	const int				m_numMaxSwaps;

	int						m_frameNdx;
	int						m_sampleNdx;
	int						m_numVertices;

	std::vector<tcu::Vec4>	m_vertexData;
	std::vector<deUint32>	m_indexData;
	std::vector<Sample>		m_samples;
	std::vector<Result>		m_results;
	std::vector<int>		m_iterationOrder;

	deUint32				m_vertexBuffer;
	deUint32				m_indexBuffer;
	deUint32				m_miscBuffer;
	int						m_numMiscVertices;
};

UploadWaitDrawCase::UploadWaitDrawCase (Context&		context,
										const char*		name,
										const char*		description,
										DrawMethod		drawMethod,
										TargetBuffer	targetBuffer,
										UploadMethod	uploadMethod,
										BufferState		bufferState)
	: RenderPerformanceTestBase	(context, name, description)
	, m_drawMethod				(drawMethod)
	, m_targetBuffer			(targetBuffer)
	, m_uploadMethod			(uploadMethod)
	, m_bufferState				(bufferState)
	, m_numSamplesPerSwap		(10)
	, m_numMaxSwaps				(4)
	, m_frameNdx				(0)
	, m_sampleNdx				(0)
	, m_numVertices				(-1)
	, m_vertexBuffer			(0)
	, m_indexBuffer				(0)
	, m_miscBuffer				(0)
	, m_numMiscVertices			(-1)
{
}

UploadWaitDrawCase::~UploadWaitDrawCase (void)
{
	deinit();
}

void UploadWaitDrawCase::init (void)
{
	const glw::Functions&	gl						= m_context.getRenderContext().getFunctions();
	const int				vertexAttribSize		= (int)sizeof(tcu::Vec4) * 2; // color4, position4
	const int				vertexIndexSize			= (int)sizeof(deUint32);
	const int				vertexUploadDataSize	= (m_targetBuffer == TARGETBUFFER_VERTEX) ? (vertexAttribSize) : (vertexIndexSize);

	RenderPerformanceTestBase::init();

	// requirements

	if (m_context.getRenderTarget().getWidth() < RENDER_AREA_SIZE ||
		m_context.getRenderTarget().getHeight() < RENDER_AREA_SIZE)
		throw tcu::NotSupportedError("Test case requires " + de::toString<int>(RENDER_AREA_SIZE) + "x" + de::toString<int>(RENDER_AREA_SIZE) + " render target");

	// gl state

	gl.viewport(0, 0, RENDER_AREA_SIZE, RENDER_AREA_SIZE);

	// enable bleding to prevent grid layers from being discarded

	gl.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	gl.blendEquation(GL_FUNC_ADD);
	gl.enable(GL_BLEND);

	// scene

	{
		LayeredGridSpec scene;

		// create ~8MB workload with similar characteristics as in the other test
		// => makes comparison to other results more straightforward
		scene.gridWidth = 93;
		scene.gridHeight = 93;
		scene.gridLayers = 5;

		generateLayeredGridVertexAttribData4C4V(m_vertexData, scene);
		generateLayeredGridIndexData(m_indexData, scene);
		m_numVertices = getLayeredGridNumVertices(scene);
	}

	// buffers

	if (m_bufferState == BUFFERSTATE_NEW)
	{
		if (m_drawMethod == DRAWMETHOD_DRAW_ELEMENTS)
		{
			// reads from two buffers, prepare the static buffer

			if (m_targetBuffer == TARGETBUFFER_VERTEX)
			{
				// index buffer is static, use another vertex buffer to keep original buffer in unused state
				const glu::Buffer vertexCopyBuffer(m_context.getRenderContext());

				gl.genBuffers(1, &m_indexBuffer);
				gl.bindBuffer(GL_ARRAY_BUFFER, *vertexCopyBuffer);
				gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer);
				gl.bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(m_vertexData.size() * sizeof(tcu::Vec4)), &m_vertexData[0], GL_STATIC_DRAW);
				gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (glw::GLsizeiptr)(m_indexData.size() * sizeof(deUint32)), &m_indexData[0], GL_STATIC_DRAW);

				setupVertexAttribs();
				gl.drawElements(GL_TRIANGLES, m_numVertices, GL_UNSIGNED_INT, DE_NULL);
			}
			else if (m_targetBuffer == TARGETBUFFER_INDEX)
			{
				// vertex buffer is static
				gl.genBuffers(1, &m_vertexBuffer);
				gl.bindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
				gl.bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(m_vertexData.size() * sizeof(tcu::Vec4)), &m_vertexData[0], GL_STATIC_DRAW);

				setupVertexAttribs();
				gl.drawArrays(GL_TRIANGLES, 0, m_numVertices);
			}
			else
				DE_ASSERT(false);
		}
	}
	else if (m_bufferState == BUFFERSTATE_EXISTING)
	{
		const glw::GLenum vertexUsage	= (m_targetBuffer == TARGETBUFFER_VERTEX) ? (GL_STATIC_DRAW) : (GL_STATIC_DRAW);
		const glw::GLenum indexUsage	= (m_targetBuffer == TARGETBUFFER_INDEX) ? (GL_STATIC_DRAW) : (GL_STATIC_DRAW);

		gl.genBuffers(1, &m_vertexBuffer);
		gl.bindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
		gl.bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(m_vertexData.size() * sizeof(tcu::Vec4)), &m_vertexData[0], vertexUsage);

		if (m_drawMethod == DRAWMETHOD_DRAW_ELEMENTS)
		{
			gl.genBuffers(1, &m_indexBuffer);
			gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer);
			gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (glw::GLsizeiptr)(m_indexData.size() * sizeof(deUint32)), &m_indexData[0], indexUsage);
		}

		setupVertexAttribs();

		if (m_drawMethod == DRAWMETHOD_DRAW_ARRAYS)
			gl.drawArrays(GL_TRIANGLES, 0, m_numVertices);
		else if (m_drawMethod == DRAWMETHOD_DRAW_ELEMENTS)
			gl.drawElements(GL_TRIANGLES, m_numVertices, GL_UNSIGNED_INT, DE_NULL);
		else
			DE_ASSERT(false);
	}
	else
		DE_ASSERT(false);

	// misc draw buffer
	{
		std::vector<tcu::Vec4>	vertexData;
		LayeredGridSpec			scene;

		// create ~1.5MB workload with similar characteristics
		scene.gridWidth = 40;
		scene.gridHeight = 40;
		scene.gridLayers = 5;

		generateLayeredGridVertexAttribData4C4V(vertexData, scene);

		gl.genBuffers(1, &m_miscBuffer);
		gl.bindBuffer(GL_ARRAY_BUFFER, m_miscBuffer);
		gl.bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(sizeof(tcu::Vec4) * vertexData.size()), &vertexData[0], GL_STATIC_DRAW);

		m_numMiscVertices = getLayeredGridNumVertices(scene);
	}

	// iterations
	{
		m_samples.resize((m_numMaxSwaps+1) * m_numSamplesPerSwap);
		m_results.resize((m_numMaxSwaps+1) * m_numSamplesPerSwap);

		for (int numSwaps = 0; numSwaps <= m_numMaxSwaps; ++numSwaps)
		for (int sampleNdx = 0; sampleNdx < m_numSamplesPerSwap; ++sampleNdx)
		{
			const int index = numSwaps*m_numSamplesPerSwap + sampleNdx;

			m_samples[index].numFrames = numSwaps;
		}

		m_iterationOrder.resize(m_samples.size());
		generateTwoPassRandomIterationOrder(m_iterationOrder, (int)m_samples.size());
	}

	// log
	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Measuring time used in " << ((m_drawMethod == DRAWMETHOD_DRAW_ARRAYS) ? ("drawArrays") : ("drawElements")) << " and readPixels call.\n"
		<< "Drawing using a buffer that has been uploaded N frames ago. Testing with N within range [0, " << m_numMaxSwaps << "].\n"
		<< "Uploaded buffer is a " << ((m_targetBuffer == TARGETBUFFER_VERTEX) ? ("vertex attribute") : ("index")) << " buffer.\n"
		<< "Uploading using "
			<< ((m_uploadMethod == UPLOADMETHOD_BUFFER_DATA)		? ("bufferData")																							:
				(m_uploadMethod == UPLOADMETHOD_BUFFER_SUB_DATA)	? ("bufferSubData")																							:
				(m_uploadMethod == UPLOADMETHOD_MAP_BUFFER_RANGE)	? ("mapBufferRange, flags = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT")	:
				((const char*)DE_NULL))
			<< "\n"
		<< "Upload size is " << getHumanReadableByteSize(m_numVertices * vertexUploadDataSize) << ".\n"
		<< ((m_bufferState == BUFFERSTATE_EXISTING) ? ("All test samples use the same buffer object.\n") : (""))
		<< "Test result is the number of frames (swaps) required for the render time to stabilize.\n"
		<< "Assuming combined time used in the draw call and readPixels call is stabilizes to a constant value.\n"
		<< tcu::TestLog::EndMessage;
}

void UploadWaitDrawCase::deinit (void)
{
	RenderPerformanceTestBase::deinit();

	if (m_vertexBuffer)
	{
		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_vertexBuffer);
		m_vertexBuffer = 0;
	}
	if (m_indexBuffer)
	{
		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_indexBuffer);
		m_indexBuffer = 0;
	}
	if (m_miscBuffer)
	{
		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_miscBuffer);
		m_miscBuffer = 0;
	}
}

UploadWaitDrawCase::IterateResult UploadWaitDrawCase::iterate (void)
{
	const glw::Functions&	gl								= m_context.getRenderContext().getFunctions();
	const int				betweenIterationFrameCount		= 5; // draw misc between test samples
	const int				frameNdx						= m_frameNdx++;
	const int				currentSampleNdx				= m_iterationOrder[m_sampleNdx];

	// Simulate work for about 8ms
	busyWait(8000);

	// Busywork rendering during unused frames
	if (frameNdx != m_samples[currentSampleNdx].numFrames)
	{
		// draw similar from another buffer
		drawMisc();
	}

	if (frameNdx == 0)
	{
		// upload and start the clock
		uploadBuffer(m_samples[currentSampleNdx], m_results[currentSampleNdx]);
	}

	if (frameNdx == m_samples[currentSampleNdx].numFrames) // \note: not else if, m_samples[currentSampleNdx].numFrames can be 0
	{
		// draw using the uploaded buffer
		drawFromBuffer(m_samples[currentSampleNdx], m_results[currentSampleNdx]);

		// re-use buffer for something else to make sure test iteration do not affect each other
		if (m_bufferState == BUFFERSTATE_NEW)
			reuseAndDeleteBuffer();
	}
	else if (frameNdx == m_samples[currentSampleNdx].numFrames + betweenIterationFrameCount)
	{
		// next sample
		++m_sampleNdx;
		m_frameNdx = 0;
	}

	GLU_EXPECT_NO_ERROR(gl.getError(), "post-iterate");

	if (m_sampleNdx < (int)m_samples.size())
		return CONTINUE;

	logAndSetTestResult();
	return STOP;
}

void UploadWaitDrawCase::uploadBuffer (Sample& sample, Result& result)
{
	const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
	deUint64				startTime;
	deUint64				endTime;
	glw::GLenum				target;
	glw::GLsizeiptr			size;
	const void*				source;

	// data source

	if (m_targetBuffer == TARGETBUFFER_VERTEX)
	{
		DE_ASSERT((m_vertexBuffer == 0) == (m_bufferState == BUFFERSTATE_NEW));

		target	= GL_ARRAY_BUFFER;
		size	= (glw::GLsizeiptr)(m_vertexData.size() * sizeof(tcu::Vec4));
		source	= &m_vertexData[0];
	}
	else if (m_targetBuffer == TARGETBUFFER_INDEX)
	{
		DE_ASSERT((m_indexBuffer == 0) == (m_bufferState == BUFFERSTATE_NEW));

		target	= GL_ELEMENT_ARRAY_BUFFER;
		size	= (glw::GLsizeiptr)(m_indexData.size() * sizeof(deUint32));
		source	= &m_indexData[0];
	}
	else
	{
		DE_ASSERT(false);
		return;
	}

	// gen buffer

	if (m_bufferState == BUFFERSTATE_NEW)
	{
		if (m_targetBuffer == TARGETBUFFER_VERTEX)
		{
			gl.genBuffers(1, &m_vertexBuffer);
			gl.bindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
		}
		else if (m_targetBuffer == TARGETBUFFER_INDEX)
		{
			gl.genBuffers(1, &m_indexBuffer);
			gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer);
		}
		else
			DE_ASSERT(false);

		if (m_uploadMethod == UPLOADMETHOD_BUFFER_SUB_DATA ||
			m_uploadMethod == UPLOADMETHOD_MAP_BUFFER_RANGE)
		{
			gl.bufferData(target, size, DE_NULL, GL_STATIC_DRAW);
		}
	}
	else if (m_bufferState == BUFFERSTATE_EXISTING)
	{
		if (m_targetBuffer == TARGETBUFFER_VERTEX)
			gl.bindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
		else if (m_targetBuffer == TARGETBUFFER_INDEX)
			gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer);
		else
			DE_ASSERT(false);
	}
	else
		DE_ASSERT(false);

	// upload

	startTime = deGetMicroseconds();

	if (m_uploadMethod == UPLOADMETHOD_BUFFER_DATA)
		gl.bufferData(target, size, source, GL_STATIC_DRAW);
	else if (m_uploadMethod == UPLOADMETHOD_BUFFER_SUB_DATA)
		gl.bufferSubData(target, 0, size, source);
	else if (m_uploadMethod == UPLOADMETHOD_MAP_BUFFER_RANGE)
	{
		void*			mapPtr;
		glw::GLboolean	unmapSuccessful;

		mapPtr = gl.mapBufferRange(target, 0, size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
		if (!mapPtr)
			throw tcu::Exception("MapBufferRange returned NULL");

		deMemcpy(mapPtr, source, (int)size);

		// if unmapping fails, just try again later
		unmapSuccessful = gl.unmapBuffer(target);
		if (!unmapSuccessful)
			throw UnmapFailureError();
	}
	else
		DE_ASSERT(false);

	endTime = deGetMicroseconds();

	sample.uploadCallEndTime = endTime;
	result.uploadDuration = endTime - startTime;
}

void UploadWaitDrawCase::drawFromBuffer (Sample& sample, Result& result)
{
	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
	tcu::Surface			resultSurface	(RENDER_AREA_SIZE, RENDER_AREA_SIZE);
	deUint64				startTime;
	deUint64				endTime;

	DE_ASSERT(m_vertexBuffer != 0);
	if (m_drawMethod == DRAWMETHOD_DRAW_ARRAYS)
		DE_ASSERT(m_indexBuffer == 0);
	else if (m_drawMethod == DRAWMETHOD_DRAW_ELEMENTS)
		DE_ASSERT(m_indexBuffer != 0);
	else
		DE_ASSERT(false);

	// draw
	{
		gl.bindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
		if (m_drawMethod == DRAWMETHOD_DRAW_ELEMENTS)
			gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer);

		setupVertexAttribs();

		// microseconds passed since return from upload call
		result.timeBeforeUse = deGetMicroseconds() - sample.uploadCallEndTime;

		startTime = deGetMicroseconds();

		if (m_drawMethod == DRAWMETHOD_DRAW_ARRAYS)
			gl.drawArrays(GL_TRIANGLES, 0, m_numVertices);
		else if (m_drawMethod == DRAWMETHOD_DRAW_ELEMENTS)
			gl.drawElements(GL_TRIANGLES, m_numVertices, GL_UNSIGNED_INT, DE_NULL);
		else
			DE_ASSERT(false);

		endTime = deGetMicroseconds();

		result.renderDuration = endTime - startTime;
	}

	// read
	{
		startTime = deGetMicroseconds();
		glu::readPixels(m_context.getRenderContext(), 0, 0, resultSurface.getAccess());
		endTime = deGetMicroseconds();

		result.readDuration = endTime - startTime;
	}

	result.renderReadDuration = result.renderDuration + result.readDuration;
}

void UploadWaitDrawCase::reuseAndDeleteBuffer (void)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (m_targetBuffer == TARGETBUFFER_INDEX)
	{
		// respecify and delete index buffer
		static const deUint32 indices[3] = {1, 3, 8};

		DE_ASSERT(m_indexBuffer != 0);

		gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
		gl.drawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, DE_NULL);
		gl.deleteBuffers(1, &m_indexBuffer);
		m_indexBuffer = 0;
	}
	else if (m_targetBuffer == TARGETBUFFER_VERTEX)
	{
		// respecify and delete vertex buffer
		static const tcu::Vec4 coloredTriangle[6] =
		{
			tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(-0.4f, -0.4f, 0.0f, 1.0f),
			tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(-0.2f,  0.4f, 0.0f, 1.0f),
			tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4( 0.8f, -0.1f, 0.0f, 1.0f),
		};

		DE_ASSERT(m_vertexBuffer != 0);

		gl.bufferData(GL_ARRAY_BUFFER, sizeof(coloredTriangle), coloredTriangle, GL_STATIC_DRAW);
		gl.drawArrays(GL_TRIANGLES, 0, 3);
		gl.deleteBuffers(1, &m_vertexBuffer);
		m_vertexBuffer = 0;
	}

	waitGLResults();
}

void UploadWaitDrawCase::logAndSetTestResult (void)
{
	int		uploadStabilization;
	int		renderReadStabilization;
	int		renderStabilization;
	int		readStabilization;
	bool	temporallyStable;

	{
		const tcu::ScopedLogSection section(m_testCtx.getLog(), "Samples", "Result samples");
		logSamples();
	}

	{
		const tcu::ScopedLogSection section(m_testCtx.getLog(), "Stabilization", "Sample stability");

		// log stabilization points
		renderReadStabilization	= findStabilizationSample(&Result::renderReadDuration, "Combined draw and read");
		uploadStabilization		= findStabilizationSample(&Result::uploadDuration, "Upload time");
		renderStabilization		= findStabilizationSample(&Result::renderDuration, "Draw call time");
		readStabilization		= findStabilizationSample(&Result::readDuration, "ReadPixels time");

		temporallyStable		= true;
		temporallyStable		&= checkSampleTemporalStability(&Result::renderReadDuration, "Combined draw and read");
		temporallyStable		&= checkSampleTemporalStability(&Result::uploadDuration, "Upload time");
		temporallyStable		&= checkSampleTemporalStability(&Result::renderDuration, "Draw call time");
		temporallyStable		&= checkSampleTemporalStability(&Result::readDuration, "ReadPixels time");
	}

	{
		const tcu::ScopedLogSection section(m_testCtx.getLog(), "Results", "Results");

		// Check result sanily
		if (uploadStabilization != 0)
			m_testCtx.getLog() << tcu::TestLog::Message << "Warning! Upload times are not stable, test result may not be accurate." << tcu::TestLog::EndMessage;
		if (!temporallyStable)
			m_testCtx.getLog() << tcu::TestLog::Message << "Warning! Time samples do not seem to be temporally stable, sample times seem to drift to one direction during test execution." << tcu::TestLog::EndMessage;

		// render & read
		if (renderReadStabilization == -1)
			m_testCtx.getLog() << tcu::TestLog::Message << "Combined time used in draw call and ReadPixels did not stabilize." << tcu::TestLog::EndMessage;
		else
			m_testCtx.getLog() << tcu::TestLog::Integer("RenderReadStabilizationPoint", "Combined draw call and ReadPixels call time stabilization time", "frames", QP_KEY_TAG_TIME, renderReadStabilization);

		// draw call
		if (renderStabilization == -1)
			m_testCtx.getLog() << tcu::TestLog::Message << "Time used in draw call did not stabilize." << tcu::TestLog::EndMessage;
		else
			m_testCtx.getLog() << tcu::TestLog::Integer("DrawCallStabilizationPoint", "Draw call time stabilization time", "frames", QP_KEY_TAG_TIME, renderStabilization);

		// readpixels
		if (readStabilization == -1)
			m_testCtx.getLog() << tcu::TestLog::Message << "Time used in ReadPixels did not stabilize." << tcu::TestLog::EndMessage;
		else
			m_testCtx.getLog() << tcu::TestLog::Integer("ReadPixelsStabilizationPoint", "ReadPixels call time stabilization time", "frames", QP_KEY_TAG_TIME, readStabilization);

		// Report renderReadStabilization
		if (renderReadStabilization != -1)
			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::toString(renderReadStabilization).c_str());
		else
			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::toString(m_numMaxSwaps).c_str()); // don't report -1
	}
}

void UploadWaitDrawCase::logSamples (void)
{
	// Inverse m_iterationOrder

	std::vector<int> runOrder(m_iterationOrder.size());
	for (int ndx = 0; ndx < (int)m_iterationOrder.size(); ++ndx)
		runOrder[m_iterationOrder[ndx]] = ndx;

	// Log samples

	m_testCtx.getLog()
		<< tcu::TestLog::SampleList("Samples", "Samples")
		<< tcu::TestLog::SampleInfo
		<< tcu::TestLog::ValueInfo("NumSwaps",		"SwapBuffers before use",			"",		QP_SAMPLE_VALUE_TAG_PREDICTOR)
		<< tcu::TestLog::ValueInfo("Delay",			"Time before use",					"us",	QP_SAMPLE_VALUE_TAG_PREDICTOR)
		<< tcu::TestLog::ValueInfo("RunOrder",		"Sample run order",					"",		QP_SAMPLE_VALUE_TAG_PREDICTOR)
		<< tcu::TestLog::ValueInfo("DrawReadTime",	"Draw call and ReadPixels time",	"us",	QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("TotalTime",		"Total time",						"us",	QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("Upload time",	"Upload time",						"us",	QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("DrawCallTime",	"Draw call time",					"us",	QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::ValueInfo("ReadTime",		"ReadPixels time",					"us",	QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< tcu::TestLog::EndSampleInfo;

	for (int sampleNdx = 0; sampleNdx < (int)m_samples.size(); ++sampleNdx)
		m_testCtx.getLog()
			<< tcu::TestLog::Sample
			<< m_samples[sampleNdx].numFrames
			<< (int)m_results[sampleNdx].timeBeforeUse
			<< runOrder[sampleNdx]
			<< (int)m_results[sampleNdx].renderReadDuration
			<< (int)(m_results[sampleNdx].renderReadDuration + m_results[sampleNdx].uploadDuration)
			<< (int)m_results[sampleNdx].uploadDuration
			<< (int)m_results[sampleNdx].renderDuration
			<< (int)m_results[sampleNdx].readDuration
			<< tcu::TestLog::EndSample;

	m_testCtx.getLog() << tcu::TestLog::EndSampleList;
}

void UploadWaitDrawCase::drawMisc (void)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.bindBuffer(GL_ARRAY_BUFFER, m_miscBuffer);
	setupVertexAttribs();
	gl.drawArrays(GL_TRIANGLES, 0, m_numMiscVertices);
}

struct DistributionCompareResult
{
	bool	equal;
	float	standardDeviations;
};

template <typename Comparer>
static float sumOfRanks (const std::vector<deUint64>& testSamples, const std::vector<deUint64>& allSamples, const Comparer& comparer)
{
	float sum = 0;

	for (int sampleNdx = 0; sampleNdx < (int)testSamples.size(); ++sampleNdx)
	{
		const deUint64	testSample		= testSamples[sampleNdx];
		const int		lowerIndex		= (int)(std::lower_bound(allSamples.begin(), allSamples.end(), testSample, comparer) - allSamples.begin());
		const int		upperIndex		= (int)(std::upper_bound(allSamples.begin(), allSamples.end(), testSample, comparer) - allSamples.begin());
		const int		lowerRank		= lowerIndex + 1;	// convert zero-indexed to rank
		const int		upperRank		= upperIndex;		// convert zero-indexed to rank, upperIndex is last equal + 1
		const float		rankMidpoint	= (float)(lowerRank + upperRank) / 2.0f;

		sum += rankMidpoint;
	}

	return sum;
}

template <typename Comparer>
static DistributionCompareResult distributionCompare (const std::vector<deUint64>& orderedObservationsA, const std::vector<deUint64>& orderedObservationsB, const Comparer& comparer)
{
	// Mann-Whitney U test

	const int				n1			= (int)orderedObservationsA.size();
	const int				n2			= (int)orderedObservationsB.size();
	std::vector<deUint64>	allSamples	(n1 + n2);

	std::copy(orderedObservationsA.begin(), orderedObservationsA.end(), allSamples.begin());
	std::copy(orderedObservationsB.begin(), orderedObservationsB.end(), allSamples.begin() + n1);
	std::sort(allSamples.begin(), allSamples.end());

	{
		const float					R1		= sumOfRanks(orderedObservationsA, allSamples, comparer);

		const float					U1		= (float)(n1*n2 + n1*(n1 + 1)/2) - R1;
		const float					U2		= (float)(n1 * n2) - U1;
		const float					U		= de::min(U1, U2);

		// \note: sample sizes might not be large enough to expect normal distribution but we do it anyway

		const float					mU		= (float)(n1 * n2) / 2.0f;
		const float					sigmaU	= deFloatSqrt((float)(n1*n2*(n1+n2+1)) / 12.0f);
		const float					z		= (U - mU) / sigmaU;

		DistributionCompareResult	result;

		result.equal				= (de::abs(z) <= 1.96f); // accept within 95% confidence interval
		result.standardDeviations	= z;

		return result;
	}
}

template <typename T>
struct ThresholdComparer
{
	float	relativeThreshold;
	T		absoluteThreshold;

	bool operator() (const T& a, const T& b) const
	{
		const float diff = de::abs((float)a - (float)b);

		// thresholds
		if (diff <= (float)absoluteThreshold)
			return false;
		if (diff <= float(a)*relativeThreshold ||
			diff <= float(b)*relativeThreshold)
			return false;

		// cmp
		return a < b;
	}
};

int UploadWaitDrawCase::findStabilizationSample (deUint64 (UploadWaitDrawCase::Result::*target), const char* description)
{
	std::vector<std::vector<deUint64> >	sampleObservations(m_numMaxSwaps+1);
	ThresholdComparer<deUint64>			comparer;

	comparer.relativeThreshold = 0.15f;	// 15%
	comparer.absoluteThreshold = 100;	// (us), assumed sampling precision

	// get observations and order them

	for (int swapNdx = 0; swapNdx <= m_numMaxSwaps; ++swapNdx)
	{
		int insertNdx = 0;

		sampleObservations[swapNdx].resize(m_numSamplesPerSwap);

		for (int ndx = 0; ndx < (int)m_samples.size(); ++ndx)
			if (m_samples[ndx].numFrames == swapNdx)
				sampleObservations[swapNdx][insertNdx++] = m_results[ndx].*target;

		DE_ASSERT(insertNdx == m_numSamplesPerSwap);

		std::sort(sampleObservations[swapNdx].begin(), sampleObservations[swapNdx].end());
	}

	// find stabilization point

	for (int sampleNdx = m_numMaxSwaps-1; sampleNdx != -1; --sampleNdx )
	{
		// Distribution is equal to all following distributions
		for (int cmpTargetDistribution = sampleNdx+1; cmpTargetDistribution <= m_numMaxSwaps; ++cmpTargetDistribution)
		{
			// Stable section ends here?
			const DistributionCompareResult result = distributionCompare(sampleObservations[sampleNdx], sampleObservations[cmpTargetDistribution], comparer);
			if (!result.equal)
			{
				// Last two samples are not equal? Samples never stabilized
				if (sampleNdx == m_numMaxSwaps-1)
				{
					m_testCtx.getLog()
						<< tcu::TestLog::Message
						<< description << ": Samples with swap count " << sampleNdx << " and " << cmpTargetDistribution << " do not seem to have the same distribution:\n"
						<< "\tDifference in standard deviations: " << result.standardDeviations << "\n"
						<< "\tSwap count " << sampleNdx << " median: " << linearSample(sampleObservations[sampleNdx], 0.5f) << "\n"
						<< "\tSwap count " << cmpTargetDistribution << " median: " << linearSample(sampleObservations[cmpTargetDistribution], 0.5f) << "\n"
						<< tcu::TestLog::EndMessage;
					return -1;
				}
				else
				{
					m_testCtx.getLog()
						<< tcu::TestLog::Message
						<< description << ": Samples with swap count " << sampleNdx << " and " << cmpTargetDistribution << " do not seem to have the same distribution:\n"
						<< "\tSamples with swap count " << sampleNdx << " are not part of the tail of stable results.\n"
						<< "\tDifference in standard deviations: " << result.standardDeviations << "\n"
						<< "\tSwap count " << sampleNdx << " median: " << linearSample(sampleObservations[sampleNdx], 0.5f) << "\n"
						<< "\tSwap count " << cmpTargetDistribution << " median: " << linearSample(sampleObservations[cmpTargetDistribution], 0.5f) << "\n"
						<< tcu::TestLog::EndMessage;

					return sampleNdx+1;
				}
			}
		}
	}

	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< description << ": All samples seem to have the same distribution"
		<< tcu::TestLog::EndMessage;

	// all distributions equal
	return 0;
}

bool UploadWaitDrawCase::checkSampleTemporalStability (deUint64 (UploadWaitDrawCase::Result::*target), const char* description)
{
	// Try to find correlation with sample order and sample times

	const int						numDataPoints	= (int)m_iterationOrder.size();
	std::vector<tcu::Vec2>			dataPoints		(m_iterationOrder.size());
	LineParametersWithConfidence	lineFit;

	for (int ndx = 0; ndx < (int)m_iterationOrder.size(); ++ndx)
	{
		dataPoints[m_iterationOrder[ndx]].x() = (float)ndx;
		dataPoints[m_iterationOrder[ndx]].y() = (float)(m_results[m_iterationOrder[ndx]].*target);
	}

	lineFit = theilSenSiegelLinearRegression(dataPoints, 0.6f);

	// Difference of more than 25% of the offset along the whole sample range
	if (de::abs(lineFit.coefficient) * (float)numDataPoints > de::abs(lineFit.offset) * 0.25f)
	{
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< description << ": Correlation with data point observation order and result time. Results are not temporally stable, observations are not independent.\n"
			<< "\tCoefficient: " << lineFit.coefficient << " (us / observation)\n"
			<< tcu::TestLog::EndMessage;

		return false;
	}
	else
		return true;
}

} // anonymous

BufferDataUploadTests::BufferDataUploadTests (Context& context)
	: TestCaseGroup(context, "data_upload", "Buffer data upload performance tests")
{
}

BufferDataUploadTests::~BufferDataUploadTests (void)
{
}

void BufferDataUploadTests::init (void)
{
	static const struct BufferUsage
	{
		const char* name;
		deUint32	usage;
		bool		primaryUsage;
	} bufferUsages[] =
	{
		{ "stream_draw",	GL_STREAM_DRAW,		true	},
		{ "stream_read",	GL_STREAM_READ,		false	},
		{ "stream_copy",	GL_STREAM_COPY,		false	},
		{ "static_draw",	GL_STATIC_DRAW,		true	},
		{ "static_read",	GL_STATIC_READ,		false	},
		{ "static_copy",	GL_STATIC_COPY,		false	},
		{ "dynamic_draw",	GL_DYNAMIC_DRAW,	true	},
		{ "dynamic_read",	GL_DYNAMIC_READ,	false	},
		{ "dynamic_copy",	GL_DYNAMIC_COPY,	false	},
	};

	tcu::TestCaseGroup* const referenceGroup			= new tcu::TestCaseGroup(m_testCtx, "reference",			"Reference functions");
	tcu::TestCaseGroup* const functionCallGroup			= new tcu::TestCaseGroup(m_testCtx, "function_call",		"Function call timing");
	tcu::TestCaseGroup* const modifyAfterUseGroup		= new tcu::TestCaseGroup(m_testCtx, "modify_after_use",		"Function call time after buffer has been used");
	tcu::TestCaseGroup* const renderAfterUploadGroup	= new tcu::TestCaseGroup(m_testCtx, "render_after_upload",	"Function call time of draw commands after buffer has been modified");

	addChild(referenceGroup);
	addChild(functionCallGroup);
	addChild(modifyAfterUseGroup);
	addChild(renderAfterUploadGroup);

	// .reference
	{
		static const struct BufferSizeRange
		{
			const char* name;
			int			minBufferSize;
			int			maxBufferSize;
			int			numSamples;
			bool		largeBuffersCase;
		} sizeRanges[] =
		{
			{ "small_buffers", 0,		1 << 18,	64,		false	}, // !< 0kB - 256kB
			{ "large_buffers", 1 << 18,	1 << 24,	32,		true	}, // !< 256kB - 16MB
		};

		for (int bufferSizeRangeNdx = 0; bufferSizeRangeNdx < DE_LENGTH_OF_ARRAY(sizeRanges); ++bufferSizeRangeNdx)
		{
			referenceGroup->addChild(new ReferenceMemcpyCase(m_context,
															 std::string("memcpy_").append(sizeRanges[bufferSizeRangeNdx].name).c_str(),
															 "Test memcpy performance",
															 sizeRanges[bufferSizeRangeNdx].minBufferSize,
															 sizeRanges[bufferSizeRangeNdx].maxBufferSize,
															 sizeRanges[bufferSizeRangeNdx].numSamples,
															 sizeRanges[bufferSizeRangeNdx].largeBuffersCase));
		}
	}

	// .function_call
	{
		const int minBufferSize		= 0;		// !< 0kiB
		const int maxBufferSize		= 1 << 24;	// !< 16MiB
		const int numDataSamples	= 25;
		const int numMapSamples		= 25;

		tcu::TestCaseGroup* const bufferDataMethodGroup		= new tcu::TestCaseGroup(m_testCtx, "buffer_data", "Use glBufferData");
		tcu::TestCaseGroup* const bufferSubDataMethodGroup	= new tcu::TestCaseGroup(m_testCtx, "buffer_sub_data", "Use glBufferSubData");
		tcu::TestCaseGroup* const mapBufferRangeMethodGroup	= new tcu::TestCaseGroup(m_testCtx, "map_buffer_range", "Use glMapBufferRange");

		functionCallGroup->addChild(bufferDataMethodGroup);
		functionCallGroup->addChild(bufferSubDataMethodGroup);
		functionCallGroup->addChild(mapBufferRangeMethodGroup);

		// .buffer_data
		{
			static const struct TargetCase
			{
				tcu::TestCaseGroup*				group;
				BufferDataUploadCase::CaseType	caseType;
				bool							allUsages;
			} targetCases[] =
			{
				{ new tcu::TestCaseGroup(m_testCtx, "new_buffer",				"Target new buffer"),							BufferDataUploadCase::CASE_NEW_BUFFER,			true	},
				{ new tcu::TestCaseGroup(m_testCtx, "unspecified_buffer",		"Target new unspecified buffer"),				BufferDataUploadCase::CASE_UNSPECIFIED_BUFFER,	true	},
				{ new tcu::TestCaseGroup(m_testCtx, "specified_buffer",			"Target new specified buffer"),					BufferDataUploadCase::CASE_SPECIFIED_BUFFER,	true	},
				{ new tcu::TestCaseGroup(m_testCtx, "used_buffer",				"Target buffer that was used in draw"),			BufferDataUploadCase::CASE_USED_BUFFER,			true	},
				{ new tcu::TestCaseGroup(m_testCtx, "larger_used_buffer",		"Target larger buffer that was used in draw"),	BufferDataUploadCase::CASE_USED_LARGER_BUFFER,	false	},
			};

			for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targetCases); ++targetNdx)
			{
				bufferDataMethodGroup->addChild(targetCases[targetNdx].group);

				for (int usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(bufferUsages); ++usageNdx)
					if (bufferUsages[usageNdx].primaryUsage || targetCases[targetNdx].allUsages)
						targetCases[targetNdx].group->addChild(new BufferDataUploadCase(m_context,
																						std::string("usage_").append(bufferUsages[usageNdx].name).c_str(),
																						std::string("Test with usage = ").append(bufferUsages[usageNdx].name).c_str(),
																						minBufferSize,
																						maxBufferSize,
																						numDataSamples,
																						bufferUsages[usageNdx].usage,
																						targetCases[targetNdx].caseType));
			}
		}

		// .buffer_sub_data
		{
			static const struct FlagCase
			{
				tcu::TestCaseGroup*					group;
				BufferSubDataUploadCase::CaseType	parentCase;
				bool								allUsages;
				int									flags;
			} flagCases[] =
			{
				{ new tcu::TestCaseGroup(m_testCtx, "used_buffer_full_upload",					    ""),															BufferSubDataUploadCase::CASE_USED_BUFFER,	true,	BufferSubDataUploadCase::FLAG_FULL_UPLOAD															},
				{ new tcu::TestCaseGroup(m_testCtx, "used_buffer_invalidate_before_full_upload",    "Clear buffer with bufferData(...,NULL) before sub data call"),	BufferSubDataUploadCase::CASE_USED_BUFFER,	false,	BufferSubDataUploadCase::FLAG_FULL_UPLOAD    | BufferSubDataUploadCase::FLAG_INVALIDATE_BEFORE_USE	},
				{ new tcu::TestCaseGroup(m_testCtx, "used_buffer_partial_upload",                   ""),															BufferSubDataUploadCase::CASE_USED_BUFFER,	true,	BufferSubDataUploadCase::FLAG_PARTIAL_UPLOAD														},
				{ new tcu::TestCaseGroup(m_testCtx, "used_buffer_invalidate_before_partial_upload", "Clear buffer with bufferData(...,NULL) before sub data call"),	BufferSubDataUploadCase::CASE_USED_BUFFER,	false,	BufferSubDataUploadCase::FLAG_PARTIAL_UPLOAD | BufferSubDataUploadCase::FLAG_INVALIDATE_BEFORE_USE	},
			};

			for (int flagNdx = 0; flagNdx < DE_LENGTH_OF_ARRAY(flagCases); ++flagNdx)
			{
				bufferSubDataMethodGroup->addChild(flagCases[flagNdx].group);

				for (int usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(bufferUsages); ++usageNdx)
					if (bufferUsages[usageNdx].primaryUsage || flagCases[flagNdx].allUsages)
							flagCases[flagNdx].group->addChild(new BufferSubDataUploadCase(m_context,
																						   std::string("usage_").append(bufferUsages[usageNdx].name).c_str(),
																						   std::string("Test with usage = ").append(bufferUsages[usageNdx].name).c_str(),
																						   minBufferSize,
																						   maxBufferSize,
																						   numDataSamples,
																						   bufferUsages[usageNdx].usage,
																						   flagCases[flagNdx].parentCase,
																						   flagCases[flagNdx].flags));
			}
		}

		// .map_buffer_range
		{
			static const struct FlagCase
			{
				const char*	name;
				bool		usefulForUnusedBuffers;
				bool		allUsages;
				int			glFlags;
				int			caseFlags;
			} flagCases[] =
			{
				{ "flag_write_full",										true,	true,	GL_MAP_WRITE_BIT,																0																				},
				{ "flag_write_partial",										true,	true,	GL_MAP_WRITE_BIT,																MapBufferRangeCase::FLAG_PARTIAL												},
				{ "flag_read_write_full",									true,	true,	GL_MAP_WRITE_BIT | GL_MAP_READ_BIT,												0																				},
				{ "flag_read_write_partial",								true,	true,	GL_MAP_WRITE_BIT | GL_MAP_READ_BIT,												MapBufferRangeCase::FLAG_PARTIAL												},
				{ "flag_invalidate_range_full",								true,	false,	GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT,									0																				},
				{ "flag_invalidate_range_partial",							true,	false,	GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT,									MapBufferRangeCase::FLAG_PARTIAL												},
				{ "flag_invalidate_buffer_full",							true,	false,	GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT,								0																				},
				{ "flag_invalidate_buffer_partial",							true,	false,	GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT,								MapBufferRangeCase::FLAG_PARTIAL												},
				{ "flag_write_full_manual_invalidate_buffer",				false,	false,	GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT,									MapBufferRangeCase::FLAG_MANUAL_INVALIDATION									},
				{ "flag_write_partial_manual_invalidate_buffer",			false,	false,	GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT,									MapBufferRangeCase::FLAG_PARTIAL | MapBufferRangeCase::FLAG_MANUAL_INVALIDATION	},
				{ "flag_unsynchronized_full",								true,	false,	GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT,									0																				},
				{ "flag_unsynchronized_partial",							true,	false,	GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT,									MapBufferRangeCase::FLAG_PARTIAL												},
				{ "flag_unsynchronized_and_invalidate_buffer_full",			true,	false,	GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT,	0																				},
				{ "flag_unsynchronized_and_invalidate_buffer_partial",		true,	false,	GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT,	MapBufferRangeCase::FLAG_PARTIAL												},
			};
			static const struct FlushCases
			{
				const char*	name;
				int			glFlags;
				int			caseFlags;
			} flushCases[] =
			{
				{ "flag_flush_explicit_map_full",					GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT,	0												},
				{ "flag_flush_explicit_map_partial",				GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT,	MapBufferRangeFlushCase::FLAG_PARTIAL			},
				{ "flag_flush_explicit_map_full_flush_in_parts",	GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT,	MapBufferRangeFlushCase::FLAG_FLUSH_IN_PARTS	},
				{ "flag_flush_explicit_map_full_flush_partial",		GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT,	MapBufferRangeFlushCase::FLAG_FLUSH_PARTIAL		},
			};
			static const struct MapTestGroup
			{
				int					flags;
				bool				unusedBufferCase;
				tcu::TestCaseGroup* group;
			} groups[] =
			{
				{ MapBufferRangeCase::FLAG_USE_UNUSED_UNSPECIFIED_BUFFER,	true,	new tcu::TestCaseGroup(m_testCtx, "new_unspecified_buffer", "Test with unused, unspecified buffers"),				},
				{ MapBufferRangeCase::FLAG_USE_UNUSED_SPECIFIED_BUFFER,		true,	new tcu::TestCaseGroup(m_testCtx, "new_specified_buffer", "Test with unused, specified buffers"),					},
				{ 0,														false,	new tcu::TestCaseGroup(m_testCtx, "used_buffer", "Test with used (data has been sourced from a buffer) buffers")	},
			};

			// we OR same flags to both range and flushRange cases, make sure it is legal
			DE_STATIC_ASSERT((int)MapBufferRangeCase::FLAG_USE_UNUSED_SPECIFIED_BUFFER == (int)MapBufferRangeFlushCase::FLAG_USE_UNUSED_SPECIFIED_BUFFER);
			DE_STATIC_ASSERT((int)MapBufferRangeCase::FLAG_USE_UNUSED_UNSPECIFIED_BUFFER == (int)MapBufferRangeFlushCase::FLAG_USE_UNUSED_UNSPECIFIED_BUFFER);

			for (int groupNdx = 0; groupNdx < DE_LENGTH_OF_ARRAY(groups); ++groupNdx)
			{
				tcu::TestCaseGroup* const bufferTypeGroup = groups[groupNdx].group;

				mapBufferRangeMethodGroup->addChild(bufferTypeGroup);

				for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(flagCases); ++caseNdx)
				{
					if (groups[groupNdx].unusedBufferCase && !flagCases[caseNdx].usefulForUnusedBuffers)
						continue;

					tcu::TestCaseGroup* const bufferUsageGroup = new tcu::TestCaseGroup(m_testCtx, flagCases[caseNdx].name, "");
					bufferTypeGroup->addChild(bufferUsageGroup);

					for (int usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(bufferUsages); ++usageNdx)
						if (bufferUsages[usageNdx].primaryUsage || flagCases[caseNdx].allUsages)
							bufferUsageGroup->addChild(new MapBufferRangeCase(m_context,
																			  bufferUsages[usageNdx].name,
																			  std::string("Test with usage = ").append(bufferUsages[usageNdx].name).c_str(),
																			  minBufferSize,
																			  maxBufferSize,
																			  numMapSamples,
																			  bufferUsages[usageNdx].usage,
																			  flagCases[caseNdx].glFlags,
																			  flagCases[caseNdx].caseFlags | groups[groupNdx].flags));
				}

				for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(flushCases); ++caseNdx)
				{
					tcu::TestCaseGroup* const bufferUsageGroup = new tcu::TestCaseGroup(m_testCtx, flushCases[caseNdx].name, "");
					bufferTypeGroup->addChild(bufferUsageGroup);

					for (int usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(bufferUsages); ++usageNdx)
						if (bufferUsages[usageNdx].primaryUsage)
							bufferUsageGroup->addChild(new MapBufferRangeFlushCase(m_context,
																				   bufferUsages[usageNdx].name,
																				   std::string("Test with usage = ").append(bufferUsages[usageNdx].name).c_str(),
																				   minBufferSize,
																				   maxBufferSize,
																				   numMapSamples,
																				   bufferUsages[usageNdx].usage,
																				   flushCases[caseNdx].glFlags,
																				   flushCases[caseNdx].caseFlags | groups[groupNdx].flags));
				}
			}
		}
	}

	// .modify_after_use
	{
		const int minBufferSize	= 0;		// !< 0kiB
		const int maxBufferSize	= 1 << 24;	// !< 16MiB

		static const struct Usage
		{
			const char* name;
			const char* description;
			deUint32	usage;
		} usages[] =
		{
			{ "static_draw",	"Test with GL_STATIC_DRAW",		GL_STATIC_DRAW	},
			{ "dynamic_draw",	"Test with GL_DYNAMIC_DRAW",	GL_DYNAMIC_DRAW	},
			{ "stream_draw",	"Test with GL_STREAM_DRAW",		GL_STREAM_DRAW },

		};

		for (int usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(usages); ++usageNdx)
		{
			tcu::TestCaseGroup* const usageGroup = new tcu::TestCaseGroup(m_testCtx, usages[usageNdx].name, usages[usageNdx].description);
			modifyAfterUseGroup->addChild(usageGroup);

			usageGroup->addChild(new ModifyAfterWithBufferDataCase		(m_context, "buffer_data",							"Respecify buffer contents after use",					minBufferSize, maxBufferSize, usages[usageNdx].usage, 0));
			usageGroup->addChild(new ModifyAfterWithBufferDataCase		(m_context, "buffer_data_different_size",			"Respecify buffer contents and size after use",			minBufferSize, maxBufferSize, usages[usageNdx].usage, ModifyAfterWithBufferDataCase::FLAG_RESPECIFY_SIZE));
			usageGroup->addChild(new ModifyAfterWithBufferDataCase		(m_context, "buffer_data_repeated",					"Respecify buffer contents after upload and use",		minBufferSize, maxBufferSize, usages[usageNdx].usage, ModifyAfterWithBufferDataCase::FLAG_UPLOAD_REPEATED));

			usageGroup->addChild(new ModifyAfterWithBufferSubDataCase	(m_context, "buffer_sub_data_full",					"Respecify buffer contents after use",					minBufferSize, maxBufferSize, usages[usageNdx].usage, 0));
			usageGroup->addChild(new ModifyAfterWithBufferSubDataCase	(m_context, "buffer_sub_data_partial",				"Respecify buffer contents partially use",				minBufferSize, maxBufferSize, usages[usageNdx].usage, ModifyAfterWithBufferSubDataCase::FLAG_PARTIAL));
			usageGroup->addChild(new ModifyAfterWithBufferSubDataCase	(m_context, "buffer_sub_data_full_repeated",		"Respecify buffer contents after upload and use",		minBufferSize, maxBufferSize, usages[usageNdx].usage, ModifyAfterWithBufferSubDataCase::FLAG_UPLOAD_REPEATED));
			usageGroup->addChild(new ModifyAfterWithBufferSubDataCase	(m_context, "buffer_sub_data_partial_repeated",		"Respecify buffer contents partially upload and use",	minBufferSize, maxBufferSize, usages[usageNdx].usage, ModifyAfterWithBufferSubDataCase::FLAG_UPLOAD_REPEATED | ModifyAfterWithBufferSubDataCase::FLAG_PARTIAL));

			usageGroup->addChild(new ModifyAfterWithMapBufferRangeCase	(m_context, "map_flag_write_full",					"Respecify buffer contents after use",					minBufferSize, maxBufferSize, usages[usageNdx].usage, 0,												GL_MAP_WRITE_BIT));
			usageGroup->addChild(new ModifyAfterWithMapBufferRangeCase	(m_context, "map_flag_write_partial",				"Respecify buffer contents partially after use",		minBufferSize, maxBufferSize, usages[usageNdx].usage, ModifyAfterWithMapBufferRangeCase::FLAG_PARTIAL,	GL_MAP_WRITE_BIT));
			usageGroup->addChild(new ModifyAfterWithMapBufferRangeCase	(m_context, "map_flag_read_write_full",				"Respecify buffer contents after use",					minBufferSize, maxBufferSize, usages[usageNdx].usage, 0,												GL_MAP_READ_BIT | GL_MAP_WRITE_BIT));
			usageGroup->addChild(new ModifyAfterWithMapBufferRangeCase	(m_context, "map_flag_read_write_partial",			"Respecify buffer contents partially after use",		minBufferSize, maxBufferSize, usages[usageNdx].usage, ModifyAfterWithMapBufferRangeCase::FLAG_PARTIAL,	GL_MAP_READ_BIT | GL_MAP_WRITE_BIT));
			usageGroup->addChild(new ModifyAfterWithMapBufferRangeCase	(m_context, "map_flag_invalidate_range_full",		"Respecify buffer contents after use",					minBufferSize, maxBufferSize, usages[usageNdx].usage, 0,												GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT));
			usageGroup->addChild(new ModifyAfterWithMapBufferRangeCase	(m_context, "map_flag_invalidate_range_partial",	"Respecify buffer contents partially after use",		minBufferSize, maxBufferSize, usages[usageNdx].usage, ModifyAfterWithMapBufferRangeCase::FLAG_PARTIAL,	GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT));
			usageGroup->addChild(new ModifyAfterWithMapBufferRangeCase	(m_context, "map_flag_invalidate_buffer_full",		"Respecify buffer contents after use",					minBufferSize, maxBufferSize, usages[usageNdx].usage, 0,												GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT));
			usageGroup->addChild(new ModifyAfterWithMapBufferRangeCase	(m_context, "map_flag_invalidate_buffer_partial",	"Respecify buffer contents partially after use",		minBufferSize, maxBufferSize, usages[usageNdx].usage, ModifyAfterWithMapBufferRangeCase::FLAG_PARTIAL,	GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT));
			usageGroup->addChild(new ModifyAfterWithMapBufferRangeCase	(m_context, "map_flag_unsynchronized_full",			"Respecify buffer contents after use",					minBufferSize, maxBufferSize, usages[usageNdx].usage, 0,												GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT));
			usageGroup->addChild(new ModifyAfterWithMapBufferRangeCase	(m_context, "map_flag_unsynchronized_partial",		"Respecify buffer contents partially after use",		minBufferSize, maxBufferSize, usages[usageNdx].usage, ModifyAfterWithMapBufferRangeCase::FLAG_PARTIAL,	GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT));

			usageGroup->addChild(new ModifyAfterWithMapBufferFlushCase	(m_context, "map_flag_flush_explicit_full",			"Respecify buffer contents after use",					minBufferSize, maxBufferSize, usages[usageNdx].usage, 0,												GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT));
			usageGroup->addChild(new ModifyAfterWithMapBufferFlushCase	(m_context, "map_flag_flush_explicit_partial",		"Respecify buffer contents partially after use",		minBufferSize, maxBufferSize, usages[usageNdx].usage, ModifyAfterWithMapBufferFlushCase::FLAG_PARTIAL,	GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT));
		}
	}

	// .render_after_upload
	{
		// .reference
		{
			tcu::TestCaseGroup* const renderReferenceGroup = new tcu::TestCaseGroup(m_testCtx, "reference", "Baseline results");
			renderAfterUploadGroup->addChild(renderReferenceGroup);

			// .draw
			{
				tcu::TestCaseGroup* const drawGroup = new tcu::TestCaseGroup(m_testCtx, "draw", "Time usage of functions with non-modified buffers");
				renderReferenceGroup->addChild(drawGroup);

				// Time consumed by readPixels
				drawGroup->addChild(new ReferenceReadPixelsTimeCase	(m_context, "read_pixels",		"Measure time consumed by readPixels() function call"));

				// Time consumed by rendering
				drawGroup->addChild(new ReferenceRenderTimeCase		(m_context, "draw_arrays",		"Measure time consumed by drawArrays() function call",		DRAWMETHOD_DRAW_ARRAYS));
				drawGroup->addChild(new ReferenceRenderTimeCase		(m_context, "draw_elements",	"Measure time consumed by drawElements() function call",	DRAWMETHOD_DRAW_ELEMENTS));
			}

			// .draw_upload_draw
			{
				static const struct
				{
					const char*		name;
					const char*		description;
					DrawMethod		drawMethod;
					TargetBuffer	targetBuffer;
					bool			partial;
				} uploadTargets[] =
				{
					{
						"draw_arrays_upload_vertices",
						"Measure time consumed by drawArrays, vertex attribute upload, another drawArrays, and readPixels function calls.",
						DRAWMETHOD_DRAW_ARRAYS,
						TARGETBUFFER_VERTEX,
						false
					},
					{
						"draw_arrays_upload_vertices_partial",
						"Measure time consumed by drawArrays, partial vertex attribute upload, another drawArrays, and readPixels function calls.",
						DRAWMETHOD_DRAW_ARRAYS,
						TARGETBUFFER_VERTEX,
						true
					},
					{
						"draw_elements_upload_vertices",
						"Measure time consumed by drawElements, vertex attribute upload, another drawElements, and readPixels function calls.",
						DRAWMETHOD_DRAW_ELEMENTS,
						TARGETBUFFER_VERTEX,
						false
					},
					{
						"draw_elements_upload_indices",
						"Measure time consumed by drawElements, index upload, another drawElements, and readPixels function calls.",
						DRAWMETHOD_DRAW_ELEMENTS,
						TARGETBUFFER_INDEX,
						false
					},
					{
						"draw_elements_upload_indices_partial",
						"Measure time consumed by drawElements, partial index upload, another drawElements, and readPixels function calls.",
						DRAWMETHOD_DRAW_ELEMENTS,
						TARGETBUFFER_INDEX,
						true
					},
				};
				static const struct
				{
					const char*							name;
					const char*							description;
					UploadMethod						uploadMethod;
					BufferInUseRenderTimeCase::MapFlags	mapFlags;
					bool								supportsPartialUpload;
				} uploadMethods[] =
				{
					{ "buffer_data",						"bufferData",		UPLOADMETHOD_BUFFER_DATA,		BufferInUseRenderTimeCase::MAPFLAG_NONE,				false	},
					{ "buffer_sub_data",					"bufferSubData",	UPLOADMETHOD_BUFFER_SUB_DATA,	BufferInUseRenderTimeCase::MAPFLAG_NONE,				true	},
					{ "map_buffer_range_invalidate_range",	"mapBufferRange",	UPLOADMETHOD_MAP_BUFFER_RANGE,	BufferInUseRenderTimeCase::MAPFLAG_INVALIDATE_RANGE,	true	},
					{ "map_buffer_range_invalidate_buffer",	"mapBufferRange",	UPLOADMETHOD_MAP_BUFFER_RANGE,	BufferInUseRenderTimeCase::MAPFLAG_INVALIDATE_BUFFER,	false	},
				};

				tcu::TestCaseGroup* const drawUploadDrawGroup = new tcu::TestCaseGroup(m_testCtx, "draw_upload_draw", "Time usage of functions draw, upload and another draw");
				renderReferenceGroup->addChild(drawUploadDrawGroup);

				for (int uploadTargetNdx = 0; uploadTargetNdx < DE_LENGTH_OF_ARRAY(uploadTargets); ++uploadTargetNdx)
				for (int uploadMethodNdx = 0; uploadMethodNdx < DE_LENGTH_OF_ARRAY(uploadMethods); ++uploadMethodNdx)
				{
					const std::string name = std::string() + uploadTargets[uploadTargetNdx].name + "_with_" + uploadMethods[uploadMethodNdx].name;

					if (uploadTargets[uploadTargetNdx].partial && !uploadMethods[uploadMethodNdx].supportsPartialUpload)
						continue;

					drawUploadDrawGroup->addChild(new BufferInUseRenderTimeCase(m_context,
																				name.c_str(),
																				uploadTargets[uploadTargetNdx].description,
																				uploadTargets[uploadTargetNdx].drawMethod,
																				uploadMethods[uploadMethodNdx].mapFlags,
																				uploadTargets[uploadTargetNdx].targetBuffer,
																				uploadMethods[uploadMethodNdx].uploadMethod,
																				(uploadTargets[uploadTargetNdx].partial) ? (UPLOADRANGE_PARTIAL) : (UPLOADRANGE_FULL),
																				BufferInUseRenderTimeCase::UPLOADBUFFERTARGET_DIFFERENT_BUFFER));
				}
			}
		}

		// .upload_unrelated_and_draw
		{
			static const struct
			{
				const char*		name;
				const char*		description;
				DrawMethod		drawMethod;
			} drawMethods[] =
			{
				{ "draw_arrays",	"drawArrays",	DRAWMETHOD_DRAW_ARRAYS		},
				{ "draw_elements",	"drawElements",	DRAWMETHOD_DRAW_ELEMENTS	},
			};

			static const struct
			{
				const char*		name;
				UploadMethod	uploadMethod;
			} uploadMethods[] =
			{
				{ "buffer_data",		UPLOADMETHOD_BUFFER_DATA		},
				{ "buffer_sub_data",	UPLOADMETHOD_BUFFER_SUB_DATA	},
				{ "map_buffer_range",	UPLOADMETHOD_MAP_BUFFER_RANGE	},
			};

			tcu::TestCaseGroup* const uploadUnrelatedGroup = new tcu::TestCaseGroup(m_testCtx, "upload_unrelated_and_draw", "Time usage of functions after an unrelated upload");
			renderAfterUploadGroup->addChild(uploadUnrelatedGroup);

			for (int drawMethodNdx = 0; drawMethodNdx < DE_LENGTH_OF_ARRAY(drawMethods); ++drawMethodNdx)
			for (int uploadMethodNdx = 0; uploadMethodNdx < DE_LENGTH_OF_ARRAY(uploadMethods); ++uploadMethodNdx)
			{
				const std::string name = std::string() + drawMethods[drawMethodNdx].name + "_upload_unrelated_with_" + uploadMethods[uploadMethodNdx].name;
				const std::string desc = std::string() + "Measure time consumed by " + drawMethods[drawMethodNdx].description + " function call after an unrelated upload";

				// Time consumed by rendering command after an unrelated upload

				uploadUnrelatedGroup->addChild(new UnrelatedUploadRenderTimeCase(m_context, name.c_str(), desc.c_str(), drawMethods[drawMethodNdx].drawMethod, uploadMethods[uploadMethodNdx].uploadMethod));
			}
		}

		// .upload_and_draw
		{
			static const struct
			{
				const char*			name;
				const char*			description;
				BufferState			bufferState;
				UnrelatedBufferType	unrelatedBuffer;
				bool				supportsPartialUpload;
			} bufferConfigs[] =
			{
				{ "used_buffer",						"Upload to an used buffer",											BUFFERSTATE_EXISTING,	UNRELATEDBUFFERTYPE_NONE,	true	},
				{ "new_buffer",							"Upload to a new buffer",											BUFFERSTATE_NEW,		UNRELATEDBUFFERTYPE_NONE,	false	},
				{ "used_buffer_and_unrelated_upload",	"Upload to an used buffer and an unrelated buffer and then draw",	BUFFERSTATE_EXISTING,	UNRELATEDBUFFERTYPE_VERTEX,	true	},
				{ "new_buffer_and_unrelated_upload",	"Upload to a new buffer and an unrelated buffer and then draw",		BUFFERSTATE_NEW,		UNRELATEDBUFFERTYPE_VERTEX,	false	},
			};

			tcu::TestCaseGroup* const uploadAndDrawGroup = new tcu::TestCaseGroup(m_testCtx, "upload_and_draw", "Time usage of rendering functions with modified buffers");
			renderAfterUploadGroup->addChild(uploadAndDrawGroup);

			// .used_buffer
			// .new_buffer
			// .used_buffer_and_unrelated_upload
			// .new_buffer_and_unrelated_upload
			for (int stateNdx = 0; stateNdx < DE_LENGTH_OF_ARRAY(bufferConfigs); ++stateNdx)
			{
				static const struct
				{
					const char*		name;
					const char*		description;
					DrawMethod		drawMethod;
					TargetBuffer	targetBuffer;
					bool			partial;
				} uploadTargets[] =
				{
					{
						"draw_arrays_upload_vertices",
						"Measure time consumed by vertex attribute upload, drawArrays, and readPixels function calls",
						DRAWMETHOD_DRAW_ARRAYS,
						TARGETBUFFER_VERTEX,
						false
					},
					{
						"draw_arrays_upload_vertices_partial",
						"Measure time consumed by partial vertex attribute upload, drawArrays, and readPixels function calls",
						DRAWMETHOD_DRAW_ARRAYS,
						TARGETBUFFER_VERTEX,
						true
					},
					{
						"draw_elements_upload_vertices",
						"Measure time consumed by vertex attribute upload, drawElements, and readPixels function calls",
						DRAWMETHOD_DRAW_ELEMENTS,
						TARGETBUFFER_VERTEX,
						false
					},
					{
						"draw_elements_upload_indices",
						"Measure time consumed by index upload, drawElements, and readPixels function calls",
						DRAWMETHOD_DRAW_ELEMENTS,
						TARGETBUFFER_INDEX,
						false
					},
					{
						"draw_elements_upload_indices_partial",
						"Measure time consumed by partial index upload, drawElements, and readPixels function calls",
						DRAWMETHOD_DRAW_ELEMENTS,
						TARGETBUFFER_INDEX,
						true
					},
				};
				static const struct
				{
					const char*		name;
					const char*		description;
					UploadMethod	uploadMethod;
					bool			supportsPartialUpload;
				} uploadMethods[] =
				{
					{ "buffer_data",		"bufferData",		UPLOADMETHOD_BUFFER_DATA,		false	},
					{ "buffer_sub_data",	"bufferSubData",	UPLOADMETHOD_BUFFER_SUB_DATA,	true	},
					{ "map_buffer_range",	"mapBufferRange",	UPLOADMETHOD_MAP_BUFFER_RANGE,	true	},
				};

				tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, bufferConfigs[stateNdx].name, bufferConfigs[stateNdx].description);
				uploadAndDrawGroup->addChild(group);

				for (int uploadTargetNdx = 0; uploadTargetNdx < DE_LENGTH_OF_ARRAY(uploadTargets); ++uploadTargetNdx)
				for (int uploadMethodNdx = 0; uploadMethodNdx < DE_LENGTH_OF_ARRAY(uploadMethods); ++uploadMethodNdx)
				{
					const std::string name = std::string() + uploadTargets[uploadTargetNdx].name + "_with_" + uploadMethods[uploadMethodNdx].name;

					if (uploadTargets[uploadTargetNdx].partial && !uploadMethods[uploadMethodNdx].supportsPartialUpload)
						continue;
					if (uploadTargets[uploadTargetNdx].partial && !bufferConfigs[stateNdx].supportsPartialUpload)
						continue;

					// Don't log unrelated buffer information to samples if there is no such buffer

					if (bufferConfigs[stateNdx].unrelatedBuffer == UNRELATEDBUFFERTYPE_NONE)
					{
						typedef UploadRenderReadDuration				SampleType;
						typedef GenericUploadRenderTimeCase<SampleType>	TestType;

						group->addChild(new TestType(m_context,
													 name.c_str(),
													 uploadTargets[uploadTargetNdx].description,
													 uploadTargets[uploadTargetNdx].drawMethod,
													 uploadTargets[uploadTargetNdx].targetBuffer,
													 uploadMethods[uploadMethodNdx].uploadMethod,
													 bufferConfigs[stateNdx].bufferState,
													 (uploadTargets[uploadTargetNdx].partial) ? (UPLOADRANGE_PARTIAL) : (UPLOADRANGE_FULL),
													 bufferConfigs[stateNdx].unrelatedBuffer));
					}
					else
					{
						typedef UploadRenderReadDurationWithUnrelatedUploadSize	SampleType;
						typedef GenericUploadRenderTimeCase<SampleType>			TestType;

						group->addChild(new TestType(m_context,
													 name.c_str(),
													 uploadTargets[uploadTargetNdx].description,
													 uploadTargets[uploadTargetNdx].drawMethod,
													 uploadTargets[uploadTargetNdx].targetBuffer,
													 uploadMethods[uploadMethodNdx].uploadMethod,
													 bufferConfigs[stateNdx].bufferState,
													 (uploadTargets[uploadTargetNdx].partial) ? (UPLOADRANGE_PARTIAL) : (UPLOADRANGE_FULL),
													 bufferConfigs[stateNdx].unrelatedBuffer));
					}
				}
			}
		}

		// .draw_modify_draw
		{
			static const struct
			{
				const char*		name;
				const char*		description;
				DrawMethod		drawMethod;
				TargetBuffer	targetBuffer;
				bool			partial;
			} uploadTargets[] =
			{
				{
					"draw_arrays_upload_vertices",
					"Measure time consumed by drawArrays, vertex attribute upload, another drawArrays, and readPixels function calls.",
					DRAWMETHOD_DRAW_ARRAYS,
					TARGETBUFFER_VERTEX,
					false
				},
				{
					"draw_arrays_upload_vertices_partial",
					"Measure time consumed by drawArrays, partial vertex attribute upload, another drawArrays, and readPixels function calls.",
					DRAWMETHOD_DRAW_ARRAYS,
					TARGETBUFFER_VERTEX,
					true
				},
				{
					"draw_elements_upload_vertices",
					"Measure time consumed by drawElements, vertex attribute upload, another drawElements, and readPixels function calls.",
					DRAWMETHOD_DRAW_ELEMENTS,
					TARGETBUFFER_VERTEX,
					false
				},
				{
					"draw_elements_upload_indices",
					"Measure time consumed by drawElements, index upload, another drawElements, and readPixels function calls.",
					DRAWMETHOD_DRAW_ELEMENTS,
					TARGETBUFFER_INDEX,
					false
				},
				{
					"draw_elements_upload_indices_partial",
					"Measure time consumed by drawElements, partial index upload, another drawElements, and readPixels function calls.",
					DRAWMETHOD_DRAW_ELEMENTS,
					TARGETBUFFER_INDEX,
					true
				},
			};
			static const struct
			{
				const char*							name;
				const char*							description;
				UploadMethod						uploadMethod;
				BufferInUseRenderTimeCase::MapFlags	mapFlags;
				bool								supportsPartialUpload;
			} uploadMethods[] =
			{
				{ "buffer_data",						"bufferData",		UPLOADMETHOD_BUFFER_DATA,		BufferInUseRenderTimeCase::MAPFLAG_NONE,				false	},
				{ "buffer_sub_data",					"bufferSubData",	UPLOADMETHOD_BUFFER_SUB_DATA,	BufferInUseRenderTimeCase::MAPFLAG_NONE,				true	},
				{ "map_buffer_range_invalidate_range",	"mapBufferRange",	UPLOADMETHOD_MAP_BUFFER_RANGE,	BufferInUseRenderTimeCase::MAPFLAG_INVALIDATE_RANGE,	true	},
				{ "map_buffer_range_invalidate_buffer",	"mapBufferRange",	UPLOADMETHOD_MAP_BUFFER_RANGE,	BufferInUseRenderTimeCase::MAPFLAG_INVALIDATE_BUFFER,	false	},
			};

			tcu::TestCaseGroup* const drawModifyDrawGroup = new tcu::TestCaseGroup(m_testCtx, "draw_modify_draw", "Time used in rendering functions with modified buffers while original buffer is still in use");
			renderAfterUploadGroup->addChild(drawModifyDrawGroup);

			for (int uploadTargetNdx = 0; uploadTargetNdx < DE_LENGTH_OF_ARRAY(uploadTargets); ++uploadTargetNdx)
			for (int uploadMethodNdx = 0; uploadMethodNdx < DE_LENGTH_OF_ARRAY(uploadMethods); ++uploadMethodNdx)
			{
				const std::string name = std::string() + uploadTargets[uploadTargetNdx].name + "_with_" + uploadMethods[uploadMethodNdx].name;

				if (uploadTargets[uploadTargetNdx].partial && !uploadMethods[uploadMethodNdx].supportsPartialUpload)
					continue;

				drawModifyDrawGroup->addChild(new BufferInUseRenderTimeCase(m_context,
																			name.c_str(),
																			uploadTargets[uploadTargetNdx].description,
																			uploadTargets[uploadTargetNdx].drawMethod,
																			uploadMethods[uploadMethodNdx].mapFlags,
																			uploadTargets[uploadTargetNdx].targetBuffer,
																			uploadMethods[uploadMethodNdx].uploadMethod,
																			(uploadTargets[uploadTargetNdx].partial) ? (UPLOADRANGE_PARTIAL) : (UPLOADRANGE_FULL),
																			BufferInUseRenderTimeCase::UPLOADBUFFERTARGET_SAME_BUFFER));
			}
		}

		// .upload_wait_draw
		{
			static const struct
			{
				const char*	name;
				const char*	description;
				BufferState	bufferState;
			} bufferStates[] =
			{
				{ "new_buffer",		"Uploading to just generated name",	BUFFERSTATE_NEW			},
				{ "used_buffer",	"Uploading to a used buffer",		BUFFERSTATE_EXISTING	},
			};
			static const struct
			{
				const char*		name;
				const char*		description;
				DrawMethod		drawMethod;
				TargetBuffer	targetBuffer;
			} uploadTargets[] =
			{
				{ "draw_arrays_vertices",	"Upload vertex data, draw with drawArrays",		DRAWMETHOD_DRAW_ARRAYS,		TARGETBUFFER_VERTEX	},
				{ "draw_elements_vertices",	"Upload vertex data, draw with drawElements",	DRAWMETHOD_DRAW_ELEMENTS,	TARGETBUFFER_VERTEX	},
				{ "draw_elements_indices",	"Upload index data, draw with drawElements",	DRAWMETHOD_DRAW_ELEMENTS,	TARGETBUFFER_INDEX	},
			};
			static const struct
			{
				const char*		name;
				const char*		description;
				UploadMethod	uploadMethod;
			} uploadMethods[] =
			{
				{ "buffer_data",		"bufferData",		UPLOADMETHOD_BUFFER_DATA		},
				{ "buffer_sub_data",	"bufferSubData",	UPLOADMETHOD_BUFFER_SUB_DATA	},
				{ "map_buffer_range",	"mapBufferRange",	UPLOADMETHOD_MAP_BUFFER_RANGE	},
			};

			tcu::TestCaseGroup* const uploadSwapDrawGroup = new tcu::TestCaseGroup(m_testCtx, "upload_wait_draw", "Time used in rendering functions after a buffer upload N frames ago");
			renderAfterUploadGroup->addChild(uploadSwapDrawGroup);

			for (int bufferStateNdx = 0; bufferStateNdx < DE_LENGTH_OF_ARRAY(bufferStates); ++bufferStateNdx)
			{
				tcu::TestCaseGroup* const bufferGroup = new tcu::TestCaseGroup(m_testCtx, bufferStates[bufferStateNdx].name, bufferStates[bufferStateNdx].description);
				uploadSwapDrawGroup->addChild(bufferGroup);

				for (int uploadTargetNdx = 0; uploadTargetNdx < DE_LENGTH_OF_ARRAY(uploadTargets); ++uploadTargetNdx)
				for (int uploadMethodNdx = 0; uploadMethodNdx < DE_LENGTH_OF_ARRAY(uploadMethods); ++uploadMethodNdx)
				{
					const std::string name = std::string() + uploadTargets[uploadTargetNdx].name + "_with_" + uploadMethods[uploadMethodNdx].name;

					bufferGroup->addChild(new UploadWaitDrawCase(m_context,
																 name.c_str(),
																 uploadTargets[uploadTargetNdx].description,
																 uploadTargets[uploadTargetNdx].drawMethod,
																 uploadTargets[uploadTargetNdx].targetBuffer,
																 uploadMethods[uploadMethodNdx].uploadMethod,
																 bufferStates[bufferStateNdx].bufferState));
				}
			}
		}
	}
}

} // Performance
} // gles3
} // deqp
