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