-
Notifications
You must be signed in to change notification settings - Fork 931
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
WebGL Internal error: 0x00000502: Vertex buffer is not big enough for the draw call #3578
Comments
And this error doesn't appear on wgpu 0.14.0, so the problem appeared somewhere on the way from wgpu 0.14.0 to 0.15.2, and looks like it is not libANGLE bug. |
Still having trouble simplifying a case to reproduce this. I'm not seeing much that would've changed between 0.14.0 and 0.15.2. Is it possible it's the |
That's exactly it. Reverting to glow::STATIC_DRAW from glow::DYNAMIC_DRAW fixes the problem. So this is about #3391 and #3371. |
Very weird. We can't back that fix out either because that breaks some older devices.
Is it possible that the buffer sizes are different between the buffer at creation vs. the one we use during draw? I don't think so because we I believe we're supposed to be pre-allocating the buffer fully and copying into that original buffer. I wonder if we can easily trace this code path through ANGLE to see how we can workaround it, or possibly file a bug upstream to ANGLE if the buffer size is correct. |
There is a very distant possibility that this is the driver accidentally exposing its limited size for host_mappable|gpu_local memory buffers, but you're right that the spec says it's a hint only, and the allocation should fail over to whatever STATIC_DRAW does. That said, I don't understand what's going on in #3391. STATIC_DRAW should always, always work. This sounds like another bug elsewhere, honestly. Otherwise we should have hit this long ago in WebGL implementations in browsers. So we should definitely prove out whether it's ANGLE at fault first! |
I did manage to reproduce that issue with regular webgl JS (excluding wgpu from the picture). I'd have to bring out an old device to test it again, but it was literally something like "after STATIC_DRAW, more copies/writes are ignored until the next frame", on all browsers but specific older (usually intel) devices. WGPU always hit it because we basically allocated, zerod out, and then copied the initial data - the STATIC_DRAW was frozen in place on either the initial allocation or the zeroed out copy, and wouldn't accept the initial data. If we didn't do the initial zeroing out copy then it may have worked more often, but I hadn't put much time into investigating that. |
We are hitting the exact same issue here. Specifically in Chrome on Windows (no problem on other OSes or firefox). After coming across the reference to #3391 in the code, we also tried reverting DYNAMIC_DRAW back to STATIC_DRAW and confirm it "fixes" the problem for us as well. |
@jleibs and me investigated this for a bit and found someone else fixing that in their library by always using draw-instanced: mosra/magnum#539
Orthogonal to that the workaround of using DYNAMIC_DRAW over STATIC_DRAW is still concerning :(. Would be nice if we could narrow down on which devices STATIC_DRAW doesn't work and apply that only then. |
Probably
in ANGLE is bugged, because it returns some nonsence when checking against
But not sure how to prove or debug it. |
It would be interesting to see how |
Minimal repro: <canvas></canvas>
<script>
const gl = document.querySelector("canvas").getContext("webgl2");
const program = gl.createProgram();
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(
vertexShader,
`#version 300 es
in float scale; void main() { gl_Position = vec4(vec2(gl_VertexID % 2, gl_VertexID % 3) * scale, 0, 1); }`
);
gl.shaderSource(
fragmentShader,
`#version 300 es
precision mediump float; out vec4 color; void main() { color = vec4(1, 0, 0, 1); }`
);
gl.compileShader(vertexShader);
gl.compileShader(fragmentShader);
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.detachShader(program, vertexShader);
gl.detachShader(program, fragmentShader);
gl.useProgram(program);
gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array([0.5]),
// Switch to STATIC_DRAW and both will work
gl.DYNAMIC_DRAW
);
const loc = gl.getAttribLocation(program, "scale");
gl.enableVertexAttribArray(loc);
gl.vertexAttribPointer(loc, 1, gl.FLOAT, false, 0, 0);
gl.vertexAttribDivisor(loc, 1);
// Both of these should succeed
gl.drawArraysInstanced(gl.TRIANGLES, 0, 3, 1);
gl.drawArrays(gl.TRIANGLES, 0, 3);
</script> |
I submitted a bug to Chrome/ANGLE at https://bugs.chromium.org/p/chromium/issues/detail?id=1425606 The correct workaround is to use |
This has also been fixed in ANGLE upstream (i.e., including Chrome) now 🎉 |
This happens on WebGL when recreating a buffer:
[.WebGL-0000554C38753500] GL_INVALID_OPERATION: Error: 0x00000502, in ..\..\third_party\angle\src\libANGLE\renderer\d3d\VertexDataManager.cpp, reserveSpaceForAttrib:520. Internal error: 0x00000502: Vertex buffer is not big enough for the draw call.
At the moment it is hard to provide small example to reproduce, sadly.
The text was updated successfully, but these errors were encountered: