Predicting_real_estate_prices_using_scikit-learn icon indicating copy to clipboard operation
Predicting_real_estate_prices_using_scikit-learn copied to clipboard

[WIN32SS][ENG][NTDDRAW] Manage DirectDraw instances when switching display mode

Open oleg-dubinskiy opened this issue 3 years ago • 0 comments

Purpose

[ENG] Implement DirectDraw management in switch display mode functions (e. g. whose change resolution, color depth, display frequency etc.):

  • Switch DirectDraw instances between the two PDEVs (the current one and the new one allocated by ourself) by calling dxg!DxDdDynamicModeChange function.
  • Suspend them before and resume after the display mode switch, by calling dxg!DxDdsuspendDirectDraw and dxg!DxDdResumeDirectDraw appropriately. We currently don't have these functions implemented, but MS DXG has, so it allows to propely manage DirectDraw PDEVs using this driver, similarly to Windows. My analysis confirms that these functions are always called in XP/2k3 on display mode switch, even when there is no any DirectX app running at the moment. So I'm doing the same. I've also analyzed their prototypes and see that my guessings are right.
  • Initialize hDev and dhpdev members for EDD_DIRECTDRAW_GLOBAL for newly created surfaces, switch them during mode change and re-initialize after it also. They are commonly used by DirectDraw stack. Also enable DirectDraw for an old and new PDEVs, by calling dxg!DxDdEnableDirectDraw function.

[NTDDRAW] Additionally, fix usage of DirectDraw lock count in PDEVOBJ structure.

  • Enable cDirectDrawDisableLocks member for storing its value, instead of DxDd_nCount, which is marked as ROS-specific.
  • Use it in win32k!DxEngGet/SetHdevData for getting/setting DirectDraw count aprropriately. My analysis also shows that in Windows, PDEVOBJ::cDirectDrawDisableLocks method calls DxEngGetHdevData with type 8, which corresponds to our DxDd_nCount. So there is no any doubts that this member is used there.
  • Rename DxEngGetHdevData_dd_count alias of type 8 to DxEngGetHdevData_dd_locks, to more match to an actual member name. Update the enumeration and fix all code parts appropriately.

All these changes allow to properly change display mode during executing DirectDraw applications, when they try to switch in fullscreen mode. At least bugcheck that happened before my changes, does no longer appear. Although some games still don't run correctly like there is no 3D acceleration (which actually exists). It needs further investigations.

And please note that my patch causes the problem when switching display mode with our current ddraw.dll (that is imported from Wine). Wine's implementation doesn't relay on DXG kernel APIs and uses WineD3D OpenGL wrapper instead. After trying to do that, appears an exception due to something uninitialized. But the MS ddraw.dll and dxg.sys are now functioning much better. So it is not recommend to apply this PR until that problem is fixed (by patching Wine's ddraw or switching to our ddraw_new instead). And don't forget that my #3638 PR also is badly needed to be applied, to see any effect from my current changes.

JIRA issue: CORE-17932

Proposed changes

  • Switch DirectDraw instances between the two PDEVs (the current one and the new one allocated by ourself) by calling dxg!DxDdDynamicModeChange function.
  • Suspend them before and resume after the display mode switch, by calling dxg!DxDdsuspendDirectDraw and dxg!DxDdResumeDirectDraw appropriately.
  • Initialize hDev and dhpdev members for EDD_DIRECTDRAW_GLOBAL for newly created surfaces, switch them during mode change and re-initialize after it also. They are commonly used by DirectDraw stack.
  • Enable cDirectDrawDisableLocks member for storing its value, instead of DxDd_nCount, which is marked as ROS-specific.
  • Use it in win32k!DxEngGet/SetHdevData for getting/setting DirectDraw count appropriately. My analysis also shows that in Windows, PDEVOBJ::cDirectDrawDisableLocks method calls DxEngGetHdevData with type 8, which corresponds to our DxDd_nCount. So there is no any doubts that this member is used there.
  • Rename DxEngGetHdevData_dd_count alias of type 8 to DxEngGetHdevData_dd_locks, to more match to an actual member name. Update the enumeration and fix all code parts appropriately.

TODO

  • [ ] Investigate why some DirectDraw games still don't run properly, like without hardware acceleration.
  • [ ] Find a possible fix for the problem with using Wine's DirectDraw after my changes.
  • [x] UPDATE: Now fixed display mode switch problem, which was discovered recently. Exception during manual attempt to switch the mode happened due to some uninitialized data in EDD_DIRECTDRAW_GLOBAL structure. Fixed it by calling dxg!DxDdEnableDirectDraw function. :slightly_smiling_face:

Result

Sorry guys, but I'm not able to make a demo video, because my recorder captures simply a black screen instead of contents, due to stupid open source Linux drivers for my video card. :frowning_face: Feel free to test my PR with by yourself and record a video if you can. :wink: UPDATE: video test is now recorded and published on my YouTube channel. :smiley: UPDATE 2: here's a video URL: https://youtu.be/H8hAfJhksdQ.

oleg-dubinskiy avatar May 16 '22 20:05 oleg-dubinskiy