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