101e04c3fSmrg/*
201e04c3fSmrg * Copyright © 2017 Keith Packard
301e04c3fSmrg *
401e04c3fSmrg * Permission to use, copy, modify, distribute, and sell this software and its
501e04c3fSmrg * documentation for any purpose is hereby granted without fee, provided that
601e04c3fSmrg * the above copyright notice appear in all copies and that both that copyright
701e04c3fSmrg * notice and this permission notice appear in supporting documentation, and
801e04c3fSmrg * that the name of the copyright holders not be used in advertising or
901e04c3fSmrg * publicity pertaining to distribution of the software without specific,
1001e04c3fSmrg * written prior permission.  The copyright holders make no representations
1101e04c3fSmrg * about the suitability of this software for any purpose.  It is provided "as
1201e04c3fSmrg * is" without express or implied warranty.
1301e04c3fSmrg *
1401e04c3fSmrg * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
1501e04c3fSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
1601e04c3fSmrg * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
1701e04c3fSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
1801e04c3fSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
1901e04c3fSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
2001e04c3fSmrg * OF THIS SOFTWARE.
2101e04c3fSmrg */
2201e04c3fSmrg
237ec681f3Smrg#include <amdgpu.h>
247ec681f3Smrg#include <fcntl.h>
2501e04c3fSmrg#include <stdbool.h>
2601e04c3fSmrg#include <string.h>
2701e04c3fSmrg#include <unistd.h>
2801e04c3fSmrg#include <xf86drm.h>
2901e04c3fSmrg#include <xf86drmMode.h>
307ec681f3Smrg#include "drm-uapi/amdgpu_drm.h"
317ec681f3Smrg#include "util/debug.h"
327ec681f3Smrg#include "util/disk_cache.h"
337ec681f3Smrg#include "util/strtod.h"
3401e04c3fSmrg#include "winsys/amdgpu/radv_amdgpu_winsys_public.h"
357ec681f3Smrg#include "radv_cs.h"
367ec681f3Smrg#include "radv_private.h"
3701e04c3fSmrg#include "sid.h"
387ec681f3Smrg#include "vk_format.h"
397ec681f3Smrg#include "vk_util.h"
4001e04c3fSmrg#include "wsi_common_display.h"
4101e04c3fSmrg
427ec681f3Smrg#define MM_PER_PIXEL (1.0 / 96.0 * 25.4)
4301e04c3fSmrg
4401e04c3fSmrg/* VK_EXT_display_control */
4501e04c3fSmrg
4601e04c3fSmrgVkResult
477ec681f3Smrgradv_RegisterDeviceEventEXT(VkDevice _device, const VkDeviceEventInfoEXT *device_event_info,
487ec681f3Smrg                            const VkAllocationCallbacks *allocator, VkFence *_fence)
4901e04c3fSmrg{
507ec681f3Smrg   RADV_FROM_HANDLE(radv_device, device, _device);
517ec681f3Smrg   VkResult ret;
527ec681f3Smrg   int fd;
5301e04c3fSmrg
547ec681f3Smrg   ret = radv_CreateFence(_device,
557ec681f3Smrg                          &(VkFenceCreateInfo){
567ec681f3Smrg                             .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
577ec681f3Smrg                             .pNext =
587ec681f3Smrg                                &(VkExportFenceCreateInfo){
597ec681f3Smrg                                   .sType = VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO,
607ec681f3Smrg                                   .handleTypes = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT,
617ec681f3Smrg                                },
627ec681f3Smrg                          },
637ec681f3Smrg                          allocator, _fence);
647ec681f3Smrg   if (ret != VK_SUCCESS)
657ec681f3Smrg      return ret;
6601e04c3fSmrg
677ec681f3Smrg   RADV_FROM_HANDLE(radv_fence, fence, *_fence);
6801e04c3fSmrg
697ec681f3Smrg   assert(fence->permanent.kind == RADV_FENCE_SYNCOBJ);
7001e04c3fSmrg
717ec681f3Smrg   if (device->ws->export_syncobj(device->ws, fence->permanent.syncobj, &fd)) {
727ec681f3Smrg      ret = VK_ERROR_OUT_OF_HOST_MEMORY;
737ec681f3Smrg   } else {
747ec681f3Smrg      ret = wsi_register_device_event(_device, &device->physical_device->wsi_device,
757ec681f3Smrg                                      device_event_info, allocator, NULL, fd);
767ec681f3Smrg      close(fd);
777ec681f3Smrg   }
7801e04c3fSmrg
797ec681f3Smrg   if (ret != VK_SUCCESS)
807ec681f3Smrg      radv_DestroyFence(_device, *_fence, allocator);
817ec681f3Smrg
827ec681f3Smrg   return ret;
8301e04c3fSmrg}
8401e04c3fSmrg
8501e04c3fSmrgVkResult
867ec681f3Smrgradv_RegisterDisplayEventEXT(VkDevice _device, VkDisplayKHR display,
877ec681f3Smrg                             const VkDisplayEventInfoEXT *display_event_info,
887ec681f3Smrg                             const VkAllocationCallbacks *allocator, VkFence *_fence)
8901e04c3fSmrg{
907ec681f3Smrg   RADV_FROM_HANDLE(radv_device, device, _device);
917ec681f3Smrg   VkResult ret;
927ec681f3Smrg   int fd;
9301e04c3fSmrg
947ec681f3Smrg   ret = radv_CreateFence(_device,
957ec681f3Smrg                          &(VkFenceCreateInfo){
967ec681f3Smrg                             .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
977ec681f3Smrg                             .pNext =
987ec681f3Smrg                                &(VkExportFenceCreateInfo){
997ec681f3Smrg                                   .sType = VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO,
1007ec681f3Smrg                                   .handleTypes = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT,
1017ec681f3Smrg                                },
1027ec681f3Smrg                          },
1037ec681f3Smrg                          allocator, _fence);
1047ec681f3Smrg   if (ret != VK_SUCCESS)
1057ec681f3Smrg      return ret;
10601e04c3fSmrg
1077ec681f3Smrg   RADV_FROM_HANDLE(radv_fence, fence, *_fence);
10801e04c3fSmrg
1097ec681f3Smrg   assert(fence->permanent.kind == RADV_FENCE_SYNCOBJ);
11001e04c3fSmrg
1117ec681f3Smrg   if (device->ws->export_syncobj(device->ws, fence->permanent.syncobj, &fd)) {
1127ec681f3Smrg      ret = VK_ERROR_OUT_OF_HOST_MEMORY;
1137ec681f3Smrg   } else {
1147ec681f3Smrg      ret = wsi_register_display_event(_device, &device->physical_device->wsi_device, display,
1157ec681f3Smrg                                       display_event_info, allocator, NULL, fd);
1167ec681f3Smrg      close(fd);
1177ec681f3Smrg   }
11801e04c3fSmrg
1197ec681f3Smrg   if (ret != VK_SUCCESS)
1207ec681f3Smrg      radv_DestroyFence(_device, *_fence, allocator);
12101e04c3fSmrg
1227ec681f3Smrg   return ret;
12301e04c3fSmrg}
124