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 deUint32 HAS_FORMAT_PARAM = 1u << 30;
44 constexpr deUint32 HAS_FLAGS_PARAM = 1u << 31;
45 enum class FuncIDs : deUint32
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& params)
64 : TestInstance (context)
65 , m_params (params) {}
66 virtual ~UnsupportedParametersMaintenance5FormatInstance (void) override = default;
67 virtual tcu::TestStatus iterate (void) override;
68 protected:
69 TestParams m_params;
70 };
71
72 class UnsupportedParametersMaintenance5FlagsInstance : public TestInstance
73 {
74 public:
UnsupportedParametersMaintenance5FlagsInstance(Context & context,const TestParams & params)75 UnsupportedParametersMaintenance5FlagsInstance (Context& context, const TestParams& params)
76 : TestInstance (context)
77 , m_params (params) {}
78 virtual ~UnsupportedParametersMaintenance5FlagsInstance (void) override = default;
79 virtual tcu::TestStatus iterate (void) override;
80 protected:
81 TestParams m_params;
82 };
83
84 class UnsupportedParametersMaintenance5TestCase : public TestCase
85 {
86 public:
UnsupportedParametersMaintenance5TestCase(tcu::TestContext & testContext,const std::string & name,const TestParams & params,bool testFormatOrFlags)87 UnsupportedParametersMaintenance5TestCase (tcu::TestContext& testContext,
88 const std::string& name,
89 const TestParams& params,
90 bool testFormatOrFlags)
91 : TestCase (testContext, name)
92 , m_params (params)
93 , m_testFormatOrFlags (testFormatOrFlags) { }
94 virtual ~UnsupportedParametersMaintenance5TestCase (void) = default;
95 void checkSupport (Context& context) const override;
96 TestInstance* createInstance (Context& context) const override;
97
98 protected:
99 const TestParams m_params;
100 const bool m_testFormatOrFlags;
101 };
102
createInstance(Context & context) const103 TestInstance* UnsupportedParametersMaintenance5TestCase::createInstance (Context& context) const
104 {
105 if (m_testFormatOrFlags)
106 return new UnsupportedParametersMaintenance5FormatInstance(context, m_params);
107 return new UnsupportedParametersMaintenance5FlagsInstance(context, m_params);
108 }
109
checkSupport(Context & context) const110 void UnsupportedParametersMaintenance5TestCase::checkSupport (Context &context) const
111 {
112 context.requireDeviceFunctionality("VK_KHR_maintenance5");
113 if (context.getMaintenance5Features().maintenance5 != VK_TRUE)
114 {
115 TCU_THROW(NotSupportedError, "Maintenance5 feature is not supported by this implementation");
116 }
117 }
118
operator ==(const VkFormatProperties & l,const VkFormatProperties & r)119 bool operator==(const VkFormatProperties& l, const VkFormatProperties& r)
120 {
121 return l.bufferFeatures == r.bufferFeatures
122 && l.linearTilingFeatures == r.linearTilingFeatures
123 && l.optimalTilingFeatures == r.optimalTilingFeatures;
124 }
125
operator ==(const VkImageFormatProperties & l,const VkImageFormatProperties & r)126 bool operator==(const VkImageFormatProperties& l, const VkImageFormatProperties& r)
127 {
128 return l.maxMipLevels == r.maxMipLevels
129 && l.maxArrayLayers == r.maxArrayLayers
130 && l.sampleCounts == r.sampleCounts
131 && l.maxResourceSize == r.maxResourceSize;
132 }
133
134 template<class StructType>
makeInvalidVulkanStructure(void * pNext=DE_NULL)135 StructType makeInvalidVulkanStructure (void* pNext = DE_NULL)
136 {
137 StructType s;
138 deMemset(&s, 0xFF, (size_t)(sizeof(s)));
139 s.sType = getStructureType<StructType>();
140 s.pNext = pNext;
141 return s;
142 }
143
iterate(void)144 tcu::TestStatus UnsupportedParametersMaintenance5FormatInstance::iterate (void)
145 {
146 const VkPhysicalDevice dev = m_context.getPhysicalDevice();
147 const InstanceInterface& inst = m_context.getInstanceInterface();
148 VkResult res = VK_ERROR_FORMAT_NOT_SUPPORTED;
149 uint32_t propsCount = 0;
150 const VkImageUsageFlags usage = VK_IMAGE_USAGE_STORAGE_BIT;
151 const VkImageType imageType = VK_IMAGE_TYPE_2D;
152 const VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL;
153 const VkImageCreateFlags createFlags = 0;
154 const VkSampleCountFlagBits sampling = VK_SAMPLE_COUNT_1_BIT;
155 VkFormatProperties2 props2 = initVulkanStructure();
156 VkFormatProperties& props1 = props2.formatProperties;
157 const VkFormatProperties invalidProps = makeInvalidVulkanStructure<VkFormatProperties2>().formatProperties;
158 const VkFormatProperties emptyProps {};
159 VkImageFormatProperties2 imageProps2 = initVulkanStructure();
160 VkImageFormatProperties& imageProps1 = imageProps2.imageFormatProperties;
161 const VkImageFormatProperties invalidImgProps = makeInvalidVulkanStructure<VkImageFormatProperties2>().imageFormatProperties;
162 const VkImageFormatProperties emptyImgProps {};
163
164 VkPhysicalDeviceImageFormatInfo2 imageFormatInfo = initVulkanStructure();
165 imageFormatInfo.format = VK_FORMAT_UNDEFINED;
166 imageFormatInfo.type = imageType;
167 imageFormatInfo.tiling = tiling;
168 imageFormatInfo.usage = usage;
169 imageFormatInfo.flags = createFlags;
170
171 VkPhysicalDeviceSparseImageFormatInfo2 sparseFormatInfo = initVulkanStructure();
172 sparseFormatInfo.format = VK_FORMAT_UNDEFINED;
173 sparseFormatInfo.type = imageType;
174 sparseFormatInfo.samples = sampling;
175 sparseFormatInfo.usage = usage;
176 sparseFormatInfo.tiling = tiling;
177
178 const deUint32 n = 5;
179 std::array<bool, n> verdicts;
180
181 DE_ASSERT(deUint32(m_params.funcID) & HAS_FORMAT_PARAM);
182
183 for (deUint32 i = 0; i < n; ++i)
184 {
185 const VkFormat format = VkFormat(VK_FORMAT_MAX_ENUM - i);
186
187 switch (m_params.funcID)
188 {
189 case FuncIDs::DeviceFormatProps:
190 props2 = makeInvalidVulkanStructure<VkFormatProperties2>();
191 inst.getPhysicalDeviceFormatProperties(dev, format, &props1);
192 verdicts[i] = (emptyProps == props1 || invalidProps == props1);
193 break;
194
195 case FuncIDs::DeviceFormatPropsSecond:
196 props2 = makeInvalidVulkanStructure<VkFormatProperties2>();
197 inst.getPhysicalDeviceFormatProperties2(dev, format, &props2);
198 verdicts[i] = (emptyProps == props1 || invalidProps == props1);
199 break;
200
201 case FuncIDs::DeviceImageFormatProps:
202 imageProps2 = makeInvalidVulkanStructure<VkImageFormatProperties2>();
203 res = inst.getPhysicalDeviceImageFormatProperties(dev, format, imageType, tiling, usage, createFlags, &imageProps1);
204 verdicts[i] = (emptyImgProps == imageProps1 || invalidImgProps == imageProps1);
205 break;
206
207 case FuncIDs::DeviceImageFormatPropsSecond:
208 imageProps2 = makeInvalidVulkanStructure<VkImageFormatProperties2>();
209 imageFormatInfo.format = format;
210 res = inst.getPhysicalDeviceImageFormatProperties2(dev, &imageFormatInfo, &imageProps2);
211 verdicts[i] = (emptyImgProps == imageProps1 || invalidImgProps == imageProps1);
212 break;
213
214 case FuncIDs::DeviceSparseImageFormatProps:
215 propsCount = 0;
216 inst.getPhysicalDeviceSparseImageFormatProperties(dev, format, imageType, sampling, usage, tiling, &propsCount, nullptr);
217 verdicts[i] = (0 == propsCount);
218 break;
219
220 case FuncIDs::DeviceSparseImageFormatPropsSecond:
221 propsCount = 0;
222 sparseFormatInfo.format = format;
223 inst.getPhysicalDeviceSparseImageFormatProperties2(dev, &sparseFormatInfo, &propsCount, nullptr);
224 verdicts[i] = (0 == propsCount);
225 break;
226
227 default: DE_ASSERT(0); break;
228 }
229 }
230
231 return (VK_ERROR_FORMAT_NOT_SUPPORTED == res && std::all_of(verdicts.begin(), verdicts.end(), [](bool x){ return x; }))
232 ? tcu::TestStatus::pass("")
233 : tcu::TestStatus::fail("");
234 }
235
iterate(void)236 tcu::TestStatus UnsupportedParametersMaintenance5FlagsInstance::iterate (void)
237 {
238 const VkPhysicalDevice dev = m_context.getPhysicalDevice();
239 const InstanceInterface& inst = m_context.getInstanceInterface();
240 VkResult res = VK_ERROR_FORMAT_NOT_SUPPORTED;
241 const VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
242 const VkImageType imageType = VK_IMAGE_TYPE_2D;
243 const VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL;
244 const VkImageCreateFlags createFlags = 0;
245 const VkSampleCountFlagBits sampling = VK_SAMPLE_COUNT_1_BIT;
246 uint32_t propsCount = 0;
247 VkImageFormatProperties2 imageProps2 = initVulkanStructure();
248 VkImageFormatProperties& imageProps1 = imageProps2.imageFormatProperties;
249 const VkImageFormatProperties invalidImgProps = makeInvalidVulkanStructure<VkImageFormatProperties2>().imageFormatProperties;
250 const VkImageFormatProperties emptyImgProps {};
251
252 VkPhysicalDeviceImageFormatInfo2 imageFormatInfo = initVulkanStructure();
253 imageFormatInfo.format = format;
254 imageFormatInfo.type = imageType;
255 imageFormatInfo.tiling = tiling;
256 imageFormatInfo.usage = VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM;
257 imageFormatInfo.flags = createFlags;
258
259 VkPhysicalDeviceSparseImageFormatInfo2 sparseFormatInfo = initVulkanStructure();
260 sparseFormatInfo.format = format;
261 sparseFormatInfo.type = imageType;
262 sparseFormatInfo.samples = sampling;
263 sparseFormatInfo.usage = VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM;
264 sparseFormatInfo.tiling = tiling;
265
266 const deUint32 n = 5;
267 std::array<bool, n> verdicts;
268
269 DE_ASSERT(deUint32(m_params.funcID) & HAS_FLAGS_PARAM);
270
271 for (deUint32 i = 0; i < n; ++i)
272 {
273 const VkImageUsageFlags usage = VkImageUsageFlags(VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM - i);
274
275 switch (m_params.funcID)
276 {
277 case FuncIDs::DeviceImageFormatProps:
278 imageProps2 = makeInvalidVulkanStructure<VkImageFormatProperties2>();
279 res = inst.getPhysicalDeviceImageFormatProperties(dev, format, imageType, tiling, usage, createFlags, &imageProps1);
280 verdicts[i] = (emptyImgProps == imageProps1 || invalidImgProps == imageProps1);
281 break;
282
283 case FuncIDs::DeviceImageFormatPropsSecond:
284 imageProps2 = makeInvalidVulkanStructure<VkImageFormatProperties2>();
285 imageFormatInfo.usage = usage;
286 res = inst.getPhysicalDeviceImageFormatProperties2(dev, &imageFormatInfo, &imageProps2);
287 verdicts[i] = (emptyImgProps == imageProps1 || invalidImgProps == imageProps1);
288 break;
289
290 case FuncIDs::DeviceSparseImageFormatProps:
291 propsCount = 0;
292 inst.getPhysicalDeviceSparseImageFormatProperties(dev, format, imageType, sampling, usage, tiling, &propsCount, nullptr);
293 /*
294 * Some of the Implementations ignore wrong flags, so at this point we consider the test passed.
295 */
296 verdicts[i] = true;
297 break;
298
299 case FuncIDs::DeviceSparseImageFormatPropsSecond:
300 propsCount = 0;
301 sparseFormatInfo.usage = usage;
302 inst.getPhysicalDeviceSparseImageFormatProperties2(dev, &sparseFormatInfo, &propsCount, nullptr);
303 /*
304 * Some of the Implementations ignore wrong formats, so at this point we consider the test passed.
305 */
306 verdicts[i] = true;
307 break;
308
309 default: DE_ASSERT(0); break;
310 }
311 }
312
313 return (VK_ERROR_FORMAT_NOT_SUPPORTED == res && std::all_of(verdicts.begin(), verdicts.end(), [](bool x){ return x; }))
314 ? tcu::TestStatus::pass("")
315 : tcu::TestStatus::fail("");
316 }
317
318 } // unnamed namespace
319
createMaintenance5Tests(tcu::TestContext & testCtx)320 tcu::TestCaseGroup* createMaintenance5Tests (tcu::TestContext& testCtx)
321 {
322 const std::pair<std::string, FuncIDs> funcs[]
323 {
324 { "device_format_props", FuncIDs::DeviceFormatProps },
325 { "device_format_props2", FuncIDs::DeviceFormatPropsSecond },
326 { "image_format_props", FuncIDs::DeviceImageFormatProps },
327 { "image_format_props2", FuncIDs::DeviceImageFormatPropsSecond },
328 { "sparse_image_format_props", FuncIDs::DeviceSparseImageFormatProps },
329 { "sparse_image_format_props2", FuncIDs::DeviceSparseImageFormatPropsSecond }
330 };
331 // Checks vkGetPhysicalDevice*FormatProperties* API functions
332 de::MovePtr<tcu::TestCaseGroup> gRoot(new tcu::TestCaseGroup(testCtx, "maintenance5"));
333 de::MovePtr<tcu::TestCaseGroup> gFormat(new tcu::TestCaseGroup(testCtx, "format", ""));
334 de::MovePtr<tcu::TestCaseGroup> gFlags(new tcu::TestCaseGroup(testCtx, "flags", ""));
335 for (const auto& func : funcs)
336 {
337 TestParams p;
338 p.funcID = func.second;
339
340 if (deUint32(func.second) & HAS_FORMAT_PARAM)
341 gFormat->addChild(new UnsupportedParametersMaintenance5TestCase(testCtx, func.first, p, true));
342 if (deUint32(func.second) & HAS_FLAGS_PARAM)
343 gFlags->addChild(new UnsupportedParametersMaintenance5TestCase(testCtx, func.first, p, false));
344 }
345 gRoot->addChild(gFormat.release());
346 gRoot->addChild(gFlags.release());
347 return gRoot.release();
348 }
349
350 } // api
351 } // vkt
352