@@ -6,6 +6,44 @@
#include "vkms_config.h"
#include "vkms_drv.h"
+static const u32 vkms_supported_plane_formats[] = {
+ DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_ABGR8888,
+ DRM_FORMAT_BGRA8888,
+ DRM_FORMAT_RGBA8888,
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_XBGR8888,
+ DRM_FORMAT_RGBX8888,
+ DRM_FORMAT_BGRX8888,
+ DRM_FORMAT_RGB888,
+ DRM_FORMAT_BGR888,
+ DRM_FORMAT_XRGB16161616,
+ DRM_FORMAT_XBGR16161616,
+ DRM_FORMAT_ARGB16161616,
+ DRM_FORMAT_ABGR16161616,
+ DRM_FORMAT_RGB565,
+ DRM_FORMAT_BGR565,
+ DRM_FORMAT_NV12,
+ DRM_FORMAT_NV16,
+ DRM_FORMAT_NV24,
+ DRM_FORMAT_NV21,
+ DRM_FORMAT_NV61,
+ DRM_FORMAT_NV42,
+ DRM_FORMAT_YUV420,
+ DRM_FORMAT_YUV422,
+ DRM_FORMAT_YUV444,
+ DRM_FORMAT_YVU420,
+ DRM_FORMAT_YVU422,
+ DRM_FORMAT_YVU444,
+ DRM_FORMAT_P010,
+ DRM_FORMAT_P012,
+ DRM_FORMAT_P016,
+ DRM_FORMAT_R1,
+ DRM_FORMAT_R2,
+ DRM_FORMAT_R4,
+ DRM_FORMAT_R8,
+};
+
struct vkms_config *vkms_config_create(void)
{
struct vkms_config *config;
@@ -120,6 +158,13 @@ struct vkms_config_plane *vkms_config_create_plane(struct vkms_config *vkms_conf
if (!vkms_config_overlay)
return NULL;
+ vkms_config_overlay->supported_formats = NULL;
+
+ if (vkms_config_plane_add_all_formats(vkms_config_overlay)) {
+ kfree(vkms_config_overlay);
+ return NULL;
+ }
+
vkms_config_overlay->type = DRM_PLANE_TYPE_OVERLAY;
vkms_config_overlay->supported_rotations = DRM_MODE_ROTATE_MASK | DRM_MODE_REFLECT_MASK;
vkms_config_overlay->default_rotation = DRM_MODE_ROTATE_0;
@@ -193,6 +238,65 @@ struct vkms_config_encoder *vkms_config_create_encoder(struct vkms_config *vkms_
}
EXPORT_SYMBOL_IF_KUNIT(vkms_config_create_encoder);
+int __must_check vkms_config_plane_add_all_formats(struct vkms_config_plane *vkms_config_plane)
+{
+ u32 *ret = krealloc_array(vkms_config_plane->supported_formats,
+ ARRAY_SIZE(vkms_supported_plane_formats),
+ sizeof(uint32_t), GFP_KERNEL);
+ if (!ret)
+ return -ENOMEM;
+ vkms_config_plane->supported_formats = ret;
+
+ memcpy(vkms_config_plane->supported_formats, vkms_supported_plane_formats,
+ sizeof(vkms_supported_plane_formats));
+ vkms_config_plane->supported_formats_count = ARRAY_SIZE(vkms_supported_plane_formats);
+ return 0;
+}
+
+int __must_check vkms_config_plane_add_format(struct vkms_config_plane *vkms_config_plane,
+ u32 drm_format)
+{
+ bool found = false;
+
+ for (int i = 0; i < ARRAY_SIZE(vkms_supported_plane_formats); i++) {
+ if (vkms_supported_plane_formats[i] == drm_format)
+ found = true;
+ }
+
+ if (!found)
+ return -EINVAL;
+ for (unsigned int i = 0; i < vkms_config_plane->supported_formats_count; i++) {
+ if (vkms_config_plane->supported_formats[i] == drm_format)
+ return 0;
+ }
+ u32 *new_ptr = krealloc_array(vkms_config_plane->supported_formats,
+ vkms_config_plane->supported_formats_count + 1,
+ sizeof(*vkms_config_plane->supported_formats), GFP_KERNEL);
+ if (!new_ptr)
+ return -ENOMEM;
+
+ vkms_config_plane->supported_formats = new_ptr;
+ vkms_config_plane->supported_formats[vkms_config_plane->supported_formats_count] = drm_format;
+ vkms_config_plane->supported_formats_count++;
+
+ return 0;
+}
+
+void vkms_config_plane_remove_all_formats(struct vkms_config_plane *vkms_config_plane)
+{
+ vkms_config_plane->supported_formats_count = 0;
+}
+
+void vkms_config_plane_remove_format(struct vkms_config_plane *vkms_config_plane, u32 drm_format)
+{
+ for (unsigned int i = 0; i < vkms_config_plane->supported_formats_count; i++) {
+ if (vkms_config_plane->supported_formats[i] == drm_format) {
+ vkms_config_plane->supported_formats[i] = vkms_config_plane->supported_formats[vkms_config_plane->supported_formats_count - 1];
+ vkms_config_plane->supported_formats_count--;
+ }
+ }
+}
+
void vkms_config_delete_plane(struct vkms_config_plane *vkms_config_plane,
struct vkms_config *vkms_config)
{
@@ -213,6 +317,7 @@ void vkms_config_delete_plane(struct vkms_config_plane *vkms_config_plane,
}
}
+ kfree(vkms_config_plane->supported_formats);
kfree(vkms_config_plane->name);
kfree(vkms_config_plane);
}
@@ -98,6 +98,8 @@ struct vkms_config_plane {
unsigned int supported_color_encoding;
enum drm_color_range default_color_range;
unsigned int supported_color_range;
+ u32 *supported_formats;
+ unsigned int supported_formats_count;
struct xarray possible_crtcs;
/* Internal usage */
@@ -144,6 +146,23 @@ bool vkms_config_is_valid(struct vkms_config *vkms_config);
*/
struct vkms_config_plane *vkms_config_create_plane(struct vkms_config *vkms_config);
+/** vkms_config_plane_add_format - Add a format to the list of supported format of a plane
+ *
+ * The passed drm_format can already be present in the list. This may fail if the allocation of a
+ * bigger array fails.
+ *
+ * @vkms_config_plane: Plane to add the format to
+ * @drm_format: Format to add to this plane
+ *
+ * Returns: 0 on success, -ENOMEM if array allocation fails, -EINVAL if the format is not supported
+ * by VKMS
+ */
+int __must_check vkms_config_plane_add_format(struct vkms_config_plane *vkms_config_plane,
+ u32 drm_format);
+int __must_check vkms_config_plane_add_all_formats(struct vkms_config_plane *vkms_config_plane);
+void vkms_config_plane_remove_format(struct vkms_config_plane *vkms_config_plane, u32 drm_format);
+void vkms_config_plane_remove_all_formats(struct vkms_config_plane *vkms_config_plane);
+
struct vkms_config_connector *vkms_config_create_connector(struct vkms_config *vkms_config);
/**
@@ -13,44 +13,6 @@
#include "vkms_formats.h"
#include "vkms_config.h"
-static const u32 vkms_formats[] = {
- DRM_FORMAT_ARGB8888,
- DRM_FORMAT_ABGR8888,
- DRM_FORMAT_BGRA8888,
- DRM_FORMAT_RGBA8888,
- DRM_FORMAT_XRGB8888,
- DRM_FORMAT_XBGR8888,
- DRM_FORMAT_RGBX8888,
- DRM_FORMAT_BGRX8888,
- DRM_FORMAT_RGB888,
- DRM_FORMAT_BGR888,
- DRM_FORMAT_XRGB16161616,
- DRM_FORMAT_XBGR16161616,
- DRM_FORMAT_ARGB16161616,
- DRM_FORMAT_ABGR16161616,
- DRM_FORMAT_RGB565,
- DRM_FORMAT_BGR565,
- DRM_FORMAT_NV12,
- DRM_FORMAT_NV16,
- DRM_FORMAT_NV24,
- DRM_FORMAT_NV21,
- DRM_FORMAT_NV61,
- DRM_FORMAT_NV42,
- DRM_FORMAT_YUV420,
- DRM_FORMAT_YUV422,
- DRM_FORMAT_YUV444,
- DRM_FORMAT_YVU420,
- DRM_FORMAT_YVU422,
- DRM_FORMAT_YVU444,
- DRM_FORMAT_P010,
- DRM_FORMAT_P012,
- DRM_FORMAT_P016,
- DRM_FORMAT_R1,
- DRM_FORMAT_R2,
- DRM_FORMAT_R4,
- DRM_FORMAT_R8,
-};
-
static struct drm_plane_state *
vkms_plane_duplicate_state(struct drm_plane *plane)
{
@@ -227,8 +189,9 @@ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
plane = drmm_universal_plane_alloc(dev, struct vkms_plane, base, 0,
&vkms_plane_funcs,
- vkms_formats, ARRAY_SIZE(vkms_formats),
- NULL, config->type, config->name);
+ config->supported_formats,
+ config->supported_formats_count, NULL, config->type,
+ config->name);
if (IS_ERR(plane))
return plane;
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com> --- drivers/gpu/drm/vkms/vkms_config.c | 105 +++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/vkms/vkms_config.h | 19 +++++++ drivers/gpu/drm/vkms/vkms_plane.c | 43 ++------------- 3 files changed, 127 insertions(+), 40 deletions(-)