Merge "Allow allocation of non-coherent memory if coherency is not required." into vulkan
diff --git a/external/vulkancts/framework/vulkan/CMakeLists.txt b/external/vulkancts/framework/vulkan/CMakeLists.txt
index 048c5f6..c39a07f 100644
--- a/external/vulkancts/framework/vulkan/CMakeLists.txt
+++ b/external/vulkancts/framework/vulkan/CMakeLists.txt
@@ -3,6 +3,8 @@
 set(VKUTIL_SRCS
 	vkApiVersion.cpp
 	vkApiVersion.hpp
+	vkBuilderUtil.cpp
+	vkBuilderUtil.hpp
 	vkDefs.cpp
 	vkDefs.hpp
 	vkRef.cpp
diff --git a/external/vulkancts/framework/vulkan/vkBasicTypes.inl b/external/vulkancts/framework/vulkan/vkBasicTypes.inl
index 9d392fe..f63715f 100644
--- a/external/vulkancts/framework/vulkan/vkBasicTypes.inl
+++ b/external/vulkancts/framework/vulkan/vkBasicTypes.inl
@@ -1,13 +1,17 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  */
-#define VK_API_VERSION				VK_MAKE_VERSION(0, 138, 1)
-#define VK_MAX_PHYSICAL_DEVICE_NAME	256
-#define VK_MAX_EXTENSION_NAME		256
-#define VK_UUID_LENGTH				16
-#define VK_MAX_MEMORY_TYPES			32
-#define VK_MAX_MEMORY_HEAPS			16
-#define VK_MAX_DESCRIPTION			256
+enum { VK_API_VERSION				= VK_MAKE_VERSION(0, 138, 1)	};
+enum { VK_MAX_PHYSICAL_DEVICE_NAME	= 256							};
+enum { VK_MAX_EXTENSION_NAME		= 256							};
+enum { VK_UUID_LENGTH				= 16							};
+enum { VK_MAX_MEMORY_TYPES			= 32							};
+enum { VK_MAX_MEMORY_HEAPS			= 16							};
+enum { VK_MAX_DESCRIPTION			= 256							};
+enum { VK_QUEUE_FAMILY_IGNORED		= UINT32_MAX					};
+enum { VK_NO_ATTACHMENT				= UINT32_MAX					};
+enum { VK_FALSE						= 0								};
+enum { VK_TRUE						= 1								};
 
 VK_DEFINE_HANDLE			(VkInstance,					HANDLE_TYPE_INSTANCE);
 VK_DEFINE_HANDLE			(VkPhysicalDevice,				HANDLE_TYPE_PHYSICAL_DEVICE);
diff --git a/external/vulkancts/framework/vulkan/vkBuilderUtil.cpp b/external/vulkancts/framework/vulkan/vkBuilderUtil.cpp
new file mode 100644
index 0000000..13aec2d
--- /dev/null
+++ b/external/vulkancts/framework/vulkan/vkBuilderUtil.cpp
@@ -0,0 +1,191 @@
+/*-------------------------------------------------------------------------
+ * Vulkan CTS Framework
+ * --------------------
+ *
+ * Copyright (c) 2015 Google Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be
+ * included in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by
+ * Khronos, at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief Vulkan object builder utilities.
+ *//*--------------------------------------------------------------------*/
+
+#include "vkBuilderUtil.hpp"
+
+#include "vkRefUtil.hpp"
+
+namespace vk
+{
+
+// DescriptorSetLayoutBuilder
+
+DescriptorSetLayoutBuilder::DescriptorSetLayoutBuilder (void)
+{
+}
+
+DescriptorSetLayoutBuilder& DescriptorSetLayoutBuilder::addBinding (VkDescriptorType	descriptorType,
+																	deUint32			arraySize,
+																	VkShaderStageFlags	stageFlags,
+																	const VkSampler*	pImmutableSamplers)
+{
+	const VkDescriptorSetLayoutBinding binding =
+	{
+		descriptorType,			//!< descriptorType
+		arraySize,				//!< arraySize
+		stageFlags,				//!< stageFlags
+		pImmutableSamplers,		//!< pImmutableSamplers
+	};
+	m_bindings.push_back(binding);
+	return *this;
+}
+
+Move<VkDescriptorSetLayout> DescriptorSetLayoutBuilder::build (const DeviceInterface& vk, VkDevice device) const
+{
+	const VkDescriptorSetLayoutBinding* const	bindingPtr	= (m_bindings.empty()) ? (DE_NULL) : (&m_bindings[0]);
+	const VkDescriptorSetLayoutCreateInfo		createInfo	=
+	{
+		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
+		DE_NULL,
+		(deUint32)m_bindings.size(),		//!< count
+		bindingPtr,							//!< pBinding
+	};
+
+	return createDescriptorSetLayout(vk, device, &createInfo);
+}
+
+// DescriptorPoolBuilder
+
+DescriptorPoolBuilder::DescriptorPoolBuilder (void)
+{
+}
+
+DescriptorPoolBuilder& DescriptorPoolBuilder::addType (VkDescriptorType type, deUint32 numDescriptors)
+{
+	if (numDescriptors == 0u)
+	{
+		// nothing to do
+		return *this;
+	}
+	else
+	{
+		for (size_t ndx = 0; ndx < m_counts.size(); ++ndx)
+		{
+			if (m_counts[ndx].type == type)
+			{
+				// augment existing requirement
+				m_counts[ndx].count += numDescriptors;
+				return *this;
+			}
+		}
+
+		{
+			// new requirement
+			const VkDescriptorTypeCount typeCount =
+			{
+				type,			//!< type
+				numDescriptors,	//!< count
+			};
+
+			m_counts.push_back(typeCount);
+			return *this;
+		}
+	}
+}
+
+Move<VkDescriptorPool> DescriptorPoolBuilder::build (const DeviceInterface& vk, VkDevice device, VkDescriptorPoolUsage poolUsage, deUint32 maxSets) const
+{
+	const VkDescriptorTypeCount* const	typeCountPtr	= (m_counts.empty()) ? (DE_NULL) : (&m_counts[0]);
+	const VkDescriptorPoolCreateInfo	createInfo		=
+	{
+		VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
+		DE_NULL,
+		(deUint32)m_counts.size(),		//!< count
+		typeCountPtr,					//!< pTypeCount
+	};
+
+	return createDescriptorPool(vk, device, poolUsage, maxSets, &createInfo);
+}
+
+// DescriptorSetUpdateBuilder
+
+DescriptorSetUpdateBuilder::DescriptorSetUpdateBuilder (void)
+{
+}
+
+DescriptorSetUpdateBuilder& DescriptorSetUpdateBuilder::write (VkDescriptorSet			destSet,
+															   deUint32					destBinding,
+															   deUint32					destArrayElement,
+															   deUint32					count,
+															   VkDescriptorType			descriptorType,
+															   const VkDescriptorInfo*	pDescriptors)
+{
+	const VkWriteDescriptorSet write =
+	{
+		VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
+		DE_NULL,
+		destSet,			//!< destSet
+		destBinding,		//!< destBinding
+		destArrayElement,	//!< destArrayElement
+		count,				//!< count
+		descriptorType,		//!< descriptorType
+		pDescriptors,		//!< pDescriptors
+	};
+	m_writes.push_back(write);
+	return *this;
+}
+
+DescriptorSetUpdateBuilder& DescriptorSetUpdateBuilder::copy (VkDescriptorSet	srcSet,
+															  deUint32			srcBinding,
+															  deUint32			srcArrayElement,
+															  VkDescriptorSet	destSet,
+															  deUint32			destBinding,
+															  deUint32			destArrayElement,
+															  deUint32			count)
+{
+	const VkCopyDescriptorSet copy =
+	{
+		VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET,
+		DE_NULL,
+		srcSet,				//!< srcSet
+		srcBinding,			//!< srcBinding
+		srcArrayElement,	//!< srcArrayElement
+		destSet,			//!< destSet
+		destBinding,		//!< destBinding
+		destArrayElement,	//!< destArrayElement
+		count,				//!< count
+	};
+	m_copies.push_back(copy);
+	return *this;
+}
+
+void DescriptorSetUpdateBuilder::update (const DeviceInterface& vk, VkDevice device) const
+{
+	const VkWriteDescriptorSet* const	writePtr	= (m_writes.empty()) ? (DE_NULL) : (&m_writes[0]);
+	const VkCopyDescriptorSet* const	copyPtr		= (m_copies.empty()) ? (DE_NULL) : (&m_copies[0]);
+
+	VK_CHECK(vk.updateDescriptorSets(device, (deUint32)m_writes.size(), writePtr, (deUint32)m_copies.size(), copyPtr));
+}
+
+} // vk
diff --git a/external/vulkancts/framework/vulkan/vkBuilderUtil.hpp b/external/vulkancts/framework/vulkan/vkBuilderUtil.hpp
new file mode 100644
index 0000000..be1bcd5
--- /dev/null
+++ b/external/vulkancts/framework/vulkan/vkBuilderUtil.hpp
@@ -0,0 +1,202 @@
+#ifndef _VKBUILDERUTIL_HPP
+#define _VKBUILDERUTIL_HPP
+/*-------------------------------------------------------------------------
+ * Vulkan CTS Framework
+ * --------------------
+ *
+ * Copyright (c) 2015 Google Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be
+ * included in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by
+ * Khronos, at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief Vulkan object builder utilities.
+ *//*--------------------------------------------------------------------*/
+
+#include "vkDefs.hpp"
+#include "vkRef.hpp"
+
+#include <vector>
+
+namespace vk
+{
+
+class DescriptorSetLayoutBuilder
+{
+public:
+												DescriptorSetLayoutBuilder	(void);
+
+	DescriptorSetLayoutBuilder&					addBinding					(VkDescriptorType	descriptorType,
+																			 deUint32			arraySize,
+																			 VkShaderStageFlags	stageFlags,
+																			 const VkSampler*	pImmutableSamplers);
+
+	Move<VkDescriptorSetLayout>					build						(const DeviceInterface& vk, VkDevice device) const;
+
+	// helpers
+
+	inline DescriptorSetLayoutBuilder&			addSingleBinding			(VkDescriptorType	descriptorType,
+																			 VkShaderStageFlags	stageFlags)
+	{
+		return addBinding(descriptorType, 1u, stageFlags, (VkSampler*)DE_NULL);
+	}
+	inline DescriptorSetLayoutBuilder&			addArrayBinding				(VkDescriptorType	descriptorType,
+																			 deUint32			arraySize,
+																			 VkShaderStageFlags	stageFlags)
+	{
+		return addBinding(descriptorType, arraySize, stageFlags, (VkSampler*)DE_NULL);
+	}
+	inline DescriptorSetLayoutBuilder&			addSingleSamplerBinding		(VkDescriptorType	descriptorType,
+																			 VkShaderStageFlags	stageFlags,
+																			 const VkSampler*	immutableSampler)	//!< \note: Using pointer to sampler to clarify that handle is not
+																													//!<        copied and argument lifetime is expected to cover build()
+																													//!<        call.
+	{
+		return addBinding(descriptorType, 1u, stageFlags, immutableSampler);
+	}
+	inline DescriptorSetLayoutBuilder&			addArraySamplerBinding		(VkDescriptorType	descriptorType,
+																			 deUint32			arraySize,
+																			 VkShaderStageFlags	stageFlags,
+																			 const VkSampler*	pImmutableSamplers)
+	{
+		return addBinding(descriptorType, arraySize, stageFlags, pImmutableSamplers);
+	}
+
+private:
+												DescriptorSetLayoutBuilder	(const DescriptorSetLayoutBuilder&); // delete
+	DescriptorSetLayoutBuilder&					operator=					(const DescriptorSetLayoutBuilder&); // delete
+
+	std::vector<VkDescriptorSetLayoutBinding>	m_bindings;
+};
+
+class DescriptorPoolBuilder
+{
+public:
+										DescriptorPoolBuilder	(void);
+
+	DescriptorPoolBuilder&				addType					(VkDescriptorType type, deUint32 numDescriptors = 1u);
+	Move<VkDescriptorPool>				build					(const DeviceInterface& vk, VkDevice device, VkDescriptorPoolUsage poolUsage, deUint32 maxSets) const;
+
+private:
+										DescriptorPoolBuilder	(const DescriptorPoolBuilder&); // delete
+	DescriptorPoolBuilder&				operator=				(const DescriptorPoolBuilder&); // delete
+
+	std::vector<VkDescriptorTypeCount>	m_counts;
+};
+
+class DescriptorSetUpdateBuilder
+{
+public:
+	class Location
+	{
+	public:
+		static inline Location	binding				(deUint32 binding)
+		{
+			return Location(binding, 0u);
+		}
+		static inline Location	bindingArrayElement	(deUint32 binding, deUint32 arrayElement)
+		{
+			return Location(binding, arrayElement);
+		}
+
+	private:
+		// \note private to force use of factory methods that have more descriptive names
+		inline					Location			(deUint32 binding, deUint32 arrayElement)
+			: m_binding			(binding)
+			, m_arrayElement	(arrayElement)
+		{
+		}
+
+		friend class DescriptorSetUpdateBuilder;
+
+		const deUint32			m_binding;
+		const deUint32			m_arrayElement;
+	};
+
+										DescriptorSetUpdateBuilder	(void);
+
+	DescriptorSetUpdateBuilder&			write						(VkDescriptorSet			destSet,
+																	 deUint32					destBinding,
+																	 deUint32					destArrayElement,
+																	 deUint32					count,
+																	 VkDescriptorType			descriptorType,
+																	 const VkDescriptorInfo*	pDescriptors);
+
+	DescriptorSetUpdateBuilder&			copy						(VkDescriptorSet	srcSet,
+																	 deUint32			srcBinding,
+																	 deUint32			srcArrayElement,
+																	 VkDescriptorSet	destSet,
+																	 deUint32			destBinding,
+																	 deUint32			destArrayElement,
+																	 deUint32			count);
+
+	void								update						(const DeviceInterface& vk, VkDevice device) const;
+
+	// helpers
+
+	inline DescriptorSetUpdateBuilder&	writeSingle					(VkDescriptorSet			destSet,
+																	 const Location& 			destLocation,
+																	 VkDescriptorType			descriptorType,
+																	 const VkDescriptorInfo*	descriptor)
+	{
+		return write(destSet, destLocation.m_binding, destLocation.m_arrayElement, 1u, descriptorType, descriptor);
+	}
+
+	inline DescriptorSetUpdateBuilder&	writeArray					(VkDescriptorSet			destSet,
+																	 const Location& 			destLocation,
+																	 VkDescriptorType			descriptorType,
+																	 deUint32					numDescriptors,
+																	 const VkDescriptorInfo*	descriptors)
+	{
+		return write(destSet, destLocation.m_binding, destLocation.m_arrayElement, numDescriptors, descriptorType, descriptors);
+	}
+
+	inline DescriptorSetUpdateBuilder&	copySingle					(VkDescriptorSet	srcSet,
+																	 const Location& 	srcLocation,
+																	 VkDescriptorSet	destSet,
+																	 const Location& 	destLocation)
+	{
+		return copy(srcSet, srcLocation.m_binding, srcLocation.m_arrayElement, destSet, destLocation.m_binding, destLocation.m_arrayElement, 1u);
+	}
+
+	inline DescriptorSetUpdateBuilder&	copyArray					(VkDescriptorSet	srcSet,
+																	 const Location& 	srcLocation,
+																	 VkDescriptorSet	destSet,
+																	 const Location& 	destLocation,
+																	 deUint32			count)
+	{
+		return copy(srcSet, srcLocation.m_binding, srcLocation.m_arrayElement, destSet, destLocation.m_binding, destLocation.m_arrayElement, count);
+	}
+
+private:
+										DescriptorSetUpdateBuilder	(const DescriptorSetUpdateBuilder&); // delete
+	DescriptorSetUpdateBuilder&			operator=					(const DescriptorSetUpdateBuilder&); // delete
+
+	std::vector<VkWriteDescriptorSet>	m_writes;
+	std::vector<VkCopyDescriptorSet>	m_copies;
+};
+
+} // vk
+
+#endif // _VKBUILDERUTIL_HPP
diff --git a/external/vulkancts/framework/vulkan/vkRefUtil.cpp b/external/vulkancts/framework/vulkan/vkRefUtil.cpp
index bde4453..75c0f73 100644
--- a/external/vulkancts/framework/vulkan/vkRefUtil.cpp
+++ b/external/vulkancts/framework/vulkan/vkRefUtil.cpp
@@ -53,7 +53,7 @@
 	return Move<VkPipeline>(check<VkPipeline>(object), Deleter<VkPipeline>(vk, device));
 }
 
