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