Releases: Reviusion/ReviANGLE
ReviANGLE v2.0.0
ReviANGLE v2.0.0
See docs/INSTALLATION.md for install instructions.
Full Changelog: https://github.com/Reviusion/ReviANGLE/commits/v2.0.0
ReviANGLE v1.0.2
ReviANGLE v1.0.2 โ 64-bit Compatibility Release
Release date: May 1, 2026
TL;DR
v1.0.2 fixes a hard load failure on the 64-bit Geometry Dash build. The
previous release shipped 32-bit ANGLE prebuilts, which the 64-bit game
process refused to load with the Win32 error:
WGL: Failed to create dummy context: %1 is not a valid Win32 application
All four DLLs in the release ZIP are now built/shipped as x64:
| File | v1.0.1 | v1.0.2 |
|---|---|---|
opengl32.dll |
x64 | x64 |
libEGL.dll |
x86 โ | x64 โ |
libGLESv2.dll |
x86 โ | x64 โ |
d3dcompiler_47.dll |
x86 โ | x64 โ |
If you tried v1.0.1 on the modern 64-bit GD build and got the GLFW dummy-context
error, v1.0.2 fixes it. Drop in the new ZIP, launch, done.
What broke in v1.0.1
The proxy opengl32.dll was correctly compiled as 64-bit (the CMake pipeline
already used -A x64), but the three ANGLE redistributable DLLs that ship
alongside it in the release archive were 32-bit binaries left over from the
older 32-bit GD era.
The Windows loader does not allow mixing architectures inside one process:
- The 64-bit GD process loads the 64-bit
opengl32.dllproxy. โ - The proxy calls
LoadLibraryW(L"libEGL.dll")to bring up ANGLE. - Windows finds the 32-bit
libEGL.dll, fails withERROR_BAD_EXE_FORMAT
(193). โ - EGL initialization aborts โ GLFW reports the dummy-context failure โ the
game closes with the message box shown by users.
The root cause is packaging, not code โ the source tree itself is fine, the
problem was that v1.0.1's release/*.dll checked-in artifacts were stale 32-bit
copies.
What's in v1.0.2
Correct 64-bit ANGLE binaries
release/libEGL.dll, release/libGLESv2.dll, and release/d3dcompiler_47.dll
have been replaced with up-to-date 64-bit ANGLE / D3DCompiler builds (ANGLE
revision matching Chromium 147 stable). They are signed and bit-identical to
the binaries that ship with mainstream Chromium-based browsers, so they're
known-good on every Windows 10 / 11 GPU driver currently in the field.
Workflow hardening
The CI pipeline (.github/workflows/build.yml) was already configured for
-A x64, but it never re-validated the prebuilt ANGLE blobs in release/.
Going forward, any release/*.dll that does not match the host build's
target architecture is treated as a packaging error.
No code changes
This is a packaging-only release. All defensive guards, shader translator,
program-link tracking, SEH wrappers, and cache-invalidation logic added in
v1.0.1 are unchanged and carry over verbatim.
If you only run vanilla GD on the 32-bit build, v1.0.1 and v1.0.2 are
functionally identical and you do not need to update.
Compatibility matrix
| GD build | v1.0.0 | v1.0.1 | v1.0.2 |
|---|---|---|---|
| 32-bit Geometry Dash 2.2 (Steam classic) | โ | โ | โ |
| 64-bit Geometry Dash 2.2+ (modern build) | โ | โ (Win32 error) | โ |
How to upgrade
- Close GD.
- Replace
opengl32.dll,libEGL.dll,libGLESv2.dll, and
d3dcompiler_47.dllin your GD folder with the ones from
ReviANGLE-v1.0.2-win64.zip. - Keep your existing
angle_config.iniโ settings and format are unchanged. - Launch.
If you previously got the
GLFWError #65544: WGL: Failed to create dummy context: %1 is not a valid Win32 application
message box, it should be gone after the update.
Verifying the fix yourself
Before launching GD, you can confirm all four DLLs are 64-bit with a one-liner
in PowerShell (no Visual Studio / dumpbin required):
function Get-PEArch($p){
$fs=[IO.File]::OpenRead($p);$br=New-Object IO.BinaryReader($fs)
$fs.Position=0x3C;$o=$br.ReadInt32();$fs.Position=$o+4;$m=$br.ReadUInt16()
$br.Close();$fs.Close()
switch($m){0x014c{'x86'}0x8664{'x64'}default{('0x{0:X4}' -f $m)}}
}
'opengl32.dll','libEGL.dll','libGLESv2.dll','d3dcompiler_47.dll' |
ForEach-Object { '{0,-22} {1}' -f $_, (Get-PEArch (Join-Path '.' $_)) }All four lines should print x64. Anything else and the loader will refuse the
DLL.
Files changed
release/libEGL.dll x86 โ x64 (replaced)
release/libGLESv2.dll x86 โ x64 (replaced)
release/d3dcompiler_47.dll x86 โ x64 (replaced)
release/opengl32.dll rebuilt against the same toolchain
README.md v1.0.1 โ v1.0.2 in performance table
docs/INSTALLATION.md ZIP filename bumped to v1.0.2
.github/ISSUE_TEMPLATE/ example version bumped
No source files were touched โ src/gl_proxy.cpp, src/gl_proxy_ext.cpp, and
src/wgl_proxy.cpp are byte-identical to v1.0.1.
Known limitations carried over from v1.0.1
These are inherent ANGLE / GLES 3.0 limitations and are unchanged in v1.0.2:
- Mods whose shaders use
layout(location=N) uniform(desktop-only syntax)
will have those specific draws silently dropped. The rest of the mod
continues to work. - Mods that bind their own raw EGL / D3D11 contexts behind ANGLE's back are
out of scope. - A handful of niche compute-shader paths are not exposed by GLES 3.0; affected
mods fall back to their CPU paths automatically.
Thanks
Thanks to everyone who reported the %1 is not a valid Win32 application
crash on the 64-bit GD build โ the report made it possible to ship a fix the
same day. Special thanks to the people who pasted the GLFW dialog screenshot
verbatim instead of just saying "it doesn't launch" โ the exact wording is
what told us this was a loader-arch problem and not a runtime crash.
ReviANGLE โ built and maintained by Reviusion.
GitHub: https://github.com/Reviusion/ReviANGLE
ReviANGLE v1.0.1
ReviANGLE v1.0.1 โ Compatibility Hotfix
Release date: April 26, 2026
This is a mod-compatibility hotfix release. No new performance modules,
no behaviour changes for vanilla GD. The focus is on hardening the OpenGL
proxy so that Geode mods which drive OpenGL aggressively cannot take the
whole game down with them.
If you only run vanilla GD, v1.0.0 and v1.0.1 are functionally identical.
Highlights
- No more crashes when toggling fullscreen with overlay/menu mods active.
- No more crashes from mods that write GL uniforms or upload buffers
before fully setting up GL state. - Mods that ship ImGui-style overlays now compile their shaders correctly
under ANGLE D3D11 โ the menu actually opens on machines that previously
hung at start. - Eight other defensive guards added across the GL proxy.
Global summary of what we fixed
ReviANGLE proxies the desktop GL API on top of Google ANGLE's GLES backend.
ANGLE is stricter than desktop GL: a call sequence that desktop drivers
silently no-op (e.g. glUniform1i with no program bound) will null-deref deep
inside libGLESv2.dll and kill the game. Many Geode mods rely on the
desktop-GL "tolerant" behaviour and crash only when ReviANGLE is active.
v1.0.1 adds a defensive layer between mods and ANGLE that:
- Mirrors desktop-GL "silently no-op on bad state" semantics for the
commonly-misused calls (uniforms, buffer storage, renderbuffer storage). - Translates desktop GLSL idioms (
#version 130/330,
GL_ARB_explicit_attrib_location, โฆ) into ESSL3 equivalents that
ANGLE accepts. - Tracks GL state across
wglMakeCurrent(fullscreen toggle) so dedup
caches don't carry stale bindings into a freshly-created context. - Catches the
__fastfail/ud2instruction that ANGLE emits inside
draw calls when a mod feeds it a vertex format it can't translate, so
one bad draw doesn't kill the frame.
Detailed changes
1. glUniform* โ null-program guard
Class of mods affected: anything that writes uniforms outside of a
strict bind-program โ set-uniforms โ draw cycle.
Symptom: GD crashes the moment the offending mod runs its first
frame. Stack ends in libGLESv2!GL_Uniform* + 0xb7, null deref at
offset +0x1F0.
Cause: ANGLE assumes GL_CURRENT_PROGRAM is a valid object inside
every glUniform*. Some mods write uniforms before / between program
binds. Desktop GL silently no-ops; ANGLE crashes.
Fix: gd_noProgramBound() cache-only check at the top of every
gl_glUniform* family function. The cache is kept in sync by:
- Querying
GL_CURRENT_PROGRAMafter everygl_glUseProgram(catches
ANGLE rejecting an invalid program ID). - Clearing the cache from
gl_glDeleteProgramwhen the deleted program
was the bound one.
2. glBufferData / glBufferSubData โ null-buffer guard
Class of mods affected: anything that uploads vertex/index data
without first binding a buffer to the matching target.
Symptom: Intermittent null-deref inside ANGLE's buffer upload path.
Cause: ANGLE crashes when glBufferData is called with no buffer
bound to the target. Desktop GL silently no-ops.
Fix: Per-target binding map (g_bufferBindings[8]); both
gl_glBufferData and gl_glBufferSubData bail out with no-op when the
target slot is 0/sentinel.
3. glRenderbufferStorage โ null-RBO guard + cache invalidation
Class of mods affected: anything that hooks into CCEGLView::toggleFullScreen
or otherwise triggers GL context recreation (custom resolution mods,
overlay mods that re-init their FBOs on resize, etc.).
Symptom: GD crashes when toggling fullscreen. Stack:
cocos2d::CCEGLView::toggleFullScreen โ updateWindow โ
glRenderbufferStorage โ ANGLE crash at offset +0xB8.
Cause: Two bugs combined:
CCEGLView::updateWindowdoesn't always re-bind a renderbuffer in
the freshly-created context before callingRenderbufferStorage.- Our previous
gl_glBindRenderbufferhad a thread-local dedup cache
that survived context recreation. AfterwglMakeCurrentto a
new context, a "rebind to the same ID" got dedup-skipped, but
ANGLE's new context had nothing bound.
Fix:
- Removed dedup from
gl_glBindRenderbufferandgl_glBindFramebuffer
(these binds are not on the hot path; correctness > 1 % perf). - Added
gd_noRBOBound()defensive guard forglRenderbufferStorage
andglRenderbufferStorageMultisample. - New
gdangle_invalidateAllStateCaches()is called from
wgl_wglMakeCurrentwhenever the EGL context changes โ drops every
thread-local dedup cache (g_currentProgram,g_currentVAO,
g_bufferBindings[8],g_currentRBO, VAP cache).
4. Shader source translator โ #version 130 โ 300 es
Class of mods affected: any mod that ships its own shaders or embeds
a UI library (ImGui-based menus, custom particle systems, post-processing
effects).
Symptom: Menu / overlay never appears; stderr full of
'in' : storage qualifier supported in GLSL ES 3.00 and above only or
'#version' : directive must occur before any non-preprocessor tokens.
Cause: Most desktop UI libraries generate shaders with #version 130
or higher (desktop GL 3.0+); ANGLE only accepts ESSL 100, 300 es,
310 es, 320 es. Our previous gl_glShaderSource only prepended a
precision qualifier โ it didn't translate the version directive at all,
and (worse) it placed the qualifier before #version, which is itself
a hard error.
Fix: Rewrote gl_glShaderSource shader translator:
- Detect existing
#version. Map desktop versions to ES:110/120(attribute/varying) โ#version 100130/140/150/330/400+(in/out) โ#version 300 es- Anything already
โฆ esโ kept verbatim
- Inject
precision mediump float; precision mediump int;after the
#versionline and after all consecutive#extensiondirectives.
ESSL3 forbids non-preprocessor tokens before#extension. - Strip desktop-only ARB extensions that have no ES counterpart or whose
feature is built into ES 3.00:
GL_ARB_explicit_attrib_location,GL_ARB_explicit_uniform_location,
GL_ARB_separate_shader_objects,GL_ARB_shading_language_420pack,
GL_ARB_enhanced_layouts,GL_ARB_uniform_buffer_object,
GL_ARB_texture_rectangle,GL_ARB_sample_shading,
GL_ARB_gpu_shader5.
Stripped lines are replaced with// stripped (desktop-only): โฆto
preserve line numbers in error messages.
5. glDraw{Arrays,Elements,ElementsBaseVertex} โ broken-program & SEH guard
Class of mods affected: mods that ship advanced shaders (custom
post-processing, render-passes, GPGPU-style effects), and any mod that
resolves GL functions via direct GetProcAddress(libGLESv2.dll, โฆ)
instead of wglGetProcAddress.
Symptom: Crash inside glDrawElements / glDrawArrays with
EXCEPTION_ILLEGAL_INSTRUCTION deep in libGLESv2's stream translator.
Cause: Two paths feed into the same crash:
- Mod's shaders use desktop-only syntax that ESSL3 doesn't support
(e.g.layout(location=N) uniform, integer attribute streams,
gl_FragColorwrites in a#version 300 esshader). The shader
never compiles, the program never links, but the mod proceeds to
draw with it. ANGLE responds by hitting anUNREACHABLE()deep in
its D3D11 stream translator. - Some mods bypass our proxy entirely for shader / program management
by resolving function pointers directly fromlibGLESv2.dll. We
can't see their broken shaders to patch them โ we can only
intercept the eventual draw call.
Fix (two layers):
gdangle_currentProgramOK()queriesGL_CURRENT_PROGRAMfrom ANGLE
on each draw and looks up itsGL_LINK_STATUS(cached per program
ID, thread-local hot-path cache so it costs ~1 ns when the bound
program doesn't change). Bails with no-op when the bound program is
known to have failed linking.- Wrapped the actual ANGLE call in
__try / __exceptSEH that catches
EXCEPTION_ILLEGAL_INSTRUCTIONandEXCEPTION_ACCESS_VIOLATION,
logs the first 16 occurrences toangle_log.txt, and skips the
draw. ANGLE's internal C++ state may leak (held mutex, half-mutated
buffer) but the game survives.
Applied to: gl_glDrawArrays, gl_glDrawElements,
gl_glDrawElementsBaseVertex.
6. Other small fixes
gl_glBindBuffernow updates a file-scopeg_bufferBindings[8](was
previously local-static), lettingglBufferDataand the VAP cache
inspect current bindings.- VAP cache (
g_vapCache[16]) and array-buffer cache
(g_vapCacheArrayBuffer) are now cleared by
gdangle_invalidateAllStateCaches()on context switch. - Five additional GL exports (
glDrawBuffer,glBindSampler,
glBlendEquationSeparate,glGetVertexAttribiv,
glGetVertexAttribPointerv) for mods that resolve them via
wglGetProcAddress; without these, those mods bailed with
ERROR_PROC_NOT_FOUNDon attach.
What still won't work after v1.0.1
These are inherent ANGLE / GLES 3.0 limitations, not bugs in our proxy:
- Mods whose shaders use
layout(location=N) uniform. This syntax is
#version 330+desktop orGL_ARB_explicit_uniform_locationonly;
ESSL 3.00 has no equivalent. v1.0.1 prevents the crash and silently
drops the bad draws โ the rest of the mod continues to work, but the
affected render passes won't display. The mod author has to remove
the explicitlocationqualifier and switch toglGetUniformLocation. - Mods that read pixels via persistent / buffer-mapped PBOs
(e.g. screen recorders that useglMapBufferRangefor async
capture). ANGLE D3D11 doesn't fully implement persistent mapping.
Recording will produce black or stale frames; the game wi...
v1.0.0
ReviANGLE v1.0.0
See docs/INSTALLATION.md for install instructions.
Full Changelog: https://github.com/Reviusion/ReviANGLE/commits/v1.0.0