• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2020 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Modifiers tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktModifiersTests.hpp"
25 #include "vktTestCase.hpp"
26 #include "vktTestGroupUtil.hpp"
27 #include "vktTestCaseUtil.hpp"
28 #include "vktExternalMemoryUtil.hpp"
29 #include "vktImageTestsUtil.hpp"
30 #include "vkRefUtil.hpp"
31 #include "vkBufferWithMemory.hpp"
32 #include "vkBarrierUtil.hpp"
33 #include "vkCmdUtil.hpp"
34 #include "vkObjUtil.hpp"
35 #include "vkImageUtil.hpp"
36 #include "vkTypeUtil.hpp"
37 #include "tcuTestLog.hpp"
38 #include "tcuTexture.hpp"
39 #include "tcuTextureUtil.hpp"
40 #include "tcuImageIO.hpp"
41 #include "tcuImageCompare.hpp"
42 #include "tcuMaybe.hpp"
43 #include "deUniquePtr.hpp"
44 #include "deStringUtil.hpp"
45 
46 #include <string>
47 #include <vector>
48 #include <algorithm>
49 #include <iterator>
50 
51 namespace vkt
52 {
53 namespace modifiers
54 {
55 namespace
56 {
57 using namespace vk;
58 using tcu::UVec2;
59 using tcu::TestLog;
60 
checkModifiersSupported(Context & context,VkFormat)61 void checkModifiersSupported (Context& context, VkFormat)
62 {
63 	if (!context.isDeviceFunctionalitySupported("VK_EXT_image_drm_format_modifier"))
64 		TCU_THROW(NotSupportedError, "VK_EXT_image_drm_format_modifier is not supported");
65 
66 	if (!context.isInstanceFunctionalitySupported("VK_KHR_get_physical_device_properties2"))
67 		TCU_THROW(TestError, "VK_KHR_get_physical_device_properties2 not supported");
68 
69 	if (!context.isDeviceFunctionalitySupported("VK_KHR_bind_memory2"))
70 		TCU_THROW(TestError, "VK_KHR_bind_memory2 not supported");
71 
72 	if (!context.isDeviceFunctionalitySupported("VK_KHR_image_format_list"))
73 		TCU_THROW(TestError, "VK_KHR_image_format_list not supported");
74 }
75 
getFormatCaseName(VkFormat format)76 std::string getFormatCaseName (VkFormat format)
77 {
78 	return de::toLower(de::toString(getFormatStr(format)).substr(10));
79 }
80 
getDrmFormatModifiers(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,VkFormat format)81 std::vector<VkDrmFormatModifierPropertiesEXT> getDrmFormatModifiers (const InstanceInterface&	vki,
82 																	 VkPhysicalDevice			physicalDevice,
83 																	 VkFormat					format)
84 {
85 	VkDrmFormatModifierPropertiesListEXT			modifierProperties;
86 	deMemset(&modifierProperties, 0, sizeof(modifierProperties));
87 
88 	modifierProperties.sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT;
89 	VkFormatProperties2								formatProperties;
90 	deMemset(&formatProperties, 0, sizeof(formatProperties));
91 
92 	std::vector<VkDrmFormatModifierPropertiesEXT>	drmFormatModifiers;
93 	formatProperties.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
94 	formatProperties.pNext = &modifierProperties;
95 
96 	vki.getPhysicalDeviceFormatProperties2(physicalDevice, format, &formatProperties);
97 
98 	drmFormatModifiers.resize(modifierProperties.drmFormatModifierCount);
99 	modifierProperties.pDrmFormatModifierProperties = drmFormatModifiers.data();
100 
101 	vki.getPhysicalDeviceFormatProperties2(physicalDevice, format, &formatProperties);
102 
103 	return drmFormatModifiers;
104 }
105 
106 // Returns true if the image with the given parameters and modifiers supports the given handle type.
verifyHandleTypeForFormatModifier(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,const VkFormat format,const VkImageType imageType,const VkImageUsageFlags imageUsages,const VkExternalMemoryHandleTypeFlags handleType,const deUint64 drmFormatModifier)107 bool verifyHandleTypeForFormatModifier (const InstanceInterface&				vki,
108 									    VkPhysicalDevice						physicalDevice,
109 									    const VkFormat							format,
110 									    const VkImageType						imageType,
111 									    const VkImageUsageFlags					imageUsages,
112 									    const VkExternalMemoryHandleTypeFlags	handleType,
113 									    const deUint64							drmFormatModifier)
114 {
115 	const VkPhysicalDeviceImageDrmFormatModifierInfoEXT imageFormatModifierInfo =
116 	{
117 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
118 		DE_NULL,
119 		drmFormatModifier,
120 		VK_SHARING_MODE_EXCLUSIVE,
121 		0,
122 		DE_NULL,
123 	};
124 
125 	const VkPhysicalDeviceExternalImageFormatInfo externalImageFormatInfo =
126 	{
127 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
128 		&imageFormatModifierInfo,
129 		(VkExternalMemoryHandleTypeFlagBits)handleType,
130 	};
131 
132 	const VkPhysicalDeviceImageFormatInfo2 imageFormatInfo =
133 	{
134 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
135 		&externalImageFormatInfo,
136 		format,
137 		imageType,
138 		VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
139 		imageUsages,
140 		0,
141 	};
142 
143 	VkExternalImageFormatProperties	externalImageProperties	= initVulkanStructure();
144 	VkImageFormatProperties2		imageProperties			= initVulkanStructure(&externalImageProperties);
145 
146 	if (vki.getPhysicalDeviceImageFormatProperties2(physicalDevice, &imageFormatInfo, &imageProperties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
147 		return false;
148 
149 	if ((externalImageProperties.externalMemoryProperties.compatibleHandleTypes & handleType) != handleType)
150 		return false;
151 
152 	return true;
153 }
154 
getExportImportCompatibleModifiers(Context & context,VkFormat format)155 std::vector<deUint64> getExportImportCompatibleModifiers (Context& context, VkFormat format)
156 {
157 	const auto&				vki					= context.getInstanceInterface();
158 	const auto				drmFormatModifiers	= getDrmFormatModifiers(vki, context.getPhysicalDevice(), format);
159 	std::vector<deUint64>	compatibleModifiers;
160 
161 	if (drmFormatModifiers.empty())
162 		return compatibleModifiers;
163 
164 	const VkFormatFeatureFlags testFeatures = (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT);
165 
166 	for (const auto& modifierProps : drmFormatModifiers)
167 	{
168 		if ((modifierProps.drmFormatModifierTilingFeatures & testFeatures) != testFeatures)
169 			continue;
170 
171 		const auto&	modifier	= modifierProps.drmFormatModifier;
172 		const auto	supported	= verifyHandleTypeForFormatModifier(vki, context.getPhysicalDevice(), format,
173 																	VK_IMAGE_TYPE_2D,
174 																	(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT),
175 																	VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
176 																	modifier);
177 
178 		if (!supported)
179 			continue;
180 
181 		compatibleModifiers.push_back(modifier);
182 	}
183 
184 	return compatibleModifiers;
185 }
186 
checkExportImportExtensions(Context & context,VkFormat format)187 void checkExportImportExtensions (Context& context, VkFormat format)
188 {
189 	// tcuTexture.cpp getChannelSize, that is used by intThresholdCompare does not support the following formats.
190 	// TODO: Add tcuTexture.cpp support for the following formats.
191 	const VkFormat					skippedFormats[]				=
192 	{
193 		VK_FORMAT_B10G11R11_UFLOAT_PACK32,
194 		VK_FORMAT_A2R10G10B10_UNORM_PACK32,
195 		VK_FORMAT_A2R10G10B10_SNORM_PACK32,
196 		VK_FORMAT_A2R10G10B10_USCALED_PACK32,
197 		VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
198 		VK_FORMAT_A2R10G10B10_UINT_PACK32,
199 		VK_FORMAT_A2R10G10B10_SINT_PACK32,
200 		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
201 		VK_FORMAT_A2B10G10R10_SNORM_PACK32,
202 		VK_FORMAT_A2B10G10R10_USCALED_PACK32,
203 		VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
204 		VK_FORMAT_A2B10G10R10_UINT_PACK32,
205 		VK_FORMAT_A2B10G10R10_SINT_PACK32,
206 	};
207 
208 	if (std::find(std::begin(skippedFormats), std::end(skippedFormats), format) != std::end(skippedFormats))
209 		TCU_THROW(NotSupportedError, de::toString(format) + " can't be checked for correctness");
210 
211 	if (!context.isDeviceFunctionalitySupported("VK_KHR_external_memory_fd"))
212 		TCU_THROW(NotSupportedError, "VK_KHR_external_memory_fd not supported");
213 
214 	checkModifiersSupported(context, format);
215 
216 	const auto compatibleModifiers = getExportImportCompatibleModifiers(context, format);
217 	if (compatibleModifiers.empty())
218 		TCU_THROW(NotSupportedError, "Could not find a format modifier supporting required transfer features for " + de::toString(format));
219 }
220 
isModifierCompatibleWithImageProperties(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,const VkFormat * formats,const deUint32 nFormats,const VkImageType imageType,const VkImageUsageFlags imageUsages,const deUint64 drmFormatModifier,VkImageFormatProperties2 & imageProperties)221 deBool isModifierCompatibleWithImageProperties (const InstanceInterface&	vki,
222 												VkPhysicalDevice			physicalDevice,
223 												const VkFormat*				formats,
224 												const deUint32				nFormats,
225 												const VkImageType			imageType,
226 												const VkImageUsageFlags		imageUsages,
227 												const deUint64				drmFormatModifier,
228 												VkImageFormatProperties2&	imageProperties)
229 {
230 	const VkPhysicalDeviceImageDrmFormatModifierInfoEXT	imageFormatModifierInfo	=
231 	{
232 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
233 		DE_NULL,
234 		drmFormatModifier,
235 		VK_SHARING_MODE_EXCLUSIVE,
236 		0,
237 		DE_NULL,
238 	};
239 	const VkImageFormatListCreateInfoKHR				imageFormatListInfo		=
240 	{
241 		VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR,
242 		&imageFormatModifierInfo,
243 		nFormats,
244 		formats,
245 	};
246 	const VkPhysicalDeviceImageFormatInfo2				imageFormatInfo			=
247 	{
248 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
249 		&imageFormatListInfo,
250 		formats[0],
251 		imageType,
252 		VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
253 		imageUsages,
254 		0,
255 	};
256 
257 	imageProperties.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
258 
259 	return vki.getPhysicalDeviceImageFormatProperties2(physicalDevice, &imageFormatInfo, &imageProperties) != VK_ERROR_FORMAT_NOT_SUPPORTED;
260 }
261 
listModifiersCase(Context & context,VkFormat format)262 tcu::TestStatus listModifiersCase (Context& context, VkFormat format)
263 {
264 	TestLog&										log					= context.getTestContext().getLog();
265 	const InstanceInterface&						vki					= context.getInstanceInterface();
266 	std::vector<VkDrmFormatModifierPropertiesEXT>	drmFormatModifiers	= getDrmFormatModifiers(vki, context.getPhysicalDevice(), format);
267 	bool											noneCompatible		= true;
268 
269 	if (drmFormatModifiers.empty())
270 		TCU_THROW(NotSupportedError, de::toString(format) + " does not support any DRM modifiers");
271 
272 	for (deUint32 m = 0; m < drmFormatModifiers.size(); m++) {
273 		VkImageFormatProperties2	imageProperties {};
274 		deBool						isCompatible	= isModifierCompatibleWithImageProperties(vki, context.getPhysicalDevice(),
275 																							  &format, 1u, VK_IMAGE_TYPE_2D,
276 																							  (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT),
277 																							  drmFormatModifiers[m].drmFormatModifier, imageProperties);
278 
279 		if (!isCompatible)
280 			continue;
281 		noneCompatible = false;
282 
283 		TCU_CHECK(imageProperties.imageFormatProperties.maxExtent.width >= 1 && imageProperties.imageFormatProperties.maxExtent.height >= 1);
284 		TCU_CHECK(imageProperties.imageFormatProperties.maxArrayLayers >= 1);
285 
286 		log << TestLog::Message
287 			<< "format modifier " << m << ":\n"
288 			<< drmFormatModifiers[m] << "\n"
289 			<< imageProperties
290 			<< TestLog::EndMessage;
291 	}
292 
293 	if (noneCompatible)
294 		TCU_THROW(NotSupportedError, de::toString(format) + " does not support any DRM modifiers for the requested image features");
295 
296 	return tcu::TestStatus::pass("OK");
297 }
298 
createImageNoModifiers(const DeviceInterface & vkd,const VkDevice device,const VkImageUsageFlags imageUsages,const VkFormat format,const UVec2 & size)299 Move<VkImage> createImageNoModifiers (const DeviceInterface&			vkd,
300 												 const VkDevice					device,
301 												 const VkImageUsageFlags		imageUsages,
302 												 const VkFormat					format,
303 												 const UVec2&					size)
304 {
305 	const VkImageCreateInfo							createInfo	=
306 	{
307 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
308 		DE_NULL,
309 		0,
310 		VK_IMAGE_TYPE_2D,
311 		format,
312 		makeExtent3D(size.x(), size.y(), 1u),
313 		1u,		// mipLevels
314 		1u,		// arrayLayers
315 		VK_SAMPLE_COUNT_1_BIT,
316 		VK_IMAGE_TILING_OPTIMAL,
317 		imageUsages,
318 		VK_SHARING_MODE_EXCLUSIVE,
319 		0u,
320 		(const deUint32*)DE_NULL,
321 		VK_IMAGE_LAYOUT_PREINITIALIZED,
322 	};
323 
324 	return createImage(vkd, device, &createInfo);
325 }
326 
createImageWithDrmFormatModifiers(const DeviceInterface & vkd,const VkDevice device,const VkImageType imageType,const VkImageUsageFlags imageUsages,const VkExternalMemoryHandleTypeFlags externalMemoryHandleTypeFlags,const std::vector<VkFormat> & formats,const UVec2 & size,const std::vector<deUint64> & drmFormatModifiers)327 Move<VkImage> createImageWithDrmFormatModifiers (const DeviceInterface&					vkd,
328 												 const VkDevice							device,
329 												 const VkImageType						imageType,
330 												 const VkImageUsageFlags				imageUsages,
331 												 const VkExternalMemoryHandleTypeFlags	externalMemoryHandleTypeFlags,
332 												 const std::vector<VkFormat>&			formats,
333 												 const UVec2&							size,
334 												 const std::vector<deUint64>&			drmFormatModifiers)
335 {
336 	const VkImageDrmFormatModifierListCreateInfoEXT	modifierListCreateInfo =
337 	{
338 		VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT,
339 		DE_NULL,
340 		(deUint32)drmFormatModifiers.size(),
341 		drmFormatModifiers.data(),
342 	};
343 
344 	const VkExternalMemoryImageCreateInfo externalMemoryCreateInfo =
345 	{
346 		VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
347 		&modifierListCreateInfo,
348 		externalMemoryHandleTypeFlags,
349 	};
350 
351 	const void* pNext = &externalMemoryCreateInfo;
352 	if (!externalMemoryHandleTypeFlags)
353 	{
354 		pNext = &modifierListCreateInfo;
355 	}
356 
357 	const VkImageFormatListCreateInfoKHR			imageFormatListInfo			=
358 	{
359 		VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR,
360 		pNext,
361 		static_cast<deUint32>(formats.size()),
362 		formats.data(),
363 	};
364 
365 	const VkImageCreateInfo							createInfo	=
366 	{
367 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
368 		&imageFormatListInfo,
369 		0,
370 		imageType,
371 		formats.front(),
372 		makeExtent3D(size.x(), size.y(), 1u),
373 		1u,		// mipLevels
374 		1u,		// arrayLayers
375 		VK_SAMPLE_COUNT_1_BIT,
376 		VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
377 		imageUsages,
378 		VK_SHARING_MODE_EXCLUSIVE,
379 		0u,
380 		(const deUint32*)DE_NULL,
381 		VK_IMAGE_LAYOUT_UNDEFINED,
382 	};
383 
384 	return createImage(vkd, device, &createInfo);
385 }
386 
createImageListModifiersCase(Context & context,const VkFormat format)387 tcu::TestStatus createImageListModifiersCase (Context& context, const VkFormat format)
388 {
389 	const InstanceInterface&						vki					= context.getInstanceInterface();
390 	const DeviceInterface&							vkd					= context.getDeviceInterface();
391 	const VkDevice									device				= context.getDevice();
392 	std::vector<VkDrmFormatModifierPropertiesEXT>	drmFormatModifiers	= getDrmFormatModifiers(vki, context.getPhysicalDevice(), format);
393 
394 	if (drmFormatModifiers.empty())
395 		TCU_THROW(NotSupportedError, de::toString(format) + " does not support any DRM modifiers");
396 
397 	// Get the list of modifiers supported for some specific image parameters.
398 	std::vector<deUint64> modifiers;
399 
400 	for (const auto& modProps : drmFormatModifiers)
401 	{
402 		VkImageFormatProperties2	imgFormatProperties	= initVulkanStructure();
403 		const auto					isCompatible		= isModifierCompatibleWithImageProperties(vki, context.getPhysicalDevice(), &format, 1u, VK_IMAGE_TYPE_2D,
404 																								  (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT),
405 																								  modProps.drmFormatModifier, imgFormatProperties);
406 		if (isCompatible)
407 			modifiers.push_back(modProps.drmFormatModifier);
408 	}
409 
410 	if (modifiers.empty())
411 		TCU_THROW(NotSupportedError, de::toString(format) + " does not support any DRM modifiers for the requested image features");
412 
413 	// Test with lists of compatible modifiers of increasing lengths.
414 	for (size_t len = 1u; len <= modifiers.size(); ++len)
415 	{
416 		std::vector<deUint64> creationModifiers;
417 		creationModifiers.reserve(len);
418 		std::copy_n(begin(modifiers), len, std::back_inserter(creationModifiers));
419 
420 		VkImageDrmFormatModifierPropertiesEXT	properties	= initVulkanStructure();
421 
422 		{
423 			std::vector<VkFormat>	formats	(1u, format);
424 			const auto				image	= createImageWithDrmFormatModifiers(vkd, device, VK_IMAGE_TYPE_2D,
425 																				(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT),
426 																				0, formats, UVec2(64, 64), creationModifiers);
427 
428 			VK_CHECK(vkd.getImageDrmFormatModifierPropertiesEXT(device, *image, &properties));
429 		}
430 
431 		if (!de::contains(begin(creationModifiers), end(creationModifiers), properties.drmFormatModifier))
432 			return tcu::TestStatus::fail("Image created with modifier not specified in the create list");
433 	}
434 
435 	return tcu::TestStatus::pass("OK");
436 }
437 
chooseMemoryType(deUint32 bits)438 deUint32 chooseMemoryType(deUint32 bits)
439 {
440 	DE_ASSERT(bits != 0);
441 
442 	for (deUint32 memoryTypeIndex = 0; (1u << memoryTypeIndex) <= bits; memoryTypeIndex++)
443 	{
444 		if ((bits & (1u << memoryTypeIndex)) != 0)
445 			return memoryTypeIndex;
446 	}
447 
448 	DE_FATAL("No supported memory types");
449 	return -1;
450 }
451 
exportImportMemoryExplicitModifiersCase(Context & context,const VkFormat format,deUint64 modifier)452 bool exportImportMemoryExplicitModifiersCase (Context& context, const VkFormat format, deUint64 modifier)
453 {
454 	const InstanceInterface&						vki					= context.getInstanceInterface();
455 	const DeviceInterface&							vkd					= context.getDeviceInterface();
456 	const VkDevice									device				= context.getDevice();
457 
458 
459 	const auto supported = verifyHandleTypeForFormatModifier(vki, context.getPhysicalDevice(), format,
460 															 VK_IMAGE_TYPE_2D,
461 															 (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT),
462 															 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
463 															 modifier);
464 
465 	if (!supported)
466 		TCU_FAIL("Modifier " + de::toString(modifier) + " for format " + de::toString(format) + " expected to be compatible");
467 
468 	std::vector<deUint64>					modifiers;
469 	modifiers.push_back(modifier);
470 
471 
472 	const UVec2									imageSize		(64, 64);
473 	const tcu::TextureFormat referenceTextureFormat (mapVkFormat(format));
474 	deUint32 bufferSize = 1<<16;
475 	const de::UniquePtr<BufferWithMemory>		inputBuffer		(new BufferWithMemory(vkd, device, context.getDefaultAllocator(),
476 																																							makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT),
477 																						MemoryRequirement::HostVisible));
478 	tcu::PixelBufferAccess				referenceImage	(referenceTextureFormat, imageSize.x(), imageSize.y(), 1, inputBuffer->getAllocation().getHostPtr());
479 	const de::UniquePtr<BufferWithMemory>		outputBuffer		(new BufferWithMemory(vkd, device, context.getDefaultAllocator(),
480 																																							makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT),
481 																						MemoryRequirement::HostVisible));
482 	Unique<VkCommandPool>			cmdPool				(createCommandPool(vkd, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex(), DE_NULL));
483 	vkt::ExternalMemoryUtil::NativeHandle								inputImageMemFd;
484 
485 	const tcu::TextureFormatInfo				formatInfo		(tcu::getTextureFormatInfo(referenceTextureFormat));
486 	tcu::fillWithComponentGradients(referenceImage, formatInfo.valueMin, formatInfo.valueMax);
487 
488 	flushAlloc(vkd, device, inputBuffer->getAllocation());
489 
490 	Move<VkImage>						srcImage		(createImageNoModifiers(vkd, device,
491 																								 VK_IMAGE_USAGE_TRANSFER_DST_BIT |
492 																								 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
493 																								 format, UVec2(64, 64)));
494 	VkMemoryRequirements srcImageMemoryReq = getImageMemoryRequirements(vkd, device, *srcImage);
495 	const vk::VkMemoryAllocateInfo	allocationInfo	=
496 	{
497 		vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
498 		DE_NULL,
499 		srcImageMemoryReq.size,
500 		chooseMemoryType(srcImageMemoryReq.memoryTypeBits),
501 	};
502 	vk::Move<vk::VkDeviceMemory>	srcMemory			(vk::allocateMemory(vkd, device, &allocationInfo));
503 	VK_CHECK(vkd.bindImageMemory(device, *srcImage, *srcMemory, 0));
504 
505 
506 	Unique<VkCommandBuffer>			cmdBuffer			(allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
507 	const VkCommandBufferBeginInfo	cmdBufferBeginInfo	=
508 	{
509 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
510 		DE_NULL,
511 		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
512 		(const VkCommandBufferInheritanceInfo*)DE_NULL,
513 	};
514 
515 	VK_CHECK(vkd.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
516 
517 	{
518 		const VkImageAspectFlags		aspect				= VK_IMAGE_ASPECT_COLOR_BIT;
519 		std::vector<VkBufferImageCopy>	copies;
520 
521 		copies.push_back(image::makeBufferImageCopy(makeExtent3D(imageSize.x(), imageSize.y(), 1u), 1u));
522 		copyBufferToImage(vkd, *cmdBuffer, inputBuffer->get(), bufferSize,
523 											copies, aspect, 1, 1, *srcImage,
524 											VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
525 
526 	}
527 
528 	Move<VkImage>						dstImage		(createImageWithDrmFormatModifiers(vkd, device, VK_IMAGE_TYPE_2D,
529 																																				 VK_IMAGE_USAGE_TRANSFER_DST_BIT |
530 																																				 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
531 																																				 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
532 																																				 {format}, UVec2(64, 64), modifiers));
533 	VkMemoryRequirements dstImageMemoryReq = getImageMemoryRequirements(vkd, device, *dstImage);
534 	vk::Move<vk::VkDeviceMemory>	dstMemory			(vkt::ExternalMemoryUtil::allocateExportableMemory(vkd, device,
535 																																																 dstImageMemoryReq.size,
536 																																																 chooseMemoryType(dstImageMemoryReq.memoryTypeBits),
537 																																																 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
538 																																																 *dstImage));
539 
540 	VK_CHECK(vkd.bindImageMemory(device, *dstImage, *dstMemory, 0));
541 	const VkImageMemoryBarrier		srcImageBarrier		=
542 	{
543 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
544 		DE_NULL,									// const void*				pNext;
545 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
546 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
547 		VK_IMAGE_LAYOUT_UNDEFINED,		// VkImageLayout			oldLayout;
548 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,			// VkImageLayout			newLayout;
549 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
550 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
551 		*srcImage,						// VkImage					image;
552 		{											// VkImageSubresourceRange	subresourceRange;
553 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
554 			0u,								// deUint32				baseMipLevel;
555 			1u,								// deUint32				mipLevels;
556 			0u,								// deUint32				baseArraySlice;
557 			1u								// deUint32				arraySize;
558 		}
559 	};
560 	const VkImageMemoryBarrier		dstImageBarrier		=
561 	{
562 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
563 		DE_NULL,									// const void*				pNext;
564 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
565 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
566 		VK_IMAGE_LAYOUT_UNDEFINED,		// VkImageLayout			oldLayout;
567 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout;
568 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
569 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
570 		*dstImage,						// VkImage					image;
571 		{											// VkImageSubresourceRange	subresourceRange;
572 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
573 			0u,								// deUint32				baseMipLevel;
574 			1u,								// deUint32				mipLevels;
575 			0u,								// deUint32				baseArraySlice;
576 			1u								// deUint32				arraySize;
577 		}
578 	};
579 	vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &srcImageBarrier);
580 	vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &dstImageBarrier);
581 
582 	VkImageBlit		imageBlit
583 	{
584 		{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1},
585 		{{0,0,0}, {64,64,1}},
586 		{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1},
587 		{{0,0,0}, {64,64,1}},
588 	};
589 	vkd.cmdBlitImage(*cmdBuffer, *srcImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *dstImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &imageBlit, VK_FILTER_NEAREST);
590 
591 	VK_CHECK(vkd.endCommandBuffer(*cmdBuffer));
592 	submitCommandsAndWait(vkd, device, context.getUniversalQueue(), *cmdBuffer);
593 	VkImageDrmFormatModifierPropertiesEXT	properties;
594 	deMemset(&properties, 0, sizeof(properties));
595 	properties.sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT;
596 	VK_CHECK(vkd.getImageDrmFormatModifierPropertiesEXT(device, *dstImage, &properties));
597 	TCU_CHECK(properties.drmFormatModifier == modifiers.front());
598 	inputImageMemFd	= vkt::ExternalMemoryUtil::getMemoryFd(vkd, device, *dstMemory, VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT);
599 
600 	Move<VkImage>				importedSrcImage		(createImageWithDrmFormatModifiers(vkd, device, VK_IMAGE_TYPE_2D,
601 																																						 VK_IMAGE_USAGE_TRANSFER_DST_BIT |
602 																																						 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
603 																																						 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
604 																																						 {format}, UVec2(64, 64), modifiers));
605 
606 	VkMemoryRequirements importedSrcImageMemoryReq = getImageMemoryRequirements(vkd, device, *importedSrcImage);
607 
608 	Move<VkDeviceMemory>						importedMemory (vkt::ExternalMemoryUtil::importMemory(vkd, device,
609 																									importedSrcImageMemoryReq,
610 																									VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
611 																									~0u, inputImageMemFd));
612 	VK_CHECK(vkd.bindImageMemory(device, *importedSrcImage, *importedMemory, 0));
613 
614 	Move<VkImage>						outImage		(createImageNoModifiers(vkd, device,
615 																															VK_IMAGE_USAGE_TRANSFER_DST_BIT |
616 																															VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
617 																															format, UVec2(64, 64)));
618 	VkMemoryRequirements outImageMemoryReq = getImageMemoryRequirements(vkd, device, *outImage);
619 	const vk::VkMemoryAllocateInfo	outAllocationInfo	=
620 	{
621 		vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
622 		DE_NULL,
623 		outImageMemoryReq.size,
624 		chooseMemoryType(outImageMemoryReq.memoryTypeBits),
625 	};
626 	vk::Move<vk::VkDeviceMemory>	outMemory			(vk::allocateMemory(vkd, device, &outAllocationInfo));
627 	VK_CHECK(vkd.bindImageMemory(device, *outImage, *outMemory, 0));
628 
629 	Unique<VkCommandBuffer>			cmdBuffer2			(allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
630 	VK_CHECK(vkd.beginCommandBuffer(*cmdBuffer2, &cmdBufferBeginInfo));
631 
632 	const VkImageMemoryBarrier		importedImageBarrier		=
633 	{
634 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
635 		DE_NULL,									// const void*				pNext;
636 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
637 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
638 		VK_IMAGE_LAYOUT_PREINITIALIZED,		// VkImageLayout			oldLayout;
639 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,			// VkImageLayout			newLayout;
640 		VK_QUEUE_FAMILY_FOREIGN_EXT,					// deUint32					srcQueueFamilyIndex;
641 		context.getUniversalQueueFamilyIndex(),			// deUint32					dstQueueFamilyIndex;
642 		*importedSrcImage,						// VkImage					image;
643 		{											// VkImageSubresourceRange	subresourceRange;
644 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
645 			0u,								// deUint32				baseMipLevel;
646 			1u,								// deUint32				mipLevels;
647 			0u,								// deUint32				baseArraySlice;
648 			1u								// deUint32				arraySize;
649 		}
650 	};
651 	const VkImageMemoryBarrier		outImageBarrier		=
652 	{
653 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
654 		DE_NULL,									// const void*				pNext;
655 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
656 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
657 		VK_IMAGE_LAYOUT_UNDEFINED,		// VkImageLayout			oldLayout;
658 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout;
659 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
660 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
661 		*outImage,						// VkImage					image;
662 		{											// VkImageSubresourceRange	subresourceRange;
663 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
664 			0u,								// deUint32				baseMipLevel;
665 			1u,								// deUint32				mipLevels;
666 			0u,								// deUint32				baseArraySlice;
667 			1u								// deUint32				arraySize;
668 		}
669 	};
670 
671 	vkd.cmdPipelineBarrier(*cmdBuffer2, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &importedImageBarrier);
672 	vkd.cmdPipelineBarrier(*cmdBuffer2, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &outImageBarrier);
673 
674 	VkImageBlit		imageBlit2
675 	{
676 		{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1},
677 		{{0,0,0}, {64,64,1}},
678 		{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1},
679 		{{0,0,0}, {64,64,1}},
680 	};
681 	vkd.cmdBlitImage(*cmdBuffer2, *importedSrcImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *outImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &imageBlit2, VK_FILTER_NEAREST);
682 
683 
684 	copyImageToBuffer(vkd, *cmdBuffer2, *outImage,
685 										outputBuffer->get(), tcu::IVec2(imageSize.x(), imageSize.y()),
686 										VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, 1);
687 
688 	VK_CHECK(vkd.endCommandBuffer(*cmdBuffer2));
689 
690 	submitCommandsAndWait(vkd, device, context.getUniversalQueue(), *cmdBuffer2);
691 
692 
693 	tcu::ConstPixelBufferAccess	result	(referenceTextureFormat, imageSize.x(), imageSize.y(), 1, outputBuffer->getAllocation().getHostPtr());
694 	const tcu::UVec4 threshold (0u);
695 
696 	return tcu::intThresholdCompare(context.getTestContext().getLog(), "Compare", "Result comparison", referenceImage, result, threshold, tcu::COMPARE_LOG_RESULT);
697 }
698 
exportImportMemoryExplicitModifiersCase(Context & context,const VkFormat format)699 tcu::TestStatus exportImportMemoryExplicitModifiersCase (Context& context, const VkFormat format)
700 {
701 	const auto compatibleModifiers = getExportImportCompatibleModifiers(context, format);
702 
703 	if (compatibleModifiers.empty())
704 		TCU_FAIL("Expected non-empty list of compatible modifiers for the given format");
705 
706 	for (const auto& modifier : compatibleModifiers)
707 	{
708 		if (!exportImportMemoryExplicitModifiersCase(context, format, modifier))
709 			return tcu::TestStatus::fail("Unexpected copy image result");
710 	}
711 
712 	return tcu::TestStatus::pass("OK");
713 }
714 
715 } // anonymous
716 
createTests(tcu::TestContext & testCtx)717 tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx)
718 {
719 	de::MovePtr<tcu::TestCaseGroup>	drmFormatModifiersGroup	(new tcu::TestCaseGroup(testCtx, "drm_format_modifiers", "DRM format modifiers tests"));
720 	const VkFormat					formats[]				=
721 	{
722 		VK_FORMAT_R4G4_UNORM_PACK8,
723 		VK_FORMAT_R4G4B4A4_UNORM_PACK16,
724 		VK_FORMAT_B4G4R4A4_UNORM_PACK16,
725 		VK_FORMAT_R5G6B5_UNORM_PACK16,
726 		VK_FORMAT_B5G6R5_UNORM_PACK16,
727 		VK_FORMAT_R5G5B5A1_UNORM_PACK16,
728 		VK_FORMAT_B5G5R5A1_UNORM_PACK16,
729 		VK_FORMAT_A1R5G5B5_UNORM_PACK16,
730 		VK_FORMAT_R8_UNORM,
731 		VK_FORMAT_R8_SNORM,
732 		VK_FORMAT_R8_USCALED,
733 		VK_FORMAT_R8_SSCALED,
734 		VK_FORMAT_R8_UINT,
735 		VK_FORMAT_R8_SINT,
736 		VK_FORMAT_R8_SRGB,
737 		VK_FORMAT_R8G8_UNORM,
738 		VK_FORMAT_R8G8_SNORM,
739 		VK_FORMAT_R8G8_USCALED,
740 		VK_FORMAT_R8G8_SSCALED,
741 		VK_FORMAT_R8G8_UINT,
742 		VK_FORMAT_R8G8_SINT,
743 		VK_FORMAT_R8G8_SRGB,
744 		VK_FORMAT_R8G8B8_UNORM,
745 		VK_FORMAT_R8G8B8_SNORM,
746 		VK_FORMAT_R8G8B8_USCALED,
747 		VK_FORMAT_R8G8B8_SSCALED,
748 		VK_FORMAT_R8G8B8_UINT,
749 		VK_FORMAT_R8G8B8_SINT,
750 		VK_FORMAT_R8G8B8_SRGB,
751 		VK_FORMAT_B8G8R8_UNORM,
752 		VK_FORMAT_B8G8R8_SNORM,
753 		VK_FORMAT_B8G8R8_USCALED,
754 		VK_FORMAT_B8G8R8_SSCALED,
755 		VK_FORMAT_B8G8R8_UINT,
756 		VK_FORMAT_B8G8R8_SINT,
757 		VK_FORMAT_B8G8R8_SRGB,
758 		VK_FORMAT_R8G8B8A8_UNORM,
759 		VK_FORMAT_R8G8B8A8_SNORM,
760 		VK_FORMAT_R8G8B8A8_USCALED,
761 		VK_FORMAT_R8G8B8A8_SSCALED,
762 		VK_FORMAT_R8G8B8A8_UINT,
763 		VK_FORMAT_R8G8B8A8_SINT,
764 		VK_FORMAT_R8G8B8A8_SRGB,
765 		VK_FORMAT_B8G8R8A8_UNORM,
766 		VK_FORMAT_B8G8R8A8_SNORM,
767 		VK_FORMAT_B8G8R8A8_USCALED,
768 		VK_FORMAT_B8G8R8A8_SSCALED,
769 		VK_FORMAT_B8G8R8A8_UINT,
770 		VK_FORMAT_B8G8R8A8_SINT,
771 		VK_FORMAT_B8G8R8A8_SRGB,
772 		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
773 		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
774 		VK_FORMAT_A8B8G8R8_USCALED_PACK32,
775 		VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
776 		VK_FORMAT_A8B8G8R8_UINT_PACK32,
777 		VK_FORMAT_A8B8G8R8_SINT_PACK32,
778 		VK_FORMAT_A8B8G8R8_SRGB_PACK32,
779 		VK_FORMAT_A2R10G10B10_UNORM_PACK32,
780 		VK_FORMAT_A2R10G10B10_SNORM_PACK32,
781 		VK_FORMAT_A2R10G10B10_USCALED_PACK32,
782 		VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
783 		VK_FORMAT_A2R10G10B10_UINT_PACK32,
784 		VK_FORMAT_A2R10G10B10_SINT_PACK32,
785 		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
786 		VK_FORMAT_A2B10G10R10_SNORM_PACK32,
787 		VK_FORMAT_A2B10G10R10_USCALED_PACK32,
788 		VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
789 		VK_FORMAT_A2B10G10R10_UINT_PACK32,
790 		VK_FORMAT_A2B10G10R10_SINT_PACK32,
791 		VK_FORMAT_R16_UNORM,
792 		VK_FORMAT_R16_SNORM,
793 		VK_FORMAT_R16_USCALED,
794 		VK_FORMAT_R16_SSCALED,
795 		VK_FORMAT_R16_UINT,
796 		VK_FORMAT_R16_SINT,
797 		VK_FORMAT_R16_SFLOAT,
798 		VK_FORMAT_R16G16_UNORM,
799 		VK_FORMAT_R16G16_SNORM,
800 		VK_FORMAT_R16G16_USCALED,
801 		VK_FORMAT_R16G16_SSCALED,
802 		VK_FORMAT_R16G16_UINT,
803 		VK_FORMAT_R16G16_SINT,
804 		VK_FORMAT_R16G16_SFLOAT,
805 		VK_FORMAT_R16G16B16_UNORM,
806 		VK_FORMAT_R16G16B16_SNORM,
807 		VK_FORMAT_R16G16B16_USCALED,
808 		VK_FORMAT_R16G16B16_SSCALED,
809 		VK_FORMAT_R16G16B16_UINT,
810 		VK_FORMAT_R16G16B16_SINT,
811 		VK_FORMAT_R16G16B16_SFLOAT,
812 		VK_FORMAT_R16G16B16A16_UNORM,
813 		VK_FORMAT_R16G16B16A16_SNORM,
814 		VK_FORMAT_R16G16B16A16_USCALED,
815 		VK_FORMAT_R16G16B16A16_SSCALED,
816 		VK_FORMAT_R16G16B16A16_UINT,
817 		VK_FORMAT_R16G16B16A16_SINT,
818 		VK_FORMAT_R16G16B16A16_SFLOAT,
819 		VK_FORMAT_R32_UINT,
820 		VK_FORMAT_R32_SINT,
821 		VK_FORMAT_R32_SFLOAT,
822 		VK_FORMAT_R32G32_UINT,
823 		VK_FORMAT_R32G32_SINT,
824 		VK_FORMAT_R32G32_SFLOAT,
825 		VK_FORMAT_R32G32B32_UINT,
826 		VK_FORMAT_R32G32B32_SINT,
827 		VK_FORMAT_R32G32B32_SFLOAT,
828 		VK_FORMAT_R32G32B32A32_UINT,
829 		VK_FORMAT_R32G32B32A32_SINT,
830 		VK_FORMAT_R32G32B32A32_SFLOAT,
831 		VK_FORMAT_R64_UINT,
832 		VK_FORMAT_R64_SINT,
833 		VK_FORMAT_R64_SFLOAT,
834 		VK_FORMAT_R64G64_UINT,
835 		VK_FORMAT_R64G64_SINT,
836 		VK_FORMAT_R64G64_SFLOAT,
837 		VK_FORMAT_R64G64B64_UINT,
838 		VK_FORMAT_R64G64B64_SINT,
839 		VK_FORMAT_R64G64B64_SFLOAT,
840 		VK_FORMAT_R64G64B64A64_UINT,
841 		VK_FORMAT_R64G64B64A64_SINT,
842 		VK_FORMAT_R64G64B64A64_SFLOAT,
843 		VK_FORMAT_B10G11R11_UFLOAT_PACK32,
844 		VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
845 		VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
846 		VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
847 	};
848 
849 	{
850 		de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "list_modifiers", "Check that listing supported modifiers is functional"));
851 
852 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
853 			addFunctionCase(group.get(), getFormatCaseName(formats[formatNdx]), "Check that listing supported modifiers is functional", checkModifiersSupported, listModifiersCase, formats[formatNdx]);
854 
855 		drmFormatModifiersGroup->addChild(group.release());
856 	}
857 
858 	{
859 		de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "create_list_modifiers", "Check that creating images with modifier list is functional"));
860 
861 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
862 			addFunctionCase(group.get(), getFormatCaseName(formats[formatNdx]), "Check that creating images with modifier list is functional", checkModifiersSupported, createImageListModifiersCase, formats[formatNdx]);
863 
864 		drmFormatModifiersGroup->addChild(group.release());
865 	}
866 
867 	{
868 		de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "export_import", "Test exporting/importing images with modifiers"));
869 
870 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
871 			addFunctionCase(group.get(), getFormatCaseName(formats[formatNdx]), "Test exporting/importing images with modifiers", checkExportImportExtensions, exportImportMemoryExplicitModifiersCase, formats[formatNdx]);
872 
873 		drmFormatModifiersGroup->addChild(group.release());
874 	}
875 
876 	return drmFormatModifiersGroup.release();
877 }
878 
879 } // modifiers
880 } // vkt
881