X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fvulkan%2Fwsi%2Fwsi_common_display.c;h=66e191906fcbd2a24a89275bd07edbad8eaaeb0c;hb=cb7c9b2a9352cc73a2d3becc0427c53c8baf153a;hp=e99b0465ec9b6757d5d2cc3e633e7a1a6db84e24;hpb=ab80889e92e2a3c2884e5da925424f9f6a88979b;p=mesa.git diff --git a/src/vulkan/wsi/wsi_common_display.c b/src/vulkan/wsi/wsi_common_display.c index e99b0465ec9..66e191906fc 100644 --- a/src/vulkan/wsi/wsi_common_display.c +++ b/src/vulkan/wsi/wsi_common_display.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include "drm-uapi/drm_fourcc.h" #ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT #include #include @@ -96,7 +96,7 @@ struct wsi_display { pthread_cond_t wait_cond; pthread_t wait_thread; - struct list_head connectors; + struct list_head connectors; /* list of all discovered connectors */ }; #define wsi_for_each_display_mode(_mode, _conn) \ @@ -171,17 +171,9 @@ wsi_display_mode_refresh(struct wsi_display_mode *wsi) (double) MAX2(wsi->vscan, 1)); } -static uint64_t wsi_get_current_monotonic(void) -{ - struct timespec tv; - - clock_gettime(CLOCK_MONOTONIC, &tv); - return tv.tv_nsec + tv.tv_sec*1000000000ull; -} - static uint64_t wsi_rel_to_abs_time(uint64_t rel_time) { - uint64_t current_time = wsi_get_current_monotonic(); + uint64_t current_time = wsi_common_get_current_time(); /* check for overflow */ if (rel_time > UINT64_MAX - current_time) @@ -766,10 +758,27 @@ wsi_get_display_plane_capabilities2( assert(capabilities->sType == VK_STRUCTURE_TYPE_DISPLAY_PLANE_CAPABILITIES_2_KHR); - return wsi_get_display_plane_capabilities(physical_device, wsi_device, - pDisplayPlaneInfo->mode, - pDisplayPlaneInfo->planeIndex, - &capabilities->capabilities); + VkResult result = + wsi_get_display_plane_capabilities(physical_device, wsi_device, + pDisplayPlaneInfo->mode, + pDisplayPlaneInfo->planeIndex, + &capabilities->capabilities); + + vk_foreach_struct(ext, capabilities->pNext) { + switch (ext->sType) { + case VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR: { + VkSurfaceProtectedCapabilitiesKHR *protected = (void *)ext; + protected->supportsProtected = VK_FALSE; + break; + } + + default: + /* Ignored */ + break; + } + } + + return result; } VkResult @@ -802,9 +811,7 @@ wsi_create_display_surface(VkInstance instance, static VkResult wsi_display_surface_get_support(VkIcdSurfaceBase *surface, struct wsi_device *wsi_device, - const VkAllocationCallbacks *allocator, uint32_t queueFamilyIndex, - int local_fd, VkBool32* pSupported) { *pSupported = VK_TRUE; @@ -813,6 +820,7 @@ wsi_display_surface_get_support(VkIcdSurfaceBase *surface, static VkResult wsi_display_surface_get_capabilities(VkIcdSurfaceBase *surface_base, + struct wsi_device *wsi_device, VkSurfaceCapabilitiesKHR* caps) { VkIcdSurfaceDisplay *surface = (VkIcdSurfaceDisplay *) surface_base; @@ -821,8 +829,11 @@ wsi_display_surface_get_capabilities(VkIcdSurfaceBase *surface_base, caps->currentExtent.width = mode->hdisplay; caps->currentExtent.height = mode->vdisplay; - /* XXX Figure out extents based on driver capabilities */ - caps->maxImageExtent = caps->minImageExtent = caps->currentExtent; + caps->minImageExtent = (VkExtent2D) { 1, 1 }; + caps->maxImageExtent = (VkExtent2D) { + wsi_device->maxImageDimension2D, + wsi_device->maxImageDimension2D, + }; caps->supportedCompositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; @@ -836,6 +847,7 @@ wsi_display_surface_get_capabilities(VkIcdSurfaceBase *surface_base, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | + VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; return VK_SUCCESS; @@ -852,13 +864,14 @@ wsi_display_surface_get_surface_counters( static VkResult wsi_display_surface_get_capabilities2(VkIcdSurfaceBase *icd_surface, + struct wsi_device *wsi_device, const void *info_next, VkSurfaceCapabilities2KHR *caps) { assert(caps->sType == VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR); VkResult result; - result = wsi_display_surface_get_capabilities(icd_surface, + result = wsi_display_surface_get_capabilities(icd_surface, wsi_device, &caps->surfaceCapabilities); if (result != VK_SUCCESS) return result; @@ -935,12 +948,34 @@ wsi_display_surface_get_present_modes(VkIcdSurfaceBase *surface, return vk_outarray_status(&conn); } +static VkResult +wsi_display_surface_get_present_rectangles(VkIcdSurfaceBase *surface_base, + struct wsi_device *wsi_device, + uint32_t* pRectCount, + VkRect2D* pRects) +{ + VkIcdSurfaceDisplay *surface = (VkIcdSurfaceDisplay *) surface_base; + wsi_display_mode *mode = wsi_display_mode_from_handle(surface->displayMode); + VK_OUTARRAY_MAKE(out, pRects, pRectCount); + + if (wsi_device_matches_drm_fd(wsi_device, mode->connector->wsi->fd)) { + vk_outarray_append(&out, rect) { + *rect = (VkRect2D) { + .offset = { 0, 0 }, + .extent = { mode->hdisplay, mode->vdisplay }, + }; + } + } + + return vk_outarray_status(&out); +} + static void wsi_display_destroy_buffer(struct wsi_display *wsi, uint32_t buffer) { - (void) drmIoctl(wsi->fd, DRM_IOCTL_MODE_DESTROY_DUMB, - &((struct drm_mode_destroy_dumb) { .handle = buffer })); + (void) drmIoctl(wsi->fd, DRM_IOCTL_GEM_CLOSE, + &((struct drm_gem_close) { .handle = buffer })); } static VkResult @@ -1042,6 +1077,8 @@ wsi_display_swapchain_destroy(struct wsi_swapchain *drv_chain, for (uint32_t i = 0; i < chain->base.image_count; i++) wsi_display_image_finish(drv_chain, allocator, &chain->images[i]); + + wsi_swapchain_finish(&chain->base); vk_free(allocator, chain); return VK_SUCCESS; } @@ -1297,7 +1334,7 @@ wsi_display_crtc_solo(struct wsi_display *wsi, * which is currently idle. */ static uint32_t -wsi_display_select_crtc(struct wsi_display_connector *connector, +wsi_display_select_crtc(const struct wsi_display_connector *connector, drmModeResPtr mode_res, drmModeConnectorPtr drm_connector) { @@ -1408,8 +1445,8 @@ wsi_display_fence_wait(struct wsi_fence *fence_wsi, uint64_t timeout) wsi_display_debug("%9lu wait fence %lu %ld\n", pthread_self(), fence->sequence, - (int64_t) (timeout - wsi_get_current_monotonic())); - wsi_display_debug_code(uint64_t start_ns = wsi_get_current_monotonic()); + (int64_t) (timeout - wsi_common_get_current_time())); + wsi_display_debug_code(uint64_t start_ns = wsi_common_get_current_time()); pthread_mutex_lock(&wsi->wait_mutex); VkResult result; @@ -1441,7 +1478,7 @@ wsi_display_fence_wait(struct wsi_fence *fence_wsi, uint64_t timeout) pthread_mutex_unlock(&wsi->wait_mutex); wsi_display_debug("%9lu fence wait %f ms\n", pthread_self(), - ((int64_t) (wsi_get_current_monotonic() - start_ns)) / + ((int64_t) (wsi_common_get_current_time() - start_ns)) / 1.0e6); return result; } @@ -1691,7 +1728,6 @@ wsi_display_surface_create_swapchain( VkIcdSurfaceBase *icd_surface, VkDevice device, struct wsi_device *wsi_device, - int local_fd, const VkSwapchainCreateInfoKHR *create_info, const VkAllocationCallbacks *allocator, struct wsi_swapchain **swapchain_out) @@ -1712,12 +1748,16 @@ wsi_display_surface_create_swapchain( VkResult result = wsi_swapchain_init(wsi_device, &chain->base, device, create_info, allocator); + if (result != VK_SUCCESS) { + vk_free(allocator, chain); + return result; + } chain->base.destroy = wsi_display_swapchain_destroy; chain->base.get_wsi_image = wsi_display_get_wsi_image; chain->base.acquire_next_image = wsi_display_acquire_next_image; chain->base.queue_present = wsi_display_queue_present; - chain->base.present_mode = create_info->presentMode; + chain->base.present_mode = wsi_swapchain_get_present_mode(wsi_device, create_info); chain->base.image_count = num_images; chain->wsi = wsi; @@ -1772,6 +1812,30 @@ fail_attr_init: return ret; } + +/* + * Local version fo the libdrm helper. Added to avoid depending on bleeding + * edge version of the library. + */ +static int +local_drmIsMaster(int fd) +{ + /* Detect master by attempting something that requires master. + * + * Authenticating magic tokens requires master and 0 is an + * internal kernel detail which we could use. Attempting this on + * a master fd would fail therefore fail with EINVAL because 0 + * is invalid. + * + * A non-master fd will fail with EACCES, as the kernel checks + * for master before attempting to do anything else. + * + * Since we don't want to leak implementation details, use + * EACCES. + */ + return drmAuthMagic(fd, 0) != -EACCES; +} + VkResult wsi_display_init_wsi(struct wsi_device *wsi_device, const VkAllocationCallbacks *alloc, @@ -1787,6 +1851,9 @@ wsi_display_init_wsi(struct wsi_device *wsi_device, } wsi->fd = display_fd; + if (wsi->fd != -1 && !local_drmIsMaster(wsi->fd)) + wsi->fd = -1; + wsi->alloc = alloc; list_inithead(&wsi->connectors); @@ -1807,6 +1874,7 @@ wsi_display_init_wsi(struct wsi_device *wsi_device, wsi->base.get_formats = wsi_display_surface_get_formats; wsi->base.get_formats2 = wsi_display_surface_get_formats2; wsi->base.get_present_modes = wsi_display_surface_get_present_modes; + wsi->base.get_present_rectangles = wsi_display_surface_get_present_rectangles; wsi->base.create_swapchain = wsi_display_surface_create_swapchain; wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY] = &wsi->base; @@ -2304,6 +2372,7 @@ wsi_acquire_xlib_display(VkPhysicalDevice physical_device, if (!crtc) return VK_ERROR_INITIALIZATION_FAILED; +#ifdef HAVE_DRI3_MODIFIERS xcb_randr_lease_t lease = xcb_generate_id(connection); xcb_randr_create_lease_cookie_t cl_c = xcb_randr_create_lease(connection, root, lease, 1, 1, @@ -2324,6 +2393,7 @@ wsi_acquire_xlib_display(VkPhysicalDevice physical_device, return VK_ERROR_INITIALIZATION_FAILED; wsi->fd = fd; +#endif return VK_SUCCESS; }