From 69c8992400c0ca2ef737635f8c3d4c2bfd508da4 Mon Sep 17 00:00:00 2001 From: kuantung Date: Thu, 8 Jun 2017 11:59:40 -0700 Subject: [PATCH 001/269] Initial empty repository From 29ed8d2c3eb6f0cef4e4a4f7392f961379325fdf Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Tue, 31 Oct 2017 10:39:43 -0700 Subject: [PATCH 002/269] minigbm: remove cirrus driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nobody should use this anymore -- virtio_gpu is the future. BUG=chromium:710629 TEST=Should already be unused, CQ will check Change-Id: I8e4184875140e0c74d886c20fcf2d1c9664fa44c Reviewed-on: https://chromium-review.googlesource.com/747983 Commit-Ready: Gurchetan Singh Tested-by: Gurchetan Singh Reviewed-by: Stéphane Marchesin --- cirrus.c | 33 --------------------------------- drv.c | 3 +-- i915.c | 6 +++--- 3 files changed, 4 insertions(+), 38 deletions(-) delete mode 100644 cirrus.c diff --git a/cirrus.c b/cirrus.c deleted file mode 100644 index d92bab4..0000000 --- a/cirrus.c +++ /dev/null @@ -1,33 +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, - .bo_unmap = drv_bo_munmap, -}; diff --git a/drv.c b/drv.c index 3ccf16e..683bea7 100644 --- a/drv.c +++ b/drv.c @@ -23,7 +23,6 @@ #ifdef DRV_AMDGPU extern struct backend backend_amdgpu; #endif -extern struct backend backend_cirrus; extern struct backend backend_evdi; #ifdef DRV_EXYNOS extern struct backend backend_exynos; @@ -69,7 +68,7 @@ static struct backend *drv_get_backend(int fd) #ifdef DRV_AMDGPU &backend_amdgpu, #endif - &backend_cirrus, &backend_evdi, + &backend_evdi, #ifdef DRV_EXYNOS &backend_exynos, #endif diff --git a/i915.c b/i915.c index e25b068..5869a59 100644 --- a/i915.c +++ b/i915.c @@ -20,10 +20,10 @@ #define I915_CACHELINE_SIZE 64 #define I915_CACHELINE_MASK (I915_CACHELINE_SIZE - 1) -static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB1555, - DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB565, +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_XRGB1555, DRM_FORMAT_XRGB2101010, DRM_FORMAT_XRGB8888 }; static const uint32_t tileable_texture_source_formats[] = { DRM_FORMAT_GR88, DRM_FORMAT_NV12, From a29bf678db525bf0e11105f9f660fbb4e062750d Mon Sep 17 00:00:00 2001 From: Alec Thilenius Date: Tue, 31 Oct 2017 14:39:16 -0600 Subject: [PATCH 003/269] minigbm: amdgpu: Add ABGR8888 to supported render target formats Added DRM_FORMAT_ABGR8888 to the list of supported render_target_formats. BUG=b:67707215 TEST=teravest@chromium.org confirmed that this worked. Change-Id: I0d1578f9a0ca98f28ebf60d396d1dbdae25435f1 Reviewed-on: https://chromium-review.googlesource.com/747723 Commit-Ready: Alec Thilenius Tested-by: Alec Thilenius Reviewed-by: Gurchetan Singh --- amdgpu.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/amdgpu.c b/amdgpu.c index 1a1f9fc..d91006d 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -41,8 +41,9 @@ enum { }; // clang-format on -const static uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB565, - DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888 }; +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_GR88, DRM_FORMAT_R8, DRM_FORMAT_NV21, DRM_FORMAT_NV12 }; From 3e9d3830dce97cb0146b9f6e0f4942253f39ca69 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Tue, 31 Oct 2017 10:36:25 -0700 Subject: [PATCH 004/269] minigbm: re-const-ify driver backends MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit minigbm driver creation needs to be re-entrant (see CL:674528). Let's re-constify to make this behavior explicit. BUG=none TEST=emerge-eve {minigbm, arc-cros-gralloc} Change-Id: I037966199d4aa6de60432127e10fea1fb602694b Reviewed-on: https://chromium-review.googlesource.com/758142 Commit-Ready: Gurchetan Singh Tested-by: Gurchetan Singh Reviewed-by: Stéphane Marchesin --- amdgpu.c | 2 +- drv.c | 34 +++++++++++++++++----------------- drv_priv.h | 2 +- evdi.c | 2 +- exynos.c | 2 +- gma500.c | 2 +- i915.c | 2 +- marvell.c | 2 +- mediatek.c | 2 +- nouveau.c | 2 +- radeon.c | 2 +- rockchip.c | 2 +- tegra.c | 2 +- udl.c | 2 +- vc4.c | 2 +- vgem.c | 2 +- virtio_gpu.c | 2 +- 17 files changed, 33 insertions(+), 33 deletions(-) diff --git a/amdgpu.c b/amdgpu.c index d91006d..aa3d599 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -426,7 +426,7 @@ static uint32_t amdgpu_resolve_format(uint32_t format, uint64_t use_flags) } } -struct backend backend_amdgpu = { +const struct backend backend_amdgpu = { .name = "amdgpu", .init = amdgpu_init, .close = amdgpu_close, diff --git a/drv.c b/drv.c index 683bea7..99ec561 100644 --- a/drv.c +++ b/drv.c @@ -21,40 +21,40 @@ #include "util.h" #ifdef DRV_AMDGPU -extern struct backend backend_amdgpu; +extern const struct backend backend_amdgpu; #endif -extern struct backend backend_evdi; +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; +extern const 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 -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; @@ -64,7 +64,7 @@ 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 diff --git a/drv_priv.h b/drv_priv.h index 3399cc7..09007de 100644 --- a/drv_priv.h +++ b/drv_priv.h @@ -57,7 +57,7 @@ struct combinations { struct driver { int fd; - struct backend *backend; + const struct backend *backend; void *priv; void *buffer_table; void *map_table; diff --git a/evdi.c b/evdi.c index 829d6ea..3bac658 100644 --- a/evdi.c +++ b/evdi.c @@ -21,7 +21,7 @@ static int evdi_init(struct driver *drv) 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, diff --git a/exynos.c b/exynos.c index 963f030..455416e 100644 --- a/exynos.c +++ b/exynos.c @@ -105,7 +105,7 @@ static int exynos_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint * 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, diff --git a/gma500.c b/gma500.c index c3f3c12..bcc3bc8 100644 --- a/gma500.c +++ b/gma500.c @@ -21,7 +21,7 @@ static int gma500_init(struct driver *drv) return drv_modify_linear_combinations(drv); } -struct backend backend_gma500 = { +const struct backend backend_gma500 = { .name = "gma500", .init = gma500_init, .bo_create = drv_dumb_bo_create, diff --git a/i915.c b/i915.c index 5869a59..2dc2484 100644 --- a/i915.c +++ b/i915.c @@ -547,7 +547,7 @@ static uint32_t i915_resolve_format(uint32_t format, uint64_t use_flags) } } -struct backend backend_i915 = { +const struct backend backend_i915 = { .name = "i915", .init = i915_init, .close = i915_close, diff --git a/marvell.c b/marvell.c index 455b033..f209139 100644 --- a/marvell.c +++ b/marvell.c @@ -24,7 +24,7 @@ static int marvell_init(struct driver *drv) 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, diff --git a/mediatek.c b/mediatek.c index 1a1061c..e902d3b 100644 --- a/mediatek.c +++ b/mediatek.c @@ -145,7 +145,7 @@ static uint32_t mediatek_resolve_format(uint32_t format, uint64_t use_flags) } } -struct backend backend_mediatek = { +const struct backend backend_mediatek = { .name = "mediatek", .init = mediatek_init, .bo_create = mediatek_bo_create, diff --git a/nouveau.c b/nouveau.c index e8a02e3..4efbda2 100644 --- a/nouveau.c +++ b/nouveau.c @@ -21,7 +21,7 @@ static int nouveau_init(struct driver *drv) 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, diff --git a/radeon.c b/radeon.c index 3af0be1..84b01c5 100644 --- a/radeon.c +++ b/radeon.c @@ -21,7 +21,7 @@ static int radeon_init(struct driver *drv) 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, diff --git a/rockchip.c b/rockchip.c index 5fb0be4..2678f77 100644 --- a/rockchip.c +++ b/rockchip.c @@ -314,7 +314,7 @@ static uint32_t rockchip_resolve_format(uint32_t format, uint64_t use_flags) } } -struct backend backend_rockchip = { +const struct backend backend_rockchip = { .name = "rockchip", .init = rockchip_init, .bo_create = rockchip_bo_create, diff --git a/tegra.c b/tegra.c index d16a182..7842ea2 100644 --- a/tegra.c +++ b/tegra.c @@ -353,7 +353,7 @@ static int tegra_bo_flush(struct bo *bo, struct map_info *data) return 0; } -struct backend backend_tegra = { +const struct backend backend_tegra = { .name = "tegra", .init = tegra_init, .bo_create = tegra_bo_create, diff --git a/udl.c b/udl.c index dc3c4eb..5ec2307 100644 --- a/udl.c +++ b/udl.c @@ -21,7 +21,7 @@ static int udl_init(struct driver *drv) 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, diff --git a/vc4.c b/vc4.c index 20431d9..4c0ae6f 100644 --- a/vc4.c +++ b/vc4.c @@ -81,7 +81,7 @@ static void *vc4_bo_map(struct bo *bo, struct map_info *data, size_t plane, uint bo_map.offset); } -struct backend backend_vc4 = { +const struct backend backend_vc4 = { .name = "vc4", .init = vc4_init, .bo_create = vc4_bo_create, diff --git a/vgem.c b/vgem.c index 867b439..a4e893b 100644 --- a/vgem.c +++ b/vgem.c @@ -60,7 +60,7 @@ static uint32_t vgem_resolve_format(uint32_t format, uint64_t flags) } } -struct backend backend_vgem = { +const struct backend backend_vgem = { .name = "vgem", .init = vgem_init, .bo_create = vgem_bo_create, diff --git a/virtio_gpu.c b/virtio_gpu.c index 6548e59..447a17d 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -60,7 +60,7 @@ static uint32_t virtio_gpu_resolve_format(uint32_t format, uint64_t use_flags) } } -struct backend backend_virtio_gpu = { +const struct backend backend_virtio_gpu = { .name = "virtio_gpu", .init = virtio_gpu_init, .bo_create = virtio_gpu_bo_create, From 425173a0c8170528f804b2a9bd02b71fa47d754b Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Tue, 7 Nov 2017 17:21:58 -0800 Subject: [PATCH 005/269] minigbm: fix map time assertions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We should assert when the refcount is equal to zero as well. BUG=chromium:764871 TEST=gbmtest passes Change-Id: Iaf8b5bd4bf51472ad7c564341b42a7079b58bd6e Reviewed-on: https://chromium-review.googlesource.com/758143 Commit-Ready: Gurchetan Singh Tested-by: Gurchetan Singh Reviewed-by: Stéphane Marchesin --- drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drv.c b/drv.c index 99ec561..d5d8ec1 100644 --- a/drv.c +++ b/drv.c @@ -458,7 +458,7 @@ int drv_bo_invalidate(struct bo *bo, struct map_info *data) { int ret = 0; assert(data); - assert(data->refcount >= 0); + assert(data->refcount > 0); if (bo->drv->backend->bo_invalidate) ret = bo->drv->backend->bo_invalidate(bo, data); @@ -470,7 +470,7 @@ int drv_bo_flush(struct bo *bo, struct map_info *data) { int ret = 0; assert(data); - assert(data->refcount >= 0); + assert(data->refcount > 0); assert(!(bo->use_flags & BO_USE_PROTECTED)); if (bo->drv->backend->bo_flush) From 47e629b70ddec014c7691a48509ef437c57761bb Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Thu, 2 Nov 2017 14:07:18 -0700 Subject: [PATCH 006/269] minigbm: refactor and rename mapping struct MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since some drivers (AMDGPU, Tegra) may have to do expensive tiling and detiling operations, we should try to take advantage of the access regions passed in by gralloc and gbm. Let's refactor struct map_data so we can separate the actual mapping and access region. Here is the Coccinelle rule used in this change: @@ struct map_info *M; @@ - (M) + M->vma In addition, struct map_data was also renamed to struct mapping. BUG=chromium:764871 TEST= mmap_test -g on Kevin Change-Id: Idb094aa3b5f81e45ce3a2f4fb2d9bf8fba32bf29 Reviewed-on: https://chromium-review.googlesource.com/758144 Commit-Ready: Gurchetan Singh Tested-by: Gurchetan Singh Reviewed-by: Joe Kniss Reviewed-by: Stéphane Marchesin --- amdgpu.c | 4 +- cros_gralloc/cros_gralloc_buffer.cc | 2 +- cros_gralloc/cros_gralloc_buffer.h | 2 +- drv.c | 69 ++++++++++++++++------------- drv.h | 14 +++--- drv_priv.h | 8 ++-- gbm.c | 2 +- helpers.c | 23 +++++----- helpers.h | 6 +-- i915.c | 14 +++--- mediatek.c | 25 ++++++----- rockchip.c | 25 ++++++----- tegra.c | 24 +++++----- vc4.c | 4 +- 14 files changed, 118 insertions(+), 104 deletions(-) diff --git a/amdgpu.c b/amdgpu.c index aa3d599..a874fd1 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -396,7 +396,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, uint32_t map_flags) +static void *amdgpu_bo_map(struct bo *bo, struct mapping *mapping, size_t plane, uint32_t map_flags) { int ret; union drm_amdgpu_gem_mmap gem_map; @@ -410,7 +410,7 @@ static void *amdgpu_bo_map(struct bo *bo, struct map_info *data, size_t plane, u return MAP_FAILED; } - data->length = bo->total_size; + mapping->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); diff --git a/cros_gralloc/cros_gralloc_buffer.cc b/cros_gralloc/cros_gralloc_buffer.cc index fe9c01a..c84e21a 100644 --- a/cros_gralloc/cros_gralloc_buffer.cc +++ b/cros_gralloc/cros_gralloc_buffer.cc @@ -62,7 +62,7 @@ int32_t cros_gralloc_buffer::lock(uint32_t map_flags, uint8_t *addr[DRV_MAX_PLAN if (map_flags) { if (lock_data_[0]) { drv_bo_invalidate(bo_, lock_data_[0]); - vaddr = lock_data_[0]->addr; + vaddr = lock_data_[0]->vma->addr; } else { vaddr = drv_bo_map(bo_, 0, 0, drv_bo_get_width(bo_), drv_bo_get_height(bo_), map_flags, &lock_data_[0], 0); diff --git a/cros_gralloc/cros_gralloc_buffer.h b/cros_gralloc/cros_gralloc_buffer.h index f629199..93ec37f 100644 --- a/cros_gralloc/cros_gralloc_buffer.h +++ b/cros_gralloc/cros_gralloc_buffer.h @@ -38,7 +38,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/drv.c b/drv.c index d5d8ec1..cb54a93 100644 --- a/drv.c +++ b/drv.c @@ -325,7 +325,7 @@ void drv_bo_destroy(struct bo *bo) pthread_mutex_unlock(&drv->driver_lock); if (total == 0) { - assert(drv_map_info_destroy(bo) == 0); + assert(drv_mapping_destroy(bo) == 0); bo->drv->backend->bo_destroy(bo); } @@ -383,12 +383,12 @@ 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 map_flags, struct map_info **map_data, size_t plane) + uint32_t map_flags, struct mapping **map_data, size_t plane) { void *ptr; uint8_t *addr; size_t offset; - struct map_info *data; + struct mapping *mapping; assert(width > 0); assert(height > 0); @@ -401,52 +401,55 @@ void *drv_bo_map(struct bo *bo, uint32_t x, uint32_t y, uint32_t width, uint32_t pthread_mutex_lock(&bo->drv->driver_lock); if (!drmHashLookup(bo->drv->map_table, bo->handles[plane].u32, &ptr)) { - data = (struct map_info *)ptr; + mapping = (struct mapping *)ptr; /* TODO(gsingh): support mapping same buffer with different flags. */ - assert(data->map_flags == map_flags); - data->refcount++; + assert(mapping->vma->map_flags == map_flags); + mapping->vma->refcount++; goto success; } - data = calloc(1, sizeof(*data)); - addr = bo->drv->backend->bo_map(bo, data, plane, map_flags); + mapping = calloc(1, sizeof(*mapping)); + mapping->vma = calloc(1, sizeof(*mapping->vma)); + addr = bo->drv->backend->bo_map(bo, mapping, plane, map_flags); if (addr == MAP_FAILED) { *map_data = NULL; - free(data); + free(mapping->vma); + free(mapping); pthread_mutex_unlock(&bo->drv->driver_lock); return MAP_FAILED; } - data->refcount = 1; - data->addr = addr; - data->handle = bo->handles[plane].u32; - data->map_flags = map_flags; - 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; + drmHashInsert(bo->drv->map_table, bo->handles[plane].u32, (void *)mapping); success: - drv_bo_invalidate(bo, data); - *map_data = data; + drv_bo_invalidate(bo, mapping); + *map_data = mapping; offset = drv_bo_get_plane_stride(bo, plane) * y; offset += drv_stride_from_format(bo->format, x, plane); - addr = (uint8_t *)data->addr; + addr = (uint8_t *)mapping->vma->addr; addr += drv_bo_get_plane_offset(bo, plane) + offset; 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 = drv_bo_flush(bo, data); + int ret = drv_bo_flush(bo, mapping); if (ret) return ret; pthread_mutex_lock(&bo->drv->driver_lock); - if (!--data->refcount) { - ret = bo->drv->backend->bo_unmap(bo, data); - drmHashDelete(bo->drv->map_table, data->handle); - free(data); + if (!--mapping->vma->refcount) { + ret = bo->drv->backend->bo_unmap(bo, mapping); + drmHashDelete(bo->drv->map_table, mapping->vma->handle); + free(mapping->vma); + free(mapping); } pthread_mutex_unlock(&bo->drv->driver_lock); @@ -454,27 +457,31 @@ int drv_bo_unmap(struct bo *bo, struct map_info *data) return ret; } -int drv_bo_invalidate(struct bo *bo, struct map_info *data) +int drv_bo_invalidate(struct bo *bo, struct mapping *mapping) { int ret = 0; - assert(data); - assert(data->refcount > 0); + + assert(mapping); + assert(mapping->vma); + assert(mapping->vma->refcount > 0); if (bo->drv->backend->bo_invalidate) - ret = bo->drv->backend->bo_invalidate(bo, data); + ret = bo->drv->backend->bo_invalidate(bo, mapping); return ret; } -int drv_bo_flush(struct bo *bo, struct map_info *data) +int drv_bo_flush(struct bo *bo, struct mapping *mapping) { int ret = 0; - assert(data); - assert(data->refcount > 0); + + assert(mapping); + assert(mapping->vma); + 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, data); + ret = bo->drv->backend->bo_flush(bo, mapping); return ret; } diff --git a/drv.h b/drv.h index 7abaf79..bfde327 100644 --- a/drv.h +++ b/drv.h @@ -78,7 +78,7 @@ struct drv_import_fd_data { uint64_t use_flags; }; -struct map_info { +struct vma { void *addr; size_t length; uint32_t handle; @@ -87,6 +87,10 @@ struct map_info { void *priv; }; +struct mapping { + struct vma *vma; +}; + struct driver *drv_create(int fd); void drv_destroy(struct driver *drv); @@ -111,13 +115,13 @@ 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 map_flags, struct map_info **map_data, size_t plane); + uint32_t map_flags, struct mapping **map_data, size_t plane); -int drv_bo_unmap(struct bo *bo, struct map_info *data); +int drv_bo_unmap(struct bo *bo, struct mapping *mapping); -int drv_bo_invalidate(struct bo *bo, struct map_info *data); +int drv_bo_invalidate(struct bo *bo, struct mapping *mapping); -int drv_bo_flush(struct bo *bo, struct map_info *data); +int drv_bo_flush(struct bo *bo, struct mapping *mapping); uint32_t drv_bo_get_width(struct bo *bo); diff --git a/drv_priv.h b/drv_priv.h index 09007de..e5b9d55 100644 --- a/drv_priv.h +++ b/drv_priv.h @@ -75,10 +75,10 @@ struct backend { 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, uint32_t map_flags); - int (*bo_unmap)(struct bo *bo, struct map_info *data); - int (*bo_invalidate)(struct bo *bo, struct map_info *data); - int (*bo_flush)(struct bo *bo, struct map_info *data); + void *(*bo_map)(struct bo *bo, struct mapping *mapping, size_t plane, uint32_t map_flags); + int (*bo_unmap)(struct bo *bo, struct mapping *mapping); + 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); }; diff --git a/gbm.c b/gbm.c index a78921c..606b195 100644 --- a/gbm.c +++ b/gbm.c @@ -232,7 +232,7 @@ PUBLIC void *gbm_bo_map(struct gbm_bo *bo, uint32_t x, uint32_t y, uint32_t widt *stride = gbm_bo_get_plane_stride(bo, 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; - return drv_bo_map(bo->bo, x, y, width, height, map_flags, (struct map_info **)map_data, + return drv_bo_map(bo->bo, x, y, width, height, map_flags, (struct mapping **)map_data, plane); } diff --git a/helpers.c b/helpers.c index bdae73d..555fb85 100644 --- a/helpers.c +++ b/helpers.c @@ -309,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, uint32_t map_flags) +void *drv_dumb_bo_map(struct bo *bo, struct mapping *mapping, size_t plane, uint32_t map_flags) { int ret; size_t i; @@ -326,23 +326,23 @@ void *drv_dumb_bo_map(struct bo *bo, struct map_info *data, size_t plane, uint32 for (i = 0; i < bo->num_planes; i++) if (bo->handles[i].u32 == bo->handles[plane].u32) - data->length += bo->sizes[i]; + mapping->vma->length += bo->sizes[i]; - return mmap(0, data->length, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, + return mmap(0, mapping->vma->length, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, map_dumb.offset); } -int drv_bo_munmap(struct bo *bo, struct map_info *data) +int drv_bo_munmap(struct bo *bo, struct mapping *mapping) { - return munmap(data->addr, data->length); + return munmap(mapping->vma->addr, mapping->vma->length); } -int drv_map_info_destroy(struct bo *bo) +int drv_mapping_destroy(struct bo *bo) { int ret; void *ptr; size_t plane; - struct map_info *data; + struct mapping *mapping; /* * This function is called right before the buffer is destroyed. It will free any mappings @@ -351,15 +351,16 @@ int drv_map_info_destroy(struct bo *bo) for (plane = 0; plane < bo->num_planes; plane++) { if (!drmHashLookup(bo->drv->map_table, bo->handles[plane].u32, &ptr)) { - data = (struct map_info *)ptr; - ret = bo->drv->backend->bo_unmap(bo, data); + mapping = (struct mapping *)ptr; + ret = bo->drv->backend->bo_unmap(bo, mapping); if (ret) { fprintf(stderr, "drv: munmap failed"); return ret; } - drmHashDelete(bo->drv->map_table, data->handle); - free(data); + drmHashDelete(bo->drv->map_table, mapping->vma->handle); + free(mapping->vma); + free(mapping); } } diff --git a/helpers.h b/helpers.h index 0e3fd14..cbd8f18 100644 --- a/helpers.h +++ b/helpers.h @@ -17,9 +17,9 @@ int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t 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, uint32_t map_flags); -int drv_bo_munmap(struct bo *bo, struct map_info *data); -int drv_map_info_destroy(struct bo *bo); +void *drv_dumb_bo_map(struct bo *bo, struct mapping *mapping, size_t plane, uint32_t map_flags); +int drv_bo_munmap(struct bo *bo, struct mapping *mapping); +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); diff --git a/i915.c b/i915.c index 2dc2484..965f62d 100644 --- a/i915.c +++ b/i915.c @@ -445,7 +445,7 @@ 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, uint32_t map_flags) +static void *i915_bo_map(struct bo *bo, struct mapping *mapping, size_t plane, uint32_t map_flags) { int ret; void *addr; @@ -489,11 +489,11 @@ static void *i915_bo_map(struct bo *bo, struct map_info *data, size_t plane, uin return addr; } - data->length = bo->total_size; + mapping->vma->length = bo->total_size; return addr; } -static int i915_bo_invalidate(struct bo *bo, struct map_info *data) +static int i915_bo_invalidate(struct bo *bo, struct mapping *mapping) { int ret; struct drm_i915_gem_set_domain set_domain; @@ -502,11 +502,11 @@ static int i915_bo_invalidate(struct bo *bo, struct map_info *data) set_domain.handle = bo->handles[0].u32; if (bo->tiling == I915_TILING_NONE) { set_domain.read_domains = I915_GEM_DOMAIN_CPU; - if (data->map_flags & BO_MAP_WRITE) + 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 (data->map_flags & BO_MAP_WRITE) + if (mapping->vma->map_flags & BO_MAP_WRITE) set_domain.write_domain = I915_GEM_DOMAIN_GTT; } @@ -519,11 +519,11 @@ static int i915_bo_invalidate(struct bo *bo, struct map_info *data) return 0; } -static int i915_bo_flush(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 0; } diff --git a/mediatek.c b/mediatek.c index e902d3b..33f57fd 100644 --- a/mediatek.c +++ b/mediatek.c @@ -78,7 +78,8 @@ 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, uint32_t map_flags) +static void *mediatek_bo_map(struct bo *bo, struct mapping *mapping, size_t plane, + uint32_t map_flags) { int ret; struct drm_mtk_gem_map_off gem_map; @@ -96,37 +97,37 @@ static void *mediatek_bo_map(struct bo *bo, struct map_info *data, size_t plane, 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; + mapping->vma->length = bo->total_size; 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; + mapping->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 mapping *mapping) { - if (data->priv) { - struct mediatek_private_map_data *priv = data->priv; - data->addr = priv->gem_addr; + if (mapping->vma->priv) { + struct mediatek_private_map_data *priv = mapping->vma->priv; + mapping->vma->addr = priv->gem_addr; free(priv->cached_addr); free(priv); - data->priv = NULL; + mapping->vma->priv = NULL; } - return munmap(data->addr, data->length); + return munmap(mapping->vma->addr, mapping->vma->length); } -static int mediatek_bo_flush(struct bo *bo, struct map_info *data) +static int mediatek_bo_flush(struct bo *bo, struct mapping *mapping) { - struct mediatek_private_map_data *priv = data->priv; - if (priv && (data->map_flags & BO_MAP_WRITE)) + 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; diff --git a/rockchip.c b/rockchip.c index 2678f77..5076f1f 100644 --- a/rockchip.c +++ b/rockchip.c @@ -239,7 +239,8 @@ static int rockchip_bo_create(struct bo *bo, uint32_t width, uint32_t height, ui ARRAY_SIZE(modifiers)); } -static void *rockchip_bo_map(struct bo *bo, struct map_info *data, size_t plane, uint32_t map_flags) +static void *rockchip_bo_map(struct bo *bo, struct mapping *mapping, size_t plane, + uint32_t map_flags) { int ret; struct drm_rockchip_gem_map_off gem_map; @@ -262,37 +263,37 @@ static void *rockchip_bo_map(struct bo *bo, struct map_info *data, size_t plane, 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; + mapping->vma->length = bo->total_size; 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; + mapping->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 mapping *mapping) { - if (data->priv) { - struct rockchip_private_map_data *priv = data->priv; - data->addr = priv->gem_addr; + if (mapping->vma->priv) { + struct rockchip_private_map_data *priv = mapping->vma->priv; + mapping->vma->addr = priv->gem_addr; free(priv->cached_addr); free(priv); - data->priv = NULL; + mapping->vma->priv = NULL; } - return munmap(data->addr, data->length); + return munmap(mapping->vma->addr, mapping->vma->length); } -static int rockchip_bo_flush(struct bo *bo, struct map_info *data) +static int rockchip_bo_flush(struct bo *bo, struct mapping *mapping) { - struct rockchip_private_map_data *priv = data->priv; - if (priv && (data->map_flags & BO_MAP_WRITE)) + 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; diff --git a/tegra.c b/tegra.c index 7842ea2..e365593 100644 --- a/tegra.c +++ b/tegra.c @@ -300,7 +300,7 @@ static int tegra_bo_import(struct bo *bo, struct drv_import_fd_data *data) return 0; } -static void *tegra_bo_map(struct bo *bo, struct map_info *data, size_t plane, uint32_t map_flags) +static void *tegra_bo_map(struct bo *bo, struct mapping *mapping, size_t plane, uint32_t map_flags) { int ret; struct drm_tegra_gem_mmap gem_map; @@ -317,12 +317,12 @@ static void *tegra_bo_map(struct bo *bo, struct map_info *data, size_t plane, ui 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; + mapping->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; - data->priv = priv; + mapping->vma->priv = priv; transfer_tiled_memory(bo, priv->tiled, priv->untiled, TEGRA_READ_TILED_BUFFER); addr = priv->untiled; } @@ -330,24 +330,24 @@ static void *tegra_bo_map(struct bo *bo, struct map_info *data, size_t plane, ui return addr; } -static int tegra_bo_unmap(struct bo *bo, struct map_info *data) +static int tegra_bo_unmap(struct bo *bo, struct mapping *mapping) { - if (data->priv) { - struct tegra_private_map_data *priv = data->priv; - data->addr = priv->tiled; + if (mapping->vma->priv) { + struct tegra_private_map_data *priv = mapping->vma->priv; + mapping->vma->addr = priv->tiled; free(priv->untiled); free(priv); - data->priv = NULL; + mapping->vma->priv = NULL; } - return munmap(data->addr, data->length); + return munmap(mapping->vma->addr, mapping->vma->length); } -static int tegra_bo_flush(struct bo *bo, struct map_info *data) +static int tegra_bo_flush(struct bo *bo, struct mapping *mapping) { - struct tegra_private_map_data *priv = data->priv; + struct tegra_private_map_data *priv = mapping->vma->priv; - if (priv && (data->map_flags & BO_MAP_WRITE)) + if (priv && (mapping->vma->map_flags & BO_MAP_WRITE)) transfer_tiled_memory(bo, priv->tiled, priv->untiled, TEGRA_WRITE_TILED_BUFFER); return 0; diff --git a/vc4.c b/vc4.c index 4c0ae6f..cfcc219 100644 --- a/vc4.c +++ b/vc4.c @@ -62,7 +62,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, uint32_t map_flags) +static void *vc4_bo_map(struct bo *bo, struct mapping *mapping, size_t plane, uint32_t map_flags) { int ret; struct drm_vc4_mmap_bo bo_map; @@ -76,7 +76,7 @@ static void *vc4_bo_map(struct bo *bo, struct map_info *data, size_t plane, uint return MAP_FAILED; } - data->length = bo->total_size; + mapping->vma->length = bo->total_size; return mmap(0, bo->total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, bo_map.offset); } From 39f66c0cf95dc64c263feb91b493c49acdbd6c71 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Thu, 2 Nov 2017 16:42:49 -0700 Subject: [PATCH 007/269] minigbm: introduce drv_array MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We want to allow multiple mappings of a single buffer with different map flags. To do this, we'll need some sort of linked list or dynamic array of mappings. We already use dynamic arrays in minigbm, so let's centralize that functionality and use it. BUG=chromium:764871 TEST=emerge-kevin {minigbm, arc-cros-gralloc} Change-Id: I2b391d6e8e690eac6368b1404a806b2bfbbcdf44 Reviewed-on: https://chromium-review.googlesource.com/758145 Commit-Ready: Gurchetan Singh Tested-by: Gurchetan Singh Reviewed-by: Stéphane Marchesin --- helpers.h | 2 +- helpers_array.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++ helpers_array.h | 22 ++++++++++++ 3 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 helpers_array.c create mode 100644 helpers_array.h diff --git a/helpers.h b/helpers.h index cbd8f18..5de7225 100644 --- a/helpers.h +++ b/helpers.h @@ -8,6 +8,7 @@ #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); @@ -35,5 +36,4 @@ struct kms_item *drv_query_kms(struct driver *drv, uint32_t *num_items); 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/helpers_array.c b/helpers_array.c new file mode 100644 index 0000000..20b43e2 --- /dev/null +++ b/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 +#include +#include +#include + +#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/helpers_array.h b/helpers_array.h new file mode 100644 index 0000000..2893976 --- /dev/null +++ b/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); From 0b78e0716b1806806ef2babc870cc19f8a485abe Mon Sep 17 00:00:00 2001 From: Ricky Liang Date: Fri, 10 Nov 2017 09:17:17 +0800 Subject: [PATCH 008/269] minigbm: amdgpu: add supported formats for camera Set the CAMERA_{READ|WRITE} flags for formats that are used by the camera stack. BUG=b:69109002 TEST=Verify that camera works on Kahlee. Change-Id: I4c9aacdc71d3b18188783007f8c88da37ed28dca Reviewed-on: https://chromium-review.googlesource.com/762687 Commit-Ready: Ricky Liang Tested-by: Justin TerAvest Reviewed-by: Gurchetan Singh --- amdgpu.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/amdgpu.c b/amdgpu.c index a874fd1..57d82e5 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -289,6 +289,16 @@ static int amdgpu_init(struct driver *drv) if (ret) return ret; + /* 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); @@ -419,6 +429,12 @@ static void *amdgpu_bo_map(struct bo *bo, struct mapping *mapping, size_t plane, 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: From cfedbcc8d475fca39ac0a0d4bc6e4881937e2875 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Thu, 2 Nov 2017 17:32:00 -0700 Subject: [PATCH 009/269] minigbm: use drv_array for mappings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Let's start allowing multiple mappings of the same buffer when different map flags are passed in. BUG=chromium:764871 TEST=mmap_test -g on Kevin, gbmtest Change-Id: I4eb0b6f4c3572a92001696c2720d5a5f7d9d73a4 Reviewed-on: https://chromium-review.googlesource.com/758146 Commit-Ready: Gurchetan Singh Tested-by: Gurchetan Singh Reviewed-by: Joe Kniss Reviewed-by: Stéphane Marchesin --- drv.c | 65 ++++++++++++++++++++++++++++++------------------------ drv_priv.h | 2 +- helpers.c | 29 +++++++++++++++--------- 3 files changed, 56 insertions(+), 40 deletions(-) diff --git a/drv.c b/drv.c index cb54a93..50d3401 100644 --- a/drv.c +++ b/drv.c @@ -132,8 +132,8 @@ 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. */ @@ -142,20 +142,20 @@ struct driver *drv_create(int fd) drv->combos.data = calloc(drv->combos.allocations, sizeof(struct combination)); if (!drv->combos.data) - goto free_map_table; + goto free_mappings; if (drv->backend->init) { ret = drv->backend->init(drv); if (ret) { free(drv->combos.data); - goto free_map_table; + 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: @@ -173,7 +173,7 @@ void drv_destroy(struct driver *drv) drv->backend->close(drv); drmHashDestroy(drv->buffer_table); - drmHashDestroy(drv->map_table); + drv_array_destroy(drv->mappings); free(drv->combos.data); @@ -385,10 +385,10 @@ 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 map_flags, struct mapping **map_data, size_t plane) { - void *ptr; + uint32_t i; uint8_t *addr; size_t offset; - struct mapping *mapping; + struct mapping mapping; assert(width > 0); assert(height > 0); @@ -398,39 +398,40 @@ void *drv_bo_map(struct bo *bo, uint32_t x, uint32_t y, uint32_t width, uint32_t /* No CPU access for protected buffers. */ assert(!(bo->use_flags & BO_USE_PROTECTED)); + memset(&mapping, 0, sizeof(mapping)); pthread_mutex_lock(&bo->drv->driver_lock); - if (!drmHashLookup(bo->drv->map_table, bo->handles[plane].u32, &ptr)) { - mapping = (struct mapping *)ptr; - /* TODO(gsingh): support mapping same buffer with different flags. */ - assert(mapping->vma->map_flags == map_flags); - mapping->vma->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; + + prior->vma->refcount++; + mapping.vma = prior->vma; goto success; } - mapping = calloc(1, sizeof(*mapping)); - mapping->vma = calloc(1, sizeof(*mapping->vma)); - addr = bo->drv->backend->bo_map(bo, mapping, plane, map_flags); + mapping.vma = calloc(1, sizeof(*mapping.vma)); + addr = bo->drv->backend->bo_map(bo, &mapping, plane, map_flags); if (addr == MAP_FAILED) { *map_data = NULL; - free(mapping->vma); - free(mapping); + free(mapping.vma); pthread_mutex_unlock(&bo->drv->driver_lock); return MAP_FAILED; } - mapping->vma->refcount = 1; - mapping->vma->addr = addr; - mapping->vma->handle = bo->handles[plane].u32; - mapping->vma->map_flags = map_flags; - drmHashInsert(bo->drv->map_table, bo->handles[plane].u32, (void *)mapping); + mapping.vma->refcount = 1; + mapping.vma->addr = addr; + mapping.vma->handle = bo->handles[plane].u32; + mapping.vma->map_flags = map_flags; success: - drv_bo_invalidate(bo, mapping); - *map_data = mapping; + drv_bo_invalidate(bo, &mapping); + *map_data = drv_array_append(bo->drv->mappings, &mapping); offset = drv_bo_get_plane_stride(bo, plane) * y; offset += drv_stride_from_format(bo->format, x, plane); - addr = (uint8_t *)mapping->vma->addr; + addr = (uint8_t *)mapping.vma->addr; addr += drv_bo_get_plane_offset(bo, plane) + offset; pthread_mutex_unlock(&bo->drv->driver_lock); @@ -439,6 +440,7 @@ void *drv_bo_map(struct bo *bo, uint32_t x, uint32_t y, uint32_t width, uint32_t int drv_bo_unmap(struct bo *bo, struct mapping *mapping) { + uint32_t i; int ret = drv_bo_flush(bo, mapping); if (ret) return ret; @@ -447,9 +449,14 @@ int drv_bo_unmap(struct bo *bo, struct mapping *mapping) if (!--mapping->vma->refcount) { ret = bo->drv->backend->bo_unmap(bo, mapping); - drmHashDelete(bo->drv->map_table, mapping->vma->handle); free(mapping->vma); - free(mapping); + } + + 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; + } } pthread_mutex_unlock(&bo->drv->driver_lock); diff --git a/drv_priv.h b/drv_priv.h index e5b9d55..dceeeb7 100644 --- a/drv_priv.h +++ b/drv_priv.h @@ -60,7 +60,7 @@ struct driver { const struct backend *backend; void *priv; void *buffer_table; - void *map_table; + struct drv_array *mappings; struct combinations combos; pthread_mutex_t driver_lock; }; diff --git a/helpers.c b/helpers.c index 555fb85..d861b9c 100644 --- a/helpers.c +++ b/helpers.c @@ -340,27 +340,36 @@ int drv_bo_munmap(struct bo *bo, struct mapping *mapping) int drv_mapping_destroy(struct bo *bo) { int ret; - void *ptr; 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++) { - if (!drmHashLookup(bo->drv->map_table, bo->handles[plane].u32, &ptr)) { - mapping = (struct mapping *)ptr; - ret = bo->drv->backend->bo_unmap(bo, mapping); - if (ret) { - fprintf(stderr, "drv: munmap failed"); - return ret; + 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; } - drmHashDelete(bo->drv->map_table, mapping->vma->handle); - free(mapping->vma); - free(mapping); + if (!--mapping->vma->refcount) { + ret = bo->drv->backend->bo_unmap(bo, mapping); + 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); } } From ee43c301c21976fb82538261c4e4288ffc754777 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Tue, 14 Nov 2017 18:20:27 -0800 Subject: [PATCH 010/269] minigbm: use struct vma for (*bo_map)/(*bo_unmap) callbacks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This sets better expectations for what we expect from the backends. BUG=chromium:764871 TEST=mmap_test Change-Id: I7fb815b58fae8e9fbd73bf7c0263c7db44488844 Reviewed-on: https://chromium-review.googlesource.com/770519 Commit-Ready: Gurchetan Singh Tested-by: Gurchetan Singh Reviewed-by: Joe Kniss Reviewed-by: Stéphane Marchesin --- amdgpu.c | 4 ++-- drv.c | 4 ++-- drv_priv.h | 4 ++-- helpers.c | 12 ++++++------ helpers.h | 4 ++-- i915.c | 8 +++++--- mediatek.c | 19 +++++++++---------- rockchip.c | 19 +++++++++---------- tegra.c | 18 +++++++++--------- vc4.c | 4 ++-- 10 files changed, 48 insertions(+), 48 deletions(-) diff --git a/amdgpu.c b/amdgpu.c index 57d82e5..4a3eb7b 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -406,7 +406,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 mapping *mapping, size_t plane, uint32_t map_flags) +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; @@ -420,7 +420,7 @@ static void *amdgpu_bo_map(struct bo *bo, struct mapping *mapping, size_t plane, return MAP_FAILED; } - mapping->vma->length = bo->total_size; + 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); diff --git a/drv.c b/drv.c index 50d3401..cd8251f 100644 --- a/drv.c +++ b/drv.c @@ -413,7 +413,7 @@ void *drv_bo_map(struct bo *bo, uint32_t x, uint32_t y, uint32_t width, uint32_t } mapping.vma = calloc(1, sizeof(*mapping.vma)); - addr = bo->drv->backend->bo_map(bo, &mapping, plane, map_flags); + addr = bo->drv->backend->bo_map(bo, mapping.vma, plane, map_flags); if (addr == MAP_FAILED) { *map_data = NULL; free(mapping.vma); @@ -448,7 +448,7 @@ int drv_bo_unmap(struct bo *bo, struct mapping *mapping) pthread_mutex_lock(&bo->drv->driver_lock); if (!--mapping->vma->refcount) { - ret = bo->drv->backend->bo_unmap(bo, mapping); + ret = bo->drv->backend->bo_unmap(bo, mapping->vma); free(mapping->vma); } diff --git a/drv_priv.h b/drv_priv.h index dceeeb7..048b9a3 100644 --- a/drv_priv.h +++ b/drv_priv.h @@ -75,8 +75,8 @@ struct backend { 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 mapping *mapping, size_t plane, uint32_t map_flags); - int (*bo_unmap)(struct bo *bo, struct mapping *mapping); + 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); diff --git a/helpers.c b/helpers.c index d861b9c..9a33804 100644 --- a/helpers.c +++ b/helpers.c @@ -309,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 mapping *mapping, size_t plane, uint32_t map_flags) +void *drv_dumb_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags) { int ret; size_t i; @@ -326,15 +326,15 @@ void *drv_dumb_bo_map(struct bo *bo, struct mapping *mapping, size_t plane, uint for (i = 0; i < bo->num_planes; i++) if (bo->handles[i].u32 == bo->handles[plane].u32) - mapping->vma->length += bo->sizes[i]; + vma->length += bo->sizes[i]; - return mmap(0, mapping->vma->length, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, + 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 mapping *mapping) +int drv_bo_munmap(struct bo *bo, struct vma *vma) { - return munmap(mapping->vma->addr, mapping->vma->length); + return munmap(vma->addr, vma->length); } int drv_mapping_destroy(struct bo *bo) @@ -359,7 +359,7 @@ int drv_mapping_destroy(struct bo *bo) } if (!--mapping->vma->refcount) { - ret = bo->drv->backend->bo_unmap(bo, mapping); + ret = bo->drv->backend->bo_unmap(bo, mapping->vma); if (ret) { fprintf(stderr, "drv: munmap failed"); return ret; diff --git a/helpers.h b/helpers.h index 5de7225..9c9dcc6 100644 --- a/helpers.h +++ b/helpers.h @@ -18,8 +18,8 @@ int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t 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 mapping *mapping, size_t plane, uint32_t map_flags); -int drv_bo_munmap(struct bo *bo, struct mapping *mapping); +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); diff --git a/i915.c b/i915.c index 965f62d..0b30703 100644 --- a/i915.c +++ b/i915.c @@ -404,7 +404,9 @@ static int i915_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint32_t 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, + I915_FORMAT_MOD_Y_TILED, + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, }; uint64_t modifier; @@ -445,7 +447,7 @@ 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 mapping *mapping, size_t plane, uint32_t map_flags) +static void *i915_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags) { int ret; void *addr; @@ -489,7 +491,7 @@ static void *i915_bo_map(struct bo *bo, struct mapping *mapping, size_t plane, u return addr; } - mapping->vma->length = bo->total_size; + vma->length = bo->total_size; return addr; } diff --git a/mediatek.c b/mediatek.c index 33f57fd..ebc000f 100644 --- a/mediatek.c +++ b/mediatek.c @@ -78,8 +78,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 mapping *mapping, size_t plane, - uint32_t map_flags) +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; @@ -97,31 +96,31 @@ static void *mediatek_bo_map(struct bo *bo, struct mapping *mapping, size_t plan void *addr = mmap(0, bo->total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, gem_map.offset); - mapping->vma->length = bo->total_size; + vma->length = bo->total_size; 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); - mapping->vma->priv = priv; + vma->priv = priv; addr = priv->cached_addr; } return addr; } -static int mediatek_bo_unmap(struct bo *bo, struct mapping *mapping) +static int mediatek_bo_unmap(struct bo *bo, struct vma *vma) { - if (mapping->vma->priv) { - struct mediatek_private_map_data *priv = mapping->vma->priv; - mapping->vma->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); - mapping->vma->priv = NULL; + vma->priv = NULL; } - return munmap(mapping->vma->addr, mapping->vma->length); + return munmap(vma->addr, vma->length); } static int mediatek_bo_flush(struct bo *bo, struct mapping *mapping) diff --git a/rockchip.c b/rockchip.c index 5076f1f..14c042b 100644 --- a/rockchip.c +++ b/rockchip.c @@ -239,8 +239,7 @@ static int rockchip_bo_create(struct bo *bo, uint32_t width, uint32_t height, ui ARRAY_SIZE(modifiers)); } -static void *rockchip_bo_map(struct bo *bo, struct mapping *mapping, size_t plane, - uint32_t map_flags) +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; @@ -263,31 +262,31 @@ static void *rockchip_bo_map(struct bo *bo, struct mapping *mapping, size_t plan void *addr = mmap(0, bo->total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, gem_map.offset); - mapping->vma->length = bo->total_size; + vma->length = bo->total_size; 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); - mapping->vma->priv = priv; + vma->priv = priv; addr = priv->cached_addr; } return addr; } -static int rockchip_bo_unmap(struct bo *bo, struct mapping *mapping) +static int rockchip_bo_unmap(struct bo *bo, struct vma *vma) { - if (mapping->vma->priv) { - struct rockchip_private_map_data *priv = mapping->vma->priv; - mapping->vma->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); - mapping->vma->priv = NULL; + vma->priv = NULL; } - return munmap(mapping->vma->addr, mapping->vma->length); + return munmap(vma->addr, vma->length); } static int rockchip_bo_flush(struct bo *bo, struct mapping *mapping) diff --git a/tegra.c b/tegra.c index e365593..4551fcf 100644 --- a/tegra.c +++ b/tegra.c @@ -300,7 +300,7 @@ static int tegra_bo_import(struct bo *bo, struct drv_import_fd_data *data) return 0; } -static void *tegra_bo_map(struct bo *bo, struct mapping *mapping, size_t plane, uint32_t map_flags) +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; @@ -317,12 +317,12 @@ static void *tegra_bo_map(struct bo *bo, struct mapping *mapping, size_t plane, void *addr = mmap(0, bo->total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, gem_map.offset); - mapping->vma->length = bo->total_size; + 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; - mapping->vma->priv = priv; + vma->priv = priv; transfer_tiled_memory(bo, priv->tiled, priv->untiled, TEGRA_READ_TILED_BUFFER); addr = priv->untiled; } @@ -330,17 +330,17 @@ static void *tegra_bo_map(struct bo *bo, struct mapping *mapping, size_t plane, return addr; } -static int tegra_bo_unmap(struct bo *bo, struct mapping *mapping) +static int tegra_bo_unmap(struct bo *bo, struct vma *vma) { - if (mapping->vma->priv) { - struct tegra_private_map_data *priv = mapping->vma->priv; - mapping->vma->addr = priv->tiled; + if (vma->priv) { + struct tegra_private_map_data *priv = vma->priv; + vma->addr = priv->tiled; free(priv->untiled); free(priv); - mapping->vma->priv = NULL; + vma->priv = NULL; } - return munmap(mapping->vma->addr, mapping->vma->length); + return munmap(vma->addr, vma->length); } static int tegra_bo_flush(struct bo *bo, struct mapping *mapping) diff --git a/vc4.c b/vc4.c index cfcc219..82b7047 100644 --- a/vc4.c +++ b/vc4.c @@ -62,7 +62,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 mapping *mapping, size_t plane, uint32_t map_flags) +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,7 +76,7 @@ static void *vc4_bo_map(struct bo *bo, struct mapping *mapping, size_t plane, ui return MAP_FAILED; } - mapping->vma->length = bo->total_size; + vma->length = bo->total_size; return mmap(0, bo->total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, bo_map.offset); } From 1ef809ecd434bfc0fd1d669ba925d58b1255d163 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Mon, 6 Nov 2017 11:07:52 -0800 Subject: [PATCH 011/269] minigbm: plumb buffer access region MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will allow drivers to tile or detile only the regions requested by the user. Note that the gralloc spec states that: "This address will represent the top-left corner of the entire buffer, even if accessRegion does not begin at the top-left corner." (see hardware/interfaces/graphics/mapper/2.0/IMapper.hal in AOSP) Also, the gralloc API makes it difficult to maintain two mappings of the same buffer. For example, say you have two access regions: module->lock(mod, handle1, 0, 0, 5, 5, &addr); module->lock(mod, handle1, 5, 5, 10, 10, &addr); module->unlock(mod, handle1); // which access region should be unlocked? In practice, this scenario never happens on Android. It's not exactly clear what gbm should return. Let's just return the top left of the access region because that's what we where doing before. BUG=chromium:764871 TEST=gbmtest, mmap_test -g, the following CTS tests: android.view.cts.SurfaceViewSyncTests android.media.cts.EncodeDecodeTest android.video.cts.VideoEncoderDecoderTest Change-Id: I7ca0713871e03928b1d4402aa161588990c7e775 Reviewed-on: https://chromium-review.googlesource.com/758147 Commit-Ready: Gurchetan Singh Tested-by: Gurchetan Singh Reviewed-by: Stéphane Marchesin --- cros_gralloc/cros_gralloc_buffer.cc | 6 ++-- cros_gralloc/cros_gralloc_buffer.h | 3 +- cros_gralloc/cros_gralloc_driver.cc | 5 +-- cros_gralloc/cros_gralloc_driver.h | 4 +-- cros_gralloc/gralloc0/gralloc0.cc | 22 +++++++++++-- drv.c | 48 ++++++++++++++++++++--------- drv.h | 15 +++++++-- gbm.c | 14 +++++++-- helpers.h | 1 - 9 files changed, 89 insertions(+), 29 deletions(-) diff --git a/cros_gralloc/cros_gralloc_buffer.cc b/cros_gralloc/cros_gralloc_buffer.cc index c84e21a..7757069 100644 --- a/cros_gralloc/cros_gralloc_buffer.cc +++ b/cros_gralloc/cros_gralloc_buffer.cc @@ -44,7 +44,8 @@ int32_t cros_gralloc_buffer::decrease_refcount() return --refcount_; } -int32_t cros_gralloc_buffer::lock(uint32_t map_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; @@ -64,8 +65,7 @@ int32_t cros_gralloc_buffer::lock(uint32_t map_flags, uint8_t *addr[DRV_MAX_PLAN 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_), - map_flags, &lock_data_[0], 0); + vaddr = drv_bo_map(bo_, rect, map_flags, &lock_data_[0], 0); } if (vaddr == MAP_FAILED) { diff --git a/cros_gralloc/cros_gralloc_buffer.h b/cros_gralloc/cros_gralloc_buffer.h index 93ec37f..e6aec91 100644 --- a/cros_gralloc/cros_gralloc_buffer.h +++ b/cros_gralloc/cros_gralloc_buffer.h @@ -23,7 +23,8 @@ class cros_gralloc_buffer int32_t increase_refcount(); int32_t decrease_refcount(); - int32_t lock(uint32_t map_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: diff --git a/cros_gralloc/cros_gralloc_driver.cc b/cros_gralloc/cros_gralloc_driver.cc index 3a0b013..fec4aba 100644 --- a/cros_gralloc/cros_gralloc_driver.cc +++ b/cros_gralloc/cros_gralloc_driver.cc @@ -235,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, uint32_t map_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); @@ -255,7 +256,7 @@ int32_t cros_gralloc_driver::lock(buffer_handle_t handle, int32_t acquire_fence, return -EINVAL; } - return buffer->lock(map_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/cros_gralloc/cros_gralloc_driver.h b/cros_gralloc/cros_gralloc_driver.h index dea2ac0..45782c9 100644 --- a/cros_gralloc/cros_gralloc_driver.h +++ b/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, uint32_t map_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/cros_gralloc/gralloc0/gralloc0.cc b/cros_gralloc/gralloc0/gralloc0.cc index ab05376..b055f65 100644 --- a/cros_gralloc/gralloc0/gralloc0.cc +++ b/cros_gralloc/gralloc0/gralloc0.cc @@ -297,6 +297,10 @@ static int gralloc0_lock_async(struct gralloc_module_t const *module, buffer_han uint32_t map_flags; uint8_t *addr[DRV_MAX_PLANES]; auto mod = (struct gralloc0_module *)module; + struct rectangle rect = { .x = static_cast(l), + .y = static_cast(t), + .width = static_cast(w), + .height = static_cast(h) }; auto hnd = cros_gralloc_convert_handle(handle); if (!hnd) { @@ -309,8 +313,13 @@ static int gralloc0_lock_async(struct gralloc_module_t const *module, buffer_han return -EINVAL; } + 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, map_flags, addr); + ret = mod->driver->lock(handle, fence_fd, &rect, map_flags, addr); *vaddr = addr[0]; return ret; } @@ -330,6 +339,10 @@ static int gralloc0_lock_async_ycbcr(struct gralloc_module_t const *module, buff 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(l), + .y = static_cast(t), + .width = static_cast(w), + .height = static_cast(h) }; auto hnd = cros_gralloc_convert_handle(handle); if (!hnd) { @@ -344,8 +357,13 @@ static int gralloc0_lock_async_ycbcr(struct gralloc_module_t const *module, buff return -EINVAL; } + 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, map_flags, addr); + ret = mod->driver->lock(handle, fence_fd, &rect, map_flags, addr); if (ret) return ret; diff --git a/drv.c b/drv.c index cd8251f..a1be245 100644 --- a/drv.c +++ b/drv.c @@ -382,25 +382,42 @@ struct bo *drv_bo_import(struct driver *drv, struct drv_import_fd_data *data) return NULL; } -void *drv_bo_map(struct bo *bo, uint32_t x, uint32_t y, uint32_t width, uint32_t height, - uint32_t map_flags, struct mapping **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) { uint32_t i; uint8_t *addr; - size_t offset; struct mapping mapping; - assert(width > 0); - assert(height > 0); - assert(x + width <= drv_bo_get_width(bo)); - assert(y + height <= drv_bo_get_height(bo)); + 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)); memset(&mapping, 0, sizeof(mapping)); + mapping.rect = *rect; + mapping.refcount = 1; + pthread_mutex_lock(&bo->drv->driver_lock); + 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 || @@ -427,14 +444,12 @@ void *drv_bo_map(struct bo *bo, uint32_t x, uint32_t y, uint32_t width, uint32_t mapping.vma->map_flags = map_flags; success: - drv_bo_invalidate(bo, &mapping); *map_data = drv_array_append(bo->drv->mappings, &mapping); - offset = drv_bo_get_plane_stride(bo, plane) * y; - offset += drv_stride_from_format(bo->format, x, plane); - addr = (uint8_t *)mapping.vma->addr; - addr += drv_bo_get_plane_offset(bo, plane) + offset; +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; } @@ -447,6 +462,9 @@ int drv_bo_unmap(struct bo *bo, struct mapping *mapping) pthread_mutex_lock(&bo->drv->driver_lock); + if (--mapping->refcount) + goto out; + if (!--mapping->vma->refcount) { ret = bo->drv->backend->bo_unmap(bo, mapping->vma); free(mapping->vma); @@ -459,8 +477,8 @@ int drv_bo_unmap(struct bo *bo, struct mapping *mapping) } } +out: pthread_mutex_unlock(&bo->drv->driver_lock); - return ret; } @@ -470,6 +488,7 @@ int drv_bo_invalidate(struct bo *bo, struct mapping *mapping) assert(mapping); assert(mapping->vma); + assert(mapping->refcount > 0); assert(mapping->vma->refcount > 0); if (bo->drv->backend->bo_invalidate) @@ -484,6 +503,7 @@ int drv_bo_flush(struct bo *bo, struct mapping *mapping) assert(mapping); assert(mapping->vma); + assert(mapping->refcount > 0); assert(mapping->vma->refcount > 0); assert(!(bo->use_flags & BO_USE_PROTECTED)); diff --git a/drv.h b/drv.h index bfde327..18653e5 100644 --- a/drv.h +++ b/drv.h @@ -87,8 +87,17 @@ struct vma { 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); @@ -114,8 +123,8 @@ 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 map_flags, struct mapping **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); @@ -147,6 +156,8 @@ uint32_t drv_bo_get_format(struct bo *bo); uint32_t drv_bo_get_stride_in_pixels(struct bo *bo); +uint32_t drv_stride_from_format(uint32_t format, uint32_t width, size_t plane); + uint32_t drv_resolve_format(struct driver *drv, uint32_t format, uint64_t use_flags); size_t drv_num_planes_from_format(uint32_t format); diff --git a/gbm.c b/gbm.c index 606b195..c67bdcd 100644 --- a/gbm.c +++ b/gbm.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "drv.h" @@ -225,15 +226,24 @@ 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 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); 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; - return drv_bo_map(bo->bo, x, y, width, height, map_flags, (struct mapping **)map_data, - plane); + + 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) diff --git a/helpers.h b/helpers.h index 9c9dcc6..92a5017 100644 --- a/helpers.h +++ b/helpers.h @@ -10,7 +10,6 @@ #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, From d300145b093cf67277648a664d3748b881d4a315 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Fri, 3 Nov 2017 17:18:36 -0700 Subject: [PATCH 012/269] minigbm: make drv_add_combinations return nothing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two reasons for this: 1) We can use drv_array for driver combinations (see next patch) 2) It's less verbose. BUG=chromium:764871 TEST=gbmtest passes Change-Id: I39bea6e2e9e4c76d2ca78566926a79bdc17f11d0 Reviewed-on: https://chromium-review.googlesource.com/758148 Commit-Ready: Gurchetan Singh Tested-by: Gurchetan Singh Reviewed-by: Stéphane Marchesin --- amdgpu.c | 33 +++++++++++---------------------- evdi.c | 7 ++----- exynos.c | 15 +++++---------- gma500.c | 7 ++----- helpers.c | 14 ++++---------- helpers.h | 4 ++-- i915.c | 48 +++++++++++++++++------------------------------- marvell.c | 7 ++----- mediatek.c | 13 ++++--------- nouveau.c | 7 ++----- radeon.c | 7 ++----- rockchip.c | 12 ++++-------- tegra.c | 13 ++++--------- udl.c | 7 ++----- vc4.c | 7 ++----- vgem.c | 13 ++++--------- virtio_gpu.c | 13 ++++--------- 17 files changed, 73 insertions(+), 154 deletions(-) diff --git a/amdgpu.c b/amdgpu.c index 4a3eb7b..9abb79f 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -273,7 +273,6 @@ static void *amdgpu_addrlib_init(int fd) static int amdgpu_init(struct driver *drv) { - int ret; void *addrlib; struct format_metadata metadata; uint64_t use_flags = BO_USE_RENDER_MASK; @@ -284,10 +283,8 @@ 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, @@ -306,10 +303,8 @@ static int amdgpu_init(struct driver *drv) metadata.priority = 2; metadata.modifier = DRM_FORMAT_MOD_LINEAR; - ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &metadata, use_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); @@ -319,10 +314,8 @@ static int amdgpu_init(struct driver *drv) metadata.priority = 3; metadata.modifier = DRM_FORMAT_MOD_LINEAR; - ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &metadata, use_flags); - if (ret) - return ret; + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &metadata, use_flags); use_flags &= ~BO_USE_SW_WRITE_OFTEN; use_flags &= ~BO_USE_SW_READ_OFTEN; @@ -331,10 +324,8 @@ static int amdgpu_init(struct driver *drv) 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, use_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); @@ -343,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, use_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) diff --git a/evdi.c b/evdi.c index 3bac658..bfa62a0 100644 --- a/evdi.c +++ b/evdi.c @@ -12,11 +12,8 @@ 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); } diff --git a/exynos.c b/exynos.c index 455416e..526603e 100644 --- a/exynos.c +++ b/exynos.c @@ -25,16 +25,11 @@ 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; - - 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, 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); } diff --git a/gma500.c b/gma500.c index bcc3bc8..366f232 100644 --- a/gma500.c +++ b/gma500.c @@ -12,11 +12,8 @@ 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; + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &LINEAR_METADATA, BO_USE_RENDER_MASK); return drv_modify_linear_combinations(drv); } diff --git a/helpers.c b/helpers.c index 9a33804..0eba698 100644 --- a/helpers.c +++ b/helpers.c @@ -444,18 +444,12 @@ int drv_add_combination(struct driver *drv, uint32_t format, struct format_metad return 0; } -int drv_add_combinations(struct driver *drv, const uint32_t *formats, uint32_t num_formats, - struct format_metadata *metadata, uint64_t use_flags) +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, use_flags); - if (ret) - return ret; - } - - return 0; + for (i = 0; i < num_formats; i++) + drv_add_combination(drv, formats[i], metadata, use_flags); } void drv_modify_combination(struct driver *drv, uint32_t format, struct format_metadata *metadata, diff --git a/helpers.h b/helpers.h index 92a5017..b0fbdee 100644 --- a/helpers.h +++ b/helpers.h @@ -27,8 +27,8 @@ void drv_decrement_reference_count(struct driver *drv, struct bo *bo, size_t pla 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); diff --git a/i915.c b/i915.c index 0b30703..d4f2ece 100644 --- a/i915.c +++ b/i915.c @@ -96,21 +96,15 @@ static int i915_add_combinations(struct driver *drv) metadata.priority = 1; metadata.modifier = DRM_FORMAT_MOD_LINEAR; - ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &metadata, render_use_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_use_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_use_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); @@ -139,31 +133,23 @@ static int i915_add_combinations(struct driver *drv) 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_use_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_use_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_use_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_use_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) diff --git a/marvell.c b/marvell.c index f209139..c0b600b 100644 --- a/marvell.c +++ b/marvell.c @@ -14,11 +14,8 @@ 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)); diff --git a/mediatek.c b/mediatek.c index ebc000f..737a8d7 100644 --- a/mediatek.c +++ b/mediatek.c @@ -32,16 +32,11 @@ 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); } diff --git a/nouveau.c b/nouveau.c index 4efbda2..d0f25d4 100644 --- a/nouveau.c +++ b/nouveau.c @@ -12,11 +12,8 @@ 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); } diff --git a/radeon.c b/radeon.c index 84b01c5..68445c1 100644 --- a/radeon.c +++ b/radeon.c @@ -12,11 +12,8 @@ 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); } diff --git a/rockchip.c b/rockchip.c index 14c042b..7964676 100644 --- a/rockchip.c +++ b/rockchip.c @@ -120,15 +120,11 @@ static int rockchip_init(struct driver *drv) metadata.priority = 1; 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); diff --git a/tegra.c b/tegra.c index 4551fcf..f0651d7 100644 --- a/tegra.c +++ b/tegra.c @@ -179,7 +179,6 @@ 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 use_flags = BO_USE_RENDER_MASK; @@ -187,10 +186,8 @@ static int tegra_init(struct driver *drv) metadata.priority = 1; metadata.modifier = DRM_FORMAT_MOD_LINEAR; - ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &metadata, use_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); @@ -202,10 +199,8 @@ static int tegra_init(struct driver *drv) metadata.tiling = NV_MEM_KIND_C32_2CRA; metadata.priority = 2; - ret = drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &metadata, use_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); diff --git a/udl.c b/udl.c index 5ec2307..12dc967 100644 --- a/udl.c +++ b/udl.c @@ -12,11 +12,8 @@ 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); } diff --git a/vc4.c b/vc4.c index 82b7047..7960247 100644 --- a/vc4.c +++ b/vc4.c @@ -21,11 +21,8 @@ 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); } diff --git a/vgem.c b/vgem.c index a4e893b..5380b78 100644 --- a/vgem.c +++ b/vgem.c @@ -20,16 +20,11 @@ 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); } diff --git a/virtio_gpu.c b/virtio_gpu.c index 447a17d..957292c 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -20,16 +20,11 @@ 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); } From bc9a87d54c5296d467ead2b4ea35e317f00ee401 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Fri, 3 Nov 2017 17:17:35 -0700 Subject: [PATCH 013/269] minigbm: use drv_array for combinations and kms_items MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This de-deuplicates the various dynamic arrays we use. BUG=chromium:764871 TEST=gbmtest passes Change-Id: I94c8cf7c71fdb98b931aab00c5381853e2ae0d3f Reviewed-on: https://chromium-review.googlesource.com/758149 Commit-Ready: Gurchetan Singh Tested-by: Gurchetan Singh Reviewed-by: Stéphane Marchesin --- drv.c | 17 +++------ drv_priv.h | 8 +--- helpers.c | 109 ++++++++++++++++++++--------------------------------- helpers.h | 2 +- i915.c | 20 +++++----- rockchip.c | 26 ++++++------- 6 files changed, 69 insertions(+), 113 deletions(-) diff --git a/drv.c b/drv.c index a1be245..5b6a116 100644 --- a/drv.c +++ b/drv.c @@ -136,18 +136,14 @@ struct driver *drv_create(int fd) if (!drv->mappings) goto free_buffer_table; - /* Start with a power of 2 number of allocations. */ - drv->combos.allocations = 2; - drv->combos.size = 0; - - drv->combos.data = calloc(drv->combos.allocations, sizeof(struct combination)); - if (!drv->combos.data) + 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->combos.data); + drv_array_destroy(drv->combos); goto free_mappings; } } @@ -174,8 +170,7 @@ void drv_destroy(struct driver *drv) drmHashDestroy(drv->buffer_table); drv_array_destroy(drv->mappings); - - free(drv->combos.data); + drv_array_destroy(drv->combos); pthread_mutex_unlock(&drv->driver_lock); pthread_mutex_destroy(&drv->driver_lock); @@ -202,8 +197,8 @@ struct combination *drv_get_combination(struct driver *drv, uint32_t format, uin best = NULL; uint32_t i; - for (i = 0; i < drv->combos.size; i++) { - curr = &drv->combos.data[i]; + 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; diff --git a/drv_priv.h b/drv_priv.h index 048b9a3..18a289c 100644 --- a/drv_priv.h +++ b/drv_priv.h @@ -49,19 +49,13 @@ struct combination { 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 combinations combos; + struct drv_array *combos; pthread_mutex_t driver_lock; }; diff --git a/helpers.c b/helpers.c index 0eba698..ef653ed 100644 --- a/helpers.c +++ b/helpers.c @@ -421,35 +421,18 @@ 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 use_flags) -{ - struct combinations *combos = &drv->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].use_flags = use_flags; - combos->size++; - return 0; -} - void drv_add_combinations(struct driver *drv, const uint32_t *formats, uint32_t num_formats, struct format_metadata *metadata, uint64_t use_flags) { uint32_t i; - for (i = 0; i < num_formats; i++) - drv_add_combination(drv, formats[i], metadata, use_flags); + + for (i = 0; i < num_formats; i++) { + struct combination combo = { .format = formats[i], + .metadata = *metadata, + .use_flags = use_flags }; + + drv_array_append(drv->combos, &combo); + } } void drv_modify_combination(struct driver *drv, uint32_t format, struct format_metadata *metadata, @@ -458,30 +441,27 @@ void drv_modify_combination(struct driver *drv, uint32_t format, struct format_m uint32_t i; struct combination *combo; /* Attempts to add the specified flags to an existing combination. */ - for (i = 0; i < drv->combos.size; i++) { - combo = &drv->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 == format && combo->metadata.tiling == metadata->tiling && combo->metadata.modifier == metadata->modifier) 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) { - struct kms_item *items; + struct drv_array *kms_items; uint64_t plane_type, use_flag; - uint32_t i, j, k, allocations, item_size; + 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; /* @@ -532,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_INVALID) { - items[k].use_flags |= use_flag; + 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_INVALID) { + 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_INVALID; - items[item_size].use_flags = use_flag; - item_size++; + struct kms_item item = { .format = plane->formats[j], + .modifier = DRM_FORMAT_MOD_INVALID, + .use_flags = use_flag }; + + drv_array_append(kms_items, &item); } } @@ -567,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 @@ -594,19 +564,20 @@ 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->combos.size; j++) { - combo = &drv->combos.data[j]; - if (items[i].format == combo->format) + 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; } diff --git a/helpers.h b/helpers.h index b0fbdee..6b8818d 100644 --- a/helpers.h +++ b/helpers.h @@ -31,7 +31,7 @@ void drv_add_combinations(struct driver *drv, const uint32_t *formats, uint32_t 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); diff --git a/i915.c b/i915.c index d4f2ece..9b7a6fe 100644 --- a/i915.c +++ b/i915.c @@ -58,8 +58,8 @@ 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->combos.size; i++) { - combo = &drv->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; @@ -84,8 +84,8 @@ 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_use_flags, texture_use_flags; @@ -151,19 +151,19 @@ static int i915_add_combinations(struct driver *drv) 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; } diff --git a/rockchip.c b/rockchip.c index 7964676..7cecf3b 100644 --- a/rockchip.c +++ b/rockchip.c @@ -76,14 +76,13 @@ 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 use_flags; struct combination *combo; struct format_metadata metadata; - for (i = 0; i < drv->combos.size; i++) { - combo = &drv->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) { use_flags = BO_USE_RENDERING | BO_USE_SCANOUT | BO_USE_TEXTURE; @@ -96,10 +95,7 @@ static int rockchip_add_kms_item(struct driver *drv, const struct kms_item *item use_flags &= ~BO_USE_RENDERING; } - ret = - drv_add_combination(drv, item[i].format, &metadata, use_flags); - if (ret) - return ret; + drv_add_combinations(drv, &item->format, 1, &metadata, use_flags); } else { combo->use_flags |= item->use_flags; } @@ -112,8 +108,8 @@ 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; @@ -139,19 +135,19 @@ static int rockchip_init(struct driver *drv) drv_modify_combination(drv, DRM_FORMAT_R8, &metadata, BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); - 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 = 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; } From 07d36cc464e6d20d08913856f50cb50c2c6877d4 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Tue, 10 Oct 2017 12:11:16 -0700 Subject: [PATCH 014/269] Revert "minigbm: Revert "minigbm: flush buffer instead of unmapping"" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The reason the tests weren't passing is because DRM_IOCTL_I915_GEM_SET_DOMAIN is required on x86 platforms when calling (*lock). A previous CLs added this. BUG=b:67073097, b:67331142 TEST= android.view.cts.SurfaceViewSyncTests android.video.cts.VideoEncoderDecoderTest#testAvcGoog0Qual0720x0480 android.video.cts.VideoEncoderDecoderTest#testAvcGoog0Qual1280x0720 android.video.cts.VideoEncoderDecoderTest#testAvcGoog0Qual1920x1080 android.media.cts.EncodeDecodeTest#testVP8EncodeDecodeVideoFromSurfaceToSurface720p android.media.cts.EncodeDecodeTest#testEncodeDecodeVideoFromPersistentSurfaceToSurface720p android.media.cts.EncodeDecodeTest#testVP8EncodeDecodeVideoFromPersistentSurfaceToSurface720p pass on Eve. This reverts commit 14033e0013b5cc0ffc5af59dda7c377d46ec761d. v2: Make lock_data[0] null after last (*unlock)(), because user may specify different access regions in the next (*lock)(). Change-Id: Ia56ecd57acc4471b026c852b178d8bc0f189dec7 Reviewed-on: https://chromium-review.googlesource.com/710324 Commit-Ready: Gurchetan Singh Tested-by: Gurchetan Singh Reviewed-by: Stéphane Marchesin --- cros_gralloc/cros_gralloc_buffer.cc | 2 +- gbm.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cros_gralloc/cros_gralloc_buffer.cc b/cros_gralloc/cros_gralloc_buffer.cc index 7757069..47a13a2 100644 --- a/cros_gralloc/cros_gralloc_buffer.cc +++ b/cros_gralloc/cros_gralloc_buffer.cc @@ -90,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/gbm.c b/gbm.c index c67bdcd..25b4fa0 100644 --- a/gbm.c +++ b/gbm.c @@ -249,7 +249,7 @@ PUBLIC void *gbm_bo_map(struct gbm_bo *bo, uint32_t x, uint32_t y, uint32_t widt 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) From 355b156a78aa17211b77730dade28f02b64752a1 Mon Sep 17 00:00:00 2001 From: Shirish S Date: Fri, 13 Oct 2017 09:54:03 +0530 Subject: [PATCH 015/269] minigbm: add GBM_BO_USE_SW_{READ,WRITE}_{OFTEN,RARELY} usage flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Need for these flags has arisen because buffer's allocated BO_USE_SCANOUT flag is not mmapable in amd, whereas going further for ensuring atomictity related operations are functional, one needs buffer to be mmap'd. These flags shall be used to strike balance in enabling AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED on amd and mmap X-tiled buffers on Intel platforms. BUG=b:65297611, chromium:777706 TEST=On Kahlee, UI comes up. GLMark2 & GLbench autotests show no performance regression atomictest -t multiplanes passes WebGL Aquarium Change-Id: I582452d331f4a05106939447784a76eba06d13c2 Reviewed-on: https://chromium-review.googlesource.com/758618 Commit-Ready: Gurchetan Singh Tested-by: Gurchetan Singh Reviewed-by: Stéphane Marchesin --- gbm.h | 12 +++++++++++- gbm_helpers.c | 8 ++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/gbm.h b/gbm.h index a58aadb..da993c2 100644 --- a/gbm.h +++ b/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), /** @@ -255,6 +256,15 @@ enum gbm_bo_flags { * 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/gbm_helpers.c b/gbm_helpers.c index c22233a..2683669 100644 --- a/gbm_helpers.c +++ b/gbm_helpers.c @@ -32,6 +32,14 @@ uint64_t gbm_convert_usage(uint32_t usage) 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 use_flags; } From ca2938a5c681e42a344f7237430726aa17ff1126 Mon Sep 17 00:00:00 2001 From: Tomasz Mikolajewski Date: Fri, 17 Nov 2017 20:30:56 +0900 Subject: [PATCH 016/269] Add a missing include for asserts. The missing include would cause image builders fail on -arcnext builds. BUG=chromium:764871 TEST=emerge arc-cros-gralloc and minigbm on -arcnext. Change-Id: Ifde30bcde72a1fae4d13c95b17273880512cafe2 Reviewed-on: https://chromium-review.googlesource.com/776640 Commit-Ready: Gurchetan Singh Tested-by: Gurchetan Singh Reviewed-by: Gurchetan Singh --- cros_gralloc/gralloc0/gralloc0.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/cros_gralloc/gralloc0/gralloc0.cc b/cros_gralloc/gralloc0/gralloc0.cc index b055f65..50cd1af 100644 --- a/cros_gralloc/gralloc0/gralloc0.cc +++ b/cros_gralloc/gralloc0/gralloc0.cc @@ -6,6 +6,7 @@ #include "../cros_gralloc_driver.h" +#include #include #include From ef262d8e314cffaedbcea13aafc31fde31c47793 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Tue, 28 Nov 2017 16:56:17 -0800 Subject: [PATCH 017/269] minigbm: rockchip/mediatek: invalidate shadow buffers In the case where process A is writing to the buffer, and process B is reading from the buffer via a shadow buffer, we should update the shadow buffer. This issue seems to only pop on renderscript tests on Mediatek devices, but that's due the various differences between 3D driver implementations. Let's modify rockchip for correctness as well. BUG=b:69700010 TEST=run cts -m CtsViewTestCases -t android.view.cts.SurfaceViewSyncTests passes on Oak Change-Id: Id551027a2093f5423ee380d8935637d6256d2295 Reviewed-on: https://chromium-review.googlesource.com/795038 Commit-Ready: Gurchetan Singh Tested-by: Gurchetan Singh Reviewed-by: Tomasz Figa --- mediatek.c | 12 +++++++++++- rockchip.c | 12 +++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/mediatek.c b/mediatek.c index 737a8d7..7614004 100644 --- a/mediatek.c +++ b/mediatek.c @@ -97,7 +97,6 @@ static void *mediatek_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint3 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); vma->priv = priv; addr = priv->cached_addr; } @@ -118,6 +117,16 @@ static int mediatek_bo_unmap(struct bo *bo, struct vma *vma) 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 0; +} + static int mediatek_bo_flush(struct bo *bo, struct mapping *mapping) { struct mediatek_private_map_data *priv = mapping->vma->priv; @@ -148,6 +157,7 @@ const 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/rockchip.c b/rockchip.c index 7cecf3b..ac17dbd 100644 --- a/rockchip.c +++ b/rockchip.c @@ -260,7 +260,6 @@ static void *rockchip_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint3 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); vma->priv = priv; addr = priv->cached_addr; } @@ -281,6 +280,16 @@ static int rockchip_bo_unmap(struct bo *bo, struct vma *vma) 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; @@ -315,6 +324,7 @@ const 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, }; From 85c4c5f4acb41b82322e041014474b7d146ee428 Mon Sep 17 00:00:00 2001 From: Zach Reizner Date: Wed, 4 Oct 2017 13:15:57 -0700 Subject: [PATCH 018/269] minigbm: virtio_gpu: use resource create ioctl for rendering MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the virtio_gpu kernel driver, there is a flag for each BO indicating if the buffer was made with the dumb buffer create ioctl. If that flag is set, the kernel will request a transfer to host on page flip, even if the dumb buffer is used in host side rendering. In the case of host side rendering, the transfer will wipe out the rendering because the transfer copies from guest side backing memory which was never used. To prevent that issue, the virtgpu resource create ioctl is used to prevent the dumb flag from being set. Simple mmap'ed framebuffers will not display properly unless they use gbm's mmap/munmap which includes a transfer to/from the host on mmap/munmap with this change. TEST=null_platform_test; mmap_test -g renders correctly but we get ENOSYS (function not implemented) from DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST. (DRM_IOCTL_VIRTGPU_TRANSFER_TO_HOST succeeds though) That'll have to be fixed .. BUG=None Change-Id: Id36080f597efd00a96e625ee4301ebf26d9f19af Reviewed-on: https://chromium-review.googlesource.com/701354 Commit-Ready: Gurchetan Singh Tested-by: Gurchetan Singh Reviewed-by: Stéphane Marchesin --- presubmit.sh | 2 +- virgl_hw.h | 286 ++++++++++++++++++++++++++++++++++ virtio_gpu.c => virtio_dumb.c | 4 + virtio_virgl.c | 219 ++++++++++++++++++++++++++ 4 files changed, 510 insertions(+), 1 deletion(-) create mode 100644 virgl_hw.h rename virtio_gpu.c => virtio_dumb.c (98%) create mode 100644 virtio_virgl.c diff --git a/presubmit.sh b/presubmit.sh index 6d55f2a..1cfc59c 100755 --- a/presubmit.sh +++ b/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/virgl_hw.h b/virgl_hw.h new file mode 100644 index 0000000..e3c56db --- /dev/null +++ b/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/virtio_gpu.c b/virtio_dumb.c similarity index 98% rename from virtio_gpu.c rename to virtio_dumb.c index 957292c..b6dc3cb 100644 --- a/virtio_gpu.c +++ b/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" @@ -65,3 +67,5 @@ const struct backend backend_virtio_gpu = { .bo_unmap = drv_bo_munmap, .resolve_format = virtio_gpu_resolve_format, }; + +#endif diff --git a/virtio_virgl.c b/virtio_virgl.c new file mode 100644 index 0000000..b33677b --- /dev/null +++ b/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 +#include +#include +#include +#include +#include +#include + +#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 From fa17cdde2da08155f0197c4150fdee4006733fb5 Mon Sep 17 00:00:00 2001 From: Dominik Behr Date: Thu, 30 Nov 2017 12:23:06 -0800 Subject: [PATCH 019/269] minigbm: amdgpu: use VRAM only for cursor and scanouts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Everything else should use GTT (USWC preferably). We should also switch scanouts to GTT after we enable display VM. BUG=b:69941535,b:69647975 TEST=run WebGL Aquarium on Kahlee Change-Id: I939b159551305f74102ba47eb551e2bed2e32e06 Signed-off-by: Dominik Behr Reviewed-on: https://chromium-review.googlesource.com/801797 Reviewed-by: Stéphane Marchesin Reviewed-by: Gurchetan Singh --- amdgpu.c | 16 ++++++++++++++-- drv_priv.h | 7 +++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/amdgpu.c b/amdgpu.c index 9abb79f..cca3537 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -376,8 +376,20 @@ static int amdgpu_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint 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 = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; + + 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)); diff --git a/drv_priv.h b/drv_priv.h index 18a289c..a397b1e 100644 --- a/drv_priv.h +++ b/drv_priv.h @@ -85,6 +85,13 @@ struct backend { 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_SW_RARELY BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY + #define LINEAR_METADATA (struct format_metadata) { 0, 1, DRM_FORMAT_MOD_NONE } // clang-format on From 9927d78669f67c2446888aa32a3e9f9c71f7228b Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Tue, 12 Dec 2017 14:38:09 -0800 Subject: [PATCH 020/269] minigbm: replace DRM_FORMAT_MOD_INVALID with DRM_FORMAT_MOD_LINEAR CL:737409 replaced DRM_FORMAT_MOD_NONE with DRM_FORMAT_MOD_INVALID in struct kms_item. We use drv_query_kms() to add the scanout flag to most buffer combinations. That means anything with DRM_FORMAT_MOD_LINEAR will not get the scanout flag, since drv_query_kms returns combinations with DRM_FORMAT_MOD_INVALID. This leads to artifacts in the zero latency app, since we end up picking a X-tiled buffer since we don't advertise a linear buffer with scanout. Since all hardware can scanout linear buffers, replace DRM_FORMAT_MOD_INVALID with DRM_FORMAT_MOD_LINEAR. BUG=chromium:762324 TEST=no overlay artifacts running Zero latency app Change-Id: Ib8a33b9e8dde3767337b9cd32c5b2849f9c8aa04 Reviewed-on: https://chromium-review.googlesource.com/823258 Commit-Ready: Gurchetan Singh Tested-by: Gurchetan Singh Reviewed-by: Gurchetan Singh --- drv_priv.h | 2 +- helpers.c | 4 ++-- i915.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drv_priv.h b/drv_priv.h index a397b1e..21c003b 100644 --- a/drv_priv.h +++ b/drv_priv.h @@ -92,7 +92,7 @@ struct backend { #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/helpers.c b/helpers.c index ef653ed..6c26e54 100644 --- a/helpers.c +++ b/helpers.c @@ -515,7 +515,7 @@ struct drv_array *drv_query_kms(struct driver *drv) 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_INVALID) { + item->modifier == DRM_FORMAT_MOD_LINEAR) { item->use_flags |= use_flag; found = true; break; @@ -524,7 +524,7 @@ struct drv_array *drv_query_kms(struct driver *drv) if (!found) { struct kms_item item = { .format = plane->formats[j], - .modifier = DRM_FORMAT_MOD_INVALID, + .modifier = DRM_FORMAT_MOD_LINEAR, .use_flags = use_flag }; drv_array_append(kms_items, &item); diff --git a/i915.c b/i915.c index 9b7a6fe..be315a1 100644 --- a/i915.c +++ b/i915.c @@ -63,7 +63,7 @@ static int i915_add_kms_item(struct driver *drv, const struct kms_item *item) if (combo->format != item->format) continue; - if (item->modifier == DRM_FORMAT_MOD_INVALID && + if (item->modifier == DRM_FORMAT_MOD_LINEAR && combo->metadata.tiling == I915_TILING_X) { /* * FIXME: drv_query_kms() does not report the available modifiers From 9ad07155dd9e5370e507d266766a8bcfbb4fa4d7 Mon Sep 17 00:00:00 2001 From: Dominik Behr Date: Fri, 5 Jan 2018 14:15:15 -0800 Subject: [PATCH 021/269] Revert "minigbm: replace DRM_FORMAT_MOD_INVALID with DRM_FORMAT_MOD_LINEAR" This reverts commit 9927d78669f67c2446888aa32a3e9f9c71f7228b. BUG=chromium:799639 TEST=run graphics_GLMark2 Change-Id: Idcf25de31fe2a17cc28900558e19145ca33dbff5 Reviewed-on: https://chromium-review.googlesource.com/853223 Commit-Ready: Dominik Behr Tested-by: Dominik Behr Reviewed-by: Robert Tarasov --- drv_priv.h | 2 +- helpers.c | 4 ++-- i915.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drv_priv.h b/drv_priv.h index 21c003b..a397b1e 100644 --- a/drv_priv.h +++ b/drv_priv.h @@ -92,7 +92,7 @@ struct backend { #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_LINEAR } +#define LINEAR_METADATA (struct format_metadata) { 0, 1, DRM_FORMAT_MOD_NONE } // clang-format on #endif diff --git a/helpers.c b/helpers.c index 6c26e54..ef653ed 100644 --- a/helpers.c +++ b/helpers.c @@ -515,7 +515,7 @@ struct drv_array *drv_query_kms(struct driver *drv) 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->modifier == DRM_FORMAT_MOD_INVALID) { item->use_flags |= use_flag; found = true; break; @@ -524,7 +524,7 @@ struct drv_array *drv_query_kms(struct driver *drv) if (!found) { struct kms_item item = { .format = plane->formats[j], - .modifier = DRM_FORMAT_MOD_LINEAR, + .modifier = DRM_FORMAT_MOD_INVALID, .use_flags = use_flag }; drv_array_append(kms_items, &item); diff --git a/i915.c b/i915.c index be315a1..9b7a6fe 100644 --- a/i915.c +++ b/i915.c @@ -63,7 +63,7 @@ static int i915_add_kms_item(struct driver *drv, const struct kms_item *item) if (combo->format != item->format) continue; - if (item->modifier == DRM_FORMAT_MOD_LINEAR && + if (item->modifier == DRM_FORMAT_MOD_INVALID && combo->metadata.tiling == I915_TILING_X) { /* * FIXME: drv_query_kms() does not report the available modifiers From 08052344f5eea7b44dabe1d5f501f91ff8f24097 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Thu, 11 Jan 2018 15:42:36 -0800 Subject: [PATCH 022/269] minigbm: add amlogic backend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add dumb amlogic backend based on udl. BUG=none TEST=emerge-falco minigbm Change-Id: I435d0924d8206b4058b76bf403175f9b2cbb1291 Reviewed-on: https://chromium-review.googlesource.com/861865 Commit-Ready: Gurchetan Singh Tested-by: Gurchetan Singh Reviewed-by: Stéphane Marchesin Reviewed-by: Sergey Volk --- Makefile | 3 +++ amlogic.c | 33 +++++++++++++++++++++++++++++++++ drv.c | 3 +++ 3 files changed, 39 insertions(+) create mode 100644 amlogic.c diff --git a/Makefile b/Makefile index 482e074..a01433e 100644 --- a/Makefile +++ b/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/amlogic.c b/amlogic.c new file mode 100644 index 0000000..5609ae8 --- /dev/null +++ b/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/drv.c b/drv.c index 5b6a116..881eefd 100644 --- a/drv.c +++ b/drv.c @@ -67,6 +67,9 @@ static const struct backend *drv_get_backend(int fd) const struct backend *backend_list[] = { #ifdef DRV_AMDGPU &backend_amdgpu, +#endif +#ifdef DRV_AMLOGIC + &backend_amlogic, #endif &backend_evdi, #ifdef DRV_EXYNOS From 218edbe81df05eb93e064dd68bd42703f22cc255 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Fri, 12 Jan 2018 15:22:53 -0800 Subject: [PATCH 023/269] minigbm: fix amlogic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 080523 ("minigbm: add amlogic backend") forgot to declare the backend external variable. BUG=None TEST=None Change-Id: I69c89645023e1cf45d7b4d480bdb85f3b838e276 Reviewed-on: https://chromium-review.googlesource.com/865771 Commit-Ready: Gurchetan Singh Tested-by: Gurchetan Singh Reviewed-by: Dominik Behr Reviewed-by: Stéphane Marchesin --- Android.mk | 1 + drv.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/Android.mk b/Android.mk index c4798ad..bd9b9ae 100644 --- a/Android.mk +++ b/Android.mk @@ -17,6 +17,7 @@ LOCAL_SHARED_LIBRARIES := \ LOCAL_SRC_FILES := \ amdgpu.c \ + amlogic.c \ cirrus.c \ drv.c \ evdi.c \ diff --git a/drv.c b/drv.c index 881eefd..1f6fcab 100644 --- a/drv.c +++ b/drv.c @@ -23,6 +23,9 @@ #ifdef DRV_AMDGPU extern const struct backend backend_amdgpu; #endif +#ifdef DRV_AMLOGIC +extern const struct backend backend_amlogic; +#endif extern const struct backend backend_evdi; #ifdef DRV_EXYNOS extern const struct backend backend_exynos; From d118a0e7466ce9ccabea300fafa2c4c28d468cb5 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Fri, 12 Jan 2018 23:31:50 +0000 Subject: [PATCH 024/269] Revert "Revert "minigbm: replace DRM_FORMAT_MOD_INVALID with DRM_FORMAT_MOD_LINEAR"" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 9ad07155dd9e5370e507d266766a8bcfbb4fa4d7. Reason for revert: We haven't seen improvements in the graphs after the speculative revert that landed in 10292.0.0: https://chromeperf.appspot.com/group_report?keys=agxzfmNocm9tZXBlcmZyFAsSB0Fub21hbHkYgICQ6IzqogoM Original change's description: > Revert "minigbm: replace DRM_FORMAT_MOD_INVALID with DRM_FORMAT_MOD_LINEAR" > > This reverts commit 9927d78669f67c2446888aa32a3e9f9c71f7228b. > > BUG=chromium:799639 > TEST=run graphics_GLMark2 > > Change-Id: Idcf25de31fe2a17cc28900558e19145ca33dbff5 > Reviewed-on: https://chromium-review.googlesource.com/853223 > Commit-Ready: Dominik Behr > Tested-by: Dominik Behr > Reviewed-by: Robert Tarasov Bug: chromium:799639 Change-Id: I100b93e41f43c026181eef0777f76b5c2cd93d6c Reviewed-on: https://chromium-review.googlesource.com/865773 Tested-by: Gurchetan Singh Reviewed-by: Stéphane Marchesin Reviewed-by: Dominik Behr --- drv_priv.h | 2 +- helpers.c | 4 ++-- i915.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drv_priv.h b/drv_priv.h index a397b1e..21c003b 100644 --- a/drv_priv.h +++ b/drv_priv.h @@ -92,7 +92,7 @@ struct backend { #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/helpers.c b/helpers.c index ef653ed..6c26e54 100644 --- a/helpers.c +++ b/helpers.c @@ -515,7 +515,7 @@ struct drv_array *drv_query_kms(struct driver *drv) 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_INVALID) { + item->modifier == DRM_FORMAT_MOD_LINEAR) { item->use_flags |= use_flag; found = true; break; @@ -524,7 +524,7 @@ struct drv_array *drv_query_kms(struct driver *drv) if (!found) { struct kms_item item = { .format = plane->formats[j], - .modifier = DRM_FORMAT_MOD_INVALID, + .modifier = DRM_FORMAT_MOD_LINEAR, .use_flags = use_flag }; drv_array_append(kms_items, &item); diff --git a/i915.c b/i915.c index 9b7a6fe..be315a1 100644 --- a/i915.c +++ b/i915.c @@ -63,7 +63,7 @@ static int i915_add_kms_item(struct driver *drv, const struct kms_item *item) if (combo->format != item->format) continue; - if (item->modifier == DRM_FORMAT_MOD_INVALID && + if (item->modifier == DRM_FORMAT_MOD_LINEAR && combo->metadata.tiling == I915_TILING_X) { /* * FIXME: drv_query_kms() does not report the available modifiers From 41eb166233736d70296dd6976b50384d6b057a11 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Tue, 9 Jan 2018 14:22:04 -0800 Subject: [PATCH 025/269] minigbm: remove gma500 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don't support this driver anymore. BUG=none TEST=none Change-Id: Ib9f03a48e8825e3ac1f359e8fd75a68599790a14 Reviewed-on: https://chromium-review.googlesource.com/858169 Commit-Ready: ChromeOS CL Exonerator Bot Tested-by: Gurchetan Singh Reviewed-by: Dominik Behr Reviewed-by: Stéphane Marchesin --- Android.mk | 2 -- drv.c | 2 -- gma500.c | 29 ----------------------------- 3 files changed, 33 deletions(-) delete mode 100644 gma500.c diff --git a/Android.mk b/Android.mk index bd9b9ae..a2558aa 100644 --- a/Android.mk +++ b/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. @@ -22,7 +21,6 @@ LOCAL_SRC_FILES := \ drv.c \ evdi.c \ exynos.c \ - gma500.c \ helpers.c \ i915.c \ marvell.c \ diff --git a/drv.c b/drv.c index 1f6fcab..7e12873 100644 --- a/drv.c +++ b/drv.c @@ -30,7 +30,6 @@ extern const struct backend backend_evdi; #ifdef DRV_EXYNOS extern const struct backend backend_exynos; #endif -extern const struct backend backend_gma500; #ifdef DRV_I915 extern const struct backend backend_i915; #endif @@ -78,7 +77,6 @@ static const struct backend *drv_get_backend(int fd) #ifdef DRV_EXYNOS &backend_exynos, #endif - &backend_gma500, #ifdef DRV_I915 &backend_i915, #endif diff --git a/gma500.c b/gma500.c deleted file mode 100644 index 366f232..0000000 --- a/gma500.c +++ /dev/null @@ -1,29 +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) -{ - 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_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, - .bo_unmap = drv_bo_munmap, -}; From b92e4f87bb2259062cf7edade6e7163486738243 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Thu, 22 Jun 2017 16:52:43 +0900 Subject: [PATCH 026/269] minigbm: i915: Use NV12 as the main YUV format, including camera output On SKL and newer, the display controller supports NV12 natively for overlays. Moreover it's the only output format supported by the camera subsystem. Since it shouldn't matter for other uses cases if we use NV12 or YVU420, let's just switch everything to NV12 for simplicity. BUG=b:32077885 TEST=Play a video in Android YouTube app on Cyan and Reef Change-Id: I5cfcdec2b0e2020a3ae1e8364b60df3585838807 Reviewed-on: https://chromium-review.googlesource.com/544489 Commit-Ready: Owen Lin Tested-by: Owen Lin Reviewed-by: Gurchetan Singh --- i915.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/i915.c b/i915.c index be315a1..c571c22 100644 --- a/i915.c +++ b/i915.c @@ -26,11 +26,11 @@ static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FO 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; @@ -526,10 +526,16 @@ static uint32_t i915_resolve_format(uint32_t format, uint64_t use_flags) /*HACK: See b/28671744 */ return DRM_FORMAT_XBGR8888; case DRM_FORMAT_FLEX_YCbCr_420_888: - /* KBL camera subsystem requires NV12. */ - if (use_flags & (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; } From 7f79cb53e1b38e8284f365a22c5dc9223f6ad847 Mon Sep 17 00:00:00 2001 From: Rajesh Yadav Date: Mon, 22 Jan 2018 18:29:06 +0530 Subject: [PATCH 027/269] minigbm: Add minimal buffer allocation support for msm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add minimal buffer allocation support using dumb_bo for early enablement till the minigbm backend implementation is avaialble for msm drv using gem ioctls. See CL:898422 for getting the DRV_MSM define in. BUG=chromium:795946, b:72483556 TEST=Boot and see some graphics Change-Id: Ieeb05923d756a3e4581a38cf6ce5cf406e2d197b Reviewed-on: https://chromium-review.googlesource.com/897729 Commit-Ready: Douglas Anderson Tested-by: Douglas Anderson Reviewed-by: Stéphane Marchesin --- Android.mk | 1 + drv.c | 6 ++++++ msm.c | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 msm.c diff --git a/Android.mk b/Android.mk index a2558aa..3f73fe5 100644 --- a/Android.mk +++ b/Android.mk @@ -25,6 +25,7 @@ LOCAL_SRC_FILES := \ i915.c \ marvell.c \ mediatek.c \ + msm.c \ nouveau.c \ rockchip.c \ tegra.c \ diff --git a/drv.c b/drv.c index 7e12873..6d6e4fc 100644 --- a/drv.c +++ b/drv.c @@ -39,6 +39,9 @@ extern const struct backend backend_marvell; #ifdef DRV_MEDIATEK extern const struct backend backend_mediatek; #endif +#ifdef DRV_MSM +extern const struct backend backend_msm; +#endif extern const struct backend backend_nouveau; #ifdef DRV_RADEON extern const struct backend backend_radeon; @@ -85,6 +88,9 @@ static const struct backend *drv_get_backend(int fd) #endif #ifdef DRV_MEDIATEK &backend_mediatek, +#endif +#ifdef DRV_MSM + &backend_msm, #endif &backend_nouveau, #ifdef DRV_RADEON diff --git a/msm.c b/msm.c new file mode 100644 index 0000000..4240c63 --- /dev/null +++ b/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 */ From 2b8f89e45cea5b2b06bc5cc8a3c03e156ee42285 Mon Sep 17 00:00:00 2001 From: "Kristian H. Kristensen" Date: Wed, 7 Feb 2018 16:10:06 -0800 Subject: [PATCH 028/269] i915: Always set the modifier when allocating BOs With CL:907756 we now pass modifiers around when export to and importing from the rest of Chrome and we need to give the right answer when ozone queries the modifier of a bo allocated with use flags. Bug: 809670, 809666 Change-Id: Iab5ea62d5e0da9ddd90013f559f802270de1e420 Reviewed-on: https://chromium-review.googlesource.com/907848 Commit-Ready: Kristian H. Kristensen Tested-by: Kristian H. Kristensen Reviewed-by: Gurchetan Singh --- i915.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/i915.c b/i915.c index c571c22..da22dc5 100644 --- a/i915.c +++ b/i915.c @@ -298,6 +298,8 @@ static int i915_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t h break; } + bo->format_modifiers[0] = modifier; + stride = drv_stride_from_format(format, width, 0); ret = i915_align_dimensions(bo, bo->tiling, &stride, &height); @@ -398,8 +400,6 @@ static int i915_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint32_t 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); } From adc70faad6be63d9396057fcbd90aced98d36b99 Mon Sep 17 00:00:00 2001 From: Deepak Sharma Date: Tue, 20 Feb 2018 14:58:26 -0800 Subject: [PATCH 029/269] minigbm: amdgpu: support DRM_FORMAT_YVU420_ANDROID Add support for DRM_FORMAT_YVU_420 for CTS. BUG=b:70373715 TEST=build cros-gralloc and run ctsMediaTestcases. Change-Id: I09f0a3da5ba56a5f275f33348fdb4d61e2fde7db Signed-off-by: Deepak Sharma Reviewed-on: https://chromium-review.googlesource.com/935491 Commit-Ready: Deepak Sharma Tested-by: Deepak Sharma Reviewed-by: Gurchetan Singh --- amdgpu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/amdgpu.c b/amdgpu.c index cca3537..f6c0547 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -46,7 +46,7 @@ const static uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMA DRM_FORMAT_XRGB8888 }; const static uint32_t texture_source_formats[] = { DRM_FORMAT_GR88, DRM_FORMAT_R8, DRM_FORMAT_NV21, - DRM_FORMAT_NV12 }; + DRM_FORMAT_NV12, DRM_FORMAT_YVU420_ANDROID }; static int amdgpu_set_metadata(int fd, uint32_t handle, struct amdgpu_bo_metadata *info) { @@ -359,6 +359,8 @@ static int amdgpu_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint if (format == DRM_FORMAT_NV12 || format == DRM_FORMAT_NV21) { drv_bo_from_format(bo, ALIGN(width, 64), height, format); + } else if (format == DRM_FORMAT_YVU420_ANDROID) { + drv_bo_from_format(bo, ALIGN(width, 128), height, format); } else { if (amdgpu_addrlib_compute(addrlib, width, height, format, use_flags, &tiling_flags, &addr_out) < 0) From 23e006a90b51589a7515a66777477398ee20c576 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Marchesin?= Date: Wed, 28 Feb 2018 16:37:46 -0800 Subject: [PATCH 030/269] msm: Align buffer dimensions for llvmpipe While we are using llvmpipe, we should align the buffer dimensions to a tile size. Change-Id: Ia0da10851886a2c25f8a4bff779fe890ec86baef Reviewed-on: https://chromium-review.googlesource.com/942346 Commit-Ready: Douglas Anderson Tested-by: Douglas Anderson Reviewed-by: Douglas Anderson Reviewed-by: Gurchetan Singh --- msm.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/msm.c b/msm.c index 4240c63..6e18789 100644 --- a/msm.c +++ b/msm.c @@ -10,6 +10,9 @@ #include "helpers.h" #include "util.h" +#define MESA_LLVMPIPE_TILE_ORDER 6 +#define MESA_LLVMPIPE_TILE_SIZE (1 << MESA_LLVMPIPE_TILE_ORDER) + static const uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888 }; static int msm_init(struct driver *drv) @@ -20,10 +23,23 @@ static int msm_init(struct driver *drv) return drv_modify_linear_combinations(drv); } +static int msm_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint64_t flags) +{ + width = ALIGN(width, MESA_LLVMPIPE_TILE_SIZE); + height = ALIGN(height, MESA_LLVMPIPE_TILE_SIZE); + + /* HAL_PIXEL_FORMAT_YV12 requires that the buffer's height not be aligned. */ + if (bo->format == DRM_FORMAT_YVU420_ANDROID) + height = bo->height; + + return drv_dumb_bo_create(bo, width, height, format, flags); +} + const struct backend backend_msm = { .name = "msm", .init = msm_init, - .bo_create = drv_dumb_bo_create, + .bo_create = msm_bo_create, .bo_destroy = drv_dumb_bo_destroy, .bo_import = drv_prime_bo_import, .bo_map = drv_dumb_bo_map, From 6eca36809e185337bfcca95310a1765c34c360e1 Mon Sep 17 00:00:00 2001 From: Sergey Volk Date: Tue, 6 Mar 2018 13:29:32 -0800 Subject: [PATCH 031/269] Rename amlogic backend in minigbm into meson The name of Amlogic DRM driver in kernel is "meson", so rename it in minigbm to match that. BUG=internal b/74248568 TEST=run ozone_demo on device Change-Id: If2ef376715231f0b3c9fe320177d0e82d94214f0 Reviewed-on: https://chromium-review.googlesource.com/951912 Reviewed-by: Gurchetan Singh Reviewed-by: Alex Sakhartchouk Tested-by: Sergey Volk --- Android.mk | 2 +- Makefile | 6 +++--- drv.c | 12 ++++++------ amlogic.c => meson.c | 10 +++++----- 4 files changed, 15 insertions(+), 15 deletions(-) rename amlogic.c => meson.c (82%) diff --git a/Android.mk b/Android.mk index 3f73fe5..28176d2 100644 --- a/Android.mk +++ b/Android.mk @@ -16,7 +16,6 @@ LOCAL_SHARED_LIBRARIES := \ LOCAL_SRC_FILES := \ amdgpu.c \ - amlogic.c \ cirrus.c \ drv.c \ evdi.c \ @@ -25,6 +24,7 @@ LOCAL_SRC_FILES := \ i915.c \ marvell.c \ mediatek.c \ + meson.c \ msm.c \ nouveau.c \ rockchip.c \ diff --git a/Makefile b/Makefile index a01433e..358cd7b 100644 --- a/Makefile +++ b/Makefile @@ -16,15 +16,15 @@ 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 ifdef DRV_I915 CFLAGS += $(shell $(PKG_CONFIG) --cflags libdrm_intel) endif +ifdef DRV_MESON + CFLAGS += $(shell $(PKG_CONFIG) --cflags libdrm_meson) +endif ifdef DRV_RADEON CFLAGS += $(shell $(PKG_CONFIG) --cflags libdrm_radeon) endif diff --git a/drv.c b/drv.c index 6d6e4fc..d548448 100644 --- a/drv.c +++ b/drv.c @@ -23,9 +23,6 @@ #ifdef DRV_AMDGPU extern const struct backend backend_amdgpu; #endif -#ifdef DRV_AMLOGIC -extern const struct backend backend_amlogic; -#endif extern const struct backend backend_evdi; #ifdef DRV_EXYNOS extern const struct backend backend_exynos; @@ -39,6 +36,9 @@ extern const struct backend backend_marvell; #ifdef DRV_MEDIATEK extern const struct backend backend_mediatek; #endif +#ifdef DRV_MESON +extern const struct backend backend_meson; +#endif #ifdef DRV_MSM extern const struct backend backend_msm; #endif @@ -72,9 +72,6 @@ static const struct backend *drv_get_backend(int fd) const struct backend *backend_list[] = { #ifdef DRV_AMDGPU &backend_amdgpu, -#endif -#ifdef DRV_AMLOGIC - &backend_amlogic, #endif &backend_evdi, #ifdef DRV_EXYNOS @@ -89,6 +86,9 @@ static const struct backend *drv_get_backend(int fd) #ifdef DRV_MEDIATEK &backend_mediatek, #endif +#ifdef DRV_MESON + &backend_meson, +#endif #ifdef DRV_MSM &backend_msm, #endif diff --git a/amlogic.c b/meson.c similarity index 82% rename from amlogic.c rename to meson.c index 5609ae8..523bf71 100644 --- a/amlogic.c +++ b/meson.c @@ -4,7 +4,7 @@ * found in the LICENSE file. */ -#ifdef DRV_AMLOGIC +#ifdef DRV_MESON #include "drv_priv.h" #include "helpers.h" @@ -12,7 +12,7 @@ static const uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888 }; -static int amlogic_init(struct driver *drv) +static int meson_init(struct driver *drv) { drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), &LINEAR_METADATA, BO_USE_RENDER_MASK); @@ -20,9 +20,9 @@ static int amlogic_init(struct driver *drv) return drv_modify_linear_combinations(drv); } -const struct backend backend_amlogic = { - .name = "amlogic", - .init = amlogic_init, +const struct backend backend_meson = { + .name = "meson", + .init = meson_init, .bo_create = drv_dumb_bo_create, .bo_destroy = drv_dumb_bo_destroy, .bo_import = drv_prime_bo_import, From 3381588d35f78e1c1d3f3fac3927f3cde9462e66 Mon Sep 17 00:00:00 2001 From: Tao Wu Date: Mon, 12 Mar 2018 18:07:43 -0700 Subject: [PATCH 032/269] minigbm: virtio_gpu: set vma->length when mmap. Othewise bo_unmap won't work. Also add a ifdef guard for PAGE_SIZE to make it also compile under ARC++. BUG=b:70179880 TEST=Run /usr/local/autotest/bin/screenshot.py with qemu+virgl TEST=Run Android App under ARC++ with qemu+virgl Change-Id: I586446c56da091dd82d9bc9c1010d9b4ee4d92ee Reviewed-on: https://chromium-review.googlesource.com/959527 Commit-Ready: Lepton Wu Tested-by: Lepton Wu Reviewed-by: Gurchetan Singh --- virtio_virgl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/virtio_virgl.c b/virtio_virgl.c index b33677b..d5429bd 100644 --- a/virtio_virgl.c +++ b/virtio_virgl.c @@ -19,7 +19,9 @@ #include "util.h" #include "virgl_hw.h" +#ifndef PAGE_SIZE #define PAGE_SIZE 0x1000 +#endif #define PIPE_TEXTURE_2D 2 static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, @@ -139,6 +141,7 @@ static void *virgl_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t return MAP_FAILED; } + vma->length = bo->total_size; return mmap(0, bo->total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, gem_map.offset); } From a50131a7102a5dcc762b943757238a2ee3346f35 Mon Sep 17 00:00:00 2001 From: Alistair Strachan Date: Mon, 19 Mar 2018 14:04:23 -0700 Subject: [PATCH 033/269] Build fix for older libdrm versions. When building against an older libdrm, the DRM_FORMAT_MOD_LINEAR enum will be missing. It's OK to use DRM_FORMAT_MOD_NONE instead, because this older libdrm has limited DRM_FORMAT_MOD_xx support and not all of the backends actually need it. Change-Id: I0c289c50de4ad1fe5a9b0848961f5bcb75bd4bf8 Reviewed-on: https://chromium-review.googlesource.com/971358 Commit-Ready: ChromeOS CL Exonerator Bot Tested-by: Alistair Strachan Reviewed-by: Gurchetan Singh --- drv_priv.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drv_priv.h b/drv_priv.h index 21c003b..e2bb019 100644 --- a/drv_priv.h +++ b/drv_priv.h @@ -92,6 +92,10 @@ struct backend { #define BO_USE_SW_RARELY BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY +#ifndef DRM_FORMAT_MOD_LINEAR +#define DRM_FORMAT_MOD_LINEAR DRM_FORMAT_MOD_NONE +#endif + #define LINEAR_METADATA (struct format_metadata) { 0, 1, DRM_FORMAT_MOD_LINEAR } // clang-format on From 5932c4ca81d5b2c64ea1878b7e1f095aa888ab07 Mon Sep 17 00:00:00 2001 From: Alistair Strachan Date: Mon, 19 Mar 2018 14:06:39 -0700 Subject: [PATCH 034/269] Fix the build against AOSP master. Clear out some bitrot and use the new mechanism for including headers. Change-Id: I3b74a5472209c7632e7aab757ef88365141c9525 Reviewed-on: https://chromium-review.googlesource.com/971359 Commit-Ready: Alistair Strachan Tested-by: Alistair Strachan Reviewed-by: Gurchetan Singh --- Android.mk | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Android.mk b/Android.mk index 28176d2..422548e 100644 --- a/Android.mk +++ b/Android.mk @@ -16,10 +16,10 @@ LOCAL_SHARED_LIBRARIES := \ LOCAL_SRC_FILES := \ amdgpu.c \ - cirrus.c \ drv.c \ evdi.c \ exynos.c \ + helpers_array.c \ helpers.c \ i915.c \ marvell.c \ @@ -27,12 +27,14 @@ LOCAL_SRC_FILES := \ meson.c \ msm.c \ nouveau.c \ + radeon.c \ rockchip.c \ tegra.c \ udl.c \ vc4.c \ vgem.c \ - virtio_gpu.c + virtio_dumb.c \ + virtio_virgl.c include $(MINIGBM_GRALLOC_MK) @@ -54,6 +56,7 @@ LOCAL_PROPRIETARY_MODULE := true LOCAL_MODULE_RELATIVE_PATH := hw LOCAL_MODULE_CLASS := SHARED_LIBRARIES LOCAL_MODULE_SUFFIX := $(TARGET_SHLIB_SUFFIX) +LOCAL_SHARED_LIBRARIES += libnativewindow libsync liblog include $(BUILD_SHARED_LIBRARY) -#endif +endif From f048a1e32c84ae51ef29f8154aff6cae3c39ad27 Mon Sep 17 00:00:00 2001 From: Alistair Strachan Date: Tue, 20 Mar 2018 11:10:51 -0700 Subject: [PATCH 035/269] Fix minigbm against older kernel DRM versions. In 4.4, the DRM implementation only allowed DRM_CLOEXEC to be specified to drmPrimeHandleToFD(), but it gave you a read/write mapping when mmap'ed. In newer kernels the DRM_RDWR flag needs to be specified to get a read/write mapping. Try the new way, and if that fails, try the old way. If the handle conversion fails for any reason other than this flag check, it'll still fail. Change-Id: I7fabb6a0d23e7b9b70f970aad0bc243a76583e33 Reviewed-on: https://chromium-review.googlesource.com/971461 Commit-Ready: Alistair Strachan Tested-by: Alistair Strachan Reviewed-by: Gurchetan Singh --- drv.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drv.c b/drv.c index d548448..4dca8e1 100644 --- a/drv.c +++ b/drv.c @@ -555,6 +555,10 @@ int drv_bo_get_plane_fd(struct bo *bo, size_t plane) ret = drmPrimeHandleToFD(bo->drv->fd, bo->handles[plane].u32, DRM_CLOEXEC | DRM_RDWR, &fd); + // Older DRM implementations blocked DRM_RDWR, but gave a read/write mapping anyways + if (ret) + ret = drmPrimeHandleToFD(bo->drv->fd, bo->handles[plane].u32, DRM_CLOEXEC, &fd); + return (ret) ? ret : fd; } From ce717c50960d8b2005bfe7e7654807b3ae4479ab Mon Sep 17 00:00:00 2001 From: Alistair Strachan Date: Tue, 20 Mar 2018 15:55:20 -0700 Subject: [PATCH 036/269] Android: Support building the virtio_virgl backend. Enabled automatically if BOARD_GPU_DRIVERS=virgl. If you leave this unset, the build will still include support for virtio_dumb. Change-Id: I2cfeab8fb3a0be7b3c1874fa036d433ff57567cd Reviewed-on: https://chromium-review.googlesource.com/972449 Commit-Ready: Alistair Strachan Tested-by: Alistair Strachan Reviewed-by: Gurchetan Singh --- Android.mk | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Android.mk b/Android.mk index 422548e..2f3f519 100644 --- a/Android.mk +++ b/Android.mk @@ -49,6 +49,11 @@ LOCAL_CFLAGS += -DDRV_I915 LOCAL_SHARED_LIBRARIES += libdrm_intel endif +ifneq ($(filter virgl, $(BOARD_GPU_DRIVERS)),) +LOCAL_CPPFLAGS += -DDRV_VIRGL +LOCAL_CFLAGS += -DDRV_VIRGL +endif + LOCAL_MODULE := gralloc.$(TARGET_BOARD_PLATFORM) LOCAL_MODULE_TAGS := optional # The preferred path for vendor HALs is /vendor/lib/hw From 0cfaaa5adb3e973a9ce5453b55a3177e3962c158 Mon Sep 17 00:00:00 2001 From: Alistair Strachan Date: Mon, 19 Mar 2018 14:03:23 -0700 Subject: [PATCH 037/269] Use Android log system in helpers.c. This code might be loaded by a daemonized process now, so the existing logging to stderr goes nowhere. It's better to use the Android logger. Change-Id: I19f088b8f049f07c9c6839038d2971fad1a0e852 Reviewed-on: https://chromium-review.googlesource.com/971360 Commit-Ready: Alistair Strachan Tested-by: Alistair Strachan Reviewed-by: Alistair Strachan Reviewed-by: Gurchetan Singh --- amdgpu.c | 6 +++--- cros_gralloc/cros_gralloc_buffer.cc | 6 +++--- cros_gralloc/cros_gralloc_driver.cc | 24 ++++++++++++------------ cros_gralloc/cros_gralloc_helpers.cc | 19 +++---------------- cros_gralloc/cros_gralloc_helpers.h | 8 -------- cros_gralloc/gralloc0/gralloc0.cc | 22 +++++++++++----------- drv.c | 27 ++++++++++++++++++++++++--- drv.h | 8 ++++++++ exynos.c | 7 +++---- helpers.c | 16 +++++++--------- i915.c | 19 +++++++++---------- mediatek.c | 5 ++--- msm.c | 2 +- rockchip.c | 7 +++---- tegra.c | 6 +++--- vc4.c | 5 ++--- virtio_virgl.c | 10 ++++------ 17 files changed, 98 insertions(+), 99 deletions(-) diff --git a/amdgpu.c b/amdgpu.c index f6c0547..e196d28 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -235,7 +235,7 @@ static void *amdgpu_addrlib_init(int fd) ret = amdgpu_query_gpu(fd, &gpu_info); if (ret) { - fprintf(stderr, "[%s]failed with error =%d\n", __func__, ret); + drv_log("failed with error =%d\n", ret); return NULL; } @@ -264,7 +264,7 @@ static void *amdgpu_addrlib_init(int fd) addr_ret = AddrCreate(&addr_create_input, &addr_create_output); if (addr_ret != ADDR_OK) { - fprintf(stderr, "[%s]failed error =%d\n", __func__, addr_ret); + drv_log("failed error =%d\n", addr_ret); return NULL; } @@ -419,7 +419,7 @@ static void *amdgpu_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_ ret = drmIoctl(bo->drv->fd, DRM_IOCTL_AMDGPU_GEM_MMAP, &gem_map); if (ret) { - fprintf(stderr, "drv: DRM_IOCTL_AMDGPU_GEM_MMAP failed\n"); + drv_log("DRM_IOCTL_AMDGPU_GEM_MMAP failed\n"); return MAP_FAILED; } diff --git a/cros_gralloc/cros_gralloc_buffer.cc b/cros_gralloc/cros_gralloc_buffer.cc index 47a13a2..40a2083 100644 --- a/cros_gralloc/cros_gralloc_buffer.cc +++ b/cros_gralloc/cros_gralloc_buffer.cc @@ -56,7 +56,7 @@ int32_t cros_gralloc_buffer::lock(const struct rectangle *rect, uint32_t map_fla * just use the first kernel buffer. */ if (drv_num_buffers_per_bo(bo_) != 1) { - cros_gralloc_error("Can only support one buffer per bo."); + drv_log("Can only support one buffer per bo.\n"); return -EINVAL; } @@ -69,7 +69,7 @@ int32_t cros_gralloc_buffer::lock(const struct rectangle *rect, uint32_t map_fla } if (vaddr == MAP_FAILED) { - cros_gralloc_error("Mapping failed."); + drv_log("Mapping failed.\n"); return -EFAULT; } } @@ -84,7 +84,7 @@ int32_t cros_gralloc_buffer::lock(const struct rectangle *rect, uint32_t map_fla int32_t cros_gralloc_buffer::unlock() { if (lockcount_ <= 0) { - cros_gralloc_error("Buffer was not locked."); + drv_log("Buffer was not locked.\n"); return -EINVAL; } diff --git a/cros_gralloc/cros_gralloc_driver.cc b/cros_gralloc/cros_gralloc_driver.cc index fec4aba..9e8d98f 100644 --- a/cros_gralloc/cros_gralloc_driver.cc +++ b/cros_gralloc/cros_gralloc_driver.cc @@ -98,7 +98,7 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto bo = drv_bo_create(drv_, descriptor->width, descriptor->height, resolved_format, descriptor->use_flags); if (!bo) { - cros_gralloc_error("Failed to create bo."); + drv_log("Failed to create bo.\n"); return -ENOMEM; } @@ -109,7 +109,7 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto */ if (drv_num_buffers_per_bo(bo) != 1) { drv_bo_destroy(bo); - cros_gralloc_error("Can only support one buffer per bo."); + drv_log("Can only support one buffer per bo.\n"); return -EINVAL; } @@ -157,7 +157,7 @@ int32_t cros_gralloc_driver::retain(buffer_handle_t handle) auto hnd = cros_gralloc_convert_handle(handle); if (!hnd) { - cros_gralloc_error("Invalid handle."); + drv_log("Invalid handle.\n"); return -EINVAL; } @@ -169,7 +169,7 @@ int32_t cros_gralloc_driver::retain(buffer_handle_t handle) } if (drmPrimeFDToHandle(drv_get_fd(drv_), hnd->fds[0], &id)) { - cros_gralloc_error("drmPrimeFDToHandle failed."); + drv_log("drmPrimeFDToHandle failed.\n"); return -errno; } @@ -214,13 +214,13 @@ int32_t cros_gralloc_driver::release(buffer_handle_t handle) auto hnd = cros_gralloc_convert_handle(handle); if (!hnd) { - cros_gralloc_error("Invalid handle."); + drv_log("Invalid handle.\n"); return -EINVAL; } auto buffer = get_buffer(hnd); if (!buffer) { - cros_gralloc_error("Invalid Reference."); + drv_log("Invalid Reference.\n"); return -EINVAL; } @@ -246,13 +246,13 @@ int32_t cros_gralloc_driver::lock(buffer_handle_t handle, int32_t acquire_fence, std::lock_guard lock(mutex_); auto hnd = cros_gralloc_convert_handle(handle); if (!hnd) { - cros_gralloc_error("Invalid handle."); + drv_log("Invalid handle.\n"); return -EINVAL; } auto buffer = get_buffer(hnd); if (!buffer) { - cros_gralloc_error("Invalid Reference."); + drv_log("Invalid Reference.\n"); return -EINVAL; } @@ -265,13 +265,13 @@ int32_t cros_gralloc_driver::unlock(buffer_handle_t handle, int32_t *release_fen auto hnd = cros_gralloc_convert_handle(handle); if (!hnd) { - cros_gralloc_error("Invalid handle."); + drv_log("Invalid handle.\n"); return -EINVAL; } auto buffer = get_buffer(hnd); if (!buffer) { - cros_gralloc_error("Invalid Reference."); + drv_log("Invalid Reference.\n"); return -EINVAL; } @@ -291,13 +291,13 @@ int32_t cros_gralloc_driver::get_backing_store(buffer_handle_t handle, uint64_t auto hnd = cros_gralloc_convert_handle(handle); if (!hnd) { - cros_gralloc_error("Invalid handle."); + drv_log("Invalid handle.\n"); return -EINVAL; } auto buffer = get_buffer(hnd); if (!buffer) { - cros_gralloc_error("Invalid Reference."); + drv_log("Invalid Reference.\n"); return -EINVAL; } diff --git a/cros_gralloc/cros_gralloc_helpers.cc b/cros_gralloc/cros_gralloc_helpers.cc index e662084..c09c2b5 100644 --- a/cros_gralloc/cros_gralloc_helpers.cc +++ b/cros_gralloc/cros_gralloc_helpers.cc @@ -6,8 +6,6 @@ #include "cros_gralloc_helpers.h" -#include -#include #include uint32_t cros_gralloc_convert_format(int format) @@ -66,30 +64,19 @@ int32_t cros_gralloc_sync_wait(int32_t acquire_fence) */ int err = sync_wait(acquire_fence, 1000); if (err < 0) { - cros_gralloc_error("Timed out on sync wait, err = %s", strerror(errno)); + drv_log("Timed out on sync wait, err = %s\n", strerror(errno)); err = sync_wait(acquire_fence, -1); if (err < 0) { - cros_gralloc_error("sync wait error = %s", strerror(errno)); + drv_log("sync wait error = %s\n", strerror(errno)); return -errno; } } err = close(acquire_fence); if (err) { - cros_gralloc_error("Unable to close fence fd, err = %s", strerror(errno)); + drv_log("Unable to close fence fd, err = %s\n", strerror(errno)); return -errno; } return 0; } - -void cros_gralloc_log(const char *prefix, const char *file, int line, const char *format, ...) -{ - char buf[50]; - snprintf(buf, sizeof(buf), "[%s:%s(%d)]", prefix, basename(file), line); - - va_list args; - va_start(args, format); - __android_log_vprint(ANDROID_LOG_ERROR, buf, format, args); - va_end(args); -} diff --git a/cros_gralloc/cros_gralloc_helpers.h b/cros_gralloc/cros_gralloc_helpers.h index cf90ec8..a55eebc 100644 --- a/cros_gralloc/cros_gralloc_helpers.h +++ b/cros_gralloc/cros_gralloc_helpers.h @@ -24,12 +24,4 @@ cros_gralloc_handle_t cros_gralloc_convert_handle(buffer_handle_t handle); int32_t cros_gralloc_sync_wait(int32_t acquire_fence); -__attribute__((format(printf, 4, 5))) void cros_gralloc_log(const char *prefix, const char *file, - int line, const char *format, ...); - -#define cros_gralloc_error(...) \ - do { \ - cros_gralloc_log("CROS_GRALLOC_ERROR", __FILE__, __LINE__, __VA_ARGS__); \ - } while (0) - #endif diff --git a/cros_gralloc/gralloc0/gralloc0.cc b/cros_gralloc/gralloc0/gralloc0.cc index 50cd1af..86c3a4e 100644 --- a/cros_gralloc/gralloc0/gralloc0.cc +++ b/cros_gralloc/gralloc0/gralloc0.cc @@ -113,10 +113,10 @@ static int gralloc0_alloc(alloc_device_t *dev, int w, int h, int format, int usa } if (!supported) { - cros_gralloc_error("Unsupported combination -- HAL format: %u, HAL usage: %u, " - "drv_format: %4.4s, use_flags: %llu", - format, usage, reinterpret_cast(&descriptor.drm_format), - static_cast(descriptor.use_flags)); + drv_log("Unsupported combination -- HAL format: %u, HAL usage: %u, " + "drv_format: %4.4s, use_flags: %llu\n", + format, usage, reinterpret_cast(&descriptor.drm_format), + static_cast(descriptor.use_flags)); return -EINVAL; } @@ -151,7 +151,7 @@ static int gralloc0_init(struct gralloc0_module *mod, bool initialize_alloc) mod->driver = std::make_unique(); if (mod->driver->init()) { - cros_gralloc_error("Failed to initialize driver."); + drv_log("Failed to initialize driver.\n"); return -ENODEV; } @@ -179,7 +179,7 @@ static int gralloc0_open(const struct hw_module_t *mod, const char *name, struct } if (strcmp(name, GRALLOC_HARDWARE_GPU0)) { - cros_gralloc_error("Incorrect device name - %s.", name); + drv_log("Incorrect device name - %s.\n", name); return -EINVAL; } @@ -253,7 +253,7 @@ static int gralloc0_perform(struct gralloc_module_t const *module, int op, ...) handle = va_arg(args, buffer_handle_t); auto hnd = cros_gralloc_convert_handle(handle); if (!hnd) { - cros_gralloc_error("Invalid handle."); + drv_log("Invalid handle.\n"); return -EINVAL; } @@ -305,12 +305,12 @@ static int gralloc0_lock_async(struct gralloc_module_t const *module, buffer_han auto hnd = cros_gralloc_convert_handle(handle); if (!hnd) { - cros_gralloc_error("Invalid handle."); + drv_log("Invalid handle.\n"); return -EINVAL; } if (hnd->droid_format == HAL_PIXEL_FORMAT_YCbCr_420_888) { - cros_gralloc_error("HAL_PIXEL_FORMAT_YCbCr_*_888 format not compatible."); + drv_log("HAL_PIXEL_FORMAT_YCbCr_*_888 format not compatible.\n"); return -EINVAL; } @@ -347,14 +347,14 @@ static int gralloc0_lock_async_ycbcr(struct gralloc_module_t const *module, buff auto hnd = cros_gralloc_convert_handle(handle); if (!hnd) { - cros_gralloc_error("Invalid handle."); + drv_log("Invalid handle.\n"); return -EINVAL; } if ((hnd->droid_format != HAL_PIXEL_FORMAT_YCbCr_420_888) && (hnd->droid_format != HAL_PIXEL_FORMAT_YV12) && (hnd->droid_format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)) { - cros_gralloc_error("Non-YUV format not compatible."); + drv_log("Non-YUV format not compatible.\n"); return -EINVAL; } diff --git a/drv.c b/drv.c index 4dca8e1..c7ac816 100644 --- a/drv.c +++ b/drv.c @@ -16,6 +16,11 @@ #include #include +#ifdef __ANDROID__ +#include +#include +#endif + #include "drv_priv.h" #include "helpers.h" #include "util.h" @@ -362,7 +367,7 @@ struct bo *drv_bo_import(struct driver *drv, struct drv_import_fd_data *data) 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)); + drv_log("lseek() failed with %s\n", strerror(errno)); goto destroy_bo; } @@ -373,7 +378,7 @@ struct bo *drv_bo_import(struct driver *drv, struct drv_import_fd_data *data) 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"); + drv_log("buffer size is too large.\n"); goto destroy_bo; } @@ -658,7 +663,7 @@ size_t drv_num_planes_from_format(uint32_t format) return 3; } - fprintf(stderr, "drv: UNKNOWN FORMAT %d\n", format); + drv_log("UNKNOWN FORMAT %d\n", format); return 0; } @@ -677,3 +682,19 @@ uint32_t drv_num_buffers_per_bo(struct bo *bo) return count; } + +void drv_log_prefix(const char *prefix, const char *file, int line, const char *format, ...) +{ + char buf[50]; + snprintf(buf, sizeof(buf), "[%s:%s(%d)]", prefix, basename(file), line); + + va_list args; + va_start(args, format); +#ifdef __ANDROID__ + __android_log_vprint(ANDROID_LOG_ERROR, buf, format, args); +#else + fprintf(stderr, "%s ", buf); + vfprintf(stderr, format, args); +#endif + va_end(args); +} diff --git a/drv.h b/drv.h index 18653e5..2271a9f 100644 --- a/drv.h +++ b/drv.h @@ -164,6 +164,14 @@ size_t drv_num_planes_from_format(uint32_t format); uint32_t drv_num_buffers_per_bo(struct bo *bo); +#define drv_log(format, ...) \ + do { \ + drv_log_prefix("minigbm", __FILE__, __LINE__, format, ##__VA_ARGS__); \ + } while (0) + +__attribute__((format(printf, 4, 5))) void drv_log_prefix(const char *prefix, const char *file, + int line, const char *format, ...); + #ifdef __cplusplus } #endif diff --git a/exynos.c b/exynos.c index 526603e..cf95b38 100644 --- a/exynos.c +++ b/exynos.c @@ -56,7 +56,7 @@ static int exynos_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint bo->total_size = bo->sizes[0] = height * bo->strides[0]; bo->offsets[0] = 0; } else { - fprintf(stderr, "drv: unsupported format %X\n", format); + drv_log("unsupported format %X\n", format); assert(0); return -EINVAL; } @@ -72,8 +72,7 @@ static int exynos_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint ret = drmIoctl(bo->drv->fd, DRM_IOCTL_EXYNOS_GEM_CREATE, &gem_create); if (ret) { - fprintf(stderr, "drv: DRM_IOCTL_EXYNOS_GEM_CREATE failed (size=%zu)\n", - size); + drv_log("DRM_IOCTL_EXYNOS_GEM_CREATE failed (size=%zu)\n", size); goto cleanup_planes; } @@ -89,7 +88,7 @@ static int exynos_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint gem_close.handle = bo->handles[plane - 1].u32; int gem_close_ret = drmIoctl(bo->drv->fd, DRM_IOCTL_GEM_CLOSE, &gem_close); if (gem_close_ret) { - fprintf(stderr, "drv: DRM_IOCTL_GEM_CLOSE failed: %d\n", gem_close_ret); + drv_log("DRM_IOCTL_GEM_CLOSE failed: %d\n", gem_close_ret); } } diff --git a/helpers.c b/helpers.c index 6c26e54..94b0d65 100644 --- a/helpers.c +++ b/helpers.c @@ -100,7 +100,7 @@ static uint32_t bpp_from_format(uint32_t format, size_t plane) return 32; } - fprintf(stderr, "drv: UNKNOWN FORMAT %d\n", format); + drv_log("UNKNOWN FORMAT %d\n", format); return 0; } @@ -211,7 +211,7 @@ int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t ret = drmIoctl(bo->drv->fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb); if (ret) { - fprintf(stderr, "drv: DRM_IOCTL_MODE_CREATE_DUMB failed\n"); + drv_log("DRM_IOCTL_MODE_CREATE_DUMB failed (%d, %d)\n", bo->drv->fd, errno); return ret; } @@ -234,8 +234,7 @@ int drv_dumb_bo_destroy(struct bo *bo) ret = drmIoctl(bo->drv->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_dumb); if (ret) { - fprintf(stderr, "drv: DRM_IOCTL_MODE_DESTROY_DUMB failed (handle=%x)\n", - bo->handles[0].u32); + drv_log("DRM_IOCTL_MODE_DESTROY_DUMB failed (handle=%x)\n", bo->handles[0].u32); return ret; } @@ -261,7 +260,7 @@ int drv_gem_bo_destroy(struct bo *bo) ret = drmIoctl(bo->drv->fd, DRM_IOCTL_GEM_CLOSE, &gem_close); if (ret) { - fprintf(stderr, "drv: DRM_IOCTL_GEM_CLOSE failed (handle=%x) error %d\n", + drv_log("DRM_IOCTL_GEM_CLOSE failed (handle=%x) error %d\n", bo->handles[plane].u32, ret); error = ret; } @@ -283,8 +282,7 @@ int drv_prime_bo_import(struct bo *bo, struct drv_import_fd_data *data) ret = drmIoctl(bo->drv->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &prime_handle); if (ret) { - fprintf(stderr, "drv: DRM_IOCTL_PRIME_FD_TO_HANDLE failed (fd=%u)\n", - prime_handle.fd); + drv_log("DRM_IOCTL_PRIME_FD_TO_HANDLE failed (fd=%u)\n", prime_handle.fd); /* * Need to call GEM close on planes that were opened, @@ -320,7 +318,7 @@ void *drv_dumb_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map ret = drmIoctl(bo->drv->fd, DRM_IOCTL_MODE_MAP_DUMB, &map_dumb); if (ret) { - fprintf(stderr, "drv: DRM_IOCTL_MODE_MAP_DUMB failed \n"); + drv_log("DRM_IOCTL_MODE_MAP_DUMB failed\n"); return MAP_FAILED; } @@ -361,7 +359,7 @@ int drv_mapping_destroy(struct bo *bo) if (!--mapping->vma->refcount) { ret = bo->drv->backend->bo_unmap(bo, mapping->vma); if (ret) { - fprintf(stderr, "drv: munmap failed"); + drv_log("munmap failed\n"); return ret; } diff --git a/i915.c b/i915.c index da22dc5..cf5a7fd 100644 --- a/i915.c +++ b/i915.c @@ -255,7 +255,7 @@ static int i915_init(struct driver *drv) get_param.value = &device_id; ret = drmIoctl(drv->fd, DRM_IOCTL_I915_GETPARAM, &get_param); if (ret) { - fprintf(stderr, "drv: Failed to get I915_PARAM_CHIPSET_ID\n"); + drv_log("Failed to get I915_PARAM_CHIPSET_ID\n"); free(i915); return -EINVAL; } @@ -267,7 +267,7 @@ static int i915_init(struct driver *drv) get_param.value = &i915->has_llc; ret = drmIoctl(drv->fd, DRM_IOCTL_I915_GETPARAM, &get_param); if (ret) { - fprintf(stderr, "drv: Failed to get I915_PARAM_HAS_LLC\n"); + drv_log("Failed to get I915_PARAM_HAS_LLC\n"); free(i915); return -EINVAL; } @@ -349,8 +349,7 @@ static int i915_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t h ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_CREATE, &gem_create); if (ret) { - fprintf(stderr, "drv: DRM_IOCTL_I915_GEM_CREATE failed (size=%llu)\n", - gem_create.size); + drv_log("DRM_IOCTL_I915_GEM_CREATE failed (size=%llu)\n", gem_create.size); return ret; } @@ -369,7 +368,7 @@ static int i915_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t h gem_close.handle = bo->handles[0].u32; drmIoctl(bo->drv->fd, DRM_IOCTL_GEM_CLOSE, &gem_close); - fprintf(stderr, "drv: DRM_IOCTL_I915_GEM_SET_TILING failed with %d", errno); + drv_log("DRM_IOCTL_I915_GEM_SET_TILING failed with %d\n", errno); return -errno; } @@ -425,7 +424,7 @@ static int i915_bo_import(struct bo *bo, struct drv_import_fd_data *data) ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_GET_TILING, &gem_get_tiling); if (ret) { drv_gem_bo_destroy(bo); - fprintf(stderr, "drv: DRM_IOCTL_I915_GEM_GET_TILING failed."); + drv_log("DRM_IOCTL_I915_GEM_GET_TILING failed.\n"); return ret; } @@ -451,7 +450,7 @@ static void *i915_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_MMAP, &gem_map); if (ret) { - fprintf(stderr, "drv: DRM_IOCTL_I915_GEM_MMAP failed\n"); + drv_log("DRM_IOCTL_I915_GEM_MMAP failed\n"); return MAP_FAILED; } @@ -464,7 +463,7 @@ static void *i915_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_MMAP_GTT, &gem_map); if (ret) { - fprintf(stderr, "drv: DRM_IOCTL_I915_GEM_MMAP_GTT failed\n"); + drv_log("DRM_IOCTL_I915_GEM_MMAP_GTT failed\n"); return MAP_FAILED; } @@ -473,7 +472,7 @@ static void *i915_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t } if (addr == MAP_FAILED) { - fprintf(stderr, "drv: i915 GEM mmap failed\n"); + drv_log("i915 GEM mmap failed\n"); return addr; } @@ -500,7 +499,7 @@ static int i915_bo_invalidate(struct bo *bo, struct mapping *mapping) ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain); if (ret) { - fprintf(stderr, "drv: DRM_IOCTL_I915_GEM_SET_DOMAIN with %d\n", ret); + drv_log("DRM_IOCTL_I915_GEM_SET_DOMAIN with %d\n", ret); return ret; } diff --git a/mediatek.c b/mediatek.c index 7614004..cfb60b3 100644 --- a/mediatek.c +++ b/mediatek.c @@ -62,8 +62,7 @@ static int mediatek_bo_create(struct bo *bo, uint32_t width, uint32_t height, ui ret = drmIoctl(bo->drv->fd, DRM_IOCTL_MTK_GEM_CREATE, &gem_create); if (ret) { - fprintf(stderr, "drv: DRM_IOCTL_MTK_GEM_CREATE failed (size=%llu)\n", - gem_create.size); + drv_log("DRM_IOCTL_MTK_GEM_CREATE failed (size=%llu)\n", gem_create.size); return ret; } @@ -84,7 +83,7 @@ static void *mediatek_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint3 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_MTK_GEM_MAP_OFFSET, &gem_map); if (ret) { - fprintf(stderr, "drv: DRM_IOCTL_MTK_GEM_MAP_OFFSET failed\n"); + drv_log("DRM_IOCTL_MTK_GEM_MAP_OFFSET failed\n"); return MAP_FAILED; } diff --git a/msm.c b/msm.c index 6e18789..fe09de0 100644 --- a/msm.c +++ b/msm.c @@ -24,7 +24,7 @@ static int msm_init(struct driver *drv) } static int msm_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, - uint64_t flags) + uint64_t flags) { width = ALIGN(width, MESA_LLVMPIPE_TILE_SIZE); height = ALIGN(height, MESA_LLVMPIPE_TILE_SIZE); diff --git a/rockchip.c b/rockchip.c index ac17dbd..a0d9141 100644 --- a/rockchip.c +++ b/rockchip.c @@ -186,7 +186,7 @@ static int rockchip_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint } else { if (!has_modifier(modifiers, count, DRM_FORMAT_MOD_LINEAR)) { errno = EINVAL; - fprintf(stderr, "no usable modifier found\n"); + drv_log("no usable modifier found\n"); return -1; } @@ -212,8 +212,7 @@ static int rockchip_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint ret = drmIoctl(bo->drv->fd, DRM_IOCTL_ROCKCHIP_GEM_CREATE, &gem_create); if (ret) { - fprintf(stderr, "drv: DRM_IOCTL_ROCKCHIP_GEM_CREATE failed (size=%llu)\n", - gem_create.size); + drv_log("DRM_IOCTL_ROCKCHIP_GEM_CREATE failed (size=%llu)\n", gem_create.size); return ret; } @@ -247,7 +246,7 @@ static void *rockchip_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint3 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_ROCKCHIP_GEM_MAP_OFFSET, &gem_map); if (ret) { - fprintf(stderr, "drv: DRM_IOCTL_ROCKCHIP_GEM_MAP_OFFSET failed\n"); + drv_log("DRM_IOCTL_ROCKCHIP_GEM_MAP_OFFSET failed\n"); return MAP_FAILED; } diff --git a/tegra.c b/tegra.c index f0651d7..fb2f6a9 100644 --- a/tegra.c +++ b/tegra.c @@ -228,7 +228,7 @@ static int tegra_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint3 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_TEGRA_GEM_CREATE, &gem_create); if (ret) { - fprintf(stderr, "drv: DRM_IOCTL_TEGRA_GEM_CREATE failed (size=%zu)\n", size); + drv_log("DRM_IOCTL_TEGRA_GEM_CREATE failed (size=%zu)\n", size); return ret; } @@ -286,7 +286,7 @@ static int tegra_bo_import(struct bo *bo, struct drv_import_fd_data *data) } 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_log("%s: unknown tile format %d\n", __func__, gem_get_tiling.mode); drv_gem_bo_destroy(bo); assert(0); } @@ -306,7 +306,7 @@ static void *tegra_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t ret = drmCommandWriteRead(bo->drv->fd, DRM_TEGRA_GEM_MMAP, &gem_map, sizeof(gem_map)); if (ret < 0) { - fprintf(stderr, "drv: DRM_TEGRA_GEM_MMAP failed\n"); + drv_log("DRM_TEGRA_GEM_MMAP failed\n"); return MAP_FAILED; } diff --git a/vc4.c b/vc4.c index 7960247..f9e1c13 100644 --- a/vc4.c +++ b/vc4.c @@ -48,8 +48,7 @@ static int vc4_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_ ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VC4_CREATE_BO, &bo_create); if (ret) { - fprintf(stderr, "drv: DRM_IOCTL_VC4_GEM_CREATE failed (size=%zu)\n", - bo->total_size); + drv_log("DRM_IOCTL_VC4_GEM_CREATE failed (size=%zu)\n", bo->total_size); return ret; } @@ -69,7 +68,7 @@ static void *vc4_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t m ret = drmCommandWriteRead(bo->drv->fd, DRM_VC4_MMAP_BO, &bo_map, sizeof(bo_map)); if (ret) { - fprintf(stderr, "drv: DRM_VC4_MMAP_BO failed\n"); + drv_log("DRM_VC4_MMAP_BO failed\n"); return MAP_FAILED; } diff --git a/virtio_virgl.c b/virtio_virgl.c index d5429bd..2b445a6 100644 --- a/virtio_virgl.c +++ b/virtio_virgl.c @@ -100,7 +100,7 @@ static int virtio_gpu_bo_create(struct bo *bo, uint32_t width, uint32_t height, 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", + drv_log("DRM_IOCTL_VIRTGPU_RESOURCE_CREATE failed with %s\n", strerror(errno)); goto fail; } @@ -137,7 +137,7 @@ static void *virgl_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t 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)); + drv_log("DRM_IOCTL_VIRTGPU_MAP failed with %s\n", strerror(errno)); return MAP_FAILED; } @@ -161,8 +161,7 @@ static int virtio_gpu_bo_invalidate(struct bo *bo, struct mapping *mapping) 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)); + drv_log("DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST failed with %s\n", strerror(errno)); return ret; } @@ -187,8 +186,7 @@ static int virtio_gpu_bo_flush(struct bo *bo, struct mapping *mapping) 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)); + drv_log("DRM_IOCTL_VIRTGPU_TRANSFER_TO_HOST failed with %s\n", strerror(errno)); return ret; } From 3cf8c92dc25c0a34b3c1d1aa73759ac21db4b953 Mon Sep 17 00:00:00 2001 From: Bas Nieuwenhuizen Date: Fri, 23 Mar 2018 17:21:37 +0100 Subject: [PATCH 038/269] minigbm: amdgpu: Disable explicit synchronization when possible. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With drm minor 21 both radv and mesa can do all the explicit synchornization extensions and hence explicit synchronization gets used. However, as implicit synchronization is not disabled we can get surprises like cyclic dependencies if producer and consumer are too far out of sync with each other. Therefore this disables implicit synchronization if the kernel is new enough for explicit synchronization to get used. v2: - Fix up compile errors - Actually set priv->addrlib BUG=b:76135512 TEST=Run dEQP-VK.wsi.android.swapchain.render.basic 10 times on Kahlee. Change-Id: I6e5389793e82b167e025b7d94958effad278c361 Reviewed-on: https://chromium-review.googlesource.com/978166 Commit-Ready: Bas Nieuwenhuizen Tested-by: Bas Nieuwenhuizen Reviewed-by: Stéphane Marchesin Reviewed-by: Gurchetan Singh --- amdgpu.c | 42 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/amdgpu.c b/amdgpu.c index e196d28..1a68a5b 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -41,6 +41,11 @@ enum { }; // clang-format on +struct amdgpu_priv { + void *addrlib; + int drm_version; +}; + const static uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888 }; @@ -273,15 +278,31 @@ static void *amdgpu_addrlib_init(int fd) static int amdgpu_init(struct driver *drv) { - void *addrlib; + struct amdgpu_priv *priv; + drmVersionPtr drm_version; struct format_metadata metadata; uint64_t use_flags = BO_USE_RENDER_MASK; - addrlib = amdgpu_addrlib_init(drv_get_fd(drv)); - if (!addrlib) + priv = calloc(1, sizeof(struct amdgpu_priv)); + if (!priv) return -1; - drv->priv = addrlib; + drm_version = drmGetVersion(drv_get_fd(drv)); + if (!drm_version) { + free(priv); + return -1; + } + + priv->drm_version = drm_version->version_minor; + drmFreeVersion(drm_version); + + priv->addrlib = amdgpu_addrlib_init(drv_get_fd(drv)); + if (!priv->addrlib) { + free(priv); + return -1; + } + + drv->priv = priv; drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), &LINEAR_METADATA, BO_USE_TEXTURE_MASK); @@ -342,14 +363,17 @@ static int amdgpu_init(struct driver *drv) static void amdgpu_close(struct driver *drv) { - AddrDestroy(drv->priv); + struct amdgpu_priv *priv = (struct amdgpu_priv *)drv->priv; + AddrDestroy(priv->addrlib); + free(priv); drv->priv = NULL; } static int amdgpu_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, uint64_t use_flags) { - void *addrlib = bo->drv->priv; + struct amdgpu_priv *priv = (struct amdgpu_priv *)bo->drv->priv; + void *addrlib = priv->addrlib; union drm_amdgpu_gem_create gem_create; struct amdgpu_bo_metadata metadata = { 0 }; ADDR_COMPUTE_SURFACE_INFO_OUTPUT addr_out = { 0 }; @@ -392,6 +416,12 @@ static int amdgpu_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint gem_create.in.domain_flags |= AMDGPU_GEM_CREATE_CPU_GTT_USWC; } + /* If drm_version >= 21 everything exposes explicit synchronization primitives + and chromeos/arc++ will use them. Disable implicit synchronization. */ + if (priv->drm_version >= 21) { + gem_create.in.domain_flags |= AMDGPU_GEM_CREATE_EXPLICIT_SYNC; + } + /* Allocate the buffer with the preferred heap. */ ret = drmCommandWriteRead(drv_get_fd(bo->drv), DRM_AMDGPU_GEM_CREATE, &gem_create, sizeof(gem_create)); From 7cfcc285d943c7c9f33ad949922e370ede98ed50 Mon Sep 17 00:00:00 2001 From: Jeremy Grosser Date: Fri, 30 Mar 2018 01:19:41 -0700 Subject: [PATCH 039/269] minigbm: Enable vc4 driver BUG=None TEST=graphics_Gbm on target board Change-Id: Id92466354e644f9237f8c19aebd0534c1b23bbc0 Reviewed-on: https://chromium-review.googlesource.com/989301 Commit-Ready: Jeremy Grosser Tested-by: Jeremy Grosser Reviewed-by: Gurchetan Singh --- Makefile | 3 +++ vc4.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 358cd7b..6cfe96b 100644 --- a/Makefile +++ b/Makefile @@ -31,6 +31,9 @@ endif ifdef DRV_ROCKCHIP CFLAGS += $(shell $(PKG_CONFIG) --cflags libdrm_rockchip) endif +ifdef DRV_VC4 + CFLAGS += $(shell $(PKG_CONFIG) --cflags libdrm_vc4) +endif CPPFLAGS += $(PC_CFLAGS) LDLIBS += $(PC_LIBS) diff --git a/vc4.c b/vc4.c index f9e1c13..71e73ea 100644 --- a/vc4.c +++ b/vc4.c @@ -73,7 +73,7 @@ static void *vc4_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t m } vma->length = bo->total_size; - return mmap(0, bo->total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, + return mmap(NULL, bo->total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, bo_map.offset); } From bd1b1b55017d252fa543d97f6e5023b0a0347109 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Thu, 29 Mar 2018 16:34:53 -0700 Subject: [PATCH 040/269] minigbm: drv_bo_flush --> drv_bo_flush_or_unmap There's no flush or invalidate mechnaism with the DRI interface, so we'll have to support mapping and unmapping. BUG=b:72972511 TEST=gbmtest passes in CQ Change-Id: If3aef651f8549544ed4ed499e17f7f99c597974c Reviewed-on: https://chromium-review.googlesource.com/990892 Commit-Ready: Gurchetan Singh Tested-by: Satyajit Sahu Reviewed-by: Joe Kniss Reviewed-by: Satyajit Sahu --- cros_gralloc/cros_gralloc_buffer.cc | 2 +- drv.c | 8 ++++---- drv.h | 2 +- gbm.c | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cros_gralloc/cros_gralloc_buffer.cc b/cros_gralloc/cros_gralloc_buffer.cc index 40a2083..0301af1 100644 --- a/cros_gralloc/cros_gralloc_buffer.cc +++ b/cros_gralloc/cros_gralloc_buffer.cc @@ -90,7 +90,7 @@ int32_t cros_gralloc_buffer::unlock() if (!--lockcount_) { if (lock_data_[0]) { - drv_bo_flush(bo_, lock_data_[0]); + drv_bo_flush_or_unmap(bo_, lock_data_[0]); lock_data_[0] = nullptr; } } diff --git a/drv.c b/drv.c index c7ac816..8970d4c 100644 --- a/drv.c +++ b/drv.c @@ -466,9 +466,7 @@ void *drv_bo_map(struct bo *bo, const struct rectangle *rect, uint32_t map_flags int drv_bo_unmap(struct bo *bo, struct mapping *mapping) { uint32_t i; - int ret = drv_bo_flush(bo, mapping); - if (ret) - return ret; + int ret = 0; pthread_mutex_lock(&bo->drv->driver_lock); @@ -507,7 +505,7 @@ int drv_bo_invalidate(struct bo *bo, struct mapping *mapping) return ret; } -int drv_bo_flush(struct bo *bo, struct mapping *mapping) +int drv_bo_flush_or_unmap(struct bo *bo, struct mapping *mapping) { int ret = 0; @@ -519,6 +517,8 @@ int drv_bo_flush(struct bo *bo, struct mapping *mapping) if (bo->drv->backend->bo_flush) ret = bo->drv->backend->bo_flush(bo, mapping); + else + ret = drv_bo_unmap(bo, mapping); return ret; } diff --git a/drv.h b/drv.h index 2271a9f..09aa33f 100644 --- a/drv.h +++ b/drv.h @@ -130,7 +130,7 @@ int drv_bo_unmap(struct bo *bo, struct mapping *mapping); int drv_bo_invalidate(struct bo *bo, struct mapping *mapping); -int drv_bo_flush(struct bo *bo, struct mapping *mapping); +int drv_bo_flush_or_unmap(struct bo *bo, struct mapping *mapping); uint32_t drv_bo_get_width(struct bo *bo); diff --git a/gbm.c b/gbm.c index 25b4fa0..a720461 100644 --- a/gbm.c +++ b/gbm.c @@ -249,7 +249,7 @@ PUBLIC void *gbm_bo_map(struct gbm_bo *bo, uint32_t x, uint32_t y, uint32_t widt PUBLIC void gbm_bo_unmap(struct gbm_bo *bo, void *map_data) { assert(bo); - drv_bo_flush(bo->bo, map_data); + drv_bo_flush_or_unmap(bo->bo, map_data); } PUBLIC uint32_t gbm_bo_get_width(struct gbm_bo *bo) From d8c0455bd8a46597fd47560977bc3a4a13046409 Mon Sep 17 00:00:00 2001 From: Albert Chaulk Date: Thu, 5 Apr 2018 16:56:53 -0400 Subject: [PATCH 041/269] Update Android.mk for amlogic This adds a separate app-linkable libminigbm target that disables the gralloc code and links in the gbm api. Adds support for meson buildflag. Bug: b/76099793 Test: amlogic test tool, drawframe Change-Id: I7aba3ec65fa39cabbb8c96c44d6d59b8225956a9 Reviewed-on: https://chromium-review.googlesource.com/998758 Commit-Ready: Gurchetan Singh Tested-by: Gurchetan Singh Reviewed-by: Alistair Strachan Reviewed-by: Gurchetan Singh --- Android.mk | 58 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/Android.mk b/Android.mk index 2f3f519..0abeaf4 100644 --- a/Android.mk +++ b/Android.mk @@ -6,15 +6,8 @@ ifeq ($(strip $(BOARD_USES_MINIGBM)), true) MINIGBM_GRALLOC_MK := $(call my-dir)/Android.gralloc.mk LOCAL_PATH := $(call my-dir) intel_drivers := i915 i965 -include $(CLEAR_VARS) - -SUBDIRS := cros_gralloc - -LOCAL_SHARED_LIBRARIES := \ - libcutils \ - libdrm -LOCAL_SRC_FILES := \ +MINIGBM_SRC := \ amdgpu.c \ drv.c \ evdi.c \ @@ -36,24 +29,43 @@ LOCAL_SRC_FILES := \ virtio_dumb.c \ virtio_virgl.c -include $(MINIGBM_GRALLOC_MK) - -LOCAL_CPPFLAGS += -std=c++14 -D_GNU_SOURCE=1 -D_FILE_OFFSET_BITS=64 -LOCAL_CFLAGS += -Wall -Wsign-compare -Wpointer-arith \ +MINIGBM_CPPFLAGS := -std=c++14 -D_GNU_SOURCE=1 -D_FILE_OFFSET_BITS=64 +MINIGBM_CFLAGS := -Wall -Wsign-compare -Wpointer-arith \ -Wcast-qual -Wcast-align \ -D_GNU_SOURCE=1 -D_FILE_OFFSET_BITS=64 ifneq ($(filter $(intel_drivers), $(BOARD_GPU_DRIVERS)),) -LOCAL_CPPFLAGS += -DDRV_I915 -LOCAL_CFLAGS += -DDRV_I915 +MINIGBM_CPPFLAGS += -DDRV_I915 +MINIGBM_CFLAGS += -DDRV_I915 LOCAL_SHARED_LIBRARIES += libdrm_intel endif ifneq ($(filter virgl, $(BOARD_GPU_DRIVERS)),) -LOCAL_CPPFLAGS += -DDRV_VIRGL -LOCAL_CFLAGS += -DDRV_VIRGL +MINIGBM_CPPFLAGS += -DDRV_VIRGL +MINIGBM_CFLAGS += -DDRV_VIRGL +endif + +ifneq ($(filter meson, $(BOARD_GPU_DRIVERS)),) +MINIGBM_CPPFLAGS += -DDRV_MESON +MINIGBM_CFLAGS += -DDRV_MESON endif + +include $(CLEAR_VARS) + +SUBDIRS := cros_gralloc + +LOCAL_SHARED_LIBRARIES := \ + libcutils \ + libdrm + +LOCAL_SRC_FILES := $(MINIGBM_SRC) + +include $(MINIGBM_GRALLOC_MK) + +LOCAL_CFLAGS := $(MINIGBM_CFLAGS) +LOCAL_CPPFLAGS := $(MINIGBM_CPPFLAGS) + LOCAL_MODULE := gralloc.$(TARGET_BOARD_PLATFORM) LOCAL_MODULE_TAGS := optional # The preferred path for vendor HALs is /vendor/lib/hw @@ -64,4 +76,18 @@ LOCAL_MODULE_SUFFIX := $(TARGET_SHLIB_SUFFIX) LOCAL_SHARED_LIBRARIES += libnativewindow libsync liblog include $(BUILD_SHARED_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_SHARED_LIBRARIES := libcutils +LOCAL_STATIC_LIBRARIES := libdrm + +LOCAL_SRC_FILES += $(MINIGBM_SRC) gbm.c gbm_helpers.c + +LOCAL_CFLAGS := $(MINIGBM_CFLAGS) +LOCAL_CPPFLAGS := $(MINIGBM_CPPFLAGS) + +LOCAL_MODULE := libminigbm +LOCAL_MODULE_TAGS := optional +include $(BUILD_SHARED_LIBRARY) + endif From 249e8636f7839786cc9b2d21808c944929307853 Mon Sep 17 00:00:00 2001 From: Lepton Wu Date: Thu, 5 Apr 2018 12:50:03 -0700 Subject: [PATCH 042/269] minigbm: virtio_gpu: select dumb/virgl at runtime. For using same image on legacy-qemu and virgl enabled qemu. We need to handle dumb and virgl code path at run time. Just merge them to one driver. BUG=b:77302150 TEST=manual - run novato image under qemu with gl=on/off. Change-Id: Ia12140fba16a350fe13f4258d25333ecfe8352b3 Reviewed-on: https://chromium-review.googlesource.com/998631 Commit-Ready: Lepton Wu Tested-by: Lepton Wu Reviewed-by: Lepton Wu Reviewed-by: Gurchetan Singh --- Android.mk | 8 +-- virtio_dumb.c | 71 -------------------- virtio_virgl.c => virtio_gpu.c | 119 ++++++++++++++++++++++++++++----- 3 files changed, 104 insertions(+), 94 deletions(-) delete mode 100644 virtio_dumb.c rename virtio_virgl.c => virtio_gpu.c (65%) diff --git a/Android.mk b/Android.mk index 0abeaf4..e75766f 100644 --- a/Android.mk +++ b/Android.mk @@ -26,8 +26,7 @@ MINIGBM_SRC := \ udl.c \ vc4.c \ vgem.c \ - virtio_dumb.c \ - virtio_virgl.c + virtio_gpu.c MINIGBM_CPPFLAGS := -std=c++14 -D_GNU_SOURCE=1 -D_FILE_OFFSET_BITS=64 MINIGBM_CFLAGS := -Wall -Wsign-compare -Wpointer-arith \ @@ -40,11 +39,6 @@ MINIGBM_CFLAGS += -DDRV_I915 LOCAL_SHARED_LIBRARIES += libdrm_intel endif -ifneq ($(filter virgl, $(BOARD_GPU_DRIVERS)),) -MINIGBM_CPPFLAGS += -DDRV_VIRGL -MINIGBM_CFLAGS += -DDRV_VIRGL -endif - ifneq ($(filter meson, $(BOARD_GPU_DRIVERS)),) MINIGBM_CPPFLAGS += -DDRV_MESON MINIGBM_CFLAGS += -DDRV_MESON diff --git a/virtio_dumb.c b/virtio_dumb.c deleted file mode 100644 index b6dc3cb..0000000 --- a/virtio_dumb.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2016 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. - */ - -#ifndef DRV_VIRGL - -#include "drv_priv.h" -#include "helpers.h" -#include "util.h" - -#define MESA_LLVMPIPE_TILE_ORDER 6 -#define MESA_LLVMPIPE_TILE_SIZE (1 << MESA_LLVMPIPE_TILE_ORDER) - -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_YVU420, - DRM_FORMAT_YVU420_ANDROID }; - -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) -{ - width = ALIGN(width, MESA_LLVMPIPE_TILE_SIZE); - height = ALIGN(height, MESA_LLVMPIPE_TILE_SIZE); - - /* HAL_PIXEL_FORMAT_YV12 requires that the buffer's height not be aligned. */ - if (bo->format == DRM_FORMAT_YVU420_ANDROID) - height = bo->height; - - return drv_dumb_bo_create(bo, width, height, format, use_flags); -} - -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; - case DRM_FORMAT_FLEX_YCbCr_420_888: - return DRM_FORMAT_YVU420; - default: - return format; - } -} - -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/virtio_virgl.c b/virtio_gpu.c similarity index 65% rename from virtio_virgl.c rename to virtio_gpu.c index 2b445a6..5200b3d 100644 --- a/virtio_virgl.c +++ b/virtio_gpu.c @@ -4,8 +4,6 @@ * found in the LICENSE file. */ -#ifdef DRV_VIRGL - #include #include #include @@ -24,12 +22,22 @@ #endif #define PIPE_TEXTURE_2D 2 +#define MESA_LLVMPIPE_TILE_ORDER 6 +#define MESA_LLVMPIPE_TILE_SIZE (1 << MESA_LLVMPIPE_TILE_ORDER) + 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 dumb_texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_YVU420, + DRM_FORMAT_YVU420_ANDROID }; + static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_RG88 }; +struct virtio_gpu_priv { + int has_3d; +}; + static uint32_t translate_format(uint32_t drm_fourcc, uint32_t plane) { switch (drm_fourcc) { @@ -52,19 +60,21 @@ static uint32_t translate_format(uint32_t drm_fourcc, uint32_t plane) } } -static int virtio_gpu_init(struct driver *drv) +static int virtio_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint64_t use_flags) { - drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &LINEAR_METADATA, BO_USE_RENDER_MASK); + width = ALIGN(width, MESA_LLVMPIPE_TILE_SIZE); + height = ALIGN(height, MESA_LLVMPIPE_TILE_SIZE); - drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), - &LINEAR_METADATA, BO_USE_TEXTURE_MASK); + /* HAL_PIXEL_FORMAT_YV12 requires that the buffer's height not be aligned. */ + if (bo->format == DRM_FORMAT_YVU420_ANDROID) + height = bo->height; - return drv_modify_linear_combinations(drv); + return drv_dumb_bo_create(bo, width, height, format, use_flags); } -static int virtio_gpu_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, - uint64_t use_flags) +static int virtio_virgl_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint64_t use_flags) { int ret; ssize_t plane; @@ -127,7 +137,7 @@ static int virtio_gpu_bo_create(struct bo *bo, uint32_t width, uint32_t height, return ret; } -static void *virgl_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags) +static void *virtio_virgl_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags) { int ret; struct drm_virtgpu_map gem_map; @@ -146,10 +156,82 @@ static void *virgl_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t gem_map.offset); } +static int virtio_gpu_init(struct driver *drv) +{ + int ret; + struct virtio_gpu_priv *priv; + struct drm_virtgpu_getparam args; + + priv = calloc(1, sizeof(*priv)); + drv->priv = priv; + + memset(&args, 0, sizeof(args)); + args.param = VIRTGPU_PARAM_3D_FEATURES; + args.value = (uint64_t)(uintptr_t)&priv->has_3d; + ret = drmIoctl(drv->fd, DRM_IOCTL_VIRTGPU_GETPARAM, &args); + if (ret) { + drv_log("virtio 3D acceleration is not available\n"); + /* Be paranoid */ + priv->has_3d = 0; + } + + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &LINEAR_METADATA, BO_USE_RENDER_MASK); + + if (priv->has_3d) + drv_add_combinations(drv, texture_source_formats, + ARRAY_SIZE(texture_source_formats), &LINEAR_METADATA, + BO_USE_TEXTURE_MASK); + else + drv_add_combinations(drv, dumb_texture_source_formats, + ARRAY_SIZE(dumb_texture_source_formats), &LINEAR_METADATA, + BO_USE_TEXTURE_MASK); + + return drv_modify_linear_combinations(drv); +} + +static void virtio_gpu_close(struct driver *drv) +{ + free(drv->priv); + drv->priv = NULL; +} + +static int virtio_gpu_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint64_t use_flags) +{ + struct virtio_gpu_priv *priv = (struct virtio_gpu_priv *)bo->drv->priv; + if (priv->has_3d) + return virtio_virgl_bo_create(bo, width, height, format, use_flags); + else + return virtio_dumb_bo_create(bo, width, height, format, use_flags); +} + +static int virtio_gpu_bo_destroy(struct bo *bo) +{ + struct virtio_gpu_priv *priv = (struct virtio_gpu_priv *)bo->drv->priv; + if (priv->has_3d) + return drv_gem_bo_destroy(bo); + else + return drv_dumb_bo_destroy(bo); +} + +static void *virtio_gpu_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags) +{ + struct virtio_gpu_priv *priv = (struct virtio_gpu_priv *)bo->drv->priv; + if (priv->has_3d) + return virtio_virgl_bo_map(bo, vma, plane, map_flags); + else + return drv_dumb_bo_map(bo, vma, plane, map_flags); +} + static int virtio_gpu_bo_invalidate(struct bo *bo, struct mapping *mapping) { int ret; struct drm_virtgpu_3d_transfer_from_host xfer; + struct virtio_gpu_priv *priv = (struct virtio_gpu_priv *)bo->drv->priv; + + if (!priv->has_3d) + return 0; memset(&xfer, 0, sizeof(xfer)); xfer.bo_handle = mapping->vma->handle; @@ -172,6 +254,10 @@ static int virtio_gpu_bo_flush(struct bo *bo, struct mapping *mapping) { int ret; struct drm_virtgpu_3d_transfer_to_host xfer; + struct virtio_gpu_priv *priv = (struct virtio_gpu_priv *)bo->drv->priv; + + if (!priv->has_3d) + return 0; if (!(mapping->vma->map_flags & BO_MAP_WRITE)) return 0; @@ -199,22 +285,23 @@ static uint32_t virtio_gpu_resolve_format(uint32_t format, uint64_t use_flags) case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED: /*HACK: See b/28671744 */ return DRM_FORMAT_XBGR8888; + case DRM_FORMAT_FLEX_YCbCr_420_888: + return DRM_FORMAT_YVU420; default: return format; } } -struct backend backend_virtio_gpu = { +const struct backend backend_virtio_gpu = { .name = "virtio_gpu", .init = virtio_gpu_init, + .close = virtio_gpu_close, .bo_create = virtio_gpu_bo_create, - .bo_destroy = drv_gem_bo_destroy, + .bo_destroy = virtio_gpu_bo_destroy, .bo_import = drv_prime_bo_import, - .bo_map = virgl_bo_map, + .bo_map = virtio_gpu_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 From 9c3fb32dd4a8b9a3cf870c533d1e88dd542d7c16 Mon Sep 17 00:00:00 2001 From: "Kristian H. Kristensen" Date: Wed, 11 Apr 2018 15:55:13 -0700 Subject: [PATCH 043/269] i915: Allow allocating ARGB buffers for scanout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CL:991261 changed our primary framebuffer format from XRGB to ARGB. We still only scanout as XRGB where the display controller doesn't support ARGB, but minigbm doesn't know that. As a result, when we try to allocate an ARGB buffer with the SCANOUT useflag, we get a linear buffer. This breaks PSR and regresses performance and, in general, just isn't what we want. This CL enables SCANOUT for all ARGB formats where the corresponding XRGB formats supports scanout. In the end, it's up to the caller to make sure a format works for scanout anyway. BUG=827188,830969 TEST=test_that graphics_Idle on samus Change-Id: Iab428e5b21abedcac7cee86fccc8df50dab3f471 Reviewed-on: https://chromium-review.googlesource.com/1008867 Commit-Ready: Kristian H. Kristensen Tested-by: Kristian H. Kristensen Reviewed-by: Stéphane Marchesin Reviewed-by: Gurchetan Singh --- i915.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/i915.c b/i915.c index cf5a7fd..fc877cb 100644 --- a/i915.c +++ b/i915.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -49,6 +50,31 @@ static uint32_t i915_get_gen(int device_id) return 4; } +/* + * We allow allocation of ARGB formats for SCANOUT if the corresponding XRGB + * formats supports it. It's up to the caller (chrome ozone) to ultimately not + * scan out ARGB if the display controller only supports XRGB, but we'll allow + * the allocation of the bo here. + */ +static bool format_compatible(const struct combination *combo, uint32_t format) +{ + if (combo->format == format) + return true; + + switch (format) { + case DRM_FORMAT_XRGB8888: + return combo->format == DRM_FORMAT_ARGB8888; + case DRM_FORMAT_XBGR8888: + return combo->format == DRM_FORMAT_ABGR8888; + case DRM_FORMAT_RGBX8888: + return combo->format == DRM_FORMAT_RGBA8888; + case DRM_FORMAT_BGRX8888: + return combo->format == DRM_FORMAT_BGRA8888; + default: + return false; + } +} + static int i915_add_kms_item(struct driver *drv, const struct kms_item *item) { uint32_t i; @@ -60,7 +86,7 @@ static int i915_add_kms_item(struct driver *drv, const struct kms_item *item) */ 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 (!format_compatible(combo, item->format)) continue; if (item->modifier == DRM_FORMAT_MOD_LINEAR && From cdcebd879cbbfdb4d5161d0aee65bea859593141 Mon Sep 17 00:00:00 2001 From: Satyajit Date: Fri, 12 Jan 2018 14:49:05 +0530 Subject: [PATCH 044/269] minigbm: using dri extensions addrlib dependency removed. dri extensions are called instead. dri.c/dri.h implements the generic dri extensions call. amdgpu.c implements amdgpu specific. BUG=b:72972511 TEST=Chrome booted to UI and passed graphics_Gbm autotest Change-Id: Ia0edec7752a258fe2f70bc4838dac6398d46def2 Signed-off-by: Satyajit Reviewed-on: https://chromium-review.googlesource.com/863723 Commit-Ready: Satyajit Sahu Tested-by: Satyajit Sahu Reviewed-by: Gurchetan Singh --- Makefile | 2 +- amdgpu.c | 432 +++++++++++++---------------------------------------- dri.c | 293 ++++++++++++++++++++++++++++++++++++ dri.h | 37 +++++ drv_priv.h | 2 +- 5 files changed, 437 insertions(+), 329 deletions(-) create mode 100644 dri.c create mode 100644 dri.h diff --git a/Makefile b/Makefile index 6cfe96b..35f92f2 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ CFLAGS += -std=c99 -Wall -Wsign-compare -Wpointer-arith -Wcast-qual \ ifdef DRV_AMDGPU CFLAGS += $(shell $(PKG_CONFIG) --cflags libdrm_amdgpu) - LDLIBS += -lamdgpuaddr + LDLIBS += -ldrm_amdgpu -ldl endif ifdef DRV_EXYNOS CFLAGS += $(shell $(PKG_CONFIG) --cflags libdrm_exynos) diff --git a/amdgpu.c b/amdgpu.c index 1a68a5b..3bf5eb2 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -13,36 +13,23 @@ #include #include -#include "addrinterface.h" +#include "dri.h" #include "drv_priv.h" #include "helpers.h" #include "util.h" -#ifndef CIASICIDGFXENGINE_SOUTHERNISLAND -#define CIASICIDGFXENGINE_SOUTHERNISLAND 0x0000000A +#ifdef __ANDROID__ +#define DRI_PATH "/vendor/lib/dri/radeonsi_dri.so" +#else +#define DRI_PATH "/usr/lib64/dri/radeonsi_dri.so" #endif -// clang-format off -#define mmCC_RB_BACKEND_DISABLE 0x263d -#define mmGB_TILE_MODE0 0x2644 -#define mmGB_MACROTILE_MODE0 0x2664 -#define mmGB_ADDR_CONFIG 0x263e -#define mmMC_ARB_RAMCFG 0x9d8 - -enum { - FAMILY_UNKNOWN, - FAMILY_SI, - FAMILY_CI, - FAMILY_KV, - FAMILY_VI, - FAMILY_CZ, - FAMILY_PI, - FAMILY_LAST, -}; -// clang-format on +#define TILE_TYPE_LINEAR 0 +/* DRI backend decides tiling in this case. */ +#define TILE_TYPE_DRI 1 struct amdgpu_priv { - void *addrlib; + struct dri_driver dri; int drm_version; }; @@ -53,229 +40,6 @@ const static uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMA const static uint32_t texture_source_formats[] = { DRM_FORMAT_GR88, DRM_FORMAT_R8, DRM_FORMAT_NV21, DRM_FORMAT_NV12, DRM_FORMAT_YVU420_ANDROID }; -static int amdgpu_set_metadata(int fd, uint32_t handle, struct amdgpu_bo_metadata *info) -{ - struct drm_amdgpu_gem_metadata args = { 0 }; - - if (!info) - return -EINVAL; - - args.handle = handle; - args.op = AMDGPU_GEM_METADATA_OP_SET_METADATA; - args.data.flags = info->flags; - args.data.tiling_info = info->tiling_info; - - if (info->size_metadata > sizeof(args.data.data)) - return -EINVAL; - - if (info->size_metadata) { - args.data.data_size_bytes = info->size_metadata; - memcpy(args.data.data, info->umd_metadata, info->size_metadata); - } - - return drmCommandWriteRead(fd, DRM_AMDGPU_GEM_METADATA, &args, sizeof(args)); -} - -static int amdgpu_read_mm_regs(int fd, unsigned dword_offset, unsigned count, uint32_t instance, - uint32_t flags, uint32_t *values) -{ - struct drm_amdgpu_info request; - - memset(&request, 0, sizeof(request)); - request.return_pointer = (uintptr_t)values; - request.return_size = count * sizeof(uint32_t); - request.query = AMDGPU_INFO_READ_MMR_REG; - request.read_mmr_reg.dword_offset = dword_offset; - request.read_mmr_reg.count = count; - request.read_mmr_reg.instance = instance; - request.read_mmr_reg.flags = flags; - - return drmCommandWrite(fd, DRM_AMDGPU_INFO, &request, sizeof(struct drm_amdgpu_info)); -} - -static int amdgpu_query_gpu(int fd, struct amdgpu_gpu_info *gpu_info) -{ - int ret; - uint32_t instance; - - if (!gpu_info) - return -EINVAL; - - instance = AMDGPU_INFO_MMR_SH_INDEX_MASK << AMDGPU_INFO_MMR_SH_INDEX_SHIFT; - - ret = amdgpu_read_mm_regs(fd, mmCC_RB_BACKEND_DISABLE, 1, instance, 0, - &gpu_info->backend_disable[0]); - if (ret) - return ret; - /* extract bitfield CC_RB_BACKEND_DISABLE.BACKEND_DISABLE */ - gpu_info->backend_disable[0] = (gpu_info->backend_disable[0] >> 16) & 0xff; - - ret = amdgpu_read_mm_regs(fd, mmGB_TILE_MODE0, 32, 0xffffffff, 0, gpu_info->gb_tile_mode); - if (ret) - return ret; - - ret = amdgpu_read_mm_regs(fd, mmGB_MACROTILE_MODE0, 16, 0xffffffff, 0, - gpu_info->gb_macro_tile_mode); - if (ret) - return ret; - - ret = amdgpu_read_mm_regs(fd, mmGB_ADDR_CONFIG, 1, 0xffffffff, 0, &gpu_info->gb_addr_cfg); - if (ret) - return ret; - - ret = amdgpu_read_mm_regs(fd, mmMC_ARB_RAMCFG, 1, 0xffffffff, 0, &gpu_info->mc_arb_ramcfg); - if (ret) - return ret; - - return 0; -} - -static void *ADDR_API alloc_sys_mem(const ADDR_ALLOCSYSMEM_INPUT *in) -{ - return malloc(in->sizeInBytes); -} - -static ADDR_E_RETURNCODE ADDR_API free_sys_mem(const ADDR_FREESYSMEM_INPUT *in) -{ - free(in->pVirtAddr); - return ADDR_OK; -} - -static int amdgpu_addrlib_compute(void *addrlib, uint32_t width, uint32_t height, uint32_t format, - 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 }; - ADDR_TILEINFO addr_tile_info = { 0 }; - ADDR_TILEINFO addr_tile_info_out = { 0 }; - uint32_t bits_per_pixel; - - addr_surf_info_in.size = sizeof(ADDR_COMPUTE_SURFACE_INFO_INPUT); - - /* Set the requested tiling mode. */ - addr_surf_info_in.tileMode = ADDR_TM_2D_TILED_THIN1; - 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; - - bits_per_pixel = drv_stride_from_format(format, 1, 0) * 8; - /* Bits per pixel should be calculated from format*/ - addr_surf_info_in.bpp = bits_per_pixel; - addr_surf_info_in.numSamples = 1; - addr_surf_info_in.width = width; - addr_surf_info_in.height = height; - addr_surf_info_in.numSlices = 1; - addr_surf_info_in.pTileInfo = &addr_tile_info; - addr_surf_info_in.tileIndex = -1; - - /* This disables incorrect calculations (hacks) in addrlib. */ - addr_surf_info_in.flags.noStencil = 1; - - /* Set the micro tile type. */ - if (use_flags & BO_USE_SCANOUT) - addr_surf_info_in.tileType = ADDR_DISPLAYABLE; - else - addr_surf_info_in.tileType = ADDR_NON_DISPLAYABLE; - - addr_out->size = sizeof(ADDR_COMPUTE_SURFACE_INFO_OUTPUT); - addr_out->pTileInfo = &addr_tile_info_out; - - if (AddrComputeSurfaceInfo(addrlib, &addr_surf_info_in, addr_out) != ADDR_OK) - return -EINVAL; - - ADDR_CONVERT_TILEINFOTOHW_INPUT s_in = { 0 }; - ADDR_CONVERT_TILEINFOTOHW_OUTPUT s_out = { 0 }; - ADDR_TILEINFO s_tile_hw_info_out = { 0 }; - - s_in.size = sizeof(ADDR_CONVERT_TILEINFOTOHW_INPUT); - /* Convert from real value to HW value */ - s_in.reverse = 0; - s_in.pTileInfo = &addr_tile_info_out; - s_in.tileIndex = -1; - - s_out.size = sizeof(ADDR_CONVERT_TILEINFOTOHW_OUTPUT); - s_out.pTileInfo = &s_tile_hw_info_out; - - if (AddrConvertTileInfoToHW(addrlib, &s_in, &s_out) != ADDR_OK) - return -EINVAL; - - if (addr_out->tileMode >= ADDR_TM_2D_TILED_THIN1) - /* 2D_TILED_THIN1 */ - *tiling_flags |= AMDGPU_TILING_SET(ARRAY_MODE, 4); - else if (addr_out->tileMode >= ADDR_TM_1D_TILED_THIN1) - /* 1D_TILED_THIN1 */ - *tiling_flags |= AMDGPU_TILING_SET(ARRAY_MODE, 2); - else - /* LINEAR_ALIGNED */ - *tiling_flags |= AMDGPU_TILING_SET(ARRAY_MODE, 1); - - *tiling_flags |= AMDGPU_TILING_SET(BANK_WIDTH, drv_log_base2(addr_tile_info_out.bankWidth)); - *tiling_flags |= - AMDGPU_TILING_SET(BANK_HEIGHT, drv_log_base2(addr_tile_info_out.bankHeight)); - *tiling_flags |= AMDGPU_TILING_SET(TILE_SPLIT, s_tile_hw_info_out.tileSplitBytes); - *tiling_flags |= AMDGPU_TILING_SET(MACRO_TILE_ASPECT, - drv_log_base2(addr_tile_info_out.macroAspectRatio)); - *tiling_flags |= AMDGPU_TILING_SET(PIPE_CONFIG, s_tile_hw_info_out.pipeConfig); - *tiling_flags |= AMDGPU_TILING_SET(NUM_BANKS, s_tile_hw_info_out.banks); - - return 0; -} - -static void *amdgpu_addrlib_init(int fd) -{ - int ret; - ADDR_CREATE_INPUT addr_create_input = { 0 }; - ADDR_CREATE_OUTPUT addr_create_output = { 0 }; - ADDR_REGISTER_VALUE reg_value = { 0 }; - ADDR_CREATE_FLAGS create_flags = { { 0 } }; - ADDR_E_RETURNCODE addr_ret; - - addr_create_input.size = sizeof(ADDR_CREATE_INPUT); - addr_create_output.size = sizeof(ADDR_CREATE_OUTPUT); - - struct amdgpu_gpu_info gpu_info = { 0 }; - - ret = amdgpu_query_gpu(fd, &gpu_info); - - if (ret) { - drv_log("failed with error =%d\n", ret); - return NULL; - } - - reg_value.noOfBanks = gpu_info.mc_arb_ramcfg & 0x3; - reg_value.gbAddrConfig = gpu_info.gb_addr_cfg; - reg_value.noOfRanks = (gpu_info.mc_arb_ramcfg & 0x4) >> 2; - - reg_value.backendDisables = gpu_info.backend_disable[0]; - reg_value.pTileConfig = gpu_info.gb_tile_mode; - reg_value.noOfEntries = sizeof(gpu_info.gb_tile_mode) / sizeof(gpu_info.gb_tile_mode[0]); - reg_value.pMacroTileConfig = gpu_info.gb_macro_tile_mode; - reg_value.noOfMacroEntries = - sizeof(gpu_info.gb_macro_tile_mode) / sizeof(gpu_info.gb_macro_tile_mode[0]); - create_flags.value = 0; - create_flags.useTileIndex = 1; - - addr_create_input.chipEngine = CIASICIDGFXENGINE_SOUTHERNISLAND; - - addr_create_input.chipFamily = FAMILY_CZ; - addr_create_input.createFlags = create_flags; - addr_create_input.callbacks.allocSysMem = alloc_sys_mem; - addr_create_input.callbacks.freeSysMem = free_sys_mem; - addr_create_input.callbacks.debugPrint = 0; - addr_create_input.regValue = reg_value; - - addr_ret = AddrCreate(&addr_create_input, &addr_create_output); - - if (addr_ret != ADDR_OK) { - drv_log("failed error =%d\n", addr_ret); - return NULL; - } - - return addr_create_output.hLib; -} - static int amdgpu_init(struct driver *drv) { struct amdgpu_priv *priv; @@ -285,125 +49,112 @@ static int amdgpu_init(struct driver *drv) priv = calloc(1, sizeof(struct amdgpu_priv)); if (!priv) - return -1; + return -ENOMEM; drm_version = drmGetVersion(drv_get_fd(drv)); if (!drm_version) { free(priv); - return -1; + return -ENODEV; } priv->drm_version = drm_version->version_minor; drmFreeVersion(drm_version); - priv->addrlib = amdgpu_addrlib_init(drv_get_fd(drv)); - if (!priv->addrlib) { - free(priv); - return -1; - } - drv->priv = priv; - 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); + if (dri_init(drv, DRI_PATH, "radeonsi")) { + free(priv); + drv->priv = NULL; + return -ENODEV; + } - metadata.tiling = ADDR_DISPLAYABLE << 16 | ADDR_TM_LINEAR_ALIGNED; - metadata.priority = 2; + metadata.tiling = TILE_TYPE_LINEAR; + metadata.priority = 1; metadata.modifier = DRM_FORMAT_MOD_LINEAR; drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), &metadata, use_flags); + drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), + &metadata, BO_USE_TEXTURE_MASK); + + /* Linear formats supported by display. */ drv_modify_combination(drv, DRM_FORMAT_ARGB8888, &metadata, BO_USE_CURSOR | BO_USE_SCANOUT); drv_modify_combination(drv, DRM_FORMAT_XRGB8888, &metadata, BO_USE_CURSOR | BO_USE_SCANOUT); drv_modify_combination(drv, DRM_FORMAT_XBGR8888, &metadata, BO_USE_SCANOUT); - metadata.tiling = ADDR_NON_DISPLAYABLE << 16 | ADDR_TM_LINEAR_ALIGNED; - metadata.priority = 3; - metadata.modifier = DRM_FORMAT_MOD_LINEAR; + /* YUV formats for camera and display. */ + drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata, + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_SCANOUT); - drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &metadata, use_flags); + drv_modify_combination(drv, DRM_FORMAT_NV21, &metadata, BO_USE_SCANOUT); + /* + * 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); + + /* + * The following formats will be allocated by the DRI backend and may be potentially tiled. + * Since format modifier support hasn't been implemented fully yet, it's not + * possible to enumerate the different types of buffers (like i915 can). + */ + use_flags &= ~BO_USE_RENDERSCRIPT; 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; + metadata.tiling = TILE_TYPE_DRI; + metadata.priority = 2; 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); + /* Potentially tiled formats supported by display. */ + drv_modify_combination(drv, DRM_FORMAT_ARGB8888, &metadata, BO_USE_CURSOR | BO_USE_SCANOUT); + drv_modify_combination(drv, DRM_FORMAT_XRGB8888, &metadata, BO_USE_CURSOR | BO_USE_SCANOUT); drv_modify_combination(drv, DRM_FORMAT_XBGR8888, &metadata, BO_USE_SCANOUT); - - metadata.tiling = ADDR_NON_DISPLAYABLE << 16 | ADDR_TM_2D_TILED_THIN1; - metadata.priority = 5; - - drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &metadata, use_flags); - return 0; } static void amdgpu_close(struct driver *drv) { - struct amdgpu_priv *priv = (struct amdgpu_priv *)drv->priv; - AddrDestroy(priv->addrlib); - free(priv); + dri_close(drv); + free(drv->priv); drv->priv = NULL; } -static int amdgpu_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, +static int amdgpu_create_bo(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, uint64_t use_flags) { - struct amdgpu_priv *priv = (struct amdgpu_priv *)bo->drv->priv; - void *addrlib = priv->addrlib; - 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; - size_t plane; int ret; + uint32_t plane, stride; + struct combination *combo; + union drm_amdgpu_gem_create gem_create; + struct amdgpu_priv *priv = bo->drv->priv; - if (format == DRM_FORMAT_NV12 || format == DRM_FORMAT_NV21) { - drv_bo_from_format(bo, ALIGN(width, 64), height, format); - } else if (format == DRM_FORMAT_YVU420_ANDROID) { - drv_bo_from_format(bo, ALIGN(width, 128), height, format); - } else { - if (amdgpu_addrlib_compute(addrlib, width, height, format, use_flags, &tiling_flags, - &addr_out) < 0) - return -EINVAL; - - bo->tiling = tiling_flags; - /* RGB has 1 plane only */ - bo->offsets[0] = 0; - bo->total_size = bo->sizes[0] = addr_out.surfSize; - bo->strides[0] = addr_out.pixelPitch * DIV_ROUND_UP(addr_out.pixelBits, 8); - } + combo = drv_get_combination(bo->drv, format, use_flags); + if (!combo) + return -EINVAL; - memset(&gem_create, 0, sizeof(gem_create)); + if (combo->metadata.tiling == TILE_TYPE_DRI) + return dri_bo_create(bo, width, height, format, use_flags); - gem_create.in.bo_size = bo->total_size; - gem_create.in.alignment = addr_out.baseAlign; - /* Set the placement. */ + stride = drv_stride_from_format(format, width, 0); + if (format == DRM_FORMAT_YVU420_ANDROID) + stride = ALIGN(stride, 128); + else + stride = ALIGN(stride, 64); + + drv_bo_from_format(bo, stride, height, format); + memset(&gem_create, 0, sizeof(gem_create)); + gem_create.in.bo_size = bo->total_size; + gem_create.in.alignment = 256; 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; @@ -425,25 +176,44 @@ static int amdgpu_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint /* Allocate the buffer with the preferred heap. */ ret = drmCommandWriteRead(drv_get_fd(bo->drv), DRM_AMDGPU_GEM_CREATE, &gem_create, sizeof(gem_create)); - if (ret < 0) return ret; - metadata.tiling_info = tiling_flags; - for (plane = 0; plane < bo->num_planes; plane++) bo->handles[plane].u32 = gem_create.out.handle; - ret = amdgpu_set_metadata(drv_get_fd(bo->drv), bo->handles[0].u32, &metadata); + return 0; +} + +static int amdgpu_import_bo(struct bo *bo, struct drv_import_fd_data *data) +{ + struct combination *combo; + combo = drv_get_combination(bo->drv, data->format, data->use_flags); + if (!combo) + return -EINVAL; + + if (combo->metadata.tiling == TILE_TYPE_DRI) + return dri_bo_import(bo, data); + else + return drv_prime_bo_import(bo, data); +} - return ret; +static int amdgpu_destroy_bo(struct bo *bo) +{ + if (bo->priv) + return dri_bo_destroy(bo); + else + return drv_gem_bo_destroy(bo); } -static void *amdgpu_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags) +static void *amdgpu_map_bo(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags) { int ret; union drm_amdgpu_gem_mmap gem_map; + if (bo->priv) + return dri_bo_map(bo, vma, plane, map_flags); + memset(&gem_map, 0, sizeof(gem_map)); gem_map.in.handle = bo->handles[plane].u32; @@ -459,6 +229,14 @@ static void *amdgpu_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_ gem_map.out.addr_ptr); } +static int amdgpu_unmap_bo(struct bo *bo, struct vma *vma) +{ + if (bo->priv) + return dri_bo_unmap(bo, vma); + else + return munmap(vma->addr, vma->length); +} + static uint32_t amdgpu_resolve_format(uint32_t format, uint64_t use_flags) { switch (format) { @@ -479,11 +257,11 @@ const struct backend backend_amdgpu = { .name = "amdgpu", .init = amdgpu_init, .close = amdgpu_close, - .bo_create = amdgpu_bo_create, - .bo_destroy = drv_gem_bo_destroy, - .bo_import = drv_prime_bo_import, - .bo_map = amdgpu_bo_map, - .bo_unmap = drv_bo_munmap, + .bo_create = amdgpu_create_bo, + .bo_destroy = amdgpu_destroy_bo, + .bo_import = amdgpu_import_bo, + .bo_map = amdgpu_map_bo, + .bo_unmap = amdgpu_unmap_bo, .resolve_format = amdgpu_resolve_format, }; diff --git a/dri.c b/dri.c new file mode 100644 index 0000000..f8a4cc3 --- /dev/null +++ b/dri.c @@ -0,0 +1,293 @@ +/* + * Copyright 2017 Advanced Micro Devices. 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_AMDGPU + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dri.h" +#include "drv_priv.h" +#include "helpers.h" +#include "util.h" + +static const struct { + uint32_t drm_format; + int dri_image_format; +} drm_to_dri_image_formats[] = { + { DRM_FORMAT_R8, __DRI_IMAGE_FORMAT_R8 }, + { DRM_FORMAT_GR88, __DRI_IMAGE_FORMAT_GR88 }, + { DRM_FORMAT_RGB565, __DRI_IMAGE_FORMAT_RGB565 }, + { DRM_FORMAT_XRGB8888, __DRI_IMAGE_FORMAT_XRGB8888 }, + { DRM_FORMAT_ARGB8888, __DRI_IMAGE_FORMAT_ARGB8888 }, + { DRM_FORMAT_XBGR8888, __DRI_IMAGE_FORMAT_XBGR8888 }, + { DRM_FORMAT_ABGR8888, __DRI_IMAGE_FORMAT_ABGR8888 }, + { DRM_FORMAT_XRGB2101010, __DRI_IMAGE_FORMAT_XRGB2101010 }, + { DRM_FORMAT_ARGB2101010, __DRI_IMAGE_FORMAT_ARGB2101010 }, +}; + +static int drm_format_to_dri_format(uint32_t drm_format) +{ + uint32_t i; + for (i = 0; i < ARRAY_SIZE(drm_to_dri_image_formats); i++) { + if (drm_to_dri_image_formats[i].drm_format == drm_format) + return drm_to_dri_image_formats[i].dri_image_format; + } + + return 0; +} + +static bool lookup_extension(const __DRIextension *const *extensions, const char *name, + int min_version, const __DRIextension **dst) +{ + while (*extensions) { + if ((*extensions)->name && !strcmp((*extensions)->name, name) && + (*extensions)->version >= min_version) { + *dst = *extensions; + return true; + } + + extensions++; + } + + return false; +} + +/* + * The DRI GEM namespace may be different from the minigbm's driver GEM namespace. We have + * to import into minigbm. + */ +static int import_into_minigbm(struct dri_driver *dri, struct bo *bo) +{ + uint32_t handle; + int prime_fd, ret; + + if (!dri->image_extension->queryImage(bo->priv, __DRI_IMAGE_ATTRIB_FD, &prime_fd)) + return -errno; + + ret = drmPrimeFDToHandle(bo->drv->fd, prime_fd, &handle); + if (ret) { + drv_log("drmPrimeFDToHandle failed with %s\n", strerror(errno)); + return ret; + } + + bo->handles[0].u32 = handle; + close(prime_fd); + return 0; +} + +/* + * The caller is responsible for setting drv->priv to a structure that derives from dri_driver. + */ +int dri_init(struct driver *drv, const char *dri_so_path, const char *driver_suffix) +{ + char fname[128]; + const __DRIextension **(*get_extensions)(); + const __DRIextension *loader_extensions[] = { NULL }; + + struct dri_driver *dri = drv->priv; + dri->driver_handle = dlopen(dri_so_path, RTLD_NOW | RTLD_GLOBAL); + if (!dri->driver_handle) + return -ENODEV; + + snprintf(fname, sizeof(fname), __DRI_DRIVER_GET_EXTENSIONS "_%s", driver_suffix); + get_extensions = dlsym(dri->driver_handle, fname); + if (!get_extensions) + goto free_handle; + + dri->extensions = get_extensions(); + if (!dri->extensions) + goto free_handle; + + if (!lookup_extension(dri->extensions, __DRI_CORE, 2, + (const __DRIextension **)&dri->core_extension)) + goto free_handle; + + /* Version 4 for createNewScreen2 */ + if (!lookup_extension(dri->extensions, __DRI_DRI2, 4, + (const __DRIextension **)&dri->dri2_extension)) + goto free_handle; + + dri->device = dri->dri2_extension->createNewScreen2(0, drv_get_fd(drv), loader_extensions, + dri->extensions, &dri->configs, NULL); + if (!dri->device) + goto free_handle; + + dri->context = + dri->dri2_extension->createNewContext(dri->device, *dri->configs, NULL, NULL); + + if (!dri->context) + goto free_screen; + + if (!lookup_extension(dri->core_extension->getExtensions(dri->device), __DRI_IMAGE, 12, + (const __DRIextension **)&dri->image_extension)) + goto free_context; + + if (!lookup_extension(dri->core_extension->getExtensions(dri->device), __DRI2_FLUSH, 4, + (const __DRIextension **)&dri->flush_extension)) + goto free_context; + + return 0; + +free_context: + dri->core_extension->destroyContext(dri->context); +free_screen: + dri->core_extension->destroyScreen(dri->device); +free_handle: + dlclose(dri->driver_handle); + dri->driver_handle = NULL; + return -ENODEV; +} + +/* + * The caller is responsible for freeing drv->priv. + */ +void dri_close(struct driver *drv) +{ + struct dri_driver *dri = drv->priv; + + dri->core_extension->destroyContext(dri->context); + dri->core_extension->destroyScreen(dri->device); + dlclose(dri->driver_handle); + dri->driver_handle = NULL; +} + +int dri_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint64_t use_flags) +{ + unsigned int dri_use; + int ret, dri_format, stride, offset; + struct dri_driver *dri = bo->drv->priv; + + assert(bo->num_planes == 1); + dri_format = drm_format_to_dri_format(format); + + /* Gallium drivers require shared to get the handle and stride. */ + dri_use = __DRI_IMAGE_USE_SHARE; + if (use_flags & BO_USE_SCANOUT) + dri_use |= __DRI_IMAGE_USE_SCANOUT; + if (use_flags & BO_USE_CURSOR) + dri_use |= __DRI_IMAGE_USE_CURSOR; + if (use_flags & (BO_USE_LINEAR | BO_USE_SW)) + dri_use |= __DRI_IMAGE_USE_LINEAR; + + bo->priv = dri->image_extension->createImage(dri->device, width, height, dri_format, + dri_use, NULL); + if (!bo->priv) { + ret = -errno; + return ret; + } + + ret = import_into_minigbm(dri, bo); + if (ret) + goto free_image; + + if (!dri->image_extension->queryImage(bo->priv, __DRI_IMAGE_ATTRIB_STRIDE, &stride)) { + ret = -errno; + goto free_image; + } + + if (!dri->image_extension->queryImage(bo->priv, __DRI_IMAGE_ATTRIB_OFFSET, &offset)) { + ret = -errno; + goto free_image; + } + + bo->strides[0] = stride; + bo->sizes[0] = stride * height; + bo->offsets[0] = offset; + bo->total_size = offset + bo->sizes[0]; + return 0; + +free_image: + dri->image_extension->destroyImage(bo->priv); + return ret; +} + +int dri_bo_import(struct bo *bo, struct drv_import_fd_data *data) +{ + int ret; + struct dri_driver *dri = bo->drv->priv; + + assert(bo->num_planes == 1); + + // clang-format off + bo->priv = dri->image_extension->createImageFromFds(dri->device, data->width, data->height, + data->format, data->fds, bo->num_planes, + (int *)data->strides, + (int *)data->offsets, NULL); + // clang-format on + if (!bo->priv) + return -errno; + + ret = import_into_minigbm(dri, bo); + if (ret) { + dri->image_extension->destroyImage(bo->priv); + return ret; + } + + return 0; +} + +int dri_bo_destroy(struct bo *bo) +{ + struct dri_driver *dri = bo->drv->priv; + + assert(bo->priv); + dri->image_extension->destroyImage(bo->priv); + bo->priv = NULL; + return 0; +} + +/* + * Map an image plane. + * + * This relies on the underlying driver to do a decompressing and/or de-tiling + * blit if necessary, + * + * This function itself is not thread-safe; we rely on the fact that the caller + * locks a per-driver mutex. + */ +void *dri_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags) +{ + struct dri_driver *dri = bo->drv->priv; + int stride; + + /* GBM flags and DRI flags are the same. */ + vma->addr = dri->image_extension->mapImage(dri->context, bo->priv, 0, 0, bo->width, + bo->height, map_flags, &stride, &vma->priv); + if (!vma->addr) + return MAP_FAILED; + + return vma->addr; +} + +int dri_bo_unmap(struct bo *bo, struct vma *vma) +{ + struct dri_driver *dri = bo->drv->priv; + + assert(vma->priv); + dri->image_extension->unmapImage(dri->context, bo->priv, vma->priv); + + /* + * From gbm_dri.c in Mesa: + * + * "Not all DRI drivers use direct maps. They may queue up DMA operations + * on the mapping context. Since there is no explicit gbm flush mechanism, + * we need to flush here." + */ + + dri->flush_extension->flush_with_flags(dri->context, NULL, __DRI2_FLUSH_CONTEXT, 0); + return 0; +} + +#endif diff --git a/dri.h b/dri.h new file mode 100644 index 0000000..d01bc5d --- /dev/null +++ b/dri.h @@ -0,0 +1,37 @@ +/* + * Copyright 2017 Advanced Micro Devices. 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_AMDGPU + +typedef int GLint; +typedef unsigned int GLuint; +typedef unsigned char GLboolean; + +#include "GL/internal/dri_interface.h" +#include "drv.h" + +struct dri_driver { + void *driver_handle; + __DRIscreen *device; + __DRIcontext *context; /* Needed for map/unmap operations. */ + const __DRIextension **extensions; + const __DRIcoreExtension *core_extension; + const __DRIdri2Extension *dri2_extension; + const __DRIimageExtension *image_extension; + const __DRI2flushExtension *flush_extension; + const __DRIconfig **configs; +}; + +int dri_init(struct driver *drv, const char *dri_so_path, const char *driver_suffix); +void dri_close(struct driver *drv); +int dri_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint64_t use_flags); +int dri_bo_import(struct bo *bo, struct drv_import_fd_data *data); +int dri_bo_destroy(struct bo *bo); +void *dri_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags); +int dri_bo_unmap(struct bo *bo, struct vma *vma); + +#endif diff --git a/drv_priv.h b/drv_priv.h index e2bb019..719cd35 100644 --- a/drv_priv.h +++ b/drv_priv.h @@ -96,7 +96,7 @@ struct backend { #define DRM_FORMAT_MOD_LINEAR DRM_FORMAT_MOD_NONE #endif -#define LINEAR_METADATA (struct format_metadata) { 0, 1, DRM_FORMAT_MOD_LINEAR } +#define LINEAR_METADATA (struct format_metadata) { 1, 0, DRM_FORMAT_MOD_LINEAR } // clang-format on #endif From f8ff0f5429bc7ad28f2db091787105f0d5363d88 Mon Sep 17 00:00:00 2001 From: Alistair Strachan Date: Mon, 9 Apr 2018 18:49:51 -0700 Subject: [PATCH 045/269] Fix -Wcast-qual warnings. The Android.mk file enables -Wcast-qual and clang finds problems in gralloc0.cc where the constness of a pointer is being cast away. AOSP master is setting -Werror, so these warnings break the build. Fix them. Change-Id: I8820efab34a15d0653b89303d5390fb9f3eee12d Reviewed-on: https://chromium-review.googlesource.com/1005719 Commit-Ready: Gurchetan Singh Tested-by: Alistair Strachan Reviewed-by: Alistair Strachan Reviewed-by: Gurchetan Singh --- cros_gralloc/gralloc0/gralloc0.cc | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/cros_gralloc/gralloc0/gralloc0.cc b/cros_gralloc/gralloc0/gralloc0.cc index 86c3a4e..df1f62c 100644 --- a/cros_gralloc/gralloc0/gralloc0.cc +++ b/cros_gralloc/gralloc0/gralloc0.cc @@ -97,7 +97,7 @@ static int gralloc0_alloc(alloc_device_t *dev, int w, int h, int format, int usa int32_t ret; bool supported; struct cros_gralloc_buffer_descriptor descriptor; - auto mod = (struct gralloc0_module *)dev->common.module; + auto mod = (struct gralloc0_module const *)dev->common.module; descriptor.width = w; descriptor.height = h; @@ -132,7 +132,7 @@ static int gralloc0_alloc(alloc_device_t *dev, int w, int h, int format, int usa static int gralloc0_free(alloc_device_t *dev, buffer_handle_t handle) { - auto mod = (struct gralloc0_module *)dev->common.module; + auto mod = (struct gralloc0_module const *)dev->common.module; return mod->driver->release(handle); } @@ -171,7 +171,8 @@ static int gralloc0_init(struct gralloc0_module *mod, bool initialize_alloc) static int gralloc0_open(const struct hw_module_t *mod, const char *name, struct hw_device_t **dev) { - auto module = (struct gralloc0_module *)mod; + auto const_module = reinterpret_cast(mod); + auto module = const_cast(const_module); if (module->initialized) { *dev = &module->alloc->common; @@ -192,7 +193,8 @@ static int gralloc0_open(const struct hw_module_t *mod, const char *name, struct static int gralloc0_register_buffer(struct gralloc_module_t const *module, buffer_handle_t handle) { - auto mod = (struct gralloc0_module *)module; + auto const_module = reinterpret_cast(module); + auto mod = const_cast(const_module); if (!mod->initialized) if (gralloc0_init(mod, false)) @@ -203,7 +205,7 @@ static int gralloc0_register_buffer(struct gralloc_module_t const *module, buffe static int gralloc0_unregister_buffer(struct gralloc_module_t const *module, buffer_handle_t handle) { - auto mod = (struct gralloc0_module *)module; + auto mod = (struct gralloc0_module const *)module; return mod->driver->release(handle); } @@ -216,7 +218,7 @@ static int gralloc0_lock(struct gralloc_module_t const *module, buffer_handle_t static int gralloc0_unlock(struct gralloc_module_t const *module, buffer_handle_t handle) { int32_t fence_fd, ret; - auto mod = (struct gralloc0_module *)module; + auto mod = (struct gralloc0_module const *)module; ret = mod->driver->unlock(handle, &fence_fd); if (ret) return ret; @@ -235,7 +237,7 @@ static int gralloc0_perform(struct gralloc_module_t const *module, int op, ...) uint64_t *out_store; buffer_handle_t handle; uint32_t *out_width, *out_height, *out_stride; - auto mod = (struct gralloc0_module *)module; + auto mod = (struct gralloc0_module const *)module; switch (op) { case GRALLOC_DRM_GET_STRIDE: @@ -297,7 +299,7 @@ static int gralloc0_lock_async(struct gralloc_module_t const *module, buffer_han int32_t ret; uint32_t map_flags; uint8_t *addr[DRV_MAX_PLANES]; - auto mod = (struct gralloc0_module *)module; + auto mod = (struct gralloc0_module const *)module; struct rectangle rect = { .x = static_cast(l), .y = static_cast(t), .width = static_cast(w), @@ -328,7 +330,7 @@ static int gralloc0_lock_async(struct gralloc_module_t const *module, buffer_han static int gralloc0_unlock_async(struct gralloc_module_t const *module, buffer_handle_t handle, int *fence_fd) { - auto mod = (struct gralloc0_module *)module; + auto mod = (struct gralloc0_module const *)module; return mod->driver->unlock(handle, fence_fd); } @@ -339,7 +341,7 @@ static int gralloc0_lock_async_ycbcr(struct gralloc_module_t const *module, buff int32_t ret; uint32_t map_flags; uint8_t *addr[DRV_MAX_PLANES] = { nullptr, nullptr, nullptr, nullptr }; - auto mod = (struct gralloc0_module *)module; + auto mod = (struct gralloc0_module const *)module; struct rectangle rect = { .x = static_cast(l), .y = static_cast(t), .width = static_cast(w), From 65141c2fd50777687bc199a5c7da130fdb48fd94 Mon Sep 17 00:00:00 2001 From: Alistair Strachan Date: Mon, 9 Apr 2018 18:50:30 -0700 Subject: [PATCH 046/269] Build fix against latest AOSP master. Move away from using the deprecated header paths in AOSP master. Add explicit dependencies on the header modules and library modules being used. Change-Id: Ifaf159129dd34d2b99f7ee86f6e5fde9276d0aea Reviewed-on: https://chromium-review.googlesource.com/1005720 Commit-Ready: Gurchetan Singh Tested-by: Alistair Strachan Reviewed-by: Alistair Strachan Reviewed-by: Gurchetan Singh --- Android.mk | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/Android.mk b/Android.mk index e75766f..c80b7d4 100644 --- a/Android.mk +++ b/Android.mk @@ -28,10 +28,12 @@ MINIGBM_SRC := \ vgem.c \ virtio_gpu.c -MINIGBM_CPPFLAGS := -std=c++14 -D_GNU_SOURCE=1 -D_FILE_OFFSET_BITS=64 -MINIGBM_CFLAGS := -Wall -Wsign-compare -Wpointer-arith \ - -Wcast-qual -Wcast-align \ - -D_GNU_SOURCE=1 -D_FILE_OFFSET_BITS=64 +MINIGBM_CPPFLAGS := -std=c++14 +MINIGBM_CFLAGS := \ + -D_GNU_SOURCE=1 -D_FILE_OFFSET_BITS=64 \ + -Wall -Wsign-compare -Wpointer-arith \ + -Wcast-qual -Wcast-align \ + -Wno-unused-parameter ifneq ($(filter $(intel_drivers), $(BOARD_GPU_DRIVERS)),) MINIGBM_CPPFLAGS += -DDRV_I915 @@ -44,7 +46,6 @@ MINIGBM_CPPFLAGS += -DDRV_MESON MINIGBM_CFLAGS += -DDRV_MESON endif - include $(CLEAR_VARS) SUBDIRS := cros_gralloc @@ -67,7 +68,10 @@ LOCAL_PROPRIETARY_MODULE := true LOCAL_MODULE_RELATIVE_PATH := hw LOCAL_MODULE_CLASS := SHARED_LIBRARIES LOCAL_MODULE_SUFFIX := $(TARGET_SHLIB_SUFFIX) +LOCAL_HEADER_LIBRARIES += \ + libhardware_headers libnativebase_headers libsystem_headers LOCAL_SHARED_LIBRARIES += libnativewindow libsync liblog +LOCAL_STATIC_LIBRARIES += libarect include $(BUILD_SHARED_LIBRARY) From 478343f363191617619b0899c578fa45e1b637f8 Mon Sep 17 00:00:00 2001 From: "Kristian H. Kristensen" Date: Wed, 4 Apr 2018 14:02:50 -0700 Subject: [PATCH 047/269] minigbm: Consolidate format info in new struct planar_layout This consolidates the relevant information about the planar layouts we support in one place. Change-Id: I6fbfd59f5d56777f612e4cc44e634ed193a435ad Reviewed-on: https://chromium-review.googlesource.com/996646 Commit-Ready: Kristian H. Kristensen Tested-by: Kristian H. Kristensen Reviewed-by: Gurchetan Singh --- drv.c | 63 ---------------------- helpers.c | 155 ++++++++++++++++++++++++++++++++++++++++-------------- helpers.h | 3 ++ 3 files changed, 119 insertions(+), 102 deletions(-) diff --git a/drv.c b/drv.c index 8970d4c..f6420e5 100644 --- a/drv.c +++ b/drv.c @@ -604,69 +604,6 @@ uint32_t drv_resolve_format(struct driver *drv, uint32_t format, uint64_t use_fl return format; } -size_t drv_num_planes_from_format(uint32_t format) -{ - switch (format) { - case DRM_FORMAT_ABGR1555: - case DRM_FORMAT_ABGR2101010: - case DRM_FORMAT_ABGR4444: - case DRM_FORMAT_ABGR8888: - case DRM_FORMAT_ARGB1555: - case DRM_FORMAT_ARGB2101010: - case DRM_FORMAT_ARGB4444: - case DRM_FORMAT_ARGB8888: - case DRM_FORMAT_AYUV: - case DRM_FORMAT_BGR233: - case DRM_FORMAT_BGR565: - case DRM_FORMAT_BGR888: - case DRM_FORMAT_BGRA1010102: - case DRM_FORMAT_BGRA4444: - case DRM_FORMAT_BGRA5551: - case DRM_FORMAT_BGRA8888: - case DRM_FORMAT_BGRX1010102: - case DRM_FORMAT_BGRX4444: - case DRM_FORMAT_BGRX5551: - case DRM_FORMAT_BGRX8888: - case DRM_FORMAT_C8: - case DRM_FORMAT_GR88: - case DRM_FORMAT_R8: - case DRM_FORMAT_RG88: - case DRM_FORMAT_RGB332: - case DRM_FORMAT_RGB565: - case DRM_FORMAT_RGB888: - case DRM_FORMAT_RGBA1010102: - case DRM_FORMAT_RGBA4444: - case DRM_FORMAT_RGBA5551: - case DRM_FORMAT_RGBA8888: - case DRM_FORMAT_RGBX1010102: - case DRM_FORMAT_RGBX4444: - case DRM_FORMAT_RGBX5551: - case DRM_FORMAT_RGBX8888: - case DRM_FORMAT_UYVY: - case DRM_FORMAT_VYUY: - case DRM_FORMAT_XBGR1555: - case DRM_FORMAT_XBGR2101010: - case DRM_FORMAT_XBGR4444: - case DRM_FORMAT_XBGR8888: - case DRM_FORMAT_XRGB1555: - case DRM_FORMAT_XRGB2101010: - case DRM_FORMAT_XRGB4444: - case DRM_FORMAT_XRGB8888: - case DRM_FORMAT_YUYV: - case DRM_FORMAT_YVYU: - return 1; - case DRM_FORMAT_NV12: - case DRM_FORMAT_NV21: - return 2; - case DRM_FORMAT_YVU420: - case DRM_FORMAT_YVU420_ANDROID: - return 3; - } - - drv_log("UNKNOWN FORMAT %d\n", format); - return 0; -} - uint32_t drv_num_buffers_per_bo(struct bo *bo) { uint32_t count = 0; diff --git a/helpers.c b/helpers.c index 94b0d65..6ffb4f4 100644 --- a/helpers.c +++ b/helpers.c @@ -18,37 +18,75 @@ #include "helpers.h" #include "util.h" -static uint32_t subsample_stride(uint32_t stride, uint32_t format, size_t plane) +struct planar_layout { + size_t num_planes; + int horizontal_subsampling[DRV_MAX_PLANES]; + int vertical_subsampling[DRV_MAX_PLANES]; + int bytes_per_pixel[DRV_MAX_PLANES]; +}; + +// clang-format off + +static const struct planar_layout packed_1bpp_layout = { + .num_planes = 1, + .horizontal_subsampling = { 1 }, + .vertical_subsampling = { 1 }, + .bytes_per_pixel = { 1 } +}; + +static const struct planar_layout packed_2bpp_layout = { + .num_planes = 1, + .horizontal_subsampling = { 1 }, + .vertical_subsampling = { 1 }, + .bytes_per_pixel = { 2 } +}; + +static const struct planar_layout packed_3bpp_layout = { + .num_planes = 1, + .horizontal_subsampling = { 1 }, + .vertical_subsampling = { 1 }, + .bytes_per_pixel = { 3 } +}; + +static const struct planar_layout packed_4bpp_layout = { + .num_planes = 1, + .horizontal_subsampling = { 1 }, + .vertical_subsampling = { 1 }, + .bytes_per_pixel = { 4 } +}; + +static const struct planar_layout biplanar_yuv_420_layout = { + .num_planes = 2, + .horizontal_subsampling = { 1, 2 }, + .vertical_subsampling = { 1, 2 }, + .bytes_per_pixel = { 1, 2 } +}; + +static const struct planar_layout triplanar_yuv_420_layout = { + .num_planes = 3, + .horizontal_subsampling = { 1, 2, 2 }, + .vertical_subsampling = { 1, 2, 2 }, + .bytes_per_pixel = { 1, 1, 1 } +}; + +// clang-format on + +static const struct planar_layout *layout_from_format(uint32_t format) { - - if (plane != 0) { - switch (format) { - case DRM_FORMAT_YVU420: - case DRM_FORMAT_YVU420_ANDROID: - stride = DIV_ROUND_UP(stride, 2); - break; - } - } - - return stride; -} - -static uint32_t bpp_from_format(uint32_t format, size_t plane) -{ - assert(plane < drv_num_planes_from_format(format)); - switch (format) { case DRM_FORMAT_BGR233: case DRM_FORMAT_C8: case DRM_FORMAT_R8: case DRM_FORMAT_RGB332: + return &packed_1bpp_layout; + case DRM_FORMAT_YVU420: case DRM_FORMAT_YVU420_ANDROID: - return 8; + return &triplanar_yuv_420_layout; case DRM_FORMAT_NV12: case DRM_FORMAT_NV21: - return (plane == 0) ? 8 : 4; + return &biplanar_yuv_420_layout; case DRM_FORMAT_ABGR1555: case DRM_FORMAT_ABGR4444: @@ -74,11 +112,11 @@ static uint32_t bpp_from_format(uint32_t format, size_t plane) case DRM_FORMAT_XRGB4444: case DRM_FORMAT_YUYV: case DRM_FORMAT_YVYU: - return 16; + return &packed_2bpp_layout; case DRM_FORMAT_BGR888: case DRM_FORMAT_RGB888: - return 24; + return &packed_3bpp_layout; case DRM_FORMAT_ABGR2101010: case DRM_FORMAT_ABGR8888: @@ -97,16 +135,49 @@ static uint32_t bpp_from_format(uint32_t format, size_t plane) case DRM_FORMAT_XBGR8888: case DRM_FORMAT_XRGB2101010: case DRM_FORMAT_XRGB8888: - return 32; + return &packed_4bpp_layout; + + default: + drv_log("UNKNOWN FORMAT %d\n", format); + return NULL; } +} - drv_log("UNKNOWN FORMAT %d\n", format); - return 0; +size_t drv_num_planes_from_format(uint32_t format) +{ + const struct planar_layout *layout = layout_from_format(format); + + /* + * drv_bo_new calls this function early to query number of planes and + * considers 0 planes to mean unknown format, so we have to support + * that. All other layout_from_format() queries can assume that the + * format is supported and that the return value is non-NULL. + */ + + return layout ? layout->num_planes : 0; +} + +uint32_t drv_height_from_format(uint32_t format, uint32_t height, size_t plane) +{ + const struct planar_layout *layout = layout_from_format(format); + + assert(plane < layout->num_planes); + + return DIV_ROUND_UP(height, layout->vertical_subsampling[plane]); +} + +uint32_t drv_bytes_per_pixel_from_format(uint32_t format, size_t plane) +{ + const struct planar_layout *layout = layout_from_format(format); + + assert(plane < layout->num_planes); + + return layout->bytes_per_pixel[plane]; } uint32_t drv_bo_get_stride_in_pixels(struct bo *bo) { - uint32_t bytes_per_pixel = DIV_ROUND_UP(bpp_from_format(bo->format, 0), 8); + uint32_t bytes_per_pixel = drv_bytes_per_pixel_from_format(bo->format, 0); return DIV_ROUND_UP(bo->strides[0], bytes_per_pixel); } @@ -115,7 +186,12 @@ uint32_t drv_bo_get_stride_in_pixels(struct bo *bo) */ uint32_t drv_stride_from_format(uint32_t format, uint32_t width, size_t plane) { - uint32_t stride = DIV_ROUND_UP(width * bpp_from_format(format, plane), 8); + const struct planar_layout *layout = layout_from_format(format); + assert(plane < layout->num_planes); + + uint32_t plane_width = + DIV_ROUND_UP(width, layout->horizontal_subsampling[plane]); + uint32_t stride = plane_width * layout->bytes_per_pixel[plane]; /* * The stride of Android YV12 buffers is required to be aligned to 16 bytes @@ -129,20 +205,21 @@ 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) { - assert(plane < drv_num_planes_from_format(format)); - uint32_t vertical_subsampling; + return stride * drv_height_from_format(format, height, plane); +} - 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; +static uint32_t subsample_stride(uint32_t stride, uint32_t format, size_t plane) +{ + if (plane != 0) { + switch (format) { + case DRM_FORMAT_YVU420: + case DRM_FORMAT_YVU420_ANDROID: + stride = DIV_ROUND_UP(stride, 2); + break; + } } - return stride * DIV_ROUND_UP(height, vertical_subsampling); + return stride; } /* @@ -206,7 +283,7 @@ int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t memset(&create_dumb, 0, sizeof(create_dumb)); create_dumb.height = aligned_height; create_dumb.width = aligned_width; - create_dumb.bpp = bpp_from_format(format, 0); + create_dumb.bpp = layout_from_format(format)->bytes_per_pixel[0] * 8; create_dumb.flags = 0; ret = drmIoctl(bo->drv->fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb); diff --git a/helpers.h b/helpers.h index 6b8818d..b292baf 100644 --- a/helpers.h +++ b/helpers.h @@ -10,8 +10,11 @@ #include "drv.h" #include "helpers_array.h" +uint32_t drv_width_from_format(uint32_t format, uint32_t width, size_t plane); +uint32_t drv_height_from_format(uint32_t format, uint32_t height, 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); +uint32_t drv_bytes_per_pixel_from_format(uint32_t format, size_t plane); int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, uint64_t use_flags); int drv_dumb_bo_destroy(struct bo *bo); From 2eeaf5a03c9ad55b27ced2800b5a5ac97531604c Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Wed, 25 Apr 2018 15:29:32 -0700 Subject: [PATCH 048/269] minigbm: cros_gralloc: fix -Wimplicit-function-declaration warnings in gralloctest MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The arcnext compiler seems to throw more warnings. BUG=none TEST=compile for kevin arc-next Change-Id: Ib7b0518d675db06549312a2e7b814093d75424f5 Reviewed-on: https://chromium-review.googlesource.com/1029354 Commit-Ready: Gurchetan Singh Tested-by: Gurchetan Singh Reviewed-by: Stéphane Marchesin --- cros_gralloc/gralloc0/tests/gralloctest.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cros_gralloc/gralloc0/tests/gralloctest.c b/cros_gralloc/gralloc0/tests/gralloctest.c index 9fc3b88..9160e62 100644 --- a/cros_gralloc/gralloc0/tests/gralloctest.c +++ b/cros_gralloc/gralloc0/tests/gralloctest.c @@ -14,6 +14,8 @@ #define _GNU_SOURCE #include #include +#include +#include #include #include From 292da5365a373a8e1eed603fc3aa16e3595d8252 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Wed, 25 Apr 2018 17:36:59 -0700 Subject: [PATCH 049/269] minigbm: add support for HAL_PIXEL_FORMAT_RGBA_FP16 This is needed to support the following CTS test: android.graphics.cts.BitmapColorSpaceTest#test16bitHardware There have been some rumblings about adding 64-bit formats to : https://lists.freedesktop.org/archives/intel-gvt-dev/2017-July/001469.html However, nothing has landed, so let's just define our own format for the time being. BUG=b:77973662 TEST=Compile for kevin and kevin-arcnext Unfortunately, my P setup refuses to work, so let the lab test. Change-Id: I1fea16400ba6632a8ef17105e27bc7799d2af515 Reviewed-on: https://chromium-review.googlesource.com/1029355 Commit-Ready: Gurchetan Singh Tested-by: Gurchetan Singh Reviewed-by: Gurchetan Singh --- amdgpu.c | 6 +++--- cros_gralloc/cros_gralloc_helpers.cc | 2 ++ cros_gralloc/cros_gralloc_helpers.h | 4 ++++ drv.h | 1 + helpers.c | 13 +++++++++++-- i915.c | 10 +++++----- mediatek.c | 6 +++--- rockchip.c | 6 +++--- 8 files changed, 32 insertions(+), 16 deletions(-) diff --git a/amdgpu.c b/amdgpu.c index 3bf5eb2..b01967a 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -33,9 +33,9 @@ struct amdgpu_priv { int drm_version; }; -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 render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, + DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, + DRM_FORMAT_XBGR16161616, DRM_FORMAT_XRGB8888 }; const static uint32_t texture_source_formats[] = { DRM_FORMAT_GR88, DRM_FORMAT_R8, DRM_FORMAT_NV21, DRM_FORMAT_NV12, DRM_FORMAT_YVU420_ANDROID }; diff --git a/cros_gralloc/cros_gralloc_helpers.cc b/cros_gralloc/cros_gralloc_helpers.cc index c09c2b5..4c9c68f 100644 --- a/cros_gralloc/cros_gralloc_helpers.cc +++ b/cros_gralloc/cros_gralloc_helpers.cc @@ -26,6 +26,8 @@ uint32_t cros_gralloc_convert_format(int format) return DRM_FORMAT_RGB888; case HAL_PIXEL_FORMAT_RGBA_8888: return DRM_FORMAT_ABGR8888; + case HAL_PIXEL_FORMAT_RGBA_FP16: + return DRM_FORMAT_XBGR16161616; case HAL_PIXEL_FORMAT_RGBX_8888: return DRM_FORMAT_XBGR8888; case HAL_PIXEL_FORMAT_YCbCr_420_888: diff --git a/cros_gralloc/cros_gralloc_helpers.h b/cros_gralloc/cros_gralloc_helpers.h index a55eebc..3e160ad 100644 --- a/cros_gralloc/cros_gralloc_helpers.h +++ b/cros_gralloc/cros_gralloc_helpers.h @@ -14,6 +14,10 @@ #include #include +#if ANDROID_VERSION < 0x0900 +#define HAL_PIXEL_FORMAT_RGBA_FP16 0x16 +#endif + constexpr uint32_t cros_gralloc_magic = 0xABCDDCBA; constexpr uint32_t handle_data_size = ((sizeof(struct cros_gralloc_handle) - offsetof(cros_gralloc_handle, fds[0])) / sizeof(int)); diff --git a/drv.h b/drv.h index 09aa33f..c91382e 100644 --- a/drv.h +++ b/drv.h @@ -50,6 +50,7 @@ extern "C" { */ #define DRM_FORMAT_NONE fourcc_code('0', '0', '0', '0') +#define DRM_FORMAT_XBGR16161616 fourcc_code('9', '9', '9', '6') #define DRM_FORMAT_YVU420_ANDROID fourcc_code('9', '9', '9', '7') #define DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED fourcc_code('9', '9', '9', '8') #define DRM_FORMAT_FLEX_YCbCr_420_888 fourcc_code('9', '9', '9', '9') diff --git a/helpers.c b/helpers.c index 6ffb4f4..b0db2c7 100644 --- a/helpers.c +++ b/helpers.c @@ -55,6 +55,13 @@ static const struct planar_layout packed_4bpp_layout = { .bytes_per_pixel = { 4 } }; +static const struct planar_layout packed_8bpp_layout = { + .num_planes = 1, + .horizontal_subsampling = { 1 }, + .vertical_subsampling = { 1 }, + .bytes_per_pixel = { 8 } +}; + static const struct planar_layout biplanar_yuv_420_layout = { .num_planes = 2, .horizontal_subsampling = { 1, 2 }, @@ -137,6 +144,9 @@ static const struct planar_layout *layout_from_format(uint32_t format) case DRM_FORMAT_XRGB8888: return &packed_4bpp_layout; + case DRM_FORMAT_XBGR16161616: + return &packed_8bpp_layout; + default: drv_log("UNKNOWN FORMAT %d\n", format); return NULL; @@ -189,8 +199,7 @@ uint32_t drv_stride_from_format(uint32_t format, uint32_t width, size_t plane) const struct planar_layout *layout = layout_from_format(format); assert(plane < layout->num_planes); - uint32_t plane_width = - DIV_ROUND_UP(width, layout->horizontal_subsampling[plane]); + uint32_t plane_width = DIV_ROUND_UP(width, layout->horizontal_subsampling[plane]); uint32_t stride = plane_width * layout->bytes_per_pixel[plane]; /* diff --git a/i915.c b/i915.c index fc877cb..af9d0ba 100644 --- a/i915.c +++ b/i915.c @@ -21,11 +21,11 @@ #define I915_CACHELINE_SIZE 64 #define I915_CACHELINE_MASK (I915_CACHELINE_SIZE - 1) -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 render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB1555, + DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB565, + DRM_FORMAT_XBGR2101010, DRM_FORMAT_XBGR8888, + DRM_FORMAT_XBGR16161616, DRM_FORMAT_XRGB1555, + DRM_FORMAT_XRGB2101010, DRM_FORMAT_XRGB8888 }; static const uint32_t tileable_texture_source_formats[] = { DRM_FORMAT_GR88, DRM_FORMAT_R8, DRM_FORMAT_UYVY, DRM_FORMAT_YUYV }; diff --git a/mediatek.c b/mediatek.c index cfb60b3..379a119 100644 --- a/mediatek.c +++ b/mediatek.c @@ -23,9 +23,9 @@ struct mediatek_private_map_data { void *gem_addr; }; -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 render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, + DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, + DRM_FORMAT_XBGR16161616, DRM_FORMAT_XRGB8888 }; static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID }; diff --git a/rockchip.c b/rockchip.c index a0d9141..dfa1324 100644 --- a/rockchip.c +++ b/rockchip.c @@ -23,9 +23,9 @@ struct rockchip_private_map_data { void *gem_addr; }; -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 render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, + DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, + DRM_FORMAT_XBGR16161616, DRM_FORMAT_XRGB8888 }; static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_NV12, DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID }; From 222919005b758a0afe24d2c2cc4bac342b575bbd Mon Sep 17 00:00:00 2001 From: "Kristian H. Kristensen" Date: Wed, 4 Apr 2018 13:40:47 -0700 Subject: [PATCH 050/269] minigbm: Drop drv_bo_get_stride_in_pixels() helper Computing "stride in pixels" assumes the pixel size divides the stride, which isn't always the case. This is only used for the cros_gralloc implementation, so lets move the calculation there instead of providing a generic helper for an unhealthy concept. BUG=822346 TEST=test_that graphics_Gbm Change-Id: Iab7a363c5471e4bacef7df7095ef77723adf5e93 Reviewed-on: https://chromium-review.googlesource.com/996645 Commit-Ready: Kristian H. Kristensen Tested-by: Kristian H. Kristensen Reviewed-by: Gurchetan Singh --- cros_gralloc/cros_gralloc_driver.cc | 4 +++- drv.h | 2 +- helpers.c | 6 ------ helpers.h | 2 -- 4 files changed, 4 insertions(+), 10 deletions(-) diff --git a/cros_gralloc/cros_gralloc_driver.cc b/cros_gralloc/cros_gralloc_driver.cc index 9e8d98f..a68023e 100644 --- a/cros_gralloc/cros_gralloc_driver.cc +++ b/cros_gralloc/cros_gralloc_driver.cc @@ -90,6 +90,7 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto uint64_t mod; size_t num_planes; uint32_t resolved_format; + uint32_t bytes_per_pixel; struct bo *bo; struct cros_gralloc_handle *hnd; @@ -135,7 +136,8 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto hnd->format = drv_bo_get_format(bo); hnd->use_flags[0] = static_cast(descriptor->use_flags >> 32); hnd->use_flags[1] = static_cast(descriptor->use_flags); - hnd->pixel_stride = drv_bo_get_stride_in_pixels(bo); + bytes_per_pixel = drv_bytes_per_pixel_from_format(hnd->format, 0); + hnd->pixel_stride = DIV_ROUND_UP(hnd->strides[0], bytes_per_pixel); hnd->magic = cros_gralloc_magic; hnd->droid_format = descriptor->droid_format; hnd->usage = descriptor->producer_usage; diff --git a/drv.h b/drv.h index c91382e..876f13a 100644 --- a/drv.h +++ b/drv.h @@ -155,7 +155,7 @@ uint64_t drv_bo_get_plane_format_modifier(struct bo *bo, size_t plane); uint32_t drv_bo_get_format(struct bo *bo); -uint32_t drv_bo_get_stride_in_pixels(struct bo *bo); +uint32_t drv_bytes_per_pixel_from_format(uint32_t format, size_t plane); uint32_t drv_stride_from_format(uint32_t format, uint32_t width, size_t plane); diff --git a/helpers.c b/helpers.c index b0db2c7..c67787f 100644 --- a/helpers.c +++ b/helpers.c @@ -185,12 +185,6 @@ uint32_t drv_bytes_per_pixel_from_format(uint32_t format, size_t plane) return layout->bytes_per_pixel[plane]; } -uint32_t drv_bo_get_stride_in_pixels(struct bo *bo) -{ - uint32_t bytes_per_pixel = drv_bytes_per_pixel_from_format(bo->format, 0); - return DIV_ROUND_UP(bo->strides[0], bytes_per_pixel); -} - /* * This function returns the stride for a given format, width and plane. */ diff --git a/helpers.h b/helpers.h index b292baf..4c649c2 100644 --- a/helpers.h +++ b/helpers.h @@ -10,11 +10,9 @@ #include "drv.h" #include "helpers_array.h" -uint32_t drv_width_from_format(uint32_t format, uint32_t width, size_t plane); uint32_t drv_height_from_format(uint32_t format, uint32_t height, 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); -uint32_t drv_bytes_per_pixel_from_format(uint32_t format, size_t plane); int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, uint64_t use_flags); int drv_dumb_bo_destroy(struct bo *bo); From bb1f4ddbeca02a3aabf4f5672a8b4b9a21978dc7 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Wed, 2 Aug 2017 05:35:52 +0000 Subject: [PATCH 051/269] Revert "minigbm: i965: Add 64-byte padding at the end of linear buffers" This reverts commit 581f3a5e3089cfd5bb38432eb2874d9a5b132a17. Reason for revert: It looks like the requirements are being removed from Mesa, due to the kernel driver being expected to provide certain guaranties over how it manages the GPU address space, so that they are satisfied (see CL:597567). With this, we can stop overallocating and simplify minigbm code. Original change's description: > minigbm: i965: Add 64-byte padding at the end of linear buffers > > According to the ISL library used now by Mesa i965 driver to manage > surfaces, linear surfaces must have 64-byte padding added at the end, > due to the way how the GPU issues cache requests. > > BUG=b:63957026 > TEST=./cts-tradefed run cts --skip-preconditions --skip-device-info -m > CtsCameraTestCases -t > android.hardware.camera2.cts.MultiViewTest#testDualTextureViewAndImageReaderPreview > on Eve > > Change-Id: I4887449a8e6e090b5ab7925b6f5c764cedd7589f > Reviewed-on: https://chromium-review.googlesource.com/582253 > Commit-Ready: Tomasz Figa > Tested-by: Tomasz Figa > Reviewed-by: Gurchetan Singh BUG=b:63957026 TEST=./cts-tradefed run cts -m CtsCameraTestCases -t android.hardware.camera2.cts.MultiViewTest TEST=./cts-tradefed run cts -m CtsMediaTestCases -t android.media.cts.VideoEncoderTest Change-Id: Id17d65fd9fe81e0152e37e92e8eda39c0fceebf1 Reviewed-on: https://chromium-review.googlesource.com/597529 Commit-Ready: Kristian H. Kristensen Tested-by: Kristian H. Kristensen Reviewed-by: Gurchetan Singh --- i915.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/i915.c b/i915.c index af9d0ba..237ec4d 100644 --- a/i915.c +++ b/i915.c @@ -360,16 +360,6 @@ static int i915_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t h drv_bo_from_format(bo, stride, height, format); } - /* - * Quoting Mesa ISL library: - * - * - For linear surfaces, additional padding of 64 bytes is required at - * the bottom of the surface. This is in addition to the padding - * required above. - */ - if (bo->tiling == I915_TILING_NONE) - bo->total_size += 64; - memset(&gem_create, 0, sizeof(gem_create)); gem_create.size = bo->total_size; From 90b14587a4b2f68f79c26d46b1166150082602d1 Mon Sep 17 00:00:00 2001 From: "Kristian H. Kristensen" Date: Thu, 3 May 2018 20:40:47 +0000 Subject: [PATCH 052/269] Revert "minigbm: i915: Add necessary padding to Android YV12 buffers" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit d846de667cba72121ec579912d0854729f013731. When mesa switched to isl internally, dma-buf import regressed in a few cases where isl was overly strict. One issue was enforcing slice alignment in calculating the minimum size of a buffer. The alignment is required for the slice placement, but not the size. We worked around it in commit d846de667cba72121ec579912d0854729f013731, but mesa commit 4d27c6095e8385cccd225993452baad4d2e35420 fixes the problem and we can now revert the minigbm bandaid. The revert leaves the change to drv_bo_from_format() in place where it was modified to look at the passed in format argument instead of bo->format. Original change's description: > minigbm: i915: Add necessary padding to Android YV12 buffers > > All the regular formats are already aligned by current code, except > Android YV12, which requires height of planes to be unchanged. However > Mesa requires each plane to have at least certain required padding > between planes. Work around this by calculating total BO size with > aligned height to allow padding space to overlap with further planes > and making sure that padding of last plane fits in the buffer. This is > okay, since Mesa requirement seems to indicate that data of the padding > area should not be affected and padding is only needed to satisfy GPU > cache requests. > > Fixes following CTS tests on Intel platforms: > android.media.cts.VideoEncoderTest#testGoogH264FlexArbitraryH > android.media.cts.VideoEncoderTest#testGoogH264FlexNearMaxMin > android.media.cts.VideoEncoderTest#testGoogH264SurfArbitraryH > android.media.cts.VideoEncoderTest#testGoogH264SurfNearMaxMin > > BUG=b:63957026 > TEST=./cts-tradefed run cts -m CtsMediaTestCases -t > android.media.cts.VideoEncoderTest > > Change-Id: I46d44178ba983c0038b630b13b9b281251393f8f > Reviewed-on: https://chromium-review.googlesource.com/592990 > Commit-Ready: Tomasz Figa > Tested-by: Tomasz Figa > Reviewed-by: Gurchetan Singh Bug: b:63957026 Change-Id: I9a0db4f01a7ec206375f8a0ba5219b5c5d9a4c0e Reviewed-on: https://chromium-review.googlesource.com/1042746 Commit-Ready: Kristian H. Kristensen Tested-by: Kristian H. Kristensen Reviewed-by: Stéphane Marchesin Reviewed-by: Gurchetan Singh --- i915.c | 30 +++++------------------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/i915.c b/i915.c index 237ec4d..6eb5c01 100644 --- a/i915.c +++ b/i915.c @@ -333,32 +333,12 @@ static int i915_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t h return ret; /* - * HAL_PIXEL_FORMAT_YV12 requires the buffer height not be aligned, but we need to keep - * total size as with aligned height to ensure enough padding space after each plane to - * satisfy GPU alignment requirements. - * - * We do it by first calling drv_bo_from_format() with aligned height and - * DRM_FORMAT_YVU420, which allows height alignment, saving the total size it calculates - * and then calling it again with requested parameters. - * - * This relies on the fact that i965 driver uses separate surfaces for each plane and - * contents of padding bytes is not affected, as it is only used to satisfy GPU cache - * requests. - * - * This is enforced by Mesa in src/intel/isl/isl_gen8.c, inside - * isl_gen8_choose_image_alignment_el(), which is used for GEN9 and GEN8. + * HAL_PIXEL_FORMAT_YV12 requires that the buffer's height not be aligned. */ - if (format == DRM_FORMAT_YVU420_ANDROID) { - uint32_t unaligned_height = bo->height; - size_t total_size; - - drv_bo_from_format(bo, stride, height, DRM_FORMAT_YVU420); - total_size = bo->total_size; - drv_bo_from_format(bo, stride, unaligned_height, format); - bo->total_size = total_size; - } else { - drv_bo_from_format(bo, stride, height, format); - } + if (format == DRM_FORMAT_YVU420_ANDROID) + height = bo->height; + + drv_bo_from_format(bo, stride, height, format); memset(&gem_create, 0, sizeof(gem_create)); gem_create.size = bo->total_size; From a0e602b84f99141700a5ab1e282ac22d4ea776a0 Mon Sep 17 00:00:00 2001 From: Satyajit Sahu Date: Thu, 3 May 2018 16:10:11 +0530 Subject: [PATCH 053/269] minigbm: For BO_USE_SW usage buffer need not be linear It is incorrect to force linear for BO_USE_SW usage as mapImage in dri_bo_map converts tiled data and returns linear. BUG=b:78200321 TEST=drm_cursor_test completes within 20 seconds. Change-Id: Ifa3ca2218cee9ff52b049a984a70a54f4899965d Signed-off-by: Satyajit Sahu Reviewed-on: https://chromium-review.googlesource.com/1041448 Commit-Ready: Drew Davenport Tested-by: Deepak Sharma Reviewed-by: Gurchetan Singh --- dri.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dri.c b/dri.c index f8a4cc3..8ca00c6 100644 --- a/dri.c +++ b/dri.c @@ -178,7 +178,7 @@ int dri_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t forma dri_use |= __DRI_IMAGE_USE_SCANOUT; if (use_flags & BO_USE_CURSOR) dri_use |= __DRI_IMAGE_USE_CURSOR; - if (use_flags & (BO_USE_LINEAR | BO_USE_SW)) + if (use_flags & BO_USE_LINEAR) dri_use |= __DRI_IMAGE_USE_LINEAR; bo->priv = dri->image_extension->createImage(dri->device, width, height, dri_format, From e8778f00ce4145eb09f57e2ec954308666cc99bf Mon Sep 17 00:00:00 2001 From: "Kristian H. Kristensen" Date: Wed, 4 Apr 2018 14:21:41 -0700 Subject: [PATCH 054/269] i915: Align stride and offset per plane Current code over-aligns the Y-plane dimensions by a factor of two, so as to make sure alignment requirements are still satisfied when the subsampled plane stride and height are divided by two. Instead, this commit changes the approach to align each plane separately after computing the plane width and height. We stop using drv_bo_from_format(), which divides the stride and instead loop through the planes ourselves. BUG=822346 TEST=test_that graphics_Gbm Change-Id: I1ea8f2fb8b1780686d4086f51e9bab759f724d78 Reviewed-on: https://chromium-review.googlesource.com/996647 Commit-Ready: ChromeOS CL Exonerator Bot Tested-by: Kristian H. Kristensen Reviewed-by: Gurchetan Singh --- i915.c | 85 +++++++++++++++++++++++++++++++++++++--------------------- util.h | 3 ++- 2 files changed, 56 insertions(+), 32 deletions(-) diff --git a/i915.c b/i915.c index 6eb5c01..ff88321 100644 --- a/i915.c +++ b/i915.c @@ -6,6 +6,7 @@ #ifdef DRV_I915 +#include #include #include #include @@ -197,13 +198,21 @@ static int i915_align_dimensions(struct bo *bo, uint32_t tiling, uint32_t *strid uint32_t *aligned_height) { struct i915_device *i915 = bo->drv->priv; - uint32_t horizontal_alignment = 4; - uint32_t vertical_alignment = 4; + uint32_t horizontal_alignment; + uint32_t vertical_alignment; switch (tiling) { default: case I915_TILING_NONE: + /* + * The Intel GPU doesn't need any alignment in linear mode, + * but libva requires the allocation stride to be aligned to + * 16 bytes and height to 4 rows. Further, we round up the + * horizontal alignment so that row start on a cache line (64 + * bytes). + */ horizontal_alignment = 64; + vertical_alignment = 4; break; case I915_TILING_X: @@ -222,21 +231,6 @@ static int i915_align_dimensions(struct bo *bo, uint32_t tiling, uint32_t *strid break; } - /* - * The alignment calculated above is based on the full size luma plane and to have chroma - * planes properly aligned with subsampled formats, we need to multiply luma alignment by - * subsampling factor. - */ - switch (bo->format) { - case DRM_FORMAT_YVU420_ANDROID: - case DRM_FORMAT_YVU420: - horizontal_alignment *= 2; - /* Fall through */ - case DRM_FORMAT_NV12: - vertical_alignment *= 2; - break; - } - *aligned_height = ALIGN(bo->height, vertical_alignment); if (i915->gen > 3) { *stride = ALIGN(*stride, horizontal_alignment); @@ -303,12 +297,40 @@ static int i915_init(struct driver *drv) return i915_add_combinations(drv); } +static int i915_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, uint32_t format) +{ + uint32_t offset; + size_t plane; + int ret; + + offset = 0; + for (plane = 0; plane < drv_num_planes_from_format(format); plane++) { + uint32_t stride = drv_stride_from_format(format, width, plane); + uint32_t plane_height = drv_height_from_format(format, height, plane); + + if (bo->tiling != I915_TILING_NONE) + assert(IS_ALIGNED(offset, 4096)); + + ret = i915_align_dimensions(bo, bo->tiling, &stride, &plane_height); + if (ret) + return ret; + + bo->strides[plane] = stride; + bo->sizes[plane] = stride * plane_height; + bo->offsets[plane] = offset; + offset += bo->sizes[plane]; + } + + bo->total_size = offset; + + return 0; +} + 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; @@ -326,19 +348,20 @@ static int i915_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t h bo->format_modifiers[0] = modifier; - stride = drv_stride_from_format(format, width, 0); - - ret = i915_align_dimensions(bo, bo->tiling, &stride, &height); - if (ret) - return ret; - - /* - * HAL_PIXEL_FORMAT_YV12 requires that the buffer's height not be aligned. - */ - if (format == DRM_FORMAT_YVU420_ANDROID) - height = bo->height; - - drv_bo_from_format(bo, stride, height, format); + if (format == DRM_FORMAT_YVU420_ANDROID) { + /* + * We only need to be able to use this as a linear texture, + * which doesn't put any HW restrictions on how we lay it + * out. The Android format does require the stride to be a + * multiple of 16 and expects the Cr and Cb stride to be + * ALIGN(Y_stride / 2, 16), which we can make happen by + * aligning to 32 bytes here. + */ + uint32_t stride = ALIGN(width, 32); + drv_bo_from_format(bo, stride, height, format); + } else { + i915_bo_from_format(bo, width, height, format); + } memset(&gem_create, 0, sizeof(gem_create)); gem_create.size = bo->total_size; diff --git a/util.h b/util.h index fd61d9b..e4e1399 100644 --- a/util.h +++ b/util.h @@ -10,7 +10,8 @@ #define MAX(A, B) ((A) > (B) ? (A) : (B)) #define ARRAY_SIZE(A) (sizeof(A) / sizeof(*(A))) #define PUBLIC __attribute__((visibility("default"))) -#define ALIGN(A, B) (((A) + (B)-1) / (B) * (B)) +#define ALIGN(A, B) (((A) + (B)-1) & ~((B)-1)) +#define IS_ALIGNED(A, B) (ALIGN((A), (B)) == (A)) #define DIV_ROUND_UP(n, d) (((n) + (d)-1) / (d)) #endif From 767c5388899aa02de3eadf0c8a2c4906968e1285 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Sat, 5 May 2018 00:42:12 +0000 Subject: [PATCH 055/269] Revert "minigbm: add support for HAL_PIXEL_FORMAT_RGBA_FP16" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 292da5365a373a8e1eed603fc3aa16e3595d8252. Reason for revert: The Android framework uses successful allocation of HAL_PIXEL_FORMAT_RGBA_FP16 to test for wide-gamut capabilities. We don't want to advertise this, so let's revert. android.graphics.cts.BitmapColorSpaceTest#test16bitHardware can pass if the framework falls back to RGBA8888, as is the plan. Original change's description: > minigbm: add support for HAL_PIXEL_FORMAT_RGBA_FP16 > > This is needed to support the following CTS test: > > android.graphics.cts.BitmapColorSpaceTest#test16bitHardware > > There have been some rumblings about adding 64-bit formats to : > > https://lists.freedesktop.org/archives/intel-gvt-dev/2017-July/001469.html > > However, nothing has landed, so let's just define our own format > for the time being. > > BUG=b:77973662 > TEST=Compile for kevin and kevin-arcnext > Unfortunately, my P setup refuses to work, so let the lab > test. > > Change-Id: I1fea16400ba6632a8ef17105e27bc7799d2af515 > Reviewed-on: https://chromium-review.googlesource.com/1029355 > Commit-Ready: Gurchetan Singh > Tested-by: Gurchetan Singh > Reviewed-by: Gurchetan Singh Bug: b:77973662 Change-Id: I9e4b79b06dd565189a2e783e8453f08af173d84c Reviewed-on: https://chromium-review.googlesource.com/1045805 Commit-Ready: Gurchetan Singh Tested-by: Gurchetan Singh Reviewed-by: Stéphane Marchesin Reviewed-by: Gurchetan Singh --- amdgpu.c | 6 +++--- cros_gralloc/cros_gralloc_helpers.cc | 2 -- cros_gralloc/cros_gralloc_helpers.h | 4 ---- drv.h | 1 - helpers.c | 13 ++----------- i915.c | 10 +++++----- mediatek.c | 6 +++--- rockchip.c | 6 +++--- 8 files changed, 16 insertions(+), 32 deletions(-) diff --git a/amdgpu.c b/amdgpu.c index b01967a..3bf5eb2 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -33,9 +33,9 @@ struct amdgpu_priv { int drm_version; }; -const static uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, - DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, - DRM_FORMAT_XBGR16161616, DRM_FORMAT_XRGB8888 }; +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_GR88, DRM_FORMAT_R8, DRM_FORMAT_NV21, DRM_FORMAT_NV12, DRM_FORMAT_YVU420_ANDROID }; diff --git a/cros_gralloc/cros_gralloc_helpers.cc b/cros_gralloc/cros_gralloc_helpers.cc index 4c9c68f..c09c2b5 100644 --- a/cros_gralloc/cros_gralloc_helpers.cc +++ b/cros_gralloc/cros_gralloc_helpers.cc @@ -26,8 +26,6 @@ uint32_t cros_gralloc_convert_format(int format) return DRM_FORMAT_RGB888; case HAL_PIXEL_FORMAT_RGBA_8888: return DRM_FORMAT_ABGR8888; - case HAL_PIXEL_FORMAT_RGBA_FP16: - return DRM_FORMAT_XBGR16161616; case HAL_PIXEL_FORMAT_RGBX_8888: return DRM_FORMAT_XBGR8888; case HAL_PIXEL_FORMAT_YCbCr_420_888: diff --git a/cros_gralloc/cros_gralloc_helpers.h b/cros_gralloc/cros_gralloc_helpers.h index 3e160ad..a55eebc 100644 --- a/cros_gralloc/cros_gralloc_helpers.h +++ b/cros_gralloc/cros_gralloc_helpers.h @@ -14,10 +14,6 @@ #include #include -#if ANDROID_VERSION < 0x0900 -#define HAL_PIXEL_FORMAT_RGBA_FP16 0x16 -#endif - constexpr uint32_t cros_gralloc_magic = 0xABCDDCBA; constexpr uint32_t handle_data_size = ((sizeof(struct cros_gralloc_handle) - offsetof(cros_gralloc_handle, fds[0])) / sizeof(int)); diff --git a/drv.h b/drv.h index 876f13a..67d763e 100644 --- a/drv.h +++ b/drv.h @@ -50,7 +50,6 @@ extern "C" { */ #define DRM_FORMAT_NONE fourcc_code('0', '0', '0', '0') -#define DRM_FORMAT_XBGR16161616 fourcc_code('9', '9', '9', '6') #define DRM_FORMAT_YVU420_ANDROID fourcc_code('9', '9', '9', '7') #define DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED fourcc_code('9', '9', '9', '8') #define DRM_FORMAT_FLEX_YCbCr_420_888 fourcc_code('9', '9', '9', '9') diff --git a/helpers.c b/helpers.c index c67787f..eaaa937 100644 --- a/helpers.c +++ b/helpers.c @@ -55,13 +55,6 @@ static const struct planar_layout packed_4bpp_layout = { .bytes_per_pixel = { 4 } }; -static const struct planar_layout packed_8bpp_layout = { - .num_planes = 1, - .horizontal_subsampling = { 1 }, - .vertical_subsampling = { 1 }, - .bytes_per_pixel = { 8 } -}; - static const struct planar_layout biplanar_yuv_420_layout = { .num_planes = 2, .horizontal_subsampling = { 1, 2 }, @@ -144,9 +137,6 @@ static const struct planar_layout *layout_from_format(uint32_t format) case DRM_FORMAT_XRGB8888: return &packed_4bpp_layout; - case DRM_FORMAT_XBGR16161616: - return &packed_8bpp_layout; - default: drv_log("UNKNOWN FORMAT %d\n", format); return NULL; @@ -193,7 +183,8 @@ uint32_t drv_stride_from_format(uint32_t format, uint32_t width, size_t plane) const struct planar_layout *layout = layout_from_format(format); assert(plane < layout->num_planes); - uint32_t plane_width = DIV_ROUND_UP(width, layout->horizontal_subsampling[plane]); + uint32_t plane_width = + DIV_ROUND_UP(width, layout->horizontal_subsampling[plane]); uint32_t stride = plane_width * layout->bytes_per_pixel[plane]; /* diff --git a/i915.c b/i915.c index ff88321..8e1871a 100644 --- a/i915.c +++ b/i915.c @@ -22,11 +22,11 @@ #define I915_CACHELINE_SIZE 64 #define I915_CACHELINE_MASK (I915_CACHELINE_SIZE - 1) -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_XBGR16161616, DRM_FORMAT_XRGB1555, - DRM_FORMAT_XRGB2101010, DRM_FORMAT_XRGB8888 }; +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_R8, DRM_FORMAT_UYVY, DRM_FORMAT_YUYV }; diff --git a/mediatek.c b/mediatek.c index 379a119..cfb60b3 100644 --- a/mediatek.c +++ b/mediatek.c @@ -23,9 +23,9 @@ struct mediatek_private_map_data { void *gem_addr; }; -static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, - DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, - DRM_FORMAT_XBGR16161616, DRM_FORMAT_XRGB8888 }; +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_YVU420, DRM_FORMAT_YVU420_ANDROID }; diff --git a/rockchip.c b/rockchip.c index dfa1324..a0d9141 100644 --- a/rockchip.c +++ b/rockchip.c @@ -23,9 +23,9 @@ struct rockchip_private_map_data { void *gem_addr; }; -static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, - DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, - DRM_FORMAT_XBGR16161616, DRM_FORMAT_XRGB8888 }; +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_NV12, DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID }; From 62a9c4ee5a1daa0bd23d1104b64c8625f2eecf93 Mon Sep 17 00:00:00 2001 From: Deepak Sharma Date: Tue, 1 May 2018 12:11:27 -0700 Subject: [PATCH 056/269] minigbm: amdgpu: switch BO allocation domain to GTT from VRAM With SG feature enabled, will move all bo allocation to GTT. BUG=b:69941535 TEST=boot Grunt, run graphics_Stress.tabopenclose Change-Id: If424709315e36e29bc99400d9333df72d5979aa0 Signed-off-by: Deepak Sharma Reviewed-on: https://chromium-review.googlesource.com/1037914 Commit-Ready: Deepak Sharma Tested-by: Deepak Sharma Reviewed-by: Gurchetan Singh --- amdgpu.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/amdgpu.c b/amdgpu.c index 3bf5eb2..83d300c 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -158,14 +158,9 @@ static int amdgpu_create_bo(struct bo *bo, uint32_t width, uint32_t height, uint 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; - } + gem_create.in.domains = AMDGPU_GEM_DOMAIN_GTT; + if (!(use_flags & (BO_USE_SW_READ_OFTEN | BO_USE_SCANOUT))) + gem_create.in.domain_flags |= AMDGPU_GEM_CREATE_CPU_GTT_USWC; /* If drm_version >= 21 everything exposes explicit synchronization primitives and chromeos/arc++ will use them. Disable implicit synchronization. */ From 77b7055a1678b5c1d0d0e44d33cda12d86ca193a Mon Sep 17 00:00:00 2001 From: Satyajit Sahu Date: Thu, 3 May 2018 16:35:24 +0530 Subject: [PATCH 057/269] minigbm: Use the stride value returned by mapImage mapImage can return a different stride value. This value must be used for the mapped address. BUG=b:38152101 b:79346377 TEST=graphics_Sanity autotest passed Change-Id: Ie0eb716291366ae6a047d704f66d24ec41738713 Signed-off-by: Satyajit Sahu Reviewed-on: https://chromium-review.googlesource.com/1041369 Commit-Ready: Bernie Thompson Tested-by: Drew Davenport Reviewed-by: Gurchetan Singh --- dri.c | 6 +++--- drv.c | 1 + drv.h | 1 + gbm.c | 5 +++-- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/dri.c b/dri.c index 8ca00c6..ae491bb 100644 --- a/dri.c +++ b/dri.c @@ -260,11 +260,11 @@ int dri_bo_destroy(struct bo *bo) void *dri_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags) { struct dri_driver *dri = bo->drv->priv; - int stride; /* GBM flags and DRI flags are the same. */ - vma->addr = dri->image_extension->mapImage(dri->context, bo->priv, 0, 0, bo->width, - bo->height, map_flags, &stride, &vma->priv); + vma->addr = + dri->image_extension->mapImage(dri->context, bo->priv, 0, 0, bo->width, bo->height, + map_flags, (int *)&vma->map_strides[plane], &vma->priv); if (!vma->addr) return MAP_FAILED; diff --git a/drv.c b/drv.c index f6420e5..bc1f782 100644 --- a/drv.c +++ b/drv.c @@ -440,6 +440,7 @@ void *drv_bo_map(struct bo *bo, const struct rectangle *rect, uint32_t map_flags } mapping.vma = calloc(1, sizeof(*mapping.vma)); + memcpy(mapping.vma->map_strides, bo->strides, sizeof(mapping.vma->map_strides)); addr = bo->drv->backend->bo_map(bo, mapping.vma, plane, map_flags); if (addr == MAP_FAILED) { *map_data = NULL; diff --git a/drv.h b/drv.h index 67d763e..9ca77d3 100644 --- a/drv.h +++ b/drv.h @@ -84,6 +84,7 @@ struct vma { uint32_t handle; uint32_t map_flags; int32_t refcount; + uint32_t map_strides[DRV_MAX_PLANES]; void *priv; }; diff --git a/gbm.c b/gbm.c index a720461..c12c269 100644 --- a/gbm.c +++ b/gbm.c @@ -233,7 +233,6 @@ PUBLIC void *gbm_bo_map(struct gbm_bo *bo, uint32_t x, uint32_t y, uint32_t widt if (!bo || width == 0 || height == 0 || !stride || !map_data) return NULL; - *stride = gbm_bo_get_plane_stride(bo, 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; @@ -241,7 +240,9 @@ PUBLIC void *gbm_bo_map(struct gbm_bo *bo, uint32_t x, uint32_t y, uint32_t widt if (addr == MAP_FAILED) return MAP_FAILED; - offset = gbm_bo_get_plane_stride(bo, plane) * rect.y; + *stride = ((struct mapping *)*map_data)->vma->map_strides[plane]; + + offset = *stride * rect.y; offset += drv_stride_from_format(bo->gbm_format, rect.x, plane); return (void *)((uint8_t *)addr + offset); } From f4e12f563b77c88a939746254a7375aa216266ce Mon Sep 17 00:00:00 2001 From: Daniel Nicoara Date: Thu, 10 May 2018 17:58:03 -0400 Subject: [PATCH 058/269] minigbm: Update Android.mk to export the include path Allows other applications depending on it to pick up minigbm headers without explicitly specifying the path. BUG=b:78869504 TEST=Compiled application depending on minigbm Change-Id: Ie1681579145620ba330721393f0ad71a00109102 Reviewed-on: https://chromium-review.googlesource.com/1054615 Commit-Ready: Daniel Nicoara Tested-by: Daniel Nicoara Reviewed-by: Gurchetan Singh --- Android.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/Android.mk b/Android.mk index c80b7d4..9169cef 100644 --- a/Android.mk +++ b/Android.mk @@ -81,6 +81,7 @@ LOCAL_STATIC_LIBRARIES := libdrm LOCAL_SRC_FILES += $(MINIGBM_SRC) gbm.c gbm_helpers.c +LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) LOCAL_CFLAGS := $(MINIGBM_CFLAGS) LOCAL_CPPFLAGS := $(MINIGBM_CPPFLAGS) From e430ac52794c8cfab586467d999336dd18b8a5c9 Mon Sep 17 00:00:00 2001 From: Satyajit Sahu Date: Wed, 16 May 2018 14:22:48 +0530 Subject: [PATCH 059/269] minigbm: remove addrlib dependency for arc-cros-gralloc addrlib is not required now. Removing the dependency BUG=b:72972511 TEST=Chrome boots to UI and android play store comes up Change-Id: If0ddfe8bee2bb74bf898479f7e263ae731e8bea9 Signed-off-by: Satyajit Sahu Reviewed-on: https://chromium-review.googlesource.com/1060935 Reviewed-by: Gurchetan Singh --- cros_gralloc/Makefile | 4 ---- 1 file changed, 4 deletions(-) diff --git a/cros_gralloc/Makefile b/cros_gralloc/Makefile index 1583a6f..17e884f 100644 --- a/cros_gralloc/Makefile +++ b/cros_gralloc/Makefile @@ -21,10 +21,6 @@ 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))) From 1bd7b04a3ae68c0314bdee06c559093de9e5a304 Mon Sep 17 00:00:00 2001 From: "Kristian H. Kristensen" Date: Wed, 4 Apr 2018 16:10:42 -0700 Subject: [PATCH 060/269] i915: Add GBM_BO_USE_HW_VIDEO_DECODER use flag This flag is used to indicate that the platform video decoder will be writing into this buffer and that it should be allocated accordingly. On Intel, this means that we have to allocate y-tiled NV12 for libva to be able to decode to the buffer. We force gralloc NV12 allocations to be linear for now, since ARC++ doesn't properly pass modifiers to ChromeOS. BUG=822346 TEST=test_that graphics_Gbm Change-Id: I840c30d22355d26816df718b49717407e2e4620f Reviewed-on: https://chromium-review.googlesource.com/996648 Commit-Ready: ChromeOS CL Exonerator Bot Tested-by: Kristian H. Kristensen Reviewed-by: Kristian H. Kristensen --- cros_gralloc/cros_gralloc_driver.cc | 12 +++++++++++- drv.h | 2 ++ gbm.h | 4 ++++ gbm_helpers.c | 2 ++ i915.c | 9 +++++++++ 5 files changed, 28 insertions(+), 1 deletion(-) diff --git a/cros_gralloc/cros_gralloc_driver.cc b/cros_gralloc/cros_gralloc_driver.cc index a68023e..31282bc 100644 --- a/cros_gralloc/cros_gralloc_driver.cc +++ b/cros_gralloc/cros_gralloc_driver.cc @@ -91,13 +91,23 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto size_t num_planes; uint32_t resolved_format; uint32_t bytes_per_pixel; + uint64_t use_flags; struct bo *bo; struct cros_gralloc_handle *hnd; resolved_format = drv_resolve_format(drv_, descriptor->drm_format, descriptor->use_flags); + use_flags = descriptor->use_flags; + /* + * TODO(b/79682290): ARC++ assumes NV12 is always linear and doesn't + * send modifiers across Wayland protocol, so we or in the + * BO_USE_LINEAR flag here. We need to fix ARC++ to allocate and work + * with tiled buffers. + */ + if (resolved_format == DRM_FORMAT_NV12) + use_flags |= BO_USE_LINEAR; bo = drv_bo_create(drv_, descriptor->width, descriptor->height, resolved_format, - descriptor->use_flags); + use_flags); if (!bo) { drv_log("Failed to create bo.\n"); return -ENOMEM; diff --git a/drv.h b/drv.h index 9ca77d3..d27e845 100644 --- a/drv.h +++ b/drv.h @@ -37,6 +37,8 @@ extern "C" { #define BO_USE_CAMERA_READ (1ull << 14) #define BO_USE_RENDERSCRIPT (1ull << 16) #define BO_USE_TEXTURE (1ull << 17) +#define BO_USE_HW_VIDEO_DECODER (1ull << 18) + /* Map flags */ #define BO_MAP_NONE 0 diff --git a/gbm.h b/gbm.h index da993c2..ce05ce3 100644 --- a/gbm.h +++ b/gbm.h @@ -265,6 +265,10 @@ enum gbm_bo_flags { GBM_BO_USE_SW_READ_RARELY = (1 << 10), GBM_BO_USE_SW_WRITE_OFTEN = (1 << 11), GBM_BO_USE_SW_WRITE_RARELY = (1 << 12), + /** + * The buffer will be written by a video decode accelerator. + */ + GBM_BO_USE_HW_VIDEO_DECODER = (1 << 13), }; int diff --git a/gbm_helpers.c b/gbm_helpers.c index 2683669..81d1680 100644 --- a/gbm_helpers.c +++ b/gbm_helpers.c @@ -40,6 +40,8 @@ uint64_t gbm_convert_usage(uint32_t usage) use_flags |= BO_USE_SW_WRITE_OFTEN; if (usage & GBM_BO_USE_SW_WRITE_RARELY) use_flags |= BO_USE_SW_WRITE_RARELY; + if (usage & GBM_BO_USE_HW_VIDEO_DECODER) + use_flags |= BO_USE_HW_VIDEO_DECODER; return use_flags; } diff --git a/i915.c b/i915.c index 8e1871a..6df6dcc 100644 --- a/i915.c +++ b/i915.c @@ -101,6 +101,10 @@ static int i915_add_kms_item(struct driver *drv, const struct kms_item *item) combo->use_flags |= item->use_flags & ~BO_USE_CURSOR; } + /* If we can scanout NV12, we support all tiling modes. */ + if (item->format == DRM_FORMAT_NV12) + combo->use_flags |= item->use_flags; + if (combo->metadata.modifier == item->modifier) combo->use_flags |= item->use_flags; } @@ -178,6 +182,11 @@ static int i915_add_combinations(struct driver *drv) ARRAY_SIZE(tileable_texture_source_formats), &metadata, texture_use_flags); + /* Support y-tiled NV12 for libva */ + const uint32_t nv12_format = DRM_FORMAT_NV12; + drv_add_combinations(drv, &nv12_format, 1, &metadata, + BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER); + kms_items = drv_query_kms(drv); if (!kms_items) return 0; From 2b682fde2d2fe12b95b434a47466bc69aa08b6bd Mon Sep 17 00:00:00 2001 From: Hirokazu Honda Date: Mon, 21 May 2018 06:32:57 +0000 Subject: [PATCH 061/269] Revert "i915: Add GBM_BO_USE_HW_VIDEO_DECODER use flag" This reverts commit 1bd7b04a3ae68c0314bdee06c559093de9e5a304. Reason for revert: Breaks video decoding on most intel platforms, e.g., caroline and samus Original change's description: > i915: Add GBM_BO_USE_HW_VIDEO_DECODER use flag > > This flag is used to indicate that the platform video decoder will be > writing into this buffer and that it should be allocated > accordingly. On Intel, this means that we have to allocate y-tiled > NV12 for libva to be able to decode to the buffer. > > We force gralloc NV12 allocations to be linear for now, since ARC++ > doesn't properly pass modifiers to ChromeOS. > > BUG=822346 > TEST=test_that graphics_Gbm > > Change-Id: I840c30d22355d26816df718b49717407e2e4620f > Reviewed-on: https://chromium-review.googlesource.com/996648 > Commit-Ready: ChromeOS CL Exonerator Bot > Tested-by: Kristian H. Kristensen > Reviewed-by: Kristian H. Kristensen Bug: 822346, 845076 Change-Id: I7681ddb66e4789951e840821993fc5562a55d1af Reviewed-on: https://chromium-review.googlesource.com/1066032 Tested-by: Hirokazu Honda Reviewed-by: Kuo Jen Wei Reviewed-by: Tomasz Figa --- cros_gralloc/cros_gralloc_driver.cc | 12 +----------- drv.h | 2 -- gbm.h | 4 ---- gbm_helpers.c | 2 -- i915.c | 9 --------- 5 files changed, 1 insertion(+), 28 deletions(-) diff --git a/cros_gralloc/cros_gralloc_driver.cc b/cros_gralloc/cros_gralloc_driver.cc index 31282bc..a68023e 100644 --- a/cros_gralloc/cros_gralloc_driver.cc +++ b/cros_gralloc/cros_gralloc_driver.cc @@ -91,23 +91,13 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto size_t num_planes; uint32_t resolved_format; uint32_t bytes_per_pixel; - uint64_t use_flags; struct bo *bo; struct cros_gralloc_handle *hnd; resolved_format = drv_resolve_format(drv_, descriptor->drm_format, descriptor->use_flags); - use_flags = descriptor->use_flags; - /* - * TODO(b/79682290): ARC++ assumes NV12 is always linear and doesn't - * send modifiers across Wayland protocol, so we or in the - * BO_USE_LINEAR flag here. We need to fix ARC++ to allocate and work - * with tiled buffers. - */ - if (resolved_format == DRM_FORMAT_NV12) - use_flags |= BO_USE_LINEAR; bo = drv_bo_create(drv_, descriptor->width, descriptor->height, resolved_format, - use_flags); + descriptor->use_flags); if (!bo) { drv_log("Failed to create bo.\n"); return -ENOMEM; diff --git a/drv.h b/drv.h index d27e845..9ca77d3 100644 --- a/drv.h +++ b/drv.h @@ -37,8 +37,6 @@ extern "C" { #define BO_USE_CAMERA_READ (1ull << 14) #define BO_USE_RENDERSCRIPT (1ull << 16) #define BO_USE_TEXTURE (1ull << 17) -#define BO_USE_HW_VIDEO_DECODER (1ull << 18) - /* Map flags */ #define BO_MAP_NONE 0 diff --git a/gbm.h b/gbm.h index ce05ce3..da993c2 100644 --- a/gbm.h +++ b/gbm.h @@ -265,10 +265,6 @@ enum gbm_bo_flags { GBM_BO_USE_SW_READ_RARELY = (1 << 10), GBM_BO_USE_SW_WRITE_OFTEN = (1 << 11), GBM_BO_USE_SW_WRITE_RARELY = (1 << 12), - /** - * The buffer will be written by a video decode accelerator. - */ - GBM_BO_USE_HW_VIDEO_DECODER = (1 << 13), }; int diff --git a/gbm_helpers.c b/gbm_helpers.c index 81d1680..2683669 100644 --- a/gbm_helpers.c +++ b/gbm_helpers.c @@ -40,8 +40,6 @@ uint64_t gbm_convert_usage(uint32_t usage) use_flags |= BO_USE_SW_WRITE_OFTEN; if (usage & GBM_BO_USE_SW_WRITE_RARELY) use_flags |= BO_USE_SW_WRITE_RARELY; - if (usage & GBM_BO_USE_HW_VIDEO_DECODER) - use_flags |= BO_USE_HW_VIDEO_DECODER; return use_flags; } diff --git a/i915.c b/i915.c index 6df6dcc..8e1871a 100644 --- a/i915.c +++ b/i915.c @@ -101,10 +101,6 @@ static int i915_add_kms_item(struct driver *drv, const struct kms_item *item) combo->use_flags |= item->use_flags & ~BO_USE_CURSOR; } - /* If we can scanout NV12, we support all tiling modes. */ - if (item->format == DRM_FORMAT_NV12) - combo->use_flags |= item->use_flags; - if (combo->metadata.modifier == item->modifier) combo->use_flags |= item->use_flags; } @@ -182,11 +178,6 @@ static int i915_add_combinations(struct driver *drv) ARRAY_SIZE(tileable_texture_source_formats), &metadata, texture_use_flags); - /* Support y-tiled NV12 for libva */ - const uint32_t nv12_format = DRM_FORMAT_NV12; - drv_add_combinations(drv, &nv12_format, 1, &metadata, - BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER); - kms_items = drv_query_kms(drv); if (!kms_items) return 0; From 3cb5bbacc5c8a79105c868875222696f6b9d8296 Mon Sep 17 00:00:00 2001 From: "Kristian H. Kristensen" Date: Wed, 4 Apr 2018 16:10:42 -0700 Subject: [PATCH 062/269] Reland "i915: Add GBM_BO_USE_HW_VIDEO_DECODER use flag" This is a reland of 1bd7b04a3ae68c0314bdee06c559093de9e5a304 We've landed CL:1070995 which fixes the missing modifier that caused tiling corruption on pre-KBL Intel devices and CL:1072638 which makes the failing vda unittests use SCANOUT_VDA_WRITE as they were supposed to. Original change's description: > i915: Add GBM_BO_USE_HW_VIDEO_DECODER use flag > > This flag is used to indicate that the platform video decoder will be > writing into this buffer and that it should be allocated > accordingly. On Intel, this means that we have to allocate y-tiled > NV12 for libva to be able to decode to the buffer. > > We force gralloc NV12 allocations to be linear for now, since ARC++ > doesn't properly pass modifiers to ChromeOS. > > BUG=822346 > TEST=test_that graphics_Gbm > > Change-Id: I840c30d22355d26816df718b49717407e2e4620f > Reviewed-on: https://chromium-review.googlesource.com/996648 > Commit-Ready: ChromeOS CL Exonerator Bot > Tested-by: Kristian H. Kristensen > Reviewed-by: Kristian H. Kristensen Bug: 822346 Change-Id: Icf0921dc91ac422da26371bffea34b26550b8234 Reviewed-on: https://chromium-review.googlesource.com/1073877 Commit-Ready: Kristian H. Kristensen Tested-by: Kristian H. Kristensen Reviewed-by: Kristian H. Kristensen --- cros_gralloc/cros_gralloc_driver.cc | 12 +++++++++++- drv.h | 2 ++ gbm.h | 4 ++++ gbm_helpers.c | 2 ++ i915.c | 9 +++++++++ 5 files changed, 28 insertions(+), 1 deletion(-) diff --git a/cros_gralloc/cros_gralloc_driver.cc b/cros_gralloc/cros_gralloc_driver.cc index a68023e..31282bc 100644 --- a/cros_gralloc/cros_gralloc_driver.cc +++ b/cros_gralloc/cros_gralloc_driver.cc @@ -91,13 +91,23 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto size_t num_planes; uint32_t resolved_format; uint32_t bytes_per_pixel; + uint64_t use_flags; struct bo *bo; struct cros_gralloc_handle *hnd; resolved_format = drv_resolve_format(drv_, descriptor->drm_format, descriptor->use_flags); + use_flags = descriptor->use_flags; + /* + * TODO(b/79682290): ARC++ assumes NV12 is always linear and doesn't + * send modifiers across Wayland protocol, so we or in the + * BO_USE_LINEAR flag here. We need to fix ARC++ to allocate and work + * with tiled buffers. + */ + if (resolved_format == DRM_FORMAT_NV12) + use_flags |= BO_USE_LINEAR; bo = drv_bo_create(drv_, descriptor->width, descriptor->height, resolved_format, - descriptor->use_flags); + use_flags); if (!bo) { drv_log("Failed to create bo.\n"); return -ENOMEM; diff --git a/drv.h b/drv.h index 9ca77d3..d27e845 100644 --- a/drv.h +++ b/drv.h @@ -37,6 +37,8 @@ extern "C" { #define BO_USE_CAMERA_READ (1ull << 14) #define BO_USE_RENDERSCRIPT (1ull << 16) #define BO_USE_TEXTURE (1ull << 17) +#define BO_USE_HW_VIDEO_DECODER (1ull << 18) + /* Map flags */ #define BO_MAP_NONE 0 diff --git a/gbm.h b/gbm.h index da993c2..ce05ce3 100644 --- a/gbm.h +++ b/gbm.h @@ -265,6 +265,10 @@ enum gbm_bo_flags { GBM_BO_USE_SW_READ_RARELY = (1 << 10), GBM_BO_USE_SW_WRITE_OFTEN = (1 << 11), GBM_BO_USE_SW_WRITE_RARELY = (1 << 12), + /** + * The buffer will be written by a video decode accelerator. + */ + GBM_BO_USE_HW_VIDEO_DECODER = (1 << 13), }; int diff --git a/gbm_helpers.c b/gbm_helpers.c index 2683669..81d1680 100644 --- a/gbm_helpers.c +++ b/gbm_helpers.c @@ -40,6 +40,8 @@ uint64_t gbm_convert_usage(uint32_t usage) use_flags |= BO_USE_SW_WRITE_OFTEN; if (usage & GBM_BO_USE_SW_WRITE_RARELY) use_flags |= BO_USE_SW_WRITE_RARELY; + if (usage & GBM_BO_USE_HW_VIDEO_DECODER) + use_flags |= BO_USE_HW_VIDEO_DECODER; return use_flags; } diff --git a/i915.c b/i915.c index 8e1871a..6df6dcc 100644 --- a/i915.c +++ b/i915.c @@ -101,6 +101,10 @@ static int i915_add_kms_item(struct driver *drv, const struct kms_item *item) combo->use_flags |= item->use_flags & ~BO_USE_CURSOR; } + /* If we can scanout NV12, we support all tiling modes. */ + if (item->format == DRM_FORMAT_NV12) + combo->use_flags |= item->use_flags; + if (combo->metadata.modifier == item->modifier) combo->use_flags |= item->use_flags; } @@ -178,6 +182,11 @@ static int i915_add_combinations(struct driver *drv) ARRAY_SIZE(tileable_texture_source_formats), &metadata, texture_use_flags); + /* Support y-tiled NV12 for libva */ + const uint32_t nv12_format = DRM_FORMAT_NV12; + drv_add_combinations(drv, &nv12_format, 1, &metadata, + BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER); + kms_items = drv_query_kms(drv); if (!kms_items) return 0; From 6bd7885bcfc2bb64fd2c532e1a83fd5d38fd981b Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Wed, 6 Jun 2018 17:15:31 -0700 Subject: [PATCH 063/269] minigbm: run clang-format It's good to do this now and again. BUG=none TEST=none Change-Id: Ie96486b5d34c99a4b00cdfd8488a0468188d35bd Reviewed-on: https://chromium-review.googlesource.com/1089492 Commit-Ready: ChromeOS CL Exonerator Bot Tested-by: Gurchetan Singh Reviewed-by: Gurchetan Singh --- cros_gralloc/cros_gralloc_driver.cc | 4 ++-- helpers.c | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/cros_gralloc/cros_gralloc_driver.cc b/cros_gralloc/cros_gralloc_driver.cc index 31282bc..8096b7f 100644 --- a/cros_gralloc/cros_gralloc_driver.cc +++ b/cros_gralloc/cros_gralloc_driver.cc @@ -106,8 +106,8 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto */ if (resolved_format == DRM_FORMAT_NV12) use_flags |= BO_USE_LINEAR; - bo = drv_bo_create(drv_, descriptor->width, descriptor->height, resolved_format, - use_flags); + + bo = drv_bo_create(drv_, descriptor->width, descriptor->height, resolved_format, use_flags); if (!bo) { drv_log("Failed to create bo.\n"); return -ENOMEM; diff --git a/helpers.c b/helpers.c index eaaa937..4fabfa9 100644 --- a/helpers.c +++ b/helpers.c @@ -183,8 +183,7 @@ uint32_t drv_stride_from_format(uint32_t format, uint32_t width, size_t plane) const struct planar_layout *layout = layout_from_format(format); assert(plane < layout->num_planes); - uint32_t plane_width = - DIV_ROUND_UP(width, layout->horizontal_subsampling[plane]); + uint32_t plane_width = DIV_ROUND_UP(width, layout->horizontal_subsampling[plane]); uint32_t stride = plane_width * layout->bytes_per_pixel[plane]; /* From abe44f62208cfaf1b329703d9043b1004baffb44 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Wed, 6 Jun 2018 17:01:51 -0700 Subject: [PATCH 064/269] minigbm: add support for BG24 Some CTS tests apparently require HAL_PIXEL_FORMAT_RGB_888 now. This format is DRM_FORMAT_BGR888 in . Let's add it to the revelant drivers. BUG=b:80496655 TEST=emerge-eve minigbm, let lab test Change-Id: Ia9dadbd2c17c137262865679af1d97d55b1a7087 Reviewed-on: https://chromium-review.googlesource.com/1089493 Commit-Ready: ChromeOS CL Exonerator Bot Tested-by: Gurchetan Singh Reviewed-by: Ilja H. Friedel --- amdgpu.c | 4 ++-- cros_gralloc/cros_gralloc_helpers.cc | 2 +- i915.c | 8 ++++---- mediatek.c | 4 ++-- msm.c | 3 ++- rockchip.c | 4 ++-- virtio_gpu.c | 4 ++-- 7 files changed, 15 insertions(+), 14 deletions(-) diff --git a/amdgpu.c b/amdgpu.c index 83d300c..4d8d222 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -34,8 +34,8 @@ struct amdgpu_priv { }; const static uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, - DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, - DRM_FORMAT_XRGB8888 }; + DRM_FORMAT_BGR888, DRM_FORMAT_RGB565, + DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888 }; const static uint32_t texture_source_formats[] = { DRM_FORMAT_GR88, DRM_FORMAT_R8, DRM_FORMAT_NV21, DRM_FORMAT_NV12, DRM_FORMAT_YVU420_ANDROID }; diff --git a/cros_gralloc/cros_gralloc_helpers.cc b/cros_gralloc/cros_gralloc_helpers.cc index c09c2b5..12daf4b 100644 --- a/cros_gralloc/cros_gralloc_helpers.cc +++ b/cros_gralloc/cros_gralloc_helpers.cc @@ -23,7 +23,7 @@ uint32_t cros_gralloc_convert_format(int format) case HAL_PIXEL_FORMAT_RGB_565: return DRM_FORMAT_RGB565; case HAL_PIXEL_FORMAT_RGB_888: - return DRM_FORMAT_RGB888; + return DRM_FORMAT_BGR888; case HAL_PIXEL_FORMAT_RGBA_8888: return DRM_FORMAT_ABGR8888; case HAL_PIXEL_FORMAT_RGBX_8888: diff --git a/i915.c b/i915.c index 6df6dcc..a88db6a 100644 --- a/i915.c +++ b/i915.c @@ -23,10 +23,10 @@ #define I915_CACHELINE_MASK (I915_CACHELINE_SIZE - 1) 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 }; + DRM_FORMAT_ARGB8888, DRM_FORMAT_BGR888, + 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_R8, DRM_FORMAT_UYVY, DRM_FORMAT_YUYV }; diff --git a/mediatek.c b/mediatek.c index cfb60b3..64c410f 100644 --- a/mediatek.c +++ b/mediatek.c @@ -24,8 +24,8 @@ struct mediatek_private_map_data { }; static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, - DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, - DRM_FORMAT_XRGB8888 }; + DRM_FORMAT_BGR888, DRM_FORMAT_RGB565, + DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888 }; static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID }; diff --git a/msm.c b/msm.c index fe09de0..420abfd 100644 --- a/msm.c +++ b/msm.c @@ -13,7 +13,8 @@ #define MESA_LLVMPIPE_TILE_ORDER 6 #define MESA_LLVMPIPE_TILE_SIZE (1 << MESA_LLVMPIPE_TILE_ORDER) -static const uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888 }; +static const uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_BGR888, + DRM_FORMAT_XRGB8888 }; static int msm_init(struct driver *drv) { diff --git a/rockchip.c b/rockchip.c index a0d9141..a53a915 100644 --- a/rockchip.c +++ b/rockchip.c @@ -24,8 +24,8 @@ struct rockchip_private_map_data { }; static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, - DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, - DRM_FORMAT_XRGB8888 }; + DRM_FORMAT_BGR888, DRM_FORMAT_RGB565, + DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888 }; static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_NV12, DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID }; diff --git a/virtio_gpu.c b/virtio_gpu.c index 5200b3d..e5729ae 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -26,8 +26,8 @@ #define MESA_LLVMPIPE_TILE_SIZE (1 << MESA_LLVMPIPE_TILE_ORDER) static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, - DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, - DRM_FORMAT_XRGB8888 }; + DRM_FORMAT_BGR888, DRM_FORMAT_RGB565, + DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888 }; static const uint32_t dumb_texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID }; From 9924776cc3150af9812d1ff2fd7803d8ea349b43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20B=C3=A1tyai?= Date: Fri, 15 Jun 2018 15:12:13 +0200 Subject: [PATCH 065/269] minigbm: Build fix for arm64 When compiling for arm64 uint64_t is considered to be unsigned long, which caused a format error. BUG=none TEST=emerge Change-Id: Ic5559ba5dce1725dd34eed60609bc1a65735c7f2 Reviewed-on: https://chromium-review.googlesource.com/1102468 Commit-Ready: ChromeOS CL Exonerator Bot Tested-by: Daniel Batyai Reviewed-by: Gurchetan Singh --- rockchip.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rockchip.c b/rockchip.c index a53a915..ccc0335 100644 --- a/rockchip.c +++ b/rockchip.c @@ -212,7 +212,8 @@ static int rockchip_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint ret = drmIoctl(bo->drv->fd, DRM_IOCTL_ROCKCHIP_GEM_CREATE, &gem_create); if (ret) { - drv_log("DRM_IOCTL_ROCKCHIP_GEM_CREATE failed (size=%llu)\n", gem_create.size); + drv_log("DRM_IOCTL_ROCKCHIP_GEM_CREATE failed (size=%llu)\n", + (unsigned long long)gem_create.size); return ret; } From 293d9e3edfb46d0a988f99a835be16349bea0c3c Mon Sep 17 00:00:00 2001 From: Drew Davenport Date: Wed, 20 Jun 2018 15:46:50 -0600 Subject: [PATCH 066/269] minigbm: DRM_FORMAT_BGR888 for amdgpu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move DRM_FORMAT_BGR888 from render_target_formats to texture_source_formats BUG=b:110472317 TEST=test_that --board=grunt graphics_Gbm Change-Id: I4da4ca1544b0596ef39c24f268c85014ef58ad7e Reviewed-on: https://chromium-review.googlesource.com/1108756 Commit-Ready: ChromeOS CL Exonerator Bot Tested-by: Drew Davenport Reviewed-by: Stéphane Marchesin Reviewed-by: Gurchetan Singh --- amdgpu.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/amdgpu.c b/amdgpu.c index 4d8d222..ee556bc 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -34,11 +34,12 @@ struct amdgpu_priv { }; const static uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, - DRM_FORMAT_BGR888, DRM_FORMAT_RGB565, - DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888 }; + DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, + DRM_FORMAT_XRGB8888 }; -const static uint32_t texture_source_formats[] = { DRM_FORMAT_GR88, DRM_FORMAT_R8, DRM_FORMAT_NV21, - DRM_FORMAT_NV12, DRM_FORMAT_YVU420_ANDROID }; +const static uint32_t texture_source_formats[] = { DRM_FORMAT_BGR888, DRM_FORMAT_GR88, + DRM_FORMAT_R8, DRM_FORMAT_NV21, + DRM_FORMAT_NV12, DRM_FORMAT_YVU420_ANDROID }; static int amdgpu_init(struct driver *drv) { From f8de45da7bbfdab2b211f13371aa75dba6ae93bf Mon Sep 17 00:00:00 2001 From: Alistair Strachan Date: Mon, 25 Jun 2018 14:40:04 -0700 Subject: [PATCH 067/269] Add OWNERS and METADATA. Along with the licensing files required by AOSP. Bug: 77276633 Change-Id: I9b8d8d2f32658750696c453d439a168af2b7f7fb Signed-off-by: Alistair Strachan --- METADATA | 17 +++++++++++++++++ MODULE_LICENSE_BSD | 0 NOTICE | 27 +++++++++++++++++++++++++++ OWNERS | 1 + 4 files changed, 45 insertions(+) create mode 100644 METADATA create mode 100644 MODULE_LICENSE_BSD create mode 100644 NOTICE create mode 100644 OWNERS diff --git a/METADATA b/METADATA new file mode 100644 index 0000000..eb61b45 --- /dev/null +++ b/METADATA @@ -0,0 +1,17 @@ +name: "minigbm" +description: + "" + +third_party { + url { + type: HOMEPAGE + value: "https://www.chromium.org/" + } + url { + type: GIT + value: "https://chromium.googlesource.com/chromiumos/platform/minigbm/" + } + version: "" + last_upgrade_date { year: 2017 month: 6 day: 12 } + license_type: NOTICE +} diff --git a/MODULE_LICENSE_BSD b/MODULE_LICENSE_BSD new file mode 100644 index 0000000..e69de29 diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..3bd5095 --- /dev/null +++ b/NOTICE @@ -0,0 +1,27 @@ +// Copyright (c) 2017 The Chromium OS Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/OWNERS b/OWNERS new file mode 100644 index 0000000..a941078 --- /dev/null +++ b/OWNERS @@ -0,0 +1 @@ +astrachan@google.com From a8a38957d97d8ecc14e57fb16ade8210f913cf87 Mon Sep 17 00:00:00 2001 From: Satyajit Sahu Date: Wed, 27 Jun 2018 12:11:12 +0530 Subject: [PATCH 068/269] minigbm: close bo handle in bo destroy In dri path the bo handle is not closed in bo destroy. This was resulting in memory leak. Closed the bo handle in bo destroy. BUG=b:80546783 TEST=graphis autotest suite Change-Id: I8d9c7fbc87fd80d03be7d9a98ac8aa95f0d175ed Signed-off-by: Satyajit Sahu Reviewed-on: https://chromium-review.googlesource.com/1117975 Commit-Ready: Martin Roth Tested-by: Martin Roth Reviewed-by: Gurchetan Singh --- dri.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/dri.c b/dri.c index ae491bb..f62ef5c 100644 --- a/dri.c +++ b/dri.c @@ -86,6 +86,21 @@ static int import_into_minigbm(struct dri_driver *dri, struct bo *bo) return 0; } +/* + * Close Gem Handle + */ +static void close_gem_handle(uint32_t handle, int fd) +{ + struct drm_gem_close gem_close; + int ret = 0; + + memset(&gem_close, 0, sizeof(gem_close)); + gem_close.handle = handle; + ret = drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &gem_close); + if (ret) + drv_log("DRM_IOCTL_GEM_CLOSE failed (handle=%x) error %d\n", handle, ret); +} + /* * The caller is responsible for setting drv->priv to a structure that derives from dri_driver. */ @@ -194,12 +209,12 @@ int dri_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t forma if (!dri->image_extension->queryImage(bo->priv, __DRI_IMAGE_ATTRIB_STRIDE, &stride)) { ret = -errno; - goto free_image; + goto close_handle; } if (!dri->image_extension->queryImage(bo->priv, __DRI_IMAGE_ATTRIB_OFFSET, &offset)) { ret = -errno; - goto free_image; + goto close_handle; } bo->strides[0] = stride; @@ -208,6 +223,8 @@ int dri_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t forma bo->total_size = offset + bo->sizes[0]; return 0; +close_handle: + close_gem_handle(bo->handles[0].u32, bo->drv->fd); free_image: dri->image_extension->destroyImage(bo->priv); return ret; @@ -243,6 +260,7 @@ int dri_bo_destroy(struct bo *bo) struct dri_driver *dri = bo->drv->priv; assert(bo->priv); + close_gem_handle(bo->handles[0].u32, bo->drv->fd); dri->image_extension->destroyImage(bo->priv); bo->priv = NULL; return 0; From dea0ccbaac1602e0453b79ee6c66785012b00048 Mon Sep 17 00:00:00 2001 From: Miguel Casas Date: Mon, 2 Jul 2018 09:40:25 -0400 Subject: [PATCH 069/269] minigbm: Add BO_USE_HW_VIDEO_DECODER to supported flags This CL adds BO_USE_HW_VIDEO_DECODER to the potential list of flags supported by RockChip, AMD and MediaTek for formats that can be used for video playback -or- for protected buffer allocation. Change-Id: Ib617a4138ecdf2fa00900aacd8afb412f77f78d5 BUG=chromium:857095 TEST=compiled minigbm for the said platforms. Reviewed-on: https://chromium-review.googlesource.com/1117606 Commit-Ready: Miguel Casas Tested-by: Miguel Casas Reviewed-by: Gurchetan Singh --- amdgpu.c | 3 ++- mediatek.c | 11 +++++++++++ rockchip.c | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/amdgpu.c b/amdgpu.c index ee556bc..932d1a8 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -86,7 +86,8 @@ static int amdgpu_init(struct driver *drv) /* YUV formats for camera and display. */ drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata, - BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_SCANOUT); + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_SCANOUT | + BO_USE_HW_VIDEO_DECODER); drv_modify_combination(drv, DRM_FORMAT_NV21, &metadata, BO_USE_SCANOUT); diff --git a/mediatek.c b/mediatek.c index 64c410f..21a10af 100644 --- a/mediatek.c +++ b/mediatek.c @@ -18,6 +18,8 @@ #include "helpers.h" #include "util.h" +#define TILE_TYPE_LINEAR 0 + struct mediatek_private_map_data { void *cached_addr; void *gem_addr; @@ -32,12 +34,21 @@ static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_YVU static int mediatek_init(struct driver *drv) { + struct format_metadata metadata; + 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); + /* Support BO_USE_HW_VIDEO_DECODER for protected content minigbm allocations. */ + metadata.tiling = TILE_TYPE_LINEAR; + metadata.priority = 1; + metadata.modifier = DRM_FORMAT_MOD_LINEAR; + drv_modify_combination(drv, DRM_FORMAT_YVU420, &metadata, BO_USE_HW_VIDEO_DECODER); + drv_modify_combination(drv, DRM_FORMAT_YVU420_ANDROID, &metadata, BO_USE_HW_VIDEO_DECODER); + return drv_modify_linear_combinations(drv); } diff --git a/rockchip.c b/rockchip.c index ccc0335..177f9c7 100644 --- a/rockchip.c +++ b/rockchip.c @@ -127,7 +127,7 @@ static int rockchip_init(struct driver *drv) /* Camera ISP supports only NV12 output. */ drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata, - BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER); /* * R8 format is used for Android's HAL_PIXEL_FORMAT_BLOB and is used for JPEG snapshots * from camera. From 1805a9b9e300f0a9e632dc48c2f82ac764d83fdc Mon Sep 17 00:00:00 2001 From: Alexandre Courbot Date: Mon, 21 May 2018 19:05:10 +0900 Subject: [PATCH 070/269] msm: allow allocation of NV12 dumb buffers Cheza's codec validation requires the ability to import external buffers into the codec driver. However the only possible provider of such buffers so far is the display. Make it possible to allocate dumb NV12 buffers by adding the format to the list of allowed formats, and adjusting the requested buffers' height to include room for the UV plane and extra padding the venus driver requires. BUG=b:80589901 TEST=Checked that VDA unittest's TestDecodeTimeMedian passed in import mode on Cheza. Change-Id: I6993f654a3bf5e64cdf8a1c665c60bb4c7d9cc9a Reviewed-on: https://chromium-review.googlesource.com/1118078 Commit-Ready: Alexandre Courbot Tested-by: Alexandre Courbot Reviewed-by: Tomasz Figa --- msm.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/msm.c b/msm.c index 420abfd..2b9bb48 100644 --- a/msm.c +++ b/msm.c @@ -16,11 +16,16 @@ static const uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_BGR888, DRM_FORMAT_XRGB8888 }; +static const uint32_t supported_formats[] = { DRM_FORMAT_NV12 }; + 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); + drv_add_combinations(drv, supported_formats, ARRAY_SIZE(supported_formats), + &LINEAR_METADATA, BO_USE_TEXTURE_MASK | BO_USE_HW_VIDEO_DECODER); + return drv_modify_linear_combinations(drv); } @@ -34,6 +39,11 @@ static int msm_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_ if (bo->format == DRM_FORMAT_YVU420_ANDROID) height = bo->height; + /* Adjust the height of NV12 buffers to include room for the UV plane */ + /* The extra 12KB at the end are a requirement of the Venus codec driver */ + if (bo->format == DRM_FORMAT_NV12) + height += DIV_ROUND_UP(height, 2) + DIV_ROUND_UP(0x3000, width); + return drv_dumb_bo_create(bo, width, height, format, flags); } From dc8554f4359dd9e1fbb7ecf75c0d02c509168e0d Mon Sep 17 00:00:00 2001 From: Satyajit Sahu Date: Wed, 11 Jul 2018 13:41:56 +0530 Subject: [PATCH 071/269] minigbm: amdgpu: align the stride to 256 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit amdgpu has a requirement of stride to be aligned to 256. Otherwise gpu faults and corruptions are observed for some resolutions. BUG=b:80148696 b:110472790 TEST=graphics autotest suite Change-Id: Ic13c19cd1641a6ce206de9b1016a242ed21c2631 Signed-off-by: Satyajit Sahu Reviewed-on: https://chromium-review.googlesource.com/1133060 Commit-Ready: ChromeOS CL Exonerator Bot Tested-by: Deepak Sharma Reviewed-by: Bas Nieuwenhuizen Reviewed-by: Stéphane Marchesin Reviewed-by: Deepak Sharma Reviewed-by: Gurchetan Singh --- amdgpu.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/amdgpu.c b/amdgpu.c index 932d1a8..eea1232 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -145,10 +145,7 @@ static int amdgpu_create_bo(struct bo *bo, uint32_t width, uint32_t height, uint return dri_bo_create(bo, width, height, format, use_flags); stride = drv_stride_from_format(format, width, 0); - if (format == DRM_FORMAT_YVU420_ANDROID) - stride = ALIGN(stride, 128); - else - stride = ALIGN(stride, 64); + stride = ALIGN(stride,256); drv_bo_from_format(bo, stride, height, format); From a047d4113fc111d33fb4ad4eea196ff9916803b4 Mon Sep 17 00:00:00 2001 From: Satyajit Sahu Date: Thu, 12 Jul 2018 12:29:39 +0530 Subject: [PATCH 072/269] minigbm: increment ref count in drv_bo_import increment the reference count of gem handle in drv_bo_import instead of backend. BUG=b:111378370 TEST=graphics autotest suite Change-Id: I68bc64e421f8505be5cd46874f02ab5c32805f04 Signed-off-by: Satyajit Sahu Reviewed-on: https://chromium-review.googlesource.com/1134720 Reviewed-by: Tomasz Figa Reviewed-by: Gurchetan Singh --- drv.c | 6 ++++++ helpers.c | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drv.c b/drv.c index bc1f782..0976404 100644 --- a/drv.c +++ b/drv.c @@ -360,6 +360,12 @@ struct bo *drv_bo_import(struct driver *drv, struct drv_import_fd_data *data) return NULL; } + for (plane = 0; plane < bo->num_planes; plane++) { + pthread_mutex_lock(&bo->drv->driver_lock); + drv_increment_reference_count(bo->drv, bo, plane); + pthread_mutex_unlock(&bo->drv->driver_lock); + } + for (plane = 0; plane < bo->num_planes; plane++) { bo->strides[plane] = data->strides[plane]; bo->offsets[plane] = data->offsets[plane]; diff --git a/helpers.c b/helpers.c index 4fabfa9..def8475 100644 --- a/helpers.c +++ b/helpers.c @@ -368,12 +368,6 @@ int drv_prime_bo_import(struct bo *bo, struct drv_import_fd_data *data) bo->handles[plane].u32 = prime_handle.handle; } - for (plane = 0; plane < bo->num_planes; plane++) { - pthread_mutex_lock(&bo->drv->driver_lock); - drv_increment_reference_count(bo->drv, bo, plane); - pthread_mutex_unlock(&bo->drv->driver_lock); - } - return 0; } From 3fbaca678398bc3508835757b9fa639e2b6b5da4 Mon Sep 17 00:00:00 2001 From: Alistair Strachan Date: Fri, 13 Jul 2018 08:56:21 -0700 Subject: [PATCH 073/269] Allow minigbm gralloc to coexist with board gralloc. Set the ro.hardware.gralloc property to 'minigbm' to have the new module name be loaded preferentially. Bug: 77276633 Change-Id: Ib247ee08486887bd76b86ed9c8b7d62c58a31af7 Signed-off-by: Alistair Strachan --- Android.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Android.mk b/Android.mk index f6e0c33..1c52e2a 100644 --- a/Android.mk +++ b/Android.mk @@ -61,7 +61,7 @@ include $(MINIGBM_GRALLOC_MK) LOCAL_CFLAGS := $(MINIGBM_CFLAGS) LOCAL_CPPFLAGS := $(MINIGBM_CPPFLAGS) -LOCAL_MODULE := gralloc.$(TARGET_BOARD_PLATFORM) +LOCAL_MODULE := gralloc.minigbm LOCAL_MODULE_TAGS := optional # The preferred path for vendor HALs is /vendor/lib/hw LOCAL_PROPRIETARY_MODULE := true From faeb009164fc35c5ec93a0ab81be7615a22dca02 Mon Sep 17 00:00:00 2001 From: Satyajit Sahu Date: Tue, 7 Aug 2018 15:17:18 +0530 Subject: [PATCH 074/269] minigbm: Opening new fd for dri backend Dri backend is not used for the all use flags. When same fd is shared between dri backend and the minigbm drv, they end up using the same kernel DRI context. BUG=b:111081134 TEST=cheets_SurfaceComposition graphics_Gbm graphics_Gralloc Change-Id: I47ae12391acfc9c947e8281de11472fcdf5dec5b Signed-off-by: Satyajit Sahu Reviewed-on: https://chromium-review.googlesource.com/1164972 Tested-by: Deepak Sharma Reviewed-by: Tomasz Figa Reviewed-by: Gurchetan Singh --- dri.c | 13 +++++++++++-- dri.h | 1 + 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/dri.c b/dri.c index f62ef5c..a9c1ed7 100644 --- a/dri.c +++ b/dri.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -111,9 +112,14 @@ int dri_init(struct driver *drv, const char *dri_so_path, const char *driver_suf const __DRIextension *loader_extensions[] = { NULL }; struct dri_driver *dri = drv->priv; + + dri->fd = open(drmGetRenderDeviceNameFromFd(drv_get_fd(drv)), O_RDWR); + if (dri->fd < 0) + return -ENODEV; + dri->driver_handle = dlopen(dri_so_path, RTLD_NOW | RTLD_GLOBAL); if (!dri->driver_handle) - return -ENODEV; + goto close_dri_fd; snprintf(fname, sizeof(fname), __DRI_DRIVER_GET_EXTENSIONS "_%s", driver_suffix); get_extensions = dlsym(dri->driver_handle, fname); @@ -133,7 +139,7 @@ int dri_init(struct driver *drv, const char *dri_so_path, const char *driver_suf (const __DRIextension **)&dri->dri2_extension)) goto free_handle; - dri->device = dri->dri2_extension->createNewScreen2(0, drv_get_fd(drv), loader_extensions, + dri->device = dri->dri2_extension->createNewScreen2(0, dri->fd, loader_extensions, dri->extensions, &dri->configs, NULL); if (!dri->device) goto free_handle; @@ -161,6 +167,8 @@ int dri_init(struct driver *drv, const char *dri_so_path, const char *driver_suf free_handle: dlclose(dri->driver_handle); dri->driver_handle = NULL; +close_dri_fd: + close(dri->fd); return -ENODEV; } @@ -175,6 +183,7 @@ void dri_close(struct driver *drv) dri->core_extension->destroyScreen(dri->device); dlclose(dri->driver_handle); dri->driver_handle = NULL; + close(dri->fd); } int dri_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, diff --git a/dri.h b/dri.h index d01bc5d..f79de99 100644 --- a/dri.h +++ b/dri.h @@ -14,6 +14,7 @@ typedef unsigned char GLboolean; #include "drv.h" struct dri_driver { + int fd; void *driver_handle; __DRIscreen *device; __DRIcontext *context; /* Needed for map/unmap operations. */ From 79205a57e23f0e9b6dd0ce14a44e4c61112234e2 Mon Sep 17 00:00:00 2001 From: Maksim Sisov Date: Fri, 3 Aug 2018 16:31:20 +0300 Subject: [PATCH 075/269] minigbm: align minigbm functions names with upstream libgbm This patch simply changes some methods' names in order to align them with the upstream ones. It's needed because Chromium/Wayland implementation is going to have a gbm implementation used by a GPU split effort. In order to avoid to have a per compile gn flags, we would like to standartize the gbm APIs and be able to use the same binary without recompilations. In follow-up CLs, I will fix callers and finally remove the old APIs namings in favor of new ones. Change-Id: I850824e7194077c47baa761cddb2947959dff9c3 Reviewed-on: https://chromium-review.googlesource.com/1162170 Commit-Ready: Michael Spang Tested-by: Michael Spang Reviewed-by: Kristian H. Kristensen --- gbm.c | 30 +++++++++++++++++++++++++----- gbm.h | 16 ++++++++++++++++ 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/gbm.c b/gbm.c index c12c269..bab8b6b 100644 --- a/gbm.c +++ b/gbm.c @@ -265,7 +265,7 @@ PUBLIC uint32_t gbm_bo_get_height(struct gbm_bo *bo) PUBLIC uint32_t gbm_bo_get_stride(struct gbm_bo *bo) { - return gbm_bo_get_plane_stride(bo, 0); + return gbm_bo_get_stride_for_plane(bo, 0); } PUBLIC uint32_t gbm_bo_get_stride_or_tiling(struct gbm_bo *bo) @@ -280,7 +280,12 @@ PUBLIC uint32_t gbm_bo_get_format(struct gbm_bo *bo) PUBLIC uint64_t gbm_bo_get_format_modifier(struct gbm_bo *bo) { - return gbm_bo_get_plane_format_modifier(bo, 0); + return gbm_bo_get_modifier(bo); +} + +PUBLIC uint64_t gbm_bo_get_modifier(struct gbm_bo *bo) +{ + return gbm_bo_get_plane_format_modifier(bo, 0); } PUBLIC struct gbm_device *gbm_bo_get_device(struct gbm_bo *bo) @@ -300,7 +305,12 @@ PUBLIC int gbm_bo_get_fd(struct gbm_bo *bo) PUBLIC size_t gbm_bo_get_num_planes(struct gbm_bo *bo) { - return drv_bo_get_num_planes(bo->bo); + return gbm_bo_get_plane_count(bo); +} + +PUBLIC size_t gbm_bo_get_plane_count(struct gbm_bo *bo) +{ + return drv_bo_get_num_planes(bo->bo); } PUBLIC union gbm_bo_handle gbm_bo_get_plane_handle(struct gbm_bo *bo, size_t plane) @@ -315,7 +325,12 @@ PUBLIC int gbm_bo_get_plane_fd(struct gbm_bo *bo, size_t plane) PUBLIC uint32_t gbm_bo_get_plane_offset(struct gbm_bo *bo, size_t plane) { - return drv_bo_get_plane_offset(bo->bo, plane); + return gbm_bo_get_offset(bo, plane); +} + +PUBLIC uint32_t gbm_bo_get_offset(struct gbm_bo *bo, size_t plane) +{ + return drv_bo_get_plane_offset(bo->bo, plane); } PUBLIC uint32_t gbm_bo_get_plane_size(struct gbm_bo *bo, size_t plane) @@ -325,7 +340,12 @@ PUBLIC uint32_t gbm_bo_get_plane_size(struct gbm_bo *bo, size_t plane) PUBLIC uint32_t gbm_bo_get_plane_stride(struct gbm_bo *bo, size_t plane) { - return drv_bo_get_plane_stride(bo->bo, plane); + return gbm_bo_get_stride_for_plane(bo, plane); +} + +PUBLIC uint32_t gbm_bo_get_stride_for_plane(struct gbm_bo *bo, size_t plane) +{ + return drv_bo_get_plane_stride(bo->bo, plane); } PUBLIC uint64_t gbm_bo_get_plane_format_modifier(struct gbm_bo *bo, size_t plane) diff --git a/gbm.h b/gbm.h index ce05ce3..0398ac2 100644 --- a/gbm.h +++ b/gbm.h @@ -376,9 +376,13 @@ gbm_bo_get_stride_or_tiling(struct gbm_bo *bo); uint32_t gbm_bo_get_format(struct gbm_bo *bo); +/* Deprecated */ uint64_t gbm_bo_get_format_modifier(struct gbm_bo *bo); +uint64_t +gbm_bo_get_modifier(struct gbm_bo *bo); + struct gbm_device * gbm_bo_get_device(struct gbm_bo *bo); @@ -388,24 +392,36 @@ gbm_bo_get_handle(struct gbm_bo *bo); int gbm_bo_get_fd(struct gbm_bo *bo); +/* Deprecated */ size_t gbm_bo_get_num_planes(struct gbm_bo *bo); +size_t +gbm_bo_get_plane_count(struct gbm_bo *bo); + union gbm_bo_handle gbm_bo_get_plane_handle(struct gbm_bo *bo, size_t plane); int gbm_bo_get_plane_fd(struct gbm_bo *bo, size_t plane); +/* Deprecated */ uint32_t gbm_bo_get_plane_offset(struct gbm_bo *bo, size_t plane); +uint32_t +gbm_bo_get_offset(struct gbm_bo *bo, size_t plane); + uint32_t gbm_bo_get_plane_size(struct gbm_bo *bo, size_t plane); +/* Deprecated */ uint32_t gbm_bo_get_plane_stride(struct gbm_bo *bo, size_t plane); +uint32_t +gbm_bo_get_stride_for_plane(struct gbm_bo *bo, size_t plane); + uint64_t gbm_bo_get_plane_format_modifier(struct gbm_bo *bo, size_t plane); From ff1ecaf1014df4cb9ca36c5a270647a9934aaa99 Mon Sep 17 00:00:00 2001 From: Maksim Sisov Date: Fri, 10 Aug 2018 14:53:34 +0300 Subject: [PATCH 076/269] minigbm: fixup! align minigbm functions names with upstream libgbm Adding missing plane handle API renaming. Change-Id: I33c4b4bcc5097ca568c95eb8c3718c3f790fd996 Reviewed-on: https://chromium-review.googlesource.com/1170773 Commit-Ready: Maksim Sisov Tested-by: Maksim Sisov Reviewed-by: Gurchetan Singh --- gbm.c | 9 +++++++-- gbm.h | 4 ++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/gbm.c b/gbm.c index bab8b6b..99d993f 100644 --- a/gbm.c +++ b/gbm.c @@ -295,7 +295,7 @@ PUBLIC struct gbm_device *gbm_bo_get_device(struct gbm_bo *bo) PUBLIC union gbm_bo_handle gbm_bo_get_handle(struct gbm_bo *bo) { - return gbm_bo_get_plane_handle(bo, 0); + return gbm_bo_get_handle_for_plane(bo, 0); } PUBLIC int gbm_bo_get_fd(struct gbm_bo *bo) @@ -315,7 +315,12 @@ PUBLIC size_t gbm_bo_get_plane_count(struct gbm_bo *bo) PUBLIC union gbm_bo_handle gbm_bo_get_plane_handle(struct gbm_bo *bo, size_t plane) { - return (union gbm_bo_handle)drv_bo_get_plane_handle(bo->bo, plane).u64; + return gbm_bo_get_handle_for_plane(bo, plane); +} + +PUBLIC union gbm_bo_handle gbm_bo_get_handle_for_plane(struct gbm_bo* bo, size_t plane) +{ + return (union gbm_bo_handle)drv_bo_get_plane_handle(bo->bo, plane).u64; } PUBLIC int gbm_bo_get_plane_fd(struct gbm_bo *bo, size_t plane) diff --git a/gbm.h b/gbm.h index 0398ac2..58ce07b 100644 --- a/gbm.h +++ b/gbm.h @@ -399,9 +399,13 @@ gbm_bo_get_num_planes(struct gbm_bo *bo); size_t gbm_bo_get_plane_count(struct gbm_bo *bo); +/* Deprecated */ union gbm_bo_handle gbm_bo_get_plane_handle(struct gbm_bo *bo, size_t plane); +union gbm_bo_handle +gbm_bo_get_handle_for_plane(struct gbm_bo* bo, size_t plane); + int gbm_bo_get_plane_fd(struct gbm_bo *bo, size_t plane); From af94db9f0ad425559d34e654a8a6ed70afa1f3a9 Mon Sep 17 00:00:00 2001 From: Keiichi Watanabe Date: Mon, 6 Aug 2018 18:37:21 +0900 Subject: [PATCH 077/269] minigbm: adjust height of NV12 buffer in helper When the format is NV12, additional buffer is required for the UV plane. Though size adjustment for this requirement is currently implemented only in the msm driver, it is not specific to this device. This commit moves the adjustment to helper function 'drv_dumb_bo_create', which is called from each driver. BUG=chromium:852302 TEST=video playback on msm Change-Id: I690f79ccc6a2c99e680b0d293ffa6002f74ae6bf Signed-off-by: Keiichi Watanabe Reviewed-on: https://chromium-review.googlesource.com/1163582 Reviewed-by: Tomasz Figa Reviewed-by: Gurchetan Singh --- helpers.c | 21 +++++++++++++-------- msm.c | 9 ++++++--- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/helpers.c b/helpers.c index def8475..463c1b3 100644 --- a/helpers.c +++ b/helpers.c @@ -261,16 +261,21 @@ int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t aligned_width = width; aligned_height = height; - if (format == DRM_FORMAT_YVU420_ANDROID) { - /* - * Align width to 32 pixels, so chroma strides are 16 bytes as - * Android requires. - */ + switch (format) { + case DRM_FORMAT_YVU420_ANDROID: + /* Align width to 32 pixels, so chroma strides are 16 bytes as + * Android requires. */ aligned_width = ALIGN(width, 32); - } - - if (format == DRM_FORMAT_YVU420_ANDROID || format == DRM_FORMAT_YVU420) { + /* Adjust the height to include room for chroma planes */ aligned_height = 3 * DIV_ROUND_UP(height, 2); + break; + case DRM_FORMAT_YVU420: + case DRM_FORMAT_NV12: + /* Adjust the height to include room for chroma planes */ + aligned_height = 3 * DIV_ROUND_UP(height, 2); + break; + default: + break; } memset(&create_dumb, 0, sizeof(create_dumb)); diff --git a/msm.c b/msm.c index 2b9bb48..5f77c8d 100644 --- a/msm.c +++ b/msm.c @@ -39,10 +39,13 @@ static int msm_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_ if (bo->format == DRM_FORMAT_YVU420_ANDROID) height = bo->height; - /* Adjust the height of NV12 buffers to include room for the UV plane */ - /* The extra 12KB at the end are a requirement of the Venus codec driver */ + /* + * The extra 12KB at the end are a requirement of the Venus codec driver. + * Since |height| will be multiplied by 3/2 in drv_dumb_bo_create, + * we multiply this padding by 2/3 here. + */ if (bo->format == DRM_FORMAT_NV12) - height += DIV_ROUND_UP(height, 2) + DIV_ROUND_UP(0x3000, width); + height += 2 * DIV_ROUND_UP(0x3000, 3 * width); return drv_dumb_bo_create(bo, width, height, format, flags); } From a13dda71b4b9568c4e65fef0bc8e4c362ba3fcf3 Mon Sep 17 00:00:00 2001 From: Keiichi Watanabe Date: Thu, 2 Aug 2018 22:45:05 +0900 Subject: [PATCH 078/269] minigbm: support NV12 in virtio_gpu To use vivid on VM as an external camera, virtio_gpu has to support NV12. BUG=chromium:852302 TEST=Use camera app on betty by using vivid as an external camera Change-Id: I84ddcbae473a06337918328afe1db8d32003ad84 Signed-off-by: Keiichi Watanabe Reviewed-on: https://chromium-review.googlesource.com/1160434 Reviewed-by: Tomasz Figa Reviewed-by: Gurchetan Singh --- virtio_gpu.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/virtio_gpu.c b/virtio_gpu.c index e5729ae..9a45eab 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -30,7 +30,8 @@ static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMA DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888 }; static const uint32_t dumb_texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_YVU420, - DRM_FORMAT_YVU420_ANDROID }; + DRM_FORMAT_YVU420_ANDROID, + DRM_FORMAT_NV12 }; static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_RG88 }; @@ -63,8 +64,10 @@ static uint32_t translate_format(uint32_t drm_fourcc, uint32_t plane) static int virtio_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, uint64_t use_flags) { - width = ALIGN(width, MESA_LLVMPIPE_TILE_SIZE); - height = ALIGN(height, MESA_LLVMPIPE_TILE_SIZE); + if (bo->format != DRM_FORMAT_R8) { + width = ALIGN(width, MESA_LLVMPIPE_TILE_SIZE); + height = ALIGN(height, MESA_LLVMPIPE_TILE_SIZE); + } /* HAL_PIXEL_FORMAT_YV12 requires that the buffer's height not be aligned. */ if (bo->format == DRM_FORMAT_YVU420_ANDROID) @@ -187,6 +190,11 @@ static int virtio_gpu_init(struct driver *drv) ARRAY_SIZE(dumb_texture_source_formats), &LINEAR_METADATA, BO_USE_TEXTURE_MASK); + drv_modify_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA, + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); + drv_modify_combination(drv, DRM_FORMAT_R8, &LINEAR_METADATA, + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); + return drv_modify_linear_combinations(drv); } @@ -283,6 +291,9 @@ static uint32_t virtio_gpu_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: From 79155d78228bd1ef9931a2d0f1e3d36198e018ef Mon Sep 17 00:00:00 2001 From: Keiichi Watanabe Date: Mon, 13 Aug 2018 16:44:54 +0900 Subject: [PATCH 079/269] minigbm: run clang-format Though presubmit.sh requires formatting by clang-format, some files are not formatted. BUG=None TEST=compile Change-Id: I828dd85536cb94dc98cd11e83ec86af53a425070 Signed-off-by: Keiichi Watanabe Reviewed-on: https://chromium-review.googlesource.com/1172241 Reviewed-by: Gurchetan Singh --- amdgpu.c | 2 +- cros_gralloc/gralloc0/gralloc0.cc | 16 ++++++++-------- gbm.c | 12 ++++++------ helpers.c | 12 ++++++------ i915.c | 4 +--- 5 files changed, 22 insertions(+), 24 deletions(-) diff --git a/amdgpu.c b/amdgpu.c index eea1232..efba3da 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -145,7 +145,7 @@ static int amdgpu_create_bo(struct bo *bo, uint32_t width, uint32_t height, uint return dri_bo_create(bo, width, height, format, use_flags); stride = drv_stride_from_format(format, width, 0); - stride = ALIGN(stride,256); + stride = ALIGN(stride, 256); drv_bo_from_format(bo, stride, height, format); diff --git a/cros_gralloc/gralloc0/gralloc0.cc b/cros_gralloc/gralloc0/gralloc0.cc index df1f62c..b645b3f 100644 --- a/cros_gralloc/gralloc0/gralloc0.cc +++ b/cros_gralloc/gralloc0/gralloc0.cc @@ -300,10 +300,10 @@ static int gralloc0_lock_async(struct gralloc_module_t const *module, buffer_han uint32_t map_flags; uint8_t *addr[DRV_MAX_PLANES]; auto mod = (struct gralloc0_module const *)module; - struct rectangle rect = { .x = static_cast(l), - .y = static_cast(t), - .width = static_cast(w), - .height = static_cast(h) }; + struct rectangle rect = {.x = static_cast(l), + .y = static_cast(t), + .width = static_cast(w), + .height = static_cast(h) }; auto hnd = cros_gralloc_convert_handle(handle); if (!hnd) { @@ -342,10 +342,10 @@ static int gralloc0_lock_async_ycbcr(struct gralloc_module_t const *module, buff uint32_t map_flags; uint8_t *addr[DRV_MAX_PLANES] = { nullptr, nullptr, nullptr, nullptr }; auto mod = (struct gralloc0_module const *)module; - struct rectangle rect = { .x = static_cast(l), - .y = static_cast(t), - .width = static_cast(w), - .height = static_cast(h) }; + struct rectangle rect = {.x = static_cast(l), + .y = static_cast(t), + .width = static_cast(w), + .height = static_cast(h) }; auto hnd = cros_gralloc_convert_handle(handle); if (!hnd) { diff --git a/gbm.c b/gbm.c index 99d993f..e265e36 100644 --- a/gbm.c +++ b/gbm.c @@ -229,7 +229,7 @@ PUBLIC void *gbm_bo_map(struct gbm_bo *bo, uint32_t x, uint32_t y, uint32_t widt void *addr; off_t offset; uint32_t map_flags; - struct rectangle rect = { .x = x, .y = y, .width = width, .height = height }; + struct rectangle rect = {.x = x, .y = y, .width = width, .height = height }; if (!bo || width == 0 || height == 0 || !stride || !map_data) return NULL; @@ -265,7 +265,7 @@ PUBLIC uint32_t gbm_bo_get_height(struct gbm_bo *bo) PUBLIC uint32_t gbm_bo_get_stride(struct gbm_bo *bo) { - return gbm_bo_get_stride_for_plane(bo, 0); + return gbm_bo_get_stride_for_plane(bo, 0); } PUBLIC uint32_t gbm_bo_get_stride_or_tiling(struct gbm_bo *bo) @@ -285,7 +285,7 @@ PUBLIC uint64_t gbm_bo_get_format_modifier(struct gbm_bo *bo) PUBLIC uint64_t gbm_bo_get_modifier(struct gbm_bo *bo) { - return gbm_bo_get_plane_format_modifier(bo, 0); + return gbm_bo_get_plane_format_modifier(bo, 0); } PUBLIC struct gbm_device *gbm_bo_get_device(struct gbm_bo *bo) @@ -310,7 +310,7 @@ PUBLIC size_t gbm_bo_get_num_planes(struct gbm_bo *bo) PUBLIC size_t gbm_bo_get_plane_count(struct gbm_bo *bo) { - return drv_bo_get_num_planes(bo->bo); + return drv_bo_get_num_planes(bo->bo); } PUBLIC union gbm_bo_handle gbm_bo_get_plane_handle(struct gbm_bo *bo, size_t plane) @@ -335,7 +335,7 @@ PUBLIC uint32_t gbm_bo_get_plane_offset(struct gbm_bo *bo, size_t plane) PUBLIC uint32_t gbm_bo_get_offset(struct gbm_bo *bo, size_t plane) { - return drv_bo_get_plane_offset(bo->bo, plane); + return drv_bo_get_plane_offset(bo->bo, plane); } PUBLIC uint32_t gbm_bo_get_plane_size(struct gbm_bo *bo, size_t plane) @@ -350,7 +350,7 @@ PUBLIC uint32_t gbm_bo_get_plane_stride(struct gbm_bo *bo, size_t plane) PUBLIC uint32_t gbm_bo_get_stride_for_plane(struct gbm_bo *bo, size_t plane) { - return drv_bo_get_plane_stride(bo->bo, plane); + return drv_bo_get_plane_stride(bo->bo, plane); } PUBLIC uint64_t gbm_bo_get_plane_format_modifier(struct gbm_bo *bo, size_t plane) diff --git a/helpers.c b/helpers.c index 463c1b3..be2c403 100644 --- a/helpers.c +++ b/helpers.c @@ -494,9 +494,9 @@ void drv_add_combinations(struct driver *drv, const uint32_t *formats, uint32_t uint32_t i; for (i = 0; i < num_formats; i++) { - struct combination combo = { .format = formats[i], - .metadata = *metadata, - .use_flags = use_flags }; + struct combination combo = {.format = formats[i], + .metadata = *metadata, + .use_flags = use_flags }; drv_array_append(drv->combos, &combo); } @@ -590,9 +590,9 @@ struct drv_array *drv_query_kms(struct driver *drv) } if (!found) { - struct kms_item item = { .format = plane->formats[j], - .modifier = DRM_FORMAT_MOD_LINEAR, - .use_flags = use_flag }; + struct kms_item item = {.format = plane->formats[j], + .modifier = DRM_FORMAT_MOD_LINEAR, + .use_flags = use_flag }; drv_array_append(kms_items, &item); } diff --git a/i915.c b/i915.c index a88db6a..e01c0e2 100644 --- a/i915.c +++ b/i915.c @@ -419,9 +419,7 @@ static int i915_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint32_t 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, + I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED, DRM_FORMAT_MOD_LINEAR, }; uint64_t modifier; From d706a8c4f90e51220f21c2b3c8722fe49655e9e2 Mon Sep 17 00:00:00 2001 From: Keiichi Watanabe Date: Mon, 13 Aug 2018 16:54:56 +0900 Subject: [PATCH 080/269] minigbm: move height adjustments to helper function Because HAL_PIXEL_FORMAT_YV12 requires that height is not aligned, adjustments are needed when the format is DRM_FORMAT_YVU420_ANDROID. This adjustment was done in each driver, but it can be moved to the helper function. BUG=None TEST=VDA test in import mode on Cheza Change-Id: I23a8a6e674664e80c30ea66b75d79e10edc28d5d Signed-off-by: Keiichi Watanabe Reviewed-on: https://chromium-review.googlesource.com/1172262 Reviewed-by: Tomasz Figa Reviewed-by: Gurchetan Singh --- helpers.c | 7 +++++-- msm.c | 4 ---- vgem.c | 4 ---- virtio_gpu.c | 4 ---- 4 files changed, 5 insertions(+), 14 deletions(-) diff --git a/helpers.c b/helpers.c index be2c403..b780ff6 100644 --- a/helpers.c +++ b/helpers.c @@ -266,8 +266,11 @@ int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t /* Align width to 32 pixels, so chroma strides are 16 bytes as * Android requires. */ aligned_width = ALIGN(width, 32); - /* Adjust the height to include room for chroma planes */ - aligned_height = 3 * DIV_ROUND_UP(height, 2); + /* Adjust the height to include room for chroma planes. + * + * HAL_PIXEL_FORMAT_YV12 requires that the buffer's height not + * be aligned. */ + aligned_height = 3 * DIV_ROUND_UP(bo->height, 2); break; case DRM_FORMAT_YVU420: case DRM_FORMAT_NV12: diff --git a/msm.c b/msm.c index 5f77c8d..cfceaf1 100644 --- a/msm.c +++ b/msm.c @@ -35,10 +35,6 @@ static int msm_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_ width = ALIGN(width, MESA_LLVMPIPE_TILE_SIZE); height = ALIGN(height, MESA_LLVMPIPE_TILE_SIZE); - /* HAL_PIXEL_FORMAT_YV12 requires that the buffer's height not be aligned. */ - if (bo->format == DRM_FORMAT_YVU420_ANDROID) - height = bo->height; - /* * The extra 12KB at the end are a requirement of the Venus codec driver. * Since |height| will be multiplied by 3/2 in drv_dumb_bo_create, diff --git a/vgem.c b/vgem.c index 5380b78..14691d1 100644 --- a/vgem.c +++ b/vgem.c @@ -35,10 +35,6 @@ static int vgem_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32 width = ALIGN(width, MESA_LLVMPIPE_TILE_SIZE); height = ALIGN(height, MESA_LLVMPIPE_TILE_SIZE); - /* HAL_PIXEL_FORMAT_YV12 requires that the buffer's height not be aligned. */ - if (bo->format == DRM_FORMAT_YVU420_ANDROID) - height = bo->height; - return drv_dumb_bo_create(bo, width, height, format, flags); } diff --git a/virtio_gpu.c b/virtio_gpu.c index 9a45eab..ff53ad3 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -69,10 +69,6 @@ static int virtio_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, height = ALIGN(height, MESA_LLVMPIPE_TILE_SIZE); } - /* HAL_PIXEL_FORMAT_YV12 requires that the buffer's height not be aligned. */ - if (bo->format == DRM_FORMAT_YVU420_ANDROID) - height = bo->height; - return drv_dumb_bo_create(bo, width, height, format, use_flags); } From 571a687e35558be5171569a21ecedc1c9eeada1e Mon Sep 17 00:00:00 2001 From: Hirokazu Honda Date: Wed, 15 Aug 2018 12:39:35 +0900 Subject: [PATCH 081/269] minigbm/i915.c: Android's HAL_PIXEL_FORMAT_BLOB is not tilable if BO_USE_PROTECTED Originally, Android's HAL_PIXEL_FORMAT_BLOB always regards tilable. It is not true if it is allocated with BO_USE_PROTECTED. This CL enables to allocated protected non-tiled Android's HAL_PIXEL_FORMAT_BLOB. BUG=b:112565837 TEST=Play protected videos with ARC++ at eve Change-Id: I0e45f658f170cd380a74b9207ba57b08b6edab8b Reviewed-on: https://chromium-review.googlesource.com/1175641 Commit-Ready: Hirokazu Honda Tested-by: Hirokazu Honda Reviewed-by: Tomasz Figa --- i915.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/i915.c b/i915.c index e01c0e2..0d1668e 100644 --- a/i915.c +++ b/i915.c @@ -154,11 +154,13 @@ static int i915_add_combinations(struct driver *drv) render_use_flags &= ~BO_USE_SW_WRITE_OFTEN; render_use_flags &= ~BO_USE_SW_READ_OFTEN; render_use_flags &= ~BO_USE_LINEAR; + render_use_flags &= ~BO_USE_PROTECTED; 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; + texture_use_flags &= ~BO_USE_PROTECTED; metadata.tiling = I915_TILING_X; metadata.priority = 2; From b131c9d7fb1838dc594f6a65e3e7ae957034c139 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Tue, 28 Aug 2018 14:17:05 -0700 Subject: [PATCH 082/269] minigbm: msm: add supported formats Since we should be using llvmpipe with MSM for now, add formats we know work well with vgem (which also uses llvmpipe). BUG=none TEST=none Change-Id: I88bf183a23a593029ed303c16ef960eb36d59f9f Reviewed-on: https://chromium-review.googlesource.com/1194189 Commit-Ready: Douglas Anderson Tested-by: Douglas Anderson Tested-by: Gurchetan Singh Reviewed-by: Douglas Anderson Reviewed-by: Gurchetan Singh --- msm.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/msm.c b/msm.c index cfceaf1..fdaa8b5 100644 --- a/msm.c +++ b/msm.c @@ -13,10 +13,12 @@ #define MESA_LLVMPIPE_TILE_ORDER 6 #define MESA_LLVMPIPE_TILE_SIZE (1 << MESA_LLVMPIPE_TILE_ORDER) -static const uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_BGR888, - DRM_FORMAT_XRGB8888 }; +static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, + DRM_FORMAT_BGR888, DRM_FORMAT_RGB565, + DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888 }; -static const uint32_t supported_formats[] = { DRM_FORMAT_NV12 }; +static const uint32_t supported_formats[] = { DRM_FORMAT_NV12, DRM_FORMAT_R8, DRM_FORMAT_YVU420, + DRM_FORMAT_YVU420_ANDROID }; static int msm_init(struct driver *drv) { From 500928fd3a78322549d9602dac6a135a028ab0ae Mon Sep 17 00:00:00 2001 From: Luigi Santivetti Date: Tue, 28 Aug 2018 10:09:20 +0100 Subject: [PATCH 083/269] minigbm: mediatek: wait for outstanding operations when invalidating Without doing this it's possible for the CPU to access the memory when it's in use by another device. TEST=adb shell "am instrument -w --abi armeabi-v7a -e class\ android.media.cts.EncodeDecodeTest#testEncodeDecodeVideoFromPersistentSurfaceToSurfaceQCIF\ android.media.cts/android.support.test.runner.AndroidJUnitRunner" BUG=b:71835379 Change-Id: I3b1508a0eab3b020b7c42978cb1e1099ebc029fd Signed-off-by: Luigi Santivetti Reviewed-on: https://chromium-review.googlesource.com/1193302 Commit-Ready: Gurchetan Singh Reviewed-by: Gurchetan Singh --- mediatek.c | 43 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/mediatek.c b/mediatek.c index 21a10af..3b8ecbf 100644 --- a/mediatek.c +++ b/mediatek.c @@ -7,9 +7,12 @@ #ifdef DRV_MEDIATEK // clang-format off +#include +#include #include #include #include +#include #include #include // clang-format on @@ -23,6 +26,7 @@ struct mediatek_private_map_data { void *cached_addr; void *gem_addr; + int prime_fd; }; static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, @@ -85,7 +89,7 @@ static int mediatek_bo_create(struct bo *bo, uint32_t width, uint32_t height, ui static void *mediatek_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags) { - int ret; + int ret, prime_fd; struct drm_mtk_gem_map_off gem_map; struct mediatek_private_map_data *priv; @@ -98,16 +102,24 @@ static void *mediatek_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint3 return MAP_FAILED; } + ret = drmPrimeHandleToFD(bo->drv->fd, gem_map.handle, DRM_CLOEXEC, &prime_fd); + if (ret) { + drv_log("Failed to get a prime fd\n"); + return MAP_FAILED; + } + 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; + priv = calloc(1, sizeof(*priv)); + priv->prime_fd = prime_fd; + vma->priv = priv; + if (bo->use_flags & BO_USE_RENDERSCRIPT) { - priv = calloc(1, sizeof(*priv)); priv->cached_addr = calloc(1, bo->total_size); priv->gem_addr = addr; - vma->priv = priv; addr = priv->cached_addr; } @@ -119,6 +131,7 @@ static int mediatek_bo_unmap(struct bo *bo, struct vma *vma) if (vma->priv) { struct mediatek_private_map_data *priv = vma->priv; vma->addr = priv->gem_addr; + close(priv->prime_fd); free(priv->cached_addr); free(priv); vma->priv = NULL; @@ -129,9 +142,25 @@ static int mediatek_bo_unmap(struct bo *bo, struct vma *vma) 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); + struct mediatek_private_map_data *priv = mapping->vma->priv; + + if (priv) { + struct pollfd fds = { + .fd = priv->prime_fd, + }; + + if (mapping->vma->map_flags & BO_MAP_WRITE) + fds.events |= POLLOUT; + + if (mapping->vma->map_flags & BO_MAP_READ) + fds.events |= POLLIN; + + poll(&fds, 1, -1); + if (fds.revents != fds.events) + drv_log("poll prime_fd failed\n"); + + if (priv->cached_addr) + memcpy(priv->cached_addr, priv->gem_addr, bo->total_size); } return 0; @@ -140,7 +169,7 @@ static int mediatek_bo_invalidate(struct bo *bo, struct mapping *mapping) 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)) + if (priv && priv->cached_addr && (mapping->vma->map_flags & BO_MAP_WRITE)) memcpy(priv->gem_addr, priv->cached_addr, bo->total_size); return 0; From a72f44230983a84e3c2e24c7ea63926812228e5a Mon Sep 17 00:00:00 2001 From: Luigi Santivetti Date: Wed, 12 Sep 2018 16:28:21 +0100 Subject: [PATCH 084/269] minigbm: mediatek: always provide munmap() with a valid address MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before this change, a NULL pointer could have been passed to munmap(), making impossible for it to unmap previoulsy mapped memory. After this change, munmap() always receives a valid pointer. BUG=b:71835379 b:114699642 TEST=adb shell "am instrument -w --abi armeabi-v7a -e class\ android.uirendering.cts.testclasses.InfrastructureTests#testScreenshot\ android.uirendering.cts/android.support.test.runner.AndroidJUnitRunner" Change-Id: Ic1b15807623209ab28d0d4ed63fe0d6ef2dcc6f8 Signed-off-by: Luigi Santivetti Reviewed-on: https://chromium-review.googlesource.com/1221667 Commit-Ready: Kazuhiro Inaba Tested-by: Pin-chih Lin Reviewed-by: Stéphane Marchesin Reviewed-by: Daniel Kurtz Reviewed-by: Gurchetan Singh --- mediatek.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/mediatek.c b/mediatek.c index 3b8ecbf..d319bf9 100644 --- a/mediatek.c +++ b/mediatek.c @@ -130,9 +130,13 @@ static int mediatek_bo_unmap(struct bo *bo, struct vma *vma) { if (vma->priv) { struct mediatek_private_map_data *priv = vma->priv; - vma->addr = priv->gem_addr; + + if (priv->cached_addr) { + vma->addr = priv->gem_addr; + free(priv->cached_addr); + } + close(priv->prime_fd); - free(priv->cached_addr); free(priv); vma->priv = NULL; } From 2b1d689b0c0a74db34fb69839d6c60b93e97141a Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Mon, 17 Sep 2018 16:58:16 -0700 Subject: [PATCH 085/269] minigbm: run clang-format Change-Id: I9b5c3db33bd0c7914a214e2181d655aec84632c5 Reviewed-on: https://chromium-review.googlesource.com/1229436 Commit-Ready: ChromeOS CL Exonerator Bot Tested-by: Gurchetan Singh Reviewed-by: Gurchetan Singh --- cros_gralloc/gralloc0/gralloc0.cc | 16 ++++++++-------- gbm.c | 6 +++--- helpers.c | 12 ++++++------ i915.c | 8 +++++--- 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/cros_gralloc/gralloc0/gralloc0.cc b/cros_gralloc/gralloc0/gralloc0.cc index b645b3f..df1f62c 100644 --- a/cros_gralloc/gralloc0/gralloc0.cc +++ b/cros_gralloc/gralloc0/gralloc0.cc @@ -300,10 +300,10 @@ static int gralloc0_lock_async(struct gralloc_module_t const *module, buffer_han uint32_t map_flags; uint8_t *addr[DRV_MAX_PLANES]; auto mod = (struct gralloc0_module const *)module; - struct rectangle rect = {.x = static_cast(l), - .y = static_cast(t), - .width = static_cast(w), - .height = static_cast(h) }; + struct rectangle rect = { .x = static_cast(l), + .y = static_cast(t), + .width = static_cast(w), + .height = static_cast(h) }; auto hnd = cros_gralloc_convert_handle(handle); if (!hnd) { @@ -342,10 +342,10 @@ static int gralloc0_lock_async_ycbcr(struct gralloc_module_t const *module, buff uint32_t map_flags; uint8_t *addr[DRV_MAX_PLANES] = { nullptr, nullptr, nullptr, nullptr }; auto mod = (struct gralloc0_module const *)module; - struct rectangle rect = {.x = static_cast(l), - .y = static_cast(t), - .width = static_cast(w), - .height = static_cast(h) }; + struct rectangle rect = { .x = static_cast(l), + .y = static_cast(t), + .width = static_cast(w), + .height = static_cast(h) }; auto hnd = cros_gralloc_convert_handle(handle); if (!hnd) { diff --git a/gbm.c b/gbm.c index e265e36..dd6013c 100644 --- a/gbm.c +++ b/gbm.c @@ -229,7 +229,7 @@ PUBLIC void *gbm_bo_map(struct gbm_bo *bo, uint32_t x, uint32_t y, uint32_t widt void *addr; off_t offset; uint32_t map_flags; - struct rectangle rect = {.x = x, .y = y, .width = width, .height = height }; + struct rectangle rect = { .x = x, .y = y, .width = width, .height = height }; if (!bo || width == 0 || height == 0 || !stride || !map_data) return NULL; @@ -318,9 +318,9 @@ PUBLIC union gbm_bo_handle gbm_bo_get_plane_handle(struct gbm_bo *bo, size_t pla return gbm_bo_get_handle_for_plane(bo, plane); } -PUBLIC union gbm_bo_handle gbm_bo_get_handle_for_plane(struct gbm_bo* bo, size_t plane) +PUBLIC union gbm_bo_handle gbm_bo_get_handle_for_plane(struct gbm_bo *bo, size_t plane) { - return (union gbm_bo_handle)drv_bo_get_plane_handle(bo->bo, plane).u64; + return (union gbm_bo_handle)drv_bo_get_plane_handle(bo->bo, plane).u64; } PUBLIC int gbm_bo_get_plane_fd(struct gbm_bo *bo, size_t plane) diff --git a/helpers.c b/helpers.c index b780ff6..de4541f 100644 --- a/helpers.c +++ b/helpers.c @@ -497,9 +497,9 @@ void drv_add_combinations(struct driver *drv, const uint32_t *formats, uint32_t uint32_t i; for (i = 0; i < num_formats; i++) { - struct combination combo = {.format = formats[i], - .metadata = *metadata, - .use_flags = use_flags }; + struct combination combo = { .format = formats[i], + .metadata = *metadata, + .use_flags = use_flags }; drv_array_append(drv->combos, &combo); } @@ -593,9 +593,9 @@ struct drv_array *drv_query_kms(struct driver *drv) } if (!found) { - struct kms_item item = {.format = plane->formats[j], - .modifier = DRM_FORMAT_MOD_LINEAR, - .use_flags = use_flag }; + struct kms_item item = { .format = plane->formats[j], + .modifier = DRM_FORMAT_MOD_LINEAR, + .use_flags = use_flag }; drv_array_append(kms_items, &item); } diff --git a/i915.c b/i915.c index 0d1668e..3f62638 100644 --- a/i915.c +++ b/i915.c @@ -154,13 +154,13 @@ static int i915_add_combinations(struct driver *drv) render_use_flags &= ~BO_USE_SW_WRITE_OFTEN; render_use_flags &= ~BO_USE_SW_READ_OFTEN; render_use_flags &= ~BO_USE_LINEAR; - render_use_flags &= ~BO_USE_PROTECTED; + render_use_flags &= ~BO_USE_PROTECTED; 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; - texture_use_flags &= ~BO_USE_PROTECTED; + texture_use_flags &= ~BO_USE_PROTECTED; metadata.tiling = I915_TILING_X; metadata.priority = 2; @@ -421,7 +421,9 @@ static int i915_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint32_t 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, + I915_FORMAT_MOD_Y_TILED, + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, }; uint64_t modifier; From 2fdb721c3583e64012250bc6a130dd2fef2fabe6 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Mon, 17 Sep 2018 17:03:17 -0700 Subject: [PATCH 086/269] minigbm: delete unused functions and definitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ie5f8b148e3f051edde08b0b46ab22a80f034ff80 Reviewed-on: https://chromium-review.googlesource.com/1229437 Commit-Ready: Gurchetan Singh Tested-by: Gurchetan Singh Reviewed-by: Stéphane Marchesin --- drv_priv.h | 4 ---- helpers.c | 10 ---------- helpers.h | 1 - 3 files changed, 15 deletions(-) diff --git a/drv_priv.h b/drv_priv.h index 719cd35..93f1d93 100644 --- a/drv_priv.h +++ b/drv_priv.h @@ -88,10 +88,6 @@ struct backend { #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_SW_RARELY BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY - #ifndef DRM_FORMAT_MOD_LINEAR #define DRM_FORMAT_MOD_LINEAR DRM_FORMAT_MOD_NONE #endif diff --git a/helpers.c b/helpers.c index de4541f..49cedb0 100644 --- a/helpers.c +++ b/helpers.c @@ -481,16 +481,6 @@ void drv_decrement_reference_count(struct driver *drv, struct bo *bo, size_t pla drmHashInsert(drv->buffer_table, bo->handles[plane].u32, (void *)(num - 1)); } -uint32_t drv_log_base2(uint32_t value) -{ - int ret = 0; - - while (value >>= 1) - ++ret; - - return ret; -} - void drv_add_combinations(struct driver *drv, const uint32_t *formats, uint32_t num_formats, struct format_metadata *metadata, uint64_t use_flags) { diff --git a/helpers.h b/helpers.h index 4c649c2..0d772ac 100644 --- a/helpers.h +++ b/helpers.h @@ -25,7 +25,6 @@ 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); void drv_add_combinations(struct driver *drv, const uint32_t *formats, uint32_t num_formats, From 86ddfdc267c0f9b87f37b4639521ecfdd44d5b92 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Mon, 17 Sep 2018 17:13:45 -0700 Subject: [PATCH 087/269] minigbm: use drv_add_combination when adding a single combination MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We defined the function, but it's since gone unused. Change-Id: I23e7e57413c4a7c82d9da302b79e6b9c5068654d Reviewed-on: https://chromium-review.googlesource.com/1229438 Commit-Ready: Gurchetan Singh Tested-by: Gurchetan Singh Reviewed-by: Stéphane Marchesin --- helpers.c | 10 ++++++++++ helpers.h | 4 ++-- i915.c | 5 ++--- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/helpers.c b/helpers.c index 49cedb0..6dbc7ce 100644 --- a/helpers.c +++ b/helpers.c @@ -481,6 +481,16 @@ void drv_decrement_reference_count(struct driver *drv, struct bo *bo, size_t pla drmHashInsert(drv->buffer_table, bo->handles[plane].u32, (void *)(num - 1)); } +void drv_add_combination(struct driver *drv, const uint32_t format, + struct format_metadata *metadata, uint64_t use_flags) +{ + struct combination combo = { .format = format, + .metadata = *metadata, + .use_flags = use_flags }; + + drv_array_append(drv->combos, &combo); +} + void drv_add_combinations(struct driver *drv, const uint32_t *formats, uint32_t num_formats, struct format_metadata *metadata, uint64_t use_flags) { diff --git a/helpers.h b/helpers.h index 0d772ac..4f68c3b 100644 --- a/helpers.h +++ b/helpers.h @@ -25,8 +25,8 @@ 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); -int drv_add_combination(struct driver *drv, uint32_t format, struct format_metadata *metadata, - uint64_t usage); +void drv_add_combination(struct driver *drv, uint32_t format, 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, diff --git a/i915.c b/i915.c index 3f62638..773fb69 100644 --- a/i915.c +++ b/i915.c @@ -185,9 +185,8 @@ static int i915_add_combinations(struct driver *drv) texture_use_flags); /* Support y-tiled NV12 for libva */ - const uint32_t nv12_format = DRM_FORMAT_NV12; - drv_add_combinations(drv, &nv12_format, 1, &metadata, - BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER); + drv_add_combination(drv, DRM_FORMAT_NV12, &metadata, + BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER); kms_items = drv_query_kms(drv); if (!kms_items) From 71bc665179f9e8a94c4b2293f6b3406887f96d34 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Mon, 17 Sep 2018 17:42:05 -0700 Subject: [PATCH 088/269] minigbm: don't advertise BGR24 as a render/texture target MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mesa drivers can't use it, in general. I'm leaving in Rockchip since I haven't gotten any reports about this test failing on kevin-arcnext. Fixes: abe44f ("minigbm: add support for BG24") BUG=b:77876551, b:115564746 TEST=The following tests should pass on Eve/Grunt arc-next: android.hardware.nativehardware.cts.AHardwareBufferNativeTests#SingleLayer_ColorTest_GpuColorOutputAndSampledImage_R8G8B8_UNORM android.hardware.nativehardware.cts.AHardwareBufferNativeTests#SingleLayer_ColorTest_GpuColorOutputCpuRead_R8G8B8_UNORM android.hardware.nativehardware.cts.AHardwareBufferNativeTests#SingleLayer_ColorTest_GpuColorOutputIsRenderable_R8G8B8_UNORM android.hardware.nativehardware.cts.AHardwareBufferNativeTests#SingleLayer_ColorTest_GpuSampledImageCanBeSampled_R8G8B8_UNORM Change-Id: Ic7aec07c89fdc21e0c8392238e833f7980062049 Reviewed-on: https://chromium-review.googlesource.com/1229439 Commit-Ready: Gurchetan Singh Tested-by: Gurchetan Singh Reviewed-by: Stéphane Marchesin --- amdgpu.c | 10 ++++++---- drv_priv.h | 4 ++-- i915.c | 11 +++++++---- mediatek.c | 7 +++++-- msm.c | 7 +++++-- virtio_gpu.c | 7 +++++-- 6 files changed, 30 insertions(+), 16 deletions(-) diff --git a/amdgpu.c b/amdgpu.c index efba3da..2b8d64b 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -37,9 +37,8 @@ const static uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMA DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888 }; -const static uint32_t texture_source_formats[] = { DRM_FORMAT_BGR888, DRM_FORMAT_GR88, - DRM_FORMAT_R8, DRM_FORMAT_NV21, - DRM_FORMAT_NV12, DRM_FORMAT_YVU420_ANDROID }; +const static uint32_t texture_source_formats[] = { DRM_FORMAT_GR88, DRM_FORMAT_R8, DRM_FORMAT_NV21, + DRM_FORMAT_NV12, DRM_FORMAT_YVU420_ANDROID }; static int amdgpu_init(struct driver *drv) { @@ -79,6 +78,9 @@ static int amdgpu_init(struct driver *drv) drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), &metadata, BO_USE_TEXTURE_MASK); + /* Android CTS tests require this. */ + drv_add_combination(drv, DRM_FORMAT_BGR888, &metadata, BO_USE_SW_MASK); + /* Linear formats supported by display. */ 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); @@ -154,7 +156,7 @@ static int amdgpu_create_bo(struct bo *bo, uint32_t width, uint32_t height, uint gem_create.in.alignment = 256; gem_create.in.domain_flags = 0; - if (use_flags & (BO_USE_LINEAR | BO_USE_SW)) + if (use_flags & (BO_USE_LINEAR | BO_USE_SW_MASK)) gem_create.in.domain_flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; gem_create.in.domains = AMDGPU_GEM_DOMAIN_GTT; diff --git a/drv_priv.h b/drv_priv.h index 93f1d93..d1369f0 100644 --- a/drv_priv.h +++ b/drv_priv.h @@ -85,8 +85,8 @@ struct backend { 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_MASK BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN | \ + BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY #ifndef DRM_FORMAT_MOD_LINEAR #define DRM_FORMAT_MOD_LINEAR DRM_FORMAT_MOD_NONE diff --git a/i915.c b/i915.c index 773fb69..b343e91 100644 --- a/i915.c +++ b/i915.c @@ -23,10 +23,10 @@ #define I915_CACHELINE_MASK (I915_CACHELINE_SIZE - 1) static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB1555, - DRM_FORMAT_ARGB8888, DRM_FORMAT_BGR888, - DRM_FORMAT_RGB565, DRM_FORMAT_XBGR2101010, - DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB1555, - DRM_FORMAT_XRGB2101010, DRM_FORMAT_XRGB8888 }; + 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_R8, DRM_FORMAT_UYVY, DRM_FORMAT_YUYV }; @@ -137,6 +137,9 @@ static int i915_add_combinations(struct driver *drv) ARRAY_SIZE(tileable_texture_source_formats), &metadata, texture_use_flags); + /* Android CTS tests require this. */ + drv_add_combination(drv, DRM_FORMAT_BGR888, &metadata, BO_USE_SW_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); diff --git a/mediatek.c b/mediatek.c index d319bf9..59a0fac 100644 --- a/mediatek.c +++ b/mediatek.c @@ -30,8 +30,8 @@ struct mediatek_private_map_data { }; static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, - DRM_FORMAT_BGR888, DRM_FORMAT_RGB565, - DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888 }; + DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, + DRM_FORMAT_XRGB8888 }; static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID }; @@ -46,6 +46,9 @@ static int mediatek_init(struct driver *drv) drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), &LINEAR_METADATA, BO_USE_TEXTURE_MASK); + /* Android CTS tests require this. */ + drv_add_combination(drv, DRM_FORMAT_BGR888, &LINEAR_METADATA, BO_USE_SW_MASK); + /* Support BO_USE_HW_VIDEO_DECODER for protected content minigbm allocations. */ metadata.tiling = TILE_TYPE_LINEAR; metadata.priority = 1; diff --git a/msm.c b/msm.c index fdaa8b5..10ada0b 100644 --- a/msm.c +++ b/msm.c @@ -14,8 +14,8 @@ #define MESA_LLVMPIPE_TILE_SIZE (1 << MESA_LLVMPIPE_TILE_ORDER) static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, - DRM_FORMAT_BGR888, DRM_FORMAT_RGB565, - DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888 }; + DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, + DRM_FORMAT_XRGB8888 }; static const uint32_t supported_formats[] = { DRM_FORMAT_NV12, DRM_FORMAT_R8, DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID }; @@ -28,6 +28,9 @@ static int msm_init(struct driver *drv) drv_add_combinations(drv, supported_formats, ARRAY_SIZE(supported_formats), &LINEAR_METADATA, BO_USE_TEXTURE_MASK | BO_USE_HW_VIDEO_DECODER); + /* Android CTS tests require this. */ + drv_add_combination(drv, DRM_FORMAT_BGR888, &LINEAR_METADATA, BO_USE_SW_MASK); + return drv_modify_linear_combinations(drv); } diff --git a/virtio_gpu.c b/virtio_gpu.c index ff53ad3..36ba8bc 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -26,8 +26,8 @@ #define MESA_LLVMPIPE_TILE_SIZE (1 << MESA_LLVMPIPE_TILE_ORDER) static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, - DRM_FORMAT_BGR888, DRM_FORMAT_RGB565, - DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888 }; + DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, + DRM_FORMAT_XRGB8888 }; static const uint32_t dumb_texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID, @@ -186,6 +186,9 @@ static int virtio_gpu_init(struct driver *drv) ARRAY_SIZE(dumb_texture_source_formats), &LINEAR_METADATA, BO_USE_TEXTURE_MASK); + /* Android CTS tests require this. */ + drv_add_combination(drv, DRM_FORMAT_BGR888, &LINEAR_METADATA, BO_USE_SW_MASK); + drv_modify_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA, BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); drv_modify_combination(drv, DRM_FORMAT_R8, &LINEAR_METADATA, From 617ee71c986e3a261a272e4e09d3e5b5ae908cd3 Mon Sep 17 00:00:00 2001 From: Tanmay Shah Date: Wed, 11 Jul 2018 16:41:05 -0700 Subject: [PATCH 089/269] minigbm: minimal buffer allocation support using msm gem ioctls DRM_IOCTL_MSM_GEM_NEW is used to create buffer and DRM_IOCTL_MSM_GEM_INFO is used to map buffer. BUG=none TEST=mmap_test, plane_test Change-Id: I7db0cf36b03625f02828b63946550c768c422419 Signed-off-by: Tanmay Shah Reviewed-on: https://chromium-review.googlesource.com/1134481 Reviewed-by: Kristian H. Kristensen Reviewed-by: Gurchetan Singh --- msm.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 70 insertions(+), 12 deletions(-) diff --git a/msm.c b/msm.c index 10ada0b..8060cea 100644 --- a/msm.c +++ b/msm.c @@ -6,26 +6,32 @@ #ifdef DRV_MSM +#include +#include +#include +#include +#include +#include + #include "drv_priv.h" #include "helpers.h" #include "util.h" -#define MESA_LLVMPIPE_TILE_ORDER 6 -#define MESA_LLVMPIPE_TILE_SIZE (1 << MESA_LLVMPIPE_TILE_ORDER) +#define DEFAULT_ALIGNMENT 64 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 supported_formats[] = { DRM_FORMAT_NV12, DRM_FORMAT_R8, DRM_FORMAT_YVU420, - DRM_FORMAT_YVU420_ANDROID }; +static const uint32_t texture_source_formats[] = { DRM_FORMAT_NV12, DRM_FORMAT_R8, + DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID }; 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); - drv_add_combinations(drv, supported_formats, ARRAY_SIZE(supported_formats), + drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), &LINEAR_METADATA, BO_USE_TEXTURE_MASK | BO_USE_HW_VIDEO_DECODER); /* Android CTS tests require this. */ @@ -34,11 +40,22 @@ static int msm_init(struct driver *drv) return drv_modify_linear_combinations(drv); } +/* msm_bo_create will create linear buffers for now */ static int msm_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, uint64_t flags) { - width = ALIGN(width, MESA_LLVMPIPE_TILE_SIZE); - height = ALIGN(height, MESA_LLVMPIPE_TILE_SIZE); + struct drm_msm_gem_new req; + uint32_t stride, alignw, alignh; + int ret; + size_t i; + + /* will get alignment from libadreno eventually */ + alignw = ALIGN(width, DEFAULT_ALIGNMENT); + alignh = ALIGN(height, DEFAULT_ALIGNMENT); + + /* HAL_PIXEL_FORMAT_YV12 requires that the buffer's height not be aligned. */ + if (bo->format == DRM_FORMAT_YVU420_ANDROID) + alignh = bo->height; /* * The extra 12KB at the end are a requirement of the Venus codec driver. @@ -46,19 +63,60 @@ static int msm_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_ * we multiply this padding by 2/3 here. */ if (bo->format == DRM_FORMAT_NV12) - height += 2 * DIV_ROUND_UP(0x3000, 3 * width); + alignh += 2 * DIV_ROUND_UP(0x3000, 3 * alignw); + + stride = drv_stride_from_format(format, alignw, 0); + + /* Calculate size and assign stride, size, offset to each plane based on format */ + drv_bo_from_format(bo, stride, alignh, format); - return drv_dumb_bo_create(bo, width, height, format, flags); + memset(&req, 0, sizeof(req)); + req.flags = MSM_BO_WC | MSM_BO_SCANOUT; + req.size = bo->total_size; + + ret = drmIoctl(bo->drv->fd, DRM_IOCTL_MSM_GEM_NEW, &req); + if (ret) { + drv_log("DRM_IOCTL_MSM_GEM_NEW failed with %s\n", strerror(errno)); + return ret; + } + + /* + * Though we use only one plane, we need to set handle for + * all planes to pass kernel checks + */ + for (i = 0; i < bo->num_planes; i++) { + bo->handles[i].u32 = req.handle; + } + + return 0; +} + +static void *msm_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags) +{ + int ret; + struct drm_msm_gem_info req; + + memset(&req, 0, sizeof(req)); + req.handle = bo->handles[0].u32; + + ret = drmIoctl(bo->drv->fd, DRM_IOCTL_MSM_GEM_INFO, &req); + if (ret) { + drv_log("DRM_IOCLT_MSM_GEM_INFO failed with %s\n", strerror(errno)); + return MAP_FAILED; + } + vma->length = bo->total_size; + + return mmap(0, bo->total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, + req.offset); } const struct backend backend_msm = { .name = "msm", .init = msm_init, .bo_create = msm_bo_create, - .bo_destroy = drv_dumb_bo_destroy, + .bo_destroy = drv_gem_bo_destroy, .bo_import = drv_prime_bo_import, - .bo_map = drv_dumb_bo_map, + .bo_map = msm_bo_map, .bo_unmap = drv_bo_munmap, }; - #endif /* DRV_MSM */ From ee98f4ecbeedd12f19ec7f8dccd4875acf4d0c75 Mon Sep 17 00:00:00 2001 From: Satyajit Sahu Date: Thu, 4 Oct 2018 10:19:50 +0530 Subject: [PATCH 090/269] minigbm: align width so that stride aligns to 256 map stride is bigger than the allocation stride. Currently gralloc_lock does not consider map_stride. Align the width so that stride get alinged to 256. BUG=b:115946221 TEST= CtsNativeHardwareTestCases GpuColorOutputCpuRead* tests Change-Id: I0e1ccfba4ec981702498a76fa5a0b2c662b6e728 Signed-off-by: Satyajit Sahu Reviewed-on: https://chromium-review.googlesource.com/1242767 Commit-Ready: ChromeOS CL Exonerator Bot Tested-by: Deepak Sharma Reviewed-by: Gurchetan Singh --- amdgpu.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/amdgpu.c b/amdgpu.c index 2b8d64b..75d0ef1 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -143,6 +143,13 @@ static int amdgpu_create_bo(struct bo *bo, uint32_t width, uint32_t height, uint if (!combo) return -EINVAL; + /* Currently Gralloc does not handle a different map_stride. So to work around, + * aligning the stride to 256 to make bo_stride same as map_stride. b/115946221. + */ +#ifdef __ANDROID__ + uint32_t bytes_per_pixel = drv_bytes_per_pixel_from_format(format, 0); + width = ALIGN(width, 256 / bytes_per_pixel); +#endif if (combo->metadata.tiling == TILE_TYPE_DRI) return dri_bo_create(bo, width, height, format, use_flags); From 11161ac65b62b628b06fb45c6f4468622bc417ad Mon Sep 17 00:00:00 2001 From: Maksim Sisov Date: Tue, 16 Oct 2018 11:24:05 +0300 Subject: [PATCH 091/269] minigbm: add MINIGBM define. This patch does not bring any functionality changes, but just adds a MINIGBM define in order to be able to distiguish if Chromium, for example, uses a system libgbm (needed by Ozone/Wayland builds for Linux due to some diffirences, which we cannot fix yet) or minigbm. Change-Id: I82366ce9a1c302124b75a6c21028a67127497065 Reviewed-on: https://chromium-review.googlesource.com/1281887 Commit-Ready: ChromeOS CL Exonerator Bot Tested-by: Maksim Sisov Reviewed-by: Gurchetan Singh --- gbm.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gbm.h b/gbm.h index 58ce07b..68a34c5 100644 --- a/gbm.h +++ b/gbm.h @@ -35,6 +35,10 @@ extern "C" { #define __GBM__ 1 +#ifndef MINIGBM +#define MINIGBM +#endif + #include #include From 39eb9519d751f4b4bb0342028937cfa05b2f43ac Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Thu, 1 Nov 2018 00:45:31 +0900 Subject: [PATCH 092/269] minigbm: i915: Do not use I915_MMAP_WC for camera buffers Some camera use cases, such as camera output buffers shared between video encoder and hwcomposer, require CPU access to the buffers (the ARC++ encoder stack is not zero-copy yet) and having uncached mapping slows them down significantly, to the point that respective CTS tests start failing. Fix it by excluding buffers with BO_CAMERA_READ and BO_CAMERA_WRITE from the WC mapping condition. BUG=b:117978452 TEST=android.hardware.camera2.cts.RecordingTest#testVideoPreviewSurfaceSharing on Nocturne Change-Id: Icc3c7104029403fbf64a7fcc8476d52a3f9ea3f0 Reviewed-on: https://chromium-review.googlesource.com/1309914 Commit-Ready: ChromeOS CL Exonerator Bot Tested-by: Tomasz Figa Reviewed-by: Tomasz Figa --- i915.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/i915.c b/i915.c index b343e91..43e72c2 100644 --- a/i915.c +++ b/i915.c @@ -473,7 +473,17 @@ static void *i915_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t 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)) + /* TODO(b/118799155): We don't seem to have a good way to + * detect the use cases for which WC mapping is really needed. + * The current heuristic seems overly coarse and may be slowing + * down some other use cases unnecessarily. + * + * For now, care must be taken not to use WC mappings for + * Renderscript and camera use cases, as they're + * performance-sensitive. */ + if ((bo->use_flags & BO_USE_SCANOUT) && + !(bo->use_flags & + (BO_USE_RENDERSCRIPT | BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE))) gem_map.flags = I915_MMAP_WC; gem_map.handle = bo->handles[0].u32; From d7630cde4637dd5728d9a1145229cdf246078625 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Thu, 25 Oct 2018 17:12:18 -0700 Subject: [PATCH 093/269] amdgpu: fix misplaced code block We only need this workaround for DRI Android buffers, not all buffers. Also, we don't need this for buffers with non-SW uses. BUG=b:117942643 TEST=compile Change-Id: I7ea24b0dc3b040b726f6c1223c96998f078a20fc Signed-off-by: Satyajit Sahu Reviewed-on: https://chromium-review.googlesource.com/1300595 Reviewed-by: Robert Tarasov --- amdgpu.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/amdgpu.c b/amdgpu.c index 75d0ef1..5c94f37 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -143,15 +143,22 @@ static int amdgpu_create_bo(struct bo *bo, uint32_t width, uint32_t height, uint if (!combo) return -EINVAL; - /* Currently Gralloc does not handle a different map_stride. So to work around, - * aligning the stride to 256 to make bo_stride same as map_stride. b/115946221. - */ + if (combo->metadata.tiling == TILE_TYPE_DRI) { #ifdef __ANDROID__ - uint32_t bytes_per_pixel = drv_bytes_per_pixel_from_format(format, 0); - width = ALIGN(width, 256 / bytes_per_pixel); + /* + * Currently, the gralloc API doesn't differentiate between allocation time and map + * time strides. A workaround for amdgpu DRI buffers is to always to align to 256 at + * allocation time. + * + * See b/115946221,b/117942643 + */ + if (use_flags & (BO_USE_SW_MASK)) { + uint32_t bytes_per_pixel = drv_bytes_per_pixel_from_format(format, 0); + width = ALIGN(width, 256 / bytes_per_pixel); + } #endif - if (combo->metadata.tiling == TILE_TYPE_DRI) return dri_bo_create(bo, width, height, format, use_flags); + } stride = drv_stride_from_format(format, width, 0); stride = ALIGN(stride, 256); From 74e4893783bb85d18470b847bd77ba3be57fd632 Mon Sep 17 00:00:00 2001 From: Deepak Sharma Date: Fri, 9 Nov 2018 14:12:04 -0800 Subject: [PATCH 094/269] amdgpu: Don't use AMDGPU_GEM_CREATE_EXPLICIT_SYNC flag. some of the android.media.cts.EncodeDecodeTest in media test are failing when enabled. Bug=b:115585732 TEST=run android.media.cts.EncodeDecodeTest tests Change-Id: Id54236a4441e6441bd8500a81f83c00e2fa405d8 Signed-off-by: Deepak Sharma Reviewed-on: https://chromium-review.googlesource.com/1329993 Commit-Ready: Deepak Sharma Tested-by: Deepak Sharma Reviewed-by: Bas Nieuwenhuizen Reviewed-by: Gurchetan Singh --- amdgpu.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/amdgpu.c b/amdgpu.c index 5c94f37..add4c20 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -137,7 +137,6 @@ static int amdgpu_create_bo(struct bo *bo, uint32_t width, uint32_t height, uint uint32_t plane, stride; struct combination *combo; union drm_amdgpu_gem_create gem_create; - struct amdgpu_priv *priv = bo->drv->priv; combo = drv_get_combination(bo->drv, format, use_flags); if (!combo) @@ -177,12 +176,6 @@ static int amdgpu_create_bo(struct bo *bo, uint32_t width, uint32_t height, uint if (!(use_flags & (BO_USE_SW_READ_OFTEN | BO_USE_SCANOUT))) gem_create.in.domain_flags |= AMDGPU_GEM_CREATE_CPU_GTT_USWC; - /* If drm_version >= 21 everything exposes explicit synchronization primitives - and chromeos/arc++ will use them. Disable implicit synchronization. */ - if (priv->drm_version >= 21) { - gem_create.in.domain_flags |= AMDGPU_GEM_CREATE_EXPLICIT_SYNC; - } - /* Allocate the buffer with the preferred heap. */ ret = drmCommandWriteRead(drv_get_fd(bo->drv), DRM_AMDGPU_GEM_CREATE, &gem_create, sizeof(gem_create)); From ff66c801c90ddeac97e6121584daff595b85d795 Mon Sep 17 00:00:00 2001 From: Deepak Sharma Date: Fri, 16 Nov 2018 12:10:54 -0800 Subject: [PATCH 095/269] amdgpu: use amdgpu_gem_wait_idle_ioctl to wait for GPU to finish. For linear path we don't wait for GPU to finish before CPU access which may case issues in gralloc lock() case. Bug=b:115585732 TEST=android.video.cts.VideoEncoderDecoderTest#testAvcGoog0Qual1920x1080 Change-Id: If827fe4a18726797082046b4f24fc8c75ff1bcb7 Signed-off-by: Deepak Sharma Reviewed-on: https://chromium-review.googlesource.com/1340484 Commit-Ready: Deepak Sharma Tested-by: Deepak Sharma Reviewed-by: Deepak Sharma Reviewed-by: Gurchetan Singh --- amdgpu.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/amdgpu.c b/amdgpu.c index add4c20..3dbe0e8 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -240,6 +240,32 @@ static int amdgpu_unmap_bo(struct bo *bo, struct vma *vma) return munmap(vma->addr, vma->length); } +static int amdgpu_bo_invalidate(struct bo *bo, struct mapping *mapping) +{ + int ret; + union drm_amdgpu_gem_wait_idle wait_idle; + + if (bo->priv) + return 0; + + memset(&wait_idle, 0, sizeof(wait_idle)); + wait_idle.in.handle = bo->handles[0].u32; + wait_idle.in.timeout = AMDGPU_TIMEOUT_INFINITE; + + ret = drmCommandWriteRead(bo->drv->fd, DRM_AMDGPU_GEM_WAIT_IDLE, &wait_idle, + sizeof(wait_idle)); + + if (ret < 0) { + drv_log("DRM_AMDGPU_GEM_WAIT_IDLE failed with %d\n", ret); + return ret; + } + + if (ret == 0 && wait_idle.out.status) + drv_log("DRM_AMDGPU_GEM_WAIT_IDLE BO is busy\n"); + + return 0; +} + static uint32_t amdgpu_resolve_format(uint32_t format, uint64_t use_flags) { switch (format) { @@ -265,6 +291,7 @@ const struct backend backend_amdgpu = { .bo_import = amdgpu_import_bo, .bo_map = amdgpu_map_bo, .bo_unmap = amdgpu_unmap_bo, + .bo_invalidate = amdgpu_bo_invalidate, .resolve_format = amdgpu_resolve_format, }; From bc667c3ef6f3cc739406bc008341bd4505c1b51f Mon Sep 17 00:00:00 2001 From: Maksim Sisov Date: Wed, 10 Oct 2018 13:41:51 +0300 Subject: [PATCH 096/269] minigbm: define GBM_BO_IMPORT_FD_MODIFIER This CL aligns the minigbm more with the upstream GBM by defining GBM_BO_IMPORT_FD_MODIFIER and using gbm_import_fd_modifier_data instead. That is, the main difference between the old gbm_import_fd_planar_data one and the new one is the format_modifiers variable. In the upstream GBM, it's a single variable. In the minigbm, it is an array. As we know there are no cases when modifiers would be different for each plane. Thus, it's safe to eliminate that and adapt more to the upstream. Change-Id: Iaae062ef1fe9fc9ab0ead09c5f4bfa91d2db67c3 Reviewed-on: https://chromium-review.googlesource.com/1360771 Commit-Ready: Maksim Sisov Tested-by: Maksim Sisov Reviewed-by: Gurchetan Singh --- gbm.c | 21 +++++++++++++++++++++ gbm.h | 16 +++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/gbm.c b/gbm.c index dd6013c..b57b345 100644 --- a/gbm.c +++ b/gbm.c @@ -167,6 +167,7 @@ PUBLIC struct gbm_bo *gbm_bo_import(struct gbm_device *gbm, uint32_t type, void struct drv_import_fd_data drv_data; struct gbm_import_fd_data *fd_data = buffer; struct gbm_import_fd_planar_data *fd_planar_data = buffer; + struct gbm_import_fd_modifier_data *fd_modifier_data = buffer; uint32_t gbm_format; size_t num_planes, i; @@ -180,6 +181,26 @@ 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; + break; + case GBM_BO_IMPORT_FD_MODIFIER: + gbm_format = fd_modifier_data->format; + drv_data.width = fd_modifier_data->width; + drv_data.height = fd_modifier_data->height; + drv_data.format = fd_modifier_data->format; + num_planes = drv_num_planes_from_format(drv_data.format); + + assert(num_planes); + + for (i = 0; i < num_planes; i++) { + drv_data.fds[i] = fd_modifier_data->fds[i]; + drv_data.offsets[i] = fd_modifier_data->offsets[i]; + drv_data.strides[i] = fd_modifier_data->strides[i]; + drv_data.format_modifiers[i] = fd_modifier_data->modifier; + } + + for (i = num_planes; i < GBM_MAX_PLANES; i++) + drv_data.fds[i] = -1; + break; case GBM_BO_IMPORT_FD_PLANAR: gbm_format = fd_planar_data->format; diff --git a/gbm.h b/gbm.h index 68a34c5..2e9d218 100644 --- a/gbm.h +++ b/gbm.h @@ -305,7 +305,9 @@ gbm_bo_create_with_modifiers(struct gbm_device *gbm, #define GBM_BO_IMPORT_WL_BUFFER 0x5501 #define GBM_BO_IMPORT_EGL_IMAGE 0x5502 #define GBM_BO_IMPORT_FD 0x5503 -#define GBM_BO_IMPORT_FD_PLANAR 0x5504 +#define GBM_BO_IMPORT_FD_MODIFIER 0x5504 +// Deprecated. Use GBM_BO_IMPORT_FD_MODIFIER instead. +#define GBM_BO_IMPORT_FD_PLANAR 0x5505 struct gbm_import_fd_data { int fd; @@ -315,6 +317,18 @@ struct gbm_import_fd_data { uint32_t format; }; +struct gbm_import_fd_modifier_data { + uint32_t width; + uint32_t height; + uint32_t format; + uint32_t num_fds; + int fds[GBM_MAX_PLANES]; + int strides[GBM_MAX_PLANES]; + int offsets[GBM_MAX_PLANES]; + uint64_t modifier; +}; + +// Deprecated. Use gbm_import_fd_modifier_data instead. struct gbm_import_fd_planar_data { int fds[GBM_MAX_PLANES]; uint32_t width; From 400e928a09f7858625233f60683263d4c7427fb7 Mon Sep 17 00:00:00 2001 From: Naoki Fukino Date: Mon, 10 Dec 2018 06:22:23 +0000 Subject: [PATCH 097/269] Revert "minigbm: define GBM_BO_IMPORT_FD_MODIFIER" This reverts commit bc667c3ef6f3cc739406bc008341bd4505c1b51f. Reason for revert: This change might cause crbug.com/913329. Original change's description: > minigbm: define GBM_BO_IMPORT_FD_MODIFIER > > This CL aligns the minigbm more with the upstream GBM > by defining GBM_BO_IMPORT_FD_MODIFIER and using > gbm_import_fd_modifier_data instead. > > That is, the main difference between the old > gbm_import_fd_planar_data one and the new one is > the format_modifiers variable. In the upstream > GBM, it's a single variable. In the minigbm, it is > an array. > > As we know there are no cases when modifiers would > be different for each plane. Thus, it's safe to eliminate > that and adapt more to the upstream. > > Change-Id: Iaae062ef1fe9fc9ab0ead09c5f4bfa91d2db67c3 > Reviewed-on: https://chromium-review.googlesource.com/1360771 > Commit-Ready: Maksim Sisov > Tested-by: Maksim Sisov > Reviewed-by: Gurchetan Singh Change-Id: I7dec62abd4243554847930cce33f0d5db069c3f4 Reviewed-on: https://chromium-review.googlesource.com/1369469 Commit-Ready: Naoki Fukino Tested-by: Naoki Fukino Reviewed-by: Naoki Fukino --- gbm.c | 21 --------------------- gbm.h | 16 +--------------- 2 files changed, 1 insertion(+), 36 deletions(-) diff --git a/gbm.c b/gbm.c index b57b345..dd6013c 100644 --- a/gbm.c +++ b/gbm.c @@ -167,7 +167,6 @@ PUBLIC struct gbm_bo *gbm_bo_import(struct gbm_device *gbm, uint32_t type, void struct drv_import_fd_data drv_data; struct gbm_import_fd_data *fd_data = buffer; struct gbm_import_fd_planar_data *fd_planar_data = buffer; - struct gbm_import_fd_modifier_data *fd_modifier_data = buffer; uint32_t gbm_format; size_t num_planes, i; @@ -181,26 +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; - break; - case GBM_BO_IMPORT_FD_MODIFIER: - gbm_format = fd_modifier_data->format; - drv_data.width = fd_modifier_data->width; - drv_data.height = fd_modifier_data->height; - drv_data.format = fd_modifier_data->format; - num_planes = drv_num_planes_from_format(drv_data.format); - - assert(num_planes); - - for (i = 0; i < num_planes; i++) { - drv_data.fds[i] = fd_modifier_data->fds[i]; - drv_data.offsets[i] = fd_modifier_data->offsets[i]; - drv_data.strides[i] = fd_modifier_data->strides[i]; - drv_data.format_modifiers[i] = fd_modifier_data->modifier; - } - - for (i = num_planes; i < GBM_MAX_PLANES; i++) - drv_data.fds[i] = -1; - break; case GBM_BO_IMPORT_FD_PLANAR: gbm_format = fd_planar_data->format; diff --git a/gbm.h b/gbm.h index 2e9d218..68a34c5 100644 --- a/gbm.h +++ b/gbm.h @@ -305,9 +305,7 @@ gbm_bo_create_with_modifiers(struct gbm_device *gbm, #define GBM_BO_IMPORT_WL_BUFFER 0x5501 #define GBM_BO_IMPORT_EGL_IMAGE 0x5502 #define GBM_BO_IMPORT_FD 0x5503 -#define GBM_BO_IMPORT_FD_MODIFIER 0x5504 -// Deprecated. Use GBM_BO_IMPORT_FD_MODIFIER instead. -#define GBM_BO_IMPORT_FD_PLANAR 0x5505 +#define GBM_BO_IMPORT_FD_PLANAR 0x5504 struct gbm_import_fd_data { int fd; @@ -317,18 +315,6 @@ struct gbm_import_fd_data { uint32_t format; }; -struct gbm_import_fd_modifier_data { - uint32_t width; - uint32_t height; - uint32_t format; - uint32_t num_fds; - int fds[GBM_MAX_PLANES]; - int strides[GBM_MAX_PLANES]; - int offsets[GBM_MAX_PLANES]; - uint64_t modifier; -}; - -// Deprecated. Use gbm_import_fd_modifier_data instead. struct gbm_import_fd_planar_data { int fds[GBM_MAX_PLANES]; uint32_t width; From c65bd8c07617e1fbe219801ea8047d3b409cdc82 Mon Sep 17 00:00:00 2001 From: Tanmay Shah Date: Wed, 21 Nov 2018 09:14:14 -0800 Subject: [PATCH 098/269] minigbm: msm: Add platform specific alignment for NV12 linear format Venus driver requires extra padding for NV12 buffers. BUG=b:120118851 TEST=plane_test -f NV12 TEST=plane_test -f NV12 -z 640x480 Change-Id: If86c548350278cc8d87159b58e56802b2598d448 Signed-off-by: Tanmay Shah Reviewed-on: https://chromium-review.googlesource.com/1362202 Commit-Ready: ChromeOS CL Exonerator Bot Reviewed-by: Gurchetan Singh --- msm.c | 72 ++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 21 deletions(-) diff --git a/msm.c b/msm.c index 8060cea..6bb70b6 100644 --- a/msm.c +++ b/msm.c @@ -18,6 +18,11 @@ #include "util.h" #define DEFAULT_ALIGNMENT 64 +#define BUFFER_SIZE_ALIGN 4096 + +#define VENUS_STRIDE_ALIGN 128 +#define VENUS_SCANLINE_ALIGN 16 +#define NV12_LINEAR_PADDING (12 * 1024) static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, @@ -26,6 +31,51 @@ static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMA static const uint32_t texture_source_formats[] = { DRM_FORMAT_NV12, DRM_FORMAT_R8, DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID }; +static void msm_calculate_linear_layout(struct bo *bo) +{ + uint32_t width, height; + + width = bo->width; + height = bo->height; + + /* NV12 format requires extra padding with platform + * specific alignments for venus driver + */ + if (bo->format == DRM_FORMAT_NV12) { + uint32_t y_stride, uv_stride, y_scanline, uv_scanline, y_plane, uv_plane, size; + y_stride = ALIGN(width, VENUS_STRIDE_ALIGN); + uv_stride = ALIGN(width, VENUS_STRIDE_ALIGN); + y_scanline = ALIGN(height, VENUS_SCANLINE_ALIGN * 2); + uv_scanline = ALIGN(DIV_ROUND_UP(height, 2), VENUS_SCANLINE_ALIGN); + y_plane = y_stride * y_scanline; + uv_plane = uv_stride * uv_scanline; + + bo->strides[0] = y_stride; + bo->sizes[0] = y_plane; + bo->offsets[1] = y_plane; + bo->strides[1] = uv_stride; + size = y_plane + uv_plane + NV12_LINEAR_PADDING; + bo->total_size = ALIGN(size, BUFFER_SIZE_ALIGN); + bo->sizes[1] = bo->total_size - bo->sizes[0]; + } else { + uint32_t stride, alignw, alignh; + + alignw = ALIGN(width, DEFAULT_ALIGNMENT); + + /* HAL_PIXEL_FORMAT_YV12 requires that the buffer's height not be aligned. */ + if (bo->format == DRM_FORMAT_YVU420_ANDROID) { + alignh = height; + } else { + alignh = ALIGN(height, DEFAULT_ALIGNMENT); + } + + stride = drv_stride_from_format(bo->format, alignw, 0); + + /* Calculate size and assign stride, size, offset to each plane based on format */ + drv_bo_from_format(bo, stride, alignh, bo->format); + } +} + static int msm_init(struct driver *drv) { drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), @@ -45,30 +95,10 @@ static int msm_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_ uint64_t flags) { struct drm_msm_gem_new req; - uint32_t stride, alignw, alignh; int ret; size_t i; - /* will get alignment from libadreno eventually */ - alignw = ALIGN(width, DEFAULT_ALIGNMENT); - alignh = ALIGN(height, DEFAULT_ALIGNMENT); - - /* HAL_PIXEL_FORMAT_YV12 requires that the buffer's height not be aligned. */ - if (bo->format == DRM_FORMAT_YVU420_ANDROID) - alignh = bo->height; - - /* - * The extra 12KB at the end are a requirement of the Venus codec driver. - * Since |height| will be multiplied by 3/2 in drv_dumb_bo_create, - * we multiply this padding by 2/3 here. - */ - if (bo->format == DRM_FORMAT_NV12) - alignh += 2 * DIV_ROUND_UP(0x3000, 3 * alignw); - - stride = drv_stride_from_format(format, alignw, 0); - - /* Calculate size and assign stride, size, offset to each plane based on format */ - drv_bo_from_format(bo, stride, alignh, format); + msm_calculate_linear_layout(bo); memset(&req, 0, sizeof(req)); req.flags = MSM_BO_WC | MSM_BO_SCANOUT; From 90f8bb08f440235eea97db38e45ab1411427c4d2 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Sun, 2 Dec 2018 10:01:56 +0900 Subject: [PATCH 099/269] minigbm: Fix some clang-format issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No functional changs. BUG=none TEST=compile Change-Id: I6b302e9bbf9d46489bfaa03d3b5cf2b070cb1d24 Reviewed-on: https://chromium-review.googlesource.com/1356697 Commit-Ready: ChromeOS CL Exonerator Bot Tested-by: Stéphane Marchesin Reviewed-by: Stéphane Marchesin Reviewed-by: Gurchetan Singh --- drv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drv.c b/drv.c index 0976404..09f303c 100644 --- a/drv.c +++ b/drv.c @@ -111,7 +111,8 @@ static const struct backend *drv_get_backend(int fd) #ifdef DRV_VC4 &backend_vc4, #endif - &backend_vgem, &backend_virtio_gpu, + &backend_vgem, + &backend_virtio_gpu, }; for (i = 0; i < ARRAY_SIZE(backend_list); i++) From 067594b15aa39835f49058853d3f1f586124c101 Mon Sep 17 00:00:00 2001 From: Tanmay Shah Date: Mon, 26 Nov 2018 10:05:18 -0800 Subject: [PATCH 100/269] minigbm: msm: Add modifier for tiled buffer allocation Allow ubwc buffer allocation and calculate its layout for XBGR8888, ABGR8888 and NV12 formats BUG=b:120118851 TEST=null_platform_test -f XB24 -m DRM_FORMAT_MOD_QCOM_COMPRESSED For above test case display might be corrupted if UBWC content is not passed to input buffer. But using crtc status, modifier information can be verified. Change-Id: If040754d0cd52200feef56e40e931da0c4d2508d Signed-off-by: Tanmay Shah Reviewed-on: https://chromium-review.googlesource.com/1363690 Commit-Ready: ChromeOS CL Exonerator Bot Reviewed-by: Kristian H. Kristensen --- msm.c | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 138 insertions(+), 11 deletions(-) diff --git a/msm.c b/msm.c index 6bb70b6..085cfb0 100644 --- a/msm.c +++ b/msm.c @@ -6,8 +6,11 @@ #ifdef DRV_MSM +#include +#include #include #include +#include #include #include #include @@ -17,12 +20,19 @@ #include "helpers.h" #include "util.h" +/* Alignment values are based on SDM845 Gfx IP */ #define DEFAULT_ALIGNMENT 64 #define BUFFER_SIZE_ALIGN 4096 #define VENUS_STRIDE_ALIGN 128 #define VENUS_SCANLINE_ALIGN 16 #define NV12_LINEAR_PADDING (12 * 1024) +#define NV12_UBWC_PADDING(y_stride) (MAX(16 * 1024, y_stride * 48)) +#define MACROTILE_WIDTH_ALIGN 64 +#define MACROTILE_HEIGHT_ALIGN 16 +#define PLANE_SIZE_ALIGN 4096 + +#define MSM_UBWC_TILING 1 static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, @@ -31,7 +41,30 @@ static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMA static const uint32_t texture_source_formats[] = { DRM_FORMAT_NV12, DRM_FORMAT_R8, DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID }; -static void msm_calculate_linear_layout(struct bo *bo) +/* + * Each macrotile consists of m x n (mostly 4 x 4) tiles. + * Pixel data pitch/stride is aligned with macrotile width. + * Pixel data height is aligned with macrotile height. + * Entire pixel data buffer is aligned with 4k(bytes). + */ +static uint32_t get_ubwc_meta_size(uint32_t width, uint32_t height, uint32_t tile_width, + uint32_t tile_height) +{ + uint32_t macrotile_width, macrotile_height; + + macrotile_width = DIV_ROUND_UP(width, tile_width); + macrotile_height = DIV_ROUND_UP(height, tile_height); + + // Align meta buffer width to 64 blocks + macrotile_width = ALIGN(macrotile_width, MACROTILE_WIDTH_ALIGN); + + // Align meta buffer height to 16 blocks + macrotile_height = ALIGN(macrotile_height, MACROTILE_HEIGHT_ALIGN); + + return ALIGN(macrotile_width * macrotile_height, PLANE_SIZE_ALIGN); +} + +static void msm_calculate_layout(struct bo *bo) { uint32_t width, height; @@ -42,7 +75,9 @@ static void msm_calculate_linear_layout(struct bo *bo) * specific alignments for venus driver */ if (bo->format == DRM_FORMAT_NV12) { - uint32_t y_stride, uv_stride, y_scanline, uv_scanline, y_plane, uv_plane, size; + uint32_t y_stride, uv_stride, y_scanline, uv_scanline, y_plane, uv_plane, size, + extra_padding; + y_stride = ALIGN(width, VENUS_STRIDE_ALIGN); uv_stride = ALIGN(width, VENUS_STRIDE_ALIGN); y_scanline = ALIGN(height, VENUS_SCANLINE_ALIGN * 2); @@ -50,18 +85,25 @@ static void msm_calculate_linear_layout(struct bo *bo) y_plane = y_stride * y_scanline; uv_plane = uv_stride * uv_scanline; + if (bo->tiling == MSM_UBWC_TILING) { + y_plane += get_ubwc_meta_size(width, height, 32, 8); + uv_plane += get_ubwc_meta_size(width >> 1, height >> 1, 16, 8); + extra_padding = NV12_UBWC_PADDING(y_stride); + } else { + extra_padding = NV12_LINEAR_PADDING; + } + bo->strides[0] = y_stride; bo->sizes[0] = y_plane; bo->offsets[1] = y_plane; bo->strides[1] = uv_stride; - size = y_plane + uv_plane + NV12_LINEAR_PADDING; + size = y_plane + uv_plane + extra_padding; bo->total_size = ALIGN(size, BUFFER_SIZE_ALIGN); bo->sizes[1] = bo->total_size - bo->sizes[0]; } else { uint32_t stride, alignw, alignh; alignw = ALIGN(width, DEFAULT_ALIGNMENT); - /* HAL_PIXEL_FORMAT_YV12 requires that the buffer's height not be aligned. */ if (bo->format == DRM_FORMAT_YVU420_ANDROID) { alignh = height; @@ -73,32 +115,87 @@ static void msm_calculate_linear_layout(struct bo *bo) /* Calculate size and assign stride, size, offset to each plane based on format */ drv_bo_from_format(bo, stride, alignh, bo->format); + + /* For all RGB UBWC formats */ + if (bo->tiling == MSM_UBWC_TILING) { + bo->sizes[0] += get_ubwc_meta_size(width, height, 16, 4); + bo->total_size = bo->sizes[0]; + assert(IS_ALIGNED(bo->total_size, BUFFER_SIZE_ALIGN)); + } + } +} + +static bool is_ubwc_fmt(uint32_t format) +{ + switch (format) { + case DRM_FORMAT_XBGR8888: + case DRM_FORMAT_ABGR8888: + case DRM_FORMAT_NV12: + return 1; + default: + return 0; + } +} + +static void msm_add_ubwc_combinations(struct driver *drv, const uint32_t *formats, + uint32_t num_formats, struct format_metadata *metadata, + uint64_t use_flags) +{ + for (uint32_t i = 0; i < num_formats; i++) { + if (is_ubwc_fmt(formats[i])) { + struct combination combo = { .format = formats[i], + .metadata = *metadata, + .use_flags = use_flags }; + drv_array_append(drv->combos, &combo); + } } } static int msm_init(struct driver *drv) { + struct format_metadata metadata; + uint64_t render_use_flags = BO_USE_RENDER_MASK; + uint64_t texture_use_flags = BO_USE_TEXTURE_MASK | BO_USE_HW_VIDEO_DECODER; + uint64_t sw_flags = (BO_USE_RENDERSCRIPT | BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_OFTEN | + BO_USE_LINEAR | BO_USE_PROTECTED); + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &LINEAR_METADATA, BO_USE_RENDER_MASK); + &LINEAR_METADATA, render_use_flags); drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), - &LINEAR_METADATA, BO_USE_TEXTURE_MASK | BO_USE_HW_VIDEO_DECODER); + &LINEAR_METADATA, texture_use_flags); /* Android CTS tests require this. */ drv_add_combination(drv, DRM_FORMAT_BGR888, &LINEAR_METADATA, BO_USE_SW_MASK); - return drv_modify_linear_combinations(drv); + drv_modify_linear_combinations(drv); + + metadata.tiling = MSM_UBWC_TILING; + metadata.priority = 2; + metadata.modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED; + + render_use_flags &= ~sw_flags; + texture_use_flags &= ~sw_flags; + + msm_add_ubwc_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &metadata, render_use_flags); + + msm_add_ubwc_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), + &metadata, texture_use_flags); + + return 0; } -/* msm_bo_create will create linear buffers for now */ -static int msm_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, - uint64_t flags) +static int msm_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t height, + uint32_t format, const uint64_t modifier) { struct drm_msm_gem_new req; int ret; size_t i; - msm_calculate_linear_layout(bo); + bo->tiling = (modifier == DRM_FORMAT_MOD_QCOM_COMPRESSED) ? MSM_UBWC_TILING : 0; + + msm_calculate_layout(bo); memset(&req, 0, sizeof(req)); req.flags = MSM_BO_WC | MSM_BO_SCANOUT; @@ -116,11 +213,40 @@ static int msm_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_ */ for (i = 0; i < bo->num_planes; i++) { bo->handles[i].u32 = req.handle; + bo->format_modifiers[i] = modifier; } return 0; } +static int msm_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[] = { + DRM_FORMAT_MOD_QCOM_COMPRESSED, + DRM_FORMAT_MOD_LINEAR, + }; + + uint64_t modifier = + drv_pick_modifier(modifiers, count, modifier_order, ARRAY_SIZE(modifier_order)); + + return msm_bo_create_for_modifier(bo, width, height, format, modifier); +} + +/* msm_bo_create will create linear buffers for now */ +static int msm_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint64_t flags) +{ + struct combination *combo = drv_get_combination(bo->drv, format, flags); + + if (!combo) { + drv_log("invalid format = %d, flags = %llx combination\n", format, flags); + return -EINVAL; + } + + return msm_bo_create_for_modifier(bo, width, height, format, combo->metadata.modifier); +} + static void *msm_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags) { int ret; @@ -144,6 +270,7 @@ const struct backend backend_msm = { .name = "msm", .init = msm_init, .bo_create = msm_bo_create, + .bo_create_with_modifiers = msm_bo_create_with_modifiers, .bo_destroy = drv_gem_bo_destroy, .bo_import = drv_prime_bo_import, .bo_map = msm_bo_map, From eea88fad3a456500e433108b24630e2589ac26b2 Mon Sep 17 00:00:00 2001 From: Satyajit Sahu Date: Thu, 31 Jan 2019 09:58:24 +0530 Subject: [PATCH 101/269] minigbm:amdgpu: align stride to 256 Previously stride was alinged to 256 only in linear path and android. Now it is aligned to 256 for all cases. BUG=b:122049612 TEST=suspend_stress_test Change-Id: I757f2d056176fe5ebfd858a017273cf02bad6020 Signed-off-by: Satyajit Sahu Reviewed-on: https://chromium-review.googlesource.com/1457777 Tested-by: Drew Davenport Reviewed-by: Gurchetan Singh --- amdgpu.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/amdgpu.c b/amdgpu.c index 3dbe0e8..fabedf3 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -143,6 +143,7 @@ static int amdgpu_create_bo(struct bo *bo, uint32_t width, uint32_t height, uint return -EINVAL; if (combo->metadata.tiling == TILE_TYPE_DRI) { + bool needs_alignment = false; #ifdef __ANDROID__ /* * Currently, the gralloc API doesn't differentiate between allocation time and map @@ -151,11 +152,18 @@ static int amdgpu_create_bo(struct bo *bo, uint32_t width, uint32_t height, uint * * See b/115946221,b/117942643 */ - if (use_flags & (BO_USE_SW_MASK)) { + if (use_flags & (BO_USE_SW_MASK)) + needs_alignment = true; +#endif + // See b/122049612 + if (use_flags & (BO_USE_SCANOUT)) + needs_alignment = true; + + if (needs_alignment) { uint32_t bytes_per_pixel = drv_bytes_per_pixel_from_format(format, 0); width = ALIGN(width, 256 / bytes_per_pixel); } -#endif + return dri_bo_create(bo, width, height, format, use_flags); } From 4fe3038be586d5db8e44e452f5ed6a93c8ccf50a Mon Sep 17 00:00:00 2001 From: Maksim Sisov Date: Mon, 7 Jan 2019 15:11:47 +0200 Subject: [PATCH 102/269] Reland "minigbm: define GBM_BO_IMPORT_FD_MODIFIER" It seems like the problem was that the GBM_BO_IMPORT_FD_PLANAR was redifened to 0x5505 from 0x5504. And GBM_BO_IMPORT_FD_MODIFIER was added as 0x5504, which lead to crashes. In order to minimize risks, do it other way round - leave GBM_BO_IMPORT_FD_PLANAR as 0x5504 and add GBM_BO_IMPORT_FD_MODIFIER as 0x5505. Once all the call sites are changed to use GBM_BO_IMPORT_FD_MODIFIER, remove GBM_BO_IMPORT_FD_PLANAR and make GBM_BO_IMPORT_FD_MODIFIER to be 0x5505. Original change's description: > minigbm: define GBM_BO_IMPORT_FD_MODIFIER > > This CL aligns the minigbm more with the upstream GBM > by defining GBM_BO_IMPORT_FD_MODIFIER and using > gbm_import_fd_modifier_data instead. > > That is, the main difference between the old > gbm_import_fd_planar_data one and the new one is > the format_modifiers variable. In the upstream > GBM, it's a single variable. In the minigbm, it is > an array. > > As we know there are no cases when modifiers would > be different for each plane. Thus, it's safe to eliminate > that and adapt more to the upstream. > > Change-Id: Iaae062ef1fe9fc9ab0ead09c5f4bfa91d2db67c3 > Reviewed-on: https://chromium-review.googlesource.com/1360771 > Commit-Ready: Maksim Sisov > Tested-by: Maksim Sisov > Reviewed-by: Gurchetan Singh Change-Id: I1617de54914734c903cb05e1694cc782a7bb171a Reviewed-on: https://chromium-review.googlesource.com/1454658 Commit-Ready: Maksim Sisov Tested-by: Maksim Sisov Tested-by: Gurchetan Singh Reviewed-by: Gurchetan Singh --- gbm.c | 26 +++++++++++++++++++++++++- gbm.h | 14 ++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/gbm.c b/gbm.c index dd6013c..4e41daa 100644 --- a/gbm.c +++ b/gbm.c @@ -167,8 +167,9 @@ PUBLIC struct gbm_bo *gbm_bo_import(struct gbm_device *gbm, uint32_t type, void struct drv_import_fd_data drv_data; struct gbm_import_fd_data *fd_data = buffer; struct gbm_import_fd_planar_data *fd_planar_data = buffer; + struct gbm_import_fd_modifier_data *fd_modifier_data = buffer; uint32_t gbm_format; - size_t num_planes, i; + size_t num_planes, i, num_fds; memset(&drv_data, 0, sizeof(drv_data)); drv_data.use_flags = gbm_convert_usage(usage); @@ -180,6 +181,29 @@ 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; + break; + case GBM_BO_IMPORT_FD_MODIFIER: + gbm_format = fd_modifier_data->format; + drv_data.width = fd_modifier_data->width; + drv_data.height = fd_modifier_data->height; + drv_data.format = fd_modifier_data->format; + num_planes = drv_num_planes_from_format(drv_data.format); + num_fds = fd_modifier_data->num_fds; + + assert(num_fds > 0 && num_fds <= num_planes); + for (i = 0; i < num_planes; i++) { + if (num_fds != num_planes) + drv_data.fds[i] = fd_modifier_data->fds[0]; + else + drv_data.fds[i] = fd_modifier_data->fds[i]; + drv_data.offsets[i] = fd_modifier_data->offsets[i]; + drv_data.strides[i] = fd_modifier_data->strides[i]; + drv_data.format_modifiers[i] = fd_modifier_data->modifier; + } + + for (i = num_planes; i < GBM_MAX_PLANES; i++) + drv_data.fds[i] = -1; + break; case GBM_BO_IMPORT_FD_PLANAR: gbm_format = fd_planar_data->format; diff --git a/gbm.h b/gbm.h index 68a34c5..6150530 100644 --- a/gbm.h +++ b/gbm.h @@ -305,7 +305,9 @@ gbm_bo_create_with_modifiers(struct gbm_device *gbm, #define GBM_BO_IMPORT_WL_BUFFER 0x5501 #define GBM_BO_IMPORT_EGL_IMAGE 0x5502 #define GBM_BO_IMPORT_FD 0x5503 +// Deprecated. Use GBM_BO_IMPORT_FD_MODIFIER instead. #define GBM_BO_IMPORT_FD_PLANAR 0x5504 +#define GBM_BO_IMPORT_FD_MODIFIER 0x5505 struct gbm_import_fd_data { int fd; @@ -315,6 +317,18 @@ struct gbm_import_fd_data { uint32_t format; }; +struct gbm_import_fd_modifier_data { + uint32_t width; + uint32_t height; + uint32_t format; + uint32_t num_fds; + int fds[GBM_MAX_PLANES]; + int strides[GBM_MAX_PLANES]; + int offsets[GBM_MAX_PLANES]; + uint64_t modifier; +}; + +// Deprecated. Use gbm_import_fd_modifier_data instead. struct gbm_import_fd_planar_data { int fds[GBM_MAX_PLANES]; uint32_t width; From cc35e699f36cce0f0b3a130b0d6ce4e2a393b373 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Thu, 28 Feb 2019 15:44:54 -0800 Subject: [PATCH 103/269] minigbm: i915: align to page size always Upstream commit 2e7bd10e05af ("drm/i915: Prevent a race during I915_GEM_MMAP ioctl with WC set") started checking this apparently. BUG=b:126609463 TEST=gbmtest on octopus Change-Id: Idfcef40b2c49c8ec6a8c18351d7da7d0edeaea1f Reviewed-on: https://chromium-review.googlesource.com/1495920 Commit-Ready: ChromeOS CL Exonerator Bot Tested-by: Guenter Roeck Reviewed-by: Guenter Roeck --- i915.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/i915.c b/i915.c index 43e72c2..922d257 100644 --- a/i915.c +++ b/i915.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "drv_priv.h" @@ -314,15 +315,16 @@ static int i915_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, u { uint32_t offset; size_t plane; - int ret; + int ret, pagesize; offset = 0; + pagesize = getpagesize(); for (plane = 0; plane < drv_num_planes_from_format(format); plane++) { uint32_t stride = drv_stride_from_format(format, width, plane); uint32_t plane_height = drv_height_from_format(format, height, plane); if (bo->tiling != I915_TILING_NONE) - assert(IS_ALIGNED(offset, 4096)); + assert(IS_ALIGNED(offset, pagesize)); ret = i915_align_dimensions(bo, bo->tiling, &stride, &plane_height); if (ret) @@ -334,7 +336,7 @@ static int i915_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, u offset += bo->sizes[plane]; } - bo->total_size = offset; + bo->total_size = ALIGN(offset, pagesize); return 0; } From 9521a6025389380924804d8f42f65fbf7bd37b99 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Fri, 22 Mar 2019 13:15:06 -0700 Subject: [PATCH 104/269] Convert external/minigbm to Android.bp See build/soong/README.md for more information. This replaces the product and BoardConfig.mk variable conditionals with different versions of the HAL for each product, which will also allow checkbuild to verify that they build even on products that don't use them. Fixes: 122332792 Test: mma Change-Id: Ie8b6316ea09795e36339f94883c89795771c1f48 --- Android.bp | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++++ Android.mk | 92 ---------------------------------------- 2 files changed, 120 insertions(+), 92 deletions(-) create mode 100644 Android.bp delete mode 100644 Android.mk diff --git a/Android.bp b/Android.bp new file mode 100644 index 0000000..63a50f7 --- /dev/null +++ b/Android.bp @@ -0,0 +1,120 @@ +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +cc_defaults { + name: "gralloc.minigbm_intel_defaults", + cflags: ["-DDRV_I915"], +} + +cc_defaults { + name: "gralloc.minigbm_meson_defaults", + cflags: ["-DDRV_MESON"], +} + +cc_defaults { + name: "gralloc.minigbm_defaults", + + srcs: [ + "amdgpu.c", + "drv.c", + "evdi.c", + "exynos.c", + "helpers_array.c", + "helpers.c", + "i915.c", + "marvell.c", + "mediatek.c", + "meson.c", + "msm.c", + "nouveau.c", + "radeon.c", + "rockchip.c", + "tegra.c", + "udl.c", + "vc4.c", + "vgem.c", + "virtio_gpu.c", + + "cros_gralloc/cros_gralloc_buffer.cc", + "cros_gralloc/cros_gralloc_driver.cc", + "cros_gralloc/cros_gralloc_helpers.cc", + "cros_gralloc/gralloc0/gralloc0.cc", + ], + + cflags: [ + "-D_GNU_SOURCE=1", + "-D_FILE_OFFSET_BITS=64", + "-Wall", + "-Wsign-compare", + "-Wpointer-arith", + "-Wcast-qual", + "-Wcast-align", + "-Wno-unused-parameter", + ], + cppflags: ["-std=c++14"], + + // The preferred path for vendor HALs is /vendor/lib/hw + vendor: true, + relative_install_path: "hw", + + header_libs: [ + "libhardware_headers", + "libnativebase_headers", + "libsystem_headers", + ], + + shared_libs: [ + "libcutils", + "libdrm", + + "libnativewindow", + "libsync", + "liblog", + ], + + static_libs: ["libarect"], +} + +cc_library_shared { + name: "gralloc.minigbm", + defaults: ["gralloc.minigbm_defaults"], +} + +cc_library_shared { + name: "gralloc.minigbm_intel", + defaults: [ + "gralloc.minigbm_defaults", + "gralloc.minigbm_intel_defaults", + ], + enabled: false, + arch: { + x86: { + enabled: true, + }, + x86_64: { + enabled: true, + }, + }, +} + +cc_library_shared { + name: "gralloc.minigbm_meson", + defaults: [ + "gralloc.minigbm_defaults", + "gralloc.minigbm_meson_defaults", + ], +} + +cc_library_shared { + name: "libminigbm", + defaults: ["gralloc.minigbm_defaults"], + shared_libs: ["liblog"], + static_libs: ["libdrm"], + + srcs: [ + "gbm.c", + "gbm_helpers.c", + ], + + export_include_dirs: ["."], +} diff --git a/Android.mk b/Android.mk deleted file mode 100644 index 1c52e2a..0000000 --- a/Android.mk +++ /dev/null @@ -1,92 +0,0 @@ -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -ifeq ($(strip $(BOARD_USES_MINIGBM)), true) - -MINIGBM_GRALLOC_MK := $(call my-dir)/Android.gralloc.mk -LOCAL_PATH := $(call my-dir) -intel_drivers := i915 i965 - -MINIGBM_SRC := \ - amdgpu.c \ - drv.c \ - evdi.c \ - exynos.c \ - helpers_array.c \ - helpers.c \ - i915.c \ - marvell.c \ - mediatek.c \ - meson.c \ - msm.c \ - nouveau.c \ - radeon.c \ - rockchip.c \ - tegra.c \ - udl.c \ - vc4.c \ - vgem.c \ - virtio_gpu.c - -MINIGBM_CPPFLAGS := -std=c++14 -MINIGBM_CFLAGS := \ - -D_GNU_SOURCE=1 -D_FILE_OFFSET_BITS=64 \ - -Wall -Wsign-compare -Wpointer-arith \ - -Wcast-qual -Wcast-align \ - -Wno-unused-parameter - -ifneq ($(filter $(intel_drivers), $(BOARD_GPU_DRIVERS)),) -MINIGBM_CPPFLAGS += -DDRV_I915 -MINIGBM_CFLAGS += -DDRV_I915 -LOCAL_SHARED_LIBRARIES += libdrm_intel -endif - -ifneq ($(filter meson, $(BOARD_GPU_DRIVERS)),) -MINIGBM_CPPFLAGS += -DDRV_MESON -MINIGBM_CFLAGS += -DDRV_MESON -endif - -include $(CLEAR_VARS) - -SUBDIRS := cros_gralloc - -LOCAL_SHARED_LIBRARIES := \ - libcutils \ - libdrm - -LOCAL_SRC_FILES := $(MINIGBM_SRC) - -include $(MINIGBM_GRALLOC_MK) - -LOCAL_CFLAGS := $(MINIGBM_CFLAGS) -LOCAL_CPPFLAGS := $(MINIGBM_CPPFLAGS) - -LOCAL_MODULE := gralloc.minigbm -LOCAL_MODULE_TAGS := optional -# The preferred path for vendor HALs is /vendor/lib/hw -LOCAL_PROPRIETARY_MODULE := true -LOCAL_MODULE_RELATIVE_PATH := hw -LOCAL_MODULE_CLASS := SHARED_LIBRARIES -LOCAL_MODULE_SUFFIX := $(TARGET_SHLIB_SUFFIX) -LOCAL_HEADER_LIBRARIES += \ - libhardware_headers libnativebase_headers libsystem_headers -LOCAL_SHARED_LIBRARIES += libnativewindow libsync liblog -LOCAL_STATIC_LIBRARIES += libarect -include $(BUILD_SHARED_LIBRARY) - - -include $(CLEAR_VARS) -LOCAL_SHARED_LIBRARIES := liblog -LOCAL_STATIC_LIBRARIES := libdrm - -LOCAL_SRC_FILES += $(MINIGBM_SRC) gbm.c gbm_helpers.c - -LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) -LOCAL_CFLAGS := $(MINIGBM_CFLAGS) -LOCAL_CPPFLAGS := $(MINIGBM_CPPFLAGS) - -LOCAL_MODULE := libminigbm -LOCAL_MODULE_TAGS := optional -include $(BUILD_SHARED_LIBRARY) - -endif From 6ac299f3d3fe2220a73442372616496dc97b652a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Marchesin?= Date: Thu, 21 Mar 2019 12:23:29 -0700 Subject: [PATCH 105/269] minigbm: Fix consistency in return values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit minigbm functions don't use errno; however drmIoctl does. So we need to return -errno instead of returning exactly what drmIoctl returns. BUG=none TEST=builds Change-Id: I20e00141782ac1407133ee72259fe43381954d26 Reviewed-on: https://chromium-review.googlesource.com/1534878 Commit-Ready: Stéphane Marchesin Tested-by: Stéphane Marchesin Reviewed-by: Gurchetan Singh --- exynos.c | 1 + helpers.c | 8 ++++---- i915.c | 2 +- mediatek.c | 3 ++- msm.c | 2 +- rockchip.c | 2 +- tegra.c | 5 +++-- vc4.c | 3 ++- virtio_gpu.c | 5 +++-- 9 files changed, 18 insertions(+), 13 deletions(-) diff --git a/exynos.c b/exynos.c index cf95b38..b2b4040 100644 --- a/exynos.c +++ b/exynos.c @@ -73,6 +73,7 @@ static int exynos_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint ret = drmIoctl(bo->drv->fd, DRM_IOCTL_EXYNOS_GEM_CREATE, &gem_create); if (ret) { drv_log("DRM_IOCTL_EXYNOS_GEM_CREATE failed (size=%zu)\n", size); + ret = -errno; goto cleanup_planes; } diff --git a/helpers.c b/helpers.c index 6dbc7ce..d2dab50 100644 --- a/helpers.c +++ b/helpers.c @@ -290,7 +290,7 @@ int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t ret = drmIoctl(bo->drv->fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb); if (ret) { drv_log("DRM_IOCTL_MODE_CREATE_DUMB failed (%d, %d)\n", bo->drv->fd, errno); - return ret; + return -errno; } drv_bo_from_format(bo, create_dumb.pitch, height, format); @@ -313,7 +313,7 @@ int drv_dumb_bo_destroy(struct bo *bo) ret = drmIoctl(bo->drv->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_dumb); if (ret) { drv_log("DRM_IOCTL_MODE_DESTROY_DUMB failed (handle=%x)\n", bo->handles[0].u32); - return ret; + return -errno; } return 0; @@ -340,7 +340,7 @@ int drv_gem_bo_destroy(struct bo *bo) if (ret) { drv_log("DRM_IOCTL_GEM_CLOSE failed (handle=%x) error %d\n", bo->handles[plane].u32, ret); - error = ret; + error = -errno; } } @@ -370,7 +370,7 @@ int drv_prime_bo_import(struct bo *bo, struct drv_import_fd_data *data) */ bo->num_planes = plane; drv_gem_bo_destroy(bo); - return ret; + return -errno; } bo->handles[plane].u32 = prime_handle.handle; diff --git a/i915.c b/i915.c index 922d257..fb74258 100644 --- a/i915.c +++ b/i915.c @@ -384,7 +384,7 @@ static int i915_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t h ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_CREATE, &gem_create); if (ret) { drv_log("DRM_IOCTL_I915_GEM_CREATE failed (size=%llu)\n", gem_create.size); - return ret; + return -errno; } for (plane = 0; plane < bo->num_planes; plane++) diff --git a/mediatek.c b/mediatek.c index 59a0fac..5edb629 100644 --- a/mediatek.c +++ b/mediatek.c @@ -7,6 +7,7 @@ #ifdef DRV_MEDIATEK // clang-format off +#include #include #include #include @@ -81,7 +82,7 @@ static int mediatek_bo_create(struct bo *bo, uint32_t width, uint32_t height, ui ret = drmIoctl(bo->drv->fd, DRM_IOCTL_MTK_GEM_CREATE, &gem_create); if (ret) { drv_log("DRM_IOCTL_MTK_GEM_CREATE failed (size=%llu)\n", gem_create.size); - return ret; + return -errno; } for (plane = 0; plane < bo->num_planes; plane++) diff --git a/msm.c b/msm.c index 085cfb0..1195a24 100644 --- a/msm.c +++ b/msm.c @@ -204,7 +204,7 @@ static int msm_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t he ret = drmIoctl(bo->drv->fd, DRM_IOCTL_MSM_GEM_NEW, &req); if (ret) { drv_log("DRM_IOCTL_MSM_GEM_NEW failed with %s\n", strerror(errno)); - return ret; + return -errno; } /* diff --git a/rockchip.c b/rockchip.c index 177f9c7..e0cc118 100644 --- a/rockchip.c +++ b/rockchip.c @@ -214,7 +214,7 @@ static int rockchip_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint if (ret) { drv_log("DRM_IOCTL_ROCKCHIP_GEM_CREATE failed (size=%llu)\n", (unsigned long long)gem_create.size); - return ret; + return -errno; } for (plane = 0; plane < bo->num_planes; plane++) diff --git a/tegra.c b/tegra.c index fb2f6a9..4b6b8d7 100644 --- a/tegra.c +++ b/tegra.c @@ -7,6 +7,7 @@ #ifdef DRV_TEGRA #include +#include #include #include #include @@ -229,7 +230,7 @@ static int tegra_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint3 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_TEGRA_GEM_CREATE, &gem_create); if (ret) { drv_log("DRM_IOCTL_TEGRA_GEM_CREATE failed (size=%zu)\n", size); - return ret; + return -errno; } bo->handles[0].u32 = gem_create.handle; @@ -276,7 +277,7 @@ static int tegra_bo_import(struct bo *bo, struct drv_import_fd_data *data) ret = drmIoctl(bo->drv->fd, DRM_IOCTL_TEGRA_GEM_GET_TILING, &gem_get_tiling); if (ret) { drv_gem_bo_destroy(bo); - return ret; + return -errno; } /* NOTE(djmk): we only know about one tiled format, so if our drmIoctl call tells us we are diff --git a/vc4.c b/vc4.c index 71e73ea..6edd967 100644 --- a/vc4.c +++ b/vc4.c @@ -6,6 +6,7 @@ #ifdef DRV_VC4 +#include #include #include #include @@ -49,7 +50,7 @@ static int vc4_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_ ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VC4_CREATE_BO, &bo_create); if (ret) { drv_log("DRM_IOCTL_VC4_GEM_CREATE failed (size=%zu)\n", bo->total_size); - return ret; + return -errno; } for (plane = 0; plane < bo->num_planes; plane++) diff --git a/virtio_gpu.c b/virtio_gpu.c index 36ba8bc..e34d718 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -111,6 +111,7 @@ static int virtio_virgl_bo_create(struct bo *bo, uint32_t width, uint32_t height if (ret) { drv_log("DRM_IOCTL_VIRTGPU_RESOURCE_CREATE failed with %s\n", strerror(errno)); + ret = -errno; goto fail; } @@ -251,7 +252,7 @@ static int virtio_gpu_bo_invalidate(struct bo *bo, struct mapping *mapping) ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST, &xfer); if (ret) { drv_log("DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST failed with %s\n", strerror(errno)); - return ret; + return -errno; } return 0; @@ -280,7 +281,7 @@ static int virtio_gpu_bo_flush(struct bo *bo, struct mapping *mapping) ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_TRANSFER_TO_HOST, &xfer); if (ret) { drv_log("DRM_IOCTL_VIRTGPU_TRANSFER_TO_HOST failed with %s\n", strerror(errno)); - return ret; + return -errno; } return 0; From 5d215249f4660982631128381f4dc6ad2730fc06 Mon Sep 17 00:00:00 2001 From: Drew Davenport Date: Mon, 25 Mar 2019 09:18:42 -0600 Subject: [PATCH 106/269] amdgpu: Add ABGR8888 for scanout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG=b:127868532 TEST=Complete glbench without errors in crosvm Change-Id: I921ab9dd1611d6b45eb980ed7988941806eb6761 Reviewed-on: https://chromium-review.googlesource.com/1538374 Commit-Ready: ChromeOS CL Exonerator Bot Tested-by: Drew Davenport Reviewed-by: Stéphane Marchesin Reviewed-by: Gurchetan Singh --- amdgpu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/amdgpu.c b/amdgpu.c index fabedf3..e4349b9 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -84,6 +84,7 @@ static int amdgpu_init(struct driver *drv) /* Linear formats supported by display. */ drv_modify_combination(drv, DRM_FORMAT_ARGB8888, &metadata, BO_USE_CURSOR | BO_USE_SCANOUT); drv_modify_combination(drv, DRM_FORMAT_XRGB8888, &metadata, BO_USE_CURSOR | BO_USE_SCANOUT); + drv_modify_combination(drv, DRM_FORMAT_ABGR8888, &metadata, BO_USE_SCANOUT); drv_modify_combination(drv, DRM_FORMAT_XBGR8888, &metadata, BO_USE_SCANOUT); /* YUV formats for camera and display. */ From 1b9b5b93fd7478885141c448ee1467814f2a1e27 Mon Sep 17 00:00:00 2001 From: Fritz Koenig Date: Tue, 19 Mar 2019 13:25:45 -0700 Subject: [PATCH 107/269] minigbm: mediatek: Implement bo_create_with_modifiers Mediatek MT8183 only supports DRM_FORMAT_MOD_LINEAR. BUG=b:123042223, b:129645475 TEST=null_platform_test -m DRM_FORMAT_MOD_LINEAR Change-Id: I1938e52a9b221f25b62ddd27916a2222be8c0a46 Reviewed-on: https://chromium-review.googlesource.com/1529226 Commit-Ready: ChromeOS CL Exonerator Bot Tested-by: Fritz Koenig Reviewed-by: Gurchetan Singh --- helpers.c | 14 +++++++++++++- helpers.h | 3 +++ mediatek.c | 20 ++++++++++++++++++-- rockchip.c | 15 ++------------- 4 files changed, 36 insertions(+), 16 deletions(-) diff --git a/helpers.c b/helpers.c index d2dab50..b18cd6a 100644 --- a/helpers.c +++ b/helpers.c @@ -6,7 +6,6 @@ #include #include -#include #include #include #include @@ -670,3 +669,16 @@ uint64_t drv_pick_modifier(const uint64_t *modifiers, uint32_t count, return DRM_FORMAT_MOD_LINEAR; } + +/* + * Search a list of modifiers to see if a given modifier is present + */ +bool drv_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; + + return false; +} diff --git a/helpers.h b/helpers.h index 4f68c3b..c09d2c2 100644 --- a/helpers.h +++ b/helpers.h @@ -7,6 +7,8 @@ #ifndef HELPERS_H #define HELPERS_H +#include + #include "drv.h" #include "helpers_array.h" @@ -35,4 +37,5 @@ 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); +bool drv_has_modifier(const uint64_t *list, uint32_t count, uint64_t modifier); #endif diff --git a/mediatek.c b/mediatek.c index 5edb629..6706fdf 100644 --- a/mediatek.c +++ b/mediatek.c @@ -60,14 +60,21 @@ static int mediatek_init(struct driver *drv) return drv_modify_linear_combinations(drv); } -static int mediatek_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, - uint64_t use_flags) +static int mediatek_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint32_t height, + uint32_t format, const uint64_t *modifiers, + uint32_t count) { int ret; size_t plane; uint32_t stride; struct drm_mtk_gem_create gem_create; + if (!drv_has_modifier(modifiers, count, DRM_FORMAT_MOD_LINEAR)) { + errno = EINVAL; + drv_log("no usable modifier found\n"); + return -EINVAL; + } + /* * Since the ARM L1 cache line size is 64 bytes, align to that as a * performance optimization. @@ -91,6 +98,14 @@ static int mediatek_bo_create(struct bo *bo, uint32_t width, uint32_t height, ui return 0; } +static int mediatek_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint64_t use_flags) +{ + uint64_t modifiers[] = { DRM_FORMAT_MOD_LINEAR }; + return mediatek_bo_create_with_modifiers(bo, width, height, format, modifiers, + ARRAY_SIZE(modifiers)); +} + static void *mediatek_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags) { int ret, prime_fd; @@ -200,6 +215,7 @@ const struct backend backend_mediatek = { .name = "mediatek", .init = mediatek_init, .bo_create = mediatek_bo_create, + .bo_create_with_modifiers = mediatek_bo_create_with_modifiers, .bo_destroy = drv_gem_bo_destroy, .bo_import = drv_prime_bo_import, .bo_map = mediatek_bo_map, diff --git a/rockchip.c b/rockchip.c index e0cc118..a33ede6 100644 --- a/rockchip.c +++ b/rockchip.c @@ -8,7 +8,6 @@ #include #include -#include #include #include #include @@ -151,16 +150,6 @@ static int rockchip_init(struct driver *drv) 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; - - return false; -} - static int rockchip_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, const uint64_t *modifiers, uint32_t count) @@ -179,12 +168,12 @@ static int rockchip_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint drv_bo_from_format(bo, aligned_width, height, format); bo->total_size = bo->strides[0] * aligned_height + w_mbs * h_mbs * 128; } else if (width <= 2560 && - has_modifier(modifiers, count, DRM_FORMAT_MOD_CHROMEOS_ROCKCHIP_AFBC)) { + drv_has_modifier(modifiers, count, DRM_FORMAT_MOD_CHROMEOS_ROCKCHIP_AFBC)) { /* If the caller has decided they can use AFBC, always * pick that */ afbc_bo_from_format(bo, width, height, format); } else { - if (!has_modifier(modifiers, count, DRM_FORMAT_MOD_LINEAR)) { + if (!drv_has_modifier(modifiers, count, DRM_FORMAT_MOD_LINEAR)) { errno = EINVAL; drv_log("no usable modifier found\n"); return -1; From 582bdbf1d78513445e5035fe594c600f69bc7332 Mon Sep 17 00:00:00 2001 From: Bas Nieuwenhuizen Date: Wed, 3 Apr 2019 18:12:12 +0200 Subject: [PATCH 108/269] amdgpu: Add ABGR8888 using non-linear tiling too. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG=b:129625642 TEST=test_that ${IP} cheets_CTS_P.9.0_r7.x86.CtsGraphicsTestCases on Grunt Change-Id: I716533df9e56e52818b4c52ee557747dc3a68e40 Reviewed-on: https://chromium-review.googlesource.com/1550921 Commit-Ready: Drew Davenport Tested-by: Bas Nieuwenhuizen Reviewed-by: Stéphane Marchesin Reviewed-by: Drew Davenport --- amdgpu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/amdgpu.c b/amdgpu.c index e4349b9..784bd3f 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -120,6 +120,7 @@ static int amdgpu_init(struct driver *drv) /* Potentially tiled formats supported by display. */ drv_modify_combination(drv, DRM_FORMAT_ARGB8888, &metadata, BO_USE_CURSOR | BO_USE_SCANOUT); drv_modify_combination(drv, DRM_FORMAT_XRGB8888, &metadata, BO_USE_CURSOR | BO_USE_SCANOUT); + drv_modify_combination(drv, DRM_FORMAT_ABGR8888, &metadata, BO_USE_SCANOUT); drv_modify_combination(drv, DRM_FORMAT_XBGR8888, &metadata, BO_USE_SCANOUT); return 0; } From 5ff0cfd262c4660afbb8edc90719f4a3c2e32b0c Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 9 Apr 2019 11:03:00 -0700 Subject: [PATCH 109/269] minigbm: msm: Silence printf warning on 64-bit build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Compiling this file with a 64-bit userland fails like so: /mnt/host/source/src/platform/minigbm/msm.c:243:70: error: format specifies type 'unsigned long long' but the argument has type 'uint64_t' (aka 'unsigned long') [-Werror,-Wformat] drv_log("invalid format = %d, flags = %llx combination\n", format, flags); ~~~~ ^~~~~ %lx Fix the error by using the appropriate hex printing printf format for uint64_t types. BUG=None TEST=Compile with arm64 userland Change-Id: If1b0298ccf12b8ed4e162a8e5668de1be7ad29e5 Reviewed-on: https://chromium-review.googlesource.com/1559755 Commit-Ready: ChromeOS CL Exonerator Bot Tested-by: Stephen Boyd Reviewed-by: Manoj Gupta Reviewed-by: Stéphane Marchesin --- msm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/msm.c b/msm.c index 1195a24..268e6d3 100644 --- a/msm.c +++ b/msm.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -240,7 +241,7 @@ static int msm_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_ struct combination *combo = drv_get_combination(bo->drv, format, flags); if (!combo) { - drv_log("invalid format = %d, flags = %llx combination\n", format, flags); + drv_log("invalid format = %d, flags = %" PRIx64 " combination\n", format, flags); return -EINVAL; } From 8894cf7256f1d17344fd1e0b5bb849e719afe11e Mon Sep 17 00:00:00 2001 From: Valerie Hau Date: Thu, 25 Apr 2019 11:12:42 -0700 Subject: [PATCH 110/269] Modify gralloc0 implementation Add validateBufferSize and getTransportSize Bug: 131089111 Test: build, boot Change-Id: I53195c75907c51585ed68a885d8c35fe90f1b885 --- cros_gralloc/gralloc0/gralloc0.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cros_gralloc/gralloc0/gralloc0.cc b/cros_gralloc/gralloc0/gralloc0.cc index df1f62c..96593b8 100644 --- a/cros_gralloc/gralloc0/gralloc0.cc +++ b/cros_gralloc/gralloc0/gralloc0.cc @@ -423,6 +423,8 @@ struct gralloc0_module HAL_MODULE_INFO_SYM = { .lockAsync = gralloc0_lock_async, .unlockAsync = gralloc0_unlock_async, .lockAsync_ycbcr = gralloc0_lock_async_ycbcr, + .validateBufferSize = NULL, + .getTransportSize = NULL, }, .alloc = nullptr, From dbab083c8466345a9ae3e38682d56ebffb7cd5f9 Mon Sep 17 00:00:00 2001 From: Lepton Wu Date: Fri, 19 Apr 2019 12:26:39 -0700 Subject: [PATCH 111/269] minigbm: virgl: Map BO_USE_SCANOUT to VIRGL_BIND_SCANOUT Now crosvm use VIRGL_BIND_SCANOUT to decide if we should allocate buffer from host minigbm. For buffers sent to Wayland, they have to be allocated from host minigbm. Since arc-cros-gralloc already maps GRALLOC_USAGE_HW_COMPOSER to BO_USE_SCANOUT, we only need to mark related formats good for BO_USE_SCANOUT and then map BO_USE_SCANOUT to VIRGL_BIND_SCANOUT. BUG=b:130848979 TEST=manual - Run arcvm with updated arc-cros-gralloc Change-Id: If6a126707701198911409f39627c860573be34f4 Reviewed-on: https://chromium-review.googlesource.com/1575526 Commit-Ready: Lepton Wu Tested-by: Lepton Wu Reviewed-by: Gurchetan Singh --- virtio_gpu.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/virtio_gpu.c b/virtio_gpu.c index e34d718..8abeb91 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -72,6 +72,29 @@ static int virtio_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, return drv_dumb_bo_create(bo, width, height, format, use_flags); } +static inline void handle_flag(uint64_t *flag, uint64_t check_flag, uint32_t *bind, + uint32_t virgl_bind) +{ + if ((*flag) & check_flag) { + (*flag) &= ~check_flag; + (*bind) |= virgl_bind; + } +} + +static uint32_t use_flags_to_bind(uint64_t use_flags) +{ + uint32_t bind = 0; + + handle_flag(&use_flags, BO_USE_TEXTURE, &bind, VIRGL_BIND_SAMPLER_VIEW); + handle_flag(&use_flags, BO_USE_RENDERING, &bind, VIRGL_BIND_RENDER_TARGET); + handle_flag(&use_flags, BO_USE_SCANOUT, &bind, VIRGL_BIND_SCANOUT); + // TODO (b/12983436): handle other use flags. + if (use_flags) { + drv_log("Unhandled bo use flag: %llx\n", (unsigned long long)use_flags); + } + return bind; +} + static int virtio_virgl_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, uint64_t use_flags) { @@ -79,6 +102,7 @@ static int virtio_virgl_bo_create(struct bo *bo, uint32_t width, uint32_t height ssize_t plane; ssize_t num_planes = drv_num_planes_from_format(format); uint32_t stride0; + uint32_t bind = use_flags_to_bind(use_flags); for (plane = 0; plane < num_planes; plane++) { uint32_t stride = drv_stride_from_format(format, width, plane); @@ -97,7 +121,7 @@ static int virtio_virgl_bo_create(struct bo *bo, uint32_t width, uint32_t height */ res_create.target = PIPE_TEXTURE_2D; res_create.format = res_format; - res_create.bind = VIRGL_BIND_RENDER_TARGET; + res_create.bind = bind; res_create.width = width; res_create.height = height; res_create.depth = 1; @@ -175,8 +199,10 @@ static int virtio_gpu_init(struct driver *drv) priv->has_3d = 0; } + /* This doesn't mean host can scanout everything, it just means host + * hypervisor can show it. */ drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &LINEAR_METADATA, BO_USE_RENDER_MASK); + &LINEAR_METADATA, BO_USE_RENDER_MASK | BO_USE_SCANOUT); if (priv->has_3d) drv_add_combinations(drv, texture_source_formats, From 055a6aa3e8274e6689740acc5eb7a4250e05edaa Mon Sep 17 00:00:00 2001 From: Miguel Casas Date: Tue, 30 Apr 2019 18:11:40 -0400 Subject: [PATCH 112/269] Add support for DRM_FORMAT_P010 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Test: Tested with chrome's ozone_gl_unittests: crrev.com/c/1561136 Bug: 911754 Change-Id: I8a9a28ba1c3a1186fd88b43c85098a5550fa1c8b Reviewed-on: https://chromium-review.googlesource.com/1590464 Commit-Ready: Miguel Casas Tested-by: Miguel Casas Reviewed-by: Daniele Castagna Reviewed-by: Gurchetan Singh Reviewed-by: Stéphane Marchesin --- drv.h | 5 +++++ helpers.c | 10 ++++++++++ i915.c | 2 +- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/drv.h b/drv.h index d27e845..d3cf9d3 100644 --- a/drv.h +++ b/drv.h @@ -56,6 +56,11 @@ extern "C" { #define DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED fourcc_code('9', '9', '9', '8') #define DRM_FORMAT_FLEX_YCbCr_420_888 fourcc_code('9', '9', '9', '9') +// TODO(crbug.com/958181): remove this definition once drm_fourcc.h contains it. +#ifndef DRM_FORMAT_P010 +#define DRM_FORMAT_P010 fourcc_code('P', '0', '1', '0') +#endif + // clang-format on struct driver; struct bo; diff --git a/helpers.c b/helpers.c index b18cd6a..05ca9eb 100644 --- a/helpers.c +++ b/helpers.c @@ -68,6 +68,13 @@ static const struct planar_layout triplanar_yuv_420_layout = { .bytes_per_pixel = { 1, 1, 1 } }; +static const struct planar_layout biplanar_yuv_p010_layout = { + .num_planes = 2, + .horizontal_subsampling = { 1, 2 }, + .vertical_subsampling = { 1, 2 }, + .bytes_per_pixel = { 2, 4 } +}; + // clang-format on static const struct planar_layout *layout_from_format(uint32_t format) @@ -87,6 +94,9 @@ static const struct planar_layout *layout_from_format(uint32_t format) case DRM_FORMAT_NV21: return &biplanar_yuv_420_layout; + case DRM_FORMAT_P010: + return &biplanar_yuv_p010_layout; + case DRM_FORMAT_ABGR1555: case DRM_FORMAT_ABGR4444: case DRM_FORMAT_ARGB1555: diff --git a/i915.c b/i915.c index fb74258..3d51d63 100644 --- a/i915.c +++ b/i915.c @@ -33,7 +33,7 @@ static const uint32_t tileable_texture_source_formats[] = { DRM_FORMAT_GR88, DRM DRM_FORMAT_UYVY, DRM_FORMAT_YUYV }; static const uint32_t texture_source_formats[] = { DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID, - DRM_FORMAT_NV12 }; + DRM_FORMAT_NV12, DRM_FORMAT_P010 }; struct i915_device { uint32_t gen; From 01c40149a273192f0f4051c16e3b639deb5e80b9 Mon Sep 17 00:00:00 2001 From: Nick Fan Date: Mon, 8 Oct 2018 11:53:26 +0800 Subject: [PATCH 113/269] minigbm: Add formats support for MT8183 camera Add NV21, YUYV and YVU420 formats support for MT8183 camera Use config to seperate modification only for MT8183 BUG=b:109911488 TEST=emerge-kukui minigbm Change-Id: I7201b89de3fa062f96cd69e4b91a2a4b434c738e Signed-off-by: Nick Fan Reviewed-on: https://chromium-review.googlesource.com/1267857 Commit-Ready: ChromeOS CL Exonerator Bot Reviewed-by: Nick Fan Reviewed-by: Gurchetan Singh --- mediatek.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/mediatek.c b/mediatek.c index 6706fdf..73e8a63 100644 --- a/mediatek.c +++ b/mediatek.c @@ -34,8 +34,14 @@ static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMA DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888 }; +#ifdef MTK_MT8183 +static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_NV21, DRM_FORMAT_NV12, + DRM_FORMAT_YUYV, DRM_FORMAT_YVU420, + DRM_FORMAT_YVU420_ANDROID }; +#else static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_YVU420, - DRM_FORMAT_YVU420_ANDROID }; + DRM_FORMAT_YVU420_ANDROID }; +#endif static int mediatek_init(struct driver *drv) { @@ -57,6 +63,20 @@ static int mediatek_init(struct driver *drv) drv_modify_combination(drv, DRM_FORMAT_YVU420, &metadata, BO_USE_HW_VIDEO_DECODER); drv_modify_combination(drv, DRM_FORMAT_YVU420_ANDROID, &metadata, BO_USE_HW_VIDEO_DECODER); +#ifdef MTK_MT8183 + /* Only for MT8183 Camera subsystem */ + drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata, + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); + drv_modify_combination(drv, DRM_FORMAT_NV21, &metadata, + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); + drv_modify_combination(drv, DRM_FORMAT_YUYV, &metadata, + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); + drv_modify_combination(drv, DRM_FORMAT_YVU420, &metadata, + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); + drv_modify_combination(drv, DRM_FORMAT_R8, &metadata, + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); +#endif + return drv_modify_linear_combinations(drv); } @@ -202,9 +222,19 @@ static uint32_t mediatek_resolve_format(uint32_t format, uint64_t use_flags) { switch (format) { case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED: +#ifdef MTK_MT8183 + /* Only for MT8183 Camera subsystem requires NV12. */ + if (use_flags & (BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE)) + return DRM_FORMAT_NV12; +#endif /*HACK: See b/28671744 */ return DRM_FORMAT_XBGR8888; case DRM_FORMAT_FLEX_YCbCr_420_888: +#ifdef MTK_MT8183 + /* Only for MT8183 Camera subsystem requires NV12 */ + if (use_flags & (BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE)) + return DRM_FORMAT_NV12; +#endif return DRM_FORMAT_YVU420; default: return format; From 490ba38396a2e9a407f4b81ddf4e9ca6939e9264 Mon Sep 17 00:00:00 2001 From: Ludovico de Nittis Date: Tue, 28 May 2019 16:03:34 +0200 Subject: [PATCH 114/269] Add dri.c to the MINIGBM_SRC list dri.c needs to be included in the minigbm build because it is required when using an AMD gpu. Bug: chromium:967346 Change-Id: I642836bb970d2b738c98a9869a245ca36c80f3ed Reviewed-on: https://chromium-review.googlesource.com/1631282 Commit-Ready: Daniel Nicoara Tested-by: Daniel Nicoara Legacy-Commit-Queue: Commit Bot Reviewed-by: Gurchetan Singh Reviewed-by: Daniel Nicoara --- Android.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/Android.mk b/Android.mk index 9169cef..564f416 100644 --- a/Android.mk +++ b/Android.mk @@ -9,6 +9,7 @@ intel_drivers := i915 i965 MINIGBM_SRC := \ amdgpu.c \ + dri.c \ drv.c \ evdi.c \ exynos.c \ From 39490e9e3f664d6d0dd80cbd1f7c7387ec5fa39f Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Tue, 28 May 2019 17:49:09 -0700 Subject: [PATCH 115/269] minigbm: run presubmit.sh and add OWNERS file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This now apparently is required. Change-Id: I28b19684d207aad50493974dc71d8249bc82ca21 Reviewed-on: https://chromium-review.googlesource.com/1633452 Commit-Ready: ChromeOS CL Exonerator Bot Tested-by: Gurchetan Singh Legacy-Commit-Queue: Commit Bot Reviewed-by: Stéphane Marchesin --- OWNERS | 8 ++++++++ drv.c | 3 +-- i915.c | 2 +- mediatek.c | 12 ++++++------ 4 files changed, 16 insertions(+), 9 deletions(-) create mode 100644 OWNERS diff --git a/OWNERS b/OWNERS new file mode 100644 index 0000000..a6feb04 --- /dev/null +++ b/OWNERS @@ -0,0 +1,8 @@ +marcheu@chromium.org +gurchetansingh@chromium.org +hoegsberg@chromium.org +tfiga@chromium.org +ddavenport@chromium.org +dbehr@chromium.org +dcastagna@chromium.org +lepton@chromium.org diff --git a/drv.c b/drv.c index 09f303c..0976404 100644 --- a/drv.c +++ b/drv.c @@ -111,8 +111,7 @@ static const struct backend *drv_get_backend(int fd) #ifdef DRV_VC4 &backend_vc4, #endif - &backend_vgem, - &backend_virtio_gpu, + &backend_vgem, &backend_virtio_gpu, }; for (i = 0; i < ARRAY_SIZE(backend_list); i++) diff --git a/i915.c b/i915.c index 3d51d63..aa76aed 100644 --- a/i915.c +++ b/i915.c @@ -33,7 +33,7 @@ static const uint32_t tileable_texture_source_formats[] = { DRM_FORMAT_GR88, DRM DRM_FORMAT_UYVY, DRM_FORMAT_YUYV }; static const uint32_t texture_source_formats[] = { DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID, - DRM_FORMAT_NV12, DRM_FORMAT_P010 }; + DRM_FORMAT_NV12, DRM_FORMAT_P010 }; struct i915_device { uint32_t gen; diff --git a/mediatek.c b/mediatek.c index 73e8a63..3ff300e 100644 --- a/mediatek.c +++ b/mediatek.c @@ -35,12 +35,12 @@ static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMA DRM_FORMAT_XRGB8888 }; #ifdef MTK_MT8183 -static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_NV21, DRM_FORMAT_NV12, - DRM_FORMAT_YUYV, DRM_FORMAT_YVU420, - DRM_FORMAT_YVU420_ANDROID }; +static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_NV21, + DRM_FORMAT_NV12, DRM_FORMAT_YUYV, + DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID }; #else static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_YVU420, - DRM_FORMAT_YVU420_ANDROID }; + DRM_FORMAT_YVU420_ANDROID }; #endif static int mediatek_init(struct driver *drv) @@ -74,7 +74,7 @@ static int mediatek_init(struct driver *drv) drv_modify_combination(drv, DRM_FORMAT_YVU420, &metadata, BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); drv_modify_combination(drv, DRM_FORMAT_R8, &metadata, - BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); #endif return drv_modify_linear_combinations(drv); @@ -233,7 +233,7 @@ static uint32_t mediatek_resolve_format(uint32_t format, uint64_t use_flags) #ifdef MTK_MT8183 /* Only for MT8183 Camera subsystem requires NV12 */ if (use_flags & (BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE)) - return DRM_FORMAT_NV12; + return DRM_FORMAT_NV12; #endif return DRM_FORMAT_YVU420; default: From 2efa6b924c3cafc1bd6b25998978aa0e9e63f526 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Wed, 5 Jun 2019 17:07:56 -0700 Subject: [PATCH 116/269] minigbm: virtio-gpu: remove NV12 as texture source format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This breaks the Ozone EGL unit tests. This should still work for Vivid Camera testing. BUG=chromium:970923 TEST=ozone EGL unit test Change-Id: I850584f926a7bd1cdd4dbc749d446ba775363e2a Reviewed-on: https://chromium-review.googlesource.com/1646884 Commit-Ready: ChromeOS CL Exonerator Bot Tested-by: Gurchetan Singh Legacy-Commit-Queue: Commit Bot Reviewed-by: Stéphane Marchesin Reviewed-by: Miguel Casas --- virtio_gpu.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/virtio_gpu.c b/virtio_gpu.c index 8abeb91..d845e08 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -30,8 +30,7 @@ static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMA DRM_FORMAT_XRGB8888 }; static const uint32_t dumb_texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_YVU420, - DRM_FORMAT_YVU420_ANDROID, - DRM_FORMAT_NV12 }; + DRM_FORMAT_YVU420_ANDROID }; static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_RG88 }; @@ -204,20 +203,21 @@ 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 | BO_USE_SCANOUT); - if (priv->has_3d) + if (priv->has_3d) { drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), &LINEAR_METADATA, BO_USE_TEXTURE_MASK); - else + } else { drv_add_combinations(drv, dumb_texture_source_formats, ARRAY_SIZE(dumb_texture_source_formats), &LINEAR_METADATA, BO_USE_TEXTURE_MASK); + drv_add_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA, + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); + } /* Android CTS tests require this. */ drv_add_combination(drv, DRM_FORMAT_BGR888, &LINEAR_METADATA, BO_USE_SW_MASK); - drv_modify_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA, - BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); drv_modify_combination(drv, DRM_FORMAT_R8, &LINEAR_METADATA, BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); From 1cbcbfd5f9908f694d3786b03d5a2bf0a5af6b90 Mon Sep 17 00:00:00 2001 From: Ludovico de Nittis Date: Wed, 29 May 2019 10:02:21 +0200 Subject: [PATCH 117/269] minigbm: fix uninitialized variable error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To fix the maybe uninitialized error we assign plane_type a starting value. The number zero corresponds to DRM_PLANE_TYPE_OVERLAY, so instead we initialize plane_type to UINT64_MAX. Bug: chromium:968030 Change-Id: I4fe119c1491926227151742041a73207971f56f0 Reviewed-on: https://chromium-review.googlesource.com/1634771 Commit-Ready: ChromeOS CL Exonerator Bot Tested-by: Stéphane Marchesin Legacy-Commit-Queue: Commit Bot Reviewed-by: Gurchetan Singh --- helpers.c | 1 + 1 file changed, 1 insertion(+) diff --git a/helpers.c b/helpers.c index 05ca9eb..66e7e78 100644 --- a/helpers.c +++ b/helpers.c @@ -558,6 +558,7 @@ struct drv_array *drv_query_kms(struct driver *drv) goto out; for (i = 0; i < resources->count_planes; i++) { + plane_type = UINT64_MAX; plane = drmModeGetPlane(drv->fd, resources->planes[i]); if (!plane) goto out; From d0dceb46dd4e07dc7a53f110cd15a445c79879f7 Mon Sep 17 00:00:00 2001 From: Alistair Delva Date: Wed, 26 Jun 2019 11:29:55 -0700 Subject: [PATCH 118/269] Update OWNERS for my new LDAP Exempt-From-Owner-Approval: I was the only owner Change-Id: Ife39959288f2414da063652739343656bccc7cf9 --- OWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OWNERS b/OWNERS index a941078..8c05344 100644 --- a/OWNERS +++ b/OWNERS @@ -1 +1 @@ -astrachan@google.com +adelva@google.com From 59598331c1d8cfc9cc8ce6cd681f632336ecabda Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Thu, 27 Jun 2019 17:53:24 -0700 Subject: [PATCH 119/269] minigbm: fix subsampling issue For YUV, we're not consistent. For the "y" component, we assume the offset is just y * plane_stride, letting the API user take care of the subsampling. For the "x" component, we subsample the "x" the user passes in (see drv_stride_from_format(..)). Let's be consistent and not subsample. This likely makes neglible difference since the users of the API map the entire plane. BUG=b:132939420 TEST=none Change-Id: I0fcfd8ba6a2ae59a419af963eb7b54245f697d77 Reviewed-on: https://chromium-review.googlesource.com/1681382 Tested-by: Gurchetan Singh Commit-Ready: Gurchetan Singh Legacy-Commit-Queue: Commit Bot Reviewed-by: Gurchetan Singh Reviewed-by: Lepton Wu --- gbm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gbm.c b/gbm.c index 4e41daa..db2b4f2 100644 --- a/gbm.c +++ b/gbm.c @@ -267,7 +267,7 @@ PUBLIC void *gbm_bo_map(struct gbm_bo *bo, uint32_t x, uint32_t y, uint32_t widt *stride = ((struct mapping *)*map_data)->vma->map_strides[plane]; offset = *stride * rect.y; - offset += drv_stride_from_format(bo->gbm_format, rect.x, plane); + offset += rect.x * drv_bytes_per_pixel_from_format(bo->gbm_format, plane); return (void *)((uint8_t *)addr + offset); } From 51e785f12dd2cd0ce159973c0ed1548440a010a6 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Wed, 5 Jun 2019 08:48:02 -0700 Subject: [PATCH 120/269] minigbm: update virgl_hw.h Taken from ToT virglrenderer (commit e27247), which contains the upstream version of this file. BUG=b:132939420 TEST=compile Change-Id: I6efc5faa55dfc2841ca17d04db9f16eaeac39d7e Reviewed-on: https://chromium-review.googlesource.com/1645878 Tested-by: Gurchetan Singh Commit-Ready: Gurchetan Singh Legacy-Commit-Queue: Commit Bot Reviewed-by: Gurchetan Singh Reviewed-by: Lepton Wu --- virgl_hw.h | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 146 insertions(+), 3 deletions(-) diff --git a/virgl_hw.h b/virgl_hw.h index e3c56db..94e1d5e 100644 --- a/virgl_hw.h +++ b/virgl_hw.h @@ -23,6 +23,8 @@ #ifndef VIRGL_HW_H #define VIRGL_HW_H +#include + struct virgl_box { uint32_t x, y, z; uint32_t w, h, d; @@ -37,6 +39,7 @@ enum virgl_formats { VIRGL_FORMAT_B5G5R5A1_UNORM = 5, VIRGL_FORMAT_B4G4R4A4_UNORM = 6, VIRGL_FORMAT_B5G6R5_UNORM = 7, + VIRGL_FORMAT_R10G10B10A2_UNORM = 8, VIRGL_FORMAT_L8_UNORM = 9, /**< ubyte luminance */ VIRGL_FORMAT_A8_UNORM = 10, /**< ubyte alpha */ VIRGL_FORMAT_L8A8_UNORM = 12, /**< ubyte alpha, luminance */ @@ -83,6 +86,7 @@ enum virgl_formats { VIRGL_FORMAT_L8A8_SRGB = 96, VIRGL_FORMAT_B8G8R8A8_SRGB = 100, VIRGL_FORMAT_B8G8R8X8_SRGB = 101, + VIRGL_FORMAT_R8G8B8A8_SRGB = 104, /* compressed formats */ VIRGL_FORMAT_DXT1_RGB = 105, @@ -111,6 +115,8 @@ enum virgl_formats { VIRGL_FORMAT_B10G10R10A2_UNORM = 131, VIRGL_FORMAT_R8G8B8X8_UNORM = 134, VIRGL_FORMAT_B4G4R4X4_UNORM = 135, + VIRGL_FORMAT_X24S8_UINT = 136, + VIRGL_FORMAT_S8X24_UINT = 137, VIRGL_FORMAT_B2G3R3_UNORM = 139, VIRGL_FORMAT_L16A16_UNORM = 140, @@ -132,6 +138,12 @@ enum virgl_formats { VIRGL_FORMAT_L32_FLOAT = 160, VIRGL_FORMAT_L32A32_FLOAT = 161, + VIRGL_FORMAT_YV12 = 163, + VIRGL_FORMAT_YV16 = 164, + VIRGL_FORMAT_IYUV = 165, /**< aka I420 */ + VIRGL_FORMAT_NV12 = 166, + VIRGL_FORMAT_NV21 = 167, + VIRGL_FORMAT_R8_UINT = 177, VIRGL_FORMAT_R8G8_UINT = 178, VIRGL_FORMAT_R8G8B8_UINT = 179, @@ -185,17 +197,75 @@ enum virgl_formats { VIRGL_FORMAT_L32_SINT = 223, VIRGL_FORMAT_L32A32_SINT = 224, - VIRGL_FORMAT_B10G10R10A2_UINT = 225, + VIRGL_FORMAT_B10G10R10A2_UINT = 225, VIRGL_FORMAT_R8G8B8X8_SNORM = 229, VIRGL_FORMAT_R8G8B8X8_SRGB = 230, + VIRGL_FORMAT_R8G8B8X8_UINT = 231, + VIRGL_FORMAT_R8G8B8X8_SINT = 232, VIRGL_FORMAT_B10G10R10X2_UNORM = 233, VIRGL_FORMAT_R16G16B16X16_UNORM = 234, VIRGL_FORMAT_R16G16B16X16_SNORM = 235, - VIRGL_FORMAT_MAX, + VIRGL_FORMAT_R16G16B16X16_FLOAT = 236, + VIRGL_FORMAT_R16G16B16X16_UINT = 237, + VIRGL_FORMAT_R16G16B16X16_SINT = 238, + + VIRGL_FORMAT_R10G10B10A2_UINT = 253, + + VIRGL_FORMAT_BPTC_RGBA_UNORM = 255, + VIRGL_FORMAT_BPTC_SRGBA = 256, + VIRGL_FORMAT_BPTC_RGB_FLOAT = 257, + VIRGL_FORMAT_BPTC_RGB_UFLOAT = 258, + + VIRGL_FORMAT_R10G10B10X2_UNORM = 308, + VIRGL_FORMAT_A4B4G4R4_UNORM = 311, + + VIRGL_FORMAT_R8_SRGB = 312, + VIRGL_FORMAT_MAX /* = PIPE_FORMAT_COUNT */, + + /* Below formats must not be used in the guest. */ + VIRGL_FORMAT_B8G8R8X8_UNORM_EMULATED, + VIRGL_FORMAT_B8G8R8A8_UNORM_EMULATED, + VIRGL_FORMAT_MAX_EXTENDED }; +/* These are used by the capability_bits field in virgl_caps_v2. */ +#define VIRGL_CAP_NONE 0 +#define VIRGL_CAP_TGSI_INVARIANT (1 << 0) +#define VIRGL_CAP_TEXTURE_VIEW (1 << 1) +#define VIRGL_CAP_SET_MIN_SAMPLES (1 << 2) +#define VIRGL_CAP_COPY_IMAGE (1 << 3) +#define VIRGL_CAP_TGSI_PRECISE (1 << 4) +#define VIRGL_CAP_TXQS (1 << 5) +#define VIRGL_CAP_MEMORY_BARRIER (1 << 6) +#define VIRGL_CAP_COMPUTE_SHADER (1 << 7) +#define VIRGL_CAP_FB_NO_ATTACH (1 << 8) +#define VIRGL_CAP_ROBUST_BUFFER_ACCESS (1 << 9) +#define VIRGL_CAP_TGSI_FBFETCH (1 << 10) +#define VIRGL_CAP_SHADER_CLOCK (1 << 11) +#define VIRGL_CAP_TEXTURE_BARRIER (1 << 12) +#define VIRGL_CAP_TGSI_COMPONENTS (1 << 13) +#define VIRGL_CAP_GUEST_MAY_INIT_LOG (1 << 14) +#define VIRGL_CAP_SRGB_WRITE_CONTROL (1 << 15) +#define VIRGL_CAP_QBO (1 << 16) +#define VIRGL_CAP_TRANSFER (1 << 17) +#define VIRGL_CAP_FBO_MIXED_COLOR_FORMATS (1 << 18) +#define VIRGL_CAP_FAKE_FP64 (1 << 19) +#define VIRGL_CAP_BIND_COMMAND_ARGS (1 << 20) +#define VIRGL_CAP_MULTI_DRAW_INDIRECT (1 << 21) +#define VIRGL_CAP_INDIRECT_PARAMS (1 << 22) +#define VIRGL_CAP_TRANSFORM_FEEDBACK3 (1 << 23) +#define VIRGL_CAP_3D_ASTC (1 << 24) +#define VIRGL_CAP_INDIRECT_INPUT_ADDR (1 << 25) +#define VIRGL_CAP_COPY_TRANSFER (1 << 26) +#define VIRGL_CAP_CLIP_HALFZ (1 << 27) +#define VIRGL_CAP_APP_TWEAK_SUPPORT (1 << 28) +#define VIRGL_CAP_BGRA_SRGB_IS_EMULATED (1 << 29) + +/* virgl bind flags - these are compatible with mesa 10.5 gallium. + * but are fixed, no other should be passed to virgl either. + */ #define VIRGL_BIND_DEPTH_STENCIL (1 << 0) #define VIRGL_BIND_RENDER_TARGET (1 << 1) #define VIRGL_BIND_SAMPLER_VIEW (1 << 3) @@ -203,10 +273,20 @@ enum virgl_formats { #define VIRGL_BIND_INDEX_BUFFER (1 << 5) #define VIRGL_BIND_CONSTANT_BUFFER (1 << 6) #define VIRGL_BIND_DISPLAY_TARGET (1 << 7) +#define VIRGL_BIND_COMMAND_ARGS (1 << 8) #define VIRGL_BIND_STREAM_OUTPUT (1 << 11) +#define VIRGL_BIND_SHADER_BUFFER (1 << 14) +#define VIRGL_BIND_QUERY_BUFFER (1 << 15) #define VIRGL_BIND_CURSOR (1 << 16) #define VIRGL_BIND_CUSTOM (1 << 17) #define VIRGL_BIND_SCANOUT (1 << 18) +/* Used for buffers that are backed by guest storage and + * are only read by the host. + */ +#define VIRGL_BIND_STAGING (1 << 19) +#define VIRGL_BIND_SHARED (1 << 20) + +#define VIRGL_BIND_PREFER_EMULATED_BGRA (1 << 21) struct virgl_caps_bool_set1 { unsigned indep_blend_enable:1; @@ -232,6 +312,16 @@ struct virgl_caps_bool_set1 { unsigned poly_stipple:1; /* not in GL 3.1 core profile */ unsigned mirror_clamp:1; unsigned texture_query_lod:1; + unsigned has_fp64:1; + unsigned has_tessellation_shaders:1; + unsigned has_indirect_draw:1; + unsigned has_sample_shading:1; + unsigned has_cull:1; + unsigned conditional_render_inverted:1; + unsigned derivative_control:1; + unsigned polygon_offset_clamp:1; + unsigned transform_feedback_overflow_query:1; + /* DO NOT ADD ANYMORE MEMBERS - need to add another 32-bit to v2 caps */ }; /* endless expansion capabilites - current gallium has 252 formats */ @@ -259,9 +349,61 @@ struct virgl_caps_v1 { uint32_t max_texture_gather_components; }; +/* + * This struct should be growable when used in capset 2, + * so we shouldn't have to add a v3 ever. + */ +struct virgl_caps_v2 { + struct virgl_caps_v1 v1; + float min_aliased_point_size; + float max_aliased_point_size; + float min_smooth_point_size; + float max_smooth_point_size; + float min_aliased_line_width; + float max_aliased_line_width; + float min_smooth_line_width; + float max_smooth_line_width; + float max_texture_lod_bias; + uint32_t max_geom_output_vertices; + uint32_t max_geom_total_output_components; + uint32_t max_vertex_outputs; + uint32_t max_vertex_attribs; + uint32_t max_shader_patch_varyings; + int32_t min_texel_offset; + int32_t max_texel_offset; + int32_t min_texture_gather_offset; + int32_t max_texture_gather_offset; + uint32_t texture_buffer_offset_alignment; + uint32_t uniform_buffer_offset_alignment; + uint32_t shader_buffer_offset_alignment; + uint32_t capability_bits; + uint32_t sample_locations[8]; + uint32_t max_vertex_attrib_stride; + uint32_t max_shader_buffer_frag_compute; + uint32_t max_shader_buffer_other_stages; + uint32_t max_shader_image_frag_compute; + uint32_t max_shader_image_other_stages; + uint32_t max_image_samples; + uint32_t max_compute_work_group_invocations; + uint32_t max_compute_shared_memory_size; + uint32_t max_compute_grid_size[3]; + uint32_t max_compute_block_size[3]; + uint32_t max_texture_2d_size; + uint32_t max_texture_3d_size; + uint32_t max_texture_cube_size; + uint32_t max_combined_shader_buffers; + uint32_t max_atomic_counters[6]; + uint32_t max_atomic_counter_buffers[6]; + uint32_t max_combined_atomic_counters; + uint32_t max_combined_atomic_counter_buffers; + uint32_t host_feature_check_version; + struct virgl_supported_format_mask supported_readback_formats; +}; + union virgl_caps { uint32_t max_version; struct virgl_caps_v1 v1; + struct virgl_caps_v2 v2; }; enum virgl_errors { @@ -279,8 +421,9 @@ enum virgl_ctx_errors { VIRGL_ERROR_CTX_ILLEGAL_SURFACE, VIRGL_ERROR_CTX_ILLEGAL_VERTEX_FORMAT, VIRGL_ERROR_CTX_ILLEGAL_CMD_BUFFER, + VIRGL_ERROR_CTX_GLES_HAVE_TES_BUT_MISS_TCS, + VIRGL_ERROR_GL_ANY_SAMPLES_PASSED, }; - #define VIRGL_RESOURCE_Y_0_TOP (1 << 0) #endif From 0d44d48d52d53dfb897fb16e610dd687fc6ba43b Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Tue, 4 Jun 2019 19:39:51 -0700 Subject: [PATCH 121/269] minigbm: modify resolve format hooks a bit Plumb the driver backend to the resolve format hook. BUG=b:132939420 TEST=compile Change-Id: I3ac10f5c986bc5dae5b34cd70654676d4ad289ea Reviewed-on: https://chromium-review.googlesource.com/1645879 Tested-by: Gurchetan Singh Commit-Ready: Gurchetan Singh Legacy-Commit-Queue: Commit Bot Reviewed-by: Gurchetan Singh Reviewed-by: Lepton Wu --- amdgpu.c | 2 +- drv.c | 2 +- drv_priv.h | 2 +- i915.c | 2 +- mediatek.c | 2 +- rockchip.c | 2 +- vgem.c | 2 +- virtio_gpu.c | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/amdgpu.c b/amdgpu.c index 784bd3f..095335e 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -276,7 +276,7 @@ static int amdgpu_bo_invalidate(struct bo *bo, struct mapping *mapping) return 0; } -static uint32_t amdgpu_resolve_format(uint32_t format, uint64_t use_flags) +static uint32_t amdgpu_resolve_format(struct driver *drv, uint32_t format, uint64_t use_flags) { switch (format) { case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED: diff --git a/drv.c b/drv.c index 0976404..b920d45 100644 --- a/drv.c +++ b/drv.c @@ -606,7 +606,7 @@ uint32_t drv_bo_get_format(struct bo *bo) 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, use_flags); + return drv->backend->resolve_format(drv, format, use_flags); return format; } diff --git a/drv_priv.h b/drv_priv.h index d1369f0..46e6490 100644 --- a/drv_priv.h +++ b/drv_priv.h @@ -73,7 +73,7 @@ struct backend { 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); + uint32_t (*resolve_format)(struct driver *drv, uint32_t format, uint64_t use_flags); }; // clang-format off diff --git a/i915.c b/i915.c index aa76aed..48869ca 100644 --- a/i915.c +++ b/i915.c @@ -559,7 +559,7 @@ static int i915_bo_flush(struct bo *bo, struct mapping *mapping) return 0; } -static uint32_t i915_resolve_format(uint32_t format, uint64_t use_flags) +static uint32_t i915_resolve_format(struct driver *drv, uint32_t format, uint64_t use_flags) { switch (format) { case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED: diff --git a/mediatek.c b/mediatek.c index 3ff300e..0bcc28c 100644 --- a/mediatek.c +++ b/mediatek.c @@ -218,7 +218,7 @@ static int mediatek_bo_flush(struct bo *bo, struct mapping *mapping) return 0; } -static uint32_t mediatek_resolve_format(uint32_t format, uint64_t use_flags) +static uint32_t mediatek_resolve_format(struct driver *drv, uint32_t format, uint64_t use_flags) { switch (format) { case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED: diff --git a/rockchip.c b/rockchip.c index a33ede6..0266357 100644 --- a/rockchip.c +++ b/rockchip.c @@ -288,7 +288,7 @@ static int rockchip_bo_flush(struct bo *bo, struct mapping *mapping) return 0; } -static uint32_t rockchip_resolve_format(uint32_t format, uint64_t use_flags) +static uint32_t rockchip_resolve_format(struct driver *drv, uint32_t format, uint64_t use_flags) { switch (format) { case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED: diff --git a/vgem.c b/vgem.c index 14691d1..0d0371c 100644 --- a/vgem.c +++ b/vgem.c @@ -38,7 +38,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 flags) +static uint32_t vgem_resolve_format(struct driver *drv, uint32_t format, uint64_t flags) { switch (format) { case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED: diff --git a/virtio_gpu.c b/virtio_gpu.c index d845e08..29a36ec 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -313,7 +313,7 @@ static int virtio_gpu_bo_flush(struct bo *bo, struct mapping *mapping) return 0; } -static uint32_t virtio_gpu_resolve_format(uint32_t format, uint64_t use_flags) +static uint32_t virtio_gpu_resolve_format(struct driver *drv, uint32_t format, uint64_t use_flags) { switch (format) { case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED: From f5d280d81f55b0e0ef328bb71b389520b7d58a76 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Tue, 4 Jun 2019 19:43:41 -0700 Subject: [PATCH 122/269] minigbm: virtio-gpu: use NV12 as flexible media format All of our future drivers (including MTK_MT8183) seem to prefer NV12 as their flexible media format, so advertise that. In the unlikely event that changes, we can set either use the capabilities or resource create versioning (a planned feature). This has the benefit of keeping Android flexible formats in Android userspace. BUG=b:132939420 TEST=compile Change-Id: I486f7be23f8431aa8bbaea89dca7c1304536e9ac Reviewed-on: https://chromium-review.googlesource.com/1644464 Tested-by: Gurchetan Singh Commit-Ready: Gurchetan Singh Legacy-Commit-Queue: Commit Bot Reviewed-by: Gurchetan Singh Reviewed-by: Lepton Wu --- virtio_gpu.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/virtio_gpu.c b/virtio_gpu.c index 29a36ec..aaebe12 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -32,7 +32,8 @@ static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMA static const uint32_t dumb_texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID }; -static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_RG88 }; +static const uint32_t texture_source_formats[] = { DRM_FORMAT_NV12, DRM_FORMAT_R8, DRM_FORMAT_RG88, + DRM_FORMAT_YVU420_ANDROID }; struct virtio_gpu_priv { int has_3d; @@ -55,6 +56,11 @@ static uint32_t translate_format(uint32_t drm_fourcc, uint32_t plane) return VIRGL_FORMAT_R8_UNORM; case DRM_FORMAT_RG88: return VIRGL_FORMAT_R8G8_UNORM; + case DRM_FORMAT_NV12: + return VIRGL_FORMAT_NV12; + case DRM_FORMAT_YVU420: + case DRM_FORMAT_YVU420_ANDROID: + return VIRGL_FORMAT_YV12; default: return 0; } @@ -315,6 +321,8 @@ static int virtio_gpu_bo_flush(struct bo *bo, struct mapping *mapping) static uint32_t virtio_gpu_resolve_format(struct driver *drv, uint32_t format, uint64_t use_flags) { + struct virtio_gpu_priv *priv = (struct virtio_gpu_priv *)drv->priv; + switch (format) { case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED: /* Camera subsystem requires NV12. */ @@ -323,7 +331,14 @@ static uint32_t virtio_gpu_resolve_format(struct driver *drv, uint32_t format, u /*HACK: See b/28671744 */ return DRM_FORMAT_XBGR8888; case DRM_FORMAT_FLEX_YCbCr_420_888: - return DRM_FORMAT_YVU420; + /* + * All of our host drivers prefer NV12 as their flexible media format. + * If that changes, this will need to be modified. + */ + if (priv->has_3d) + return DRM_FORMAT_NV12; + else + return DRM_FORMAT_YVU420; default: return format; } From 5cbb165bdee49c590dfb00c7db5cc28c5374d5f6 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Thu, 4 Jul 2019 02:41:30 +0000 Subject: [PATCH 123/269] Revert "minigbm: virtio-gpu: remove NV12 as texture source format" This reverts commit 2efa6b924c3cafc1bd6b25998978aa0e9e63f526. Reason for revert: Broke camera VM tests, b/135504137. The intention was to apparently just disable the texturing usage, but the change effectively reduced NV12 from the whole BO_USE_TEXTURE_MASK down to just BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE. Given the definition of the former, which is #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 it removed even the SW access flags, which are needed in the capture stack, and thus broke the camera. Original change's description: > minigbm: virtio-gpu: remove NV12 as texture source format > > This breaks the Ozone EGL unit tests. This should still work for > Vivid Camera testing. > > BUG=chromium:970923 > TEST=ozone EGL unit test > > Change-Id: I850584f926a7bd1cdd4dbc749d446ba775363e2a > Reviewed-on: https://chromium-review.googlesource.com/1646884 > Commit-Ready: ChromeOS CL Exonerator Bot > Tested-by: Gurchetan Singh > Legacy-Commit-Queue: Commit Bot > Reviewed-by: Stphane Marchesin > Reviewed-by: Miguel Casas Bug: chromium:970923 Bug: b:135504137 Change-Id: Ic506f38a85f1fa164f0ac7fd9f562872e4cac700 Test: tast.camera.WebRTC on betty Reviewed-on: https://chromium-review.googlesource.com/1687732 Tested-by: Keiichi Watanabe Commit-Ready: Keiichi Watanabe Legacy-Commit-Queue: Commit Bot Reviewed-by: Tomasz Figa --- virtio_gpu.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/virtio_gpu.c b/virtio_gpu.c index aaebe12..01fbb24 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -30,7 +30,8 @@ static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMA DRM_FORMAT_XRGB8888 }; static const uint32_t dumb_texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_YVU420, - DRM_FORMAT_YVU420_ANDROID }; + DRM_FORMAT_YVU420_ANDROID, + DRM_FORMAT_NV12 }; static const uint32_t texture_source_formats[] = { DRM_FORMAT_NV12, DRM_FORMAT_R8, DRM_FORMAT_RG88, DRM_FORMAT_YVU420_ANDROID }; @@ -209,21 +210,20 @@ 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 | BO_USE_SCANOUT); - if (priv->has_3d) { + if (priv->has_3d) drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), &LINEAR_METADATA, BO_USE_TEXTURE_MASK); - } else { + else drv_add_combinations(drv, dumb_texture_source_formats, ARRAY_SIZE(dumb_texture_source_formats), &LINEAR_METADATA, BO_USE_TEXTURE_MASK); - drv_add_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA, - BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); - } /* Android CTS tests require this. */ drv_add_combination(drv, DRM_FORMAT_BGR888, &LINEAR_METADATA, BO_USE_SW_MASK); + drv_modify_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA, + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); drv_modify_combination(drv, DRM_FORMAT_R8, &LINEAR_METADATA, BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); From 769de64c8309fce3169af04521fccb69c917e7de Mon Sep 17 00:00:00 2001 From: Mark Yacoub Date: Tue, 9 Jul 2019 13:59:50 -0400 Subject: [PATCH 124/269] Change Assert to Check and return NULL Security wise, we now end up relying on gbm_bo_import failing. gbm does some basic validation based on lseek and the provided format. For robustness, return NULL instead of crashing the system. BUG=979736 Change-Id: Ib25a770a3a986a3079fe8db183ea78ac5f777602 Reviewed-on: https://chromium-review.googlesource.com/1693301 Tested-by: Mark Yacoub Commit-Ready: Mark Yacoub Legacy-Commit-Queue: Commit Bot Reviewed-by: Gurchetan Singh Reviewed-by: Mark Yacoub --- gbm.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gbm.c b/gbm.c index db2b4f2..7f9ed99 100644 --- a/gbm.c +++ b/gbm.c @@ -188,9 +188,12 @@ PUBLIC struct gbm_bo *gbm_bo_import(struct gbm_device *gbm, uint32_t type, void drv_data.height = fd_modifier_data->height; drv_data.format = fd_modifier_data->format; num_planes = drv_num_planes_from_format(drv_data.format); + assert(num_planes); + num_fds = fd_modifier_data->num_fds; + if (!num_fds || num_fds > num_planes) + return NULL; - assert(num_fds > 0 && num_fds <= num_planes); for (i = 0; i < num_planes; i++) { if (num_fds != num_planes) drv_data.fds[i] = fd_modifier_data->fds[0]; From 3f3e5f9a98324e1b2dfe9c08dbba904ebee77a0b Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Mon, 8 Jul 2019 09:50:01 -0700 Subject: [PATCH 125/269] minigbm: Reland "minigbm: virtio-gpu: remove NV12 as texture source format" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the SW mask and linear flags too, which are required for WebRTC tests. BUG=b:135504137 TEST=tast.camera.WebRTC Change-Id: Ifa37546e855471e3a125acb483c57d5b34d61edf Reviewed-on: https://chromium-review.googlesource.com/1691068 Tested-by: Gurchetan Singh Commit-Ready: Gurchetan Singh Legacy-Commit-Queue: Commit Bot Reviewed-by: Tomasz Figa Reviewed-by: Stéphane Marchesin --- virtio_gpu.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/virtio_gpu.c b/virtio_gpu.c index 01fbb24..4e671dd 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -30,8 +30,7 @@ static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMA DRM_FORMAT_XRGB8888 }; static const uint32_t dumb_texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_YVU420, - DRM_FORMAT_YVU420_ANDROID, - DRM_FORMAT_NV12 }; + DRM_FORMAT_YVU420_ANDROID }; static const uint32_t texture_source_formats[] = { DRM_FORMAT_NV12, DRM_FORMAT_R8, DRM_FORMAT_RG88, DRM_FORMAT_YVU420_ANDROID }; @@ -210,20 +209,22 @@ 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 | BO_USE_SCANOUT); - if (priv->has_3d) + if (priv->has_3d) { drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), &LINEAR_METADATA, BO_USE_TEXTURE_MASK); - else + } else { drv_add_combinations(drv, dumb_texture_source_formats, ARRAY_SIZE(dumb_texture_source_formats), &LINEAR_METADATA, BO_USE_TEXTURE_MASK); + drv_add_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA, + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_SW_MASK | + BO_USE_LINEAR); + } /* Android CTS tests require this. */ drv_add_combination(drv, DRM_FORMAT_BGR888, &LINEAR_METADATA, BO_USE_SW_MASK); - drv_modify_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA, - BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); drv_modify_combination(drv, DRM_FORMAT_R8, &LINEAR_METADATA, BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); From 6acf248c84b316a464f740c678d47f48eabd19fa Mon Sep 17 00:00:00 2001 From: Greg Hartman Date: Wed, 17 Jul 2019 15:55:17 -0700 Subject: [PATCH 126/269] Fix potential uninitialized read BUG: 137793471 Test: Patched and can compile minigbm Change-Id: I65577ca08f4d41ff6a7b6d2a2af42f82798608bf --- helpers.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/helpers.c b/helpers.c index 4fabfa9..592981d 100644 --- a/helpers.c +++ b/helpers.c @@ -520,7 +520,8 @@ void drv_modify_combination(struct driver *drv, uint32_t format, struct format_m struct drv_array *drv_query_kms(struct driver *drv) { struct drv_array *kms_items; - uint64_t plane_type, use_flag; + uint64_t plane_type = UINT64_MAX; + uint64_t use_flag; uint32_t i, j, k; drmModePlanePtr plane; From b75efb67f84f080a03cdee96f7232dbc8c041258 Mon Sep 17 00:00:00 2001 From: David Riley Date: Tue, 28 May 2019 13:08:12 -0700 Subject: [PATCH 127/269] minigbm: i915: Add support for AR30 DRM_FORMAT_ARGB2101010. BUG=chromium:963559 TEST=freecad starts under crosvm Change-Id: I01c9bfcb0eb8419f06fff69edff6f5eb09232403 Reviewed-on: https://chromium-review.googlesource.com/1631946 Tested-by: David Riley Commit-Ready: ChromeOS CL Exonerator Bot Legacy-Commit-Queue: Commit Bot Reviewed-by: Gurchetan Singh --- i915.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i915.c b/i915.c index 48869ca..dfde42f 100644 --- a/i915.c +++ b/i915.c @@ -27,7 +27,7 @@ static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FO DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB565, DRM_FORMAT_XBGR2101010, DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB1555, DRM_FORMAT_XRGB2101010, - DRM_FORMAT_XRGB8888 }; + DRM_FORMAT_XRGB8888, DRM_FORMAT_ARGB2101010 }; static const uint32_t tileable_texture_source_formats[] = { DRM_FORMAT_GR88, DRM_FORMAT_R8, DRM_FORMAT_UYVY, DRM_FORMAT_YUYV }; From cdb2554d7e109ca2416779b0b3edfdf3d8027ec5 Mon Sep 17 00:00:00 2001 From: Miguel Casas Date: Thu, 18 Jul 2019 13:07:30 -0400 Subject: [PATCH 128/269] minigbm: enable BO_USE_HW_VIDEO_DECODER for P010 This should be enabled for decoding P010 buffers, but had forgotten to add this BO explicitly. Change-Id: Icd3bbd419711b649299c7eea92d93b3c7f9a5ada Bug: 911754 Reviewed-on: https://chromium-review.googlesource.com/1708514 Tested-by: Miguel Casas Commit-Ready: Miguel Casas Legacy-Commit-Queue: Commit Bot Reviewed-by: Gurchetan Singh --- i915.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/i915.c b/i915.c index dfde42f..a583ad9 100644 --- a/i915.c +++ b/i915.c @@ -188,9 +188,11 @@ static int i915_add_combinations(struct driver *drv) ARRAY_SIZE(tileable_texture_source_formats), &metadata, texture_use_flags); - /* Support y-tiled NV12 for libva */ + /* Support y-tiled NV12 and P010 for libva */ drv_add_combination(drv, DRM_FORMAT_NV12, &metadata, BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER); + drv_add_combination(drv, DRM_FORMAT_P010, &metadata, + BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER); kms_items = drv_query_kms(drv); if (!kms_items) From 4a0fecf12f7b712000c5da9fb8f5f2ceccd7dbb9 Mon Sep 17 00:00:00 2001 From: Greg Hartman Date: Wed, 17 Jul 2019 15:55:17 -0700 Subject: [PATCH 129/269] Fix potential uninitialed read BUG=none Test=can compile crosvm Change-Id: I65577ca08f4d41ff6a7b6d2a2af42f82798608bf Tested-by: ghartman@google.com Reviewed-by: adelva@google.com Reviewed-on: https://android-review.googlesource.com/c/platform/external/minigbm/+/1056177 Reviewed-on: https://chromium-review.googlesource.com/1707385 Tested-by: Greg Hartman Commit-Ready: ChromeOS CL Exonerator Bot Legacy-Commit-Queue: Commit Bot Reviewed-by: Gurchetan Singh --- helpers.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/helpers.c b/helpers.c index 66e7e78..992eeb7 100644 --- a/helpers.c +++ b/helpers.c @@ -531,7 +531,8 @@ void drv_modify_combination(struct driver *drv, uint32_t format, struct format_m struct drv_array *drv_query_kms(struct driver *drv) { struct drv_array *kms_items; - uint64_t plane_type, use_flag; + uint64_t plane_type = UINT64_MAX; + uint64_t use_flag; uint32_t i, j, k; drmModePlanePtr plane; From a0868975d7d0242fd47c0090c2f779f8f2049dba Mon Sep 17 00:00:00 2001 From: Mark Yacoub Date: Thu, 25 Jul 2019 11:08:07 -0400 Subject: [PATCH 130/269] minigbm/i915: Add support for I915_FORMAT_MOD_Y_TILED_CCS This adds support for allocating buffers with the I915_FORMAT_MOD_Y_TILED_CCS modifier, which enables Intels render buffer compression. BUG=979736 Change-Id: I2f3d19be8b7661693054da8a153c2412c65233f1 Reviewed-on: https://chromium-review.googlesource.com/1706735 Tested-by: Mark Yacoub Commit-Ready: ChromeOS CL Exonerator Bot Legacy-Commit-Queue: Commit Bot Reviewed-by: Gurchetan Singh Reviewed-by: Mark Yacoub --- i915.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/i915.c b/i915.c index a583ad9..714142e 100644 --- a/i915.c +++ b/i915.c @@ -359,6 +359,7 @@ static int i915_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t h bo->tiling = I915_TILING_X; break; case I915_FORMAT_MOD_Y_TILED: + case I915_FORMAT_MOD_Y_TILED_CCS: bo->tiling = I915_TILING_Y; break; } @@ -376,6 +377,47 @@ static int i915_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t h */ uint32_t stride = ALIGN(width, 32); drv_bo_from_format(bo, stride, height, format); + } else if (modifier == I915_FORMAT_MOD_Y_TILED_CCS) { + /* + * For compressed surfaces, we need a color control surface + * (CCS). Color compression is only supported for Y tiled + * surfaces, and for each 32x16 tiles in the main surface we + * need a tile in the control surface. Y tiles are 128 bytes + * wide and 32 lines tall and we use that to first compute the + * width and height in tiles of the main surface. stride and + * height are already multiples of 128 and 32, respectively: + */ + uint32_t stride = drv_stride_from_format(format, width, 0); + uint32_t width_in_tiles = DIV_ROUND_UP(stride, 128); + uint32_t height_in_tiles = DIV_ROUND_UP(height, 32); + uint32_t size = width_in_tiles * height_in_tiles * 4096; + uint32_t offset = 0; + + bo->strides[0] = width_in_tiles * 128; + bo->sizes[0] = size; + bo->offsets[0] = offset; + offset += size; + + /* + * Now, compute the width and height in tiles of the control + * surface by dividing and rounding up. + */ + uint32_t ccs_width_in_tiles = DIV_ROUND_UP(width_in_tiles, 32); + uint32_t ccs_height_in_tiles = DIV_ROUND_UP(height_in_tiles, 16); + uint32_t ccs_size = ccs_width_in_tiles * ccs_height_in_tiles * 4096; + + /* + * With stride and height aligned to y tiles, offset is + * already a multiple of 4096, which is the required alignment + * of the CCS. + */ + bo->strides[1] = ccs_width_in_tiles * 128; + bo->sizes[1] = ccs_size; + bo->offsets[1] = offset; + offset += ccs_size; + + bo->num_planes = 2; + bo->total_size = offset; } else { i915_bo_from_format(bo, width, height, format); } @@ -427,6 +469,7 @@ static int i915_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint32_t uint32_t format, const uint64_t *modifiers, uint32_t count) { static const uint64_t modifier_order[] = { + I915_FORMAT_MOD_Y_TILED_CCS, I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED, DRM_FORMAT_MOD_LINEAR, @@ -473,6 +516,9 @@ static void *i915_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t int ret; void *addr; + if (bo->format_modifiers[0] == I915_FORMAT_MOD_Y_TILED_CCS) + return MAP_FAILED; + if (bo->tiling == I915_TILING_NONE) { struct drm_i915_gem_mmap gem_map; memset(&gem_map, 0, sizeof(gem_map)); From 62a7f2ef5106a1e090a6ab5b0fd5c39d36555ba8 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Thu, 25 Jul 2019 20:48:28 -0700 Subject: [PATCH 131/269] minigbm: clang format It's good to run this once and a while. Change-Id: I69b6f9252455360b6d326a3ec89fe51517abda2f Reviewed-on: https://chromium-review.googlesource.com/1719976 Tested-by: Gurchetan Singh Commit-Ready: ChromeOS CL Exonerator Bot Legacy-Commit-Queue: Commit Bot Reviewed-by: Gurchetan Singh --- cros_gralloc/gralloc0/tests/gralloctest.c | 2 +- drv.c | 2 +- i915.c | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cros_gralloc/gralloc0/tests/gralloctest.c b/cros_gralloc/gralloc0/tests/gralloctest.c index 9160e62..8dfcd0b 100644 --- a/cros_gralloc/gralloc0/tests/gralloctest.c +++ b/cros_gralloc/gralloc0/tests/gralloctest.c @@ -95,7 +95,7 @@ static struct combinations combos[] = { // clang-format on struct grallocinfo { - buffer_handle_t handle; /* handle to the buffer */ + buffer_handle_t handle; /* handle to the buffer */ int w; /* width of buffer */ int h; /* height of buffer */ int format; /* format of the buffer */ diff --git a/drv.c b/drv.c index b920d45..fa157ef 100644 --- a/drv.c +++ b/drv.c @@ -111,7 +111,7 @@ static const struct backend *drv_get_backend(int fd) #ifdef DRV_VC4 &backend_vc4, #endif - &backend_vgem, &backend_virtio_gpu, + &backend_vgem, &backend_virtio_gpu, }; for (i = 0; i < ARRAY_SIZE(backend_list); i++) diff --git a/i915.c b/i915.c index 714142e..6a36ae9 100644 --- a/i915.c +++ b/i915.c @@ -23,11 +23,11 @@ #define I915_CACHELINE_SIZE 64 #define I915_CACHELINE_MASK (I915_CACHELINE_SIZE - 1) -static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB1555, - DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB565, +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, DRM_FORMAT_ARGB2101010 }; + DRM_FORMAT_XRGB1555, DRM_FORMAT_XRGB2101010, + DRM_FORMAT_XRGB8888, DRM_FORMAT_ARGB2101010 }; static const uint32_t tileable_texture_source_formats[] = { DRM_FORMAT_GR88, DRM_FORMAT_R8, DRM_FORMAT_UYVY, DRM_FORMAT_YUYV }; From f659eb7d3df7f1bac875ecb11c8ec6f9c1f4a01f Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Fri, 26 Jul 2019 18:11:18 -0700 Subject: [PATCH 132/269] minigbm: cros_gralloc: fix fd leaks We were leaking fds. BUG=none TEST=compile Change-Id: I75f43d6f696f619c0ae284695b38586bc9ffff8c Reviewed-on: https://chromium-review.googlesource.com/1722289 Tested-by: Gurchetan Singh Commit-Ready: ChromeOS CL Exonerator Bot Legacy-Commit-Queue: Commit Bot Reviewed-by: Tomasz Figa --- cros_gralloc/cros_gralloc_driver.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/cros_gralloc/cros_gralloc_driver.cc b/cros_gralloc/cros_gralloc_driver.cc index 8096b7f..8a63864 100644 --- a/cros_gralloc/cros_gralloc_driver.cc +++ b/cros_gralloc/cros_gralloc_driver.cc @@ -21,8 +21,10 @@ cros_gralloc_driver::~cros_gralloc_driver() handles_.clear(); if (drv_) { + int fd = drv_get_fd(drv_); drv_destroy(drv_); drv_ = nullptr; + close(fd); } } @@ -56,10 +58,13 @@ int32_t cros_gralloc_driver::init() continue; version = drmGetVersion(fd); - if (!version) + if (!version) { + close(fd); continue; + } if (undesired[i] && !strcmp(version->name, undesired[i])) { + close(fd); drmFreeVersion(version); continue; } @@ -68,6 +73,8 @@ int32_t cros_gralloc_driver::init() drv_ = drv_create(fd); if (drv_) return 0; + + close(fd); } } From 5dc63faf56e4833f45c18c7ab6be9f9847cfe53c Mon Sep 17 00:00:00 2001 From: Hirokazu Honda Date: Wed, 31 Jul 2019 17:33:06 +0900 Subject: [PATCH 133/269] amdgpu: Enable to allocate YVU420 buffer with BO_USE_TEXTURE_MASK flag Chrome needs to allocate YUV420 buffer that cpu can read and write with a linear view. YUV420 is not supported by gbm widely. YVU420 is used on behalf of YUV420. This CL adds YVU420 to texture_source_formats so that YVU420 buffer can be allocated on AMD platform. BUG=chromium:987860 TEST=None Change-Id: I11af92e74ad1d3c7c5631e67c5a2fef90077d887 Reviewed-on: https://chromium-review.googlesource.com/1728730 Tested-by: Hirokazu Honda Commit-Ready: Hirokazu Honda Legacy-Commit-Queue: Commit Bot Reviewed-by: Gurchetan Singh Reviewed-by: Hirokazu Honda --- amdgpu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/amdgpu.c b/amdgpu.c index 095335e..8e578df 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -38,7 +38,8 @@ const static uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMA DRM_FORMAT_XRGB8888 }; const static uint32_t texture_source_formats[] = { DRM_FORMAT_GR88, DRM_FORMAT_R8, DRM_FORMAT_NV21, - DRM_FORMAT_NV12, DRM_FORMAT_YVU420_ANDROID }; + DRM_FORMAT_NV12, DRM_FORMAT_YVU420_ANDROID, + DRM_FORMAT_YVU420 }; static int amdgpu_init(struct driver *drv) { From b892a8f722fe3ccf44fdd6e81777f8ad674598cb Mon Sep 17 00:00:00 2001 From: Hirokazu Honda Date: Thu, 1 Aug 2019 16:37:47 +0900 Subject: [PATCH 134/269] rockchip: Fix the size computation with NV12 buffer The size and offsets are computed with the given height that is not aligned. This CL changes to compute them with an aligned height Bug: None Test: video_decode_accelerator_tests on kevin Change-Id: I3e316400d2ab40beee8785f337e9451408ef7318 Reviewed-on: https://chromium-review.googlesource.com/1729176 Tested-by: Hirokazu Honda Commit-Ready: ChromeOS CL Exonerator Bot Legacy-Commit-Queue: Commit Bot Reviewed-by: Gurchetan Singh Reviewed-by: Tomasz Figa --- rockchip.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/rockchip.c b/rockchip.c index 0266357..840b37a 100644 --- a/rockchip.c +++ b/rockchip.c @@ -159,14 +159,18 @@ static int rockchip_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint struct drm_rockchip_gem_create gem_create; if (format == DRM_FORMAT_NV12) { - uint32_t w_mbs = DIV_ROUND_UP(ALIGN(width, 16), 16); - uint32_t h_mbs = DIV_ROUND_UP(ALIGN(height, 16), 16); + uint32_t w_mbs = DIV_ROUND_UP(width, 16); + uint32_t h_mbs = DIV_ROUND_UP(height, 16); uint32_t aligned_width = w_mbs * 16; - uint32_t aligned_height = DIV_ROUND_UP(h_mbs * 16 * 3, 2); + uint32_t aligned_height = h_mbs * 16; - drv_bo_from_format(bo, aligned_width, height, format); - bo->total_size = bo->strides[0] * aligned_height + w_mbs * h_mbs * 128; + drv_bo_from_format(bo, aligned_width, aligned_height, format); + /* + * drv_bo_from_format updates total_size. Add an extra data space for rockchip video + * driver to store motion vectors. + */ + bo->total_size += w_mbs * h_mbs * 128; } else if (width <= 2560 && drv_has_modifier(modifiers, count, DRM_FORMAT_MOD_CHROMEOS_ROCKCHIP_AFBC)) { /* If the caller has decided they can use AFBC, always From 0f0ce6ffc9059a1fe945e697dea5a01e40316c52 Mon Sep 17 00:00:00 2001 From: Hirokazu Honda Date: Wed, 24 Jul 2019 19:40:20 +0900 Subject: [PATCH 135/269] mediatek: Add NV12 format for output frame in HW decoder YV12 have been a pixel format of output frame in HW decoder on MediaTek device. Since all other platforms uses NV12 for the format, it is good to change the format to NV12 on MediaTek as well. So we can only think about NV12 for a pixel format in HW decoder. BUG=chromium:987185 TEST=video_decode_accelerator_tests TEST=Play video with Chrome Cq-Depend:chromium:1716844 Change-Id: Ic7e4f66d503247bdeba9cb66c8a598b233ed6df9 Reviewed-on: https://chromium-review.googlesource.com/1716864 Tested-by: Hirokazu Honda Commit-Ready: ChromeOS CL Exonerator Bot Legacy-Commit-Queue: Commit Bot Reviewed-by: Gurchetan Singh --- mediatek.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mediatek.c b/mediatek.c index 0bcc28c..8842850 100644 --- a/mediatek.c +++ b/mediatek.c @@ -40,7 +40,7 @@ static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID }; #else static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_YVU420, - DRM_FORMAT_YVU420_ANDROID }; + DRM_FORMAT_YVU420_ANDROID, DRM_FORMAT_NV12 }; #endif static int mediatek_init(struct driver *drv) @@ -62,6 +62,7 @@ static int mediatek_init(struct driver *drv) metadata.modifier = DRM_FORMAT_MOD_LINEAR; drv_modify_combination(drv, DRM_FORMAT_YVU420, &metadata, BO_USE_HW_VIDEO_DECODER); drv_modify_combination(drv, DRM_FORMAT_YVU420_ANDROID, &metadata, BO_USE_HW_VIDEO_DECODER); + drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata, BO_USE_HW_VIDEO_DECODER); #ifdef MTK_MT8183 /* Only for MT8183 Camera subsystem */ @@ -235,7 +236,7 @@ static uint32_t mediatek_resolve_format(struct driver *drv, uint32_t format, uin if (use_flags & (BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE)) return DRM_FORMAT_NV12; #endif - return DRM_FORMAT_YVU420; + return DRM_FORMAT_NV12; default: return format; } From 3b8d4d0c83d0d46a9bc2e855f2330a850efd94ee Mon Sep 17 00:00:00 2001 From: Hirokazu Honda Date: Wed, 31 Jul 2019 16:35:52 +0900 Subject: [PATCH 136/269] Add GBM_BO_USE_HW_VIDEO_ENCODER use flag Chrome needs to allocate a linear buffer that a hardware video encoder can read and cpu can read and write. There is no use flag in gbm that specifies the former. This CL introduces a new use flag for that. BUG=b:138703716 TEST=None Change-Id: Ied0321914a366294a47e4fc5c2a8f08ee0351bd8 Reviewed-on: https://chromium-review.googlesource.com/1728729 Tested-by: Hirokazu Honda Commit-Ready: ChromeOS CL Exonerator Bot Legacy-Commit-Queue: Commit Bot Reviewed-by: Gurchetan Singh --- amdgpu.c | 13 ++++++++++--- gbm.h | 4 ++++ gbm_helpers.c | 2 ++ i915.c | 7 +++++++ mediatek.c | 7 +++++++ msm.c | 7 +++++++ rockchip.c | 7 +++++++ 7 files changed, 44 insertions(+), 3 deletions(-) diff --git a/amdgpu.c b/amdgpu.c index 8e578df..65dd864 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -37,9 +37,9 @@ const static uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMA DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888 }; -const static uint32_t texture_source_formats[] = { DRM_FORMAT_GR88, DRM_FORMAT_R8, DRM_FORMAT_NV21, - DRM_FORMAT_NV12, DRM_FORMAT_YVU420_ANDROID, - DRM_FORMAT_YVU420 }; +const static uint32_t texture_source_formats[] = { DRM_FORMAT_GR88, DRM_FORMAT_R8, + DRM_FORMAT_NV21, DRM_FORMAT_NV12, + DRM_FORMAT_YVU420_ANDROID, DRM_FORMAT_YVU420 }; static int amdgpu_init(struct driver *drv) { @@ -79,6 +79,13 @@ static int amdgpu_init(struct driver *drv) drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), &metadata, BO_USE_TEXTURE_MASK); + /* + * Chrome uses DMA-buf mmap to write to YV12 buffers, which are then accessed by the + * Video Encoder Accelerator (VEA). It could also support NV12 potentially in the future. + */ + drv_modify_combination(drv, DRM_FORMAT_YVU420, &metadata, BO_USE_HW_VIDEO_ENCODER); + drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata, BO_USE_HW_VIDEO_ENCODER); + /* Android CTS tests require this. */ drv_add_combination(drv, DRM_FORMAT_BGR888, &metadata, BO_USE_SW_MASK); diff --git a/gbm.h b/gbm.h index 6150530..a2f10f6 100644 --- a/gbm.h +++ b/gbm.h @@ -273,6 +273,10 @@ enum gbm_bo_flags { * The buffer will be written by a video decode accelerator. */ GBM_BO_USE_HW_VIDEO_DECODER = (1 << 13), + /** + * The buffer will be read by a video encode accelerator. + */ + GBM_BO_USE_HW_VIDEO_ENCODER = (1 << 14), }; int diff --git a/gbm_helpers.c b/gbm_helpers.c index 81d1680..0626a6d 100644 --- a/gbm_helpers.c +++ b/gbm_helpers.c @@ -42,6 +42,8 @@ uint64_t gbm_convert_usage(uint32_t usage) use_flags |= BO_USE_SW_WRITE_RARELY; if (usage & GBM_BO_USE_HW_VIDEO_DECODER) use_flags |= BO_USE_HW_VIDEO_DECODER; + if (usage & GBM_BO_USE_HW_VIDEO_ENCODER) + use_flags |= BO_USE_HW_VIDEO_ENCODER; return use_flags; } diff --git a/i915.c b/i915.c index 6a36ae9..44f08f8 100644 --- a/i915.c +++ b/i915.c @@ -138,6 +138,13 @@ static int i915_add_combinations(struct driver *drv) ARRAY_SIZE(tileable_texture_source_formats), &metadata, texture_use_flags); + /* + * Chrome uses DMA-buf mmap to write to YV12 buffers, which are then accessed by the + * Video Encoder Accelerator (VEA). It could also support NV12 potentially in the future. + */ + drv_modify_combination(drv, DRM_FORMAT_YVU420, &metadata, BO_USE_HW_VIDEO_ENCODER); + drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata, BO_USE_HW_VIDEO_ENCODER); + /* Android CTS tests require this. */ drv_add_combination(drv, DRM_FORMAT_BGR888, &metadata, BO_USE_SW_MASK); diff --git a/mediatek.c b/mediatek.c index 8842850..fd0c126 100644 --- a/mediatek.c +++ b/mediatek.c @@ -53,6 +53,13 @@ static int mediatek_init(struct driver *drv) drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), &LINEAR_METADATA, BO_USE_TEXTURE_MASK); + /* + * Chrome uses DMA-buf mmap to write to YV12 buffers, which are then accessed by the + * Video Encoder Accelerator (VEA). It could also support NV12 potentially in the future. + */ + drv_modify_combination(drv, DRM_FORMAT_YVU420, &LINEAR_METADATA, BO_USE_HW_VIDEO_ENCODER); + drv_modify_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA, BO_USE_HW_VIDEO_ENCODER); + /* Android CTS tests require this. */ drv_add_combination(drv, DRM_FORMAT_BGR888, &LINEAR_METADATA, BO_USE_SW_MASK); diff --git a/msm.c b/msm.c index 268e6d3..a8df000 100644 --- a/msm.c +++ b/msm.c @@ -166,6 +166,13 @@ static int msm_init(struct driver *drv) drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), &LINEAR_METADATA, texture_use_flags); + /* + * Chrome uses DMA-buf mmap to write to YV12 buffers, which are then accessed by the + * Video Encoder Accelerator (VEA). It could also support NV12 potentially in the future. + */ + drv_modify_combination(drv, DRM_FORMAT_YVU420, &LINEAR_METADATA, BO_USE_HW_VIDEO_ENCODER); + drv_modify_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA, BO_USE_HW_VIDEO_ENCODER); + /* Android CTS tests require this. */ drv_add_combination(drv, DRM_FORMAT_BGR888, &LINEAR_METADATA, BO_USE_SW_MASK); diff --git a/rockchip.c b/rockchip.c index 840b37a..a1685af 100644 --- a/rockchip.c +++ b/rockchip.c @@ -121,6 +121,13 @@ static int rockchip_init(struct driver *drv) drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), &metadata, BO_USE_TEXTURE_MASK); + /* + * Chrome uses DMA-buf mmap to write to YV12 buffers, which are then accessed by the + * Video Encoder Accelerator (VEA). It could also support NV12 potentially in the future. + */ + drv_modify_combination(drv, DRM_FORMAT_YVU420, &metadata, BO_USE_HW_VIDEO_ENCODER); + drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata, BO_USE_HW_VIDEO_ENCODER); + 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); From 9f7897f47f82790fbabbe36fe5515b5f050bcb74 Mon Sep 17 00:00:00 2001 From: David Stevens Date: Fri, 9 Aug 2019 20:20:23 +0900 Subject: [PATCH 137/269] minigbm: virtio_gpu: Add camera usage to all NV12 combinations This change adds camera usage to all NV12 combinations after all combinations have been added. This fixes an issue where a virtio_gpu with 3d support would not have any camera compatible NV12 combinations. BUG=b:132939858 TEST=Camera apps run on arcvm with no gralloc errors (although they don't actually work for separate reasons). Change-Id: Icc868398d6e036f8430afb9a351809bb7965202e Reviewed-on: https://chromium-review.googlesource.com/1746346 Tested-by: Tomasz Figa Commit-Ready: ChromeOS CL Exonerator Bot Legacy-Commit-Queue: Commit Bot Reviewed-by: Tomasz Figa --- virtio_gpu.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/virtio_gpu.c b/virtio_gpu.c index 4e671dd..163207e 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -218,13 +218,14 @@ static int virtio_gpu_init(struct driver *drv) ARRAY_SIZE(dumb_texture_source_formats), &LINEAR_METADATA, BO_USE_TEXTURE_MASK); drv_add_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA, - BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_SW_MASK | - BO_USE_LINEAR); + BO_USE_SW_MASK | BO_USE_LINEAR); } /* Android CTS tests require this. */ drv_add_combination(drv, DRM_FORMAT_BGR888, &LINEAR_METADATA, BO_USE_SW_MASK); + drv_modify_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA, + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); drv_modify_combination(drv, DRM_FORMAT_R8, &LINEAR_METADATA, BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); From 782fae07b2294c5d901561a24125658e78cf988d Mon Sep 17 00:00:00 2001 From: Mark Yacoub Date: Wed, 21 Aug 2019 19:32:43 +0000 Subject: [PATCH 138/269] Revert "minigbm/i915: Add support for I915_FORMAT_MOD_Y_TILED_CCS" This reverts commit a0868975d7d0242fd47c0090c2f779f8f2049dba. Reason for revert: Broke many tests such as the screenshot test and using a 2nd external monitor. Original change's description: > minigbm/i915: Add support for I915_FORMAT_MOD_Y_TILED_CCS > > This adds support for allocating buffers with the > I915_FORMAT_MOD_Y_TILED_CCS modifier, which enables Intels render > buffer compression. > > BUG=979736 > > Change-Id: I2f3d19be8b7661693054da8a153c2412c65233f1 > Reviewed-on: https://chromium-review.googlesource.com/1706735 > Tested-by: Mark Yacoub > Commit-Ready: ChromeOS CL Exonerator Bot > Legacy-Commit-Queue: Commit Bot > Reviewed-by: Gurchetan Singh > Reviewed-by: Mark Yacoub Bug: 996011,988559,995549,996036, Change-Id: I5fbed90c5d8774b9385811a145b14a11423bb707 Reviewed-on: https://chromium-review.googlesource.com/1759155 Tested-by: Mark Yacoub Commit-Ready: Mark Yacoub Legacy-Commit-Queue: Commit Bot Reviewed-by: Gurchetan Singh Reviewed-by: Mark Yacoub --- i915.c | 46 ---------------------------------------------- 1 file changed, 46 deletions(-) diff --git a/i915.c b/i915.c index 44f08f8..9683bf0 100644 --- a/i915.c +++ b/i915.c @@ -366,7 +366,6 @@ static int i915_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t h bo->tiling = I915_TILING_X; break; case I915_FORMAT_MOD_Y_TILED: - case I915_FORMAT_MOD_Y_TILED_CCS: bo->tiling = I915_TILING_Y; break; } @@ -384,47 +383,6 @@ static int i915_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t h */ uint32_t stride = ALIGN(width, 32); drv_bo_from_format(bo, stride, height, format); - } else if (modifier == I915_FORMAT_MOD_Y_TILED_CCS) { - /* - * For compressed surfaces, we need a color control surface - * (CCS). Color compression is only supported for Y tiled - * surfaces, and for each 32x16 tiles in the main surface we - * need a tile in the control surface. Y tiles are 128 bytes - * wide and 32 lines tall and we use that to first compute the - * width and height in tiles of the main surface. stride and - * height are already multiples of 128 and 32, respectively: - */ - uint32_t stride = drv_stride_from_format(format, width, 0); - uint32_t width_in_tiles = DIV_ROUND_UP(stride, 128); - uint32_t height_in_tiles = DIV_ROUND_UP(height, 32); - uint32_t size = width_in_tiles * height_in_tiles * 4096; - uint32_t offset = 0; - - bo->strides[0] = width_in_tiles * 128; - bo->sizes[0] = size; - bo->offsets[0] = offset; - offset += size; - - /* - * Now, compute the width and height in tiles of the control - * surface by dividing and rounding up. - */ - uint32_t ccs_width_in_tiles = DIV_ROUND_UP(width_in_tiles, 32); - uint32_t ccs_height_in_tiles = DIV_ROUND_UP(height_in_tiles, 16); - uint32_t ccs_size = ccs_width_in_tiles * ccs_height_in_tiles * 4096; - - /* - * With stride and height aligned to y tiles, offset is - * already a multiple of 4096, which is the required alignment - * of the CCS. - */ - bo->strides[1] = ccs_width_in_tiles * 128; - bo->sizes[1] = ccs_size; - bo->offsets[1] = offset; - offset += ccs_size; - - bo->num_planes = 2; - bo->total_size = offset; } else { i915_bo_from_format(bo, width, height, format); } @@ -476,7 +434,6 @@ static int i915_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint32_t uint32_t format, const uint64_t *modifiers, uint32_t count) { static const uint64_t modifier_order[] = { - I915_FORMAT_MOD_Y_TILED_CCS, I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED, DRM_FORMAT_MOD_LINEAR, @@ -523,9 +480,6 @@ static void *i915_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t int ret; void *addr; - if (bo->format_modifiers[0] == I915_FORMAT_MOD_Y_TILED_CCS) - return MAP_FAILED; - if (bo->tiling == I915_TILING_NONE) { struct drm_i915_gem_mmap gem_map; memset(&gem_map, 0, sizeof(gem_map)); From 3d856025f8f057d29361e753ef712993d218d6e9 Mon Sep 17 00:00:00 2001 From: Hirokazu Honda Date: Fri, 23 Aug 2019 14:31:31 +0900 Subject: [PATCH 139/269] mediatek: Change android flexible format to allocate YVU420 buffer crrev.com/c/1716864 made gralloc allocae NV12 buffer with the android flexible format, DRM_FORMAT_FLEX_YCbCr_420_888. However, the change broke many CTS tests. This partially reverts the commit. The allocated buffer fromat becomes YVU420. BUG=chromium:987185 BUG=b:139714614 Cq-Depend: chromium:1767680 Change-Id: I9fcde88cff79fac2655fb627418b371b314077c1 Reviewed-on: https://chromium-review.googlesource.com/1767450 Tested-by: Hirokazu Honda Commit-Ready: Hirokazu Honda Legacy-Commit-Queue: Commit Bot Reviewed-by: Tomasz Figa --- mediatek.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediatek.c b/mediatek.c index fd0c126..199d3cf 100644 --- a/mediatek.c +++ b/mediatek.c @@ -243,7 +243,7 @@ static uint32_t mediatek_resolve_format(struct driver *drv, uint32_t format, uin if (use_flags & (BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE)) return DRM_FORMAT_NV12; #endif - return DRM_FORMAT_NV12; + return DRM_FORMAT_YVU420; default: return format; } From d7c83386cc7ff1cb96adc9530bfc48ef08c9bb87 Mon Sep 17 00:00:00 2001 From: Nicolas Boichat Date: Thu, 29 Aug 2019 21:46:29 +0800 Subject: [PATCH 140/269] mediatek/rockchip: Use PRIu64 to print uint64_t variables Required to build for arm64 on mediatek, and let's fix the rockchip one, while we're at it. BUG=b:140228960 TEST=emerge-kevin-arc64 -av arc-cros-gralloc TEST=emerge-kukui -av arc-cros-gralloc (with ARC++ 64-bit) Change-Id: I8e04355a4d247b44ac86963331be72495655d321 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1775949 Tested-by: Nicolas Boichat Auto-Submit: Nicolas Boichat Legacy-Commit-Queue: Commit Bot Reviewed-by: Gurchetan Singh Commit-Queue: Nicolas Boichat --- mediatek.c | 3 ++- rockchip.c | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/mediatek.c b/mediatek.c index 199d3cf..d3a2727 100644 --- a/mediatek.c +++ b/mediatek.c @@ -9,6 +9,7 @@ // clang-format off #include #include +#include #include #include #include @@ -116,7 +117,7 @@ static int mediatek_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint ret = drmIoctl(bo->drv->fd, DRM_IOCTL_MTK_GEM_CREATE, &gem_create); if (ret) { - drv_log("DRM_IOCTL_MTK_GEM_CREATE failed (size=%llu)\n", gem_create.size); + drv_log("DRM_IOCTL_MTK_GEM_CREATE failed (size=%" PRIu64 ")\n", gem_create.size); return -errno; } diff --git a/rockchip.c b/rockchip.c index a1685af..216c592 100644 --- a/rockchip.c +++ b/rockchip.c @@ -7,6 +7,7 @@ #ifdef DRV_ROCKCHIP #include +#include #include #include #include @@ -212,8 +213,8 @@ static int rockchip_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint ret = drmIoctl(bo->drv->fd, DRM_IOCTL_ROCKCHIP_GEM_CREATE, &gem_create); if (ret) { - drv_log("DRM_IOCTL_ROCKCHIP_GEM_CREATE failed (size=%llu)\n", - (unsigned long long)gem_create.size); + drv_log("DRM_IOCTL_ROCKCHIP_GEM_CREATE failed (size=%" PRIu64 ")\n", + gem_create.size); return -errno; } From b80c6b9737dc22e7b71ca684fa85e51953465512 Mon Sep 17 00:00:00 2001 From: Hirokazu Honda Date: Fri, 30 Aug 2019 11:07:53 +0900 Subject: [PATCH 141/269] rockchip: Don't align height in NV12 format crrev.com/c/1729176 corrected a wrong NV12 buffer allocation on rockchip. After the CL, the width and height both are aligned by 16. Since GBM API doesn't notify the aligned height to an application. The application must handle the planes with offsets. It turns out that Camera HAL on ChromeOS doesn't handle the allocated buffer with offsets. In other words, it doesn't think of extra data between planes. This causes, in a camera preview, a green line at bottom and a strange blue line due to misposition of color planes. This CL is a temproal workaround for the Camera HAL issue. This CL changes minigbm implementation to not align height. This works because present video encoder and decoder always calls GBM API with the height already aligned by video driver. Note that a camera stack on encoding process will have to allocate a proper buffer with non-aligned height in the future. This must be a temporal workaround. BUG=b:140152839 TEST=Confirm no green line in camera view and recorded video with Camera app Change-Id: Ide53fa6801fc4bdabcfbe46004d01f5ab83a002f Reviewed-on: https://chromium-review.googlesource.com/1775953 Tested-by: Hirokazu Honda Commit-Ready: Hirokazu Honda Legacy-Commit-Queue: Commit Bot Reviewed-by: Tomasz Figa --- rockchip.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/rockchip.c b/rockchip.c index 216c592..e620a1b 100644 --- a/rockchip.c +++ b/rockchip.c @@ -171,9 +171,10 @@ static int rockchip_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint uint32_t h_mbs = DIV_ROUND_UP(height, 16); uint32_t aligned_width = w_mbs * 16; - uint32_t aligned_height = h_mbs * 16; - drv_bo_from_format(bo, aligned_width, aligned_height, format); + // TODO(b/140152839): Align height by 16 once camera HAL + // supports multi planar format. + drv_bo_from_format(bo, aligned_width, height, format); /* * drv_bo_from_format updates total_size. Add an extra data space for rockchip video * driver to store motion vectors. From d97877bb4e458275e20e40af0a2f4335bb5e69de Mon Sep 17 00:00:00 2001 From: Kansho Nishida Date: Fri, 14 Jun 2019 18:28:18 +0900 Subject: [PATCH 142/269] minigbm: virtio-gpu: Allocate one buffer even for multi plane format It seems that DRM_IOCTL_VIRTGPU_RESOURCE_INFO ioctl doesn't work. BUG=b:133385154 b:132939420 TEST=None Change-Id: I3eec946894b0935a5fcd774346194087bb831249 Signed-off-by: Kansho Nishida Reviewed-on: https://chromium-review.googlesource.com/1659792 Tested-by: David Stevens Commit-Ready: Keiichi Watanabe Legacy-Commit-Queue: Commit Bot Reviewed-by: Gurchetan Singh --- virtio_gpu.c | 96 +++++++++++++++++++++------------------------------- 1 file changed, 38 insertions(+), 58 deletions(-) diff --git a/virtio_gpu.c b/virtio_gpu.c index 163207e..205f53a 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -39,7 +39,7 @@ struct virtio_gpu_priv { int has_3d; }; -static uint32_t translate_format(uint32_t drm_fourcc, uint32_t plane) +static uint32_t translate_format(uint32_t drm_fourcc) { switch (drm_fourcc) { case DRM_FORMAT_XRGB8888: @@ -88,7 +88,8 @@ static inline void handle_flag(uint64_t *flag, uint64_t check_flag, uint32_t *bi static uint32_t use_flags_to_bind(uint64_t use_flags) { - uint32_t bind = 0; + /* In crosvm, VIRGL_BIND_SHARED means minigbm will allocate, not virglrenderer. */ + uint32_t bind = VIRGL_BIND_SHARED; handle_flag(&use_flags, BO_USE_TEXTURE, &bind, VIRGL_BIND_SAMPLER_VIEW); handle_flag(&use_flags, BO_USE_RENDERING, &bind, VIRGL_BIND_RENDER_TARGET); @@ -97,6 +98,7 @@ static uint32_t use_flags_to_bind(uint64_t use_flags) if (use_flags) { drv_log("Unhandled bo use flag: %llx\n", (unsigned long long)use_flags); } + return bind; } @@ -104,66 +106,44 @@ static int virtio_virgl_bo_create(struct bo *bo, uint32_t width, uint32_t height uint64_t use_flags) { int ret; - ssize_t plane; - ssize_t num_planes = drv_num_planes_from_format(format); - uint32_t stride0; - uint32_t bind = use_flags_to_bind(use_flags); - - 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 = bind; - 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) { - drv_log("DRM_IOCTL_VIRTGPU_RESOURCE_CREATE failed with %s\n", - strerror(errno)); - ret = -errno; - goto fail; - } - - bo->handles[plane].u32 = res_create.bo_handle; + uint32_t stride; + struct drm_virtgpu_resource_create res_create; + + stride = drv_stride_from_format(format, width, 0); + drv_bo_from_format(bo, stride, height, format); + + /* + * 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. + */ + memset(&res_create, 0, sizeof(res_create)); + + res_create.target = PIPE_TEXTURE_2D; + res_create.format = translate_format(format); + res_create.bind = use_flags_to_bind(use_flags); + res_create.width = width; + res_create.height = height; + + /* For virgl 3D */ + res_create.depth = 1; + res_create.array_size = 1; + res_create.last_level = 0; + res_create.nr_samples = 0; + + res_create.size = ALIGN(bo->total_size, PAGE_SIZE); // PAGE_SIZE = 0x1000 + ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_RESOURCE_CREATE, &res_create); + if (ret) { + drv_log("DRM_IOCTL_VIRTGPU_RESOURCE_CREATE failed with %s\n", strerror(errno)); + return ret; } - 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; + for (uint32_t plane = 0; plane < bo->num_planes; plane++) + bo->handles[plane].u32 = res_create.bo_handle; 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 *virtio_virgl_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags) From d014ed5b4c12e7c806260e2ae304accfcd6c73aa Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Tue, 4 Jun 2019 16:27:56 -0700 Subject: [PATCH 143/269] minigbm: remove vgem backend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's not used anymore, or atleast shouldn't be. BUG=none TEST=CQ will test Change-Id: Ib9232a7704bd39e59a8e2a5bc2ece62c5dd8e9c1 Reviewed-on: https://chromium-review.googlesource.com/1643676 Tested-by: Gurchetan Singh Commit-Ready: ChromeOS CL Exonerator Bot Legacy-Commit-Queue: Commit Bot Reviewed-by: Stéphane Marchesin --- Android.mk | 1 - drv.c | 3 +-- vgem.c | 63 ------------------------------------------------------ 3 files changed, 1 insertion(+), 66 deletions(-) delete mode 100644 vgem.c diff --git a/Android.mk b/Android.mk index 564f416..0e1f284 100644 --- a/Android.mk +++ b/Android.mk @@ -26,7 +26,6 @@ MINIGBM_SRC := \ tegra.c \ udl.c \ vc4.c \ - vgem.c \ virtio_gpu.c MINIGBM_CPPFLAGS := -std=c++14 diff --git a/drv.c b/drv.c index fa157ef..810d4f8 100644 --- a/drv.c +++ b/drv.c @@ -61,7 +61,6 @@ extern const struct backend backend_udl; #ifdef DRV_VC4 extern const struct backend backend_vc4; #endif -extern const struct backend backend_vgem; extern const struct backend backend_virtio_gpu; static const struct backend *drv_get_backend(int fd) @@ -111,7 +110,7 @@ static const struct backend *drv_get_backend(int fd) #ifdef DRV_VC4 &backend_vc4, #endif - &backend_vgem, &backend_virtio_gpu, + &backend_virtio_gpu, }; for (i = 0; i < ARRAY_SIZE(backend_list); i++) diff --git a/vgem.c b/vgem.c deleted file mode 100644 index 0d0371c..0000000 --- a/vgem.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2016 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" - -#define MESA_LLVMPIPE_TILE_ORDER 6 -#define MESA_LLVMPIPE_TILE_SIZE (1 << MESA_LLVMPIPE_TILE_ORDER) - -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_YVU420, - DRM_FORMAT_YVU420_ANDROID }; - -static int vgem_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 vgem_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, - uint64_t flags) -{ - width = ALIGN(width, MESA_LLVMPIPE_TILE_SIZE); - height = ALIGN(height, MESA_LLVMPIPE_TILE_SIZE); - - return drv_dumb_bo_create(bo, width, height, format, flags); -} - -static uint32_t vgem_resolve_format(struct driver *drv, uint32_t format, uint64_t flags) -{ - switch (format) { - case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED: - /*HACK: See b/28671744 */ - return DRM_FORMAT_XBGR8888; - case DRM_FORMAT_FLEX_YCbCr_420_888: - return DRM_FORMAT_YVU420; - default: - return format; - } -} - -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, -}; From 05e67cc5e06af2b9898ae6fa396fb544efd600df Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Fri, 28 Jun 2019 17:21:40 -0700 Subject: [PATCH 144/269] minigbm: virtio-gpu: stride == level Unfortunately, the kernel doesn't actually pass the guest layer_stride and guest stride to the host (compare virtio_gpu.h and virtgpu_drm.h). We can use the level to work around this. BUG=b:132939420 TEST=none Change-Id: I96927b22fae2662a3a37e5191b3dfdf86c99dd84 Reviewed-on: https://chromium-review.googlesource.com/1683087 Tested-by: David Stevens Commit-Ready: David Stevens Legacy-Commit-Queue: Commit Bot Reviewed-by: David Stevens Reviewed-by: Gurchetan Singh --- virtio_gpu.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/virtio_gpu.c b/virtio_gpu.c index 205f53a..0c94eaf 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -263,6 +263,11 @@ static int virtio_gpu_bo_invalidate(struct bo *bo, struct mapping *mapping) xfer.box.h = mapping->rect.height; xfer.box.d = 1; + // Unfortunately, the kernel doesn't actually pass the guest layer_stride and + // guest stride to the host (compare virtio_gpu.h and virtgpu_drm.h). We can use + // the level to work around this. + xfer.level = bo->strides[0]; + ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST, &xfer); if (ret) { drv_log("DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST failed with %s\n", strerror(errno)); @@ -292,6 +297,11 @@ static int virtio_gpu_bo_flush(struct bo *bo, struct mapping *mapping) xfer.box.h = mapping->rect.height; xfer.box.d = 1; + // Unfortunately, the kernel doesn't actually pass the guest layer_stride and + // guest stride to the host (compare virtio_gpu.h and virtgpu_drm.h). We can use + // the level to work around this. + xfer.level = bo->strides[0]; + ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_TRANSFER_TO_HOST, &xfer); if (ret) { drv_log("DRM_IOCTL_VIRTGPU_TRANSFER_TO_HOST failed with %s\n", strerror(errno)); From 586e2d6f3a5c60cc9cc118392c3a4c2fd7798667 Mon Sep 17 00:00:00 2001 From: Nataraj Deshpande Date: Wed, 21 Aug 2019 15:19:46 -0700 Subject: [PATCH 145/269] minigbm: Add support for RGBA_1010102 and RGBA_FP16 The CL adds support for HAL_PIXEL_FORMAT_RGBA_1010102 and HAL_PIXEL_FORMAT_RGBA_FP16 in order to supplement Android framework's VkFormats: VK_FORMAT_A2B10G10R10_UNORM_PACK32 and VK_FORMAT_R16G16B16A16_SFLOAT. Fixes following dEQP failures on eve-arcnext. dEQP-VK.wsi.android.swapchain.create#image_format dEQP-VK.wsi.android.swapchain.simulate_oom#image_format dEQP-VK.wsi.android.colorspace#basic dEQP-VK.wsi.android.incremental_present.* BUG=b:139890132 TEST=Run dEQP-VK.wsi.android.* tests on eve-arcnext. Change-Id: I0b52d9f970d34fe69e1b8c31a1f096365a74d8ec Signed-off-by: Nataraj Deshpande Reviewed-on: https://chromium-review.googlesource.com/1769261 Commit-Ready: ChromeOS CL Exonerator Bot Legacy-Commit-Queue: Commit Bot Reviewed-by: Gurchetan Singh --- cros_gralloc/cros_gralloc_helpers.cc | 6 ++++++ helpers.c | 10 ++++++++++ i915.c | 11 ++++++----- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/cros_gralloc/cros_gralloc_helpers.cc b/cros_gralloc/cros_gralloc_helpers.cc index 12daf4b..73e59cb 100644 --- a/cros_gralloc/cros_gralloc_helpers.cc +++ b/cros_gralloc/cros_gralloc_helpers.cc @@ -39,6 +39,12 @@ uint32_t cros_gralloc_convert_format(int format) */ case HAL_PIXEL_FORMAT_BLOB: return DRM_FORMAT_R8; +#if ANDROID_VERSION >= 0x0a00 + case HAL_PIXEL_FORMAT_RGBA_1010102: + return DRM_FORMAT_ABGR2101010; + case HAL_PIXEL_FORMAT_RGBA_FP16: + return DRM_FORMAT_ABGR16161616F; +#endif } return DRM_FORMAT_NONE; diff --git a/helpers.c b/helpers.c index 992eeb7..1f5dfbb 100644 --- a/helpers.c +++ b/helpers.c @@ -54,6 +54,13 @@ static const struct planar_layout packed_4bpp_layout = { .bytes_per_pixel = { 4 } }; +static const struct planar_layout packed_8bpp_layout = { + .num_planes = 1, + .horizontal_subsampling = { 1 }, + .vertical_subsampling = { 1 }, + .bytes_per_pixel = { 8 } +}; + static const struct planar_layout biplanar_yuv_420_layout = { .num_planes = 2, .horizontal_subsampling = { 1, 2 }, @@ -146,6 +153,9 @@ static const struct planar_layout *layout_from_format(uint32_t format) case DRM_FORMAT_XRGB8888: return &packed_4bpp_layout; + case DRM_FORMAT_ABGR16161616F: + return &packed_8bpp_layout; + default: drv_log("UNKNOWN FORMAT %d\n", format); return NULL; diff --git a/i915.c b/i915.c index 9683bf0..3639eaa 100644 --- a/i915.c +++ b/i915.c @@ -23,11 +23,12 @@ #define I915_CACHELINE_SIZE 64 #define I915_CACHELINE_MASK (I915_CACHELINE_SIZE - 1) -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, DRM_FORMAT_ARGB2101010 }; +static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR16161616F, DRM_FORMAT_ABGR2101010, + DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB1555, + DRM_FORMAT_ARGB2101010, 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_R8, DRM_FORMAT_UYVY, DRM_FORMAT_YUYV }; From 5b91ec048176d9b9417075171912d1f9b7898f8a Mon Sep 17 00:00:00 2001 From: Kazuhiro Inaba Date: Thu, 19 Sep 2019 03:18:31 +0000 Subject: [PATCH 146/269] Revert "minigbm: remove vgem backend" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit d014ed5b4c12e7c806260e2ae304accfcd6c73aa. Reason for revert: broke video tests on rockchip devices b/141093122 Bug: 141278896 Bug: 141093122 Original change's description: > minigbm: remove vgem backend > > It's not used anymore, or atleast shouldn't be. > > BUG=none > TEST=CQ will test > > Change-Id: Ib9232a7704bd39e59a8e2a5bc2ece62c5dd8e9c1 > Reviewed-on: https://chromium-review.googlesource.com/1643676 > Tested-by: Gurchetan Singh > Commit-Ready: ChromeOS CL Exonerator Bot > Legacy-Commit-Queue: Commit Bot > Reviewed-by: Stéphane Marchesin Bug: none Change-Id: I6645e9b32ebc6dcd97d126cc40523f516a201a05 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1812540 Reviewed-by: Kazuhiro Inaba Reviewed-by: Gurchetan Singh Tested-by: Kazuhiro Inaba Auto-Submit: Kazuhiro Inaba Legacy-Commit-Queue: Commit Bot --- Android.mk | 1 + drv.c | 3 ++- vgem.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 vgem.c diff --git a/Android.mk b/Android.mk index 0e1f284..564f416 100644 --- a/Android.mk +++ b/Android.mk @@ -26,6 +26,7 @@ MINIGBM_SRC := \ tegra.c \ udl.c \ vc4.c \ + vgem.c \ virtio_gpu.c MINIGBM_CPPFLAGS := -std=c++14 diff --git a/drv.c b/drv.c index 810d4f8..fa157ef 100644 --- a/drv.c +++ b/drv.c @@ -61,6 +61,7 @@ extern const struct backend backend_udl; #ifdef DRV_VC4 extern const struct backend backend_vc4; #endif +extern const struct backend backend_vgem; extern const struct backend backend_virtio_gpu; static const struct backend *drv_get_backend(int fd) @@ -110,7 +111,7 @@ static const struct backend *drv_get_backend(int fd) #ifdef DRV_VC4 &backend_vc4, #endif - &backend_virtio_gpu, + &backend_vgem, &backend_virtio_gpu, }; for (i = 0; i < ARRAY_SIZE(backend_list); i++) diff --git a/vgem.c b/vgem.c new file mode 100644 index 0000000..0d0371c --- /dev/null +++ b/vgem.c @@ -0,0 +1,63 @@ +/* + * Copyright 2016 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" + +#define MESA_LLVMPIPE_TILE_ORDER 6 +#define MESA_LLVMPIPE_TILE_SIZE (1 << MESA_LLVMPIPE_TILE_ORDER) + +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_YVU420, + DRM_FORMAT_YVU420_ANDROID }; + +static int vgem_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 vgem_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint64_t flags) +{ + width = ALIGN(width, MESA_LLVMPIPE_TILE_SIZE); + height = ALIGN(height, MESA_LLVMPIPE_TILE_SIZE); + + return drv_dumb_bo_create(bo, width, height, format, flags); +} + +static uint32_t vgem_resolve_format(struct driver *drv, uint32_t format, uint64_t flags) +{ + switch (format) { + case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED: + /*HACK: See b/28671744 */ + return DRM_FORMAT_XBGR8888; + case DRM_FORMAT_FLEX_YCbCr_420_888: + return DRM_FORMAT_YVU420; + default: + return format; + } +} + +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, +}; From dc9b1204517ef9f2a8cdab4e03056bd51ed6fa70 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Tue, 4 Jun 2019 16:53:54 -0700 Subject: [PATCH 147/269] minigbm: rockchip/mediatek: remove R8 as texture source on Mali/Bifrost MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit EGL can't import this format on Mali/Bifrost. BUG=chromium:969044 TEST=Ozone unit test Change-Id: I356ec2bd35030af600b268bf39565e30e16465f5 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1643677 Reviewed-by: Stéphane Marchesin Tested-by: Gurchetan Singh Legacy-Commit-Queue: Commit Bot Commit-Queue: ChromeOS CL Exonerator Bot --- helpers.c | 2 +- mediatek.c | 11 ++++++----- rockchip.c | 9 +++++---- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/helpers.c b/helpers.c index 1f5dfbb..229d6be 100644 --- a/helpers.c +++ b/helpers.c @@ -542,7 +542,7 @@ struct drv_array *drv_query_kms(struct driver *drv) { struct drv_array *kms_items; uint64_t plane_type = UINT64_MAX; - uint64_t use_flag; + uint64_t use_flag; uint32_t i, j, k; drmModePlanePtr plane; diff --git a/mediatek.c b/mediatek.c index d3a2727..7282437 100644 --- a/mediatek.c +++ b/mediatek.c @@ -36,12 +36,12 @@ static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMA DRM_FORMAT_XRGB8888 }; #ifdef MTK_MT8183 -static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_NV21, - DRM_FORMAT_NV12, DRM_FORMAT_YUYV, - DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID }; +static const uint32_t texture_source_formats[] = { DRM_FORMAT_NV21, DRM_FORMAT_NV12, + DRM_FORMAT_YUYV, DRM_FORMAT_YVU420, + DRM_FORMAT_YVU420_ANDROID }; #else -static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_YVU420, - DRM_FORMAT_YVU420_ANDROID, DRM_FORMAT_NV12 }; +static const uint32_t texture_source_formats[] = { DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID, + DRM_FORMAT_NV12 }; #endif static int mediatek_init(struct driver *drv) @@ -54,6 +54,7 @@ static int mediatek_init(struct driver *drv) drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), &LINEAR_METADATA, BO_USE_TEXTURE_MASK); + drv_add_combination(drv, DRM_FORMAT_R8, &metadata, BO_USE_SW_MASK | BO_USE_LINEAR); /* * Chrome uses DMA-buf mmap to write to YV12 buffers, which are then accessed by the * Video Encoder Accelerator (VEA). It could also support NV12 potentially in the future. diff --git a/rockchip.c b/rockchip.c index e620a1b..9d1cf44 100644 --- a/rockchip.c +++ b/rockchip.c @@ -27,8 +27,8 @@ static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMA DRM_FORMAT_BGR888, DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888 }; -static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_NV12, - DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID }; +static const uint32_t texture_source_formats[] = { DRM_FORMAT_NV12, DRM_FORMAT_YVU420, + DRM_FORMAT_YVU420_ANDROID }; static int afbc_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, uint32_t format) { @@ -139,8 +139,9 @@ static int rockchip_init(struct driver *drv) * 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); + drv_add_combination(drv, DRM_FORMAT_R8, &metadata, + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_SW_MASK | + BO_USE_LINEAR); kms_items = drv_query_kms(drv); if (!kms_items) From 6116b3180dc347cce88f2750daf2227668ef03d4 Mon Sep 17 00:00:00 2001 From: David Stevens Date: Tue, 3 Sep 2019 10:49:50 +0900 Subject: [PATCH 148/269] minigbm: cros_gralloc: handle video decoder flag Although gralloc0 doesn't include a video decoder flag, the IAllocator gralloc0 passthrough gives the lower 32 bits of the BufferUsage flags to gralloc0. This change makes cros_gralloc add the video decoder BO_USE flag when that happens. It also adds some missing combinations for when the BO_USE_HW_VIDEO_DECODER flag is actually set. Change-Id: If2248f33ac2456c077fe63e90d2c39e7f57e2568 Reviewed-on: https://chromium-review.googlesource.com/1786419 Tested-by: David Stevens Commit-Ready: ChromeOS CL Exonerator Bot Legacy-Commit-Queue: Commit Bot Reviewed-by: Gurchetan Singh --- cros_gralloc/gralloc0/gralloc0.cc | 7 +++++++ i915.c | 3 ++- virtio_gpu.c | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/cros_gralloc/gralloc0/gralloc0.cc b/cros_gralloc/gralloc0/gralloc0.cc index df1f62c..eef5d2f 100644 --- a/cros_gralloc/gralloc0/gralloc0.cc +++ b/cros_gralloc/gralloc0/gralloc0.cc @@ -33,6 +33,11 @@ enum { }; // clang-format on +// Gralloc0 doesn't define a video decoder flag. However, the IAllocator gralloc0 +// passthrough gives the low 32-bits of the BufferUsage flags to gralloc0 in their +// entirety, so we can detect the video decoder flag passed by IAllocator clients. +#define BUFFER_USAGE_VIDEO_DECODER (1 << 22) + static uint64_t gralloc0_convert_usage(int usage) { uint64_t use_flags = BO_USE_NONE; @@ -75,6 +80,8 @@ static uint64_t gralloc0_convert_usage(int usage) use_flags |= BO_USE_CAMERA_READ; if (usage & GRALLOC_USAGE_RENDERSCRIPT) use_flags |= BO_USE_RENDERSCRIPT; + if (usage & BUFFER_USAGE_VIDEO_DECODER) + use_flags |= BO_USE_HW_VIDEO_DECODER; return use_flags; } diff --git a/i915.c b/i915.c index 3639eaa..ff5c66d 100644 --- a/i915.c +++ b/i915.c @@ -144,7 +144,8 @@ static int i915_add_combinations(struct driver *drv) * Video Encoder Accelerator (VEA). It could also support NV12 potentially in the future. */ drv_modify_combination(drv, DRM_FORMAT_YVU420, &metadata, BO_USE_HW_VIDEO_ENCODER); - drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata, BO_USE_HW_VIDEO_ENCODER); + drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata, + BO_USE_HW_VIDEO_ENCODER | BO_USE_HW_VIDEO_DECODER); /* Android CTS tests require this. */ drv_add_combination(drv, DRM_FORMAT_BGR888, &metadata, BO_USE_SW_MASK); diff --git a/virtio_gpu.c b/virtio_gpu.c index 0c94eaf..e3fd174 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -205,7 +205,7 @@ static int virtio_gpu_init(struct driver *drv) drv_add_combination(drv, DRM_FORMAT_BGR888, &LINEAR_METADATA, BO_USE_SW_MASK); drv_modify_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA, - BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER); drv_modify_combination(drv, DRM_FORMAT_R8, &LINEAR_METADATA, BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); From 298b7579139a5693096c00b794302df47f1bee6c Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Thu, 19 Sep 2019 09:55:18 -0700 Subject: [PATCH 149/269] minigbm: factor out metadata from struct bo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Generated using coccinelle: @@ struct bo *B; @@ - B->width + B->width BUG=chromium:924405 TEST=compile Change-Id: I4da1731a650d198ce7f2bda3031a47b2f9c3041c Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1815566 Reviewed-by: Stéphane Marchesin Tested-by: Gurchetan Singh Legacy-Commit-Queue: Commit Bot --- amdgpu.c | 8 +++--- dri.c | 21 +++++++------- drv.c | 80 ++++++++++++++++++++++++++-------------------------- drv_priv.h | 10 +++++-- exynos.c | 20 ++++++------- helpers.c | 31 ++++++++++---------- i915.c | 58 ++++++++++++++++++------------------- mediatek.c | 16 +++++------ msm.c | 46 +++++++++++++++--------------- rockchip.c | 30 ++++++++++---------- tegra.c | 38 ++++++++++++------------- vc4.c | 10 +++---- virtio_gpu.c | 14 ++++----- 13 files changed, 194 insertions(+), 188 deletions(-) diff --git a/amdgpu.c b/amdgpu.c index 65dd864..436b892 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -183,7 +183,7 @@ static int amdgpu_create_bo(struct bo *bo, uint32_t width, uint32_t height, uint drv_bo_from_format(bo, stride, height, format); memset(&gem_create, 0, sizeof(gem_create)); - gem_create.in.bo_size = bo->total_size; + gem_create.in.bo_size = bo->meta.total_size; gem_create.in.alignment = 256; gem_create.in.domain_flags = 0; @@ -200,7 +200,7 @@ static int amdgpu_create_bo(struct bo *bo, uint32_t width, uint32_t height, uint if (ret < 0) return ret; - for (plane = 0; plane < bo->num_planes; plane++) + for (plane = 0; plane < bo->meta.num_planes; plane++) bo->handles[plane].u32 = gem_create.out.handle; return 0; @@ -244,9 +244,9 @@ static void *amdgpu_map_bo(struct bo *bo, struct vma *vma, size_t plane, uint32_ return MAP_FAILED; } - vma->length = bo->total_size; + vma->length = bo->meta.total_size; - return mmap(0, bo->total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, + return mmap(0, bo->meta.total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, gem_map.out.addr_ptr); } diff --git a/dri.c b/dri.c index a9c1ed7..f61134b 100644 --- a/dri.c +++ b/dri.c @@ -193,7 +193,7 @@ int dri_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t forma int ret, dri_format, stride, offset; struct dri_driver *dri = bo->drv->priv; - assert(bo->num_planes == 1); + assert(bo->meta.num_planes == 1); dri_format = drm_format_to_dri_format(format); /* Gallium drivers require shared to get the handle and stride. */ @@ -226,10 +226,10 @@ int dri_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t forma goto close_handle; } - bo->strides[0] = stride; - bo->sizes[0] = stride * height; - bo->offsets[0] = offset; - bo->total_size = offset + bo->sizes[0]; + bo->meta.strides[0] = stride; + bo->meta.sizes[0] = stride * height; + bo->meta.offsets[0] = offset; + bo->meta.total_size = offset + bo->meta.sizes[0]; return 0; close_handle: @@ -244,11 +244,12 @@ int dri_bo_import(struct bo *bo, struct drv_import_fd_data *data) int ret; struct dri_driver *dri = bo->drv->priv; - assert(bo->num_planes == 1); + assert(bo->meta.num_planes == 1); // clang-format off bo->priv = dri->image_extension->createImageFromFds(dri->device, data->width, data->height, - data->format, data->fds, bo->num_planes, + data->format, data->fds, + bo->meta.num_planes, (int *)data->strides, (int *)data->offsets, NULL); // clang-format on @@ -289,9 +290,9 @@ void *dri_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flag struct dri_driver *dri = bo->drv->priv; /* GBM flags and DRI flags are the same. */ - vma->addr = - dri->image_extension->mapImage(dri->context, bo->priv, 0, 0, bo->width, bo->height, - map_flags, (int *)&vma->map_strides[plane], &vma->priv); + vma->addr = dri->image_extension->mapImage(dri->context, bo->priv, 0, 0, bo->meta.width, + bo->meta.height, map_flags, + (int *)&vma->map_strides[plane], &vma->priv); if (!vma->addr) return MAP_FAILED; diff --git a/drv.c b/drv.c index fa157ef..ef5cbc5 100644 --- a/drv.c +++ b/drv.c @@ -233,13 +233,13 @@ struct bo *drv_bo_new(struct driver *drv, uint32_t width, uint32_t height, uint3 return NULL; bo->drv = drv; - bo->width = width; - bo->height = height; - bo->format = format; - bo->use_flags = use_flags; - bo->num_planes = drv_num_planes_from_format(format); + bo->meta.width = width; + bo->meta.height = height; + bo->meta.format = format; + bo->meta.use_flags = use_flags; + bo->meta.num_planes = drv_num_planes_from_format(format); - if (!bo->num_planes) { + if (!bo->meta.num_planes) { free(bo); return NULL; } @@ -268,9 +268,9 @@ 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->meta.num_planes; plane++) { if (plane > 0) - assert(bo->offsets[plane] >= bo->offsets[plane - 1]); + assert(bo->meta.offsets[plane] >= bo->meta.offsets[plane - 1]); drv_increment_reference_count(drv, bo, plane); } @@ -306,9 +306,9 @@ 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->meta.num_planes; plane++) { if (plane > 0) - assert(bo->offsets[plane] >= bo->offsets[plane - 1]); + assert(bo->meta.offsets[plane] >= bo->meta.offsets[plane - 1]); drv_increment_reference_count(drv, bo, plane); } @@ -326,10 +326,10 @@ void drv_bo_destroy(struct bo *bo) pthread_mutex_lock(&drv->driver_lock); - for (plane = 0; plane < bo->num_planes; plane++) + for (plane = 0; plane < bo->meta.num_planes; plane++) drv_decrement_reference_count(drv, bo, plane); - for (plane = 0; plane < bo->num_planes; plane++) + for (plane = 0; plane < bo->meta.num_planes; plane++) total += drv_get_reference_count(drv, bo, plane); pthread_mutex_unlock(&drv->driver_lock); @@ -360,16 +360,16 @@ struct bo *drv_bo_import(struct driver *drv, struct drv_import_fd_data *data) return NULL; } - for (plane = 0; plane < bo->num_planes; plane++) { + for (plane = 0; plane < bo->meta.num_planes; plane++) { pthread_mutex_lock(&bo->drv->driver_lock); drv_increment_reference_count(bo->drv, bo, plane); pthread_mutex_unlock(&bo->drv->driver_lock); } - for (plane = 0; plane < bo->num_planes; plane++) { - bo->strides[plane] = data->strides[plane]; - bo->offsets[plane] = data->offsets[plane]; - bo->format_modifiers[plane] = data->format_modifiers[plane]; + for (plane = 0; plane < bo->meta.num_planes; plane++) { + bo->meta.strides[plane] = data->strides[plane]; + bo->meta.offsets[plane] = data->offsets[plane]; + bo->meta.format_modifiers[plane] = data->format_modifiers[plane]; seek_end = lseek(data->fds[plane], 0, SEEK_END); if (seek_end == (off_t)(-1)) { @@ -378,17 +378,17 @@ struct bo *drv_bo_import(struct driver *drv, struct drv_import_fd_data *data) } 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]; + if (plane == bo->meta.num_planes - 1 || data->offsets[plane + 1] == 0) + bo->meta.sizes[plane] = seek_end - data->offsets[plane]; else - bo->sizes[plane] = data->offsets[plane + 1] - data->offsets[plane]; + bo->meta.sizes[plane] = data->offsets[plane + 1] - data->offsets[plane]; - if ((int64_t)bo->offsets[plane] + bo->sizes[plane] > seek_end) { + if ((int64_t)bo->meta.offsets[plane] + bo->meta.sizes[plane] > seek_end) { drv_log("buffer size is too large.\n"); goto destroy_bo; } - bo->total_size += bo->sizes[plane]; + bo->meta.total_size += bo->meta.sizes[plane]; } return bo; @@ -411,7 +411,7 @@ void *drv_bo_map(struct bo *bo, const struct rectangle *rect, uint32_t map_flags 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(!(bo->meta.use_flags & BO_USE_PROTECTED)); memset(&mapping, 0, sizeof(mapping)); mapping.rect = *rect; @@ -446,7 +446,7 @@ void *drv_bo_map(struct bo *bo, const struct rectangle *rect, uint32_t map_flags } mapping.vma = calloc(1, sizeof(*mapping.vma)); - memcpy(mapping.vma->map_strides, bo->strides, sizeof(mapping.vma->map_strides)); + memcpy(mapping.vma->map_strides, bo->meta.strides, sizeof(mapping.vma->map_strides)); addr = bo->drv->backend->bo_map(bo, mapping.vma, plane, map_flags); if (addr == MAP_FAILED) { *map_data = NULL; @@ -520,7 +520,7 @@ int drv_bo_flush_or_unmap(struct bo *bo, struct mapping *mapping) assert(mapping->vma); assert(mapping->refcount > 0); assert(mapping->vma->refcount > 0); - assert(!(bo->use_flags & BO_USE_PROTECTED)); + assert(!(bo->meta.use_flags & BO_USE_PROTECTED)); if (bo->drv->backend->bo_flush) ret = bo->drv->backend->bo_flush(bo, mapping); @@ -532,22 +532,22 @@ int drv_bo_flush_or_unmap(struct bo *bo, struct mapping *mapping) uint32_t drv_bo_get_width(struct bo *bo) { - return bo->width; + return bo->meta.width; } uint32_t drv_bo_get_height(struct bo *bo) { - return bo->height; + return bo->meta.height; } uint32_t drv_bo_get_stride_or_tiling(struct bo *bo) { - return bo->tiling ? bo->tiling : drv_bo_get_plane_stride(bo, 0); + return bo->meta.tiling ? bo->meta.tiling : drv_bo_get_plane_stride(bo, 0); } size_t drv_bo_get_num_planes(struct bo *bo) { - return bo->num_planes; + return bo->meta.num_planes; } union bo_handle drv_bo_get_plane_handle(struct bo *bo, size_t plane) @@ -563,7 +563,7 @@ int drv_bo_get_plane_fd(struct bo *bo, size_t plane) { int ret, fd; - assert(plane < bo->num_planes); + assert(plane < bo->meta.num_planes); ret = drmPrimeHandleToFD(bo->drv->fd, bo->handles[plane].u32, DRM_CLOEXEC | DRM_RDWR, &fd); @@ -576,31 +576,31 @@ int drv_bo_get_plane_fd(struct bo *bo, size_t plane) uint32_t drv_bo_get_plane_offset(struct bo *bo, size_t plane) { - assert(plane < bo->num_planes); - return bo->offsets[plane]; + assert(plane < bo->meta.num_planes); + return bo->meta.offsets[plane]; } uint32_t drv_bo_get_plane_size(struct bo *bo, size_t plane) { - assert(plane < bo->num_planes); - return bo->sizes[plane]; + assert(plane < bo->meta.num_planes); + return bo->meta.sizes[plane]; } uint32_t drv_bo_get_plane_stride(struct bo *bo, size_t plane) { - assert(plane < bo->num_planes); - return bo->strides[plane]; + assert(plane < bo->meta.num_planes); + return bo->meta.strides[plane]; } uint64_t drv_bo_get_plane_format_modifier(struct bo *bo, size_t plane) { - assert(plane < bo->num_planes); - return bo->format_modifiers[plane]; + assert(plane < bo->meta.num_planes); + return bo->meta.format_modifiers[plane]; } uint32_t drv_bo_get_format(struct bo *bo) { - return bo->format; + return bo->meta.format; } uint32_t drv_resolve_format(struct driver *drv, uint32_t format, uint64_t use_flags) @@ -616,7 +616,7 @@ uint32_t drv_num_buffers_per_bo(struct bo *bo) uint32_t count = 0; size_t plane, p; - for (plane = 0; plane < bo->num_planes; plane++) { + for (plane = 0; plane < bo->meta.num_planes; plane++) { for (p = 0; p < plane; p++) if (bo->handles[p].u32 == bo->handles[plane].u32) break; diff --git a/drv_priv.h b/drv_priv.h index 46e6490..b497890 100644 --- a/drv_priv.h +++ b/drv_priv.h @@ -14,20 +14,24 @@ #include "drv.h" -struct bo { - struct driver *drv; +struct bo_metadata { uint32_t width; uint32_t height; uint32_t format; uint32_t tiling; size_t num_planes; - union bo_handle handles[DRV_MAX_PLANES]; uint32_t offsets[DRV_MAX_PLANES]; uint32_t sizes[DRV_MAX_PLANES]; uint32_t strides[DRV_MAX_PLANES]; uint64_t format_modifiers[DRV_MAX_PLANES]; uint64_t use_flags; size_t total_size; +}; + +struct bo { + struct driver *drv; + struct bo_metadata meta; + union bo_handle handles[DRV_MAX_PLANES]; void *priv; }; diff --git a/exynos.c b/exynos.c index b2b4040..6a80107 100644 --- a/exynos.c +++ b/exynos.c @@ -45,16 +45,16 @@ static int exynos_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint width = ALIGN(width, 16); height = ALIGN(height, 32); chroma_height = ALIGN(height / 2, 32); - bo->strides[0] = bo->strides[1] = width; + bo->meta.strides[0] = bo->meta.strides[1] = width; /* MFC v8+ requires 64 byte padding in the end of luma and chroma buffers. */ - bo->sizes[0] = bo->strides[0] * height + 64; - bo->sizes[1] = bo->strides[1] * chroma_height + 64; - bo->offsets[0] = bo->offsets[1] = 0; - bo->total_size = bo->sizes[0] + bo->sizes[1]; + bo->meta.sizes[0] = bo->meta.strides[0] * height + 64; + bo->meta.sizes[1] = bo->meta.strides[1] * chroma_height + 64; + bo->meta.offsets[0] = bo->meta.offsets[1] = 0; + bo->meta.total_size = bo->meta.sizes[0] + bo->meta.sizes[1]; } else if (format == DRM_FORMAT_XRGB8888 || format == DRM_FORMAT_ARGB8888) { - bo->strides[0] = drv_stride_from_format(format, width, 0); - bo->total_size = bo->sizes[0] = height * bo->strides[0]; - bo->offsets[0] = 0; + bo->meta.strides[0] = drv_stride_from_format(format, width, 0); + bo->meta.total_size = bo->meta.sizes[0] = height * bo->meta.strides[0]; + bo->meta.offsets[0] = 0; } else { drv_log("unsupported format %X\n", format); assert(0); @@ -62,8 +62,8 @@ static int exynos_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint } int ret; - for (plane = 0; plane < bo->num_planes; plane++) { - size_t size = bo->sizes[plane]; + for (plane = 0; plane < bo->meta.num_planes; plane++) { + size_t size = bo->meta.sizes[plane]; struct drm_exynos_gem_create gem_create; memset(&gem_create, 0, sizeof(gem_create)); diff --git a/helpers.c b/helpers.c index 229d6be..c7396a4 100644 --- a/helpers.c +++ b/helpers.c @@ -255,18 +255,19 @@ int drv_bo_from_format(struct bo *bo, uint32_t stride, uint32_t aligned_height, * is 32 bytes aligned. */ if (format == DRM_FORMAT_YVU420_ANDROID) { - assert(aligned_height == bo->height); + assert(aligned_height == bo->meta.height); assert(stride == ALIGN(stride, 32)); } for (p = 0; p < num_planes; p++) { - bo->strides[p] = subsample_stride(stride, format, p); - bo->sizes[p] = drv_size_from_format(format, bo->strides[p], aligned_height, p); - bo->offsets[p] = offset; - offset += bo->sizes[p]; + bo->meta.strides[p] = subsample_stride(stride, format, p); + bo->meta.sizes[p] = + drv_size_from_format(format, bo->meta.strides[p], aligned_height, p); + bo->meta.offsets[p] = offset; + offset += bo->meta.sizes[p]; } - bo->total_size = offset; + bo->meta.total_size = offset; return 0; } @@ -289,7 +290,7 @@ int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t * * HAL_PIXEL_FORMAT_YV12 requires that the buffer's height not * be aligned. */ - aligned_height = 3 * DIV_ROUND_UP(bo->height, 2); + aligned_height = 3 * DIV_ROUND_UP(bo->meta.height, 2); break; case DRM_FORMAT_YVU420: case DRM_FORMAT_NV12: @@ -314,10 +315,10 @@ int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t drv_bo_from_format(bo, create_dumb.pitch, height, format); - for (plane = 0; plane < bo->num_planes; plane++) + for (plane = 0; plane < bo->meta.num_planes; plane++) bo->handles[plane].u32 = create_dumb.handle; - bo->total_size = create_dumb.size; + bo->meta.total_size = create_dumb.size; return 0; } @@ -344,7 +345,7 @@ int drv_gem_bo_destroy(struct bo *bo) int ret, error = 0; size_t plane, i; - for (plane = 0; plane < bo->num_planes; plane++) { + for (plane = 0; plane < bo->meta.num_planes; plane++) { for (i = 0; i < plane; i++) if (bo->handles[i].u32 == bo->handles[plane].u32) break; @@ -372,7 +373,7 @@ int drv_prime_bo_import(struct bo *bo, struct drv_import_fd_data *data) size_t plane; struct drm_prime_handle prime_handle; - for (plane = 0; plane < bo->num_planes; plane++) { + for (plane = 0; plane < bo->meta.num_planes; plane++) { memset(&prime_handle, 0, sizeof(prime_handle)); prime_handle.fd = data->fds[plane]; @@ -387,7 +388,7 @@ int drv_prime_bo_import(struct bo *bo, struct drv_import_fd_data *data) * plane that failed, so GEM close will be called on * planes before that plane. */ - bo->num_planes = plane; + bo->meta.num_planes = plane; drv_gem_bo_destroy(bo); return -errno; } @@ -413,9 +414,9 @@ void *drv_dumb_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map return MAP_FAILED; } - for (i = 0; i < bo->num_planes; i++) + for (i = 0; i < bo->meta.num_planes; i++) if (bo->handles[i].u32 == bo->handles[plane].u32) - vma->length += bo->sizes[i]; + vma->length += bo->meta.sizes[i]; return mmap(0, vma->length, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, map_dumb.offset); @@ -439,7 +440,7 @@ int drv_mapping_destroy(struct bo *bo) */ idx = 0; - for (plane = 0; plane < bo->num_planes; plane++) { + for (plane = 0; plane < bo->meta.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) { diff --git a/i915.c b/i915.c index ff5c66d..1a51aa4 100644 --- a/i915.c +++ b/i915.c @@ -24,10 +24,10 @@ #define I915_CACHELINE_MASK (I915_CACHELINE_SIZE - 1) static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR16161616F, DRM_FORMAT_ABGR2101010, - DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB1555, + DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB1555, DRM_FORMAT_ARGB2101010, DRM_FORMAT_ARGB8888, - DRM_FORMAT_RGB565, DRM_FORMAT_XBGR2101010, - DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB1555, + 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_R8, @@ -256,7 +256,7 @@ static int i915_align_dimensions(struct bo *bo, uint32_t tiling, uint32_t *strid break; } - *aligned_height = ALIGN(bo->height, vertical_alignment); + *aligned_height = ALIGN(bo->meta.height, vertical_alignment); if (i915->gen > 3) { *stride = ALIGN(*stride, horizontal_alignment); } else { @@ -334,20 +334,20 @@ static int i915_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, u uint32_t stride = drv_stride_from_format(format, width, plane); uint32_t plane_height = drv_height_from_format(format, height, plane); - if (bo->tiling != I915_TILING_NONE) + if (bo->meta.tiling != I915_TILING_NONE) assert(IS_ALIGNED(offset, pagesize)); - ret = i915_align_dimensions(bo, bo->tiling, &stride, &plane_height); + ret = i915_align_dimensions(bo, bo->meta.tiling, &stride, &plane_height); if (ret) return ret; - bo->strides[plane] = stride; - bo->sizes[plane] = stride * plane_height; - bo->offsets[plane] = offset; - offset += bo->sizes[plane]; + bo->meta.strides[plane] = stride; + bo->meta.sizes[plane] = stride * plane_height; + bo->meta.offsets[plane] = offset; + offset += bo->meta.sizes[plane]; } - bo->total_size = ALIGN(offset, pagesize); + bo->meta.total_size = ALIGN(offset, pagesize); return 0; } @@ -362,17 +362,17 @@ static int i915_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t h switch (modifier) { case DRM_FORMAT_MOD_LINEAR: - bo->tiling = I915_TILING_NONE; + bo->meta.tiling = I915_TILING_NONE; break; case I915_FORMAT_MOD_X_TILED: - bo->tiling = I915_TILING_X; + bo->meta.tiling = I915_TILING_X; break; case I915_FORMAT_MOD_Y_TILED: - bo->tiling = I915_TILING_Y; + bo->meta.tiling = I915_TILING_Y; break; } - bo->format_modifiers[0] = modifier; + bo->meta.format_modifiers[0] = modifier; if (format == DRM_FORMAT_YVU420_ANDROID) { /* @@ -390,7 +390,7 @@ static int i915_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t h } memset(&gem_create, 0, sizeof(gem_create)); - gem_create.size = bo->total_size; + gem_create.size = bo->meta.total_size; ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_CREATE, &gem_create); if (ret) { @@ -398,13 +398,13 @@ static int i915_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t h return -errno; } - for (plane = 0; plane < bo->num_planes; plane++) + for (plane = 0; plane < bo->meta.num_planes; plane++) bo->handles[plane].u32 = gem_create.handle; memset(&gem_set_tiling, 0, sizeof(gem_set_tiling)); gem_set_tiling.handle = bo->handles[0].u32; - gem_set_tiling.tiling_mode = bo->tiling; - gem_set_tiling.stride = bo->strides[0]; + gem_set_tiling.tiling_mode = bo->meta.tiling; + gem_set_tiling.stride = bo->meta.strides[0]; ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_SET_TILING, &gem_set_tiling); if (ret) { @@ -473,7 +473,7 @@ static int i915_bo_import(struct bo *bo, struct drv_import_fd_data *data) return ret; } - bo->tiling = gem_get_tiling.tiling_mode; + bo->meta.tiling = gem_get_tiling.tiling_mode; return 0; } @@ -482,7 +482,7 @@ static void *i915_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t int ret; void *addr; - if (bo->tiling == I915_TILING_NONE) { + if (bo->meta.tiling == I915_TILING_NONE) { struct drm_i915_gem_mmap gem_map; memset(&gem_map, 0, sizeof(gem_map)); @@ -494,14 +494,14 @@ static void *i915_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t * For now, care must be taken not to use WC mappings for * Renderscript and camera use cases, as they're * performance-sensitive. */ - if ((bo->use_flags & BO_USE_SCANOUT) && - !(bo->use_flags & + if ((bo->meta.use_flags & BO_USE_SCANOUT) && + !(bo->meta.use_flags & (BO_USE_RENDERSCRIPT | BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE))) gem_map.flags = I915_MMAP_WC; gem_map.handle = bo->handles[0].u32; gem_map.offset = 0; - gem_map.size = bo->total_size; + gem_map.size = bo->meta.total_size; ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_MMAP, &gem_map); if (ret) { @@ -522,8 +522,8 @@ static void *i915_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t return MAP_FAILED; } - addr = mmap(0, bo->total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, - gem_map.offset); + addr = mmap(0, bo->meta.total_size, drv_get_prot(map_flags), MAP_SHARED, + bo->drv->fd, gem_map.offset); } if (addr == MAP_FAILED) { @@ -531,7 +531,7 @@ static void *i915_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t return addr; } - vma->length = bo->total_size; + vma->length = bo->meta.total_size; return addr; } @@ -542,7 +542,7 @@ static int i915_bo_invalidate(struct bo *bo, struct mapping *mapping) memset(&set_domain, 0, sizeof(set_domain)); set_domain.handle = bo->handles[0].u32; - if (bo->tiling == I915_TILING_NONE) { + if (bo->meta.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; @@ -564,7 +564,7 @@ static int i915_bo_invalidate(struct bo *bo, struct mapping *mapping) 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) + if (!i915->has_llc && bo->meta.tiling == I915_TILING_NONE) i915_clflush(mapping->vma->addr, mapping->vma->length); return 0; diff --git a/mediatek.c b/mediatek.c index 7282437..6319570 100644 --- a/mediatek.c +++ b/mediatek.c @@ -114,7 +114,7 @@ static int mediatek_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint drv_bo_from_format(bo, stride, height, format); memset(&gem_create, 0, sizeof(gem_create)); - gem_create.size = bo->total_size; + gem_create.size = bo->meta.total_size; ret = drmIoctl(bo->drv->fd, DRM_IOCTL_MTK_GEM_CREATE, &gem_create); if (ret) { @@ -122,7 +122,7 @@ static int mediatek_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint return -errno; } - for (plane = 0; plane < bo->num_planes; plane++) + for (plane = 0; plane < bo->meta.num_planes; plane++) bo->handles[plane].u32 = gem_create.handle; return 0; @@ -157,17 +157,17 @@ static void *mediatek_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint3 return MAP_FAILED; } - void *addr = mmap(0, bo->total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, + void *addr = mmap(0, bo->meta.total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, gem_map.offset); - vma->length = bo->total_size; + vma->length = bo->meta.total_size; priv = calloc(1, sizeof(*priv)); priv->prime_fd = prime_fd; vma->priv = priv; - if (bo->use_flags & BO_USE_RENDERSCRIPT) { - priv->cached_addr = calloc(1, bo->total_size); + if (bo->meta.use_flags & BO_USE_RENDERSCRIPT) { + priv->cached_addr = calloc(1, bo->meta.total_size); priv->gem_addr = addr; addr = priv->cached_addr; } @@ -213,7 +213,7 @@ static int mediatek_bo_invalidate(struct bo *bo, struct mapping *mapping) drv_log("poll prime_fd failed\n"); if (priv->cached_addr) - memcpy(priv->cached_addr, priv->gem_addr, bo->total_size); + memcpy(priv->cached_addr, priv->gem_addr, bo->meta.total_size); } return 0; @@ -223,7 +223,7 @@ static int mediatek_bo_flush(struct bo *bo, struct mapping *mapping) { struct mediatek_private_map_data *priv = mapping->vma->priv; if (priv && priv->cached_addr && (mapping->vma->map_flags & BO_MAP_WRITE)) - memcpy(priv->gem_addr, priv->cached_addr, bo->total_size); + memcpy(priv->gem_addr, priv->cached_addr, bo->meta.total_size); return 0; } diff --git a/msm.c b/msm.c index a8df000..175d90f 100644 --- a/msm.c +++ b/msm.c @@ -69,13 +69,13 @@ static void msm_calculate_layout(struct bo *bo) { uint32_t width, height; - width = bo->width; - height = bo->height; + width = bo->meta.width; + height = bo->meta.height; /* NV12 format requires extra padding with platform * specific alignments for venus driver */ - if (bo->format == DRM_FORMAT_NV12) { + if (bo->meta.format == DRM_FORMAT_NV12) { uint32_t y_stride, uv_stride, y_scanline, uv_scanline, y_plane, uv_plane, size, extra_padding; @@ -86,7 +86,7 @@ static void msm_calculate_layout(struct bo *bo) y_plane = y_stride * y_scanline; uv_plane = uv_stride * uv_scanline; - if (bo->tiling == MSM_UBWC_TILING) { + if (bo->meta.tiling == MSM_UBWC_TILING) { y_plane += get_ubwc_meta_size(width, height, 32, 8); uv_plane += get_ubwc_meta_size(width >> 1, height >> 1, 16, 8); extra_padding = NV12_UBWC_PADDING(y_stride); @@ -94,34 +94,34 @@ static void msm_calculate_layout(struct bo *bo) extra_padding = NV12_LINEAR_PADDING; } - bo->strides[0] = y_stride; - bo->sizes[0] = y_plane; - bo->offsets[1] = y_plane; - bo->strides[1] = uv_stride; + bo->meta.strides[0] = y_stride; + bo->meta.sizes[0] = y_plane; + bo->meta.offsets[1] = y_plane; + bo->meta.strides[1] = uv_stride; size = y_plane + uv_plane + extra_padding; - bo->total_size = ALIGN(size, BUFFER_SIZE_ALIGN); - bo->sizes[1] = bo->total_size - bo->sizes[0]; + bo->meta.total_size = ALIGN(size, BUFFER_SIZE_ALIGN); + bo->meta.sizes[1] = bo->meta.total_size - bo->meta.sizes[0]; } else { uint32_t stride, alignw, alignh; alignw = ALIGN(width, DEFAULT_ALIGNMENT); /* HAL_PIXEL_FORMAT_YV12 requires that the buffer's height not be aligned. */ - if (bo->format == DRM_FORMAT_YVU420_ANDROID) { + if (bo->meta.format == DRM_FORMAT_YVU420_ANDROID) { alignh = height; } else { alignh = ALIGN(height, DEFAULT_ALIGNMENT); } - stride = drv_stride_from_format(bo->format, alignw, 0); + stride = drv_stride_from_format(bo->meta.format, alignw, 0); /* Calculate size and assign stride, size, offset to each plane based on format */ - drv_bo_from_format(bo, stride, alignh, bo->format); + drv_bo_from_format(bo, stride, alignh, bo->meta.format); /* For all RGB UBWC formats */ - if (bo->tiling == MSM_UBWC_TILING) { - bo->sizes[0] += get_ubwc_meta_size(width, height, 16, 4); - bo->total_size = bo->sizes[0]; - assert(IS_ALIGNED(bo->total_size, BUFFER_SIZE_ALIGN)); + if (bo->meta.tiling == MSM_UBWC_TILING) { + bo->meta.sizes[0] += get_ubwc_meta_size(width, height, 16, 4); + bo->meta.total_size = bo->meta.sizes[0]; + assert(IS_ALIGNED(bo->meta.total_size, BUFFER_SIZE_ALIGN)); } } } @@ -201,13 +201,13 @@ static int msm_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t he int ret; size_t i; - bo->tiling = (modifier == DRM_FORMAT_MOD_QCOM_COMPRESSED) ? MSM_UBWC_TILING : 0; + bo->meta.tiling = (modifier == DRM_FORMAT_MOD_QCOM_COMPRESSED) ? MSM_UBWC_TILING : 0; msm_calculate_layout(bo); memset(&req, 0, sizeof(req)); req.flags = MSM_BO_WC | MSM_BO_SCANOUT; - req.size = bo->total_size; + req.size = bo->meta.total_size; ret = drmIoctl(bo->drv->fd, DRM_IOCTL_MSM_GEM_NEW, &req); if (ret) { @@ -219,9 +219,9 @@ static int msm_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t he * Though we use only one plane, we need to set handle for * all planes to pass kernel checks */ - for (i = 0; i < bo->num_planes; i++) { + for (i = 0; i < bo->meta.num_planes; i++) { bo->handles[i].u32 = req.handle; - bo->format_modifiers[i] = modifier; + bo->meta.format_modifiers[i] = modifier; } return 0; @@ -268,9 +268,9 @@ static void *msm_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t m drv_log("DRM_IOCLT_MSM_GEM_INFO failed with %s\n", strerror(errno)); return MAP_FAILED; } - vma->length = bo->total_size; + vma->length = bo->meta.total_size; - return mmap(0, bo->total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, + return mmap(0, bo->meta.total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, req.offset); } diff --git a/rockchip.c b/rockchip.c index 9d1cf44..ed8a7ae 100644 --- a/rockchip.c +++ b/rockchip.c @@ -63,13 +63,13 @@ static int afbc_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, u const uint32_t body_plane_offset = ALIGN(header_plane_size, body_plane_alignment); const uint32_t total_size = body_plane_offset + body_plane_size; - bo->strides[0] = width_in_blocks * block_width * pixel_size; - bo->sizes[0] = total_size; - bo->offsets[0] = 0; + bo->meta.strides[0] = width_in_blocks * block_width * pixel_size; + bo->meta.sizes[0] = total_size; + bo->meta.offsets[0] = 0; - bo->total_size = total_size; + bo->meta.total_size = total_size; - bo->format_modifiers[0] = DRM_FORMAT_MOD_CHROMEOS_ROCKCHIP_AFBC; + bo->meta.format_modifiers[0] = DRM_FORMAT_MOD_CHROMEOS_ROCKCHIP_AFBC; return 0; } @@ -180,7 +180,7 @@ static int rockchip_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint * drv_bo_from_format updates total_size. Add an extra data space for rockchip video * driver to store motion vectors. */ - bo->total_size += w_mbs * h_mbs * 128; + bo->meta.total_size += w_mbs * h_mbs * 128; } else if (width <= 2560 && drv_has_modifier(modifiers, count, DRM_FORMAT_MOD_CHROMEOS_ROCKCHIP_AFBC)) { /* If the caller has decided they can use AFBC, always @@ -210,7 +210,7 @@ static int rockchip_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint } memset(&gem_create, 0, sizeof(gem_create)); - gem_create.size = bo->total_size; + gem_create.size = bo->meta.total_size; ret = drmIoctl(bo->drv->fd, DRM_IOCTL_ROCKCHIP_GEM_CREATE, &gem_create); @@ -220,7 +220,7 @@ static int rockchip_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint return -errno; } - for (plane = 0; plane < bo->num_planes; plane++) + for (plane = 0; plane < bo->meta.num_planes; plane++) bo->handles[plane].u32 = gem_create.handle; return 0; @@ -242,7 +242,7 @@ static void *rockchip_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint3 /* We can only map buffers created with SW access flags, which should * have no modifiers (ie, not AFBC). */ - if (bo->format_modifiers[0] == DRM_FORMAT_MOD_CHROMEOS_ROCKCHIP_AFBC) + if (bo->meta.format_modifiers[0] == DRM_FORMAT_MOD_CHROMEOS_ROCKCHIP_AFBC) return MAP_FAILED; memset(&gem_map, 0, sizeof(gem_map)); @@ -254,14 +254,14 @@ static void *rockchip_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint3 return MAP_FAILED; } - void *addr = mmap(0, bo->total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, + void *addr = mmap(0, bo->meta.total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, gem_map.offset); - vma->length = bo->total_size; + vma->length = bo->meta.total_size; - if (bo->use_flags & BO_USE_RENDERSCRIPT) { + if (bo->meta.use_flags & BO_USE_RENDERSCRIPT) { priv = calloc(1, sizeof(*priv)); - priv->cached_addr = calloc(1, bo->total_size); + priv->cached_addr = calloc(1, bo->meta.total_size); priv->gem_addr = addr; vma->priv = priv; addr = priv->cached_addr; @@ -287,7 +287,7 @@ 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); + memcpy(priv->cached_addr, priv->gem_addr, bo->meta.total_size); } return 0; @@ -297,7 +297,7 @@ 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); + memcpy(priv->gem_addr, priv->cached_addr, bo->meta.total_size); return 0; } diff --git a/tegra.c b/tegra.c index 4b6b8d7..df97461 100644 --- a/tegra.c +++ b/tegra.c @@ -119,12 +119,12 @@ static void transfer_tile(struct bo *bo, uint8_t *tiled, uint8_t *untiled, enum if (tiled >= tiled_last) return; - if (x >= bo->width || y >= bo->height) { + if (x >= bo->meta.width || y >= bo->meta.height) { tiled += bytes_per_pixel; continue; } - tmp = untiled + y * bo->strides[0] + x * bytes_per_pixel; + tmp = untiled + y * bo->meta.strides[0] + x * bytes_per_pixel; if (type == TEGRA_READ_TILED_BUFFER) memcpy(tmp, tiled, bytes_per_pixel); @@ -143,7 +143,7 @@ static void transfer_tiled_memory(struct bo *bo, uint8_t *tiled, uint8_t *untile gob_top, gob_left; uint32_t i, j, offset; uint8_t *tmp, *tiled_last; - uint32_t bytes_per_pixel = drv_stride_from_format(bo->format, 1, 0); + uint32_t bytes_per_pixel = drv_stride_from_format(bo->meta.format, 1, 0); /* * The blocklinear format consists of 8*(2^n) x 64 byte sized tiles, @@ -152,16 +152,16 @@ static void transfer_tiled_memory(struct bo *bo, uint8_t *tiled, uint8_t *untile gob_width = DIV_ROUND_UP(NV_BLOCKLINEAR_GOB_WIDTH, bytes_per_pixel); gob_height = NV_BLOCKLINEAR_GOB_HEIGHT * (1 << NV_DEFAULT_BLOCK_HEIGHT_LOG2); /* Calculate the height from maximum possible gob height */ - while (gob_height > NV_BLOCKLINEAR_GOB_HEIGHT && gob_height >= 2 * bo->height) + while (gob_height > NV_BLOCKLINEAR_GOB_HEIGHT && gob_height >= 2 * bo->meta.height) gob_height /= 2; gob_size_bytes = gob_height * NV_BLOCKLINEAR_GOB_WIDTH; gob_size_pixels = gob_height * gob_width; - gob_count_x = DIV_ROUND_UP(bo->strides[0], NV_BLOCKLINEAR_GOB_WIDTH); - gob_count_y = DIV_ROUND_UP(bo->height, gob_height); + gob_count_x = DIV_ROUND_UP(bo->meta.strides[0], NV_BLOCKLINEAR_GOB_WIDTH); + gob_count_y = DIV_ROUND_UP(bo->meta.height, gob_height); - tiled_last = tiled + bo->total_size; + tiled_last = tiled + bo->meta.total_size; offset = 0; for (j = 0; j < gob_count_y; j++) { @@ -234,9 +234,9 @@ static int tegra_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint3 } bo->handles[0].u32 = gem_create.handle; - bo->offsets[0] = 0; - bo->total_size = bo->sizes[0] = size; - bo->strides[0] = stride; + bo->meta.offsets[0] = 0; + bo->meta.total_size = bo->meta.sizes[0] = size; + bo->meta.strides[0] = stride; if (kind != NV_MEM_KIND_PITCH) { struct drm_tegra_gem_set_tiling gem_tile; @@ -254,8 +254,8 @@ static int tegra_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint3 } /* Encode blocklinear parameters for EGLImage creation. */ - bo->tiling = (kind & 0xff) | ((block_height_log2 & 0xf) << 8); - bo->format_modifiers[0] = fourcc_mod_code(NV, bo->tiling); + bo->meta.tiling = (kind & 0xff) | ((block_height_log2 & 0xf) << 8); + bo->meta.format_modifiers[0] = fourcc_mod_code(NV, bo->meta.tiling); } return 0; @@ -283,16 +283,16 @@ static int tegra_bo_import(struct bo *bo, struct drv_import_fd_data *data) /* 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; + bo->meta.tiling = NV_MEM_KIND_PITCH; } else if (gem_get_tiling.mode == DRM_TEGRA_GEM_TILING_MODE_BLOCK) { - bo->tiling = NV_MEM_KIND_C32_2CRA; + bo->meta.tiling = NV_MEM_KIND_C32_2CRA; } else { drv_log("%s: unknown tile format %d\n", __func__, gem_get_tiling.mode); drv_gem_bo_destroy(bo); assert(0); } - bo->format_modifiers[0] = fourcc_mod_code(NV, bo->tiling); + bo->meta.format_modifiers[0] = fourcc_mod_code(NV, bo->meta.tiling); return 0; } @@ -311,12 +311,12 @@ static void *tegra_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t return MAP_FAILED; } - void *addr = mmap(0, bo->total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, + void *addr = mmap(0, bo->meta.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) { + vma->length = bo->meta.total_size; + if ((bo->meta.tiling & 0xFF) == NV_MEM_KIND_C32_2CRA && addr != MAP_FAILED) { priv = calloc(1, sizeof(*priv)); - priv->untiled = calloc(1, bo->total_size); + priv->untiled = calloc(1, bo->meta.total_size); priv->tiled = addr; vma->priv = priv; transfer_tiled_memory(bo, priv->tiled, priv->untiled, TEGRA_READ_TILED_BUFFER); diff --git a/vc4.c b/vc4.c index 6edd967..7af16c2 100644 --- a/vc4.c +++ b/vc4.c @@ -45,15 +45,15 @@ static int vc4_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_ drv_bo_from_format(bo, stride, height, format); memset(&bo_create, 0, sizeof(bo_create)); - bo_create.size = bo->total_size; + bo_create.size = bo->meta.total_size; ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VC4_CREATE_BO, &bo_create); if (ret) { - drv_log("DRM_IOCTL_VC4_GEM_CREATE failed (size=%zu)\n", bo->total_size); + drv_log("DRM_IOCTL_VC4_GEM_CREATE failed (size=%zu)\n", bo->meta.total_size); return -errno; } - for (plane = 0; plane < bo->num_planes; plane++) + for (plane = 0; plane < bo->meta.num_planes; plane++) bo->handles[plane].u32 = bo_create.handle; return 0; @@ -73,8 +73,8 @@ static void *vc4_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t m return MAP_FAILED; } - vma->length = bo->total_size; - return mmap(NULL, bo->total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, + vma->length = bo->meta.total_size; + return mmap(NULL, bo->meta.total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, bo_map.offset); } diff --git a/virtio_gpu.c b/virtio_gpu.c index e3fd174..3570a5f 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -69,7 +69,7 @@ static uint32_t translate_format(uint32_t drm_fourcc) static int virtio_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, uint64_t use_flags) { - if (bo->format != DRM_FORMAT_R8) { + if (bo->meta.format != DRM_FORMAT_R8) { width = ALIGN(width, MESA_LLVMPIPE_TILE_SIZE); height = ALIGN(height, MESA_LLVMPIPE_TILE_SIZE); } @@ -133,14 +133,14 @@ static int virtio_virgl_bo_create(struct bo *bo, uint32_t width, uint32_t height res_create.last_level = 0; res_create.nr_samples = 0; - res_create.size = ALIGN(bo->total_size, PAGE_SIZE); // PAGE_SIZE = 0x1000 + res_create.size = ALIGN(bo->meta.total_size, PAGE_SIZE); // PAGE_SIZE = 0x1000 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_RESOURCE_CREATE, &res_create); if (ret) { drv_log("DRM_IOCTL_VIRTGPU_RESOURCE_CREATE failed with %s\n", strerror(errno)); return ret; } - for (uint32_t plane = 0; plane < bo->num_planes; plane++) + for (uint32_t plane = 0; plane < bo->meta.num_planes; plane++) bo->handles[plane].u32 = res_create.bo_handle; return 0; @@ -160,8 +160,8 @@ static void *virtio_virgl_bo_map(struct bo *bo, struct vma *vma, size_t plane, u return MAP_FAILED; } - vma->length = bo->total_size; - return mmap(0, bo->total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, + vma->length = bo->meta.total_size; + return mmap(0, bo->meta.total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd, gem_map.offset); } @@ -266,7 +266,7 @@ static int virtio_gpu_bo_invalidate(struct bo *bo, struct mapping *mapping) // Unfortunately, the kernel doesn't actually pass the guest layer_stride and // guest stride to the host (compare virtio_gpu.h and virtgpu_drm.h). We can use // the level to work around this. - xfer.level = bo->strides[0]; + xfer.level = bo->meta.strides[0]; ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST, &xfer); if (ret) { @@ -300,7 +300,7 @@ static int virtio_gpu_bo_flush(struct bo *bo, struct mapping *mapping) // Unfortunately, the kernel doesn't actually pass the guest layer_stride and // guest stride to the host (compare virtio_gpu.h and virtgpu_drm.h). We can use // the level to work around this. - xfer.level = bo->strides[0]; + xfer.level = bo->meta.strides[0]; ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_TRANSFER_TO_HOST, &xfer); if (ret) { From 48b4c086ab660c4b6e94cffe5b93248c59a641b8 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Fri, 13 Sep 2019 18:36:52 -0700 Subject: [PATCH 150/269] minigbm: fix flags to align with GBM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For virtio, we can just forward use flags to host gbm. For that to work, these flags must be aligned. BUG=chromium:924405 TEST=compile Change-Id: I64c03b4a374296a59749dccf65ab9ebeb59fc762 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1804827 Reviewed-by: Stéphane Marchesin Tested-by: Gurchetan Singh Legacy-Commit-Queue: Commit Bot --- drv.h | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/drv.h b/drv.h index d3cf9d3..0cb062d 100644 --- a/drv.h +++ b/drv.h @@ -23,21 +23,19 @@ extern "C" { #define BO_USE_CURSOR (1ull << 1) #define BO_USE_CURSOR_64X64 BO_USE_CURSOR #define BO_USE_RENDERING (1ull << 2) -#define BO_USE_LINEAR (1ull << 3) -#define BO_USE_SW_READ_NEVER (1ull << 4) -#define BO_USE_SW_READ_RARELY (1ull << 5) -#define BO_USE_SW_READ_OFTEN (1ull << 6) -#define BO_USE_SW_WRITE_NEVER (1ull << 7) -#define BO_USE_SW_WRITE_RARELY (1ull << 8) -#define BO_USE_SW_WRITE_OFTEN (1ull << 9) -#define BO_USE_EXTERNAL_DISP (1ull << 10) -#define BO_USE_PROTECTED (1ull << 11) -#define BO_USE_HW_VIDEO_ENCODER (1ull << 12) -#define BO_USE_CAMERA_WRITE (1ull << 13) -#define BO_USE_CAMERA_READ (1ull << 14) -#define BO_USE_RENDERSCRIPT (1ull << 16) -#define BO_USE_TEXTURE (1ull << 17) -#define BO_USE_HW_VIDEO_DECODER (1ull << 18) +/* Skip for GBM_BO_USE_WRITE */ +#define BO_USE_LINEAR (1ull << 4) +#define BO_USE_TEXTURE (1ull << 5) +#define BO_USE_CAMERA_WRITE (1ull << 6) +#define BO_USE_CAMERA_READ (1ull << 7) +#define BO_USE_PROTECTED (1ull << 8) +#define BO_USE_SW_READ_OFTEN (1ull << 9) +#define BO_USE_SW_READ_RARELY (1ull << 10) +#define BO_USE_SW_WRITE_OFTEN (1ull << 11) +#define BO_USE_SW_WRITE_RARELY (1ull << 12) +#define BO_USE_HW_VIDEO_ENCODER (1ull << 13) +#define BO_USE_HW_VIDEO_DECODER (1ull << 14) +#define BO_USE_RENDERSCRIPT (1ull << 15) /* Map flags */ From 356747071d3770d4d0b35011b0bd496ceb46f1c9 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Tue, 24 Sep 2019 10:18:59 -0700 Subject: [PATCH 151/269] minigbm: modify OWNERS Having more reviewers is always nice. BUG=none TEST=none Change-Id: I6990e248f0c1a2c4b9c791110dbf32585e296507 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1821691 Reviewed-by: Gurchetan Singh Commit-Queue: Gurchetan Singh Tested-by: Gurchetan Singh --- OWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/OWNERS b/OWNERS index a6feb04..3c1e063 100644 --- a/OWNERS +++ b/OWNERS @@ -6,3 +6,4 @@ ddavenport@chromium.org dbehr@chromium.org dcastagna@chromium.org lepton@chromium.org +tutankhamen@chromium.org From 86e72a439a0da42108ff66e4aa6ad9578cf85fbd Mon Sep 17 00:00:00 2001 From: Ricky Liang Date: Tue, 24 Sep 2019 13:15:55 +0800 Subject: [PATCH 152/269] mediatek: Fix the metadata for R8 The R8 format should be configured with LINEAR_METADATA. BUG=b:141328294 TEST=manually on Kukui Change-Id: I612e78d28b63960428a6dce04104c3266b124a23 Reviewed-on: https://chromium-review.googlesource.com/1816204 Tested-by: Ricky Liang Commit-Ready: Ricky Liang Legacy-Commit-Queue: Commit Bot Reviewed-by: Tomasz Figa --- mediatek.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediatek.c b/mediatek.c index 6319570..270d810 100644 --- a/mediatek.c +++ b/mediatek.c @@ -54,7 +54,7 @@ static int mediatek_init(struct driver *drv) drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), &LINEAR_METADATA, BO_USE_TEXTURE_MASK); - drv_add_combination(drv, DRM_FORMAT_R8, &metadata, BO_USE_SW_MASK | BO_USE_LINEAR); + drv_add_combination(drv, DRM_FORMAT_R8, &LINEAR_METADATA, BO_USE_SW_MASK | BO_USE_LINEAR); /* * Chrome uses DMA-buf mmap to write to YV12 buffers, which are then accessed by the * Video Encoder Accelerator (VEA). It could also support NV12 potentially in the future. From 55a6cf9faa0030641e480b7c94bfe26c3a0e9169 Mon Sep 17 00:00:00 2001 From: David Stevens Date: Tue, 3 Sep 2019 10:45:33 +0900 Subject: [PATCH 153/269] minigbm: virtio-gpu: pass more bind flags Change-Id: I771b5e7ce8e028477570bff8bc7eee6822aaf22b Reviewed-on: https://chromium-review.googlesource.com/1786418 Tested-by: David Stevens Commit-Ready: David Stevens Legacy-Commit-Queue: Commit Bot Reviewed-by: Gurchetan Singh --- virgl_hw.h | 2 ++ virtio_gpu.c | 14 +++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/virgl_hw.h b/virgl_hw.h index 94e1d5e..8c169a7 100644 --- a/virgl_hw.h +++ b/virgl_hw.h @@ -288,6 +288,8 @@ enum virgl_formats { #define VIRGL_BIND_PREFER_EMULATED_BGRA (1 << 21) +#define VIRGL_BIND_LINEAR (1 << 22) + struct virgl_caps_bool_set1 { unsigned indep_blend_enable:1; unsigned indep_blend_func:1; diff --git a/virtio_gpu.c b/virtio_gpu.c index 3570a5f..9e5b0ba 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -94,7 +94,19 @@ static uint32_t use_flags_to_bind(uint64_t use_flags) handle_flag(&use_flags, BO_USE_TEXTURE, &bind, VIRGL_BIND_SAMPLER_VIEW); handle_flag(&use_flags, BO_USE_RENDERING, &bind, VIRGL_BIND_RENDER_TARGET); handle_flag(&use_flags, BO_USE_SCANOUT, &bind, VIRGL_BIND_SCANOUT); - // TODO (b/12983436): handle other use flags. + handle_flag(&use_flags, BO_USE_CURSOR, &bind, VIRGL_BIND_CURSOR); + handle_flag(&use_flags, BO_USE_LINEAR, &bind, VIRGL_BIND_LINEAR); + + handle_flag(&use_flags, BO_USE_SW_READ_OFTEN, &bind, VIRGL_BIND_LINEAR); + handle_flag(&use_flags, BO_USE_SW_READ_RARELY, &bind, VIRGL_BIND_LINEAR); + handle_flag(&use_flags, BO_USE_SW_WRITE_OFTEN, &bind, VIRGL_BIND_LINEAR); + handle_flag(&use_flags, BO_USE_SW_WRITE_RARELY, &bind, VIRGL_BIND_LINEAR); + + // All host drivers only support linear camera buffer formats. If + // that changes, this will need to be modified. + handle_flag(&use_flags, BO_USE_CAMERA_READ, &bind, VIRGL_BIND_LINEAR); + handle_flag(&use_flags, BO_USE_CAMERA_WRITE, &bind, VIRGL_BIND_LINEAR); + if (use_flags) { drv_log("Unhandled bo use flag: %llx\n", (unsigned long long)use_flags); } From c062c3b8e12f9a99bd835acaa996602d920e531d Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Thu, 20 Jun 2019 20:48:01 -0700 Subject: [PATCH 154/269] minigbm: allocate YV12 according to Android requirements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If we teach GBM/Virgl protocol/crosvm about DRM_FORMAT_YVU420_ANDROID, we'll have probably teach Chrome too. Since nobody uses DRM_FORMAT_YVU420 on GBM side really, let's just resolve to DRM_FORMAT_YVU420_ANDROID for now. Since DRM_FORMAT_YVU420_ANDROID is strictly defined, this call can be probably be completely resolved in the guest in the future possibly. BUG=b:132939420 TEST=compile only Change-Id: I834e1d2644b199d74ac6efc5920e9040097246c7 Reviewed-on: https://chromium-review.googlesource.com/1670555 Tested-by: Gurchetan Singh Commit-Ready: ChromeOS CL Exonerator Bot Legacy-Commit-Queue: Commit Bot Reviewed-by: Stéphane Marchesin --- gbm.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/gbm.c b/gbm.c index 7f9ed99..8db622b 100644 --- a/gbm.c +++ b/gbm.c @@ -117,6 +117,14 @@ PUBLIC struct gbm_bo *gbm_bo_create(struct gbm_device *gbm, uint32_t width, uint if (!bo) return NULL; + /* + * HACK: This is for HAL_PIXEL_FORMAT_YV12 buffers allocated by arcvm. + * None of our platforms can display YV12, so we can treat as a SW buffer. + * Remove once this can be intelligently resolved in the guest. + */ + if (format == GBM_FORMAT_YVU420 && (usage & GBM_BO_USE_LINEAR)) + format = DRM_FORMAT_YVU420_ANDROID; + bo->bo = drv_bo_create(gbm->drv, width, height, format, gbm_convert_usage(usage)); if (!bo->bo) { From 6ad6382539c2bb113c5b2682023247c9fe7c4d35 Mon Sep 17 00:00:00 2001 From: Alexandre Courbot Date: Tue, 1 Oct 2019 16:07:31 +0900 Subject: [PATCH 155/269] mediatek: provide NV12 buffers for video decoding for MT8183 crrev.com/c/1767450 changed the default android flexible buffer format back to YV12, but the video decoding scenario on MT8183 requires NV12 buffers. Add an exception for this case. BUG=b:141732718 TEST=Play H.264 video with acceleration using both Chrome and Android's Youtube. Change-Id: Ie4b80389b22650450ea45f5cdea36a00360899a9 Reviewed-on: https://chromium-review.googlesource.com/1833362 Tested-by: Alexandre Courbot Commit-Ready: Alexandre Courbot Legacy-Commit-Queue: Commit Bot Reviewed-by: Gurchetan Singh --- mediatek.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mediatek.c b/mediatek.c index 270d810..4492207 100644 --- a/mediatek.c +++ b/mediatek.c @@ -241,8 +241,9 @@ static uint32_t mediatek_resolve_format(struct driver *drv, uint32_t format, uin return DRM_FORMAT_XBGR8888; case DRM_FORMAT_FLEX_YCbCr_420_888: #ifdef MTK_MT8183 - /* Only for MT8183 Camera subsystem requires NV12 */ - if (use_flags & (BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE)) + /* MT8183 camera and decoder subsystems require NV12. */ + if (use_flags & + (BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER)) return DRM_FORMAT_NV12; #endif return DRM_FORMAT_YVU420; From 2c783afd958b92ed25cce2692f52968236a92210 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Tue, 24 Sep 2019 10:20:07 -0700 Subject: [PATCH 156/269] minigbm: modify gbm.pc virglrenderer will start requiring gbm >= 18.0.0, so add that here. BUG=none TEST=local build Change-Id: I40e63140d8b0ad6a76fc273c9c1e561c264aad7d Reviewed-on: https://chromium-review.googlesource.com/1821692 Tested-by: Gurchetan Singh Commit-Ready: Kazuhiro Inaba Legacy-Commit-Queue: Commit Bot Reviewed-by: Robert Tarasov --- gbm.pc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gbm.pc b/gbm.pc index e99ac83..a7509fc 100644 --- a/gbm.pc +++ b/gbm.pc @@ -5,6 +5,6 @@ libdir=${exec_prefix}/lib Name: libgbm Description: A small gbm implementation -Version: 0 +Version: 18.0.0 Cflags: -I${includedir} Libs: -L${libdir} -lgbm From 793675a1c0ed0b79b52820ad564fc61c6027f65e Mon Sep 17 00:00:00 2001 From: David Stevens Date: Wed, 25 Sep 2019 11:17:48 +0900 Subject: [PATCH 157/269] minigbm: i915: fix planar height alignment Aligned planar height should be calculated from the planar height, not the buffer height. BUG=b:133292033 TEST=ArcVideoTest renders video correctly (w/a few other changes) Change-Id: I1dc35ab4eebf9a5a86b2a9befaeb817a56dcfec2 Reviewed-on: https://chromium-review.googlesource.com/1824304 Tested-by: David Stevens Commit-Ready: Tomasz Figa Legacy-Commit-Queue: Commit Bot Reviewed-by: Tomasz Figa --- i915.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i915.c b/i915.c index 1a51aa4..ec0d8fd 100644 --- a/i915.c +++ b/i915.c @@ -256,7 +256,7 @@ static int i915_align_dimensions(struct bo *bo, uint32_t tiling, uint32_t *strid break; } - *aligned_height = ALIGN(bo->meta.height, vertical_alignment); + *aligned_height = ALIGN(*aligned_height, vertical_alignment); if (i915->gen > 3) { *stride = ALIGN(*stride, horizontal_alignment); } else { From 8312ec228d0c96e4c7cca85b8fd141dd6dd9e15e Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Tue, 24 Sep 2019 10:37:59 -0700 Subject: [PATCH 158/269] minigbm: rockchip/mediatek: add PROTECTED flag back in crrev.com/c/1643677 removed it, so we should add it back in. BUG=b:141347335 TEST=GtsExoPlayerTestCases/GtsMediaTestCases Change-Id: Ic49bd4158349da6170e8435c5c516954fe1646fa Reviewed-on: https://chromium-review.googlesource.com/1821693 Tested-by: Gurchetan Singh Commit-Ready: Kazuhiro Inaba Legacy-Commit-Queue: Commit Bot Reviewed-by: Gurchetan Singh --- mediatek.c | 3 ++- rockchip.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/mediatek.c b/mediatek.c index 4492207..6d77970 100644 --- a/mediatek.c +++ b/mediatek.c @@ -54,7 +54,8 @@ static int mediatek_init(struct driver *drv) drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), &LINEAR_METADATA, BO_USE_TEXTURE_MASK); - drv_add_combination(drv, DRM_FORMAT_R8, &LINEAR_METADATA, BO_USE_SW_MASK | BO_USE_LINEAR); + drv_add_combination(drv, DRM_FORMAT_R8, &LINEAR_METADATA, + BO_USE_SW_MASK | BO_USE_LINEAR | BO_USE_PROTECTED); /* * Chrome uses DMA-buf mmap to write to YV12 buffers, which are then accessed by the * Video Encoder Accelerator (VEA). It could also support NV12 potentially in the future. diff --git a/rockchip.c b/rockchip.c index ed8a7ae..43cbfe2 100644 --- a/rockchip.c +++ b/rockchip.c @@ -141,7 +141,7 @@ static int rockchip_init(struct driver *drv) */ drv_add_combination(drv, DRM_FORMAT_R8, &metadata, BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_SW_MASK | - BO_USE_LINEAR); + BO_USE_LINEAR | BO_USE_PROTECTED); kms_items = drv_query_kms(drv); if (!kms_items) From 4d5358d32cdf2afa2fd10b09c002751eed2c4cdc Mon Sep 17 00:00:00 2001 From: David Stevens Date: Thu, 24 Oct 2019 14:59:31 +0900 Subject: [PATCH 159/269] minigbm: virtio-gpu: bo_invalidate fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When invalidating a buffer, minigbm needs to ensure that the host-to-guest transfer completes before returning from invalidate, to prevent the host from overwriting subsequent guest changes. However, invalidate is only necessary when the host can modify the buffer. For now, just check for buffers the virtio gpu device can write to (BO_USE_RENDERING). More flags can be added later for other virtio devices. BUG=b:142687692 TEST=manual - Launch play store and verify there is no black app window. Change-Id: Id9475e6037ff667324f4fd95a94b1723c18ea2d2 Reviewed-on: https://chromium-review.googlesource.com/1875897 Tested-by: David Stevens Commit-Ready: ChromeOS CL Exonerator Bot Legacy-Commit-Queue: Commit Bot Reviewed-by: Stéphane Marchesin Reviewed-by: Lepton Wu --- virtio_gpu.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/virtio_gpu.c b/virtio_gpu.c index 9e5b0ba..daeafde 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -263,10 +263,15 @@ static int virtio_gpu_bo_invalidate(struct bo *bo, struct mapping *mapping) int ret; struct drm_virtgpu_3d_transfer_from_host xfer; struct virtio_gpu_priv *priv = (struct virtio_gpu_priv *)bo->drv->priv; + struct drm_virtgpu_3d_wait waitcmd; if (!priv->has_3d) return 0; + // Invalidate is only necessary if the host writes to the buffer. + if ((bo->meta.use_flags & BO_USE_RENDERING) == 0) + return 0; + memset(&xfer, 0, sizeof(xfer)); xfer.bo_handle = mapping->vma->handle; xfer.box.x = mapping->rect.x; @@ -286,6 +291,17 @@ static int virtio_gpu_bo_invalidate(struct bo *bo, struct mapping *mapping) return -errno; } + // The transfer needs to complete before invalidate returns so that any host changes + // are visible and to ensure the host doesn't overwrite subsequent guest changes. + // TODO(b/136733358): Support returning fences from transfers + memset(&waitcmd, 0, sizeof(waitcmd)); + waitcmd.handle = mapping->vma->handle; + ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_WAIT, &waitcmd); + if (ret) { + drv_log("DRM_IOCTL_VIRTGPU_WAIT failed with %s\n", strerror(errno)); + return -errno; + } + return 0; } From 0907d821ccd589ecc0e047909cc6df18ddb5f31c Mon Sep 17 00:00:00 2001 From: Jason Macnak Date: Tue, 12 Nov 2019 10:53:05 -0800 Subject: [PATCH 160/269] Make drv_mapping_destroy() be called in release builds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The entire assert statement is currently being dropped when NDEBUG is defined which causes mappings to never be cleaned up on bo destruction. When mappings are not cleaned up, a new buffer that gets a recycled handle may find an old mapping in drv_bo_map() which is not valid for the new buffer. BUG=b:123764798 TEST=built and ran with cuttlefish locally Change-Id: Ib7147c3f5ed3a2b84793dfc2b17236ee0d92ac13 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1912760 Tested-by: Jason Macnak Reviewed-by: Stéphane Marchesin Reviewed-by: Gurchetan Singh Commit-Queue: Jason Macnak --- drv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drv.c b/drv.c index ef5cbc5..872b5d4 100644 --- a/drv.c +++ b/drv.c @@ -320,6 +320,7 @@ struct bo *drv_bo_create_with_modifiers(struct driver *drv, uint32_t width, uint void drv_bo_destroy(struct bo *bo) { + int ret; size_t plane; uintptr_t total = 0; struct driver *drv = bo->drv; @@ -335,7 +336,8 @@ void drv_bo_destroy(struct bo *bo) pthread_mutex_unlock(&drv->driver_lock); if (total == 0) { - assert(drv_mapping_destroy(bo) == 0); + ret = drv_mapping_destroy(bo); + assert(ret == 0); bo->drv->backend->bo_destroy(bo); } From 37be43662a019bc3291661d3a0a8e61131588ed1 Mon Sep 17 00:00:00 2001 From: Lepton Wu Date: Fri, 8 Nov 2019 22:58:12 -0800 Subject: [PATCH 161/269] minigbm: virtio_gpu: add NV12 back as texture source format BUG=b:141082210 TEST=ozone_gl_unittests Change-Id: I8288806796038f46ef9cb61afbf37443505dc79e Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1907996 Reviewed-by: Gurchetan Singh Tested-by: Lepton Wu Auto-Submit: Lepton Wu Commit-Queue: Lepton Wu --- virtio_gpu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/virtio_gpu.c b/virtio_gpu.c index daeafde..b420e58 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -30,6 +30,7 @@ static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMA DRM_FORMAT_XRGB8888 }; static const uint32_t dumb_texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_YVU420, + DRM_FORMAT_NV12, DRM_FORMAT_YVU420_ANDROID }; static const uint32_t texture_source_formats[] = { DRM_FORMAT_NV12, DRM_FORMAT_R8, DRM_FORMAT_RG88, From 5e55f956f70213ad990f796f511246a0bfd99d3e Mon Sep 17 00:00:00 2001 From: Hirokazu Honda Date: Fri, 8 Nov 2019 12:57:55 +0900 Subject: [PATCH 162/269] gralloc0: Add BO_USE_HW_VIDEO_ENCODER mask in GRALLOC_USAGE_HW_VIDEO_ENCODER MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG=b:144135251 TEST=ARC++ encoder on kukui Change-Id: Ic15adebf2266b51aeaa19e863369e1c49c4fab03 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1904910 Reviewed-by: Gurchetan Singh Reviewed-by: Stéphane Marchesin Tested-by: Hirokazu Honda Auto-Submit: Hirokazu Honda Commit-Queue: Hirokazu Honda --- cros_gralloc/gralloc0/gralloc0.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cros_gralloc/gralloc0/gralloc0.cc b/cros_gralloc/gralloc0/gralloc0.cc index eef5d2f..fcedc8e 100644 --- a/cros_gralloc/gralloc0/gralloc0.cc +++ b/cros_gralloc/gralloc0/gralloc0.cc @@ -71,9 +71,11 @@ static uint64_t gralloc0_convert_usage(int usage) use_flags |= BO_USE_NONE; if (usage & GRALLOC_USAGE_PROTECTED) use_flags |= BO_USE_PROTECTED; - if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) + if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) { + use_flags |= BO_USE_HW_VIDEO_ENCODER; /*HACK: See b/30054495 */ 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) From 55485403648122bd13e33060319880ba3a3762dd Mon Sep 17 00:00:00 2001 From: Miguel Casas Date: Tue, 19 Nov 2019 16:10:17 -0500 Subject: [PATCH 163/269] i915: allow allocating AR30/AB30 for scanout This CL extends the current M.O. of allowing ARGB formats for scanout if the corresponding XRGB format supports it, for XR30 and XB30. (Needs crrev.com/c/1925247 patched in). BUG=chromium:949260 TEST=null_platform_tests -f AR30 etc on kohaku/hatch Change-Id: I720e82a17873e5f635f530bf3eefff24c2e3ab77 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1925250 Tested-by: Miguel Casas Reviewed-by: Gurchetan Singh Reviewed-by: Daniele Castagna --- i915.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/i915.c b/i915.c index ec0d8fd..025b6b5 100644 --- a/i915.c +++ b/i915.c @@ -73,6 +73,10 @@ static bool format_compatible(const struct combination *combo, uint32_t format) return combo->format == DRM_FORMAT_RGBA8888; case DRM_FORMAT_BGRX8888: return combo->format == DRM_FORMAT_BGRA8888; + case DRM_FORMAT_XRGB2101010: + return combo->format == DRM_FORMAT_ARGB2101010; + case DRM_FORMAT_XBGR2101010: + return combo->format == DRM_FORMAT_ABGR2101010; default: return false; } From aa6b072d4ce2d445e48b9978ac3f0bc73cd97176 Mon Sep 17 00:00:00 2001 From: Hirokazu Honda Date: Mon, 25 Nov 2019 16:48:30 +0900 Subject: [PATCH 164/269] Enable to allocate XBGR8888 with HW_VIDEO_ENCODER usage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit crrev.com/c/1904910 masks the HW_VIDEO_ENCODER usage when BO_USE_HW_VIDEO_ENCODER is specified in gralloc. A camera stack allocates XBGR8888 buffer with BO_USE_HW_VIDEO_ENCODER usage in ARC++ video recording if the camera HAL version is V1. Thanks to crrev.com/c/1904910, it is necessary to enable to allocate XBGR8888 with HW_VIDEO_ENCODER usage. BUG=b:144135251 TEST=Recording with GCA Change-Id: I61beee87a1531c0dea371861ffb31ce2189ef854 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1934068 Tested-by: Hirokazu Honda Reviewed-by: Stéphane Marchesin Commit-Queue: Hirokazu Honda --- i915.c | 7 +++++++ mediatek.c | 7 +++++++ rockchip.c | 7 +++++++ 3 files changed, 21 insertions(+) diff --git a/i915.c b/i915.c index 025b6b5..3485c83 100644 --- a/i915.c +++ b/i915.c @@ -151,6 +151,13 @@ static int i915_add_combinations(struct driver *drv) drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata, BO_USE_HW_VIDEO_ENCODER | BO_USE_HW_VIDEO_DECODER); + /* + * Camera buffers are allocated with GRALLOC_USAGE_HW_VIDEO_ENCODER, and the camera stack + * selects XBGR8888 in ARC++ video recording if the camera HAL is V1. So we need to be able + * to allocate this format. + */ + drv_modify_combination(drv, DRM_FORMAT_XBGR8888, &metadata, BO_USE_HW_VIDEO_ENCODER); + /* Android CTS tests require this. */ drv_add_combination(drv, DRM_FORMAT_BGR888, &metadata, BO_USE_SW_MASK); diff --git a/mediatek.c b/mediatek.c index 6d77970..9adec5c 100644 --- a/mediatek.c +++ b/mediatek.c @@ -63,6 +63,13 @@ static int mediatek_init(struct driver *drv) drv_modify_combination(drv, DRM_FORMAT_YVU420, &LINEAR_METADATA, BO_USE_HW_VIDEO_ENCODER); drv_modify_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA, BO_USE_HW_VIDEO_ENCODER); + /* + * Camera buffers are allocated with GRALLOC_USAGE_HW_VIDEO_ENCODER, and the camera stack + * selects XBGR8888 in ARC++ video recording if the camera HAL is V1. So we need to be able + * to allocate this format. + */ + drv_modify_combination(drv, DRM_FORMAT_XBGR8888, &metadata, BO_USE_HW_VIDEO_ENCODER); + /* Android CTS tests require this. */ drv_add_combination(drv, DRM_FORMAT_BGR888, &LINEAR_METADATA, BO_USE_SW_MASK); diff --git a/rockchip.c b/rockchip.c index 43cbfe2..dfa25a8 100644 --- a/rockchip.c +++ b/rockchip.c @@ -129,6 +129,13 @@ static int rockchip_init(struct driver *drv) drv_modify_combination(drv, DRM_FORMAT_YVU420, &metadata, BO_USE_HW_VIDEO_ENCODER); drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata, BO_USE_HW_VIDEO_ENCODER); + /* + * Camera buffers are allocated with GRALLOC_USAGE_HW_VIDEO_ENCODER, and the camera stack + * selects XBGR8888 in ARC++ video recording if the camera HAL is V1. So we need to be able + * to allocate this format. + */ + drv_modify_combination(drv, DRM_FORMAT_XBGR8888, &metadata, BO_USE_HW_VIDEO_ENCODER); + 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); From b6c4cf7b91a0b69b72cf96efaef1d19412ba716d Mon Sep 17 00:00:00 2001 From: Hirokazu Honda Date: Tue, 3 Dec 2019 02:12:09 +0000 Subject: [PATCH 165/269] Revert "Enable to allocate XBGR8888 with HW_VIDEO_ENCODER usage" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit aa6b072d4ce2d445e48b9978ac3f0bc73cd97176. Reason for revert: This change is unnecessary because HW_VIDEO_ENCODER usage is unmasked in crrev.com/c/1940034. Original change's description: > Enable to allocate XBGR8888 with HW_VIDEO_ENCODER usage > > crrev.com/c/1904910 masks the HW_VIDEO_ENCODER usage when > BO_USE_HW_VIDEO_ENCODER is specified in gralloc. A camera stack allocates > XBGR8888 buffer with BO_USE_HW_VIDEO_ENCODER usage in ARC++ video > recording if the camera HAL version is V1. Thanks to crrev.com/c/1904910, > it is necessary to enable to allocate XBGR8888 with HW_VIDEO_ENCODER usage. > > BUG=b:144135251 > TEST=Recording with GCA > > Change-Id: I61beee87a1531c0dea371861ffb31ce2189ef854 > Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1934068 > Tested-by: Hirokazu Honda > Reviewed-by: Stéphane Marchesin > Commit-Queue: Hirokazu Honda Bug: b:144135251 Cq-Depend: chromium:1940034 Change-Id: I8d64c97399a601487fc84a6ecae337c235bd4464 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1947685 Tested-by: Hirokazu Honda Auto-Submit: Hirokazu Honda Reviewed-by: Gurchetan Singh Commit-Queue: Hirokazu Honda --- i915.c | 7 ------- mediatek.c | 7 ------- rockchip.c | 7 ------- 3 files changed, 21 deletions(-) diff --git a/i915.c b/i915.c index 3485c83..025b6b5 100644 --- a/i915.c +++ b/i915.c @@ -151,13 +151,6 @@ static int i915_add_combinations(struct driver *drv) drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata, BO_USE_HW_VIDEO_ENCODER | BO_USE_HW_VIDEO_DECODER); - /* - * Camera buffers are allocated with GRALLOC_USAGE_HW_VIDEO_ENCODER, and the camera stack - * selects XBGR8888 in ARC++ video recording if the camera HAL is V1. So we need to be able - * to allocate this format. - */ - drv_modify_combination(drv, DRM_FORMAT_XBGR8888, &metadata, BO_USE_HW_VIDEO_ENCODER); - /* Android CTS tests require this. */ drv_add_combination(drv, DRM_FORMAT_BGR888, &metadata, BO_USE_SW_MASK); diff --git a/mediatek.c b/mediatek.c index 9adec5c..6d77970 100644 --- a/mediatek.c +++ b/mediatek.c @@ -63,13 +63,6 @@ static int mediatek_init(struct driver *drv) drv_modify_combination(drv, DRM_FORMAT_YVU420, &LINEAR_METADATA, BO_USE_HW_VIDEO_ENCODER); drv_modify_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA, BO_USE_HW_VIDEO_ENCODER); - /* - * Camera buffers are allocated with GRALLOC_USAGE_HW_VIDEO_ENCODER, and the camera stack - * selects XBGR8888 in ARC++ video recording if the camera HAL is V1. So we need to be able - * to allocate this format. - */ - drv_modify_combination(drv, DRM_FORMAT_XBGR8888, &metadata, BO_USE_HW_VIDEO_ENCODER); - /* Android CTS tests require this. */ drv_add_combination(drv, DRM_FORMAT_BGR888, &LINEAR_METADATA, BO_USE_SW_MASK); diff --git a/rockchip.c b/rockchip.c index dfa25a8..43cbfe2 100644 --- a/rockchip.c +++ b/rockchip.c @@ -129,13 +129,6 @@ static int rockchip_init(struct driver *drv) drv_modify_combination(drv, DRM_FORMAT_YVU420, &metadata, BO_USE_HW_VIDEO_ENCODER); drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata, BO_USE_HW_VIDEO_ENCODER); - /* - * Camera buffers are allocated with GRALLOC_USAGE_HW_VIDEO_ENCODER, and the camera stack - * selects XBGR8888 in ARC++ video recording if the camera HAL is V1. So we need to be able - * to allocate this format. - */ - drv_modify_combination(drv, DRM_FORMAT_XBGR8888, &metadata, BO_USE_HW_VIDEO_ENCODER); - 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); From 758cf12c8e701c2f783d895eeb87e9bb9017e72e Mon Sep 17 00:00:00 2001 From: Hirokazu Honda Date: Tue, 3 Dec 2019 11:01:59 +0900 Subject: [PATCH 166/269] gralloc0: Unmask HW_VIDEO_ENCODER usage in the case of non-YUV formats Non-yuv formats are allocated with HW_VIDEO_ENCODER usage as an intermediate buffers, for example, camera fills. They are converted to YUV formats finally when they are fed to a hw encoder. So there is no need of allocating the buffers with HW_VIDEO_ENCODER. TEST=Recording with GCA TEST=android.media.cts.EncodeVirtualDisplayTest#testEncodeVirtualDisplay on kevin Cq-Depend: chromium:1947685 Change-Id: Ic5c09823de1f53ffb6117d07327779e46f32a3f6 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1940034 Tested-by: Hirokazu Honda Auto-Submit: Hirokazu Honda Commit-Queue: Hirokazu Honda Reviewed-by: Gurchetan Singh --- cros_gralloc/cros_gralloc_driver.cc | 9 +++++++++ cros_gralloc/gralloc0/gralloc0.cc | 20 +++++++++++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/cros_gralloc/cros_gralloc_driver.cc b/cros_gralloc/cros_gralloc_driver.cc index 8a63864..89897e0 100644 --- a/cros_gralloc/cros_gralloc_driver.cc +++ b/cros_gralloc/cros_gralloc_driver.cc @@ -114,6 +114,15 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto if (resolved_format == DRM_FORMAT_NV12) use_flags |= BO_USE_LINEAR; + /* + * This unmask is a backup in the case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED is resolved + * to non-YUV formats. + */ + if (descriptor->drm_format == DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED && + (resolved_format == DRM_FORMAT_XBGR8888 || resolved_format == DRM_FORMAT_ABGR8888)) { + use_flags &= ~BO_USE_HW_VIDEO_ENCODER; + } + bo = drv_bo_create(drv_, descriptor->width, descriptor->height, resolved_format, use_flags); if (!bo) { drv_log("Failed to create bo.\n"); diff --git a/cros_gralloc/gralloc0/gralloc0.cc b/cros_gralloc/gralloc0/gralloc0.cc index fcedc8e..0a302b4 100644 --- a/cros_gralloc/gralloc0/gralloc0.cc +++ b/cros_gralloc/gralloc0/gralloc0.cc @@ -100,6 +100,13 @@ static uint32_t gralloc0_convert_map_usage(int map_usage) return map_flags; } +static int gralloc0_droid_yuv_format(int droid_format) +{ + + return (droid_format == HAL_PIXEL_FORMAT_YCbCr_420_888 || + droid_format == HAL_PIXEL_FORMAT_YV12); +} + static int gralloc0_alloc(alloc_device_t *dev, int w, int h, int format, int usage, buffer_handle_t *handle, int *stride) { @@ -120,6 +127,14 @@ static int gralloc0_alloc(alloc_device_t *dev, int w, int h, int format, int usa descriptor.use_flags &= ~BO_USE_SCANOUT; supported = mod->driver->is_supported(&descriptor); } + if (!supported && (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) && + !gralloc0_droid_yuv_format(format)) { + // Unmask BO_USE_HW_VIDEO_ENCODER in the case of non-yuv formats + // because they are not input to a hw encoder but used as an + // intermediate format (e.g. camera). + descriptor.use_flags &= ~BO_USE_HW_VIDEO_ENCODER; + supported = mod->driver->is_supported(&descriptor); + } if (!supported) { drv_log("Unsupported combination -- HAL format: %u, HAL usage: %u, " @@ -362,9 +377,8 @@ static int gralloc0_lock_async_ycbcr(struct gralloc_module_t const *module, buff return -EINVAL; } - if ((hnd->droid_format != HAL_PIXEL_FORMAT_YCbCr_420_888) && - (hnd->droid_format != HAL_PIXEL_FORMAT_YV12) && - (hnd->droid_format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)) { + if (!gralloc0_droid_yuv_format(hnd->droid_format) && + hnd->droid_format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) { drv_log("Non-YUV format not compatible.\n"); return -EINVAL; } From c7aa974dd383680ce8b1384785416bc77fa2c145 Mon Sep 17 00:00:00 2001 From: Jasmine Chen Date: Wed, 14 Aug 2019 15:28:22 +0800 Subject: [PATCH 167/269] Add MediaTek private format for reprocessing In this CL, we add DRM_FORMAT_MTISP_SXYZW10, a 10-bit private bayer format for private reprocessing on MediaTek ISP P1. We change the logic around resolving the DRM format for IMPLEMENTATION_DEFINED buffers. When CAMERA_READ usage flag is present, we consider it to be a buffer for reprocessing and resolve the format to our private format. BUG=b:130851309 TEST=Emerge and deploy minigbm cros-camera-libcbm cros-camera cros-camera-hal-mtk, then verify that ZSL is working. Change-Id: I8d9fd4e6a20c284751915e136bef0b4ceb143d78 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1753902 Tested-by: Jasmine Chen Auto-Submit: Jasmine Chen Reviewed-by: Gurchetan Singh Commit-Queue: Jasmine Chen --- drv.h | 6 +++++- helpers.c | 1 + mediatek.c | 13 +++++++++++-- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/drv.h b/drv.h index 0cb062d..15b9736 100644 --- a/drv.h +++ b/drv.h @@ -48,12 +48,16 @@ extern "C" { * on the namespace of already defined formats, which can be done by using invalid * fourcc codes. */ - #define DRM_FORMAT_NONE fourcc_code('0', '0', '0', '0') #define DRM_FORMAT_YVU420_ANDROID fourcc_code('9', '9', '9', '7') #define DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED fourcc_code('9', '9', '9', '8') #define DRM_FORMAT_FLEX_YCbCr_420_888 fourcc_code('9', '9', '9', '9') +/* This is a 10-bit bayer format for private reprocessing on MediaTek ISP. It's + * a private RAW format that other DRM drivers will never support and thus + * making it not upstreamable (i.e., defined in official DRM headers). */ +#define DRM_FORMAT_MTISP_SXYZW10 fourcc_code('M', 'B', '1', '0') + // TODO(crbug.com/958181): remove this definition once drm_fourcc.h contains it. #ifndef DRM_FORMAT_P010 #define DRM_FORMAT_P010 fourcc_code('P', '0', '1', '0') diff --git a/helpers.c b/helpers.c index c7396a4..ad8a9f0 100644 --- a/helpers.c +++ b/helpers.c @@ -128,6 +128,7 @@ static const struct planar_layout *layout_from_format(uint32_t format) case DRM_FORMAT_XRGB4444: case DRM_FORMAT_YUYV: case DRM_FORMAT_YVYU: + case DRM_FORMAT_MTISP_SXYZW10: return &packed_2bpp_layout; case DRM_FORMAT_BGR888: diff --git a/mediatek.c b/mediatek.c index 6d77970..ce84b43 100644 --- a/mediatek.c +++ b/mediatek.c @@ -86,6 +86,9 @@ static int mediatek_init(struct driver *drv) BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); drv_modify_combination(drv, DRM_FORMAT_R8, &metadata, BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); + /* Private formats for private reprocessing in camera */ + drv_add_combination(drv, DRM_FORMAT_MTISP_SXYZW10, &metadata, + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_SW_MASK); #endif return drv_modify_linear_combinations(drv); @@ -234,8 +237,14 @@ static uint32_t mediatek_resolve_format(struct driver *drv, uint32_t format, uin switch (format) { case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED: #ifdef MTK_MT8183 - /* Only for MT8183 Camera subsystem requires NV12. */ - if (use_flags & (BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE)) + /* Only MT8183 Camera subsystem offers private reprocessing + * capability. CAMERA_READ indicates the buffer is intended for + * reprocessing and hence given the private format for MTK. */ + if (use_flags & BO_USE_CAMERA_READ) + return DRM_FORMAT_MTISP_SXYZW10; + /* For non-reprocessing uses, only MT8183 Camera subsystem + * requires NV12. */ + else if (use_flags & BO_USE_CAMERA_WRITE) return DRM_FORMAT_NV12; #endif /*HACK: See b/28671744 */ From 9a9672f8e48ad59b1eaaf4037a5363bf8d8ef4ab Mon Sep 17 00:00:00 2001 From: Drew Davenport Date: Tue, 12 Nov 2019 12:03:59 -0700 Subject: [PATCH 168/269] minigbm: dri: Don't redefine GL typedefs dri_interface.h now #includes GL/gl.h so there is no need to define these. BUG=b:143621384 TEST=build/deploy minigbm and arc-cros-gralloc for grunt Cq-Depend: chromium:1907530 Change-Id: Ic370dc1404156c8e5de5dc9490a8c68b49661c00 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1912763 Reviewed-by: Gurchetan Singh Commit-Queue: Ilja H. Friedel Tested-by: Ilja H. Friedel --- dri.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dri.h b/dri.h index f79de99..9c72b1e 100644 --- a/dri.h +++ b/dri.h @@ -6,11 +6,11 @@ #ifdef DRV_AMDGPU -typedef int GLint; -typedef unsigned int GLuint; -typedef unsigned char GLboolean; - +// Avoid transitively including a bunch of unnecessary headers. +#define GL_GLEXT_LEGACY #include "GL/internal/dri_interface.h" +#undef GL_GLEXT_LEGACY + #include "drv.h" struct dri_driver { From 20e4a932ee4f2aa90191d0b4ad2e1b16bf0a798a Mon Sep 17 00:00:00 2001 From: Hirokazu Honda Date: Fri, 6 Dec 2019 15:21:45 +0900 Subject: [PATCH 169/269] virtio_gpu: Add HW_VIDEO_ENCODER usage flags to NV12 A virtual device resolves a flexible format to NV12. NV12 should have the usage HW_VIDEO_ENCODER. BUG=b:145715379 TEST=Camera video recording on a virtual device Change-Id: I8ea1c75087d35c19c472890138c603b74f1ef491 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1955344 Reviewed-by: Gurchetan Singh Reviewed-by: Matthias Springer Reviewed-by: Hirokazu Honda Tested-by: Matthias Springer Auto-Submit: Hirokazu Honda Commit-Queue: Hirokazu Honda --- virtio_gpu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/virtio_gpu.c b/virtio_gpu.c index b420e58..aa3378c 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -218,7 +218,8 @@ static int virtio_gpu_init(struct driver *drv) drv_add_combination(drv, DRM_FORMAT_BGR888, &LINEAR_METADATA, BO_USE_SW_MASK); drv_modify_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA, - BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER); + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER | + BO_USE_HW_VIDEO_ENCODER); drv_modify_combination(drv, DRM_FORMAT_R8, &LINEAR_METADATA, BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); From 6e6dc49707737d0578617f89cb01bb585f9b00c3 Mon Sep 17 00:00:00 2001 From: Dominik Behr Date: Wed, 9 Oct 2019 15:43:52 -0700 Subject: [PATCH 170/269] minigbm: virtio: restrict formats supported without 3D Upstream virtio drm commit "drm/virtio: fix DRM_FORMAT_* handling" severely restricts supported formats and strictly enforces 32bpp dumb buffers. Therefore now we only support XRGB8888 for scanout, ARGB8888 for cursor, ARGB8888 for rendering. Also, we pretend all buffers are 32bpp when allocating as dumb buffers. BUG=none TEST=tast run 127.0.0.1:9222 webrtc.RTCPeerConnection.vp8 Change-Id: I6225a9cb3c49f0850c6d94b2d12efaf9a33b149e Signed-off-by: Dominik Behr Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1849773 Reviewed-by: Gurchetan Singh --- drv.h | 3 +++ helpers.c | 20 ++++++++++++++++---- helpers.h | 2 ++ virtio_gpu.c | 22 ++++++++++++++++------ 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/drv.h b/drv.h index 15b9736..d3cfb45 100644 --- a/drv.h +++ b/drv.h @@ -37,6 +37,9 @@ extern "C" { #define BO_USE_HW_VIDEO_DECODER (1ull << 14) #define BO_USE_RENDERSCRIPT (1ull << 15) +/* Quirks for allocating a buffer. */ +#define BO_QUIRK_NONE 0 +#define BO_QUIRK_DUMB32BPP (1ull << 0) /* Map flags */ #define BO_MAP_NONE 0 diff --git a/helpers.c b/helpers.c index ad8a9f0..ec5fdac 100644 --- a/helpers.c +++ b/helpers.c @@ -272,8 +272,8 @@ int drv_bo_from_format(struct bo *bo, uint32_t stride, uint32_t aligned_height, return 0; } -int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, - uint64_t use_flags) +int drv_dumb_bo_create_ex(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint64_t use_flags, uint64_t quirks) { int ret; size_t plane; @@ -303,9 +303,15 @@ int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t } memset(&create_dumb, 0, sizeof(create_dumb)); - create_dumb.height = aligned_height; + if (quirks & BO_QUIRK_DUMB32BPP) { + aligned_width = + DIV_ROUND_UP(aligned_width * layout_from_format(format)->bytes_per_pixel[0], 4); + create_dumb.bpp = 32; + } else { + create_dumb.bpp = layout_from_format(format)->bytes_per_pixel[0] * 8; + } create_dumb.width = aligned_width; - create_dumb.bpp = layout_from_format(format)->bytes_per_pixel[0] * 8; + create_dumb.height = aligned_height; create_dumb.flags = 0; ret = drmIoctl(bo->drv->fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb); @@ -323,6 +329,12 @@ int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t return 0; } +int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint64_t use_flags) +{ + return drv_dumb_bo_create_ex(bo, width, height, format, use_flags, BO_QUIRK_NONE); +} + int drv_dumb_bo_destroy(struct bo *bo) { struct drm_mode_destroy_dumb destroy_dumb; diff --git a/helpers.h b/helpers.h index c09d2c2..c503b01 100644 --- a/helpers.h +++ b/helpers.h @@ -17,6 +17,8 @@ uint32_t drv_size_from_format(uint32_t format, uint32_t stride, uint32_t height, 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, uint64_t use_flags); +int drv_dumb_bo_create_ex(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint64_t use_flags, uint64_t quirks); 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); diff --git a/virtio_gpu.c b/virtio_gpu.c index aa3378c..50ca997 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -75,7 +75,7 @@ static int virtio_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, height = ALIGN(height, MESA_LLVMPIPE_TILE_SIZE); } - return drv_dumb_bo_create(bo, width, height, format, use_flags); + return drv_dumb_bo_create_ex(bo, width, height, format, use_flags, BO_QUIRK_DUMB32BPP); } static inline void handle_flag(uint64_t *flag, uint64_t check_flag, uint32_t *bind, @@ -197,16 +197,26 @@ static int virtio_gpu_init(struct driver *drv) priv->has_3d = 0; } - /* This doesn't mean host can scanout everything, it just means host - * hypervisor can show it. */ - drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &LINEAR_METADATA, BO_USE_RENDER_MASK | BO_USE_SCANOUT); - if (priv->has_3d) { + /* This doesn't mean host can scanout everything, it just means host + * hypervisor can show it. */ + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &LINEAR_METADATA, BO_USE_RENDER_MASK | BO_USE_SCANOUT); drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), &LINEAR_METADATA, BO_USE_TEXTURE_MASK); } else { + /* Virtio primary plane only allows this format. */ + drv_add_combination(drv, DRM_FORMAT_XRGB8888, &LINEAR_METADATA, + BO_USE_RENDER_MASK | BO_USE_SCANOUT); + /* Virtio cursor plane only allows this format and Chrome cannot live without + * ARGB888 renderable format. */ + drv_add_combination(drv, DRM_FORMAT_ARGB8888, &LINEAR_METADATA, + BO_USE_RENDER_MASK | BO_USE_CURSOR); + /* Android needs more, but they cannot be bound as scanouts anymore after + * "drm/virtio: fix DRM_FORMAT_* handling" */ + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &LINEAR_METADATA, BO_USE_RENDER_MASK); drv_add_combinations(drv, dumb_texture_source_formats, ARRAY_SIZE(dumb_texture_source_formats), &LINEAR_METADATA, BO_USE_TEXTURE_MASK); From 2a2bfc25bb4eaf53d6d1d9e1990c6b2888d4d3fb Mon Sep 17 00:00:00 2001 From: Hirokazu Honda Date: Fri, 11 Oct 2019 15:54:50 +0900 Subject: [PATCH 171/269] mediatek: Allocate a buffer expected by encoder if BO_USE_HW_VIDEO_ENCODER MediaTek driver expects 16 aligned width and 32 aligned height for an input buffer on encoding [1]. Besides, there is an extra data between planes. This changes the minigbm allocation to match the expectation though width is aligned by 64 for the AMD cache-width optimization. [1] https://chromium.googlesource.com/chromiumos/third_party/kernel/+/3c551224d8600b956ed53097520501d58f31cf59/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c#278 BUG=b:144135251 TEST=ARC++ encoder on kukui Change-Id: Id330a8a6b0a40040098920427e6e29f05fcb64d4 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1855520 Reviewed-by: Tomasz Figa Tested-by: Hirokazu Honda Auto-Submit: Hirokazu Honda Commit-Queue: Hsu Wei-Cheng --- helpers.c | 18 +++++++++++++++++- helpers.h | 3 +++ mediatek.c | 21 ++++++++++++++++++--- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/helpers.c b/helpers.c index ec5fdac..e29f539 100644 --- a/helpers.c +++ b/helpers.c @@ -186,6 +186,15 @@ uint32_t drv_height_from_format(uint32_t format, uint32_t height, size_t plane) return DIV_ROUND_UP(height, layout->vertical_subsampling[plane]); } +uint32_t drv_vertical_subsampling_from_format(uint32_t format, size_t plane) +{ + const struct planar_layout *layout = layout_from_format(format); + + assert(plane < layout->num_planes); + + return layout->vertical_subsampling[plane]; +} + uint32_t drv_bytes_per_pixel_from_format(uint32_t format, size_t plane) { const struct planar_layout *layout = layout_from_format(format); @@ -242,7 +251,13 @@ static uint32_t subsample_stride(uint32_t stride, uint32_t format, size_t plane) */ int drv_bo_from_format(struct bo *bo, uint32_t stride, uint32_t aligned_height, uint32_t format) { + uint32_t padding[DRV_MAX_PLANES] = { 0 }; + return drv_bo_from_format_and_padding(bo, stride, aligned_height, format, padding); +} +int drv_bo_from_format_and_padding(struct bo *bo, uint32_t stride, uint32_t aligned_height, + uint32_t format, uint32_t padding[DRV_MAX_PLANES]) +{ size_t p, num_planes; uint32_t offset = 0; @@ -263,7 +278,8 @@ int drv_bo_from_format(struct bo *bo, uint32_t stride, uint32_t aligned_height, for (p = 0; p < num_planes; p++) { bo->meta.strides[p] = subsample_stride(stride, format, p); bo->meta.sizes[p] = - drv_size_from_format(format, bo->meta.strides[p], aligned_height, p); + drv_size_from_format(format, bo->meta.strides[p], aligned_height, p) + + padding[p]; bo->meta.offsets[p] = offset; offset += bo->meta.sizes[p]; } diff --git a/helpers.h b/helpers.h index c503b01..fe4519d 100644 --- a/helpers.h +++ b/helpers.h @@ -13,8 +13,11 @@ #include "helpers_array.h" uint32_t drv_height_from_format(uint32_t format, uint32_t height, size_t plane); +uint32_t drv_vertical_subsampling_from_format(uint32_t format, 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_bo_from_format_and_padding(struct bo *bo, uint32_t stride, uint32_t aligned_height, + uint32_t format, uint32_t padding[DRV_MAX_PLANES]); int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, uint64_t use_flags); int drv_dumb_bo_create_ex(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, diff --git a/mediatek.c b/mediatek.c index ce84b43..5581e8f 100644 --- a/mediatek.c +++ b/mediatek.c @@ -115,7 +115,21 @@ static int mediatek_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint */ stride = drv_stride_from_format(format, width, 0); stride = ALIGN(stride, 64); - drv_bo_from_format(bo, stride, height, format); + + if (bo->meta.use_flags & BO_USE_HW_VIDEO_ENCODER) { + uint32_t aligned_height = ALIGN(height, 32); + uint32_t padding[DRV_MAX_PLANES] = { 0 }; + + for (plane = 0; plane < bo->meta.num_planes; ++plane) { + uint32_t plane_stride = drv_stride_from_format(format, stride, plane); + padding[plane] = plane_stride * + (32 / drv_vertical_subsampling_from_format(format, plane)); + } + + drv_bo_from_format_and_padding(bo, stride, aligned_height, format, padding); + } else { + drv_bo_from_format(bo, stride, height, format); + } memset(&gem_create, 0, sizeof(gem_create)); gem_create.size = bo->meta.total_size; @@ -252,9 +266,10 @@ static uint32_t mediatek_resolve_format(struct driver *drv, uint32_t format, uin case DRM_FORMAT_FLEX_YCbCr_420_888: #ifdef MTK_MT8183 /* MT8183 camera and decoder subsystems require NV12. */ - if (use_flags & - (BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER)) + if (use_flags & (BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | + BO_USE_HW_VIDEO_DECODER | BO_USE_HW_VIDEO_ENCODER)) { return DRM_FORMAT_NV12; + } #endif return DRM_FORMAT_YVU420; default: From 059ac08b0b3ad075b741fe090c031be63fc5a1e7 Mon Sep 17 00:00:00 2001 From: Moja Hsu Date: Wed, 2 Oct 2019 14:47:10 +0800 Subject: [PATCH 172/269] mediatek: Align height to 16 bytes for NV12 We want to use the same buffer from camera to JPEG hardware encoder so align the height of camera usage buffer 16 that is required by the JPEG hardware encoder. BUG=b:141516308 TEST=Check if data offset is correct. Take picture with CCA. Change-Id: I0db10762494423f7c4a340725015839803b40af4 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1984211 Reviewed-by: Gurchetan Singh Tested-by: Hsu Wei-Cheng Commit-Queue: Hsu Wei-Cheng --- mediatek.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/mediatek.c b/mediatek.c index 5581e8f..36d8115 100644 --- a/mediatek.c +++ b/mediatek.c @@ -128,6 +128,15 @@ static int mediatek_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint drv_bo_from_format_and_padding(bo, stride, aligned_height, format, padding); } else { +#ifdef MTK_MT8183 + /* + * JPEG Encoder Accelerator requires 16x16 alignment. We want the buffer + * from camera can be put in JEA directly so align the height to 16 + * bytes. + */ + if (format == DRM_FORMAT_NV12) + height = ALIGN(height, 16); +#endif drv_bo_from_format(bo, stride, height, format); } From e5c3fdf746e89d91abcde3bac2c4bb5f0f56a427 Mon Sep 17 00:00:00 2001 From: Fritz Koenig Date: Tue, 10 Dec 2019 16:30:34 -0800 Subject: [PATCH 173/269] msm: Add scanout support for UBWC RGB8888 msm hardware does not support UBWC RGB, only BGR. The creator and consumers know that UBWC buffers are hw native format. This is an opaque buffer that will not be accessed outside of the gpu. BUG=b:145579089 TEST=webgl aquarium goes to ubwc underlay Change-Id: I4872958d00e1de623b2a9692249e88e4aa302334 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1960784 Reviewed-by: Gurchetan Singh Tested-by: Fritz Koenig Commit-Queue: Fritz Koenig Auto-Submit: Fritz Koenig --- msm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/msm.c b/msm.c index 175d90f..dbc5b70 100644 --- a/msm.c +++ b/msm.c @@ -131,6 +131,8 @@ static bool is_ubwc_fmt(uint32_t format) switch (format) { case DRM_FORMAT_XBGR8888: case DRM_FORMAT_ABGR8888: + case DRM_FORMAT_XRGB8888: + case DRM_FORMAT_ARGB8888: case DRM_FORMAT_NV12: return 1; default: @@ -186,10 +188,10 @@ static int msm_init(struct driver *drv) texture_use_flags &= ~sw_flags; msm_add_ubwc_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &metadata, render_use_flags); + &metadata, render_use_flags | BO_USE_SCANOUT); msm_add_ubwc_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), - &metadata, texture_use_flags); + &metadata, texture_use_flags | BO_USE_SCANOUT); return 0; } From 9982421bb30e52b31e056711817cbbca3ad6a552 Mon Sep 17 00:00:00 2001 From: David Stevens Date: Wed, 25 Dec 2019 16:35:55 +0900 Subject: [PATCH 174/269] minigbm: align BO_USE flags with GBM flags Swap the values of the BO_USE encoder and decoder flags, to match the values of the respective GBM flags. BUG=none TEST=compile Change-Id: I419ca7b8234d4ce4e8a771ee608efac836b7d007 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1980687 Reviewed-by: Gurchetan Singh Tested-by: David Stevens Commit-Queue: David Stevens --- drv.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drv.h b/drv.h index d3cfb45..ab71a06 100644 --- a/drv.h +++ b/drv.h @@ -33,8 +33,8 @@ extern "C" { #define BO_USE_SW_READ_RARELY (1ull << 10) #define BO_USE_SW_WRITE_OFTEN (1ull << 11) #define BO_USE_SW_WRITE_RARELY (1ull << 12) -#define BO_USE_HW_VIDEO_ENCODER (1ull << 13) -#define BO_USE_HW_VIDEO_DECODER (1ull << 14) +#define BO_USE_HW_VIDEO_DECODER (1ull << 13) +#define BO_USE_HW_VIDEO_ENCODER (1ull << 14) #define BO_USE_RENDERSCRIPT (1ull << 15) /* Quirks for allocating a buffer. */ From 555ed2957179432ab8ab994e9bbe76cf4f001727 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Fri, 6 Dec 2019 09:11:53 -0800 Subject: [PATCH 175/269] minigbm: gbm.h sync gbm header First step to removing technical debt: sync header. This patch series is not bisectable. The header was copied from commit 1abca2b3c84a42ab64c466bc209db42c41bba5e3. BUG=b:145747113 TEST=emerge-nami minigbm Cq-Depend: chromium:1963000 Change-Id: Ic19a471887f57a46de75e71c3db4791d4ae9795d Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1963000 Tested-by: Gurchetan Singh Commit-Queue: Gurchetan Singh Reviewed-by: Kristian H. Kristensen Reviewed-by: Dominik Behr --- gbm.h | 192 ++++++++++++++++++++-------------------------------------- 1 file changed, 65 insertions(+), 127 deletions(-) diff --git a/gbm.h b/gbm.h index a2f10f6..45dead8 100644 --- a/gbm.h +++ b/gbm.h @@ -28,20 +28,16 @@ #ifndef _GBM_H_ #define _GBM_H_ -#ifdef __cplusplus -extern "C" { -#endif - - #define __GBM__ 1 -#ifndef MINIGBM -#define MINIGBM -#endif - #include #include +#ifdef __cplusplus +extern "C" { +#endif + + /** * \file gbm.h * \brief Generic Buffer Manager @@ -73,8 +69,20 @@ union gbm_bo_handle { uint64_t u64; }; -#define GBM_MAX_PLANES 4 +/** Format of the allocated buffer */ +enum gbm_bo_format { + /** RGB with 8 bits per channel in a 32 bit value */ + GBM_BO_FORMAT_XRGB8888, + /** ARGB with 8 bits per channel in a 32 bit value */ + GBM_BO_FORMAT_ARGB8888 +}; + +/** + * The FourCC format codes are taken from the drm_fourcc.h definition, and + * re-namespaced. New GBM formats must not be added, unless they are + * identical ports from drm_fourcc. + */ #define __gbm_fourcc_code(a,b,c,d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | \ ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24)) @@ -87,7 +95,6 @@ union gbm_bo_handle { #define GBM_FORMAT_R8 __gbm_fourcc_code('R', '8', ' ', ' ') /* [7:0] R */ /* 16 bpp RG */ -#define GBM_FORMAT_RG88 __gbm_fourcc_code('R', 'G', '8', '8') /* [15:0] R:G 8:8 little endian */ #define GBM_FORMAT_GR88 __gbm_fourcc_code('G', 'R', '8', '8') /* [15:0] G:R 8:8 little endian */ /* 8 bpp RGB */ @@ -143,6 +150,15 @@ union gbm_bo_handle { #define GBM_FORMAT_RGBA1010102 __gbm_fourcc_code('R', 'A', '3', '0') /* [31:0] R:G:B:A 10:10:10:2 little endian */ #define GBM_FORMAT_BGRA1010102 __gbm_fourcc_code('B', 'A', '3', '0') /* [31:0] B:G:R:A 10:10:10:2 little endian */ +/* + * Floating point 64bpp RGB + * IEEE 754-2008 binary16 half-precision float + * [15:0] sign:exponent:mantissa 1:5:10 + */ +#define GBM_FORMAT_XBGR16161616F __gbm_fourcc_code('X', 'B', '4', 'H') /* [63:0] x:B:G:R 16:16:16:16 little endian */ + +#define GBM_FORMAT_ABGR16161616F __gbm_fourcc_code('A', 'B', '4', 'H') /* [63:0] A:B:G:R 16:16:16:16 little endian */ + /* packed YCbCr */ #define GBM_FORMAT_YUYV __gbm_fourcc_code('Y', 'U', 'Y', 'V') /* [31:0] Cr0:Y1:Cb0:Y0 8:8:8:8 little endian */ #define GBM_FORMAT_YVYU __gbm_fourcc_code('Y', 'V', 'Y', 'U') /* [31:0] Cb0:Y1:Cr0:Y0 8:8:8:8 little endian */ @@ -183,28 +199,9 @@ union gbm_bo_handle { #define GBM_FORMAT_YUV444 __gbm_fourcc_code('Y', 'U', '2', '4') /* non-subsampled Cb (1) and Cr (2) planes */ #define GBM_FORMAT_YVU444 __gbm_fourcc_code('Y', 'V', '2', '4') /* non-subsampled Cr (1) and Cb (2) planes */ -/* - * Format Modifiers: - * - * Format modifiers describe, typically, a re-ordering or modification - * of the data in a plane of an FB. This can be used to express tiled/ - * swizzled formats, or compression, or a combination of the two. - * - * The upper 8 bits of the format modifier are a vendor-id as assigned - * below. The lower 56 bits are assigned as vendor sees fit. - */ - -/* Vendor Ids: */ -#define GBM_FORMAT_MOD_NONE 0 -#define GBM_FORMAT_MOD_VENDOR_INTEL 0x01 -#define GBM_FORMAT_MOD_VENDOR_AMD 0x02 -#define GBM_FORMAT_MOD_VENDOR_NV 0x03 -#define GBM_FORMAT_MOD_VENDOR_SAMSUNG 0x04 -#define GBM_FORMAT_MOD_VENDOR_QCOM 0x05 -/* add more to the end as needed */ - -#define gbm_fourcc_mod_code(vendor, val) \ - ((((__u64)GBM_FORMAT_MOD_VENDOR_## vendor) << 56) | (val & 0x00ffffffffffffffULL)) +struct gbm_format_name_desc { + char name[5]; +}; /** * Flags to indicate the intended use for the buffer - these are passed into @@ -233,50 +230,14 @@ enum gbm_bo_flags { */ GBM_BO_USE_RENDERING = (1 << 2), /** - * Deprecated + * Buffer can be used for gbm_bo_write. This is guaranteed to work + * with GBM_BO_USE_CURSOR, but may not work for other combinations. */ GBM_BO_USE_WRITE = (1 << 3), /** - * 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. This is intended to be used with buffers that will be accessed - * via dma-buf mmap(). - */ - GBM_BO_USE_LINEAR = (1 << 4), - /** - * The buffer will be used as a texture that will be sampled from. - */ - GBM_BO_USE_TEXTURING = (1 << 5), - /** - * The buffer will be written to by a camera subsystem. - */ - GBM_BO_USE_CAMERA_WRITE = (1 << 6), - /** - * The buffer will be read from by a camera subsystem. + * Buffer is linear, i.e. not tiled. */ - 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), - /** - * The buffer will be written by a video decode accelerator. - */ - GBM_BO_USE_HW_VIDEO_DECODER = (1 << 13), - /** - * The buffer will be read by a video encode accelerator. - */ - GBM_BO_USE_HW_VIDEO_ENCODER = (1 << 14), + GBM_BO_USE_LINEAR = (1 << 4), }; int @@ -289,6 +250,11 @@ int gbm_device_is_format_supported(struct gbm_device *gbm, uint32_t format, uint32_t usage); +int +gbm_device_get_format_modifier_plane_count(struct gbm_device *gbm, + uint32_t format, + uint64_t modifier); + void gbm_device_destroy(struct gbm_device *gbm); @@ -304,14 +270,12 @@ struct gbm_bo * gbm_bo_create_with_modifiers(struct gbm_device *gbm, uint32_t width, uint32_t height, uint32_t format, - const uint64_t *modifiers, uint32_t count); - + const uint64_t *modifiers, + const unsigned int count); #define GBM_BO_IMPORT_WL_BUFFER 0x5501 #define GBM_BO_IMPORT_EGL_IMAGE 0x5502 #define GBM_BO_IMPORT_FD 0x5503 -// Deprecated. Use GBM_BO_IMPORT_FD_MODIFIER instead. -#define GBM_BO_IMPORT_FD_PLANAR 0x5504 -#define GBM_BO_IMPORT_FD_MODIFIER 0x5505 +#define GBM_BO_IMPORT_FD_MODIFIER 0x5504 struct gbm_import_fd_data { int fd; @@ -321,6 +285,8 @@ struct gbm_import_fd_data { uint32_t format; }; +#define GBM_MAX_PLANES 4 + struct gbm_import_fd_modifier_data { uint32_t width; uint32_t height; @@ -332,17 +298,6 @@ struct gbm_import_fd_modifier_data { uint64_t modifier; }; -// Deprecated. Use gbm_import_fd_modifier_data instead. -struct gbm_import_fd_planar_data { - int fds[GBM_MAX_PLANES]; - uint32_t width; - uint32_t height; - uint32_t format; - uint32_t strides[GBM_MAX_PLANES]; - uint32_t offsets[GBM_MAX_PLANES]; - uint64_t format_modifiers[GBM_MAX_PLANES]; -}; - struct gbm_bo * gbm_bo_import(struct gbm_device *gbm, uint32_t type, void *buffer, uint32_t usage); @@ -377,7 +332,7 @@ enum gbm_bo_transfer_flags { 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 flags, uint32_t *stride, void **map_data); void gbm_bo_unmap(struct gbm_bo *bo, void *map_data); @@ -391,19 +346,17 @@ gbm_bo_get_height(struct gbm_bo *bo); uint32_t gbm_bo_get_stride(struct gbm_bo *bo); -/* Tegra bringup hack to pass tiling parameters at EGLImage creation. */ uint32_t -gbm_bo_get_stride_or_tiling(struct gbm_bo *bo); +gbm_bo_get_stride_for_plane(struct gbm_bo *bo, int plane); uint32_t gbm_bo_get_format(struct gbm_bo *bo); -/* Deprecated */ -uint64_t -gbm_bo_get_format_modifier(struct gbm_bo *bo); +uint32_t +gbm_bo_get_bpp(struct gbm_bo *bo); -uint64_t -gbm_bo_get_modifier(struct gbm_bo *bo); +uint32_t +gbm_bo_get_offset(struct gbm_bo *bo, int plane); struct gbm_device * gbm_bo_get_device(struct gbm_bo *bo); @@ -414,42 +367,17 @@ gbm_bo_get_handle(struct gbm_bo *bo); int gbm_bo_get_fd(struct gbm_bo *bo); -/* Deprecated */ -size_t -gbm_bo_get_num_planes(struct gbm_bo *bo); +uint64_t +gbm_bo_get_modifier(struct gbm_bo *bo); -size_t +int gbm_bo_get_plane_count(struct gbm_bo *bo); -/* Deprecated */ union gbm_bo_handle -gbm_bo_get_plane_handle(struct gbm_bo *bo, size_t plane); - -union gbm_bo_handle -gbm_bo_get_handle_for_plane(struct gbm_bo* bo, size_t plane); +gbm_bo_get_handle_for_plane(struct gbm_bo *bo, int plane); int -gbm_bo_get_plane_fd(struct gbm_bo *bo, size_t plane); - -/* Deprecated */ -uint32_t -gbm_bo_get_plane_offset(struct gbm_bo *bo, size_t plane); - -uint32_t -gbm_bo_get_offset(struct gbm_bo *bo, size_t plane); - -uint32_t -gbm_bo_get_plane_size(struct gbm_bo *bo, size_t plane); - -/* Deprecated */ -uint32_t -gbm_bo_get_plane_stride(struct gbm_bo *bo, size_t plane); - -uint32_t -gbm_bo_get_stride_for_plane(struct gbm_bo *bo, size_t plane); - -uint64_t -gbm_bo_get_plane_format_modifier(struct gbm_bo *bo, size_t plane); +gbm_bo_write(struct gbm_bo *bo, const void *buf, size_t count); void gbm_bo_set_user_data(struct gbm_bo *bo, void *data, @@ -466,6 +394,13 @@ gbm_surface_create(struct gbm_device *gbm, uint32_t width, uint32_t height, uint32_t format, uint32_t flags); +struct gbm_surface * +gbm_surface_create_with_modifiers(struct gbm_device *gbm, + uint32_t width, uint32_t height, + uint32_t format, + const uint64_t *modifiers, + const unsigned int count); + struct gbm_bo * gbm_surface_lock_front_buffer(struct gbm_surface *surface); @@ -478,6 +413,9 @@ gbm_surface_has_free_buffers(struct gbm_surface *surface); void gbm_surface_destroy(struct gbm_surface *surface); +char * +gbm_format_get_name(uint32_t gbm_format, struct gbm_format_name_desc *desc); + #ifdef __cplusplus } #endif From e32ec0be673a4c6638fbd8fee6e9c1c1494cd7a3 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Fri, 6 Dec 2019 09:52:03 -0800 Subject: [PATCH 176/269] minigbm: gbm.h: organize our downstream patches This patch series is not bisectable. BUG=b:145747113 TEST=compile Change-Id: I447e554f27e55e43a4f5d3ca8f1725eda46852fd Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1963001 Reviewed-by: Gurchetan Singh Tested-by: Gurchetan Singh Commit-Queue: Gurchetan Singh --- drv.c | 5 --- drv.h | 2 - gbm.c | 141 ++++++++++++++++++++++++---------------------------------- gbm.h | 83 ++++++++++++++++++++++++++++++---- 4 files changed, 131 insertions(+), 100 deletions(-) diff --git a/drv.c b/drv.c index 872b5d4..7f64188 100644 --- a/drv.c +++ b/drv.c @@ -542,11 +542,6 @@ uint32_t drv_bo_get_height(struct bo *bo) return bo->meta.height; } -uint32_t drv_bo_get_stride_or_tiling(struct bo *bo) -{ - return bo->meta.tiling ? bo->meta.tiling : drv_bo_get_plane_stride(bo, 0); -} - size_t drv_bo_get_num_planes(struct bo *bo) { return bo->meta.num_planes; diff --git a/drv.h b/drv.h index ab71a06..39fd5dd 100644 --- a/drv.h +++ b/drv.h @@ -149,8 +149,6 @@ uint32_t drv_bo_get_width(struct bo *bo); uint32_t drv_bo_get_height(struct bo *bo); -uint32_t drv_bo_get_stride_or_tiling(struct bo *bo); - size_t drv_bo_get_num_planes(struct bo *bo); union bo_handle drv_bo_get_plane_handle(struct bo *bo, size_t plane); diff --git a/gbm.c b/gbm.c index 8db622b..d46d212 100644 --- a/gbm.c +++ b/gbm.c @@ -174,7 +174,6 @@ PUBLIC struct gbm_bo *gbm_bo_import(struct gbm_device *gbm, uint32_t type, void struct gbm_bo *bo; struct drv_import_fd_data drv_data; struct gbm_import_fd_data *fd_data = buffer; - struct gbm_import_fd_planar_data *fd_planar_data = buffer; struct gbm_import_fd_modifier_data *fd_modifier_data = buffer; uint32_t gbm_format; size_t num_planes, i, num_fds; @@ -212,26 +211,6 @@ PUBLIC struct gbm_bo *gbm_bo_import(struct gbm_device *gbm, uint32_t type, void drv_data.format_modifiers[i] = fd_modifier_data->modifier; } - for (i = num_planes; i < GBM_MAX_PLANES; i++) - drv_data.fds[i] = -1; - - break; - case GBM_BO_IMPORT_FD_PLANAR: - gbm_format = fd_planar_data->format; - drv_data.width = fd_planar_data->width; - drv_data.height = fd_planar_data->height; - drv_data.format = fd_planar_data->format; - num_planes = drv_num_planes_from_format(drv_data.format); - - assert(num_planes); - - for (i = 0; i < num_planes; i++) { - drv_data.fds[i] = fd_planar_data->fds[i]; - 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]; - } - for (i = num_planes; i < GBM_MAX_PLANES; i++) drv_data.fds[i] = -1; @@ -258,30 +237,6 @@ PUBLIC struct gbm_bo *gbm_bo_import(struct gbm_device *gbm, uint32_t type, void return bo; } -PUBLIC void *gbm_bo_map(struct gbm_bo *bo, uint32_t x, uint32_t y, uint32_t width, uint32_t height, - 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; - - 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; - - *stride = ((struct mapping *)*map_data)->vma->map_strides[plane]; - - offset = *stride * rect.y; - offset += rect.x * drv_bytes_per_pixel_from_format(bo->gbm_format, plane); - return (void *)((uint8_t *)addr + offset); -} - PUBLIC void gbm_bo_unmap(struct gbm_bo *bo, void *map_data) { assert(bo); @@ -303,24 +258,14 @@ PUBLIC uint32_t gbm_bo_get_stride(struct gbm_bo *bo) return gbm_bo_get_stride_for_plane(bo, 0); } -PUBLIC uint32_t gbm_bo_get_stride_or_tiling(struct gbm_bo *bo) -{ - return drv_bo_get_stride_or_tiling(bo->bo); -} - PUBLIC uint32_t gbm_bo_get_format(struct gbm_bo *bo) { return bo->gbm_format; } -PUBLIC uint64_t gbm_bo_get_format_modifier(struct gbm_bo *bo) -{ - return gbm_bo_get_modifier(bo); -} - PUBLIC uint64_t gbm_bo_get_modifier(struct gbm_bo *bo) { - return gbm_bo_get_plane_format_modifier(bo, 0); + return drv_bo_get_plane_format_modifier(bo->bo, 0); } PUBLIC struct gbm_device *gbm_bo_get_device(struct gbm_bo *bo) @@ -338,69 +283,97 @@ PUBLIC int gbm_bo_get_fd(struct gbm_bo *bo) return gbm_bo_get_plane_fd(bo, 0); } -PUBLIC size_t gbm_bo_get_num_planes(struct gbm_bo *bo) -{ - return gbm_bo_get_plane_count(bo); -} - -PUBLIC size_t gbm_bo_get_plane_count(struct gbm_bo *bo) +PUBLIC int gbm_bo_get_plane_count(struct gbm_bo *bo) { return drv_bo_get_num_planes(bo->bo); } -PUBLIC union gbm_bo_handle gbm_bo_get_plane_handle(struct gbm_bo *bo, size_t plane) +PUBLIC union gbm_bo_handle gbm_bo_get_handle_for_plane(struct gbm_bo *bo, size_t plane) { - return gbm_bo_get_handle_for_plane(bo, plane); + return (union gbm_bo_handle)drv_bo_get_plane_handle(bo->bo, (size_t)plane).u64; } -PUBLIC union gbm_bo_handle gbm_bo_get_handle_for_plane(struct gbm_bo *bo, size_t plane) +PUBLIC uint32_t gbm_bo_get_offset(struct gbm_bo *bo, size_t plane) { - return (union gbm_bo_handle)drv_bo_get_plane_handle(bo->bo, plane).u64; + return drv_bo_get_plane_offset(bo->bo, (size_t)plane); } -PUBLIC int gbm_bo_get_plane_fd(struct gbm_bo *bo, size_t plane) +PUBLIC uint32_t gbm_bo_get_stride_for_plane(struct gbm_bo *bo, size_t plane) { - return drv_bo_get_plane_fd(bo->bo, plane); + return drv_bo_get_plane_stride(bo->bo, (size_t)plane); } -PUBLIC uint32_t gbm_bo_get_plane_offset(struct gbm_bo *bo, size_t plane) +PUBLIC void gbm_bo_set_user_data(struct gbm_bo *bo, void *data, + void (*destroy_user_data)(struct gbm_bo *, void *)) { - return gbm_bo_get_offset(bo, plane); + bo->user_data = data; + bo->destroy_user_data = destroy_user_data; } -PUBLIC uint32_t gbm_bo_get_offset(struct gbm_bo *bo, size_t plane) +PUBLIC void *gbm_bo_get_user_data(struct gbm_bo *bo) { - return drv_bo_get_plane_offset(bo->bo, plane); + return bo->user_data; } +/* + * The following functions are not deprecated, but not in the Mesa the gbm + * header. The main difference is minigbm allows for the possibility of + * disjoint YUV images, while Mesa GBM does not. + */ PUBLIC uint32_t gbm_bo_get_plane_size(struct gbm_bo *bo, size_t plane) { return drv_bo_get_plane_size(bo->bo, plane); } -PUBLIC uint32_t gbm_bo_get_plane_stride(struct gbm_bo *bo, size_t plane) +PUBLIC int gbm_bo_get_plane_fd(struct gbm_bo *bo, size_t plane) { - return gbm_bo_get_stride_for_plane(bo, plane); + return drv_bo_get_plane_fd(bo->bo, plane); } -PUBLIC uint32_t gbm_bo_get_stride_for_plane(struct gbm_bo *bo, size_t plane) +PUBLIC void *gbm_bo_map(struct gbm_bo *bo, uint32_t x, uint32_t y, uint32_t width, uint32_t height, + uint32_t transfer_flags, uint32_t *stride, void **map_data, size_t plane) { - return drv_bo_get_plane_stride(bo->bo, plane); + void *addr; + off_t offset; + uint32_t map_flags; + plane = (size_t)plane; + struct rectangle rect = { .x = x, .y = y, .width = width, .height = height }; + if (!bo || width == 0 || height == 0 || !stride || !map_data) + return NULL; + + 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; + + *stride = ((struct mapping *)*map_data)->vma->map_strides[plane]; + + offset = *stride * rect.y; + offset += rect.x * drv_bytes_per_pixel_from_format(bo->gbm_format, plane); + return (void *)((uint8_t *)addr + offset); } -PUBLIC uint64_t gbm_bo_get_plane_format_modifier(struct gbm_bo *bo, size_t plane) +/* + * The following functions are deprecated. They can be removed * once crbug.com/946907 is fixed. + */ +PUBLIC size_t gbm_bo_get_num_planes(struct gbm_bo *bo) { - return drv_bo_get_plane_format_modifier(bo->bo, plane); + return gbm_bo_get_plane_count(bo); } -PUBLIC void gbm_bo_set_user_data(struct gbm_bo *bo, void *data, - void (*destroy_user_data)(struct gbm_bo *, void *)) +PUBLIC union gbm_bo_handle gbm_bo_get_plane_handle(struct gbm_bo *bo, size_t plane) { - bo->user_data = data; - bo->destroy_user_data = destroy_user_data; + return gbm_bo_get_handle_for_plane(bo, plane); } -PUBLIC void *gbm_bo_get_user_data(struct gbm_bo *bo) +PUBLIC uint32_t gbm_bo_get_plane_offset(struct gbm_bo *bo, size_t plane) { - return bo->user_data; + return gbm_bo_get_offset(bo, plane); +} + +PUBLIC uint32_t gbm_bo_get_plane_stride(struct gbm_bo *bo, size_t plane) +{ + return gbm_bo_get_stride_for_plane(bo, plane); } diff --git a/gbm.h b/gbm.h index 45dead8..d313865 100644 --- a/gbm.h +++ b/gbm.h @@ -238,6 +238,39 @@ enum gbm_bo_flags { * Buffer is linear, i.e. not tiled. */ GBM_BO_USE_LINEAR = (1 << 4), + /** + * The buffer will be used as a texture that will be sampled from. + */ + GBM_BO_USE_TEXTURING = (1 << 5), + /** + * The buffer will be written to by a camera subsystem. + */ + GBM_BO_USE_CAMERA_WRITE = (1 << 6), + /** + * 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), + /** + * The buffer will be written by a video decode accelerator. + */ + GBM_BO_USE_HW_VIDEO_DECODER = (1 << 13), + /** + * The buffer will be read by a video encode accelerator. + */ + GBM_BO_USE_HW_VIDEO_ENCODER = (1 << 14), }; int @@ -275,7 +308,9 @@ gbm_bo_create_with_modifiers(struct gbm_device *gbm, #define GBM_BO_IMPORT_WL_BUFFER 0x5501 #define GBM_BO_IMPORT_EGL_IMAGE 0x5502 #define GBM_BO_IMPORT_FD 0x5503 -#define GBM_BO_IMPORT_FD_MODIFIER 0x5504 +// Deprecated. Use GBM_BO_IMPORT_FD_MODIFIER instead. +#define GBM_BO_IMPORT_FD_PLANAR 0x5504 +#define GBM_BO_IMPORT_FD_MODIFIER 0x5505 struct gbm_import_fd_data { int fd; @@ -329,11 +364,6 @@ enum gbm_bo_transfer_flags { GBM_BO_TRANSFER_READ_WRITE = (GBM_BO_TRANSFER_READ | GBM_BO_TRANSFER_WRITE), }; -void * -gbm_bo_map(struct gbm_bo *bo, - uint32_t x, uint32_t y, uint32_t width, uint32_t height, - uint32_t flags, uint32_t *stride, void **map_data); - void gbm_bo_unmap(struct gbm_bo *bo, void *map_data); @@ -347,7 +377,7 @@ uint32_t gbm_bo_get_stride(struct gbm_bo *bo); uint32_t -gbm_bo_get_stride_for_plane(struct gbm_bo *bo, int plane); +gbm_bo_get_stride_for_plane(struct gbm_bo *bo, size_t plane); uint32_t gbm_bo_get_format(struct gbm_bo *bo); @@ -356,7 +386,7 @@ uint32_t gbm_bo_get_bpp(struct gbm_bo *bo); uint32_t -gbm_bo_get_offset(struct gbm_bo *bo, int plane); +gbm_bo_get_offset(struct gbm_bo *bo, size_t plane); struct gbm_device * gbm_bo_get_device(struct gbm_bo *bo); @@ -374,7 +404,7 @@ int gbm_bo_get_plane_count(struct gbm_bo *bo); union gbm_bo_handle -gbm_bo_get_handle_for_plane(struct gbm_bo *bo, int plane); +gbm_bo_get_handle_for_plane(struct gbm_bo *bo, size_t plane); int gbm_bo_write(struct gbm_bo *bo, const void *buf, size_t count); @@ -416,6 +446,41 @@ gbm_surface_destroy(struct gbm_surface *surface); char * gbm_format_get_name(uint32_t gbm_format, struct gbm_format_name_desc *desc); + +#ifndef MINIGBM +#define MINIGBM +#endif +/* + * The following functions are not deprecated, but not in the Mesa the gbm + * header. The main difference is minigbm allows for the possibility of + * disjoint YUV images, while Mesa GBM does not. + */ +uint32_t +gbm_bo_get_plane_size(struct gbm_bo *bo, size_t plane); + +int +gbm_bo_get_plane_fd(struct gbm_bo *bo, size_t plane); + +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); + +/* + * The following functions are deprecated. They can be removed * once crbug.com/946907 is fixed. + */ +size_t +gbm_bo_get_num_planes(struct gbm_bo *bo); + +union gbm_bo_handle +gbm_bo_get_plane_handle(struct gbm_bo *bo, size_t plane); + +uint32_t +gbm_bo_get_plane_offset(struct gbm_bo *bo, size_t plane); + +uint32_t +gbm_bo_get_plane_stride(struct gbm_bo *bo, size_t plane); + #ifdef __cplusplus } #endif From 1cfdc31d8142bb2c2d917139948f190e26a8173f Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Fri, 6 Dec 2019 10:24:53 -0800 Subject: [PATCH 177/269] minigbm: implement new functions These functions were newly added -- implement some, don't implement surface functions. This patch series is not bisectable. BUG=b:145747113 TEST=emerge-nami minigbm Cq-Depend: chromium:1963000 Change-Id: I36814955b754840daab31fa2762910aa44e80fd8 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1963002 Tested-by: Gurchetan Singh Commit-Queue: Gurchetan Singh Reviewed-by: Kristian H. Kristensen Reviewed-by: Dominik Behr --- gbm.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/gbm.c b/gbm.c index d46d212..4f9c34b 100644 --- a/gbm.c +++ b/gbm.c @@ -41,6 +41,12 @@ PUBLIC int gbm_device_is_format_supported(struct gbm_device *gbm, uint32_t forma return (drv_get_combination(gbm->drv, format, use_flags) != NULL); } +PUBLIC int gbm_device_get_format_modifier_plane_count(struct gbm_device *gbm, uint32_t format, + uint64_t modifier) +{ + return 0; +} + PUBLIC struct gbm_device *gbm_create_device(int fd) { struct gbm_device *gbm; @@ -76,9 +82,15 @@ PUBLIC struct gbm_surface *gbm_surface_create(struct gbm_device *gbm, uint32_t w return surface; } -PUBLIC void gbm_surface_destroy(struct gbm_surface *surface) +PUBLIC struct gbm_surface *gbm_surface_create_with_modifiers(struct gbm_device *gbm, uint32_t width, + uint32_t height, uint32_t format, + const uint64_t *modifiers, + const unsigned int count) { - free(surface); + if (count != 0 || modifiers != NULL) + return NULL; + + return gbm_surface_create(gbm, width, height, format, 0); } PUBLIC struct gbm_bo *gbm_surface_lock_front_buffer(struct gbm_surface *surface) @@ -90,6 +102,16 @@ PUBLIC void gbm_surface_release_buffer(struct gbm_surface *surface, struct gbm_b { } +PUBLIC int gbm_surface_has_free_buffers(struct gbm_surface *surface) +{ + return 0; +} + +PUBLIC void gbm_surface_destroy(struct gbm_surface *surface) +{ + free(surface); +} + static struct gbm_bo *gbm_bo_new(struct gbm_device *gbm, uint32_t format) { struct gbm_bo *bo; @@ -263,6 +285,11 @@ PUBLIC uint32_t gbm_bo_get_format(struct gbm_bo *bo) return bo->gbm_format; } +PUBLIC uint32_t gbm_bo_get_bpp(struct gbm_bo *bo) +{ + return drv_bytes_per_pixel_from_format(drv_bo_get_format(bo->bo), 0); +} + PUBLIC uint64_t gbm_bo_get_modifier(struct gbm_bo *bo) { return drv_bo_get_plane_format_modifier(bo->bo, 0); @@ -315,6 +342,38 @@ PUBLIC void *gbm_bo_get_user_data(struct gbm_bo *bo) return bo->user_data; } +/* The two GBM_BO_FORMAT_[XA]RGB8888 formats alias the GBM_FORMAT_* + * formats of the same name. We want to accept them whenever someone + * has a GBM format, but never return them to the user. + */ +static uint32_t gbm_format_canonicalize(uint32_t gbm_format) +{ + switch (gbm_format) { + case GBM_BO_FORMAT_XRGB8888: + return GBM_FORMAT_XRGB8888; + case GBM_BO_FORMAT_ARGB8888: + return GBM_FORMAT_ARGB8888; + default: + return gbm_format; + } +} + +/** + * Returns a string representing the fourcc format name. + */ +PUBLIC char *gbm_format_get_name(uint32_t gbm_format, struct gbm_format_name_desc *desc) +{ + gbm_format = gbm_format_canonicalize(gbm_format); + + desc->name[0] = gbm_format; + desc->name[1] = gbm_format >> 8; + desc->name[2] = gbm_format >> 16; + desc->name[3] = gbm_format >> 24; + desc->name[4] = 0; + + return desc->name; +} + /* * The following functions are not deprecated, but not in the Mesa the gbm * header. The main difference is minigbm allows for the possibility of From 064a36b45cdce8e67893787ab19d59d10946f4dc Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Thu, 12 Dec 2019 10:20:41 -0800 Subject: [PATCH 178/269] minigbm: add gbm_bo_map2 Plan is convert all users to gbm_bo_map2, and then make gbm_bo_map follow the upstream convention. BUG=b:145747350 TEST=emerge-nami minigbm Change-Id: I7c7d54d519277e21ebfa99c57d9a738e9d257a57 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1965671 Tested-by: Gurchetan Singh Commit-Queue: Gurchetan Singh Reviewed-by: Gurchetan Singh --- gbm.c | 6 ++++++ gbm.h | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/gbm.c b/gbm.c index 4f9c34b..f23a867 100644 --- a/gbm.c +++ b/gbm.c @@ -391,6 +391,12 @@ PUBLIC int gbm_bo_get_plane_fd(struct gbm_bo *bo, size_t plane) PUBLIC void *gbm_bo_map(struct gbm_bo *bo, uint32_t x, uint32_t y, uint32_t width, uint32_t height, uint32_t transfer_flags, uint32_t *stride, void **map_data, size_t plane) +{ + return gbm_bo_map2(bo, x, y, width, height, transfer_flags, stride, map_data, plane); +} + +PUBLIC void *gbm_bo_map2(struct gbm_bo *bo, uint32_t x, uint32_t y, uint32_t width, uint32_t height, + uint32_t transfer_flags, uint32_t *stride, void **map_data, int plane) { void *addr; off_t offset; diff --git a/gbm.h b/gbm.h index d313865..e341c40 100644 --- a/gbm.h +++ b/gbm.h @@ -465,6 +465,10 @@ 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); +void * +gbm_bo_map2(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, int plane); /* * The following functions are deprecated. They can be removed * once crbug.com/946907 is fixed. From 785a54858931bc023f19c32b197a6f7f6378e2a5 Mon Sep 17 00:00:00 2001 From: Hirokazu Honda Date: Tue, 14 Jan 2020 04:08:12 +0000 Subject: [PATCH 179/269] rockchip: align height in NV12 format This reverts commit b80c6b9737dc22e7b71ca684fa85e51953465512. Thanks to crrev.com/c/1909686, camera HAL on scarlet can fill camera content with arbitrary offsets. Remove the workaround introduced in b80c6b9737dc22e7b71ca684fa85e51953465512. BUG=b:140152839 TEST=GCA on scarlet TEST=CCA on scarlet Cq-Depend: chromium:1906454 Change-Id: I6782e713b8f5dd57c5cdf6d1217adc9f73b61ac3 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1999866 Reviewed-by: Gurchetan Singh Commit-Queue: Hirokazu Honda Tested-by: Hirokazu Honda Auto-Submit: Hirokazu Honda --- rockchip.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/rockchip.c b/rockchip.c index 43cbfe2..698f85b 100644 --- a/rockchip.c +++ b/rockchip.c @@ -172,10 +172,9 @@ static int rockchip_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint uint32_t h_mbs = DIV_ROUND_UP(height, 16); uint32_t aligned_width = w_mbs * 16; + uint32_t aligned_height = h_mbs * 16; - // TODO(b/140152839): Align height by 16 once camera HAL - // supports multi planar format. - drv_bo_from_format(bo, aligned_width, height, format); + drv_bo_from_format(bo, aligned_width, aligned_height, format); /* * drv_bo_from_format updates total_size. Add an extra data space for rockchip video * driver to store motion vectors. From cf9ed9dc8e481485054616cfd5e06db530b54afd Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Fri, 13 Dec 2019 09:37:01 -0800 Subject: [PATCH 180/269] amdgpu: make libdir work on stock Linux BUG=b:145747113 TEST=emerge-grunt minigbm Cq-Depend: chromium:1967711 Change-Id: I10e721ffcbe8e36551269cf54e981be411389eaf Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1967731 Tested-by: Gurchetan Singh Commit-Queue: Gurchetan Singh Reviewed-by: Gurchetan Singh --- amdgpu.c | 4 +++- util.h | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/amdgpu.c b/amdgpu.c index 436b892..2654f9a 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -21,7 +21,9 @@ #ifdef __ANDROID__ #define DRI_PATH "/vendor/lib/dri/radeonsi_dri.so" #else -#define DRI_PATH "/usr/lib64/dri/radeonsi_dri.so" +// clang-format off +#define DRI_PATH STRINGIZE(DRI_DRIVER_DIR/radeonsi_dri.so) +// clang-format on #endif #define TILE_TYPE_LINEAR 0 diff --git a/util.h b/util.h index e4e1399..8f8bb0d 100644 --- a/util.h +++ b/util.h @@ -13,5 +13,7 @@ #define ALIGN(A, B) (((A) + (B)-1) & ~((B)-1)) #define IS_ALIGNED(A, B) (ALIGN((A), (B)) == (A)) #define DIV_ROUND_UP(n, d) (((n) + (d)-1) / (d)) +#define STRINGIZE_NO_EXPANSION(x) #x +#define STRINGIZE(x) STRINGIZE_NO_EXPANSION(x) #endif From 706cd467069cedcb532d440a865fb90040fe7bfd Mon Sep 17 00:00:00 2001 From: Maksim Sisov Date: Wed, 6 Mar 2019 13:04:12 +0200 Subject: [PATCH 181/269] minigbm: Remove deprecated methods. We have been running an effort to align minigbm apis with the upstream libgbm. The clients of minigbm are fixed, and the deprecated methods can be removed now. Change-Id: I09043ef5728af36298e3331c6694fde656b0d7e1 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1505613 Tested-by: Gurchetan Singh Commit-Queue: Gurchetan Singh Reviewed-by: Gurchetan Singh --- gbm.c | 23 ----------------------- gbm.h | 15 --------------- 2 files changed, 38 deletions(-) diff --git a/gbm.c b/gbm.c index f23a867..4b62bbf 100644 --- a/gbm.c +++ b/gbm.c @@ -419,26 +419,3 @@ PUBLIC void *gbm_bo_map2(struct gbm_bo *bo, uint32_t x, uint32_t y, uint32_t wid offset += rect.x * drv_bytes_per_pixel_from_format(bo->gbm_format, plane); return (void *)((uint8_t *)addr + offset); } - -/* - * The following functions are deprecated. They can be removed * once crbug.com/946907 is fixed. - */ -PUBLIC size_t gbm_bo_get_num_planes(struct gbm_bo *bo) -{ - return gbm_bo_get_plane_count(bo); -} - -PUBLIC union gbm_bo_handle gbm_bo_get_plane_handle(struct gbm_bo *bo, size_t plane) -{ - return gbm_bo_get_handle_for_plane(bo, plane); -} - -PUBLIC uint32_t gbm_bo_get_plane_offset(struct gbm_bo *bo, size_t plane) -{ - return gbm_bo_get_offset(bo, plane); -} - -PUBLIC uint32_t gbm_bo_get_plane_stride(struct gbm_bo *bo, size_t plane) -{ - return gbm_bo_get_stride_for_plane(bo, plane); -} diff --git a/gbm.h b/gbm.h index e341c40..4993b5c 100644 --- a/gbm.h +++ b/gbm.h @@ -470,21 +470,6 @@ gbm_bo_map2(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, int plane); -/* - * The following functions are deprecated. They can be removed * once crbug.com/946907 is fixed. - */ -size_t -gbm_bo_get_num_planes(struct gbm_bo *bo); - -union gbm_bo_handle -gbm_bo_get_plane_handle(struct gbm_bo *bo, size_t plane); - -uint32_t -gbm_bo_get_plane_offset(struct gbm_bo *bo, size_t plane); - -uint32_t -gbm_bo_get_plane_stride(struct gbm_bo *bo, size_t plane); - #ifdef __cplusplus } #endif From 9d20b9e3887d67b069b58b37d795d6b857ec5371 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Thu, 19 Dec 2019 09:48:21 -0800 Subject: [PATCH 182/269] minigbm: i915: get rid of tileable texture formats I don't think Chrome ever used DRM_FORMAT_UYVY + DRM_FORMAT_YUYV. Plus, R8 tiled isn't really useful. BUG=b:145747113 TEST=compile Change-Id: I30bc3d966cc935dab725f96d39d86629436f5640 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1976273 Tested-by: Gurchetan Singh Reviewed-by: Gurchetan Singh Reviewed-by: Kristian H. Kristensen Commit-Queue: Gurchetan Singh --- i915.c | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/i915.c b/i915.c index 025b6b5..925eba3 100644 --- a/i915.c +++ b/i915.c @@ -24,17 +24,13 @@ #define I915_CACHELINE_MASK (I915_CACHELINE_SIZE - 1) static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR16161616F, DRM_FORMAT_ABGR2101010, - DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB1555, - DRM_FORMAT_ARGB2101010, DRM_FORMAT_ARGB8888, - DRM_FORMAT_RGB565, DRM_FORMAT_XBGR2101010, - DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB1555, + DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB2101010, + DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB565, + DRM_FORMAT_XBGR2101010, DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB2101010, DRM_FORMAT_XRGB8888 }; -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, - DRM_FORMAT_NV12, DRM_FORMAT_P010 }; +static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_NV12, DRM_FORMAT_P010, + DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID }; struct i915_device { uint32_t gen; @@ -139,10 +135,6 @@ static int i915_add_combinations(struct driver *drv) drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), &metadata, texture_use_flags); - drv_add_combinations(drv, tileable_texture_source_formats, - ARRAY_SIZE(tileable_texture_source_formats), &metadata, - texture_use_flags); - /* * Chrome uses DMA-buf mmap to write to YV12 buffers, which are then accessed by the * Video Encoder Accelerator (VEA). It could also support NV12 potentially in the future. @@ -186,10 +178,6 @@ static int i915_add_combinations(struct driver *drv) drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), &metadata, render_use_flags); - 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; @@ -197,10 +185,6 @@ static int i915_add_combinations(struct driver *drv) drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), &metadata, render_use_flags); - drv_add_combinations(drv, tileable_texture_source_formats, - ARRAY_SIZE(tileable_texture_source_formats), &metadata, - texture_use_flags); - /* Support y-tiled NV12 and P010 for libva */ drv_add_combination(drv, DRM_FORMAT_NV12, &metadata, BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER); From fbfb338e7db246f05ae68da97141fbd49481584b Mon Sep 17 00:00:00 2001 From: Woody Chow Date: Fri, 17 Jan 2020 16:46:33 +0900 Subject: [PATCH 183/269] Remove level=stride hack in virtio_gpu_bo_invalidate The non-gbm path in virglrenderer does not need this hack BUG=b:142364535 TEST=Run these CTS tests android.hardware.nativehardware.cts.AHardwareBufferNativeTests#SingleLayer_ColorTest_GpuColorOutputCpuRead_R8G8B8A8_UNORM android.hardware.nativehardware.cts.AHardwareBufferNativeTests#SingleLayer_ColorTest_GpuColorOutputCpuRead_R8G8B8X8_UNORM android.hardware.nativehardware.cts.AHardwareBufferNativeTests#SingleLayer_ColorTest_GpuColorOutputCpuRead_R5G6B5_UNORM Change-Id: I672dcec7e3bb5d9e6841e6ea48f56f26a4130df2 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2007028 Reviewed-by: Gurchetan Singh Tested-by: Woody Chow Commit-Queue: Woody Chow --- virtio_gpu.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/virtio_gpu.c b/virtio_gpu.c index 50ca997..1eeba26 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -292,10 +292,8 @@ static int virtio_gpu_bo_invalidate(struct bo *bo, struct mapping *mapping) xfer.box.h = mapping->rect.height; xfer.box.d = 1; - // Unfortunately, the kernel doesn't actually pass the guest layer_stride and - // guest stride to the host (compare virtio_gpu.h and virtgpu_drm.h). We can use - // the level to work around this. - xfer.level = bo->meta.strides[0]; + // TODO(b/145993887): Send also stride when the patches are landed + // When BO_USE_RENDERING is set, the level=stride hack is not needed ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST, &xfer); if (ret) { From d441f4ec3366202ccf35d0bb8d6b0c246cc2d5e9 Mon Sep 17 00:00:00 2001 From: Junichi Uekawa Date: Wed, 29 Jan 2020 15:45:16 +0900 Subject: [PATCH 184/269] minigbm: Reformat with clang-format. Touching the files seem to cause reformatting. BUG=None TEST=None Change-Id: I31d2fbb01f4ee803da2b740dea036971e861bf60 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2027288 Tested-by: Junichi Uekawa Reviewed-by: Lepton Wu Commit-Queue: Junichi Uekawa --- amdgpu.c | 4 ++-- cros_gralloc/gralloc0/tests/gralloctest.c | 2 +- drv.c | 2 +- i915.c | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/amdgpu.c b/amdgpu.c index 2654f9a..f25af6a 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -39,8 +39,8 @@ const static uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMA DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888 }; -const static uint32_t texture_source_formats[] = { DRM_FORMAT_GR88, DRM_FORMAT_R8, - 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, DRM_FORMAT_YVU420_ANDROID, DRM_FORMAT_YVU420 }; static int amdgpu_init(struct driver *drv) diff --git a/cros_gralloc/gralloc0/tests/gralloctest.c b/cros_gralloc/gralloc0/tests/gralloctest.c index 8dfcd0b..9160e62 100644 --- a/cros_gralloc/gralloc0/tests/gralloctest.c +++ b/cros_gralloc/gralloc0/tests/gralloctest.c @@ -95,7 +95,7 @@ static struct combinations combos[] = { // clang-format on struct grallocinfo { - buffer_handle_t handle; /* handle to the buffer */ + buffer_handle_t handle; /* handle to the buffer */ int w; /* width of buffer */ int h; /* height of buffer */ int format; /* format of the buffer */ diff --git a/drv.c b/drv.c index 7f64188..dcca838 100644 --- a/drv.c +++ b/drv.c @@ -111,7 +111,7 @@ static const struct backend *drv_get_backend(int fd) #ifdef DRV_VC4 &backend_vc4, #endif - &backend_vgem, &backend_virtio_gpu, + &backend_vgem, &backend_virtio_gpu, }; for (i = 0; i < ARRAY_SIZE(backend_list); i++) diff --git a/i915.c b/i915.c index 925eba3..6538aef 100644 --- a/i915.c +++ b/i915.c @@ -24,8 +24,8 @@ #define I915_CACHELINE_MASK (I915_CACHELINE_SIZE - 1) static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR16161616F, DRM_FORMAT_ABGR2101010, - DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB2101010, - DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB565, + DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB2101010, + DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB565, DRM_FORMAT_XBGR2101010, DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB2101010, DRM_FORMAT_XRGB8888 }; From 12d007879874704b0af8de606363503017ca1335 Mon Sep 17 00:00:00 2001 From: Matthias Springer Date: Mon, 3 Feb 2020 16:40:09 +0900 Subject: [PATCH 185/269] cros_gralloc: Use entire graphics buffer if all-zeros access region is specified This is a requirement of gralloc and the graphics.mapper HAL in Android. BUG=b:143924619 TEST=Photo capture in GCA succeeds and most camera CTS tests pass Change-Id: Ic34a49aa7175c1c3b9f6c0738b5ab848e002b93d Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2035207 Tested-by: Matthias Springer Commit-Queue: Matthias Springer Reviewed-by: Tomasz Figa Reviewed-by: David Stevens Auto-Submit: Matthias Springer --- cros_gralloc/cros_gralloc_buffer.cc | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/cros_gralloc/cros_gralloc_buffer.cc b/cros_gralloc/cros_gralloc_buffer.cc index 0301af1..01d4038 100644 --- a/cros_gralloc/cros_gralloc_buffer.cc +++ b/cros_gralloc/cros_gralloc_buffer.cc @@ -65,7 +65,18 @@ int32_t cros_gralloc_buffer::lock(const struct rectangle *rect, uint32_t map_fla drv_bo_invalidate(bo_, lock_data_[0]); vaddr = lock_data_[0]->vma->addr; } else { - vaddr = drv_bo_map(bo_, rect, map_flags, &lock_data_[0], 0); + struct rectangle r = *rect; + + if (!r.width && !r.height && !r.x && !r.y) { + /* + * Android IMapper.hal: An accessRegion of all-zeros means the + * entire buffer. + */ + r.width = drv_bo_get_width(bo_); + r.height = drv_bo_get_height(bo_); + } + + vaddr = drv_bo_map(bo_, &r, map_flags, &lock_data_[0], 0); } if (vaddr == MAP_FAILED) { From c95656442e30260746de658afe73e3b2b790594c Mon Sep 17 00:00:00 2001 From: Mark Yacoub Date: Fri, 7 Feb 2020 11:02:22 -0500 Subject: [PATCH 186/269] minigbm/i915: Add support for I915_FORMAT_MOD_Y_TILED_CCS This adds support for allocating buffers with the I915_FORMAT_MOD_Y_TILED_CCS modifier, which enables Intel's rendering buffer compression. (reland of crrev.com/c/1706735) BUG=979736 Change-Id: I90a8bc5fad0e1133d527b5ef4cff56d371763fc6 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2044490 Reviewed-by: Mark Yacoub Reviewed-by: Robert Tarasov Tested-by: Mark Yacoub Tested-by: Robert Tarasov Auto-Submit: Mark Yacoub Commit-Queue: Mark Yacoub --- i915.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/i915.c b/i915.c index 6538aef..27ff209 100644 --- a/i915.c +++ b/i915.c @@ -356,6 +356,7 @@ static int i915_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t h bo->meta.tiling = I915_TILING_X; break; case I915_FORMAT_MOD_Y_TILED: + case I915_FORMAT_MOD_Y_TILED_CCS: bo->meta.tiling = I915_TILING_Y; break; } @@ -373,6 +374,47 @@ static int i915_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t h */ uint32_t stride = ALIGN(width, 32); drv_bo_from_format(bo, stride, height, format); + } else if (modifier == I915_FORMAT_MOD_Y_TILED_CCS) { + /* + * For compressed surfaces, we need a color control surface + * (CCS). Color compression is only supported for Y tiled + * surfaces, and for each 32x16 tiles in the main surface we + * need a tile in the control surface. Y tiles are 128 bytes + * wide and 32 lines tall and we use that to first compute the + * width and height in tiles of the main surface. stride and + * height are already multiples of 128 and 32, respectively: + */ + uint32_t stride = drv_stride_from_format(format, width, 0); + uint32_t width_in_tiles = DIV_ROUND_UP(stride, 128); + uint32_t height_in_tiles = DIV_ROUND_UP(height, 32); + uint32_t size = width_in_tiles * height_in_tiles * 4096; + uint32_t offset = 0; + + bo->meta.strides[0] = width_in_tiles * 128; + bo->meta.sizes[0] = size; + bo->meta.offsets[0] = offset; + offset += size; + + /* + * Now, compute the width and height in tiles of the control + * surface by dividing and rounding up. + */ + uint32_t ccs_width_in_tiles = DIV_ROUND_UP(width_in_tiles, 32); + uint32_t ccs_height_in_tiles = DIV_ROUND_UP(height_in_tiles, 16); + uint32_t ccs_size = ccs_width_in_tiles * ccs_height_in_tiles * 4096; + + /* + * With stride and height aligned to y tiles, offset is + * already a multiple of 4096, which is the required alignment + * of the CCS. + */ + bo->meta.strides[1] = ccs_width_in_tiles * 128; + bo->meta.sizes[1] = ccs_size; + bo->meta.offsets[1] = offset; + offset += ccs_size; + + bo->meta.num_planes = 2; + bo->meta.total_size = offset; } else { i915_bo_from_format(bo, width, height, format); } @@ -424,6 +466,7 @@ static int i915_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint32_t uint32_t format, const uint64_t *modifiers, uint32_t count) { static const uint64_t modifier_order[] = { + I915_FORMAT_MOD_Y_TILED_CCS, I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED, DRM_FORMAT_MOD_LINEAR, @@ -470,6 +513,9 @@ static void *i915_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t int ret; void *addr; + if (bo->meta.format_modifiers[0] == I915_FORMAT_MOD_Y_TILED_CCS) + return MAP_FAILED; + if (bo->meta.tiling == I915_TILING_NONE) { struct drm_i915_gem_mmap gem_map; memset(&gem_map, 0, sizeof(gem_map)); From 6f266902d1d1b258a639d7835d307c019312a013 Mon Sep 17 00:00:00 2001 From: Jeffrey Kardatzke Date: Thu, 13 Feb 2020 16:19:03 -0800 Subject: [PATCH 187/269] minigbm: Disable UBWC for texture formats The venus driver doesn't understand UBWC formats yet so we shouldn't be using them for texture formats that the video decoder writes to. BUG=b:149190288 TEST=video_decode_accelerator_tests pass on trogdor Change-Id: I572c7ff9e1bddcd58136772b3ced07f79a219cba Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2055873 Tested-by: Jeffrey Kardatzke Auto-Submit: Jeffrey Kardatzke Reviewed-by: Gurchetan Singh Reviewed-by: Fritz Koenig Commit-Queue: Fritz Koenig --- msm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm.c b/msm.c index dbc5b70..46d2a34 100644 --- a/msm.c +++ b/msm.c @@ -191,7 +191,7 @@ static int msm_init(struct driver *drv) &metadata, render_use_flags | BO_USE_SCANOUT); msm_add_ubwc_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), - &metadata, texture_use_flags | BO_USE_SCANOUT); + &metadata, texture_use_flags); return 0; } From 7119d3319174d509e30463445bf98bc6ac6e8be3 Mon Sep 17 00:00:00 2001 From: Bas Nieuwenhuizen Date: Fri, 7 Feb 2020 20:20:30 +0100 Subject: [PATCH 188/269] minigbm: Set modifiers for amdgpu/dri. I tried kernel with modifier support and userspace without and it failed due to having a linear (which is 0) modifier for the tiled textures. Set the modifier explicitly. BUG=b:144023522 TEST=Chrome shows the login screen on zork (with some other bugfixes) Change-Id: I806d3bb744e52d094e5b852679057cea3f0bcad0 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2043848 Tested-by: Bas Nieuwenhuizen Reviewed-by: Gurchetan Singh Commit-Queue: Bas Nieuwenhuizen --- amdgpu.c | 2 ++ dri.c | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/amdgpu.c b/amdgpu.c index f25af6a..5f2a93b 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -205,6 +205,8 @@ static int amdgpu_create_bo(struct bo *bo, uint32_t width, uint32_t height, uint for (plane = 0; plane < bo->meta.num_planes; plane++) bo->handles[plane].u32 = gem_create.out.handle; + bo->meta.format_modifiers[0] = DRM_FORMAT_MOD_LINEAR; + return 0; } diff --git a/dri.c b/dri.c index f61134b..950d616 100644 --- a/dri.c +++ b/dri.c @@ -191,6 +191,7 @@ int dri_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t forma { unsigned int dri_use; int ret, dri_format, stride, offset; + int modifier_upper, modifier_lower; struct dri_driver *dri = bo->drv->priv; assert(bo->meta.num_planes == 1); @@ -226,6 +227,16 @@ int dri_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t forma goto close_handle; } + if (dri->image_extension->queryImage(bo->priv, __DRI_IMAGE_ATTRIB_MODIFIER_UPPER, + &modifier_upper) && + dri->image_extension->queryImage(bo->priv, __DRI_IMAGE_ATTRIB_MODIFIER_LOWER, + &modifier_lower)) { + bo->meta.format_modifiers[0] = + ((uint64_t)modifier_upper << 32) | (uint32_t)modifier_lower; + } else { + bo->meta.format_modifiers[0] = DRM_FORMAT_MOD_INVALID; + } + bo->meta.strides[0] = stride; bo->meta.sizes[0] = stride * height; bo->meta.offsets[0] = offset; From 0254a661f1511cea63d1b993d3d2b1457e371e36 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Tue, 17 Dec 2019 09:07:16 -0800 Subject: [PATCH 189/269] minigbm: i915: remove KMS query This simplifies the code. We just have to make sure: - the scanout flag goes to X-tiled. BUG=b:145747132 TEST=compile and run on Nami Cq-Depend: chromium:1998011 Change-Id: Ic2a1c367017c28abc3a9307bea53c577bc33e31e Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1976275 Reviewed-by: Gurchetan Singh Tested-by: Gurchetan Singh Commit-Queue: Gurchetan Singh Auto-Submit: Gurchetan Singh --- i915.c | 160 ++++++++++++++++----------------------------------------- 1 file changed, 44 insertions(+), 116 deletions(-) diff --git a/i915.c b/i915.c index 27ff209..d0c9db1 100644 --- a/i915.c +++ b/i915.c @@ -23,14 +23,16 @@ #define I915_CACHELINE_SIZE 64 #define I915_CACHELINE_MASK (I915_CACHELINE_SIZE - 1) -static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR16161616F, DRM_FORMAT_ABGR2101010, - DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB2101010, - DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB565, - DRM_FORMAT_XBGR2101010, DRM_FORMAT_XBGR8888, - DRM_FORMAT_XRGB2101010, DRM_FORMAT_XRGB8888 }; +static const uint32_t scanout_render_formats[] = { DRM_FORMAT_ABGR2101010, DRM_FORMAT_ABGR8888, + DRM_FORMAT_ARGB2101010, DRM_FORMAT_ARGB8888, + DRM_FORMAT_RGB565, DRM_FORMAT_XBGR2101010, + DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB2101010, + DRM_FORMAT_XRGB8888 }; -static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_NV12, DRM_FORMAT_P010, - DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID }; +static const uint32_t render_formats[] = { DRM_FORMAT_ABGR16161616F }; + +static const uint32_t texture_only_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_NV12, DRM_FORMAT_P010, + DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID }; struct i915_device { uint32_t gen; @@ -49,109 +51,49 @@ static uint32_t i915_get_gen(int device_id) return 4; } -/* - * We allow allocation of ARGB formats for SCANOUT if the corresponding XRGB - * formats supports it. It's up to the caller (chrome ozone) to ultimately not - * scan out ARGB if the display controller only supports XRGB, but we'll allow - * the allocation of the bo here. - */ -static bool format_compatible(const struct combination *combo, uint32_t format) +static uint64_t unset_flags(uint64_t current_flags, uint64_t mask) { - if (combo->format == format) - return true; - - switch (format) { - case DRM_FORMAT_XRGB8888: - return combo->format == DRM_FORMAT_ARGB8888; - case DRM_FORMAT_XBGR8888: - return combo->format == DRM_FORMAT_ABGR8888; - case DRM_FORMAT_RGBX8888: - return combo->format == DRM_FORMAT_RGBA8888; - case DRM_FORMAT_BGRX8888: - return combo->format == DRM_FORMAT_BGRA8888; - case DRM_FORMAT_XRGB2101010: - return combo->format == DRM_FORMAT_ARGB2101010; - case DRM_FORMAT_XBGR2101010: - return combo->format == DRM_FORMAT_ABGR2101010; - default: - return false; - } -} - -static int i915_add_kms_item(struct driver *drv, const struct kms_item *item) -{ - uint32_t i; - struct combination *combo; - - /* - * Older hardware can't scanout Y-tiled formats. Newer devices can, and - * report this functionality via format modifiers. - */ - for (i = 0; i < drv_array_size(drv->combos); i++) { - combo = (struct combination *)drv_array_at_idx(drv->combos, i); - if (!format_compatible(combo, item->format)) - continue; - - if (item->modifier == DRM_FORMAT_MOD_LINEAR && - combo->metadata.tiling == I915_TILING_X) { - /* - * FIXME: drv_query_kms() does not report the available modifiers - * yet, but we know that all hardware can scanout from X-tiled - * buffers, so let's add this to our combinations, except for - * cursor, which must not be tiled. - */ - combo->use_flags |= item->use_flags & ~BO_USE_CURSOR; - } - - /* If we can scanout NV12, we support all tiling modes. */ - if (item->format == DRM_FORMAT_NV12) - combo->use_flags |= item->use_flags; - - if (combo->metadata.modifier == item->modifier) - combo->use_flags |= item->use_flags; - } - - return 0; + uint64_t value = current_flags & ~mask; + return value; } static int i915_add_combinations(struct driver *drv) { - int ret; - uint32_t i; - struct drv_array *kms_items; struct format_metadata metadata; - uint64_t render_use_flags, texture_use_flags; + uint64_t render, scanout_and_render, texture_only; - render_use_flags = BO_USE_RENDER_MASK; - texture_use_flags = BO_USE_TEXTURE_MASK; + scanout_and_render = BO_USE_RENDER_MASK | BO_USE_SCANOUT; + render = BO_USE_RENDER_MASK; + texture_only = BO_USE_TEXTURE_MASK; + uint64_t linear_mask = BO_USE_RENDERSCRIPT | BO_USE_LINEAR | BO_USE_PROTECTED | + BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN; metadata.tiling = I915_TILING_NONE; metadata.priority = 1; metadata.modifier = DRM_FORMAT_MOD_LINEAR; - drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &metadata, render_use_flags); + drv_add_combinations(drv, scanout_render_formats, ARRAY_SIZE(scanout_render_formats), + &metadata, scanout_and_render); + + drv_add_combinations(drv, render_formats, ARRAY_SIZE(render_formats), &metadata, render); - drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), - &metadata, texture_use_flags); + drv_add_combinations(drv, texture_only_formats, ARRAY_SIZE(texture_only_formats), &metadata, + texture_only); + drv_modify_linear_combinations(drv); /* * Chrome uses DMA-buf mmap to write to YV12 buffers, which are then accessed by the * Video Encoder Accelerator (VEA). It could also support NV12 potentially in the future. */ drv_modify_combination(drv, DRM_FORMAT_YVU420, &metadata, BO_USE_HW_VIDEO_ENCODER); + /* IPU3 camera ISP supports only NV12 output. */ drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata, - BO_USE_HW_VIDEO_ENCODER | BO_USE_HW_VIDEO_DECODER); + BO_USE_HW_VIDEO_ENCODER | BO_USE_HW_VIDEO_DECODER | + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_SCANOUT); /* Android CTS tests require this. */ drv_add_combination(drv, DRM_FORMAT_BGR888, &metadata, BO_USE_SW_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); - - /* IPU3 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. @@ -159,51 +101,37 @@ 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_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; - render_use_flags &= ~BO_USE_PROTECTED; - - 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; - texture_use_flags &= ~BO_USE_PROTECTED; + render = unset_flags(render, linear_mask); + scanout_and_render = unset_flags(scanout_and_render, linear_mask); metadata.tiling = I915_TILING_X; metadata.priority = 2; metadata.modifier = I915_FORMAT_MOD_X_TILED; - drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &metadata, render_use_flags); + drv_add_combinations(drv, render_formats, ARRAY_SIZE(render_formats), &metadata, render); + drv_add_combinations(drv, scanout_render_formats, ARRAY_SIZE(scanout_render_formats), + &metadata, scanout_and_render); metadata.tiling = I915_TILING_Y; metadata.priority = 3; metadata.modifier = I915_FORMAT_MOD_Y_TILED; - drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &metadata, render_use_flags); - - /* Support y-tiled NV12 and P010 for libva */ + scanout_and_render = unset_flags(scanout_and_render, BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY); +/* Support y-tiled NV12 and P010 for libva */ +#ifdef I915_SCANOUT_Y_TILED + drv_add_combination(drv, DRM_FORMAT_NV12, &metadata, + BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER | BO_USE_SCANOUT); +#else drv_add_combination(drv, DRM_FORMAT_NV12, &metadata, BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER); +#endif + scanout_and_render = unset_flags(scanout_and_render, BO_USE_SCANOUT); drv_add_combination(drv, DRM_FORMAT_P010, &metadata, BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER); - kms_items = drv_query_kms(drv); - if (!kms_items) - return 0; - - 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) { - drv_array_destroy(kms_items); - return ret; - } - } - - drv_array_destroy(kms_items); + drv_add_combinations(drv, render_formats, ARRAY_SIZE(render_formats), &metadata, render); + drv_add_combinations(drv, scanout_render_formats, ARRAY_SIZE(scanout_render_formats), + &metadata, scanout_and_render); return 0; } From c87a6d361abc95a6375da32f085c4a43e97bb48f Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Thu, 19 Dec 2019 10:51:14 -0800 Subject: [PATCH 190/269] minigbm: rockchip: remove KMS dependency Same reason has i915. BUG=b:145747132 TEST=emerge-kevin minigbm Change-Id: Id51c5e9e27a7bfae7db63730d637b8d5d0ff841f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1976276 Tested-by: Gurchetan Singh Commit-Queue: Gurchetan Singh Reviewed-by: Gurchetan Singh Reviewed-by: Robert Tarasov --- rockchip.c | 75 ++++++++++-------------------------------------------- 1 file changed, 13 insertions(+), 62 deletions(-) diff --git a/rockchip.c b/rockchip.c index 698f85b..25f16ab 100644 --- a/rockchip.c +++ b/rockchip.c @@ -23,12 +23,12 @@ struct rockchip_private_map_data { void *gem_addr; }; -static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, - DRM_FORMAT_BGR888, DRM_FORMAT_RGB565, - DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888 }; +static const uint32_t scanout_render_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, + DRM_FORMAT_BGR888, DRM_FORMAT_RGB565, + DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888 }; -static const uint32_t texture_source_formats[] = { DRM_FORMAT_NV12, DRM_FORMAT_YVU420, - DRM_FORMAT_YVU420_ANDROID }; +static const uint32_t texture_only_formats[] = { DRM_FORMAT_NV12, DRM_FORMAT_YVU420, + DRM_FORMAT_YVU420_ANDROID }; static int afbc_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, uint32_t format) { @@ -74,67 +74,31 @@ static int afbc_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, u return 0; } -static int rockchip_add_kms_item(struct driver *drv, const struct kms_item *item) -{ - uint32_t i, j; - uint64_t use_flags; - struct combination *combo; - struct format_metadata metadata; - - 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) { - 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]) - use_flags &= ~BO_USE_RENDERING; - } - - drv_add_combinations(drv, &item->format, 1, &metadata, use_flags); - } else { - combo->use_flags |= item->use_flags; - } - } - } - - return 0; -} - static int rockchip_init(struct driver *drv) { - int ret; - uint32_t i; - struct drv_array *kms_items; struct format_metadata metadata; metadata.tiling = 0; metadata.priority = 1; metadata.modifier = DRM_FORMAT_MOD_LINEAR; - drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &metadata, BO_USE_RENDER_MASK); + drv_add_combinations(drv, scanout_render_formats, ARRAY_SIZE(scanout_render_formats), + &metadata, BO_USE_RENDER_MASK | BO_USE_SCANOUT); - drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), - &metadata, BO_USE_TEXTURE_MASK); + drv_add_combinations(drv, texture_only_formats, ARRAY_SIZE(texture_only_formats), &metadata, + BO_USE_TEXTURE_MASK); /* * Chrome uses DMA-buf mmap to write to YV12 buffers, which are then accessed by the * Video Encoder Accelerator (VEA). It could also support NV12 potentially in the future. */ drv_modify_combination(drv, DRM_FORMAT_YVU420, &metadata, BO_USE_HW_VIDEO_ENCODER); - drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata, BO_USE_HW_VIDEO_ENCODER); - - 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); - /* Camera ISP supports only NV12 output. */ drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata, - BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER); + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER | + BO_USE_HW_VIDEO_ENCODER | BO_USE_SCANOUT); + + drv_modify_linear_combinations(drv); /* * R8 format is used for Android's HAL_PIXEL_FORMAT_BLOB and is used for JPEG snapshots * from camera. @@ -143,19 +107,6 @@ static int rockchip_init(struct driver *drv) BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_SW_MASK | BO_USE_LINEAR | BO_USE_PROTECTED); - kms_items = drv_query_kms(drv); - if (!kms_items) - return 0; - - 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) { - drv_array_destroy(kms_items); - return ret; - } - } - - drv_array_destroy(kms_items); return 0; } From 28e5ea0f88de9084bf5e99d5dc957d02533607aa Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Thu, 19 Dec 2019 10:56:51 -0800 Subject: [PATCH 191/269] minigbm: remove KMS dependency Adds unneeded complication and extra kernel patches. Hopefully with Chrome using modifiers we can remove this. BUG=b:145747132 TEST=compile and run Change-Id: I557bbd50828d7e39848c315a44a24587c9e2ce3a Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1976277 Tested-by: Gurchetan Singh Commit-Queue: Gurchetan Singh Reviewed-by: Gurchetan Singh Reviewed-by: Kristian H. Kristensen --- drv_priv.h | 6 --- helpers.c | 124 +---------------------------------------------------- helpers.h | 1 - 3 files changed, 1 insertion(+), 130 deletions(-) diff --git a/drv_priv.h b/drv_priv.h index b497890..1e0e75b 100644 --- a/drv_priv.h +++ b/drv_priv.h @@ -35,12 +35,6 @@ struct bo { void *priv; }; -struct kms_item { - uint32_t format; - uint64_t modifier; - uint64_t use_flags; -}; - struct format_metadata { uint32_t priority; uint32_t tiling; diff --git a/helpers.c b/helpers.c index e29f539..833a2d8 100644 --- a/helpers.c +++ b/helpers.c @@ -11,7 +11,6 @@ #include #include #include -#include #include "drv_priv.h" #include "helpers.h" @@ -568,137 +567,16 @@ void drv_modify_combination(struct driver *drv, uint32_t format, struct format_m } } -struct drv_array *drv_query_kms(struct driver *drv) -{ - struct drv_array *kms_items; - uint64_t plane_type = UINT64_MAX; - uint64_t use_flag; - uint32_t i, j, k; - - drmModePlanePtr plane; - drmModePropertyPtr prop; - drmModePlaneResPtr resources; - drmModeObjectPropertiesPtr props; - - kms_items = drv_array_init(sizeof(struct kms_item)); - if (!kms_items) - goto out; - - /* - * The ability to return universal planes is only complete on - * ChromeOS kernel versions >= v3.18. The SET_CLIENT_CAP ioctl - * therefore might return an error code, so don't check it. If it - * fails, it'll just return the plane list as overlay planes, which is - * fine in our case (our drivers already have cursor bits set). - * modetest in libdrm does the same thing. - */ - drmSetClientCap(drv->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); - - resources = drmModeGetPlaneResources(drv->fd); - if (!resources) - goto out; - - for (i = 0; i < resources->count_planes; i++) { - plane_type = UINT64_MAX; - plane = drmModeGetPlane(drv->fd, resources->planes[i]); - if (!plane) - goto out; - - props = drmModeObjectGetProperties(drv->fd, plane->plane_id, DRM_MODE_OBJECT_PLANE); - if (!props) - goto out; - - for (j = 0; j < props->count_props; j++) { - prop = drmModeGetProperty(drv->fd, props->props[j]); - if (prop) { - if (strcmp(prop->name, "type") == 0) { - plane_type = props->prop_values[j]; - } - - drmModeFreeProperty(prop); - } - } - - switch (plane_type) { - case DRM_PLANE_TYPE_OVERLAY: - case DRM_PLANE_TYPE_PRIMARY: - use_flag = BO_USE_SCANOUT; - break; - case DRM_PLANE_TYPE_CURSOR: - use_flag = BO_USE_CURSOR; - break; - default: - assert(0); - } - - for (j = 0; j < plane->count_formats; j++) { - bool found = false; - 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) { - struct kms_item item = { .format = plane->formats[j], - .modifier = DRM_FORMAT_MOD_LINEAR, - .use_flags = use_flag }; - - drv_array_append(kms_items, &item); - } - } - - drmModeFreeObjectProperties(props); - drmModeFreePlane(plane); - } - - drmModeFreePlaneResources(resources); -out: - if (kms_items && !drv_array_size(kms_items)) { - drv_array_destroy(kms_items); - return NULL; - } - - return kms_items; -} - int drv_modify_linear_combinations(struct driver *drv) { - 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 - * plane and as a cursor. Some drivers don't support - * drmModeGetPlaneResources, so add the combination here. Note that the - * kernel disregards the alpha component of ARGB unless it's an overlay - * plane. + * plane and as a cursor. */ drv_modify_combination(drv, DRM_FORMAT_XRGB8888, &LINEAR_METADATA, BO_USE_CURSOR | BO_USE_SCANOUT); drv_modify_combination(drv, DRM_FORMAT_ARGB8888, &LINEAR_METADATA, BO_USE_CURSOR | BO_USE_SCANOUT); - - kms_items = drv_query_kms(drv); - if (!kms_items) - return 0; - - 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; - } - } - - drv_array_destroy(kms_items); return 0; } diff --git a/helpers.h b/helpers.h index fe4519d..19d0fd7 100644 --- a/helpers.h +++ b/helpers.h @@ -38,7 +38,6 @@ void drv_add_combinations(struct driver *drv, const uint32_t *formats, uint32_t 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 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); From ddf4ec078d753c744ec82df7504e109a9a161bfd Mon Sep 17 00:00:00 2001 From: Jason Macnak Date: Mon, 3 Feb 2020 16:36:46 -0800 Subject: [PATCH 192/269] minigbm: virtio-gpu: check format support when adding combinations Updates the minigbm virtio backend to check for renderer support before advertising support of various combinations. This prevents minigbm from advertising yuv/nv12 formats which are not supported on Cuttlefish when running on GCE with Nvidia GPUs which do not support GBM. BUG=b:123764798 TEST=build + launch_cvd TEST=build + launch_cvd --gpu_mode=drm_virgl Change-Id: I8d315a590b1953e6b73144409e6f0b8d15c7d2cd Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2036962 Reviewed-by: Gurchetan Singh Tested-by: Gurchetan Singh Commit-Queue: Jason Macnak --- virtio_gpu.c | 131 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 114 insertions(+), 17 deletions(-) diff --git a/virtio_gpu.c b/virtio_gpu.c index 1eeba26..edc8fc9 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -38,6 +38,7 @@ static const uint32_t texture_source_formats[] = { DRM_FORMAT_NV12, DRM_FORMAT_R struct virtio_gpu_priv { int has_3d; + union virgl_caps caps; }; static uint32_t translate_format(uint32_t drm_fourcc) @@ -67,6 +68,56 @@ static uint32_t translate_format(uint32_t drm_fourcc) } } +static bool virtio_gpu_supports_format(struct virgl_supported_format_mask *supported, + uint32_t drm_format) +{ + uint32_t virgl_format = translate_format(drm_format); + if (!virgl_format) { + return false; + } + + uint32_t bitmask_index = virgl_format / 32; + uint32_t bit_index = virgl_format % 32; + return supported->bitmask[bitmask_index] & (1 << bit_index); +} + +// Adds the given buffer combination to the list of supported buffer combinations if the +// combination is supported by the virtio backend. +static void virtio_gpu_add_combination(struct driver *drv, uint32_t drm_format, + struct format_metadata *metadata, uint64_t use_flags) +{ + struct virtio_gpu_priv *priv = (struct virtio_gpu_priv *)drv->priv; + + if (priv->has_3d) { + if ((use_flags & BO_USE_RENDERING) != 0 && + !virtio_gpu_supports_format(&priv->caps.v1.render, drm_format)) { + drv_log("Skipping unsupported render format: %d\n", drm_format); + return; + } + + if ((use_flags & BO_USE_TEXTURE) != 0 && + !virtio_gpu_supports_format(&priv->caps.v1.sampler, drm_format)) { + drv_log("Skipping unsupported texture format: %d\n", drm_format); + return; + } + } + + drv_add_combination(drv, drm_format, metadata, use_flags); +} + +// Adds each given buffer combination to the list of supported buffer combinations if the +// combination supported by the virtio backend. +static void virtio_gpu_add_combinations(struct driver *drv, const uint32_t *drm_formats, + uint32_t num_formats, struct format_metadata *metadata, + uint64_t use_flags) +{ + uint32_t i; + + for (i = 0; i < num_formats; i++) { + virtio_gpu_add_combination(drv, drm_formats[i], metadata, use_flags); + } +} + static int virtio_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, uint64_t use_flags) { @@ -178,6 +229,48 @@ static void *virtio_virgl_bo_map(struct bo *bo, struct vma *vma, size_t plane, u gem_map.offset); } +static int virtio_gpu_get_caps(struct driver *drv, union virgl_caps *caps) +{ + int ret; + struct drm_virtgpu_get_caps cap_args; + struct drm_virtgpu_getparam param_args; + uint32_t can_query_v2 = 0; + + memset(¶m_args, 0, sizeof(param_args)); + param_args.param = VIRTGPU_PARAM_CAPSET_QUERY_FIX; + param_args.value = (uint64_t)(uintptr_t)&can_query_v2; + ret = drmIoctl(drv->fd, DRM_IOCTL_VIRTGPU_GETPARAM, ¶m_args); + if (ret) { + drv_log("DRM_IOCTL_VIRTGPU_GETPARAM failed with %s\n", strerror(errno)); + } + + memset(&cap_args, 0, sizeof(cap_args)); + cap_args.addr = (unsigned long long)caps; + if (can_query_v2) { + cap_args.cap_set_id = 2; + cap_args.size = sizeof(union virgl_caps); + } else { + cap_args.cap_set_id = 1; + cap_args.size = sizeof(struct virgl_caps_v1); + } + + ret = drmIoctl(drv->fd, DRM_IOCTL_VIRTGPU_GET_CAPS, &cap_args); + if (ret) { + drv_log("DRM_IOCTL_VIRTGPU_GET_CAPS failed with %s\n", strerror(errno)); + + // Fallback to v1 + cap_args.cap_set_id = 1; + cap_args.size = sizeof(struct virgl_caps_v1); + + ret = drmIoctl(drv->fd, DRM_IOCTL_VIRTGPU_GET_CAPS, &cap_args); + if (ret) { + drv_log("DRM_IOCTL_VIRTGPU_GET_CAPS failed with %s\n", strerror(errno)); + } + } + + return ret; +} + static int virtio_gpu_init(struct driver *drv) { int ret; @@ -198,34 +291,38 @@ static int virtio_gpu_init(struct driver *drv) } if (priv->has_3d) { + virtio_gpu_get_caps(drv, &priv->caps); + /* This doesn't mean host can scanout everything, it just means host * hypervisor can show it. */ - drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &LINEAR_METADATA, BO_USE_RENDER_MASK | BO_USE_SCANOUT); - drv_add_combinations(drv, texture_source_formats, - ARRAY_SIZE(texture_source_formats), &LINEAR_METADATA, - BO_USE_TEXTURE_MASK); + virtio_gpu_add_combinations(drv, render_target_formats, + ARRAY_SIZE(render_target_formats), &LINEAR_METADATA, + BO_USE_RENDER_MASK | BO_USE_SCANOUT); + virtio_gpu_add_combinations(drv, texture_source_formats, + ARRAY_SIZE(texture_source_formats), &LINEAR_METADATA, + BO_USE_TEXTURE_MASK); } else { /* Virtio primary plane only allows this format. */ - drv_add_combination(drv, DRM_FORMAT_XRGB8888, &LINEAR_METADATA, - BO_USE_RENDER_MASK | BO_USE_SCANOUT); + virtio_gpu_add_combination(drv, DRM_FORMAT_XRGB8888, &LINEAR_METADATA, + BO_USE_RENDER_MASK | BO_USE_SCANOUT); /* Virtio cursor plane only allows this format and Chrome cannot live without * ARGB888 renderable format. */ - drv_add_combination(drv, DRM_FORMAT_ARGB8888, &LINEAR_METADATA, - BO_USE_RENDER_MASK | BO_USE_CURSOR); + virtio_gpu_add_combination(drv, DRM_FORMAT_ARGB8888, &LINEAR_METADATA, + BO_USE_RENDER_MASK | BO_USE_CURSOR); /* Android needs more, but they cannot be bound as scanouts anymore after * "drm/virtio: fix DRM_FORMAT_* handling" */ - drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &LINEAR_METADATA, BO_USE_RENDER_MASK); - drv_add_combinations(drv, dumb_texture_source_formats, - ARRAY_SIZE(dumb_texture_source_formats), &LINEAR_METADATA, - BO_USE_TEXTURE_MASK); - drv_add_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA, - BO_USE_SW_MASK | BO_USE_LINEAR); + virtio_gpu_add_combinations(drv, render_target_formats, + ARRAY_SIZE(render_target_formats), &LINEAR_METADATA, + BO_USE_RENDER_MASK); + virtio_gpu_add_combinations(drv, dumb_texture_source_formats, + ARRAY_SIZE(dumb_texture_source_formats), + &LINEAR_METADATA, BO_USE_TEXTURE_MASK); + virtio_gpu_add_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA, + BO_USE_SW_MASK | BO_USE_LINEAR); } /* Android CTS tests require this. */ - drv_add_combination(drv, DRM_FORMAT_BGR888, &LINEAR_METADATA, BO_USE_SW_MASK); + virtio_gpu_add_combination(drv, DRM_FORMAT_BGR888, &LINEAR_METADATA, BO_USE_SW_MASK); drv_modify_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA, BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER | From f11f1dfcb5f22d3b627eb366ee902fb6a8c3de61 Mon Sep 17 00:00:00 2001 From: Ricky Liang Date: Thu, 13 Feb 2020 10:42:46 +0800 Subject: [PATCH 193/269] msm: add camera use flags for NV12 and R8 NV12 is used by the camera stack for YUV buffers. R8 is used by the camera stack as a blob format for JPEG images. BUG=b:148152367 TEST=Manually with built-in camera app on Cheza Change-Id: I484f1a5ede2dfece549706310d832086af087544 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2053665 Tested-by: Ricky Liang Commit-Queue: Ricky Liang Reviewed-by: Gurchetan Singh --- msm.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/msm.c b/msm.c index 46d2a34..d902968 100644 --- a/msm.c +++ b/msm.c @@ -175,6 +175,16 @@ static int msm_init(struct driver *drv) drv_modify_combination(drv, DRM_FORMAT_YVU420, &LINEAR_METADATA, BO_USE_HW_VIDEO_ENCODER); drv_modify_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA, BO_USE_HW_VIDEO_ENCODER); + /* The camera stack standardizes on NV12 for YUV buffers. */ + 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); + /* Android CTS tests require this. */ drv_add_combination(drv, DRM_FORMAT_BGR888, &LINEAR_METADATA, BO_USE_SW_MASK); From a6a9efc138ebd63b8d9a5e5f13425a0dbc0270c9 Mon Sep 17 00:00:00 2001 From: Jeffrey Kardatzke Date: Fri, 21 Feb 2020 15:35:01 -0800 Subject: [PATCH 194/269] msm: Don't height align R8, height 1 buffers used for camera output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We height align to multiples of 64 and the camera will create a height one buffer of length 13MB for JPEG output with R8 format. If we see R8 format with height 1, then don't do the height alignment. BUG=b:148152367 TEST=Camera app works on trogdor Change-Id: I6e4260f37cc45fe3b7e9bd132844cbde4a58fc26 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2066796 Reviewed-by: Rob Clark Reviewed-by: Stéphane Marchesin Tested-by: Jeffrey Kardatzke Auto-Submit: Jeffrey Kardatzke Commit-Queue: Jeffrey Kardatzke --- msm.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/msm.c b/msm.c index d902968..6a1a3de 100644 --- a/msm.c +++ b/msm.c @@ -105,8 +105,11 @@ static void msm_calculate_layout(struct bo *bo) uint32_t stride, alignw, alignh; alignw = ALIGN(width, DEFAULT_ALIGNMENT); - /* HAL_PIXEL_FORMAT_YV12 requires that the buffer's height not be aligned. */ - if (bo->meta.format == DRM_FORMAT_YVU420_ANDROID) { + /* HAL_PIXEL_FORMAT_YV12 requires that the buffer's height not be aligned. + DRM_FORMAT_R8 of height one is used for JPEG camera output, so don't + height align that. */ + if (bo->meta.format == DRM_FORMAT_YVU420_ANDROID || + (bo->meta.format == DRM_FORMAT_R8 && height == 1)) { alignh = height; } else { alignh = ALIGN(height, DEFAULT_ALIGNMENT); From b0787a9fdb40b580c473d79d0e55070a1fd4844a Mon Sep 17 00:00:00 2001 From: Jao-ke Chin-Lee Date: Wed, 26 Feb 2020 02:14:19 +0000 Subject: [PATCH 195/269] Revert "minigbm: i915: remove KMS query" This reverts commit 0254a661f1511cea63d1b993d3d2b1457e371e36. Reason for revert: speculative revert to address octopus breakages BUG=b:149959202 Exempt-From-Owner-Approval: revert change. Original change's description: > minigbm: i915: remove KMS query > > This simplifies the code. We just have to make sure: > > - the scanout flag goes to X-tiled. > > BUG=b:145747132 > TEST=compile and run on Nami > > Cq-Depend: chromium:1998011 > Change-Id: Ic2a1c367017c28abc3a9307bea53c577bc33e31e > Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1976275 > Reviewed-by: Gurchetan Singh > Tested-by: Gurchetan Singh > Commit-Queue: Gurchetan Singh > Auto-Submit: Gurchetan Singh Bug: b:145747132 Change-Id: If6aa7e3623461b8f837dec581934ed86d4c4a573 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2073173 Tested-by: Ilja H. Friedel Reviewed-by: Jao-ke Chin-Lee Commit-Queue: Jao-ke Chin-Lee --- i915.c | 160 +++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 116 insertions(+), 44 deletions(-) diff --git a/i915.c b/i915.c index d0c9db1..27ff209 100644 --- a/i915.c +++ b/i915.c @@ -23,16 +23,14 @@ #define I915_CACHELINE_SIZE 64 #define I915_CACHELINE_MASK (I915_CACHELINE_SIZE - 1) -static const uint32_t scanout_render_formats[] = { DRM_FORMAT_ABGR2101010, DRM_FORMAT_ABGR8888, - DRM_FORMAT_ARGB2101010, DRM_FORMAT_ARGB8888, - DRM_FORMAT_RGB565, DRM_FORMAT_XBGR2101010, - DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB2101010, - DRM_FORMAT_XRGB8888 }; +static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR16161616F, DRM_FORMAT_ABGR2101010, + DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB2101010, + DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB565, + DRM_FORMAT_XBGR2101010, DRM_FORMAT_XBGR8888, + DRM_FORMAT_XRGB2101010, DRM_FORMAT_XRGB8888 }; -static const uint32_t render_formats[] = { DRM_FORMAT_ABGR16161616F }; - -static const uint32_t texture_only_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_NV12, DRM_FORMAT_P010, - DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID }; +static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_NV12, DRM_FORMAT_P010, + DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID }; struct i915_device { uint32_t gen; @@ -51,49 +49,109 @@ static uint32_t i915_get_gen(int device_id) return 4; } -static uint64_t unset_flags(uint64_t current_flags, uint64_t mask) +/* + * We allow allocation of ARGB formats for SCANOUT if the corresponding XRGB + * formats supports it. It's up to the caller (chrome ozone) to ultimately not + * scan out ARGB if the display controller only supports XRGB, but we'll allow + * the allocation of the bo here. + */ +static bool format_compatible(const struct combination *combo, uint32_t format) { - uint64_t value = current_flags & ~mask; - return value; + if (combo->format == format) + return true; + + switch (format) { + case DRM_FORMAT_XRGB8888: + return combo->format == DRM_FORMAT_ARGB8888; + case DRM_FORMAT_XBGR8888: + return combo->format == DRM_FORMAT_ABGR8888; + case DRM_FORMAT_RGBX8888: + return combo->format == DRM_FORMAT_RGBA8888; + case DRM_FORMAT_BGRX8888: + return combo->format == DRM_FORMAT_BGRA8888; + case DRM_FORMAT_XRGB2101010: + return combo->format == DRM_FORMAT_ARGB2101010; + case DRM_FORMAT_XBGR2101010: + return combo->format == DRM_FORMAT_ABGR2101010; + default: + return false; + } +} + +static int i915_add_kms_item(struct driver *drv, const struct kms_item *item) +{ + uint32_t i; + struct combination *combo; + + /* + * Older hardware can't scanout Y-tiled formats. Newer devices can, and + * report this functionality via format modifiers. + */ + for (i = 0; i < drv_array_size(drv->combos); i++) { + combo = (struct combination *)drv_array_at_idx(drv->combos, i); + if (!format_compatible(combo, item->format)) + continue; + + if (item->modifier == DRM_FORMAT_MOD_LINEAR && + combo->metadata.tiling == I915_TILING_X) { + /* + * FIXME: drv_query_kms() does not report the available modifiers + * yet, but we know that all hardware can scanout from X-tiled + * buffers, so let's add this to our combinations, except for + * cursor, which must not be tiled. + */ + combo->use_flags |= item->use_flags & ~BO_USE_CURSOR; + } + + /* If we can scanout NV12, we support all tiling modes. */ + if (item->format == DRM_FORMAT_NV12) + combo->use_flags |= item->use_flags; + + if (combo->metadata.modifier == item->modifier) + combo->use_flags |= item->use_flags; + } + + return 0; } static int i915_add_combinations(struct driver *drv) { + int ret; + uint32_t i; + struct drv_array *kms_items; struct format_metadata metadata; - uint64_t render, scanout_and_render, texture_only; + uint64_t render_use_flags, texture_use_flags; - scanout_and_render = BO_USE_RENDER_MASK | BO_USE_SCANOUT; - render = BO_USE_RENDER_MASK; - texture_only = BO_USE_TEXTURE_MASK; - uint64_t linear_mask = BO_USE_RENDERSCRIPT | BO_USE_LINEAR | BO_USE_PROTECTED | - BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN; + 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_LINEAR; - drv_add_combinations(drv, scanout_render_formats, ARRAY_SIZE(scanout_render_formats), - &metadata, scanout_and_render); - - drv_add_combinations(drv, render_formats, ARRAY_SIZE(render_formats), &metadata, render); + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &metadata, render_use_flags); - drv_add_combinations(drv, texture_only_formats, ARRAY_SIZE(texture_only_formats), &metadata, - texture_only); + drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), + &metadata, texture_use_flags); - drv_modify_linear_combinations(drv); /* * Chrome uses DMA-buf mmap to write to YV12 buffers, which are then accessed by the * Video Encoder Accelerator (VEA). It could also support NV12 potentially in the future. */ drv_modify_combination(drv, DRM_FORMAT_YVU420, &metadata, BO_USE_HW_VIDEO_ENCODER); - /* IPU3 camera ISP supports only NV12 output. */ drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata, - BO_USE_HW_VIDEO_ENCODER | BO_USE_HW_VIDEO_DECODER | - BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_SCANOUT); + BO_USE_HW_VIDEO_ENCODER | BO_USE_HW_VIDEO_DECODER); /* Android CTS tests require this. */ drv_add_combination(drv, DRM_FORMAT_BGR888, &metadata, BO_USE_SW_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); + + /* IPU3 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. @@ -101,37 +159,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 = unset_flags(render, linear_mask); - scanout_and_render = unset_flags(scanout_and_render, linear_mask); + 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; + render_use_flags &= ~BO_USE_PROTECTED; + + 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; + texture_use_flags &= ~BO_USE_PROTECTED; metadata.tiling = I915_TILING_X; metadata.priority = 2; metadata.modifier = I915_FORMAT_MOD_X_TILED; - drv_add_combinations(drv, render_formats, ARRAY_SIZE(render_formats), &metadata, render); - drv_add_combinations(drv, scanout_render_formats, ARRAY_SIZE(scanout_render_formats), - &metadata, scanout_and_render); + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &metadata, render_use_flags); metadata.tiling = I915_TILING_Y; metadata.priority = 3; metadata.modifier = I915_FORMAT_MOD_Y_TILED; - scanout_and_render = unset_flags(scanout_and_render, BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY); -/* Support y-tiled NV12 and P010 for libva */ -#ifdef I915_SCANOUT_Y_TILED - drv_add_combination(drv, DRM_FORMAT_NV12, &metadata, - BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER | BO_USE_SCANOUT); -#else + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &metadata, render_use_flags); + + /* Support y-tiled NV12 and P010 for libva */ drv_add_combination(drv, DRM_FORMAT_NV12, &metadata, BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER); -#endif - scanout_and_render = unset_flags(scanout_and_render, BO_USE_SCANOUT); drv_add_combination(drv, DRM_FORMAT_P010, &metadata, BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER); - drv_add_combinations(drv, render_formats, ARRAY_SIZE(render_formats), &metadata, render); - drv_add_combinations(drv, scanout_render_formats, ARRAY_SIZE(scanout_render_formats), - &metadata, scanout_and_render); + kms_items = drv_query_kms(drv); + if (!kms_items) + return 0; + + 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) { + drv_array_destroy(kms_items); + return ret; + } + } + + drv_array_destroy(kms_items); return 0; } From f39dcbc6a067d83e15b0fbebf1a7889f79de10be Mon Sep 17 00:00:00 2001 From: "Ilja H. Friedel" Date: Wed, 26 Feb 2020 02:50:51 +0000 Subject: [PATCH 196/269] Reland "minigbm: i915: remove KMS query" This reverts commit b0787a9fdb40b580c473d79d0e55070a1fd4844a. Reason for revert: I want to avoid a potentially broken build due to the revert. My local build is taking too long. BUG=b:149959202 Exempt-From-Owner-Approval: reland change. Original change's description: > Revert "minigbm: i915: remove KMS query" > > This reverts commit 0254a661f1511cea63d1b993d3d2b1457e371e36. > > Reason for revert: speculative revert to address octopus breakages > > BUG=b:149959202 > Exempt-From-Owner-Approval: revert change. > > > Original change's description: > > minigbm: i915: remove KMS query > > > > This simplifies the code. We just have to make sure: > > > > - the scanout flag goes to X-tiled. > > > > BUG=b:145747132 > > TEST=compile and run on Nami > > > > Cq-Depend: chromium:1998011 > > Change-Id: Ic2a1c367017c28abc3a9307bea53c577bc33e31e > > Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1976275 > > Reviewed-by: Gurchetan Singh > > Tested-by: Gurchetan Singh > > Commit-Queue: Gurchetan Singh > > Auto-Submit: Gurchetan Singh > > Bug: b:145747132 > Change-Id: If6aa7e3623461b8f837dec581934ed86d4c4a573 > Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2073173 > Tested-by: Ilja H. Friedel > Reviewed-by: Jao-ke Chin-Lee > Commit-Queue: Jao-ke Chin-Lee Bug: b:149959202, b:145747132 Change-Id: I529f24309ee33bc6b500c65fd83a7f282dafef05 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2073478 Reviewed-by: Ilja H. Friedel Reviewed-by: Jao-ke Chin-Lee Commit-Queue: Ilja H. Friedel Tested-by: Ilja H. Friedel --- i915.c | 160 ++++++++++++++++----------------------------------------- 1 file changed, 44 insertions(+), 116 deletions(-) diff --git a/i915.c b/i915.c index 27ff209..d0c9db1 100644 --- a/i915.c +++ b/i915.c @@ -23,14 +23,16 @@ #define I915_CACHELINE_SIZE 64 #define I915_CACHELINE_MASK (I915_CACHELINE_SIZE - 1) -static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR16161616F, DRM_FORMAT_ABGR2101010, - DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB2101010, - DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB565, - DRM_FORMAT_XBGR2101010, DRM_FORMAT_XBGR8888, - DRM_FORMAT_XRGB2101010, DRM_FORMAT_XRGB8888 }; +static const uint32_t scanout_render_formats[] = { DRM_FORMAT_ABGR2101010, DRM_FORMAT_ABGR8888, + DRM_FORMAT_ARGB2101010, DRM_FORMAT_ARGB8888, + DRM_FORMAT_RGB565, DRM_FORMAT_XBGR2101010, + DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB2101010, + DRM_FORMAT_XRGB8888 }; -static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_NV12, DRM_FORMAT_P010, - DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID }; +static const uint32_t render_formats[] = { DRM_FORMAT_ABGR16161616F }; + +static const uint32_t texture_only_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_NV12, DRM_FORMAT_P010, + DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID }; struct i915_device { uint32_t gen; @@ -49,109 +51,49 @@ static uint32_t i915_get_gen(int device_id) return 4; } -/* - * We allow allocation of ARGB formats for SCANOUT if the corresponding XRGB - * formats supports it. It's up to the caller (chrome ozone) to ultimately not - * scan out ARGB if the display controller only supports XRGB, but we'll allow - * the allocation of the bo here. - */ -static bool format_compatible(const struct combination *combo, uint32_t format) +static uint64_t unset_flags(uint64_t current_flags, uint64_t mask) { - if (combo->format == format) - return true; - - switch (format) { - case DRM_FORMAT_XRGB8888: - return combo->format == DRM_FORMAT_ARGB8888; - case DRM_FORMAT_XBGR8888: - return combo->format == DRM_FORMAT_ABGR8888; - case DRM_FORMAT_RGBX8888: - return combo->format == DRM_FORMAT_RGBA8888; - case DRM_FORMAT_BGRX8888: - return combo->format == DRM_FORMAT_BGRA8888; - case DRM_FORMAT_XRGB2101010: - return combo->format == DRM_FORMAT_ARGB2101010; - case DRM_FORMAT_XBGR2101010: - return combo->format == DRM_FORMAT_ABGR2101010; - default: - return false; - } -} - -static int i915_add_kms_item(struct driver *drv, const struct kms_item *item) -{ - uint32_t i; - struct combination *combo; - - /* - * Older hardware can't scanout Y-tiled formats. Newer devices can, and - * report this functionality via format modifiers. - */ - for (i = 0; i < drv_array_size(drv->combos); i++) { - combo = (struct combination *)drv_array_at_idx(drv->combos, i); - if (!format_compatible(combo, item->format)) - continue; - - if (item->modifier == DRM_FORMAT_MOD_LINEAR && - combo->metadata.tiling == I915_TILING_X) { - /* - * FIXME: drv_query_kms() does not report the available modifiers - * yet, but we know that all hardware can scanout from X-tiled - * buffers, so let's add this to our combinations, except for - * cursor, which must not be tiled. - */ - combo->use_flags |= item->use_flags & ~BO_USE_CURSOR; - } - - /* If we can scanout NV12, we support all tiling modes. */ - if (item->format == DRM_FORMAT_NV12) - combo->use_flags |= item->use_flags; - - if (combo->metadata.modifier == item->modifier) - combo->use_flags |= item->use_flags; - } - - return 0; + uint64_t value = current_flags & ~mask; + return value; } static int i915_add_combinations(struct driver *drv) { - int ret; - uint32_t i; - struct drv_array *kms_items; struct format_metadata metadata; - uint64_t render_use_flags, texture_use_flags; + uint64_t render, scanout_and_render, texture_only; - render_use_flags = BO_USE_RENDER_MASK; - texture_use_flags = BO_USE_TEXTURE_MASK; + scanout_and_render = BO_USE_RENDER_MASK | BO_USE_SCANOUT; + render = BO_USE_RENDER_MASK; + texture_only = BO_USE_TEXTURE_MASK; + uint64_t linear_mask = BO_USE_RENDERSCRIPT | BO_USE_LINEAR | BO_USE_PROTECTED | + BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN; metadata.tiling = I915_TILING_NONE; metadata.priority = 1; metadata.modifier = DRM_FORMAT_MOD_LINEAR; - drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &metadata, render_use_flags); + drv_add_combinations(drv, scanout_render_formats, ARRAY_SIZE(scanout_render_formats), + &metadata, scanout_and_render); + + drv_add_combinations(drv, render_formats, ARRAY_SIZE(render_formats), &metadata, render); - drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), - &metadata, texture_use_flags); + drv_add_combinations(drv, texture_only_formats, ARRAY_SIZE(texture_only_formats), &metadata, + texture_only); + drv_modify_linear_combinations(drv); /* * Chrome uses DMA-buf mmap to write to YV12 buffers, which are then accessed by the * Video Encoder Accelerator (VEA). It could also support NV12 potentially in the future. */ drv_modify_combination(drv, DRM_FORMAT_YVU420, &metadata, BO_USE_HW_VIDEO_ENCODER); + /* IPU3 camera ISP supports only NV12 output. */ drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata, - BO_USE_HW_VIDEO_ENCODER | BO_USE_HW_VIDEO_DECODER); + BO_USE_HW_VIDEO_ENCODER | BO_USE_HW_VIDEO_DECODER | + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_SCANOUT); /* Android CTS tests require this. */ drv_add_combination(drv, DRM_FORMAT_BGR888, &metadata, BO_USE_SW_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); - - /* IPU3 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. @@ -159,51 +101,37 @@ 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_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; - render_use_flags &= ~BO_USE_PROTECTED; - - 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; - texture_use_flags &= ~BO_USE_PROTECTED; + render = unset_flags(render, linear_mask); + scanout_and_render = unset_flags(scanout_and_render, linear_mask); metadata.tiling = I915_TILING_X; metadata.priority = 2; metadata.modifier = I915_FORMAT_MOD_X_TILED; - drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &metadata, render_use_flags); + drv_add_combinations(drv, render_formats, ARRAY_SIZE(render_formats), &metadata, render); + drv_add_combinations(drv, scanout_render_formats, ARRAY_SIZE(scanout_render_formats), + &metadata, scanout_and_render); metadata.tiling = I915_TILING_Y; metadata.priority = 3; metadata.modifier = I915_FORMAT_MOD_Y_TILED; - drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &metadata, render_use_flags); - - /* Support y-tiled NV12 and P010 for libva */ + scanout_and_render = unset_flags(scanout_and_render, BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY); +/* Support y-tiled NV12 and P010 for libva */ +#ifdef I915_SCANOUT_Y_TILED + drv_add_combination(drv, DRM_FORMAT_NV12, &metadata, + BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER | BO_USE_SCANOUT); +#else drv_add_combination(drv, DRM_FORMAT_NV12, &metadata, BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER); +#endif + scanout_and_render = unset_flags(scanout_and_render, BO_USE_SCANOUT); drv_add_combination(drv, DRM_FORMAT_P010, &metadata, BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER); - kms_items = drv_query_kms(drv); - if (!kms_items) - return 0; - - 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) { - drv_array_destroy(kms_items); - return ret; - } - } - - drv_array_destroy(kms_items); + drv_add_combinations(drv, render_formats, ARRAY_SIZE(render_formats), &metadata, render); + drv_add_combinations(drv, scanout_render_formats, ARRAY_SIZE(scanout_render_formats), + &metadata, scanout_and_render); return 0; } From e3cd0d38dc5039421e5d110887586afe16002f01 Mon Sep 17 00:00:00 2001 From: Jeffrey Kardatzke Date: Tue, 25 Feb 2020 10:33:37 -0800 Subject: [PATCH 197/269] minigbm/msm: Add NV12 format for Android flex allocation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG=b:149344523 TEST=HW decoder playback on ARC works w/ test codec manifest Change-Id: Ic4c8ed8466a783dd9779b529e96be85298fc680e Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2072600 Tested-by: Jeffrey Kardatzke Reviewed-by: Fritz Koenig Reviewed-by: Alexandre Courbot Reviewed-by: Stéphane Marchesin Commit-Queue: Jeffrey Kardatzke --- msm.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/msm.c b/msm.c index 6a1a3de..a640599 100644 --- a/msm.c +++ b/msm.c @@ -289,6 +289,16 @@ static void *msm_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t m req.offset); } +static uint32_t msm_resolve_format(struct driver *drv, uint32_t format, uint64_t use_flags) +{ + switch (format) { + case DRM_FORMAT_FLEX_YCbCr_420_888: + return DRM_FORMAT_NV12; + default: + return format; + } +} + const struct backend backend_msm = { .name = "msm", .init = msm_init, @@ -298,5 +308,6 @@ const struct backend backend_msm = { .bo_import = drv_prime_bo_import, .bo_map = msm_bo_map, .bo_unmap = drv_bo_munmap, + .resolve_format = msm_resolve_format, }; #endif /* DRV_MSM */ From baab6c8488b9f670c6109fe71d902417f7740217 Mon Sep 17 00:00:00 2001 From: David Stevens Date: Wed, 26 Feb 2020 17:14:43 +0900 Subject: [PATCH 198/269] minigbm: virtio-gpu: wait for transfers when necessary There are two situations where guest access and host access to buffers need to be synchronized to ensure consistency: - If the guest CPU can write to the mapping and something in the host besides the GPU might access the buffer, flush must be synchronous to ensure the host sees any guest changes. Waiting is not necessary if only the GPU can access the buffer because any subsequent commands will be properly ordered. - If the guest CPU can access the mapping and something in the host can write to the buffer, then invalidate must be synchronous to ensure the guest sees any host changes. To perform this synchronization, have the virtio_gpu backend wait for the transfer to/from the host to complete before returning from flush/invalidate. In the future, support for fence-based synchronization should also be added. BUG=b:120456557 b:136733358 TEST=arc-codec-test, ArcVideoPlayer Change-Id: If4ad293886a67d93d85b0d4a682b31c66597d4ef Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1687736 Reviewed-by: Gurchetan Singh Commit-Queue: David Stevens Tested-by: David Stevens --- drv_priv.h | 15 +++++++++------ virtio_gpu.c | 31 ++++++++++++++++++++++++++++--- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/drv_priv.h b/drv_priv.h index 1e0e75b..76fa443 100644 --- a/drv_priv.h +++ b/drv_priv.h @@ -75,16 +75,19 @@ struct backend { }; // clang-format off -#define BO_USE_RENDER_MASK BO_USE_LINEAR | BO_USE_PROTECTED | BO_USE_RENDERING | \ +#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 + 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 | \ +#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 + BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY | BO_USE_TEXTURE) -#define BO_USE_SW_MASK BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN | \ - BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY +#define BO_USE_SW_MASK (BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN | \ + BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY) + +#define BO_USE_NON_GPU_HW (BO_USE_SCANOUT | BO_USE_CAMERA_WRITE | BO_USE_CAMERA_READ | \ + BO_USE_HW_VIDEO_ENCODER | BO_USE_HW_VIDEO_DECODER) #ifndef DRM_FORMAT_MOD_LINEAR #define DRM_FORMAT_MOD_LINEAR DRM_FORMAT_MOD_NONE diff --git a/virtio_gpu.c b/virtio_gpu.c index edc8fc9..d6c9974 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -378,7 +378,8 @@ static int virtio_gpu_bo_invalidate(struct bo *bo, struct mapping *mapping) return 0; // Invalidate is only necessary if the host writes to the buffer. - if ((bo->meta.use_flags & BO_USE_RENDERING) == 0) + if ((bo->meta.use_flags & (BO_USE_RENDERING | BO_USE_CAMERA_WRITE | + BO_USE_HW_VIDEO_ENCODER | BO_USE_HW_VIDEO_DECODER)) == 0) return 0; memset(&xfer, 0, sizeof(xfer)); @@ -389,8 +390,16 @@ static int virtio_gpu_bo_invalidate(struct bo *bo, struct mapping *mapping) xfer.box.h = mapping->rect.height; xfer.box.d = 1; - // TODO(b/145993887): Send also stride when the patches are landed - // When BO_USE_RENDERING is set, the level=stride hack is not needed + if ((bo->meta.use_flags & BO_USE_RENDERING) == 0) { + // Unfortunately, the kernel doesn't actually pass the guest layer_stride and + // guest stride to the host (compare virtio_gpu.h and virtgpu_drm.h). For gbm + // based resources, we can work around this by using the level field to pass + // the stride to virglrenderer's gbm transfer code. However, we need to avoid + // doing this for resources which don't rely on that transfer code, which is + // resources with the BO_USE_RENDERING flag set. + // TODO(b/145993887): Send also stride when the patches are landed + xfer.level = bo->meta.strides[0]; + } ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST, &xfer); if (ret) { @@ -417,6 +426,7 @@ static int virtio_gpu_bo_flush(struct bo *bo, struct mapping *mapping) int ret; struct drm_virtgpu_3d_transfer_to_host xfer; struct virtio_gpu_priv *priv = (struct virtio_gpu_priv *)bo->drv->priv; + struct drm_virtgpu_3d_wait waitcmd; if (!priv->has_3d) return 0; @@ -443,6 +453,21 @@ static int virtio_gpu_bo_flush(struct bo *bo, struct mapping *mapping) return -errno; } + // If the buffer is only accessed by the host GPU, then the flush is ordered + // with subsequent commands. However, if other host hardware can access the + // buffer, we need to wait for the transfer to complete for consistency. + // TODO(b/136733358): Support returning fences from transfers + if (bo->meta.use_flags & BO_USE_NON_GPU_HW) { + memset(&waitcmd, 0, sizeof(waitcmd)); + waitcmd.handle = mapping->vma->handle; + + ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_WAIT, &waitcmd); + if (ret) { + drv_log("DRM_IOCTL_VIRTGPU_WAIT failed with %s\n", strerror(errno)); + return -errno; + } + } + return 0; } From eebce653c9d6d312f0bd0f6cd78b73c2eabf2c60 Mon Sep 17 00:00:00 2001 From: Lepton Wu Date: Wed, 26 Feb 2020 15:13:34 -0800 Subject: [PATCH 199/269] minigbm: virtio: Advertise BO_USE_SCANOUT correctly. If host doesn't support BO_USE_SCANOUT for some format, we shouldn't advertise it. Otherwise the bo will fail to allocate at host side with minigbm. BUG=b:145603024 TEST=tast run 127.0.0.1:9222 arc.Boot.vm Change-Id: I9e2c8141462b630bf18cc8859df607dca7b335c9 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2076580 Reviewed-by: Jason Macnak Reviewed-by: Gurchetan Singh Tested-by: Lepton Wu Commit-Queue: Lepton Wu Auto-Submit: Lepton Wu --- virgl_hw.h | 1 + virtio_gpu.c | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/virgl_hw.h b/virgl_hw.h index 8c169a7..145780b 100644 --- a/virgl_hw.h +++ b/virgl_hw.h @@ -400,6 +400,7 @@ struct virgl_caps_v2 { uint32_t max_combined_atomic_counter_buffers; uint32_t host_feature_check_version; struct virgl_supported_format_mask supported_readback_formats; + struct virgl_supported_format_mask scanout; }; union virgl_caps { diff --git a/virtio_gpu.c b/virtio_gpu.c index d6c9974..b061e8b 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -38,6 +38,7 @@ static const uint32_t texture_source_formats[] = { DRM_FORMAT_NV12, DRM_FORMAT_R struct virtio_gpu_priv { int has_3d; + int caps_is_v2; union virgl_caps caps; }; @@ -89,17 +90,22 @@ static void virtio_gpu_add_combination(struct driver *drv, uint32_t drm_format, struct virtio_gpu_priv *priv = (struct virtio_gpu_priv *)drv->priv; if (priv->has_3d) { - if ((use_flags & BO_USE_RENDERING) != 0 && + if ((use_flags & BO_USE_RENDERING) && !virtio_gpu_supports_format(&priv->caps.v1.render, drm_format)) { drv_log("Skipping unsupported render format: %d\n", drm_format); return; } - if ((use_flags & BO_USE_TEXTURE) != 0 && + if ((use_flags & BO_USE_TEXTURE) && !virtio_gpu_supports_format(&priv->caps.v1.sampler, drm_format)) { drv_log("Skipping unsupported texture format: %d\n", drm_format); return; } + if ((use_flags & BO_USE_SCANOUT) && priv->caps_is_v2 && + !virtio_gpu_supports_format(&priv->caps.v2.scanout, drm_format)) { + drv_log("Unsupported scanout format: %d\n", drm_format); + use_flags &= ~BO_USE_SCANOUT; + } } drv_add_combination(drv, drm_format, metadata, use_flags); @@ -229,7 +235,7 @@ static void *virtio_virgl_bo_map(struct bo *bo, struct vma *vma, size_t plane, u gem_map.offset); } -static int virtio_gpu_get_caps(struct driver *drv, union virgl_caps *caps) +static int virtio_gpu_get_caps(struct driver *drv, union virgl_caps *caps, int *caps_is_v2) { int ret; struct drm_virtgpu_get_caps cap_args; @@ -244,9 +250,11 @@ static int virtio_gpu_get_caps(struct driver *drv, union virgl_caps *caps) drv_log("DRM_IOCTL_VIRTGPU_GETPARAM failed with %s\n", strerror(errno)); } + *caps_is_v2 = 0; memset(&cap_args, 0, sizeof(cap_args)); cap_args.addr = (unsigned long long)caps; if (can_query_v2) { + *caps_is_v2 = 1; cap_args.cap_set_id = 2; cap_args.size = sizeof(union virgl_caps); } else { @@ -257,6 +265,7 @@ static int virtio_gpu_get_caps(struct driver *drv, union virgl_caps *caps) ret = drmIoctl(drv->fd, DRM_IOCTL_VIRTGPU_GET_CAPS, &cap_args); if (ret) { drv_log("DRM_IOCTL_VIRTGPU_GET_CAPS failed with %s\n", strerror(errno)); + *caps_is_v2 = 0; // Fallback to v1 cap_args.cap_set_id = 1; @@ -291,7 +300,7 @@ static int virtio_gpu_init(struct driver *drv) } if (priv->has_3d) { - virtio_gpu_get_caps(drv, &priv->caps); + virtio_gpu_get_caps(drv, &priv->caps, &priv->caps_is_v2); /* This doesn't mean host can scanout everything, it just means host * hypervisor can show it. */ From afb2c56b57fe762c051fdc3804b6b75736b6ec91 Mon Sep 17 00:00:00 2001 From: Jeffrey Kardatzke Date: Mon, 2 Mar 2020 12:25:55 -0800 Subject: [PATCH 200/269] minigbm/msm: Update msm for removal of kms_query Recently kms_query was removed which then caused the NV12 texture format here to use UBWC, which is incorrect currently. This updates the msm code similar to other changes. I'm somewhat guessing at this, so please review this thoroughly. BUG=b:149190288 TEST=VDA tests pass on trogdor again Change-Id: Ie3370623d324f8378d03bcc3562cd17561f5ba01 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2083720 Tested-by: Jeffrey Kardatzke Reviewed-by: Kristian H. Kristensen Commit-Queue: Jeffrey Kardatzke --- msm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/msm.c b/msm.c index a640599..5771f6e 100644 --- a/msm.c +++ b/msm.c @@ -160,7 +160,7 @@ static void msm_add_ubwc_combinations(struct driver *drv, const uint32_t *format static int msm_init(struct driver *drv) { struct format_metadata metadata; - uint64_t render_use_flags = BO_USE_RENDER_MASK; + uint64_t render_use_flags = BO_USE_RENDER_MASK | BO_USE_SCANOUT; uint64_t texture_use_flags = BO_USE_TEXTURE_MASK | BO_USE_HW_VIDEO_DECODER; uint64_t sw_flags = (BO_USE_RENDERSCRIPT | BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_OFTEN | BO_USE_LINEAR | BO_USE_PROTECTED); @@ -180,7 +180,7 @@ static int msm_init(struct driver *drv) /* The camera stack standardizes on NV12 for YUV buffers. */ drv_modify_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA, - BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_SCANOUT); /* * R8 format is used for Android's HAL_PIXEL_FORMAT_BLOB and is used for JPEG snapshots * from camera. @@ -201,7 +201,7 @@ static int msm_init(struct driver *drv) texture_use_flags &= ~sw_flags; msm_add_ubwc_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &metadata, render_use_flags | BO_USE_SCANOUT); + &metadata, render_use_flags); msm_add_ubwc_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), &metadata, texture_use_flags); From f0e607c7d436134b53fd45a4ead36d714451be8a Mon Sep 17 00:00:00 2001 From: David Stevens Date: Wed, 25 Dec 2019 16:43:36 +0900 Subject: [PATCH 201/269] minigbm: introduce test allocation This change introduces a GBM_TEST_ALLOC flag to minigbm, which allows for the creation of fake buffers that can be used to determine buffer metadata without actually allocating a full buffer. The new flag is supported by the i915 backends. This flag also alleviates the need to cache buffers when virtio_gpu queries metadata properties. BUG=b:145994510 TEST=play youtube with arcvm demo image plus this and virgl change Change-Id: I9c6819aa3b5b674e4bb33b0656f2a9f155b0884e Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1980688 Tested-by: David Stevens Reviewed-by: Gurchetan Singh Commit-Queue: David Stevens --- drv.c | 89 ++++++++++++++++++++++++++++++++++++++++++------------ drv.h | 6 ++-- drv_priv.h | 7 +++++ gbm.h | 9 ++++++ i915.c | 66 ++++++++++++++++++---------------------- 5 files changed, 119 insertions(+), 58 deletions(-) diff --git a/drv.c b/drv.c index dcca838..e5e0be6 100644 --- a/drv.c +++ b/drv.c @@ -114,11 +114,21 @@ static const struct backend *drv_get_backend(int fd) &backend_vgem, &backend_virtio_gpu, }; - for (i = 0; i < ARRAY_SIZE(backend_list); i++) - if (!strcmp(drm_version->name, backend_list[i]->name)) { + for (i = 0; i < ARRAY_SIZE(backend_list); i++) { + const struct backend *b = backend_list[i]; + // Exactly one of the main create functions must be defined. + assert((b->bo_create != NULL) ^ (b->bo_create_from_metadata != NULL)); + // Either both or neither must be implemented. + assert((b->bo_compute_metadata != NULL) == (b->bo_create_from_metadata != NULL)); + // Both can't be defined, but it's okay for neither to be (i.e. only bo_create). + assert((b->bo_create_with_modifiers == NULL) || + (b->bo_create_from_metadata == NULL)); + + if (!strcmp(drm_version->name, b->name)) { drmFreeVersion(drm_version); - return backend_list[i]; + return b; } + } drmFreeVersion(drm_version); return NULL; @@ -223,7 +233,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 use_flags) + uint64_t use_flags, bool is_test_buffer) { struct bo *bo; @@ -238,6 +248,7 @@ struct bo *drv_bo_new(struct driver *drv, uint32_t width, uint32_t height, uint3 bo->meta.format = format; bo->meta.use_flags = use_flags; bo->meta.num_planes = drv_num_planes_from_format(format); + bo->is_test_buffer = is_test_buffer; if (!bo->meta.num_planes) { free(bo); @@ -253,13 +264,28 @@ struct bo *drv_bo_create(struct driver *drv, uint32_t width, uint32_t height, ui int ret; size_t plane; struct bo *bo; + bool is_test_alloc; + + is_test_alloc = use_flags & BO_USE_TEST_ALLOC; + use_flags &= ~BO_USE_TEST_ALLOC; - bo = drv_bo_new(drv, width, height, format, use_flags); + bo = drv_bo_new(drv, width, height, format, use_flags, is_test_alloc); if (!bo) return NULL; - ret = drv->backend->bo_create(bo, width, height, format, use_flags); + ret = -EINVAL; + if (drv->backend->bo_compute_metadata) { + ret = drv->backend->bo_compute_metadata(bo, width, height, format, use_flags, NULL, + 0); + if (!is_test_alloc && ret == 0) { + ret = drv->backend->bo_create_from_metadata(bo); + if (ret == 0) + return bo; + } + } else if (!is_test_alloc) { + ret = drv->backend->bo_create(bo, width, height, format, use_flags); + } if (ret) { free(bo); @@ -287,17 +313,26 @@ struct bo *drv_bo_create_with_modifiers(struct driver *drv, uint32_t width, uint size_t plane; struct bo *bo; - if (!drv->backend->bo_create_with_modifiers) { + if (!drv->backend->bo_create_with_modifiers && !drv->backend->bo_compute_metadata) { errno = ENOENT; return NULL; } - bo = drv_bo_new(drv, width, height, format, BO_USE_NONE); + bo = drv_bo_new(drv, width, height, format, BO_USE_NONE, false); if (!bo) return NULL; - ret = drv->backend->bo_create_with_modifiers(bo, width, height, format, modifiers, count); + ret = -EINVAL; + if (drv->backend->bo_compute_metadata) { + ret = drv->backend->bo_compute_metadata(bo, width, height, format, BO_USE_NONE, + modifiers, count); + if (ret == 0) + ret = drv->backend->bo_create_from_metadata(bo); + } else { + ret = drv->backend->bo_create_with_modifiers(bo, width, height, format, modifiers, + count); + } if (ret) { free(bo); @@ -325,20 +360,22 @@ void drv_bo_destroy(struct bo *bo) uintptr_t total = 0; struct driver *drv = bo->drv; - pthread_mutex_lock(&drv->driver_lock); + if (!bo->is_test_buffer) { + pthread_mutex_lock(&drv->driver_lock); - for (plane = 0; plane < bo->meta.num_planes; plane++) - drv_decrement_reference_count(drv, bo, plane); + for (plane = 0; plane < bo->meta.num_planes; plane++) + drv_decrement_reference_count(drv, bo, plane); - for (plane = 0; plane < bo->meta.num_planes; plane++) - total += drv_get_reference_count(drv, bo, plane); + for (plane = 0; plane < bo->meta.num_planes; plane++) + total += drv_get_reference_count(drv, bo, plane); - pthread_mutex_unlock(&drv->driver_lock); + pthread_mutex_unlock(&drv->driver_lock); - if (total == 0) { - ret = drv_mapping_destroy(bo); - assert(ret == 0); - bo->drv->backend->bo_destroy(bo); + if (total == 0) { + ret = drv_mapping_destroy(bo); + assert(ret == 0); + bo->drv->backend->bo_destroy(bo); + } } free(bo); @@ -351,7 +388,7 @@ struct bo *drv_bo_import(struct driver *drv, struct drv_import_fd_data *data) struct bo *bo; off_t seek_end; - bo = drv_bo_new(drv, data->width, data->height, data->format, data->use_flags); + bo = drv_bo_new(drv, data->width, data->height, data->format, data->use_flags, false); if (!bo) return NULL; @@ -415,6 +452,10 @@ void *drv_bo_map(struct bo *bo, const struct rectangle *rect, uint32_t map_flags /* No CPU access for protected buffers. */ assert(!(bo->meta.use_flags & BO_USE_PROTECTED)); + if (bo->is_test_buffer) { + return MAP_FAILED; + } + memset(&mapping, 0, sizeof(mapping)); mapping.rect = *rect; mapping.refcount = 1; @@ -562,6 +603,10 @@ int drv_bo_get_plane_fd(struct bo *bo, size_t plane) int ret, fd; assert(plane < bo->meta.num_planes); + if (bo->is_test_buffer) { + return -EINVAL; + } + ret = drmPrimeHandleToFD(bo->drv->fd, bo->handles[plane].u32, DRM_CLOEXEC | DRM_RDWR, &fd); // Older DRM implementations blocked DRM_RDWR, but gave a read/write mapping anyways @@ -613,6 +658,10 @@ uint32_t drv_num_buffers_per_bo(struct bo *bo) uint32_t count = 0; size_t plane, p; + if (bo->is_test_buffer) { + return 0; + } + for (plane = 0; plane < bo->meta.num_planes; plane++) { for (p = 0; p < plane; p++) if (bo->handles[p].u32 == bo->handles[plane].u32) diff --git a/drv.h b/drv.h index 39fd5dd..937487b 100644 --- a/drv.h +++ b/drv.h @@ -12,6 +12,7 @@ extern "C" { #endif #include +#include #include #define DRV_MAX_PLANES 4 @@ -35,7 +36,8 @@ extern "C" { #define BO_USE_SW_WRITE_RARELY (1ull << 12) #define BO_USE_HW_VIDEO_DECODER (1ull << 13) #define BO_USE_HW_VIDEO_ENCODER (1ull << 14) -#define BO_USE_RENDERSCRIPT (1ull << 15) +#define BO_USE_TEST_ALLOC (1ull << 15) +#define BO_USE_RENDERSCRIPT (1ull << 16) /* Quirks for allocating a buffer. */ #define BO_QUIRK_NONE 0 @@ -124,7 +126,7 @@ const char *drv_get_name(struct driver *drv); 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 use_flags); + uint64_t use_flags, bool is_test_buffer); struct bo *drv_bo_create(struct driver *drv, uint32_t width, uint32_t height, uint32_t format, uint64_t use_flags); diff --git a/drv_priv.h b/drv_priv.h index 76fa443..31ab892 100644 --- a/drv_priv.h +++ b/drv_priv.h @@ -8,6 +8,7 @@ #define DRV_PRIV_H #include +#include #include #include #include @@ -31,6 +32,7 @@ struct bo_metadata { struct bo { struct driver *drv; struct bo_metadata meta; + bool is_test_buffer; union bo_handle handles[DRV_MAX_PLANES]; void *priv; }; @@ -65,6 +67,11 @@ struct backend { 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); + // Either both or neither _metadata functions must be implemented. + // If the functions are implemented, bo_create and bo_create_with_modifiers must not be. + int (*bo_compute_metadata)(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint64_t use_flags, const uint64_t *modifiers, uint32_t count); + int (*bo_create_from_metadata)(struct bo *bo); 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 vma *vma, size_t plane, uint32_t map_flags); diff --git a/gbm.h b/gbm.h index 4993b5c..2492728 100644 --- a/gbm.h +++ b/gbm.h @@ -271,6 +271,15 @@ enum gbm_bo_flags { * The buffer will be read by a video encode accelerator. */ GBM_BO_USE_HW_VIDEO_ENCODER = (1 << 14), + + /** + * If this flag is set, no backing memory will be allocated for the + * created buffer. The metadata of the buffer (e.g. size) can be + * queried, and the values will be equal to a buffer allocated with + * the same same arguments minus this flag. However, any methods + * which would otherwise access the underlying buffer will fail. + */ + GBM_TEST_ALLOC = (1 << 15), }; int diff --git a/i915.c b/i915.c index d0c9db1..05c8272 100644 --- a/i915.c +++ b/i915.c @@ -268,13 +268,26 @@ static int i915_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, u return 0; } -static int i915_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t height, - uint32_t format, uint64_t modifier) +static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint64_t use_flags, const uint64_t *modifiers, uint32_t count) { - int ret; - size_t plane; - struct drm_i915_gem_create gem_create; - struct drm_i915_gem_set_tiling gem_set_tiling; + static const uint64_t modifier_order[] = { + I915_FORMAT_MOD_Y_TILED_CCS, + I915_FORMAT_MOD_Y_TILED, + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, + }; + uint64_t modifier; + + if (modifiers) { + modifier = + drv_pick_modifier(modifiers, count, modifier_order, ARRAY_SIZE(modifier_order)); + } else { + struct combination *combo = drv_get_combination(bo->drv, format, use_flags); + if (!combo) + return -EINVAL; + modifier = combo->metadata.modifier; + } switch (modifier) { case DRM_FORMAT_MOD_LINEAR: @@ -346,6 +359,15 @@ static int i915_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t h } else { i915_bo_from_format(bo, width, height, format); } + return 0; +} + +static int i915_bo_create_from_metadata(struct bo *bo) +{ + int ret; + size_t plane; + struct drm_i915_gem_create gem_create; + struct drm_i915_gem_set_tiling gem_set_tiling; memset(&gem_create, 0, sizeof(gem_create)); gem_create.size = bo->meta.total_size; @@ -378,34 +400,6 @@ static int i915_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t h 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_CCS, - 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)); - - return i915_bo_create_for_modifier(bo, width, height, format, modifier); -} - static void i915_close(struct driver *drv) { free(drv->priv); @@ -561,8 +555,8 @@ 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_compute_metadata = i915_bo_compute_metadata, + .bo_create_from_metadata = i915_bo_create_from_metadata, .bo_destroy = drv_gem_bo_destroy, .bo_import = i915_bo_import, .bo_map = i915_bo_map, From c5352e6b363e47e2f3ad6765ad95c94d4e9c7923 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Fri, 21 Feb 2020 17:59:01 -0800 Subject: [PATCH 202/269] minigbm: vc4: add create_with_modifiers function Change-Id: Iedba297cbcf69e3c87165bd54fce316b75a7a530 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2068463 Reviewed-by: Ewan Roycroft Reviewed-by: Gurchetan Singh Commit-Queue: Gurchetan Singh Tested-by: Gurchetan Singh --- vc4.c | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/vc4.c b/vc4.c index 7af16c2..06b3ed7 100644 --- a/vc4.c +++ b/vc4.c @@ -28,14 +28,24 @@ static int vc4_init(struct driver *drv) return drv_modify_linear_combinations(drv); } -static int vc4_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, - uint64_t use_flags) +static int vc4_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_vc4_create_bo bo_create; + switch (modifier) { + case DRM_FORMAT_MOD_LINEAR: + break; + case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED: + drv_log("DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED not supported yet\n"); + return -EINVAL; + default: + return -EINVAL; + } + /* * Since the ARM L1 cache line size is 64 bytes, align to that as a * performance optimization. @@ -59,6 +69,31 @@ static int vc4_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_ return 0; } +static int vc4_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 vc4_bo_create_for_modifier(bo, width, height, format, combo->metadata.modifier); +} + +static int vc4_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[] = { + DRM_FORMAT_MOD_LINEAR, + }; + uint64_t modifier; + + modifier = drv_pick_modifier(modifiers, count, modifier_order, ARRAY_SIZE(modifier_order)); + + return vc4_bo_create_for_modifier(bo, width, height, format, modifier); +} + static void *vc4_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags) { int ret; @@ -82,6 +117,7 @@ const struct backend backend_vc4 = { .name = "vc4", .init = vc4_init, .bo_create = vc4_bo_create, + .bo_create_with_modifiers = vc4_bo_create_with_modifiers, .bo_import = drv_prime_bo_import, .bo_destroy = drv_gem_bo_destroy, .bo_map = vc4_bo_map, From 08d8dbf094fdc5aa9b92c7257e292edcf28602b2 Mon Sep 17 00:00:00 2001 From: "Ilja H. Friedel" Date: Sun, 8 Mar 2020 04:48:13 +0000 Subject: [PATCH 203/269] Revert "minigbm: introduce test allocation" This reverts commit f0e607c7d436134b53fd45a4ead36d714451be8a. Reason for revert: caused flaky regressions across the board. BUG=b:150997559 Exempt-From-Owner-Approval: revert. Original change's description: > minigbm: introduce test allocation > > This change introduces a GBM_TEST_ALLOC flag to minigbm, which allows > for the creation of fake buffers that can be used to determine buffer > metadata without actually allocating a full buffer. The new flag is > supported by the i915 backends. This flag also alleviates the need to > cache buffers when virtio_gpu queries metadata properties. > > BUG=b:145994510 > TEST=play youtube with arcvm demo image plus this and virgl change > > Change-Id: I9c6819aa3b5b674e4bb33b0656f2a9f155b0884e > Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1980688 > Tested-by: David Stevens > Reviewed-by: Gurchetan Singh > Commit-Queue: David Stevens Bug: b:145994510 Change-Id: I50079b7f0aabf38e1f373cac0f28c0e057eed760 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2093923 Commit-Queue: Ilja H. Friedel Tested-by: Ilja H. Friedel Reviewed-by: Ilja H. Friedel --- drv.c | 89 ++++++++++++------------------------------------------ drv.h | 6 ++-- drv_priv.h | 7 ----- gbm.h | 9 ------ i915.c | 66 ++++++++++++++++++++++------------------ 5 files changed, 58 insertions(+), 119 deletions(-) diff --git a/drv.c b/drv.c index e5e0be6..dcca838 100644 --- a/drv.c +++ b/drv.c @@ -114,21 +114,11 @@ static const struct backend *drv_get_backend(int fd) &backend_vgem, &backend_virtio_gpu, }; - for (i = 0; i < ARRAY_SIZE(backend_list); i++) { - const struct backend *b = backend_list[i]; - // Exactly one of the main create functions must be defined. - assert((b->bo_create != NULL) ^ (b->bo_create_from_metadata != NULL)); - // Either both or neither must be implemented. - assert((b->bo_compute_metadata != NULL) == (b->bo_create_from_metadata != NULL)); - // Both can't be defined, but it's okay for neither to be (i.e. only bo_create). - assert((b->bo_create_with_modifiers == NULL) || - (b->bo_create_from_metadata == NULL)); - - if (!strcmp(drm_version->name, b->name)) { + for (i = 0; i < ARRAY_SIZE(backend_list); i++) + if (!strcmp(drm_version->name, backend_list[i]->name)) { drmFreeVersion(drm_version); - return b; + return backend_list[i]; } - } drmFreeVersion(drm_version); return NULL; @@ -233,7 +223,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 use_flags, bool is_test_buffer) + uint64_t use_flags) { struct bo *bo; @@ -248,7 +238,6 @@ struct bo *drv_bo_new(struct driver *drv, uint32_t width, uint32_t height, uint3 bo->meta.format = format; bo->meta.use_flags = use_flags; bo->meta.num_planes = drv_num_planes_from_format(format); - bo->is_test_buffer = is_test_buffer; if (!bo->meta.num_planes) { free(bo); @@ -264,28 +253,13 @@ struct bo *drv_bo_create(struct driver *drv, uint32_t width, uint32_t height, ui int ret; size_t plane; struct bo *bo; - bool is_test_alloc; - - is_test_alloc = use_flags & BO_USE_TEST_ALLOC; - use_flags &= ~BO_USE_TEST_ALLOC; - bo = drv_bo_new(drv, width, height, format, use_flags, is_test_alloc); + bo = drv_bo_new(drv, width, height, format, use_flags); if (!bo) return NULL; - ret = -EINVAL; - if (drv->backend->bo_compute_metadata) { - ret = drv->backend->bo_compute_metadata(bo, width, height, format, use_flags, NULL, - 0); - if (!is_test_alloc && ret == 0) { - ret = drv->backend->bo_create_from_metadata(bo); - if (ret == 0) - return bo; - } - } else if (!is_test_alloc) { - ret = drv->backend->bo_create(bo, width, height, format, use_flags); - } + ret = drv->backend->bo_create(bo, width, height, format, use_flags); if (ret) { free(bo); @@ -313,26 +287,17 @@ struct bo *drv_bo_create_with_modifiers(struct driver *drv, uint32_t width, uint size_t plane; struct bo *bo; - if (!drv->backend->bo_create_with_modifiers && !drv->backend->bo_compute_metadata) { + if (!drv->backend->bo_create_with_modifiers) { errno = ENOENT; return NULL; } - bo = drv_bo_new(drv, width, height, format, BO_USE_NONE, false); + bo = drv_bo_new(drv, width, height, format, BO_USE_NONE); if (!bo) return NULL; - ret = -EINVAL; - if (drv->backend->bo_compute_metadata) { - ret = drv->backend->bo_compute_metadata(bo, width, height, format, BO_USE_NONE, - modifiers, count); - if (ret == 0) - ret = drv->backend->bo_create_from_metadata(bo); - } else { - ret = drv->backend->bo_create_with_modifiers(bo, width, height, format, modifiers, - count); - } + ret = drv->backend->bo_create_with_modifiers(bo, width, height, format, modifiers, count); if (ret) { free(bo); @@ -360,22 +325,20 @@ void drv_bo_destroy(struct bo *bo) uintptr_t total = 0; struct driver *drv = bo->drv; - if (!bo->is_test_buffer) { - pthread_mutex_lock(&drv->driver_lock); + pthread_mutex_lock(&drv->driver_lock); - for (plane = 0; plane < bo->meta.num_planes; plane++) - drv_decrement_reference_count(drv, bo, plane); + for (plane = 0; plane < bo->meta.num_planes; plane++) + drv_decrement_reference_count(drv, bo, plane); - for (plane = 0; plane < bo->meta.num_planes; plane++) - total += drv_get_reference_count(drv, bo, plane); + for (plane = 0; plane < bo->meta.num_planes; plane++) + total += drv_get_reference_count(drv, bo, plane); - pthread_mutex_unlock(&drv->driver_lock); + pthread_mutex_unlock(&drv->driver_lock); - if (total == 0) { - ret = drv_mapping_destroy(bo); - assert(ret == 0); - bo->drv->backend->bo_destroy(bo); - } + if (total == 0) { + ret = drv_mapping_destroy(bo); + assert(ret == 0); + bo->drv->backend->bo_destroy(bo); } free(bo); @@ -388,7 +351,7 @@ struct bo *drv_bo_import(struct driver *drv, struct drv_import_fd_data *data) struct bo *bo; off_t seek_end; - bo = drv_bo_new(drv, data->width, data->height, data->format, data->use_flags, false); + bo = drv_bo_new(drv, data->width, data->height, data->format, data->use_flags); if (!bo) return NULL; @@ -452,10 +415,6 @@ void *drv_bo_map(struct bo *bo, const struct rectangle *rect, uint32_t map_flags /* No CPU access for protected buffers. */ assert(!(bo->meta.use_flags & BO_USE_PROTECTED)); - if (bo->is_test_buffer) { - return MAP_FAILED; - } - memset(&mapping, 0, sizeof(mapping)); mapping.rect = *rect; mapping.refcount = 1; @@ -603,10 +562,6 @@ int drv_bo_get_plane_fd(struct bo *bo, size_t plane) int ret, fd; assert(plane < bo->meta.num_planes); - if (bo->is_test_buffer) { - return -EINVAL; - } - ret = drmPrimeHandleToFD(bo->drv->fd, bo->handles[plane].u32, DRM_CLOEXEC | DRM_RDWR, &fd); // Older DRM implementations blocked DRM_RDWR, but gave a read/write mapping anyways @@ -658,10 +613,6 @@ uint32_t drv_num_buffers_per_bo(struct bo *bo) uint32_t count = 0; size_t plane, p; - if (bo->is_test_buffer) { - return 0; - } - for (plane = 0; plane < bo->meta.num_planes; plane++) { for (p = 0; p < plane; p++) if (bo->handles[p].u32 == bo->handles[plane].u32) diff --git a/drv.h b/drv.h index 937487b..39fd5dd 100644 --- a/drv.h +++ b/drv.h @@ -12,7 +12,6 @@ extern "C" { #endif #include -#include #include #define DRV_MAX_PLANES 4 @@ -36,8 +35,7 @@ extern "C" { #define BO_USE_SW_WRITE_RARELY (1ull << 12) #define BO_USE_HW_VIDEO_DECODER (1ull << 13) #define BO_USE_HW_VIDEO_ENCODER (1ull << 14) -#define BO_USE_TEST_ALLOC (1ull << 15) -#define BO_USE_RENDERSCRIPT (1ull << 16) +#define BO_USE_RENDERSCRIPT (1ull << 15) /* Quirks for allocating a buffer. */ #define BO_QUIRK_NONE 0 @@ -126,7 +124,7 @@ const char *drv_get_name(struct driver *drv); 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 use_flags, bool is_test_buffer); + uint64_t use_flags); struct bo *drv_bo_create(struct driver *drv, uint32_t width, uint32_t height, uint32_t format, uint64_t use_flags); diff --git a/drv_priv.h b/drv_priv.h index 31ab892..76fa443 100644 --- a/drv_priv.h +++ b/drv_priv.h @@ -8,7 +8,6 @@ #define DRV_PRIV_H #include -#include #include #include #include @@ -32,7 +31,6 @@ struct bo_metadata { struct bo { struct driver *drv; struct bo_metadata meta; - bool is_test_buffer; union bo_handle handles[DRV_MAX_PLANES]; void *priv; }; @@ -67,11 +65,6 @@ struct backend { 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); - // Either both or neither _metadata functions must be implemented. - // If the functions are implemented, bo_create and bo_create_with_modifiers must not be. - int (*bo_compute_metadata)(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, - uint64_t use_flags, const uint64_t *modifiers, uint32_t count); - int (*bo_create_from_metadata)(struct bo *bo); 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 vma *vma, size_t plane, uint32_t map_flags); diff --git a/gbm.h b/gbm.h index 2492728..4993b5c 100644 --- a/gbm.h +++ b/gbm.h @@ -271,15 +271,6 @@ enum gbm_bo_flags { * The buffer will be read by a video encode accelerator. */ GBM_BO_USE_HW_VIDEO_ENCODER = (1 << 14), - - /** - * If this flag is set, no backing memory will be allocated for the - * created buffer. The metadata of the buffer (e.g. size) can be - * queried, and the values will be equal to a buffer allocated with - * the same same arguments minus this flag. However, any methods - * which would otherwise access the underlying buffer will fail. - */ - GBM_TEST_ALLOC = (1 << 15), }; int diff --git a/i915.c b/i915.c index 05c8272..d0c9db1 100644 --- a/i915.c +++ b/i915.c @@ -268,26 +268,13 @@ static int i915_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, u return 0; } -static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, - uint64_t use_flags, const uint64_t *modifiers, uint32_t count) +static int i915_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t height, + uint32_t format, uint64_t modifier) { - static const uint64_t modifier_order[] = { - I915_FORMAT_MOD_Y_TILED_CCS, - I915_FORMAT_MOD_Y_TILED, - I915_FORMAT_MOD_X_TILED, - DRM_FORMAT_MOD_LINEAR, - }; - uint64_t modifier; - - if (modifiers) { - modifier = - drv_pick_modifier(modifiers, count, modifier_order, ARRAY_SIZE(modifier_order)); - } else { - struct combination *combo = drv_get_combination(bo->drv, format, use_flags); - if (!combo) - return -EINVAL; - modifier = combo->metadata.modifier; - } + int ret; + size_t plane; + struct drm_i915_gem_create gem_create; + struct drm_i915_gem_set_tiling gem_set_tiling; switch (modifier) { case DRM_FORMAT_MOD_LINEAR: @@ -359,15 +346,6 @@ static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t heig } else { i915_bo_from_format(bo, width, height, format); } - return 0; -} - -static int i915_bo_create_from_metadata(struct bo *bo) -{ - int ret; - size_t plane; - struct drm_i915_gem_create gem_create; - struct drm_i915_gem_set_tiling gem_set_tiling; memset(&gem_create, 0, sizeof(gem_create)); gem_create.size = bo->meta.total_size; @@ -400,6 +378,34 @@ static int i915_bo_create_from_metadata(struct bo *bo) 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_CCS, + 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)); + + return i915_bo_create_for_modifier(bo, width, height, format, modifier); +} + static void i915_close(struct driver *drv) { free(drv->priv); @@ -555,8 +561,8 @@ const struct backend backend_i915 = { .name = "i915", .init = i915_init, .close = i915_close, - .bo_compute_metadata = i915_bo_compute_metadata, - .bo_create_from_metadata = i915_bo_create_from_metadata, + .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, From 26fe6823066a0cf50b396d24b234756398be6f55 Mon Sep 17 00:00:00 2001 From: David Stevens Date: Mon, 9 Mar 2020 12:23:42 +0000 Subject: [PATCH 204/269] Reland "minigbm: introduce test allocation" This reverts commit 08d8dbf094fdc5aa9b92c7257e292edcf28602b2. The original change returned early from drv_bo_create_with_modifiers, which broke reference counting. This must have hit some race condition in the tests, as they no longer flake after fixing reference counting. Original change's description: > Revert "minigbm: introduce test allocation" > > This reverts commit f0e607c7d436134b53fd45a4ead36d714451be8a. > > Reason for revert: caused flaky regressions across the board. > > BUG=b:150997559 > Exempt-From-Owner-Approval: revert. > > Original change's description: > > minigbm: introduce test allocation > > > > This change introduces a GBM_TEST_ALLOC flag to minigbm, which allows > > for the creation of fake buffers that can be used to determine buffer > > metadata without actually allocating a full buffer. The new flag is > > supported by the i915 backends. This flag also alleviates the need to > > cache buffers when virtio_gpu queries metadata properties. > > > > BUG=b:145994510 > > TEST=play youtube with arcvm demo image plus this and virgl change > > > > Change-Id: I9c6819aa3b5b674e4bb33b0656f2a9f155b0884e > > Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1980688 > > Tested-by: David Stevens > > Reviewed-by: Gurchetan Singh > > Commit-Queue: David Stevens > > Bug: b:145994510 > Change-Id: I50079b7f0aabf38e1f373cac0f28c0e057eed760 > Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2093923 > Commit-Queue: Ilja H. Friedel > Tested-by: Ilja H. Friedel > Reviewed-by: Ilja H. Friedel Bug: b:150997559, b:145994510 Change-Id: If0f02a4701bb6960b6413d6b0c00b481146914d9 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2094068 Reviewed-by: Gurchetan Singh Commit-Queue: David Stevens Tested-by: David Stevens --- drv.c | 86 +++++++++++++++++++++++++++++++++++++++++------------- drv.h | 6 ++-- drv_priv.h | 7 +++++ gbm.h | 9 ++++++ i915.c | 66 +++++++++++++++++++---------------------- 5 files changed, 116 insertions(+), 58 deletions(-) diff --git a/drv.c b/drv.c index dcca838..52f26a5 100644 --- a/drv.c +++ b/drv.c @@ -114,11 +114,21 @@ static const struct backend *drv_get_backend(int fd) &backend_vgem, &backend_virtio_gpu, }; - for (i = 0; i < ARRAY_SIZE(backend_list); i++) - if (!strcmp(drm_version->name, backend_list[i]->name)) { + for (i = 0; i < ARRAY_SIZE(backend_list); i++) { + const struct backend *b = backend_list[i]; + // Exactly one of the main create functions must be defined. + assert((b->bo_create != NULL) ^ (b->bo_create_from_metadata != NULL)); + // Either both or neither must be implemented. + assert((b->bo_compute_metadata != NULL) == (b->bo_create_from_metadata != NULL)); + // Both can't be defined, but it's okay for neither to be (i.e. only bo_create). + assert((b->bo_create_with_modifiers == NULL) || + (b->bo_create_from_metadata == NULL)); + + if (!strcmp(drm_version->name, b->name)) { drmFreeVersion(drm_version); - return backend_list[i]; + return b; } + } drmFreeVersion(drm_version); return NULL; @@ -223,7 +233,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 use_flags) + uint64_t use_flags, bool is_test_buffer) { struct bo *bo; @@ -238,6 +248,7 @@ struct bo *drv_bo_new(struct driver *drv, uint32_t width, uint32_t height, uint3 bo->meta.format = format; bo->meta.use_flags = use_flags; bo->meta.num_planes = drv_num_planes_from_format(format); + bo->is_test_buffer = is_test_buffer; if (!bo->meta.num_planes) { free(bo); @@ -253,13 +264,25 @@ struct bo *drv_bo_create(struct driver *drv, uint32_t width, uint32_t height, ui int ret; size_t plane; struct bo *bo; + bool is_test_alloc; + + is_test_alloc = use_flags & BO_USE_TEST_ALLOC; + use_flags &= ~BO_USE_TEST_ALLOC; - bo = drv_bo_new(drv, width, height, format, use_flags); + bo = drv_bo_new(drv, width, height, format, use_flags, is_test_alloc); if (!bo) return NULL; - ret = drv->backend->bo_create(bo, width, height, format, use_flags); + ret = -EINVAL; + if (drv->backend->bo_compute_metadata) { + ret = drv->backend->bo_compute_metadata(bo, width, height, format, use_flags, NULL, + 0); + if (!is_test_alloc && ret == 0) + ret = drv->backend->bo_create_from_metadata(bo); + } else if (!is_test_alloc) { + ret = drv->backend->bo_create(bo, width, height, format, use_flags); + } if (ret) { free(bo); @@ -287,17 +310,26 @@ struct bo *drv_bo_create_with_modifiers(struct driver *drv, uint32_t width, uint size_t plane; struct bo *bo; - if (!drv->backend->bo_create_with_modifiers) { + if (!drv->backend->bo_create_with_modifiers && !drv->backend->bo_compute_metadata) { errno = ENOENT; return NULL; } - bo = drv_bo_new(drv, width, height, format, BO_USE_NONE); + bo = drv_bo_new(drv, width, height, format, BO_USE_NONE, false); if (!bo) return NULL; - ret = drv->backend->bo_create_with_modifiers(bo, width, height, format, modifiers, count); + ret = -EINVAL; + if (drv->backend->bo_compute_metadata) { + ret = drv->backend->bo_compute_metadata(bo, width, height, format, BO_USE_NONE, + modifiers, count); + if (ret == 0) + ret = drv->backend->bo_create_from_metadata(bo); + } else { + ret = drv->backend->bo_create_with_modifiers(bo, width, height, format, modifiers, + count); + } if (ret) { free(bo); @@ -325,20 +357,22 @@ void drv_bo_destroy(struct bo *bo) uintptr_t total = 0; struct driver *drv = bo->drv; - pthread_mutex_lock(&drv->driver_lock); + if (!bo->is_test_buffer) { + pthread_mutex_lock(&drv->driver_lock); - for (plane = 0; plane < bo->meta.num_planes; plane++) - drv_decrement_reference_count(drv, bo, plane); + for (plane = 0; plane < bo->meta.num_planes; plane++) + drv_decrement_reference_count(drv, bo, plane); - for (plane = 0; plane < bo->meta.num_planes; plane++) - total += drv_get_reference_count(drv, bo, plane); + for (plane = 0; plane < bo->meta.num_planes; plane++) + total += drv_get_reference_count(drv, bo, plane); - pthread_mutex_unlock(&drv->driver_lock); + pthread_mutex_unlock(&drv->driver_lock); - if (total == 0) { - ret = drv_mapping_destroy(bo); - assert(ret == 0); - bo->drv->backend->bo_destroy(bo); + if (total == 0) { + ret = drv_mapping_destroy(bo); + assert(ret == 0); + bo->drv->backend->bo_destroy(bo); + } } free(bo); @@ -351,7 +385,7 @@ struct bo *drv_bo_import(struct driver *drv, struct drv_import_fd_data *data) struct bo *bo; off_t seek_end; - bo = drv_bo_new(drv, data->width, data->height, data->format, data->use_flags); + bo = drv_bo_new(drv, data->width, data->height, data->format, data->use_flags, false); if (!bo) return NULL; @@ -415,6 +449,10 @@ void *drv_bo_map(struct bo *bo, const struct rectangle *rect, uint32_t map_flags /* No CPU access for protected buffers. */ assert(!(bo->meta.use_flags & BO_USE_PROTECTED)); + if (bo->is_test_buffer) { + return MAP_FAILED; + } + memset(&mapping, 0, sizeof(mapping)); mapping.rect = *rect; mapping.refcount = 1; @@ -562,6 +600,10 @@ int drv_bo_get_plane_fd(struct bo *bo, size_t plane) int ret, fd; assert(plane < bo->meta.num_planes); + if (bo->is_test_buffer) { + return -EINVAL; + } + ret = drmPrimeHandleToFD(bo->drv->fd, bo->handles[plane].u32, DRM_CLOEXEC | DRM_RDWR, &fd); // Older DRM implementations blocked DRM_RDWR, but gave a read/write mapping anyways @@ -613,6 +655,10 @@ uint32_t drv_num_buffers_per_bo(struct bo *bo) uint32_t count = 0; size_t plane, p; + if (bo->is_test_buffer) { + return 0; + } + for (plane = 0; plane < bo->meta.num_planes; plane++) { for (p = 0; p < plane; p++) if (bo->handles[p].u32 == bo->handles[plane].u32) diff --git a/drv.h b/drv.h index 39fd5dd..937487b 100644 --- a/drv.h +++ b/drv.h @@ -12,6 +12,7 @@ extern "C" { #endif #include +#include #include #define DRV_MAX_PLANES 4 @@ -35,7 +36,8 @@ extern "C" { #define BO_USE_SW_WRITE_RARELY (1ull << 12) #define BO_USE_HW_VIDEO_DECODER (1ull << 13) #define BO_USE_HW_VIDEO_ENCODER (1ull << 14) -#define BO_USE_RENDERSCRIPT (1ull << 15) +#define BO_USE_TEST_ALLOC (1ull << 15) +#define BO_USE_RENDERSCRIPT (1ull << 16) /* Quirks for allocating a buffer. */ #define BO_QUIRK_NONE 0 @@ -124,7 +126,7 @@ const char *drv_get_name(struct driver *drv); 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 use_flags); + uint64_t use_flags, bool is_test_buffer); struct bo *drv_bo_create(struct driver *drv, uint32_t width, uint32_t height, uint32_t format, uint64_t use_flags); diff --git a/drv_priv.h b/drv_priv.h index 76fa443..31ab892 100644 --- a/drv_priv.h +++ b/drv_priv.h @@ -8,6 +8,7 @@ #define DRV_PRIV_H #include +#include #include #include #include @@ -31,6 +32,7 @@ struct bo_metadata { struct bo { struct driver *drv; struct bo_metadata meta; + bool is_test_buffer; union bo_handle handles[DRV_MAX_PLANES]; void *priv; }; @@ -65,6 +67,11 @@ struct backend { 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); + // Either both or neither _metadata functions must be implemented. + // If the functions are implemented, bo_create and bo_create_with_modifiers must not be. + int (*bo_compute_metadata)(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint64_t use_flags, const uint64_t *modifiers, uint32_t count); + int (*bo_create_from_metadata)(struct bo *bo); 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 vma *vma, size_t plane, uint32_t map_flags); diff --git a/gbm.h b/gbm.h index 4993b5c..2492728 100644 --- a/gbm.h +++ b/gbm.h @@ -271,6 +271,15 @@ enum gbm_bo_flags { * The buffer will be read by a video encode accelerator. */ GBM_BO_USE_HW_VIDEO_ENCODER = (1 << 14), + + /** + * If this flag is set, no backing memory will be allocated for the + * created buffer. The metadata of the buffer (e.g. size) can be + * queried, and the values will be equal to a buffer allocated with + * the same same arguments minus this flag. However, any methods + * which would otherwise access the underlying buffer will fail. + */ + GBM_TEST_ALLOC = (1 << 15), }; int diff --git a/i915.c b/i915.c index d0c9db1..05c8272 100644 --- a/i915.c +++ b/i915.c @@ -268,13 +268,26 @@ static int i915_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, u return 0; } -static int i915_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t height, - uint32_t format, uint64_t modifier) +static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint64_t use_flags, const uint64_t *modifiers, uint32_t count) { - int ret; - size_t plane; - struct drm_i915_gem_create gem_create; - struct drm_i915_gem_set_tiling gem_set_tiling; + static const uint64_t modifier_order[] = { + I915_FORMAT_MOD_Y_TILED_CCS, + I915_FORMAT_MOD_Y_TILED, + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, + }; + uint64_t modifier; + + if (modifiers) { + modifier = + drv_pick_modifier(modifiers, count, modifier_order, ARRAY_SIZE(modifier_order)); + } else { + struct combination *combo = drv_get_combination(bo->drv, format, use_flags); + if (!combo) + return -EINVAL; + modifier = combo->metadata.modifier; + } switch (modifier) { case DRM_FORMAT_MOD_LINEAR: @@ -346,6 +359,15 @@ static int i915_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t h } else { i915_bo_from_format(bo, width, height, format); } + return 0; +} + +static int i915_bo_create_from_metadata(struct bo *bo) +{ + int ret; + size_t plane; + struct drm_i915_gem_create gem_create; + struct drm_i915_gem_set_tiling gem_set_tiling; memset(&gem_create, 0, sizeof(gem_create)); gem_create.size = bo->meta.total_size; @@ -378,34 +400,6 @@ static int i915_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t h 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_CCS, - 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)); - - return i915_bo_create_for_modifier(bo, width, height, format, modifier); -} - static void i915_close(struct driver *drv) { free(drv->priv); @@ -561,8 +555,8 @@ 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_compute_metadata = i915_bo_compute_metadata, + .bo_create_from_metadata = i915_bo_create_from_metadata, .bo_destroy = drv_gem_bo_destroy, .bo_import = i915_bo_import, .bo_map = i915_bo_map, From 44588bb28284b034fa7f36dbf0cd2177dbac0be5 Mon Sep 17 00:00:00 2001 From: ChromeOS Developer Date: Mon, 2 Mar 2020 16:32:09 +0100 Subject: [PATCH 205/269] minigbm: dri: Support 2+ planes query for modifiers. If the driver does not implement the new function, or if modifier is INVALID this should return exactly the same as before. For LINEAR, DRI should return exactly the same as minigbm for all the YUV formats. BUG=b:149819940 TEST=Use with followup patch and login on a Zork device + play a YT video. Change-Id: I6ea3b5827876844e510794b85212be51e5dfd68f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2093211 Tested-by: Bas Nieuwenhuizen Reviewed-by: Gurchetan Singh Commit-Queue: Bas Nieuwenhuizen --- amdgpu.c | 1 + dri.c | 18 ++++++++++++++++++ dri.h | 1 + drv.h | 2 ++ drv_priv.h | 1 + gbm.c | 3 ++- helpers.c | 14 ++++++++++++++ 7 files changed, 39 insertions(+), 1 deletion(-) diff --git a/amdgpu.c b/amdgpu.c index 5f2a93b..8670087 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -315,6 +315,7 @@ const struct backend backend_amdgpu = { .bo_unmap = amdgpu_unmap_bo, .bo_invalidate = amdgpu_bo_invalidate, .resolve_format = amdgpu_resolve_format, + .num_planes_from_modifier = dri_num_planes_from_modifier, }; #endif diff --git a/dri.c b/dri.c index 950d616..8492385 100644 --- a/dri.c +++ b/dri.c @@ -329,4 +329,22 @@ int dri_bo_unmap(struct bo *bo, struct vma *vma) return 0; } +size_t dri_num_planes_from_modifier(struct driver *drv, uint32_t format, uint64_t modifier) +{ + struct dri_driver *dri = drv->priv; + if (!dri->image_extension->queryDmaBufFormatModifierAttribs) { + /* We do not do any modifier checks here. The create will fail + * later if the modifier is not supported. */ + return drv_num_planes_from_format(format); + } + + uint64_t planes; + GLboolean ret = dri->image_extension->queryDmaBufFormatModifierAttribs( + dri->device, format, modifier, __DRI_IMAGE_ATTRIB_NUM_PLANES, &planes); + if (!ret) + return 0; + + return planes; +} + #endif diff --git a/dri.h b/dri.h index 9c72b1e..d424dfc 100644 --- a/dri.h +++ b/dri.h @@ -34,5 +34,6 @@ int dri_bo_import(struct bo *bo, struct drv_import_fd_data *data); int dri_bo_destroy(struct bo *bo); void *dri_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags); int dri_bo_unmap(struct bo *bo, struct vma *vma); +size_t dri_num_planes_from_modifier(struct driver *drv, uint32_t format, uint64_t modifier); #endif diff --git a/drv.h b/drv.h index 937487b..6642a3d 100644 --- a/drv.h +++ b/drv.h @@ -175,6 +175,8 @@ uint32_t drv_resolve_format(struct driver *drv, uint32_t format, uint64_t use_fl size_t drv_num_planes_from_format(uint32_t format); +size_t drv_num_planes_from_modifier(struct driver *drv, uint32_t format, uint64_t modifier); + uint32_t drv_num_buffers_per_bo(struct bo *bo); #define drv_log(format, ...) \ diff --git a/drv_priv.h b/drv_priv.h index 31ab892..4eb1ee1 100644 --- a/drv_priv.h +++ b/drv_priv.h @@ -79,6 +79,7 @@ struct backend { int (*bo_invalidate)(struct bo *bo, struct mapping *mapping); int (*bo_flush)(struct bo *bo, struct mapping *mapping); uint32_t (*resolve_format)(struct driver *drv, uint32_t format, uint64_t use_flags); + size_t (*num_planes_from_modifier)(struct driver *drv, uint32_t format, uint64_t modifier); }; // clang-format off diff --git a/gbm.c b/gbm.c index 4b62bbf..705acff 100644 --- a/gbm.c +++ b/gbm.c @@ -216,7 +216,8 @@ PUBLIC struct gbm_bo *gbm_bo_import(struct gbm_device *gbm, uint32_t type, void drv_data.width = fd_modifier_data->width; drv_data.height = fd_modifier_data->height; drv_data.format = fd_modifier_data->format; - num_planes = drv_num_planes_from_format(drv_data.format); + num_planes = drv_num_planes_from_modifier(gbm->drv, drv_data.format, + fd_modifier_data->modifier); assert(num_planes); num_fds = fd_modifier_data->num_fds; diff --git a/helpers.c b/helpers.c index 833a2d8..22a6106 100644 --- a/helpers.c +++ b/helpers.c @@ -176,6 +176,20 @@ size_t drv_num_planes_from_format(uint32_t format) return layout ? layout->num_planes : 0; } +size_t drv_num_planes_from_modifier(struct driver *drv, uint32_t format, uint64_t modifier) +{ + size_t planes = drv_num_planes_from_format(format); + + /* Disallow unsupported formats. */ + if (!planes) + return 0; + + if (drv->backend->num_planes_from_modifier && modifier != DRM_FORMAT_MOD_INVALID) + return drv->backend->num_planes_from_modifier(drv, format, modifier); + + return planes; +} + uint32_t drv_height_from_format(uint32_t format, uint32_t height, size_t plane) { const struct planar_layout *layout = layout_from_format(format); From 9b367b3efed08fee7568dee8600dcf9335d547ef Mon Sep 17 00:00:00 2001 From: ChromeOS Developer Date: Mon, 2 Mar 2020 13:08:53 +0100 Subject: [PATCH 206/269] minigbm: dri,amdgpu: Modifier support. This adds modifier support to minigbm in the amdgpu driver. This includes (a) creation of images with modifiers (b) imports - Had to distinguish between legacy and non-legacy. (c) Support for planes > format planes BUG=b:149819940 TEST=Login on a Zork device + play a YT video. Change-Id: If58ada081aa254932e299536c48c18937266c2e8 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2093212 Tested-by: Bas Nieuwenhuizen Reviewed-by: Gurchetan Singh Commit-Queue: Bas Nieuwenhuizen --- amdgpu.c | 95 ++++++++++++++++--------- dri.c | 206 ++++++++++++++++++++++++++++++++++++++++--------------- dri.h | 2 + gbm.c | 3 + 4 files changed, 217 insertions(+), 89 deletions(-) diff --git a/amdgpu.c b/amdgpu.c index 8670087..bb9342e 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -142,14 +142,49 @@ static void amdgpu_close(struct driver *drv) drv->priv = NULL; } -static int amdgpu_create_bo(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, - uint64_t use_flags) +static int amdgpu_create_bo_linear(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + uint64_t use_flags) { int ret; uint32_t plane, stride; - struct combination *combo; union drm_amdgpu_gem_create gem_create; + stride = drv_stride_from_format(format, width, 0); + stride = ALIGN(stride, 256); + + drv_bo_from_format(bo, stride, height, format); + + memset(&gem_create, 0, sizeof(gem_create)); + gem_create.in.bo_size = bo->meta.total_size; + gem_create.in.alignment = 256; + gem_create.in.domain_flags = 0; + + if (use_flags & (BO_USE_LINEAR | BO_USE_SW_MASK)) + gem_create.in.domain_flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; + + gem_create.in.domains = AMDGPU_GEM_DOMAIN_GTT; + if (!(use_flags & (BO_USE_SW_READ_OFTEN | BO_USE_SCANOUT))) + 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)); + if (ret < 0) + return ret; + + for (plane = 0; plane < bo->meta.num_planes; plane++) + bo->handles[plane].u32 = gem_create.out.handle; + + bo->meta.format_modifiers[0] = DRM_FORMAT_MOD_LINEAR; + + return 0; +} + +static int amdgpu_create_bo(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; @@ -179,45 +214,38 @@ static int amdgpu_create_bo(struct bo *bo, uint32_t width, uint32_t height, uint return dri_bo_create(bo, width, height, format, use_flags); } - stride = drv_stride_from_format(format, width, 0); - stride = ALIGN(stride, 256); - - drv_bo_from_format(bo, stride, height, format); - - memset(&gem_create, 0, sizeof(gem_create)); - gem_create.in.bo_size = bo->meta.total_size; - gem_create.in.alignment = 256; - gem_create.in.domain_flags = 0; - - if (use_flags & (BO_USE_LINEAR | BO_USE_SW_MASK)) - gem_create.in.domain_flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; - - gem_create.in.domains = AMDGPU_GEM_DOMAIN_GTT; - if (!(use_flags & (BO_USE_SW_READ_OFTEN | BO_USE_SCANOUT))) - gem_create.in.domain_flags |= AMDGPU_GEM_CREATE_CPU_GTT_USWC; + return amdgpu_create_bo_linear(bo, width, height, format, use_flags); +} - /* Allocate the buffer with the preferred heap. */ - ret = drmCommandWriteRead(drv_get_fd(bo->drv), DRM_AMDGPU_GEM_CREATE, &gem_create, - sizeof(gem_create)); - if (ret < 0) - return ret; +static int amdgpu_create_bo_with_modifiers(struct bo *bo, uint32_t width, uint32_t height, + uint32_t format, const uint64_t *modifiers, + uint32_t count) +{ + bool only_use_linear = true; - for (plane = 0; plane < bo->meta.num_planes; plane++) - bo->handles[plane].u32 = gem_create.out.handle; + for (uint32_t i = 0; i < count; ++i) + if (modifiers[i] != DRM_FORMAT_MOD_LINEAR) + only_use_linear = false; - bo->meta.format_modifiers[0] = DRM_FORMAT_MOD_LINEAR; + if (only_use_linear) + return amdgpu_create_bo_linear(bo, width, height, format, BO_USE_SCANOUT); - return 0; + return dri_bo_create_with_modifiers(bo, width, height, format, modifiers, count); } static int amdgpu_import_bo(struct bo *bo, struct drv_import_fd_data *data) { - struct combination *combo; - combo = drv_get_combination(bo->drv, data->format, data->use_flags); - if (!combo) - return -EINVAL; + bool dri_tiling = data->format_modifiers[0] != DRM_FORMAT_MOD_LINEAR; + if (data->format_modifiers[0] == DRM_FORMAT_MOD_INVALID) { + struct combination *combo; + combo = drv_get_combination(bo->drv, data->format, data->use_flags); + if (!combo) + return -EINVAL; + + dri_tiling = combo->metadata.tiling == TILE_TYPE_DRI; + } - if (combo->metadata.tiling == TILE_TYPE_DRI) + if (dri_tiling) return dri_bo_import(bo, data); else return drv_prime_bo_import(bo, data); @@ -309,6 +337,7 @@ const struct backend backend_amdgpu = { .init = amdgpu_init, .close = amdgpu_close, .bo_create = amdgpu_create_bo, + .bo_create_with_modifiers = amdgpu_create_bo_with_modifiers, .bo_destroy = amdgpu_destroy_bo, .bo_import = amdgpu_import_bo, .bo_map = amdgpu_map_bo, diff --git a/dri.c b/dri.c index 8492385..6d7c9a0 100644 --- a/dri.c +++ b/dri.c @@ -64,6 +64,21 @@ static bool lookup_extension(const __DRIextension *const *extensions, const char return false; } +/* + * Close Gem Handle + */ +static void close_gem_handle(uint32_t handle, int fd) +{ + struct drm_gem_close gem_close; + int ret = 0; + + memset(&gem_close, 0, sizeof(gem_close)); + gem_close.handle = handle; + ret = drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &gem_close); + if (ret) + drv_log("DRM_IOCTL_GEM_CLOSE failed (handle=%x) error %d\n", handle, ret); +} + /* * The DRI GEM namespace may be different from the minigbm's driver GEM namespace. We have * to import into minigbm. @@ -71,35 +86,88 @@ static bool lookup_extension(const __DRIextension *const *extensions, const char static int import_into_minigbm(struct dri_driver *dri, struct bo *bo) { uint32_t handle; - int prime_fd, ret; + int ret, modifier_upper, modifier_lower, num_planes, i, j; + __DRIimage *plane_image = NULL; - if (!dri->image_extension->queryImage(bo->priv, __DRI_IMAGE_ATTRIB_FD, &prime_fd)) + if (dri->image_extension->queryImage(bo->priv, __DRI_IMAGE_ATTRIB_MODIFIER_UPPER, + &modifier_upper) && + dri->image_extension->queryImage(bo->priv, __DRI_IMAGE_ATTRIB_MODIFIER_LOWER, + &modifier_lower)) { + bo->meta.format_modifiers[0] = + ((uint64_t)modifier_upper << 32) | (uint32_t)modifier_lower; + } else { + bo->meta.format_modifiers[0] = DRM_FORMAT_MOD_INVALID; + } + + if (!dri->image_extension->queryImage(bo->priv, __DRI_IMAGE_ATTRIB_NUM_PLANES, + &num_planes)) { return -errno; + } - ret = drmPrimeFDToHandle(bo->drv->fd, prime_fd, &handle); - if (ret) { - drv_log("drmPrimeFDToHandle failed with %s\n", strerror(errno)); - return ret; + bo->meta.num_planes = num_planes; + + for (i = 0; i < num_planes; ++i) { + int prime_fd, stride, offset; + plane_image = dri->image_extension->fromPlanar(bo->priv, i, NULL); + __DRIimage *image = plane_image ? plane_image : bo->priv; + + if (i) + bo->meta.format_modifiers[i] = bo->meta.format_modifiers[0]; + + if (!dri->image_extension->queryImage(image, __DRI_IMAGE_ATTRIB_STRIDE, &stride) || + !dri->image_extension->queryImage(image, __DRI_IMAGE_ATTRIB_OFFSET, &offset)) { + ret = -errno; + goto cleanup; + } + + if (!dri->image_extension->queryImage(image, __DRI_IMAGE_ATTRIB_FD, &prime_fd)) { + ret = -errno; + goto cleanup; + } + + ret = drmPrimeFDToHandle(bo->drv->fd, prime_fd, &handle); + + close(prime_fd); + + if (ret) { + drv_log("drmPrimeFDToHandle failed with %s\n", strerror(errno)); + goto cleanup; + } + + bo->handles[i].u32 = handle; + + bo->meta.strides[i] = stride; + bo->meta.offsets[i] = offset; + + /* Not setting sizes[i] and total_size as these are not + * provided by DRI. The best way to "approximate" would be + * what drv_bo_import does, but I see nothing in the minigbm + * core that needs it. */ + + if (plane_image) + dri->image_extension->destroyImage(plane_image); } - bo->handles[0].u32 = handle; - close(prime_fd); return 0; -} - -/* - * Close Gem Handle - */ -static void close_gem_handle(uint32_t handle, int fd) -{ - struct drm_gem_close gem_close; - int ret = 0; - memset(&gem_close, 0, sizeof(gem_close)); - gem_close.handle = handle; - ret = drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &gem_close); - if (ret) - drv_log("DRM_IOCTL_GEM_CLOSE failed (handle=%x) error %d\n", handle, ret); +cleanup: + if (plane_image) + dri->image_extension->destroyImage(plane_image); + while (--i >= 0) { + for (j = 0; j <= i; ++j) + if (bo->handles[j].u32 == bo->handles[i].u32) + break; + + /* Multiple equivalent handles) */ + if (i == j) + break; + + /* This kind of goes horribly wrong when we already imported + * the same handles earlier, as we should really reference + * count handles. */ + close_gem_handle(bo->handles[i].u32, bo->drv->fd); + } + return ret; } /* @@ -190,11 +258,9 @@ int dri_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t forma uint64_t use_flags) { unsigned int dri_use; - int ret, dri_format, stride, offset; - int modifier_upper, modifier_lower; + int ret, dri_format; struct dri_driver *dri = bo->drv->priv; - assert(bo->meta.num_planes == 1); dri_format = drm_format_to_dri_format(format); /* Gallium drivers require shared to get the handle and stride. */ @@ -217,34 +283,38 @@ int dri_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t forma if (ret) goto free_image; - if (!dri->image_extension->queryImage(bo->priv, __DRI_IMAGE_ATTRIB_STRIDE, &stride)) { - ret = -errno; - goto close_handle; + return 0; + +free_image: + dri->image_extension->destroyImage(bo->priv); + return ret; +} + +int dri_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + const uint64_t *modifiers, uint32_t modifier_count) +{ + int ret, dri_format; + struct dri_driver *dri = bo->drv->priv; + + if (!dri->image_extension->createImageWithModifiers) { + return -ENOENT; } - if (!dri->image_extension->queryImage(bo->priv, __DRI_IMAGE_ATTRIB_OFFSET, &offset)) { + dri_format = drm_format_to_dri_format(format); + + bo->priv = dri->image_extension->createImageWithModifiers( + dri->device, width, height, dri_format, modifiers, modifier_count, NULL); + if (!bo->priv) { ret = -errno; - goto close_handle; + return ret; } - if (dri->image_extension->queryImage(bo->priv, __DRI_IMAGE_ATTRIB_MODIFIER_UPPER, - &modifier_upper) && - dri->image_extension->queryImage(bo->priv, __DRI_IMAGE_ATTRIB_MODIFIER_LOWER, - &modifier_lower)) { - bo->meta.format_modifiers[0] = - ((uint64_t)modifier_upper << 32) | (uint32_t)modifier_lower; - } else { - bo->meta.format_modifiers[0] = DRM_FORMAT_MOD_INVALID; - } + ret = import_into_minigbm(dri, bo); + if (ret) + goto free_image; - bo->meta.strides[0] = stride; - bo->meta.sizes[0] = stride * height; - bo->meta.offsets[0] = offset; - bo->meta.total_size = offset + bo->meta.sizes[0]; return 0; -close_handle: - close_gem_handle(bo->handles[0].u32, bo->drv->fd); free_image: dri->image_extension->destroyImage(bo->priv); return ret; @@ -255,17 +325,41 @@ int dri_bo_import(struct bo *bo, struct drv_import_fd_data *data) int ret; struct dri_driver *dri = bo->drv->priv; - assert(bo->meta.num_planes == 1); - - // clang-format off - bo->priv = dri->image_extension->createImageFromFds(dri->device, data->width, data->height, - data->format, data->fds, - bo->meta.num_planes, - (int *)data->strides, - (int *)data->offsets, NULL); - // clang-format on - if (!bo->priv) - return -errno; + if (data->format_modifiers[0] != DRM_FORMAT_MOD_INVALID) { + unsigned error; + + if (!dri->image_extension->createImageFromDmaBufs2) + return -ENOSYS; + + // clang-format off + bo->priv = dri->image_extension->createImageFromDmaBufs2(dri->device, data->width, data->height, + data->format, + data->format_modifiers[0], + data->fds, + bo->meta.num_planes, + (int *)data->strides, + (int *)data->offsets, + __DRI_YUV_COLOR_SPACE_UNDEFINED, + __DRI_YUV_RANGE_UNDEFINED, + __DRI_YUV_CHROMA_SITING_UNDEFINED, + __DRI_YUV_CHROMA_SITING_UNDEFINED, + &error, NULL); + // clang-format on + + /* Could translate the DRI error, but the Mesa GBM also returns ENOSYS. */ + if (!bo->priv) + return -ENOSYS; + } else { + // clang-format off + bo->priv = dri->image_extension->createImageFromFds(dri->device, data->width, data->height, + data->format, data->fds, + bo->meta.num_planes, + (int *)data->strides, + (int *)data->offsets, NULL); + // clang-format on + if (!bo->priv) + return -errno; + } ret = import_into_minigbm(dri, bo); if (ret) { diff --git a/dri.h b/dri.h index d424dfc..6218e82 100644 --- a/dri.h +++ b/dri.h @@ -30,6 +30,8 @@ int dri_init(struct driver *drv, const char *dri_so_path, const char *driver_suf void dri_close(struct driver *drv); int dri_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, uint64_t use_flags); +int dri_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, + const uint64_t *modifiers, uint32_t modifier_count); int dri_bo_import(struct bo *bo, struct drv_import_fd_data *data); int dri_bo_destroy(struct bo *bo); void *dri_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags); diff --git a/gbm.c b/gbm.c index 705acff..ab5b3f7 100644 --- a/gbm.c +++ b/gbm.c @@ -210,6 +210,9 @@ 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; + + for (i = 0; i < GBM_MAX_PLANES; ++i) + drv_data.format_modifiers[i] = DRM_FORMAT_MOD_INVALID; break; case GBM_BO_IMPORT_FD_MODIFIER: gbm_format = fd_modifier_data->format; From cfcea2f16549205a2a7e626cc38e995acd54cbaa Mon Sep 17 00:00:00 2001 From: Satyajit Sahu Date: Wed, 4 Mar 2020 15:53:30 +0530 Subject: [PATCH 207/269] arc-cros-gralloc: amdgpu: Use DRI_PATH to load radeonsi Use DRI_PATH cpp flag exported by ebuild to load the radeonsi library. This ensures 64/32 bit libraries are loaded as per arch. BUG=b:148405947, b:148045046, b:139690910, b:150425665, b:150422260, b:150742051, b:150742059 TEST=Launch play store, no black screen observed Cq-Depend: chromium:2098992 Change-Id: I12649457c82808aafb468d3d3123ff3eb028e7b6 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2087294 Reviewed-by: Drew Davenport Tested-by: Drew Davenport Commit-Queue: Drew Davenport --- amdgpu.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/amdgpu.c b/amdgpu.c index bb9342e..6e1b9b8 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -18,13 +18,9 @@ #include "helpers.h" #include "util.h" -#ifdef __ANDROID__ -#define DRI_PATH "/vendor/lib/dri/radeonsi_dri.so" -#else // clang-format off #define DRI_PATH STRINGIZE(DRI_DRIVER_DIR/radeonsi_dri.so) // clang-format on -#endif #define TILE_TYPE_LINEAR 0 /* DRI backend decides tiling in this case. */ From 51990ce15443fed0a9ca3136916fd80a5b1f2ea0 Mon Sep 17 00:00:00 2001 From: Jason Macnak Date: Fri, 13 Mar 2020 09:36:33 -0700 Subject: [PATCH 208/269] minigbm: virtio: check caps available before disabling formats Gfxstream backend does not yet populate supported formats cap info. Bug: b/146066070 Test: launch_cvd --gpu_mode=gfxstream Change-Id: I2eac7bcb1c75e22f554bafc7ae354c961b73583e --- virtio_gpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virtio_gpu.c b/virtio_gpu.c index b061e8b..e059497 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -89,7 +89,7 @@ static void virtio_gpu_add_combination(struct driver *drv, uint32_t drm_format, { struct virtio_gpu_priv *priv = (struct virtio_gpu_priv *)drv->priv; - if (priv->has_3d) { + if (priv->has_3d && priv->caps.max_version >= 1) { if ((use_flags & BO_USE_RENDERING) && !virtio_gpu_supports_format(&priv->caps.v1.render, drm_format)) { drv_log("Skipping unsupported render format: %d\n", drm_format); From 912c4c33a9e5d14c6509e27a82961b52dc557112 Mon Sep 17 00:00:00 2001 From: Bas Nieuwenhuizen Date: Fri, 13 Mar 2020 11:21:34 +0100 Subject: [PATCH 209/269] minigbm: dri: Set the plane sizes on bo creation. I cut a corner here on a previous patch and apparently it is used. Since DRI does not give us useful horizontal & vertical strides (especially considering things like auxiliary surfaces), do this calculation based on offsets & buffer strides. BUG=1061315 TEST=test_that graphics_Gbm on Zork. Change-Id: Idbca7ce42f4f8a692129a2f8ab5d9c3ccd796496 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2100795 Tested-by: Bas Nieuwenhuizen Reviewed-by: Gurchetan Singh Commit-Queue: Ilja H. Friedel --- dri.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/dri.c b/dri.c index 6d7c9a0..97dc567 100644 --- a/dri.c +++ b/dri.c @@ -87,6 +87,7 @@ static int import_into_minigbm(struct dri_driver *dri, struct bo *bo) { uint32_t handle; int ret, modifier_upper, modifier_lower, num_planes, i, j; + off_t dmabuf_sizes[DRV_MAX_PLANES]; __DRIimage *plane_image = NULL; if (dri->image_extension->queryImage(bo->priv, __DRI_IMAGE_ATTRIB_MODIFIER_UPPER, @@ -125,6 +126,15 @@ static int import_into_minigbm(struct dri_driver *dri, struct bo *bo) goto cleanup; } + dmabuf_sizes[i] = lseek(prime_fd, 0, SEEK_END); + if (dmabuf_sizes[i] == (off_t)-1) { + ret = -errno; + close(prime_fd); + goto cleanup; + } + + lseek(prime_fd, 0, SEEK_SET); + ret = drmPrimeFDToHandle(bo->drv->fd, prime_fd, &handle); close(prime_fd); @@ -139,15 +149,26 @@ static int import_into_minigbm(struct dri_driver *dri, struct bo *bo) bo->meta.strides[i] = stride; bo->meta.offsets[i] = offset; - /* Not setting sizes[i] and total_size as these are not - * provided by DRI. The best way to "approximate" would be - * what drv_bo_import does, but I see nothing in the minigbm - * core that needs it. */ - if (plane_image) dri->image_extension->destroyImage(plane_image); } + for (i = 0; i < num_planes; ++i) { + off_t next_plane = dmabuf_sizes[i]; + for (j = 0; j < num_planes; ++j) { + if (bo->meta.offsets[j] < next_plane && + bo->meta.offsets[j] > bo->meta.offsets[i] && + bo->handles[j].u32 == bo->handles[i].u32) + next_plane = bo->meta.offsets[j]; + } + + bo->meta.sizes[i] = next_plane - bo->meta.offsets[i]; + + /* This is kind of misleading if different planes use + different dmabufs. */ + bo->meta.total_size += bo->meta.sizes[i]; + } + return 0; cleanup: From ddb56b5eac4a659d8343acc59cfaef632f6b85b6 Mon Sep 17 00:00:00 2001 From: David Stevens Date: Fri, 13 Mar 2020 15:24:37 +0900 Subject: [PATCH 210/269] mediatek: get prime fd with drv_bo_get_plane_fd Instead of calling drmPrimeHandleToFD directly, call drv_bo_get_plane_fd so that the FD is exported with DRM_RDWR if possible. When a handle is exported, the drm framework caches the underlying dma_buf struct, even if all fd references are closed. This means that the flags from the first export operation end up being the primary flags for all subsequent export attempts. This change ensures that the O_RDWR flag is set on the first call, to prevent permission checks in PlatformSharedMemoryRegion from failing. BUG=b:151394062 TEST=youtube on arcvm on kukui Change-Id: I9de7bb67b45b3669704f3487889b10ed62493418 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2101054 Tested-by: David Stevens Reviewed-by: Gurchetan Singh Commit-Queue: David Stevens --- mediatek.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mediatek.c b/mediatek.c index 36d8115..6d03022 100644 --- a/mediatek.c +++ b/mediatek.c @@ -178,8 +178,8 @@ static void *mediatek_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint3 return MAP_FAILED; } - ret = drmPrimeHandleToFD(bo->drv->fd, gem_map.handle, DRM_CLOEXEC, &prime_fd); - if (ret) { + prime_fd = drv_bo_get_plane_fd(bo, 0); + if (prime_fd < 0) { drv_log("Failed to get a prime fd\n"); return MAP_FAILED; } From 827b8c257087a9bac366a4cfa5edf5edc8fc24bf Mon Sep 17 00:00:00 2001 From: Jason Macnak Date: Fri, 13 Mar 2020 09:55:13 -0700 Subject: [PATCH 211/269] minigbm: virtio: check caps version before disabling formats Gfxstream backend does not yet populate supported formats cap info. Bug: b/146066070 Test: launch_cvd --gpu_mode=gfxstream Change-Id: I28964c7701c5fd4cbe4ebc77f9fc553c64aeb924 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2103048 Reviewed-by: Gurchetan Singh Tested-by: Jason Macnak Commit-Queue: Jason Macnak --- virtio_gpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virtio_gpu.c b/virtio_gpu.c index b061e8b..e059497 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -89,7 +89,7 @@ static void virtio_gpu_add_combination(struct driver *drv, uint32_t drm_format, { struct virtio_gpu_priv *priv = (struct virtio_gpu_priv *)drv->priv; - if (priv->has_3d) { + if (priv->has_3d && priv->caps.max_version >= 1) { if ((use_flags & BO_USE_RENDERING) && !virtio_gpu_supports_format(&priv->caps.v1.render, drm_format)) { drv_log("Skipping unsupported render format: %d\n", drm_format); From 8d88474891dfb726c661849a7d299eb81ed91c7a Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Tue, 24 Mar 2020 13:48:54 -0700 Subject: [PATCH 212/269] minigbm: run presubmit.sh, modify OWNERs BUG=none TEST=none Change-Id: I07ae6fa603117f16dee39b1b7e9ca3162daa0c97 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2118462 Reviewed-by: Gurchetan Singh Commit-Queue: Gurchetan Singh Tested-by: Gurchetan Singh --- OWNERS | 1 + amdgpu.c | 4 ++-- cros_gralloc/gralloc0/tests/gralloctest.c | 2 +- drv.c | 2 +- i915.c | 3 ++- msm.c | 2 +- 6 files changed, 8 insertions(+), 6 deletions(-) diff --git a/OWNERS b/OWNERS index 3c1e063..f4aa651 100644 --- a/OWNERS +++ b/OWNERS @@ -7,3 +7,4 @@ dbehr@chromium.org dcastagna@chromium.org lepton@chromium.org tutankhamen@chromium.org +stevensd@chromium.org diff --git a/amdgpu.c b/amdgpu.c index 6e1b9b8..795d137 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -35,8 +35,8 @@ const static uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMA DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888 }; -const static uint32_t texture_source_formats[] = { DRM_FORMAT_GR88, DRM_FORMAT_R8, - 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, DRM_FORMAT_YVU420_ANDROID, DRM_FORMAT_YVU420 }; static int amdgpu_init(struct driver *drv) diff --git a/cros_gralloc/gralloc0/tests/gralloctest.c b/cros_gralloc/gralloc0/tests/gralloctest.c index 9160e62..8dfcd0b 100644 --- a/cros_gralloc/gralloc0/tests/gralloctest.c +++ b/cros_gralloc/gralloc0/tests/gralloctest.c @@ -95,7 +95,7 @@ static struct combinations combos[] = { // clang-format on struct grallocinfo { - buffer_handle_t handle; /* handle to the buffer */ + buffer_handle_t handle; /* handle to the buffer */ int w; /* width of buffer */ int h; /* height of buffer */ int format; /* format of the buffer */ diff --git a/drv.c b/drv.c index 52f26a5..fee3e57 100644 --- a/drv.c +++ b/drv.c @@ -111,7 +111,7 @@ static const struct backend *drv_get_backend(int fd) #ifdef DRV_VC4 &backend_vc4, #endif - &backend_vgem, &backend_virtio_gpu, + &backend_vgem, &backend_virtio_gpu, }; for (i = 0; i < ARRAY_SIZE(backend_list); i++) { diff --git a/i915.c b/i915.c index 05c8272..3ed785a 100644 --- a/i915.c +++ b/i915.c @@ -116,7 +116,8 @@ static int i915_add_combinations(struct driver *drv) metadata.priority = 3; metadata.modifier = I915_FORMAT_MOD_Y_TILED; - scanout_and_render = unset_flags(scanout_and_render, BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY); + scanout_and_render = + unset_flags(scanout_and_render, BO_USE_SW_READ_RARELY | BO_USE_SW_WRITE_RARELY); /* Support y-tiled NV12 and P010 for libva */ #ifdef I915_SCANOUT_Y_TILED drv_add_combination(drv, DRM_FORMAT_NV12, &metadata, diff --git a/msm.c b/msm.c index 5771f6e..fac1fd0 100644 --- a/msm.c +++ b/msm.c @@ -109,7 +109,7 @@ static void msm_calculate_layout(struct bo *bo) DRM_FORMAT_R8 of height one is used for JPEG camera output, so don't height align that. */ if (bo->meta.format == DRM_FORMAT_YVU420_ANDROID || - (bo->meta.format == DRM_FORMAT_R8 && height == 1)) { + (bo->meta.format == DRM_FORMAT_R8 && height == 1)) { alignh = height; } else { alignh = ALIGN(height, DEFAULT_ALIGNMENT); From c2ad3d7b4c24696749d23421932c5788535414e1 Mon Sep 17 00:00:00 2001 From: Daniel Nicoara Date: Tue, 24 Mar 2020 19:24:43 -0400 Subject: [PATCH 213/269] Add more scanout formats to meson driver BUG=None TEST=Allocated AB24 buffers with scanout bit to validate it works. Change-Id: I415026034e2dd1598d519f00ef4e075731d28074 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2118939 Reviewed-by: Gurchetan Singh Tested-by: Daniel Nicoara Commit-Queue: Daniel Nicoara --- meson.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/meson.c b/meson.c index 523bf71..f82c57a 100644 --- a/meson.c +++ b/meson.c @@ -10,12 +10,14 @@ #include "helpers.h" #include "util.h" -static const uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888 }; +static const uint32_t scanout_render_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888, + DRM_FORMAT_ABGR8888, DRM_FORMAT_XBGR8888, + DRM_FORMAT_BGR888, DRM_FORMAT_BGR565}; static int meson_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, scanout_render_formats, ARRAY_SIZE(scanout_render_formats), + &LINEAR_METADATA, BO_USE_RENDER_MASK | BO_USE_SCANOUT); return drv_modify_linear_combinations(drv); } From 612426912366e95c262fb848baeafc95a89e0087 Mon Sep 17 00:00:00 2001 From: Bob Badour Date: Wed, 25 Mar 2020 18:56:41 -0700 Subject: [PATCH 214/269] Remove redundant NOTICE copied from LICENSE. Identified using the below shell script: $ find -H . -name LICENSE -type f -print0 | xargs -0 dirname \ | while read dir; do \ if [ -f "${dir}/NOTICE" ] \ && diff "${dir}/LICENSE" "${dir}/NOTICE" >/dev/null; then \ echo "${dir}/NOTICE"; \ fi; \ done Now that http://r.android.com/r/1235427 and http://r.android.com/r/1238719 are merged, LICENSE files copied into NOTICE files are no longer needed. Bug: 67772237 Bug: 68860345 Test: manually built and diffed before and after system image notices Change-Id: I09ef28a103ff9f4b186f4a977cfb66ae63ca01e1 --- NOTICE | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 NOTICE diff --git a/NOTICE b/NOTICE deleted file mode 100644 index 3bd5095..0000000 --- a/NOTICE +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2017 The Chromium OS Authors. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. From 8f708a18e65b6992a385fbf90e21011f2d12cf17 Mon Sep 17 00:00:00 2001 From: Leona Chou Date: Thu, 19 Mar 2020 15:06:12 +0800 Subject: [PATCH 215/269] minigbm: add synaptics gbm driver Change the ozone platform from cast to drm add synaptics gbm driver for buffer management. BUG=b:152384632 TEST=use chromecast ui to verify drm TEST=use ozone_demo app to verify drm Change-Id: I9dff03e6b522ee84e34cbbcb28a40ca7857c4168 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2108458 Reviewed-by: Daniel Nicoara Reviewed-by: Gurchetan Singh Tested-by: Daniel Nicoara Commit-Queue: Daniel Nicoara --- Android.mk | 1 + drv.c | 6 ++++++ synaptics.c | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 synaptics.c diff --git a/Android.mk b/Android.mk index 564f416..3eab7ae 100644 --- a/Android.mk +++ b/Android.mk @@ -23,6 +23,7 @@ MINIGBM_SRC := \ nouveau.c \ radeon.c \ rockchip.c \ + synaptics.c \ tegra.c \ udl.c \ vc4.c \ diff --git a/drv.c b/drv.c index fee3e57..8009bac 100644 --- a/drv.c +++ b/drv.c @@ -54,6 +54,9 @@ extern const struct backend backend_radeon; #ifdef DRV_ROCKCHIP extern const struct backend backend_rockchip; #endif +#ifdef DRV_SYNAPTICS +extern const struct backend backend_synaptics; +#endif #ifdef DRV_TEGRA extern const struct backend backend_tegra; #endif @@ -104,6 +107,9 @@ static const struct backend *drv_get_backend(int fd) #ifdef DRV_ROCKCHIP &backend_rockchip, #endif +#ifdef DRV_SYNAPTICS + &backend_synaptics, +#endif #ifdef DRV_TEGRA &backend_tegra, #endif diff --git a/synaptics.c b/synaptics.c new file mode 100644 index 0000000..bcd8189 --- /dev/null +++ b/synaptics.c @@ -0,0 +1,33 @@ +/* + * Copyright 2020 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_SYNAPTICS + +#include "drv_priv.h" +#include "helpers.h" +#include "util.h" + +static const uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_ABGR8888, + DRM_FORMAT_XRGB8888 }; + +static int synaptics_init(struct driver *drv) +{ + drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + &LINEAR_METADATA, BO_USE_RENDER_MASK | BO_USE_SCANOUT); + + return drv_modify_linear_combinations(drv); +} + +const struct backend backend_synaptics = { + .name = "synaptics", + .init = synaptics_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 From 1914f989418995f24e5a8ce32a2f182db576896d Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Tue, 24 Mar 2020 13:53:51 -0700 Subject: [PATCH 216/269] minigbm: mediatek: fix SCANOUT flag All renderer target works are eligible for scanout, after looking at mtk_plane_init. BUG=b:151064316 TEST=Mirror mode works again on Kukui Change-Id: Ife8948c167c1d75622404af573f8cc92b3516416 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2118463 Reviewed-by: David Stevens Tested-by: Gurchetan Singh Commit-Queue: Gurchetan Singh --- mediatek.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediatek.c b/mediatek.c index 6d03022..cdfc9ab 100644 --- a/mediatek.c +++ b/mediatek.c @@ -49,7 +49,7 @@ static int mediatek_init(struct driver *drv) struct format_metadata metadata; drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), - &LINEAR_METADATA, BO_USE_RENDER_MASK); + &LINEAR_METADATA, BO_USE_RENDER_MASK | BO_USE_SCANOUT); drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), &LINEAR_METADATA, BO_USE_TEXTURE_MASK); From 69bc430166c8bc5ece56b987176ec3f11fb8d2f1 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Wed, 5 Feb 2020 18:18:52 -0800 Subject: [PATCH 217/269] drm/virtgpu: add header It's useless to try to keep up with a evolving UAPI, so just add it here temporarily. Change-Id: I18671f64cdf28af829fef1124f9f93cb4ffddcb4 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2003266 Reviewed-by: David Stevens Tested-by: Gurchetan Singh Commit-Queue: Gurchetan Singh --- presubmit.sh | 1 + virtgpu_drm.h | 182 ++++++++++++++++++++++++++++++++++++++++++++++++++ virtio_gpu.c | 2 +- 3 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 virtgpu_drm.h diff --git a/presubmit.sh b/presubmit.sh index 1cfc59c..5e8a32a 100755 --- a/presubmit.sh +++ b/presubmit.sh @@ -4,5 +4,6 @@ # found in the LICENSE file. find \ '(' -name '*.[ch]' -or -name '*.cc' ')' \ + -not -name 'virtgpu_drm.h' \ -not -name 'gbm.h' -not -name 'virgl_hw.h' \ -exec clang-format -style=file -i {} + diff --git a/virtgpu_drm.h b/virtgpu_drm.h new file mode 100644 index 0000000..f06a789 --- /dev/null +++ b/virtgpu_drm.h @@ -0,0 +1,182 @@ +/* + * Copyright 2013 Red Hat + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef VIRTGPU_DRM_H +#define VIRTGPU_DRM_H + +#include "drm.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +/* Please note that modifications to all structs defined here are + * subject to backwards-compatibility constraints. + * + * Do not use pointers, use __u64 instead for 32 bit / 64 bit user/kernel + * compatibility Keep fields aligned to their size + */ + +#define DRM_VIRTGPU_MAP 0x01 +#define DRM_VIRTGPU_EXECBUFFER 0x02 +#define DRM_VIRTGPU_GETPARAM 0x03 +#define DRM_VIRTGPU_RESOURCE_CREATE 0x04 +#define DRM_VIRTGPU_RESOURCE_INFO 0x05 +#define DRM_VIRTGPU_TRANSFER_FROM_HOST 0x06 +#define DRM_VIRTGPU_TRANSFER_TO_HOST 0x07 +#define DRM_VIRTGPU_WAIT 0x08 +#define DRM_VIRTGPU_GET_CAPS 0x09 + +#define VIRTGPU_EXECBUF_FENCE_FD_IN 0x01 +#define VIRTGPU_EXECBUF_FENCE_FD_OUT 0x02 +#define VIRTGPU_EXECBUF_FLAGS (\ + VIRTGPU_EXECBUF_FENCE_FD_IN |\ + VIRTGPU_EXECBUF_FENCE_FD_OUT |\ + 0) + +struct drm_virtgpu_map { + __u64 offset; /* use for mmap system call */ + __u32 handle; + __u32 pad; +}; + +struct drm_virtgpu_execbuffer { + __u32 flags; + __u32 size; + __u64 command; /* void* */ + __u64 bo_handles; + __u32 num_bo_handles; + __s32 fence_fd; /* in/out fence fd (see VIRTGPU_EXECBUF_FENCE_FD_IN/OUT) */ +}; + +#define VIRTGPU_PARAM_3D_FEATURES 1 /* do we have 3D features in the hw */ +#define VIRTGPU_PARAM_CAPSET_QUERY_FIX 2 /* do we have the capset fix */ + +struct drm_virtgpu_getparam { + __u64 param; + __u64 value; +}; + +/* NO_BO flags? NO resource flag? */ +/* resource flag for y_0_top */ +struct drm_virtgpu_resource_create { + __u32 target; + __u32 format; + __u32 bind; + __u32 width; + __u32 height; + __u32 depth; + __u32 array_size; + __u32 last_level; + __u32 nr_samples; + __u32 flags; + __u32 bo_handle; /* if this is set - recreate a new resource attached to this bo ? */ + __u32 res_handle; /* returned by kernel */ + __u32 size; /* validate transfer in the host */ + __u32 stride; /* validate transfer in the host */ +}; + +struct drm_virtgpu_resource_info { + __u32 bo_handle; + __u32 res_handle; + __u32 size; + __u32 stride; +}; + +struct drm_virtgpu_3d_box { + __u32 x; + __u32 y; + __u32 z; + __u32 w; + __u32 h; + __u32 d; +}; + +struct drm_virtgpu_3d_transfer_to_host { + __u32 bo_handle; + struct drm_virtgpu_3d_box box; + __u32 level; + __u32 offset; +}; + +struct drm_virtgpu_3d_transfer_from_host { + __u32 bo_handle; + struct drm_virtgpu_3d_box box; + __u32 level; + __u32 offset; +}; + +#define VIRTGPU_WAIT_NOWAIT 1 /* like it */ +struct drm_virtgpu_3d_wait { + __u32 handle; /* 0 is an invalid handle */ + __u32 flags; +}; + +struct drm_virtgpu_get_caps { + __u32 cap_set_id; + __u32 cap_set_ver; + __u64 addr; + __u32 size; + __u32 pad; +}; + +#define DRM_IOCTL_VIRTGPU_MAP \ + DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_MAP, struct drm_virtgpu_map) + +#define DRM_IOCTL_VIRTGPU_EXECBUFFER \ + DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_EXECBUFFER,\ + struct drm_virtgpu_execbuffer) + +#define DRM_IOCTL_VIRTGPU_GETPARAM \ + DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_GETPARAM,\ + struct drm_virtgpu_getparam) + +#define DRM_IOCTL_VIRTGPU_RESOURCE_CREATE \ + DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_RESOURCE_CREATE, \ + struct drm_virtgpu_resource_create) + +#define DRM_IOCTL_VIRTGPU_RESOURCE_INFO \ + DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_RESOURCE_INFO, \ + struct drm_virtgpu_resource_info) + +#define DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST \ + DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_TRANSFER_FROM_HOST, \ + struct drm_virtgpu_3d_transfer_from_host) + +#define DRM_IOCTL_VIRTGPU_TRANSFER_TO_HOST \ + DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_TRANSFER_TO_HOST, \ + struct drm_virtgpu_3d_transfer_to_host) + +#define DRM_IOCTL_VIRTGPU_WAIT \ + DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_WAIT, \ + struct drm_virtgpu_3d_wait) + +#define DRM_IOCTL_VIRTGPU_GET_CAPS \ + DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_GET_CAPS, \ + struct drm_virtgpu_get_caps) + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/virtio_gpu.c b/virtio_gpu.c index e059497..b5e5878 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -9,13 +9,13 @@ #include #include #include -#include #include #include "drv_priv.h" #include "helpers.h" #include "util.h" #include "virgl_hw.h" +#include "virtgpu_drm.h" #ifndef PAGE_SIZE #define PAGE_SIZE 0x1000 From bc4f023bfcc51cf9dcfcfec5bf4177b2e607dd68 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Thu, 27 Jun 2019 20:05:54 -0700 Subject: [PATCH 218/269] minigbm: add resource_info callback for virtio-gpu In ARC++, the wayland sevice and the video stack rely on GRALLOC_DRM_GET_STRIDE and (*lock_ycbcr) with zero flags to return the metadata associated with the buffer. In the past, we've simply returned the metadata that was calculated during allocation. Since the current virtio-gpu API relies on shadow buffers, there's actually two different sets of metadata: 1) The metadata of the shadow buffer --> useful for mapping 2) The metadata of the host resource --> useful for passing to Chrome For the wayland_service and video stack, we want to return (2). For the Android framework, we want to return (1). BUG=b:132939420 TEST=compile Change-Id: I1134d651396ba68e064eaf2e3cad3cb3225d7c5c Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1681383 Reviewed-by: David Stevens Commit-Queue: Gurchetan Singh Tested-by: Gurchetan Singh --- cros_gralloc/cros_gralloc_buffer.cc | 6 +++++ cros_gralloc/cros_gralloc_buffer.h | 1 + cros_gralloc/cros_gralloc_driver.cc | 20 +++++++++++++++++ cros_gralloc/cros_gralloc_driver.h | 2 ++ cros_gralloc/gralloc0/gralloc0.cc | 34 ++++++++++++++++++++++++----- drv.c | 14 ++++++++++++ drv.h | 3 +++ drv_priv.h | 2 ++ virtgpu_drm.h | 8 ++++++- virtio_gpu.c | 33 ++++++++++++++++++++++++++++ 10 files changed, 117 insertions(+), 6 deletions(-) diff --git a/cros_gralloc/cros_gralloc_buffer.cc b/cros_gralloc/cros_gralloc_buffer.cc index 01d4038..1066edc 100644 --- a/cros_gralloc/cros_gralloc_buffer.cc +++ b/cros_gralloc/cros_gralloc_buffer.cc @@ -108,3 +108,9 @@ int32_t cros_gralloc_buffer::unlock() return 0; } + +int32_t cros_gralloc_buffer::resource_info(uint32_t strides[DRV_MAX_PLANES], + uint32_t offsets[DRV_MAX_PLANES]) +{ + return drv_resource_info(bo_, strides, offsets); +} diff --git a/cros_gralloc/cros_gralloc_buffer.h b/cros_gralloc/cros_gralloc_buffer.h index e6aec91..ebd72ec 100644 --- a/cros_gralloc/cros_gralloc_buffer.h +++ b/cros_gralloc/cros_gralloc_buffer.h @@ -26,6 +26,7 @@ class cros_gralloc_buffer int32_t lock(const struct rectangle *rect, uint32_t map_flags, uint8_t *addr[DRV_MAX_PLANES]); int32_t unlock(); + int32_t resource_info(uint32_t strides[DRV_MAX_PLANES], uint32_t offsets[DRV_MAX_PLANES]); private: cros_gralloc_buffer(cros_gralloc_buffer const &); diff --git a/cros_gralloc/cros_gralloc_driver.cc b/cros_gralloc/cros_gralloc_driver.cc index 89897e0..62b43d4 100644 --- a/cros_gralloc/cros_gralloc_driver.cc +++ b/cros_gralloc/cros_gralloc_driver.cc @@ -333,6 +333,26 @@ int32_t cros_gralloc_driver::get_backing_store(buffer_handle_t handle, uint64_t return 0; } +int32_t cros_gralloc_driver::resource_info(buffer_handle_t handle, uint32_t strides[DRV_MAX_PLANES], + uint32_t offsets[DRV_MAX_PLANES]) +{ + std::lock_guard lock(mutex_); + + auto hnd = cros_gralloc_convert_handle(handle); + if (!hnd) { + drv_log("Invalid handle.\n"); + return -EINVAL; + } + + auto buffer = get_buffer(hnd); + if (!buffer) { + drv_log("Invalid Reference.\n"); + return -EINVAL; + } + + return buffer->resource_info(strides, offsets); +} + cros_gralloc_buffer *cros_gralloc_driver::get_buffer(cros_gralloc_handle_t hnd) { /* Assumes driver mutex is held. */ diff --git a/cros_gralloc/cros_gralloc_driver.h b/cros_gralloc/cros_gralloc_driver.h index 45782c9..f051277 100644 --- a/cros_gralloc/cros_gralloc_driver.h +++ b/cros_gralloc/cros_gralloc_driver.h @@ -31,6 +31,8 @@ class cros_gralloc_driver int32_t unlock(buffer_handle_t handle, int32_t *release_fence); int32_t get_backing_store(buffer_handle_t handle, uint64_t *out_store); + int32_t resource_info(buffer_handle_t handle, uint32_t strides[DRV_MAX_PLANES], + uint32_t offsets[DRV_MAX_PLANES]); private: cros_gralloc_driver(cros_gralloc_driver const &); diff --git a/cros_gralloc/gralloc0/gralloc0.cc b/cros_gralloc/gralloc0/gralloc0.cc index 0a302b4..6c49d3a 100644 --- a/cros_gralloc/gralloc0/gralloc0.cc +++ b/cros_gralloc/gralloc0/gralloc0.cc @@ -4,6 +4,7 @@ * found in the LICENSE file. */ +#include "../../util.h" #include "../cros_gralloc_driver.h" #include @@ -261,6 +262,8 @@ static int gralloc0_perform(struct gralloc_module_t const *module, int op, ...) uint64_t *out_store; buffer_handle_t handle; uint32_t *out_width, *out_height, *out_stride; + uint32_t strides[DRV_MAX_PLANES] = { 0, 0, 0, 0 }; + uint32_t offsets[DRV_MAX_PLANES] = { 0, 0, 0, 0 }; auto mod = (struct gralloc0_module const *)module; switch (op) { @@ -286,7 +289,17 @@ static int gralloc0_perform(struct gralloc_module_t const *module, int op, ...) switch (op) { case GRALLOC_DRM_GET_STRIDE: out_stride = va_arg(args, uint32_t *); - *out_stride = hnd->pixel_stride; + ret = mod->driver->resource_info(handle, strides, offsets); + if (ret) + break; + + if (strides[0] != hnd->strides[0]) { + uint32_t bytes_per_pixel = drv_bytes_per_pixel_from_format(hnd->format, 0); + *out_stride = DIV_ROUND_UP(strides[0], bytes_per_pixel); + } else { + *out_stride = hnd->pixel_stride; + } + break; case GRALLOC_DRM_GET_FORMAT: out_format = va_arg(args, int32_t *); @@ -364,6 +377,8 @@ static int gralloc0_lock_async_ycbcr(struct gralloc_module_t const *module, buff { int32_t ret; uint32_t map_flags; + uint32_t strides[DRV_MAX_PLANES] = { 0, 0, 0, 0 }; + uint32_t offsets[DRV_MAX_PLANES] = { 0, 0, 0, 0 }; uint8_t *addr[DRV_MAX_PLANES] = { nullptr, nullptr, nullptr, nullptr }; auto mod = (struct gralloc0_module const *)module; struct rectangle rect = { .x = static_cast(l), @@ -393,13 +408,22 @@ static int gralloc0_lock_async_ycbcr(struct gralloc_module_t const *module, buff if (ret) return ret; + if (!map_flags) { + ret = mod->driver->resource_info(handle, strides, offsets); + if (ret) + return ret; + + for (uint32_t plane = 0; plane < DRV_MAX_PLANES; plane++) + addr[plane] = static_cast(nullptr) + offsets[plane]; + } + switch (hnd->format) { case DRM_FORMAT_NV12: ycbcr->y = addr[0]; ycbcr->cb = addr[1]; ycbcr->cr = addr[1] + 1; - ycbcr->ystride = hnd->strides[0]; - ycbcr->cstride = hnd->strides[1]; + ycbcr->ystride = (!map_flags) ? strides[0] : hnd->strides[0]; + ycbcr->cstride = (!map_flags) ? strides[1] : hnd->strides[1]; ycbcr->chroma_step = 2; break; case DRM_FORMAT_YVU420: @@ -407,8 +431,8 @@ static int gralloc0_lock_async_ycbcr(struct gralloc_module_t const *module, buff ycbcr->y = addr[0]; ycbcr->cb = addr[2]; ycbcr->cr = addr[1]; - ycbcr->ystride = hnd->strides[0]; - ycbcr->cstride = hnd->strides[1]; + ycbcr->ystride = (!map_flags) ? strides[0] : hnd->strides[0]; + ycbcr->cstride = (!map_flags) ? strides[1] : hnd->strides[1]; ycbcr->chroma_step = 1; break; default: diff --git a/drv.c b/drv.c index 8009bac..920cf4d 100644 --- a/drv.c +++ b/drv.c @@ -691,3 +691,17 @@ void drv_log_prefix(const char *prefix, const char *file, int line, const char * #endif va_end(args); } + +int drv_resource_info(struct bo *bo, uint32_t strides[DRV_MAX_PLANES], + uint32_t offsets[DRV_MAX_PLANES]) +{ + for (uint32_t plane = 0; plane < bo->meta.num_planes; plane++) { + strides[plane] = bo->meta.strides[plane]; + offsets[plane] = bo->meta.offsets[plane]; + } + + if (bo->drv->backend->resource_info) + return bo->drv->backend->resource_info(bo, strides, offsets); + + return 0; +} diff --git a/drv.h b/drv.h index 6642a3d..2b86aad 100644 --- a/drv.h +++ b/drv.h @@ -179,6 +179,9 @@ size_t drv_num_planes_from_modifier(struct driver *drv, uint32_t format, uint64_ uint32_t drv_num_buffers_per_bo(struct bo *bo); +int drv_resource_info(struct bo *bo, uint32_t strides[DRV_MAX_PLANES], + uint32_t offsets[DRV_MAX_PLANES]); + #define drv_log(format, ...) \ do { \ drv_log_prefix("minigbm", __FILE__, __LINE__, format, ##__VA_ARGS__); \ diff --git a/drv_priv.h b/drv_priv.h index 4eb1ee1..32c082d 100644 --- a/drv_priv.h +++ b/drv_priv.h @@ -80,6 +80,8 @@ struct backend { int (*bo_flush)(struct bo *bo, struct mapping *mapping); uint32_t (*resolve_format)(struct driver *drv, uint32_t format, uint64_t use_flags); size_t (*num_planes_from_modifier)(struct driver *drv, uint32_t format, uint64_t modifier); + int (*resource_info)(struct bo *bo, uint32_t strides[DRV_MAX_PLANES], + uint32_t offsets[DRV_MAX_PLANES]); }; // clang-format off diff --git a/virtgpu_drm.h b/virtgpu_drm.h index f06a789..a92d764 100644 --- a/virtgpu_drm.h +++ b/virtgpu_drm.h @@ -100,7 +100,13 @@ struct drm_virtgpu_resource_info { __u32 bo_handle; __u32 res_handle; __u32 size; - __u32 stride; + union { + __u32 stride; + __u32 strides[4]; /* strides[0] is accessible with stride. */ + }; + __u32 num_planes; + __u32 offsets[4]; + __u64 format_modifier; }; struct drm_virtgpu_3d_box { diff --git a/virtio_gpu.c b/virtio_gpu.c index b5e5878..eb6c97d 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -505,6 +505,38 @@ static uint32_t virtio_gpu_resolve_format(struct driver *drv, uint32_t format, u } } +static int virtio_gpu_resource_info(struct bo *bo, uint32_t strides[DRV_MAX_PLANES], + uint32_t offsets[DRV_MAX_PLANES]) +{ + int ret; + struct drm_virtgpu_resource_info res_info; + struct virtio_gpu_priv *priv = (struct virtio_gpu_priv *)bo->drv->priv; + + if (!priv->has_3d) + return 0; + + memset(&res_info, 0, sizeof(res_info)); + res_info.bo_handle = bo->handles[0].u32; + ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_RESOURCE_INFO, &res_info); + if (ret) { + drv_log("DRM_IOCTL_VIRTGPU_RESOURCE_INFO failed with %s\n", strerror(errno)); + return ret; + } + + for (uint32_t plane = 0; plane < bo->meta.num_planes; plane++) { + /* + * Currently, kernel v4.14 (Betty) doesn't have the extended resource info + * ioctl. + */ + if (res_info.strides[plane]) { + strides[plane] = res_info.strides[plane]; + offsets[plane] = res_info.offsets[plane]; + } + } + + return 0; +} + const struct backend backend_virtio_gpu = { .name = "virtio_gpu", .init = virtio_gpu_init, @@ -517,4 +549,5 @@ const struct backend backend_virtio_gpu = { .bo_invalidate = virtio_gpu_bo_invalidate, .bo_flush = virtio_gpu_bo_flush, .resolve_format = virtio_gpu_resolve_format, + .resource_info = virtio_gpu_resource_info, }; From d708f6108cdd644a64cac407e166a8d40faac494 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Thu, 12 Sep 2019 17:26:45 -0700 Subject: [PATCH 219/269] minigbm: virtgpu: refactor virtgpu features This way, we can call the GET_PARAM ioctl in a loop. BUG=chromium:924405 TEST=compile Change-Id: I74359b758a864d72bdec04b7741bbe9e2b466f1c Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2133073 Reviewed-by: David Stevens Reviewed-by: Lepton Wu Tested-by: Gurchetan Singh Commit-Queue: Lepton Wu --- virtio_gpu.c | 77 ++++++++++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 38 deletions(-) diff --git a/virtio_gpu.c b/virtio_gpu.c index eb6c97d..4912af0 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -25,6 +25,27 @@ #define MESA_LLVMPIPE_TILE_ORDER 6 #define MESA_LLVMPIPE_TILE_SIZE (1 << MESA_LLVMPIPE_TILE_ORDER) +struct feature { + uint64_t feature; + const char *name; + uint32_t enabled; +}; + +enum feature_id { + feat_3d, + feat_capset_fix, + feat_max, +}; + +#define FEATURE(x) \ + (struct feature) \ + { \ + x, #x, 0 \ + } + +static struct feature features[] = { FEATURE(VIRTGPU_PARAM_3D_FEATURES), + FEATURE(VIRTGPU_PARAM_CAPSET_QUERY_FIX) }; + static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888 }; @@ -37,7 +58,6 @@ static const uint32_t texture_source_formats[] = { DRM_FORMAT_NV12, DRM_FORMAT_R DRM_FORMAT_YVU420_ANDROID }; struct virtio_gpu_priv { - int has_3d; int caps_is_v2; union virgl_caps caps; }; @@ -89,7 +109,7 @@ static void virtio_gpu_add_combination(struct driver *drv, uint32_t drm_format, { struct virtio_gpu_priv *priv = (struct virtio_gpu_priv *)drv->priv; - if (priv->has_3d && priv->caps.max_version >= 1) { + if (features[feat_3d].enabled && priv->caps.max_version >= 1) { if ((use_flags & BO_USE_RENDERING) && !virtio_gpu_supports_format(&priv->caps.v1.render, drm_format)) { drv_log("Skipping unsupported render format: %d\n", drm_format); @@ -239,21 +259,11 @@ static int virtio_gpu_get_caps(struct driver *drv, union virgl_caps *caps, int * { int ret; struct drm_virtgpu_get_caps cap_args; - struct drm_virtgpu_getparam param_args; - uint32_t can_query_v2 = 0; - - memset(¶m_args, 0, sizeof(param_args)); - param_args.param = VIRTGPU_PARAM_CAPSET_QUERY_FIX; - param_args.value = (uint64_t)(uintptr_t)&can_query_v2; - ret = drmIoctl(drv->fd, DRM_IOCTL_VIRTGPU_GETPARAM, ¶m_args); - if (ret) { - drv_log("DRM_IOCTL_VIRTGPU_GETPARAM failed with %s\n", strerror(errno)); - } *caps_is_v2 = 0; memset(&cap_args, 0, sizeof(cap_args)); cap_args.addr = (unsigned long long)caps; - if (can_query_v2) { + if (features[feat_capset_fix].enabled) { *caps_is_v2 = 1; cap_args.cap_set_id = 2; cap_args.size = sizeof(union virgl_caps); @@ -284,22 +294,20 @@ static int virtio_gpu_init(struct driver *drv) { int ret; struct virtio_gpu_priv *priv; - struct drm_virtgpu_getparam args; priv = calloc(1, sizeof(*priv)); drv->priv = priv; - - memset(&args, 0, sizeof(args)); - args.param = VIRTGPU_PARAM_3D_FEATURES; - args.value = (uint64_t)(uintptr_t)&priv->has_3d; - ret = drmIoctl(drv->fd, DRM_IOCTL_VIRTGPU_GETPARAM, &args); - if (ret) { - drv_log("virtio 3D acceleration is not available\n"); - /* Be paranoid */ - priv->has_3d = 0; + for (uint32_t i = 0; i < ARRAY_SIZE(features); i++) { + struct drm_virtgpu_getparam params = { 0 }; + + params.param = features[i].feature; + params.value = (uint64_t)(uintptr_t)&features[i].enabled; + ret = drmIoctl(drv->fd, DRM_IOCTL_VIRTGPU_GETPARAM, ¶ms); + if (ret) + drv_log("DRM_IOCTL_VIRTGPU_GET_PARAM failed with %s\n", strerror(errno)); } - if (priv->has_3d) { + if (features[feat_3d].enabled) { virtio_gpu_get_caps(drv, &priv->caps, &priv->caps_is_v2); /* This doesn't mean host can scanout everything, it just means host @@ -351,8 +359,7 @@ static void virtio_gpu_close(struct driver *drv) static int virtio_gpu_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, uint64_t use_flags) { - struct virtio_gpu_priv *priv = (struct virtio_gpu_priv *)bo->drv->priv; - if (priv->has_3d) + if (features[feat_3d].enabled) return virtio_virgl_bo_create(bo, width, height, format, use_flags); else return virtio_dumb_bo_create(bo, width, height, format, use_flags); @@ -360,8 +367,7 @@ static int virtio_gpu_bo_create(struct bo *bo, uint32_t width, uint32_t height, static int virtio_gpu_bo_destroy(struct bo *bo) { - struct virtio_gpu_priv *priv = (struct virtio_gpu_priv *)bo->drv->priv; - if (priv->has_3d) + if (features[feat_3d].enabled) return drv_gem_bo_destroy(bo); else return drv_dumb_bo_destroy(bo); @@ -369,8 +375,7 @@ static int virtio_gpu_bo_destroy(struct bo *bo) static void *virtio_gpu_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags) { - struct virtio_gpu_priv *priv = (struct virtio_gpu_priv *)bo->drv->priv; - if (priv->has_3d) + if (features[feat_3d].enabled) return virtio_virgl_bo_map(bo, vma, plane, map_flags); else return drv_dumb_bo_map(bo, vma, plane, map_flags); @@ -380,10 +385,9 @@ static int virtio_gpu_bo_invalidate(struct bo *bo, struct mapping *mapping) { int ret; struct drm_virtgpu_3d_transfer_from_host xfer; - struct virtio_gpu_priv *priv = (struct virtio_gpu_priv *)bo->drv->priv; struct drm_virtgpu_3d_wait waitcmd; - if (!priv->has_3d) + if (!features[feat_3d].enabled) return 0; // Invalidate is only necessary if the host writes to the buffer. @@ -434,10 +438,9 @@ static int virtio_gpu_bo_flush(struct bo *bo, struct mapping *mapping) { int ret; struct drm_virtgpu_3d_transfer_to_host xfer; - struct virtio_gpu_priv *priv = (struct virtio_gpu_priv *)bo->drv->priv; struct drm_virtgpu_3d_wait waitcmd; - if (!priv->has_3d) + if (!features[feat_3d].enabled) return 0; if (!(mapping->vma->map_flags & BO_MAP_WRITE)) @@ -482,7 +485,6 @@ static int virtio_gpu_bo_flush(struct bo *bo, struct mapping *mapping) static uint32_t virtio_gpu_resolve_format(struct driver *drv, uint32_t format, uint64_t use_flags) { - struct virtio_gpu_priv *priv = (struct virtio_gpu_priv *)drv->priv; switch (format) { case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED: @@ -496,7 +498,7 @@ static uint32_t virtio_gpu_resolve_format(struct driver *drv, uint32_t format, u * All of our host drivers prefer NV12 as their flexible media format. * If that changes, this will need to be modified. */ - if (priv->has_3d) + if (features[feat_3d].enabled) return DRM_FORMAT_NV12; else return DRM_FORMAT_YVU420; @@ -510,9 +512,8 @@ static int virtio_gpu_resource_info(struct bo *bo, uint32_t strides[DRV_MAX_PLAN { int ret; struct drm_virtgpu_resource_info res_info; - struct virtio_gpu_priv *priv = (struct virtio_gpu_priv *)bo->drv->priv; - if (!priv->has_3d) + if (!features[feat_3d].enabled) return 0; memset(&res_info, 0, sizeof(res_info)); From 4eebcea0cc53e385f715730e883963e86761a2f9 Mon Sep 17 00:00:00 2001 From: Shirish S Date: Tue, 31 Mar 2020 16:05:33 +0530 Subject: [PATCH 220/269] amdgpu: make AMDGPU_GEM_CREATE_CPU_GTT_USWC flag default amdgpu kernel driver requires USWC flag for allowing bo allocation in GTT domain, hence enable it by default. BUG=b:152378755 TEST=On Dali play 4k YouTube video Signed-off-by: Shirish S Change-Id: Ic509701f683d184d3fb85b7616dc9a7ed467cfe3 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2128147 Tested-by: Bas Nieuwenhuizen Reviewed-by: Bas Nieuwenhuizen Reviewed-by: Drew Davenport --- amdgpu.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/amdgpu.c b/amdgpu.c index 795d137..dd30524 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -159,8 +159,7 @@ static int amdgpu_create_bo_linear(struct bo *bo, uint32_t width, uint32_t heigh gem_create.in.domain_flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; gem_create.in.domains = AMDGPU_GEM_DOMAIN_GTT; - if (!(use_flags & (BO_USE_SW_READ_OFTEN | BO_USE_SCANOUT))) - gem_create.in.domain_flags |= AMDGPU_GEM_CREATE_CPU_GTT_USWC; + 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, From 5481e3c91e45bbe0049e6f1ead70c487b9366112 Mon Sep 17 00:00:00 2001 From: Jao-ke Chin-Lee Date: Fri, 10 Apr 2020 00:12:12 +0000 Subject: [PATCH 221/269] Revert "amdgpu: make AMDGPU_GEM_CREATE_CPU_GTT_USWC flag default" This reverts commit 4eebcea0cc53e385f715730e883963e86761a2f9. Reason for revert: Broke tast.video.DecodeAccel.*.h264_resolution_switch on grunt Original change's description: > amdgpu: make AMDGPU_GEM_CREATE_CPU_GTT_USWC flag default > > amdgpu kernel driver requires USWC flag for allowing bo > allocation in GTT domain, hence enable it by default. > > BUG=b:152378755 > TEST=On Dali play 4k YouTube video > > Signed-off-by: Shirish S > Change-Id: Ic509701f683d184d3fb85b7616dc9a7ed467cfe3 > Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2128147 > Tested-by: Bas Nieuwenhuizen > Reviewed-by: Bas Nieuwenhuizen > Reviewed-by: Drew Davenport Bug: b:152378755 Change-Id: If382833a741faa5462df841cc801e60fd9fca77a Exempt-From-Owner-Approval: revert. Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2145078 Tested-by: Ilja H. Friedel Reviewed-by: Jao-ke Chin-Lee --- amdgpu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/amdgpu.c b/amdgpu.c index dd30524..795d137 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -159,7 +159,8 @@ static int amdgpu_create_bo_linear(struct bo *bo, uint32_t width, uint32_t heigh gem_create.in.domain_flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; gem_create.in.domains = AMDGPU_GEM_DOMAIN_GTT; - gem_create.in.domain_flags |= AMDGPU_GEM_CREATE_CPU_GTT_USWC; + if (!(use_flags & (BO_USE_SW_READ_OFTEN | BO_USE_SCANOUT))) + 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, From 2b1ee8584432d60c109a29127f1c295f3b60f808 Mon Sep 17 00:00:00 2001 From: Mark Yacoub Date: Fri, 17 Apr 2020 16:27:48 -0400 Subject: [PATCH 222/269] Remove i915_FORMAT_MOD_Y_TILED_CCS from modifier_order Revert adding i915_FORMAT_MOD_Y_TILED_CCS to the modifiers options. Reason for revert: Devices with internal 4K displays aren't able to drive external 4K monitors as well. (This is a partial revert of crrev.com/c/2044490) BUG=chromium:979736,b:153731006 Change-Id: I40a0c686ee348f94e25b399b9ab91d4d6d377bc5 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2154983 Tested-by: Ilja H. Friedel Tested-by: Mark Yacoub Reviewed-by: Ilja H. Friedel Reviewed-by: Mark Yacoub Reviewed-by: Gurchetan Singh Auto-Submit: Mark Yacoub Commit-Queue: Ilja H. Friedel Commit-Queue: Matthew Blecker --- i915.c | 1 - 1 file changed, 1 deletion(-) diff --git a/i915.c b/i915.c index 3ed785a..92fd5b1 100644 --- a/i915.c +++ b/i915.c @@ -273,7 +273,6 @@ static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t heig uint64_t use_flags, const uint64_t *modifiers, uint32_t count) { static const uint64_t modifier_order[] = { - I915_FORMAT_MOD_Y_TILED_CCS, I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED, DRM_FORMAT_MOD_LINEAR, From b2504205e07166ef33e35b725f0db9a841872439 Mon Sep 17 00:00:00 2001 From: "Ilja H. Friedel" Date: Fri, 17 Apr 2020 15:50:41 -0700 Subject: [PATCH 223/269] Sort OWNERS and add ihf. BUG=None. TEST=None. Change-Id: Id3efc609c23f71b1170ff6c50ef018693425f044 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2154052 Tested-by: Ilja H. Friedel Reviewed-by: Gurchetan Singh Commit-Queue: Ilja H. Friedel --- OWNERS | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/OWNERS b/OWNERS index f4aa651..d9d5bf3 100644 --- a/OWNERS +++ b/OWNERS @@ -1,10 +1,11 @@ -marcheu@chromium.org -gurchetansingh@chromium.org -hoegsberg@chromium.org -tfiga@chromium.org -ddavenport@chromium.org dbehr@chromium.org dcastagna@chromium.org +ddavenport@chromium.org +gurchetansingh@chromium.org +hoegsberg@chromium.org +ihf@chromium.org lepton@chromium.org -tutankhamen@chromium.org +marcheu@chromium.org stevensd@chromium.org +tfiga@chromium.org +tutankhamen@chromium.org From d2c28439190dbf1ab678a4dae5aa23dada7808bd Mon Sep 17 00:00:00 2001 From: Bas Nieuwenhuizen Date: Mon, 6 Apr 2020 18:50:24 +0200 Subject: [PATCH 224/269] amdgpu: Set USWC for SCANOUT images. This is necessary for scanout from GTT. Without it, the kernel will migrate it to the carveout. For large resolutions this would not be feasible due to small carveout sizes and hence it is important that we alloc scanout from GTT. The original patch was on top of 4eebcea "amdgpu: make AMDGPU_GEM_CREATE_CPU_GTT_USWC flag default" which set USWC unconditionally, but has since been reverted. The main failure reason is being addressed in mesa-amd. This patch also still disables USWC if we can and the image will be read often on the CPU, to avoid staging textures during memory mapping. BUG=b:153247881 TEST=Run CtsCameraTestCases on Grunt. 4k YouTube video p/b Change-Id: If6393e60cea5d2a98a052d7c46604e0012de0618 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2134451 Tested-by: Bas Nieuwenhuizen Reviewed-by: Gurchetan Singh Commit-Queue: Bas Nieuwenhuizen --- amdgpu.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/amdgpu.c b/amdgpu.c index 795d137..d70bb8f 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -159,7 +159,11 @@ static int amdgpu_create_bo_linear(struct bo *bo, uint32_t width, uint32_t heigh gem_create.in.domain_flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; gem_create.in.domains = AMDGPU_GEM_DOMAIN_GTT; - if (!(use_flags & (BO_USE_SW_READ_OFTEN | BO_USE_SCANOUT))) + + /* Scanout in GTT requires USWC, otherwise try to use cachable memory + * for buffers that are read often, because uncacheable reads can be + * very slow. USWC should be faster on the GPU though. */ + if ((use_flags & BO_USE_SCANOUT) || !(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. */ From 659719ade911f726280c42cdbad29a4e54cb9016 Mon Sep 17 00:00:00 2001 From: Min Zhao Date: Tue, 14 Apr 2020 15:51:04 -0700 Subject: [PATCH 225/269] minigbm: synaptics: add texture source format support BUG=b:152384632 TEST=Test by making DUO video call Change-Id: I2c7920652ab48699a66aedc11f56f44aea9d1c4d Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2162517 Tested-by: Daniel Nicoara Commit-Queue: Daniel Nicoara Reviewed-by: Daniel Nicoara Reviewed-by: Gurchetan Singh --- synaptics.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/synaptics.c b/synaptics.c index bcd8189..28cb518 100644 --- a/synaptics.c +++ b/synaptics.c @@ -12,11 +12,17 @@ static const uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_ABGR8888, DRM_FORMAT_XRGB8888 }; +static const uint32_t texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_NV12, + DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID }; + static int synaptics_init(struct driver *drv) { drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), &LINEAR_METADATA, BO_USE_RENDER_MASK | BO_USE_SCANOUT); + drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats), + &LINEAR_METADATA, BO_USE_TEXTURE_MASK | BO_USE_HW_VIDEO_ENCODER); + return drv_modify_linear_combinations(drv); } From 91d36976aa84abde87f0f56d235d57042ca3ea81 Mon Sep 17 00:00:00 2001 From: Bas Nieuwenhuizen Date: Mon, 27 Apr 2020 19:59:29 +0000 Subject: [PATCH 226/269] Revert "amdgpu: Set USWC for SCANOUT images." This reverts commit d2c28439190dbf1ab678a4dae5aa23dada7808bd. Reason for revert: b/55018529: broke android.hardware.camera2.cts.RecordingTest#testVideoPreviewSurfaceSharing and fixing it is non-trivial Original change's description: > amdgpu: Set USWC for SCANOUT images. > > This is necessary for scanout from GTT. Without it, the kernel will > migrate it to the carveout. For large resolutions this would not be > feasible due to small carveout sizes and hence it is important that > we alloc scanout from GTT. > > The original patch was on top of > 4eebcea "amdgpu: make AMDGPU_GEM_CREATE_CPU_GTT_USWC flag default" > which set USWC unconditionally, but has since been reverted. The > main failure reason is being addressed in mesa-amd. This patch also > still disables USWC if we can and the image will be read often on > the CPU, to avoid staging textures during memory mapping. > > BUG=b:153247881 > TEST=Run CtsCameraTestCases on Grunt. > 4k YouTube video p/b > > Change-Id: If6393e60cea5d2a98a052d7c46604e0012de0618 > Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2134451 > Tested-by: Bas Nieuwenhuizen > Reviewed-by: Gurchetan Singh > Commit-Queue: Bas Nieuwenhuizen Bug: b:153247881 Change-Id: I395798c637ab10a2cf2a2a65a3a418a18feb2310 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2167399 Reviewed-by: Gurchetan Singh Tested-by: Bas Nieuwenhuizen Commit-Queue: Bas Nieuwenhuizen --- amdgpu.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/amdgpu.c b/amdgpu.c index d70bb8f..795d137 100644 --- a/amdgpu.c +++ b/amdgpu.c @@ -159,11 +159,7 @@ static int amdgpu_create_bo_linear(struct bo *bo, uint32_t width, uint32_t heigh gem_create.in.domain_flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; gem_create.in.domains = AMDGPU_GEM_DOMAIN_GTT; - - /* Scanout in GTT requires USWC, otherwise try to use cachable memory - * for buffers that are read often, because uncacheable reads can be - * very slow. USWC should be faster on the GPU though. */ - if ((use_flags & BO_USE_SCANOUT) || !(use_flags & BO_USE_SW_READ_OFTEN)) + if (!(use_flags & (BO_USE_SW_READ_OFTEN | BO_USE_SCANOUT))) gem_create.in.domain_flags |= AMDGPU_GEM_CREATE_CPU_GTT_USWC; /* Allocate the buffer with the preferred heap. */ From 778e21ddb3d6eb5e25b79bb122aa0ad1dd20e257 Mon Sep 17 00:00:00 2001 From: Jason Macnak Date: Tue, 28 Apr 2020 11:21:16 -0700 Subject: [PATCH 227/269] Fix YV12 dumb buffer plane sizes Allocating a 1280x720 YUV420 (YV12) buffer results in calling the create dumb ioctl with 1280x1080 and results in a file with size 1384448 (1280 * 1080 = 1382400, ALIGN(1382400, 4096) = 1384448). The existing code calls drv_bo_from_format with the aligned height of 768 which results in oversized planes totaling a size of 1474560 bytes. This ultimately leads to segfaults when running past the end of the mapped file. Because the dumb buffer iotcl height is computed using the buffer's unaligned height (bo->meta.height), the call to drv_bo_from_format should use the unaligned height as well. BUG=b:146515640 TEST=cts android.media.cts.EncodeDecodeTest Change-Id: I40893cf92caa9d35a89d21a3512604f361822222 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2171157 Reviewed-by: Gurchetan Singh Tested-by: Jason Macnak Commit-Queue: Jason Macnak --- helpers.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/helpers.c b/helpers.c index 22a6106..fed4af9 100644 --- a/helpers.c +++ b/helpers.c @@ -313,14 +313,17 @@ int drv_dumb_bo_create_ex(struct bo *bo, uint32_t width, uint32_t height, uint32 aligned_height = height; switch (format) { case DRM_FORMAT_YVU420_ANDROID: + /* HAL_PIXEL_FORMAT_YV12 requires that the buffer's height not + * be aligned. Update 'height' so that drv_bo_from_format below + * uses the non-aligned height. */ + height = bo->meta.height; + /* Align width to 32 pixels, so chroma strides are 16 bytes as * Android requires. */ aligned_width = ALIGN(width, 32); - /* Adjust the height to include room for chroma planes. - * - * HAL_PIXEL_FORMAT_YV12 requires that the buffer's height not - * be aligned. */ - aligned_height = 3 * DIV_ROUND_UP(bo->meta.height, 2); + + /* Adjust the height to include room for chroma planes. */ + aligned_height = 3 * DIV_ROUND_UP(height, 2); break; case DRM_FORMAT_YVU420: case DRM_FORMAT_NV12: From b03fc148d7cf44ffa0ecd042223e663621dab904 Mon Sep 17 00:00:00 2001 From: Chih-Yu Huang Date: Thu, 7 May 2020 11:54:24 +0900 Subject: [PATCH 228/269] minigbm: virtio_gpu: add BO_USE_HW_VIDEO_DECODER usage to R8 format. This combination will be used by ARCVM for video decoder bitstream blobs. BUG=b:156442659 TEST=run e2e test with C2VDAComponent Change-Id: Iad978f659c0a8edf3279b303794c2b840446be31 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2189994 Reviewed-by: Keiichi Watanabe Reviewed-by: David Stevens Auto-Submit: Chih-Yu Huang Commit-Queue: Chih-Yu Huang Tested-by: Chih-Yu Huang --- virtio_gpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virtio_gpu.c b/virtio_gpu.c index 4912af0..4dbcc4f 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -345,7 +345,7 @@ static int virtio_gpu_init(struct driver *drv) BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER | BO_USE_HW_VIDEO_ENCODER); drv_modify_combination(drv, DRM_FORMAT_R8, &LINEAR_METADATA, - BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE); + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER); return drv_modify_linear_combinations(drv); } From a03926ece6273ee14b7ea7e662c790e7233453d5 Mon Sep 17 00:00:00 2001 From: Jason Macnak Date: Thu, 14 May 2020 10:57:17 -0700 Subject: [PATCH 229/269] minigbm: Fix cast to avoid null pointer arithmetic 'external/minigbm/cros_gralloc/gralloc0/gralloc0.cc:417:50: error: arithmetic on a null pointer treated as a cast from integer to pointer is a GNU extension' BUG=b:146515640 TEST=m gralloc.minigbm Change-Id: I2e86b676224657bdb656a45db4cfa49e84b61c2d Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2202518 Reviewed-by: Gurchetan Singh Auto-Submit: Jason Macnak Tested-by: Jason Macnak Commit-Queue: Jason Macnak --- cros_gralloc/gralloc0/gralloc0.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cros_gralloc/gralloc0/gralloc0.cc b/cros_gralloc/gralloc0/gralloc0.cc index 6c49d3a..9f24a5d 100644 --- a/cros_gralloc/gralloc0/gralloc0.cc +++ b/cros_gralloc/gralloc0/gralloc0.cc @@ -414,7 +414,8 @@ static int gralloc0_lock_async_ycbcr(struct gralloc_module_t const *module, buff return ret; for (uint32_t plane = 0; plane < DRV_MAX_PLANES; plane++) - addr[plane] = static_cast(nullptr) + offsets[plane]; + addr[plane] = + reinterpret_cast(static_cast(offsets[plane])); } switch (hnd->format) { From 1476c7ea85c1e0334e86ab49b0d7dea59f003e3c Mon Sep 17 00:00:00 2001 From: Marissa Wall Date: Fri, 24 Jan 2020 15:05:57 -0800 Subject: [PATCH 230/269] gralloc4: adds gralloc4 support Implements the Allocator 4.0 and Mapper 4.0 interfaces. Some notable features of the 4.0 interface: - buffer metadata getter/setters - buffer flushing - buffer debugging (buffer listing and buffer id) Exempt-From-Owner-Approval: OWNERS.android is not being parsed Bug: b/146515640 Test: m && launch_cvd Test: m && launch_cvd --gpu_mode=drm_virgl Change-Id: I27f020b4f661890bcc2817deb09ffb9af1c76f1b --- Android.bp | 98 +- cros_gralloc/cros_gralloc_buffer.cc | 59 +- cros_gralloc/cros_gralloc_buffer.h | 15 +- cros_gralloc/cros_gralloc_driver.cc | 188 ++- cros_gralloc/cros_gralloc_driver.h | 16 +- cros_gralloc/cros_gralloc_handle.h | 33 +- cros_gralloc/cros_gralloc_helpers.cc | 20 +- cros_gralloc/cros_gralloc_helpers.h | 2 +- cros_gralloc/cros_gralloc_types.h | 9 +- cros_gralloc/gralloc0/gralloc0.cc | 9 +- cros_gralloc/gralloc0/tests/gralloctest.c | 9 +- cros_gralloc/gralloc4/.clang-format | 19 + cros_gralloc/gralloc4/Android.bp | 82 ++ .../gralloc4/CrosGralloc4Allocator.cc | 122 ++ cros_gralloc/gralloc4/CrosGralloc4Allocator.h | 26 + .../gralloc4/CrosGralloc4AllocatorService.cc | 30 + cros_gralloc/gralloc4/CrosGralloc4Mapper.cc | 1004 +++++++++++++++++ cros_gralloc/gralloc4/CrosGralloc4Mapper.h | 80 ++ cros_gralloc/gralloc4/CrosGralloc4Utils.cc | 772 +++++++++++++ cros_gralloc/gralloc4/CrosGralloc4Utils.h | 41 + ....graphics.allocator@4.0-service.minigbm.rc | 24 + drv.c | 22 +- drv.h | 2 + helpers.c | 11 + virgl_hw.h | 2 +- virtio_gpu.c | 436 ++++++- 26 files changed, 2972 insertions(+), 159 deletions(-) create mode 100644 cros_gralloc/gralloc4/.clang-format create mode 100644 cros_gralloc/gralloc4/Android.bp create mode 100644 cros_gralloc/gralloc4/CrosGralloc4Allocator.cc create mode 100644 cros_gralloc/gralloc4/CrosGralloc4Allocator.h create mode 100644 cros_gralloc/gralloc4/CrosGralloc4AllocatorService.cc create mode 100644 cros_gralloc/gralloc4/CrosGralloc4Mapper.cc create mode 100644 cros_gralloc/gralloc4/CrosGralloc4Mapper.h create mode 100644 cros_gralloc/gralloc4/CrosGralloc4Utils.cc create mode 100644 cros_gralloc/gralloc4/CrosGralloc4Utils.h create mode 100644 cros_gralloc/gralloc4/android.hardware.graphics.allocator@4.0-service.minigbm.rc diff --git a/Android.bp b/Android.bp index 63a50f7..02e8e5d 100644 --- a/Android.bp +++ b/Android.bp @@ -2,17 +2,7 @@ // found in the LICENSE file. cc_defaults { - name: "gralloc.minigbm_intel_defaults", - cflags: ["-DDRV_I915"], -} - -cc_defaults { - name: "gralloc.minigbm_meson_defaults", - cflags: ["-DDRV_MESON"], -} - -cc_defaults { - name: "gralloc.minigbm_defaults", + name: "minigbm_defaults", srcs: [ "amdgpu.c", @@ -34,11 +24,6 @@ cc_defaults { "vc4.c", "vgem.c", "virtio_gpu.c", - - "cros_gralloc/cros_gralloc_buffer.cc", - "cros_gralloc/cros_gralloc_driver.cc", - "cros_gralloc/cros_gralloc_helpers.cc", - "cros_gralloc/gralloc0/gralloc0.cc", ], cflags: [ @@ -53,39 +38,79 @@ cc_defaults { ], cppflags: ["-std=c++14"], - // The preferred path for vendor HALs is /vendor/lib/hw vendor: true, - relative_install_path: "hw", header_libs: [ "libhardware_headers", "libnativebase_headers", + "libnativewindow_headers", + "libsystem_headers", + ], + + export_header_lib_headers: [ + "libhardware_headers", + "libnativebase_headers", + "libnativewindow_headers", "libsystem_headers", ], shared_libs: [ "libcutils", "libdrm", - "libnativewindow", "libsync", "liblog", ], static_libs: ["libarect"], + + export_static_lib_headers: ["libarect"], +} + +cc_defaults { + name: "minigbm_cros_gralloc_defaults", + + defaults: ["minigbm_defaults"], + + srcs: [ + "cros_gralloc/cros_gralloc_buffer.cc", + "cros_gralloc/cros_gralloc_helpers.cc", + "cros_gralloc/cros_gralloc_driver.cc", + ] +} + +cc_library_static { + name: "libminigbm", + defaults: ["minigbm_defaults"], + shared_libs: ["liblog"], + static_libs: ["libdrm"], + + srcs: [ + "gbm.c", + "gbm_helpers.c", + ], + + export_include_dirs: ["."], +} + +cc_library_static { + name: "libminigbm_cros_gralloc", + defaults: ["minigbm_cros_gralloc_defaults"], + shared_libs: ["liblog"], + static_libs: ["libdrm"], + + export_include_dirs: ["."], } cc_library_shared { name: "gralloc.minigbm", - defaults: ["gralloc.minigbm_defaults"], + defaults: ["minigbm_cros_gralloc_defaults"], + srcs: ["cros_gralloc/gralloc0/gralloc0.cc"], } cc_library_shared { name: "gralloc.minigbm_intel", - defaults: [ - "gralloc.minigbm_defaults", - "gralloc.minigbm_intel_defaults", - ], + defaults: ["minigbm_cros_gralloc_defaults"], enabled: false, arch: { x86: { @@ -95,26 +120,13 @@ cc_library_shared { enabled: true, }, }, + cflags: ["-DDRV_I915"], + srcs: ["cros_gralloc/gralloc0/gralloc0.cc"], } cc_library_shared { name: "gralloc.minigbm_meson", - defaults: [ - "gralloc.minigbm_defaults", - "gralloc.minigbm_meson_defaults", - ], -} - -cc_library_shared { - name: "libminigbm", - defaults: ["gralloc.minigbm_defaults"], - shared_libs: ["liblog"], - static_libs: ["libdrm"], - - srcs: [ - "gbm.c", - "gbm_helpers.c", - ], - - export_include_dirs: ["."], -} + defaults: ["minigbm_cros_gralloc_defaults"], + cflags: ["-DDRV_MESON"], + srcs: ["cros_gralloc/gralloc0/gralloc0.cc"], +} \ No newline at end of file diff --git a/cros_gralloc/cros_gralloc_buffer.cc b/cros_gralloc/cros_gralloc_buffer.cc index 1066edc..2982505 100644 --- a/cros_gralloc/cros_gralloc_buffer.cc +++ b/cros_gralloc/cros_gralloc_buffer.cc @@ -10,8 +10,11 @@ #include cros_gralloc_buffer::cros_gralloc_buffer(uint32_t id, struct bo *acquire_bo, - struct cros_gralloc_handle *acquire_handle) - : id_(id), bo_(acquire_bo), hnd_(acquire_handle), refcount_(1), lockcount_(0) + struct cros_gralloc_handle *acquire_handle, + int32_t reserved_region_fd, uint64_t reserved_region_size) + : id_(id), bo_(acquire_bo), hnd_(acquire_handle), refcount_(1), lockcount_(0), + reserved_region_fd_(reserved_region_fd), reserved_region_size_(reserved_region_size), + reserved_region_addr_(nullptr) { assert(bo_); num_planes_ = drv_bo_get_num_planes(bo_); @@ -26,6 +29,9 @@ cros_gralloc_buffer::~cros_gralloc_buffer() native_handle_close(&hnd_->base); delete hnd_; } + if (reserved_region_addr_) { + munmap(reserved_region_addr_, reserved_region_size_); + } } uint32_t cros_gralloc_buffer::get_id() const @@ -114,3 +120,52 @@ int32_t cros_gralloc_buffer::resource_info(uint32_t strides[DRV_MAX_PLANES], { return drv_resource_info(bo_, strides, offsets); } + +int32_t cros_gralloc_buffer::invalidate() +{ + if (lockcount_ <= 0) { + drv_log("Buffer was not locked.\n"); + return -EINVAL; + } + + if (lock_data_[0]) { + return drv_bo_invalidate(bo_, lock_data_[0]); + } + + return 0; +} + +int32_t cros_gralloc_buffer::flush() +{ + if (lockcount_ <= 0) { + drv_log("Buffer was not locked.\n"); + return -EINVAL; + } + + if (lock_data_[0]) { + return drv_bo_flush(bo_, lock_data_[0]); + } + + return 0; +} + +int32_t cros_gralloc_buffer::get_reserved_region(void **addr, uint64_t *size) +{ + if (reserved_region_fd_ <= 0) { + drv_log("Buffer does not have reserved region.\n"); + return -EINVAL; + } + + if (!reserved_region_addr_) { + reserved_region_addr_ = mmap(nullptr, reserved_region_size_, PROT_WRITE | PROT_READ, + MAP_SHARED, reserved_region_fd_, 0); + if (reserved_region_addr_ == MAP_FAILED) { + drv_log("Failed to mmap reserved region: %s.\n", strerror(errno)); + return -errno; + } + } + + *addr = reserved_region_addr_; + *size = reserved_region_size_; + return 0; +} diff --git a/cros_gralloc/cros_gralloc_buffer.h b/cros_gralloc/cros_gralloc_buffer.h index ebd72ec..8634882 100644 --- a/cros_gralloc/cros_gralloc_buffer.h +++ b/cros_gralloc/cros_gralloc_buffer.h @@ -14,7 +14,8 @@ class cros_gralloc_buffer { public: cros_gralloc_buffer(uint32_t id, struct bo *acquire_bo, - struct cros_gralloc_handle *acquire_handle); + struct cros_gralloc_handle *acquire_handle, int32_t reserved_region_fd, + uint64_t reserved_region_size); ~cros_gralloc_buffer(); uint32_t get_id() const; @@ -28,12 +29,19 @@ class cros_gralloc_buffer int32_t unlock(); int32_t resource_info(uint32_t strides[DRV_MAX_PLANES], uint32_t offsets[DRV_MAX_PLANES]); + int32_t invalidate(); + int32_t flush(); + + int32_t get_reserved_region(void **reserved_region_addr, uint64_t *reserved_region_size); + private: cros_gralloc_buffer(cros_gralloc_buffer const &); cros_gralloc_buffer operator=(cros_gralloc_buffer const &); uint32_t id_; struct bo *bo_; + + /* Note: this will be nullptr for imported/retained buffers. */ struct cros_gralloc_handle *hnd_; int32_t refcount_; @@ -41,6 +49,11 @@ class cros_gralloc_buffer uint32_t num_planes_; struct mapping *lock_data_[DRV_MAX_PLANES]; + + /* Optional additional shared memory region attached to some gralloc4 buffers. */ + int32_t reserved_region_fd_; + uint64_t reserved_region_size_; + void *reserved_region_addr_; }; #endif diff --git a/cros_gralloc/cros_gralloc_driver.cc b/cros_gralloc/cros_gralloc_driver.cc index 62b43d4..e324bce 100644 --- a/cros_gralloc/cros_gralloc_driver.cc +++ b/cros_gralloc/cros_gralloc_driver.cc @@ -5,12 +5,16 @@ */ #include "cros_gralloc_driver.h" -#include "../util.h" #include #include +#include #include +#include "../drv_priv.h" +#include "../helpers.h" +#include "../util.h" + cros_gralloc_driver::cros_gralloc_driver() : drv_(nullptr) { } @@ -90,15 +94,38 @@ bool cros_gralloc_driver::is_supported(const struct cros_gralloc_buffer_descript return (combo != nullptr); } +int32_t create_reserved_region(const std::string &buffer_name, uint64_t reserved_region_size) +{ + int32_t reserved_region_fd; + std::string reserved_region_name = buffer_name + " reserved region"; + + reserved_region_fd = memfd_create(reserved_region_name.c_str(), FD_CLOEXEC); + if (reserved_region_fd == -1) { + drv_log("Failed to create reserved region fd: %s.\n", strerror(errno)); + return -errno; + } + + if (ftruncate(reserved_region_fd, reserved_region_size)) { + drv_log("Failed to set reserved region size: %s.\n", strerror(errno)); + return -errno; + } + + return reserved_region_fd; +} + int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descriptor *descriptor, buffer_handle_t *out_handle) { uint32_t id; - uint64_t mod; size_t num_planes; + size_t num_fds; + size_t num_ints; + size_t num_bytes; uint32_t resolved_format; uint32_t bytes_per_pixel; uint64_t use_flags; + int32_t reserved_region_fd; + char *name; struct bo *bo; struct cros_gralloc_handle *hnd; @@ -140,41 +167,72 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto return -EINVAL; } - hnd = new cros_gralloc_handle(); num_planes = drv_bo_get_num_planes(bo); + num_fds = num_planes; + + if (descriptor->reserved_region_size > 0) { + reserved_region_fd = + create_reserved_region(descriptor->name, descriptor->reserved_region_size); + if (reserved_region_fd < 0) { + drv_bo_destroy(bo); + return reserved_region_fd; + } + num_fds += 1; + } else { + reserved_region_fd = -1; + } + num_bytes = sizeof(struct cros_gralloc_handle); + num_bytes += (descriptor->name.size() + 1); + /* + * Ensure that the total number of bytes is a multiple of sizeof(int) as + * native_handle_clone() copies data based on hnd->base.numInts. + */ + num_bytes = ALIGN(num_bytes, sizeof(int)); + num_ints = num_bytes - sizeof(native_handle_t) - num_fds; + /* + * Malloc is used as handles are ultimetly destroyed via free in + * native_handle_delete(). + */ + hnd = static_cast(malloc(num_bytes)); hnd->base.version = sizeof(hnd->base); - hnd->base.numFds = num_planes; - hnd->base.numInts = handle_data_size - num_planes; - + hnd->base.numFds = num_fds; + hnd->base.numInts = num_ints; + hnd->num_planes = num_planes; for (size_t plane = 0; plane < num_planes; plane++) { 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); - - mod = drv_bo_get_plane_format_modifier(bo, plane); - hnd->format_modifiers[2 * plane] = static_cast(mod >> 32); - hnd->format_modifiers[2 * plane + 1] = static_cast(mod); + hnd->sizes[plane] = drv_bo_get_plane_size(bo, plane); } - + hnd->fds[hnd->num_planes] = reserved_region_fd; + hnd->reserved_region_size = descriptor->reserved_region_size; + static std::atomic next_buffer_id{ 1 }; + hnd->id = next_buffer_id++; hnd->width = drv_bo_get_width(bo); hnd->height = drv_bo_get_height(bo); hnd->format = drv_bo_get_format(bo); - hnd->use_flags[0] = static_cast(descriptor->use_flags >> 32); - hnd->use_flags[1] = static_cast(descriptor->use_flags); + hnd->format_modifier = drv_bo_get_plane_format_modifier(bo, 0); + hnd->use_flags = descriptor->use_flags; bytes_per_pixel = drv_bytes_per_pixel_from_format(hnd->format, 0); hnd->pixel_stride = DIV_ROUND_UP(hnd->strides[0], bytes_per_pixel); hnd->magic = cros_gralloc_magic; hnd->droid_format = descriptor->droid_format; - hnd->usage = descriptor->producer_usage; + hnd->usage = descriptor->droid_usage; + hnd->total_size = descriptor->reserved_region_size + bo->meta.total_size; + hnd->name_offset = handle_data_size; + + name = (char *)(&hnd->base.data[hnd->name_offset]); + snprintf(name, descriptor->name.size() + 1, "%s", descriptor->name.c_str()); id = drv_bo_get_plane_handle(bo, 0).u32; - auto buffer = new cros_gralloc_buffer(id, bo, hnd); + auto buffer = new cros_gralloc_buffer(id, bo, hnd, hnd->fds[hnd->num_planes], + hnd->reserved_region_size); std::lock_guard lock(mutex_); buffers_.emplace(id, buffer); handles_.emplace(hnd, std::make_pair(buffer, 1)); - *out_handle = &hnd->base; + *out_handle = reinterpret_cast(hnd); return 0; } @@ -208,18 +266,16 @@ int32_t cros_gralloc_driver::retain(buffer_handle_t handle) struct bo *bo; struct drv_import_fd_data data; data.format = hnd->format; + data.width = hnd->width; data.height = hnd->height; - data.use_flags = static_cast(hnd->use_flags[0]) << 32; - data.use_flags |= hnd->use_flags[1]; + data.use_flags = hnd->use_flags; memcpy(data.fds, hnd->fds, sizeof(data.fds)); memcpy(data.strides, hnd->strides, sizeof(data.strides)); memcpy(data.offsets, hnd->offsets, sizeof(data.offsets)); for (uint32_t plane = 0; plane < DRV_MAX_PLANES; plane++) { - data.format_modifiers[plane] = - static_cast(hnd->format_modifiers[2 * plane]) << 32; - data.format_modifiers[plane] |= hnd->format_modifiers[2 * plane + 1]; + data.format_modifiers[plane] = hnd->format_modifier; } bo = drv_bo_import(drv_, &data); @@ -228,7 +284,8 @@ int32_t cros_gralloc_driver::retain(buffer_handle_t handle) id = drv_bo_get_plane_handle(bo, 0).u32; - buffer = new cros_gralloc_buffer(id, bo, nullptr); + buffer = new cros_gralloc_buffer(id, bo, nullptr, hnd->fds[hnd->num_planes], + hnd->reserved_region_size); buffers_.emplace(id, buffer); } @@ -264,10 +321,10 @@ int32_t cros_gralloc_driver::release(buffer_handle_t handle) } 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]) + bool close_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); + int32_t ret = cros_gralloc_sync_wait(acquire_fence, close_acquire_fence); if (ret) return ret; @@ -313,6 +370,51 @@ int32_t cros_gralloc_driver::unlock(buffer_handle_t handle, int32_t *release_fen return buffer->unlock(); } +int32_t cros_gralloc_driver::invalidate(buffer_handle_t handle) +{ + std::lock_guard lock(mutex_); + + auto hnd = cros_gralloc_convert_handle(handle); + if (!hnd) { + drv_log("Invalid handle.\n"); + return -EINVAL; + } + + auto buffer = get_buffer(hnd); + if (!buffer) { + drv_log("Invalid Reference.\n"); + return -EINVAL; + } + + return buffer->invalidate(); +} + +int32_t cros_gralloc_driver::flush(buffer_handle_t handle, int32_t *release_fence) +{ + std::lock_guard lock(mutex_); + + auto hnd = cros_gralloc_convert_handle(handle); + if (!hnd) { + drv_log("Invalid handle.\n"); + return -EINVAL; + } + + auto buffer = get_buffer(hnd); + if (!buffer) { + drv_log("Invalid Reference.\n"); + return -EINVAL; + } + + /* + * From the ANativeWindow::dequeueBuffer documentation: + * + * "A value of -1 indicates that the caller may access the buffer immediately without + * waiting on a fence." + */ + *release_fence = -1; + return buffer->flush(); +} + int32_t cros_gralloc_driver::get_backing_store(buffer_handle_t handle, uint64_t *out_store) { std::lock_guard lock(mutex_); @@ -353,6 +455,32 @@ int32_t cros_gralloc_driver::resource_info(buffer_handle_t handle, uint32_t stri return buffer->resource_info(strides, offsets); } +int32_t cros_gralloc_driver::get_reserved_region(buffer_handle_t handle, + void **reserved_region_addr, + uint64_t *reserved_region_size) +{ + std::lock_guard lock(mutex_); + + auto hnd = cros_gralloc_convert_handle(handle); + if (!hnd) { + drv_log("Invalid handle.\n"); + return -EINVAL; + } + + auto buffer = get_buffer(hnd); + if (!buffer) { + drv_log("Invalid Reference.\n"); + return -EINVAL; + } + + return buffer->get_reserved_region(reserved_region_addr, reserved_region_size); +} + +uint32_t cros_gralloc_driver::get_resolved_drm_format(uint32_t drm_format, uint64_t usage) +{ + return drv_resolve_format(drv_, drm_format, usage); +} + cros_gralloc_buffer *cros_gralloc_driver::get_buffer(cros_gralloc_handle_t hnd) { /* Assumes driver mutex is held. */ @@ -361,3 +489,13 @@ cros_gralloc_buffer *cros_gralloc_driver::get_buffer(cros_gralloc_handle_t hnd) return nullptr; } + +void cros_gralloc_driver::for_each_handle( + const std::function &function) +{ + std::lock_guard lock(mutex_); + + for (const auto &pair : handles_) { + function(pair.first); + } +} \ No newline at end of file diff --git a/cros_gralloc/cros_gralloc_driver.h b/cros_gralloc/cros_gralloc_driver.h index f051277..d444ecd 100644 --- a/cros_gralloc/cros_gralloc_driver.h +++ b/cros_gralloc/cros_gralloc_driver.h @@ -9,6 +9,7 @@ #include "cros_gralloc_buffer.h" +#include #include #include @@ -26,14 +27,25 @@ 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, const struct rectangle *rect, - uint32_t map_flags, uint8_t *addr[DRV_MAX_PLANES]); + int32_t lock(buffer_handle_t handle, int32_t acquire_fence, bool close_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 invalidate(buffer_handle_t handle); + int32_t flush(buffer_handle_t handle, int32_t *release_fence); + int32_t get_backing_store(buffer_handle_t handle, uint64_t *out_store); int32_t resource_info(buffer_handle_t handle, uint32_t strides[DRV_MAX_PLANES], uint32_t offsets[DRV_MAX_PLANES]); + int32_t get_reserved_region(buffer_handle_t handle, void **reserved_region_addr, + uint64_t *reserved_region_size); + + uint32_t get_resolved_drm_format(uint32_t drm_format, uint64_t usage); + + void for_each_handle(const std::function &function); + private: cros_gralloc_driver(cros_gralloc_driver const &); cros_gralloc_driver operator=(cros_gralloc_driver const &); diff --git a/cros_gralloc/cros_gralloc_handle.h b/cros_gralloc/cros_gralloc_handle.h index cd3edfe..d2e1607 100644 --- a/cros_gralloc/cros_gralloc_handle.h +++ b/cros_gralloc/cros_gralloc_handle.h @@ -11,27 +11,40 @@ #include #define DRV_MAX_PLANES 4 - -/* - * Only use 32-bit integers in the handle. This guarantees that the handle is - * densely packed (i.e, the compiler does not insert any padding). - */ +#define DRV_MAX_FDS (DRV_MAX_PLANES + 1) struct cros_gralloc_handle { native_handle_t base; - int32_t fds[DRV_MAX_PLANES]; + /* + * File descriptors must immediately follow the native_handle_t base and used file + * descriptors must be packed at the beginning of this array to work with + * native_handle_clone(). + * + * This field contains 'num_planes' plane file descriptors followed by an optional metadata + * reserved region file descriptor if 'reserved_region_size' is greater than zero. + */ + int32_t fds[DRV_MAX_FDS]; uint32_t strides[DRV_MAX_PLANES]; uint32_t offsets[DRV_MAX_PLANES]; - uint32_t format_modifiers[2 * DRV_MAX_PLANES]; + uint32_t sizes[DRV_MAX_PLANES]; + uint32_t id; uint32_t width; uint32_t height; - uint32_t format; /* DRM format */ - uint32_t use_flags[2]; /* Buffer creation flags */ + uint32_t format; /* DRM format */ + uint64_t format_modifier; + uint64_t use_flags; /* Buffer creation flags */ uint32_t magic; uint32_t pixel_stride; int32_t droid_format; int32_t usage; /* Android usage. */ -}; + uint32_t num_planes; + uint64_t reserved_region_size; + uint64_t total_size; /* Total allocation size */ + /* + * Name is a null terminated char array located at handle->base.data[handle->name_offset]. + */ + uint32_t name_offset; +} __attribute__((packed)); typedef const struct cros_gralloc_handle *cros_gralloc_handle_t; diff --git a/cros_gralloc/cros_gralloc_helpers.cc b/cros_gralloc/cros_gralloc_helpers.cc index 73e59cb..1e05150 100644 --- a/cros_gralloc/cros_gralloc_helpers.cc +++ b/cros_gralloc/cros_gralloc_helpers.cc @@ -20,6 +20,8 @@ uint32_t cros_gralloc_convert_format(int format) return DRM_FORMAT_ARGB8888; case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: return DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED; + case HAL_PIXEL_FORMAT_RAW16: + return DRM_FORMAT_R16; case HAL_PIXEL_FORMAT_RGB_565: return DRM_FORMAT_RGB565; case HAL_PIXEL_FORMAT_RGB_888: @@ -59,29 +61,31 @@ cros_gralloc_handle_t cros_gralloc_convert_handle(buffer_handle_t handle) return hnd; } -int32_t cros_gralloc_sync_wait(int32_t acquire_fence) +int32_t cros_gralloc_sync_wait(int32_t fence, bool close_fence) { - if (acquire_fence < 0) + if (fence < 0) return 0; /* * Wait initially for 1000 ms, and then wait indefinitely. The SYNC_IOC_WAIT * documentation states the caller waits indefinitely on the fence if timeout < 0. */ - int err = sync_wait(acquire_fence, 1000); + int err = sync_wait(fence, 1000); if (err < 0) { drv_log("Timed out on sync wait, err = %s\n", strerror(errno)); - err = sync_wait(acquire_fence, -1); + err = sync_wait(fence, -1); if (err < 0) { drv_log("sync wait error = %s\n", strerror(errno)); return -errno; } } - err = close(acquire_fence); - if (err) { - drv_log("Unable to close fence fd, err = %s\n", strerror(errno)); - return -errno; + if (close_fence) { + err = close(fence); + if (err) { + drv_log("Unable to close fence fd, err = %s\n", strerror(errno)); + return -errno; + } } return 0; diff --git a/cros_gralloc/cros_gralloc_helpers.h b/cros_gralloc/cros_gralloc_helpers.h index a55eebc..36f86ef 100644 --- a/cros_gralloc/cros_gralloc_helpers.h +++ b/cros_gralloc/cros_gralloc_helpers.h @@ -22,6 +22,6 @@ uint32_t cros_gralloc_convert_format(int32_t format); cros_gralloc_handle_t cros_gralloc_convert_handle(buffer_handle_t handle); -int32_t cros_gralloc_sync_wait(int32_t acquire_fence); +int32_t cros_gralloc_sync_wait(int32_t fence, bool close_fence); #endif diff --git a/cros_gralloc/cros_gralloc_types.h b/cros_gralloc/cros_gralloc_types.h index 1fa81de..22f58e2 100644 --- a/cros_gralloc/cros_gralloc_types.h +++ b/cros_gralloc/cros_gralloc_types.h @@ -7,14 +7,17 @@ #ifndef CROS_GRALLOC_TYPES_H #define CROS_GRALLOC_TYPES_H +#include + struct cros_gralloc_buffer_descriptor { uint32_t width; uint32_t height; - uint32_t consumer_usage; - uint32_t producer_usage; - uint32_t droid_format; + int32_t droid_format; + int32_t droid_usage; uint32_t drm_format; uint64_t use_flags; + uint64_t reserved_region_size; + std::string name; }; #endif diff --git a/cros_gralloc/gralloc0/gralloc0.cc b/cros_gralloc/gralloc0/gralloc0.cc index a70498a..170dae9 100644 --- a/cros_gralloc/gralloc0/gralloc0.cc +++ b/cros_gralloc/gralloc0/gralloc0.cc @@ -119,9 +119,10 @@ static int gralloc0_alloc(alloc_device_t *dev, int w, int h, int format, int usa descriptor.width = w; descriptor.height = h; descriptor.droid_format = format; - descriptor.producer_usage = descriptor.consumer_usage = usage; + descriptor.droid_usage = usage; descriptor.drm_format = cros_gralloc_convert_format(format); descriptor.use_flags = gralloc0_convert_usage(usage); + descriptor.reserved_region_size = 0; supported = mod->driver->is_supported(&descriptor); if (!supported && (usage & GRALLOC_USAGE_HW_COMPOSER)) { @@ -248,7 +249,7 @@ static int gralloc0_unlock(struct gralloc_module_t const *module, buffer_handle_ if (ret) return ret; - ret = cros_gralloc_sync_wait(fence_fd); + ret = cros_gralloc_sync_wait(fence_fd, /*close_acquire_fence=*/true); if (ret) return ret; @@ -359,7 +360,7 @@ static int gralloc0_lock_async(struct gralloc_module_t const *module, buffer_han assert(h >= 0); map_flags = gralloc0_convert_map_usage(usage); - ret = mod->driver->lock(handle, fence_fd, &rect, map_flags, addr); + ret = mod->driver->lock(handle, fence_fd, true, &rect, map_flags, addr); *vaddr = addr[0]; return ret; } @@ -404,7 +405,7 @@ static int gralloc0_lock_async_ycbcr(struct gralloc_module_t const *module, buff assert(h >= 0); map_flags = gralloc0_convert_map_usage(usage); - ret = mod->driver->lock(handle, fence_fd, &rect, map_flags, addr); + ret = mod->driver->lock(handle, fence_fd, true, &rect, map_flags, addr); if (ret) return ret; diff --git a/cros_gralloc/gralloc0/tests/gralloctest.c b/cros_gralloc/gralloc0/tests/gralloctest.c index 8dfcd0b..f663cd0 100644 --- a/cros_gralloc/gralloc0/tests/gralloctest.c +++ b/cros_gralloc/gralloc0/tests/gralloctest.c @@ -42,10 +42,11 @@ } while (0) /* Private API enumeration -- see */ -enum { GRALLOC_DRM_GET_STRIDE, - GRALLOC_DRM_GET_FORMAT, - GRALLOC_DRM_GET_DIMENSIONS, - GRALLOC_DRM_GET_BACKING_STORE, +enum { + GRALLOC_DRM_GET_STRIDE, + GRALLOC_DRM_GET_FORMAT, + GRALLOC_DRM_GET_DIMENSIONS, + GRALLOC_DRM_GET_BACKING_STORE, }; struct gralloctest_context { diff --git a/cros_gralloc/gralloc4/.clang-format b/cros_gralloc/gralloc4/.clang-format new file mode 100644 index 0000000..b310cc1 --- /dev/null +++ b/cros_gralloc/gralloc4/.clang-format @@ -0,0 +1,19 @@ +# Copyright 2020 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. +# +# This directory is formatted to match the format of the interfaces implemented. + +BasedOnStyle: Google +Standard: Cpp11 +AccessModifierOffset: -2 +AllowShortFunctionsOnASingleLine: Inline +ColumnLimit: 100 +CommentPragmas: NOLINT:.* +DerivePointerAlignment: false +IncludeBlocks: Preserve +IndentWidth: 4 +ContinuationIndentWidth: 8 +PointerAlignment: Left +TabWidth: 4 +UseTab: Never \ No newline at end of file diff --git a/cros_gralloc/gralloc4/Android.bp b/cros_gralloc/gralloc4/Android.bp new file mode 100644 index 0000000..a0a8622 --- /dev/null +++ b/cros_gralloc/gralloc4/Android.bp @@ -0,0 +1,82 @@ +/* + * Copyright 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +cc_binary { + name: "android.hardware.graphics.allocator@4.0-service.minigbm", + relative_install_path: "hw", + vendor: true, + init_rc: ["android.hardware.graphics.allocator@4.0-service.minigbm.rc"], + + cflags: [ + "-Wall", + "-Werror", + ], + + shared_libs: [ + "android.hardware.graphics.allocator@4.0", + "android.hardware.graphics.mapper@4.0", + "libbase", + "libcutils", + "libgralloctypes", + "libhidlbase", + "liblog", + "libsync", + "libutils", + ], + + static_libs: [ + "libdrm", + "libminigbm_cros_gralloc", + ], + + srcs: [ + "CrosGralloc4Allocator.cc", + "CrosGralloc4AllocatorService.cc", + "CrosGralloc4Utils.cc", + ], +} + +cc_library_shared { + name: "android.hardware.graphics.mapper@4.0-impl.minigbm", + relative_install_path: "hw", + vendor: true, + + cflags: [ + "-Wall", + "-Werror", + ], + + shared_libs: [ + "android.hardware.graphics.mapper@4.0", + "libbase", + "libcutils", + "libgralloctypes", + "libhidlbase", + "liblog", + "libsync", + "libutils", + ], + + static_libs: [ + "libdrm", + "libminigbm_cros_gralloc", + ], + + srcs: [ + "CrosGralloc4Mapper.cc", + "CrosGralloc4Utils.cc", + ], +} diff --git a/cros_gralloc/gralloc4/CrosGralloc4Allocator.cc b/cros_gralloc/gralloc4/CrosGralloc4Allocator.cc new file mode 100644 index 0000000..4fb7845 --- /dev/null +++ b/cros_gralloc/gralloc4/CrosGralloc4Allocator.cc @@ -0,0 +1,122 @@ +/* + * Copyright 2020 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 "cros_gralloc/gralloc4/CrosGralloc4Allocator.h" + +#include +#include + +#include "cros_gralloc/cros_gralloc_helpers.h" +#include "cros_gralloc/gralloc4/CrosGralloc4Utils.h" + +using android::hardware::hidl_handle; +using android::hardware::hidl_vec; +using android::hardware::Return; +using android::hardware::Void; +using android::hardware::graphics::common::V1_2::BufferUsage; +using android::hardware::graphics::common::V1_2::PixelFormat; +using android::hardware::graphics::mapper::V4_0::Error; + +using BufferDescriptorInfo = + android::hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo; + +CrosGralloc4Allocator::CrosGralloc4Allocator() : mDriver(std::make_unique()) { + if (mDriver->init()) { + drv_log("Failed to initialize driver.\n"); + mDriver = nullptr; + } +} + +Error CrosGralloc4Allocator::allocate(const BufferDescriptorInfo& descriptor, uint32_t* outStride, + hidl_handle* outHandle) { + if (!mDriver) { + drv_log("Failed to allocate. Driver is uninitialized.\n"); + return Error::NO_RESOURCES; + } + + if (!outStride || !outHandle) { + return Error::NO_RESOURCES; + } + + struct cros_gralloc_buffer_descriptor crosDescriptor; + if (convertToCrosDescriptor(descriptor, &crosDescriptor)) { + return Error::UNSUPPORTED; + } + + bool supported = mDriver->is_supported(&crosDescriptor); + if (!supported && (descriptor.usage & BufferUsage::COMPOSER_OVERLAY)) { + crosDescriptor.use_flags &= ~BO_USE_SCANOUT; + supported = mDriver->is_supported(&crosDescriptor); + } + + if (!supported) { + std::string drmFormatString = getDrmFormatString(crosDescriptor.drm_format); + std::string pixelFormatString = getPixelFormatString(descriptor.format); + std::string usageString = getUsageString(descriptor.usage); + drv_log("Unsupported combination -- pixel format: %s, drm format:%s, usage: %s\n", + pixelFormatString.c_str(), drmFormatString.c_str(), usageString.c_str()); + return Error::UNSUPPORTED; + } + + buffer_handle_t handle; + int ret = mDriver->allocate(&crosDescriptor, &handle); + if (ret) { + return Error::NO_RESOURCES; + } + + cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(handle); + if (!crosHandle) { + return Error::NO_RESOURCES; + } + + *outHandle = handle; + *outStride = crosHandle->pixel_stride; + + return Error::NONE; +} + +Return CrosGralloc4Allocator::allocate(const hidl_vec& descriptor, uint32_t count, + allocate_cb hidlCb) { + hidl_vec handles; + + if (!mDriver) { + drv_log("Failed to allocate. Driver is uninitialized.\n"); + hidlCb(Error::NO_RESOURCES, 0, handles); + return Void(); + } + + BufferDescriptorInfo description; + + int ret = android::gralloc4::decodeBufferDescriptorInfo(descriptor, &description); + if (ret) { + drv_log("Failed to allocate. Failed to decode buffer descriptor: %d.\n", ret); + hidlCb(Error::BAD_DESCRIPTOR, 0, handles); + return Void(); + } + + handles.resize(count); + + uint32_t stride = 0; + for (int i = 0; i < handles.size(); i++) { + Error err = allocate(description, &stride, &(handles[i])); + if (err != Error::NONE) { + for (int j = 0; j < i; j++) { + mDriver->release(handles[j].getNativeHandle()); + } + handles.resize(0); + hidlCb(err, 0, handles); + return Void(); + } + } + + hidlCb(Error::NONE, stride, handles); + + for (const hidl_handle& handle : handles) { + mDriver->release(handle.getNativeHandle()); + } + + return Void(); +} diff --git a/cros_gralloc/gralloc4/CrosGralloc4Allocator.h b/cros_gralloc/gralloc4/CrosGralloc4Allocator.h new file mode 100644 index 0000000..21ad7ad --- /dev/null +++ b/cros_gralloc/gralloc4/CrosGralloc4Allocator.h @@ -0,0 +1,26 @@ +/* + * Copyright 2020 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 +#include + +#include "cros_gralloc/cros_gralloc_driver.h" + +class CrosGralloc4Allocator : public android::hardware::graphics::allocator::V4_0::IAllocator { + public: + CrosGralloc4Allocator(); + + android::hardware::Return allocate(const android::hardware::hidl_vec& descriptor, + uint32_t count, allocate_cb hidl_cb) override; + + private: + android::hardware::graphics::mapper::V4_0::Error allocate( + const android::hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo& + description, + uint32_t* outStride, android::hardware::hidl_handle* outHandle); + + std::unique_ptr mDriver; +}; diff --git a/cros_gralloc/gralloc4/CrosGralloc4AllocatorService.cc b/cros_gralloc/gralloc4/CrosGralloc4AllocatorService.cc new file mode 100644 index 0000000..5b79860 --- /dev/null +++ b/cros_gralloc/gralloc4/CrosGralloc4AllocatorService.cc @@ -0,0 +1,30 @@ +/* + * Copyright 2020 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. + */ + +#define LOG_TAG "AllocatorService" + +#include + +#include "cros_gralloc/gralloc4/CrosGralloc4Allocator.h" + +using android::sp; +using android::hardware::configureRpcThreadpool; +using android::hardware::joinRpcThreadpool; +using android::hardware::graphics::allocator::V4_0::IAllocator; + +int main(int, char**) { + sp allocator = new CrosGralloc4Allocator(); + configureRpcThreadpool(4, true /* callerWillJoin */); + if (allocator->registerAsService() != android::NO_ERROR) { + ALOGE("failed to register graphics IAllocator 4.0 service"); + return -EINVAL; + } + + ALOGI("graphics IAllocator 4.0 service is initialized"); + android::hardware::joinRpcThreadpool(); + ALOGI("graphics IAllocator 4.0 service is terminating"); + return 0; +} diff --git a/cros_gralloc/gralloc4/CrosGralloc4Mapper.cc b/cros_gralloc/gralloc4/CrosGralloc4Mapper.cc new file mode 100644 index 0000000..47e24ac --- /dev/null +++ b/cros_gralloc/gralloc4/CrosGralloc4Mapper.cc @@ -0,0 +1,1004 @@ +/* + * Copyright 2020 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 "cros_gralloc/gralloc4/CrosGralloc4Mapper.h" + +#include +#include +#include +#include +#include +#include + +#include "cros_gralloc/gralloc4/CrosGralloc4Utils.h" +#include "helpers.h" + +using aidl::android::hardware::graphics::common::BlendMode; +using aidl::android::hardware::graphics::common::Dataspace; +using aidl::android::hardware::graphics::common::PlaneLayout; +using aidl::android::hardware::graphics::common::Rect; +using android::hardware::hidl_handle; +using android::hardware::hidl_vec; +using android::hardware::Return; +using android::hardware::Void; +using android::hardware::graphics::common::V1_2::BufferUsage; +using android::hardware::graphics::common::V1_2::PixelFormat; +using android::hardware::graphics::mapper::V4_0::Error; +using android::hardware::graphics::mapper::V4_0::IMapper; + +CrosGralloc4Mapper::CrosGralloc4Mapper() : mDriver(std::make_unique()) { + if (mDriver->init()) { + drv_log("Failed to initialize driver.\n"); + mDriver = nullptr; + } +} + +Return CrosGralloc4Mapper::createDescriptor(const BufferDescriptorInfo& description, + createDescriptor_cb hidlCb) { + hidl_vec descriptor; + + if (description.width == 0) { + drv_log("Failed to createDescriptor. Bad width: %d.\n", description.width); + hidlCb(Error::BAD_VALUE, descriptor); + return Void(); + } + + if (description.height == 0) { + drv_log("Failed to createDescriptor. Bad height: %d.\n", description.height); + hidlCb(Error::BAD_VALUE, descriptor); + return Void(); + } + + if (description.layerCount == 0) { + drv_log("Failed to createDescriptor. Bad layer count: %d.\n", description.layerCount); + hidlCb(Error::BAD_VALUE, descriptor); + return Void(); + } + + int ret = android::gralloc4::encodeBufferDescriptorInfo(description, &descriptor); + if (ret) { + drv_log("Failed to createDescriptor. Failed to encode: %d.\n", ret); + hidlCb(Error::BAD_VALUE, descriptor); + return Void(); + } + + hidlCb(Error::NONE, descriptor); + return Void(); +} + +Return CrosGralloc4Mapper::importBuffer(const hidl_handle& handle, importBuffer_cb hidlCb) { + if (!mDriver) { + drv_log("Failed to import buffer. Driver is uninitialized.\n"); + hidlCb(Error::NO_RESOURCES, nullptr); + return Void(); + } + + const native_handle_t* bufferHandle = handle.getNativeHandle(); + if (!bufferHandle || bufferHandle->numFds == 0) { + drv_log("Failed to importBuffer. Bad handle.\n"); + hidlCb(Error::BAD_BUFFER, nullptr); + return Void(); + } + + native_handle_t* importedBufferHandle = native_handle_clone(bufferHandle); + if (!importedBufferHandle) { + drv_log("Failed to importBuffer. Handle clone failed.\n"); + hidlCb(Error::NO_RESOURCES, nullptr); + return Void(); + } + + int ret = mDriver->retain(importedBufferHandle); + if (ret) { + native_handle_close(importedBufferHandle); + native_handle_delete(importedBufferHandle); + hidlCb(Error::NO_RESOURCES, nullptr); + return Void(); + } + + hidlCb(Error::NONE, importedBufferHandle); + return Void(); +} + +Return CrosGralloc4Mapper::freeBuffer(void* rawHandle) { + if (!mDriver) { + drv_log("Failed to freeBuffer. Driver is uninitialized.\n"); + return Error::NO_RESOURCES; + } + + native_handle_t* bufferHandle = reinterpret_cast(rawHandle); + if (!bufferHandle) { + drv_log("Failed to freeBuffer. Empty handle.\n"); + return Error::BAD_BUFFER; + } + + int ret = mDriver->release(bufferHandle); + if (ret) { + return Error::BAD_BUFFER; + } + + native_handle_close(bufferHandle); + native_handle_delete(bufferHandle); + return Error::NONE; +} + +Return CrosGralloc4Mapper::validateBufferSize(void* rawHandle, + const BufferDescriptorInfo& descriptor, + uint32_t stride) { + if (!mDriver) { + drv_log("Failed to validateBufferSize. Driver is uninitialized.\n"); + return Error::NO_RESOURCES; + } + + native_handle_t* bufferHandle = reinterpret_cast(rawHandle); + if (!bufferHandle) { + drv_log("Failed to validateBufferSize. Empty handle.\n"); + return Error::BAD_BUFFER; + } + + cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle); + if (!crosHandle) { + drv_log("Failed to validateBufferSize. Invalid handle.\n"); + return Error::BAD_BUFFER; + } + + PixelFormat crosHandleFormat = static_cast(crosHandle->droid_format); + if (descriptor.format != crosHandleFormat) { + drv_log("Failed to validateBufferSize. Format mismatch.\n"); + return Error::BAD_BUFFER; + } + + if (descriptor.width != crosHandle->width) { + drv_log("Failed to validateBufferSize. Width mismatch (%d vs %d).\n", descriptor.width, + crosHandle->width); + return Error::BAD_VALUE; + } + + if (descriptor.height != crosHandle->height) { + drv_log("Failed to validateBufferSize. Height mismatch (%d vs %d).\n", descriptor.height, + crosHandle->height); + return Error::BAD_VALUE; + } + + if (stride != crosHandle->pixel_stride) { + drv_log("Failed to validateBufferSize. Stride mismatch (%d vs %d).\n", stride, + crosHandle->pixel_stride); + return Error::BAD_VALUE; + } + + return Error::NONE; +} + +Return CrosGralloc4Mapper::getTransportSize(void* rawHandle, getTransportSize_cb hidlCb) { + if (!mDriver) { + drv_log("Failed to getTransportSize. Driver is uninitialized.\n"); + hidlCb(Error::BAD_BUFFER, 0, 0); + return Void(); + } + + native_handle_t* bufferHandle = reinterpret_cast(rawHandle); + if (!bufferHandle) { + drv_log("Failed to getTransportSize. Bad handle.\n"); + hidlCb(Error::BAD_BUFFER, 0, 0); + return Void(); + } + + // No local process data is currently stored on the native handle. + hidlCb(Error::NONE, bufferHandle->numFds, bufferHandle->numInts); + return Void(); +} + +Return CrosGralloc4Mapper::lock(void* rawBuffer, uint64_t cpuUsage, const Rect& region, + const hidl_handle& acquireFence, lock_cb hidlCb) { + if (!mDriver) { + drv_log("Failed to lock. Driver is uninitialized.\n"); + hidlCb(Error::NO_RESOURCES, nullptr); + return Void(); + } + + buffer_handle_t bufferHandle = reinterpret_cast(rawBuffer); + if (!bufferHandle) { + drv_log("Failed to lock. Empty handle.\n"); + hidlCb(Error::BAD_BUFFER, nullptr); + return Void(); + } + + if (cpuUsage == 0) { + drv_log("Failed to lock. Bad cpu usage: %" PRIu64 ".\n", cpuUsage); + hidlCb(Error::BAD_VALUE, nullptr); + return Void(); + } + + uint32_t mapUsage = 0; + int ret = convertToMapUsage(cpuUsage, &mapUsage); + if (ret) { + drv_log("Failed to lock. Convert usage failed.\n"); + hidlCb(Error::BAD_VALUE, nullptr); + return Void(); + } + + cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle); + if (crosHandle == nullptr) { + drv_log("Failed to lock. Invalid handle.\n"); + hidlCb(Error::BAD_VALUE, nullptr); + return Void(); + } + + if (region.left < 0) { + drv_log("Failed to lock. Invalid region: negative left value %d.\n", region.left); + hidlCb(Error::BAD_VALUE, nullptr); + return Void(); + } + + if (region.top < 0) { + drv_log("Failed to lock. Invalid region: negative top value %d.\n", region.top); + hidlCb(Error::BAD_VALUE, nullptr); + return Void(); + } + + if (region.width < 0) { + drv_log("Failed to lock. Invalid region: negative width value %d.\n", region.width); + hidlCb(Error::BAD_VALUE, nullptr); + return Void(); + } + + if (region.height < 0) { + drv_log("Failed to lock. Invalid region: negative height value %d.\n", region.height); + hidlCb(Error::BAD_VALUE, nullptr); + return Void(); + } + + if (region.width > crosHandle->width) { + drv_log("Failed to lock. Invalid region: width greater than buffer width (%d vs %d).\n", + region.width, crosHandle->width); + hidlCb(Error::BAD_VALUE, nullptr); + return Void(); + } + + if (region.height > crosHandle->height) { + drv_log("Failed to lock. Invalid region: height greater than buffer height (%d vs %d).\n", + region.height, crosHandle->height); + hidlCb(Error::BAD_VALUE, nullptr); + return Void(); + } + + struct rectangle rect = {static_cast(region.left), static_cast(region.top), + static_cast(region.width), + static_cast(region.height)}; + + // An access region of all zeros means the entire buffer. + if (rect.x == 0 && rect.y == 0 && rect.width == 0 && rect.height == 0) { + rect.width = crosHandle->width; + rect.height = crosHandle->height; + } + + int acquireFenceFd = -1; + ret = convertToFenceFd(acquireFence, &acquireFenceFd); + if (ret) { + drv_log("Failed to lock. Bad acquire fence.\n"); + hidlCb(Error::BAD_VALUE, nullptr); + return Void(); + } + + uint8_t* addr[DRV_MAX_PLANES]; + ret = mDriver->lock(bufferHandle, acquireFenceFd, /*close_acquire_fence=*/false, &rect, + mapUsage, addr); + if (ret) { + hidlCb(Error::BAD_VALUE, nullptr); + return Void(); + } + + hidlCb(Error::NONE, addr[0]); + return Void(); +} + +Return CrosGralloc4Mapper::unlock(void* rawHandle, unlock_cb hidlCb) { + if (!mDriver) { + drv_log("Failed to unlock. Driver is uninitialized.\n"); + hidlCb(Error::BAD_BUFFER, nullptr); + return Void(); + } + + buffer_handle_t bufferHandle = reinterpret_cast(rawHandle); + if (!bufferHandle) { + drv_log("Failed to unlock. Empty handle.\n"); + hidlCb(Error::BAD_BUFFER, nullptr); + return Void(); + } + + int releaseFenceFd = -1; + int ret = mDriver->unlock(bufferHandle, &releaseFenceFd); + if (ret) { + drv_log("Failed to unlock.\n"); + hidlCb(Error::BAD_BUFFER, nullptr); + return Void(); + } + + hidl_handle releaseFenceHandle; + ret = convertToFenceHandle(releaseFenceFd, &releaseFenceHandle); + if (ret) { + drv_log("Failed to unlock. Failed to convert release fence to handle.\n"); + hidlCb(Error::BAD_BUFFER, nullptr); + return Void(); + } + + hidlCb(Error::NONE, releaseFenceHandle); + return Void(); +} + +Return CrosGralloc4Mapper::flushLockedBuffer(void* rawHandle, flushLockedBuffer_cb hidlCb) { + if (!mDriver) { + drv_log("Failed to flushLockedBuffer. Driver is uninitialized.\n"); + hidlCb(Error::NO_RESOURCES, nullptr); + return Void(); + } + + buffer_handle_t bufferHandle = reinterpret_cast(rawHandle); + if (!bufferHandle) { + drv_log("Failed to flushLockedBuffer. Empty handle.\n"); + hidlCb(Error::BAD_BUFFER, nullptr); + return Void(); + } + + int releaseFenceFd = -1; + int ret = mDriver->flush(bufferHandle, &releaseFenceFd); + if (ret) { + drv_log("Failed to flushLockedBuffer. Flush failed.\n"); + hidlCb(Error::BAD_BUFFER, nullptr); + return Void(); + } + + hidl_handle releaseFenceHandle; + ret = convertToFenceHandle(releaseFenceFd, &releaseFenceHandle); + if (ret) { + drv_log("Failed to flushLockedBuffer. Failed to convert release fence to handle.\n"); + hidlCb(Error::BAD_BUFFER, nullptr); + return Void(); + } + + hidlCb(Error::NONE, releaseFenceHandle); + return Void(); +} + +Return CrosGralloc4Mapper::rereadLockedBuffer(void* rawHandle) { + if (!mDriver) { + drv_log("Failed to rereadLockedBuffer. Driver is uninitialized.\n"); + return Error::NO_RESOURCES; + } + + buffer_handle_t bufferHandle = reinterpret_cast(rawHandle); + if (!bufferHandle) { + drv_log("Failed to rereadLockedBuffer. Empty handle.\n"); + return Error::BAD_BUFFER; + } + + int ret = mDriver->invalidate(bufferHandle); + if (ret) { + drv_log("Failed to rereadLockedBuffer. Failed to invalidate.\n"); + return Error::BAD_BUFFER; + } + + return Error::NONE; +} + +Return CrosGralloc4Mapper::isSupported(const BufferDescriptorInfo& descriptor, + isSupported_cb hidlCb) { + if (!mDriver) { + drv_log("Failed to isSupported. Driver is uninitialized.\n"); + hidlCb(Error::BAD_VALUE, false); + return Void(); + } + + struct cros_gralloc_buffer_descriptor crosDescriptor; + if (convertToCrosDescriptor(descriptor, &crosDescriptor)) { + hidlCb(Error::NONE, false); + return Void(); + } + + bool supported = mDriver->is_supported(&crosDescriptor); + if (!supported) { + crosDescriptor.use_flags &= ~BO_USE_SCANOUT; + supported = mDriver->is_supported(&crosDescriptor); + } + + hidlCb(Error::NONE, supported); + return Void(); +} + +Return CrosGralloc4Mapper::get(void* rawHandle, const MetadataType& metadataType, + get_cb hidlCb) { + hidl_vec encodedMetadata; + + if (!mDriver) { + drv_log("Failed to get. Driver is uninitialized.\n"); + hidlCb(Error::NO_RESOURCES, encodedMetadata); + return Void(); + } + + buffer_handle_t bufferHandle = reinterpret_cast(rawHandle); + if (!bufferHandle) { + drv_log("Failed to get. Empty handle.\n"); + hidlCb(Error::BAD_BUFFER, encodedMetadata); + return Void(); + } + + cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle); + if (!crosHandle) { + drv_log("Failed to get. Invalid handle.\n"); + hidlCb(Error::BAD_BUFFER, encodedMetadata); + return Void(); + } + + get(crosHandle, metadataType, hidlCb); + return Void(); +} + +Return CrosGralloc4Mapper::get(cros_gralloc_handle_t crosHandle, + const MetadataType& metadataType, get_cb hidlCb) { + hidl_vec encodedMetadata; + + if (!mDriver) { + drv_log("Failed to get. Driver is uninitialized.\n"); + hidlCb(Error::NO_RESOURCES, encodedMetadata); + return Void(); + } + + if (!crosHandle) { + drv_log("Failed to get. Invalid handle.\n"); + hidlCb(Error::BAD_BUFFER, encodedMetadata); + return Void(); + } + + android::status_t status = android::NO_ERROR; + if (metadataType == android::gralloc4::MetadataType_BufferId) { + status = android::gralloc4::encodeBufferId(crosHandle->id, &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_Name) { + const char* name = (const char*)(&crosHandle->base.data[crosHandle->name_offset]); + status = android::gralloc4::encodeName(name, &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_Width) { + status = android::gralloc4::encodeWidth(crosHandle->width, &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_Height) { + status = android::gralloc4::encodeHeight(crosHandle->height, &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_LayerCount) { + status = android::gralloc4::encodeLayerCount(1, &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_PixelFormatRequested) { + PixelFormat pixelFormat = static_cast(crosHandle->droid_format); + status = android::gralloc4::encodePixelFormatRequested(pixelFormat, &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_PixelFormatFourCC) { + status = android::gralloc4::encodePixelFormatFourCC(crosHandle->format, &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_PixelFormatModifier) { + status = android::gralloc4::encodePixelFormatModifier(crosHandle->format_modifier, + &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_Usage) { + uint64_t usage = static_cast(crosHandle->usage); + status = android::gralloc4::encodeUsage(usage, &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_AllocationSize) { + status = android::gralloc4::encodeAllocationSize(crosHandle->total_size, &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_ProtectedContent) { + uint64_t hasProtectedContent = crosHandle->usage & BufferUsage::PROTECTED ? 1 : 0; + status = android::gralloc4::encodeProtectedContent(hasProtectedContent, &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_Compression) { + status = android::gralloc4::encodeCompression(android::gralloc4::Compression_None, + &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_Interlaced) { + status = android::gralloc4::encodeInterlaced(android::gralloc4::Interlaced_None, + &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_ChromaSiting) { + status = android::gralloc4::encodeChromaSiting(android::gralloc4::ChromaSiting_None, + &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_PlaneLayouts) { + std::vector planeLayouts; + getPlaneLayouts(crosHandle->format, &planeLayouts); + + for (size_t plane = 0; plane < planeLayouts.size(); plane++) { + PlaneLayout& planeLayout = planeLayouts[plane]; + planeLayout.offsetInBytes = crosHandle->offsets[plane]; + planeLayout.strideInBytes = crosHandle->strides[plane]; + planeLayout.totalSizeInBytes = crosHandle->sizes[plane]; + planeLayout.widthInSamples = crosHandle->width; + planeLayout.heightInSamples = crosHandle->height; + } + + status = android::gralloc4::encodePlaneLayouts(planeLayouts, &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_Crop) { + std::vector crops; + for (size_t plane = 0; plane < crosHandle->num_planes; plane++) { + aidl::android::hardware::graphics::common::Rect crop; + crop.left = 0; + crop.top = 0; + crop.right = crosHandle->width; + crop.bottom = crosHandle->height; + crops.push_back(crop); + } + + status = android::gralloc4::encodeCrop(crops, &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_Dataspace) { + status = android::gralloc4::encodeDataspace(Dataspace::UNKNOWN, &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_BlendMode) { + status = android::gralloc4::encodeBlendMode(BlendMode::INVALID, &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_Smpte2086) { + status = android::gralloc4::encodeSmpte2086(std::nullopt, &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_Cta861_3) { + status = android::gralloc4::encodeCta861_3(std::nullopt, &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_Smpte2094_40) { + status = android::gralloc4::encodeSmpte2094_40(std::nullopt, &encodedMetadata); + } else { + hidlCb(Error::UNSUPPORTED, encodedMetadata); + return Void(); + } + + if (status != android::NO_ERROR) { + hidlCb(Error::NO_RESOURCES, encodedMetadata); + drv_log("Failed to get. Failed to encode metadata.\n"); + return Void(); + } + + hidlCb(Error::NONE, encodedMetadata); + return Void(); +} + +Return CrosGralloc4Mapper::set(void* rawHandle, const MetadataType& metadataType, + const hidl_vec& /*metadata*/) { + if (!mDriver) { + drv_log("Failed to set. Driver is uninitialized.\n"); + return Error::NO_RESOURCES; + } + + buffer_handle_t bufferHandle = reinterpret_cast(rawHandle); + if (!bufferHandle) { + drv_log("Failed to set. Empty handle.\n"); + return Error::BAD_BUFFER; + } + + cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle); + if (!crosHandle) { + drv_log("Failed to set. Invalid handle.\n"); + return Error::BAD_BUFFER; + } + + if (metadataType == android::gralloc4::MetadataType_BufferId) { + return Error::BAD_VALUE; + } else if (metadataType == android::gralloc4::MetadataType_Name) { + return Error::BAD_VALUE; + } else if (metadataType == android::gralloc4::MetadataType_Width) { + return Error::BAD_VALUE; + } else if (metadataType == android::gralloc4::MetadataType_Height) { + return Error::BAD_VALUE; + } else if (metadataType == android::gralloc4::MetadataType_LayerCount) { + return Error::BAD_VALUE; + } else if (metadataType == android::gralloc4::MetadataType_PixelFormatRequested) { + return Error::BAD_VALUE; + } else if (metadataType == android::gralloc4::MetadataType_Usage) { + return Error::BAD_VALUE; + } + + return Error::UNSUPPORTED; +} + +int CrosGralloc4Mapper::getResolvedDrmFormat(PixelFormat pixelFormat, uint64_t bufferUsage, + uint32_t* outDrmFormat) { + uint32_t drmFormat; + if (convertToDrmFormat(pixelFormat, &drmFormat)) { + std::string pixelFormatString = getPixelFormatString(pixelFormat); + drv_log("Failed to getResolvedDrmFormat. Failed to convert format %s\n", + pixelFormatString.c_str()); + return -1; + } + + uint64_t usage; + if (convertToBufferUsage(bufferUsage, &usage)) { + std::string usageString = getUsageString(bufferUsage); + drv_log("Failed to getResolvedDrmFormat. Failed to convert usage %s\n", + usageString.c_str()); + return -1; + } + + uint32_t resolvedDrmFormat = mDriver->get_resolved_drm_format(drmFormat, usage); + if (resolvedDrmFormat == DRM_FORMAT_INVALID) { + std::string drmFormatString = getDrmFormatString(drmFormat); + drv_log("Failed to getResolvedDrmFormat. Failed to resolve drm format %s\n", + drmFormatString.c_str()); + return -1; + } + + *outDrmFormat = resolvedDrmFormat; + + return 0; +} + +Return CrosGralloc4Mapper::getFromBufferDescriptorInfo( + const BufferDescriptorInfo& descriptor, const MetadataType& metadataType, + getFromBufferDescriptorInfo_cb hidlCb) { + hidl_vec encodedMetadata; + + if (!mDriver) { + drv_log("Failed to getFromBufferDescriptorInfo. Driver is uninitialized.\n"); + hidlCb(Error::NO_RESOURCES, encodedMetadata); + return Void(); + } + + android::status_t status = android::NO_ERROR; + if (metadataType == android::gralloc4::MetadataType_Name) { + status = android::gralloc4::encodeName(descriptor.name, &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_Width) { + status = android::gralloc4::encodeWidth(descriptor.width, &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_Height) { + status = android::gralloc4::encodeHeight(descriptor.height, &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_LayerCount) { + status = android::gralloc4::encodeLayerCount(1, &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_PixelFormatRequested) { + status = android::gralloc4::encodePixelFormatRequested(descriptor.format, &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_PixelFormatFourCC) { + uint32_t drmFormat; + if (getResolvedDrmFormat(descriptor.format, descriptor.usage, &drmFormat)) { + hidlCb(Error::BAD_VALUE, encodedMetadata); + return Void(); + } + status = android::gralloc4::encodePixelFormatFourCC(drmFormat, &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_Usage) { + status = android::gralloc4::encodeUsage(descriptor.usage, &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_ProtectedContent) { + uint64_t hasProtectedContent = descriptor.usage & BufferUsage::PROTECTED ? 1 : 0; + status = android::gralloc4::encodeProtectedContent(hasProtectedContent, &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_Compression) { + status = android::gralloc4::encodeCompression(android::gralloc4::Compression_None, + &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_Interlaced) { + status = android::gralloc4::encodeInterlaced(android::gralloc4::Interlaced_None, + &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_ChromaSiting) { + status = android::gralloc4::encodeChromaSiting(android::gralloc4::ChromaSiting_None, + &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_Crop) { + uint32_t drmFormat; + if (getResolvedDrmFormat(descriptor.format, descriptor.usage, &drmFormat)) { + hidlCb(Error::BAD_VALUE, encodedMetadata); + return Void(); + } + + size_t numPlanes = drv_num_planes_from_format(drmFormat); + + std::vector crops; + for (size_t plane = 0; plane < numPlanes; plane++) { + aidl::android::hardware::graphics::common::Rect crop; + crop.left = 0; + crop.top = 0; + crop.right = descriptor.width; + crop.bottom = descriptor.height; + crops.push_back(crop); + } + status = android::gralloc4::encodeCrop(crops, &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_Dataspace) { + status = android::gralloc4::encodeDataspace(Dataspace::UNKNOWN, &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_BlendMode) { + status = android::gralloc4::encodeBlendMode(BlendMode::INVALID, &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_Smpte2086) { + status = android::gralloc4::encodeSmpte2086(std::nullopt, &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_Cta861_3) { + status = android::gralloc4::encodeCta861_3(std::nullopt, &encodedMetadata); + } else if (metadataType == android::gralloc4::MetadataType_Smpte2094_40) { + status = android::gralloc4::encodeSmpte2094_40(std::nullopt, &encodedMetadata); + } else { + hidlCb(Error::UNSUPPORTED, encodedMetadata); + return Void(); + } + + if (status != android::NO_ERROR) { + hidlCb(Error::NO_RESOURCES, encodedMetadata); + return Void(); + } + + hidlCb(Error::NONE, encodedMetadata); + return Void(); +} + +Return CrosGralloc4Mapper::listSupportedMetadataTypes(listSupportedMetadataTypes_cb hidlCb) { + hidl_vec supported; + + if (!mDriver) { + drv_log("Failed to listSupportedMetadataTypes. Driver is uninitialized.\n"); + hidlCb(Error::NO_RESOURCES, supported); + return Void(); + } + + supported = hidl_vec({ + { + android::gralloc4::MetadataType_BufferId, + "", + /*isGettable=*/true, + /*isSettable=*/false, + }, + { + android::gralloc4::MetadataType_Name, + "", + /*isGettable=*/true, + /*isSettable=*/false, + }, + { + android::gralloc4::MetadataType_Width, + "", + /*isGettable=*/true, + /*isSettable=*/false, + }, + { + android::gralloc4::MetadataType_Height, + "", + /*isGettable=*/true, + /*isSettable=*/false, + }, + { + android::gralloc4::MetadataType_LayerCount, + "", + /*isGettable=*/true, + /*isSettable=*/false, + }, + { + android::gralloc4::MetadataType_PixelFormatRequested, + "", + /*isGettable=*/true, + /*isSettable=*/false, + }, + { + android::gralloc4::MetadataType_PixelFormatFourCC, + "", + /*isGettable=*/true, + /*isSettable=*/false, + }, + { + android::gralloc4::MetadataType_PixelFormatModifier, + "", + /*isGettable=*/true, + /*isSettable=*/false, + }, + { + android::gralloc4::MetadataType_Usage, + "", + /*isGettable=*/true, + /*isSettable=*/false, + }, + { + android::gralloc4::MetadataType_AllocationSize, + "", + /*isGettable=*/true, + /*isSettable=*/false, + }, + { + android::gralloc4::MetadataType_ProtectedContent, + "", + /*isGettable=*/true, + /*isSettable=*/false, + }, + { + android::gralloc4::MetadataType_Compression, + "", + /*isGettable=*/true, + /*isSettable=*/false, + }, + { + android::gralloc4::MetadataType_Interlaced, + "", + /*isGettable=*/true, + /*isSettable=*/false, + }, + { + android::gralloc4::MetadataType_ChromaSiting, + "", + /*isGettable=*/true, + /*isSettable=*/false, + }, + { + android::gralloc4::MetadataType_PlaneLayouts, + "", + /*isGettable=*/true, + /*isSettable=*/false, + }, + { + android::gralloc4::MetadataType_Dataspace, + "", + /*isGettable=*/true, + /*isSettable=*/false, + }, + { + android::gralloc4::MetadataType_BlendMode, + "", + /*isGettable=*/true, + /*isSettable=*/false, + }, + { + android::gralloc4::MetadataType_Smpte2086, + "", + /*isGettable=*/true, + /*isSettable=*/false, + }, + { + android::gralloc4::MetadataType_Cta861_3, + "", + /*isGettable=*/true, + /*isSettable=*/false, + }, + { + android::gralloc4::MetadataType_Smpte2094_40, + "", + /*isGettable=*/true, + /*isSettable=*/false, + }, + }); + + hidlCb(Error::NONE, supported); + return Void(); +} + +Return CrosGralloc4Mapper::dumpBuffer(void* rawHandle, dumpBuffer_cb hidlCb) { + BufferDump bufferDump; + + if (!mDriver) { + drv_log("Failed to dumpBuffer. Driver is uninitialized.\n"); + hidlCb(Error::NO_RESOURCES, bufferDump); + return Void(); + } + + buffer_handle_t bufferHandle = reinterpret_cast(rawHandle); + if (!bufferHandle) { + drv_log("Failed to dumpBuffer. Empty handle.\n"); + hidlCb(Error::BAD_BUFFER, bufferDump); + return Void(); + } + + cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle); + if (!crosHandle) { + drv_log("Failed to dumpBuffer. Invalid handle.\n"); + hidlCb(Error::BAD_BUFFER, bufferDump); + return Void(); + } + + return dumpBuffer(crosHandle, hidlCb); +} + +Return CrosGralloc4Mapper::dumpBuffer(cros_gralloc_handle_t crosHandle, + dumpBuffer_cb hidlCb) { + BufferDump bufferDump; + + if (!mDriver) { + drv_log("Failed to dumpBuffer. Driver is uninitialized.\n"); + hidlCb(Error::NO_RESOURCES, bufferDump); + return Void(); + } + + if (!crosHandle) { + drv_log("Failed to dumpBuffer. Invalid handle.\n"); + hidlCb(Error::BAD_BUFFER, bufferDump); + return Void(); + } + + std::vector metadataDumps; + + MetadataType metadataType = android::gralloc4::MetadataType_BufferId; + auto metadata_get_callback = [&](Error, hidl_vec metadata) { + MetadataDump metadataDump; + metadataDump.metadataType = metadataType; + metadataDump.metadata = metadata; + metadataDumps.push_back(metadataDump); + }; + + metadataType = android::gralloc4::MetadataType_BufferId; + get(crosHandle, metadataType, metadata_get_callback); + + metadataType = android::gralloc4::MetadataType_Name; + get(crosHandle, metadataType, metadata_get_callback); + + metadataType = android::gralloc4::MetadataType_Width; + get(crosHandle, metadataType, metadata_get_callback); + + metadataType = android::gralloc4::MetadataType_Height; + get(crosHandle, metadataType, metadata_get_callback); + + metadataType = android::gralloc4::MetadataType_LayerCount; + get(crosHandle, metadataType, metadata_get_callback); + + metadataType = android::gralloc4::MetadataType_PixelFormatRequested; + get(crosHandle, metadataType, metadata_get_callback); + + metadataType = android::gralloc4::MetadataType_PixelFormatFourCC; + get(crosHandle, metadataType, metadata_get_callback); + + metadataType = android::gralloc4::MetadataType_PixelFormatModifier; + get(crosHandle, metadataType, metadata_get_callback); + + metadataType = android::gralloc4::MetadataType_Usage; + get(crosHandle, metadataType, metadata_get_callback); + + metadataType = android::gralloc4::MetadataType_AllocationSize; + get(crosHandle, metadataType, metadata_get_callback); + + metadataType = android::gralloc4::MetadataType_ProtectedContent; + get(crosHandle, metadataType, metadata_get_callback); + + metadataType = android::gralloc4::MetadataType_Compression; + get(crosHandle, metadataType, metadata_get_callback); + + metadataType = android::gralloc4::MetadataType_Interlaced; + get(crosHandle, metadataType, metadata_get_callback); + + metadataType = android::gralloc4::MetadataType_ChromaSiting; + get(crosHandle, metadataType, metadata_get_callback); + + metadataType = android::gralloc4::MetadataType_PlaneLayouts; + get(crosHandle, metadataType, metadata_get_callback); + + metadataType = android::gralloc4::MetadataType_Dataspace; + get(crosHandle, metadataType, metadata_get_callback); + + metadataType = android::gralloc4::MetadataType_BlendMode; + get(crosHandle, metadataType, metadata_get_callback); + + bufferDump.metadataDump = metadataDumps; + hidlCb(Error::NONE, bufferDump); + return Void(); +} + +Return CrosGralloc4Mapper::dumpBuffers(dumpBuffers_cb hidlCb) { + std::vector bufferDumps; + + if (!mDriver) { + drv_log("Failed to dumpBuffers. Driver is uninitialized.\n"); + hidlCb(Error::NO_RESOURCES, bufferDumps); + return Void(); + } + + Error error = Error::NONE; + + auto handleCallback = [&](cros_gralloc_handle_t crosHandle) { + auto dumpBufferCallback = [&](Error err, BufferDump bufferDump) { + error = err; + if (error == Error::NONE) { + bufferDumps.push_back(bufferDump); + } + }; + + dumpBuffer(crosHandle, dumpBufferCallback); + }; + mDriver->for_each_handle(handleCallback); + + hidlCb(error, bufferDumps); + return Void(); +} + +Return CrosGralloc4Mapper::getReservedRegion(void* rawHandle, getReservedRegion_cb hidlCb) { + if (!mDriver) { + drv_log("Failed to getReservedRegion. Driver is uninitialized.\n"); + hidlCb(Error::NO_RESOURCES, nullptr, 0); + return Void(); + } + + buffer_handle_t bufferHandle = reinterpret_cast(rawHandle); + if (!bufferHandle) { + drv_log("Failed to getReservedRegion. Empty handle.\n"); + hidlCb(Error::BAD_BUFFER, nullptr, 0); + return Void(); + } + + cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(bufferHandle); + if (!crosHandle) { + drv_log("Failed to getReservedRegion. Invalid handle.\n"); + hidlCb(Error::BAD_BUFFER, nullptr, 0); + return Void(); + } + + void* reservedRegionAddr = nullptr; + uint64_t reservedRegionSize = 0; + int ret = mDriver->get_reserved_region(bufferHandle, &reservedRegionAddr, &reservedRegionSize); + if (ret) { + drv_log("Failed to getReservedRegion.\n"); + hidlCb(Error::BAD_BUFFER, nullptr, 0); + return Void(); + } + + hidlCb(Error::NONE, reservedRegionAddr, reservedRegionSize); + return Void(); +} + +android::hardware::graphics::mapper::V4_0::IMapper* HIDL_FETCH_IMapper(const char* /*name*/) { + return static_cast(new CrosGralloc4Mapper); +} diff --git a/cros_gralloc/gralloc4/CrosGralloc4Mapper.h b/cros_gralloc/gralloc4/CrosGralloc4Mapper.h new file mode 100644 index 0000000..b318930 --- /dev/null +++ b/cros_gralloc/gralloc4/CrosGralloc4Mapper.h @@ -0,0 +1,80 @@ +/* + * Copyright 2020 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 + +#include "cros_gralloc/cros_gralloc_driver.h" +#include "cros_gralloc/cros_gralloc_handle.h" + +class CrosGralloc4Mapper : public android::hardware::graphics::mapper::V4_0::IMapper { + public: + CrosGralloc4Mapper(); + + android::hardware::Return createDescriptor(const BufferDescriptorInfo& description, + createDescriptor_cb hidlCb) override; + + android::hardware::Return importBuffer(const android::hardware::hidl_handle& rawHandle, + importBuffer_cb hidlCb) override; + + android::hardware::Return freeBuffer( + void* rawHandle) override; + + android::hardware::Return validateBufferSize( + void* rawHandle, const BufferDescriptorInfo& descriptor, uint32_t stride) override; + + android::hardware::Return getTransportSize(void* rawHandle, + getTransportSize_cb hidlCb) override; + + android::hardware::Return lock(void* rawHandle, uint64_t cpuUsage, + const Rect& accessRegion, + const android::hardware::hidl_handle& acquireFence, + lock_cb hidlCb) override; + + android::hardware::Return unlock(void* rawHandle, unlock_cb hidlCb) override; + + android::hardware::Return flushLockedBuffer(void* rawHandle, + flushLockedBuffer_cb hidlCb) override; + + android::hardware::Return rereadLockedBuffer( + void* rawHandle) override; + + android::hardware::Return isSupported(const BufferDescriptorInfo& descriptor, + isSupported_cb hidlCb) override; + + android::hardware::Return get(void* rawHandle, const MetadataType& metadataType, + get_cb hidlCb) override; + + android::hardware::Return set( + void* rawHandle, const MetadataType& metadataType, + const android::hardware::hidl_vec& metadata) override; + + android::hardware::Return getFromBufferDescriptorInfo( + const BufferDescriptorInfo& descriptor, const MetadataType& metadataType, + getFromBufferDescriptorInfo_cb hidlCb) override; + + android::hardware::Return listSupportedMetadataTypes( + listSupportedMetadataTypes_cb hidlCb) override; + + android::hardware::Return dumpBuffer(void* rawHandle, dumpBuffer_cb hidlCb) override; + android::hardware::Return dumpBuffers(dumpBuffers_cb hidlCb) override; + + android::hardware::Return getReservedRegion(void* rawHandle, + getReservedRegion_cb hidlCb) override; + + private: + android::hardware::Return get(cros_gralloc_handle_t crosHandle, + const MetadataType& metadataType, get_cb hidlCb); + + android::hardware::Return dumpBuffer(cros_gralloc_handle_t crosHandle, + dumpBuffer_cb hidlCb); + + int getResolvedDrmFormat(android::hardware::graphics::common::V1_2::PixelFormat pixelFormat, + uint64_t bufferUsage, uint32_t* outDrmFormat); + + std::unique_ptr mDriver; +}; + +extern "C" android::hardware::graphics::mapper::V4_0::IMapper* HIDL_FETCH_IMapper(const char* name); diff --git a/cros_gralloc/gralloc4/CrosGralloc4Utils.cc b/cros_gralloc/gralloc4/CrosGralloc4Utils.cc new file mode 100644 index 0000000..8931164 --- /dev/null +++ b/cros_gralloc/gralloc4/CrosGralloc4Utils.cc @@ -0,0 +1,772 @@ +/* + * Copyright 2020 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 "cros_gralloc/gralloc4/CrosGralloc4Utils.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "cros_gralloc/cros_gralloc_helpers.h" + +using aidl::android::hardware::graphics::common::PlaneLayout; +using aidl::android::hardware::graphics::common::PlaneLayoutComponent; +using aidl::android::hardware::graphics::common::PlaneLayoutComponentType; +using android::hardware::hidl_bitfield; +using android::hardware::hidl_handle; +using android::hardware::graphics::common::V1_2::BufferUsage; +using android::hardware::graphics::common::V1_2::PixelFormat; + +using BufferDescriptorInfo = + android::hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo; + +std::string getDrmFormatString(uint32_t drmFormat) { + switch (drmFormat) { + case DRM_FORMAT_ABGR1555: + return "DRM_FORMAT_ABGR1555"; + case DRM_FORMAT_ABGR2101010: + return "DRM_FORMAT_ABGR2101010"; + case DRM_FORMAT_ABGR4444: + return "DRM_FORMAT_ABGR4444"; + case DRM_FORMAT_ABGR8888: + return "DRM_FORMAT_ABGR8888"; + case DRM_FORMAT_ARGB1555: + return "DRM_FORMAT_ARGB1555"; + case DRM_FORMAT_ARGB2101010: + return "DRM_FORMAT_ARGB2101010"; + case DRM_FORMAT_ARGB4444: + return "DRM_FORMAT_ARGB4444"; + case DRM_FORMAT_ARGB8888: + return "DRM_FORMAT_ARGB8888"; + case DRM_FORMAT_AYUV: + return "DRM_FORMAT_AYUV"; + case DRM_FORMAT_BGR233: + return "DRM_FORMAT_BGR233"; + case DRM_FORMAT_BGR565: + return "DRM_FORMAT_BGR565"; + case DRM_FORMAT_BGR888: + return "DRM_FORMAT_BGR888"; + case DRM_FORMAT_BGRA1010102: + return "DRM_FORMAT_BGRA1010102"; + case DRM_FORMAT_BGRA4444: + return "DRM_FORMAT_BGRA4444"; + case DRM_FORMAT_BGRA5551: + return "DRM_FORMAT_BGRA5551"; + case DRM_FORMAT_BGRA8888: + return "DRM_FORMAT_BGRA8888"; + case DRM_FORMAT_BGRX1010102: + return "DRM_FORMAT_BGRX1010102"; + case DRM_FORMAT_BGRX4444: + return "DRM_FORMAT_BGRX4444"; + case DRM_FORMAT_BGRX5551: + return "DRM_FORMAT_BGRX5551"; + case DRM_FORMAT_BGRX8888: + return "DRM_FORMAT_BGRX8888"; + case DRM_FORMAT_C8: + return "DRM_FORMAT_C8"; + case DRM_FORMAT_GR88: + return "DRM_FORMAT_GR88"; + case DRM_FORMAT_NV12: + return "DRM_FORMAT_NV12"; + case DRM_FORMAT_NV21: + return "DRM_FORMAT_NV21"; + case DRM_FORMAT_R8: + return "DRM_FORMAT_R8"; + case DRM_FORMAT_RG88: + return "DRM_FORMAT_RG88"; + case DRM_FORMAT_RGB332: + return "DRM_FORMAT_RGB332"; + case DRM_FORMAT_RGB565: + return "DRM_FORMAT_RGB565"; + case DRM_FORMAT_RGB888: + return "DRM_FORMAT_RGB888"; + case DRM_FORMAT_RGBA1010102: + return "DRM_FORMAT_RGBA1010102"; + case DRM_FORMAT_RGBA4444: + return "DRM_FORMAT_RGBA4444"; + case DRM_FORMAT_RGBA5551: + return "DRM_FORMAT_RGBA5551"; + case DRM_FORMAT_RGBA8888: + return "DRM_FORMAT_RGBA8888"; + case DRM_FORMAT_RGBX1010102: + return "DRM_FORMAT_RGBX1010102"; + case DRM_FORMAT_RGBX4444: + return "DRM_FORMAT_RGBX4444"; + case DRM_FORMAT_RGBX5551: + return "DRM_FORMAT_RGBX5551"; + case DRM_FORMAT_RGBX8888: + return "DRM_FORMAT_RGBX8888"; + case DRM_FORMAT_UYVY: + return "DRM_FORMAT_UYVY"; + case DRM_FORMAT_VYUY: + return "DRM_FORMAT_VYUY"; + case DRM_FORMAT_XBGR1555: + return "DRM_FORMAT_XBGR1555"; + case DRM_FORMAT_XBGR2101010: + return "DRM_FORMAT_XBGR2101010"; + case DRM_FORMAT_XBGR4444: + return "DRM_FORMAT_XBGR4444"; + case DRM_FORMAT_XBGR8888: + return "DRM_FORMAT_XBGR8888"; + case DRM_FORMAT_XRGB1555: + return "DRM_FORMAT_XRGB1555"; + case DRM_FORMAT_XRGB2101010: + return "DRM_FORMAT_XRGB2101010"; + case DRM_FORMAT_XRGB4444: + return "DRM_FORMAT_XRGB4444"; + case DRM_FORMAT_XRGB8888: + return "DRM_FORMAT_XRGB8888"; + case DRM_FORMAT_YUYV: + return "DRM_FORMAT_YUYV"; + case DRM_FORMAT_YVU420: + return "DRM_FORMAT_YVU420"; + case DRM_FORMAT_YVYU: + return "DRM_FORMAT_YVYU"; + } + return android::base::StringPrintf("Unknown(%d)", drmFormat); +} + +std::string getPixelFormatString(PixelFormat format) { + switch (format) { + case PixelFormat::BGRA_8888: + return "PixelFormat::BGRA_8888"; + case PixelFormat::BLOB: + return "PixelFormat::BLOB"; + case PixelFormat::DEPTH_16: + return "PixelFormat::DEPTH_16"; + case PixelFormat::DEPTH_24: + return "PixelFormat::DEPTH_24"; + case PixelFormat::DEPTH_24_STENCIL_8: + return "PixelFormat::DEPTH_24_STENCIL_8"; + case PixelFormat::DEPTH_32F: + return "PixelFormat::DEPTH_24"; + case PixelFormat::DEPTH_32F_STENCIL_8: + return "PixelFormat::DEPTH_24_STENCIL_8"; + case PixelFormat::HSV_888: + return "PixelFormat::HSV_888"; + case PixelFormat::IMPLEMENTATION_DEFINED: + return "PixelFormat::IMPLEMENTATION_DEFINED"; + case PixelFormat::RAW10: + return "PixelFormat::RAW10"; + case PixelFormat::RAW12: + return "PixelFormat::RAW12"; + case PixelFormat::RAW16: + return "PixelFormat::RAW16"; + case PixelFormat::RAW_OPAQUE: + return "PixelFormat::RAW_OPAQUE"; + case PixelFormat::RGBA_1010102: + return "PixelFormat::RGBA_1010102"; + case PixelFormat::RGBA_8888: + return "PixelFormat::RGBA_8888"; + case PixelFormat::RGBA_FP16: + return "PixelFormat::RGBA_FP16"; + case PixelFormat::RGBX_8888: + return "PixelFormat::RGBX_8888"; + case PixelFormat::RGB_565: + return "PixelFormat::RGB_565"; + case PixelFormat::RGB_888: + return "PixelFormat::RGB_888"; + case PixelFormat::STENCIL_8: + return "PixelFormat::STENCIL_8"; + case PixelFormat::Y16: + return "PixelFormat::Y16"; + case PixelFormat::Y8: + return "PixelFormat::Y8"; + case PixelFormat::YCBCR_420_888: + return "PixelFormat::YCBCR_420_888"; + case PixelFormat::YCBCR_422_I: + return "PixelFormat::YCBCR_422_I"; + case PixelFormat::YCBCR_422_SP: + return "PixelFormat::YCBCR_422_SP"; + case PixelFormat::YCBCR_P010: + return "PixelFormat::YCBCR_P010"; + case PixelFormat::YCRCB_420_SP: + return "PixelFormat::YCRCB_420_SP"; + case PixelFormat::YV12: + return "PixelFormat::YV12"; + } + return android::base::StringPrintf("PixelFormat::Unknown(%d)", static_cast(format)); +} + +std::string getUsageString(hidl_bitfield bufferUsage) { + using Underlying = typename std::underlying_type::type; + + Underlying usage = static_cast(bufferUsage); + + std::vector usages; + if (usage & BufferUsage::CAMERA_INPUT) { + usage &= ~static_cast(BufferUsage::CAMERA_INPUT); + usages.push_back("BufferUsage::CAMERA_INPUT"); + } + if (usage & BufferUsage::CAMERA_OUTPUT) { + usage &= ~static_cast(BufferUsage::CAMERA_OUTPUT); + usages.push_back("BufferUsage::CAMERA_OUTPUT"); + } + if (usage & BufferUsage::COMPOSER_CURSOR) { + usage &= ~static_cast(BufferUsage::COMPOSER_CURSOR); + usages.push_back("BufferUsage::COMPOSER_CURSOR"); + } + if (usage & BufferUsage::COMPOSER_OVERLAY) { + usage &= ~static_cast(BufferUsage::COMPOSER_OVERLAY); + usages.push_back("BufferUsage::COMPOSER_OVERLAY"); + } + if (usage & BufferUsage::CPU_READ_OFTEN) { + usage &= ~static_cast(BufferUsage::CPU_READ_OFTEN); + usages.push_back("BufferUsage::CPU_READ_OFTEN"); + } + if (usage & BufferUsage::CPU_READ_NEVER) { + usage &= ~static_cast(BufferUsage::CPU_READ_NEVER); + usages.push_back("BufferUsage::CPU_READ_NEVER"); + } + if (usage & BufferUsage::CPU_READ_RARELY) { + usage &= ~static_cast(BufferUsage::CPU_READ_RARELY); + usages.push_back("BufferUsage::CPU_READ_RARELY"); + } + if (usage & BufferUsage::CPU_WRITE_NEVER) { + usage &= ~static_cast(BufferUsage::CPU_WRITE_NEVER); + usages.push_back("BufferUsage::CPU_WRITE_NEVER"); + } + if (usage & BufferUsage::CPU_WRITE_OFTEN) { + usage &= ~static_cast(BufferUsage::CPU_WRITE_OFTEN); + usages.push_back("BufferUsage::CPU_WRITE_OFTEN"); + } + if (usage & BufferUsage::CPU_WRITE_RARELY) { + usage &= ~static_cast(BufferUsage::CPU_WRITE_RARELY); + usages.push_back("BufferUsage::CPU_WRITE_RARELY"); + } + if (usage & BufferUsage::GPU_RENDER_TARGET) { + usage &= ~static_cast(BufferUsage::GPU_RENDER_TARGET); + usages.push_back("BufferUsage::GPU_RENDER_TARGET"); + } + if (usage & BufferUsage::GPU_TEXTURE) { + usage &= ~static_cast(BufferUsage::GPU_TEXTURE); + usages.push_back("BufferUsage::GPU_TEXTURE"); + } + if (usage & BufferUsage::PROTECTED) { + usage &= ~static_cast(BufferUsage::PROTECTED); + usages.push_back("BufferUsage::PROTECTED"); + } + if (usage & BufferUsage::RENDERSCRIPT) { + usage &= ~static_cast(BufferUsage::RENDERSCRIPT); + usages.push_back("BufferUsage::RENDERSCRIPT"); + } + if (usage & BufferUsage::VIDEO_DECODER) { + usage &= ~static_cast(BufferUsage::VIDEO_DECODER); + usages.push_back("BufferUsage::VIDEO_DECODER"); + } + if (usage & BufferUsage::VIDEO_ENCODER) { + usage &= ~static_cast(BufferUsage::VIDEO_ENCODER); + usages.push_back("BufferUsage::VIDEO_ENCODER"); + } + + if (usage) { + usages.push_back(android::base::StringPrintf("UnknownUsageBits-%" PRIu64, usage)); + } + + return android::base::Join(usages, '|'); +} + +int convertToDrmFormat(PixelFormat format, uint32_t* outDrmFormat) { + switch (format) { + case PixelFormat::BGRA_8888: + *outDrmFormat = DRM_FORMAT_ARGB8888; + return 0; + /** + * Choose DRM_FORMAT_R8 because requires the buffers + * with a format HAL_PIXEL_FORMAT_BLOB have a height of 1, and width + * equal to their size in bytes. + */ + case PixelFormat::BLOB: + *outDrmFormat = DRM_FORMAT_R8; + return 0; + case PixelFormat::DEPTH_16: + return -EINVAL; + case PixelFormat::DEPTH_24: + return -EINVAL; + case PixelFormat::DEPTH_24_STENCIL_8: + return -EINVAL; + case PixelFormat::DEPTH_32F: + return -EINVAL; + case PixelFormat::DEPTH_32F_STENCIL_8: + return -EINVAL; + case PixelFormat::HSV_888: + return -EINVAL; + case PixelFormat::IMPLEMENTATION_DEFINED: + *outDrmFormat = DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED; + return 0; + case PixelFormat::RAW10: + return -EINVAL; + case PixelFormat::RAW12: + return -EINVAL; + case PixelFormat::RAW16: + *outDrmFormat = DRM_FORMAT_R16; + return 0; + /* TODO use blob */ + case PixelFormat::RAW_OPAQUE: + return -EINVAL; + case PixelFormat::RGBA_1010102: + *outDrmFormat = DRM_FORMAT_ABGR2101010; + return 0; + case PixelFormat::RGBA_8888: + *outDrmFormat = DRM_FORMAT_ABGR8888; + return 0; + case PixelFormat::RGBA_FP16: + *outDrmFormat = DRM_FORMAT_ABGR16161616F; + return 0; + case PixelFormat::RGBX_8888: + *outDrmFormat = DRM_FORMAT_XBGR8888; + return 0; + case PixelFormat::RGB_565: + *outDrmFormat = DRM_FORMAT_RGB565; + return 0; + case PixelFormat::RGB_888: + *outDrmFormat = DRM_FORMAT_RGB888; + return 0; + case PixelFormat::STENCIL_8: + return -EINVAL; + case PixelFormat::Y16: + *outDrmFormat = DRM_FORMAT_R16; + return 0; + case PixelFormat::Y8: + *outDrmFormat = DRM_FORMAT_R8; + return 0; + case PixelFormat::YCBCR_420_888: + *outDrmFormat = DRM_FORMAT_FLEX_YCbCr_420_888; + return 0; + case PixelFormat::YCBCR_422_SP: + return -EINVAL; + case PixelFormat::YCBCR_422_I: + return -EINVAL; + case PixelFormat::YCBCR_P010: + *outDrmFormat = DRM_FORMAT_P010; + return 0; + case PixelFormat::YCRCB_420_SP: + *outDrmFormat = DRM_FORMAT_NV21; + return 0; + case PixelFormat::YV12: + *outDrmFormat = DRM_FORMAT_YVU420_ANDROID; + return 0; + }; + return -EINVAL; +} + +int convertToBufferUsage(uint64_t grallocUsage, uint64_t* outBufferUsage) { + uint64_t bufferUsage = BO_USE_NONE; + + if ((grallocUsage & BufferUsage::CPU_READ_MASK) == + static_cast(BufferUsage::CPU_READ_RARELY)) { + bufferUsage |= BO_USE_SW_READ_RARELY; + } + if ((grallocUsage & BufferUsage::CPU_READ_MASK) == + static_cast(BufferUsage::CPU_READ_OFTEN)) { + bufferUsage |= BO_USE_SW_READ_OFTEN; + } + if ((grallocUsage & BufferUsage::CPU_WRITE_MASK) == + static_cast(BufferUsage::CPU_WRITE_RARELY)) { + bufferUsage |= BO_USE_SW_WRITE_RARELY; + } + if ((grallocUsage & BufferUsage::CPU_WRITE_MASK) == + static_cast(BufferUsage::CPU_WRITE_OFTEN)) { + bufferUsage |= BO_USE_SW_WRITE_OFTEN; + } + if (grallocUsage & BufferUsage::GPU_TEXTURE) { + bufferUsage |= BO_USE_TEXTURE; + } + if (grallocUsage & BufferUsage::GPU_RENDER_TARGET) { + bufferUsage |= BO_USE_RENDERING; + } + if (grallocUsage & BufferUsage::COMPOSER_OVERLAY) { + /* HWC wants to use display hardware, but can defer to OpenGL. */ + bufferUsage |= BO_USE_SCANOUT | BO_USE_TEXTURE; + } + if (grallocUsage & BufferUsage::PROTECTED) { + bufferUsage |= BO_USE_PROTECTED; + } + if (grallocUsage & BufferUsage::COMPOSER_CURSOR) { + bufferUsage |= BO_USE_NONE; + } + if (grallocUsage & BufferUsage::VIDEO_ENCODER) { + /*HACK: See b/30054495 */ + bufferUsage |= BO_USE_SW_READ_OFTEN; + } + if (grallocUsage & BufferUsage::CAMERA_OUTPUT) { + bufferUsage |= BO_USE_CAMERA_WRITE; + } + if (grallocUsage & BufferUsage::CAMERA_INPUT) { + bufferUsage |= BO_USE_CAMERA_READ; + } + if (grallocUsage & BufferUsage::RENDERSCRIPT) { + bufferUsage |= BO_USE_RENDERSCRIPT; + } + if (grallocUsage & BufferUsage::VIDEO_DECODER) { + bufferUsage |= BO_USE_HW_VIDEO_DECODER; + } + + *outBufferUsage = bufferUsage; + return 0; +} + +int convertToCrosDescriptor(const BufferDescriptorInfo& descriptor, + struct cros_gralloc_buffer_descriptor* outCrosDescriptor) { + outCrosDescriptor->name = descriptor.name; + outCrosDescriptor->width = descriptor.width; + outCrosDescriptor->height = descriptor.height; + outCrosDescriptor->droid_format = static_cast(descriptor.format); + outCrosDescriptor->droid_usage = descriptor.usage; + outCrosDescriptor->reserved_region_size = descriptor.reservedSize; + + if (convertToDrmFormat(descriptor.format, &outCrosDescriptor->drm_format)) { + std::string pixelFormatString = getPixelFormatString(descriptor.format); + drv_log("Failed to convert descriptor. Unsupported fomat %s\n", pixelFormatString.c_str()); + return -1; + } + if (convertToBufferUsage(descriptor.usage, &outCrosDescriptor->use_flags)) { + std::string usageString = getUsageString(descriptor.usage); + drv_log("Failed to convert descriptor. Unsupported usage flags %s\n", usageString.c_str()); + return -1; + } + return 0; +} + +int convertToMapUsage(uint64_t grallocUsage, uint32_t* outMapUsage) { + uint32_t mapUsage = BO_MAP_NONE; + + if (grallocUsage & BufferUsage::CPU_READ_MASK) { + mapUsage |= BO_MAP_READ; + } + if (grallocUsage & BufferUsage::CPU_WRITE_MASK) { + mapUsage |= BO_MAP_WRITE; + } + + *outMapUsage = mapUsage; + return 0; +} + +int convertToFenceFd(const hidl_handle& fenceHandle, int* outFenceFd) { + if (!outFenceFd) { + return -EINVAL; + } + + const native_handle_t* nativeHandle = fenceHandle.getNativeHandle(); + if (nativeHandle && nativeHandle->numFds > 1) { + return -EINVAL; + } + + *outFenceFd = (nativeHandle && nativeHandle->numFds == 1) ? nativeHandle->data[0] : -1; + return 0; +} + +int convertToFenceHandle(int fenceFd, hidl_handle* outFenceHandle) { + if (!outFenceHandle) { + return -EINVAL; + } + if (fenceFd < 0) { + return 0; + } + + NATIVE_HANDLE_DECLARE_STORAGE(handleStorage, 1, 0); + auto fenceHandle = native_handle_init(handleStorage, 1, 0); + fenceHandle->data[0] = fenceFd; + + *outFenceHandle = fenceHandle; + return 0; +} + +const std::unordered_map>& GetPlaneLayoutsMap() { + static const auto* kPlaneLayoutsMap = + new std::unordered_map>({ + {DRM_FORMAT_ABGR8888, + {{ + .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R, + .offsetInBits = 0, + .sizeInBits = 8}, + {.type = android::gralloc4::PlaneLayoutComponentType_G, + .offsetInBits = 8, + .sizeInBits = 8}, + {.type = android::gralloc4::PlaneLayoutComponentType_B, + .offsetInBits = 16, + .sizeInBits = 8}, + {.type = android::gralloc4::PlaneLayoutComponentType_A, + .offsetInBits = 24, + .sizeInBits = 8}}, + .sampleIncrementInBits = 32, + .horizontalSubsampling = 1, + .verticalSubsampling = 1, + }}}, + + {DRM_FORMAT_ABGR2101010, + {{ + .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R, + .offsetInBits = 0, + .sizeInBits = 10}, + {.type = android::gralloc4::PlaneLayoutComponentType_G, + .offsetInBits = 10, + .sizeInBits = 10}, + {.type = android::gralloc4::PlaneLayoutComponentType_B, + .offsetInBits = 20, + .sizeInBits = 10}, + {.type = android::gralloc4::PlaneLayoutComponentType_A, + .offsetInBits = 30, + .sizeInBits = 2}}, + .sampleIncrementInBits = 32, + .horizontalSubsampling = 1, + .verticalSubsampling = 1, + }}}, + + {DRM_FORMAT_ABGR16161616F, + {{ + .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R, + .offsetInBits = 0, + .sizeInBits = 16}, + {.type = android::gralloc4::PlaneLayoutComponentType_G, + .offsetInBits = 16, + .sizeInBits = 16}, + {.type = android::gralloc4::PlaneLayoutComponentType_B, + .offsetInBits = 32, + .sizeInBits = 16}, + {.type = android::gralloc4::PlaneLayoutComponentType_A, + .offsetInBits = 48, + .sizeInBits = 16}}, + .sampleIncrementInBits = 64, + .horizontalSubsampling = 1, + .verticalSubsampling = 1, + }}}, + + {DRM_FORMAT_ARGB8888, + {{ + .components = {{.type = android::gralloc4::PlaneLayoutComponentType_B, + .offsetInBits = 0, + .sizeInBits = 8}, + {.type = android::gralloc4::PlaneLayoutComponentType_G, + .offsetInBits = 8, + .sizeInBits = 8}, + {.type = android::gralloc4::PlaneLayoutComponentType_R, + .offsetInBits = 16, + .sizeInBits = 8}, + {.type = android::gralloc4::PlaneLayoutComponentType_A, + .offsetInBits = 24, + .sizeInBits = 8}}, + .sampleIncrementInBits = 32, + .horizontalSubsampling = 1, + .verticalSubsampling = 1, + }}}, + + {DRM_FORMAT_NV12, + {{ + .components = {{.type = android::gralloc4::PlaneLayoutComponentType_Y, + .offsetInBits = 0, + .sizeInBits = 8}}, + .sampleIncrementInBits = 8, + .horizontalSubsampling = 1, + .verticalSubsampling = 1, + }, + { + .components = + {{.type = android::gralloc4::PlaneLayoutComponentType_CB, + .offsetInBits = 0, + .sizeInBits = 8}, + {.type = android::gralloc4::PlaneLayoutComponentType_CR, + .offsetInBits = 8, + .sizeInBits = 8}}, + .sampleIncrementInBits = 16, + .horizontalSubsampling = 2, + .verticalSubsampling = 2, + }}}, + + {DRM_FORMAT_NV21, + {{ + .components = {{.type = android::gralloc4::PlaneLayoutComponentType_Y, + .offsetInBits = 0, + .sizeInBits = 8}}, + .sampleIncrementInBits = 8, + .horizontalSubsampling = 1, + .verticalSubsampling = 1, + }, + { + .components = + {{.type = android::gralloc4::PlaneLayoutComponentType_CR, + .offsetInBits = 0, + .sizeInBits = 8}, + {.type = android::gralloc4::PlaneLayoutComponentType_CB, + .offsetInBits = 8, + .sizeInBits = 8}}, + .sampleIncrementInBits = 16, + .horizontalSubsampling = 2, + .verticalSubsampling = 2, + }}}, + + {DRM_FORMAT_P010, + {{ + .components = {{.type = android::gralloc4::PlaneLayoutComponentType_Y, + .offsetInBits = 6, + .sizeInBits = 10}}, + .sampleIncrementInBits = 16, + .horizontalSubsampling = 1, + .verticalSubsampling = 1, + }, + { + .components = + {{.type = android::gralloc4::PlaneLayoutComponentType_CB, + .offsetInBits = 6, + .sizeInBits = 10}, + {.type = android::gralloc4::PlaneLayoutComponentType_CR, + .offsetInBits = 22, + .sizeInBits = 10}}, + .sampleIncrementInBits = 32, + .horizontalSubsampling = 2, + .verticalSubsampling = 2, + }}}, + + {DRM_FORMAT_R8, + {{ + .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R, + .offsetInBits = 0, + .sizeInBits = 8}}, + .sampleIncrementInBits = 8, + .horizontalSubsampling = 1, + .verticalSubsampling = 1, + }}}, + + {DRM_FORMAT_R16, + {{ + .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R, + .offsetInBits = 0, + .sizeInBits = 16}}, + .sampleIncrementInBits = 16, + .horizontalSubsampling = 1, + .verticalSubsampling = 1, + }}}, + + {DRM_FORMAT_RGB565, + {{ + .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R, + .offsetInBits = 0, + .sizeInBits = 5}, + {.type = android::gralloc4::PlaneLayoutComponentType_G, + .offsetInBits = 5, + .sizeInBits = 6}, + {.type = android::gralloc4::PlaneLayoutComponentType_B, + .offsetInBits = 11, + .sizeInBits = 5}}, + .sampleIncrementInBits = 16, + .horizontalSubsampling = 1, + .verticalSubsampling = 1, + }}}, + + {DRM_FORMAT_RGB888, + {{ + .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R, + .offsetInBits = 0, + .sizeInBits = 8}, + {.type = android::gralloc4::PlaneLayoutComponentType_G, + .offsetInBits = 8, + .sizeInBits = 8}, + {.type = android::gralloc4::PlaneLayoutComponentType_B, + .offsetInBits = 16, + .sizeInBits = 8}}, + .sampleIncrementInBits = 24, + .horizontalSubsampling = 1, + .verticalSubsampling = 1, + }}}, + + {DRM_FORMAT_XBGR8888, + {{ + .components = {{.type = android::gralloc4::PlaneLayoutComponentType_B, + .offsetInBits = 0, + .sizeInBits = 8}, + {.type = android::gralloc4::PlaneLayoutComponentType_G, + .offsetInBits = 8, + .sizeInBits = 8}, + {.type = android::gralloc4::PlaneLayoutComponentType_R, + .offsetInBits = 16, + .sizeInBits = 8}}, + .sampleIncrementInBits = 32, + .horizontalSubsampling = 1, + .verticalSubsampling = 1, + }}}, + + {DRM_FORMAT_YVU420, + { + { + .components = {{.type = android::gralloc4:: + PlaneLayoutComponentType_Y, + .offsetInBits = 0, + .sizeInBits = 8}}, + .sampleIncrementInBits = 8, + .horizontalSubsampling = 1, + .verticalSubsampling = 1, + }, + { + .components = {{.type = android::gralloc4:: + PlaneLayoutComponentType_CB, + .offsetInBits = 0, + .sizeInBits = 8}}, + .sampleIncrementInBits = 8, + .horizontalSubsampling = 2, + .verticalSubsampling = 2, + }, + { + .components = {{.type = android::gralloc4:: + PlaneLayoutComponentType_CR, + .offsetInBits = 0, + .sizeInBits = 8}}, + .sampleIncrementInBits = 8, + .horizontalSubsampling = 2, + .verticalSubsampling = 2, + }, + }}, + + {DRM_FORMAT_YVU420_ANDROID, + { + { + .components = {{.type = android::gralloc4:: + PlaneLayoutComponentType_Y, + .offsetInBits = 0, + .sizeInBits = 8}}, + .sampleIncrementInBits = 8, + .horizontalSubsampling = 1, + .verticalSubsampling = 1, + }, + { + .components = {{.type = android::gralloc4:: + PlaneLayoutComponentType_CR, + .offsetInBits = 0, + .sizeInBits = 8}}, + .sampleIncrementInBits = 8, + .horizontalSubsampling = 2, + .verticalSubsampling = 2, + }, + { + .components = {{.type = android::gralloc4:: + PlaneLayoutComponentType_CB, + .offsetInBits = 0, + .sizeInBits = 8}}, + .sampleIncrementInBits = 8, + .horizontalSubsampling = 2, + .verticalSubsampling = 2, + }, + }}, + }); + return *kPlaneLayoutsMap; +} + +int getPlaneLayouts(uint32_t drmFormat, std::vector* outPlaneLayouts) { + const auto& planeLayoutsMap = GetPlaneLayoutsMap(); + const auto it = planeLayoutsMap.find(drmFormat); + if (it == planeLayoutsMap.end()) { + drv_log("Unknown plane layout for format %d\n", drmFormat); + return -1; + } + + *outPlaneLayouts = it->second; + return 0; +} \ No newline at end of file diff --git a/cros_gralloc/gralloc4/CrosGralloc4Utils.h b/cros_gralloc/gralloc4/CrosGralloc4Utils.h new file mode 100644 index 0000000..094ef74 --- /dev/null +++ b/cros_gralloc/gralloc4/CrosGralloc4Utils.h @@ -0,0 +1,41 @@ +/* + * Copyright 2020 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 +#include + +#include +#include +#include + +#include "cros_gralloc/cros_gralloc_types.h" + +std::string getDrmFormatString(uint32_t drmFormat); + +std::string getPixelFormatString(android::hardware::graphics::common::V1_2::PixelFormat format); + +std::string getUsageString( + android::hardware::hidl_bitfield + usage); + +int convertToDrmFormat(android::hardware::graphics::common::V1_2::PixelFormat format, + uint32_t* outDrmFormat); + +int convertToBufferUsage(uint64_t grallocUsage, uint64_t* outBufferUsage); + +int convertToCrosDescriptor( + const android::hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo& descriptor, + struct cros_gralloc_buffer_descriptor* outCrosDescriptor); + +int convertToMapUsage(uint64_t grallocUsage, uint32_t* outMapUsage); + +int convertToFenceFd(const android::hardware::hidl_handle& fence_handle, int* out_fence_fd); + +int convertToFenceHandle(int fence_fd, android::hardware::hidl_handle* out_fence_handle); + +int getPlaneLayouts( + uint32_t drm_format, + std::vector* out_layouts); \ No newline at end of file diff --git a/cros_gralloc/gralloc4/android.hardware.graphics.allocator@4.0-service.minigbm.rc b/cros_gralloc/gralloc4/android.hardware.graphics.allocator@4.0-service.minigbm.rc new file mode 100644 index 0000000..a96a6e1 --- /dev/null +++ b/cros_gralloc/gralloc4/android.hardware.graphics.allocator@4.0-service.minigbm.rc @@ -0,0 +1,24 @@ +# +# Copyright 2020 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +service vendor.graphics.allocator-4-0 /vendor/bin/hw/android.hardware.graphics.allocator@4.0-service.minigbm + interface android.hardware.graphics.allocator@4.0::IAllocator default + class hal animation + user system + group graphics drmrpc + capabilities SYS_NICE + onrestart restart surfaceflinger + writepid /dev/cpuset/system-background/tasks diff --git a/drv.c b/drv.c index 920cf4d..636cd07 100644 --- a/drv.c +++ b/drv.c @@ -117,7 +117,7 @@ static const struct backend *drv_get_backend(int fd) #ifdef DRV_VC4 &backend_vc4, #endif - &backend_vgem, &backend_virtio_gpu, + &backend_vgem, &backend_virtio_gpu, }; for (i = 0; i < ARRAY_SIZE(backend_list); i++) { @@ -558,6 +558,21 @@ int drv_bo_invalidate(struct bo *bo, struct mapping *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); + + if (bo->drv->backend->bo_flush) + ret = bo->drv->backend->bo_flush(bo, mapping); + + return ret; +} + int drv_bo_flush_or_unmap(struct bo *bo, struct mapping *mapping) { int ret = 0; @@ -648,6 +663,11 @@ uint32_t drv_bo_get_format(struct bo *bo) return bo->meta.format; } +size_t drv_bo_get_total_size(struct bo *bo) +{ + return bo->meta.total_size; +} + uint32_t drv_resolve_format(struct driver *drv, uint32_t format, uint64_t use_flags) { if (drv->backend->resolve_format) diff --git a/drv.h b/drv.h index 2b86aad..f19f9de 100644 --- a/drv.h +++ b/drv.h @@ -145,6 +145,8 @@ int drv_bo_unmap(struct bo *bo, struct mapping *mapping); int drv_bo_invalidate(struct bo *bo, struct mapping *mapping); +int drv_bo_flush(struct bo *bo, struct mapping *mapping); + int drv_bo_flush_or_unmap(struct bo *bo, struct mapping *mapping); uint32_t drv_bo_get_width(struct bo *bo); diff --git a/helpers.c b/helpers.c index fed4af9..17b1765 100644 --- a/helpers.c +++ b/helpers.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include #include "drv_priv.h" @@ -92,6 +94,9 @@ static const struct planar_layout *layout_from_format(uint32_t format) case DRM_FORMAT_RGB332: return &packed_1bpp_layout; + case DRM_FORMAT_R16: + return &packed_2bpp_layout; + case DRM_FORMAT_YVU420: case DRM_FORMAT_YVU420_ANDROID: return &triplanar_yuv_420_layout; @@ -312,6 +317,11 @@ int drv_dumb_bo_create_ex(struct bo *bo, uint32_t width, uint32_t height, uint32 aligned_width = width; aligned_height = height; switch (format) { + case DRM_FORMAT_R16: + /* HAL_PIXEL_FORMAT_Y16 requires that the buffer's width be 16 pixel + * aligned. See hardware/interfaces/graphics/common/1.0/types.hal. */ + aligned_width = ALIGN(width, 16); + break; case DRM_FORMAT_YVU420_ANDROID: /* HAL_PIXEL_FORMAT_YV12 requires that the buffer's height not * be aligned. Update 'height' so that drv_bo_from_format below @@ -327,6 +337,7 @@ int drv_dumb_bo_create_ex(struct bo *bo, uint32_t width, uint32_t height, uint32 break; case DRM_FORMAT_YVU420: case DRM_FORMAT_NV12: + case DRM_FORMAT_NV21: /* Adjust the height to include room for chroma planes */ aligned_height = 3 * DIV_ROUND_UP(height, 2); break; diff --git a/virgl_hw.h b/virgl_hw.h index 145780b..1c493d1 100644 --- a/virgl_hw.h +++ b/virgl_hw.h @@ -69,7 +69,7 @@ enum virgl_formats { VIRGL_FORMAT_R8_UNORM = 64, VIRGL_FORMAT_R8G8_UNORM = 65, - + VIRGL_FORMAT_R8G8B8_UNORM = 66, VIRGL_FORMAT_R8G8B8A8_UNORM = 67, VIRGL_FORMAT_R8_SNORM = 74, diff --git a/virtio_gpu.c b/virtio_gpu.c index 4dbcc4f..83d46d3 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -4,6 +4,7 @@ * found in the LICENSE file. */ +#include #include #include #include @@ -50,21 +51,27 @@ static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMA DRM_FORMAT_RGB565, DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888 }; -static const uint32_t dumb_texture_source_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_YVU420, - DRM_FORMAT_NV12, - DRM_FORMAT_YVU420_ANDROID }; +static const uint32_t dumb_texture_source_formats[] = { + DRM_FORMAT_R8, DRM_FORMAT_R16, DRM_FORMAT_YVU420, + DRM_FORMAT_NV12, DRM_FORMAT_NV21, DRM_FORMAT_YVU420_ANDROID +}; -static const uint32_t texture_source_formats[] = { DRM_FORMAT_NV12, DRM_FORMAT_R8, DRM_FORMAT_RG88, - DRM_FORMAT_YVU420_ANDROID }; +static const uint32_t texture_source_formats[] = { DRM_FORMAT_NV12, DRM_FORMAT_NV21, + DRM_FORMAT_R8, DRM_FORMAT_R16, + DRM_FORMAT_RG88, DRM_FORMAT_YVU420_ANDROID }; struct virtio_gpu_priv { int caps_is_v2; union virgl_caps caps; + int host_gbm_enabled; }; static uint32_t translate_format(uint32_t drm_fourcc) { switch (drm_fourcc) { + case DRM_FORMAT_BGR888: + case DRM_FORMAT_RGB888: + return VIRGL_FORMAT_R8G8B8_UNORM; case DRM_FORMAT_XRGB8888: return VIRGL_FORMAT_B8G8R8X8_UNORM; case DRM_FORMAT_ARGB8888: @@ -73,6 +80,8 @@ static uint32_t translate_format(uint32_t drm_fourcc) return VIRGL_FORMAT_R8G8B8X8_UNORM; case DRM_FORMAT_ABGR8888: return VIRGL_FORMAT_R8G8B8A8_UNORM; + case DRM_FORMAT_ABGR16161616F: + return VIRGL_FORMAT_R16G16B16A16_UNORM; case DRM_FORMAT_RGB565: return VIRGL_FORMAT_B5G6R5_UNORM; case DRM_FORMAT_R8: @@ -81,6 +90,8 @@ static uint32_t translate_format(uint32_t drm_fourcc) return VIRGL_FORMAT_R8G8_UNORM; case DRM_FORMAT_NV12: return VIRGL_FORMAT_NV12; + case DRM_FORMAT_NV21: + return VIRGL_FORMAT_NV21; case DRM_FORMAT_YVU420: case DRM_FORMAT_YVU420_ANDROID: return VIRGL_FORMAT_YV12; @@ -89,8 +100,8 @@ static uint32_t translate_format(uint32_t drm_fourcc) } } -static bool virtio_gpu_supports_format(struct virgl_supported_format_mask *supported, - uint32_t drm_format) +static bool virtio_gpu_bitmask_supports_format(struct virgl_supported_format_mask *supported, + uint32_t drm_format) { uint32_t virgl_format = translate_format(drm_format); if (!virgl_format) { @@ -102,6 +113,243 @@ static bool virtio_gpu_supports_format(struct virgl_supported_format_mask *suppo return supported->bitmask[bitmask_index] & (1 << bit_index); } +// The metadata generated here for emulated buffers is slightly different than the metadata +// generated by drv_bo_from_format. In order to simplify transfers in the flush and invalidate +// functions below, the emulated buffers are oversized. For example, ignoring stride alignment +// requirements to demonstrate, a 6x6 YUV420 image buffer might have the following layout from +// drv_bo_from_format: +// +// | Y | Y | Y | Y | Y | Y | +// | Y | Y | Y | Y | Y | Y | +// | Y | Y | Y | Y | Y | Y | +// | Y | Y | Y | Y | Y | Y | +// | Y | Y | Y | Y | Y | Y | +// | Y | Y | Y | Y | Y | Y | +// | U | U | U | U | U | U | +// | U | U | U | V | V | V | +// | V | V | V | V | V | V | +// +// where each plane immediately follows the previous plane in memory. This layout makes it +// difficult to compute the transfers needed for example when the middle 2x2 region of the +// image is locked and needs to be flushed/invalidated. +// +// Emulated multi-plane buffers instead have a layout of: +// +// | Y | Y | Y | Y | Y | Y | +// | Y | Y | Y | Y | Y | Y | +// | Y | Y | Y | Y | Y | Y | +// | Y | Y | Y | Y | Y | Y | +// | Y | Y | Y | Y | Y | Y | +// | Y | Y | Y | Y | Y | Y | +// | U | U | U | | | | +// | U | U | U | | | | +// | U | U | U | | | | +// | V | V | V | | | | +// | V | V | V | | | | +// | V | V | V | | | | +// +// where each plane is placed as a sub-image (albeit with a very large stride) in order to +// simplify transfers into 3 sub-image transfers for the above example. +// +// Additional note: the V-plane is not placed to the right of the U-plane due to some +// observed failures in media framework code which assumes the V-plane is not +// "row-interlaced" with the U-plane. +static void virtio_gpu_get_emulated_metadata(const struct bo *bo, struct bo_metadata *metadata) +{ + uint32_t y_plane_height; + uint32_t c_plane_height; + uint32_t original_width = bo->meta.width; + uint32_t original_height = bo->meta.height; + + metadata->format = DRM_FORMAT_R8; + switch (bo->meta.format) { + case DRM_FORMAT_NV12: + case DRM_FORMAT_NV21: + // Bi-planar + metadata->num_planes = 2; + + y_plane_height = original_height; + c_plane_height = DIV_ROUND_UP(original_height, 2); + + metadata->width = original_width; + metadata->height = y_plane_height + c_plane_height; + + // Y-plane (full resolution) + metadata->strides[0] = metadata->width; + metadata->offsets[0] = 0; + metadata->sizes[0] = metadata->width * y_plane_height; + + // CbCr-plane (half resolution, interleaved, placed below Y-plane) + metadata->strides[1] = metadata->width; + metadata->offsets[1] = metadata->offsets[0] + metadata->sizes[0]; + metadata->sizes[1] = metadata->width * c_plane_height; + + metadata->total_size = metadata->width * metadata->height; + break; + case DRM_FORMAT_YVU420: + case DRM_FORMAT_YVU420_ANDROID: + // Tri-planar + metadata->num_planes = 3; + + y_plane_height = original_height; + c_plane_height = DIV_ROUND_UP(original_height, 2); + + metadata->width = ALIGN(original_width, 32); + metadata->height = y_plane_height + (2 * c_plane_height); + + // Y-plane (full resolution) + metadata->strides[0] = metadata->width; + metadata->offsets[0] = 0; + metadata->sizes[0] = metadata->width * original_height; + + // Cb-plane (half resolution, placed below Y-plane) + metadata->strides[1] = metadata->width; + metadata->offsets[1] = metadata->offsets[0] + metadata->sizes[0]; + metadata->sizes[1] = metadata->width * c_plane_height; + + // Cr-plane (half resolution, placed below Cb-plane) + metadata->strides[2] = metadata->width; + metadata->offsets[2] = metadata->offsets[1] + metadata->sizes[1]; + metadata->sizes[2] = metadata->width * c_plane_height; + + metadata->total_size = metadata->width * metadata->height; + break; + default: + break; + } +} + +struct virtio_transfers_params { + size_t xfers_needed; + struct rectangle xfer_boxes[DRV_MAX_PLANES]; +}; + +static void virtio_gpu_get_emulated_transfers_params(const struct bo *bo, + const struct rectangle *transfer_box, + struct virtio_transfers_params *xfer_params) +{ + uint32_t y_plane_height; + uint32_t c_plane_height; + struct bo_metadata emulated_metadata; + + if (transfer_box->x == 0 && transfer_box->y == 0 && transfer_box->width == bo->meta.width && + transfer_box->height == bo->meta.height) { + virtio_gpu_get_emulated_metadata(bo, &emulated_metadata); + + xfer_params->xfers_needed = 1; + xfer_params->xfer_boxes[0].x = 0; + xfer_params->xfer_boxes[0].y = 0; + xfer_params->xfer_boxes[0].width = emulated_metadata.width; + xfer_params->xfer_boxes[0].height = emulated_metadata.height; + + return; + } + + switch (bo->meta.format) { + case DRM_FORMAT_NV12: + case DRM_FORMAT_NV21: + // Bi-planar + xfer_params->xfers_needed = 2; + + y_plane_height = bo->meta.height; + c_plane_height = DIV_ROUND_UP(bo->meta.height, 2); + + // Y-plane (full resolution) + xfer_params->xfer_boxes[0].x = transfer_box->x; + xfer_params->xfer_boxes[0].y = transfer_box->y; + xfer_params->xfer_boxes[0].width = transfer_box->width; + xfer_params->xfer_boxes[0].height = transfer_box->height; + + // CbCr-plane (half resolution, interleaved, placed below Y-plane) + xfer_params->xfer_boxes[1].x = transfer_box->x; + xfer_params->xfer_boxes[1].y = transfer_box->y + y_plane_height; + xfer_params->xfer_boxes[1].width = transfer_box->width; + xfer_params->xfer_boxes[1].height = DIV_ROUND_UP(transfer_box->height, 2); + + break; + case DRM_FORMAT_YVU420: + case DRM_FORMAT_YVU420_ANDROID: + // Tri-planar + xfer_params->xfers_needed = 3; + + y_plane_height = bo->meta.height; + c_plane_height = DIV_ROUND_UP(bo->meta.height, 2); + + // Y-plane (full resolution) + xfer_params->xfer_boxes[0].x = transfer_box->x; + xfer_params->xfer_boxes[0].y = transfer_box->y; + xfer_params->xfer_boxes[0].width = transfer_box->width; + xfer_params->xfer_boxes[0].height = transfer_box->height; + + // Cb-plane (half resolution, placed below Y-plane) + xfer_params->xfer_boxes[1].x = transfer_box->x; + xfer_params->xfer_boxes[1].y = transfer_box->y + y_plane_height; + xfer_params->xfer_boxes[1].width = DIV_ROUND_UP(transfer_box->width, 2); + xfer_params->xfer_boxes[1].height = DIV_ROUND_UP(transfer_box->height, 2); + + // Cr-plane (half resolution, placed below Cb-plane) + xfer_params->xfer_boxes[2].x = transfer_box->x; + xfer_params->xfer_boxes[2].y = transfer_box->y + y_plane_height + c_plane_height; + xfer_params->xfer_boxes[2].width = DIV_ROUND_UP(transfer_box->width, 2); + xfer_params->xfer_boxes[2].height = DIV_ROUND_UP(transfer_box->height, 2); + + break; + } +} + +static bool virtio_gpu_supports_combination_natively(struct driver *drv, uint32_t drm_format, + uint64_t use_flags) +{ + struct virtio_gpu_priv *priv = (struct virtio_gpu_priv *)drv->priv; + + if (priv->caps.max_version == 0) { + return true; + } + + if ((use_flags & BO_USE_RENDERING) && + !virtio_gpu_bitmask_supports_format(&priv->caps.v1.render, drm_format)) { + return false; + } + + if ((use_flags & BO_USE_TEXTURE) && + !virtio_gpu_bitmask_supports_format(&priv->caps.v1.sampler, drm_format)) { + return false; + } + + if ((use_flags & BO_USE_SCANOUT) && priv->caps_is_v2 && + !virtio_gpu_bitmask_supports_format(&priv->caps.v2.scanout, drm_format)) { + return false; + } + + return true; +} + +// For virtio backends that do not support formats natively (e.g. multi-planar formats are not +// supported in virglrenderer when gbm is unavailable on the host machine), whether or not the +// format and usage combination can be handled as a blob (byte buffer). +static bool virtio_gpu_supports_combination_through_emulation(struct driver *drv, + uint32_t drm_format, + uint64_t use_flags) +{ + struct virtio_gpu_priv *priv = (struct virtio_gpu_priv *)drv->priv; + + // Only enable emulation on non-gbm virtio backends. + if (priv->host_gbm_enabled) { + return false; + } + + if (use_flags & (BO_USE_RENDERING | BO_USE_SCANOUT)) { + return false; + } + + if (!virtio_gpu_supports_combination_natively(drv, DRM_FORMAT_R8, use_flags)) { + return false; + } + + return drm_format == DRM_FORMAT_NV12 || drm_format == DRM_FORMAT_NV21 || + drm_format == DRM_FORMAT_YVU420 || drm_format == DRM_FORMAT_YVU420_ANDROID; +} + // Adds the given buffer combination to the list of supported buffer combinations if the // combination is supported by the virtio backend. static void virtio_gpu_add_combination(struct driver *drv, uint32_t drm_format, @@ -110,22 +358,18 @@ static void virtio_gpu_add_combination(struct driver *drv, uint32_t drm_format, struct virtio_gpu_priv *priv = (struct virtio_gpu_priv *)drv->priv; if (features[feat_3d].enabled && priv->caps.max_version >= 1) { - if ((use_flags & BO_USE_RENDERING) && - !virtio_gpu_supports_format(&priv->caps.v1.render, drm_format)) { - drv_log("Skipping unsupported render format: %d\n", drm_format); - return; + if ((use_flags & BO_USE_SCANOUT) && priv->caps_is_v2 && + !virtio_gpu_supports_combination_natively(drv, drm_format, use_flags)) { + drv_log("Scanout format: %d\n", drm_format); + use_flags &= ~BO_USE_SCANOUT; } - if ((use_flags & BO_USE_TEXTURE) && - !virtio_gpu_supports_format(&priv->caps.v1.sampler, drm_format)) { - drv_log("Skipping unsupported texture format: %d\n", drm_format); + if (!virtio_gpu_supports_combination_natively(drv, drm_format, use_flags) && + !virtio_gpu_supports_combination_through_emulation(drv, drm_format, + use_flags)) { + drv_log("Skipping unsupported combination format:%d\n", drm_format); return; } - if ((use_flags & BO_USE_SCANOUT) && priv->caps_is_v2 && - !virtio_gpu_supports_format(&priv->caps.v2.scanout, drm_format)) { - drv_log("Unsupported scanout format: %d\n", drm_format); - use_flags &= ~BO_USE_SCANOUT; - } } drv_add_combination(drv, drm_format, metadata, use_flags); @@ -196,11 +440,30 @@ static int virtio_virgl_bo_create(struct bo *bo, uint32_t width, uint32_t height uint64_t use_flags) { int ret; + size_t i; uint32_t stride; struct drm_virtgpu_resource_create res_create; + struct bo_metadata emulated_metadata; - stride = drv_stride_from_format(format, width, 0); - drv_bo_from_format(bo, stride, height, format); + if (virtio_gpu_supports_combination_natively(bo->drv, format, use_flags)) { + stride = drv_stride_from_format(format, width, 0); + drv_bo_from_format(bo, stride, height, format); + } else { + assert( + virtio_gpu_supports_combination_through_emulation(bo->drv, format, use_flags)); + + virtio_gpu_get_emulated_metadata(bo, &emulated_metadata); + + format = emulated_metadata.format; + width = emulated_metadata.width; + height = emulated_metadata.height; + for (i = 0; i < emulated_metadata.num_planes; i++) { + bo->meta.strides[i] = emulated_metadata.strides[i]; + bo->meta.offsets[i] = emulated_metadata.offsets[i]; + bo->meta.sizes[i] = emulated_metadata.sizes[i]; + } + bo->meta.total_size = emulated_metadata.total_size; + } /* * Setting the target is intended to ensure this resource gets bound as a 2D @@ -290,26 +553,39 @@ static int virtio_gpu_get_caps(struct driver *drv, union virgl_caps *caps, int * return ret; } -static int virtio_gpu_init(struct driver *drv) +static void virtio_gpu_init_features_and_caps(struct driver *drv) { - int ret; - struct virtio_gpu_priv *priv; + struct virtio_gpu_priv *priv = (struct virtio_gpu_priv *)drv->priv; - priv = calloc(1, sizeof(*priv)); - drv->priv = priv; for (uint32_t i = 0; i < ARRAY_SIZE(features); i++) { struct drm_virtgpu_getparam params = { 0 }; params.param = features[i].feature; params.value = (uint64_t)(uintptr_t)&features[i].enabled; - ret = drmIoctl(drv->fd, DRM_IOCTL_VIRTGPU_GETPARAM, ¶ms); + int ret = drmIoctl(drv->fd, DRM_IOCTL_VIRTGPU_GETPARAM, ¶ms); if (ret) drv_log("DRM_IOCTL_VIRTGPU_GET_PARAM failed with %s\n", strerror(errno)); } if (features[feat_3d].enabled) { virtio_gpu_get_caps(drv, &priv->caps, &priv->caps_is_v2); + } + // Multi-planar formats are currently only supported in virglrenderer through gbm. + priv->host_gbm_enabled = + virtio_gpu_supports_combination_natively(drv, DRM_FORMAT_NV12, BO_USE_TEXTURE); +} + +static int virtio_gpu_init(struct driver *drv) +{ + struct virtio_gpu_priv *priv; + + priv = calloc(1, sizeof(*priv)); + drv->priv = priv; + + virtio_gpu_init_features_and_caps(drv); + + if (features[feat_3d].enabled) { /* This doesn't mean host can scanout everything, it just means host * hypervisor can show it. */ virtio_gpu_add_combinations(drv, render_target_formats, @@ -336,16 +612,29 @@ static int virtio_gpu_init(struct driver *drv) &LINEAR_METADATA, BO_USE_TEXTURE_MASK); virtio_gpu_add_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA, BO_USE_SW_MASK | BO_USE_LINEAR); + virtio_gpu_add_combination(drv, DRM_FORMAT_NV21, &LINEAR_METADATA, + BO_USE_SW_MASK | BO_USE_LINEAR); } /* Android CTS tests require this. */ + virtio_gpu_add_combination(drv, DRM_FORMAT_RGB888, &LINEAR_METADATA, BO_USE_SW_MASK); virtio_gpu_add_combination(drv, DRM_FORMAT_BGR888, &LINEAR_METADATA, BO_USE_SW_MASK); + virtio_gpu_add_combination(drv, DRM_FORMAT_ABGR16161616F, &LINEAR_METADATA, + BO_USE_SW_MASK | BO_USE_TEXTURE_MASK); drv_modify_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA, BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER | BO_USE_HW_VIDEO_ENCODER); + drv_modify_combination(drv, DRM_FORMAT_NV21, &LINEAR_METADATA, + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER | + BO_USE_HW_VIDEO_ENCODER); + drv_modify_combination(drv, DRM_FORMAT_YVU420, &LINEAR_METADATA, + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER | + BO_USE_HW_VIDEO_ENCODER | BO_USE_RENDERSCRIPT); drv_modify_combination(drv, DRM_FORMAT_R8, &LINEAR_METADATA, BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER); + drv_modify_combination(drv, DRM_FORMAT_R16, &LINEAR_METADATA, + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER); return drv_modify_linear_combinations(drv); } @@ -384,8 +673,11 @@ static void *virtio_gpu_bo_map(struct bo *bo, struct vma *vma, size_t plane, uin static int virtio_gpu_bo_invalidate(struct bo *bo, struct mapping *mapping) { int ret; + size_t i; struct drm_virtgpu_3d_transfer_from_host xfer; struct drm_virtgpu_3d_wait waitcmd; + struct virtio_transfers_params xfer_params; + struct virtio_gpu_priv *priv = (struct virtio_gpu_priv *)bo->drv->priv; if (!features[feat_3d].enabled) return 0; @@ -397,27 +689,44 @@ static int virtio_gpu_bo_invalidate(struct bo *bo, struct mapping *mapping) 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; if ((bo->meta.use_flags & BO_USE_RENDERING) == 0) { - // Unfortunately, the kernel doesn't actually pass the guest layer_stride and - // guest stride to the host (compare virtio_gpu.h and virtgpu_drm.h). For gbm - // based resources, we can work around this by using the level field to pass - // the stride to virglrenderer's gbm transfer code. However, we need to avoid - // doing this for resources which don't rely on that transfer code, which is - // resources with the BO_USE_RENDERING flag set. + // Unfortunately, the kernel doesn't actually pass the guest layer_stride + // and guest stride to the host (compare virtio_gpu.h and virtgpu_drm.h). + // For gbm based resources, we can work around this by using the level field + // to pass the stride to virglrenderer's gbm transfer code. However, we need + // to avoid doing this for resources which don't rely on that transfer code, + // which is resources with the BO_USE_RENDERING flag set. // TODO(b/145993887): Send also stride when the patches are landed - xfer.level = bo->meta.strides[0]; + if (priv->host_gbm_enabled) { + xfer.level = bo->meta.strides[0]; + } } - ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST, &xfer); - if (ret) { - drv_log("DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST failed with %s\n", strerror(errno)); - return -errno; + if (virtio_gpu_supports_combination_natively(bo->drv, bo->meta.format, + bo->meta.use_flags)) { + xfer_params.xfers_needed = 1; + xfer_params.xfer_boxes[0] = mapping->rect; + } else { + assert(virtio_gpu_supports_combination_through_emulation(bo->drv, bo->meta.format, + bo->meta.use_flags)); + + virtio_gpu_get_emulated_transfers_params(bo, &mapping->rect, &xfer_params); + } + + for (i = 0; i < xfer_params.xfers_needed; i++) { + xfer.box.x = xfer_params.xfer_boxes[i].x; + xfer.box.y = xfer_params.xfer_boxes[i].y; + xfer.box.w = xfer_params.xfer_boxes[i].width; + xfer.box.h = xfer_params.xfer_boxes[i].height; + xfer.box.d = 1; + + ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST, &xfer); + if (ret) { + drv_log("DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST failed with %s\n", + strerror(errno)); + return -errno; + } } // The transfer needs to complete before invalidate returns so that any host changes @@ -437,8 +746,11 @@ static int virtio_gpu_bo_invalidate(struct bo *bo, struct mapping *mapping) static int virtio_gpu_bo_flush(struct bo *bo, struct mapping *mapping) { int ret; + size_t i; struct drm_virtgpu_3d_transfer_to_host xfer; struct drm_virtgpu_3d_wait waitcmd; + struct virtio_transfers_params xfer_params; + struct virtio_gpu_priv *priv = (struct virtio_gpu_priv *)bo->drv->priv; if (!features[feat_3d].enabled) return 0; @@ -448,21 +760,38 @@ static int virtio_gpu_bo_flush(struct bo *bo, struct mapping *mapping) 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; // Unfortunately, the kernel doesn't actually pass the guest layer_stride and // guest stride to the host (compare virtio_gpu.h and virtgpu_drm.h). We can use // the level to work around this. - xfer.level = bo->meta.strides[0]; + if (priv->host_gbm_enabled) { + xfer.level = bo->meta.strides[0]; + } - ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_TRANSFER_TO_HOST, &xfer); - if (ret) { - drv_log("DRM_IOCTL_VIRTGPU_TRANSFER_TO_HOST failed with %s\n", strerror(errno)); - return -errno; + if (virtio_gpu_supports_combination_natively(bo->drv, bo->meta.format, + bo->meta.use_flags)) { + xfer_params.xfers_needed = 1; + xfer_params.xfer_boxes[0] = mapping->rect; + } else { + assert(virtio_gpu_supports_combination_through_emulation(bo->drv, bo->meta.format, + bo->meta.use_flags)); + + virtio_gpu_get_emulated_transfers_params(bo, &mapping->rect, &xfer_params); + } + + for (i = 0; i < xfer_params.xfers_needed; i++) { + xfer.box.x = xfer_params.xfer_boxes[i].x; + xfer.box.y = xfer_params.xfer_boxes[i].y; + xfer.box.w = xfer_params.xfer_boxes[i].width; + xfer.box.h = xfer_params.xfer_boxes[i].height; + xfer.box.d = 1; + + ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VIRTGPU_TRANSFER_TO_HOST, &xfer); + if (ret) { + drv_log("DRM_IOCTL_VIRTGPU_TRANSFER_TO_HOST failed with %s\n", + strerror(errno)); + return -errno; + } } // If the buffer is only accessed by the host GPU, then the flush is ordered @@ -485,7 +814,6 @@ static int virtio_gpu_bo_flush(struct bo *bo, struct mapping *mapping) static uint32_t virtio_gpu_resolve_format(struct driver *drv, uint32_t format, uint64_t use_flags) { - switch (format) { case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED: /* Camera subsystem requires NV12. */ From 06d77b4e7d0b75cc894117ecb63859a2b69c10b5 Mon Sep 17 00:00:00 2001 From: Jason Macnak Date: Wed, 10 Jun 2020 22:39:06 -0700 Subject: [PATCH 231/269] gralloc: Use YVU420_ANDROID for YCbCr flex ... to fix camera preview. Bug: b/146515640 Bug: b/158703419 Test: manually open default camera app Test: manually open TestingCamera app Change-Id: Ice550649c5fa125cc09394bd17ad8a5f9c4ed2fa --- virtio_gpu.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/virtio_gpu.c b/virtio_gpu.c index 83d46d3..ed67693 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -631,6 +631,9 @@ static int virtio_gpu_init(struct driver *drv) drv_modify_combination(drv, DRM_FORMAT_YVU420, &LINEAR_METADATA, BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER | BO_USE_HW_VIDEO_ENCODER | BO_USE_RENDERSCRIPT); + drv_modify_combination(drv, DRM_FORMAT_YVU420_ANDROID, &LINEAR_METADATA, + BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER | + BO_USE_HW_VIDEO_ENCODER | BO_USE_RENDERSCRIPT); drv_modify_combination(drv, DRM_FORMAT_R8, &LINEAR_METADATA, BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER); drv_modify_combination(drv, DRM_FORMAT_R16, &LINEAR_METADATA, @@ -829,7 +832,7 @@ static uint32_t virtio_gpu_resolve_format(struct driver *drv, uint32_t format, u if (features[feat_3d].enabled) return DRM_FORMAT_NV12; else - return DRM_FORMAT_YVU420; + return DRM_FORMAT_YVU420_ANDROID; default: return format; } From 5be4e4abfd4671baec60e218c4002583e7628d30 Mon Sep 17 00:00:00 2001 From: renchenglei Date: Thu, 10 Dec 2020 03:14:18 +0800 Subject: [PATCH 232/269] INTERNAL: Rename *.so name in Android.bp We have to copy of minigbm in Android code, this helps to fix "redefine" issues --- Android.bp | 61 ++++++++++++++++++++++++-------- cros_gralloc/gralloc4/Android.bp | 4 +-- 2 files changed, 49 insertions(+), 16 deletions(-) diff --git a/Android.bp b/Android.bp index 02e8e5d..1ba475c 100644 --- a/Android.bp +++ b/Android.bp @@ -2,7 +2,7 @@ // found in the LICENSE file. cc_defaults { - name: "minigbm_defaults", + name: "minigbm_defaults_celadon", srcs: [ "amdgpu.c", @@ -68,9 +68,9 @@ cc_defaults { } cc_defaults { - name: "minigbm_cros_gralloc_defaults", + name: "minigbm_cros_gralloc_defaults_celadon", - defaults: ["minigbm_defaults"], + defaults: ["minigbm_defaults_celadon"], srcs: [ "cros_gralloc/cros_gralloc_buffer.cc", @@ -80,8 +80,8 @@ cc_defaults { } cc_library_static { - name: "libminigbm", - defaults: ["minigbm_defaults"], + name: "libminigbm_celadon", + defaults: ["minigbm_defaults_celadon"], shared_libs: ["liblog"], static_libs: ["libdrm"], @@ -94,8 +94,8 @@ cc_library_static { } cc_library_static { - name: "libminigbm_cros_gralloc", - defaults: ["minigbm_cros_gralloc_defaults"], + name: "libminigbm_cros_gralloc_celadon", + defaults: ["minigbm_cros_gralloc_defaults_celadon"], shared_libs: ["liblog"], static_libs: ["libdrm"], @@ -103,14 +103,15 @@ cc_library_static { } cc_library_shared { - name: "gralloc.minigbm", - defaults: ["minigbm_cros_gralloc_defaults"], + name: "gralloc.minigbm_celadon", + defaults: ["minigbm_cros_gralloc_defaults_celadon"], + enabled: false, srcs: ["cros_gralloc/gralloc0/gralloc0.cc"], } cc_library_shared { - name: "gralloc.minigbm_intel", - defaults: ["minigbm_cros_gralloc_defaults"], + name: "gralloc.minigbm_intel_celadon", + defaults: ["minigbm_cros_gralloc_defaults_celadon"], enabled: false, arch: { x86: { @@ -125,8 +126,40 @@ cc_library_shared { } cc_library_shared { - name: "gralloc.minigbm_meson", - defaults: ["minigbm_cros_gralloc_defaults"], + name: "gralloc.intel", + defaults: ["minigbm_cros_gralloc_defaults_celadon"], + arch: { + x86: { + enabled: true, + }, + x86_64: { + enabled: true, + }, + }, + cflags: ["-DDRV_I915"], + relative_install_path: "hw", + srcs: ["cros_gralloc/gralloc0/gralloc0.cc"], +} + +cc_library_shared { + name: "gralloc.celadon", + defaults: ["minigbm_cros_gralloc_defaults_celadon"], + arch: { + x86: { + enabled: true, + }, + x86_64: { + enabled: true, + }, + }, + cflags: ["-DDRV_I915"], + relative_install_path: "hw", + srcs: ["cros_gralloc/gralloc0/gralloc0.cc"], +} + +cc_library_shared { + name: "gralloc.minigbm_meson_celadon", + defaults: ["minigbm_cros_gralloc_defaults_celadon"], cflags: ["-DDRV_MESON"], srcs: ["cros_gralloc/gralloc0/gralloc0.cc"], -} \ No newline at end of file +} diff --git a/cros_gralloc/gralloc4/Android.bp b/cros_gralloc/gralloc4/Android.bp index a0a8622..50075b9 100644 --- a/cros_gralloc/gralloc4/Android.bp +++ b/cros_gralloc/gralloc4/Android.bp @@ -39,7 +39,7 @@ cc_binary { static_libs: [ "libdrm", - "libminigbm_cros_gralloc", + "libminigbm_cros_gralloc_celadon", ], srcs: [ @@ -72,7 +72,7 @@ cc_library_shared { static_libs: [ "libdrm", - "libminigbm_cros_gralloc", + "libminigbm_cros_gralloc_celadon", ], srcs: [ From e598e066c27a4365cfa1bc78030d2e800cdf6818 Mon Sep 17 00:00:00 2001 From: renchenglei Date: Thu, 10 Dec 2020 06:36:13 +0800 Subject: [PATCH 233/269] INTERNAL: Add Gralloc 1.0 support This is to help enable Gralloc 1.0 --- Android.bp | 21 +- cros_gralloc/cros_gralloc_buffer.cc | 48 ++ cros_gralloc/cros_gralloc_buffer.h | 3 + cros_gralloc/cros_gralloc_driver.cc | 31 +- cros_gralloc/cros_gralloc_driver.h | 4 + cros_gralloc/cros_gralloc_handle.h | 4 + cros_gralloc/cros_gralloc_helpers.cc | 30 + cros_gralloc/cros_gralloc_helpers.h | 4 + cros_gralloc/cros_gralloc_types.h | 4 + cros_gralloc/gralloc1/cros_gralloc1_module.cc | 599 ++++++++++++++++++ cros_gralloc/gralloc1/cros_gralloc1_module.h | 294 +++++++++ 11 files changed, 1037 insertions(+), 5 deletions(-) create mode 100644 cros_gralloc/gralloc1/cros_gralloc1_module.cc create mode 100644 cros_gralloc/gralloc1/cros_gralloc1_module.h diff --git a/Android.bp b/Android.bp index 1ba475c..72a1dfe 100644 --- a/Android.bp +++ b/Android.bp @@ -35,6 +35,9 @@ cc_defaults { "-Wcast-qual", "-Wcast-align", "-Wno-unused-parameter", + "-Wno-switch", + "-Wno-format", + "-Wno-unused-variable", ], cppflags: ["-std=c++14"], @@ -72,6 +75,10 @@ cc_defaults { defaults: ["minigbm_defaults_celadon"], + local_include_dirs: [ + "cros_gralloc", + ], + srcs: [ "cros_gralloc/cros_gralloc_buffer.cc", "cros_gralloc/cros_gralloc_helpers.cc", @@ -136,9 +143,12 @@ cc_library_shared { enabled: true, }, }, - cflags: ["-DDRV_I915"], + cflags: [ + "-DDRV_I915", + "-DUSE_GRALLOC1", + ], relative_install_path: "hw", - srcs: ["cros_gralloc/gralloc0/gralloc0.cc"], + srcs: ["cros_gralloc/gralloc1/cros_gralloc1_module.cc"], } cc_library_shared { @@ -152,9 +162,12 @@ cc_library_shared { enabled: true, }, }, - cflags: ["-DDRV_I915"], + cflags: [ + "-DDRV_I915", + "-DUSE_GRALLOC1", + ], relative_install_path: "hw", - srcs: ["cros_gralloc/gralloc0/gralloc0.cc"], + srcs: ["cros_gralloc/gralloc1/cros_gralloc1_module.cc"], } cc_library_shared { diff --git a/cros_gralloc/cros_gralloc_buffer.cc b/cros_gralloc/cros_gralloc_buffer.cc index 2982505..fdaf7d3 100644 --- a/cros_gralloc/cros_gralloc_buffer.cc +++ b/cros_gralloc/cros_gralloc_buffer.cc @@ -98,6 +98,54 @@ int32_t cros_gralloc_buffer::lock(const struct rectangle *rect, uint32_t map_fla return 0; } +#ifdef USE_GRALLOC1 +int32_t cros_gralloc_buffer::lock(uint32_t map_flags, uint8_t *addr[DRV_MAX_PLANES]) +{ + void *vaddr = nullptr; + + memset(addr, 0, DRV_MAX_PLANES * sizeof(*addr)); + + /* + * Gralloc consumers don't support more than one kernel buffer per buffer object yet, so + * just use the first kernel buffer. + */ + if (drv_num_buffers_per_bo(bo_) != 1) { + drv_log("Can only support one buffer per bo."); + return -EINVAL; + } + + if (map_flags) { + if (lock_data_[0]) { + drv_bo_invalidate(bo_, lock_data_[0]); + vaddr = lock_data_[0]->vma->addr; + } else { + struct rectangle r; + + if (!r.width && !r.height && !r.x && !r.y) { + /* + * Android IMapper.hal: An accessRegion of all-zeros means the + * entire buffer. + */ + r.width = drv_bo_get_width(bo_); + r.height = drv_bo_get_height(bo_); + } + vaddr = drv_bo_map(bo_, &r, map_flags, &lock_data_[0], 0); + } + + if (vaddr == MAP_FAILED) { + drv_log("Mapping failed."); + return -EFAULT; + } + } + + for (uint32_t plane = 0; plane < num_planes_; plane++) + addr[plane] = static_cast(vaddr) + drv_bo_get_plane_offset(bo_, plane); + + lockcount_++; + return 0; +} +#endif + int32_t cros_gralloc_buffer::unlock() { if (lockcount_ <= 0) { diff --git a/cros_gralloc/cros_gralloc_buffer.h b/cros_gralloc/cros_gralloc_buffer.h index 8634882..ff5c171 100644 --- a/cros_gralloc/cros_gralloc_buffer.h +++ b/cros_gralloc/cros_gralloc_buffer.h @@ -26,6 +26,9 @@ class cros_gralloc_buffer int32_t lock(const struct rectangle *rect, uint32_t map_flags, uint8_t *addr[DRV_MAX_PLANES]); +#ifdef USE_GRALLOC1 + int32_t lock(uint32_t map_flags, uint8_t *addr[DRV_MAX_PLANES]); +#endif int32_t unlock(); int32_t resource_info(uint32_t strides[DRV_MAX_PLANES], uint32_t offsets[DRV_MAX_PLANES]); diff --git a/cros_gralloc/cros_gralloc_driver.cc b/cros_gralloc/cros_gralloc_driver.cc index e324bce..ba980b3 100644 --- a/cros_gralloc/cros_gralloc_driver.cc +++ b/cros_gralloc/cros_gralloc_driver.cc @@ -219,6 +219,10 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto hnd->magic = cros_gralloc_magic; hnd->droid_format = descriptor->droid_format; hnd->usage = descriptor->droid_usage; +#ifdef USE_GRALLOC1 + hnd->producer_usage = descriptor->producer_usage; + hnd->consumer_usage = descriptor->consumer_usage; +#endif hnd->total_size = descriptor->reserved_region_size + bo->meta.total_size; hnd->name_offset = handle_data_size; @@ -344,6 +348,31 @@ int32_t cros_gralloc_driver::lock(buffer_handle_t handle, int32_t acquire_fence, return buffer->lock(rect, map_flags, addr); } +#ifdef USE_GRALLOC1 +int32_t cros_gralloc_driver::lock(buffer_handle_t handle, int32_t acquire_fence, uint32_t map_flags, + uint8_t *addr[DRV_MAX_PLANES]) +{ + int32_t ret = cros_gralloc_sync_wait(acquire_fence); + if (ret) + return ret; + + std::lock_guard lock(mutex_); + auto hnd = cros_gralloc_convert_handle(handle); + if (!hnd) { + drv_log("Invalid handle."); + return -EINVAL; + } + + auto buffer = get_buffer(hnd); + if (!buffer) { + drv_log("Invalid Reference."); + return -EINVAL; + } + + return buffer->lock(map_flags, addr); +} +#endif + int32_t cros_gralloc_driver::unlock(buffer_handle_t handle, int32_t *release_fence) { std::lock_guard lock(mutex_); @@ -498,4 +527,4 @@ void cros_gralloc_driver::for_each_handle( for (const auto &pair : handles_) { function(pair.first); } -} \ No newline at end of file +} diff --git a/cros_gralloc/cros_gralloc_driver.h b/cros_gralloc/cros_gralloc_driver.h index d444ecd..9ac4233 100644 --- a/cros_gralloc/cros_gralloc_driver.h +++ b/cros_gralloc/cros_gralloc_driver.h @@ -30,6 +30,10 @@ class cros_gralloc_driver int32_t lock(buffer_handle_t handle, int32_t acquire_fence, bool close_acquire_fence, const struct rectangle *rect, uint32_t map_flags, uint8_t *addr[DRV_MAX_PLANES]); +#ifdef USE_GRALLOC1 + int32_t lock(buffer_handle_t handle, int32_t acquire_fence, uint32_t map_flags, + uint8_t *addr[DRV_MAX_PLANES]); +#endif int32_t unlock(buffer_handle_t handle, int32_t *release_fence); int32_t invalidate(buffer_handle_t handle); diff --git a/cros_gralloc/cros_gralloc_handle.h b/cros_gralloc/cros_gralloc_handle.h index d2e1607..c0fe2af 100644 --- a/cros_gralloc/cros_gralloc_handle.h +++ b/cros_gralloc/cros_gralloc_handle.h @@ -44,6 +44,10 @@ struct cros_gralloc_handle { * Name is a null terminated char array located at handle->base.data[handle->name_offset]. */ uint32_t name_offset; +#ifdef USE_GRALLOC1 + uint32_t consumer_usage; + uint32_t producer_usage; +#endif } __attribute__((packed)); typedef const struct cros_gralloc_handle *cros_gralloc_handle_t; diff --git a/cros_gralloc/cros_gralloc_helpers.cc b/cros_gralloc/cros_gralloc_helpers.cc index 1e05150..f5fb9e9 100644 --- a/cros_gralloc/cros_gralloc_helpers.cc +++ b/cros_gralloc/cros_gralloc_helpers.cc @@ -90,3 +90,33 @@ int32_t cros_gralloc_sync_wait(int32_t fence, bool close_fence) return 0; } + +#ifdef USE_GRALLOC1 +int32_t cros_gralloc_sync_wait(int32_t acquire_fence) +{ + if (acquire_fence < 0) + return 0; + + /* + * Wait initially for 1000 ms, and then wait indefinitely. The SYNC_IOC_WAIT + * documentation states the caller waits indefinitely on the fence if timeout < 0. + */ + int err = sync_wait(acquire_fence, 1000); + if (err < 0) { + drv_log("Timed out on sync wait, err = %s", strerror(errno)); + err = sync_wait(acquire_fence, -1); + if (err < 0) { + drv_log("sync wait error = %s", strerror(errno)); + return -errno; + } + } + + err = close(acquire_fence); + if (err) { + drv_log("Unable to close fence fd, err = %s", strerror(errno)); + return -errno; + } + + return 0; +} +#endif diff --git a/cros_gralloc/cros_gralloc_helpers.h b/cros_gralloc/cros_gralloc_helpers.h index 36f86ef..5d18282 100644 --- a/cros_gralloc/cros_gralloc_helpers.h +++ b/cros_gralloc/cros_gralloc_helpers.h @@ -24,4 +24,8 @@ cros_gralloc_handle_t cros_gralloc_convert_handle(buffer_handle_t handle); int32_t cros_gralloc_sync_wait(int32_t fence, bool close_fence); +#ifdef USE_GRALLOC1 +int32_t cros_gralloc_sync_wait(int32_t acquire_fence); +#endif + #endif diff --git a/cros_gralloc/cros_gralloc_types.h b/cros_gralloc/cros_gralloc_types.h index 22f58e2..8ea73e3 100644 --- a/cros_gralloc/cros_gralloc_types.h +++ b/cros_gralloc/cros_gralloc_types.h @@ -18,6 +18,10 @@ struct cros_gralloc_buffer_descriptor { uint64_t use_flags; uint64_t reserved_region_size; std::string name; +#ifdef USE_GRALLOC1 + uint32_t consumer_usage; + uint32_t producer_usage; +#endif }; #endif diff --git a/cros_gralloc/gralloc1/cros_gralloc1_module.cc b/cros_gralloc/gralloc1/cros_gralloc1_module.cc new file mode 100644 index 0000000..df29e22 --- /dev/null +++ b/cros_gralloc/gralloc1/cros_gralloc1_module.cc @@ -0,0 +1,599 @@ +/* + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#undef LOG_TAG +#define LOG_TAG "CrosGralloc1 " + +#include "cros_gralloc1_module.h" + +#include + +#include + +template static gralloc1_function_pointer_t asFP(T function) +{ + static_assert(std::is_same::value, "Incompatible function pointer"); + return reinterpret_cast(function); +} + +uint64_t cros_gralloc1_convert_flags(uint64_t producer_flags, uint64_t consumer_flags) +{ + uint64_t usage = BO_USE_NONE; + + if (consumer_flags & GRALLOC1_CONSUMER_USAGE_CURSOR) + usage |= BO_USE_CURSOR; + if (consumer_flags & GRALLOC1_CONSUMER_USAGE_CPU_READ) + usage |= BO_USE_SW_READ_RARELY; + if (consumer_flags & GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN) + usage |= BO_USE_SW_READ_OFTEN; + if ((consumer_flags & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) || + (consumer_flags & GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET)) { + /* HWC wants to use display hardware, but can defer to OpenGL. */ + usage |= BO_USE_SCANOUT | BO_USE_TEXTURE; + } else if (consumer_flags & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) { + usage |= BO_USE_TEXTURE; + } + if (consumer_flags & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER) + /*HACK: See b/30054495 */ + usage |= BO_USE_SW_READ_OFTEN; + if (consumer_flags & GRALLOC1_CONSUMER_USAGE_CAMERA) + usage |= BO_USE_CAMERA_READ; + if (consumer_flags & GRALLOC1_CONSUMER_USAGE_RENDERSCRIPT) + /* We use CPU for compute. */ + usage |= BO_USE_LINEAR; + + if (producer_flags & GRALLOC1_PRODUCER_USAGE_CPU_READ) + usage |= BO_USE_SW_READ_RARELY; + if (producer_flags & GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN) + usage |= BO_USE_SW_READ_OFTEN; + if (producer_flags & GRALLOC1_PRODUCER_USAGE_CPU_WRITE) + usage |= BO_USE_SW_WRITE_RARELY; + if (producer_flags & GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN) + usage |= BO_USE_SW_WRITE_OFTEN; + if (producer_flags & GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET) + usage |= BO_USE_RENDERING; + if (producer_flags & GRALLOC1_PRODUCER_USAGE_VIDEO_DECODER) + /* Video wants to use display hardware, but can defer to OpenGL. */ + usage |= BO_USE_SCANOUT | BO_USE_RENDERING; + if (producer_flags & GRALLOC1_PRODUCER_USAGE_PROTECTED) + usage |= BO_USE_PROTECTED; + if (producer_flags & GRALLOC1_PRODUCER_USAGE_CAMERA) + usage |= BO_USE_CAMERA_WRITE; + + return usage; +} + +namespace android +{ + +/* CrosGralloc1 is a Singleton and pCrosGralloc1 holds pointer to its instance*/ +static CrosGralloc1 *pCrosGralloc1 = NULL; +static uint32_t ref_count = 0; +//static SpinLock global_lock_; + +CrosGralloc1::CrosGralloc1() +{ + getCapabilities = getCapabilitiesHook; + getFunction = getFunctionHook; + common.tag = HARDWARE_DEVICE_TAG; + common.version = HARDWARE_MODULE_API_VERSION(1, 0); + common.close = HookDevClose; +} + +CrosGralloc1::~CrosGralloc1() +{ +} + +bool CrosGralloc1::Init() +{ + if (driver) + return true; + + driver = std::make_unique(); + if (driver->init()) { + drv_log("Failed to initialize driver."); + return false; + } + + return true; +} + +void CrosGralloc1::doGetCapabilities(uint32_t *outCount, int32_t *outCapabilities) +{ + if (outCapabilities == nullptr) { + *outCount = 0; + } +} + +gralloc1_function_pointer_t CrosGralloc1::doGetFunction(int32_t intDescriptor) +{ + constexpr auto lastDescriptor = static_cast(GRALLOC1_LAST_FUNCTION); + if (intDescriptor < 0 || intDescriptor > lastDescriptor) { + drv_log("Invalid function descriptor"); + return nullptr; + } + + auto descriptor = static_cast(intDescriptor); + switch (descriptor) { + case GRALLOC1_FUNCTION_DUMP: + return asFP(dumpHook); + case GRALLOC1_FUNCTION_CREATE_DESCRIPTOR: + return asFP(createDescriptorHook); + case GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR: + return asFP(destroyDescriptorHook); + case GRALLOC1_FUNCTION_SET_CONSUMER_USAGE: + return asFP(setConsumerUsageHook); + case GRALLOC1_FUNCTION_SET_DIMENSIONS: + return asFP(setDimensionsHook); + case GRALLOC1_FUNCTION_SET_FORMAT: + return asFP(setFormatHook); + case GRALLOC1_FUNCTION_SET_PRODUCER_USAGE: + return asFP(setProducerUsageHook); + case GRALLOC1_FUNCTION_GET_BACKING_STORE: + return asFP(getBackingStoreHook); + case GRALLOC1_FUNCTION_GET_CONSUMER_USAGE: + return asFP(getConsumerUsageHook); + case GRALLOC1_FUNCTION_GET_DIMENSIONS: + return asFP(getDimensionsHook); + case GRALLOC1_FUNCTION_GET_FORMAT: + return asFP(getFormatHook); + case GRALLOC1_FUNCTION_GET_PRODUCER_USAGE: + return asFP(getProducerUsageHook); + case GRALLOC1_FUNCTION_GET_STRIDE: + return asFP(getStrideHook); + case GRALLOC1_FUNCTION_ALLOCATE: + if (driver) { + return asFP(allocateBuffers); + } else { + return nullptr; + } + case GRALLOC1_FUNCTION_RETAIN: + return asFP(managementHook<&CrosGralloc1::retain>); + case GRALLOC1_FUNCTION_RELEASE: + return asFP(managementHook<&CrosGralloc1::release>); + case GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES: + return asFP(getNumFlexPlanesHook); + case GRALLOC1_FUNCTION_LOCK: + return asFP(lockHook); + case GRALLOC1_FUNCTION_LOCK_FLEX: + return asFP( + lockHook); + case GRALLOC1_FUNCTION_UNLOCK: + return asFP(unlockHook); + case GRALLOC1_FUNCTION_INVALID: + drv_log("Invalid function descriptor"); + return nullptr; + } + + drv_log("Unknown function descriptor: %d", intDescriptor); + return nullptr; +} + +void CrosGralloc1::dump(uint32_t *outSize, char *outBuffer) +{ + drv_log("dump(%u (%p), %p", outSize ? *outSize : 0, outSize, outBuffer); +} + +int32_t CrosGralloc1::createDescriptor(gralloc1_buffer_descriptor_t *outDescriptor) +{ + if (!outDescriptor) + return CROS_GRALLOC_ERROR_BAD_DESCRIPTOR; + + struct cros_gralloc_buffer_descriptor *hnd = new cros_gralloc_buffer_descriptor(); + *outDescriptor = (gralloc1_buffer_descriptor_t)hnd; + return CROS_GRALLOC_ERROR_NONE; +} + +int32_t CrosGralloc1::destroyDescriptor(gralloc1_buffer_descriptor_t descriptor) +{ + auto hnd = (struct cros_gralloc_buffer_descriptor *)descriptor; + delete hnd; + return CROS_GRALLOC_ERROR_NONE; +} + +int32_t CrosGralloc1::setConsumerUsage(gralloc1_buffer_descriptor_t descriptorId, uint64_t intUsage) +{ + auto hnd = (struct cros_gralloc_buffer_descriptor *)descriptorId; + hnd->consumer_usage = intUsage; + return CROS_GRALLOC_ERROR_NONE; +} + +int32_t CrosGralloc1::setProducerUsage(gralloc1_buffer_descriptor_t descriptorId, uint64_t intUsage) +{ + auto hnd = (struct cros_gralloc_buffer_descriptor *)descriptorId; + hnd->producer_usage = intUsage; + return CROS_GRALLOC_ERROR_NONE; +} + +int32_t CrosGralloc1::setDimensions(gralloc1_buffer_descriptor_t descriptorId, uint32_t width, + uint32_t height) +{ + auto hnd = (struct cros_gralloc_buffer_descriptor *)descriptorId; + hnd->width = width; + hnd->height = height; + return CROS_GRALLOC_ERROR_NONE; +} + +int32_t CrosGralloc1::setFormat(gralloc1_buffer_descriptor_t descriptorId, int32_t format) +{ + auto hnd = (struct cros_gralloc_buffer_descriptor *)descriptorId; + hnd->droid_format = format; + hnd->drm_format = cros_gralloc_convert_format(format); + return CROS_GRALLOC_ERROR_NONE; +} + +int32_t CrosGralloc1::allocate(struct cros_gralloc_buffer_descriptor *descriptor, + buffer_handle_t *outBufferHandle) +{ + // If this function is being called, it's because we handed out its function + // pointer, which only occurs when mDevice has been loaded successfully and + // we are permitted to allocate + uint64_t usage = + cros_gralloc1_convert_flags(descriptor->producer_usage, descriptor->consumer_usage); + descriptor->use_flags = usage; + bool supported = driver->is_supported(descriptor); + if (!supported && (descriptor->consumer_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER)) { + descriptor->use_flags &= ~BO_USE_SCANOUT; + supported = driver->is_supported(descriptor); + } + + if (!supported) { + drv_log("Unsupported combination -- HAL format: %u, HAL flags: %u, " + "drv_format: %u, drv_flags: %llu", + descriptor->droid_format, usage, descriptor->drm_format, + static_cast(descriptor->use_flags)); + return CROS_GRALLOC_ERROR_UNSUPPORTED; + } + if (driver->allocate(descriptor, outBufferHandle)) + return CROS_GRALLOC_ERROR_NO_RESOURCES; + + return CROS_GRALLOC_ERROR_NONE; +} + +int32_t CrosGralloc1::allocateBuffers(gralloc1_device_t *device, uint32_t numDescriptors, + const gralloc1_buffer_descriptor_t *descriptors, + buffer_handle_t *outBuffers) +{ + auto adapter = getAdapter(device); + for (uint32_t i = 0; i < numDescriptors; i++) { + auto descriptor = (struct cros_gralloc_buffer_descriptor *)descriptors[i]; + if (!descriptor) { + return CROS_GRALLOC_ERROR_BAD_DESCRIPTOR; + } + + buffer_handle_t bufferHandle = nullptr; + int32_t error = adapter->allocate(descriptor, &bufferHandle); + if (error != CROS_GRALLOC_ERROR_NONE) { + return error; + } + + outBuffers[i] = bufferHandle; + } + + return CROS_GRALLOC_ERROR_NONE; +} + +int32_t CrosGralloc1::retain(buffer_handle_t bufferHandle) +{ + if (driver->retain(bufferHandle)) + return CROS_GRALLOC_ERROR_BAD_HANDLE; + + return CROS_GRALLOC_ERROR_NONE; +} + +int32_t CrosGralloc1::release(buffer_handle_t bufferHandle) +{ + if (driver->release(bufferHandle)) + return CROS_GRALLOC_ERROR_BAD_HANDLE; + + return CROS_GRALLOC_ERROR_NONE; +} + +int32_t CrosGralloc1::lock(buffer_handle_t bufferHandle, gralloc1_producer_usage_t producerUsage, + gralloc1_consumer_usage_t consumerUsage, + const gralloc1_rect_t &accessRegion, void **outData, + int32_t acquireFence) +{ + int32_t ret; + uint64_t flags; + uint8_t *addr[DRV_MAX_PLANES]; + + auto hnd = cros_gralloc_convert_handle(bufferHandle); + if (!hnd) { + drv_log("Invalid handle."); + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + + if ((hnd->droid_format == HAL_PIXEL_FORMAT_YCbCr_420_888)) { + drv_log("HAL_PIXEL_FORMAT_YCbCr_*_888 format not compatible."); + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + + flags = cros_gralloc1_convert_flags(producerUsage, consumerUsage); + + if (driver->lock(bufferHandle, acquireFence, flags, addr)) + return CROS_GRALLOC_ERROR_BAD_HANDLE; + + *outData = addr[0]; + + return CROS_GRALLOC_ERROR_NONE; +} + +android_flex_plane_t ycbcrplanes[3]; + +int32_t update_flex_layout(struct android_ycbcr *ycbcr, struct android_flex_layout *outFlexLayout) +{ + /*Need to add generic support*/ + ycbcrplanes[0].component = FLEX_COMPONENT_Y; + ycbcrplanes[0].top_left = (uint8_t *)ycbcr->y; + ycbcrplanes[0].h_increment = ycbcr->ystride; + ycbcrplanes[1].component = FLEX_COMPONENT_Cb; + ycbcrplanes[1].top_left = (uint8_t *)ycbcr->cb; + ycbcrplanes[1].h_increment = ycbcr->cstride; + ycbcrplanes[2].component = FLEX_COMPONENT_Cr; + ycbcrplanes[2].top_left = (uint8_t *)ycbcr->cr; + ycbcrplanes[2].h_increment = ycbcr->chroma_step; + outFlexLayout->format = FLEX_FORMAT_YCbCr; + outFlexLayout->planes = ycbcrplanes; + outFlexLayout->num_planes = 3; + return 0; +} + +int32_t CrosGralloc1::lockFlex(buffer_handle_t bufferHandle, + gralloc1_producer_usage_t producerUsage, + gralloc1_consumer_usage_t consumerUsage, + const gralloc1_rect_t &accessRegion, + struct android_flex_layout *outData, int32_t acquireFence) +{ + int32_t ret = -EINVAL; + struct android_ycbcr ycbcrData; + + /*Check the format and support only for YUV format */ + auto hnd = cros_gralloc_convert_handle(bufferHandle); + if (!hnd) { + drv_log("lockFlex: Invalid handle."); + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + + if ((hnd->droid_format != HAL_PIXEL_FORMAT_YCbCr_420_888) && + (hnd->droid_format != HAL_PIXEL_FORMAT_YV12)) { + drv_log("lockFlex: Non-YUV format not compatible."); + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + + ret = lockYCbCr(bufferHandle, producerUsage, consumerUsage, accessRegion, &ycbcrData, + acquireFence); + + /* convert the data in flex format*/ + update_flex_layout(&ycbcrData, outData); + + return ret; +} + +int32_t CrosGralloc1::lockYCbCr(buffer_handle_t bufferHandle, + gralloc1_producer_usage_t producerUsage, + gralloc1_consumer_usage_t consumerUsage, + const gralloc1_rect_t &accessRegion, struct android_ycbcr *ycbcr, + int32_t acquireFence) +{ + uint64_t flags; + int32_t ret; + uint8_t *addr[DRV_MAX_PLANES] = { nullptr, nullptr, nullptr, nullptr }; + + auto hnd = cros_gralloc_convert_handle(bufferHandle); + if (!hnd) { + drv_log("Invalid handle."); + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + + if ((hnd->droid_format != HAL_PIXEL_FORMAT_YCbCr_420_888) && + (hnd->droid_format != HAL_PIXEL_FORMAT_YV12)) { + drv_log("Non-YUV format not compatible."); + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + + flags = cros_gralloc1_convert_flags(producerUsage, consumerUsage); + if (driver->lock(bufferHandle, acquireFence, flags, addr)) + return CROS_GRALLOC_ERROR_BAD_HANDLE; + + switch (hnd->format) { + case DRM_FORMAT_NV12: + ycbcr->y = addr[0]; + ycbcr->cb = addr[1]; + ycbcr->cr = addr[1] + 1; + ycbcr->ystride = hnd->strides[0]; + ycbcr->cstride = hnd->strides[1]; + ycbcr->chroma_step = 2; + break; + case DRM_FORMAT_YVU420: + case DRM_FORMAT_YVU420_ANDROID: + ycbcr->y = addr[0]; + ycbcr->cb = addr[2]; + ycbcr->cr = addr[1]; + ycbcr->ystride = hnd->strides[0]; + ycbcr->cstride = hnd->strides[1]; + ycbcr->chroma_step = 1; + break; + default: + return CROS_GRALLOC_ERROR_UNSUPPORTED; + } + + return CROS_GRALLOC_ERROR_NONE; +} + +int32_t CrosGralloc1::unlock(buffer_handle_t bufferHandle, int32_t *outReleaseFence) +{ + if (driver->unlock(bufferHandle, outReleaseFence)) + return CROS_GRALLOC_ERROR_BAD_HANDLE; + + return CROS_GRALLOC_ERROR_NONE; +} + +int32_t CrosGralloc1::getNumFlexPlanes(buffer_handle_t buffer, uint32_t *outNumPlanes) +{ + auto hnd = cros_gralloc_convert_handle(buffer); + if (!hnd) { + drv_log("Invalid handle."); + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + + *outNumPlanes = drv_num_planes_from_format(hnd->format); + return CROS_GRALLOC_ERROR_NONE; +} + +int32_t CrosGralloc1::getBackingStore(buffer_handle_t buffer, gralloc1_backing_store_t *outStore) +{ + auto hnd = cros_gralloc_convert_handle(buffer); + if (!hnd) { + drv_log("Invalid handle."); + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + + if (driver->get_backing_store(buffer, outStore)) + return CROS_GRALLOC_ERROR_BAD_HANDLE; + + return CROS_GRALLOC_ERROR_NONE; +} + +int32_t CrosGralloc1::getConsumerUsage(buffer_handle_t buffer, + uint64_t * /*gralloc1_consumer_usage_t*/ outUsage) +{ + auto hnd = cros_gralloc_convert_handle(buffer); + if (!hnd) { + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + + *outUsage = hnd->consumer_usage; + return CROS_GRALLOC_ERROR_NONE; +} + +int32_t CrosGralloc1::getDimensions(buffer_handle_t buffer, uint32_t *outWidth, uint32_t *outHeight) +{ + auto hnd = cros_gralloc_convert_handle(buffer); + if (!hnd) { + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + + *outWidth = hnd->width; + *outHeight = hnd->height; + return CROS_GRALLOC_ERROR_NONE; +} + +int32_t CrosGralloc1::getFormat(buffer_handle_t buffer, int32_t *outFormat) +{ + auto hnd = cros_gralloc_convert_handle(buffer); + if (!hnd) { + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + + *outFormat = hnd->droid_format; + return CROS_GRALLOC_ERROR_NONE; +} + +int32_t CrosGralloc1::getProducerUsage(buffer_handle_t buffer, + uint64_t * /*gralloc1_producer_usage_t*/ outUsage) +{ + auto hnd = cros_gralloc_convert_handle(buffer); + if (!hnd) { + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + + *outUsage = hnd->producer_usage; + return CROS_GRALLOC_ERROR_NONE; +} + +int32_t CrosGralloc1::getStride(buffer_handle_t buffer, uint32_t *outStride) +{ + auto hnd = cros_gralloc_convert_handle(buffer); + if (!hnd) { + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + + *outStride = hnd->pixel_stride; + return CROS_GRALLOC_ERROR_NONE; +} + +// static +int CrosGralloc1::HookDevOpen(const struct hw_module_t *mod, const char *name, + struct hw_device_t **device) +{ + if (strcmp(name, GRALLOC_HARDWARE_MODULE_ID)) { + drv_log("Invalid module name- %s", name); + return -EINVAL; + } + + //ScopedSpinLock lock(global_lock_); + std::lock_guard lock(std::mutex); + ref_count++; + + if (pCrosGralloc1 != NULL) { + *device = &pCrosGralloc1->common; + return 0; + } else + pCrosGralloc1 = new CrosGralloc1(); + + std::unique_ptr ctx(pCrosGralloc1); + if (!ctx) { + drv_log("Failed to allocate CrosGralloc1"); + return -ENOMEM; + } + + if (!ctx->Init()) { + drv_log("Failed to initialize CrosGralloc1. \n"); + return -EINVAL; + } + + ctx->common.module = const_cast(mod); + *device = &ctx->common; + ctx.release(); + return 0; +} + +// static +int CrosGralloc1::HookDevClose(hw_device_t * /*dev*/) +{ + //ScopedSpinLock lock(global_lock_); + std::lock_guard lock(std::mutex); + if (ref_count > 0) { + ref_count--; + } + + if (ref_count > 0) { + return 0; + } + + if (pCrosGralloc1) { + delete pCrosGralloc1; + pCrosGralloc1 = NULL; + } + + return 0; +} + +} // namespace android + +static struct hw_module_methods_t cros_gralloc_module_methods = { + .open = android::CrosGralloc1::HookDevOpen, +}; + +hw_module_t HAL_MODULE_INFO_SYM = { + .tag = HARDWARE_MODULE_TAG, + .module_api_version = HARDWARE_MODULE_API_VERSION(1, 0), + .id = GRALLOC_HARDWARE_MODULE_ID, + .name = "Gralloc 1.0 module", + .author = "Intel Android", + .methods = &cros_gralloc_module_methods, +}; diff --git a/cros_gralloc/gralloc1/cros_gralloc1_module.h b/cros_gralloc/gralloc1/cros_gralloc1_module.h new file mode 100644 index 0000000..09aff0b --- /dev/null +++ b/cros_gralloc/gralloc1/cros_gralloc1_module.h @@ -0,0 +1,294 @@ +/* + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CROS_GRALLOC1_MODULE_H +#define CROS_GRALLOC1_MODULE_H + +#include + +#include "cros_gralloc_driver.h" + +#include + +#include "drv.h" + +struct cros_gralloc_module; + +namespace android +{ + +typedef enum { + CROS_GRALLOC_ERROR_NONE = 0, + CROS_GRALLOC_ERROR_BAD_DESCRIPTOR = 1, + CROS_GRALLOC_ERROR_BAD_HANDLE = 2, + CROS_GRALLOC_ERROR_BAD_VALUE = 3, + CROS_GRALLOC_ERROR_NOT_SHARED = 4, + CROS_GRALLOC_ERROR_NO_RESOURCES = 5, + CROS_GRALLOC_ERROR_UNDEFINED = 6, + CROS_GRALLOC_ERROR_UNSUPPORTED = 7, +} cros_gralloc_error_t; + +class CrosGralloc1 : public gralloc1_device_t +{ + public: + CrosGralloc1(); + ~CrosGralloc1(); + + bool Init(); + + static int HookDevOpen(const struct hw_module_t *mod, const char *name, + struct hw_device_t **device); + static int HookDevClose(hw_device_t *dev); + + private: + static inline CrosGralloc1 *getAdapter(gralloc1_device_t *device) + { + return static_cast(device); + } + + // getCapabilities + + void doGetCapabilities(uint32_t *outCount, + int32_t * /*gralloc1_capability_t*/ outCapabilities); + static void getCapabilitiesHook(gralloc1_device_t *device, uint32_t *outCount, + int32_t * /*gralloc1_capability_t*/ outCapabilities) + { + getAdapter(device)->doGetCapabilities(outCount, outCapabilities); + }; + + // getFunction + + gralloc1_function_pointer_t + doGetFunction(int32_t /*gralloc1_function_descriptor_t*/ descriptor); + static gralloc1_function_pointer_t + getFunctionHook(gralloc1_device_t *device, + int32_t /*gralloc1_function_descriptor_t*/ descriptor) + { + return getAdapter(device)->doGetFunction(descriptor); + } + + // dump + + void dump(uint32_t *outSize, char *outBuffer); + static void dumpHook(gralloc1_device_t *device, uint32_t *outSize, char *outBuffer) + { + return getAdapter(device)->dump(outSize, outBuffer); + } + + // Buffer descriptor functions + + int32_t setConsumerUsage(gralloc1_buffer_descriptor_t descriptorId, uint64_t intUsage); + + int32_t setProducerUsage(gralloc1_buffer_descriptor_t descriptorId, uint64_t intUsage); + + int32_t setDimensions(gralloc1_buffer_descriptor_t descriptorId, uint32_t width, + uint32_t height); + + int32_t setFormat(gralloc1_buffer_descriptor_t descriptorId, int32_t format); + + int32_t createDescriptor(gralloc1_buffer_descriptor_t *outDescriptor); + static int32_t createDescriptorHook(gralloc1_device_t *device, + gralloc1_buffer_descriptor_t *outDescriptor) + { + return getAdapter(device)->createDescriptor(outDescriptor); + } + + int32_t destroyDescriptor(gralloc1_buffer_descriptor_t descriptor); + static int32_t destroyDescriptorHook(gralloc1_device_t *device, + gralloc1_buffer_descriptor_t descriptor) + { + return getAdapter(device)->destroyDescriptor(descriptor); + } + + static int32_t setConsumerUsageHook(gralloc1_device_t *device, + gralloc1_buffer_descriptor_t descriptorId, + uint64_t intUsage) + { + return getAdapter(device)->setConsumerUsage(descriptorId, intUsage); + } + + static int32_t setDimensionsHook(gralloc1_device_t *device, + gralloc1_buffer_descriptor_t descriptorId, uint32_t width, + uint32_t height) + { + return getAdapter(device)->setDimensions(descriptorId, width, height); + } + + static int32_t setFormatHook(gralloc1_device_t *device, + gralloc1_buffer_descriptor_t descriptorId, int32_t format) + { + return getAdapter(device)->setFormat(descriptorId, format); + } + + static int32_t setProducerUsageHook(gralloc1_device_t *device, + gralloc1_buffer_descriptor_t descriptorId, + uint64_t intUsage) + { + return getAdapter(device)->setProducerUsage(descriptorId, intUsage); + } + + int32_t getNumFlexPlanes(buffer_handle_t buffer, uint32_t *outNumPlanes); + static int32_t getNumFlexPlanesHook(gralloc1_device_t *device, buffer_handle_t buffer, + uint32_t *outNumPlanes) + { + return getAdapter(device)->getNumFlexPlanes(buffer, outNumPlanes); + } + + int32_t getBackingStore(buffer_handle_t buffer, gralloc1_backing_store_t *outStore); + static int32_t getBackingStoreHook(gralloc1_device_t *device, buffer_handle_t buffer, + gralloc1_backing_store_t *outStore) + { + return getAdapter(device)->getBackingStore(buffer, outStore); + } + + int32_t getConsumerUsage(buffer_handle_t buffer, + uint64_t * /*gralloc1_consumer_usage_t*/ outUsage); + static int32_t getConsumerUsageHook(gralloc1_device_t *device, buffer_handle_t buffer, + uint64_t * /*gralloc1_consumer_usage_t*/ outUsage) + { + return getAdapter(device)->getConsumerUsage(buffer, outUsage); + } + + int32_t getDimensions(buffer_handle_t buffer, uint32_t *outWidth, uint32_t *outHeight); + static int32_t getDimensionsHook(gralloc1_device_t *device, buffer_handle_t buffer, + uint32_t *outWidth, uint32_t *outHeight) + { + return getAdapter(device)->getDimensions(buffer, outWidth, outHeight); + } + + int32_t getFormat(buffer_handle_t buffer, int32_t *outFormat); + static int32_t getFormatHook(gralloc1_device_t *device, buffer_handle_t buffer, + int32_t *outFormat) + { + return getAdapter(device)->getFormat(buffer, outFormat); + } + + int32_t getProducerUsage(buffer_handle_t buffer, + uint64_t * /*gralloc1_producer_usage_t*/ outUsage); + static int32_t getProducerUsageHook(gralloc1_device_t *device, buffer_handle_t buffer, + uint64_t * /*gralloc1_producer_usage_t*/ outUsage) + { + return getAdapter(device)->getProducerUsage(buffer, outUsage); + } + + int32_t getStride(buffer_handle_t buffer, uint32_t *outStride); + static int32_t getStrideHook(gralloc1_device_t *device, buffer_handle_t buffer, + uint32_t *outStride) + { + return getAdapter(device)->getStride(buffer, outStride); + } + + // Buffer Management functions + int32_t allocate(struct cros_gralloc_buffer_descriptor *descriptor, + buffer_handle_t *outBufferHandle); + static int32_t allocateBuffers(gralloc1_device_t *device, uint32_t numDescriptors, + const gralloc1_buffer_descriptor_t *descriptors, + buffer_handle_t *outBuffers); + + int32_t release(buffer_handle_t bufferHandle); + int32_t retain(buffer_handle_t bufferHandle); + + // Member function pointer 'member' will either be retain or release + template + static int32_t managementHook(gralloc1_device_t *device, buffer_handle_t bufferHandle) + { + auto adapter = getAdapter(device); + return ((*adapter).*member)(bufferHandle); + } + + // Buffer access functions + int32_t lock(buffer_handle_t bufferHandle, gralloc1_producer_usage_t producerUsage, + gralloc1_consumer_usage_t consumerUsage, const gralloc1_rect_t &accessRegion, + void **outData, int32_t acquireFence); + int32_t lockFlex(buffer_handle_t bufferHandle, gralloc1_producer_usage_t producerUsage, + gralloc1_consumer_usage_t consumerUsage, + const gralloc1_rect_t &accessRegion, struct android_flex_layout *outFlex, + int32_t acquireFence); + int32_t lockYCbCr(buffer_handle_t bufferHandle, gralloc1_producer_usage_t producerUsage, + gralloc1_consumer_usage_t consumerUsage, + const gralloc1_rect_t &accessRegion, struct android_ycbcr *outFlex, + int32_t acquireFence); + + template + static int32_t lockHook(gralloc1_device_t *device, buffer_handle_t bufferHandle, + uint64_t /*gralloc1_producer_usage_t*/ uintProducerUsage, + uint64_t /*gralloc1_consumer_usage_t*/ uintConsumerUsage, + const gralloc1_rect_t *accessRegion, OUT *outData, + int32_t acquireFenceFd) + { + auto adapter = getAdapter(device); + + // Exactly one of producer and consumer usage must be *_USAGE_NONE, + // but we can't check this until the upper levels of the framework + // correctly distinguish between producer and consumer usage + /* + bool hasProducerUsage = + uintProducerUsage != GRALLOC1_PRODUCER_USAGE_NONE; + bool hasConsumerUsage = + uintConsumerUsage != GRALLOC1_CONSUMER_USAGE_NONE; + if (hasProducerUsage && hasConsumerUsage || + !hasProducerUsage && !hasConsumerUsage) { + return static_cast(GRALLOC1_ERROR_BAD_VALUE); + } + */ + + auto producerUsage = static_cast(uintProducerUsage); + auto consumerUsage = static_cast(uintConsumerUsage); + + if (!outData) { + const auto producerCpuUsage = + GRALLOC1_PRODUCER_USAGE_CPU_READ | GRALLOC1_PRODUCER_USAGE_CPU_WRITE; + if (producerUsage & (producerCpuUsage != 0)) { + return CROS_GRALLOC_ERROR_BAD_VALUE; + } + if (consumerUsage & (GRALLOC1_CONSUMER_USAGE_CPU_READ != 0)) { + return CROS_GRALLOC_ERROR_BAD_VALUE; + } + } + + if (!accessRegion) { + drv_log("accessRegion is null"); + return CROS_GRALLOC_ERROR_BAD_VALUE; + } + + return ((*adapter).*member)(bufferHandle, producerUsage, consumerUsage, + *accessRegion, outData, acquireFenceFd); + } + + int32_t unlock(buffer_handle_t bufferHandle, int32_t *outReleaseFence); + static int32_t unlockHook(gralloc1_device_t *device, buffer_handle_t bufferHandle, + int32_t *outReleaseFenceFd) + { + auto adapter = getAdapter(device); + *outReleaseFenceFd = -1; + int32_t releaseFence; + auto error = adapter->unlock(bufferHandle, &releaseFence); + if (error == CROS_GRALLOC_ERROR_NONE && releaseFence > 0) { + *outReleaseFenceFd = dup(releaseFence); + } + return error; + } + + // Adapter internals + std::unique_ptr driver; +}; + +} // namespace android + +#endif From c1916351a094957fd48be5b7b07d919a9e26d9c0 Mon Sep 17 00:00:00 2001 From: renchenglei Date: Thu, 17 Dec 2020 02:34:21 +0800 Subject: [PATCH 234/269] INTERNAL: Add information required for media. --- cros_gralloc/cros_gralloc_handle.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/cros_gralloc/cros_gralloc_handle.h b/cros_gralloc/cros_gralloc_handle.h index c0fe2af..be9b1b9 100644 --- a/cros_gralloc/cros_gralloc_handle.h +++ b/cros_gralloc/cros_gralloc_handle.h @@ -47,6 +47,16 @@ struct cros_gralloc_handle { #ifdef USE_GRALLOC1 uint32_t consumer_usage; uint32_t producer_usage; + uint32_t yuv_color_range; // YUV Color range. + uint32_t is_updated; // frame updated flag + uint32_t is_encoded; // frame encoded flag + uint32_t is_encrypted; + uint32_t is_key_frame; + uint32_t is_interlaced; + uint32_t is_mmc_capable; + uint32_t compression_mode; + uint32_t compression_hint; + uint32_t codec; #endif } __attribute__((packed)); From 4aade8de189dc06baa5f06db2e3793896a28d367 Mon Sep 17 00:00:00 2001 From: renchenglei Date: Thu, 17 Dec 2020 03:15:51 +0800 Subject: [PATCH 235/269] INTERNAL: Add support to easily add new formats Camera, Media use cases seem to need lot of custom formats depending on hardware support. This patch squashes earlies work done for NV12, NV12 tiled etc into one and also makes it easy to isolate these custom formats into i915_private_* files, rather than spreading them over whole code base. --- Android.bp | 9 + cros_gralloc/cros_gralloc_driver.cc | 11 + cros_gralloc/cros_gralloc_helpers.cc | 16 ++ cros_gralloc/cros_gralloc_helpers.h | 1 + cros_gralloc/gralloc1/cros_gralloc1_module.cc | 97 ++++++--- cros_gralloc/i915_private_android.cc | 99 +++++++++ cros_gralloc/i915_private_android.h | 19 ++ cros_gralloc/i915_private_android_types.h | 59 ++++++ drv.c | 4 + helpers.c | 8 + i915.c | 25 +++ i915_private.c | 193 ++++++++++++++++++ i915_private.h | 30 +++ i915_private_types.h | 11 + 14 files changed, 558 insertions(+), 24 deletions(-) create mode 100644 cros_gralloc/i915_private_android.cc create mode 100644 cros_gralloc/i915_private_android.h create mode 100644 cros_gralloc/i915_private_android_types.h create mode 100644 i915_private.c create mode 100644 i915_private.h create mode 100644 i915_private_types.h diff --git a/Android.bp b/Android.bp index 72a1dfe..9ecd2e0 100644 --- a/Android.bp +++ b/Android.bp @@ -24,6 +24,7 @@ cc_defaults { "vc4.c", "vgem.c", "virtio_gpu.c", + "i915_private.c", ], cflags: [ @@ -38,6 +39,8 @@ cc_defaults { "-Wno-switch", "-Wno-format", "-Wno-unused-variable", + "-DDRV_I915", + "-DUSE_GRALLOC1", ], cppflags: ["-std=c++14"], @@ -79,10 +82,16 @@ cc_defaults { "cros_gralloc", ], + cflags: [ + "-DDRV_I915", + "-DUSE_GRALLOC1", + ], + srcs: [ "cros_gralloc/cros_gralloc_buffer.cc", "cros_gralloc/cros_gralloc_helpers.cc", "cros_gralloc/cros_gralloc_driver.cc", + "cros_gralloc/i915_private_android.cc", ] } diff --git a/cros_gralloc/cros_gralloc_driver.cc b/cros_gralloc/cros_gralloc_driver.cc index ba980b3..34673be 100644 --- a/cros_gralloc/cros_gralloc_driver.cc +++ b/cros_gralloc/cros_gralloc_driver.cc @@ -15,6 +15,10 @@ #include "../helpers.h" #include "../util.h" +#ifdef USE_GRALLOC1 +#include "i915_private_android.h" +#endif + cros_gralloc_driver::cros_gralloc_driver() : drv_(nullptr) { } @@ -222,6 +226,13 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto #ifdef USE_GRALLOC1 hnd->producer_usage = descriptor->producer_usage; hnd->consumer_usage = descriptor->consumer_usage; + int32_t format = i915_private_invert_format(hnd->format); + if (format == 0) { + format = descriptor->droid_format; + } + hnd->droid_format = format; +#else + hnd->droid_format = descriptor->droid_format; #endif hnd->total_size = descriptor->reserved_region_size + bo->meta.total_size; hnd->name_offset = handle_data_size; diff --git a/cros_gralloc/cros_gralloc_helpers.cc b/cros_gralloc/cros_gralloc_helpers.cc index f5fb9e9..6b8f5fc 100644 --- a/cros_gralloc/cros_gralloc_helpers.cc +++ b/cros_gralloc/cros_gralloc_helpers.cc @@ -8,6 +8,18 @@ #include +#ifdef USE_GRALLOC1 +#include "i915_private_android.h" +const char* drmFormat2Str(int drm_format) +{ + static char buf[5]; + char *pDrmFormat = (char*) &drm_format; + snprintf(buf, sizeof(buf), "%c%c%c%c", *pDrmFormat, *(pDrmFormat + 1), + *(pDrmFormat + 2), *(pDrmFormat + 3)); + return buf; +} +#endif + uint32_t cros_gralloc_convert_format(int format) { /* @@ -49,7 +61,11 @@ uint32_t cros_gralloc_convert_format(int format) #endif } +#ifdef USE_GRALLOC1 +return i915_private_convert_format(format); +#else return DRM_FORMAT_NONE; +#endif } cros_gralloc_handle_t cros_gralloc_convert_handle(buffer_handle_t handle) diff --git a/cros_gralloc/cros_gralloc_helpers.h b/cros_gralloc/cros_gralloc_helpers.h index 5d18282..f956bea 100644 --- a/cros_gralloc/cros_gralloc_helpers.h +++ b/cros_gralloc/cros_gralloc_helpers.h @@ -26,6 +26,7 @@ int32_t cros_gralloc_sync_wait(int32_t fence, bool close_fence); #ifdef USE_GRALLOC1 int32_t cros_gralloc_sync_wait(int32_t acquire_fence); +const char *drmFormat2Str(int format); #endif #endif diff --git a/cros_gralloc/gralloc1/cros_gralloc1_module.cc b/cros_gralloc/gralloc1/cros_gralloc1_module.cc index df29e22..34a024c 100644 --- a/cros_gralloc/gralloc1/cros_gralloc1_module.cc +++ b/cros_gralloc/gralloc1/cros_gralloc1_module.cc @@ -23,13 +23,17 @@ #include +#include "i915_private_android.h" + +#include "i915_private_android_types.h" + template static gralloc1_function_pointer_t asFP(T function) { static_assert(std::is_same::value, "Incompatible function pointer"); return reinterpret_cast(function); } -uint64_t cros_gralloc1_convert_flags(uint64_t producer_flags, uint64_t consumer_flags) +uint64_t cros_gralloc1_convert_usage(uint64_t producer_flags, uint64_t consumer_flags) { uint64_t usage = BO_USE_NONE; @@ -53,7 +57,7 @@ uint64_t cros_gralloc1_convert_flags(uint64_t producer_flags, uint64_t consumer_ usage |= BO_USE_CAMERA_READ; if (consumer_flags & GRALLOC1_CONSUMER_USAGE_RENDERSCRIPT) /* We use CPU for compute. */ - usage |= BO_USE_LINEAR; + usage |= BO_USE_RENDERSCRIPT; if (producer_flags & GRALLOC1_PRODUCER_USAGE_CPU_READ) usage |= BO_USE_SW_READ_RARELY; @@ -76,6 +80,44 @@ uint64_t cros_gralloc1_convert_flags(uint64_t producer_flags, uint64_t consumer_ return usage; } +uint64_t cros_gralloc1_convert_map_usage(uint64_t producer_flags, uint64_t consumer_flags) +{ + uint64_t usage = BO_USE_NONE; + + if (consumer_flags & GRALLOC1_CONSUMER_USAGE_CPU_READ) + usage |= BO_MAP_READ; + if (consumer_flags & GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN) + usage |= BO_MAP_READ; + if (consumer_flags & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER) + /*HACK: See b/30054495 */ + usage |= BO_MAP_READ; + + if (producer_flags & GRALLOC1_PRODUCER_USAGE_CPU_READ) + usage |= BO_MAP_READ; + if (producer_flags & GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN) + usage |= BO_MAP_READ; + if (producer_flags & GRALLOC1_PRODUCER_USAGE_CPU_WRITE) + usage |= BO_MAP_WRITE; + if (producer_flags & GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN) + usage |= BO_MAP_WRITE; + + return usage; +} + +bool IsSupportedYUVFormat(uint32_t droid_format) +{ + switch (droid_format) { + case HAL_PIXEL_FORMAT_YCbCr_420_888: + case HAL_PIXEL_FORMAT_YV12: + case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: + return true; + default: + return i915_private_supported_yuv_format(droid_format); + } + + return false; +} + namespace android { @@ -242,7 +284,7 @@ int32_t CrosGralloc1::allocate(struct cros_gralloc_buffer_descriptor *descriptor // pointer, which only occurs when mDevice has been loaded successfully and // we are permitted to allocate uint64_t usage = - cros_gralloc1_convert_flags(descriptor->producer_usage, descriptor->consumer_usage); + cros_gralloc1_convert_usage(descriptor->producer_usage, descriptor->consumer_usage); descriptor->use_flags = usage; bool supported = driver->is_supported(descriptor); if (!supported && (descriptor->consumer_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER)) { @@ -307,8 +349,7 @@ int32_t CrosGralloc1::lock(buffer_handle_t bufferHandle, gralloc1_producer_usage const gralloc1_rect_t &accessRegion, void **outData, int32_t acquireFence) { - int32_t ret; - uint64_t flags; + uint64_t map_flags; uint8_t *addr[DRV_MAX_PLANES]; auto hnd = cros_gralloc_convert_handle(bufferHandle); @@ -322,9 +363,9 @@ int32_t CrosGralloc1::lock(buffer_handle_t bufferHandle, gralloc1_producer_usage return CROS_GRALLOC_ERROR_BAD_HANDLE; } - flags = cros_gralloc1_convert_flags(producerUsage, consumerUsage); + map_flags = cros_gralloc1_convert_map_usage(producerUsage, consumerUsage); - if (driver->lock(bufferHandle, acquireFence, flags, addr)) + if (driver->lock(bufferHandle, acquireFence, map_flags, addr)) return CROS_GRALLOC_ERROR_BAD_HANDLE; *outData = addr[0]; @@ -336,19 +377,29 @@ android_flex_plane_t ycbcrplanes[3]; int32_t update_flex_layout(struct android_ycbcr *ycbcr, struct android_flex_layout *outFlexLayout) { - /*Need to add generic support*/ + outFlexLayout->format = FLEX_FORMAT_YCbCr; + outFlexLayout->num_planes = 3; + for (uint32_t i = 0; i < outFlexLayout->num_planes; i++) { + ycbcrplanes[i].bits_per_component = 8; + ycbcrplanes[i].bits_used = 8; + } + + ycbcrplanes[0].top_left = static_cast(ycbcr->y); ycbcrplanes[0].component = FLEX_COMPONENT_Y; - ycbcrplanes[0].top_left = (uint8_t *)ycbcr->y; - ycbcrplanes[0].h_increment = ycbcr->ystride; + ycbcrplanes[0].h_increment = 1; + ycbcrplanes[0].v_increment = static_cast(ycbcr->ystride); + + ycbcrplanes[1].top_left = static_cast(ycbcr->cb); ycbcrplanes[1].component = FLEX_COMPONENT_Cb; - ycbcrplanes[1].top_left = (uint8_t *)ycbcr->cb; - ycbcrplanes[1].h_increment = ycbcr->cstride; + ycbcrplanes[1].h_increment = static_cast(ycbcr->chroma_step); + ycbcrplanes[1].v_increment = static_cast(ycbcr->cstride); + + ycbcrplanes[2].top_left = static_cast(ycbcr->cr); ycbcrplanes[2].component = FLEX_COMPONENT_Cr; - ycbcrplanes[2].top_left = (uint8_t *)ycbcr->cr; - ycbcrplanes[2].h_increment = ycbcr->chroma_step; - outFlexLayout->format = FLEX_FORMAT_YCbCr; + ycbcrplanes[2].h_increment = static_cast(ycbcr->chroma_step); + ycbcrplanes[2].v_increment = static_cast(ycbcr->cstride); + outFlexLayout->planes = ycbcrplanes; - outFlexLayout->num_planes = 3; return 0; } @@ -368,8 +419,7 @@ int32_t CrosGralloc1::lockFlex(buffer_handle_t bufferHandle, return CROS_GRALLOC_ERROR_BAD_HANDLE; } - if ((hnd->droid_format != HAL_PIXEL_FORMAT_YCbCr_420_888) && - (hnd->droid_format != HAL_PIXEL_FORMAT_YV12)) { + if (!IsSupportedYUVFormat(hnd->droid_format)) { drv_log("lockFlex: Non-YUV format not compatible."); return CROS_GRALLOC_ERROR_BAD_HANDLE; } @@ -389,8 +439,7 @@ int32_t CrosGralloc1::lockYCbCr(buffer_handle_t bufferHandle, const gralloc1_rect_t &accessRegion, struct android_ycbcr *ycbcr, int32_t acquireFence) { - uint64_t flags; - int32_t ret; + uint64_t map_flags; uint8_t *addr[DRV_MAX_PLANES] = { nullptr, nullptr, nullptr, nullptr }; auto hnd = cros_gralloc_convert_handle(bufferHandle); @@ -399,18 +448,18 @@ int32_t CrosGralloc1::lockYCbCr(buffer_handle_t bufferHandle, return CROS_GRALLOC_ERROR_BAD_HANDLE; } - if ((hnd->droid_format != HAL_PIXEL_FORMAT_YCbCr_420_888) && - (hnd->droid_format != HAL_PIXEL_FORMAT_YV12)) { + if (!IsSupportedYUVFormat(hnd->droid_format)) { drv_log("Non-YUV format not compatible."); return CROS_GRALLOC_ERROR_BAD_HANDLE; } - flags = cros_gralloc1_convert_flags(producerUsage, consumerUsage); - if (driver->lock(bufferHandle, acquireFence, flags, addr)) + map_flags = cros_gralloc1_convert_map_usage(producerUsage, consumerUsage); + if (driver->lock(bufferHandle, acquireFence, map_flags, addr)) return CROS_GRALLOC_ERROR_BAD_HANDLE; switch (hnd->format) { case DRM_FORMAT_NV12: + case DRM_FORMAT_NV12_Y_TILED_INTEL: ycbcr->y = addr[0]; ycbcr->cb = addr[1]; ycbcr->cr = addr[1] + 1; diff --git a/cros_gralloc/i915_private_android.cc b/cros_gralloc/i915_private_android.cc new file mode 100644 index 0000000..334fb48 --- /dev/null +++ b/cros_gralloc/i915_private_android.cc @@ -0,0 +1,99 @@ +/* + * 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 "i915_private_android.h" +#include "i915_private_android_types.h" + +#include "cros_gralloc_helpers.h" + +#include + +#include "drv.h" + +uint32_t i915_private_convert_format(int format) +{ + switch (format) { + case HAL_PIXEL_FORMAT_NV12: + return DRM_FORMAT_NV12; + case HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL: + return DRM_FORMAT_NV12_Y_TILED_INTEL; + case HAL_PIXEL_FORMAT_YCbCr_422_I: + return DRM_FORMAT_YUYV; + case HAL_PIXEL_FORMAT_Y16: + return DRM_FORMAT_R16; + case HAL_PIXEL_FORMAT_YCbCr_444_888: + return DRM_FORMAT_YUV444; + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + return DRM_FORMAT_NV21; + case HAL_PIXEL_FORMAT_YCbCr_422_SP: + return DRM_FORMAT_NV16; + case HAL_PIXEL_FORMAT_YCbCr_422_888: + return DRM_FORMAT_YUV422; + } + + return DRM_FORMAT_NONE; +} + +int32_t i915_private_invert_format(int format) +{ + /* Convert the DRM FourCC into the most specific HAL pixel format. */ + switch (format) { + case DRM_FORMAT_ARGB8888: + return HAL_PIXEL_FORMAT_BGRA_8888; + case DRM_FORMAT_RGB565: + return HAL_PIXEL_FORMAT_RGB_565; + case DRM_FORMAT_RGB888: + return HAL_PIXEL_FORMAT_RGB_888; + case DRM_FORMAT_ABGR8888: + return HAL_PIXEL_FORMAT_RGBA_8888; + case DRM_FORMAT_XBGR8888: + return HAL_PIXEL_FORMAT_RGBX_8888; + case DRM_FORMAT_FLEX_YCbCr_420_888: + return HAL_PIXEL_FORMAT_YCbCr_420_888; + case DRM_FORMAT_YVU420_ANDROID: + return HAL_PIXEL_FORMAT_YV12; + case DRM_FORMAT_R8: + return HAL_PIXEL_FORMAT_BLOB; + case DRM_FORMAT_NV12: + return HAL_PIXEL_FORMAT_NV12; + case DRM_FORMAT_NV12_Y_TILED_INTEL: + return HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL; + case DRM_FORMAT_YUYV: + return HAL_PIXEL_FORMAT_YCbCr_422_I; + case DRM_FORMAT_R16: + return HAL_PIXEL_FORMAT_Y16; + case DRM_FORMAT_YUV444: + return HAL_PIXEL_FORMAT_YCbCr_444_888; + case DRM_FORMAT_NV21: + return HAL_PIXEL_FORMAT_YCrCb_420_SP; + case DRM_FORMAT_NV16: + return HAL_PIXEL_FORMAT_YCbCr_422_SP; + case DRM_FORMAT_YUV422: + return HAL_PIXEL_FORMAT_YCbCr_422_888; + default: + drv_log("Unhandled DRM format %4.4s", drmFormat2Str(format)); + } + + return 0; +} + +bool i915_private_supported_yuv_format(uint32_t droid_format) +{ + switch (droid_format) { + case HAL_PIXEL_FORMAT_NV12: + case HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL: + case HAL_PIXEL_FORMAT_YCbCr_422_I: + case HAL_PIXEL_FORMAT_YCbCr_422_888: + case HAL_PIXEL_FORMAT_YCbCr_444_888: + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + case HAL_PIXEL_FORMAT_Y16: + return true; + default: + return false; + } + + return false; +} diff --git a/cros_gralloc/i915_private_android.h b/cros_gralloc/i915_private_android.h new file mode 100644 index 0000000..ce35cbe --- /dev/null +++ b/cros_gralloc/i915_private_android.h @@ -0,0 +1,19 @@ +/* + * 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. + */ +#ifndef I915_PRIVATE_ANDROID +#define I915_PRIVATE_ANDROID + +#include + +#include "i915_private_types.h" + +uint32_t i915_private_convert_format(int format); + +int32_t i915_private_invert_format(int format); + +bool i915_private_supported_yuv_format(uint32_t droid_format); + +#endif diff --git a/cros_gralloc/i915_private_android_types.h b/cros_gralloc/i915_private_android_types.h new file mode 100644 index 0000000..57d9750 --- /dev/null +++ b/cros_gralloc/i915_private_android_types.h @@ -0,0 +1,59 @@ +/* + * 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. + */ +#ifndef I915_PRIVATE_ANDROID_TYPE +#define I915_PRIVATE_ANDROID_TYPE +/* + * Android graphics.h defines the formats and leaves 0x100 - 0x1FF + * range available for HAL implementation specific formats. + */ +enum { HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL = 0x100, + HAL_PIXEL_FORMAT_NV12_LINEAR_INTEL = 0x101, + HAL_PIXEL_FORMAT_YCrCb_422_H_INTEL = 0x102, + HAL_PIXEL_FORMAT_NV12_LINEAR_PACKED_INTEL = 0x103, + HAL_PIXEL_FORMAT_YCbCr_422_H_INTEL = 0x104, + HAL_PIXEL_FORMAT_NV12_X_TILED_INTEL = 0x105, + HAL_PIXEL_FORMAT_RGBA_5551_INTEL = 0x106, + HAL_PIXEL_FORMAT_RGBA_4444_INTEL = 0x107, + HAL_PIXEL_FORMAT_GENERIC_8BIT_INTEL = 0x108, + HAL_PIXEL_FORMAT_YCbCr_411_INTEL = 0x109, + HAL_PIXEL_FORMAT_YCbCr_420_H_INTEL = 0x10A, + HAL_PIXEL_FORMAT_YCbCr_422_V_INTEL = 0x10B, + HAL_PIXEL_FORMAT_YCbCr_444_INTEL = 0x10C, + HAL_PIXEL_FORMAT_RGBP_INTEL = 0x10D, + HAL_PIXEL_FORMAT_BGRP_INTEL = 0x10E, + HAL_PIXEL_FORMAT_NV12_LINEAR_CAMERA_INTEL = 0x10F, + HAL_PIXEL_FORMAT_P010_INTEL = 0x110, + HAL_PIXEL_FORMAT_Z16_INTEL = 0x111, + HAL_PIXEL_FORMAT_UVMAP64_INTEL = 0x112, + HAL_PIXEL_FORMAT_A2R10G10B10_INTEL = 0x113, + HAL_PIXEL_FORMAT_A2B10G10R10_INTEL = 0x114, + HAL_PIXEL_FORMAT_YCrCb_NORMAL_INTEL = 0x115, + HAL_PIXEL_FORMAT_YCrCb_SWAPUVY_INTEL = 0x116, + HAL_PIXEL_FORMAT_YCrCb_SWAPUV_INTEL = 0x117, + HAL_PIXEL_FORMAT_YCrCb_SWAPY_INTEL = 0x118, + HAL_PIXEL_FORMAT_X2R10G10B10_INTEL = 0x119, + HAL_PIXEL_FORMAT_X2B10G10R10_INTEL = 0x11A, + HAL_PIXEL_FORMAT_P016_INTEL = 0x11C, + HAL_PIXEL_FORMAT_Y210_INTEL = 0x11D, + HAL_PIXEL_FORMAT_Y216_INTEL = 0x11E, + HAL_PIXEL_FORMAT_Y410_INTEL = 0x11F, + HAL_PIXEL_FORMAT_Y416_INTEL = 0x120, + HAL_PIXEL_FORMAT_Y8I_INTEL = 0x121, + HAL_PIXEL_FORMAT_Y12I_INTEL = 0x122, + HAL_PIXEL_FORMAT_YUYV_INTEL = HAL_PIXEL_FORMAT_YCrCb_NORMAL_INTEL, + HAL_PIXEL_FORMAT_YUY2_INTEL = HAL_PIXEL_FORMAT_YCrCb_NORMAL_INTEL, + HAL_PIXEL_FORMAT_VYUY_INTEL = HAL_PIXEL_FORMAT_YCrCb_SWAPUVY_INTEL, + HAL_PIXEL_FORMAT_YVYU_INTEL = HAL_PIXEL_FORMAT_YCrCb_SWAPUV_INTEL, + HAL_PIXEL_FORMAT_UYVY_INTEL = HAL_PIXEL_FORMAT_YCrCb_SWAPY_INTEL, + HAL_PIXEL_FORMAT_NV12_TILED_INTEL = HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL, + HAL_PIXEL_FORMAT_NV12_INTEL = HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL, + HAL_PIXEL_FORMAT_INTEL_NV12 = HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL, + HAL_PIXEL_FORMAT_NV12 = 0x10F, + HAL_PIXEL_FORMAT_YUV420PackedSemiPlanar_INTEL = 0x7FA00E00, + HAL_PIXEL_FORMAT_YUV420PackedSemiPlanar_Tiled_INTEL = 0x7FA00F00, +}; + +#endif diff --git a/drv.c b/drv.c index 636cd07..3c1b236 100644 --- a/drv.c +++ b/drv.c @@ -25,6 +25,10 @@ #include "helpers.h" #include "util.h" +#ifdef USE_GRALLOC1 +#include "i915_private.h" +#endif + #ifdef DRV_AMDGPU extern const struct backend backend_amdgpu; #endif diff --git a/helpers.c b/helpers.c index 17b1765..6e56d6d 100644 --- a/helpers.c +++ b/helpers.c @@ -18,6 +18,10 @@ #include "helpers.h" #include "util.h" +#ifdef USE_GRALLOC1 +#include "i915_private.h" +#endif + struct planar_layout { size_t num_planes; int horizontal_subsampling[DRV_MAX_PLANES]; @@ -178,7 +182,11 @@ size_t drv_num_planes_from_format(uint32_t format) * format is supported and that the return value is non-NULL. */ +#ifdef USE_GRALLOC1 + return layout ? layout->num_planes : i915_private_num_planes_from_format(format); +#else return layout ? layout->num_planes : 0; +#endif } size_t drv_num_planes_from_modifier(struct driver *drv, uint32_t format, uint64_t modifier) diff --git a/i915.c b/i915.c index 92fd5b1..ecd9d97 100644 --- a/i915.c +++ b/i915.c @@ -20,6 +20,10 @@ #include "helpers.h" #include "util.h" +#ifdef USE_GRALLOC1 +#include "i915_private.h" +#endif + #define I915_CACHELINE_SIZE 64 #define I915_CACHELINE_MASK (I915_CACHELINE_SIZE - 1) @@ -37,6 +41,10 @@ static const uint32_t texture_only_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_NV12, struct i915_device { uint32_t gen; int32_t has_llc; +#ifdef USE_GRALLOC1 + uint64_t cursor_width; + uint64_t cursor_height; +#endif }; static uint32_t i915_get_gen(int device_id) @@ -133,6 +141,9 @@ static int i915_add_combinations(struct driver *drv) drv_add_combinations(drv, render_formats, ARRAY_SIZE(render_formats), &metadata, render); drv_add_combinations(drv, scanout_render_formats, ARRAY_SIZE(scanout_render_formats), &metadata, scanout_and_render); +#ifdef USE_GRALLOC1 + i915_private_add_combinations(drv); +#endif return 0; } @@ -173,6 +184,10 @@ static int i915_align_dimensions(struct bo *bo, uint32_t tiling, uint32_t *strid break; } +#ifdef USE_GRALLOC1 + i915_private_align_dimensions(bo->meta.format, &vertical_alignment); +#endif + *aligned_height = ALIGN(*aligned_height, vertical_alignment); if (i915->gen > 3) { *stride = ALIGN(*stride, horizontal_alignment); @@ -236,6 +251,10 @@ static int i915_init(struct driver *drv) drv->priv = i915; +#ifdef USE_GRALLOC1 + i915_private_init(drv, &i915->cursor_width, &i915->cursor_height); +#endif + return i915_add_combinations(drv); } @@ -528,6 +547,12 @@ static int i915_bo_flush(struct bo *bo, struct mapping *mapping) static uint32_t i915_resolve_format(struct driver *drv, uint32_t format, uint64_t use_flags) { +#ifdef USE_GRALLOC1 + uint32_t resolved_format; + if (i915_private_resolve_format(format, use_flags, &resolved_format)) { + return resolved_format; + } +#endif switch (format) { case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED: /* KBL camera subsystem requires NV12. */ diff --git a/i915_private.c b/i915_private.c new file mode 100644 index 0000000..14c52e9 --- /dev/null +++ b/i915_private.c @@ -0,0 +1,193 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include "drv_priv.h" +#include "helpers.h" +#include "util.h" +#include "i915_private.h" + +static const uint32_t private_linear_source_formats[] = { DRM_FORMAT_R16, DRM_FORMAT_NV16, + DRM_FORMAT_YUV420, DRM_FORMAT_YUV422, + DRM_FORMAT_YUV444, DRM_FORMAT_NV21 }; + +static const uint32_t private_source_formats[] = { DRM_FORMAT_NV12_Y_TILED_INTEL }; + +#if !defined(DRM_CAP_CURSOR_WIDTH) +#define DRM_CAP_CURSOR_WIDTH 0x8 +#endif + +#if !defined(DRM_CAP_CURSOR_HEIGHT) +#define DRM_CAP_CURSOR_HEIGHT 0x9 +#endif + +static const uint32_t kDefaultCursorWidth = 64; +static const uint32_t kDefaultCursorHeight = 64; + +#define BO_USE_CAMERA_MASK BO_USE_CAMERA_READ | BO_USE_SCANOUT | BO_USE_CAMERA_WRITE + +static void get_preferred_cursor_attributes(uint32_t drm_fd, uint64_t *cursor_width, + uint64_t *cursor_height) +{ + uint64_t width = 0, height = 0; + if (drmGetCap(drm_fd, DRM_CAP_CURSOR_WIDTH, &width)) { + fprintf(stderr, "cannot get cursor width. \n"); + } else if (drmGetCap(drm_fd, DRM_CAP_CURSOR_HEIGHT, &height)) { + fprintf(stderr, "cannot get cursor height. \n"); + } + + if (!width) + width = kDefaultCursorWidth; + + *cursor_width = width; + + if (!height) + height = kDefaultCursorHeight; + + *cursor_height = height; +} + +int i915_private_init(struct driver *drv, uint64_t *cursor_width, uint64_t *cursor_height) +{ + get_preferred_cursor_attributes(drv->fd, cursor_width, cursor_height); + return 0; +} + +int i915_private_add_combinations(struct driver *drv) +{ + struct format_metadata metadata; + uint64_t render_flags, texture_flags; + + render_flags = BO_USE_RENDER_MASK; + texture_flags = BO_USE_TEXTURE_MASK; + + metadata.tiling = I915_TILING_NONE; + metadata.priority = 1; + metadata.modifier = DRM_FORMAT_MOD_NONE; + + drv_modify_combination(drv, DRM_FORMAT_ABGR8888, &metadata, BO_USE_CURSOR | BO_USE_SCANOUT); + drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata, + BO_USE_RENDERING | BO_USE_TEXTURE | BO_USE_CAMERA_MASK); + drv_modify_combination(drv, DRM_FORMAT_YUYV, &metadata, + BO_USE_TEXTURE | BO_USE_CAMERA_MASK); + drv_modify_combination(drv, DRM_FORMAT_YVU420_ANDROID, &metadata, + BO_USE_TEXTURE | BO_USE_CAMERA_MASK); + + /* Media/Camera expect these formats support. */ + metadata.tiling = I915_TILING_NONE; + metadata.priority = 1; + metadata.modifier = DRM_FORMAT_MOD_NONE; + drv_add_combinations(drv, private_linear_source_formats, + ARRAY_SIZE(private_linear_source_formats), &metadata, + texture_flags | BO_USE_CAMERA_MASK); + + metadata.tiling = I915_TILING_Y; + metadata.priority = 3; + metadata.modifier = I915_FORMAT_MOD_Y_TILED; + drv_add_combinations(drv, private_source_formats, ARRAY_SIZE(private_source_formats), + &metadata, texture_flags | BO_USE_CAMERA_MASK); + + texture_flags &= ~BO_USE_RENDERSCRIPT; + texture_flags &= ~BO_USE_SW_WRITE_OFTEN; + texture_flags &= ~BO_USE_SW_READ_OFTEN; + texture_flags &= ~BO_USE_LINEAR; + + metadata.tiling = I915_TILING_X; + metadata.priority = 2; + metadata.modifier = I915_FORMAT_MOD_X_TILED; + + drv_add_combinations(drv, private_linear_source_formats, + ARRAY_SIZE(private_linear_source_formats), &metadata, + texture_flags | BO_USE_CAMERA_MASK); + + return 0; +} + +void i915_private_align_dimensions(uint32_t format, uint32_t *vertical_alignment) +{ + switch (format) { + case DRM_FORMAT_NV12_Y_TILED_INTEL: + *vertical_alignment = 64; + break; + } +} + +uint32_t i915_private_bpp_from_format(uint32_t format, size_t plane) +{ + assert(plane < drv_num_planes_from_format(format)); + + switch (format) { + case DRM_FORMAT_NV12_Y_TILED_INTEL: + return (plane == 0) ? 8 : 4; + case DRM_FORMAT_YUV420: + case DRM_FORMAT_YUV422: + case DRM_FORMAT_YUV444: + case DRM_FORMAT_NV16: + return 8; + case DRM_FORMAT_R16: + return 16; + } + + fprintf(stderr, "drv: UNKNOWN FORMAT %d\n", format); + return 0; +} + +void i915_private_vertical_subsampling_from_format(uint32_t *vertical_subsampling, uint32_t format, + size_t plane) +{ + switch (format) { + case DRM_FORMAT_NV12_Y_TILED_INTEL: + case DRM_FORMAT_YUV420: + *vertical_subsampling = (plane == 0) ? 1 : 2; + break; + default: + *vertical_subsampling = 1; + } +} + +size_t i915_private_num_planes_from_format(uint32_t format) +{ + switch (format) { + case DRM_FORMAT_R16: + return 1; + case DRM_FORMAT_NV12_Y_TILED_INTEL: + case DRM_FORMAT_NV16: + return 2; + case DRM_FORMAT_YUV420: + case DRM_FORMAT_YUV422: + case DRM_FORMAT_YUV444: + return 3; + } + + fprintf(stderr, "drv: UNKNOWN FORMAT %d\n", format); + return 0; +} + +uint32_t i915_private_resolve_format(uint32_t format, uint64_t usage, uint32_t *resolved_format) +{ + switch (format) { + case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED: + /* KBL camera subsystem requires NV12. */ + if (usage & (BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE)) { + *resolved_format = DRM_FORMAT_NV12; + return 1; + } + + if (usage & BO_USE_TEXTURE) { + *resolved_format = DRM_FORMAT_ABGR8888; + return 1; + } + } + + return 0; +} diff --git a/i915_private.h b/i915_private.h new file mode 100644 index 0000000..ccf1836 --- /dev/null +++ b/i915_private.h @@ -0,0 +1,30 @@ +/* + * 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. + */ +#ifndef I915_PRIVATE +#define I915_PRIVATE + +#include + +#include "i915_private_types.h" + +struct driver; + +int i915_private_init(struct driver *drv, uint64_t *cursor_width, uint64_t *cursor_height); + +int i915_private_add_combinations(struct driver *drv); + +void i915_private_align_dimensions(uint32_t format, uint32_t *vertical_alignment); + +uint32_t i915_private_bpp_from_format(uint32_t format, size_t plane); + +void i915_private_vertical_subsampling_from_format(uint32_t *vertical_subsampling, uint32_t format, + size_t plane); + +size_t i915_private_num_planes_from_format(uint32_t format); + +uint32_t i915_private_resolve_format(uint32_t format, uint64_t usage, uint32_t *resolved_format); + +#endif diff --git a/i915_private_types.h b/i915_private_types.h new file mode 100644 index 0000000..57d3ec4 --- /dev/null +++ b/i915_private_types.h @@ -0,0 +1,11 @@ +/* + * 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. + */ +#ifndef I915_PRIVATE_TYPES +#define I915_PRIVATE_TYPES + +#define DRM_FORMAT_NV12_Y_TILED_INTEL fourcc_code('9', '9', '9', '6') + +#endif From c759269e47a60211b5e2f956783c4b3d19287ebd Mon Sep 17 00:00:00 2001 From: renchenglei Date: Thu, 17 Dec 2020 05:07:51 +0800 Subject: [PATCH 236/269] INTERNAL: Add BO_USAGE_RENDERING to YUYV/VYUY formats This is needed for overlay input with YUYV/VYUY formats. --- i915_private.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/i915_private.c b/i915_private.c index 14c52e9..7980149 100644 --- a/i915_private.c +++ b/i915_private.c @@ -79,7 +79,13 @@ int i915_private_add_combinations(struct driver *drv) drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata, BO_USE_RENDERING | BO_USE_TEXTURE | BO_USE_CAMERA_MASK); drv_modify_combination(drv, DRM_FORMAT_YUYV, &metadata, - BO_USE_TEXTURE | BO_USE_CAMERA_MASK); + BO_USE_TEXTURE | BO_USE_CAMERA_MASK | BO_USE_RENDERING); + drv_modify_combination(drv, DRM_FORMAT_VYUY, &metadata, + BO_USE_TEXTURE | BO_USE_CAMERA_MASK | BO_USE_RENDERING); + drv_modify_combination(drv, DRM_FORMAT_UYVY, &metadata, + BO_USE_TEXTURE | BO_USE_CAMERA_MASK | BO_USE_RENDERING); + drv_modify_combination(drv, DRM_FORMAT_YVYU, &metadata, + BO_USE_TEXTURE | BO_USE_CAMERA_MASK | BO_USE_RENDERING); drv_modify_combination(drv, DRM_FORMAT_YVU420_ANDROID, &metadata, BO_USE_TEXTURE | BO_USE_CAMERA_MASK); From d19e06f9a90269d33f920e028d8216f2fcbcfa27 Mon Sep 17 00:00:00 2001 From: renchenglei Date: Thu, 17 Dec 2020 18:58:51 +0800 Subject: [PATCH 237/269] INTERNAL: Add P010 support --- cros_gralloc/i915_private_android.cc | 5 +++++ i915_private.c | 9 +++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/cros_gralloc/i915_private_android.cc b/cros_gralloc/i915_private_android.cc index 334fb48..f5d97c4 100644 --- a/cros_gralloc/i915_private_android.cc +++ b/cros_gralloc/i915_private_android.cc @@ -32,6 +32,8 @@ uint32_t i915_private_convert_format(int format) return DRM_FORMAT_NV16; case HAL_PIXEL_FORMAT_YCbCr_422_888: return DRM_FORMAT_YUV422; + case HAL_PIXEL_FORMAT_P010_INTEL: + return DRM_FORMAT_P010; } return DRM_FORMAT_NONE; @@ -65,6 +67,8 @@ int32_t i915_private_invert_format(int format) return HAL_PIXEL_FORMAT_YCbCr_422_I; case DRM_FORMAT_R16: return HAL_PIXEL_FORMAT_Y16; + case DRM_FORMAT_P010: + return HAL_PIXEL_FORMAT_P010_INTEL; case DRM_FORMAT_YUV444: return HAL_PIXEL_FORMAT_YCbCr_444_888; case DRM_FORMAT_NV21: @@ -90,6 +94,7 @@ bool i915_private_supported_yuv_format(uint32_t droid_format) case HAL_PIXEL_FORMAT_YCbCr_444_888: case HAL_PIXEL_FORMAT_YCrCb_420_SP: case HAL_PIXEL_FORMAT_Y16: + case HAL_PIXEL_FORMAT_P010_INTEL: return true; default: return false; diff --git a/i915_private.c b/i915_private.c index 7980149..b800d2b 100644 --- a/i915_private.c +++ b/i915_private.c @@ -19,9 +19,10 @@ static const uint32_t private_linear_source_formats[] = { DRM_FORMAT_R16, DRM_FORMAT_NV16, DRM_FORMAT_YUV420, DRM_FORMAT_YUV422, - DRM_FORMAT_YUV444, DRM_FORMAT_NV21 }; + DRM_FORMAT_YUV444, DRM_FORMAT_NV21, + DRM_FORMAT_P010 }; -static const uint32_t private_source_formats[] = { DRM_FORMAT_NV12_Y_TILED_INTEL }; +static const uint32_t private_source_formats[] = { DRM_FORMAT_P010, DRM_FORMAT_NV12_Y_TILED_INTEL }; #if !defined(DRM_CAP_CURSOR_WIDTH) #define DRM_CAP_CURSOR_WIDTH 0x8 @@ -135,6 +136,8 @@ uint32_t i915_private_bpp_from_format(uint32_t format, size_t plane) switch (format) { case DRM_FORMAT_NV12_Y_TILED_INTEL: return (plane == 0) ? 8 : 4; + case DRM_FORMAT_P010: + return (plane == 0) ? 16 : 8; case DRM_FORMAT_YUV420: case DRM_FORMAT_YUV422: case DRM_FORMAT_YUV444: @@ -154,6 +157,7 @@ void i915_private_vertical_subsampling_from_format(uint32_t *vertical_subsamplin switch (format) { case DRM_FORMAT_NV12_Y_TILED_INTEL: case DRM_FORMAT_YUV420: + case DRM_FORMAT_P010: *vertical_subsampling = (plane == 0) ? 1 : 2; break; default: @@ -168,6 +172,7 @@ size_t i915_private_num_planes_from_format(uint32_t format) return 1; case DRM_FORMAT_NV12_Y_TILED_INTEL: case DRM_FORMAT_NV16: + case DRM_FORMAT_P010: return 2; case DRM_FORMAT_YUV420: case DRM_FORMAT_YUV422: From 7a15f86e5fdf2105b40c8995c553d27e17f5bea9 Mon Sep 17 00:00:00 2001 From: renchenglei Date: Fri, 11 Dec 2020 07:47:42 +0800 Subject: [PATCH 238/269] INTERNAL: Fix errors after rebase. 1) Bring sizes field back to gralloc_handle for binary consistancy. 2) Add missing P010 changes. 3) Change Android.mk to add libnativewindow. Revert 1 once we have all dependent components re-compiled against the new version. --- cros_gralloc/gralloc1/cros_gralloc1_module.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cros_gralloc/gralloc1/cros_gralloc1_module.cc b/cros_gralloc/gralloc1/cros_gralloc1_module.cc index 34a024c..98b5b1c 100644 --- a/cros_gralloc/gralloc1/cros_gralloc1_module.cc +++ b/cros_gralloc/gralloc1/cros_gralloc1_module.cc @@ -476,6 +476,14 @@ int32_t CrosGralloc1::lockYCbCr(buffer_handle_t bufferHandle, ycbcr->cstride = hnd->strides[1]; ycbcr->chroma_step = 1; break; + case DRM_FORMAT_P010: + ycbcr->y = addr[0]; + ycbcr->cb = addr[1]; + ycbcr->cr = addr[1] + 2; + ycbcr->ystride = hnd->strides[0]; + ycbcr->cstride = hnd->strides[1]; + ycbcr->chroma_step = 4; + break; default: return CROS_GRALLOC_ERROR_UNSUPPORTED; } From f1edc3133368d008d2b38fc3cc725adeb9c1fe25 Mon Sep 17 00:00:00 2001 From: renchenglei Date: Thu, 17 Dec 2020 05:26:40 +0800 Subject: [PATCH 239/269] INTERNAL: Add API to set Modifier This will be needed to pass prefered modifier from user space and get rid of all custom enums we have. Also, would help enable RBC support. --- cros_gralloc/cros_gralloc_driver.cc | 10 ++++++++++ cros_gralloc/cros_gralloc_types.h | 1 + cros_gralloc/gralloc1/cros_gralloc1_module.cc | 13 +++++++++++-- cros_gralloc/gralloc1/cros_gralloc1_module.h | 7 +++++++ cros_gralloc/i915_private_android_types.h | 9 +++++++++ 5 files changed, 38 insertions(+), 2 deletions(-) diff --git a/cros_gralloc/cros_gralloc_driver.cc b/cros_gralloc/cros_gralloc_driver.cc index 34673be..68587cb 100644 --- a/cros_gralloc/cros_gralloc_driver.cc +++ b/cros_gralloc/cros_gralloc_driver.cc @@ -154,7 +154,17 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto use_flags &= ~BO_USE_HW_VIDEO_ENCODER; } +#ifdef USE_GRALLOC1 + if (descriptor->modifier == 0) { + bo = drv_bo_create(drv_, descriptor->width, descriptor->height, resolved_format, + use_flags); + } else { + bo = drv_bo_create_with_modifiers(drv_, descriptor->width, descriptor->height, + resolved_format, &descriptor->modifier, 1); + } +#else bo = drv_bo_create(drv_, descriptor->width, descriptor->height, resolved_format, use_flags); +#endif if (!bo) { drv_log("Failed to create bo.\n"); return -ENOMEM; diff --git a/cros_gralloc/cros_gralloc_types.h b/cros_gralloc/cros_gralloc_types.h index 8ea73e3..e51a075 100644 --- a/cros_gralloc/cros_gralloc_types.h +++ b/cros_gralloc/cros_gralloc_types.h @@ -21,6 +21,7 @@ struct cros_gralloc_buffer_descriptor { #ifdef USE_GRALLOC1 uint32_t consumer_usage; uint32_t producer_usage; + uint64_t modifier; #endif }; diff --git a/cros_gralloc/gralloc1/cros_gralloc1_module.cc b/cros_gralloc/gralloc1/cros_gralloc1_module.cc index 98b5b1c..c89d792 100644 --- a/cros_gralloc/gralloc1/cros_gralloc1_module.cc +++ b/cros_gralloc/gralloc1/cros_gralloc1_module.cc @@ -163,8 +163,8 @@ void CrosGralloc1::doGetCapabilities(uint32_t *outCount, int32_t *outCapabilitie gralloc1_function_pointer_t CrosGralloc1::doGetFunction(int32_t intDescriptor) { constexpr auto lastDescriptor = static_cast(GRALLOC1_LAST_FUNCTION); - if (intDescriptor < 0 || intDescriptor > lastDescriptor) { - drv_log("Invalid function descriptor"); + if (intDescriptor < 0 || ((intDescriptor > lastDescriptor) && ((intDescriptor < 100) || (intDescriptor > GRALLOC1_LAST_CUSTOM)))) { + drv_log("Invalid function descriptor %d", intDescriptor); return nullptr; } @@ -215,6 +215,8 @@ gralloc1_function_pointer_t CrosGralloc1::doGetFunction(int32_t intDescriptor) lockHook); case GRALLOC1_FUNCTION_UNLOCK: return asFP(unlockHook); + case GRALLOC1_FUNCTION_SET_MODIFIER: + return asFP(setModifierHook); case GRALLOC1_FUNCTION_INVALID: drv_log("Invalid function descriptor"); return nullptr; @@ -277,6 +279,13 @@ int32_t CrosGralloc1::setFormat(gralloc1_buffer_descriptor_t descriptorId, int32 return CROS_GRALLOC_ERROR_NONE; } +int32_t CrosGralloc1::setModifier(gralloc1_buffer_descriptor_t descriptorId, uint64_t modifier) +{ + auto hnd = (struct cros_gralloc_buffer_descriptor *)descriptorId; + hnd->modifier = modifier; + return CROS_GRALLOC_ERROR_NONE; +} + int32_t CrosGralloc1::allocate(struct cros_gralloc_buffer_descriptor *descriptor, buffer_handle_t *outBufferHandle) { diff --git a/cros_gralloc/gralloc1/cros_gralloc1_module.h b/cros_gralloc/gralloc1/cros_gralloc1_module.h index 09aff0b..35f5369 100644 --- a/cros_gralloc/gralloc1/cros_gralloc1_module.h +++ b/cros_gralloc/gralloc1/cros_gralloc1_module.h @@ -285,6 +285,13 @@ class CrosGralloc1 : public gralloc1_device_t return error; } + int32_t setModifier(gralloc1_buffer_descriptor_t descriptor, uint64_t modifier); + static int32_t setModifierHook(gralloc1_device_t *device, + gralloc1_buffer_descriptor_t descriptor, uint64_t modifier) + { + return getAdapter(device)->setModifier(descriptor, modifier); + } + // Adapter internals std::unique_ptr driver; }; diff --git a/cros_gralloc/i915_private_android_types.h b/cros_gralloc/i915_private_android_types.h index 57d9750..f75e084 100644 --- a/cros_gralloc/i915_private_android_types.h +++ b/cros_gralloc/i915_private_android_types.h @@ -9,6 +9,9 @@ * Android graphics.h defines the formats and leaves 0x100 - 0x1FF * range available for HAL implementation specific formats. */ + +#include + enum { HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL = 0x100, HAL_PIXEL_FORMAT_NV12_LINEAR_INTEL = 0x101, HAL_PIXEL_FORMAT_YCrCb_422_H_INTEL = 0x102, @@ -56,4 +59,10 @@ enum { HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL = 0x100, HAL_PIXEL_FORMAT_YUV420PackedSemiPlanar_Tiled_INTEL = 0x7FA00F00, }; +enum { GRALLOC1_FUNCTION_SET_MODIFIER = 101, + GRALLOC1_LAST_CUSTOM = 500 }; + +typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_SET_MODIFIER)( + gralloc1_device_t *device, gralloc1_buffer_descriptor_t descriptor, uint64_t modifier); + #endif From 531f6c12bd563fa779b27981ca914be783513e8d Mon Sep 17 00:00:00 2001 From: renchenglei Date: Thu, 17 Dec 2020 05:29:43 +0800 Subject: [PATCH 240/269] INTERNAL: Add support to query tiling mode --- cros_gralloc/cros_gralloc_driver.cc | 1 + cros_gralloc/cros_gralloc_handle.h | 1 + drv.c | 7 +++++++ drv.h | 4 ++++ 4 files changed, 13 insertions(+) diff --git a/cros_gralloc/cros_gralloc_driver.cc b/cros_gralloc/cros_gralloc_driver.cc index 68587cb..a4909c5 100644 --- a/cros_gralloc/cros_gralloc_driver.cc +++ b/cros_gralloc/cros_gralloc_driver.cc @@ -236,6 +236,7 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto #ifdef USE_GRALLOC1 hnd->producer_usage = descriptor->producer_usage; hnd->consumer_usage = descriptor->consumer_usage; + hnd->tiling_mode = drv_bo_get_stride_or_tiling(bo); int32_t format = i915_private_invert_format(hnd->format); if (format == 0) { format = descriptor->droid_format; diff --git a/cros_gralloc/cros_gralloc_handle.h b/cros_gralloc/cros_gralloc_handle.h index be9b1b9..be33bcd 100644 --- a/cros_gralloc/cros_gralloc_handle.h +++ b/cros_gralloc/cros_gralloc_handle.h @@ -57,6 +57,7 @@ struct cros_gralloc_handle { uint32_t compression_mode; uint32_t compression_hint; uint32_t codec; + uint32_t tiling_mode; #endif } __attribute__((packed)); diff --git a/drv.c b/drv.c index 3c1b236..c7c487a 100644 --- a/drv.c +++ b/drv.c @@ -729,3 +729,10 @@ int drv_resource_info(struct bo *bo, uint32_t strides[DRV_MAX_PLANES], return 0; } + +#ifdef USE_GRALLOC1 +uint32_t drv_bo_get_stride_or_tiling(struct bo *bo) +{ + return bo->meta.tiling ? bo->meta.tiling : drv_bo_get_plane_stride(bo, 0); +} +#endif diff --git a/drv.h b/drv.h index f19f9de..f1667bf 100644 --- a/drv.h +++ b/drv.h @@ -184,6 +184,10 @@ uint32_t drv_num_buffers_per_bo(struct bo *bo); int drv_resource_info(struct bo *bo, uint32_t strides[DRV_MAX_PLANES], uint32_t offsets[DRV_MAX_PLANES]); +#ifdef USE_GRALLOC1 +uint32_t drv_bo_get_stride_or_tiling(struct bo *bo); +#endif + #define drv_log(format, ...) \ do { \ drv_log_prefix("minigbm", __FILE__, __LINE__, format, ##__VA_ARGS__); \ From ee7ce53bfa281b8bd8e0f6d5180a71f1daaa973b Mon Sep 17 00:00:00 2001 From: renchenglei Date: Thu, 17 Dec 2020 05:31:13 +0800 Subject: [PATCH 241/269] INTERNAL: Remove the reject checking for HAL_PIXEL_FORMAT_YCbCr_420_888 This format is used in VTS tests VTS use it as default color format --- cros_gralloc/gralloc1/cros_gralloc1_module.cc | 5 ----- 1 file changed, 5 deletions(-) diff --git a/cros_gralloc/gralloc1/cros_gralloc1_module.cc b/cros_gralloc/gralloc1/cros_gralloc1_module.cc index c89d792..ca39beb 100644 --- a/cros_gralloc/gralloc1/cros_gralloc1_module.cc +++ b/cros_gralloc/gralloc1/cros_gralloc1_module.cc @@ -367,11 +367,6 @@ int32_t CrosGralloc1::lock(buffer_handle_t bufferHandle, gralloc1_producer_usage return CROS_GRALLOC_ERROR_BAD_HANDLE; } - if ((hnd->droid_format == HAL_PIXEL_FORMAT_YCbCr_420_888)) { - drv_log("HAL_PIXEL_FORMAT_YCbCr_*_888 format not compatible."); - return CROS_GRALLOC_ERROR_BAD_HANDLE; - } - map_flags = cros_gralloc1_convert_map_usage(producerUsage, consumerUsage); if (driver->lock(bufferHandle, acquireFence, map_flags, addr)) From 61c3593452a0193627881201df6d45c600953ea2 Mon Sep 17 00:00:00 2001 From: renchenglei Date: Thu, 17 Dec 2020 05:44:17 +0800 Subject: [PATCH 242/269] INTERNAL: Add getByteStride to support Media --- cros_gralloc/gralloc1/cros_gralloc1_module.cc | 22 +++++++++++++++++++ cros_gralloc/gralloc1/cros_gralloc1_module.h | 7 ++++++ cros_gralloc/i915_private_android_types.h | 4 ++++ 3 files changed, 33 insertions(+) diff --git a/cros_gralloc/gralloc1/cros_gralloc1_module.cc b/cros_gralloc/gralloc1/cros_gralloc1_module.cc index ca39beb..53deb0d 100644 --- a/cros_gralloc/gralloc1/cros_gralloc1_module.cc +++ b/cros_gralloc/gralloc1/cros_gralloc1_module.cc @@ -196,6 +196,8 @@ gralloc1_function_pointer_t CrosGralloc1::doGetFunction(int32_t intDescriptor) return asFP(getProducerUsageHook); case GRALLOC1_FUNCTION_GET_STRIDE: return asFP(getStrideHook); + case GRALLOC1_FUNCTION_GET_BYTE_STRIDE: + return asFP(getByteStrideHook); case GRALLOC1_FUNCTION_ALLOCATE: if (driver) { return asFP(allocateBuffers); @@ -587,6 +589,26 @@ int32_t CrosGralloc1::getStride(buffer_handle_t buffer, uint32_t *outStride) return CROS_GRALLOC_ERROR_NONE; } +int32_t CrosGralloc1::getByteStride(buffer_handle_t buffer, uint32_t *outStride, uint32_t size) +{ + auto hnd = cros_gralloc_convert_handle(buffer); + + if (!outStride) + return -EINVAL; + + if (!hnd) { + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + + if (size != drv_num_planes_from_format(hnd->format)) { + drv_log("Invalid array size- %d", size); + return -EINVAL; + } + + memcpy(outStride, hnd->strides, sizeof(*outStride) * size); + return CROS_GRALLOC_ERROR_NONE; +} + // static int CrosGralloc1::HookDevOpen(const struct hw_module_t *mod, const char *name, struct hw_device_t **device) diff --git a/cros_gralloc/gralloc1/cros_gralloc1_module.h b/cros_gralloc/gralloc1/cros_gralloc1_module.h index 35f5369..f05667e 100644 --- a/cros_gralloc/gralloc1/cros_gralloc1_module.h +++ b/cros_gralloc/gralloc1/cros_gralloc1_module.h @@ -191,6 +191,13 @@ class CrosGralloc1 : public gralloc1_device_t return getAdapter(device)->getStride(buffer, outStride); } + int32_t getByteStride(buffer_handle_t buffer, uint32_t *outStride, uint32_t size); + static int32_t getByteStrideHook(gralloc1_device_t *device, buffer_handle_t buffer, + uint32_t *outStride, uint32_t size) + { + return getAdapter(device)->getByteStride(buffer, outStride, size); + } + // Buffer Management functions int32_t allocate(struct cros_gralloc_buffer_descriptor *descriptor, buffer_handle_t *outBufferHandle); diff --git a/cros_gralloc/i915_private_android_types.h b/cros_gralloc/i915_private_android_types.h index f75e084..7748095 100644 --- a/cros_gralloc/i915_private_android_types.h +++ b/cros_gralloc/i915_private_android_types.h @@ -60,9 +60,13 @@ enum { HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL = 0x100, }; enum { GRALLOC1_FUNCTION_SET_MODIFIER = 101, + GRALLOC1_FUNCTION_GET_BYTE_STRIDE = 102, GRALLOC1_LAST_CUSTOM = 500 }; typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_SET_MODIFIER)( gralloc1_device_t *device, gralloc1_buffer_descriptor_t descriptor, uint64_t modifier); +typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_GET_BYTE_STRIDE)( + gralloc1_device_t *device, buffer_handle_t buffer, uint32_t *outStride, uint32_t size); + #endif From dec4fd77baff2b280dd5bcbb30942c08ff490268 Mon Sep 17 00:00:00 2001 From: renchenglei Date: Thu, 17 Dec 2020 05:53:25 +0800 Subject: [PATCH 243/269] INTERNAL: Fix format_modifiers not found in handle This is to help fix the building issues in IA HWC --- cros_gralloc/cros_gralloc_driver.cc | 8 ++++++++ cros_gralloc/cros_gralloc_handle.h | 1 + 2 files changed, 9 insertions(+) diff --git a/cros_gralloc/cros_gralloc_driver.cc b/cros_gralloc/cros_gralloc_driver.cc index a4909c5..2772d7d 100644 --- a/cros_gralloc/cros_gralloc_driver.cc +++ b/cros_gralloc/cros_gralloc_driver.cc @@ -120,6 +120,9 @@ int32_t create_reserved_region(const std::string &buffer_name, uint64_t reserved int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descriptor *descriptor, buffer_handle_t *out_handle) { +#ifdef USE_GRALLOC1 + uint64_t mod; +#endif uint32_t id; size_t num_planes; size_t num_fds; @@ -218,6 +221,11 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto 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); +#ifdef USE_GRALLOC1 + mod = drv_bo_get_plane_format_modifier(bo, plane); + hnd->format_modifiers[2 * plane] = static_cast(mod >> 32); + hnd->format_modifiers[2 * plane + 1] = static_cast(mod); +#endif } hnd->fds[hnd->num_planes] = reserved_region_fd; hnd->reserved_region_size = descriptor->reserved_region_size; diff --git a/cros_gralloc/cros_gralloc_handle.h b/cros_gralloc/cros_gralloc_handle.h index be33bcd..4c53899 100644 --- a/cros_gralloc/cros_gralloc_handle.h +++ b/cros_gralloc/cros_gralloc_handle.h @@ -58,6 +58,7 @@ struct cros_gralloc_handle { uint32_t compression_hint; uint32_t codec; uint32_t tiling_mode; + uint32_t format_modifiers[2 * DRV_MAX_PLANES]; #endif } __attribute__((packed)); From f5b23f3f77516f30cfc2dbb2b9faec0716b5bc76 Mon Sep 17 00:00:00 2001 From: renchenglei Date: Thu, 17 Dec 2020 05:58:09 +0800 Subject: [PATCH 244/269] INTERNAL: Add fourcc defines --- cros_gralloc/i915_private_android.h | 2 +- i915_private.h | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/cros_gralloc/i915_private_android.h b/cros_gralloc/i915_private_android.h index ce35cbe..70c41f2 100644 --- a/cros_gralloc/i915_private_android.h +++ b/cros_gralloc/i915_private_android.h @@ -8,7 +8,7 @@ #include -#include "i915_private_types.h" +#include "i915_private.h" uint32_t i915_private_convert_format(int format); diff --git a/i915_private.h b/i915_private.h index ccf1836..3eb89f6 100644 --- a/i915_private.h +++ b/i915_private.h @@ -12,6 +12,33 @@ struct driver; +/* + * 2 plane YCbCr MSB aligned + * index 0 = Y plane, [15:0] Y:x [10:6] little endian + * index 1 = Cr:Cb plane, [31:0] Cr:x:Cb:x [10:6:10:6] little endian + */ +#ifndef DRM_FORMAT_P010 +#define DRM_FORMAT_P010 fourcc_code('P', '0', '1', '0') /* 2x2 subsampled Cr:Cb plane 10 bits per channel */ +#endif + +/* + * 2 plane YCbCr MSB aligned + * index 0 = Y plane, [15:0] Y:x [12:4] little endian + * index 1 = Cr:Cb plane, [31:0] Cr:x:Cb:x [12:4:12:4] little endian + */ +#define DRM_FORMAT_P012 fourcc_code('P', '0', '1', '2') /* 2x2 subsampled Cr:Cb plane 12 bits per channel */ + +/* + * 2 plane YCbCr MSB aligned + * index 0 = Y plane, [15:0] Y little endian + * index 1 = Cr:Cb plane, [31:0] Cr:Cb [16:16] little endian + */ +#define DRM_FORMAT_P016 fourcc_code('P', '0', '1', '6') /* 2x2 subsampled Cr:Cb plane 16 bits per channel */ + +/* 64 bpp RGB */ +#define DRM_FORMAT_XRGB161616 fourcc_code('X', 'R', '4', '8') /* [63:0] x:R:G:B 16:16:16:16 little endian */ +#define DRM_FORMAT_XBGR161616 fourcc_code('X', 'B', '4', '8') /* [63:0] x:B:G:R 16:16:16:16 little endian */ + int i915_private_init(struct driver *drv, uint64_t *cursor_width, uint64_t *cursor_height); int i915_private_add_combinations(struct driver *drv); From 8c213d207c392763c480beb833071cc3cbed729c Mon Sep 17 00:00:00 2001 From: renchenglei Date: Thu, 17 Dec 2020 07:05:01 +0800 Subject: [PATCH 245/269] INTERNAL: Add getPrime API to support media --- cros_gralloc/gralloc1/cros_gralloc1_module.cc | 13 +++++++++++++ cros_gralloc/gralloc1/cros_gralloc1_module.h | 7 +++++++ cros_gralloc/i915_private_android_types.h | 4 ++++ 3 files changed, 24 insertions(+) diff --git a/cros_gralloc/gralloc1/cros_gralloc1_module.cc b/cros_gralloc/gralloc1/cros_gralloc1_module.cc index 53deb0d..3e51670 100644 --- a/cros_gralloc/gralloc1/cros_gralloc1_module.cc +++ b/cros_gralloc/gralloc1/cros_gralloc1_module.cc @@ -198,6 +198,8 @@ gralloc1_function_pointer_t CrosGralloc1::doGetFunction(int32_t intDescriptor) return asFP(getStrideHook); case GRALLOC1_FUNCTION_GET_BYTE_STRIDE: return asFP(getByteStrideHook); + case GRALLOC1_FUNCTION_GET_PRIME: + return asFP(getPrimeHook); case GRALLOC1_FUNCTION_ALLOCATE: if (driver) { return asFP(allocateBuffers); @@ -609,6 +611,17 @@ int32_t CrosGralloc1::getByteStride(buffer_handle_t buffer, uint32_t *outStride, return CROS_GRALLOC_ERROR_NONE; } +int32_t CrosGralloc1::getPrime(buffer_handle_t buffer, uint32_t *prime) +{ + auto hnd = cros_gralloc_convert_handle(buffer); + if (!hnd) { + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + + *prime = hnd->fds[0]; + return CROS_GRALLOC_ERROR_NONE; +} + // static int CrosGralloc1::HookDevOpen(const struct hw_module_t *mod, const char *name, struct hw_device_t **device) diff --git a/cros_gralloc/gralloc1/cros_gralloc1_module.h b/cros_gralloc/gralloc1/cros_gralloc1_module.h index f05667e..587d93b 100644 --- a/cros_gralloc/gralloc1/cros_gralloc1_module.h +++ b/cros_gralloc/gralloc1/cros_gralloc1_module.h @@ -198,6 +198,13 @@ class CrosGralloc1 : public gralloc1_device_t return getAdapter(device)->getByteStride(buffer, outStride, size); } + int32_t getPrime(buffer_handle_t buffer, uint32_t *prime); + static int32_t getPrimeHook(gralloc1_device_t *device, buffer_handle_t buffer, + uint32_t *prime) + { + return getAdapter(device)->getPrime(buffer, prime); + } + // Buffer Management functions int32_t allocate(struct cros_gralloc_buffer_descriptor *descriptor, buffer_handle_t *outBufferHandle); diff --git a/cros_gralloc/i915_private_android_types.h b/cros_gralloc/i915_private_android_types.h index 7748095..aeb9734 100644 --- a/cros_gralloc/i915_private_android_types.h +++ b/cros_gralloc/i915_private_android_types.h @@ -61,6 +61,7 @@ enum { HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL = 0x100, enum { GRALLOC1_FUNCTION_SET_MODIFIER = 101, GRALLOC1_FUNCTION_GET_BYTE_STRIDE = 102, + GRALLOC1_FUNCTION_GET_PRIME = 103, GRALLOC1_LAST_CUSTOM = 500 }; typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_SET_MODIFIER)( @@ -69,4 +70,7 @@ typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_SET_MODIFIER)( typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_GET_BYTE_STRIDE)( gralloc1_device_t *device, buffer_handle_t buffer, uint32_t *outStride, uint32_t size); +typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_GET_PRIME)( + gralloc1_device_t *device, buffer_handle_t buffer, uint32_t *prime); + #endif From 0c5a2aa8b5d2a55ff352704d49bb886d837d30ad Mon Sep 17 00:00:00 2001 From: renchenglei Date: Thu, 17 Dec 2020 07:14:06 +0800 Subject: [PATCH 246/269] INTERNAL: Add setInterlace and setProtectionInfo function SetInterface is used by MSDK for the interalce info of the buffer SetProtectionInfo is used by MSDK for protection info for the buffer union type added for protection info --- Android.bp | 1 + cros_gralloc/gralloc1/cros_gralloc1_module.cc | 24 +++++++++++++++++++ cros_gralloc/gralloc1/cros_gralloc1_module.h | 15 ++++++++++++ cros_gralloc/i915_private_android_types.h | 17 +++++++++++++ 4 files changed, 57 insertions(+) diff --git a/Android.bp b/Android.bp index 9ecd2e0..4aa6a22 100644 --- a/Android.bp +++ b/Android.bp @@ -41,6 +41,7 @@ cc_defaults { "-Wno-unused-variable", "-DDRV_I915", "-DUSE_GRALLOC1", + "-Wno-cast-qual", ], cppflags: ["-std=c++14"], diff --git a/cros_gralloc/gralloc1/cros_gralloc1_module.cc b/cros_gralloc/gralloc1/cros_gralloc1_module.cc index 3e51670..16257a8 100644 --- a/cros_gralloc/gralloc1/cros_gralloc1_module.cc +++ b/cros_gralloc/gralloc1/cros_gralloc1_module.cc @@ -221,6 +221,10 @@ gralloc1_function_pointer_t CrosGralloc1::doGetFunction(int32_t intDescriptor) return asFP(unlockHook); case GRALLOC1_FUNCTION_SET_MODIFIER: return asFP(setModifierHook); + case GRALLOC1_FUNCTION_SET_INTERLACE: + return asFP(setInterlaceHook); + case GRALLOC1_FUNCTION_SET_PROTECTIONINFO: + return asFP(setProtectionInfoHook); case GRALLOC1_FUNCTION_INVALID: drv_log("Invalid function descriptor"); return nullptr; @@ -290,6 +294,26 @@ int32_t CrosGralloc1::setModifier(gralloc1_buffer_descriptor_t descriptorId, uin return CROS_GRALLOC_ERROR_NONE; } +int32_t CrosGralloc1::setInterlace(buffer_handle_t buffer, uint32_t interlace) +{ + auto hnd = (cros_gralloc_handle*) cros_gralloc_convert_handle(buffer); + if (!hnd) { + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + hnd->is_interlaced = interlace; + return CROS_GRALLOC_ERROR_NONE; +} + +int32_t CrosGralloc1::setProtectionInfo(buffer_handle_t buffer, uint32_t protection_info) +{ + auto hnd = (cros_gralloc_handle*) cros_gralloc_convert_handle(buffer); + if (!hnd) { + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + hnd->is_encrypted = protection_info; + return CROS_GRALLOC_ERROR_NONE; +} + int32_t CrosGralloc1::allocate(struct cros_gralloc_buffer_descriptor *descriptor, buffer_handle_t *outBufferHandle) { diff --git a/cros_gralloc/gralloc1/cros_gralloc1_module.h b/cros_gralloc/gralloc1/cros_gralloc1_module.h index 587d93b..318b590 100644 --- a/cros_gralloc/gralloc1/cros_gralloc1_module.h +++ b/cros_gralloc/gralloc1/cros_gralloc1_module.h @@ -99,6 +99,9 @@ class CrosGralloc1 : public gralloc1_device_t int32_t setFormat(gralloc1_buffer_descriptor_t descriptorId, int32_t format); + int32_t setInterlace(buffer_handle_t buffer, uint32_t interlace); + int32_t setProtectionInfo(buffer_handle_t buffer, uint32_t protection_info); + int32_t createDescriptor(gralloc1_buffer_descriptor_t *outDescriptor); static int32_t createDescriptorHook(gralloc1_device_t *device, gralloc1_buffer_descriptor_t *outDescriptor) @@ -133,6 +136,18 @@ class CrosGralloc1 : public gralloc1_device_t return getAdapter(device)->setFormat(descriptorId, format); } + static int32_t setInterlaceHook(gralloc1_device_t *device, + buffer_handle_t buffer, uint32_t interlace) + { + return getAdapter(device)->setInterlace(buffer, interlace); + } + + static int32_t setProtectionInfoHook(gralloc1_device_t *device, + buffer_handle_t buffer, uint32_t protection_info) + { + return getAdapter(device)->setProtectionInfo(buffer, protection_info); + } + static int32_t setProducerUsageHook(gralloc1_device_t *device, gralloc1_buffer_descriptor_t descriptorId, uint64_t intUsage) diff --git a/cros_gralloc/i915_private_android_types.h b/cros_gralloc/i915_private_android_types.h index aeb9734..a7072d0 100644 --- a/cros_gralloc/i915_private_android_types.h +++ b/cros_gralloc/i915_private_android_types.h @@ -62,6 +62,8 @@ enum { HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL = 0x100, enum { GRALLOC1_FUNCTION_SET_MODIFIER = 101, GRALLOC1_FUNCTION_GET_BYTE_STRIDE = 102, GRALLOC1_FUNCTION_GET_PRIME = 103, + GRALLOC1_FUNCTION_SET_INTERLACE = 104, + GRALLOC1_FUNCTION_SET_PROTECTIONINFO = 105, GRALLOC1_LAST_CUSTOM = 500 }; typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_SET_MODIFIER)( @@ -73,4 +75,19 @@ typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_GET_BYTE_STRIDE)( typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_GET_PRIME)( gralloc1_device_t *device, buffer_handle_t buffer, uint32_t *prime); +typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_SET_INTERLACE)( + gralloc1_device_t *device, buffer_handle_t buffer, uint32_t interlace); + +typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_SET_PROTECTIONINFO)( + gralloc1_device_t *device, buffer_handle_t buffer, uint32_t protection_info); + +typedef union intel_protection_info_type_t { + uint32_t value; + struct { + uint32_t is_encrypted : 8; + uint32_t pavp_sesion_id : 8; + uint32_t pavp_instance_id: 16; + }; +}intel_protection_info_type_t; + #endif From aeb5cf5203480dd8b6601c8fbe03b689ac0e9111 Mon Sep 17 00:00:00 2001 From: renchenglei Date: Thu, 17 Dec 2020 07:16:42 +0800 Subject: [PATCH 247/269] INTERNAL: Yf tiled and Yf tiled CCS should be set Y Tile Otherwise it will cause sramble sceen issues in Android --- i915.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/i915.c b/i915.c index ecd9d97..c07941b 100644 --- a/i915.c +++ b/i915.c @@ -317,6 +317,10 @@ static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t heig break; case I915_FORMAT_MOD_Y_TILED: case I915_FORMAT_MOD_Y_TILED_CCS: +#ifdef USE_GRALLOC1 + case I915_FORMAT_MOD_Yf_TILED: + case I915_FORMAT_MOD_Yf_TILED_CCS: +#endif bo->meta.tiling = I915_TILING_Y; break; } From 7ff5a0cd4358edcc629f0dcbc8eef8d5ea97e12a Mon Sep 17 00:00:00 2001 From: renchenglei Date: Thu, 17 Dec 2020 07:18:38 +0800 Subject: [PATCH 248/269] INTERNAL: Mitigate GRALLOC1_PFN_LOCK_FLEX multithread issue lockFlex fills outFlexLayout->planes with pointer to global variable ycbcrplanes, doesn't work from multiple threads. Workaround: change the variable to thread_local. --- cros_gralloc/gralloc1/cros_gralloc1_module.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cros_gralloc/gralloc1/cros_gralloc1_module.cc b/cros_gralloc/gralloc1/cros_gralloc1_module.cc index 16257a8..d93bd65 100644 --- a/cros_gralloc/gralloc1/cros_gralloc1_module.cc +++ b/cros_gralloc/gralloc1/cros_gralloc1_module.cc @@ -405,7 +405,7 @@ int32_t CrosGralloc1::lock(buffer_handle_t bufferHandle, gralloc1_producer_usage return CROS_GRALLOC_ERROR_NONE; } -android_flex_plane_t ycbcrplanes[3]; +thread_local android_flex_plane_t ycbcrplanes[3]; int32_t update_flex_layout(struct android_ycbcr *ycbcr, struct android_flex_layout *outFlexLayout) { From dad3540293e10380d4bfd6099ed496b24501ac75 Mon Sep 17 00:00:00 2001 From: renchenglei Date: Thu, 17 Dec 2020 07:22:15 +0800 Subject: [PATCH 249/269] INTERNAL: Add mapper 2.1 functions support --- cros_gralloc/gralloc1/cros_gralloc1_module.cc | 77 +++++++++++++++++-- cros_gralloc/gralloc1/cros_gralloc1_module.h | 25 ++++++ 2 files changed, 96 insertions(+), 6 deletions(-) diff --git a/cros_gralloc/gralloc1/cros_gralloc1_module.cc b/cros_gralloc/gralloc1/cros_gralloc1_module.cc index d93bd65..4441411 100644 --- a/cros_gralloc/gralloc1/cros_gralloc1_module.cc +++ b/cros_gralloc/gralloc1/cros_gralloc1_module.cc @@ -225,6 +225,12 @@ gralloc1_function_pointer_t CrosGralloc1::doGetFunction(int32_t intDescriptor) return asFP(setInterlaceHook); case GRALLOC1_FUNCTION_SET_PROTECTIONINFO: return asFP(setProtectionInfoHook); + case GRALLOC1_FUNCTION_VALIDATE_BUFFER_SIZE: + return asFP(validateBufferSizeHook); + case GRALLOC1_FUNCTION_GET_TRANSPORT_SIZE: + return asFP(getTransportSizeHook); + case GRALLOC1_FUNCTION_IMPORT_BUFFER: + return asFP(importBufferHook); case GRALLOC1_FUNCTION_INVALID: drv_log("Invalid function descriptor"); return nullptr; @@ -306,12 +312,71 @@ int32_t CrosGralloc1::setInterlace(buffer_handle_t buffer, uint32_t interlace) int32_t CrosGralloc1::setProtectionInfo(buffer_handle_t buffer, uint32_t protection_info) { - auto hnd = (cros_gralloc_handle*) cros_gralloc_convert_handle(buffer); - if (!hnd) { - return CROS_GRALLOC_ERROR_BAD_HANDLE; - } - hnd->is_encrypted = protection_info; - return CROS_GRALLOC_ERROR_NONE; + auto hnd = (cros_gralloc_handle *)cros_gralloc_convert_handle(buffer); + if (!hnd) { + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + hnd->is_encrypted = protection_info; + return CROS_GRALLOC_ERROR_NONE; +} + +int32_t CrosGralloc1::validateBufferSize(buffer_handle_t buffer, + const gralloc1_buffer_descriptor_info_t *descriptorInfo, + uint32_t stride) +{ + auto hnd = (cros_gralloc_handle *)cros_gralloc_convert_handle(buffer); + if (!hnd) { + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + + if (cros_gralloc_convert_format(descriptorInfo->format) != hnd->format) { + return CROS_GRALLOC_ERROR_BAD_VALUE; + } + + // Do not support GRALLOC1_CAPABILITY_LAYERED_BUFFERS, only allocate buffers with a + // single layer. + if (descriptorInfo->layerCount != 1) { + return CROS_GRALLOC_ERROR_BAD_VALUE; + } + if (stride > hnd->pixel_stride || descriptorInfo->width > hnd->width || + descriptorInfo->height > hnd->height) { + return CROS_GRALLOC_ERROR_BAD_VALUE; + } + return CROS_GRALLOC_ERROR_NONE; +} + +int32_t CrosGralloc1::getTransportSize(buffer_handle_t buffer, uint32_t *outNumFds, + uint32_t *outNumInts) +{ + auto hnd = (cros_gralloc_handle *)cros_gralloc_convert_handle(buffer); + if (!hnd) { + return CROS_GRALLOC_ERROR_BAD_HANDLE; + } + *outNumFds = hnd->base.numFds; + *outNumInts = hnd->base.numInts; + return CROS_GRALLOC_ERROR_NONE; +} + +int32_t CrosGralloc1::importBuffer(const buffer_handle_t rawHandle, buffer_handle_t *outBuffer) +{ + if (!rawHandle) { + *outBuffer = NULL; + return GRALLOC1_ERROR_BAD_HANDLE; + } + buffer_handle_t buffer_handle = native_handle_clone(rawHandle); + if (!buffer_handle) { + *outBuffer = NULL; + return GRALLOC1_ERROR_NO_RESOURCES; + } + auto error = retain(buffer_handle); + if (error != GRALLOC1_ERROR_NONE) { + delete buffer_handle; + *outBuffer = NULL; + return error; + } + + *outBuffer = buffer_handle; + return GRALLOC1_ERROR_NONE; } int32_t CrosGralloc1::allocate(struct cros_gralloc_buffer_descriptor *descriptor, diff --git a/cros_gralloc/gralloc1/cros_gralloc1_module.h b/cros_gralloc/gralloc1/cros_gralloc1_module.h index 318b590..247b456 100644 --- a/cros_gralloc/gralloc1/cros_gralloc1_module.h +++ b/cros_gralloc/gralloc1/cros_gralloc1_module.h @@ -191,6 +191,31 @@ class CrosGralloc1 : public gralloc1_device_t return getAdapter(device)->getFormat(buffer, outFormat); } + int32_t validateBufferSize(buffer_handle_t buffer, + const gralloc1_buffer_descriptor_info_t *descriptorInfo, + uint32_t stride); + static int32_t + validateBufferSizeHook(gralloc1_device_t *device, buffer_handle_t buffer, + const gralloc1_buffer_descriptor_info_t *descriptorInfo, + uint32_t stride) + { + return getAdapter(device)->validateBufferSize(buffer, descriptorInfo, stride); + } + + int32_t getTransportSize(buffer_handle_t buffer, uint32_t *outNumFds, uint32_t *outNumInts); + static int32_t getTransportSizeHook(gralloc1_device_t *device, buffer_handle_t buffer, + uint32_t *outNumFds, uint32_t *outNumInts) + { + return getAdapter(device)->getTransportSize(buffer, outNumFds, outNumInts); + } + + int32_t importBuffer(const buffer_handle_t rawHandle, buffer_handle_t *outBuffer); + static int32_t importBufferHook(gralloc1_device_t *device, const buffer_handle_t rawHandle, + buffer_handle_t *outBuffer) + { + return getAdapter(device)->importBuffer(rawHandle, outBuffer); + } + int32_t getProducerUsage(buffer_handle_t buffer, uint64_t * /*gralloc1_producer_usage_t*/ outUsage); static int32_t getProducerUsageHook(gralloc1_device_t *device, buffer_handle_t buffer, From 4fe7fe747c8971102e83eaef79989e6a5c8c04ae Mon Sep 17 00:00:00 2001 From: renchenglei Date: Thu, 17 Dec 2020 07:26:09 +0800 Subject: [PATCH 250/269] INTERNAL: Add the flex format check --- cros_gralloc/cros_gralloc_helpers.cc | 12 ++++++++++++ cros_gralloc/cros_gralloc_helpers.h | 1 + cros_gralloc/gralloc1/cros_gralloc1_module.cc | 3 ++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/cros_gralloc/cros_gralloc_helpers.cc b/cros_gralloc/cros_gralloc_helpers.cc index 6b8f5fc..a23585c 100644 --- a/cros_gralloc/cros_gralloc_helpers.cc +++ b/cros_gralloc/cros_gralloc_helpers.cc @@ -18,6 +18,18 @@ const char* drmFormat2Str(int drm_format) *(pDrmFormat + 2), *(pDrmFormat + 3)); return buf; } + +bool is_flex_format(uint32_t format) +{ + switch (format) { + case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED: + case DRM_FORMAT_FLEX_YCbCr_420_888: + return true; + default: + return false; + } + return false; +} #endif uint32_t cros_gralloc_convert_format(int format) diff --git a/cros_gralloc/cros_gralloc_helpers.h b/cros_gralloc/cros_gralloc_helpers.h index f956bea..abd3431 100644 --- a/cros_gralloc/cros_gralloc_helpers.h +++ b/cros_gralloc/cros_gralloc_helpers.h @@ -27,6 +27,7 @@ int32_t cros_gralloc_sync_wait(int32_t fence, bool close_fence); #ifdef USE_GRALLOC1 int32_t cros_gralloc_sync_wait(int32_t acquire_fence); const char *drmFormat2Str(int format); +bool is_flex_format(uint32_t format); #endif #endif diff --git a/cros_gralloc/gralloc1/cros_gralloc1_module.cc b/cros_gralloc/gralloc1/cros_gralloc1_module.cc index 4441411..3a38f2b 100644 --- a/cros_gralloc/gralloc1/cros_gralloc1_module.cc +++ b/cros_gralloc/gralloc1/cros_gralloc1_module.cc @@ -329,7 +329,8 @@ int32_t CrosGralloc1::validateBufferSize(buffer_handle_t buffer, return CROS_GRALLOC_ERROR_BAD_HANDLE; } - if (cros_gralloc_convert_format(descriptorInfo->format) != hnd->format) { + if (!is_flex_format(cros_gralloc_convert_format(descriptorInfo->format)) && + cros_gralloc_convert_format(descriptorInfo->format) != hnd->format) { return CROS_GRALLOC_ERROR_BAD_VALUE; } From ed6a8cef676cca1d784adeb6f72d7eed07fb2eed Mon Sep 17 00:00:00 2001 From: renchenglei Date: Sat, 26 Dec 2020 23:04:11 +0800 Subject: [PATCH 251/269] INTERNAL: Fix lockFlex issues We allocate buffer by using allocate4, but lockFlex is called by gralloc1. Bufore we use buffer, we need retain/release. --- cros_gralloc/gralloc1/cros_gralloc1_module.cc | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/cros_gralloc/gralloc1/cros_gralloc1_module.cc b/cros_gralloc/gralloc1/cros_gralloc1_module.cc index 3a38f2b..3df2224 100644 --- a/cros_gralloc/gralloc1/cros_gralloc1_module.cc +++ b/cros_gralloc/gralloc1/cros_gralloc1_module.cc @@ -552,8 +552,20 @@ int32_t CrosGralloc1::lockYCbCr(buffer_handle_t bufferHandle, } map_flags = cros_gralloc1_convert_map_usage(producerUsage, consumerUsage); - if (driver->lock(bufferHandle, acquireFence, map_flags, addr)) - return CROS_GRALLOC_ERROR_BAD_HANDLE; + + if (driver->lock(bufferHandle, acquireFence, map_flags, addr)) { + buffer_handle_t buffer_handle = native_handle_clone(bufferHandle); + auto error = retain(buffer_handle); + if (error != GRALLOC1_ERROR_NONE) { + delete buffer_handle; + return error; + } + bufferHandle = buffer_handle; + if (driver->lock(bufferHandle, acquireFence, map_flags, addr)) + return CROS_GRALLOC_ERROR_BAD_HANDLE; + driver->release(buffer_handle); + delete buffer_handle; + } switch (hnd->format) { case DRM_FORMAT_NV12: From 58f2ab11a7cfa20db6046cb8fb9bd4c8d4e589c5 Mon Sep 17 00:00:00 2001 From: renchenglei Date: Sat, 26 Dec 2020 23:26:25 +0800 Subject: [PATCH 252/269] INTERNAL: Add Intel private video format support Add NV12_Y_TILED_INTEL video format support --- cros_gralloc/gralloc4/Android.bp | 2 ++ cros_gralloc/gralloc4/CrosGralloc4Mapper.cc | 7 ++++- cros_gralloc/gralloc4/CrosGralloc4Utils.cc | 34 ++++++++++++++++++++- helpers.c | 3 ++ 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/cros_gralloc/gralloc4/Android.bp b/cros_gralloc/gralloc4/Android.bp index 50075b9..223ef80 100644 --- a/cros_gralloc/gralloc4/Android.bp +++ b/cros_gralloc/gralloc4/Android.bp @@ -23,6 +23,7 @@ cc_binary { cflags: [ "-Wall", "-Werror", + "-DUSE_GRALLOC1", ], shared_libs: [ @@ -57,6 +58,7 @@ cc_library_shared { cflags: [ "-Wall", "-Werror", + "-DUSE_GRALLOC1", ], shared_libs: [ diff --git a/cros_gralloc/gralloc4/CrosGralloc4Mapper.cc b/cros_gralloc/gralloc4/CrosGralloc4Mapper.cc index 47e24ac..8314266 100644 --- a/cros_gralloc/gralloc4/CrosGralloc4Mapper.cc +++ b/cros_gralloc/gralloc4/CrosGralloc4Mapper.cc @@ -145,8 +145,13 @@ Return CrosGralloc4Mapper::validateBufferSize(void* rawHandle, } PixelFormat crosHandleFormat = static_cast(crosHandle->droid_format); - if (descriptor.format != crosHandleFormat) { +#ifdef USE_GRALLOC1 + int32_t yuvFormat = static_cast(descriptor.format); + if (descriptor.format != crosHandleFormat && yuvFormat != crosHandle->droid_format) { drv_log("Failed to validateBufferSize. Format mismatch.\n"); +#else + if (descriptor.format != crosHandleFormat) { +#endif return Error::BAD_BUFFER; } diff --git a/cros_gralloc/gralloc4/CrosGralloc4Utils.cc b/cros_gralloc/gralloc4/CrosGralloc4Utils.cc index 8931164..eba596f 100644 --- a/cros_gralloc/gralloc4/CrosGralloc4Utils.cc +++ b/cros_gralloc/gralloc4/CrosGralloc4Utils.cc @@ -18,6 +18,10 @@ #include "cros_gralloc/cros_gralloc_helpers.h" +#ifdef USE_GRALLOC1 +#include "cros_gralloc/i915_private_android.h" +#endif + using aidl::android::hardware::graphics::common::PlaneLayout; using aidl::android::hardware::graphics::common::PlaneLayoutComponent; using aidl::android::hardware::graphics::common::PlaneLayoutComponentType; @@ -415,6 +419,23 @@ int convertToBufferUsage(uint64_t grallocUsage, uint64_t* outBufferUsage) { return 0; } +#ifdef USE_GRALLOC1 +bool IsSupportedYUVFormat(uint32_t droid_format) { + + switch (droid_format) { + case HAL_PIXEL_FORMAT_YCbCr_420_888: + case HAL_PIXEL_FORMAT_YV12: + case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: + return true; + default: + return i915_private_supported_yuv_format(droid_format); + } + + return false; +} + +#endif + int convertToCrosDescriptor(const BufferDescriptorInfo& descriptor, struct cros_gralloc_buffer_descriptor* outCrosDescriptor) { outCrosDescriptor->name = descriptor.name; @@ -425,9 +446,20 @@ int convertToCrosDescriptor(const BufferDescriptorInfo& descriptor, outCrosDescriptor->reserved_region_size = descriptor.reservedSize; if (convertToDrmFormat(descriptor.format, &outCrosDescriptor->drm_format)) { +#ifdef USE_GRALLOC1 + drv_log("Failed to convert descriptor by convertToDrmFormat"); + if (!IsSupportedYUVFormat(static_cast(descriptor.format))) { + std::string pixelFormatString = getPixelFormatString(descriptor.format); + drv_log("Failed to convert descriptor. Unsupported fomat %s\n", pixelFormatString.c_str()); + return -1; + } else { + outCrosDescriptor->drm_format = cros_gralloc_convert_format(static_cast(descriptor.format)); + } +#else std::string pixelFormatString = getPixelFormatString(descriptor.format); drv_log("Failed to convert descriptor. Unsupported fomat %s\n", pixelFormatString.c_str()); return -1; +#endif } if (convertToBufferUsage(descriptor.usage, &outCrosDescriptor->use_flags)) { std::string usageString = getUsageString(descriptor.usage); @@ -769,4 +801,4 @@ int getPlaneLayouts(uint32_t drmFormat, std::vector* outPlaneLayout *outPlaneLayouts = it->second; return 0; -} \ No newline at end of file +} diff --git a/helpers.c b/helpers.c index 6e56d6d..f648d5a 100644 --- a/helpers.c +++ b/helpers.c @@ -107,6 +107,9 @@ static const struct planar_layout *layout_from_format(uint32_t format) case DRM_FORMAT_NV12: case DRM_FORMAT_NV21: +#ifdef USE_GRALLOC1 + case DRM_FORMAT_NV12_Y_TILED_INTEL: +#endif return &biplanar_yuv_420_layout; case DRM_FORMAT_P010: From 337832b55855858e8a2ed43851d90832e2c0fbbd Mon Sep 17 00:00:00 2001 From: renchenglei Date: Sat, 26 Dec 2020 23:29:17 +0800 Subject: [PATCH 253/269] INTERNAL: Fix non 1080P video green issue on bottom We use one wrong align heigh for NV12_Y_TILED_INTEL video format. Fix this issue with this changes. --- cros_gralloc/cros_gralloc_driver.cc | 1 - i915.c | 4 ---- 2 files changed, 5 deletions(-) diff --git a/cros_gralloc/cros_gralloc_driver.cc b/cros_gralloc/cros_gralloc_driver.cc index 2772d7d..271347a 100644 --- a/cros_gralloc/cros_gralloc_driver.cc +++ b/cros_gralloc/cros_gralloc_driver.cc @@ -239,7 +239,6 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto bytes_per_pixel = drv_bytes_per_pixel_from_format(hnd->format, 0); hnd->pixel_stride = DIV_ROUND_UP(hnd->strides[0], bytes_per_pixel); hnd->magic = cros_gralloc_magic; - hnd->droid_format = descriptor->droid_format; hnd->usage = descriptor->droid_usage; #ifdef USE_GRALLOC1 hnd->producer_usage = descriptor->producer_usage; diff --git a/i915.c b/i915.c index c07941b..9d25328 100644 --- a/i915.c +++ b/i915.c @@ -184,10 +184,6 @@ static int i915_align_dimensions(struct bo *bo, uint32_t tiling, uint32_t *strid break; } -#ifdef USE_GRALLOC1 - i915_private_align_dimensions(bo->meta.format, &vertical_alignment); -#endif - *aligned_height = ALIGN(*aligned_height, vertical_alignment); if (i915->gen > 3) { *stride = ALIGN(*stride, horizontal_alignment); From 530ea58fe069df8cb8bc77d95ee733a7949aa974 Mon Sep 17 00:00:00 2001 From: "Yang, Dong" Date: Wed, 30 Dec 2020 12:32:09 +0800 Subject: [PATCH 254/269] INTERNAL: add more usage flag for DRM_FORMAT_ABGR2101010 The DRM_FORMAT_ABGR2101010 format will be used by Android Media framework for software codec of AV1Hdr, and the usage flag request as: BO_USE_SW_READ_RARELY BO_USE_SW_READ_OFTEN BO_USE_SW_WRITE_RARELY BO_USE_SW_WRITE_OFTEN Tracked-On: OAM-95578 Signed-off-by: Yang, Dong --- i915.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/i915.c b/i915.c index 9d25328..243970c 100644 --- a/i915.c +++ b/i915.c @@ -101,6 +101,9 @@ static int i915_add_combinations(struct driver *drv) /* Android CTS tests require this. */ drv_add_combination(drv, DRM_FORMAT_BGR888, &metadata, BO_USE_SW_MASK); +#ifdef USE_GRALLOC1 + drv_modify_combination(drv, DRM_FORMAT_ABGR2101010, &metadata, BO_USE_SW_MASK); +#endif /* * R8 format is used for Android's HAL_PIXEL_FORMAT_BLOB and is used for JPEG snapshots From 8af45a3f4fd78793a11637bf39a12f814140282d Mon Sep 17 00:00:00 2001 From: renchenglei Date: Wed, 30 Dec 2020 23:40:15 +0800 Subject: [PATCH 255/269] INTERNAL: Fix HWC crash issue when playing video on GVT-d Add YUYV format for 264 video which is used by HWC. Align 263 video with 64, if we use 32, we may encounter VA create surface failures in HWC. Tracked-On: OAM-95589 Signed-off-by: Ren Chenglei --- i915.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/i915.c b/i915.c index 243970c..0d0e637 100644 --- a/i915.c +++ b/i915.c @@ -36,7 +36,12 @@ static const uint32_t scanout_render_formats[] = { DRM_FORMAT_ABGR2101010, DRM_F static const uint32_t render_formats[] = { DRM_FORMAT_ABGR16161616F }; static const uint32_t texture_only_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_NV12, DRM_FORMAT_P010, +#ifdef USE_GRALLOC1 + DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID, + DRM_FORMAT_YUYV }; +#else DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID }; +#endif struct i915_device { uint32_t gen; @@ -335,7 +340,11 @@ static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t heig * ALIGN(Y_stride / 2, 16), which we can make happen by * aligning to 32 bytes here. */ +#ifdef USE_GRALLOC1 + uint32_t stride = ALIGN(width, 64); +#else uint32_t stride = ALIGN(width, 32); +#endif drv_bo_from_format(bo, stride, height, format); } else if (modifier == I915_FORMAT_MOD_Y_TILED_CCS) { /* From 5af42ff565ccb99de1b2a5127b4450ffca74f87b Mon Sep 17 00:00:00 2001 From: renchenglei Date: Wed, 30 Dec 2020 23:48:49 +0800 Subject: [PATCH 256/269] UPSTREAM: Fix PlaneLayout width/height metadata Fix PlaneLayout width/height metadata by using the horizontal/vertical subsampling of each plane. TEST=vts -m VtsHalGraphicsMapperV4_0TargetTest Tracked-On: OAM-95590 Signed-off-by: ason Macnak --- cros_gralloc/gralloc4/CrosGralloc4Mapper.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cros_gralloc/gralloc4/CrosGralloc4Mapper.cc b/cros_gralloc/gralloc4/CrosGralloc4Mapper.cc index 8314266..3815ffe 100644 --- a/cros_gralloc/gralloc4/CrosGralloc4Mapper.cc +++ b/cros_gralloc/gralloc4/CrosGralloc4Mapper.cc @@ -502,8 +502,8 @@ Return CrosGralloc4Mapper::get(cros_gralloc_handle_t crosHandle, planeLayout.offsetInBytes = crosHandle->offsets[plane]; planeLayout.strideInBytes = crosHandle->strides[plane]; planeLayout.totalSizeInBytes = crosHandle->sizes[plane]; - planeLayout.widthInSamples = crosHandle->width; - planeLayout.heightInSamples = crosHandle->height; + planeLayout.widthInSamples = crosHandle->width / planeLayout.horizontalSubsampling; + planeLayout.heightInSamples = crosHandle->height / planeLayout.verticalSubsampling; } status = android::gralloc4::encodePlaneLayouts(planeLayouts, &encodedMetadata); From 27224109cb4b3d8f8f416a4a239d4f36b2e081b0 Mon Sep 17 00:00:00 2001 From: renchenglei Date: Thu, 31 Dec 2020 05:36:04 +0800 Subject: [PATCH 257/269] INTERNAL: Fix camera preview & record issues Camera preview use YCbCr, and will be converted to resolved format NV12. NV12 is one private defined format. So the descriptor.format is not same with crosHandle->droid_format. Suppress the check here. Camera works as one buffer producer for media. In previous, we may allocate & lock buffer with one same "driver". But when we switch to allocator & mapper 4.0, some components still use allocate & mapper 2.0, and which will use two different drivers. So, we need retain before we use the buffer allocated by other driver. In future, those components should switch to allocator & mapper 4.0 which is asked by API 30. Tracked-On: OAM-95595 Signed-off-by: Ren Chenglei --- cros_gralloc/gralloc1/cros_gralloc1_module.cc | 14 ++++++++++++-- cros_gralloc/gralloc4/CrosGralloc4Mapper.cc | 9 ++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/cros_gralloc/gralloc1/cros_gralloc1_module.cc b/cros_gralloc/gralloc1/cros_gralloc1_module.cc index 3df2224..da18297 100644 --- a/cros_gralloc/gralloc1/cros_gralloc1_module.cc +++ b/cros_gralloc/gralloc1/cros_gralloc1_module.cc @@ -463,8 +463,18 @@ int32_t CrosGralloc1::lock(buffer_handle_t bufferHandle, gralloc1_producer_usage map_flags = cros_gralloc1_convert_map_usage(producerUsage, consumerUsage); - if (driver->lock(bufferHandle, acquireFence, map_flags, addr)) - return CROS_GRALLOC_ERROR_BAD_HANDLE; + if (driver->lock(bufferHandle, acquireFence, map_flags, addr)) { + buffer_handle_t buffer_handle = native_handle_clone(bufferHandle); + auto error = retain(buffer_handle); + if (error != GRALLOC1_ERROR_NONE) { + delete buffer_handle; + return error; + } + bufferHandle = buffer_handle; + if (driver->lock(bufferHandle, acquireFence, map_flags, addr)) + return CROS_GRALLOC_ERROR_BAD_HANDLE; + delete buffer_handle; + } *outData = addr[0]; diff --git a/cros_gralloc/gralloc4/CrosGralloc4Mapper.cc b/cros_gralloc/gralloc4/CrosGralloc4Mapper.cc index 3815ffe..1912a19 100644 --- a/cros_gralloc/gralloc4/CrosGralloc4Mapper.cc +++ b/cros_gralloc/gralloc4/CrosGralloc4Mapper.cc @@ -16,6 +16,10 @@ #include "cros_gralloc/gralloc4/CrosGralloc4Utils.h" #include "helpers.h" +#ifdef USE_GRALLOC1 +#include "cros_gralloc/i915_private_android_types.h" +#endif + using aidl::android::hardware::graphics::common::BlendMode; using aidl::android::hardware::graphics::common::Dataspace; using aidl::android::hardware::graphics::common::PlaneLayout; @@ -147,10 +151,13 @@ Return CrosGralloc4Mapper::validateBufferSize(void* rawHandle, PixelFormat crosHandleFormat = static_cast(crosHandle->droid_format); #ifdef USE_GRALLOC1 int32_t yuvFormat = static_cast(descriptor.format); - if (descriptor.format != crosHandleFormat && yuvFormat != crosHandle->droid_format) { + if (descriptor.format != crosHandleFormat && yuvFormat != crosHandle->droid_format && + !(descriptor.format == PixelFormat::YCBCR_420_888 && + crosHandle->droid_format == HAL_PIXEL_FORMAT_NV12)) { drv_log("Failed to validateBufferSize. Format mismatch.\n"); #else if (descriptor.format != crosHandleFormat) { + drv_log("Failed to validateBufferSize. Format mismatch.\n"); #endif return Error::BAD_BUFFER; } From d1a0ac0ee62179d2538faa9b714c749aeacd3d24 Mon Sep 17 00:00:00 2001 From: renchenglei Date: Tue, 5 Jan 2021 02:38:14 +0800 Subject: [PATCH 258/269] INTERNAL: Fix CTS CtsNativeHardwareTestCases failures With allocator & mapper 4.0, there is some regression in CTS CtsNativeHardwareTestCases. Compared with allocator & mapper 2.0, we still not support two mipmap usage, and also not support to allocate more than 1 layer. Tracked-On: OAM-95612 Signed-off-by: Ren Chenglei chenglei.ren@intel.com --- cros_gralloc/gralloc4/CrosGralloc4Utils.cc | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/cros_gralloc/gralloc4/CrosGralloc4Utils.cc b/cros_gralloc/gralloc4/CrosGralloc4Utils.cc index eba596f..3f3fa2e 100644 --- a/cros_gralloc/gralloc4/CrosGralloc4Utils.cc +++ b/cros_gralloc/gralloc4/CrosGralloc4Utils.cc @@ -414,6 +414,13 @@ int convertToBufferUsage(uint64_t grallocUsage, uint64_t* outBufferUsage) { if (grallocUsage & BufferUsage::VIDEO_DECODER) { bufferUsage |= BO_USE_HW_VIDEO_DECODER; } +#ifdef USE_GRALLOC1 + if ((grallocUsage & BufferUsage::GPU_MIPMAP_COMPLETE) || + (grallocUsage & BufferUsage::GPU_CUBE_MAP)) { + drv_log("GPU_MIPMAP_COMPLETE or GPU_CUBE_MAP not supported"); + return -1; + } +#endif *outBufferUsage = bufferUsage; return 0; @@ -466,6 +473,12 @@ int convertToCrosDescriptor(const BufferDescriptorInfo& descriptor, drv_log("Failed to convert descriptor. Unsupported usage flags %s\n", usageString.c_str()); return -1; } +#ifdef USE_GRALLOC1 + if (descriptor.layerCount > 1) { + drv_log("Failed to convert descriptor. Can't support more than 1 layercount %d\n", descriptor.layerCount); + return -1; + } +#endif return 0; } From 60be15c64f9a4411766bfa39b6c9f62775184a52 Mon Sep 17 00:00:00 2001 From: renchenglei Date: Tue, 5 Jan 2021 06:55:51 +0800 Subject: [PATCH 259/269] INTERNAL: Fix CtsGraphicsTestCases failures For RGBA_FP16 format, we still not support RENDERING and TEXTURE usage. Tracked-On: OAM-95612 Signed-off-by: Ren Chenglei chenglei.ren@intel.com --- i915.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/i915.c b/i915.c index 0d0e637..636dd9c 100644 --- a/i915.c +++ b/i915.c @@ -76,7 +76,11 @@ static int i915_add_combinations(struct driver *drv) uint64_t render, scanout_and_render, texture_only; scanout_and_render = BO_USE_RENDER_MASK | BO_USE_SCANOUT; +#ifdef USE_GRALLOC1 + render = BO_USE_RENDER_MASK & ~(BO_USE_RENDERING | BO_USE_TEXTURE); +#else render = BO_USE_RENDER_MASK; +#endif texture_only = BO_USE_TEXTURE_MASK; uint64_t linear_mask = BO_USE_RENDERSCRIPT | BO_USE_LINEAR | BO_USE_PROTECTED | BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN; From 12c5aef0a4c372384b88bc6c019ce65bc6a18cde Mon Sep 17 00:00:00 2001 From: renchenglei Date: Tue, 12 Jan 2021 21:21:14 +0800 Subject: [PATCH 260/269] INTERNAL: Fix CtsNNAPITestCases failures For DRM_FORMAT_R8, we don't need align the stride. This change could help fix allocator issues in CtsNNAPITestCases. Tracked-On: OAM-95724 Signed-off-by: Ren Chenglei chenglei.ren@intel.com --- i915.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/i915.c b/i915.c index 636dd9c..633c1f3 100644 --- a/i915.c +++ b/i915.c @@ -198,6 +198,9 @@ static int i915_align_dimensions(struct bo *bo, uint32_t tiling, uint32_t *strid *aligned_height = ALIGN(*aligned_height, vertical_alignment); if (i915->gen > 3) { +#ifdef USE_GRALLOC1 + if(DRM_FORMAT_R8 != bo->meta.format) +#endif *stride = ALIGN(*stride, horizontal_alignment); } else { while (*stride > horizontal_alignment) From 13c5c1d95eb522ec20a6b71ad00b07eebabb98c5 Mon Sep 17 00:00:00 2001 From: renchenglei Date: Thu, 14 Jan 2021 21:18:40 +0800 Subject: [PATCH 261/269] INTERNAL: Fix CtsHardwareTestCases failures Add BO_USE_SW_MASK usage to DRM_FORMAT_RGB888 format, this is required by Android R CTS. Test: android.hardware.cts.HardwareBufferTest#testCreate Tracked-On: OAM-95726 Signed-off-by: Ren Chenglei chenglei.ren@intel.com --- i915.c | 1 + 1 file changed, 1 insertion(+) diff --git a/i915.c b/i915.c index 633c1f3..9949977 100644 --- a/i915.c +++ b/i915.c @@ -112,6 +112,7 @@ static int i915_add_combinations(struct driver *drv) drv_add_combination(drv, DRM_FORMAT_BGR888, &metadata, BO_USE_SW_MASK); #ifdef USE_GRALLOC1 drv_modify_combination(drv, DRM_FORMAT_ABGR2101010, &metadata, BO_USE_SW_MASK); + drv_add_combination(drv, DRM_FORMAT_RGB888, &metadata, BO_USE_SW_MASK); #endif /* From caefa6cdbdbd4f3ce335a913a9203b96733d168e Mon Sep 17 00:00:00 2001 From: renchenglei Date: Tue, 2 Feb 2021 21:45:02 +0800 Subject: [PATCH 262/269] INTERNAL: Add freeBuffer function support for gralloc1 After we rebased our allocator & mapper from 2.0 to 4.0, we use allocator 4.0 to allocate buffer, which can't be accessed by mapper 2.0 directly. Here, we add freeBuffer function, if we want to use mapper 2.0 to lock & unlock buffer(allocated by allocator 4.0), we need importBuffer & freeBuffer before/after lock and unlock. Tracked-On: OAM-95916 Signed-off-by: Ren Chenglei --- cros_gralloc/gralloc1/cros_gralloc1_module.cc | 34 +++++++++++++++++++ cros_gralloc/gralloc1/cros_gralloc1_module.h | 6 ++++ cros_gralloc/i915_private_android_types.h | 4 +++ 3 files changed, 44 insertions(+) diff --git a/cros_gralloc/gralloc1/cros_gralloc1_module.cc b/cros_gralloc/gralloc1/cros_gralloc1_module.cc index da18297..17a9201 100644 --- a/cros_gralloc/gralloc1/cros_gralloc1_module.cc +++ b/cros_gralloc/gralloc1/cros_gralloc1_module.cc @@ -231,6 +231,8 @@ gralloc1_function_pointer_t CrosGralloc1::doGetFunction(int32_t intDescriptor) return asFP(getTransportSizeHook); case GRALLOC1_FUNCTION_IMPORT_BUFFER: return asFP(importBufferHook); + case GRALLOC1_FUNCTION_FREE_BUFFER: + return asFP(freeBufferHook); case GRALLOC1_FUNCTION_INVALID: drv_log("Invalid function descriptor"); return nullptr; @@ -380,6 +382,36 @@ int32_t CrosGralloc1::importBuffer(const buffer_handle_t rawHandle, buffer_handl return GRALLOC1_ERROR_NONE; } +int32_t CrosGralloc1::freeBuffer(void *freeBuffer) +{ + if (!freeBuffer) { + drv_log("Failed to freeBuffer, empty handle.\n"); + return GRALLOC1_ERROR_BAD_HANDLE; + } + + native_handle_t *bufferHandle = reinterpret_cast(freeBuffer); + + int ret = driver->release(bufferHandle); + if (ret) { + drv_log("Failed to release handle, bad handle.\n"); + return GRALLOC1_ERROR_BAD_HANDLE; + } + + ret = native_handle_close(bufferHandle); + if (ret) { + drv_log("Failed to close handle, bad handle.\n"); + return GRALLOC1_ERROR_BAD_HANDLE; + } + + ret = native_handle_delete(bufferHandle); + if (ret) { + drv_log("Failed to delete handle, bad handle.\n"); + return GRALLOC1_ERROR_BAD_HANDLE; + } + + return GRALLOC1_ERROR_NONE; +} + int32_t CrosGralloc1::allocate(struct cros_gralloc_buffer_descriptor *descriptor, buffer_handle_t *outBufferHandle) { @@ -464,6 +496,7 @@ int32_t CrosGralloc1::lock(buffer_handle_t bufferHandle, gralloc1_producer_usage map_flags = cros_gralloc1_convert_map_usage(producerUsage, consumerUsage); if (driver->lock(bufferHandle, acquireFence, map_flags, addr)) { + drv_log("Plz switch to mapper 4.0 or call importBuffer & freeBuffer with mapper 2.0 before lock"); buffer_handle_t buffer_handle = native_handle_clone(bufferHandle); auto error = retain(buffer_handle); if (error != GRALLOC1_ERROR_NONE) { @@ -564,6 +597,7 @@ int32_t CrosGralloc1::lockYCbCr(buffer_handle_t bufferHandle, map_flags = cros_gralloc1_convert_map_usage(producerUsage, consumerUsage); if (driver->lock(bufferHandle, acquireFence, map_flags, addr)) { + drv_log("Plz switch to mapper 4.0 or call importBuffer & freeBuffer with mapper 2.0 before lockFlex"); buffer_handle_t buffer_handle = native_handle_clone(bufferHandle); auto error = retain(buffer_handle); if (error != GRALLOC1_ERROR_NONE) { diff --git a/cros_gralloc/gralloc1/cros_gralloc1_module.h b/cros_gralloc/gralloc1/cros_gralloc1_module.h index 247b456..ca12743 100644 --- a/cros_gralloc/gralloc1/cros_gralloc1_module.h +++ b/cros_gralloc/gralloc1/cros_gralloc1_module.h @@ -216,6 +216,12 @@ class CrosGralloc1 : public gralloc1_device_t return getAdapter(device)->importBuffer(rawHandle, outBuffer); } + int32_t freeBuffer(void *freeBuffer); + static int32_t freeBufferHook(gralloc1_device_t *device, void *freeBuffer) + { + return getAdapter(device)->freeBuffer(freeBuffer); + } + int32_t getProducerUsage(buffer_handle_t buffer, uint64_t * /*gralloc1_producer_usage_t*/ outUsage); static int32_t getProducerUsageHook(gralloc1_device_t *device, buffer_handle_t buffer, diff --git a/cros_gralloc/i915_private_android_types.h b/cros_gralloc/i915_private_android_types.h index a7072d0..fd9caf7 100644 --- a/cros_gralloc/i915_private_android_types.h +++ b/cros_gralloc/i915_private_android_types.h @@ -64,6 +64,7 @@ enum { GRALLOC1_FUNCTION_SET_MODIFIER = 101, GRALLOC1_FUNCTION_GET_PRIME = 103, GRALLOC1_FUNCTION_SET_INTERLACE = 104, GRALLOC1_FUNCTION_SET_PROTECTIONINFO = 105, + GRALLOC1_FUNCTION_FREE_BUFFER = 106, GRALLOC1_LAST_CUSTOM = 500 }; typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_SET_MODIFIER)( @@ -81,6 +82,9 @@ typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_SET_INTERLACE)( typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_SET_PROTECTIONINFO)( gralloc1_device_t *device, buffer_handle_t buffer, uint32_t protection_info); +typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_FREE_BUFFER)( + gralloc1_device_t *device, void *freeBuffer); + typedef union intel_protection_info_type_t { uint32_t value; struct { From 5e4d60a6c2d5e0bc5de31becafb0d04ebee510ff Mon Sep 17 00:00:00 2001 From: renchenglei Date: Tue, 6 Apr 2021 23:42:28 +0800 Subject: [PATCH 263/269] INTERNAL: Align 263 video back to 32 Issue has been fixed from media driver, revert back to 32, which can help pass VTS failure Tracked-On: OAM-96724 Signed-off-by: Ren Chenglei --- i915.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/i915.c b/i915.c index 9949977..7787d48 100644 --- a/i915.c +++ b/i915.c @@ -348,11 +348,7 @@ static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t heig * ALIGN(Y_stride / 2, 16), which we can make happen by * aligning to 32 bytes here. */ -#ifdef USE_GRALLOC1 - uint32_t stride = ALIGN(width, 64); -#else uint32_t stride = ALIGN(width, 32); -#endif drv_bo_from_format(bo, stride, height, format); } else if (modifier == I915_FORMAT_MOD_Y_TILED_CCS) { /* From 107d9ef5ad40806336f6ca0d71dc9d91ccd42261 Mon Sep 17 00:00:00 2001 From: renchenglei Date: Tue, 6 Apr 2021 23:54:39 +0800 Subject: [PATCH 264/269] INTERNAL: Add camera usage for RGBA format On virgl backend, we use vhal camera. During camera preview, we use RGBA format, so add camera usage for it. Tracked-On: OAM-96725 Signed-off-by: Ren Chenglei chenglei.ren@intel.com --- virtio_gpu.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/virtio_gpu.c b/virtio_gpu.c index ed67693..aae2458 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -638,6 +638,10 @@ static int virtio_gpu_init(struct driver *drv) BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER); drv_modify_combination(drv, DRM_FORMAT_R16, &LINEAR_METADATA, BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER); +#ifdef USE_GRALLOC1 + drv_modify_combination(drv, DRM_FORMAT_ABGR8888, &LINEAR_METADATA, + BO_USE_CAMERA_WRITE | BO_USE_CAMERA_READ); +#endif return drv_modify_linear_combinations(drv); } From a0ae9c6885abab3ee97a9437518b802c97934a5d Mon Sep 17 00:00:00 2001 From: renchenglei Date: Wed, 7 Apr 2021 00:02:28 +0800 Subject: [PATCH 265/269] INTERNAL: Add NV12_Y_TILED_INTEL format for PlaneLayoutsMap This is needed for codec2.0 Tracked-On: OAM-96726 Signed-off-by: Yang, Dong Signed-off-by: Ren Chenglei --- cros_gralloc/gralloc4/CrosGralloc4Utils.cc | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/cros_gralloc/gralloc4/CrosGralloc4Utils.cc b/cros_gralloc/gralloc4/CrosGralloc4Utils.cc index 3f3fa2e..38298bc 100644 --- a/cros_gralloc/gralloc4/CrosGralloc4Utils.cc +++ b/cros_gralloc/gralloc4/CrosGralloc4Utils.cc @@ -649,6 +649,30 @@ const std::unordered_map>& GetPlaneLayoutsMap .verticalSubsampling = 2, }}}, +#ifdef USE_GRALLOC1 + {DRM_FORMAT_NV12_Y_TILED_INTEL, + {{ + .components = {{.type = android::gralloc4::PlaneLayoutComponentType_Y, + .offsetInBits = 0, + .sizeInBits = 8}}, + .sampleIncrementInBits = 8, + .horizontalSubsampling = 1, + .verticalSubsampling = 1, + }, + { + .components = + {{.type = android::gralloc4::PlaneLayoutComponentType_CB, + .offsetInBits = 0, + .sizeInBits = 8}, + {.type = android::gralloc4::PlaneLayoutComponentType_CR, + .offsetInBits = 8, + .sizeInBits = 8}}, + .sampleIncrementInBits = 16, + .horizontalSubsampling = 2, + .verticalSubsampling = 2, + }}}, +#endif + {DRM_FORMAT_P010, {{ .components = {{.type = android::gralloc4::PlaneLayoutComponentType_Y, From 2935160545c87a2e1c147fd5bddd781ca1740625 Mon Sep 17 00:00:00 2001 From: renchenglei Date: Fri, 16 Apr 2021 22:56:09 +0800 Subject: [PATCH 266/269] INTERNAL: Refine importBuffer & freeBuffer 1. native_handle_* need native_handle_t instead of buffer_handle_t, this conflicts with mapper 2.0 release function 2. importBuffer call native_handle_clone, which will have "malloc", then we need use "free" by native_handle_delete in case of memory leak, which is called in private defined API freeBuffer 3. We should use Android official define API release instead of private defined API freeBuffer; so we need remove native_handle_clone in importBuffer and use release directly Tracked-On: OAM-96807 Signed-off-by: Chenglei Ren --- cros_gralloc/gralloc1/cros_gralloc1_module.cc | 61 ++++++++----------- cros_gralloc/gralloc1/cros_gralloc1_module.h | 6 -- cros_gralloc/i915_private_android_types.h | 4 -- 3 files changed, 25 insertions(+), 46 deletions(-) diff --git a/cros_gralloc/gralloc1/cros_gralloc1_module.cc b/cros_gralloc/gralloc1/cros_gralloc1_module.cc index 17a9201..5d2fa93 100644 --- a/cros_gralloc/gralloc1/cros_gralloc1_module.cc +++ b/cros_gralloc/gralloc1/cros_gralloc1_module.cc @@ -231,8 +231,6 @@ gralloc1_function_pointer_t CrosGralloc1::doGetFunction(int32_t intDescriptor) return asFP(getTransportSizeHook); case GRALLOC1_FUNCTION_IMPORT_BUFFER: return asFP(importBufferHook); - case GRALLOC1_FUNCTION_FREE_BUFFER: - return asFP(freeBufferHook); case GRALLOC1_FUNCTION_INVALID: drv_log("Invalid function descriptor"); return nullptr; @@ -373,7 +371,8 @@ int32_t CrosGralloc1::importBuffer(const buffer_handle_t rawHandle, buffer_handl } auto error = retain(buffer_handle); if (error != GRALLOC1_ERROR_NONE) { - delete buffer_handle; + native_handle_close(buffer_handle); + native_handle_delete((native_handle_t*)buffer_handle); *outBuffer = NULL; return error; } @@ -382,36 +381,6 @@ int32_t CrosGralloc1::importBuffer(const buffer_handle_t rawHandle, buffer_handl return GRALLOC1_ERROR_NONE; } -int32_t CrosGralloc1::freeBuffer(void *freeBuffer) -{ - if (!freeBuffer) { - drv_log("Failed to freeBuffer, empty handle.\n"); - return GRALLOC1_ERROR_BAD_HANDLE; - } - - native_handle_t *bufferHandle = reinterpret_cast(freeBuffer); - - int ret = driver->release(bufferHandle); - if (ret) { - drv_log("Failed to release handle, bad handle.\n"); - return GRALLOC1_ERROR_BAD_HANDLE; - } - - ret = native_handle_close(bufferHandle); - if (ret) { - drv_log("Failed to close handle, bad handle.\n"); - return GRALLOC1_ERROR_BAD_HANDLE; - } - - ret = native_handle_delete(bufferHandle); - if (ret) { - drv_log("Failed to delete handle, bad handle.\n"); - return GRALLOC1_ERROR_BAD_HANDLE; - } - - return GRALLOC1_ERROR_NONE; -} - int32_t CrosGralloc1::allocate(struct cros_gralloc_buffer_descriptor *descriptor, buffer_handle_t *outBufferHandle) { @@ -473,10 +442,30 @@ int32_t CrosGralloc1::retain(buffer_handle_t bufferHandle) int32_t CrosGralloc1::release(buffer_handle_t bufferHandle) { - if (driver->release(bufferHandle)) - return CROS_GRALLOC_ERROR_BAD_HANDLE; + if (!bufferHandle) { + drv_log("Failed to freeBuffer, empty handle.\n"); + return GRALLOC1_ERROR_BAD_HANDLE; + } - return CROS_GRALLOC_ERROR_NONE; + int ret = driver->release(bufferHandle); + if (ret) { + drv_log("Failed to release handle, bad handle.\n"); + return GRALLOC1_ERROR_BAD_HANDLE; + } + + ret = native_handle_close(bufferHandle); + if (ret) { + drv_log("Failed to close handle, bad handle.\n"); + return GRALLOC1_ERROR_BAD_HANDLE; + } + + ret = native_handle_delete((native_handle_t*)bufferHandle); + if (ret) { + drv_log("Failed to delete handle, bad handle.\n"); + return GRALLOC1_ERROR_BAD_HANDLE; + } + + return GRALLOC1_ERROR_NONE; } int32_t CrosGralloc1::lock(buffer_handle_t bufferHandle, gralloc1_producer_usage_t producerUsage, diff --git a/cros_gralloc/gralloc1/cros_gralloc1_module.h b/cros_gralloc/gralloc1/cros_gralloc1_module.h index ca12743..247b456 100644 --- a/cros_gralloc/gralloc1/cros_gralloc1_module.h +++ b/cros_gralloc/gralloc1/cros_gralloc1_module.h @@ -216,12 +216,6 @@ class CrosGralloc1 : public gralloc1_device_t return getAdapter(device)->importBuffer(rawHandle, outBuffer); } - int32_t freeBuffer(void *freeBuffer); - static int32_t freeBufferHook(gralloc1_device_t *device, void *freeBuffer) - { - return getAdapter(device)->freeBuffer(freeBuffer); - } - int32_t getProducerUsage(buffer_handle_t buffer, uint64_t * /*gralloc1_producer_usage_t*/ outUsage); static int32_t getProducerUsageHook(gralloc1_device_t *device, buffer_handle_t buffer, diff --git a/cros_gralloc/i915_private_android_types.h b/cros_gralloc/i915_private_android_types.h index fd9caf7..a7072d0 100644 --- a/cros_gralloc/i915_private_android_types.h +++ b/cros_gralloc/i915_private_android_types.h @@ -64,7 +64,6 @@ enum { GRALLOC1_FUNCTION_SET_MODIFIER = 101, GRALLOC1_FUNCTION_GET_PRIME = 103, GRALLOC1_FUNCTION_SET_INTERLACE = 104, GRALLOC1_FUNCTION_SET_PROTECTIONINFO = 105, - GRALLOC1_FUNCTION_FREE_BUFFER = 106, GRALLOC1_LAST_CUSTOM = 500 }; typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_SET_MODIFIER)( @@ -82,9 +81,6 @@ typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_SET_INTERLACE)( typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_SET_PROTECTIONINFO)( gralloc1_device_t *device, buffer_handle_t buffer, uint32_t protection_info); -typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_FREE_BUFFER)( - gralloc1_device_t *device, void *freeBuffer); - typedef union intel_protection_info_type_t { uint32_t value; struct { From 1bed61befe3bc14b5eff1aaa6fd5eb1b98b2dee7 Mon Sep 17 00:00:00 2001 From: Kaushlendra Kumar Date: Wed, 5 May 2021 19:16:56 +0530 Subject: [PATCH 267/269] INTERNAL: fix of suspend/resume issue Inside the release function (CrosGralloc1::release()) native_handle_close() and native_handle_delete() functions are getting called after driver release function call (driver->release()). In driver release function these are already cleaned up. Inside driver release function native_handle_close() is called inside destructor of cros_gralloc_buffer. Tracked-On: OAM-97019 Signed-off-by: Kaushlendra Kumar Signed-off-by: Chenglei Ren --- cros_gralloc/gralloc1/cros_gralloc1_module.cc | 22 ++----------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/cros_gralloc/gralloc1/cros_gralloc1_module.cc b/cros_gralloc/gralloc1/cros_gralloc1_module.cc index 5d2fa93..2365c70 100644 --- a/cros_gralloc/gralloc1/cros_gralloc1_module.cc +++ b/cros_gralloc/gralloc1/cros_gralloc1_module.cc @@ -364,20 +364,13 @@ int32_t CrosGralloc1::importBuffer(const buffer_handle_t rawHandle, buffer_handl *outBuffer = NULL; return GRALLOC1_ERROR_BAD_HANDLE; } - buffer_handle_t buffer_handle = native_handle_clone(rawHandle); - if (!buffer_handle) { - *outBuffer = NULL; - return GRALLOC1_ERROR_NO_RESOURCES; - } - auto error = retain(buffer_handle); + auto error = driver->retain(rawHandle); if (error != GRALLOC1_ERROR_NONE) { - native_handle_close(buffer_handle); - native_handle_delete((native_handle_t*)buffer_handle); *outBuffer = NULL; return error; } - *outBuffer = buffer_handle; + *outBuffer = rawHandle; return GRALLOC1_ERROR_NONE; } @@ -453,17 +446,6 @@ int32_t CrosGralloc1::release(buffer_handle_t bufferHandle) return GRALLOC1_ERROR_BAD_HANDLE; } - ret = native_handle_close(bufferHandle); - if (ret) { - drv_log("Failed to close handle, bad handle.\n"); - return GRALLOC1_ERROR_BAD_HANDLE; - } - - ret = native_handle_delete((native_handle_t*)bufferHandle); - if (ret) { - drv_log("Failed to delete handle, bad handle.\n"); - return GRALLOC1_ERROR_BAD_HANDLE; - } return GRALLOC1_ERROR_NONE; } From ed5e8add6284bd1d5ee90381a3970ac3c190a6f4 Mon Sep 17 00:00:00 2001 From: "Yang, Dong" Date: Thu, 13 May 2021 11:19:01 +0800 Subject: [PATCH 268/269] INTERNAL: getBackingStore() return unique value getBackingStore() should return a globally unique value for a dedicated graphics buffer, the graphics buffers will share between different modules like display and codec, the unique value will be used to identify specifi memory. Tracked-On: OAM-97062 Signed-off-by: Yang, Dong --- cros_gralloc/cros_gralloc_driver.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cros_gralloc/cros_gralloc_driver.cc b/cros_gralloc/cros_gralloc_driver.cc index 271347a..fd8d7b3 100644 --- a/cros_gralloc/cros_gralloc_driver.cc +++ b/cros_gralloc/cros_gralloc_driver.cc @@ -483,6 +483,9 @@ int32_t cros_gralloc_driver::get_backing_store(buffer_handle_t handle, uint64_t return -EINVAL; } +#ifdef USE_GRALLOC1 + *out_store = static_cast(hnd->id); +#else auto buffer = get_buffer(hnd); if (!buffer) { drv_log("Invalid Reference.\n"); @@ -490,6 +493,7 @@ int32_t cros_gralloc_driver::get_backing_store(buffer_handle_t handle, uint64_t } *out_store = static_cast(buffer->get_id()); +#endif return 0; } From c41a734b75fc769ec39b741ca64d4764c745e47b Mon Sep 17 00:00:00 2001 From: Shaofeng Tang Date: Thu, 25 Nov 2021 11:38:27 +0800 Subject: [PATCH 269/269] Add i915 private format convert Signed-off-by: Shaofeng Tang --- cros_gralloc/gralloc4/CrosGralloc4Utils.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cros_gralloc/gralloc4/CrosGralloc4Utils.cc b/cros_gralloc/gralloc4/CrosGralloc4Utils.cc index 38298bc..84cda7a 100644 --- a/cros_gralloc/gralloc4/CrosGralloc4Utils.cc +++ b/cros_gralloc/gralloc4/CrosGralloc4Utils.cc @@ -360,6 +360,11 @@ int convertToDrmFormat(PixelFormat format, uint32_t* outDrmFormat) { *outDrmFormat = DRM_FORMAT_YVU420_ANDROID; return 0; }; +#ifdef USE_GRALLOC1 + *outDrmFormat = i915_private_convert_format((int)format); + if (DRM_FORMAT_NONE != *outDrmFormat) + return 0; +#endif return -EINVAL; } @@ -454,7 +459,7 @@ int convertToCrosDescriptor(const BufferDescriptorInfo& descriptor, if (convertToDrmFormat(descriptor.format, &outCrosDescriptor->drm_format)) { #ifdef USE_GRALLOC1 - drv_log("Failed to convert descriptor by convertToDrmFormat"); + drv_log("Failed to convert descriptor by convertToDrmFormat for format = %d\n", descriptor.format); if (!IsSupportedYUVFormat(static_cast(descriptor.format))) { std::string pixelFormatString = getPixelFormatString(descriptor.format); drv_log("Failed to convert descriptor. Unsupported fomat %s\n", pixelFormatString.c_str());