diff mbox series

test: Add CLU (3D LUT) test

Message ID 20230621081250.8098-1-jacopo.mondi@ideasonboard.com (mailing list archive)
State New
Delegated to: Kieran Bingham
Headers show
Series test: Add CLU (3D LUT) test | expand

Commit Message

Jacopo Mondi June 21, 2023, 8:12 a.m. UTC
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@ideasonboard.com>
---
 tests/kms-test-clu.py | 102 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 102 insertions(+)
 create mode 100755 tests/kms-test-clu.py

--
2.40.1
diff mbox series

Patch

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()