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