All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 0/9] Add method to describe tile/bit_level_packed formats
@ 2018-10-19 10:57 Alexandru Gheorghe
  2018-10-19 10:57 ` [PATCH v5 1/9] drm: fourcc: Convert drm_format_info kerneldoc to in-line member documentation Alexandru Gheorghe
                   ` (8 more replies)
  0 siblings, 9 replies; 24+ messages in thread
From: Alexandru Gheorghe @ 2018-10-19 10:57 UTC (permalink / raw)
  To: seanpaul, airlied, dri-devel, liviu.dudau, brian.starkey, malidp,
	maxime.ripard, maarten.lankhorst, ayan.halder, daniel.vetter,
	raymond.smith, david.garbett, lisa.wu, matt.szczesiak,
	charles.xu, james.qian.wang
  Cc: nd, Alexandru Gheorghe

Changes since v4:
  - Rebased selftests on latest drm-misc-next

Changes since v3:
  - added an utility function that computes the minimum pitch.
  - switched drm_format_info to in-line member documentation.
  - Cleanup/Improved the kernel doc.
  - Added selftests for: drm_format_info* helpers.

There has been some discussion about extending drm core to handle
linear tile formats, in the series sent by me here [1] and how to
handle formats that are intended to be used just with
modifiers(particularly AFBC modifiers) on Brian series [2] and on IRC
here [3] and [4].

Hence, this big-merged series:

Patch 1: Just a preparation patch that converts the drm_format_info
kerneldoc to in-line documentation.

Patches 2-4: handle tiled formats both in core and in malidp driver,
this is done by extending drm_format_info with three new fields
char_per_block, block_w, block_h and consistently handle in the generic
code paths, both linear tiled formats and normal formats.
What's different from [1] is the interpretation of pitch for tile
formats which has been kept to be the same as for the other formats:
pitch = average_chars_per_pixel * width.

Patches 5-7: Introduce the YUV AFBC formats, the only thing noteworthy
here is that cpp/char_per_block are set to 0 for formats where it's
mandatory to be used together with a non-linear modifier and then that
is used to bypass pitch check in framebuffer_check for formats that
have cpp/char_per_block set to 0.

Patches 8-9: A small fix for test-drm-helper module and adds self
tests for drm_format_info* helpers. For the other touched functions we
need a bit more infrastructure to be able to unittest/selftest them,
since they need a stub drm_device and drm_file.

As a side note, igt master branch doesn't seem to be using
test-drm-helper.ko, so I just tested by loading/unloading the module
manually.


[1] https://lists.freedesktop.org/archives/dri-devel/2018-September/188245.html
[2] https://lists.freedesktop.org/archives/dri-devel/2018-September/189620.html
[3] https://people.freedesktop.org/~cbrill/dri-log/?channel=dri-devel&highlight_names=&date=2018-09-13&show_html=true
[4] https://people.freedesktop.org/~cbrill/dri-log/?channel=dri-devel&highlight_names=&date=2018-09-14&show_html=true


Alexandru Gheorghe (7):
  drm: fourcc: Convert drm_format_info kerneldoc to in-line member
    documentation
  drm/fourcc: Add char_per_block, block_w and block_h in drm_format_info
  drm/fourcc: Add fourcc for Mali linear tiled formats
  drm: mali-dp: Enable Mali-DP tiled buffer formats
  drm: Extend framebuffer_check to handle formats with
    cpp/char_per_block 0
  drm/selftest: Refactor test-drm_plane_helper
  drm/selftests: Add tests for drm_format_info* helpers

Brian Starkey (2):
  drm/fourcc: Add AFBC yuv fourccs for Mali
  drm/afbc: Add AFBC modifier usage documentation

 Documentation/gpu/afbc.rst                    | 233 ++++++++++++++
 Documentation/gpu/drivers.rst                 |   1 +
 MAINTAINERS                                   |   1 +
 drivers/gpu/drm/arm/malidp_hw.c               |  14 +-
 drivers/gpu/drm/arm/malidp_planes.c           |  23 +-
 drivers/gpu/drm/drm_fb_cma_helper.c           |  21 +-
 drivers/gpu/drm/drm_fb_helper.c               |   6 +
 drivers/gpu/drm/drm_fourcc.c                  |  87 ++++++
 drivers/gpu/drm/drm_framebuffer.c             |  11 +-
 drivers/gpu/drm/drm_gem_framebuffer_helper.c  |   2 +-
 drivers/gpu/drm/selftests/Makefile            |   3 +-
 ...er_selftests.h => drm_modeset_selftests.h} |   3 +
 drivers/gpu/drm/selftests/test-drm_format.c   | 290 ++++++++++++++++++
 .../drm/selftests/test-drm_modeset_common.c   |  11 +-
 .../drm/selftests/test-drm_modeset_common.h   |   5 +-
 .../gpu/drm/selftests/test-drm_plane_helper.c |  19 +-
 include/drm/drm_fourcc.h                      |  89 +++++-
 include/uapi/drm/drm_fourcc.h                 |  31 ++
 18 files changed, 806 insertions(+), 44 deletions(-)
 create mode 100644 Documentation/gpu/afbc.rst
 rename drivers/gpu/drm/selftests/{drm_plane_helper_selftests.h => drm_modeset_selftests.h} (61%)
 create mode 100644 drivers/gpu/drm/selftests/test-drm_format.c

-- 
2.18.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v5 1/9] drm: fourcc: Convert drm_format_info kerneldoc to in-line member documentation
  2018-10-19 10:57 [PATCH v5 0/9] Add method to describe tile/bit_level_packed formats Alexandru Gheorghe
@ 2018-10-19 10:57 ` Alexandru Gheorghe
  2018-10-19 12:54   ` Maxime Ripard
  2018-10-19 10:57 ` [PATCH v5 2/9] drm/fourcc: Add char_per_block, block_w and block_h in drm_format_info Alexandru Gheorghe
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 24+ messages in thread
From: Alexandru Gheorghe @ 2018-10-19 10:57 UTC (permalink / raw)
  To: seanpaul, airlied, dri-devel, liviu.dudau, brian.starkey, malidp,
	maxime.ripard, maarten.lankhorst, ayan.halder, daniel.vetter,
	raymond.smith, david.garbett, lisa.wu, matt.szczesiak,
	charles.xu, james.qian.wang
  Cc: nd, Alexandru Gheorghe

In-line member documentation seems to be desired way of documenting
structure members.

This change had been suggested by Daniel Vetter here:
https://lists.freedesktop.org/archives/dri-devel/2018-October/192176.html

Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>
---
 include/drm/drm_fourcc.h | 30 ++++++++++++++++++++----------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
index 865ef60c17af..345f11227e9e 100644
--- a/include/drm/drm_fourcc.h
+++ b/include/drm/drm_fourcc.h
@@ -52,25 +52,35 @@ struct drm_mode_fb_cmd2;
 
 /**
  * struct drm_format_info - information about a DRM format
- * @format: 4CC format identifier (DRM_FORMAT_*)
- * @depth: Color depth (number of bits per pixel excluding padding bits),
- *	valid for a subset of RGB formats only. This is a legacy field, do not
- *	use in new code and set to 0 for new formats.
- * @num_planes: Number of color planes (1 to 3)
- * @cpp: Number of bytes per pixel (per plane)
- * @hsub: Horizontal chroma subsampling factor
- * @vsub: Vertical chroma subsampling factor
- * @has_alpha: Does the format embeds an alpha component?
- * @is_yuv: Is it a YUV format?
  */
 struct drm_format_info {
+	/** @format: 4CC format identifier (DRM_FORMAT_*) */
 	u32 format;
+
+	/**
+	 * @depth:
+	 *
+	 * Color depth (number of bits per pixel excluding padding bits),
+	 * valid for a subset of RGB formats only. This is a legacy field, do
+	 * not use in new code and set to 0 for new formats.
+	 */
 	u8 depth;
+
+	/** @num_planes: Number of color planes (1 to 3) */
 	u8 num_planes;
+
+	/** @cpp: Number of bytes per pixel (per plane) */
 	u8 cpp[3];
+
+	/** @hsub: Horizontal chroma subsampling factor */
 	u8 hsub;
+	/** @vsub: Vertical chroma subsampling factor */
 	u8 vsub;
+
+	/** @has_alpha: Does the format embeds an alpha component? */
 	bool has_alpha;
+
+	/** @is_yuv: Is it a YUV format? */
 	bool is_yuv;
 };
 
-- 
2.18.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v5 2/9] drm/fourcc: Add char_per_block, block_w and block_h in drm_format_info
  2018-10-19 10:57 [PATCH v5 0/9] Add method to describe tile/bit_level_packed formats Alexandru Gheorghe
  2018-10-19 10:57 ` [PATCH v5 1/9] drm: fourcc: Convert drm_format_info kerneldoc to in-line member documentation Alexandru Gheorghe
@ 2018-10-19 10:57 ` Alexandru Gheorghe
  2018-10-19 13:09   ` Brian Starkey
  2018-10-19 10:57 ` [PATCH v5 3/9] drm/fourcc: Add fourcc for Mali linear tiled formats Alexandru Gheorghe
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 24+ messages in thread
From: Alexandru Gheorghe @ 2018-10-19 10:57 UTC (permalink / raw)
  To: seanpaul, airlied, dri-devel, liviu.dudau, brian.starkey, malidp,
	maxime.ripard, maarten.lankhorst, ayan.halder, daniel.vetter,
	raymond.smith, david.garbett, lisa.wu, matt.szczesiak,
	charles.xu, james.qian.wang
  Cc: nd, Alexandru Gheorghe

For some pixel formats .cpp structure in drm_format info it's not
enough to describe the peculiarities of the pixel layout, for example
tiled formats or packed formats at bit level.

What's implemented here is to add three new members to drm_format_info
that could describe such formats:

- char_per_block[3]
- block_w[3]
- block_h[3]

char_per_block will be put in a union alongside cpp, for transparent
compatibility  with the existing format descriptions.

Regarding, block_w and block_h they are intended to be used through
their equivalent getters drm_format_info_block_width /
drm_format_info_block_height, the reason of the getters is to abstract
the fact that for normal formats block_w and block_h will be unset/0,
but the methods will be returning 1.

Additionally, convenience function drm_format_info_min_pitch had been
added that computes the minimum required pitch for a given pixel
format and buffer width.

Using that the following drm core functions had been updated to
generically handle both block and non-block formats:

- drm_fb_cma_get_gem_addr: for block formats it will just return the
  beginning of the block.
- framebuffer_check: Use the newly added drm_format_info_min_pitch.
- drm_gem_fb_create_with_funcs: Use the newly added
  drm_format_info_min_pitch.
- In places where is not expecting to handle block formats, like fbdev
  helpers I just added some warnings in case the block width/height
  are greater than 1.

Changes since v3:
 - Add helper function for computing the minimum required pitch.
 - Improve/cleanup documentation

Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>
---
 drivers/gpu/drm/drm_fb_cma_helper.c          | 21 ++++++-
 drivers/gpu/drm/drm_fb_helper.c              |  6 ++
 drivers/gpu/drm/drm_fourcc.c                 | 62 ++++++++++++++++++++
 drivers/gpu/drm/drm_framebuffer.c            |  6 +-
 drivers/gpu/drm/drm_gem_framebuffer_helper.c |  2 +-
 include/drm/drm_fourcc.h                     | 61 ++++++++++++++++++-
 6 files changed, 149 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c
index d52344a03aa8..83941a8ca0e0 100644
--- a/drivers/gpu/drm/drm_fb_cma_helper.c
+++ b/drivers/gpu/drm/drm_fb_cma_helper.c
@@ -72,7 +72,9 @@ struct drm_gem_cma_object *drm_fb_cma_get_gem_obj(struct drm_framebuffer *fb,
 EXPORT_SYMBOL_GPL(drm_fb_cma_get_gem_obj);
 
 /**
- * drm_fb_cma_get_gem_addr() - Get physical address for framebuffer
+ * drm_fb_cma_get_gem_addr() - Get physical address for framebuffer, for pixel
+ * formats where values are grouped in blocks this will get you the beginning of
+ * the block
  * @fb: The framebuffer
  * @state: Which state of drm plane
  * @plane: Which plane
@@ -87,6 +89,14 @@ dma_addr_t drm_fb_cma_get_gem_addr(struct drm_framebuffer *fb,
 	struct drm_gem_cma_object *obj;
 	dma_addr_t paddr;
 	u8 h_div = 1, v_div = 1;
+	u32 block_w = drm_format_info_block_width(fb->format, plane);
+	u32 block_h = drm_format_info_block_height(fb->format, plane);
+	u32 block_size = fb->format->char_per_block[plane];
+	u32 sample_x;
+	u32 sample_y;
+	u32 block_start_y;
+	u32 num_hblocks;
+
 
 	obj = drm_fb_cma_get_gem_obj(fb, plane);
 	if (!obj)
@@ -99,8 +109,13 @@ dma_addr_t drm_fb_cma_get_gem_addr(struct drm_framebuffer *fb,
 		v_div = fb->format->vsub;
 	}
 
-	paddr += (fb->format->cpp[plane] * (state->src_x >> 16)) / h_div;
-	paddr += (fb->pitches[plane] * (state->src_y >> 16)) / v_div;
+	sample_x = (state->src_x >> 16) / h_div;
+	sample_y = (state->src_y >> 16) / v_div;
+	block_start_y = (sample_y / block_h) * block_h;
+	num_hblocks = sample_x / block_w;
+
+	paddr += fb->pitches[plane] * block_start_y;
+	paddr += block_size * num_hblocks;
 
 	return paddr;
 }
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index a504a5e05676..9add0d7da744 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -1595,6 +1595,10 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
 	if (var->pixclock != 0 || in_dbg_master())
 		return -EINVAL;
 
+	if ((drm_format_info_block_width(fb->format, 0) > 1) ||
+	    (drm_format_info_block_height(fb->format, 0) > 1))
+		return -EINVAL;
+
 	/*
 	 * Changes struct fb_var_screeninfo are currently not pushed back
 	 * to KMS, hence fail if different settings are requested.
@@ -1969,6 +1973,8 @@ void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helpe
 {
 	struct drm_framebuffer *fb = fb_helper->fb;
 
+	WARN_ON((drm_format_info_block_width(fb->format, 0) > 1) ||
+		(drm_format_info_block_height(fb->format, 0) > 1));
 	info->pseudo_palette = fb_helper->pseudo_palette;
 	info->var.xres_virtual = fb->width;
 	info->var.yres_virtual = fb->height;
diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index e177f6d0d1f4..a843a5fc8dbf 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -403,3 +403,65 @@ int drm_format_plane_height(int height, uint32_t format, int plane)
 	return height / info->vsub;
 }
 EXPORT_SYMBOL(drm_format_plane_height);
+
+/**
+ * drm_format_info_block_width - width in pixels of block.
+ * @info: pixel format info
+ * @plane: plane index
+ *
+ * Returns:
+ * The width in pixels of a block, depending on the plane index.
+ */
+unsigned int drm_format_info_block_width(const struct drm_format_info *info,
+					 int plane)
+{
+	if (!info || plane < 0 || plane >= info->num_planes)
+		return 0;
+
+	if (!info->block_w[plane])
+		return 1;
+	return info->block_w[plane];
+}
+EXPORT_SYMBOL(drm_format_info_block_width);
+
+/**
+ * drm_format_info_block_height - height in pixels of a block
+ * @info: pixel format info
+ * @plane: plane index
+ *
+ * Returns:
+ * The height in pixels of a block, depending on the plane index.
+ */
+unsigned int drm_format_info_block_height(const struct drm_format_info *info,
+					  int plane)
+{
+	if (!info || plane < 0 || plane >= info->num_planes)
+		return 0;
+
+	if (!info->block_h[plane])
+		return 1;
+	return info->block_h[plane];
+}
+EXPORT_SYMBOL(drm_format_info_block_height);
+
+/**
+ * drm_format_info_min_pitch - computes the minimum required pitch in bytes
+ * @info: pixel format info
+ * @plane: plane index
+ * @buffer_width: buffer width in pixels
+ *
+ * Returns:
+ * The minimum required pitch in bytes for a buffer by taking into consideration
+ * the pixel format information and the buffer width.
+ */
+uint64_t drm_format_info_min_pitch(const struct drm_format_info *info,
+				   int plane, unsigned int buffer_width)
+{
+	if (!info || plane < 0 || plane >= info->num_planes)
+		return 0;
+
+	return DIV_ROUND_UP((u64)buffer_width * info->char_per_block[plane],
+			    drm_format_info_block_width(info, plane) *
+			    drm_format_info_block_height(info, plane));
+}
+EXPORT_SYMBOL(drm_format_info_min_pitch);
diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
index 3bf729d0aae5..6aca8a1ccdb6 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -195,20 +195,20 @@ static int framebuffer_check(struct drm_device *dev,
 	for (i = 0; i < info->num_planes; i++) {
 		unsigned int width = fb_plane_width(r->width, info, i);
 		unsigned int height = fb_plane_height(r->height, info, i);
-		unsigned int cpp = info->cpp[i];
+		u64 min_pitch = drm_format_info_min_pitch(info, i, width);
 
 		if (!r->handles[i]) {
 			DRM_DEBUG_KMS("no buffer object handle for plane %d\n", i);
 			return -EINVAL;
 		}
 
-		if ((uint64_t) width * cpp > UINT_MAX)
+		if (min_pitch > UINT_MAX)
 			return -ERANGE;
 
 		if ((uint64_t) height * r->pitches[i] + r->offsets[i] > UINT_MAX)
 			return -ERANGE;
 
-		if (r->pitches[i] < width * cpp) {
+		if (r->pitches[i] < min_pitch) {
 			DRM_DEBUG_KMS("bad pitch %u for plane %d\n", r->pitches[i], i);
 			return -EINVAL;
 		}
diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
index ded7a379ac35..acb466d25afc 100644
--- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
+++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
@@ -171,7 +171,7 @@ drm_gem_fb_create_with_funcs(struct drm_device *dev, struct drm_file *file,
 		}
 
 		min_size = (height - 1) * mode_cmd->pitches[i]
-			 + width * info->cpp[i]
+			 + drm_format_info_min_pitch(info, i, width)
 			 + mode_cmd->offsets[i];
 
 		if (objs[i]->size < min_size) {
diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
index 345f11227e9e..253d4c07a10c 100644
--- a/include/drm/drm_fourcc.h
+++ b/include/drm/drm_fourcc.h
@@ -69,8 +69,59 @@ struct drm_format_info {
 	/** @num_planes: Number of color planes (1 to 3) */
 	u8 num_planes;
 
-	/** @cpp: Number of bytes per pixel (per plane) */
-	u8 cpp[3];
+	union {
+		/**
+		 * @cpp:
+		 *
+		 * Number of bytes per pixel (per plane), this is aliased with
+		 * @char_per_block. It is deprecated in favour of using the
+		 * triplet @char_per_block, @block_w, @block_h for better
+		 * describing the pixel format.
+		 */
+		u8 cpp[3];
+
+		/**
+		 * @char_per_block:
+		 *
+		 * Number of bytes per block (per plane), where blocks are
+		 * defined as a rectangle of pixels which are stored next to
+		 * each other in a byte aligned memory region. Together with
+		 * @block_w and @block_h this is used to properly describe tiles
+		 * in tiled formats or to describe groups of pixels in packed
+		 * formats for which the memory needed for a single pixel it's
+		 * not byte aligned.
+		 *
+		 * @cpp had been kept from historical reasons because there are
+		 * a lot of places in drivers where it's used. In drm core for
+		 * generic code paths the preferred way is to use
+		 * @char_per_block, drm_format_info_block_width() and
+		 * drm_format_info_block_height() which allows handling both
+		 * block and non-block formats in the same way.
+		 *
+		 * For formats that are intended to be used only with non-linear
+		 * modifiers both @cpp and @char_per_block must be 0 in the
+		 * generic format table. Drivers could supply accurate
+		 * information from their drm_mode_config.get_format_info hook
+		 * if they want the core to be validating the pitch.
+		 */
+		u8 char_per_block[3];
+	};
+
+	/**
+	 * @block_w:
+	 *
+	 * Block width in pixels, this is intended to be accessed through
+	 * drm_format_info_block_width()
+	 */
+	u8 block_w[3];
+
+	/**
+	 * @block_h:
+	 *
+	 * Block height in pixels, this is intended to be accessed through
+	 * drm_format_info_block_height()
+	 */
+	u8 block_h[3];
 
 	/** @hsub: Horizontal chroma subsampling factor */
 	u8 hsub;
@@ -106,6 +157,12 @@ int drm_format_horz_chroma_subsampling(uint32_t format);
 int drm_format_vert_chroma_subsampling(uint32_t format);
 int drm_format_plane_width(int width, uint32_t format, int plane);
 int drm_format_plane_height(int height, uint32_t format, int plane);
+unsigned int drm_format_info_block_width(const struct drm_format_info *info,
+					 int plane);
+unsigned int drm_format_info_block_height(const struct drm_format_info *info,
+					  int plane);
+uint64_t drm_format_info_min_pitch(const struct drm_format_info *info,
+				   int plane, unsigned int buffer_width);
 const char *drm_get_format_name(uint32_t format, struct drm_format_name_buf *buf);
 
 #endif /* __DRM_FOURCC_H__ */
-- 
2.18.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v5 3/9] drm/fourcc: Add fourcc for Mali linear tiled formats
  2018-10-19 10:57 [PATCH v5 0/9] Add method to describe tile/bit_level_packed formats Alexandru Gheorghe
  2018-10-19 10:57 ` [PATCH v5 1/9] drm: fourcc: Convert drm_format_info kerneldoc to in-line member documentation Alexandru Gheorghe
  2018-10-19 10:57 ` [PATCH v5 2/9] drm/fourcc: Add char_per_block, block_w and block_h in drm_format_info Alexandru Gheorghe
@ 2018-10-19 10:57 ` Alexandru Gheorghe
  2018-10-19 13:12   ` Brian Starkey
  2018-10-19 10:57 ` [PATCH v5 4/9] drm: mali-dp: Enable Mali-DP tiled buffer formats Alexandru Gheorghe
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 24+ messages in thread
From: Alexandru Gheorghe @ 2018-10-19 10:57 UTC (permalink / raw)
  To: seanpaul, airlied, dri-devel, liviu.dudau, brian.starkey, malidp,
	maxime.ripard, maarten.lankhorst, ayan.halder, daniel.vetter,
	raymond.smith, david.garbett, lisa.wu, matt.szczesiak,
	charles.xu, james.qian.wang
  Cc: nd, Alexandru Gheorghe

