Home | History | Annotate | Download | only in pipeline
      1 /*------------------------------------------------------------------------
      2  * Vulkan Conformance Tests
      3  * ------------------------
      4  *
      5  * Copyright (c) 2015 The Khronos Group Inc.
      6  * Copyright (c) 2015 Imagination Technologies Ltd.
      7  *
      8  * Licensed under the Apache License, Version 2.0 (the "License");
      9  * you may not use this file except in compliance with the License.
     10  * You may obtain a copy of the License at
     11  *
     12  *      http://www.apache.org/licenses/LICENSE-2.0
     13  *
     14  * Unless required by applicable law or agreed to in writing, software
     15  * distributed under the License is distributed on an "AS IS" BASIS,
     16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     17  * See the License for the specific language governing permissions and
     18  * limitations under the License.
     19  *
     20  *//*!
     21  * \file
     22  * \brief Utilities for images.
     23  *//*--------------------------------------------------------------------*/
     24 
     25 #include "vktPipelineImageUtil.hpp"
     26 #include "vkImageUtil.hpp"
     27 #include "vkMemUtil.hpp"
     28 #include "vkQueryUtil.hpp"
     29 #include "vkRefUtil.hpp"
     30 #include "tcuTextureUtil.hpp"
     31 #include "tcuAstcUtil.hpp"
     32 #include "deRandom.hpp"
     33 
     34 namespace vkt
     35 {
     36 namespace pipeline
     37 {
     38 
     39 using namespace vk;
     40 
     41 /*! Gets the next multiple of a given divisor */
     42 static deUint32 getNextMultiple (deUint32 divisor, deUint32 value)
     43 {
     44 	if (value % divisor == 0)
     45 	{
     46 		return value;
     47 	}
     48 	return value + divisor - (value % divisor);
     49 }
     50 
     51 /*! Gets the next value that is multiple of all given divisors */
     52 static deUint32 getNextMultiple (const std::vector<deUint32>& divisors, deUint32 value)
     53 {
     54 	deUint32	nextMultiple		= value;
     55 	bool		nextMultipleFound	= false;
     56 
     57 	while (true)
     58 	{
     59 		nextMultipleFound = true;
     60 
     61 		for (size_t divNdx = 0; divNdx < divisors.size(); divNdx++)
     62 			nextMultipleFound = nextMultipleFound && (nextMultiple % divisors[divNdx] == 0);
     63 
     64 		if (nextMultipleFound)
     65 			break;
     66 
     67 		DE_ASSERT(nextMultiple < ~((deUint32)0u));
     68 		nextMultiple = getNextMultiple(divisors[0], nextMultiple + 1);
     69 	}
     70 
     71 	return nextMultiple;
     72 }
     73 
     74 bool isSupportedSamplableFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format)
     75 {
     76 	if (isCompressedFormat(format))
     77 	{
     78 		VkPhysicalDeviceFeatures		physicalFeatures;
     79 		const tcu::CompressedTexFormat	compressedFormat	= mapVkCompressedFormat(format);
     80 
     81 		instanceInterface.getPhysicalDeviceFeatures(device, &physicalFeatures);
     82 
     83 		if (tcu::isAstcFormat(compressedFormat))
     84 		{
     85 			if (!physicalFeatures.textureCompressionASTC_LDR)
     86 				return false;
     87 		}
     88 		else if (tcu::isEtcFormat(compressedFormat))
     89 		{
     90 			if (!physicalFeatures.textureCompressionETC2)
     91 				return false;
     92 		}
     93 		else
     94 		{
     95 			DE_FATAL("Unsupported compressed format");
     96 		}
     97 	}
     98 
     99 	VkFormatProperties	formatProps;
    100 	instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps);
    101 
    102 	return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0u;
    103 }
    104 
    105 // \todo [2016-01-21 pyry] Update this to just rely on vkDefs.hpp once
    106 //						   CTS has been updated to 1.0.2.
    107 enum
    108 {
    109 	VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT = 0x00001000,
    110 };
    111 
    112 bool isLinearFilteringSupported (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkFormat format, VkImageTiling tiling)
    113 {
    114 	const VkFormatProperties	formatProperties	= getPhysicalDeviceFormatProperties(vki, physicalDevice, format);
    115 	const VkFormatFeatureFlags	formatFeatures		= tiling == VK_IMAGE_TILING_LINEAR
    116 													? formatProperties.linearTilingFeatures
    117 													: formatProperties.optimalTilingFeatures;
    118 
    119 	switch (format)
    120 	{
    121 		case VK_FORMAT_R32_SFLOAT:
    122 		case VK_FORMAT_R32G32_SFLOAT:
    123 		case VK_FORMAT_R32G32B32_SFLOAT:
    124 		case VK_FORMAT_R32G32B32A32_SFLOAT:
    125 		case VK_FORMAT_R64_SFLOAT:
    126 		case VK_FORMAT_R64G64_SFLOAT:
    127 		case VK_FORMAT_R64G64B64_SFLOAT:
    128 		case VK_FORMAT_R64G64B64A64_SFLOAT:
    129 			return (formatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) != 0;
    130 
    131 		default:
    132 			// \todo [2016-01-21 pyry] Check for all formats once drivers have been updated to 1.0.2
    133 			//						   and we have tests to verify format properties.
    134 			return true;
    135 	}
    136 }
    137 
    138 VkBorderColor getFormatBorderColor (BorderColor color, VkFormat format)
    139 {
    140 	if (!isCompressedFormat(format) && (isIntFormat(format) || isUintFormat(format)))
    141 	{
    142 		switch (color)
    143 		{
    144 			case BORDER_COLOR_OPAQUE_BLACK:			return VK_BORDER_COLOR_INT_OPAQUE_BLACK;
    145 			case BORDER_COLOR_OPAQUE_WHITE:			return VK_BORDER_COLOR_INT_OPAQUE_WHITE;
    146 			case BORDER_COLOR_TRANSPARENT_BLACK:	return VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
    147 			default:
    148 				break;
    149 		}
    150 	}
    151 	else
    152 	{
    153 		switch (color)
    154 		{
    155 			case BORDER_COLOR_OPAQUE_BLACK:			return VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
    156 			case BORDER_COLOR_OPAQUE_WHITE:			return VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
    157 			case BORDER_COLOR_TRANSPARENT_BLACK:	return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
    158 			default:
    159 				break;
    160 		}
    161 	}
    162 
    163 	DE_ASSERT(false);
    164 	return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
    165 }
    166 
    167 de::MovePtr<tcu::TextureLevel> readColorAttachment (const vk::DeviceInterface&	vk,
    168 													vk::VkDevice				device,
    169 													vk::VkQueue					queue,
    170 													deUint32					queueFamilyIndex,
    171 													vk::Allocator&				allocator,
    172 													vk::VkImage					image,
    173 													vk::VkFormat				format,
    174 													const tcu::UVec2&			renderSize)
    175 {
    176 	Move<VkBuffer>					buffer;
    177 	de::MovePtr<Allocation>			bufferAlloc;
    178 	Move<VkCommandPool>				cmdPool;
    179 	Move<VkCommandBuffer>			cmdBuffer;
    180 	Move<VkFence>					fence;
    181 	const tcu::TextureFormat		tcuFormat		= mapVkFormat(format);
    182 	const VkDeviceSize				pixelDataSize	= renderSize.x() * renderSize.y() * tcuFormat.getPixelSize();
    183 	de::MovePtr<tcu::TextureLevel>	resultLevel		(new tcu::TextureLevel(tcuFormat, renderSize.x(), renderSize.y()));
    184 
    185 	// Create destination buffer
    186 	{
    187 		const VkBufferCreateInfo bufferParams =
    188 		{
    189 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
    190 			DE_NULL,									// const void*			pNext;
    191 			0u,											// VkBufferCreateFlags	flags;
    192 			pixelDataSize,								// VkDeviceSize			size;
    193 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
    194 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
    195 			0u,											// deUint32				queueFamilyIndexCount;
    196 			DE_NULL										// const deUint32*		pQueueFamilyIndices;
    197 		};
    198 
    199 		buffer		= createBuffer(vk, device, &bufferParams);
    200 		bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
    201 		VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
    202 	}
    203 
    204 	// Create command pool and buffer
    205 	{
    206 		const VkCommandPoolCreateInfo cmdPoolParams =
    207 		{
    208 			VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,		// VkStructureType		sType;
    209 			DE_NULL,										// const void*			pNext;
    210 			VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,			// VkCmdPoolCreateFlags	flags;
    211 			queueFamilyIndex,								// deUint32				queueFamilyIndex;
    212 		};
    213 
    214 		cmdPool = createCommandPool(vk, device, &cmdPoolParams);
    215 
    216 		const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
    217 		{
    218 			VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,	// VkStructureType			sType;
    219 			DE_NULL,										// const void*				pNext;
    220 			*cmdPool,										// VkCommandPool			commandPool;
    221 			VK_COMMAND_BUFFER_LEVEL_PRIMARY,				// VkCommandBufferLevel		level;
    222 			1u												// deUint32					bufferCount;
    223 		};
    224 
    225 		cmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocateInfo);
    226 	}
    227 
    228 	// Create fence
    229 	{
    230 		const VkFenceCreateInfo fenceParams =
    231 		{
    232 			VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,		// VkStructureType		sType;
    233 			DE_NULL,									// const void*			pNext;
    234 			0u											// VkFenceCreateFlags	flags;
    235 		};
    236 
    237 		fence = createFence(vk, device, &fenceParams);
    238 	}
    239 
    240 	// Barriers for copying image to buffer
    241 
    242 	const VkImageMemoryBarrier imageBarrier =
    243 	{
    244 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
    245 		DE_NULL,									// const void*				pNext;
    246 		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			srcAccessMask;
    247 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
    248 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout			oldLayout;
    249 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout;
    250 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
    251 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
    252 		image,										// VkImage					image;
    253 		{											// VkImageSubresourceRange	subresourceRange;
    254 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
    255 			0u,							// deUint32				baseMipLevel;
    256 			1u,							// deUint32				mipLevels;
    257 			0u,							// deUint32				baseArraySlice;
    258 			1u							// deUint32				arraySize;
    259 		}
    260 	};
    261 
    262 	const VkBufferMemoryBarrier bufferBarrier =
    263 	{
    264 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
    265 		DE_NULL,									// const void*		pNext;
    266 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
    267 		VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
    268 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
    269 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
    270 		*buffer,									// VkBuffer			buffer;
    271 		0u,											// VkDeviceSize		offset;
    272 		pixelDataSize								// VkDeviceSize		size;
    273 	};
    274 
    275 	const VkCommandBufferBeginInfo cmdBufferBeginInfo =
    276 	{
    277 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,			// VkStructureType					sType;
    278 		DE_NULL,												// const void*						pNext;
    279 		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,			// VkCommandBufferUsageFlags		flags;
    280 		(const VkCommandBufferInheritanceInfo*)DE_NULL,
    281 	};
    282 
    283 	// Copy image to buffer
    284 
    285 	const VkBufferImageCopy copyRegion =
    286 	{
    287 		0u,												// VkDeviceSize				bufferOffset;
    288 		(deUint32)renderSize.x(),						// deUint32					bufferRowLength;
    289 		(deUint32)renderSize.y(),						// deUint32					bufferImageHeight;
    290 		{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u },		// VkImageSubresourceLayers	imageSubresource;
    291 		{ 0, 0, 0 },									// VkOffset3D				imageOffset;
    292 		{ renderSize.x(), renderSize.y(), 1u }			// VkExtent3D				imageExtent;
    293 	};
    294 
    295 	VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
    296 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
    297 	vk.cmdCopyImageToBuffer(*cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1, &copyRegion);
    298 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
    299 	VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
    300 
    301 	const VkSubmitInfo submitInfo =
    302 	{
    303 		VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType			sType;
    304 		DE_NULL,						// const void*				pNext;
    305 		0u,								// deUint32					waitSemaphoreCount;
    306 		DE_NULL,						// const VkSemaphore*		pWaitSemaphores;
    307 		DE_NULL,
    308 		1u,								// deUint32					commandBufferCount;
    309 		&cmdBuffer.get(),				// const VkCommandBuffer*	pCommandBuffers;
    310 		0u,								// deUint32					signalSemaphoreCount;
    311 		DE_NULL							// const VkSemaphore*		pSignalSemaphores;
    312 	};
    313 
    314 	VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
    315 	VK_CHECK(vk.waitForFences(device, 1, &fence.get(), 0, ~(0ull) /* infinity */));
    316 
    317 	// Read buffer data
    318 	invalidateMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize);
    319 	tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), bufferAlloc->getHostPtr()));
    320 
    321 	return resultLevel;
    322 }
    323 
    324 void uploadTestTexture (const DeviceInterface&			vk,
    325 						VkDevice						device,
    326 						VkQueue							queue,
    327 						deUint32						queueFamilyIndex,
    328 						Allocator&						allocator,
    329 						const TestTexture&				srcTexture,
    330 						VkImage							destImage)
    331 {
    332 	deUint32						bufferSize;
    333 	Move<VkBuffer>					buffer;
    334 	de::MovePtr<Allocation>			bufferAlloc;
    335 	Move<VkCommandPool>				cmdPool;
    336 	Move<VkCommandBuffer>			cmdBuffer;
    337 	Move<VkFence>					fence;
    338 	std::vector<deUint32>			levelDataSizes;
    339 
    340 	// Calculate buffer size
    341 	bufferSize =  (srcTexture.isCompressed())? srcTexture.getCompressedSize(): srcTexture.getSize();
    342 
    343 	// Create source buffer
    344 	{
    345 		const VkBufferCreateInfo bufferParams =
    346 		{
    347 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
    348 			DE_NULL,									// const void*			pNext;
    349 			0u,											// VkBufferCreateFlags	flags;
    350 			bufferSize,									// VkDeviceSize			size;
    351 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
    352 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
    353 			0u,											// deUint32				queueFamilyIndexCount;
    354 			DE_NULL,									// const deUint32*		pQueueFamilyIndices;
    355 		};
    356 
    357 		buffer		= createBuffer(vk, device, &bufferParams);
    358 		bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
    359 		VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
    360 	}
    361 
    362 	// Create command pool and buffer
    363 	{
    364 		const VkCommandPoolCreateInfo cmdPoolParams =
    365 		{
    366 			VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,		// VkStructureType			sType;
    367 			DE_NULL,										// const void*				pNext;
    368 			VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,			// VkCommandPoolCreateFlags	flags;
    369 			queueFamilyIndex,								// deUint32					queueFamilyIndex;
    370 		};
    371 
    372 		cmdPool = createCommandPool(vk, device, &cmdPoolParams);
    373 
    374 		const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
    375 		{
    376 			VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,	// VkStructureType			sType;
    377 			DE_NULL,										// const void*				pNext;
    378 			*cmdPool,										// VkCommandPool			commandPool;
    379 			VK_COMMAND_BUFFER_LEVEL_PRIMARY,				// VkCommandBufferLevel		level;
    380 			1u,												// deUint32					bufferCount;
    381 		};
    382 
    383 		cmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocateInfo);
    384 	}
    385 
    386 	// Create fence
    387 	{
    388 		const VkFenceCreateInfo fenceParams =
    389 		{
    390 			VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,		// VkStructureType		sType;
    391 			DE_NULL,									// const void*			pNext;
    392 			0u											// VkFenceCreateFlags	flags;
    393 		};
    394 
    395 		fence = createFence(vk, device, &fenceParams);
    396 	}
    397 
    398 	// Barriers for copying buffer to image
    399 	const VkBufferMemoryBarrier preBufferBarrier =
    400 	{
    401 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
    402 		DE_NULL,									// const void*		pNext;
    403 		VK_ACCESS_HOST_WRITE_BIT,					// VkAccessFlags	srcAccessMask;
    404 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags	dstAccessMask;
    405 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
    406 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
    407 		*buffer,									// VkBuffer			buffer;
    408 		0u,											// VkDeviceSize		offset;
    409 		bufferSize									// VkDeviceSize		size;
    410 	};
    411 
    412 	const VkImageMemoryBarrier preImageBarrier =
    413 	{
    414 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
    415 		DE_NULL,										// const void*				pNext;
    416 		0u,												// VkAccessFlags			srcAccessMask;
    417 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
    418 		VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
    419 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout;
    420 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
    421 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
    422 		destImage,										// VkImage					image;
    423 		{												// VkImageSubresourceRange	subresourceRange;
    424 			VK_IMAGE_ASPECT_COLOR_BIT,				// VkImageAspect	aspect;
    425 			0u,										// deUint32			baseMipLevel;
    426 			(deUint32)srcTexture.getNumLevels(),	// deUint32			mipLevels;
    427 			0u,										// deUint32			baseArraySlice;
    428 			(deUint32)srcTexture.getArraySize(),	// deUint32			arraySize;
    429 		}
    430 	};
    431 
    432 	const VkImageMemoryBarrier postImageBarrier =
    433 	{
    434 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
    435 		DE_NULL,										// const void*				pNext;
    436 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			srcAccessMask;
    437 		VK_ACCESS_SHADER_READ_BIT,						// VkAccessFlags			dstAccessMask;
    438 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			oldLayout;
    439 		VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,		// VkImageLayout			newLayout;
    440 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
    441 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
    442 		destImage,										// VkImage					image;
    443 		{												// VkImageSubresourceRange	subresourceRange;
    444 			VK_IMAGE_ASPECT_COLOR_BIT,				// VkImageAspect	aspect;
    445 			0u,										// deUint32			baseMipLevel;
    446 			(deUint32)srcTexture.getNumLevels(),	// deUint32			mipLevels;
    447 			0u,										// deUint32			baseArraySlice;
    448 			(deUint32)srcTexture.getArraySize(),	// deUint32			arraySize;
    449 		}
    450 	};
    451 
    452 	const VkCommandBufferBeginInfo cmdBufferBeginInfo =
    453 	{
    454 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType					sType;
    455 		DE_NULL,										// const void*						pNext;
    456 		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,	// VkCommandBufferUsageFlags		flags;
    457 		(const VkCommandBufferInheritanceInfo*)DE_NULL,
    458 	};
    459 
    460 	const std::vector<VkBufferImageCopy>	copyRegions		= srcTexture.getBufferCopyRegions();
    461 
    462 	// Write buffer data
    463 	srcTexture.write(reinterpret_cast<deUint8*>(bufferAlloc->getHostPtr()));
    464 	flushMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), bufferSize);
    465 
    466 	// Copy buffer to image
    467 	VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
    468 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 1, &preImageBarrier);
    469 	vk.cmdCopyBufferToImage(*cmdBuffer, *buffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), copyRegions.data());
    470 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
    471 
    472 	VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
    473 
    474 	const VkSubmitInfo submitInfo =
    475 	{
    476 		VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType			sType;
    477 		DE_NULL,						// const void*				pNext;
    478 		0u,								// deUint32					waitSemaphoreCount;
    479 		DE_NULL,						// const VkSemaphore*		pWaitSemaphores;
    480 		DE_NULL,
    481 		1u,								// deUint32					commandBufferCount;
    482 		&cmdBuffer.get(),				// const VkCommandBuffer*	pCommandBuffers;
    483 		0u,								// deUint32					signalSemaphoreCount;
    484 		DE_NULL							// const VkSemaphore*		pSignalSemaphores;
    485 	};
    486 
    487 	VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
    488 	VK_CHECK(vk.waitForFences(device, 1, &fence.get(), true, ~(0ull) /* infinity */));
    489 }
    490 
    491 
    492 // Utilities for test textures
    493 
    494 template<typename TcuTextureType>
    495 void allocateLevels (TcuTextureType& texture)
    496 {
    497 	for (int levelNdx = 0; levelNdx < texture.getNumLevels(); levelNdx++)
    498 		texture.allocLevel(levelNdx);
    499 }
    500 
    501 template<typename TcuTextureType>
    502 std::vector<tcu::PixelBufferAccess> getLevelsVector (const TcuTextureType& texture)
    503 {
    504 	std::vector<tcu::PixelBufferAccess> levels(texture.getNumLevels());
    505 
    506 	for (int levelNdx = 0; levelNdx < texture.getNumLevels(); levelNdx++)
    507 		levels[levelNdx] = *reinterpret_cast<const tcu::PixelBufferAccess*>(&texture.getLevel(levelNdx));
    508 
    509 	return levels;
    510 }
    511 
    512 
    513 // TestTexture
    514 
    515 TestTexture::TestTexture (const tcu::TextureFormat& format, int width, int height, int depth)
    516 {
    517 	DE_ASSERT(width >= 1);
    518 	DE_ASSERT(height >= 1);
    519 	DE_ASSERT(depth >= 1);
    520 
    521 	DE_UNREF(format);
    522 	DE_UNREF(width);
    523 	DE_UNREF(height);
    524 	DE_UNREF(depth);
    525 }
    526 
    527 TestTexture::TestTexture (const tcu::CompressedTexFormat& format, int width, int height, int depth)
    528 {
    529 	DE_ASSERT(width >= 1);
    530 	DE_ASSERT(height >= 1);
    531 	DE_ASSERT(depth >= 1);
    532 
    533 	DE_UNREF(format);
    534 	DE_UNREF(width);
    535 	DE_UNREF(height);
    536 	DE_UNREF(depth);
    537 }
    538 
    539 TestTexture::~TestTexture (void)
    540 {
    541 	for (size_t levelNdx = 0; levelNdx < m_compressedLevels.size(); levelNdx++)
    542 		delete m_compressedLevels[levelNdx];
    543 }
    544 
    545 deUint32 TestTexture::getSize (void) const
    546 {
    547 	std::vector<deUint32>	offsetMultiples;
    548 	deUint32				textureSize = 0;
    549 
    550 	offsetMultiples.push_back(4);
    551 	offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
    552 
    553 	for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
    554 	{
    555 		for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
    556 		{
    557 			const tcu::ConstPixelBufferAccess level = getLevel(levelNdx, layerNdx);
    558 			textureSize = getNextMultiple(offsetMultiples, textureSize);
    559 			textureSize += level.getWidth() * level.getHeight() * level.getDepth() * level.getFormat().getPixelSize();
    560 		}
    561 	}
    562 
    563 	return textureSize;
    564 }
    565 
    566 deUint32 TestTexture::getCompressedSize (void) const
    567 {
    568 	if (!isCompressed())
    569 		throw tcu::InternalError("Texture is not compressed");
    570 
    571 	std::vector<deUint32>	offsetMultiples;
    572 	deUint32				textureSize			= 0;
    573 
    574 	offsetMultiples.push_back(4);
    575 	offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
    576 
    577 	for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
    578 	{
    579 		for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
    580 		{
    581 			textureSize = getNextMultiple(offsetMultiples, textureSize);
    582 			textureSize += getCompressedLevel(levelNdx, layerNdx).getDataSize();
    583 		}
    584 	}
    585 
    586 	return textureSize;
    587 }
    588 
    589 tcu::CompressedTexture& TestTexture::getCompressedLevel (int level, int layer)
    590 {
    591 	DE_ASSERT(level >= 0 && level < getNumLevels());
    592 	DE_ASSERT(layer >= 0 && layer < getArraySize());
    593 
    594 	return *m_compressedLevels[level * getArraySize() + layer];
    595 }
    596 
    597 const tcu::CompressedTexture& TestTexture::getCompressedLevel (int level, int layer) const
    598 {
    599 	DE_ASSERT(level >= 0 && level < getNumLevels());
    600 	DE_ASSERT(layer >= 0 && layer < getArraySize());
    601 
    602 	return *m_compressedLevels[level * getArraySize() + layer];
    603 }
    604 
    605 std::vector<VkBufferImageCopy> TestTexture::getBufferCopyRegions (void) const
    606 {
    607 	std::vector<deUint32>			offsetMultiples;
    608 	std::vector<VkBufferImageCopy>	regions;
    609 	deUint32						layerDataOffset	= 0;
    610 
    611 	offsetMultiples.push_back(4);
    612 
    613 	if (isCompressed())
    614 	{
    615 		offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
    616 
    617 		for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
    618 		{
    619 			for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
    620 			{
    621 				const tcu::CompressedTexture& level = getCompressedLevel(levelNdx, layerNdx);
    622 				tcu::IVec3 blockPixelSize			= getBlockPixelSize(level.getFormat());
    623 				layerDataOffset						= getNextMultiple(offsetMultiples, layerDataOffset);
    624 
    625 				const VkBufferImageCopy layerRegion =
    626 				{
    627 					layerDataOffset,													// VkDeviceSize				bufferOffset;
    628 					(deUint32)getNextMultiple(blockPixelSize.x(), level.getWidth()),	// deUint32					bufferRowLength;
    629 					(deUint32)getNextMultiple(blockPixelSize.y(), level.getHeight()),	// deUint32					bufferImageHeight;
    630 					{																	// VkImageSubresourceLayers	imageSubresource;
    631 						VK_IMAGE_ASPECT_COLOR_BIT,
    632 						(deUint32)levelNdx,
    633 						(deUint32)layerNdx,
    634 						1u
    635 					},
    636 					{ 0u, 0u, 0u },							// VkOffset3D				imageOffset;
    637 					{										// VkExtent3D				imageExtent;
    638 						(deUint32)level.getWidth(),
    639 						(deUint32)level.getHeight(),
    640 						(deUint32)level.getDepth()
    641 					}
    642 				};
    643 
    644 				regions.push_back(layerRegion);
    645 				layerDataOffset += level.getDataSize();
    646 			}
    647 		}
    648 	}
    649 	else
    650 	{
    651 		offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
    652 
    653 		for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
    654 		{
    655 			for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
    656 			{
    657 				const tcu::ConstPixelBufferAccess level = getLevel(levelNdx, layerNdx);
    658 
    659 				layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset);
    660 
    661 				const VkBufferImageCopy layerRegion =
    662 				{
    663 					layerDataOffset,						// VkDeviceSize				bufferOffset;
    664 					(deUint32)level.getWidth(),				// deUint32					bufferRowLength;
    665 					(deUint32)level.getHeight(),			// deUint32					bufferImageHeight;
    666 					{										// VkImageSubresourceLayers	imageSubresource;
    667 						VK_IMAGE_ASPECT_COLOR_BIT,
    668 						(deUint32)levelNdx,
    669 						(deUint32)layerNdx,
    670 						1u
    671 					},
    672 					{ 0u, 0u, 0u },							// VkOffset3D			imageOffset;
    673 					{										// VkExtent3D			imageExtent;
    674 						(deUint32)level.getWidth(),
    675 						(deUint32)level.getHeight(),
    676 						(deUint32)level.getDepth()
    677 					}
    678 				};
    679 
    680 				regions.push_back(layerRegion);
    681 				layerDataOffset += level.getWidth() * level.getHeight() * level.getDepth() * level.getFormat().getPixelSize();
    682 			}
    683 		}
    684 	}
    685 
    686 	return regions;
    687 }
    688 
    689 void TestTexture::write (deUint8* destPtr) const
    690 {
    691 	std::vector<deUint32>	offsetMultiples;
    692 	deUint32				levelOffset		= 0;
    693 
    694 	offsetMultiples.push_back(4);
    695 
    696 	if (isCompressed())
    697 	{
    698 		offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
    699 
    700 		for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
    701 		{
    702 			for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
    703 			{
    704 				levelOffset = getNextMultiple(offsetMultiples, levelOffset);
    705 
    706 				const tcu::CompressedTexture&		compressedTex	= getCompressedLevel(levelNdx, layerNdx);
    707 
    708 				deMemcpy(destPtr + levelOffset, compressedTex.getData(), compressedTex.getDataSize());
    709 				levelOffset += compressedTex.getDataSize();
    710 			}
    711 		}
    712 	}
    713 	else
    714 	{
    715 		offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
    716 
    717 		for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
    718 		{
    719 			for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
    720 			{
    721 				levelOffset = getNextMultiple(offsetMultiples, levelOffset);
    722 
    723 				const tcu::ConstPixelBufferAccess	srcAccess		= getLevel(levelNdx, layerNdx);
    724 				const tcu::PixelBufferAccess		destAccess		(srcAccess.getFormat(), srcAccess.getSize(), srcAccess.getPitch(), destPtr + levelOffset);
    725 
    726 				tcu::copy(destAccess, srcAccess);
    727 				levelOffset += srcAccess.getWidth() * srcAccess.getHeight() * srcAccess.getDepth() * srcAccess.getFormat().getPixelSize();
    728 			}
    729 		}
    730 	}
    731 }
    732 
    733 void TestTexture::populateLevels (const std::vector<tcu::PixelBufferAccess>& levels)
    734 {
    735 	for (size_t levelNdx = 0; levelNdx < levels.size(); levelNdx++)
    736 		TestTexture::fillWithGradient(levels[levelNdx]);
    737 }
    738 
    739 void TestTexture::populateCompressedLevels (tcu::CompressedTexFormat format, const std::vector<tcu::PixelBufferAccess>& decompressedLevels)
    740 {
    741 	// Generate random compressed data and update decompressed data
    742 
    743 	de::Random random(123);
    744 
    745 	for (size_t levelNdx = 0; levelNdx < decompressedLevels.size(); levelNdx++)
    746 	{
    747 		const tcu::PixelBufferAccess	level				= decompressedLevels[levelNdx];
    748 		tcu::CompressedTexture*			compressedLevel		= new tcu::CompressedTexture(format, level.getWidth(), level.getHeight(), level.getDepth());
    749 		deUint8* const					compressedData		= (deUint8*)compressedLevel->getData();
    750 
    751 		if (tcu::isAstcFormat(format))
    752 		{
    753 			// \todo [2016-01-20 pyry] Comparison doesn't currently handle invalid blocks correctly so we use only valid blocks
    754 			tcu::astc::generateRandomValidBlocks(compressedData, compressedLevel->getDataSize()/tcu::astc::BLOCK_SIZE_BYTES,
    755 												 format, tcu::TexDecompressionParams::ASTCMODE_LDR, random.getUint32());
    756 		}
    757 		else
    758 		{
    759 			// Generate random compressed data
    760 			for (int byteNdx = 0; byteNdx < compressedLevel->getDataSize(); byteNdx++)
    761 				compressedData[byteNdx] = 0xFF & random.getUint32();
    762 		}
    763 
    764 		m_compressedLevels.push_back(compressedLevel);
    765 
    766 		// Store decompressed data
    767 		compressedLevel->decompress(level, tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR));
    768 	}
    769 }
    770 
    771 void TestTexture::fillWithGradient (const tcu::PixelBufferAccess& levelAccess)
    772 {
    773 	const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(levelAccess.getFormat());
    774 	tcu::fillWithComponentGradients(levelAccess, formatInfo.valueMin, formatInfo.valueMax);
    775 }
    776 
    777 // TestTexture1D
    778 
    779 TestTexture1D::TestTexture1D (const tcu::TextureFormat& format, int width)
    780 	: TestTexture	(format, width, 1, 1)
    781 	, m_texture		(format, width)
    782 {
    783 	allocateLevels(m_texture);
    784 	TestTexture::populateLevels(getLevelsVector(m_texture));
    785 }
    786 
    787 TestTexture1D::TestTexture1D (const tcu::CompressedTexFormat& format, int width)
    788 	: TestTexture	(format, width, 1, 1)
    789 	, m_texture		(tcu::getUncompressedFormat(format), width)
    790 {
    791 	allocateLevels(m_texture);
    792 	TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
    793 }
    794 
    795 TestTexture1D::~TestTexture1D (void)
    796 {
    797 }
    798 
    799 int TestTexture1D::getNumLevels (void) const
    800 {
    801 	return m_texture.getNumLevels();
    802 }
    803 
    804 tcu::PixelBufferAccess TestTexture1D::getLevel (int level, int layer)
    805 {
    806 	DE_ASSERT(layer == 0);
    807 	DE_UNREF(layer);
    808 	return m_texture.getLevel(level);
    809 }
    810 
    811 const tcu::ConstPixelBufferAccess TestTexture1D::getLevel (int level, int layer) const
    812 {
    813 	DE_ASSERT(layer == 0);
    814 	DE_UNREF(layer);
    815 	return m_texture.getLevel(level);
    816 }
    817 
    818 const tcu::Texture1D& TestTexture1D::getTexture (void) const
    819 {
    820 	return m_texture;
    821 }
    822 
    823 
    824 // TestTexture1DArray
    825 
    826 TestTexture1DArray::TestTexture1DArray (const tcu::TextureFormat& format, int width, int arraySize)
    827 	: TestTexture	(format, width, 1, arraySize)
    828 	, m_texture		(format, width, arraySize)
    829 {
    830 	allocateLevels(m_texture);
    831 	TestTexture::populateLevels(getLevelsVector(m_texture));
    832 }
    833 
    834 TestTexture1DArray::TestTexture1DArray (const tcu::CompressedTexFormat& format, int width, int arraySize)
    835 	: TestTexture	(format, width, 1, arraySize)
    836 	, m_texture		(tcu::getUncompressedFormat(format), width, arraySize)
    837 {
    838 	allocateLevels(m_texture);
    839 
    840 	std::vector<tcu::PixelBufferAccess> layers;
    841 	for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
    842 		for (int layerNdx = 0; layerNdx < m_texture.getNumLayers(); layerNdx++)
    843 			layers.push_back(getLevel(levelNdx, layerNdx));
    844 
    845 	TestTexture::populateCompressedLevels(format, layers);
    846 }
    847 
    848 TestTexture1DArray::~TestTexture1DArray (void)
    849 {
    850 }
    851 
    852 int TestTexture1DArray::getNumLevels (void) const
    853 {
    854 	return m_texture.getNumLevels();
    855 }
    856 
    857 tcu::PixelBufferAccess TestTexture1DArray::getLevel (int level, int layer)
    858 {
    859 	const tcu::PixelBufferAccess	levelLayers	= m_texture.getLevel(level);
    860 	const deUint32					layerSize	= levelLayers.getWidth() * levelLayers.getFormat().getPixelSize();
    861 	const deUint32					layerOffset	= layerSize * layer;
    862 
    863 	return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
    864 }
    865 
    866 const tcu::ConstPixelBufferAccess TestTexture1DArray::getLevel (int level, int layer) const
    867 {
    868 	const tcu::ConstPixelBufferAccess	levelLayers	= m_texture.getLevel(level);
    869 	const deUint32						layerSize	= levelLayers.getWidth() * levelLayers.getFormat().getPixelSize();
    870 	const deUint32						layerOffset	= layerSize * layer;
    871 
    872 	return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
    873 }
    874 
    875 const tcu::Texture1DArray& TestTexture1DArray::getTexture (void) const
    876 {
    877 	return m_texture;
    878 }
    879 
    880 int TestTexture1DArray::getArraySize (void) const
    881 {
    882 	return m_texture.getNumLayers();
    883 }
    884 
    885 
    886 // TestTexture2D
    887 
    888 TestTexture2D::TestTexture2D (const tcu::TextureFormat& format, int width, int height)
    889 	: TestTexture	(format, width, height, 1)
    890 	, m_texture		(format, width, height)
    891 {
    892 	allocateLevels(m_texture);
    893 	TestTexture::populateLevels(getLevelsVector(m_texture));
    894 }
    895 
    896 TestTexture2D::TestTexture2D (const tcu::CompressedTexFormat& format, int width, int height)
    897 	: TestTexture	(format, width, height, 1)
    898 	, m_texture		(tcu::getUncompressedFormat(format), width, height)
    899 {
    900 	allocateLevels(m_texture);
    901 	TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
    902 }
    903 
    904 TestTexture2D::~TestTexture2D (void)
    905 {
    906 }
    907 
    908 int TestTexture2D::getNumLevels (void) const
    909 {
    910 	return m_texture.getNumLevels();
    911 }
    912 
    913 tcu::PixelBufferAccess TestTexture2D::getLevel (int level, int layer)
    914 {
    915 	DE_ASSERT(layer == 0);
    916 	DE_UNREF(layer);
    917 	return m_texture.getLevel(level);
    918 }
    919 
    920 const tcu::ConstPixelBufferAccess TestTexture2D::getLevel (int level, int layer) const
    921 {
    922 	DE_ASSERT(layer == 0);
    923 	DE_UNREF(layer);
    924 	return m_texture.getLevel(level);
    925 }
    926 
    927 const tcu::Texture2D& TestTexture2D::getTexture (void) const
    928 {
    929 	return m_texture;
    930 }
    931 
    932 
    933 // TestTexture2DArray
    934 
    935 TestTexture2DArray::TestTexture2DArray (const tcu::TextureFormat& format, int width, int height, int arraySize)
    936 	: TestTexture	(format, width, height, arraySize)
    937 	, m_texture		(format, width, height, arraySize)
    938 {
    939 	allocateLevels(m_texture);
    940 	TestTexture::populateLevels(getLevelsVector(m_texture));
    941 }
    942 
    943 TestTexture2DArray::TestTexture2DArray (const tcu::CompressedTexFormat& format, int width, int height, int arraySize)
    944 	: TestTexture	(format, width, height, arraySize)
    945 	, m_texture		(tcu::getUncompressedFormat(format), width, height, arraySize)
    946 {
    947 	allocateLevels(m_texture);
    948 
    949 	std::vector<tcu::PixelBufferAccess> layers;
    950 	for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
    951 		for (int layerNdx = 0; layerNdx < m_texture.getNumLayers(); layerNdx++)
    952 			layers.push_back(getLevel(levelNdx, layerNdx));
    953 
    954 	TestTexture::populateCompressedLevels(format, layers);
    955 }
    956 
    957 TestTexture2DArray::~TestTexture2DArray (void)
    958 {
    959 }
    960 
    961 int TestTexture2DArray::getNumLevels (void) const
    962 {
    963 	return m_texture.getNumLevels();
    964 }
    965 
    966 tcu::PixelBufferAccess TestTexture2DArray::getLevel (int level, int layer)
    967 {
    968 	const tcu::PixelBufferAccess	levelLayers	= m_texture.getLevel(level);
    969 	const deUint32					layerSize	= levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
    970 	const deUint32					layerOffset	= layerSize * layer;
    971 
    972 	return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
    973 }
    974 
    975 const tcu::ConstPixelBufferAccess TestTexture2DArray::getLevel (int level, int layer) const
    976 {
    977 	const tcu::ConstPixelBufferAccess	levelLayers	= m_texture.getLevel(level);
    978 	const deUint32						layerSize	= levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
    979 	const deUint32						layerOffset	= layerSize * layer;
    980 
    981 	return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
    982 }
    983 
    984 const tcu::Texture2DArray& TestTexture2DArray::getTexture (void) const
    985 {
    986 	return m_texture;
    987 }
    988 
    989 int TestTexture2DArray::getArraySize (void) const
    990 {
    991 	return m_texture.getNumLayers();
    992 }
    993 
    994 
    995 // TestTexture3D
    996 
    997 TestTexture3D::TestTexture3D (const tcu::TextureFormat& format, int width, int height, int depth)
    998 	: TestTexture	(format, width, height, depth)
    999 	, m_texture		(format, width, height, depth)
   1000 {
   1001 	allocateLevels(m_texture);
   1002 	TestTexture::populateLevels(getLevelsVector(m_texture));
   1003 }
   1004 
   1005 TestTexture3D::TestTexture3D (const tcu::CompressedTexFormat& format, int width, int height, int depth)
   1006 	: TestTexture	(format, width, height, depth)
   1007 	, m_texture		(tcu::getUncompressedFormat(format), width, height, depth)
   1008 {
   1009 	allocateLevels(m_texture);
   1010 	TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
   1011 }
   1012 
   1013 TestTexture3D::~TestTexture3D (void)
   1014 {
   1015 }
   1016 
   1017 int TestTexture3D::getNumLevels (void) const
   1018 {
   1019 	return m_texture.getNumLevels();
   1020 }
   1021 
   1022 tcu::PixelBufferAccess TestTexture3D::getLevel (int level, int layer)
   1023 {
   1024 	DE_ASSERT(layer == 0);
   1025 	DE_UNREF(layer);
   1026 	return m_texture.getLevel(level);
   1027 }
   1028 
   1029 const tcu::ConstPixelBufferAccess TestTexture3D::getLevel (int level, int layer) const
   1030 {
   1031 	DE_ASSERT(layer == 0);
   1032 	DE_UNREF(layer);
   1033 	return m_texture.getLevel(level);
   1034 }
   1035 
   1036 const tcu::Texture3D& TestTexture3D::getTexture (void) const
   1037 {
   1038 	return m_texture;
   1039 }
   1040 
   1041 
   1042 // TestTextureCube
   1043 
   1044 const static tcu::CubeFace tcuFaceMapping[tcu::CUBEFACE_LAST] =
   1045 {
   1046 	tcu::CUBEFACE_POSITIVE_X,
   1047 	tcu::CUBEFACE_NEGATIVE_X,
   1048 	tcu::CUBEFACE_POSITIVE_Y,
   1049 	tcu::CUBEFACE_NEGATIVE_Y,
   1050 	tcu::CUBEFACE_POSITIVE_Z,
   1051 	tcu::CUBEFACE_NEGATIVE_Z
   1052 };
   1053 
   1054 TestTextureCube::TestTextureCube (const tcu::TextureFormat& format, int size)
   1055 	: TestTexture	(format, size, size, 1)
   1056 	, m_texture		(format, size)
   1057 {
   1058 	for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
   1059 	{
   1060 		for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
   1061 		{
   1062 			m_texture.allocLevel(tcuFaceMapping[faceNdx], levelNdx);
   1063 			TestTexture::fillWithGradient(m_texture.getLevelFace(levelNdx, tcuFaceMapping[faceNdx]));
   1064 		}
   1065 	}
   1066 }
   1067 
   1068 TestTextureCube::TestTextureCube (const tcu::CompressedTexFormat& format, int size)
   1069 	: TestTexture	(format, size, size, 1)
   1070 	, m_texture		(tcu::getUncompressedFormat(format), size)
   1071 {
   1072 	std::vector<tcu::PixelBufferAccess> levels(m_texture.getNumLevels() * tcu::CUBEFACE_LAST);
   1073 
   1074 	for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
   1075 	{
   1076 		for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
   1077 		{
   1078 			m_texture.allocLevel(tcuFaceMapping[faceNdx], levelNdx);
   1079 			levels[levelNdx * tcu::CUBEFACE_LAST + faceNdx] = m_texture.getLevelFace(levelNdx, tcuFaceMapping[faceNdx]);
   1080 		}
   1081 	}
   1082 
   1083 	TestTexture::populateCompressedLevels(format, levels);
   1084 }
   1085 
   1086 TestTextureCube::~TestTextureCube (void)
   1087 {
   1088 }
   1089 
   1090 int TestTextureCube::getNumLevels (void) const
   1091 {
   1092 	return m_texture.getNumLevels();
   1093 }
   1094 
   1095 tcu::PixelBufferAccess TestTextureCube::getLevel (int level, int face)
   1096 {
   1097 	return m_texture.getLevelFace(level, (tcu::CubeFace)face);
   1098 }
   1099 
   1100 const tcu::ConstPixelBufferAccess TestTextureCube::getLevel (int level, int face) const
   1101 {
   1102 	return m_texture.getLevelFace(level, (tcu::CubeFace)face);
   1103 }
   1104 
   1105 int TestTextureCube::getArraySize (void) const
   1106 {
   1107 	return (int)tcu::CUBEFACE_LAST;
   1108 }
   1109 
   1110 const tcu::TextureCube& TestTextureCube::getTexture (void) const
   1111 {
   1112 	return m_texture;
   1113 }
   1114 
   1115 // TestTextureCubeArray
   1116 
   1117 TestTextureCubeArray::TestTextureCubeArray (const tcu::TextureFormat& format, int size, int arraySize)
   1118 	: TestTexture	(format, size, size, arraySize)
   1119 	, m_texture		(format, size, arraySize)
   1120 {
   1121 	allocateLevels(m_texture);
   1122 	TestTexture::populateLevels(getLevelsVector(m_texture));
   1123 }
   1124 
   1125 TestTextureCubeArray::TestTextureCubeArray (const tcu::CompressedTexFormat& format, int size, int arraySize)
   1126 	: TestTexture	(format, size, size, arraySize)
   1127 	, m_texture		(tcu::getUncompressedFormat(format), size, arraySize)
   1128 {
   1129 	DE_ASSERT(arraySize % 6 == 0);
   1130 
   1131 	allocateLevels(m_texture);
   1132 
   1133 	std::vector<tcu::PixelBufferAccess> layers;
   1134 	for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
   1135 		for (int layerNdx = 0; layerNdx < m_texture.getDepth(); layerNdx++)
   1136 			layers.push_back(getLevel(levelNdx, layerNdx));
   1137 
   1138 	TestTexture::populateCompressedLevels(format, layers);
   1139 }
   1140 
   1141 TestTextureCubeArray::~TestTextureCubeArray (void)
   1142 {
   1143 }
   1144 
   1145 int TestTextureCubeArray::getNumLevels (void) const
   1146 {
   1147 	return m_texture.getNumLevels();
   1148 }
   1149 
   1150 tcu::PixelBufferAccess TestTextureCubeArray::getLevel (int level, int layer)
   1151 {
   1152 	const tcu::PixelBufferAccess	levelLayers	= m_texture.getLevel(level);
   1153 	const deUint32					layerSize	= levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
   1154 	const deUint32					layerOffset	= layerSize * layer;
   1155 
   1156 	return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
   1157 }
   1158 
   1159 const tcu::ConstPixelBufferAccess TestTextureCubeArray::getLevel (int level, int layer) const
   1160 {
   1161 	const tcu::ConstPixelBufferAccess	levelLayers	= m_texture.getLevel(level);
   1162 	const deUint32						layerSize	= levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
   1163 	const deUint32						layerOffset	= layerSize * layer;
   1164 
   1165 	return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
   1166 }
   1167 
   1168 int TestTextureCubeArray::getArraySize (void) const
   1169 {
   1170 	return m_texture.getDepth();
   1171 }
   1172 
   1173 const tcu::TextureCubeArray& TestTextureCubeArray::getTexture (void) const
   1174 {
   1175 	return m_texture;
   1176 }
   1177 
   1178 } // pipeline
   1179 } // vkt
   1180