From 7ba1e29d4e170b251ea41c993b5223016584f3c1 Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Thu, 28 Nov 2024 08:15:09 +0100 Subject: [PATCH] Screen/OSX: Make Intel iGPU pageflip checking on recent macOS more robust. Turns out that at least under macOS 13 with Intel Kabylake iGPU, the lower bits of the live surface address register now encode something else than the surface base address. This throws off our pageflip update pending check. Mask out the lowest 12 bits of the read out surface address to fix the check. 12 bits will not make a difference, as no display surface would be small enough for those bits to matter. -> Fixes pageflip checking on MBP 2017 under macOS 13 Ventura on Intel iGPU. --- .../Common/Screen/PsychGraphicsHardwareHALSupport.c | 12 ++++++++---- PsychSourceGL/Source/OSX/Screen/PsychScreenGlue.c | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/PsychSourceGL/Source/Common/Screen/PsychGraphicsHardwareHALSupport.c b/PsychSourceGL/Source/Common/Screen/PsychGraphicsHardwareHALSupport.c index ffe56be66..48975220d 100644 --- a/PsychSourceGL/Source/Common/Screen/PsychGraphicsHardwareHALSupport.c +++ b/PsychSourceGL/Source/Common/Screen/PsychGraphicsHardwareHALSupport.c @@ -737,10 +737,12 @@ psych_bool PsychGetCurrentGPUSurfaceAddresses(PsychWindowRecordType* windowRecor // Intel IGP: // No secondary surface atm., but (ab)use to store the latched next requested surface address for reg doublebuffering: - *secondarySurface = (psych_uint64) PsychOSKDReadRegister(screenId, 0x7019C + (headid * 0x1000), NULL);; + // We mask out the lowest 12 bits, as they may store unrelated scanout surface information, as of macOS 13 Ventura, + // which would taint comparisons below. + *secondarySurface = (psych_uint64) PsychOSKDReadRegister(screenId, 0x7019C + (headid * 0x1000), NULL) & 0xFFFFF000; // Get primarySurface address from plane base address live register, ie. the true current value from last completed flip: - *primarySurface = (psych_uint64) PsychOSKDReadRegister(screenId, 0x701AC + (headid * 0x1000), NULL); + *primarySurface = (psych_uint64) PsychOSKDReadRegister(screenId, 0x701AC + (headid * 0x1000), NULL) & 0xFFFFF000; // primarySurface encodes current scanout buffer address - live, whereas secondarySurface encodes pre-doublebuffered // address for a flip. If both are identical then no flip is pending. If they differ then obviously the wanted @@ -756,8 +758,10 @@ psych_bool PsychGetCurrentGPUSurfaceAddresses(PsychWindowRecordType* windowRecor if (gpuMaintype == kPsychIntelIGP) { // Intel: - printf("PTB-DEBUG: %6lf : Screen %i: Head %i: currentSurface=%p <-- requestedSurface=%p : updatePending=%i\n", - tNow, screenId, headid, *primarySurface, *secondarySurface, (int) *updatePending); + printf("PTB-DEBUG: %6lf : Screen %i: Head %i: currentSurface=%p <-- requestedSurface=%p : updatePending=%i : tilingOffset=%p : linearOffset=%p\n", + tNow, screenId, headid, *primarySurface, *secondarySurface, (int) *updatePending, (psych_uint64) PsychOSKDReadRegister(screenId, 0x701A4 + (headid * 0x1000), NULL), + (psych_uint64) PsychOSKDReadRegister(screenId, 0x70184 + (headid * 0x1000), NULL)); + } else { // AMD: printf("PTB-DEBUG: %6lf : Screen %i: Head %i: primarySurface=%p : secondarySurface=%p : updateStatus=%i", diff --git a/PsychSourceGL/Source/OSX/Screen/PsychScreenGlue.c b/PsychSourceGL/Source/OSX/Screen/PsychScreenGlue.c index 8692a875e..680c3e4d5 100644 --- a/PsychSourceGL/Source/OSX/Screen/PsychScreenGlue.c +++ b/PsychSourceGL/Source/OSX/Screen/PsychScreenGlue.c @@ -120,7 +120,7 @@ typedef struct { } display_mode_t; // Apple macOS CGS private api. Subject to backwards incompatible and breaking change without any notice or warning! -// Work as of macOS 10.11, 10.12, 10.13, 10.14, 10.15 and hopefully later versions. +// Work as of macOS 10.11, 10.12, 10.13, 10.14, 10.15, 11, 12, 13 and hopefully later versions. #define MODE_SIZE (sizeof(display_mode_t) - sizeof(char) * 32 - sizeof(int)) void CGSGetCurrentDisplayMode(CGDirectDisplayID display, int *mode); void CGSConfigureDisplayMode(CGDisplayConfigRef config, CGDirectDisplayID display, int mode);