mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-03 05:00:09 +01:00
zink: Implement PIPE_CAP_RESOURCE_FROM_USER_MEMORY
Needed for GL_AMD_pinned_memory & zero-copy support in opencl Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23199>
This commit is contained in:
parent
c5054b1dfd
commit
81b0840caa
3 changed files with 49 additions and 10 deletions
|
|
@ -84,6 +84,7 @@ EXTENSIONS = [
|
|||
Extension("VK_KHR_buffer_device_address",
|
||||
alias="bda",
|
||||
features=True),
|
||||
Extension("VK_EXT_external_memory_host", alias="ext_host_mem", properties=True),
|
||||
Extension("VK_EXT_queue_family_foreign"),
|
||||
Extension("VK_KHR_swapchain_mutable_format"),
|
||||
Extension("VK_EXT_provoking_vertex",
|
||||
|
|
|
|||
|
|
@ -603,7 +603,7 @@ retry:
|
|||
|
||||
static struct zink_resource_object *
|
||||
resource_object_create(struct zink_screen *screen, const struct pipe_resource *templ, struct winsys_handle *whandle, bool *linear,
|
||||
uint64_t *modifiers, int modifiers_count, const void *loader_private)
|
||||
uint64_t *modifiers, int modifiers_count, const void *loader_private, const void *user_mem)
|
||||
{
|
||||
struct zink_resource_object *obj = CALLOC_STRUCT(zink_resource_object);
|
||||
unsigned max_level = 0;
|
||||
|
|
@ -985,6 +985,20 @@ resource_object_create(struct zink_screen *screen, const struct pipe_resource *t
|
|||
if (templ->bind & ZINK_BIND_TRANSIENT)
|
||||
flags |= VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT;
|
||||
|
||||
if (user_mem) {
|
||||
VkExternalMemoryHandleTypeFlagBits handle_type = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
|
||||
VkMemoryHostPointerPropertiesEXT memory_host_pointer_properties = {0};
|
||||
memory_host_pointer_properties.sType = VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT;
|
||||
memory_host_pointer_properties.pNext = NULL;
|
||||
VkResult res = VKSCR(GetMemoryHostPointerPropertiesEXT)(screen->dev, handle_type, user_mem, &memory_host_pointer_properties);
|
||||
if (res != VK_SUCCESS) {
|
||||
mesa_loge("ZINK: vkGetMemoryHostPointerPropertiesEXT failed");
|
||||
goto fail1;
|
||||
}
|
||||
reqs.memoryTypeBits &= memory_host_pointer_properties.memoryTypeBits;
|
||||
flags &= ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||
}
|
||||
|
||||
VkMemoryAllocateInfo mai;
|
||||
enum zink_alloc_flag aflags = templ->flags & PIPE_RESOURCE_FLAG_SPARSE ? ZINK_ALLOC_SPARSE : 0;
|
||||
mai.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||
|
|
@ -1062,6 +1076,17 @@ resource_object_create(struct zink_screen *screen, const struct pipe_resource *t
|
|||
|
||||
#endif
|
||||
|
||||
VkImportMemoryHostPointerInfoEXT imhpi = {
|
||||
VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT,
|
||||
NULL,
|
||||
};
|
||||
if (user_mem) {
|
||||
imhpi.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
|
||||
imhpi.pHostPointer = (void*)user_mem;
|
||||
imhpi.pNext = mai.pNext;
|
||||
mai.pNext = &imhpi;
|
||||
}
|
||||
|
||||
unsigned alignment = MAX2(reqs.alignment, 256);
|
||||
if (templ->usage == PIPE_USAGE_STAGING && obj->is_buffer)
|
||||
alignment = MAX2(alignment, screen->info.props.limits.minMemoryMapAlignment);
|
||||
|
|
@ -1178,7 +1203,7 @@ resource_create(struct pipe_screen *pscreen,
|
|||
struct winsys_handle *whandle,
|
||||
unsigned external_usage,
|
||||
const uint64_t *modifiers, int modifiers_count,
|
||||
const void *loader_private)
|
||||
const void *loader_private, const void *user_mem)
|
||||
{
|
||||
struct zink_screen *screen = zink_screen(pscreen);
|
||||
struct zink_resource *res = CALLOC_STRUCT_CL(zink_resource);
|
||||
|
|
@ -1214,7 +1239,7 @@ resource_create(struct pipe_screen *pscreen,
|
|||
templ2.flags &= ~PIPE_RESOURCE_FLAG_SPARSE;
|
||||
res->base.b.flags &= ~PIPE_RESOURCE_FLAG_SPARSE;
|
||||
}
|
||||
res->obj = resource_object_create(screen, &templ2, whandle, &linear, res->modifiers, res->modifiers_count, loader_private);
|
||||
res->obj = resource_object_create(screen, &templ2, whandle, &linear, res->modifiers, res->modifiers_count, loader_private, user_mem);
|
||||
if (!res->obj) {
|
||||
free(res->modifiers);
|
||||
FREE_CL(res);
|
||||
|
|
@ -1325,14 +1350,14 @@ static struct pipe_resource *
|
|||
zink_resource_create(struct pipe_screen *pscreen,
|
||||
const struct pipe_resource *templ)
|
||||
{
|
||||
return resource_create(pscreen, templ, NULL, 0, NULL, 0, NULL);
|
||||
return resource_create(pscreen, templ, NULL, 0, NULL, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
static struct pipe_resource *
|
||||
zink_resource_create_with_modifiers(struct pipe_screen *pscreen, const struct pipe_resource *templ,
|
||||
const uint64_t *modifiers, int modifiers_count)
|
||||
{
|
||||
return resource_create(pscreen, templ, NULL, 0, modifiers, modifiers_count, NULL);
|
||||
return resource_create(pscreen, templ, NULL, 0, modifiers, modifiers_count, NULL, NULL);
|
||||
}
|
||||
|
||||
static struct pipe_resource *
|
||||
|
|
@ -1340,7 +1365,7 @@ zink_resource_create_drawable(struct pipe_screen *pscreen,
|
|||
const struct pipe_resource *templ,
|
||||
const void *loader_private)
|
||||
{
|
||||
return resource_create(pscreen, templ, NULL, 0, NULL, 0, loader_private);
|
||||
return resource_create(pscreen, templ, NULL, 0, NULL, 0, loader_private, NULL);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -1360,7 +1385,7 @@ add_resource_bind(struct zink_context *ctx, struct zink_resource *res, unsigned
|
|||
|
||||
res->modifiers[0] = DRM_FORMAT_MOD_LINEAR;
|
||||
}
|
||||
struct zink_resource_object *new_obj = resource_object_create(screen, &res->base.b, NULL, &res->linear, res->modifiers, res->modifiers_count, NULL);
|
||||
struct zink_resource_object *new_obj = resource_object_create(screen, &res->base.b, NULL, &res->linear, res->modifiers, res->modifiers_count, NULL, NULL);
|
||||
if (!new_obj) {
|
||||
debug_printf("new backing resource alloc failed!\n");
|
||||
res->base.b.bind &= ~bind;
|
||||
|
|
@ -1610,7 +1635,7 @@ zink_resource_from_handle(struct pipe_screen *pscreen,
|
|||
modifier = whandle->modifier;
|
||||
modifier_count = 1;
|
||||
}
|
||||
struct pipe_resource *pres = resource_create(pscreen, &templ2, whandle, usage, &modifier, modifier_count, NULL);
|
||||
struct pipe_resource *pres = resource_create(pscreen, &templ2, whandle, usage, &modifier, modifier_count, NULL, NULL);
|
||||
if (pres) {
|
||||
struct zink_resource *res = zink_resource(pres);
|
||||
if (pres->target != PIPE_BUFFER)
|
||||
|
|
@ -1625,6 +1650,14 @@ zink_resource_from_handle(struct pipe_screen *pscreen,
|
|||
#endif
|
||||
}
|
||||
|
||||
static struct pipe_resource *
|
||||
zink_resource_from_user_memory(struct pipe_screen *pscreen,
|
||||
const struct pipe_resource *templ,
|
||||
void *user_memory)
|
||||
{
|
||||
return resource_create(pscreen, templ, NULL, 0, NULL, 0, NULL, user_memory);
|
||||
}
|
||||
|
||||
struct zink_memory_object {
|
||||
struct pipe_memory_object b;
|
||||
struct winsys_handle whandle;
|
||||
|
|
@ -1680,7 +1713,7 @@ zink_resource_from_memobj(struct pipe_screen *pscreen,
|
|||
{
|
||||
struct zink_memory_object *memobj = (struct zink_memory_object *)pmemobj;
|
||||
|
||||
struct pipe_resource *pres = resource_create(pscreen, templ, &memobj->whandle, 0, NULL, 0, NULL);
|
||||
struct pipe_resource *pres = resource_create(pscreen, templ, &memobj->whandle, 0, NULL, 0, NULL, NULL);
|
||||
if (pres) {
|
||||
if (pres->target != PIPE_BUFFER)
|
||||
zink_resource(pres)->valid = true;
|
||||
|
|
@ -1714,7 +1747,7 @@ invalidate_buffer(struct zink_context *ctx, struct zink_resource *res)
|
|||
if (!zink_resource_has_usage(res))
|
||||
return false;
|
||||
|
||||
struct zink_resource_object *new_obj = resource_object_create(screen, &res->base.b, NULL, NULL, NULL, 0, NULL);
|
||||
struct zink_resource_object *new_obj = resource_object_create(screen, &res->base.b, NULL, NULL, NULL, 0, NULL, 0);
|
||||
if (!new_obj) {
|
||||
debug_printf("new backing resource alloc failed!\n");
|
||||
return false;
|
||||
|
|
@ -2664,6 +2697,9 @@ zink_screen_resource_init(struct pipe_screen *pscreen)
|
|||
pscreen->resource_get_handle = zink_resource_get_handle;
|
||||
pscreen->resource_from_handle = zink_resource_from_handle;
|
||||
}
|
||||
if (screen->info.have_EXT_external_memory_host) {
|
||||
pscreen->resource_from_user_memory = zink_resource_from_user_memory;
|
||||
}
|
||||
if (screen->instance_info.have_KHR_external_memory_capabilities) {
|
||||
pscreen->memobj_create_from_handle = zink_memobj_create_from_handle;
|
||||
pscreen->memobj_destroy = zink_memobj_destroy;
|
||||
|
|
|
|||
|
|
@ -551,6 +551,8 @@ zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
|||
return screen->info.have_KHR_external_semaphore_fd || screen->info.have_KHR_external_semaphore_win32;
|
||||
case PIPE_CAP_NATIVE_FENCE_FD:
|
||||
return screen->instance_info.have_KHR_external_semaphore_capabilities && screen->info.have_KHR_external_semaphore_fd;
|
||||
case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
|
||||
return screen->info.have_EXT_external_memory_host;
|
||||
|
||||
case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS:
|
||||
return screen->info.have_vulkan11 || screen->info.have_KHR_maintenance2;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue