On Friday 18 March 2005 07:07, Attila Kinali wrote:
> > > Actually, all solutions i've seen so far are too complicated.
> >
> > Then I simply didn't explain clearly. The ring buffer scheme (even
> > with definable physical page vector) is pretty much as simple as it
> > gets. It needs the following PIO registers:
> >
> > - Head register: The ring buffer offset from which the card will
> > next read an indirect DMA command.
> >
> > - Tail register: The ring buffer offset where the kernel driver
> > will next write an indirect DMA command.
> >
> > - Threshold register: The threshold below which the card will
> > generate a buffer low interrupt.
> >
> > As opposed to having a single physical base register for the command
> > ring buffer (the classic arrangement) there is a table of physical
> > pages, which I suggested can be just one page for the initial rev
> > (sufficient for a PCI card).
>
> Do i understand it correctly, that the head register is
> the "source" and the tail register the "destination" ?
The head is the "source" from the card's point of view and the "tail" is the
destination from the host's point of view. To avoid confusion, I use the
classic queue terminology: write to the tail and read from the head.
A ring buffer is simply a circular queue with a fixed maximum size. It has
very nice properties for synchronization between a "producer" (the host)
and a "consumer" (the card). The producer only has to worry about whether
there is _at least_ enough room in the ring buffer to write its data.
Between the time it checks for available space and the time it writes
something into that space, the card may remove some data from the head of
the queue, creating more space. The producer doesn't care, because it is
only worried about whether there is at least enough space, so that it
doesn't overwrite the head of the queue.
Similarly, the consumer is only worried about whether there are at least a
certain amount of data in the queue. When the tail gets far enough ahead
of the head so that it knows it has enough data to process, it can go to
work. It does not care whether the producer puts more data into the queue
while it is working on a given data chunk.
So producer and consumer can work independently, which is what we want.
Another property of a ring buffer is that the consumer owns all data above
the head (taking buffer wrap into account) and below the tail. The
producer owns all data above the tail and below the head. So the producer
can't step on the consumer's data, and the consumer can't read data that
the producer hasn't finished loading into the queue yet. The rule is: the
producer first stores the data in the queue, then advances the tail
pointer. The consumer first reads the queue data, then advances the head.
> BTW: how about replacing the threshold register by a
> DMA command that triggers an interrup ? Then it would
> be possible to insert interrupts at any arbitrary point
> ("drawing operation X has been completed") or leave it
> completely away if no interrupt is needed (when the driver
> is sure that the operation will finish before it will send
> the next commands).
Oh, right, I was actually kicking that idea around for a while then I
somehow forgot about it. It might be useful and it might not. One problem
is, after one task puts an interrupt instruction in the buffer, another
task might come along and put more data in the ring buffer, making the
first interrupt redundant. Maybe there is an elegant solution to this, but
it needs to be pondered.
The threshold method on the other hand is tried and true.
> > I should reiterate what we are avoiding with the proposed ring buffer
> > interface: a fullblown and wooly scatter/gather DMA interface.
>
> How does a scatter/gather DMA interface work ? I thought
> it was just a list of "get the blocks from there in this
> order and place them over there", or am i wrong ?
That's it, however do you think that is a simple interface? I don't. The
best you can say about it is, it's better that having to issue a bunch of
separate commands, and have to wait for each to complete before submitting
the next. With the ring buffer, we have a much nicer way of avoiding
waiting.
Regards,
Daniel
_______________________________________________
Open-graphics mailing list
[email protected]
http://lists.duskglow.com/mailman/listinfo/open-graphics
List service provided by Duskglow Consulting, LLC (www.duskglow.com)