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