• 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 
61 struct ExplicitModifier
62 {
63 	uint64_t				modifier;
64 	uint32_t				modifierPlaneCount;
65 	VkSubresourceLayout*	pPlaneLayouts;
66 };
67 
checkModifiersSupported(Context & context,VkFormat)68 void checkModifiersSupported (Context& context, VkFormat)
69 {
70 	if (!context.isDeviceFunctionalitySupported("VK_EXT_image_drm_format_modifier"))
71 		TCU_THROW(NotSupportedError, "VK_EXT_image_drm_format_modifier is not supported");
72 
73 	if (!context.isInstanceFunctionalitySupported("VK_KHR_get_physical_device_properties2"))
74 		TCU_THROW(NotSupportedError, "VK_KHR_get_physical_device_properties2 not supported");
75 
76 	if (!context.isDeviceFunctionalitySupported("VK_KHR_bind_memory2"))
77 		TCU_THROW(NotSupportedError, "VK_KHR_bind_memory2 not supported");
78 
79 	if (!context.isDeviceFunctionalitySupported("VK_KHR_image_format_list"))
80 		TCU_THROW(NotSupportedError, "VK_KHR_image_format_list not supported");
81 }
82 
checkModifiersList2Supported(Context & context,VkFormat fmt)83 void checkModifiersList2Supported (Context& context, VkFormat fmt)
84 {
85 	checkModifiersSupported(context, fmt);
86 
87 	if (!context.isDeviceFunctionalitySupported("VK_KHR_format_feature_flags2"))
88 		TCU_THROW(NotSupportedError, "VK_KHR_format_feature_flags2 not supported");
89 }
90 
getFormatCaseName(VkFormat format)91 std::string getFormatCaseName (VkFormat format)
92 {
93 	return de::toLower(de::toString(getFormatStr(format)).substr(10));
94 }
95 
96 template <typename ModifierList, typename ModifierProps, VkStructureType modifierListSType>
getDrmFormatModifiers(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,VkFormat format)97 std::vector<ModifierProps> getDrmFormatModifiers (const InstanceInterface&	vki,
98 												  VkPhysicalDevice			physicalDevice,
99 												  VkFormat					format)
100 {
101 	ModifierList									modifierProperties;
102 	deMemset(&modifierProperties, 0, sizeof(modifierProperties));
103 
104 	modifierProperties.sType = modifierListSType;
105 	VkFormatProperties2								formatProperties;
106 	deMemset(&formatProperties, 0, sizeof(formatProperties));
107 
108 	std::vector<ModifierProps>						drmFormatModifiers;
109 	formatProperties.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
110 	formatProperties.pNext = &modifierProperties;
111 
112 	vki.getPhysicalDeviceFormatProperties2(physicalDevice, format, &formatProperties);
113 
114 	drmFormatModifiers.resize(modifierProperties.drmFormatModifierCount);
115 	modifierProperties.pDrmFormatModifierProperties = drmFormatModifiers.data();
116 
117 	vki.getPhysicalDeviceFormatProperties2(physicalDevice, format, &formatProperties);
118 
119 	return drmFormatModifiers;
120 }
121 
122 // 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)123 bool verifyHandleTypeForFormatModifier (const InstanceInterface&				vki,
124 									    VkPhysicalDevice						physicalDevice,
125 									    const VkFormat							format,
126 									    const VkImageType						imageType,
127 									    const VkImageUsageFlags					imageUsages,
128 									    const VkExternalMemoryHandleTypeFlags	handleType,
129 									    const deUint64							drmFormatModifier)
130 {
131 	const VkPhysicalDeviceImageDrmFormatModifierInfoEXT imageFormatModifierInfo =
132 	{
133 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
134 		DE_NULL,
135 		drmFormatModifier,
136 		VK_SHARING_MODE_EXCLUSIVE,
137 		0,
138 		DE_NULL,
139 	};
140 
141 	const VkPhysicalDeviceExternalImageFormatInfo externalImageFormatInfo =
142 	{
143 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
144 		&imageFormatModifierInfo,
145 		(VkExternalMemoryHandleTypeFlagBits)handleType,
146 	};
147 
148 	const VkPhysicalDeviceImageFormatInfo2 imageFormatInfo =
149 	{
150 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
151 		&externalImageFormatInfo,
152 		format,
153 		imageType,
154 		VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
155 		imageUsages,
156 		0,
157 	};
158 
159 	VkExternalImageFormatProperties	externalImageProperties	= initVulkanStructure();
160 	VkImageFormatProperties2		imageProperties			= initVulkanStructure(&externalImageProperties);
161 
162 	if (vki.getPhysicalDeviceImageFormatProperties2(physicalDevice, &imageFormatInfo, &imageProperties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
163 		return false;
164 
165 	if ((externalImageProperties.externalMemoryProperties.compatibleHandleTypes & handleType) != handleType)
166 		return false;
167 
168 	return true;
169 }
170 
171 template <typename FlagsType>
featuresCompatible(FlagsType modifierFeatures,VkFormatFeatureFlags testFeatures)172 static deBool featuresCompatible(FlagsType modifierFeatures, VkFormatFeatureFlags testFeatures)
173 {
174 	// All the format feature flags alias with their equivalents in the lower
175 	// 32 bits of VkFormatFeatureFlags2KHR, so as long as we're casting "up",
176 	// this should always be safe
177 	DE_STATIC_ASSERT(sizeof(modifierFeatures) >= sizeof(testFeatures));
178 	return ((modifierFeatures & static_cast<FlagsType>(testFeatures)) == static_cast<FlagsType>(testFeatures));
179 }
180 
181 template <typename ModifierList, typename ModifierProps, VkStructureType modifierListSType>
getExportImportCompatibleModifiers(Context & context,VkFormat format)182 std::vector<deUint64> getExportImportCompatibleModifiers (Context& context, VkFormat format)
183 {
184 	const auto&				vki					= context.getInstanceInterface();
185 	const auto				drmFormatModifiers	= getDrmFormatModifiers<ModifierList, ModifierProps, modifierListSType>(vki, context.getPhysicalDevice(), format);
186 	std::vector<deUint64>	compatibleModifiers;
187 
188 	if (drmFormatModifiers.empty())
189 		return compatibleModifiers;
190 
191 	const VkFormatFeatureFlags testFeatures = (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT |
192 									VK_FORMAT_FEATURE_BLIT_SRC_BIT |
193 									VK_FORMAT_FEATURE_BLIT_DST_BIT |
194 									VK_FORMAT_FEATURE_TRANSFER_DST_BIT);
195 
196 	for (const auto& modifierProps : drmFormatModifiers)
197 	{
198 		if (modifierProps.drmFormatModifierTilingFeatures == 0)
199 			TCU_FAIL(de::toString(format) + " does not support any DRM modifier tiling features");
200 
201 		if (!featuresCompatible(modifierProps.drmFormatModifierTilingFeatures, testFeatures))
202 			continue;
203 
204 		const auto&	modifier	= modifierProps.drmFormatModifier;
205 		const auto	supported	= verifyHandleTypeForFormatModifier(vki, context.getPhysicalDevice(), format,
206 																	VK_IMAGE_TYPE_2D,
207 																	(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT),
208 																	VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
209 																	modifier);
210 
211 		if (!supported)
212 			continue;
213 
214 		compatibleModifiers.push_back(modifier);
215 	}
216 
217 	return compatibleModifiers;
218 }
219 
220 template <typename ModifierList, typename ModifierProps, VkStructureType modifierListSType>
checkExportImportExtensions(Context & context,VkFormat format)221 void checkExportImportExtensions (Context& context, VkFormat format)
222 {
223 	// tcuTexture.cpp getChannelSize, that is used by intThresholdCompare does not support the following formats.
224 	// TODO: Add tcuTexture.cpp support for the following formats.
225 	const VkFormat					skippedFormats[]				=
226 	{
227 		VK_FORMAT_B10G11R11_UFLOAT_PACK32,
228 		VK_FORMAT_A2R10G10B10_UNORM_PACK32,
229 		VK_FORMAT_A2R10G10B10_SNORM_PACK32,
230 		VK_FORMAT_A2R10G10B10_USCALED_PACK32,
231 		VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
232 		VK_FORMAT_A2R10G10B10_UINT_PACK32,
233 		VK_FORMAT_A2R10G10B10_SINT_PACK32,
234 		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
235 		VK_FORMAT_A2B10G10R10_SNORM_PACK32,
236 		VK_FORMAT_A2B10G10R10_USCALED_PACK32,
237 		VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
238 		VK_FORMAT_A2B10G10R10_UINT_PACK32,
239 		VK_FORMAT_A2B10G10R10_SINT_PACK32,
240 		VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
241 	};
242 
243 	if (std::find(std::begin(skippedFormats), std::end(skippedFormats), format) != std::end(skippedFormats))
244 		TCU_THROW(NotSupportedError, de::toString(format) + " can't be checked for correctness");
245 
246 	if (!context.isDeviceFunctionalitySupported("VK_KHR_external_memory_fd"))
247 		TCU_THROW(NotSupportedError, "VK_KHR_external_memory_fd not supported");
248 
249 	if (modifierListSType == VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT)
250 		checkModifiersSupported(context, format);
251 	else
252 		checkModifiersList2Supported(context, format);
253 
254 	const auto compatibleModifiers = getExportImportCompatibleModifiers<ModifierList, ModifierProps, modifierListSType>(context, format);
255 	if (compatibleModifiers.empty())
256 		TCU_THROW(NotSupportedError, "Could not find a format modifier supporting required transfer features for " + de::toString(format));
257 }
258 
isModifierCompatibleWithImageProperties(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,const VkFormat * formats,const deUint32 nFormats,const VkImageType imageType,const VkImageUsageFlags imageUsages,const VkExternalMemoryHandleTypeFlags handleType,const deUint64 drmFormatModifier,VkImageFormatProperties2 & imageProperties)259 deBool isModifierCompatibleWithImageProperties (const InstanceInterface&				vki,
260 												VkPhysicalDevice						physicalDevice,
261 												const VkFormat*							formats,
262 												const deUint32							nFormats,
263 												const VkImageType						imageType,
264 												const VkImageUsageFlags					imageUsages,
265 												const VkExternalMemoryHandleTypeFlags	handleType,
266 												const deUint64							drmFormatModifier,
267 												VkImageFormatProperties2&				imageProperties)
268 {
269 	const VkPhysicalDeviceImageDrmFormatModifierInfoEXT	imageFormatModifierInfo	=
270 	{
271 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
272 		DE_NULL,
273 		drmFormatModifier,
274 		VK_SHARING_MODE_EXCLUSIVE,
275 		0,
276 		DE_NULL,
277 	};
278 
279 	const VkPhysicalDeviceExternalImageFormatInfo	externalImageFormatInfo =
280 	{
281 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
282 		&imageFormatModifierInfo,
283 		(VkExternalMemoryHandleTypeFlagBits)handleType,
284 	};
285 
286 	const VkImageFormatListCreateInfo				imageFormatListInfo		=
287 	{
288 		VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO,
289 		&externalImageFormatInfo,
290 		nFormats,
291 		formats,
292 	};
293 
294 	const VkPhysicalDeviceImageFormatInfo2			imageFormatInfo			=
295 	{
296 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
297 		&imageFormatListInfo,
298 		formats[0],
299 		imageType,
300 		VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
301 		imageUsages,
302 		0,
303 	};
304 
305 	VkExternalImageFormatProperties	externalImageProperties	= initVulkanStructure();
306 	imageProperties.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
307 	imageProperties.pNext = &externalImageProperties;
308 
309 	if (vki.getPhysicalDeviceImageFormatProperties2(physicalDevice, &imageFormatInfo, &imageProperties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
310 		return false;
311 
312 	if ((externalImageProperties.externalMemoryProperties.compatibleHandleTypes & handleType) != handleType)
313 		return false;
314 
315 	return true;
316 }
317 
318 template <typename ModifierList, typename ModifierProps, VkStructureType modifierListSType>
listModifiersCase(Context & context,VkFormat format)319 tcu::TestStatus listModifiersCase (Context& context, VkFormat format)
320 {
321 	TestLog&					log					= context.getTestContext().getLog();
322 	const InstanceInterface&	vki					= context.getInstanceInterface();
323 	const auto					drmFormatModifiers	= getDrmFormatModifiers<ModifierList, ModifierProps, modifierListSType>(vki, context.getPhysicalDevice(), format);
324 	bool											noneCompatible		= true;
325 
326 	if (drmFormatModifiers.empty())
327 		TCU_THROW(NotSupportedError, de::toString(format) + " does not support any DRM modifiers");
328 
329 	for (deUint32 m = 0; m < drmFormatModifiers.size(); m++) {
330 		VkImageFormatProperties2	imageProperties {};
331 		deBool						isCompatible	= isModifierCompatibleWithImageProperties(vki, context.getPhysicalDevice(),
332 																							  &format, 1u, VK_IMAGE_TYPE_2D,
333 																							  (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT),
334 																							  VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
335 																							  drmFormatModifiers[m].drmFormatModifier, imageProperties);
336 
337 		if (drmFormatModifiers[m].drmFormatModifierTilingFeatures == 0)
338 			TCU_FAIL(de::toString(format) + " does not support any DRM modifier tiling features");
339 
340 		if (!isCompatible)
341 			continue;
342 		noneCompatible = false;
343 
344 		TCU_CHECK(imageProperties.imageFormatProperties.maxExtent.width >= 1 && imageProperties.imageFormatProperties.maxExtent.height >= 1);
345 		TCU_CHECK(imageProperties.imageFormatProperties.maxArrayLayers >= 1);
346 
347 		log << TestLog::Message
348 			<< "format modifier " << m << ":\n"
349 			<< drmFormatModifiers[m] << "\n"
350 			<< imageProperties
351 			<< TestLog::EndMessage;
352 	}
353 
354 	if (noneCompatible)
355 		TCU_THROW(NotSupportedError, de::toString(format) + " does not support any DRM modifiers for the requested image features");
356 
357 	return tcu::TestStatus::pass("OK");
358 }
359 
createImageNoModifiers(const DeviceInterface & vkd,const VkDevice device,const VkImageUsageFlags imageUsages,const VkFormat format,const UVec2 & size)360 Move<VkImage> createImageNoModifiers (const DeviceInterface&			vkd,
361 												 const VkDevice					device,
362 												 const VkImageUsageFlags		imageUsages,
363 												 const VkFormat					format,
364 												 const UVec2&					size)
365 {
366 	const VkImageCreateInfo							createInfo	=
367 	{
368 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
369 		DE_NULL,
370 		0,
371 		VK_IMAGE_TYPE_2D,
372 		format,
373 		makeExtent3D(size.x(), size.y(), 1u),
374 		1u,		// mipLevels
375 		1u,		// arrayLayers
376 		VK_SAMPLE_COUNT_1_BIT,
377 		VK_IMAGE_TILING_OPTIMAL,
378 		imageUsages,
379 		VK_SHARING_MODE_EXCLUSIVE,
380 		0u,
381 		(const deUint32*)DE_NULL,
382 		VK_IMAGE_LAYOUT_PREINITIALIZED,
383 	};
384 
385 	return createImage(vkd, device, &createInfo);
386 }
387 
createImageWithDrmFormatExplicitModifier(const DeviceInterface & vkd,const VkDevice device,const VkImageType imageType,const VkImageUsageFlags imageUsages,const VkExternalMemoryHandleTypeFlags externalMemoryHandleTypeFlags,const std::vector<VkFormat> & formats,const UVec2 & size,const ExplicitModifier drmFormatModifier)388 Move<VkImage> createImageWithDrmFormatExplicitModifier (const DeviceInterface&					vkd,
389 														const VkDevice							device,
390 														const VkImageType						imageType,
391 														const VkImageUsageFlags					imageUsages,
392 														const VkExternalMemoryHandleTypeFlags	externalMemoryHandleTypeFlags,
393 														const std::vector<VkFormat>&			formats,
394 														const UVec2&							size,
395 														const ExplicitModifier					drmFormatModifier)
396 {
397 	const VkImageDrmFormatModifierExplicitCreateInfoEXT	modifierExplicitCreateInfo =
398 	{
399 		VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT,
400 		DE_NULL,
401 		drmFormatModifier.modifier,
402 		drmFormatModifier.modifierPlaneCount,
403 		drmFormatModifier.pPlaneLayouts,
404 	};
405 
406 	const VkExternalMemoryImageCreateInfo externalMemoryCreateInfo =
407 	{
408 		VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
409 		&modifierExplicitCreateInfo,
410 		externalMemoryHandleTypeFlags,
411 	};
412 
413 	const void* pNext = &externalMemoryCreateInfo;
414 	if (!externalMemoryHandleTypeFlags)
415 	{
416 		pNext = &modifierExplicitCreateInfo;
417 	}
418 
419 	const VkImageFormatListCreateInfo			imageFormatListInfo			=
420 	{
421 		VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO,
422 		pNext,
423 		de::sizeU32(formats),
424 		de::dataOrNull(formats),
425 	};
426 
427 	const VkImageCreateInfo							createInfo	=
428 	{
429 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
430 		&imageFormatListInfo,
431 		0,
432 		imageType,
433 		formats.front(),
434 		makeExtent3D(size.x(), size.y(), 1u),
435 		1u,		// mipLevels
436 		1u,		// arrayLayers
437 		VK_SAMPLE_COUNT_1_BIT,
438 		VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
439 		imageUsages,
440 		VK_SHARING_MODE_EXCLUSIVE,
441 		0u,
442 		nullptr,
443 		VK_IMAGE_LAYOUT_UNDEFINED,
444 	};
445 
446 	return createImage(vkd, device, &createInfo);
447 }
448 
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)449 Move<VkImage> createImageWithDrmFormatModifiers (const DeviceInterface&					vkd,
450 												 const VkDevice							device,
451 												 const VkImageType						imageType,
452 												 const VkImageUsageFlags				imageUsages,
453 												 const VkExternalMemoryHandleTypeFlags	externalMemoryHandleTypeFlags,
454 												 const std::vector<VkFormat>&			formats,
455 												 const UVec2&							size,
456 												 const std::vector<deUint64>&			drmFormatModifiers)
457 {
458 	const VkImageDrmFormatModifierListCreateInfoEXT	modifierListCreateInfo =
459 	{
460 		VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT,
461 		DE_NULL,
462 		(deUint32)drmFormatModifiers.size(),
463 		drmFormatModifiers.data(),
464 	};
465 
466 	const VkExternalMemoryImageCreateInfo externalMemoryCreateInfo =
467 	{
468 		VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
469 		&modifierListCreateInfo,
470 		externalMemoryHandleTypeFlags,
471 	};
472 
473 	const void* pNext = &externalMemoryCreateInfo;
474 	if (!externalMemoryHandleTypeFlags)
475 	{
476 		pNext = &modifierListCreateInfo;
477 	}
478 
479 	const VkImageFormatListCreateInfo			imageFormatListInfo			=
480 	{
481 		VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO,
482 		pNext,
483 		static_cast<deUint32>(formats.size()),
484 		formats.data(),
485 	};
486 
487 	const VkImageCreateInfo							createInfo	=
488 	{
489 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
490 		&imageFormatListInfo,
491 		0,
492 		imageType,
493 		formats.front(),
494 		makeExtent3D(size.x(), size.y(), 1u),
495 		1u,		// mipLevels
496 		1u,		// arrayLayers
497 		VK_SAMPLE_COUNT_1_BIT,
498 		VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
499 		imageUsages,
500 		VK_SHARING_MODE_EXCLUSIVE,
501 		0u,
502 		(const deUint32*)DE_NULL,
503 		VK_IMAGE_LAYOUT_UNDEFINED,
504 	};
505 
506 	return createImage(vkd, device, &createInfo);
507 }
508 
509 template <typename ModifierList, typename ModifierProps, VkStructureType modifierListSType>
createImageListModifiersCase(Context & context,const VkFormat format)510 tcu::TestStatus createImageListModifiersCase (Context& context, const VkFormat format)
511 {
512 	const InstanceInterface&	vki					= context.getInstanceInterface();
513 	const DeviceInterface&		vkd					= context.getDeviceInterface();
514 	const VkDevice				device				= context.getDevice();
515 	const auto					drmFormatModifiers	= getDrmFormatModifiers<ModifierList, ModifierProps, modifierListSType>(vki, context.getPhysicalDevice(), format);
516 
517 	if (drmFormatModifiers.empty())
518 		TCU_THROW(NotSupportedError, de::toString(format) + " does not support any DRM modifiers");
519 
520 	// Get the list of modifiers supported for some specific image parameters.
521 	std::vector<deUint64> modifiers;
522 
523 	for (const auto& modProps : drmFormatModifiers)
524 	{
525 		VkImageFormatProperties2	imgFormatProperties	= initVulkanStructure();
526 		const auto					isCompatible		= isModifierCompatibleWithImageProperties(vki, context.getPhysicalDevice(), &format, 1u, VK_IMAGE_TYPE_2D,
527 																								  (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT),
528 																								  VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
529 																								  modProps.drmFormatModifier, imgFormatProperties);
530 		if (isCompatible)
531 			modifiers.push_back(modProps.drmFormatModifier);
532 		if (modProps.drmFormatModifierTilingFeatures == 0)
533 			TCU_FAIL(de::toString(format) + " does not support any DRM modifier tiling features");
534 	}
535 
536 	if (modifiers.empty())
537 		TCU_THROW(NotSupportedError, de::toString(format) + " does not support any DRM modifiers for the requested image features");
538 
539 	// Test with lists of compatible modifiers of increasing lengths.
540 	for (size_t len = 1u; len <= modifiers.size(); ++len)
541 	{
542 		std::vector<deUint64> creationModifiers;
543 		creationModifiers.reserve(len);
544 		std::copy_n(begin(modifiers), len, std::back_inserter(creationModifiers));
545 
546 		VkImageDrmFormatModifierPropertiesEXT	properties	= initVulkanStructure();
547 
548 		{
549 			std::vector<VkFormat>	formats	(1u, format);
550 			const auto				image	= createImageWithDrmFormatModifiers(vkd, device, VK_IMAGE_TYPE_2D,
551 																				(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT),
552 																				0, formats, UVec2(64, 64), creationModifiers);
553 
554 			VK_CHECK(vkd.getImageDrmFormatModifierPropertiesEXT(device, *image, &properties));
555 		}
556 
557 		if (!de::contains(begin(creationModifiers), end(creationModifiers), properties.drmFormatModifier))
558 			return tcu::TestStatus::fail("Image created with modifier not specified in the create list");
559 	}
560 
561 	return tcu::TestStatus::pass("OK");
562 }
563 
564 template <typename ModifierList, typename ModifierProps, VkStructureType modifierListSType>
createImageModifierExplicitCase(Context & context,const VkFormat format)565 tcu::TestStatus createImageModifierExplicitCase (Context& context, const VkFormat format)
566 {
567 	const InstanceInterface&	vki					= context.getInstanceInterface();
568 	const DeviceInterface&		vkd					= context.getDeviceInterface();
569 	const VkDevice				device				= context.getDevice();
570 	const auto					drmFormatModifiers	= getDrmFormatModifiers<ModifierList, ModifierProps, modifierListSType>(vki, context.getPhysicalDevice(), format);
571 
572 	if (drmFormatModifiers.empty())
573 		TCU_THROW(NotSupportedError, de::toString(format) + " does not support any DRM modifiers");
574 
575 	// Get the list of modifiers supported for some specific image parameters.
576 	std::vector<ExplicitModifier> modifiers;
577 
578 	for (const auto& modProps : drmFormatModifiers)
579 	{
580 		if (modProps.drmFormatModifierTilingFeatures == 0)
581 			TCU_FAIL(de::toString(format) + " does not support any DRM modifier tiling features");
582 
583 		VkImageFormatProperties2	imgFormatProperties	= initVulkanStructure();
584 		const auto					isCompatible		= isModifierCompatibleWithImageProperties(vki, context.getPhysicalDevice(), &format, 1u, VK_IMAGE_TYPE_2D,
585 																								  (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT),
586 																								  VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
587 																								  modProps.drmFormatModifier, imgFormatProperties);
588 		if (isCompatible)
589 		{
590 			const ExplicitModifier modifier =
591 			{
592 				modProps.drmFormatModifier,				// modifier
593 				modProps.drmFormatModifierPlaneCount,	// modifierPlaneCount
594 				DE_NULL,								// pPlaneLayouts
595 			};
596 
597 			modifiers.push_back(modifier);
598 		}
599 	}
600 
601 	if (modifiers.empty())
602 		TCU_THROW(NotSupportedError, de::toString(format) + " does not support any DRM modifiers for the requested image features");
603 
604 	for (auto& modifier : modifiers)
605 	{
606 		std::vector<VkFormat> formats			(1u, format);
607 		std::vector<uint64_t> creationModifier	(1u, modifier.modifier);
608 
609 		VkImageDrmFormatModifierPropertiesEXT properties = initVulkanStructure();
610 
611 		const auto imageRef = createImageWithDrmFormatModifiers(vkd, device, VK_IMAGE_TYPE_2D,
612 																(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT),
613 																0, formats, UVec2(64, 64), creationModifier);
614 
615 		std::vector<VkSubresourceLayout>	planeLayouts;
616 		for (uint32_t i = 0; i < modifier.modifierPlaneCount; i++)
617 		{
618 			VkImageSubresource imageSubresource;
619 			VkSubresourceLayout subresourceLayout;
620 
621 			deMemset(&imageSubresource, 0, sizeof(imageSubresource));
622 
623 			imageSubresource.aspectMask = VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT << i;
624 
625 			vkd.getImageSubresourceLayout(device, *imageRef, &imageSubresource, &subresourceLayout);
626 
627 			// From the spec:
628 			//   VUID-VkImageDrmFormatModifierExplicitCreateInfoEXT-size-02267
629 			//   For each element of pPlaneLayouts, size must be 0
630 			//
631 			//   VUID-VkImageDrmFormatModifierExplicitCreateInfoEXT-arrayPitch-02268
632 			//   For each element of pPlaneLayouts, arrayPitch must be 0 if VkImageCreateInfo::arrayLayers is 1
633 			//
634 			//   VUID-VkImageDrmFormatModifierExplicitCreateInfoEXT-depthPitch-02269
635 			//   For each element of pPlaneLayouts, depthPitch must be 0 if VkImageCreateInfo::extent.depth is 1
636 			subresourceLayout.size = 0;
637 			subresourceLayout.arrayPitch = 0;
638 			subresourceLayout.depthPitch = 0;
639 
640 			planeLayouts.push_back(subresourceLayout);
641 
642 		}
643 		modifier.pPlaneLayouts = planeLayouts.data();
644 
645 		const auto image = createImageWithDrmFormatExplicitModifier(vkd, device, VK_IMAGE_TYPE_2D,
646 																    (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT),
647 																    0, formats, UVec2(64, 64), modifier);
648 		VK_CHECK(vkd.getImageDrmFormatModifierPropertiesEXT(device, *image, &properties));
649 
650 		if (modifier.modifier != properties.drmFormatModifier)
651 			return tcu::TestStatus::fail("The created image's modifier with an explicit modifier not matched");
652 	}
653 
654 	return tcu::TestStatus::pass("OK");
655 }
656 
chooseMemoryType(deUint32 bits)657 deUint32 chooseMemoryType(deUint32 bits)
658 {
659 	DE_ASSERT(bits != 0);
660 
661 	for (deUint32 memoryTypeIndex = 0; (1u << memoryTypeIndex) <= bits; memoryTypeIndex++)
662 	{
663 		if ((bits & (1u << memoryTypeIndex)) != 0)
664 			return memoryTypeIndex;
665 	}
666 
667 	DE_FATAL("No supported memory types");
668 	return -1;
669 }
670 
exportImportMemoryExplicitModifiersCase(Context & context,const VkFormat format,deUint64 modifier)671 bool exportImportMemoryExplicitModifiersCase (Context& context, const VkFormat format, deUint64 modifier)
672 {
673 	const InstanceInterface&						vki					= context.getInstanceInterface();
674 	const DeviceInterface&							vkd					= context.getDeviceInterface();
675 	const VkDevice									device				= context.getDevice();
676 
677 
678 	const auto supported = verifyHandleTypeForFormatModifier(vki, context.getPhysicalDevice(), format,
679 															 VK_IMAGE_TYPE_2D,
680 															 (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT),
681 															 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
682 															 modifier);
683 
684 	if (!supported)
685 		TCU_FAIL("Modifier " + de::toString(modifier) + " for format " + de::toString(format) + " expected to be compatible");
686 
687 	std::vector<deUint64>					modifiers;
688 	modifiers.push_back(modifier);
689 
690 
691 	const UVec2									imageSize		(64, 64);
692 	const tcu::TextureFormat referenceTextureFormat (mapVkFormat(format));
693 	deUint32 bufferSize = 1<<16;
694 	const de::UniquePtr<BufferWithMemory>		inputBuffer		(new BufferWithMemory(vkd, device, context.getDefaultAllocator(),
695 																																							makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT),
696 																						MemoryRequirement::HostVisible));
697 	tcu::PixelBufferAccess				referenceImage	(referenceTextureFormat, imageSize.x(), imageSize.y(), 1, inputBuffer->getAllocation().getHostPtr());
698 	const de::UniquePtr<BufferWithMemory>		outputBuffer		(new BufferWithMemory(vkd, device, context.getDefaultAllocator(),
699 																																							makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT),
700 																						MemoryRequirement::HostVisible));
701 	Unique<VkCommandPool>			cmdPool				(createCommandPool(vkd, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex(), DE_NULL));
702 	vkt::ExternalMemoryUtil::NativeHandle								inputImageMemFd;
703 
704 	const tcu::TextureFormatInfo				formatInfo		(tcu::getTextureFormatInfo(referenceTextureFormat));
705 	tcu::fillWithComponentGradients(referenceImage, formatInfo.valueMin, formatInfo.valueMax);
706 
707 	flushAlloc(vkd, device, inputBuffer->getAllocation());
708 
709 	Move<VkImage>						srcImage		(createImageNoModifiers(vkd, device,
710 																								 VK_IMAGE_USAGE_TRANSFER_DST_BIT |
711 																								 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
712 																								 format, UVec2(64, 64)));
713 	VkMemoryRequirements srcImageMemoryReq = getImageMemoryRequirements(vkd, device, *srcImage);
714 	const vk::VkMemoryAllocateInfo	allocationInfo	=
715 	{
716 		vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
717 		DE_NULL,
718 		srcImageMemoryReq.size,
719 		chooseMemoryType(srcImageMemoryReq.memoryTypeBits),
720 	};
721 	vk::Move<vk::VkDeviceMemory>	srcMemory			(vk::allocateMemory(vkd, device, &allocationInfo));
722 	VK_CHECK(vkd.bindImageMemory(device, *srcImage, *srcMemory, 0));
723 
724 
725 	Unique<VkCommandBuffer>			cmdBuffer			(allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
726 	const VkCommandBufferBeginInfo	cmdBufferBeginInfo	=
727 	{
728 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
729 		DE_NULL,
730 		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
731 		(const VkCommandBufferInheritanceInfo*)DE_NULL,
732 	};
733 
734 	VK_CHECK(vkd.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
735 
736 	{
737 		const VkImageAspectFlags		aspect				= VK_IMAGE_ASPECT_COLOR_BIT;
738 		std::vector<VkBufferImageCopy>	copies;
739 
740 		copies.push_back(image::makeBufferImageCopy(makeExtent3D(imageSize.x(), imageSize.y(), 1u), 1u));
741 		copyBufferToImage(vkd, *cmdBuffer, inputBuffer->get(), bufferSize,
742 											copies, aspect, 1, 1, *srcImage,
743 											VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
744 
745 	}
746 
747 	Move<VkImage>						dstImage		(createImageWithDrmFormatModifiers(vkd, device, VK_IMAGE_TYPE_2D,
748 																																				 VK_IMAGE_USAGE_TRANSFER_DST_BIT |
749 																																				 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
750 																																				 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
751 																																				 {format}, UVec2(64, 64), modifiers));
752 	VkMemoryRequirements dstImageMemoryReq = getImageMemoryRequirements(vkd, device, *dstImage);
753 	vk::Move<vk::VkDeviceMemory>	dstMemory			(vkt::ExternalMemoryUtil::allocateExportableMemory(vkd, device,
754 																																																 dstImageMemoryReq.size,
755 																																																 chooseMemoryType(dstImageMemoryReq.memoryTypeBits),
756 																																																 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
757 																																																 *dstImage));
758 
759 	VK_CHECK(vkd.bindImageMemory(device, *dstImage, *dstMemory, 0));
760 	const VkImageMemoryBarrier		srcImageBarrier		=
761 	{
762 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
763 		DE_NULL,									// const void*				pNext;
764 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
765 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
766 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			oldLayout;
767 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,			// VkImageLayout			newLayout;
768 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
769 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
770 		*srcImage,						// VkImage					image;
771 		{											// VkImageSubresourceRange	subresourceRange;
772 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
773 			0u,								// deUint32				baseMipLevel;
774 			1u,								// deUint32				mipLevels;
775 			0u,								// deUint32				baseArraySlice;
776 			1u								// deUint32				arraySize;
777 		}
778 	};
779 	const VkImageMemoryBarrier		dstImageBarrier		=
780 	{
781 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
782 		DE_NULL,									// const void*				pNext;
783 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
784 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
785 		VK_IMAGE_LAYOUT_UNDEFINED,		// VkImageLayout			oldLayout;
786 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout;
787 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
788 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
789 		*dstImage,						// VkImage					image;
790 		{											// VkImageSubresourceRange	subresourceRange;
791 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
792 			0u,								// deUint32				baseMipLevel;
793 			1u,								// deUint32				mipLevels;
794 			0u,								// deUint32				baseArraySlice;
795 			1u								// deUint32				arraySize;
796 		}
797 	};
798 	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);
799 	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);
800 
801 	VkImageBlit		imageBlit
802 	{
803 		{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1},
804 		{{0,0,0}, {64,64,1}},
805 		{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1},
806 		{{0,0,0}, {64,64,1}},
807 	};
808 	vkd.cmdBlitImage(*cmdBuffer, *srcImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *dstImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &imageBlit, VK_FILTER_NEAREST);
809 
810 	const VkImageMemoryBarrier		exportImageBarrier		=
811 	{
812 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
813 		DE_NULL,									// const void*				pNext;
814 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
815 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
816 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
817 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout;
818 		context.getUniversalQueueFamilyIndex(),		// deUint32					dstQueueFamilyIndex;
819 		VK_QUEUE_FAMILY_FOREIGN_EXT,				// deUint32					srcQueueFamilyIndex;
820 		*dstImage,									// VkImage					image;
821 		{											// VkImageSubresourceRange	subresourceRange;
822 			VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags		aspectMask;
823 			0u,								// deUint32					baseMipLevel;
824 			1u,								// deUint32					mipLevels;
825 			0u,								// deUint32					baseArraySlice;
826 			1u								// deUint32					arraySize;
827 		}
828 	};
829 
830 	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, &exportImageBarrier);
831 	VK_CHECK(vkd.endCommandBuffer(*cmdBuffer));
832 	submitCommandsAndWait(vkd, device, context.getUniversalQueue(), *cmdBuffer);
833 	VkImageDrmFormatModifierPropertiesEXT	properties;
834 	deMemset(&properties, 0, sizeof(properties));
835 	properties.sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT;
836 	VK_CHECK(vkd.getImageDrmFormatModifierPropertiesEXT(device, *dstImage, &properties));
837 	TCU_CHECK(properties.drmFormatModifier == modifiers.front());
838 	inputImageMemFd	= vkt::ExternalMemoryUtil::getMemoryFd(vkd, device, *dstMemory, VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT);
839 
840 	Move<VkImage>				importedSrcImage		(createImageWithDrmFormatModifiers(vkd, device, VK_IMAGE_TYPE_2D,
841 																																						 VK_IMAGE_USAGE_TRANSFER_DST_BIT |
842 																																						 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
843 																																						 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
844 																																						 {format}, UVec2(64, 64), modifiers));
845 
846 	VkMemoryRequirements importedSrcImageMemoryReq = getImageMemoryRequirements(vkd, device, *importedSrcImage);
847 
848 	Move<VkDeviceMemory>						importedMemory (vkt::ExternalMemoryUtil::importDedicatedMemory(vkd, device, *importedSrcImage,
849                                                                                                                importedSrcImageMemoryReq,
850                                                                                                                VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
851                                                                                                                ~0u, inputImageMemFd));
852 	VK_CHECK(vkd.bindImageMemory(device, *importedSrcImage, *importedMemory, 0));
853 
854 	Move<VkImage>						outImage		(createImageNoModifiers(vkd, device,
855 																															VK_IMAGE_USAGE_TRANSFER_DST_BIT |
856 																															VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
857 																															format, UVec2(64, 64)));
858 	VkMemoryRequirements outImageMemoryReq = getImageMemoryRequirements(vkd, device, *outImage);
859 	const vk::VkMemoryAllocateInfo	outAllocationInfo	=
860 	{
861 		vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
862 		DE_NULL,
863 		outImageMemoryReq.size,
864 		chooseMemoryType(outImageMemoryReq.memoryTypeBits),
865 	};
866 	vk::Move<vk::VkDeviceMemory>	outMemory			(vk::allocateMemory(vkd, device, &outAllocationInfo));
867 	VK_CHECK(vkd.bindImageMemory(device, *outImage, *outMemory, 0));
868 
869 	Unique<VkCommandBuffer>			cmdBuffer2			(allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
870 	VK_CHECK(vkd.beginCommandBuffer(*cmdBuffer2, &cmdBufferBeginInfo));
871 
872 	const VkImageMemoryBarrier		importedImageBarrier		=
873 	{
874 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
875 		DE_NULL,									// const void*				pNext;
876 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
877 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
878 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			oldLayout;
879 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,			// VkImageLayout			newLayout;
880 		VK_QUEUE_FAMILY_FOREIGN_EXT,					// deUint32					srcQueueFamilyIndex;
881 		context.getUniversalQueueFamilyIndex(),			// deUint32					dstQueueFamilyIndex;
882 		*importedSrcImage,						// VkImage					image;
883 		{											// VkImageSubresourceRange	subresourceRange;
884 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
885 			0u,								// deUint32				baseMipLevel;
886 			1u,								// deUint32				mipLevels;
887 			0u,								// deUint32				baseArraySlice;
888 			1u								// deUint32				arraySize;
889 		}
890 	};
891 	const VkImageMemoryBarrier		outImageBarrier		=
892 	{
893 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
894 		DE_NULL,									// const void*				pNext;
895 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
896 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
897 		VK_IMAGE_LAYOUT_UNDEFINED,		// VkImageLayout			oldLayout;
898 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout;
899 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
900 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
901 		*outImage,						// VkImage					image;
902 		{											// VkImageSubresourceRange	subresourceRange;
903 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
904 			0u,								// deUint32				baseMipLevel;
905 			1u,								// deUint32				mipLevels;
906 			0u,								// deUint32				baseArraySlice;
907 			1u								// deUint32				arraySize;
908 		}
909 	};
910 
911 	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);
912 	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);
913 
914 	VkImageBlit		imageBlit2
915 	{
916 		{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1},
917 		{{0,0,0}, {64,64,1}},
918 		{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1},
919 		{{0,0,0}, {64,64,1}},
920 	};
921 	vkd.cmdBlitImage(*cmdBuffer2, *importedSrcImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *outImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &imageBlit2, VK_FILTER_NEAREST);
922 
923 
924 	copyImageToBuffer(vkd, *cmdBuffer2, *outImage,
925 										outputBuffer->get(), tcu::IVec2(imageSize.x(), imageSize.y()),
926 										VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1);
927 
928 	VK_CHECK(vkd.endCommandBuffer(*cmdBuffer2));
929 
930 	submitCommandsAndWait(vkd, device, context.getUniversalQueue(), *cmdBuffer2);
931 
932 
933 	tcu::ConstPixelBufferAccess	result	(referenceTextureFormat, imageSize.x(), imageSize.y(), 1, outputBuffer->getAllocation().getHostPtr());
934 	const tcu::UVec4 threshold (0u);
935 
936 	invalidateAlloc(vkd, device, outputBuffer->getAllocation());
937 
938 	return tcu::intThresholdCompare(context.getTestContext().getLog(), "Compare", "Result comparison", referenceImage, result, threshold, tcu::COMPARE_LOG_RESULT);
939 }
940 
941 template <typename ModifierList, typename ModifierProps, VkStructureType modifierListSType>
exportImportMemoryExplicitModifiersCase(Context & context,const VkFormat format)942 tcu::TestStatus exportImportMemoryExplicitModifiersCase (Context& context, const VkFormat format)
943 {
944 	const auto compatibleModifiers = getExportImportCompatibleModifiers<ModifierList, ModifierProps, modifierListSType>(context, format);
945 
946 	if (compatibleModifiers.empty())
947 		TCU_FAIL("Expected non-empty list of compatible modifiers for the given format");
948 
949 	for (const auto& modifier : compatibleModifiers)
950 	{
951 		if (!exportImportMemoryExplicitModifiersCase(context, format, modifier))
952 			return tcu::TestStatus::fail("Unexpected copy image result");
953 	}
954 
955 	return tcu::TestStatus::pass("OK");
956 }
957 
958 } // anonymous
959 
createTests(tcu::TestContext & testCtx)960 tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx)
961 {
962 	de::MovePtr<tcu::TestCaseGroup>	drmFormatModifiersGroup	(new tcu::TestCaseGroup(testCtx, "drm_format_modifiers", "DRM format modifiers tests"));
963 	const VkFormat					formats[]				=
964 	{
965 		VK_FORMAT_R4G4_UNORM_PACK8,
966 		VK_FORMAT_R4G4B4A4_UNORM_PACK16,
967 		VK_FORMAT_B4G4R4A4_UNORM_PACK16,
968 		VK_FORMAT_R5G6B5_UNORM_PACK16,
969 		VK_FORMAT_B5G6R5_UNORM_PACK16,
970 		VK_FORMAT_R5G5B5A1_UNORM_PACK16,
971 		VK_FORMAT_B5G5R5A1_UNORM_PACK16,
972 		VK_FORMAT_A1R5G5B5_UNORM_PACK16,
973 		VK_FORMAT_R8_UNORM,
974 		VK_FORMAT_R8_SNORM,
975 		VK_FORMAT_R8_USCALED,
976 		VK_FORMAT_R8_SSCALED,
977 		VK_FORMAT_R8_UINT,
978 		VK_FORMAT_R8_SINT,
979 		VK_FORMAT_R8_SRGB,
980 		VK_FORMAT_R8G8_UNORM,
981 		VK_FORMAT_R8G8_SNORM,
982 		VK_FORMAT_R8G8_USCALED,
983 		VK_FORMAT_R8G8_SSCALED,
984 		VK_FORMAT_R8G8_UINT,
985 		VK_FORMAT_R8G8_SINT,
986 		VK_FORMAT_R8G8_SRGB,
987 		VK_FORMAT_R8G8B8_UNORM,
988 		VK_FORMAT_R8G8B8_SNORM,
989 		VK_FORMAT_R8G8B8_USCALED,
990 		VK_FORMAT_R8G8B8_SSCALED,
991 		VK_FORMAT_R8G8B8_UINT,
992 		VK_FORMAT_R8G8B8_SINT,
993 		VK_FORMAT_R8G8B8_SRGB,
994 		VK_FORMAT_B8G8R8_UNORM,
995 		VK_FORMAT_B8G8R8_SNORM,
996 		VK_FORMAT_B8G8R8_USCALED,
997 		VK_FORMAT_B8G8R8_SSCALED,
998 		VK_FORMAT_B8G8R8_UINT,
999 		VK_FORMAT_B8G8R8_SINT,
1000 		VK_FORMAT_B8G8R8_SRGB,
1001 		VK_FORMAT_R8G8B8A8_UNORM,
1002 		VK_FORMAT_R8G8B8A8_SNORM,
1003 		VK_FORMAT_R8G8B8A8_USCALED,
1004 		VK_FORMAT_R8G8B8A8_SSCALED,
1005 		VK_FORMAT_R8G8B8A8_UINT,
1006 		VK_FORMAT_R8G8B8A8_SINT,
1007 		VK_FORMAT_R8G8B8A8_SRGB,
1008 		VK_FORMAT_B8G8R8A8_UNORM,
1009 		VK_FORMAT_B8G8R8A8_SNORM,
1010 		VK_FORMAT_B8G8R8A8_USCALED,
1011 		VK_FORMAT_B8G8R8A8_SSCALED,
1012 		VK_FORMAT_B8G8R8A8_UINT,
1013 		VK_FORMAT_B8G8R8A8_SINT,
1014 		VK_FORMAT_B8G8R8A8_SRGB,
1015 		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1016 		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
1017 		VK_FORMAT_A8B8G8R8_USCALED_PACK32,
1018 		VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
1019 		VK_FORMAT_A8B8G8R8_UINT_PACK32,
1020 		VK_FORMAT_A8B8G8R8_SINT_PACK32,
1021 		VK_FORMAT_A8B8G8R8_SRGB_PACK32,
1022 		VK_FORMAT_A2R10G10B10_UNORM_PACK32,
1023 		VK_FORMAT_A2R10G10B10_SNORM_PACK32,
1024 		VK_FORMAT_A2R10G10B10_USCALED_PACK32,
1025 		VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
1026 		VK_FORMAT_A2R10G10B10_UINT_PACK32,
1027 		VK_FORMAT_A2R10G10B10_SINT_PACK32,
1028 		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1029 		VK_FORMAT_A2B10G10R10_SNORM_PACK32,
1030 		VK_FORMAT_A2B10G10R10_USCALED_PACK32,
1031 		VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
1032 		VK_FORMAT_A2B10G10R10_UINT_PACK32,
1033 		VK_FORMAT_A2B10G10R10_SINT_PACK32,
1034 		VK_FORMAT_R16_UNORM,
1035 		VK_FORMAT_R16_SNORM,
1036 		VK_FORMAT_R16_USCALED,
1037 		VK_FORMAT_R16_SSCALED,
1038 		VK_FORMAT_R16_UINT,
1039 		VK_FORMAT_R16_SINT,
1040 		VK_FORMAT_R16_SFLOAT,
1041 		VK_FORMAT_R16G16_UNORM,
1042 		VK_FORMAT_R16G16_SNORM,
1043 		VK_FORMAT_R16G16_USCALED,
1044 		VK_FORMAT_R16G16_SSCALED,
1045 		VK_FORMAT_R16G16_UINT,
1046 		VK_FORMAT_R16G16_SINT,
1047 		VK_FORMAT_R16G16_SFLOAT,
1048 		VK_FORMAT_R16G16B16_UNORM,
1049 		VK_FORMAT_R16G16B16_SNORM,
1050 		VK_FORMAT_R16G16B16_USCALED,
1051 		VK_FORMAT_R16G16B16_SSCALED,
1052 		VK_FORMAT_R16G16B16_UINT,
1053 		VK_FORMAT_R16G16B16_SINT,
1054 		VK_FORMAT_R16G16B16_SFLOAT,
1055 		VK_FORMAT_R16G16B16A16_UNORM,
1056 		VK_FORMAT_R16G16B16A16_SNORM,
1057 		VK_FORMAT_R16G16B16A16_USCALED,
1058 		VK_FORMAT_R16G16B16A16_SSCALED,
1059 		VK_FORMAT_R16G16B16A16_UINT,
1060 		VK_FORMAT_R16G16B16A16_SINT,
1061 		VK_FORMAT_R16G16B16A16_SFLOAT,
1062 		VK_FORMAT_R32_UINT,
1063 		VK_FORMAT_R32_SINT,
1064 		VK_FORMAT_R32_SFLOAT,
1065 		VK_FORMAT_R32G32_UINT,
1066 		VK_FORMAT_R32G32_SINT,
1067 		VK_FORMAT_R32G32_SFLOAT,
1068 		VK_FORMAT_R32G32B32_UINT,
1069 		VK_FORMAT_R32G32B32_SINT,
1070 		VK_FORMAT_R32G32B32_SFLOAT,
1071 		VK_FORMAT_R32G32B32A32_UINT,
1072 		VK_FORMAT_R32G32B32A32_SINT,
1073 		VK_FORMAT_R32G32B32A32_SFLOAT,
1074 		VK_FORMAT_R64_UINT,
1075 		VK_FORMAT_R64_SINT,
1076 		VK_FORMAT_R64_SFLOAT,
1077 		VK_FORMAT_R64G64_UINT,
1078 		VK_FORMAT_R64G64_SINT,
1079 		VK_FORMAT_R64G64_SFLOAT,
1080 		VK_FORMAT_R64G64B64_UINT,
1081 		VK_FORMAT_R64G64B64_SINT,
1082 		VK_FORMAT_R64G64B64_SFLOAT,
1083 		VK_FORMAT_R64G64B64A64_UINT,
1084 		VK_FORMAT_R64G64B64A64_SINT,
1085 		VK_FORMAT_R64G64B64A64_SFLOAT,
1086 		VK_FORMAT_B10G11R11_UFLOAT_PACK32,
1087 		VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
1088 		VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
1089 		VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
1090 	};
1091 
1092 	{
1093 		de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "list_modifiers", "Check that listing supported modifiers is functional"));
1094 		de::MovePtr<tcu::TestCaseGroup> group2(new tcu::TestCaseGroup(testCtx, "list_modifiers_fmt_features2", "Check that listing supported modifiers is functional with VK_KHR_format_feature_flags2"));
1095 
1096 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
1097 		{
1098 			addFunctionCase(group.get(), getFormatCaseName(formats[formatNdx]), "Check that listing supported modifiers is functional", checkModifiersSupported, listModifiersCase<VkDrmFormatModifierPropertiesListEXT, VkDrmFormatModifierPropertiesEXT, VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT>, formats[formatNdx]);
1099 			addFunctionCase(group2.get(), getFormatCaseName(formats[formatNdx]), "Check that listing supported modifiers is functional", checkModifiersList2Supported, listModifiersCase<VkDrmFormatModifierPropertiesList2EXT, VkDrmFormatModifierProperties2EXT, VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT>, formats[formatNdx]);
1100 		}
1101 
1102 		drmFormatModifiersGroup->addChild(group.release());
1103 		drmFormatModifiersGroup->addChild(group2.release());
1104 	}
1105 
1106 	{
1107 		de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "create_list_modifiers", "Check that creating images with modifier list is functional"));
1108 		de::MovePtr<tcu::TestCaseGroup> group2(new tcu::TestCaseGroup(testCtx, "create_list_modifiers_fmt_features2", "Check that creating images with modifier list is functional with VK_KHR_format_feature_flags2"));
1109 
1110 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
1111 		{
1112 			addFunctionCase(group.get(), getFormatCaseName(formats[formatNdx]), "Check that creating images with modifier list is functional", checkModifiersSupported, createImageListModifiersCase<VkDrmFormatModifierPropertiesListEXT, VkDrmFormatModifierPropertiesEXT, VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT>, formats[formatNdx]);
1113 			addFunctionCase(group2.get(), getFormatCaseName(formats[formatNdx]), "Check that creating images with modifier list is functional", checkModifiersList2Supported, createImageListModifiersCase<VkDrmFormatModifierPropertiesList2EXT, VkDrmFormatModifierProperties2EXT, VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT>, formats[formatNdx]);
1114 		}
1115 
1116 		drmFormatModifiersGroup->addChild(group.release());
1117 		drmFormatModifiersGroup->addChild(group2.release());
1118 	}
1119 
1120 	{
1121 		de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "create_explicit_modifier", "Check that creating images with an explicit modifier is functional"));
1122 		de::MovePtr<tcu::TestCaseGroup> group2(new tcu::TestCaseGroup(testCtx, "create_explicit_modifier_fmt_features2", "Check that creating images with an explicit modifier is functional with VK_KHR_format_feature_flags2"));
1123 
1124 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
1125 		{
1126 			addFunctionCase(group.get(), getFormatCaseName(formats[formatNdx]), "Check that creating images with an explicit modifier is functional", checkModifiersSupported, createImageModifierExplicitCase<VkDrmFormatModifierPropertiesListEXT, VkDrmFormatModifierPropertiesEXT, VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT>, formats[formatNdx]);
1127 			addFunctionCase(group2.get(), getFormatCaseName(formats[formatNdx]), "Check that creating images with an explicit modifier is functional", checkModifiersList2Supported, createImageModifierExplicitCase<VkDrmFormatModifierPropertiesList2EXT, VkDrmFormatModifierProperties2EXT, VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT>, formats[formatNdx]);
1128 		}
1129 
1130 		drmFormatModifiersGroup->addChild(group.release());
1131 		drmFormatModifiersGroup->addChild(group2.release());
1132 	}
1133 
1134 	{
1135 		de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "export_import", "Test exporting/importing images with modifiers"));
1136 		de::MovePtr<tcu::TestCaseGroup> group2(new tcu::TestCaseGroup(testCtx, "export_import_fmt_features2", "Test exporting/importing images with modifiers with VK_KHR_format_feature_flags2"));
1137 
1138 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
1139 		{
1140 			addFunctionCase(group.get(), getFormatCaseName(formats[formatNdx]), "Test exporting/importing images with modifiers", checkExportImportExtensions<VkDrmFormatModifierPropertiesListEXT, VkDrmFormatModifierPropertiesEXT, VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT>, exportImportMemoryExplicitModifiersCase<VkDrmFormatModifierPropertiesListEXT, VkDrmFormatModifierPropertiesEXT, VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT>, formats[formatNdx]);
1141 			addFunctionCase(group2.get(), getFormatCaseName(formats[formatNdx]), "Test exporting/importing images with modifiers", checkExportImportExtensions<VkDrmFormatModifierPropertiesList2EXT, VkDrmFormatModifierProperties2EXT, VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT>, exportImportMemoryExplicitModifiersCase<VkDrmFormatModifierPropertiesList2EXT, VkDrmFormatModifierProperties2EXT, VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT>, formats[formatNdx]);
1142 		}
1143 
1144 		drmFormatModifiersGroup->addChild(group.release());
1145 		drmFormatModifiersGroup->addChild(group2.release());
1146 	}
1147 
1148 	return drmFormatModifiersGroup.release();
1149 }
1150 
1151 } // modifiers
1152 } // vkt
1153