Mali-DP implements a number of tiled yuv formats which are not
currently described in drm_fourcc.h.
This adds those definitions and describes their memory layout by
using the newly added char_per_block, block_w, block_h.

Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>
---
 drivers/gpu/drm/drm_fourcc.c  | 12 ++++++++++++
 include/uapi/drm/drm_fourcc.h | 14 ++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index a843a5fc8dbf..69caa577149c 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -228,6 +228,18 @@ const struct drm_format_info *__drm_format_info(u32 format)
 		{ .format = DRM_FORMAT_P010,		.depth = 0,  .num_planes = 2, .cpp = { 2, 4, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true  },
 		{ .format = DRM_FORMAT_P012,		.depth = 0,  .num_planes = 2, .cpp = { 2, 4, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true  },
 		{ .format = DRM_FORMAT_P016,		.depth = 0,  .num_planes = 2, .cpp = { 2, 4, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true  },
+		{ .format = DRM_FORMAT_Y0L0,		.depth = 0,  .num_planes = 1,
+		  .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, .block_h = { 2, 0, 0},
+		  .hsub = 2, .vsub = 2, .has_alpha = true, .is_yuv = true },
+		{ .format = DRM_FORMAT_X0L0,		.depth = 0,  .num_planes = 1,
+		  .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, .block_h = { 2, 0, 0},
+		  .hsub = 2, .vsub = 2, .is_yuv = true },
+		{ .format = DRM_FORMAT_Y0L2,		.depth = 0,  .num_planes = 1,
+		  .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, .block_h = { 2, 0, 0},
+		  .hsub = 2, .vsub = 2, .has_alpha = true, .is_yuv = true },
+		{ .format = DRM_FORMAT_X0L2,		.depth = 0,  .num_planes = 1,
+		  .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, .block_h = { 2, 0, 0},
+		  .hsub = 2, .vsub = 2, .is_yuv = true },
 	};
 
 	unsigned int i;
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 600106adf91f..4de86dbf40ca 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -152,6 +152,20 @@ extern "C" {
 
 #define DRM_FORMAT_AYUV		fourcc_code('A', 'Y', 'U', 'V') /* [31:0] A:Y:Cb:Cr 8:8:8:8 little endian */
 
+/*
+ * packed YCbCr420 2x2 tiled formats
+ * first 64 bits will contain Y,Cb,Cr components for a 2x2 tile
+ */
+/* [63:0]   A3:A2:Y3:0:Cr0:0:Y2:0:A1:A0:Y1:0:Cb0:0:Y0:0  1:1:8:2:8:2:8:2:1:1:8:2:8:2:8:2 little endian */
+#define DRM_FORMAT_Y0L0		fourcc_code('Y', '0', 'L', '0')
+/* [63:0]   X3:X2:Y3:0:Cr0:0:Y2:0:X1:X0:Y1:0:Cb0:0:Y0:0  1:1:8:2:8:2:8:2:1:1:8:2:8:2:8:2 little endian */
+#define DRM_FORMAT_X0L0		fourcc_code('X', '0', 'L', '0')
+
+/* [63:0]   A3:A2:Y3:Cr0:Y2:A1:A0:Y1:Cb0:Y0  1:1:10:10:10:1:1:10:10:10 little endian */
+#define DRM_FORMAT_Y0L2		fourcc_code('Y', '0', 'L', '2')
+/* [63:0]   X3:X2:Y3:Cr0:Y2:X1:X0:Y1:Cb0:Y0  1:1:10:10:10:1:1:10:10:10 little endian */
+#define DRM_FORMAT_X0L2		fourcc_code('X', '0', 'L', '2')
+
 /*
  * 2 plane RGB + A
  * index 0 = RGB plane, same format as the corresponding non _A8 format has
-- 
2.18.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v5 4/9] drm: mali-dp: Enable Mali-DP tiled buffer formats
  2018-10-19 10:57 [PATCH v5 0/9] Add method to describe tile/bit_level_packed formats Alexandru Gheorghe
                   ` (2 preceding siblings ...)
  2018-10-19 10:57 ` [PATCH v5 3/9] drm/fourcc: Add fourcc for Mali linear tiled formats Alexandru Gheorghe
@ 2018-10-19 10:57 ` Alexandru Gheorghe
  2018-10-19 13:17   ` Brian Starkey
  2018-10-19 10:57 ` [PATCH v5 5/9] drm: Extend framebuffer_check to handle formats with cpp/char_per_block 0 Alexandru Gheorghe
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 24+ messages in thread
From: Alexandru Gheorghe @ 2018-10-19 10:57 UTC (permalink / raw)
  To: seanpaul, airlied, dri-devel, liviu.dudau, brian.starkey, malidp,
	maxime.ripard, maarten.lankhorst, ayan.halder, daniel.vetter,
	raymond.smith, david.garbett, lisa.wu, matt.szczesiak,
	charles.xu, james.qian.wang
  Cc: nd, Alexandru Gheorghe

Enable the following formats
- DRM_FORMAT_X0L0: DP650
- DRM_FORMAT_X0L2: DP550, DP650

Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>
---
 drivers/gpu/drm/arm/malidp_hw.c     | 14 +++++++++++---
 drivers/gpu/drm/arm/malidp_planes.c | 23 +++++++++++++++++++++--
 2 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
index c94a4422e0e9..e01fc0e5b503 100644
--- a/drivers/gpu/drm/arm/malidp_hw.c
+++ b/drivers/gpu/drm/arm/malidp_hw.c
@@ -77,12 +77,18 @@ static const struct malidp_format_id malidp500_de_formats[] = {
 	{ DRM_FORMAT_YUYV, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 2) },	\
 	{ DRM_FORMAT_UYVY, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 3) },	\
 	{ DRM_FORMAT_NV12, DE_VIDEO1 | DE_VIDEO2 | SE_MEMWRITE, MALIDP_ID(5, 6) },	\
-	{ DRM_FORMAT_YUV420, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 7) }
+	{ DRM_FORMAT_YUV420, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 7) }, \
+	{ DRM_FORMAT_X0L2, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(6, 6)}
 
 static const struct malidp_format_id malidp550_de_formats[] = {
 	MALIDP_COMMON_FORMATS,
 };
 
+static const struct malidp_format_id malidp650_de_formats[] = {
+	MALIDP_COMMON_FORMATS,
+	{ DRM_FORMAT_X0L0, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 4)},
+};
+
 static const struct malidp_layer malidp500_layers[] = {
 	{ DE_VIDEO1, MALIDP500_DE_LV_BASE, MALIDP500_DE_LV_PTR_BASE, MALIDP_DE_LV_STRIDE0, MALIDP500_LV_YUV2RGB },
 	{ DE_GRAPHICS1, MALIDP500_DE_LG1_BASE, MALIDP500_DE_LG1_PTR_BASE, MALIDP_DE_LG_STRIDE, 0 },
@@ -595,6 +601,8 @@ static int malidp550_rotmem_required(struct malidp_hw_device *hwdev, u16 w, u16
 	case DRM_FORMAT_BGR565:
 	case DRM_FORMAT_UYVY:
 	case DRM_FORMAT_YUYV:
+	case DRM_FORMAT_X0L0:
+	case DRM_FORMAT_X0L2:
 		bytes_per_col = 32;
 		break;
 	/* 16 lines at 1.5 bytes per pixel */
@@ -860,8 +868,8 @@ const struct malidp_hw malidp_device[MALIDP_MAX_DEVICES] = {
 					    MALIDP550_DC_IRQ_SE,
 				.vsync_irq = MALIDP550_DC_IRQ_CONF_VALID,
 			},
-			.pixel_formats = malidp550_de_formats,
-			.n_pixel_formats = ARRAY_SIZE(malidp550_de_formats),
+			.pixel_formats = malidp650_de_formats,
+			.n_pixel_formats = ARRAY_SIZE(malidp650_de_formats),
 			.bus_align_bytes = 16,
 		},
 		.query_hw = malidp650_query_hw,
diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c
index 49c37f6dd63e..33bbc29da774 100644
--- a/drivers/gpu/drm/arm/malidp_planes.c
+++ b/drivers/gpu/drm/arm/malidp_planes.c
@@ -196,13 +196,26 @@ static int malidp_de_plane_check(struct drm_plane *plane,
 	ms->n_planes = fb->format->num_planes;
 	for (i = 0; i < ms->n_planes; i++) {
 		u8 alignment = malidp_hw_get_pitch_align(mp->hwdev, rotated);
-		if (fb->pitches[i] & (alignment - 1)) {
+
+		if ((fb->pitches[i] * drm_format_info_block_height(fb->format, i))
+				& (alignment - 1)) {
 			DRM_DEBUG_KMS("Invalid pitch %u for plane %d\n",
 				      fb->pitches[i], i);
 			return -EINVAL;
 		}
 	}
 
+	if (fb->width % drm_format_info_block_width(fb->format, 0) ||
+	    fb->height % drm_format_info_block_height(fb->format, 0)) {
+		DRM_DEBUG_KMS("Buffer width/height needs to be a multiple of tile sizes");
+		return -EINVAL;
+	}
+	if ((state->src_x >> 16) % drm_format_info_block_width(fb->format, 0) ||
+	    (state->src_y >> 16) % drm_format_info_block_height(fb->format, 0)) {
+		DRM_DEBUG_KMS("Plane src_x/src_y needs to be a multiple of tile sizes");
+		return -EINVAL;
+	}
+
 	if ((state->crtc_w > mp->hwdev->max_line_size) ||
 	    (state->crtc_h > mp->hwdev->max_line_size) ||
 	    (state->crtc_w < mp->hwdev->min_line_size) ||
@@ -258,8 +271,14 @@ static void malidp_de_set_plane_pitches(struct malidp_plane *mp,
 		num_strides = (mp->hwdev->hw->features &
 			       MALIDP_DEVICE_LV_HAS_3_STRIDES) ? 3 : 2;
 
+	/*
+	 * The drm convention for pitch is that it needs to cover width * cpp,
+	 * but our hardware wants the pitch/stride to cover all rows included
+	 * in a tile.
+	 */
 	for (i = 0; i < num_strides; ++i)
-		malidp_hw_write(mp->hwdev, pitches[i],
+		malidp_hw_write(mp->hwdev, pitches[i] *
+				drm_format_info_block_height(mp->base.state->fb->format, i),
 				mp->layer->base +
 				mp->layer->stride_offset + i * 4);
 }
-- 
2.18.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v5 5/9] drm: Extend framebuffer_check to handle formats with cpp/char_per_block 0
  2018-10-19 10:57 [PATCH v5 0/9] Add method to describe tile/bit_level_packed formats Alexandru Gheorghe
                   ` (3 preceding siblings ...)
  2018-10-19 10:57 ` [PATCH v5 4/9] drm: mali-dp: Enable Mali-DP tiled buffer formats Alexandru Gheorghe
@ 2018-10-19 10:57 ` Alexandru Gheorghe
  2018-10-19 13:21   ` Brian Starkey
  2018-10-19 10:57 ` [PATCH v5 6/9] drm/fourcc: Add AFBC yuv fourccs for Mali Alexandru Gheorghe
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 24+ messages in thread
From: Alexandru Gheorghe @ 2018-10-19 10:57 UTC (permalink / raw)
  To: seanpaul, airlied, dri-devel, liviu.dudau, brian.starkey, malidp,
	maxime.ripard, maarten.lankhorst, ayan.halder, daniel.vetter,
	raymond.smith, david.garbett, lisa.wu, matt.szczesiak,
	charles.xu, james.qian.wang
  Cc: nd, Alexandru Gheorghe

For formats that are supported only with non-linear modifiers it
doesn't make to much sense to define cpp or char_per_block, so that
will be set to 0.

This patch adds a restriction to force having a modifier attached when
cpp/char_per_block is 0, and to bypass checking the pitch restriction.

This had been discussed here.
[1] https://people.freedesktop.org/~cbrill/dri-log/?channel=dri-devel&highlight_names=&date=2018-09-13&show_html=true

Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>
---
 drivers/gpu/drm/drm_framebuffer.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
index 6aca8a1ccdb6..e346d0ad92e0 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -195,8 +195,13 @@ static int framebuffer_check(struct drm_device *dev,
 	for (i = 0; i < info->num_planes; i++) {
 		unsigned int width = fb_plane_width(r->width, info, i);
 		unsigned int height = fb_plane_height(r->height, info, i);
+		unsigned int block_size = info->char_per_block[i];
 		u64 min_pitch = drm_format_info_min_pitch(info, i, width);
 
+		if (!block_size && (r->modifier[i] == DRM_FORMAT_MOD_LINEAR)) {
+			DRM_DEBUG_KMS("Format requires non-linear modifier for plane %d\n", i);
+			return -EINVAL;
+		}
 		if (!r->handles[i]) {
 			DRM_DEBUG_KMS("no buffer object handle for plane %d\n", i);
 			return -EINVAL;
@@ -208,7 +213,7 @@ static int framebuffer_check(struct drm_device *dev,
 		if ((uint64_t) height * r->pitches[i] + r->offsets[i] > UINT_MAX)
 			return -ERANGE;
 
-		if (r->pitches[i] < min_pitch) {
+		if (block_size && r->pitches[i] < min_pitch) {
 			DRM_DEBUG_KMS("bad pitch %u for plane %d\n", r->pitches[i], i);
 			return -EINVAL;
 		}
-- 
2.18.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v5 6/9] drm/fourcc: Add AFBC yuv fourccs for Mali
  2018-10-19 10:57 [PATCH v5 0/9] Add method to describe tile/bit_level_packed formats Alexandru Gheorghe
                   ` (4 preceding siblings ...)
  2018-10-19 10:57 ` [PATCH v5 5/9] drm: Extend framebuffer_check to handle formats with cpp/char_per_block 0 Alexandru Gheorghe
@ 2018-10-19 10:57 ` Alexandru Gheorghe
  2018-10-19 10:57 ` [PATCH v5 7/9] drm/afbc: Add AFBC modifier usage documentation Alexandru Gheorghe
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 24+ messages in thread
From: Alexandru Gheorghe @ 2018-10-19 10:57 UTC (permalink / raw)
  To: seanpaul, airlied, dri-devel, liviu.dudau, brian.starkey, malidp,
	maxime.ripard, maarten.lankhorst, ayan.halder, daniel.vetter,
	raymond.smith, david.garbett, lisa.wu, matt.szczesiak,
	charles.xu, james.qian.wang
  Cc: nd

From: Brian Starkey <brian.starkey@arm.com>

As we look to enable AFBC using DRM format modifiers, we run into
problems which we've historically handled via vendor-private details
(i.e. gralloc, on Android).

AFBC (as an encoding) is fully flexible, and for example YUV data can
be encoded into 1, 2 or 3 encoded "planes", much like the linear
equivalents. Component order is also meaningful, as AFBC doesn't
necessarily care about what each "channel" of the data it encodes
contains. Therefore ABGR8888 and RGBA8888 can be encoded in AFBC with
different representations. Similarly, 'X' components may be encoded
into AFBC streams in cases where a decoder expects to decode a 4th
component.

In addition, AFBC is a licensable IP, meaning that to support the
ecosystem we need to ensure that _all_ AFBC users are able to describe
the encodings that they need. This is much better achieved by
preserving meaning in the fourcc codes when they are combined with an
AFBC modifier.

In essence, we want to use the modifier to describe the parameters of
the AFBC encode/decode, and use the fourcc code to describe the data
being encoded/decoded.

To do anything different would be to introduce redundancy - we would
need to duplicate in the modifier information which is _already_
conveyed clearly and non-ambigiously by a fourcc code.

I hope that for RGB this is non-controversial.
(BGRA8888 + MODIFIER_AFBC) is a different format from
(RGBA8888 + MODIFIER_AFBC).

Possibly more controversial is that (XBGR8888 + MODIFIER_AFBC)
is different from (BGR888 + MODIFIER_AFBC). I understand that in some
schemes it is not the case - but in AFBC it is so.

Where we run into problems is where there are not already fourcc codes
which represent the data which the AFBC encoder/decoder is processing.
To that end, we want to introduce new fourcc codes to describe the
data being encoded/decoded, in the places where none of the existing
fourcc codes are applicable.

Where we don't support an equivalent non-compressed layout, or where
no "obvious" linear layout exists, we are proposing adding fourcc
codes which have no associated linear layout - because any layout we
proposed would be completely arbitrary.

Some formats are following the naming conventions from [2].

The summary of the new formats is:
 DRM_FORMAT_VUY888 - Packed 8-bit YUV 444. Y followed by U then V.
 DRM_FORMAT_VUY101010 - Packed 10-bit YUV 444. Y followed by U then
                        V. No defined linear encoding.
 DRM_FORMAT_Y210 - Packed 10-bit YUV 422. Y followed by U (then Y)
                   then V. 10-bit samples in 16-bit words.
 DRM_FORMAT_Y410 - Packed 10-bit YUV 444, with 2-bit alpha.
 DRM_FORMAT_P210 - Semi-planar 10-bit YUV 422. Y plane, followed by
                   interleaved U-then-V plane. 10-bit samples in
                   16-bit words.
 DRM_FORMAT_YUV420_8BIT - Packed 8-bit YUV 420. Y followed by U then
                          V. No defined linear encoding
 DRM_FORMAT_YUV420_10BIT - Packed 10-bit YUV 420. Y followed by U
                           then V. No defined linear encoding

Please also note that in the absence of AFBC, we would still need to
add Y410, Y210 and P210.

Full rationale follows:

YUV 444 8-bit, 1-plane
----------------------
 The currently defined AYUV format encodes a 4th alpha component,
 which makes it unsuitable for representing a 3-component YUV 444
 AFBC stream.

 The proposed[1] XYUV format which is supported by Mali-DP in linear
 layout is also unsuitable, because the component order is the
 opposite of the AFBC version, and it encodes a 4th 'X' component.

 DRM_FORMAT_VUY888 is the "obvious" format for a 3-component, packed,
 YUV 444 8-bit format, with the component order which our HW expects to
 encode/decode. It conforms to the same naming convention as the
 existing packed YUV 444 format.
 The naming here is meant to be consistent with DRM_FORMAT_AYUV and
 DRM_FORMAT_XYUV[1]

YUV 444 10-bit, 1-plane
-----------------------
 There is no currently-defined YUV 444 10-bit format in
 drm_fourcc.h, irrespective of number of planes.

 The proposed[1] XVYU2101010 format which is supported by Mali-DP in
 linear layout uses the wrong component order, and also encodes a 4th
 'X' component, which doesn't match the AFBC version of YUV 444
 10-bit which we support.

 DRM_FORMAT_Y410 is the same layout as XVYU2101010, but with 2 bits of
 alpha.  This format is supported with linear layout by Mali GPUs. The
 naming follows[2].

 There is no "obvious" linear encoding for a 3-component 10:10:10
 packed format, and so DRM_FORMAT_VUY101010 defines a component
 order, but not a bit encoding. Again, the naming is meant to be
 consistent with DRM_FORMAT_AYUV.

YUV 422 8-bit, 1-plane
----------------------
 The existing DRM_FORMAT_YUYV (and the other component orders) are
 single-planar YUV 422 8-bit formats. Following the convention of
 the component orders of the RGB formats, YUYV has the correct
 component order for our AFBC encoding (Y followed by U followed by
 V). We can use YUYV for AFBC YUV 422 8-bit.

YUV 422 10-bit, 1-plane
-----------------------
 There is no currently-defined YUV 422 10-bit format in drm_fourcc.h

 DRM_FORMAT_Y210 is analogous to YUYV, but with 10-bits per sample
 packed into the upper 10-bits of 16-bit samples. This format is
 supported in both linear and AFBC by Mali GPUs.

YUV 422 10-bit, 2-plane
-----------------------
 The recently defined DRM_FORMAT_P010 format is a 10-bit semi-planar
 YUV 420 format, which has the correct component ordering for an AFBC
 2-plane YUV 420 buffer. The linear layout contains meaningless padding
 bits, which will not be encoded in an AFBC stream.

YUV 420 8-bit, 1-plane
----------------------
 There is no currently defined single-planar YUV 420, 8-bit format
 in drm_fourcc.h. There's differing opinions on whether using the
 existing fourcc-implied n_planes where possible is a good idea or
 not when using modifiers.

 For me, it's much more "obvious" to use NV12 for 2-plane AFBC and
 YUV420 for 3-plane AFBC. This keeps the aforementioned separation
 between the AFBC codec settings (in the modifier) and the pixel data
 format (in the fourcc). With different vendors using AFBC, this helps
 to ensure that there is no confusion in interoperation. It also
 ensures that the AFBC modifiers describe AFBC itself (which is a
 licensable component), and not implementation details which are not
 defined by AFBC.

 The proposed[1] X0L0 format which Mali-DP supports with Linear layout
 is unsuitable, as it contains a 4th 'X' component, and our AFBC
 decoder expects only 3 components.

 To that end, we propose a new YUV 420 8-bit format. There is no
 "obvious" linear encoding for a 3-component 8:8:8, 420, packed format,
 and so DRM_FORMAT_YUV420_8BIT defines a component order, but not a
 bit encoding. I'm happy to hear different naming suggestions.

YUV 420 8-bit, 2-, 3-plane
--------------------------
 These already exist, we can use NV12 and YUV420.

YUV 420 10-bit, 1-plane
-----------------------
 As above, no current definition exists, and X0L2 encodes a 4th 'X'
 channel.

 Analogous to DRM_FORMAT_YUV420_8BIT, we define DRM_FORMAT_YUV420_10BIT.

[1] https://lists.freedesktop.org/archives/dri-devel/2018-July/184598.html
[2] https://docs.microsoft.com/en-us/windows/desktop/medfound/10-bit-and-16-bit-yuv-video-formats

Changes since RFC v1:
 - Fix confusing subsampling vs bit-depth X:X:X notation in
   descriptions (danvet)
 - Rename DRM_FORMAT_AVYU1101010 to DRM_FORMAT_Y410 (Lisa Wu)
 - Add drm_format_info structures for the new formats, using the
   new 'bpp' field for those with non-integer bytes-per-pixel
 - Rebase, including Juha-Pekka Heikkila's format definitions

Signed-off-by: Brian Starkey <brian.starkey@arm.com>
Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
---
 drivers/gpu/drm/drm_fourcc.c  | 13 +++++++++++++
 include/uapi/drm/drm_fourcc.h | 14 ++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index 69caa577149c..48afb56d5934 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -224,10 +224,17 @@ const struct drm_format_info *__drm_format_info(u32 format)
 		{ .format = DRM_FORMAT_YVYU,		.depth = 0,  .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
 		{ .format = DRM_FORMAT_UYVY,		.depth = 0,  .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
 		{ .format = DRM_FORMAT_VYUY,		.depth = 0,  .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
+		{ .format = DRM_FORMAT_Y210,		.depth = 0,  .num_planes = 1,
+		  .cpp = { 4, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
+		{ .format = DRM_FORMAT_VUY888,		.depth = 0,  .num_planes = 1,
+		  .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true },
+		{ .format = DRM_FORMAT_Y410,		.depth = 0,  .num_planes = 1,
+		  .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true, .is_yuv = true },
 		{ .format = DRM_FORMAT_AYUV,		.depth = 0,  .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true, .is_yuv = true },
 		{ .format = DRM_FORMAT_P010,		.depth = 0,  .num_planes = 2, .cpp = { 2, 4, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true  },
 		{ .format = DRM_FORMAT_P012,		.depth = 0,  .num_planes = 2, .cpp = { 2, 4, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true  },
 		{ .format = DRM_FORMAT_P016,		.depth = 0,  .num_planes = 2, .cpp = { 2, 4, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true  },
+		{ .format = DRM_FORMAT_P210,		.depth = 0,  .num_planes = 2, .cpp = { 2, 4, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
 		{ .format = DRM_FORMAT_Y0L0,		.depth = 0,  .num_planes = 1,
 		  .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, .block_h = { 2, 0, 0},
 		  .hsub = 2, .vsub = 2, .has_alpha = true, .is_yuv = true },
@@ -240,6 +247,12 @@ const struct drm_format_info *__drm_format_info(u32 format)
 		{ .format = DRM_FORMAT_X0L2,		.depth = 0,  .num_planes = 1,
 		  .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, .block_h = { 2, 0, 0},
 		  .hsub = 2, .vsub = 2, .is_yuv = true },
+		{ .format = DRM_FORMAT_VUY101010,	.depth = 0,  .num_planes = 1,
+		  .cpp = { 0, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true },
+		{ .format = DRM_FORMAT_YUV420_8BIT,	.depth = 0,  .num_planes = 1,
+		  .cpp = { 0, 0, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true },
+		{ .format = DRM_FORMAT_YUV420_10BIT,	.depth = 0,  .num_planes = 1,
+		  .cpp = { 0, 0, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true },
 	};
 
 	unsigned int i;
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 4de86dbf40ca..f8396d1b8fbd 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -149,8 +149,12 @@ extern "C" {
 #define DRM_FORMAT_YVYU		fourcc_code('Y', 'V', 'Y', 'U') /* [31:0] Cb0:Y1:Cr0:Y0 8:8:8:8 little endian */
 #define DRM_FORMAT_UYVY		fourcc_code('U', 'Y', 'V', 'Y') /* [31:0] Y1:Cr0:Y0:Cb0 8:8:8:8 little endian */
 #define DRM_FORMAT_VYUY		fourcc_code('V', 'Y', 'U', 'Y') /* [31:0] Y1:Cb0:Y0:Cr0 8:8:8:8 little endian */
+#define DRM_FORMAT_Y210		fourcc_code('Y', '2', '1', '0') /* [63:0] Cr0:0:Y1:0:Cb0:0:Y0:0 10:6:10:6:10:6:10:6 little endian */
 
 #define DRM_FORMAT_AYUV		fourcc_code('A', 'Y', 'U', 'V') /* [31:0] A:Y:Cb:Cr 8:8:8:8 little endian */
+#define DRM_FORMAT_VUY888	fourcc_code('V', 'U', '2', '4') /* [23:0] Cr:Cb:Y 8:8:8 little endian */
+#define DRM_FORMAT_Y410		fourcc_code('Y', '4', '1', '0') /* [31:0] A:Cr:Y:Cb 2:10:10:10 little endian */
+#define DRM_FORMAT_VUY101010	fourcc_code('V', 'U', '3', '0') /* Y followed by U then V, 10:10:10. Non-linear modifier only */
 
 /*
  * packed YCbCr420 2x2 tiled formats
@@ -166,6 +170,15 @@ extern "C" {
 /* [63:0]   X3:X2:Y3:Cr0:Y2:X1:X0:Y1:Cb0:Y0  1:1:10:10:10:1:1:10:10:10 little endian */
 #define DRM_FORMAT_X0L2		fourcc_code('X', '0', 'L', '2')
 
+/*
+ * 1-plane YUV 4:2:0
+ * In these formats, the component ordering is specified (Y, followed by U
+ * then V), but the exact Linear layout is undefined.
+ * These formats can only be used with a non-Linear modifier.
+ */
+#define DRM_FORMAT_YUV420_8BIT	fourcc_code('Y', 'U', '0', '8')
+#define DRM_FORMAT_YUV420_10BIT	fourcc_code('Y', 'U', '1', '0')
+
 /*
  * 2 plane RGB + A
  * index 0 = RGB plane, same format as the corresponding non _A8 format has
@@ -200,6 +213,7 @@ extern "C" {
  * component xxx msb Y [xxx:16-xxx]
  * index 1 = Cr:Cb plane, [31:0] Cr:Cb little endian [xxx:16-xxx:xxx:16-xxx]
  */
+#define DRM_FORMAT_P210		fourcc_code('P', '2', '1', '0') /* 2x1 subsampled Cr:Cb plane, 10 bit per channel */
 #define DRM_FORMAT_P010		fourcc_code('P', '0', '1', '0') /* 2x2 subsampled Cr:Cb plane, 10 bit per channel */
 #define DRM_FORMAT_P012		fourcc_code('P', '0', '1', '2') /* 2x2 subsampled Cr:Cb plane, 12 bit per channel */
 #define DRM_FORMAT_P016		fourcc_code('P', '0', '1', '6') /* 2x2 subsampled Cr:Cb plane, 16 bit per channel */
-- 
2.18.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v5 7/9] drm/afbc: Add AFBC modifier usage documentation
  2018-10-19 10:57 [PATCH v5 0/9] Add method to describe tile/bit_level_packed formats Alexandru Gheorghe
                   ` (5 preceding siblings ...)
  2018-10-19 10:57 ` [PATCH v5 6/9] drm/fourcc: Add AFBC yuv fourccs for Mali Alexandru Gheorghe
@ 2018-10-19 10:57 ` Alexandru Gheorghe
  2018-10-19 10:57 ` [PATCH v5 8/9] drm/selftest: Refactor test-drm_plane_helper Alexandru Gheorghe
  2018-10-19 10:57 ` [PATCH v5 9/9] drm/selftests: Add tests for drm_format_info* helpers Alexandru Gheorghe
  8 siblings, 0 replies; 24+ messages in thread
From: Alexandru Gheorghe @ 2018-10-19 10:57 UTC (permalink / raw)
  To: seanpaul, airlied, dri-devel, liviu.dudau, brian.starkey, malidp,
	maxime.ripard, maarten.lankhorst, ayan.halder, daniel.vetter,
	raymond.smith, david.garbett, lisa.wu, matt.szczesiak,
	charles.xu, james.qian.wang
  Cc: nd

From: Brian Starkey <brian.starkey@arm.com>

AFBC is a flexible, proprietary, lossless compression protocol and
format, with a number of defined DRM format modifiers. To facilitate
consistency and compatibility between different AFBC producers and
consumers, document the expectations for usage of the AFBC DRM format
modifiers in a new .rst chapter.

Signed-off-by: Brian Starkey <brian.starkey@arm.com>
Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
---
 Documentation/gpu/afbc.rst    | 233 ++++++++++++++++++++++++++++++++++
 Documentation/gpu/drivers.rst |   1 +
 MAINTAINERS                   |   1 +
 include/uapi/drm/drm_fourcc.h |   3 +
 4 files changed, 238 insertions(+)
 create mode 100644 Documentation/gpu/afbc.rst

diff --git a/Documentation/gpu/afbc.rst b/Documentation/gpu/afbc.rst
new file mode 100644
index 000000000000..922d955da192
--- /dev/null
+++ b/Documentation/gpu/afbc.rst
@@ -0,0 +1,233 @@
+===================================
+ Arm Framebuffer Compression (AFBC)
+===================================
+
+AFBC is a proprietary lossless image compression protocol and format.
+It provides fine-grained random access and minimizes the amount of
+data transferred between IP blocks.
+
+AFBC can be enabled on drivers which support it via use of the AFBC
+format modifiers defined in drm_fourcc.h. See DRM_FORMAT_MOD_ARM_AFBC(*).
+
+All users of the AFBC modifiers must follow the usage guidelines laid
+out in this document, to ensure compatibility across different AFBC
+producers and consumers.
+
+Components and Ordering
+=======================
+
+AFBC streams can contain several components - where a component
+corresponds to a color channel (i.e. R, G, B, X, A, Y, Cb, Cr).
+The assignment of input/output color channels must be consistent
+between the encoder and the decoder for correct operation, otherwise
+the consumer will interpret the decoded data incorrectly.
+
+Furthermore, when the lossless colorspace transform is used
+(AFBC_FORMAT_MOD_YTR, which should be enabled for RGB buffers for
+maximum compression efficiency), the component order must be:
+
+ * Component 0: R
+ * Component 1: G
+ * Component 2: B
+
+The component ordering is communicated via the fourcc code in the
+fourcc:modifier pair. In general, component '0' is considered to
+reside in the least-significant bits of the corresponding linear
+format. For example, COMP(bits):
+
+ * DRM_FORMAT_ABGR8888
+
+   * Component 0: R(8)
+   * Component 1: G(8)
+   * Component 2: B(8)
+   * Component 3: A(8)
+
+ * DRM_FORMAT_BGR888
+
+   * Component 0: R(8)
+   * Component 1: G(8)
+   * Component 2: B(8)
+
+ * DRM_FORMAT_YUYV
+
+   * Component 0: Y(8)
+   * Component 1: Cb(8, 2x1 subsampled)
+   * Component 2: Cr(8, 2x1 subsampled)
+
+In AFBC, 'X' components are not treated any differently from any other
+component. Therefore, an AFBC buffer with fourcc DRM_FORMAT_XBGR8888
+encodes with 4 components, like so:
+
+ * DRM_FORMAT_XBGR8888
+
+   * Component 0: R(8)
+   * Component 1: G(8)
+   * Component 2: B(8)
+   * Component 3: X(8)
+
+Please note, however, that the inclusion of a "wasted" 'X' channel is
+bad for compression efficiency, and so it's recommended to avoid
+formats containing 'X' bits. If a fourth component is
+required/expected by the encoder/decoder, then it is recommended to
+instead use an equivalent format with alpha, setting all alpha bits to
+'1'. If there is no requirement for a fourth component, then a format
+which doesn't include alpha can be used, e.g. DRM_FORMAT_BGR888.
+
+Number of Planes
+================
+
+Formats which are typically multi-planar in linear layouts (e.g. YUV
+420), can be encoded into one, or multiple, AFBC planes. As with
+component order, the encoder and decoder must agree about the number
+of planes in order to correctly decode the buffer. The fourcc code is
+used to determine the number of encoded planes in an AFBC buffer,
+matching the number of planes for the linear (unmodified) format.
+Within each plane, the component ordering also follows the fourcc
+code:
+
+For example:
+
+ * DRM_FORMAT_YUYV: nplanes = 1
+
+   * Plane 0:
+
+     * Component 0: Y(8)
+     * Component 1: Cb(8, 2x1 subsampled)
+     * Component 2: Cr(8, 2x1 subsampled)
+
+ * DRM_FORMAT_NV12: nplanes = 2
+
+   * Plane 0:
+
+     * Component 0: Y(8)
+
+   * Plane 1:
+
+     * Component 0: Cb(8, 2x1 subsampled)
+     * Component 1: Cr(8, 2x1 subsampled)
+
+Cross-device interoperability
+=============================
+
+For maximum compatibility across devices, the table below defines
+canonical formats for use between AFBC-enabled devices. Formats which
+are listed here must be used exactly as specified when using the AFBC
+modifiers. Formats which are not listed should be avoided.
+
+.. flat-table:: AFBC formats
+
+   * - Fourcc code
+     - Description
+     - Planes/Components
+
+   * - DRM_FORMAT_ABGR2101010
+     - 10-bit per component RGB, with 2-bit alpha
+     - Plane 0: 4 components
+              * Component 0: R(10)
+              * Component 1: G(10)
+              * Component 2: B(10)
+              * Component 3: A(2)
+
+   * - DRM_FORMAT_ABGR8888
+     - 8-bit per component RGB, with 8-bit alpha
+     - Plane 0: 4 components
+              * Component 0: R(8)
+              * Component 1: G(8)
+              * Component 2: B(8)
+              * Component 3: A(8)
+
+   * - DRM_FORMAT_BGR888
+     - 8-bit per component RGB
+     - Plane 0: 3 components
+              * Component 0: R(8)
+              * Component 1: G(8)
+              * Component 2: B(8)
+
+   * - DRM_FORMAT_BGR565
+     - 5/6-bit per component RGB
+     - Plane 0: 3 components
+              * Component 0: R(5)
+              * Component 1: G(6)
+              * Component 2: B(5)
+
+   * - DRM_FORMAT_ABGR1555
+     - 5-bit per component RGB, with 1-bit alpha
+     - Plane 0: 4 components
+              * Component 0: R(5)
+              * Component 1: G(5)
+              * Component 2: B(5)
+              * Component 3: A(1)
+
+   * - DRM_FORMAT_VUY888
+     - 8-bit per component YCbCr 444, single plane
+     - Plane 0: 3 components
+              * Component 0: Y(8)
+              * Component 1: Cb(8)
+              * Component 2: Cr(8)
+
+   * - DRM_FORMAT_VUY101010
+     - 10-bit per component YCbCr 444, single plane
+     - Plane 0: 3 components
+              * Component 0: Y(10)
+              * Component 1: Cb(10)
+              * Component 2: Cr(10)
+
+   * - DRM_FORMAT_YUYV
+     - 8-bit per component YCbCr 422, single plane
+     - Plane 0: 3 components
+              * Component 0: Y(8)
+              * Component 1: Cb(8, 2x1 subsampled)
+              * Component 2: Cr(8, 2x1 subsampled)
+
+   * - DRM_FORMAT_NV16
+     - 8-bit per component YCbCr 422, two plane
+     - Plane 0: 1 component
+              * Component 0: Y(8)
+       Plane 1: 2 components
+              * Component 0: Cb(8, 2x1 subsampled)
+              * Component 1: Cr(8, 2x1 subsampled)
+
+   * - DRM_FORMAT_Y210
+     - 10-bit per component YCbCr 422, single plane
+     - Plane 0: 3 components
+              * Component 0: Y(10)
+              * Component 1: Cb(10, 2x1 subsampled)
+              * Component 2: Cr(10, 2x1 subsampled)
+
+   * - DRM_FORMAT_P210
+     - 10-bit per component YCbCr 422, two plane
+     - Plane 0: 1 component
+              * Component 0: Y(10)
+       Plane 1: 2 components
+              * Component 0: Cb(10, 2x1 subsampled)
+              * Component 1: Cr(10, 2x1 subsampled)
+
+   * - DRM_FORMAT_YUV420_8BIT
+     - 8-bit per component YCbCr 420, single plane
+     - Plane 0: 3 components
+              * Component 0: Y(8)
+              * Component 1: Cb(8, 2x2 subsampled)
+              * Component 2: Cr(8, 2x2 subsampled)
+
+   * - DRM_FORMAT_YUV420_10BIT
+     - 10-bit per component YCbCr 420, single plane
+     - Plane 0: 3 components
+              * Component 0: Y(10)
+              * Component 1: Cb(10, 2x2 subsampled)
+              * Component 2: Cr(10, 2x2 subsampled)
+
+   * - DRM_FORMAT_NV12
+     - 8-bit per component YCbCr 420, two plane
+     - Plane 0: 1 component
+              * Component 0: Y(8)
+       Plane 1: 2 components
+              * Component 0: Cb(8, 2x2 subsampled)
+              * Component 1: Cr(8, 2x2 subsampled)
+
+   * - DRM_FORMAT_P010
+     - 10-bit per component YCbCr 420, two plane
+     - Plane 0: 1 component
+              * Component 0: Y(10)
+       Plane 1: 2 components
+              * Component 0: Cb(10, 2x2 subsampled)
+              * Component 1: Cr(10, 2x2 subsampled)
diff --git a/Documentation/gpu/drivers.rst b/Documentation/gpu/drivers.rst
index 7d2d3875ff1a..8ec755024390 100644
--- a/Documentation/gpu/drivers.rst
+++ b/Documentation/gpu/drivers.rst
@@ -16,6 +16,7 @@ GPU Driver Documentation
    vkms
    bridge/dw-hdmi
    xen-front
+   afbc
 
 .. only::  subproject and html
 
diff --git a/MAINTAINERS b/MAINTAINERS
index 39c3f6682ace..4d3a8822b4c5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1091,6 +1091,7 @@ M:	Mali DP Maintainers <malidp@foss.arm.com>
 S:	Supported
 F:	drivers/gpu/drm/arm/
 F:	Documentation/devicetree/bindings/display/arm,malidp.txt
+F:	Documentation/gpu/afbc.rst
 
 ARM MFM AND FLOPPY DRIVERS
 M:	Ian Molton <spyro@f2s.com>
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index f8396d1b8fbd..b2fb2d53fff7 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -586,6 +586,9 @@ extern "C" {
  * AFBC has several features which may be supported and/or used, which are
  * represented using bits in the modifier. Not all combinations are valid,
  * and different devices or use-cases may support different combinations.
+ *
+ * Further information on the use of AFBC modifiers can be found in
+ * Documentation/gpu/afbc.rst
  */
 #define DRM_FORMAT_MOD_ARM_AFBC(__afbc_mode)	fourcc_mod_code(ARM, __afbc_mode)
 
-- 
2.18.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v5 8/9] drm/selftest: Refactor test-drm_plane_helper
  2018-10-19 10:57 [PATCH v5 0/9] Add method to describe tile/bit_level_packed formats Alexandru Gheorghe
                   ` (6 preceding siblings ...)
  2018-10-19 10:57 ` [PATCH v5 7/9] drm/afbc: Add AFBC modifier usage documentation Alexandru Gheorghe
@ 2018-10-19 10:57 ` Alexandru Gheorghe
  2018-10-19 15:14   ` Daniel Vetter
  2018-10-19 10:57 ` [PATCH v5 9/9] drm/selftests: Add tests for drm_format_info* helpers Alexandru Gheorghe
  8 siblings, 1 reply; 24+ messages in thread
From: Alexandru Gheorghe @ 2018-10-19 10:57 UTC (permalink / raw)
  To: seanpaul, airlied, dri-devel, liviu.dudau, brian.starkey, malidp,
	maxime.ripard, maarten.lankhorst, ayan.halder, daniel.vetter,
	raymond.smith, david.garbett, lisa.wu, matt.szczesiak,
	charles.xu, james.qian.wang
  Cc: nd, Alexandru Gheorghe

The idea is to split test implementations in different compilation
units, but have one single place where we define the list of tests,
in this case(drm_modeset_selftests.h).

Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>
---
 ...er_selftests.h => drm_modeset_selftests.h} |  0
 .../drm/selftests/test-drm_modeset_common.c   | 11 ++++++++++-
 .../drm/selftests/test-drm_modeset_common.h   |  2 +-
 .../gpu/drm/selftests/test-drm_plane_helper.c | 19 +------------------
 4 files changed, 12 insertions(+), 20 deletions(-)
 rename drivers/gpu/drm/selftests/{drm_plane_helper_selftests.h => drm_modeset_selftests.h} (100%)

diff --git a/drivers/gpu/drm/selftests/drm_plane_helper_selftests.h b/drivers/gpu/drm/selftests/drm_modeset_selftests.h
similarity index 100%
rename from drivers/gpu/drm/selftests/drm_plane_helper_selftests.h
rename to drivers/gpu/drm/selftests/drm_modeset_selftests.h
diff --git a/drivers/gpu/drm/selftests/test-drm_modeset_common.c b/drivers/gpu/drm/selftests/test-drm_modeset_common.c
index fad5209043f1..2a7f93774006 100644
--- a/drivers/gpu/drm/selftests/test-drm_modeset_common.c
+++ b/drivers/gpu/drm/selftests/test-drm_modeset_common.c
@@ -7,9 +7,18 @@
 
 #include "test-drm_modeset_common.h"
 
+#define TESTS "drm_modeset_selftests.h"
+#include "drm_selftest.h"
+
+#include "drm_selftest.c"
+
 static int __init test_drm_modeset_init(void)
 {
-	return test_drm_plane_helper();
+	int err;
+
+	err = run_selftests(selftests, ARRAY_SIZE(selftests), NULL);
+
+	return err > 0 ? 0 : err;
 }
 
 static void __exit test_drm_modeset_exit(void)
diff --git a/drivers/gpu/drm/selftests/test-drm_modeset_common.h b/drivers/gpu/drm/selftests/test-drm_modeset_common.h
index bdeba264661f..b0065a2eb067 100644
--- a/drivers/gpu/drm/selftests/test-drm_modeset_common.h
+++ b/drivers/gpu/drm/selftests/test-drm_modeset_common.h
@@ -13,6 +13,6 @@
 
 #define FAIL_ON(x) FAIL((x), "%s", "FAIL_ON(" __stringify(x) ")\n")
 
-int test_drm_plane_helper(void);
+int igt_check_plane_state(void *ignored);
 
 #endif
diff --git a/drivers/gpu/drm/selftests/test-drm_plane_helper.c b/drivers/gpu/drm/selftests/test-drm_plane_helper.c
index 0dad2f812a27..0a9553f51796 100644
--- a/drivers/gpu/drm/selftests/test-drm_plane_helper.c
+++ b/drivers/gpu/drm/selftests/test-drm_plane_helper.c
@@ -11,9 +11,6 @@
 
 #include "test-drm_modeset_common.h"
 
-#define TESTS "drm_plane_helper_selftests.h"
-#include "drm_selftest.h"
-
 static void set_src(struct drm_plane_state *plane_state,
 		    unsigned src_x, unsigned src_y,
 		    unsigned src_w, unsigned src_h)
@@ -76,7 +73,7 @@ static bool check_crtc_eq(struct drm_plane_state *plane_state,
 	return true;
 }
 
-static int igt_check_plane_state(void *ignored)
+int igt_check_plane_state(void *ignored)
 {
 	int ret;
 
@@ -220,17 +217,3 @@ static int igt_check_plane_state(void *ignored)
 
 	return 0;
 }
-
-#include "drm_selftest.c"
-
-/**
- * test_drm_plane_helper - Run drm plane helper selftests.
- */
-int test_drm_plane_helper(void)
-{
-	int err;
-
-	err = run_selftests(selftests, ARRAY_SIZE(selftests), NULL);
-
-	return err > 0 ? 0 : err;
-}
-- 
2.18.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v5 9/9] drm/selftests: Add tests for drm_format_info* helpers
  2018-10-19 10:57 [PATCH v5 0/9] Add method to describe tile/bit_level_packed formats Alexandru Gheorghe
                   ` (7 preceding siblings ...)
  2018-10-19 10:57 ` [PATCH v5 8/9] drm/selftest: Refactor test-drm_plane_helper Alexandru Gheorghe
@ 2018-10-19 10:57 ` Alexandru Gheorghe
  2018-10-19 15:29   ` Daniel Vetter
  8 siblings, 1 reply; 24+ messages in thread
From: Alexandru Gheorghe @ 2018-10-19 10:57 UTC (permalink / raw)
  To: seanpaul, airlied, dri-devel, liviu.dudau, brian.starkey, malidp,
	maxime.ripard, maarten.lankhorst, ayan.halder, daniel.vetter,
	raymond.smith, david.garbett, lisa.wu, matt.szczesiak,
	charles.xu, james.qian.wang
  Cc: nd, Alexandru Gheorghe

Add selftests for the following newly added functions:
 - drm_format_info_block_width
 - drm_format_info_block_height
 - drm_format_info_min_pitch

Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>
---
 drivers/gpu/drm/selftests/Makefile            |   3 +-
 .../gpu/drm/selftests/drm_modeset_selftests.h |   3 +
 drivers/gpu/drm/selftests/test-drm_format.c   | 290 ++++++++++++++++++
 .../drm/selftests/test-drm_modeset_common.h   |   3 +
 4 files changed, 298 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/selftests/test-drm_format.c

diff --git a/drivers/gpu/drm/selftests/Makefile b/drivers/gpu/drm/selftests/Makefile
index 7e6581921da0..07b4f88b422a 100644
--- a/drivers/gpu/drm/selftests/Makefile
+++ b/drivers/gpu/drm/selftests/Makefile
@@ -1,3 +1,4 @@
-test-drm_modeset-y := test-drm_modeset_common.o test-drm_plane_helper.o
+test-drm_modeset-y := test-drm_modeset_common.o test-drm_plane_helper.o \
+                      test-drm_format.o
 
 obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_modeset.o
diff --git a/drivers/gpu/drm/selftests/drm_modeset_selftests.h b/drivers/gpu/drm/selftests/drm_modeset_selftests.h
index 9771290ed228..4e203ac8c134 100644
--- a/drivers/gpu/drm/selftests/drm_modeset_selftests.h
+++ b/drivers/gpu/drm/selftests/drm_modeset_selftests.h
@@ -7,3 +7,6 @@
  * Tests are executed in order by igt/drm_selftests_helper
  */
 selftest(check_plane_state, igt_check_plane_state)
+selftest(check_drm_format_block_width, igt_check_drm_format_block_width)
+selftest(check_drm_format_block_height, igt_check_drm_format_block_height)
+selftest(check_drm_format_min_pitch, igt_check_drm_format_min_pitch)
diff --git a/drivers/gpu/drm/selftests/test-drm_format.c b/drivers/gpu/drm/selftests/test-drm_format.c
new file mode 100644
index 000000000000..5abfd5e28d7d
--- /dev/null
+++ b/drivers/gpu/drm/selftests/test-drm_format.c
@@ -0,0 +1,290 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Test cases for the drm_format functions
+ */
+
+#define pr_fmt(fmt) "drm_format: " fmt
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+
+#include <drm/drm_fourcc.h>
+
+#include "test-drm_modeset_common.h"
+
+int igt_check_drm_format_block_width(void *ignored)
+{
+	const struct drm_format_info *info = NULL;
+
+	/* Test invalid arguments */
+	FAIL_ON(drm_format_info_block_width(info, 0) != 0);
+	FAIL_ON(drm_format_info_block_width(info, -1) != 0);
+	FAIL_ON(drm_format_info_block_width(info, 1) != 0);
+
+	/* Test 1 plane format */
+	info = drm_format_info(DRM_FORMAT_XRGB4444);
+	FAIL_ON(!info);
+	FAIL_ON(drm_format_info_block_width(info, 0) != 1);
+	FAIL_ON(drm_format_info_block_width(info, 1) != 0);
+	FAIL_ON(drm_format_info_block_width(info, -1) != 0);
+
+	/* Test 2 planes format */
+	info = drm_format_info(DRM_FORMAT_NV12);
+	FAIL_ON(!info);
+	FAIL_ON(drm_format_info_block_width(info, 0) != 1);
+	FAIL_ON(drm_format_info_block_width(info, 1) != 1);
+	FAIL_ON(drm_format_info_block_width(info, 2) != 0);
+	FAIL_ON(drm_format_info_block_width(info, -1) != 0);
+
+	/* Test 3 planes format */
+	info = drm_format_info(DRM_FORMAT_YUV422);
+	FAIL_ON(!info);
+	FAIL_ON(drm_format_info_block_width(info, 0) != 1);
+	FAIL_ON(drm_format_info_block_width(info, 1) != 1);
+	FAIL_ON(drm_format_info_block_width(info, 2) != 1);
+	FAIL_ON(drm_format_info_block_width(info, 3) != 0);
+	FAIL_ON(drm_format_info_block_width(info, -1) != 0);
+
+	/* Test a tiled format */
+	info = drm_format_info(DRM_FORMAT_X0L0);
+	FAIL_ON(!info);
+	FAIL_ON(drm_format_info_block_width(info, 0) != 2);
+	FAIL_ON(drm_format_info_block_width(info, 1) != 0);
+	FAIL_ON(drm_format_info_block_width(info, -1) != 0);
+
+	return 0;
+}
+
+int igt_check_drm_format_block_height(void *ignored)
+{
+	const struct drm_format_info *info = NULL;
+
+	/* Test invalid arguments */
+	FAIL_ON(drm_format_info_block_height(info, 0) != 0);
+	FAIL_ON(drm_format_info_block_height(info, -1) != 0);
+	FAIL_ON(drm_format_info_block_height(info, 1) != 0);
+
+	/* Test 1 plane format */
+	info = drm_format_info(DRM_FORMAT_XRGB4444);
+	FAIL_ON(!info);
+	FAIL_ON(drm_format_info_block_height(info, 0) != 1);
+	FAIL_ON(drm_format_info_block_height(info, 1) != 0);
+	FAIL_ON(drm_format_info_block_height(info, -1) != 0);
+
+	/* Test 2 planes format */
+	info = drm_format_info(DRM_FORMAT_NV12);
+	FAIL_ON(!info);
+	FAIL_ON(drm_format_info_block_height(info, 0) != 1);
+	FAIL_ON(drm_format_info_block_height(info, 1) != 1);
+	FAIL_ON(drm_format_info_block_height(info, 2) != 0);
+	FAIL_ON(drm_format_info_block_height(info, -1) != 0);
+
+	/* Test 3 planes format */
+	info = drm_format_info(DRM_FORMAT_YUV422);
+	FAIL_ON(!info);
+	FAIL_ON(drm_format_info_block_height(info, 0) != 1);
+	FAIL_ON(drm_format_info_block_height(info, 1) != 1);
+	FAIL_ON(drm_format_info_block_height(info, 2) != 1);
+	FAIL_ON(drm_format_info_block_height(info, 3) != 0);
+	FAIL_ON(drm_format_info_block_height(info, -1) != 0);
+
+	/* Test a tiled format */
+	info = drm_format_info(DRM_FORMAT_X0L0);
+	FAIL_ON(!info);
+	FAIL_ON(drm_format_info_block_height(info, 0) != 2);
+	FAIL_ON(drm_format_info_block_height(info, 1) != 0);
+	FAIL_ON(drm_format_info_block_height(info, -1) != 0);
+
+	return 0;
+}
+
+int igt_check_drm_format_min_pitch(void *ignored)
+{
+	const struct drm_format_info *info = NULL;
+
+	/* Test invalid arguments */
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
+	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
+	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
+
+	/* Test 1 plane 8 bits per pixel format */
+	info = drm_format_info(DRM_FORMAT_RGB332);
+	FAIL_ON(!info);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
+	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
+	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
+
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 1);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 2);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 640);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 1024);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 1920);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 4096);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 671);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
+			(uint64_t)UINT_MAX);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, (UINT_MAX - 1)) !=
+			(uint64_t)(UINT_MAX - 1));
+
+	/* Test 1 plane 16 bits per pixel format */
+	info = drm_format_info(DRM_FORMAT_XRGB4444);
+	FAIL_ON(!info);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
+	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
+	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
+
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 2);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 4);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 1280);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 2048);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 3840);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 8192);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 1342);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
+			(uint64_t)UINT_MAX * 2);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, (UINT_MAX - 1)) !=
+			(uint64_t)(UINT_MAX - 1) * 2);
+
+	/* Test 1 plane 24 bits per pixel format */
+	info = drm_format_info(DRM_FORMAT_RGB888);
+	FAIL_ON(!info);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
+	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
+	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
+
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 3);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 6);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 1920);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 3072);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 5760);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 12288);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 2013);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
+			(uint64_t)UINT_MAX * 3);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX - 1) !=
+			(uint64_t)(UINT_MAX - 1) * 3);
+
+	/* Test 1 plane 32 bits per pixel format */
+	info = drm_format_info(DRM_FORMAT_ABGR8888);
+	FAIL_ON(!info);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
+	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
+	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
+
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 4);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 8);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 2560);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 4096);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 7680);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 16384);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 2684);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
+			(uint64_t)UINT_MAX * 4);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX - 1) !=
+			(uint64_t)(UINT_MAX - 1) * 4);
+
+	/* Test 2 planes format */
+	info = drm_format_info(DRM_FORMAT_NV12);
+	FAIL_ON(!info);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
+	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
+	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
+	FAIL_ON(drm_format_info_min_pitch(info, 2, 0) != 0);
+
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 1);
+	FAIL_ON(drm_format_info_min_pitch(info, 1, 1) != 2);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 2);
+	FAIL_ON(drm_format_info_min_pitch(info, 1, 1) != 2);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 640);
+	FAIL_ON(drm_format_info_min_pitch(info, 1, 320) != 640);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 1024);
+	FAIL_ON(drm_format_info_min_pitch(info, 1, 512) != 1024);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 1920);
+	FAIL_ON(drm_format_info_min_pitch(info, 1, 960) != 1920);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 4096);
+	FAIL_ON(drm_format_info_min_pitch(info, 1, 2048) != 4096);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 671);
+	FAIL_ON(drm_format_info_min_pitch(info, 1, 336) != 672);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
+			(uint64_t)UINT_MAX);
+	FAIL_ON(drm_format_info_min_pitch(info, 1, UINT_MAX / 2 + 1) !=
+			(uint64_t)UINT_MAX + 1);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, (UINT_MAX - 1)) !=
+			(uint64_t)(UINT_MAX - 1));
+	FAIL_ON(drm_format_info_min_pitch(info, 1, (UINT_MAX - 1) /  2) !=
+			(uint64_t)(UINT_MAX - 1));
+
+	/* Test 3 planes 8 bits per pixel format */
+	info = drm_format_info(DRM_FORMAT_YUV422);
+	FAIL_ON(!info);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
+	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
+	FAIL_ON(drm_format_info_min_pitch(info, 2, 0) != 0);
+	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
+	FAIL_ON(drm_format_info_min_pitch(info, 3, 0) != 0);
+
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 1);
+	FAIL_ON(drm_format_info_min_pitch(info, 1, 1) != 1);
+	FAIL_ON(drm_format_info_min_pitch(info, 2, 1) != 1);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 2);
+	FAIL_ON(drm_format_info_min_pitch(info, 1, 2) != 2);
+	FAIL_ON(drm_format_info_min_pitch(info, 2, 2) != 2);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 640);
+	FAIL_ON(drm_format_info_min_pitch(info, 1, 320) != 320);
+	FAIL_ON(drm_format_info_min_pitch(info, 2, 320) != 320);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 1024);
+	FAIL_ON(drm_format_info_min_pitch(info, 1, 512) != 512);
+	FAIL_ON(drm_format_info_min_pitch(info, 2, 512) != 512);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 1920);
+	FAIL_ON(drm_format_info_min_pitch(info, 1, 960) != 960);
+	FAIL_ON(drm_format_info_min_pitch(info, 2, 960) != 960);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 4096);
+	FAIL_ON(drm_format_info_min_pitch(info, 1, 2048) != 2048);
+	FAIL_ON(drm_format_info_min_pitch(info, 2, 2048) != 2048);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 671);
+	FAIL_ON(drm_format_info_min_pitch(info, 1, 336) != 336);
+	FAIL_ON(drm_format_info_min_pitch(info, 2, 336) != 336);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
+			(uint64_t)UINT_MAX);
+	FAIL_ON(drm_format_info_min_pitch(info, 1, UINT_MAX / 2 + 1) !=
+			(uint64_t)UINT_MAX / 2 + 1);
+	FAIL_ON(drm_format_info_min_pitch(info, 2, UINT_MAX / 2 + 1) !=
+			(uint64_t)UINT_MAX / 2 + 1);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, (UINT_MAX - 1) / 2) !=
+			(uint64_t)(UINT_MAX - 1) / 2);
+	FAIL_ON(drm_format_info_min_pitch(info, 1, (UINT_MAX - 1) / 2) !=
+			(uint64_t)(UINT_MAX - 1) / 2);
+	FAIL_ON(drm_format_info_min_pitch(info, 2, (UINT_MAX - 1) / 2) !=
+			(uint64_t)(UINT_MAX - 1) / 2);
+
+	/* Test tiled format */
+	info = drm_format_info(DRM_FORMAT_X0L2);
+	FAIL_ON(!info);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
+	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
+	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
+
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 2);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 4);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 1280);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 2048);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 3840);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 8192);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 1342);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
+			(uint64_t)UINT_MAX * 2);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX - 1) !=
+			(uint64_t)(UINT_MAX - 1) * 2);
+
+	/* Test format with cpp/char_per_block 0 */
+	info = drm_format_info(DRM_FORMAT_VUY101010);
+	FAIL_ON(!info);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
+	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
+	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
+
+	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 0);
+	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) != 0);
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/selftests/test-drm_modeset_common.h b/drivers/gpu/drm/selftests/test-drm_modeset_common.h
index b0065a2eb067..592a6581b189 100644
--- a/drivers/gpu/drm/selftests/test-drm_modeset_common.h
+++ b/drivers/gpu/drm/selftests/test-drm_modeset_common.h
@@ -14,5 +14,8 @@
 #define FAIL_ON(x) FAIL((x), "%s", "FAIL_ON(" __stringify(x) ")\n")
 
 int igt_check_plane_state(void *ignored);
+int igt_check_drm_format_block_width(void *ignored);
+int igt_check_drm_format_block_height(void *ignored);
+int igt_check_drm_format_min_pitch(void *ignored);
 
 #endif
-- 
2.18.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [PATCH v5 1/9] drm: fourcc: Convert drm_format_info kerneldoc to in-line member documentation
  2018-10-19 10:57 ` [PATCH v5 1/9] drm: fourcc: Convert drm_format_info kerneldoc to in-line member documentation Alexandru Gheorghe
@ 2018-10-19 12:54   ` Maxime Ripard
  2018-10-22  9:36     ` Alexandru-Cosmin Gheorghe
  0 siblings, 1 reply; 24+ messages in thread
From: Maxime Ripard @ 2018-10-19 12:54 UTC (permalink / raw)
  To: Alexandru Gheorghe
  Cc: charles.xu, nd, matt.szczesiak, airlied, liviu.dudau, dri-devel,
	david.garbett, seanpaul, lisa.wu, daniel.vetter, malidp,
	ayan.halder, james.qian.wang

On Fri, Oct 19, 2018 at 11:57:44AM +0100, Alexandru Gheorghe wrote:
> In-line member documentation seems to be desired way of documenting
> structure members.
> 
> This change had been suggested by Daniel Vetter here:
> https://lists.freedesktop.org/archives/dri-devel/2018-October/192176.html
> 
> Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>

Reviewed-by: Maxime Ripard <maxime.ripard@bootlin.com>

Thanks!
Maxime

-- 
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v5 2/9] drm/fourcc: Add char_per_block, block_w and block_h in drm_format_info
  2018-10-19 10:57 ` [PATCH v5 2/9] drm/fourcc: Add char_per_block, block_w and block_h in drm_format_info Alexandru Gheorghe
@ 2018-10-19 13:09   ` Brian Starkey
  2018-10-22 10:07     ` Alexandru-Cosmin Gheorghe
  0 siblings, 1 reply; 24+ messages in thread
From: Brian Starkey @ 2018-10-19 13:09 UTC (permalink / raw)
  To: Alexandru Gheorghe
  Cc: charles.xu, nd, matt.szczesiak, airlied, liviu.dudau, dri-devel,
	maxime.ripard, david.garbett, seanpaul, lisa.wu, daniel.vetter,
	malidp, ayan.halder, james.qian.wang

Hi Alex,

On Fri, Oct 19, 2018 at 11:57:45AM +0100, Alexandru Gheorghe wrote:
>For some pixel formats .cpp structure in drm_format info it's not
>enough to describe the peculiarities of the pixel layout, for example
>tiled formats or packed formats at bit level.
>
>What's implemented here is to add three new members to drm_format_info
>that could describe such formats:
>
>- char_per_block[3]
>- block_w[3]
>- block_h[3]
>
>char_per_block will be put in a union alongside cpp, for transparent
>compatibility  with the existing format descriptions.
>
>Regarding, block_w and block_h they are intended to be used through
>their equivalent getters drm_format_info_block_width /
>drm_format_info_block_height, the reason of the getters is to abstract
>the fact that for normal formats block_w and block_h will be unset/0,
>but the methods will be returning 1.
>
>Additionally, convenience function drm_format_info_min_pitch had been
>added that computes the minimum required pitch for a given pixel
>format and buffer width.
>
>Using that the following drm core functions had been updated to
>generically handle both block and non-block formats:
>
>- drm_fb_cma_get_gem_addr: for block formats it will just return the
>  beginning of the block.
>- framebuffer_check: Use the newly added drm_format_info_min_pitch.
>- drm_gem_fb_create_with_funcs: Use the newly added
>  drm_format_info_min_pitch.
>- In places where is not expecting to handle block formats, like fbdev
>  helpers I just added some warnings in case the block width/height
>  are greater than 1.
>
>Changes since v3:
> - Add helper function for computing the minimum required pitch.
> - Improve/cleanup documentation
>
>Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>

I commented on a couple of tiny typographical things below, but
otherwise this looks good to me. Thanks!

Reviewed-by: Brian Starkey <brian.starkey@arm.com>

>---
> drivers/gpu/drm/drm_fb_cma_helper.c          | 21 ++++++-
> drivers/gpu/drm/drm_fb_helper.c              |  6 ++
> drivers/gpu/drm/drm_fourcc.c                 | 62 ++++++++++++++++++++
> drivers/gpu/drm/drm_framebuffer.c            |  6 +-
> drivers/gpu/drm/drm_gem_framebuffer_helper.c |  2 +-
> include/drm/drm_fourcc.h                     | 61 ++++++++++++++++++-
> 6 files changed, 149 insertions(+), 9 deletions(-)
>
>diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c
>index d52344a03aa8..83941a8ca0e0 100644
>--- a/drivers/gpu/drm/drm_fb_cma_helper.c
>+++ b/drivers/gpu/drm/drm_fb_cma_helper.c
>@@ -72,7 +72,9 @@ struct drm_gem_cma_object *drm_fb_cma_get_gem_obj(struct drm_framebuffer *fb,
> EXPORT_SYMBOL_GPL(drm_fb_cma_get_gem_obj);
>
> /**
>- * drm_fb_cma_get_gem_addr() - Get physical address for framebuffer
>+ * drm_fb_cma_get_gem_addr() - Get physical address for framebuffer, for pixel
>+ * formats where values are grouped in blocks this will get you the beginning of
>+ * the block
>  * @fb: The framebuffer
>  * @state: Which state of drm plane
>  * @plane: Which plane
>@@ -87,6 +89,14 @@ dma_addr_t drm_fb_cma_get_gem_addr(struct drm_framebuffer *fb,
> 	struct drm_gem_cma_object *obj;
> 	dma_addr_t paddr;
> 	u8 h_div = 1, v_div = 1;
>+	u32 block_w = drm_format_info_block_width(fb->format, plane);
>+	u32 block_h = drm_format_info_block_height(fb->format, plane);
>+	u32 block_size = fb->format->char_per_block[plane];
>+	u32 sample_x;
>+	u32 sample_y;
>+	u32 block_start_y;
>+	u32 num_hblocks;
>+

nit: extra newline

>
> 	obj = drm_fb_cma_get_gem_obj(fb, plane);
> 	if (!obj)
>@@ -99,8 +109,13 @@ dma_addr_t drm_fb_cma_get_gem_addr(struct drm_framebuffer *fb,
> 		v_div = fb->format->vsub;
> 	}
>
>-	paddr += (fb->format->cpp[plane] * (state->src_x >> 16)) / h_div;
>-	paddr += (fb->pitches[plane] * (state->src_y >> 16)) / v_div;
>+	sample_x = (state->src_x >> 16) / h_div;
>+	sample_y = (state->src_y >> 16) / v_div;
>+	block_start_y = (sample_y / block_h) * block_h;
>+	num_hblocks = sample_x / block_w;
>+
>+	paddr += fb->pitches[plane] * block_start_y;
>+	paddr += block_size * num_hblocks;
>
> 	return paddr;
> }
>diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
>index a504a5e05676..9add0d7da744 100644
>--- a/drivers/gpu/drm/drm_fb_helper.c
>+++ b/drivers/gpu/drm/drm_fb_helper.c
>@@ -1595,6 +1595,10 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
> 	if (var->pixclock != 0 || in_dbg_master())
> 		return -EINVAL;
>
>+	if ((drm_format_info_block_width(fb->format, 0) > 1) ||
>+	    (drm_format_info_block_height(fb->format, 0) > 1))
>+		return -EINVAL;
>+
> 	/*
> 	 * Changes struct fb_var_screeninfo are currently not pushed back
> 	 * to KMS, hence fail if different settings are requested.
>@@ -1969,6 +1973,8 @@ void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helpe
> {
> 	struct drm_framebuffer *fb = fb_helper->fb;
>
>+	WARN_ON((drm_format_info_block_width(fb->format, 0) > 1) ||
>+		(drm_format_info_block_height(fb->format, 0) > 1));
> 	info->pseudo_palette = fb_helper->pseudo_palette;
> 	info->var.xres_virtual = fb->width;
> 	info->var.yres_virtual = fb->height;
>diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
>index e177f6d0d1f4..a843a5fc8dbf 100644
>--- a/drivers/gpu/drm/drm_fourcc.c
>+++ b/drivers/gpu/drm/drm_fourcc.c
>@@ -403,3 +403,65 @@ int drm_format_plane_height(int height, uint32_t format, int plane)
> 	return height / info->vsub;
> }
> EXPORT_SYMBOL(drm_format_plane_height);
>+
>+/**
>+ * drm_format_info_block_width - width in pixels of block.
>+ * @info: pixel format info
>+ * @plane: plane index
>+ *
>+ * Returns:
>+ * The width in pixels of a block, depending on the plane index.
>+ */
>+unsigned int drm_format_info_block_width(const struct drm_format_info *info,
>+					 int plane)
>+{
>+	if (!info || plane < 0 || plane >= info->num_planes)
>+		return 0;

Thinking aloud: The other helpers don't check < 0, but it looks to me
that it would make sense (someday...) to change all of the 'plane'
arguments to 'unsigned int' so that there's no possibility of < 0.

>+
>+	if (!info->block_w[plane])
>+		return 1;
>+	return info->block_w[plane];
>+}
>+EXPORT_SYMBOL(drm_format_info_block_width);
>+
>+/**
>+ * drm_format_info_block_height - height in pixels of a block
>+ * @info: pixel format info
>+ * @plane: plane index
>+ *
>+ * Returns:
>+ * The height in pixels of a block, depending on the plane index.
>+ */
>+unsigned int drm_format_info_block_height(const struct drm_format_info *info,
>+					  int plane)
>+{
>+	if (!info || plane < 0 || plane >= info->num_planes)
>+		return 0;
>+
>+	if (!info->block_h[plane])
>+		return 1;
>+	return info->block_h[plane];
>+}
>+EXPORT_SYMBOL(drm_format_info_block_height);
>+
>+/**
>+ * drm_format_info_min_pitch - computes the minimum required pitch in bytes
>+ * @info: pixel format info
>+ * @plane: plane index
>+ * @buffer_width: buffer width in pixels
>+ *
>+ * Returns:
>+ * The minimum required pitch in bytes for a buffer by taking into consideration
>+ * the pixel format information and the buffer width.
>+ */
>+uint64_t drm_format_info_min_pitch(const struct drm_format_info *info,
>+				   int plane, unsigned int buffer_width)
>+{
>+	if (!info || plane < 0 || plane >= info->num_planes)
>+		return 0;
>+
>+	return DIV_ROUND_UP((u64)buffer_width * info->char_per_block[plane],
>+			    drm_format_info_block_width(info, plane) *
>+			    drm_format_info_block_height(info, plane));
>+}
>+EXPORT_SYMBOL(drm_format_info_min_pitch);
>diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
>index 3bf729d0aae5..6aca8a1ccdb6 100644
>--- a/drivers/gpu/drm/drm_framebuffer.c
>+++ b/drivers/gpu/drm/drm_framebuffer.c
>@@ -195,20 +195,20 @@ static int framebuffer_check(struct drm_device *dev,
> 	for (i = 0; i < info->num_planes; i++) {
> 		unsigned int width = fb_plane_width(r->width, info, i);
> 		unsigned int height = fb_plane_height(r->height, info, i);
>-		unsigned int cpp = info->cpp[i];
>+		u64 min_pitch = drm_format_info_min_pitch(info, i, width);
>
> 		if (!r->handles[i]) {
> 			DRM_DEBUG_KMS("no buffer object handle for plane %d\n", i);
> 			return -EINVAL;
> 		}
>
>-		if ((uint64_t) width * cpp > UINT_MAX)
>+		if (min_pitch > UINT_MAX)
> 			return -ERANGE;
>
> 		if ((uint64_t) height * r->pitches[i] + r->offsets[i] > UINT_MAX)
> 			return -ERANGE;
>
>-		if (r->pitches[i] < width * cpp) {
>+		if (r->pitches[i] < min_pitch) {
> 			DRM_DEBUG_KMS("bad pitch %u for plane %d\n", r->pitches[i], i);
> 			return -EINVAL;
> 		}
>diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
>index ded7a379ac35..acb466d25afc 100644
>--- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
>+++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
>@@ -171,7 +171,7 @@ drm_gem_fb_create_with_funcs(struct drm_device *dev, struct drm_file *file,
> 		}
>
> 		min_size = (height - 1) * mode_cmd->pitches[i]
>-			 + width * info->cpp[i]
>+			 + drm_format_info_min_pitch(info, i, width)
> 			 + mode_cmd->offsets[i];
>
> 		if (objs[i]->size < min_size) {
>diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
>index 345f11227e9e..253d4c07a10c 100644
>--- a/include/drm/drm_fourcc.h
>+++ b/include/drm/drm_fourcc.h
>@@ -69,8 +69,59 @@ struct drm_format_info {
> 	/** @num_planes: Number of color planes (1 to 3) */
> 	u8 num_planes;
>
>-	/** @cpp: Number of bytes per pixel (per plane) */
>-	u8 cpp[3];
>+	union {
>+		/**
>+		 * @cpp:
>+		 *
>+		 * Number of bytes per pixel (per plane), this is aliased with
>+		 * @char_per_block. It is deprecated in favour of using the
>+		 * triplet @char_per_block, @block_w, @block_h for better
>+		 * describing the pixel format.
>+		 */
>+		u8 cpp[3];
>+
>+		/**
>+		 * @char_per_block:
>+		 *
>+		 * Number of bytes per block (per plane), where blocks are
>+		 * defined as a rectangle of pixels which are stored next to
>+		 * each other in a byte aligned memory region. Together with
>+		 * @block_w and @block_h this is used to properly describe tiles
>+		 * in tiled formats or to describe groups of pixels in packed
>+		 * formats for which the memory needed for a single pixel it's

s/it's/is/

>+		 * not byte aligned.
>+		 *
>+		 * @cpp had been kept from historical reasons because there are

s/had/has/, s/from/for/

>+		 * a lot of places in drivers where it's used. In drm core for
>+		 * generic code paths the preferred way is to use
>+		 * @char_per_block, drm_format_info_block_width() and
>+		 * drm_format_info_block_height() which allows handling both
>+		 * block and non-block formats in the same way.
>+		 *
>+		 * For formats that are intended to be used only with non-linear
>+		 * modifiers both @cpp and @char_per_block must be 0 in the
>+		 * generic format table. Drivers could supply accurate
>+		 * information from their drm_mode_config.get_format_info hook
>+		 * if they want the core to be validating the pitch.
>+		 */
>+		u8 char_per_block[3];
>+	};
>+
>+	/**
>+	 * @block_w:
>+	 *
>+	 * Block width in pixels, this is intended to be accessed through
>+	 * drm_format_info_block_width()
>+	 */
>+	u8 block_w[3];
>+
>+	/**
>+	 * @block_h:
>+	 *
>+	 * Block height in pixels, this is intended to be accessed through
>+	 * drm_format_info_block_height()
>+	 */
>+	u8 block_h[3];
>
> 	/** @hsub: Horizontal chroma subsampling factor */
> 	u8 hsub;
>@@ -106,6 +157,12 @@ int drm_format_horz_chroma_subsampling(uint32_t format);
> int drm_format_vert_chroma_subsampling(uint32_t format);
> int drm_format_plane_width(int width, uint32_t format, int plane);
> int drm_format_plane_height(int height, uint32_t format, int plane);
>+unsigned int drm_format_info_block_width(const struct drm_format_info *info,
>+					 int plane);
>+unsigned int drm_format_info_block_height(const struct drm_format_info *info,
>+					  int plane);
>+uint64_t drm_format_info_min_pitch(const struct drm_format_info *info,
>+				   int plane, unsigned int buffer_width);
> const char *drm_get_format_name(uint32_t format, struct drm_format_name_buf *buf);
>
> #endif /* __DRM_FOURCC_H__ */
>-- 
>2.18.0
>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v5 3/9] drm/fourcc: Add fourcc for Mali linear tiled formats
  2018-10-19 10:57 ` [PATCH v5 3/9] drm/fourcc: Add fourcc for Mali linear tiled formats Alexandru Gheorghe
@ 2018-10-19 13:12   ` Brian Starkey
  0 siblings, 0 replies; 24+ messages in thread
From: Brian Starkey @ 2018-10-19 13:12 UTC (permalink / raw)
  To: Alexandru Gheorghe
  Cc: charles.xu, nd, matt.szczesiak, airlied, liviu.dudau, dri-devel,
	maxime.ripard, david.garbett, seanpaul, lisa.wu, daniel.vetter,
	malidp, ayan.halder, james.qian.wang

Hi Alex,

On Fri, Oct 19, 2018 at 11:57:46AM +0100, Alexandru Gheorghe wrote:
>Mali-DP implements a number of tiled yuv formats which are not
>currently described in drm_fourcc.h.
>This adds those definitions and describes their memory layout by
>using the newly added char_per_block, block_w, block_h.
>
>Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>

I'm splitting formatting hairs again below, but otherwise LGTM:

Reviewed-by: Brian Starkey <brian.starkey@arm.com>

>---
> drivers/gpu/drm/drm_fourcc.c  | 12 ++++++++++++
> include/uapi/drm/drm_fourcc.h | 14 ++++++++++++++
> 2 files changed, 26 insertions(+)
>
>diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
>index a843a5fc8dbf..69caa577149c 100644
>--- a/drivers/gpu/drm/drm_fourcc.c
>+++ b/drivers/gpu/drm/drm_fourcc.c
>@@ -228,6 +228,18 @@ const struct drm_format_info *__drm_format_info(u32 format)
> 		{ .format = DRM_FORMAT_P010,		.depth = 0,  .num_planes = 2, .cpp = { 2, 4, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true  },
> 		{ .format = DRM_FORMAT_P012,		.depth = 0,  .num_planes = 2, .cpp = { 2, 4, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true  },
> 		{ .format = DRM_FORMAT_P016,		.depth = 0,  .num_planes = 2, .cpp = { 2, 4, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true  },
>+		{ .format = DRM_FORMAT_Y0L0,		.depth = 0,  .num_planes = 1,
>+		  .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, .block_h = { 2, 0, 0},

I think you're missing a space before all the closing braces on
.block_h

>+		  .hsub = 2, .vsub = 2, .has_alpha = true, .is_yuv = true },
>+		{ .format = DRM_FORMAT_X0L0,		.depth = 0,  .num_planes = 1,
>+		  .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, .block_h = { 2, 0, 0},
>+		  .hsub = 2, .vsub = 2, .is_yuv = true },
>+		{ .format = DRM_FORMAT_Y0L2,		.depth = 0,  .num_planes = 1,
>+		  .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, .block_h = { 2, 0, 0},
>+		  .hsub = 2, .vsub = 2, .has_alpha = true, .is_yuv = true },
>+		{ .format = DRM_FORMAT_X0L2,		.depth = 0,  .num_planes = 1,
>+		  .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, .block_h = { 2, 0, 0},
>+		  .hsub = 2, .vsub = 2, .is_yuv = true },
> 	};
>
> 	unsigned int i;
>diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
>index 600106adf91f..4de86dbf40ca 100644
>--- a/include/uapi/drm/drm_fourcc.h
>+++ b/include/uapi/drm/drm_fourcc.h
>@@ -152,6 +152,20 @@ extern "C" {
>
> #define DRM_FORMAT_AYUV		fourcc_code('A', 'Y', 'U', 'V') /* [31:0] A:Y:Cb:Cr 8:8:8:8 little endian */
>
>+/*
>+ * packed YCbCr420 2x2 tiled formats
>+ * first 64 bits will contain Y,Cb,Cr components for a 2x2 tile
>+ */
>+/* [63:0]   A3:A2:Y3:0:Cr0:0:Y2:0:A1:A0:Y1:0:Cb0:0:Y0:0  1:1:8:2:8:2:8:2:1:1:8:2:8:2:8:2 little endian */
>+#define DRM_FORMAT_Y0L0		fourcc_code('Y', '0', 'L', '0')
>+/* [63:0]   X3:X2:Y3:0:Cr0:0:Y2:0:X1:X0:Y1:0:Cb0:0:Y0:0  1:1:8:2:8:2:8:2:1:1:8:2:8:2:8:2 little endian */
>+#define DRM_FORMAT_X0L0		fourcc_code('X', '0', 'L', '0')
>+
>+/* [63:0]   A3:A2:Y3:Cr0:Y2:A1:A0:Y1:Cb0:Y0  1:1:10:10:10:1:1:10:10:10 little endian */
>+#define DRM_FORMAT_Y0L2		fourcc_code('Y', '0', 'L', '2')
>+/* [63:0]   X3:X2:Y3:Cr0:Y2:X1:X0:Y1:Cb0:Y0  1:1:10:10:10:1:1:10:10:10 little endian */
>+#define DRM_FORMAT_X0L2		fourcc_code('X', '0', 'L', '2')
>+
> /*
>  * 2 plane RGB + A
>  * index 0 = RGB plane, same format as the corresponding non _A8 format has
>-- 
>2.18.0
>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v5 4/9] drm: mali-dp: Enable Mali-DP tiled buffer formats
  2018-10-19 10:57 ` [PATCH v5 4/9] drm: mali-dp: Enable Mali-DP tiled buffer formats Alexandru Gheorghe
@ 2018-10-19 13:17   ` Brian Starkey
  2018-10-22 10:08     ` Alexandru-Cosmin Gheorghe
  0 siblings, 1 reply; 24+ messages in thread
From: Brian Starkey @ 2018-10-19 13:17 UTC (permalink / raw)
  To: Alexandru Gheorghe
  Cc: charles.xu, nd, matt.szczesiak, airlied, liviu.dudau, dri-devel,
	maxime.ripard, david.garbett, seanpaul, lisa.wu, daniel.vetter,
	malidp, ayan.halder, james.qian.wang

Hi Alex,

On Fri, Oct 19, 2018 at 11:57:47AM +0100, Alexandru Gheorghe wrote:
>Enable the following formats
>- DRM_FORMAT_X0L0: DP650
>- DRM_FORMAT_X0L2: DP550, DP650
>
>Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>

A couple of suggestions below, but with or without you can add my
r-b.

>---
> drivers/gpu/drm/arm/malidp_hw.c     | 14 +++++++++++---
> drivers/gpu/drm/arm/malidp_planes.c | 23 +++++++++++++++++++++--
> 2 files changed, 32 insertions(+), 5 deletions(-)
>
>diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
>index c94a4422e0e9..e01fc0e5b503 100644
>--- a/drivers/gpu/drm/arm/malidp_hw.c
>+++ b/drivers/gpu/drm/arm/malidp_hw.c
>@@ -77,12 +77,18 @@ static const struct malidp_format_id malidp500_de_formats[] = {
> 	{ DRM_FORMAT_YUYV, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 2) },	\
> 	{ DRM_FORMAT_UYVY, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 3) },	\
> 	{ DRM_FORMAT_NV12, DE_VIDEO1 | DE_VIDEO2 | SE_MEMWRITE, MALIDP_ID(5, 6) },	\
>-	{ DRM_FORMAT_YUV420, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 7) }
>+	{ DRM_FORMAT_YUV420, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 7) }, \
>+	{ DRM_FORMAT_X0L2, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(6, 6)}
>
> static const struct malidp_format_id malidp550_de_formats[] = {
> 	MALIDP_COMMON_FORMATS,
> };
>
>+static const struct malidp_format_id malidp650_de_formats[] = {
>+	MALIDP_COMMON_FORMATS,
>+	{ DRM_FORMAT_X0L0, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 4)},
>+};
>+
> static const struct malidp_layer malidp500_layers[] = {
> 	{ DE_VIDEO1, MALIDP500_DE_LV_BASE, MALIDP500_DE_LV_PTR_BASE, MALIDP_DE_LV_STRIDE0, MALIDP500_LV_YUV2RGB },
> 	{ DE_GRAPHICS1, MALIDP500_DE_LG1_BASE, MALIDP500_DE_LG1_PTR_BASE, MALIDP_DE_LG_STRIDE, 0 },
>@@ -595,6 +601,8 @@ static int malidp550_rotmem_required(struct malidp_hw_device *hwdev, u16 w, u16
> 	case DRM_FORMAT_BGR565:
> 	case DRM_FORMAT_UYVY:
> 	case DRM_FORMAT_YUYV:
>+	case DRM_FORMAT_X0L0:
>+	case DRM_FORMAT_X0L2:
> 		bytes_per_col = 32;
> 		break;
> 	/* 16 lines at 1.5 bytes per pixel */
>@@ -860,8 +868,8 @@ const struct malidp_hw malidp_device[MALIDP_MAX_DEVICES] = {
> 					    MALIDP550_DC_IRQ_SE,
> 				.vsync_irq = MALIDP550_DC_IRQ_CONF_VALID,
> 			},
>-			.pixel_formats = malidp550_de_formats,
>-			.n_pixel_formats = ARRAY_SIZE(malidp550_de_formats),
>+			.pixel_formats = malidp650_de_formats,
>+			.n_pixel_formats = ARRAY_SIZE(malidp650_de_formats),
> 			.bus_align_bytes = 16,
> 		},
> 		.query_hw = malidp650_query_hw,
>diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c
>index 49c37f6dd63e..33bbc29da774 100644
>--- a/drivers/gpu/drm/arm/malidp_planes.c
>+++ b/drivers/gpu/drm/arm/malidp_planes.c
>@@ -196,13 +196,26 @@ static int malidp_de_plane_check(struct drm_plane *plane,
> 	ms->n_planes = fb->format->num_planes;
> 	for (i = 0; i < ms->n_planes; i++) {
> 		u8 alignment = malidp_hw_get_pitch_align(mp->hwdev, rotated);
>-		if (fb->pitches[i] & (alignment - 1)) {
>+
>+		if ((fb->pitches[i] * drm_format_info_block_height(fb->format, i))
>+				& (alignment - 1)) {
> 			DRM_DEBUG_KMS("Invalid pitch %u for plane %d\n",
> 				      fb->pitches[i], i);
> 			return -EINVAL;
> 		}
> 	}
>
>+	if (fb->width % drm_format_info_block_width(fb->format, 0) ||
>+	    fb->height % drm_format_info_block_height(fb->format, 0)) {
>+		DRM_DEBUG_KMS("Buffer width/height needs to be a multiple of tile sizes");
>+		return -EINVAL;
>+	}
>+	if ((state->src_x >> 16) % drm_format_info_block_width(fb->format, 0) ||
>+	    (state->src_y >> 16) % drm_format_info_block_height(fb->format, 0)) {
>+		DRM_DEBUG_KMS("Plane src_x/src_y needs to be a multiple of tile sizes");
>+		return -EINVAL;
>+	}

Some local variables for block_w and block_h instead of all the
function calls might be easier to parse in this function.

>+
> 	if ((state->crtc_w > mp->hwdev->max_line_size) ||
> 	    (state->crtc_h > mp->hwdev->max_line_size) ||
> 	    (state->crtc_w < mp->hwdev->min_line_size) ||
>@@ -258,8 +271,14 @@ static void malidp_de_set_plane_pitches(struct malidp_plane *mp,
> 		num_strides = (mp->hwdev->hw->features &
> 			       MALIDP_DEVICE_LV_HAS_3_STRIDES) ? 3 : 2;
>
>+	/*
>+	 * The drm convention for pitch is that it needs to cover width * cpp,
>+	 * but our hardware wants the pitch/stride to cover all rows included
>+	 * in a tile.
>+	 */
> 	for (i = 0; i < num_strides; ++i)
>-		malidp_hw_write(mp->hwdev, pitches[i],
>+		malidp_hw_write(mp->hwdev, pitches[i] *
>+				drm_format_info_block_height(mp->base.state->fb->format, i),
> 				mp->layer->base +
> 				mp->layer->stride_offset + i * 4);

Personally I think longer lines which don't break up the arguments (or
local variables again) would make this easier to read.

Cheers,
-Brian

> }
>-- 
>2.18.0
>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v5 5/9] drm: Extend framebuffer_check to handle formats with cpp/char_per_block 0
  2018-10-19 10:57 ` [PATCH v5 5/9] drm: Extend framebuffer_check to handle formats with cpp/char_per_block 0 Alexandru Gheorghe
@ 2018-10-19 13:21   ` Brian Starkey
  2018-10-22 10:09     ` Alexandru-Cosmin Gheorghe
  0 siblings, 1 reply; 24+ messages in thread
From: Brian Starkey @ 2018-10-19 13:21 UTC (permalink / raw)
  To: Alexandru Gheorghe
  Cc: charles.xu, nd, matt.szczesiak, airlied, liviu.dudau, dri-devel,
	maxime.ripard, david.garbett, seanpaul, lisa.wu, daniel.vetter,
	malidp, ayan.halder, james.qian.wang

Hi Alex,

On Fri, Oct 19, 2018 at 11:57:48AM +0100, Alexandru Gheorghe wrote:
>For formats that are supported only with non-linear modifiers it
>doesn't make to much sense to define cpp or char_per_block, so that
>will be set to 0.
>
>This patch adds a restriction to force having a modifier attached when
>cpp/char_per_block is 0, and to bypass checking the pitch restriction.
>
>This had been discussed here.
>[1] https://people.freedesktop.org/~cbrill/dri-log/?channel=dri-devel&highlight_names=&date=2018-09-13&show_html=true
>
>Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>
>---
> drivers/gpu/drm/drm_framebuffer.c | 7 ++++++-
> 1 file changed, 6 insertions(+), 1 deletion(-)
>
>diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
>index 6aca8a1ccdb6..e346d0ad92e0 100644
>--- a/drivers/gpu/drm/drm_framebuffer.c
>+++ b/drivers/gpu/drm/drm_framebuffer.c
>@@ -195,8 +195,13 @@ static int framebuffer_check(struct drm_device *dev,
> 	for (i = 0; i < info->num_planes; i++) {
> 		unsigned int width = fb_plane_width(r->width, info, i);
> 		unsigned int height = fb_plane_height(r->height, info, i);
>+		unsigned int block_size = info->char_per_block[i];
> 		u64 min_pitch = drm_format_info_min_pitch(info, i, width);
>
>+		if (!block_size && (r->modifier[i] == DRM_FORMAT_MOD_LINEAR)) {
>+			DRM_DEBUG_KMS("Format requires non-linear modifier for plane %d\n", i);
>+			return -EINVAL;
>+		}

You could probably move that blank like from Patch 2 to here ;-)
Otherwise LGTM:

Reviewed By: Brian Starkey <brian.starkey@arm.com>

> 		if (!r->handles[i]) {
> 			DRM_DEBUG_KMS("no buffer object handle for plane %d\n", i);
> 			return -EINVAL;
>@@ -208,7 +213,7 @@ static int framebuffer_check(struct drm_device *dev,
> 		if ((uint64_t) height * r->pitches[i] + r->offsets[i] > UINT_MAX)
> 			return -ERANGE;
>
>-		if (r->pitches[i] < min_pitch) {
>+		if (block_size && r->pitches[i] < min_pitch) {
> 			DRM_DEBUG_KMS("bad pitch %u for plane %d\n", r->pitches[i], i);
> 			return -EINVAL;
> 		}
>-- 
>2.18.0
>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v5 8/9] drm/selftest: Refactor test-drm_plane_helper
  2018-10-19 10:57 ` [PATCH v5 8/9] drm/selftest: Refactor test-drm_plane_helper Alexandru Gheorghe
@ 2018-10-19 15:14   ` Daniel Vetter
  2018-10-22  9:40     ` Alexandru-Cosmin Gheorghe
  0 siblings, 1 reply; 24+ messages in thread
From: Daniel Vetter @ 2018-10-19 15:14 UTC (permalink / raw)
  To: Alexandru Gheorghe
  Cc: charles.xu, nd, matt.szczesiak, airlied, liviu.dudau, dri-devel,
	maxime.ripard, david.garbett, seanpaul, lisa.wu, daniel.vetter,
	malidp, ayan.halder, james.qian.wang

On Fri, Oct 19, 2018 at 11:57:51AM +0100, Alexandru Gheorghe wrote:
> The idea is to split test implementations in different compilation
> units, but have one single place where we define the list of tests,
> in this case(drm_modeset_selftests.h).
> 
> Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>
> ---
>  ...er_selftests.h => drm_modeset_selftests.h} |  0
>  .../drm/selftests/test-drm_modeset_common.c   | 11 ++++++++++-
>  .../drm/selftests/test-drm_modeset_common.h   |  2 +-
>  .../gpu/drm/selftests/test-drm_plane_helper.c | 19 +------------------
>  4 files changed, 12 insertions(+), 20 deletions(-)
>  rename drivers/gpu/drm/selftests/{drm_plane_helper_selftests.h => drm_modeset_selftests.h} (100%)
> 
> diff --git a/drivers/gpu/drm/selftests/drm_plane_helper_selftests.h b/drivers/gpu/drm/selftests/drm_modeset_selftests.h
> similarity index 100%
> rename from drivers/gpu/drm/selftests/drm_plane_helper_selftests.h
> rename to drivers/gpu/drm/selftests/drm_modeset_selftests.h
> diff --git a/drivers/gpu/drm/selftests/test-drm_modeset_common.c b/drivers/gpu/drm/selftests/test-drm_modeset_common.c
> index fad5209043f1..2a7f93774006 100644
> --- a/drivers/gpu/drm/selftests/test-drm_modeset_common.c
> +++ b/drivers/gpu/drm/selftests/test-drm_modeset_common.c
> @@ -7,9 +7,18 @@
>  
>  #include "test-drm_modeset_common.h"
>  
> +#define TESTS "drm_modeset_selftests.h"
> +#include "drm_selftest.h"
> +
> +#include "drm_selftest.c"
> +
>  static int __init test_drm_modeset_init(void)
>  {
> -	return test_drm_plane_helper();
> +	int err;
> +
> +	err = run_selftests(selftests, ARRAY_SIZE(selftests), NULL);
> +
> +	return err > 0 ? 0 : err;
>  }
>  
>  static void __exit test_drm_modeset_exit(void)
> diff --git a/drivers/gpu/drm/selftests/test-drm_modeset_common.h b/drivers/gpu/drm/selftests/test-drm_modeset_common.h
> index bdeba264661f..b0065a2eb067 100644
> --- a/drivers/gpu/drm/selftests/test-drm_modeset_common.h
> +++ b/drivers/gpu/drm/selftests/test-drm_modeset_common.h
> @@ -13,6 +13,6 @@
>  
>  #define FAIL_ON(x) FAIL((x), "%s", "FAIL_ON(" __stringify(x) ")\n")
>  
> -int test_drm_plane_helper(void);
> +int igt_check_plane_state(void *ignored);

I wonder whether we can't do some macro trickery to also generate these
here from the selftest.h file. But that's probably for when we're drowning
in these, which we're definitely not yet :-)

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

>  
>  #endif
> diff --git a/drivers/gpu/drm/selftests/test-drm_plane_helper.c b/drivers/gpu/drm/selftests/test-drm_plane_helper.c
> index 0dad2f812a27..0a9553f51796 100644
> --- a/drivers/gpu/drm/selftests/test-drm_plane_helper.c
> +++ b/drivers/gpu/drm/selftests/test-drm_plane_helper.c
> @@ -11,9 +11,6 @@
>  
>  #include "test-drm_modeset_common.h"
>  
> -#define TESTS "drm_plane_helper_selftests.h"
> -#include "drm_selftest.h"
> -
>  static void set_src(struct drm_plane_state *plane_state,
>  		    unsigned src_x, unsigned src_y,
>  		    unsigned src_w, unsigned src_h)
> @@ -76,7 +73,7 @@ static bool check_crtc_eq(struct drm_plane_state *plane_state,
>  	return true;
>  }
>  
> -static int igt_check_plane_state(void *ignored)
> +int igt_check_plane_state(void *ignored)

>  {
>  	int ret;
>  
> @@ -220,17 +217,3 @@ static int igt_check_plane_state(void *ignored)
>  
>  	return 0;
>  }
> -
> -#include "drm_selftest.c"
> -
> -/**
> - * test_drm_plane_helper - Run drm plane helper selftests.
> - */
> -int test_drm_plane_helper(void)
> -{
> -	int err;
> -
> -	err = run_selftests(selftests, ARRAY_SIZE(selftests), NULL);
> -
> -	return err > 0 ? 0 : err;
> -}
> -- 
> 2.18.0
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v5 9/9] drm/selftests: Add tests for drm_format_info* helpers
  2018-10-19 10:57 ` [PATCH v5 9/9] drm/selftests: Add tests for drm_format_info* helpers Alexandru Gheorghe
@ 2018-10-19 15:29   ` Daniel Vetter
  2018-10-22 10:32     ` Alexandru-Cosmin Gheorghe
  0 siblings, 1 reply; 24+ messages in thread
From: Daniel Vetter @ 2018-10-19 15:29 UTC (permalink / raw)
  To: Alexandru Gheorghe
  Cc: charles.xu, nd, matt.szczesiak, airlied, liviu.dudau, dri-devel,
	maxime.ripard, david.garbett, seanpaul, lisa.wu, daniel.vetter,
	malidp, ayan.halder, james.qian.wang

On Fri, Oct 19, 2018 at 11:57:52AM +0100, Alexandru Gheorghe wrote:
> Add selftests for the following newly added functions:
>  - drm_format_info_block_width
>  - drm_format_info_block_height
>  - drm_format_info_min_pitch
> 
> Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>
> ---
>  drivers/gpu/drm/selftests/Makefile            |   3 +-
>  .../gpu/drm/selftests/drm_modeset_selftests.h |   3 +
>  drivers/gpu/drm/selftests/test-drm_format.c   | 290 ++++++++++++++++++
>  .../drm/selftests/test-drm_modeset_common.h   |   3 +
>  4 files changed, 298 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/selftests/test-drm_format.c
> 
> diff --git a/drivers/gpu/drm/selftests/Makefile b/drivers/gpu/drm/selftests/Makefile
> index 7e6581921da0..07b4f88b422a 100644
> --- a/drivers/gpu/drm/selftests/Makefile
> +++ b/drivers/gpu/drm/selftests/Makefile
> @@ -1,3 +1,4 @@
> -test-drm_modeset-y := test-drm_modeset_common.o test-drm_plane_helper.o
> +test-drm_modeset-y := test-drm_modeset_common.o test-drm_plane_helper.o \
> +                      test-drm_format.o
>  
>  obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_modeset.o
> diff --git a/drivers/gpu/drm/selftests/drm_modeset_selftests.h b/drivers/gpu/drm/selftests/drm_modeset_selftests.h
> index 9771290ed228..4e203ac8c134 100644
> --- a/drivers/gpu/drm/selftests/drm_modeset_selftests.h
> +++ b/drivers/gpu/drm/selftests/drm_modeset_selftests.h
> @@ -7,3 +7,6 @@
>   * Tests are executed in order by igt/drm_selftests_helper
>   */
>  selftest(check_plane_state, igt_check_plane_state)
> +selftest(check_drm_format_block_width, igt_check_drm_format_block_width)
> +selftest(check_drm_format_block_height, igt_check_drm_format_block_height)
> +selftest(check_drm_format_min_pitch, igt_check_drm_format_min_pitch)
> diff --git a/drivers/gpu/drm/selftests/test-drm_format.c b/drivers/gpu/drm/selftests/test-drm_format.c
> new file mode 100644
> index 000000000000..5abfd5e28d7d
> --- /dev/null
> +++ b/drivers/gpu/drm/selftests/test-drm_format.c
> @@ -0,0 +1,290 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Test cases for the drm_format functions
> + */
> +
> +#define pr_fmt(fmt) "drm_format: " fmt
> +
> +#include <linux/errno.h>
> +#include <linux/kernel.h>
> +
> +#include <drm/drm_fourcc.h>
> +
> +#include "test-drm_modeset_common.h"
> +
> +int igt_check_drm_format_block_width(void *ignored)
> +{
> +	const struct drm_format_info *info = NULL;
> +
> +	/* Test invalid arguments */
> +	FAIL_ON(drm_format_info_block_width(info, 0) != 0);
> +	FAIL_ON(drm_format_info_block_width(info, -1) != 0);
> +	FAIL_ON(drm_format_info_block_width(info, 1) != 0);
> +
> +	/* Test 1 plane format */
> +	info = drm_format_info(DRM_FORMAT_XRGB4444);
> +	FAIL_ON(!info);
> +	FAIL_ON(drm_format_info_block_width(info, 0) != 1);
> +	FAIL_ON(drm_format_info_block_width(info, 1) != 0);
> +	FAIL_ON(drm_format_info_block_width(info, -1) != 0);
> +
> +	/* Test 2 planes format */
> +	info = drm_format_info(DRM_FORMAT_NV12);
> +	FAIL_ON(!info);
> +	FAIL_ON(drm_format_info_block_width(info, 0) != 1);
> +	FAIL_ON(drm_format_info_block_width(info, 1) != 1);
> +	FAIL_ON(drm_format_info_block_width(info, 2) != 0);
> +	FAIL_ON(drm_format_info_block_width(info, -1) != 0);
> +
> +	/* Test 3 planes format */
> +	info = drm_format_info(DRM_FORMAT_YUV422);
> +	FAIL_ON(!info);
> +	FAIL_ON(drm_format_info_block_width(info, 0) != 1);
> +	FAIL_ON(drm_format_info_block_width(info, 1) != 1);
> +	FAIL_ON(drm_format_info_block_width(info, 2) != 1);
> +	FAIL_ON(drm_format_info_block_width(info, 3) != 0);
> +	FAIL_ON(drm_format_info_block_width(info, -1) != 0);
> +
> +	/* Test a tiled format */
> +	info = drm_format_info(DRM_FORMAT_X0L0);
> +	FAIL_ON(!info);
> +	FAIL_ON(drm_format_info_block_width(info, 0) != 2);
> +	FAIL_ON(drm_format_info_block_width(info, 1) != 0);
> +	FAIL_ON(drm_format_info_block_width(info, -1) != 0);
> +
> +	return 0;
> +}
> +
> +int igt_check_drm_format_block_height(void *ignored)
> +{
> +	const struct drm_format_info *info = NULL;
> +
> +	/* Test invalid arguments */
> +	FAIL_ON(drm_format_info_block_height(info, 0) != 0);
> +	FAIL_ON(drm_format_info_block_height(info, -1) != 0);
> +	FAIL_ON(drm_format_info_block_height(info, 1) != 0);
> +
> +	/* Test 1 plane format */
> +	info = drm_format_info(DRM_FORMAT_XRGB4444);
> +	FAIL_ON(!info);
> +	FAIL_ON(drm_format_info_block_height(info, 0) != 1);
> +	FAIL_ON(drm_format_info_block_height(info, 1) != 0);
> +	FAIL_ON(drm_format_info_block_height(info, -1) != 0);
> +
> +	/* Test 2 planes format */
> +	info = drm_format_info(DRM_FORMAT_NV12);
> +	FAIL_ON(!info);
> +	FAIL_ON(drm_format_info_block_height(info, 0) != 1);
> +	FAIL_ON(drm_format_info_block_height(info, 1) != 1);
> +	FAIL_ON(drm_format_info_block_height(info, 2) != 0);
> +	FAIL_ON(drm_format_info_block_height(info, -1) != 0);
> +
> +	/* Test 3 planes format */
> +	info = drm_format_info(DRM_FORMAT_YUV422);
> +	FAIL_ON(!info);
> +	FAIL_ON(drm_format_info_block_height(info, 0) != 1);
> +	FAIL_ON(drm_format_info_block_height(info, 1) != 1);
> +	FAIL_ON(drm_format_info_block_height(info, 2) != 1);
> +	FAIL_ON(drm_format_info_block_height(info, 3) != 0);
> +	FAIL_ON(drm_format_info_block_height(info, -1) != 0);
> +
> +	/* Test a tiled format */
> +	info = drm_format_info(DRM_FORMAT_X0L0);
> +	FAIL_ON(!info);
> +	FAIL_ON(drm_format_info_block_height(info, 0) != 2);
> +	FAIL_ON(drm_format_info_block_height(info, 1) != 0);
> +	FAIL_ON(drm_format_info_block_height(info, -1) != 0);
> +
> +	return 0;
> +}
> +
> +int igt_check_drm_format_min_pitch(void *ignored)
> +{
> +	const struct drm_format_info *info = NULL;
> +
> +	/* Test invalid arguments */
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
> +	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
> +	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
> +
> +	/* Test 1 plane 8 bits per pixel format */
> +	info = drm_format_info(DRM_FORMAT_RGB332);
> +	FAIL_ON(!info);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
> +	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
> +	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
> +
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 1);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 2);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 640);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 1024);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 1920);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 4096);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 671);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
> +			(uint64_t)UINT_MAX);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, (UINT_MAX - 1)) !=
> +			(uint64_t)(UINT_MAX - 1));
> +
> +	/* Test 1 plane 16 bits per pixel format */
> +	info = drm_format_info(DRM_FORMAT_XRGB4444);
> +	FAIL_ON(!info);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
> +	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
> +	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
> +
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 2);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 4);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 1280);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 2048);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 3840);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 8192);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 1342);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
> +			(uint64_t)UINT_MAX * 2);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, (UINT_MAX - 1)) !=
> +			(uint64_t)(UINT_MAX - 1) * 2);
> +
> +	/* Test 1 plane 24 bits per pixel format */
> +	info = drm_format_info(DRM_FORMAT_RGB888);
> +	FAIL_ON(!info);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
> +	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
> +	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
> +
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 3);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 6);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 1920);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 3072);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 5760);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 12288);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 2013);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
> +			(uint64_t)UINT_MAX * 3);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX - 1) !=
> +			(uint64_t)(UINT_MAX - 1) * 3);
> +
> +	/* Test 1 plane 32 bits per pixel format */
> +	info = drm_format_info(DRM_FORMAT_ABGR8888);
> +	FAIL_ON(!info);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
> +	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
> +	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
> +
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 4);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 8);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 2560);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 4096);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 7680);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 16384);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 2684);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
> +			(uint64_t)UINT_MAX * 4);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX - 1) !=
> +			(uint64_t)(UINT_MAX - 1) * 4);
> +
> +	/* Test 2 planes format */
> +	info = drm_format_info(DRM_FORMAT_NV12);
> +	FAIL_ON(!info);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
> +	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
> +	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
> +	FAIL_ON(drm_format_info_min_pitch(info, 2, 0) != 0);
> +
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 1);
> +	FAIL_ON(drm_format_info_min_pitch(info, 1, 1) != 2);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 2);
> +	FAIL_ON(drm_format_info_min_pitch(info, 1, 1) != 2);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 640);
> +	FAIL_ON(drm_format_info_min_pitch(info, 1, 320) != 640);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 1024);
> +	FAIL_ON(drm_format_info_min_pitch(info, 1, 512) != 1024);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 1920);
> +	FAIL_ON(drm_format_info_min_pitch(info, 1, 960) != 1920);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 4096);
> +	FAIL_ON(drm_format_info_min_pitch(info, 1, 2048) != 4096);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 671);
> +	FAIL_ON(drm_format_info_min_pitch(info, 1, 336) != 672);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
> +			(uint64_t)UINT_MAX);
> +	FAIL_ON(drm_format_info_min_pitch(info, 1, UINT_MAX / 2 + 1) !=
> +			(uint64_t)UINT_MAX + 1);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, (UINT_MAX - 1)) !=
> +			(uint64_t)(UINT_MAX - 1));
> +	FAIL_ON(drm_format_info_min_pitch(info, 1, (UINT_MAX - 1) /  2) !=
> +			(uint64_t)(UINT_MAX - 1));
> +
> +	/* Test 3 planes 8 bits per pixel format */
> +	info = drm_format_info(DRM_FORMAT_YUV422);
> +	FAIL_ON(!info);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
> +	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
> +	FAIL_ON(drm_format_info_min_pitch(info, 2, 0) != 0);
> +	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
> +	FAIL_ON(drm_format_info_min_pitch(info, 3, 0) != 0);
> +
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 1);
> +	FAIL_ON(drm_format_info_min_pitch(info, 1, 1) != 1);
> +	FAIL_ON(drm_format_info_min_pitch(info, 2, 1) != 1);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 2);
> +	FAIL_ON(drm_format_info_min_pitch(info, 1, 2) != 2);
> +	FAIL_ON(drm_format_info_min_pitch(info, 2, 2) != 2);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 640);
> +	FAIL_ON(drm_format_info_min_pitch(info, 1, 320) != 320);
> +	FAIL_ON(drm_format_info_min_pitch(info, 2, 320) != 320);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 1024);
> +	FAIL_ON(drm_format_info_min_pitch(info, 1, 512) != 512);
> +	FAIL_ON(drm_format_info_min_pitch(info, 2, 512) != 512);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 1920);
> +	FAIL_ON(drm_format_info_min_pitch(info, 1, 960) != 960);
> +	FAIL_ON(drm_format_info_min_pitch(info, 2, 960) != 960);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 4096);
> +	FAIL_ON(drm_format_info_min_pitch(info, 1, 2048) != 2048);
> +	FAIL_ON(drm_format_info_min_pitch(info, 2, 2048) != 2048);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 671);
> +	FAIL_ON(drm_format_info_min_pitch(info, 1, 336) != 336);
> +	FAIL_ON(drm_format_info_min_pitch(info, 2, 336) != 336);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
> +			(uint64_t)UINT_MAX);
> +	FAIL_ON(drm_format_info_min_pitch(info, 1, UINT_MAX / 2 + 1) !=
> +			(uint64_t)UINT_MAX / 2 + 1);
> +	FAIL_ON(drm_format_info_min_pitch(info, 2, UINT_MAX / 2 + 1) !=
> +			(uint64_t)UINT_MAX / 2 + 1);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, (UINT_MAX - 1) / 2) !=
> +			(uint64_t)(UINT_MAX - 1) / 2);
> +	FAIL_ON(drm_format_info_min_pitch(info, 1, (UINT_MAX - 1) / 2) !=
> +			(uint64_t)(UINT_MAX - 1) / 2);
> +	FAIL_ON(drm_format_info_min_pitch(info, 2, (UINT_MAX - 1) / 2) !=
> +			(uint64_t)(UINT_MAX - 1) / 2);
> +
> +	/* Test tiled format */
> +	info = drm_format_info(DRM_FORMAT_X0L2);
> +	FAIL_ON(!info);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
> +	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
> +	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
> +
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 2);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 4);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 1280);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 2048);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 3840);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 8192);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 1342);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
> +			(uint64_t)UINT_MAX * 2);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX - 1) !=
> +			(uint64_t)(UINT_MAX - 1) * 2);
> +
> +	/* Test format with cpp/char_per_block 0 */
> +	info = drm_format_info(DRM_FORMAT_VUY101010);
> +	FAIL_ON(!info);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
> +	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
> +	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
> +
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 0);
> +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) != 0);
> +
> +	return 0;
> +}

Comprehensive, but also fairly boring. Anyway, it's a start, so:

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

What I had in mind is maybe not quite so low-level unit testing, but
exercising the entire framebuffer_create machinery. The recently
drm_client_framebuffer_create essentially gives you that interface for
modules (but I guess we could also EXPORT_SYMBOL_FOR_TESTS_ONLY,
conditional on drm selftests being enabled, directly on
drm_internal_framebuffer_create).

This needs some fairly minimal mocking of a drm_device with a bunch of
dummy functions (throw them into test-drm_modeset_common.c if you feel
like). Then go through a pile of valid and invalid combinations and make
sure your ->fb_create driver callback is only called when when it should
be (and not for anything invalid). I think that would yield the much more
interesting testing ...

That will also pave the ground for some rather more serious addfb testing
in the future. And eventually even more serious testing on e.g. atomic
helpers.

Anyway, if you feel like, would be awesome to follow up a bit in that
direction.

Cheers, Daniel

> diff --git a/drivers/gpu/drm/selftests/test-drm_modeset_common.h b/drivers/gpu/drm/selftests/test-drm_modeset_common.h
> index b0065a2eb067..592a6581b189 100644
> --- a/drivers/gpu/drm/selftests/test-drm_modeset_common.h
> +++ b/drivers/gpu/drm/selftests/test-drm_modeset_common.h
> @@ -14,5 +14,8 @@
>  #define FAIL_ON(x) FAIL((x), "%s", "FAIL_ON(" __stringify(x) ")\n")
>  
>  int igt_check_plane_state(void *ignored);
> +int igt_check_drm_format_block_width(void *ignored);
> +int igt_check_drm_format_block_height(void *ignored);
> +int igt_check_drm_format_min_pitch(void *ignored);
>  
>  #endif
> -- 
> 2.18.0
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v5 1/9] drm: fourcc: Convert drm_format_info kerneldoc to in-line member documentation
  2018-10-19 12:54   ` Maxime Ripard
@ 2018-10-22  9:36     ` Alexandru-Cosmin Gheorghe
  0 siblings, 0 replies; 24+ messages in thread
From: Alexandru-Cosmin Gheorghe @ 2018-10-22  9:36 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: charles.xu, nd, matt.szczesiak, airlied, liviu.dudau, dri-devel,
	david.garbett, seanpaul, lisa.wu, daniel.vetter, malidp,
	ayan.halder, james.qian.wang

Hi Maxime,

Thanks for the review, pushed the patch to drm-misc-next.

On Fri, Oct 19, 2018 at 02:54:18PM +0200, Maxime Ripard wrote:
> On Fri, Oct 19, 2018 at 11:57:44AM +0100, Alexandru Gheorghe wrote:
> > In-line member documentation seems to be desired way of documenting
> > structure members.
> > 
> > This change had been suggested by Daniel Vetter here:
> > https://lists.freedesktop.org/archives/dri-devel/2018-October/192176.html
> > 
> > Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>
> 
> Reviewed-by: Maxime Ripard <maxime.ripard@bootlin.com>
> 
> Thanks!
> Maxime
> 
> -- 
> Maxime Ripard, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com

-- 
Cheers,
Alex G
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v5 8/9] drm/selftest: Refactor test-drm_plane_helper
  2018-10-19 15:14   ` Daniel Vetter
@ 2018-10-22  9:40     ` Alexandru-Cosmin Gheorghe
  0 siblings, 0 replies; 24+ messages in thread
From: Alexandru-Cosmin Gheorghe @ 2018-10-22  9:40 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: charles.xu, nd, matt.szczesiak, airlied, liviu.dudau, dri-devel,
	maxime.ripard, david.garbett, seanpaul, lisa.wu, daniel.vetter,
	malidp, ayan.halder, james.qian.wang

Hi Daniel,

On Fri, Oct 19, 2018 at 05:14:51PM +0200, Daniel Vetter wrote:
> On Fri, Oct 19, 2018 at 11:57:51AM +0100, Alexandru Gheorghe wrote:
> > The idea is to split test implementations in different compilation
> > units, but have one single place where we define the list of tests,
> > in this case(drm_modeset_selftests.h).
> > 
> > Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>
> > ---
> >  ...er_selftests.h => drm_modeset_selftests.h} |  0
> >  .../drm/selftests/test-drm_modeset_common.c   | 11 ++++++++++-
> >  .../drm/selftests/test-drm_modeset_common.h   |  2 +-
> >  .../gpu/drm/selftests/test-drm_plane_helper.c | 19 +------------------
> >  4 files changed, 12 insertions(+), 20 deletions(-)
> >  rename drivers/gpu/drm/selftests/{drm_plane_helper_selftests.h => drm_modeset_selftests.h} (100%)
> > 
> > diff --git a/drivers/gpu/drm/selftests/drm_plane_helper_selftests.h b/drivers/gpu/drm/selftests/drm_modeset_selftests.h
> > similarity index 100%
> > rename from drivers/gpu/drm/selftests/drm_plane_helper_selftests.h
> > rename to drivers/gpu/drm/selftests/drm_modeset_selftests.h
> > diff --git a/drivers/gpu/drm/selftests/test-drm_modeset_common.c b/drivers/gpu/drm/selftests/test-drm_modeset_common.c
> > index fad5209043f1..2a7f93774006 100644
> > --- a/drivers/gpu/drm/selftests/test-drm_modeset_common.c
> > +++ b/drivers/gpu/drm/selftests/test-drm_modeset_common.c
> > @@ -7,9 +7,18 @@
> >  
> >  #include "test-drm_modeset_common.h"
> >  
> > +#define TESTS "drm_modeset_selftests.h"
> > +#include "drm_selftest.h"
> > +
> > +#include "drm_selftest.c"
> > +
> >  static int __init test_drm_modeset_init(void)
> >  {
> > -	return test_drm_plane_helper();
> > +	int err;
> > +
> > +	err = run_selftests(selftests, ARRAY_SIZE(selftests), NULL);
> > +
> > +	return err > 0 ? 0 : err;
> >  }
> >  
> >  static void __exit test_drm_modeset_exit(void)
> > diff --git a/drivers/gpu/drm/selftests/test-drm_modeset_common.h b/drivers/gpu/drm/selftests/test-drm_modeset_common.h
> > index bdeba264661f..b0065a2eb067 100644
> > --- a/drivers/gpu/drm/selftests/test-drm_modeset_common.h
> > +++ b/drivers/gpu/drm/selftests/test-drm_modeset_common.h
> > @@ -13,6 +13,6 @@
> >  
> >  #define FAIL_ON(x) FAIL((x), "%s", "FAIL_ON(" __stringify(x) ")\n")
> >  
> > -int test_drm_plane_helper(void);
> > +int igt_check_plane_state(void *ignored);
> 
> I wonder whether we can't do some macro trickery to also generate these
> here from the selftest.h file. But that's probably for when we're drowning
> in these, which we're definitely not yet :-)

I agree.

> 
> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

Pushed the patch to drm-misc-next. 
Thanks for the review.

> 
> >  
> >  #endif
> > diff --git a/drivers/gpu/drm/selftests/test-drm_plane_helper.c b/drivers/gpu/drm/selftests/test-drm_plane_helper.c
> > index 0dad2f812a27..0a9553f51796 100644
> > --- a/drivers/gpu/drm/selftests/test-drm_plane_helper.c
> > +++ b/drivers/gpu/drm/selftests/test-drm_plane_helper.c
> > @@ -11,9 +11,6 @@
> >  
> >  #include "test-drm_modeset_common.h"
> >  
> > -#define TESTS "drm_plane_helper_selftests.h"
> > -#include "drm_selftest.h"
> > -
> >  static void set_src(struct drm_plane_state *plane_state,
> >  		    unsigned src_x, unsigned src_y,
> >  		    unsigned src_w, unsigned src_h)
> > @@ -76,7 +73,7 @@ static bool check_crtc_eq(struct drm_plane_state *plane_state,
> >  	return true;
> >  }
> >  
> > -static int igt_check_plane_state(void *ignored)
> > +int igt_check_plane_state(void *ignored)
> 
> >  {
> >  	int ret;
> >  
> > @@ -220,17 +217,3 @@ static int igt_check_plane_state(void *ignored)
> >  
> >  	return 0;
> >  }
> > -
> > -#include "drm_selftest.c"
> > -
> > -/**
> > - * test_drm_plane_helper - Run drm plane helper selftests.
> > - */
> > -int test_drm_plane_helper(void)
> > -{
> > -	int err;
> > -
> > -	err = run_selftests(selftests, ARRAY_SIZE(selftests), NULL);
> > -
> > -	return err > 0 ? 0 : err;
> > -}
> > -- 
> > 2.18.0
> > 
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

-- 
Cheers,
Alex G
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v5 2/9] drm/fourcc: Add char_per_block, block_w and block_h in drm_format_info
  2018-10-19 13:09   ` Brian Starkey
@ 2018-10-22 10:07     ` Alexandru-Cosmin Gheorghe
  0 siblings, 0 replies; 24+ messages in thread
From: Alexandru-Cosmin Gheorghe @ 2018-10-22 10:07 UTC (permalink / raw)
  To: Brian Starkey
  Cc: charles.xu, nd, matt.szczesiak, airlied, liviu.dudau, dri-devel,
	maxime.ripard, david.garbett, seanpaul, lisa.wu, daniel.vetter,
	malidp, ayan.halder, james.qian.wang

On Fri, Oct 19, 2018 at 02:09:38PM +0100, Brian Starkey wrote:
> Hi Alex,
> 
> On Fri, Oct 19, 2018 at 11:57:45AM +0100, Alexandru Gheorghe wrote:
> >For some pixel formats .cpp structure in drm_format info it's not
> >enough to describe the peculiarities of the pixel layout, for example
> >tiled formats or packed formats at bit level.
> >
> >What's implemented here is to add three new members to drm_format_info
> >that could describe such formats:
> >
> >- char_per_block[3]
> >- block_w[3]
> >- block_h[3]
> >
> >char_per_block will be put in a union alongside cpp, for transparent
> >compatibility  with the existing format descriptions.
> >
> >Regarding, block_w and block_h they are intended to be used through
> >their equivalent getters drm_format_info_block_width /
> >drm_format_info_block_height, the reason of the getters is to abstract
> >the fact that for normal formats block_w and block_h will be unset/0,
> >but the methods will be returning 1.
> >
> >Additionally, convenience function drm_format_info_min_pitch had been
> >added that computes the minimum required pitch for a given pixel
> >format and buffer width.
> >
> >Using that the following drm core functions had been updated to
> >generically handle both block and non-block formats:
> >
> >- drm_fb_cma_get_gem_addr: for block formats it will just return the
> > beginning of the block.
> >- framebuffer_check: Use the newly added drm_format_info_min_pitch.
> >- drm_gem_fb_create_with_funcs: Use the newly added
> > drm_format_info_min_pitch.
> >- In places where is not expecting to handle block formats, like fbdev
> > helpers I just added some warnings in case the block width/height
> > are greater than 1.
> >
> >Changes since v3:
> >- Add helper function for computing the minimum required pitch.
> >- Improve/cleanup documentation
> >
> >Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>
> 
> I commented on a couple of tiny typographical things below, but
> otherwise this looks good to me. Thanks!
> 
> Reviewed-by: Brian Starkey <brian.starkey@arm.com>
> 
> >---
> >drivers/gpu/drm/drm_fb_cma_helper.c          | 21 ++++++-
> >drivers/gpu/drm/drm_fb_helper.c              |  6 ++
> >drivers/gpu/drm/drm_fourcc.c                 | 62 ++++++++++++++++++++
> >drivers/gpu/drm/drm_framebuffer.c            |  6 +-
> >drivers/gpu/drm/drm_gem_framebuffer_helper.c |  2 +-
> >include/drm/drm_fourcc.h                     | 61 ++++++++++++++++++-
> >6 files changed, 149 insertions(+), 9 deletions(-)
> >
> >diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c
> >index d52344a03aa8..83941a8ca0e0 100644
> >--- a/drivers/gpu/drm/drm_fb_cma_helper.c
> >+++ b/drivers/gpu/drm/drm_fb_cma_helper.c
> >@@ -72,7 +72,9 @@ struct drm_gem_cma_object *drm_fb_cma_get_gem_obj(struct drm_framebuffer *fb,
> >EXPORT_SYMBOL_GPL(drm_fb_cma_get_gem_obj);
> >
> >/**
> >- * drm_fb_cma_get_gem_addr() - Get physical address for framebuffer
> >+ * drm_fb_cma_get_gem_addr() - Get physical address for framebuffer, for pixel
> >+ * formats where values are grouped in blocks this will get you the beginning of
> >+ * the block
> > * @fb: The framebuffer
> > * @state: Which state of drm plane
> > * @plane: Which plane
> >@@ -87,6 +89,14 @@ dma_addr_t drm_fb_cma_get_gem_addr(struct drm_framebuffer *fb,
> >	struct drm_gem_cma_object *obj;
> >	dma_addr_t paddr;
> >	u8 h_div = 1, v_div = 1;
> >+	u32 block_w = drm_format_info_block_width(fb->format, plane);
> >+	u32 block_h = drm_format_info_block_height(fb->format, plane);
> >+	u32 block_size = fb->format->char_per_block[plane];
> >+	u32 sample_x;
> >+	u32 sample_y;
> >+	u32 block_start_y;
> >+	u32 num_hblocks;
> >+
> 
> nit: extra newline
> 
> >
> >	obj = drm_fb_cma_get_gem_obj(fb, plane);
> >	if (!obj)
> >@@ -99,8 +109,13 @@ dma_addr_t drm_fb_cma_get_gem_addr(struct drm_framebuffer *fb,
> >		v_div = fb->format->vsub;
> >	}
> >
> >-	paddr += (fb->format->cpp[plane] * (state->src_x >> 16)) / h_div;
> >-	paddr += (fb->pitches[plane] * (state->src_y >> 16)) / v_div;
> >+	sample_x = (state->src_x >> 16) / h_div;
> >+	sample_y = (state->src_y >> 16) / v_div;
> >+	block_start_y = (sample_y / block_h) * block_h;
> >+	num_hblocks = sample_x / block_w;
> >+
> >+	paddr += fb->pitches[plane] * block_start_y;
> >+	paddr += block_size * num_hblocks;
> >
> >	return paddr;
> >}
> >diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
> >index a504a5e05676..9add0d7da744 100644
> >--- a/drivers/gpu/drm/drm_fb_helper.c
> >+++ b/drivers/gpu/drm/drm_fb_helper.c
> >@@ -1595,6 +1595,10 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
> >	if (var->pixclock != 0 || in_dbg_master())
> >		return -EINVAL;
> >
> >+	if ((drm_format_info_block_width(fb->format, 0) > 1) ||
> >+	    (drm_format_info_block_height(fb->format, 0) > 1))
> >+		return -EINVAL;
> >+
> >	/*
> >	 * Changes struct fb_var_screeninfo are currently not pushed back
> >	 * to KMS, hence fail if different settings are requested.
> >@@ -1969,6 +1973,8 @@ void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helpe
> >{
> >	struct drm_framebuffer *fb = fb_helper->fb;
> >
> >+	WARN_ON((drm_format_info_block_width(fb->format, 0) > 1) ||
> >+		(drm_format_info_block_height(fb->format, 0) > 1));
> >	info->pseudo_palette = fb_helper->pseudo_palette;
> >	info->var.xres_virtual = fb->width;
> >	info->var.yres_virtual = fb->height;
> >diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
> >index e177f6d0d1f4..a843a5fc8dbf 100644
> >--- a/drivers/gpu/drm/drm_fourcc.c
> >+++ b/drivers/gpu/drm/drm_fourcc.c
> >@@ -403,3 +403,65 @@ int drm_format_plane_height(int height, uint32_t format, int plane)
> >	return height / info->vsub;
> >}
> >EXPORT_SYMBOL(drm_format_plane_height);
> >+
> >+/**
> >+ * drm_format_info_block_width - width in pixels of block.
> >+ * @info: pixel format info
> >+ * @plane: plane index
> >+ *
> >+ * Returns:
> >+ * The width in pixels of a block, depending on the plane index.
> >+ */
> >+unsigned int drm_format_info_block_width(const struct drm_format_info *info,
> >+					 int plane)
> >+{
> >+	if (!info || plane < 0 || plane >= info->num_planes)
> >+		return 0;
> 
> Thinking aloud: The other helpers don't check < 0, but it looks to me
> that it would make sense (someday...) to change all of the 'plane'
> arguments to 'unsigned int' so that there's no possibility of < 0.

The only reason is int it's for consistency with the others, and I
added <0, once I started unit testing it. 

> 
> >+
> >+	if (!info->block_w[plane])
> >+		return 1;
> >+	return info->block_w[plane];
> >+}
> >+EXPORT_SYMBOL(drm_format_info_block_width);
> >+
> >+/**
> >+ * drm_format_info_block_height - height in pixels of a block
> >+ * @info: pixel format info
> >+ * @plane: plane index
> >+ *
> >+ * Returns:
> >+ * The height in pixels of a block, depending on the plane index.
> >+ */
> >+unsigned int drm_format_info_block_height(const struct drm_format_info *info,
> >+					  int plane)
> >+{
> >+	if (!info || plane < 0 || plane >= info->num_planes)
> >+		return 0;
> >+
> >+	if (!info->block_h[plane])
> >+		return 1;
> >+	return info->block_h[plane];
> >+}
> >+EXPORT_SYMBOL(drm_format_info_block_height);
> >+
> >+/**
> >+ * drm_format_info_min_pitch - computes the minimum required pitch in bytes
> >+ * @info: pixel format info
> >+ * @plane: plane index
> >+ * @buffer_width: buffer width in pixels
> >+ *
> >+ * Returns:
> >+ * The minimum required pitch in bytes for a buffer by taking into consideration
> >+ * the pixel format information and the buffer width.
> >+ */
> >+uint64_t drm_format_info_min_pitch(const struct drm_format_info *info,
> >+				   int plane, unsigned int buffer_width)
> >+{
> >+	if (!info || plane < 0 || plane >= info->num_planes)
> >+		return 0;
> >+
> >+	return DIV_ROUND_UP((u64)buffer_width * info->char_per_block[plane],
> >+			    drm_format_info_block_width(info, plane) *
> >+			    drm_format_info_block_height(info, plane));
> >+}
> >+EXPORT_SYMBOL(drm_format_info_min_pitch);
> >diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
> >index 3bf729d0aae5..6aca8a1ccdb6 100644
> >--- a/drivers/gpu/drm/drm_framebuffer.c
> >+++ b/drivers/gpu/drm/drm_framebuffer.c
> >@@ -195,20 +195,20 @@ static int framebuffer_check(struct drm_device *dev,
> >	for (i = 0; i < info->num_planes; i++) {
> >		unsigned int width = fb_plane_width(r->width, info, i);
> >		unsigned int height = fb_plane_height(r->height, info, i);
> >-		unsigned int cpp = info->cpp[i];
> >+		u64 min_pitch = drm_format_info_min_pitch(info, i, width);
> >
> >		if (!r->handles[i]) {
> >			DRM_DEBUG_KMS("no buffer object handle for plane %d\n", i);
> >			return -EINVAL;
> >		}
> >
> >-		if ((uint64_t) width * cpp > UINT_MAX)
> >+		if (min_pitch > UINT_MAX)
> >			return -ERANGE;
> >
> >		if ((uint64_t) height * r->pitches[i] + r->offsets[i] > UINT_MAX)
> >			return -ERANGE;
> >
> >-		if (r->pitches[i] < width * cpp) {
> >+		if (r->pitches[i] < min_pitch) {
> >			DRM_DEBUG_KMS("bad pitch %u for plane %d\n", r->pitches[i], i);
> >			return -EINVAL;
> >		}
> >diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> >index ded7a379ac35..acb466d25afc 100644
> >--- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> >+++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> >@@ -171,7 +171,7 @@ drm_gem_fb_create_with_funcs(struct drm_device *dev, struct drm_file *file,
> >		}
> >
> >		min_size = (height - 1) * mode_cmd->pitches[i]
> >-			 + width * info->cpp[i]
> >+			 + drm_format_info_min_pitch(info, i, width)
> >			 + mode_cmd->offsets[i];
> >
> >		if (objs[i]->size < min_size) {
> >diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
> >index 345f11227e9e..253d4c07a10c 100644
> >--- a/include/drm/drm_fourcc.h
> >+++ b/include/drm/drm_fourcc.h
> >@@ -69,8 +69,59 @@ struct drm_format_info {
> >	/** @num_planes: Number of color planes (1 to 3) */
> >	u8 num_planes;
> >
> >-	/** @cpp: Number of bytes per pixel (per plane) */
> >-	u8 cpp[3];
> >+	union {
> >+		/**
> >+		 * @cpp:
> >+		 *
> >+		 * Number of bytes per pixel (per plane), this is aliased with
> >+		 * @char_per_block. It is deprecated in favour of using the
> >+		 * triplet @char_per_block, @block_w, @block_h for better
> >+		 * describing the pixel format.
> >+		 */
> >+		u8 cpp[3];
> >+
> >+		/**
> >+		 * @char_per_block:
> >+		 *
> >+		 * Number of bytes per block (per plane), where blocks are
> >+		 * defined as a rectangle of pixels which are stored next to
> >+		 * each other in a byte aligned memory region. Together with
> >+		 * @block_w and @block_h this is used to properly describe tiles
> >+		 * in tiled formats or to describe groups of pixels in packed
> >+		 * formats for which the memory needed for a single pixel it's
> 
> s/it's/is/
> 
> >+		 * not byte aligned.
> >+		 *
> >+		 * @cpp had been kept from historical reasons because there are
> 
> s/had/has/, s/from/for/
> 
> >+		 * a lot of places in drivers where it's used. In drm core for
> >+		 * generic code paths the preferred way is to use
> >+		 * @char_per_block, drm_format_info_block_width() and
> >+		 * drm_format_info_block_height() which allows handling both
> >+		 * block and non-block formats in the same way.
> >+		 *
> >+		 * For formats that are intended to be used only with non-linear
> >+		 * modifiers both @cpp and @char_per_block must be 0 in the
> >+		 * generic format table. Drivers could supply accurate
> >+		 * information from their drm_mode_config.get_format_info hook
> >+		 * if they want the core to be validating the pitch.
> >+		 */
> >+		u8 char_per_block[3];
> >+	};
> >+
> >+	/**
> >+	 * @block_w:
> >+	 *
> >+	 * Block width in pixels, this is intended to be accessed through
> >+	 * drm_format_info_block_width()
> >+	 */
> >+	u8 block_w[3];
> >+
> >+	/**
> >+	 * @block_h:
> >+	 *
> >+	 * Block height in pixels, this is intended to be accessed through
> >+	 * drm_format_info_block_height()
> >+	 */
> >+	u8 block_h[3];
> >
> >	/** @hsub: Horizontal chroma subsampling factor */
> >	u8 hsub;
> >@@ -106,6 +157,12 @@ int drm_format_horz_chroma_subsampling(uint32_t format);
> >int drm_format_vert_chroma_subsampling(uint32_t format);
> >int drm_format_plane_width(int width, uint32_t format, int plane);
> >int drm_format_plane_height(int height, uint32_t format, int plane);
> >+unsigned int drm_format_info_block_width(const struct drm_format_info *info,
> >+					 int plane);
> >+unsigned int drm_format_info_block_height(const struct drm_format_info *info,
> >+					  int plane);
> >+uint64_t drm_format_info_min_pitch(const struct drm_format_info *info,
> >+				   int plane, unsigned int buffer_width);
> >const char *drm_get_format_name(uint32_t format, struct drm_format_name_buf *buf);
> >
> >#endif /* __DRM_FOURCC_H__ */
> >-- 
> >2.18.0
> >

-- 
Cheers,
Alex G
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v5 4/9] drm: mali-dp: Enable Mali-DP tiled buffer formats
  2018-10-19 13:17   ` Brian Starkey
@ 2018-10-22 10:08     ` Alexandru-Cosmin Gheorghe
  0 siblings, 0 replies; 24+ messages in thread
From: Alexandru-Cosmin Gheorghe @ 2018-10-22 10:08 UTC (permalink / raw)
  To: Brian Starkey
  Cc: charles.xu, nd, matt.szczesiak, airlied, liviu.dudau, dri-devel,
	maxime.ripard, david.garbett, seanpaul, lisa.wu, daniel.vetter,
	malidp, ayan.halder, james.qian.wang

On Fri, Oct 19, 2018 at 02:17:22PM +0100, Brian Starkey wrote:
> Hi Alex,
> 
> On Fri, Oct 19, 2018 at 11:57:47AM +0100, Alexandru Gheorghe wrote:
> >Enable the following formats
> >- DRM_FORMAT_X0L0: DP650
> >- DRM_FORMAT_X0L2: DP550, DP650
> >
> >Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>
> 
> A couple of suggestions below, but with or without you can add my
> r-b.

Will address them in the next version.

> 
> >---
> >drivers/gpu/drm/arm/malidp_hw.c     | 14 +++++++++++---
> >drivers/gpu/drm/arm/malidp_planes.c | 23 +++++++++++++++++++++--
> >2 files changed, 32 insertions(+), 5 deletions(-)
> >
> >diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
> >index c94a4422e0e9..e01fc0e5b503 100644
> >--- a/drivers/gpu/drm/arm/malidp_hw.c
> >+++ b/drivers/gpu/drm/arm/malidp_hw.c
> >@@ -77,12 +77,18 @@ static const struct malidp_format_id malidp500_de_formats[] = {
> >	{ DRM_FORMAT_YUYV, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 2) },	\
> >	{ DRM_FORMAT_UYVY, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 3) },	\
> >	{ DRM_FORMAT_NV12, DE_VIDEO1 | DE_VIDEO2 | SE_MEMWRITE, MALIDP_ID(5, 6) },	\
> >-	{ DRM_FORMAT_YUV420, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 7) }
> >+	{ DRM_FORMAT_YUV420, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 7) }, \
> >+	{ DRM_FORMAT_X0L2, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(6, 6)}
> >
> >static const struct malidp_format_id malidp550_de_formats[] = {
> >	MALIDP_COMMON_FORMATS,
> >};
> >
> >+static const struct malidp_format_id malidp650_de_formats[] = {
> >+	MALIDP_COMMON_FORMATS,
> >+	{ DRM_FORMAT_X0L0, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 4)},
> >+};
> >+
> >static const struct malidp_layer malidp500_layers[] = {
> >	{ DE_VIDEO1, MALIDP500_DE_LV_BASE, MALIDP500_DE_LV_PTR_BASE, MALIDP_DE_LV_STRIDE0, MALIDP500_LV_YUV2RGB },
> >	{ DE_GRAPHICS1, MALIDP500_DE_LG1_BASE, MALIDP500_DE_LG1_PTR_BASE, MALIDP_DE_LG_STRIDE, 0 },
> >@@ -595,6 +601,8 @@ static int malidp550_rotmem_required(struct malidp_hw_device *hwdev, u16 w, u16
> >	case DRM_FORMAT_BGR565:
> >	case DRM_FORMAT_UYVY:
> >	case DRM_FORMAT_YUYV:
> >+	case DRM_FORMAT_X0L0:
> >+	case DRM_FORMAT_X0L2:
> >		bytes_per_col = 32;
> >		break;
> >	/* 16 lines at 1.5 bytes per pixel */
> >@@ -860,8 +868,8 @@ const struct malidp_hw malidp_device[MALIDP_MAX_DEVICES] = {
> >					    MALIDP550_DC_IRQ_SE,
> >				.vsync_irq = MALIDP550_DC_IRQ_CONF_VALID,
> >			},
> >-			.pixel_formats = malidp550_de_formats,
> >-			.n_pixel_formats = ARRAY_SIZE(malidp550_de_formats),
> >+			.pixel_formats = malidp650_de_formats,
> >+			.n_pixel_formats = ARRAY_SIZE(malidp650_de_formats),
> >			.bus_align_bytes = 16,
> >		},
> >		.query_hw = malidp650_query_hw,
> >diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c
> >index 49c37f6dd63e..33bbc29da774 100644
> >--- a/drivers/gpu/drm/arm/malidp_planes.c
> >+++ b/drivers/gpu/drm/arm/malidp_planes.c
> >@@ -196,13 +196,26 @@ static int malidp_de_plane_check(struct drm_plane *plane,
> >	ms->n_planes = fb->format->num_planes;
> >	for (i = 0; i < ms->n_planes; i++) {
> >		u8 alignment = malidp_hw_get_pitch_align(mp->hwdev, rotated);
> >-		if (fb->pitches[i] & (alignment - 1)) {
> >+
> >+		if ((fb->pitches[i] * drm_format_info_block_height(fb->format, i))
> >+				& (alignment - 1)) {
> >			DRM_DEBUG_KMS("Invalid pitch %u for plane %d\n",
> >				      fb->pitches[i], i);
> >			return -EINVAL;
> >		}
> >	}
> >
> >+	if (fb->width % drm_format_info_block_width(fb->format, 0) ||
> >+	    fb->height % drm_format_info_block_height(fb->format, 0)) {
> >+		DRM_DEBUG_KMS("Buffer width/height needs to be a multiple of tile sizes");
> >+		return -EINVAL;
> >+	}
> >+	if ((state->src_x >> 16) % drm_format_info_block_width(fb->format, 0) ||
> >+	    (state->src_y >> 16) % drm_format_info_block_height(fb->format, 0)) {
> >+		DRM_DEBUG_KMS("Plane src_x/src_y needs to be a multiple of tile sizes");
> >+		return -EINVAL;
> >+	}
> 
> Some local variables for block_w and block_h instead of all the
> function calls might be easier to parse in this function.
> 
> >+
> >	if ((state->crtc_w > mp->hwdev->max_line_size) ||
> >	    (state->crtc_h > mp->hwdev->max_line_size) ||
> >	    (state->crtc_w < mp->hwdev->min_line_size) ||
> >@@ -258,8 +271,14 @@ static void malidp_de_set_plane_pitches(struct malidp_plane *mp,
> >		num_strides = (mp->hwdev->hw->features &
> >			       MALIDP_DEVICE_LV_HAS_3_STRIDES) ? 3 : 2;
> >
> >+	/*
> >+	 * The drm convention for pitch is that it needs to cover width * cpp,
> >+	 * but our hardware wants the pitch/stride to cover all rows included
> >+	 * in a tile.
> >+	 */
> >	for (i = 0; i < num_strides; ++i)
> >-		malidp_hw_write(mp->hwdev, pitches[i],
> >+		malidp_hw_write(mp->hwdev, pitches[i] *
> >+				drm_format_info_block_height(mp->base.state->fb->format, i),
> >				mp->layer->base +
> >				mp->layer->stride_offset + i * 4);
> 
> Personally I think longer lines which don't break up the arguments (or
> local variables again) would make this easier to read.
> 
> Cheers,
> -Brian
> 
> >}
> >-- 
> >2.18.0
> >

-- 
Cheers,
Alex G
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v5 5/9] drm: Extend framebuffer_check to handle formats with cpp/char_per_block 0
  2018-10-19 13:21   ` Brian Starkey
@ 2018-10-22 10:09     ` Alexandru-Cosmin Gheorghe
  0 siblings, 0 replies; 24+ messages in thread
From: Alexandru-Cosmin Gheorghe @ 2018-10-22 10:09 UTC (permalink / raw)
  To: Brian Starkey
  Cc: charles.xu, nd, matt.szczesiak, airlied, liviu.dudau, dri-devel,
	maxime.ripard, david.garbett, seanpaul, lisa.wu, daniel.vetter,
	malidp, ayan.halder, james.qian.wang

On Fri, Oct 19, 2018 at 02:21:46PM +0100, Brian Starkey wrote:
> Hi Alex,
> 
> On Fri, Oct 19, 2018 at 11:57:48AM +0100, Alexandru Gheorghe wrote:
> >For formats that are supported only with non-linear modifiers it
> >doesn't make to much sense to define cpp or char_per_block, so that
> >will be set to 0.
> >
> >This patch adds a restriction to force having a modifier attached when
> >cpp/char_per_block is 0, and to bypass checking the pitch restriction.
> >
> >This had been discussed here.
> >[1] https://people.freedesktop.org/~cbrill/dri-log/?channel=dri-devel&highlight_names=&date=2018-09-13&show_html=true
> >
> >Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>
> >---
> >drivers/gpu/drm/drm_framebuffer.c | 7 ++++++-
> >1 file changed, 6 insertions(+), 1 deletion(-)
> >
> >diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
> >index 6aca8a1ccdb6..e346d0ad92e0 100644
> >--- a/drivers/gpu/drm/drm_framebuffer.c
> >+++ b/drivers/gpu/drm/drm_framebuffer.c
> >@@ -195,8 +195,13 @@ static int framebuffer_check(struct drm_device *dev,
> >	for (i = 0; i < info->num_planes; i++) {
> >		unsigned int width = fb_plane_width(r->width, info, i);
> >		unsigned int height = fb_plane_height(r->height, info, i);
> >+		unsigned int block_size = info->char_per_block[i];
> >		u64 min_pitch = drm_format_info_min_pitch(info, i, width);
> >
> >+		if (!block_size && (r->modifier[i] == DRM_FORMAT_MOD_LINEAR)) {
> >+			DRM_DEBUG_KMS("Format requires non-linear modifier for plane %d\n", i);
> >+			return -EINVAL;
> >+		}
> 
> You could probably move that blank like from Patch 2 to here ;-)
> Otherwise LGTM:

I blame rebase :)

> 
> Reviewed By: Brian Starkey <brian.starkey@arm.com>
> 
> >		if (!r->handles[i]) {
> >			DRM_DEBUG_KMS("no buffer object handle for plane %d\n", i);
> >			return -EINVAL;
> >@@ -208,7 +213,7 @@ static int framebuffer_check(struct drm_device *dev,
> >		if ((uint64_t) height * r->pitches[i] + r->offsets[i] > UINT_MAX)
> >			return -ERANGE;
> >
> >-		if (r->pitches[i] < min_pitch) {
> >+		if (block_size && r->pitches[i] < min_pitch) {
> >			DRM_DEBUG_KMS("bad pitch %u for plane %d\n", r->pitches[i], i);
> >			return -EINVAL;
> >		}
> >-- 
> >2.18.0
> >

-- 
Cheers,
Alex G
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v5 9/9] drm/selftests: Add tests for drm_format_info* helpers
  2018-10-19 15:29   ` Daniel Vetter
@ 2018-10-22 10:32     ` Alexandru-Cosmin Gheorghe
  2018-10-23 13:56       ` Daniel Vetter
  0 siblings, 1 reply; 24+ messages in thread
From: Alexandru-Cosmin Gheorghe @ 2018-10-22 10:32 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: charles.xu, nd, matt.szczesiak, airlied, liviu.dudau, dri-devel,
	maxime.ripard, david.garbett, seanpaul, lisa.wu, daniel.vetter,
	malidp, ayan.halder, james.qian.wang

On Fri, Oct 19, 2018 at 05:29:15PM +0200, Daniel Vetter wrote:
> On Fri, Oct 19, 2018 at 11:57:52AM +0100, Alexandru Gheorghe wrote:
> > Add selftests for the following newly added functions:
> >  - drm_format_info_block_width
> >  - drm_format_info_block_height
> >  - drm_format_info_min_pitch
> > 
> > Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>
> > ---
> >  drivers/gpu/drm/selftests/Makefile            |   3 +-
> >  .../gpu/drm/selftests/drm_modeset_selftests.h |   3 +
> >  drivers/gpu/drm/selftests/test-drm_format.c   | 290 ++++++++++++++++++
> >  .../drm/selftests/test-drm_modeset_common.h   |   3 +
> >  4 files changed, 298 insertions(+), 1 deletion(-)
> >  create mode 100644 drivers/gpu/drm/selftests/test-drm_format.c
> > 
> > diff --git a/drivers/gpu/drm/selftests/Makefile b/drivers/gpu/drm/selftests/Makefile
> > index 7e6581921da0..07b4f88b422a 100644
> > --- a/drivers/gpu/drm/selftests/Makefile
> > +++ b/drivers/gpu/drm/selftests/Makefile
> > @@ -1,3 +1,4 @@
> > -test-drm_modeset-y := test-drm_modeset_common.o test-drm_plane_helper.o
> > +test-drm_modeset-y := test-drm_modeset_common.o test-drm_plane_helper.o \
> > +                      test-drm_format.o
> >  
> >  obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_modeset.o
> > diff --git a/drivers/gpu/drm/selftests/drm_modeset_selftests.h b/drivers/gpu/drm/selftests/drm_modeset_selftests.h
> > index 9771290ed228..4e203ac8c134 100644
> > --- a/drivers/gpu/drm/selftests/drm_modeset_selftests.h
> > +++ b/drivers/gpu/drm/selftests/drm_modeset_selftests.h
> > @@ -7,3 +7,6 @@
> >   * Tests are executed in order by igt/drm_selftests_helper
> >   */
> >  selftest(check_plane_state, igt_check_plane_state)
> > +selftest(check_drm_format_block_width, igt_check_drm_format_block_width)
> > +selftest(check_drm_format_block_height, igt_check_drm_format_block_height)
> > +selftest(check_drm_format_min_pitch, igt_check_drm_format_min_pitch)
> > diff --git a/drivers/gpu/drm/selftests/test-drm_format.c b/drivers/gpu/drm/selftests/test-drm_format.c
> > new file mode 100644
> > index 000000000000..5abfd5e28d7d
> > --- /dev/null
> > +++ b/drivers/gpu/drm/selftests/test-drm_format.c
> > @@ -0,0 +1,290 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Test cases for the drm_format functions
> > + */
> > +
> > +#define pr_fmt(fmt) "drm_format: " fmt
> > +
> > +#include <linux/errno.h>
> > +#include <linux/kernel.h>
> > +
> > +#include <drm/drm_fourcc.h>
> > +
> > +#include "test-drm_modeset_common.h"
> > +
> > +int igt_check_drm_format_block_width(void *ignored)
> > +{
> > +	const struct drm_format_info *info = NULL;
> > +
> > +	/* Test invalid arguments */
> > +	FAIL_ON(drm_format_info_block_width(info, 0) != 0);
> > +	FAIL_ON(drm_format_info_block_width(info, -1) != 0);
> > +	FAIL_ON(drm_format_info_block_width(info, 1) != 0);
> > +
> > +	/* Test 1 plane format */
> > +	info = drm_format_info(DRM_FORMAT_XRGB4444);
> > +	FAIL_ON(!info);
> > +	FAIL_ON(drm_format_info_block_width(info, 0) != 1);
> > +	FAIL_ON(drm_format_info_block_width(info, 1) != 0);
> > +	FAIL_ON(drm_format_info_block_width(info, -1) != 0);
> > +
> > +	/* Test 2 planes format */
> > +	info = drm_format_info(DRM_FORMAT_NV12);
> > +	FAIL_ON(!info);
> > +	FAIL_ON(drm_format_info_block_width(info, 0) != 1);
> > +	FAIL_ON(drm_format_info_block_width(info, 1) != 1);
> > +	FAIL_ON(drm_format_info_block_width(info, 2) != 0);
> > +	FAIL_ON(drm_format_info_block_width(info, -1) != 0);
> > +
> > +	/* Test 3 planes format */
> > +	info = drm_format_info(DRM_FORMAT_YUV422);
> > +	FAIL_ON(!info);
> > +	FAIL_ON(drm_format_info_block_width(info, 0) != 1);
> > +	FAIL_ON(drm_format_info_block_width(info, 1) != 1);
> > +	FAIL_ON(drm_format_info_block_width(info, 2) != 1);
> > +	FAIL_ON(drm_format_info_block_width(info, 3) != 0);
> > +	FAIL_ON(drm_format_info_block_width(info, -1) != 0);
> > +
> > +	/* Test a tiled format */
> > +	info = drm_format_info(DRM_FORMAT_X0L0);
> > +	FAIL_ON(!info);
> > +	FAIL_ON(drm_format_info_block_width(info, 0) != 2);
> > +	FAIL_ON(drm_format_info_block_width(info, 1) != 0);
> > +	FAIL_ON(drm_format_info_block_width(info, -1) != 0);
> > +
> > +	return 0;
> > +}
> > +
> > +int igt_check_drm_format_block_height(void *ignored)
> > +{
> > +	const struct drm_format_info *info = NULL;
> > +
> > +	/* Test invalid arguments */
> > +	FAIL_ON(drm_format_info_block_height(info, 0) != 0);
> > +	FAIL_ON(drm_format_info_block_height(info, -1) != 0);
> > +	FAIL_ON(drm_format_info_block_height(info, 1) != 0);
> > +
> > +	/* Test 1 plane format */
> > +	info = drm_format_info(DRM_FORMAT_XRGB4444);
> > +	FAIL_ON(!info);
> > +	FAIL_ON(drm_format_info_block_height(info, 0) != 1);
> > +	FAIL_ON(drm_format_info_block_height(info, 1) != 0);
> > +	FAIL_ON(drm_format_info_block_height(info, -1) != 0);
> > +
> > +	/* Test 2 planes format */
> > +	info = drm_format_info(DRM_FORMAT_NV12);
> > +	FAIL_ON(!info);
> > +	FAIL_ON(drm_format_info_block_height(info, 0) != 1);
> > +	FAIL_ON(drm_format_info_block_height(info, 1) != 1);
> > +	FAIL_ON(drm_format_info_block_height(info, 2) != 0);
> > +	FAIL_ON(drm_format_info_block_height(info, -1) != 0);
> > +
> > +	/* Test 3 planes format */
> > +	info = drm_format_info(DRM_FORMAT_YUV422);
> > +	FAIL_ON(!info);
> > +	FAIL_ON(drm_format_info_block_height(info, 0) != 1);
> > +	FAIL_ON(drm_format_info_block_height(info, 1) != 1);
> > +	FAIL_ON(drm_format_info_block_height(info, 2) != 1);
> > +	FAIL_ON(drm_format_info_block_height(info, 3) != 0);
> > +	FAIL_ON(drm_format_info_block_height(info, -1) != 0);
> > +
> > +	/* Test a tiled format */
> > +	info = drm_format_info(DRM_FORMAT_X0L0);
> > +	FAIL_ON(!info);
> > +	FAIL_ON(drm_format_info_block_height(info, 0) != 2);
> > +	FAIL_ON(drm_format_info_block_height(info, 1) != 0);
> > +	FAIL_ON(drm_format_info_block_height(info, -1) != 0);
> > +
> > +	return 0;
> > +}
> > +
> > +int igt_check_drm_format_min_pitch(void *ignored)
> > +{
> > +	const struct drm_format_info *info = NULL;
> > +
> > +	/* Test invalid arguments */
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
> > +	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
> > +
> > +	/* Test 1 plane 8 bits per pixel format */
> > +	info = drm_format_info(DRM_FORMAT_RGB332);
> > +	FAIL_ON(!info);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
> > +	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
> > +
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 1);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 2);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 640);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 1024);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 1920);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 4096);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 671);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
> > +			(uint64_t)UINT_MAX);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, (UINT_MAX - 1)) !=
> > +			(uint64_t)(UINT_MAX - 1));
> > +
> > +	/* Test 1 plane 16 bits per pixel format */
> > +	info = drm_format_info(DRM_FORMAT_XRGB4444);
> > +	FAIL_ON(!info);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
> > +	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
> > +
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 2);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 4);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 1280);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 2048);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 3840);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 8192);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 1342);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
> > +			(uint64_t)UINT_MAX * 2);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, (UINT_MAX - 1)) !=
> > +			(uint64_t)(UINT_MAX - 1) * 2);
> > +
> > +	/* Test 1 plane 24 bits per pixel format */
> > +	info = drm_format_info(DRM_FORMAT_RGB888);
> > +	FAIL_ON(!info);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
> > +	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
> > +
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 3);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 6);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 1920);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 3072);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 5760);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 12288);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 2013);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
> > +			(uint64_t)UINT_MAX * 3);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX - 1) !=
> > +			(uint64_t)(UINT_MAX - 1) * 3);
> > +
> > +	/* Test 1 plane 32 bits per pixel format */
> > +	info = drm_format_info(DRM_FORMAT_ABGR8888);
> > +	FAIL_ON(!info);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
> > +	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
> > +
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 4);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 8);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 2560);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 4096);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 7680);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 16384);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 2684);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
> > +			(uint64_t)UINT_MAX * 4);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX - 1) !=
> > +			(uint64_t)(UINT_MAX - 1) * 4);
> > +
> > +	/* Test 2 planes format */
> > +	info = drm_format_info(DRM_FORMAT_NV12);
> > +	FAIL_ON(!info);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
> > +	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 2, 0) != 0);
> > +
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 1);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 1) != 2);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 2);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 1) != 2);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 640);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 320) != 640);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 1024);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 512) != 1024);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 1920);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 960) != 1920);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 4096);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 2048) != 4096);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 671);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 336) != 672);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
> > +			(uint64_t)UINT_MAX);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 1, UINT_MAX / 2 + 1) !=
> > +			(uint64_t)UINT_MAX + 1);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, (UINT_MAX - 1)) !=
> > +			(uint64_t)(UINT_MAX - 1));
> > +	FAIL_ON(drm_format_info_min_pitch(info, 1, (UINT_MAX - 1) /  2) !=
> > +			(uint64_t)(UINT_MAX - 1));
> > +
> > +	/* Test 3 planes 8 bits per pixel format */
> > +	info = drm_format_info(DRM_FORMAT_YUV422);
> > +	FAIL_ON(!info);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 2, 0) != 0);
> > +	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 3, 0) != 0);
> > +
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 1);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 1) != 1);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 2, 1) != 1);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 2);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 2) != 2);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 2, 2) != 2);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 640);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 320) != 320);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 2, 320) != 320);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 1024);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 512) != 512);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 2, 512) != 512);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 1920);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 960) != 960);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 2, 960) != 960);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 4096);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 2048) != 2048);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 2, 2048) != 2048);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 671);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 336) != 336);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 2, 336) != 336);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
> > +			(uint64_t)UINT_MAX);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 1, UINT_MAX / 2 + 1) !=
> > +			(uint64_t)UINT_MAX / 2 + 1);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 2, UINT_MAX / 2 + 1) !=
> > +			(uint64_t)UINT_MAX / 2 + 1);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, (UINT_MAX - 1) / 2) !=
> > +			(uint64_t)(UINT_MAX - 1) / 2);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 1, (UINT_MAX - 1) / 2) !=
> > +			(uint64_t)(UINT_MAX - 1) / 2);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 2, (UINT_MAX - 1) / 2) !=
> > +			(uint64_t)(UINT_MAX - 1) / 2);
> > +
> > +	/* Test tiled format */
> > +	info = drm_format_info(DRM_FORMAT_X0L2);
> > +	FAIL_ON(!info);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
> > +	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
> > +
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 2);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 4);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 1280);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 2048);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 3840);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 8192);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 1342);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
> > +			(uint64_t)UINT_MAX * 2);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX - 1) !=
> > +			(uint64_t)(UINT_MAX - 1) * 2);
> > +
> > +	/* Test format with cpp/char_per_block 0 */
> > +	info = drm_format_info(DRM_FORMAT_VUY101010);
> > +	FAIL_ON(!info);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
> > +	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
> > +
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 0);
> > +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) != 0);
> > +
> > +	return 0;
> > +}
> 
> Comprehensive, but also fairly boring. Anyway, it's a start, so:

