1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2017 Khronos Group
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Checks vkGetPhysicalDevice*FormatProperties* API functions
22 *//*--------------------------------------------------------------------*/
23
24 #include "vkDefs.hpp"
25 #include "vkDeviceUtil.hpp"
26 #include "vkQueryUtil.hpp"
27 #include "vktTestCaseUtil.hpp"
28 #include "vktApiPhysicalDeviceFormatPropertiesMaint5Tests.hpp"
29
30 #include <algorithm>
31 #include <array>
32
33 using namespace vk;
34
35 namespace vkt
36 {
37 namespace api
38 {
39
40 namespace
41 {
42
43 constexpr uint32_t HAS_FORMAT_PARAM = 1u << 30;
44 constexpr uint32_t HAS_FLAGS_PARAM = 1u << 31;
45 enum class FuncIDs : uint32_t
46 {
47 DeviceFormatProps = 100u | HAS_FORMAT_PARAM,
48 DeviceFormatPropsSecond = 101u | HAS_FORMAT_PARAM,
49 DeviceImageFormatProps = 200u | HAS_FORMAT_PARAM | HAS_FLAGS_PARAM,
50 DeviceImageFormatPropsSecond = 201u | HAS_FORMAT_PARAM | HAS_FLAGS_PARAM,
51 DeviceSparseImageFormatProps = 300u | HAS_FORMAT_PARAM | HAS_FLAGS_PARAM,
52 DeviceSparseImageFormatPropsSecond = 301u | HAS_FORMAT_PARAM | HAS_FLAGS_PARAM,
53 };
54
55 struct TestParams
56 {
57 FuncIDs funcID;
58 };
59
60 class UnsupportedParametersMaintenance5FormatInstance : public TestInstance
61 {
62 public:
UnsupportedParametersMaintenance5FormatInstance(Context & context,const TestParams & params)63 UnsupportedParametersMaintenance5FormatInstance(Context &context, const TestParams ¶ms)
64 : TestInstance(context)
65 , m_params(params)
66 {
67 }
68 virtual ~UnsupportedParametersMaintenance5FormatInstance(void) override = default;
69 virtual tcu::TestStatus iterate(void) override;
70
71 protected:
72 TestParams m_params;
73 };
74
75 class UnsupportedParametersMaintenance5FlagsInstance : public TestInstance
76 {
77 public:
UnsupportedParametersMaintenance5FlagsInstance(Context & context,const TestParams & params)78 UnsupportedParametersMaintenance5FlagsInstance(Context &context, const TestParams ¶ms)
79 : TestInstance(context)
80 , m_params(params)
81 {
82 }
83 virtual ~UnsupportedParametersMaintenance5FlagsInstance(void) override = default;
84 virtual tcu::TestStatus iterate(void) override;
85
86 protected:
87 TestParams m_params;
88 };
89
90 class UnsupportedParametersMaintenance5TestCase : public TestCase
91 {
92 public:
UnsupportedParametersMaintenance5TestCase(tcu::TestContext & testContext,const std::string & name,const TestParams & params,bool testFormatOrFlags)93 UnsupportedParametersMaintenance5TestCase(tcu::TestContext &testContext, const std::string &name,
94 const TestParams ¶ms, bool testFormatOrFlags)
95 : TestCase(testContext, name)
96 , m_params(params)
97 , m_testFormatOrFlags(testFormatOrFlags)
98 {
99 }
100 virtual ~UnsupportedParametersMaintenance5TestCase(void) = default;
101 void checkSupport(Context &context) const override;
102 TestInstance *createInstance(Context &context) const override;
103
104 protected:
105 const TestParams m_params;
106 const bool m_testFormatOrFlags;
107 };
108
createInstance(Context & context) const109 TestInstance *UnsupportedParametersMaintenance5TestCase::createInstance(Context &context) const
110 {
111 if (m_testFormatOrFlags)
112 return new UnsupportedParametersMaintenance5FormatInstance(context, m_params);
113 return new UnsupportedParametersMaintenance5FlagsInstance(context, m_params);
114 }
115
checkSupport(Context & context) const116 void UnsupportedParametersMaintenance5TestCase::checkSupport(Context &context) const
117 {
118 context.requireDeviceFunctionality("VK_KHR_maintenance5");
119 if (context.getMaintenance5Features().maintenance5 != VK_TRUE)
120 {
121 TCU_THROW(NotSupportedError, "Maintenance5 feature is not supported by this implementation");
122 }
123 }
124
operator ==(const VkFormatProperties & l,const VkFormatProperties & r)125 bool operator==(const VkFormatProperties &l, const VkFormatProperties &r)
126 {
127 return l.bufferFeatures == r.bufferFeatures && l.linearTilingFeatures == r.linearTilingFeatures &&
128 l.optimalTilingFeatures == r.optimalTilingFeatures;
129 }
130
operator ==(const VkImageFormatProperties & l,const VkImageFormatProperties & r)131 bool operator==(const VkImageFormatProperties &l, const VkImageFormatProperties &r)
132 {
133 return l.maxMipLevels == r.maxMipLevels && l.maxArrayLayers == r.maxArrayLayers &&
134 l.sampleCounts == r.sampleCounts && l.maxResourceSize == r.maxResourceSize;
135 }
136
137 template <class StructType>
makeInvalidVulkanStructure(void * pNext=DE_NULL)138 StructType makeInvalidVulkanStructure(void *pNext = DE_NULL)
139 {
140 StructType s;
141 deMemset(&s, 0xFF, (size_t)(sizeof(s)));
142 s.sType = getStructureType<StructType>();
143 s.pNext = pNext;
144 return s;
145 }
146
iterate(void)147 tcu::TestStatus UnsupportedParametersMaintenance5FormatInstance::iterate(void)
148 {
149 const VkPhysicalDevice dev = m_context.getPhysicalDevice();
150 const InstanceInterface &inst = m_context.getInstanceInterface();
151 VkResult res = VK_ERROR_FORMAT_NOT_SUPPORTED;
152 uint32_t propsCount = 0;
153 const VkImageUsageFlags usage = VK_IMAGE_USAGE_STORAGE_BIT;
154 const VkImageType imageType = VK_IMAGE_TYPE_2D;
155 const VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL;
156 const VkImageCreateFlags createFlags = 0;
157 const VkSampleCountFlagBits sampling = VK_SAMPLE_COUNT_1_BIT;
158 VkFormatProperties2 props2 = initVulkanStructure();
159 VkFormatProperties &props1 = props2.formatProperties;
160 const VkFormatProperties invalidProps = makeInvalidVulkanStructure<VkFormatProperties2>().formatProperties;
161 const VkFormatProperties emptyProps{};
162 VkImageFormatProperties2 imageProps2 = initVulkanStructure();
163 VkImageFormatProperties &imageProps1 = imageProps2.imageFormatProperties;
164 const VkImageFormatProperties invalidImgProps =
165 makeInvalidVulkanStructure<VkImageFormatProperties2>().imageFormatProperties;
166 const VkImageFormatProperties emptyImgProps{};
167
168 VkPhysicalDeviceImageFormatInfo2 imageFormatInfo = initVulkanStructure();
169 imageFormatInfo.format = VK_FORMAT_UNDEFINED;
170 imageFormatInfo.type = imageType;
171 imageFormatInfo.tiling = tiling;
172 imageFormatInfo.usage = usage;
173 imageFormatInfo.flags = createFlags;
174
175 VkPhysicalDeviceSparseImageFormatInfo2 sparseFormatInfo = initVulkanStructure();
176 sparseFormatInfo.format = VK_FORMAT_UNDEFINED;
177 sparseFormatInfo.type = imageType;
178 sparseFormatInfo.samples = sampling;
179 sparseFormatInfo.usage = usage;
180 sparseFormatInfo.tiling = tiling;
181
182 const uint32_t n = 5;
183 std::array<bool, n> verdicts;
184
185 DE_ASSERT(uint32_t(m_params.funcID) & HAS_FORMAT_PARAM);
186
187 for (uint32_t i = 0; i < n; ++i)
188 {
189 const VkFormat format = VkFormat(VK_FORMAT_MAX_ENUM - i);
190
191 switch (m_params.funcID)
192 {
193 case FuncIDs::DeviceFormatProps:
194 props2 = makeInvalidVulkanStructure<VkFormatProperties2>();
195 inst.getPhysicalDeviceFormatProperties(dev, format, &props1);
196 verdicts[i] = (emptyProps == props1 || invalidProps == props1);
197 break;
198
199 case FuncIDs::DeviceFormatPropsSecond:
200 props2 = makeInvalidVulkanStructure<VkFormatProperties2>();
201 inst.getPhysicalDeviceFormatProperties2(dev, format, &props2);
202 verdicts[i] = (emptyProps == props1 || invalidProps == props1);
203 break;
204
205 case FuncIDs::DeviceImageFormatProps:
206 imageProps2 = makeInvalidVulkanStructure<VkImageFormatProperties2>();
207 res = inst.getPhysicalDeviceImageFormatProperties(dev, format, imageType, tiling, usage, createFlags,
208 &imageProps1);
209 verdicts[i] = (emptyImgProps == imageProps1 || invalidImgProps == imageProps1);
210 break;
211
212 case FuncIDs::DeviceImageFormatPropsSecond:
213 imageProps2 = makeInvalidVulkanStructure<VkImageFormatProperties2>();
214 imageFormatInfo.format = format;
215 res = inst.getPhysicalDeviceImageFormatProperties2(dev, &imageFormatInfo, &imageProps2);
216 verdicts[i] = (emptyImgProps == imageProps1 || invalidImgProps == imageProps1);
217 break;
218
219 case FuncIDs::DeviceSparseImageFormatProps:
220 propsCount = 0;
221 inst.getPhysicalDeviceSparseImageFormatProperties(dev, format, imageType, sampling, usage, tiling,
222 &propsCount, nullptr);
223 verdicts[i] = (0 == propsCount);
224 break;
225
226 case FuncIDs::DeviceSparseImageFormatPropsSecond:
227 propsCount = 0;
228 sparseFormatInfo.format = format;
229 inst.getPhysicalDeviceSparseImageFormatProperties2(dev, &sparseFormatInfo, &propsCount, nullptr);
230 verdicts[i] = (0 == propsCount);
231 break;
232
233 default:
234 DE_ASSERT(0);
235 break;
236 }
237 }
238
239 return (VK_ERROR_FORMAT_NOT_SUPPORTED == res &&
240 std::all_of(verdicts.begin(), verdicts.end(), [](bool x) { return x; })) ?
241 tcu::TestStatus::pass("") :
242 tcu::TestStatus::fail("");
243 }
244
iterate(void)245 tcu::TestStatus UnsupportedParametersMaintenance5FlagsInstance::iterate(void)
246 {
247 const VkPhysicalDevice dev = m_context.getPhysicalDevice();
248 const InstanceInterface &inst = m_context.getInstanceInterface();
249 VkResult res = VK_ERROR_FORMAT_NOT_SUPPORTED;
250 const VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
251 const VkImageType imageType = VK_IMAGE_TYPE_2D;
252 const VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL;
253 const VkImageCreateFlags createFlags = 0;
254 const VkSampleCountFlagBits sampling = VK_SAMPLE_COUNT_1_BIT;
255 uint32_t propsCount = 0;
256 VkImageFormatProperties2 imageProps2 = initVulkanStructure();
257 VkImageFormatProperties &imageProps1 = imageProps2.imageFormatProperties;
258 const VkImageFormatProperties invalidImgProps =
259 makeInvalidVulkanStructure<VkImageFormatProperties2>().imageFormatProperties;
260 const VkImageFormatProperties emptyImgProps{};
261
262 VkPhysicalDeviceImageFormatInfo2 imageFormatInfo = initVulkanStructure();
263 imageFormatInfo.format = format;
264 imageFormatInfo.type = imageType;
265 imageFormatInfo.tiling = tiling;
266 imageFormatInfo.usage = VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM;
267 imageFormatInfo.flags = createFlags;
268
269 VkPhysicalDeviceSparseImageFormatInfo2 sparseFormatInfo = initVulkanStructure();
270 sparseFormatInfo.format = format;
271 sparseFormatInfo.type = imageType;
272 sparseFormatInfo.samples = sampling;
273 sparseFormatInfo.usage = VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM;
274 sparseFormatInfo.tiling = tiling;
275
276 const uint32_t n = 5;
277 std::array<bool, n> verdicts;
278
279 DE_ASSERT(uint32_t(m_params.funcID) & HAS_FLAGS_PARAM);
280
281 for (uint32_t i = 0; i < n; ++i)
282 {
283 const VkImageUsageFlags usage = VkImageUsageFlags(VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM - i);
284
285 switch (m_params.funcID)
286 {
287 case FuncIDs::DeviceImageFormatProps:
288 imageProps2 = makeInvalidVulkanStructure<VkImageFormatProperties2>();
289 res = inst.getPhysicalDeviceImageFormatProperties(dev, format, imageType, tiling, usage, createFlags,
290 &imageProps1);
291 verdicts[i] = (emptyImgProps == imageProps1 || invalidImgProps == imageProps1);
292 break;
293
294 case FuncIDs::DeviceImageFormatPropsSecond:
295 imageProps2 = makeInvalidVulkanStructure<VkImageFormatProperties2>();
296 imageFormatInfo.usage = usage;
297 res = inst.getPhysicalDeviceImageFormatProperties2(dev, &imageFormatInfo, &imageProps2);
298 verdicts[i] = (emptyImgProps == imageProps1 || invalidImgProps == imageProps1);
299 break;
300
301 case FuncIDs::DeviceSparseImageFormatProps:
302 propsCount = 0;
303 inst.getPhysicalDeviceSparseImageFormatProperties(dev, format, imageType, sampling, usage, tiling,
304 &propsCount, nullptr);
305 /*
306 * Some of the Implementations ignore wrong flags, so at this point we consider the test passed.
307 */
308 verdicts[i] = true;
309 break;
310
311 case FuncIDs::DeviceSparseImageFormatPropsSecond:
312 propsCount = 0;
313 sparseFormatInfo.usage = usage;
314 inst.getPhysicalDeviceSparseImageFormatProperties2(dev, &sparseFormatInfo, &propsCount, nullptr);
315 /*
316 * Some of the Implementations ignore wrong formats, so at this point we consider the test passed.
317 */
318 verdicts[i] = true;
319 break;
320
321 default:
322 DE_ASSERT(0);
323 break;
324 }
325 }
326
327 return (VK_ERROR_FORMAT_NOT_SUPPORTED == res &&
328 std::all_of(verdicts.begin(), verdicts.end(), [](bool x) { return x; })) ?
329 tcu::TestStatus::pass("") :
330 tcu::TestStatus::fail("");
331 }
332
333 } // unnamed namespace
334
createMaintenance5Tests(tcu::TestContext & testCtx)335 tcu::TestCaseGroup *createMaintenance5Tests(tcu::TestContext &testCtx)
336 {
337 const std::pair<std::string, FuncIDs> funcs[]{
338 {"device_format_props", FuncIDs::DeviceFormatProps},
339 {"device_format_props2", FuncIDs::DeviceFormatPropsSecond},
340 {"image_format_props", FuncIDs::DeviceImageFormatProps},
341 {"image_format_props2", FuncIDs::DeviceImageFormatPropsSecond},
342 {"sparse_image_format_props", FuncIDs::DeviceSparseImageFormatProps},
343 {"sparse_image_format_props2", FuncIDs::DeviceSparseImageFormatPropsSecond}};
344 // Checks vkGetPhysicalDevice*FormatProperties* API functions
345 de::MovePtr<tcu::TestCaseGroup> gRoot(new tcu::TestCaseGroup(testCtx, "maintenance5"));
346 de::MovePtr<tcu::TestCaseGroup> gFormat(new tcu::TestCaseGroup(testCtx, "format"));
347 de::MovePtr<tcu::TestCaseGroup> gFlags(new tcu::TestCaseGroup(testCtx, "flags"));
348 for (const auto &func : funcs)
349 {
350 TestParams p;
351 p.funcID = func.second;
352
353 if (uint32_t(func.second) & HAS_FORMAT_PARAM)
354 gFormat->addChild(new UnsupportedParametersMaintenance5TestCase(testCtx, func.first, p, true));
355 if (uint32_t(func.second) & HAS_FLAGS_PARAM)
356 gFlags->addChild(new UnsupportedParametersMaintenance5TestCase(testCtx, func.first, p, false));
357 }
358 gRoot->addChild(gFormat.release());
359 gRoot->addChild(gFlags.release());
360 return gRoot.release();
361 }
362
363 } // namespace api
364 } // namespace vkt
365