Skip to content

Commit

Permalink
Avoid garbage-free WebGL APIs when memory size is over 2gb.
Browse files Browse the repository at this point in the history
Both chrome and firefox see have some issues with passing 2gb+ and 4gb+
offsets to these APIs.

Once the browser issues are addressed we can lift these restrictions
over time.

Fixes: emscripten-core#20533
  • Loading branch information
sbc100 committed Feb 29, 2024
1 parent 165133b commit 42b17c1
Show file tree
Hide file tree
Showing 18 changed files with 106,634 additions and 102 deletions.
26,553 changes: 26,553 additions & 0 deletions a.out.js

Large diffs are not rendered by default.

Binary file added a.out.wasm
Binary file not shown.
26,640 changes: 26,640 additions & 0 deletions new.js

Large diffs are not rendered by default.

Binary file added new.wasm
Binary file not shown.
Binary file added old-js.wasm
Binary file not shown.
26,665 changes: 26,665 additions & 0 deletions old.js

Large diffs are not rendered by default.

Binary file added old.wasm
Binary file not shown.
26,665 changes: 26,665 additions & 0 deletions oldld.js

Large diffs are not rendered by default.

Binary file added oldld.wasm
Binary file not shown.
130 changes: 58 additions & 72 deletions src/library_webgl.js

Large diffs are not rendered by default.

15 changes: 14 additions & 1 deletion src/library_webgl2.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,11 @@ var LibraryWebGL2 = {
return;
}
#endif
#if WEBGL_USE_GARBAGE_FREE_APIS
size && GLctx.getBufferSubData(target, offset, HEAPU8, data, size);
#else
size && GLctx.getBufferSubData(target, offset, HEAPU8.subarray(data, data+size));
#endif
},

glInvalidateFramebuffer__deps: ['$tempFixedLengthArray'],
Expand Down Expand Up @@ -147,13 +151,22 @@ var LibraryWebGL2 = {
GLctx.invalidateSubFramebuffer(target, list, x, y, width, height);
},

glTexImage3D__deps: ['$heapObjectForWebGLType', '$toTypedArrayIndex'],
glTexImage3D__deps: ['$heapObjectForWebGLType', '$toTypedArrayIndex',
#if !WEBGL_USE_GARBAGE_FREE_APIS
'$emscriptenWebGLGetTexPixelData',
#endif
],
glTexImage3D: (target, level, internalFormat, width, height, depth, border, format, type, pixels) => {
if (GLctx.currentPixelUnpackBufferBinding) {
GLctx.texImage3D(target, level, internalFormat, width, height, depth, border, format, type, pixels);
} else if (pixels) {
var heap = heapObjectForWebGLType(type);
#if WEBGL_USE_GARBAGE_FREE_APIS
GLctx.texImage3D(target, level, internalFormat, width, height, depth, border, format, type, heap, toTypedArrayIndex(pixels, heap));
#else
var pixelData = emscriptenWebGLGetTexPixelData(type, format, width, height * depth, pixels, internalFormat);
GLctx.texImage3D(target, level, internalFormat, width, height, depth, border, format, type, pixelData);
#endif
} else {
GLctx.texImage3D(target, level, internalFormat, width, height, depth, border, format, type, null);
}
Expand Down
6 changes: 6 additions & 0 deletions src/settings_internal.js
Original file line number Diff line number Diff line change
Expand Up @@ -270,3 +270,9 @@ var MINIFY_WHITESPACE = true;
var ASYNCIFY_IMPORTS_EXCEPT_JS_LIBS = [];

var WARN_DEPRECATED = true;

// WebGL 2 provides new garbage-free entry points to call to WebGL. Use
// those always when possible.
// We currently set this to false for certain browser when large memory sizes
// (2gb+ or 4gb+) are used
var WEBGL_USE_GARBAGE_FREE_APIS = false;
8 changes: 4 additions & 4 deletions test/code_size/hello_webgl2_wasm.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"a.html": 569,
"a.html.gz": 379,
"a.js": 4589,
"a.js.gz": 2341,
"a.js": 4536,
"a.js.gz": 2312,
"a.wasm": 10451,
"a.wasm.gz": 6724,
"total": 15609,
"total_gz": 9444
"total": 15556,
"total_gz": 9415
}
8 changes: 4 additions & 4 deletions test/code_size/hello_webgl2_wasm2js.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"a.html": 354,
"a.html.gz": 266,
"a.js": 22323,
"a.js.gz": 11632,
"total": 22677,
"total_gz": 11898
"a.js": 22270,
"a.js.gz": 11604,
"total": 22624,
"total_gz": 11870
}
8 changes: 4 additions & 4 deletions test/code_size/hello_webgl_wasm.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"a.html": 569,
"a.html.gz": 379,
"a.js": 4075,
"a.js.gz": 2170,
"a.js": 4056,
"a.js.gz": 2152,
"a.wasm": 10451,
"a.wasm.gz": 6724,
"total": 15095,
"total_gz": 9273
"total": 15076,
"total_gz": 9255
}
8 changes: 4 additions & 4 deletions test/code_size/hello_webgl_wasm2js.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"a.html": 354,
"a.html.gz": 266,
"a.js": 21794,
"a.js.gz": 11450,
"total": 22148,
"total_gz": 11716
"a.js": 21775,
"a.js.gz": 11436,
"total": 22129,
"total_gz": 11702
}
19 changes: 6 additions & 13 deletions test/test_browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -1318,7 +1318,6 @@ def test_webgl_parallel_shader_compile(self):
self.btest_exit('webgl_parallel_shader_compile.cpp')

@requires_graphics_hardware
@no_4gb('readPixels fails: https://crbug.com/324992397')
def test_webgl_explicit_uniform_location(self):
self.btest_exit('webgl_explicit_uniform_location.c', args=['-sGL_EXPLICIT_UNIFORM_LOCATION', '-sMIN_WEBGL_VERSION=2'])

Expand All @@ -1327,7 +1326,6 @@ def test_webgl_sampler_layout_binding(self):
self.btest_exit('webgl_sampler_layout_binding.c', args=['-sGL_EXPLICIT_UNIFORM_BINDING'])

@requires_graphics_hardware
@no_4gb('readPixels fails: https://crbug.com/324992397')
def test_webgl2_ubo_layout_binding(self):
self.btest_exit('webgl2_ubo_layout_binding.c', args=['-sGL_EXPLICIT_UNIFORM_BINDING', '-sMIN_WEBGL_VERSION=2'])

Expand Down Expand Up @@ -1529,7 +1527,6 @@ def test_sdl_gl_read(self):
self.btest_exit('test_sdl_gl_read.c', args=['-lSDL', '-lGL'])

@requires_graphics_hardware
@no_4gb('readPixels fails: https://crbug.com/324992397')
def test_sdl_gl_mapbuffers(self):
self.btest_exit('test_sdl_gl_mapbuffers.c', args=['-sFULL_ES3', '-lSDL', '-lGL'])

Expand Down Expand Up @@ -2032,12 +2029,10 @@ def test_gl_stride(self):
self.reftest('gl_stride.c', 'gl_stride.png', args=['-sGL_UNSAFE_OPTS=0', '-sLEGACY_GL_EMULATION', '-lGL', '-lSDL'])

@requires_graphics_hardware
@no_4gb('assertion failure')
def test_gl_vertex_buffer_pre(self):
self.reftest('gl_vertex_buffer_pre.c', 'gl_vertex_buffer_pre.png', args=['-sGL_UNSAFE_OPTS=0', '-sLEGACY_GL_EMULATION', '-lGL', '-lSDL'])

@requires_graphics_hardware
@no_4gb('assertion failure')
def test_gl_vertex_buffer(self):
self.reftest('gl_vertex_buffer.c', 'gl_vertex_buffer.png', args=['-sGL_UNSAFE_OPTS=0', '-sLEGACY_GL_EMULATION', '-lGL', '-lSDL'], reference_slack=1)

Expand Down Expand Up @@ -2779,7 +2774,6 @@ def test_webgl2_pbo(self):

