[PATCH v2] drm: Fix drm_fixp2int_round() making it add 0.5

2024-03-16 Thread Arthur Grillo
As well noted by Pekka[1], the rounding of drm_fixp2int_round is wrong.
To round a number, you need to add 0.5 to the number and floor that,
drm_fixp2int_round() is adding 0.076. Make it add 0.5.

[1]: 
https://lore.kernel.org/all/20240301135327.22efe0dd.pekka.paala...@collabora.com/

Fixes: 8b25320887d7 ("drm: Add fixed-point helper to get rounded integer 
values")
Suggested-by: Pekka Paalanen 
Reviewed-by: Harry Wentland 
Signed-off-by: Arthur Grillo 
---
Changes in v2:
- Add Fixes tag (Melissa Wen)
- Remove DRM_FIXED_POINT_HALF (Melissa Wen)
- Link to v1: 
https://lore.kernel.org/all/20240306-louis-vkms-conv-v1-1-5bfe7d129...@riseup.net/
---
 include/drm/drm_fixed.h | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/include/drm/drm_fixed.h b/include/drm/drm_fixed.h
index 0c9f917a4d4b..81572d32db0c 100644
--- a/include/drm/drm_fixed.h
+++ b/include/drm/drm_fixed.h
@@ -71,7 +71,6 @@ static inline u32 dfixed_div(fixed20_12 A, fixed20_12 B)
 }
 
 #define DRM_FIXED_POINT32
-#define DRM_FIXED_POINT_HALF   16
 #define DRM_FIXED_ONE  (1ULL << DRM_FIXED_POINT)
 #define DRM_FIXED_DECIMAL_MASK (DRM_FIXED_ONE - 1)
 #define DRM_FIXED_DIGITS_MASK  (~DRM_FIXED_DECIMAL_MASK)
@@ -90,7 +89,7 @@ static inline int drm_fixp2int(s64 a)
 
 static inline int drm_fixp2int_round(s64 a)
 {
-   return drm_fixp2int(a + (1 << (DRM_FIXED_POINT_HALF - 1)));
+   return drm_fixp2int(a + DRM_FIXED_ONE / 2);
 }
 
 static inline int drm_fixp2int_ceil(s64 a)

---
base-commit: f89632a9e5fa6c4787c14458cd42a9ef42025434
change-id: 20240315-drm_fixed-c680ba078ecb

Best regards,
-- 
Arthur Grillo 



Re: [PATCH 1/7] drm: Fix drm_fixp2int_round() making it add 0.5

2024-03-16 Thread Arthur Grillo



On 12/03/24 15:27, Melissa Wen wrote:
> On 03/06, Arthur Grillo wrote:
>> As well noted by Pekka[1], the rounding of drm_fixp2int_round is wrong.
>> To round a number, you need to add 0.5 to the number and floor that,
>> drm_fixp2int_round() is adding 0.076. Make it add 0.5.
>>
>> [1]: 
>> https://lore.kernel.org/all/20240301135327.22efe0dd.pekka.paala...@collabora.com/
>>
> Hi Arthur,
> 
> thanks for addressing this issue.
> 
> Please, add a fix tag to the commit that you are fixing, so we can
> easily backport. Might be this commit:
> https://cgit.freedesktop.org/drm/drm-misc/commit/drivers/gpu/drm/vkms?id=ab87f558dcfb2562c3497e89600dec798a446665

Wouldn't be this commit instead?
https://cgit.freedesktop.org/drm/drm-misc/commit/?id=8b25320887d7feac98875546ea0f521628b745bb

Best Regards,
~Arthur Grillo


>> Suggested-by: Pekka Paalanen 
>> Signed-off-by: Arthur Grillo 
>> ---
>>  include/drm/drm_fixed.h | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/include/drm/drm_fixed.h b/include/drm/drm_fixed.h
>> index 0c9f917a4d4b..de3a79909ac9 100644
>> --- a/include/drm/drm_fixed.h
>> +++ b/include/drm/drm_fixed.h
>> @@ -90,7 +90,7 @@ static inline int drm_fixp2int(s64 a)
>>  
>>  static inline int drm_fixp2int_round(s64 a)
>>  {
>> -return drm_fixp2int(a + (1 << (DRM_FIXED_POINT_HALF - 1)));
> Also, this is the only usage of DRM_FIXED_POINT_HALF. Can you also
> remove it as it won't be used anymore?
> 
>> +return drm_fixp2int(a + DRM_FIXED_ONE / 2);
> Would this division be equivalent to just shifting 1ULL by 31 instead of
> 32 as done in DRM_FIXED_ONE?
> 
> Melissa
> 
>>  }
>>  
>>  static inline int drm_fixp2int_ceil(s64 a)
>>
>> -- 
>> 2.43.0
>>


Re: [PATCH 1/7] drm: Fix drm_fixp2int_round() making it add 0.5

2024-03-13 Thread Arthur Grillo



On 12/03/24 15:27, Melissa Wen wrote:
> On 03/06, Arthur Grillo wrote:
>> As well noted by Pekka[1], the rounding of drm_fixp2int_round is wrong.
>> To round a number, you need to add 0.5 to the number and floor that,
>> drm_fixp2int_round() is adding 0.076. Make it add 0.5.
>>
>> [1]: 
>> https://lore.kernel.org/all/20240301135327.22efe0dd.pekka.paala...@collabora.com/
>>
> Hi Arthur,
> 
> thanks for addressing this issue.
> 
> Please, add a fix tag to the commit that you are fixing, so we can
> easily backport. Might be this commit:
> https://cgit.freedesktop.org/drm/drm-misc/commit/drivers/gpu/drm/vkms?id=ab87f558dcfb2562c3497e89600dec798a446665
>> Suggested-by: Pekka Paalanen 
>> Signed-off-by: Arthur Grillo 
>> ---
>>  include/drm/drm_fixed.h | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/include/drm/drm_fixed.h b/include/drm/drm_fixed.h
>> index 0c9f917a4d4b..de3a79909ac9 100644
>> --- a/include/drm/drm_fixed.h
>> +++ b/include/drm/drm_fixed.h
>> @@ -90,7 +90,7 @@ static inline int drm_fixp2int(s64 a)
>>  
>>  static inline int drm_fixp2int_round(s64 a)
>>  {
>> -return drm_fixp2int(a + (1 << (DRM_FIXED_POINT_HALF - 1)));
> Also, this is the only usage of DRM_FIXED_POINT_HALF. Can you also
> remove it as it won't be used anymore?
> 
>> +return drm_fixp2int(a + DRM_FIXED_ONE / 2);
> Would this division be equivalent to just shifting 1ULL by 31 instead of
> 32 as done in DRM_FIXED_ONE?

Yes, but I think the division makes it easier to understand what is
going on.

Best Regards,
~Arthur Grillo

> 
> Melissa
> 
>>  }
>>  
>>  static inline int drm_fixp2int_ceil(s64 a)
>>
>> -- 
>> 2.43.0
>>


Re: [PATCH 4/7] drm/vkms: Fix compilation issues

2024-03-07 Thread Arthur Grillo



On 06/03/24 21:03, Louis Chauvet wrote:
> Le 06/03/24 - 17:03, Arthur Grillo a écrit :
>> Signed-off-by: Arthur Grillo 
>> ---
>>  drivers/gpu/drm/vkms/tests/vkms_format_test.c | 2 +-
>>  drivers/gpu/drm/vkms/vkms_drv.h   | 4 
>>  2 files changed, 5 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/vkms/tests/vkms_format_test.c 
>> b/drivers/gpu/drm/vkms/tests/vkms_format_test.c
>> index 4636b013602f..3522ecee960f 100644
>> --- a/drivers/gpu/drm/vkms/tests/vkms_format_test.c
>> +++ b/drivers/gpu/drm/vkms/tests/vkms_format_test.c
>> @@ -113,7 +113,7 @@ static void vkms_format_test_yuv_u8_to_argb_u16(struct 
>> kunit *test)
>>  for (size_t i = 0; i < param->n_colors; i++) {
>>  const struct format_pair *color = >colors[i];
>>  
>> -const struct conversion_matrix *matrix = 
>> get_conversion_matrix_to_argb_u16
>> +struct conversion_matrix *matrix = 
>> get_conversion_matrix_to_argb_u16
>>  (DRM_FORMAT_NV12, param->encoding, param->range);
>>  
>>  argb = argb_u16_from_yuv888(color->yuv.y, color->yuv.u, 
>> color->yuv.v, matrix);
>> diff --git a/drivers/gpu/drm/vkms/vkms_drv.h 
>> b/drivers/gpu/drm/vkms/vkms_drv.h
>> index 393b76e7c694..3d62578499ab 100644
>> --- a/drivers/gpu/drm/vkms/vkms_drv.h
>> +++ b/drivers/gpu/drm/vkms/vkms_drv.h
>> @@ -47,6 +47,10 @@ struct pixel_argb_u16 {
>>  u16 a, r, g, b;
>>  };
>>  
>> +struct pixel_yuv_u8 {
>> +u8 y, u, v;
>> +};
> 
> Can I move this structure in the test itself? As discussed with Pekka, I 
> think it's not a good idea to have such specific `pixel_{fmt}_{size}` for 
> each variant. Leaving it in vkms_drv.h give the idea of "for each new kind 
> of format we have to create a new structure".

Sure, it makes more sense.

Best Regards,
~Arthur Grillo

> 
>> +
>>  struct line_buffer {
>>  size_t n_pixels;
>>  struct pixel_argb_u16 *pixels;
>>
>> -- 
>> 2.43.0
>>
> 


Re: [PATCH v2 6/9] drm/vkms: Add YUV support

2024-03-06 Thread Arthur Grillo



On 04/03/24 13:51, Arthur Grillo wrote:
> 
> 
> On 04/03/24 12:48, Louis Chauvet wrote:
[...]
>>>
>>>> Regarding the YUV part, I don't feel confortable adressing Pekka's 
>>>> comments, would you mind doing it?
>>>
>>> I'm already doing that, how do you want me to send those changes? I reply to
>>> your series, like a did before?
>>
>> Yes, simply reply to my series, so I can rebase everything on the 
>> line-by-line work.
> 
> OK, I will do that.

Hi,

I know that I said that, but it would be very difficult to that with my
b4 workflow. So, I sent a separate series based on the v4:

https://lore.kernel.org/all/20240306-louis-vkms-conv-v1-0-5bfe7d129...@riseup.net/

I hope that it does not difficult things for you.

Best Regards,
~Arthur Grillo

> 
> Best Regards,
> ~Arthur Grillo
> 
>> Kind regards,
>> Louis Chauvet
>>
>>> Best Regards,
>>> ~Arthur Grillo
>>>
>>>>
>>>> Kind regards,
>>>> Louis Chauvet
>>>>
>>>> [...]
>>>>
>>


[PATCH 7/7] drm/vkms: Add how to run the Kunit tests

2024-03-06 Thread Arthur Grillo
Now that we have KUnit tests, add instructions on how to run them.

Signed-off-by: Arthur Grillo 
---
 Documentation/gpu/vkms.rst | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
index 13b866c3617c..5ef5ef2e6a21 100644
--- a/Documentation/gpu/vkms.rst
+++ b/Documentation/gpu/vkms.rst
@@ -89,6 +89,17 @@ You can also run subtests if you do not want to run the 
entire test::
   sudo ./build/tests/kms_flip --run-subtest basic-plain-flip --device 
"sys:/sys/devices/platform/vkms"
   sudo IGT_DEVICE="sys:/sys/devices/platform/vkms" ./build/tests/kms_flip 
--run-subtest basic-plain-flip
 
+Testing With KUnit
+==
+
+KUnit (Kernel unit testing framework) provides a common framework for unit 
tests
+within the Linux kernel.
+More information in ../dev-tools/kunit/index.rst .
+
+To run the VKMS KUnit tests::
+
+  tools/testing/kunit/kunit.py run --kunitconfig=drivers/gpu/drm/vkms/tests
+
 TODO
 
 

-- 
2.43.0



[PATCH 6/7] drm/vkms: Change the gray RGB representation

2024-03-06 Thread Arthur Grillo
Using the drm_fixed calls, this needs to be changed. Which in fact is
more correct, colour.YCbCr_to_RGB() gives 0x8080 for same the yuv
parameters.

Signed-off-by: Arthur Grillo 
---
 drivers/gpu/drm/vkms/tests/vkms_format_test.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/vkms/tests/vkms_format_test.c 
b/drivers/gpu/drm/vkms/tests/vkms_format_test.c
index 66cdd83c3d25..49125cf76eb5 100644
--- a/drivers/gpu/drm/vkms/tests/vkms_format_test.c
+++ b/drivers/gpu/drm/vkms/tests/vkms_format_test.c
@@ -48,7 +48,7 @@ static struct yuv_u8_to_argb_u16_case 
yuv_u8_to_argb_u16_cases[] = {
.n_colors = 6,
.colors = {
{"white", {0xff, 0x80, 0x80}, {0x, 0x, 0x, 
0x}},
-   {"gray",  {0x80, 0x80, 0x80}, {0x, 0x8000, 0x8000, 
0x8000}},
+   {"gray",  {0x80, 0x80, 0x80}, {0x, 0x8080, 0x8080, 
0x8080}},
{"black", {0x00, 0x80, 0x80}, {0x, 0x, 0x, 
0x}},
{"red",   {0x4c, 0x55, 0xff}, {0x, 0x, 0x, 
0x}},
{"green", {0x96, 0x2c, 0x15}, {0x, 0x, 0x, 
0x}},
@@ -71,7 +71,7 @@ static struct yuv_u8_to_argb_u16_case 
yuv_u8_to_argb_u16_cases[] = {
.n_colors = 6,
.colors = {
{"white", {0xeb, 0x80, 0x80}, {0x, 0x, 0x, 
0x}},
-   {"gray",  {0x7e, 0x80, 0x80}, {0x, 0x8000, 0x8000, 
0x8000}},
+   {"gray",  {0x7e, 0x80, 0x80}, {0x, 0x8080, 0x8080, 
0x8080}},
{"black", {0x10, 0x80, 0x80}, {0x, 0x, 0x, 
0x}},
{"red",   {0x51, 0x5a, 0xf0}, {0x, 0x, 0x, 
0x}},
{"green", {0x91, 0x36, 0x22}, {0x, 0x, 0x, 
0x}},
@@ -94,7 +94,7 @@ static struct yuv_u8_to_argb_u16_case 
yuv_u8_to_argb_u16_cases[] = {
.n_colors = 4,
.colors = {
{"white", {0xff, 0x80, 0x80}, {0x, 0x, 0x, 
0x}},
-   {"gray",  {0x80, 0x80, 0x80}, {0x, 0x8000, 0x8000, 
0x8000}},
+   {"gray",  {0x80, 0x80, 0x80}, {0x, 0x8080, 0x8080, 
0x8080}},
{"black", {0x00, 0x80, 0x80}, {0x, 0x, 0x, 
0x}},
{"red",   {0x36, 0x63, 0xff}, {0x, 0x, 0x, 
0x}},
{"green", {0xb6, 0x1e, 0x0c}, {0x, 0x, 0x, 
0x}},
@@ -117,7 +117,7 @@ static struct yuv_u8_to_argb_u16_case 
yuv_u8_to_argb_u16_cases[] = {
.n_colors = 4,
.colors = {
{"white", {0xeb, 0x80, 0x80}, {0x, 0x, 0x, 
0x}},
-   {"gray",  {0x7e, 0x80, 0x80}, {0x, 0x8000, 0x8000, 
0x8000}},
+   {"gray",  {0x7e, 0x80, 0x80}, {0x, 0x8080, 0x8080, 
0x8080}},
{"black", {0x10, 0x80, 0x80}, {0x, 0x, 0x, 
0x}},
{"red",   {0x3f, 0x66, 0xf0}, {0x, 0x, 0x, 
0x}},
{"green", {0xad, 0x2a, 0x1a}, {0x, 0x, 0x, 
0x}},
@@ -140,7 +140,7 @@ static struct yuv_u8_to_argb_u16_case 
yuv_u8_to_argb_u16_cases[] = {
.n_colors = 4,
.colors = {
{"white", {0xff, 0x80, 0x80}, {0x, 0x, 0x, 
0x}},
-   {"gray",  {0x80, 0x80, 0x80}, {0x, 0x8000, 0x8000, 
0x8000}},
+   {"gray",  {0x80, 0x80, 0x80}, {0x, 0x8080, 0x8080, 
0x8080}},
{"black", {0x00, 0x80, 0x80}, {0x, 0x, 0x, 
0x}},
{"red",   {0x43, 0x5c, 0xff}, {0x, 0x, 0x, 
0x}},
{"green", {0xad, 0x24, 0x0b}, {0x, 0x, 0x, 
0x}},
@@ -163,7 +163,7 @@ static struct yuv_u8_to_argb_u16_case 
yuv_u8_to_argb_u16_cases[] = {
.n_colors = 4,
.colors = {
{"white", {0xeb, 0x80, 0x80}, {0x, 0x, 0x, 
0x}},
-   {"gray",  {0x7e, 0x80, 0x80}, {0x, 0x8000, 0x8000, 
0x8000}},
+   {"gray",  {0x7e, 0x80, 0x80}, {0x, 0x8080, 0x8080, 
0x8080}},
{"black", {0x10, 0x80, 0x80}, {0x, 0x, 0x, 
0x}},
{"red",   {0x4a, 0x61, 0xf0}, {0x, 0x, 0x, 
0x}},
{"green", {0xa4, 0x2f, 0x19}, {0x, 0x, 0x, 
0x}},

-- 
2.43.0



[PATCH 5/7] drm/vkms: Add comments to format tests

2024-03-06 Thread Arthur Grillo
Signed-off-by: Arthur Grillo 
---
 drivers/gpu/drm/vkms/tests/vkms_format_test.c | 67 +++
 1 file changed, 67 insertions(+)

diff --git a/drivers/gpu/drm/vkms/tests/vkms_format_test.c 
b/drivers/gpu/drm/vkms/tests/vkms_format_test.c
index 3522ecee960f..66cdd83c3d25 100644
--- a/drivers/gpu/drm/vkms/tests/vkms_format_test.c
+++ b/drivers/gpu/drm/vkms/tests/vkms_format_test.c
@@ -24,7 +24,24 @@ struct yuv_u8_to_argb_u16_case {
} colors[TEST_BUFF_SIZE];
 };
 
+/*
+ * The YUV color representation were acquired via the colour python framework.
+ * Below are the function calls used for generating each case.
+ *
+ * for more information got to the docs:
+ * https://colour.readthedocs.io/en/master/generated/colour.RGB_to_YCbCr.html
+ */
 static struct yuv_u8_to_argb_u16_case yuv_u8_to_argb_u16_cases[] = {
+   /*
+* colour.RGB_to_YCbCr(,
+* K=colour.WEIGHTS_YCBCR["ITU-R BT.601"],
+* in_bits = 16,
+* in_legal = False,
+* in_int = True,
+* out_bits = 8,
+* out_legal = False,
+* out_int = True)
+*/
{
.encoding = DRM_COLOR_YCBCR_BT601,
.range = DRM_COLOR_YCBCR_FULL_RANGE,
@@ -38,6 +55,16 @@ static struct yuv_u8_to_argb_u16_case 
yuv_u8_to_argb_u16_cases[] = {
{"blue",  {0x1d, 0xff, 0x6b}, {0x, 0x, 0x, 
0x}},
},
},
+   /*
+* colour.RGB_to_YCbCr(,
+* K=colour.WEIGHTS_YCBCR["ITU-R BT.601"],
+* in_bits = 16,
+* in_legal = False,
+* in_int = True,
+* out_bits = 8,
+* out_legal = True,
+* out_int = True)
+*/
{
.encoding = DRM_COLOR_YCBCR_BT601,
.range = DRM_COLOR_YCBCR_LIMITED_RANGE,
@@ -51,6 +78,16 @@ static struct yuv_u8_to_argb_u16_case 
yuv_u8_to_argb_u16_cases[] = {
{"blue",  {0x29, 0xf0, 0x6e}, {0x, 0x, 0x, 
0x}},
},
},
+   /*
+* colour.RGB_to_YCbCr(,
+* K=colour.WEIGHTS_YCBCR["ITU-R BT.709"],
+* in_bits = 16,
+* in_legal = False,
+* in_int = True,
+* out_bits = 8,
+* out_legal = False,
+* out_int = True)
+*/
{
.encoding = DRM_COLOR_YCBCR_BT709,
.range = DRM_COLOR_YCBCR_FULL_RANGE,
@@ -64,6 +101,16 @@ static struct yuv_u8_to_argb_u16_case 
yuv_u8_to_argb_u16_cases[] = {
{"blue",  {0x12, 0xff, 0x74}, {0x, 0x, 0x, 
0x}},
},
},
+   /*
+* colour.RGB_to_YCbCr(,
+* K=colour.WEIGHTS_YCBCR["ITU-R BT.709"],
+* in_bits = 16,
+* int_legal = False,
+* in_int = True,
+* out_bits = 8,
+* out_legal = True,
+* out_int = True)
+*/
{
.encoding = DRM_COLOR_YCBCR_BT709,
.range = DRM_COLOR_YCBCR_LIMITED_RANGE,
@@ -77,6 +124,16 @@ static struct yuv_u8_to_argb_u16_case 
yuv_u8_to_argb_u16_cases[] = {
{"blue",  {0x20, 0xf0, 0x76}, {0x, 0x, 0x, 
0x}},
},
},
+   /*
+* colour.RGB_to_YCbCr(,
+* K=colour.WEIGHTS_YCBCR["ITU-R BT.2020"],
+* in_bits = 16,
+* in_legal = False,
+* in_int = True,
+* out_bits = 8,
+* out_legal = False,
+* out_int = True)
+*/
{
.encoding = DRM_COLOR_YCBCR_BT2020,
.range = DRM_COLOR_YCBCR_FULL_RANGE,
@@ -90,6 +147,16 @@ static struct yuv_u8_to_argb_u16_case 
yuv_u8_to_argb_u16_cases[] = {
{"blue",  {0x0f, 0xff, 0x76}, {0x, 0x, 0x, 
0x}},
},
},
+   /*
+* colour.RGB_to_YCbCr(,
+* K=colour.WEIGHTS_YCBCR["ITU-R BT.2020"],
+* in_bits = 16,
+* in_legal = False,
+* in_int = True,
+* out_bits = 8,
+* out_legal = True,
+

[PATCH 4/7] drm/vkms: Fix compilation issues

2024-03-06 Thread Arthur Grillo
Signed-off-by: Arthur Grillo 
---
 drivers/gpu/drm/vkms/tests/vkms_format_test.c | 2 +-
 drivers/gpu/drm/vkms/vkms_drv.h   | 4 
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vkms/tests/vkms_format_test.c 
b/drivers/gpu/drm/vkms/tests/vkms_format_test.c
index 4636b013602f..3522ecee960f 100644
--- a/drivers/gpu/drm/vkms/tests/vkms_format_test.c
+++ b/drivers/gpu/drm/vkms/tests/vkms_format_test.c
@@ -113,7 +113,7 @@ static void vkms_format_test_yuv_u8_to_argb_u16(struct 
kunit *test)
for (size_t i = 0; i < param->n_colors; i++) {
const struct format_pair *color = >colors[i];
 
-   const struct conversion_matrix *matrix = 
get_conversion_matrix_to_argb_u16
+   struct conversion_matrix *matrix = 
get_conversion_matrix_to_argb_u16
(DRM_FORMAT_NV12, param->encoding, param->range);
 
argb = argb_u16_from_yuv888(color->yuv.y, color->yuv.u, 
color->yuv.v, matrix);
diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index 393b76e7c694..3d62578499ab 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -47,6 +47,10 @@ struct pixel_argb_u16 {
u16 a, r, g, b;
 };
 
+struct pixel_yuv_u8 {
+   u8 y, u, v;
+};
+
 struct line_buffer {
size_t n_pixels;
struct pixel_argb_u16 *pixels;

-- 
2.43.0



[PATCH 3/7] drm/vkmm: Use drm_fixed api

2024-03-06 Thread Arthur Grillo
With the new 32.32 values it makes more sense to use drm_fixed functions
than trying to recreate the wheel.

Signed-off-by: Arthur Grillo 
---
 drivers/gpu/drm/vkms/vkms_formats.c | 54 +++--
 1 file changed, 28 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_formats.c 
b/drivers/gpu/drm/vkms/vkms_formats.c
index 55ed3f598bd7..adde53cdea26 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.c
+++ b/drivers/gpu/drm/vkms/vkms_formats.c
@@ -191,32 +191,34 @@ VISIBLE_IF_KUNIT struct pixel_argb_u16 
argb_u16_from_yuv888(u8 y, u8 cb, u8 cr,
  struct conversion_matrix 
*matrix)
 {
u8 r, g, b;
-   s64 y_16, cb_16, cr_16;
-   s64 r_16, g_16, b_16;
-
-   y_16 = y - matrix->y_offset;
-   cb_16 = cb - 128;
-   cr_16 = cr - 128;
-
-   r_16 = matrix->matrix[0][0] * y_16 + matrix->matrix[0][1] * cb_16 +
-  matrix->matrix[0][2] * cr_16;
-   g_16 = matrix->matrix[1][0] * y_16 + matrix->matrix[1][1] * cb_16 +
-  matrix->matrix[1][2] * cr_16;
-   b_16 = matrix->matrix[2][0] * y_16 + matrix->matrix[2][1] * cb_16 +
-  matrix->matrix[2][2] * cr_16;
-
-   // rounding the values
-   r_16 = r_16 + (1LL << (CONVERSION_MATRIX_FLOAT_DEPTH - 4));
-   g_16 = g_16 + (1LL << (CONVERSION_MATRIX_FLOAT_DEPTH - 4));
-   b_16 = b_16 + (1LL << (CONVERSION_MATRIX_FLOAT_DEPTH - 4));
-
-   r_16 = clamp(r_16, 0, (1LL << (CONVERSION_MATRIX_FLOAT_DEPTH + 8)) - 1);
-   g_16 = clamp(g_16, 0, (1LL << (CONVERSION_MATRIX_FLOAT_DEPTH + 8)) - 1);
-   b_16 = clamp(b_16, 0, (1LL << (CONVERSION_MATRIX_FLOAT_DEPTH + 8)) - 1);
-
-   r = r_16 >> CONVERSION_MATRIX_FLOAT_DEPTH;
-   g = g_16 >> CONVERSION_MATRIX_FLOAT_DEPTH;
-   b = b_16 >> CONVERSION_MATRIX_FLOAT_DEPTH;
+   s64 fp_y, fp_cb, fp_cr;
+   s64 fp_r, fp_g, fp_b;
+
+   fp_y = y - matrix->y_offset;
+   fp_cb = cb - 128;
+   fp_cr = cr - 128;
+
+   fp_y = drm_int2fixp(fp_y);
+   fp_cb = drm_int2fixp(fp_cb);
+   fp_cr = drm_int2fixp(fp_cr);
+
+   fp_r = drm_fixp_mul(matrix->matrix[0][0], fp_y) +
+  drm_fixp_mul(matrix->matrix[0][1], fp_cb) +
+  drm_fixp_mul(matrix->matrix[0][2], fp_cr);
+   fp_g = drm_fixp_mul(matrix->matrix[1][0], fp_y) +
+  drm_fixp_mul(matrix->matrix[1][1], fp_cb) +
+  drm_fixp_mul(matrix->matrix[1][2], fp_cr);
+   fp_b = drm_fixp_mul(matrix->matrix[2][0], fp_y) +
+  drm_fixp_mul(matrix->matrix[2][1], fp_cb) +
+  drm_fixp_mul(matrix->matrix[2][2], fp_cr);
+
+   fp_r = drm_fixp2int_round(fp_r);
+   fp_g = drm_fixp2int_round(fp_g);
+   fp_b = drm_fixp2int_round(fp_b);
+
+   r = clamp(fp_r, 0, 0xff);
+   g = clamp(fp_g, 0, 0xff);
+   b = clamp(fp_b, 0, 0xff);
 
return argb_u16_from_u(255, r, g, b);
 }

-- 
2.43.0



[PATCH 2/7] drm/vkms: Add comments

2024-03-06 Thread Arthur Grillo
Signed-off-by: Arthur Grillo 
---
 drivers/gpu/drm/vkms/vkms_formats.c | 47 +
 1 file changed, 47 insertions(+)

diff --git a/drivers/gpu/drm/vkms/vkms_formats.c 
b/drivers/gpu/drm/vkms/vkms_formats.c
index 44d9b9b3bdc3..55ed3f598bd7 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.c
+++ b/drivers/gpu/drm/vkms/vkms_formats.c
@@ -577,6 +577,18 @@ get_conversion_matrix_to_argb_u16(u32 format, enum 
drm_color_encoding encoding,
},
.y_offset = 0,
};
+
+   /*
+* Those matrixies were generated using the colour python framework
+*
+* Below are the function calls used to generate eac matrix, go to
+* 
https://colour.readthedocs.io/en/develop/generated/colour.matrix_YCbCr.html
+* for more info:
+*
+* numpy.around(colour.matrix_YCbCr(K=colour.WEIGHTS_YCBCR["ITU-R 
BT.601"],
+*  is_legal = False,
+*  bits = 8) * 2**32).astype(int)
+*/
static struct conversion_matrix yuv_bt601_full = {
.matrix = {
{ 4294967296, 0,   6021544149 },
@@ -585,6 +597,12 @@ get_conversion_matrix_to_argb_u16(u32 format, enum 
drm_color_encoding encoding,
},
.y_offset = 0,
};
+
+   /*
+* numpy.around(colour.matrix_YCbCr(K=colour.WEIGHTS_YCBCR["ITU-R 
BT.601"],
+*  is_legal = True,
+*  bits = 8) * 2**32).astype(int)
+*/
static struct conversion_matrix yuv_bt601_limited = {
.matrix = {
{ 5020601039, 0,   6881764740 },
@@ -593,6 +611,12 @@ get_conversion_matrix_to_argb_u16(u32 format, enum 
drm_color_encoding encoding,
},
.y_offset = 16,
};
+
+   /*
+* numpy.around(colour.matrix_YCbCr(K=colour.WEIGHTS_YCBCR["ITU-R 
BT.709"],
+*  is_legal = False,
+*  bits = 8) * 2**32).astype(int)
+*/
static struct conversion_matrix yuv_bt709_full = {
.matrix = {
{ 4294967296, 0,  6763714498 },
@@ -601,6 +625,12 @@ get_conversion_matrix_to_argb_u16(u32 format, enum 
drm_color_encoding encoding,
},
.y_offset = 0,
};
+
+   /*
+* numpy.around(colour.matrix_YCbCr(K=colour.WEIGHTS_YCBCR["ITU-R 
BT.709"],
+*  is_legal = True,
+*  bits = 8) * 2**32).astype(int)
+*/
static struct conversion_matrix yuv_bt709_limited = {
.matrix = {
{ 5020601039, 0,  7729959424 },
@@ -609,6 +639,12 @@ get_conversion_matrix_to_argb_u16(u32 format, enum 
drm_color_encoding encoding,
},
.y_offset = 16,
};
+
+   /*
+* numpy.around(colour.matrix_YCbCr(K=colour.WEIGHTS_YCBCR["ITU-R 
BT.2020"],
+*  is_legal = False,
+*  bits = 8) * 2**32).astype(int)
+*/
static struct conversion_matrix yuv_bt2020_full = {
.matrix = {
{ 4294967296, 0,  658775 },
@@ -617,6 +653,12 @@ get_conversion_matrix_to_argb_u16(u32 format, enum 
drm_color_encoding encoding,
},
.y_offset = 0,
};
+
+   /*
+* numpy.around(colour.matrix_YCbCr(K=colour.WEIGHTS_YCBCR["ITU-R 
BT.2020"],
+*  is_legal = True,
+*  bits = 8) * 2**32).astype(int)
+*/
static struct conversion_matrix yuv_bt2020_limited = {
.matrix = {
{ 5020601039, 0,  7238124312 },
@@ -625,6 +667,11 @@ get_conversion_matrix_to_argb_u16(u32 format, enum 
drm_color_encoding encoding,
},
.y_offset = 16,
};
+
+   /*
+* The next matrices are just the previous ones, but with the first and
+* second columns swapped
+*/
static struct conversion_matrix yvu_bt601_full = {
.matrix = {
{ 4294967296, 6021544149,  0 },

-- 
2.43.0



[PATCH 1/7] drm: Fix drm_fixp2int_round() making it add 0.5

2024-03-06 Thread Arthur Grillo
As well noted by Pekka[1], the rounding of drm_fixp2int_round is wrong.
To round a number, you need to add 0.5 to the number and floor that,
drm_fixp2int_round() is adding 0.076. Make it add 0.5.

[1]: 
https://lore.kernel.org/all/20240301135327.22efe0dd.pekka.paala...@collabora.com/

Suggested-by: Pekka Paalanen 
Signed-off-by: Arthur Grillo 
---
 include/drm/drm_fixed.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/drm/drm_fixed.h b/include/drm/drm_fixed.h
index 0c9f917a4d4b..de3a79909ac9 100644
--- a/include/drm/drm_fixed.h
+++ b/include/drm/drm_fixed.h
@@ -90,7 +90,7 @@ static inline int drm_fixp2int(s64 a)
 
 static inline int drm_fixp2int_round(s64 a)
 {
-   return drm_fixp2int(a + (1 << (DRM_FIXED_POINT_HALF - 1)));
+   return drm_fixp2int(a + DRM_FIXED_ONE / 2);
 }
 
 static inline int drm_fixp2int_ceil(s64 a)

-- 
2.43.0



[PATCH 0/7] Additions to "Reimplement line-per-line pixel conversion for plane reading" series

2024-03-06 Thread Arthur Grillo
These are some patches that add some fixes/features to the series by
Louis Chauvet[1], it was based on top of the patches from v4.

Patches #2 and #3 should be amended to "[PATCH v4 11/14] drm/vkms: Add
YUV support". To make patch #3 work, we need patch #1. So, please, add
it before the patch that #2 and #3 amend to.

Patches #4 to #6 should be amended to "[PATCH v4 14/14] drm/vkms: Create
KUnit tests for YUV conversions". While doing the additions, I found
some compilation issues, so I fixed them (patch #4). That's when I
thought that it would be good to add some documentation on how to run
them (patch #7), this patch should be added to the series as new patch.

[1]: https://lore.kernel.org/r/20240304-yuv-v4-0-76beac8e9...@bootlin.com

To: Rodrigo Siqueira 
To: Melissa Wen 
To: Maíra Canal 
To: Haneen Mohammed 
To: Daniel Vetter 
To: Maarten Lankhorst 
To: Maxime Ripard 
To: Thomas Zimmermann 
To: David Airlie 
To: arthurgri...@riseup.net
To: Jonathan Corbet 
To: pekka.paala...@haloniitty.fi
To: Louis Chauvet 
Cc: dri-devel@lists.freedesktop.org
Cc: linux-ker...@vger.kernel.org
Cc: jeremie.dautheri...@bootlin.com
Cc: miquel.ray...@bootlin.com
Cc: thomas.petazz...@bootlin.com
Cc: seanp...@google.com
Cc: marc...@google.com
Cc: nicolejade...@google.com

Signed-off-by: Arthur Grillo 
---
Arthur Grillo (7):
  drm: Fix drm_fixp2int_round() making it add 0.5
  drm/vkms: Add comments
  drm/vkmm: Use drm_fixed api
  drm/vkms: Fix compilation issues
  drm/vkms: Add comments to format tests
  drm/vkms: Change the gray RGB representation
  drm/vkms: Add how to run the Kunit tests

 Documentation/gpu/vkms.rst|  11 +++
 drivers/gpu/drm/vkms/tests/vkms_format_test.c |  81 +++--
 drivers/gpu/drm/vkms/vkms_drv.h   |   4 +
 drivers/gpu/drm/vkms/vkms_formats.c   | 101 +++---
 include/drm/drm_fixed.h   |   2 +-
 5 files changed, 165 insertions(+), 34 deletions(-)
---
base-commit: 9658aba38ae9f3f3068506c9c8e93e85b500fcb4
change-id: 20240306-louis-vkms-conv-61362ff12ab8

Best regards,
-- 
Arthur Grillo 



Re: [PATCH v2 6/9] drm/vkms: Add YUV support

2024-03-04 Thread Arthur Grillo



On 04/03/24 12:48, Louis Chauvet wrote:
> [...]
> 
>>> @arthur, I will submit a v4 with this:
>>> - matrix selection in plane_atomic_update (so it's selected only once)
>>> - s64 numbers for matrix
>>> - avoiding multiple loop implementation by switching matrix columns
>>
>> This looks good to me.
>>
>>>
>>> Regarding the YUV part, I don't feel confortable adressing Pekka's 
>>> comments, would you mind doing it?
>>
>> I'm already doing that, how do you want me to send those changes? I reply to
>> your series, like a did before?
> 
> Yes, simply reply to my series, so I can rebase everything on the 
> line-by-line work.

OK, I will do that.

Best Regards,
~Arthur Grillo

> Kind regards,
> Louis Chauvet
> 
>> Best Regards,
>> ~Arthur Grillo
>>
>>>
>>> Kind regards,
>>> Louis Chauvet
>>>
>>> [...]
>>>
> 


Re: [PATCH v2 6/9] drm/vkms: Add YUV support

2024-03-04 Thread Arthur Grillo



On 04/03/24 12:28, Louis Chauvet wrote:
> Le 29/02/24 - 14:12, Pekka Paalanen a écrit :
>> On Wed, 28 Feb 2024 22:52:09 -0300
>> Arthur Grillo  wrote:
>>
>>> On 27/02/24 17:01, Arthur Grillo wrote:
>>>>
>>>>
>>>> On 27/02/24 12:02, Louis Chauvet wrote:  
>>>>> Hi Pekka,
>>>>>
>>>>> For all the comment related to the conversion part, maybe Arthur have an 
>>>>> opinion on it, I took his patch as a "black box" (I did not want to 
>>>>> break (and debug) it).
>>>>>
>>>>> Le 26/02/24 - 14:19, Pekka Paalanen a écrit :  
>>>>>> On Fri, 23 Feb 2024 12:37:26 +0100
>>>>>> Louis Chauvet  wrote:
>>>>>>  
>>>>>>> From: Arthur Grillo 
>>>>>>>
>>>>>>> Add support to the YUV formats bellow:
>>>>>>>
>>>>>>> - NV12
>>>>>>> - NV16
>>>>>>> - NV24
>>>>>>> - NV21
>>>>>>> - NV61
>>>>>>> - NV42
>>>>>>> - YUV420
>>>>>>> - YUV422
>>>>>>> - YUV444
>>>>>>> - YVU420
>>>>>>> - YVU422
>>>>>>> - YVU444
>>>>>>>
>>>>>>> The conversion matrices of each encoding and range were obtained by
>>>>>>> rounding the values of the original conversion matrices multiplied by
>>>>>>> 2^8. This is done to avoid the use of fixed point operations.
>>>>>>>
>>>>>>> Signed-off-by: Arthur Grillo 
>>>>>>> [Louis Chauvet: Adapted Arthur's work and implemented the read_line_t
>>>>>>> callbacks for yuv formats]
>>>>>>> Signed-off-by: Louis Chauvet 
>>>>>>> ---
>>>>>>>  drivers/gpu/drm/vkms/vkms_composer.c |   2 +-
>>>>>>>  drivers/gpu/drm/vkms/vkms_drv.h  |   6 +-
>>>>>>>  drivers/gpu/drm/vkms/vkms_formats.c  | 289 
>>>>>>> +--
>>>>>>>  drivers/gpu/drm/vkms/vkms_formats.h  |   4 +
>>>>>>>  drivers/gpu/drm/vkms/vkms_plane.c|  14 +-
>>>>>>>  5 files changed, 295 insertions(+), 20 deletions(-)
>>>>>>>
>>>>>>> diff --git a/drivers/gpu/drm/vkms/vkms_composer.c 
>>>>>>> b/drivers/gpu/drm/vkms/vkms_composer.c
>>>>>>> index e555bf9c1aee..54fc5161d565 100644
>>>>>>> --- a/drivers/gpu/drm/vkms/vkms_composer.c
>>>>>>> +++ b/drivers/gpu/drm/vkms/vkms_composer.c
>>>>>>> @@ -312,7 +312,7 @@ static void blend(struct vkms_writeback_job *wb,
>>>>>>>  * buffer [1]
>>>>>>>  */
>>>>>>> current_plane->pixel_read_line(
>>>>>>> -   current_plane->frame_info,
>>>>>>> +   current_plane,
>>>>>>> x_start,
>>>>>>> y_start,
>>>>>>> direction,
>>>>>>> diff --git a/drivers/gpu/drm/vkms/vkms_drv.h 
>>>>>>> b/drivers/gpu/drm/vkms/vkms_drv.h
>>>>>>> index ccc5be009f15..a4f6456cb971 100644
>>>>>>> --- a/drivers/gpu/drm/vkms/vkms_drv.h
>>>>>>> +++ b/drivers/gpu/drm/vkms/vkms_drv.h
>>>>>>> @@ -75,6 +75,8 @@ enum pixel_read_direction {
>>>>>>> READ_RIGHT
>>>>>>>  };
>>>>>>>  
>>>>>>> +struct vkms_plane_state;
>>>>>>> +
>>>>>>>  /**
>>>>>>>  <<<<<<< HEAD
>>>>>>>   * typedef pixel_read_line_t - These functions are used to read a 
>>>>>>> pixel line in the source frame,
>>>>>>> @@ -87,8 +89,8 @@ enum pixel_read_direction {
>>>>>>>   * @out_pixel: Pointer where to write the pixel value. Pixels will be 
>>>>>>> written between x_start and
>>>>>>>   *  x_end.
>>>>>>>   */
>>>>>>> -typedef void (*pixel_read_line_t)(struct vkms_frame_info *frame_info,

Re: [PATCH v2 6/9] drm/vkms: Add YUV support

2024-03-02 Thread Arthur Grillo



On 01/03/24 08:53, Pekka Paalanen wrote:
> On Thu, 29 Feb 2024 14:57:06 -0300
> Arthur Grillo  wrote:
> 
>> On 29/02/24 09:12, Pekka Paalanen wrote:
>>> On Wed, 28 Feb 2024 22:52:09 -0300
>>> Arthur Grillo  wrote:
>>>   
>>>> On 27/02/24 17:01, Arthur Grillo wrote:  
>>>>>
>>>>>
>>>>> On 27/02/24 12:02, Louis Chauvet wrote:
>>>>>> Hi Pekka,
>>>>>>
>>>>>> For all the comment related to the conversion part, maybe Arthur have an 
>>>>>> opinion on it, I took his patch as a "black box" (I did not want to 
>>>>>> break (and debug) it).
>>>>>>
>>>>>> Le 26/02/24 - 14:19, Pekka Paalanen a écrit :
>>>>>>> On Fri, 23 Feb 2024 12:37:26 +0100
>>>>>>> Louis Chauvet  wrote:
>>>>>>>
>>>>>>>> From: Arthur Grillo 
>>>>>>>>
>>>>>>>> Add support to the YUV formats bellow:
>>>>>>>>
>>>>>>>> - NV12
>>>>>>>> - NV16
>>>>>>>> - NV24
>>>>>>>> - NV21
>>>>>>>> - NV61
>>>>>>>> - NV42
>>>>>>>> - YUV420
>>>>>>>> - YUV422
>>>>>>>> - YUV444
>>>>>>>> - YVU420
>>>>>>>> - YVU422
>>>>>>>> - YVU444
>>>>>>>>
>>>>>>>> The conversion matrices of each encoding and range were obtained by
>>>>>>>> rounding the values of the original conversion matrices multiplied by
>>>>>>>> 2^8. This is done to avoid the use of fixed point operations.
>>>>>>>>
>>>>>>>> Signed-off-by: Arthur Grillo 
>>>>>>>> [Louis Chauvet: Adapted Arthur's work and implemented the read_line_t
>>>>>>>> callbacks for yuv formats]
>>>>>>>> Signed-off-by: Louis Chauvet 
>>>>>>>> ---
>>>>>>>>  drivers/gpu/drm/vkms/vkms_composer.c |   2 +-
>>>>>>>>  drivers/gpu/drm/vkms/vkms_drv.h  |   6 +-
>>>>>>>>  drivers/gpu/drm/vkms/vkms_formats.c  | 289 
>>>>>>>> +--
>>>>>>>>  drivers/gpu/drm/vkms/vkms_formats.h  |   4 +
>>>>>>>>  drivers/gpu/drm/vkms/vkms_plane.c|  14 +-
>>>>>>>>  5 files changed, 295 insertions(+), 20 deletions(-)
> 
> ...
> 
>>>> diff --git a/drivers/gpu/drm/vkms/tests/vkms_format_test.c 
>>>> b/drivers/gpu/drm/vkms/tests/vkms_format_test.c
>>>> index f66584549827..4cee3c2d8d84 100644
>>>> --- a/drivers/gpu/drm/vkms/tests/vkms_format_test.c
>>>> +++ b/drivers/gpu/drm/vkms/tests/vkms_format_test.c
>>>> @@ -59,7 +59,7 @@ static struct yuv_u8_to_argb_u16_case 
>>>> yuv_u8_to_argb_u16_cases[] = {
>>>>{"white", {0xff, 0x80, 0x80}, {0x, 0x, 0x, 
>>>> 0x}},
>>>>{"gray",  {0x80, 0x80, 0x80}, {0x, 0x8000, 0x8000, 
>>>> 0x8000}},
>>>>{"black", {0x00, 0x80, 0x80}, {0x, 0x, 0x, 
>>>> 0x}},
>>>> -  {"red",   {0x35, 0x63, 0xff}, {0x, 0x, 0x, 
>>>> 0x}},
>>>> +  {"red",   {0x36, 0x63, 0xff}, {0x, 0x, 0x, 
>>>> 0x}},
>>>>{"green", {0xb6, 0x1e, 0x0c}, {0x, 0x, 0x, 
>>>> 0x}},
>>>>{"blue",  {0x12, 0xff, 0x74}, {0x, 0x, 0x, 
>>>> 0x}},
>>>>},
>>>> diff --git a/drivers/gpu/drm/vkms/vkms_formats.c 
>>>> b/drivers/gpu/drm/vkms/vkms_formats.c
>>>> index e06bbd7c0a67..043f23dbf80d 100644
>>>> --- a/drivers/gpu/drm/vkms/vkms_formats.c
>>>> +++ b/drivers/gpu/drm/vkms/vkms_formats.c
>>>> @@ -121,10 +121,12 @@ static void RGB565_to_argb_u16(u8 **src_pixels, 
>>>> struct pixel_argb_u16 *out_pixel
>>>>out_pixel->b = drm_fixp2int_round(drm_fixp_mul(fp_b, fp_rb_ratio));
>>>>  }
>>>>  
>>>> -static void ycbcr2rgb(const s16 m[3][3], u8 y, u8 cb, u8 cr, u8 y_offset, 
>

Re: [PATCH v2 0/7] Add YUV formats to VKMS

2024-02-29 Thread Arthur Grillo



On 29/02/24 14:52, Sebastian Wick wrote:
> On Wed, Feb 28, 2024 at 08:42:41PM -0300, Arthur Grillo wrote:
>>
>>
>> On 15/01/24 12:06, Sebastian Wick wrote:
>>> On Wed, Jan 10, 2024 at 02:44:00PM -0300, Arthur Grillo wrote:
>>>> This patchset aims to add support for additional buffer YUV formats.
>>>> More specifically, it adds support to:
>>>>
>>>> Semi-planar formats:
>>>>
>>>> - NV12
>>>> - NV16
>>>> - NV24
>>>> - NV21
>>>> - NV61
>>>> - NV42
>>>>
>>>> Planar formats:
>>>>
>>>> - YUV440
>>>> - YUV422
>>>> - YUV444
>>>> - YVU440
>>>> - YVU422
>>>> - YVU444
>>>>
>>>> These formats have more than one plane, and most have chroma
>>>> subsampling. These properties don't have support on VKMS, so I had to
>>>> work on this before.
>>>>
>>>> To ensure that the conversions from YUV to RGB are working, I wrote a
>>>> KUnit test. As the work from Harry on creating KUnit tests on VKMS[1] is
>>>> not yet merged, I took the setup part (Kconfig entry and .kunitfile)
>>>> from it.
>>>>
>>>> Furthermore, I couldn't find any sources with the conversion matrices,
>>>> so I had to work out the values myself based on the ITU papers[2][3][4].
>>>> So, I'm not 100% sure if the values are accurate. I'd appreciate some
>>>> input if anyone has more knowledge in this area.
>>>
>>> H.273 CICP [1] has concise descriptions of the required values for most
>>> widely used formats and the colour python framework [2] also can be used
>>> to quickly get to the desired information most of the time.
>>>
>>> [1]: https://www.itu.int/rec/T-REC-H.273
>>> [2]: https://www.colour-science.org/
>>
>> I want to thank you for suggesting the python framework, it helped
>> immensely now that I'm changing the precision from 8-bit to 32-bit[1].
>>
>> If I'd known about this framework while developing this patch, I
>> would've saved myself a few weeks of pain and suffering recreating a
>> part of this library XD.
> 
> I'm glad this is useful for you! We also used it for our color-and-hdr
> project https://gitlab.freedesktop.org/pq/color-and-hdr/.

Cool project! I'll be sure to give look!

Best Regards,
~Arthur Grillo

> 
>> [1]: 
>> https://lore.kernel.org/all/b23da076-0bfb-48b2-9386-383a6dec1...@riseup.net/
>>
>> Best Regards,
>> ~Arthur Grillo
>>
>>>
>>>> Also, I used two IGT tests to check if the formats were having a correct
>>>> conversion (all with the --extended flag):
>>>>
>>>> - kms_plane@pixel_format
>>>> - kms_plane@pixel_format_source_clamping.
>>>>
>>>> The nonsubsampled formats don't have support on IGT, so I sent a patch
>>>> fixing this[5].
>>>>
>>>> Currently, this patchset does not add those formats to the writeback, as
>>>> it would require a rewrite of how the conversions are done (similar to
>>>> what was done on a previous patch[6]). So, I would like to review this
>>>> patchset before I start the work on this other part.
>>>>
>>>> [1]: 
>>>> https://lore.kernel.org/all/20231108163647.106853-5-harry.wentl...@amd.com/
>>>> [2]: https://www.itu.int/rec/R-REC-BT.601-7-201103-I/en
>>>> [3]: https://www.itu.int/rec/R-REC-BT.709-6-201506-I/en
>>>> [4]: https://www.itu.int/rec/R-REC-BT.2020-2-201510-I/en
>>>> [5]: 
>>>> https://lists.freedesktop.org/archives/igt-dev/2024-January/066937.html
>>>> [6]: 
>>>> https://lore.kernel.org/dri-devel/20230414135151.75975-2-mca...@igalia.com/
>>>>
>>>> Signed-off-by: Arthur Grillo 
>>>> ---
>>>> Changes in v2:
>>>> - Use EXPORT_SYMBOL_IF_KUNIT instead of including the .c test
>>>>   file (Maxime)
>>>> - Link to v1: 
>>>> https://lore.kernel.org/r/20240105-vkms-yuv-v1-0-34c4cd345...@riseup.net
>>>>
>>>> ---
>>>> Arthur Grillo (7):
>>>>   drm/vkms: Use drm_frame directly
>>>>   drm/vkms: Add support for multy-planar framebuffers
>>>>   drm/vkms: Add range and encoding properties to pixel_read function
>>>>   drm/vkms: Add chroma subsampling
>>>>   drm/vkms: Add YUV support
>>>>   drm/vkms: Drop YUV formats TODO
>>>>   drm/vkms: Create KUnit tests for YUV conversions
>>>>
>>>>  Documentation/gpu/vkms.rst|   3 +-
>>>>  drivers/gpu/drm/vkms/Kconfig  |  15 ++
>>>>  drivers/gpu/drm/vkms/Makefile |   1 +
>>>>  drivers/gpu/drm/vkms/tests/.kunitconfig   |   4 +
>>>>  drivers/gpu/drm/vkms/tests/Makefile   |   3 +
>>>>  drivers/gpu/drm/vkms/tests/vkms_format_test.c | 156 
>>>>  drivers/gpu/drm/vkms/vkms_drv.h   |   6 +-
>>>>  drivers/gpu/drm/vkms/vkms_formats.c   | 247 
>>>> ++
>>>>  drivers/gpu/drm/vkms/vkms_formats.h   |   9 +
>>>>  drivers/gpu/drm/vkms/vkms_plane.c |  26 ++-
>>>>  drivers/gpu/drm/vkms/vkms_writeback.c |   5 -
>>>>  11 files changed, 426 insertions(+), 49 deletions(-)
>>>> ---
>>>> base-commit: eeb8e8d9f124f279e80ae679f4ba6e822ce4f95f
>>>> change-id: 20231226-vkms-yuv-6f7859f32df8
>>>>
>>>> Best regards,
>>>> -- 
>>>> Arthur Grillo 
>>>>
>>>
>>
> 


Re: [PATCH v2 6/9] drm/vkms: Add YUV support

2024-02-29 Thread Arthur Grillo



On 29/02/24 09:12, Pekka Paalanen wrote:
> On Wed, 28 Feb 2024 22:52:09 -0300
> Arthur Grillo  wrote:
> 
>> On 27/02/24 17:01, Arthur Grillo wrote:
>>>
>>>
>>> On 27/02/24 12:02, Louis Chauvet wrote:  
>>>> Hi Pekka,
>>>>
>>>> For all the comment related to the conversion part, maybe Arthur have an 
>>>> opinion on it, I took his patch as a "black box" (I did not want to 
>>>> break (and debug) it).
>>>>
>>>> Le 26/02/24 - 14:19, Pekka Paalanen a écrit :  
>>>>> On Fri, 23 Feb 2024 12:37:26 +0100
>>>>> Louis Chauvet  wrote:
>>>>>  
>>>>>> From: Arthur Grillo 
>>>>>>
>>>>>> Add support to the YUV formats bellow:
>>>>>>
>>>>>> - NV12
>>>>>> - NV16
>>>>>> - NV24
>>>>>> - NV21
>>>>>> - NV61
>>>>>> - NV42
>>>>>> - YUV420
>>>>>> - YUV422
>>>>>> - YUV444
>>>>>> - YVU420
>>>>>> - YVU422
>>>>>> - YVU444
>>>>>>
>>>>>> The conversion matrices of each encoding and range were obtained by
>>>>>> rounding the values of the original conversion matrices multiplied by
>>>>>> 2^8. This is done to avoid the use of fixed point operations.
>>>>>>
>>>>>> Signed-off-by: Arthur Grillo 
>>>>>> [Louis Chauvet: Adapted Arthur's work and implemented the read_line_t
>>>>>> callbacks for yuv formats]
>>>>>> Signed-off-by: Louis Chauvet 
>>>>>> ---
>>>>>>  drivers/gpu/drm/vkms/vkms_composer.c |   2 +-
>>>>>>  drivers/gpu/drm/vkms/vkms_drv.h  |   6 +-
>>>>>>  drivers/gpu/drm/vkms/vkms_formats.c  | 289 
>>>>>> +--
>>>>>>  drivers/gpu/drm/vkms/vkms_formats.h  |   4 +
>>>>>>  drivers/gpu/drm/vkms/vkms_plane.c|  14 +-
>>>>>>  5 files changed, 295 insertions(+), 20 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/gpu/drm/vkms/vkms_composer.c 
>>>>>> b/drivers/gpu/drm/vkms/vkms_composer.c
>>>>>> index e555bf9c1aee..54fc5161d565 100644
>>>>>> --- a/drivers/gpu/drm/vkms/vkms_composer.c
>>>>>> +++ b/drivers/gpu/drm/vkms/vkms_composer.c
>>>>>> @@ -312,7 +312,7 @@ static void blend(struct vkms_writeback_job *wb,
>>>>>>   * buffer [1]
>>>>>>   */
>>>>>>  current_plane->pixel_read_line(
>>>>>> -current_plane->frame_info,
>>>>>> +current_plane,
>>>>>>  x_start,
>>>>>>  y_start,
>>>>>>  direction,
>>>>>> diff --git a/drivers/gpu/drm/vkms/vkms_drv.h 
>>>>>> b/drivers/gpu/drm/vkms/vkms_drv.h
>>>>>> index ccc5be009f15..a4f6456cb971 100644
>>>>>> --- a/drivers/gpu/drm/vkms/vkms_drv.h
>>>>>> +++ b/drivers/gpu/drm/vkms/vkms_drv.h
>>>>>> @@ -75,6 +75,8 @@ enum pixel_read_direction {
>>>>>>  READ_RIGHT
>>>>>>  };
>>>>>>  
>>>>>> +struct vkms_plane_state;
>>>>>> +
>>>>>>  /**
>>>>>>  <<<<<<< HEAD
>>>>>>   * typedef pixel_read_line_t - These functions are used to read a pixel 
>>>>>> line in the source frame,
>>>>>> @@ -87,8 +89,8 @@ enum pixel_read_direction {
>>>>>>   * @out_pixel: Pointer where to write the pixel value. Pixels will be 
>>>>>> written between x_start and
>>>>>>   *  x_end.
>>>>>>   */
>>>>>> -typedef void (*pixel_read_line_t)(struct vkms_frame_info *frame_info, 
>>>>>> int x_start, int y_start, enum
>>>>>> -pixel_read_direction direction, int count, struct 
>>>>>> pixel_argb_u16 out_pixel[]);
>>>>>> +typedef void (*pixel_read_line_t)(struct vkms_plane_state *frame_info, 
>>>>>> int x_start, int y_start,
>>>>>> +   

Re: [PATCH v2 6/9] drm/vkms: Add YUV support

2024-02-28 Thread Arthur Grillo



On 27/02/24 17:01, Arthur Grillo wrote:
> 
> 
> On 27/02/24 12:02, Louis Chauvet wrote:
>> Hi Pekka,
>>
>> For all the comment related to the conversion part, maybe Arthur have an 
>> opinion on it, I took his patch as a "black box" (I did not want to 
>> break (and debug) it).
>>
>> Le 26/02/24 - 14:19, Pekka Paalanen a écrit :
>>> On Fri, 23 Feb 2024 12:37:26 +0100
>>> Louis Chauvet  wrote:
>>>
>>>> From: Arthur Grillo 
>>>>
>>>> Add support to the YUV formats bellow:
>>>>
>>>> - NV12
>>>> - NV16
>>>> - NV24
>>>> - NV21
>>>> - NV61
>>>> - NV42
>>>> - YUV420
>>>> - YUV422
>>>> - YUV444
>>>> - YVU420
>>>> - YVU422
>>>> - YVU444
>>>>
>>>> The conversion matrices of each encoding and range were obtained by
>>>> rounding the values of the original conversion matrices multiplied by
>>>> 2^8. This is done to avoid the use of fixed point operations.
>>>>
>>>> Signed-off-by: Arthur Grillo 
>>>> [Louis Chauvet: Adapted Arthur's work and implemented the read_line_t
>>>> callbacks for yuv formats]
>>>> Signed-off-by: Louis Chauvet 
>>>> ---
>>>>  drivers/gpu/drm/vkms/vkms_composer.c |   2 +-
>>>>  drivers/gpu/drm/vkms/vkms_drv.h  |   6 +-
>>>>  drivers/gpu/drm/vkms/vkms_formats.c  | 289 
>>>> +--
>>>>  drivers/gpu/drm/vkms/vkms_formats.h  |   4 +
>>>>  drivers/gpu/drm/vkms/vkms_plane.c|  14 +-
>>>>  5 files changed, 295 insertions(+), 20 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/vkms/vkms_composer.c 
>>>> b/drivers/gpu/drm/vkms/vkms_composer.c
>>>> index e555bf9c1aee..54fc5161d565 100644
>>>> --- a/drivers/gpu/drm/vkms/vkms_composer.c
>>>> +++ b/drivers/gpu/drm/vkms/vkms_composer.c
>>>> @@ -312,7 +312,7 @@ static void blend(struct vkms_writeback_job *wb,
>>>> * buffer [1]
>>>> */
>>>>current_plane->pixel_read_line(
>>>> -  current_plane->frame_info,
>>>> +  current_plane,
>>>>x_start,
>>>>y_start,
>>>>direction,
>>>> diff --git a/drivers/gpu/drm/vkms/vkms_drv.h 
>>>> b/drivers/gpu/drm/vkms/vkms_drv.h
>>>> index ccc5be009f15..a4f6456cb971 100644
>>>> --- a/drivers/gpu/drm/vkms/vkms_drv.h
>>>> +++ b/drivers/gpu/drm/vkms/vkms_drv.h
>>>> @@ -75,6 +75,8 @@ enum pixel_read_direction {
>>>>READ_RIGHT
>>>>  };
>>>>  
>>>> +struct vkms_plane_state;
>>>> +
>>>>  /**
>>>>  <<<<<<< HEAD
>>>>   * typedef pixel_read_line_t - These functions are used to read a pixel 
>>>> line in the source frame,
>>>> @@ -87,8 +89,8 @@ enum pixel_read_direction {
>>>>   * @out_pixel: Pointer where to write the pixel value. Pixels will be 
>>>> written between x_start and
>>>>   *  x_end.
>>>>   */
>>>> -typedef void (*pixel_read_line_t)(struct vkms_frame_info *frame_info, int 
>>>> x_start, int y_start, enum
>>>> -  pixel_read_direction direction, int count, struct pixel_argb_u16 
>>>> out_pixel[]);
>>>> +typedef void (*pixel_read_line_t)(struct vkms_plane_state *frame_info, 
>>>> int x_start, int y_start,
>>>> +  enum pixel_read_direction direction, int count, struct pixel_argb_u16 
>>>> out_pixel[]);
>>>
>>> This is the second or third time in this one series changing this type.
>>> Could you not do the change once, in its own patch if possible?
>>
>> Sorry, this is not a change here, but a wrong formatting (missed when 
>> rebasing).
>>
>> Do you think that it make sense to re-order my patches and put this 
>> typedef at the end? This way it is never updated.
>>
>>>>  
>>>>  /**
>>>>   * vkms_plane_state - Driver specific plane state
>>>> diff --git a/drivers/gpu/drm/vkms/vkms_formats.c 
>>>> b/drivers/gpu/drm/vkms/vkms_formats.c
>>>> index 46daea6d3ee9..515c80866a58 100644
>>>> --- a/drivers/gpu/drm/vkms/vkms_formats.c
>>>> +

Re: [PATCH v2 0/7] Add YUV formats to VKMS

2024-02-28 Thread Arthur Grillo



On 15/01/24 12:06, Sebastian Wick wrote:
> On Wed, Jan 10, 2024 at 02:44:00PM -0300, Arthur Grillo wrote:
>> This patchset aims to add support for additional buffer YUV formats.
>> More specifically, it adds support to:
>>
>> Semi-planar formats:
>>
>> - NV12
>> - NV16
>> - NV24
>> - NV21
>> - NV61
>> - NV42
>>
>> Planar formats:
>>
>> - YUV440
>> - YUV422
>> - YUV444
>> - YVU440
>> - YVU422
>> - YVU444
>>
>> These formats have more than one plane, and most have chroma
>> subsampling. These properties don't have support on VKMS, so I had to
>> work on this before.
>>
>> To ensure that the conversions from YUV to RGB are working, I wrote a
>> KUnit test. As the work from Harry on creating KUnit tests on VKMS[1] is
>> not yet merged, I took the setup part (Kconfig entry and .kunitfile)
>> from it.
>>
>> Furthermore, I couldn't find any sources with the conversion matrices,
>> so I had to work out the values myself based on the ITU papers[2][3][4].
>> So, I'm not 100% sure if the values are accurate. I'd appreciate some
>> input if anyone has more knowledge in this area.
> 
> H.273 CICP [1] has concise descriptions of the required values for most
> widely used formats and the colour python framework [2] also can be used
> to quickly get to the desired information most of the time.
> 
> [1]: https://www.itu.int/rec/T-REC-H.273
> [2]: https://www.colour-science.org/

I want to thank you for suggesting the python framework, it helped
immensely now that I'm changing the precision from 8-bit to 32-bit[1].

If I'd known about this framework while developing this patch, I
would've saved myself a few weeks of pain and suffering recreating a
part of this library XD.

[1]: 
https://lore.kernel.org/all/b23da076-0bfb-48b2-9386-383a6dec1...@riseup.net/

Best Regards,
~Arthur Grillo

> 
>> Also, I used two IGT tests to check if the formats were having a correct
>> conversion (all with the --extended flag):
>>
>> - kms_plane@pixel_format
>> - kms_plane@pixel_format_source_clamping.
>>
>> The nonsubsampled formats don't have support on IGT, so I sent a patch
>> fixing this[5].
>>
>> Currently, this patchset does not add those formats to the writeback, as
>> it would require a rewrite of how the conversions are done (similar to
>> what was done on a previous patch[6]). So, I would like to review this
>> patchset before I start the work on this other part.
>>
>> [1]: 
>> https://lore.kernel.org/all/20231108163647.106853-5-harry.wentl...@amd.com/
>> [2]: https://www.itu.int/rec/R-REC-BT.601-7-201103-I/en
>> [3]: https://www.itu.int/rec/R-REC-BT.709-6-201506-I/en
>> [4]: https://www.itu.int/rec/R-REC-BT.2020-2-201510-I/en
>> [5]: https://lists.freedesktop.org/archives/igt-dev/2024-January/066937.html
>> [6]: 
>> https://lore.kernel.org/dri-devel/20230414135151.75975-2-mca...@igalia.com/
>>
>> Signed-off-by: Arthur Grillo 
>> ---
>> Changes in v2:
>> - Use EXPORT_SYMBOL_IF_KUNIT instead of including the .c test
>>   file (Maxime)
>> - Link to v1: 
>> https://lore.kernel.org/r/20240105-vkms-yuv-v1-0-34c4cd345...@riseup.net
>>
>> ---
>> Arthur Grillo (7):
>>   drm/vkms: Use drm_frame directly
>>   drm/vkms: Add support for multy-planar framebuffers
>>   drm/vkms: Add range and encoding properties to pixel_read function
>>   drm/vkms: Add chroma subsampling
>>   drm/vkms: Add YUV support
>>   drm/vkms: Drop YUV formats TODO
>>   drm/vkms: Create KUnit tests for YUV conversions
>>
>>  Documentation/gpu/vkms.rst|   3 +-
>>  drivers/gpu/drm/vkms/Kconfig  |  15 ++
>>  drivers/gpu/drm/vkms/Makefile |   1 +
>>  drivers/gpu/drm/vkms/tests/.kunitconfig   |   4 +
>>  drivers/gpu/drm/vkms/tests/Makefile   |   3 +
>>  drivers/gpu/drm/vkms/tests/vkms_format_test.c | 156 
>>  drivers/gpu/drm/vkms/vkms_drv.h   |   6 +-
>>  drivers/gpu/drm/vkms/vkms_formats.c   | 247 
>> ++
>>  drivers/gpu/drm/vkms/vkms_formats.h   |   9 +
>>  drivers/gpu/drm/vkms/vkms_plane.c |  26 ++-
>>  drivers/gpu/drm/vkms/vkms_writeback.c |   5 -
>>  11 files changed, 426 insertions(+), 49 deletions(-)
>> ---
>> base-commit: eeb8e8d9f124f279e80ae679f4ba6e822ce4f95f
>> change-id: 20231226-vkms-yuv-6f7859f32df8
>>
>> Best regards,
>> -- 
>> Arthur Grillo 
>>
> 


Re: [PATCH v2 6/9] drm/vkms: Add YUV support

2024-02-27 Thread Arthur Grillo



On 27/02/24 12:02, Louis Chauvet wrote:
> Hi Pekka,
> 
> For all the comment related to the conversion part, maybe Arthur have an 
> opinion on it, I took his patch as a "black box" (I did not want to 
> break (and debug) it).
> 
> Le 26/02/24 - 14:19, Pekka Paalanen a écrit :
>> On Fri, 23 Feb 2024 12:37:26 +0100
>> Louis Chauvet  wrote:
>>
>>> From: Arthur Grillo 
>>>
>>> Add support to the YUV formats bellow:
>>>
>>> - NV12
>>> - NV16
>>> - NV24
>>> - NV21
>>> - NV61
>>> - NV42
>>> - YUV420
>>> - YUV422
>>> - YUV444
>>> - YVU420
>>> - YVU422
>>> - YVU444
>>>
>>> The conversion matrices of each encoding and range were obtained by
>>> rounding the values of the original conversion matrices multiplied by
>>> 2^8. This is done to avoid the use of fixed point operations.
>>>
>>> Signed-off-by: Arthur Grillo 
>>> [Louis Chauvet: Adapted Arthur's work and implemented the read_line_t
>>> callbacks for yuv formats]
>>> Signed-off-by: Louis Chauvet 
>>> ---
>>>  drivers/gpu/drm/vkms/vkms_composer.c |   2 +-
>>>  drivers/gpu/drm/vkms/vkms_drv.h  |   6 +-
>>>  drivers/gpu/drm/vkms/vkms_formats.c  | 289 
>>> +--
>>>  drivers/gpu/drm/vkms/vkms_formats.h  |   4 +
>>>  drivers/gpu/drm/vkms/vkms_plane.c|  14 +-
>>>  5 files changed, 295 insertions(+), 20 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/vkms/vkms_composer.c 
>>> b/drivers/gpu/drm/vkms/vkms_composer.c
>>> index e555bf9c1aee..54fc5161d565 100644
>>> --- a/drivers/gpu/drm/vkms/vkms_composer.c
>>> +++ b/drivers/gpu/drm/vkms/vkms_composer.c
>>> @@ -312,7 +312,7 @@ static void blend(struct vkms_writeback_job *wb,
>>>  * buffer [1]
>>>  */
>>> current_plane->pixel_read_line(
>>> -   current_plane->frame_info,
>>> +   current_plane,
>>> x_start,
>>> y_start,
>>> direction,
>>> diff --git a/drivers/gpu/drm/vkms/vkms_drv.h 
>>> b/drivers/gpu/drm/vkms/vkms_drv.h
>>> index ccc5be009f15..a4f6456cb971 100644
>>> --- a/drivers/gpu/drm/vkms/vkms_drv.h
>>> +++ b/drivers/gpu/drm/vkms/vkms_drv.h
>>> @@ -75,6 +75,8 @@ enum pixel_read_direction {
>>> READ_RIGHT
>>>  };
>>>  
>>> +struct vkms_plane_state;
>>> +
>>>  /**
>>>  <<<<<<< HEAD
>>>   * typedef pixel_read_line_t - These functions are used to read a pixel 
>>> line in the source frame,
>>> @@ -87,8 +89,8 @@ enum pixel_read_direction {
>>>   * @out_pixel: Pointer where to write the pixel value. Pixels will be 
>>> written between x_start and
>>>   *  x_end.
>>>   */
>>> -typedef void (*pixel_read_line_t)(struct vkms_frame_info *frame_info, int 
>>> x_start, int y_start, enum
>>> -   pixel_read_direction direction, int count, struct pixel_argb_u16 
>>> out_pixel[]);
>>> +typedef void (*pixel_read_line_t)(struct vkms_plane_state *frame_info, int 
>>> x_start, int y_start,
>>> +   enum pixel_read_direction direction, int count, struct pixel_argb_u16 
>>> out_pixel[]);
>>
>> This is the second or third time in this one series changing this type.
>> Could you not do the change once, in its own patch if possible?
> 
> Sorry, this is not a change here, but a wrong formatting (missed when 
> rebasing).
> 
> Do you think that it make sense to re-order my patches and put this 
> typedef at the end? This way it is never updated.
> 
>>>  
>>>  /**
>>>   * vkms_plane_state - Driver specific plane state
>>> diff --git a/drivers/gpu/drm/vkms/vkms_formats.c 
>>> b/drivers/gpu/drm/vkms/vkms_formats.c
>>> index 46daea6d3ee9..515c80866a58 100644
>>> --- a/drivers/gpu/drm/vkms/vkms_formats.c
>>> +++ b/drivers/gpu/drm/vkms/vkms_formats.c
>>> @@ -33,7 +33,8 @@ static size_t packed_pixels_offset(const struct 
>>> vkms_frame_info *frame_info, int
>>>  */
>>> return fb->offsets[plane_index] +
>>>(y / drm_format_info_block_width(format, plane_index)) * 
>>> fb->pitches[plane_index] +
>>> -  (x / drm_format_info_block_height(format, plane_index)) * 
>&g

Re: [PATCH v3 3/9] drm/vkms: write/update the documentation for pixel conversion and pixel write functions

2024-02-27 Thread Arthur Grillo



On 27/02/24 12:02, Louis Chauvet wrote:
> Le 26/02/24 - 10:07, Arthur Grillo a écrit :
>>
>>
>> On 26/02/24 05:46, Louis Chauvet wrote:
>>> Add some documentation on pixel conversion functions.
>>> Update of outdated comments for pixel_write functions.
>>>
>>> Signed-off-by: Louis Chauvet 
>>> ---
>>>  drivers/gpu/drm/vkms/vkms_composer.c |  4 +++
>>>  drivers/gpu/drm/vkms/vkms_drv.h  | 13 
>>>  drivers/gpu/drm/vkms/vkms_formats.c  | 58 
>>> ++--
>>>  3 files changed, 66 insertions(+), 9 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/vkms/vkms_composer.c 
>>> b/drivers/gpu/drm/vkms/vkms_composer.c
>>> index c6d9b4a65809..5b341222d239 100644
>>> --- a/drivers/gpu/drm/vkms/vkms_composer.c
>>> +++ b/drivers/gpu/drm/vkms/vkms_composer.c
>>> @@ -189,6 +189,10 @@ static void blend(struct vkms_writeback_job *wb,
>>>  
>>> size_t crtc_y_limit = crtc_state->base.crtc->mode.vdisplay;
>>>  
>>> +   /*
>>> +* The planes are composed line-by-line. It is a necessary complexity 
>>> to avoid poor
>>> +* blending performance.
>>
>> At this moment in the series, you have not yet reintroduced the
>> line-by-line algorithm yet. Maybe it's better to add this comment when
>> you do.
> 
> Is it better with this:
> 
>   /*
>* The planes are composed line-by-line to avoid heavy memory usage. It 
> is a necessary
>* complexity to avoid poor blending performance.
>*
>* The function vkms_compose_row is used to read a line, 
> pixel-by-pixel, into the staging
>* buffer.
>*/
>  
>> Also, I think it's good to give more context, like:
>> "The planes are composed line-by-line, instead of pixel-by-pixel"
> 
> And after PATCHv3 5/9:
> 
>   /*
>* The planes are composed line-by-line to avoid heavy memory usage. It 
> is a necessary
>* complexity to avoid poor blending performance.
>*
>* The function pixel_read_line callback is used to read a line, using 
> an efficient 
>* algorithm for a specific format, into the staging buffer.
>*/
> 

Hi,

This looks good to me.

Best Regards,
~Arthur Grillo

> Kind regards,
> Louis Chauvet
> 
>> Best Regards,
>> ~Arthur Grillo
> 
> [...]
> 


Re: [PATCH] drm/vkms: Add information on how to benchmark

2024-02-27 Thread Arthur Grillo



On 27/02/24 12:02, Louis Chauvet wrote:
> Le 27/02/24 - 15:26, Pekka Paalanen a écrit :
>> On Tue, 27 Feb 2024 09:29:58 -0300
>> Arthur Grillo  wrote:
>>
>>> On 27/02/24 08:55, Pekka Paalanen wrote:
>>>> On Tue, 27 Feb 2024 08:44:52 -0300
>>>> Arthur Grillo  wrote:
>>>>   
>>>>> On 27/02/24 06:19, Pekka Paalanen wrote:  
>>>>>> On Mon, 26 Feb 2024 17:42:11 -0300
>>>>>> Arthur Grillo  wrote:
>>>>>> 
>>>>>>> Now that we have a defined benchmark for testing the driver, add
>>>>>>> documentation on how to run it.
>>>>>>>
>>>>>>> Signed-off-by: Arthur Grillo 
>>>>>>> ---
>>>>>>>  Documentation/gpu/vkms.rst | 6 ++
>>>>>>>  1 file changed, 6 insertions(+)
>>>>>>>
>>>>>>> diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
>>>>>>> index ba04ac7c2167..6d07f79f77ff 100644
>>>>>>> --- a/Documentation/gpu/vkms.rst
>>>>>>> +++ b/Documentation/gpu/vkms.rst
>>>>>>> @@ -89,6 +89,12 @@ You can also run subtests if you do not want to run 
>>>>>>> the entire test::
>>>>>>>sudo ./build/tests/kms_flip --run-subtest basic-plain-flip --device 
>>>>>>> "sys:/sys/devices/platform/vkms"
>>>>>>>sudo IGT_DEVICE="sys:/sys/devices/platform/vkms" 
>>>>>>> ./build/tests/kms_flip --run-subtest basic-plain-flip
>>>>>>>  
>>>>>>> +If you are developing features that may affect performance, you can 
>>>>>>> run the kms_fb_stress
>>>>>>
>>>>>> s/can/must/
>>>>>> 
>>>>>>> +benchmark::
>>>>>>
>>>>>> before and after, and report the numbers.
>>>>>
>>>>> Did you mean to write the benchmarks logs here?  
>>>>
>>>> I mean people should be required tell their before and after numbers in
>>>> either commit message (my preference) or in series cover letter (if
>>>> benchmarking commits is not useful).
>>>>
>>>> With the addition of YUV support in VKMS, maybe the benchmark needs to  
>>>
>>> With the upcoming addition, I've sent a patch to arbitrarily change the
>>> formats on the benchmark via command-line options. It's not adding a new
>>> case, but maybe just this could already help.
>>>
>>> https://lore.kernel.org/all/20240226-kms_fb_stress-dev-v1-0-1c14942b1...@riseup.net/
>>
>> In that case you would need to document exactly what command line
>> options to use, and ask people to report the numbers of each test
>> case.
>>
>> That works. Alternatively or additionally, the test cases could be
>> built in to the benchmark, and it just reports numbers for all of them
>> in a single invocation. Then people running the standard benchmark do
>> not need to worry about getting the command line options right, or
>> running multiple cases. And reviewers do not need to ask to re-run with
>> the correct options.
>>
>> I suppose rotations might get added, too.
>>
>> Or maybe you'd provide a script that covers all the standard
>> performance test cases?
> 
> I agree with Pekka, it would be nice to have a simple "bench everything" 
> tool. Like kms_rotation is a test for all rotations, kms_plane for color 
> conversions... kms_fb_test can run a few combinations (rgb+norotation, 
> rgb+yuv, rgb+rotation...) and report a "global result" (this way it's easy 
> to spot a regression not related directly to your changes).
> 
> I don't know the IGT benchmark API, but I think there is a way to create 
> "sub-benchmarks" so you can run a specific benchmark when developping and 
> the whole thing before pushing your series.
> 
> Kind regards,
> Louis Chauvet
> 

Thank you guys for the ideas!

I'm going to work on something along on those lines, having combinations
of formats, rotations and whatever property that might be useful for
stress testing the driver. Maybe query the driver for the supported
properties (e.g. what formats and rotations it supports) and do many/all
possible combinations.

Best Regards,
~Arthur Grillo


>>
>> Thanks,
>> pq
>>
>>>> start printing YUV numbers separately as a new case.
>>>>
>>>>
>>>> Thanks,
>>>> pq
>>>>   
>>>>>  
>>>>>> 
>>>>>>> +
>>>>>>> +  sudo ./build/benchmarks/kms_fb_stress --device 
>>>>>>> "sys:/sys/devices/platform/vkms"
>>>>>>> +  sudo IGT_DEVICE="sys:/sys/devices/platform/vkms" 
>>>>>>> ./build/benchmarks/kms_fb_stress
>>>>>>
>>>>>> Do people need to run both commands?
>>>>>
>>>>> No, they don't, just two options.
>>>>>
>>>>> Best Regards,
>>>>> ~Arthur Grillo
>>>>>  
>>>>>>
>>>>>> Anyway, a good idea.
>>>>>>
>>>>>> Acked-by: Pekka Paalanen 
>>>>>>
>>>>>>
>>>>>> Thanks,
>>>>>> pq
>>>>>> 
>>>>>>> +
>>>>>>>  TODO
>>>>>>>  
>>>>>>>  
>>>>>>>
>>>>>>> ---
>>>>>>> base-commit: eeb8e8d9f124f279e80ae679f4ba6e822ce4f95f
>>>>>>> change-id: 20240226-bench-vkms-5b8b7aab255e
>>>>>>>
>>>>>>> Best regards,
>>>>>> 
>>>>   
>>
> 
> 
> 


Re: [PATCH] drm/vkms: Add information on how to benchmark

2024-02-27 Thread Arthur Grillo



On 27/02/24 08:55, Pekka Paalanen wrote:
> On Tue, 27 Feb 2024 08:44:52 -0300
> Arthur Grillo  wrote:
> 
>> On 27/02/24 06:19, Pekka Paalanen wrote:
>>> On Mon, 26 Feb 2024 17:42:11 -0300
>>> Arthur Grillo  wrote:
>>>   
>>>> Now that we have a defined benchmark for testing the driver, add
>>>> documentation on how to run it.
>>>>
>>>> Signed-off-by: Arthur Grillo 
>>>> ---
>>>>  Documentation/gpu/vkms.rst | 6 ++
>>>>  1 file changed, 6 insertions(+)
>>>>
>>>> diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
>>>> index ba04ac7c2167..6d07f79f77ff 100644
>>>> --- a/Documentation/gpu/vkms.rst
>>>> +++ b/Documentation/gpu/vkms.rst
>>>> @@ -89,6 +89,12 @@ You can also run subtests if you do not want to run the 
>>>> entire test::
>>>>sudo ./build/tests/kms_flip --run-subtest basic-plain-flip --device 
>>>> "sys:/sys/devices/platform/vkms"
>>>>sudo IGT_DEVICE="sys:/sys/devices/platform/vkms" ./build/tests/kms_flip 
>>>> --run-subtest basic-plain-flip
>>>>  
>>>> +If you are developing features that may affect performance, you can run 
>>>> the kms_fb_stress  
>>>
>>> s/can/must/
>>>   
>>>> +benchmark::  
>>>
>>> before and after, and report the numbers.  
>>
>> Did you mean to write the benchmarks logs here?
> 
> I mean people should be required tell their before and after numbers in
> either commit message (my preference) or in series cover letter (if
> benchmarking commits is not useful).
> 
> With the addition of YUV support in VKMS, maybe the benchmark needs to

With the upcoming addition, I've sent a patch to arbitrarily change the
formats on the benchmark via command-line options. It's not adding a new
case, but maybe just this could already help.

https://lore.kernel.org/all/20240226-kms_fb_stress-dev-v1-0-1c14942b1...@riseup.net/

Best Regards,
~Arthur Grillo

> start printing YUV numbers separately as a new case.
> 
> 
> Thanks,
> pq
> 
>>
>>>   
>>>> +
>>>> +  sudo ./build/benchmarks/kms_fb_stress --device 
>>>> "sys:/sys/devices/platform/vkms"
>>>> +  sudo IGT_DEVICE="sys:/sys/devices/platform/vkms" 
>>>> ./build/benchmarks/kms_fb_stress  
>>>
>>> Do people need to run both commands?  
>>
>> No, they don't, just two options.
>>
>> Best Regards,
>> ~Arthur Grillo
>>
>>>
>>> Anyway, a good idea.
>>>
>>> Acked-by: Pekka Paalanen 
>>>
>>>
>>> Thanks,
>>> pq
>>>   
>>>> +
>>>>  TODO
>>>>  
>>>>  
>>>>
>>>> ---
>>>> base-commit: eeb8e8d9f124f279e80ae679f4ba6e822ce4f95f
>>>> change-id: 20240226-bench-vkms-5b8b7aab255e
>>>>
>>>> Best regards,  
>>>   
> 


Re: [RFC PATCH v4 06/42] drm/vkms: Add kunit tests for VKMS LUT handling

2024-02-27 Thread Arthur Grillo



On 26/02/24 18:10, Harry Wentland wrote:
> Debugging LUT math is much easier when we can unit test
> it. Add kunit functionality to VKMS and add tests for
>  - get_lut_index
>  - lerp_u16
> 
> v4:
>  - Test the critical points of the lerp function (Pekka)
> 
> v3:
>  - Use include way of testing static functions (Arthur)
> 
> Signed-off-by: Harry Wentland 
> Cc: Arthur Grillo 
> ---
>  drivers/gpu/drm/vkms/Kconfig  |   5 +
>  drivers/gpu/drm/vkms/tests/.kunitconfig   |   4 +
>  drivers/gpu/drm/vkms/tests/vkms_color_tests.c | 163 ++
>  drivers/gpu/drm/vkms/vkms_composer.c  |   8 +-
>  4 files changed, 178 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/gpu/drm/vkms/tests/.kunitconfig
>  create mode 100644 drivers/gpu/drm/vkms/tests/vkms_color_tests.c
> 
> diff --git a/drivers/gpu/drm/vkms/Kconfig b/drivers/gpu/drm/vkms/Kconfig
> index b9ecdebecb0b..c1f8b343ff0e 100644
> --- a/drivers/gpu/drm/vkms/Kconfig
> +++ b/drivers/gpu/drm/vkms/Kconfig
> @@ -13,3 +13,8 @@ config DRM_VKMS
> a VKMS.
>  
> If M is selected the module will be called vkms.
> +
> +config DRM_VKMS_KUNIT_TESTS
> + tristate "Tests for VKMS" if !KUNIT_ALL_TESTS
> + depends on DRM_VKMS && KUNIT
> + default KUNIT_ALL_TESTS
> diff --git a/drivers/gpu/drm/vkms/tests/.kunitconfig 
> b/drivers/gpu/drm/vkms/tests/.kunitconfig
> new file mode 100644
> index ..70e378228cbd
> --- /dev/null
> +++ b/drivers/gpu/drm/vkms/tests/.kunitconfig
> @@ -0,0 +1,4 @@
> +CONFIG_KUNIT=y
> +CONFIG_DRM=y
> +CONFIG_DRM_VKMS=y
> +CONFIG_DRM_VKMS_KUNIT_TESTS=y
> diff --git a/drivers/gpu/drm/vkms/tests/vkms_color_tests.c 
> b/drivers/gpu/drm/vkms/tests/vkms_color_tests.c
> new file mode 100644
> index ..fc73e48aa57c
> --- /dev/null
> +++ b/drivers/gpu/drm/vkms/tests/vkms_color_tests.c
> @@ -0,0 +1,163 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +
> +#include 
> +
> +#include 
> +
> +#define TEST_LUT_SIZE 16
> +
> +static struct drm_color_lut test_linear_array[TEST_LUT_SIZE] = {
> + { 0x0, 0x0, 0x0, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> +};
> +
> +const struct vkms_color_lut test_linear_lut = {
> + .base = test_linear_array,
> + .lut_length = TEST_LUT_SIZE,
> + .channel_value2index_ratio = 0xf000fll
> +};
> +
> +
> +static void vkms_color_test_get_lut_index(struct kunit *test)
> +{
> + int i;
> +
> + KUNIT_EXPECT_EQ(test, drm_fixp2int(get_lut_index(_linear_lut, 
> test_linear_array[0].red)), 0);
> +
> + for (i = 0; i < TEST_LUT_SIZE; i++)
> + KUNIT_EXPECT_EQ(test, 
> drm_fixp2int_ceil(get_lut_index(_linear_lut, test_linear_array[i].red)), 
> i);
> +}
> +
> +static void vkms_color_test_lerp(struct kunit *test)
> +{
> + /*** half-way round down ***/
> + s64 t = 0x8000 - 1;
> + KUNIT_EXPECT_EQ(test, lerp_u16(0x0, 0x10, t), 0x8);
> +
> + /* odd a */
> + KUNIT_EXPECT_EQ(test, lerp_u16(0x1, 0x10, t), 0x8);
> +
> + /* odd b */
> + KUNIT_EXPECT_EQ(test, lerp_u16(0x1, 0xf, t), 0x8);
> +
> + /* b = a */
> + KUNIT_EXPECT_EQ(test, lerp_u16(0x10, 0x10, t), 0x10);
> +
> + /* b = a + 1 */
> + KUNIT_EXPECT_EQ(test, lerp_u16(0x10, 0x11, t), 0x10);
> +
> +
> + /*** half-way round up ***/
> + t = 0x8000;
> + KUNIT_EXPECT_EQ(test, lerp_u16(0x0, 0x10, t), 0x8);
> +
> + /* odd a */
> + KUNIT_EXPECT_EQ(test, lerp_u16(0x1, 0x10, t), 0x9);
> +
> + /* odd b */
> + KUNIT_EXPECT_EQ(test, lerp_u16(0x1, 0xf, t), 0x8);
> +
> + /* b = a */
> + KUNIT_EXPECT_EQ(test, lerp_u16(0x10, 0x10, t), 0x10);
> +
> + /* b = a + 1 */
> + KUNIT_EXPECT_EQ(test, lerp_u16(0x10, 0x11, t), 0x11);
> +
> + /*** t = 0.0 ***/
> + t = 0x0;
> + KUNIT_EXPECT_EQ(test, lerp_u16(0x0, 0x10, t), 0x0);
> +
> + /* odd a */
> + KUNIT_EXPECT_EQ(test, lerp_u16(0x1, 0x10, t), 0x1);
> +
> + /* odd b */
> + KUNIT_EXPECT_EQ(test, lerp_u16(0x1, 0xf, t), 0x1);
> +
> + /* b 

Re: [PATCH] drm/vkms: Add information on how to benchmark

2024-02-27 Thread Arthur Grillo



On 27/02/24 06:19, Pekka Paalanen wrote:
> On Mon, 26 Feb 2024 17:42:11 -0300
> Arthur Grillo  wrote:
> 
>> Now that we have a defined benchmark for testing the driver, add
>> documentation on how to run it.
>>
>> Signed-off-by: Arthur Grillo 
>> ---
>>  Documentation/gpu/vkms.rst | 6 ++
>>  1 file changed, 6 insertions(+)
>>
>> diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
>> index ba04ac7c2167..6d07f79f77ff 100644
>> --- a/Documentation/gpu/vkms.rst
>> +++ b/Documentation/gpu/vkms.rst
>> @@ -89,6 +89,12 @@ You can also run subtests if you do not want to run the 
>> entire test::
>>sudo ./build/tests/kms_flip --run-subtest basic-plain-flip --device 
>> "sys:/sys/devices/platform/vkms"
>>sudo IGT_DEVICE="sys:/sys/devices/platform/vkms" ./build/tests/kms_flip 
>> --run-subtest basic-plain-flip
>>  
>> +If you are developing features that may affect performance, you can run the 
>> kms_fb_stress
> 
> s/can/must/
> 
>> +benchmark::
> 
> before and after, and report the numbers.

Did you mean to write the benchmarks logs here?

> 
>> +
>> +  sudo ./build/benchmarks/kms_fb_stress --device 
>> "sys:/sys/devices/platform/vkms"
>> +  sudo IGT_DEVICE="sys:/sys/devices/platform/vkms" 
>> ./build/benchmarks/kms_fb_stress
> 
> Do people need to run both commands?

No, they don't, just two options.

Best Regards,
~Arthur Grillo

> 
> Anyway, a good idea.
> 
> Acked-by: Pekka Paalanen 
> 
> 
> Thanks,
> pq
> 
>> +
>>  TODO
>>  
>>  
>>
>> ---
>> base-commit: eeb8e8d9f124f279e80ae679f4ba6e822ce4f95f
>> change-id: 20240226-bench-vkms-5b8b7aab255e
>>
>> Best regards,
> 


[PATCH] drm/vkms: Add information on how to benchmark

2024-02-26 Thread Arthur Grillo
Now that we have a defined benchmark for testing the driver, add
documentation on how to run it.

Signed-off-by: Arthur Grillo 
---
 Documentation/gpu/vkms.rst | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
index ba04ac7c2167..6d07f79f77ff 100644
--- a/Documentation/gpu/vkms.rst
+++ b/Documentation/gpu/vkms.rst
@@ -89,6 +89,12 @@ You can also run subtests if you do not want to run the 
entire test::
   sudo ./build/tests/kms_flip --run-subtest basic-plain-flip --device 
"sys:/sys/devices/platform/vkms"
   sudo IGT_DEVICE="sys:/sys/devices/platform/vkms" ./build/tests/kms_flip 
--run-subtest basic-plain-flip
 
+If you are developing features that may affect performance, you can run the 
kms_fb_stress
+benchmark::
+
+  sudo ./build/benchmarks/kms_fb_stress --device 
"sys:/sys/devices/platform/vkms"
+  sudo IGT_DEVICE="sys:/sys/devices/platform/vkms" 
./build/benchmarks/kms_fb_stress
+
 TODO
 
 

---
base-commit: eeb8e8d9f124f279e80ae679f4ba6e822ce4f95f
change-id: 20240226-bench-vkms-5b8b7aab255e

Best regards,
-- 
Arthur Grillo 



Re: [PATCH v2 9/9] drm/vkms: Create KUnit tests for YUV conversions

2024-02-26 Thread Arthur Grillo



On 23/02/24 08:37, Louis Chauvet wrote:
> From: Arthur Grillo 
> 
> Create KUnit tests to test the conversion between YUV and RGB. Test each
> conversion and range combination with some common colors.
> 
> Signed-off-by: Arthur Grillo 
> [Louis Chauvet: fix minor formating issues (whitespace, double line)]
> Signed-off-by: Louis Chauvet 
> ---
>  drivers/gpu/drm/vkms/Makefile |   1 +
>  drivers/gpu/drm/vkms/tests/.kunitconfig   |   4 +
>  drivers/gpu/drm/vkms/tests/Makefile   |   3 +
>  drivers/gpu/drm/vkms/tests/vkms_format_test.c | 155 
> ++
>  drivers/gpu/drm/vkms/vkms_formats.c   |   9 +-
>  drivers/gpu/drm/vkms/vkms_formats.h   |   5 +
>  6 files changed, 175 insertions(+), 2 deletions(-)

You need to add the CONFIG_DRM_VKMS_KUNIT_TESTS config to
drivers/gpu/drm/vkms/Kconfig, like my previous patch did.

Best Regards,
~Arthur Grillo

> 
> diff --git a/drivers/gpu/drm/vkms/Makefile b/drivers/gpu/drm/vkms/Makefile
> index 1b28a6a32948..8d3e46dde635 100644
> --- a/drivers/gpu/drm/vkms/Makefile
> +++ b/drivers/gpu/drm/vkms/Makefile
> @@ -9,3 +9,4 @@ vkms-y := \
>   vkms_writeback.o
>  
>  obj-$(CONFIG_DRM_VKMS) += vkms.o
> +obj-$(CONFIG_DRM_VKMS_KUNIT_TESTS) += tests/
> diff --git a/drivers/gpu/drm/vkms/tests/.kunitconfig 
> b/drivers/gpu/drm/vkms/tests/.kunitconfig
> new file mode 100644
> index ..70e378228cbd
> --- /dev/null
> +++ b/drivers/gpu/drm/vkms/tests/.kunitconfig
> @@ -0,0 +1,4 @@
> +CONFIG_KUNIT=y
> +CONFIG_DRM=y
> +CONFIG_DRM_VKMS=y
> +CONFIG_DRM_VKMS_KUNIT_TESTS=y
> diff --git a/drivers/gpu/drm/vkms/tests/Makefile 
> b/drivers/gpu/drm/vkms/tests/Makefile
> new file mode 100644
> index ..2d1df668569e
> --- /dev/null
> +++ b/drivers/gpu/drm/vkms/tests/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +
> +obj-$(CONFIG_DRM_VKMS_KUNIT_TESTS) += vkms_format_test.o
> diff --git a/drivers/gpu/drm/vkms/tests/vkms_format_test.c 
> b/drivers/gpu/drm/vkms/tests/vkms_format_test.c
> new file mode 100644
> index ..cb6d32ff115d
> --- /dev/null
> +++ b/drivers/gpu/drm/vkms/tests/vkms_format_test.c
> @@ -0,0 +1,155 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +
> +#include "../../drm_crtc_internal.h"
> +
> +#include "../vkms_drv.h"
> +#include "../vkms_formats.h"
> +
> +#define TEST_BUFF_SIZE 50
> +
> +struct yuv_u8_to_argb_u16_case {
> + enum drm_color_encoding encoding;
> + enum drm_color_range range;
> + size_t n_colors;
> + struct format_pair {
> + char *name;
> + struct pixel_yuv_u8 yuv;
> + struct pixel_argb_u16 argb;
> + } colors[TEST_BUFF_SIZE];
> +};
> +
> +static struct yuv_u8_to_argb_u16_case yuv_u8_to_argb_u16_cases[] = {
> + {
> + .encoding = DRM_COLOR_YCBCR_BT601,
> + .range = DRM_COLOR_YCBCR_FULL_RANGE,
> + .n_colors = 6,
> + .colors = {
> + {"white", {0xff, 0x80, 0x80}, {0x, 0x, 0x, 
> 0x}},
> + {"gray",  {0x80, 0x80, 0x80}, {0x, 0x8000, 0x8000, 
> 0x8000}},
> + {"black", {0x00, 0x80, 0x80}, {0x, 0x, 0x, 
> 0x}},
> + {"red",   {0x4c, 0x55, 0xff}, {0x, 0x, 0x, 
> 0x}},
> + {"green", {0x96, 0x2c, 0x15}, {0x, 0x, 0x, 
> 0x}},
> + {"blue",  {0x1d, 0xff, 0x6b}, {0x, 0x, 0x, 
> 0x}},
> + },
> + },
> + {
> + .encoding = DRM_COLOR_YCBCR_BT601,
> + .range = DRM_COLOR_YCBCR_LIMITED_RANGE,
> + .n_colors = 6,
> + .colors = {
> + {"white", {0xeb, 0x80, 0x80}, {0x, 0x, 0x, 
> 0x}},
> + {"gray",  {0x7e, 0x80, 0x80}, {0x, 0x8000, 0x8000, 
> 0x8000}},
> + {"black", {0x10, 0x80, 0x80}, {0x, 0x, 0x, 
> 0x}},
> + {"red",   {0x51, 0x5a, 0xf0}, {0x, 0x, 0x, 
> 0x}},
> + {"green", {0x91, 0x36, 0x22}, {0x, 0x, 0x, 
> 0x}},
> + {"blue",  {0x29, 0xf0, 0x6e}, {0x, 0x, 0x, 
> 0x}},
> + },
> + },
> + {
> + .encoding = DRM_COLOR_YCBCR_BT709,
> + .range = DRM_COLOR_YCBCR_FULL_RAN

Re: [PATCH v3 5/9] drm/vkms: Re-introduce line-per-line composition algorithm

2024-02-26 Thread Arthur Grillo
  out[x].b = pre_mul_blend_channel(in[x].b, out[x].b, in[x].a);
> + struct pixel_argb_u16 *out = _buffer->pixels[x_start];
> + struct pixel_argb_u16 *in = _buffer->pixels[x_start];
> +
> + for (int i = 0; i < pixel_count; i++) {
> + out[i].a = (u16)0x;
> + out[i].r = pre_mul_blend_channel(in[i].r, out[i].r, in[i].a);
> + out[i].g = pre_mul_blend_channel(in[i].g, out[i].g, in[i].a);
> + out[i].b = pre_mul_blend_channel(in[i].b, out[i].b, in[i].a);
>   }
>  }
>  
> -static int get_y_pos(struct vkms_frame_info *frame_info, int y)
> -{
> - if (frame_info->rotation & DRM_MODE_REFLECT_Y)
> - return drm_rect_height(_info->rotated) - y - 1;
> -
> - switch (frame_info->rotation & DRM_MODE_ROTATE_MASK) {
> - case DRM_MODE_ROTATE_90:
> - return frame_info->rotated.x2 - y - 1;
> - case DRM_MODE_ROTATE_270:
> - return y + frame_info->rotated.x1;
> - default:
> - return y;
> - }
> -}
> -
> -static bool check_limit(struct vkms_frame_info *frame_info, int pos)
> -{
> - if (drm_rotation_90_or_270(frame_info->rotation)) {
> - if (pos >= 0 && pos < drm_rect_width(_info->rotated))
> - return true;
> - } else {
> - if (pos >= frame_info->rotated.y1 && pos < 
> frame_info->rotated.y2)
> - return true;
> - }
> -
> - return false;
> -}
>  
>  static void fill_background(const struct pixel_argb_u16 *background_color,
>   struct line_buffer *output_buffer)
> @@ -163,6 +136,37 @@ static void apply_lut(const struct vkms_crtc_state 
> *crtc_state, struct line_buff
>   }
>  }
>  
> +/**
> + * direction_for_rotation() - Helper to get the correct reading direction 
> for a specific rotation
> + *
> + * @rotation: rotation to analyze
> + */
> +enum pixel_read_direction direction_for_rotation(unsigned int rotation)
> +{
> + if (rotation & DRM_MODE_ROTATE_0) {
> + if (rotation & DRM_MODE_REFLECT_X)
> + return READ_LEFT;
> + else
> + return READ_RIGHT;
> + } else if (rotation & DRM_MODE_ROTATE_90) {
> + if (rotation & DRM_MODE_REFLECT_Y)
> + return READ_UP;
> + else
> + return READ_DOWN;
> + } else if (rotation & DRM_MODE_ROTATE_180) {
> + if (rotation & DRM_MODE_REFLECT_X)
> + return READ_RIGHT;
> + else
> + return READ_LEFT;
> + } else if (rotation & DRM_MODE_ROTATE_270) {
> + if (rotation & DRM_MODE_REFLECT_Y)
> + return READ_DOWN;
> + else
> + return READ_UP;
> + }
> + return READ_RIGHT;
> +}
> +
>  /**
>   * blend - blend the pixels from all planes and compute crc
>   * @wb: The writeback frame buffer metadata
> @@ -183,11 +187,11 @@ static void blend(struct vkms_writeback_job *wb,
>  {
>   struct vkms_plane_state **plane = crtc_state->active_planes;
>   u32 n_active_planes = crtc_state->num_active_planes;
> - int y_pos;
>  
>   const struct pixel_argb_u16 background_color = { .a = 0x };
>  
>   size_t crtc_y_limit = crtc_state->base.crtc->mode.vdisplay;
> + size_t crtc_x_limit = crtc_state->base.crtc->mode.hdisplay;
>  
>   /*
>* The planes are composed line-by-line. It is a necessary complexity 
> to avoid poor
> @@ -198,22 +202,133 @@ static void blend(struct vkms_writeback_job *wb,
>  
>   /* The active planes are composed associatively in z-order. */
>   for (size_t i = 0; i < n_active_planes; i++) {
> - y_pos = get_y_pos(plane[i]->frame_info, y);
> + struct vkms_plane_state *current_plane = plane[i];
>  
> - if (!check_limit(plane[i]->frame_info, y_pos))
> + /* Avoid rendering useless lines */
> + if (y < current_plane->frame_info->dst.y1 ||
> + y >= current_plane->frame_info->dst.y2) {
>   continue;
> -
> - vkms_compose_row(stage_buffer, plane[i], y_pos);
> - pre_mul_alpha_blend(plane[i]->frame_info, stage_buffer,
> - output_buffer);
> + }
> +
> + /*
> +  

Re: [PATCH v3 3/9] drm/vkms: write/update the documentation for pixel conversion and pixel write functions

2024-02-26 Thread Arthur Grillo



On 26/02/24 05:46, Louis Chauvet wrote:
> Add some documentation on pixel conversion functions.
> Update of outdated comments for pixel_write functions.
> 
> Signed-off-by: Louis Chauvet 
> ---
>  drivers/gpu/drm/vkms/vkms_composer.c |  4 +++
>  drivers/gpu/drm/vkms/vkms_drv.h  | 13 
>  drivers/gpu/drm/vkms/vkms_formats.c  | 58 
> ++--
>  3 files changed, 66 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vkms/vkms_composer.c 
> b/drivers/gpu/drm/vkms/vkms_composer.c
> index c6d9b4a65809..5b341222d239 100644
> --- a/drivers/gpu/drm/vkms/vkms_composer.c
> +++ b/drivers/gpu/drm/vkms/vkms_composer.c
> @@ -189,6 +189,10 @@ static void blend(struct vkms_writeback_job *wb,
>  
>   size_t crtc_y_limit = crtc_state->base.crtc->mode.vdisplay;
>  
> + /*
> +  * The planes are composed line-by-line. It is a necessary complexity 
> to avoid poor
> +  * blending performance.

At this moment in the series, you have not yet reintroduced the
line-by-line algorithm yet. Maybe it's better to add this comment when
you do.

Also, I think it's good to give more context, like:
"The planes are composed line-by-line, instead of pixel-by-pixel"

Best Regards,
~Arthur Grillo

> +  */
>   for (size_t y = 0; y < crtc_y_limit; y++) {
>   fill_background(_color, output_buffer);
>  
> diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
> index b4b357447292..18086423a3a7 100644
> --- a/drivers/gpu/drm/vkms/vkms_drv.h
> +++ b/drivers/gpu/drm/vkms/vkms_drv.h
> @@ -25,6 +25,17 @@
>  
>  #define VKMS_LUT_SIZE 256
>  
> +/**
> + * struct vkms_frame_info - structure to store the state of a frame
> + *
> + * @fb: backing drm framebuffer
> + * @src: source rectangle of this frame in the source framebuffer
> + * @dst: destination rectangle in the crtc buffer
> + * @map: see drm_shadow_plane_state@data
> + * @rotation: rotation applied to the source.
> + *
> + * @src and @dst should have the same size modulo the rotation.
> + */
>  struct vkms_frame_info {
>   struct drm_framebuffer *fb;
>   struct drm_rect src, dst;
> @@ -52,6 +63,8 @@ struct vkms_writeback_job {
>   * vkms_plane_state - Driver specific plane state
>   * @base: base plane state
>   * @frame_info: data required for composing computation
> + * @pixel_read: function to read a pixel in this plane. The creator of a 
> vkms_plane_state must
> + * ensure that this pointer is valid
>   */
>  struct vkms_plane_state {
>   struct drm_shadow_plane_state base;
> diff --git a/drivers/gpu/drm/vkms/vkms_formats.c 
> b/drivers/gpu/drm/vkms/vkms_formats.c
> index 172830a3936a..cb7a49b7c8e7 100644
> --- a/drivers/gpu/drm/vkms/vkms_formats.c
> +++ b/drivers/gpu/drm/vkms/vkms_formats.c
> @@ -9,6 +9,17 @@
>  
>  #include "vkms_formats.h"
>  
> +/**
> + * packed_pixels_offset() - Get the offset of the block containing the pixel 
> at coordinates x/y
> + * in the first plane
> + *
> + * @frame_info: Buffer metadata
> + * @x: The x coordinate of the wanted pixel in the buffer
> + * @y: The y coordinate of the wanted pixel in the buffer
> + *
> + * The caller must be aware that this offset is not always a pointer to a 
> pixel. If individual
> + * pixel values are needed, they have to be extracted from the resulting 
> block.
> + */
>  static size_t pixel_offset(const struct vkms_frame_info *frame_info, int x, 
> int y)
>  {
>   struct drm_framebuffer *fb = frame_info->fb;
> @@ -17,12 +28,13 @@ static size_t pixel_offset(const struct vkms_frame_info 
> *frame_info, int x, int
> + (x * fb->format->cpp[0]);
>  }
>  
> -/*
> - * packed_pixels_addr - Get the pointer to pixel of a given pair of 
> coordinates
> +/**
> + * packed_pixels_addr() - Get the pointer to the block containing the pixel 
> at the given
> + * coordinates
>   *
>   * @frame_info: Buffer metadata
> - * @x: The x(width) coordinate of the 2D buffer
> - * @y: The y(Heigth) coordinate of the 2D buffer
> + * @x: The x(width) coordinate inside the plane
> + * @y: The y(height) coordinate inside the plane
>   *
>   * Takes the information stored in the frame_info, a pair of coordinates, and
>   * returns the address of the first color channel.
> @@ -53,6 +65,13 @@ static int get_x_position(const struct vkms_frame_info 
> *frame_info, int limit, i
>   return x;
>  }
>  
> +/*
> + * The following  functions take pixel data from the buffer and convert them 
> to the format
> + * ARGB16161616 in out_pixel.
> + *
> + * They are used in the `vkms_compose_row` function to handle mul

Re: [PATCH v3 4/9] drm/vkms: Add typedef and documentation for pixel_read and pixel_write functions

2024-02-26 Thread Arthur Grillo
c void vkms_plane_atomic_update(struct drm_plane 
> *plane,
>   return;
>  
>   fmt = fb->format->format;
> + pixel_read_t pixel_read = get_pixel_read_function(fmt);
> +
> + if (!pixel_read) {
> + DRM_WARN("Pixel format is not supported by VKMS planes. State 
> is inchanged\n");

s/inchanged/unchanged/

> + return;
> + }
> +
>   vkms_plane_state = to_vkms_plane_state(new_state);
>   shadow_plane_state = _plane_state->base;
>  
> @@ -124,7 +131,7 @@ static void vkms_plane_atomic_update(struct drm_plane 
> *plane,
>   drm_rect_rotate(_info->rotated, 
> drm_rect_width(_info->rotated),
>   drm_rect_height(_info->rotated), 
> frame_info->rotation);
>  
> - vkms_plane_state->pixel_read = get_pixel_conversion_function(fmt);
> + vkms_plane_state->pixel_read = pixel_read;
>  }
>  
>  static int vkms_plane_atomic_check(struct drm_plane *plane,
> diff --git a/drivers/gpu/drm/vkms/vkms_writeback.c 
> b/drivers/gpu/drm/vkms/vkms_writeback.c
> index c8582df1f739..c92b9f06c4a4 100644
> --- a/drivers/gpu/drm/vkms/vkms_writeback.c
> +++ b/drivers/gpu/drm/vkms/vkms_writeback.c
> @@ -140,6 +140,13 @@ static void vkms_wb_atomic_commit(struct drm_connector 
> *conn,
>   if (!conn_state)
>   return;
>  
> + pixel_write_t pixel_write = get_pixel_write_function(wb_format);
> +
> + if (!pixel_write) {
> + DRM_WARN("Pixel format is not supported by VKMS writeback. 
> State is inchanged\n");

Same here

Best Regards,
~Arthur Grillo

> + return;
> + }
> +
>   vkms_set_composer(>output, true);
>  
>   active_wb = conn_state->writeback_job->priv;
> @@ -150,7 +157,7 @@ static void vkms_wb_atomic_commit(struct drm_connector 
> *conn,
>   crtc_state->wb_pending = true;
>   spin_unlock_irq(>composer_lock);
>   drm_writeback_queue_job(wb_conn, connector_state);
> - active_wb->pixel_write = get_pixel_write_function(wb_format);
> + active_wb->pixel_write = pixel_write;
>   drm_rect_init(_frame_info->src, 0, 0, crtc_width, crtc_height);
>   drm_rect_init(_frame_info->dst, 0, 0, crtc_width, crtc_height);
>  }
> 


Re: [PATCH 2/2] drm/vkms: Use a simpler composition function

2024-02-15 Thread Arthur Grillo
 that could result in cleaner code.
> 
>>  [...] /* Small common logic to manage 
>> REFLECT_X/Y and translations */
>>  planes[plane].read_line();
>>  } else {
>>  [...] /* v1 of my patch, pixel by pixel read */
>>  }
>>  }
>>  }
>> }
>>
>> where read_line is:
>>   void read_line(frame_info *src, int y, int x_start, int x_stop, 
>> pixel_argb16 *dts[])
>>  - y is the line to read (so the caller need to compute the correct offset)
>>  - x_start/x_stop are the start and stop column, but they may be not 
>>ordered properly (i.e DRM_REFLECT_X will make x_start greater than 
>>x_stop)
>>  - src/dst are source and destination buffers
> 
> This sounds ok. An alternative would be something like
> 
> enum direction {
> RIGHT,
> LEFT,
> UP,
> DOWN,
> };
> 
> void read_line(frame_info *src, int start_x, int start_y, enum direction dir,
>int count_pixels, pixel_argb16 *dst);
> 
> Based on dir, before the inner loop this function would compute the
> byte offset between the pixels to be read. If the format is multiplanar
> YUV, it can compute the offset per plane. And the starting pointers per
> pixel plane, of course, and one end pointer for the loop stop condition
> maybe from dst.
> 
> This might make all the other directions than RIGHT much faster than
> calling read_line one pixel at a time to achieve the same.
> 
> Would need to benchmark if this is significantly slower than your
> suggestion for dir=RIGHT, though. If it's roughly the same, then it
> would probably be worth it.
> 
> 
>> This way:
>> - It's simple to read for the general case (usage of drm_rect_* instead of 
>>   manually rewriting the logic)
>> - Each pixel format can be quickly implemented with "pixel-by-pixel" 
>>   methods
>> - The performances should be good if no rotation is implied for some 
>>   formats
>>
>> I also created some helpers for conversions between formats to avoid code 
>> duplication between pixel and line algorithms (and also between argb and 
>> xrgb variants).
>>
>> The only flaw with this, is that most of the read_line functions will 
>> look like:
>>
>> void read_line(...) {
>>  int increment = x_start < x_stop ? 1: -1;
>>  while(x_start != x_stop) {
>>  out += 1;
>>  [...] /* color conversion */
>>  x_start += increment;
>>  }
>> }
>>
>> But as Pekka explained, it's probably the most efficient way to do it.
> 
> Yes, I expect them to look roughly like that. It's necessary for moving
> as much of the setup computations and real function calls out of the
> inner-most loop as possible. The middle (over KMS planes) and outer
> (over y) loops are less sensitive to wasted cycles on redundant
> computations.
> 
>> Is there a way to save the output of vkms to a folder (something like 
>> "one image per frame")? It's a bit complex to debug graphics without 
>> seeing them.
>>
>> I have something which (I think) should work, but some tests are failing 
>> and I don't find why in my code (I don't find the reason why the they are 
>> failing and the hexdump I added to debug seems normal).
>>
>> I think my issue is a simple mistake in the "translation managment" or 
>> maybe just a wrong offset, but I don't see my error in the code. I think a 
>> quick look on the final image would help me a lot.
> 
> I don't know anything about the kernel unit testing frameworks, maybe
> they could help?
> 
> But if you drive the test through UAPI from userspace, use a writeback
> connector to fetch the resulting image. I'm sure IGT has code doing
> that somewhere, although many IGT tests rely on CRC instead because CRC
> is more widely available in hardware.
> 
> Arthur's new benchmark seems to be using writeback, you just need to
> make it save to file:
> https://lore.kernel.org/all/20240207-bench-v1-1-7135ad426...@riseup.net/

Hi,

I just found that the IGT's test kms_writeback has a flag '--dump' that
does that, maybe you can use it or copy the logic to the benchmark.

Best Regards,
~Arthur Grillo

> 
> 
> Thanks,
> pq


Re: [PATCH i-g-t v3] benchmarks: Add VKMS benchmark

2024-02-13 Thread Arthur Grillo



On 13/02/24 15:06, Kamil Konieczny wrote:
> Hi Arthur,
> On 2024-02-09 at 16:39:09 -0300, Arthur Grillo wrote:
> 
> I will merge this with different description:
> 
> [PATCH i-g-t v3] benchmarks: Add KMS frambuffer stress benchmark
> 
> Is this ok?

Its ok

Best Regards,
~Arthur Grillo

> 
> Regards,
> Kamil
> 
>> Create a benchmark for the VKMS driver. Use a KMS layout with deliberate
>> odd sizes to try to avoid alignment accidents and run it for FRAME_COUNT
>> frames flipping framebuffers in each plane.
>>
>> This benchmark was suggested by Pekka Paalanen to better analyse
>> possible performance regression on the Virtual Kernel Modesetting(VKMS)
>> driver.
>>
>> With this benchmark I was able to determine two performance regression:
>>
>> - 322d716a3e8a ("drm/vkms: isolate pixel conversion functionality")
>> - cc4fd2934d41 ("drm/vkms: Isolate writeback pixel conversion functions")
>>
>> Link: https://lore.kernel.org/all/20240202214527.1d97c881@ferris.localdomain/
>> Suggested-by: Pekka Paalanen 
>> Acked-by: Pekka Paalanen 
>> Acked-by: Maíra Canal 
>> Acked-by: Kamil Konieczny 
>> Signed-off-by: Arthur Grillo 
>> ---
>> Changes in v3:
>> - Change primary plane width to not extend outside the CRTC size
>> - Explicitly set a big CRTC size (Peeka Paalanen)
>> - Report time spent in the loop (Peeka Paalanen)
>> - Put file name in alphabetical order on meson script (Kamil Konieczny)
>> - Link to v2: 
>> https://lore.kernel.org/r/20240208-bench-v2-1-1eccee105...@riseup.net
>>
>> Changes in v2:
>> - Zero initialize data
>> - Don't wrap igt_create_* functions (Juha-Pekka Heikkila)
>> - Add a `break;` when a pipe is found (Pekka Paalanen)
>> - Rename file to kms_fb_stress.c (Kamil Konieczny)
>> - Replace 2 by NUM_FBS (Juha-Pekka Heikkila)
>> - Replace license text by SPDX License (Kamil Konieczny)
>> - Move explanations to commit description (Kamil Konieczny)
>> - Require output after find_wb_output() (Pekka Paalanen & Juha-Pekka
>>   Heikkila)
>> - Remove unnecessary commit (Pekka Paalanen)
>> - Link to v1: 
>> https://lore.kernel.org/r/20240207-bench-v1-1-7135ad426...@riseup.net
>> ---
>>  benchmarks/kms_fb_stress.c | 208 
>> +
>>  benchmarks/meson.build |   1 +
>>  2 files changed, 209 insertions(+)
>>
>> diff --git a/benchmarks/kms_fb_stress.c b/benchmarks/kms_fb_stress.c
>> new file mode 100644
>> index ..9a0e98bed8ad
>> --- /dev/null
>> +++ b/benchmarks/kms_fb_stress.c
>> @@ -0,0 +1,208 @@
>> +// SPDX-License-Identifier: MIT
>> +/*
>> + * Copyright © 2024 Arthur Grillo
>> + */
>> +
>> +#include "igt.h"
>> +
>> +#define FRAME_COUNT 100
>> +#define NUM_FBS 2
>> +
>> +struct rect_t {
>> +int x, y;
>> +int width, height;
>> +};
>> +
>> +struct plane_t {
>> +igt_plane_t *base;
>> +struct rect_t rect;
>> +uint32_t format;
>> +struct igt_fb fbs[NUM_FBS];
>> +};
>> +
>> +struct kms_t {
>> +struct rect_t crtc;
>> +struct plane_t primary;
>> +struct plane_t overlay_a;
>> +struct plane_t overlay_b;
>> +struct plane_t writeback;
>> +};
>> +
>> +struct data_t {
>> +int fd;
>> +igt_display_t display;
>> +igt_output_t *wb_output;
>> +drmModeModeInfo *mode;
>> +struct kms_t kms;
>> +};
>> +
>> +static void plane_setup(struct plane_t *plane, int index)
>> +{
>> +igt_plane_set_size(plane->base, plane->rect.width, plane->rect.height);
>> +igt_plane_set_position(plane->base, plane->rect.x, plane->rect.y);
>> +igt_plane_set_fb(plane->base, >fbs[index]);
>> +}
>> +
>> +static void gen_fbs(struct data_t *data)
>> +{
>> +struct kms_t *kms = >kms;
>> +drmModeModeInfo *mode = igt_output_get_mode(data->wb_output);
>> +
>> +for (int i = 0; i < NUM_FBS; i++) {
>> +igt_create_color_fb(data->fd, kms->primary.rect.width, 
>> kms->primary.rect.height,
>> +kms->primary.format, DRM_FORMAT_MOD_LINEAR,
>> +!i, i, i,
>> +>primary.fbs[i]);
>> +
>> +igt_create_color_fb(data->fd, kms->overlay_a.rect.width, 
>> kms->overlay_a.rect.height,
>> +

[PATCH i-g-t v3] benchmarks: Add VKMS benchmark

2024-02-09 Thread Arthur Grillo
Create a benchmark for the VKMS driver. Use a KMS layout with deliberate
odd sizes to try to avoid alignment accidents and run it for FRAME_COUNT
frames flipping framebuffers in each plane.

This benchmark was suggested by Pekka Paalanen to better analyse
possible performance regression on the Virtual Kernel Modesetting(VKMS)
driver.

With this benchmark I was able to determine two performance regression:

- 322d716a3e8a ("drm/vkms: isolate pixel conversion functionality")
- cc4fd2934d41 ("drm/vkms: Isolate writeback pixel conversion functions")

Link: https://lore.kernel.org/all/20240202214527.1d97c881@ferris.localdomain/
Suggested-by: Pekka Paalanen 
Acked-by: Pekka Paalanen 
Acked-by: Maíra Canal 
Acked-by: Kamil Konieczny 
Signed-off-by: Arthur Grillo 
---
Changes in v3:
- Change primary plane width to not extend outside the CRTC size
- Explicitly set a big CRTC size (Peeka Paalanen)
- Report time spent in the loop (Peeka Paalanen)
- Put file name in alphabetical order on meson script (Kamil Konieczny)
- Link to v2: 
https://lore.kernel.org/r/20240208-bench-v2-1-1eccee105...@riseup.net

Changes in v2:
- Zero initialize data
- Don't wrap igt_create_* functions (Juha-Pekka Heikkila)
- Add a `break;` when a pipe is found (Pekka Paalanen)
- Rename file to kms_fb_stress.c (Kamil Konieczny)
- Replace 2 by NUM_FBS (Juha-Pekka Heikkila)
- Replace license text by SPDX License (Kamil Konieczny)
- Move explanations to commit description (Kamil Konieczny)
- Require output after find_wb_output() (Pekka Paalanen & Juha-Pekka
  Heikkila)
- Remove unnecessary commit (Pekka Paalanen)
- Link to v1: 
https://lore.kernel.org/r/20240207-bench-v1-1-7135ad426...@riseup.net
---
 benchmarks/kms_fb_stress.c | 208 +
 benchmarks/meson.build |   1 +
 2 files changed, 209 insertions(+)

diff --git a/benchmarks/kms_fb_stress.c b/benchmarks/kms_fb_stress.c
new file mode 100644
index ..9a0e98bed8ad
--- /dev/null
+++ b/benchmarks/kms_fb_stress.c
@@ -0,0 +1,208 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2024 Arthur Grillo
+ */
+
+#include "igt.h"
+
+#define FRAME_COUNT 100
+#define NUM_FBS 2
+
+struct rect_t {
+   int x, y;
+   int width, height;
+};
+
+struct plane_t {
+   igt_plane_t *base;
+   struct rect_t rect;
+   uint32_t format;
+   struct igt_fb fbs[NUM_FBS];
+};
+
+struct kms_t {
+   struct rect_t crtc;
+   struct plane_t primary;
+   struct plane_t overlay_a;
+   struct plane_t overlay_b;
+   struct plane_t writeback;
+};
+
+struct data_t {
+   int fd;
+   igt_display_t display;
+   igt_output_t *wb_output;
+   drmModeModeInfo *mode;
+   struct kms_t kms;
+};
+
+static void plane_setup(struct plane_t *plane, int index)
+{
+   igt_plane_set_size(plane->base, plane->rect.width, plane->rect.height);
+   igt_plane_set_position(plane->base, plane->rect.x, plane->rect.y);
+   igt_plane_set_fb(plane->base, >fbs[index]);
+}
+
+static void gen_fbs(struct data_t *data)
+{
+   struct kms_t *kms = >kms;
+   drmModeModeInfo *mode = igt_output_get_mode(data->wb_output);
+
+   for (int i = 0; i < NUM_FBS; i++) {
+   igt_create_color_fb(data->fd, kms->primary.rect.width, 
kms->primary.rect.height,
+   kms->primary.format, DRM_FORMAT_MOD_LINEAR,
+   !i, i, i,
+   >primary.fbs[i]);
+
+   igt_create_color_fb(data->fd, kms->overlay_a.rect.width, 
kms->overlay_a.rect.height,
+   kms->overlay_a.format, 
DRM_FORMAT_MOD_LINEAR,
+   i, !i, i,
+   >overlay_a.fbs[i]);
+
+   igt_create_color_fb(data->fd, kms->overlay_b.rect.width, 
kms->overlay_b.rect.height,
+   kms->overlay_b.format, 
DRM_FORMAT_MOD_LINEAR,
+   i, i, !i,
+   >overlay_b.fbs[i]);
+
+   kms->writeback.rect.width = mode->hdisplay;
+   kms->writeback.rect.height = mode->vdisplay;
+   igt_create_fb(data->fd, kms->writeback.rect.width, 
kms->writeback.rect.height,
+ kms->writeback.format, DRM_FORMAT_MOD_LINEAR,
+ >writeback.fbs[i]);
+   }
+}
+
+static igt_output_t *find_wb_output(struct data_t *data)
+{
+   for (int i = 0; i < data->display.n_outputs; i++) {
+   igt_output_t *output = >display.outputs[i];
+
+   if (output->config.connector->connector_type != 
DRM_MODE_CONNECTOR_WRITEBACK)
+   continue;
+
+   return output;
+
+   }
+
+   return NULL;
+}
+
+static void set_crtc_size(struct data_t *

Re: [PATCH i-g-t] benchmarks: Add VKMS benchmark

2024-02-09 Thread Arthur Grillo



On 09/02/24 05:32, Pekka Paalanen wrote:
> On Thu, 8 Feb 2024 16:38:31 -0300
> Arthur Grillo  wrote:
> 
>> On 08/02/24 06:50, Pekka Paalanen wrote:
>>> On Wed, 07 Feb 2024 17:17:15 -0300
>>> Arthur Grillo  wrote:
>>>   
>>>> Create a benchmark for the VKMS driver. Use a KMS layout with deliberate
>>>> odd sizes to try to avoid alignment accidents and run it for FRAME_COUNT
>>>> frames flipping framebuffers in each plane.
>>>>
>>>> Link: 
>>>> https://lore.kernel.org/all/20240202214527.1d97c881@ferris.localdomain/
>>>> Suggested-by: Pekka Paalanen 
>>>> Signed-off-by: Arthur Grillo 
>>>> ---
>>>> This benchmark was suggested by Pekka Paalanen on [1] to better analyse
>>>> possible performance regression on the Virtual Kernel Modesetting(VKMS)
>>>> driver.
>>>>
>>>> With this benchmark I was able to determine two performance regression:
>>>>
>>>> - 322d716a3e8a ("drm/vkms: isolate pixel conversion functionality")
>>>> - cc4fd2934d41 ("drm/vkms: Isolate writeback pixel conversion functions")
>>>>
>>>> [1]: 
>>>> https://lore.kernel.org/all/20240202214527.1d97c881@ferris.localdomain/
>>>> ---
>>>>  benchmarks/meson.build   |   1 +
>>>>  benchmarks/vkms_stress.c | 203 
>>>> +++
>>>>  2 files changed, 204 insertions(+)
>>>>
>>>> diff --git a/benchmarks/meson.build b/benchmarks/meson.build
>>>> index c451268bc44f..3aa66d6dffe2 100644
>>>> --- a/benchmarks/meson.build
>>>> +++ b/benchmarks/meson.build
>>>> @@ -20,6 +20,7 @@ benchmark_progs = [
>>>>'kms_vblank',
>>>>'prime_lookup',
>>>>'vgem_mmap',
>>>> +  'vkms_stress',
>>>>  ]
>>>>  
>>>>  benchmarksdir = join_paths(libexecdir, 'benchmarks')
>>>> diff --git a/benchmarks/vkms_stress.c b/benchmarks/vkms_stress.c
>>>> new file mode 100644
>>>> index ..b9128c208861
>>>> --- /dev/null
>>>> +++ b/benchmarks/vkms_stress.c
> 
> ...
> 
>>>> +
>>>> +igt_simple_main
>>>> +{
>>>> +  struct data_t data;
>>>> +  enum pipe pipe = PIPE_NONE;
>>>> +
>>>> +  data.kms = default_kms;
>>>> +  
>>>
>>> Hi Arthur,
>>>
>>> all the above looks really good!
>>>
>>> Some things below look strange to me, but I don't know the igt API.
>>>   
>>>> +  data.fd = drm_open_driver_master(DRIVER_ANY);
>>>> +
>>>> +  igt_display_require(, data.fd);
>>>> +
>>>> +  kmstest_set_vt_graphics_mode();
>>>> +
>>>> +  igt_display_require(, data.fd);  
>>>
>>> Are you supposed to call igt_display_require twice?
>>>   
>>
>> Only this way the writeback connector appears. I took this from
>> `tests/kms_writeback.c`.
>>
>> I now did a bit of lore.kernel.org archaeology and found why this is
>> necessary:
>>
>> Rodrigo Siqueira sent this patch:
>> https://lore.kernel.org/all/20190306213005.7hvbnwl7dohr3...@smtp.gmail.com/
>>
>> It places drmSetClientCap() before drmModeGetResources(). (The patch
>> description is wrong, as noted by [1])
>>
>> Without this, you don't need to call igt_display_require() twice. I
>> don't know if this patch is wrong, but it is good to bring it up for
>> discussion.
> 
> Hi Arthur,
> 
> did you mean "*With* this, you don't need to call igt_display_require()
> twice."?

No, I really meant _without_. The patch has already been applied, it was
added inside commit 3642acbb74f5 ("lib/igt_kms: Add writeback support")
(it says on the commit message).

If you remove this change you don't need to call igt_display_require()
twice. But, based on you explanation, I don't think it's right to remove
it. Although, for some reason, you need call igt_display_require() twice
with this fix.

Best Regards,
~Arthur Grillo

> 
> All DRM client caps do need to be set before any call to GetResources
> or anything else, exactly because the client caps change the kernel
> side behaviour. Client caps may also hide things, not only expose
> things, at least in the future if not already (color pipelines will
> replace legacy color properties).
> 
> If you need to check DRM (kernel) caps, that should be done immediately
> after setting DRM client caps. I think that's the most logical and
> safest order.
> 
> 
> Thanks,
> pq
> 
>>
>> [1]: 
>> https://lore.kernel.org/all/20190318104128.gh26...@e110455-lin.cambridge.arm.com/
>>
>>>> +  igt_require(data.display.is_atomic);
>>>> +
>>>> +  igt_display_require_output();
>>>> +
>>>> +  igt_require(data.wb_output);
>>>> +  igt_display_reset();
>>>> +
>>>> +  data.wb_output = find_wb_output();  
>>>
>>> Should igt_require(data.wb_output) be after find_wb_output?
>>>   
>>>> +
>>>> +  for_each_pipe(, pipe) {
>>>> +  igt_debug("Selecting pipe %s to %s\n",
>>>> +kmstest_pipe_name(pipe),
>>>> +igt_output_name(data.wb_output));
>>>> +  igt_output_set_pipe(data.wb_output, pipe);  
>>>
>>> Isn't this strange if there are multiple pipes?  
>>
>> Yeah, I forgot to place a `break;` there.
>>
>> All the others comments will be addressed on v2.
>>
>> Best Regards,
>> ~Arthur Grillo


[PATCH i-g-t v2] benchmarks: Add VKMS benchmark

2024-02-08 Thread Arthur Grillo
Create a benchmark for the VKMS driver. Use a KMS layout with deliberate
odd sizes to try to avoid alignment accidents and run it for FRAME_COUNT
frames flipping framebuffers in each plane.

This benchmark was suggested by Pekka Paalanen to better analyse
possible performance regression on the Virtual Kernel Modesetting(VKMS)
driver.

With this benchmark I was able to determine two performance regression:

- 322d716a3e8a ("drm/vkms: isolate pixel conversion functionality")
- cc4fd2934d41 ("drm/vkms: Isolate writeback pixel conversion functions")

Link: https://lore.kernel.org/all/20240202214527.1d97c881@ferris.localdomain/
Suggested-by: Pekka Paalanen 
Acked-by: Pekka Paalanen 
Signed-off-by: Arthur Grillo 
---
Changes in v2:
- Zero initialize data
- Don't wrap igt_create_* functions (Juha-Pekka Heikkila)
- Add a `break;` when a pipe is found (Pekka Paalanen)
- Rename file to kms_fb_stress.c (Kamil Konieczny)
- Replace 2 by NUM_FBS (Juha-Pekka Heikkila)
- Replace license text by SPDX License (Kamil Konieczny)
- Move explanations to commit description (Kamil Konieczny)
- Require output after find_wb_output() (Pekka Paalanen & Juha-Pekka
  Heikkila)
- Remove unnecessary commit (Pekka Paalanen)
- Link to v1: 
https://lore.kernel.org/r/20240207-bench-v1-1-7135ad426...@riseup.net
---
 benchmarks/kms_fb_stress.c | 176 +
 benchmarks/meson.build |   1 +
 2 files changed, 177 insertions(+)

diff --git a/benchmarks/kms_fb_stress.c b/benchmarks/kms_fb_stress.c
new file mode 100644
index ..af0014bed672
--- /dev/null
+++ b/benchmarks/kms_fb_stress.c
@@ -0,0 +1,176 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2024 Arthur Grillo
+ */
+
+#include "igt.h"
+
+#define FRAME_COUNT 100
+#define NUM_FBS 2
+
+struct rect_t {
+   int x, y;
+   int width, height;
+};
+
+struct plane_t {
+   igt_plane_t *base;
+   struct rect_t rect;
+   uint32_t format;
+   struct igt_fb fbs[NUM_FBS];
+};
+
+struct kms_t {
+   struct plane_t primary;
+   struct plane_t overlay_a;
+   struct plane_t overlay_b;
+   struct plane_t writeback;
+};
+
+struct data_t {
+   int fd;
+   igt_display_t display;
+   igt_output_t *wb_output;
+   drmModeModeInfo *mode;
+   struct kms_t kms;
+};
+
+static void plane_setup(struct plane_t *plane, int index)
+{
+   igt_plane_set_size(plane->base, plane->rect.width, plane->rect.height);
+   igt_plane_set_position(plane->base, plane->rect.x, plane->rect.y);
+   igt_plane_set_fb(plane->base, >fbs[index]);
+}
+
+static void gen_fbs(struct data_t *data)
+{
+   struct kms_t *kms = >kms;
+   drmModeModeInfo *mode = igt_output_get_mode(data->wb_output);
+
+   for (int i = 0; i < NUM_FBS; i++) {
+   igt_create_color_fb(data->fd, kms->primary.rect.width, 
kms->primary.rect.height,
+   kms->primary.format, DRM_FORMAT_MOD_LINEAR,
+   !i, i, i,
+   >primary.fbs[i]);
+
+   igt_create_color_fb(data->fd, kms->overlay_a.rect.width, 
kms->overlay_a.rect.height,
+   kms->overlay_a.format, 
DRM_FORMAT_MOD_LINEAR,
+   i, !i, i,
+   >overlay_a.fbs[i]);
+
+   igt_create_color_fb(data->fd, kms->overlay_b.rect.width, 
kms->overlay_b.rect.height,
+   kms->overlay_b.format, 
DRM_FORMAT_MOD_LINEAR,
+   i, i, !i,
+   >overlay_b.fbs[i]);
+
+   kms->writeback.rect.width = mode->hdisplay;
+   kms->writeback.rect.height = mode->vdisplay;
+   igt_create_fb(data->fd, kms->writeback.rect.width, 
kms->writeback.rect.height,
+ kms->writeback.format, DRM_FORMAT_MOD_LINEAR,
+ >writeback.fbs[i]);
+   }
+}
+
+static igt_output_t *find_wb_output(struct data_t *data)
+{
+   for (int i = 0; i < data->display.n_outputs; i++) {
+   igt_output_t *output = >display.outputs[i];
+
+   if (output->config.connector->connector_type != 
DRM_MODE_CONNECTOR_WRITEBACK)
+   continue;
+
+   return output;
+
+   }
+
+   return NULL;
+}
+
+static struct kms_t default_kms = {
+   .primary = {
+   .rect = {
+   .x = 101, .y = 0,
+   .width = 3639, .height = 2161,
+   },
+   .format = DRM_FORMAT_XRGB,
+   },
+   .overlay_a = {
+   .rect = {
+   .x = 201, .y = 199,
+   .width = 3033, .height = 1777,
+   },
+   .format = DRM_FORMAT_XR

Re: [PATCH i-g-t] benchmarks: Add VKMS benchmark

2024-02-08 Thread Arthur Grillo



On 08/02/24 06:50, Pekka Paalanen wrote:
> On Wed, 07 Feb 2024 17:17:15 -0300
> Arthur Grillo  wrote:
> 
>> Create a benchmark for the VKMS driver. Use a KMS layout with deliberate
>> odd sizes to try to avoid alignment accidents and run it for FRAME_COUNT
>> frames flipping framebuffers in each plane.
>>
>> Link: https://lore.kernel.org/all/20240202214527.1d97c881@ferris.localdomain/
>> Suggested-by: Pekka Paalanen 
>> Signed-off-by: Arthur Grillo 
>> ---
>> This benchmark was suggested by Pekka Paalanen on [1] to better analyse
>> possible performance regression on the Virtual Kernel Modesetting(VKMS)
>> driver.
>>
>> With this benchmark I was able to determine two performance regression:
>>
>> - 322d716a3e8a ("drm/vkms: isolate pixel conversion functionality")
>> - cc4fd2934d41 ("drm/vkms: Isolate writeback pixel conversion functions")
>>
>> [1]: https://lore.kernel.org/all/20240202214527.1d97c881@ferris.localdomain/
>> ---
>>  benchmarks/meson.build   |   1 +
>>  benchmarks/vkms_stress.c | 203 
>> +++
>>  2 files changed, 204 insertions(+)
>>
>> diff --git a/benchmarks/meson.build b/benchmarks/meson.build
>> index c451268bc44f..3aa66d6dffe2 100644
>> --- a/benchmarks/meson.build
>> +++ b/benchmarks/meson.build
>> @@ -20,6 +20,7 @@ benchmark_progs = [
>>  'kms_vblank',
>>  'prime_lookup',
>>  'vgem_mmap',
>> +'vkms_stress',
>>  ]
>>  
>>  benchmarksdir = join_paths(libexecdir, 'benchmarks')
>> diff --git a/benchmarks/vkms_stress.c b/benchmarks/vkms_stress.c
>> new file mode 100644
>> index ..b9128c208861
>> --- /dev/null
>> +++ b/benchmarks/vkms_stress.c
>> @@ -0,0 +1,203 @@
>> +/*
>> + * Copyright © 2024 Arthur Grillo
>> + *
>> + * Permission is hereby granted, free of charge, to any person obtaining a
>> + * copy of this software and associated documentation files (the 
>> "Software"),
>> + * to deal in the Software without restriction, including without limitation
>> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
>> + * and/or sell copies of the Software, and to permit persons to whom the
>> + * Software is furnished to do so, subject to the following conditions:
>> + *
>> + * The above copyright notice and this permission notice (including the next
>> + * paragraph) shall be included in all copies or substantial portions of the
>> + * Software.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
>> OR
>> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
>> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
>> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 
>> OTHER
>> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
>> DEALINGS
>> + * IN THE SOFTWARE.
>> + *
>> + * Authors:
>> + *Arthur Grillo 
>> + *
>> + */
>> +
>> +#include "igt.h"
>> +
>> +#define FRAME_COUNT 100
>> +
>> +struct rect_t {
>> +int x, y;
>> +int width, height;
>> +};
>> +
>> +struct plane_t {
>> +igt_plane_t *base;
>> +struct rect_t rect;
>> +uint32_t format;
>> +struct igt_fb fbs[2];
>> +};
>> +
>> +struct kms_t {
>> +struct plane_t primary;
>> +struct plane_t overlay_a;
>> +struct plane_t overlay_b;
>> +struct plane_t writeback;
>> +};
>> +
>> +struct data_t {
>> +int fd;
>> +igt_display_t display;
>> +igt_output_t *wb_output;
>> +drmModeModeInfo *mode;
>> +struct kms_t kms;
>> +};
>> +
>> +static void plane_create_fb(struct plane_t *plane, int fd, size_t index)
>> +{
>> +igt_create_fb(fd, plane->rect.width, plane->rect.height,
>> +plane->format, DRM_FORMAT_MOD_LINEAR,
>> +>fbs[index]);
>> +}
>> +
>> +static void plane_create_color_fb(struct plane_t *plane, int fd, size_t 
>> index, double r, double g,
>> +   double b)
>> +{
>> +igt_create_color_fb(fd, plane->rect.width, plane->rect.height,
>> +plane->format, DRM_FORMAT_MOD_LINEAR,
>> +r, g, b,

Re: [PATCH 2/2] drm/vkms: Use a simpler composition function

2024-02-07 Thread Arthur Grillo



On 07/02/24 13:03, Louis Chauvet wrote:
> Hello Pekka, Arthur,
> 
> [...]
> 
 Would it be possible to have a standardised benchmark specifically
 for performance rather than correctness, in IGT or where-ever it
 would make sense? Then it would be simple to tell contributors to
 run this and report the numbers before and after.

 I would propose this kind of KMS layout:

 - CRTC size 3841 x 2161
 - primary plane, XRGB, 3639 x 2161 @ 101,0
 - overlay A, XBGR2101010, 3033 x 1777 @ 201,199
 - overlay B, ARGB, 1507 x 1400 @ 1800,250

 The sizes and positions are deliberately odd to try to avoid happy
 alignment accidents. The planes are big, which should let the pixel
 operations easily dominate performance measurement. There are
 different pixel formats, both opaque and semi-transparent. There is
 lots of plane overlap. The planes also do not cover the whole CRTC
 leaving the background visible a bit.

 There should be two FBs per each plane, flipped alternatingly each
 frame. Writeback should be active. Run this a number of frames, say,
 100, and measure the kernel CPU time taken. It's supposed to take at
 least several seconds in total.

 I think something like this should be the base benchmark. One can
 add more to it, like rotated planes, YUV planes, etc. or switch
 settings on the existing planes. Maybe even FB_DAMAGE_CLIPS. Maybe
 one more overlay that is very tall and thin.

 Just an idea, what do you all think?  
>>>
>>> Hi Pekka,
>>>
>>> I just finished writing this proposal using IGT.
>>>
>>> I got pretty interesting results:
>>>
>>> The mentioned commit 8356b97906503a02125c8d03c9b88a61ea46a05a took
>>> around 13 seconds. While drm-misc/drm-misc-next took 36 seconds.
>>>
>>> I'm currently bisecting to be certain that the change to the
>>> pixel-by-pixel is the culprit, but I don't see why it wouldn't be.
>>>
>>> I just need to do some final touches on the benchmark code and it
>>> will be ready for revision.
>>
>> Awesome, thank you very much for doing that!
>> pq
> 
> I also think it's a good benchmarks for classic configurations. The odd 
> size is a very nice idea to verify the corner cases of line-by-line 
> algorithms.
> 
> When this is ready, please share the test, so I can check if my patch is 
> as performant as before.
> 
> Thank you for this work.
> 
> Have a nice day,
> Louis Chauvet
> 

Just sent the benchmark for revision:
https://lore.kernel.org/r/20240207-bench-v1-1-7135ad426...@riseup.net


[PATCH i-g-t] benchmarks: Add VKMS benchmark

2024-02-07 Thread Arthur Grillo
Create a benchmark for the VKMS driver. Use a KMS layout with deliberate
odd sizes to try to avoid alignment accidents and run it for FRAME_COUNT
frames flipping framebuffers in each plane.

Link: https://lore.kernel.org/all/20240202214527.1d97c881@ferris.localdomain/
Suggested-by: Pekka Paalanen 
Signed-off-by: Arthur Grillo 
---
This benchmark was suggested by Pekka Paalanen on [1] to better analyse
possible performance regression on the Virtual Kernel Modesetting(VKMS)
driver.

With this benchmark I was able to determine two performance regression:

- 322d716a3e8a ("drm/vkms: isolate pixel conversion functionality")
- cc4fd2934d41 ("drm/vkms: Isolate writeback pixel conversion functions")

[1]: https://lore.kernel.org/all/20240202214527.1d97c881@ferris.localdomain/
---
 benchmarks/meson.build   |   1 +
 benchmarks/vkms_stress.c | 203 +++
 2 files changed, 204 insertions(+)

diff --git a/benchmarks/meson.build b/benchmarks/meson.build
index c451268bc44f..3aa66d6dffe2 100644
--- a/benchmarks/meson.build
+++ b/benchmarks/meson.build
@@ -20,6 +20,7 @@ benchmark_progs = [
'kms_vblank',
'prime_lookup',
'vgem_mmap',
+   'vkms_stress',
 ]
 
 benchmarksdir = join_paths(libexecdir, 'benchmarks')
diff --git a/benchmarks/vkms_stress.c b/benchmarks/vkms_stress.c
new file mode 100644
index ..b9128c208861
--- /dev/null
+++ b/benchmarks/vkms_stress.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright © 2024 Arthur Grillo
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *Arthur Grillo 
+ *
+ */
+
+#include "igt.h"
+
+#define FRAME_COUNT 100
+
+struct rect_t {
+   int x, y;
+   int width, height;
+};
+
+struct plane_t {
+   igt_plane_t *base;
+   struct rect_t rect;
+   uint32_t format;
+   struct igt_fb fbs[2];
+};
+
+struct kms_t {
+   struct plane_t primary;
+   struct plane_t overlay_a;
+   struct plane_t overlay_b;
+   struct plane_t writeback;
+};
+
+struct data_t {
+   int fd;
+   igt_display_t display;
+   igt_output_t *wb_output;
+   drmModeModeInfo *mode;
+   struct kms_t kms;
+};
+
+static void plane_create_fb(struct plane_t *plane, int fd, size_t index)
+{
+   igt_create_fb(fd, plane->rect.width, plane->rect.height,
+   plane->format, DRM_FORMAT_MOD_LINEAR,
+   >fbs[index]);
+}
+
+static void plane_create_color_fb(struct plane_t *plane, int fd, size_t index, 
double r, double g,
+  double b)
+{
+   igt_create_color_fb(fd, plane->rect.width, plane->rect.height,
+   plane->format, DRM_FORMAT_MOD_LINEAR,
+   r, g, b,
+   >fbs[index]);
+}
+
+static void plane_setup(struct plane_t *plane, int index)
+{
+   igt_plane_set_size(plane->base, plane->rect.width, plane->rect.height);
+   igt_plane_set_position(plane->base, plane->rect.x, plane->rect.y);
+   igt_plane_set_fb(plane->base, >fbs[index]);
+}
+
+static void gen_fbs(struct data_t *data)
+{
+   struct kms_t *kms = >kms;
+   drmModeModeInfo *mode = igt_output_get_mode(data->wb_output);
+
+   for (int i = 0; i < 2; i++) {
+   plane_create_color_fb(>primary, data->fd, i, !i, i, i);
+
+   plane_create_color_fb(>overlay_a, data->fd, i, i, !i, i);
+
+   plane_create_color_fb(>overlay_b, data->fd, i, i, i, !i);
+
+   kms->writeback.rect.width = mode->hdisplay;
+   kms->writeback.rect.height = mode->vdisplay;
+   plane_create_fb(>writeback, data->fd, i);
+   }
+}
+
+static igt_output_t *find_wb_output(struct data_t *data)
+{
+   for (int i = 0; i < data->

Re: [PATCH 2/2] drm/vkms: Use a simpler composition function

2024-02-06 Thread Arthur Grillo



On 02/02/24 16:45, Pekka Paalanen wrote:
> On Fri, 2 Feb 2024 17:07:34 +0100
> Miquel Raynal  wrote:
> 
>> Hi Pekka,
> 
> Hi Miquel,
> 
> I'm happy to see no hard feelings below. I know I may be blunt at
> times.
> 
> Another thing coming to my mind is that I suppose there is no
> agreed standard benchmark for VKMS performance, is there?
> 
> I recall people running selected IGT tests in a loop in the past,
> and I worry that the IGT start-up overhead and small plane
> dimensions might skew the results.
> 
> Would it be possible to have a standardised benchmark specifically
> for performance rather than correctness, in IGT or where-ever it
> would make sense? Then it would be simple to tell contributors to
> run this and report the numbers before and after.
> 
> I would propose this kind of KMS layout:
> 
> - CRTC size 3841 x 2161
> - primary plane, XRGB, 3639 x 2161 @ 101,0
> - overlay A, XBGR2101010, 3033 x 1777 @ 201,199
> - overlay B, ARGB, 1507 x 1400 @ 1800,250
> 
> The sizes and positions are deliberately odd to try to avoid happy
> alignment accidents. The planes are big, which should let the pixel
> operations easily dominate performance measurement. There are
> different pixel formats, both opaque and semi-transparent. There is
> lots of plane overlap. The planes also do not cover the whole CRTC
> leaving the background visible a bit.
> 
> There should be two FBs per each plane, flipped alternatingly each
> frame. Writeback should be active. Run this a number of frames, say,
> 100, and measure the kernel CPU time taken. It's supposed to take at
> least several seconds in total.
> 
> I think something like this should be the base benchmark. One can
> add more to it, like rotated planes, YUV planes, etc. or switch
> settings on the existing planes. Maybe even FB_DAMAGE_CLIPS. Maybe
> one more overlay that is very tall and thin.
> 
> Just an idea, what do you all think?

Hi Pekka,

I just finished writing this proposal using IGT.

I got pretty interesting results:

The mentioned commit 8356b97906503a02125c8d03c9b88a61ea46a05a took
around 13 seconds. While drm-misc/drm-misc-next took 36 seconds.

I'm currently bisecting to be certain that the change to the
pixel-by-pixel is the culprit, but I don't see why it wouldn't be.

I just need to do some final touches on the benchmark code and it
will be ready for revision.

Best Regards,
~Arthur Grillo

> 
> 
> Thanks,
> pq
> 
>> pekka.paala...@haloniitty.fi wrote on Fri, 2 Feb 2024 17:49:13 +0200:
>>
>>> On Fri, 2 Feb 2024 13:13:22 +0100
>>> Miquel Raynal  wrote:
>>>   
>>>> Hello Maxime,
>>>>
>>>> + Arthur
>>>>
>>>> mrip...@kernel.org wrote on Fri, 2 Feb 2024 10:53:37 +0100:
>>>> 
>>>>> Hi Miquel,
>>>>>
>>>>> On Fri, Feb 02, 2024 at 10:26:01AM +0100, Miquel Raynal wrote:  
>>>>>> pekka.paala...@haloniitty.fi wrote on Fri, 2 Feb 2024 10:55:22 +0200:
>>>>>> 
>>>>>>> On Thu, 01 Feb 2024 18:31:32 +0100
>>>>>>> Louis Chauvet  wrote:
>>>>>>> 
>>>>>>>> Change the composition algorithm to iterate over pixels instead of 
>>>>>>>> lines.
>>>>>>>> It allows a simpler management of rotation and pixel access for 
>>>>>>>> complex formats.
>>>>>>>>
>>>>>>>> This new algorithm allows read_pixel function to have access to x/y
>>>>>>>> coordinates and make it possible to read the correct thing in a block
>>>>>>>> when block_w and block_h are not 1.
>>>>>>>> The iteration pixel-by-pixel in the same method also allows a simpler
>>>>>>>> management of rotation with drm_rect_* helpers. This way it's not 
>>>>>>>> needed
>>>>>>>> anymore to have misterious switch-case distributed in multiple places. 
>>>>>>>>  
>>>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>> there was a very good reason to write this code using lines:
>>>>>>> performance. Before lines, it was indeed operating on individual pixels.
>>>>>>>
>>>>>>> Please, include performance measurements before and after this series
>>>>>>> to quantify the impact on the previously already supported pixel
>>>>>>> formats, particularly the 32-bit-per-pixel RGB variants.
>>>>>>>
&

Re: [PATCH 1/2] drm/vkms: Create a type to check a function pointer validity

2024-02-02 Thread Arthur Grillo



On 01/02/24 14:31, Louis Chauvet wrote:
> Add the pixel_read_t type to check function prototype in structures
> and functions.
> It avoids casting to (void *) and at the same occasion allows the
> compiler to check the type properly.
> 
> Signed-off-by: Louis Chauvet 
> ---
>  drivers/gpu/drm/vkms/vkms_drv.h | 17 +++--
>  drivers/gpu/drm/vkms/vkms_formats.c |  4 ++--
>  drivers/gpu/drm/vkms/vkms_formats.h |  2 +-
>  3 files changed, 18 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
> index 51349a0c32d8..cb20bab26cae 100644
> --- a/drivers/gpu/drm/vkms/vkms_drv.h
> +++ b/drivers/gpu/drm/vkms/vkms_drv.h
> @@ -48,6 +48,20 @@ struct vkms_writeback_job {
>   void (*pixel_write)(u8 *dst_pixels, struct pixel_argb_u16 *in_pixel);
>  };
>  
> +/**
> + * typedef pixel_read_t - These functions are used to read the pixels in the 
> source frame, convert
> + * them to argb16 and write them to out_pixel.
> + * It assumes that src_pixels point to a valid pixel (not a block, or a 
> block of 1x1 pixel)
> + *
> + * @src_pixels: Source pointer to a pixel
> + * @out_pixel: Pointer where to write the pixel value
> + * @encoding: Color encoding to use (mainly used for YUV formats)
> + * @range: Color range to use (mainly used for YUV formats)
> + */
> +typedef void (*pixel_read_t)(u8 **src_pixels, int y,
> +  struct pixel_argb_u16 *out_pixel, enum 
> drm_color_encoding enconding,
> +  enum drm_color_range range);
> +
>  /**
>   * vkms_plane_state - Driver specific plane state
>   * @base: base plane state
> @@ -56,8 +70,7 @@ struct vkms_writeback_job {
>  struct vkms_plane_state {
>   struct drm_shadow_plane_state base;
>   struct vkms_frame_info *frame_info;
> - void (*pixel_read)(u8 **src_buffer, struct pixel_argb_u16 *out_pixel,
> -enum drm_color_encoding enconding, enum 
> drm_color_range range);
> + pixel_read_t pixel_read;

Hi,

Please Cc me on the next versions,

You added the argument 'y' to the function but did not change the calls
to it, resulting in a compiler error. I think this argument addition
would be better on patch #2.

Best Regards,
~Arthur Grillo

>  };
>  
>  struct vkms_plane {
> diff --git a/drivers/gpu/drm/vkms/vkms_formats.c 
> b/drivers/gpu/drm/vkms/vkms_formats.c
> index e06bbd7c0a67..c6376db58d38 100644
> --- a/drivers/gpu/drm/vkms/vkms_formats.c
> +++ b/drivers/gpu/drm/vkms/vkms_formats.c
> @@ -390,7 +390,7 @@ void vkms_writeback_row(struct vkms_writeback_job *wb,
>   wb->pixel_write(dst_pixels, _pixels[x]);
>  }
>  
> -void *get_pixel_conversion_function(u32 format)
> +pixel_read_t get_pixel_conversion_function(u32 format)
>  {
>   switch (format) {
>   case DRM_FORMAT_ARGB:
> @@ -420,7 +420,7 @@ void *get_pixel_conversion_function(u32 format)
>   case DRM_FORMAT_YVU444:
>   return _yvu_to_argb_u16;
>   default:
> - return NULL;
> + return (pixel_read_t)NULL;
>   }
>  }
>  
> diff --git a/drivers/gpu/drm/vkms/vkms_formats.h 
> b/drivers/gpu/drm/vkms/vkms_formats.h
> index 0cf835292cec..04e31e126ab1 100644
> --- a/drivers/gpu/drm/vkms/vkms_formats.h
> +++ b/drivers/gpu/drm/vkms/vkms_formats.h
> @@ -5,7 +5,7 @@
>  
>  #include "vkms_drv.h"
>  
> -void *get_pixel_conversion_function(u32 format);
> +pixel_read_t get_pixel_conversion_function(u32 format);
>  
>  void *get_pixel_write_function(u32 format);
>  
> 


Re: [PATCH 2/2] drm/vkms: Use a simpler composition function

2024-02-02 Thread Arthur Grillo
ptimized logic.
>> Performances would not change much as this path is not optimized today
>> anyway (the pixel-oriented logic is already used in the rotation case).
>>
>> Arthur's YUV implementation is indeed well optimized but the added
>> complexity probably lead to small mistakes in the logic. The
>> per-format read_line() implementation mentioned above could be
>> extended to the YUV format as well, which would leverage Arthur's
>> proposal by re-using his optimized version. Louis will help on this
>> regard. However, for more complex cases such as when there is a
>> rotation, it will be easier (and not sub-optimized compared to the RGB
>> case) to also fallback to a pixel-oriented processing.
>>
>> Would this approach make sense?
> 
> Hi,
> 
> I think it would, if I understand what you mean. Ever since I proposed
> a line-by-line algorithm to improve the performance, I was thinking of
> per-format read_line() functions that would be selected outside of any
> loops. Extending that to support YUV is only natural. I can imagine
> rotation complicates things, and I won't oppose that resulting in a
> much heavier read_line() implementation used in those cases. They might
> perhaps call the original read_line() implementations pixel-by-pixel or
> plane-by-plane (i.e. YUV planes) per pixel. Chroma-siting complicates
> things even further. That way one could compose any
> rotation-format-siting combination by chaining function pointers.
> 
> I haven't looked at VKMS in a long time, and I am disappointed to find
> that vkms_compose_row() is calling plane->pixel_read() pixel-by-pixel.
> The reading vfunc should be called with many pixels at a time when the
> source FB layout allows it. The whole point of the line-based functions
> was that they repeat the innermost loop in every function body to make
> the per-pixel overhead as small as possible. The VKMS implementations
> benchmarked before and after the original line-based algorithm showed
> that calling a function pointer per-pixel is relatively very expensive.
> Or maybe it was a switch-case.

Hi,

I think I'm the culprit for that, as stated on [1]. My intention with
the suggestion was to remove some code repetition and too facilitate the
rotation support implementation. Going back, I think I was to high on
DRY at the time and didn't worry about optimization, which was a
mistake.

But, I agree with Miquel that the rotation logic is easier to implement
in a pixel-based way. So going pixel-by-pixel only when rotation occurs
would be great.

Best Regards,
~Arthur Grillo

[1]: 
https://lore.kernel.org/dri-devel/20230418130525.128733-2-mca...@igalia.com/

> 
> Sorry, I didn't realize the optimization had already been lost.
> 
> Btw. I'd suggest renaming vkms_compose_row() to vkms_fetch_row() since
> it's not composing anything and the name mislead me.
> 
> I think if you inspect the compositing code as of revision
> 8356b97906503a02125c8d03c9b88a61ea46a05a you'll get a better feeling of
> what it was supposed to be.
> 
> 
> Thanks,
> pq


Re: [PATCH v2 2/7] drm/vkms: Add support for multy-planar framebuffers

2024-02-02 Thread Arthur Grillo
d be to profide two 
> more parameters: the x and y positions of the pixel to copy, using 
> "absolute coordinates" (i.e x=0,y=0 means the first byte of the src 
> buffer, not the first pixel in the `drm_rect src`, this way the method 
> `pixel_read` can extract the correct value).
> 
> This way it become easy to manage "complex" pixel representations in this 
> loop: simply increment x/y and let the pixel_read method handle 
> everything.
> 
> The second patch I will send is doing this. And as explained before, it 
> will also simplify a lot the code related to rotation and translation (no 
> more switch case everywhere to add offset to x/y, it simply use drm_rect_* 
> helpers).

I like this, expect my review soon :).

> 
> It's not optimal in term of performance (in some situation it will read 
> the same block multiple time to generate different pixels), but I 
> believe it still is an intersting trade-off.
> 
> In the future, if performance is actally critical, the whole composition 
> loop will have to be specialized for each pixel formats: some can be 
> treated line by line (as it's done today), but with blocks or packed 
> pixels it's more complex.
> 
>> +for (size_t i = 0; i < frame_format->num_planes; i++)
>> +src_pixels[i] += frame_format->cpp[i];
> 
> This is likely working with format with block_w != 1, see explanation 
> above.

I think you meant that is _not_ working. Yeah, as I already explained,
it was never my plan to add support for packed or tiled formats.

Best Regards,
~Arthur Grillo


[PATCH v2 7/7] drm/vkms: Create KUnit tests for YUV conversions

2024-01-10 Thread Arthur Grillo
Create KUnit tests to test the conversion between YUV and RGB. Test each
conversion and range combination with some common colors.

Signed-off-by: Arthur Grillo 
---
 drivers/gpu/drm/vkms/Kconfig  |  15 +++
 drivers/gpu/drm/vkms/Makefile |   1 +
 drivers/gpu/drm/vkms/tests/.kunitconfig   |   4 +
 drivers/gpu/drm/vkms/tests/Makefile   |   3 +
 drivers/gpu/drm/vkms/tests/vkms_format_test.c | 156 ++
 drivers/gpu/drm/vkms/vkms_formats.c   |   9 +-
 drivers/gpu/drm/vkms/vkms_formats.h   |   5 +
 7 files changed, 191 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vkms/Kconfig b/drivers/gpu/drm/vkms/Kconfig
index b9ecdebecb0b..5b0094ad41eb 100644
--- a/drivers/gpu/drm/vkms/Kconfig
+++ b/drivers/gpu/drm/vkms/Kconfig
@@ -13,3 +13,18 @@ config DRM_VKMS
  a VKMS.
 
  If M is selected the module will be called vkms.
+
+config DRM_VKMS_KUNIT_TESTS
+   tristate "Tests for VKMS" if !KUNIT_ALL_TESTS
+   depends on DRM_VKMS && KUNIT
+   default KUNIT_ALL_TESTS
+   help
+ This builds unit tests for VKMS. This option is not useful for
+ distributions or general kernels, but only for kernel
+ developers working on VKMS.
+
+ For more information on KUnit and unit tests in general,
+ please refer to the KUnit documentation in
+ Documentation/dev-tools/kunit/.
+
+ If in doubt, say "N".
diff --git a/drivers/gpu/drm/vkms/Makefile b/drivers/gpu/drm/vkms/Makefile
index 1b28a6a32948..8d3e46dde635 100644
--- a/drivers/gpu/drm/vkms/Makefile
+++ b/drivers/gpu/drm/vkms/Makefile
@@ -9,3 +9,4 @@ vkms-y := \
vkms_writeback.o
 
 obj-$(CONFIG_DRM_VKMS) += vkms.o
+obj-$(CONFIG_DRM_VKMS_KUNIT_TESTS) += tests/
diff --git a/drivers/gpu/drm/vkms/tests/.kunitconfig 
b/drivers/gpu/drm/vkms/tests/.kunitconfig
new file mode 100644
index ..70e378228cbd
--- /dev/null
+++ b/drivers/gpu/drm/vkms/tests/.kunitconfig
@@ -0,0 +1,4 @@
+CONFIG_KUNIT=y
+CONFIG_DRM=y
+CONFIG_DRM_VKMS=y
+CONFIG_DRM_VKMS_KUNIT_TESTS=y
diff --git a/drivers/gpu/drm/vkms/tests/Makefile 
b/drivers/gpu/drm/vkms/tests/Makefile
new file mode 100644
index ..2d1df668569e
--- /dev/null
+++ b/drivers/gpu/drm/vkms/tests/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+obj-$(CONFIG_DRM_VKMS_KUNIT_TESTS) += vkms_format_test.o
diff --git a/drivers/gpu/drm/vkms/tests/vkms_format_test.c 
b/drivers/gpu/drm/vkms/tests/vkms_format_test.c
new file mode 100644
index ..f04b8169d5a2
--- /dev/null
+++ b/drivers/gpu/drm/vkms/tests/vkms_format_test.c
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include 
+
+#include 
+#include 
+#include 
+
+#include "../../drm_crtc_internal.h"
+
+#include "../vkms_drv.h"
+#include "../vkms_formats.h"
+
+#define TEST_BUFF_SIZE 50
+
+struct yuv_u8_to_argb_u16_case {
+   enum drm_color_encoding encoding;
+   enum drm_color_range range;
+   size_t n_colors;
+   struct format_pair {
+   char *name;
+   struct pixel_yuv_u8 yuv;
+   struct pixel_argb_u16 argb;
+   } colors[TEST_BUFF_SIZE];
+};
+
+static struct yuv_u8_to_argb_u16_case yuv_u8_to_argb_u16_cases[] = {
+   {
+   .encoding = DRM_COLOR_YCBCR_BT601,
+   .range = DRM_COLOR_YCBCR_FULL_RANGE,
+   .n_colors = 6,
+   .colors = {
+   {"white", {0xff, 0x80, 0x80}, {0x, 0x, 0x, 
0x}},
+   {"gray",  {0x80, 0x80, 0x80}, {0x, 0x8000, 0x8000, 
0x8000}},
+   {"black", {0x00, 0x80, 0x80}, {0x, 0x, 0x, 
0x}},
+   {"red",   {0x4c, 0x55, 0xff}, {0x, 0x, 0x, 
0x}},
+   {"green", {0x96, 0x2c, 0x15}, {0x, 0x, 0x, 
0x}},
+   {"blue",  {0x1d, 0xff, 0x6b}, {0x, 0x, 0x, 
0x}},
+   },
+   },
+   {
+   .encoding = DRM_COLOR_YCBCR_BT601,
+   .range = DRM_COLOR_YCBCR_LIMITED_RANGE,
+   .n_colors = 6,
+   .colors = {
+   {"white", {0xeb, 0x80, 0x80}, {0x, 0x, 0x, 
0x}},
+   {"gray",  {0x7e, 0x80, 0x80}, {0x, 0x8000, 0x8000, 
0x8000}},
+   {"black", {0x10, 0x80, 0x80}, {0x, 0x, 0x, 
0x}},
+   {"red",   {0x51, 0x5a, 0xf0}, {0x, 0x, 0x, 
0x}},
+   {"green", {0x91, 0x36, 0x22}, {0x, 0x, 0x, 
0x}},
+   {"blue",  {0x29, 0xf0, 0x6e}, {0x, 0x, 0x, 
0x}},
+   },
+   },
+   {
+   .encoding = DRM_COLOR_YCBCR_BT709,
+  

[PATCH v2 6/7] drm/vkms: Drop YUV formats TODO

2024-01-10 Thread Arthur Grillo
VKMS has support for YUV formats now. Remove the task from the TODO
list.

Signed-off-by: Arthur Grillo 
---
 Documentation/gpu/vkms.rst | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
index ba04ac7c2167..13b866c3617c 100644
--- a/Documentation/gpu/vkms.rst
+++ b/Documentation/gpu/vkms.rst
@@ -122,8 +122,7 @@ There's lots of plane features we could add support for:
 
 - Scaling.
 
-- Additional buffer formats, especially YUV formats for video like NV12.
-  Low/high bpp RGB formats would also be interesting.
+- Additional buffer formats. Low/high bpp RGB formats would be interesting.
 
 - Async updates (currently only possible on cursor plane using the legacy
   cursor api).

-- 
2.43.0



[PATCH v2 5/7] drm/vkms: Add YUV support

2024-01-10 Thread Arthur Grillo
Add support to the YUV formats bellow:

- NV12
- NV16
- NV24
- NV21
- NV61
- NV42
- YUV420
- YUV422
- YUV444
- YVU420
- YVU422
- YVU444

The conversion matrices of each encoding and range were obtained by
rounding the values of the original conversion matrices multiplied by
2^8. This is done to avoid the use of fixed point operations.

Signed-off-by: Arthur Grillo 
---
 drivers/gpu/drm/vkms/vkms_formats.c | 147 
 drivers/gpu/drm/vkms/vkms_formats.h |   4 +
 drivers/gpu/drm/vkms/vkms_plane.c   |  14 +++-
 3 files changed, 164 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vkms/vkms_formats.c 
b/drivers/gpu/drm/vkms/vkms_formats.c
index 098ed16f2104..7c1a0ca322d9 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.c
+++ b/drivers/gpu/drm/vkms/vkms_formats.c
@@ -119,6 +119,137 @@ static void RGB565_to_argb_u16(u8 **src_pixels, struct 
pixel_argb_u16 *out_pixel
out_pixel->b = drm_fixp2int_round(drm_fixp_mul(fp_b, fp_rb_ratio));
 }
 
+static void ycbcr2rgb(const s16 m[3][3], u8 y, u8 cb, u8 cr, u8 y_offset, u8 
*r, u8 *g, u8 *b)
+{
+   s32 y_16, cb_16, cr_16;
+   s32 r_16, g_16, b_16;
+
+   y_16 =  y - y_offset;
+   cb_16 = cb - 128;
+   cr_16 = cr - 128;
+
+   r_16 = m[0][0] * y_16 + m[0][1] * cb_16 + m[0][2] * cr_16;
+   g_16 = m[1][0] * y_16 + m[1][1] * cb_16 + m[1][2] * cr_16;
+   b_16 = m[2][0] * y_16 + m[2][1] * cb_16 + m[2][2] * cr_16;
+
+   *r = clamp(r_16, 0, 0x) >> 8;
+   *g = clamp(g_16, 0, 0x) >> 8;
+   *b = clamp(b_16, 0, 0x) >> 8;
+}
+
+static void yuv_u8_to_argb_u16(struct pixel_argb_u16 *argb_u16, const struct 
pixel_yuv_u8 *yuv_u8,
+  enum drm_color_encoding encoding, enum 
drm_color_range range)
+{
+   static const s16 bt601_full[3][3] = {
+   {256,   0,  359},
+   {256, -88, -183},
+   {256, 454,0},
+   };
+   static const s16 bt601[3][3] = {
+   {298,0,  409},
+   {298, -100, -208},
+   {298,  516,0},
+   };
+   static const s16 rec709_full[3][3] = {
+   {256,   0,  408},
+   {256, -48, -120},
+   {256, 476,   0 },
+   };
+   static const s16 rec709[3][3] = {
+   {298,   0,  459},
+   {298, -55, -136},
+   {298, 541,0},
+   };
+   static const s16 bt2020_full[3][3] = {
+   {256,   0,  377},
+   {256, -42, -146},
+   {256, 482,0},
+   };
+   static const s16 bt2020[3][3] = {
+   {298,   0,  430},
+   {298, -48, -167},
+   {298, 548,0},
+   };
+
+   u8 r = 0;
+   u8 g = 0;
+   u8 b = 0;
+   bool full = range == DRM_COLOR_YCBCR_FULL_RANGE;
+   unsigned int y_offset = full ? 0 : 16;
+
+   switch (encoding) {
+   case DRM_COLOR_YCBCR_BT601:
+   ycbcr2rgb(full ? bt601_full : bt601,
+ yuv_u8->y, yuv_u8->u, yuv_u8->v, y_offset, , , 
);
+   break;
+   case DRM_COLOR_YCBCR_BT709:
+   ycbcr2rgb(full ? rec709_full : rec709,
+ yuv_u8->y, yuv_u8->u, yuv_u8->v, y_offset, , , 
);
+   break;
+   case DRM_COLOR_YCBCR_BT2020:
+   ycbcr2rgb(full ? bt2020_full : bt2020,
+ yuv_u8->y, yuv_u8->u, yuv_u8->v, y_offset, , , 
);
+   break;
+   default:
+   pr_warn_once("Not supported color encoding\n");
+   break;
+   }
+
+   argb_u16->r = r * 257;
+   argb_u16->g = g * 257;
+   argb_u16->b = b * 257;
+}
+
+static void semi_planar_yuv_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 
*out_pixel,
+   enum drm_color_encoding encoding,
+   enum drm_color_range range)
+{
+   struct pixel_yuv_u8 yuv_u8;
+
+   yuv_u8.y = src_pixels[0][0];
+   yuv_u8.u = src_pixels[1][0];
+   yuv_u8.v = src_pixels[1][1];
+
+   yuv_u8_to_argb_u16(out_pixel, _u8, encoding, range);
+}
+
+static void semi_planar_yvu_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 
*out_pixel,
+   enum drm_color_encoding encoding,
+   enum drm_color_range range)
+{
+   struct pixel_yuv_u8 yuv_u8;
+
+   yuv_u8.y = src_pixels[0][0];
+   yuv_u8.v = src_pixels[1][0];
+   yuv_u8.u = src_pixels[1][1];
+
+   yuv_u8_to_argb_u16(out_pixel, _u8, encoding, range);
+}
+
+static void planar_yuv_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 
*out_pixel,
+  enum drm_color_encoding encoding, enum 
drm_color_range range)
+{
+   struct pixel_yuv_u8 yuv_u8;
+
+   yuv_u8.y = src_pixels[0][0];
+   yuv_u8.u = src_pixels[1][0];
+   yuv_u8.v = src_

[PATCH v2 4/7] drm/vkms: Add chroma subsampling

2024-01-10 Thread Arthur Grillo
Add support to chroma subsampling. This should be noop, as all supported
formats do not have chroma subsampling.

Signed-off-by: Arthur Grillo 
---
 drivers/gpu/drm/vkms/vkms_formats.c | 18 +-
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_formats.c 
b/drivers/gpu/drm/vkms/vkms_formats.c
index 0156372aa1ef..098ed16f2104 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.c
+++ b/drivers/gpu/drm/vkms/vkms_formats.c
@@ -26,12 +26,15 @@ static size_t pixel_offset(const struct vkms_frame_info 
*frame_info, int x, int
  * @index: The index of the plane on the 2D buffer
  *
  * Takes the information stored in the frame_info, a pair of coordinates, and
- * returns the address of the first color channel on the desired index.
+ * returns the address of the first color channel on the desired index. The
+ * format's specific subsample is applied.
  */
 static void *packed_pixels_addr(const struct vkms_frame_info *frame_info,
int x, int y, size_t index)
 {
-   size_t offset = pixel_offset(frame_info, x, y, index);
+   int vsub = index == 0 ? 1 : frame_info->fb->format->vsub;
+   int hsub = index == 0 ? 1 : frame_info->fb->format->hsub;
+   size_t offset = pixel_offset(frame_info, x / hsub, y / vsub, index);
 
return (u8 *)frame_info->map[0].vaddr + offset;
 }
@@ -146,18 +149,23 @@ void vkms_compose_row(struct line_buffer *stage_buffer, 
struct vkms_plane_state
for (size_t x = 0; x < limit; x++) {
int x_pos = get_x_position(frame_info, limit, x);
 
+   bool shoud_inc = !((x + 1) % frame_format->num_planes);
+
if (drm_rotation_90_or_270(frame_info->rotation)) {
for (size_t i = 0; i < frame_format->num_planes; i++) {
src_pixels[i] = get_packed_src_addr(frame_info,
x + 
frame_info->rotated.y1, i);
-   src_pixels[i] += frame_format->cpp[i] * y;
+   if (!i || shoud_inc)
+   src_pixels[i] += frame_format->cpp[i] * 
y;
}
}
 
plane->pixel_read(src_pixels, _pixels[x_pos], encoding, 
range);
 
-   for (size_t i = 0; i < frame_format->num_planes; i++)
-   src_pixels[i] += frame_format->cpp[i];
+   for (size_t i = 0; i < frame_format->num_planes; i++) {
+   if (!i || shoud_inc)
+   src_pixels[i] += frame_format->cpp[i];
+   }
}
 }
 

-- 
2.43.0



[PATCH v2 3/7] drm/vkms: Add range and encoding properties to pixel_read function

2024-01-10 Thread Arthur Grillo
Create range and encoding properties. This should be noop, as none of
the conversion functions need those properties.

Signed-off-by: Arthur Grillo 
---
 drivers/gpu/drm/vkms/vkms_drv.h |  3 ++-
 drivers/gpu/drm/vkms/vkms_formats.c | 20 ++--
 drivers/gpu/drm/vkms/vkms_plane.c   |  9 +
 3 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index c38590562e4b..51349a0c32d8 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -56,7 +56,8 @@ struct vkms_writeback_job {
 struct vkms_plane_state {
struct drm_shadow_plane_state base;
struct vkms_frame_info *frame_info;
-   void (*pixel_read)(u8 **src_buffer, struct pixel_argb_u16 *out_pixel);
+   void (*pixel_read)(u8 **src_buffer, struct pixel_argb_u16 *out_pixel,
+  enum drm_color_encoding enconding, enum 
drm_color_range range);
 };
 
 struct vkms_plane {
diff --git a/drivers/gpu/drm/vkms/vkms_formats.c 
b/drivers/gpu/drm/vkms/vkms_formats.c
index 5566a7cd7bb4..0156372aa1ef 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.c
+++ b/drivers/gpu/drm/vkms/vkms_formats.c
@@ -51,7 +51,8 @@ static int get_x_position(const struct vkms_frame_info 
*frame_info, int limit, i
return x;
 }
 
-static void ARGB_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 
*out_pixel)
+static void ARGB_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 
*out_pixel,
+enum drm_color_encoding encoding, enum 
drm_color_range range)
 {
/*
 * The 257 is the "conversion ratio". This number is obtained by the
@@ -65,7 +66,8 @@ static void ARGB_to_argb_u16(u8 **src_pixels, struct 
pixel_argb_u16 *out_pix
out_pixel->b = (u16)src_pixels[0][0] * 257;
 }
 
-static void XRGB_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 
*out_pixel)
+static void XRGB_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 
*out_pixel,
+enum drm_color_encoding encoding, enum 
drm_color_range range)
 {
out_pixel->a = (u16)0x;
out_pixel->r = (u16)src_pixels[0][2] * 257;
@@ -73,7 +75,8 @@ static void XRGB_to_argb_u16(u8 **src_pixels, struct 
pixel_argb_u16 *out_pix
out_pixel->b = (u16)src_pixels[0][0] * 257;
 }
 
-static void ARGB16161616_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 
*out_pixel)
+static void ARGB16161616_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 
*out_pixel,
+enum drm_color_encoding encoding, enum 
drm_color_range range)
 {
u16 *pixels = (u16 *)src_pixels[0];
 
@@ -83,7 +86,8 @@ static void ARGB16161616_to_argb_u16(u8 **src_pixels, struct 
pixel_argb_u16 *out
out_pixel->b = le16_to_cpu(pixels[0]);
 }
 
-static void XRGB16161616_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 
*out_pixel)
+static void XRGB16161616_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 
*out_pixel,
+enum drm_color_encoding encoding, enum 
drm_color_range range)
 {
u16 *pixels = (u16 *)src_pixels[0];
 
@@ -93,7 +97,8 @@ static void XRGB16161616_to_argb_u16(u8 **src_pixels, struct 
pixel_argb_u16 *out
out_pixel->b = le16_to_cpu(pixels[0]);
 }
 
-static void RGB565_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 
*out_pixel)
+static void RGB565_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 
*out_pixel,
+  enum drm_color_encoding encoding, enum 
drm_color_range range)
 {
u16 *pixels = (u16 *)src_pixels[0];
 
@@ -132,6 +137,9 @@ void vkms_compose_row(struct line_buffer *stage_buffer, 
struct vkms_plane_state
int limit = min_t(size_t, drm_rect_width(_info->dst), 
stage_buffer->n_pixels);
u8 *src_pixels[DRM_FORMAT_MAX_PLANES];
 
+   enum drm_color_encoding encoding = plane->base.base.color_encoding;
+   enum drm_color_range range = plane->base.base.color_range;
+
for (size_t i = 0; i < frame_format->num_planes; i++)
src_pixels[i] = get_packed_src_addr(frame_info, y, i);
 
@@ -146,7 +154,7 @@ void vkms_compose_row(struct line_buffer *stage_buffer, 
struct vkms_plane_state
}
}
 
-   plane->pixel_read(src_pixels, _pixels[x_pos]);
+   plane->pixel_read(src_pixels, _pixels[x_pos], encoding, 
range);
 
for (size_t i = 0; i < frame_format->num_planes; i++)
src_pixels[i] += frame_format->cpp[i];
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c 
b/drivers/gpu/drm/vkms/vkms_plane.c
index 8f2c6ea419a3..e87c80575b7d 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -212,5 +212,14 @@ struct vkms_plane *vkms_plane_init(struct vkms_device 
*vkmsdev,
  

[PATCH v2 2/7] drm/vkms: Add support for multy-planar framebuffers

2024-01-10 Thread Arthur Grillo
Add support to multy-planar formats by adding an index argument to the
framebuffer data access functions.

Also, give all the planes to the conversion functions. This, for now,
should be noop, as all the supported formats have only one plane.

Signed-off-by: Arthur Grillo 
---
 drivers/gpu/drm/vkms/vkms_drv.h |  2 +-
 drivers/gpu/drm/vkms/vkms_formats.c | 73 +
 2 files changed, 42 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index b4b357447292..c38590562e4b 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -56,7 +56,7 @@ struct vkms_writeback_job {
 struct vkms_plane_state {
struct drm_shadow_plane_state base;
struct vkms_frame_info *frame_info;
-   void (*pixel_read)(u8 *src_buffer, struct pixel_argb_u16 *out_pixel);
+   void (*pixel_read)(u8 **src_buffer, struct pixel_argb_u16 *out_pixel);
 };
 
 struct vkms_plane {
diff --git a/drivers/gpu/drm/vkms/vkms_formats.c 
b/drivers/gpu/drm/vkms/vkms_formats.c
index 172830a3936a..5566a7cd7bb4 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.c
+++ b/drivers/gpu/drm/vkms/vkms_formats.c
@@ -9,12 +9,12 @@
 
 #include "vkms_formats.h"
 
-static size_t pixel_offset(const struct vkms_frame_info *frame_info, int x, 
int y)
+static size_t pixel_offset(const struct vkms_frame_info *frame_info, int x, 
int y, size_t index)
 {
struct drm_framebuffer *fb = frame_info->fb;
 
-   return fb->offsets[0] + (y * fb->pitches[0])
- + (x * fb->format->cpp[0]);
+   return fb->offsets[index] + (y * fb->pitches[index])
+ + (x * fb->format->cpp[index]);
 }
 
 /*
@@ -23,27 +23,25 @@ static size_t pixel_offset(const struct vkms_frame_info 
*frame_info, int x, int
  * @frame_info: Buffer metadata
  * @x: The x(width) coordinate of the 2D buffer
  * @y: The y(Heigth) coordinate of the 2D buffer
+ * @index: The index of the plane on the 2D buffer
  *
  * Takes the information stored in the frame_info, a pair of coordinates, and
- * returns the address of the first color channel.
- * This function assumes the channels are packed together, i.e. a color channel
- * comes immediately after another in the memory. And therefore, this function
- * doesn't work for YUV with chroma subsampling (e.g. YUV420 and NV21).
+ * returns the address of the first color channel on the desired index.
  */
 static void *packed_pixels_addr(const struct vkms_frame_info *frame_info,
-   int x, int y)
+   int x, int y, size_t index)
 {
-   size_t offset = pixel_offset(frame_info, x, y);
+   size_t offset = pixel_offset(frame_info, x, y, index);
 
return (u8 *)frame_info->map[0].vaddr + offset;
 }
 
-static void *get_packed_src_addr(const struct vkms_frame_info *frame_info, int 
y)
+static void *get_packed_src_addr(const struct vkms_frame_info *frame_info, int 
y, size_t index)
 {
int x_src = frame_info->src.x1 >> 16;
int y_src = y - frame_info->rotated.y1 + (frame_info->src.y1 >> 16);
 
-   return packed_pixels_addr(frame_info, x_src, y_src);
+   return packed_pixels_addr(frame_info, x_src, y_src, index);
 }
 
 static int get_x_position(const struct vkms_frame_info *frame_info, int limit, 
int x)
@@ -53,7 +51,7 @@ static int get_x_position(const struct vkms_frame_info 
*frame_info, int limit, i
return x;
 }
 
-static void ARGB_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 
*out_pixel)
+static void ARGB_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 
*out_pixel)
 {
/*
 * The 257 is the "conversion ratio". This number is obtained by the
@@ -61,23 +59,23 @@ static void ARGB_to_argb_u16(u8 *src_pixels, struct 
pixel_argb_u16 *out_pixe
 * the best color value in a pixel format with more possibilities.
 * A similar idea applies to others RGB color conversions.
 */
-   out_pixel->a = (u16)src_pixels[3] * 257;
-   out_pixel->r = (u16)src_pixels[2] * 257;
-   out_pixel->g = (u16)src_pixels[1] * 257;
-   out_pixel->b = (u16)src_pixels[0] * 257;
+   out_pixel->a = (u16)src_pixels[0][3] * 257;
+   out_pixel->r = (u16)src_pixels[0][2] * 257;
+   out_pixel->g = (u16)src_pixels[0][1] * 257;
+   out_pixel->b = (u16)src_pixels[0][0] * 257;
 }
 
-static void XRGB_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 
*out_pixel)
+static void XRGB_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 
*out_pixel)
 {
out_pixel->a = (u16)0x;
-   out_pixel->r = (u16)src_pixels[2] * 257;
-   out_pixel->g = (u16)src_pixels[1] * 257;
-   out_pixel->b = (u16)src_pixels[0] * 257;
+   out_pixel->r = (u16)src_pixels[0][2] * 257;
+   out_pixel->g = (u16)src_pixels[0][1] * 2

[PATCH v2 1/7] drm/vkms: Use drm_frame directly

2024-01-10 Thread Arthur Grillo
Remove intermidiary variables and access the variables directly from
drm_frame. These changes should be noop.

Signed-off-by: Arthur Grillo 
---
 drivers/gpu/drm/vkms/vkms_drv.h   |  3 ---
 drivers/gpu/drm/vkms/vkms_formats.c   | 12 +++-
 drivers/gpu/drm/vkms/vkms_plane.c |  3 ---
 drivers/gpu/drm/vkms/vkms_writeback.c |  5 -
 4 files changed, 7 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index 8f5710debb1e..b4b357447292 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -31,9 +31,6 @@ struct vkms_frame_info {
struct drm_rect rotated;
struct iosys_map map[DRM_FORMAT_MAX_PLANES];
unsigned int rotation;
-   unsigned int offset;
-   unsigned int pitch;
-   unsigned int cpp;
 };
 
 struct pixel_argb_u16 {
diff --git a/drivers/gpu/drm/vkms/vkms_formats.c 
b/drivers/gpu/drm/vkms/vkms_formats.c
index 36046b12f296..172830a3936a 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.c
+++ b/drivers/gpu/drm/vkms/vkms_formats.c
@@ -11,8 +11,10 @@
 
 static size_t pixel_offset(const struct vkms_frame_info *frame_info, int x, 
int y)
 {
-   return frame_info->offset + (y * frame_info->pitch)
- + (x * frame_info->cpp);
+   struct drm_framebuffer *fb = frame_info->fb;
+
+   return fb->offsets[0] + (y * fb->pitches[0])
+ + (x * fb->format->cpp[0]);
 }
 
 /*
@@ -131,12 +133,12 @@ void vkms_compose_row(struct line_buffer *stage_buffer, 
struct vkms_plane_state
u8 *src_pixels = get_packed_src_addr(frame_info, y);
int limit = min_t(size_t, drm_rect_width(_info->dst), 
stage_buffer->n_pixels);
 
-   for (size_t x = 0; x < limit; x++, src_pixels += frame_info->cpp) {
+   for (size_t x = 0; x < limit; x++, src_pixels += 
frame_info->fb->format->cpp[0]) {
int x_pos = get_x_position(frame_info, limit, x);
 
if (drm_rotation_90_or_270(frame_info->rotation))
src_pixels = get_packed_src_addr(frame_info, x + 
frame_info->rotated.y1)
-   + frame_info->cpp * y;
+   + frame_info->fb->format->cpp[0] * y;
 
plane->pixel_read(src_pixels, _pixels[x_pos]);
}
@@ -223,7 +225,7 @@ void vkms_writeback_row(struct vkms_writeback_job *wb,
struct pixel_argb_u16 *in_pixels = src_buffer->pixels;
int x_limit = min_t(size_t, drm_rect_width(_info->dst), 
src_buffer->n_pixels);
 
-   for (size_t x = 0; x < x_limit; x++, dst_pixels += frame_info->cpp)
+   for (size_t x = 0; x < x_limit; x++, dst_pixels += 
frame_info->fb->format->cpp[0])
wb->pixel_write(dst_pixels, _pixels[x]);
 }
 
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c 
b/drivers/gpu/drm/vkms/vkms_plane.c
index e5c625ab8e3e..8f2c6ea419a3 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -125,9 +125,6 @@ static void vkms_plane_atomic_update(struct drm_plane 
*plane,
drm_rect_rotate(_info->rotated, 
drm_rect_width(_info->rotated),
drm_rect_height(_info->rotated), 
frame_info->rotation);
 
-   frame_info->offset = fb->offsets[0];
-   frame_info->pitch = fb->pitches[0];
-   frame_info->cpp = fb->format->cpp[0];
vkms_plane_state->pixel_read = get_pixel_conversion_function(fmt);
 }
 
diff --git a/drivers/gpu/drm/vkms/vkms_writeback.c 
b/drivers/gpu/drm/vkms/vkms_writeback.c
index bc724cbd5e3a..c8582df1f739 100644
--- a/drivers/gpu/drm/vkms/vkms_writeback.c
+++ b/drivers/gpu/drm/vkms/vkms_writeback.c
@@ -149,11 +149,6 @@ static void vkms_wb_atomic_commit(struct drm_connector 
*conn,
crtc_state->active_writeback = active_wb;
crtc_state->wb_pending = true;
spin_unlock_irq(>composer_lock);
-
-   wb_frame_info->offset = fb->offsets[0];
-   wb_frame_info->pitch = fb->pitches[0];
-   wb_frame_info->cpp = fb->format->cpp[0];
-
drm_writeback_queue_job(wb_conn, connector_state);
active_wb->pixel_write = get_pixel_write_function(wb_format);
drm_rect_init(_frame_info->src, 0, 0, crtc_width, crtc_height);

-- 
2.43.0



[PATCH v2 0/7] Add YUV formats to VKMS

2024-01-10 Thread Arthur Grillo
This patchset aims to add support for additional buffer YUV formats.
More specifically, it adds support to:

Semi-planar formats:

- NV12
- NV16
- NV24
- NV21
- NV61
- NV42

Planar formats:

- YUV440
- YUV422
- YUV444
- YVU440
- YVU422
- YVU444

These formats have more than one plane, and most have chroma
subsampling. These properties don't have support on VKMS, so I had to
work on this before.

To ensure that the conversions from YUV to RGB are working, I wrote a
KUnit test. As the work from Harry on creating KUnit tests on VKMS[1] is
not yet merged, I took the setup part (Kconfig entry and .kunitfile)
from it.

Furthermore, I couldn't find any sources with the conversion matrices,
so I had to work out the values myself based on the ITU papers[2][3][4].
So, I'm not 100% sure if the values are accurate. I'd appreciate some
input if anyone has more knowledge in this area.

Also, I used two IGT tests to check if the formats were having a correct
conversion (all with the --extended flag):

- kms_plane@pixel_format
- kms_plane@pixel_format_source_clamping.

The nonsubsampled formats don't have support on IGT, so I sent a patch
fixing this[5].

Currently, this patchset does not add those formats to the writeback, as
it would require a rewrite of how the conversions are done (similar to
what was done on a previous patch[6]). So, I would like to review this
patchset before I start the work on this other part.

[1]: https://lore.kernel.org/all/20231108163647.106853-5-harry.wentl...@amd.com/
[2]: https://www.itu.int/rec/R-REC-BT.601-7-201103-I/en
[3]: https://www.itu.int/rec/R-REC-BT.709-6-201506-I/en
[4]: https://www.itu.int/rec/R-REC-BT.2020-2-201510-I/en
[5]: https://lists.freedesktop.org/archives/igt-dev/2024-January/066937.html
[6]: https://lore.kernel.org/dri-devel/20230414135151.75975-2-mca...@igalia.com/

Signed-off-by: Arthur Grillo 
---
Changes in v2:
- Use EXPORT_SYMBOL_IF_KUNIT instead of including the .c test
  file (Maxime)
- Link to v1: 
https://lore.kernel.org/r/20240105-vkms-yuv-v1-0-34c4cd345...@riseup.net

---
Arthur Grillo (7):
  drm/vkms: Use drm_frame directly
  drm/vkms: Add support for multy-planar framebuffers
  drm/vkms: Add range and encoding properties to pixel_read function
  drm/vkms: Add chroma subsampling
  drm/vkms: Add YUV support
  drm/vkms: Drop YUV formats TODO
  drm/vkms: Create KUnit tests for YUV conversions

 Documentation/gpu/vkms.rst|   3 +-
 drivers/gpu/drm/vkms/Kconfig  |  15 ++
 drivers/gpu/drm/vkms/Makefile |   1 +
 drivers/gpu/drm/vkms/tests/.kunitconfig   |   4 +
 drivers/gpu/drm/vkms/tests/Makefile   |   3 +
 drivers/gpu/drm/vkms/tests/vkms_format_test.c | 156 
 drivers/gpu/drm/vkms/vkms_drv.h   |   6 +-
 drivers/gpu/drm/vkms/vkms_formats.c   | 247 ++
 drivers/gpu/drm/vkms/vkms_formats.h   |   9 +
 drivers/gpu/drm/vkms/vkms_plane.c |  26 ++-
 drivers/gpu/drm/vkms/vkms_writeback.c |   5 -
 11 files changed, 426 insertions(+), 49 deletions(-)
---
base-commit: eeb8e8d9f124f279e80ae679f4ba6e822ce4f95f
change-id: 20231226-vkms-yuv-6f7859f32df8

Best regards,
-- 
Arthur Grillo 



Re: [PATCH 7/7] drm/vkms: Create KUnit tests for YUV conversions

2024-01-08 Thread Arthur Grillo



On 08/01/24 07:15, Maxime Ripard wrote:
> Hi Arthur,
> 
> On Fri, Jan 05, 2024 at 01:35:08PM -0300, Arthur Grillo wrote:
>> diff --git a/drivers/gpu/drm/vkms/vkms_formats.c 
>> b/drivers/gpu/drm/vkms/vkms_formats.c
>> index b654b6661a20..11df990a0fa9 100644
>> --- a/drivers/gpu/drm/vkms/vkms_formats.c
>> +++ b/drivers/gpu/drm/vkms/vkms_formats.c
>> @@ -440,3 +440,7 @@ void *get_pixel_write_function(u32 format)
>>  return NULL;
>>  }
>>  }
>> +
>> +#ifdef CONFIG_DRM_VKMS_KUNIT_TESTS
>> +#include "tests/vkms_format_test.c"
>> +#endif
> 
> I assume this is due to testing a static function?

Yeah, you're right.

> 
> If so, the preferred way nowadays is to use EXPORT_SYMBOL_IF_KUNIT or
> EXPORT_SYMBOL_FOR_TESTS_ONLY if it's DRM/KMS only.

Oh, I didn't know about that. I think I will use EXPORT_SYMBOL_IF_KUNIT
as you can use VISIBLE_IF_KUNIT to maintain the function static if the
test is not used.

~Arthur Grillo
> 
> Maxime


[PATCH 4/7] drm/vkms: Add chroma subsampling

2024-01-05 Thread Arthur Grillo
Add support to chroma subsampling. This should be noop, as all supported
formats do not have chroma subsampling.

Signed-off-by: Arthur Grillo 
---
 drivers/gpu/drm/vkms/vkms_formats.c | 18 +-
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_formats.c 
b/drivers/gpu/drm/vkms/vkms_formats.c
index 0156372aa1ef..098ed16f2104 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.c
+++ b/drivers/gpu/drm/vkms/vkms_formats.c
@@ -26,12 +26,15 @@ static size_t pixel_offset(const struct vkms_frame_info 
*frame_info, int x, int
  * @index: The index of the plane on the 2D buffer
  *
  * Takes the information stored in the frame_info, a pair of coordinates, and
- * returns the address of the first color channel on the desired index.
+ * returns the address of the first color channel on the desired index. The
+ * format's specific subsample is applied.
  */
 static void *packed_pixels_addr(const struct vkms_frame_info *frame_info,
int x, int y, size_t index)
 {
-   size_t offset = pixel_offset(frame_info, x, y, index);
+   int vsub = index == 0 ? 1 : frame_info->fb->format->vsub;
+   int hsub = index == 0 ? 1 : frame_info->fb->format->hsub;
+   size_t offset = pixel_offset(frame_info, x / hsub, y / vsub, index);
 
return (u8 *)frame_info->map[0].vaddr + offset;
 }
@@ -146,18 +149,23 @@ void vkms_compose_row(struct line_buffer *stage_buffer, 
struct vkms_plane_state
for (size_t x = 0; x < limit; x++) {
int x_pos = get_x_position(frame_info, limit, x);
 
+   bool shoud_inc = !((x + 1) % frame_format->num_planes);
+
if (drm_rotation_90_or_270(frame_info->rotation)) {
for (size_t i = 0; i < frame_format->num_planes; i++) {
src_pixels[i] = get_packed_src_addr(frame_info,
x + 
frame_info->rotated.y1, i);
-   src_pixels[i] += frame_format->cpp[i] * y;
+   if (!i || shoud_inc)
+   src_pixels[i] += frame_format->cpp[i] * 
y;
}
}
 
plane->pixel_read(src_pixels, _pixels[x_pos], encoding, 
range);
 
-   for (size_t i = 0; i < frame_format->num_planes; i++)
-   src_pixels[i] += frame_format->cpp[i];
+   for (size_t i = 0; i < frame_format->num_planes; i++) {
+   if (!i || shoud_inc)
+   src_pixels[i] += frame_format->cpp[i];
+   }
}
 }
 

-- 
2.43.0



[PATCH 0/7] Add YUV formats to VKMS

2024-01-05 Thread Arthur Grillo
This patchset aims to add support for additional buffer YUV formats.
More specifically, it adds support to:

Semi-planar formats:

- NV12
- NV16
- NV24
- NV21
- NV61
- NV42

Planar formats:

- YUV440
- YUV422
- YUV444
- YVU440
- YVU422
- YVU444

These formats have more than one plane, and most have chroma
subsampling. These properties don't have support on VKMS, so I had to
work on this before.

To ensure that the conversions from YUV to RGB are working, I wrote a
KUnit test. As the work from Harry on creating KUnit tests on VKMS[1] is
not yet merged, I took the setup part (Kconfig entry and .kunitfile)
from it.

Furthermore, I couldn't find any sources with the conversion matrices,
so I had to work out the values myself based on the ITU papers[2][3][4].
So, I'm not 100% sure if the values are accurate. I'd appreciate some
input if anyone has more knowledge in this area.

Also, I used two IGT tests to check if the formats were having a correct
conversion (all with the --extended flag):

- kms_plane@pixel_format
- kms_plane@pixel_format_source_clamping.

The nonsubsampled formats don't have support on IGT, so I sent a patch
fixing this[5].

Currently, this patchset does not add those formats to the writeback, as
it would require a rewrite of how the conversions are done (similar to
what was done on a previous patch[6]). So, I would like to review this
patchset before I start the work on this other part.

[1]: https://lore.kernel.org/all/20231108163647.106853-5-harry.wentl...@amd.com/
[2]: https://www.itu.int/rec/R-REC-BT.601-7-201103-I/en
[3]: https://www.itu.int/rec/R-REC-BT.709-6-201506-I/en
[4]: https://www.itu.int/rec/R-REC-BT.2020-2-201510-I/en
[5]: https://lists.freedesktop.org/archives/igt-dev/2024-January/066937.html
[6]: https://lore.kernel.org/dri-devel/20230414135151.75975-2-mca...@igalia.com/

Signed-off-by: Arthur Grillo 
---
Arthur Grillo (7):
  drm/vkms: Use drm_frame directly
  drm/vkms: Add support for multy-planar framebuffers
  drm/vkms: Add range and encoding properties to pixel_read function
  drm/vkms: Add chroma subsampling
  drm/vkms: Add YUV support
  drm/vkms: Drop YUV formats TODO
  drm/vkms: Create KUnit tests for YUV conversions

 Documentation/gpu/vkms.rst|   3 +-
 drivers/gpu/drm/vkms/Kconfig  |  15 ++
 drivers/gpu/drm/vkms/tests/.kunitconfig   |   4 +
 drivers/gpu/drm/vkms/tests/vkms_format_test.c | 151 
 drivers/gpu/drm/vkms/vkms_drv.h   |   6 +-
 drivers/gpu/drm/vkms/vkms_formats.c   | 250 ++
 drivers/gpu/drm/vkms/vkms_plane.c |  26 ++-
 drivers/gpu/drm/vkms/vkms_writeback.c |   5 -
 8 files changed, 411 insertions(+), 49 deletions(-)
---
base-commit: 0c75d52190b8bfa22cdb66e07148aea599c4535d
change-id: 20231226-vkms-yuv-6f7859f32df8

Best regards,
-- 
Arthur Grillo 



[PATCH 7/7] drm/vkms: Create KUnit tests for YUV conversions

2024-01-05 Thread Arthur Grillo
Create KUnit tests to test the conversion between YUV and RGB. Test each
conversion and range combination with some common colors.

Signed-off-by: Arthur Grillo 
---
 drivers/gpu/drm/vkms/Kconfig  |  15 +++
 drivers/gpu/drm/vkms/tests/.kunitconfig   |   4 +
 drivers/gpu/drm/vkms/tests/vkms_format_test.c | 151 ++
 drivers/gpu/drm/vkms/vkms_formats.c   |   4 +
 4 files changed, 174 insertions(+)

diff --git a/drivers/gpu/drm/vkms/Kconfig b/drivers/gpu/drm/vkms/Kconfig
index b9ecdebecb0b..5b0094ad41eb 100644
--- a/drivers/gpu/drm/vkms/Kconfig
+++ b/drivers/gpu/drm/vkms/Kconfig
@@ -13,3 +13,18 @@ config DRM_VKMS
  a VKMS.
 
  If M is selected the module will be called vkms.
+
+config DRM_VKMS_KUNIT_TESTS
+   tristate "Tests for VKMS" if !KUNIT_ALL_TESTS
+   depends on DRM_VKMS && KUNIT
+   default KUNIT_ALL_TESTS
+   help
+ This builds unit tests for VKMS. This option is not useful for
+ distributions or general kernels, but only for kernel
+ developers working on VKMS.
+
+ For more information on KUnit and unit tests in general,
+ please refer to the KUnit documentation in
+ Documentation/dev-tools/kunit/.
+
+ If in doubt, say "N".
diff --git a/drivers/gpu/drm/vkms/tests/.kunitconfig 
b/drivers/gpu/drm/vkms/tests/.kunitconfig
new file mode 100644
index ..70e378228cbd
--- /dev/null
+++ b/drivers/gpu/drm/vkms/tests/.kunitconfig
@@ -0,0 +1,4 @@
+CONFIG_KUNIT=y
+CONFIG_DRM=y
+CONFIG_DRM_VKMS=y
+CONFIG_DRM_VKMS_KUNIT_TESTS=y
diff --git a/drivers/gpu/drm/vkms/tests/vkms_format_test.c 
b/drivers/gpu/drm/vkms/tests/vkms_format_test.c
new file mode 100644
index ..c902cdd2d7f2
--- /dev/null
+++ b/drivers/gpu/drm/vkms/tests/vkms_format_test.c
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include 
+
+#include 
+
+#include "../../drm_crtc_internal.h"
+
+#define TEST_BUFF_SIZE 50
+
+struct yuv_u8_to_argb_u16_case {
+   enum drm_color_encoding encoding;
+   enum drm_color_range range;
+   size_t n_colors;
+   struct format_pair {
+   char *name;
+   struct pixel_yuv_u8 yuv;
+   struct pixel_argb_u16 argb;
+   } colors[TEST_BUFF_SIZE];
+};
+
+static struct yuv_u8_to_argb_u16_case yuv_u8_to_argb_u16_cases[] = {
+   {
+   .encoding = DRM_COLOR_YCBCR_BT601,
+   .range = DRM_COLOR_YCBCR_FULL_RANGE,
+   .n_colors = 6,
+   .colors = {
+   {"white", {0xff, 0x80, 0x80}, {0x, 0x, 0x, 
0x}},
+   {"gray",  {0x80, 0x80, 0x80}, {0x, 0x8000, 0x8000, 
0x8000}},
+   {"black", {0x00, 0x80, 0x80}, {0x, 0x, 0x, 
0x}},
+   {"red",   {0x4c, 0x55, 0xff}, {0x, 0x, 0x, 
0x}},
+   {"green", {0x96, 0x2c, 0x15}, {0x, 0x, 0x, 
0x}},
+   {"blue",  {0x1d, 0xff, 0x6b}, {0x, 0x, 0x, 
0x}},
+   },
+   },
+   {
+   .encoding = DRM_COLOR_YCBCR_BT601,
+   .range = DRM_COLOR_YCBCR_LIMITED_RANGE,
+   .n_colors = 6,
+   .colors = {
+   {"white", {0xeb, 0x80, 0x80}, {0x, 0x, 0x, 
0x}},
+   {"gray",  {0x7e, 0x80, 0x80}, {0x, 0x8000, 0x8000, 
0x8000}},
+   {"black", {0x10, 0x80, 0x80}, {0x, 0x, 0x, 
0x}},
+   {"red",   {0x51, 0x5a, 0xf0}, {0x, 0x, 0x, 
0x}},
+   {"green", {0x91, 0x36, 0x22}, {0x, 0x, 0x, 
0x}},
+   {"blue",  {0x29, 0xf0, 0x6e}, {0x, 0x, 0x, 
0x}},
+   },
+   },
+   {
+   .encoding = DRM_COLOR_YCBCR_BT709,
+   .range = DRM_COLOR_YCBCR_FULL_RANGE,
+   .n_colors = 4,
+   .colors = {
+   {"white", {0xff, 0x80, 0x80}, {0x, 0x, 0x, 
0x}},
+   {"gray",  {0x80, 0x80, 0x80}, {0x, 0x8000, 0x8000, 
0x8000}},
+   {"black", {0x00, 0x80, 0x80}, {0x, 0x, 0x, 
0x}},
+   {"red",   {0x35, 0x63, 0xff}, {0x, 0x, 0x, 
0x}},
+   {"green", {0xb6, 0x1e, 0x0c}, {0x, 0x, 0x, 
0x}},
+   {"blue",  {0x12, 0xff, 0x74}, {0x, 0x, 0x, 
0x}},
+   },
+   },
+   {
+   .encoding = DRM_COLOR_YCBCR_BT709,
+   .range = DRM_COLOR_YCBCR_LIMITED_RANGE,
+   .n_colors = 4,
+   .colors = {
+  

[PATCH 3/7] drm/vkms: Add range and encoding properties to pixel_read function

2024-01-05 Thread Arthur Grillo
Create range and encoding properties. This should be noop, as none of
the conversion functions need those properties.

Signed-off-by: Arthur Grillo 
---
 drivers/gpu/drm/vkms/vkms_drv.h |  3 ++-
 drivers/gpu/drm/vkms/vkms_formats.c | 20 ++--
 drivers/gpu/drm/vkms/vkms_plane.c   |  9 +
 3 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index c38590562e4b..51349a0c32d8 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -56,7 +56,8 @@ struct vkms_writeback_job {
 struct vkms_plane_state {
struct drm_shadow_plane_state base;
struct vkms_frame_info *frame_info;
-   void (*pixel_read)(u8 **src_buffer, struct pixel_argb_u16 *out_pixel);
+   void (*pixel_read)(u8 **src_buffer, struct pixel_argb_u16 *out_pixel,
+  enum drm_color_encoding enconding, enum 
drm_color_range range);
 };
 
 struct vkms_plane {
diff --git a/drivers/gpu/drm/vkms/vkms_formats.c 
b/drivers/gpu/drm/vkms/vkms_formats.c
index 5566a7cd7bb4..0156372aa1ef 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.c
+++ b/drivers/gpu/drm/vkms/vkms_formats.c
@@ -51,7 +51,8 @@ static int get_x_position(const struct vkms_frame_info 
*frame_info, int limit, i
return x;
 }
 
-static void ARGB_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 
*out_pixel)
+static void ARGB_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 
*out_pixel,
+enum drm_color_encoding encoding, enum 
drm_color_range range)
 {
/*
 * The 257 is the "conversion ratio". This number is obtained by the
@@ -65,7 +66,8 @@ static void ARGB_to_argb_u16(u8 **src_pixels, struct 
pixel_argb_u16 *out_pix
out_pixel->b = (u16)src_pixels[0][0] * 257;
 }
 
-static void XRGB_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 
*out_pixel)
+static void XRGB_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 
*out_pixel,
+enum drm_color_encoding encoding, enum 
drm_color_range range)
 {
out_pixel->a = (u16)0x;
out_pixel->r = (u16)src_pixels[0][2] * 257;
@@ -73,7 +75,8 @@ static void XRGB_to_argb_u16(u8 **src_pixels, struct 
pixel_argb_u16 *out_pix
out_pixel->b = (u16)src_pixels[0][0] * 257;
 }
 
-static void ARGB16161616_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 
*out_pixel)
+static void ARGB16161616_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 
*out_pixel,
+enum drm_color_encoding encoding, enum 
drm_color_range range)
 {
u16 *pixels = (u16 *)src_pixels[0];
 
@@ -83,7 +86,8 @@ static void ARGB16161616_to_argb_u16(u8 **src_pixels, struct 
pixel_argb_u16 *out
out_pixel->b = le16_to_cpu(pixels[0]);
 }
 
-static void XRGB16161616_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 
*out_pixel)
+static void XRGB16161616_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 
*out_pixel,
+enum drm_color_encoding encoding, enum 
drm_color_range range)
 {
u16 *pixels = (u16 *)src_pixels[0];
 
@@ -93,7 +97,8 @@ static void XRGB16161616_to_argb_u16(u8 **src_pixels, struct 
pixel_argb_u16 *out
out_pixel->b = le16_to_cpu(pixels[0]);
 }
 
-static void RGB565_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 
*out_pixel)
+static void RGB565_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 
*out_pixel,
+  enum drm_color_encoding encoding, enum 
drm_color_range range)
 {
u16 *pixels = (u16 *)src_pixels[0];
 
@@ -132,6 +137,9 @@ void vkms_compose_row(struct line_buffer *stage_buffer, 
struct vkms_plane_state
int limit = min_t(size_t, drm_rect_width(_info->dst), 
stage_buffer->n_pixels);
u8 *src_pixels[DRM_FORMAT_MAX_PLANES];
 
+   enum drm_color_encoding encoding = plane->base.base.color_encoding;
+   enum drm_color_range range = plane->base.base.color_range;
+
for (size_t i = 0; i < frame_format->num_planes; i++)
src_pixels[i] = get_packed_src_addr(frame_info, y, i);
 
@@ -146,7 +154,7 @@ void vkms_compose_row(struct line_buffer *stage_buffer, 
struct vkms_plane_state
}
}
 
-   plane->pixel_read(src_pixels, _pixels[x_pos]);
+   plane->pixel_read(src_pixels, _pixels[x_pos], encoding, 
range);
 
for (size_t i = 0; i < frame_format->num_planes; i++)
src_pixels[i] += frame_format->cpp[i];
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c 
b/drivers/gpu/drm/vkms/vkms_plane.c
index 8f2c6ea419a3..e87c80575b7d 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -212,5 +212,14 @@ struct vkms_plane *vkms_plane_init(struct vkms_device 
*vkmsdev,
  

[PATCH 2/7] drm/vkms: Add support for multy-planar framebuffers

2024-01-05 Thread Arthur Grillo
Add support to multy-planar formats by adding an index argument to the
framebuffer data access functions.

Also, give all the planes to the conversion functions. This, for now,
should be noop, as all the supported formats have only one plane.

Signed-off-by: Arthur Grillo 
---
 drivers/gpu/drm/vkms/vkms_drv.h |  2 +-
 drivers/gpu/drm/vkms/vkms_formats.c | 73 +
 2 files changed, 42 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index b4b357447292..c38590562e4b 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -56,7 +56,7 @@ struct vkms_writeback_job {
 struct vkms_plane_state {
struct drm_shadow_plane_state base;
struct vkms_frame_info *frame_info;
-   void (*pixel_read)(u8 *src_buffer, struct pixel_argb_u16 *out_pixel);
+   void (*pixel_read)(u8 **src_buffer, struct pixel_argb_u16 *out_pixel);
 };
 
 struct vkms_plane {
diff --git a/drivers/gpu/drm/vkms/vkms_formats.c 
b/drivers/gpu/drm/vkms/vkms_formats.c
index 172830a3936a..5566a7cd7bb4 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.c
+++ b/drivers/gpu/drm/vkms/vkms_formats.c
@@ -9,12 +9,12 @@
 
 #include "vkms_formats.h"
 
-static size_t pixel_offset(const struct vkms_frame_info *frame_info, int x, 
int y)
+static size_t pixel_offset(const struct vkms_frame_info *frame_info, int x, 
int y, size_t index)
 {
struct drm_framebuffer *fb = frame_info->fb;
 
-   return fb->offsets[0] + (y * fb->pitches[0])
- + (x * fb->format->cpp[0]);
+   return fb->offsets[index] + (y * fb->pitches[index])
+ + (x * fb->format->cpp[index]);
 }
 
 /*
@@ -23,27 +23,25 @@ static size_t pixel_offset(const struct vkms_frame_info 
*frame_info, int x, int
  * @frame_info: Buffer metadata
  * @x: The x(width) coordinate of the 2D buffer
  * @y: The y(Heigth) coordinate of the 2D buffer
+ * @index: The index of the plane on the 2D buffer
  *
  * Takes the information stored in the frame_info, a pair of coordinates, and
- * returns the address of the first color channel.
- * This function assumes the channels are packed together, i.e. a color channel
- * comes immediately after another in the memory. And therefore, this function
- * doesn't work for YUV with chroma subsampling (e.g. YUV420 and NV21).
+ * returns the address of the first color channel on the desired index.
  */
 static void *packed_pixels_addr(const struct vkms_frame_info *frame_info,
-   int x, int y)
+   int x, int y, size_t index)
 {
-   size_t offset = pixel_offset(frame_info, x, y);
+   size_t offset = pixel_offset(frame_info, x, y, index);
 
return (u8 *)frame_info->map[0].vaddr + offset;
 }
 
-static void *get_packed_src_addr(const struct vkms_frame_info *frame_info, int 
y)
+static void *get_packed_src_addr(const struct vkms_frame_info *frame_info, int 
y, size_t index)
 {
int x_src = frame_info->src.x1 >> 16;
int y_src = y - frame_info->rotated.y1 + (frame_info->src.y1 >> 16);
 
-   return packed_pixels_addr(frame_info, x_src, y_src);
+   return packed_pixels_addr(frame_info, x_src, y_src, index);
 }
 
 static int get_x_position(const struct vkms_frame_info *frame_info, int limit, 
int x)
@@ -53,7 +51,7 @@ static int get_x_position(const struct vkms_frame_info 
*frame_info, int limit, i
return x;
 }
 
-static void ARGB_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 
*out_pixel)
+static void ARGB_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 
*out_pixel)
 {
/*
 * The 257 is the "conversion ratio". This number is obtained by the
@@ -61,23 +59,23 @@ static void ARGB_to_argb_u16(u8 *src_pixels, struct 
pixel_argb_u16 *out_pixe
 * the best color value in a pixel format with more possibilities.
 * A similar idea applies to others RGB color conversions.
 */
-   out_pixel->a = (u16)src_pixels[3] * 257;
-   out_pixel->r = (u16)src_pixels[2] * 257;
-   out_pixel->g = (u16)src_pixels[1] * 257;
-   out_pixel->b = (u16)src_pixels[0] * 257;
+   out_pixel->a = (u16)src_pixels[0][3] * 257;
+   out_pixel->r = (u16)src_pixels[0][2] * 257;
+   out_pixel->g = (u16)src_pixels[0][1] * 257;
+   out_pixel->b = (u16)src_pixels[0][0] * 257;
 }
 
-static void XRGB_to_argb_u16(u8 *src_pixels, struct pixel_argb_u16 
*out_pixel)
+static void XRGB_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 
*out_pixel)
 {
out_pixel->a = (u16)0x;
-   out_pixel->r = (u16)src_pixels[2] * 257;
-   out_pixel->g = (u16)src_pixels[1] * 257;
-   out_pixel->b = (u16)src_pixels[0] * 257;
+   out_pixel->r = (u16)src_pixels[0][2] * 257;
+   out_pixel->g = (u16)src_pixels[0][1] * 2

[PATCH 6/7] drm/vkms: Drop YUV formats TODO

2024-01-05 Thread Arthur Grillo
VKMS has support for YUV formats now. Remove the task from the TODO
list.

Signed-off-by: Arthur Grillo 
---
 Documentation/gpu/vkms.rst | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
index ba04ac7c2167..13b866c3617c 100644
--- a/Documentation/gpu/vkms.rst
+++ b/Documentation/gpu/vkms.rst
@@ -122,8 +122,7 @@ There's lots of plane features we could add support for:
 
 - Scaling.
 
-- Additional buffer formats, especially YUV formats for video like NV12.
-  Low/high bpp RGB formats would also be interesting.
+- Additional buffer formats. Low/high bpp RGB formats would be interesting.
 
 - Async updates (currently only possible on cursor plane using the legacy
   cursor api).

-- 
2.43.0



[PATCH 1/7] drm/vkms: Use drm_frame directly

2024-01-05 Thread Arthur Grillo
Remove intermidiary variables and access the variables directly from
drm_frame. These changes should be noop.

Signed-off-by: Arthur Grillo 
---
 drivers/gpu/drm/vkms/vkms_drv.h   |  3 ---
 drivers/gpu/drm/vkms/vkms_formats.c   | 12 +++-
 drivers/gpu/drm/vkms/vkms_plane.c |  3 ---
 drivers/gpu/drm/vkms/vkms_writeback.c |  5 -
 4 files changed, 7 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index 8f5710debb1e..b4b357447292 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -31,9 +31,6 @@ struct vkms_frame_info {
struct drm_rect rotated;
struct iosys_map map[DRM_FORMAT_MAX_PLANES];
unsigned int rotation;
-   unsigned int offset;
-   unsigned int pitch;
-   unsigned int cpp;
 };
 
 struct pixel_argb_u16 {
diff --git a/drivers/gpu/drm/vkms/vkms_formats.c 
b/drivers/gpu/drm/vkms/vkms_formats.c
index 36046b12f296..172830a3936a 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.c
+++ b/drivers/gpu/drm/vkms/vkms_formats.c
@@ -11,8 +11,10 @@
 
 static size_t pixel_offset(const struct vkms_frame_info *frame_info, int x, 
int y)
 {
-   return frame_info->offset + (y * frame_info->pitch)
- + (x * frame_info->cpp);
+   struct drm_framebuffer *fb = frame_info->fb;
+
+   return fb->offsets[0] + (y * fb->pitches[0])
+ + (x * fb->format->cpp[0]);
 }
 
 /*
@@ -131,12 +133,12 @@ void vkms_compose_row(struct line_buffer *stage_buffer, 
struct vkms_plane_state
u8 *src_pixels = get_packed_src_addr(frame_info, y);
int limit = min_t(size_t, drm_rect_width(_info->dst), 
stage_buffer->n_pixels);
 
-   for (size_t x = 0; x < limit; x++, src_pixels += frame_info->cpp) {
+   for (size_t x = 0; x < limit; x++, src_pixels += 
frame_info->fb->format->cpp[0]) {
int x_pos = get_x_position(frame_info, limit, x);
 
if (drm_rotation_90_or_270(frame_info->rotation))
src_pixels = get_packed_src_addr(frame_info, x + 
frame_info->rotated.y1)
-   + frame_info->cpp * y;
+   + frame_info->fb->format->cpp[0] * y;
 
plane->pixel_read(src_pixels, _pixels[x_pos]);
}
@@ -223,7 +225,7 @@ void vkms_writeback_row(struct vkms_writeback_job *wb,
struct pixel_argb_u16 *in_pixels = src_buffer->pixels;
int x_limit = min_t(size_t, drm_rect_width(_info->dst), 
src_buffer->n_pixels);
 
-   for (size_t x = 0; x < x_limit; x++, dst_pixels += frame_info->cpp)
+   for (size_t x = 0; x < x_limit; x++, dst_pixels += 
frame_info->fb->format->cpp[0])
wb->pixel_write(dst_pixels, _pixels[x]);
 }
 
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c 
b/drivers/gpu/drm/vkms/vkms_plane.c
index e5c625ab8e3e..8f2c6ea419a3 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -125,9 +125,6 @@ static void vkms_plane_atomic_update(struct drm_plane 
*plane,
drm_rect_rotate(_info->rotated, 
drm_rect_width(_info->rotated),
drm_rect_height(_info->rotated), 
frame_info->rotation);
 
-   frame_info->offset = fb->offsets[0];
-   frame_info->pitch = fb->pitches[0];
-   frame_info->cpp = fb->format->cpp[0];
vkms_plane_state->pixel_read = get_pixel_conversion_function(fmt);
 }
 
diff --git a/drivers/gpu/drm/vkms/vkms_writeback.c 
b/drivers/gpu/drm/vkms/vkms_writeback.c
index bc724cbd5e3a..c8582df1f739 100644
--- a/drivers/gpu/drm/vkms/vkms_writeback.c
+++ b/drivers/gpu/drm/vkms/vkms_writeback.c
@@ -149,11 +149,6 @@ static void vkms_wb_atomic_commit(struct drm_connector 
*conn,
crtc_state->active_writeback = active_wb;
crtc_state->wb_pending = true;
spin_unlock_irq(>composer_lock);
-
-   wb_frame_info->offset = fb->offsets[0];
-   wb_frame_info->pitch = fb->pitches[0];
-   wb_frame_info->cpp = fb->format->cpp[0];
-
drm_writeback_queue_job(wb_conn, connector_state);
active_wb->pixel_write = get_pixel_write_function(wb_format);
drm_rect_init(_frame_info->src, 0, 0, crtc_width, crtc_height);

-- 
2.43.0



[PATCH 5/7] drm/vkms: Add YUV support

2024-01-05 Thread Arthur Grillo
Add support to the YUV formats bellow:

- NV12
- NV16
- NV24
- NV21
- NV61
- NV42
- YUV420
- YUV422
- YUV444
- YVU420
- YVU422
- YVU444

The conversion matrices of each encoding and range were obtained by
rounding the values of the original conversion matrices multiplied by
2^8. This is done to avoid the use of fixed point operations.

Signed-off-by: Arthur Grillo 
---
 drivers/gpu/drm/vkms/vkms_formats.c | 151 
 drivers/gpu/drm/vkms/vkms_plane.c   |  14 +++-
 2 files changed, 164 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vkms/vkms_formats.c 
b/drivers/gpu/drm/vkms/vkms_formats.c
index 098ed16f2104..b654b6661a20 100644
--- a/drivers/gpu/drm/vkms/vkms_formats.c
+++ b/drivers/gpu/drm/vkms/vkms_formats.c
@@ -119,6 +119,141 @@ static void RGB565_to_argb_u16(u8 **src_pixels, struct 
pixel_argb_u16 *out_pixel
out_pixel->b = drm_fixp2int_round(drm_fixp_mul(fp_b, fp_rb_ratio));
 }
 
+struct pixel_yuv_u8 {
+   u8 y, u, v;
+};
+
+static void ycbcr2rgb(const s16 m[3][3], u8 y, u8 cb, u8 cr, u8 y_offset, u8 
*r, u8 *g, u8 *b)
+{
+   s32 y_16, cb_16, cr_16;
+   s32 r_16, g_16, b_16;
+
+   y_16 =  y - y_offset;
+   cb_16 = cb - 128;
+   cr_16 = cr - 128;
+
+   r_16 = m[0][0] * y_16 + m[0][1] * cb_16 + m[0][2] * cr_16;
+   g_16 = m[1][0] * y_16 + m[1][1] * cb_16 + m[1][2] * cr_16;
+   b_16 = m[2][0] * y_16 + m[2][1] * cb_16 + m[2][2] * cr_16;
+
+   *r = clamp(r_16, 0, 0x) >> 8;
+   *g = clamp(g_16, 0, 0x) >> 8;
+   *b = clamp(b_16, 0, 0x) >> 8;
+}
+
+static void yuv_u8_to_argb_u16(struct pixel_argb_u16 *argb_u16, const struct 
pixel_yuv_u8 *yuv_u8,
+  enum drm_color_encoding encoding, enum 
drm_color_range range)
+{
+   static const s16 bt601_full[3][3] = {
+   {256,   0,  359},
+   {256, -88, -183},
+   {256, 454,0},
+   };
+   static const s16 bt601[3][3] = {
+   {298,0,  409},
+   {298, -100, -208},
+   {298,  516,0},
+   };
+   static const s16 rec709_full[3][3] = {
+   {256,   0,  408},
+   {256, -48, -120},
+   {256, 476,   0 },
+   };
+   static const s16 rec709[3][3] = {
+   {298,   0,  459},
+   {298, -55, -136},
+   {298, 541,0},
+   };
+   static const s16 bt2020_full[3][3] = {
+   {256,   0,  377},
+   {256, -42, -146},
+   {256, 482,0},
+   };
+   static const s16 bt2020[3][3] = {
+   {298,   0,  430},
+   {298, -48, -167},
+   {298, 548,0},
+   };
+
+   u8 r = 0;
+   u8 g = 0;
+   u8 b = 0;
+   bool full = range == DRM_COLOR_YCBCR_FULL_RANGE;
+   unsigned int y_offset = full ? 0 : 16;
+
+   switch (encoding) {
+   case DRM_COLOR_YCBCR_BT601:
+   ycbcr2rgb(full ? bt601_full : bt601,
+ yuv_u8->y, yuv_u8->u, yuv_u8->v, y_offset, , , 
);
+   break;
+   case DRM_COLOR_YCBCR_BT709:
+   ycbcr2rgb(full ? rec709_full : rec709,
+ yuv_u8->y, yuv_u8->u, yuv_u8->v, y_offset, , , 
);
+   break;
+   case DRM_COLOR_YCBCR_BT2020:
+   ycbcr2rgb(full ? bt2020_full : bt2020,
+ yuv_u8->y, yuv_u8->u, yuv_u8->v, y_offset, , , 
);
+   break;
+   default:
+   pr_warn_once("Not supported color encoding\n");
+   break;
+   }
+
+   argb_u16->r = r * 257;
+   argb_u16->g = g * 257;
+   argb_u16->b = b * 257;
+}
+
+static void semi_planar_yuv_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 
*out_pixel,
+   enum drm_color_encoding encoding,
+   enum drm_color_range range)
+{
+   struct pixel_yuv_u8 yuv_u8;
+
+   yuv_u8.y = src_pixels[0][0];
+   yuv_u8.u = src_pixels[1][0];
+   yuv_u8.v = src_pixels[1][1];
+
+   yuv_u8_to_argb_u16(out_pixel, _u8, encoding, range);
+}
+
+static void semi_planar_yvu_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 
*out_pixel,
+   enum drm_color_encoding encoding,
+   enum drm_color_range range)
+{
+   struct pixel_yuv_u8 yuv_u8;
+
+   yuv_u8.y = src_pixels[0][0];
+   yuv_u8.v = src_pixels[1][0];
+   yuv_u8.u = src_pixels[1][1];
+
+   yuv_u8_to_argb_u16(out_pixel, _u8, encoding, range);
+}
+
+static void planar_yuv_to_argb_u16(u8 **src_pixels, struct pixel_argb_u16 
*out_pixel,
+  enum drm_color_encoding encoding, enum 
drm_color_range range)
+{
+   struct pixel_yuv_u8 yuv_u8;
+
+   yuv_u8.y = src_pixels[0][0];
+   yuv_u8.u = src_pixels[1][0];
+   yuv_u

Re: [RFC PATCH v3 04/23] drm/vkms: Add kunit tests for VKMS LUT handling

2023-11-10 Thread Arthur Grillo



On 09/11/23 19:05, Arthur Grillo wrote:
> 
> 
> On 08/11/23 13:36, Harry Wentland wrote:
>> Debugging LUT math is much easier when we can unit test
>> it. Add kunit functionality to VKMS and add tests for
>>  - get_lut_index
>>  - lerp_u16
>>
>> v3:
>>  - Use include way of testing static functions (Arthur)
>>
>> Signed-off-by: Harry Wentland 
>> Cc: Arthur Grillo 
>> ---
>>  drivers/gpu/drm/vkms/Kconfig  |  5 ++
>>  drivers/gpu/drm/vkms/tests/.kunitconfig   |  4 ++
>>  drivers/gpu/drm/vkms/tests/vkms_color_tests.c | 62 +++

Also, s/tests/test/ to follow the naming of other test files (like on
drivers/gpu/drm/tests/)

Best Regards,
~Arthur Grillo

>>  drivers/gpu/drm/vkms/vkms_composer.c  |  8 ++-
>>  4 files changed, 77 insertions(+), 2 deletions(-)
>>  create mode 100644 drivers/gpu/drm/vkms/tests/.kunitconfig
>>  create mode 100644 drivers/gpu/drm/vkms/tests/vkms_color_tests.c
>>
>> diff --git a/drivers/gpu/drm/vkms/Kconfig b/drivers/gpu/drm/vkms/Kconfig
>> index b9ecdebecb0b..c1f8b343ff0e 100644
>> --- a/drivers/gpu/drm/vkms/Kconfig
>> +++ b/drivers/gpu/drm/vkms/Kconfig
>> @@ -13,3 +13,8 @@ config DRM_VKMS
>>a VKMS.
>>  
>>If M is selected the module will be called vkms.
>> +
>> +config DRM_VKMS_KUNIT_TESTS
>> +tristate "Tests for VKMS" if !KUNIT_ALL_TESTS
>> +depends on DRM_VKMS && KUNIT
>> +default KUNIT_ALL_TESTS
>> diff --git a/drivers/gpu/drm/vkms/tests/.kunitconfig 
>> b/drivers/gpu/drm/vkms/tests/.kunitconfig
>> new file mode 100644
>> index ..70e378228cbd
>> --- /dev/null
>> +++ b/drivers/gpu/drm/vkms/tests/.kunitconfig
>> @@ -0,0 +1,4 @@
>> +CONFIG_KUNIT=y
>> +CONFIG_DRM=y
>> +CONFIG_DRM_VKMS=y
>> +CONFIG_DRM_VKMS_KUNIT_TESTS=y
>> diff --git a/drivers/gpu/drm/vkms/tests/vkms_color_tests.c 
>> b/drivers/gpu/drm/vkms/tests/vkms_color_tests.c
>> new file mode 100644
>> index ..b995114cf6b8
>> --- /dev/null
>> +++ b/drivers/gpu/drm/vkms/tests/vkms_color_tests.c
>> @@ -0,0 +1,62 @@
>> +/* SPDX-License-Identifier: GPL-2.0+ */
>> +
>> +#include 
>> +
>> +#include 
>> +
>> +#define TEST_LUT_SIZE 16
>> +
>> +static struct drm_color_lut test_linear_array[TEST_LUT_SIZE] = {
>> +{ 0x0, 0x0, 0x0, 0 },
>> +{ 0x, 0x, 0x, 0 },
>> +{ 0x, 0x, 0x, 0 },
>> +{ 0x, 0x, 0x, 0 },
>> +{ 0x, 0x, 0x, 0 },
>> +{ 0x, 0x, 0x, 0 },
>> +{ 0x, 0x, 0x, 0 },
>> +{ 0x, 0x, 0x, 0 },
>> +{ 0x, 0x, 0x, 0 },
>> +{ 0x, 0x, 0x, 0 },
>> +{ 0x, 0x, 0x, 0 },
>> +{ 0x, 0x, 0x, 0 },
>> +{ 0x, 0x, 0x, 0 },
>> +{ 0x, 0x, 0x, 0 },
>> +{ 0x, 0x, 0x, 0 },
>> +{ 0x, 0x, 0x, 0 },
>> +};
>> +
>> +const struct vkms_color_lut test_linear_lut = {
>> +.base = test_linear_array,
>> +.lut_length = TEST_LUT_SIZE,
>> +.channel_value2index_ratio = 0xf000fll
>> +};
>> +
>> +
>> +static void vkms_color_test_get_lut_index(struct kunit *test)
>> +{
>> +int i;
>> +
>> +KUNIT_EXPECT_EQ(test, drm_fixp2int(get_lut_index(_linear_lut, 
>> test_linear_array[0].red)), 0);
>> +
>> +for (i = 0; i < TEST_LUT_SIZE; i++)
>> +KUNIT_EXPECT_EQ(test, 
>> drm_fixp2int_ceil(get_lut_index(_linear_lut, 
>> test_linear_array[i].red)), i);
>> +}
>> +
>> +static void vkms_color_test_lerp(struct kunit *test)
>> +{
>> +KUNIT_EXPECT_EQ(test, lerp_u16(0x0, 0x10, 0x8000), 0x8);
>> +}
>> +
>> +static struct kunit_case vkms_color_test_cases[] = {
>> +KUNIT_CASE(vkms_color_test_get_lut_index),
>> +KUNIT_CASE(vkms_color_test_lerp),
>> +{}
>> +};
>> +
>> +static struct kunit_suite vkms_color_test_suite = {
>> +.name = "vkms-color",
>> +.test_cases = vkms_color_test_cases,
>> +};
>> +kunit_test_suite(vkms_color_test_suite);
>> +
>> +MODULE_LICENSE("GPL");
>> \ No newline at end of file
>> diff --git a/drivers/gpu/drm/vkms/vkms_composer.c 
>> b/drivers/gpu/drm/vkms/vkms_composer.c
>> index 3c99fb8b54e2..6f942896036e 100644
>> --- a/drivers/gpu/drm/vkms/vkms_composer.c
>> +++ b/drivers/gpu/drm/vkms/vkms_composer.c
>> @@ -91,7 

Re: [RFC PATCH v3 05/23] drm/vkms: Avoid reading beyond LUT array

2023-11-10 Thread Arthur Grillo



On 08/11/23 13:36, Harry Wentland wrote:
> When the floor LUT index (drm_fixp2int(lut_index) is the last
> index of the array the ceil LUT index will point to an entry
> beyond the array. Make sure we guard against it and use the
> value of the floor LUT index.
> 
> v3:
>  - Drop bits from commit description that didn't contribute
>anything of value
> 
> Signed-off-by: Harry Wentland 
> Cc: Arthur Grillo 

LGTM
Reviewed-by: Arthur Grillo 

Best Regards,
~Arthur Grillo

> ---
>  drivers/gpu/drm/vkms/vkms_composer.c | 14 ++
>  1 file changed, 10 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vkms/vkms_composer.c 
> b/drivers/gpu/drm/vkms/vkms_composer.c
> index 6f942896036e..25b6b73bece8 100644
> --- a/drivers/gpu/drm/vkms/vkms_composer.c
> +++ b/drivers/gpu/drm/vkms/vkms_composer.c
> @@ -123,6 +123,8 @@ static u16 apply_lut_to_channel_value(const struct 
> vkms_color_lut *lut, u16 chan
> enum lut_channel channel)
>  {
>   s64 lut_index = get_lut_index(lut, channel_value);
> + u16 *floor_lut_value, *ceil_lut_value;
> + u16 floor_channel_value, ceil_channel_value;
>  
>   /*
>* This checks if `struct drm_color_lut` has any gap added by the 
> compiler
> @@ -130,11 +132,15 @@ static u16 apply_lut_to_channel_value(const struct 
> vkms_color_lut *lut, u16 chan
>*/
>   static_assert(sizeof(struct drm_color_lut) == sizeof(__u16) * 4);
>  
> - u16 *floor_lut_value = (__u16 *)>base[drm_fixp2int(lut_index)];
> - u16 *ceil_lut_value = (__u16 *)>base[drm_fixp2int_ceil(lut_index)];
> + floor_lut_value = (__u16 *)>base[drm_fixp2int(lut_index)];
> + if (drm_fixp2int(lut_index) == (lut->lut_length - 1))
> + /* We're at the end of the LUT array, use same value for ceil 
> and floor */
> + ceil_lut_value = floor_lut_value;
> + else
> + ceil_lut_value = (__u16 
> *)>base[drm_fixp2int_ceil(lut_index)];
>  
> - u16 floor_channel_value = floor_lut_value[channel];
> - u16 ceil_channel_value = ceil_lut_value[channel];
> + floor_channel_value = floor_lut_value[channel];
> + ceil_channel_value = ceil_lut_value[channel];
>  
>   return lerp_u16(floor_channel_value, ceil_channel_value,
>   lut_index & DRM_FIXED_DECIMAL_MASK);


Re: [RFC PATCH v3 04/23] drm/vkms: Add kunit tests for VKMS LUT handling

2023-11-09 Thread Arthur Grillo



On 08/11/23 13:36, Harry Wentland wrote:
> Debugging LUT math is much easier when we can unit test
> it. Add kunit functionality to VKMS and add tests for
>  - get_lut_index
>  - lerp_u16
> 
> v3:
>  - Use include way of testing static functions (Arthur)
> 
> Signed-off-by: Harry Wentland 
> Cc: Arthur Grillo 
> ---
>  drivers/gpu/drm/vkms/Kconfig  |  5 ++
>  drivers/gpu/drm/vkms/tests/.kunitconfig   |  4 ++
>  drivers/gpu/drm/vkms/tests/vkms_color_tests.c | 62 +++
>  drivers/gpu/drm/vkms/vkms_composer.c  |  8 ++-
>  4 files changed, 77 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/gpu/drm/vkms/tests/.kunitconfig
>  create mode 100644 drivers/gpu/drm/vkms/tests/vkms_color_tests.c
> 
> diff --git a/drivers/gpu/drm/vkms/Kconfig b/drivers/gpu/drm/vkms/Kconfig
> index b9ecdebecb0b..c1f8b343ff0e 100644
> --- a/drivers/gpu/drm/vkms/Kconfig
> +++ b/drivers/gpu/drm/vkms/Kconfig
> @@ -13,3 +13,8 @@ config DRM_VKMS
> a VKMS.
>  
> If M is selected the module will be called vkms.
> +
> +config DRM_VKMS_KUNIT_TESTS
> + tristate "Tests for VKMS" if !KUNIT_ALL_TESTS
> + depends on DRM_VKMS && KUNIT
> + default KUNIT_ALL_TESTS
> diff --git a/drivers/gpu/drm/vkms/tests/.kunitconfig 
> b/drivers/gpu/drm/vkms/tests/.kunitconfig
> new file mode 100644
> index ..70e378228cbd
> --- /dev/null
> +++ b/drivers/gpu/drm/vkms/tests/.kunitconfig
> @@ -0,0 +1,4 @@
> +CONFIG_KUNIT=y
> +CONFIG_DRM=y
> +CONFIG_DRM_VKMS=y
> +CONFIG_DRM_VKMS_KUNIT_TESTS=y
> diff --git a/drivers/gpu/drm/vkms/tests/vkms_color_tests.c 
> b/drivers/gpu/drm/vkms/tests/vkms_color_tests.c
> new file mode 100644
> index ..b995114cf6b8
> --- /dev/null
> +++ b/drivers/gpu/drm/vkms/tests/vkms_color_tests.c
> @@ -0,0 +1,62 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +
> +#include 
> +
> +#include 
> +
> +#define TEST_LUT_SIZE 16
> +
> +static struct drm_color_lut test_linear_array[TEST_LUT_SIZE] = {
> + { 0x0, 0x0, 0x0, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> +};
> +
> +const struct vkms_color_lut test_linear_lut = {
> + .base = test_linear_array,
> + .lut_length = TEST_LUT_SIZE,
> + .channel_value2index_ratio = 0xf000fll
> +};
> +
> +
> +static void vkms_color_test_get_lut_index(struct kunit *test)
> +{
> + int i;
> +
> + KUNIT_EXPECT_EQ(test, drm_fixp2int(get_lut_index(_linear_lut, 
> test_linear_array[0].red)), 0);
> +
> + for (i = 0; i < TEST_LUT_SIZE; i++)
> + KUNIT_EXPECT_EQ(test, 
> drm_fixp2int_ceil(get_lut_index(_linear_lut, test_linear_array[i].red)), 
> i);
> +}
> +
> +static void vkms_color_test_lerp(struct kunit *test)
> +{
> + KUNIT_EXPECT_EQ(test, lerp_u16(0x0, 0x10, 0x8000), 0x8);
> +}
> +
> +static struct kunit_case vkms_color_test_cases[] = {
> + KUNIT_CASE(vkms_color_test_get_lut_index),
> + KUNIT_CASE(vkms_color_test_lerp),
> + {}
> +};
> +
> +static struct kunit_suite vkms_color_test_suite = {
> + .name = "vkms-color",
> + .test_cases = vkms_color_test_cases,
> +};
> +kunit_test_suite(vkms_color_test_suite);
> +
> +MODULE_LICENSE("GPL");
> \ No newline at end of file
> diff --git a/drivers/gpu/drm/vkms/vkms_composer.c 
> b/drivers/gpu/drm/vkms/vkms_composer.c
> index 3c99fb8b54e2..6f942896036e 100644
> --- a/drivers/gpu/drm/vkms/vkms_composer.c
> +++ b/drivers/gpu/drm/vkms/vkms_composer.c
> @@ -91,7 +91,7 @@ static void fill_background(const struct pixel_argb_u16 
> *background_color,
>  }
>  
>  // lerp(a, b, t) = a + (b - a) * t
> -static u16 lerp_u16(u16 a, u16 b, s64 t)
> +u16 lerp_u16(u16 a, u16 b, s64 t)

Now you don't need to remove the static keyword.

>  {
>   s64 a_fp = drm_int2fixp(a);
>   s64 b_fp = drm_int2fixp(b);
> @@ -101,7 +101,7 @@ static u16 lerp_u16(u16 a, u16 b, s64 t)
>   return drm_fixp2int(a_fp + delta);
>  }
>  
> -static s64 get_lut_index(const struct vkms_color_lut *lut, u16 channel_value)
> +s64 get_lut_index(const struct vkms_color_lut *lut, u16 channel_value)

DITTO

Best Regards,
~Arthur Grillo

>  {
>   s64 color_channel_fp = drm_int2fixp(channel_value);
>  
> @@ -429,3 +429,7 @@ int vkms_set_crc_source(struct drm_crtc *crtc, const char 
> *src_name)
>  
>   return ret;
>  }
> +
> +#ifdef CONFIG_DRM_VKMS_KUNIT_TESTS
> +#include "tests/vkms_color_tests.c"
> +#endif


Re: [RFC PATCH v2 04/17] drm/vkms: Add kunit tests for VKMS LUT handling

2023-10-23 Thread Arthur Grillo



On 19/10/23 18:21, Harry Wentland wrote:
> Debugging LUT math is much easier when we can unit test
> it. Add kunit functionality to VKMS and add tests for
>  - get_lut_index
>  - lerp_u16
> 
> Signed-off-by: Harry Wentland 
> Cc: Ville Syrjala 
> Cc: Pekka Paalanen 
> Cc: Simon Ser 
> Cc: Harry Wentland 
> Cc: Melissa Wen 
> Cc: Jonas Ådahl 
> Cc: Sebastian Wick 
> Cc: Shashank Sharma 
> Cc: Alexander Goins 
> Cc: Joshua Ashton 
> Cc: Michel Dänzer 
> Cc: Aleix Pol 
> Cc: Xaver Hugl 
> Cc: Victoria Brekenfeld 
> Cc: Sima 
> Cc: Uma Shankar 
> Cc: Naseer Ahmed 
> Cc: Christopher Braga 
> Cc: Abhinav Kumar 
> Cc: Arthur Grillo 
> Cc: Hector Martin 
> Cc: Liviu Dudau 
> Cc: Sasha McIntosh 
> ---
>  drivers/gpu/drm/vkms/Kconfig  |  5 ++
>  drivers/gpu/drm/vkms/Makefile |  2 +
>  drivers/gpu/drm/vkms/tests/.kunitconfig   |  4 ++
>  drivers/gpu/drm/vkms/tests/Makefile   |  4 ++
>  drivers/gpu/drm/vkms/tests/vkms_color_tests.c | 64 +++
>  drivers/gpu/drm/vkms/vkms_composer.c  |  4 +-
>  drivers/gpu/drm/vkms/vkms_composer.h  | 11 
>  7 files changed, 92 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/gpu/drm/vkms/tests/.kunitconfig
>  create mode 100644 drivers/gpu/drm/vkms/tests/Makefile
>  create mode 100644 drivers/gpu/drm/vkms/tests/vkms_color_tests.c
>  create mode 100644 drivers/gpu/drm/vkms/vkms_composer.h
> 
> diff --git a/drivers/gpu/drm/vkms/Kconfig b/drivers/gpu/drm/vkms/Kconfig
> index 1816562381a2..372cc5fa92f1 100644
> --- a/drivers/gpu/drm/vkms/Kconfig
> +++ b/drivers/gpu/drm/vkms/Kconfig
> @@ -13,3 +13,8 @@ config DRM_VKMS
> a VKMS.
>  
> If M is selected the module will be called vkms.
> +
> +config DRM_VKMS_KUNIT_TESTS
> + tristate "Tests for VKMS" if !KUNIT_ALL_TESTS
> + depends on DRM_VKMS && KUNIT
> + default KUNIT_ALL_TESTS
> diff --git a/drivers/gpu/drm/vkms/Makefile b/drivers/gpu/drm/vkms/Makefile
> index 1b28a6a32948..d3440f228f46 100644
> --- a/drivers/gpu/drm/vkms/Makefile
> +++ b/drivers/gpu/drm/vkms/Makefile
> @@ -9,3 +9,5 @@ vkms-y := \
>   vkms_writeback.o
>  
>  obj-$(CONFIG_DRM_VKMS) += vkms.o
> +
> +obj-y += tests/
> \ No newline at end of file
> diff --git a/drivers/gpu/drm/vkms/tests/.kunitconfig 
> b/drivers/gpu/drm/vkms/tests/.kunitconfig
> new file mode 100644
> index ..70e378228cbd
> --- /dev/null
> +++ b/drivers/gpu/drm/vkms/tests/.kunitconfig
> @@ -0,0 +1,4 @@
> +CONFIG_KUNIT=y
> +CONFIG_DRM=y
> +CONFIG_DRM_VKMS=y
> +CONFIG_DRM_VKMS_KUNIT_TESTS=y
> diff --git a/drivers/gpu/drm/vkms/tests/Makefile 
> b/drivers/gpu/drm/vkms/tests/Makefile
> new file mode 100644
> index ..761465332ff2
> --- /dev/null
> +++ b/drivers/gpu/drm/vkms/tests/Makefile
> @@ -0,0 +1,4 @@
> +# SPDX-License-Identifier: GPL-2.0+
> +
> +obj-$(CONFIG_DRM_VKMS_KUNIT_TESTS) += \
> + vkms_color_tests.o
> \ No newline at end of file
> diff --git a/drivers/gpu/drm/vkms/tests/vkms_color_tests.c 
> b/drivers/gpu/drm/vkms/tests/vkms_color_tests.c
> new file mode 100644
> index ..843b2e1d607e
> --- /dev/null
> +++ b/drivers/gpu/drm/vkms/tests/vkms_color_tests.c
> @@ -0,0 +1,64 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +
> +#include 
> +
> +#include 
> +
> +#include "../vkms_composer.h"
> +
> +#define TEST_LUT_SIZE 16
> +
> +static struct drm_color_lut test_linear_array[TEST_LUT_SIZE] = {
> + { 0x0, 0x0, 0x0, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> + { 0x, 0x, 0x, 0 },
> +};
> +
> +const struct vkms_color_lut test_linear_lut = {
> + .base = test_linear_array,
> + .lut_length = TEST_LUT_SIZE,
> + .channel_value2index_ratio = 0xf000fll
> +};
> +
> +
> +static void vkms_color_test_get_lut_index(struct kunit *test)
> +{
> + int i;
> +
> + KUNIT_EXPECT_EQ(test, drm_fixp2int(get_lut_index(_linear_lut, 
> test_linear_array[0].red)), 0);
> +
> + for (i = 0; i < TEST_LUT_SIZE; i++)
> + KUNIT_EXPECT_EQ(test, 
> drm_fixp2int_ceil(ge

Re: [PATCH 1/3] drm/tests: Fix kunit_release_action ctx argument

2023-09-27 Thread Arthur Grillo



On 27/09/23 19:47, Maira Canal wrote:
> Hi Arthur,
> 
> On 9/20/23 03:11, Arthur Grillo wrote:
>> The kunit_action_platform_driver_unregister is added with
>> _platform_driver as ctx, but the kunit_release_action is called
>> pdev as ctx. Fix that by replacing it with _platform_driver.
>>
>> Fixes: 4f2b0b583baa ("drm/tests: helpers: Switch to kunit actions")
>> Signed-off-by: Arthur Grillo 
> 
> Reviewed-by: Maíra Canal 
> 
> Do you need me to apply this patch to drm-misc-fixes?

Yes, please do, if possible.

Thanks,
~Arthur Grillo

> 
> Best Regards,
> - Maíra
> 
>> ---
>>   drivers/gpu/drm/tests/drm_kunit_helpers.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c 
>> b/drivers/gpu/drm/tests/drm_kunit_helpers.c
>> index 3d624ff2f651..3150dbc647ee 100644
>> --- a/drivers/gpu/drm/tests/drm_kunit_helpers.c
>> +++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c
>> @@ -118,7 +118,7 @@ void drm_kunit_helper_free_device(struct kunit *test, 
>> struct device *dev)
>> kunit_release_action(test,
>>kunit_action_platform_driver_unregister,
>> - pdev);
>> + _platform_driver);
>>   }
>>   EXPORT_SYMBOL_GPL(drm_kunit_helper_free_device);
>>  


Re: [PATCH 3/3] drm/tests: Fix a use-after-free bug in __drm_kunit_helper_alloc_drm_device()

2023-09-20 Thread Arthur Grillo



On 20/09/23 03:40, Maxime Ripard wrote:
> Hi,
> 
> On Wed, Sep 20, 2023 at 03:11:38AM -0300, Arthur Grillo wrote:
>> In __drm_kunit_helper_alloc_drm_device_with_driver(), a drm_driver is
>> allocated with kunit_kzalloc. If the dev argument was allocated by
>> drm_kunit_helper_alloc_device, its deferred actions would access the
>> already deallocated drm_driver.
> 
> We already have a fix for that in drm-misc-fixes, could you give it a try?

Oh! I didn't see that. I just ran it, it worked! Great fix :)

Best Regards,
~Arthur Grillo

> 
> Thanks!
> Maxime


[PATCH 3/3] drm/tests: Fix a use-after-free bug in __drm_kunit_helper_alloc_drm_device()

2023-09-20 Thread Arthur Grillo
00(slab|zone=0)
page_type: 0x()
raw: 0200 62401900 0122 
raw:  80080008 0001
page dumped because: kasan: bad access detected

Memory state around the buggy address:
 63194d00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
 63194d80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>63194e00: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
  ^
 63194e80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
 63194f00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
==

Signed-off-by: Arthur Grillo 
---
 drivers/gpu/drm/tests/drm_kunit_helpers.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c 
b/drivers/gpu/drm/tests/drm_kunit_helpers.c
index 3150dbc647ee..655cedf7ab13 100644
--- a/drivers/gpu/drm/tests/drm_kunit_helpers.c
+++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c
@@ -129,6 +129,7 @@ __drm_kunit_helper_alloc_drm_device_with_driver(struct 
kunit *test,
const struct drm_driver *driver)
 {
struct drm_device *drm;
+   struct platform_device *pdev = to_platform_device(dev);
void *container;
int ret;
 
@@ -143,6 +144,21 @@ __drm_kunit_helper_alloc_drm_device_with_driver(struct 
kunit *test,
if (ret)
return ERR_PTR(ret);
 
+   ret = kunit_move_action_to_top_or_reset(test,
+   
kunit_action_platform_driver_unregister,
+   _platform_driver);
+   KUNIT_ASSERT_EQ(test, ret, 0);
+
+   ret = kunit_move_action_to_top_or_reset(test,
+   
kunit_action_platform_device_put,
+   pdev);
+   KUNIT_ASSERT_EQ(test, ret, 0);
+
+   ret = kunit_move_action_to_top_or_reset(test,
+   
kunit_action_platform_device_del,
+   pdev);
+   KUNIT_ASSERT_EQ(test, ret, 0);
+
return drm;
 }
 EXPORT_SYMBOL_GPL(__drm_kunit_helper_alloc_drm_device_with_driver);

-- 
2.41.0



[PATCH 2/3] kunit: Add kunit_move_action_to_top_or_reset() to reorder actions

2023-09-20 Thread Arthur Grillo
On Kunit, if we allocate a resource A and B on this order, with its
deferred actions to free them. The resource stack would be something
like this:

 +-+
 | free(B) |
 +-+
 |   ...   |
 +-+
 | free(A) |
 +-+

If the deferred action of A accesses B, this would cause a
use-after-free bug. To solve that, we need a way to change the order
of actions.

Create a function to move an action to the top of the resource stack,
as shown in the diagram below.

 +-++-+
 | free(B) || free(A) |
 +-++-+
 |   ...   | -> | free(B) |
 +-++-+
 | free(A) ||   ...   |
 +-++-+

Signed-off-by: Arthur Grillo 
---
 include/kunit/resource.h | 17 +
 lib/kunit/resource.c | 19 +++
 2 files changed, 36 insertions(+)

diff --git a/include/kunit/resource.h b/include/kunit/resource.h
index c7383e90f5c9..c598b23680e3 100644
--- a/include/kunit/resource.h
+++ b/include/kunit/resource.h
@@ -479,4 +479,21 @@ void kunit_remove_action(struct kunit *test,
 void kunit_release_action(struct kunit *test,
  kunit_action_t *action,
  void *ctx);
+
+/**
+ * kunit_move_action_to_top_or_reset - Move a previously added action to the 
top
+ *of the order of actions calls.
+ * @test: Test case to associate the action with.
+ * @action: The function to run on test exit
+ * @ctx: Data passed into @func
+ *
+ * Reorder the action stack, by moving the desired action to the top.
+ *
+ * Returns:
+ *   0 on success, an error if the action could not be inserted on the top.
+ */
+int kunit_move_action_to_top_or_reset(struct kunit *test,
+ kunit_action_t *action,
+ void *ctx);
+
 #endif /* _KUNIT_RESOURCE_H */
diff --git a/lib/kunit/resource.c b/lib/kunit/resource.c
index f0209252b179..fe40a34b62a6 100644
--- a/lib/kunit/resource.c
+++ b/lib/kunit/resource.c
@@ -176,3 +176,22 @@ void kunit_release_action(struct kunit *test,
}
 }
 EXPORT_SYMBOL_GPL(kunit_release_action);
+
+int kunit_move_action_to_top_or_reset(struct kunit *test,
+ kunit_action_t *action,
+ void *ctx)
+{
+   struct kunit_action_ctx match_ctx;
+   struct kunit_resource *res;
+
+   match_ctx.func = action;
+   match_ctx.ctx = ctx;
+   res = kunit_find_resource(test, __kunit_action_match, _ctx);
+   if (res) {
+   kunit_remove_action(test, action, ctx);
+   return kunit_add_action_or_reset(test, action, ctx);
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(kunit_move_action_to_top_or_reset);

-- 
2.41.0



[PATCH 1/3] drm/tests: Fix kunit_release_action ctx argument

2023-09-20 Thread Arthur Grillo
The kunit_action_platform_driver_unregister is added with
_platform_driver as ctx, but the kunit_release_action is called
pdev as ctx. Fix that by replacing it with _platform_driver.

Fixes: 4f2b0b583baa ("drm/tests: helpers: Switch to kunit actions")
Signed-off-by: Arthur Grillo 
---
 drivers/gpu/drm/tests/drm_kunit_helpers.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c 
b/drivers/gpu/drm/tests/drm_kunit_helpers.c
index 3d624ff2f651..3150dbc647ee 100644
--- a/drivers/gpu/drm/tests/drm_kunit_helpers.c
+++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c
@@ -118,7 +118,7 @@ void drm_kunit_helper_free_device(struct kunit *test, 
struct device *dev)
 
kunit_release_action(test,
 kunit_action_platform_driver_unregister,
-pdev);
+_platform_driver);
 }
 EXPORT_SYMBOL_GPL(drm_kunit_helper_free_device);
 

-- 
2.41.0



[PATCH 0/3] Fix a couble of bugs in drm_kunit_helpers.c

2023-09-20 Thread Arthur Grillo
This patchset started when I found a use-after-free error reported by
KASAN while running some tests that did some mocking. When trying to fix
the initial problem, I found another noon-related one.

The second bug is just a wrong argument passed to a kunit_release_action
call. Patch #1 solves that.

Patches #2 and #3 solve the use-after-free bug. This error was a bit
trickier to find. Basically, the usual order in which the kunit_actions
run is the culprit, so #2 creates a helper function to reorder actions,
and #3 uses that helper.

Signed-off-by: Arthur Grillo 
---
Arthur Grillo (3):
  drm/tests: Fix kunit_release_action ctx argument
  kunit: Add kunit_move_action_to_top_or_reset() to reorder actions
  drm/tests: Fix a use-after-free bug in 
__drm_kunit_helper_alloc_drm_device()

 drivers/gpu/drm/tests/drm_kunit_helpers.c | 18 +-
 include/kunit/resource.h  | 17 +
 lib/kunit/resource.c  | 19 +++
 3 files changed, 53 insertions(+), 1 deletion(-)
---
base-commit: 37454bcbb68601c326b58ac45f508067047d791f
change-id: 20230918-kunit-kasan-fixes-88ee78002078

Best regards,
-- 
Arthur Grillo 



[PATCH RESEND v3 2/2] drm/tests: Add new format conversion tests to better cover drm_fb_blit()

2023-09-18 Thread Arthur Grillo
To fully cover drm_fb_blit(), add format conversion tests that are only
supported through drm_fb_blit().

Signed-off-by: Arthur Grillo 
Reviewed-by: Maíra Canal 
---
 drivers/gpu/drm/tests/drm_format_helper_test.c | 142 +
 1 file changed, 142 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c 
b/drivers/gpu/drm/tests/drm_format_helper_test.c
index 9cad723ada9d..8ad062bd2396 100644
--- a/drivers/gpu/drm/tests/drm_format_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
@@ -81,6 +81,16 @@ struct fb_swab_result {
const u32 expected[TEST_BUF_SIZE];
 };
 
+struct convert_to_xbgr_result {
+   unsigned int dst_pitch;
+   const u32 expected[TEST_BUF_SIZE];
+};
+
+struct convert_to_abgr_result {
+   unsigned int dst_pitch;
+   const u32 expected[TEST_BUF_SIZE];
+};
+
 struct convert_xrgb_case {
const char *name;
unsigned int pitch;
@@ -98,6 +108,8 @@ struct convert_xrgb_case {
struct convert_to_argb2101010_result argb2101010_result;
struct convert_to_mono_result mono_result;
struct fb_swab_result swab_result;
+   struct convert_to_xbgr_result xbgr_result;
+   struct convert_to_abgr_result abgr_result;
 };
 
 static struct convert_xrgb_case convert_xrgb_cases[] = {
@@ -155,6 +167,14 @@ static struct convert_xrgb_case 
convert_xrgb_cases[] = {
.dst_pitch =  TEST_USE_DEFAULT_PITCH,
.expected = { 0xFF01 },
},
+   .xbgr_result = {
+   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
+   .expected = { 0x01FF },
+   },
+   .abgr_result = {
+   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
+   .expected = { 0xFFFF },
+   },
},
{
.name = "single_pixel_clip_rectangle",
@@ -213,6 +233,14 @@ static struct convert_xrgb_case 
convert_xrgb_cases[] = {
.dst_pitch =  TEST_USE_DEFAULT_PITCH,
.expected = { 0xFF10 },
},
+   .xbgr_result = {
+   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
+   .expected = { 0x10FF },
+   },
+   .abgr_result = {
+   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
+   .expected = { 0xFFFF },
+   },
},
{
/* Well known colors: White, black, red, green, blue, magenta,
@@ -343,6 +371,24 @@ static struct convert_xrgb_case 
convert_xrgb_cases[] = {
0x0077, 0x0088,
},
},
+   .xbgr_result = {
+   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
+   .expected = {
+   0x11FF, 0x2200,
+   0x33FF, 0x4400FF00,
+   0x55FF, 0x66FF00FF,
+   0x7700, 0x8800,
+   },
+   },
+   .abgr_result = {
+   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
+   .expected = {
+   0x, 0xFF00,
+   0xFFFF, 0xFF00FF00,
+   0x, 0x00FF,
+   0xFF00, 0xFF00,
+   },
+   },
},
{
/* Randomly picked colors. Full buffer within the clip area. */
@@ -458,6 +504,22 @@ static struct convert_xrgb_case 
convert_xrgb_cases[] = {
0x0303A8C2, 0x73F06CD2, 0x9C440EA3, 0x, 
0x,
},
},
+   .xbgr_result = {
+   .dst_pitch =  20,
+   .expected = {
+   0xA19C440E, 0xB1054D11, 0xC103F3A8, 0x, 
0x,
+   0xD173F06C, 0xA29C440E, 0xB2054D11, 0x, 
0x,
+   0xC20303A8, 0xD273F06C, 0xA39C440E, 0x, 
0x,
+   },
+   },
+   .abgr_result = {
+   .dst_pitch =  20,
+   .expected = {
+   0xFF9C440E, 0xFF054D11, 0xFF03F3A8, 0x, 
0x,
+   0xFF73F06C, 0xFF9C440E, 0xFF054D11, 0x, 
0x,
+   0xFF0303A8, 0xFF73F06C, 0xFF9C440E, 0x, 
0x,
+   },
+   },
},
 };
 
@@ -1082,6 +1144,84 @@ static void drm_test_fb_swab(struct kunit *test)
KUNIT_EXPECT_MEMEQ(test, b

[PATCH RESEND v3 1/2] drm/tests: Add calls to drm_fb_blit() on supported format conversion tests

2023-09-18 Thread Arthur Grillo
Add a call to drm_fb_blit() on existing format conversion tests that
has support.

Signed-off-by: Arthur Grillo 
Reviewed-by: Maíra Canal 
---
 drivers/gpu/drm/tests/drm_format_helper_test.c | 143 +
 1 file changed, 143 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c 
b/drivers/gpu/drm/tests/drm_format_helper_test.c
index 1a6bd291345d..9cad723ada9d 100644
--- a/drivers/gpu/drm/tests/drm_format_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
@@ -643,6 +643,18 @@ static void drm_test_fb_xrgb_to_rgb565(struct kunit 
*test)
drm_fb_xrgb_to_rgb565(, >dst_pitch, , , 
>clip, true);
buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / 
sizeof(__le16));
KUNIT_EXPECT_MEMEQ(test, buf, result->expected_swab, dst_size);
+
+   buf = dst.vaddr;
+   memset(buf, 0, dst_size);
+
+   int blit_result = 0;
+
+   blit_result = drm_fb_blit(, dst_pitch, DRM_FORMAT_RGB565, , 
, >clip);
+
+   buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / 
sizeof(__le16));
+
+   KUNIT_EXPECT_FALSE(test, blit_result);
+   KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
 }
 
 static void drm_test_fb_xrgb_to_xrgb1555(struct kunit *test)
@@ -677,6 +689,18 @@ static void drm_test_fb_xrgb_to_xrgb1555(struct kunit 
*test)
drm_fb_xrgb_to_xrgb1555(, dst_pitch, , , >clip);
buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / 
sizeof(__le16));
KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
+
+   buf = dst.vaddr; /* restore original value of buf */
+   memset(buf, 0, dst_size);
+
+   int blit_result = 0;
+
+   blit_result = drm_fb_blit(, dst_pitch, DRM_FORMAT_XRGB1555, , 
, >clip);
+
+   buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / 
sizeof(__le16));
+
+   KUNIT_EXPECT_FALSE(test, blit_result);
+   KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
 }
 
 static void drm_test_fb_xrgb_to_argb1555(struct kunit *test)
@@ -711,6 +735,18 @@ static void drm_test_fb_xrgb_to_argb1555(struct kunit 
*test)
drm_fb_xrgb_to_argb1555(, dst_pitch, , , >clip);
buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / 
sizeof(__le16));
KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
+
+   buf = dst.vaddr; /* restore original value of buf */
+   memset(buf, 0, dst_size);
+
+   int blit_result = 0;
+
+   blit_result = drm_fb_blit(, dst_pitch, DRM_FORMAT_ARGB1555, , 
, >clip);
+
+   buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / 
sizeof(__le16));
+
+   KUNIT_EXPECT_FALSE(test, blit_result);
+   KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
 }
 
 static void drm_test_fb_xrgb_to_rgba5551(struct kunit *test)
@@ -745,6 +781,18 @@ static void drm_test_fb_xrgb_to_rgba5551(struct kunit 
*test)
drm_fb_xrgb_to_rgba5551(, dst_pitch, , , >clip);
buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / 
sizeof(__le16));
KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
+
+   buf = dst.vaddr; /* restore original value of buf */
+   memset(buf, 0, dst_size);
+
+   int blit_result = 0;
+
+   blit_result = drm_fb_blit(, dst_pitch, DRM_FORMAT_RGBA5551, , 
, >clip);
+
+   buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / 
sizeof(__le16));
+
+   KUNIT_EXPECT_FALSE(test, blit_result);
+   KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
 }
 
 static void drm_test_fb_xrgb_to_rgb888(struct kunit *test)
@@ -782,6 +830,16 @@ static void drm_test_fb_xrgb_to_rgb888(struct kunit 
*test)
 
drm_fb_xrgb_to_rgb888(, dst_pitch, , , >clip);
KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
+
+   buf = dst.vaddr; /* restore original value of buf */
+   memset(buf, 0, dst_size);
+
+   int blit_result = 0;
+
+   blit_result = drm_fb_blit(, dst_pitch, DRM_FORMAT_RGB888, , 
, >clip);
+
+   KUNIT_EXPECT_FALSE(test, blit_result);
+   KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
 }
 
 static void drm_test_fb_xrgb_to_argb(struct kunit *test)
@@ -816,6 +874,18 @@ static void drm_test_fb_xrgb_to_argb(struct kunit 
*test)
drm_fb_xrgb_to_argb(, dst_pitch, , , >clip);
buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / 
sizeof(u32));
KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
+
+   buf = dst.vaddr; /* restore original value of buf */
+   memset(buf, 0, dst_size);
+
+   int blit_result = 0;
+
+   blit_result = drm_fb_blit(, dst_pitch, DRM_FORMAT_ARGB, , 
, >clip);
+
+   buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / 
sizeof(u32));
+
+   KUNIT_EXPEC

[PATCH RESEND v3 0/2] Add KUnit tests for drm_fb_blit()

2023-09-18 Thread Arthur Grillo
This patchset tests the drm_fb_blit() function.

As this function can be used with already tested formats, the first
patch adds calls to drm_fb_blit() on the tests of supported formats.

Some supported formats were not yet covered by the existing tests
because they are only supported by drm_fb_blit(). The second patch
adds those format conversion tests.

Signed-off-by: Arthur Grillo 
---
Changes in v3:
- Fix memset sizes to avoid out-of-bound access
- Link to v2: 
https://lore.kernel.org/r/20230905-final-gsoc-v2-0-b52e8cb06...@riseup.net

Changes in v2:
- Split the patch into two (Maíra Canal)
- Link to v1: 
https://lore.kernel.org/r/20230901-final-gsoc-v1-1-e310c7685...@riseup.net

---
Arthur Grillo (2):
  drm/tests: Add calls to drm_fb_blit() on supported format conversion tests
  drm/tests: Add new format conversion tests to better cover drm_fb_blit()

 drivers/gpu/drm/tests/drm_format_helper_test.c | 285 +
 1 file changed, 285 insertions(+)
---
base-commit: 37454bcbb68601c326b58ac45f508067047d791f
change-id: 20230901-final-gsoc-395a84443c8f

Best regards,
-- 
Arthur Grillo 



Re: [PATCH v3 0/2] Add KUnit tests for drm_fb_blit()

2023-09-18 Thread Arthur Grillo



On 18/09/23 19:57, Arthur Grillo wrote:
> This patchset tests the drm_fb_blit() function.
> 
> As this function can be used with already tested formats, the first
> patch adds calls to drm_fb_blit() on the tests of supported formats.
> 
> Some supported formats were not yet covered by the existing tests
> because they are only supported by drm_fb_blit(). The second patch
> adds those format conversion tests.
> 
> Signed-off-by: Arthur Grillo 

Please ignore this patchset, One patch is missing. I will resend this
v3.

> ---
> Changes in v3:
> - Fix memset sizes to avoid out-of-bound access
> - Link to v2: 
> https://lore.kernel.org/r/20230905-final-gsoc-v2-0-b52e8cb06...@riseup.net
> 
> Changes in v2:
> - Split the patch into two (Maíra Canal)
> - Link to v1: 
> https://lore.kernel.org/r/20230901-final-gsoc-v1-1-e310c7685...@riseup.net
> 
> ---
> Arthur Grillo (2):
>   drm/tests: Add calls to drm_fb_blit() on supported format conversion 
> tests
>   drm/tests: Add new format conversion tests to better cover drm_fb_blit()
> 
>  drivers/gpu/drm/tests/drm_format_helper_test.c | 285 
> +
>  1 file changed, 285 insertions(+)
> ---
> base-commit: 37454bcbb68601c326b58ac45f508067047d791f
> change-id: 20230901-final-gsoc-395a84443c8f
> 
> Best regards,


[PATCH v3 1/2] drm/tests: Add calls to drm_fb_blit() on supported format conversion tests

2023-09-18 Thread Arthur Grillo
Add a call to drm_fb_blit() on existing format conversion tests that
has support.

Signed-off-by: Arthur Grillo 
---
 drivers/gpu/drm/tests/drm_format_helper_test.c | 143 +
 1 file changed, 143 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c 
b/drivers/gpu/drm/tests/drm_format_helper_test.c
index 1a6bd291345d..9cad723ada9d 100644
--- a/drivers/gpu/drm/tests/drm_format_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
@@ -643,6 +643,18 @@ static void drm_test_fb_xrgb_to_rgb565(struct kunit 
*test)
drm_fb_xrgb_to_rgb565(, >dst_pitch, , , 
>clip, true);
buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / 
sizeof(__le16));
KUNIT_EXPECT_MEMEQ(test, buf, result->expected_swab, dst_size);
+
+   buf = dst.vaddr;
+   memset(buf, 0, dst_size);
+
+   int blit_result = 0;
+
+   blit_result = drm_fb_blit(, dst_pitch, DRM_FORMAT_RGB565, , 
, >clip);
+
+   buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / 
sizeof(__le16));
+
+   KUNIT_EXPECT_FALSE(test, blit_result);
+   KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
 }
 
 static void drm_test_fb_xrgb_to_xrgb1555(struct kunit *test)
@@ -677,6 +689,18 @@ static void drm_test_fb_xrgb_to_xrgb1555(struct kunit 
*test)
drm_fb_xrgb_to_xrgb1555(, dst_pitch, , , >clip);
buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / 
sizeof(__le16));
KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
+
+   buf = dst.vaddr; /* restore original value of buf */
+   memset(buf, 0, dst_size);
+
+   int blit_result = 0;
+
+   blit_result = drm_fb_blit(, dst_pitch, DRM_FORMAT_XRGB1555, , 
, >clip);
+
+   buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / 
sizeof(__le16));
+
+   KUNIT_EXPECT_FALSE(test, blit_result);
+   KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
 }
 
 static void drm_test_fb_xrgb_to_argb1555(struct kunit *test)
@@ -711,6 +735,18 @@ static void drm_test_fb_xrgb_to_argb1555(struct kunit 
*test)
drm_fb_xrgb_to_argb1555(, dst_pitch, , , >clip);
buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / 
sizeof(__le16));
KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
+
+   buf = dst.vaddr; /* restore original value of buf */
+   memset(buf, 0, dst_size);
+
+   int blit_result = 0;
+
+   blit_result = drm_fb_blit(, dst_pitch, DRM_FORMAT_ARGB1555, , 
, >clip);
+
+   buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / 
sizeof(__le16));
+
+   KUNIT_EXPECT_FALSE(test, blit_result);
+   KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
 }
 
 static void drm_test_fb_xrgb_to_rgba5551(struct kunit *test)
@@ -745,6 +781,18 @@ static void drm_test_fb_xrgb_to_rgba5551(struct kunit 
*test)
drm_fb_xrgb_to_rgba5551(, dst_pitch, , , >clip);
buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / 
sizeof(__le16));
KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
+
+   buf = dst.vaddr; /* restore original value of buf */
+   memset(buf, 0, dst_size);
+
+   int blit_result = 0;
+
+   blit_result = drm_fb_blit(, dst_pitch, DRM_FORMAT_RGBA5551, , 
, >clip);
+
+   buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / 
sizeof(__le16));
+
+   KUNIT_EXPECT_FALSE(test, blit_result);
+   KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
 }
 
 static void drm_test_fb_xrgb_to_rgb888(struct kunit *test)
@@ -782,6 +830,16 @@ static void drm_test_fb_xrgb_to_rgb888(struct kunit 
*test)
 
drm_fb_xrgb_to_rgb888(, dst_pitch, , , >clip);
KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
+
+   buf = dst.vaddr; /* restore original value of buf */
+   memset(buf, 0, dst_size);
+
+   int blit_result = 0;
+
+   blit_result = drm_fb_blit(, dst_pitch, DRM_FORMAT_RGB888, , 
, >clip);
+
+   KUNIT_EXPECT_FALSE(test, blit_result);
+   KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
 }
 
 static void drm_test_fb_xrgb_to_argb(struct kunit *test)
@@ -816,6 +874,18 @@ static void drm_test_fb_xrgb_to_argb(struct kunit 
*test)
drm_fb_xrgb_to_argb(, dst_pitch, , , >clip);
buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / 
sizeof(u32));
KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
+
+   buf = dst.vaddr; /* restore original value of buf */
+   memset(buf, 0, dst_size);
+
+   int blit_result = 0;
+
+   blit_result = drm_fb_blit(, dst_pitch, DRM_FORMAT_ARGB, , 
, >clip);
+
+   buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / 
sizeof(u32));
+
+   KUNIT_EXPECT_FALSE(test, blit_r

[PATCH v3 0/2] Add KUnit tests for drm_fb_blit()

2023-09-18 Thread Arthur Grillo
This patchset tests the drm_fb_blit() function.

As this function can be used with already tested formats, the first
patch adds calls to drm_fb_blit() on the tests of supported formats.

Some supported formats were not yet covered by the existing tests
because they are only supported by drm_fb_blit(). The second patch
adds those format conversion tests.

Signed-off-by: Arthur Grillo 
---
Changes in v3:
- Fix memset sizes to avoid out-of-bound access
- Link to v2: 
https://lore.kernel.org/r/20230905-final-gsoc-v2-0-b52e8cb06...@riseup.net

Changes in v2:
- Split the patch into two (Maíra Canal)
- Link to v1: 
https://lore.kernel.org/r/20230901-final-gsoc-v1-1-e310c7685...@riseup.net

---
Arthur Grillo (2):
  drm/tests: Add calls to drm_fb_blit() on supported format conversion tests
  drm/tests: Add new format conversion tests to better cover drm_fb_blit()

 drivers/gpu/drm/tests/drm_format_helper_test.c | 285 +
 1 file changed, 285 insertions(+)
---
base-commit: 37454bcbb68601c326b58ac45f508067047d791f
change-id: 20230901-final-gsoc-395a84443c8f

Best regards,
-- 
Arthur Grillo 



[PATCH v2 2/2] drm/tests: Add new format conversion tests to better cover drm_fb_blit()

2023-09-05 Thread Arthur Grillo
To fully cover drm_fb_blit(), add format conversion tests that are only
supported through drm_fb_blit().

Signed-off-by: Arthur Grillo 
---
 drivers/gpu/drm/tests/drm_format_helper_test.c | 142 +
 1 file changed, 142 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c 
b/drivers/gpu/drm/tests/drm_format_helper_test.c
index b888f7334510..889287245b1e 100644
--- a/drivers/gpu/drm/tests/drm_format_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
@@ -81,6 +81,16 @@ struct fb_swab_result {
const u32 expected[TEST_BUF_SIZE];
 };
 
+struct convert_to_xbgr_result {
+   unsigned int dst_pitch;
+   const u32 expected[TEST_BUF_SIZE];
+};
+
+struct convert_to_abgr_result {
+   unsigned int dst_pitch;
+   const u32 expected[TEST_BUF_SIZE];
+};
+
 struct convert_xrgb_case {
const char *name;
unsigned int pitch;
@@ -98,6 +108,8 @@ struct convert_xrgb_case {
struct convert_to_argb2101010_result argb2101010_result;
struct convert_to_mono_result mono_result;
struct fb_swab_result swab_result;
+   struct convert_to_xbgr_result xbgr_result;
+   struct convert_to_abgr_result abgr_result;
 };
 
 static struct convert_xrgb_case convert_xrgb_cases[] = {
@@ -155,6 +167,14 @@ static struct convert_xrgb_case 
convert_xrgb_cases[] = {
.dst_pitch =  TEST_USE_DEFAULT_PITCH,
.expected = { 0xFF01 },
},
+   .xbgr_result = {
+   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
+   .expected = { 0x01FF },
+   },
+   .abgr_result = {
+   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
+   .expected = { 0xFFFF },
+   },
},
{
.name = "single_pixel_clip_rectangle",
@@ -213,6 +233,14 @@ static struct convert_xrgb_case 
convert_xrgb_cases[] = {
.dst_pitch =  TEST_USE_DEFAULT_PITCH,
.expected = { 0xFF10 },
},
+   .xbgr_result = {
+   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
+   .expected = { 0x10FF },
+   },
+   .abgr_result = {
+   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
+   .expected = { 0xFFFF },
+   },
},
{
/* Well known colors: White, black, red, green, blue, magenta,
@@ -343,6 +371,24 @@ static struct convert_xrgb_case 
convert_xrgb_cases[] = {
0x0077, 0x0088,
},
},
+   .xbgr_result = {
+   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
+   .expected = {
+   0x11FF, 0x2200,
+   0x33FF, 0x4400FF00,
+   0x55FF, 0x66FF00FF,
+   0x7700, 0x8800,
+   },
+   },
+   .abgr_result = {
+   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
+   .expected = {
+   0x, 0xFF00,
+   0xFFFF, 0xFF00FF00,
+   0x, 0x00FF,
+   0xFF00, 0xFF00,
+   },
+   },
},
{
/* Randomly picked colors. Full buffer within the clip area. */
@@ -458,6 +504,22 @@ static struct convert_xrgb_case 
convert_xrgb_cases[] = {
0x0303A8C2, 0x73F06CD2, 0x9C440EA3, 0x, 
0x,
},
},
+   .xbgr_result = {
+   .dst_pitch =  20,
+   .expected = {
+   0xA19C440E, 0xB1054D11, 0xC103F3A8, 0x, 
0x,
+   0xD173F06C, 0xA29C440E, 0xB2054D11, 0x, 
0x,
+   0xC20303A8, 0xD273F06C, 0xA39C440E, 0x, 
0x,
+   },
+   },
+   .abgr_result = {
+   .dst_pitch =  20,
+   .expected = {
+   0xFF9C440E, 0xFF054D11, 0xFF03F3A8, 0x, 
0x,
+   0xFF73F06C, 0xFF9C440E, 0xFF054D11, 0x, 
0x,
+   0xFF0303A8, 0xFF73F06C, 0xFF9C440E, 0x, 
0x,
+   },
+   },
},
 };
 
@@ -1082,6 +1144,84 @@ static void drm_test_fb_swab(struct kunit *test)
KUNIT_EXPECT_MEMEQ(test, buf, result->expec

[PATCH v2 1/2] drm/tests: Add calls to drm_fb_blit() on supported format conversion tests

2023-09-05 Thread Arthur Grillo
Add a call to drm_fb_blit() on existing format conversion tests that
has support.

Signed-off-by: Arthur Grillo 
---
 drivers/gpu/drm/tests/drm_format_helper_test.c | 142 +
 1 file changed, 142 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c 
b/drivers/gpu/drm/tests/drm_format_helper_test.c
index 79bc9d4bbd71..b888f7334510 100644
--- a/drivers/gpu/drm/tests/drm_format_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
@@ -643,6 +643,18 @@ static void drm_test_fb_xrgb_to_rgb565(struct kunit 
*test)
drm_fb_xrgb_to_rgb565(, >dst_pitch, , , 
>clip, true);
buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / 
sizeof(__le16));
KUNIT_EXPECT_MEMEQ(test, buf, result->expected_swab, dst_size);
+
+   buf = dst.vaddr;
+   memset(buf, 0, TEST_BUF_SIZE);
+
+   int blit_result = 0;
+
+   blit_result = drm_fb_blit(, dst_pitch, DRM_FORMAT_RGB565, , 
, >clip);
+
+   buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / 
sizeof(__le16));
+
+   KUNIT_EXPECT_FALSE(test, blit_result);
+   KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
 }
 
 static void drm_test_fb_xrgb_to_xrgb1555(struct kunit *test)
@@ -677,6 +689,18 @@ static void drm_test_fb_xrgb_to_xrgb1555(struct kunit 
*test)
drm_fb_xrgb_to_xrgb1555(, dst_pitch, , , >clip);
buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / 
sizeof(__le16));
KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
+
+   buf = dst.vaddr; /* restore original value of buf */
+   memset(buf, 0, TEST_BUF_SIZE);
+
+   int blit_result = 0;
+
+   blit_result = drm_fb_blit(, dst_pitch, DRM_FORMAT_XRGB1555, , 
, >clip);
+
+   buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / 
sizeof(__le16));
+
+   KUNIT_EXPECT_FALSE(test, blit_result);
+   KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
 }
 
 static void drm_test_fb_xrgb_to_argb1555(struct kunit *test)
@@ -711,6 +735,18 @@ static void drm_test_fb_xrgb_to_argb1555(struct kunit 
*test)
drm_fb_xrgb_to_argb1555(, dst_pitch, , , >clip);
buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / 
sizeof(__le16));
KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
+
+   buf = dst.vaddr; /* restore original value of buf */
+   memset(buf, 0, TEST_BUF_SIZE);
+
+   int blit_result = 0;
+
+   blit_result = drm_fb_blit(, dst_pitch, DRM_FORMAT_ARGB1555, , 
, >clip);
+
+   buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / 
sizeof(__le16));
+
+   KUNIT_EXPECT_FALSE(test, blit_result);
+   KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
 }
 
 static void drm_test_fb_xrgb_to_rgba5551(struct kunit *test)
@@ -745,6 +781,18 @@ static void drm_test_fb_xrgb_to_rgba5551(struct kunit 
*test)
drm_fb_xrgb_to_rgba5551(, dst_pitch, , , >clip);
buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / 
sizeof(__le16));
KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
+
+   buf = dst.vaddr; /* restore original value of buf */
+   memset(buf, 0, TEST_BUF_SIZE);
+
+   int blit_result = 0;
+
+   blit_result = drm_fb_blit(, dst_pitch, DRM_FORMAT_RGBA5551, , 
, >clip);
+
+   buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / 
sizeof(__le16));
+
+   KUNIT_EXPECT_FALSE(test, blit_result);
+   KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
 }
 
 static void drm_test_fb_xrgb_to_rgb888(struct kunit *test)
@@ -782,6 +830,16 @@ static void drm_test_fb_xrgb_to_rgb888(struct kunit 
*test)
 
drm_fb_xrgb_to_rgb888(, dst_pitch, , , >clip);
KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
+
+   buf = dst.vaddr; /* restore original value of buf */
+   memset(buf, 0, TEST_BUF_SIZE);
+
+   int blit_result = 0;
+
+   blit_result = drm_fb_blit(, dst_pitch, DRM_FORMAT_RGB888, , 
, >clip);
+
+   KUNIT_EXPECT_FALSE(test, blit_result);
+   KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
 }
 
 static void drm_test_fb_xrgb_to_argb(struct kunit *test)
@@ -816,6 +874,18 @@ static void drm_test_fb_xrgb_to_argb(struct kunit 
*test)
drm_fb_xrgb_to_argb(, dst_pitch, , , >clip);
buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / 
sizeof(u32));
KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
+
+   buf = dst.vaddr; /* restore original value of buf */
+   memset(buf, 0, TEST_BUF_SIZE);
+
+   int blit_result = 0;
+
+   blit_result = drm_fb_blit(, dst_pitch, DRM_FORMAT_ARGB, , 
, >clip);
+
+   buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / 
sizeof(u32));
+
+   KUN

[PATCH v2 0/2] Add KUnit tests for drm_fb_blit()

2023-09-05 Thread Arthur Grillo
This patchset tests the drm_fb_blit() function.

As this function can be used with already tested formats, the first
patch adds calls to drm_fb_blit() on the tests of supported formats.

Some supported formats were not yet covered by the existing tests
because they are only supported by drm_fb_blit(). The second patch
adds those format conversion tests.

Signed-off-by: Arthur Grillo 
---
Changes in v2:
- Split the patch into two (Maíra Canal)
- Link to v1: 
https://lore.kernel.org/r/20230901-final-gsoc-v1-1-e310c7685...@riseup.net

---
Arthur Grillo (2):
  drm/tests: Add calls to drm_fb_blit() on supported format conversion tests
  drm/tests: Add new format conversion tests to better cover drm_fb_blit()

 drivers/gpu/drm/tests/drm_format_helper_test.c | 284 +
 1 file changed, 284 insertions(+)
---
base-commit: f45acf7acf75921c0409d452f0165f51a19a74fd
change-id: 20230901-final-gsoc-395a84443c8f

Best regards,
-- 
Arthur Grillo 



[PATCH] drm/tests: Zero initialize fourccs_out

2023-09-01 Thread Arthur Grillo
fourccs_out array is not initialized. As the
drm_fb_build_fourcc_list() doesn't necessarily change all the array,
and the test compares all of it, the comparison could fail if the
array is not initialized. Zero initialize the array to fix this.

Fixes: 371e0b186a13 ("drm/tests: Add KUnit tests for 
drm_fb_build_fourcc_list()")
Signed-off-by: Arthur Grillo 
---
 drivers/gpu/drm/tests/drm_format_helper_test.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c 
b/drivers/gpu/drm/tests/drm_format_helper_test.c
index 79bc9d4bbd71..1a6bd291345d 100644
--- a/drivers/gpu/drm/tests/drm_format_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
@@ -1165,7 +1165,7 @@ KUNIT_ARRAY_PARAM(fb_build_fourcc_list, 
fb_build_fourcc_list_cases, fb_build_fou
 static void drm_test_fb_build_fourcc_list(struct kunit *test)
 {
const struct fb_build_fourcc_list_case *params = test->param_value;
-   u32 fourccs_out[TEST_BUF_SIZE];
+   u32 fourccs_out[TEST_BUF_SIZE] = {0};
size_t nfourccs_out;
struct drm_device *drm;
struct device *dev;

---
base-commit: 8e455145d8f163aefa6b9cc29478e0a9f82276e6
change-id: 20230901-zero-init-fourcc-list-test-2c934b6b7eb8

Best regards,
-- 
Arthur Grillo 



[PATCH] drm/debugfs: Add inline to drm_debugfs_dev_init() to suppres -Wunused-function

2023-09-01 Thread Arthur Grillo
When CONFIG_DEBUG_FS is not set -Wunused-function warnings appear,
make the static function inline to suppress that.

Reported-by: kernel test robot 
Closes: 
https://lore.kernel.org/oe-kbuild-all/202309012114.t8vlfaf8-...@intel.com/
Closes: 
https://lore.kernel.org/oe-kbuild-all/202309012131.feakbzej-...@intel.com/
Signed-off-by: Arthur Grillo 
---
 include/drm/drm_drv.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index 9850fe73b739..e2640dc64e08 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -584,7 +584,7 @@ static inline bool drm_firmware_drivers_only(void)
 #if defined(CONFIG_DEBUG_FS)
 void drm_debugfs_dev_init(struct drm_device *dev, struct dentry *root);
 #else
-static void drm_debugfs_dev_init(struct drm_device *dev, struct dentry *root)
+static inline void drm_debugfs_dev_init(struct drm_device *dev, struct dentry 
*root)
 {
 }
 #endif

---
base-commit: 8e455145d8f163aefa6b9cc29478e0a9f82276e6
change-id: 20230901-debugfs-fix-unused-function-warning-9ebbecbd6a5a

Best regards,
-- 
Arthur Grillo 



[PATCH] drm/tests: Add KUnit tests for drm_fb_blit()

2023-09-01 Thread Arthur Grillo
Insert parameterized test for the drm_fb_blit() to ensure correctness
and prevent future regressions.

The test is done by adding a call to drm_fb_blit() on every format
that has support. Also, to fully test the function, add new format
conversion tests.

Signed-off-by: Arthur Grillo 
---
 drivers/gpu/drm/tests/drm_format_helper_test.c | 284 +
 1 file changed, 284 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c 
b/drivers/gpu/drm/tests/drm_format_helper_test.c
index 79bc9d4bbd71..889287245b1e 100644
--- a/drivers/gpu/drm/tests/drm_format_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
@@ -81,6 +81,16 @@ struct fb_swab_result {
const u32 expected[TEST_BUF_SIZE];
 };
 
+struct convert_to_xbgr_result {
+   unsigned int dst_pitch;
+   const u32 expected[TEST_BUF_SIZE];
+};
+
+struct convert_to_abgr_result {
+   unsigned int dst_pitch;
+   const u32 expected[TEST_BUF_SIZE];
+};
+
 struct convert_xrgb_case {
const char *name;
unsigned int pitch;
@@ -98,6 +108,8 @@ struct convert_xrgb_case {
struct convert_to_argb2101010_result argb2101010_result;
struct convert_to_mono_result mono_result;
struct fb_swab_result swab_result;
+   struct convert_to_xbgr_result xbgr_result;
+   struct convert_to_abgr_result abgr_result;
 };
 
 static struct convert_xrgb_case convert_xrgb_cases[] = {
@@ -155,6 +167,14 @@ static struct convert_xrgb_case 
convert_xrgb_cases[] = {
.dst_pitch =  TEST_USE_DEFAULT_PITCH,
.expected = { 0xFF01 },
},
+   .xbgr_result = {
+   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
+   .expected = { 0x01FF },
+   },
+   .abgr_result = {
+   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
+   .expected = { 0xFFFF },
+   },
},
{
.name = "single_pixel_clip_rectangle",
@@ -213,6 +233,14 @@ static struct convert_xrgb_case 
convert_xrgb_cases[] = {
.dst_pitch =  TEST_USE_DEFAULT_PITCH,
.expected = { 0xFF10 },
},
+   .xbgr_result = {
+   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
+   .expected = { 0x10FF },
+   },
+   .abgr_result = {
+   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
+   .expected = { 0xFFFF },
+   },
},
{
/* Well known colors: White, black, red, green, blue, magenta,
@@ -343,6 +371,24 @@ static struct convert_xrgb_case 
convert_xrgb_cases[] = {
0x0077, 0x0088,
},
},
+   .xbgr_result = {
+   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
+   .expected = {
+   0x11FF, 0x2200,
+   0x33FF, 0x4400FF00,
+   0x55FF, 0x66FF00FF,
+   0x7700, 0x8800,
+   },
+   },
+   .abgr_result = {
+   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
+   .expected = {
+   0x, 0xFF00,
+   0xFFFF, 0xFF00FF00,
+   0x, 0x00FF,
+   0xFF00, 0xFF00,
+   },
+   },
},
{
/* Randomly picked colors. Full buffer within the clip area. */
@@ -458,6 +504,22 @@ static struct convert_xrgb_case 
convert_xrgb_cases[] = {
0x0303A8C2, 0x73F06CD2, 0x9C440EA3, 0x, 
0x,
},
},
+   .xbgr_result = {
+   .dst_pitch =  20,
+   .expected = {
+   0xA19C440E, 0xB1054D11, 0xC103F3A8, 0x, 
0x,
+   0xD173F06C, 0xA29C440E, 0xB2054D11, 0x, 
0x,
+   0xC20303A8, 0xD273F06C, 0xA39C440E, 0x, 
0x,
+   },
+   },
+   .abgr_result = {
+   .dst_pitch =  20,
+   .expected = {
+   0xFF9C440E, 0xFF054D11, 0xFF03F3A8, 0x, 
0x,
+   0xFF73F06C, 0xFF9C440E, 0xFF054D11, 0x, 
0x,
+   0xFF0303A8, 0xFF73F06C, 0xFF9C440E, 0x, 

[PATCH v3 6/6] drm/tests: Add KUnit tests for drm_fb_memcpy()

2023-08-14 Thread Arthur Grillo
Insert parameterized test for the drm_fb_memcpy() to ensure correctness
and prevent future regressions. The test case can accept different
formats.

Signed-off-by: Arthur Grillo 
---
 drivers/gpu/drm/tests/drm_format_helper_test.c | 362 +
 1 file changed, 362 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c 
b/drivers/gpu/drm/tests/drm_format_helper_test.c
index 8ac7a667f0d9..0cbca4ccabac 100644
--- a/drivers/gpu/drm/tests/drm_format_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
@@ -1184,6 +1184,367 @@ static void drm_test_fb_build_fourcc_list(struct kunit 
*test)
KUNIT_EXPECT_MEMEQ(test, fourccs_out, params->expected, TEST_BUF_SIZE);
 }
 
+struct fb_memcpy_case {
+   const char *name;
+   u32 format;
+   struct drm_rect clip;
+   unsigned int src_pitches[DRM_FORMAT_MAX_PLANES];
+   const u32 src[DRM_FORMAT_MAX_PLANES][TEST_BUF_SIZE];
+   unsigned int dst_pitches[DRM_FORMAT_MAX_PLANES];
+   const u32 expected[DRM_FORMAT_MAX_PLANES][TEST_BUF_SIZE];
+};
+
+/* The `src` and `expected` buffers are u32 arrays. To deal with planes that
+ * have a cpp != 4 the values are stored together on the same u32 number in a
+ * way so the order in memory is correct in a little-endian machine.
+ *
+ * Because of that, on some occasions, parts of a u32 will not be part of the
+ * test, to make this explicit the 0xFF byte is used on those parts.
+ */
+
+static struct fb_memcpy_case fb_memcpy_cases[] = {
+   {
+   .name = "single_pixel_source_buffer",
+   .format = DRM_FORMAT_XRGB,
+   .clip = DRM_RECT_INIT(0, 0, 1, 1),
+   .src_pitches = { 1 * 4 },
+   .src = {{ 0x01020304 }},
+   .dst_pitches = { TEST_USE_DEFAULT_PITCH },
+   .expected = {{ 0x01020304 }},
+   },
+   {
+   .name = "single_pixel_source_buffer",
+   .format = DRM_FORMAT_XRGB_A8,
+   .clip = DRM_RECT_INIT(0, 0, 1, 1),
+   .src_pitches = { 1 * 4, 1 },
+   .src = {
+   { 0x01020304 },
+   { 0xFF01 },
+   },
+   .dst_pitches = { TEST_USE_DEFAULT_PITCH },
+   .expected = {
+   { 0x01020304 },
+   { 0x0001 },
+   },
+   },
+   {
+   .name = "single_pixel_source_buffer",
+   .format = DRM_FORMAT_YUV444,
+   .clip = DRM_RECT_INIT(0, 0, 1, 1),
+   .src_pitches = { 1, 1, 1 },
+   .src = {
+   { 0xFF01 },
+   { 0xFF01 },
+   { 0xFF01 },
+   },
+   .dst_pitches = { TEST_USE_DEFAULT_PITCH },
+   .expected = {
+   { 0x0001 },
+   { 0x0001 },
+   { 0x0001 },
+   },
+   },
+   {
+   .name = "single_pixel_clip_rectangle",
+   .format = DRM_FORMAT_XBGR,
+   .clip = DRM_RECT_INIT(1, 1, 1, 1),
+   .src_pitches = { 2 * 4 },
+   .src = {
+   {
+   0x, 0x,
+   0x, 0x01020304,
+   },
+   },
+   .dst_pitches = { TEST_USE_DEFAULT_PITCH },
+   .expected = {
+   { 0x01020304 },
+   },
+   },
+   {
+   .name = "single_pixel_clip_rectangle",
+   .format = DRM_FORMAT_XRGB_A8,
+   .clip = DRM_RECT_INIT(1, 1, 1, 1),
+   .src_pitches = { 2 * 4, 2 * 1 },
+   .src = {
+   {
+   0x, 0x,
+   0x, 0x01020304,
+   },
+   { 0x0100 },
+   },
+   .dst_pitches = { TEST_USE_DEFAULT_PITCH },
+   .expected = {
+   { 0x01020304 },
+   { 0x0001 },
+   },
+   },
+   {
+   .name = "single_pixel_clip_rectangle",
+   .format = DRM_FORMAT_YUV444,
+   .clip = DRM_RECT_INIT(1, 1, 1, 1),
+   .src_pitches = { 2 * 1, 2 * 1, 2 * 1 },
+   .src = {
+   { 0x0100 },
+   { 0x0100 },
+   { 0x0100 },
+   },
+   .dst_pitches = { TEST_USE_DEFAULT_PITCH },
+   .expected = {
+   { 0x0001 },
+   { 0x0001 },
+   { 0x0001 },
+   },
+   },
+   {
+   .name = "well_known_colors&qu

[PATCH v3 5/6] drm/tests: Add multi-plane support to conversion_buf_size()

2023-08-14 Thread Arthur Grillo
The drm_fb_memcpy() supports multi-plane formats. To fully test it in
the future, add multi-plane support to the conversion_buf_size() helper.

Signed-off-by: Arthur Grillo 
Reviewed-by: Maíra Canal 
---
 drivers/gpu/drm/tests/drm_format_helper_test.c | 28 +-
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c 
b/drivers/gpu/drm/tests/drm_format_helper_test.c
index eca6b3415a42..8ac7a667f0d9 100644
--- a/drivers/gpu/drm/tests/drm_format_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
@@ -472,7 +472,7 @@ static struct convert_xrgb_case 
convert_xrgb_cases[] = {
  * The size of the destination buffer or negative value on error.
  */
 static size_t conversion_buf_size(u32 dst_format, unsigned int dst_pitch,
- const struct drm_rect *clip)
+ const struct drm_rect *clip, int plane)
 {
const struct drm_format_info *dst_fi = drm_format_info(dst_format);
 
@@ -480,7 +480,7 @@ static size_t conversion_buf_size(u32 dst_format, unsigned 
int dst_pitch,
return -EINVAL;
 
if (!dst_pitch)
-   dst_pitch = drm_format_info_min_pitch(dst_fi, 0, 
drm_rect_width(clip));
+   dst_pitch = drm_format_info_min_pitch(dst_fi, plane, 
drm_rect_width(clip));
 
return dst_pitch * drm_rect_height(clip);
 }
@@ -554,7 +554,7 @@ static void drm_test_fb_xrgb_to_gray8(struct kunit 
*test)
};
 
dst_size = conversion_buf_size(DRM_FORMAT_R8, result->dst_pitch,
-  >clip);
+  >clip, 0);
KUNIT_ASSERT_GT(test, dst_size, 0);
 
buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
@@ -588,7 +588,7 @@ static void drm_test_fb_xrgb_to_rgb332(struct kunit 
*test)
};
 
dst_size = conversion_buf_size(DRM_FORMAT_RGB332, result->dst_pitch,
-  >clip);
+  >clip, 0);
KUNIT_ASSERT_GT(test, dst_size, 0);
 
buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
@@ -621,7 +621,7 @@ static void drm_test_fb_xrgb_to_rgb565(struct kunit 
*test)
};
 
dst_size = conversion_buf_size(DRM_FORMAT_RGB565, result->dst_pitch,
-  >clip);
+  >clip, 0);
KUNIT_ASSERT_GT(test, dst_size, 0);
 
buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
@@ -660,7 +660,7 @@ static void drm_test_fb_xrgb_to_xrgb1555(struct kunit 
*test)
};
 
dst_size = conversion_buf_size(DRM_FORMAT_XRGB1555, result->dst_pitch,
-  >clip);
+  >clip, 0);
KUNIT_ASSERT_GT(test, dst_size, 0);
 
buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
@@ -694,7 +694,7 @@ static void drm_test_fb_xrgb_to_argb1555(struct kunit 
*test)
};
 
dst_size = conversion_buf_size(DRM_FORMAT_ARGB1555, result->dst_pitch,
-  >clip);
+  >clip, 0);
KUNIT_ASSERT_GT(test, dst_size, 0);
 
buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
@@ -728,7 +728,7 @@ static void drm_test_fb_xrgb_to_rgba5551(struct kunit 
*test)
};
 
dst_size = conversion_buf_size(DRM_FORMAT_RGBA5551, result->dst_pitch,
-  >clip);
+  >clip, 0);
KUNIT_ASSERT_GT(test, dst_size, 0);
 
buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
@@ -762,7 +762,7 @@ static void drm_test_fb_xrgb_to_rgb888(struct kunit 
*test)
};
 
dst_size = conversion_buf_size(DRM_FORMAT_RGB888, result->dst_pitch,
-  >clip);
+  >clip, 0);
KUNIT_ASSERT_GT(test, dst_size, 0);
 
buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
@@ -799,7 +799,7 @@ static void drm_test_fb_xrgb_to_argb(struct kunit 
*test)
};
 
dst_size = conversion_buf_size(DRM_FORMAT_ARGB,
-  result->dst_pitch, >clip);
+  result->dst_pitch, >clip, 0);
KUNIT_ASSERT_GT(test, dst_size, 0);
 
buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
@@ -833,7 +833,7 @@ static void drm_test_fb_xrgb_to_xrgb2101010(struct 
kunit *test)
};
 
dst_size = conversion_buf_size(DRM_FORMAT_XRGB2101010,
-  result->dst_pitch, >clip);
+  result->dst_pitch, >clip, 0);
KUNIT_ASSERT_GT(test, dst_size, 0);
 
buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
@@ -867,7 +867,7 @@ static void drm_test_fb_xrgb_

[PATCH v3 4/6] drm/tests: Add KUnit tests for drm_fb_build_fourcc_list()

2023-08-14 Thread Arthur Grillo
Insert parameterized test for the drm_fb_build_fourcc_list() to ensure
correctness and prevent future regressions.

Signed-off-by: Arthur Grillo 
---
 drivers/gpu/drm/tests/drm_format_helper_test.c | 144 +
 1 file changed, 144 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c 
b/drivers/gpu/drm/tests/drm_format_helper_test.c
index 7f24da0b1e00..eca6b3415a42 100644
--- a/drivers/gpu/drm/tests/drm_format_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
@@ -3,11 +3,13 @@
 #include 
 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1041,6 +1043,147 @@ static void drm_test_fb_clip_offset(struct kunit *test)
KUNIT_EXPECT_EQ(test, offset, params->expected_offset);
 }
 
+struct fb_build_fourcc_list_case {
+   const char *name;
+   u32 native_fourccs[TEST_BUF_SIZE];
+   size_t native_fourccs_size;
+   u32 expected[TEST_BUF_SIZE];
+   size_t expected_fourccs_size;
+};
+
+static struct fb_build_fourcc_list_case fb_build_fourcc_list_cases[] = {
+   {
+   .name = "no native formats",
+   .native_fourccs = { },
+   .native_fourccs_size = 0,
+   .expected = { DRM_FORMAT_XRGB },
+   .expected_fourccs_size = 1,
+   },
+   {
+   .name = "XRGB as native format",
+   .native_fourccs = { DRM_FORMAT_XRGB },
+   .native_fourccs_size = 1,
+   .expected = { DRM_FORMAT_XRGB },
+   .expected_fourccs_size = 1,
+   },
+   {
+   .name = "remove duplicates",
+   .native_fourccs = {
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_XRGB,
+   },
+   .native_fourccs_size = 11,
+   .expected = {
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_RGB565,
+   },
+   .expected_fourccs_size = 3,
+   },
+   {
+   .name = "convert alpha formats",
+   .native_fourccs = {
+   DRM_FORMAT_ARGB1555,
+   DRM_FORMAT_ABGR1555,
+   DRM_FORMAT_RGBA5551,
+   DRM_FORMAT_BGRA5551,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_ABGR,
+   DRM_FORMAT_RGBA,
+   DRM_FORMAT_BGRA,
+   DRM_FORMAT_ARGB2101010,
+   DRM_FORMAT_ABGR2101010,
+   DRM_FORMAT_RGBA1010102,
+   DRM_FORMAT_BGRA1010102,
+   },
+   .native_fourccs_size = 12,
+   .expected = {
+   DRM_FORMAT_XRGB1555,
+   DRM_FORMAT_XBGR1555,
+   DRM_FORMAT_RGBX5551,
+   DRM_FORMAT_BGRX5551,
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_XBGR,
+   DRM_FORMAT_RGBX,
+   DRM_FORMAT_BGRX,
+   DRM_FORMAT_XRGB2101010,
+   DRM_FORMAT_XBGR2101010,
+   DRM_FORMAT_RGBX1010102,
+   DRM_FORMAT_BGRX1010102,
+   },
+   .expected_fourccs_size = 12,
+   },
+   {
+   .name = "random formats",
+   .native_fourccs = {
+   DRM_FORMAT_Y212,
+   DRM_FORMAT_ARGB1555,
+   DRM_FORMAT_ABGR16161616F,
+   DRM_FORMAT_C8,
+   DRM_FORMAT_BGR888,
+   DRM_FORMAT_XRGB1555,
+   DRM_FORMAT_RGBA5551,
+   DRM_FORMAT_BGR565_A8,
+   DRM_FORMAT_R10,
+   DRM_FORMAT_XYUV,
+   },
+   .native_fourccs_size = 10,
+   .expected = {
+   DRM_FORMAT_Y212,
+   DRM_FORMAT_XRGB1555,
+   DRM_FORMAT_ABGR16161616F,
+   DRM_FORMAT_C8,
+   DRM_FORMAT_BGR888,
+   DRM_FORMAT_RGBX5551,
+   DRM_FORMAT_BGR565_A8,
+   DRM_FO

[PATCH v3 3/6] drm/tests: Add KUnit tests for drm_fb_clip_offset()

2023-08-14 Thread Arthur Grillo
Insert parameterized test for the drm_fb_clip_offset() to ensure
correctness and prevent future regressions.

Signed-off-by: Arthur Grillo 
Reviewed-by: Maíra Canal 
---
 drivers/gpu/drm/tests/drm_format_helper_test.c | 91 ++
 1 file changed, 91 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c 
b/drivers/gpu/drm/tests/drm_format_helper_test.c
index d10e18fcb994..7f24da0b1e00 100644
--- a/drivers/gpu/drm/tests/drm_format_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
@@ -951,6 +951,96 @@ static void drm_test_fb_swab(struct kunit *test)
KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
 }
 
+struct clip_offset_case {
+   const char *name;
+   unsigned int pitch;
+   u32 format;
+   struct drm_rect clip;
+   unsigned int expected_offset;
+};
+
+static struct clip_offset_case clip_offset_cases[] = {
+   {
+   .name = "pass through",
+   .pitch = TEST_USE_DEFAULT_PITCH,
+   .format = DRM_FORMAT_XRGB,
+   .clip = DRM_RECT_INIT(0, 0, 3, 3),
+   .expected_offset = 0
+   },
+   {
+   .name = "horizontal offset",
+   .pitch = TEST_USE_DEFAULT_PITCH,
+   .format = DRM_FORMAT_XRGB,
+   .clip = DRM_RECT_INIT(1, 0, 3, 3),
+   .expected_offset = 4,
+   },
+   {
+   .name = "vertical offset",
+   .pitch = TEST_USE_DEFAULT_PITCH,
+   .format = DRM_FORMAT_XRGB,
+   .clip = DRM_RECT_INIT(0, 1, 3, 3),
+   .expected_offset = 12,
+   },
+   {
+   .name = "horizontal and vertical offset",
+   .pitch = TEST_USE_DEFAULT_PITCH,
+   .format = DRM_FORMAT_XRGB,
+   .clip = DRM_RECT_INIT(1, 1, 3, 3),
+   .expected_offset = 16,
+   },
+   {
+   .name = "horizontal offset (custom pitch)",
+   .pitch = 20,
+   .format = DRM_FORMAT_XRGB,
+   .clip = DRM_RECT_INIT(1, 0, 3, 3),
+   .expected_offset = 4,
+   },
+   {
+   .name = "vertical offset (custom pitch)",
+   .pitch = 20,
+   .format = DRM_FORMAT_XRGB,
+   .clip = DRM_RECT_INIT(0, 1, 3, 3),
+   .expected_offset = 20,
+   },
+   {
+   .name = "horizontal and vertical offset (custom pitch)",
+   .pitch = 20,
+   .format = DRM_FORMAT_XRGB,
+   .clip = DRM_RECT_INIT(1, 1, 3, 3),
+   .expected_offset = 24,
+   },
+};
+
+static void clip_offset_case_desc(struct clip_offset_case *t, char *desc)
+{
+   strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
+}
+
+KUNIT_ARRAY_PARAM(clip_offset, clip_offset_cases, clip_offset_case_desc);
+
+static void drm_test_fb_clip_offset(struct kunit *test)
+{
+   const struct clip_offset_case *params = test->param_value;
+   const struct drm_format_info *format_info = 
drm_format_info(params->format);
+
+   unsigned int offset;
+   unsigned int pitch = params->pitch;
+
+   if (pitch == TEST_USE_DEFAULT_PITCH)
+   pitch = drm_format_info_min_pitch(format_info, 0,
+ 
drm_rect_width(>clip));
+
+   /*
+* Assure that the pitch is not zero, because this will inevitable 
cause the
+* wrong expected result
+*/
+   KUNIT_ASSERT_NE(test, pitch, 0);
+
+   offset = drm_fb_clip_offset(pitch, format_info, >clip);
+
+   KUNIT_EXPECT_EQ(test, offset, params->expected_offset);
+}
+
 static struct kunit_case drm_format_helper_test_cases[] = {
KUNIT_CASE_PARAM(drm_test_fb_xrgb_to_gray8, 
convert_xrgb_gen_params),
KUNIT_CASE_PARAM(drm_test_fb_xrgb_to_rgb332, 
convert_xrgb_gen_params),
@@ -964,6 +1054,7 @@ static struct kunit_case drm_format_helper_test_cases[] = {
KUNIT_CASE_PARAM(drm_test_fb_xrgb_to_argb2101010, 
convert_xrgb_gen_params),
KUNIT_CASE_PARAM(drm_test_fb_xrgb_to_mono, 
convert_xrgb_gen_params),
KUNIT_CASE_PARAM(drm_test_fb_swab, convert_xrgb_gen_params),
+   KUNIT_CASE_PARAM(drm_test_fb_clip_offset, clip_offset_gen_params),
{}
 };
 

-- 
2.41.0



[PATCH v3 2/6] drm/tests: Add KUnit tests for drm_fb_swab()

2023-08-14 Thread Arthur Grillo
Insert parameterized test for the drm_fb_swab() to ensure correctness
and prevent future regressions.

Each expected color has it bytes reversed in order, so xrgb would be
bgrx.

Signed-off-by: Arthur Grillo 
Reviewed-by: Maíra Canal 
---
 drivers/gpu/drm/tests/drm_format_helper_test.c | 66 ++
 1 file changed, 66 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c 
b/drivers/gpu/drm/tests/drm_format_helper_test.c
index 938d4fdb4291..d10e18fcb994 100644
--- a/drivers/gpu/drm/tests/drm_format_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
@@ -74,6 +74,11 @@ struct convert_to_mono_result {
const u8 expected[TEST_BUF_SIZE];
 };
 
+struct fb_swab_result {
+   unsigned int dst_pitch;
+   const u32 expected[TEST_BUF_SIZE];
+};
+
 struct convert_xrgb_case {
const char *name;
unsigned int pitch;
@@ -90,6 +95,7 @@ struct convert_xrgb_case {
struct convert_to_xrgb2101010_result xrgb2101010_result;
struct convert_to_argb2101010_result argb2101010_result;
struct convert_to_mono_result mono_result;
+   struct fb_swab_result swab_result;
 };
 
 static struct convert_xrgb_case convert_xrgb_cases[] = {
@@ -143,6 +149,10 @@ static struct convert_xrgb_case 
convert_xrgb_cases[] = {
.dst_pitch =  TEST_USE_DEFAULT_PITCH,
.expected = { 0b0 },
},
+   .swab_result = {
+   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
+   .expected = { 0xFF01 },
+   },
},
{
.name = "single_pixel_clip_rectangle",
@@ -197,6 +207,10 @@ static struct convert_xrgb_case 
convert_xrgb_cases[] = {
.dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0b0 },
},
+   .swab_result = {
+   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
+   .expected = { 0xFF10 },
+   },
},
{
/* Well known colors: White, black, red, green, blue, magenta,
@@ -318,6 +332,15 @@ static struct convert_xrgb_case 
convert_xrgb_cases[] = {
0b11,
},
},
+   .swab_result = {
+   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
+   .expected = {
+   0xFF11, 0x0022,
+   0xFF33, 0x00FF0044,
+   0xFF55, 0xFF00FF66,
+   0x0077, 0x0088,
+   },
+   },
},
{
/* Randomly picked colors. Full buffer within the clip area. */
@@ -425,6 +448,14 @@ static struct convert_xrgb_case 
convert_xrgb_cases[] = {
0b010, 0b000,
},
},
+   .swab_result = {
+   .dst_pitch =  20,
+   .expected = {
+   0x9C440EA1, 0x054D11B1, 0x03F3A8C1, 0x, 
0x,
+   0x73F06CD1, 0x9C440EA2, 0x054D11B2, 0x, 
0x,
+   0x0303A8C2, 0x73F06CD2, 0x9C440EA3, 0x, 
0x,
+   },
+   },
},
 };
 
@@ -886,6 +917,40 @@ static void drm_test_fb_xrgb_to_mono(struct kunit 
*test)
KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
 }
 
+static void drm_test_fb_swab(struct kunit *test)
+{
+   const struct convert_xrgb_case *params = test->param_value;
+   const struct fb_swab_result *result = >swab_result;
+   size_t dst_size;
+   u32 *buf = NULL;
+   __le32 *xrgb = NULL;
+   struct iosys_map dst, src;
+
+   struct drm_framebuffer fb = {
+   .format = drm_format_info(DRM_FORMAT_XRGB),
+   .pitches = { params->pitch, 0, 0 },
+   };
+
+   dst_size = conversion_buf_size(DRM_FORMAT_XRGB, result->dst_pitch, 
>clip);
+
+   KUNIT_ASSERT_GT(test, dst_size, 0);
+
+   buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
+   iosys_map_set_vaddr(, buf);
+
+   xrgb = cpubuf_to_le32(test, params->xrgb, TEST_BUF_SIZE);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb);
+   iosys_map_set_vaddr(, xrgb);
+
+   const unsigned int *dst_pitch = (result->dst_pitch == 
TEST_USE_DEFAULT_PITCH) ?
+   NULL : >dst_pitch;
+
+   drm_fb_swab(, dst_pitch, , , >clip, false);
+   buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / 
sizeof(u32));
+   KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
+}
+
 static struct kunit_case drm_format_helpe

[PATCH v3 1/6] drm/tests: Test default pitch fallback

2023-08-14 Thread Arthur Grillo
Test the default pitch fallback when NULL is passed as the dst_pitch on
the conversion procedures.

Reviewed-by: Maíra Canal 
Signed-off-by: Arthur Grillo 
---
 drivers/gpu/drm/tests/drm_format_helper_test.c | 126 -
 1 file changed, 81 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c 
b/drivers/gpu/drm/tests/drm_format_helper_test.c
index 474bb7a1c4ee..938d4fdb4291 100644
--- a/drivers/gpu/drm/tests/drm_format_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
@@ -16,6 +16,8 @@
 
 #define TEST_BUF_SIZE 50
 
+#define TEST_USE_DEFAULT_PITCH 0
+
 struct convert_to_gray8_result {
unsigned int dst_pitch;
const u8 expected[TEST_BUF_SIZE];
@@ -97,48 +99,48 @@ static struct convert_xrgb_case 
convert_xrgb_cases[] = {
.clip = DRM_RECT_INIT(0, 0, 1, 1),
.xrgb = { 0x01FF },
.gray8_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0x4C },
},
.rgb332_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0xE0 },
},
.rgb565_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0xF800 },
.expected_swab = { 0x00F8 },
},
.xrgb1555_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0x7C00 },
},
.argb1555_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0xFC00 },
},
.rgba5551_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0xF801 },
},
.rgb888_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0x00, 0x00, 0xFF },
},
.argb_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0x },
},
.xrgb2101010_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0x3FF0 },
},
.argb2101010_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0xFFF0 },
},
.mono_result = {
-   .dst_pitch = 0,
+   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
.expected = { 0b0 },
},
},
@@ -151,48 +153,48 @@ static struct convert_xrgb_case 
convert_xrgb_cases[] = {
0x, 0x10FF,
},
.gray8_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0x4C },
},
.rgb332_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0xE0 },
},
.rgb565_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0xF800 },
.expected_swab = { 0x00F8 },
},
.xrgb1555_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0x7C00 },
},
.argb1555_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0xFC00 },
},
.rgba5551_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0xF801 },
},
.rgb888_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0x00, 0x00, 0xFF },
},
.argb_result = {
-   .dst_pitch = 0

[PATCH v3 0/6] Increase code coverage on drm_format_helper.c

2023-08-14 Thread Arthur Grillo
The following series include improvements and new KUnit tests to some
functions on drm_format_helper.c.

The first patch improves existing conversion tests to assure that the
default pitch is used when NULL is used on the `dst_pitch` argument.

Patches 2, 3, 4, and 6 add the new parametrized tests to the following
functions:

- drm_fb_swab()
- drm_fb_clip_offset()
- drm_fb_build_fourcc_list()
- drm_fb_memcpy()

The 5th patch is a change to the conversion_buf_size() helper used on
the tests, this change was needed to make the patch 6.

a coverage report for the file can be found below:
https://grillo-0.github.io/coverage-reports/gsoc-drm-format-test/drivers/gpu/drm/drm_format_helper.c.gcov.html

Signed-off-by: Arthur Grillo 
---

v1->v2: 
https://lore.kernel.org/r/20230721182316.560649-1-arthurgri...@riseup.net
- Change patch prefix to "drm/tests" (Maíra Canal)
- Simplify the code by changing to an ternary operator on the
  pitch (Maíra Canal)
- Explain how the expected swab colors were obtained (André Almeida)
- Fix multi-line comment style (André Almeida)
- Remove unnecessary use of drm_kunit_helper_free_device() (Maíra Canal)
- Hard-code the expected number of fourcss (Maíra Canal & Andre Almeida)
- Fix some sparce warnings (kernel test robot)

v2->v3: 
https://lore.kernel.org/r/20230811-gsoc-drm-format-test-v2-v2-0-763b17890...@riseup.net
- Hard-code the number of native fourcss (Maíra Canal)
- Change to a ternary operator on them memcpy test too (Maíra Canal)
- Remove the memcpy_result and place the expected values with the
  parameters
- s/multi_plane_op/fb_memcpy/ (Maíra Canal)

---
Arthur Grillo (6):
  drm/tests: Test default pitch fallback
  drm/tests: Add KUnit tests for drm_fb_swab()
  drm/tests: Add KUnit tests for drm_fb_clip_offset()
  drm/tests: Add KUnit tests for drm_fb_build_fourcc_list()
  drm/tests: Add multi-plane support to conversion_buf_size()
  drm/tests: Add KUnit tests for drm_fb_memcpy()

 drivers/gpu/drm/tests/drm_format_helper_test.c | 815 +++--
 1 file changed, 757 insertions(+), 58 deletions(-)
---
base-commit: b31f78496643fa6dec31b182a3466cf4139e
change-id: 20230810-gsoc-drm-format-test-v2-1989f08e115b

Best regards,
-- 
Arthur Grillo 



Re: [PATCH v2 6/6] drm/tests: Add KUnit tests for drm_fb_memcpy()

2023-08-14 Thread Arthur Grillo



On 13/08/23 10:30, Maira Canal wrote:
> Hi Arthur,
> 
> On 8/11/23 15:17, Arthur Grillo wrote:
>> Insert parameterized test for the drm_fb_memcpy() to ensure correctness
>> and prevent future regressions. The test case can accept different
>> formats.
>>
>> Signed-off-by: Arthur Grillo 
>> ---
>>   drivers/gpu/drm/tests/drm_format_helper_test.c | 391 
>> +
>>   1 file changed, 391 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c 
>> b/drivers/gpu/drm/tests/drm_format_helper_test.c
>> index 08071b6c00f8..09214ae65091 100644
>> --- a/drivers/gpu/drm/tests/drm_format_helper_test.c
>> +++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
>> @@ -1188,6 +1188,396 @@ static void drm_test_fb_build_fourcc_list(struct 
>> kunit *test)
>>   KUNIT_EXPECT_MEMEQ(test, fourccs_out, params->expected, TEST_BUF_SIZE);
>>   }
>>   +struct fb_memcpy_result {
>> +unsigned int dst_pitches[DRM_FORMAT_MAX_PLANES];
>> +const u32 expected[DRM_FORMAT_MAX_PLANES][TEST_BUF_SIZE];
>> +};
>> +
>> +struct multi_plane_op_case {
> 
> I'm not sure if this is the best name to describe the test. Maybe a name 
> related to drm_fb_memcpy would be more appropriate.
> 
>> +const char *name;
>> +u32 format;
>> +struct drm_rect clip;
>> +unsigned int src_pitches[DRM_FORMAT_MAX_PLANES];
>> +const u32 src[DRM_FORMAT_MAX_PLANES][TEST_BUF_SIZE];
>> +struct fb_memcpy_result memcpy_result;
> 
> Could you write
> 
> struct {
> unsigned int dst_pitches[DRM_FORMAT_MAX_PLANES];
> const u32 expected[DRM_FORMAT_MAX_PLANES][TEST_BUF_SIZE];
> } memcpy_result;
> 
> instead of creating a named struct?
> 

By using a unnamed struct I cannot reference it on the test function,
so I would have to write `params->memcpy_result.dst_pitches[0]`, I
think this would make the code less readable. I will just remove the
result struct and place the expected values and the parameters
together.

Best Regards,
~Arthur Grillo

>> +};
>> +
>> +/* The `src` and `expected` buffers are u32 arrays. To deal with planes that
>> + * have a cpp != 4 the values are stored together on the same u32 number in 
>> a
>> + * way so the order in memory is correct in a little-endian machine.
>> + *
>> + * Because of that, on some occasions, parts of a u32 will not be part of 
>> the
>> + * test, to make this explicit the 0xFF byte is used on those parts.
>> + */
>> +
>> +static struct multi_plane_op_case multi_plane_op_cases[] = {
>> +{
>> +.name = "single_pixel_source_buffer",
>> +.format = DRM_FORMAT_XRGB,
>> +.clip = DRM_RECT_INIT(0, 0, 1, 1),
>> +.src_pitches = { 1 * 4 },
>> +.src = {{ 0x01020304 }},
>> +.memcpy_result = {
>> +.dst_pitches = { TEST_USE_DEFAULT_PITCH },
>> +.expected = {{ 0x01020304 }},
>> +}
>> +},
>> +{
>> +.name = "single_pixel_source_buffer",
>> +.format = DRM_FORMAT_XRGB_A8,
>> +.clip = DRM_RECT_INIT(0, 0, 1, 1),
>> +.src_pitches = { 1 * 4, 1 },
>> +.src = {
>> +{ 0x01020304 },
>> +{ 0xFF01 },
>> +},
>> +.memcpy_result = {
>> +.dst_pitches = { TEST_USE_DEFAULT_PITCH },
>> +.expected = {
>> +{ 0x01020304 },
>> +{ 0x0001 },
>> +},
>> +},
>> +},
>> +{
>> +.name = "single_pixel_source_buffer",
>> +.format = DRM_FORMAT_YUV444,
>> +.clip = DRM_RECT_INIT(0, 0, 1, 1),
>> +.src_pitches = { 1, 1, 1 },
>> +.src = {
>> +{ 0xFF01 },
>> +{ 0xFF01 },
>> +{ 0xFF01 },
>> +},
>> +.memcpy_result = {
>> +.dst_pitches = { TEST_USE_DEFAULT_PITCH },
>> +.expected = {
>> +{ 0x0001 },
>> +{ 0x0001 },
>> +{ 0x0001 },
>> +},
>> +},
>> +},
>> +{
>> +.name = "single_pixel_clip_rectangle",
>> +.format = DRM_FORMAT_XBGR,
>> +.clip = DRM_RECT_INIT(1, 1, 1, 1),
>> +.src_pitches = { 2 * 4 },
>> +.src = {
>> +{
>> +0x, 0x,
>> +0x, 0

[PATCH v2 6/6] drm/tests: Add KUnit tests for drm_fb_memcpy()

2023-08-11 Thread Arthur Grillo
Insert parameterized test for the drm_fb_memcpy() to ensure correctness
and prevent future regressions. The test case can accept different
formats.

Signed-off-by: Arthur Grillo 
---
 drivers/gpu/drm/tests/drm_format_helper_test.c | 391 +
 1 file changed, 391 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c 
b/drivers/gpu/drm/tests/drm_format_helper_test.c
index 08071b6c00f8..09214ae65091 100644
--- a/drivers/gpu/drm/tests/drm_format_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
@@ -1188,6 +1188,396 @@ static void drm_test_fb_build_fourcc_list(struct kunit 
*test)
KUNIT_EXPECT_MEMEQ(test, fourccs_out, params->expected, TEST_BUF_SIZE);
 }
 
+struct fb_memcpy_result {
+   unsigned int dst_pitches[DRM_FORMAT_MAX_PLANES];
+   const u32 expected[DRM_FORMAT_MAX_PLANES][TEST_BUF_SIZE];
+};
+
+struct multi_plane_op_case {
+   const char *name;
+   u32 format;
+   struct drm_rect clip;
+   unsigned int src_pitches[DRM_FORMAT_MAX_PLANES];
+   const u32 src[DRM_FORMAT_MAX_PLANES][TEST_BUF_SIZE];
+   struct fb_memcpy_result memcpy_result;
+};
+
+/* The `src` and `expected` buffers are u32 arrays. To deal with planes that
+ * have a cpp != 4 the values are stored together on the same u32 number in a
+ * way so the order in memory is correct in a little-endian machine.
+ *
+ * Because of that, on some occasions, parts of a u32 will not be part of the
+ * test, to make this explicit the 0xFF byte is used on those parts.
+ */
+
+static struct multi_plane_op_case multi_plane_op_cases[] = {
+   {
+   .name = "single_pixel_source_buffer",
+   .format = DRM_FORMAT_XRGB,
+   .clip = DRM_RECT_INIT(0, 0, 1, 1),
+   .src_pitches = { 1 * 4 },
+   .src = {{ 0x01020304 }},
+   .memcpy_result = {
+   .dst_pitches = { TEST_USE_DEFAULT_PITCH },
+   .expected = {{ 0x01020304 }},
+   }
+   },
+   {
+   .name = "single_pixel_source_buffer",
+   .format = DRM_FORMAT_XRGB_A8,
+   .clip = DRM_RECT_INIT(0, 0, 1, 1),
+   .src_pitches = { 1 * 4, 1 },
+   .src = {
+   { 0x01020304 },
+   { 0xFF01 },
+   },
+   .memcpy_result = {
+   .dst_pitches = { TEST_USE_DEFAULT_PITCH },
+   .expected = {
+   { 0x01020304 },
+   { 0x0001 },
+   },
+   },
+   },
+   {
+   .name = "single_pixel_source_buffer",
+   .format = DRM_FORMAT_YUV444,
+   .clip = DRM_RECT_INIT(0, 0, 1, 1),
+   .src_pitches = { 1, 1, 1 },
+   .src = {
+   { 0xFF01 },
+   { 0xFF01 },
+   { 0xFF01 },
+   },
+   .memcpy_result = {
+   .dst_pitches = { TEST_USE_DEFAULT_PITCH },
+   .expected = {
+   { 0x0001 },
+   { 0x0001 },
+   { 0x0001 },
+   },
+   },
+   },
+   {
+   .name = "single_pixel_clip_rectangle",
+   .format = DRM_FORMAT_XBGR,
+   .clip = DRM_RECT_INIT(1, 1, 1, 1),
+   .src_pitches = { 2 * 4 },
+   .src = {
+   {
+   0x, 0x,
+   0x, 0x01020304,
+   },
+   },
+   .memcpy_result = {
+   .dst_pitches = { TEST_USE_DEFAULT_PITCH },
+   .expected = {
+   { 0x01020304 },
+   },
+   },
+   },
+   {
+   .name = "single_pixel_clip_rectangle",
+   .format = DRM_FORMAT_XRGB_A8,
+   .clip = DRM_RECT_INIT(1, 1, 1, 1),
+   .src_pitches = { 2 * 4, 2 * 1 },
+   .src = {
+   {
+   0x, 0x,
+   0x, 0x01020304,
+   },
+   { 0x0100 },
+   },
+   .memcpy_result = {
+   .dst_pitches = { TEST_USE_DEFAULT_PITCH },
+   .expected = {
+   { 0x01020304 },
+   { 0x0001 },
+   },
+   },
+   },
+   {
+   .name = "single_pixel_clip_rectangle",
+   .format = DRM_FORMAT_YUV444,
+   .clip = DRM_RECT_

[PATCH v2 5/6] drm/tests: Add multi-plane support to conversion_buf_size()

2023-08-11 Thread Arthur Grillo
The drm_fb_memcpy() supports multi-plane formats. To fully test it in
the future, add multi-plane support to the conversion_buf_size() helper.

Signed-off-by: Arthur Grillo 
Reviewed-by: Maíra Canal 
---
 drivers/gpu/drm/tests/drm_format_helper_test.c | 28 +-
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c 
b/drivers/gpu/drm/tests/drm_format_helper_test.c
index 2b55d9f025f9..08071b6c00f8 100644
--- a/drivers/gpu/drm/tests/drm_format_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
@@ -472,7 +472,7 @@ static struct convert_xrgb_case 
convert_xrgb_cases[] = {
  * The size of the destination buffer or negative value on error.
  */
 static size_t conversion_buf_size(u32 dst_format, unsigned int dst_pitch,
- const struct drm_rect *clip)
+ const struct drm_rect *clip, int plane)
 {
const struct drm_format_info *dst_fi = drm_format_info(dst_format);
 
@@ -480,7 +480,7 @@ static size_t conversion_buf_size(u32 dst_format, unsigned 
int dst_pitch,
return -EINVAL;
 
if (!dst_pitch)
-   dst_pitch = drm_format_info_min_pitch(dst_fi, 0, 
drm_rect_width(clip));
+   dst_pitch = drm_format_info_min_pitch(dst_fi, plane, 
drm_rect_width(clip));
 
return dst_pitch * drm_rect_height(clip);
 }
@@ -554,7 +554,7 @@ static void drm_test_fb_xrgb_to_gray8(struct kunit 
*test)
};
 
dst_size = conversion_buf_size(DRM_FORMAT_R8, result->dst_pitch,
-  >clip);
+  >clip, 0);
KUNIT_ASSERT_GT(test, dst_size, 0);
 
buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
@@ -588,7 +588,7 @@ static void drm_test_fb_xrgb_to_rgb332(struct kunit 
*test)
};
 
dst_size = conversion_buf_size(DRM_FORMAT_RGB332, result->dst_pitch,
-  >clip);
+  >clip, 0);
KUNIT_ASSERT_GT(test, dst_size, 0);
 
buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
@@ -621,7 +621,7 @@ static void drm_test_fb_xrgb_to_rgb565(struct kunit 
*test)
};
 
dst_size = conversion_buf_size(DRM_FORMAT_RGB565, result->dst_pitch,
-  >clip);
+  >clip, 0);
KUNIT_ASSERT_GT(test, dst_size, 0);
 
buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
@@ -660,7 +660,7 @@ static void drm_test_fb_xrgb_to_xrgb1555(struct kunit 
*test)
};
 
dst_size = conversion_buf_size(DRM_FORMAT_XRGB1555, result->dst_pitch,
-  >clip);
+  >clip, 0);
KUNIT_ASSERT_GT(test, dst_size, 0);
 
buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
@@ -694,7 +694,7 @@ static void drm_test_fb_xrgb_to_argb1555(struct kunit 
*test)
};
 
dst_size = conversion_buf_size(DRM_FORMAT_ARGB1555, result->dst_pitch,
-  >clip);
+  >clip, 0);
KUNIT_ASSERT_GT(test, dst_size, 0);
 
buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
@@ -728,7 +728,7 @@ static void drm_test_fb_xrgb_to_rgba5551(struct kunit 
*test)
};
 
dst_size = conversion_buf_size(DRM_FORMAT_RGBA5551, result->dst_pitch,
-  >clip);
+  >clip, 0);
KUNIT_ASSERT_GT(test, dst_size, 0);
 
buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
@@ -762,7 +762,7 @@ static void drm_test_fb_xrgb_to_rgb888(struct kunit 
*test)
};
 
dst_size = conversion_buf_size(DRM_FORMAT_RGB888, result->dst_pitch,
-  >clip);
+  >clip, 0);
KUNIT_ASSERT_GT(test, dst_size, 0);
 
buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
@@ -799,7 +799,7 @@ static void drm_test_fb_xrgb_to_argb(struct kunit 
*test)
};
 
dst_size = conversion_buf_size(DRM_FORMAT_ARGB,
-  result->dst_pitch, >clip);
+  result->dst_pitch, >clip, 0);
KUNIT_ASSERT_GT(test, dst_size, 0);
 
buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
@@ -833,7 +833,7 @@ static void drm_test_fb_xrgb_to_xrgb2101010(struct 
kunit *test)
};
 
dst_size = conversion_buf_size(DRM_FORMAT_XRGB2101010,
-  result->dst_pitch, >clip);
+  result->dst_pitch, >clip, 0);
KUNIT_ASSERT_GT(test, dst_size, 0);
 
buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
@@ -867,7 +867,7 @@ static void drm_test_fb_xrgb_

[PATCH v2 2/6] drm/tests: Add KUnit tests for drm_fb_swab()

2023-08-11 Thread Arthur Grillo
Insert parameterized test for the drm_fb_swab() to ensure correctness
and prevent future regressions.

Each expected color has it bytes reversed in order, so xrgb would be
bgrx.

Signed-off-by: Arthur Grillo 
Reviewed-by: Maíra Canal 
---
 drivers/gpu/drm/tests/drm_format_helper_test.c | 66 ++
 1 file changed, 66 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c 
b/drivers/gpu/drm/tests/drm_format_helper_test.c
index 938d4fdb4291..d10e18fcb994 100644
--- a/drivers/gpu/drm/tests/drm_format_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
@@ -74,6 +74,11 @@ struct convert_to_mono_result {
const u8 expected[TEST_BUF_SIZE];
 };
 
+struct fb_swab_result {
+   unsigned int dst_pitch;
+   const u32 expected[TEST_BUF_SIZE];
+};
+
 struct convert_xrgb_case {
const char *name;
unsigned int pitch;
@@ -90,6 +95,7 @@ struct convert_xrgb_case {
struct convert_to_xrgb2101010_result xrgb2101010_result;
struct convert_to_argb2101010_result argb2101010_result;
struct convert_to_mono_result mono_result;
+   struct fb_swab_result swab_result;
 };
 
 static struct convert_xrgb_case convert_xrgb_cases[] = {
@@ -143,6 +149,10 @@ static struct convert_xrgb_case 
convert_xrgb_cases[] = {
.dst_pitch =  TEST_USE_DEFAULT_PITCH,
.expected = { 0b0 },
},
+   .swab_result = {
+   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
+   .expected = { 0xFF01 },
+   },
},
{
.name = "single_pixel_clip_rectangle",
@@ -197,6 +207,10 @@ static struct convert_xrgb_case 
convert_xrgb_cases[] = {
.dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0b0 },
},
+   .swab_result = {
+   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
+   .expected = { 0xFF10 },
+   },
},
{
/* Well known colors: White, black, red, green, blue, magenta,
@@ -318,6 +332,15 @@ static struct convert_xrgb_case 
convert_xrgb_cases[] = {
0b11,
},
},
+   .swab_result = {
+   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
+   .expected = {
+   0xFF11, 0x0022,
+   0xFF33, 0x00FF0044,
+   0xFF55, 0xFF00FF66,
+   0x0077, 0x0088,
+   },
+   },
},
{
/* Randomly picked colors. Full buffer within the clip area. */
@@ -425,6 +448,14 @@ static struct convert_xrgb_case 
convert_xrgb_cases[] = {
0b010, 0b000,
},
},
+   .swab_result = {
+   .dst_pitch =  20,
+   .expected = {
+   0x9C440EA1, 0x054D11B1, 0x03F3A8C1, 0x, 
0x,
+   0x73F06CD1, 0x9C440EA2, 0x054D11B2, 0x, 
0x,
+   0x0303A8C2, 0x73F06CD2, 0x9C440EA3, 0x, 
0x,
+   },
+   },
},
 };
 
@@ -886,6 +917,40 @@ static void drm_test_fb_xrgb_to_mono(struct kunit 
*test)
KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
 }
 
+static void drm_test_fb_swab(struct kunit *test)
+{
+   const struct convert_xrgb_case *params = test->param_value;
+   const struct fb_swab_result *result = >swab_result;
+   size_t dst_size;
+   u32 *buf = NULL;
+   __le32 *xrgb = NULL;
+   struct iosys_map dst, src;
+
+   struct drm_framebuffer fb = {
+   .format = drm_format_info(DRM_FORMAT_XRGB),
+   .pitches = { params->pitch, 0, 0 },
+   };
+
+   dst_size = conversion_buf_size(DRM_FORMAT_XRGB, result->dst_pitch, 
>clip);
+
+   KUNIT_ASSERT_GT(test, dst_size, 0);
+
+   buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
+   iosys_map_set_vaddr(, buf);
+
+   xrgb = cpubuf_to_le32(test, params->xrgb, TEST_BUF_SIZE);
+   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb);
+   iosys_map_set_vaddr(, xrgb);
+
+   const unsigned int *dst_pitch = (result->dst_pitch == 
TEST_USE_DEFAULT_PITCH) ?
+   NULL : >dst_pitch;
+
+   drm_fb_swab(, dst_pitch, , , >clip, false);
+   buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / 
sizeof(u32));
+   KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
+}
+
 static struct kunit_case drm_format_helpe

[PATCH v2 3/6] drm/tests: Add KUnit tests for drm_fb_clip_offset()

2023-08-11 Thread Arthur Grillo
Insert parameterized test for the drm_fb_clip_offset() to ensure
correctness and prevent future regressions.

Signed-off-by: Arthur Grillo 
Reviewed-by: Maíra Canal 
---
 drivers/gpu/drm/tests/drm_format_helper_test.c | 91 ++
 1 file changed, 91 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c 
b/drivers/gpu/drm/tests/drm_format_helper_test.c
index d10e18fcb994..7f24da0b1e00 100644
--- a/drivers/gpu/drm/tests/drm_format_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
@@ -951,6 +951,96 @@ static void drm_test_fb_swab(struct kunit *test)
KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
 }
 
+struct clip_offset_case {
+   const char *name;
+   unsigned int pitch;
+   u32 format;
+   struct drm_rect clip;
+   unsigned int expected_offset;
+};
+
+static struct clip_offset_case clip_offset_cases[] = {
+   {
+   .name = "pass through",
+   .pitch = TEST_USE_DEFAULT_PITCH,
+   .format = DRM_FORMAT_XRGB,
+   .clip = DRM_RECT_INIT(0, 0, 3, 3),
+   .expected_offset = 0
+   },
+   {
+   .name = "horizontal offset",
+   .pitch = TEST_USE_DEFAULT_PITCH,
+   .format = DRM_FORMAT_XRGB,
+   .clip = DRM_RECT_INIT(1, 0, 3, 3),
+   .expected_offset = 4,
+   },
+   {
+   .name = "vertical offset",
+   .pitch = TEST_USE_DEFAULT_PITCH,
+   .format = DRM_FORMAT_XRGB,
+   .clip = DRM_RECT_INIT(0, 1, 3, 3),
+   .expected_offset = 12,
+   },
+   {
+   .name = "horizontal and vertical offset",
+   .pitch = TEST_USE_DEFAULT_PITCH,
+   .format = DRM_FORMAT_XRGB,
+   .clip = DRM_RECT_INIT(1, 1, 3, 3),
+   .expected_offset = 16,
+   },
+   {
+   .name = "horizontal offset (custom pitch)",
+   .pitch = 20,
+   .format = DRM_FORMAT_XRGB,
+   .clip = DRM_RECT_INIT(1, 0, 3, 3),
+   .expected_offset = 4,
+   },
+   {
+   .name = "vertical offset (custom pitch)",
+   .pitch = 20,
+   .format = DRM_FORMAT_XRGB,
+   .clip = DRM_RECT_INIT(0, 1, 3, 3),
+   .expected_offset = 20,
+   },
+   {
+   .name = "horizontal and vertical offset (custom pitch)",
+   .pitch = 20,
+   .format = DRM_FORMAT_XRGB,
+   .clip = DRM_RECT_INIT(1, 1, 3, 3),
+   .expected_offset = 24,
+   },
+};
+
+static void clip_offset_case_desc(struct clip_offset_case *t, char *desc)
+{
+   strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
+}
+
+KUNIT_ARRAY_PARAM(clip_offset, clip_offset_cases, clip_offset_case_desc);
+
+static void drm_test_fb_clip_offset(struct kunit *test)
+{
+   const struct clip_offset_case *params = test->param_value;
+   const struct drm_format_info *format_info = 
drm_format_info(params->format);
+
+   unsigned int offset;
+   unsigned int pitch = params->pitch;
+
+   if (pitch == TEST_USE_DEFAULT_PITCH)
+   pitch = drm_format_info_min_pitch(format_info, 0,
+ 
drm_rect_width(>clip));
+
+   /*
+* Assure that the pitch is not zero, because this will inevitable 
cause the
+* wrong expected result
+*/
+   KUNIT_ASSERT_NE(test, pitch, 0);
+
+   offset = drm_fb_clip_offset(pitch, format_info, >clip);
+
+   KUNIT_EXPECT_EQ(test, offset, params->expected_offset);
+}
+
 static struct kunit_case drm_format_helper_test_cases[] = {
KUNIT_CASE_PARAM(drm_test_fb_xrgb_to_gray8, 
convert_xrgb_gen_params),
KUNIT_CASE_PARAM(drm_test_fb_xrgb_to_rgb332, 
convert_xrgb_gen_params),
@@ -964,6 +1054,7 @@ static struct kunit_case drm_format_helper_test_cases[] = {
KUNIT_CASE_PARAM(drm_test_fb_xrgb_to_argb2101010, 
convert_xrgb_gen_params),
KUNIT_CASE_PARAM(drm_test_fb_xrgb_to_mono, 
convert_xrgb_gen_params),
KUNIT_CASE_PARAM(drm_test_fb_swab, convert_xrgb_gen_params),
+   KUNIT_CASE_PARAM(drm_test_fb_clip_offset, clip_offset_gen_params),
{}
 };
 

-- 
2.41.0



[PATCH v2 4/6] drm/tests: Add KUnit tests for drm_fb_build_fourcc_list()

2023-08-11 Thread Arthur Grillo
Insert parameterized test for the drm_fb_build_fourcc_list() to ensure
correctness and prevent future regressions.

Signed-off-by: Arthur Grillo 
---
 drivers/gpu/drm/tests/drm_format_helper_test.c | 148 +
 1 file changed, 148 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c 
b/drivers/gpu/drm/tests/drm_format_helper_test.c
index 7f24da0b1e00..2b55d9f025f9 100644
--- a/drivers/gpu/drm/tests/drm_format_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
@@ -3,11 +3,13 @@
 #include 
 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1041,6 +1043,151 @@ static void drm_test_fb_clip_offset(struct kunit *test)
KUNIT_EXPECT_EQ(test, offset, params->expected_offset);
 }
 
+struct fb_build_fourcc_list_case {
+   const char *name;
+   u32 native_fourccs[TEST_BUF_SIZE];
+   u32 expected[TEST_BUF_SIZE];
+   size_t fourccs_size;
+};
+
+static struct fb_build_fourcc_list_case fb_build_fourcc_list_cases[] = {
+   {
+   .name = "no native formats",
+   .native_fourccs = { },
+   .expected = { DRM_FORMAT_XRGB },
+   .fourccs_size = 1,
+   },
+   {
+   .name = "XRGB as native format",
+   .native_fourccs = { DRM_FORMAT_XRGB },
+   .expected = { DRM_FORMAT_XRGB },
+   .fourccs_size = 1,
+   },
+   {
+   .name = "remove duplicates",
+   .native_fourccs = {
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_XRGB,
+   },
+   .expected = {
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_RGB565,
+   },
+   .fourccs_size = 3,
+   },
+   {
+   .name = "convert alpha formats",
+   .native_fourccs = {
+   DRM_FORMAT_ARGB1555,
+   DRM_FORMAT_ABGR1555,
+   DRM_FORMAT_RGBA5551,
+   DRM_FORMAT_BGRA5551,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_ABGR,
+   DRM_FORMAT_RGBA,
+   DRM_FORMAT_BGRA,
+   DRM_FORMAT_ARGB2101010,
+   DRM_FORMAT_ABGR2101010,
+   DRM_FORMAT_RGBA1010102,
+   DRM_FORMAT_BGRA1010102,
+   },
+   .expected = {
+   DRM_FORMAT_XRGB1555,
+   DRM_FORMAT_XBGR1555,
+   DRM_FORMAT_RGBX5551,
+   DRM_FORMAT_BGRX5551,
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_XBGR,
+   DRM_FORMAT_RGBX,
+   DRM_FORMAT_BGRX,
+   DRM_FORMAT_XRGB2101010,
+   DRM_FORMAT_XBGR2101010,
+   DRM_FORMAT_RGBX1010102,
+   DRM_FORMAT_BGRX1010102,
+   },
+   .fourccs_size = 12,
+   },
+   {
+   .name = "random formats",
+   .native_fourccs = {
+   DRM_FORMAT_Y212,
+   DRM_FORMAT_ARGB1555,
+   DRM_FORMAT_ABGR16161616F,
+   DRM_FORMAT_C8,
+   DRM_FORMAT_BGR888,
+   DRM_FORMAT_XRGB1555,
+   DRM_FORMAT_RGBA5551,
+   DRM_FORMAT_BGR565_A8,
+   DRM_FORMAT_R10,
+   DRM_FORMAT_XYUV,
+   },
+   .expected = {
+   DRM_FORMAT_Y212,
+   DRM_FORMAT_XRGB1555,
+   DRM_FORMAT_ABGR16161616F,
+   DRM_FORMAT_C8,
+   DRM_FORMAT_BGR888,
+   DRM_FORMAT_RGBX5551,
+   DRM_FORMAT_BGR565_A8,
+   DRM_FORMAT_R10,
+   DRM_FORMAT_XYUV,
+   DRM_FORMAT_XRGB,
+   },
+   .fourccs_size = 10,
+   },
+};
+
+static void fb_build_fourcc_list_case_desc(struct fb_build_fourcc_list_case 
*t, char *desc)
+{
+   strscpy(desc, t->name, KUNIT_PARAM_

[PATCH v2 1/6] drm/tests: Test default pitch fallback

2023-08-11 Thread Arthur Grillo
Test the default pitch fallback when NULL is passed as the dst_pitch on
the conversion procedures.

Signed-off-by: Arthur Grillo 
---
 drivers/gpu/drm/tests/drm_format_helper_test.c | 126 -
 1 file changed, 81 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c 
b/drivers/gpu/drm/tests/drm_format_helper_test.c
index 474bb7a1c4ee..938d4fdb4291 100644
--- a/drivers/gpu/drm/tests/drm_format_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
@@ -16,6 +16,8 @@
 
 #define TEST_BUF_SIZE 50
 
+#define TEST_USE_DEFAULT_PITCH 0
+
 struct convert_to_gray8_result {
unsigned int dst_pitch;
const u8 expected[TEST_BUF_SIZE];
@@ -97,48 +99,48 @@ static struct convert_xrgb_case 
convert_xrgb_cases[] = {
.clip = DRM_RECT_INIT(0, 0, 1, 1),
.xrgb = { 0x01FF },
.gray8_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0x4C },
},
.rgb332_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0xE0 },
},
.rgb565_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0xF800 },
.expected_swab = { 0x00F8 },
},
.xrgb1555_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0x7C00 },
},
.argb1555_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0xFC00 },
},
.rgba5551_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0xF801 },
},
.rgb888_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0x00, 0x00, 0xFF },
},
.argb_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0x },
},
.xrgb2101010_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0x3FF0 },
},
.argb2101010_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0xFFF0 },
},
.mono_result = {
-   .dst_pitch = 0,
+   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
.expected = { 0b0 },
},
},
@@ -151,48 +153,48 @@ static struct convert_xrgb_case 
convert_xrgb_cases[] = {
0x, 0x10FF,
},
.gray8_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0x4C },
},
.rgb332_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0xE0 },
},
.rgb565_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0xF800 },
.expected_swab = { 0x00F8 },
},
.xrgb1555_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0x7C00 },
},
.argb1555_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0xFC00 },
},
.rgba5551_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0xF801 },
},
.rgb888_result = {
-   .dst_pitch = 0,
+   .dst_pitch = TEST_USE_DEFAULT_PITCH,
.expected = { 0x00, 0x00, 0xFF },
},
.argb_result = {
-   .dst_pitch = 0,
+   .dst_pitch

[PATCH v2 0/6] Increase code coverage on drm_format_helper.c

2023-08-11 Thread Arthur Grillo
The following series include improvements and new KUnit tests to some
functions on drm_format_helper.c.

The first patch improves existing conversion tests to assure that the
default pitch is used when NULL is used on the `dst_pitch` argument.

Patches 2, 3, 4, and 6 add the new parametrized tests to the following
functions:

- drm_fb_swab()
- drm_fb_clip_offset()
- drm_fb_build_fourcc_list()
- drm_fb_memcpy()

The 5th patch is a change to the conversion_buf_size() helper used on
the tests, this change was needed to make the patch 6.

a coverage report for the file can be found below:
https://grillo-0.github.io/coverage-reports/gsoc-drm-format-test/drivers/gpu/drm/drm_format_helper.c.gcov.html

Signed-off-by: Arthur Grillo 
---

v1->v2: 
https://lore.kernel.org/r/20230721182316.560649-1-arthurgri...@riseup.net
- Change patch prefix to "drm/tests" (Maíra Canal)
- Simplify the code by changing to an ternary operator on the
  pitch (Maíra Canal)
- Explain how the expected swab colors were obtained (André Almeida)
- Fix multi-line comment style (André Almeida)
- Remove unnecessary use of drm_kunit_helper_free_device() (Maíra Canal)
- Hard-code the expected number of fourcss (Maíra Canal & Andre Almeida)
- Fix some sparce warnings (kernel test robot)

---
Arthur Grillo (6):
  drm/tests: Test default pitch fallback
  drm/tests: Add KUnit tests for drm_fb_swab()
  drm/tests: Add KUnit tests for drm_fb_clip_offset()
  drm/tests: Add KUnit tests for drm_fb_build_fourcc_list()
  drm/tests: Add multi-plane support to conversion_buf_size()
  drm/tests: Add KUnit tests for drm_fb_memcpy()

 drivers/gpu/drm/tests/drm_format_helper_test.c | 848 +++--
 1 file changed, 790 insertions(+), 58 deletions(-)
---
base-commit: b31f78496643fa6dec31b182a3466cf4139e
change-id: 20230810-gsoc-drm-format-test-v2-1989f08e115b

Best regards,
-- 
Arthur Grillo 



Re: [PATCH 6/6] drm/format-helper: Add KUnit tests for drm_fb_memcpy()

2023-08-09 Thread Arthur Grillo



On 05/08/23 10:26, Maira Canal wrote:
> On 7/21/23 15:23, Arthur Grillo wrote:
>> Insert parameterized test for the drm_fb_memcpy() to ensure correctness
>> and prevent future regressions. The test case can accept different
>> formats.
>>
>> Signed-off-by: Arthur Grillo 
>> ---
>>   .../gpu/drm/tests/drm_format_helper_test.c| 391 ++
>>   1 file changed, 391 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c 
>> b/drivers/gpu/drm/tests/drm_format_helper_test.c
>> index 6ecd92898e8e..3db4b95f3a98 100644
>> --- a/drivers/gpu/drm/tests/drm_format_helper_test.c
>> +++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
>> @@ -1189,6 +1189,396 @@ static void drm_test_fb_build_fourcc_list(struct 
>> kunit *test)
>>   KUNIT_EXPECT_MEMEQ(test, fourccs_out, params->expected, TEST_BUF_SIZE);
>>   }
>>   +struct fb_memcpy_result {
>> +unsigned int dst_pitches[DRM_FORMAT_MAX_PLANES];
>> +const u32 expected[DRM_FORMAT_MAX_PLANES][TEST_BUF_SIZE];
>> +};
>> +
>> +struct multi_plane_op_case {
>> +const char *name;
>> +u32 format;
>> +struct drm_rect clip;
>> +unsigned int src_pitches[DRM_FORMAT_MAX_PLANES];
>> +const u32 src[DRM_FORMAT_MAX_PLANES][TEST_BUF_SIZE];
>> +struct fb_memcpy_result memcpy_result;
>> +};
>> +
>> +/* The `src` and `expected` buffers are u32 arrays. To deal with planes that
>> + * have a cpp != 4 the values are stored together on the same u32 number in 
>> a
>> + * way so the order in memory is correct in a little-endian machine.
>> + *
>> + * Because of that, on some occasions, parts of a u32 will not be part of 
>> the
>> + * test, to make this explicit the 0xFF byte is used on those parts.
>> + */
>> +
>> +static struct multi_plane_op_case multi_plane_op_cases[] = {
>> +{
>> +.name = "single_pixel_source_buffer",
>> +.format = DRM_FORMAT_XRGB,
>> +.clip = DRM_RECT_INIT(0, 0, 1, 1),
>> +.src_pitches = { 1 * 4 },
>> +.src = {{ 0x01020304 }},
>> +.memcpy_result = {
>> +.dst_pitches = { TEST_USE_DEFAULT_PITCH },
>> +.expected = {{ 0x01020304 }},
>> +}
>> +},
>> +{
>> +.name = "single_pixel_source_buffer",
>> +.format = DRM_FORMAT_XRGB_A8,
>> +.clip = DRM_RECT_INIT(0, 0, 1, 1),
>> +.src_pitches = { 1 * 4, 1 },
>> +.src = {
>> +{ 0x01020304 },
>> +{ 0xFF01 },
>> +},
>> +.memcpy_result = {
>> +.dst_pitches = { TEST_USE_DEFAULT_PITCH },
>> +.expected = {
>> +{ 0x01020304 },
>> +{ 0x0001 },
>> +},
>> +},
>> +},
> 
> Some tests have the same description name. Could you distinct them with
> different names?

The test description is formed not only by the `.name` attribute but also by the
string representation of the `.format` attribute, so two test descriptions are
distinct if they have the same `.name` but different `.format`.

Best Regards,
~Arthur Grillo

> 
> Best Regards,
> - Maíra
> 
>> +{
>> +.name = "single_pixel_source_buffer",
>> +.format = DRM_FORMAT_YUV444,
>> +.clip = DRM_RECT_INIT(0, 0, 1, 1),
>> +.src_pitches = { 1, 1, 1 },
>> +.src = {
>> +{ 0xFF01 },
>> +{ 0xFF01 },
>> +{ 0xFF01 },
>> +},
>> +.memcpy_result = {
>> +.dst_pitches = { TEST_USE_DEFAULT_PITCH },
>> +.expected = {
>> +{ 0x0001 },
>> +{ 0x0001 },
>> +{ 0x0001 },
>> +},
>> +},
>> +},
>> +{
>> +.name = "single_pixel_clip_rectangle",
>> +.format = DRM_FORMAT_XBGR,
>> +.clip = DRM_RECT_INIT(1, 1, 1, 1),
>> +.src_pitches = { 2 * 4 },
>> +.src = {
>> +{
>> +0x, 0x,
>> +0x, 0x01020304,
>> +},
>> +},
>> +.memcpy_result = {
>> +.dst_pitches = { TEST_USE_DEFAULT_PITCH },
>> +.expected = {
>> +{ 0x01020304 },
>> +},
>> +},
>> +},
>> +{
>> +.name = "s

Re: [PATCH -next 6/7] drm/format-helper: Remove unnecessary NULL values

2023-08-09 Thread Arthur Grillo



On 09/08/23 00:44, Ruan Jinjie wrote:
> The NULL initialization of the pointers assigned by
> kunit_kzalloc() first is not necessary, because if kunit_kzalloc()
> failed, the pointers will be assigned NULL, otherwise it works
> as usual. so remove it.
> 
> Signed-off-by: Ruan Jinjie 
> ---
>  .../gpu/drm/tests/drm_format_helper_test.c| 28 +--
>  1 file changed, 14 insertions(+), 14 deletions(-)

Reviewed-by: Arthur Grillo 

Best Regards,
~Arthur Grillo

> 
> diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c 
> b/drivers/gpu/drm/tests/drm_format_helper_test.c
> index 474bb7a1c4ee..1db12d8ed23c 100644
> --- a/drivers/gpu/drm/tests/drm_format_helper_test.c
> +++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
> @@ -452,7 +452,7 @@ static size_t conversion_buf_size(u32 dst_format, 
> unsigned int dst_pitch,
>  
>  static u16 *le16buf_to_cpu(struct kunit *test, const __le16 *buf, size_t 
> buf_size)
>  {
> - u16 *dst = NULL;
> + u16 *dst;
>   int n;
>  
>   dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL);
> @@ -467,7 +467,7 @@ static u16 *le16buf_to_cpu(struct kunit *test, const 
> __le16 *buf, size_t buf_siz
>  
>  static u32 *le32buf_to_cpu(struct kunit *test, const __le32 *buf, size_t 
> buf_size)
>  {
> - u32 *dst = NULL;
> + u32 *dst;
>   int n;
>  
>   dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL);
> @@ -482,7 +482,7 @@ static u32 *le32buf_to_cpu(struct kunit *test, const 
> __le32 *buf, size_t buf_siz
>  
>  static __le32 *cpubuf_to_le32(struct kunit *test, const u32 *buf, size_t 
> buf_size)
>  {
> - __le32 *dst = NULL;
> + __le32 *dst;
>   int n;
>  
>   dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL);
> @@ -509,7 +509,7 @@ static void drm_test_fb_xrgb_to_gray8(struct kunit 
> *test)
>   const struct convert_xrgb_case *params = test->param_value;
>   const struct convert_to_gray8_result *result = >gray8_result;
>   size_t dst_size;
> - u8 *buf = NULL;
> + u8 *buf;
>   __le32 *xrgb = NULL;
>   struct iosys_map dst, src;
>  
> @@ -539,7 +539,7 @@ static void drm_test_fb_xrgb_to_rgb332(struct kunit 
> *test)
>   const struct convert_xrgb_case *params = test->param_value;
>   const struct convert_to_rgb332_result *result = >rgb332_result;
>   size_t dst_size;
> - u8 *buf = NULL;
> + u8 *buf;
>   __le32 *xrgb = NULL;
>   struct iosys_map dst, src;
>  
> @@ -569,7 +569,7 @@ static void drm_test_fb_xrgb_to_rgb565(struct kunit 
> *test)
>   const struct convert_xrgb_case *params = test->param_value;
>   const struct convert_to_rgb565_result *result = >rgb565_result;
>   size_t dst_size;
> - u16 *buf = NULL;
> + u16 *buf;
>   __le32 *xrgb = NULL;
>   struct iosys_map dst, src;
>  
> @@ -605,7 +605,7 @@ static void drm_test_fb_xrgb_to_xrgb1555(struct kunit 
> *test)
>   const struct convert_xrgb_case *params = test->param_value;
>   const struct convert_to_xrgb1555_result *result = 
> >xrgb1555_result;
>   size_t dst_size;
> - u16 *buf = NULL;
> + u16 *buf;
>   __le32 *xrgb = NULL;
>   struct iosys_map dst, src;
>  
> @@ -636,7 +636,7 @@ static void drm_test_fb_xrgb_to_argb1555(struct kunit 
> *test)
>   const struct convert_xrgb_case *params = test->param_value;
>   const struct convert_to_argb1555_result *result = 
> >argb1555_result;
>   size_t dst_size;
> - u16 *buf = NULL;
> + u16 *buf;
>   __le32 *xrgb = NULL;
>   struct iosys_map dst, src;
>  
> @@ -667,7 +667,7 @@ static void drm_test_fb_xrgb_to_rgba5551(struct kunit 
> *test)
>   const struct convert_xrgb_case *params = test->param_value;
>   const struct convert_to_rgba5551_result *result = 
> >rgba5551_result;
>   size_t dst_size;
> - u16 *buf = NULL;
> + u16 *buf;
>   __le32 *xrgb = NULL;
>   struct iosys_map dst, src;
>  
> @@ -698,7 +698,7 @@ static void drm_test_fb_xrgb_to_rgb888(struct kunit 
> *test)
>   const struct convert_xrgb_case *params = test->param_value;
>   const struct convert_to_rgb888_result *result = >rgb888_result;
>   size_t dst_size;
> - u8 *buf = NULL;
> + u8 *buf;
>   __le32 *xrgb = NULL;
>   struct iosys_map dst, src;
>  
> @@ -732,7 +732,7 @@ static void drm_test_fb_xrgb_to_argb(struct kunit 
> *test)
>   const struct convert_xrgb_case *params = test->param_value;
>   const struct c

Re: [PATCH] drm: Drop select FRAMEBUFFER_CONSOLE for DRM_FBDEV_EMULATION

2023-08-04 Thread Arthur Grillo



On 04/08/23 09:51, Javier Martinez Canillas wrote:
> The commit c242f48433e7 ("drm: Make FB_CORE to be selected if DRM fbdev
> emulation is enabled") changed DRM_FBDEV_EMULATION from 'depends on FB'
> to an effective 'select FB_CORE', so any config that previously had DRM=y
> and FB=n now has FB_CORE=y and FRAMEBUFFER_CONSOLE=y.
> 
> This leads to unmet direct dependencies detected for FRAMEBUFFER_CONSOLE
> as reported by Arthur Grillo, e.g:
> 
> WARNING: unmet direct dependencies detected for FRAMEBUFFER_CONSOLE
>   Depends on [n]: VT [=n] && FB_CORE [=y] && !UML [=y]
>   Selected by [y]:
>   - DRM_FBDEV_EMULATION [=y] && HAS_IOMEM [=y] && DRM [=y] && !EXPERT [=n]
> 
> Arnd Bergmann suggests to drop the select FRAMEBUFFER_CONSOLE for the
> DRM_FBDEV_EMULATION Kconfig symbol, since a possible use case could
> be to enable DRM fbdev emulation but without a framebuffer console.
> 
> Fixes: c242f48433e7 ("drm: Make FB_CORE to be selected if DRM fbdev emulation 
> is enabled")
> Reported-by: Arthur Grillo 
> Closes: 
> https://lore.kernel.org/dri-devel/20230726220325.278976-1-arthurgri...@riseup.net
> Suggested-by: Arnd Bergmann 
> Signed-off-by: Javier Martinez Canillas 
> ---

Greate patch! I was about to send the same one XD.

Reviewed-by: Arthur Grillo 

Best Regards,
~Arthur Grillo

> 
>  drivers/gpu/drm/Kconfig | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> index b51c6a141dfa..2a44b9419d4d 100644
> --- a/drivers/gpu/drm/Kconfig
> +++ b/drivers/gpu/drm/Kconfig
> @@ -135,7 +135,6 @@ config DRM_DEBUG_MODESET_LOCK
>  config DRM_FBDEV_EMULATION
>   bool "Enable legacy fbdev support for your modesetting driver"
>   depends on DRM
> - select FRAMEBUFFER_CONSOLE if !EXPERT
>   select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE
>   default y
>   help


  1   2   >