Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://community.khronos.org/t/glcompressedteximage2d-and-null-data/41505

IIUC this link is saying you can call glTexImage2D with a null pointer to allocate the texture, then glCompressedTexSubImage2D to initialize it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According #19300, GLES users expect to be able to call glCompressedTexImage2D with the null final argument.

So I think the test code here should use what the existing GLES code expects to be able to do.

Copy link
Collaborator

@juj juj Aug 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC this link is saying you can call glTexImage2D with a null pointer to allocate the texture, then gl_Compressed_TexSubImage2D to initialize it.

I am not sure if that is how the spec is supposed to work. Calling (Compressed)TexSubImage will not change a type of the texture that was previously created with a call to (Compressed)TexImage?

I tried with the following test code:

<!DOCTYPE html><html><body><script>
var gl = document.createElement("canvas").getContext('webgl');
gl.bindTexture(gl.TEXTURE_2D, gl.createTexture());
var dxt1 = gl.getExtension('WEBGL_compressed_texture_s3tc').COMPRESSED_RGB_S3TC_DXT1_EXT;
var w = 1024;
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, w, w, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
var foo = new Uint8Array(w*w/2);
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, w, w, dxt1, foo);
</script></body></html>

which gives a warning in Firefox:

image

that suggests the same.

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