gbm: Support fixed-rate compression allocation

Add the fixed-rate compression ratios exposed by GL and Vulkan to the
flags for gbm_bo and gbm_surface creation, and intersect these with the
list of supplied modifiers to add another filter.

Although gbm_surface could support this by the EGLSurface flags in
EGL_EXT_surface_compression, gbm_bo cannot: it allocates a buffer first
and then imports it into the consuming API post-hoc, after the modifier
is already (must be) known. It seems more important to keep the
gbm_surface and gbm_bo APIs in sync, so keep the responsibility for
filtering on the GBM side.

Signed-off-by: Daniel Stone <daniels@collabora.com>
Reviewed-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27109>
This commit is contained in:
Daniel Stone
2023-11-01 15:35:56 +00:00
committed by Marge Bot
parent ea8977618f
commit a33bd78a54
2 changed files with 161 additions and 1 deletions

View File

@@ -942,6 +942,9 @@ gbm_dri_bo_create(struct gbm_device *gbm,
struct gbm_dri_bo *bo;
int dri_format;
unsigned dri_use = 0;
uint64_t *mods_comp = NULL;
uint64_t *mods_filtered = NULL;
unsigned int count_filtered = 0;
format = gbm_core.v0.format_canonicalize(format);
@@ -982,12 +985,98 @@ gbm_dri_bo_create(struct gbm_device *gbm,
goto failed;
}
/* If the driver supports fixed-rate compression, filter the acceptable
* modifiers by the compression rate. */
if (modifiers && dri->image->queryCompressionModifiers) {
enum __DRIFixedRateCompression comp = __DRI_FIXED_RATE_COMPRESSION_NONE;
switch (usage & GBM_BO_FIXED_COMPRESSION_MASK) {
#define CASE(x) case GBM_BO_FIXED_COMPRESSION_ ## x: comp = __DRI_FIXED_RATE_COMPRESSION_ ## x; break;
CASE(DEFAULT);
CASE(1BPC);
CASE(2BPC);
CASE(3BPC);
CASE(4BPC);
CASE(5BPC);
CASE(6BPC);
CASE(7BPC);
CASE(8BPC);
CASE(9BPC);
CASE(10BPC);
CASE(11BPC);
CASE(12BPC);
#undef CASE
default:
break;
}
int count_comp = 0;
/* Find how many acceptable modifiers there are for our rate. If there
* are none, fall back to no compression, as it is not mandatory to use
* the specified compression rate. */
if (!dri->image->queryCompressionModifiers(dri->screen, format, comp,
0, NULL, &count_comp) ||
count_comp == 0) {
if (comp == __DRI_FIXED_RATE_COMPRESSION_NONE) {
errno = EINVAL;
goto failed;
}
comp = __DRI_FIXED_RATE_COMPRESSION_NONE;
if (!dri->image->queryCompressionModifiers(dri->screen, format, comp,
0, NULL, &count_comp)) {
errno = EINVAL;
goto failed;
}
}
if (count_comp == 0) {
errno = EINVAL;
goto failed;
}
mods_comp = malloc(count_comp * sizeof(uint64_t));
mods_filtered = malloc(count_comp * sizeof(uint64_t));
if (!mods_comp || !mods_filtered) {
errno = ENOMEM;
goto failed;
}
if (!dri->image->queryCompressionModifiers(dri->screen, format, comp,
count_comp, mods_comp,
&count_comp)) {
errno = ENOMEM;
goto failed;
}
/* Intersect the list of user-supplied acceptable modifiers with the set
* of modifiers acceptable for this compression rate. */
for (unsigned int i = 0; i < count_comp; i++) {
for (unsigned int j = 0; j < count; j++) {
if (mods_comp[i] == modifiers[j]) {
mods_filtered[count_filtered++] = mods_comp[i];
break;
}
}
}
free(mods_comp);
mods_comp = NULL;
}
bo->image = loader_dri_create_image(dri->screen, dri->image, width, height,
dri_format, dri_use, modifiers, count,
dri_format, dri_use,
mods_filtered ? mods_filtered : modifiers,
mods_filtered ? count_filtered : count,
bo);
if (bo->image == NULL)
goto failed;
free(mods_filtered);
mods_filtered = NULL;
if (modifiers)
assert(gbm_dri_bo_get_modifier(&bo->base) != DRM_FORMAT_MOD_INVALID);
@@ -999,6 +1088,8 @@ gbm_dri_bo_create(struct gbm_device *gbm,
return &bo->base;
failed:
free(mods_comp);
free(mods_filtered);
free(bo);
return NULL;
}

View File

@@ -264,8 +264,77 @@ enum gbm_bo_flags {
* with pixel data.
*/
GBM_BO_USE_FRONT_RENDERING = (1 << 6),
/**
* Allow the driver to select fixed-rate compression parameters.
*/
GBM_BO_FIXED_COMPRESSION_DEFAULT = (1 << 7),
/**
* Fixed-rate compression: at least 1bpc, less than 2bpc
*/
GBM_BO_FIXED_COMPRESSION_1BPC = (2 << 7),
/**
* Fixed-rate compression: at least 2bpc, less than 3bpc
*/
GBM_BO_FIXED_COMPRESSION_2BPC = (3 << 7),
/**
* Fixed-rate compression: at least 3bpc, less than 4bpc
*/
GBM_BO_FIXED_COMPRESSION_3BPC = (4 << 7),
/**
* Fixed-rate compression: at least 4bpc, less than 5bpc
*/
GBM_BO_FIXED_COMPRESSION_4BPC = (5 << 7),
/**
* Fixed-rate compression: at least 5bpc, less than 6bpc
*/
GBM_BO_FIXED_COMPRESSION_5BPC = (6 << 7),
/**
* Fixed-rate compression: at least 6bpc, less than 7bpc
*/
GBM_BO_FIXED_COMPRESSION_6BPC = (7 << 7),
/**
* Fixed-rate compression: at least 7bpc, less than 8bpc
*/
GBM_BO_FIXED_COMPRESSION_7BPC = (8 << 7),
/**
* Fixed-rate compression: at least 8bpc, less than 9bpc
*/
GBM_BO_FIXED_COMPRESSION_8BPC = (9 << 7),
/**
* Fixed-rate compression: at least 9bpc, less than 10bpc
*/
GBM_BO_FIXED_COMPRESSION_9BPC = (10 << 7),
/**
* Fixed-rate compression: at least 10bpc, less than 11bpc
*/
GBM_BO_FIXED_COMPRESSION_10BPC = (11 << 7),
/**
* Fixed-rate compression: at least 11bpc, less than 12bpc
*/
GBM_BO_FIXED_COMPRESSION_11BPC = (12 << 7),
/**
* Fixed-rate compression: at least 12bpc, no maximum rate
*/
GBM_BO_FIXED_COMPRESSION_12BPC = (13 << 7),
/* next available value is (1 << 11) */
};
#define GBM_BO_FIXED_COMPRESSION_MASK (((1 << 11) - 1) & ~((1 << 7) - 1))
int
gbm_device_get_fd(struct gbm_device *gbm);