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