Commit dc1059b2 authored by Philip Langdale's avatar Philip Langdale

vulkan: Suppress validation errors when binding imported image memory

Importing image memory is a funny thing; there's no core mechanism
to communicate the layout of the image. Depending on how exactly
the memory was imported, and where it was imported from, it might
be possible to manage without explicit knowledge of layout, or
out-of-band mechanisms might exist to communicate it.

Today, we specifically can handle importing of memory via dma_buf
fds. While there is a Vulakn extension defined that could help
to communicate layout (VK_EXT_image_drm_format_modifier), this
extension isn't actually implemented in any driver and it doesn't
look like it will happen any time soon.

Without it, we have to hope that imported memory has the same layout
that Vulkan expects, based on the declared image format. In
practice, this has proven to be true for the real world scenario
we care about - which is importing decoded video from VAAPI - there
are only a couple of relevant formats, and the drivers for both
Vulkan and VAAPI are written by the same sets of people following
the same hardware driven recommendations for layout.

However, just because layouts match in practice, doesn't mean that
they pass validation. What we see is that, for some formats,
validation will fail when binding memory, saying that the memory
segment is smaller than the vulkan-calcuated memory size. I assume
this happens due to a difference in memory alignment (pretty much
any other cause would lead to visible errors).

As we would like to be able to use VAAPI imported surfaces without
sacrificing validation, we need a way to filter out these expected
errors, and let validation proceed as normal elsewhere.

The mechanism we've decided on is to provide a way to ignore
errors on a specified vulkan object (in our specific case, the
VkImage). We store the object ID before the bind call, and clear
it afterwards. While it is set, errors on that object will be

It's a simple mechanism that isn't thread safe, but could be made
so if/when the need arises.
parent 644f9d57
Pipeline #7282 passed with stages
in 1 minute and 35 seconds
......@@ -23,6 +23,8 @@
struct pl_context {
struct pl_context_params params;
struct bstr logbuffer;
// Provide a place for implementations to track suppression of errors
uint64_t suppress_errors_for_object;
// Logging-related functions
......@@ -140,6 +140,13 @@ static VkBool32 VKAPI_PTR vk_dbg_callback(VkDebugReportFlagsEXT flags,
struct pl_context *ctx = priv;
enum pl_log_level lev = PL_LOG_INFO;
// We will ignore errors for a designated object, but we need to explicitly
// handle the case where no object is designated, because errors can have no
// object associated with them, and we don't want to suppress those errors.
if (ctx->suppress_errors_for_object != VK_NULL_HANDLE &&
ctx->suppress_errors_for_object == obj)
return false;
switch (flags) {
......@@ -898,11 +898,20 @@ static const struct pl_tex *vk_tex_create(const struct pl_gpu *gpu,
goto error;
// Currently, we know that attempting to bind imported memory may generate
// validation errors because there's no way to communicate the memory
// layout; the validation layer will rely on the expected Vulkan layout
// for the image. As long as the driver can handle the image, we'll be ok
// so we don't want these validation errors to fire and create false
// positives.
vk->ctx->suppress_errors_for_object = (uint64_t)tex_vk->img;
} else {
if (!vk_malloc_generic(p->alloc, reqs, memFlags, params->export_handle, mem))
goto error;
VK(vkBindImageMemory(vk->dev, tex_vk->img, mem->vkmem, mem->offset));
if (params->import_handle)
vk->ctx->suppress_errors_for_object = VK_NULL_HANDLE;
if (!vk_init_image(gpu, tex))
goto error;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment