From: Thomas H. <th...@tu...> - 2008-02-27 22:18:50
|
Jerome Glisse wrote: > On Wed, 27 Feb 2008 19:03:32 +0100 > Thomas Hellström <th...@tu...> wrote: > > >> Jerome Glisse wrote: >> >>> On Wed, 27 Feb 2008 17:08:41 +0100 >>> Thomas Hellström <th...@tu...> wrote: >>> >>> >>> >>>> Thomas Hellström wrote: >>>> Some additional info on this: >>>> flush() only needs to start a flush, and poll() will report it when it's >>>> done, but note that on, for example intel, the flush mechanism currently >>>> implemented doesn't have an IRQ that reports when it's done. Hence the >>>> polling part of the intel fence wait. A better way of implementing this >>>> is to have flushes go through a high-priority ring, accompanied by a >>>> user irq. Not done yet. >>>> A third way is to just add an MI_FLUSH to the ring and keep track of its >>>> execution. The disadvantage of this is that the ring might be full of >>>> rendering commands that will take a lot of time to complete and we will >>>> drain the ring waiting for idle buffers. >>>> >>>> >>> Well problem on radeon is that flush can take time ie we have to insert >>> command in the ring to flush the whole pipeline from vertex to fragment. >>> But i guess that i will need to have some real use case to see if it leads >>> to drain the ring (i hope not :)) >>> >>> >>> >>>> Note also, that if poll() sees that fc->flush_pending is non-zero, it >>>> should also start a flush and clear fc->flush_pending. It can be set to >>>> non-zero in the drm fence handler. >>>> >>>> >>> Do we really have to do this ? I mean if i get some one polling for a >>> buffer i don't want to insert flush command into the ring each time i >>> poll with fc->flush_pending being non zero, as last poll might already >>> have inserted such command. Or do i have to keep track in the driver of >>> current pending flush and have a mecanism to minize the number of flush >>> i am sending ? >>> >>> >> So what happens is that the drm fence handler calls needed_flush() when >> it has signaled a fence_type on a fence. If needed_flush() determines >> that further flushing is needed, it should then check if there is a >> flush in the command stream that would perform the required action, and >> if so return zero. A simple way to track flushes is to store the >> sequence number for the last flush. >> If that sequence number is higher than the current sequence number, no >> flush is needed, and needed_flush() would return zero. >> >> So yes, you need to check fc->pending_flush during poll, and make sure >> needed_flush() is smart enough to check the ring for previous flushes >> that would do the job, so we don't issue any unnecessary flushes. >> >> So over to the question, how does the poll() function tell that a flush >> has executed? >> One option is to have a separate list with all flushes in the ring, and >> a corresponding sequence number. Everytime we hit a new sequence number >> we check the list, and see if a flush has executed, and in that case >> call drm_fence_handler() with the correct fence_type. >> >> One other option is to use fence->native_type. When TYPE_EXE signals on >> a fence with a non-zero native_type, it will also automatically signal >> fence->native_type on itself and all previous fences. There is a problem >> with this, however, and that is that such a fence might disappear when >> it's no longer referenced by a buffer and thus we will lose track of >> that flush. This can probably be fixed with refcounting tricks, but now >> it starts to get more and more complicated. If you look in the >> intel_driver, native_type is used exactly in this way to track flushes >> that are programmed by user-space. Here, a driver-specific fence-flag is >> used to tell the intel fence driver that we have programmed an MI_FLUSH. >> However, if you look even more closely, the intel needed_flush() >> implementation ignores these user-space flushes, unless they occur on >> the current fence. This is to avoid the previously mentioned ring >> round-trip delay. >> So currently it's a bit stupid since even if a flush occurs on the next >> fence, it will go on initiating a sync_flush operation. >> >> > > Is this problematic to report several time same sequence to > drm_fence_handler ? Or does the fence code won't mind :) > No, it's OK. The only thing is that is loops through a list of unsignaled fences each time. > Btw for radeon i will use the 31bits of sequence and set it > to 1 if the fence is preceded by a RW flush, looks to be the > easiest way to know what to signal to drm_fence_handler. > Oh and i mask out this bit in the sequence number i report > to fence manager. > > Cheers, > Jerome Glisse <gl...@fr...> > Yes, seems indeed like the simplest approach. /Thomas |