gbm: Compat to mesa3d 20.1.5 APIs

Use gbm wrapper library to provide missing functions.

Change-Id: I62c9838f91adfd2f54df5eb75b256c361c7ce9a0
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
This commit is contained in:
Jeffy Chen 2020-08-13 16:18:41 +08:00
parent 23dbb929bd
commit 7359b29cb9
3 changed files with 464 additions and 32 deletions

297
gbm_wrapper.c Normal file
View file

@ -0,0 +1,297 @@
/*
* Copyright (c) 2020, Rockchip Electronics Co., Ltd
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <xf86drm.h>
#include <sys/mman.h>
#include "gbm.h"
#ifndef DRM_FORMAT_MOD_INVALID
#define DRM_FORMAT_MOD_INVALID ((1ULL<<56) - 1)
#endif
#ifndef HAS_gbm_bo_get_offset
uint32_t
gbm_bo_get_offset(struct gbm_bo *bo, int plane)
{
return 0;
}
#endif
#ifndef HAS_gbm_bo_get_modifier
uint64_t
gbm_bo_get_modifier(struct gbm_bo *bo)
{
return DRM_FORMAT_MOD_INVALID;
}
#endif
#ifndef HAS_gbm_bo_get_plane_count
int
gbm_bo_get_plane_count(struct gbm_bo *bo)
{
return 1;
}
#endif
#ifndef HAS_gbm_device_get_format_modifier_plane_count
int
gbm_device_get_format_modifier_plane_count(struct gbm_device *gbm,
uint32_t format,
uint64_t modifier)
{
return 1;
}
#endif
#ifndef HAS_gbm_bo_get_stride_for_plane
uint32_t
gbm_bo_get_stride_for_plane(struct gbm_bo *bo, int plane)
{
if (plane)
return 0;
return gbm_bo_get_stride(bo);
}
#endif
#ifndef HAS_gbm_bo_get_handle_for_plane
union gbm_bo_handle
gbm_bo_get_handle_for_plane(struct gbm_bo *bo, int plane)
{
union gbm_bo_handle ret;
ret.s32 = -1;
if (plane)
return ret;
return gbm_bo_get_handle(bo);
}
#endif
#ifndef HAS_gbm_bo_create_with_modifiers
struct gbm_bo *
gbm_bo_create_with_modifiers(struct gbm_device *gbm,
uint32_t width, uint32_t height,
uint32_t format,
const uint64_t *modifiers,
const unsigned int count)
{
return gbm_bo_create(gbm, width, height, format, GBM_BO_USE_LINEAR);
}
#endif
#ifndef HAS_gbm_surface_create_with_modifiers
struct gbm_surface *
gbm_surface_create_with_modifiers(struct gbm_device *gbm,
uint32_t width, uint32_t height,
uint32_t format,
const uint64_t *modifiers,
const unsigned int count)
{
return gbm_surface_create(gbm, width, height, format, 0);
}
#endif
#ifndef HAS_gbm_bo_map
void *
gbm_bo_map(struct gbm_bo *bo,
uint32_t x, uint32_t y, uint32_t width, uint32_t height,
uint32_t flags, uint32_t *stride, void **map_data)
{
struct drm_mode_map_dumb arg;
struct gbm_device *gbm_dev;
void *map;
int fd, ret;
if (!bo || !map_data || width <= 0 || width > gbm_bo_get_width(bo) ||
height <= 0 || height > gbm_bo_get_height(bo)) {
errno = EINVAL;
return MAP_FAILED;
}
gbm_dev = gbm_bo_get_device(bo);
if (!gbm_dev)
return MAP_FAILED;
fd = gbm_device_get_fd(gbm_dev);
if (fd < 0)
return MAP_FAILED;
memset(&arg, 0, sizeof(arg));
arg.handle = gbm_bo_get_handle(bo).u32;
ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &arg);
if (ret)
return MAP_FAILED;
map = mmap(NULL, gbm_bo_get_stride(bo) * gbm_bo_get_height(bo),
PROT_READ | PROT_WRITE, MAP_SHARED, fd, arg.offset);
if (map == MAP_FAILED)
return map;
*map_data = map;
if (stride)
*stride = gbm_bo_get_stride(bo);
return map + y * gbm_bo_get_stride(bo) + x * (gbm_bo_get_bpp(bo) >> 3);
}
#endif
#ifndef HAS_gbm_bo_unmap
void
gbm_bo_unmap(struct gbm_bo *bo, void *map_data)
{
if (map_data)
munmap(map_data, gbm_bo_get_stride(bo) * gbm_bo_get_height(bo));
}
#endif
/* Wrappers for unsupported flags */
struct gbm_surface *
gbm_surface_create(struct gbm_device *gbm,
uint32_t width, uint32_t height,
uint32_t format, uint32_t flags)
{
struct gbm_surface *surface;
static struct gbm_surface * (*surface_create)();
if(!surface_create)
surface_create =
(struct gbm_surface *(*)()) dlsym(RTLD_NEXT, "gbm_surface_create");
surface = surface_create(gbm, width, height, format, flags);
if (!surface)
surface = surface_create(gbm, width, height, format, 0);
return surface;
}
/* Wrappers for unsupported usage */
struct gbm_bo *
gbm_bo_create(struct gbm_device *gbm,
uint32_t width, uint32_t height,
uint32_t format, uint32_t usage)
{
struct gbm_bo *bo;
static struct gbm_bo * (*bo_create)();
if(!bo_create)
bo_create =
(struct gbm_bo *(*)()) dlsym(RTLD_NEXT, "gbm_bo_create");
bo = bo_create(gbm, width, height, format, usage);
if (!bo)
bo = bo_create(gbm, width, height, format, 0);
return bo;
}
/* From mesa3d 20.1.5 : src/gbm/main/gbm.c */
#ifndef HAS_gbm_bo_get_bpp
uint32_t
gbm_bo_get_bpp(struct gbm_bo *bo)
{
switch (gbm_bo_get_format(bo)) {
default:
return 0;
case GBM_FORMAT_C8:
case GBM_FORMAT_R8:
case GBM_FORMAT_RGB332:
case GBM_FORMAT_BGR233:
return 8;
case GBM_FORMAT_GR88:
case GBM_FORMAT_XRGB4444:
case GBM_FORMAT_XBGR4444:
case GBM_FORMAT_RGBX4444:
case GBM_FORMAT_BGRX4444:
case GBM_FORMAT_ARGB4444:
case GBM_FORMAT_ABGR4444:
case GBM_FORMAT_RGBA4444:
case GBM_FORMAT_BGRA4444:
case GBM_FORMAT_XRGB1555:
case GBM_FORMAT_XBGR1555:
case GBM_FORMAT_RGBX5551:
case GBM_FORMAT_BGRX5551:
case GBM_FORMAT_ARGB1555:
case GBM_FORMAT_ABGR1555:
case GBM_FORMAT_RGBA5551:
case GBM_FORMAT_BGRA5551:
case GBM_FORMAT_RGB565:
case GBM_FORMAT_BGR565:
return 16;
case GBM_FORMAT_RGB888:
case GBM_FORMAT_BGR888:
return 24;
case GBM_FORMAT_XRGB8888:
case GBM_FORMAT_XBGR8888:
case GBM_FORMAT_RGBX8888:
case GBM_FORMAT_BGRX8888:
case GBM_FORMAT_ARGB8888:
case GBM_FORMAT_ABGR8888:
case GBM_FORMAT_RGBA8888:
case GBM_FORMAT_BGRA8888:
case GBM_FORMAT_XRGB2101010:
case GBM_FORMAT_XBGR2101010:
case GBM_FORMAT_RGBX1010102:
case GBM_FORMAT_BGRX1010102:
case GBM_FORMAT_ARGB2101010:
case GBM_FORMAT_ABGR2101010:
case GBM_FORMAT_RGBA1010102:
case GBM_FORMAT_BGRA1010102:
return 32;
case GBM_FORMAT_XBGR16161616F:
case GBM_FORMAT_ABGR16161616F:
return 64;
}
}
#endif
/* From mesa3d 20.1.5 : src/gbm/main/gbm.c */
#ifndef HAS_gbm_format_get_name
static uint32_t
gbm_format_canonicalize(uint32_t gbm_format)
{
switch (gbm_format) {
case GBM_BO_FORMAT_XRGB8888:
return GBM_FORMAT_XRGB8888;
case GBM_BO_FORMAT_ARGB8888:
return GBM_FORMAT_ARGB8888;
default:
return gbm_format;
}
}
char *
gbm_format_get_name(uint32_t gbm_format, struct gbm_format_name_desc *desc)
{
gbm_format = gbm_format_canonicalize(gbm_format);
desc->name[0] = gbm_format;
desc->name[1] = gbm_format >> 8;
desc->name[2] = gbm_format >> 16;
desc->name[3] = gbm_format >> 24;
desc->name[4] = 0;
return desc->name;
}
#endif

