gbm: Introduce modifiers into surface/bo creation
The idea behind modifiers like this is that the user of GBM will have some mechanism to query what properties the hardware supports for its BO or surface. This information is directly passed in (and stored) so that the DRI implementation can create an image with the appropriate attributes. A getter() will be added later so that the user GBM will be able to query what modifier should be used. Only in surface creation, the modifiers are stored until the BO is actually allocated. In regular buffer allocation, the correct modifier can (will be, in future patches be chosen at creation time. v2: Make sure to check if count is non-zero in addition to testing if calloc fails. (Daniel) v3: Remove "usage" and "flags" from modifier creation. Requested by Kristian. v4: Take advantage of the "INVALID" modifier added by the GET_PLANE2 series. v5: Don't bother with storing modifiers for gbm_bo_create because that's a synchronous operation and we can actually select the correct modifier at create time (done in a later patch) (Jason) v6: Make modifier condition outside the check so that dri_use will work properly (Jason) Cc: Kristian Høgsberg <krh@bitplanet.net> References (v4): https://lists.freedesktop.org/archives/intel-gfx/2017-January/116636.html Signed-off-by: Ben Widawsky <ben@bwidawsk.net> Reviewed-by: Eric Engestrom <eric.engestrom@imgtec.com> (v1) Reviewed-by: Jason Ekstrand <jason@jlekstrand.net> Acked-by: Daniel Stone <daniels@collabora.com>
This commit is contained in:
@@ -1023,13 +1023,20 @@ free_bo:
|
||||
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);
|
||||
|
||||
@@ -1087,11 +1094,25 @@ gbm_dri_bo_create(struct gbm_device *gbm,
|
||||
/* 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;
|
||||
|
||||
@@ -1165,19 +1186,44 @@ gbm_dri_bo_unmap(struct gbm_bo *_bo, void *map_data)
|
||||
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;
|
||||
|
||||
surf = calloc(1, sizeof *surf);
|
||||
if (surf == NULL)
|
||||
if (modifiers &&
|
||||
(!dri->image || dri->image->base.version < 14 ||
|
||||
!dri->image->createImageWithModifiers)) {
|
||||
errno = ENOSYS;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
surf = calloc(1, sizeof *surf);
|
||||
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;
|
||||
}
|
||||
@@ -1187,6 +1233,7 @@ gbm_dri_surface_destroy(struct gbm_surface *_surf)
|
||||
{
|
||||
struct gbm_dri_surface *surf = gbm_dri_surface(_surf);
|
||||
|
||||
free(surf->base.modifiers);
|
||||
free(surf);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ gbm_device_is_format_supported
|
||||
gbm_device_destroy
|
||||
gbm_create_device
|
||||
gbm_bo_create
|
||||
gbm_bo_create_with_modifiers
|
||||
gbm_bo_import
|
||||
gbm_bo_map
|
||||
gbm_bo_unmap
|
||||
@@ -27,6 +28,7 @@ gbm_bo_set_user_data
|
||||
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
|
||||
|
||||
+37
-2
@@ -369,9 +369,28 @@ gbm_bo_create(struct gbm_device *gbm,
|
||||
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
|
||||
*
|
||||
@@ -477,7 +496,23 @@ gbm_surface_create(struct gbm_device *gbm,
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -243,6 +243,12 @@ gbm_bo_create(struct gbm_device *gbm,
|
||||
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
|
||||
@@ -345,6 +351,12 @@ gbm_surface_create(struct gbm_device *gbm,
|
||||
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);
|
||||
|
||||
|
||||
+10
-2
@@ -65,7 +65,9 @@ struct gbm_device {
|
||||
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,
|
||||
@@ -84,7 +86,9 @@ struct gbm_device {
|
||||
|
||||
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);
|
||||
@@ -114,6 +118,10 @@ struct gbm_surface {
|
||||
uint32_t height;
|
||||
uint32_t format;
|
||||
uint32_t flags;
|
||||
struct {
|
||||
uint64_t *modifiers;
|
||||
unsigned count;
|
||||
};
|
||||
};
|
||||
|
||||
struct gbm_backend {
|
||||
|
||||
Reference in New Issue
Block a user