summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGurchetan Singh <gurchetansingh@chromium.org>2016-10-28 10:07:35 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-12-01 00:50:54 -0800
commit179687e4ebc9ce7c5a3199247c116852d9d418ce (patch)
tree88417a24ceb928916741d646b7effba5545bfbec
parente8ab0a503a36264c28b226ca0a5b3f9c339c03b1 (diff)
minigbm: Fix cursor and scanout flags
We were incorrectly advertising the scanout and cursor flags in the drivers. Chrome never used the BO_USE_CURSOR flag (see chromium:666488), and we set it for incorrect formats. Let's only advertise ARGB8888/XRGB8888 cursors if they were previously advertised, and prevent cursors from being used as render targets. For scanout, formats can vary from kernel version to kernel version. For example, the v3.18 i915 driver can't scanout NV12, but the upstream v4.4 i915 driver can. Let's query the KMS API in those cases. In addition, we would also like to move to a place where our backends can determine if a specific {format, usage, format modifier} tuple is supported. The plan is to add modifiers to the properties that are exposed in KMS, which can help with optimization. BUG=b:31942635, chromium:666488 TEST=Ran graphics_Gbm and checked if Chrome boots on cyan, minnie, and nyan_big CQ-DEPEND=CL:413325 Change-Id: Ifd3fd1c8063db97b3f1fe057ace82d22def76943 Reviewed-on: https://chromium-review.googlesource.com/405019 Commit-Ready: Gurchetan Singh <gurchetansingh@chromium.org> Tested-by: Gurchetan Singh <gurchetansingh@chromium.org> Reviewed-by: Ilja H. Friedel <ihf@chromium.org>
-rw-r--r--amdgpu.c22
-rw-r--r--cirrus.c25
-rw-r--r--cros_gralloc/Makefile1
-rw-r--r--cros_gralloc/cros_alloc_device.cc3
-rw-r--r--drv.c31
-rw-r--r--drv.h4
-rw-r--r--drv_priv.h18
-rw-r--r--evdi.c23
-rw-r--r--exynos.c24
-rw-r--r--gbm.c3
-rw-r--r--gma500.c18
-rw-r--r--helpers.c130
-rw-r--r--helpers.h6
-rw-r--r--i915.c83
-rw-r--r--list.h247
-rw-r--r--marvell.c23
-rw-r--r--mediatek.c51
-rw-r--r--rockchip.c62
-rw-r--r--tegra.c32
-rw-r--r--udl.c23
-rw-r--r--vgem.c23
-rw-r--r--virtio_gpu.c23
22 files changed, 687 insertions, 188 deletions
diff --git a/amdgpu.c b/amdgpu.c
index 84ba8f1..32170cb 100644
--- a/amdgpu.c
+++ b/amdgpu.c
@@ -38,6 +38,14 @@ enum {
FAMILY_LAST,
};
+static struct supported_combination combos[5] = {
+ {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE, DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR},
+ {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE, DRV_BO_USE_RENDERING},
+ {DRM_FORMAT_XBGR8888, DRM_FORMAT_MOD_NONE, DRV_BO_USE_RENDERING},
+ {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE, DRV_BO_USE_LINEAR},
+ {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE, DRV_BO_USE_RENDERING},
+};
+
static int amdgpu_set_metadata(int fd, uint32_t handle,
struct amdgpu_bo_metadata *info)
{
@@ -283,7 +291,8 @@ static int amdgpu_init(struct driver *drv)
drv->priv = addrlib;
- return 0;
+ drv_insert_combinations(drv, combos, ARRAY_SIZE(combos));
+ return drv_add_kms_flags(drv);
}
static void amdgpu_close(struct driver *drv)
@@ -338,21 +347,12 @@ static int amdgpu_bo_create(struct bo *bo, uint32_t width, uint32_t height,
return ret;
}
-const struct backend backend_amdgpu = {
+struct backend backend_amdgpu = {
.name = "amdgpu",
.init = amdgpu_init,
.close = amdgpu_close,
.bo_create = amdgpu_bo_create,
.bo_destroy = drv_gem_bo_destroy,
- .format_list = {
- /* Linear support */
- {DRM_FORMAT_XRGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_LINEAR},
- {DRM_FORMAT_ARGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR},
- /* Blocklinear support */
- {DRM_FORMAT_XRGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_RENDERING},
- {DRM_FORMAT_ARGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_RENDERING},
- {DRM_FORMAT_XBGR8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_RENDERING},
- }
};
#endif
diff --git a/cirrus.c b/cirrus.c
index 25a16bf..4958fef 100644
--- a/cirrus.c
+++ b/cirrus.c
@@ -6,18 +6,27 @@
#include "drv_priv.h"
#include "helpers.h"
+#include "util.h"
-const struct backend backend_cirrus =
+static struct supported_combination combos[5] = {
+ {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE, DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR},
+ {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE, DRV_BO_USE_RENDERING},
+ {DRM_FORMAT_RGB888, DRM_FORMAT_MOD_NONE, DRV_BO_USE_RENDERING},
+ {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE, DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR},
+ {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE, DRV_BO_USE_RENDERING},
+};
+
+static int cirrus_init(struct driver *drv)
+{
+ drv_insert_combinations(drv, combos, ARRAY_SIZE(combos));
+ return drv_add_kms_flags(drv);
+}
+
+struct backend backend_cirrus =
{
.name = "cirrus",
+ .init = cirrus_init,
.bo_create = drv_dumb_bo_create,
.bo_destroy = drv_dumb_bo_destroy,
.bo_map = drv_dumb_bo_map,
- .format_list = {
- {DRM_FORMAT_RGB888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_RENDERING},
- {DRM_FORMAT_XRGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_RENDERING},
- {DRM_FORMAT_XRGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR},
- {DRM_FORMAT_ARGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_RENDERING},
- {DRM_FORMAT_ARGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR},
- }
};
diff --git a/cros_gralloc/Makefile b/cros_gralloc/Makefile
index 977d637..bde9c42 100644
--- a/cros_gralloc/Makefile
+++ b/cros_gralloc/Makefile
@@ -11,6 +11,7 @@ VPATH = $(dir $(SOURCES))
CPPFLAGS += -Wall -fPIC -Werror -flto
CXXFLAGS += -std=c++11
+CFLAGS += -std=c99
LIBS += -shared -lcutils -lhardware -ldrm
OBJS = $(foreach source, $(SOURCES), $(addsuffix .o, $(basename $(source))))
diff --git a/cros_gralloc/cros_alloc_device.cc b/cros_gralloc/cros_alloc_device.cc
index 7af21fa..ddfb448 100644
--- a/cros_gralloc/cros_alloc_device.cc
+++ b/cros_gralloc/cros_alloc_device.cc
@@ -18,7 +18,8 @@ static struct cros_gralloc_bo *cros_gralloc_bo_create(struct driver *drv,
drv_format = drv_resolve_format(drv, drv_format);
drv_usage = cros_gralloc_convert_flags(usage);
- if (!drv_is_format_supported(drv, drv_format, drv_usage)) {
+ if (!drv_is_combination_supported(drv, drv_format, drv_usage,
+ DRM_FORMAT_MOD_NONE)) {
cros_gralloc_error("Unsupported combination -- HAL format: %u, "
"HAL flags: %u, drv_format: %u, "
"drv_flags: %llu", format, usage,
diff --git a/drv.c b/drv.c
index a2afd0f..eed722f 100644
--- a/drv.c
+++ b/drv.c
@@ -122,6 +122,8 @@ struct driver *drv_create(int fd)
if (!drv->map_table)
goto free_buffer_table;
+ LIST_INITHEAD(&drv->backend->combinations);
+
if (drv->backend->init) {
ret = drv->backend->init(drv);
if (ret)
@@ -143,13 +145,23 @@ free_driver:
void drv_destroy(struct driver *drv)
{
+ pthread_mutex_lock(&drv->table_lock);
+
if (drv->backend->close)
drv->backend->close(drv);
- pthread_mutex_destroy(&drv->table_lock);
drmHashDestroy(drv->buffer_table);
drmHashDestroy(drv->map_table);
+ list_for_each_entry_safe(struct combination_list_element, elem,
+ &drv->backend->combinations, link) {
+ LIST_DEL(&elem->link);
+ free(elem);
+ }
+
+ pthread_mutex_unlock(&drv->table_lock);
+ pthread_mutex_destroy(&drv->table_lock);
+
free(drv);
}
@@ -164,21 +176,18 @@ drv_get_name(struct driver *drv)
return drv->backend->name;
}
-int drv_is_format_supported(struct driver *drv, uint32_t format,
- uint64_t usage)
+int drv_is_combination_supported(struct driver *drv, uint32_t format,
+ uint64_t usage, uint64_t modifier)
{
- unsigned int i;
if (format == DRM_FORMAT_NONE || usage == DRV_BO_USE_NONE)
return 0;
- for (i = 0 ; i < ARRAY_SIZE(drv->backend->format_list); i++)
- {
- if (!drv->backend->format_list[i].format)
- break;
-
- if (drv->backend->format_list[i].format == format &&
- (drv->backend->format_list[i].usage & usage) == usage)
+ list_for_each_entry(struct combination_list_element, elem,
+ &drv->backend->combinations, link) {
+ if (format == elem->combination.format &&
+ usage == (elem->combination.usage & usage) &&
+ modifier == elem->combination.modifier)
return 1;
}
diff --git a/drv.h b/drv.h
index 0d05cbb..c567fb9 100644
--- a/drv.h
+++ b/drv.h
@@ -81,8 +81,8 @@ const char *
drv_get_name(struct driver *drv);
int
-drv_is_format_supported(struct driver *drv, uint32_t format,
- uint64_t usage);
+drv_is_combination_supported(struct driver *drv, uint32_t format,
+ uint64_t usage, uint64_t modifier);
struct bo *
drv_bo_new(struct driver *drv, uint32_t width, uint32_t height,
diff --git a/drv_priv.h b/drv_priv.h
index fc427bd..5300b48 100644
--- a/drv_priv.h
+++ b/drv_priv.h
@@ -13,6 +13,7 @@
#include <sys/types.h>
#include "drv.h"
+#include "list.h"
struct bo
{
@@ -47,6 +48,17 @@ struct map_info {
int32_t refcount;
};
+struct supported_combination {
+ uint32_t format;
+ uint64_t modifier;
+ uint64_t usage;
+};
+
+struct combination_list_element {
+ struct supported_combination combination;
+ struct list_head link;
+};
+
struct backend
{
char *name;
@@ -57,11 +69,7 @@ struct backend
void* (*bo_map)(struct bo *bo, struct map_info *data, size_t plane);
int (*bo_destroy)(struct bo *bo);
uint32_t (*resolve_format)(uint32_t format);
- struct format_supported {
- uint32_t format;
- uint64_t usage;
- }
- format_list[19];
+ struct list_head combinations;
};
#endif
diff --git a/evdi.c b/evdi.c
index 5b8154f..610ccb1 100644
--- a/evdi.c
+++ b/evdi.c
@@ -6,18 +6,27 @@
#include "drv_priv.h"
#include "helpers.h"
+#include "util.h"
-const struct backend backend_evdi =
+static struct supported_combination combos[4] = {
+ {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE, DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR},
+ {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE, DRV_BO_USE_RENDERING},
+ {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE, DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR},
+ {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE, DRV_BO_USE_RENDERING},
+};
+
+static int evdi_init(struct driver *drv)
+{
+ drv_insert_combinations(drv, combos, ARRAY_SIZE(combos));
+ return drv_add_kms_flags(drv);
+}
+
+struct backend backend_evdi =
{
.name = "evdi",
+ .init = evdi_init,
.bo_create = drv_dumb_bo_create,
.bo_destroy = drv_dumb_bo_destroy,
.bo_map = drv_dumb_bo_map,
- .format_list = {
- {DRM_FORMAT_XRGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_RENDERING},
- {DRM_FORMAT_XRGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR},
- {DRM_FORMAT_ARGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_RENDERING},
- {DRM_FORMAT_ARGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR},
- }
};
diff --git a/exynos.c b/exynos.c
index ab79ef8..c5e1759 100644
--- a/exynos.c
+++ b/exynos.c
@@ -17,6 +17,20 @@
#include "helpers.h"
#include "util.h"
+static struct supported_combination combos[5] = {
+ {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE, DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR},
+ {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE, DRV_BO_USE_RENDERING},
+ {DRM_FORMAT_NV12, DRM_FORMAT_MOD_NONE, DRV_BO_USE_RENDERING},
+ {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE, DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR},
+ {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE, DRV_BO_USE_RENDERING},
+};
+
+static int exynos_init(struct driver *drv)
+{
+ drv_insert_combinations(drv, combos, ARRAY_SIZE(combos));
+ return drv_add_kms_flags(drv);
+}
+
static int exynos_bo_create(struct bo *bo, uint32_t width, uint32_t height,
uint32_t format, uint32_t flags)
{
@@ -86,19 +100,13 @@ cleanup_planes:
* Use dumb mapping with exynos even though a GEM buffer is created.
* libdrm does the same thing in exynos_drm.c
*/
-const struct backend backend_exynos =
+struct backend backend_exynos =
{
.name = "exynos",
+ .init = exynos_init,
.bo_create = exynos_bo_create,
.bo_destroy = drv_gem_bo_destroy,
.bo_map = drv_dumb_bo_map,
- .format_list = {
- {DRM_FORMAT_XRGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_RENDERING},
- {DRM_FORMAT_XRGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR},
- {DRM_FORMAT_ARGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_RENDERING},
- {DRM_FORMAT_ARGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR},
- {DRM_FORMAT_NV12, DRV_BO_USE_SCANOUT | DRV_BO_USE_RENDERING},
- }
};
#endif
diff --git a/gbm.c b/gbm.c
index 4030c3e..7389cd8 100644
--- a/gbm.c
+++ b/gbm.c
@@ -42,7 +42,8 @@ gbm_device_is_format_supported(struct gbm_device *gbm,
drv_usage = gbm_convert_flags(usage);
- return drv_is_format_supported(gbm->drv, format, drv_usage);
+ return drv_is_combination_supported(gbm->drv, format, drv_usage,
+ DRM_FORMAT_MOD_NONE);
}
PUBLIC struct gbm_device *gbm_create_device(int fd)
diff --git a/gma500.c b/gma500.c
index 84df530..bbe2091 100644
--- a/gma500.c
+++ b/gma500.c
@@ -6,14 +6,24 @@
#include "drv_priv.h"
#include "helpers.h"
+#include "util.h"
-const struct backend backend_gma500 =
+static struct supported_combination combos[2] = {
+ {DRM_FORMAT_RGBX8888, DRM_FORMAT_MOD_NONE, DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR},
+ {DRM_FORMAT_RGBX8888, DRM_FORMAT_MOD_NONE, DRV_BO_USE_RENDERING},
+};
+
+static int gma500_init(struct driver *drv)
+{
+ drv_insert_combinations(drv, combos, ARRAY_SIZE(combos));
+ return drv_add_kms_flags(drv);
+}
+
+struct backend backend_gma500 =
{
.name = "gma500",
+ .init = gma500_init,
.bo_create = drv_dumb_bo_create,
.bo_destroy = drv_dumb_bo_destroy,
.bo_map = drv_dumb_bo_map,
- .format_list = {
- {DRM_FORMAT_RGBX8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_RENDERING},
- }
};
diff --git a/helpers.c b/helpers.c
index 1e35936..8ad0411 100644
--- a/helpers.c
+++ b/helpers.c
@@ -11,6 +11,7 @@
#include <string.h>
#include <sys/mman.h>
#include <xf86drm.h>
+#include <xf86drmMode.h>
#include "drv_priv.h"
#include "helpers.h"
@@ -274,3 +275,132 @@ uint32_t drv_log_base2(uint32_t value)
return ret;
}
+
+void drv_insert_supported_combination(struct driver *drv, uint32_t format,
+ uint64_t usage, uint64_t modifier)
+{
+ int found = 0;
+ struct combination_list_element *elem;
+
+ pthread_mutex_lock(&drv->table_lock);
+
+ list_for_each_entry(struct combination_list_element,
+ elem, &drv->backend->combinations, link) {
+ if (elem->combination.format == format &&
+ elem->combination.modifier == modifier) {
+ elem->combination.usage |= usage;
+ found = 1;
+ }
+ }
+
+ if (found)
+ goto out;
+
+ elem = calloc(1, sizeof(*elem));
+ elem->combination.format = format;
+ elem->combination.modifier = modifier;
+ elem->combination.usage = usage;
+ LIST_ADD(&elem->link, &drv->backend->combinations);
+
+out:
+ pthread_mutex_unlock(&drv->table_lock);
+}
+
+void drv_insert_combinations(struct driver *drv, struct supported_combination *combos,
+ uint32_t size)
+{
+ unsigned int i;
+ for (i = 0; i < size; i++)
+ drv_insert_supported_combination(drv, combos[i].format,
+ combos[i].usage,
+ combos[i].modifier);
+}
+
+int drv_add_kms_flags(struct driver *drv)
+{
+ int ret;
+ uint32_t i, j;
+ uint64_t flag, usage;
+ drmModePlanePtr plane;
+ drmModePropertyPtr prop;
+ drmModePlaneResPtr resources;
+ drmModeObjectPropertiesPtr props;
+
+ /*
+ * All current drivers can scanout XRGB8888/ARGB8888 as a primary plane.
+ * Some older kernel versions can only return overlay planes, so add the
+ * combination here. Note that the kernel disregards the alpha component
+ * of ARGB unless it's an overlay plane.
+ */
+ drv_insert_supported_combination(drv, DRM_FORMAT_XRGB8888,
+ DRV_BO_USE_SCANOUT,
+ 0);
+ drv_insert_supported_combination(drv, DRM_FORMAT_ARGB8888,
+ DRV_BO_USE_SCANOUT,
+ 0);
+
+ /*
+ * The ability to return universal planes is only complete on
+ * ChromeOS kernel versions >= v3.18. The SET_CLIENT_CAP ioctl
+ * therefore might return an error code, so don't check it. If it
+ * fails, it'll just return the plane list as overlay planes, which is
+ * fine in our case (our drivers already have cursor bits set).
+ * modetest in libdrm does the same thing.
+ */
+ drmSetClientCap(drv->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
+
+ resources = drmModeGetPlaneResources(drv->fd);
+ if (!resources)
+ goto err;
+
+ for (i = 0; i < resources->count_planes; i++) {
+
+ plane = drmModeGetPlane(drv->fd, resources->planes[i]);
+
+ if (!plane)
+ goto err;
+
+ props = drmModeObjectGetProperties(drv->fd, plane->plane_id,
+ DRM_MODE_OBJECT_PLANE);
+ if (!props)
+ goto err;
+
+ for (j = 0; j < props->count_props; j++) {
+
+ prop = drmModeGetProperty(drv->fd, props->props[j]);
+ if (prop) {
+ if (strcmp(prop->name, "type") == 0) {
+ flag = props->prop_values[j];
+ }
+ drmModeFreeProperty(prop);
+ }
+ }
+
+ switch (flag) {
+ case DRM_PLANE_TYPE_OVERLAY:
+ case DRM_PLANE_TYPE_PRIMARY:
+ usage = DRV_BO_USE_SCANOUT;
+ break;
+ case DRM_PLANE_TYPE_CURSOR:
+ usage = DRV_BO_USE_CURSOR;
+ break;
+ default:
+ assert(0);
+ }
+
+ for (j = 0; j < plane->count_formats; j++)
+ drv_insert_supported_combination(drv, plane->formats[j],
+ usage, 0);
+
+ drmModeFreeObjectProperties(props);
+ drmModeFreePlane(plane);
+
+ }
+
+ drmModeFreePlaneResources(resources);
+ return 0;
+
+err:
+ ret = -1;
+ return ret;
+}
diff --git a/helpers.h b/helpers.h
index cfedcff..aa549b0 100644
--- a/helpers.h
+++ b/helpers.h
@@ -24,4 +24,10 @@ void drv_increment_reference_count(struct driver *drv, struct bo *bo,
void drv_decrement_reference_count(struct driver *drv, struct bo *bo,
size_t plane);
uint32_t drv_log_base2(uint32_t value);
+void drv_insert_supported_combination(struct driver *drv, uint32_t format,
+ uint64_t usage, uint64_t modifier);
+void drv_insert_combinations(struct driver *drv,
+ struct supported_combination *combos,
+ uint32_t size);
+int drv_add_kms_flags(struct driver *drv);
#endif
diff --git a/i915.c b/i915.c
index f0c8af6..712fd01 100644
--- a/i915.c
+++ b/i915.c
@@ -17,12 +17,50 @@
#include "helpers.h"
#include "util.h"
+static struct supported_combination combos[18] = {
+ {DRM_FORMAT_ARGB1555, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_RENDERING | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
+ {DRM_FORMAT_ABGR8888, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_RENDERING | DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
+ {DRM_FORMAT_ABGR8888, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_RENDERING | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
+ {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR | DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
+ {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_RENDERING | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
+ {DRM_FORMAT_GR88, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_LINEAR | DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
+ {DRM_FORMAT_R8, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_LINEAR | DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
+ {DRM_FORMAT_RGB565, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_RENDERING | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
+ {DRM_FORMAT_UYVY, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_LINEAR | DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
+ {DRM_FORMAT_UYVY, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_RENDERING | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
+ {DRM_FORMAT_XBGR8888, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_RENDERING | DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
+ {DRM_FORMAT_XBGR8888, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_RENDERING | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
+ {DRM_FORMAT_XRGB1555, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_RENDERING | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
+ {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR | DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
+ {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_RENDERING | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
+ {DRM_FORMAT_YUYV, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_LINEAR | DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
+ {DRM_FORMAT_YUYV, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_RENDERING | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
+ {DRM_FORMAT_YVU420, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_RENDERING | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
+};
+
struct i915_device
{
int gen;
};
-
static int get_gen(int device_id)
{
const uint16_t gen3_ids[] = {0x2582, 0x2592, 0x2772, 0x27A2, 0x27AE,
@@ -60,7 +98,8 @@ static int i915_init(struct driver *drv)
drv->priv = i915_drv;
- return 0;
+ drv_insert_combinations(drv, combos, ARRAY_SIZE(combos));
+ return drv_add_kms_flags(drv);
}
static void i915_close(struct driver *drv)
@@ -216,7 +255,7 @@ static uint32_t i915_resolve_format(uint32_t format)
}
}
-const struct backend backend_i915 =
+struct backend backend_i915 =
{
.name = "i915",
.init = i915_init,
@@ -225,44 +264,6 @@ const struct backend backend_i915 =
.bo_destroy = drv_gem_bo_destroy,
.bo_map = i915_bo_map,
.resolve_format = i915_resolve_format,
- .format_list = {
- {DRM_FORMAT_XRGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_RENDERING
- | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
- {DRM_FORMAT_XRGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR |
- DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
- {DRM_FORMAT_ARGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_RENDERING
- | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
- {DRM_FORMAT_ARGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR |
- DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
- {DRM_FORMAT_XBGR8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_RENDERING
- | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
- {DRM_FORMAT_XBGR8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_RENDERING |
- DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
- {DRM_FORMAT_ABGR8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_RENDERING
- | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
- {DRM_FORMAT_ABGR8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_RENDERING | DRV_BO_USE_CURSOR
- | DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
- {DRM_FORMAT_XRGB1555, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_RENDERING
- | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
- {DRM_FORMAT_ARGB1555, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_RENDERING
- | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
- {DRM_FORMAT_RGB565, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_RENDERING
- | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
- {DRM_FORMAT_UYVY, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_RENDERING
- | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
- {DRM_FORMAT_UYVY, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR |
- DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
- {DRM_FORMAT_YUYV, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_RENDERING
- | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
- {DRM_FORMAT_YUYV, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR |
- DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
- {DRM_FORMAT_R8, DRV_BO_USE_SCANOUT | DRV_BO_USE_LINEAR |
- DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
- {DRM_FORMAT_GR88, DRV_BO_USE_SCANOUT | DRV_BO_USE_LINEAR |
- DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
- {DRM_FORMAT_YVU420, DRV_BO_USE_RENDERING | DRV_BO_USE_SW_READ_RARELY |
- DRV_BO_USE_SW_WRITE_RARELY},
- }
};
#endif
diff --git a/list.h b/list.h
new file mode 100644
index 0000000..53f46e7
--- /dev/null
+++ b/list.h
@@ -0,0 +1,247 @@
+/**************************************************************************
+ *
+ * Copyright 2006 VMware, Inc., Bismarck, ND. USA.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ **************************************************************************/
+
+/**
+ * \file
+ * List macros heavily inspired by the Linux kernel
+ * list handling. No list looping yet.
+ *
+ * Is not threadsafe, so common operations need to
+ * be protected using an external mutex.
+ */
+
+#ifndef _UTIL_LIST_H_
+#define _UTIL_LIST_H_
+
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <assert.h>
+
+
+struct list_head
+{
+ struct list_head *prev;
+ struct list_head *next;
+};
+
+static inline void list_inithead(struct list_head *item)
+{
+ item->prev = item;
+ item->next = item;
+}
+
+static inline void list_add(struct list_head *item, struct list_head *list)
+{
+ item->prev = list;
+ item->next = list->next;
+ list->next->prev = item;
+ list->next = item;
+}
+
+static inline void list_addtail(struct list_head *item, struct list_head *list)
+{
+ item->next = list;
+ item->prev = list->prev;
+ list->prev->next = item;
+ list->prev = item;
+}
+
+static inline bool list_empty(struct list_head *list);
+
+static inline void list_replace(struct list_head *from, struct list_head *to)
+{
+ if (list_empty(from)) {
+ list_inithead(to);
+ } else {
+ to->prev = from->prev;
+ to->next = from->next;
+ from->next->prev = to;
+ from->prev->next = to;
+ }
+}
+
+static inline void list_del(struct list_head *item)
+{
+ item->prev->next = item->next;
+ item->next->prev = item->prev;
+ item->prev = item->next = NULL;
+}
+
+static inline void list_delinit(struct list_head *item)
+{
+ item->prev->next = item->next;
+ item->next->prev = item->prev;
+ item->next = item;
+ item->prev = item;
+}
+
+static inline bool list_empty(struct list_head *list)
+{
+ return list->next == list;
+}
+
+/**
+ * Returns whether the list has exactly one element.
+ */
+static inline bool list_is_singular(const struct list_head *list)
+{
+ return list->next != NULL && list->next->next == list;
+}
+
+static inline unsigned list_length(struct list_head *list)
+{
+ struct list_head *node;
+ unsigned length = 0;
+ for (node = list->next; node != list; node = node->next)
+ length++;
+ return length;
+}
+
+static inline void list_splice(struct list_head *src, struct list_head *dst)
+{
+ if (list_empty(src))
+ return;
+
+ src->next->prev = dst;
+ src->prev->next = dst->next;
+ dst->next->prev = src->prev;
+ dst->next = src->next;
+}
+
+static inline void list_splicetail(struct list_head *src, struct list_head *dst)
+{
+ if (list_empty(src))
+ return;
+
+ src->prev->next = dst;
+ src->next->prev = dst->prev;
+ dst->prev->next = src->next;
+ dst->prev = src->prev;
+}
+
+static inline void list_validate(struct list_head *list)
+{
+ struct list_head *node;
+ assert(list->next->prev == list && list->prev->next == list);
+ for (node = list->next; node != list; node = node->next)
+ assert(node->next->prev == node && node->prev->next == node);
+}
+
+#define LIST_INITHEAD(__item) list_inithead(__item)
+#define LIST_ADD(__item, __list) list_add(__item, __list)
+#define LIST_ADDTAIL(__item, __list) list_addtail(__item, __list)
+#define LIST_REPLACE(__from, __to) list_replace(__from, __to)
+#define LIST_DEL(__item) list_del(__item)
+#define LIST_DELINIT(__item) list_delinit(__item)
+
+#define LIST_ENTRY(__type, __item, __field) \
+ ((__type *)(void *)(((char *)(__item)) - offsetof(__type, __field)))
+
+#define LIST_IS_EMPTY(__list) \
+ ((__list)->next == (__list))
+
+/**
+ * Cast from a pointer to a member of a struct back to the containing struct.
+ *
+ * 'sample' MUST be initialized, or else the result is undefined!
+ */
+#ifndef container_of
+#define container_of(ptr, sample, member) \
+ (void *)((char *)(ptr) \
+ - ((char *)&(sample)->member - (char *)(sample)))
+#endif
+
+#define list_first_entry(ptr, type, member) \
+ LIST_ENTRY(type, (ptr)->next, member)
+
+#define list_last_entry(ptr, type, member) \
+ LIST_ENTRY(type, (ptr)->prev, member)
+
+
+#define LIST_FOR_EACH_ENTRY(pos, head, member) \
+ for (pos = NULL, pos = container_of((head)->next, pos, member); \
+ &pos->member != (head); \
+ pos = container_of(pos->member.next, pos, member))
+
+#define LIST_FOR_EACH_ENTRY_SAFE(pos, storage, head, member) \
+ for (pos = NULL, pos = container_of((head)->next, pos, member), \
+ storage = container_of(pos->member.next, pos, member); \
+ &pos->member != (head); \
+ pos = storage, storage = container_of(storage->member.next, storage, member))
+
+#define LIST_FOR_EACH_ENTRY_SAFE_REV(pos, storage, head, member) \
+ for (pos = NULL, pos = container_of((head)->prev, pos, member), \
+ storage = container_of(pos->member.prev, pos, member); \
+ &pos->member != (head); \
+ pos = storage, storage = container_of(storage->member.prev, storage, member))
+
+#define LIST_FOR_EACH_ENTRY_FROM(pos, start, head, member) \
+ for (pos = NULL, pos = container_of((start), pos, member); \
+ &pos->member != (head); \
+ pos = container_of(pos->member.next, pos, member))
+
+#define LIST_FOR_EACH_ENTRY_FROM_REV(pos, start, head, member) \
+ for (pos = NULL, pos = container_of((start), pos, member); \
+ &pos->member != (head); \
+ pos = container_of(pos->member.prev, pos, member))
+
+#define list_for_each_entry(type, pos, head, member) \
+ for (type *pos = LIST_ENTRY(type, (head)->next, member); \
+ &pos->member != (head); \
+ pos = LIST_ENTRY(type, pos->member.next, member))
+
+#define list_for_each_entry_safe(type, pos, head, member) \
+ for (type *pos = LIST_ENTRY(type, (head)->next, member), \
+ *__next = LIST_ENTRY(type, pos->member.next, member); \
+ &pos->member != (head); \
+ pos = __next, \
+ __next = LIST_ENTRY(type, __next->member.next, member))
+
+#define list_for_each_entry_rev(type, pos, head, member) \
+ for (type *pos = LIST_ENTRY(type, (head)->prev, member); \
+ &pos->member != (head); \
+ pos = LIST_ENTRY(type, pos->member.prev, member))
+
+#define list_for_each_entry_safe_rev(type, pos, head, member) \
+ for (type *pos = LIST_ENTRY(type, (head)->prev, member), \
+ *__prev = LIST_ENTRY(type, pos->member.prev, member); \
+ &pos->member != (head); \
+ pos = __prev, \
+ __prev = LIST_ENTRY(type, __prev->member.prev, member))
+
+#define list_for_each_entry_from(type, pos, start, head, member) \
+ for (type *pos = LIST_ENTRY(type, (start), member); \
+ &pos->member != (head); \
+ pos = LIST_ENTRY(type, pos->member.next, member))
+
+#define list_for_each_entry_from_rev(type, pos, start, head, member) \
+ for (type *pos = LIST_ENTRY(type, (start), member); \
+ &pos->member != (head); \
+ pos = LIST_ENTRY(type, pos->member.prev, member))
+
+#endif /*_UTIL_LIST_H_*/
diff --git a/marvell.c b/marvell.c
index 85c87ce..73f7d9a 100644
--- a/marvell.c
+++ b/marvell.c
@@ -8,19 +8,28 @@
#include "drv_priv.h"
#include "helpers.h"
+#include "util.h"
-const struct backend backend_marvell =
+static struct supported_combination combos[4] = {
+ {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE, DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR},
+ {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE, DRV_BO_USE_RENDERING},
+ {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE, DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR},
+ {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE, DRV_BO_USE_RENDERING},
+}
+
+static int marvell_init(struct driver *drv)
+{
+ drv_insert_combinations(drv, combos, ARRAY_SIZE(combos));
+ return drv_add_kms_flags(drv);
+}
+
+struct backend backend_marvell =
{
.name = "marvell",
+ .init = marvell_init,
.bo_create = drv_dumb_bo_create,
.bo_destroy = drv_dumb_bo_destroy,
.bo_map = drv_dumb_bo_map,
- .format_list = {
- {DRM_FORMAT_XRGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_RENDERING},
- {DRM_FORMAT_XRGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR},
- {DRM_FORMAT_ARGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_RENDERING},
- {DRM_FORMAT_ARGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR},
- }
};
#endif
diff --git a/mediatek.c b/mediatek.c
index 54067c7..23b1dd2 100644
--- a/mediatek.c
+++ b/mediatek.c
@@ -14,6 +14,34 @@
#include "drv_priv.h"
#include "helpers.h"
+#include "util.h"
+
+static struct supported_combination combos[8] = {
+ {DRM_FORMAT_ABGR8888, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_RENDERING | DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN |
+ DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
+ {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR | DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
+ {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_RENDERING | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
+ {DRM_FORMAT_RGB565, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_RENDERING | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
+ {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR | DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
+ {DRM_FORMAT_XBGR8888, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_RENDERING | DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN |
+ DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
+ {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_RENDERING | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
+ {DRM_FORMAT_YVU420, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_RENDERING | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
+};
+
+static int mediatek_init(struct driver *drv)
+{
+ drv_insert_combinations(drv, combos, ARRAY_SIZE(combos));
+ return drv_add_kms_flags(drv);
+}
static int mediatek_bo_create(struct bo *bo, uint32_t width, uint32_t height,
uint32_t format, uint32_t flags)
@@ -73,33 +101,14 @@ static uint32_t mediatek_resolve_format(uint32_t format)
}
}
-const struct backend backend_mediatek =
+struct backend backend_mediatek =
{
.name = "mediatek",
+ .init = mediatek_init,
.bo_create = mediatek_bo_create,
.bo_destroy = drv_gem_bo_destroy,
.bo_map = mediatek_bo_map,
.resolve_format = mediatek_resolve_format,
- .format_list = {
- {DRM_FORMAT_XRGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_RENDERING
- | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
- {DRM_FORMAT_XRGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR
- | DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
- {DRM_FORMAT_ARGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_RENDERING
- | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
- {DRM_FORMAT_ARGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR |
- DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
- {DRM_FORMAT_ABGR8888, DRV_BO_USE_RENDERING
- | DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN
- | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
- {DRM_FORMAT_XBGR8888, DRV_BO_USE_RENDERING
- | DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN
- | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
- {DRM_FORMAT_RGB565, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_RENDERING
- | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
- {DRM_FORMAT_YVU420, DRV_BO_USE_RENDERING | DRV_BO_USE_SW_READ_RARELY |
- DRV_BO_USE_SW_WRITE_RARELY},
- }
};
#endif
diff --git a/rockchip.c b/rockchip.c
index d593051..59e44c2 100644
--- a/rockchip.c
+++ b/rockchip.c
@@ -17,6 +17,39 @@
#include "helpers.h"
#include "util.h"
+static struct supported_combination combos[11] = {
+ {DRM_FORMAT_ABGR8888, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_RENDERING | DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN |
+ DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
+ {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR | DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
+ {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_RENDERING | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
+ {DRM_FORMAT_NV12, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_RENDERING | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
+ {DRM_FORMAT_NV12, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_LINEAR | DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
+ {DRM_FORMAT_RGB565, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_RENDERING | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
+ {DRM_FORMAT_XBGR8888, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_RENDERING | DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN |
+ DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
+ {DRM_FORMAT_XBGR8888, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_LINEAR | DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
+ {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR | DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
+ {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_RENDERING | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
+ {DRM_FORMAT_YVU420, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_RENDERING | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
+};
+
+static int rockchip_init(struct driver *drv)
+{
+ drv_insert_combinations(drv, combos, ARRAY_SIZE(combos));
+ return drv_add_kms_flags(drv);
+}
+
static int rockchip_bo_create(struct bo *bo, uint32_t width, uint32_t height,
uint32_t format, uint32_t flags)
{
@@ -91,39 +124,14 @@ static uint32_t rockchip_resolve_format(uint32_t format)
}
}
-const struct backend backend_rockchip =
+struct backend backend_rockchip =
{
.name = "rockchip",
+ .init = rockchip_init,
.bo_create = rockchip_bo_create,
.bo_destroy = drv_gem_bo_destroy,
.bo_map = rockchip_bo_map,
.resolve_format = rockchip_resolve_format,
- .format_list = {
- {DRM_FORMAT_XRGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_RENDERING
- | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
- {DRM_FORMAT_XRGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR |
- DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
- {DRM_FORMAT_XBGR8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_RENDERING
- | DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN
- | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
- {DRM_FORMAT_XBGR8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR |
- DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
- {DRM_FORMAT_ARGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_RENDERING
- | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
- {DRM_FORMAT_RGB565, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_RENDERING
- | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
- {DRM_FORMAT_ARGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR |
- DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
- {DRM_FORMAT_ABGR8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_RENDERING
- | DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN
- | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
- {DRM_FORMAT_NV12, DRV_BO_USE_SCANOUT | DRV_BO_USE_RENDERING |
- DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
- {DRM_FORMAT_NV12, DRV_BO_USE_SCANOUT | DRV_BO_USE_LINEAR |
- DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
- {DRM_FORMAT_YVU420, DRV_BO_USE_RENDERING | DRV_BO_USE_SW_READ_RARELY |
- DRV_BO_USE_SW_WRITE_RARELY},
- }
};
#endif
diff --git a/tegra.c b/tegra.c
index dd82c86..513229c 100644
--- a/tegra.c
+++ b/tegra.c
@@ -33,6 +33,17 @@ enum nv_mem_kind
NV_MEM_KIND_GENERIC_16Bx2 = 0xfe,
};
+static struct supported_combination combos[4] = {
+ {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR | DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
+ {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_RENDERING | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
+ {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR | DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
+ {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_RENDERING | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
+};
+
static int compute_block_height_log2(int height)
{
int block_height_log2 = NV_DEFAULT_BLOCK_HEIGHT_LOG2;
@@ -87,6 +98,12 @@ static void compute_layout_linear(int width, int height, int format,
*size = *stride * height;
}
+static int tegra_init(struct driver *drv)
+{
+ drv_insert_combinations(drv, combos, ARRAY_SIZE(combos));
+ return drv_add_kms_flags(drv);
+}
+
static int tegra_bo_create(struct bo *bo, uint32_t width, uint32_t height,
uint32_t format, uint32_t flags)
{
@@ -162,24 +179,13 @@ static void *tegra_bo_map(struct bo *bo, struct map_info *data, size_t plane)
bo->drv->fd, gem_map.offset);
}
-const struct backend backend_tegra =
+struct backend backend_tegra =
{
.name = "tegra",
+ .init = tegra_init,
.bo_create = tegra_bo_create,
.bo_destroy = drv_gem_bo_destroy,
.bo_map = tegra_bo_map,
- .format_list = {
- /* Linear support */
- {DRM_FORMAT_XRGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR
- | DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
- {DRM_FORMAT_ARGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR
- | DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
- /* Blocklinear support */
- {DRM_FORMAT_XRGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_RENDERING |
- DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
- {DRM_FORMAT_ARGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_RENDERING |
- DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
- }
};
#endif
diff --git a/udl.c b/udl.c
index 3e845f6..2608afb 100644
--- a/udl.c
+++ b/udl.c
@@ -6,17 +6,26 @@
#include "drv_priv.h"
#include "helpers.h"
+#include "util.h"
-const struct backend backend_udl =
+static struct supported_combination combos[4] = {
+ {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE, DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR},
+ {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE, DRV_BO_USE_RENDERING},
+ {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE, DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR},
+ {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE, DRV_BO_USE_RENDERING},
+};
+
+static int udl_init(struct driver *drv)
+{
+ drv_insert_combinations(drv, combos, ARRAY_SIZE(combos));
+ return drv_add_kms_flags(drv);
+}
+
+struct backend backend_udl =
{
.name = "udl",
+ .init = udl_init,
.bo_create = drv_dumb_bo_create,
.bo_destroy = drv_dumb_bo_destroy,
.bo_map = drv_dumb_bo_map,
- .format_list = {
- {DRM_FORMAT_XRGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_RENDERING},
- {DRM_FORMAT_XRGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR},
- {DRM_FORMAT_ARGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_RENDERING},
- {DRM_FORMAT_ARGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR},
- }
};
diff --git a/vgem.c b/vgem.c
index 56f91b8..21d8f22 100644
--- a/vgem.c
+++ b/vgem.c
@@ -6,6 +6,20 @@
#include "drv_priv.h"
#include "helpers.h"
+#include "util.h"
+
+static struct supported_combination combos[2] = {
+ {DRM_FORMAT_ABGR8888, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_RENDERING | DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
+ {DRM_FORMAT_YVU420, DRM_FORMAT_MOD_NONE,
+ DRV_BO_USE_RENDERING | DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
+};
+
+static int vgem_init(struct driver *drv)
+{
+ drv_insert_combinations(drv, combos, ARRAY_SIZE(combos));
+ return drv_add_kms_flags(drv);
+}
static uint32_t vgem_resolve_format(uint32_t format)
{
@@ -20,18 +34,13 @@ static uint32_t vgem_resolve_format(uint32_t format)
}
}
-const struct backend backend_vgem =
+struct backend backend_vgem =
{
.name = "vgem",
+ .init = vgem_init,
.bo_create = drv_dumb_bo_create,
.bo_destroy = drv_dumb_bo_destroy,
.bo_map = drv_dumb_bo_map,
.resolve_format = vgem_resolve_format,
- .format_list = {
- {DRM_FORMAT_ABGR8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_RENDERING | DRV_BO_USE_CURSOR
- | DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
- {DRM_FORMAT_YVU420, DRV_BO_USE_SCANOUT | DRV_BO_USE_RENDERING |
- DRV_BO_USE_SW_READ_RARELY | DRV_BO_USE_SW_WRITE_RARELY},
- }
};
diff --git a/virtio_gpu.c b/virtio_gpu.c
index 20420cc..d711f82 100644
--- a/virtio_gpu.c
+++ b/virtio_gpu.c
@@ -6,18 +6,27 @@
#include "drv_priv.h"
#include "helpers.h"
+#include "util.h"
-const struct backend backend_virtio_gpu =
+static struct supported_combination combos[4] = {
+ {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE, DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR},
+ {DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE, DRV_BO_USE_RENDERING},
+ {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE, DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR},
+ {DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE, DRV_BO_USE_RENDERING},
+};
+
+static int virtio_gpu_init(struct driver *drv)
+{
+ drv_insert_combinations(drv, combos, ARRAY_SIZE(combos));
+ return drv_add_kms_flags(drv);
+}
+
+struct backend backend_virtio_gpu =
{
.name = "virtio_gpu",
+ .init = virtio_gpu_init,
.bo_create = drv_dumb_bo_create,
.bo_destroy = drv_dumb_bo_destroy,
.bo_map = drv_dumb_bo_map,
- .format_list = {
- {DRM_FORMAT_XRGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_RENDERING},
- {DRM_FORMAT_XRGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR},
- {DRM_FORMAT_ARGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_RENDERING},
- {DRM_FORMAT_ARGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR},
- }
};