Skip to content

Commit e72445b

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. Also make sure when the extension is used, the KHR version of the symbol is loaded. 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 e72445b

2 files changed

Lines changed: 70 additions & 27 deletions

File tree

src/vulkan.cpp

Lines changed: 70 additions & 27 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);
@@ -1867,8 +1858,15 @@ static VkResult overlay_CreateDevice(
18671858
driverProps.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
18681859
driverProps.pNext = nullptr;
18691860
if (can_get_driver_info) {
1870-
VkPhysicalDeviceProperties2 deviceProps = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, &driverProps};
1871-
instance_data->vtable.GetPhysicalDeviceProperties2(device_data->physical_device, &deviceProps);
1861+
// In Vulkan 1.0, use the KHR symbol which is guaranteed to be available if extension is.
1862+
auto get_props2 = (PFN_vkGetPhysicalDeviceProperties2) fpGetInstanceProcAddr(
1863+
instance_data->instance,
1864+
instance_data->api_version > VK_VERSION_1_0 ? "vkGetPhysicalDeviceProperties2"
1865+
: "vkGetPhysicalDeviceProperties2KHR");
1866+
if (get_props2) {
1867+
VkPhysicalDeviceProperties2 deviceProps = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, &driverProps};
1868+
get_props2(device_data->physical_device, &deviceProps);
1869+
}
18721870
}
18731871

18741872
if (!is_blacklisted()) {
@@ -1949,11 +1947,58 @@ static VkResult overlay_CreateInstance(
19491947
// Advance the link info for the next element on the chain
19501948
chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
19511949

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

19531996
VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
19541997
if (result != VK_SUCCESS) return result;
19551998

19561999
struct instance_data *instance_data = new_instance_data(*pInstance);
2000+
instance_data->api_version = api_version;
2001+
instance_data->has_props2 = has_props2;
19572002
vk_load_instance_commands(instance_data->instance,
19582003
fpGetInstanceProcAddr,
19592004
&instance_data->vtable);
@@ -1982,8 +2027,6 @@ static VkResult overlay_CreateInstance(
19822027
instance_data->engineVersion = engineVersion;
19832028
}
19842029

1985-
instance_data->api_version = pCreateInfo->pApplicationInfo ? pCreateInfo->pApplicationInfo->apiVersion : VK_API_VERSION_1_0;
1986-
19872030
return result;
19882031
}
19892032

subprojects/.wraplock

Whitespace-only changes.

0 commit comments

Comments
 (0)