From patchwork Wed Feb 14 00:31:27 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Packard X-Patchwork-Id: 10217823 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 29B3B60216 for ; Wed, 14 Feb 2018 00:33:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1BF6228F08 for ; Wed, 14 Feb 2018 00:33:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1092128F0A; Wed, 14 Feb 2018 00:33:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 841EB28F08 for ; Wed, 14 Feb 2018 00:33:57 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id E2A5E6E3A5; Wed, 14 Feb 2018 00:32:04 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from elaine.keithp.com (home.keithp.com [63.227.221.253]) by gabe.freedesktop.org (Postfix) with ESMTP id C5F876E31E; Wed, 14 Feb 2018 00:31:43 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by elaine.keithp.com (Postfix) with ESMTP id 9C6883F205D3; Tue, 13 Feb 2018 16:31:43 -0800 (PST) X-Virus-Scanned: Debian amavisd-new at keithp.com Received: from elaine.keithp.com ([127.0.0.1]) by localhost (elaine.keithp.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id Ehd9AguIhHTs; Tue, 13 Feb 2018 16:31:43 -0800 (PST) Received: from keithp.com (koto.keithp.com [10.0.0.2]) by elaine.keithp.com (Postfix) with ESMTPSA id 5E6243F21500; Tue, 13 Feb 2018 16:31:35 -0800 (PST) Received: by keithp.com (Postfix, from userid 1000) id 3BA0615829F9; Tue, 13 Feb 2018 16:31:35 -0800 (PST) From: Keith Packard To: mesa-dev@lists.freedesktop.org Subject: [PATCH 14/21] anv: add VK_EXT_display_control to anv driver Date: Tue, 13 Feb 2018 16:31:27 -0800 Message-Id: <20180214003134.1552-15-keithp@keithp.com> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180214003134.1552-1-keithp@keithp.com> References: <20180214003134.1552-1-keithp@keithp.com> X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Keith Packard , dri-devel@lists.freedesktop.org MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP This extension provides fences and frame count information to direct display contexts. It uses new kernel ioctls to provide 64-bits of vblank sequence and nanosecond resolution. Signed-off-by: Keith Packard --- src/intel/vulkan/anv_extensions.py | 1 + src/intel/vulkan/anv_private.h | 4 ++ src/intel/vulkan/anv_queue.c | 59 ++++++++++++++++++--- src/intel/vulkan/anv_wsi_display.c | 103 +++++++++++++++++++++++++++++++++++++ 4 files changed, 160 insertions(+), 7 deletions(-) diff --git a/src/intel/vulkan/anv_extensions.py b/src/intel/vulkan/anv_extensions.py index 32643e31045..1c6c4f8e27b 100644 --- a/src/intel/vulkan/anv_extensions.py +++ b/src/intel/vulkan/anv_extensions.py @@ -90,6 +90,7 @@ EXTENSIONS = [ Extension('VK_EXT_debug_report', 8, True), Extension('VK_EXT_external_memory_dma_buf', 1, True), Extension('VK_EXT_display_surface_counter', 1, 'VK_USE_PLATFORM_DISPLAY_KHR'), + Extension('VK_EXT_display_control', 1, 'VK_USE_PLATFORM_DISPLAY_KHR'), ] class VkVersion: diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index d38dd9e4220..1d3e5fcd921 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -1941,6 +1941,7 @@ enum anv_fence_type { ANV_FENCE_TYPE_NONE = 0, ANV_FENCE_TYPE_BO, ANV_FENCE_TYPE_SYNCOBJ, + ANV_FENCE_TYPE_WSI, }; enum anv_bo_fence_state { @@ -1975,6 +1976,9 @@ struct anv_fence_impl { /** DRM syncobj handle for syncobj-based fences */ uint32_t syncobj; + + /** WSI fence */ + struct wsi_fence *fence_wsi; }; }; diff --git a/src/intel/vulkan/anv_queue.c b/src/intel/vulkan/anv_queue.c index c6b2e01c628..d0bfad742d7 100644 --- a/src/intel/vulkan/anv_queue.c +++ b/src/intel/vulkan/anv_queue.c @@ -320,6 +320,10 @@ anv_fence_impl_cleanup(struct anv_device *device, case ANV_FENCE_TYPE_SYNCOBJ: anv_gem_syncobj_destroy(device, impl->syncobj); return; + + case ANV_FENCE_TYPE_WSI: + impl->fence_wsi->destroy(impl->fence_wsi); + return; } unreachable("Invalid fence type"); @@ -465,11 +469,32 @@ anv_wait_for_syncobj_fences(struct anv_device *device, uint32_t *syncobjs = vk_zalloc(&device->alloc, sizeof(*syncobjs) * fenceCount, 8, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); + uint32_t syncobjCount = 0; if (!syncobjs) return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); for (uint32_t i = 0; i < fenceCount; i++) { ANV_FROM_HANDLE(anv_fence, fence, pFences[i]); + + if (fence->permanent.type == ANV_FENCE_TYPE_WSI) { + struct anv_fence_impl *impl = &fence->permanent; + bool expired = impl->fence_wsi->wait(impl->fence_wsi, true, _timeout); + + VkResult result; + + if (!expired) { + result = VK_TIMEOUT; + goto done; + } + if (!waitAll) { + result = VK_SUCCESS; + goto done; + } + continue; + done: + vk_free(&device->alloc, syncobjs); + return result; + } assert(fence->permanent.type == ANV_FENCE_TYPE_SYNCOBJ); struct anv_fence_impl *impl = @@ -477,7 +502,7 @@ anv_wait_for_syncobj_fences(struct anv_device *device, &fence->temporary : &fence->permanent; assert(impl->type == ANV_FENCE_TYPE_SYNCOBJ); - syncobjs[i] = impl->syncobj; + syncobjs[syncobjCount++] = impl->syncobj; } int64_t abs_timeout_ns = 0; @@ -499,7 +524,7 @@ anv_wait_for_syncobj_fences(struct anv_device *device, */ int ret; do { - ret = anv_gem_syncobj_wait(device, syncobjs, fenceCount, + ret = anv_gem_syncobj_wait(device, syncobjs, syncobjCount, abs_timeout_ns, waitAll); } while (ret == -1 && errno == ETIME && gettime_ns() < abs_timeout_ns); @@ -545,14 +570,33 @@ anv_wait_for_bo_fences(struct anv_device *device, for (uint32_t i = 0; i < fenceCount; i++) { ANV_FROM_HANDLE(anv_fence, fence, pFences[i]); - /* This function assumes that all fences are BO fences and that they - * have no temporary state. Since BO fences will never be exported, - * this should be a safe assumption. + /* This function assumes that all fences have no temporary + * state.Since BO fences will never be exported, this should be a + * safe assumption. */ - assert(fence->permanent.type == ANV_FENCE_TYPE_BO); assert(fence->temporary.type == ANV_FENCE_TYPE_NONE); struct anv_fence_impl *impl = &fence->permanent; + /* This function assumes that all fences are either BO fences or WSI + * fences + */ + + if (impl->type == ANV_FENCE_TYPE_WSI) { + bool expired = impl->fence_wsi->wait(impl->fence_wsi, true, timeout); + + if (!expired) { + result = VK_TIMEOUT; + goto done; + } + if (!waitAll) { + result = VK_SUCCESS; + goto done; + } + continue; + } + + assert(impl->type == ANV_FENCE_TYPE_BO); + switch (impl->bo.state) { case ANV_BO_FENCE_STATE_RESET: /* This fence hasn't been submitted yet, we'll catch it the next @@ -610,7 +654,8 @@ anv_wait_for_bo_fences(struct anv_device *device, uint32_t now_pending_fences = 0; for (uint32_t i = 0; i < fenceCount; i++) { ANV_FROM_HANDLE(anv_fence, fence, pFences[i]); - if (fence->permanent.bo.state == ANV_BO_FENCE_STATE_RESET) + if (fence->permanent.type == ANV_FENCE_TYPE_BO && + fence->permanent.bo.state == ANV_BO_FENCE_STATE_RESET) now_pending_fences++; } assert(now_pending_fences <= pending_fences); diff --git a/src/intel/vulkan/anv_wsi_display.c b/src/intel/vulkan/anv_wsi_display.c index e87aed49f7d..32a948d76ca 100644 --- a/src/intel/vulkan/anv_wsi_display.c +++ b/src/intel/vulkan/anv_wsi_display.c @@ -168,3 +168,106 @@ anv_GetRandROutputDisplayEXT(VkPhysicalDevice physical_device, display); } #endif /* VK_USE_PLATFORM_XLIB_XRANDR_EXT */ + +/* VK_EXT_display_control */ + +VkResult +anv_DisplayPowerControlEXT(VkDevice _device, + VkDisplayKHR display, + const VkDisplayPowerInfoEXT *display_power_info) +{ + ANV_FROM_HANDLE(anv_device, device, _device); + + return wsi_display_power_control(_device, + &device->instance->physicalDevice.wsi_device, + display, + display_power_info); +} + +VkResult +anv_RegisterDeviceEventEXT(VkDevice _device, + const VkDeviceEventInfoEXT *device_event_info, + const VkAllocationCallbacks *allocator, + VkFence *_fence) +{ + ANV_FROM_HANDLE(anv_device, device, _device); + const VkAllocationCallbacks *alloc; + struct anv_fence *fence; + VkResult ret; + + if (allocator) + alloc = allocator; + else + alloc = &device->instance->alloc; + + fence = vk_alloc(alloc, sizeof (*fence), 8, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (!fence) + return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); + + fence->permanent.type = ANV_FENCE_TYPE_WSI; + + ret = wsi_register_device_event(_device, + &device->instance->physicalDevice.wsi_device, + device_event_info, + alloc, + &fence->permanent.fence_wsi); + if (ret == VK_SUCCESS) + *_fence = anv_fence_to_handle(fence); + else + vk_free(alloc, fence); + return ret; +} + +VkResult +anv_RegisterDisplayEventEXT(VkDevice _device, + VkDisplayKHR display, + const VkDisplayEventInfoEXT *display_event_info, + const VkAllocationCallbacks *allocator, + VkFence *_fence) +{ + ANV_FROM_HANDLE(anv_device, device, _device); + const VkAllocationCallbacks *alloc; + struct anv_fence *fence; + VkResult ret; + + if (allocator) + alloc = allocator; + else + alloc = &device->instance->alloc; + + fence = vk_zalloc2(&device->alloc, allocator, sizeof (*fence), 8, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (!fence) + return VK_ERROR_OUT_OF_HOST_MEMORY; + + fence->permanent.type = ANV_FENCE_TYPE_WSI; + + ret = wsi_register_display_event(_device, + &device->instance->physicalDevice.wsi_device, + display, + display_event_info, + alloc, + &(fence->permanent.fence_wsi)); + + if (ret == VK_SUCCESS) + *_fence = anv_fence_to_handle(fence); + else + vk_free(alloc, fence); + return ret; +} + +VkResult +anv_GetSwapchainCounterEXT(VkDevice _device, + VkSwapchainKHR swapchain, + VkSurfaceCounterFlagBitsEXT flag_bits, + uint64_t *value) +{ + ANV_FROM_HANDLE(anv_device, device, _device); + + return wsi_get_swapchain_counter(_device, + &device->instance->physicalDevice.wsi_device, + swapchain, + flag_bits, + value); +}