From: Marek Olšák <marek.ol...@amd.com> This is optional (and no CAP).
Implemented by radeonsi, ddebug, rbug, trace. --- src/gallium/drivers/ddebug/dd_screen.c | 11 +++++++++++ src/gallium/drivers/radeon/r600_texture.c | 21 +++++++++++++++++++++ src/gallium/drivers/rbug/rbug_screen.c | 14 ++++++++++++++ src/gallium/drivers/trace/tr_screen.c | 11 +++++++++++ src/gallium/include/pipe/p_screen.h | 17 +++++++++++++++++ 5 files changed, 74 insertions(+) diff --git a/src/gallium/drivers/ddebug/dd_screen.c b/src/gallium/drivers/ddebug/dd_screen.c index c518f5f..caf31f6 100644 --- a/src/gallium/drivers/ddebug/dd_screen.c +++ b/src/gallium/drivers/ddebug/dd_screen.c @@ -301,20 +301,30 @@ dd_screen_resource_get_handle(struct pipe_screen *_screen, struct pipe_resource *resource, struct winsys_handle *handle, unsigned usage) { struct pipe_screen *screen = dd_screen(_screen)->screen; struct pipe_context *pipe = _pipe ? dd_context(_pipe)->pipe : NULL; return screen->resource_get_handle(screen, pipe, resource, handle, usage); } +static bool +dd_screen_check_resource_capability(struct pipe_screen *_screen, + struct pipe_resource *resource, + unsigned bind) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + + return screen->check_resource_capability(screen, resource, bind); +} + /******************************************************************** * fence */ static void dd_screen_fence_reference(struct pipe_screen *_screen, struct pipe_fence_handle **pdst, struct pipe_fence_handle *src) { @@ -460,20 +470,21 @@ ddebug_screen_create(struct pipe_screen *screen) /* get_compute_param */ SCR_INIT(get_timestamp); dscreen->base.context_create = dd_screen_context_create; dscreen->base.is_format_supported = dd_screen_is_format_supported; /* is_video_format_supported */ SCR_INIT(can_create_resource); dscreen->base.resource_create = dd_screen_resource_create; dscreen->base.resource_from_handle = dd_screen_resource_from_handle; SCR_INIT(resource_from_memobj); SCR_INIT(resource_from_user_memory); + SCR_INIT(check_resource_capability); dscreen->base.resource_get_handle = dd_screen_resource_get_handle; SCR_INIT(resource_changed); dscreen->base.resource_destroy = dd_screen_resource_destroy; SCR_INIT(flush_frontbuffer); SCR_INIT(fence_reference); SCR_INIT(fence_finish); SCR_INIT(memobj_create_from_handle); SCR_INIT(memobj_destroy); SCR_INIT(get_driver_query_info); SCR_INIT(get_driver_query_group_info); diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c index 78d49c2..a237c3c 100644 --- a/src/gallium/drivers/radeon/r600_texture.c +++ b/src/gallium/drivers/radeon/r600_texture.c @@ -2871,25 +2871,46 @@ r600_texture_from_memobj(struct pipe_screen *screen, rtex->resource.b.is_shared = true; rtex->resource.external_usage = PIPE_HANDLE_USAGE_READ_WRITE; if (rscreen->apply_opaque_metadata) rscreen->apply_opaque_metadata(rscreen, rtex, &metadata); return &rtex->resource.b.b; } +static bool si_check_resource_capability(struct pipe_screen *screen, + struct pipe_resource *resource, + unsigned bind) +{ + struct r600_texture *tex = (struct r600_texture*)resource; + + /* Buffers only support the linear flag. */ + if (resource->target == PIPE_BUFFER) + return (bind & ~PIPE_BIND_LINEAR) == 0; + + if (bind & PIPE_BIND_LINEAR && !tex->surface.is_linear) + return false; + + if (bind & PIPE_BIND_SCANOUT && !tex->surface.is_displayable) + return false; + + /* TODO: PIPE_BIND_CURSOR - do we care? */ + return true; +} + void si_init_screen_texture_functions(struct r600_common_screen *rscreen) { rscreen->b.resource_from_handle = r600_texture_from_handle; rscreen->b.resource_get_handle = r600_texture_get_handle; rscreen->b.resource_from_memobj = r600_texture_from_memobj; rscreen->b.memobj_create_from_handle = r600_memobj_from_handle; rscreen->b.memobj_destroy = r600_memobj_destroy; + rscreen->b.check_resource_capability = si_check_resource_capability; } void si_init_context_texture_functions(struct r600_common_context *rctx) { rctx->b.create_surface = r600_create_surface; rctx->b.surface_destroy = r600_surface_destroy; rctx->b.clear_texture = r600_clear_texture; } diff --git a/src/gallium/drivers/rbug/rbug_screen.c b/src/gallium/drivers/rbug/rbug_screen.c index b12f029..2477edb 100644 --- a/src/gallium/drivers/rbug/rbug_screen.c +++ b/src/gallium/drivers/rbug/rbug_screen.c @@ -176,20 +176,33 @@ rbug_screen_resource_from_handle(struct pipe_screen *_screen, struct pipe_screen *screen = rb_screen->screen; struct pipe_resource *result; result = screen->resource_from_handle(screen, templ, handle, usage); result = rbug_resource_create(rbug_screen(_screen), result); return result; } +static bool +rbug_screen_check_resource_capability(struct pipe_screen *_screen, + struct pipe_resource *_resource, + unsigned bind) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct rbug_resource *rb_resource = rbug_resource(_resource); + struct pipe_screen *screen = rb_screen->screen; + struct pipe_resource *resource = rb_resource->resource; + + return screen->check_resource_capability(screen, resource, bind); +} + static boolean rbug_screen_resource_get_handle(struct pipe_screen *_screen, struct pipe_context *_pipe, struct pipe_resource *_resource, struct winsys_handle *handle, unsigned usage) { struct rbug_screen *rb_screen = rbug_screen(_screen); struct rbug_context *rb_pipe = rbug_context(_pipe); struct rbug_resource *rb_resource = rbug_resource(_resource); @@ -294,20 +307,21 @@ rbug_screen_create(struct pipe_screen *screen) rb_screen->base.get_vendor = rbug_screen_get_vendor; SCR_INIT(get_disk_shader_cache); rb_screen->base.get_device_vendor = rbug_screen_get_device_vendor; rb_screen->base.get_param = rbug_screen_get_param; rb_screen->base.get_shader_param = rbug_screen_get_shader_param; rb_screen->base.get_paramf = rbug_screen_get_paramf; rb_screen->base.is_format_supported = rbug_screen_is_format_supported; rb_screen->base.context_create = rbug_screen_context_create; rb_screen->base.resource_create = rbug_screen_resource_create; rb_screen->base.resource_from_handle = rbug_screen_resource_from_handle; + SCR_INIT(check_resource_capability); rb_screen->base.resource_get_handle = rbug_screen_resource_get_handle; SCR_INIT(resource_changed); rb_screen->base.resource_destroy = rbug_screen_resource_destroy; rb_screen->base.flush_frontbuffer = rbug_screen_flush_frontbuffer; rb_screen->base.fence_reference = rbug_screen_fence_reference; rb_screen->base.fence_finish = rbug_screen_fence_finish; rb_screen->screen = screen; rb_screen->private_context = screen->context_create(screen, NULL, 0); diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c index 539b17e..d5a8124 100644 --- a/src/gallium/drivers/trace/tr_screen.c +++ b/src/gallium/drivers/trace/tr_screen.c @@ -372,20 +372,30 @@ trace_screen_resource_from_handle(struct pipe_screen *_screen, /* TODO trace call */ result = screen->resource_from_handle(screen, templ, handle, usage); if (result) result->screen = _screen; return result; } +static bool +trace_screen_check_resource_capability(struct pipe_screen *_screen, + struct pipe_resource *resource, + unsigned bind) +{ + struct pipe_screen *screen = trace_screen(_screen)->screen; + + return screen->check_resource_capability(screen, resource, bind); +} + static boolean trace_screen_resource_get_handle(struct pipe_screen *_screen, struct pipe_context *_pipe, struct pipe_resource *resource, struct winsys_handle *handle, unsigned usage) { struct trace_screen *tr_screen = trace_screen(_screen); struct trace_context *tr_pipe = _pipe ? trace_context(_pipe) : NULL; struct pipe_screen *screen = tr_screen->screen; @@ -629,20 +639,21 @@ trace_screen_create(struct pipe_screen *screen) SCR_INIT(get_disk_shader_cache); tr_scr->base.get_param = trace_screen_get_param; tr_scr->base.get_shader_param = trace_screen_get_shader_param; tr_scr->base.get_paramf = trace_screen_get_paramf; tr_scr->base.get_compute_param = trace_screen_get_compute_param; tr_scr->base.is_format_supported = trace_screen_is_format_supported; assert(screen->context_create); tr_scr->base.context_create = trace_screen_context_create; tr_scr->base.resource_create = trace_screen_resource_create; tr_scr->base.resource_from_handle = trace_screen_resource_from_handle; + SCR_INIT(check_resource_capability); tr_scr->base.resource_get_handle = trace_screen_resource_get_handle; SCR_INIT(resource_from_memobj); SCR_INIT(resource_changed); tr_scr->base.resource_destroy = trace_screen_resource_destroy; tr_scr->base.fence_reference = trace_screen_fence_reference; tr_scr->base.fence_finish = trace_screen_fence_finish; SCR_INIT(memobj_create_from_handle); SCR_INIT(memobj_destroy); tr_scr->base.flush_frontbuffer = trace_screen_flush_frontbuffer; tr_scr->base.get_timestamp = trace_screen_get_timestamp; diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h index 8c6028a..c249c7d 100644 --- a/src/gallium/include/pipe/p_screen.h +++ b/src/gallium/include/pipe/p_screen.h @@ -198,20 +198,37 @@ struct pipe_screen { /** * Create a resource from user memory. This maps the user memory into * the device address space. */ struct pipe_resource * (*resource_from_user_memory)(struct pipe_screen *, const struct pipe_resource *t, void *user_memory); /** + * Unlike pipe_resource::bind, which describes what state trackers want, + * resources can have much greater capabilities in practice, often implied + * by the tiling layout or memory placement. This function allows querying + * whether a capability is supported beyond what was requested by state + * trackers. It's also useful for querying capabilities of imported + * resources where the capabilities are unknown at first. + * + * Only these flags are allowed: + * - PIPE_BIND_SCANOUT + * - PIPE_BIND_CURSOR + * - PIPE_BIND_LINEAR + */ + bool (*check_resource_capability)(struct pipe_screen *screen, + struct pipe_resource *resource, + unsigned bind); + + /** * Get a winsys_handle from a texture. Some platforms/winsys requires * that the texture is created with a special usage flag like * DISPLAYTARGET or PRIMARY. * * The context parameter can optionally be used to flush the resource and * the context to make sure the resource is coherent with whatever user * will use it. Some drivers may also use the context to convert * the resource into a format compatible for sharing. The use case is * OpenGL-OpenCL interop. The context parameter is allowed to be NULL. * -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev