[igt-dev] [RFC PATCH 5/7] igt/color: Add SW color transform functionality

Harry Wentland harry.wentland at amd.com
Fri Nov 3 14:30:14 UTC 2023



On 2023-09-18 05:21, Kamil Konieczny wrote:
> Hi Harry,
> 
> On 2023-09-08 at 11:03:13 -0400, Harry Wentland wrote:
>> In order to test color we want to compare a HW (KMS) transform
>> with a SW transform. This introduces color transform for an
>> sRGB EOTF but this can be extended to other transforms. Code is
>> borrowed from Skia.
> 
> From what you wrote below it looks like you borrowed only few
> functions from Skia. Am I missing something?
> 

Correct, I'm only pulling in what I need.

>>
>> Signed-off-by: Harry Wentland <harry.wentland at amd.com>
>> Cc: Ville Syrjala <ville.syrjala at linux.intel.com>
>> Cc: Pekka Paalanen <pekka.paalanen at collabora.com>
>> Cc: Simon Ser <contact at emersion.fr>
>> Cc: Harry Wentland <harry.wentland at amd.com>
>> Cc: Melissa Wen <mwen at igalia.com>
>> Cc: Jonas Ådahl <jadahl at redhat.com>
>> Cc: Sebastian Wick <sebastian.wick at redhat.com>
>> Cc: Shashank Sharma <shashank.sharma at amd.com>
>> Cc: Alexander Goins <agoins at nvidia.com>
>> Cc: Joshua Ashton <joshua at froggi.es>
>> Cc: Michel Dänzer <mdaenzer at redhat.com>
>> Cc: Aleix Pol <aleixpol at kde.org>
>> Cc: Xaver Hugl <xaver.hugl at gmail.com>
>> Cc: Victoria Brekenfeld <victoria at system76.com>
>> Cc: Daniel Vetter <daniel at ffwll.ch>
>> Cc: Uma Shankar <uma.shankar at intel.com>
>> Cc: Naseer Ahmed <quic_naseer at quicinc.com>
>> Cc: Christopher Braga <quic_cbraga at quicinc.com>
>> ---
>>  lib/igt_color.c | 330 ++++++++++++++++++++++++++++++++++++++++++++++++
>>  lib/igt_color.h | 105 +++++++++++++++
>>  lib/igt_fb.c    |   6 +-
>>  lib/igt_fb.h    |   2 +
>>  lib/meson.build |   1 +
>>  5 files changed, 441 insertions(+), 3 deletions(-)
>>  create mode 100644 lib/igt_color.c
>>  create mode 100644 lib/igt_color.h
>>
>> diff --git a/lib/igt_color.c b/lib/igt_color.c
>> new file mode 100644
>> index 000000000000..12ff9ad1f324
>> --- /dev/null
>> +++ b/lib/igt_color.c
>> @@ -0,0 +1,330 @@
>> +/*
>> + * Copyright 2023 Advanced Micro Devices, Inc.
>> + *
>> + * Permission is hereby granted, free of charge, to any person obtaining a
> 
> Use SPDX instead, look at other igt-gpu-tools sources for
> guide how to use it in source.c and header.h
> 
>> + * 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
>> + */
>> +
>> +#include <errno.h>
>> +#include <math.h>
>> +
>> +#include "igt_color.h"
>> +#include "igt_core.h"
>> +#include "igt_x86.h"
>> +
>> +
>> +static float clamp(float val, float min, float max)
>> +{
>> +	return ((val < min) ? min : ((val > max) ? max : val));
>> +}
>> +
>> +/*
>> + * Below code is taken from Skia and adapted for style and needs of
>> + * IGT.
>> + *
>> + * https://chromium.googlesource.com/chromium/src/+/3e1a26c44c024d97dc9a4c09bbc6a2365398ca2c/ui/gfx/skia_color_space_util.cc#15
>> + *
>> + * To comply with the original code's license we'll include it, as well
>> + * as the original copyright here:
>> + *
>> + * // Copyright 2015 The Chromium Authors
>> + * //
> 
> imho this is strange, I am against this, either add Chromium
> to copyright header at begin of file or delete this. What
> exactly licence is this? GNU GPL? MIT?
> 

BSD. From what I can tell it's compatible with MIT and all I need to do
is add Google's copyright at the top, so I'll do that for the next version.

Harry

> +cc Pteri
> 
> Regards,
> Kamil
> 
>> + * // Redistribution and use in source and binary forms, with or without
>> + * // modification, are permitted provided that the following conditions are
>> + * // met:
>> + * //
>> + * //    * Redistributions of source code must retain the above copyright
>> + * // notice, this list of conditions and the following disclaimer.
>> + * //    * Redistributions in binary form must reproduce the above
>> + * // copyright notice, this list of conditions and the following disclaimer
>> + * // in the documentation and/or other materials provided with the
>> + * // distribution.
>> + * //    * Neither the name of Google LLC nor the names of its
>> + * // contributors may be used to endorse or promote products derived from
>> + * // this software without specific prior written permission.
>> + * //
>> + * // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
>> + * // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
>> + * // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
>> + * // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
>> + * // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>> + * // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>> + * // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
>> + * // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
>> + * // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
>> + * // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
>> + * // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>> + */
>> +
>> +static float igt_color_tf_eval_unclamped(const struct igt_color_tf *fn, float x)
>> +{
>> +	if (x < fn->d)
>> +		return fn->c * x + fn->f;
>> +	return pow(fn->a * x + fn->b, fn->g) + fn->e;
>> +}
>> +
>> +static float igt_color_tf_eval(const struct igt_color_tf *fn, float x)
>> +{
>> +	float fn_at_x_unclamped = igt_color_tf_eval_unclamped(fn, x);
>> +	return clamp(fn_at_x_unclamped, 0.0f, 1.0f);
>> +}
>> +
>> +#if 0
>> +skcms_TransferFunction SkTransferFnInverse(const skcms_TransferFunction& fn) {
>> +  skcms_TransferFunction fn_inv = {0};
>> +  if (fn.a > 0 && fn.g > 0) {
>> +    double a_to_the_g = std::pow(fn.a, fn.g);
>> +    fn_inv.a = 1.f / a_to_the_g;
>> +    fn_inv.b = -fn.e / a_to_the_g;
>> +    fn_inv.g = 1.f / fn.g;
>> +  }
>> +  fn_inv.d = fn.c * fn.d + fn.f;
>> +  fn_inv.e = -fn.b / fn.a;
>> +  if (fn.c != 0) {
>> +    fn_inv.c = 1.f / fn.c;
>> +    fn_inv.f = -fn.f / fn.c;
>> +  }
>> +  return fn_inv;
>> +}
>> +#endif
>> +
>> +/* end of Skia-based code */
>> +
>> +static void igt_color_srgb_inv_eotf(igt_pixel_t *pixel)
>> +{
>> +}
>> +
>> +
>> +
>> +static void igt_color_srgb_eotf(igt_pixel_t *pixel)
>> +{
>> +	pixel->r = igt_color_tf_eval(&srgb_tf, pixel->r);
>> +	pixel->g = igt_color_tf_eval(&srgb_tf, pixel->g);
>> +	pixel->b = igt_color_tf_eval(&srgb_tf, pixel->b);
>> +}
>> +
>> +int igt_color_transform_pixels(igt_fb_t *fb, igt_pixel_transform transform)
>> +{
>> +	uint32_t *line = NULL;
>> +	void *map;
>> +	char *ptr;
>> +	int x, y, cpp = igt_drm_format_to_bpp(fb->drm_format) / 8;
>> +	uint32_t stride = igt_fb_calc_plane_stride(fb, 0);
>> +
>> +	if (fb->num_planes != 1)
>> +		return -EINVAL;
>> +
>> +	/* TODO expand for other formats */
>> +	if (fb->drm_format != DRM_FORMAT_XRGB8888)
>> +		return -EINVAL;
>> +
>> +	ptr = igt_fb_map_buffer(fb->fd, fb);
>> +	igt_assert(ptr);
>> +	map = ptr;
>> +
>> +	/*
>> +	 * Framebuffers are often uncached, which can make byte-wise accesses
>> +	 * very slow. We copy each line of the FB into a local buffer to speed
>> +	 * up the hashing.
>> +	 */
>> +	line = malloc(stride);
>> +	if (!line) {
>> +		munmap(map, fb->size);
>> +		return -ENOMEM;
>> +	}
>> +
>> +	for (y = 0; y < fb->height; y++, ptr += stride) {
>> +
>> +		/* get line from buffer */
>> +		igt_memcpy_from_wc(line, ptr, fb->width * cpp);
>> +
>> +		for (x = 0; x < fb->width; x++) {
>> +			uint32_t raw_pixel = le32_to_cpu(line[x]);
>> +			igt_pixel_t pixel;
>> +			raw_pixel &= 0x00ffffff;
>> +
>> +			/*
>> +			 * unpack pixel into igt_pixel_t
>> +			 *
>> +			 * only for XRGB8888 for now
>> +			 *
>> +			 * TODO add "generic" mechanism for unpacking
>> +			 * other FB formats
>> +			 */
>> +			pixel.r = (raw_pixel & 0x00ff0000) >> 16;
>> +			pixel.g = (raw_pixel & 0x0000ff00) >> 8;
>> +			pixel.b = (raw_pixel & 0x000000ff);
>> +
>> +			/* normalize for 8-bit */
>> +			pixel.r /= (0xff);
>> +			pixel.g /= (0xff);
>> +			pixel.b /= (0xff);
>> +
>> +			/* TODO use read_rgb from igt_fb? */
>> +
>> +			/* run transform on pixel */
>> +			transform(&pixel);
>> +
>> +			/* de-normalize back to 8-bit */
>> +			pixel.r *= (0xff);
>> +			pixel.g *= (0xff);
>> +			pixel.b *= (0xff);
>> +
>> +			/* re-pack pixel into FB*/
>> +			raw_pixel = 0x0;
>> +			raw_pixel |= ((uint8_t) (lround(pixel.r) & 0xff)) << 16;
>> +			raw_pixel |= ((uint8_t) (lround(pixel.g) & 0xff)) << 8;
>> +			raw_pixel |= ((uint8_t) (lround(pixel.b) & 0xff));
>> +			/* TODO use write_rgb from igt_fb? */
>> +
>> +			/* write back to line */
>> +			line[x] = cpu_to_le32(raw_pixel);
>> +		}
>> +
>> +		/* copy line back to fb buffer */
>> +		igt_memcpy_from_wc(ptr, line, fb->width * cpp);
>> +	}
>> +
>> +	free(line);
>> +	igt_fb_unmap_buffer(fb, map);
>> +
>> +	return 0;
>> +
>> +	/* for each pixel */
>> +
>> +	/* convert to float and create igt_pixel */
>> +
>> +	/* call transform */
>> +
>> +	/* convert back to fb format from igt_pixel */
>> +
>> +
>> +}
>> +
>> +int igt_color_transform_srgb_eotf(igt_fb_t *fb)
>> +{
>> +	return igt_color_transform_pixels(fb, &igt_color_srgb_eotf);
>> +}
>> +
>> +int igt_color_transform_srgb_inv_eotf(igt_fb_t *fb)
>> +{
>> +	return igt_color_transform_pixels(fb, &igt_color_srgb_inv_eotf);
>> +}
>> +
>> +#if 0
>> +#define PRINT_PIXEL_CMP
>> +#endif
>> +
>> +bool igt_cmp_fb_component(uint16_t comp1, uint16_t comp2, uint8_t up, uint8_t down)
>> +{
>> +	int16_t diff = comp2 - comp1;
>> +
>> +	if ((diff < -down) || (diff > up)) {
>> +		printf("comp1 %x comp2 %x diff %d down %d, up %d\n", comp1, comp2, diff, -down, up);
>> +		return false;
>> +	}
>> +
>> +	return true;
>> +}
>> +
>> +bool igt_cmp_fb_pixels(igt_fb_t *fb1, igt_fb_t *fb2, uint8_t up, uint8_t down)
>> +{
>> +	uint32_t *ptr1, *ptr2;
>> +	uint32_t pixel1, pixel2, i, j;
>> +	bool matched = true;
>> +
>> +#ifdef PRINT_PIXEL_CMP
>> +	printf("hwhw: %s %d\n", __func__, __LINE__);
>> +#endif
>> +
>> +	ptr1 = igt_fb_map_buffer(fb1->fd, fb1);
>> +	ptr2 = igt_fb_map_buffer(fb2->fd, fb2);
>> +
>> +	igt_assert(fb1->drm_format == fb2->drm_format);
>> +	igt_assert(fb1->size == fb2->size);
>> +
>> +	for (i = 0; i < fb1->size / sizeof(uint32_t); i++) {
>> +		uint16_t mask = 0xff;
>> +		uint16_t shift = 8;
>> +
>> +		if (fb1->drm_format == DRM_FORMAT_XRGB2101010) {
>> +			/* ignore alpha */
>> +			pixel1 = ptr1[i] & ~0xc0000000;
>> +			pixel2 = ptr2[i] & ~0xc0000000;
>> +
>> +			mask = 0x3ff;
>> +			shift = 10;
>> +
>> +
>> +		} else if (fb1->drm_format == DRM_FORMAT_XRGB8888) {
>> +			/* ignore alpha */
>> +			pixel1 = ptr1[i] & ~0xff000000;
>> +			pixel2 = ptr2[i] & ~0xff000000;
>> +
>> +			mask = 0xff;
>> +			shift = 8;
>> +
>> +		} else {
>> +			pixel1 = ptr1[i];
>> +			pixel2 = ptr2[i];
>> +		}
>> +
>> +#ifdef PRINT_PIXEL_CMP
>> +		/* print first 5 pixels */
>> +		if (i < 5) {
>> +			printf("hwhw: %s %u\n", __func__, i);
>> +			printf("\t\traw_in\t%u\n", ptr1[i]);
>> +			printf("\t\traw_out\t%u\n", ptr2[i]);
>> +			printf("\t\tin\t%u\n", pixel1);
>> +			printf("\t\tout\t%u\n", pixel2);
>> +		}
>> +#endif
>> +
>> +		for (j = 0; j < 3; j++) {
>> +			uint16_t comp1 = (pixel1 >> (shift*j)) & mask;
>> +			uint16_t comp2 = (pixel2 >> (shift*j)) & mask;
>> +
>> +			if (!igt_cmp_fb_component(comp1, comp2, up, down)) {
>> +				/* TODO use proper log*/
>> +				printf("i %d j %d shift %d mask %x comp1 %x comp2 %x, pixel1 %x pixel2 %x\n",
>> +				       i, j, shift, mask, comp1, comp2, pixel1, pixel2);
>> +				return false;
>> +			}
>> +		}
>> +	}
>> +
>> +	igt_fb_unmap_buffer(fb1, ptr1);
>> +	igt_fb_unmap_buffer(fb2, ptr2);
>> +
>> +	return matched;
>> +}
>> +
>> +
>> +void igt_dump_fb(igt_display_t *display, igt_fb_t *fb,
>> +		 const char *path_name, const char *file_name)
>> +{
>> +	char filepath_out[PATH_MAX];
>> +	cairo_surface_t *fb_surface_out;
>> +	cairo_status_t status;
>> +
>> +	snprintf(filepath_out, PATH_MAX, "%s/%s.png", path_name, file_name);
>> +	fb_surface_out = igt_get_cairo_surface(display->drm_fd, fb);
>> +	status = cairo_surface_write_to_png(fb_surface_out, filepath_out);
>> +	igt_assert_eq(status, CAIRO_STATUS_SUCCESS);
>> +	cairo_surface_destroy(fb_surface_out);
>> +}
>> \ No newline at end of file
>> diff --git a/lib/igt_color.h b/lib/igt_color.h
>> new file mode 100644
>> index 000000000000..fc136eecfd17
>> --- /dev/null
>> +++ b/lib/igt_color.h
>> @@ -0,0 +1,105 @@
>> +/*
>> + * Copyright 2023 Advanced Micro Devices, Inc.
>> + *
>> + * 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
>> + */
>> +
>> +
>> +#ifndef __IGT_COLOR_H__
>> +#define __IGT_COLOR_H__
>> +
>> +#include <limits.h>
>> +
>> +#include "igt_fb.h"
>> +#include "igt_kms.h"
>> +
>> +/*
>> + * Below code is taken from Skia and adapted for style and needs of
>> + * IGT.
>> + *
>> + * https://chromium.googlesource.com/chromium/src/+/3e1a26c44c024d97dc9a4c09bbc6a2365398ca2c/ui/gfx/skia_color_space_util.cc#15
>> + *
>> + * To comply with the original code's license we'll include it, as well
>> + * as the original copyright here:
>> + *
>> + * // Copyright 2015 The Chromium Authors
>> + * //
>> + * // Redistribution and use in source and binary forms, with or without
>> + * // modification, are permitted provided that the following conditions are
>> + * // met:
>> + * //
>> + * //    * Redistributions of source code must retain the above copyright
>> + * // notice, this list of conditions and the following disclaimer.
>> + * //    * Redistributions in binary form must reproduce the above
>> + * // copyright notice, this list of conditions and the following disclaimer
>> + * // in the documentation and/or other materials provided with the
>> + * // distribution.
>> + * //    * Neither the name of Google LLC nor the names of its
>> + * // contributors may be used to endorse or promote products derived from
>> + * // this software without specific prior written permission.
>> + * //
>> + * // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
>> + * // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
>> + * // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
>> + * // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
>> + * // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>> + * // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>> + * // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
>> + * // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
>> + * // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
>> + * // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
>> + * // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>> + */
>> +/*
>> + * A transfer function mapping encoded values to linear values,
>> + * represented by this 7-parameter piecewise function:
>> + *
>> + *   linear = sign(encoded) *  (c*|encoded| + f)       , 0 <= |encoded| < d
>> + *          = sign(encoded) * ((a*|encoded| + b)^g + e), d <= |encoded|
>> + *
>> + * (A simple gamma transfer function sets g to gamma and a to 1.)
>> + */
>> +struct igt_color_tf {
>> +    float g, a,b,c,d,e,f;
>> +};
>> +
>> +const struct igt_color_tf srgb_tf = {2.4f, (float)(1/1.055), (float)(0.055/1.055), (float)(1/12.92), 0.04045f, 0, 0};
>> +
>> +/* end of Skia-based code */
>> +
>> +typedef struct igt_pixel {
>> +	float r;
>> +	float g;
>> +	float b;
>> +} igt_pixel_t;
>> +
>> +bool igt_cmp_fb_component(uint16_t comp1, uint16_t comp2, uint8_t up, uint8_t down);
>> +bool igt_cmp_fb_pixels(igt_fb_t *fb1, igt_fb_t *fb2, uint8_t up, uint8_t down);
>> +
>> +void igt_dump_fb(igt_display_t *display, igt_fb_t *fb, const char *path_name, const char *file_name);
>> +
>> +/* TODO also allow 64-bit pixels, or other weird sizes */
>> +typedef void (*igt_pixel_transform)(igt_pixel_t *pixel);
>> +
>> +int igt_color_transform_pixels(igt_fb_t *fb, igt_pixel_transform transform);
>> +
>> +int igt_color_transform_srgb_eotf(igt_fb_t *fb);
>> +int igt_color_transform_srgb_inv_eotf(igt_fb_t *fb);
>> +
>> +#endif
>> \ No newline at end of file
>> diff --git a/lib/igt_fb.c b/lib/igt_fb.c
>> index 0fe5b6adf8f4..0667d3fcbcff 100644
>> --- a/lib/igt_fb.c
>> +++ b/lib/igt_fb.c
>> @@ -739,7 +739,7 @@ void igt_init_fb(struct igt_fb *fb, int fd, int width, int height,
>>  	}
>>  }
>>  
>> -static uint32_t calc_plane_stride(struct igt_fb *fb, int plane)
>> +uint32_t igt_fb_calc_plane_stride(struct igt_fb *fb, int plane)
>>  {
>>  	uint32_t min_stride = fb->plane_width[plane] *
>>  		(fb->plane_bpp[plane] / 8);
>> @@ -916,7 +916,7 @@ static uint64_t calc_fb_size(struct igt_fb *fb)
>>  
>>  		/* respect the stride requested by the caller */
>>  		if (!fb->strides[plane])
>> -			fb->strides[plane] = calc_plane_stride(fb, plane);
>> +			fb->strides[plane] = igt_fb_calc_plane_stride(fb, plane);
>>  
>>  		align = get_plane_alignment(fb, plane);
>>  		if (align)
>> @@ -4471,7 +4471,7 @@ int igt_fb_get_fnv1a_crc(struct igt_fb *fb, igt_crc_t *crc)
>>  	void *map;
>>  	char *ptr;
>>  	int x, y, cpp = igt_drm_format_to_bpp(fb->drm_format) / 8;
>> -	uint32_t stride = calc_plane_stride(fb, 0);
>> +	uint32_t stride = igt_fb_calc_plane_stride(fb, 0);
>>  
>>  	if (fb->num_planes != 1)
>>  		return -EINVAL;
>> diff --git a/lib/igt_fb.h b/lib/igt_fb.h
>> index 73bdfc8669d8..b753c1580884 100644
>> --- a/lib/igt_fb.h
>> +++ b/lib/igt_fb.h
>> @@ -170,6 +170,8 @@ int igt_dirty_fb(int fd, struct igt_fb *fb);
>>  void *igt_fb_map_buffer(int fd, struct igt_fb *fb);
>>  void igt_fb_unmap_buffer(struct igt_fb *fb, void *buffer);
>>  
>> +uint32_t igt_fb_calc_plane_stride(struct igt_fb *fb, int plane);
>> +
>>  void igt_create_bo_for_fb(int fd, int width, int height,
>>  			  uint32_t format, uint64_t modifier,
>>  			  struct igt_fb *fb);
>> diff --git a/lib/meson.build b/lib/meson.build
>> index 85f100f75510..7c9aa56d429c 100644
>> --- a/lib/meson.build
>> +++ b/lib/meson.build
>> @@ -97,6 +97,7 @@ lib_sources = [
>>  	'igt_edid.c',
>>  	'igt_eld.c',
>>  	'igt_infoframe.c',
>> +	'igt_color.c',
>>  	'veboxcopy_gen12.c',
>>  	'igt_msm.c',
>>  	'igt_dsc.c',
>> -- 
>> 2.42.0
>>



More information about the igt-dev mailing list