The multi-planar formats are being allocated into a single plane, and the minigbm exynos backend is dropped. So we can use `handle` instead of handles as of now. Remove some of the helper functions that calculate the number of planes. There is no need to check if there is more than one kernel buffer per buffer object. Added a new function `drv_gem_close` in `drv_helpers` that can be used by `drv_gem_bo_destroy` and `drv_prime_bo_import`. It can be used to clean the unused gem_handle. Bug=b:266776512 TEST=camera and screenshot work fine after deploying the change #strongbad TEST=camera and screenshot work fine after deploying the change #kukui-arc-r TEST=camera and screenshot work fine after deploying the change, tested a couple of apps in the Google Play Store, and checked file `dma_buf/bufinfo` to see there's no object leaking. #guybrush Change-Id: Ib63559504e4cb8f1a32ae90170925146613d694f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/4297873 Commit-Queue: Dawn Han <dawnhan@google.com> Reviewed-by: Yiwei Zhang <zzyiwei@chromium.org> Tested-by: Dawn Han <dawnhan@google.com>
136 lines
3.8 KiB
C
136 lines
3.8 KiB
C
/*
|
|
* 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_VC4
|
|
|
|
#include <errno.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <sys/mman.h>
|
|
#include <vc4_drm.h>
|
|
#include <xf86drm.h>
|
|
|
|
#include "drv_helpers.h"
|
|
#include "drv_priv.h"
|
|
#include "util.h"
|
|
|
|
static const uint32_t render_target_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB565,
|
|
DRM_FORMAT_XRGB8888 };
|
|
|
|
static const uint32_t texture_only_formats[] = { DRM_FORMAT_NV12, DRM_FORMAT_YVU420 };
|
|
|
|
static int vc4_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_only_formats, ARRAY_SIZE(texture_only_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_DECODER | BO_USE_SCANOUT | BO_USE_HW_VIDEO_ENCODER);
|
|
|
|
return drv_modify_linear_combinations(drv);
|
|
}
|
|
|
|
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 = { 0 };
|
|
|
|
switch (modifier) {
|
|
case DRM_FORMAT_MOD_LINEAR:
|
|
break;
|
|
case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED:
|
|
drv_loge("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.
|
|
*/
|
|
stride = drv_stride_from_format(format, width, 0);
|
|
stride = ALIGN(stride, 64);
|
|
drv_bo_from_format(bo, stride, 1, height, format);
|
|
|
|
bo_create.size = bo->meta.total_size;
|
|
|
|
ret = drmIoctl(bo->drv->fd, DRM_IOCTL_VC4_CREATE_BO, &bo_create);
|
|
if (ret) {
|
|
drv_loge("DRM_IOCTL_VC4_CREATE_BO failed (size=%zu)\n", bo->meta.total_size);
|
|
return -errno;
|
|
}
|
|
|
|
bo->handle.u32 = bo_create.handle;
|
|
|
|
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, uint32_t map_flags)
|
|
{
|
|
int ret;
|
|
struct drm_vc4_mmap_bo bo_map = { 0 };
|
|
|
|
bo_map.handle = bo->handle.u32;
|
|
ret = drmCommandWriteRead(bo->drv->fd, DRM_VC4_MMAP_BO, &bo_map, sizeof(bo_map));
|
|
if (ret) {
|
|
drv_loge("DRM_VC4_MMAP_BO failed\n");
|
|
return MAP_FAILED;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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,
|
|
.bo_unmap = drv_bo_munmap,
|
|
.resolve_format_and_use_flags = drv_resolve_format_and_use_flags_helper,
|
|
};
|
|
|
|
#endif
|