summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Radomski <dextero@google.com>2024-03-12 14:52:04 +0000
committerMarcin Radomski <dextero@google.com>2024-03-12 14:52:29 +0000
commitb1dc3731382333c64f1e3af301f8041911f107ca (patch)
treec28403a41a30f971bcb538c6b28ef19f14fc4184
parent4eceb378d6a3552d85df4285c469b1cd5ab70cad (diff)
parent40b28f098a29589b3f72de1ba6753d46a616c48b (diff)
downloadminigbm-b1dc3731382333c64f1e3af301f8041911f107ca.tar.gz
Merge remote-tracking branch 'cros/main'
To pull in https://crrev.com/c/5352370 and https://crrev.com/c/5352371. Additionally, add backend_mock.c to Android.bp. It was added in https://crrev.com/c/4923791, and drv.c uses symbols defined there unconditionally. The one merge conflict was an i915->is_media_compression_enabled assert in i915_num_planes_from_modifier [1] that was removed upstream in https://crrev.com/c/5118242. The assertion referenced a flag that was set through an ENABLE_INTEL_MEDIA_COMPRESSION environment variable. There are no references to that variable in AOSP sources. [1] https://cs.android.com/android/platform/superproject/main/+/main:external/minigbm/i915.c;l=591;drc=350c09cf0fa662928e208eb6749a1f3ca34dac9f Bug: b/328181805 Test: lunch aosp_cf_x86_64_only_phone-trunk_staging-userdebug Test: m && cvd start && atest SurfaceFlinger_test Change-Id: I8faba268580ad984af92a63c47366d6a69e8c9d0
-rw-r--r--Android.bp1
-rw-r--r--Makefile11
-rw-r--r--backend_mock.c16
-rw-r--r--cros_gralloc/aidl/Allocator.h4
-rw-r--r--drv.c46
-rw-r--r--drv.h21
-rw-r--r--drv_priv.h2
-rw-r--r--gbm.c37
-rw-r--r--gbm.h43
-rw-r--r--gbm_unittest.cc82
-rw-r--r--i915.c144
-rw-r--r--mediatek.c83
-rw-r--r--testrunner.cc15
-rw-r--r--virtgpu.h6
-rw-r--r--virtgpu_cross_domain.c7
-rw-r--r--virtgpu_virgl.c27
16 files changed, 457 insertions, 88 deletions
diff --git a/Android.bp b/Android.bp
index 654af84..ad70ab9 100644
--- a/Android.bp
+++ b/Android.bp
@@ -37,6 +37,7 @@ filegroup {
srcs: [
"amdgpu.c",
+ "backend_mock.c",
"drv.c",
"drv_array_helpers.c",
"drv_helpers.c",
diff --git a/Makefile b/Makefile
index b45226d..db27cf6 100644
--- a/Makefile
+++ b/Makefile
@@ -12,6 +12,10 @@ CPPFLAGS += -D_GNU_SOURCE=1
CFLAGS += -std=c99 -Wall -Wsign-compare -Wpointer-arith -Wcast-qual \
-Wcast-align -D_GNU_SOURCE=1 -D_FILE_OFFSET_BITS=64
+# Dependencies that all gtest based unittests should have.
+UNITTEST_LIBS := -lcap -lgtest -lgmock
+UNITTEST_DEPS := gbm_unittest.o testrunner.o gbm.o dri.o drv_array_helpers.o drv_helpers.o drv.o backend_mock.o virtgpu_cross_domain.o virtgpu_virgl.o virtgpu.o msm.o vc4.o amdgpu.o i915.o mediatek.o dumb_driver.o
+
ifdef DRV_AMDGPU
CFLAGS += $(shell $(PKG_CONFIG) --cflags libdrm_amdgpu)
LDLIBS += -ldrm_amdgpu -ldl
@@ -52,6 +56,13 @@ all: CC_LIBRARY($(MINIGBM_FILENAME))
clean: CLEAN($(MINIGBM_FILENAME))
+CXX_BINARY(gbm_unittest): CXXFLAGS += -Wno-write-strings \
+ $(GTEST_CXXFLAGS)
+CXX_BINARY(gbm_unittest): LDLIBS += $(UNITTEST_LIBS)
+CXX_BINARY(gbm_unittest): $(UNITTEST_DEPS)
+clean: CLEAN(gbm_unittest)
+tests: TEST(CXX_BINARY(gbm_unittest))
+
install: all
mkdir -p $(DESTDIR)/$(LIBDIR)
install -D -m 755 $(OUT)/$(MINIGBM_FILENAME) $(DESTDIR)/$(LIBDIR)
diff --git a/backend_mock.c b/backend_mock.c
new file mode 100644
index 0000000..ae0d758
--- /dev/null
+++ b/backend_mock.c
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2023 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"
+
+static int backend_mock_init(struct driver *drv) {
+ return 0;
+}
+
+const struct backend backend_mock = {
+ .name = "Mock Backend",
+ .init = backend_mock_init,
+};
diff --git a/cros_gralloc/aidl/Allocator.h b/cros_gralloc/aidl/Allocator.h
index 85a13cd..be06dbb 100644
--- a/cros_gralloc/aidl/Allocator.h
+++ b/cros_gralloc/aidl/Allocator.h
@@ -27,10 +27,10 @@ class Allocator : public BnAllocator {
allocator::AllocationResult* outResult) override;
ndk::ScopedAStatus allocate2(const BufferDescriptorInfo& descriptor, int32_t count,
- allocator::AllocationResult* outResult) override;
+ allocator::AllocationResult* outResult) override;
ndk::ScopedAStatus isSupported(const BufferDescriptorInfo& descriptor,
- bool* outResult) override;
+ bool* outResult) override;
ndk::ScopedAStatus getIMapperLibrarySuffix(std::string* outResult) override;
diff --git a/drv.c b/drv.c
index e3a71cb..ea3bd64 100644
--- a/drv.c
+++ b/drv.c
@@ -6,6 +6,7 @@
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
+#include <inttypes.h>
#include <pthread.h>
#include <stdint.h>
#include <stdio.h>
@@ -55,6 +56,8 @@ extern const struct backend backend_virtgpu;
extern const struct backend backend_udl;
extern const struct backend backend_vkms;
+extern const struct backend backend_mock;
+
static const struct backend *drv_backend_list[] = {
#ifdef DRV_AMDGPU
&backend_amdgpu,
@@ -71,7 +74,7 @@ static const struct backend *drv_backend_list[] = {
&backend_evdi, &backend_komeda, &backend_marvell, &backend_mediatek,
&backend_meson, &backend_nouveau, &backend_radeon, &backend_rockchip,
&backend_sun4i_drm, &backend_synaptics, &backend_udl, &backend_virtgpu,
- &backend_vkms
+ &backend_vkms, &backend_mock
};
void drv_preload(bool load)
@@ -118,7 +121,8 @@ struct driver *drv_create(int fd)
const char *minigbm_debug;
minigbm_debug = drv_get_os_option(MINIGBM_DEBUG);
- drv->compression = (minigbm_debug == NULL) || (strcmp(minigbm_debug, "nocompression") != 0);
+ drv->compression = (minigbm_debug == NULL) || (strstr(minigbm_debug, "nocompression") == NULL);
+ drv->log_bos = (minigbm_debug && strstr(minigbm_debug, "log_bos") != NULL);
drv->fd = fd;
drv->backend = drv_get_backend(fd);
@@ -365,6 +369,9 @@ struct bo *drv_bo_create(struct driver *drv, uint32_t width, uint32_t height, ui
drv_bo_acquire(bo);
+ if (drv->log_bos)
+ drv_bo_log_info(bo, "legacy created");
+
return bo;
}
@@ -402,6 +409,9 @@ struct bo *drv_bo_create_with_modifiers(struct driver *drv, uint32_t width, uint
drv_bo_acquire(bo);
+ if (drv->log_bos)
+ drv_bo_log_info(bo, "created");
+
return bo;
}
@@ -460,6 +470,9 @@ struct bo *drv_bo_import(struct driver *drv, struct drv_import_fd_data *data)
bo->meta.total_size += bo->meta.sizes[plane];
}
+ if (drv->log_bos)
+ drv_bo_log_info(bo, "imported");
+
return bo;
destroy_bo:
@@ -574,6 +587,11 @@ out:
return ret;
}
+bool drv_bo_cached(struct bo *bo)
+{
+ return bo->meta.cached;
+}
+
int drv_bo_invalidate(struct bo *bo, struct mapping *mapping)
{
int ret = 0;
@@ -710,6 +728,26 @@ size_t drv_bo_get_total_size(struct bo *bo)
return bo->meta.total_size;
}
+void drv_bo_log_info(const struct bo *bo, const char *prefix)
+{
+ const struct bo_metadata *meta = &bo->meta;
+
+ drv_logd("%s %s bo %p: %dx%d '%c%c%c%c' tiling %d plane %zu mod 0x%" PRIx64 " use 0x%" PRIx64 " size %zu\n",
+ prefix, bo->drv->backend->name, bo,
+ meta->width, meta->height,
+ meta->format & 0xff,
+ (meta->format >> 8) & 0xff,
+ (meta->format >> 16) & 0xff,
+ (meta->format >> 24) & 0xff,
+ meta->tiling, meta->num_planes, meta->format_modifier,
+ meta->use_flags, meta->total_size);
+ for (uint32_t i = 0; i < meta->num_planes; i++) {
+ drv_logd(" bo %p plane %d: offset %d size %d stride %d\n",
+ bo, i, meta->offsets[i], meta->sizes[i],
+ meta->strides[i]);
+ }
+}
+
/*
* Map internal fourcc codes back to standard fourcc codes.
*/
@@ -727,11 +765,11 @@ void drv_resolve_format_and_use_flags(struct driver *drv, uint32_t format, uint6
out_use_flags);
}
-void drv_log_prefix(enum drv_log_level level, const char *prefix, const char *file, int line,
+void drv_log_prefix(enum drv_log_level level, const char *prefix, const char *func, int line,
const char *format, ...)
{
char buf[50];
- snprintf(buf, sizeof(buf), "[%s:%s(%d)]", prefix, basename(file), line);
+ snprintf(buf, sizeof(buf), "[%s:%s(%d)]", prefix, func, line);
va_list args;
va_start(args, format);
diff --git a/drv.h b/drv.h
index 106c29c..b61aedf 100644
--- a/drv.h
+++ b/drv.h
@@ -83,6 +83,21 @@ extern "C" {
#ifndef I915_FORMAT_MOD_4_TILED
#define I915_FORMAT_MOD_4_TILED fourcc_mod_code(INTEL, 9)
#endif
+
+#ifndef I915_FORMAT_MOD_4_TILED_MTL_RC_CCS
+//TODO: remove this defination once drm_fourcc.h contains it.
+/*
+ * Intel color control surfaces (CCS) for display ver 14 render compression.
+ *
+ * The main surface is tile4 and at plane index 0, the CCS is linear and
+ * at index 1. A 64B CCS cache line corresponds to an area of 4x1 tiles in
+ * main surface. In other words, 4 bits in CCS map to a main surface cache
+ * line pair. The main surface pitch is required to be a multiple of four
+ * tile4 widths.
+ */
+#define I915_FORMAT_MOD_4_TILED_MTL_RC_CCS fourcc_mod_code(INTEL, 13)
+#endif
+
// clang-format on
struct driver;
struct bo;
@@ -161,6 +176,8 @@ 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);
+bool drv_bo_cached(struct bo *bo);
+
int drv_bo_invalidate(struct bo *bo, struct mapping *mapping);
int drv_bo_flush(struct bo *bo, struct mapping *mapping);
@@ -193,6 +210,8 @@ uint64_t drv_bo_get_use_flags(struct bo *bo);
size_t drv_bo_get_total_size(struct bo *bo);
+void drv_bo_log_info(const struct bo *bo, const char *prefix);
+
uint32_t drv_get_standard_fourcc(uint32_t fourcc_internal);
uint32_t drv_bytes_per_pixel_from_format(uint32_t format, size_t plane);
@@ -221,7 +240,7 @@ enum drv_log_level {
#define _drv_log(level, format, ...) \
do { \
- drv_log_prefix(level, "minigbm", __FILE__, __LINE__, format, ##__VA_ARGS__); \
+ drv_log_prefix(level, "minigbm", __func__, __LINE__, format, ##__VA_ARGS__); \
} while (0)
#define drv_loge(format, ...) _drv_log(DRV_LOGE, format, ##__VA_ARGS__)
diff --git a/drv_priv.h b/drv_priv.h
index d9888d0..337b58e 100644
--- a/drv_priv.h
+++ b/drv_priv.h
@@ -27,6 +27,7 @@ struct bo_metadata {
uint64_t format_modifier;
uint64_t use_flags;
size_t total_size;
+ bool cached;
/*
* Most of the following metadata is virtgpu cross_domain specific. However, that backend
@@ -70,6 +71,7 @@ struct driver {
struct drv_array *mappings;
struct drv_array *combos;
bool compression;
+ bool log_bos;
};
struct backend {
diff --git a/gbm.c b/gbm.c
index 190347e..408fb98 100644
--- a/gbm.c
+++ b/gbm.c
@@ -87,10 +87,21 @@ PUBLIC struct gbm_surface *gbm_surface_create_with_modifiers(struct gbm_device *
const uint64_t *modifiers,
const unsigned int count)
{
+ return gbm_surface_create_with_modifiers2(gbm, width, height, format, modifiers, count, 0);
+}
+
+PUBLIC struct gbm_surface *
+gbm_surface_create_with_modifiers2(struct gbm_device *gbm, uint32_t width, uint32_t height,
+ uint32_t format, const uint64_t *modifiers,
+ const unsigned int count, uint32_t flags)
+{
if (count != 0 || modifiers != NULL)
return NULL;
- return gbm_surface_create(gbm, width, height, format, 0);
+ if (flags != 0)
+ return NULL;
+
+ return gbm_surface_create(gbm, width, height, format, flags);
}
PUBLIC struct gbm_bo *gbm_surface_lock_front_buffer(struct gbm_surface *surface)
@@ -161,8 +172,19 @@ PUBLIC struct gbm_bo *gbm_bo_create_with_modifiers(struct gbm_device *gbm, uint3
uint32_t height, uint32_t format,
const uint64_t *modifiers, uint32_t count)
{
+ return gbm_bo_create_with_modifiers2(gbm, width, height, format, modifiers, count, 0);
+}
+
+PUBLIC struct gbm_bo *gbm_bo_create_with_modifiers2(struct gbm_device *gbm, uint32_t width,
+ uint32_t height, uint32_t format,
+ const uint64_t *modifiers,
+ const unsigned int count, uint32_t flags)
+{
struct gbm_bo *bo;
+ if (flags != 0)
+ return NULL;
+
bo = gbm_bo_new(gbm, format);
if (!bo)
@@ -267,6 +289,13 @@ PUBLIC void *gbm_bo_map(struct gbm_bo *bo, uint32_t x, uint32_t y, uint32_t widt
return gbm_bo_map2(bo, x, y, width, height, transfer_flags, stride, map_data, 0);
}
+PUBLIC enum gbm_bo_map_cache_mode gbm_bo_get_map_info(struct gbm_bo *bo)
+{
+ if (drv_bo_cached(bo->bo))
+ return GBM_BO_MAP_CACHE_CACHED;
+ return GBM_BO_MAP_CACHE_WC;
+}
+
PUBLIC void gbm_bo_unmap(struct gbm_bo *bo, void *map_data)
{
assert(bo);
@@ -323,7 +352,7 @@ 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_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, int plane)
{
return (union gbm_bo_handle)drv_bo_get_plane_handle(bo->bo, (size_t)plane).u64;
}
@@ -333,12 +362,12 @@ PUBLIC int gbm_bo_get_fd_for_plane(struct gbm_bo *bo, int plane)
return drv_bo_get_plane_fd(bo->bo, plane);
}
-PUBLIC uint32_t gbm_bo_get_offset(struct gbm_bo *bo, size_t plane)
+PUBLIC uint32_t gbm_bo_get_offset(struct gbm_bo *bo, int plane)
{
return drv_bo_get_plane_offset(bo->bo, (size_t)plane);
}
-PUBLIC uint32_t gbm_bo_get_stride_for_plane(struct gbm_bo *bo, size_t plane)
+PUBLIC uint32_t gbm_bo_get_stride_for_plane(struct gbm_bo *bo, int plane)
{
return drv_bo_get_plane_stride(bo->bo, (size_t)plane);
}
diff --git a/gbm.h b/gbm.h
index 7fae11c..8e32769 100644
--- a/gbm.h
+++ b/gbm.h
@@ -339,6 +339,16 @@ gbm_bo_create_with_modifiers(struct gbm_device *gbm,
uint32_t format,
const uint64_t *modifiers,
const unsigned int count);
+
+struct gbm_bo *
+gbm_bo_create_with_modifiers2(struct gbm_device *gbm,
+ uint32_t width,
+ uint32_t height,
+ uint32_t format,
+ const uint64_t *modifiers,
+ const unsigned int count,
+ uint32_t flags);
+
#define GBM_BO_IMPORT_WL_BUFFER 0x5501
#define GBM_BO_IMPORT_EGL_IMAGE 0x5502
#define GBM_BO_IMPORT_FD 0x5503
@@ -403,6 +413,24 @@ 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);
+/**
+ * Enum to indicate the cache attributes of CPU mapping returned by
+ * gbm_bo_map()
+ *
+ * Note that definition aligns with VIRTIO_GPU_MAP_CACHE_*, RUTABAGA_MAP_CACHE_*,
+ * and VIRGL_RENDERER_MAP_CACHE_* (but skipping the _NONE and _UNCACHED values as
+ * those don't actually make sense to use).
+ */
+enum gbm_bo_map_cache_mode {
+ /*GBM_BO_MAP_CACHE_NONE = 0,*/
+ GBM_BO_MAP_CACHE_CACHED = 1,
+ /*GBM_BO_MAP_CACHE_UNCACHED = 2,*/
+ GBM_BO_MAP_CACHE_WC = 3,
+};
+
+enum gbm_bo_map_cache_mode
+gbm_bo_get_map_info(struct gbm_bo *bo);
+
void
gbm_bo_unmap(struct gbm_bo *bo, void *map_data);
@@ -416,7 +444,7 @@ uint32_t
gbm_bo_get_stride(struct gbm_bo *bo);
uint32_t
-gbm_bo_get_stride_for_plane(struct gbm_bo *bo, size_t plane);
+gbm_bo_get_stride_for_plane(struct gbm_bo *bo, int plane);
uint32_t
gbm_bo_get_format(struct gbm_bo *bo);
@@ -425,7 +453,7 @@ uint32_t
gbm_bo_get_bpp(struct gbm_bo *bo);
uint32_t
-gbm_bo_get_offset(struct gbm_bo *bo, size_t plane);
+gbm_bo_get_offset(struct gbm_bo *bo, int plane);
struct gbm_device *
gbm_bo_get_device(struct gbm_bo *bo);
@@ -443,7 +471,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, size_t plane);
+gbm_bo_get_handle_for_plane(struct gbm_bo *bo, int plane);
int
gbm_bo_get_fd_for_plane(struct gbm_bo *bo, int plane);
@@ -473,6 +501,15 @@ gbm_surface_create_with_modifiers(struct gbm_device *gbm,
const uint64_t *modifiers,
const unsigned int count);
+struct gbm_surface *
+gbm_surface_create_with_modifiers2(struct gbm_device *gbm,
+ uint32_t width,
+ uint32_t height,
+ uint32_t format,
+ const uint64_t *modifiers,
+ const unsigned int count,
+ uint32_t flags);
+
struct gbm_bo *
gbm_surface_lock_front_buffer(struct gbm_surface *surface);
diff --git a/gbm_unittest.cc b/gbm_unittest.cc
new file mode 100644
index 0000000..9f2a46f
--- /dev/null
+++ b/gbm_unittest.cc
@@ -0,0 +1,82 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Test gbm.h module code using gtest.
+ */
+
+#include <drm/drm_fourcc.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <xf86drm.h>
+
+#include "gbm.h"
+
+class MockDrm
+{
+ public:
+ MOCK_METHOD(drmVersionPtr, drmGetVersion, (int fd));
+ MOCK_METHOD(void, drmFreeVersion, (drmVersionPtr v));
+};
+
+// Define a mock version of drmGetVersion
+drmVersionPtr drmGetVersion(int fd)
+{
+ drmVersionPtr mock_version = new drmVersion();
+ mock_version->name = "Mock Backend";
+ return mock_version;
+}
+
+// Define a mock version of drmFreeVersion
+void drmFreeVersion(drmVersionPtr v)
+{
+ delete(v);
+}
+
+/* TODO : This is a protocol to add unit tests for the public APIs in minigbm.
+ *
+ * The ultimate goal would be cover more APIs and the input combinations.
+ * Set fd to 0 for now, it doesn't have any particular meaning
+ */
+
+TEST(gbm_unit_test, create_device)
+{
+ MockDrm mock_drm; // Create a mock object
+
+ EXPECT_CALL(mock_drm, drmGetVersion(testing::_))
+ .WillRepeatedly(testing::Invoke(&mock_drm, &MockDrm::drmGetVersion));
+
+ struct gbm_device *gbm_device = gbm_create_device(0);
+
+ ASSERT_TRUE(gbm_device);
+
+ gbm_device_destroy(gbm_device);
+}
+
+TEST(gbm_unit_test, valid_fd)
+{
+ MockDrm mock_drm; // Create a mock object
+
+ EXPECT_CALL(mock_drm, drmGetVersion(testing::_))
+ .WillRepeatedly(testing::Invoke(&mock_drm, &MockDrm::drmGetVersion));
+ struct gbm_device *gbm_device = gbm_create_device(99);
+ int fd = gbm_device_get_fd(gbm_device);
+
+ ASSERT_EQ(fd, 99);
+
+ gbm_device_destroy(gbm_device);
+}
+
+TEST(gbm_unit_test, valid_backend_name)
+{
+ MockDrm mock_drm; // Create a mock object
+
+ EXPECT_CALL(mock_drm, drmGetVersion(testing::_))
+ .WillRepeatedly(testing::Invoke(&mock_drm, &MockDrm::drmGetVersion));
+ struct gbm_device *gbm_device = gbm_create_device(0);
+ const char *backend_name = gbm_device_get_backend_name(gbm_device);
+
+ ASSERT_STREQ(backend_name, "Mock Backend");
+
+ gbm_device_destroy(gbm_device);
+}
diff --git a/i915.c b/i915.c
index 96333df..b9e377f 100644
--- a/i915.c
+++ b/i915.c
@@ -37,21 +37,16 @@ static const uint32_t texture_only_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_NV12,
static const uint64_t gen_modifier_order[] = { I915_FORMAT_MOD_Y_TILED_CCS, I915_FORMAT_MOD_Y_TILED,
I915_FORMAT_MOD_X_TILED, DRM_FORMAT_MOD_LINEAR };
-static const uint64_t gen12_modifier_order_without_mc[] = { I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS,
- I915_FORMAT_MOD_Y_TILED,
- I915_FORMAT_MOD_X_TILED,
- DRM_FORMAT_MOD_LINEAR };
-
-static const uint64_t gen12_modifier_order_with_mc[] = { I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS,
- I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS,
- I915_FORMAT_MOD_Y_TILED,
- I915_FORMAT_MOD_X_TILED,
- DRM_FORMAT_MOD_LINEAR };
+static const uint64_t gen12_modifier_order[] = {
+ I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS, I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS,
+ I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED, DRM_FORMAT_MOD_LINEAR
+};
static const uint64_t gen11_modifier_order[] = { I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED,
DRM_FORMAT_MOD_LINEAR };
-static const uint64_t xe_lpdp_modifier_order[] = { I915_FORMAT_MOD_4_TILED, I915_FORMAT_MOD_X_TILED,
+static const uint64_t xe_lpdp_modifier_order[] = { I915_FORMAT_MOD_4_TILED_MTL_RC_CCS,
+ I915_FORMAT_MOD_4_TILED, I915_FORMAT_MOD_X_TILED,
DRM_FORMAT_MOD_LINEAR };
struct modifier_support_t {
@@ -70,7 +65,6 @@ struct i915_device {
bool is_mtl;
int32_t num_fences_avail;
bool has_mmap_offset;
- bool is_media_compression_enabled;
};
static void i915_info_from_device_id(struct i915_device *i915)
@@ -120,9 +114,10 @@ static void i915_info_from_device_id(struct i915_device *i915)
};
const uint16_t adlp_ids[] = { 0x46A0, 0x46A1, 0x46A2, 0x46A3, 0x46A6, 0x46A8, 0x46AA,
0x462A, 0x4626, 0x4628, 0x46B0, 0x46B1, 0x46B2, 0x46B3,
- 0x46C0, 0x46C1, 0x46C2, 0x46C3, 0x46D0, 0x46D1, 0x46D2 };
+ 0x46C0, 0x46C1, 0x46C2, 0x46C3, 0x46D0, 0x46D1, 0x46D2,
+ 0x46D3, 0x46D4 };
- const uint16_t rplp_ids[] = { 0xA720, 0xA721, 0xA7A0, 0xA7A1, 0xA7A8, 0xA7A9 };
+ const uint16_t rplp_ids[] = { 0xA720, 0xA721, 0xA7A0, 0xA7A1, 0xA7A8, 0xA7A9, 0xA7AA, 0xA7AB, 0xA7AC, 0xA7AD };
const uint16_t mtl_ids[] = { 0x7D40, 0x7D60, 0x7D45, 0x7D55, 0x7DD5 };
@@ -200,13 +195,12 @@ static void i915_get_modifier_order(struct i915_device *i915)
i915->modifier.order = xe_lpdp_modifier_order;
i915->modifier.count = ARRAY_SIZE(xe_lpdp_modifier_order);
} else if (i915->graphics_version == 12) {
- if (i915->is_media_compression_enabled) {
- i915->modifier.order = gen12_modifier_order_with_mc;
- i915->modifier.count = ARRAY_SIZE(gen12_modifier_order_with_mc);
- } else {
- i915->modifier.order = gen12_modifier_order_without_mc;
- i915->modifier.count = ARRAY_SIZE(gen12_modifier_order_without_mc);
- }
+ /*
+ * On ADL platforms of gen 12 onwards, Intel media compression is supported for
+ * video decoding on Chrome.
+ */
+ i915->modifier.order = gen12_modifier_order;
+ i915->modifier.count = ARRAY_SIZE(gen12_modifier_order);
} else if (i915->graphics_version == 11) {
i915->modifier.order = gen11_modifier_order;
i915->modifier.count = ARRAY_SIZE(gen11_modifier_order);
@@ -308,14 +302,10 @@ static int i915_add_combinations(struct driver *drv)
ARRAY_SIZE(scanout_render_formats), &metadata_4_tiled,
scanout_and_render_not_linear);
} else {
- struct format_metadata metadata_y_tiled = {
- .tiling = I915_TILING_Y,
- .priority = 3,
- .modifier =
- (i915->graphics_version == 12 && i915->is_media_compression_enabled)
- ? I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS
- : I915_FORMAT_MOD_Y_TILED
- };
+ struct format_metadata metadata_y_tiled = { .tiling = I915_TILING_Y,
+ .priority = 3,
+ .modifier = I915_FORMAT_MOD_Y_TILED };
+
/* Support y-tiled NV12 and P010 for libva */
#ifdef I915_SCANOUT_Y_TILED
const uint64_t nv12_usage =
@@ -327,13 +317,6 @@ static int i915_add_combinations(struct driver *drv)
const uint64_t nv12_usage = BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER;
const uint64_t p010_usage = nv12_usage;
#endif
- drv_add_combination(drv, DRM_FORMAT_NV12, &metadata_y_tiled, nv12_usage);
- drv_add_combination(drv, DRM_FORMAT_P010, &metadata_y_tiled, p010_usage);
-
- /* Don't allocate media compressed buffers for formats other than NV12
- * and P010.
- */
- metadata_y_tiled.modifier = I915_FORMAT_MOD_Y_TILED;
drv_add_combinations(drv, render_formats, ARRAY_SIZE(render_formats),
&metadata_y_tiled, render_not_linear);
/* Y-tiled scanout isn't available on old platforms so we add
@@ -342,6 +325,8 @@ static int i915_add_combinations(struct driver *drv)
drv_add_combinations(drv, scanout_render_formats,
ARRAY_SIZE(scanout_render_formats), &metadata_y_tiled,
render_not_linear);
+ drv_add_combination(drv, DRM_FORMAT_NV12, &metadata_y_tiled, nv12_usage);
+ drv_add_combination(drv, DRM_FORMAT_P010, &metadata_y_tiled, p010_usage);
}
return 0;
}
@@ -459,17 +444,6 @@ static int i915_init(struct driver *drv)
if (!i915)
return -ENOMEM;
- const char *enable_intel_media_compression_env_var =
- getenv("ENABLE_INTEL_MEDIA_COMPRESSION");
- if (enable_intel_media_compression_env_var == NULL) {
- drv_logd("Failed to get ENABLE_INTEL_MEDIA_COMPRESSION");
- i915->is_media_compression_enabled = false;
- } else {
- i915->is_media_compression_enabled =
- (drv->compression) &&
- (strcmp(enable_intel_media_compression_env_var, "1") == 0);
- }
-
get_param.param = I915_PARAM_CHIPSET_ID;
get_param.value = &(i915->device_id);
ret = drmIoctl(drv->fd, DRM_IOCTL_I915_GETPARAM, &get_param);
@@ -584,15 +558,11 @@ static size_t i915_num_planes_from_modifier(struct driver *drv, uint32_t format,
{
size_t num_planes = drv_num_planes_from_format(format);
if (modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
- modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS) {
+ modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS ||
+ modifier == I915_FORMAT_MOD_4_TILED_MTL_RC_CCS) {
assert(num_planes == 1);
return 2;
} else if (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS) {
- assert(drv);
- struct i915_device *i915 = drv->priv;
- assert(i915 && i915->is_media_compression_enabled);
- (void)i915;
-
assert(num_planes == 2);
return 4;
}
@@ -615,6 +585,19 @@ static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t heig
if (!combo)
return -EINVAL;
modifier = combo->metadata.modifier;
+ /*
+ * Media compression modifiers should not be picked automatically by minigbm based
+ * on |use_flags|. Instead the client should request them explicitly through
+ * gbm_bo_create_with_modifiers().
+ */
+ assert(modifier != I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS);
+ /* TODO(b/323863689): Account for driver's bandwidth compression in minigbm for
+ * media compressed buffers. */
+ }
+ if (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS &&
+ !(format == DRM_FORMAT_NV12 || format == DRM_FORMAT_P010)) {
+ drv_loge("Media compression is only supported for NV12 and P010\n");
+ return -EINVAL;
}
/*
@@ -655,9 +638,6 @@ static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t heig
modifier = DRM_FORMAT_MOD_LINEAR;
}
- assert(modifier != I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS ||
- i915->is_media_compression_enabled);
-
switch (modifier) {
case DRM_FORMAT_MOD_LINEAR:
bo->meta.tiling = I915_TILING_NONE;
@@ -675,6 +655,7 @@ static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t heig
bo->meta.tiling = I915_TILING_Y;
break;
case I915_FORMAT_MOD_4_TILED:
+ case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS:
bo->meta.tiling = I915_TILING_4;
break;
}
@@ -735,10 +716,17 @@ static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t heig
bo->meta.total_size = offset;
} else if (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS ||
modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS) {
+ /*
+ * Media compression modifiers should only be possible via the
+ * gbm_bo_create_with_modifiers() path, i.e., the minigbm client needs to
+ * explicitly request it.
+ */
+ assert(modifier != I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS ||
+ use_flags == BO_USE_NONE);
assert(modifier != I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS ||
- i915->is_media_compression_enabled);
+ bo->meta.use_flags == BO_USE_NONE);
assert(modifier != I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS ||
- (format == DRM_FORMAT_NV12 || format == DRM_FORMAT_P010));
+ (!!modifiers && count > 0));
assert(drv_num_planes_from_format(format) > 0);
uint32_t offset = 0;
@@ -794,6 +782,39 @@ static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t heig
/* Total number of planes & sizes */
bo->meta.num_planes = plane + a_plane;
bo->meta.total_size = offset;
+ } else if (modifier == I915_FORMAT_MOD_4_TILED_MTL_RC_CCS) {
+
+ /*
+ * considering only 128 byte compression and one cache line of
+ * aux buffer(64B) contains compression status of 4-Y tiles.
+ * Which is 4 * (128B * 32L).
+ * line stride(bytes) is 4 * 128B
+ * and tile stride(lines) is 32L
+ */
+ uint32_t stride = ALIGN(drv_stride_from_format(format, width, 0), 512);
+ stride = ALIGN(stride, 256);
+
+ height = ALIGN(drv_height_from_format(format, height, 0), 32);
+
+
+ bo->meta.strides[0] = stride;
+ /* size calculation and alignment are 64KB aligned
+ * size as per spec
+ */
+ bo->meta.sizes[0] = ALIGN(stride * height, 65536);
+ bo->meta.offsets[0] = 0;
+
+ /* Aux buffer is linear and page aligned. It is placed after
+ * other planes and aligned to main buffer stride.
+ */
+ bo->meta.strides[1] = bo->meta.strides[0] / 8;
+
+ /* Aligned to page size */
+ bo->meta.sizes[1] = ALIGN(bo->meta.sizes[0] / 256, getpagesize());
+ bo->meta.offsets[1] = bo->meta.sizes[0];
+ /* Total number of planes & sizes */
+ bo->meta.num_planes = 2;
+ bo->meta.total_size = bo->meta.sizes[0] + bo->meta.sizes[1];
} else {
return i915_bo_from_format(bo, width, height, format);
}
@@ -858,6 +879,10 @@ static int i915_bo_create_from_metadata(struct bo *bo)
return -errno;
}
}
+
+ bo->meta.cached = (i915->has_llc || i915->is_mtl) &&
+ !(bo->meta.use_flags & BO_USE_SCANOUT);
+
return 0;
}
@@ -907,7 +932,8 @@ static void *i915_bo_map(struct bo *bo, struct vma *vma, uint32_t map_flags)
if ((bo->meta.format_modifier == I915_FORMAT_MOD_Y_TILED_CCS) ||
(bo->meta.format_modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS) ||
(bo->meta.format_modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS) ||
- (bo->meta.format_modifier == I915_FORMAT_MOD_4_TILED))
+ (bo->meta.format_modifier == I915_FORMAT_MOD_4_TILED) ||
+ (bo->meta.format_modifier == I915_FORMAT_MOD_4_TILED_MTL_RC_CCS))
return MAP_FAILED;
if (bo->meta.tiling == I915_TILING_NONE) {
diff --git a/mediatek.c b/mediatek.c
index 2d60462..6ebde6e 100644
--- a/mediatek.c
+++ b/mediatek.c
@@ -47,6 +47,17 @@
#define DONT_USE_64_ALIGNMENT_FOR_VIDEO_BUFFERS
#endif
+// Devices newer than MT8186 support AR30 overlays and 10-bit video.
+// clang-format off
+#if !defined(MTK_MT8173) && \
+ !defined(MTK_MT8183) && \
+ !defined(MTK_MT8186) && \
+ !defined(MTK_MT8192)
+// clang-format on
+#define SUPPORT_P010
+#define SUPPORT_AR30_OVERLAYS
+#endif
+
// For Mali Sigurd based GPUs, the texture unit reads outside the specified texture dimensions.
// Therefore, certain formats require extra memory padding to its allocated surface to prevent the
// hardware from reading outside an allocation. For YVU420, we need additional padding for the last
@@ -71,6 +82,9 @@ static const uint32_t texture_source_formats[] = {
DRM_FORMAT_NV21,
DRM_FORMAT_YUYV,
#endif
+#ifdef SUPPORT_P010
+ DRM_FORMAT_P010,
+#endif
#ifdef SUPPORT_FP16_AND_10BIT_ABGR
DRM_FORMAT_ABGR2101010,
DRM_FORMAT_ABGR16161616F,
@@ -83,6 +97,9 @@ static const uint32_t texture_source_formats[] = {
static const uint32_t video_yuv_formats[] = {
DRM_FORMAT_NV21,
DRM_FORMAT_NV12,
+#ifdef SUPPORT_P010
+ DRM_FORMAT_P010,
+#endif
DRM_FORMAT_YUYV,
DRM_FORMAT_YVU420,
DRM_FORMAT_YVU420_ANDROID
@@ -110,7 +127,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 | BO_USE_PROTECTED);
- drv_add_combination(drv, DRM_FORMAT_R8, &LINEAR_METADATA, BO_USE_SW_MASK | BO_USE_LINEAR | BO_USE_PROTECTED);
+ drv_add_combination(drv, DRM_FORMAT_R8, &LINEAR_METADATA,
+ BO_USE_SW_MASK | BO_USE_LINEAR | BO_USE_PROTECTED);
+
+#ifdef SUPPORT_AR30_OVERLAYS
+ drv_add_combination(drv, DRM_FORMAT_ARGB2101010, &LINEAR_METADATA,
+ BO_USE_TEXTURE | BO_USE_SCANOUT | BO_USE_PROTECTED | BO_USE_LINEAR);
+#endif
/* YUYV format for video overlay and camera subsystem. */
drv_add_combination(drv, DRM_FORMAT_YUYV, &LINEAR_METADATA,
@@ -124,12 +147,26 @@ static int mediatek_init(struct driver *drv)
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 | BO_USE_PROTECTED);
- drv_modify_combination(drv, DRM_FORMAT_YVU420_ANDROID, &metadata, BO_USE_HW_VIDEO_DECODER | BO_USE_PROTECTED);
+ drv_modify_combination(drv, DRM_FORMAT_YVU420, &metadata,
+ BO_USE_HW_VIDEO_DECODER | BO_USE_PROTECTED);
+#ifdef MTK_MT8173
+ /*
+ * b/292507490: The MT8173 decoder can output YUV420 only. Some CTS tests feed the
+ * decoded buffer to the hardware encoder and the tests allocate the buffer with
+ * DRM_FORMAT_FLEX_YCbCr_420_888 with the mask of BO_USE_HW_VIDEO_ENCODER |
+ * BO_USE_HW_VIDEO_DECODER. Therefore, we have to allocate YUV420 in the case.
+ */
+ drv_modify_combination(drv, DRM_FORMAT_YVU420, &metadata, BO_USE_HW_VIDEO_ENCODER);
+#endif
+ drv_modify_combination(drv, DRM_FORMAT_YVU420_ANDROID, &metadata,
+ BO_USE_HW_VIDEO_DECODER | BO_USE_PROTECTED);
#ifdef USE_NV12_FOR_HW_VIDEO_DECODING
// TODO(hiroh): Switch to use NV12 for video decoder on MT8173 as well.
- drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata, BO_USE_HW_VIDEO_DECODER | BO_USE_PROTECTED);
+ drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata,
+ BO_USE_HW_VIDEO_DECODER | BO_USE_PROTECTED);
#endif
+ drv_modify_combination(drv, DRM_FORMAT_P010, &metadata,
+ BO_USE_HW_VIDEO_DECODER | BO_USE_PROTECTED);
/*
* R8 format is used for Android's HAL_PIXEL_FORMAT_BLOB for input/output from
@@ -176,6 +213,11 @@ static int mediatek_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint
const bool is_camera_preview =
(bo->meta.use_flags & BO_USE_SCANOUT) && (bo->meta.use_flags & BO_USE_CAMERA_WRITE);
const bool is_hw_video_encoder = bo->meta.use_flags & BO_USE_HW_VIDEO_ENCODER;
+#ifdef MTK_MT8173
+ const bool is_mt8173_video_decoder = bo->meta.use_flags & BO_USE_HW_VIDEO_DECODER;
+#else
+ const bool is_mt8173_video_decoder = false;
+#endif
/*
* Android sends blobs for encoding in the shape of a single-row pixel buffer. Use R8 +
* single row as a proxy for Android HAL_PIXEL_FORMAT_BLOB until a drm equivalent is
@@ -203,7 +245,24 @@ static int mediatek_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint
stride = ALIGN(stride, 64);
#endif
- if ((is_hw_video_encoder && !is_format_blob) || is_camera_preview) {
+ /*
+ * The mediatek video decoder requires to align width and height by 64. But this is
+ * the requirement for mediatek tiled format (e.g. MT21 and MM21). The buffers are
+ * not allocated by minigbm. So we don't have to care about it. The tiled buffer is
+ * converted to NV12 or YV12, which is allocated by minigbm. V4L2 MDP doesn't
+ * require any special alignment for them.
+ * On the other hand, the mediatek video encoder reuqires a padding on each plane.
+ * When both video decoder and encoder use flag is masked (in some CTS test), we
+ * align with the encoder alignment.
+ * However, V4L2VideoDecodeAccelerator used on MT8173 fails handling the buffer with
+ * padding, although V4L2VideoDecoder used on MT8183 and later can do. We workaround
+ * this problem to allocate a buffer without padding on MT8173. This works because
+ * MT8173 decoder's output NV12 is converted to YV12 buffer that is allocated with
+ * video encoder usage mask only and thus have padding in Android.
+ * See go/mediatek-video-buffer-alignment-note for detail.
+ */
+ if ((is_hw_video_encoder && !is_mt8173_video_decoder && !is_format_blob) ||
+ is_camera_preview) {
uint32_t aligned_height = ALIGN(height, 32);
uint32_t padding[DRV_MAX_PLANES] = { 0 };
@@ -432,12 +491,24 @@ static void mediatek_resolve_format_and_use_flags(struct driver *drv, uint32_t f
break;
}
#endif
+ /*
+ * b/292507490: The MT8173 decoder can output YUV420 only. Some CTS tests feed the
+ * decoded buffer to the hardware encoder and the tests allocate the buffer with
+ * DRM_FORMAT_FLEX_YCbCr_420_888 with the mask of BO_USE_HW_VIDEO_ENCODER |
+ * BO_USE_HW_VIDEO_DECODER. Therefore, we have to allocate YUV420 in the case.
+ */
if (use_flags &
(BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_ENCODER)) {
+#ifndef MTK_MT8173
*out_format = DRM_FORMAT_NV12;
break;
+#else
+ if (!(use_flags & BO_USE_HW_VIDEO_DECODER)) {
+ *out_format = DRM_FORMAT_NV12;
+ break;
+ }
+#endif
}
-
/* HACK: See b/139714614 */
*out_format = DRM_FORMAT_YVU420;
*out_use_flags &= ~BO_USE_SCANOUT;
diff --git a/testrunner.cc b/testrunner.cc
new file mode 100644
index 0000000..37a858f
--- /dev/null
+++ b/testrunner.cc
@@ -0,0 +1,15 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Main entrypoint for gtest.
+ */
+
+#include <gtest/gtest.h>
+
+int main(int argc, char **argv)
+{
+ testing::InitGoogleTest(&argc, argv);
+
+ return RUN_ALL_TESTS();
+}
diff --git a/virtgpu.h b/virtgpu.h
index 3f68731..b2f82ba 100644
--- a/virtgpu.h
+++ b/virtgpu.h
@@ -23,3 +23,9 @@ enum virtgpu_param_id {
param_guest_vram,
param_max,
};
+
+#define VIRTIO_GPU_CAPSET_VIRGL 1
+#define VIRTIO_GPU_CAPSET_VIRGL2 2
+#define VIRTIO_GPU_CAPSET_GFXSTREAM 3
+#define VIRTIO_GPU_CAPSET_VENUS 4
+#define VIRTIO_GPU_CAPSET_CROSS_DOMAIN 5
diff --git a/virtgpu_cross_domain.c b/virtgpu_cross_domain.c
index dc3fbc1..85589dc 100644
--- a/virtgpu_cross_domain.c
+++ b/virtgpu_cross_domain.c
@@ -16,7 +16,6 @@
#include "util.h"
#include "virtgpu.h"
-#define CAPSET_CROSS_DOMAIN 5
#define CAPSET_CROSS_FAKE 30
static const uint32_t scanout_render_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888,
@@ -246,7 +245,7 @@ static int cross_domain_init(struct driver *drv)
if (!params[param_context_init].value)
return -ENOTSUP;
- if ((params[param_supported_capset_ids].value & (1 << CAPSET_CROSS_DOMAIN)) == 0)
+ if ((params[param_supported_capset_ids].value & (1 << VIRTIO_GPU_CAPSET_CROSS_DOMAIN)) == 0)
return -ENOTSUP;
if (!params[param_resource_blob].value)
@@ -275,7 +274,7 @@ static int cross_domain_init(struct driver *drv)
priv->ring_addr = MAP_FAILED;
drv->priv = priv;
- args.cap_set_id = CAPSET_CROSS_DOMAIN;
+ args.cap_set_id = VIRTIO_GPU_CAPSET_CROSS_DOMAIN;
args.size = sizeof(struct CrossDomainCapabilities);
args.addr = (unsigned long long)&cross_domain_caps;
@@ -296,7 +295,7 @@ static int cross_domain_init(struct driver *drv)
// Intialize the cross domain context. Create one fence context to wait for metadata
// queries.
ctx_set_params[0].param = VIRTGPU_CONTEXT_PARAM_CAPSET_ID;
- ctx_set_params[0].value = CAPSET_CROSS_DOMAIN;
+ ctx_set_params[0].value = VIRTIO_GPU_CAPSET_CROSS_DOMAIN;
ctx_set_params[1].param = VIRTGPU_CONTEXT_PARAM_NUM_RINGS;
ctx_set_params[1].value = 1;
diff --git a/virtgpu_virgl.c b/virtgpu_virgl.c
index b8517fc..222703e 100644
--- a/virtgpu_virgl.c
+++ b/virtgpu_virgl.c
@@ -549,14 +549,31 @@ static int virgl_get_caps(struct driver *drv, union virgl_caps *caps, int *caps_
int ret;
struct drm_virtgpu_get_caps cap_args = { 0 };
+ memset(caps, 0, sizeof(union virgl_caps));
*caps_is_v2 = 0;
- cap_args.addr = (unsigned long long)caps;
- if (params[param_capset_fix].value) {
+
+ if (params[param_supported_capset_ids].value) {
+ drv_logi("Supported CAPSET IDs: %u.", params[param_supported_capset_ids].value);
+ if (params[param_supported_capset_ids].value & (1 << VIRTIO_GPU_CAPSET_VIRGL2)) {
+ *caps_is_v2 = 1;
+ } else if (params[param_supported_capset_ids].value &
+ (1 << VIRTIO_GPU_CAPSET_VIRGL)) {
+ *caps_is_v2 = 0;
+ } else {
+ drv_logi("Unrecognized CAPSET IDs: %u. Assuming all zero caps.",
+ params[param_supported_capset_ids].value);
+ return 0;
+ }
+ } else if (params[param_capset_fix].value) {
*caps_is_v2 = 1;
- cap_args.cap_set_id = 2;
+ }
+
+ cap_args.addr = (unsigned long long)caps;
+ if (*caps_is_v2) {
+ cap_args.cap_set_id = VIRTIO_GPU_CAPSET_VIRGL2;
cap_args.size = sizeof(union virgl_caps);
} else {
- cap_args.cap_set_id = 1;
+ cap_args.cap_set_id = VIRTIO_GPU_CAPSET_VIRGL;
cap_args.size = sizeof(struct virgl_caps_v1);
}
@@ -566,7 +583,7 @@ static int virgl_get_caps(struct driver *drv, union virgl_caps *caps, int *caps_
*caps_is_v2 = 0;
// Fallback to v1
- cap_args.cap_set_id = 1;
+ cap_args.cap_set_id = VIRTIO_GPU_CAPSET_VIRGL;
cap_args.size = sizeof(struct virgl_caps_v1);
ret = drmIoctl(drv->fd, DRM_IOCTL_VIRTGPU_GET_CAPS, &cap_args);