I think I've tracked down a source of a ton of woes for me so far, but I'm not sure what the best solution GD-side is:
Prep:
Shader1, with 5 vertexAttribs
Shader2, with 1 vertexAttrib
Bind the (large, but mostly static) 4 (of 5) vertexAttribs for Shader1
Drawing a full frame:
drawCall1 uses Shader1, only binds the 1 remaining (changing) vertexAttrib
drawCall2 uses Shader2 with 1 vertexAttrib, bind that data.
The problem:
- The 1 vertexAttrib in
Shader2 is at location 0.
- We switch back to
Shader1 when starting the next frame
- The vertexAttrib at location 0 is now bound to the data/buffer meant for
Shader2, rather than what was meant for Shader1.
This has happened over and over again (especially as I try to minimize the number of binds/etc.), and is a constant source of state bleeding through draw calls. The challenge is that this may be the correct behavior (allow me to have very fine-grained control over what buffer is bound when). But if that's the case, requiring the program at time of binding seems strange, because GD isn't keeping track of resetting the correct buffers when calling draw.
Ideally (from an api, perhaps not performance PoV) when I gd/bind some data to program-1, it would keep track of the current state of inputs/buffers, and then on subsequent draw calls that use program-1 it would diff the actual state of the WebGL bound buffers and figure out which inputs have been "stolen" by other programs since the last draw call.
@toji has mentioned this several times on SO (http://stackoverflow.com/questions/9261258/multiple-programs-in-webgl-doesnt-work?lq=1):
"Basically, you want to treat every time you change programs as if it's the first time you're setting up a draw call."
Hope this is clear enough, happy to go into more detail while it's fresh in my mind.
I think I've tracked down a source of a ton of woes for me so far, but I'm not sure what the best solution GD-side is:
The problem:
Shader2is at location 0.Shader1when starting the next frameShader2, rather than what was meant forShader1.This has happened over and over again (especially as I try to minimize the number of binds/etc.), and is a constant source of state bleeding through draw calls. The challenge is that this may be the correct behavior (allow me to have very fine-grained control over what buffer is bound when). But if that's the case, requiring the program at time of binding seems strange, because GD isn't keeping track of resetting the correct buffers when calling draw.
Ideally (from an api, perhaps not performance PoV) when I
gd/bindsome data toprogram-1, it would keep track of the current state of inputs/buffers, and then on subsequent draw calls that useprogram-1it would diff the actual state of the WebGL bound buffers and figure out which inputs have been "stolen" by other programs since the last draw call.@toji has mentioned this several times on SO (http://stackoverflow.com/questions/9261258/multiple-programs-in-webgl-doesnt-work?lq=1):
Hope this is clear enough, happy to go into more detail while it's fresh in my mind.