[igt-dev] [PATCH i-g-t 6/7] tests/kms_ccs: Generate compressed surfaces with rendercopy
Ville Syrjälä
ville.syrjala at linux.intel.com
Fri Feb 22 16:13:58 UTC 2019
On Thu, Feb 21, 2019 at 06:41:08AM -0800, Dhinakaran Pandiyan wrote:
> lib/igt_fb.c now has capability to make use of rendercopy, which means
> we do not have to handwrite compressed buffers.
>
> Cc: Clinton Taylor <clinton.a.taylor at intel.com>
> Cc: Ville Syrjälä <ville.syrjala at linux.intel.com>
> Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan at intel.com>
> ---
> tests/kms_ccs.c | 202 ++++++++++++------------------------------------
> 1 file changed, 49 insertions(+), 153 deletions(-)
>
> diff --git a/tests/kms_ccs.c b/tests/kms_ccs.c
> index 42596a45..8cbf100f 100644
> --- a/tests/kms_ccs.c
> +++ b/tests/kms_ccs.c
> @@ -60,13 +60,14 @@ typedef struct {
> igt_pipe_crc_t *pipe_crc;
> } data_t;
>
> -#define RED 0x00ff0000
> -#define COMPRESSED_RED 0x0ff0000f
> -#define GREEN 0x0000ff00
> -#define COMPRESSED_GREEN 0x000ff00f
> -
> -#define CCS_UNCOMPRESSED 0x0
> -#define CCS_COMPRESSED 0x55
> +const struct {
static
> + double r;
> + double g;
> + double b;
> +} colors[2] = {
> + {1.0, 0.0, 0.0},
> + {0.0, 1.0, 0.0}
> +};
>
> /*
> * Limit maximum used sprite plane width so this test will not mistakenly
> @@ -192,104 +193,32 @@ static bool plane_has_format_with_ccs(data_t *data, igt_plane_t *plane, uint32_t
> return false;
> }
>
> -static void render_fb(data_t *data, uint32_t gem_handle, unsigned int size,
> - enum test_fb_flags fb_flags,
> - int height, unsigned int stride)
> +static void addfb_init(struct igt_fb *fb, struct drm_mode_fb_cmd2 *f)
> {
> - uint32_t *ptr;
> - unsigned int half_height, half_size;
> - uint32_t uncompressed_color = data->plane ? GREEN : RED;
> - uint32_t compressed_color =
> - data->plane ? COMPRESSED_GREEN : COMPRESSED_RED;
> - uint32_t bad_color = RED;
> int i;
>
> - ptr = gem_mmap__cpu(data->drm_fd, gem_handle, 0, size,
> - PROT_READ | PROT_WRITE);
> + f->width = fb->width;
> + f->height = fb->height;
> + f->pixel_format = fb->drm_format;
> + f->flags = LOCAL_DRM_MODE_FB_MODIFIERS;
>
> - if (fb_flags & FB_COMPRESSED) {
> - /* In the compressed case, we want the top half of the
> - * surface to be uncompressed and the bottom half to be
> - * compressed.
> - *
> - * We need to cut the surface on a CCS cache-line boundary,
> - * otherwise, we're going to be in trouble when we try to
> - * generate CCS data for the surface. A cache line in the
> - * CCS is 16x16 cache-line-pairs in the main surface. 16
> - * cache lines is 64 rows high.
> - */
> - half_height = ALIGN(height, 128) / 2;
> - half_size = half_height * stride;
> - for (i = 0; i < size / 4; i++) {
> - if (i < half_size / 4)
> - ptr[i] = uncompressed_color;
> - else
> - ptr[i] = compressed_color;
> - }
> - } else {
> - /* When we're displaying the primary plane underneath a
> - * sprite plane, cut out a 128 x 128 area (less than the sprite)
> - * plane size which we paint red, so we know easily if it's
> - * bad.
> - */
> - for (i = 0; i < size / 4; i++) {
> - if ((fb_flags & FB_HAS_PLANE) &&
> - (i / (stride / 4)) < 128 &&
> - (i % (stride / 4)) < 128) {
> - ptr[i] = bad_color;
> - } else {
> - ptr[i] = uncompressed_color;
> - }
> - }
> + for (i = 0; i < fb->num_planes; i++) {
> + f->handles[i] = fb->gem_handle;
> + f->modifier[i] = fb->modifier;
> + f->pitches[i] = fb->strides[i];
> + f->offsets[i] = fb->offsets[i];
> }
> -
> - munmap(ptr, size);
> -}
> -
> -static unsigned int
> -y_tile_y_pos(unsigned int offset, unsigned int stride)
> -{
> - unsigned int y_tiles, y;
> - y_tiles = (offset / 4096) / (stride / 128);
> - y = y_tiles * 32 + ((offset & 0x1f0) >> 4);
> - return y;
> -}
> -
> -static void render_ccs(data_t *data, uint32_t gem_handle,
> - uint32_t offset, uint32_t size,
> - int height, unsigned int ccs_stride)
> -{
> - unsigned int half_height, ccs_half_height;
> - uint8_t *ptr;
> - int i;
> -
> - half_height = ALIGN(height, 128) / 2;
> - ccs_half_height = half_height / 16;
> -
> - ptr = gem_mmap__cpu(data->drm_fd, gem_handle, offset, size,
> - PROT_READ | PROT_WRITE);
> -
> - for (i = 0; i < size; i++) {
> - if (y_tile_y_pos(i, ccs_stride) < ccs_half_height)
> - ptr[i] = CCS_UNCOMPRESSED;
> - else
> - ptr[i] = CCS_COMPRESSED;
> - }
> -
> - munmap(ptr, size);
> }
>
> static void generate_fb(data_t *data, struct igt_fb *fb,
> int width, int height,
> enum test_fb_flags fb_flags)
> {
> - struct local_drm_mode_fb_cmd2 f = {};
> - unsigned int size[2];
> + struct drm_mode_fb_cmd2 f = {0};
> + uint32_t format;
> uint64_t modifier;
> + cairo_t *cr;
> int ret;
> - uint32_t ccs_handle;
> -
> - memset(fb, 0, sizeof(*fb));
>
> /* Use either compressed or Y-tiled to test. However, given the lack of
> * available bandwidth, we use linear for the primary plane when
> @@ -303,74 +232,52 @@ static void generate_fb(data_t *data, struct igt_fb *fb,
> else
> modifier = 0;
>
> - f.flags = LOCAL_DRM_MODE_FB_MODIFIERS;
> - f.width = width;
> - f.height = height;
> -
> if (data->flags & TEST_BAD_PIXEL_FORMAT)
> - f.pixel_format = DRM_FORMAT_RGB565;
> + format = DRM_FORMAT_RGB565;
> else
> - f.pixel_format = DRM_FORMAT_XRGB8888;
> + format = DRM_FORMAT_XRGB8888;
>
> - f.pitches[0] = ALIGN(width * 4, 128);
> - f.modifier[0] = modifier;
> - f.offsets[0] = 0;
> - size[0] = f.pitches[0] * ALIGN(height, 32);
> + igt_create_bo_for_fb(data->drm_fd, width, height, format, modifier, fb);
Hmm. So we're allocating the bo based on the original parameters. The
original code allocates based on the adjust aux stride for
FB_MISALIGN_AUX_STRIDE and FB_SMALL_AUX_STRIDE. But since those just
reduce the stride they can't fail spuriously since the original buffer
size will be big enough.
So looks like this should work just fine
Reviewed-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
> + igt_assert(fb->gem_handle > 0);
>
> - if (fb_flags & FB_COMPRESSED) {
> - /* From the Sky Lake PRM, Vol 12, "Color Control Surface":
> - *
> - * "The compression state of the cache-line pair is
> - * specified by 2 bits in the CCS. Each CCS cache-line
> - * represents an area on the main surface of 16x16 sets
> - * of 128 byte Y-tiled cache-line-pairs. CCS is always Y
> - * tiled."
> - *
> - * A "cache-line-pair" for a Y-tiled surface is two
> - * horizontally adjacent cache lines. When operating in
> - * bytes and rows, this gives us a scale-down factor of
> - * 32x16. Since the main surface has a 32-bit format, we
> - * need to multiply width by 4 to get bytes.
> - */
> - int ccs_width = ALIGN(width * 4, 32) / 32;
> - int ccs_height = ALIGN(height, 16) / 16;
> - int ccs_pitches = ALIGN(ccs_width * 1, 128);
> - int ccs_offsets = size[0];
> + addfb_init(fb, &f);
>
> + if (fb_flags & FB_COMPRESSED) {
> if (fb_flags & FB_MISALIGN_AUX_STRIDE) {
> igt_skip_on_f(width <= 1024,
> "FB already has the smallest possible stride\n");
> - ccs_pitches -= 64;
> + f.pitches[1] -= 64;
> }
> - else if (fb_flags & FB_SMALL_AUX_STRIDE) {
> +
> + if (fb_flags & FB_SMALL_AUX_STRIDE) {
> igt_skip_on_f(width <= 1024,
> "FB already has the smallest possible stride\n");
> - ccs_pitches = ALIGN(ccs_width/2, 128);
> + f.pitches[1] = ALIGN(f.pitches[1]/2, 128);
> }
>
> - size[1] = ccs_pitches * ALIGN(ccs_height, 32);
> -
> - f.handles[0] = gem_create(data->drm_fd, size[0] + size[1]);
> - if (data->flags & TEST_BAD_CCS_HANDLE) {
> - /* Put the CCS buffer on a different BO. */
> - ccs_handle = gem_create(data->drm_fd, size[0] + size[1]);
> - } else
> - ccs_handle = f.handles[0];
> + if (fb_flags & FB_ZERO_AUX_STRIDE)
> + f.pitches[1] = 0;
>
> - if (!(data->flags & TEST_NO_AUX_BUFFER)) {
> - f.modifier[1] = modifier;
> - f.handles[1] = ccs_handle;
> - f.offsets[1] = ccs_offsets;
> - f.pitches[1] = (fb_flags & FB_ZERO_AUX_STRIDE)? 0:ccs_pitches;
> + /* Put the CCS buffer on a different BO. */
> + if (data->flags & TEST_BAD_CCS_HANDLE)
> + f.handles[1] = gem_create(data->drm_fd, fb->size);
>
> - render_ccs(data, f.handles[1], f.offsets[1], size[1],
> - height, ccs_pitches);
> + if (data->flags & TEST_NO_AUX_BUFFER) {
> + f.handles[1] = 0;
> + f.modifier[1] = 0;
> + f.pitches[1] = 0;
> + f.offsets[1] = 0;
> }
> - } else {
> - f.handles[0] = gem_create(data->drm_fd, size[0]);
> }
>
> - render_fb(data, f.handles[0], size[0], fb_flags, height, f.pitches[0]);
> + if (!(data->flags & TEST_BAD_PIXEL_FORMAT)) {
> + int c = !!data->plane;
> +
> + cr = igt_get_cairo_ctx(data->drm_fd, fb);
> + igt_paint_color(cr, 0, 0, width, height,
> + colors[c].r, colors[c].g, colors[c].b);
> + igt_put_cairo_ctx(data->drm_fd, fb, cr);
> + }
>
> ret = drmIoctl(data->drm_fd, LOCAL_DRM_IOCTL_MODE_ADDFB2, &f);
> if (data->flags & TEST_FAIL_ON_ADDFB2) {
> @@ -381,17 +288,6 @@ static void generate_fb(data_t *data, struct igt_fb *fb,
> igt_assert_eq(ret, 0);
>
> fb->fb_id = f.fb_id;
> - fb->fd = data->drm_fd;
> - fb->gem_handle = f.handles[0];
> - fb->is_dumb = false;
> - fb->drm_format = f.pixel_format;
> - fb->width = f.width;
> - fb->height = f.height;
> - fb->strides[0] = f.pitches[0];
> - fb->modifier = f.modifier[0];
> - fb->size = size[0];
> - fb->cairo_surface = NULL;
> - fb->domain = 0;
> }
>
> static bool try_config(data_t *data, enum test_fb_flags fb_flags,
> --
> 2.17.1
--
Ville Syrjälä
Intel
More information about the igt-dev
mailing list