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 for zero count in glUniform family of functions #21573

Merged
merged 1 commit into from
Mar 26, 2024

Conversation

sbc100
Copy link
Collaborator

@sbc100 sbc100 commented Mar 20, 2024

The previous fix for this was in #16837, but I looks like that only covered the new "garbage-free" webgl2 path. When old webgl1 path was still using the zero count value.

As part of this change I resurrected
test_webgl_draw_triangle_with_uniform_color.c which has not actually
be used since #20925.

Fixes: #21567

@sbc100
Copy link
Collaborator Author

sbc100 commented Mar 20, 2024

The code size code here is either 2 bytes or 4 bytes of total compressed size.

However, the alternative would be add an additional count && to yet more like lines in each of these functions, which depending on the build config can also have a code size cost (due to many count && in the each function).

@sbc100 sbc100 force-pushed the uniform4fv_zero branch 2 times, most recently from 0935560 to 386965b Compare March 20, 2024 16:19
Copy link
Member

@kripken kripken left a comment

Choose a reason for hiding this comment

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

lgtm, but can we add a test for this?

@sbc100
Copy link
Collaborator Author

sbc100 commented Mar 20, 2024

lgtm, but can we add a test for this?

Can I use the same excuse that was used last time not to? #16837 (comment) :)

@kripken
Copy link
Member

kripken commented Mar 20, 2024

I'll meet you halfway: how about a test for one of them? 😄 that would at least test the recurring pattern, and have a good chance of catching regressions assuming we regress them all at once.

@sbc100
Copy link
Collaborator Author

sbc100 commented Mar 20, 2024

Test added! Confirmed that it fails without this change.

@sbc100 sbc100 requested a review from kripken March 21, 2024 18:15
@sbc100
Copy link
Collaborator Author

sbc100 commented Mar 21, 2024

OK to land now?

@sbc100 sbc100 enabled auto-merge (squash) March 21, 2024 18:16
src/library_webgl.js Outdated Show resolved Hide resolved
@juj
Copy link
Collaborator

juj commented Mar 21, 2024

I see that in miniTempWebGLInt/FloatBuffers we have

for (/**@suppress{duplicate}*/var i = 0; i < {{{ GL_POOL_TEMP_BUFFERS_SIZE }}}; ++i) {
  miniTempWebGLFloatBuffers[i] = miniTempWebGLFloatBuffersStorage.subarray(0, i+1);
}
for (/**@suppress{duplicate}*/var i = 0; i < {{{ GL_POOL_TEMP_BUFFERS_SIZE }}}; ++i) {
  miniTempWebGLIntBuffers[i] = miniTempWebGLIntBuffersStorage.subarray(0, i+1);
}

and then at site of use there is that

    if (count <= {{{ GL_POOL_TEMP_BUFFERS_SIZE }}}) {
      // avoid allocation when uploading few enough uniforms
      var view = miniTempWebGLIntBuffers[count-1];
      for (var i = 0; i < count; ++i) {
        view[i] = {{{ makeGetValue('value', '4*i', 'i32') }}};
      }
    } else

Maybe we can fix this by changing miniTempWebGLIntBuffersStorage.subarray(0, i+1); to miniTempWebGLIntBuffersStorage.subarray(0, i);, and then var view = miniTempWebGLIntBuffers[count-1]; to var view = miniTempWebGLIntBuffers[count];?

That should result in a zero-sized arraybuffer being passed to the function calls naturally?

Not sure why that original -1 offset existed, maybe some idiomatic thinking that allocating a dummy zero-sized array as first entry of the pooled buffers would have been silly, hence the offset. But that should be fine to do, and it would then allow count=0 naturally?

@sbc100
Copy link
Collaborator Author

sbc100 commented Mar 21, 2024

I see that in miniTempWebGLInt/FloatBuffers we have

for (/**@suppress{duplicate}*/var i = 0; i < {{{ GL_POOL_TEMP_BUFFERS_SIZE }}}; ++i) {
  miniTempWebGLFloatBuffers[i] = miniTempWebGLFloatBuffersStorage.subarray(0, i+1);
}
for (/**@suppress{duplicate}*/var i = 0; i < {{{ GL_POOL_TEMP_BUFFERS_SIZE }}}; ++i) {
  miniTempWebGLIntBuffers[i] = miniTempWebGLIntBuffersStorage.subarray(0, i+1);
}

and then at site of use there is that

    if (count <= {{{ GL_POOL_TEMP_BUFFERS_SIZE }}}) {
      // avoid allocation when uploading few enough uniforms
      var view = miniTempWebGLIntBuffers[count-1];
      for (var i = 0; i < count; ++i) {
        view[i] = {{{ makeGetValue('value', '4*i', 'i32') }}};
      }
    } else

Maybe we can fix this by changing miniTempWebGLIntBuffersStorage.subarray(0, i+1); to miniTempWebGLIntBuffersStorage.subarray(0, i);, and then var view = miniTempWebGLIntBuffers[count-1]; to var view = miniTempWebGLIntBuffers[count];?

That should result in a zero-sized arraybuffer being passed to the function calls naturally?

Not sure why that original -1 offset existed, maybe some idiomatic thinking that allocating a dummy zero-sized array as first entry of the pooled buffers would have been silly, hence the offset. But that should be fine to do, and it would then allow count=0 naturally?

Thats works great!

The previous fix for this was in emscripten-core#16837, but I looks like that only
covered the new "garbage-free" webgl2 path.  When old webgl1 path was
still using the zero count value.

As part of this change I resurrected
`test_webgl_draw_triangle_with_uniform_color.c` which has not actually
be used since emscripten-core#20925.

Fixes: emscripten-core#21567
@sbc100
Copy link
Collaborator Author

sbc100 commented Mar 26, 2024

Ping...

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.

Nice!

@sbc100 sbc100 merged commit 65b26e3 into emscripten-core:main Mar 26, 2024
29 checks passed
@sbc100 sbc100 deleted the uniform4fv_zero branch March 26, 2024 11:34
kainino0x added a commit to kainino0x/emscripten that referenced this pull request Jun 22, 2024
library_webgl.js attempts to use a pool of temp float or int buffers for
uniform uploads up to 288 elements, however it would only allocate 288
temp buffers, so 0 through 287 would be fine but 288 would crash
(miniTempWebGLFloatBuffers[288] would be undefined).

Fix for emscripten-core#21573
kainino0x added a commit that referenced this pull request Jun 24, 2024
library_webgl.js attempts to use a pool of temp float or int buffers for
uniform uploads up to 288 elements, however it would only allocate 288
temp buffers, so 0 through 287 would be fine but 288 would crash
(miniTempWebGLFloatBuffers[288] would be undefined).

Confirmed manually that any one of the six "Just at the optimization
limit" calls would crash before, and with the fix does not.

Fix for the change in PR #21573
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.

Uncaught TypeError: Failed to execute 'uniform4fv' on 'WebGL2RenderingContext': Overload resolution failed.
3 participants