• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 The Khronos Group Inc.
6  * Copyright (c) 2016 The Android Open Source Project
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 Memory qualifiers tests
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktImageExtendedUsageBitTests.hpp"
26 
27 #include "vkRef.hpp"
28 #include "vkQueryUtil.hpp"
29 #include "vktTestCaseUtil.hpp"
30 #include "vktImageTestsUtil.hpp"
31 
32 #include "tcuTestLog.hpp"
33 
34 using namespace vk;
35 
36 namespace vkt
37 {
38 namespace image
39 {
40 namespace
41 {
42 
isCompatibleCompressedFormat(VkFormat format0,VkFormat format1)43 bool isCompatibleCompressedFormat(VkFormat format0, VkFormat format1)
44 {
45 	DE_ASSERT(isCompressedFormat(format0) && isCompressedFormat(format1));
46 	// update this mapping if VkFormat changes
47 	DE_STATIC_ASSERT(VK_CORE_FORMAT_LAST == 185);
48 
49 	bool result = false;
50 
51 	std::map<VkFormat, VkFormat> map =
52 	{
53 		{ VK_FORMAT_BC1_RGB_UNORM_BLOCK, VK_FORMAT_BC1_RGB_SRGB_BLOCK },
54 		{ VK_FORMAT_BC1_RGB_SRGB_BLOCK, VK_FORMAT_BC1_RGB_UNORM_BLOCK },
55 		{ VK_FORMAT_BC1_RGBA_UNORM_BLOCK, VK_FORMAT_BC1_RGBA_SRGB_BLOCK },
56 		{ VK_FORMAT_BC1_RGBA_SRGB_BLOCK, VK_FORMAT_BC1_RGBA_UNORM_BLOCK },
57 		{ VK_FORMAT_BC2_UNORM_BLOCK, VK_FORMAT_BC2_SRGB_BLOCK },
58 		{ VK_FORMAT_BC2_SRGB_BLOCK, VK_FORMAT_BC2_UNORM_BLOCK },
59 		{ VK_FORMAT_BC3_UNORM_BLOCK, VK_FORMAT_BC3_SRGB_BLOCK },
60 		{ VK_FORMAT_BC3_SRGB_BLOCK, VK_FORMAT_BC3_UNORM_BLOCK },
61 		{ VK_FORMAT_BC4_UNORM_BLOCK, VK_FORMAT_BC4_SNORM_BLOCK },
62 		{ VK_FORMAT_BC4_SNORM_BLOCK, VK_FORMAT_BC4_UNORM_BLOCK},
63 		{ VK_FORMAT_BC5_UNORM_BLOCK, VK_FORMAT_BC5_SNORM_BLOCK },
64 		{ VK_FORMAT_BC5_SNORM_BLOCK, VK_FORMAT_BC5_UNORM_BLOCK },
65 		{ VK_FORMAT_BC7_UNORM_BLOCK, VK_FORMAT_BC7_SRGB_BLOCK },
66 		{ VK_FORMAT_BC7_SRGB_BLOCK, VK_FORMAT_BC7_UNORM_BLOCK },
67 		{ VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK },
68 		{ VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK, VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK },
69 		{ VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK },
70 		{ VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK, VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK },
71 		{ VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK },
72 		{ VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK, VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK },
73 		{ VK_FORMAT_EAC_R11_UNORM_BLOCK, VK_FORMAT_EAC_R11_SNORM_BLOCK },
74 		{ VK_FORMAT_EAC_R11_SNORM_BLOCK, VK_FORMAT_EAC_R11_UNORM_BLOCK },
75 		{ VK_FORMAT_EAC_R11G11_UNORM_BLOCK, VK_FORMAT_EAC_R11G11_SNORM_BLOCK },
76 		{ VK_FORMAT_EAC_R11G11_SNORM_BLOCK, VK_FORMAT_EAC_R11G11_UNORM_BLOCK },
77 		{ VK_FORMAT_ASTC_4x4_UNORM_BLOCK, VK_FORMAT_ASTC_4x4_SRGB_BLOCK },
78 		{ VK_FORMAT_ASTC_4x4_SRGB_BLOCK, VK_FORMAT_ASTC_4x4_UNORM_BLOCK },
79 		{ VK_FORMAT_ASTC_5x4_UNORM_BLOCK, VK_FORMAT_ASTC_5x4_SRGB_BLOCK },
80 		{ VK_FORMAT_ASTC_5x4_SRGB_BLOCK, VK_FORMAT_ASTC_5x4_UNORM_BLOCK },
81 		{ VK_FORMAT_ASTC_5x5_UNORM_BLOCK, VK_FORMAT_ASTC_5x5_SRGB_BLOCK },
82 		{ VK_FORMAT_ASTC_5x5_SRGB_BLOCK, VK_FORMAT_ASTC_5x5_UNORM_BLOCK },
83 		{ VK_FORMAT_ASTC_6x5_UNORM_BLOCK, VK_FORMAT_ASTC_6x5_SRGB_BLOCK },
84 		{ VK_FORMAT_ASTC_6x5_SRGB_BLOCK,  VK_FORMAT_ASTC_6x5_UNORM_BLOCK },
85 		{ VK_FORMAT_ASTC_6x6_UNORM_BLOCK, VK_FORMAT_ASTC_6x6_SRGB_BLOCK },
86 		{ VK_FORMAT_ASTC_6x6_SRGB_BLOCK, VK_FORMAT_ASTC_6x6_UNORM_BLOCK },
87 		{ VK_FORMAT_ASTC_8x5_UNORM_BLOCK, VK_FORMAT_ASTC_8x5_SRGB_BLOCK },
88 		{ VK_FORMAT_ASTC_8x5_SRGB_BLOCK, VK_FORMAT_ASTC_8x5_UNORM_BLOCK },
89 		{ VK_FORMAT_ASTC_8x6_UNORM_BLOCK, VK_FORMAT_ASTC_8x6_SRGB_BLOCK },
90 		{ VK_FORMAT_ASTC_8x6_SRGB_BLOCK, VK_FORMAT_ASTC_8x6_UNORM_BLOCK },
91 		{ VK_FORMAT_ASTC_8x8_UNORM_BLOCK, VK_FORMAT_ASTC_8x8_SRGB_BLOCK },
92 		{ VK_FORMAT_ASTC_8x8_SRGB_BLOCK, VK_FORMAT_ASTC_8x8_UNORM_BLOCK },
93 		{ VK_FORMAT_ASTC_10x5_UNORM_BLOCK, VK_FORMAT_ASTC_10x5_SRGB_BLOCK },
94 		{ VK_FORMAT_ASTC_10x5_SRGB_BLOCK, VK_FORMAT_ASTC_10x5_UNORM_BLOCK },
95 		{ VK_FORMAT_ASTC_10x6_UNORM_BLOCK, VK_FORMAT_ASTC_10x6_SRGB_BLOCK },
96 		{ VK_FORMAT_ASTC_10x6_SRGB_BLOCK, VK_FORMAT_ASTC_10x6_UNORM_BLOCK },
97 		{ VK_FORMAT_ASTC_10x8_UNORM_BLOCK, VK_FORMAT_ASTC_10x8_SRGB_BLOCK },
98 		{ VK_FORMAT_ASTC_10x8_SRGB_BLOCK, VK_FORMAT_ASTC_10x8_UNORM_BLOCK },
99 		{ VK_FORMAT_ASTC_10x10_UNORM_BLOCK, VK_FORMAT_ASTC_10x10_SRGB_BLOCK },
100 		{ VK_FORMAT_ASTC_10x10_SRGB_BLOCK, VK_FORMAT_ASTC_10x10_UNORM_BLOCK },
101 		{ VK_FORMAT_ASTC_12x10_UNORM_BLOCK, VK_FORMAT_ASTC_12x10_SRGB_BLOCK },
102 		{ VK_FORMAT_ASTC_12x10_SRGB_BLOCK, VK_FORMAT_ASTC_12x10_UNORM_BLOCK },
103 		{ VK_FORMAT_ASTC_12x12_UNORM_BLOCK, VK_FORMAT_ASTC_12x12_SRGB_BLOCK },
104 		{ VK_FORMAT_ASTC_12x12_SRGB_BLOCK, VK_FORMAT_ASTC_12x12_UNORM_BLOCK },
105 	};
106 
107 	if (map.find(format1) != map.end() && map.find(format1)->second == format0)
108 		result = true;
109 
110 	return result;
111 }
112 
isCompatibleFormat(VkFormat format0,VkFormat format1)113 bool isCompatibleFormat(VkFormat format0, VkFormat format1)
114 {
115 	if (format0 == format1)
116 		return true;
117 
118 	// Uncompressed color formats are compatible with each other if they occupy the same number of bits per texel block.
119 	if (!isDepthStencilFormat(format0) && !isCompressedFormat(format0) &&
120 		!isDepthStencilFormat(format1) && !isCompressedFormat(format1) &&
121 		mapVkFormat(format0).getPixelSize() == mapVkFormat(format1).getPixelSize())
122 		return true;
123 
124 	if (isCompressedFormat(format0) && isCompressedFormat(format1) &&
125 	    isCompatibleCompressedFormat(format0, format1))
126 		 return true;
127 
128 	return false;
129 }
130 
131 struct TestParams
132 {
133 	VkFormat			imageFormat;
134 	VkImageUsageFlags	usage;
135 	VkImageTiling		tiling;
136 };
137 
138 class PhysicalDeviceImageFormatProperties
139 {
140 public:
getPhysicalDeviceImageFormatProperties(const InstanceInterface & vki,VkPhysicalDevice device,VkFormat viewFormat,VkImageTiling tiling,VkImageUsageFlags usage,VkImageCreateFlags flags)141 	virtual VkResult getPhysicalDeviceImageFormatProperties(const InstanceInterface &vki, VkPhysicalDevice device, VkFormat viewFormat, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags)
142 	{
143 		VkImageFormatProperties formatProperties;
144 		return vki.getPhysicalDeviceImageFormatProperties(device, viewFormat, VK_IMAGE_TYPE_2D, tiling, usage, flags, &formatProperties);
145 	}
146 };
147 
148 class PhysicalDeviceImageFormatProperties2 : public PhysicalDeviceImageFormatProperties
149 {
150 public:
getPhysicalDeviceImageFormatProperties(const InstanceInterface & vki,VkPhysicalDevice device,VkFormat viewFormat,VkImageTiling tiling,VkImageUsageFlags usage,VkImageCreateFlags flags)151 	virtual VkResult getPhysicalDeviceImageFormatProperties(const InstanceInterface &vki, VkPhysicalDevice device, VkFormat viewFormat, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags)
152 	{
153 		VkImageFormatProperties2			formatProperties2	= initVulkanStructure();
154 		VkPhysicalDeviceImageFormatInfo2	imageFormatInfo2	=
155 		{
156 			VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,	// VkStructureType		sType
157 			DE_NULL,												// const void*			pNext
158 			viewFormat,												// VkFormat				format
159 			VK_IMAGE_TYPE_2D,										// VkImageType			type
160 			tiling,													// VkImageTiling		tiling
161 			usage,													// VkImageUsageFlags	usage
162 			flags													// VkImageCreateFlags	flags
163 		};
164 		return vki.getPhysicalDeviceImageFormatProperties2(device, &imageFormatInfo2, &formatProperties2);
165 	}
166 };
167 
168 template<typename T>
testExtendedUsageBitCompatiblity(Context & context,TestParams params)169 tcu::TestStatus testExtendedUsageBitCompatiblity (Context& context, TestParams params)
170 {
171 	T							func;
172 	VkFormat					viewFormat;
173 	VkResult					expected			= VK_ERROR_FORMAT_NOT_SUPPORTED;
174 	const InstanceInterface&	vki					= context.getInstanceInterface();
175 
176 	for (viewFormat = (VkFormat)(VK_FORMAT_UNDEFINED + 1); viewFormat < VK_CORE_FORMAT_LAST; viewFormat = (VkFormat)(viewFormat + 1))
177 	{
178 		if (!isCompatibleFormat((VkFormat)viewFormat, params.imageFormat))
179 			continue;
180 
181 		if (func.getPhysicalDeviceImageFormatProperties(vki, context.getPhysicalDevice(), (VkFormat)viewFormat, params.tiling, params.usage, 0) == VK_SUCCESS)
182 		{
183 			expected = VK_SUCCESS;
184 			break;
185 		}
186 	}
187 
188 	// No compatible view format supports the tested usage.
189 	if (viewFormat == VK_CORE_FORMAT_LAST)
190 	{
191 		std::ostringstream error;
192 		error << "Usage is not supported by any compatible format";
193 		throw tcu::NotSupportedError(error.str().c_str());
194 	}
195 
196 	VkResult res = func.getPhysicalDeviceImageFormatProperties(vki, context.getPhysicalDevice(), params.imageFormat, params.tiling, params.usage, VK_IMAGE_CREATE_EXTENDED_USAGE_BIT | VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT);
197 
198 	if (res != expected)
199 	{
200 		std::ostringstream error;
201 		error << "Fail: view format " << getFormatStr(viewFormat);
202 		return tcu::TestStatus::fail(error.str().c_str());
203 	}
204 
205 	return tcu::TestStatus::pass("Pass");
206 }
207 
checkSupport(Context & context,TestParams params)208 void checkSupport (Context& context, TestParams params)
209 {
210 	context.requireDeviceFunctionality("VK_KHR_maintenance2");
211 
212 	VkFormatProperties formatProperties;
213 	context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), params.imageFormat, &formatProperties);
214 
215 	if (params.tiling == vk::VK_IMAGE_TILING_OPTIMAL && formatProperties.optimalTilingFeatures == 0)
216 		throw tcu::NotSupportedError("Format not supported");
217 
218 	if (params.tiling == vk::VK_IMAGE_TILING_LINEAR && formatProperties.linearTilingFeatures == 0)
219 		throw tcu::NotSupportedError("Format not supported");
220 
221 #ifndef CTS_USES_VULKANSC
222 	if (params.usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR ||
223 		params.usage & VK_IMAGE_USAGE_VIDEO_DECODE_SRC_BIT_KHR ||
224 		params.usage & VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR)
225 		context.requireDeviceFunctionality("VK_KHR_video_decode_queue");
226 
227 	if (params.usage & VK_IMAGE_USAGE_VIDEO_ENCODE_DST_BIT_KHR ||
228 		params.usage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR ||
229 		params.usage & VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR)
230 		context.requireDeviceFunctionality("VK_KHR_video_encode_queue");
231 
232 	if (params.usage & VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT)
233 		context.requireDeviceFunctionality("VK_EXT_fragment_density_map");
234 
235 	if (params.usage & VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR)
236 		context.requireDeviceFunctionality("VK_KHR_fragment_shading_rate");
237 
238 	if (params.usage & VK_IMAGE_USAGE_INVOCATION_MASK_BIT_HUAWEI)
239 		context.requireDeviceFunctionality("VK_HUAWEI_invocation_mask");
240 #endif // CTS_USES_VULKANSC
241 
242 }
243 
244 } // anonymous ns
245 
createImageExtendedUsageBitTests(tcu::TestContext & testCtx)246 tcu::TestCaseGroup* createImageExtendedUsageBitTests (tcu::TestContext& testCtx)
247 {
248 	de::MovePtr<tcu::TestCaseGroup> imageExtendedUsageBitTests(new tcu::TestCaseGroup(testCtx, "extended_usage_bit_compatibility", "VK_IMAGE_CREATE_EXTENDED_USAGE_BIT tests to check format compatibility"));
249 	de::MovePtr<tcu::TestCaseGroup> getPhysicalDeviceImageFormatPropertiesTests(new tcu::TestCaseGroup(testCtx, "image_format_properties", "vkGetPhysicalDeviceImageFormatProperties() tests"));
250 	de::MovePtr<tcu::TestCaseGroup> getPhysicalDeviceImageFormatProperties2Tests(new tcu::TestCaseGroup(testCtx, "image_format_properties2", "vkGetPhysicalDeviceImageFormatProperties2() tests"));
251 
252 	struct ImageUsageFlags
253 	{
254 		VkImageUsageFlags		usage;
255 		const char*				name;
256 	};
257 
258 	ImageUsageFlags				usages[]	=
259 	{
260 		{ VK_IMAGE_USAGE_TRANSFER_SRC_BIT,							"VK_IMAGE_USAGE_TRANSFER_SRC_BIT" },
261 		{ VK_IMAGE_USAGE_TRANSFER_DST_BIT,							"VK_IMAGE_USAGE_TRANSFER_DST_BIT" },
262 		{ VK_IMAGE_USAGE_SAMPLED_BIT,								"VK_IMAGE_USAGE_SAMPLED_BIT" },
263 		{ VK_IMAGE_USAGE_STORAGE_BIT,								"VK_IMAGE_USAGE_STORAGE_BIT" },
264 		{ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,						"VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT" },
265 		{ VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,				"VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT" },
266 		{ VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,					"VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT" },
267 		{ VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,						"VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT" },
268 #ifndef CTS_USES_VULKANSC
269 		{ VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR,					"VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR" },
270 		{ VK_IMAGE_USAGE_VIDEO_DECODE_SRC_BIT_KHR,					"VK_IMAGE_USAGE_VIDEO_DECODE_SRC_BIT_KHR" },
271 		{ VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR,					"VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR" },
272 		{ VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT,				"VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT" },
273 		{ VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR,	"VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR" },
274 		{ VK_IMAGE_USAGE_VIDEO_ENCODE_DST_BIT_KHR,					"VK_IMAGE_USAGE_VIDEO_ENCODE_DST_BIT_KHR" },
275 		{ VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR,					"VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR" },
276 		{ VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR,					"VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR" },
277 		{ VK_IMAGE_USAGE_INVOCATION_MASK_BIT_HUAWEI,				"VK_IMAGE_USAGE_INVOCATION_MASK_BIT_HUAWEI" },
278 		{ VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV,					"VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV" },
279 #endif // CTS_USES_VULKANSC
280 	};
281 
282 	struct TilingParams
283 	{
284 		VkImageTiling		tiling;
285 		const char*			name;
286 	};
287 	TilingParams			tiling[]	=
288 	{
289 		{ VK_IMAGE_TILING_LINEAR,	"linear"},
290 		{ VK_IMAGE_TILING_OPTIMAL,	"optimal"}
291 	};
292 
293 	for (VkFormat imageFormat = (VkFormat)(VK_FORMAT_UNDEFINED + 1); imageFormat < VK_CORE_FORMAT_LAST; imageFormat = (VkFormat)(imageFormat + 1))
294 	{
295 		for (unsigned tilingNdx = 0; tilingNdx < DE_LENGTH_OF_ARRAY(tiling); tilingNdx++)
296 		{
297 			for (unsigned usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(usages); usageNdx++)
298 			{
299 				struct TestParams params = { imageFormat, usages[usageNdx].usage, tiling[tilingNdx].tiling };
300 				std::ostringstream name;
301 				std::string usageName = usages[usageNdx].name;
302 				name << getFormatShortString(imageFormat) << "_" << tiling[tilingNdx].name << "_" << de::toLower(usageName.substr(15));
303 				addFunctionCase(getPhysicalDeviceImageFormatPropertiesTests.get(), name.str().c_str(), "Checks usage bit format compatibility among compatible image view formats", checkSupport, testExtendedUsageBitCompatiblity<PhysicalDeviceImageFormatProperties>, params);
304 				addFunctionCase(getPhysicalDeviceImageFormatProperties2Tests.get(), name.str().c_str(), "Checks usage bit format compatibility among compatible image view formats", checkSupport, testExtendedUsageBitCompatiblity<PhysicalDeviceImageFormatProperties2>, params);
305 			}
306 		}
307 	}
308 
309 	imageExtendedUsageBitTests->addChild(getPhysicalDeviceImageFormatPropertiesTests.release());
310 	imageExtendedUsageBitTests->addChild(getPhysicalDeviceImageFormatProperties2Tests.release());
311 	return imageExtendedUsageBitTests.release();
312 }
313 
314 } // image
315 } // vkt
316