• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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,vk::VkImageLayout oldLayout)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 													vk::VkImageLayout			oldLayout)
216 {
217 	Move<VkBuffer>					buffer;
218 	de::MovePtr<Allocation>			bufferAlloc;
219 	Move<VkCommandPool>				cmdPool;
220 	Move<VkCommandBuffer>			cmdBuffer;
221 	Move<VkFence>					fence;
222 	const tcu::TextureFormat		tcuFormat		= mapVkFormat(format);
223 	const VkDeviceSize				pixelDataSize	= renderSize.x() * renderSize.y() * tcuFormat.getPixelSize();
224 	de::MovePtr<tcu::TextureLevel>	resultLevel		(new tcu::TextureLevel(tcuFormat, renderSize.x(), renderSize.y()));
225 
226 	// Create destination buffer
227 	{
228 		const VkBufferCreateInfo bufferParams =
229 		{
230 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
231 			DE_NULL,									// const void*			pNext;
232 			0u,											// VkBufferCreateFlags	flags;
233 			pixelDataSize,								// VkDeviceSize			size;
234 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
235 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
236 			0u,											// deUint32				queueFamilyIndexCount;
237 			DE_NULL										// const deUint32*		pQueueFamilyIndices;
238 		};
239 
240 		buffer		= createBuffer(vk, device, &bufferParams);
241 		bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
242 		VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
243 	}
244 
245 	// Create command pool and buffer
246 	cmdPool		= createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
247 	cmdBuffer	= allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
248 
249 	// Create fence
250 	fence = createFence(vk, device);
251 
252 	beginCommandBuffer(vk, *cmdBuffer);
253 	copyImageToBuffer(vk, *cmdBuffer, image, *buffer, tcu::IVec2(renderSize.x(), renderSize.y()), VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, oldLayout);
254 	endCommandBuffer(vk, *cmdBuffer);
255 
256 	submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
257 
258 	// Read buffer data
259 	invalidateAlloc(vk, device, *bufferAlloc);
260 	tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), bufferAlloc->getHostPtr()));
261 
262 	return resultLevel;
263 }
264 
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)265 de::MovePtr<tcu::TextureLevel> readDepthAttachment (const vk::DeviceInterface&	vk,
266 													vk::VkDevice				device,
267 													vk::VkQueue					queue,
268 													deUint32					queueFamilyIndex,
269 													vk::Allocator&				allocator,
270 													vk::VkImage					image,
271 													vk::VkFormat				format,
272 													const tcu::UVec2&			renderSize,
273 													vk::VkImageLayout			currentLayout)
274 {
275 	Move<VkBuffer>					buffer;
276 	de::MovePtr<Allocation>			bufferAlloc;
277 	Move<VkCommandPool>				cmdPool;
278 	Move<VkCommandBuffer>			cmdBuffer;
279 
280 	tcu::TextureFormat				retFormat		(tcu::TextureFormat::D, tcu::TextureFormat::CHANNELTYPE_LAST);
281 	tcu::TextureFormat				bufferFormat	(tcu::TextureFormat::D, tcu::TextureFormat::CHANNELTYPE_LAST);
282 	const VkImageAspectFlags		barrierAspect	= VK_IMAGE_ASPECT_DEPTH_BIT | (mapVkFormat(format).order == tcu::TextureFormat::DS ? VK_IMAGE_ASPECT_STENCIL_BIT : (VkImageAspectFlagBits)0);
283 
284 	switch (format)
285 	{
286 	case vk::VK_FORMAT_D16_UNORM:
287 	case vk::VK_FORMAT_D16_UNORM_S8_UINT:
288 		bufferFormat.type = retFormat.type = tcu::TextureFormat::UNORM_INT16;
289 		break;
290 	case vk::VK_FORMAT_D24_UNORM_S8_UINT:
291 	case vk::VK_FORMAT_X8_D24_UNORM_PACK32:
292 		retFormat.type = tcu::TextureFormat::UNORM_INT24;
293 		// vkCmdCopyBufferToImage copies D24 data to 32-bit pixels.
294 		bufferFormat.type = tcu::TextureFormat::UNSIGNED_INT_24_8_REV;
295 		break;
296 	case vk::VK_FORMAT_D32_SFLOAT:
297 	case vk::VK_FORMAT_D32_SFLOAT_S8_UINT:
298 		bufferFormat.type = retFormat.type = tcu::TextureFormat::FLOAT;
299 		break;
300 	default:
301 		TCU_FAIL("unrecognized format");
302 	}
303 
304 	const VkDeviceSize				pixelDataSize	= renderSize.x() * renderSize.y() * bufferFormat.getPixelSize();
305 	de::MovePtr<tcu::TextureLevel>	resultLevel		(new tcu::TextureLevel(retFormat, renderSize.x(), renderSize.y()));
306 
307 	// Create destination buffer
308 	{
309 		const VkBufferCreateInfo bufferParams =
310 		{
311 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
312 			DE_NULL,									// const void*			pNext;
313 			0u,											// VkBufferCreateFlags	flags;
314 			pixelDataSize,								// VkDeviceSize			size;
315 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
316 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
317 			0u,											// deUint32				queueFamilyIndexCount;
318 			DE_NULL										// const deUint32*		pQueueFamilyIndices;
319 		};
320 
321 		buffer		= createBuffer(vk, device, &bufferParams);
322 		bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
323 		VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
324 	}
325 
326 	// Create command pool and buffer
327 	cmdPool		= createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
328 	cmdBuffer	= allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
329 
330 	beginCommandBuffer(vk, *cmdBuffer);
331 	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);
332 	endCommandBuffer(vk, *cmdBuffer);
333 
334 	submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
335 
336 	// Read buffer data
337 	invalidateAlloc(vk, device, *bufferAlloc);
338 	tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(bufferFormat, resultLevel->getSize(), bufferAlloc->getHostPtr()));
339 
340 	return resultLevel;
341 }
342 
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)343 de::MovePtr<tcu::TextureLevel> readStencilAttachment (const vk::DeviceInterface&	vk,
344 													  vk::VkDevice					device,
345 													  vk::VkQueue					queue,
346 													  deUint32						queueFamilyIndex,
347 													  vk::Allocator&				allocator,
348 													  vk::VkImage					image,
349 													  vk::VkFormat					format,
350 													  const tcu::UVec2&				renderSize,
351 													  vk::VkImageLayout				currentLayout)
352 {
353 	Move<VkBuffer>					buffer;
354 	de::MovePtr<Allocation>			bufferAlloc;
355 	Move<VkCommandPool>				cmdPool;
356 	Move<VkCommandBuffer>			cmdBuffer;
357 
358 	tcu::TextureFormat				retFormat		(tcu::TextureFormat::S, tcu::TextureFormat::UNSIGNED_INT8);
359 	tcu::TextureFormat				bufferFormat	(tcu::TextureFormat::S, tcu::TextureFormat::UNSIGNED_INT8);
360 
361 	const VkImageAspectFlags		barrierAspect	= VK_IMAGE_ASPECT_STENCIL_BIT | (mapVkFormat(format).order == tcu::TextureFormat::DS ? VK_IMAGE_ASPECT_DEPTH_BIT : (VkImageAspectFlagBits)0);
362 	const VkDeviceSize				pixelDataSize	= renderSize.x() * renderSize.y() * bufferFormat.getPixelSize();
363 	de::MovePtr<tcu::TextureLevel>	resultLevel		(new tcu::TextureLevel(retFormat, renderSize.x(), renderSize.y()));
364 
365 	// Create destination buffer
366 	{
367 		const VkBufferCreateInfo bufferParams =
368 		{
369 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
370 			DE_NULL,									// const void*			pNext;
371 			0u,											// VkBufferCreateFlags	flags;
372 			pixelDataSize,								// VkDeviceSize			size;
373 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
374 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
375 			0u,											// deUint32				queueFamilyIndexCount;
376 			DE_NULL										// const deUint32*		pQueueFamilyIndices;
377 		};
378 
379 		buffer		= createBuffer(vk, device, &bufferParams);
380 		bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
381 		VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
382 	}
383 
384 	// Create command pool and buffer
385 	cmdPool		= createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
386 	cmdBuffer	= allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
387 
388 	beginCommandBuffer(vk, *cmdBuffer);
389 	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);
390 	endCommandBuffer(vk, *cmdBuffer);
391 
392 	submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
393 
394 	// Read buffer data
395 	invalidateAlloc(vk, device, *bufferAlloc);
396 	tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(bufferFormat, resultLevel->getSize(), bufferAlloc->getHostPtr()));
397 
398 	return resultLevel;
399 }
400 
uploadTestTextureInternal(const DeviceInterface & vk,VkDevice device,VkQueue queue,deUint32 queueFamilyIndex,Allocator & allocator,const TestTexture & srcTexture,const TestTexture * srcStencilTexture,tcu::TextureFormat format,VkImage destImage)401 void uploadTestTextureInternal (const DeviceInterface&	vk,
402 								VkDevice				device,
403 								VkQueue					queue,
404 								deUint32				queueFamilyIndex,
405 								Allocator&				allocator,
406 								const TestTexture&		srcTexture,
407 								const TestTexture*		srcStencilTexture,
408 								tcu::TextureFormat		format,
409 								VkImage					destImage)
410 {
411 	Move<VkBuffer>					buffer;
412 	de::MovePtr<Allocation>			bufferAlloc;
413 	Move<VkCommandPool>				cmdPool;
414 	Move<VkCommandBuffer>			cmdBuffer;
415 	const VkImageAspectFlags		imageAspectFlags	= getImageAspectFlags(format);
416 	deUint32						stencilOffset		= 0u;
417 	std::vector<VkBufferImageCopy>	copyRegions			= srcTexture.getBufferCopyRegions();
418 	deUint32						bufferSize			= (srcTexture.isCompressed())? srcTexture.getCompressedSize(): srcTexture.getSize();
419 
420 	// Stencil-only texture should be provided if (and only if) the image has a combined DS format
421 	DE_ASSERT((tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order)) == (srcStencilTexture != DE_NULL));
422 
423 	if (srcStencilTexture != DE_NULL)
424 	{
425 		stencilOffset	= static_cast<deUint32>(deAlign32(static_cast<deInt32>(bufferSize), 4));
426 		bufferSize		= stencilOffset + srcStencilTexture->getSize();
427 	}
428 
429 	// Create source buffer
430 	{
431 		const VkBufferCreateInfo bufferParams =
432 		{
433 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType      sType;
434 			DE_NULL,								// const void*          pNext;
435 			0u,										// VkBufferCreateFlags  flags;
436 			bufferSize,								// VkDeviceSize         size;
437 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,		// VkBufferUsageFlags   usage;
438 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode        sharingMode;
439 			0u,										// deUint32             queueFamilyIndexCount;
440 			DE_NULL,								// const deUint32*      pQueueFamilyIndices;
441 		};
442 
443 		buffer		= createBuffer(vk, device, &bufferParams);
444 		bufferAlloc	= allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
445 		VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
446 	}
447 
448 	// Write buffer data
449 	{
450 		srcTexture.write(reinterpret_cast<deUint8*>(bufferAlloc->getHostPtr()));
451 
452 		if (srcStencilTexture != DE_NULL)
453 		{
454 			DE_ASSERT(stencilOffset != 0u);
455 
456 			srcStencilTexture->write(reinterpret_cast<deUint8*>(bufferAlloc->getHostPtr()) + stencilOffset);
457 
458 			std::vector<VkBufferImageCopy>	stencilCopyRegions = srcStencilTexture->getBufferCopyRegions();
459 			for (size_t regionIdx = 0; regionIdx < stencilCopyRegions.size(); regionIdx++)
460 			{
461 				VkBufferImageCopy region = stencilCopyRegions[regionIdx];
462 				region.bufferOffset += stencilOffset;
463 
464 				copyRegions.push_back(region);
465 			}
466 		}
467 
468 		flushAlloc(vk, device, *bufferAlloc);
469 	}
470 
471 	copyBufferToImage(vk, device, queue, queueFamilyIndex, *buffer, bufferSize, copyRegions, DE_NULL, imageAspectFlags, srcTexture.getNumLevels(), srcTexture.getArraySize(), destImage);
472 }
473 
checkSparseImageFormatSupport(const VkPhysicalDevice physicalDevice,const InstanceInterface & instance,const VkImageCreateInfo & imageCreateInfo)474 bool checkSparseImageFormatSupport (const VkPhysicalDevice		physicalDevice,
475 									const InstanceInterface&	instance,
476 									const VkImageCreateInfo&	imageCreateInfo)
477 {
478 	const std::vector<VkSparseImageFormatProperties> sparseImageFormatPropVec =
479 		getPhysicalDeviceSparseImageFormatProperties(instance, physicalDevice, imageCreateInfo.format, imageCreateInfo.imageType, imageCreateInfo.samples, imageCreateInfo.usage, imageCreateInfo.tiling);
480 
481 	return (sparseImageFormatPropVec.size() != 0);
482 }
483 
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)484 void uploadTestTextureInternalSparse (const DeviceInterface&					vk,
485 									  VkDevice									device,
486 									  const VkPhysicalDevice					physicalDevice,
487 									  const InstanceInterface&					instance,
488 									  const VkImageCreateInfo&					imageCreateInfo,
489 									  VkQueue									universalQueue,
490 									  deUint32									universalQueueFamilyIndex,
491 									  VkQueue									sparseQueue,
492 									  Allocator&								allocator,
493 									  std::vector<de::SharedPtr<Allocation> >&	allocations,
494 									  const TestTexture&						srcTexture,
495 									  const TestTexture*						srcStencilTexture,
496 									  tcu::TextureFormat						format,
497 									  VkImage									destImage)
498 {
499 	deUint32						bufferSize				= (srcTexture.isCompressed()) ? srcTexture.getCompressedSize(): srcTexture.getSize();
500 	const VkImageAspectFlags		imageAspectFlags		= getImageAspectFlags(format);
501 	deUint32						stencilOffset			= 0u;
502 	const Unique<VkSemaphore>		imageMemoryBindSemaphore(createSemaphore(vk, device));
503 	Move<VkCommandPool>				cmdPool					= createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, universalQueueFamilyIndex);
504 	Move<VkCommandBuffer>			cmdBuffer				= allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
505 	Move<VkFence>					fence					= createFence(vk, device);
506 	std::vector<VkBufferImageCopy>	copyRegions				= srcTexture.getBufferCopyRegions();
507 	Move<VkBuffer>					buffer;
508 	de::MovePtr<Allocation>			bufferAlloc;
509 
510 	// Stencil-only texture should be provided if (and only if) the image has a combined DS format
511 	DE_ASSERT((tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order)) == (srcStencilTexture != DE_NULL));
512 
513 	if (srcStencilTexture != DE_NULL)
514 	{
515 		stencilOffset	= static_cast<deUint32>(deAlign32(static_cast<deInt32>(bufferSize), 4));
516 		bufferSize		= stencilOffset + srcStencilTexture->getSize();
517 	}
518 
519 	allocateAndBindSparseImage (vk, device, physicalDevice, instance, imageCreateInfo, imageMemoryBindSemaphore.get(), sparseQueue, allocator, allocations, format, destImage);
520 
521 	{
522 		// Create source buffer
523 		const VkBufferCreateInfo bufferParams =
524 		{
525 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
526 			DE_NULL,									// const void*			pNext;
527 			0u,											// VkBufferCreateFlags	flags;
528 			bufferSize,									// VkDeviceSize			size;
529 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
530 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
531 			0u,											// deUint32				queueFamilyIndexCount;
532 			DE_NULL,									// const deUint32*		pQueueFamilyIndices;
533 		};
534 
535 		buffer		= createBuffer(vk, device, &bufferParams);
536 		bufferAlloc	= allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
537 
538 		VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
539 	}
540 
541 	{
542 		// Write buffer data
543 		srcTexture.write(reinterpret_cast<deUint8*>(bufferAlloc->getHostPtr()));
544 
545 		if (srcStencilTexture != DE_NULL)
546 		{
547 			DE_ASSERT(stencilOffset != 0u);
548 
549 			srcStencilTexture->write(reinterpret_cast<deUint8*>(bufferAlloc->getHostPtr()) + stencilOffset);
550 
551 			std::vector<VkBufferImageCopy>	stencilCopyRegions = srcStencilTexture->getBufferCopyRegions();
552 			for (size_t regionIdx = 0; regionIdx < stencilCopyRegions.size(); regionIdx++)
553 			{
554 				VkBufferImageCopy region = stencilCopyRegions[regionIdx];
555 				region.bufferOffset += stencilOffset;
556 
557 				copyRegions.push_back(region);
558 			}
559 		}
560 
561 		flushAlloc(vk, device, *bufferAlloc);
562 	}
563 
564 	copyBufferToImage(vk, device, universalQueue, universalQueueFamilyIndex, *buffer, bufferSize, copyRegions, &(*imageMemoryBindSemaphore), imageAspectFlags, imageCreateInfo.mipLevels, imageCreateInfo.arrayLayers, destImage);
565 }
566 
uploadTestTexture(const DeviceInterface & vk,VkDevice device,VkQueue queue,deUint32 queueFamilyIndex,Allocator & allocator,const TestTexture & srcTexture,VkImage destImage)567 void uploadTestTexture (const DeviceInterface&			vk,
568 						VkDevice						device,
569 						VkQueue							queue,
570 						deUint32						queueFamilyIndex,
571 						Allocator&						allocator,
572 						const TestTexture&				srcTexture,
573 						VkImage							destImage)
574 {
575 	if (tcu::isCombinedDepthStencilType(srcTexture.getTextureFormat().type))
576 	{
577 		de::MovePtr<TestTexture> srcDepthTexture;
578 		de::MovePtr<TestTexture> srcStencilTexture;
579 
580 		if (tcu::hasDepthComponent(srcTexture.getTextureFormat().order))
581 		{
582 			tcu::TextureFormat format;
583 			switch (srcTexture.getTextureFormat().type)
584 			{
585 				case tcu::TextureFormat::UNSIGNED_INT_16_8_8:
586 					format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
587 					break;
588 				case tcu::TextureFormat::UNSIGNED_INT_24_8_REV:
589 					format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8_REV);
590 					break;
591 				case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
592 					format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
593 					break;
594 				default:
595 					DE_FATAL("Unexpected source texture format.");
596 					break;
597 			}
598 			srcDepthTexture = srcTexture.copy(format);
599 		}
600 
601 		if (tcu::hasStencilComponent(srcTexture.getTextureFormat().order))
602 			srcStencilTexture = srcTexture.copy(tcu::getEffectiveDepthStencilTextureFormat(srcTexture.getTextureFormat(), tcu::Sampler::MODE_STENCIL));
603 
604 		uploadTestTextureInternal(vk, device, queue, queueFamilyIndex, allocator, *srcDepthTexture, srcStencilTexture.get(), srcTexture.getTextureFormat(), destImage);
605 	}
606 	else
607 		uploadTestTextureInternal(vk, device, queue, queueFamilyIndex, allocator, srcTexture, DE_NULL, srcTexture.getTextureFormat(), destImage);
608 }
609 
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)610 void uploadTestTextureSparse (const DeviceInterface&					vk,
611 							  VkDevice									device,
612 							  const VkPhysicalDevice					physicalDevice,
613 							  const InstanceInterface&					instance,
614 							  const VkImageCreateInfo&					imageCreateInfo,
615 							  VkQueue									universalQueue,
616 							  deUint32									universalQueueFamilyIndex,
617 							  VkQueue									sparseQueue,
618 							  Allocator&								allocator,
619 							  std::vector<de::SharedPtr<Allocation> >&	allocations,
620 							  const TestTexture&						srcTexture,
621 							  VkImage									destImage)
622 {
623 	if (tcu::isCombinedDepthStencilType(srcTexture.getTextureFormat().type))
624 	{
625 		de::MovePtr<TestTexture> srcDepthTexture;
626 		de::MovePtr<TestTexture> srcStencilTexture;
627 
628 		if (tcu::hasDepthComponent(srcTexture.getTextureFormat().order))
629 		{
630 			tcu::TextureFormat format;
631 			switch (srcTexture.getTextureFormat().type)
632 			{
633 				case tcu::TextureFormat::UNSIGNED_INT_16_8_8:
634 					format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
635 					break;
636 				case tcu::TextureFormat::UNSIGNED_INT_24_8_REV:
637 					format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8_REV);
638 					break;
639 				case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
640 					format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
641 					break;
642 				default:
643 					DE_FATAL("Unexpected source texture format.");
644 					break;
645 			}
646 			srcDepthTexture = srcTexture.copy(format);
647 		}
648 
649 		if (tcu::hasStencilComponent(srcTexture.getTextureFormat().order))
650 			srcStencilTexture = srcTexture.copy(tcu::getEffectiveDepthStencilTextureFormat(srcTexture.getTextureFormat(), tcu::Sampler::MODE_STENCIL));
651 
652 		uploadTestTextureInternalSparse	(vk,
653 										 device,
654 										 physicalDevice,
655 										 instance,
656 										 imageCreateInfo,
657 										 universalQueue,
658 										 universalQueueFamilyIndex,
659 										 sparseQueue,
660 										 allocator,
661 										 allocations,
662 										 *srcDepthTexture,
663 										 srcStencilTexture.get(),
664 										 srcTexture.getTextureFormat(),
665 										 destImage);
666 	}
667 	else
668 	{
669 		uploadTestTextureInternalSparse	(vk,
670 										 device,
671 										 physicalDevice,
672 										 instance,
673 										 imageCreateInfo,
674 										 universalQueue,
675 										 universalQueueFamilyIndex,
676 										 sparseQueue,
677 										 allocator,
678 										 allocations,
679 										 srcTexture,
680 										 DE_NULL,
681 										 srcTexture.getTextureFormat(),
682 										 destImage);
683 	}
684 }
685 
686 // Utilities for test textures
687 
688 template<typename TcuTextureType>
allocateLevels(TcuTextureType & texture)689 void allocateLevels (TcuTextureType& texture)
690 {
691 	for (int levelNdx = 0; levelNdx < texture.getNumLevels(); levelNdx++)
692 		texture.allocLevel(levelNdx);
693 }
694 
695 template<typename TcuTextureType>
getLevelsVector(const TcuTextureType & texture)696 std::vector<tcu::PixelBufferAccess> getLevelsVector (const TcuTextureType& texture)
697 {
698 	std::vector<tcu::PixelBufferAccess> levels(texture.getNumLevels());
699 
700 	for (int levelNdx = 0; levelNdx < texture.getNumLevels(); levelNdx++)
701 		levels[levelNdx] = *reinterpret_cast<const tcu::PixelBufferAccess*>(&texture.getLevel(levelNdx));
702 
703 	return levels;
704 }
705 
706 // TestTexture
707 
TestTexture(const tcu::TextureFormat & format,int width,int height,int depth)708 TestTexture::TestTexture (const tcu::TextureFormat& format, int width, int height, int depth)
709 {
710 	DE_ASSERT(width >= 1);
711 	DE_ASSERT(height >= 1);
712 	DE_ASSERT(depth >= 1);
713 
714 	DE_UNREF(format);
715 	DE_UNREF(width);
716 	DE_UNREF(height);
717 	DE_UNREF(depth);
718 }
719 
TestTexture(const tcu::CompressedTexFormat & format,int width,int height,int depth)720 TestTexture::TestTexture (const tcu::CompressedTexFormat& format, int width, int height, int depth)
721 {
722 	DE_ASSERT(width >= 1);
723 	DE_ASSERT(height >= 1);
724 	DE_ASSERT(depth >= 1);
725 
726 	DE_UNREF(format);
727 	DE_UNREF(width);
728 	DE_UNREF(height);
729 	DE_UNREF(depth);
730 }
731 
~TestTexture(void)732 TestTexture::~TestTexture (void)
733 {
734 	for (size_t levelNdx = 0; levelNdx < m_compressedLevels.size(); levelNdx++)
735 		delete m_compressedLevels[levelNdx];
736 }
737 
getSize(void) const738 deUint32 TestTexture::getSize (void) const
739 {
740 	std::vector<deUint32>	offsetMultiples;
741 	deUint32				textureSize = 0;
742 
743 	offsetMultiples.push_back(4);
744 	offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
745 
746 	for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
747 	{
748 		for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
749 		{
750 			const tcu::ConstPixelBufferAccess level = getLevel(levelNdx, layerNdx);
751 			textureSize = getNextMultiple(offsetMultiples, textureSize);
752 			textureSize += level.getWidth() * level.getHeight() * level.getDepth() * level.getFormat().getPixelSize();
753 		}
754 	}
755 
756 	return textureSize;
757 }
758 
getCompressedSize(void) const759 deUint32 TestTexture::getCompressedSize (void) const
760 {
761 	if (!isCompressed())
762 		throw tcu::InternalError("Texture is not compressed");
763 
764 	std::vector<deUint32>	offsetMultiples;
765 	deUint32				textureSize			= 0;
766 
767 	offsetMultiples.push_back(4);
768 	offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
769 
770 	for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
771 	{
772 		for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
773 		{
774 			textureSize = getNextMultiple(offsetMultiples, textureSize);
775 			textureSize += getCompressedLevel(levelNdx, layerNdx).getDataSize();
776 		}
777 	}
778 
779 	return textureSize;
780 }
781 
getCompressedLevel(int level,int layer)782 tcu::CompressedTexture& TestTexture::getCompressedLevel (int level, int layer)
783 {
784 	DE_ASSERT(level >= 0 && level < getNumLevels());
785 	DE_ASSERT(layer >= 0 && layer < getArraySize());
786 
787 	return *m_compressedLevels[level * getArraySize() + layer];
788 }
789 
getCompressedLevel(int level,int layer) const790 const tcu::CompressedTexture& TestTexture::getCompressedLevel (int level, int layer) const
791 {
792 	DE_ASSERT(level >= 0 && level < getNumLevels());
793 	DE_ASSERT(layer >= 0 && layer < getArraySize());
794 
795 	return *m_compressedLevels[level * getArraySize() + layer];
796 }
797 
getBufferCopyRegions(void) const798 std::vector<VkBufferImageCopy> TestTexture::getBufferCopyRegions (void) const
799 {
800 	std::vector<deUint32>			offsetMultiples;
801 	std::vector<VkBufferImageCopy>	regions;
802 	deUint32						layerDataOffset = 0;
803 
804 	offsetMultiples.push_back(4);
805 
806 	if (isCompressed())
807 	{
808 		offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
809 
810 		for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
811 		{
812 			for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
813 			{
814 				const tcu::CompressedTexture& level = getCompressedLevel(levelNdx, layerNdx);
815 				tcu::IVec3 blockPixelSize			= getBlockPixelSize(level.getFormat());
816 				layerDataOffset						= getNextMultiple(offsetMultiples, layerDataOffset);
817 
818 				const VkBufferImageCopy layerRegion =
819 				{
820 					layerDataOffset,													// VkDeviceSize				bufferOffset;
821 					(deUint32)getNextMultiple(blockPixelSize.x(), level.getWidth()),	// deUint32					bufferRowLength;
822 					(deUint32)getNextMultiple(blockPixelSize.y(), level.getHeight()),	// deUint32					bufferImageHeight;
823 					{																	// VkImageSubresourceLayers	imageSubresource;
824 						VK_IMAGE_ASPECT_COLOR_BIT,
825 						(deUint32)levelNdx,
826 						(deUint32)layerNdx,
827 						1u
828 					},
829 					{ 0u, 0u, 0u },							// VkOffset3D				imageOffset;
830 					{										// VkExtent3D				imageExtent;
831 						(deUint32)level.getWidth(),
832 						(deUint32)level.getHeight(),
833 						(deUint32)level.getDepth()
834 					}
835 				};
836 
837 				regions.push_back(layerRegion);
838 				layerDataOffset += level.getDataSize();
839 			}
840 		}
841 	}
842 	else
843 	{
844 		std::vector<VkImageAspectFlags>	imageAspects;
845 		tcu::TextureFormat				textureFormat	= getTextureFormat();
846 
847 		if (tcu::hasDepthComponent(textureFormat.order))
848 			imageAspects.push_back(VK_IMAGE_ASPECT_DEPTH_BIT);
849 
850 		if (tcu::hasStencilComponent(textureFormat.order))
851 			imageAspects.push_back(VK_IMAGE_ASPECT_STENCIL_BIT);
852 
853 		if (imageAspects.empty())
854 			imageAspects.push_back(VK_IMAGE_ASPECT_COLOR_BIT);
855 
856 		offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
857 
858 		for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
859 		{
860 			for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
861 			{
862 				const tcu::ConstPixelBufferAccess level = getLevel(levelNdx, layerNdx);
863 
864 				layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset);
865 
866 				for (size_t aspectIndex = 0; aspectIndex < imageAspects.size(); ++aspectIndex)
867 				{
868 					const VkBufferImageCopy layerRegion =
869 					{
870 						layerDataOffset,						// VkDeviceSize				bufferOffset;
871 						(deUint32)level.getWidth(),				// deUint32					bufferRowLength;
872 						(deUint32)level.getHeight(),			// deUint32					bufferImageHeight;
873 						{										// VkImageSubresourceLayers	imageSubresource;
874 							imageAspects[aspectIndex],
875 							(deUint32)levelNdx,
876 							(deUint32)layerNdx,
877 							1u
878 						},
879 						{ 0u, 0u, 0u },							// VkOffset3D			imageOffset;
880 						{										// VkExtent3D			imageExtent;
881 							(deUint32)level.getWidth(),
882 							(deUint32)level.getHeight(),
883 							(deUint32)level.getDepth()
884 						}
885 					};
886 
887 					regions.push_back(layerRegion);
888 				}
889 				layerDataOffset += level.getWidth() * level.getHeight() * level.getDepth() * level.getFormat().getPixelSize();
890 			}
891 		}
892 	}
893 
894 	return regions;
895 }
896 
write(deUint8 * destPtr) const897 void TestTexture::write (deUint8* destPtr) const
898 {
899 	std::vector<deUint32>	offsetMultiples;
900 	deUint32				levelOffset		= 0;
901 
902 	offsetMultiples.push_back(4);
903 
904 	if (isCompressed())
905 	{
906 		offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
907 
908 		for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
909 		{
910 			for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
911 			{
912 				levelOffset = getNextMultiple(offsetMultiples, levelOffset);
913 
914 				const tcu::CompressedTexture&		compressedTex	= getCompressedLevel(levelNdx, layerNdx);
915 
916 				deMemcpy(destPtr + levelOffset, compressedTex.getData(), compressedTex.getDataSize());
917 				levelOffset += compressedTex.getDataSize();
918 			}
919 		}
920 	}
921 	else
922 	{
923 		offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
924 
925 		for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
926 		{
927 			for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
928 			{
929 				levelOffset = getNextMultiple(offsetMultiples, levelOffset);
930 
931 				const tcu::ConstPixelBufferAccess	srcAccess		= getLevel(levelNdx, layerNdx);
932 				const tcu::PixelBufferAccess		destAccess		(srcAccess.getFormat(), srcAccess.getSize(), srcAccess.getPitch(), destPtr + levelOffset);
933 
934 				tcu::copy(destAccess, srcAccess);
935 				levelOffset += srcAccess.getWidth() * srcAccess.getHeight() * srcAccess.getDepth() * srcAccess.getFormat().getPixelSize();
936 			}
937 		}
938 	}
939 }
940 
copyToTexture(TestTexture & destTexture) const941 void TestTexture::copyToTexture (TestTexture& destTexture) const
942 {
943 	for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
944 		for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
945 			tcu::copy(destTexture.getLevel(levelNdx, layerNdx), getLevel(levelNdx, layerNdx));
946 }
947 
populateLevels(const std::vector<tcu::PixelBufferAccess> & levels)948 void TestTexture::populateLevels (const std::vector<tcu::PixelBufferAccess>& levels)
949 {
950 	for (size_t levelNdx = 0; levelNdx < levels.size(); levelNdx++)
951 		TestTexture::fillWithGradient(levels[levelNdx]);
952 }
953 
populateCompressedLevels(tcu::CompressedTexFormat format,const std::vector<tcu::PixelBufferAccess> & decompressedLevels)954 void TestTexture::populateCompressedLevels (tcu::CompressedTexFormat format, const std::vector<tcu::PixelBufferAccess>& decompressedLevels)
955 {
956 	// Generate random compressed data and update decompressed data
957 
958 	de::Random random(123);
959 
960 	for (size_t levelNdx = 0; levelNdx < decompressedLevels.size(); levelNdx++)
961 	{
962 		const tcu::PixelBufferAccess	level				= decompressedLevels[levelNdx];
963 		tcu::CompressedTexture*			compressedLevel		= new tcu::CompressedTexture(format, level.getWidth(), level.getHeight(), level.getDepth());
964 		deUint8* const					compressedData		= (deUint8*)compressedLevel->getData();
965 
966 		if (tcu::isAstcFormat(format))
967 		{
968 			// \todo [2016-01-20 pyry] Comparison doesn't currently handle invalid blocks correctly so we use only valid blocks
969 			tcu::astc::generateRandomValidBlocks(compressedData, compressedLevel->getDataSize()/tcu::astc::BLOCK_SIZE_BYTES,
970 												 format, tcu::TexDecompressionParams::ASTCMODE_LDR, random.getUint32());
971 		}
972 		else
973 		{
974 			// Generate random compressed data
975 			// Random initial values cause assertion during the decompression in case of COMPRESSEDTEXFORMAT_ETC1_RGB8 format
976 			if (format != tcu::COMPRESSEDTEXFORMAT_ETC1_RGB8)
977 				for (int byteNdx = 0; byteNdx < compressedLevel->getDataSize(); byteNdx++)
978 					compressedData[byteNdx] = 0xFF & random.getUint32();
979 		}
980 
981 		m_compressedLevels.push_back(compressedLevel);
982 
983 		// Store decompressed data
984 		compressedLevel->decompress(level, tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR));
985 	}
986 }
987 
fillWithGradient(const tcu::PixelBufferAccess & levelAccess)988 void TestTexture::fillWithGradient (const tcu::PixelBufferAccess& levelAccess)
989 {
990 	const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(levelAccess.getFormat());
991 	tcu::fillWithComponentGradients2(levelAccess, formatInfo.valueMin, formatInfo.valueMax);
992 }
993 
994 // TestTexture1D
995 
TestTexture1D(const tcu::TextureFormat & format,int width)996 TestTexture1D::TestTexture1D (const tcu::TextureFormat& format, int width)
997 	: TestTexture	(format, width, 1, 1)
998 	, m_texture		(format, width)
999 {
1000 	allocateLevels(m_texture);
1001 	TestTexture::populateLevels(getLevelsVector(m_texture));
1002 }
1003 
TestTexture1D(const tcu::CompressedTexFormat & format,int width)1004 TestTexture1D::TestTexture1D (const tcu::CompressedTexFormat& format, int width)
1005 	: TestTexture	(format, width, 1, 1)
1006 	, m_texture		(tcu::getUncompressedFormat(format), width)
1007 {
1008 	allocateLevels(m_texture);
1009 	TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
1010 }
1011 
~TestTexture1D(void)1012 TestTexture1D::~TestTexture1D (void)
1013 {
1014 }
1015 
getNumLevels(void) const1016 int TestTexture1D::getNumLevels (void) const
1017 {
1018 	return m_texture.getNumLevels();
1019 }
1020 
getLevel(int level,int layer)1021 tcu::PixelBufferAccess TestTexture1D::getLevel (int level, int layer)
1022 {
1023 	DE_ASSERT(layer == 0);
1024 	DE_UNREF(layer);
1025 	return m_texture.getLevel(level);
1026 }
1027 
getLevel(int level,int layer) const1028 const tcu::ConstPixelBufferAccess TestTexture1D::getLevel (int level, int layer) const
1029 {
1030 	DE_ASSERT(layer == 0);
1031 	DE_UNREF(layer);
1032 	return m_texture.getLevel(level);
1033 }
1034 
getTexture(void) const1035 const tcu::Texture1D& TestTexture1D::getTexture (void) const
1036 {
1037 	return m_texture;
1038 }
1039 
getTexture(void)1040 tcu::Texture1D& TestTexture1D::getTexture (void)
1041 {
1042 	return m_texture;
1043 }
1044 
copy(const tcu::TextureFormat format) const1045 de::MovePtr<TestTexture> TestTexture1D::copy(const tcu::TextureFormat format) const
1046 {
1047 	DE_ASSERT(!isCompressed());
1048 
1049 	de::MovePtr<TestTexture>	texture	(new TestTexture1D(format, m_texture.getWidth()));
1050 
1051 	copyToTexture(*texture);
1052 
1053 	return texture;
1054 }
1055 
1056 // TestTexture1DArray
1057 
TestTexture1DArray(const tcu::TextureFormat & format,int width,int arraySize)1058 TestTexture1DArray::TestTexture1DArray (const tcu::TextureFormat& format, int width, int arraySize)
1059 	: TestTexture	(format, width, arraySize, 1)
1060 	, m_texture		(format, width, arraySize)
1061 {
1062 	allocateLevels(m_texture);
1063 	TestTexture::populateLevels(getLevelsVector(m_texture));
1064 }
1065 
TestTexture1DArray(const tcu::CompressedTexFormat & format,int width,int arraySize)1066 TestTexture1DArray::TestTexture1DArray (const tcu::CompressedTexFormat& format, int width, int arraySize)
1067 	: TestTexture	(format, width, arraySize, 1)
1068 	, m_texture		(tcu::getUncompressedFormat(format), width, arraySize)
1069 {
1070 	allocateLevels(m_texture);
1071 
1072 	std::vector<tcu::PixelBufferAccess> layers;
1073 	for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
1074 		for (int layerNdx = 0; layerNdx < m_texture.getNumLayers(); layerNdx++)
1075 			layers.push_back(getLevel(levelNdx, layerNdx));
1076 
1077 	TestTexture::populateCompressedLevels(format, layers);
1078 }
1079 
~TestTexture1DArray(void)1080 TestTexture1DArray::~TestTexture1DArray (void)
1081 {
1082 }
1083 
getNumLevels(void) const1084 int TestTexture1DArray::getNumLevels (void) const
1085 {
1086 	return m_texture.getNumLevels();
1087 }
1088 
getLevel(int level,int layer)1089 tcu::PixelBufferAccess TestTexture1DArray::getLevel (int level, int layer)
1090 {
1091 	const tcu::PixelBufferAccess	levelLayers	= m_texture.getLevel(level);
1092 	const deUint32					layerSize	= levelLayers.getWidth() * levelLayers.getFormat().getPixelSize();
1093 	const deUint32					layerOffset	= layerSize * layer;
1094 
1095 	return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1096 }
1097 
getLevel(int level,int layer) const1098 const tcu::ConstPixelBufferAccess TestTexture1DArray::getLevel (int level, int layer) const
1099 {
1100 	const tcu::ConstPixelBufferAccess	levelLayers	= m_texture.getLevel(level);
1101 	const deUint32						layerSize	= levelLayers.getWidth() * levelLayers.getFormat().getPixelSize();
1102 	const deUint32						layerOffset	= layerSize * layer;
1103 
1104 	return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1105 }
1106 
getTexture(void) const1107 const tcu::Texture1DArray& TestTexture1DArray::getTexture (void) const
1108 {
1109 	return m_texture;
1110 }
1111 
getTexture(void)1112 tcu::Texture1DArray& TestTexture1DArray::getTexture (void)
1113 {
1114 	return m_texture;
1115 }
1116 
getArraySize(void) const1117 int TestTexture1DArray::getArraySize (void) const
1118 {
1119 	return m_texture.getNumLayers();
1120 }
1121 
copy(const tcu::TextureFormat format) const1122 de::MovePtr<TestTexture> TestTexture1DArray::copy(const tcu::TextureFormat format) const
1123 {
1124 	DE_ASSERT(!isCompressed());
1125 
1126 	de::MovePtr<TestTexture>	texture	(new TestTexture1DArray(format, m_texture.getWidth(), getArraySize()));
1127 
1128 	copyToTexture(*texture);
1129 
1130 	return texture;
1131 }
1132 
1133 // TestTexture2D
1134 
TestTexture2D(const tcu::TextureFormat & format,int width,int height)1135 TestTexture2D::TestTexture2D (const tcu::TextureFormat& format, int width, int height)
1136 	: TestTexture	(format, width, height, 1)
1137 	, m_texture		(format, width, height)
1138 {
1139 	allocateLevels(m_texture);
1140 	TestTexture::populateLevels(getLevelsVector(m_texture));
1141 }
1142 
TestTexture2D(const tcu::TextureFormat & format,int width,int height,int miplevels)1143 TestTexture2D::TestTexture2D (const tcu::TextureFormat& format, int width, int height, int miplevels)
1144 	: TestTexture(format, width, height, 1)
1145 	, m_texture(format, width, height, miplevels)
1146 {
1147 	allocateLevels(m_texture);
1148 	TestTexture::populateLevels(getLevelsVector(m_texture));
1149 }
1150 
1151 
TestTexture2D(const tcu::CompressedTexFormat & format,int width,int height)1152 TestTexture2D::TestTexture2D (const tcu::CompressedTexFormat& format, int width, int height)
1153 	: TestTexture	(format, width, height, 1)
1154 	, m_texture		(tcu::getUncompressedFormat(format), width, height)
1155 {
1156 	allocateLevels(m_texture);
1157 	TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
1158 }
1159 
~TestTexture2D(void)1160 TestTexture2D::~TestTexture2D (void)
1161 {
1162 }
1163 
getNumLevels(void) const1164 int TestTexture2D::getNumLevels (void) const
1165 {
1166 	return m_texture.getNumLevels();
1167 }
1168 
getLevel(int level,int layer)1169 tcu::PixelBufferAccess TestTexture2D::getLevel (int level, int layer)
1170 {
1171 	DE_ASSERT(layer == 0);
1172 	DE_UNREF(layer);
1173 	return m_texture.getLevel(level);
1174 }
1175 
getLevel(int level,int layer) const1176 const tcu::ConstPixelBufferAccess TestTexture2D::getLevel (int level, int layer) const
1177 {
1178 	DE_ASSERT(layer == 0);
1179 	DE_UNREF(layer);
1180 	return m_texture.getLevel(level);
1181 }
1182 
getTexture(void) const1183 const tcu::Texture2D& TestTexture2D::getTexture (void) const
1184 {
1185 	return m_texture;
1186 }
1187 
getTexture(void)1188 tcu::Texture2D& TestTexture2D::getTexture (void)
1189 {
1190 	return m_texture;
1191 }
1192 
copy(const tcu::TextureFormat format) const1193 de::MovePtr<TestTexture> TestTexture2D::copy(const tcu::TextureFormat format) const
1194 {
1195 	DE_ASSERT(!isCompressed());
1196 
1197 	de::MovePtr<TestTexture>	texture	(new TestTexture2D(format, m_texture.getWidth(), m_texture.getHeight(), m_texture.getNumLevels()));
1198 
1199 	copyToTexture(*texture);
1200 
1201 	return texture;
1202 }
1203 
1204 // TestTexture2DArray
1205 
TestTexture2DArray(const tcu::TextureFormat & format,int width,int height,int arraySize)1206 TestTexture2DArray::TestTexture2DArray (const tcu::TextureFormat& format, int width, int height, int arraySize)
1207 	: TestTexture	(format, width, height, arraySize)
1208 	, m_texture		(format, width, height, arraySize)
1209 {
1210 	allocateLevels(m_texture);
1211 	TestTexture::populateLevels(getLevelsVector(m_texture));
1212 }
1213 
TestTexture2DArray(const tcu::CompressedTexFormat & format,int width,int height,int arraySize)1214 TestTexture2DArray::TestTexture2DArray (const tcu::CompressedTexFormat& format, int width, int height, int arraySize)
1215 	: TestTexture	(format, width, height, arraySize)
1216 	, m_texture		(tcu::getUncompressedFormat(format), width, height, arraySize)
1217 {
1218 	allocateLevels(m_texture);
1219 
1220 	std::vector<tcu::PixelBufferAccess> layers;
1221 	for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
1222 		for (int layerNdx = 0; layerNdx < m_texture.getNumLayers(); layerNdx++)
1223 			layers.push_back(getLevel(levelNdx, layerNdx));
1224 
1225 	TestTexture::populateCompressedLevels(format, layers);
1226 }
1227 
~TestTexture2DArray(void)1228 TestTexture2DArray::~TestTexture2DArray (void)
1229 {
1230 }
1231 
getNumLevels(void) const1232 int TestTexture2DArray::getNumLevels (void) const
1233 {
1234 	return m_texture.getNumLevels();
1235 }
1236 
getLevel(int level,int layer)1237 tcu::PixelBufferAccess TestTexture2DArray::getLevel (int level, int layer)
1238 {
1239 	const tcu::PixelBufferAccess	levelLayers	= m_texture.getLevel(level);
1240 	const deUint32					layerSize	= levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1241 	const deUint32					layerOffset	= layerSize * layer;
1242 
1243 	return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1244 }
1245 
getLevel(int level,int layer) const1246 const tcu::ConstPixelBufferAccess TestTexture2DArray::getLevel (int level, int layer) const
1247 {
1248 	const tcu::ConstPixelBufferAccess	levelLayers	= m_texture.getLevel(level);
1249 	const deUint32						layerSize	= levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1250 	const deUint32						layerOffset	= layerSize * layer;
1251 
1252 	return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1253 }
1254 
getTexture(void) const1255 const tcu::Texture2DArray& TestTexture2DArray::getTexture (void) const
1256 {
1257 	return m_texture;
1258 }
1259 
getTexture(void)1260 tcu::Texture2DArray& TestTexture2DArray::getTexture (void)
1261 {
1262 	return m_texture;
1263 }
1264 
getArraySize(void) const1265 int TestTexture2DArray::getArraySize (void) const
1266 {
1267 	return m_texture.getNumLayers();
1268 }
1269 
copy(const tcu::TextureFormat format) const1270 de::MovePtr<TestTexture> TestTexture2DArray::copy(const tcu::TextureFormat format) const
1271 {
1272 	DE_ASSERT(!isCompressed());
1273 
1274 	de::MovePtr<TestTexture>	texture	(new TestTexture2DArray(format, m_texture.getWidth(), m_texture.getHeight(), getArraySize()));
1275 
1276 	copyToTexture(*texture);
1277 
1278 	return texture;
1279 }
1280 
1281 // TestTexture3D
1282 
TestTexture3D(const tcu::TextureFormat & format,int width,int height,int depth)1283 TestTexture3D::TestTexture3D (const tcu::TextureFormat& format, int width, int height, int depth)
1284 	: TestTexture	(format, width, height, depth)
1285 	, m_texture		(format, width, height, depth)
1286 {
1287 	allocateLevels(m_texture);
1288 	TestTexture::populateLevels(getLevelsVector(m_texture));
1289 }
1290 
TestTexture3D(const tcu::CompressedTexFormat & format,int width,int height,int depth)1291 TestTexture3D::TestTexture3D (const tcu::CompressedTexFormat& format, int width, int height, int depth)
1292 	: TestTexture	(format, width, height, depth)
1293 	, m_texture		(tcu::getUncompressedFormat(format), width, height, depth)
1294 {
1295 	allocateLevels(m_texture);
1296 	TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
1297 }
1298 
~TestTexture3D(void)1299 TestTexture3D::~TestTexture3D (void)
1300 {
1301 }
1302 
getNumLevels(void) const1303 int TestTexture3D::getNumLevels (void) const
1304 {
1305 	return m_texture.getNumLevels();
1306 }
1307 
getLevel(int level,int layer)1308 tcu::PixelBufferAccess TestTexture3D::getLevel (int level, int layer)
1309 {
1310 	DE_ASSERT(layer == 0);
1311 	DE_UNREF(layer);
1312 	return m_texture.getLevel(level);
1313 }
1314 
getLevel(int level,int layer) const1315 const tcu::ConstPixelBufferAccess TestTexture3D::getLevel (int level, int layer) const
1316 {
1317 	DE_ASSERT(layer == 0);
1318 	DE_UNREF(layer);
1319 	return m_texture.getLevel(level);
1320 }
1321 
getTexture(void) const1322 const tcu::Texture3D& TestTexture3D::getTexture (void) const
1323 {
1324 	return m_texture;
1325 }
1326 
getTexture(void)1327 tcu::Texture3D& TestTexture3D::getTexture (void)
1328 {
1329 	return m_texture;
1330 }
1331 
copy(const tcu::TextureFormat format) const1332 de::MovePtr<TestTexture> TestTexture3D::copy(const tcu::TextureFormat format) const
1333 {
1334 	DE_ASSERT(!isCompressed());
1335 
1336 	de::MovePtr<TestTexture>	texture	(new TestTexture3D(format, m_texture.getWidth(), m_texture.getHeight(), m_texture.getDepth()));
1337 
1338 	copyToTexture(*texture);
1339 
1340 	return texture;
1341 }
1342 
1343 // TestTextureCube
1344 
1345 const static tcu::CubeFace tcuFaceMapping[tcu::CUBEFACE_LAST] =
1346 {
1347 	tcu::CUBEFACE_POSITIVE_X,
1348 	tcu::CUBEFACE_NEGATIVE_X,
1349 	tcu::CUBEFACE_POSITIVE_Y,
1350 	tcu::CUBEFACE_NEGATIVE_Y,
1351 	tcu::CUBEFACE_POSITIVE_Z,
1352 	tcu::CUBEFACE_NEGATIVE_Z
1353 };
1354 
TestTextureCube(const tcu::TextureFormat & format,int size)1355 TestTextureCube::TestTextureCube (const tcu::TextureFormat& format, int size)
1356 	: TestTexture	(format, size, size, 1)
1357 	, m_texture		(format, size)
1358 {
1359 	for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
1360 	{
1361 		for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
1362 		{
1363 			m_texture.allocLevel(tcuFaceMapping[faceNdx], levelNdx);
1364 			TestTexture::fillWithGradient(m_texture.getLevelFace(levelNdx, tcuFaceMapping[faceNdx]));
1365 		}
1366 	}
1367 }
1368 
TestTextureCube(const tcu::CompressedTexFormat & format,int size)1369 TestTextureCube::TestTextureCube (const tcu::CompressedTexFormat& format, int size)
1370 	: TestTexture	(format, size, size, 1)
1371 	, m_texture		(tcu::getUncompressedFormat(format), size)
1372 {
1373 	std::vector<tcu::PixelBufferAccess> levels(m_texture.getNumLevels() * tcu::CUBEFACE_LAST);
1374 
1375 	for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
1376 	{
1377 		for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
1378 		{
1379 			m_texture.allocLevel(tcuFaceMapping[faceNdx], levelNdx);
1380 			levels[levelNdx * tcu::CUBEFACE_LAST + faceNdx] = m_texture.getLevelFace(levelNdx, tcuFaceMapping[faceNdx]);
1381 		}
1382 	}
1383 
1384 	TestTexture::populateCompressedLevels(format, levels);
1385 }
1386 
~TestTextureCube(void)1387 TestTextureCube::~TestTextureCube (void)
1388 {
1389 }
1390 
getNumLevels(void) const1391 int TestTextureCube::getNumLevels (void) const
1392 {
1393 	return m_texture.getNumLevels();
1394 }
1395 
getLevel(int level,int layer)1396 tcu::PixelBufferAccess TestTextureCube::getLevel (int level, int layer)
1397 {
1398 	return m_texture.getLevelFace(level, tcuFaceMapping[layer]);
1399 }
1400 
getLevel(int level,int layer) const1401 const tcu::ConstPixelBufferAccess TestTextureCube::getLevel (int level, int layer) const
1402 {
1403 	return m_texture.getLevelFace(level, tcuFaceMapping[layer]);
1404 }
1405 
getArraySize(void) const1406 int TestTextureCube::getArraySize (void) const
1407 {
1408 	return (int)tcu::CUBEFACE_LAST;
1409 }
1410 
getTexture(void) const1411 const tcu::TextureCube& TestTextureCube::getTexture (void) const
1412 {
1413 	return m_texture;
1414 }
1415 
getTexture(void)1416 tcu::TextureCube& TestTextureCube::getTexture (void)
1417 {
1418 	return m_texture;
1419 }
1420 
copy(const tcu::TextureFormat format) const1421 de::MovePtr<TestTexture> TestTextureCube::copy(const tcu::TextureFormat format) const
1422 {
1423 	DE_ASSERT(!isCompressed());
1424 
1425 	de::MovePtr<TestTexture>	texture	(new TestTextureCube(format, m_texture.getSize()));
1426 
1427 	copyToTexture(*texture);
1428 
1429 	return texture;
1430 }
1431 
1432 // TestTextureCubeArray
1433 
TestTextureCubeArray(const tcu::TextureFormat & format,int size,int arraySize)1434 TestTextureCubeArray::TestTextureCubeArray (const tcu::TextureFormat& format, int size, int arraySize)
1435 	: TestTexture	(format, size, size, arraySize)
1436 	, m_texture		(format, size, arraySize)
1437 {
1438 	allocateLevels(m_texture);
1439 	TestTexture::populateLevels(getLevelsVector(m_texture));
1440 }
1441 
TestTextureCubeArray(const tcu::CompressedTexFormat & format,int size,int arraySize)1442 TestTextureCubeArray::TestTextureCubeArray (const tcu::CompressedTexFormat& format, int size, int arraySize)
1443 	: TestTexture	(format, size, size, arraySize)
1444 	, m_texture		(tcu::getUncompressedFormat(format), size, arraySize)
1445 {
1446 	DE_ASSERT(arraySize % 6 == 0);
1447 
1448 	allocateLevels(m_texture);
1449 
1450 	std::vector<tcu::PixelBufferAccess> layers;
1451 	for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
1452 		for (int layerNdx = 0; layerNdx < m_texture.getDepth(); layerNdx++)
1453 			layers.push_back(getLevel(levelNdx, layerNdx));
1454 
1455 	TestTexture::populateCompressedLevels(format, layers);
1456 }
1457 
~TestTextureCubeArray(void)1458 TestTextureCubeArray::~TestTextureCubeArray (void)
1459 {
1460 }
1461 
getNumLevels(void) const1462 int TestTextureCubeArray::getNumLevels (void) const
1463 {
1464 	return m_texture.getNumLevels();
1465 }
1466 
getLevel(int level,int layer)1467 tcu::PixelBufferAccess TestTextureCubeArray::getLevel (int level, int layer)
1468 {
1469 	const tcu::PixelBufferAccess	levelLayers	= m_texture.getLevel(level);
1470 	const deUint32					layerSize	= levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1471 	const deUint32					layerOffset	= layerSize * layer;
1472 
1473 	return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1474 }
1475 
getLevel(int level,int layer) const1476 const tcu::ConstPixelBufferAccess TestTextureCubeArray::getLevel (int level, int layer) const
1477 {
1478 	const tcu::ConstPixelBufferAccess	levelLayers	= m_texture.getLevel(level);
1479 	const deUint32						layerSize	= levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1480 	const deUint32						layerOffset	= layerSize * layer;
1481 
1482 	return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1483 }
1484 
getArraySize(void) const1485 int TestTextureCubeArray::getArraySize (void) const
1486 {
1487 	return m_texture.getDepth();
1488 }
1489 
getTexture(void) const1490 const tcu::TextureCubeArray& TestTextureCubeArray::getTexture (void) const
1491 {
1492 	return m_texture;
1493 }
1494 
getTexture(void)1495 tcu::TextureCubeArray& TestTextureCubeArray::getTexture (void)
1496 {
1497 	return m_texture;
1498 }
1499 
copy(const tcu::TextureFormat format) const1500 de::MovePtr<TestTexture> TestTextureCubeArray::copy(const tcu::TextureFormat format) const
1501 {
1502 	DE_ASSERT(!isCompressed());
1503 
1504 	de::MovePtr<TestTexture>	texture	(new TestTextureCubeArray(format, m_texture.getSize(), getArraySize()));
1505 
1506 	copyToTexture(*texture);
1507 
1508 	return texture;
1509 }
1510 
1511 } // pipeline
1512 } // vkt
1513