zink: add dri loader
authorDave Airlie <airlied@redhat.com>
Tue, 2 Oct 2018 22:27:36 +0000 (23:27 +0100)
committerErik Faye-Lund <erik.faye-lund@collabora.com>
Mon, 28 Oct 2019 08:51:43 +0000 (08:51 +0000)
export MESA_LOADER_DRIVER_OVERRIDE=zink should now work without using
swrast paths

Acked-by: Jordan Justen <jordan.l.justen@intel.com>
src/gallium/auxiliary/pipe-loader/pipe_loader_drm.c
src/gallium/auxiliary/target-helpers/drm_helper.h
src/gallium/auxiliary/target-helpers/drm_helper_public.h
src/gallium/drivers/zink/zink_context.c
src/gallium/drivers/zink/zink_public.h
src/gallium/drivers/zink/zink_resource.c
src/gallium/drivers/zink/zink_screen.c
src/gallium/drivers/zink/zink_screen.h
src/gallium/targets/dri/target.c

index 3b9b39f62a3b9d982c0e8b8c54275f4db25d7b71..2e1bff4c233caf8b2efa658917c3354bb0b98483 100644 (file)
@@ -135,6 +135,10 @@ static const struct drm_driver_descriptor driver_descriptors[] = {
         .driver_name = "lima",
         .create_screen = pipe_lima_create_screen,
     },
