This page describes how to use the kmsxx library and its Python bindings to test DRM/KMS drivers.
Setting up kmsxx
kmsxx has a number of dependencies:
- Python 3
- cmake (minimum version 2.8.11)
- a current build of libdrm; if your version is older than a couple of days, it is recommended to build a new one.
- a C++ compiler supporting C++11
Getting the source code
- Check out kmsxx from https://github.com/tomba/kmsxx
- Check out the pybind11 submodule:
git submodule update --init
mkdir build && cd build && cmake ..
For mode detailed instructions see the README.md file in https://github.com/tomba/kmsxx/blob/master/README.md.
Using kmsxx with the Python bindings
|Warning:||The Python bindings in mainline kmsxx are not complete. An more comprehensive set can be found here: https://github.com/uli/kmsxx/tree/topic-bindings|
It is now possible to access the driver API through kmsxx from Python:
# PYTHONPATH=build/py/:py/ python3 Python 3.4.2 (default, Oct 8 2014, 14:47:30) [GCC 4.9.1] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import pykms >>> card = pykms.Card() >>> conn = card.get_first_connected_connector() >>> crtc = conn.get_current_crtc() >>> crtc.mode.name '1024x768' [...]
A version of kmsxx that adds a handful of automated tests can be found here: https://github.com/uli/kmsxx/tree/autotest.
Invoke the test suite using
bash run_tests.sh. The output should look something like this:
aaa_sanity.py Testing connector VGA-1 PASS atomic_flip.py PASS atomic_set_plane.py FAIL atomic_small_dest.py PASS atomic_small_fb.py PASS fb_large.py PASS fb_small.py PASS mode_invalid.py PASS mode_reset.py PASS mode_set_all.py PASS 9 passed, 1 failed, 0 skipped
The test suite will exit with an error code if any tests have failed.
By default, tests are performed using the first available connector. It is possible to specify a different connector on the command line:
bash run_tests.sh 1, for instance, will use the second connector.
A version of kmsxx that includes tests for fences is available in the swsync branch of http://git.ideasonboard.com/renesas/kmsxx.git.
The fences test script is written in Python and named sync.py. It queues page flips with an in fence and arms a 500ms timer that signals the fence. The page flip handler then verifies that the flip doesn't complete before the timer fires.
The test uses the kernel sw_sync driver to signal fences in software, avoiding dependencies on other devices. The sw_sync driver must be compiled in the kernel (by enabling the CONFIG_SW_SYNC kernel option), and debugfs mounted on /sys/kernel/debug/.
If the test works, you will get an output similar to
# ./sync.py --> timeout None flipping with fence @1, timeline is @0 adding timer 11.729406 --> timeout 0.49938235800000008 fireing timer 11.729406 signaling timeline @0 --> timeout None flipping with fence @3, timeline is @2 adding timer 12.246879 --> timeout 0.49987063900000095 fireing timer 12.246879 signaling timeline @2 --> timeout None flipping with fence @5, timeline is @4 adding timer 12.750432 --> timeout 0.49989679999999836 fireing timer 12.750432 signaling timeline @4 --> timeout None flipping with fence @7, timeline is @6 adding timer 13.254087 --> timeout 0.49990999899999977
If the DRM driver doesn't support in fences, the page flip will complete too soon and the test should throw an exception:
# ./sync.py --> timeout None flipping with fence @1, timeline is @0 adding timer 41.450282 --> timeout 0.4993602780000046 terminate called after throwing an instance of 'pybind11::error_already_set' what(): RuntimeError: Page flip 1 for fence 1 complete before timeline (0)! At: ./sync.py(67): handle_page_flip ./sync.py(157): readdrm ./sync.py(175): main ./sync.py(180): <module> Aborted
By default, the test uses the first connected connector. A specific connector can be selected by name on the command line: