gallium: add pipe_screen::check_resource_capability
authorMarek Olšák <marek.olsak@amd.com>
Mon, 9 Oct 2017 16:44:50 +0000 (18:44 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Thu, 12 Oct 2017 17:03:33 +0000 (19:03 +0200)
This is optional (and no CAP).

Implemented by radeonsi, ddebug, rbug, trace.

Reviewed-by: Daniel Stone <daniels@collabora.com>
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/gallium/drivers/ddebug/dd_screen.c
src/gallium/drivers/radeon/r600_texture.c
src/gallium/drivers/rbug/rbug_screen.c
src/gallium/drivers/trace/tr_screen.c
src/gallium/include/pipe/p_screen.h

index c518f5f9e9d224fe41ba8682bd535fdbb535ad50..caf31f6df0f11923ead2cb0399a331622c905419 100644 (file)
@@ -308,6 +308,16 @@ dd_screen_resource_get_handle(struct pipe_screen *_screen,
    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
@@ -467,6 +477,7 @@ ddebug_screen_create(struct pipe_screen *screen)
    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;
index 78d49c289d1fdc515d49745b778ff2b769a6bd51..a237c3cd4d849905e3b4290490f3996a8f85b094 100644 (file)
@@ -2878,6 +2878,26 @@ r600_texture_from_memobj(struct pipe_screen *screen,
        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;
@@ -2885,6 +2905,7 @@ void si_init_screen_texture_functions(struct r600_common_screen *rscreen)
        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)
index b12f029b3ea1a5f6dad50ab4d3c6c872229cf8d3..2477edbadf07c8706f14608b65da88170699eaec 100644 (file)
@@ -183,6 +183,19 @@ rbug_screen_resource_from_handle(struct pipe_screen *_screen,
    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,
@@ -301,6 +314,7 @@ rbug_screen_create(struct pipe_screen *screen)
    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;
index 539b17e2702ec4ec5745a925c8ea247a32db8cb9..d5a81249b519f5512bed14b6dd5a881618d53756 100644 (file)
@@ -379,6 +379,16 @@ trace_screen_resource_from_handle(struct pipe_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,
@@ -636,6 +646,7 @@ trace_screen_create(struct pipe_screen *screen)
    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);
index 8c6028a0fca42508b844c3defce94d4cc0cff489..c249c7d63b46ee8cb96a9f7290354d4aab1a63ad 100644 (file)
@@ -204,6 +204,23 @@ 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