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 34namespace vkt 35{ 36namespace ShaderObject 37{ 38 39namespace 40{ 41 42enum ShaderObjectApiTest { 43 EXT_DISCARD_RECTANGLES = 0, 44 NV_SCISSOR_EXCLUSIVE, 45 KHR_DYNAMIC_RENDERING, 46 SHADER_BINARY_UUID, 47}; 48 49class ShaderObjectApiInstance : public vkt::TestInstance 50{ 51public: 52 ShaderObjectApiInstance (Context& context) 53 : vkt::TestInstance (context) 54 {} 55 virtual ~ShaderObjectApiInstance (void) {} 56 57 tcu::TestStatus iterate (void) override; 58}; 59 60tcu::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 172class ShaderObjectApiCase : public vkt::TestCase 173{ 174public: 175 ShaderObjectApiCase (tcu::TestContext& testCtx, const std::string& name) 176 : vkt::TestCase (testCtx, name) 177 {} 178 virtual ~ShaderObjectApiCase (void) {} 179 180 void checkSupport (vkt::Context& context) const override; 181 TestInstance* createInstance (Context& context) const override { return new ShaderObjectApiInstance(context); } 182}; 183 184void ShaderObjectApiCase::checkSupport (Context& context) const 185{ 186 context.requireDeviceFunctionality("VK_EXT_shader_object"); 187} 188 189class ShaderObjectExtensionVersionInstance : public vkt::TestInstance 190{ 191public: 192 ShaderObjectExtensionVersionInstance (Context& context, const ShaderObjectApiTest test) 193 : vkt::TestInstance (context) 194 , m_test (test) 195 {} 196 virtual ~ShaderObjectExtensionVersionInstance (void) {} 197 198 tcu::TestStatus iterate (void) override; 199private: 200 ShaderObjectApiTest m_test; 201}; 202 203tcu::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 297class ShaderObjectExtensionVersionCase : public vkt::TestCase 298{ 299public: 300 ShaderObjectExtensionVersionCase (tcu::TestContext& testCtx, const std::string& name, const ShaderObjectApiTest test) 301 : vkt::TestCase (testCtx, name) 302 , m_test (test) 303 {} 304 virtual ~ShaderObjectExtensionVersionCase (void) {} 305 306 void checkSupport (vkt::Context& context) const override; 307 TestInstance* createInstance (Context& context) const override { return new ShaderObjectExtensionVersionInstance(context, m_test); } 308private: 309 ShaderObjectApiTest m_test; 310}; 311 312void 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 326tcu::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