minigbm: rework flag API
We've been back and forth on the semantics of the flag API many times, and the current situation is confusing. Change the drivers so every combination defines a distinct type of buffer. That means if the same format is in the combination list three times, the tiling or format modifiers of one of those combinations must be different from the other two. Let's add a priority variable in struct supported_combination that breaks ties. For example, if a consumer specifies BO_USE_TEXTURE, we of course can texture from both linear and tiled buffers, but because a tiled buffer's priority is greater, it will be chosen. If a consumer specifies BO_USE_TEXTURE | BO_USE_SW_WRITE_OFTEN, the tiled combination won't have the BO_USE_SW_WRITE_OFTEN flag and the linear combination will be chosen. We expect drivers to modify the combinations after querying KMS. This is clunky using linked lists, so get rid of list.h and use arrays. BUG=chromium:616275 TEST=all the following compiles: emerge-cyan minigbm/arc-cros-gralloc emerge-oak minigbm/arc-cros-gralloc emerge-veyron_minnie-cheets minigbm/arc-cros-gralloc emerge-peach_pi minigbm emerge-nyan_big minigbm emerge-jadeite minigbm Tested with gbmtest on cyan, checked if Chrome boots Change-Id: Ib3fccf6f0cb86c8ded45924297df3c06f8e49271 Reviewed-on: https://chromium-review.googlesource.com/448252 Commit-Ready: Gurchetan Singh <gurchetansingh@chromium.org> Tested-by: Gurchetan Singh <gurchetansingh@chromium.org> Reviewed-by: Stéphane Marchesin <marcheu@chromium.org>
This commit is contained in:
parent
4d22b4e285
commit
6b41fb55de
23 changed files with 538 additions and 591 deletions
80
amdgpu.c
80
amdgpu.c
|
|
@ -39,17 +39,8 @@ enum {
|
|||
FAMILY_LAST,
|
||||
};
|
||||
|
||||
static struct supported_combination combos[5] = {
|
||||
{DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN},
|
||||
{DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_XBGR8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN},
|
||||
{DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
const static uint32_t supported_formats[] = {
|
||||
DRM_FORMAT_ARGB8888, DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888
|
||||
};
|
||||
|
||||
static int amdgpu_set_metadata(int fd, uint32_t handle,
|
||||
|
|
@ -162,9 +153,10 @@ static int amdgpu_addrlib_compute(void *addrlib, uint32_t width,
|
|||
|
||||
/* Set the requested tiling mode. */
|
||||
addr_surf_info_in.tileMode = ADDR_TM_2D_TILED_THIN1;
|
||||
if (usage & (BO_USE_CURSOR | BO_USE_LINEAR))
|
||||
if (usage & (BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_SW_READ_OFTEN |
|
||||
BO_USE_SW_WRITE_OFTEN))
|
||||
addr_surf_info_in.tileMode = ADDR_TM_LINEAR_ALIGNED;
|
||||
if (width <= 16 || height <= 16)
|
||||
else if (width <= 16 || height <= 16)
|
||||
addr_surf_info_in.tileMode = ADDR_TM_1D_TILED_THIN1;
|
||||
|
||||
/* Bits per pixel should be calculated from format*/
|
||||
|
|
@ -289,7 +281,10 @@ static void *amdgpu_addrlib_init(int fd)
|
|||
|
||||
static int amdgpu_init(struct driver *drv)
|
||||
{
|
||||
int ret;
|
||||
void *addrlib;
|
||||
struct format_metadata metadata;
|
||||
uint32_t flags = BO_COMMON_USE_MASK;
|
||||
|
||||
addrlib = amdgpu_addrlib_init(drv_get_fd(drv));
|
||||
if (!addrlib)
|
||||
|
|
@ -297,8 +292,63 @@ static int amdgpu_init(struct driver *drv)
|
|||
|
||||
drv->priv = addrlib;
|
||||
|
||||
drv_insert_combinations(drv, combos, ARRAY_SIZE(combos));
|
||||
return drv_add_kms_flags(drv);
|
||||
metadata.tiling = ADDR_DISPLAYABLE << 16 | ADDR_TM_LINEAR_ALIGNED;
|
||||
metadata.priority = 1;
|
||||
metadata.modifier = DRM_FORMAT_MOD_NONE;
|
||||
|
||||
ret = drv_add_combinations(drv, supported_formats,
|
||||
ARRAY_SIZE(supported_formats), &metadata,
|
||||
flags);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
drv_modify_combination(drv, DRM_FORMAT_ARGB8888, &metadata,
|
||||
BO_USE_CURSOR | BO_USE_SCANOUT);
|
||||
drv_modify_combination(drv, DRM_FORMAT_XRGB8888, &metadata,
|
||||
BO_USE_CURSOR | BO_USE_SCANOUT);
|
||||
drv_modify_combination(drv, DRM_FORMAT_XBGR8888, &metadata,
|
||||
BO_USE_SCANOUT);
|
||||
|
||||
metadata.tiling = ADDR_NON_DISPLAYABLE << 16 | ADDR_TM_LINEAR_ALIGNED;
|
||||
metadata.priority = 2;
|
||||
metadata.modifier = DRM_FORMAT_MOD_NONE;
|
||||
|
||||
ret = drv_add_combinations(drv, supported_formats,
|
||||
ARRAY_SIZE(supported_formats), &metadata,
|
||||
flags);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
flags &= ~BO_USE_SW_WRITE_OFTEN;
|
||||
flags &= ~BO_USE_SW_READ_OFTEN;
|
||||
flags &= ~BO_USE_LINEAR;
|
||||
|
||||
metadata.tiling = ADDR_DISPLAYABLE << 16 | ADDR_TM_2D_TILED_THIN1;
|
||||
metadata.priority = 3;
|
||||
|
||||
ret = drv_add_combinations(drv, supported_formats,
|
||||
ARRAY_SIZE(supported_formats), &metadata,
|
||||
flags);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
drv_modify_combination(drv, DRM_FORMAT_ARGB8888, &metadata,
|
||||
BO_USE_SCANOUT);
|
||||
drv_modify_combination(drv, DRM_FORMAT_XRGB8888, &metadata,
|
||||
BO_USE_SCANOUT);
|
||||
drv_modify_combination(drv, DRM_FORMAT_XBGR8888, &metadata,
|
||||
BO_USE_SCANOUT);
|
||||
|
||||
metadata.tiling = ADDR_NON_DISPLAYABLE << 16 | ADDR_TM_2D_TILED_THIN1;
|
||||
metadata.priority = 4;
|
||||
|
||||
ret = drv_add_combinations(drv, supported_formats,
|
||||
ARRAY_SIZE(supported_formats), &metadata,
|
||||
flags);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void amdgpu_close(struct driver *drv)
|
||||
|
|
|
|||
16
cirrus.c
16
cirrus.c
|
|
@ -8,22 +8,14 @@
|
|||
#include "helpers.h"
|
||||
#include "util.h"
|
||||
|
||||
static struct supported_combination combos[3] = {
|
||||
{DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN |
|
||||
BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_RGB888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN |
|
||||
BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN |
|
||||
BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
const static uint32_t supported_formats[] = {
|
||||
DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB888, DRM_FORMAT_XRGB8888
|
||||
};
|
||||
|
||||
static int cirrus_init(struct driver *drv)
|
||||
{
|
||||
drv_insert_combinations(drv, combos, ARRAY_SIZE(combos));
|
||||
return drv_add_kms_flags(drv);
|
||||
return drv_add_linear_combinations(drv, supported_formats,
|
||||
ARRAY_SIZE(supported_formats));
|
||||
}
|
||||
|
||||
struct backend backend_cirrus =
|
||||
|
|
|
|||
|
|
@ -10,34 +10,23 @@ static struct cros_gralloc_bo *cros_gralloc_bo_create(struct driver *drv,
|
|||
int width, int height,
|
||||
int format, int usage)
|
||||
{
|
||||
int32_t supported;
|
||||
uint64_t drv_usage;
|
||||
uint32_t drv_format;
|
||||
struct combination *combo;
|
||||
struct cros_gralloc_bo *bo;
|
||||
|
||||
drv_format = cros_gralloc_convert_format(format);
|
||||
drv_format = drv_resolve_format(drv, drv_format);
|
||||
drv_usage = cros_gralloc_convert_flags(usage);
|
||||
|
||||
supported = drv_is_combination_supported(drv, drv_format, drv_usage,
|
||||
DRM_FORMAT_MOD_NONE);
|
||||
combo = drv_get_combination(drv, drv_format, drv_usage);
|
||||
|
||||
if (!supported && (usage & GRALLOC_USAGE_HW_COMPOSER)) {
|
||||
if (!combo && (usage & GRALLOC_USAGE_HW_COMPOSER)) {
|
||||
drv_usage &= ~BO_USE_SCANOUT;
|
||||
supported = drv_is_combination_supported(drv, drv_format,
|
||||
drv_usage,
|
||||
DRM_FORMAT_MOD_NONE);
|
||||
combo = drv_get_combination(drv, drv_format, drv_usage);
|
||||
}
|
||||
|
||||
if (!supported && (drv_usage & BO_USE_RENDERING) &&
|
||||
(drv_usage && (BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN))) {
|
||||
drv_usage &= ~BO_USE_RENDERING;
|
||||
supported = drv_is_combination_supported(drv, drv_format,
|
||||
drv_usage,
|
||||
DRM_FORMAT_MOD_NONE);
|
||||
}
|
||||
|
||||
if (!supported) {
|
||||
if (!combo) {
|
||||
cros_gralloc_error("Unsupported combination -- HAL format: %u, "
|
||||
"HAL flags: %u, drv_format: %u, "
|
||||
"drv_flags: %llu", format, usage,
|
||||
|
|
|
|||
39
drv.c
39
drv.c
|
|
@ -131,12 +131,20 @@ struct driver *drv_create(int fd)
|
|||
if (!drv->map_table)
|
||||
goto free_buffer_table;
|
||||
|
||||
LIST_INITHEAD(&drv->backend->combinations);
|
||||
/* Start with a power of 2 number of allocations. */
|
||||
drv->backend->combos.allocations = 2;
|
||||
drv->backend->combos.size = 0;
|
||||
drv->backend->combos.data = calloc(drv->backend->combos.allocations,
|
||||
sizeof(struct combination));
|
||||
if (!drv->backend->combos.data)
|
||||
goto free_map_table;
|
||||
|
||||
if (drv->backend->init) {
|
||||
ret = drv->backend->init(drv);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
free(drv->backend->combos.data);
|
||||
goto free_map_table;
|
||||
}
|
||||
}
|
||||
|
||||
return drv;
|
||||
|
|
@ -162,11 +170,7 @@ void drv_destroy(struct driver *drv)
|
|||
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);
|
||||
}
|
||||
free(drv->backend->combos.data);
|
||||
|
||||
pthread_mutex_unlock(&drv->driver_lock);
|
||||
pthread_mutex_destroy(&drv->driver_lock);
|
||||
|
|
@ -185,22 +189,25 @@ drv_get_name(struct driver *drv)
|
|||
return drv->backend->name;
|
||||
}
|
||||
|
||||
int drv_is_combination_supported(struct driver *drv, uint32_t format,
|
||||
uint64_t usage, uint64_t modifier)
|
||||
struct combination *drv_get_combination(struct driver *drv, uint32_t format,
|
||||
uint64_t usage)
|
||||
{
|
||||
struct combination *curr, *best;
|
||||
|
||||
if (format == DRM_FORMAT_NONE || usage == BO_USE_NONE)
|
||||
return 0;
|
||||
|
||||
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;
|
||||
best = NULL;
|
||||
uint32_t i;
|
||||
for (i = 0; i < drv->backend->combos.size; i++) {
|
||||
curr = &drv->backend->combos.data[i];
|
||||
if ((format == curr->format) && usage == (curr->usage & usage))
|
||||
if (!best ||
|
||||
best->metadata.priority < curr->metadata.priority)
|
||||
best = curr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return best;
|
||||
}
|
||||
|
||||
struct bo *drv_bo_new(struct driver *drv, uint32_t width, uint32_t height,
|
||||
|
|
|
|||
10
drv.h
10
drv.h
|
|
@ -47,8 +47,13 @@ extern "C" {
|
|||
#define DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED fourcc_code('9', '9', '9', '8')
|
||||
#define DRM_FORMAT_FLEX_YCbCr_420_888 fourcc_code('9', '9', '9', '9')
|
||||
|
||||
#define BO_COMMON_USE_MASK BO_USE_LINEAR | BO_USE_RENDERING | \
|
||||
BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN | \
|
||||
BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY | \
|
||||
BO_USE_TEXTURE
|
||||
struct driver;
|
||||
struct bo;
|
||||
struct combination;
|
||||
|
||||
union bo_handle {
|
||||
void *ptr;
|
||||
|
|
@ -81,9 +86,8 @@ drv_get_fd(struct driver *drv);
|
|||
const char *
|
||||
drv_get_name(struct driver *drv);
|
||||
|
||||
int
|
||||
drv_is_combination_supported(struct driver *drv, uint32_t format,
|
||||
uint64_t usage, uint64_t modifier);
|
||||
struct combination *
|
||||
drv_get_combination(struct driver *drv, uint32_t format, uint64_t usage);
|
||||
|
||||
struct bo *
|
||||
drv_bo_new(struct driver *drv, uint32_t width, uint32_t height,
|
||||
|
|
|
|||
24
drv_priv.h
24
drv_priv.h
|
|
@ -13,7 +13,6 @@
|
|||
#include <sys/types.h>
|
||||
|
||||
#include "drv.h"
|
||||
#include "list.h"
|
||||
|
||||
struct bo
|
||||
{
|
||||
|
|
@ -49,15 +48,28 @@ struct map_info {
|
|||
void *priv;
|
||||
};
|
||||
|
||||
struct supported_combination {
|
||||
struct kms_item {
|
||||
uint32_t format;
|
||||
uint64_t modifier;
|
||||
uint64_t usage;
|
||||
};
|
||||
|
||||
struct combination_list_element {
|
||||
struct supported_combination combination;
|
||||
struct list_head link;
|
||||
struct format_metadata {
|
||||
uint32_t priority;
|
||||
uint32_t tiling;
|
||||
uint64_t modifier;
|
||||
};
|
||||
|
||||
struct combination {
|
||||
uint32_t format;
|
||||
struct format_metadata metadata;
|
||||
uint64_t usage;
|
||||
};
|
||||
|
||||
struct combinations {
|
||||
struct combination *data;
|
||||
uint32_t size;
|
||||
uint32_t allocations;
|
||||
};
|
||||
|
||||
struct backend
|
||||
|
|
@ -77,7 +89,7 @@ struct backend
|
|||
void* (*bo_map)(struct bo *bo, struct map_info *data, size_t plane);
|
||||
int (*bo_unmap)(struct bo *bo, struct map_info *data);
|
||||
uint32_t (*resolve_format)(uint32_t format);
|
||||
struct list_head combinations;
|
||||
struct combinations combos;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
13
evdi.c
13
evdi.c
|
|
@ -8,19 +8,14 @@
|
|||
#include "helpers.h"
|
||||
#include "util.h"
|
||||
|
||||
static struct supported_combination combos[2] = {
|
||||
{DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN |
|
||||
BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN |
|
||||
BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
static const uint32_t supported_formats[] = {
|
||||
DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888
|
||||
};
|
||||
|
||||
static int evdi_init(struct driver *drv)
|
||||
{
|
||||
drv_insert_combinations(drv, combos, ARRAY_SIZE(combos));
|
||||
return drv_add_kms_flags(drv);
|
||||
return drv_add_linear_combinations(drv, supported_formats,
|
||||
ARRAY_SIZE(supported_formats));
|
||||
}
|
||||
|
||||
struct backend backend_evdi =
|
||||
|
|
|
|||
16
exynos.c
16
exynos.c
|
|
@ -17,22 +17,14 @@
|
|||
#include "helpers.h"
|
||||
#include "util.h"
|
||||
|
||||
static struct supported_combination combos[3] = {
|
||||
{DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN |
|
||||
BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_NV12, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN |
|
||||
BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN |
|
||||
BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
static const uint32_t supported_formats[] = {
|
||||
DRM_FORMAT_ARGB8888, DRM_FORMAT_NV12, DRM_FORMAT_XRGB8888
|
||||
};
|
||||
|
||||
static int exynos_init(struct driver *drv)
|
||||
{
|
||||
drv_insert_combinations(drv, combos, ARRAY_SIZE(combos));
|
||||
return drv_add_kms_flags(drv);
|
||||
return drv_add_linear_combinations(drv, supported_formats,
|
||||
ARRAY_SIZE(supported_formats));
|
||||
}
|
||||
|
||||
static int exynos_bo_create(struct bo *bo, uint32_t width, uint32_t height,
|
||||
|
|
|
|||
3
gbm.c
3
gbm.c
|
|
@ -42,8 +42,7 @@ gbm_device_is_format_supported(struct gbm_device *gbm,
|
|||
|
||||
drv_usage = gbm_convert_flags(usage);
|
||||
|
||||
return drv_is_combination_supported(gbm->drv, format, drv_usage,
|
||||
DRM_FORMAT_MOD_NONE);
|
||||
return (drv_get_combination(gbm->drv, format, drv_usage) != NULL);
|
||||
}
|
||||
|
||||
PUBLIC struct gbm_device *gbm_create_device(int fd)
|
||||
|
|
|
|||
10
gma500.c
10
gma500.c
|
|
@ -8,16 +8,14 @@
|
|||
#include "helpers.h"
|
||||
#include "util.h"
|
||||
|
||||
static struct supported_combination combos[1] = {
|
||||
{DRM_FORMAT_RGBX8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN |
|
||||
BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
static const uint32_t supported_formats[] = {
|
||||
DRM_FORMAT_RGBX8888
|
||||
};
|
||||
|
||||
static int gma500_init(struct driver *drv)
|
||||
{
|
||||
drv_insert_combinations(drv, combos, ARRAY_SIZE(combos));
|
||||
return drv_add_kms_flags(drv);
|
||||
return drv_add_linear_combinations(drv, supported_formats,
|
||||
ARRAY_SIZE(supported_formats));
|
||||
}
|
||||
|
||||
struct backend backend_gma500 =
|
||||
|
|
|
|||
221
helpers.c
221
helpers.c
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
@ -318,81 +319,77 @@ uint32_t drv_log_base2(uint32_t value)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* Inserts a combination into list -- caller should have lock on driver. */
|
||||
void drv_insert_supported_combination(struct driver *drv, uint32_t format,
|
||||
uint64_t usage, uint64_t modifier)
|
||||
int drv_add_combination(struct driver *drv, uint32_t format,
|
||||
struct format_metadata *metadata, uint64_t usage)
|
||||
{
|
||||
struct combination_list_element *elem;
|
||||
struct combinations *combos = &drv->backend->combos;
|
||||
if (combos->size >= combos->allocations) {
|
||||
struct combination *new_data;
|
||||
combos->allocations *= 2;
|
||||
new_data = realloc(combos->data, combos->allocations
|
||||
* sizeof(*combos->data));
|
||||
if (!new_data)
|
||||
return -ENOMEM;
|
||||
|
||||
elem = calloc(1, sizeof(*elem));
|
||||
elem->combination.format = format;
|
||||
elem->combination.modifier = modifier;
|
||||
elem->combination.usage = usage;
|
||||
LIST_ADD(&elem->link, &drv->backend->combinations);
|
||||
}
|
||||
|
||||
void drv_insert_combinations(struct driver *drv, struct supported_combination *combos,
|
||||
uint32_t size)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
pthread_mutex_lock(&drv->driver_lock);
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
drv_insert_supported_combination(drv, combos[i].format,
|
||||
combos[i].usage,
|
||||
combos[i].modifier);
|
||||
|
||||
pthread_mutex_unlock(&drv->driver_lock);
|
||||
}
|
||||
|
||||
void drv_modify_supported_combination(struct driver *drv, uint32_t format,
|
||||
uint64_t usage, uint64_t modifier)
|
||||
{
|
||||
/*
|
||||
* Attempts to add the specified usage to an existing {format, modifier}
|
||||
* pair. If the pair is not present, a new combination is created.
|
||||
*/
|
||||
int found = 0;
|
||||
|
||||
pthread_mutex_lock(&drv->driver_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;
|
||||
}
|
||||
combos->data = new_data;
|
||||
}
|
||||
|
||||
|
||||
if (!found)
|
||||
drv_insert_supported_combination(drv, format, usage, modifier);
|
||||
|
||||
pthread_mutex_unlock(&drv->driver_lock);
|
||||
combos->data[combos->size].format = format;
|
||||
combos->data[combos->size].metadata.priority = metadata->priority;
|
||||
combos->data[combos->size].metadata.tiling = metadata->tiling;
|
||||
combos->data[combos->size].metadata.modifier = metadata->modifier;
|
||||
combos->data[combos->size].usage = usage;
|
||||
combos->size++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drv_add_kms_flags(struct driver *drv)
|
||||
int drv_add_combinations(struct driver *drv, const uint32_t *formats,
|
||||
uint32_t num_formats, struct format_metadata *metadata,
|
||||
uint64_t usage)
|
||||
{
|
||||
int ret;
|
||||
uint32_t i, j;
|
||||
uint32_t i;
|
||||
for (i = 0; i < num_formats; i++) {
|
||||
ret = drv_add_combination(drv, formats[i], metadata, usage);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void drv_modify_combination(struct driver *drv, uint32_t format,
|
||||
struct format_metadata *metadata, uint64_t usage)
|
||||
{
|
||||
uint32_t i;
|
||||
struct combination *combo;
|
||||
/* Attempts to add the specified usage to an existing combination. */
|
||||
for (i = 0; i < drv->backend->combos.size; i++) {
|
||||
combo = &drv->backend->combos.data[i];
|
||||
if (combo->format == format &&
|
||||
combo->metadata.tiling == metadata->tiling &&
|
||||
combo->metadata.modifier == metadata->modifier)
|
||||
combo->usage |= usage;
|
||||
}
|
||||
}
|
||||
|
||||
struct kms_item *drv_query_kms(struct driver *drv, uint32_t *num_items)
|
||||
{
|
||||
uint64_t flag, usage;
|
||||
struct kms_item *items;
|
||||
uint32_t i, j, k, allocations, item_size;
|
||||
|
||||
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_modify_supported_combination(drv, DRM_FORMAT_XRGB8888,
|
||||
BO_USE_SCANOUT, 0);
|
||||
drv_modify_supported_combination(drv, DRM_FORMAT_ARGB8888,
|
||||
BO_USE_SCANOUT, 0);
|
||||
/* Start with a power of 2 number of allocations. */
|
||||
allocations = 2;
|
||||
item_size = 0;
|
||||
items = calloc(allocations, sizeof(*items));
|
||||
if (!items)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* The ability to return universal planes is only complete on
|
||||
|
|
@ -406,27 +403,25 @@ int drv_add_kms_flags(struct driver *drv)
|
|||
|
||||
resources = drmModeGetPlaneResources(drv->fd);
|
||||
if (!resources)
|
||||
goto err;
|
||||
goto out;
|
||||
|
||||
for (i = 0; i < resources->count_planes; i++) {
|
||||
|
||||
plane = drmModeGetPlane(drv->fd, resources->planes[i]);
|
||||
|
||||
if (!plane)
|
||||
goto err;
|
||||
goto out;
|
||||
|
||||
props = drmModeObjectGetProperties(drv->fd, plane->plane_id,
|
||||
DRM_MODE_OBJECT_PLANE);
|
||||
if (!props)
|
||||
goto err;
|
||||
goto out;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -443,9 +438,37 @@ int drv_add_kms_flags(struct driver *drv)
|
|||
assert(0);
|
||||
}
|
||||
|
||||
for (j = 0; j < plane->count_formats; j++)
|
||||
drv_modify_supported_combination(drv, plane->formats[j],
|
||||
usage, 0);
|
||||
for (j = 0; j < plane->count_formats; j++) {
|
||||
bool found = false;
|
||||
for (k = 0; k < item_size; k++) {
|
||||
if (items[k].format == plane->formats[j] &&
|
||||
items[k].modifier == DRM_FORMAT_MOD_NONE) {
|
||||
items[k].usage |= usage;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found && item_size >= allocations) {
|
||||
struct kms_item *new_data = NULL;
|
||||
allocations *= 2;
|
||||
new_data = realloc(items, allocations *
|
||||
sizeof(*items));
|
||||
if (!new_data) {
|
||||
item_size = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
items = new_data;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
items[item_size].format = plane->formats[j];
|
||||
items[item_size].modifier = DRM_FORMAT_MOD_NONE;
|
||||
items[item_size].usage = usage;
|
||||
item_size++;
|
||||
}
|
||||
}
|
||||
|
||||
drmModeFreeObjectProperties(props);
|
||||
drmModeFreePlane(plane);
|
||||
|
|
@ -453,9 +476,59 @@ int drv_add_kms_flags(struct driver *drv)
|
|||
}
|
||||
|
||||
drmModeFreePlaneResources(resources);
|
||||
return 0;
|
||||
out:
|
||||
if (items && item_size == 0) {
|
||||
free(items);
|
||||
items = NULL;
|
||||
}
|
||||
|
||||
err:
|
||||
ret = -1;
|
||||
return ret;
|
||||
*num_items = item_size;
|
||||
return items;
|
||||
}
|
||||
|
||||
int drv_add_linear_combinations(struct driver *drv, const uint32_t *formats,
|
||||
uint32_t num_formats)
|
||||
{
|
||||
int ret;
|
||||
uint32_t i, j, num_items;
|
||||
struct kms_item *items;
|
||||
struct combination *combo;
|
||||
struct format_metadata metadata;
|
||||
|
||||
metadata.tiling = 0;
|
||||
metadata.priority = 1;
|
||||
metadata.modifier = DRM_FORMAT_MOD_NONE;
|
||||
|
||||
ret = drv_add_combinations(drv, formats, num_formats, &metadata,
|
||||
BO_COMMON_USE_MASK);
|
||||
if (ret)
|
||||
return ret;
|
||||
/*
|
||||
* All current drivers can scanout linear XRGB8888/ARGB8888 as a primary
|
||||
* plane and as a cursor. Some drivers don't support
|
||||
* drmModeGetPlaneResources, so add the combination here. Note that the
|
||||
* kernel disregards the alpha component of ARGB unless it's an overlay
|
||||
* plane.
|
||||
*/
|
||||
drv_modify_combination(drv, DRM_FORMAT_XRGB8888, &metadata,
|
||||
BO_USE_CURSOR | BO_USE_SCANOUT);
|
||||
drv_modify_combination(drv, DRM_FORMAT_ARGB8888, &metadata,
|
||||
BO_USE_CURSOR | BO_USE_SCANOUT);
|
||||
|
||||
items = drv_query_kms(drv, &num_items);
|
||||
if (!items || !num_items)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < num_items; i++) {
|
||||
for (j = 0; j < drv->backend->combos.size; j++) {
|
||||
combo = &drv->backend->combos.data[j];
|
||||
if (items[i].format == combo->format)
|
||||
combo->usage |= BO_USE_SCANOUT;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
free(items);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
18
helpers.h
18
helpers.h
|
|
@ -25,12 +25,14 @@ 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);
|
||||
void drv_modify_supported_combination(struct driver *drv, uint32_t format,
|
||||
uint64_t usage, uint64_t modifier);
|
||||
int drv_add_kms_flags(struct driver *drv);
|
||||
int drv_add_combination(struct driver *drv, uint32_t format,
|
||||
struct format_metadata *metadata, uint64_t usage);
|
||||
int drv_add_combinations(struct driver *drv, const uint32_t *formats,
|
||||
uint32_t num_formats, struct format_metadata *metadata,
|
||||
uint64_t usage);
|
||||
void drv_modify_combination(struct driver *drv, uint32_t format,
|
||||
struct format_metadata *metadata, uint64_t usage);
|
||||
struct kms_item *drv_query_kms(struct driver *drv, uint32_t *num_items);
|
||||
int drv_add_linear_combinations(struct driver *drv, const uint32_t *formats,
|
||||
uint32_t num_formats);
|
||||
#endif
|
||||
|
|
|
|||
144
i915.c
144
i915.c
|
|
@ -17,45 +17,14 @@
|
|||
#include "helpers.h"
|
||||
#include "util.h"
|
||||
|
||||
static struct supported_combination combos[19] = {
|
||||
{DRM_FORMAT_ARGB1555, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_ABGR8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN},
|
||||
{DRM_FORMAT_ABGR8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN},
|
||||
{DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_GR88, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN},
|
||||
{DRM_FORMAT_R8, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN},
|
||||
{DRM_FORMAT_RGB565, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_UYVY, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN},
|
||||
{DRM_FORMAT_UYVY, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_XBGR8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN},
|
||||
{DRM_FORMAT_XBGR8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_XRGB1555, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN},
|
||||
{DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_YUYV, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN},
|
||||
{DRM_FORMAT_YUYV, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_YVU420, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_YVU420, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN},
|
||||
static const uint32_t tileable_formats[] = {
|
||||
DRM_FORMAT_ARGB1555, DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888,
|
||||
DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB1555,
|
||||
DRM_FORMAT_XRGB8888, DRM_FORMAT_UYVY, DRM_FORMAT_YUYV
|
||||
};
|
||||
|
||||
static const uint32_t linear_only_formats[] = {
|
||||
DRM_FORMAT_GR88, DRM_FORMAT_R8, DRM_FORMAT_YVU420
|
||||
};
|
||||
|
||||
struct i915_device
|
||||
|
|
@ -82,6 +51,100 @@ static int get_gen(int device_id)
|
|||
return 4;
|
||||
}
|
||||
|
||||
static int i915_add_kms_item(struct driver *drv, const struct kms_item *item)
|
||||
{
|
||||
uint32_t i;
|
||||
struct combination *combo;
|
||||
|
||||
/*
|
||||
* Older hardware can't scanout Y-tiled formats. Newer devices can, and
|
||||
* report this functionality via format modifiers.
|
||||
*/
|
||||
for (i = 0; i < drv->backend->combos.size; i++) {
|
||||
combo = &drv->backend->combos.data[i];
|
||||
if (combo->format == item->format) {
|
||||
if ((combo->metadata.tiling == I915_TILING_Y &&
|
||||
item->modifier == I915_FORMAT_MOD_Y_TILED) ||
|
||||
(combo->metadata.tiling == I915_TILING_X &&
|
||||
item->modifier == I915_FORMAT_MOD_X_TILED)) {
|
||||
combo->metadata.modifier = item->modifier;
|
||||
combo->usage |= item->usage;
|
||||
} else if (combo->metadata.tiling != I915_TILING_Y) {
|
||||
combo->usage |= item->usage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i915_add_combinations(struct driver *drv)
|
||||
{
|
||||
int ret;
|
||||
uint32_t i, num_items;
|
||||
struct kms_item *items;
|
||||
struct format_metadata metadata;
|
||||
uint64_t flags = BO_COMMON_USE_MASK;
|
||||
|
||||
metadata.tiling = I915_TILING_NONE;
|
||||
metadata.priority = 1;
|
||||
metadata.modifier = DRM_FORMAT_MOD_NONE;
|
||||
|
||||
ret = drv_add_combinations(drv, linear_only_formats,
|
||||
ARRAY_SIZE(linear_only_formats), &metadata,
|
||||
flags);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = drv_add_combinations(drv, tileable_formats,
|
||||
ARRAY_SIZE(tileable_formats), &metadata,
|
||||
flags);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
drv_modify_combination(drv, DRM_FORMAT_XRGB8888, &metadata,
|
||||
BO_USE_CURSOR | BO_USE_SCANOUT);
|
||||
drv_modify_combination(drv, DRM_FORMAT_ARGB8888, &metadata,
|
||||
BO_USE_CURSOR | BO_USE_SCANOUT);
|
||||
|
||||
flags &= ~BO_USE_SW_WRITE_OFTEN;
|
||||
flags &= ~BO_USE_SW_READ_OFTEN;
|
||||
flags &= ~BO_USE_LINEAR;
|
||||
|
||||
metadata.tiling = I915_TILING_X;
|
||||
metadata.priority = 2;
|
||||
|
||||
ret = drv_add_combinations(drv, tileable_formats,
|
||||
ARRAY_SIZE(tileable_formats), &metadata,
|
||||
flags);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
metadata.tiling = I915_TILING_Y;
|
||||
metadata.priority = 3;
|
||||
|
||||
ret = drv_add_combinations(drv, tileable_formats,
|
||||
ARRAY_SIZE(tileable_formats), &metadata,
|
||||
flags);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
items = drv_query_kms(drv, &num_items);
|
||||
if (!items || !num_items)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < num_items; i++) {
|
||||
ret = i915_add_kms_item(drv, &items[i]);
|
||||
if (ret) {
|
||||
free(items);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
free(items);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void i915_align_dimensions(struct driver *drv, uint32_t tiling_mode,
|
||||
uint32_t *width, uint32_t *height, int bpp)
|
||||
{
|
||||
|
|
@ -165,8 +228,7 @@ static int i915_init(struct driver *drv)
|
|||
|
||||
drv->priv = i915_dev;
|
||||
|
||||
drv_insert_combinations(drv, combos, ARRAY_SIZE(combos));
|
||||
return drv_add_kms_flags(drv);
|
||||
return i915_add_combinations(drv);
|
||||
}
|
||||
|
||||
static void i915_close(struct driver *drv)
|
||||
|
|
|
|||
247
list.h
247
list.h
|
|
@ -1,247 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* 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_*/
|
||||
15
marvell.c
15
marvell.c
|
|
@ -10,19 +10,14 @@
|
|||
#include "helpers.h"
|
||||
#include "util.h"
|
||||
|
||||
static struct supported_combination combos[2] = {
|
||||
{DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN |
|
||||
BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN |
|
||||
BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
}
|
||||
static const uint32_t supported_formats[] = {
|
||||
DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888
|
||||
};
|
||||
|
||||
static int marvell_init(struct driver *drv)
|
||||
{
|
||||
drv_insert_combinations(drv, combos, ARRAY_SIZE(combos));
|
||||
return drv_add_kms_flags(drv);
|
||||
return drv_add_linear_combinations(drv, supported_formats,
|
||||
ARRAY_SIZE(supported_formats));
|
||||
}
|
||||
|
||||
struct backend backend_marvell =
|
||||
|
|
|
|||
26
mediatek.c
26
mediatek.c
|
|
@ -16,31 +16,15 @@
|
|||
#include "helpers.h"
|
||||
#include "util.h"
|
||||
|
||||
static struct supported_combination combos[6] = {
|
||||
{DRM_FORMAT_ABGR8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN |
|
||||
BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN |
|
||||
BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_RGB565, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN |
|
||||
BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_XBGR8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN |
|
||||
BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN |
|
||||
BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_YVU420, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN |
|
||||
BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
static const uint32_t supported_formats[] = {
|
||||
DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB565,
|
||||
DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888, DRM_FORMAT_YVU420
|
||||
};
|
||||
|
||||
static int mediatek_init(struct driver *drv)
|
||||
{
|
||||
drv_insert_combinations(drv, combos, ARRAY_SIZE(combos));
|
||||
return drv_add_kms_flags(drv);
|
||||
return drv_add_linear_combinations(drv, supported_formats,
|
||||
ARRAY_SIZE(supported_formats));
|
||||
}
|
||||
|
||||
static int mediatek_bo_create(struct bo *bo, uint32_t width, uint32_t height,
|
||||
|
|
|
|||
|
|
@ -8,15 +8,14 @@
|
|||
#include "helpers.h"
|
||||
#include "util.h"
|
||||
|
||||
static struct supported_combination combos[2] = {
|
||||
{DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE, BO_USE_CURSOR | BO_USE_RENDERING},
|
||||
{DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE, BO_USE_CURSOR | BO_USE_RENDERING},
|
||||
static const uint32_t supported_formats[] = {
|
||||
DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888
|
||||
};
|
||||
|
||||
static int nouveau_init(struct driver *drv)
|
||||
{
|
||||
drv_insert_combinations(drv, combos, ARRAY_SIZE(combos));
|
||||
return drv_add_kms_flags(drv);
|
||||
return drv_add_linear_combinations(drv, supported_formats,
|
||||
ARRAY_SIZE(supported_formats));
|
||||
}
|
||||
|
||||
struct backend backend_nouveau =
|
||||
|
|
|
|||
99
rockchip.c
99
rockchip.c
|
|
@ -7,6 +7,7 @@
|
|||
#ifdef DRV_ROCKCHIP
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
|
|
@ -17,33 +18,9 @@
|
|||
#include "helpers.h"
|
||||
#include "util.h"
|
||||
|
||||
static struct supported_combination combos[12] = {
|
||||
{DRM_FORMAT_ABGR8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN |
|
||||
BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN},
|
||||
{DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_NV12, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_NV12, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN},
|
||||
{DRM_FORMAT_RGB565, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_XBGR8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN |
|
||||
BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_XBGR8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN},
|
||||
{DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN},
|
||||
{DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_YVU420, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_YVU420, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN},
|
||||
static const uint32_t supported_formats[] = {
|
||||
DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB565,
|
||||
DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888, DRM_FORMAT_YVU420
|
||||
};
|
||||
|
||||
static int afbc_bo_from_format(struct bo *bo, uint32_t width, uint32_t height,
|
||||
|
|
@ -93,10 +70,74 @@ static int afbc_bo_from_format(struct bo *bo, uint32_t width, uint32_t height,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int rockchip_add_kms_item(struct driver *drv, const struct kms_item *item)
|
||||
{
|
||||
int ret;
|
||||
uint32_t i;
|
||||
uint64_t flags;
|
||||
struct combination *combo;
|
||||
struct format_metadata metadata;
|
||||
|
||||
for (i = 0; i < drv->backend->combos.size; i++) {
|
||||
combo = &drv->backend->combos.data[i];
|
||||
if (combo->format == item->format) {
|
||||
if (item->modifier ==
|
||||
DRM_FORMAT_MOD_CHROMEOS_ROCKCHIP_AFBC) {
|
||||
flags = BO_USE_RENDERING | BO_USE_SCANOUT |
|
||||
BO_USE_TEXTURE;
|
||||
metadata.modifier = item->modifier;
|
||||
metadata.tiling = 0;
|
||||
metadata.priority = 2;
|
||||
|
||||
ret = drv_add_combination(drv, item[i].format,
|
||||
&metadata, flags);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
combo->usage |= item->usage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rockchip_init(struct driver *drv)
|
||||
{
|
||||
drv_insert_combinations(drv, combos, ARRAY_SIZE(combos));
|
||||
return drv_add_kms_flags(drv);
|
||||
int ret;
|
||||
uint32_t i, num_items;
|
||||
struct kms_item *items;
|
||||
struct format_metadata metadata;
|
||||
|
||||
metadata.tiling = 0;
|
||||
metadata.priority = 1;
|
||||
metadata.modifier = DRM_FORMAT_MOD_NONE;
|
||||
|
||||
ret = drv_add_combinations(drv, supported_formats,
|
||||
ARRAY_SIZE(supported_formats), &metadata,
|
||||
BO_COMMON_USE_MASK);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
drv_modify_combination(drv, DRM_FORMAT_XRGB8888, &metadata,
|
||||
BO_USE_CURSOR | BO_USE_SCANOUT);
|
||||
drv_modify_combination(drv, DRM_FORMAT_ARGB8888, &metadata,
|
||||
BO_USE_CURSOR | BO_USE_SCANOUT);
|
||||
|
||||
items = drv_query_kms(drv, &num_items);
|
||||
if (!items || !num_items)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < num_items; i++) {
|
||||
ret = rockchip_add_kms_item(drv, &items[i]);
|
||||
if (ret) {
|
||||
free(items);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
free(items);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool has_modifier(const uint64_t *list, uint32_t count, uint64_t modifier)
|
||||
|
|
|
|||
57
tegra.c
57
tegra.c
|
|
@ -43,15 +43,8 @@ struct tegra_private_map_data {
|
|||
void *untiled;
|
||||
};
|
||||
|
||||
static struct supported_combination combos[4] = {
|
||||
{DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN},
|
||||
{DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN},
|
||||
{DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_RENDERING | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
static const uint32_t supported_formats[] = {
|
||||
DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888
|
||||
};
|
||||
|
||||
static int compute_block_height_log2(int height)
|
||||
|
|
@ -180,8 +173,43 @@ static void transfer_tiled_memory(struct bo *bo, uint8_t *tiled,
|
|||
|
||||
static int tegra_init(struct driver *drv)
|
||||
{
|
||||
drv_insert_combinations(drv, combos, ARRAY_SIZE(combos));
|
||||
return drv_add_kms_flags(drv);
|
||||
int ret;
|
||||
struct format_metadata metadata;
|
||||
uint64_t flags = BO_COMMON_USE_MASK;
|
||||
|
||||
metadata.tiling = NV_MEM_KIND_PITCH;
|
||||
metadata.priority = 1;
|
||||
metadata.modifier = DRM_FORMAT_MOD_NONE;
|
||||
|
||||
ret = drv_add_combinations(drv, supported_formats,
|
||||
ARRAY_SIZE(supported_formats), &metadata,
|
||||
flags);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
drv_modify_combination(drv, DRM_FORMAT_XRGB8888, &metadata,
|
||||
BO_USE_CURSOR | BO_USE_SCANOUT);
|
||||
drv_modify_combination(drv, DRM_FORMAT_ARGB8888, &metadata,
|
||||
BO_USE_CURSOR | BO_USE_SCANOUT);
|
||||
|
||||
flags &= ~BO_USE_SW_WRITE_OFTEN;
|
||||
flags &= ~BO_USE_SW_READ_OFTEN;
|
||||
flags &= ~BO_USE_LINEAR;
|
||||
|
||||
metadata.tiling = NV_MEM_KIND_C32_2CRA;
|
||||
metadata.priority = 2;
|
||||
|
||||
ret = drv_add_combinations(drv, supported_formats,
|
||||
ARRAY_SIZE(supported_formats), &metadata,
|
||||
flags);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
drv_modify_combination(drv, DRM_FORMAT_XRGB8888, &metadata,
|
||||
BO_USE_SCANOUT);
|
||||
drv_modify_combination(drv, DRM_FORMAT_ARGB8888, &metadata,
|
||||
BO_USE_SCANOUT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_bo_create(struct bo *bo, uint32_t width, uint32_t height,
|
||||
|
|
@ -192,11 +220,12 @@ static int tegra_bo_create(struct bo *bo, uint32_t width, uint32_t height,
|
|||
struct drm_tegra_gem_create gem_create;
|
||||
int ret;
|
||||
|
||||
if (flags & BO_USE_RENDERING)
|
||||
if (flags & (BO_USE_CURSOR | BO_USE_LINEAR |
|
||||
BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN))
|
||||
compute_layout_linear(width, height, format, &stride, &size);
|
||||
else
|
||||
compute_layout_blocklinear(width, height, format, &kind,
|
||||
&block_height_log2, &stride, &size);
|
||||
else
|
||||
compute_layout_linear(width, height, format, &stride, &size);
|
||||
|
||||
memset(&gem_create, 0, sizeof(gem_create));
|
||||
gem_create.size = size;
|
||||
|
|
|
|||
13
udl.c
13
udl.c
|
|
@ -8,19 +8,14 @@
|
|||
#include "helpers.h"
|
||||
#include "util.h"
|
||||
|
||||
static struct supported_combination combos[2] = {
|
||||
{DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN |
|
||||
BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN |
|
||||
BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
static const uint32_t supported_formats[] = {
|
||||
DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888
|
||||
};
|
||||
|
||||
static int udl_init(struct driver *drv)
|
||||
{
|
||||
drv_insert_combinations(drv, combos, ARRAY_SIZE(combos));
|
||||
return drv_add_kms_flags(drv);
|
||||
return drv_add_linear_combinations(drv, supported_formats,
|
||||
ARRAY_SIZE(supported_formats));
|
||||
}
|
||||
|
||||
struct backend backend_udl =
|
||||
|
|
|
|||
16
vc4.c
16
vc4.c
|
|
@ -16,22 +16,14 @@
|
|||
#include "helpers.h"
|
||||
#include "util.h"
|
||||
|
||||
static struct supported_combination combos[3] = {
|
||||
{DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN |
|
||||
BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_RGB565, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN |
|
||||
BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN |
|
||||
BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
static const uint32_t supported_formats[] = {
|
||||
DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB565, DRM_FORMAT_XRGB8888
|
||||
};
|
||||
|
||||
static int vc4_init(struct driver *drv)
|
||||
{
|
||||
drv_insert_combinations(drv, combos, ARRAY_SIZE(combos));
|
||||
return drv_add_kms_flags(drv);
|
||||
return drv_add_linear_combinations(drv, supported_formats,
|
||||
ARRAY_SIZE(supported_formats));
|
||||
}
|
||||
|
||||
static int vc4_bo_create(struct bo *bo, uint32_t width, uint32_t height,
|
||||
|
|
|
|||
19
vgem.c
19
vgem.c
|
|
@ -11,25 +11,14 @@
|
|||
#define MESA_LLVMPIPE_TILE_ORDER 6
|
||||
#define MESA_LLVMPIPE_TILE_SIZE (1 << MESA_LLVMPIPE_TILE_ORDER)
|
||||
|
||||
static struct supported_combination combos[4] = {
|
||||
{DRM_FORMAT_ABGR8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN |
|
||||
BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_RGB565, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN |
|
||||
BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_XBGR8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN |
|
||||
BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_YVU420, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN |
|
||||
BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
static const uint32_t supported_formats[] = {
|
||||
DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB565, DRM_FORMAT_XRGB8888
|
||||
};
|
||||
|
||||
static int vgem_init(struct driver *drv)
|
||||
{
|
||||
drv_insert_combinations(drv, combos, ARRAY_SIZE(combos));
|
||||
return 0;
|
||||
return drv_add_linear_combinations(drv, supported_formats,
|
||||
ARRAY_SIZE(supported_formats));
|
||||
}
|
||||
|
||||
static int vgem_bo_create(struct bo *bo, uint32_t width, uint32_t height,
|
||||
|
|
|
|||
13
virtio_gpu.c
13
virtio_gpu.c
|
|
@ -8,19 +8,14 @@
|
|||
#include "helpers.h"
|
||||
#include "util.h"
|
||||
|
||||
static struct supported_combination combos[2] = {
|
||||
{DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN |
|
||||
BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
{DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_NONE,
|
||||
BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_SW_READ_OFTEN |
|
||||
BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY},
|
||||
static const uint32_t supported_formats[] = {
|
||||
DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888
|
||||
};
|
||||
|
||||
static int virtio_gpu_init(struct driver *drv)
|
||||
{
|
||||
drv_insert_combinations(drv, combos, ARRAY_SIZE(combos));
|
||||
return drv_add_kms_flags(drv);
|
||||
return drv_add_linear_combinations(drv, supported_formats,
|
||||
ARRAY_SIZE(supported_formats));
|
||||
}
|
||||
|
||||
struct backend backend_virtio_gpu =
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue