pipe_crc: igt-gpu-tools Reference Manual

## pipe_crc pipe_crc — Pipe CRC support |

## Functions

bool | igt_find_crc_mismatch ()
void | igt_assert_crc_equal ()
bool | igt_check_crc_equal ()
char * | igt_crc_to_string_extended ()
char * | igt_crc_to_string ()
void | igt_require_pipe_crc ()
igt_pipe_crc_t * | igt_pipe_crc_new ()
igt_pipe_crc_t * | igt_pipe_crc_new_nonblock ()
void | igt_pipe_crc_free ()
void | igt_pipe_crc_start ()
void | igt_pipe_crc_stop ()
int | igt_pipe_crc_get_crcs ()
void | igt_pipe_crc_drain ()
void | igt_pipe_crc_get_single ()
void | igt_pipe_crc_get_current ()
void | igt_pipe_crc_get_for_frame ()
void | igt_pipe_crc_collect_crc ()

## Types and Values

typedef | igt_pipe_crc_t
#define | DRM_MAX_CRC_NR
struct | igt_crc
typedef | igt_crc_t
#define | IGT_PIPE_CRC_SOURCE_AUTO
#define | AMDGPU_PIPE_CRC_SOURCE_DPRX

## Includes

    #include <igt_pipe_crc.h>

## Description

This library wraps up the kernel's support for capturing pipe CRCs into a neat and tidy package. For the detailed usage see all the functions which work on igt_pipe_crc_t. This is supported on all platforms and outputs.

Actually using pipe CRCs to write modeset tests is a bit tricky though, so there is no way to directly check a CRC: Both the details of the plane blending, color correction and other hardware and how exactly the CRC is computed at each tap point vary by hardware generation and are not disclosed.

The only way to use igt_crc_t CRCs therefore is to compare CRCs among each another either for equality or difference. Otherwise CRCs must be treated as completely opaque values. Note that not even CRCs from different pipes or tap points on the same platform can be compared. Hence only use `igt_assert_crc_equal()` to inspect CRC values captured by the same igt_pipe_crc_t object.

## Functions

### igt_find_crc_mismatch ()

    bool
    igt_find_crc_mismatch (const igt_crc_t *a,
                           const igt_crc_t *b,
                           int *index);

Check if CRC a and CRC b mismatch.

Returns true if CRC values mismatch, false otherwise;

#### Parameters

a | first pipe CRC value |
b | second pipe CRC value |
index | index of the first value that mismatched |

### igt_assert_crc_equal ()

    void
    igt_assert_crc_equal (const igt_crc_t *a,
                          const igt_crc_t *b);

Compares two CRC values and fails the testcase if they don't match with `igt_fail()`. Note that due to CRC collisions CRC based testcase can only assert that CRCs match, never that they are different. Otherwise there might be random testcase failures when different screen contents end up with the same CRC by chance.

Passing --skip-crc-compare on the command line will force this function to always pass, which can be useful in interactive debugging where you might know the test will fail, but still want the test to keep going as if it had succeeded so that you can see the on-screen behavior.

#### Parameters

a | first pipe CRC value |
b | second pipe CRC value |

### igt_check_crc_equal ()

    bool
    igt_check_crc_equal (const igt_crc_t *a,
                         const igt_crc_t *b);

Compares two CRC values and return whether they match.

#### Parameters

a | first pipe CRC value |
b | second pipe CRC value |

#### Returns

A boolean indicating whether the CRC values match

### igt_crc_to_string_extended ()

    char *
    igt_crc_to_string_extended (igt_crc_t *crc,
                                char delimiter,
                                int crc_size);

This function allocates a string and formats `crc` into it, depending on `delimiter` and `crc_size` . The caller is responsible for freeing the string.

This should only ever be used for diagnostic debug output.

#### Parameters

crc | pipe CRC value to print |
delimiter | The delimiter to use between crc words |
crc_size | the number of bytes to print per crc word (between 1 and 4) |

### igt_crc_to_string ()

    char *
    igt_crc_to_string (igt_crc_t *crc);

This function allocates a string and formats `crc` into it. The caller is responsible for freeing the string.

This should only ever be used for diagnostic debug output.

#### Parameters

crc | pipe CRC value to print |

### igt_require_pipe_crc ()

    void
    igt_require_pipe_crc (int fd);

Convenience helper to check whether pipe CRC capturing is supported by the kernel. Uses igt_skip to automatically skip the test/subtest if this isn't the case.

### igt_pipe_crc_new ()

    igt_pipe_crc_t *
    igt_pipe_crc_new (int fd,
                      enum pipe pipe,
                      const char *source);

This sets up a new pipe CRC capture object for the given `pipe` and `source` in blocking mode.

#### Parameters

pipe | display pipe to use as source |
source | CRC tap point to use as source |

#### Returns

A pipe CRC object for the given `pipe` and `source` . The library assumes that the source is always available since recent kernels support at least IGT_PIPE_CRC_SOURCE_AUTO everywhere.

### igt_pipe_crc_new_nonblock ()

    igt_pipe_crc_t *
    igt_pipe_crc_new_nonblock (int fd,
                               enum pipe pipe,
                               const char *source);

This sets up a new pipe CRC capture object for the given `pipe` and `source` in nonblocking mode.

#### Parameters

pipe | display pipe to use as source |
source | CRC tap point to use as source |

#### Returns

A pipe CRC object for the given `pipe` and `source` . The library assumes that the source is always available since recent kernels support at least IGT_PIPE_CRC_SOURCE_AUTO everywhere.

