1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2023 LunarG, Inc.
6 * Copyright (c) 2023 Nintendo
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 Shader Object API Tests
23 *//*--------------------------------------------------------------------*/
24
25 #include "tcuDefs.hpp"
26 #include "tcuTestCase.hpp"
27 #include "deUniquePtr.hpp"
28 #include "tcuTestCase.hpp"
29 #include "vktTestCase.hpp"
30 #include "vkQueryUtil.hpp"
31 #include "vktCustomInstancesDevices.hpp"
32 #include "tcuCommandLine.hpp"
33
34 namespace vkt
35 {
36 namespace ShaderObject
37 {
38
39 namespace
40 {
41
42 enum ShaderObjectApiTest
43 {
44 EXT_DISCARD_RECTANGLES = 0,
45 NV_SCISSOR_EXCLUSIVE,
46 KHR_DYNAMIC_RENDERING,
47 SHADER_BINARY_UUID,
48 };
49
50 class ShaderObjectApiInstance : public vkt::TestInstance
51 {
52 public:
ShaderObjectApiInstance(Context & context)53 ShaderObjectApiInstance(Context &context) : vkt::TestInstance(context)
54 {
55 }
~ShaderObjectApiInstance(void)56 virtual ~ShaderObjectApiInstance(void)
57 {
58 }
59
60 tcu::TestStatus iterate(void) override;
61 };
62
iterate(void)63 tcu::TestStatus ShaderObjectApiInstance::iterate(void)
64 {
65 const vk::InstanceInterface &vki = m_context.getInstanceInterface();
66 const vk::PlatformInterface &vkp = m_context.getPlatformInterface();
67 const auto instance = m_context.getInstance();
68 const auto physicalDevice = m_context.getPhysicalDevice();
69 vk::VkPhysicalDeviceFeatures2 deviceFeatures = vk::initVulkanStructure();
70
71 vki.getPhysicalDeviceFeatures2(physicalDevice, &deviceFeatures);
72
73 const auto queuePriority = 1.0f;
74 const vk::VkDeviceQueueCreateInfo queueInfo{
75 vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // VkStructureType sType;
76 nullptr, // const void* pNext;
77 0u, // VkDeviceQueueCreateFlags flags;
78 m_context.getUniversalQueueFamilyIndex(), // uint32_t queueFamilyIndex;
79 1u, // uint32_t queueCount;
80 &queuePriority, // const float* pQueuePriorities;
81 };
82
83 std::vector<const char *> extensions = {"VK_EXT_shader_object"};
84
85 vk::VkPhysicalDeviceShaderObjectFeaturesEXT shaderObjectFeaturesEXT = vk::initVulkanStructure();
86 vk::VkPhysicalDeviceFeatures2 features2 = vk::initVulkanStructure(&shaderObjectFeaturesEXT);
87 vki.getPhysicalDeviceFeatures2(physicalDevice, &features2);
88
89 const vk::VkDeviceCreateInfo deviceInfo{
90 vk::VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // VkStructureType sType;
91 &features2, // const void* pNext;
92 0u, // VkDeviceCreateFlags flags;
93 1u, // uint32_t queueCreateInfoCount;
94 &queueInfo, // const VkDeviceQueueCreateInfo* pQueueCreateInfos;
95 0u, // uint32_t enabledLayerCount;
96 nullptr, // const char* const* ppEnabledLayerNames;
97 (uint32_t)extensions.size(), // uint32_t enabledExtensionCount;
98 extensions.data(), // const char* const* ppEnabledExtensionNames;
99 DE_NULL, // const VkPhysicalDeviceFeatures* pEnabledFeatures;
100 };
101
102 const auto device = createCustomDevice(m_context.getTestContext().getCommandLine().isValidationEnabled(), vkp,
103 instance, vki, physicalDevice, &deviceInfo);
104
105 de::MovePtr<vk::DeviceDriver> vkd(new vk::DeviceDriver(vkp, instance, device.get(), m_context.getUsedApiVersion(),
106 m_context.getTestContext().getCommandLine()));
107 const auto &vk = *vkd.get();
108
109 const std::vector<std::string> functions = {
110 // VK_EXT_extended_dynamic_state
111 "vkCmdBindVertexBuffers2EXT",
112 "vkCmdSetCullModeEXT",
113 "vkCmdSetDepthBoundsTestEnableEXT",
114 "vkCmdSetDepthCompareOpEXT",
115 "vkCmdSetDepthTestEnableEXT",
116 "vkCmdSetDepthWriteEnableEXT",
117 "vkCmdSetFrontFaceEXT",
118 "vkCmdSetPrimitiveTopologyEXT",
119 "vkCmdSetScissorWithCountEXT",
120 "vkCmdSetStencilOpEXT",
121 "vkCmdSetStencilTestEnableEXT",
122 "vkCmdSetViewportWithCountEXT",
123 // VK_EXT_extended_dynamic_state2
124 "vkCmdSetDepthBiasEnableEXT",
125 "vkCmdSetLogicOpEXT",
126 "vkCmdSetPatchControlPointsEXT",
127 "vkCmdSetPrimitiveRestartEnableEXT",
128 "vkCmdSetRasterizerDiscardEnableEXT",
129 // VK_EXT_extended_dynamic_state3
130 "vkCmdSetAlphaToCoverageEnableEXT",
131 "vkCmdSetAlphaToOneEnableEXT",
132 "vkCmdSetColorBlendAdvancedEXT",
133 "vkCmdSetColorBlendEnableEXT",
134 "vkCmdSetColorBlendEquationEXT",
135 "vkCmdSetColorWriteMaskEXT",
136 "vkCmdSetConservativeRasterizationModeEXT",
137 "vkCmdSetCoverageModulationModeNV",
138 "vkCmdSetCoverageModulationTableEnableNV",
139 "vkCmdSetCoverageModulationTableNV",
140 "vkCmdSetCoverageReductionModeNV",
141 "vkCmdSetCoverageToColorEnableNV",
142 "vkCmdSetCoverageToColorLocationNV",
143 "vkCmdSetDepthClampEnableEXT",
144 "vkCmdSetDepthClipEnableEXT",
145 "vkCmdSetDepthClipNegativeOneToOneEXT",
146 "vkCmdSetExtraPrimitiveOverestimationSizeEXT",
147 "vkCmdSetLineRasterizationModeEXT",
148 "vkCmdSetLineStippleEnableEXT",
149 "vkCmdSetLogicOpEnableEXT",
150 "vkCmdSetPolygonModeEXT",
151 "vkCmdSetProvokingVertexModeEXT",
152 "vkCmdSetRasterizationSamplesEXT",
153 "vkCmdSetRasterizationStreamEXT",
154 "vkCmdSetRepresentativeFragmentTestEnableNV",
155 "vkCmdSetSampleLocationsEnableEXT",
156 "vkCmdSetSampleMaskEXT",
157 "vkCmdSetShadingRateImageEnableNV",
158 "vkCmdSetTessellationDomainOriginEXT",
159 "vkCmdSetViewportSwizzleNV",
160 "vkCmdSetViewportWScalingEnableNV",
161 // VK_EXT_vertex_input_dynamic_state
162 "vkCmdSetVertexInputEXT",
163 };
164
165 for (const auto &func : functions)
166 {
167 const auto &f = vk.getDeviceProcAddr(*device, func.c_str());
168 if (f == DE_NULL)
169 return tcu::TestStatus::fail("Failed: " + func);
170 }
171
172 return tcu::TestStatus::pass("Pass");
173 }
174
175 class ShaderObjectApiCase : public vkt::TestCase
176 {
177 public:
ShaderObjectApiCase(tcu::TestContext & testCtx,const std::string & name)178 ShaderObjectApiCase(tcu::TestContext &testCtx, const std::string &name) : vkt::TestCase(testCtx, name)
179 {
180 }
~ShaderObjectApiCase(void)181 virtual ~ShaderObjectApiCase(void)
182 {
183 }
184
185 void checkSupport(vkt::Context &context) const override;
createInstance(Context & context) const186 TestInstance *createInstance(Context &context) const override
187 {
188 return new ShaderObjectApiInstance(context);
189 }
190 };
191
checkSupport(Context & context) const192 void ShaderObjectApiCase::checkSupport(Context &context) const
193 {
194 context.requireDeviceFunctionality("VK_EXT_shader_object");
195 }
196
197 class ShaderObjectExtensionVersionInstance : public vkt::TestInstance
198 {
199 public:
ShaderObjectExtensionVersionInstance(Context & context,const ShaderObjectApiTest test)200 ShaderObjectExtensionVersionInstance(Context &context, const ShaderObjectApiTest test)
201 : vkt::TestInstance(context)
202 , m_test(test)
203 {
204 }
~ShaderObjectExtensionVersionInstance(void)205 virtual ~ShaderObjectExtensionVersionInstance(void)
206 {
207 }
208
209 tcu::TestStatus iterate(void) override;
210
211 private:
212 ShaderObjectApiTest m_test;
213 };
214
iterate(void)215 tcu::TestStatus ShaderObjectExtensionVersionInstance::iterate(void)
216 {
217 vk::VkInstance instance = m_context.getInstance();
218 vk::InstanceDriver instanceDriver(m_context.getPlatformInterface(), instance);
219 vk::VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
220 const vk::InstanceInterface &vki = m_context.getInstanceInterface();
221 const vk::ApiVersion deviceVersion = vk::unpackVersion(m_context.getDeviceVersion());
222 tcu::TestLog &log = m_context.getTestContext().getLog();
223
224 vk::VkPhysicalDeviceShaderObjectPropertiesEXT shaderObjectProperties = vk::initVulkanStructure();
225
226 vk::VkPhysicalDeviceProperties properties;
227 deMemset(&properties, 0, sizeof(vk::VkPhysicalDeviceProperties));
228 vk::VkPhysicalDeviceProperties2 properties2 = {
229 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, // VkStructureType sType
230 &shaderObjectProperties, // const void* pNext
231 properties // VkPhysicalDeviceProperties properties
232 };
233
234 instanceDriver.getPhysicalDeviceProperties2(physicalDevice, &properties2);
235
236 const std::vector<vk::VkExtensionProperties> &deviceExtensionProperties =
237 enumerateCachedDeviceExtensionProperties(vki, physicalDevice);
238
239 if (m_test == SHADER_BINARY_UUID)
240 {
241 bool nonZero = false;
242 for (uint32_t i = 0; i < VK_UUID_SIZE; ++i)
243 {
244 if (shaderObjectProperties.shaderBinaryUUID[i] != 0)
245 {
246 nonZero = true;
247 break;
248 }
249 }
250 if (!nonZero)
251 {
252 log << tcu::TestLog::Message << "All shaderBinaryUUID bytes are 0" << tcu::TestLog::EndMessage;
253 return tcu::TestStatus::fail("Fail");
254 }
255 }
256 else if (m_test == KHR_DYNAMIC_RENDERING)
257 {
258 if (deviceVersion.majorNum == 1 && deviceVersion.minorNum < 3)
259 {
260 bool found = false;
261 for (const auto &ext : deviceExtensionProperties)
262 {
263 if (strcmp(ext.extensionName, "VK_KHR_dynamic_rendering") == 0)
264 {
265 found = true;
266 break;
267 }
268 }
269 if (!found)
270 {
271 log << tcu::TestLog::Message
272 << "VK_EXT_shader_object is supported, but vulkan version is < 1.3 and VK_KHR_dynamic_rendering is "
273 "not supported"
274 << tcu::TestLog::EndMessage;
275 return tcu::TestStatus::fail("Fail");
276 }
277 }
278 }
279 else
280 {
281 for (const auto &ext : deviceExtensionProperties)
282 {
283 if (m_test == EXT_DISCARD_RECTANGLES)
284 {
285 if (strcmp(ext.extensionName, "VK_EXT_discard_rectangles") == 0)
286 {
287 if (ext.specVersion < 2)
288 {
289 log << tcu::TestLog::Message
290 << "VK_EXT_shader_object and VK_EXT_discard_rectangles are supported, but "
291 "VK_EXT_discard_rectangles reports version "
292 << ext.specVersion << tcu::TestLog::EndMessage;
293 return tcu::TestStatus::fail("Fail");
294 }
295 break;
296 }
297 }
298 else if (m_test == NV_SCISSOR_EXCLUSIVE)
299 {
300 if (strcmp(ext.extensionName, "VK_NV_scissor_exclusive") == 0)
301 {
302 if (ext.specVersion < 2)
303 {
304 log << tcu::TestLog::Message
305 << "VK_EXT_shader_object and VK_NV_scissor_exclusive are supported, but "
306 "VK_NV_scissor_exclusive reports version "
307 << ext.specVersion << tcu::TestLog::EndMessage;
308 return tcu::TestStatus::fail("Fail");
309 }
310 break;
311 }
312 }
313 }
314 }
315 return tcu::TestStatus::pass("Pass");
316 }
317
318 class ShaderObjectExtensionVersionCase : public vkt::TestCase
319 {
320 public:
ShaderObjectExtensionVersionCase(tcu::TestContext & testCtx,const std::string & name,const ShaderObjectApiTest test)321 ShaderObjectExtensionVersionCase(tcu::TestContext &testCtx, const std::string &name, const ShaderObjectApiTest test)
322 : vkt::TestCase(testCtx, name)
323 , m_test(test)
324 {
325 }
~ShaderObjectExtensionVersionCase(void)326 virtual ~ShaderObjectExtensionVersionCase(void)
327 {
328 }
329
330 void checkSupport(vkt::Context &context) const override;
createInstance(Context & context) const331 TestInstance *createInstance(Context &context) const override
332 {
333 return new ShaderObjectExtensionVersionInstance(context, m_test);
334 }
335
336 private:
337 ShaderObjectApiTest m_test;
338 };
339
checkSupport(Context & context) const340 void ShaderObjectExtensionVersionCase::checkSupport(Context &context) const
341 {
342 context.requireDeviceFunctionality("VK_EXT_shader_object");
343 if (m_test == EXT_DISCARD_RECTANGLES)
344 {
345 context.requireDeviceFunctionality("VK_EXT_discard_rectangles");
346 }
347 else if (m_test == NV_SCISSOR_EXCLUSIVE)
348 {
349 context.requireDeviceFunctionality("VK_NV_scissor_exclusive");
350 }
351 }
352 } // namespace
353
createShaderObjectApiTests(tcu::TestContext & testCtx)354 tcu::TestCaseGroup *createShaderObjectApiTests(tcu::TestContext &testCtx)
355 {
356 de::MovePtr<tcu::TestCaseGroup> apiGroup(new tcu::TestCaseGroup(testCtx, "api"));
357 apiGroup->addChild(new ShaderObjectApiCase(testCtx, "get_device_proc_addr"));
358
359 const struct
360 {
361 ShaderObjectApiTest test;
362 const char *name;
363 } apiTests[] = {
364 {EXT_DISCARD_RECTANGLES, "discard_rectangles"},
365 {NV_SCISSOR_EXCLUSIVE, "scissor_exclusive"},
366 {KHR_DYNAMIC_RENDERING, "dynamic_rendering"},
367 {SHADER_BINARY_UUID, "shader_binary_uuid"},
368 };
369
370 for (const auto &test : apiTests)
371 {
372 apiGroup->addChild(new ShaderObjectExtensionVersionCase(testCtx, test.name, test.test));
373 }
374 return apiGroup.release();
375 }
376
377 } // namespace ShaderObject
378 } // namespace vkt
379