Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 22 additions & 9 deletions renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -855,6 +855,11 @@ VkResult WrappedVulkan::vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo
record->instDevInfo->vulkanVersion = renderdocAppInfo.apiVersion;

std::set<rdcstr> availablePhysDeviceFunctions;
// Track the highest core apiVersion actually supported by a physical device. Some apps (e.g.
// Adreno titles) request a low VkApplicationInfo::apiVersion but still call promoted core
// functions that the driver leniently provides. Gate promoted-function exposure on this too,
// otherwise GetDeviceProcAddr returns NULL for them and the app crashes calling a null pointer.
uint32_t maxPhysDeviceApiVersion = 0;

{
uint32_t count = 0;
Expand All @@ -867,6 +872,10 @@ VkResult WrappedVulkan::vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo
rdcarray<VkExtensionProperties> exts;
for(VkPhysicalDevice p : physDevs)
{
VkPhysicalDeviceProperties physProps = {};
ObjDisp(m_Instance)->GetPhysicalDeviceProperties(p, &physProps);
maxPhysDeviceApiVersion = RDCMAX(maxPhysDeviceApiVersion, physProps.apiVersion);

ObjDisp(m_Instance)->EnumerateDeviceExtensionProperties(p, NULL, &count, NULL);

exts.resize(count);
Expand Down Expand Up @@ -901,7 +910,7 @@ VkResult WrappedVulkan::vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo
// * it's a device extension and available on at least one physical device
#undef CheckExt
#define CheckExt(name, ver) \
if(record->instDevInfo->vulkanVersion >= ver || \
if(record->instDevInfo->vulkanVersion >= ver || maxPhysDeviceApiVersion >= ver || \
availablePhysDeviceFunctions.find("VK_" #name) != availablePhysDeviceFunctions.end()) \
{ \
record->instDevInfo->ext_##name = true; \
Expand Down Expand Up @@ -1935,7 +1944,7 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi
// enable VK_KHR_shader_subgroup_uniform_control_flow if it's available, to make subgroup
// debugging more reliable/spec-clean.
// if we can't get it, we'll just emit the same code anyway and hope it compiles to something sensible
if(RDCMIN(m_EnabledExtensions.vulkanVersion, physProps.apiVersion) >= VK_MAKE_VERSION(1, 1, 0))
if(physProps.apiVersion >= VK_MAKE_VERSION(1, 1, 0))
{
if(supportedExtensions.find(VK_KHR_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_EXTENSION_NAME) !=
supportedExtensions.end())
Expand Down Expand Up @@ -4098,7 +4107,7 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES,
};

if(RDCMIN(m_EnabledExtensions.vulkanVersion, physProps.apiVersion) >= VK_MAKE_VERSION(1, 2, 0))
if(physProps.apiVersion >= VK_MAKE_VERSION(1, 2, 0))
{
VkPhysicalDeviceVulkan12Features avail12Features = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES,
Expand Down Expand Up @@ -4186,7 +4195,7 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES,
};

if(RDCMIN(m_EnabledExtensions.vulkanVersion, physProps.apiVersion) >= VK_MAKE_VERSION(1, 3, 0))
if(physProps.apiVersion >= VK_MAKE_VERSION(1, 3, 0))
{
// VK_EXT_extended_dynamic_state and VK_EXT_extended_dynamic_state2 were unconditionally
// promoted and considered implicitly enabled in vulkan 1.3
Expand All @@ -4195,7 +4204,7 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi
// logic and patch CPs were not
}

if(RDCMIN(m_EnabledExtensions.vulkanVersion, physProps.apiVersion) >= VK_MAKE_VERSION(1, 2, 0))
if(physProps.apiVersion >= VK_MAKE_VERSION(1, 2, 0))
{
VkPhysicalDeviceVulkan12Features avail12Features = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES,
Expand Down Expand Up @@ -4405,7 +4414,7 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi

CheckDeviceExts();

uint32_t effectiveApiVersion = RDCMIN(m_EnabledExtensions.vulkanVersion, physProps.apiVersion);
uint32_t effectiveApiVersion = physProps.apiVersion;

#undef CheckExt
#define CheckExt(name, ver) \
Expand Down Expand Up @@ -4669,7 +4678,7 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi
for(size_t i = 0; i < queueProps.size(); i++)
m_PhysicalDeviceData.queueProps[i] = queueProps[i];

if(RDCMIN(m_EnabledExtensions.vulkanVersion, physProps.apiVersion) >= VK_MAKE_VERSION(1, 1, 0))
if(physProps.apiVersion >= VK_MAKE_VERSION(1, 1, 0))
{
VkPhysicalDeviceVulkan11Properties vulkan11Props = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES,
Expand Down Expand Up @@ -5130,8 +5139,12 @@ VkResult WrappedVulkan::vkCreateDevice(VkPhysicalDevice physicalDevice,
VkPhysicalDeviceProperties physProps;
ObjDisp(physicalDevice)->GetPhysicalDeviceProperties(Unwrap(physicalDevice), &physProps);

record->instDevInfo->vulkanVersion =
RDCMIN(physProps.apiVersion, GetRecord(m_Instance)->instDevInfo->vulkanVersion);
// Use the physical device's supported apiVersion rather than RDCMIN with the app-requested
// version. Some apps (e.g. Adreno titles like Asphalt 9) request a low VkApplicationInfo
// apiVersion but still call promoted core functions that the driver leniently provides;
// taking the MIN made GetDeviceProcAddr return NULL for those, and the app crashed calling
// a null pointer. Exposing everything the physical device supports matches the driver.
record->instDevInfo->vulkanVersion = physProps.apiVersion;

#undef CheckExt
#define CheckExt(name, ver) \
Expand Down