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