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