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 API Maintenance3 Check test - checks structs and function from VK_KHR_maintenance3
22 *//*--------------------------------------------------------------------*/
23
24 #include "tcuTestLog.hpp"
25
26 #include "vkQueryUtil.hpp"
27
28 #include "vktApiMaintenance3Check.hpp"
29 #include "vktTestCase.hpp"
30
31 #define VK_DESCRIPTOR_TYPE_LAST (VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT + 1)
32
33 using namespace vk;
34
35 namespace vkt
36 {
37
38 namespace api
39 {
40
41 namespace
42 {
43 using ::std::string;
44 using ::std::vector;
45
46 typedef vk::VkPhysicalDeviceProperties DevProp1;
47 typedef vk::VkPhysicalDeviceProperties2 DevProp2;
48 typedef vk::VkPhysicalDeviceMaintenance3Properties MainDevProp3;
49
50
checkSupport(const Context & m_context)51 void checkSupport (const Context& m_context)
52 {
53 const vector<string> extensions = m_context.getDeviceExtensions();
54
55 if (!isDeviceExtensionSupported(m_context.getUsedApiVersion(), m_context.getDeviceExtensions(), "VK_KHR_maintenance3"))
56 TCU_THROW(NotSupportedError, "VK_KHR_maintenance3 extension is not supported");
57 }
58
59 class Maintenance3StructTestInstance : public TestInstance
60 {
61 public:
Maintenance3StructTestInstance(Context & ctx)62 Maintenance3StructTestInstance (Context& ctx)
63 : TestInstance (ctx)
64 {}
iterate(void)65 virtual tcu::TestStatus iterate (void)
66 {
67 checkSupport(m_context);
68 tcu::TestLog& log = m_context.getTestContext().getLog();
69
70 // these variables are equal to minimal values for maxMemoryAllocationSize and maxPerSetDescriptors
71 const deUint32 maxMemoryAllocationSize = 1073741824u;
72 const deUint32 maxDescriptorsInSet = 1024u;
73
74 // set values to be a bit smaller than required minimum values
75 MainDevProp3 mainProp3 =
76 {
77 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES, //VkStructureType sType;
78 DE_NULL, //void* pNext;
79 maxDescriptorsInSet - 1u, //deUint32 maxPerSetDescriptors;
80 maxMemoryAllocationSize - 1u //VkDeviceSize maxMemoryAllocationSize;
81 };
82
83 DevProp2 prop2;
84 deMemset(&prop2, 0, sizeof(prop2)); // zero the structure
85 prop2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
86 prop2.pNext = &mainProp3;
87
88 m_context.getInstanceInterface().getPhysicalDeviceProperties2(m_context.getPhysicalDevice(), &prop2);
89
90 if (mainProp3.maxMemoryAllocationSize < maxMemoryAllocationSize)
91 return tcu::TestStatus::fail("Fail");
92
93 if (mainProp3.maxPerSetDescriptors < maxDescriptorsInSet)
94 return tcu::TestStatus::fail("Fail");
95
96 log << tcu::TestLog::Message << "maxMemoryAllocationSize: " << mainProp3.maxMemoryAllocationSize << tcu::TestLog::EndMessage;
97 log << tcu::TestLog::Message << "maxPerSetDescriptors: " << mainProp3.maxPerSetDescriptors << tcu::TestLog::EndMessage;
98 return tcu::TestStatus::pass("Pass");
99 }
100 };
101
102 class Maintenance3StructTestCase : public TestCase
103 {
104 public:
Maintenance3StructTestCase(tcu::TestContext & testCtx)105 Maintenance3StructTestCase (tcu::TestContext& testCtx)
106 : TestCase(testCtx, "maintenance3_properties", "tests VkPhysicalDeviceMaintenance3Properties struct")
107 {}
108
~Maintenance3StructTestCase(void)109 virtual ~Maintenance3StructTestCase (void)
110 {}
createInstance(Context & ctx) const111 virtual TestInstance* createInstance (Context& ctx) const
112 {
113 return new Maintenance3StructTestInstance(ctx);
114 }
115
116 private:
117 };
118
119 class Maintenance3DescriptorTestInstance : public TestInstance
120 {
121 public:
Maintenance3DescriptorTestInstance(Context & ctx)122 Maintenance3DescriptorTestInstance (Context& ctx)
123 : TestInstance(ctx)
124 {}
iterate(void)125 virtual tcu::TestStatus iterate (void)
126 {
127 checkSupport(m_context);
128
129 // these variables are equal to minimal values for maxMemoryAllocationSize and maxPerSetDescriptors
130 const deUint32 maxMemoryAllocationSize = 1073741824u;
131 const deUint32 maxDescriptorsInSet = 1024u;
132
133 MainDevProp3 mainProp3 =
134 {
135 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES, //VkStructureType sType;
136 DE_NULL, //void* pNext;
137 maxDescriptorsInSet, //deUint32 maxPerSetDescriptors;
138 maxMemoryAllocationSize //VkDeviceSize maxMemoryAllocationSize;
139 };
140
141 DevProp2 prop2 =
142 {
143 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, //VkStructureType sType;
144 &mainProp3, //void* pNext;
145 VkPhysicalDeviceProperties() //VkPhysicalDeviceProperties properties;
146 };
147
148 DevProp1 prop1;
149
150 m_context.getInstanceInterface().getPhysicalDeviceProperties(m_context.getPhysicalDevice(), &prop1);
151 m_context.getInstanceInterface().getPhysicalDeviceProperties2(m_context.getPhysicalDevice(), &prop2);
152
153 // setup for descriptors sets
154 VkDescriptorSetLayoutBinding descriptorSetLayoutBinding[VK_DESCRIPTOR_TYPE_LAST];
155
156 for (deUint32 ndx = 0u; ndx < VK_DESCRIPTOR_TYPE_LAST; ++ndx)
157 {
158 descriptorSetLayoutBinding[ndx].binding = ndx;
159 descriptorSetLayoutBinding[ndx].descriptorType = static_cast<VkDescriptorType>(ndx);
160 descriptorSetLayoutBinding[ndx].descriptorCount = mainProp3.maxPerSetDescriptors;
161 descriptorSetLayoutBinding[ndx].stageFlags = VK_SHADER_STAGE_ALL;
162 descriptorSetLayoutBinding[ndx].pImmutableSamplers = DE_NULL;
163 }
164
165 // VkDescriptorSetLayoutCreateInfo setup
166 vk::VkDescriptorSetLayoutCreateInfo pCreateInfo =
167 {
168 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, //VkStructureType sType;
169 DE_NULL, //const void* pNext;
170 0u, //VkDescriptorSetLayoutCreateFlags flags;
171 1u, //deUint32 bindingCount;
172 DE_NULL //const VkDescriptorSetLayoutBinding* pBindings;
173 };
174
175 // VkDescriptorSetLayoutSupport setup
176 vk::VkDescriptorSetLayoutSupport pSupport =
177 {
178 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT, //VkStructureType sType;
179 DE_NULL, //void* pNext;
180 VK_FALSE //VkBool32 supported;
181 };
182
183 // check for single descriptors
184 for (deUint32 ndx = 0u; ndx < VK_DESCRIPTOR_TYPE_LAST; ++ndx)
185 {
186 pCreateInfo.pBindings = &descriptorSetLayoutBinding[ndx];
187 m_context.getDeviceInterface().getDescriptorSetLayoutSupport(m_context.getDevice(), &pCreateInfo, &pSupport);
188
189 if(extraLimitCheck(descriptorSetLayoutBinding, ndx, pCreateInfo.bindingCount, prop1))
190 {
191 if (pSupport.supported == VK_FALSE)
192 return tcu::TestStatus::fail("fail");
193 }
194 }
195
196 // check for accumulated descriptors (all eleven types)
197
198 pCreateInfo.pBindings = &descriptorSetLayoutBinding[0u];
199 pCreateInfo.bindingCount = static_cast<deUint32>(VK_DESCRIPTOR_TYPE_LAST);
200
201 deUint32 fraction = mainProp3.maxPerSetDescriptors / static_cast<deUint32>(VK_DESCRIPTOR_TYPE_LAST);
202 deUint32 rest = mainProp3.maxPerSetDescriptors % static_cast<deUint32>(VK_DESCRIPTOR_TYPE_LAST);
203
204 for (deUint32 ndx = 0u; ndx < VK_DESCRIPTOR_TYPE_LAST; ++ndx)
205 descriptorSetLayoutBinding[ndx].descriptorCount = fraction;
206 descriptorSetLayoutBinding[0u].descriptorCount += rest;
207
208 m_context.getDeviceInterface().getDescriptorSetLayoutSupport(m_context.getDevice(), &pCreateInfo, &pSupport);
209
210 if (extraLimitCheck(descriptorSetLayoutBinding, 0u, pCreateInfo.bindingCount, prop1))
211 {
212 if (pSupport.supported == VK_FALSE)
213 return tcu::TestStatus::fail("fail");
214 }
215
216 return tcu::TestStatus::pass("Pass");
217 }
218
219 private:
extraLimitCheck(const VkDescriptorSetLayoutBinding * descriptorSetLayoutBinding,const deUint32 & curNdx,const deUint32 & size,const DevProp1 & prop1)220 bool extraLimitCheck (const VkDescriptorSetLayoutBinding* descriptorSetLayoutBinding, const deUint32& curNdx, const deUint32& size, const DevProp1& prop1)
221 {
222 deUint32 maxPerStageDescriptorSamplers = 0u;
223 deUint32 maxPerStageDescriptorUniformBuffers = 0u;
224 deUint32 maxPerStageDescriptorStorageBuffers = 0u;
225 deUint32 maxPerStageDescriptorSampledImages = 0u;
226 deUint32 maxPerStageDescriptorStorageImages = 0u;
227 deUint32 maxPerStageDescriptorInputAttachments = 0u;
228
229 for(deUint32 ndx = curNdx; ndx < curNdx + size; ++ndx)
230 {
231 if ((descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) ||
232 (descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER))
233 maxPerStageDescriptorSamplers += descriptorSetLayoutBinding->descriptorCount;
234
235 if ((descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) ||
236 (descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC))
237 maxPerStageDescriptorUniformBuffers += descriptorSetLayoutBinding->descriptorCount;
238
239 if ((descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) ||
240 (descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC))
241 maxPerStageDescriptorStorageBuffers += descriptorSetLayoutBinding->descriptorCount;
242
243 if ((descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) ||
244 (descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) ||
245 (descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER))
246 maxPerStageDescriptorSampledImages += descriptorSetLayoutBinding->descriptorCount;
247
248 if ((descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ||
249 (descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER))
250 maxPerStageDescriptorStorageImages += descriptorSetLayoutBinding->descriptorCount;
251
252 if (descriptorSetLayoutBinding[ndx].descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)
253 maxPerStageDescriptorInputAttachments += descriptorSetLayoutBinding->descriptorCount;
254 }
255
256 if (prop1.limits.maxPerStageDescriptorSamplers < maxPerStageDescriptorSamplers)
257 return false;
258 if (prop1.limits.maxPerStageDescriptorUniformBuffers < maxPerStageDescriptorUniformBuffers)
259 return false;
260 if (prop1.limits.maxPerStageDescriptorStorageBuffers < maxPerStageDescriptorStorageBuffers)
261 return false;
262 if (prop1.limits.maxPerStageDescriptorSampledImages < maxPerStageDescriptorSampledImages)
263 return false;
264 if (prop1.limits.maxPerStageDescriptorStorageImages < maxPerStageDescriptorStorageImages)
265 return false;
266 if (prop1.limits.maxPerStageDescriptorInputAttachments < maxPerStageDescriptorInputAttachments)
267 return false;
268
269 return true;
270 }
271 };
272
273 class Maintenance3DescriptorTestCase : public TestCase
274 {
275
276 public:
Maintenance3DescriptorTestCase(tcu::TestContext & testCtx)277 Maintenance3DescriptorTestCase (tcu::TestContext& testCtx)
278 : TestCase(testCtx, "descriptor_set", "tests vkGetDescriptorSetLayoutSupport struct")
279 {}
~Maintenance3DescriptorTestCase(void)280 virtual ~Maintenance3DescriptorTestCase (void)
281 {}
createInstance(Context & ctx) const282 virtual TestInstance* createInstance (Context& ctx) const
283 {
284 return new Maintenance3DescriptorTestInstance(ctx);
285 }
286
287 private:
288 };
289
290 } // anonymous
291
createMaintenance3Tests(tcu::TestContext & testCtx)292 tcu::TestCaseGroup* createMaintenance3Tests (tcu::TestContext& testCtx)
293 {
294 de::MovePtr<tcu::TestCaseGroup> main3Tests(new tcu::TestCaseGroup(testCtx, "maintenance3_check", "Maintenance3 Tests"));
295 main3Tests->addChild(new Maintenance3StructTestCase(testCtx));
296 main3Tests->addChild(new Maintenance3DescriptorTestCase(testCtx));
297
298 return main3Tests.release();
299 }
300
301 } // api
302 } // vkt
303