### igt_pipe_crc_free ()

    void
    igt_pipe_crc_free (igt_pipe_crc_t *pipe_crc);

Frees all resources associated with `pipe_crc` .

#### Parameters

pipe_crc | pipe CRC object |

### igt_pipe_crc_start ()

    void
    igt_pipe_crc_start (igt_pipe_crc_t *pipe_crc);

Starts the CRC capture process on `pipe_crc` .

#### Parameters

pipe_crc | pipe CRC object |

### igt_pipe_crc_stop ()

    void
    igt_pipe_crc_stop (igt_pipe_crc_t *pipe_crc);

Stops the CRC capture process on `pipe_crc` .

#### Parameters

pipe_crc | pipe CRC object |

### igt_pipe_crc_get_crcs ()

    int
    igt_pipe_crc_get_crcs (igt_pipe_crc_t *pipe_crc,
                           int n_crcs,
                           igt_crc_t **out_crcs);

Read up to `n_crcs` from `pipe_crc` . This function does not block, and will return early if not enough CRCs can be captured, if `pipe_crc` has been opened using `igt_pipe_crc_new_nonblock()`. It will block until `n_crcs` are retrieved if `pipe_crc` has been opened using `igt_pipe_crc_new()`. `out_crcs` is alloced by this function and must be released with `free()` by the caller.

Callers must start and stop the capturing themselves by calling `igt_pipe_crc_start()` and `igt_pipe_crc_stop()`. For one-shot CRC collecting look at `igt_pipe_crc_collect_crc()`.

#### Parameters

pipe_crc | pipe CRC object |
n_crcs | number of CRCs to capture |
out_crcs | buffer pointer for the captured CRC values |

#### Returns

The number of CRCs captured. Should be equal to `n_crcs` in blocking mode, but can be less (even zero) in non-blocking mode.

### igt_pipe_crc_drain ()

    void
    igt_pipe_crc_drain (igt_pipe_crc_t *pipe_crc);

Discards all currently queued CRC values from `pipe_crc` . This function does not block, and is useful to flush `pipe_crc` . Afterwards you can get a fresh CRC with `igt_pipe_crc_get_single()`.

#### Parameters

pipe_crc | pipe CRC object |

### igt_pipe_crc_get_single ()

    void
    igt_pipe_crc_get_single (igt_pipe_crc_t *pipe_crc,
                             igt_crc_t *out_crc);

Read a single `crc` from `pipe_crc` . This function blocks even when nonblocking CRC is requested.

Callers must start and stop the capturing themselves by calling `igt_pipe_crc_start()` and `igt_pipe_crc_stop()`. For one-shot CRC collecting look at `igt_pipe_crc_collect_crc()`.

If capturing has been going on for a while and a fresh crc is required, you should use `igt_pipe_crc_get_current()` instead.

#### Parameters

pipe_crc | pipe CRC object |
crc | buffer pointer for the captured CRC value |

### igt_pipe_crc_get_current ()

    void
    igt_pipe_crc_get_current (int drm_fd,
                              igt_pipe_crc_t *pipe_crc,
                              igt_crc_t *crc);

Same as `igt_pipe_crc_get_single()`, but will wait until a new CRC can be captured. This is useful for retrieving the current CRC in a more race free way than `igt_pipe_crc_drain()` + `igt_pipe_crc_get_single()`.

#### Parameters

drm_fd | Pointer to drm fd for vblank counter |
pipe_crc | pipe CRC object |
crc | buffer pointer for the captured CRC value |

### igt_pipe_crc_get_for_frame ()

    void
    igt_pipe_crc_get_for_frame (int drm_fd,
                                igt_pipe_crc_t *pipe_crc,
                                unsigned int vblank,
                                igt_crc_t *crc);

### igt_pipe_crc_collect_crc ()

    void
    igt_pipe_crc_collect_crc (igt_pipe_crc_t *pipe_crc,
                              igt_crc_t *out_crc);

Read a single CRC from `pipe_crc` . This function blocks until the CRC is retrieved, irrespective of whether `pipe_crc` has been opened with `igt_pipe_crc_new()` or `igt_pipe_crc_new_nonblock()`. `out_crc` must be allocated by the caller.

This function takes care of the pipe_crc book-keeping, it will start/stop the collection of the CRC.

This function also calls the interactive debug with the "crc" domain, so you can make use of this feature to actually see the screen that is being CRC'd.

For continuous CRC collection look at `igt_pipe_crc_start()`, `igt_pipe_crc_get_crcs()` and `igt_pipe_crc_stop()`.

#### Parameters

pipe_crc | pipe CRC object |
out_crc | buffer for the captured CRC values |

## Types and Values

### igt_pipe_crc_t

    typedef struct _igt_pipe_crc igt_pipe_crc_t;

Pipe CRC support structure. Needs to be allocated and set up with `igt_pipe_crc_new()` for a specific pipe and pipe CRC source value.

### DRM_MAX_CRC_NR

    #define DRM_MAX_CRC_NR 10

### struct igt_crc

    struct igt_crc {
    	uint32_t frame;
    	bool has_valid_frame;
    	int n_words;
    	uint32_t crc[DRM_MAX_CRC_NR];
    };

### igt_crc_t

Pipe CRC value. All other members than `frame` are private and should not be inspected by testcases.

### IGT_PIPE_CRC_SOURCE_AUTO

    #define IGT_PIPE_CRC_SOURCE_AUTO "auto"

### AMDGPU_PIPE_CRC_SOURCE_DPRX

    #define AMDGPU_PIPE_CRC_SOURCE_DPRX "dprx"