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 <lepton@chromium.org>
Tested-by: Lepton Wu <lepton@chromium.org>
Reviewed-by: Lepton Wu <lepton@chromium.org>
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
diff --git a/Android.mk b/Android.mk
index 0abeaf4..e75766f 100644
--- a/Android.mk
+++ b/Android.mk
@@ -26,8 +26,7 @@
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 @@
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 <errno.h>
#include <stdint.h>
#include <stdio.h>
@@ -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 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 @@
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 @@
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 @@
{
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 @@
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