diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-05-03 13:42:47 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-05-15 10:27:51 +0000 |
commit | 8c5c43c7b138c9b4b0bf56d946e61d3bbc111bec (patch) | |
tree | d29d987c4d7b173cf853279b79a51598f104b403 /chromium/third_party/minigbm | |
parent | 830c9e163d31a9180fadca926b3e1d7dfffb5021 (diff) | |
download | qtwebengine-chromium-8c5c43c7b138c9b4b0bf56d946e61d3bbc111bec.tar.gz |
BASELINE: Update Chromium to 66.0.3359.156
Change-Id: I0c9831ad39911a086b6377b16f995ad75a51e441
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
Diffstat (limited to 'chromium/third_party/minigbm')
43 files changed, 1780 insertions, 802 deletions
diff --git a/chromium/third_party/minigbm/BUILD.gn b/chromium/third_party/minigbm/BUILD.gn index 806e12ff7a0..0b401b7d2ec 100644 --- a/chromium/third_party/minigbm/BUILD.gn +++ b/chromium/third_party/minigbm/BUILD.gn @@ -12,34 +12,86 @@ declare_args() { # system version, but when building on dev workstations or the Chrome # waterfall we bundle it because Ubuntu doesn't ship a usable version. use_system_minigbm = false + + use_amdgpu_minigbm = false + use_amlogic_minigbm = false + use_exynos_minigbm = false + use_intel_minigbm = false + use_marvell_minigbm = false + use_mediatek_minigbm = false + use_msm_minigbm = false + use_radeon_minigbm = false + use_rockchip_minigbm = false + use_tegra_minigbm = false + use_vc4_minigbm = false } if (!use_system_minigbm) { config("minigbm_config") { include_dirs = [ "src" ] + defines = [] + if (use_amdgpu_minigbm) { + defines += [ "DRV_AMDGPU" ] + } + if (use_amlogic_minigbm) { + defines += [ "DRV_AMLOGIC" ] + } + if (use_exynos_minigbm) { + defines += [ "DRV_EXYNOS" ] + } + if (use_intel_minigbm) { + defines += [ "DRV_I915" ] + } + if (use_marvell_minigbm) { + defines += [ "DRV_MARVELL" ] + } + if (use_mediatek_minigbm) { + defines += [ "DRV_MEDIATEK" ] + } + if (use_msm_minigbm) { + defines += [ "DRV_MSM" ] + } + if (use_msm_minigbm) { + defines += [ "DRV_MSM" ] + } + if (use_radeon_minigbm) { + defines += [ "DRV_RADEON" ] + } + if (use_rockchip_minigbm) { + defines += [ "DRV_ROCKCHIP" ] + } + if (use_tegra_minigbm) { + defines += [ "DRV_TEGRA" ] + } + if (use_vc4_minigbm) { + defines += [ "DRV_VC4" ] + } } shared_library("minigbm") { sources = [ "src/amdgpu.c", - "src/cirrus.c", + "src/amlogic.c", "src/drv.c", "src/evdi.c", "src/exynos.c", "src/gbm.c", "src/gbm_helpers.c", - "src/gma500.c", "src/helpers.c", + "src/helpers_array.c", "src/i915.c", "src/marvell.c", "src/mediatek.c", + "src/msm.c", "src/nouveau.c", + "src/radeon.c", "src/rockchip.c", "src/tegra.c", "src/udl.c", "src/vc4.c", "src/vgem.c", - "src/virtio_gpu.c", + "src/virtio_dumb.c", + "src/virtio_virgl.c", ] configs -= [ "//build/config/compiler:chromium_code" ] diff --git a/chromium/third_party/minigbm/src/Android.mk b/chromium/third_party/minigbm/src/Android.mk index c4798adb197..3f73fe5f4b0 100644 --- a/chromium/third_party/minigbm/src/Android.mk +++ b/chromium/third_party/minigbm/src/Android.mk @@ -1,4 +1,3 @@ -# Copyright 2017 The Chromium OS Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -17,15 +16,16 @@ LOCAL_SHARED_LIBRARIES := \ LOCAL_SRC_FILES := \ amdgpu.c \ + amlogic.c \ cirrus.c \ drv.c \ evdi.c \ exynos.c \ - gma500.c \ helpers.c \ i915.c \ marvell.c \ mediatek.c \ + msm.c \ nouveau.c \ rockchip.c \ tegra.c \ diff --git a/chromium/third_party/minigbm/src/Makefile b/chromium/third_party/minigbm/src/Makefile index 482e074a232..a01433ed07b 100644 --- a/chromium/third_party/minigbm/src/Makefile +++ b/chromium/third_party/minigbm/src/Makefile @@ -16,6 +16,9 @@ ifdef DRV_AMDGPU CFLAGS += $(shell $(PKG_CONFIG) --cflags libdrm_amdgpu) LDLIBS += -lamdgpuaddr endif +ifdef DRV_AMLOGIC + CFLAGS += $(shell $(PKG_CONFIG) --cflags libdrm_amlogic) +endif ifdef DRV_EXYNOS CFLAGS += $(shell $(PKG_CONFIG) --cflags libdrm_exynos) endif diff --git a/chromium/third_party/minigbm/src/amdgpu.c b/chromium/third_party/minigbm/src/amdgpu.c index ff1336dbc75..cca35377344 100644 --- a/chromium/third_party/minigbm/src/amdgpu.c +++ b/chromium/third_party/minigbm/src/amdgpu.c @@ -41,10 +41,12 @@ enum { }; // clang-format on -const static uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_XBGR8888, +const static uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, + DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888 }; -const static uint32_t texture_source_formats[] = { DRM_FORMAT_NV21, DRM_FORMAT_NV12 }; +const static uint32_t texture_source_formats[] = { DRM_FORMAT_GR88, DRM_FORMAT_R8, DRM_FORMAT_NV21, + DRM_FORMAT_NV12 }; static int amdgpu_set_metadata(int fd, uint32_t handle, struct amdgpu_bo_metadata *info) { @@ -135,7 +137,7 @@ static ADDR_E_RETURNCODE ADDR_API free_sys_mem(const ADDR_FREESYSMEM_INPUT *in) } static int amdgpu_addrlib_compute(void *addrlib, uint32_t width, uint32_t height, uint32_t format, - uint32_t usage, uint32_t *tiling_flags, + uint64_t use_flags, uint32_t *tiling_flags, ADDR_COMPUTE_SURFACE_INFO_OUTPUT *addr_out) { ADDR_COMPUTE_SURFACE_INFO_INPUT addr_surf_info_in = { 0 }; @@ -147,7 +149,8 @@ static int amdgpu_addrlib_compute(void *addrlib, uint32_t width, uint32_t height /* Set the requested tiling mode. */ addr_surf_info_in.tileMode = ADDR_TM_2D_TILED_THIN1; - if (usage & (BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN)) + if (use_flags & + (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; else if (width <= 16 || height <= 16) addr_surf_info_in.tileMode = ADDR_TM_1D_TILED_THIN1; @@ -166,7 +169,7 @@ static int amdgpu_addrlib_compute(void *addrlib, uint32_t width, uint32_t height addr_surf_info_in.flags.noStencil = 1; /* Set the micro tile type. */ - if (usage & BO_USE_SCANOUT) + if (use_flags & BO_USE_SCANOUT) addr_surf_info_in.tileType = ADDR_DISPLAYABLE; else addr_surf_info_in.tileType = ADDR_NON_DISPLAYABLE; @@ -270,10 +273,9 @@ 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_USE_RENDER_MASK; + uint64_t use_flags = BO_USE_RENDER_MASK; addrlib = amdgpu_addrlib_init(drv_get_fd(drv)); if (!addrlib) @@ -281,22 +283,28 @@ static int amdgpu_init(struct driver *drv) drv->priv = addrlib; - ret = drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), - &LINEAR_METADATA, BO_USE_TEXTURE_MASK); - if (ret) - return ret; + drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), + &LINEAR_METADATA, BO_USE_TEXTURE_MASK); + + /* YUV format for camera */ + drv_modify_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA, + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); + /* + * R8 format is used for Android's HAL_PIXEL_FORMAT_BLOB and is used for JPEG snapshots + * from camera. + */ + drv_modify_combination(drv, DRM_FORMAT_R8, &LINEAR_METADATA, + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); drv_modify_combination(drv, DRM_FORMAT_NV21, &LINEAR_METADATA, BO_USE_SCANOUT); drv_modify_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA, BO_USE_SCANOUT); metadata.tiling = ADDR_DISPLAYABLE << 16 | ADDR_TM_LINEAR_ALIGNED; metadata.priority = 2; - metadata.modifier = DRM_FORMAT_MOD_NONE; + metadata.modifier = DRM_FORMAT_MOD_LINEAR; - ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &metadata, flags); - if (ret) - return ret; + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &metadata, use_flags); 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); @@ -304,24 +312,20 @@ static int amdgpu_init(struct driver *drv) metadata.tiling = ADDR_NON_DISPLAYABLE << 16 | ADDR_TM_LINEAR_ALIGNED; metadata.priority = 3; - metadata.modifier = DRM_FORMAT_MOD_NONE; + metadata.modifier = DRM_FORMAT_MOD_LINEAR; - ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &metadata, flags); - if (ret) - return ret; + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &metadata, use_flags); - flags &= ~BO_USE_SW_WRITE_OFTEN; - flags &= ~BO_USE_SW_READ_OFTEN; - flags &= ~BO_USE_LINEAR; + use_flags &= ~BO_USE_SW_WRITE_OFTEN; + use_flags &= ~BO_USE_SW_READ_OFTEN; + use_flags &= ~BO_USE_LINEAR; metadata.tiling = ADDR_DISPLAYABLE << 16 | ADDR_TM_2D_TILED_THIN1; metadata.priority = 4; - ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &metadata, flags); - if (ret) - return ret; + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &metadata, use_flags); drv_modify_combination(drv, DRM_FORMAT_ARGB8888, &metadata, BO_USE_SCANOUT); drv_modify_combination(drv, DRM_FORMAT_XRGB8888, &metadata, BO_USE_SCANOUT); @@ -330,12 +334,10 @@ static int amdgpu_init(struct driver *drv) metadata.tiling = ADDR_NON_DISPLAYABLE << 16 | ADDR_TM_2D_TILED_THIN1; metadata.priority = 5; - ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &metadata, flags); - if (ret) - return ret; + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &metadata, use_flags); - return ret; + return 0; } static void amdgpu_close(struct driver *drv) @@ -345,21 +347,20 @@ static void amdgpu_close(struct driver *drv) } static int amdgpu_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, - uint32_t usage) + uint64_t use_flags) { void *addrlib = bo->drv->priv; union drm_amdgpu_gem_create gem_create; struct amdgpu_bo_metadata metadata = { 0 }; ADDR_COMPUTE_SURFACE_INFO_OUTPUT addr_out = { 0 }; uint32_t tiling_flags = 0; - uint32_t gem_create_flags = 0; size_t plane; int ret; if (format == DRM_FORMAT_NV12 || format == DRM_FORMAT_NV21) { drv_bo_from_format(bo, ALIGN(width, 64), height, format); } else { - if (amdgpu_addrlib_compute(addrlib, width, height, format, usage, &tiling_flags, + if (amdgpu_addrlib_compute(addrlib, width, height, format, use_flags, &tiling_flags, &addr_out) < 0) return -EINVAL; @@ -370,19 +371,25 @@ static int amdgpu_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint bo->strides[0] = addr_out.pixelPitch * DIV_ROUND_UP(addr_out.pixelBits, 8); } - if (usage & (BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN | - BO_USE_SW_WRITE_RARELY | BO_USE_SW_READ_RARELY)) - gem_create_flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; - else - gem_create_flags |= AMDGPU_GEM_CREATE_NO_CPU_ACCESS; - memset(&gem_create, 0, sizeof(gem_create)); gem_create.in.bo_size = bo->total_size; gem_create.in.alignment = addr_out.baseAlign; /* Set the placement. */ - gem_create.in.domains = AMDGPU_GEM_DOMAIN_VRAM; - gem_create.in.domain_flags = gem_create_flags; + + gem_create.in.domain_flags = 0; + if (use_flags & (BO_USE_LINEAR | BO_USE_SW)) + gem_create.in.domain_flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; + + if (use_flags & (BO_USE_SCANOUT | BO_USE_CURSOR)) { + /* TODO(dbehr) do not use VRAM after we enable display VM */ + gem_create.in.domains = AMDGPU_GEM_DOMAIN_VRAM; + } else { + gem_create.in.domains = AMDGPU_GEM_DOMAIN_GTT; + if (!(use_flags & BO_USE_SW_READ_OFTEN)) + gem_create.in.domain_flags |= AMDGPU_GEM_CREATE_CPU_GTT_USWC; + } + /* Allocate the buffer with the preferred heap. */ ret = drmCommandWriteRead(drv_get_fd(bo->drv), DRM_AMDGPU_GEM_CREATE, &gem_create, sizeof(gem_create)); @@ -400,7 +407,7 @@ static int amdgpu_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint return ret; } -static void *amdgpu_bo_map(struct bo *bo, struct map_info *data, size_t plane, int prot) +static void *amdgpu_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags) { int ret; union drm_amdgpu_gem_mmap gem_map; @@ -413,14 +420,22 @@ static void *amdgpu_bo_map(struct bo *bo, struct map_info *data, size_t plane, i fprintf(stderr, "drv: DRM_IOCTL_AMDGPU_GEM_MMAP failed\n"); return MAP_FAILED; } - data->length = bo->total_size; - return mmap(0, bo->total_size, prot, MAP_SHARED, bo->drv->fd, gem_map.out.addr_ptr); + vma->length = bo->total_size; + + return mmap(0, bo->total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, + gem_map.out.addr_ptr); } -static uint32_t amdgpu_resolve_format(uint32_t format, uint64_t usage) +static uint32_t amdgpu_resolve_format(uint32_t format, uint64_t use_flags) { switch (format) { + case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED: + /* Camera subsystem requires NV12. */ + if (use_flags & (BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE)) + return DRM_FORMAT_NV12; + /*HACK: See b/28671744 */ + return DRM_FORMAT_XBGR8888; case DRM_FORMAT_FLEX_YCbCr_420_888: return DRM_FORMAT_NV12; default: @@ -428,7 +443,7 @@ static uint32_t amdgpu_resolve_format(uint32_t format, uint64_t usage) } } -struct backend backend_amdgpu = { +const struct backend backend_amdgpu = { .name = "amdgpu", .init = amdgpu_init, .close = amdgpu_close, @@ -436,6 +451,7 @@ struct backend backend_amdgpu = { .bo_destroy = drv_gem_bo_destroy, .bo_import = drv_prime_bo_import, .bo_map = amdgpu_bo_map, + .bo_unmap = drv_bo_munmap, .resolve_format = amdgpu_resolve_format, }; diff --git a/chromium/third_party/minigbm/src/amlogic.c b/chromium/third_party/minigbm/src/amlogic.c new file mode 100644 index 00000000000..5609ae8ae80 --- /dev/null +++ b/chromium/third_party/minigbm/src/amlogic.c @@ -0,0 +1,33 @@ +/* + * Copyright 2018 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifdef DRV_AMLOGIC + +#include "drv_priv.h" +#include "helpers.h" +#include "util.h" + +static const uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888 }; + +static int amlogic_init(struct driver *drv) +{ + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &LINEAR_METADATA, BO_USE_RENDER_MASK); + + return drv_modify_linear_combinations(drv); +} + +const struct backend backend_amlogic = { + .name = "amlogic", + .init = amlogic_init, + .bo_create = drv_dumb_bo_create, + .bo_destroy = drv_dumb_bo_destroy, + .bo_import = drv_prime_bo_import, + .bo_map = drv_dumb_bo_map, + .bo_unmap = drv_bo_munmap, +}; + +#endif diff --git a/chromium/third_party/minigbm/src/cirrus.c b/chromium/third_party/minigbm/src/cirrus.c deleted file mode 100644 index 4f0e983538d..00000000000 --- a/chromium/third_party/minigbm/src/cirrus.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2014 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "drv_priv.h" -#include "helpers.h" -#include "util.h" - -const static uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB888, - DRM_FORMAT_XRGB8888 }; - -static int cirrus_init(struct driver *drv) -{ - int ret; - ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &LINEAR_METADATA, BO_USE_RENDER_MASK); - if (ret) - return ret; - - return drv_modify_linear_combinations(drv); -} - -struct backend backend_cirrus = { - .name = "cirrus", - .init = cirrus_init, - .bo_create = drv_dumb_bo_create, - .bo_destroy = drv_dumb_bo_destroy, - .bo_import = drv_prime_bo_import, - .bo_map = drv_dumb_bo_map, -}; diff --git a/chromium/third_party/minigbm/src/cros_gralloc/Makefile b/chromium/third_party/minigbm/src/cros_gralloc/Makefile index 17e884fb210..1583a6fb427 100644 --- a/chromium/third_party/minigbm/src/cros_gralloc/Makefile +++ b/chromium/third_party/minigbm/src/cros_gralloc/Makefile @@ -21,6 +21,10 @@ CXXFLAGS += -std=c++14 CFLAGS += -std=c99 LIBS += -shared -lcutils -lhardware -lsync $(LIBDRM_LIBS) +ifdef DRV_AMDGPU + LIBS += -lamdgpuaddr +endif + OBJS = $(foreach source, $(SOURCES), $(addsuffix .o, $(basename $(source)))) OBJECTS = $(addprefix $(TARGET_DIR), $(notdir $(OBJS))) diff --git a/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_buffer.cc b/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_buffer.cc index b6da605515e..47a13a2ddb9 100644 --- a/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_buffer.cc +++ b/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_buffer.cc @@ -9,9 +9,9 @@ #include <assert.h> #include <sys/mman.h> -cros_gralloc_buffer::cros_gralloc_buffer(uint32_t id, struct bo *acquirebo_, +cros_gralloc_buffer::cros_gralloc_buffer(uint32_t id, struct bo *acquire_bo, struct cros_gralloc_handle *acquire_handle) - : id_(id), bo_(acquirebo_), hnd_(acquire_handle), refcount_(1), lockcount_(0) + : id_(id), bo_(acquire_bo), hnd_(acquire_handle), refcount_(1), lockcount_(0) { assert(bo_); num_planes_ = drv_bo_get_num_planes(bo_); @@ -44,7 +44,8 @@ int32_t cros_gralloc_buffer::decrease_refcount() return --refcount_; } -int32_t cros_gralloc_buffer::lock(uint64_t flags, uint8_t *addr[DRV_MAX_PLANES]) +int32_t cros_gralloc_buffer::lock(const struct rectangle *rect, uint32_t map_flags, + uint8_t *addr[DRV_MAX_PLANES]) { void *vaddr = nullptr; @@ -59,12 +60,12 @@ int32_t cros_gralloc_buffer::lock(uint64_t flags, uint8_t *addr[DRV_MAX_PLANES]) return -EINVAL; } - if (flags) { + if (map_flags) { if (lock_data_[0]) { - vaddr = lock_data_[0]->addr; + drv_bo_invalidate(bo_, lock_data_[0]); + vaddr = lock_data_[0]->vma->addr; } else { - vaddr = drv_bo_map(bo_, 0, 0, drv_bo_get_width(bo_), drv_bo_get_height(bo_), - BO_TRANSFER_READ_WRITE, &lock_data_[0], 0); + vaddr = drv_bo_map(bo_, rect, map_flags, &lock_data_[0], 0); } if (vaddr == MAP_FAILED) { @@ -89,7 +90,7 @@ int32_t cros_gralloc_buffer::unlock() if (!--lockcount_) { if (lock_data_[0]) { - drv_bo_unmap(bo_, lock_data_[0]); + drv_bo_flush(bo_, lock_data_[0]); lock_data_[0] = nullptr; } } diff --git a/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_buffer.h b/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_buffer.h index 673ff9d8f0b..e6aec91df7b 100644 --- a/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_buffer.h +++ b/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_buffer.h @@ -13,7 +13,7 @@ class cros_gralloc_buffer { public: - cros_gralloc_buffer(uint32_t id, struct bo *acquirebo_, + cros_gralloc_buffer(uint32_t id, struct bo *acquire_bo, struct cros_gralloc_handle *acquire_handle); ~cros_gralloc_buffer(); @@ -23,7 +23,8 @@ class cros_gralloc_buffer int32_t increase_refcount(); int32_t decrease_refcount(); - int32_t lock(uint64_t flags, uint8_t *addr[DRV_MAX_PLANES]); + int32_t lock(const struct rectangle *rect, uint32_t map_flags, + uint8_t *addr[DRV_MAX_PLANES]); int32_t unlock(); private: @@ -38,7 +39,7 @@ class cros_gralloc_buffer int32_t lockcount_; uint32_t num_planes_; - struct map_info *lock_data_[DRV_MAX_PLANES]; + struct mapping *lock_data_[DRV_MAX_PLANES]; }; #endif diff --git a/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_driver.cc b/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_driver.cc index f6e65b7bfb2..fec4aba30ec 100644 --- a/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_driver.cc +++ b/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_driver.cc @@ -78,8 +78,8 @@ bool cros_gralloc_driver::is_supported(const struct cros_gralloc_buffer_descript { struct combination *combo; uint32_t resolved_format; - resolved_format = drv_resolve_format(drv_, descriptor->drm_format, descriptor->drv_usage); - combo = drv_get_combination(drv_, resolved_format, descriptor->drv_usage); + resolved_format = drv_resolve_format(drv_, descriptor->drm_format, descriptor->use_flags); + combo = drv_get_combination(drv_, resolved_format, descriptor->use_flags); return (combo != nullptr); } @@ -94,9 +94,9 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto struct bo *bo; struct cros_gralloc_handle *hnd; - resolved_format = drv_resolve_format(drv_, descriptor->drm_format, descriptor->drv_usage); + resolved_format = drv_resolve_format(drv_, descriptor->drm_format, descriptor->use_flags); bo = drv_bo_create(drv_, descriptor->width, descriptor->height, resolved_format, - descriptor->drv_usage); + descriptor->use_flags); if (!bo) { cros_gralloc_error("Failed to create bo."); return -ENOMEM; @@ -124,7 +124,6 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto hnd->fds[plane] = drv_bo_get_plane_fd(bo, plane); hnd->strides[plane] = drv_bo_get_plane_stride(bo, plane); hnd->offsets[plane] = drv_bo_get_plane_offset(bo, plane); - hnd->sizes[plane] = drv_bo_get_plane_size(bo, plane); mod = drv_bo_get_plane_format_modifier(bo, plane); hnd->format_modifiers[2 * plane] = static_cast<uint32_t>(mod >> 32); @@ -134,8 +133,8 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto hnd->width = drv_bo_get_width(bo); hnd->height = drv_bo_get_height(bo); hnd->format = drv_bo_get_format(bo); - hnd->flags[0] = static_cast<uint32_t>(descriptor->drv_usage >> 32); - hnd->flags[1] = static_cast<uint32_t>(descriptor->drv_usage); + hnd->use_flags[0] = static_cast<uint32_t>(descriptor->use_flags >> 32); + hnd->use_flags[1] = static_cast<uint32_t>(descriptor->use_flags); hnd->pixel_stride = drv_bo_get_stride_in_pixels(bo); hnd->magic = cros_gralloc_magic; hnd->droid_format = descriptor->droid_format; @@ -183,13 +182,12 @@ int32_t cros_gralloc_driver::retain(buffer_handle_t handle) data.format = hnd->format; data.width = hnd->width; data.height = hnd->height; - data.flags = static_cast<uint64_t>(hnd->flags[0]) << 32; - data.flags |= hnd->flags[1]; + data.use_flags = static_cast<uint64_t>(hnd->use_flags[0]) << 32; + data.use_flags |= hnd->use_flags[1]; memcpy(data.fds, hnd->fds, sizeof(data.fds)); memcpy(data.strides, hnd->strides, sizeof(data.strides)); memcpy(data.offsets, hnd->offsets, sizeof(data.offsets)); - memcpy(data.sizes, hnd->sizes, sizeof(data.sizes)); for (uint32_t plane = 0; plane < DRV_MAX_PLANES; plane++) { data.format_modifiers[plane] = static_cast<uint64_t>(hnd->format_modifiers[2 * plane]) << 32; @@ -237,7 +235,8 @@ int32_t cros_gralloc_driver::release(buffer_handle_t handle) return 0; } -int32_t cros_gralloc_driver::lock(buffer_handle_t handle, int32_t acquire_fence, uint64_t flags, +int32_t cros_gralloc_driver::lock(buffer_handle_t handle, int32_t acquire_fence, + const struct rectangle *rect, uint32_t map_flags, uint8_t *addr[DRV_MAX_PLANES]) { int32_t ret = cros_gralloc_sync_wait(acquire_fence); @@ -257,7 +256,7 @@ int32_t cros_gralloc_driver::lock(buffer_handle_t handle, int32_t acquire_fence, return -EINVAL; } - return buffer->lock(flags, addr); + return buffer->lock(rect, map_flags, addr); } int32_t cros_gralloc_driver::unlock(buffer_handle_t handle, int32_t *release_fence) diff --git a/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_driver.h b/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_driver.h index b8754977a40..45782c93115 100644 --- a/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_driver.h +++ b/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_driver.h @@ -26,8 +26,8 @@ class cros_gralloc_driver int32_t retain(buffer_handle_t handle); int32_t release(buffer_handle_t handle); - int32_t lock(buffer_handle_t handle, int32_t acquire_fence, uint64_t flags, - uint8_t *addr[DRV_MAX_PLANES]); + int32_t lock(buffer_handle_t handle, int32_t acquire_fence, const struct rectangle *rect, + uint32_t map_flags, uint8_t *addr[DRV_MAX_PLANES]); int32_t unlock(buffer_handle_t handle, int32_t *release_fence); int32_t get_backing_store(buffer_handle_t handle, uint64_t *out_store); diff --git a/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_handle.h b/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_handle.h index 4cb554dc04a..cd3edfe7680 100644 --- a/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_handle.h +++ b/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_handle.h @@ -22,12 +22,11 @@ struct cros_gralloc_handle { int32_t fds[DRV_MAX_PLANES]; uint32_t strides[DRV_MAX_PLANES]; uint32_t offsets[DRV_MAX_PLANES]; - uint32_t sizes[DRV_MAX_PLANES]; uint32_t format_modifiers[2 * DRV_MAX_PLANES]; uint32_t width; uint32_t height; - uint32_t format; /* DRM format */ - uint32_t flags[2]; /* driver creation time flags */ + uint32_t format; /* DRM format */ + uint32_t use_flags[2]; /* Buffer creation flags */ uint32_t magic; uint32_t pixel_stride; int32_t droid_format; diff --git a/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_types.h b/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_types.h index 2f6122e1324..1fa81de5b67 100644 --- a/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_types.h +++ b/chromium/third_party/minigbm/src/cros_gralloc/cros_gralloc_types.h @@ -14,7 +14,7 @@ struct cros_gralloc_buffer_descriptor { uint32_t producer_usage; uint32_t droid_format; uint32_t drm_format; - uint64_t drv_usage; + uint64_t use_flags; }; #endif diff --git a/chromium/third_party/minigbm/src/cros_gralloc/gralloc0/gralloc0.cc b/chromium/third_party/minigbm/src/cros_gralloc/gralloc0/gralloc0.cc index 533f8cac099..50cd1af99e9 100644 --- a/chromium/third_party/minigbm/src/cros_gralloc/gralloc0/gralloc0.cc +++ b/chromium/third_party/minigbm/src/cros_gralloc/gralloc0/gralloc0.cc @@ -6,6 +6,7 @@ #include "../cros_gralloc_driver.h" +#include <cassert> #include <hardware/gralloc.h> #include <memory.h> @@ -32,50 +33,62 @@ enum { }; // clang-format on -static int64_t gralloc0_convert_flags(int flags) +static uint64_t gralloc0_convert_usage(int usage) { - uint64_t usage = BO_USE_NONE; - - if (flags & GRALLOC_USAGE_CURSOR) - usage |= BO_USE_NONE; - if ((flags & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_RARELY) - usage |= BO_USE_SW_READ_RARELY; - if ((flags & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN) - usage |= BO_USE_SW_READ_OFTEN; - if ((flags & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_RARELY) - usage |= BO_USE_SW_WRITE_RARELY; - if ((flags & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_OFTEN) - usage |= BO_USE_SW_WRITE_OFTEN; - if (flags & GRALLOC_USAGE_HW_TEXTURE) - usage |= BO_USE_TEXTURE; - if (flags & GRALLOC_USAGE_HW_RENDER) - usage |= BO_USE_RENDERING; - if (flags & GRALLOC_USAGE_HW_2D) - usage |= BO_USE_RENDERING; - if (flags & GRALLOC_USAGE_HW_COMPOSER) + uint64_t use_flags = BO_USE_NONE; + + if (usage & GRALLOC_USAGE_CURSOR) + use_flags |= BO_USE_NONE; + if ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_RARELY) + use_flags |= BO_USE_SW_READ_RARELY; + if ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN) + use_flags |= BO_USE_SW_READ_OFTEN; + if ((usage & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_RARELY) + use_flags |= BO_USE_SW_WRITE_RARELY; + if ((usage & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_OFTEN) + use_flags |= BO_USE_SW_WRITE_OFTEN; + if (usage & GRALLOC_USAGE_HW_TEXTURE) + use_flags |= BO_USE_TEXTURE; + if (usage & GRALLOC_USAGE_HW_RENDER) + use_flags |= BO_USE_RENDERING; + if (usage & GRALLOC_USAGE_HW_2D) + use_flags |= BO_USE_RENDERING; + if (usage & GRALLOC_USAGE_HW_COMPOSER) /* HWC wants to use display hardware, but can defer to OpenGL. */ - usage |= BO_USE_SCANOUT | BO_USE_TEXTURE; - if (flags & GRALLOC_USAGE_HW_FB) - usage |= BO_USE_NONE; - if (flags & GRALLOC_USAGE_EXTERNAL_DISP) + use_flags |= BO_USE_SCANOUT | BO_USE_TEXTURE; + if (usage & GRALLOC_USAGE_HW_FB) + use_flags |= BO_USE_NONE; + if (usage & GRALLOC_USAGE_EXTERNAL_DISP) /* * This flag potentially covers external display for the normal drivers (i915, * rockchip) and usb monitors (evdi/udl). It's complicated so ignore it. * */ - usage |= BO_USE_NONE; - if (flags & GRALLOC_USAGE_PROTECTED) - usage |= BO_USE_PROTECTED; - if (flags & GRALLOC_USAGE_HW_VIDEO_ENCODER) + use_flags |= BO_USE_NONE; + if (usage & GRALLOC_USAGE_PROTECTED) + use_flags |= BO_USE_PROTECTED; + if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) /*HACK: See b/30054495 */ - usage |= BO_USE_SW_READ_OFTEN; - if (flags & GRALLOC_USAGE_HW_CAMERA_WRITE) - usage |= BO_USE_CAMERA_WRITE; - if (flags & GRALLOC_USAGE_HW_CAMERA_READ) - usage |= BO_USE_CAMERA_READ; - if (flags & GRALLOC_USAGE_RENDERSCRIPT) - usage |= BO_USE_RENDERSCRIPT; - - return usage; + use_flags |= BO_USE_SW_READ_OFTEN; + if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) + use_flags |= BO_USE_CAMERA_WRITE; + if (usage & GRALLOC_USAGE_HW_CAMERA_READ) + use_flags |= BO_USE_CAMERA_READ; + if (usage & GRALLOC_USAGE_RENDERSCRIPT) + use_flags |= BO_USE_RENDERSCRIPT; + + return use_flags; +} + +static uint32_t gralloc0_convert_map_usage(int map_usage) +{ + uint32_t map_flags = BO_MAP_NONE; + + if (map_usage & GRALLOC_USAGE_SW_READ_MASK) + map_flags |= BO_MAP_READ; + if (map_usage & GRALLOC_USAGE_SW_WRITE_MASK) + map_flags |= BO_MAP_WRITE; + + return map_flags; } static int gralloc0_alloc(alloc_device_t *dev, int w, int h, int format, int usage, @@ -91,19 +104,19 @@ static int gralloc0_alloc(alloc_device_t *dev, int w, int h, int format, int usa descriptor.droid_format = format; descriptor.producer_usage = descriptor.consumer_usage = usage; descriptor.drm_format = cros_gralloc_convert_format(format); - descriptor.drv_usage = gralloc0_convert_flags(usage); + descriptor.use_flags = gralloc0_convert_usage(usage); supported = mod->driver->is_supported(&descriptor); if (!supported && (usage & GRALLOC_USAGE_HW_COMPOSER)) { - descriptor.drv_usage &= ~BO_USE_SCANOUT; + descriptor.use_flags &= ~BO_USE_SCANOUT; supported = mod->driver->is_supported(&descriptor); } if (!supported) { - cros_gralloc_error("Unsupported combination -- HAL format: %u, HAL flags: %u, " - "drv_format: %4.4s, drv_flags: %llu", + cros_gralloc_error("Unsupported combination -- HAL format: %u, HAL usage: %u, " + "drv_format: %4.4s, use_flags: %llu", format, usage, reinterpret_cast<char *>(&descriptor.drm_format), - static_cast<unsigned long long>(descriptor.drv_usage)); + static_cast<unsigned long long>(descriptor.use_flags)); return -EINVAL; } @@ -282,9 +295,13 @@ static int gralloc0_lock_async(struct gralloc_module_t const *module, buffer_han int usage, int l, int t, int w, int h, void **vaddr, int fence_fd) { int32_t ret; - uint64_t flags; + uint32_t map_flags; uint8_t *addr[DRV_MAX_PLANES]; auto mod = (struct gralloc0_module *)module; + struct rectangle rect = { .x = static_cast<uint32_t>(l), + .y = static_cast<uint32_t>(t), + .width = static_cast<uint32_t>(w), + .height = static_cast<uint32_t>(h) }; auto hnd = cros_gralloc_convert_handle(handle); if (!hnd) { @@ -297,8 +314,13 @@ static int gralloc0_lock_async(struct gralloc_module_t const *module, buffer_han return -EINVAL; } - flags = gralloc0_convert_flags(usage); - ret = mod->driver->lock(handle, fence_fd, flags, addr); + assert(l >= 0); + assert(t >= 0); + assert(w >= 0); + assert(h >= 0); + + map_flags = gralloc0_convert_map_usage(usage); + ret = mod->driver->lock(handle, fence_fd, &rect, map_flags, addr); *vaddr = addr[0]; return ret; } @@ -314,10 +336,14 @@ static int gralloc0_lock_async_ycbcr(struct gralloc_module_t const *module, buff int usage, int l, int t, int w, int h, struct android_ycbcr *ycbcr, int fence_fd) { - uint64_t flags; int32_t ret; + uint32_t map_flags; uint8_t *addr[DRV_MAX_PLANES] = { nullptr, nullptr, nullptr, nullptr }; auto mod = (struct gralloc0_module *)module; + struct rectangle rect = { .x = static_cast<uint32_t>(l), + .y = static_cast<uint32_t>(t), + .width = static_cast<uint32_t>(w), + .height = static_cast<uint32_t>(h) }; auto hnd = cros_gralloc_convert_handle(handle); if (!hnd) { @@ -332,8 +358,13 @@ static int gralloc0_lock_async_ycbcr(struct gralloc_module_t const *module, buff return -EINVAL; } - flags = gralloc0_convert_flags(usage); - ret = mod->driver->lock(handle, fence_fd, flags, addr); + assert(l >= 0); + assert(t >= 0); + assert(w >= 0); + assert(h >= 0); + + map_flags = gralloc0_convert_map_usage(usage); + ret = mod->driver->lock(handle, fence_fd, &rect, map_flags, addr); if (ret) return ret; diff --git a/chromium/third_party/minigbm/src/drv.c b/chromium/third_party/minigbm/src/drv.c index 10a63485ea5..6d6e4fc8e79 100644 --- a/chromium/third_party/minigbm/src/drv.c +++ b/chromium/third_party/minigbm/src/drv.c @@ -12,6 +12,8 @@ #include <stdlib.h> #include <string.h> #include <sys/mman.h> +#include <sys/types.h> +#include <unistd.h> #include <xf86drm.h> #include "drv_priv.h" @@ -19,41 +21,45 @@ #include "util.h" #ifdef DRV_AMDGPU -extern struct backend backend_amdgpu; +extern const struct backend backend_amdgpu; #endif -extern struct backend backend_cirrus; -extern struct backend backend_evdi; +#ifdef DRV_AMLOGIC +extern const struct backend backend_amlogic; +#endif +extern const struct backend backend_evdi; #ifdef DRV_EXYNOS -extern struct backend backend_exynos; +extern const struct backend backend_exynos; #endif -extern struct backend backend_gma500; #ifdef DRV_I915 -extern struct backend backend_i915; +extern const struct backend backend_i915; #endif #ifdef DRV_MARVELL -extern struct backend backend_marvell; +extern const struct backend backend_marvell; #endif #ifdef DRV_MEDIATEK -extern struct backend backend_mediatek; +extern const struct backend backend_mediatek; +#endif +#ifdef DRV_MSM +extern const struct backend backend_msm; #endif -extern struct backend backend_nouveau; +extern const struct backend backend_nouveau; #ifdef DRV_RADEON -extern struct backend backend_radeon; +extern const struct backend backend_radeon; #endif #ifdef DRV_ROCKCHIP -extern struct backend backend_rockchip; +extern const struct backend backend_rockchip; #endif #ifdef DRV_TEGRA -extern struct backend backend_tegra; +extern const struct backend backend_tegra; #endif -extern struct backend backend_udl; +extern const struct backend backend_udl; #ifdef DRV_VC4 -extern struct backend backend_vc4; +extern const struct backend backend_vc4; #endif -extern struct backend backend_vgem; -extern struct backend backend_virtio_gpu; +extern const struct backend backend_vgem; +extern const struct backend backend_virtio_gpu; -static struct backend *drv_get_backend(int fd) +static const struct backend *drv_get_backend(int fd) { drmVersionPtr drm_version; unsigned int i; @@ -63,15 +69,17 @@ static struct backend *drv_get_backend(int fd) if (!drm_version) return NULL; - struct backend *backend_list[] = { + const struct backend *backend_list[] = { #ifdef DRV_AMDGPU &backend_amdgpu, #endif - &backend_cirrus, &backend_evdi, +#ifdef DRV_AMLOGIC + &backend_amlogic, +#endif + &backend_evdi, #ifdef DRV_EXYNOS &backend_exynos, #endif - &backend_gma500, #ifdef DRV_I915 &backend_i915, #endif @@ -81,6 +89,9 @@ static struct backend *drv_get_backend(int fd) #ifdef DRV_MEDIATEK &backend_mediatek, #endif +#ifdef DRV_MSM + &backend_msm, +#endif &backend_nouveau, #ifdef DRV_RADEON &backend_radeon, @@ -131,30 +142,26 @@ struct driver *drv_create(int fd) if (!drv->buffer_table) goto free_lock; - drv->map_table = drmHashCreate(); - if (!drv->map_table) + drv->mappings = drv_array_init(sizeof(struct mapping)); + if (!drv->mappings) goto free_buffer_table; - /* 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; + drv->combos = drv_array_init(sizeof(struct combination)); + if (!drv->combos) + goto free_mappings; if (drv->backend->init) { ret = drv->backend->init(drv); if (ret) { - free(drv->backend->combos.data); - goto free_map_table; + drv_array_destroy(drv->combos); + goto free_mappings; } } return drv; -free_map_table: - drmHashDestroy(drv->map_table); +free_mappings: + drv_array_destroy(drv->mappings); free_buffer_table: drmHashDestroy(drv->buffer_table); free_lock: @@ -172,9 +179,8 @@ void drv_destroy(struct driver *drv) drv->backend->close(drv); drmHashDestroy(drv->buffer_table); - drmHashDestroy(drv->map_table); - - free(drv->backend->combos.data); + drv_array_destroy(drv->mappings); + drv_array_destroy(drv->combos); pthread_mutex_unlock(&drv->driver_lock); pthread_mutex_destroy(&drv->driver_lock); @@ -192,18 +198,18 @@ const char *drv_get_name(struct driver *drv) return drv->backend->name; } -struct combination *drv_get_combination(struct driver *drv, uint32_t format, uint64_t usage) +struct combination *drv_get_combination(struct driver *drv, uint32_t format, uint64_t use_flags) { struct combination *curr, *best; - if (format == DRM_FORMAT_NONE || usage == BO_USE_NONE) + if (format == DRM_FORMAT_NONE || use_flags == BO_USE_NONE) return 0; 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)) + for (i = 0; i < drv_array_size(drv->combos); i++) { + curr = drv_array_at_idx(drv->combos, i); + if ((format == curr->format) && use_flags == (curr->use_flags & use_flags)) if (!best || best->metadata.priority < curr->metadata.priority) best = curr; } @@ -212,7 +218,7 @@ struct combination *drv_get_combination(struct driver *drv, uint32_t format, uin } struct bo *drv_bo_new(struct driver *drv, uint32_t width, uint32_t height, uint32_t format, - uint64_t flags) + uint64_t use_flags) { struct bo *bo; @@ -225,7 +231,7 @@ struct bo *drv_bo_new(struct driver *drv, uint32_t width, uint32_t height, uint3 bo->width = width; bo->height = height; bo->format = format; - bo->flags = flags; + bo->use_flags = use_flags; bo->num_planes = drv_num_planes_from_format(format); if (!bo->num_planes) { @@ -237,18 +243,18 @@ struct bo *drv_bo_new(struct driver *drv, uint32_t width, uint32_t height, uint3 } struct bo *drv_bo_create(struct driver *drv, uint32_t width, uint32_t height, uint32_t format, - uint64_t flags) + uint64_t use_flags) { int ret; size_t plane; struct bo *bo; - bo = drv_bo_new(drv, width, height, format, flags); + bo = drv_bo_new(drv, width, height, format, use_flags); if (!bo) return NULL; - ret = drv->backend->bo_create(bo, width, height, format, flags); + ret = drv->backend->bo_create(bo, width, height, format, use_flags); if (ret) { free(bo); @@ -257,8 +263,12 @@ struct bo *drv_bo_create(struct driver *drv, uint32_t width, uint32_t height, ui pthread_mutex_lock(&drv->driver_lock); - for (plane = 0; plane < bo->num_planes; plane++) + for (plane = 0; plane < bo->num_planes; plane++) { + if (plane > 0) + assert(bo->offsets[plane] >= bo->offsets[plane - 1]); + drv_increment_reference_count(drv, bo, plane); + } pthread_mutex_unlock(&drv->driver_lock); @@ -291,8 +301,12 @@ struct bo *drv_bo_create_with_modifiers(struct driver *drv, uint32_t width, uint pthread_mutex_lock(&drv->driver_lock); - for (plane = 0; plane < bo->num_planes; plane++) + for (plane = 0; plane < bo->num_planes; plane++) { + if (plane > 0) + assert(bo->offsets[plane] >= bo->offsets[plane - 1]); + drv_increment_reference_count(drv, bo, plane); + } pthread_mutex_unlock(&drv->driver_lock); @@ -303,7 +317,6 @@ void drv_bo_destroy(struct bo *bo) { size_t plane; uintptr_t total = 0; - size_t map_count = 0; struct driver *drv = bo->drv; pthread_mutex_lock(&drv->driver_lock); @@ -311,22 +324,13 @@ void drv_bo_destroy(struct bo *bo) for (plane = 0; plane < bo->num_planes; plane++) drv_decrement_reference_count(drv, bo, plane); - for (plane = 0; plane < bo->num_planes; plane++) { - void *ptr; - + for (plane = 0; plane < bo->num_planes; plane++) total += drv_get_reference_count(drv, bo, plane); - map_count += !drmHashLookup(bo->drv->map_table, bo->handles[plane].u32, &ptr); - } pthread_mutex_unlock(&drv->driver_lock); if (total == 0) { - /* - * If we leak a reference to the GEM handle being freed here in the mapping table, - * we risk using the mapping table entry later for a completely different BO that - * gets the same handle. (See b/38250067.) - */ - assert(!map_count); + assert(drv_mapping_destroy(bo) == 0); bo->drv->backend->bo_destroy(bo); } @@ -338,8 +342,9 @@ struct bo *drv_bo_import(struct driver *drv, struct drv_import_fd_data *data) int ret; size_t plane; struct bo *bo; + off_t seek_end; - bo = drv_bo_new(drv, data->width, data->height, data->format, data->flags); + bo = drv_bo_new(drv, data->width, data->height, data->format, data->use_flags); if (!bo) return NULL; @@ -353,82 +358,162 @@ struct bo *drv_bo_import(struct driver *drv, struct drv_import_fd_data *data) for (plane = 0; plane < bo->num_planes; plane++) { bo->strides[plane] = data->strides[plane]; bo->offsets[plane] = data->offsets[plane]; - bo->sizes[plane] = data->sizes[plane]; bo->format_modifiers[plane] = data->format_modifiers[plane]; - bo->total_size += data->sizes[plane]; + + seek_end = lseek(data->fds[plane], 0, SEEK_END); + if (seek_end == (off_t)(-1)) { + fprintf(stderr, "drv: lseek() failed with %s\n", strerror(errno)); + goto destroy_bo; + } + + lseek(data->fds[plane], 0, SEEK_SET); + if (plane == bo->num_planes - 1 || data->offsets[plane + 1] == 0) + bo->sizes[plane] = seek_end - data->offsets[plane]; + else + bo->sizes[plane] = data->offsets[plane + 1] - data->offsets[plane]; + + if ((int64_t)bo->offsets[plane] + bo->sizes[plane] > seek_end) { + fprintf(stderr, "drv: buffer size is too large.\n"); + goto destroy_bo; + } + + bo->total_size += bo->sizes[plane]; } return bo; + +destroy_bo: + drv_bo_destroy(bo); + return NULL; } -void *drv_bo_map(struct bo *bo, uint32_t x, uint32_t y, uint32_t width, uint32_t height, - uint32_t flags, struct map_info **map_data, size_t plane) +void *drv_bo_map(struct bo *bo, const struct rectangle *rect, uint32_t map_flags, + struct mapping **map_data, size_t plane) { - void *ptr; + uint32_t i; uint8_t *addr; - size_t offset; - struct map_info *data; - int prot; + struct mapping mapping; + + assert(rect->width >= 0); + assert(rect->height >= 0); + assert(rect->x + rect->width <= drv_bo_get_width(bo)); + assert(rect->y + rect->height <= drv_bo_get_height(bo)); + assert(BO_MAP_READ_WRITE & map_flags); + /* No CPU access for protected buffers. */ + assert(!(bo->use_flags & BO_USE_PROTECTED)); - assert(width > 0); - assert(height > 0); - assert(x + width <= drv_bo_get_width(bo)); - assert(y + height <= drv_bo_get_height(bo)); - assert(BO_TRANSFER_READ_WRITE & flags); + memset(&mapping, 0, sizeof(mapping)); + mapping.rect = *rect; + mapping.refcount = 1; pthread_mutex_lock(&bo->drv->driver_lock); - if (!drmHashLookup(bo->drv->map_table, bo->handles[plane].u32, &ptr)) { - data = (struct map_info *)ptr; - data->refcount++; + for (i = 0; i < drv_array_size(bo->drv->mappings); i++) { + struct mapping *prior = (struct mapping *)drv_array_at_idx(bo->drv->mappings, i); + if (prior->vma->handle != bo->handles[plane].u32 || + prior->vma->map_flags != map_flags) + continue; + + if (rect->x != prior->rect.x || rect->y != prior->rect.y || + rect->width != prior->rect.width || rect->height != prior->rect.height) + continue; + + prior->refcount++; + *map_data = prior; + goto exact_match; + } + + for (i = 0; i < drv_array_size(bo->drv->mappings); i++) { + struct mapping *prior = (struct mapping *)drv_array_at_idx(bo->drv->mappings, i); + if (prior->vma->handle != bo->handles[plane].u32 || + prior->vma->map_flags != map_flags) + continue; + + prior->vma->refcount++; + mapping.vma = prior->vma; goto success; } - data = calloc(1, sizeof(*data)); - prot = BO_TRANSFER_WRITE & flags ? PROT_WRITE | PROT_READ : PROT_READ; - addr = bo->drv->backend->bo_map(bo, data, plane, prot); + mapping.vma = calloc(1, sizeof(*mapping.vma)); + addr = bo->drv->backend->bo_map(bo, mapping.vma, plane, map_flags); if (addr == MAP_FAILED) { *map_data = NULL; - free(data); + free(mapping.vma); pthread_mutex_unlock(&bo->drv->driver_lock); return MAP_FAILED; } - data->refcount = 1; - data->addr = addr; - data->handle = bo->handles[plane].u32; - drmHashInsert(bo->drv->map_table, bo->handles[plane].u32, (void *)data); + mapping.vma->refcount = 1; + mapping.vma->addr = addr; + mapping.vma->handle = bo->handles[plane].u32; + mapping.vma->map_flags = map_flags; success: - *map_data = data; - offset = drv_bo_get_plane_stride(bo, plane) * y; - offset += drv_stride_from_format(bo->format, x, plane); - addr = (uint8_t *)data->addr; - addr += drv_bo_get_plane_offset(bo, plane) + offset; + *map_data = drv_array_append(bo->drv->mappings, &mapping); +exact_match: + drv_bo_invalidate(bo, *map_data); + addr = (uint8_t *)((*map_data)->vma->addr); + addr += drv_bo_get_plane_offset(bo, plane); pthread_mutex_unlock(&bo->drv->driver_lock); - return (void *)addr; } -int drv_bo_unmap(struct bo *bo, struct map_info *data) +int drv_bo_unmap(struct bo *bo, struct mapping *mapping) { - int ret = 0; - - assert(data); - assert(data->refcount >= 0); + uint32_t i; + int ret = drv_bo_flush(bo, mapping); + if (ret) + return ret; pthread_mutex_lock(&bo->drv->driver_lock); - if (!--data->refcount) { - if (bo->drv->backend->bo_unmap) - ret = bo->drv->backend->bo_unmap(bo, data); - else - ret = munmap(data->addr, data->length); - drmHashDelete(bo->drv->map_table, data->handle); - free(data); + if (--mapping->refcount) + goto out; + + if (!--mapping->vma->refcount) { + ret = bo->drv->backend->bo_unmap(bo, mapping->vma); + free(mapping->vma); } + for (i = 0; i < drv_array_size(bo->drv->mappings); i++) { + if (mapping == (struct mapping *)drv_array_at_idx(bo->drv->mappings, i)) { + drv_array_remove(bo->drv->mappings, i); + break; + } + } + +out: pthread_mutex_unlock(&bo->drv->driver_lock); + return ret; +} + +int drv_bo_invalidate(struct bo *bo, struct mapping *mapping) +{ + int ret = 0; + + assert(mapping); + assert(mapping->vma); + assert(mapping->refcount > 0); + assert(mapping->vma->refcount > 0); + + if (bo->drv->backend->bo_invalidate) + ret = bo->drv->backend->bo_invalidate(bo, mapping); + + return ret; +} + +int drv_bo_flush(struct bo *bo, struct mapping *mapping) +{ + int ret = 0; + + assert(mapping); + assert(mapping->vma); + assert(mapping->refcount > 0); + assert(mapping->vma->refcount > 0); + assert(!(bo->use_flags & BO_USE_PROTECTED)); + + if (bo->drv->backend->bo_flush) + ret = bo->drv->backend->bo_flush(bo, mapping); return ret; } @@ -502,10 +587,10 @@ uint32_t drv_bo_get_format(struct bo *bo) return bo->format; } -uint32_t drv_resolve_format(struct driver *drv, uint32_t format, uint64_t usage) +uint32_t drv_resolve_format(struct driver *drv, uint32_t format, uint64_t use_flags) { if (drv->backend->resolve_format) - return drv->backend->resolve_format(format, usage); + return drv->backend->resolve_format(format, use_flags); return format; } @@ -573,24 +658,6 @@ size_t drv_num_planes_from_format(uint32_t format) return 0; } -uint32_t drv_size_from_format(uint32_t format, uint32_t stride, uint32_t height, size_t plane) -{ - assert(plane < drv_num_planes_from_format(format)); - uint32_t vertical_subsampling; - - switch (format) { - case DRM_FORMAT_NV12: - case DRM_FORMAT_YVU420: - case DRM_FORMAT_YVU420_ANDROID: - vertical_subsampling = (plane == 0) ? 1 : 2; - break; - default: - vertical_subsampling = 1; - } - - return stride * DIV_ROUND_UP(height, vertical_subsampling); -} - uint32_t drv_num_buffers_per_bo(struct bo *bo) { uint32_t count = 0; diff --git a/chromium/third_party/minigbm/src/drv.h b/chromium/third_party/minigbm/src/drv.h index e4678a118e5..18653e5b93a 100644 --- a/chromium/third_party/minigbm/src/drv.h +++ b/chromium/third_party/minigbm/src/drv.h @@ -38,11 +38,11 @@ extern "C" { #define BO_USE_RENDERSCRIPT (1ull << 16) #define BO_USE_TEXTURE (1ull << 17) -/* Read-Write permissions for drv_bo_map() flags */ -#define BO_TRANSFER_NONE 0 -#define BO_TRANSFER_READ (1 << 0) -#define BO_TRANSFER_WRITE (1 << 1) -#define BO_TRANSFER_READ_WRITE (BO_TRANSFER_READ | BO_TRANSFER_WRITE) +/* Map flags */ +#define BO_MAP_NONE 0 +#define BO_MAP_READ (1 << 0) +#define BO_MAP_WRITE (1 << 1) +#define BO_MAP_READ_WRITE (BO_MAP_READ | BO_MAP_WRITE) /* This is our extension to <drm_fourcc.h>. We need to make sure we don't step * on the namespace of already defined formats, which can be done by using invalid @@ -71,22 +71,35 @@ struct drv_import_fd_data { int fds[DRV_MAX_PLANES]; uint32_t strides[DRV_MAX_PLANES]; uint32_t offsets[DRV_MAX_PLANES]; - uint32_t sizes[DRV_MAX_PLANES]; uint64_t format_modifiers[DRV_MAX_PLANES]; uint32_t width; uint32_t height; uint32_t format; - uint64_t flags; + uint64_t use_flags; }; -struct map_info { +struct vma { void *addr; size_t length; uint32_t handle; + uint32_t map_flags; int32_t refcount; void *priv; }; +struct rectangle { + uint32_t x; + uint32_t y; + uint32_t width; + uint32_t height; +}; + +struct mapping { + struct vma *vma; + struct rectangle rect; + uint32_t refcount; +}; + struct driver *drv_create(int fd); void drv_destroy(struct driver *drv); @@ -95,13 +108,13 @@ int drv_get_fd(struct driver *drv); const char *drv_get_name(struct driver *drv); -struct combination *drv_get_combination(struct driver *drv, uint32_t format, uint64_t usage); +struct combination *drv_get_combination(struct driver *drv, uint32_t format, uint64_t use_flags); struct bo *drv_bo_new(struct driver *drv, uint32_t width, uint32_t height, uint32_t format, - uint64_t flags); + uint64_t use_flags); struct bo *drv_bo_create(struct driver *drv, uint32_t width, uint32_t height, uint32_t format, - uint64_t flags); + uint64_t use_flags); struct bo *drv_bo_create_with_modifiers(struct driver *drv, uint32_t width, uint32_t height, uint32_t format, const uint64_t *modifiers, uint32_t count); @@ -110,10 +123,14 @@ void drv_bo_destroy(struct bo *bo); struct bo *drv_bo_import(struct driver *drv, struct drv_import_fd_data *data); -void *drv_bo_map(struct bo *bo, uint32_t x, uint32_t y, uint32_t width, uint32_t height, - uint32_t flags, struct map_info **map_data, size_t plane); +void *drv_bo_map(struct bo *bo, const struct rectangle *rect, uint32_t map_flags, + struct mapping **map_data, size_t plane); + +int drv_bo_unmap(struct bo *bo, struct mapping *mapping); + +int drv_bo_invalidate(struct bo *bo, struct mapping *mapping); -int drv_bo_unmap(struct bo *bo, struct map_info *map_data); +int drv_bo_flush(struct bo *bo, struct mapping *mapping); uint32_t drv_bo_get_width(struct bo *bo); @@ -139,11 +156,11 @@ uint32_t drv_bo_get_format(struct bo *bo); uint32_t drv_bo_get_stride_in_pixels(struct bo *bo); -uint32_t drv_resolve_format(struct driver *drv, uint32_t format, uint64_t usage); +uint32_t drv_stride_from_format(uint32_t format, uint32_t width, size_t plane); -size_t drv_num_planes_from_format(uint32_t format); +uint32_t drv_resolve_format(struct driver *drv, uint32_t format, uint64_t use_flags); -uint32_t drv_size_from_format(uint32_t format, uint32_t stride, uint32_t height, size_t plane); +size_t drv_num_planes_from_format(uint32_t format); uint32_t drv_num_buffers_per_bo(struct bo *bo); diff --git a/chromium/third_party/minigbm/src/drv_priv.h b/chromium/third_party/minigbm/src/drv_priv.h index 5547b787e91..21c003bae31 100644 --- a/chromium/third_party/minigbm/src/drv_priv.h +++ b/chromium/third_party/minigbm/src/drv_priv.h @@ -26,24 +26,15 @@ struct bo { uint32_t sizes[DRV_MAX_PLANES]; uint32_t strides[DRV_MAX_PLANES]; uint64_t format_modifiers[DRV_MAX_PLANES]; - uint64_t flags; + uint64_t use_flags; size_t total_size; void *priv; }; -struct driver { - int fd; - struct backend *backend; - void *priv; - void *buffer_table; - void *map_table; - pthread_mutex_t driver_lock; -}; - struct kms_item { uint32_t format; uint64_t modifier; - uint64_t usage; + uint64_t use_flags; }; struct format_metadata { @@ -55,13 +46,17 @@ struct format_metadata { struct combination { uint32_t format; struct format_metadata metadata; - uint64_t usage; + uint64_t use_flags; }; -struct combinations { - struct combination *data; - uint32_t size; - uint32_t allocations; +struct driver { + int fd; + const struct backend *backend; + void *priv; + void *buffer_table; + struct drv_array *mappings; + struct drv_array *combos; + pthread_mutex_t driver_lock; }; struct backend { @@ -69,27 +64,35 @@ struct backend { int (*init)(struct driver *drv); void (*close)(struct driver *drv); int (*bo_create)(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, - uint32_t flags); + uint64_t use_flags); int (*bo_create_with_modifiers)(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, const uint64_t *modifiers, uint32_t count); int (*bo_destroy)(struct bo *bo); int (*bo_import)(struct bo *bo, struct drv_import_fd_data *data); - void *(*bo_map)(struct bo *bo, struct map_info *data, size_t plane, int prot); - int (*bo_unmap)(struct bo *bo, struct map_info *data); - uint32_t (*resolve_format)(uint32_t format, uint64_t usage); - struct combinations combos; + void *(*bo_map)(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags); + int (*bo_unmap)(struct bo *bo, struct vma *vma); + int (*bo_invalidate)(struct bo *bo, struct mapping *mapping); + int (*bo_flush)(struct bo *bo, struct mapping *mapping); + uint32_t (*resolve_format)(uint32_t format, uint64_t use_flags); }; // clang-format off -#define BO_USE_RENDER_MASK BO_USE_LINEAR | BO_USE_RENDERING | BO_USE_RENDERSCRIPT | \ - BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | \ - BO_USE_SW_WRITE_RARELY | BO_USE_TEXTURE +#define BO_USE_RENDER_MASK BO_USE_LINEAR | BO_USE_PROTECTED | BO_USE_RENDERING | \ + BO_USE_RENDERSCRIPT | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN | \ + BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY | BO_USE_TEXTURE + +#define BO_USE_TEXTURE_MASK BO_USE_LINEAR | BO_USE_PROTECTED | BO_USE_RENDERSCRIPT | \ + BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN | \ + BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY | BO_USE_TEXTURE + +#define BO_USE_SW BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN | \ + BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY + +#define BO_USE_SW_OFTEN BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN -#define BO_USE_TEXTURE_MASK BO_USE_LINEAR | BO_USE_RENDERSCRIPT | BO_USE_SW_READ_OFTEN | \ - BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY | \ - BO_USE_SW_WRITE_RARELY | BO_USE_TEXTURE +#define BO_USE_SW_RARELY BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY -#define LINEAR_METADATA (struct format_metadata) { 0, 1, DRM_FORMAT_MOD_NONE } +#define LINEAR_METADATA (struct format_metadata) { 0, 1, DRM_FORMAT_MOD_LINEAR } // clang-format on #endif diff --git a/chromium/third_party/minigbm/src/evdi.c b/chromium/third_party/minigbm/src/evdi.c index f66fb2d48bb..bfa62a045c1 100644 --- a/chromium/third_party/minigbm/src/evdi.c +++ b/chromium/third_party/minigbm/src/evdi.c @@ -12,20 +12,18 @@ static const uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMA static int evdi_init(struct driver *drv) { - int ret; - ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &LINEAR_METADATA, BO_USE_RENDER_MASK); - if (ret) - return ret; + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &LINEAR_METADATA, BO_USE_RENDER_MASK); return drv_modify_linear_combinations(drv); } -struct backend backend_evdi = { +const struct backend backend_evdi = { .name = "evdi", .init = evdi_init, .bo_create = drv_dumb_bo_create, .bo_destroy = drv_dumb_bo_destroy, .bo_import = drv_prime_bo_import, .bo_map = drv_dumb_bo_map, + .bo_unmap = drv_bo_munmap, }; diff --git a/chromium/third_party/minigbm/src/exynos.c b/chromium/third_party/minigbm/src/exynos.c index 0d935ebf13c..526603e9b05 100644 --- a/chromium/third_party/minigbm/src/exynos.c +++ b/chromium/third_party/minigbm/src/exynos.c @@ -25,22 +25,17 @@ static const uint32_t texture_source_formats[] = { DRM_FORMAT_NV12 }; static int exynos_init(struct driver *drv) { - int ret; - ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &LINEAR_METADATA, BO_USE_RENDER_MASK); - if (ret) - return ret; + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &LINEAR_METADATA, BO_USE_RENDER_MASK); - ret = drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), - &LINEAR_METADATA, BO_USE_TEXTURE_MASK); - if (ret) - return ret; + drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), + &LINEAR_METADATA, BO_USE_TEXTURE_MASK); return drv_modify_linear_combinations(drv); } static int exynos_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, - uint32_t flags) + uint64_t use_flags) { size_t plane; @@ -105,13 +100,14 @@ cleanup_planes: * Use dumb mapping with exynos even though a GEM buffer is created. * libdrm does the same thing in exynos_drm.c */ -struct backend backend_exynos = { +const struct backend backend_exynos = { .name = "exynos", .init = exynos_init, .bo_create = exynos_bo_create, .bo_destroy = drv_gem_bo_destroy, .bo_import = drv_prime_bo_import, .bo_map = drv_dumb_bo_map, + .bo_unmap = drv_bo_munmap, }; #endif diff --git a/chromium/third_party/minigbm/src/gbm.c b/chromium/third_party/minigbm/src/gbm.c index 37fb1d914c7..25b4fa0bc68 100644 --- a/chromium/third_party/minigbm/src/gbm.c +++ b/chromium/third_party/minigbm/src/gbm.c @@ -10,6 +10,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <sys/mman.h> #include <xf86drm.h> #include "drv.h" @@ -30,14 +31,14 @@ PUBLIC const char *gbm_device_get_backend_name(struct gbm_device *gbm) PUBLIC int gbm_device_is_format_supported(struct gbm_device *gbm, uint32_t format, uint32_t usage) { - uint64_t drv_usage; + uint64_t use_flags; if (usage & GBM_BO_USE_CURSOR && usage & GBM_BO_USE_RENDERING) return 0; - drv_usage = gbm_convert_flags(usage); + use_flags = gbm_convert_usage(usage); - return (drv_get_combination(gbm->drv, format, drv_usage) != NULL); + return (drv_get_combination(gbm->drv, format, use_flags) != NULL); } PUBLIC struct gbm_device *gbm_create_device(int fd) @@ -65,7 +66,7 @@ PUBLIC void gbm_device_destroy(struct gbm_device *gbm) } PUBLIC struct gbm_surface *gbm_surface_create(struct gbm_device *gbm, uint32_t width, - uint32_t height, uint32_t format, uint32_t flags) + uint32_t height, uint32_t format, uint32_t usage) { struct gbm_surface *surface = (struct gbm_surface *)malloc(sizeof(*surface)); @@ -104,11 +105,11 @@ static struct gbm_bo *gbm_bo_new(struct gbm_device *gbm, uint32_t format) } PUBLIC struct gbm_bo *gbm_bo_create(struct gbm_device *gbm, uint32_t width, uint32_t height, - uint32_t format, uint32_t flags) + uint32_t format, uint32_t usage) { struct gbm_bo *bo; - if (!gbm_device_is_format_supported(gbm, format, flags)) + if (!gbm_device_is_format_supported(gbm, format, usage)) return NULL; bo = gbm_bo_new(gbm, format); @@ -116,7 +117,7 @@ PUBLIC struct gbm_bo *gbm_bo_create(struct gbm_device *gbm, uint32_t width, uint if (!bo) return NULL; - bo->bo = drv_bo_create(gbm->drv, width, height, format, gbm_convert_flags(flags)); + bo->bo = drv_bo_create(gbm->drv, width, height, format, gbm_convert_usage(usage)); if (!bo->bo) { free(bo); @@ -170,7 +171,7 @@ PUBLIC struct gbm_bo *gbm_bo_import(struct gbm_device *gbm, uint32_t type, void size_t num_planes, i; memset(&drv_data, 0, sizeof(drv_data)); - + drv_data.use_flags = gbm_convert_usage(usage); switch (type) { case GBM_BO_IMPORT_FD: gbm_format = fd_data->format; @@ -179,7 +180,6 @@ PUBLIC struct gbm_bo *gbm_bo_import(struct gbm_device *gbm, uint32_t type, void drv_data.format = fd_data->format; drv_data.fds[0] = fd_data->fd; drv_data.strides[0] = fd_data->stride; - drv_data.sizes[0] = fd_data->height * fd_data->stride; break; case GBM_BO_IMPORT_FD_PLANAR: gbm_format = fd_planar_data->format; @@ -195,9 +195,6 @@ PUBLIC struct gbm_bo *gbm_bo_import(struct gbm_device *gbm, uint32_t type, void drv_data.offsets[i] = fd_planar_data->offsets[i]; drv_data.strides[i] = fd_planar_data->strides[i]; drv_data.format_modifiers[i] = fd_planar_data->format_modifiers[i]; - - drv_data.sizes[i] = drv_size_from_format( - drv_data.format, drv_data.strides[i], drv_data.height, i); } for (i = num_planes; i < GBM_MAX_PLANES; i++) @@ -227,22 +224,32 @@ PUBLIC struct gbm_bo *gbm_bo_import(struct gbm_device *gbm, uint32_t type, void } PUBLIC 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, size_t plane) + uint32_t transfer_flags, uint32_t *stride, void **map_data, size_t plane) { + void *addr; + off_t offset; + uint32_t map_flags; + struct rectangle rect = { .x = x, .y = y, .width = width, .height = height }; if (!bo || width == 0 || height == 0 || !stride || !map_data) return NULL; *stride = gbm_bo_get_plane_stride(bo, plane); - uint32_t drv_flags = flags & GBM_BO_TRANSFER_READ ? BO_TRANSFER_READ : BO_TRANSFER_NONE; - drv_flags |= flags & GBM_BO_TRANSFER_WRITE ? BO_TRANSFER_WRITE : BO_TRANSFER_NONE; - return drv_bo_map(bo->bo, x, y, width, height, drv_flags, (struct map_info **)map_data, - plane); + map_flags = (transfer_flags & GBM_BO_TRANSFER_READ) ? BO_MAP_READ : BO_MAP_NONE; + map_flags |= (transfer_flags & GBM_BO_TRANSFER_WRITE) ? BO_MAP_WRITE : BO_MAP_NONE; + + addr = drv_bo_map(bo->bo, &rect, map_flags, (struct mapping **)map_data, plane); + if (addr == MAP_FAILED) + return MAP_FAILED; + + offset = gbm_bo_get_plane_stride(bo, plane) * rect.y; + offset += drv_stride_from_format(bo->gbm_format, rect.x, plane); + return (void *)((uint8_t *)addr + offset); } PUBLIC void gbm_bo_unmap(struct gbm_bo *bo, void *map_data) { assert(bo); - drv_bo_unmap(bo->bo, map_data); + drv_bo_flush(bo->bo, map_data); } PUBLIC uint32_t gbm_bo_get_width(struct gbm_bo *bo) diff --git a/chromium/third_party/minigbm/src/gbm.h b/chromium/third_party/minigbm/src/gbm.h index 5ec13bc003d..da993c2a16e 100644 --- a/chromium/third_party/minigbm/src/gbm.h +++ b/chromium/third_party/minigbm/src/gbm.h @@ -236,7 +236,8 @@ enum gbm_bo_flags { * Buffer is guaranteed to be laid out linearly in memory. That is, the * buffer is laid out as an array with 'height' blocks, each block with * length 'stride'. Each stride is in the same order as the rows of the - * buffer. + * buffer. This is intended to be used with buffers that will be accessed + * via dma-buf mmap(). */ GBM_BO_USE_LINEAR = (1 << 4), /** @@ -251,6 +252,19 @@ enum gbm_bo_flags { * The buffer will be read from by a camera subsystem. */ GBM_BO_USE_CAMERA_READ = (1 << 7), + /** + * Buffer inaccessible to unprivileged users. + */ + GBM_BO_USE_PROTECTED = (1 << 8), + /** + * These flags specify the frequency of software access. These flags do not + * guarantee the buffer is linear, but do guarantee gbm_bo_map(..) will + * present a linear view. + */ + GBM_BO_USE_SW_READ_OFTEN = (1 << 9), + GBM_BO_USE_SW_READ_RARELY = (1 << 10), + GBM_BO_USE_SW_WRITE_OFTEN = (1 << 11), + GBM_BO_USE_SW_WRITE_RARELY = (1 << 12), }; int diff --git a/chromium/third_party/minigbm/src/gbm_helpers.c b/chromium/third_party/minigbm/src/gbm_helpers.c index 529d7fe73b0..26836696e42 100644 --- a/chromium/third_party/minigbm/src/gbm_helpers.c +++ b/chromium/third_party/minigbm/src/gbm_helpers.c @@ -10,26 +10,36 @@ #include "drv.h" #include "gbm.h" -uint64_t gbm_convert_flags(uint32_t flags) +uint64_t gbm_convert_usage(uint32_t usage) { - uint64_t usage = BO_USE_NONE; + uint64_t use_flags = BO_USE_NONE; - if (flags & GBM_BO_USE_SCANOUT) - usage |= BO_USE_SCANOUT; - if (flags & GBM_BO_USE_CURSOR) - usage |= BO_USE_CURSOR; - if (flags & GBM_BO_USE_CURSOR_64X64) - usage |= BO_USE_CURSOR_64X64; - if (flags & GBM_BO_USE_RENDERING) - usage |= BO_USE_RENDERING; - if (flags & GBM_BO_USE_TEXTURING) - usage |= BO_USE_TEXTURE; - if (flags & GBM_BO_USE_LINEAR) - usage |= BO_USE_LINEAR; - if (flags & GBM_BO_USE_CAMERA_WRITE) - usage |= BO_USE_CAMERA_WRITE; - if (flags & GBM_BO_USE_CAMERA_READ) - usage |= BO_USE_CAMERA_READ; + if (usage & GBM_BO_USE_SCANOUT) + use_flags |= BO_USE_SCANOUT; + if (usage & GBM_BO_USE_CURSOR) + use_flags |= BO_USE_CURSOR; + if (usage & GBM_BO_USE_CURSOR_64X64) + use_flags |= BO_USE_CURSOR_64X64; + if (usage & GBM_BO_USE_RENDERING) + use_flags |= BO_USE_RENDERING; + if (usage & GBM_BO_USE_TEXTURING) + use_flags |= BO_USE_TEXTURE; + if (usage & GBM_BO_USE_LINEAR) + use_flags |= BO_USE_LINEAR; + if (usage & GBM_BO_USE_CAMERA_WRITE) + use_flags |= BO_USE_CAMERA_WRITE; + if (usage & GBM_BO_USE_CAMERA_READ) + use_flags |= BO_USE_CAMERA_READ; + if (usage & GBM_BO_USE_PROTECTED) + use_flags |= BO_USE_PROTECTED; + if (usage & GBM_BO_USE_SW_READ_OFTEN) + use_flags |= BO_USE_SW_READ_OFTEN; + if (usage & GBM_BO_USE_SW_READ_RARELY) + use_flags |= BO_USE_SW_READ_RARELY; + if (usage & GBM_BO_USE_SW_WRITE_OFTEN) + use_flags |= BO_USE_SW_WRITE_OFTEN; + if (usage & GBM_BO_USE_SW_WRITE_RARELY) + use_flags |= BO_USE_SW_WRITE_RARELY; - return usage; + return use_flags; } diff --git a/chromium/third_party/minigbm/src/gbm_helpers.h b/chromium/third_party/minigbm/src/gbm_helpers.h index 48ff3913736..4d625c52dc9 100644 --- a/chromium/third_party/minigbm/src/gbm_helpers.h +++ b/chromium/third_party/minigbm/src/gbm_helpers.h @@ -7,6 +7,6 @@ #ifndef GBM_HELPERS_H #define GBM_HELPERS_H -uint64_t gbm_convert_flags(uint32_t flags); +uint64_t gbm_convert_usage(uint32_t usage); #endif diff --git a/chromium/third_party/minigbm/src/gma500.c b/chromium/third_party/minigbm/src/gma500.c deleted file mode 100644 index 5b08bc32b09..00000000000 --- a/chromium/third_party/minigbm/src/gma500.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2014 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "drv_priv.h" -#include "helpers.h" -#include "util.h" - -static const uint32_t render_target_formats[] = { DRM_FORMAT_RGBX8888 }; - -static int gma500_init(struct driver *drv) -{ - int ret; - ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &LINEAR_METADATA, BO_USE_RENDER_MASK); - if (ret) - return ret; - - return drv_modify_linear_combinations(drv); -} - -struct backend backend_gma500 = { - .name = "gma500", - .init = gma500_init, - .bo_create = drv_dumb_bo_create, - .bo_destroy = drv_dumb_bo_destroy, - .bo_import = drv_prime_bo_import, - .bo_map = drv_dumb_bo_map, -}; diff --git a/chromium/third_party/minigbm/src/helpers.c b/chromium/third_party/minigbm/src/helpers.c index 238563de923..6c26e54795d 100644 --- a/chromium/third_party/minigbm/src/helpers.c +++ b/chromium/third_party/minigbm/src/helpers.c @@ -127,6 +127,24 @@ uint32_t drv_stride_from_format(uint32_t format, uint32_t width, size_t plane) return stride; } +uint32_t drv_size_from_format(uint32_t format, uint32_t stride, uint32_t height, size_t plane) +{ + assert(plane < drv_num_planes_from_format(format)); + uint32_t vertical_subsampling; + + switch (format) { + case DRM_FORMAT_NV12: + case DRM_FORMAT_YVU420: + case DRM_FORMAT_YVU420_ANDROID: + vertical_subsampling = (plane == 0) ? 1 : 2; + break; + default: + vertical_subsampling = 1; + } + + return stride * DIV_ROUND_UP(height, vertical_subsampling); +} + /* * This function fills in the buffer object given the driver aligned stride of * the first plane, height and a format. This function assumes there is just @@ -164,7 +182,7 @@ int drv_bo_from_format(struct bo *bo, uint32_t stride, uint32_t aligned_height, } int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, - uint32_t flags) + uint64_t use_flags) { int ret; size_t plane; @@ -291,7 +309,7 @@ int drv_prime_bo_import(struct bo *bo, struct drv_import_fd_data *data) return 0; } -void *drv_dumb_bo_map(struct bo *bo, struct map_info *data, size_t plane, int prot) +void *drv_dumb_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags) { int ret; size_t i; @@ -308,9 +326,59 @@ void *drv_dumb_bo_map(struct bo *bo, struct map_info *data, size_t plane, int pr for (i = 0; i < bo->num_planes; i++) if (bo->handles[i].u32 == bo->handles[plane].u32) - data->length += bo->sizes[i]; + vma->length += bo->sizes[i]; + + return mmap(0, vma->length, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, + map_dumb.offset); +} + +int drv_bo_munmap(struct bo *bo, struct vma *vma) +{ + return munmap(vma->addr, vma->length); +} + +int drv_mapping_destroy(struct bo *bo) +{ + int ret; + size_t plane; + struct mapping *mapping; + uint32_t idx; + + /* + * This function is called right before the buffer is destroyed. It will free any mappings + * associated with the buffer. + */ + + idx = 0; + for (plane = 0; plane < bo->num_planes; plane++) { + while (idx < drv_array_size(bo->drv->mappings)) { + mapping = (struct mapping *)drv_array_at_idx(bo->drv->mappings, idx); + if (mapping->vma->handle != bo->handles[plane].u32) { + idx++; + continue; + } + + if (!--mapping->vma->refcount) { + ret = bo->drv->backend->bo_unmap(bo, mapping->vma); + if (ret) { + fprintf(stderr, "drv: munmap failed"); + return ret; + } + + free(mapping->vma); + } + + /* This shrinks and shifts the array, so don't increment idx. */ + drv_array_remove(bo->drv->mappings, idx); + } + } + + return 0; +} - return mmap(0, data->length, prot, MAP_SHARED, bo->drv->fd, map_dumb.offset); +int drv_get_prot(uint32_t map_flags) +{ + return (BO_MAP_WRITE & map_flags) ? PROT_WRITE | PROT_READ : PROT_READ; } uintptr_t drv_get_reference_count(struct driver *drv, struct bo *bo, size_t plane) @@ -353,73 +421,47 @@ uint32_t drv_log_base2(uint32_t value) return ret; } -int drv_add_combination(struct driver *drv, uint32_t format, struct format_metadata *metadata, - uint64_t usage) -{ - 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; - - combos->data = new_data; - } - - 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_combinations(struct driver *drv, const uint32_t *formats, uint32_t num_formats, - struct format_metadata *metadata, uint64_t usage) +void drv_add_combinations(struct driver *drv, const uint32_t *formats, uint32_t num_formats, + struct format_metadata *metadata, uint64_t use_flags) { - int ret; uint32_t i; + for (i = 0; i < num_formats; i++) { - ret = drv_add_combination(drv, formats[i], metadata, usage); - if (ret) - return ret; - } + struct combination combo = { .format = formats[i], + .metadata = *metadata, + .use_flags = use_flags }; - return 0; + drv_array_append(drv->combos, &combo); + } } void drv_modify_combination(struct driver *drv, uint32_t format, struct format_metadata *metadata, - uint64_t usage) + uint64_t use_flags) { 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]; + /* Attempts to add the specified flags to an existing combination. */ + for (i = 0; i < drv_array_size(drv->combos); i++) { + combo = (struct combination *)drv_array_at_idx(drv->combos, i); if (combo->format == format && combo->metadata.tiling == metadata->tiling && combo->metadata.modifier == metadata->modifier) - combo->usage |= usage; + combo->use_flags |= use_flags; } } -struct kms_item *drv_query_kms(struct driver *drv, uint32_t *num_items) +struct drv_array *drv_query_kms(struct driver *drv) { - uint64_t flag, usage; - struct kms_item *items; - uint32_t i, j, k, allocations, item_size; + struct drv_array *kms_items; + uint64_t plane_type, use_flag; + uint32_t i, j, k; drmModePlanePtr plane; drmModePropertyPtr prop; drmModePlaneResPtr resources; drmModeObjectPropertiesPtr props; - /* Start with a power of 2 number of allocations. */ - allocations = 2; - item_size = 0; - items = calloc(allocations, sizeof(*items)); - if (!items) + kms_items = drv_array_init(sizeof(struct kms_item)); + if (!kms_items) goto out; /* @@ -449,20 +491,20 @@ struct kms_item *drv_query_kms(struct driver *drv, uint32_t *num_items) prop = drmModeGetProperty(drv->fd, props->props[j]); if (prop) { if (strcmp(prop->name, "type") == 0) { - flag = props->prop_values[j]; + plane_type = props->prop_values[j]; } drmModeFreeProperty(prop); } } - switch (flag) { + switch (plane_type) { case DRM_PLANE_TYPE_OVERLAY: case DRM_PLANE_TYPE_PRIMARY: - usage = BO_USE_SCANOUT; + use_flag = BO_USE_SCANOUT; break; case DRM_PLANE_TYPE_CURSOR: - usage = BO_USE_CURSOR; + use_flag = BO_USE_CURSOR; break; default: assert(0); @@ -470,32 +512,22 @@ struct kms_item *drv_query_kms(struct driver *drv, uint32_t *num_items) 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; + for (k = 0; k < drv_array_size(kms_items); k++) { + struct kms_item *item = drv_array_at_idx(kms_items, k); + if (item->format == plane->formats[j] && + item->modifier == DRM_FORMAT_MOD_LINEAR) { + item->use_flags |= use_flag; 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++; + struct kms_item item = { .format = plane->formats[j], + .modifier = DRM_FORMAT_MOD_LINEAR, + .use_flags = use_flag }; + + drv_array_append(kms_items, &item); } } @@ -505,20 +537,20 @@ struct kms_item *drv_query_kms(struct driver *drv, uint32_t *num_items) drmModeFreePlaneResources(resources); out: - if (items && item_size == 0) { - free(items); - items = NULL; + if (kms_items && !drv_array_size(kms_items)) { + drv_array_destroy(kms_items); + return NULL; } - *num_items = item_size; - return items; + return kms_items; } int drv_modify_linear_combinations(struct driver *drv) { - uint32_t i, j, num_items; - struct kms_item *items; + uint32_t i, j; + struct kms_item *item; struct combination *combo; + struct drv_array *kms_items; /* * All current drivers can scanout linear XRGB8888/ARGB8888 as a primary @@ -532,18 +564,39 @@ int drv_modify_linear_combinations(struct driver *drv) drv_modify_combination(drv, DRM_FORMAT_ARGB8888, &LINEAR_METADATA, BO_USE_CURSOR | BO_USE_SCANOUT); - items = drv_query_kms(drv, &num_items); - if (!items || !num_items) + kms_items = drv_query_kms(drv); + if (!kms_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; + for (i = 0; i < drv_array_size(kms_items); i++) { + item = (struct kms_item *)drv_array_at_idx(kms_items, i); + for (j = 0; j < drv_array_size(drv->combos); j++) { + combo = drv_array_at_idx(drv->combos, j); + if (item->format == combo->format) + combo->use_flags |= BO_USE_SCANOUT; } } - free(items); + drv_array_destroy(kms_items); return 0; } + +/* + * Pick the best modifier from modifiers, according to the ordering + * given by modifier_order. + */ +uint64_t drv_pick_modifier(const uint64_t *modifiers, uint32_t count, + const uint64_t *modifier_order, uint32_t order_count) +{ + uint32_t i, j; + + for (i = 0; i < order_count; i++) { + for (j = 0; j < count; j++) { + if (modifiers[j] == modifier_order[i]) { + return modifiers[j]; + } + } + } + + return DRM_FORMAT_MOD_LINEAR; +} diff --git a/chromium/third_party/minigbm/src/helpers.h b/chromium/third_party/minigbm/src/helpers.h index dc1a7c06233..6b8818d2d37 100644 --- a/chromium/third_party/minigbm/src/helpers.h +++ b/chromium/third_party/minigbm/src/helpers.h @@ -8,25 +8,31 @@ #define HELPERS_H #include "drv.h" +#include "helpers_array.h" -uint32_t drv_stride_from_format(uint32_t format, uint32_t width, size_t plane); +uint32_t drv_size_from_format(uint32_t format, uint32_t stride, uint32_t height, size_t plane); int drv_bo_from_format(struct bo *bo, uint32_t stride, uint32_t aligned_height, uint32_t format); int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, - uint32_t flags); + uint64_t use_flags); int drv_dumb_bo_destroy(struct bo *bo); int drv_gem_bo_destroy(struct bo *bo); int drv_prime_bo_import(struct bo *bo, struct drv_import_fd_data *data); -void *drv_dumb_bo_map(struct bo *bo, struct map_info *data, size_t plane, int prot); +void *drv_dumb_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags); +int drv_bo_munmap(struct bo *bo, struct vma *vma); +int drv_mapping_destroy(struct bo *bo); +int drv_get_prot(uint32_t map_flags); uintptr_t drv_get_reference_count(struct driver *drv, struct bo *bo, size_t plane); void drv_increment_reference_count(struct driver *drv, struct bo *bo, size_t plane); void drv_decrement_reference_count(struct driver *drv, struct bo *bo, size_t plane); uint32_t drv_log_base2(uint32_t value); 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_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); +struct drv_array *drv_query_kms(struct driver *drv); int drv_modify_linear_combinations(struct driver *drv); +uint64_t drv_pick_modifier(const uint64_t *modifiers, uint32_t count, + const uint64_t *modifier_order, uint32_t order_count); #endif diff --git a/chromium/third_party/minigbm/src/helpers_array.c b/chromium/third_party/minigbm/src/helpers_array.c new file mode 100644 index 00000000000..20b43e232e6 --- /dev/null +++ b/chromium/third_party/minigbm/src/helpers_array.c @@ -0,0 +1,96 @@ +/* + * Copyright 2017 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <assert.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include "util.h" + +struct drv_array { + void **items; + uint32_t size; + uint32_t item_size; + uint32_t allocations; +}; + +struct drv_array *drv_array_init(uint32_t item_size) +{ + struct drv_array *array; + + array = calloc(1, sizeof(*array)); + + /* Start with a power of 2 number of allocations. */ + array->allocations = 2; + array->items = calloc(array->allocations, sizeof(*array->items)); + array->item_size = item_size; + return array; +} + +void *drv_array_append(struct drv_array *array, void *data) +{ + void *item; + + if (array->size >= array->allocations) { + void **new_items = NULL; + array->allocations *= 2; + new_items = realloc(array->items, array->allocations * sizeof(*array->items)); + assert(new_items); + array->items = new_items; + } + + item = calloc(1, array->item_size); + memcpy(item, data, array->item_size); + array->items[array->size] = item; + array->size++; + return item; +} + +void drv_array_remove(struct drv_array *array, uint32_t idx) +{ + uint32_t i; + + assert(array); + assert(idx < array->size); + + free(array->items[idx]); + array->items[idx] = NULL; + + for (i = idx + 1; i < array->size; i++) + array->items[i - 1] = array->items[i]; + + array->size--; + if ((DIV_ROUND_UP(array->allocations, 2) > array->size) && array->allocations > 2) { + void **new_items = NULL; + array->allocations = DIV_ROUND_UP(array->allocations, 2); + new_items = realloc(array->items, array->allocations * sizeof(*array->items)); + assert(new_items); + array->items = new_items; + } +} + +void *drv_array_at_idx(struct drv_array *array, uint32_t idx) +{ + assert(idx < array->size); + return array->items[idx]; +} + +uint32_t drv_array_size(struct drv_array *array) +{ + return array->size; +} + +void drv_array_destroy(struct drv_array *array) +{ + uint32_t i; + + for (i = 0; i < array->size; i++) + free(array->items[i]); + + free(array->items); + free(array); +} diff --git a/chromium/third_party/minigbm/src/helpers_array.h b/chromium/third_party/minigbm/src/helpers_array.h new file mode 100644 index 00000000000..2893976f2b9 --- /dev/null +++ b/chromium/third_party/minigbm/src/helpers_array.h @@ -0,0 +1,22 @@ +/* + * Copyright 2017 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +struct drv_array; + +struct drv_array *drv_array_init(uint32_t item_size); + +/* The data will be copied and appended to the array. */ +void *drv_array_append(struct drv_array *array, void *data); + +/* The data at the specified index will be freed -- the array will shrink. */ +void drv_array_remove(struct drv_array *array, uint32_t idx); + +void *drv_array_at_idx(struct drv_array *array, uint32_t idx); + +uint32_t drv_array_size(struct drv_array *array); + +/* The array and all associated data will be freed. */ +void drv_array_destroy(struct drv_array *array); diff --git a/chromium/third_party/minigbm/src/i915.c b/chromium/third_party/minigbm/src/i915.c index fe162f16d50..c571c224cf0 100644 --- a/chromium/third_party/minigbm/src/i915.c +++ b/chromium/third_party/minigbm/src/i915.c @@ -20,16 +20,17 @@ #define I915_CACHELINE_SIZE 64 #define I915_CACHELINE_MASK (I915_CACHELINE_SIZE - 1) -static const uint32_t render_target_formats[] = { DRM_FORMAT_ARGB1555, DRM_FORMAT_ABGR8888, - DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB565, - DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB1555, +static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB1555, + DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB565, + DRM_FORMAT_XBGR2101010, DRM_FORMAT_XBGR8888, + DRM_FORMAT_XRGB1555, DRM_FORMAT_XRGB2101010, DRM_FORMAT_XRGB8888 }; -static const uint32_t tileable_texture_source_formats[] = { DRM_FORMAT_GR88, DRM_FORMAT_NV12, - DRM_FORMAT_R8, DRM_FORMAT_UYVY, - DRM_FORMAT_YUYV }; +static const uint32_t tileable_texture_source_formats[] = { DRM_FORMAT_GR88, DRM_FORMAT_R8, + DRM_FORMAT_UYVY, DRM_FORMAT_YUYV }; -static const uint32_t texture_source_formats[] = { DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID }; +static const uint32_t texture_source_formats[] = { DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID, + DRM_FORMAT_NV12 }; struct i915_device { uint32_t gen; @@ -57,12 +58,12 @@ static int i915_add_kms_item(struct driver *drv, const struct kms_item *item) * 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]; + for (i = 0; i < drv_array_size(drv->combos); i++) { + combo = (struct combination *)drv_array_at_idx(drv->combos, i); if (combo->format != item->format) continue; - if (item->modifier == DRM_FORMAT_MOD_NONE && + if (item->modifier == DRM_FORMAT_MOD_LINEAR && combo->metadata.tiling == I915_TILING_X) { /* * FIXME: drv_query_kms() does not report the available modifiers @@ -70,11 +71,11 @@ static int i915_add_kms_item(struct driver *drv, const struct kms_item *item) * buffers, so let's add this to our combinations, except for * cursor, which must not be tiled. */ - combo->usage |= item->usage & ~BO_USE_CURSOR; + combo->use_flags |= item->use_flags & ~BO_USE_CURSOR; } if (combo->metadata.modifier == item->modifier) - combo->usage |= item->usage; + combo->use_flags |= item->use_flags; } return 0; @@ -83,33 +84,27 @@ static int i915_add_kms_item(struct driver *drv, const struct kms_item *item) static int i915_add_combinations(struct driver *drv) { int ret; - uint32_t i, num_items; - struct kms_item *items; + uint32_t i; + struct drv_array *kms_items; struct format_metadata metadata; - uint64_t render_flags, texture_flags; + uint64_t render_use_flags, texture_use_flags; - render_flags = BO_USE_RENDER_MASK; - texture_flags = BO_USE_TEXTURE_MASK; + render_use_flags = BO_USE_RENDER_MASK; + texture_use_flags = BO_USE_TEXTURE_MASK; metadata.tiling = I915_TILING_NONE; metadata.priority = 1; - metadata.modifier = DRM_FORMAT_MOD_NONE; + metadata.modifier = DRM_FORMAT_MOD_LINEAR; - ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &metadata, render_flags); - if (ret) - return ret; + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &metadata, render_use_flags); - ret = drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), - &metadata, texture_flags); - if (ret) - return ret; + drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), + &metadata, texture_use_flags); - ret = drv_add_combinations(drv, tileable_texture_source_formats, - ARRAY_SIZE(tileable_texture_source_formats), &metadata, - texture_flags); - if (ret) - return ret; + drv_add_combinations(drv, tileable_texture_source_formats, + ARRAY_SIZE(tileable_texture_source_formats), &metadata, + texture_use_flags); 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); @@ -124,59 +119,51 @@ static int i915_add_combinations(struct driver *drv) drv_modify_combination(drv, DRM_FORMAT_R8, &metadata, BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); - render_flags &= ~BO_USE_RENDERSCRIPT; - render_flags &= ~BO_USE_SW_WRITE_OFTEN; - render_flags &= ~BO_USE_SW_READ_OFTEN; - render_flags &= ~BO_USE_LINEAR; + render_use_flags &= ~BO_USE_RENDERSCRIPT; + render_use_flags &= ~BO_USE_SW_WRITE_OFTEN; + render_use_flags &= ~BO_USE_SW_READ_OFTEN; + render_use_flags &= ~BO_USE_LINEAR; - texture_flags &= ~BO_USE_RENDERSCRIPT; - texture_flags &= ~BO_USE_SW_WRITE_OFTEN; - texture_flags &= ~BO_USE_SW_READ_OFTEN; - texture_flags &= ~BO_USE_LINEAR; + texture_use_flags &= ~BO_USE_RENDERSCRIPT; + texture_use_flags &= ~BO_USE_SW_WRITE_OFTEN; + texture_use_flags &= ~BO_USE_SW_READ_OFTEN; + texture_use_flags &= ~BO_USE_LINEAR; metadata.tiling = I915_TILING_X; metadata.priority = 2; metadata.modifier = I915_FORMAT_MOD_X_TILED; - ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &metadata, render_flags); - if (ret) - return ret; + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &metadata, render_use_flags); - ret = drv_add_combinations(drv, tileable_texture_source_formats, - ARRAY_SIZE(tileable_texture_source_formats), &metadata, - texture_flags); - if (ret) - return ret; + drv_add_combinations(drv, tileable_texture_source_formats, + ARRAY_SIZE(tileable_texture_source_formats), &metadata, + texture_use_flags); metadata.tiling = I915_TILING_Y; metadata.priority = 3; metadata.modifier = I915_FORMAT_MOD_Y_TILED; - ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &metadata, render_flags); - if (ret) - return ret; + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &metadata, render_use_flags); - ret = drv_add_combinations(drv, tileable_texture_source_formats, - ARRAY_SIZE(tileable_texture_source_formats), &metadata, - texture_flags); - if (ret) - return ret; + drv_add_combinations(drv, tileable_texture_source_formats, + ARRAY_SIZE(tileable_texture_source_formats), &metadata, + texture_use_flags); - items = drv_query_kms(drv, &num_items); - if (!items || !num_items) + kms_items = drv_query_kms(drv); + if (!kms_items) return 0; - for (i = 0; i < num_items; i++) { - ret = i915_add_kms_item(drv, &items[i]); + for (i = 0; i < drv_array_size(kms_items); i++) { + ret = i915_add_kms_item(drv, (struct kms_item *)drv_array_at_idx(kms_items, i)); if (ret) { - free(items); + drv_array_destroy(kms_items); return ret; } } - free(items); + drv_array_destroy(kms_items); return 0; } @@ -218,7 +205,7 @@ static int i915_align_dimensions(struct bo *bo, uint32_t tiling, uint32_t *strid case DRM_FORMAT_YVU420_ANDROID: case DRM_FORMAT_YVU420: horizontal_alignment *= 2; - /* Fall through */ + /* Fall through */ case DRM_FORMAT_NV12: vertical_alignment *= 2; break; @@ -290,21 +277,26 @@ static int i915_init(struct driver *drv) return i915_add_combinations(drv); } -static int i915_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, - uint32_t flags) +static int i915_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t height, + uint32_t format, uint64_t modifier) { int ret; size_t plane; uint32_t stride; struct drm_i915_gem_create gem_create; struct drm_i915_gem_set_tiling gem_set_tiling; - struct combination *combo; - combo = drv_get_combination(bo->drv, format, flags); - if (!combo) - return -EINVAL; - - bo->tiling = combo->metadata.tiling; + switch (modifier) { + case DRM_FORMAT_MOD_LINEAR: + bo->tiling = I915_TILING_NONE; + break; + case I915_FORMAT_MOD_X_TILED: + bo->tiling = I915_TILING_X; + break; + case I915_FORMAT_MOD_Y_TILED: + bo->tiling = I915_TILING_Y; + break; + } stride = drv_stride_from_format(format, width, 0); @@ -382,6 +374,35 @@ static int i915_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32 return 0; } +static int i915_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint64_t use_flags) +{ + struct combination *combo; + + combo = drv_get_combination(bo->drv, format, use_flags); + if (!combo) + return -EINVAL; + + return i915_bo_create_for_modifier(bo, width, height, format, combo->metadata.modifier); +} + +static int i915_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint32_t height, + uint32_t format, const uint64_t *modifiers, uint32_t count) +{ + static const uint64_t modifier_order[] = { + I915_FORMAT_MOD_Y_TILED, + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, + }; + uint64_t modifier; + + modifier = drv_pick_modifier(modifiers, count, modifier_order, ARRAY_SIZE(modifier_order)); + + bo->format_modifiers[0] = modifier; + + return i915_bo_create_for_modifier(bo, width, height, format, modifier); +} + static void i915_close(struct driver *drv) { free(drv->priv); @@ -412,18 +433,18 @@ static int i915_bo_import(struct bo *bo, struct drv_import_fd_data *data) return 0; } -static void *i915_bo_map(struct bo *bo, struct map_info *data, size_t plane, int prot) +static void *i915_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags) { int ret; void *addr; - struct drm_i915_gem_set_domain set_domain; - memset(&set_domain, 0, sizeof(set_domain)); - set_domain.handle = bo->handles[0].u32; if (bo->tiling == I915_TILING_NONE) { struct drm_i915_gem_mmap gem_map; memset(&gem_map, 0, sizeof(gem_map)); + if ((bo->use_flags & BO_USE_SCANOUT) && !(bo->use_flags & BO_USE_RENDERSCRIPT)) + gem_map.flags = I915_MMAP_WC; + gem_map.handle = bo->handles[0].u32; gem_map.offset = 0; gem_map.size = bo->total_size; @@ -435,9 +456,6 @@ static void *i915_bo_map(struct bo *bo, struct map_info *data, size_t plane, int } addr = (void *)(uintptr_t)gem_map.addr_ptr; - set_domain.read_domains = I915_GEM_DOMAIN_CPU; - set_domain.write_domain = I915_GEM_DOMAIN_CPU; - } else { struct drm_i915_gem_mmap_gtt gem_map; memset(&gem_map, 0, sizeof(gem_map)); @@ -450,9 +468,8 @@ static void *i915_bo_map(struct bo *bo, struct map_info *data, size_t plane, int return MAP_FAILED; } - addr = mmap(0, bo->total_size, prot, MAP_SHARED, bo->drv->fd, gem_map.offset); - set_domain.read_domains = I915_GEM_DOMAIN_GTT; - set_domain.write_domain = I915_GEM_DOMAIN_GTT; + addr = mmap(0, bo->total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, + gem_map.offset); } if (addr == MAP_FAILED) { @@ -460,53 +477,82 @@ static void *i915_bo_map(struct bo *bo, struct map_info *data, size_t plane, int return addr; } + vma->length = bo->total_size; + return addr; +} + +static int i915_bo_invalidate(struct bo *bo, struct mapping *mapping) +{ + int ret; + struct drm_i915_gem_set_domain set_domain; + + memset(&set_domain, 0, sizeof(set_domain)); + set_domain.handle = bo->handles[0].u32; + if (bo->tiling == I915_TILING_NONE) { + set_domain.read_domains = I915_GEM_DOMAIN_CPU; + if (mapping->vma->map_flags & BO_MAP_WRITE) + set_domain.write_domain = I915_GEM_DOMAIN_CPU; + } else { + set_domain.read_domains = I915_GEM_DOMAIN_GTT; + if (mapping->vma->map_flags & BO_MAP_WRITE) + set_domain.write_domain = I915_GEM_DOMAIN_GTT; + } + ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain); if (ret) { - fprintf(stderr, "drv: DRM_IOCTL_I915_GEM_SET_DOMAIN failed\n"); - return MAP_FAILED; + fprintf(stderr, "drv: DRM_IOCTL_I915_GEM_SET_DOMAIN with %d\n", ret); + return ret; } - data->length = bo->total_size; - return addr; + return 0; } -static int i915_bo_unmap(struct bo *bo, struct map_info *data) +static int i915_bo_flush(struct bo *bo, struct mapping *mapping) { struct i915_device *i915 = bo->drv->priv; if (!i915->has_llc && bo->tiling == I915_TILING_NONE) - i915_clflush(data->addr, data->length); + i915_clflush(mapping->vma->addr, mapping->vma->length); - return munmap(data->addr, data->length); + return 0; } -static uint32_t i915_resolve_format(uint32_t format, uint64_t usage) +static uint32_t i915_resolve_format(uint32_t format, uint64_t use_flags) { switch (format) { case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED: /* KBL camera subsystem requires NV12. */ - if (usage & (BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE)) + if (use_flags & (BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE)) return DRM_FORMAT_NV12; /*HACK: See b/28671744 */ return DRM_FORMAT_XBGR8888; case DRM_FORMAT_FLEX_YCbCr_420_888: - /* KBL camera subsystem requires NV12. */ - if (usage & (BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE)) - return DRM_FORMAT_NV12; - return DRM_FORMAT_YVU420; + /* + * KBL camera subsystem requires NV12. Our other use cases + * don't care: + * - Hardware video supports NV12, + * - USB Camera HALv3 supports NV12, + * - USB Camera HALv1 doesn't use this format. + * Moreover, NV12 is preferred for video, due to overlay + * support on SKL+. + */ + return DRM_FORMAT_NV12; default: return format; } } -struct backend backend_i915 = { +const struct backend backend_i915 = { .name = "i915", .init = i915_init, .close = i915_close, .bo_create = i915_bo_create, + .bo_create_with_modifiers = i915_bo_create_with_modifiers, .bo_destroy = drv_gem_bo_destroy, .bo_import = i915_bo_import, .bo_map = i915_bo_map, - .bo_unmap = i915_bo_unmap, + .bo_unmap = drv_bo_munmap, + .bo_invalidate = i915_bo_invalidate, + .bo_flush = i915_bo_flush, .resolve_format = i915_resolve_format, }; diff --git a/chromium/third_party/minigbm/src/marvell.c b/chromium/third_party/minigbm/src/marvell.c index 8114ac7d7ae..c0b600b5c29 100644 --- a/chromium/third_party/minigbm/src/marvell.c +++ b/chromium/third_party/minigbm/src/marvell.c @@ -14,23 +14,21 @@ static const uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMA static int marvell_init(struct driver *drv) { - int ret; - ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &LINEAR_METADATA, BO_USE_RENDER_MASK); - if (ret) - return ret; + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &LINEAR_METADATA, BO_USE_RENDER_MASK); return drv_add_linear_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats)); } -struct backend backend_marvell = { +const struct backend backend_marvell = { .name = "marvell", .init = marvell_init, .bo_create = drv_dumb_bo_create, .bo_destroy = drv_dumb_bo_destroy, .bo_import = drv_prime_bo_import, .bo_map = drv_dumb_bo_map, + .bo_unmap = drv_bo_munmap, }; #endif diff --git a/chromium/third_party/minigbm/src/mediatek.c b/chromium/third_party/minigbm/src/mediatek.c index a4879d9d623..761400486cd 100644 --- a/chromium/third_party/minigbm/src/mediatek.c +++ b/chromium/third_party/minigbm/src/mediatek.c @@ -32,22 +32,17 @@ static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_YVU static int mediatek_init(struct driver *drv) { - int ret; - ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &LINEAR_METADATA, BO_USE_RENDER_MASK); - if (ret) - return ret; + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &LINEAR_METADATA, BO_USE_RENDER_MASK); - ret = drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), - &LINEAR_METADATA, BO_USE_TEXTURE_MASK); - if (ret) - return ret; + drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), + &LINEAR_METADATA, BO_USE_TEXTURE_MASK); return drv_modify_linear_combinations(drv); } static int mediatek_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, - uint32_t flags) + uint64_t use_flags) { int ret; size_t plane; @@ -78,7 +73,7 @@ static int mediatek_bo_create(struct bo *bo, uint32_t width, uint32_t height, ui return 0; } -static void *mediatek_bo_map(struct bo *bo, struct map_info *data, size_t plane, int prot) +static void *mediatek_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags) { int ret; struct drm_mtk_gem_map_off gem_map; @@ -93,37 +88,55 @@ static void *mediatek_bo_map(struct bo *bo, struct map_info *data, size_t plane, return MAP_FAILED; } - void *addr = mmap(0, bo->total_size, prot, MAP_SHARED, bo->drv->fd, gem_map.offset); + void *addr = mmap(0, bo->total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, + gem_map.offset); - data->length = bo->total_size; + vma->length = bo->total_size; - if (bo->flags & BO_USE_RENDERSCRIPT) { + if (bo->use_flags & BO_USE_RENDERSCRIPT) { priv = calloc(1, sizeof(*priv)); priv->cached_addr = calloc(1, bo->total_size); priv->gem_addr = addr; - memcpy(priv->cached_addr, priv->gem_addr, bo->total_size); - data->priv = priv; + vma->priv = priv; addr = priv->cached_addr; } return addr; } -static int mediatek_bo_unmap(struct bo *bo, struct map_info *data) +static int mediatek_bo_unmap(struct bo *bo, struct vma *vma) { - if (data->priv) { - struct mediatek_private_map_data *priv = data->priv; - memcpy(priv->gem_addr, priv->cached_addr, bo->total_size); - data->addr = priv->gem_addr; + if (vma->priv) { + struct mediatek_private_map_data *priv = vma->priv; + vma->addr = priv->gem_addr; free(priv->cached_addr); free(priv); - data->priv = NULL; + vma->priv = NULL; + } + + return munmap(vma->addr, vma->length); +} + +static int mediatek_bo_invalidate(struct bo *bo, struct mapping *mapping) +{ + if (mapping->vma->priv) { + struct mediatek_private_map_data *priv = mapping->vma->priv; + memcpy(priv->cached_addr, priv->gem_addr, bo->total_size); } - return munmap(data->addr, data->length); + return 0; +} + +static int mediatek_bo_flush(struct bo *bo, struct mapping *mapping) +{ + struct mediatek_private_map_data *priv = mapping->vma->priv; + if (priv && (mapping->vma->map_flags & BO_MAP_WRITE)) + memcpy(priv->gem_addr, priv->cached_addr, bo->total_size); + + return 0; } -static uint32_t mediatek_resolve_format(uint32_t format, uint64_t usage) +static uint32_t mediatek_resolve_format(uint32_t format, uint64_t use_flags) { switch (format) { case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED: @@ -136,7 +149,7 @@ static uint32_t mediatek_resolve_format(uint32_t format, uint64_t usage) } } -struct backend backend_mediatek = { +const struct backend backend_mediatek = { .name = "mediatek", .init = mediatek_init, .bo_create = mediatek_bo_create, @@ -144,6 +157,8 @@ struct backend backend_mediatek = { .bo_import = drv_prime_bo_import, .bo_map = mediatek_bo_map, .bo_unmap = mediatek_bo_unmap, + .bo_invalidate = mediatek_bo_invalidate, + .bo_flush = mediatek_bo_flush, .resolve_format = mediatek_resolve_format, }; diff --git a/chromium/third_party/minigbm/src/msm.c b/chromium/third_party/minigbm/src/msm.c new file mode 100644 index 00000000000..4240c63cbf9 --- /dev/null +++ b/chromium/third_party/minigbm/src/msm.c @@ -0,0 +1,33 @@ +/* + * Copyright 2018 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifdef DRV_MSM + +#include "drv_priv.h" +#include "helpers.h" +#include "util.h" + +static const uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888 }; + +static int msm_init(struct driver *drv) +{ + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &LINEAR_METADATA, BO_USE_RENDER_MASK); + + return drv_modify_linear_combinations(drv); +} + +const struct backend backend_msm = { + .name = "msm", + .init = msm_init, + .bo_create = drv_dumb_bo_create, + .bo_destroy = drv_dumb_bo_destroy, + .bo_import = drv_prime_bo_import, + .bo_map = drv_dumb_bo_map, + .bo_unmap = drv_bo_munmap, +}; + +#endif /* DRV_MSM */ diff --git a/chromium/third_party/minigbm/src/nouveau.c b/chromium/third_party/minigbm/src/nouveau.c index 7cdab3a040d..d0f25d4129d 100644 --- a/chromium/third_party/minigbm/src/nouveau.c +++ b/chromium/third_party/minigbm/src/nouveau.c @@ -12,20 +12,18 @@ static const uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMA static int nouveau_init(struct driver *drv) { - int ret; - ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &LINEAR_METADATA, BO_USE_RENDER_MASK); - if (ret) - return ret; + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &LINEAR_METADATA, BO_USE_RENDER_MASK); return drv_modify_linear_combinations(drv); } -struct backend backend_nouveau = { +const struct backend backend_nouveau = { .name = "nouveau", .init = nouveau_init, .bo_create = drv_dumb_bo_create, .bo_destroy = drv_dumb_bo_destroy, .bo_import = drv_prime_bo_import, .bo_map = drv_dumb_bo_map, + .bo_unmap = drv_bo_munmap, }; diff --git a/chromium/third_party/minigbm/src/presubmit.sh b/chromium/third_party/minigbm/src/presubmit.sh index 6d55f2a5e70..1cfc59cee0b 100755 --- a/chromium/third_party/minigbm/src/presubmit.sh +++ b/chromium/third_party/minigbm/src/presubmit.sh @@ -4,5 +4,5 @@ # found in the LICENSE file. find \ '(' -name '*.[ch]' -or -name '*.cc' ')' \ - -not -name 'gbm.h' \ + -not -name 'gbm.h' -not -name 'virgl_hw.h' \ -exec clang-format -style=file -i {} + diff --git a/chromium/third_party/minigbm/src/radeon.c b/chromium/third_party/minigbm/src/radeon.c index baf42ed994f..68445c16372 100644 --- a/chromium/third_party/minigbm/src/radeon.c +++ b/chromium/third_party/minigbm/src/radeon.c @@ -12,20 +12,18 @@ static const uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMA static int radeon_init(struct driver *drv) { - int ret; - ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &LINEAR_METADATA, BO_USE_RENDER_MASK); - if (ret) - return ret; + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &LINEAR_METADATA, BO_USE_RENDER_MASK); return drv_modify_linear_combinations(drv); } -struct backend backend_radeon = { +const struct backend backend_radeon = { .name = "radeon", .init = radeon_init, .bo_create = drv_dumb_bo_create, .bo_destroy = drv_dumb_bo_destroy, .bo_import = drv_prime_bo_import, .bo_map = drv_dumb_bo_map, + .bo_unmap = drv_bo_munmap, }; diff --git a/chromium/third_party/minigbm/src/rockchip.c b/chromium/third_party/minigbm/src/rockchip.c index fbc9ed5c0de..ac17dbda107 100644 --- a/chromium/third_party/minigbm/src/rockchip.c +++ b/chromium/third_party/minigbm/src/rockchip.c @@ -76,31 +76,28 @@ static int afbc_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, u static int rockchip_add_kms_item(struct driver *drv, const struct kms_item *item) { - int ret; uint32_t i, j; - uint64_t flags; + uint64_t use_flags; struct combination *combo; struct format_metadata metadata; - for (i = 0; i < drv->backend->combos.size; i++) { - combo = &drv->backend->combos.data[i]; + for (i = 0; i < drv_array_size(drv->combos); i++) { + combo = (struct combination *)drv_array_at_idx(drv->combos, 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; + use_flags = BO_USE_RENDERING | BO_USE_SCANOUT | BO_USE_TEXTURE; metadata.modifier = item->modifier; metadata.tiling = 0; metadata.priority = 2; for (j = 0; j < ARRAY_SIZE(texture_source_formats); j++) { if (item->format == texture_source_formats[j]) - flags &= ~BO_USE_RENDERING; + use_flags &= ~BO_USE_RENDERING; } - ret = drv_add_combination(drv, item[i].format, &metadata, flags); - if (ret) - return ret; + drv_add_combinations(drv, &item->format, 1, &metadata, use_flags); } else { - combo->usage |= item->usage; + combo->use_flags |= item->use_flags; } } } @@ -111,47 +108,52 @@ static int rockchip_add_kms_item(struct driver *drv, const struct kms_item *item static int rockchip_init(struct driver *drv) { int ret; - uint32_t i, num_items; - struct kms_item *items; + uint32_t i; + struct drv_array *kms_items; struct format_metadata metadata; metadata.tiling = 0; metadata.priority = 1; - metadata.modifier = DRM_FORMAT_MOD_NONE; + metadata.modifier = DRM_FORMAT_MOD_LINEAR; - ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &metadata, BO_USE_RENDER_MASK); - if (ret) - return ret; + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &metadata, BO_USE_RENDER_MASK); - ret = drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), - &metadata, BO_USE_TEXTURE_MASK); - if (ret) - return ret; + drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), + &metadata, BO_USE_TEXTURE_MASK); 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) + /* Camera ISP supports only NV12 output. */ + drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata, + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); + /* + * R8 format is used for Android's HAL_PIXEL_FORMAT_BLOB and is used for JPEG snapshots + * from camera. + */ + drv_modify_combination(drv, DRM_FORMAT_R8, &metadata, + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); + + kms_items = drv_query_kms(drv); + if (!kms_items) return 0; - for (i = 0; i < num_items; i++) { - ret = rockchip_add_kms_item(drv, &items[i]); + for (i = 0; i < drv_array_size(kms_items); i++) { + ret = rockchip_add_kms_item(drv, (struct kms_item *)drv_array_at_idx(kms_items, i)); if (ret) { - free(items); + drv_array_destroy(kms_items); return ret; } } - free(items); + drv_array_destroy(kms_items); return 0; } static bool has_modifier(const uint64_t *list, uint32_t count, uint64_t modifier) { uint32_t i; - for (i = 0; i < count; i++) if (list[i] == modifier) return true; @@ -182,7 +184,7 @@ static int rockchip_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint * pick that */ afbc_bo_from_format(bo, width, height, format); } else { - if (!has_modifier(modifiers, count, DRM_FORMAT_MOD_NONE)) { + if (!has_modifier(modifiers, count, DRM_FORMAT_MOD_LINEAR)) { errno = EINVAL; fprintf(stderr, "no usable modifier found\n"); return -1; @@ -222,15 +224,14 @@ static int rockchip_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint } static int rockchip_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, - uint32_t flags) + uint64_t use_flags) { - uint64_t modifiers[] = { DRM_FORMAT_MOD_NONE }; - + uint64_t modifiers[] = { DRM_FORMAT_MOD_LINEAR }; return rockchip_bo_create_with_modifiers(bo, width, height, format, modifiers, ARRAY_SIZE(modifiers)); } -static void *rockchip_bo_map(struct bo *bo, struct map_info *data, size_t plane, int prot) +static void *rockchip_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags) { int ret; struct drm_rockchip_gem_map_off gem_map; @@ -250,40 +251,61 @@ static void *rockchip_bo_map(struct bo *bo, struct map_info *data, size_t plane, return MAP_FAILED; } - void *addr = mmap(0, bo->total_size, prot, MAP_SHARED, bo->drv->fd, gem_map.offset); + void *addr = mmap(0, bo->total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, + gem_map.offset); - data->length = bo->total_size; + vma->length = bo->total_size; - if (bo->flags & BO_USE_RENDERSCRIPT) { + if (bo->use_flags & BO_USE_RENDERSCRIPT) { priv = calloc(1, sizeof(*priv)); priv->cached_addr = calloc(1, bo->total_size); priv->gem_addr = addr; - memcpy(priv->cached_addr, priv->gem_addr, bo->total_size); - data->priv = priv; + vma->priv = priv; addr = priv->cached_addr; } return addr; } -static int rockchip_bo_unmap(struct bo *bo, struct map_info *data) +static int rockchip_bo_unmap(struct bo *bo, struct vma *vma) { - if (data->priv) { - struct rockchip_private_map_data *priv = data->priv; - memcpy(priv->gem_addr, priv->cached_addr, bo->total_size); - data->addr = priv->gem_addr; + if (vma->priv) { + struct rockchip_private_map_data *priv = vma->priv; + vma->addr = priv->gem_addr; free(priv->cached_addr); free(priv); - data->priv = NULL; + vma->priv = NULL; } - return munmap(data->addr, data->length); + return munmap(vma->addr, vma->length); +} + +static int rockchip_bo_invalidate(struct bo *bo, struct mapping *mapping) +{ + if (mapping->vma->priv) { + struct rockchip_private_map_data *priv = mapping->vma->priv; + memcpy(priv->cached_addr, priv->gem_addr, bo->total_size); + } + + return 0; +} + +static int rockchip_bo_flush(struct bo *bo, struct mapping *mapping) +{ + struct rockchip_private_map_data *priv = mapping->vma->priv; + if (priv && (mapping->vma->map_flags & BO_MAP_WRITE)) + memcpy(priv->gem_addr, priv->cached_addr, bo->total_size); + + return 0; } -static uint32_t rockchip_resolve_format(uint32_t format, uint64_t usage) +static uint32_t rockchip_resolve_format(uint32_t format, uint64_t use_flags) { switch (format) { case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED: + /* Camera subsystem requires NV12. */ + if (use_flags & (BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE)) + return DRM_FORMAT_NV12; /*HACK: See b/28671744 */ return DRM_FORMAT_XBGR8888; case DRM_FORMAT_FLEX_YCbCr_420_888: @@ -293,7 +315,7 @@ static uint32_t rockchip_resolve_format(uint32_t format, uint64_t usage) } } -struct backend backend_rockchip = { +const struct backend backend_rockchip = { .name = "rockchip", .init = rockchip_init, .bo_create = rockchip_bo_create, @@ -302,6 +324,8 @@ struct backend backend_rockchip = { .bo_import = drv_prime_bo_import, .bo_map = rockchip_bo_map, .bo_unmap = rockchip_bo_unmap, + .bo_invalidate = rockchip_bo_invalidate, + .bo_flush = rockchip_bo_flush, .resolve_format = rockchip_resolve_format, }; diff --git a/chromium/third_party/minigbm/src/tegra.c b/chromium/third_party/minigbm/src/tegra.c index 7ddeb96873c..f0651d79f0f 100644 --- a/chromium/third_party/minigbm/src/tegra.c +++ b/chromium/third_party/minigbm/src/tegra.c @@ -44,7 +44,6 @@ enum tegra_map_type { struct tegra_private_map_data { void *tiled; void *untiled; - int prot; }; static const uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888 }; @@ -180,33 +179,28 @@ static void transfer_tiled_memory(struct bo *bo, uint8_t *tiled, uint8_t *untile static int tegra_init(struct driver *drv) { - int ret; struct format_metadata metadata; - uint64_t flags = BO_USE_RENDER_MASK; + uint64_t use_flags = BO_USE_RENDER_MASK; metadata.tiling = NV_MEM_KIND_PITCH; metadata.priority = 1; - metadata.modifier = DRM_FORMAT_MOD_NONE; + metadata.modifier = DRM_FORMAT_MOD_LINEAR; - ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &metadata, flags); - if (ret) - return ret; + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &metadata, use_flags); 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; + use_flags &= ~BO_USE_SW_WRITE_OFTEN; + use_flags &= ~BO_USE_SW_READ_OFTEN; + use_flags &= ~BO_USE_LINEAR; metadata.tiling = NV_MEM_KIND_C32_2CRA; metadata.priority = 2; - ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &metadata, flags); - if (ret) - return ret; + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &metadata, use_flags); drv_modify_combination(drv, DRM_FORMAT_XRGB8888, &metadata, BO_USE_SCANOUT); drv_modify_combination(drv, DRM_FORMAT_ARGB8888, &metadata, BO_USE_SCANOUT); @@ -214,14 +208,15 @@ static int tegra_init(struct driver *drv) } static int tegra_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, - uint32_t flags) + uint64_t use_flags) { uint32_t size, stride, block_height_log2 = 0; enum nv_mem_kind kind = NV_MEM_KIND_PITCH; struct drm_tegra_gem_create gem_create; int ret; - if (flags & (BO_USE_CURSOR | BO_USE_LINEAR | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN)) + if (use_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, @@ -265,7 +260,42 @@ static int tegra_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint3 return 0; } -static void *tegra_bo_map(struct bo *bo, struct map_info *data, size_t plane, int prot) +static int tegra_bo_import(struct bo *bo, struct drv_import_fd_data *data) +{ + int ret; + struct drm_tegra_gem_get_tiling gem_get_tiling; + + ret = drv_prime_bo_import(bo, data); + if (ret) + return ret; + + /* TODO(gsingh): export modifiers and get rid of backdoor tiling. */ + memset(&gem_get_tiling, 0, sizeof(gem_get_tiling)); + gem_get_tiling.handle = bo->handles[0].u32; + + ret = drmIoctl(bo->drv->fd, DRM_IOCTL_TEGRA_GEM_GET_TILING, &gem_get_tiling); + if (ret) { + drv_gem_bo_destroy(bo); + return ret; + } + + /* NOTE(djmk): we only know about one tiled format, so if our drmIoctl call tells us we are + tiled, assume it is this format (NV_MEM_KIND_C32_2CRA) otherwise linear (KIND_PITCH). */ + if (gem_get_tiling.mode == DRM_TEGRA_GEM_TILING_MODE_PITCH) { + bo->tiling = NV_MEM_KIND_PITCH; + } else if (gem_get_tiling.mode == DRM_TEGRA_GEM_TILING_MODE_BLOCK) { + bo->tiling = NV_MEM_KIND_C32_2CRA; + } else { + fprintf(stderr, "tegra_bo_import: unknown tile format %d", gem_get_tiling.mode); + drv_gem_bo_destroy(bo); + assert(0); + } + + bo->format_modifiers[0] = fourcc_mod_code(NV, bo->tiling); + return 0; +} + +static void *tegra_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags) { int ret; struct drm_tegra_gem_mmap gem_map; @@ -280,14 +310,14 @@ static void *tegra_bo_map(struct bo *bo, struct map_info *data, size_t plane, in return MAP_FAILED; } - void *addr = mmap(0, bo->total_size, prot, MAP_SHARED, bo->drv->fd, gem_map.offset); - data->length = bo->total_size; + void *addr = mmap(0, bo->total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, + gem_map.offset); + vma->length = bo->total_size; if ((bo->tiling & 0xFF) == NV_MEM_KIND_C32_2CRA && addr != MAP_FAILED) { priv = calloc(1, sizeof(*priv)); priv->untiled = calloc(1, bo->total_size); priv->tiled = addr; - priv->prot = prot; - data->priv = priv; + vma->priv = priv; transfer_tiled_memory(bo, priv->tiled, priv->untiled, TEGRA_READ_TILED_BUFFER); addr = priv->untiled; } @@ -295,58 +325,30 @@ static void *tegra_bo_map(struct bo *bo, struct map_info *data, size_t plane, in return addr; } -static int tegra_bo_unmap(struct bo *bo, struct map_info *data) +static int tegra_bo_unmap(struct bo *bo, struct vma *vma) { - if (data->priv) { - struct tegra_private_map_data *priv = data->priv; - if (priv->prot & PROT_WRITE) - transfer_tiled_memory(bo, priv->tiled, priv->untiled, - TEGRA_WRITE_TILED_BUFFER); - data->addr = priv->tiled; + if (vma->priv) { + struct tegra_private_map_data *priv = vma->priv; + vma->addr = priv->tiled; free(priv->untiled); free(priv); - data->priv = NULL; + vma->priv = NULL; } - return munmap(data->addr, data->length); + return munmap(vma->addr, vma->length); } -static int tegra_bo_import(struct bo *bo, struct drv_import_fd_data *data) +static int tegra_bo_flush(struct bo *bo, struct mapping *mapping) { - int ret; - struct drm_tegra_gem_get_tiling gem_get_tiling; - - ret = drv_prime_bo_import(bo, data); - if (ret) - return ret; - - /* TODO(gsingh): export modifiers and get rid of backdoor tiling. */ - memset(&gem_get_tiling, 0, sizeof(gem_get_tiling)); - gem_get_tiling.handle = bo->handles[0].u32; - - ret = drmIoctl(bo->drv->fd, DRM_IOCTL_TEGRA_GEM_GET_TILING, &gem_get_tiling); - if (ret) { - drv_gem_bo_destroy(bo); - return ret; - } + struct tegra_private_map_data *priv = mapping->vma->priv; - /* NOTE(djmk): we only know about one tiled format, so if our drmIoctl call tells us we are - tiled, assume it is this format (NV_MEM_KIND_C32_2CRA) otherwise linear (KIND_PITCH). */ - if (gem_get_tiling.mode == DRM_TEGRA_GEM_TILING_MODE_PITCH) { - bo->tiling = NV_MEM_KIND_PITCH; - } else if (gem_get_tiling.mode == DRM_TEGRA_GEM_TILING_MODE_BLOCK) { - bo->tiling = NV_MEM_KIND_C32_2CRA; - } else { - fprintf(stderr, "tegra_bo_import: unknown tile format %d", gem_get_tiling.mode); - drv_gem_bo_destroy(bo); - assert(0); - } + if (priv && (mapping->vma->map_flags & BO_MAP_WRITE)) + transfer_tiled_memory(bo, priv->tiled, priv->untiled, TEGRA_WRITE_TILED_BUFFER); - bo->format_modifiers[0] = fourcc_mod_code(NV, bo->tiling); return 0; } -struct backend backend_tegra = { +const struct backend backend_tegra = { .name = "tegra", .init = tegra_init, .bo_create = tegra_bo_create, @@ -354,6 +356,7 @@ struct backend backend_tegra = { .bo_import = tegra_bo_import, .bo_map = tegra_bo_map, .bo_unmap = tegra_bo_unmap, + .bo_flush = tegra_bo_flush, }; #endif diff --git a/chromium/third_party/minigbm/src/udl.c b/chromium/third_party/minigbm/src/udl.c index eb15fbeb461..12dc9677a4f 100644 --- a/chromium/third_party/minigbm/src/udl.c +++ b/chromium/third_party/minigbm/src/udl.c @@ -12,20 +12,18 @@ static const uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMA static int udl_init(struct driver *drv) { - int ret; - ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &LINEAR_METADATA, BO_USE_RENDER_MASK); - if (ret) - return ret; + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &LINEAR_METADATA, BO_USE_RENDER_MASK); return drv_modify_linear_combinations(drv); } -struct backend backend_udl = { +const struct backend backend_udl = { .name = "udl", .init = udl_init, .bo_create = drv_dumb_bo_create, .bo_destroy = drv_dumb_bo_destroy, .bo_import = drv_prime_bo_import, .bo_map = drv_dumb_bo_map, + .bo_unmap = drv_bo_munmap, }; diff --git a/chromium/third_party/minigbm/src/vc4.c b/chromium/third_party/minigbm/src/vc4.c index c797bd9529c..79602474ae0 100644 --- a/chromium/third_party/minigbm/src/vc4.c +++ b/chromium/third_party/minigbm/src/vc4.c @@ -21,17 +21,14 @@ static const uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMA static int vc4_init(struct driver *drv) { - int ret; - ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &LINEAR_METADATA, BO_USE_RENDER_MASK); - if (ret) - return ret; + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &LINEAR_METADATA, BO_USE_RENDER_MASK); return drv_modify_linear_combinations(drv); } static int vc4_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, - uint32_t flags) + uint64_t use_flags) { int ret; size_t plane; @@ -62,7 +59,7 @@ static int vc4_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_ return 0; } -static void *vc4_bo_map(struct bo *bo, struct map_info *data, size_t plane, int prot) +static void *vc4_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags) { int ret; struct drm_vc4_mmap_bo bo_map; @@ -76,17 +73,19 @@ static void *vc4_bo_map(struct bo *bo, struct map_info *data, size_t plane, int return MAP_FAILED; } - data->length = bo->total_size; - return mmap(0, bo->total_size, prot, MAP_SHARED, bo->drv->fd, bo_map.offset); + vma->length = bo->total_size; + return mmap(0, bo->total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, + bo_map.offset); } -struct backend backend_vc4 = { +const struct backend backend_vc4 = { .name = "vc4", .init = vc4_init, .bo_create = vc4_bo_create, .bo_import = drv_prime_bo_import, .bo_destroy = drv_gem_bo_destroy, .bo_map = vc4_bo_map, + .bo_unmap = drv_bo_munmap, }; #endif diff --git a/chromium/third_party/minigbm/src/vgem.c b/chromium/third_party/minigbm/src/vgem.c index 4e6eefb7375..5380b7858a8 100644 --- a/chromium/third_party/minigbm/src/vgem.c +++ b/chromium/third_party/minigbm/src/vgem.c @@ -20,22 +20,17 @@ static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_YVU static int vgem_init(struct driver *drv) { - int ret; - ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &LINEAR_METADATA, BO_USE_RENDER_MASK); - if (ret) - return ret; + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &LINEAR_METADATA, BO_USE_RENDER_MASK); - ret = drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), - &LINEAR_METADATA, BO_USE_TEXTURE_MASK); - if (ret) - return ret; + drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), + &LINEAR_METADATA, BO_USE_TEXTURE_MASK); return drv_modify_linear_combinations(drv); } static int vgem_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, - uint32_t flags) + uint64_t flags) { width = ALIGN(width, MESA_LLVMPIPE_TILE_SIZE); height = ALIGN(height, MESA_LLVMPIPE_TILE_SIZE); @@ -47,7 +42,7 @@ static int vgem_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32 return drv_dumb_bo_create(bo, width, height, format, flags); } -static uint32_t vgem_resolve_format(uint32_t format, uint64_t usage) +static uint32_t vgem_resolve_format(uint32_t format, uint64_t flags) { switch (format) { case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED: @@ -60,12 +55,13 @@ static uint32_t vgem_resolve_format(uint32_t format, uint64_t usage) } } -struct backend backend_vgem = { +const struct backend backend_vgem = { .name = "vgem", .init = vgem_init, .bo_create = vgem_bo_create, .bo_destroy = drv_dumb_bo_destroy, .bo_import = drv_prime_bo_import, .bo_map = drv_dumb_bo_map, + .bo_unmap = drv_bo_munmap, .resolve_format = vgem_resolve_format, }; diff --git a/chromium/third_party/minigbm/src/virgl_hw.h b/chromium/third_party/minigbm/src/virgl_hw.h new file mode 100644 index 00000000000..e3c56db2ac6 --- /dev/null +++ b/chromium/third_party/minigbm/src/virgl_hw.h @@ -0,0 +1,286 @@ +/* + * Copyright 2014, 2015 Red Hat. + * + * 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 + * on 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 above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * 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 AUTHOR(S) AND/OR THEIR 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. + */ +#ifndef VIRGL_HW_H +#define VIRGL_HW_H + +struct virgl_box { + uint32_t x, y, z; + uint32_t w, h, d; +}; + +/* formats known by the HW device - based on gallium subset */ +enum virgl_formats { + VIRGL_FORMAT_B8G8R8A8_UNORM = 1, + VIRGL_FORMAT_B8G8R8X8_UNORM = 2, + VIRGL_FORMAT_A8R8G8B8_UNORM = 3, + VIRGL_FORMAT_X8R8G8B8_UNORM = 4, + VIRGL_FORMAT_B5G5R5A1_UNORM = 5, + VIRGL_FORMAT_B4G4R4A4_UNORM = 6, + VIRGL_FORMAT_B5G6R5_UNORM = 7, + VIRGL_FORMAT_L8_UNORM = 9, /**< ubyte luminance */ + VIRGL_FORMAT_A8_UNORM = 10, /**< ubyte alpha */ + VIRGL_FORMAT_L8A8_UNORM = 12, /**< ubyte alpha, luminance */ + VIRGL_FORMAT_L16_UNORM = 13, /**< ushort luminance */ + + VIRGL_FORMAT_Z16_UNORM = 16, + VIRGL_FORMAT_Z32_UNORM = 17, + VIRGL_FORMAT_Z32_FLOAT = 18, + VIRGL_FORMAT_Z24_UNORM_S8_UINT = 19, + VIRGL_FORMAT_S8_UINT_Z24_UNORM = 20, + VIRGL_FORMAT_Z24X8_UNORM = 21, + VIRGL_FORMAT_S8_UINT = 23, /**< ubyte stencil */ + + VIRGL_FORMAT_R32_FLOAT = 28, + VIRGL_FORMAT_R32G32_FLOAT = 29, + VIRGL_FORMAT_R32G32B32_FLOAT = 30, + VIRGL_FORMAT_R32G32B32A32_FLOAT = 31, + + VIRGL_FORMAT_R16_UNORM = 48, + VIRGL_FORMAT_R16G16_UNORM = 49, + + VIRGL_FORMAT_R16G16B16A16_UNORM = 51, + + VIRGL_FORMAT_R16_SNORM = 56, + VIRGL_FORMAT_R16G16_SNORM = 57, + VIRGL_FORMAT_R16G16B16A16_SNORM = 59, + + VIRGL_FORMAT_R8_UNORM = 64, + VIRGL_FORMAT_R8G8_UNORM = 65, + + VIRGL_FORMAT_R8G8B8A8_UNORM = 67, + + VIRGL_FORMAT_R8_SNORM = 74, + VIRGL_FORMAT_R8G8_SNORM = 75, + VIRGL_FORMAT_R8G8B8_SNORM = 76, + VIRGL_FORMAT_R8G8B8A8_SNORM = 77, + + VIRGL_FORMAT_R16_FLOAT = 91, + VIRGL_FORMAT_R16G16_FLOAT = 92, + VIRGL_FORMAT_R16G16B16_FLOAT = 93, + VIRGL_FORMAT_R16G16B16A16_FLOAT = 94, + + VIRGL_FORMAT_L8_SRGB = 95, + VIRGL_FORMAT_L8A8_SRGB = 96, + VIRGL_FORMAT_B8G8R8A8_SRGB = 100, + VIRGL_FORMAT_B8G8R8X8_SRGB = 101, + + /* compressed formats */ + VIRGL_FORMAT_DXT1_RGB = 105, + VIRGL_FORMAT_DXT1_RGBA = 106, + VIRGL_FORMAT_DXT3_RGBA = 107, + VIRGL_FORMAT_DXT5_RGBA = 108, + + /* sRGB, compressed */ + VIRGL_FORMAT_DXT1_SRGB = 109, + VIRGL_FORMAT_DXT1_SRGBA = 110, + VIRGL_FORMAT_DXT3_SRGBA = 111, + VIRGL_FORMAT_DXT5_SRGBA = 112, + + /* rgtc compressed */ + VIRGL_FORMAT_RGTC1_UNORM = 113, + VIRGL_FORMAT_RGTC1_SNORM = 114, + VIRGL_FORMAT_RGTC2_UNORM = 115, + VIRGL_FORMAT_RGTC2_SNORM = 116, + + VIRGL_FORMAT_A8B8G8R8_UNORM = 121, + VIRGL_FORMAT_B5G5R5X1_UNORM = 122, + VIRGL_FORMAT_R11G11B10_FLOAT = 124, + VIRGL_FORMAT_R9G9B9E5_FLOAT = 125, + VIRGL_FORMAT_Z32_FLOAT_S8X24_UINT = 126, + + VIRGL_FORMAT_B10G10R10A2_UNORM = 131, + VIRGL_FORMAT_R8G8B8X8_UNORM = 134, + VIRGL_FORMAT_B4G4R4X4_UNORM = 135, + VIRGL_FORMAT_B2G3R3_UNORM = 139, + + VIRGL_FORMAT_L16A16_UNORM = 140, + VIRGL_FORMAT_A16_UNORM = 141, + + VIRGL_FORMAT_A8_SNORM = 147, + VIRGL_FORMAT_L8_SNORM = 148, + VIRGL_FORMAT_L8A8_SNORM = 149, + + VIRGL_FORMAT_A16_SNORM = 151, + VIRGL_FORMAT_L16_SNORM = 152, + VIRGL_FORMAT_L16A16_SNORM = 153, + + VIRGL_FORMAT_A16_FLOAT = 155, + VIRGL_FORMAT_L16_FLOAT = 156, + VIRGL_FORMAT_L16A16_FLOAT = 157, + + VIRGL_FORMAT_A32_FLOAT = 159, + VIRGL_FORMAT_L32_FLOAT = 160, + VIRGL_FORMAT_L32A32_FLOAT = 161, + + VIRGL_FORMAT_R8_UINT = 177, + VIRGL_FORMAT_R8G8_UINT = 178, + VIRGL_FORMAT_R8G8B8_UINT = 179, + VIRGL_FORMAT_R8G8B8A8_UINT = 180, + + VIRGL_FORMAT_R8_SINT = 181, + VIRGL_FORMAT_R8G8_SINT = 182, + VIRGL_FORMAT_R8G8B8_SINT = 183, + VIRGL_FORMAT_R8G8B8A8_SINT = 184, + + VIRGL_FORMAT_R16_UINT = 185, + VIRGL_FORMAT_R16G16_UINT = 186, + VIRGL_FORMAT_R16G16B16_UINT = 187, + VIRGL_FORMAT_R16G16B16A16_UINT = 188, + + VIRGL_FORMAT_R16_SINT = 189, + VIRGL_FORMAT_R16G16_SINT = 190, + VIRGL_FORMAT_R16G16B16_SINT = 191, + VIRGL_FORMAT_R16G16B16A16_SINT = 192, + VIRGL_FORMAT_R32_UINT = 193, + VIRGL_FORMAT_R32G32_UINT = 194, + VIRGL_FORMAT_R32G32B32_UINT = 195, + VIRGL_FORMAT_R32G32B32A32_UINT = 196, + + VIRGL_FORMAT_R32_SINT = 197, + VIRGL_FORMAT_R32G32_SINT = 198, + VIRGL_FORMAT_R32G32B32_SINT = 199, + VIRGL_FORMAT_R32G32B32A32_SINT = 200, + + VIRGL_FORMAT_A8_UINT = 201, + VIRGL_FORMAT_L8_UINT = 203, + VIRGL_FORMAT_L8A8_UINT = 204, + + VIRGL_FORMAT_A8_SINT = 205, + VIRGL_FORMAT_L8_SINT = 207, + VIRGL_FORMAT_L8A8_SINT = 208, + + VIRGL_FORMAT_A16_UINT = 209, + VIRGL_FORMAT_L16_UINT = 211, + VIRGL_FORMAT_L16A16_UINT = 212, + + VIRGL_FORMAT_A16_SINT = 213, + VIRGL_FORMAT_L16_SINT = 215, + VIRGL_FORMAT_L16A16_SINT = 216, + + VIRGL_FORMAT_A32_UINT = 217, + VIRGL_FORMAT_L32_UINT = 219, + VIRGL_FORMAT_L32A32_UINT = 220, + + VIRGL_FORMAT_A32_SINT = 221, + VIRGL_FORMAT_L32_SINT = 223, + VIRGL_FORMAT_L32A32_SINT = 224, + + VIRGL_FORMAT_B10G10R10A2_UINT = 225, + VIRGL_FORMAT_R8G8B8X8_SNORM = 229, + + VIRGL_FORMAT_R8G8B8X8_SRGB = 230, + + VIRGL_FORMAT_B10G10R10X2_UNORM = 233, + VIRGL_FORMAT_R16G16B16X16_UNORM = 234, + VIRGL_FORMAT_R16G16B16X16_SNORM = 235, + VIRGL_FORMAT_MAX, +}; + +#define VIRGL_BIND_DEPTH_STENCIL (1 << 0) +#define VIRGL_BIND_RENDER_TARGET (1 << 1) +#define VIRGL_BIND_SAMPLER_VIEW (1 << 3) +#define VIRGL_BIND_VERTEX_BUFFER (1 << 4) +#define VIRGL_BIND_INDEX_BUFFER (1 << 5) +#define VIRGL_BIND_CONSTANT_BUFFER (1 << 6) +#define VIRGL_BIND_DISPLAY_TARGET (1 << 7) +#define VIRGL_BIND_STREAM_OUTPUT (1 << 11) +#define VIRGL_BIND_CURSOR (1 << 16) +#define VIRGL_BIND_CUSTOM (1 << 17) +#define VIRGL_BIND_SCANOUT (1 << 18) + +struct virgl_caps_bool_set1 { + unsigned indep_blend_enable:1; + unsigned indep_blend_func:1; + unsigned cube_map_array:1; + unsigned shader_stencil_export:1; + unsigned conditional_render:1; + unsigned start_instance:1; + unsigned primitive_restart:1; + unsigned blend_eq_sep:1; + unsigned instanceid:1; + unsigned vertex_element_instance_divisor:1; + unsigned seamless_cube_map:1; + unsigned occlusion_query:1; + unsigned timer_query:1; + unsigned streamout_pause_resume:1; + unsigned texture_multisample:1; + unsigned fragment_coord_conventions:1; + unsigned depth_clip_disable:1; + unsigned seamless_cube_map_per_texture:1; + unsigned ubo:1; + unsigned color_clamping:1; /* not in GL 3.1 core profile */ + unsigned poly_stipple:1; /* not in GL 3.1 core profile */ + unsigned mirror_clamp:1; + unsigned texture_query_lod:1; +}; + +/* endless expansion capabilites - current gallium has 252 formats */ +struct virgl_supported_format_mask { + uint32_t bitmask[16]; +}; +/* capabilities set 2 - version 1 - 32-bit and float values */ +struct virgl_caps_v1 { + uint32_t max_version; + struct virgl_supported_format_mask sampler; + struct virgl_supported_format_mask render; + struct virgl_supported_format_mask depthstencil; + struct virgl_supported_format_mask vertexbuffer; + struct virgl_caps_bool_set1 bset; + uint32_t glsl_level; + uint32_t max_texture_array_layers; + uint32_t max_streamout_buffers; + uint32_t max_dual_source_render_targets; + uint32_t max_render_targets; + uint32_t max_samples; + uint32_t prim_mask; + uint32_t max_tbo_size; + uint32_t max_uniform_blocks; + uint32_t max_viewports; + uint32_t max_texture_gather_components; +}; + +union virgl_caps { + uint32_t max_version; + struct virgl_caps_v1 v1; +}; + +enum virgl_errors { + VIRGL_ERROR_NONE, + VIRGL_ERROR_UNKNOWN, + VIRGL_ERROR_UNKNOWN_RESOURCE_FORMAT, +}; + +enum virgl_ctx_errors { + VIRGL_ERROR_CTX_NONE, + VIRGL_ERROR_CTX_UNKNOWN, + VIRGL_ERROR_CTX_ILLEGAL_SHADER, + VIRGL_ERROR_CTX_ILLEGAL_HANDLE, + VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, + VIRGL_ERROR_CTX_ILLEGAL_SURFACE, + VIRGL_ERROR_CTX_ILLEGAL_VERTEX_FORMAT, + VIRGL_ERROR_CTX_ILLEGAL_CMD_BUFFER, +}; + + +#define VIRGL_RESOURCE_Y_0_TOP (1 << 0) +#endif diff --git a/chromium/third_party/minigbm/src/virtio_gpu.c b/chromium/third_party/minigbm/src/virtio_dumb.c index fe580cd15b6..b6dc3cbf9f4 100644 --- a/chromium/third_party/minigbm/src/virtio_gpu.c +++ b/chromium/third_party/minigbm/src/virtio_dumb.c @@ -4,6 +4,8 @@ * found in the LICENSE file. */ +#ifndef DRV_VIRGL + #include "drv_priv.h" #include "helpers.h" #include "util.h" @@ -20,22 +22,17 @@ static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_YVU static int virtio_gpu_init(struct driver *drv) { - int ret; - ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &LINEAR_METADATA, BO_USE_RENDER_MASK); - if (ret) - return ret; + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &LINEAR_METADATA, BO_USE_RENDER_MASK); - ret = drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), - &LINEAR_METADATA, BO_USE_TEXTURE_MASK); - if (ret) - return ret; + drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), + &LINEAR_METADATA, BO_USE_TEXTURE_MASK); return drv_modify_linear_combinations(drv); } static int virtio_gpu_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, - uint32_t flags) + uint64_t use_flags) { width = ALIGN(width, MESA_LLVMPIPE_TILE_SIZE); height = ALIGN(height, MESA_LLVMPIPE_TILE_SIZE); @@ -44,10 +41,10 @@ static int virtio_gpu_bo_create(struct bo *bo, uint32_t width, uint32_t height, if (bo->format == DRM_FORMAT_YVU420_ANDROID) height = bo->height; - return drv_dumb_bo_create(bo, width, height, format, flags); + return drv_dumb_bo_create(bo, width, height, format, use_flags); } -static uint32_t virtio_gpu_resolve_format(uint32_t format, uint64_t usage) +static uint32_t virtio_gpu_resolve_format(uint32_t format, uint64_t use_flags) { switch (format) { case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED: @@ -60,12 +57,15 @@ static uint32_t virtio_gpu_resolve_format(uint32_t format, uint64_t usage) } } -struct backend backend_virtio_gpu = { +const struct backend backend_virtio_gpu = { .name = "virtio_gpu", .init = virtio_gpu_init, .bo_create = virtio_gpu_bo_create, .bo_destroy = drv_dumb_bo_destroy, .bo_import = drv_prime_bo_import, .bo_map = drv_dumb_bo_map, + .bo_unmap = drv_bo_munmap, .resolve_format = virtio_gpu_resolve_format, }; + +#endif diff --git a/chromium/third_party/minigbm/src/virtio_virgl.c b/chromium/third_party/minigbm/src/virtio_virgl.c new file mode 100644 index 00000000000..b33677bacda --- /dev/null +++ b/chromium/third_party/minigbm/src/virtio_virgl.c @@ -0,0 +1,219 @@ +/* + * Copyright 2017 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifdef DRV_VIRGL + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> +#include <sys/mman.h> +#include <virtgpu_drm.h> +#include <xf86drm.h> + +#include "drv_priv.h" +#include "helpers.h" +#include "util.h" +#include "virgl_hw.h" + +#define PAGE_SIZE 0x1000 +#define PIPE_TEXTURE_2D 2 + +static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, + DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, + DRM_FORMAT_XRGB8888 }; + +static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_RG88 }; + +static uint32_t translate_format(uint32_t drm_fourcc, uint32_t plane) +{ + switch (drm_fourcc) { + case DRM_FORMAT_XRGB8888: + return VIRGL_FORMAT_B8G8R8X8_UNORM; + case DRM_FORMAT_ARGB8888: + return VIRGL_FORMAT_B8G8R8A8_UNORM; + case DRM_FORMAT_XBGR8888: + return VIRGL_FORMAT_R8G8B8X8_UNORM; + case DRM_FORMAT_ABGR8888: + return VIRGL_FORMAT_R8G8B8A8_UNORM; + case DRM_FORMAT_RGB565: + return VIRGL_FORMAT_B5G6R5_UNORM; + case DRM_FORMAT_R8: + return VIRGL_FORMAT_R8_UNORM; + case DRM_FORMAT_RG88: + return VIRGL_FORMAT_R8G8_UNORM; + default: + return 0; + } +} + +static int virtio_gpu_init(struct driver *drv) +{ + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &LINEAR_METADATA, BO_USE_RENDER_MASK); + + drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), + &LINEAR_METADATA, BO_USE_TEXTURE_MASK); + + return drv_modify_linear_combinations(drv); +} + +static int virtio_gpu_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint64_t use_flags) +{ + int ret; + ssize_t plane; + ssize_t num_planes = drv_num_planes_from_format(format); + uint32_t stride0; + + for (plane = 0; plane < num_planes; plane++) { + uint32_t stride = drv_stride_from_format(format, width, plane); + uint32_t size = drv_size_from_format(format, stride, height, plane); + uint32_t res_format = translate_format(format, plane); + struct drm_virtgpu_resource_create res_create; + + memset(&res_create, 0, sizeof(res_create)); + size = ALIGN(size, PAGE_SIZE); + /* + * Setting the target is intended to ensure this resource gets bound as a 2D + * texture in the host renderer's GL state. All of these resource properties are + * sent unchanged by the kernel to the host, which in turn sends them unchanged to + * virglrenderer. When virglrenderer makes a resource, it will convert the target + * enum to the equivalent one in GL and then bind the resource to that target. + */ + res_create.target = PIPE_TEXTURE_2D; + res_create.format = res_format; + res_create.bind = VIRGL_BIND_RENDER_TARGET; + res_create.width = width; + res_create.height = height; + res_create.depth = 1; + res_create.array_size = 1; + res_create.last_level = 0; + res_create.nr_samples = 0; + res_create.stride = stride; + res_create.size = size; + + ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_RESOURCE_CREATE, &res_create); + if (ret) { + fprintf(stderr, "drv: DRM_IOCTL_VIRTGPU_RESOURCE_CREATE failed with %s\n", + strerror(errno)); + goto fail; + } + + bo->handles[plane].u32 = res_create.bo_handle; + } + + stride0 = drv_stride_from_format(format, width, 0); + drv_bo_from_format(bo, stride0, height, format); + + for (plane = 0; plane < num_planes; plane++) + bo->offsets[plane] = 0; + + return 0; + +fail: + for (plane--; plane >= 0; plane--) { + struct drm_gem_close gem_close; + memset(&gem_close, 0, sizeof(gem_close)); + gem_close.handle = bo->handles[plane].u32; + drmIoctl(bo->drv->fd, DRM_IOCTL_GEM_CLOSE, &gem_close); + } + + return ret; +} + +static void *virgl_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags) +{ + int ret; + struct drm_virtgpu_map gem_map; + + memset(&gem_map, 0, sizeof(gem_map)); + gem_map.handle = bo->handles[0].u32; + + ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_MAP, &gem_map); + if (ret) { + fprintf(stderr, "drv: DRM_IOCTL_VIRTGPU_MAP failed with %s\n", strerror(errno)); + return MAP_FAILED; + } + + return mmap(0, bo->total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, + gem_map.offset); +} + +static int virtio_gpu_bo_invalidate(struct bo *bo, struct mapping *mapping) +{ + int ret; + struct drm_virtgpu_3d_transfer_from_host xfer; + + memset(&xfer, 0, sizeof(xfer)); + xfer.bo_handle = mapping->vma->handle; + xfer.box.x = mapping->rect.x; + xfer.box.y = mapping->rect.y; + xfer.box.w = mapping->rect.width; + xfer.box.h = mapping->rect.height; + xfer.box.d = 1; + + ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST, &xfer); + if (ret) { + fprintf(stderr, "drv: DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST failed with %s\n", + strerror(errno)); + return ret; + } + + return 0; +} + +static int virtio_gpu_bo_flush(struct bo *bo, struct mapping *mapping) +{ + int ret; + struct drm_virtgpu_3d_transfer_to_host xfer; + + if (!(mapping->vma->map_flags & BO_MAP_WRITE)) + return 0; + + memset(&xfer, 0, sizeof(xfer)); + xfer.bo_handle = mapping->vma->handle; + xfer.box.x = mapping->rect.x; + xfer.box.y = mapping->rect.y; + xfer.box.w = mapping->rect.width; + xfer.box.h = mapping->rect.height; + xfer.box.d = 1; + + ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_TRANSFER_TO_HOST, &xfer); + if (ret) { + fprintf(stderr, "drv: DRM_IOCTL_VIRTGPU_TRANSFER_TO_HOST failed with %s\n", + strerror(errno)); + return ret; + } + + return 0; +} + +static uint32_t virtio_gpu_resolve_format(uint32_t format, uint64_t use_flags) +{ + switch (format) { + case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED: + /*HACK: See b/28671744 */ + return DRM_FORMAT_XBGR8888; + default: + return format; + } +} + +struct backend backend_virtio_gpu = { + .name = "virtio_gpu", + .init = virtio_gpu_init, + .bo_create = virtio_gpu_bo_create, + .bo_destroy = drv_gem_bo_destroy, + .bo_import = drv_prime_bo_import, + .bo_map = virgl_bo_map, + .bo_unmap = drv_bo_munmap, + .bo_invalidate = virtio_gpu_bo_invalidate, + .bo_flush = virtio_gpu_bo_flush, + .resolve_format = virtio_gpu_resolve_format, +}; + +#endif |