.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 = {
#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 */
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 */
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,
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);
struct pipe_screen *
zink_create_screen(struct sw_winsys *winsys);
+struct pipe_screen *
+zink_drm_create_screen(int fd);
#endif
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;
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;
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,
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
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);
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) {
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)
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);
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);
+}
uint32_t gfx_queue;
VkDevice dev;
+
+ PFN_vkGetMemoryFdKHR vk_GetMemoryFdKHR;
};
static inline struct zink_screen *
#if defined(GALLIUM_LIMA)
DEFINE_LOADER_DRM_ENTRYPOINT(lima)
#endif
+
+#if defined(GALLIUM_ZINK)
+DEFINE_LOADER_DRM_ENTRYPOINT(zink);
+#endif