[Mesa-dev] [RFC] st/dri: implement createImageWithModifiers
Varad Gautam
varadgautam at gmail.com
Fri May 12 09:41:30 UTC 2017
gallium doesn't have a way to pass modifiers to the driver when creating
resources. we require this to support
dri2ImageExtension->createImageWithModifiers() to get
gbm_bo_create_with_modifiers() to work.
this adds a pscreen->resource_create_with_modifier() to pass the modifier
flags to the driver when allocating textures, and implements image creation
with modifiers.
requires cherry-picking the following patches from the EGL modifiers series:
https://patchwork.freedesktop.org/patch/155308/
https://patchwork.freedesktop.org/patch/155309/
https://patchwork.freedesktop.org/patch/155312/
complete tree, with the egl series:
https://git.collabora.com/cgit/user/varad/mesa.git/log/?h=egl-modifiers-v4
Signed-off-by: Varad Gautam <varadgautam at gmail.com>
---
src/gallium/include/pipe/p_screen.h | 13 ++++++
src/gallium/state_trackers/dri/dri2.c | 80 ++++++++++++++++++++++++++++-------
2 files changed, 77 insertions(+), 16 deletions(-)
diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h
index 8b4239c..7d248ec 100644
--- a/src/gallium/include/pipe/p_screen.h
+++ b/src/gallium/include/pipe/p_screen.h
@@ -328,6 +328,19 @@ struct pipe_screen {
* driver doesn't support an on-disk shader cache.
*/
struct disk_cache *(*get_disk_shader_cache)(struct pipe_screen *screen);
+
+ /**
+ * Create a new texture object from the given template info, taking
+ * format modifier into account. \p modifier adheres to the format
+ * modifier tokens specified in drm_fourcc.h.
+ *
+ * Returns NULL if the \p modifier is unsupported by the driver.
+ */
+ struct pipe_resource * (*resource_create_with_modifier)(
+ struct pipe_screen *,
+ const struct pipe_resource *templat,
+ uint64_t modifier);
+
};
diff --git a/src/gallium/state_trackers/dri/dri2.c b/src/gallium/state_trackers/dri/dri2.c
index 42fa155..54ca5fe 100644
--- a/src/gallium/state_trackers/dri/dri2.c
+++ b/src/gallium/state_trackers/dri/dri2.c
@@ -977,9 +977,12 @@ dri2_create_image_from_renderbuffer(__DRIcontext *context,
}
static __DRIimage *
-dri2_create_image(__DRIscreen *_screen,
- int width, int height, int format,
- unsigned int use, void *loaderPrivate)
+dri2_create_image_common(__DRIscreen *_screen,
+ int width, int height,
+ int format, unsigned int use,
+ const uint64_t *modifiers,
+ const unsigned count,
+ void *loaderPrivate)
{
struct dri_screen *screen = dri_screen(_screen);
__DRIimage *img;
@@ -987,17 +990,29 @@ dri2_create_image(__DRIscreen *_screen,
unsigned tex_usage;
enum pipe_format pf;
+ /* createImageWithModifiers does not take a usage flag, the caller can
+ * specify either modifiers or usage.
+ */
+ assert(!(use && (modifiers != NULL)));
+
+ /* XXX: it is probably a bad idea to assume that all drivers will support
+ * usage = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW with all of
+ * their modifiers. tex_usage must be determined in the driver instead
+ * when modifiers are present.
+ */
tex_usage = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
- if (use & __DRI_IMAGE_USE_SCANOUT)
- tex_usage |= PIPE_BIND_SCANOUT;
- if (use & __DRI_IMAGE_USE_SHARE)
- tex_usage |= PIPE_BIND_SHARED;
- if (use & __DRI_IMAGE_USE_LINEAR)
- tex_usage |= PIPE_BIND_LINEAR;
- if (use & __DRI_IMAGE_USE_CURSOR) {
- if (width != 64 || height != 64)
- return NULL;
- tex_usage |= PIPE_BIND_CURSOR;
+ if (use) {
+ if (use & __DRI_IMAGE_USE_SCANOUT)
+ tex_usage |= PIPE_BIND_SCANOUT;
+ if (use & __DRI_IMAGE_USE_SHARE)
+ tex_usage |= PIPE_BIND_SHARED;
+ if (use & __DRI_IMAGE_USE_LINEAR)
+ tex_usage |= PIPE_BIND_LINEAR;
+ if (use & __DRI_IMAGE_USE_CURSOR) {
+ if (width != 64 || height != 64)
+ return NULL;
+ tex_usage |= PIPE_BIND_CURSOR;
+ }
}
pf = dri2_format_to_pipe_format (format);
@@ -1018,7 +1033,18 @@ dri2_create_image(__DRIscreen *_screen,
templ.depth0 = 1;
templ.array_size = 1;
- img->texture = screen->base.screen->resource_create(screen->base.screen, &templ);
+ if (modifiers && screen->base.screen->resource_create_with_modifier)
+ /* pick the first modifier for alloc. */
+ img->texture = screen->base.screen
+ ->resource_create_with_modifier(screen->base.screen,
+ &templ,
+ modifiers[0]);
+ else if (modifiers)
+ /* the driver doesn't support tex creation with modifiers, return */
+ img->texture = NULL;
+ else
+ img->texture = screen->base.screen->resource_create(screen->base.screen,
+ &templ);
if (!img->texture) {
FREE(img);
return NULL;
@@ -1029,12 +1055,34 @@ dri2_create_image(__DRIscreen *_screen,
img->dri_format = format;
img->dri_components = 0;
img->use = use;
- img->modifier = DRM_FORMAT_MOD_INVALID;
+ img->modifier = modifiers ? modifiers[0] : DRM_FORMAT_MOD_INVALID;
img->loader_private = loaderPrivate;
return img;
}
+static __DRIimage *
+dri2_create_image(__DRIscreen *_screen,
+ int width, int height, int format,
+ unsigned int use, void *loaderPrivate)
+{
+ return dri2_create_image_common(_screen, width, height, format, use,
+ NULL /* modifiers */, 0 /* count */,
+ loaderPrivate);
+}
+
+static __DRIimage *
+dri2_create_image_with_modifiers(__DRIscreen *dri_screen,
+ int width, int height, int format,
+ const uint64_t *modifiers,
+ const unsigned count,
+ void *loaderPrivate)
+{
+ return dri2_create_image_common(dri_screen, width, height, format,
+ 0 /* use */, modifiers, count,
+ loaderPrivate);
+}
+
static GLboolean
dri2_query_image(__DRIimage *image, int attrib, int *value)
{
@@ -1450,7 +1498,7 @@ static __DRIimageExtension dri2ImageExtension = {
.getCapabilities = dri2_get_capabilities,
.mapImage = dri2_map_image,
.unmapImage = dri2_unmap_image,
- .createImageWithModifiers = NULL,
+ .createImageWithModifiers = dri2_create_image_with_modifiers,
};
--
2.10.0
More information about the mesa-dev
mailing list