[igt-dev] [PATCH v3 2/3] tests/kms_rotation_crc: Add HW Rotation test case for amdgpu with tiling

Kazlauskas, Nicholas nicholas.kazlauskas at amd.com
Mon Feb 22 17:35:48 UTC 2021


On 2021-02-22 10:45 a.m., Juha-Pekka Heikkila wrote:
> On 19.2.2021 19.19, Kazlauskas, Nicholas wrote:
>> On 2021-02-14 5:18 a.m., Juha-Pekka Heikkila wrote:
>>> On 12.2.2021 20.13, Kazlauskas, Nicholas wrote:
>>>> On 2021-02-03 3:56 p.m., Sung Joon Kim wrote:
>>>>> Allow amdgpu to run HW rotation IGT test case
>>>>> Added conditions to bypass all the requirements needed for intel 
>>>>> when testing amdgpu.
>>>>> Additionally, freed unused frame buffers.
>>>>> Added swizzle 64kb tiling method for amdgpu-specific.
>>>>> Updated drm header for amdgpu tiling modifiers.
>>>>>
>>>>> v2: drm_fourcc.h copied from kernel header 
>>>>> commit:8ba16d5993749c3f31fd2b49e16f0dc1e1770b9c from drm-next.
>>>>> removed igt_pipe_crc_collect_crc for intel gpu. Only on AMDGPU.
>>>>>
>>>>> v3: moved drm_fourcc.h to another patch.
>>>>> Removed creating redundant fb in prepare_crtc for amdgpu.
>>>>> Guarded display commit for amdgpu.
>>>>> Blocked cursor plane rotation for amdgpu.
>>>>> Added back tiling when creating reference fb.
>>>>>
>>>>> Signed-off-by: Sung Joon Kim <sungkim at amd.com>
>>>>
>>>> This looks okay to me now. Thanks for addressing all my feedback.
>>>>
>>>> Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas at amd.com>
>>>>
>>>> I ran a smoke test of a rebase of this patch on the latest tree and 
>>>> the tests pass. CI results are good too, so I think this looks OK to 
>>>> merge.
>>>>
>>>> I'll put this in on Monday or Tuesday provided there are no further 
>>>> concerns from Juha-Pekka or Petri Latvala.
>>>
>>> Hei
>>>
>>> Sorry I had missed original patch set hence slow to comment, now my 
>>> mail client picked up my name here. Generally things look all ok to 
>>> me with just one exception, I wish things going to lib/ will be 
>>> separated into their own patch from things going into actual test in 
>>> tests/ so later when will see changes in test there will not come 
>>> changes in view not in test itself.
>>>
>>> For those amd related changes I cannot say anything because I don't 
>>> have amd hw to try with. I'll put some comments below that just come 
>>> to my mind.
>>>
>>>>
>>>> Regards,
>>>> Nicholas Kazlauskas
>>>>
>>>>> ---
>>>>>   lib/igt_amd.c            | 192 
>>>>> +++++++++++++++++++++++++++++++++++++++
>>>>>   lib/igt_amd.h            |  14 ++-
>>>>>   lib/igt_fb.c             |  36 +++++++-
>>>>>   tests/kms_rotation_crc.c |  76 ++++++++++++----
>>>>>   4 files changed, 299 insertions(+), 19 deletions(-)
>>>>>
>>>>> diff --git a/lib/igt_amd.c b/lib/igt_amd.c
>>>>> index abd3ad96..a4e1cb59 100644
>>>>> --- a/lib/igt_amd.c
>>>>> +++ b/lib/igt_amd.c
>>>>> @@ -24,6 +24,29 @@
>>>>>   #include "igt.h"
>>>>>   #include <amdgpu_drm.h>
>>>>> +#define X0 1
>>>>> +#define X1 2
>>>>> +#define X2 4
>>>>> +#define X3 8
>>>>> +#define X4 16
>>>>> +#define X5 32
>>>>> +#define X6 64
>>>>> +#define X7 128
>>>>> +#define Y0 1
>>>>> +#define Y1 2
>>>>> +#define Y2 4
>>>>> +#define Y3 8
>>>>> +#define Y4 16
>>>>> +#define Y5 32
>>>>> +#define Y6 64
>>>>> +#define Y7 128
>>>>> +
>>>>> +struct dim2d
>>>>> +{
>>>>> +    int w;
>>>>> +    int h;
>>>>> +};
>>>>> +
>>>>>   uint32_t igt_amd_create_bo(int fd, uint64_t size)
>>>>>   {
>>>>>       union drm_amdgpu_gem_create create;
>>>>> @@ -54,3 +77,172 @@ void *igt_amd_mmap_bo(int fd, uint32_t handle, 
>>>>> uint64_t size, int prot)
>>>>>       ptr = mmap(0, size, prot, MAP_SHARED, fd, map.out.addr_ptr);
>>>>>       return ptr == MAP_FAILED ? NULL : ptr;
>>>>>   }
>>>>> +
>>>>> +unsigned int igt_amd_compute_offset(unsigned int* swizzle_pattern,
>>>>> +                       unsigned int x, unsigned int y)
>>>>> +{
>>>>> +    unsigned int offset = 0, index = 0;
>>>>> +    unsigned int blk_size_table_index = 0, interleave = 0;
>>>>> +    unsigned int channel[16] =
>>>>> +                {0, 0, 1, 1, 2, 2, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1};
>>>>> +    unsigned int i, v;
>>>>> +
>>>>> +    for (i = 0; i < 16; i++)
>>>>> +    {
>>>>> +        v = 0;
>>>>> +        if (channel[i] == 1)
>>>>> +        {
>>>>> +            blk_size_table_index = 0;
>>>>> +            interleave = swizzle_pattern[i];
>>>>> +
>>>>> +            while (interleave > 1) {
>>>>> +                blk_size_table_index++;
>>>>> +                interleave = (interleave + 1) >> 1;
>>>>> +            }
>>>>> +
>>>>> +            index = blk_size_table_index + 2;
>>>>> +            v ^= (x >> index) & 1;
>>>>> +        }
>>>>> +        else if (channel[i] == 2)
>>>>> +        {
>>>>> +            blk_size_table_index = 0;
>>>>> +            interleave = swizzle_pattern[i];
>>>>> +
>>>>> +            while (interleave > 1) {
>>>>> +                blk_size_table_index++;
>>>>> +                interleave = (interleave + 1) >> 1;
>>>>> +            }
>>>>> +
>>>>> +            index = blk_size_table_index;
>>>>> +            v ^= (y >> index) & 1;
>>>>> +        }
>>>>> +
>>>>> +        offset |= (v << i);
>>>>> +    }
>>>>> +
>>>>> +    return offset;
>>>>> +}
>>>>> +
>>>>> +unsigned int igt_amd_fb_get_blk_size_table_idx(unsigned int bpp)
>>>>> +{
>>>>> +    unsigned int element_bytes;
>>>>> +    unsigned int blk_size_table_index = 0;
>>>>> +
>>>>> +    element_bytes = bpp >> 3;
>>>>> +
>>>>> +    while (element_bytes > 1) {
>>>>> +        blk_size_table_index++;
>>>>> +        element_bytes = (element_bytes + 1) >> 1;
>>>>> +    }
>>>>> +
>>>>> +    return blk_size_table_index;
>>>>> +}
>>>>> +
>>>>> +void igt_amd_fb_calculate_tile_dimension(unsigned int bpp,
>>>>> +                       unsigned int *width, unsigned int *height)
>>>>> +{
>>>>> +    unsigned int blk_size_table_index;
>>>>> +    unsigned int blk_size_log2, blk_size_log2_256B;
>>>>> +    unsigned int width_amp, height_amp;
>>>>> +
>>>>> +    // swizzle 64kb tile block
>>>>> +    unsigned int block256_2d[][2] = {{16, 16}, {16, 8}, {8, 8}, 
>>>>> {8, 4}, {4, 4}};
>>>>> +    blk_size_log2 = 16;
>>>>> +
>>>>> +    blk_size_table_index = igt_amd_fb_get_blk_size_table_idx(bpp);
>>>>> +
>>>>> +    blk_size_log2_256B = blk_size_log2 - 8;
>>>>> +
>>>>> +    width_amp = blk_size_log2_256B / 2;
>>>>> +    height_amp = blk_size_log2_256B - width_amp;
>>>>> +
>>>>> +    *width  = (block256_2d[blk_size_table_index][0] << width_amp);
>>>>> +    *height = (block256_2d[blk_size_table_index][1] << height_amp);
>>>>> +}
>>>>> +
>>>>> +uint32_t igt_amd_fb_tiled_offset(unsigned int bpp, unsigned int 
>>>>> x_input,
>>>>> +                       unsigned int y_input, unsigned int 
>>>>> width_input)
>>>>> +{
>>>>> +    unsigned int width, height, pitch;
>>>>> +    unsigned int pb, yb, xb, blk_idx, blk_offset, addr;
>>>>> +    unsigned int blk_size_table_index, blk_size_log2;
>>>>> +    unsigned int* swizzle_pattern;
>>>>> +
>>>>> +    // swizzle 64kb tile block
>>>>> +    unsigned int sw_64k_s[][16]=
>>>>> +    {
>>>>> +        {X0, X1, X2, X3, Y0, Y1, Y2, Y3, Y4, X4, Y5, X5, Y6, X6, 
>>>>> Y7, X7},
>>>>> +        {0,  X0, X1, X2, Y0, Y1, Y2, X3, Y3, X4, Y4, X5, Y5, X6, 
>>>>> Y6, X7},
>>>>> +        {0,  0,  X0, X1, Y0, Y1, Y2, X2, Y3, X3, Y4, X4, Y5, X5, 
>>>>> Y6, X6},
>>>>> +        {0,  0,  0,  X0, Y0, Y1, X1, X2, Y2, X3, Y3, X4, Y4, X5, 
>>>>> Y5, X6},
>>>>> +        {0,  0,  0,  0,  Y0, Y1, X0, X1, Y2, X2, Y3, X3, Y4, X4, 
>>>>> Y5, X5},
>>>>> +    };
>>>>> +    igt_amd_fb_calculate_tile_dimension(bpp, &width, &height);
>>>>> +    blk_size_table_index = igt_amd_fb_get_blk_size_table_idx(bpp);
>>>>> +    blk_size_log2 = 16;
>>>>> +
>>>>> +    pitch = (width_input + (width - 1)) & (~(width - 1));
>>>>> +
>>>>> +    swizzle_pattern = sw_64k_s[blk_size_table_index];
>>>>> +
>>>>> +    pb = pitch / width;
>>>>> +    yb = y_input / height;
>>>>> +    xb = x_input / width;
>>>>> +    blk_idx = yb * pb + xb;
>>>>> +    blk_offset = igt_amd_compute_offset(swizzle_pattern,
>>>>> +                    x_input << blk_size_table_index, y_input);
>>>>> +    addr = (blk_idx << blk_size_log2) + blk_offset;
>>>>> +
>>>>> +    return (uint32_t)addr;
>>>>> +}
>>>>> +
>>>>> +void igt_amd_fb_to_tiled(struct igt_fb *dst, void *dst_buf, struct 
>>>>> igt_fb *src,
>>>>> +                       void *src_buf, unsigned int plane)
>>>>> +{
>>>>> +    uint32_t src_offset, dst_offset;
>>>>> +    unsigned int bpp = src->plane_bpp[plane];
>>>>> +    unsigned int width = dst->plane_width[plane];
>>>>> +    unsigned int height = dst->plane_height[plane];
>>>>> +    unsigned int x, y;
>>>>> +
>>>>> +    for (y = 0; y < height; y++) {
>>>>> +        for (x = 0; x < width; x++) {
>>>>> +            src_offset = src->offsets[plane];
>>>>> +            dst_offset = dst->offsets[plane];
>>>>> +
>>>>> +            src_offset += src->strides[plane] * y + x * bpp / 8;
>>>>> +            dst_offset += igt_amd_fb_tiled_offset(bpp, x, y, width);
>>>>> +
>>>>> +            switch (bpp) {
>>>>> +            case 16:
>>>>> +                *(uint16_t *)(dst_buf + dst_offset) =
>>>>> +                    *(uint16_t *)(src_buf + src_offset);
>>>>> +                break;
>>>>> +            case 32:
>>>>> +                *(uint32_t *)(dst_buf + dst_offset) =
>>>>> +                    *(uint32_t *)(src_buf + src_offset);
>>>>> +                break;
>>>>> +            }
>>>>> +        }
>>>>> +    }
>>>>> +}
>>>>> +
>>>>> +void igt_amd_fb_convert_plane_to_tiled(struct igt_fb *dst, void 
>>>>> *dst_buf,
>>>>> +                       struct igt_fb *src, void *src_buf)
>>>>> +{
>>>>> +    unsigned int plane;
>>>>> +
>>>>> +    for (plane = 0; plane < src->num_planes; plane++) {
>>>>> +        igt_require(AMD_FMT_MOD_GET(TILE, dst->modifier) ==
>>>>> +                    AMD_FMT_MOD_TILE_GFX9_64K_S);
>>>>> +        igt_amd_fb_to_tiled(dst, dst_buf, src, src_buf, plane);
>>>>> +    }
>>>>> +}
>>>>> +
>>>>> +bool igt_amd_is_tiled(uint64_t modifier)
>>>>> +{
>>>>> +    if (IS_AMD_FMT_MOD(modifier) && AMD_FMT_MOD_GET(TILE, modifier))
>>>>> +        return true;
>>>>> +    else
>>>>> +        return false;
>>>>> +}
>>>>> diff --git a/lib/igt_amd.h b/lib/igt_amd.h
>>>>> index f63d26f4..6656d901 100644
>>>>> --- a/lib/igt_amd.h
>>>>> +++ b/lib/igt_amd.h
>>>>> @@ -24,8 +24,20 @@
>>>>>   #define IGT_AMD_H
>>>>>   #include <stdint.h>
>>>>> +#include "igt_fb.h"
>>>>>   uint32_t igt_amd_create_bo(int fd, uint64_t size);
>>>>>   void *igt_amd_mmap_bo(int fd, uint32_t handle, uint64_t size, int 
>>>>> prot);
>>>>> -
>>>>> +unsigned int igt_amd_compute_offset(unsigned int* swizzle_pattern,
>>>>> +                       unsigned int x, unsigned int y);
>>>>> +unsigned int igt_amd_fb_get_blk_size_table_idx(unsigned int bpp);
>>>>> +void igt_amd_fb_calculate_tile_dimension(unsigned int bpp,
>>>>> +                       unsigned int *width, unsigned int *height);
>>>>> +uint32_t igt_amd_fb_tiled_offset(unsigned int bpp, unsigned int 
>>>>> x_input,
>>>>> +                       unsigned int y_input, unsigned int 
>>>>> width_input);
>>>>> +void igt_amd_fb_to_tiled(struct igt_fb *dst, void *dst_buf, struct 
>>>>> igt_fb *src,
>>>>> +                       void *src_buf, unsigned int plane);
>>>>> +void igt_amd_fb_convert_plane_to_tiled(struct igt_fb *dst, void 
>>>>> *dst_buf,
>>>>> +                       struct igt_fb *src, void *src_buf);
>>>>> +bool igt_amd_is_tiled(uint64_t modifier);
>>>>>   #endif /* IGT_AMD_H */
>>>>> diff --git a/lib/igt_fb.c b/lib/igt_fb.c
>>>>> index 4b9be47e..f0fcd1a7 100644
>>>>> --- a/lib/igt_fb.c
>>>>> +++ b/lib/igt_fb.c
>>>>> @@ -671,6 +671,17 @@ static uint32_t calc_plane_stride(struct 
>>>>> igt_fb *fb, int plane)
>>>>>            * so the easiest way is to align the luma stride to 256.
>>>>>            */
>>>>>           return ALIGN(min_stride, 256);
>>>>> +    } else if (fb->modifier != LOCAL_DRM_FORMAT_MOD_NONE && 
>>>>> is_amdgpu_device(fb->fd)) {
>>>>> +        /*
>>>>> +         * For amdgpu device with tiling mode
>>>>> +         */
>>>>> +        unsigned int tile_width, tile_height;
>>>>> +
>>>>> +        igt_amd_fb_calculate_tile_dimension(fb->plane_bpp[plane],
>>>>> +                     &tile_width, &tile_height);
>>>>> +        tile_width *= (fb->plane_bpp[plane] / 8);
>>>>> +
>>>>> +        return ALIGN(min_stride, tile_width);
>>>>>       } else if (is_gen12_ccs_cc_plane(fb, plane)) {
>>>>>           /* clear color always fixed to 64 bytes */
>>>>>           return 64;
>>>>> @@ -711,6 +722,18 @@ static uint64_t calc_plane_size(struct igt_fb 
>>>>> *fb, int plane)
>>>>>           size = roundup_power_of_two(size);
>>>>>           return size;
>>>>> +    } else if (fb->modifier != LOCAL_DRM_FORMAT_MOD_NONE && 
>>>>> is_amdgpu_device(fb->fd)) {
>>>>> +        /*
>>>>> +         * For amdgpu device with tiling mode
>>>>> +         */
>>>>> +        unsigned int tile_width, tile_height;
>>>>> +
>>>>> +        igt_amd_fb_calculate_tile_dimension(fb->plane_bpp[plane],
>>>>> +                     &tile_width, &tile_height);
>>>>> +        tile_height *= (fb->plane_bpp[plane] / 8);
>>>>> +
>>>>> +        return (uint64_t) fb->strides[plane] *
>>>>> +            ALIGN(fb->plane_height[plane], tile_height);
>>>>>       } else if (is_gen12_ccs_plane(fb, plane)) {
>>>>>           /* The AUX CCS surface must be page aligned */
>>>>>           return (uint64_t)fb->strides[plane] *
>>>>> @@ -2352,6 +2375,12 @@ static void free_linear_mapping(struct 
>>>>> fb_blit_upload *blit)
>>>>>           vc4_fb_convert_plane_to_tiled(fb, map, &linear->fb, 
>>>>> &linear->map);
>>>>> +        munmap(map, fb->size);
>>>>> +    } else if (igt_amd_is_tiled(fb->modifier)) {
>>>>> +        void *map = igt_amd_mmap_bo(fd, fb->gem_handle, fb->size, 
>>>>> PROT_WRITE);
>>>>> +
>>>>> +        igt_amd_fb_convert_plane_to_tiled(fb, map, &linear->fb, 
>>>>> linear->map);
>>>>> +
>>>>>           munmap(map, fb->size);
>>>>>       } else {
>>>>>           gem_munmap(linear->map, linear->fb.size);
>>>>> @@ -2419,6 +2448,10 @@ static void setup_linear_mapping(struct 
>>>>> fb_blit_upload *blit)
>>>>>           vc4_fb_convert_plane_from_tiled(&linear->fb, 
>>>>> &linear->map, fb, map);
>>>>>           munmap(map, fb->size);
>>>>> +    } else if (igt_amd_is_tiled(fb->modifier)) {
>>>>> +        linear->map = igt_amd_mmap_bo(fd, linear->fb.gem_handle,
>>>>> +                          linear->fb.size,
>>>>> +                          PROT_READ | PROT_WRITE);
>>>>>       } else {
>>>>>           /* Copy fb content to linear BO */
>>>>>           gem_set_domain(fd, linear->fb.gem_handle,
>>>>> @@ -3625,7 +3658,8 @@ cairo_surface_t *igt_get_cairo_surface(int 
>>>>> fd, struct igt_fb *fb)
>>>>>           if (use_convert(fb))
>>>>>               create_cairo_surface__convert(fd, fb);
>>>>>           else if (use_blitter(fb) || use_enginecopy(fb) ||
>>>>> -             igt_vc4_is_tiled(fb->modifier))
>>>>> +             igt_vc4_is_tiled(fb->modifier) ||
>>>>> +             igt_amd_is_tiled(fb->modifier))
>>>>>               create_cairo_surface__gpu(fd, fb);
>>>>>           else
>>>>>               create_cairo_surface__gtt(fd, fb);
>>>>> diff --git a/tests/kms_rotation_crc.c b/tests/kms_rotation_crc.c
>>>>> index e7072e20..6b0ea67c 100644
>>>>> --- a/tests/kms_rotation_crc.c
>>>>> +++ b/tests/kms_rotation_crc.c
>>>>> @@ -197,10 +197,14 @@ static void prepare_crtc(data_t *data, 
>>>>> igt_output_t *output, enum pipe pipe,
>>>>>       /* create the pipe_crc object for this pipe */
>>>>>       igt_pipe_crc_free(data->pipe_crc);
>>>>> -    igt_display_commit2(display, COMMIT_ATOMIC);
>>>>> +    /* defer crtc cleanup + crtc active for later on amd - not valid
>>>>> +     * to enable CRTC without a plane active
>>>>> +     */
>>>>> +    if (!is_amdgpu_device(data->gfx_fd))
>>>>> +        igt_display_commit2(display, COMMIT_ATOMIC);
>>>>>       data->pipe_crc = igt_pipe_crc_new(data->gfx_fd, pipe, 
>>>>> INTEL_PIPE_CRC_SOURCE_AUTO);
>>>>> -    if (start_crc)
>>>>> +    if (!is_amdgpu_device(data->gfx_fd) && start_crc)
>>>>>           igt_pipe_crc_start(data->pipe_crc);
>>>>>   }
>>>>> @@ -285,8 +289,14 @@ static void prepare_fbs(data_t *data, 
>>>>> igt_output_t *output,
>>>>>               igt_plane_set_position(plane, data->pos_x, data->pos_y);
>>>>>           igt_display_commit2(display, COMMIT_ATOMIC);
>>>>> -        igt_pipe_crc_get_current(display->drm_fd, data->pipe_crc, 
>>>>> &data->crc_rect[rect].flip_crc);
>>>>> -        igt_remove_fb(data->gfx_fd, &data->fb_flip);
>>>>> +        if (is_i915_device(data->gfx_fd)) {
>>>>> +            igt_pipe_crc_get_current(display->drm_fd, data->pipe_crc,
>>>>> +                    &data->crc_rect[rect].flip_crc);
>>>>> +            igt_remove_fb(data->gfx_fd, &data->fb_flip);
>>>>> +        } else if (is_amdgpu_device(data->gfx_fd)) {
>>>>> +            igt_pipe_crc_collect_crc(data->pipe_crc,
>>>>> +                    &data->crc_rect[rect].flip_crc);
>>>>> +        }
>>>
>>> I'm ok with this change but I was wondering why is this so for amd? 
>>> Driver on amd has crc counted all the time or crc buffer is very 
>>> short? On intel hw restarting crc counting will waste several vblanks 
>>> which can overall double execution time of this test.
>>>
>>> If crc buffer is very short on amd there is also possibility to use 
>>> igt_pipe_crc_drain(..) placed 'correctly'
>>
>> CRC generation is tied to vblank handler on AMDGPU, so the OTG needs 
>> to be running.
>>
>> I think that's the case for i915 as well, but a lot of IGT tests are 
>> written in a way that the CRTC is enabled before commiting any planes 
>> at all.
>>
>> Unfortunately we can't do the same thing on AMDGPU or we break legacy 
>> userspace and their HW cursor checks.
>>
>> See:
>> https://www.spinics.net/lists/amd-gfx/msg52208.html
>>
> 
> This is good to know. While working with these tests I can try to take 
> this issue into account.
> 
>>
>> I don't really know the best way to solve this in IGT/kernel driver at 
>> the moment, but it's kind of a mess and we run into this problem on 
>> nearly every test.
>>
>> So while collect_crc adds a two vblank overhead on every CRC capture 
>> and makes the tests run slower it at least enables the tests to run on 
>> amdgpu.
>>
> 
> For now this is bit theoretical as rotation test on amd hw will be run 
> on DRM_FORMAT_XRGB8888 but if you enable other formats for rotation 
> tests would something like below work better for this crc issue? I have 
> no way of testing it so I don't know if it's correct for amd hw, on 
> intel hw it doesn't seem to make a difference.. (I just tested it on my 
> icelake) What below does is just delay starting of crc counting until 
> there's first plane on screen.
> 
> /Juha-Pekka

Thanks for taking a look at this.

This looks theoertically OK to me, though I'm not sure what happens when 
the framebuffer gets removed if the test can continue as-is.

It'd be good if Joon can double check this on his setup as it'd help 
cleanup all the if/else surrounding the CRC checks.

Regards,
Nicholas Kazlauskas

> 
> ---
> diff --git a/tests/kms_rotation_crc.c b/tests/kms_rotation_crc.c
> index a90293442..c0ca7f3e7 100644
> --- a/tests/kms_rotation_crc.c
> +++ b/tests/kms_rotation_crc.c
> @@ -180,16 +180,13 @@ static void cleanup_crtc(data_t *data)
>   {
>       igt_display_t *display = &data->display;
> 
> -    igt_pipe_crc_free(data->pipe_crc);
> -    data->pipe_crc = NULL;
> -
>       remove_fbs(data);
> 
>       igt_display_reset(display);
>   }
> 
>   static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe 
> pipe,
> -             igt_plane_t *plane, bool start_crc)
> +             igt_plane_t *plane)
>   {
>       igt_display_t *display = &data->display;
> 
> @@ -198,14 +195,7 @@ static void prepare_crtc(data_t *data, igt_output_t 
> *output, enum pipe pipe,
>       igt_output_set_pipe(output, pipe);
>       igt_plane_set_rotation(plane, IGT_ROTATION_0);
> 
> -    /* create the pipe_crc object for this pipe */
> -    igt_pipe_crc_free(data->pipe_crc);
> -
>       igt_display_commit2(display, COMMIT_ATOMIC);
> -    data->pipe_crc = igt_pipe_crc_new(data->gfx_fd, pipe, 
> INTEL_PIPE_CRC_SOURCE_AUTO);
> -
> -    if (start_crc)
> -        igt_pipe_crc_start(data->pipe_crc);
>   }
> 
>   static void prepare_fbs(data_t *data, igt_output_t *output,
> @@ -289,11 +279,16 @@ static void prepare_fbs(data_t *data, igt_output_t 
> *output,
>               igt_plane_set_position(plane, data->pos_x, data->pos_y);
>           igt_display_commit2(display, COMMIT_ATOMIC);
> 
> -        igt_pipe_crc_get_current(display->drm_fd, data->pipe_crc,
> -                     
> &data->crc_rect[data->output_crc_in_use][rect].flip_crc);
> +        if (data->pipe_crc == NULL) {
> +            data->pipe_crc = igt_pipe_crc_new(data->gfx_fd,
> +                              output->config.pipe,
> +                              INTEL_PIPE_CRC_SOURCE_AUTO);
> 
> -        igt_remove_fb(data->gfx_fd, &data->fb_flip);
> +            igt_pipe_crc_start(data->pipe_crc);
> +        }
> 
> +        igt_pipe_crc_get_current(display->drm_fd, data->pipe_crc,
> +                     
> &data->crc_rect[data->output_crc_in_use][rect].flip_crc);
>           /*
>           * Create a reference CRC for a software-rotated fb.
>           */
> @@ -310,6 +305,7 @@ static void prepare_fbs(data_t *data, igt_output_t 
> *output,
>                        
> &data->crc_rect[data->output_crc_in_use][rect].ref_crc);
> 
>           data->crc_rect[data->output_crc_in_use][rect].valid = true;
> +        igt_remove_fb(data->gfx_fd, &data->fb_flip);
>       }
> 
>       data->last_on_screen = data->fb_flip;
> @@ -479,7 +475,7 @@ static void test_plane_rotation(data_t *data, int 
> plane_type, bool test_bad_form
>           plane = igt_output_get_plane_type(output, plane_type);
>           igt_require(igt_plane_has_prop(plane, IGT_PLANE_ROTATION));
> 
> -        prepare_crtc(data, output, pipe, plane, true);
> +        prepare_crtc(data, output, pipe, plane);
> 
>           for (i = 0; i < num_rectangle_types; i++) {
>               /* Unsupported on i915 */
> @@ -520,6 +516,8 @@ static void test_plane_rotation(data_t *data, int 
> plane_type, bool test_bad_form
>               }
>           }
>           igt_pipe_crc_stop(data->pipe_crc);
> +        igt_pipe_crc_free(data->pipe_crc);
> +        data->pipe_crc = NULL;
>       }
>   }
> 
> @@ -762,7 +760,7 @@ static void 
> test_plane_rotation_exhaust_fences(data_t *data,
> 
>       igt_require(igt_plane_has_prop(plane, IGT_PLANE_ROTATION));
> 
> -    prepare_crtc(data, output, pipe, plane, false);
> +    prepare_crtc(data, output, pipe, plane);
> 
>       mode = igt_output_get_mode(output);
>       w = mode->hdisplay;



More information about the igt-dev mailing list