/*-------------------------------------------------------------------------
 * 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_dummyVertexShader =		"#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_dummyFragnentShader =	"#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 dummyCalculation (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			dummy				= *tcu::warmupCPUInternal::g_dummy.m_v;
	int				workSize			= 500;

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

		dummy = dummyCalculation(dummy, workSize);

		totalTime = deGetMicroseconds() - startTime;

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

	// "wait"
	while (deGetMicroseconds() < endTime)
		dummy = dummyCalculation(dummy, workSize);

	*tcu::warmupCPUInternal::g_dummy.m_v = dummy;
}

// 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
	{
		DUMMY_RENDER_AREA_SIZE = 32
	};

	glu::ShaderProgram*		m_dummyProgram;
	deInt32					m_dummyProgramPosLoc;
	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_dummyProgram			(DE_NULL)
	, m_dummyProgramPosLoc		(-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 hhan DUMMY_RENDER_AREA_SIZE

	// dummy shader

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

	m_dummyProgramPosLoc = gl.getAttribLocation(m_dummyProgram->getProgram(), "a_position");
	if (m_dummyProgramPosLoc == -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_dummyProgram;
	m_dummyProgram = 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_dummyProgram->getProgram());
		gl.viewport(0, 0, DUMMY_RENDER_AREA_SIZE, DUMMY_RENDER_AREA_SIZE);
		gl.enableVertexAttribArray(m_dummyProgramPosLoc);

		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_dummyProgramPosLoc, 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_dummyProgramPosLoc, 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 dummySurface(DUMMY_RENDER_AREA_SIZE, DUMMY_RENDER_AREA_SIZE);
	glu::readPixels(m_context.getRenderContext(), 0, 0, dummySurface.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_dummyBufferID;

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>::DUMMY_RENDER_AREA_SIZE;
	using BasicBufferCase<SampleType>::m_dummyProgram;
	using BasicBufferCase<SampleType>::m_dummyProgramPosLoc;
	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_dummyBufferID				(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);

	// dummy buffer

	gl.genBuffers(1, &m_dummyBufferID);
	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_dummyBufferID)
	{
		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_dummyBufferID);
		m_dummyBufferID = 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					dummyUploadSize = deAlign32(1048576 + sizeDelta, 4*4); // Vary buffer size to make sure it is always reallocated
		const std::vector<deUint8>	dummyData		(dummyUploadSize, 0x20);

		gl.bindBuffer(GL_ARRAY_BUFFER, m_dummyBufferID);
		gl.bufferData(GL_ARRAY_BUFFER, dummyUploadSize, &dummyData[0], m_bufferUsage);

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

		// 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> dummyData(bufferSize, 0x20);
		gl.bufferData(GL_ARRAY_BUFFER, bufferSize, &dummyData[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> dummyData(bufferSize, 0x20);
		gl.bufferData(GL_ARRAY_BUFFER, bufferSize, &dummyData[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_dummyProgram->getProgram());

	gl.viewport(0, 0, DUMMY_RENDER_AREA_SIZE, DUMMY_RENDER_AREA_SIZE);
	gl.vertexAttribPointer(m_dummyProgramPosLoc, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
	gl.enableVertexAttribArray(m_dummyProgramPosLoc);

	// 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>::DUMMY_RENDER_AREA_SIZE;
	using BasicBufferCase<SampleType>::m_dummyProgram;
	using BasicBufferCase<SampleType>::m_dummyProgramPosLoc;
	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_dummyProgram->getProgram());
		gl.viewport(0, 0, DUMMY_RENDER_AREA_SIZE, DUMMY_RENDER_AREA_SIZE);
		gl.enableVertexAttribArray(m_dummyProgramPosLoc);
	}
}

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_dummyProgramPosLoc, 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 dummySurface(RENDER_AREA_SIZE, RENDER_AREA_SIZE);
	glu::readPixels(m_context.getRenderContext(), 0, 0, dummySurface.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 dummy 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				betweenIterationDummyFrameCount = 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);

	// Dummy rendering during dummy 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 + betweenIterationDummyFrameCount)
	{
		// 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
