Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KMSDRM: Garbled video with testgles2 on NVIDIA Tegra #10107

Closed
ijsf opened this issue Jun 24, 2024 · 5 comments
Closed

KMSDRM: Garbled video with testgles2 on NVIDIA Tegra #10107

ijsf opened this issue Jun 24, 2024 · 5 comments
Milestone

Comments

@ijsf
Copy link
Contributor

ijsf commented Jun 24, 2024

I've been attempting to get the latest version SDL working with the kmsdrm driver, on a NVIDIA Jetson Nano board running OE4T (OpenEmbedded for Tegra, branch kirkstone-l4t-r32.7.x).

I'm compiling SDL (main branch) with the following options:

-DSDL_OFFSCREEN=OFF -DSDL_OPENGL=OFF -DSDL_OPENGLES=ON -DSDL_X11=OFF -DSDL_WAYLAND=OFF -DSDL_KMSDRM=ON -DSDL_KMSDRM_SHARED=OFF -DSDL_STATIC=ON -DSDL_SHARED=OFF -DSDL_TESTS=ON -DCMAKE_BUILD_TYPE=Debug

Afterwards, I try to run testgles2:

./test/testgles2

Which gives me the following output:

INFO: Threaded  : no
INFO: Screen bpp: 32
INFO:
INFO: Vendor     : NVIDIA Corporation
INFO: Renderer   : NVIDIA Tegra X1 (nvgpu)/integrated
INFO: Version    : OpenGL ES 3.2 NVIDIA 32.7.4
...

Unfortunately, the result is a messed up image:

2024-06-24-03-23-31-374

The garbled image seems to show the right colors of the test however, so I'm suspecting something is wrong with the framebuffer. Perhaps a wrong stride, offset, or something like that.

This seems to happen on SDL2 (e.g. release-2.30.4) as well. So far I've tried with 2 different HDMI screens with different resolutions, as well as different SDL versions, and different test command-line arguments, all to no avail. I've also verified that KMSDRM is actually working on the device by testing another app (https://github.com/astefanutti/kms-glsl) which works perfectly.

I've also tried the suggestion in #8579 (comment) to rule out an async flip problem, to no effect.

I've been trying to analyze the kmsdrm driver for anything that might go wrong, but haven't been able to find anything so far.

@slouken slouken added this to the 2.32.0 milestone Jun 24, 2024
@ijsf
Copy link
Contributor Author

ijsf commented Jun 25, 2024

I've been trying to debug this problem and stepping through the KMSDRM and EGL code. Changing strides and such doesn't seem to have any effect at all.

However once thing I've noticed is that this platform (NVIDIA Tegra) reports having two displays, one of which seems to be a 640x480 display, possibly some internal or MIPI thing. If I look at the way the picture is garbled I'm beginning to suspect that somewhere in SDL the displays get mixed up and perhaps EGL is created using the dimensions of one screen while the GBM is using the other.

P.S. --fullscreen does not seem to be working:

ERROR: Could not lock front buffer on GBM surface
ERROR: eglSwapBuffers failed

@ijsf ijsf changed the title KMSDRM: Garbled video with testgles2 on NVIDIA Jetson Nano KMSDRM: Garbled video with testgles2 on NVIDIA Tegra Jun 25, 2024
@ijsf
Copy link
Contributor Author

ijsf commented Jun 25, 2024

I've finally found the problem on this particular platform, after testing between drm*, GBM and EGL call differences between a known working app (https://github.com/embtom/kmscube) and SDL.

There seem to be three different variants of the drmModeAddFB call: drmModeAddFB, drmModeAddFB2 and drmModeAddFB2WithModifiers. SDL uses the first variant as can be seen at https://github.com/libsdl-org/SDL/blob/release-2.30.x/src/video/kmsdrm/SDL_kmsdrmvideo.c#L360

When I replace that call with drmModeAddFB2WithModifiers instead and use the GBM bo modifiers, the test cases start working:

uint32_t format, strides[4] = {0}, handles[4] = {0}, offsets[4] = {0}, flags = 0;

w = KMSDRM_gbm_bo_get_width(bo);
h = KMSDRM_gbm_bo_get_height(bo);
format = KMSDRM_gbm_bo_get_format(bo);

uint64_t modifiers[4] = {0};
modifiers[0] = gbm_bo_get_modifier(bo);
const int num_planes = gbm_bo_get_plane_count(bo);
for (int i = 0; i < num_planes; i++) {
        strides[i] = gbm_bo_get_stride_for_plane(bo, i);
        handles[i] = gbm_bo_get_handle(bo).u32;
        offsets[i] = gbm_bo_get_offset(bo, i);
        modifiers[i] = modifiers[0];
}

if (modifiers[0]) {
        flags = DRM_MODE_FB_MODIFIERS;
}

ret = drmModeAddFB2WithModifiers(viddata->drm_fd, w, h, format, handles, strides, offsets, modifiers, &fb_info->fb_id, flags);

The GBM modifier seems to be set at 0x3000000000fe014 so I'm suspecting that the modifier must be used when creating the frame buffer. It doesn't seem that strange, as these modifiers come from GBM itself.

Swapping in the above code seems to fix the display issue, tested with release-2.30.x. If helpful I could open a PR for this issue.

(Inversely, when I changed kmscube to use drmModeAddFB2 or drmModeAddFB it showed the same display problem as SDL.)

🙊 I've also noticed that the fullscreen flag seems to be failing the test case, this seems to be due to the fullscreen logic causing a dirty surface and recreation at https://github.com/libsdl-org/SDL/blob/release-2.30.x/src/video/kmsdrm/SDL_kmsdrmopengles.c#L110 but I suspect something is not released properly as eglSwapBuffers will fail with GL_FALSE from that point on. Should probably keep this for a different issue, but just wanted to note it down for reference.

@slouken
Copy link
Collaborator

slouken commented Jun 25, 2024

Sure, a PR would be helpful, thanks! Good sleuthing. :)

@ijsf
Copy link
Contributor Author

ijsf commented Jun 25, 2024

Great, a pull request was made in #10117. One thing to note is that drmModeAddFB2WithModifiers and the newer gbm* modifier API calls seems to be a newer calls so this might break backwards compatibility with old versions of those libraries.

@ijsf
Copy link
Contributor Author

ijsf commented Jun 25, 2024

Excellent, thanks for merging 🏆

@ijsf ijsf closed this as completed Jun 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants