[Answer myself for some of the questions]
On Mon, Mar 28, 2011 at 3:35 PM, Chia-I Wu olvaffe@gmail.com wrote:
Hi list,
I have a simple scenario that there are clients rendering to buffer objects using the CPU, and the display server compositing the buffers using OpenGL and doing page flips to present the final contents. It is like doing the following steps repeatedly
- process A (the server) allocates a bo
bo = radeon_bo_open(info->bufmgr, 0, size, align, RADEON_GEM_DOMAIN_GTT, 0);
- process B (the client) maps the bo for CPU rendering and unmaps
radeon_bo_map(bo, 1); /* ...render with CPU... */ radeon_bo_unmap(bo);
- process A renders to the back buffer using the bo as the texture
/* renders with OpenGL followed by a glFinish() */
- process A flips its front and back buffers
drmModePageFlip(fd, crtc_id, fb_id_of_the_bo, 0x0, NULL); drmWaitVBlank(fd, &vbl); /* HACK! wait until the next vblank */
With this setup, I am seeing glitches frequently. My hardware is a CEDAR. The kernel is 2.6.38-rc7 and both mesa and drm are from master. I originally ran them on a i965-based machine using libdrm_i915, and it is fine there.
I think there are sync issues in how I use libdrm_radeon, but I could not identify them. Here are my findings/questions
In 1), The bo is initially in the GTT domain because CPU rendering is expected. Using VRAM domain reduces the glitches greatly, but there are still glitches and the framerate is much lower.
In 3), glFinish() is called after rendering to make sure the frame is complete before page flipping. Does glFlush() suffice here? I think that would require page flipping to be pipelined, but I am not sure if that is the case with radeon.
Yes, it should pipelined. glFlush() suffices here.
In 4), The kernel does not block rendering to the back buffer (which was the front buffer before flipping) until the flip takes place. I think the kernel driver should be fixed because, in drm_crtc.h, it says "the implementation must return immediately and block all rendering to the current fb until the flip has completed". To workaround that, I do a drmWaitVBlank() call as a hacky way to wait for the flip to complete.
But they still do not explain the glitches I am seeing (with my limited understanding of radeon).
The hack in 4) does not work as expected. The right way to wait for the page flip to take place is to call drmModePageFlip with DRM_MODE_PAGE_FLIP_EVENT and do a blocking read. With this change, the glitches are gone (visually). But this is still a workaround and the kernel driver should be fixed.
Regards, olv