View file

@ -28,16 +28,16 @@
#ifndef _GBM_H_
#define _GBM_H_
#ifdef __cplusplus
extern "C" {
#endif
#define __GBM__ 1
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \file gbm.h
* \brief Generic Buffer Manager
@ -77,6 +77,12 @@ enum gbm_bo_format {
GBM_BO_FORMAT_ARGB8888
};
/**
* The FourCC format codes are taken from the drm_fourcc.h definition, and
* re-namespaced. New GBM formats must not be added, unless they are
* identical ports from drm_fourcc.
*/
#define __gbm_fourcc_code(a,b,c,d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | \
((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
@ -84,8 +90,13 @@ enum gbm_bo_format {
/* color index */
#define GBM_FORMAT_C8 __gbm_fourcc_code('C', '8', ' ', ' ') /* [7:0] C */
/* 8 bpp Red */
#define GBM_FORMAT_R8 __gbm_fourcc_code('R', '8', ' ', ' ') /* [7:0] R */
/* 16 bpp RG */
#define GBM_FORMAT_GR88 __gbm_fourcc_code('G', 'R', '8', '8') /* [15:0] G:R 8:8 little endian */
/* 8 bpp RGB */
#define GBM_FORMAT_RGB332 __gbm_fourcc_code('R', 'G', 'B', '8') /* [7:0] R:G:B 3:3:2 */
#define GBM_FORMAT_BGR233 __gbm_fourcc_code('B', 'G', 'R', '8') /* [7:0] B:G:R 2:3:3 */
@ -139,6 +150,15 @@ enum gbm_bo_format {
#define GBM_FORMAT_RGBA1010102 __gbm_fourcc_code('R', 'A', '3', '0') /* [31:0] R:G:B:A 10:10:10:2 little endian */
#define GBM_FORMAT_BGRA1010102 __gbm_fourcc_code('B', 'A', '3', '0') /* [31:0] B:G:R:A 10:10:10:2 little endian */
/*
* Floating point 64bpp RGB
* IEEE 754-2008 binary16 half-precision float
* [15:0] sign:exponent:mantissa 1:5:10
*/
#define GBM_FORMAT_XBGR16161616F __gbm_fourcc_code('X', 'B', '4', 'H') /* [63:0] x:B:G:R 16:16:16:16 little endian */
#define GBM_FORMAT_ABGR16161616F __gbm_fourcc_code('A', 'B', '4', 'H') /* [63:0] A:B:G:R 16:16:16:16 little endian */
/* packed YCbCr */
#define GBM_FORMAT_YUYV __gbm_fourcc_code('Y', 'U', 'Y', 'V') /* [31:0] Cr0:Y1:Cb0:Y0 8:8:8:8 little endian */
#define GBM_FORMAT_YVYU __gbm_fourcc_code('Y', 'V', 'Y', 'U') /* [31:0] Cb0:Y1:Cr0:Y0 8:8:8:8 little endian */
@ -179,6 +199,9 @@ enum gbm_bo_format {
#define GBM_FORMAT_YUV444 __gbm_fourcc_code('Y', 'U', '2', '4') /* non-subsampled Cb (1) and Cr (2) planes */
#define GBM_FORMAT_YVU444 __gbm_fourcc_code('Y', 'V', '2', '4') /* non-subsampled Cr (1) and Cb (2) planes */
struct gbm_format_name_desc {
char name[5];
};
/**
* Flags to indicate the intended use for the buffer - these are passed into
@ -189,21 +212,16 @@ enum gbm_bo_format {
* and use flags are supported
*/
enum gbm_bo_flags {
/**
* Mali doesn't use or support this flag
*/
GBM_BO_USE_LINEAR = (0),
/**
* Buffer is going to be presented to the screen using an API such as KMS
*/
GBM_BO_USE_SCANOUT = (1 << 0),
/**
* Buffer is going to be used as cursor
*/
/**
* Buffer is going to be used as cursor
*/
GBM_BO_USE_CURSOR = (1 << 1),
/**
* Buffer is going to be used as cursor - the dimensions for the buffer
* must be 64x64 if this flag is passed.
* Deprecated
*/
GBM_BO_USE_CURSOR_64X64 = GBM_BO_USE_CURSOR,
/**
@ -213,12 +231,18 @@ enum gbm_bo_flags {
GBM_BO_USE_RENDERING = (1 << 2),
/**
* Buffer can be used for gbm_bo_write. This is guaranteed to work
* with GBM_BO_USE_CURSOR_64X64. but may not work for other
* combinations.
* with GBM_BO_USE_CURSOR, but may not work for other combinations.
*/
GBM_BO_USE_WRITE = (1 << 3),
/**
* Buffer is linear, i.e. not tiled.
*/
GBM_BO_USE_LINEAR = (1 << 4),
};
/* HACK: Mali doesn't support this flag */
#define GBM_BO_USE_LINEAR 0
int
gbm_device_get_fd(struct gbm_device *gbm);
@ -229,6 +253,11 @@ int
gbm_device_is_format_supported(struct gbm_device *gbm,
uint32_t format, uint32_t usage);
int
gbm_device_get_format_modifier_plane_count(struct gbm_device *gbm,
uint32_t format,
uint64_t modifier);
void
gbm_device_destroy(struct gbm_device *gbm);
@ -240,9 +269,16 @@ gbm_bo_create(struct gbm_device *gbm,
uint32_t width, uint32_t height,
uint32_t format, uint32_t flags);
struct gbm_bo *
gbm_bo_create_with_modifiers(struct gbm_device *gbm,
uint32_t width, uint32_t height,
uint32_t format,
const uint64_t *modifiers,
const unsigned int count);
#define GBM_BO_IMPORT_WL_BUFFER 0x5501
#define GBM_BO_IMPORT_EGL_IMAGE 0x5502
#define GBM_BO_IMPORT_FD 0x5503
#define GBM_BO_IMPORT_FD_MODIFIER 0x5504
struct gbm_import_fd_data {
int fd;
@ -252,34 +288,54 @@ struct gbm_import_fd_data {
uint32_t format;
};
#define GBM_MAX_PLANES 4
struct gbm_import_fd_modifier_data {
uint32_t width;
uint32_t height;
uint32_t format;
uint32_t num_fds;
int fds[GBM_MAX_PLANES];
int strides[GBM_MAX_PLANES];
int offsets[GBM_MAX_PLANES];
uint64_t modifier;
};
struct gbm_bo *
gbm_bo_import(struct gbm_device *gbm, uint32_t type,
void *buffer, uint32_t usage);
/**
* Mali doesn't support those flags
* Flags to indicate the type of mapping for the buffer - these are
* passed into gbm_bo_map(). The caller must set the union of all the
* flags that are appropriate.
*
* These flags are independent of the GBM_BO_USE_* creation flags. However,
* mapping the buffer may require copying to/from a staging buffer.
*
* See also: pipe_transfer_usage
*/
enum gbm_bo_transfer_flags {
/**
* Buffer contents read back (or accessed directly) at transfer
* create time.
*/
GBM_BO_TRANSFER_READ = (0),
GBM_BO_TRANSFER_READ = (1 << 0),
/**
* Buffer contents will be written back at unmap time
* (or modified as a result of being accessed directly).
*/
GBM_BO_TRANSFER_WRITE = (0),
GBM_BO_TRANSFER_WRITE = (1 << 1),
/**
* Read/modify/write
*/
GBM_BO_TRANSFER_READ_WRITE = (0),
GBM_BO_TRANSFER_READ_WRITE = (GBM_BO_TRANSFER_READ | GBM_BO_TRANSFER_WRITE),
};
void *
gbm_bo_map(struct gbm_bo *bo,
uint32_t x, uint32_t y, uint32_t width, uint32_t height,
uint32_t flags, uint32_t *stride, void **mp_data);
uint32_t flags, uint32_t *stride, void **map_data);
void
gbm_bo_unmap(struct gbm_bo *bo, void *map_data);
@ -293,9 +349,18 @@ gbm_bo_get_height(struct gbm_bo *bo);
uint32_t
gbm_bo_get_stride(struct gbm_bo *bo);
uint32_t
gbm_bo_get_stride_for_plane(struct gbm_bo *bo, int plane);
uint32_t
gbm_bo_get_format(struct gbm_bo *bo);
uint32_t
gbm_bo_get_bpp(struct gbm_bo *bo);
uint32_t
gbm_bo_get_offset(struct gbm_bo *bo, int plane);
struct gbm_device *
gbm_bo_get_device(struct gbm_bo *bo);
@ -305,6 +370,15 @@ gbm_bo_get_handle(struct gbm_bo *bo);
int
gbm_bo_get_fd(struct gbm_bo *bo);
uint64_t
gbm_bo_get_modifier(struct gbm_bo *bo);
int
gbm_bo_get_plane_count(struct gbm_bo *bo);
union gbm_bo_handle
gbm_bo_get_handle_for_plane(struct gbm_bo *bo, int plane);
int
gbm_bo_write(struct gbm_bo *bo, const void *buf, size_t count);
@ -325,6 +399,13 @@ gbm_surface_create(struct gbm_device *gbm,
uint32_t width, uint32_t height,
uint32_t format, uint32_t flags);
struct gbm_surface *
gbm_surface_create_with_modifiers(struct gbm_device *gbm,
uint32_t width, uint32_t height,
uint32_t format,
const uint64_t *modifiers,
const unsigned int count);
int
gbm_surface_needs_lock_front_buffer(struct gbm_surface *surface);
@ -340,6 +421,9 @@ gbm_surface_has_free_buffers(struct gbm_surface *surface);
void
gbm_surface_destroy(struct gbm_surface *surface);
char *
gbm_format_get_name(uint32_t gbm_format, struct gbm_format_name_desc *desc);
#ifdef __cplusplus
}
#endif

View file

@ -2,7 +2,7 @@ project(
'libmali', 'c',
version : '1.9.0',
meson_version : '>=0.49.0',
default_options: ['b_asneeded=false'],
default_options: ['b_asneeded=false', 'b_lundef=false'],
)
pkgconfig = import('pkgconfig')
@ -92,7 +92,7 @@ cl_headers = {
# Package name : required symbol, wrappers, headers, package version
map = {
'mali' : ['', mali_wrappers, mali_headers, meson.project_version()],
'gbm' : ['gbm_create_device', gbm_wrappers, {'' : 'include/gbm.h'}, '10.4.0'],
'gbm' : ['gbm_create_device', gbm_wrappers, {'' : 'include/gbm.h'}, '20.1.5'],
'egl' : ['eglCreateContext', egl_wrappers, egl_headers, '7.10'],
'glesv1_cm' : ['eglCreateContext', glesv1_wrappers, glesv1_headers, '7.10'],
'glesv2' : ['eglCreateContext', glesv2_wrappers, glesv2_headers, '7.10'],
@ -101,21 +101,68 @@ map = {
}
# Create dummy source for building libraries
run_command('touch', join_paths(meson.current_build_dir(), 'dummy.c'))
dummy_source = join_paths(meson.current_build_dir(), 'dummy.c')
run_command('touch', dummy_source)
# Create a dummy library for building wrappers
libmali = shared_library(
'mali',
join_paths(meson.current_build_dir(), 'dummy.c'),
dummy_source,
install : true,
version : meson.project_version())
# The gbm functions might be missing
gbm_check_funcs = [
'gbm_bo_map',
'gbm_bo_unmap',
'gbm_bo_get_offset',
'gbm_bo_get_plane_count',
'gbm_device_get_format_modifier_plane_count',
'gbm_bo_get_handle_for_plane',
'gbm_bo_get_stride_for_plane',
'gbm_bo_get_modifier',
'gbm_bo_create_with_modifiers',
'gbm_surface_create_with_modifiers',
'gbm_bo_get_bpp',
'gbm_format_get_name',
]
# Create libgbm wrapper for missing functions
libgbm = []
gbm_symbol = map['gbm'][0]
if run_command('grep', '-q', gbm_symbol, default_lib).returncode() == 0
libgbm_version = gbm_wrappers['gbm']
libgbm_cflags = []
libdrm_dep = dependency('libdrm', version : '>= 2.4.0')
if not libdrm_dep.found()
error('libdrm not found.')
endif
foreach symbol : gbm_check_funcs
if run_command('grep', '-q', symbol, default_lib).returncode() == 0
libgbm_cflags += '-DHAS_' + symbol
endif
endforeach
libgbm = shared_library(
'gbm',
'gbm_wrapper.c',
c_args : libgbm_cflags,
include_directories : include_directories('include'),
dependencies : libdrm_dep,
link_with : libmali,
install : true,
version : libgbm_version)
endif
foreach name, values : map
symbol = values[0]
wrappers = values[1]
headers = values[2]
pkg_version = values[3]
mali_cflags = []
wrapper_ldflags = []
# TODO: Use readelf -s ?
if run_command('grep', '-q', symbol, default_lib).returncode() != 0
@ -127,12 +174,16 @@ foreach name, values : map
endif
foreach wrapper, version : wrappers
shared_library(
wrapper,
join_paths(meson.current_build_dir(), 'dummy.c'),
link_with : libmali,
install : true,
version : version)
wrapper_ldflags += '-l' + wrapper
if wrapper != 'gbm'
shared_library(
wrapper,
dummy_source,
link_with : [libgbm, libmali],
install : true,
version : version)
endif
endforeach
foreach dir, files : headers
@ -140,7 +191,7 @@ foreach name, values : map
endforeach
pkgconfig.generate(
libraries : ['-L${libdir} -lmali'],
libraries : ['-L${libdir} -lmali', wrapper_ldflags],
extra_cflags : mali_cflags,
version : pkg_version,
name : name,