Unit tests usually are :)

> 
> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

Can I also get your reviewed-by on the patches that adds this functions ?

> 
> What I had in mind is maybe not quite so low-level unit testing, but
> exercising the entire framebuffer_create machinery. The recently
> drm_client_framebuffer_create essentially gives you that interface for
> modules (but I guess we could also EXPORT_SYMBOL_FOR_TESTS_ONLY,
> conditional on drm selftests being enabled, directly on
> drm_internal_framebuffer_create).

Yeah, that's exactly what I thought I started looking at it, but I got
discouraged, by the lack of mocking, so I decided to start small.

> 
> This needs some fairly minimal mocking of a drm_device with a bunch of
> dummy functions (throw them into test-drm_modeset_common.c if you feel
> like). Then go through a pile of valid and invalid combinations and make
> sure your ->fb_create driver callback is only called when when it should
> be (and not for anything invalid). I think that would yield the much more
> interesting testing ...

This combined with EXPORT_SYMBOL_FOR_TESTS_ONLY should be fairly
simple, but it still feels like a drop in the ocean, I can't even
test the other functions that patch [1] touches like:
drm_gem_fb_create_with_funcs and drm_fb_cma_get_gem_addr.

[1] https://lists.freedesktop.org/archives/dri-devel/2018-October/193671.html

