Skip to content

Commit 13924d9

Browse files
committed
vulkan: Expand cases where can_get_driver_info is true
VK_KHR_driver_properties requires VK_KHR_get_physical_device_properties2 extension. For Vulkan 1.2 both extensions are core, so nothing to do, for Vulkan 1.1, the latter is core, so only need the former. For Vulkan 1.0 both extensions are required. VK_KHR_driver_properties is a device extension that doesn't need to be explicitly enabled here. As long as its supported it can be used in the query on the physical device, before the logical device is created (i.e. before device extensions can be enabled). See https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#fundamentals-validusage-pNext. VK_KHR_get_physical_device_properties2 is an instance extension, required for the previous one. If the application hasn't enabled it, do in its behalf. This fixes `vulkan_driver` option in applications that ask for Vulkan 1.0 (e.g. vkcube) but that the driver does support the extra extensions.
1 parent eb7fe42 commit 13924d9

File tree

1 file changed

+62
-25
lines changed

1 file changed

+62
-25
lines changed

src/vulkan.cpp

Lines changed: 62 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ struct instance_data {
8282
enum EngineTypes engine;
8383
notify_thread notifier;
8484
int control_client;
85+
bool has_props2;
8586
};
8687

8788
/* Mapped from VkDevice */
@@ -1819,35 +1820,25 @@ static VkResult overlay_CreateDevice(
18191820
chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
18201821

18211822

1822-
std::vector<const char*> enabled_extensions(pCreateInfo->ppEnabledExtensionNames,
1823-
pCreateInfo->ppEnabledExtensionNames +
1824-
pCreateInfo->enabledExtensionCount);
1823+
bool can_get_driver_info = false;
18251824

1826-
uint32_t extension_count;
1827-
1828-
instance_data->vtable.EnumerateDeviceExtensionProperties(physicalDevice, nullptr, &extension_count, nullptr);
1829-
1830-
std::vector<VkExtensionProperties> available_extensions(extension_count);
1831-
instance_data->vtable.EnumerateDeviceExtensionProperties(physicalDevice, nullptr, &extension_count, available_extensions.data());
1825+
// VK_KHR_driver_properties became core in 1.2
1826+
if (instance_data->api_version >= VK_API_VERSION_1_2) {
1827+
can_get_driver_info = true;
18321828

1829+
} else if (instance_data->has_props2) {
1830+
uint32_t device_extension_count;
1831+
instance_data->vtable.EnumerateDeviceExtensionProperties(physicalDevice, nullptr, &device_extension_count, nullptr);
18331832

1834-
bool can_get_driver_info = instance_data->api_version < VK_API_VERSION_1_1 ? false : true;
1833+
std::vector<VkExtensionProperties> device_extensions(device_extension_count);
1834+
instance_data->vtable.EnumerateDeviceExtensionProperties(physicalDevice, nullptr, &device_extension_count, device_extensions.data());
18351835

1836-
// VK_KHR_driver_properties became core in 1.2
1837-
if (instance_data->api_version < VK_API_VERSION_1_2 && can_get_driver_info) {
1838-
for (auto& extension : available_extensions) {
1839-
if (extension.extensionName == std::string(VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME)) {
1840-
for (auto& enabled : enabled_extensions) {
1841-
if (enabled == std::string(VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME))
1842-
goto DONT;
1843-
}
1844-
enabled_extensions.push_back(VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME);
1845-
DONT:
1846-
goto FOUND;
1836+
for (const auto& ext : device_extensions) {
1837+
if (ext.extensionName == std::string(VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME)) {
1838+
can_get_driver_info = true;
1839+
break;
18471840
}
18481841
}
1849-
can_get_driver_info = false;
1850-
FOUND:;
18511842
}
18521843

18531844
VkResult result = fpCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);
@@ -1949,11 +1940,59 @@ static VkResult overlay_CreateInstance(
19491940
// Advance the link info for the next element on the chain
19501941
chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
19511942

1943+
const uint32_t api_version = pCreateInfo->pApplicationInfo ? pCreateInfo->pApplicationInfo->apiVersion : VK_API_VERSION_1_0;
1944+
bool has_props2 = false;
1945+
1946+
std::vector<const char *> modified_extensions(pCreateInfo->enabledExtensionCount);
1947+
VkInstanceCreateInfo modified_create_info = {};
1948+
1949+
if (api_version >= VK_API_VERSION_1_1) {
1950+
// Part of Vulkan core.
1951+
has_props2 = true;
1952+
1953+
} else {
1954+
bool present = false;
1955+
for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
1956+
const char *ext = pCreateInfo->ppEnabledExtensionNames[i];
1957+
modified_extensions[i] = ext;
1958+
if (strcmp(ext, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME) == 0)
1959+
present = true;
1960+
}
1961+
1962+
// Enable VK_KHR_get_physical_device_properties2 if the application hasn't yet and
1963+
// it is supported.
1964+
if (!present) {
1965+
PFN_vkEnumerateInstanceExtensionProperties fpEnumerateInstnaceExtensionProperties =
1966+
(PFN_vkEnumerateInstanceExtensionProperties)fpGetInstanceProcAddr(NULL, "vkEnumerateInstanceExtensionProperties");
1967+
uint32_t supported_extensions_count;
1968+
fpEnumerateInstnaceExtensionProperties(nullptr, &supported_extensions_count, nullptr);
1969+
1970+
std::vector<VkExtensionProperties> supported_extensions(supported_extensions_count);
1971+
fpEnumerateInstnaceExtensionProperties(nullptr, &supported_extensions_count, supported_extensions.data());
1972+
1973+
for (const auto& ext : supported_extensions) {
1974+
if (strcmp(ext.extensionName, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME) == 0) {
1975+
has_props2 = true;
1976+
break;
1977+
}
1978+
}
1979+
1980+
if (has_props2) {
1981+
modified_extensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
1982+
modified_create_info = *pCreateInfo;
1983+
modified_create_info.enabledExtensionCount = modified_extensions.size();
1984+
modified_create_info.ppEnabledExtensionNames = modified_extensions.data();
1985+
pCreateInfo = &modified_create_info;
1986+
}
1987+
}
1988+
}
19521989

19531990
VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
19541991
if (result != VK_SUCCESS) return result;
19551992

19561993
struct instance_data *instance_data = new_instance_data(*pInstance);
1994+
instance_data->api_version = api_version;
1995+
instance_data->has_props2 = true;
19571996
vk_load_instance_commands(instance_data->instance,
19581997
fpGetInstanceProcAddr,
19591998
&instance_data->vtable);
@@ -1982,8 +2021,6 @@ static VkResult overlay_CreateInstance(
19822021
instance_data->engineVersion = engineVersion;
19832022
}
19842023

1985-
instance_data->api_version = pCreateInfo->pApplicationInfo ? pCreateInfo->pApplicationInfo->apiVersion : VK_API_VERSION_1_0;
1986-
19872024
return result;
19882025
}
19892026

0 commit comments

Comments
 (0)