-
Notifications
You must be signed in to change notification settings - Fork 70
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to mix GDI and Direct3D #269
Comments
I thought that GDI hasn't worked in exclusive fullscreen mode since DWM was introduced, or at least not since Windows 8 when DWM became mandatory and borderless fullscreen mode was added for ddraw/D3D8. I don't have a way to verify this anymore, but I guess in Vista and 7 it worked because DWM could turn itself off, and on Windows 8+ it still works because ddraw and D3D8 run in borderless fullscreen mode by default. However, this is not the case for D3D9 according to this post: Unfortunately, I found no way to enable the same kind of borderless windowed presentation mode for D3D9 either. The shim and the registry settings don't seem to do anything. I can reproduce the problem with Indiana Jones and the Emperor's Tomb. According to PresentMon, with native D3D8 it uses "Composed: Copy with GPU GDI", but with d3d8to9 it uses "Hardware Composed: Independent Flip", no matter what I do. For comparison, DirectDraw natively also uses "Composed: Copy with GPU GDI" and can display GDI content and other top-level windows in fullscreen mode. With the DXPrimaryEmulation -DisableMaxWindowedMode shim, the process doesn't show up in PresentMon, so I'm not quite sure what it uses, but I think it should be "Hardware: Legacy Flip", based on my memory from very old testing. In this mode, neither GDI rendering on the fullscreen window itself, nor any other top level windows above it are displayed (e.g. dialog windows or popup menus). "Hardware Composed: Independent Flip" seems a bit different in that it allows other top level windows to show up, but I'm guessing it still prevents GDI from drawing on any window that uses a Direct3D 9 swapchain. Most likely, Independent Flip mode simply wasn't activated in older Windows versions, and now it seems rather difficult to get rid of. There is some more info about the various presentation modes here: https://wiki.special-k.info/en/SwapChain |
I followed the registry changes (except for the GameDVR_FSEBehavior key, which I don't have) here: After restarting my PC (not sure if needed), Indiana Jones now uses "Hardware: Legacy Flip" mode with d3d8to9, and indeed a top-level window is no longer visible above it (but the cursor still changes, so I know it's there). Unless the top-level window was already above the game window around the time when the game entered fullscreen mode, in which case it uses "Hardware Composed: Independent Flip" instead, and the other top-level window becomes visible again. What a mess... However, I still couldn't figure out how to enable maximized windowed mode for D3D9. |
Here is some code I made to set maximized windowed mode for D3D9. Edit: I tested this code and it did work in disabling maximized windowed mode. |
BTW: I also noticed that D3D9 creates a new window and puts that window at the top of all other windows. I caught this by hooking the CreateWindowEx() functions. |
I mean we're looking for a way to enable it, not disable it. It should be disabled by default. With disabled, GDI won't work I think. It doesn't work with DirectDraw either, except in maximized windowed mode. |
I thought you could just call |
Maybe it has to do with the Direct3D9SetMaximizedWindowedModeShim? |
Deleted. |
Sorry for the mistake in the last message. If I call Direct3D9SetSwapEffectUpgradeShim with a parameter of 0. Then the game runs and GDI can be seen on fullscreen exclusive mode. |
Well, I have no idea anymore. I've never heard of these shims before. What shim is supposed to call this function? I can't find any references to it. Does it change the presentation mode according to PresentMon? |
First of all, thank you for the response and looking into this. Your comments helped me search for this solution. I have never heard of these extra shims either. PresentMon is showing as "Hardware: Legacy Flip" when I call |
Closing this for now. Thanks for your help here! |
Closing |
First time I hear about this shim.. Though I guess it makes sense it exists, considering microsoft wanted to uplift everything to flip. |
Yeah. For this I check the following:
Hopefully, Microsoft will not remove this function and add a different hidden function with the same ordinal as this one was. I don't see that as very likely. I suspect if Microsoft creates other unnamed functions they will give them different ordinal numbers. There are plenty of numbers out there to use... |
I meant the conditions that triggers such or such behaviors to begin with (i.e. when conversely the fixes are required) |
When a game tries to display GDI (like a bik movie) to the screen when it is in Direct3D9 fullscreen exclusive mode then it just shows a black screen and nothing can be seen. This could also happen when a game writes text to the screen using GDI rather than DirectX and then game is in Direct3D9 fullscreen exclusive mode. However, the issue here is that I need to call this |
There is a long standing issue that was caused in an update to Windows 10 a few years ago (specifically in Windows 10 Fall Creators Edition) and still manifests itself in Windows 11. The issue is that once you call
Present()
onto a window from Direct3D9 when running in exclusive fullscreen mode it will overwrite all GDI on the screen. Even if later you try and draw things in GDI then it will not be seen at all.This used to work, and according to the Microsoft documentation this should work. It also works fine on Direct3D8 (and older) and on DirectDraw (as you know). But the issue only manifests itself if using Direct3D9 and exclusive fullscreen mode. The reason this is an issue is because I have been working to convert older Direct3D into Direct3D9 and some games play their video or show text on the screen using GDI, which completely disappears when upgrading it to Direct3D9.
I have already tried setting DisableMaxWindowedMode, which I thought should solve it but it does not. The only solution I have been able to come up with is to build a fullscreen windowed mode option. But this causes other issues.
There are some additional details about this here and in this thread starting here.
I know you are not an expert at Direct3D, but this question is not directly related to DirectD3, rather the interaction between things created in GDI vs Direct3D.
Any ideas or thoughts you have here would be appreciated.
The text was updated successfully, but these errors were encountered: