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 <stevensd@chromium.org> Commit-Queue: Gurchetan Singh <gurchetansingh@chromium.org> Tested-by: Gurchetan Singh <gurchetansingh@chromium.org>
This commit is contained in:
parent
69bc430166
commit
bc4f023bfc
10 changed files with 117 additions and 6 deletions
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 &);
|
||||
|
|
|
|||
|
|
@ -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<std::mutex> 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. */
|
||||
|
|
|
|||
|
|
@ -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 &);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "../../util.h"
|
||||
#include "../cros_gralloc_driver.h"
|
||||
|
||||
#include <cassert>
|
||||
|
|
@ -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<uint32_t>(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<uint8_t *>(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:
|
||||
|
|
|
|||
14
drv.c
14
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;
|
||||
}
|
||||
|
|
|
|||
3
drv.h
3
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__); \
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
33
virtio_gpu.c
33
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,
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue