[PATCH] DRI2: Expose API to set drawable swap limit.
Mario Kleiner
mario.kleiner at tuebingen.mpg.de
Wed Oct 27 08:38:17 PDT 2010
On Oct 26, 2010, at 10:35 AM, Pauli Nieminen wrote:
> On 26/10/10 02:54 +0200, ext Mario Kleiner wrote:
>> On Oct 25, 2010, at 6:59 PM, Jesse Barnes wrote:
>>> On Mon, 25 Oct 2010 17:13:55 +0300
>>> Pauli Nieminen <ext-pauli.nieminen at nokia.com> wrote:
>>>
>>>> This allows ddx to set swap_limit if there is more than one back
>>>> buffer for drawable. Setting swap_limit has to also check if change
>>>> affects a client that is blocked.
>>>>
>>>>
...
>>>> +Bool
>>>> +DRI2SwapLimit(DrawablePtr pDraw, int swap_limit)
>>>> +{
>>>> + DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw);
>>>> + if (!pPriv)
>>>> + return FALSE;
>>>> +
>>>> + pPriv->swap_limit = swap_limit;
>>>> +
>>>> + /* Check throttling */
>>>> + if (pPriv->swapsPending >= pPriv->swap_limit)
>>>> + return TRUE;
>>>> +
>>>> + if (pPriv->target_sbc == -1 && !pPriv->blockedOnMsc) {
>>>> + if (pPriv->blockedClient) {
>>>> + AttendClient(pPriv->blockedClient);
>>>> + pPriv->blockedClient = NULL;
>>>> + }
>>>> + }
>>>> +
>>>> + return TRUE;
>>>> +}
>>
>> Ja, i think the patch is ok for doing what it does. But i think it
>> isn't sufficient to implement n-buffering reliably. We'd need more
>> clever scheduling of swaps and vblank events if multiple swaps are
>> pending.
>
<... snip ...>
> IMO, That is driver side problem. There is 2 thing missing in Intel
> driver
> for this case.
>
> - Fair scheduling/GPU preemption.
>
> Preemption would give you better latency when there is multiple
> clients with
> only one having expensive rendering operations.
>
> - Intel driver should have logic to synchronize flips with rendering.
>
> It is drivers job to know what goes on in HW side. That why Intel
> driver
> should know when rendering completes and only after that assume
> flip happens.
> If it doesn't do that then it is driver bug that has nothing to do
> with DRI2
> swap limit.
>
Yes, but it is a limitation that i think all drivers are sharing at
the moment.
>
> This patch doesn't change anything unless driver is ready to change
> swaplimit. Driver should change swaplimit only when it is good
> enough to
> handle it.
>
I'm not against merging your patch for changing the swap limit. I was
just summarizing for everybody the problems that current drivers (at
least intel and radeon and the kernel drm part of dri2) will have/
cause for a swap_limit > 1. However, currently your patch allows
changing the swap limit without approval from the ddx, which can't
handle swap_limit > 1 reliably at the moment and that's not a bug of
the ddx but a valid limitation of the current ddx implementations.
I think we should have some way for the drivers to back out of this
gracefully or at least cover their tails. E.g., allow the ddx to set
a hard upper limit for the swap_limit, in a new field max_swap_limit.
Your patch could make sure that swap_limit is never set to a value
higher than that. Then the intel and radeon ddx could set
max_swap_limit = 1 unless users somehow (xorg.conf option? dri.conf?)
opt into risky higher max_swap_limits.
Or some part of the implementation (your patch? the ddx itself?)
should output some warning in the x log if a value is selected that
it can't reliably handle, so app developers aren't confused to death
about weird behaviour.
>>
>> My idea was to solve it as follows for n-buffering. If somebody feels
>> like implementing that or something better now, instead of me in a
>> couple of weeks or months, go for it:
>>
>> 1. We maintain a little fifo queue / list of pending swap requests
>> for each drawable.
>> 2. The DRI2ScheduleSwap() function just converts the incoming
>> swapbuffers request into a little struct with all the parameters
>> (target_msc, divisor, remainder, ...) and inserts it at the tail of
>> that queue, after checking that swaps_pending < current swaplimit.
>> If (++swaps_pending) == 1, it kicks off a little
>> DRI2ReallyScheduleOneSwap() function which dequeues this first
>> request from the queue and calls into the ddx->ScheduleSwap()
>> routine. At the end of the DRI2SwapComplete() function, when a swap
>> really got completed, that DRI2ReallyScheduleOneSwap() function gets
>> called and checks if more swap requests are pending in the queue and
>> dequeues and processes the oldest request. If the queue is empty, it
>> is a no op and the whole thing goes idle again. Maybe
>> DRI2ReallyScheduleOneSwap() would also take care of msc jumps due to
>> drawables being moved between crtc's etc.
>>
>> This can't perfectly solve delays in one swapbuffer request due to
>> traffic jams in the command stream, but it could prevent that one
>> misscheduled swap will trigger the followup ones to go ugly in random
>> ways.
>>
>>
>
> This would break gl and x interaction. When swap is scheduled iver
> has to
> already exchange the to be new front in case next request is xrender
> operation affecting same pixmap/window. In that case swap buffers
> is barrier
> that allows client to assume old back buffer is already front. But
> that is
> old bug for Intel.
>
Good point. I wasn't aware of that. So something like sketched above
should/could be implemented inside the ddx instead of the common
server code. But there, where it can already exchange to the new
front, it should work, right?
> Driver might have to do other operations also for swap request. In
> that case
> driver wants knowledge for about swap request as early as possible.
>
> This patch works perfectly fine if ddx driver handles hw correctly.
> If driver
> can't handle hw right (synchronize flips with render completion)
> then driver
> should change swaplimit. Render completion is hw specific detail
> that shouldn't
> affect common code.
>
Good point.
> Also DRI2 code can't handle MSC jumps correctly without help from
> DDX driver.
> Only way to handle it right is to get MSC from old and new crtc and
> apply
> difference as offset to target_msc. Only driver can read these both
> values
> when it has to be done.
>
I half-agree, see the response to the other patch.
>> The problems with multiple clients blocking on glXWaitForMscOML or
>> glXWaitForSbcOML() is a separate issue which would need
>> implementation of additional wait queues.
>>
>
> yes. This patch doesn't try to implement the missing linked list
> for blocked
> clients.
>
Ja, that's just another todo item, unrelated to your patch.
>> And then, as we discussed on xds, there's the need for proper
>> timestamping of copyswaps in the kernel, otherwise this proposal
>> would only fix the pageflipped case, not the windowed case.
>
> yes. But that is kernel driver problem that it doesn't provide the
> info.
> Too bad copy timestamp isn't what application needs.
We need copy timestamps for non-composited desktop. pageflip
timestamps are hopefully done in a reliable way soon at the kernel
level. We had some ideas for reliable copy timestamps to implement
after pageflip timestamps are done.
> It needs MSC timestamp
> from compositor when that swap gets to screen. But that isn't
> trivial to
> implement without proved protocol. Maybe the synchronization
> extension work
> from NVIDIA could be used to provide that information.
>
Agreed, that's yet another todo.
-mario
*********************************************************************
Mario Kleiner
Max Planck Institute for Biological Cybernetics
Spemannstr. 38
72076 Tuebingen
Germany
e-mail: mario.kleiner at tuebingen.mpg.de
office: +49 (0)7071/601-1623
fax: +49 (0)7071/601-616
www: http://www.kyb.tuebingen.mpg.de/~kleinerm
*********************************************************************
"For a successful technology, reality must take precedence
over public relations, for Nature cannot be fooled."
(Richard Feynman)
More information about the xorg-devel
mailing list