-Move<VkDescriptorSet> allocDescriptorSet (const DeviceInterface& vk, vk::VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorSetUsage setUsage, VkDescriptorSetLayout layout)
+Move<VkDescriptorSet> allocDescriptorSet (const DeviceInterface& vk, VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorSetUsage setUsage, VkDescriptorSetLayout layout)
 {
 	VkDescriptorSet	descriptorSet	= 0u;
 	deUint32		numCreated		= 0;
diff --git a/external/vulkancts/framework/vulkan/vkRefUtil.hpp b/external/vulkancts/framework/vulkan/vkRefUtil.hpp
index 46b134b..7dedbd7 100644
--- a/external/vulkancts/framework/vulkan/vkRefUtil.hpp
+++ b/external/vulkancts/framework/vulkan/vkRefUtil.hpp
@@ -44,7 +44,7 @@
 
 Move<VkPipeline>		createGraphicsPipeline	(const DeviceInterface& vk, VkDevice device, VkPipelineCache pipelineCache, const VkGraphicsPipelineCreateInfo* pCreateInfo);
 Move<VkPipeline>		createComputePipeline	(const DeviceInterface& vk, VkDevice device, VkPipelineCache pipelineCache, const VkComputePipelineCreateInfo* pCreateInfo);
-Move<VkDescriptorSet>	allocDescriptorSet		(const DeviceInterface& vk, vk::VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorSetUsage setUsage, VkDescriptorSetLayout layout);
+Move<VkDescriptorSet>	allocDescriptorSet		(const DeviceInterface& vk, VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorSetUsage setUsage, VkDescriptorSetLayout layout);
 
 } // vk
 
