Skip to content

macOS: native HiDPI/Retina rendering (full-screen, sharp, correct input)#204

Merged
fbraz3 merged 3 commits into
fbraz3:mainfrom
wormeyman:fix/macos-hidpi-retina
Jul 12, 2026
Merged

macOS: native HiDPI/Retina rendering (full-screen, sharp, correct input)#204
fbraz3 merged 3 commits into
fbraz3:mainfrom
wormeyman:fix/macos-hidpi-retina

Conversation

@wormeyman

Copy link
Copy Markdown

On Apple Silicon Retina displays the game renders at logical (1x) resolution and the compositor upscales the result, so it looks soft next to the same engine running under Wine/CrossOver.

Requesting a high-density drawable on its own is not enough. The game then renders 1:1 in the top-left corner, because DXVK's SDL3 WSI sizes the swapchain in points while the Metal layer is in pixels. And once the picture does fill the screen, mouse hit-testing is off, because the pillarbox viewport rect stays in pixel space while SDL reports mouse coordinates in points.

Four changes work together so the game renders at native resolution, fills the screen, and maps input correctly:

  1. SDL3Main.cpp (Generals + GeneralsMD): request SDL_WINDOW_HIGH_PIXEL_DENSITY on Apple, so the Metal drawable is native-resolution. Scoped to __APPLE__; Linux is unchanged.
  2. bundle-macos-{generals,zh}.sh: set NSHighResolutionCapable=true. Without it macOS gives the app a 1x backing store and the flag above has no effect.
  3. DX8Wrapper::Pillarbox_Setup (dx8wrapper.cpp): populate the pixel density even when the backbuffer size comes from the present parameters. Pillarbox_Get_Rect divides by that density to convert the viewport back to points for input mapping; with it left at 1.0, clicks landed at roughly half position.
  4. DXVK SDL3 WSI: getWindowSize must query pixels, not points. It is vendored here as cmake/patches/dxvk-macos-hidpi-wsi.patch and applied in the DXVK ExternalProject PATCH_COMMAND, so a default build picks it up automatically. Once the fix lands in the pinned DXVK ref, the patch, the PATCH_COMMAND, and this note can be removed and DXVK_REMOTE_REF bumped. A companion PR to fbraz3/dxvk will carry that change upstream.

Testing: GeneralsMD (Zero Hour) fullscreen on a 14" M4 Pro (3024x1964). Before: soft, or corner-cropped once the high-density flag was on. After: fills the screen at native 3024x1898, sharp, with working menu and in-game input. Played a full skirmish to confirm gameplay input.

The vendored patch lets this branch build and run standalone until the DXVK change merges.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Gpbm3zSo8ggFfLaRByKoaC

wormeyman and others added 2 commits July 11, 2026 12:05
…rect input)

On Apple Silicon Retina displays the game rendered at logical (1x) resolution
and the compositor upscaled it, producing a soft image. Enabling a
high-pixel-density drawable alone made it render 1:1 in the top-left corner
because the DXVK SDL3 WSI sized the swapchain in points while the Metal layer
is in pixels.

Four coordinated changes make the game render at true native resolution,
fill the screen, and map input correctly:

- SDL3Main.cpp (Generals + GeneralsMD): request SDL_WINDOW_HIGH_PIXEL_DENSITY
  on Apple so the Metal drawable is native-resolution.
- bundle-macos-{generals,zh}.sh: add NSHighResolutionCapable=true, required for
  macOS to give the app a high-res backing store.
- DX8Wrapper::Pillarbox_Setup (dx8wrapper.cpp): populate the pixel density even
  when the backbuffer size comes from the present parameters, so the viewport
  rect converts back to logical points and SDL point-space mouse coordinates
  hit-test correctly.
- cmake/patches/dxvk-macos-hidpi-wsi.patch: DXVK SDL3 WSI getWindowSize() must
  query SDL_GetWindowSizeInPixels (pixels), not SDL_GetWindowSize (points).
  This lives in the fbraz3/dxvk submodule; the patch is vendored here and is
  currently applied via SAGE_DXVK_USE_LOCAL_FORK. It needs a matching PR to
  fbraz3/dxvk, after which DXVK_REMOTE_REF can be bumped.

Verified: GeneralsMD (Zero Hour) runs full-screen at native 3024x1898 on a
14" M4 Pro, sharp, with working menu/skirmish input.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gpbm3zSo8ggFfLaRByKoaC
…anch builds standalone

Wire cmake/patches/dxvk-macos-hidpi-wsi.patch into the remote DXVK
ExternalProject PATCH_COMMAND (idempotent reverse-check + git apply), so a
default build (SAGE_DXVK_USE_LOCAL_FORK=OFF) fetches the pinned fbraz3/dxvk
commit and applies the pixel-size WSI fix automatically. Removes the need for
the local-fork flag. Once the fix lands in the pinned DXVK ref, this
PATCH_COMMAND and the patch file can be dropped.

Verified: clean DXVK re-clone -> patch applies -> libdxvk_d3d9 built with
SDL_GetWindowSizeInPixels; GeneralsXZH runs full-screen native Retina.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gpbm3zSo8ggFfLaRByKoaC
@fbraz3

fbraz3 commented Jul 12, 2026

Copy link
Copy Markdown
Owner

Hi @wormeyman thanks for the contribution, I was noticed something strange with graphics but don't figure out what was it.

The DXVK PR has just been merged.

Could you please update this PR to point to the new upstream DXVK commit and clean up the temporary patch files?

Specifically:

  • Bump DXVK_REMOTE_REF in CMakeLists.txt to the newly merged commit hash: 1132d306e36c932fb4d062bce7c5602c45913ac8.
  • Remove the local patch file cmake/patches/dxvk-macos-hidpi-wsi.patch and the PATCH_COMMAND config referencing it from CMakeLists.txt.

Once these changes are pushed, we are ready to merge this PR.

The macOS HiDPI WSI fix has merged into fbraz3/dxvk. Bump DXVK_REMOTE_REF
to the merged commit (1132d306e36c932fb4d062bce7c5602c45913ac8) and remove
the now-redundant vendored patch and its PATCH_COMMAND.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CqpfGUwtpZiH5j5aErC3TE
@wormeyman

Copy link
Copy Markdown
Author

Thanks for merging it! Pushed a commit that bumps DXVK_REMOTE_REF to 1132d306e36c932fb4d062bce7c5602c45913ac8 and removes the vendored patch file plus the PATCH_COMMAND that applied it.

One note: the DXVK config actually lives in cmake/dx8.cmake (included by CMakeLists.txt), not CMakeLists.txt directly, so that's where the changes landed. Should be good to merge now.

@fbraz3 fbraz3 merged commit f993ae2 into fbraz3:main Jul 12, 2026
8 checks passed
@wormeyman wormeyman deleted the fix/macos-hidpi-retina branch July 13, 2026 03:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants