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