diff --git a/external/vulkancts/gen_framework.py b/external/vulkancts/gen_framework.py
index b80703c..f94eefa 100644
--- a/external/vulkancts/gen_framework.py
+++ b/external/vulkancts/gen_framework.py
@@ -74,7 +74,11 @@
 	"VK_UUID_LENGTH",
 	"VK_MAX_MEMORY_TYPES",
 	"VK_MAX_MEMORY_HEAPS",
-	"VK_MAX_DESCRIPTION"
+	"VK_MAX_DESCRIPTION",
+	"VK_QUEUE_FAMILY_IGNORED",
+	"VK_NO_ATTACHMENT",
+	"VK_FALSE",
+	"VK_TRUE",
 ]
 
 class Handle:
@@ -204,7 +208,10 @@
 	return bitEnumName[:-4] + "s"
 
 def parsePreprocDefinedValue (src, name):
-	return re.search(r'#\s*define\s+' + name + r'\s+([^\n]+)\n', src).group(1).strip()
+	definition = re.search(r'#\s*define\s+' + name + r'\s+([^\n]+)\n', src)
+	if definition is None:
+		raise Exception("No such definition: %s" % name)
+	return definition.group(1).strip()
 
 def parseEnum (name, src):
 	keyValuePtrn	= '(' + IDENT_PTRN + r')\s*=\s*([^\s,}]+)\s*[,}]'
