Skip to content

Commit 55a8337

Browse files
authored
[Vulkan] Use the API version from the device (#190)
Initially this code just hard-coded Vulkan 1.1 because you need to set it before you can query device capabilities (which is messy). This changes the code to setup a 1.1 device, query it, then recreate the device with the highest supported version (generally 1.3). We should update this code to accept a vulkan version from command line arguments (see #189).
1 parent 2416411 commit 55a8337

File tree

1 file changed

+30
-2
lines changed

1 file changed

+30
-2
lines changed

lib/API/VK/Device.cpp

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,8 @@ class VKDevice : public offloadtest::Device {
170170
}
171171
}
172172

173+
const VkPhysicalDeviceProperties &getProps() const { return Props; }
174+
173175
private:
174176
void queryCapabilities() {
175177

@@ -779,31 +781,57 @@ class VKContext {
779781
}
780782

781783
llvm::Error initialize() {
784+
// Create a Vulkan 1.1 instance to determine the API version
782785
VkApplicationInfo AppInfo = {};
783786
AppInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
784787
AppInfo.pApplicationName = "OffloadTest";
788+
// TODO: We should set this based on a command line flag, and simplify the
789+
// code below to error if the requested version isn't supported.
785790
AppInfo.apiVersion = VK_API_VERSION_1_1;
786791

787792
VkInstanceCreateInfo CreateInfo = {};
788793
CreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
789794
CreateInfo.pApplicationInfo = &AppInfo;
790795

796+
VkResult Res = vkCreateInstance(&CreateInfo, NULL, &Instance);
797+
if (Res == VK_ERROR_INCOMPATIBLE_DRIVER)
798+
return llvm::createStringError(std::errc::no_such_device,
799+
"Cannot find a compatible Vulkan device");
800+
else if (Res)
801+
return llvm::createStringError(std::errc::no_such_device,
802+
"Unkown Vulkan initialization error");
803+
804+
uint32_t DeviceCount = 0;
805+
if (vkEnumeratePhysicalDevices(Instance, &DeviceCount, nullptr))
806+
return llvm::createStringError(std::errc::no_such_device,
807+
"Failed to get device count");
808+
std::vector<VkPhysicalDevice> PhysicalDevicesTmp(DeviceCount);
809+
if (vkEnumeratePhysicalDevices(Instance, &DeviceCount,
810+
PhysicalDevicesTmp.data()))
811+
return llvm::createStringError(std::errc::no_such_device,
812+
"Failed to enumerate devices");
813+
{
814+
auto TmpDev = std::make_shared<VKDevice>(PhysicalDevicesTmp[0]);
815+
AppInfo.apiVersion = TmpDev->getProps().apiVersion;
816+
}
817+
vkDestroyInstance(Instance, NULL);
818+
791819
// TODO: This is a bit hacky but matches what I did in DX.
792820
#ifndef NDEBUG
793821
const char *ValidationLayer = "VK_LAYER_KHRONOS_validation";
794822
CreateInfo.ppEnabledLayerNames = &ValidationLayer;
795823
CreateInfo.enabledLayerCount = 1;
796824
#endif
797825

798-
VkResult Res = vkCreateInstance(&CreateInfo, NULL, &Instance);
826+
Res = vkCreateInstance(&CreateInfo, NULL, &Instance);
799827
if (Res == VK_ERROR_INCOMPATIBLE_DRIVER)
800828
return llvm::createStringError(std::errc::no_such_device,
801829
"Cannot find a compatible Vulkan device");
802830
else if (Res)
803831
return llvm::createStringError(std::errc::no_such_device,
804832
"Unkown Vulkan initialization error");
805833

806-
uint32_t DeviceCount = 0;
834+
DeviceCount = 0;
807835
if (vkEnumeratePhysicalDevices(Instance, &DeviceCount, nullptr))
808836
return llvm::createStringError(std::errc::no_such_device,
809837
"Failed to get device count");

0 commit comments

Comments
 (0)