> 
> That will also pave the ground for some rather more serious addfb testing
> in the future. And eventually even more serious testing on e.g. atomic
> helpers.
> 
> Anyway, if you feel like, would be awesome to follow up a bit in that
> direction.
> 
> Cheers, Daniel
> 
> > diff --git a/drivers/gpu/drm/selftests/test-drm_modeset_common.h b/drivers/gpu/drm/selftests/test-drm_modeset_common.h
> > index b0065a2eb067..592a6581b189 100644
> > --- a/drivers/gpu/drm/selftests/test-drm_modeset_common.h
> > +++ b/drivers/gpu/drm/selftests/test-drm_modeset_common.h
> > @@ -14,5 +14,8 @@
> >  #define FAIL_ON(x) FAIL((x), "%s", "FAIL_ON(" __stringify(x) ")\n")
> >  
> >  int igt_check_plane_state(void *ignored);
> > +int igt_check_drm_format_block_width(void *ignored);
> > +int igt_check_drm_format_block_height(void *ignored);
> > +int igt_check_drm_format_min_pitch(void *ignored);
> >  
> >  #endif
> > -- 
> > 2.18.0
> > 
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

-- 
Cheers,
Alex G
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v5 9/9] drm/selftests: Add tests for drm_format_info* helpers
  2018-10-22 10:32     ` Alexandru-Cosmin Gheorghe
@ 2018-10-23 13:56       ` Daniel Vetter
  0 siblings, 0 replies; 24+ messages in thread
