1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 *
6 * Copyright (c) 2022 Khronos Group
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 */ /*!
21 * \file
22 * \brief Test for Image Compression control
23 */ /*--------------------------------------------------------------------*/
24
25 #include <iostream>
26 #include <typeinfo>
27
28 #include "tcuCommandLine.hpp"
29 #include "tcuDefs.hpp"
30 #include "tcuFunctionLibrary.hpp"
31 #include "tcuPlatform.hpp"
32 #include "tcuResultCollector.hpp"
33 #include "tcuTestCase.hpp"
34 #include "tcuTestLog.hpp"
35
36 #include "vkApiVersion.hpp"
37 #include "vkDefs.hpp"
38 #include "vkPlatform.hpp"
39
40 #include "vktApiVersionCheck.hpp"
41 #include "vktCustomInstancesDevices.hpp"
42 #include "vktExternalMemoryUtil.hpp"
43 #include "vktTestCase.hpp"
44 #include "vktTestCaseUtil.hpp"
45 #include "vktTestGroupUtil.hpp"
46 #include "wsi/vktNativeObjectsUtil.hpp"
47
48 #include "vkDeviceUtil.hpp"
49 #include "vkImageUtil.hpp"
50 #include "vkQueryUtil.hpp"
51 #include "vkRefUtil.hpp"
52 #include "vkWsiUtil.hpp"
53
54 #include "deString.h"
55 #include "deStringUtil.hpp"
56
57 #include <map>
58 #include <vector>
59
60 using namespace vk;
61 using namespace vk::wsi;
62 using namespace std;
63
64 typedef vector<VkExtensionProperties> Extensions;
65
66 namespace vkt
67 {
68
69 namespace api
70 {
71
72 struct TestParams
73 {
74 VkFormat format;
75 bool useExtension;
76 VkImageCompressionControlEXT control;
77 Type wsiType;
78 };
79
checkImageCompressionControlSupport(Context& context, bool swapchain = false)80 static void checkImageCompressionControlSupport(Context& context, bool swapchain = false)
81 {
82 context.requireDeviceFunctionality("VK_EXT_image_compression_control");
83 vk::VkPhysicalDeviceImageCompressionControlFeaturesEXT imageCompressionControlFeatures = initVulkanStructure();
84 vk::VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT imageCompressionSwapchain = initVulkanStructure();
85 vk::VkPhysicalDeviceFeatures2 features2 = initVulkanStructure(&imageCompressionControlFeatures);
86 if (swapchain)
87 {
88 context.requireDeviceFunctionality("VK_EXT_image_compression_control_swapchain");
89 imageCompressionControlFeatures.pNext = &imageCompressionSwapchain;
90 }
91
92 context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features2);
93
94 if (!imageCompressionControlFeatures.imageCompressionControl)
95 TCU_THROW(NotSupportedError, "VK_EXT_image_compression_control Image "
96 "compression control feature not supported.");
97 if (swapchain && !imageCompressionSwapchain.imageCompressionControlSwapchain)
98 TCU_THROW(NotSupportedError, "VK_EXT_image_compression_control_swapchain Image "
99 "compression control feature for swapchains not supported.");
100 }
101
validate(const InstanceInterface& vki, const DeviceInterface& vkd, tcu::ResultCollector& results, VkPhysicalDevice physicalDevice, VkDevice device, TestParams& testParams, VkImage image)102 static void validate(const InstanceInterface& vki, const DeviceInterface& vkd, tcu::ResultCollector& results,
103 VkPhysicalDevice physicalDevice, VkDevice device, TestParams& testParams, VkImage image)
104 {
105 constexpr VkImageAspectFlags planeAspects[]{ VK_IMAGE_ASPECT_PLANE_0_BIT, VK_IMAGE_ASPECT_PLANE_1_BIT,
106 VK_IMAGE_ASPECT_PLANE_2_BIT };
107 const bool isYCbCr = isYCbCrFormat(testParams.format);
108 const int numPlanes = isYCbCr ? getPlaneCount(testParams.format) : 1;
109 for (int planeIndex = 0; planeIndex < numPlanes; planeIndex++)
110 {
111 VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT;
112 if (isYCbCr)
113 {
114 aspect = planeAspects[planeIndex];
115 }
116
117 VkImageCompressionPropertiesEXT compressionProperties = initVulkanStructure();
118 VkImageSubresource2EXT subresource = initVulkanStructure();
119 subresource.imageSubresource.aspectMask = aspect;
120 VkSubresourceLayout2EXT subresourceLayout = initVulkanStructure(&compressionProperties);
121 vkd.getImageSubresourceLayout2KHR(device, image, &subresource, &subresourceLayout);
122
123 VkImageCompressionControlEXT compressionEnabled = initVulkanStructure();
124 compressionEnabled.compressionControlPlaneCount = testParams.control.compressionControlPlaneCount;
125 compressionEnabled.flags = testParams.control.flags;
126 VkImageCompressionFixedRateFlagsEXT fixedRateFlags[3] = {
127 VK_IMAGE_COMPRESSION_FIXED_RATE_FLAG_BITS_MAX_ENUM_EXT,
128 VK_IMAGE_COMPRESSION_FIXED_RATE_FLAG_BITS_MAX_ENUM_EXT,
129 VK_IMAGE_COMPRESSION_FIXED_RATE_FLAG_BITS_MAX_ENUM_EXT
130 };
131
132 if (compressionEnabled.compressionControlPlaneCount > 0)
133 {
134 compressionEnabled.pFixedRateFlags = fixedRateFlags;
135 }
136
137 VkPhysicalDeviceImageFormatInfo2 formatInfo = initVulkanStructure(&compressionEnabled);
138 formatInfo.format = testParams.format;
139 formatInfo.type = VK_IMAGE_TYPE_2D;
140 formatInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
141 formatInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
142
143 VkImageCompressionPropertiesEXT compressionPropertiesSupported = initVulkanStructure();
144 VkImageFormatProperties2 properties2 = initVulkanStructure(&compressionPropertiesSupported);
145
146 vki.getPhysicalDeviceImageFormatProperties2(physicalDevice, &formatInfo, &properties2);
147
148 if (testParams.useExtension)
149 {
150 if ((compressionPropertiesSupported.imageCompressionFixedRateFlags &
151 compressionProperties.imageCompressionFixedRateFlags) !=
152 compressionProperties.imageCompressionFixedRateFlags)
153 {
154 results.fail("Got image with fixed rate flags that are not supported "
155 "in image format properties.");
156 }
157 if ((compressionPropertiesSupported.imageCompressionFlags & compressionProperties.imageCompressionFlags) !=
158 compressionProperties.imageCompressionFlags &&
159 compressionProperties.imageCompressionFlags != VK_IMAGE_COMPRESSION_DISABLED_EXT)
160 {
161 results.fail("Got image with compression flags that are not supported "
162 "in image format properties.");
163 }
164 if (testParams.control.flags == VK_IMAGE_COMPRESSION_DEFAULT_EXT &&
165 compressionProperties.imageCompressionFixedRateFlags != 0)
166 {
167 results.fail("Got lossy compression when DEFAULT compression was requested.");
168 }
169 if (testParams.control.flags == VK_IMAGE_COMPRESSION_DISABLED_EXT &&
170 compressionProperties.imageCompressionFlags != VK_IMAGE_COMPRESSION_DISABLED_EXT)
171 {
172 results.fail("Image compression not disabled.");
173 }
174 if (testParams.control.flags == VK_IMAGE_COMPRESSION_DISABLED_EXT &&
175 compressionProperties.imageCompressionFixedRateFlags != 0)
176 {
177 results.fail("Image compression disabled but got fixed rate flags.");
178 }
179 if (testParams.control.flags == VK_IMAGE_COMPRESSION_FIXED_RATE_DEFAULT_EXT &&
180 !(compressionProperties.imageCompressionFlags == VK_IMAGE_COMPRESSION_FIXED_RATE_EXPLICIT_EXT ||
181 compressionProperties.imageCompressionFlags == VK_IMAGE_COMPRESSION_DISABLED_EXT ||
182 compressionProperties.imageCompressionFlags == VK_IMAGE_COMPRESSION_DEFAULT_EXT))
183 {
184 results.fail("Explicit compression flags not returned for image "
185 "creation with FIXED RATE DEFAULT.");
186 }
187
188 if (testParams.control.flags == VK_IMAGE_COMPRESSION_FIXED_RATE_EXPLICIT_EXT)
189 {
190 uint32_t minRequestedRate = 1 << deCtz32(testParams.control.pFixedRateFlags[planeIndex]);
191 uint32_t actualRate = compressionProperties.imageCompressionFixedRateFlags;
192 if (compressionProperties.imageCompressionFlags != VK_IMAGE_COMPRESSION_DISABLED_EXT &&
193 compressionProperties.imageCompressionFlags != VK_IMAGE_COMPRESSION_DEFAULT_EXT)
194 {
195
196 if (minRequestedRate > actualRate)
197 {
198 results.fail("Image created with less bpc than requested.");
199 }
200 }
201 }
202 }
203 else
204 {
205 if (compressionProperties.imageCompressionFixedRateFlags != VK_IMAGE_COMPRESSION_FIXED_RATE_NONE_EXT)
206 {
207 results.fail("Fixed rate compression should not be enabled.");
208 }
209
210 if (compressionProperties.imageCompressionFlags != VK_IMAGE_COMPRESSION_DISABLED_EXT &&
211 compressionProperties.imageCompressionFlags != VK_IMAGE_COMPRESSION_DEFAULT_EXT)
212 {
213 results.fail("Image compression should be default or not be enabled.");
214 }
215 }
216 }
217 }
218
checkAhbImageSupport(const Context& context, const TestParams testParams, const deUint32 width, const deUint32 height, const VkImageUsageFlagBits vkUsage)219 static void checkAhbImageSupport (const Context& context, const TestParams testParams, const deUint32 width, const deUint32 height, const VkImageUsageFlagBits vkUsage)
220 {
221 using namespace vkt::ExternalMemoryUtil;
222
223 // Check android hardware buffer can be allocated for the format with usage.
224 AndroidHardwareBufferExternalApi* ahbApi = AndroidHardwareBufferExternalApi::getInstance();
225 if (!ahbApi)
226 {
227 TCU_THROW(NotSupportedError, "Platform doesn't support Android Hardware Buffer handles");
228 }
229 deUint64 ahbUsage = ahbApi->vkUsageToAhbUsage(vkUsage);
230 {
231 pt::AndroidHardwareBufferPtr ahb = ahbApi->allocate(width,height, 1, ahbApi->vkFormatToAhbFormat(testParams.format), ahbUsage);
232 if (ahb.internal == DE_NULL)
233 {
234 TCU_THROW(NotSupportedError, "Android hardware buffer format not supported");
235 }
236 }
237
238 // Check external memory supported.
239 const VkPhysicalDeviceExternalImageFormatInfoKHR external_image_format_info =
240 {
241 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
242 &testParams.control,
243 VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID
244 };
245
246 const VkPhysicalDeviceImageFormatInfo2 info =
247 {
248 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
249 &external_image_format_info,
250 testParams.format,
251 VK_IMAGE_TYPE_2D,
252 VK_IMAGE_TILING_OPTIMAL,
253 VK_IMAGE_USAGE_SAMPLED_BIT,
254 0,
255 };
256
257 VkImageCompressionPropertiesEXT compressionPropertiesSupported =
258 {
259 VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_PROPERTIES_EXT,
260 DE_NULL,
261 0,
262 0
263 };
264
265 VkAndroidHardwareBufferUsageANDROID ahbUsageProperties =
266 {
267 VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID,
268 &compressionPropertiesSupported,
269 0u
270 };
271
272 VkExternalImageFormatProperties externalProperties =
273 {
274 VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES,
275 &ahbUsageProperties,
276 { 0u, 0u, 0u }
277 };
278
279 VkImageFormatProperties2 properties =
280 {
281 VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
282 &externalProperties,
283 {
284 { 0u, 0u, 0u },
285 0u,
286 0u,
287 0u,
288 0u
289 }
290 };
291
292 VkResult result = context.getInstanceInterface().getPhysicalDeviceImageFormatProperties2(context.getPhysicalDevice(), &info, &properties);
293
294 if(result == VK_ERROR_FORMAT_NOT_SUPPORTED)
295 TCU_THROW(NotSupportedError, "Format not supported");
296
297 if ((externalProperties.externalMemoryProperties.externalMemoryFeatures & VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT) == 0)
298 TCU_THROW(NotSupportedError, "External handle type doesn't support exporting image");
299
300 if ((externalProperties.externalMemoryProperties.externalMemoryFeatures & VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT) == 0)
301 TCU_THROW(NotSupportedError, "External handle type requires dedicated allocation");
302
303 if((compressionPropertiesSupported.imageCompressionFlags == VK_IMAGE_COMPRESSION_DISABLED_EXT)
304 && (testParams.control.flags != VK_IMAGE_COMPRESSION_DISABLED_EXT))
305 {
306 TCU_THROW(NotSupportedError, "Compression is disbaled, and other compression flags are not supported");
307 }
308
309 if((ahbUsageProperties.androidHardwareBufferUsage & ahbUsage) != ahbUsage)
310 {
311 TCU_THROW(NotSupportedError, "Android hardware buffer usage is not supported");
312 }
313 }
314
CheckOHOSImageSupport(const Context& context, const TestParams testParams, const deUint32 width, const deUint32 height, const VkImageUsageFlagBits vkUsage)315 static void CheckOHOSImageSupport (const Context& context, const TestParams testParams, const deUint32 width,
316 const deUint32 height, const VkImageUsageFlagBits vkUsage)
317 {
318 using namespace vkt::ExternalMemoryUtil;
319
320 // Check native buffer can be allocated for the format with usage.
321 OHOSNativeBufferExternalApi* bufferApi = OHOSNativeBufferExternalApi::getInstance();
322 if (!bufferApi)
323 {
324 TCU_THROW(NotSupportedError, "Platform doesn't support Native Buffer handles");
325 }
326 deUint64 ohosUsage = bufferApi->VKUsageToOHOSUsage(vkUsage);
327 {
328 pt::OHOSNativeBufferPtr ptr = bufferApi->Allocate(width,height, bufferApi->VKFormatToOHOSFormat(
329 testParams.format), ohosUsage);
330 if (ptr.internal == DE_NULL)
331 {
332 TCU_THROW(NotSupportedError, "OHOS Native buffer format not supported");
333 }
334 }
335
336 // Check external memory supported.
337 const VkPhysicalDeviceExternalImageFormatInfoKHR external_image_format_info =
338 {
339 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
340 &testParams.control,
341 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OHOS_NATIVE_BUFFER_BIT_OHOS
342 };
343
344 const VkPhysicalDeviceImageFormatInfo2 info =
345 {
346 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
347 &external_image_format_info,
348 testParams.format,
349 VK_IMAGE_TYPE_2D,
350 VK_IMAGE_TILING_OPTIMAL,
351 VK_IMAGE_USAGE_SAMPLED_BIT,
352 0,
353 };
354
355 VkImageCompressionPropertiesEXT compressionPropertiesSupported =
356 {
357 VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_PROPERTIES_EXT,
358 DE_NULL,
359 0,
360 0
361 };
362
363 VkNativeBufferUsageOHOS ohosUsageProperties =
364 {
365 VK_STRUCTURE_TYPE_NATIVE_BUFFER_USAGE_OHOS,
366 &compressionPropertiesSupported,
367 0u
368 };
369
370 VkExternalImageFormatProperties externalProperties =
371 {
372 VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES,
373 &ohosUsageProperties,
374 { 0u, 0u, 0u }
375 };
376
377 VkImageFormatProperties2 properties =
378 {
379 VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
380 &externalProperties,
381 {
382 { 0u, 0u, 0u },
383 0u,
384 0u,
385 0u,
386 0u
387 }
388 };
389
390 VkResult result = context.getInstanceInterface().getPhysicalDeviceImageFormatProperties2(
391 context.getPhysicalDevice(), &info, &properties);
392
393 if(result == VK_ERROR_FORMAT_NOT_SUPPORTED)
394 TCU_THROW(NotSupportedError, "Format not supported");
395
396 if ((externalProperties.externalMemoryProperties.externalMemoryFeatures & VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT) == 0)
397 TCU_THROW(NotSupportedError, "External handle type doesn't support exporting image");
398
399 if ((externalProperties.externalMemoryProperties.externalMemoryFeatures & VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT) == 0)
400 TCU_THROW(NotSupportedError, "External handle type requires dedicated allocation");
401
402 if((compressionPropertiesSupported.imageCompressionFlags == VK_IMAGE_COMPRESSION_DISABLED_EXT)
403 && (testParams.control.flags != VK_IMAGE_COMPRESSION_DISABLED_EXT))
404 {
405 TCU_THROW(NotSupportedError, "Compression is disbaled, and other compression flags are not supported");
406 }
407
408 if((ohosUsageProperties.OHOSNativeBufferUsage & ohosUsage) != ohosUsage)
409 {
410 TCU_THROW(NotSupportedError, "Native buffer usage is not supported");
411 }
412 }
413
ahbImageCreateTest(Context& context, TestParams testParams)414 static tcu::TestStatus ahbImageCreateTest(Context& context, TestParams testParams)
415 {
416 using namespace vkt::ExternalMemoryUtil;
417
418 context.requireDeviceFunctionality("VK_ANDROID_external_memory_android_hardware_buffer");
419 context.requireDeviceFunctionality("VK_EXT_image_compression_control");
420
421 const deUint32 width = 32;
422 const deUint32 height = 32;
423 deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
424 const vk::DeviceInterface& vkd = context.getDeviceInterface();
425 VkDevice device = context.getDevice();
426 tcu::TestLog& log = context.getTestContext().getLog();
427 tcu::ResultCollector results(log);
428 const VkImageUsageFlagBits vkUsage = VK_IMAGE_USAGE_SAMPLED_BIT;
429 const bool is_fixed_rate_ex = testParams.control.flags == VK_IMAGE_COMPRESSION_FIXED_RATE_EXPLICIT_EXT;
430 const uint32_t numPlanes = isYCbCrFormat(testParams.format) ? getPlaneCount(testParams.format) : 1;
431
432 testParams.control.compressionControlPlaneCount = is_fixed_rate_ex ? numPlanes : 0;
433
434 VkImageCompressionFixedRateFlagsEXT planeFlags[3]{};
435
436 for (unsigned i{}; i < (is_fixed_rate_ex ? 24 : 1); i++)
437 {
438 planeFlags[0] ^= 3 << i;
439 planeFlags[1] ^= 5 << i;
440 planeFlags[2] ^= 7 << i;
441
442 if (is_fixed_rate_ex)
443 {
444 testParams.control.compressionControlPlaneCount = numPlanes;
445 testParams.control.pFixedRateFlags = planeFlags;
446 }
447
448 const vk::VkExternalMemoryImageCreateInfo externalCreateInfo = {
449 vk::VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO, &testParams.control,
450 VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID
451 };
452 const vk::VkImageCreateInfo createInfo = { vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
453 &externalCreateInfo,
454 0,
455 vk::VK_IMAGE_TYPE_2D,
456 testParams.format,
457 {
458 width,
459 height,
460 1u,
461 },
462 1,
463 1,
464 vk::VK_SAMPLE_COUNT_1_BIT,
465 VK_IMAGE_TILING_OPTIMAL,
466 vkUsage,
467 vk::VK_SHARING_MODE_EXCLUSIVE,
468 1,
469 &queueFamilyIndex,
470 vk::VK_IMAGE_LAYOUT_UNDEFINED };
471
472 checkAhbImageSupport(context, testParams, width, height, vkUsage);
473
474 Move<VkImage> image = vk::createImage(vkd, device, &createInfo);
475 const VkMemoryRequirements requirements = ExternalMemoryUtil::getImageMemoryRequirements(
476 vkd, device, image.get(), VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID);
477 const deUint32 exportedMemoryTypeIndex(ExternalMemoryUtil::chooseMemoryType(requirements.memoryTypeBits));
478 Move<VkDeviceMemory> memory = ExternalMemoryUtil::allocateExportableMemory(
479 vkd, device, requirements.size, exportedMemoryTypeIndex,
480 VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID, image.get());
481
482 VK_CHECK(vkd.bindImageMemory(device, image.get(), memory.get(), 0u));
483 validate(context.getInstanceInterface(), context.getDeviceInterface(), results, context.getPhysicalDevice(),
484 context.getDevice(), testParams, image.get());
485 }
486 return tcu::TestStatus(results.getResult(), results.getMessage());
487 }
488
OHOSImageCreateTest(Context& context, TestParams testParams)489 static tcu::TestStatus OHOSImageCreateTest(Context& context, TestParams testParams)
490 {
491 using namespace vkt::ExternalMemoryUtil;
492
493 context.requireDeviceFunctionality("VK_OHOS_external_memory");
494 context.requireDeviceFunctionality("VK_EXT_image_compression_control");
495
496 const deUint32 width = 32;
497 const deUint32 height = 32;
498 deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
499 const vk::DeviceInterface& vkd = context.getDeviceInterface();
500 VkDevice device = context.getDevice();
501 tcu::TestLog& log = context.getTestContext().getLog();
502 tcu::ResultCollector results(log);
503 const VkImageUsageFlagBits vkUsage = VK_IMAGE_USAGE_SAMPLED_BIT;
504 const bool is_fixed_rate_ex = testParams.control.flags == VK_IMAGE_COMPRESSION_FIXED_RATE_EXPLICIT_EXT;
505 const uint32_t numPlanes = isYCbCrFormat(testParams.format) ? getPlaneCount(testParams.format) : 1;
506
507 testParams.control.compressionControlPlaneCount = is_fixed_rate_ex ? numPlanes : 0;
508
509 VkImageCompressionFixedRateFlagsEXT planeFlags[3]{};
510
511 for (unsigned i{}; i < (is_fixed_rate_ex ? 24 : 1); i++)
512 {
513 planeFlags[0] ^= 3 << i;
514 planeFlags[1] ^= 5 << i;
515 planeFlags[2] ^= 7 << i;
516
517 if (is_fixed_rate_ex)
518 {
519 testParams.control.compressionControlPlaneCount = numPlanes;
520 testParams.control.pFixedRateFlags = planeFlags;
521 }
522
523 const vk::VkExternalMemoryImageCreateInfo externalCreateInfo = {
524 vk::VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO, &testParams.control,
525 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OHOS_NATIVE_BUFFER_BIT_OHOS
526 };
527 const vk::VkImageCreateInfo createInfo = { vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
528 &externalCreateInfo,
529 0,
530 vk::VK_IMAGE_TYPE_2D,
531 testParams.format,
532 {
533 width,
534 height,
535 1u,
536 },
537 1,
538 1,
539 vk::VK_SAMPLE_COUNT_1_BIT,
540 VK_IMAGE_TILING_OPTIMAL,
541 vkUsage,
542 vk::VK_SHARING_MODE_EXCLUSIVE,
543 1,
544 &queueFamilyIndex,
545 vk::VK_IMAGE_LAYOUT_UNDEFINED };
546
547 CheckOHOSImageSupport(context, testParams, width, height, vkUsage);
548
549 Move<VkImage> image = vk::createImage(vkd, device, &createInfo);
550 const VkMemoryRequirements requirements = ExternalMemoryUtil::getImageMemoryRequirements(
551 vkd, device, image.get(), VK_EXTERNAL_MEMORY_HANDLE_TYPE_OHOS_NATIVE_BUFFER_BIT_OHOS);
552 const deUint32 exportedMemoryTypeIndex(ExternalMemoryUtil::chooseMemoryType(requirements.memoryTypeBits));
553 Move<VkDeviceMemory> memory = ExternalMemoryUtil::allocateExportableMemory(
554 vkd, device, requirements.size, exportedMemoryTypeIndex,
555 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OHOS_NATIVE_BUFFER_BIT_OHOS, image.get());
556
557 VK_CHECK(vkd.bindImageMemory(device, image.get(), memory.get(), 0u));
558 validate(context.getInstanceInterface(), context.getDeviceInterface(), results, context.getPhysicalDevice(),
559 context.getDevice(), testParams, image.get());
560 }
561 return tcu::TestStatus(results.getResult(), results.getMessage());
562 }
563
imageCreateTest(Context& context, TestParams testParams)564 static tcu::TestStatus imageCreateTest(Context& context, TestParams testParams)
565 {
566 checkImageCompressionControlSupport(context);
567 deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
568 const VkDevice device = context.getDevice();
569 VkExtent3D extent = { 16, 16, 1 };
570 tcu::TestLog& log = context.getTestContext().getLog();
571 tcu::ResultCollector results(log);
572 const bool is_fixed_rate_ex = testParams.control.flags == VK_IMAGE_COMPRESSION_FIXED_RATE_EXPLICIT_EXT;
573
574 VkImageCompressionFixedRateFlagsEXT planeFlags[3]{};
575
576 for (unsigned i{}; i < (is_fixed_rate_ex ? 24 : 1); i++)
577 {
578 planeFlags[0] ^= 3 << i;
579 planeFlags[1] ^= 5 << i;
580 planeFlags[2] ^= 7 << i;
581
582 if (is_fixed_rate_ex)
583 {
584 testParams.control.pFixedRateFlags = planeFlags;
585 }
586
587 VkImageCreateInfo imageCreateInfo = {
588 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
589 DE_NULL, // const void* pNext;
590 0, // VkImageCreateFlags flags;
591 VK_IMAGE_TYPE_2D, // VkImageType
592 testParams.format, // VkFormat format;
593 extent, // VkExtent3D extent;
594 1u, // deUint32 mipLevels;
595 1u, // deUint32 arraySize;
596 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
597 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
598 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, // VkImageUsageFlags usage;
599 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
600 1u, // deUint32 queueFamilyCount;
601 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
602 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
603 };
604
605 if (testParams.useExtension)
606 {
607 imageCreateInfo.pNext = &testParams.control;
608 }
609
610 checkImageSupport(context.getInstanceInterface(), context.getPhysicalDevice(), imageCreateInfo);
611
612 Move<VkImage> image = createImage(context.getDeviceInterface(), device, &imageCreateInfo);
613
614 validate(context.getInstanceInterface(), context.getDeviceInterface(), results, context.getPhysicalDevice(),
615 context.getDevice(), testParams, image.get());
616 }
617 return tcu::TestStatus(results.getResult(), results.getMessage());
618 }
619
addImageCompressionControlTests(tcu::TestCaseGroup* group, TestParams testParams)620 void addImageCompressionControlTests(tcu::TestCaseGroup* group, TestParams testParams)
621 {
622 const bool is_fixed_rate_ex = testParams.control.flags == VK_IMAGE_COMPRESSION_FIXED_RATE_EXPLICIT_EXT;
623
624 static const struct
625 {
626 VkFormat begin;
627 VkFormat end;
628 } s_formatRanges[] = {
629 // core formats
630 { (VkFormat)(VK_FORMAT_UNDEFINED + 1), VK_CORE_FORMAT_LAST },
631
632 // YCbCr formats
633 { VK_FORMAT_G8B8G8R8_422_UNORM, (VkFormat)(VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM + 1) },
634
635 // YCbCr extended formats
636 { VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT, (VkFormat)(VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT + 1) },
637 };
638
639 for (int rangeNdx = 0; rangeNdx < DE_LENGTH_OF_ARRAY(s_formatRanges); ++rangeNdx)
640 {
641 const VkFormat rangeBegin = s_formatRanges[rangeNdx].begin;
642 const VkFormat rangeEnd = s_formatRanges[rangeNdx].end;
643
644 for (testParams.format = rangeBegin; testParams.format != rangeEnd;
645 testParams.format = (VkFormat)(testParams.format + 1))
646 {
647 if (isCompressedFormat(testParams.format))
648 continue;
649
650 const uint32_t numPlanes = isYCbCrFormat(testParams.format) ? getPlaneCount(testParams.format) : 1;
651 testParams.control.compressionControlPlaneCount = is_fixed_rate_ex ? numPlanes : 0;
652
653 const char* const enumName = getFormatName(testParams.format);
654 const string caseName = de::toLower(string(enumName).substr(10));
655 addFunctionCase(group, caseName, imageCreateTest, testParams);
656 }
657 }
658 }
659
createInstanceWithWsi(Context& context, Type wsiType, const vector<string> extraExtensions, const VkAllocationCallbacks* pAllocator = DE_NULL)660 CustomInstance createInstanceWithWsi(Context& context, Type wsiType, const vector<string> extraExtensions,
661 const VkAllocationCallbacks* pAllocator = DE_NULL)
662 {
663 const deUint32 version = context.getUsedApiVersion();
664 vector<string> extensions = extraExtensions;
665
666 extensions.push_back("VK_KHR_surface");
667 extensions.push_back(getExtensionName(wsiType));
668 extensions.push_back("VK_KHR_get_surface_capabilities2");
669
670 vector<string> instanceExtensions;
671 for (const auto& ext : extensions)
672 {
673 if (!context.isInstanceFunctionalitySupported(ext))
674 TCU_THROW(NotSupportedError, (ext + " is not supported").c_str());
675
676 if (!isCoreInstanceExtension(version, ext))
677 instanceExtensions.push_back(ext);
678 }
679
680 return vkt::createCustomInstanceWithExtensions(context, instanceExtensions, pAllocator);
681 }
682 struct InstanceHelper
683 {
684 const vector<VkExtensionProperties> supportedExtensions;
685 CustomInstance instance;
686 const InstanceDriver& vki;
687
InstanceHelpervkt::api::InstanceHelper688 InstanceHelper(Context& context, Type wsiType, const VkAllocationCallbacks* pAllocator = DE_NULL)
689 : supportedExtensions(enumerateInstanceExtensionProperties(context.getPlatformInterface(), DE_NULL))
690 , instance(createInstanceWithWsi(context, wsiType, vector<string>(), pAllocator))
691 , vki(instance.getDriver())
692 {
693 }
694
InstanceHelpervkt::api::InstanceHelper695 InstanceHelper(Context& context, Type wsiType, const vector<string>& extensions,
696 const VkAllocationCallbacks* pAllocator = DE_NULL)
697 : supportedExtensions(enumerateInstanceExtensionProperties(context.getPlatformInterface(), DE_NULL))
698 , instance(createInstanceWithWsi(context, wsiType, extensions, pAllocator))
699 , vki(instance.getDriver())
700 {
701 }
702 };
703
createDeviceWithWsi(const PlatformInterface& vkp, deUint32 apiVersion, VkInstance instance, const InstanceInterface& vki, VkPhysicalDevice physicalDevice, const Extensions& supportedExtensions, const vector<string>& additionalExtensions, deUint32 queueFamilyIndex, bool validationEnabled, const VkAllocationCallbacks* pAllocator = DE_NULL)704 Move<VkDevice> createDeviceWithWsi(const PlatformInterface& vkp, deUint32 apiVersion, VkInstance instance,
705 const InstanceInterface& vki, VkPhysicalDevice physicalDevice,
706 const Extensions& supportedExtensions, const vector<string>& additionalExtensions,
707 deUint32 queueFamilyIndex, bool validationEnabled,
708 const VkAllocationCallbacks* pAllocator = DE_NULL)
709 {
710 const float queuePriorities[] = { 1.0f };
711 const VkDeviceQueueCreateInfo queueInfo = {
712 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
713 nullptr,
714 (VkDeviceQueueCreateFlags)0,
715 queueFamilyIndex,
716 DE_LENGTH_OF_ARRAY(queuePriorities),
717 &queuePriorities[0],
718 };
719
720 vector<string> extensions;
721 extensions.push_back("VK_KHR_swapchain");
722 extensions.push_back("VK_EXT_image_compression_control");
723 extensions.push_back("VK_EXT_image_compression_control_swapchain");
724 extensions.insert(end(extensions), begin(additionalExtensions), end(additionalExtensions));
725
726 for (const auto& extName : extensions)
727 {
728 if (!isCoreDeviceExtension(apiVersion, extName) &&
729 !isExtensionStructSupported(supportedExtensions, RequiredExtension(extName)))
730 TCU_THROW(NotSupportedError, extName + " is not supported");
731 }
732
733 vk::VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT imageCompressionSwapchain = initVulkanStructure();
734 imageCompressionSwapchain.imageCompressionControlSwapchain = VK_TRUE;
735
736 const VkPhysicalDeviceFeatures features = {};
737
738 // Convert from std::vector<std::string> to std::vector<const char*>.
739 std::vector<const char*> extensionsChar;
740 extensionsChar.reserve(extensions.size());
741 std::transform(begin(extensions), end(extensions), std::back_inserter(extensionsChar),
742 [](const std::string& s) { return s.c_str(); });
743
744 const VkDeviceCreateInfo deviceParams = { VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
745 &imageCompressionSwapchain,
746 (VkDeviceCreateFlags)0,
747 1u,
748 &queueInfo,
749 0u, // enabledLayerCount
750 nullptr, // ppEnabledLayerNames
751 static_cast<deUint32>(extensionsChar.size()), // enabledExtensionCount
752 extensionsChar.data(), // ppEnabledExtensionNames
753 &features };
754
755 return createCustomDevice(validationEnabled, vkp, instance, vki, physicalDevice, &deviceParams, pAllocator);
756 }
757
758 struct DeviceHelper
759 {
760 const VkPhysicalDevice physicalDevice;
761 const deUint32 queueFamilyIndex;
762 const Unique<VkDevice> device;
763 const DeviceDriver vkd;
764 const VkQueue queue;
765
DeviceHelpervkt::api::DeviceHelper766 DeviceHelper(Context& context, const InstanceInterface& vki, VkInstance instance,
767 const vector<VkSurfaceKHR>& surface, const vector<string>& additionalExtensions = vector<string>(),
768 const VkAllocationCallbacks* pAllocator = DE_NULL)
769 : physicalDevice(chooseDevice(vki, instance, context.getTestContext().getCommandLine()))
770 , queueFamilyIndex(chooseQueueFamilyIndex(vki, physicalDevice, surface))
771 , device(createDeviceWithWsi(context.getPlatformInterface(), context.getUsedApiVersion(), instance, vki,
772 physicalDevice, enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL),
773 additionalExtensions, queueFamilyIndex,
774 context.getTestContext().getCommandLine().isValidationEnabled(), pAllocator))
775 , vkd(context.getPlatformInterface(), instance, *device, context.getUsedApiVersion())
776 , queue(getDeviceQueue(vkd, *device, queueFamilyIndex, 0))
777 {
778 }
779
780 // Single-surface shortcut.
DeviceHelpervkt::api::DeviceHelper781 DeviceHelper(Context& context, const InstanceInterface& vki, VkInstance instance, VkSurfaceKHR surface,
782 const vector<string>& additionalExtensions = vector<string>(),
783 const VkAllocationCallbacks* pAllocator = DE_NULL)
784 : DeviceHelper(context, vki, instance, vector<VkSurfaceKHR>(1u, surface), additionalExtensions, pAllocator)
785 {
786 }
787 };
swapchainCreateTest(Context& context, TestParams testParams)788 static tcu::TestStatus swapchainCreateTest(Context& context, TestParams testParams)
789 {
790 checkImageCompressionControlSupport(context, true);
791
792 tcu::TestLog& log = context.getTestContext().getLog();
793 tcu::ResultCollector results(log);
794
795 const InstanceHelper instHelper(context, testParams.wsiType);
796 const wsi::NativeObjects native(context, instHelper.supportedExtensions, testParams.wsiType);
797 const bool is_fixed_rate_ex = testParams.control.flags == VK_IMAGE_COMPRESSION_FIXED_RATE_EXPLICIT_EXT;
798
799 VkExtent2D extent2d = { 16, 16 };
800 VkImageCompressionFixedRateFlagsEXT planeFlags[3]{};
801
802 for (unsigned i{}; i < (is_fixed_rate_ex ? 24 : 1); i++)
803 {
804 planeFlags[0] ^= 3 << i;
805
806 if (is_fixed_rate_ex)
807 {
808 testParams.control.pFixedRateFlags = planeFlags;
809 }
810
811 const Unique<VkSurfaceKHR> surface(createSurface(instHelper.vki, instHelper.instance, testParams.wsiType,
812 native.getDisplay(), native.getWindow(),
813 context.getTestContext().getCommandLine()));
814
815 const DeviceHelper devHelper(context, instHelper.vki, instHelper.instance, *surface, vector<string>());
816
817 VkPhysicalDeviceSurfaceInfo2KHR surfaceInfo = initVulkanStructure();
818 VkSurfaceCapabilities2KHR caps = initVulkanStructure();
819 surfaceInfo.surface = surface.get();
820
821 instHelper.vki.getPhysicalDeviceSurfaceCapabilities2KHR(devHelper.physicalDevice, &surfaceInfo, &caps);
822
823 deUint32 numFormats;
824 instHelper.vki.getPhysicalDeviceSurfaceFormats2KHR(devHelper.physicalDevice, &surfaceInfo, &numFormats,
825 nullptr);
826
827 vector<VkSurfaceFormat2KHR> formats(numFormats);
828 for (auto& surfaceFormat : formats)
829 {
830 surfaceFormat = initVulkanStructure();
831 }
832
833 instHelper.vki.getPhysicalDeviceSurfaceFormats2KHR(devHelper.physicalDevice, &surfaceInfo, &numFormats,
834 formats.data());
835
836 deUint32 queueFamilyIndex = devHelper.queueFamilyIndex;
837
838 for (auto& format : formats)
839 {
840 testParams.format = format.surfaceFormat.format;
841
842 const uint32_t numPlanes = isYCbCrFormat(testParams.format) ? getPlaneCount(testParams.format) : 1;
843 testParams.control.compressionControlPlaneCount = is_fixed_rate_ex ? numPlanes : 0;
844
845 VkSwapchainCreateInfoKHR swapchainInfo = initVulkanStructure();
846 swapchainInfo.surface = surface.get();
847 swapchainInfo.minImageCount = caps.surfaceCapabilities.minImageCount;
848 swapchainInfo.imageFormat = format.surfaceFormat.format;
849 swapchainInfo.imageColorSpace = format.surfaceFormat.colorSpace;
850 swapchainInfo.imageExtent = extent2d;
851 swapchainInfo.imageArrayLayers = 1;
852 swapchainInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
853 swapchainInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
854 swapchainInfo.queueFamilyIndexCount = 1;
855 swapchainInfo.pQueueFamilyIndices = &queueFamilyIndex;
856 swapchainInfo.preTransform = caps.surfaceCapabilities.currentTransform;
857 swapchainInfo.compositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR;
858 swapchainInfo.presentMode = VK_PRESENT_MODE_FIFO_KHR;
859 swapchainInfo.clipped = VK_TRUE;
860
861 swapchainInfo.pNext = &testParams.control;
862
863 Move<VkSwapchainKHR> swapchain = createSwapchainKHR(devHelper.vkd, devHelper.device.get(), &swapchainInfo);
864
865 deUint32 imageCount = 0;
866 devHelper.vkd.getSwapchainImagesKHR(devHelper.device.get(), swapchain.get(), &imageCount, nullptr);
867 vector<VkImage> images(imageCount);
868 devHelper.vkd.getSwapchainImagesKHR(devHelper.device.get(), swapchain.get(), &imageCount, images.data());
869
870 validate(instHelper.vki, devHelper.vkd, results, devHelper.physicalDevice, devHelper.device.get(),
871 testParams, images[0]);
872 }
873 }
874
875 return tcu::TestStatus(results.getResult(), results.getMessage());
876 }
877
addAhbCompressionControlTests(tcu::TestCaseGroup *group, TestParams testParams)878 void addAhbCompressionControlTests(tcu::TestCaseGroup *group, TestParams testParams)
879 {
880 // Ahb formats
881 static const vk::VkFormat ahbFormats[] = {
882 VK_FORMAT_R8G8B8A8_UNORM,
883 VK_FORMAT_R8G8B8_UNORM,
884 VK_FORMAT_R5G6B5_UNORM_PACK16,
885 VK_FORMAT_R16G16B16A16_SFLOAT,
886 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
887 VK_FORMAT_D16_UNORM,
888 VK_FORMAT_X8_D24_UNORM_PACK32,
889 VK_FORMAT_D24_UNORM_S8_UINT,
890 VK_FORMAT_D32_SFLOAT,
891 VK_FORMAT_D32_SFLOAT_S8_UINT,
892 VK_FORMAT_S8_UINT
893 };
894
895 for (int index = 0; index < DE_LENGTH_OF_ARRAY(ahbFormats); ++index)
896 {
897 testParams.format = ahbFormats[index];
898 const char *const enumName = getFormatName(testParams.format);
899 const string caseName = de::toLower(string(enumName).substr(10));
900 addFunctionCase(group, caseName, ahbImageCreateTest, testParams);
901 }
902 }
903
AddOHOSCompressionControlTests(tcu::TestCaseGroup *group, TestParams testParams)904 void AddOHOSCompressionControlTests(tcu::TestCaseGroup *group, TestParams testParams)
905 {
906 static const vk::VkFormat formats[] = {
907 VK_FORMAT_R8G8B8A8_UNORM,
908 VK_FORMAT_R8G8B8_UNORM,
909 VK_FORMAT_R5G6B5_UNORM_PACK16,
910 VK_FORMAT_R16G16B16A16_SFLOAT,
911 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
912 VK_FORMAT_D16_UNORM,
913 VK_FORMAT_X8_D24_UNORM_PACK32,
914 VK_FORMAT_D24_UNORM_S8_UINT,
915 VK_FORMAT_D32_SFLOAT,
916 VK_FORMAT_D32_SFLOAT_S8_UINT,
917 VK_FORMAT_S8_UINT
918 };
919
920 for (int index = 0; index < DE_LENGTH_OF_ARRAY(formats); ++index)
921 {
922 testParams.format = formats[index];
923 const char *const enumName = getFormatName(testParams.format);
924 const string caseName = de::toLower(string(enumName).substr(10));
925 addFunctionCase(group, caseName, OHOSImageCreateTest, testParams);
926 }
927 }
928
createImageCompressionControlTests(tcu::TestContext& testCtx)929 tcu::TestCaseGroup* createImageCompressionControlTests(tcu::TestContext& testCtx)
930 {
931 // Test for image compression control.
932 de::MovePtr<tcu::TestCaseGroup> group(
933 new tcu::TestCaseGroup(testCtx, "image_compression_control"));
934
935 TestParams testParams{};
936 // Test creating images with compression control struct
937 tcu::TestCaseGroup* subgroup(
938 new tcu::TestCaseGroup(testCtx, "create_image"));
939
940 // Queries images created without compression control struct.
941 subgroup->addChild(createTestGroup(testCtx, "no_compression_control",
942 addImageCompressionControlTests, testParams));
943
944 testParams.useExtension = true;
945 testParams.control = initVulkanStructure();
946 testParams.control.flags = VK_IMAGE_COMPRESSION_FIXED_RATE_DEFAULT_EXT;
947
948 struct
949 {
950 const char* name;
951 VkImageCompressionFlagsEXT flag;
952 } constexpr compression_flags[] = {
953 { "default", VK_IMAGE_COMPRESSION_DEFAULT_EXT },
954 { "fixed_rate_default", VK_IMAGE_COMPRESSION_FIXED_RATE_DEFAULT_EXT },
955 { "disabled", VK_IMAGE_COMPRESSION_DISABLED_EXT },
956 { "explicit", VK_IMAGE_COMPRESSION_FIXED_RATE_EXPLICIT_EXT },
957 };
958
959 for (auto& flag : compression_flags)
960 {
961 testParams.control.flags = flag.flag;
962 // Queries images created with compression control struct.
963 subgroup->addChild(createTestGroup(testCtx, flag.name,
964 addImageCompressionControlTests, testParams));
965 }
966 group->addChild(subgroup);
967
968
969 // Test creating Android Hardware buffer with compression control struct
970 subgroup = new tcu::TestCaseGroup(testCtx, "android_hardware_buffer");
971
972 for (auto& flag : compression_flags)
973 {
974 testParams.control.flags = flag.flag;
975 // Queries images created with compression control struct.
976 subgroup->addChild(createTestGroup(testCtx, flag.name, addAhbCompressionControlTests, testParams));
977 }
978
979 group->addChild(subgroup);
980
981 subgroup = new tcu::TestCaseGroup(testCtx, "ohos_native_buffer");
982
983 for (auto& flag : compression_flags)
984 {
985 testParams.control.flags = flag.flag;
986 // Queries images created with compression control struct.
987 subgroup->addChild(createTestGroup(testCtx, flag.name, AddOHOSCompressionControlTests, testParams));
988 }
989
990 group->addChild(subgroup);
991
992 subgroup = new tcu::TestCaseGroup(testCtx, "swapchain");
993 for (int typeNdx = 0; typeNdx < vk::wsi::TYPE_LAST; ++typeNdx)
994 {
995 const vk::wsi::Type wsiType = (vk::wsi::Type)typeNdx;
996 testParams.wsiType = wsiType;
997
998 tcu::TestCaseGroup* wsi_subgroup(new tcu::TestCaseGroup(testCtx, getName(wsiType)));
999
1000 for (auto& flag : compression_flags)
1001 {
1002 testParams.control.flags = flag.flag;
1003 addFunctionCase(wsi_subgroup, flag.name, swapchainCreateTest, testParams);
1004 }
1005 subgroup->addChild(wsi_subgroup);
1006 }
1007
1008 group->addChild(subgroup);
1009
1010 return group.release();
1011 }
1012
1013 } // namespace api
1014
1015 } // namespace vkt
1016