static struct gbm_bo *
gbm_dri_bo_create(struct gbm_device *gbm,
uint32_t width, uint32_t height,
- uint32_t format, uint32_t usage)
+ uint32_t format, uint32_t usage,
+ const uint64_t *modifiers,
+ const unsigned int count)
{
struct gbm_dri_device *dri = gbm_dri_device(gbm);
struct gbm_dri_bo *bo;
int dri_format;
unsigned dri_use = 0;
+ /* Callers of this may specify a modifier, or a dri usage, but not both. The
+ * newer modifier interface deprecates the older usage flags.
+ */
+ assert(!(usage && count));
+
if (usage & GBM_BO_USE_WRITE || dri->image == NULL)
return create_dumb(gbm, width, height, format, usage);
/* Gallium drivers requires shared in order to get the handle/stride */
dri_use |= __DRI_IMAGE_USE_SHARE;
- bo->image =
- dri->image->createImage(dri->screen,
- width, height,
- dri_format, dri_use,
- bo);
+ if (modifiers) {
+ if (!dri->image || dri->image->base.version < 14 ||
+ !dri->image->createImageWithModifiers) {
+ fprintf(stderr, "Modifiers specified, but DRI is too old\n");
+ errno = ENOSYS;
+ goto failed;
+ }
+
+ bo->image =
+ dri->image->createImageWithModifiers(dri->screen,
+ width, height,
+ dri_format,
+ modifiers, count,
+ bo);
+ } else {
+ bo->image = dri->image->createImage(dri->screen, width, height,
+ dri_format, dri_use, bo);
+ }
+
if (bo->image == NULL)
goto failed;
static struct gbm_surface *
gbm_dri_surface_create(struct gbm_device *gbm,
uint32_t width, uint32_t height,
- uint32_t format, uint32_t flags)
+ uint32_t format, uint32_t flags,
+ const uint64_t *modifiers, const unsigned count)
{
+ struct gbm_dri_device *dri = gbm_dri_device(gbm);
struct gbm_dri_surface *surf;
+ if (modifiers &&
+ (!dri->image || dri->image->base.version < 14 ||
+ !dri->image->createImageWithModifiers)) {
+ errno = ENOSYS;
+ return NULL;
+ }
+
surf = calloc(1, sizeof *surf);
- if (surf == NULL)
+ if (surf == NULL) {
+ errno = ENOMEM;
return NULL;
+ }
surf->base.gbm = gbm;
surf->base.width = width;
surf->base.height = height;
surf->base.format = format;
surf->base.flags = flags;
+ if (!modifiers) {
+ assert(!count);
+ return &surf->base;
+ }
+
+ surf->base.modifiers = calloc(count, sizeof(*modifiers));
+ if (count && !surf->base.modifiers) {
+ errno = ENOMEM;
+ free(surf);
+ return NULL;
+ }
+
+ surf->base.count = count;
+ memcpy(surf->base.modifiers, modifiers, count * sizeof(*modifiers));
return &surf->base;
}
{
struct gbm_dri_surface *surf = gbm_dri_surface(_surf);
+ free(surf->base.modifiers);
free(surf);
}
gbm_device_destroy
gbm_create_device
gbm_bo_create
+gbm_bo_create_with_modifiers
gbm_bo_import
gbm_bo_map
gbm_bo_unmap
gbm_bo_get_user_data
gbm_bo_destroy
gbm_surface_create
+gbm_surface_create_with_modifiers
gbm_surface_needs_lock_front_buffer
gbm_surface_lock_front_buffer
gbm_surface_release_buffer
return NULL;
}
- return gbm->bo_create(gbm, width, height, format, usage);
+ return gbm->bo_create(gbm, width, height, format, usage, NULL, 0);
}
+GBM_EXPORT struct gbm_bo *
+gbm_bo_create_with_modifiers(struct gbm_device *gbm,
+ uint32_t width, uint32_t height,
+ uint32_t format,
+ const uint64_t *modifiers,
+ const unsigned int count)
+{
+ if (width == 0 || height == 0) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if ((count && !modifiers) || (modifiers && !count)) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ return gbm->bo_create(gbm, width, height, format, 0, modifiers, count);
+}
/**
* Create a gbm buffer object from an foreign object
*
uint32_t width, uint32_t height,
uint32_t format, uint32_t flags)
{
- return gbm->surface_create(gbm, width, height, format, flags);
+ return gbm->surface_create(gbm, width, height, format, flags, NULL, 0);
+}
+
+GBM_EXPORT struct gbm_surface *
+gbm_surface_create_with_modifiers(struct gbm_device *gbm,
+ uint32_t width, uint32_t height,
+ uint32_t format,
+ const uint64_t *modifiers,
+ const unsigned int count)
+{
+ if ((count && !modifiers) || (modifiers && !count)) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ return gbm->surface_create(gbm, width, height, format, 0,
+ modifiers, count);
}
/**
uint32_t width, uint32_t height,
uint32_t format, uint32_t flags);
+struct gbm_bo *
+gbm_bo_create_with_modifiers(struct gbm_device *gbm,
+ uint32_t width, uint32_t height,
+ uint32_t format,
+ const uint64_t *modifiers,
+ const unsigned int count);
#define GBM_BO_IMPORT_WL_BUFFER 0x5501
#define GBM_BO_IMPORT_EGL_IMAGE 0x5502
#define GBM_BO_IMPORT_FD 0x5503
uint32_t width, uint32_t height,
uint32_t format, uint32_t flags);
+struct gbm_surface *
+gbm_surface_create_with_modifiers(struct gbm_device *gbm,
+ uint32_t width, uint32_t height,
+ uint32_t format,
+ const uint64_t *modifiers,
+ const unsigned int count);
int
gbm_surface_needs_lock_front_buffer(struct gbm_surface *surface);
struct gbm_bo *(*bo_create)(struct gbm_device *gbm,
uint32_t width, uint32_t height,
uint32_t format,
- uint32_t usage);
+ uint32_t usage,
+ const uint64_t *modifiers,
+ const unsigned int count);
struct gbm_bo *(*bo_import)(struct gbm_device *gbm, uint32_t type,
void *buffer, uint32_t usage);
void *(*bo_map)(struct gbm_bo *bo,
struct gbm_surface *(*surface_create)(struct gbm_device *gbm,
uint32_t width, uint32_t height,
- uint32_t format, uint32_t flags);
+ uint32_t format, uint32_t flags,
+ const uint64_t *modifiers,
+ const unsigned count);
struct gbm_bo *(*surface_lock_front_buffer)(struct gbm_surface *surface);
void (*surface_release_buffer)(struct gbm_surface *surface,
struct gbm_bo *bo);
uint32_t height;
uint32_t format;
uint32_t flags;
+ struct {
+ uint64_t *modifiers;
+ unsigned count;
+ };
};
struct gbm_backend {