From: Daniel Vetter @ 2018-10-23 13:56 UTC (permalink / raw)
  To: Alexandru-Cosmin Gheorghe
  Cc: charles.xu, nd, matt.szczesiak, airlied, liviu.dudau, dri-devel,
	maxime.ripard, david.garbett, seanpaul, lisa.wu, daniel.vetter,
	malidp, ayan.halder, james.qian.wang

On Mon, Oct 22, 2018 at 11:32:10AM +0100, Alexandru-Cosmin Gheorghe wrote:
> On Fri, Oct 19, 2018 at 05:29:15PM +0200, Daniel Vetter wrote:
> > On Fri, Oct 19, 2018 at 11:57:52AM +0100, Alexandru Gheorghe wrote:
> > > Add selftests for the following newly added functions:
> > >  - drm_format_info_block_width
> > >  - drm_format_info_block_height
> > >  - drm_format_info_min_pitch
> > > 
> > > Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>
> > > ---
> > >  drivers/gpu/drm/selftests/Makefile            |   3 +-
> > >  .../gpu/drm/selftests/drm_modeset_selftests.h |   3 +
> > >  drivers/gpu/drm/selftests/test-drm_format.c   | 290 ++++++++++++++++++
> > >  .../drm/selftests/test-drm_modeset_common.h   |   3 +
> > >  4 files changed, 298 insertions(+), 1 deletion(-)
> > >  create mode 100644 drivers/gpu/drm/selftests/test-drm_format.c
> > > 
> > > diff --git a/drivers/gpu/drm/selftests/Makefile b/drivers/gpu/drm/selftests/Makefile
> > > index 7e6581921da0..07b4f88b422a 100644
> > > --- a/drivers/gpu/drm/selftests/Makefile
> > > +++ b/drivers/gpu/drm/selftests/Makefile
> > > @@ -1,3 +1,4 @@
> > > -test-drm_modeset-y := test-drm_modeset_common.o test-drm_plane_helper.o
> > > +test-drm_modeset-y := test-drm_modeset_common.o test-drm_plane_helper.o \
> > > +                      test-drm_format.o
> > >  
> > >  obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_modeset.o
> > > diff --git a/drivers/gpu/drm/selftests/drm_modeset_selftests.h b/drivers/gpu/drm/selftests/drm_modeset_selftests.h
> > > index 9771290ed228..4e203ac8c134 100644
> > > --- a/drivers/gpu/drm/selftests/drm_modeset_selftests.h
> > > +++ b/drivers/gpu/drm/selftests/drm_modeset_selftests.h
> > > @@ -7,3 +7,6 @@
> > >   * Tests are executed in order by igt/drm_selftests_helper
> > >   */
> > >  selftest(check_plane_state, igt_check_plane_state)
> > > +selftest(check_drm_format_block_width, igt_check_drm_format_block_width)
> > > +selftest(check_drm_format_block_height, igt_check_drm_format_block_height)
> > > +selftest(check_drm_format_min_pitch, igt_check_drm_format_min_pitch)
> > > diff --git a/drivers/gpu/drm/selftests/test-drm_format.c b/drivers/gpu/drm/selftests/test-drm_format.c
> > > new file mode 100644
> > > index 000000000000..5abfd5e28d7d
> > > --- /dev/null
> > > +++ b/drivers/gpu/drm/selftests/test-drm_format.c
> > > @@ -0,0 +1,290 @@
> > > +// SPDX-License-Identifier: GPL-2.0
> > > +/*
> > > + * Test cases for the drm_format functions
> > > + */
> > > +
> > > +#define pr_fmt(fmt) "drm_format: " fmt
> > > +
> > > +#include <linux/errno.h>
> > > +#include <linux/kernel.h>
> > > +
> > > +#include <drm/drm_fourcc.h>
> > > +
> > > +#include "test-drm_modeset_common.h"
> > > +
> > > +int igt_check_drm_format_block_width(void *ignored)
> > > +{
> > > +	const struct drm_format_info *info = NULL;
> > > +
> > > +	/* Test invalid arguments */
> > > +	FAIL_ON(drm_format_info_block_width(info, 0) != 0);
> > > +	FAIL_ON(drm_format_info_block_width(info, -1) != 0);
> > > +	FAIL_ON(drm_format_info_block_width(info, 1) != 0);
> > > +
> > > +	/* Test 1 plane format */
> > > +	info = drm_format_info(DRM_FORMAT_XRGB4444);
> > > +	FAIL_ON(!info);
> > > +	FAIL_ON(drm_format_info_block_width(info, 0) != 1);
> > > +	FAIL_ON(drm_format_info_block_width(info, 1) != 0);
> > > +	FAIL_ON(drm_format_info_block_width(info, -1) != 0);
> > > +
> > > +	/* Test 2 planes format */
> > > +	info = drm_format_info(DRM_FORMAT_NV12);
> > > +	FAIL_ON(!info);
> > > +	FAIL_ON(drm_format_info_block_width(info, 0) != 1);
> > > +	FAIL_ON(drm_format_info_block_width(info, 1) != 1);
> > > +	FAIL_ON(drm_format_info_block_width(info, 2) != 0);
> > > +	FAIL_ON(drm_format_info_block_width(info, -1) != 0);
> > > +
> > > +	/* Test 3 planes format */
> > > +	info = drm_format_info(DRM_FORMAT_YUV422);
> > > +	FAIL_ON(!info);
> > > +	FAIL_ON(drm_format_info_block_width(info, 0) != 1);
> > > +	FAIL_ON(drm_format_info_block_width(info, 1) != 1);
> > > +	FAIL_ON(drm_format_info_block_width(info, 2) != 1);
> > > +	FAIL_ON(drm_format_info_block_width(info, 3) != 0);
> > > +	FAIL_ON(drm_format_info_block_width(info, -1) != 0);
> > > +
> > > +	/* Test a tiled format */
> > > +	info = drm_format_info(DRM_FORMAT_X0L0);
> > > +	FAIL_ON(!info);
> > > +	FAIL_ON(drm_format_info_block_width(info, 0) != 2);
> > > +	FAIL_ON(drm_format_info_block_width(info, 1) != 0);
> > > +	FAIL_ON(drm_format_info_block_width(info, -1) != 0);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +int igt_check_drm_format_block_height(void *ignored)
> > > +{
> > > +	const struct drm_format_info *info = NULL;
> > > +
> > > +	/* Test invalid arguments */
> > > +	FAIL_ON(drm_format_info_block_height(info, 0) != 0);
> > > +	FAIL_ON(drm_format_info_block_height(info, -1) != 0);
> > > +	FAIL_ON(drm_format_info_block_height(info, 1) != 0);
> > > +
> > > +	/* Test 1 plane format */
> > > +	info = drm_format_info(DRM_FORMAT_XRGB4444);
> > > +	FAIL_ON(!info);
> > > +	FAIL_ON(drm_format_info_block_height(info, 0) != 1);
> > > +	FAIL_ON(drm_format_info_block_height(info, 1) != 0);
> > > +	FAIL_ON(drm_format_info_block_height(info, -1) != 0);
> > > +
> > > +	/* Test 2 planes format */
> > > +	info = drm_format_info(DRM_FORMAT_NV12);
> > > +	FAIL_ON(!info);
> > > +	FAIL_ON(drm_format_info_block_height(info, 0) != 1);
> > > +	FAIL_ON(drm_format_info_block_height(info, 1) != 1);
> > > +	FAIL_ON(drm_format_info_block_height(info, 2) != 0);
> > > +	FAIL_ON(drm_format_info_block_height(info, -1) != 0);
> > > +
> > > +	/* Test 3 planes format */
> > > +	info = drm_format_info(DRM_FORMAT_YUV422);
> > > +	FAIL_ON(!info);
> > > +	FAIL_ON(drm_format_info_block_height(info, 0) != 1);
> > > +	FAIL_ON(drm_format_info_block_height(info, 1) != 1);
> > > +	FAIL_ON(drm_format_info_block_height(info, 2) != 1);
> > > +	FAIL_ON(drm_format_info_block_height(info, 3) != 0);
> > > +	FAIL_ON(drm_format_info_block_height(info, -1) != 0);
> > > +
> > > +	/* Test a tiled format */
> > > +	info = drm_format_info(DRM_FORMAT_X0L0);
> > > +	FAIL_ON(!info);
> > > +	FAIL_ON(drm_format_info_block_height(info, 0) != 2);
> > > +	FAIL_ON(drm_format_info_block_height(info, 1) != 0);
> > > +	FAIL_ON(drm_format_info_block_height(info, -1) != 0);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +int igt_check_drm_format_min_pitch(void *ignored)
> > > +{
> > > +	const struct drm_format_info *info = NULL;
> > > +
> > > +	/* Test invalid arguments */
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
> > > +
> > > +	/* Test 1 plane 8 bits per pixel format */
> > > +	info = drm_format_info(DRM_FORMAT_RGB332);
> > > +	FAIL_ON(!info);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
> > > +
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 1);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 2);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 640);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 1024);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 1920);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 4096);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 671);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
> > > +			(uint64_t)UINT_MAX);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, (UINT_MAX - 1)) !=
> > > +			(uint64_t)(UINT_MAX - 1));
> > > +
> > > +	/* Test 1 plane 16 bits per pixel format */
> > > +	info = drm_format_info(DRM_FORMAT_XRGB4444);
> > > +	FAIL_ON(!info);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
> > > +
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 2);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 4);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 1280);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 2048);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 3840);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 8192);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 1342);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
> > > +			(uint64_t)UINT_MAX * 2);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, (UINT_MAX - 1)) !=
> > > +			(uint64_t)(UINT_MAX - 1) * 2);
> > > +
> > > +	/* Test 1 plane 24 bits per pixel format */
> > > +	info = drm_format_info(DRM_FORMAT_RGB888);
> > > +	FAIL_ON(!info);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
> > > +
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 3);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 6);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 1920);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 3072);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 5760);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 12288);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 2013);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
> > > +			(uint64_t)UINT_MAX * 3);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX - 1) !=
> > > +			(uint64_t)(UINT_MAX - 1) * 3);
> > > +
> > > +	/* Test 1 plane 32 bits per pixel format */
> > > +	info = drm_format_info(DRM_FORMAT_ABGR8888);
> > > +	FAIL_ON(!info);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
> > > +
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 4);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 8);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 2560);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 4096);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 7680);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 16384);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 2684);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
> > > +			(uint64_t)UINT_MAX * 4);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX - 1) !=
> > > +			(uint64_t)(UINT_MAX - 1) * 4);
> > > +
> > > +	/* Test 2 planes format */
> > > +	info = drm_format_info(DRM_FORMAT_NV12);
> > > +	FAIL_ON(!info);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 2, 0) != 0);
> > > +
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 1);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 1) != 2);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 2);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 1) != 2);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 640);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 320) != 640);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 1024);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 512) != 1024);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 1920);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 960) != 1920);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 4096);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 2048) != 4096);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 671);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 336) != 672);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
> > > +			(uint64_t)UINT_MAX);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 1, UINT_MAX / 2 + 1) !=
> > > +			(uint64_t)UINT_MAX + 1);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, (UINT_MAX - 1)) !=
> > > +			(uint64_t)(UINT_MAX - 1));
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 1, (UINT_MAX - 1) /  2) !=
> > > +			(uint64_t)(UINT_MAX - 1));
> > > +
> > > +	/* Test 3 planes 8 bits per pixel format */
> > > +	info = drm_format_info(DRM_FORMAT_YUV422);
> > > +	FAIL_ON(!info);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 2, 0) != 0);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 3, 0) != 0);
> > > +
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 1);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 1) != 1);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 2, 1) != 1);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 2);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 2) != 2);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 2, 2) != 2);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 640);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 320) != 320);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 2, 320) != 320);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 1024);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 512) != 512);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 2, 512) != 512);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 1920);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 960) != 960);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 2, 960) != 960);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 4096);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 2048) != 2048);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 2, 2048) != 2048);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 671);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 336) != 336);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 2, 336) != 336);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
> > > +			(uint64_t)UINT_MAX);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 1, UINT_MAX / 2 + 1) !=
> > > +			(uint64_t)UINT_MAX / 2 + 1);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 2, UINT_MAX / 2 + 1) !=
> > > +			(uint64_t)UINT_MAX / 2 + 1);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, (UINT_MAX - 1) / 2) !=
> > > +			(uint64_t)(UINT_MAX - 1) / 2);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 1, (UINT_MAX - 1) / 2) !=
> > > +			(uint64_t)(UINT_MAX - 1) / 2);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 2, (UINT_MAX - 1) / 2) !=
> > > +			(uint64_t)(UINT_MAX - 1) / 2);
> > > +
> > > +	/* Test tiled format */
> > > +	info = drm_format_info(DRM_FORMAT_X0L2);
> > > +	FAIL_ON(!info);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
> > > +
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 2);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 4);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 1280);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 2048);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 3840);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 8192);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 1342);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
> > > +			(uint64_t)UINT_MAX * 2);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX - 1) !=
> > > +			(uint64_t)(UINT_MAX - 1) * 2);
> > > +
> > > +	/* Test format with cpp/char_per_block 0 */
> > > +	info = drm_format_info(DRM_FORMAT_VUY101010);
> > > +	FAIL_ON(!info);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
> > > +
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 0);
> > > +	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) != 0);
> > > +
> > > +	return 0;
> > > +}
> > 
> > Comprehensive, but also fairly boring. Anyway, it's a start, so:
> 
> Unit tests usually are :)
> 
> > 
> > Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> 
> Can I also get your reviewed-by on the patches that adds this functions ?
> 
> > 
> > What I had in mind is maybe not quite so low-level unit testing, but
> > exercising the entire framebuffer_create machinery. The recently
> > drm_client_framebuffer_create essentially gives you that interface for
> > modules (but I guess we could also EXPORT_SYMBOL_FOR_TESTS_ONLY,
> > conditional on drm selftests being enabled, directly on
> > drm_internal_framebuffer_create).
> 
> Yeah, that's exactly what I thought I started looking at it, but I got
> discouraged, by the lack of mocking, so I decided to start small.

