xref: /aosp_15_r20/external/deqp/external/vulkancts/modules/vulkan/shader_object/vktShaderObjectApiTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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