From 38eb8e2221b317703d6d2ff0b08473d180a8cd50 Mon Sep 17 00:00:00 2001 From: yifang ma Date: Thu, 5 Dec 2019 17:25:16 +0800 Subject: [PATCH] rename lib name to gralloc.intel To avoid lib name conflicts from external minigbm. Tracked-On: OAM-88753 Signed-off-by: yifang ma --- Android.bp | 56 +----- cros_gralloc/cros_gralloc_driver.cc | 31 ++- cros_gralloc/cros_gralloc_helpers.cc | 13 +- cros_gralloc/cros_gralloc_helpers.h | 1 + cros_gralloc/gralloc0/gralloc0.cc | 10 +- cros_gralloc/i915_private_android.cc | 116 +++++++++++ cros_gralloc/i915_private_android.h | 19 ++ cros_gralloc/i915_private_android_types.h | 62 ++++++ drv_priv.h | 3 + helpers.c | 57 +++++- helpers.h | 2 +- helpers_array.c | 9 +- i915.c | 69 ++++++- i915_private.c | 232 ++++++++++++++++++++++ i915_private.h | 56 ++++++ 15 files changed, 659 insertions(+), 77 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 diff --git a/Android.bp b/Android.bp index 63a50f7..77854f6 100644 --- a/Android.bp +++ b/Android.bp @@ -2,39 +2,28 @@ // found in the LICENSE file. cc_defaults { - name: "gralloc.minigbm_intel_defaults", + name: "gralloc.minigbm_intel_defaults_pri", cflags: ["-DDRV_I915"], } cc_defaults { - name: "gralloc.minigbm_meson_defaults", - cflags: ["-DDRV_MESON"], -} - -cc_defaults { - name: "gralloc.minigbm_defaults", + name: "gralloc.minigbm_defaults_pri", 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", + // for i915 private + "i915_private.c", + "cros_gralloc/i915_private_android.cc", + "cros_gralloc/cros_gralloc_buffer.cc", "cros_gralloc/cros_gralloc_driver.cc", "cros_gralloc/cros_gralloc_helpers.cc", @@ -76,15 +65,10 @@ cc_defaults { } cc_library_shared { - name: "gralloc.minigbm", - defaults: ["gralloc.minigbm_defaults"], -} - -cc_library_shared { - name: "gralloc.minigbm_intel", + name: "gralloc.intel", defaults: [ - "gralloc.minigbm_defaults", - "gralloc.minigbm_intel_defaults", + "gralloc.minigbm_defaults_pri", + "gralloc.minigbm_intel_defaults_pri", ], enabled: false, arch: { @@ -96,25 +80,3 @@ cc_library_shared { }, }, } - -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/cros_gralloc/cros_gralloc_driver.cc b/cros_gralloc/cros_gralloc_driver.cc index 8096b7f..33aa926 100644 --- a/cros_gralloc/cros_gralloc_driver.cc +++ b/cros_gralloc/cros_gralloc_driver.cc @@ -56,18 +56,27 @@ 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])) { drmFreeVersion(version); + close(fd); continue; } drmFreeVersion(version); drv_ = drv_create(fd); - if (drv_) + + if (drv_) { return 0; + } + else { + close(fd); + continue; + } } } @@ -232,12 +241,22 @@ int32_t cros_gralloc_driver::release(buffer_handle_t handle) auto buffer = get_buffer(hnd); if (!buffer) { - drv_log("Invalid Reference.\n"); - return -EINVAL; + uint32_t id = -1; + if (drmPrimeFDToHandle(drv_get_fd(drv_), hnd->fds[0], &id)) { + drv_log("drmPrimeFDToHandle failed."); + return -errno; + } + if (buffers_.count(id)) { + buffer = buffers_[id]; + buffer->increase_refcount(); + } else { + drv_log("Could not found reference"); + return -EINVAL; + } } - - if (!--handles_[hnd].second) + else if (!--handles_[hnd].second) { handles_.erase(hnd); + } if (buffer->decrease_refcount() == 0) { buffers_.erase(buffer->get_id()); diff --git a/cros_gralloc/cros_gralloc_helpers.cc b/cros_gralloc/cros_gralloc_helpers.cc index 12daf4b..1d6c7d6 100644 --- a/cros_gralloc/cros_gralloc_helpers.cc +++ b/cros_gralloc/cros_gralloc_helpers.cc @@ -5,8 +5,19 @@ */ #include "cros_gralloc_helpers.h" +#include "i915_private_android.h" #include +#include + +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; +} uint32_t cros_gralloc_convert_format(int format) { @@ -41,7 +52,7 @@ uint32_t cros_gralloc_convert_format(int format) return DRM_FORMAT_R8; } - return DRM_FORMAT_NONE; + return i915_private_convert_format(format); } 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 a55eebc..dfb30a7 100644 --- a/cros_gralloc/cros_gralloc_helpers.h +++ b/cros_gralloc/cros_gralloc_helpers.h @@ -18,6 +18,7 @@ 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)); +const char *drmFormat2Str(int format); uint32_t cros_gralloc_convert_format(int32_t format); cros_gralloc_handle_t cros_gralloc_convert_handle(buffer_handle_t handle); diff --git a/cros_gralloc/gralloc0/gralloc0.cc b/cros_gralloc/gralloc0/gralloc0.cc index 96593b8..676a5a8 100644 --- a/cros_gralloc/gralloc0/gralloc0.cc +++ b/cros_gralloc/gralloc0/gralloc0.cc @@ -5,6 +5,7 @@ */ #include "../cros_gralloc_driver.h" +#include "../i915_private_android.h" #include #include @@ -115,7 +116,7 @@ static int gralloc0_alloc(alloc_device_t *dev, int w, int h, int format, int usa if (!supported) { 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), + format, usage, drmFormat2Str(descriptor.drm_format), static_cast(descriptor.use_flags)); return -EINVAL; } @@ -179,13 +180,15 @@ static int gralloc0_open(const struct hw_module_t *mod, const char *name, struct return 0; } - if (strcmp(name, GRALLOC_HARDWARE_GPU0)) { + if (strcmp(name, GRALLOC_HARDWARE_GPU0) != 0 && strcmp(name, GRALLOC_HARDWARE_MODULE_ID) != 0) { drv_log("Incorrect device name - %s.\n", name); return -EINVAL; } - if (gralloc0_init(module, true)) + if (gralloc0_init(module, true)) { + drv_log("gralloc0_init failed"); return -ENODEV; + } *dev = &module->alloc->common; return 0; @@ -372,6 +375,7 @@ static int gralloc0_lock_async_ycbcr(struct gralloc_module_t const *module, buff 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..08050e6 --- /dev/null +++ b/cros_gralloc/i915_private_android.cc @@ -0,0 +1,116 @@ +/* + * 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_I915 + +#include "i915_private_android.h" +#include "i915_private_android_types.h" + +#include "cros_gralloc_helpers.h" + +#include + +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; + case HAL_PIXEL_FORMAT_P010_INTEL: + return DRM_FORMAT_P010; + case HAL_PIXEL_FORMAT_RGBA_1010102: + return DRM_FORMAT_ABGR2101010; + case HAL_PIXEL_FORMAT_RGBA_FP16: + return DRM_FORMAT_ABGR16161616F; + } + + return DRM_FORMAT_NONE; +} + +#if 0 +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_P010: + return HAL_PIXEL_FORMAT_P010_INTEL; + 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; + case DRM_FORMAT_ABGR2101010: + return HAL_PIXEL_FORMAT_RGBA_1010102; + case DRM_FORMAT_ABGR16161616F: + return HAL_PIXEL_FORMAT_RGBA_FP16; + default: + cros_gralloc_error("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: + case HAL_PIXEL_FORMAT_P010_INTEL: + return true; + default: + return false; + } + + return false; +} +#endif + +#endif diff --git a/cros_gralloc/i915_private_android.h b/cros_gralloc/i915_private_android.h new file mode 100644 index 0000000..b30985d --- /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. + */ + +#ifdef DRV_I915 + +#include + +#include "i915_private.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..cc6d2e9 --- /dev/null +++ b/cros_gralloc/i915_private_android_types.h @@ -0,0 +1,62 @@ +/* + * 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. + */ + +/* + * Android graphics.h defines the formats and leaves 0x100 - 0x1FF + * range available for HAL implementation specific formats. + */ + +#ifndef i915_PRIVATE_ANDROID_TYPES_H_ +#define i915_PRIVATE_ANDROID_TYPES_H_ + +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_priv.h b/drv_priv.h index 719cd35..c6589be 100644 --- a/drv_priv.h +++ b/drv_priv.h @@ -99,4 +99,7 @@ struct backend { #define LINEAR_METADATA (struct format_metadata) { 1, 0, DRM_FORMAT_MOD_LINEAR } // clang-format on +#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 + #endif diff --git a/helpers.c b/helpers.c index 4fabfa9..81e85cf 100644 --- a/helpers.c +++ b/helpers.c @@ -17,6 +17,7 @@ #include "drv_priv.h" #include "helpers.h" #include "util.h" +#include "i915_private.h" struct planar_layout { size_t num_planes; @@ -55,6 +56,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 }, @@ -69,8 +77,41 @@ static const struct planar_layout triplanar_yuv_420_layout = { .bytes_per_pixel = { 1, 1, 1 } }; +static const struct planar_layout biplanar_ycrcb_420_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_i915_private(uint32_t format) +{ + assert(plane < drv_num_planes_from_format(format)); + + switch (format) { + case DRM_FORMAT_NV12_Y_TILED_INTEL: + return &biplanar_yuv_420_layout; + case DRM_FORMAT_P010: + return &biplanar_ycrcb_420_layout; + case DRM_FORMAT_YUV420: + case DRM_FORMAT_YUV422: + case DRM_FORMAT_YUV444: + case DRM_FORMAT_NV16: + return &triplanar_yuv_420_layout; + case DRM_FORMAT_R16: + return &packed_2bpp_layout; + case DRM_FORMAT_ABGR2101010: + return &packed_4bpp_layout; + case DRM_FORMAT_ABGR16161616F: + return &packed_8bpp_layout; + } + + fprintf(stderr, "drv: UNKNOWN FORMAT %d\n", format); + return NULL; +} + static const struct planar_layout *layout_from_format(uint32_t format) { switch (format) { @@ -136,11 +177,9 @@ static const struct planar_layout *layout_from_format(uint32_t format) case DRM_FORMAT_XRGB2101010: case DRM_FORMAT_XRGB8888: return &packed_4bpp_layout; - - default: - drv_log("UNKNOWN FORMAT %d\n", format); - return NULL; } + + return layout_from_format_i915_private(format); } size_t drv_num_planes_from_format(uint32_t format) @@ -489,18 +528,22 @@ uint32_t drv_log_base2(uint32_t value) return ret; } -void drv_add_combinations(struct driver *drv, const uint32_t *formats, uint32_t num_formats, +int 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; + int ret = 0; + uint32_t i = 0; 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); + if (!drv_array_append(drv->combos, &combo)) { + return -ENOMEM; + } } + return ret; } void drv_modify_combination(struct driver *drv, uint32_t format, struct format_metadata *metadata, diff --git a/helpers.h b/helpers.h index 4c649c2..07766d9 100644 --- a/helpers.h +++ b/helpers.h @@ -28,7 +28,7 @@ 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); -void drv_add_combinations(struct driver *drv, const uint32_t *formats, uint32_t num_formats, +int drv_add_combinations(struct driver *drv, const uint32_t *formats, uint32_t num_formats, struct format_metadata *metadata, uint64_t usage); void drv_modify_combination(struct driver *drv, uint32_t format, struct format_metadata *metadata, uint64_t usage); diff --git a/helpers_array.c b/helpers_array.c index 20b43e2..1d71cdb 100644 --- a/helpers_array.c +++ b/helpers_array.c @@ -33,17 +33,22 @@ struct drv_array *drv_array_init(uint32_t item_size) void *drv_array_append(struct drv_array *array, void *data) { - void *item; + void *item = NULL; 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); + if (!new_items) { + return NULL; + } array->items = new_items; } item = calloc(1, array->item_size); + if (!item) { + return NULL; + } memcpy(item, data, array->item_size); array->items[array->size] = item; array->size++; diff --git a/i915.c b/i915.c index a88db6a..5973d0c 100644 --- a/i915.c +++ b/i915.c @@ -18,6 +18,7 @@ #include "drv_priv.h" #include "helpers.h" #include "util.h" +#include "i915_private.h" #define I915_CACHELINE_SIZE 64 #define I915_CACHELINE_MASK (I915_CACHELINE_SIZE - 1) @@ -114,7 +115,7 @@ static int i915_add_kms_item(struct driver *drv, const struct kms_item *item) static int i915_add_combinations(struct driver *drv) { - int ret; + int ret = 0; uint32_t i; struct drv_array *kms_items; struct format_metadata metadata; @@ -127,15 +128,24 @@ static int i915_add_combinations(struct driver *drv) 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); + 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, texture_source_formats, ARRAY_SIZE(texture_source_formats), + 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, tileable_texture_source_formats, + ret = drv_add_combinations(drv, tileable_texture_source_formats, ARRAY_SIZE(tileable_texture_source_formats), &metadata, texture_use_flags); + if (ret) { + return ret; + } drv_modify_combination(drv, DRM_FORMAT_XRGB8888, &metadata, BO_USE_CURSOR | BO_USE_SCANOUT); drv_modify_combination(drv, DRM_FORMAT_ARGB8888, &metadata, BO_USE_CURSOR | BO_USE_SCANOUT); @@ -164,28 +174,45 @@ static int i915_add_combinations(struct driver *drv) metadata.priority = 2; metadata.modifier = I915_FORMAT_MOD_X_TILED; - drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), + 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, tileable_texture_source_formats, + ret = drv_add_combinations(drv, tileable_texture_source_formats, ARRAY_SIZE(tileable_texture_source_formats), &metadata, texture_use_flags); + if (ret) { + return ret; + } 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), + 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, tileable_texture_source_formats, + ret = drv_add_combinations(drv, tileable_texture_source_formats, ARRAY_SIZE(tileable_texture_source_formats), &metadata, texture_use_flags); + if (ret) { + return ret; + } /* Support y-tiled NV12 for libva */ const uint32_t nv12_format = DRM_FORMAT_NV12; - drv_add_combinations(drv, &nv12_format, 1, &metadata, + ret = drv_add_combinations(drv, &nv12_format, 1, &metadata, BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER); + if (ret) { + return ret; + } + + i915_private_add_combinations(drv); kms_items = drv_query_kms(drv); if (!kms_items) @@ -240,6 +267,23 @@ 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; + } + + i915_private_align_dimensions(bo->format, &vertical_alignment); + *aligned_height = ALIGN(bo->height, vertical_alignment); if (i915->gen > 3) { *stride = ALIGN(*stride, horizontal_alignment); @@ -545,6 +589,11 @@ static int i915_bo_flush(struct bo *bo, struct mapping *mapping) static uint32_t i915_resolve_format(uint32_t format, uint64_t use_flags) { + uint32_t resolved_format; + if (i915_private_resolve_format(format, use_flags, &resolved_format)) { + return resolved_format; + } + 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..90ea8a0 --- /dev/null +++ b/i915_private.c @@ -0,0 +1,232 @@ +/* + * 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_I915 + +#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, + DRM_FORMAT_P010 }; + +static const uint32_t private_rgb24_formats[] = { DRM_FORMAT_RGB888, DRM_FORMAT_BGR888 }; + +static const uint32_t private_source_formats[] = { DRM_FORMAT_P010, DRM_FORMAT_NV12_Y_TILED_INTEL }; + +static const uint32_t private_rgba_format[] = { DRM_FORMAT_ABGR2101010, DRM_FORMAT_ABGR16161616F }; + +#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_TEXTURE | BO_USE_CAMERA_MASK); + drv_modify_combination(drv, DRM_FORMAT_YUYV, &metadata, + 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); + drv_modify_combination(drv, DRM_FORMAT_RGB565, &metadata, 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_NONE; + metadata.priority = 1; + metadata.modifier = DRM_FORMAT_MOD_NONE; + drv_add_combinations(drv, private_rgba_format, ARRAY_SIZE(private_rgba_format), &metadata, + BO_USE_SW_WRITE_OFTEN | BO_USE_SCANOUT); + + 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); + + /* Android CTS tests require this. */ + drv_add_combinations(drv, private_rgb24_formats, ARRAY_SIZE(private_rgb24_formats), + &metadata, BO_USE_SW_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; + + int ret = drv_add_combinations(drv, private_linear_source_formats, + ARRAY_SIZE(private_linear_source_formats), &metadata, + texture_flags | BO_USE_CAMERA_MASK); + if (ret) + return ret; + + return 0; + 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_P010: + return (plane == 0) ? 16 : 8; + case DRM_FORMAT_YUV420: + case DRM_FORMAT_YUV422: + case DRM_FORMAT_YUV444: + case DRM_FORMAT_NV16: + return 8; + case DRM_FORMAT_R16: + return 16; + case DRM_FORMAT_ABGR2101010: + return 32; + case DRM_FORMAT_ABGR16161616F: + return 64; + } + + 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: + case DRM_FORMAT_P010: + *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: + case DRM_FORMAT_ABGR2101010: + case DRM_FORMAT_ABGR16161616F: + 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: + 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; +} + +#endif diff --git a/i915_private.h b/i915_private.h new file mode 100644 index 0000000..4fe9a39 --- /dev/null +++ b/i915_private.h @@ -0,0 +1,56 @@ +/* + * 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_I915 + +#include + +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 + */ +#define DRM_FORMAT_P010 fourcc_code('P', '0', '1', '0') /* 2x2 subsampled Cr:Cb plane 10 bits per channel */ + +/* + * 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 */ +#define DRM_FORMAT_ABGR16161616F fourcc_code('A', 'B', '4', 'H') /* [63:0] x:B:G:R 16:16:16:16 little endian */ + +#define DRM_FORMAT_NV12_Y_TILED_INTEL fourcc_code('9', '9', '9', '6') + +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