Fix the bugs with function dispatcher and swapchain handling

Fixes two bugs:
  - The handling when swapchains are destroyed when VK_NULL_HANDLE is
    passed for the vkDestroySwapchain function to terminate early rather
    than forward it to any dispatch functions below us which could
    potentially not be exported by the layers/ICDs below us.
  - The dispatcher did not implement get_fn() correctly as if the
    function that we attempted to acquire was NULL, this function still
    returned a valid std::optional with the function pointer itself
    being set to NULL if no layers/ICDs under ours did not implement
    these entrypoints. This fixes other issues that could arise in the
    layer when this function is used.

Change-Id: If4fb67c246ef48a97f88914acfb8db3df734b133
Signed-off-by: Normunds Rieksts <normunds.rieksts@arm.com>
This commit is contained in:
Normunds Rieksts 2025-03-10 13:58:12 +00:00
parent ad47eb201f
commit 637b847465
2 changed files with 14 additions and 8 deletions

View file

@ -94,7 +94,7 @@ public:
*
* @tparam FunctionType The signature of the requested function.
* @param fn_name The name of the function.
* @return the requested function pointer, or std::nullopt.
* @return the requested function pointer if valid pointer, or std::nullopt.
*/
template <typename FunctionType>
std::optional<FunctionType> get_fn(const char *fn_name) const
@ -102,7 +102,10 @@ public:
auto fn = m_entrypoints->find(fn_name);
if (fn != m_entrypoints->end())
{
return reinterpret_cast<FunctionType>(fn->second.fn);
if (fn->second.fn != nullptr)
{
return reinterpret_cast<FunctionType>(fn->second.fn);
}
}
return std::nullopt;
@ -138,8 +141,7 @@ protected:
return (*fn)(std::forward<Args>(args)...);
}
WSI_LOG_WARNING("Call to %s failed, dispatch table does not contain the function.", fn_name);
WSI_LOG_ERROR("Call to %s failed, dispatch table does not contain the function.", fn_name);
return std::nullopt;
}
@ -163,7 +165,7 @@ protected:
return (*fn)(std::forward<Args>(args)...);
}
WSI_LOG_WARNING("Call to %s failed, dispatch table does not contain the function.", fn_name);
WSI_LOG_ERROR("Call to %s failed, dispatch table does not contain the function.", fn_name);
}
/**
@ -187,8 +189,7 @@ protected:
return (*fn)(std::forward<Args>(args)...);
}
WSI_LOG_WARNING("Call to %s failed, dispatch table does not contain the function.", fn_name);
WSI_LOG_ERROR("Call to %s failed, dispatch table does not contain the function.", fn_name);
return VK_ERROR_EXTENSION_NOT_PRESENT;
}

View file

@ -79,10 +79,15 @@ wsi_layer_vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapc,
const VkAllocationCallbacks *pAllocator) VWL_API_POST
{
layer::device_private_data &device_data = layer::device_private_data::get(device);
if (swapc == VK_NULL_HANDLE)
{
return;
}
if (!device_data.layer_owns_swapchain(swapc))
{
return device_data.disp.DestroySwapchainKHR(device_data.device, swapc, pAllocator);
device_data.disp.DestroySwapchainKHR(device_data.device, swapc, pAllocator);
return;
}
assert(swapc != VK_NULL_HANDLE);