Skip to content

Mark Remix interop memory as a dedicated allocation - #100

Draft
sambvfx wants to merge 1 commit into
NVIDIAGameWorks:mainfrom
sambvfx:interop-dedicated-memory
Draft

sambvfx wants to merge 1 commit into
NVIDIAGameWorks:mainfrom
sambvfx:interop-dedicated-memory

Conversation

@sambvfx

@sambvfx sambvfx commented Nov 10, 2026 •

Copy link
Copy Markdown
Collaborator

Refs #41

Under Proton, players reported in #41 that the world renders upside down and no Minecraft UI appears. This PR fixes the mod's part of that report.

The bug

The mod imports two images from the Remix runtime into OpenGL: a color image and a depth image. The runtime creates both as dedicated allocations, because DXVK gives every shared image its own allocation. EXT_external_objects requires an importer of such memory to set GL_DEDICATED_MEMORY_OBJECT_EXT to GL_TRUE before the import. GlInterop never set it.

Windows drivers accept the import anyway, so nothing broke on Windows. Under Wine and Proton, the Linux driver reportedly imports without an error but binds no memory. Minecraft's UI then never reaches the shared image. The world is still drawn, but without the flip that the composite normally applies, so it appears upside down. The reporter found this and shared a mixin that sets the flag.

The change

GlInterop now sets GL_DEDICATED_MEMORY_OBJECT_EXT on every memory object before importing it. The flag has to be set first, because the import fixes the memory object's parameters. The change is 7 lines in one file. There is no switch: the spec requires the flag for these allocations, and Windows renders the same with it.

The Forge 1.12.2 bridge has the same omission. It will be fixed separately.

Testing

Tested on Windows 11 only: one RTX PRO 6000 Blackwell desktop, driver 616.92, runtime a00da12a, DLSS with frame generation (3x).

  • Root build and test pass: 835 tests, 0 failures.
  • The title screen renders the right way up, with its menus.
  • In the demo world, the HUD, the hotbar and an open chat all show over the path-traced image, which is the right way up.
  • After each resize the image and UI come back, the shared images are re-imported, and no GL errors appear. Resizes tried: a smaller window, back to 1920x1080, F11 fullscreen at 2560x1440, then windowed again.
  • Alt+X opens and closes the developer menu over gameplay.
  • The game quits cleanly.
  • A baseline run without the flag showed the same title screen and world.

Performance

The flag is set only when the shared images are imported, at startup and on each resize, so no per-frame cost was expected. An A/B/B/A benchmark confirms there is none. The setup was the same machine, the release runtime a00da12a, the high preset, the RTXDemo benchmark camera, 1920x1080 windowed, and 2 runs per slot (8 runs). A is the parent commit, 7d2ba9f1, and B is this PR.

Arm Avg frame p50 p95 p99 Avg FPS
A, parent (4 runs) 9.79 ms 9.14 ms 14.98 ms 19.25 ms 102.2
B, this PR (4 runs) 9.68 ms 9.13 ms 14.66 ms 18.23 ms 103.3

The 1.1% difference in average frame time is within the spread between runs: the standard deviation across runs is 0.17 ms for A and 0.08 ms for B. Every run in both arms ended with the same native crash during runtime shutdown, after its results were written. The crash predates this change.

Still needs testing

Getting a test build

CI doesn't publish build artifacts for pull requests. To test, check out this branch on Windows with the toolchain from Getting Started, then run:

.\gradlew.bat package -Parch=win64

This writes the installable JAR to build/distributions/. Use it in place of the RTX Remix JAR in your instance's mods folder. gradlew build only produces a development JAR without the runtime, so use package. For a report, the useful files are logs/latest.log and rtx-remix/logs/remix-dxvk.log from the game folder, plus a screenshot.

🤖 Generated with Claude Code

The runtime exports its color and depth interop images from dedicated
allocations: DXVK forces one for every shared image. EXT_external_objects
requires an importer to set GL_DEDICATED_MEMORY_OBJECT_EXT to TRUE before
importing such a handle, and GlInterop never did. Windows drivers accept
the import without it. Under Wine and Proton, the Linux driver reportedly
imports without error but binds nothing. The UI then never reaches the
presented image, and the world shows upside down (NVIDIAGameWorks#41).

GlInterop now sets the flag on every memory object before importing it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

1 participant