| Summary: | Software renderer produces bugs when optimizations are turned on with Visual C++ 2019 | ||
|---|---|---|---|
| Product: | SDL | Reporter: | Konrad <iryont> |
| Component: | render | Assignee: | Ryan C. Gordon <icculus> |
| Status: | RESOLVED FIXED | QA Contact: | Sam Lantinga <slouken> |
| Severity: | major | ||
| Priority: | P2 | CC: | icculus |
| Version: | HG 2.1 | ||
| Hardware: | x86_64 | ||
| OS: | Windows 10 | ||
| Attachments: | Fix | ||
|
Description
Konrad
2020-01-04 22:49:48 UTC
Visual Studio 2019 has known aggressive optimization bugs and is not recommended for production code at this time. Perhaps, but optimizations from Visual C++ 2019 are doing quite well to hardware renderers. I was hitting 1600 fps on direct3d11 backend while without any optimizations I get roughly about 800-900. Optimizations on Visual C++ 2015 do work fine though as I am able to hit about 1400 - 1500 fps on direct3d11 backend with them being enabled. Anyway, I choose to mix binaries until this issue is resolved. If you have any ideas regarding what might be optimized away and causing this issue let me know and I will gladly check it. Slow blitter seems to be working fine after all. I did assume incorrectly that it isn't since I did see bunch of calls to slow bitter while profiling the application with inefficient pixel format. Even after changing all texture format to ARGB888 which did speed up the application quite a lot compared to ABGR8888 I can still see SDL_Blit_Slow taking some time doing not sure what, exactly. This is quite interesting and I need to investigate it further more. That being said, I did force the application to use slow bitter by removing entries from SDL_GeneratedBlitFuncTable and it seems to render everything just fine. That being the case I can only assume that only auto generated blitters are affected. If I get some more free time I will investigate it more. I had some time to look at it just now and I don't think fast blitters are the ones failing here. In my case when I blend semi-transparent ARGB texture into RGB the following blitter function is chosen:
SDL_Blit_ARGB8888_RGB888_Scale
This is definitely wrong as I believe SDL_Blit_ARGB8888_RGB888_Blend should be chosen for this job instead (SDL_BLENDMODE_BLEND is used for ARGB texture).
I immediately assumed that SDL_ChooseBlitFunc might be failing and in fact when I enclose that function within pragma directive of:
#pragma optimize("", off)
SDL_ChooseBlitFunc(...)
#pragma optimize("", on)
It is correctly choosing blitting function and everything works as expected.
At first sight I cannot possibly find anything wrong there with bitwise operators, so I will have to dig deeper. At least we know what is failing.
Another hint - removing flagcheck and adding its bitwise ORed flags content directly to all "ifs" within the loop of SDL_ChooseBlitFunc allows the function to properly choose blitter.
However, I don't think the issue is there as changing:
for (i = 0; entries[i].func; ++i) {
to
while (entries[i].func) {
And adding i++ before every continue does seem to do the trick as well.
Something strange is going on within that loop when optimizations are turned on.
That being the case, the easiest "solution" to fix this issue with optimizations turned on is to add volatile for: int i, flagcheck; => volatile int i, flagcheck; Created attachment 4168 [details]
Fix
I do apologize for the spam, but since I cannot edit previous replies I'm afraid I have no choice.
I took the liberty of rewriting this function a bit as it seemed to be unnecessary extended with ifs regarding flags (we can check everything in one pass which seem to be the thing which confuses Visual C++ 2019 as well).
Also, I have made CPU features an int instead of uint because if we check it against flags which are all ints it might as well just be int (no signed/unsigned bitwise comparison).
This fix is in, thanks! https://hg.libsdl.org/SDL/rev/7efbcfc8e3cc Fixed! |