[Mesa-dev] Proper implemtation of glFinish

Francisco Jerez currojerez at riseup.net
Tue Jan 4 05:07:00 PST 2011


Michel Dänzer <michel at daenzer.net> writes:

> On Mon, 2011-01-03 at 22:50 +0100, Francisco Jerez wrote: 
>> Bob Gleitsmann <rjgleits at bellsouth.net> writes:
>> 
>> > When trying the demo program copytex for the first time recently, I noticed 
>> > pathological behavior: after running for a long time it asserted out and 
>> > locked up X. Investigation showed this to be due to the glFinish function 
>> > acting like glFlush and not waiting as it is supposed to for completion of 
>> > whatever commands had been issued. I took up the task of remedying this.
>> 
>> Thank you for having a look at this, I've been meaning to fix it for a while.
>> 
>> > There are, as usual, a variety of different ways of doing so. Influenced by
>> > the current gallium code, I planned a separate call to the kernel to wait
>> > for the fence created by the pushbuf flush ioctl to complete. After
>> > completing the implementation in this way, it occurred to me that it would
>> > be more economical to modify the pushbuf flush ioctl call with a flag to
>> > indicate whether it should wait for completion or not. This would require
>> > modifying the FIRE_RING inline which appears in numerous places. Perhaps my
>> > original plan is adequate.  The code changes required for the original plan
>> > involve mesa, drm, and the kernel.
>> 
>> ATM the nouveau DRM API doesn't let you wait on a fence (it doesn't even have
>> the concept of "fence"), instead, you're supposed to wait for a specific
>> buffer using the CPU_PREP IOCTL. I think the simplest way to get nouveau an
>> implementation of the screen fence stuff would be something like:
>> 
>> | struct nouveau_fence {
>> |       struct nouveau_bo *bo;
>> |       boolean signalled;
>> | }
>> 
>> IOW, a fence would just hold a reference to a buffer object being rendered to
>> when the fence was created. nouveau_screen_fence_finish() would call
>> nouveau_bo_map()/unmap() with the BO as argument to make sure the fenced
>> rendering has landed. The BO selection process would look a bit like
>> r300_finish() and it could be done from nvfx/nv50_context.c.
>
> Beware that this approach will wait for *all* rendering to (and possibly
> from) that BO to finish, whereas the intended semantics are to wait only
> for the operations up to the point when the fence was created. This
> distinction probably doesn't matter for the GL state tracker so far but
> I think this will change sooner or later, and it already matters at
> least for the xorg state tracker (for the swap/dirty throttling).

Right, a "proper" implementation of pipe_fence could be done using 3D
object fences directly from userspace. I would be happy with the simple
approach I described before though, as you said this doesn't matter at
all right now.

Bob, if you're interested in doing a "full" implementation,
0x1a4/0x1d6c/0x1d70 are the nv30-nv40 3D object methods you need to
know. IIRC, the first one sets the fence DMA object handle (basically
the address space it's stored in, you could possibly allocate one using
"nouveau_notifier_alloc"), the second one selects an offset within the
DMA object, and the third one writes its argument (usually some kind of
sequence number) to the fence offset.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 229 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20110104/5d19f287/attachment-0001.pgp>


More information about the mesa-dev mailing list