https://bugs.winehq.org/show_bug.cgi?id=45724
Bug ID: 45724 Summary: Multiple EndScene calls result in multiple glFlush (FF XIV) Product: Wine Version: unspecified Hardware: x86-64 OS: Linux Status: UNCONFIRMED Severity: enhancement Priority: P2 Component: directx-d3d Assignee: wine-bugs@winehq.org Reporter: awesie@gmail.com Distribution: ---
While investigating the performance of FF XIV (DirectX 9), one major issue is that it will call EndScene multiple times per frame. MSDN discourages this behavior, and on Wine it introduces a significant performance penalty because a flush is emitted for every call to wined3d_device_end_scene.
I removed the call to wined3d_cs_emit_flush in wined3d_device_end_scene which significantly improved (~40%) the fps in my test area. Mileage may vary depending on other patches.
https://bugs.winehq.org/show_bug.cgi?id=45724
--- Comment #1 from Henri Verbeet hverbeet@gmail.com --- Yeah, that glFlush() there probably isn't ideal, although I'm a little hesitant to simply remove it without more evidence that EndScene() isn't supposed to flush. I'm a little worried about interactions with queries in particular.
https://bugs.winehq.org/show_bug.cgi?id=45724
--- Comment #2 from Andrew Wesie awesie@gmail.com --- Is the concern that applications may expect EndScene (without a Present call) to flush the pipeline and they can rely on that instead of using the D3DGETDATA_FLUSH flag for queries?
While I haven't found an authoritative source regarding EndScene and flushes, a random forum post (https://www.gamedev.net/forums/topic/620095-present-without-actually-present...) states that:
"without calling Present() you can't be sure that after EndScene() the GPU will flush the pipeline"
I agree that a unit test demonstrating this behavior would be ideal.
https://bugs.winehq.org/show_bug.cgi?id=45724
--- Comment #3 from Henri Verbeet hverbeet@gmail.com --- (In reply to Andrew Wesie from comment #2)
Is the concern that applications may expect EndScene (without a Present call) to flush the pipeline and they can rely on that instead of using the D3DGETDATA_FLUSH flag for queries?
For example, yeah.
While I haven't found an authoritative source regarding EndScene and flushes, a random forum post (https://www.gamedev.net/forums/topic/620095-present-without-actually- presenting/?do=findComment&comment=4911694) states that:
"without calling Present() you can't be sure that after EndScene() the GPU will flush the pipeline"
Yeah, though what Windows drivers do in practice tends to be more important than what the documentation claims they should or shouldn't do.
I don't think we need a formal unit test for this, although that would be ideal. Some manual testing may be enough, but note that this would affect d3d8 and ddraw as well.
https://bugs.winehq.org/show_bug.cgi?id=45724
--- Comment #4 from Andrew Wesie awesie@gmail.com --- (In reply to Henri Verbeet from comment #3)
I don't think we need a formal unit test for this, although that would be ideal. Some manual testing may be enough, but note that this would affect d3d8 and ddraw as well.
Looking at the wine ddraw module, I am wondering if maybe we need the flush in EndScene iff there are no back buffers. If there is a back buffer, then the client should need to call present, which will call wglSwapBuffers and do an implicit flush. Otherwise, we are drawing directly to the front buffer and need to flush in EndScene.
https://bugs.winehq.org/show_bug.cgi?id=45724
--- Comment #5 from Henri Verbeet hverbeet@gmail.com --- (In reply to Andrew Wesie from comment #4)
(In reply to Henri Verbeet from comment #3)
I don't think we need a formal unit test for this, although that would be ideal. Some manual testing may be enough, but note that this would affect d3d8 and ddraw as well.
Looking at the wine ddraw module, I am wondering if maybe we need the flush in EndScene iff there are no back buffers. If there is a back buffer, then the client should need to call present, which will call wglSwapBuffers and do an implicit flush. Otherwise, we are drawing directly to the front buffer and need to flush in EndScene.
I seem to recall that it shouldn't be possible to create a front buffer with DDSCAPS_3DDEVICE, but I may be misremembering. Note that ddraw never has real front/back buffers though; it always draws offscreen and then goes through ddraw_surface_update_frontbuffer() to get things to the screen.
https://bugs.winehq.org/show_bug.cgi?id=45724
--- Comment #6 from Andrew Wesie awesie@gmail.com --- (In reply to Henri Verbeet from comment #5)
I seem to recall that it shouldn't be possible to create a front buffer with DDSCAPS_3DDEVICE, but I may be misremembering. Note that ddraw never has real front/back buffers though; it always draws offscreen and then goes through ddraw_surface_update_frontbuffer() to get things to the screen.
Thanks, I missed it at first glance.
I modified the d3d9 occlusion query test to check if it gets flushed implicitly, flushed implicitly with BeginScene / Draw / EndScene, and then flushed explicitly. This revised test passes on my Windows 10 x64 installation when using Intel GPU. It does not pass with AMD GPU because the query is flushed implicitly (e.g. even without the BeginScene / EndScene).
With my previous patch to wined3d query and the attached patch to remove glFlush from wined3d_device_end_scene, the revised test also passes on Wine. Obviously without removing glFlush from wined3d_device_end_scene, it does not pass.
https://bugs.winehq.org/show_bug.cgi?id=45724
--- Comment #7 from Andrew Wesie awesie@gmail.com --- Created attachment 62232 --> https://bugs.winehq.org/attachment.cgi?id=62232 Test case using occlusion query
https://bugs.winehq.org/show_bug.cgi?id=45724
--- Comment #8 from Andrew Wesie awesie@gmail.com --- Created attachment 62233 --> https://bugs.winehq.org/attachment.cgi?id=62233 Patch to remove flush
https://bugs.winehq.org/show_bug.cgi?id=45724
zzzzzyzz@hacari.org changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |zzzzzyzz@hacari.org
https://bugs.winehq.org/show_bug.cgi?id=45724
--- Comment #9 from Henri Verbeet hverbeet@gmail.com --- (In reply to Andrew Wesie from comment #6)
I modified the d3d9 occlusion query test to check if it gets flushed implicitly, flushed implicitly with BeginScene / Draw / EndScene, and then flushed explicitly. This revised test passes on my Windows 10 x64 installation when using Intel GPU. It does not pass with AMD GPU because the query is flushed implicitly (e.g. even without the BeginScene / EndScene).
Perhaps that's good enough as an indicator that the D3D runtime doesn't flush on EndScene(), for d3d9 at least. At the same time, I think the AMD result also highlights the danger of this kind of change. Even if the change itself is correct, there's potential for this to break things. I'd be willing to sign-off on this one though, provided you'll keep an eye on any regressions.
https://bugs.winehq.org/show_bug.cgi?id=45724
André H. nerv@dawncrow.de changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |nerv@dawncrow.de Fixed by SHA1| |504380a2b3122d7a44c20fd96a1 | |2d8309fdf1822 Status|UNCONFIRMED |RESOLVED Resolution|--- |FIXED
--- Comment #10 from André H. nerv@dawncrow.de --- fixed by https://source.winehq.org/git/wine.git/commitdiff/504380a2b3122d7a44c20fd96a...
https://bugs.winehq.org/show_bug.cgi?id=45724
Alexandre Julliard julliard@winehq.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |CLOSED
--- Comment #11 from Alexandre Julliard julliard@winehq.org --- Closing bugs fixed in 3.17.
https://bugs.winehq.org/show_bug.cgi?id=45724
Michael Stefaniuc mstefani@winehq.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Target Milestone|--- |3.0.x
https://bugs.winehq.org/show_bug.cgi?id=45724
Michael Stefaniuc mstefani@winehq.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Target Milestone|3.0.x |---
--- Comment #12 from Michael Stefaniuc mstefani@winehq.org --- Removing the 3.0.x milestone from bug fixes included in 3.0.5.