X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fvulkan%2Fwsi%2Fwsi_common_x11.c;h=8860d8edb6e883266ec8dd8a6b352f85ffd08acf;hb=393aa3f6c929fdbcaa599597e28a3206aa09dcc2;hp=c399aae5afdc3d91f8c3c89bb5df8f22ac4721f1;hpb=f82b6c6272b48b4ce1f267239fa5b1cd3dfffcc7;p=mesa.git diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c index c399aae5afd..8860d8edb6e 100644 --- a/src/vulkan/wsi/wsi_common_x11.c +++ b/src/vulkan/wsi/wsi_common_x11.c @@ -38,7 +38,8 @@ #include #include "util/hash_table.h" -#include "wsi_common.h" +#include "vk_util.h" +#include "wsi_common_private.h" #include "wsi_common_x11.h" #include "wsi_common_queue.h" @@ -235,9 +236,9 @@ wsi_x11_get_connection(struct wsi_device *wsi_dev, return entry->data; } -static const VkSurfaceFormatKHR formats[] = { - { .format = VK_FORMAT_B8G8R8A8_SRGB, }, - { .format = VK_FORMAT_B8G8R8A8_UNORM, }, +static const VkFormat formats[] = { + VK_FORMAT_B8G8R8A8_SRGB, + VK_FORMAT_B8G8R8A8_UNORM, }; static const VkPresentModeKHR present_modes[] = { @@ -510,22 +511,52 @@ x11_surface_get_capabilities(VkIcdSurfaceBase *icd_surface, return VK_SUCCESS; } +static VkResult +x11_surface_get_capabilities2(VkIcdSurfaceBase *icd_surface, + const void *info_next, + VkSurfaceCapabilities2KHR *caps) +{ + assert(caps->sType == VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR); + + return x11_surface_get_capabilities(icd_surface, &caps->surfaceCapabilities); +} + static VkResult x11_surface_get_formats(VkIcdSurfaceBase *surface, struct wsi_device *wsi_device, uint32_t *pSurfaceFormatCount, VkSurfaceFormatKHR *pSurfaceFormats) { - if (pSurfaceFormats == NULL) { - *pSurfaceFormatCount = ARRAY_SIZE(formats); - return VK_SUCCESS; + VK_OUTARRAY_MAKE(out, pSurfaceFormats, pSurfaceFormatCount); + + for (unsigned i = 0; i < ARRAY_SIZE(formats); i++) { + vk_outarray_append(&out, f) { + f->format = formats[i]; + f->colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; + } } - *pSurfaceFormatCount = MIN2(*pSurfaceFormatCount, ARRAY_SIZE(formats)); - typed_memcpy(pSurfaceFormats, formats, *pSurfaceFormatCount); + return vk_outarray_status(&out); +} + +static VkResult +x11_surface_get_formats2(VkIcdSurfaceBase *surface, + struct wsi_device *wsi_device, + const void *info_next, + uint32_t *pSurfaceFormatCount, + VkSurfaceFormat2KHR *pSurfaceFormats) +{ + VK_OUTARRAY_MAKE(out, pSurfaceFormats, pSurfaceFormatCount); - return *pSurfaceFormatCount < ARRAY_SIZE(formats) ? - VK_INCOMPLETE : VK_SUCCESS; + for (unsigned i = 0; i < ARRAY_SIZE(formats); i++) { + vk_outarray_append(&out, f) { + assert(f->sType == VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR); + f->surfaceFormat.format = formats[i]; + f->surfaceFormat.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; + } + } + + return vk_outarray_status(&out); } static VkResult @@ -584,10 +615,7 @@ VkResult wsi_create_xlib_surface(const VkAllocationCallbacks *pAllocator, } struct x11_image { - VkImage image; - VkImage linear_image; // for prime - VkDeviceMemory memory; - VkDeviceMemory linear_memory; // for prime + struct wsi_image base; xcb_pixmap_t pixmap; bool busy; struct xshmfence * shm_fence; @@ -597,6 +625,8 @@ struct x11_image { struct x11_swapchain { struct wsi_swapchain base; + bool use_prime_blit; + xcb_connection_t * conn; xcb_window_t window; xcb_gc_t gc; @@ -618,39 +648,11 @@ struct x11_swapchain { struct x11_image images[0]; }; -static VkResult -x11_get_images(struct wsi_swapchain *anv_chain, - uint32_t* pCount, VkImage *pSwapchainImages) -{ - struct x11_swapchain *chain = (struct x11_swapchain *)anv_chain; - uint32_t ret_count; - VkResult result; - - if (pSwapchainImages == NULL) { - *pCount = chain->base.image_count; - return VK_SUCCESS; - } - - result = VK_SUCCESS; - ret_count = chain->base.image_count; - if (chain->base.image_count > *pCount) { - ret_count = *pCount; - result = VK_INCOMPLETE; - } - - for (uint32_t i = 0; i < ret_count; i++) - pSwapchainImages[i] = chain->images[i].image; - - return result; -} - -static void -x11_get_image_and_linear(struct wsi_swapchain *drv_chain, - int imageIndex, VkImage *image, VkImage *linear_image) +static struct wsi_image * +x11_get_wsi_image(struct wsi_swapchain *wsi_chain, uint32_t image_index) { - struct x11_swapchain *chain = (struct x11_swapchain *)drv_chain; - *image = chain->images[imageIndex].image; - *linear_image = chain->images[imageIndex].linear_image; + struct x11_swapchain *chain = (struct x11_swapchain *)wsi_chain; + return &chain->images[image_index].base; } static VkResult @@ -860,10 +862,24 @@ x11_acquire_next_image(struct wsi_swapchain *anv_chain, static VkResult x11_queue_present(struct wsi_swapchain *anv_chain, + VkQueue queue, + uint32_t waitSemaphoreCount, + const VkSemaphore *pWaitSemaphores, uint32_t image_index, const VkPresentRegionKHR *damage) { struct x11_swapchain *chain = (struct x11_swapchain *)anv_chain; + VkResult result; + + if (chain->use_prime_blit) { + result = wsi_prime_image_blit_to_linear(&chain->base, + &chain->images[image_index].base, + queue, + waitSemaphoreCount, + pWaitSemaphores); + if (result != VK_SUCCESS) + return result; + } if (chain->threaded) { wsi_queue_push(&chain->present_queue, image_index); @@ -908,6 +924,7 @@ x11_manage_fifo_queues(void *state) goto fail; result = x11_handle_dri3_present_event(chain, (void *)event); + free(event); if (result != VK_SUCCESS) goto fail; } @@ -928,44 +945,15 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain, { xcb_void_cookie_t cookie; VkResult result; - uint32_t row_pitch; - uint32_t offset; uint32_t bpp = 32; - int fd; - uint32_t size; - - result = chain->base.image_fns->create_wsi_image(device_h, - pCreateInfo, - pAllocator, - chain->base.needs_linear_copy, - false, - &image->image, - &image->memory, - &size, - &offset, - &row_pitch, - &fd); - if (result != VK_SUCCESS) - return result; - if (chain->base.needs_linear_copy) { - result = chain->base.image_fns->create_wsi_image(device_h, - pCreateInfo, - pAllocator, - chain->base.needs_linear_copy, - true, - &image->linear_image, - &image->linear_memory, - &size, - &offset, - &row_pitch, - &fd); - if (result != VK_SUCCESS) { - chain->base.image_fns->free_wsi_image(device_h, pAllocator, - image->image, image->memory); - return result; - } + if (chain->use_prime_blit) { + result = wsi_create_prime_image(&chain->base, pCreateInfo, &image->base); + } else { + result = wsi_create_native_image(&chain->base, pCreateInfo, &image->base); } + if (result != VK_SUCCESS) + return result; image->pixmap = xcb_generate_id(chain->conn); @@ -973,12 +961,14 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain, xcb_dri3_pixmap_from_buffer_checked(chain->conn, image->pixmap, chain->window, - size, + image->base.size, pCreateInfo->imageExtent.width, pCreateInfo->imageExtent.height, - row_pitch, - chain->depth, bpp, fd); + image->base.row_pitch, + chain->depth, bpp, + image->base.fd); xcb_discard_reply(chain->conn, cookie.sequence); + image->base.fd = -1; /* XCB has now taken ownership of the FD */ int fence_fd = xshmfence_alloc_shm(); if (fence_fd < 0) @@ -1007,12 +997,7 @@ fail_pixmap: cookie = xcb_free_pixmap(chain->conn, image->pixmap); xcb_discard_reply(chain->conn, cookie.sequence); - if (chain->base.needs_linear_copy) { - chain->base.image_fns->free_wsi_image(device_h, pAllocator, - image->linear_image, image->linear_memory); - } - chain->base.image_fns->free_wsi_image(device_h, pAllocator, - image->image, image->memory); + wsi_destroy_image(&chain->base, &image->base); return result; } @@ -1031,12 +1016,7 @@ x11_image_finish(struct x11_swapchain *chain, cookie = xcb_free_pixmap(chain->conn, image->pixmap); xcb_discard_reply(chain->conn, cookie.sequence); - if (chain->base.needs_linear_copy) { - chain->base.image_fns->free_wsi_image(chain->base.device, pAllocator, - image->linear_image, image->linear_memory); - } - chain->base.image_fns->free_wsi_image(chain->base.device, pAllocator, - image->image, image->memory); + wsi_destroy_image(&chain->base, &image->base); } static VkResult @@ -1064,6 +1044,8 @@ x11_swapchain_destroy(struct wsi_swapchain *anv_chain, XCB_PRESENT_EVENT_MASK_NO_EVENT); xcb_discard_reply(chain->conn, cookie.sequence); + wsi_swapchain_finish(&chain->base); + vk_free(pAllocator, chain); return VK_SUCCESS; @@ -1076,7 +1058,6 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, int local_fd, const VkSwapchainCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks* pAllocator, - const struct wsi_image_fns *image_fns, struct wsi_swapchain **swapchain_out) { struct x11_swapchain *chain; @@ -1087,43 +1068,47 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, const unsigned num_images = pCreateInfo->minImageCount; - size_t size = sizeof(*chain) + num_images * sizeof(chain->images[0]); - chain = vk_alloc(pAllocator, size, 8, - VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); - if (chain == NULL) - return VK_ERROR_OUT_OF_HOST_MEMORY; - + /* Check for whether or not we have a window up-front */ xcb_connection_t *conn = x11_surface_get_connection(icd_surface); xcb_window_t window = x11_surface_get_window(icd_surface); xcb_get_geometry_reply_t *geometry = xcb_get_geometry_reply(conn, xcb_get_geometry(conn, window), NULL); - if (geometry == NULL) return VK_ERROR_SURFACE_LOST_KHR; + const uint32_t bit_depth = geometry->depth; + free(geometry); + + size_t size = sizeof(*chain) + num_images * sizeof(chain->images[0]); + chain = vk_alloc(pAllocator, size, 8, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (chain == NULL) + return VK_ERROR_OUT_OF_HOST_MEMORY; + + result = wsi_swapchain_init(wsi_device, &chain->base, device, + pCreateInfo, pAllocator); + if (result != VK_SUCCESS) + goto fail_alloc; - chain->base.device = device; chain->base.destroy = x11_swapchain_destroy; - chain->base.get_images = x11_get_images; - chain->base.get_image_and_linear = x11_get_image_and_linear; + chain->base.get_wsi_image = x11_get_wsi_image; chain->base.acquire_next_image = x11_acquire_next_image; chain->base.queue_present = x11_queue_present; - chain->base.image_fns = image_fns; chain->base.present_mode = pCreateInfo->presentMode; chain->base.image_count = num_images; chain->conn = conn; chain->window = window; - chain->depth = geometry->depth; + chain->depth = bit_depth; chain->extent = pCreateInfo->imageExtent; chain->send_sbc = 0; chain->last_present_msc = 0; chain->threaded = false; chain->status = VK_SUCCESS; - free(geometry); - chain->base.needs_linear_copy = false; - if (!wsi_x11_check_dri3_compatible(conn, local_fd)) - chain->base.needs_linear_copy = true; + chain->use_prime_blit = false; + if (!wsi_x11_check_dri3_compatible(conn, local_fd)) { + chain->use_prime_blit = true; + } chain->event_id = xcb_generate_id(chain->conn); xcb_present_select_input(chain->conn, chain->event_id, chain->window, @@ -1202,6 +1187,9 @@ fail_init_images: fail_register: xcb_unregister_for_special_event(chain->conn, chain->special_event); + wsi_swapchain_finish(&chain->base); + +fail_alloc: vk_free(pAllocator, chain); return result; @@ -1242,7 +1230,9 @@ wsi_x11_init_wsi(struct wsi_device *wsi_device, wsi->base.get_support = x11_surface_get_support; wsi->base.get_capabilities = x11_surface_get_capabilities; + wsi->base.get_capabilities2 = x11_surface_get_capabilities2; wsi->base.get_formats = x11_surface_get_formats; + wsi->base.get_formats2 = x11_surface_get_formats2; wsi->base.get_present_modes = x11_surface_get_present_modes; wsi->base.create_swapchain = x11_surface_create_swapchain;