External Image format(and other properites) in Vulkan with X11

Hello, I am trying to make a vulkan based x11 compositor and I’ve got stuck.
I was able to load external memory, from a redirected window:

    const redirected_window = xxx; // I've used xwininfo to grab a random window, 
    const redirected_pixmap = c.xcb_generate_id(conn);
    _ = c.xcb_composite_redirect_window(conn, redirected_window, c.XCB_COMPOSITE_REDIRECT_MANUAL);
    _ = c.xcb_composite_name_window_pixmap(conn, redirected_window, redirected_pixmap);
    _ = c.xcb_flush(conn);
    const buffer_from_pixmap_cookie = c.xcb_dri3_buffer_from_pixmap(conn, redirected_pixmap);
    var xcb_error: ?*c.xcb_generic_error_t = null;
    const buffer_from_pixmap_reply = c.xcb_dri3_buffer_from_pixmap_reply(conn, buffer_from_pixmap_cookie, &xcb_error);
    std.debug.assert(xcb_error == null);
    std.debug.assert(buffer_from_pixmap_reply.*.nfd == 1);
    const redirected_fd: i32 = c.xcb_dri3_buffer_from_pixmap_reply_fds(conn, buffer_from_pixmap_reply)[0];

    const import_memory_info = vk.ImportMemoryFdInfoKHR{ .fd = redirected_fd, .handle_type = vk.ExternalMemoryHandleTypeFlags{ .dma_buf_bit_ext = true } };
    const memory_allocate_info = vk.MemoryAllocateInfo{
        .p_next = &import_memory_info,
        .allocation_size = buffer_from_pixmap_reply.*.size,
        .memory_type_index = 0,
    };

    const redirected_memory = vkd.allocateMemory(device, &memory_allocate_info, null) catch |e| {
        std.log.err("Couldn't import memory from redirected window, error: {}", .{e});
        return;
    };
    defer vkd.freeMemory(device, redirected_memory, null);

I’ve included the source for that, because maybe I messed up something in this stage after all.
After importing the memory I’ve tried to create an image binded to that memory, but unfortunately I get an error from validation layer:


    const external_memory_image_create_info = vk.ExternalMemoryImageCreateInfo{ .handle_types = .{ .dma_buf_bit_ext = true } };

    const image_create_info = vk.ImageCreateInfo{ .p_next = &external_memory_image_create_info, .extent = vk.Extent3D{
        .width = buffer_from_pixmap_reply.*.width,
        .height = buffer_from_pixmap_reply.*.height,
        .depth = 1,
    }, .image_type = .@"2d", .mip_levels = 1, .array_layers = 1, .format = .b8g8r8a8_uint, .tiling = .optimal, .initial_layout = .undefined, .usage = vk.ImageUsageFlags{
        .sampled_bit = true,
    }, .sharing_mode = .exclusive, .samples = vk.SampleCountFlags{
        .@"1_bit" = true,
    }, .flags = vk.ImageCreateFlags{} };
    const redirected_image = vkd.createImage(device, &image_create_info, null) catch |e| {
        std.log.err("Couldn't create an image for redirected window buffer, error {}", .{e});
        return;
    };
    vkd.bindImageMemory(device, redirected_image, redirected_memory, 0) catch |e| {
        std.log.err("Couldn't bind the image to redirected window buffer, error {}", .{e});
        return;
    };

It says that this combination of format and other properties is unsupported, and it links to vkGetPhysicalDeviceImageFormatProperties2. This function if I understand it properly takes a format, usage and so one at returns the valid handle types, but how do I get the supported formats in the first place and how do I know which of them is correct for the redirected window surface buffer?
I could try to iterate over the formats returned by vkGetPhysicalDeviceSurfaceFormatsKHR but this doesn’t return the rest of the properties like tiling or flags, should I try every combination of those?

I don’t think you can just import random file descriptor willy nilly…

The file descriptor is obtained via dri3 extension which if understand it correctly is exactly for this purpose. At least that’s what I’ve read in the extension manual. I could be using it wrong though

A Swapchain object is for interfacing with X11 stuff.

As far as I know you can import only memory from the same device made by another (instance) of graphics API. Meaning you know what device it is created on and with which format you created it with etc.

I think “blind” imports currently exist only on Android.

PS: your immediate problem with validation probably be more mundane that you don’t check support and limits…

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.