Add a test to demonstrate usage of the CMM CLU 3-D LUT. Program a blac&white 3-D LUT in the CLU and output a black&white pattern. Signed-off-by: Jacopo Mondi <jacopo.mondi@xxxxxxxxxxxxxxxx> --- tests/kms-test-clu.py | 102 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100755 tests/kms-test-clu.py diff --git a/tests/kms-test-clu.py b/tests/kms-test-clu.py new file mode 100755 index 000000000000..3df647b00339 --- /dev/null +++ b/tests/kms-test-clu.py @@ -0,0 +1,102 @@ +#!/usr/bin/python3 +# SPDX-License-Identifier: GPL-2.0-or-later +# SPDX-FileCopyrightText: 2023 Renesas Electronics Corporation + +import kmstest +import pykms + +import numpy as np + +class CluTest(kmstest.KMSTest): + """ Test the CMM color management unit 3-D LUT (CLU) capabilities by + programming a black&white 3-D LUT and display a pattern """ + + clu_table = np.ndarray((17, 17, 17, 4), np.uint16) + + def handle_page_flip(self, frame, time): + self.logger.log('Page flip complete') + + def main(self): + + # Program the black&white 3-D LUT: convert the [r, g, b] color + # components in YUV format and use the luma value only + for r in range(17): + for g in range(17): + for b in range(17): + # Compute the luma value by applying a color conversion + # matrix; also multiply each color component by 0xff as the + # CLU divides the [0, 255] scale in 17 intervals: each CLU + # increment is a 0xff increment in the color value + y = r * 0xff * 0.299 + + g * 0xff * 0.587 + b * 0xff * 0.114 + + # Re-scale the luma value in 16 bits, as that's the + # format used by DRM/KMS to represent colors (see + # struct drm_color_lut) + val = y * 0xffff / 0xff + + # Program r, g, b with the re-scaled luma value to get a + # black&white output + self.clu_table[r][g][b][0] = val + self.clu_table[r][g][b][1] = val + self.clu_table[r][g][b][2] = val + + for connector in self.output_connectors(): + self.start(f'atomic mode set on connector {connector.fullname}') + + # Skip disconnected connectors + if not connector.connected(): + self.skip('unconnected connector') + continue + + # Find a CRTC suitable for the connector + crtc = connector.get_current_crtc() + if not crtc: + crtcs = connector.get_possible_crtcs() + if len(crtcs) == 0: + pass + + crtc = crtcs[0] + + # Get the default mode for the connector + try: + mode = connector.get_default_mode() + except ValueError: + self.skip('no mode available') + continue + + self.logger.log(f'Testing connector {connector.fullname} ' + f'on CRTC {crtc.id} with mode {mode.name}') + + # Create a frame buffer and draw the usual (color) pattern + fb = pykms.DumbFramebuffer(self.card, mode.hdisplay, mode.vdisplay, 'XR24') + pykms.draw_test_pattern(fb) + + # Perform a mode set + ret = self.atomic_crtc_mode_set(crtc, connector, mode, fb) + if ret < 0: + self.fail(f'atomic mode set failed with {ret}') + continue + + # Configure the CLU by setting the LUT3D property + clu_blob = pykms.Blob(self.card, self.clu_table.flatten()) + req = kmstest.AtomicRequest(self) + req.add(crtc.primary_plane, 'FB_ID', fb.id) + req.add(connector, 'CRTC_ID', crtc.id) + req.add(crtc, { 'ACTIVE': 1 , 'LUT3D': clu_blob.id }) + ret = req.commit_sync(True) + if ret < 0: + self.fail(f'failed to set 3D LUT: {ret}') + continue + + self.logger.log('Atomic mode set complete') + self.run(5) + self.atomic_crtc_disable(crtc) + + if self.flips == 0: + self.fail('Page flip not registered') + else: + self.success() + + +if __name__ == '__main__': + CluTest().execute() -- 2.40.1