@@ -347,7 +354,7 @@
 
 def writeBasicTypes (api, filename):
 	def gen ():
-		for line in indentLines(["#define %s\t%s" % define for define in api.definitions]):
+		for line in indentLines(["enum { %s\t= %s\t};" % define for define in api.definitions]):
 			yield line
 		yield ""
 		for line in genHandlesSrc(api.handles):
diff --git a/framework/delibs/decpp/deArrayBuffer.hpp b/framework/delibs/decpp/deArrayBuffer.hpp
index 0ecb690..5a98898 100644
--- a/framework/delibs/decpp/deArrayBuffer.hpp
+++ b/framework/delibs/decpp/deArrayBuffer.hpp
@@ -48,8 +48,11 @@
 class ArrayBuffer
 {
 public:
+	DE_STATIC_ASSERT(Stride >= sizeof(T));
+
 					ArrayBuffer		(void) throw();
 					ArrayBuffer		(size_t numElements);
+					ArrayBuffer		(const T* ptr, size_t numElements);
 					ArrayBuffer		(const ArrayBuffer& other);
 					~ArrayBuffer	(void) throw();
 	ArrayBuffer&	operator=		(const ArrayBuffer& other);
@@ -97,6 +100,33 @@
 }
 
 template <typename T, size_t Alignment, size_t Stride>
+ArrayBuffer<T,Alignment,Stride>::ArrayBuffer (const T* ptr, size_t numElements)
+	: m_ptr	(DE_NULL)
+	, m_cap	(0)
+{
+	if (numElements)
+	{
+		// create new buffer of wanted size, copy to it, and swap to it
+		ArrayBuffer<T,Alignment,Stride> tmp(numElements);
+
+		if (Stride == sizeof(T))
+		{
+			// tightly packed
+			const size_t storageSize = sizeof(T) * numElements;
+			deMemcpy(tmp.m_ptr, ptr, (int)storageSize);
+		}
+		else
+		{
+			// sparsely packed
+			for (size_t ndx = 0; ndx < numElements; ++ndx)
+				*tmp.getElementPtr(ndx) = ptr[ndx];
+		}
+
+		swap(tmp);
+	}
+}
+
+template <typename T, size_t Alignment, size_t Stride>
 ArrayBuffer<T,Alignment,Stride>::ArrayBuffer (const ArrayBuffer<T,Alignment,Stride>& other)
 	: m_ptr	(DE_NULL)
 	, m_cap	(0)
diff --git a/framework/opengl/gluTexture.cpp b/framework/opengl/gluTexture.cpp
index 7ae0a3c..d81bda1 100644
--- a/framework/opengl/gluTexture.cpp
+++ b/framework/opengl/gluTexture.cpp
@@ -839,10 +839,9 @@
 		}
 	}
 
-	m_refBuffer.resize(bufferSize, 0);
-
+	m_refBuffer.setStorage(bufferSize);
 	if (data)
-		deMemcpy(&m_refBuffer[0], data, (int)bufferSize);
+		deMemcpy(m_refBuffer.getPtr(), data, (int)bufferSize);
 
 	m_format	= internalFormat;
 	m_offset	= offset;
@@ -851,16 +850,6 @@
 	DE_ASSERT(size != 0 || offset == 0);
 
 	{
-		const tcu::TextureFormat	format			= mapGLInternalFormat(internalFormat);
-		deInt32						maxTextureSize	= 0;
-
-		gl.getIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &maxTextureSize);
-		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE) failed");
-
-		m_refTexture = tcu::PixelBufferAccess(format, de::min<int>((int)maxTextureSize, (int)((m_size != 0 ? m_size : bufferSize) / format.getPixelSize())), 1, 1, &(m_refBuffer[m_offset]));
-	}
-
-	{
 		gl.genTextures(1, &m_glTexture);
 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
 
@@ -868,7 +857,7 @@
 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() failed");
 
 		gl.bindBuffer(GL_TEXTURE_BUFFER, m_glBuffer);
-		gl.bufferData(GL_TEXTURE_BUFFER, (glw::GLsizei)m_refBuffer.size(), &(m_refBuffer[0]), GL_STATIC_DRAW);
+		gl.bufferData(GL_TEXTURE_BUFFER, (glw::GLsizei)m_refBuffer.size(), data, GL_STATIC_DRAW);
 		gl.bindBuffer(GL_TEXTURE_BUFFER, 0);
 		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create buffer");
 
@@ -893,31 +882,31 @@
 		m_context.getFunctions().deleteBuffers(1, &m_glBuffer);
 }
 
+
+const tcu::PixelBufferAccess TextureBuffer::getFullRefTexture (void)
+{
+	const tcu::TextureFormat	format				= mapGLInternalFormat(m_format);
+	const size_t				bufferLengthBytes	= (m_size != 0) ? (m_size) : (m_refBuffer.size());
+	const int					bufferLengthPixels	= (int)bufferLengthBytes / format.getPixelSize();
+
+	return tcu::PixelBufferAccess(format,
+								  tcu::IVec3(bufferLengthPixels, 1, 1),
+								  (deUint8*)m_refBuffer.getPtr() + m_offset);
+}
+
+const tcu::ConstPixelBufferAccess TextureBuffer::getFullRefTexture (void) const
+{
+	return const_cast<TextureBuffer*>(this)->getFullRefTexture();
+}
+
 void TextureBuffer::upload (void)
 {
 	const glw::Functions& gl = m_context.getFunctions();
 
 	gl.bindBuffer(GL_TEXTURE_BUFFER, m_glBuffer);
-	gl.bufferData(GL_TEXTURE_BUFFER, (glw::GLsizei)m_refBuffer.size(), &(m_refBuffer[0]), GL_STATIC_DRAW);
+	gl.bufferData(GL_TEXTURE_BUFFER, (glw::GLsizei)m_refBuffer.size(), m_refBuffer.getPtr(), GL_STATIC_DRAW);
 	gl.bindBuffer(GL_TEXTURE_BUFFER, 0);
 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to upload buffer");
 }
 