There's no formal mocking framework, but initializing a few bare-bones
drm_device structs has become really simple. We've done lots of work in
making all kinds of vtables optional :-)

And addfb here is very minimal, so kinda ideal to get started on this
journey.

"Test coverage not at 100% yet, let's not even bother" is kinda a
fallacy, since we do have all the CI already (at least for intel stuff),
so any test you add _will_ run, and it _will_ catch bugs. Even if it's
really lonely :-)

> > This needs some fairly minimal mocking of a drm_device with a bunch of
> > dummy functions (throw them into test-drm_modeset_common.c if you feel
> > like). Then go through a pile of valid and invalid combinations and make
> > sure your ->fb_create driver callback is only called when when it should
> > be (and not for anything invalid). I think that would yield the much more
> > interesting testing ...
> 
> This combined with EXPORT_SYMBOL_FOR_TESTS_ONLY should be fairly
> simple, but it still feels like a drop in the ocean, I can't even
> test the other functions that patch [1] touches like:
> drm_gem_fb_create_with_funcs and drm_fb_cma_get_gem_addr.
> 
> [1] https://lists.freedesktop.org/archives/dri-devel/2018-October/193671.html

We need to start somewhere imo.

Also note that igt does fairly massive testing of a lot of infrastructure
too, I think best to aim for complementary testing. fbdev not having
perfect test coverage from the go is not a big deal imo, if we can just
start with the core code and core helpers, that's already a huge step
forward.
-Daniel

