Skip to content

Commit

Permalink
Screen/OSX: Make Intel iGPU pageflip checking on recent macOS more ro…
Browse files Browse the repository at this point in the history
…bust.

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.
  • Loading branch information
kleinerm committed Nov 29, 2024
1 parent ce12353 commit 7ba1e29
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion PsychSourceGL/Source/OSX/Screen/PsychScreenGlue.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 7ba1e29

Please sign in to comment.