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