@no_firefox('fails on CI likely due to GPU drivers there')
@requires_graphics_hardware
@no_4gb('fails to render')
def test_webgl2_sokol_mipmap(self):
self.reftest('third_party/sokol/mipmap-emsc.c', 'third_party/sokol/mipmap-emsc.png',
args=['-sMAX_WEBGL_VERSION=2', '-lGL', '-O1'], reference_slack=2)
Expand Down Expand Up @@ -4487,12 +4481,13 @@ def test_small_js_flags(self):
self.assertLess(abs(size - 4800), 100)

# Tests that it is possible to initialize and render WebGL content in a
# pthread by using OffscreenCanvas. -DTEST_CHAINED_WEBGL_CONTEXT_PASSING:
# Tests that it is possible to transfer WebGL canvas in a chain from main
# thread -> thread 1 -> thread 2 and then init and render WebGL content there.
@no_chrome('see https://crbug.com/961765')
# pthread by using OffscreenCanvas.
@no_chrome('https://crbug.com/961765')
@parameterized({
'': ([],),
# -DTEST_CHAINED_WEBGL_CONTEXT_PASSING:
# Tests that it is possible to transfer WebGL canvas in a chain from main
# thread -> thread 1 -> thread 2 and then init and render WebGL content there.
'chained': (['-DTEST_CHAINED_WEBGL_CONTEXT_PASSING'],),
})
@requires_threads
Expand Down Expand Up @@ -4563,7 +4558,6 @@ def test_webgl_draw_base_vertex_base_instance(self):
'-DWEBGL_CONTEXT_VERSION=2'])

@requires_graphics_hardware
@no_4gb('fails to render')
def test_webgl_sample_query(self):
self.btest_exit('webgl_sample_query.cpp', args=['-sMAX_WEBGL_VERSION=2', '-lGL'])

Expand Down Expand Up @@ -4621,7 +4615,6 @@ def test_webgl_offscreen_framebuffer_state_restoration(self):

# Tests that using an array of structs in GL uniforms works.
@requires_graphics_hardware
@no_4gb('fails to render')
def test_webgl_array_of_structs_uniform(self):
self.reftest('webgl_array_of_structs_uniform.c', 'webgl_array_of_structs_uniform.png', args=['-lGL', '-sMAX_WEBGL_VERSION=2'])

Expand Down Expand Up @@ -4688,7 +4681,7 @@ def test_webgl_simple_extensions(self, simple_enable_extensions, webgl_version):
self.btest_exit('webgl2_simple_enable_extensions.c', args=cmd)

@parameterized({
'default': ([],),
'': ([],),
'closure': (['-sASSERTIONS', '--closure=1'],),
'main_module': (['-sMAIN_MODULE=1'],),
})
Expand Down
11 changes: 11 additions & 0 deletions tools/link.py
Original file line number Diff line number Diff line change
Expand Up @@ -1611,6 +1611,17 @@ def check_memory_setting(setting):
if not settings.MEMORY64 and settings.MAXIMUM_MEMORY > 2 * 1024 * 1024 * 1024:
settings.CAN_ADDRESS_2GB = 1

if settings.MAX_WEBGL_VERSION >= 2:
settings.WEBGL_USE_GARBAGE_FREE_APIS = 1
# Some browsers have issues using the WebGL2 garbage-free APIs when the
# memory offsets are over 2^31 or 2^32
# For firefox see: https://bugzilla.mozilla.org/show_bug.cgi?id=1838218
if settings.MIN_FIREFOX_VERSION != feature_matrix.UNSUPPORTED and settings.MAXIMUM_MEMORY > 2 ** 31:
settings.WEBGL_USE_GARBAGE_FREE_APIS = 0
# For chrome see: https://crbug.com/324992397
if settings.MIN_CHROME_VERSION != feature_matrix.UNSUPPORTED and settings.MEMORY64 and settings.MAXIMUM_MEMORY > 2 ** 32:
settings.WEBGL_USE_GARBAGE_FREE_APIS = 0

if settings.MINIMAL_RUNTIME:
if settings.EXIT_RUNTIME:
settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['proc_exit', '$callRuntimeCallbacks']
Expand Down

0 comments on commit 42b17c1

Please sign in to comment.