Skip to content

Commit

Permalink
Fix calls to glCcompressedTexImage2D with null pixel data
Browse files Browse the repository at this point in the history
I believe this has always been an issue with emscripten's WebGL1 code
which only recently became more prevalent with #21445.

Fixes: #19300
  • Loading branch information
sbc100 committed Aug 27, 2024
1 parent 62d7153 commit 2b6781e
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 4 deletions.
9 changes: 7 additions & 2 deletions src/library_webgl.js
Original file line number Diff line number Diff line change
Expand Up @@ -1520,6 +1520,11 @@ for (/**@suppress{duplicate}*/var i = 0; i <= {{{ GL_POOL_TEMP_BUFFERS_SIZE }}};
},
glCompressedTexImage2D: (target, level, internalFormat, width, height, border, imageSize, data) => {
// `data` may be null here, which means "allocate uniniitalized space but
// don't upload" in GLES parlance, but `compressedTexImage2D` requires the
// final data parameter, so we simply pass a heap view starting at zero
// effectively uploading whatever happens to be near address zero. See
// https://github.com/emscripten-core/emscripten/issues/19300.
#if MAX_WEBGL_VERSION >= 2
if ({{{ isCurrentContextWebGL2() }}}) {
if (GLctx.currentPixelUnpackBufferBinding || !imageSize) {
Expand All @@ -1533,7 +1538,7 @@ for (/**@suppress{duplicate}*/var i = 0; i <= {{{ GL_POOL_TEMP_BUFFERS_SIZE }}};
}
#endif
#if INCLUDE_WEBGL1_FALLBACK
GLctx.compressedTexImage2D(target, level, internalFormat, width, height, border, data ? {{{ makeHEAPView('U8', 'data', 'data+imageSize') }}} : null);
GLctx.compressedTexImage2D(target, level, internalFormat, width, height, border, {{{ makeHEAPView('U8', 'data', 'data+imageSize') }}});
#endif
},
Expand All @@ -1552,7 +1557,7 @@ for (/**@suppress{duplicate}*/var i = 0; i <= {{{ GL_POOL_TEMP_BUFFERS_SIZE }}};
}
#endif
#if INCLUDE_WEBGL1_FALLBACK
GLctx.compressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, data ? {{{ makeHEAPView('U8', 'data', 'data+imageSize') }}} : null);
GLctx.compressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, {{{ makeHEAPView('U8', 'data', 'data+imageSize') }}});
#endif
},
Expand Down
10 changes: 10 additions & 0 deletions test/browser/test_anisotropic.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,12 @@ int main(int argc, char *argv[])
while (level < 5) {
printf("uploading level %d: %d, %d\n", level, w, h);
assert(!glGetError());
#if TEST_TEXSUBIMAGE
glCompressedTexImage2D(GL_TEXTURE_2D, level, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, w, h, 0, w*h, NULL);
glCompressedTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, w, h, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, w*h, curr);
#else
glCompressedTexImage2D(GL_TEXTURE_2D, level, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, w, h, 0, w*h, curr);
#endif
assert(!glGetError());
curr += MAX(w, 4)*MAX(h, 4);
w /= 2;
Expand All @@ -136,7 +141,12 @@ int main(int argc, char *argv[])
while (level < 5) {
printf("uploading level %d: %d, %d\n", level, w, h);
assert(!glGetError());
#if TEST_TEXSUBIMAGE
glCompressedTexImage2D(GL_TEXTURE_2D, level, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, w, h, 0, w*h, NULL);
glCompressedTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, w, h, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, w*h, curr);
#else
glCompressedTexImage2D(GL_TEXTURE_2D, level, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, w, h, 0, w*h, curr);
#endif
assert(!glGetError());
curr += MAX(w, 4)*MAX(h, 4);
w /= 2;
Expand Down
8 changes: 6 additions & 2 deletions test/test_browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -2185,9 +2185,13 @@ def test_s3tc_ffp_only(self):
self.reftest('s3tc.c', 's3tc.png', args=['--preload-file', 'screenshot.dds', '-sLEGACY_GL_EMULATION', '-sGL_FFP_ONLY', '-lGL', '-lSDL'])

@requires_graphics_hardware
def test_anisotropic(self):
@parameterized({
'': ([],),
'subimage': (['-DTEST_TEXSUBIMAGE'],),
})
def test_anisotropic(self, args):
shutil.copyfile(test_file('browser/water.dds'), 'water.dds')
self.reftest('test_anisotropic.c', 'test_anisotropic.png', reference_slack=2, args=['--preload-file', 'water.dds', '-sLEGACY_GL_EMULATION', '-lGL', '-lSDL', '-Wno-incompatible-pointer-types'])
self.reftest('test_anisotropic.c', 'test_anisotropic.png', reference_slack=2, args=['--preload-file', 'water.dds', '-sLEGACY_GL_EMULATION', '-lGL', '-lSDL', '-Wno-incompatible-pointer-types'] + args)

@requires_graphics_hardware
def test_tex_nonbyte(self):
Expand Down

0 comments on commit 2b6781e

Please sign in to comment.