<div dir="auto">The input lag is maxframes*1000/fps ms. For 10 fps and 2 frames, the lag is 200 ms. You might also say that it's the amount of time it will take the GPU to catch up with the CPU after fence_finish returns.<div dir="auto"><br></div><div dir="auto">Hopefully that clears up performance concerns.</div><div dir="auto"><br></div><div dir="auto">Marek</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Apr 27, 2019, 4:07 PM Axel Davy <<a href="mailto:davyaxel0@gmail.com">davyaxel0@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On 27/04/2019 21:02, Rob Clark wrote:<br>
> On Sat, Apr 27, 2019 at 9:52 AM Axel Davy <<a href="mailto:davyaxel0@gmail.com" target="_blank" rel="noreferrer">davyaxel0@gmail.com</a>> wrote:<br>
>> On 27/04/2019 18:13, Rob Clark wrote:<br>
>>> On Thu, Apr 25, 2019 at 7:06 PM Marek Olšák <<a href="mailto:maraeo@gmail.com" target="_blank" rel="noreferrer">maraeo@gmail.com</a>> wrote:<br>
>>>> From: Marek Olšák <<a href="mailto:marek.olsak@amd.com" target="_blank" rel="noreferrer">marek.olsak@amd.com</a>><br>
>>>><br>
>>>> It's done by:<br>
>>>> - decrease the number of frames in flight by 1<br>
>>>> - flush before throttling in SwapBuffers<br>
>>>>     (instead of wait-then-flush, do flush-then-wait)<br>
>>>><br>
>>>> The improvement is apparent with Unigine Heaven.<br>
>>>><br>
>>>> Previously:<br>
>>>>       draw frame 2<br>
>>>>       wait frame 0<br>
>>>>       flush frame 2<br>
>>>>       present frame 2<br>
>>>><br>
>>>>       The input lag is 2 frames.<br>
>>>><br>
>>>> Now:<br>
>>>>       draw frame 2<br>
>>>>       flush frame 2<br>
>>>>       wait frame 1<br>
>>>>       present frame 2<br>
>>>><br>
>>>>       The input lag is 1 frame. Flushing is done before waiting, because<br>
>>>>       otherwise the device would be idle after waiting.<br>
>>>><br>
>>>> Nine is affected because it also uses the pipe cap.<br>
>>>> ---<br>
>>>>    src/gallium/auxiliary/util/u_screen.c         |  2 +-<br>
>>>>    src/gallium/state_trackers/dri/dri_drawable.c | 20 +++++++++----------<br>
>>>>    2 files changed, 11 insertions(+), 11 deletions(-)<br>
>>>><br>
>>>> diff --git a/src/gallium/auxiliary/util/u_screen.c b/src/gallium/auxiliary/util/u_screen.c<br>
>>>> index 27f51e0898e..410f17421e6 100644<br>
>>>> --- a/src/gallium/auxiliary/util/u_screen.c<br>
>>>> +++ b/src/gallium/auxiliary/util/u_screen.c<br>
>>>> @@ -349,21 +349,21 @@ u_pipe_screen_get_param_defaults(struct pipe_screen *pscreen,<br>
>>>>       case PIPE_CAP_MAX_VARYINGS:<br>
>>>>          return 8;<br>
>>>><br>
>>>>       case PIPE_CAP_COMPUTE_GRID_INFO_LAST_BLOCK:<br>
>>>>          return 0;<br>
>>>><br>
>>>>       case PIPE_CAP_COMPUTE_SHADER_DERIVATIVES:<br>
>>>>          return 0;<br>
>>>><br>
>>>>       case PIPE_CAP_MAX_FRAMES_IN_FLIGHT:<br>
>>>> -      return 2;<br>
>>>> +      return 1;<br>
>>> would it be safer to leave the current default and let drivers opt-in<br>
>>> to the lower # individually?  I guess triple buffering would still be<br>
>>> better for some of the smaller gpu's?<br>
>>><br>
>>> disclaimer: I haven't tested this myself or looked very closely at the<br>
>>> dri code.. so could be misunderstanding something..<br>
>>><br>
>>> BR,<br>
>>> -R<br>
>><br>
>> I think I can shed some light on the issue to justify (or not) the change.<br>
>><br>
>> If we don't do throttling and the CPU renders frames at a faster rate<br>
>> than what the GPU can render,<br>
>> the GPU can become quite late and cause huge frame lag.<br>
>><br>
>> The throttling involves forcing a (CPU) wait when a frame is presented<br>
>> if the 'x' previous images have not finished rendering.<br>
>><br>
>> The lower 'x', the lower the frame lag.<br>
>><br>
>> However if 'x' is too low (waiting current frame is rendered for<br>
>> example), the GPU can be idle until the CPU is flushing new commands.<br>
>><br>
>> Now there is a choice to be made for the value of 'x'. 1 or 2 are<br>
>> reasonable values.<br>
>><br>
>> if 'x' is 1, we wait the previous frame was rendered when we present the<br>
>> current frame. For '2' we wait the frame before.<br>
>><br>
>><br>
>> Thus for smaller gpu's, a value of 1 is better than 2 as it is more<br>
>> affected by the frame lag (as frames take longer to render).<br>
>><br>
> I get the latency aspect.. but my comment was more about latency vs<br>
> framerate (or maybe more cynically, about games vs benchmarks :-P)<br>
><br>
> BR,<br>
> -R<br>
<br>
<br>
As long at the GPU has work to do, performance should be maximized.<br>
<br>
However in the case I described below, if CPU and GPU render at about <br>
the same framerate and<br>
the framerate has some variations (whether it being the GPU taking more <br>
time for one frame, or the CPU),<br>
using more than 1 would give a bit better performance.<br>
<br>
<br>
Axel<br>
<br>
<br>
<br>
><br>
>> However if a game is rendering at a very unstable framerate (some frames<br>
>> needing more work than others), using a value of 2 is safer<br>
>> to maximize performance. (As using a value of 1 would lead to wait if we<br>
>> get a frame that takes particularly long, as using 2 smooths that a bit)<br>
>><br>
>><br>
>> I remember years ago I had extremely unstable fps when using catalyst on<br>
>> Portal for example. But I believe it is more a driver issue than a game<br>
>> issue.<br>
>><br>
>> If we assume games don't have unstable framerate, (which seems<br>
>> reasonable assumption), using 1 as default makes sense.<br>
>><br>
>><br>
>> If one wants to test experimentally for regression, the ideal test case<br>
>> if when the GPU renders at about the same framerate as the CPU feeds it.<br>
>><br>
>><br>
>><br>
>> Axel<br>
>><br>
>><br>
>><br>
>><br>
<br>
</blockquote></div>