| /*------------------------------------------------------------------------ |
| * Vulkan Conformance Tests |
| * ------------------------ |
| * |
| * Copyright (c) 2022 NVIDIA CORPORATION, Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| *//*! |
| * \file |
| * \brief Vulkan SC VK_EXT_application_parameters Tests |
| *//*--------------------------------------------------------------------*/ |
| |
| #include "vktApplicationParametersTests.hpp" |
| |
| #include "vktTestCaseUtil.hpp" |
| #include "vktCustomInstancesDevices.hpp" |
| #include "vkSafetyCriticalUtil.hpp" |
| #include "vkDeviceUtil.hpp" |
| #include "vkQueryUtil.hpp" |
| #include "tcuTestLog.hpp" |
| |
| namespace vkt |
| { |
| namespace sc |
| { |
| |
| using namespace vk; |
| |
| enum ApplicationParametersCreateType |
| { |
| INSTANCE = 0, |
| DEVICE |
| }; |
| |
| enum ApplicationParametersTestType |
| { |
| INVALID_VENDOR_ID = 0, |
| INVALID_DEVICE_ID, |
| INVALID_PARAM_KEY, |
| INVALID_PARAM_VALUE, |
| VALID |
| }; |
| |
| struct TestParams |
| { |
| ApplicationParametersCreateType createType; |
| ApplicationParametersTestType testType; |
| }; |
| |
| struct TestData |
| { |
| TestParams testParams; |
| uint32_t vendorId; |
| uint32_t deviceId; |
| uint32_t paramKey; |
| uint64_t paramValue; |
| VkResult expectedResult; |
| }; |
| |
| void readIDsFromDevice (Context& context, uint32_t& vendorId, uint32_t& deviceId) |
| { |
| const InstanceInterface& instanceInterface = context.getInstanceInterface(); |
| VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); |
| VkPhysicalDeviceProperties properties; |
| |
| instanceInterface.getPhysicalDeviceProperties(physicalDevice, &properties); |
| |
| vendorId = properties.vendorID; |
| deviceId = properties.deviceID; |
| } |
| |
| TestData getDefaultTestData (Context& context, TestParams testParams) |
| { |
| TestData testData{}; |
| testData.testParams = testParams; |
| |
| readIDsFromDevice(context, testData.vendorId, testData.deviceId); |
| |
| switch(testParams.testType) |
| { |
| case INVALID_VENDOR_ID: |
| testData.vendorId = 0x01234567; |
| testData.expectedResult = VK_ERROR_INCOMPATIBLE_DRIVER; |
| break; |
| |
| case INVALID_DEVICE_ID: |
| testData.deviceId = 0x01234567; |
| testData.expectedResult = VK_ERROR_INCOMPATIBLE_DRIVER; |
| break; |
| |
| case INVALID_PARAM_KEY: |
| testData.paramKey = 0x7fffffff; |
| testData.expectedResult = VK_ERROR_INITIALIZATION_FAILED; |
| break; |
| |
| case INVALID_PARAM_VALUE: |
| case VALID: |
| // There is no default test case for the invalid param value and valid tests. |
| // Vendors should provide their own test data for these tests in getTestDataList. |
| break; |
| } |
| |
| if (testParams.createType == DEVICE && testParams.testType != VALID) |
| testData.expectedResult = VK_ERROR_INITIALIZATION_FAILED; |
| |
| return testData; |
| } |
| |
| std::vector<TestData> getTestDataList(Context& context, TestParams testParams) |
| { |
| std::vector<TestData> testDataList; |
| uint32_t vendorId; |
| uint32_t deviceId; |
| |
| readIDsFromDevice(context, vendorId, deviceId); |
| |
| const std::vector<TestData> vendorTestDataList = |
| { |
| // The invalid param value and valid tests need to use vendor-specific application |
| // parameter keys and values. In order to have full test coverage, vendors should |
| // provide their own test data for the invalid param value and valid tests here. |
| // For example: |
| // |
| // { |
| // { INSTANCE, INVALID_PARAM_VALUE }, |
| // validVendorID, |
| // validDeviceID, |
| // validParamKey, |
| // invalidParamValue, |
| // VK_ERROR_INITIALIZATION_FAILED |
| // }, |
| // { |
| // { INSTANCE, VALID }, |
| // validVendorID, |
| // validDeviceID, |
| // validParamKey, |
| // validParamValue, |
| // VK_SUCCESS |
| // }, |
| // { |
| // { DEVICE, INVALID_PARAM_VALUE }, |
| // validVendorID, |
| // validDeviceID, |
| // validParamKey, |
| // invalidParamValue, |
| // VK_ERROR_INITIALIZATION_FAILED |
| // }, |
| // { |
| // { DEVICE, VALID }, |
| // validVendorID, |
| // validDeviceID, |
| // validParamKey, |
| // validParamValue, |
| // VK_SUCCESS |
| // } |
| }; |
| |
| if (testParams.testType != INVALID_PARAM_VALUE && testParams.testType != VALID) |
| testDataList.push_back(getDefaultTestData(context, testParams)); |
| |
| for (TestData vendorTestData : vendorTestDataList) |
| { |
| if (vendorTestData.testParams.createType == testParams.createType && |
| vendorTestData.testParams.testType == testParams.testType && |
| vendorTestData.vendorId == vendorId && |
| (vendorTestData.deviceId == 0 || vendorTestData.deviceId == deviceId)) |
| { |
| testDataList.push_back(vendorTestData); |
| } |
| } |
| |
| return testDataList; |
| } |
| |
| void checkSupport (Context& context, TestParams testParams) |
| { |
| const std::vector<VkExtensionProperties> supportedExtensions = enumerateInstanceExtensionProperties(context.getPlatformInterface(), DE_NULL); |
| |
| if (!isExtensionStructSupported(supportedExtensions, RequiredExtension("VK_EXT_application_parameters"))) |
| TCU_THROW(NotSupportedError, "VK_EXT_application_parameters is not supported"); |
| |
| const std::vector<TestData> testDataList = getTestDataList(context, testParams); |
| |
| if (testDataList.empty()) |
| TCU_THROW(NotSupportedError, "No test data available"); |
| } |
| |
| tcu::TestStatus createDeviceTest (Context& context, TestParams testParams) |
| { |
| tcu::TestLog& log = context.getTestContext().getLog(); |
| const PlatformInterface& platformInterface = context.getPlatformInterface(); |
| const CustomInstance instance (createCustomInstanceFromContext(context)); |
| const InstanceDriver& instanceDriver (instance.getDriver()); |
| const VkPhysicalDevice physicalDevice = chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine()); |
| const std::vector<TestData> testDataList = getTestDataList(context, testParams); |
| const float queuePriority = 1.0f; |
| VkDeviceObjectReservationCreateInfo devObjectResCreateInfo = resetDeviceObjectReservationCreateInfo(); |
| bool testPassed = true; |
| const VkPhysicalDeviceVulkanSC10Features sc10Features = |
| { |
| VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_SC_1_0_FEATURES, // sType; |
| &devObjectResCreateInfo, // pNext; |
| VK_FALSE // shaderAtomicInstructions; |
| }; |
| |
| for (TestData testData : testDataList) |
| { |
| const VkApplicationParametersEXT appParams = |
| { |
| VK_STRUCTURE_TYPE_APPLICATION_PARAMETERS_EXT, |
| &sc10Features, |
| testData.vendorId, |
| testData.deviceId, |
| testData.paramKey, |
| testData.paramValue |
| }; |
| |
| const VkDeviceQueueCreateInfo deviceQueueCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType |
| DE_NULL, // pNext |
| (VkDeviceQueueCreateFlags)0u, // flags |
| 0, // queueFamilyIndex; |
| 1, // queueCount; |
| &queuePriority, // pQueuePriorities; |
| }; |
| |
| VkDeviceCreateInfo deviceCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType; |
| &appParams, // pNext; |
| (VkDeviceCreateFlags)0u, // flags |
| 1, // queueRecordCount; |
| &deviceQueueCreateInfo, // pRequestedQueues; |
| 0, // layerCount; |
| DE_NULL, // ppEnabledLayerNames; |
| 0, // extensionCount; |
| DE_NULL, // ppEnabledExtensionNames; |
| DE_NULL, // pEnabledFeatures; |
| }; |
| |
| log << tcu::TestLog::Message << "Creating device with application parameters: " << appParams << tcu::TestLog::EndMessage; |
| |
| VkDevice device = (VkDevice)0; |
| const VkResult result = instanceDriver.createDevice(physicalDevice, &deviceCreateInfo, DE_NULL, &device); |
| |
| if (device) |
| { |
| const DeviceDriver deviceIface(platformInterface, instance, device); |
| deviceIface.destroyDevice(device, DE_NULL/*pAllocator*/); |
| } |
| |
| log << tcu::TestLog::Message << "Device creation returned with " + de::toString(getResultName(result)) + |
| " (expecting " + de::toString(getResultName(testData.expectedResult)) + ")" << tcu::TestLog::EndMessage; |
| |
| if (result != testData.expectedResult) |
| testPassed = false; |
| } |
| |
| if (testPassed) |
| return tcu::TestStatus::pass("Pass"); |
| else |
| return tcu::TestStatus::fail("Fail"); |
| } |
| |
| tcu::TestStatus createInstanceTest (Context& context, TestParams testParams) |
| { |
| tcu::TestLog& log = context.getTestContext().getLog(); |
| const PlatformInterface& platformInterface = context.getPlatformInterface(); |
| const std::vector<TestData> testDataList = getTestDataList(context, testParams); |
| bool testPassed = true; |
| |
| for (TestData testData : testDataList) |
| { |
| const VkApplicationParametersEXT appParams |
| { |
| VK_STRUCTURE_TYPE_APPLICATION_PARAMETERS_EXT, |
| DE_NULL, |
| testData.vendorId, |
| testData.deviceId, |
| testData.paramKey, |
| testData.paramValue |
| }; |
| |
| const VkApplicationInfo appInfo = |
| { |
| VK_STRUCTURE_TYPE_APPLICATION_INFO, // VkStructureType sType; |
| &appParams, // const void* pNext; |
| "appName", // const char* pAppName; |
| 0u, // deUint32 appVersion; |
| "engineName", // const char* pEngineName; |
| 0u, // deUint32 engineVersion; |
| context.getUsedApiVersion(), // deUint32 apiVersion; |
| }; |
| |
| const VkInstanceCreateInfo instanceCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| (VkInstanceCreateFlags)0u, // VkInstanceCreateFlags flags; |
| &appInfo, // const VkApplicationInfo* pAppInfo; |
| 0u, // deUint32 layerCount; |
| DE_NULL, // const char*const* ppEnabledLayernames; |
| 0u, // deUint32 extensionCount; |
| DE_NULL, // const char*const* ppEnabledExtensionNames; |
| }; |
| |
| log << tcu::TestLog::Message << "Creating instance with application parameters: " << appParams << tcu::TestLog::EndMessage; |
| |
| VkInstance instance = (VkInstance)0; |
| const VkResult result = platformInterface.createInstance(&instanceCreateInfo, DE_NULL/*pAllocator*/, &instance); |
| |
| if (instance) |
| { |
| const InstanceDriver instanceIface(platformInterface, instance); |
| instanceIface.destroyInstance(instance, DE_NULL/*pAllocator*/); |
| } |
| |
| log << tcu::TestLog::Message << "Instance creation returned with " + de::toString(getResultName(result)) + |
| " (expecting " + de::toString(getResultName(testData.expectedResult)) + ")" << tcu::TestLog::EndMessage; |
| |
| if (result != testData.expectedResult) |
| testPassed = false; |
| } |
| |
| if (testPassed) |
| return tcu::TestStatus::pass("Pass"); |
| else |
| return tcu::TestStatus::fail("Fail"); |
| } |
| |
| tcu::TestCaseGroup* createApplicationParametersTests (tcu::TestContext& testCtx) |
| { |
| de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "application_parameters", "Tests VK_EXT_application_parameters")); |
| |
| const struct |
| { |
| ApplicationParametersCreateType createType; |
| const char* name; |
| } groups[2] = |
| { |
| { INSTANCE, "create_instance" }, |
| { DEVICE, "create_device" } |
| }; |
| |
| const struct |
| { |
| ApplicationParametersTestType testType; |
| const char* name; |
| } tests[5] = |
| { |
| { INVALID_VENDOR_ID, "invalid_vendor_id" }, |
| { INVALID_DEVICE_ID, "invalid_device_id" }, |
| { INVALID_PARAM_KEY, "invalid_parameter_key" }, |
| { INVALID_PARAM_VALUE, "invalid_parameter_value" }, |
| { VALID, "valid" } |
| }; |
| |
| for (int groupIdx = 0; groupIdx < DE_LENGTH_OF_ARRAY(groups); ++groupIdx) |
| { |
| de::MovePtr<tcu::TestCaseGroup> createGroup(new tcu::TestCaseGroup(testCtx, groups[groupIdx].name, "")); |
| |
| for (int testIdx = 0; testIdx < DE_LENGTH_OF_ARRAY(tests); ++testIdx) |
| { |
| TestParams testParams = { groups[groupIdx].createType, tests[testIdx].testType }; |
| |
| if (testParams.createType == INSTANCE) |
| addFunctionCase(createGroup.get(), tests[testIdx].name, "", checkSupport, createInstanceTest, testParams); |
| else |
| addFunctionCase(createGroup.get(), tests[testIdx].name, "", checkSupport, createDeviceTest, testParams); |
| } |
| |
| group->addChild(createGroup.release()); |
| } |
| |
| return group.release(); |
| } |
| |
| } // sc |
| |
| } // vkt |