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