http://bugs.winehq.org/show_bug.cgi?id=32096
Bug #: 32096 Summary: drawStridedSlow can be more efficient Product: Wine Version: unspecified Platform: x86 OS/Version: Linux Status: UNCONFIRMED Severity: enhancement Priority: P2 Component: directx-d3d AssignedTo: wine-bugs@winehq.org ReportedBy: guillaum.bouchard@gmail.com Classification: Unclassified
Hi,
Recently I noticed that World of Warcaft is far more slow on d3d9 mode than using the OpenGL mode on my computer (pentium 4 and geforce 5 fx). Unfortunately the OpenGL mode is unusable since last WoW update (bug is inside WoW, not wine)
D3D mode is slower because an important amount of the primitives are rendered using drawStridedSlow (dlls/wined3d/drawprim.c) which generates a lot of opengl call (here, 600K calls compared to 12K in OpenGL mode).
It appears that if the computer can handle vertex array (ie: glDrawElements/glDrawArrays/gl[Vertex|Color|TexCoords|Fog]Pointer and glClientActiveTexture) the number of openGL call can be dramatically reduced, leading to an important increase in FPS (8 to 25 in important city in WoW).
On my computer, I hacked inside drawStritedSlow and I have only one issue, the format of color is packed in BGRA, which is not compatible with the format awaited by glColorPointer. This can be fixed using the extension ARB_vertex_array_BGRA, which is unfortunately not available on my computer. I solved this issue by looping over each vertex and building a custom array in memory that I submitted to glColorPointer. I got approximately the same FPS increase using this approach.
My conclusions here are that the fallback to drawStridedSlow is a bit extreme and in most case unnecessary. In my configuration everything works except the conversion from the d3d BGRA format for color in RGBA. This part can be easily done in software to create a suitable color array. Also, I did not dig inside the shader code of wined3d, but perhaps this conversion can be simply implemented as a swizzle in the custom vertex shader. (am I right guessing that wined3d does not uses the default shader of the fixed pipeline ?).
So this bug report is more a way of opening the discussion. I see many options to improve the situation:
a) Tweak the heuristics which detects and fallbacks to drawStridedSlow. If necessary implements the needed conversions in software. But this will not generates OpenGL function call and will increase performance a bit b) Tweak the vertex shader to do the conversion in the vertex shader, I think it is our best option c) Tweak drawStridedSlow to still rely on vertex array when possible (I have an example of code which is doing this. I'm playing WoW with this since 3 days without any issue and with a FPS increase of 200%). I don't think that honestly it is the good idea. d) do something else. Because I did not read anything else than the drawStritedSlow function, I may have missed something important.
I'm motivated to help in the DX -> GL code. I'm a skilled C and GL coder, I don't know DX, but can learn enough. Thank you for reading.