• 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 "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 	cmdPool		= createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
242 	cmdBuffer	= allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
243 
244 	// Create fence
245 	fence = createFence(vk, device);
246 
247 	// Barriers for copying image to buffer
248 
249 	const VkImageMemoryBarrier imageBarrier =
250 	{
251 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
252 		DE_NULL,									// const void*				pNext;
253 		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			srcAccessMask;
254 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
255 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout			oldLayout;
256 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout;
257 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
258 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
259 		image,										// VkImage					image;
260 		{											// VkImageSubresourceRange	subresourceRange;
261 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
262 			0u,							// deUint32				baseMipLevel;
263 			1u,							// deUint32				mipLevels;
264 			0u,							// deUint32				baseArraySlice;
265 			1u							// deUint32				arraySize;
266 		}
267 	};
268 
269 	const VkBufferMemoryBarrier bufferBarrier =
270 	{
271 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
272 		DE_NULL,									// const void*		pNext;
273 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
274 		VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
275 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
276 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
277 		*buffer,									// VkBuffer			buffer;
278 		0u,											// VkDeviceSize		offset;
279 		pixelDataSize								// VkDeviceSize		size;
280 	};
281 
282 	const VkCommandBufferBeginInfo cmdBufferBeginInfo =
283 	{
284 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,			// VkStructureType					sType;
285 		DE_NULL,												// const void*						pNext;
286 		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,			// VkCommandBufferUsageFlags		flags;
287 		(const VkCommandBufferInheritanceInfo*)DE_NULL,
288 	};
289 
290 	// Copy image to buffer
291 
292 	const VkBufferImageCopy copyRegion =
293 	{
294 		0u,												// VkDeviceSize				bufferOffset;
295 		(deUint32)renderSize.x(),						// deUint32					bufferRowLength;
296 		(deUint32)renderSize.y(),						// deUint32					bufferImageHeight;
297 		{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u },		// VkImageSubresourceLayers	imageSubresource;
298 		{ 0, 0, 0 },									// VkOffset3D				imageOffset;
299 		{ renderSize.x(), renderSize.y(), 1u }			// VkExtent3D				imageExtent;
300 	};
301 
302 	VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
303 	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);
304 	vk.cmdCopyImageToBuffer(*cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1, &copyRegion);
305 	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);
306 	VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
307 
308 	const VkSubmitInfo submitInfo =
309 	{
310 		VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType			sType;
311 		DE_NULL,						// const void*				pNext;
312 		0u,								// deUint32					waitSemaphoreCount;
313 		DE_NULL,						// const VkSemaphore*		pWaitSemaphores;
314 		DE_NULL,
315 		1u,								// deUint32					commandBufferCount;
316 		&cmdBuffer.get(),				// const VkCommandBuffer*	pCommandBuffers;
317 		0u,								// deUint32					signalSemaphoreCount;
318 		DE_NULL							// const VkSemaphore*		pSignalSemaphores;
319 	};
320 
321 	VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
322 	VK_CHECK(vk.waitForFences(device, 1, &fence.get(), 0, ~(0ull) /* infinity */));
323 
324 	// Read buffer data
325 	invalidateMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), VK_WHOLE_SIZE);
326 	tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), bufferAlloc->getHostPtr()));
327 
328 	return resultLevel;
329 }
330 
331 namespace
332 {
333 
getImageAspectFlags(const tcu::TextureFormat textureFormat)334 VkImageAspectFlags getImageAspectFlags (const tcu::TextureFormat textureFormat)
335 {
336 	VkImageAspectFlags imageAspectFlags = 0;
337 
338 	if (tcu::hasDepthComponent(textureFormat.order))
339 		imageAspectFlags |= VK_IMAGE_ASPECT_DEPTH_BIT;
340 
341 	if (tcu::hasStencilComponent(textureFormat.order))
342 		imageAspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT;
343 
344 	if (imageAspectFlags == 0)
345 		imageAspectFlags = VK_IMAGE_ASPECT_COLOR_BIT;
346 
347 	return imageAspectFlags;
348 }
349 
350 } // anonymous
351 
uploadTestTextureInternal(const DeviceInterface & vk,VkDevice device,VkQueue queue,deUint32 queueFamilyIndex,Allocator & allocator,const TestTexture & srcTexture,const TestTexture * srcStencilTexture,tcu::TextureFormat format,VkImage destImage)352 void uploadTestTextureInternal (const DeviceInterface&			vk,
353 								VkDevice						device,
354 								VkQueue							queue,
355 								deUint32						queueFamilyIndex,
356 								Allocator&						allocator,
357 								const TestTexture&				srcTexture,
358 								const TestTexture*				srcStencilTexture,
359 								tcu::TextureFormat				format,
360 								VkImage							destImage)
361 {
362 	deUint32						bufferSize;
363 	Move<VkBuffer>					buffer;
364 	de::MovePtr<Allocation>			bufferAlloc;
365 	Move<VkCommandPool>				cmdPool;
366 	Move<VkCommandBuffer>			cmdBuffer;
367 	Move<VkFence>					fence;
368 	const VkImageAspectFlags		imageAspectFlags	= getImageAspectFlags(format);
369 	deUint32						stencilOffset		= 0u;
370 
371 	// Calculate buffer size
372 	bufferSize =  (srcTexture.isCompressed())? srcTexture.getCompressedSize(): srcTexture.getSize();
373 
374 	// Stencil-only texture should be provided if (and only if) the image has a combined DS format
375 	DE_ASSERT((tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order)) == (srcStencilTexture != DE_NULL));
376 
377 	if (srcStencilTexture != DE_NULL)
378 	{
379 		stencilOffset	= static_cast<deUint32>(deAlign32(static_cast<deInt32>(bufferSize), 4));
380 		bufferSize		= stencilOffset + srcStencilTexture->getSize();
381 	}
382 
383 	// Create source buffer
384 	{
385 		const VkBufferCreateInfo bufferParams =
386 		{
387 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
388 			DE_NULL,									// const void*			pNext;
389 			0u,											// VkBufferCreateFlags	flags;
390 			bufferSize,									// VkDeviceSize			size;
391 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
392 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
393 			0u,											// deUint32				queueFamilyIndexCount;
394 			DE_NULL,									// const deUint32*		pQueueFamilyIndices;
395 		};
396 
397 		buffer		= createBuffer(vk, device, &bufferParams);
398 		bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
399 		VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
400 	}
401 
402 	// Create command pool and buffer
403 	cmdPool		= createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
404 	cmdBuffer	= allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
405 
406 	// Create fence
407 	fence = createFence(vk, device);
408 
409 	// Barriers for copying buffer to image
410 	const VkBufferMemoryBarrier preBufferBarrier =
411 	{
412 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
413 		DE_NULL,									// const void*		pNext;
414 		VK_ACCESS_HOST_WRITE_BIT,					// VkAccessFlags	srcAccessMask;
415 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags	dstAccessMask;
416 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
417 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
418 		*buffer,									// VkBuffer			buffer;
419 		0u,											// VkDeviceSize		offset;
420 		bufferSize									// VkDeviceSize		size;
421 	};
422 
423 	const VkImageMemoryBarrier preImageBarrier =
424 	{
425 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
426 		DE_NULL,										// const void*				pNext;
427 		0u,												// VkAccessFlags			srcAccessMask;
428 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
429 		VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
430 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout;
431 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
432 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
433 		destImage,										// VkImage					image;
434 		{												// VkImageSubresourceRange	subresourceRange;
435 			imageAspectFlags,						// VkImageAspectFlags	aspectMask;
436 			0u,										// deUint32				baseMipLevel;
437 			(deUint32)srcTexture.getNumLevels(),	// deUint32				mipLevels;
438 			0u,										// deUint32				baseArraySlice;
439 			(deUint32)srcTexture.getArraySize(),	// deUint32				arraySize;
440 		}
441 	};
442 
443 	const VkImageMemoryBarrier postImageBarrier =
444 	{
445 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
446 		DE_NULL,										// const void*				pNext;
447 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			srcAccessMask;
448 		VK_ACCESS_SHADER_READ_BIT,						// VkAccessFlags			dstAccessMask;
449 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			oldLayout;
450 		VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,		// VkImageLayout			newLayout;
451 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
452 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
453 		destImage,										// VkImage					image;
454 		{												// VkImageSubresourceRange	subresourceRange;
455 			imageAspectFlags,						// VkImageAspectFlags	aspectMask;
456 			0u,										// deUint32				baseMipLevel;
457 			(deUint32)srcTexture.getNumLevels(),	// deUint32				mipLevels;
458 			0u,										// deUint32				baseArraySlice;
459 			(deUint32)srcTexture.getArraySize(),	// deUint32				arraySize;
460 		}
461 	};
462 
463 	const VkCommandBufferBeginInfo cmdBufferBeginInfo =
464 	{
465 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType					sType;
466 		DE_NULL,										// const void*						pNext;
467 		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,	// VkCommandBufferUsageFlags		flags;
468 		(const VkCommandBufferInheritanceInfo*)DE_NULL,
469 	};
470 
471 	std::vector<VkBufferImageCopy>	copyRegions		= srcTexture.getBufferCopyRegions();
472 
473 	// Write buffer data
474 	srcTexture.write(reinterpret_cast<deUint8*>(bufferAlloc->getHostPtr()));
475 
476 	if (srcStencilTexture != DE_NULL)
477 	{
478 		DE_ASSERT(stencilOffset != 0u);
479 
480 		srcStencilTexture->write(reinterpret_cast<deUint8*>(bufferAlloc->getHostPtr()) + stencilOffset);
481 
482 		std::vector<VkBufferImageCopy>	stencilCopyRegions = srcStencilTexture->getBufferCopyRegions();
483 		for (size_t regionIdx = 0; regionIdx < stencilCopyRegions.size(); regionIdx++)
484 		{
485 			VkBufferImageCopy region = stencilCopyRegions[regionIdx];
486 			region.bufferOffset += stencilOffset;
487 
488 			copyRegions.push_back(region);
489 		}
490 	}
491 
492 	flushMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), VK_WHOLE_SIZE);
493 
494 	// Copy buffer to image
495 	VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
496 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 1, &preImageBarrier);
497 	vk.cmdCopyBufferToImage(*cmdBuffer, *buffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), copyRegions.data());
498 	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);
499 
500 	VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
501 
502 	const VkSubmitInfo submitInfo =
503 	{
504 		VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType			sType;
505 		DE_NULL,						// const void*				pNext;
506 		0u,								// deUint32					waitSemaphoreCount;
507 		DE_NULL,						// const VkSemaphore*		pWaitSemaphores;
508 		DE_NULL,
509 		1u,								// deUint32					commandBufferCount;
510 		&cmdBuffer.get(),				// const VkCommandBuffer*	pCommandBuffers;
511 		0u,								// deUint32					signalSemaphoreCount;
512 		DE_NULL							// const VkSemaphore*		pSignalSemaphores;
513 	};
514 
515 	VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
516 	VK_CHECK(vk.waitForFences(device, 1, &fence.get(), true, ~(0ull) /* infinity */));
517 }
518 
uploadTestTexture(const DeviceInterface & vk,VkDevice device,VkQueue queue,deUint32 queueFamilyIndex,Allocator & allocator,const TestTexture & srcTexture,VkImage destImage)519 void uploadTestTexture (const DeviceInterface&			vk,
520 						VkDevice						device,
521 						VkQueue							queue,
522 						deUint32						queueFamilyIndex,
523 						Allocator&						allocator,
524 						const TestTexture&				srcTexture,
525 						VkImage							destImage)
526 {
527 	if (tcu::isCombinedDepthStencilType(srcTexture.getTextureFormat().type))
528 	{
529 		de::MovePtr<TestTexture> srcDepthTexture;
530 		de::MovePtr<TestTexture> srcStencilTexture;
531 
532 		if (tcu::hasDepthComponent(srcTexture.getTextureFormat().order))
533 		{
534 			tcu::TextureFormat format;
535 			switch (srcTexture.getTextureFormat().type) {
536 			case tcu::TextureFormat::UNSIGNED_INT_16_8_8:
537 				format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
538 				break;
539 			case tcu::TextureFormat::UNSIGNED_INT_24_8_REV:
540 				format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8_REV);
541 				break;
542 			case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
543 				format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
544 				break;
545 			default:
546 				DE_ASSERT(0);
547 				break;
548 			}
549 			srcDepthTexture = srcTexture.copy(format);
550 		}
551 
552 		if (tcu::hasStencilComponent(srcTexture.getTextureFormat().order))
553 			srcStencilTexture = srcTexture.copy(tcu::getEffectiveDepthStencilTextureFormat(srcTexture.getTextureFormat(), tcu::Sampler::MODE_STENCIL));
554 
555 		uploadTestTextureInternal(vk, device, queue, queueFamilyIndex, allocator, *srcDepthTexture, srcStencilTexture.get(), srcTexture.getTextureFormat(), destImage);
556 	}
557 	else
558 		uploadTestTextureInternal(vk, device, queue, queueFamilyIndex, allocator, srcTexture, DE_NULL, srcTexture.getTextureFormat(), destImage);
559 }
560 
561 // Utilities for test textures
562 
563 template<typename TcuTextureType>
allocateLevels(TcuTextureType & texture)564 void allocateLevels (TcuTextureType& texture)
565 {
566 	for (int levelNdx = 0; levelNdx < texture.getNumLevels(); levelNdx++)
567 		texture.allocLevel(levelNdx);
568 }
569 
570 template<typename TcuTextureType>
getLevelsVector(const TcuTextureType & texture)571 std::vector<tcu::PixelBufferAccess> getLevelsVector (const TcuTextureType& texture)
572 {
573 	std::vector<tcu::PixelBufferAccess> levels(texture.getNumLevels());
574 
575 	for (int levelNdx = 0; levelNdx < texture.getNumLevels(); levelNdx++)
576 		levels[levelNdx] = *reinterpret_cast<const tcu::PixelBufferAccess*>(&texture.getLevel(levelNdx));
577 
578 	return levels;
579 }
580 
581 // TestTexture
582 
TestTexture(const tcu::TextureFormat & format,int width,int height,int depth)583 TestTexture::TestTexture (const tcu::TextureFormat& format, int width, int height, int depth)
584 {
585 	DE_ASSERT(width >= 1);
586 	DE_ASSERT(height >= 1);
587 	DE_ASSERT(depth >= 1);
588 
589 	DE_UNREF(format);
590 	DE_UNREF(width);
591 	DE_UNREF(height);
592 	DE_UNREF(depth);
593 }
594 
TestTexture(const tcu::CompressedTexFormat & format,int width,int height,int depth)595 TestTexture::TestTexture (const tcu::CompressedTexFormat& format, int width, int height, int depth)
596 {
597 	DE_ASSERT(width >= 1);
598 	DE_ASSERT(height >= 1);
599 	DE_ASSERT(depth >= 1);
600 
601 	DE_UNREF(format);
602 	DE_UNREF(width);
603 	DE_UNREF(height);
604 	DE_UNREF(depth);
605 }
606 
~TestTexture(void)607 TestTexture::~TestTexture (void)
608 {
609 	for (size_t levelNdx = 0; levelNdx < m_compressedLevels.size(); levelNdx++)
610 		delete m_compressedLevels[levelNdx];
611 }
612 
getSize(void) const613 deUint32 TestTexture::getSize (void) const
614 {
615 	std::vector<deUint32>	offsetMultiples;
616 	deUint32				textureSize = 0;
617 
618 	offsetMultiples.push_back(4);
619 	offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
620 
621 	for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
622 	{
623 		for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
624 		{
625 			const tcu::ConstPixelBufferAccess level = getLevel(levelNdx, layerNdx);
626 			textureSize = getNextMultiple(offsetMultiples, textureSize);
627 			textureSize += level.getWidth() * level.getHeight() * level.getDepth() * level.getFormat().getPixelSize();
628 		}
629 	}
630 
631 	return textureSize;
632 }
633 
getCompressedSize(void) const634 deUint32 TestTexture::getCompressedSize (void) const
635 {
636 	if (!isCompressed())
637 		throw tcu::InternalError("Texture is not compressed");
638 
639 	std::vector<deUint32>	offsetMultiples;
640 	deUint32				textureSize			= 0;
641 
642 	offsetMultiples.push_back(4);
643 	offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
644 
645 	for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
646 	{
647 		for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
648 		{
649 			textureSize = getNextMultiple(offsetMultiples, textureSize);
650 			textureSize += getCompressedLevel(levelNdx, layerNdx).getDataSize();
651 		}
652 	}
653 
654 	return textureSize;
655 }
656 
getCompressedLevel(int level,int layer)657 tcu::CompressedTexture& TestTexture::getCompressedLevel (int level, int layer)
658 {
659 	DE_ASSERT(level >= 0 && level < getNumLevels());
660 	DE_ASSERT(layer >= 0 && layer < getArraySize());
661 
662 	return *m_compressedLevels[level * getArraySize() + layer];
663 }
664 
getCompressedLevel(int level,int layer) const665 const tcu::CompressedTexture& TestTexture::getCompressedLevel (int level, int layer) const
666 {
667 	DE_ASSERT(level >= 0 && level < getNumLevels());
668 	DE_ASSERT(layer >= 0 && layer < getArraySize());
669 
670 	return *m_compressedLevels[level * getArraySize() + layer];
671 }
672 
getBufferCopyRegions(void) const673 std::vector<VkBufferImageCopy> TestTexture::getBufferCopyRegions (void) const
674 {
675 	std::vector<deUint32>			offsetMultiples;
676 	std::vector<VkBufferImageCopy>	regions;
677 	deUint32						layerDataOffset = 0;
678 
679 	offsetMultiples.push_back(4);
680 
681 	if (isCompressed())
682 	{
683 		offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
684 
685 		for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
686 		{
687 			for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
688 			{
689 				const tcu::CompressedTexture& level = getCompressedLevel(levelNdx, layerNdx);
690 				tcu::IVec3 blockPixelSize			= getBlockPixelSize(level.getFormat());
691 				layerDataOffset						= getNextMultiple(offsetMultiples, layerDataOffset);
692 
693 				const VkBufferImageCopy layerRegion =
694 				{
695 					layerDataOffset,													// VkDeviceSize				bufferOffset;
696 					(deUint32)getNextMultiple(blockPixelSize.x(), level.getWidth()),	// deUint32					bufferRowLength;
697 					(deUint32)getNextMultiple(blockPixelSize.y(), level.getHeight()),	// deUint32					bufferImageHeight;
698 					{																	// VkImageSubresourceLayers	imageSubresource;
699 						VK_IMAGE_ASPECT_COLOR_BIT,
700 						(deUint32)levelNdx,
701 						(deUint32)layerNdx,
702 						1u
703 					},
704 					{ 0u, 0u, 0u },							// VkOffset3D				imageOffset;
705 					{										// VkExtent3D				imageExtent;
706 						(deUint32)level.getWidth(),
707 						(deUint32)level.getHeight(),
708 						(deUint32)level.getDepth()
709 					}
710 				};
711 
712 				regions.push_back(layerRegion);
713 				layerDataOffset += level.getDataSize();
714 			}
715 		}
716 	}
717 	else
718 	{
719 		std::vector<VkImageAspectFlags>	imageAspects;
720 		tcu::TextureFormat				textureFormat	= getTextureFormat();
721 
722 		if (tcu::hasDepthComponent(textureFormat.order))
723 			imageAspects.push_back(VK_IMAGE_ASPECT_DEPTH_BIT);
724 
725 		if (tcu::hasStencilComponent(textureFormat.order))
726 			imageAspects.push_back(VK_IMAGE_ASPECT_STENCIL_BIT);
727 
728 		if (imageAspects.empty())
729 			imageAspects.push_back(VK_IMAGE_ASPECT_COLOR_BIT);
730 
731 		offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
732 
733 		for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
734 		{
735 			for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
736 			{
737 				const tcu::ConstPixelBufferAccess level = getLevel(levelNdx, layerNdx);
738 
739 				layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset);
740 
741 				for (size_t aspectIndex = 0; aspectIndex < imageAspects.size(); ++aspectIndex)
742 				{
743 					const VkBufferImageCopy layerRegion =
744 					{
745 						layerDataOffset,						// VkDeviceSize				bufferOffset;
746 						(deUint32)level.getWidth(),				// deUint32					bufferRowLength;
747 						(deUint32)level.getHeight(),			// deUint32					bufferImageHeight;
748 						{										// VkImageSubresourceLayers	imageSubresource;
749 							imageAspects[aspectIndex],
750 							(deUint32)levelNdx,
751 							(deUint32)layerNdx,
752 							1u
753 						},
754 						{ 0u, 0u, 0u },							// VkOffset3D			imageOffset;
755 						{										// VkExtent3D			imageExtent;
756 							(deUint32)level.getWidth(),
757 							(deUint32)level.getHeight(),
758 							(deUint32)level.getDepth()
759 						}
760 					};
761 
762 					regions.push_back(layerRegion);
763 				}
764 				layerDataOffset += level.getWidth() * level.getHeight() * level.getDepth() * level.getFormat().getPixelSize();
765 			}
766 		}
767 	}
768 
769 	return regions;
770 }
771 
write(deUint8 * destPtr) const772 void TestTexture::write (deUint8* destPtr) const
773 {
774 	std::vector<deUint32>	offsetMultiples;
775 	deUint32				levelOffset		= 0;
776 
777 	offsetMultiples.push_back(4);
778 
779 	if (isCompressed())
780 	{
781 		offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
782 
783 		for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
784 		{
785 			for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
786 			{
787 				levelOffset = getNextMultiple(offsetMultiples, levelOffset);
788 
789 				const tcu::CompressedTexture&		compressedTex	= getCompressedLevel(levelNdx, layerNdx);
790 
791 				deMemcpy(destPtr + levelOffset, compressedTex.getData(), compressedTex.getDataSize());
792 				levelOffset += compressedTex.getDataSize();
793 			}
794 		}
795 	}
796 	else
797 	{
798 		offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
799 
800 		for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
801 		{
802 			for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
803 			{
804 				levelOffset = getNextMultiple(offsetMultiples, levelOffset);
805 
806 				const tcu::ConstPixelBufferAccess	srcAccess		= getLevel(levelNdx, layerNdx);
807 				const tcu::PixelBufferAccess		destAccess		(srcAccess.getFormat(), srcAccess.getSize(), srcAccess.getPitch(), destPtr + levelOffset);
808 
809 				tcu::copy(destAccess, srcAccess);
810 				levelOffset += srcAccess.getWidth() * srcAccess.getHeight() * srcAccess.getDepth() * srcAccess.getFormat().getPixelSize();
811 			}
812 		}
813 	}
814 }
815 
copyToTexture(TestTexture & destTexture) const816 void TestTexture::copyToTexture (TestTexture& destTexture) const
817 {
818 	for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
819 		for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
820 			tcu::copy(destTexture.getLevel(levelNdx, layerNdx), getLevel(levelNdx, layerNdx));
821 }
822 
populateLevels(const std::vector<tcu::PixelBufferAccess> & levels)823 void TestTexture::populateLevels (const std::vector<tcu::PixelBufferAccess>& levels)
824 {
825 	for (size_t levelNdx = 0; levelNdx < levels.size(); levelNdx++)
826 		TestTexture::fillWithGradient(levels[levelNdx]);
827 }
828 
populateCompressedLevels(tcu::CompressedTexFormat format,const std::vector<tcu::PixelBufferAccess> & decompressedLevels)829 void TestTexture::populateCompressedLevels (tcu::CompressedTexFormat format, const std::vector<tcu::PixelBufferAccess>& decompressedLevels)
830 {
831 	// Generate random compressed data and update decompressed data
832 
833 	de::Random random(123);
834 
835 	for (size_t levelNdx = 0; levelNdx < decompressedLevels.size(); levelNdx++)
836 	{
837 		const tcu::PixelBufferAccess	level				= decompressedLevels[levelNdx];
838 		tcu::CompressedTexture*			compressedLevel		= new tcu::CompressedTexture(format, level.getWidth(), level.getHeight(), level.getDepth());
839 		deUint8* const					compressedData		= (deUint8*)compressedLevel->getData();
840 
841 		if (tcu::isAstcFormat(format))
842 		{
843 			// \todo [2016-01-20 pyry] Comparison doesn't currently handle invalid blocks correctly so we use only valid blocks
844 			tcu::astc::generateRandomValidBlocks(compressedData, compressedLevel->getDataSize()/tcu::astc::BLOCK_SIZE_BYTES,
845 												 format, tcu::TexDecompressionParams::ASTCMODE_LDR, random.getUint32());
846 		}
847 		else
848 		{
849 			// Generate random compressed data
850 			// Random initial values cause assertion during the decompression in case of COMPRESSEDTEXFORMAT_ETC1_RGB8 format
851 			if (format != tcu::COMPRESSEDTEXFORMAT_ETC1_RGB8)
852 				for (int byteNdx = 0; byteNdx < compressedLevel->getDataSize(); byteNdx++)
853 					compressedData[byteNdx] = 0xFF & random.getUint32();
854 		}
855 
856 		m_compressedLevels.push_back(compressedLevel);
857 
858 		// Store decompressed data
859 		compressedLevel->decompress(level, tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR));
860 	}
861 }
862 
fillWithGradient(const tcu::PixelBufferAccess & levelAccess)863 void TestTexture::fillWithGradient (const tcu::PixelBufferAccess& levelAccess)
864 {
865 	const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(levelAccess.getFormat());
866 	tcu::fillWithComponentGradients(levelAccess, formatInfo.valueMin, formatInfo.valueMax);
867 }
868 
869 // TestTexture1D
870 
TestTexture1D(const tcu::TextureFormat & format,int width)871 TestTexture1D::TestTexture1D (const tcu::TextureFormat& format, int width)
872 	: TestTexture	(format, width, 1, 1)
873 	, m_texture		(format, width)
874 {
875 	allocateLevels(m_texture);
876 	TestTexture::populateLevels(getLevelsVector(m_texture));
877 }
878 
TestTexture1D(const tcu::CompressedTexFormat & format,int width)879 TestTexture1D::TestTexture1D (const tcu::CompressedTexFormat& format, int width)
880 	: TestTexture	(format, width, 1, 1)
881 	, m_texture		(tcu::getUncompressedFormat(format), width)
882 {
883 	allocateLevels(m_texture);
884 	TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
885 }
886 
~TestTexture1D(void)887 TestTexture1D::~TestTexture1D (void)
888 {
889 }
890 
getNumLevels(void) const891 int TestTexture1D::getNumLevels (void) const
892 {
893 	return m_texture.getNumLevels();
894 }
895 
getLevel(int level,int layer)896 tcu::PixelBufferAccess TestTexture1D::getLevel (int level, int layer)
897 {
898 	DE_ASSERT(layer == 0);
899 	DE_UNREF(layer);
900 	return m_texture.getLevel(level);
901 }
902 
getLevel(int level,int layer) const903 const tcu::ConstPixelBufferAccess TestTexture1D::getLevel (int level, int layer) const
904 {
905 	DE_ASSERT(layer == 0);
906 	DE_UNREF(layer);
907 	return m_texture.getLevel(level);
908 }
909 
getTexture(void) const910 const tcu::Texture1D& TestTexture1D::getTexture (void) const
911 {
912 	return m_texture;
913 }
914 
getTexture(void)915 tcu::Texture1D& TestTexture1D::getTexture (void)
916 {
917 	return m_texture;
918 }
919 
copy(const tcu::TextureFormat format) const920 de::MovePtr<TestTexture> TestTexture1D::copy(const tcu::TextureFormat format) const
921 {
922 	DE_ASSERT(!isCompressed());
923 
924 	de::MovePtr<TestTexture>	texture	(new TestTexture1D(format, m_texture.getWidth()));
925 
926 	copyToTexture(*texture);
927 
928 	return texture;
929 }
930 
931 // TestTexture1DArray
932 
TestTexture1DArray(const tcu::TextureFormat & format,int width,int arraySize)933 TestTexture1DArray::TestTexture1DArray (const tcu::TextureFormat& format, int width, int arraySize)
934 	: TestTexture	(format, width, 1, arraySize)
935 	, m_texture		(format, width, arraySize)
936 {
937 	allocateLevels(m_texture);
938 	TestTexture::populateLevels(getLevelsVector(m_texture));
939 }
940 
TestTexture1DArray(const tcu::CompressedTexFormat & format,int width,int arraySize)941 TestTexture1DArray::TestTexture1DArray (const tcu::CompressedTexFormat& format, int width, int arraySize)
942 	: TestTexture	(format, width, 1, arraySize)
943 	, m_texture		(tcu::getUncompressedFormat(format), width, arraySize)
944 {
945 	allocateLevels(m_texture);
946 
947 	std::vector<tcu::PixelBufferAccess> layers;
948 	for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
949 		for (int layerNdx = 0; layerNdx < m_texture.getNumLayers(); layerNdx++)
950 			layers.push_back(getLevel(levelNdx, layerNdx));
951 
952 	TestTexture::populateCompressedLevels(format, layers);
953 }
954 
~TestTexture1DArray(void)955 TestTexture1DArray::~TestTexture1DArray (void)
956 {
957 }
958 
getNumLevels(void) const959 int TestTexture1DArray::getNumLevels (void) const
960 {
961 	return m_texture.getNumLevels();
962 }
963 
getLevel(int level,int layer)964 tcu::PixelBufferAccess TestTexture1DArray::getLevel (int level, int layer)
965 {
966 	const tcu::PixelBufferAccess	levelLayers	= m_texture.getLevel(level);
967 	const deUint32					layerSize	= levelLayers.getWidth() * levelLayers.getFormat().getPixelSize();
968 	const deUint32					layerOffset	= layerSize * layer;
969 
970 	return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
971 }
972 
getLevel(int level,int layer) const973 const tcu::ConstPixelBufferAccess TestTexture1DArray::getLevel (int level, int layer) const
974 {
975 	const tcu::ConstPixelBufferAccess	levelLayers	= m_texture.getLevel(level);
976 	const deUint32						layerSize	= levelLayers.getWidth() * levelLayers.getFormat().getPixelSize();
977 	const deUint32						layerOffset	= layerSize * layer;
978 
979 	return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
980 }
981 
getTexture(void) const982 const tcu::Texture1DArray& TestTexture1DArray::getTexture (void) const
983 {
984 	return m_texture;
985 }
986 
getTexture(void)987 tcu::Texture1DArray& TestTexture1DArray::getTexture (void)
988 {
989 	return m_texture;
990 }
991 
getArraySize(void) const992 int TestTexture1DArray::getArraySize (void) const
993 {
994 	return m_texture.getNumLayers();
995 }
996 
copy(const tcu::TextureFormat format) const997 de::MovePtr<TestTexture> TestTexture1DArray::copy(const tcu::TextureFormat format) const
998 {
999 	DE_ASSERT(!isCompressed());
1000 
1001 	de::MovePtr<TestTexture>	texture	(new TestTexture1DArray(format, m_texture.getWidth(), getArraySize()));
1002 
1003 	copyToTexture(*texture);
1004 
1005 	return texture;
1006 }
1007 
1008 // TestTexture2D
1009 
TestTexture2D(const tcu::TextureFormat & format,int width,int height)1010 TestTexture2D::TestTexture2D (const tcu::TextureFormat& format, int width, int height)
1011 	: TestTexture	(format, width, height, 1)
1012 	, m_texture		(format, width, height)
1013 {
1014 	allocateLevels(m_texture);
1015 	TestTexture::populateLevels(getLevelsVector(m_texture));
1016 }
1017 
TestTexture2D(const tcu::CompressedTexFormat & format,int width,int height)1018 TestTexture2D::TestTexture2D (const tcu::CompressedTexFormat& format, int width, int height)
1019 	: TestTexture	(format, width, height, 1)
1020 	, m_texture		(tcu::getUncompressedFormat(format), width, height)
1021 {
1022 	allocateLevels(m_texture);
1023 	TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
1024 }
1025 
~TestTexture2D(void)1026 TestTexture2D::~TestTexture2D (void)
1027 {
1028 }
1029 
getNumLevels(void) const1030 int TestTexture2D::getNumLevels (void) const
1031 {
1032 	return m_texture.getNumLevels();
1033 }
1034 
getLevel(int level,int layer)1035 tcu::PixelBufferAccess TestTexture2D::getLevel (int level, int layer)
1036 {
1037 	DE_ASSERT(layer == 0);
1038 	DE_UNREF(layer);
1039 	return m_texture.getLevel(level);
1040 }
1041 
getLevel(int level,int layer) const1042 const tcu::ConstPixelBufferAccess TestTexture2D::getLevel (int level, int layer) const
1043 {
1044 	DE_ASSERT(layer == 0);
1045 	DE_UNREF(layer);
1046 	return m_texture.getLevel(level);
1047 }
1048 
getTexture(void) const1049 const tcu::Texture2D& TestTexture2D::getTexture (void) const
1050 {
1051 	return m_texture;
1052 }
1053 
getTexture(void)1054 tcu::Texture2D& TestTexture2D::getTexture (void)
1055 {
1056 	return m_texture;
1057 }
1058 
copy(const tcu::TextureFormat format) const1059 de::MovePtr<TestTexture> TestTexture2D::copy(const tcu::TextureFormat format) const
1060 {
1061 	DE_ASSERT(!isCompressed());
1062 
1063 	de::MovePtr<TestTexture>	texture	(new TestTexture2D(format, m_texture.getWidth(), m_texture.getHeight()));
1064 
1065 	copyToTexture(*texture);
1066 
1067 	return texture;
1068 }
1069 
1070 // TestTexture2DArray
1071 
TestTexture2DArray(const tcu::TextureFormat & format,int width,int height,int arraySize)1072 TestTexture2DArray::TestTexture2DArray (const tcu::TextureFormat& format, int width, int height, int arraySize)
1073 	: TestTexture	(format, width, height, arraySize)
1074 	, m_texture		(format, width, height, arraySize)
1075 {
1076 	allocateLevels(m_texture);
1077 	TestTexture::populateLevels(getLevelsVector(m_texture));
1078 }
1079 
TestTexture2DArray(const tcu::CompressedTexFormat & format,int width,int height,int arraySize)1080 TestTexture2DArray::TestTexture2DArray (const tcu::CompressedTexFormat& format, int width, int height, int arraySize)
1081 	: TestTexture	(format, width, height, arraySize)
1082 	, m_texture		(tcu::getUncompressedFormat(format), width, height, arraySize)
1083 {
1084 	allocateLevels(m_texture);
1085 
1086 	std::vector<tcu::PixelBufferAccess> layers;
1087 	for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
1088 		for (int layerNdx = 0; layerNdx < m_texture.getNumLayers(); layerNdx++)
1089 			layers.push_back(getLevel(levelNdx, layerNdx));
1090 
1091 	TestTexture::populateCompressedLevels(format, layers);
1092 }
1093 
~TestTexture2DArray(void)1094 TestTexture2DArray::~TestTexture2DArray (void)
1095 {
1096 }
1097 
getNumLevels(void) const1098 int TestTexture2DArray::getNumLevels (void) const
1099 {
1100 	return m_texture.getNumLevels();
1101 }
1102 
getLevel(int level,int layer)1103 tcu::PixelBufferAccess TestTexture2DArray::getLevel (int level, int layer)
1104 {
1105 	const tcu::PixelBufferAccess	levelLayers	= m_texture.getLevel(level);
1106 	const deUint32					layerSize	= levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1107 	const deUint32					layerOffset	= layerSize * layer;
1108 
1109 	return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1110 }
1111 
getLevel(int level,int layer) const1112 const tcu::ConstPixelBufferAccess TestTexture2DArray::getLevel (int level, int layer) const
1113 {
1114 	const tcu::ConstPixelBufferAccess	levelLayers	= m_texture.getLevel(level);
1115 	const deUint32						layerSize	= levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1116 	const deUint32						layerOffset	= layerSize * layer;
1117 
1118 	return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1119 }
1120 
getTexture(void) const1121 const tcu::Texture2DArray& TestTexture2DArray::getTexture (void) const
1122 {
1123 	return m_texture;
1124 }
1125 
getTexture(void)1126 tcu::Texture2DArray& TestTexture2DArray::getTexture (void)
1127 {
1128 	return m_texture;
1129 }
1130 
getArraySize(void) const1131 int TestTexture2DArray::getArraySize (void) const
1132 {
1133 	return m_texture.getNumLayers();
1134 }
1135 
copy(const tcu::TextureFormat format) const1136 de::MovePtr<TestTexture> TestTexture2DArray::copy(const tcu::TextureFormat format) const
1137 {
1138 	DE_ASSERT(!isCompressed());
1139 
1140 	de::MovePtr<TestTexture>	texture	(new TestTexture2DArray(format, m_texture.getWidth(), m_texture.getHeight(), getArraySize()));
1141 
1142 	copyToTexture(*texture);
1143 
1144 	return texture;
1145 }
1146 
1147 // TestTexture3D
1148 
TestTexture3D(const tcu::TextureFormat & format,int width,int height,int depth)1149 TestTexture3D::TestTexture3D (const tcu::TextureFormat& format, int width, int height, int depth)
1150 	: TestTexture	(format, width, height, depth)
1151 	, m_texture		(format, width, height, depth)
1152 {
1153 	allocateLevels(m_texture);
1154 	TestTexture::populateLevels(getLevelsVector(m_texture));
1155 }
1156 
TestTexture3D(const tcu::CompressedTexFormat & format,int width,int height,int depth)1157 TestTexture3D::TestTexture3D (const tcu::CompressedTexFormat& format, int width, int height, int depth)
1158 	: TestTexture	(format, width, height, depth)
1159 	, m_texture		(tcu::getUncompressedFormat(format), width, height, depth)
1160 {
1161 	allocateLevels(m_texture);
1162 	TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
1163 }
1164 
~TestTexture3D(void)1165 TestTexture3D::~TestTexture3D (void)
1166 {
1167 }
1168 
getNumLevels(void) const1169 int TestTexture3D::getNumLevels (void) const
1170 {
1171 	return m_texture.getNumLevels();
1172 }
1173 
getLevel(int level,int layer)1174 tcu::PixelBufferAccess TestTexture3D::getLevel (int level, int layer)
1175 {
1176 	DE_ASSERT(layer == 0);
1177 	DE_UNREF(layer);
1178 	return m_texture.getLevel(level);
1179 }
1180 
getLevel(int level,int layer) const1181 const tcu::ConstPixelBufferAccess TestTexture3D::getLevel (int level, int layer) const
1182 {
1183 	DE_ASSERT(layer == 0);
1184 	DE_UNREF(layer);
1185 	return m_texture.getLevel(level);
1186 }
1187 
getTexture(void) const1188 const tcu::Texture3D& TestTexture3D::getTexture (void) const
1189 {
1190 	return m_texture;
1191 }
1192 
getTexture(void)1193 tcu::Texture3D& TestTexture3D::getTexture (void)
1194 {
1195 	return m_texture;
1196 }
1197 
copy(const tcu::TextureFormat format) const1198 de::MovePtr<TestTexture> TestTexture3D::copy(const tcu::TextureFormat format) const
1199 {
1200 	DE_ASSERT(!isCompressed());
1201 
1202 	de::MovePtr<TestTexture>	texture	(new TestTexture3D(format, m_texture.getWidth(), m_texture.getHeight(), m_texture.getDepth()));
1203 
1204 	copyToTexture(*texture);
1205 
1206 	return texture;
1207 }
1208 
1209 // TestTextureCube
1210 
1211 const static tcu::CubeFace tcuFaceMapping[tcu::CUBEFACE_LAST] =
1212 {
1213 	tcu::CUBEFACE_POSITIVE_X,
1214 	tcu::CUBEFACE_NEGATIVE_X,
1215 	tcu::CUBEFACE_POSITIVE_Y,
1216 	tcu::CUBEFACE_NEGATIVE_Y,
1217 	tcu::CUBEFACE_POSITIVE_Z,
1218 	tcu::CUBEFACE_NEGATIVE_Z
1219 };
1220 
TestTextureCube(const tcu::TextureFormat & format,int size)1221 TestTextureCube::TestTextureCube (const tcu::TextureFormat& format, int size)
1222 	: TestTexture	(format, size, size, 1)
1223 	, m_texture		(format, size)
1224 {
1225 	for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
1226 	{
1227 		for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
1228 		{
1229 			m_texture.allocLevel(tcuFaceMapping[faceNdx], levelNdx);
1230 			TestTexture::fillWithGradient(m_texture.getLevelFace(levelNdx, tcuFaceMapping[faceNdx]));
1231 		}
1232 	}
1233 }
1234 
TestTextureCube(const tcu::CompressedTexFormat & format,int size)1235 TestTextureCube::TestTextureCube (const tcu::CompressedTexFormat& format, int size)
1236 	: TestTexture	(format, size, size, 1)
1237 	, m_texture		(tcu::getUncompressedFormat(format), size)
1238 {
1239 	std::vector<tcu::PixelBufferAccess> levels(m_texture.getNumLevels() * tcu::CUBEFACE_LAST);
1240 
1241 	for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
1242 	{
1243 		for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
1244 		{
1245 			m_texture.allocLevel(tcuFaceMapping[faceNdx], levelNdx);
1246 			levels[levelNdx * tcu::CUBEFACE_LAST + faceNdx] = m_texture.getLevelFace(levelNdx, tcuFaceMapping[faceNdx]);
1247 		}
1248 	}
1249 
1250 	TestTexture::populateCompressedLevels(format, levels);
1251 }
1252 
~TestTextureCube(void)1253 TestTextureCube::~TestTextureCube (void)
1254 {
1255 }
1256 
getNumLevels(void) const1257 int TestTextureCube::getNumLevels (void) const
1258 {
1259 	return m_texture.getNumLevels();
1260 }
1261 
getLevel(int level,int layer)1262 tcu::PixelBufferAccess TestTextureCube::getLevel (int level, int layer)
1263 {
1264 	return m_texture.getLevelFace(level, tcuFaceMapping[layer]);
1265 }
1266 
getLevel(int level,int layer) const1267 const tcu::ConstPixelBufferAccess TestTextureCube::getLevel (int level, int layer) const
1268 {
1269 	return m_texture.getLevelFace(level, tcuFaceMapping[layer]);
1270 }
1271 
getArraySize(void) const1272 int TestTextureCube::getArraySize (void) const
1273 {
1274 	return (int)tcu::CUBEFACE_LAST;
1275 }
1276 
getTexture(void) const1277 const tcu::TextureCube& TestTextureCube::getTexture (void) const
1278 {
1279 	return m_texture;
1280 }
1281 
getTexture(void)1282 tcu::TextureCube& TestTextureCube::getTexture (void)
1283 {
1284 	return m_texture;
1285 }
1286 
copy(const tcu::TextureFormat format) const1287 de::MovePtr<TestTexture> TestTextureCube::copy(const tcu::TextureFormat format) const
1288 {
1289 	DE_ASSERT(!isCompressed());
1290 
1291 	de::MovePtr<TestTexture>	texture	(new TestTextureCube(format, m_texture.getSize()));
1292 
1293 	copyToTexture(*texture);
1294 
1295 	return texture;
1296 }
1297 
1298 // TestTextureCubeArray
1299 
TestTextureCubeArray(const tcu::TextureFormat & format,int size,int arraySize)1300 TestTextureCubeArray::TestTextureCubeArray (const tcu::TextureFormat& format, int size, int arraySize)
1301 	: TestTexture	(format, size, size, arraySize)
1302 	, m_texture		(format, size, arraySize)
1303 {
1304 	allocateLevels(m_texture);
1305 	TestTexture::populateLevels(getLevelsVector(m_texture));
1306 }
1307 
TestTextureCubeArray(const tcu::CompressedTexFormat & format,int size,int arraySize)1308 TestTextureCubeArray::TestTextureCubeArray (const tcu::CompressedTexFormat& format, int size, int arraySize)
1309 	: TestTexture	(format, size, size, arraySize)
1310 	, m_texture		(tcu::getUncompressedFormat(format), size, arraySize)
1311 {
1312 	DE_ASSERT(arraySize % 6 == 0);
1313 
1314 	allocateLevels(m_texture);
1315 
1316 	std::vector<tcu::PixelBufferAccess> layers;
1317 	for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
1318 		for (int layerNdx = 0; layerNdx < m_texture.getDepth(); layerNdx++)
1319 			layers.push_back(getLevel(levelNdx, layerNdx));
1320 
1321 	TestTexture::populateCompressedLevels(format, layers);
1322 }
1323 
~TestTextureCubeArray(void)1324 TestTextureCubeArray::~TestTextureCubeArray (void)
1325 {
1326 }
1327 
getNumLevels(void) const1328 int TestTextureCubeArray::getNumLevels (void) const
1329 {
1330 	return m_texture.getNumLevels();
1331 }
1332 
getLevel(int level,int layer)1333 tcu::PixelBufferAccess TestTextureCubeArray::getLevel (int level, int layer)
1334 {
1335 	const tcu::PixelBufferAccess	levelLayers	= m_texture.getLevel(level);
1336 	const deUint32					layerSize	= levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1337 	const deUint32					layerOffset	= layerSize * layer;
1338 
1339 	return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1340 }
1341 
getLevel(int level,int layer) const1342 const tcu::ConstPixelBufferAccess TestTextureCubeArray::getLevel (int level, int layer) const
1343 {
1344 	const tcu::ConstPixelBufferAccess	levelLayers	= m_texture.getLevel(level);
1345 	const deUint32						layerSize	= levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1346 	const deUint32						layerOffset	= layerSize * layer;
1347 
1348 	return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1349 }
1350 
getArraySize(void) const1351 int TestTextureCubeArray::getArraySize (void) const
1352 {
1353 	return m_texture.getDepth();
1354 }
1355 
getTexture(void) const1356 const tcu::TextureCubeArray& TestTextureCubeArray::getTexture (void) const
1357 {
1358 	return m_texture;
1359 }
1360 
getTexture(void)1361 tcu::TextureCubeArray& TestTextureCubeArray::getTexture (void)
1362 {
1363 	return m_texture;
1364 }
1365 
copy(const tcu::TextureFormat format) const1366 de::MovePtr<TestTexture> TestTextureCubeArray::copy(const tcu::TextureFormat format) const
1367 {
1368 	DE_ASSERT(!isCompressed());
1369 
1370 	de::MovePtr<TestTexture>	texture	(new TestTextureCubeArray(format, m_texture.getSize(), getArraySize()));
1371 
1372 	copyToTexture(*texture);
1373 
1374 	return texture;
1375 }
1376 
1377 } // pipeline
1378 } // vkt
1379