Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix calls to glCcompressedTexImage2D with null pixel data #22453

Merged
merged 1 commit into from
Aug 27, 2024

Conversation

sbc100
Copy link
Collaborator

@sbc100 sbc100 commented Aug 26, 2024

I believe this has always been an issue with emscripten's WebGL1 code which only recently became more prevalent with #21445.

Fixes: #19300

@@ -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.

@@ -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 space but don't upload" in
Copy link
Collaborator

Choose a reason for hiding this comment

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

My understanding of the conversation on the issue was that if data is null, that's literally just telling GL to read from the null pointer, it has no actual meaning. (glTexImage2D special-cases null, but glCompressedTexImage2D does not.) So seems to me like we should have a debug assert that data isn't null.

Copy link
Collaborator Author

@sbc100 sbc100 Aug 27, 2024

Choose a reason for hiding this comment

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

IIUC, data is allowed to be null here (i.e. in the GLES C API), and the (in GLES) that means "just allocate some space". It certainly doesn't mean "read from address zero". since that would instantly crash, right?

I think its just an oversight in the GLES man page that it doesn't document the null special case. See #19300 (comment):

"
If the data argument of CompressedTexImage1D, CompressedTexImage2D, or CompressedTexImage3D is NULL, and the pixel unpack buffer object is zero, a texture image with unspecified image contents is created, just as when a NULL pointer is passed to TexImage1D, TexImage2D, or TexImage3D.
"

Copy link
Collaborator

Choose a reason for hiding this comment

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

In GLES3, data is allowed to be null. In GLES2 the specification missed clarifying whether data is allowed to be null or not. KhronosGroup/WebGL#3686

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ahh, I didn't read far enough in the GLES3 spec because it was buried way at the bottom under the table!

Copy link
Collaborator

Choose a reason for hiding this comment

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

a little clarification:

Suggested change
// `data` may be null here, which means "allocate space but don't upload" in
// `data` may be null here, which means "allocate uninitialized space but don't upload" in

Copy link
Collaborator

@juj juj left a comment

Choose a reason for hiding this comment

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

Looks great to me!

@sbc100
Copy link
Collaborator Author

sbc100 commented Aug 27, 2024

@kenrussell, can you confirm this is the solution you recommend?

@@ -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 space but don't upload" in
Copy link
Collaborator

Choose a reason for hiding this comment

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

a little clarification:

Suggested change
// `data` may be null here, which means "allocate space but don't upload" in
// `data` may be null here, which means "allocate uninitialized space but don't upload" in

I believe this has always been an issue with emscripten's WebGL1 code
which only recently became more prevalent with emscripten-core#21445.

Fixes: emscripten-core#19300
@sbc100 sbc100 enabled auto-merge (squash) August 27, 2024 17:08
@sbc100 sbc100 merged commit f104079 into emscripten-core:main Aug 27, 2024
27 checks passed
@sbc100 sbc100 deleted the glCcompressedTexImage2D branch August 27, 2024 18:17
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.

glCompressedTexImage2D error
3 participants