From 9fa7400564244bdd333066eb71285c3703b537f7 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 2 Oct 2018 23:27:36 +0100 Subject: [PATCH] zink: add dri loader export MESA_LOADER_DRIVER_OVERRIDE=zink should now work without using swrast paths Acked-by: Jordan Justen --- .../auxiliary/pipe-loader/pipe_loader_drm.c | 4 ++ .../auxiliary/target-helpers/drm_helper.h | 22 ++++++++ .../target-helpers/drm_helper_public.h | 4 ++ src/gallium/drivers/zink/zink_context.c | 7 +++ src/gallium/drivers/zink/zink_public.h | 2 + src/gallium/drivers/zink/zink_resource.c | 56 +++++++++++++++++-- src/gallium/drivers/zink/zink_screen.c | 29 +++++++++- src/gallium/drivers/zink/zink_screen.h | 2 + src/gallium/targets/dri/target.c | 4 ++ 9 files changed, 123 insertions(+), 7 deletions(-) diff --git a/src/gallium/auxiliary/pipe-loader/pipe_loader_drm.c b/src/gallium/auxiliary/pipe-loader/pipe_loader_drm.c index 3b9b39f62a3..2e1bff4c233 100644 --- a/src/gallium/auxiliary/pipe-loader/pipe_loader_drm.c +++ b/src/gallium/auxiliary/pipe-loader/pipe_loader_drm.c @@ -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 = { diff --git a/src/gallium/auxiliary/target-helpers/drm_helper.h b/src/gallium/auxiliary/target-helpers/drm_helper.h index 6c5902d3c27..01b65d6c7f8 100644 --- a/src/gallium/auxiliary/target-helpers/drm_helper.h +++ b/src/gallium/auxiliary/target-helpers/drm_helper.h @@ -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 */ diff --git a/src/gallium/auxiliary/target-helpers/drm_helper_public.h b/src/gallium/auxiliary/target-helpers/drm_helper_public.h index 99018f0df88..82dfe9e2575 100644 --- a/src/gallium/auxiliary/target-helpers/drm_helper_public.h +++ b/src/gallium/auxiliary/target-helpers/drm_helper_public.h @@ -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 */ diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 785666f8bb8..5b3f2d5263d 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -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); diff --git a/src/gallium/drivers/zink/zink_public.h b/src/gallium/drivers/zink/zink_public.h index 5652c56a45e..be772f51ee8 100644 --- a/src/gallium/drivers/zink/zink_public.h +++ b/src/gallium/drivers/zink/zink_public.h @@ -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 diff --git a/src/gallium/drivers/zink/zink_resource.c b/src/gallium/drivers/zink/zink_resource.c index 297b1c1feef..50b7604a891 100644 --- a/src/gallium/drivers/zink/zink_resource.c +++ b/src/gallium/drivers/zink/zink_resource.c @@ -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 diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c index 5f8bbfd9f05..b50f2f5d030 100644 --- a/src/gallium/drivers/zink/zink_screen.c +++ b/src/gallium/drivers/zink/zink_screen.c @@ -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); +} diff --git a/src/gallium/drivers/zink/zink_screen.h b/src/gallium/drivers/zink/zink_screen.h index ab20a683f88..e91d7849a65 100644 --- a/src/gallium/drivers/zink/zink_screen.h +++ b/src/gallium/drivers/zink/zink_screen.h @@ -52,6 +52,8 @@ struct zink_screen { uint32_t gfx_queue; VkDevice dev; + + PFN_vkGetMemoryFdKHR vk_GetMemoryFdKHR; }; static inline struct zink_screen * diff --git a/src/gallium/targets/dri/target.c b/src/gallium/targets/dri/target.c index 43af7d8ddbf..1295823e4f5 100644 --- a/src/gallium/targets/dri/target.c +++ b/src/gallium/targets/dri/target.c @@ -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 -- 2.30.2