Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Heinz__Marcel
Beginner
147 Views

OpenGL ICD calls ReleaseDC on application's own HDC on WM_DESTROY events

System Setup Information:
-----------------------------------------

System Used: Custom on ASUSTEK Prime H310M-D
CPU SKU: i7-8700
GPU SKU: UHD 630
Processor Line: N/A
System BIOS Version: 1601 (10/09/2018)
CMOS settings: N/A
Graphics Driver Version: 25.20.100.6618
GOP/VBIOS Version: N/A
Operating System: Windows 10 x64
OS Version:  1809 (Build 17763.437)
API: OpenGL
Occurs on non-Intel GPUs: no

Steps to Reproduce:
-------------------------------
1. Optional: Compile attached Source code (VS2017 project included, but should work with any C++ Compiler on Windows)
   Compile as console applications to see the messages!
2. Start the EXE (precompiled one provided  in RELEASE subfolder)
3. Press any key  on the (red) GL Window to trigger the issue

Expected Results:
-------------------------------

The HDC which was acquired with GetDC during initialization stays valid, and calling wglMakeCurrent(hDC, hRC) in the WNDPROC for WM_DESTROY message succeeds.

Console Output:

Calling DestroyWindow()...
CleanupGL: prepare to clean up
Calling DestroyWindow() done

Actual Results:
-------------------------------

The HDC which was acquired with GetDC is freed with ReleaseDC by ig9icd32.dll somewhere inbetween DestroyWindow and the actual Window Procedure handling the WM_DESTROY event, therefore wglMakeCurrent(hDC, hRC) does fail.

Console Output:

Calling DestroyWindow()...
CleanupGL: prepare to clean up
CleanupGL: MakeCurrent failed, err=0xc0070006
CleanupGL: MakeUncurrent failed, err=0x6
Calling DestroyWindow() done

 

Additional Information:
-------------------------------

 

The issue is not limited to this particular GPU or driver version, we observed this in the wild a lot with many different Intel GPUs and drivers.

I was able to debug this further and it seems like the Intel driver is using some kind WH_CALLWNDPROC hook, and does seem to react to
WM_DESTROY. Note that at the time DestroyWindow is called, the GL context (and DC) was unbound, so it is not the current thread and DC.

With http://www.rohitab.com/apimonitor, I can actually see the intel ICD calling ReleaseDC exactly on the HDC the application is owning:

#    Time of Day    Thread    Module    API    Return Value    Error    Duration
32465    2:42:38.646 PM    1    ig9icd32.dll    CallNextHookEx ( NULL, 0, 0, 20773544 )    0        0.0000000
32466    2:42:38.646 PM    1    ig9icd32.dll    ReleaseDC ( 0x00050ae8, 0x79013a4d )    1        0.0000025
32467    2:42:38.646 PM    1    ig9icd32.dll    CallNextHookEx ( NULL, 0, 0, 20773548 )    0        0.0000001
32468    2:42:38.646 PM    1    OPENGL32.dll    CallWindowProcW ( 0xffff089d, 0x00050ae8, WM_DESTROY, 0, 0 )    0        0.0020730
32470    2:42:38.646 PM    1    TEST.exe    wglMakeCurrent ( 0x79013a4d, 0x00010000 )    FALSE    -1073283066 =     0.0000315

Note: Error Code -1073283066 is 0xC0070006, whith the lower 16 bits suggesting INVALID_HANDLE)

By adding a WH_DEBUG hook and preventing the execution of WH_CALLWNDPROC for WM_DESTROY messages, the issue can be mitigated (see #define HOOKHACK in the attached source code), but it is unclear what consequences this will have, as some of the operations the driver is normally doing will be bypassed.

0 Kudos
0 Replies
Reply