-void TextureBuffer::bufferData (const deUint8* data, size_t size)
-{
-	const glw::Functions& gl = m_context.getFunctions();
-
-	m_refBuffer = vector<deUint8>(data, data+size);
-
-	{
-		const tcu::TextureFormat	format			= mapGLInternalFormat(m_format);
-		deInt32						maxTextureSize	= 0;
-
-		gl.getIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &maxTextureSize);
-		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE) failed");
-
-		m_refTexture = tcu::PixelBufferAccess(format, de::min<int>((int)maxTextureSize, (int)((m_size != 0 ? m_size : m_refBuffer.size())  / format.getPixelSize())), 1, 1, &(m_refBuffer[m_offset]));
-	}
-}
-
 } // glu
diff --git a/framework/opengl/gluTexture.hpp b/framework/opengl/gluTexture.hpp
index 1a8d7db..f3670d7 100644
--- a/framework/opengl/gluTexture.hpp
+++ b/framework/opengl/gluTexture.hpp
@@ -276,11 +276,13 @@
 
 										~TextureBuffer		(void);
 
-	const tcu::PixelBufferAccess&		getRefTexture		(void)			{ return m_refTexture;			}
-	const tcu::ConstPixelBufferAccess&	getRefTexture		(void) const	{ return m_refTexture;			}
+	// \note Effective pixel buffer access must be limited to w <= GL_MAX_TEXTURE_BUFFER_SIZE
+	const tcu::PixelBufferAccess		getFullRefTexture	(void);
+	const tcu::ConstPixelBufferAccess	getFullRefTexture	(void) const;
 
-	deUint8*							getRefBuffer		(void)			{ return &(m_refBuffer[0]);		}
-	const deUint8*						getRefBuffer		(void) const	{ return &(m_refBuffer[0]);		}
+	// \note mutating buffer storage will invalidate existing pixel buffer accesses
+	de::ArrayBuffer<deUint8>&			getRefBuffer		(void)			{ return m_refBuffer;			}
+	const de::ArrayBuffer<deUint8>&		getRefBuffer		(void) const	{ return m_refBuffer;			}
 
 	size_t								getSize				(void) const	{ return m_size;				}
 	size_t								getOffset			(void) const	{ return m_offset;				}
@@ -289,25 +291,21 @@
 	deUint32							getGLTexture		(void) const	{ return m_glTexture;			}
 	deUint32							getGLBuffer			(void) const	{ return m_glBuffer;			}
 
-	// \note Resizes reference buffer. Invalidates old pixel buffer acceses.
-	// \note Doesn't upload data.
-	void								bufferData			(const deUint8* data, size_t size);
 	void								upload				(void);
 
 private:
-	void					init					(deUint32 internalFormat, size_t bufferSize, size_t offset, size_t size, const void* data);
-							TextureBuffer			(const TextureBuffer& other); // Not allowed!
-	TextureBuffer&			operator=				(const TextureBuffer& other); // Not allowed!
+	void								init				(deUint32 internalFormat, size_t bufferSize, size_t offset, size_t size, const void* data);
+										TextureBuffer		(const TextureBuffer& other); // Not allowed!
+	TextureBuffer&						operator=			(const TextureBuffer& other); // Not allowed!
 
-	const RenderContext&	m_context;
-	deUint32				m_format;		//!< Internal format.
-	std::vector<deUint8>	m_refBuffer;
-	size_t					m_offset;
-	size_t					m_size;
+	const RenderContext&				m_context;
+	deUint32							m_format;		//!< Internal format.
+	de::ArrayBuffer<deUint8>			m_refBuffer;
+	size_t								m_offset;
+	size_t								m_size;
 
-	tcu::PixelBufferAccess	m_refTexture;
-	deUint32				m_glTexture;
-	deUint32				m_glBuffer;
+	deUint32							m_glTexture;
+	deUint32							m_glBuffer;
 } DE_WARN_UNUSED_TYPE;
 
 } // glu
diff --git a/framework/opengl/gluTextureUtil.cpp b/framework/opengl/gluTextureUtil.cpp
index 5b31d2f..154963e 100644
--- a/framework/opengl/gluTextureUtil.cpp
+++ b/framework/opengl/gluTextureUtil.cpp
@@ -24,6 +24,7 @@
 #include "gluTextureUtil.hpp"
 #include "gluRenderContext.hpp"
 #include "gluContextInfo.hpp"
+#include "gluTexture.hpp"
 #include "tcuTextureUtil.hpp"
 #include "tcuFormatUtil.hpp"
 #include "glwEnums.hpp"
@@ -1170,4 +1171,21 @@
 	return s_defaultOffsets;
 }
 
+tcu::PixelBufferAccess getTextureBufferEffectiveRefTexture (TextureBuffer& buffer, int maxTextureBufferSize)
+{
+	DE_ASSERT(maxTextureBufferSize > 0);
+
+	const tcu::PixelBufferAccess& fullAccess = buffer.getFullRefTexture();
+
+	return tcu::PixelBufferAccess(fullAccess.getFormat(),
+								  tcu::IVec3(de::min(fullAccess.getWidth(), maxTextureBufferSize), 1, 1),
+								  fullAccess.getPitch(),
+								  fullAccess.getDataPtr());
+}
+
+tcu::ConstPixelBufferAccess getTextureBufferEffectiveRefTexture (const TextureBuffer& buffer, int maxTextureBufferSize)
+{
+	return getTextureBufferEffectiveRefTexture(const_cast<TextureBuffer&>(buffer), maxTextureBufferSize);
+}
+
 } // glu
diff --git a/framework/opengl/gluTextureUtil.hpp b/framework/opengl/gluTextureUtil.hpp
index 3112347..f806ec8 100644
--- a/framework/opengl/gluTextureUtil.hpp
+++ b/framework/opengl/gluTextureUtil.hpp
@@ -34,6 +34,7 @@
 
 class RenderContext;
 class ContextInfo;
