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 "vkCmdUtil.hpp"
31 #include "vkTypeUtil.hpp"
32 #include "tcuTextureUtil.hpp"
33 #include "tcuAstcUtil.hpp"
34 #include "deRandom.hpp"
35 #include "deSharedPtr.hpp"
36 
37 namespace vkt
38 {
39 namespace pipeline
40 {
41 
42 using namespace vk;
43 
44 /*! Gets the next multiple of a given divisor */
getNextMultiple(deUint32 divisor,deUint32 value)45 static deUint32 getNextMultiple (deUint32 divisor, deUint32 value)
46 {
47 	if (value % divisor == 0)
48 	{
49 		return value;
50 	}
51 	return value + divisor - (value % divisor);
52 }
53 
54 /*! Gets the next value that is multiple of all given divisors */
getNextMultiple(const std::vector<deUint32> & divisors,deUint32 value)55 static deUint32 getNextMultiple (const std::vector<deUint32>& divisors, deUint32 value)
56 {
57 	deUint32	nextMultiple		= value;
58 	bool		nextMultipleFound	= false;
59 
60 	while (true)
61 	{
62 		nextMultipleFound = true;
63 
64 		for (size_t divNdx = 0; divNdx < divisors.size(); divNdx++)
65 			nextMultipleFound = nextMultipleFound && (nextMultiple % divisors[divNdx] == 0);
66 
67 		if (nextMultipleFound)
68 			break;
69 
70 		DE_ASSERT(nextMultiple < ~((deUint32)0u));
71 		nextMultiple = getNextMultiple(divisors[0], nextMultiple + 1);
72 	}
73 
74 	return nextMultiple;
75 }
76 
isSupportedSamplableFormat(const InstanceInterface & instanceInterface,VkPhysicalDevice device,VkFormat format)77 bool isSupportedSamplableFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format)
78 {
79 	if (isCompressedFormat(format))
80 	{
81 		VkPhysicalDeviceFeatures		physicalFeatures;
82 		const tcu::CompressedTexFormat	compressedFormat	= mapVkCompressedFormat(format);
83 
84 		instanceInterface.getPhysicalDeviceFeatures(device, &physicalFeatures);
85 
86 		if (tcu::isAstcFormat(compressedFormat))
87 		{
88 			if (!physicalFeatures.textureCompressionASTC_LDR)
89 				return false;
90 		}
91 		else if (tcu::isEtcFormat(compressedFormat))
92 		{
93 			if (!physicalFeatures.textureCompressionETC2)
94 				return false;
95 		}
96 		else
97 		{
98 			DE_FATAL("Unsupported compressed format");
99 		}
100 	}
101 
102 	VkFormatProperties	formatProps;
103 	instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps);
104 
105 	return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0u;
106 }
107 
isLinearFilteringSupported(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,VkFormat format,VkImageTiling tiling)108 bool isLinearFilteringSupported (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkFormat format, VkImageTiling tiling)
109 {
110 	const VkFormatProperties	formatProperties	= getPhysicalDeviceFormatProperties(vki, physicalDevice, format);
111 	const VkFormatFeatureFlags	formatFeatures		= tiling == VK_IMAGE_TILING_LINEAR
112 													? formatProperties.linearTilingFeatures
113 													: formatProperties.optimalTilingFeatures;
114 
115 	return (formatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) != 0;
116 }
117 
isMinMaxFilteringSupported(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,VkFormat format,VkImageTiling tiling)118 bool isMinMaxFilteringSupported (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkFormat format, VkImageTiling tiling)
119 {
120 	const VkFormatProperties	formatProperties	= getPhysicalDeviceFormatProperties(vki, physicalDevice, format);
121 	const VkFormatFeatureFlags	formatFeatures		= tiling == VK_IMAGE_TILING_LINEAR
122 													? formatProperties.linearTilingFeatures
123 													: formatProperties.optimalTilingFeatures;
124 
125 	return (formatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT) != 0;
126 }
127 
getFormatBorderColor(BorderColor color,VkFormat format)128 VkBorderColor getFormatBorderColor (BorderColor color, VkFormat format)
129 {
130 	if (!isCompressedFormat(format) && (isIntFormat(format) || isUintFormat(format)))
131 	{
132 		switch (color)
133 		{
134 			case BORDER_COLOR_OPAQUE_BLACK:			return VK_BORDER_COLOR_INT_OPAQUE_BLACK;
135 			case BORDER_COLOR_OPAQUE_WHITE:			return VK_BORDER_COLOR_INT_OPAQUE_WHITE;
136 			case BORDER_COLOR_TRANSPARENT_BLACK:	return VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
137 			case BORDER_COLOR_CUSTOM:				return VK_BORDER_COLOR_INT_CUSTOM_EXT;
138 			default:
139 				break;
140 		}
141 	}
142 	else
143 	{
144 		switch (color)
145 		{
146 			case BORDER_COLOR_OPAQUE_BLACK:			return VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
147 			case BORDER_COLOR_OPAQUE_WHITE:			return VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
148 			case BORDER_COLOR_TRANSPARENT_BLACK:	return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
149 			case BORDER_COLOR_CUSTOM:				return VK_BORDER_COLOR_FLOAT_CUSTOM_EXT;
150 			default:
151 				break;
152 		}
153 	}
154 
155 	DE_ASSERT(false);
156 	return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
157 }
158 
getFormatCustomBorderColor(tcu::Vec4 floatValue,tcu::IVec4 intValue,vk::VkFormat format)159 rr::GenericVec4 getFormatCustomBorderColor	(tcu::Vec4 floatValue, tcu::IVec4 intValue, vk::VkFormat format)
160 {
161 	if (!isCompressedFormat(format) && (isIntFormat(format) || isUintFormat(format)))
162 	{
163 		return rr::GenericVec4(intValue);
164 	}
165 	else
166 	{
167 		return rr::GenericVec4(floatValue);
168 	}
169 }
170 
getLookupScaleBias(vk::VkFormat format,tcu::Vec4 & lookupScale,tcu::Vec4 & lookupBias)171 void getLookupScaleBias (vk::VkFormat format, tcu::Vec4& lookupScale, tcu::Vec4& lookupBias)
172 {
173 	if (!isCompressedFormat(format))
174 	{
175 		const tcu::TextureFormatInfo	fmtInfo	= tcu::getTextureFormatInfo(mapVkFormat(format));
176 
177 		// Needed to normalize various formats to 0..1 range for writing into RT
178 		lookupScale	= fmtInfo.lookupScale;
179 		lookupBias	= fmtInfo.lookupBias;
180 	}
181 	else
182 	{
183 		switch (format)
184 		{
185 			case VK_FORMAT_EAC_R11_SNORM_BLOCK:
186 				lookupScale	= tcu::Vec4(0.5f, 1.0f, 1.0f, 1.0f);
187 				lookupBias	= tcu::Vec4(0.5f, 0.0f, 0.0f, 0.0f);
188 				break;
189 
190 			case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
191 				lookupScale	= tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f);
192 				lookupBias	= tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f);
193 				break;
194 
195 			default:
196 				// else: All supported compressed formats are fine with no normalization.
197 				//		 ASTC LDR blocks decompress to f16 so querying normalization parameters
198 				//		 based on uncompressed formats would actually lead to massive precision loss
199 				//		 and complete lack of coverage in case of R8G8B8A8_UNORM RT.
200 				lookupScale	= tcu::Vec4(1.0f);
201 				lookupBias	= tcu::Vec4(0.0f);
202 				break;
203 		}
204 	}
205 }
206 
readColorAttachment(const vk::DeviceInterface & vk,vk::VkDevice device,vk::VkQueue queue,deUint32 queueFamilyIndex,vk::Allocator & allocator,vk::VkImage image,vk::VkFormat format,const tcu::UVec2 & renderSize)207 de::MovePtr<tcu::TextureLevel> readColorAttachment (const vk::DeviceInterface&	vk,
208 													vk::VkDevice				device,
209 													vk::VkQueue					queue,
210 													deUint32					queueFamilyIndex,
211 													vk::Allocator&				allocator,
212 													vk::VkImage					image,
213 													vk::VkFormat				format,
214 													const tcu::UVec2&			renderSize)
215 {
216 	Move<VkBuffer>					buffer;
217 	de::MovePtr<Allocation>			bufferAlloc;
218 	Move<VkCommandPool>				cmdPool;
219 	Move<VkCommandBuffer>			cmdBuffer;
220 	Move<VkFence>					fence;
221 	const tcu::TextureFormat		tcuFormat		= mapVkFormat(format);
222 	const VkDeviceSize				pixelDataSize	= renderSize.x() * renderSize.y() * tcuFormat.getPixelSize();
223 	de::MovePtr<tcu::TextureLevel>	resultLevel		(new tcu::TextureLevel(tcuFormat, renderSize.x(), renderSize.y()));
224 
225 	// Create destination buffer
226 	{
227 		const VkBufferCreateInfo bufferParams =
228 		{
229 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
230 			DE_NULL,									// const void*			pNext;
231 			0u,											// VkBufferCreateFlags	flags;
232 			pixelDataSize,								// VkDeviceSize			size;
233 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
234 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
235 			0u,											// deUint32				queueFamilyIndexCount;
236 			DE_NULL										// const deUint32*		pQueueFamilyIndices;
237 		};
238 
239 		buffer		= createBuffer(vk, device, &bufferParams);
240 		bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
241 		VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
242 	}
243 
244 	// Create command pool and buffer
245 	cmdPool		= createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
246 	cmdBuffer	= allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
247 
248 	// Create fence
249 	fence = createFence(vk, device);
250 
251 	beginCommandBuffer(vk, *cmdBuffer);
252 	copyImageToBuffer(vk, *cmdBuffer, image, *buffer, tcu::IVec2(renderSize.x(), renderSize.y()));
253 	endCommandBuffer(vk, *cmdBuffer);
254 
255 	submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
256 
257 	// Read buffer data
258 	invalidateAlloc(vk, device, *bufferAlloc);
259 	tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), bufferAlloc->getHostPtr()));
260 
261 	return resultLevel;
262 }
263 
readDepthAttachment(const vk::DeviceInterface & vk,vk::VkDevice device,vk::VkQueue queue,deUint32 queueFamilyIndex,vk::Allocator & allocator,vk::VkImage image,vk::VkFormat format,const tcu::UVec2 & renderSize,vk::VkImageLayout currentLayout)264 de::MovePtr<tcu::TextureLevel> readDepthAttachment (const vk::DeviceInterface&	vk,
265 													vk::VkDevice				device,
266 													vk::VkQueue					queue,
267 													deUint32					queueFamilyIndex,
268 													vk::Allocator&				allocator,
269 													vk::VkImage					image,
270 													vk::VkFormat				format,
271 													const tcu::UVec2&			renderSize,
272 													vk::VkImageLayout			currentLayout)
273 {
274 	Move<VkBuffer>					buffer;
275 	de::MovePtr<Allocation>			bufferAlloc;
276 	Move<VkCommandPool>				cmdPool;
277 	Move<VkCommandBuffer>			cmdBuffer;
278 
279 	tcu::TextureFormat				retFormat		(tcu::TextureFormat::D, tcu::TextureFormat::CHANNELTYPE_LAST);
280 	tcu::TextureFormat				bufferFormat	(tcu::TextureFormat::D, tcu::TextureFormat::CHANNELTYPE_LAST);
281 	const VkImageAspectFlags		barrierAspect	= VK_IMAGE_ASPECT_DEPTH_BIT | (mapVkFormat(format).order == tcu::TextureFormat::DS ? VK_IMAGE_ASPECT_STENCIL_BIT : (VkImageAspectFlagBits)0);
282 
283 	switch (format)
284 	{
285 	case vk::VK_FORMAT_D16_UNORM:
286 	case vk::VK_FORMAT_D16_UNORM_S8_UINT:
287 		bufferFormat.type = retFormat.type = tcu::TextureFormat::UNORM_INT16;
288 		break;
289 	case vk::VK_FORMAT_D24_UNORM_S8_UINT:
290 	case vk::VK_FORMAT_X8_D24_UNORM_PACK32:
291 		retFormat.type = tcu::TextureFormat::UNORM_INT24;
292 		// vkCmdCopyBufferToImage copies D24 data to 32-bit pixels.
293 		bufferFormat.type = tcu::TextureFormat::UNSIGNED_INT_24_8_REV;
294 		break;
295 	case vk::VK_FORMAT_D32_SFLOAT:
296 	case vk::VK_FORMAT_D32_SFLOAT_S8_UINT:
297 		bufferFormat.type = retFormat.type = tcu::TextureFormat::FLOAT;
298 		break;
299 	default:
300 		TCU_FAIL("unrecognized format");
301 	}
302 
303 	const VkDeviceSize				pixelDataSize	= renderSize.x() * renderSize.y() * bufferFormat.getPixelSize();
304 	de::MovePtr<tcu::TextureLevel>	resultLevel		(new tcu::TextureLevel(retFormat, renderSize.x(), renderSize.y()));
305 
306 	// Create destination buffer
307 	{
308 		const VkBufferCreateInfo bufferParams =
309 		{
310 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
311 			DE_NULL,									// const void*			pNext;
312 			0u,											// VkBufferCreateFlags	flags;
313 			pixelDataSize,								// VkDeviceSize			size;
314 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
315 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
316 			0u,											// deUint32				queueFamilyIndexCount;
317 			DE_NULL										// const deUint32*		pQueueFamilyIndices;
318 		};
319 
320 		buffer		= createBuffer(vk, device, &bufferParams);
321 		bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
322 		VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
323 	}
324 
325 	// Create command pool and buffer
326 	cmdPool		= createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
327 	cmdBuffer	= allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
328 
329 	beginCommandBuffer(vk, *cmdBuffer);
330 	copyImageToBuffer(vk, *cmdBuffer, image, *buffer, tcu::IVec2(renderSize.x(), renderSize.y()), VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, currentLayout, 1u, barrierAspect, VK_IMAGE_ASPECT_DEPTH_BIT);
331 	endCommandBuffer(vk, *cmdBuffer);
332 
333 	submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
334 
335 	// Read buffer data
336 	invalidateAlloc(vk, device, *bufferAlloc);
337 	tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(bufferFormat, resultLevel->getSize(), bufferAlloc->getHostPtr()));
338 
339 	return resultLevel;
340 }
341 
readStencilAttachment(const vk::DeviceInterface & vk,vk::VkDevice device,vk::VkQueue queue,deUint32 queueFamilyIndex,vk::Allocator & allocator,vk::VkImage image,vk::VkFormat format,const tcu::UVec2 & renderSize,vk::VkImageLayout currentLayout)342 de::MovePtr<tcu::TextureLevel> readStencilAttachment (const vk::DeviceInterface&	vk,
343 													  vk::VkDevice					device,
344 													  vk::VkQueue					queue,
345 													  deUint32						queueFamilyIndex,
346 													  vk::Allocator&				allocator,
347 													  vk::VkImage					image,
348 													  vk::VkFormat					format,
349 													  const tcu::UVec2&				renderSize,
350 													  vk::VkImageLayout				currentLayout)
351 {
352 	Move<VkBuffer>					buffer;
353 	de::MovePtr<Allocation>			bufferAlloc;
354 	Move<VkCommandPool>				cmdPool;
355 	Move<VkCommandBuffer>			cmdBuffer;
356 
357 	tcu::TextureFormat				retFormat		(tcu::TextureFormat::S, tcu::TextureFormat::UNSIGNED_INT8);
358 	tcu::TextureFormat				bufferFormat	(tcu::TextureFormat::S, tcu::TextureFormat::UNSIGNED_INT8);
359 
360 	const VkImageAspectFlags		barrierAspect	= VK_IMAGE_ASPECT_STENCIL_BIT | (mapVkFormat(format).order == tcu::TextureFormat::DS ? VK_IMAGE_ASPECT_DEPTH_BIT : (VkImageAspectFlagBits)0);
361 	const VkDeviceSize				pixelDataSize	= renderSize.x() * renderSize.y() * bufferFormat.getPixelSize();
362 	de::MovePtr<tcu::TextureLevel>	resultLevel		(new tcu::TextureLevel(retFormat, renderSize.x(), renderSize.y()));
363 
364 	// Create destination buffer
365 	{
366 		const VkBufferCreateInfo bufferParams =
367 		{
368 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
369 			DE_NULL,									// const void*			pNext;
370 			0u,											// VkBufferCreateFlags	flags;
371 			pixelDataSize,								// VkDeviceSize			size;
372 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
373 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
374 			0u,											// deUint32				queueFamilyIndexCount;
375 			DE_NULL										// const deUint32*		pQueueFamilyIndices;
376 		};
377 
378 		buffer		= createBuffer(vk, device, &bufferParams);
379 		bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
380 		VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
381 	}
382 
383 	// Create command pool and buffer
384 	cmdPool		= createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
385 	cmdBuffer	= allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
386 
387 	beginCommandBuffer(vk, *cmdBuffer);
388 	copyImageToBuffer(vk, *cmdBuffer, image, *buffer, tcu::IVec2(renderSize.x(), renderSize.y()), VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, currentLayout, 1u, barrierAspect, VK_IMAGE_ASPECT_STENCIL_BIT);
389 	endCommandBuffer(vk, *cmdBuffer);
390 
391 	submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
392 
393 	// Read buffer data
394 	invalidateAlloc(vk, device, *bufferAlloc);
395 	tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(bufferFormat, resultLevel->getSize(), bufferAlloc->getHostPtr()));
396 
397 	return resultLevel;
398 }
399 
uploadTestTextureInternal(const DeviceInterface & vk,VkDevice device,VkQueue queue,deUint32 queueFamilyIndex,Allocator & allocator,const TestTexture & srcTexture,const TestTexture * srcStencilTexture,tcu::TextureFormat format,VkImage destImage)400 void uploadTestTextureInternal (const DeviceInterface&	vk,
401 								VkDevice				device,
402 								VkQueue					queue,
403 								deUint32				queueFamilyIndex,
404 								Allocator&				allocator,
405 								const TestTexture&		srcTexture,
406 								const TestTexture*		srcStencilTexture,
407 								tcu::TextureFormat		format,
408 								VkImage					destImage)
409 {
410 	Move<VkBuffer>					buffer;
411 	de::MovePtr<Allocation>			bufferAlloc;
412 	Move<VkCommandPool>				cmdPool;
413 	Move<VkCommandBuffer>			cmdBuffer;
414 	const VkImageAspectFlags		imageAspectFlags	= getImageAspectFlags(format);
415 	deUint32						stencilOffset		= 0u;
416 	std::vector<VkBufferImageCopy>	copyRegions			= srcTexture.getBufferCopyRegions();
417 	deUint32						bufferSize			= (srcTexture.isCompressed())? srcTexture.getCompressedSize(): srcTexture.getSize();
418 
419 	// Stencil-only texture should be provided if (and only if) the image has a combined DS format
420 	DE_ASSERT((tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order)) == (srcStencilTexture != DE_NULL));
421 
422 	if (srcStencilTexture != DE_NULL)
423 	{
424 		stencilOffset	= static_cast<deUint32>(deAlign32(static_cast<deInt32>(bufferSize), 4));
425 		bufferSize		= stencilOffset + srcStencilTexture->getSize();
426 	}
427 
428 	// Create source buffer
429 	{
430 		const VkBufferCreateInfo bufferParams =
431 		{
432 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType      sType;
433 			DE_NULL,								// const void*          pNext;
434 			0u,										// VkBufferCreateFlags  flags;
435 			bufferSize,								// VkDeviceSize         size;
436 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,		// VkBufferUsageFlags   usage;
437 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode        sharingMode;
438 			0u,										// deUint32             queueFamilyIndexCount;
439 			DE_NULL,								// const deUint32*      pQueueFamilyIndices;
440 		};
441 
442 		buffer		= createBuffer(vk, device, &bufferParams);
443 		bufferAlloc	= allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
444 		VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
445 	}
446 
447 	// Write buffer data
448 	{
449 		srcTexture.write(reinterpret_cast<deUint8*>(bufferAlloc->getHostPtr()));
450 
451 		if (srcStencilTexture != DE_NULL)
452 		{
453 			DE_ASSERT(stencilOffset != 0u);
454 
455 			srcStencilTexture->write(reinterpret_cast<deUint8*>(bufferAlloc->getHostPtr()) + stencilOffset);
456 
457 			std::vector<VkBufferImageCopy>	stencilCopyRegions = srcStencilTexture->getBufferCopyRegions();
458 			for (size_t regionIdx = 0; regionIdx < stencilCopyRegions.size(); regionIdx++)
459 			{
460 				VkBufferImageCopy region = stencilCopyRegions[regionIdx];
461 				region.bufferOffset += stencilOffset;
462 
463 				copyRegions.push_back(region);
464 			}
465 		}
466 
467 		flushAlloc(vk, device, *bufferAlloc);
468 	}
469 
470 	copyBufferToImage(vk, device, queue, queueFamilyIndex, *buffer, bufferSize, copyRegions, DE_NULL, imageAspectFlags, srcTexture.getNumLevels(), srcTexture.getArraySize(), destImage);
471 }
472 
checkSparseImageFormatSupport(const VkPhysicalDevice physicalDevice,const InstanceInterface & instance,const VkImageCreateInfo & imageCreateInfo)473 bool checkSparseImageFormatSupport (const VkPhysicalDevice		physicalDevice,
474 									const InstanceInterface&	instance,
475 									const VkImageCreateInfo&	imageCreateInfo)
476 {
477 	const std::vector<VkSparseImageFormatProperties> sparseImageFormatPropVec =
478 		getPhysicalDeviceSparseImageFormatProperties(instance, physicalDevice, imageCreateInfo.format, imageCreateInfo.imageType, imageCreateInfo.samples, imageCreateInfo.usage, imageCreateInfo.tiling);
479 
480 	return (sparseImageFormatPropVec.size() != 0);
481 }
482 
uploadTestTextureInternalSparse(const DeviceInterface & vk,VkDevice device,const VkPhysicalDevice physicalDevice,const InstanceInterface & instance,const VkImageCreateInfo & imageCreateInfo,VkQueue universalQueue,deUint32 universalQueueFamilyIndex,VkQueue sparseQueue,Allocator & allocator,std::vector<de::SharedPtr<Allocation>> & allocations,const TestTexture & srcTexture,const TestTexture * srcStencilTexture,tcu::TextureFormat format,VkImage destImage)483 void uploadTestTextureInternalSparse (const DeviceInterface&					vk,
484 									  VkDevice									device,
485 									  const VkPhysicalDevice					physicalDevice,
486 									  const InstanceInterface&					instance,
487 									  const VkImageCreateInfo&					imageCreateInfo,
488 									  VkQueue									universalQueue,
489 									  deUint32									universalQueueFamilyIndex,
490 									  VkQueue									sparseQueue,
491 									  Allocator&								allocator,
492 									  std::vector<de::SharedPtr<Allocation> >&	allocations,
493 									  const TestTexture&						srcTexture,
494 									  const TestTexture*						srcStencilTexture,
495 									  tcu::TextureFormat						format,
496 									  VkImage									destImage)
497 {
498 	deUint32						bufferSize				= (srcTexture.isCompressed()) ? srcTexture.getCompressedSize(): srcTexture.getSize();
499 	const VkImageAspectFlags		imageAspectFlags		= getImageAspectFlags(format);
500 	deUint32						stencilOffset			= 0u;
501 	const Unique<VkSemaphore>		imageMemoryBindSemaphore(createSemaphore(vk, device));
502 	Move<VkCommandPool>				cmdPool					= createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, universalQueueFamilyIndex);
503 	Move<VkCommandBuffer>			cmdBuffer				= allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
504 	Move<VkFence>					fence					= createFence(vk, device);
505 	std::vector<VkBufferImageCopy>	copyRegions				= srcTexture.getBufferCopyRegions();
506 	Move<VkBuffer>					buffer;
507 	de::MovePtr<Allocation>			bufferAlloc;
508 
509 	// Stencil-only texture should be provided if (and only if) the image has a combined DS format
510 	DE_ASSERT((tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order)) == (srcStencilTexture != DE_NULL));
511 
512 	if (srcStencilTexture != DE_NULL)
513 	{
514 		stencilOffset	= static_cast<deUint32>(deAlign32(static_cast<deInt32>(bufferSize), 4));
515 		bufferSize		= stencilOffset + srcStencilTexture->getSize();
516 	}
517 
518 	allocateAndBindSparseImage (vk, device, physicalDevice, instance, imageCreateInfo, imageMemoryBindSemaphore.get(), sparseQueue, allocator, allocations, format, destImage);
519 
520 	{
521 		// Create source buffer
522 		const VkBufferCreateInfo bufferParams =
523 		{
524 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
525 			DE_NULL,									// const void*			pNext;
526 			0u,											// VkBufferCreateFlags	flags;
527 			bufferSize,									// VkDeviceSize			size;
528 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
529 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
530 			0u,											// deUint32				queueFamilyIndexCount;
531 			DE_NULL,									// const deUint32*		pQueueFamilyIndices;
532 		};
533 
534 		buffer		= createBuffer(vk, device, &bufferParams);
535 		bufferAlloc	= allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
536 
537 		VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
538 	}
539 
540 	{
541 		// Write buffer data
542 		srcTexture.write(reinterpret_cast<deUint8*>(bufferAlloc->getHostPtr()));
543 
544 		if (srcStencilTexture != DE_NULL)
545 		{
546 			DE_ASSERT(stencilOffset != 0u);
547 
548 			srcStencilTexture->write(reinterpret_cast<deUint8*>(bufferAlloc->getHostPtr()) + stencilOffset);
549 
550 			std::vector<VkBufferImageCopy>	stencilCopyRegions = srcStencilTexture->getBufferCopyRegions();
551 			for (size_t regionIdx = 0; regionIdx < stencilCopyRegions.size(); regionIdx++)
552 			{
553 				VkBufferImageCopy region = stencilCopyRegions[regionIdx];
554 				region.bufferOffset += stencilOffset;
555 
556 				copyRegions.push_back(region);
557 			}
558 		}
559 
560 		flushAlloc(vk, device, *bufferAlloc);
561 	}
562 
563 	copyBufferToImage(vk, device, universalQueue, universalQueueFamilyIndex, *buffer, bufferSize, copyRegions, &(*imageMemoryBindSemaphore), imageAspectFlags, imageCreateInfo.mipLevels, imageCreateInfo.arrayLayers, destImage);
564 }
565 
uploadTestTexture(const DeviceInterface & vk,VkDevice device,VkQueue queue,deUint32 queueFamilyIndex,Allocator & allocator,const TestTexture & srcTexture,VkImage destImage)566 void uploadTestTexture (const DeviceInterface&			vk,
567 						VkDevice						device,
568 						VkQueue							queue,
569 						deUint32						queueFamilyIndex,
570 						Allocator&						allocator,
571 						const TestTexture&				srcTexture,
572 						VkImage							destImage)
573 {
574 	if (tcu::isCombinedDepthStencilType(srcTexture.getTextureFormat().type))
575 	{
576 		de::MovePtr<TestTexture> srcDepthTexture;
577 		de::MovePtr<TestTexture> srcStencilTexture;
578 
579 		if (tcu::hasDepthComponent(srcTexture.getTextureFormat().order))
580 		{
581 			tcu::TextureFormat format;
582 			switch (srcTexture.getTextureFormat().type)
583 			{
584 				case tcu::TextureFormat::UNSIGNED_INT_16_8_8:
585 					format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
586 					break;
587 				case tcu::TextureFormat::UNSIGNED_INT_24_8_REV:
588 					format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8_REV);
589 					break;
590 				case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
591 					format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
592 					break;
593 				default:
594 					DE_FATAL("Unexpected source texture format.");
595 					break;
596 			}
597 			srcDepthTexture = srcTexture.copy(format);
598 		}
599 
600 		if (tcu::hasStencilComponent(srcTexture.getTextureFormat().order))
601 			srcStencilTexture = srcTexture.copy(tcu::getEffectiveDepthStencilTextureFormat(srcTexture.getTextureFormat(), tcu::Sampler::MODE_STENCIL));
602 
603 		uploadTestTextureInternal(vk, device, queue, queueFamilyIndex, allocator, *srcDepthTexture, srcStencilTexture.get(), srcTexture.getTextureFormat(), destImage);
604 	}
605 	else
606 		uploadTestTextureInternal(vk, device, queue, queueFamilyIndex, allocator, srcTexture, DE_NULL, srcTexture.getTextureFormat(), destImage);
607 }
608 
uploadTestTextureSparse(const DeviceInterface & vk,VkDevice device,const VkPhysicalDevice physicalDevice,const InstanceInterface & instance,const VkImageCreateInfo & imageCreateInfo,VkQueue universalQueue,deUint32 universalQueueFamilyIndex,VkQueue sparseQueue,Allocator & allocator,std::vector<de::SharedPtr<Allocation>> & allocations,const TestTexture & srcTexture,VkImage destImage)609 void uploadTestTextureSparse (const DeviceInterface&					vk,
610 							  VkDevice									device,
611 							  const VkPhysicalDevice					physicalDevice,
612 							  const InstanceInterface&					instance,
613 							  const VkImageCreateInfo&					imageCreateInfo,
614 							  VkQueue									universalQueue,
615 							  deUint32									universalQueueFamilyIndex,
616 							  VkQueue									sparseQueue,
617 							  Allocator&								allocator,
618 							  std::vector<de::SharedPtr<Allocation> >&	allocations,
619 							  const TestTexture&						srcTexture,
620 							  VkImage									destImage)
621 {
622 	if (tcu::isCombinedDepthStencilType(srcTexture.getTextureFormat().type))
623 	{
624 		de::MovePtr<TestTexture> srcDepthTexture;
625 		de::MovePtr<TestTexture> srcStencilTexture;
626 
627 		if (tcu::hasDepthComponent(srcTexture.getTextureFormat().order))
628 		{
629 			tcu::TextureFormat format;
630 			switch (srcTexture.getTextureFormat().type)
631 			{
632 				case tcu::TextureFormat::UNSIGNED_INT_16_8_8:
633 					format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
634 					break;
635 				case tcu::TextureFormat::UNSIGNED_INT_24_8_REV:
636 					format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8_REV);
637 					break;
638 				case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
639 					format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
640 					break;
641 				default:
642 					DE_FATAL("Unexpected source texture format.");
643 					break;
644 			}
645 			srcDepthTexture = srcTexture.copy(format);
646 		}
647 
648 		if (tcu::hasStencilComponent(srcTexture.getTextureFormat().order))
649 			srcStencilTexture = srcTexture.copy(tcu::getEffectiveDepthStencilTextureFormat(srcTexture.getTextureFormat(), tcu::Sampler::MODE_STENCIL));
650 
651 		uploadTestTextureInternalSparse	(vk,
652 										 device,
653 										 physicalDevice,
654 										 instance,
655 										 imageCreateInfo,
656 										 universalQueue,
657 										 universalQueueFamilyIndex,
658 										 sparseQueue,
659 										 allocator,
660 										 allocations,
661 										 *srcDepthTexture,
662 										 srcStencilTexture.get(),
663 										 srcTexture.getTextureFormat(),
664 										 destImage);
665 	}
666 	else
667 	{
668 		uploadTestTextureInternalSparse	(vk,
669 										 device,
670 										 physicalDevice,
671 										 instance,
672 										 imageCreateInfo,
673 										 universalQueue,
674 										 universalQueueFamilyIndex,
675 										 sparseQueue,
676 										 allocator,
677 										 allocations,
678 										 srcTexture,
679 										 DE_NULL,
680 										 srcTexture.getTextureFormat(),
681 										 destImage);
682 	}
683 }
684 
685 // Utilities for test textures
686 
687 template<typename TcuTextureType>
allocateLevels(TcuTextureType & texture)688 void allocateLevels (TcuTextureType& texture)
689 {
690 	for (int levelNdx = 0; levelNdx < texture.getNumLevels(); levelNdx++)
691 		texture.allocLevel(levelNdx);
692 }
693 
694 template<typename TcuTextureType>
getLevelsVector(const TcuTextureType & texture)695 std::vector<tcu::PixelBufferAccess> getLevelsVector (const TcuTextureType& texture)
696 {
697 	std::vector<tcu::PixelBufferAccess> levels(texture.getNumLevels());
698 
699 	for (int levelNdx = 0; levelNdx < texture.getNumLevels(); levelNdx++)
700 		levels[levelNdx] = *reinterpret_cast<const tcu::PixelBufferAccess*>(&texture.getLevel(levelNdx));
701 
702 	return levels;
703 }
704 
705 // TestTexture
706 
TestTexture(const tcu::TextureFormat & format,int width,int height,int depth)707 TestTexture::TestTexture (const tcu::TextureFormat& format, int width, int height, int depth)
708 {
709 	DE_ASSERT(width >= 1);
710 	DE_ASSERT(height >= 1);
711 	DE_ASSERT(depth >= 1);
712 
713 	DE_UNREF(format);
714 	DE_UNREF(width);
715 	DE_UNREF(height);
716 	DE_UNREF(depth);
717 }
718 
TestTexture(const tcu::CompressedTexFormat & format,int width,int height,int depth)719 TestTexture::TestTexture (const tcu::CompressedTexFormat& format, int width, int height, int depth)
720 {
721 	DE_ASSERT(width >= 1);
722 	DE_ASSERT(height >= 1);
723 	DE_ASSERT(depth >= 1);
724 
725 	DE_UNREF(format);
726 	DE_UNREF(width);
727 	DE_UNREF(height);
728 	DE_UNREF(depth);
729 }
730 
~TestTexture(void)731 TestTexture::~TestTexture (void)
732 {
733 	for (size_t levelNdx = 0; levelNdx < m_compressedLevels.size(); levelNdx++)
734 		delete m_compressedLevels[levelNdx];
735 }
736 
getSize(void) const737 deUint32 TestTexture::getSize (void) const
738 {
739 	std::vector<deUint32>	offsetMultiples;
740 	deUint32				textureSize = 0;
741 
742 	offsetMultiples.push_back(4);
743 	offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
744 
745 	for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
746 	{
747 		for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
748 		{
749 			const tcu::ConstPixelBufferAccess level = getLevel(levelNdx, layerNdx);
750 			textureSize = getNextMultiple(offsetMultiples, textureSize);
751 			textureSize += level.getWidth() * level.getHeight() * level.getDepth() * level.getFormat().getPixelSize();
752 		}
753 	}
754 
755 	return textureSize;
756 }
757 
getCompressedSize(void) const758 deUint32 TestTexture::getCompressedSize (void) const
759 {
760 	if (!isCompressed())
761 		throw tcu::InternalError("Texture is not compressed");
762 
763 	std::vector<deUint32>	offsetMultiples;
764 	deUint32				textureSize			= 0;
765 
766 	offsetMultiples.push_back(4);
767 	offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
768 
769 	for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
770 	{
771 		for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
772 		{
773 			textureSize = getNextMultiple(offsetMultiples, textureSize);
774 			textureSize += getCompressedLevel(levelNdx, layerNdx).getDataSize();
775 		}
776 	}
777 
778 	return textureSize;
779 }
780 
getCompressedLevel(int level,int layer)781 tcu::CompressedTexture& TestTexture::getCompressedLevel (int level, int layer)
782 {
783 	DE_ASSERT(level >= 0 && level < getNumLevels());
784 	DE_ASSERT(layer >= 0 && layer < getArraySize());
785 
786 	return *m_compressedLevels[level * getArraySize() + layer];
787 }
788 
getCompressedLevel(int level,int layer) const789 const tcu::CompressedTexture& TestTexture::getCompressedLevel (int level, int layer) const
790 {
791 	DE_ASSERT(level >= 0 && level < getNumLevels());
792 	DE_ASSERT(layer >= 0 && layer < getArraySize());
793 
794 	return *m_compressedLevels[level * getArraySize() + layer];
795 }
796 
getBufferCopyRegions(void) const797 std::vector<VkBufferImageCopy> TestTexture::getBufferCopyRegions (void) const
798 {
799 	std::vector<deUint32>			offsetMultiples;
800 	std::vector<VkBufferImageCopy>	regions;
801 	deUint32						layerDataOffset = 0;
802 
803 	offsetMultiples.push_back(4);
804 
805 	if (isCompressed())
806 	{
807 		offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
808 
809 		for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
810 		{
811 			for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
812 			{
813 				const tcu::CompressedTexture& level = getCompressedLevel(levelNdx, layerNdx);
814 				tcu::IVec3 blockPixelSize			= getBlockPixelSize(level.getFormat());
815 				layerDataOffset						= getNextMultiple(offsetMultiples, layerDataOffset);
816 
817 				const VkBufferImageCopy layerRegion =
818 				{
819 					layerDataOffset,													// VkDeviceSize				bufferOffset;
820 					(deUint32)getNextMultiple(blockPixelSize.x(), level.getWidth()),	// deUint32					bufferRowLength;
821 					(deUint32)getNextMultiple(blockPixelSize.y(), level.getHeight()),	// deUint32					bufferImageHeight;
822 					{																	// VkImageSubresourceLayers	imageSubresource;
823 						VK_IMAGE_ASPECT_COLOR_BIT,
824 						(deUint32)levelNdx,
825 						(deUint32)layerNdx,
826 						1u
827 					},
828 					{ 0u, 0u, 0u },							// VkOffset3D				imageOffset;
829 					{										// VkExtent3D				imageExtent;
830 						(deUint32)level.getWidth(),
831 						(deUint32)level.getHeight(),
832 						(deUint32)level.getDepth()
833 					}
834 				};
835 
836 				regions.push_back(layerRegion);
837 				layerDataOffset += level.getDataSize();
838 			}
839 		}
840 	}
841 	else
842 	{
843 		std::vector<VkImageAspectFlags>	imageAspects;
844 		tcu::TextureFormat				textureFormat	= getTextureFormat();
845 
846 		if (tcu::hasDepthComponent(textureFormat.order))
847 			imageAspects.push_back(VK_IMAGE_ASPECT_DEPTH_BIT);
848 
849 		if (tcu::hasStencilComponent(textureFormat.order))
850 			imageAspects.push_back(VK_IMAGE_ASPECT_STENCIL_BIT);
851 
852 		if (imageAspects.empty())
853 			imageAspects.push_back(VK_IMAGE_ASPECT_COLOR_BIT);
854 
855 		offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
856 
857 		for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
858 		{
859 			for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
860 			{
861 				const tcu::ConstPixelBufferAccess level = getLevel(levelNdx, layerNdx);
862 
863 				layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset);
864 
865 				for (size_t aspectIndex = 0; aspectIndex < imageAspects.size(); ++aspectIndex)
866 				{
867 					const VkBufferImageCopy layerRegion =
868 					{
869 						layerDataOffset,						// VkDeviceSize				bufferOffset;
870 						(deUint32)level.getWidth(),				// deUint32					bufferRowLength;
871 						(deUint32)level.getHeight(),			// deUint32					bufferImageHeight;
872 						{										// VkImageSubresourceLayers	imageSubresource;
873 							imageAspects[aspectIndex],
874 							(deUint32)levelNdx,
875 							(deUint32)layerNdx,
876 							1u
877 						},
878 						{ 0u, 0u, 0u },							// VkOffset3D			imageOffset;
879 						{										// VkExtent3D			imageExtent;
880 							(deUint32)level.getWidth(),
881 							(deUint32)level.getHeight(),
882 							(deUint32)level.getDepth()
883 						}
884 					};
885 
886 					regions.push_back(layerRegion);
887 				}
888 				layerDataOffset += level.getWidth() * level.getHeight() * level.getDepth() * level.getFormat().getPixelSize();
889 			}
890 		}
891 	}
892 
893 	return regions;
894 }
895 
write(deUint8 * destPtr) const896 void TestTexture::write (deUint8* destPtr) const
897 {
898 	std::vector<deUint32>	offsetMultiples;
899 	deUint32				levelOffset		= 0;
900 
901 	offsetMultiples.push_back(4);
902 
903 	if (isCompressed())
904 	{
905 		offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
906 
907 		for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
908 		{
909 			for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
910 			{
911 				levelOffset = getNextMultiple(offsetMultiples, levelOffset);
912 
913 				const tcu::CompressedTexture&		compressedTex	= getCompressedLevel(levelNdx, layerNdx);
914 
915 				deMemcpy(destPtr + levelOffset, compressedTex.getData(), compressedTex.getDataSize());
916 				levelOffset += compressedTex.getDataSize();
917 			}
918 		}
919 	}
920 	else
921 	{
922 		offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
923 
924 		for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
925 		{
926 			for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
927 			{
928 				levelOffset = getNextMultiple(offsetMultiples, levelOffset);
929 
930 				const tcu::ConstPixelBufferAccess	srcAccess		= getLevel(levelNdx, layerNdx);
931 				const tcu::PixelBufferAccess		destAccess		(srcAccess.getFormat(), srcAccess.getSize(), srcAccess.getPitch(), destPtr + levelOffset);
932 
933 				tcu::copy(destAccess, srcAccess);
934 				levelOffset += srcAccess.getWidth() * srcAccess.getHeight() * srcAccess.getDepth() * srcAccess.getFormat().getPixelSize();
935 			}
936 		}
937 	}
938 }
939 
copyToTexture(TestTexture & destTexture) const940 void TestTexture::copyToTexture (TestTexture& destTexture) const
941 {
942 	for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
943 		for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
944 			tcu::copy(destTexture.getLevel(levelNdx, layerNdx), getLevel(levelNdx, layerNdx));
945 }
946 
populateLevels(const std::vector<tcu::PixelBufferAccess> & levels)947 void TestTexture::populateLevels (const std::vector<tcu::PixelBufferAccess>& levels)
948 {
949 	for (size_t levelNdx = 0; levelNdx < levels.size(); levelNdx++)
950 		TestTexture::fillWithGradient(levels[levelNdx]);
951 }
952 
populateCompressedLevels(tcu::CompressedTexFormat format,const std::vector<tcu::PixelBufferAccess> & decompressedLevels)953 void TestTexture::populateCompressedLevels (tcu::CompressedTexFormat format, const std::vector<tcu::PixelBufferAccess>& decompressedLevels)
954 {
955 	// Generate random compressed data and update decompressed data
956 
957 	de::Random random(123);
958 
959 	for (size_t levelNdx = 0; levelNdx < decompressedLevels.size(); levelNdx++)
960 	{
961 		const tcu::PixelBufferAccess	level				= decompressedLevels[levelNdx];
962 		tcu::CompressedTexture*			compressedLevel		= new tcu::CompressedTexture(format, level.getWidth(), level.getHeight(), level.getDepth());
963 		deUint8* const					compressedData		= (deUint8*)compressedLevel->getData();
964 
965 		if (tcu::isAstcFormat(format))
966 		{
967 			// \todo [2016-01-20 pyry] Comparison doesn't currently handle invalid blocks correctly so we use only valid blocks
968 			tcu::astc::generateRandomValidBlocks(compressedData, compressedLevel->getDataSize()/tcu::astc::BLOCK_SIZE_BYTES,
969 												 format, tcu::TexDecompressionParams::ASTCMODE_LDR, random.getUint32());
970 		}
971 		else
972 		{
973 			// Generate random compressed data
974 			// Random initial values cause assertion during the decompression in case of COMPRESSEDTEXFORMAT_ETC1_RGB8 format
975 			if (format != tcu::COMPRESSEDTEXFORMAT_ETC1_RGB8)
976 				for (int byteNdx = 0; byteNdx < compressedLevel->getDataSize(); byteNdx++)
977 					compressedData[byteNdx] = 0xFF & random.getUint32();
978 		}
979 
980 		m_compressedLevels.push_back(compressedLevel);
981 
982 		// Store decompressed data
983 		compressedLevel->decompress(level, tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR));
984 	}
985 }
986 
fillWithGradient(const tcu::PixelBufferAccess & levelAccess)987 void TestTexture::fillWithGradient (const tcu::PixelBufferAccess& levelAccess)
988 {
989 	const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(levelAccess.getFormat());
990 	tcu::fillWithComponentGradients2(levelAccess, formatInfo.valueMin, formatInfo.valueMax);
991 }
992 
993 // TestTexture1D
994 
TestTexture1D(const tcu::TextureFormat & format,int width)995 TestTexture1D::TestTexture1D (const tcu::TextureFormat& format, int width)
996 	: TestTexture	(format, width, 1, 1)
997 	, m_texture		(format, width)
998 {
999 	allocateLevels(m_texture);
1000 	TestTexture::populateLevels(getLevelsVector(m_texture));
1001 }
1002 
TestTexture1D(const tcu::CompressedTexFormat & format,int width)1003 TestTexture1D::TestTexture1D (const tcu::CompressedTexFormat& format, int width)
1004 	: TestTexture	(format, width, 1, 1)
1005 	, m_texture		(tcu::getUncompressedFormat(format), width)
1006 {
1007 	allocateLevels(m_texture);
1008 	TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
1009 }
1010 
~TestTexture1D(void)1011 TestTexture1D::~TestTexture1D (void)
1012 {
1013 }
1014 
getNumLevels(void) const1015 int TestTexture1D::getNumLevels (void) const
1016 {
1017 	return m_texture.getNumLevels();
1018 }
1019 
getLevel(int level,int layer)1020 tcu::PixelBufferAccess TestTexture1D::getLevel (int level, int layer)
1021 {
1022 	DE_ASSERT(layer == 0);
1023 	DE_UNREF(layer);
1024 	return m_texture.getLevel(level);
1025 }
1026 
getLevel(int level,int layer) const1027 const tcu::ConstPixelBufferAccess TestTexture1D::getLevel (int level, int layer) const
1028 {
1029 	DE_ASSERT(layer == 0);
1030 	DE_UNREF(layer);
1031 	return m_texture.getLevel(level);
1032 }
1033 
getTexture(void) const1034 const tcu::Texture1D& TestTexture1D::getTexture (void) const
1035 {
1036 	return m_texture;
1037 }
1038 
getTexture(void)1039 tcu::Texture1D& TestTexture1D::getTexture (void)
1040 {
1041 	return m_texture;
1042 }
1043 
copy(const tcu::TextureFormat format) const1044 de::MovePtr<TestTexture> TestTexture1D::copy(const tcu::TextureFormat format) const
1045 {
1046 	DE_ASSERT(!isCompressed());
1047 
1048 	de::MovePtr<TestTexture>	texture	(new TestTexture1D(format, m_texture.getWidth()));
1049 
1050 	copyToTexture(*texture);
1051 
1052 	return texture;
1053 }
1054 
1055 // TestTexture1DArray
1056 
TestTexture1DArray(const tcu::TextureFormat & format,int width,int arraySize)1057 TestTexture1DArray::TestTexture1DArray (const tcu::TextureFormat& format, int width, int arraySize)
1058 	: TestTexture	(format, width, 1, arraySize)
1059 	, m_texture		(format, width, arraySize)
1060 {
1061 	allocateLevels(m_texture);
1062 	TestTexture::populateLevels(getLevelsVector(m_texture));
1063 }
1064 
TestTexture1DArray(const tcu::CompressedTexFormat & format,int width,int arraySize)1065 TestTexture1DArray::TestTexture1DArray (const tcu::CompressedTexFormat& format, int width, int arraySize)
1066 	: TestTexture	(format, width, 1, arraySize)
1067 	, m_texture		(tcu::getUncompressedFormat(format), width, arraySize)
1068 {
1069 	allocateLevels(m_texture);
1070 
1071 	std::vector<tcu::PixelBufferAccess> layers;
1072 	for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
1073 		for (int layerNdx = 0; layerNdx < m_texture.getNumLayers(); layerNdx++)
1074 			layers.push_back(getLevel(levelNdx, layerNdx));
1075 
1076 	TestTexture::populateCompressedLevels(format, layers);
1077 }
1078 
~TestTexture1DArray(void)1079 TestTexture1DArray::~TestTexture1DArray (void)
1080 {
1081 }
1082 
getNumLevels(void) const1083 int TestTexture1DArray::getNumLevels (void) const
1084 {
1085 	return m_texture.getNumLevels();
1086 }
1087 
getLevel(int level,int layer)1088 tcu::PixelBufferAccess TestTexture1DArray::getLevel (int level, int layer)
1089 {
1090 	const tcu::PixelBufferAccess	levelLayers	= m_texture.getLevel(level);
1091 	const deUint32					layerSize	= levelLayers.getWidth() * levelLayers.getFormat().getPixelSize();
1092 	const deUint32					layerOffset	= layerSize * layer;
1093 
1094 	return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1095 }
1096 
getLevel(int level,int layer) const1097 const tcu::ConstPixelBufferAccess TestTexture1DArray::getLevel (int level, int layer) const
1098 {
1099 	const tcu::ConstPixelBufferAccess	levelLayers	= m_texture.getLevel(level);
1100 	const deUint32						layerSize	= levelLayers.getWidth() * levelLayers.getFormat().getPixelSize();
1101 	const deUint32						layerOffset	= layerSize * layer;
1102 
1103 	return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1104 }
1105 
getTexture(void) const1106 const tcu::Texture1DArray& TestTexture1DArray::getTexture (void) const
1107 {
1108 	return m_texture;
1109 }
1110 
getTexture(void)1111 tcu::Texture1DArray& TestTexture1DArray::getTexture (void)
1112 {
1113 	return m_texture;
1114 }
1115 
getArraySize(void) const1116 int TestTexture1DArray::getArraySize (void) const
1117 {
1118 	return m_texture.getNumLayers();
1119 }
1120 
copy(const tcu::TextureFormat format) const1121 de::MovePtr<TestTexture> TestTexture1DArray::copy(const tcu::TextureFormat format) const
1122 {
1123 	DE_ASSERT(!isCompressed());
1124 
1125 	de::MovePtr<TestTexture>	texture	(new TestTexture1DArray(format, m_texture.getWidth(), getArraySize()));
1126 
1127 	copyToTexture(*texture);
1128 
1129 	return texture;
1130 }
1131 
1132 // TestTexture2D
1133 
TestTexture2D(const tcu::TextureFormat & format,int width,int height)1134 TestTexture2D::TestTexture2D (const tcu::TextureFormat& format, int width, int height)
1135 	: TestTexture	(format, width, height, 1)
1136 	, m_texture		(format, width, height)
1137 {
1138 	allocateLevels(m_texture);
1139 	TestTexture::populateLevels(getLevelsVector(m_texture));
1140 }
1141 
TestTexture2D(const tcu::TextureFormat & format,int width,int height,int miplevels)1142 TestTexture2D::TestTexture2D (const tcu::TextureFormat& format, int width, int height, int miplevels)
1143 	: TestTexture(format, width, height, 1)
1144 	, m_texture(format, width, height, miplevels)
1145 {
1146 	allocateLevels(m_texture);
1147 	TestTexture::populateLevels(getLevelsVector(m_texture));
1148 }
1149 
1150 
TestTexture2D(const tcu::CompressedTexFormat & format,int width,int height)1151 TestTexture2D::TestTexture2D (const tcu::CompressedTexFormat& format, int width, int height)
1152 	: TestTexture	(format, width, height, 1)
1153 	, m_texture		(tcu::getUncompressedFormat(format), width, height)
1154 {
1155 	allocateLevels(m_texture);
1156 	TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
1157 }
1158 
~TestTexture2D(void)1159 TestTexture2D::~TestTexture2D (void)
1160 {
1161 }
1162 
getNumLevels(void) const1163 int TestTexture2D::getNumLevels (void) const
1164 {
1165 	return m_texture.getNumLevels();
1166 }
1167 
getLevel(int level,int layer)1168 tcu::PixelBufferAccess TestTexture2D::getLevel (int level, int layer)
1169 {
1170 	DE_ASSERT(layer == 0);
1171 	DE_UNREF(layer);
1172 	return m_texture.getLevel(level);
1173 }
1174 
getLevel(int level,int layer) const1175 const tcu::ConstPixelBufferAccess TestTexture2D::getLevel (int level, int layer) const
1176 {
1177 	DE_ASSERT(layer == 0);
1178 	DE_UNREF(layer);
1179 	return m_texture.getLevel(level);
1180 }
1181 
getTexture(void) const1182 const tcu::Texture2D& TestTexture2D::getTexture (void) const
1183 {
1184 	return m_texture;
1185 }
1186 
getTexture(void)1187 tcu::Texture2D& TestTexture2D::getTexture (void)
1188 {
1189 	return m_texture;
1190 }
1191 
copy(const tcu::TextureFormat format) const1192 de::MovePtr<TestTexture> TestTexture2D::copy(const tcu::TextureFormat format) const
1193 {
1194 	DE_ASSERT(!isCompressed());
1195 
1196 	de::MovePtr<TestTexture>	texture	(new TestTexture2D(format, m_texture.getWidth(), m_texture.getHeight(), m_texture.getNumLevels()));
1197 
1198 	copyToTexture(*texture);
1199 
1200 	return texture;
1201 }
1202 
1203 // TestTexture2DArray
1204 
TestTexture2DArray(const tcu::TextureFormat & format,int width,int height,int arraySize)1205 TestTexture2DArray::TestTexture2DArray (const tcu::TextureFormat& format, int width, int height, int arraySize)
1206 	: TestTexture	(format, width, height, arraySize)
1207 	, m_texture		(format, width, height, arraySize)
1208 {
1209 	allocateLevels(m_texture);
1210 	TestTexture::populateLevels(getLevelsVector(m_texture));
1211 }
1212 
TestTexture2DArray(const tcu::CompressedTexFormat & format,int width,int height,int arraySize)1213 TestTexture2DArray::TestTexture2DArray (const tcu::CompressedTexFormat& format, int width, int height, int arraySize)
1214 	: TestTexture	(format, width, height, arraySize)
1215 	, m_texture		(tcu::getUncompressedFormat(format), width, height, arraySize)
1216 {
1217 	allocateLevels(m_texture);
1218 
1219 	std::vector<tcu::PixelBufferAccess> layers;
1220 	for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
1221 		for (int layerNdx = 0; layerNdx < m_texture.getNumLayers(); layerNdx++)
1222 			layers.push_back(getLevel(levelNdx, layerNdx));
1223 
1224 	TestTexture::populateCompressedLevels(format, layers);
1225 }
1226 
~TestTexture2DArray(void)1227 TestTexture2DArray::~TestTexture2DArray (void)
1228 {
1229 }
1230 
getNumLevels(void) const1231 int TestTexture2DArray::getNumLevels (void) const
1232 {
1233 	return m_texture.getNumLevels();
1234 }
1235 
getLevel(int level,int layer)1236 tcu::PixelBufferAccess TestTexture2DArray::getLevel (int level, int layer)
1237 {
1238 	const tcu::PixelBufferAccess	levelLayers	= m_texture.getLevel(level);
1239 	const deUint32					layerSize	= levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1240 	const deUint32					layerOffset	= layerSize * layer;
1241 
1242 	return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1243 }
1244 
getLevel(int level,int layer) const1245 const tcu::ConstPixelBufferAccess TestTexture2DArray::getLevel (int level, int layer) const
1246 {
1247 	const tcu::ConstPixelBufferAccess	levelLayers	= m_texture.getLevel(level);
1248 	const deUint32						layerSize	= levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1249 	const deUint32						layerOffset	= layerSize * layer;
1250 
1251 	return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1252 }
1253 
getTexture(void) const1254 const tcu::Texture2DArray& TestTexture2DArray::getTexture (void) const
1255 {
1256 	return m_texture;
1257 }
1258 
getTexture(void)1259 tcu::Texture2DArray& TestTexture2DArray::getTexture (void)
1260 {
1261 	return m_texture;
1262 }
1263 
getArraySize(void) const1264 int TestTexture2DArray::getArraySize (void) const
1265 {
1266 	return m_texture.getNumLayers();
1267 }
1268 
copy(const tcu::TextureFormat format) const1269 de::MovePtr<TestTexture> TestTexture2DArray::copy(const tcu::TextureFormat format) const
1270 {
1271 	DE_ASSERT(!isCompressed());
1272 
1273 	de::MovePtr<TestTexture>	texture	(new TestTexture2DArray(format, m_texture.getWidth(), m_texture.getHeight(), getArraySize()));
1274 
1275 	copyToTexture(*texture);
1276 
1277 	return texture;
1278 }
1279 
1280 // TestTexture3D
1281 
TestTexture3D(const tcu::TextureFormat & format,int width,int height,int depth)1282 TestTexture3D::TestTexture3D (const tcu::TextureFormat& format, int width, int height, int depth)
1283 	: TestTexture	(format, width, height, depth)
1284 	, m_texture		(format, width, height, depth)
1285 {
1286 	allocateLevels(m_texture);
1287 	TestTexture::populateLevels(getLevelsVector(m_texture));
1288 }
1289 
TestTexture3D(const tcu::CompressedTexFormat & format,int width,int height,int depth)1290 TestTexture3D::TestTexture3D (const tcu::CompressedTexFormat& format, int width, int height, int depth)
1291 	: TestTexture	(format, width, height, depth)
1292 	, m_texture		(tcu::getUncompressedFormat(format), width, height, depth)
1293 {
1294 	allocateLevels(m_texture);
1295 	TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
1296 }
1297 
~TestTexture3D(void)1298 TestTexture3D::~TestTexture3D (void)
1299 {
1300 }
1301 
getNumLevels(void) const1302 int TestTexture3D::getNumLevels (void) const
1303 {
1304 	return m_texture.getNumLevels();
1305 }
1306 
getLevel(int level,int layer)1307 tcu::PixelBufferAccess TestTexture3D::getLevel (int level, int layer)
1308 {
1309 	DE_ASSERT(layer == 0);
1310 	DE_UNREF(layer);
1311 	return m_texture.getLevel(level);
1312 }
1313 
getLevel(int level,int layer) const1314 const tcu::ConstPixelBufferAccess TestTexture3D::getLevel (int level, int layer) const
1315 {
1316 	DE_ASSERT(layer == 0);
1317 	DE_UNREF(layer);
1318 	return m_texture.getLevel(level);
1319 }
1320 
getTexture(void) const1321 const tcu::Texture3D& TestTexture3D::getTexture (void) const
1322 {
1323 	return m_texture;
1324 }
1325 
getTexture(void)1326 tcu::Texture3D& TestTexture3D::getTexture (void)
1327 {
1328 	return m_texture;
1329 }
1330 
copy(const tcu::TextureFormat format) const1331 de::MovePtr<TestTexture> TestTexture3D::copy(const tcu::TextureFormat format) const
1332 {
1333 	DE_ASSERT(!isCompressed());
1334 
1335 	de::MovePtr<TestTexture>	texture	(new TestTexture3D(format, m_texture.getWidth(), m_texture.getHeight(), m_texture.getDepth()));
1336 
1337 	copyToTexture(*texture);
1338 
1339 	return texture;
1340 }
1341 
1342 // TestTextureCube
1343 
1344 const static tcu::CubeFace tcuFaceMapping[tcu::CUBEFACE_LAST] =
1345 {
1346 	tcu::CUBEFACE_POSITIVE_X,
1347 	tcu::CUBEFACE_NEGATIVE_X,
1348 	tcu::CUBEFACE_POSITIVE_Y,
1349 	tcu::CUBEFACE_NEGATIVE_Y,
1350 	tcu::CUBEFACE_POSITIVE_Z,
1351 	tcu::CUBEFACE_NEGATIVE_Z
1352 };
1353 
TestTextureCube(const tcu::TextureFormat & format,int size)1354 TestTextureCube::TestTextureCube (const tcu::TextureFormat& format, int size)
1355 	: TestTexture	(format, size, size, 1)
1356 	, m_texture		(format, size)
1357 {
1358 	for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
1359 	{
1360 		for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
1361 		{
1362 			m_texture.allocLevel(tcuFaceMapping[faceNdx], levelNdx);
1363 			TestTexture::fillWithGradient(m_texture.getLevelFace(levelNdx, tcuFaceMapping[faceNdx]));
1364 		}
1365 	}
1366 }
1367 
TestTextureCube(const tcu::CompressedTexFormat & format,int size)1368 TestTextureCube::TestTextureCube (const tcu::CompressedTexFormat& format, int size)
1369 	: TestTexture	(format, size, size, 1)
1370 	, m_texture		(tcu::getUncompressedFormat(format), size)
1371 {
1372 	std::vector<tcu::PixelBufferAccess> levels(m_texture.getNumLevels() * tcu::CUBEFACE_LAST);
1373 
1374 	for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
1375 	{
1376 		for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
1377 		{
1378 			m_texture.allocLevel(tcuFaceMapping[faceNdx], levelNdx);
1379 			levels[levelNdx * tcu::CUBEFACE_LAST + faceNdx] = m_texture.getLevelFace(levelNdx, tcuFaceMapping[faceNdx]);
1380 		}
1381 	}
1382 
1383 	TestTexture::populateCompressedLevels(format, levels);
1384 }
1385 
~TestTextureCube(void)1386 TestTextureCube::~TestTextureCube (void)
1387 {
1388 }
1389 
getNumLevels(void) const1390 int TestTextureCube::getNumLevels (void) const
1391 {
1392 	return m_texture.getNumLevels();
1393 }
1394 
getLevel(int level,int layer)1395 tcu::PixelBufferAccess TestTextureCube::getLevel (int level, int layer)
1396 {
1397 	return m_texture.getLevelFace(level, tcuFaceMapping[layer]);
1398 }
1399 
getLevel(int level,int layer) const1400 const tcu::ConstPixelBufferAccess TestTextureCube::getLevel (int level, int layer) const
1401 {
1402 	return m_texture.getLevelFace(level, tcuFaceMapping[layer]);
1403 }
1404 
getArraySize(void) const1405 int TestTextureCube::getArraySize (void) const
1406 {
1407 	return (int)tcu::CUBEFACE_LAST;
1408 }
1409 
getTexture(void) const1410 const tcu::TextureCube& TestTextureCube::getTexture (void) const
1411 {
1412 	return m_texture;
1413 }
1414 
getTexture(void)1415 tcu::TextureCube& TestTextureCube::getTexture (void)
1416 {
1417 	return m_texture;
1418 }
1419 
copy(const tcu::TextureFormat format) const1420 de::MovePtr<TestTexture> TestTextureCube::copy(const tcu::TextureFormat format) const
1421 {
1422 	DE_ASSERT(!isCompressed());
1423 
1424 	de::MovePtr<TestTexture>	texture	(new TestTextureCube(format, m_texture.getSize()));
1425 
1426 	copyToTexture(*texture);
1427 
1428 	return texture;
1429 }
1430 
1431 // TestTextureCubeArray
1432 
TestTextureCubeArray(const tcu::TextureFormat & format,int size,int arraySize)1433 TestTextureCubeArray::TestTextureCubeArray (const tcu::TextureFormat& format, int size, int arraySize)
1434 	: TestTexture	(format, size, size, arraySize)
1435 	, m_texture		(format, size, arraySize)
1436 {
1437 	allocateLevels(m_texture);
1438 	TestTexture::populateLevels(getLevelsVector(m_texture));
1439 }
1440 
TestTextureCubeArray(const tcu::CompressedTexFormat & format,int size,int arraySize)1441 TestTextureCubeArray::TestTextureCubeArray (const tcu::CompressedTexFormat& format, int size, int arraySize)
1442 	: TestTexture	(format, size, size, arraySize)
1443 	, m_texture		(tcu::getUncompressedFormat(format), size, arraySize)
1444 {
1445 	DE_ASSERT(arraySize % 6 == 0);
1446 
1447 	allocateLevels(m_texture);
1448 
1449 	std::vector<tcu::PixelBufferAccess> layers;
1450 	for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
1451 		for (int layerNdx = 0; layerNdx < m_texture.getDepth(); layerNdx++)
1452 			layers.push_back(getLevel(levelNdx, layerNdx));
1453 
1454 	TestTexture::populateCompressedLevels(format, layers);
1455 }
1456 
~TestTextureCubeArray(void)1457 TestTextureCubeArray::~TestTextureCubeArray (void)
1458 {
1459 }
1460 
getNumLevels(void) const1461 int TestTextureCubeArray::getNumLevels (void) const
1462 {
1463 	return m_texture.getNumLevels();
1464 }
1465 
getLevel(int level,int layer)1466 tcu::PixelBufferAccess TestTextureCubeArray::getLevel (int level, int layer)
1467 {
1468 	const tcu::PixelBufferAccess	levelLayers	= m_texture.getLevel(level);
1469 	const deUint32					layerSize	= levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1470 	const deUint32					layerOffset	= layerSize * layer;
1471 
1472 	return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1473 }
1474 
getLevel(int level,int layer) const1475 const tcu::ConstPixelBufferAccess TestTextureCubeArray::getLevel (int level, int layer) const
1476 {
1477 	const tcu::ConstPixelBufferAccess	levelLayers	= m_texture.getLevel(level);
1478 	const deUint32						layerSize	= levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1479 	const deUint32						layerOffset	= layerSize * layer;
1480 
1481 	return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1482 }
1483 
getArraySize(void) const1484 int TestTextureCubeArray::getArraySize (void) const
1485 {
1486 	return m_texture.getDepth();
1487 }
1488 
getTexture(void) const1489 const tcu::TextureCubeArray& TestTextureCubeArray::getTexture (void) const
1490 {
1491 	return m_texture;
1492 }
1493 
getTexture(void)1494 tcu::TextureCubeArray& TestTextureCubeArray::getTexture (void)
1495 {
1496 	return m_texture;
1497 }
1498 
copy(const tcu::TextureFormat format) const1499 de::MovePtr<TestTexture> TestTextureCubeArray::copy(const tcu::TextureFormat format) const
1500 {
1501 	DE_ASSERT(!isCompressed());
1502 
1503 	de::MovePtr<TestTexture>	texture	(new TestTextureCubeArray(format, m_texture.getSize(), getArraySize()));
1504 
1505 	copyToTexture(*texture);
1506 
1507 	return texture;
1508 }
1509 
1510 } // pipeline
1511 } // vkt
1512