Reply 160 of 183, by serdeliuk
@dreamer__ i have build dosbox-staging on my Ubuntu and generate the map file, many thanks, i will keep you posted about the progress
@dreamer__ i have build dosbox-staging on my Ubuntu and generate the map file, many thanks, i will keep you posted about the progress
While I am able to change all keys in sdl_mapper.cpp to my remote SDL_SCANCODE_XX including ctrl, alt, shift, left or right, i can change F keys with my numeric keys, but i am not able to get ctrl+key to work or alt+key. Tried the map file as well, i can change all but ctrl+key not.
I started pinball fantasies in full screen 640x468 and left/right ctrl can control flippers, but i am unable to find a way to emulate two keypress.
Also the sound and image cursivity have interruptions every 1/4 second but the cpu load is at 0.3 from 2 (two cores) is there anything to check?
Found in that SDL2 patch one issue at least: It expects that on exit all OSes have some garbage collector and will free all resources in OpenGL mode. I.e. there in few places forgotten SDL_GL_DeleteContext and/or SDL_DestroyWindow. For example, SDL_Quit_Wrapper() probably should look like this instead:
static void SDL_Quit_Wrapper(void)
{
#if SDL_VERSION_ATLEAST(2,0,0) && C_PHYSICAL_CDROM_MOUNT
Compat_SDL_CDROMQuit();
#endif
#if C_OPENGL
if (sdl.opengl.context) {
SDL_GL_DeleteContext(sdl.opengl.context);
sdl.opengl.context = 0;
}
#endif
if(sdl.window) {
SDL_DestroyWindow(sdl.window);
sdl.window =0;
}
SDL_Quit();
}
Because on OSes which do not clean resources for programmers, it will lead to issues and memory trashing.
I started dosbox with -startmapper parameter and saw that he mouse does not click where it is supposed to, however, clicked somewhere in the lower right corner and selected left control and show it is mapped to "key red", after a lot of blindly clicks on screen i was able to save the config file and for mod1 says mod_1 "key 301" "key 298" which are not my keys , my keys are 401 for BLUE and 398 for RED, could be a char/255 limitation somewhere?
However, if i try to put any existing number from any other existing keys nothing happen....
Is there anything i can do with my sound/image which goes with interruptions?
even the mouse move has interruptions
I found some other issue, but I do not know if it issue for real, or something in our SDL2 (or in our platform in general).
So, on my platform (AmigaOS4 PPC Big-Endian), I found that when I use output "texture" everything quite fast deadlocks and system completely freezes. Debugged all the stuff we found that it happens because when DosBox lock the texture (so promised to update it), it does call SDL_GetTicks, SDL_PollEvent, and SDL_SetWindowTitle. And only then do things and unlock texture. And the deadlock happens exactly because of the SDL_SetWindowTitle call.
Now, I do not know if it legal from SDL2 side to do other things with a window between lock/unlock of texture, or not, but the usage of SDL_SetWindowTittle call after locking of texture do bad things. Sure, GetTicks and PollEvent could have something to do with emulation parts (and they are probably, at least because of mouse and co), but SetWindowTitle clearly doesn't.
I do not know why it didn't happen on other oses like Windows, Linux, macOS or where else SDL2 version was checked. Maybe they robust enough, maybe they have some "internal check" and some "bad stuff auto-fix" in their runtimes, or maybe it's our OS just behave like that. Currently dunno, but logically, you can't and shouldn't call SetWindowTitle when locking the texture for updating, right?
There can be lots of workarounds for this issue of course, like postpone SetWindowTitle call, so that title will be updated after DosBox has unlocked the bitmap. Store the string, set some flag, and if flag set, then update when it's safe. But not between Lock/Unlock of texture.
Basically, it's not only about SDL2, but it also about the SDL1 version placed in the original repo too, where when HW_SURFACES used (so we have internal locking/unlocking as well), also SDL_WM_SetCaption(title,VERSION); is happening.
Anyone with a clue on the subject ?:)
kas1e, I would agree that, as a general rule, we should minimize work done between the locks to only those actions needing to be locked (similar to thread locking) - so adjusting the title of the GUI Window sounds extraneous, and should be moved outside the lock events (ideally only called on-demand for events that actually change the the title.. like pressing the cycles up or down hotkeys).
Perhaps we can also eliminate the lock/unlock from our side of the code, and instead call UpdateTexture (which is roughly 5% faster than using texture locks). Some discussion here, including Ryan C Gordon's thoughts: https://forums.libsdl.org/viewtopic.php?t=9728
@krcroft
Today I even have dead-lock without Setwindow_Title() called (so only SDL_getticks & SDL_getevents called between lock/unlock). So it seems that doing anything in between not a good idea. It will be interesting to experiment with replacing lock/unlock on UpdateTexture.
But as I read in other docs, everyone keeps saying that SDL_UpdateTexture is slower, strange!
EDIT: I think the cause of deadlocks even with removed SDL_SetWindowTitle call is can be because DosBox probably between Lock/Unlock can do some random printf() or something?
EDIT2: but probably replacing Lock()/Unlock() with UpdateTexture() will help, as even if internally it will still do locking, it means that there will be no random things between Lock/Unlock at all. So if speed will be not worse than with Lock/Unlock, then that one probably the way to go to avoid deadlocks?
Ok, replacing SDL_LockTexture/SDL_UnlockTexture in favor of SDL_UpdateTexture did the trick, and deadlocks are gone! There are changes I do to make test: https://github.com/dreamer/dosbox-staging/iss … mment-586731606
But I also found another bug, not sure if it again SDL2 code of DosBox, or our SDL2: when used output=texture, then, when I run DOSBox (and its window for sure active), to gain the speed I got with "output=surface", I need to click on desktop, and then click back to DOSBox. And then speed go normal. Maybe CPU_Enable_SkipAutoAdjust(); do not work properly with "output=texture", or its something about focus (but window surely active, just like in some slow mode). Maybe the bug is there in SDL2 code, just wasn't noticed on windows/Linux/macOS due to better speed and went unnoticed. Or maybe it indeed our SDL2 port.
EDIT: Yes, its just focus lost on startup when output=texure. I just put print() to case SDL_WINDOWEVENT_FOCUS_LOST: and when "output=surface" no prints, when "output=texture", print is here. Like some bad things happen and focus is lost somehow when "output=texture" is used. Created a ticket there: https://github.com/dreamer/dosbox-staging/issues/178
EDIT2: Compiling the latest version of DOSBox-staging for win32 (MinGW) : and issue there the same. When we use "output=texture", then focus is lost right from the beginning.
Some more progress about "focus lost" issue: focus lost also with "output=opengl", or with any output which is not surface.
I also noticed, that when we set "output=surface", then after running the window didn't close/ recreated. That why probably focus not lost.
But with output like opengl or texture, the DOSBox window closes and creates a new one, which then has loose focus.
What it means, that when we recreate a window for a new renderer which is not surface (for which window is not recreated) we didn't do something which does for the original, first window.
For output=surface, I even can see that after "splash" screen window _not_ recreated, renderer is already created and used. While for any other renderers I can see how window closes and new ones created.
Through, that kind of strange, why we did not create from beginning a window with necessary renderer? I mean from the beginning, why we create surface one, then close it, and create a new one?
The splash screen is rendered in surface, regardless of output.
> The splash screen is rendered in surface, regardless of output.
I see it, but why? Why not create one single window with the necessary renderer from the start?
Because of the need to close the original window rendered in a surface, and recreate a new window with the new renderer, we lose focus and who knows what else, because all the code from GUI_StartUp() is called only for the first window (especially part about focus). No surprise we lose focus (and who know what else) when the first window with necessary options set closed, and a new one, without those options set created.
What I mean that why there needs to create the first window be renderer in a surface if in options we have set other renderer. The window created should be just one from the beginning, without mambo-jambo as it now: "open window in a surface, render splash screen, close window, open a new one with another renderer, loose options which are set for the first window". Of course, in this case, the focus is lost. We didn't do any kind of code from GUI_StartUp() at the top when the first window created. No one worries about focus after the original window was closed, and a new one was created. And as a result, big speed drop on start when any other than surface renderer is used, because no focus => lower priority => speed drop.
I suggest writing this in an extra thread in the development forum. The devs might not follow this thread closely
kas1e: Good find about SDL_Quit_Wrapper and freeing resources on quit. I think that what you've described also applies to stock DOSBox with SDL 1.2, so the patch makes no change with regards to that.
Also good to read about SDL_LockTexture/SDL_UnlockTexture and SDL_UpdateTexture. I did use the former, as "streaming texture" indeed sounded more like DOSBox' use-case. It's also technically convenient when you need to have some buffer to fill with graphical output, possibly via some differing code segments.
A bit surprised to see that the problem (with changing the title while a texture is locked) wasn't already reproduced with SDL 1.2 builds and other outputs. Or maybe it did happen, and I just didn't spot it or don't recall such a case.
================
On the splash screen window surface: Indeed, it isn't specific to the SDL2 patch at all. I just tried to use the same code, albeit with a possible change (I think that just a resize) for when I messed with rendering this on Android.
================
On the issues with VSync:
Are the problems you're having with VSync under Linux specific to the SDL 2.0 builds? What about SDL 1.2 builds, either of vanilla DOSBox, my patch or an older revision of dosbox-staging?
I should probably add what I know about this. Basically, getting DOSBox to work well with VSync can be quite tricky. In fact, because of this, I even experimented in the past with a patch aiming to move most of the code not interacting with SDL to a separate thread.
Suppose that DOSBox runs a game in a video mode with emulated refresh rate close to 70Hz. If your host display rate is 60Hz, then DOSBox can't keep up with the rendering if it needs to show 70 distinct frames per second.
DOSBox itself does have an optimization, used to skip the output of a frame to screen if its contents are not modified. Thus, depending on your hardware, OS and their configurations, as long as a game you're running in DOSBox renders significantly less than 60 distinct frames per second, there are good chances that you won't spot any issue.
Problems start to arrive as you're getting close to 60 distinct frames per second or more. On my current setup, if I'm using a fixed amount of cycles, then DOSBox at least seems to render a game's output at a rate close to 60fps, obviously with a general slowdown. It can become much worse with cycles=max, though.
GranMinigun's comment about the fizzle fade effect in Catacomb 3-D (FizzleFade function) is a good example, along with actual gameplay with a sufficiently high amount of emulated cycles per second: https://github.com/dreamer/dosbox-staging/iss … mment-585107812
@Ny: I had no time to test but does your patch play well with the very recent SVN change to allow OpenGl shaders?
NY00123 wrote on 2020-02-18, 19:45:On the issues with VSync:
Are the problems you're having with VSync under Linux specific to the SDL 2.0 builds? What about SDL 1.2 builds, either of vanilla DOSBox, my patch or an older revision of dosbox-staging?
Linux vsync issue was the first regression we found when merging in SDL 2.0 - we decided to go on despite of it, as the benefits of SDL 2.0 are far more greater than this one regression. We're tracking this issue in #104, everyone is welcome to chime in.
NY00123 wrote on 2020-02-18, 19:45:I should probably add what I know about this. Basically, getting DOSBox to work well with VSync can be quite tricky. In fact, because of this, I even experimented in the past with a patch aiming to move most of the code not interacting with SDL to a separate thread.
Funny you mention it 😀 Just today I found, that moving SDL event handling to a separate thread is probably THE solution for DOSBox stopping rendering when the window is moving/resizing (on Windows and macOS - somehow on Linux it works OK).
NY00123 wrote on 2020-02-18, 19:45:DOSBox itself does have an optimization, used to skip the output of a frame to screen if its contents are not modified.
Really? I thought it was the games themselves doing it - e.g. in Battle Chess FPS drops to single digits when the cursor is not moving, but e.g. in Dark Forces I have stable 70FPS as soon as the map loads.
NY00123 wrote on 2020-02-18, 19:45:Problems start to arrive as you're getting close to 60 distinct frames per second or more. On my current setup, if I'm using a fixed amount of cycles, then DOSBox at least seems to render a game's output at a rate close to 60fps, obviously with a general slowdown. It can become much worse with cycles=max, though.
I recommend using `cycles=max 90%` - it's not really a compromise on emulation speed on modern machines, but it does prevent hiccups. It did not prevent vsync issue when I tested it (but the test was long time ago).
One hypothesis, that I have is that it might be a timing-related issue happening as a side-effect of new dynrec implementation. One clue, that lead me to this hypothesis was a weird regression (in SVN) in PC Player Benchmark - when running in lower resolutions (e.g. `PCPBENCH.EXE 151`), a graphical corruption appears - but only with dynrec. I did bisect this regression and it landed exactly on new dynrec implementation (but the code in that commit does not touch vga area at all - that's why I think is some weird timing-related problem). But it's just a hypothesis.
Hmm, I think I'll need to eventually run the proper git-bisect to find the change that introduced the regression… which might not be easy in this case.
| ← Ceci n'est pas une pipe
dosbox-staging
You'll likely find that it's because the core is faster than it used to be, leading to frames being rendered more often and bumping into the screen refresh rate (which is lower than the render rate) as NY00123 described, which in turn leads to frames getting delayed until the next screen refresh/ticks between frames blowing out to >20ms which screws up the cycles calculation because it's not meant to happen.
When the core is slower (i.e. normal or dynrec instead of dyn_x86) you're more likely to get partial screen updates, which don't get passed to the renderer (but can be observed in recordings). So the render rate is more likely to be below the refresh rate and doesn't get "backed up" by trying to push too many frames out.
PCPBench also has some major issues on higher end machines (once it goes over ~80fps), it starts triggering divide-by-zeros and causes all sorts of glitchiness, easily reproduced by running it on real hardware instead of DOSBox.
tl;dr: Unless you're using a screen that has a refresh rate >= 70fps, don't enable vsync.
@NY00123
Another issue is that "focus lost" thing when we use any renderer, but not surface one. The original window closes, a new one opened, focus lost and we in lower priority and worse speed (while visually window looks as active one).
Do you think it is worth/possible without much blood to rewrite patch so it will create one single window at the beginning with the necessary renderer set? I mean without needs to render splash screen in a surface, then close it, and open a new one with the necessary renderer.
In my local build, I do some scary/ugly hack: I just check in focus_event_loss if it any renderer but not surface, and then skip code coming after in that even for the first time. It works, but of course very ugly.
Dominus wrote on 2020-02-18, 20:10:@Ny: I had no time to test but does your patch play well with the very recent SVN change to allow OpenGl shaders?
Afraid that I haven't checked it so far. After briefly inspecting the changes in r4319, I think that the last revision of the SDL2 patch is incompatible with it.
jmarsh wrote on 2020-02-19, 01:45:tl;dr: Unless you're using a screen that has a refresh rate >= 70fps, don't enable vsync.
Basically this. There's a reason why sdlmain.cpp has this line of code:
SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, 0 );
I do recall being able to enable VSync on Windows with non-GL outputs, though, so you can check if you get the same problems with these.
Basically, try using fulldouble=true with output=surface or output=ddraw (albeit you may have to set aspect=false if you're using surface output).
As expected, this is the description of the fulldouble option in the .conf file:
Use double buffering in fullscreen. It can reduce screen flickering, but it can also result in a slow DOSBox.
kas1e wrote on 2020-02-19, 11:11:@NY00123 Another issue is that "focus lost" thing when we use any renderer, but not surface one. The original window closes, a n […]
@NY00123
Another issue is that "focus lost" thing when we use any renderer, but not surface one. The original window closes, a new one opened, focus lost and we in lower priority and worse speed (while visually window looks as active one).Do you think it is worth/possible without much blood to rewrite patch so it will create one single window at the beginning with the necessary renderer set? I mean without needs to render splash screen in a surface, then close it, and open a new one with the necessary renderer.
In my local build, I do some scary/ugly hack: I just check in focus_event_loss if it any renderer but not surface, and then skip code coming after in that even for the first time. It works, but of course very ugly.
That's interesting, albeit reminding me of similar issues I possibly experienced with the mouse in the past.
Doesn't seem to be reproduced for me with output=opengl and priority=higher,pause (on Linux, with X11).
Doing as suggested by you should work if you figure out how to hook the splash screen code to currently existing code, like what's used for rendering - which might be somewhat non-trivial. Or just manually add your own drawing code, which might be a bit inefficient in terms of code duplication.
But maybe the problem is elsewhere? It just sounds a bit weird to me that you can't close a window and then create a new one with focus. Then again, maybe it is a common problem not under control of the programs doing this, at least on certain platforms.
btw, you might already know this, but the window you get after the splash screen is actually the 3rd one if you're using output=opengl; Initially, DOSBox is creating an OpenGL window in order to prepare some variables and struct fields. Assuming success, it then creates a window surface for the splash screen.
NY00123 wrote on 2020-02-19, 20:33:Dominus wrote on 2020-02-18, 20:10:@Ny: I had no time to test but does your patch play well with the very recent SVN change to allow OpenGl shaders?
Afraid that I haven't checked it so far. After briefly inspecting the changes in r4319, I think that the last revision of the SDL2 patch is incompatible with it.
I haven't finished testing everything, but after I had (manually, line by line) applied the SDL2 patch to the latest SVN I kept having "dosbox window stops drawing if focus lost" and the mouse cursor up to that point would randomly be lost.
I pulled some of the "fixes" from dosbox-staging that began in this thread and suddenly everything worked that I tested, however I do say "I haven't finished" testing because up to making the changes, the conditions were not easily replicated, sometimes it would happen within a minute, sometimes it would happen after several minutes, all using texturenb and the weird thing was that even though the dosbox window stopped updating, the video capture was still going, and it was also still accepting mouse input, which tells me that it somehow lost the rendering context and Win10 thinks it's crashed. If I were to attach the Visual Studio debugger at this point, sometimes it would start working again .
Anyway, I'm attaching a few files.
The x64 Win10 binary I'm currently using with this patch applied
The sdlmain.cpp file with the patch applied (this is not enough to make SDL2 work, this is just to generate a diff against newer versions of SDL2 patch)
and hopefully a patch against the current SVN (4391 at the time of this post)
Unfortunately the versioning on my build is a little bit of a mess, SDL 2.0.13-GIT(14206), MUNT 2.4.1-GIT(with SOXR-0.1.3) and FLUIDSYNTH-1.1.x(no-glib) are in the binary. I've never had success getting vcpkg to work, so these are all git snapshots, they're all built statically with VS2019 16.7.7.
edit: deleted patch, all it did was overwrite the file.