+    {
+        .driver_name = "zink",
+        .create_screen = pipe_zink_create_screen,
+    },
 };
 
 static const struct drm_driver_descriptor default_driver_descriptor = {
index 6c5902d3c27982266a690841520d4db6f9aa9fd0..01b65d6c7f845f19b4a8dc4053a61741c1967249 100644 (file)
@@ -414,4 +414,26 @@ pipe_lima_create_screen(int fd, const struct pipe_screen_config *config)
 
 #endif
 
+#ifdef GALLIUM_ZINK
+#include "zink/zink_public.h"
+
+struct pipe_screen *
+pipe_zink_create_screen(int fd, const struct pipe_screen_config *config)
+{
+   struct pipe_screen *screen;
+   screen = zink_drm_create_screen(fd);
+   return screen ? debug_screen_wrap(screen) : NULL;
+}
+
+#else
+
+struct pipe_screen *
+pipe_zink_create_screen(int fd, const struct pipe_screen_config *config)
+{
+   fprintf(stderr, "zink: driver missing\n");
+   return NULL;
+}
+
+#endif
+
 #endif /* DRM_HELPER_H */
index 99018f0df88dcd48a3e127a754a0ea20b6b0d8e1..82dfe9e257552fa8f3d2cad975138255ce2aecaf 100644 (file)
@@ -60,4 +60,8 @@ pipe_tegra_create_screen(int fd, const struct pipe_screen_config *config);
 struct pipe_screen *
 pipe_lima_create_screen(int fd, const struct pipe_screen_config *config);
 
+struct pipe_screen *
+pipe_zink_create_screen(int fd, const struct pipe_screen_config *config);
+
+
 #endif /* _DRM_HELPER_PUBLIC_H */
index 785666f8bb88d1ed871c520efba3bb19dd1183c7..5b3f2d5263d1e27e229b69e97f45366fccb3909f 100644 (file)
@@ -1031,6 +1031,12 @@ zink_blit(struct pipe_context *pctx,
    zink_end_cmdbuf(ctx, cmdbuf);
 }
 
+static void
+zink_flush_resource(struct pipe_context *pipe,
+                    struct pipe_resource *resource)
+{
+}
+
 static void
 zink_resource_copy_region(struct pipe_context *pctx,
                           struct pipe_resource *pdst,
@@ -1134,6 +1140,7 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
    ctx->base.resource_copy_region = zink_resource_copy_region;
    ctx->base.blit = zink_blit;
 
+   ctx->base.flush_resource = zink_flush_resource;
    zink_context_surface_init(&ctx->base);
    zink_context_resource_init(&ctx->base);
 
index 5652c56a45e3e90ab53e61d1f4fca0c6ad183f15..be772f51ee8cf59789f6af64ae884c7d95394bc6 100644 (file)
@@ -30,4 +30,6 @@ struct sw_winsys;
 struct pipe_screen *
 zink_create_screen(struct sw_winsys *winsys);
 
+struct pipe_screen *
+zink_drm_create_screen(int fd);
 #endif
index 297b1c1feef0c6d8e53641d9a64371f5b8836ca9..50b7604a891a60fd1d5985a94cf5985c1b107d15 100644 (file)
@@ -229,7 +229,7 @@ zink_resource_create(struct pipe_screen *pscreen,
       res->aspect = zink_aspect_from_format(templ->format);
 
       vkGetImageMemoryRequirements(screen->dev, res->image, &reqs);
-      if (templ->usage == PIPE_USAGE_STAGING || (templ->bind & (PIPE_BIND_SCANOUT|PIPE_BIND_DISPLAY_TARGET|PIPE_BIND_SHARED)))
+      if (templ->usage == PIPE_USAGE_STAGING || (screen->winsys && (templ->bind & (PIPE_BIND_SCANOUT|PIPE_BIND_DISPLAY_TARGET|PIPE_BIND_SHARED))))
         flags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
       else
         flags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
@@ -240,6 +240,13 @@ zink_resource_create(struct pipe_screen *pscreen,
    mai.allocationSize = reqs.size;
    mai.memoryTypeIndex = get_memory_type_index(screen, &reqs, flags);
 
+   VkExportMemoryAllocateInfo emai = {};
+   if (templ->bind & PIPE_BIND_SHARED) {
+      emai.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO;
+      emai.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
+      mai.pNext = &emai;
+   }
+
    if (vkAllocateMemory(screen->dev, &mai, NULL, &res->mem) != VK_SUCCESS)
       goto fail;
 
@@ -251,9 +258,9 @@ zink_resource_create(struct pipe_screen *pscreen,
    else
       vkBindImageMemory(screen->dev, res->image, res->mem, res->offset);
 
-   if (templ->bind & (PIPE_BIND_DISPLAY_TARGET |
-                      PIPE_BIND_SCANOUT |
-                      PIPE_BIND_SHARED)) {
+   if (screen->winsys && (templ->bind & (PIPE_BIND_DISPLAY_TARGET |
+                                         PIPE_BIND_SCANOUT |
+                                         PIPE_BIND_SHARED))) {
       struct sw_winsys *winsys = screen->winsys;
       res->dt = winsys->displaytarget_create(screen->winsys,
                                              res->base.bind,
@@ -277,11 +284,52 @@ fail:
    return NULL;
 }
 
+static bool
+zink_resource_get_handle(struct pipe_screen *pscreen,
+                         struct pipe_context *context,
+                         struct pipe_resource *tex,
+                         struct winsys_handle *whandle,
+                         unsigned usage)
+{
+   struct zink_resource *res = zink_resource(tex);
+   struct zink_screen *screen = zink_screen(pscreen);
+   VkMemoryGetFdInfoKHR fd_info = {};
+   int fd;
+
+   if (res->base.target != PIPE_BUFFER) {
+      VkImageSubresource sub_res = {};
+      VkSubresourceLayout sub_res_layout = {};
+
+      sub_res.aspectMask = res->aspect;
+
+      vkGetImageSubresourceLayout(screen->dev, res->image, &sub_res, &sub_res_layout);
+
+      whandle->stride = sub_res_layout.rowPitch;
+   }
+
+   if (whandle->type == WINSYS_HANDLE_TYPE_FD) {
+
+      if (!screen->vk_GetMemoryFdKHR)
+         screen->vk_GetMemoryFdKHR = (PFN_vkGetMemoryFdKHR)vkGetDeviceProcAddr(screen->dev, "vkGetMemoryFdKHR");
+      if (!screen->vk_GetMemoryFdKHR)
+         return false;
+      fd_info.sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR;
+      fd_info.memory = res->mem;
+      fd_info.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
+      VkResult result = (*screen->vk_GetMemoryFdKHR)(screen->dev, &fd_info, &fd);
+      if (result != VK_SUCCESS)
+         return false;
+      whandle->handle = fd;
+   }
+   return true;
+}
+
 void
 zink_screen_resource_init(struct pipe_screen *pscreen)
 {
    pscreen->resource_create = zink_resource_create;
    pscreen->resource_destroy = zink_resource_destroy;
+   pscreen->resource_get_handle = zink_resource_get_handle;
 }
 
 static bool
index 5f8bbfd9f058dc00d777db7cf128fcefe5550bed..b50f2f5d0307b38f72f0eae932be55de6f2ab4d3 100644 (file)
@@ -595,9 +595,16 @@ create_instance()
    ai.pEngineName = "mesa zink";
    ai.apiVersion = VK_API_VERSION_1_0;
 
+   const char *extensions[] = {
+      VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
+      VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME,
+   };
+
    VkInstanceCreateInfo ici = {};
    ici.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
    ici.pApplicationInfo = &ai;
+   ici.ppEnabledExtensionNames = extensions;
+   ici.enabledExtensionCount = ARRAY_SIZE(extensions);
 
    VkInstance instance = VK_NULL_HANDLE;
    VkResult err = vkCreateInstance(&ici, NULL, &instance);
@@ -663,6 +670,8 @@ zink_flush_frontbuffer(struct pipe_screen *pscreen,
    struct sw_winsys *winsys = screen->winsys;
    struct zink_resource *res = zink_resource(pres);
 
+   if (!winsys)
+     return;
    void *map = winsys->displaytarget_map(winsys, res->dt, 0);
 
    if (map) {
@@ -694,8 +703,8 @@ zink_flush_frontbuffer(struct pipe_screen *pscreen,
       winsys->displaytarget_display(winsys, res->dt, winsys_drawable_handle, sub_box);
 }
 
-struct pipe_screen *
-zink_create_screen(struct sw_winsys *winsys)
+static struct pipe_screen *
+zink_internal_create_screen(struct sw_winsys *winsys, int fd)
 {
    struct zink_screen *screen = CALLOC_STRUCT(zink_screen);
    if (!screen)
@@ -742,7 +751,9 @@ zink_create_screen(struct sw_winsys *winsys)
    dci.pQueueCreateInfos = &qci;
    dci.pEnabledFeatures = &screen->feats;
    const char *extensions[] = {
-      VK_KHR_MAINTENANCE1_EXTENSION_NAME
+      VK_KHR_MAINTENANCE1_EXTENSION_NAME,
+      VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,
+      VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
    };
    dci.ppEnabledExtensionNames = extensions;
    dci.enabledExtensionCount = ARRAY_SIZE(extensions);
@@ -774,3 +785,15 @@ fail:
    FREE(screen);
    return NULL;
 }
+
+struct pipe_screen *
+zink_create_screen(struct sw_winsys *winsys)
+{
+   return zink_internal_create_screen(winsys, -1);
+}
+
+struct pipe_screen *
+zink_drm_create_screen(int fd)
+{
+   return zink_internal_create_screen(NULL, fd);
+}
index ab20a683f88f842085bcbf3510efb39674cfd02a..e91d7849a659155676e2cd5c8c13f68e158f8d88 100644 (file)
@@ -52,6 +52,8 @@ struct zink_screen {
 
    uint32_t gfx_queue;
    VkDevice dev;
+
+   PFN_vkGetMemoryFdKHR vk_GetMemoryFdKHR;
 };
 
 static inline struct zink_screen *
index 43af7d8ddbff91b652237844266b3c21bf797619..1295823e4f515878d4371c6a0f85546b2030413b 100644 (file)
@@ -113,3 +113,7 @@ DEFINE_LOADER_DRM_ENTRYPOINT(sun4i_drm)
 #if defined(GALLIUM_LIMA)
 DEFINE_LOADER_DRM_ENTRYPOINT(lima)
 #endif
+
+#if defined(GALLIUM_ZINK)
+DEFINE_LOADER_DRM_ENTRYPOINT(zink);
+#endif