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