> 
> > 
> > That will also pave the ground for some rather more serious addfb testing
> > in the future. And eventually even more serious testing on e.g. atomic
> > helpers.
> > 
> > Anyway, if you feel like, would be awesome to follow up a bit in that
> > direction.
> > 
> > Cheers, Daniel
> > 
> > > diff --git a/drivers/gpu/drm/selftests/test-drm_modeset_common.h b/drivers/gpu/drm/selftests/test-drm_modeset_common.h
> > > index b0065a2eb067..592a6581b189 100644
> > > --- a/drivers/gpu/drm/selftests/test-drm_modeset_common.h
> > > +++ b/drivers/gpu/drm/selftests/test-drm_modeset_common.h
> > > @@ -14,5 +14,8 @@
> > >  #define FAIL_ON(x) FAIL((x), "%s", "FAIL_ON(" __stringify(x) ")\n")
> > >  
> > >  int igt_check_plane_state(void *ignored);
> > > +int igt_check_drm_format_block_width(void *ignored);
> > > +int igt_check_drm_format_block_height(void *ignored);
> > > +int igt_check_drm_format_min_pitch(void *ignored);
> > >  
> > >  #endif
> > > -- 
> > > 2.18.0
> > > 
> > 
> > -- 
> > Daniel Vetter
> > Software Engineer, Intel Corporation
> > http://blog.ffwll.ch
> 
> -- 
> Cheers,
> Alex G

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2018-10-23 13:57 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-10-19 10:57 [PATCH v5 0/9] Add method to describe tile/bit_level_packed formats Alexandru Gheorghe
2018-10-19 10:57 ` [PATCH v5 1/9] drm: fourcc: Convert drm_format_info kerneldoc to in-line member documentation Alexandru Gheorghe
2018-10-19 12:54   ` Maxime Ripard
2018-10-22  9:36     ` Alexandru-Cosmin Gheorghe
2018-10-19 10:57 ` [PATCH v5 2/9] drm/fourcc: Add char_per_block, block_w and block_h in drm_format_info Alexandru Gheorghe
2018-10-19 13:09   ` Brian Starkey
2018-10-22 10:07     ` Alexandru-Cosmin Gheorghe
2018-10-19 10:57 ` [PATCH v5 3/9] drm/fourcc: Add fourcc for Mali linear tiled formats Alexandru Gheorghe
2018-10-19 13:12   ` Brian Starkey
2018-10-19 10:57 ` [PATCH v5 4/9] drm: mali-dp: Enable Mali-DP tiled buffer formats Alexandru Gheorghe
2018-10-19 13:17   ` Brian Starkey
2018-10-22 10:08     ` Alexandru-Cosmin Gheorghe
2018-10-19 10:57 ` [PATCH v5 5/9] drm: Extend framebuffer_check to handle formats with cpp/char_per_block 0 Alexandru Gheorghe
2018-10-19 13:21   ` Brian Starkey
2018-10-22 10:09     ` Alexandru-Cosmin Gheorghe
2018-10-19 10:57 ` [PATCH v5 6/9] drm/fourcc: Add AFBC yuv fourccs for Mali Alexandru Gheorghe
2018-10-19 10:57 ` [PATCH v5 7/9] drm/afbc: Add AFBC modifier usage documentation Alexandru Gheorghe
2018-10-19 10:57 ` [PATCH v5 8/9] drm/selftest: Refactor test-drm_plane_helper Alexandru Gheorghe
2018-10-19 15:14   ` Daniel Vetter
2018-10-22  9:40     ` Alexandru-Cosmin Gheorghe
2018-10-19 10:57 ` [PATCH v5 9/9] drm/selftests: Add tests for drm_format_info* helpers Alexandru Gheorghe
2018-10-19 15:29   ` Daniel Vetter
2018-10-22 10:32     ` Alexandru-Cosmin Gheorghe
2018-10-23 13:56       ` Daniel Vetter

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.