4 changed files with 140 additions and 11 deletions
@ -0,0 +1,102 @@ |
|||||||
|
|
||||||
|
// attempt to fix vsync with opengl on windows
|
||||||
|
// https://bugs.chromium.org/p/chromium/issues/detail?id=467617
|
||||||
|
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/d3dkmthk/nf-d3dkmthk-d3dkmtwaitforverticalblankevent
|
||||||
|
// NOTE: requires installing windows driver kit addon for msvc
|
||||||
|
// TODO: not working with hdc provided by SDL, try enumerating display devices as described here:
|
||||||
|
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/d3dkmthk/nf-d3dkmthk-d3dkmtopenadapterfromhdc
|
||||||
|
// NOTE: the above seems to make some difference in lowering cpu usage, but cpu stays at max frequency even when relatively idle.
|
||||||
|
|
||||||
|
// TODO: if d3dkmt... doensn't work, try DWMFlush() https://docs.microsoft.com/en-us/windows/desktop/api/dwmapi/nf-dwmapi-dwmflush
|
||||||
|
// glfw uses this https://github.com/glfw/glfw/blob/master/src/wgl_context.c
|
||||||
|
//
|
||||||
|
// if that doesn't work... https://docs.microsoft.com/en-us/windows/desktop/api/timeapi/nf-timeapi-timebeginperiod
|
||||||
|
// to increase schedular granularity. can then use sleep(1) for 1ms resolution
|
||||||
|
|
||||||
|
#pragma once |
||||||
|
|
||||||
|
#include <cstdint> |
||||||
|
|
||||||
|
#include "SDL_syswm.h" |
||||||
|
|
||||||
|
#if defined(_WIN32) |
||||||
|
#include "windows.h" |
||||||
|
#include "d3dkmthk.h" |
||||||
|
|
||||||
|
typedef uint32_t D3DKMT_HANDLE; |
||||||
|
typedef struct { |
||||||
|
D3DKMT_HANDLE hAdapter = NULL; |
||||||
|
UINT vidID = 0; |
||||||
|
} platform_win_device_handles; |
||||||
|
platform_win_device_handles g_platform_win_device_handles; |
||||||
|
|
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
|
|
||||||
|
inline bool |
||||||
|
platform_init(SDL_Window* window) |
||||||
|
{ |
||||||
|
#if defined(_WIN32) |
||||||
|
D3DKMT_HANDLE hAdapter = NULL; |
||||||
|
UINT vidID = 0; |
||||||
|
D3DKMT_OPENADAPTERFROMHDC OpenAdapterData; |
||||||
|
DISPLAY_DEVICE dd; |
||||||
|
HDC hdc; |
||||||
|
|
||||||
|
memset(&dd, 0, sizeof(dd)); |
||||||
|
dd.cb = sizeof dd; |
||||||
|
|
||||||
|
for (int i = 0; EnumDisplayDevicesA(NULL, i, &dd, 0); ++i) { |
||||||
|
if (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
hdc = CreateDC(NULL, dd.DeviceName, NULL, NULL); |
||||||
|
if (hdc == NULL) |
||||||
|
return false; |
||||||
|
|
||||||
|
OpenAdapterData.hDc = hdc; |
||||||
|
if ((D3DKMTOpenAdapterFromHdc(&OpenAdapterData)) >= 0) { |
||||||
|
DeleteDC(hdc); |
||||||
|
g_platform_win_device_handles.hAdapter = OpenAdapterData.hAdapter; |
||||||
|
g_platform_win_device_handles.vidID = OpenAdapterData.VidPnSourceId; |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
DeleteDC(hdc); |
||||||
|
return false; |
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
inline void |
||||||
|
platform_wait_for_vblank(bool wait=true) |
||||||
|
{ |
||||||
|
if (!wait) return; |
||||||
|
|
||||||
|
#if defined(_WIN32) |
||||||
|
_D3DKMT_WAITFORVERTICALBLANKEVENT waitForVBlankData; |
||||||
|
memset(&waitForVBlankData, 0, sizeof(waitForVBlankData)); |
||||||
|
waitForVBlankData.hAdapter = g_platform_win_device_handles.hAdapter; |
||||||
|
waitForVBlankData.VidPnSourceId = g_platform_win_device_handles.vidID; |
||||||
|
NTSTATUS ret = D3DKMTWaitForVerticalBlankEvent(&waitForVBlankData); |
||||||
|
|
||||||
|
switch (ret) { |
||||||
|
case 0x00000000: // STATUS_SUCCESS
|
||||||
|
//OutputDebugString("Success\r\n");
|
||||||
|
break; |
||||||
|
//case STATUS_DEVICE_REMOVED:
|
||||||
|
// OutputDebugString("STATUS_DEVICE_REMOVED\r\n");
|
||||||
|
// break;
|
||||||
|
case STATUS_INVALID_PARAMETER: |
||||||
|
OutputDebugString("STATUS_INVALID_PARAMETER\r\n"); |
||||||
|
break; |
||||||
|
default: |
||||||
|
OutputDebugString("????"); |
||||||
|
} |
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
|
// TODO: implement/test for linux
|
||||||
|
} |
||||||
|
|
||||||
Loading…
Reference in new issue