+class TextureBuffer;
 
 /*--------------------------------------------------------------------*//*!
  * \brief GL pixel transfer format.
@@ -88,6 +89,9 @@
 
 const tcu::IVec2				(&getDefaultGatherOffsets			(void))[4];
 
+tcu::PixelBufferAccess			getTextureBufferEffectiveRefTexture	(TextureBuffer& buffer, int maxTextureBufferSize);
+tcu::ConstPixelBufferAccess		getTextureBufferEffectiveRefTexture	(const TextureBuffer& buffer, int maxTextureBufferSize);
+
 } // glu
 
 #endif // _GLUTEXTUREUTIL_HPP
diff --git a/modules/gles31/functional/es31fTextureFormatTests.cpp b/modules/gles31/functional/es31fTextureFormatTests.cpp
index ad35705..c014870 100644
--- a/modules/gles31/functional/es31fTextureFormatTests.cpp
+++ b/modules/gles31/functional/es31fTextureFormatTests.cpp
@@ -240,10 +240,10 @@
 
 // TextureBufferFormatCase
 
-class TextureBufferFormatCase : public tcu::TestCase
+class TextureBufferFormatCase : public TestCase
 {
 public:
-								TextureBufferFormatCase		(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, deUint32 internalFormat, int width);
+								TextureBufferFormatCase		(Context& ctx, glu::RenderContext& renderCtx, const char* name, const char* description, deUint32 internalFormat, int width);
 								~TextureBufferFormatCase	(void);
 
 	void						init						(void);
@@ -258,18 +258,20 @@
 
 	deUint32					m_format;
 	int							m_width;
+	int							m_maxTextureBufferSize;
 
 	glu::TextureBuffer*			m_texture;
 	TextureRenderer				m_renderer;
 };
 
-TextureBufferFormatCase::TextureBufferFormatCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, deUint32 internalFormat, int width)
-	: TestCase		(testCtx, name, description)
-	, m_renderCtx	(renderCtx)
-	, m_format		(internalFormat)
-	, m_width		(width)
-	, m_texture		(DE_NULL)
-	, m_renderer	(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_310_ES, glu::PRECISION_HIGHP)
+TextureBufferFormatCase::TextureBufferFormatCase (Context& ctx, glu::RenderContext& renderCtx, const char* name, const char* description, deUint32 internalFormat, int width)
+	: TestCase					(ctx, name, description)
+	, m_renderCtx				(renderCtx)
+	, m_format					(internalFormat)
+	, m_width					(width)
+	, m_maxTextureBufferSize	(0)
+	, m_texture					(DE_NULL)
+	, m_renderer				(renderCtx, ctx.getTestContext().getLog(), glu::GLSL_VERSION_310_ES, glu::PRECISION_HIGHP)
 {
 }
 
@@ -285,18 +287,19 @@
 	tcu::TextureFormatInfo	spec	= tcu::getTextureFormatInfo(fmt);
 	tcu::Vec4				colorA	(spec.valueMin.x(), spec.valueMax.y(), spec.valueMin.z(), spec.valueMax.w());
 	tcu::Vec4				colorB	(spec.valueMax.x(), spec.valueMin.y(), spec.valueMax.z(), spec.valueMin.w());
-	std::ostringstream		fmtName;
 
-	fmtName << glu::getPixelFormatStr(m_format);
+	m_maxTextureBufferSize = m_context.getContextInfo().getInt(GL_MAX_TEXTURE_BUFFER_SIZE);
+	if (m_maxTextureBufferSize <= 0)
+		TCU_THROW(NotSupportedError, "GL_MAX_TEXTURE_BUFFER_SIZE > 0 required");
 
-	log << TestLog::Message << "Buffer texture, " << fmtName.str() << ", " << m_width
+	log << TestLog::Message << "Buffer texture, " << glu::getPixelFormatStr(m_format) << ", " << m_width
 							<< ",\n  fill with " << formatGradient(&colorA, &colorB) << " gradient"
 		<< TestLog::EndMessage;
 
 	m_texture = new glu::TextureBuffer(m_renderCtx, m_format, m_width * fmt.getPixelSize());
 
 	// Fill level 0.
-	tcu::fillWithComponentGradients(m_texture->getRefTexture(), colorA, colorB);
+	tcu::fillWithComponentGradients(m_texture->getFullRefTexture(), colorA, colorB);
 }
 
 void TextureBufferFormatCase::deinit (void)
@@ -309,22 +312,23 @@
 
 TextureBufferFormatCase::IterateResult TextureBufferFormatCase::iterate (void)
 {
-	TestLog&				log					= m_testCtx.getLog();
-	const glw::Functions&	gl					= m_renderCtx.getFunctions();
-	RandomViewport			viewport			(m_renderCtx.getRenderTarget(), m_width, 1, deStringHash(getName()));
-	tcu::Surface			renderedFrame		(viewport.width, viewport.height);
-	tcu::Surface			referenceFrame		(viewport.width, viewport.height);
-	tcu::RGBA				threshold			= m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
-	vector<float>			texCoord;
-	RenderParams			renderParams		(TEXTURETYPE_BUFFER);
-	tcu::TextureFormatInfo	spec				= tcu::getTextureFormatInfo(m_texture->getRefTexture().getFormat());
+	TestLog&							log						= m_testCtx.getLog();
+	const glw::Functions&				gl						= m_renderCtx.getFunctions();
+	RandomViewport						viewport				(m_renderCtx.getRenderTarget(), m_width, 1, deStringHash(getName()));
+	tcu::Surface						renderedFrame			(viewport.width, viewport.height);
+	tcu::Surface						referenceFrame			(viewport.width, viewport.height);
+	tcu::RGBA							threshold				= m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
+	vector<float>						texCoord;
+	RenderParams						renderParams			(TEXTURETYPE_BUFFER);
+	const tcu::ConstPixelBufferAccess	effectiveRefTexture		= glu::getTextureBufferEffectiveRefTexture(*m_texture, m_maxTextureBufferSize);
+	tcu::TextureFormatInfo				spec					= tcu::getTextureFormatInfo(effectiveRefTexture.getFormat());
 
 	renderParams.flags			|= RenderParams::LOG_ALL;
-	renderParams.samplerType	= getFetchSamplerType(m_texture->getRefTexture().getFormat());
+	renderParams.samplerType	= getFetchSamplerType(effectiveRefTexture.getFormat());
 	renderParams.colorScale		= spec.lookupScale;
 	renderParams.colorBias		= spec.lookupBias;
 
-	computeQuadTexCoord1D(texCoord, 0.0f, (float)(m_texture->getRefTexture().getWidth()));
+	computeQuadTexCoord1D(texCoord, 0.0f, (float)(effectiveRefTexture.getWidth()));
 
 	gl.clearColor(0.125f, 0.25f, 0.5f, 1.0f);
 	gl.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
@@ -349,7 +353,7 @@
 	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels()");
 
 	// Compute reference.
-	fetchTexture(SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat()), m_texture->getRefTexture(), &texCoord[0], spec.lookupScale, spec.lookupBias);
+	fetchTexture(SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat()), effectiveRefTexture, &texCoord[0], spec.lookupScale, spec.lookupBias);
 
 	// Compare and log.
 	bool isOk = compareImages(log, referenceFrame, renderedFrame, threshold);
@@ -553,8 +557,8 @@
 		string		nameBase		= bufferColorFormats[formatNdx].name;
 		string		descriptionBase	= glu::getPixelFormatName(internalFormat);
 
-		sizedBufferGroup->addChild	(new TextureBufferFormatCase	(m_testCtx, m_context.getRenderContext(),	(nameBase + "_pot").c_str(),	(descriptionBase + ", GL_TEXTURE_BUFFER").c_str(),	internalFormat, 64));
-		sizedBufferGroup->addChild	(new TextureBufferFormatCase	(m_testCtx, m_context.getRenderContext(),	(nameBase + "_npot").c_str(),	(descriptionBase + ", GL_TEXTURE_BUFFER").c_str(),	internalFormat, 112));
+		sizedBufferGroup->addChild	(new TextureBufferFormatCase	(m_context, m_context.getRenderContext(),	(nameBase + "_pot").c_str(),	(descriptionBase + ", GL_TEXTURE_BUFFER").c_str(),	internalFormat, 64));
+		sizedBufferGroup->addChild	(new TextureBufferFormatCase	(m_context, m_context.getRenderContext(),	(nameBase + "_npot").c_str(),	(descriptionBase + ", GL_TEXTURE_BUFFER").c_str(),	internalFormat, 112));
 	}
 }
 
diff --git a/modules/glshared/glsTextureBufferCase.cpp b/modules/glshared/glsTextureBufferCase.cpp
index cb4b35a..b7f1f73 100644
--- a/modules/glshared/glsTextureBufferCase.cpp
+++ b/modules/glshared/glsTextureBufferCase.cpp
@@ -41,6 +41,7 @@
 #include "gluShaderUtil.hpp"
 #include "gluStrUtil.hpp"
 #include "gluTexture.hpp"
+#include "gluTextureUtil.hpp"
 
 #include "glwEnums.hpp"
 #include "glwFunctions.hpp"
@@ -204,7 +205,7 @@
 	}
 
 private:
-	const tcu::ConstPixelBufferAccess& m_texture;
+	const tcu::ConstPixelBufferAccess m_texture;
 };
 
 class CoordFragmentShader : public rr::FragmentShader
@@ -287,7 +288,7 @@
 	}
 
 private:
-	const tcu::ConstPixelBufferAccess& m_texture;
+	const tcu::ConstPixelBufferAccess m_texture;
 };
 
 string generateVertexShaderTemplate (RenderBits renderBits)
@@ -428,7 +429,12 @@
 
 	log << TestLog::Message << "BufferData, Size: " << data.size() << TestLog::EndMessage;
 
-	texture.bufferData(&(data[0]), data.size());
+	{
+		// replace getRefBuffer with a new buffer
+		de::ArrayBuffer<deUint8> buffer(&(data[0]), data.size());
+		texture.getRefBuffer().swap(buffer);
+	}
+
 	texture.upload();
 }
 
@@ -452,7 +458,7 @@
 	gl.bindBuffer(GL_TEXTURE_BUFFER, 0);
 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to update data with glBufferSubData()");
 
-	deMemcpy(texture.getRefBuffer() + offset, &(data[0]), int(data.size()));
+	deMemcpy((deUint8*)texture.getRefBuffer().getPtr() + offset, &(data[0]), int(data.size()));
 }
 
 void modifyMapWrite (TestLog&				log,
@@ -485,7 +491,7 @@
 	gl.bindBuffer(GL_TEXTURE_BUFFER, 0);
 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to update data with glMapBufferRange()");
 
-	deMemcpy(texture.getRefBuffer()+offset, &(data[0]), int(data.size()));
+	deMemcpy((deUint8*)texture.getRefBuffer().getPtr()+offset, &(data[0]), int(data.size()));
 }
 
 void modifyMapReadWrite (TestLog&				log,
@@ -498,6 +504,7 @@
 	const size_t				size		= de::max<size_t>(minSize, size_t((float)(texture.getSize() != 0 ? texture.getSize() : texture.getBufferSize()) * (0.7f + 0.3f * rng.getFloat())));
 	const size_t				minOffset	= texture.getOffset();
 	const size_t				offset		= minOffset + (rng.getUint32() % (texture.getBufferSize() - (size + minOffset)));
+	deUint8* const				refPtr		= (deUint8*)texture.getRefBuffer().getPtr() + offset;
 	vector<deUint8>				data;
 
 	genRandomCoords(rng, data, offset, size);
@@ -514,10 +521,10 @@
 
 		for (int i = 0; i < (int)data.size(); i++)
 		{
-			if (ptr[i] != texture.getRefBuffer()[offset+i])
+			if (ptr[i] != refPtr[i])
 			{
 				if (invalidBytes < 24)
-					log << TestLog::Message << "Invalid byte in mapped buffer. " << tcu::Format::Hex<2>(data[i]).toString() << " at " << i << ", expected " << tcu::Format::Hex<2>(texture.getRefBuffer()[i]).toString() << TestLog::EndMessage;
+					log << TestLog::Message << "Invalid byte in mapped buffer. " << tcu::Format::Hex<2>(data[i]).toString() << " at " << i << ", expected " << tcu::Format::Hex<2>(refPtr[i]).toString() << TestLog::EndMessage;
 
 				invalidBytes++;
 			}
@@ -538,7 +545,7 @@
 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to update data with glMapBufferRange()");
 
 	for (int i = 0; i < (int)data.size(); i++)
-		texture.getRefBuffer()[offset+i] = data[i];
+		refPtr[i] = data[i];
 }
 
 void modify (TestLog&						log,
@@ -649,31 +656,34 @@
 void renderReference (RenderBits					renderBits,
 					  deUint32						coordSeed,
 					  int							triangleCount,
-					  glu::TextureBuffer&			texture,
+					  const glu::TextureBuffer&		texture,
+					  int							maxTextureBufferSize,
 					  const tcu::PixelBufferAccess&	target)
 {
-	const CoordVertexShader			coordVertexShader;
-	const TextureVertexShader		textureVertexShader		(texture.getRefTexture());
-	const rr::VertexShader* const	vertexShader			= (renderBits & RENDERBITS_AS_VERTEX_TEXTURE ? static_cast<const rr::VertexShader*>(&textureVertexShader) : &coordVertexShader);
+	const tcu::ConstPixelBufferAccess	effectiveAccess			= glu::getTextureBufferEffectiveRefTexture(texture, maxTextureBufferSize);
 
-	const CoordFragmentShader		coordFragmmentShader;
-	const TextureFragmentShader		textureFragmentShader	(texture.getRefTexture());
-	const rr::FragmentShader* const	fragmentShader			= (renderBits & RENDERBITS_AS_FRAGMENT_TEXTURE ? static_cast<const rr::FragmentShader*>(&textureFragmentShader) : &coordFragmmentShader);
+	const CoordVertexShader				coordVertexShader;
+	const TextureVertexShader			textureVertexShader		(effectiveAccess);
+	const rr::VertexShader* const		vertexShader			= (renderBits & RENDERBITS_AS_VERTEX_TEXTURE ? static_cast<const rr::VertexShader*>(&textureVertexShader) : &coordVertexShader);
 
-	const rr::Renderer				renderer;
-	const rr::RenderState			renderState(rr::ViewportState(rr::WindowRectangle(0, 0, target.getWidth(), target.getHeight())));
-	const rr::RenderTarget			renderTarget(rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(target));
+	const CoordFragmentShader			coordFragmmentShader;
+	const TextureFragmentShader			textureFragmentShader	(effectiveAccess);
+	const rr::FragmentShader* const		fragmentShader			= (renderBits & RENDERBITS_AS_FRAGMENT_TEXTURE ? static_cast<const rr::FragmentShader*>(&textureFragmentShader) : &coordFragmmentShader);
 
-	const rr::Program				program(vertexShader, fragmentShader);
+	const rr::Renderer					renderer;
+	const rr::RenderState				renderState(rr::ViewportState(rr::WindowRectangle(0, 0, target.getWidth(), target.getHeight())));
+	const rr::RenderTarget				renderTarget(rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(target));
 
-	rr::VertexAttrib				vertexAttribs[1];
-	vector<deUint8>					coords;
+	const rr::Program					program(vertexShader, fragmentShader);
+
+	rr::VertexAttrib					vertexAttribs[1];
+	vector<deUint8>						coords;
 
 	if (renderBits & RENDERBITS_AS_VERTEX_ARRAY)
 	{
 		vertexAttribs[0].type			= rr::VERTEXATTRIBTYPE_NONPURE_UNORM8;
 		vertexAttribs[0].size			= 2;
-		vertexAttribs[0].pointer		= texture.getRefBuffer();
+		vertexAttribs[0].pointer		= texture.getRefBuffer().getPtr();
 	}
 	else
 	{
@@ -688,7 +698,7 @@
 
 	if (renderBits & RENDERBITS_AS_INDEX_ARRAY)
 	{
-		const rr::PrimitiveList	primitives(rr::PRIMITIVETYPE_TRIANGLES, triangleCount * 3, rr::DrawIndices((const void*)texture.getRefBuffer(), rr::INDEXTYPE_UINT8));
+		const rr::PrimitiveList	primitives(rr::PRIMITIVETYPE_TRIANGLES, triangleCount * 3, rr::DrawIndices(texture.getRefBuffer().getPtr(), rr::INDEXTYPE_UINT8));
 		const rr::DrawCommand	cmd(renderState, renderTarget, program, 1, vertexAttribs, primitives);
 
 		renderer.draw(cmd);
@@ -752,14 +762,19 @@
 			 glu::TextureBuffer&			texture,
 			 const tcu::PixelBufferAccess&	target)
 {
-	const tcu::ScopedLogSection	renderSection	(log, "Render Texture buffer", "Render Texture Buffer");
-	const int					triangleCount	= 8;
-	const deUint32				coordSeed		= rng.getUint32();
+	const tcu::ScopedLogSection	renderSection			(log, "Render Texture buffer", "Render Texture Buffer");
+	const int					triangleCount			= 8;
+	const deUint32				coordSeed				= rng.getUint32();
+	int							maxTextureBufferSize	= 0;
+
+	renderContext.getFunctions().getIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &maxTextureBufferSize);
+	GLU_EXPECT_NO_ERROR(renderContext.getFunctions().getError(), "query GL_MAX_TEXTURE_BUFFER_SIZE");
+	DE_ASSERT(maxTextureBufferSize > 0); // checked in init()
 
 	logRendering(log, renderBits);
 
 	renderGL(renderContext, renderBits, coordSeed, triangleCount, program, texture);
-	renderReference(renderBits, coordSeed, triangleCount, texture, target);
+	renderReference(renderBits, coordSeed, triangleCount, texture, maxTextureBufferSize, target);
 }
 
 void verifyScreen (TestLog&								log,
@@ -951,6 +966,12 @@
 		&& !(glu::contextSupports(m_renderCtx.getType(), glu::ApiType(3, 1, glu::PROFILE_ES)) && info->isExtensionSupported("GL_EXT_texture_buffer")))
 		throw tcu::NotSupportedError("Texture buffers not supported", "", __FILE__, __LINE__);
 
+	{
+		const int maxTextureBufferSize = info->getInt(GL_MAX_TEXTURE_BUFFER_SIZE);
+		if (maxTextureBufferSize <= 0)
+			TCU_THROW(NotSupportedError, "GL_MAX_TEXTURE_BUFFER_SIZE > 0 required");
+	}
+
 	if (m_preRender != 0)
 	{
 		TestLog&					log			= m_testCtx.getLog();