KhronosGroup / WebGL

The Official Khronos WebGL Repository
Other
2.6k stars 667 forks source link

Change spec and add conformance tests asserting variables are initialized to zero #1266

Open kenrussell opened 8 years ago

kenrussell commented 8 years ago

Per discussion in the working group: it's been a longstanding problem that WebGL didn't mandate that variables (global, local) in shaders are initialized to zero. Many implementations enforce this but some don't, which has historically led to behavioral differences of some shaders which accumulate values.

After discussing the options, it's been resolved to initialize these variables to zero explicitly. (Alternatives included failing shader compilation if there was a possibility of using uninitialized values, but enforcing this consistently is problematic, since sophisticated compilers may be able to prove things simpler compilers can't.) Microsoft's WebGL implementation has been initializing variables to zero all along, and there doesn't seem to be a performance penalty from doing so.

The WebGL 1.0 specification needs to be updated and some conformance tests written for this. Mac OS X is one platform where in the past it was observed that GLSL variables weren't initialized to 0, so it's possible that implementations can be most easily verified on that platform.

gfxstrand commented 8 years ago

As a driver developer, I would really like to see browsers start doing this. There is a theoretical security concern where uninitialized values may get values from other shaders running on the system. I don't think that's a big concern, but it is there. The bigger issue, as mentioned above, is an issue of normalization.

It's worth noting that D3D (not sure what all versions) does require variables to get auto-initialized to zero so any webGL versions running on D3D, angle, or NVIDIA hardware (their hardware zero-inits at the top of the shader) is going to get zero-initialized by default. This leaves non-zero-initializing implementations as kind-of a corner case (probably less than 50%).

One other note is that (as hinted above) I would like to see this happen in the browser and not become another robustness requirement on GL. The WebGL implementations are doing shader mangling anyway so it's pretty easy for them to provide default initializers. If they initialize a few too many things, driver shader compilers should be pretty good at chewing through them so it shouldn't be a big performance problem. I specifcially don't want that requirement in the driver because it does hide issues that should be fixed in the shader. (I think that ANGLE and other ways of running on top of D3D make the statistics of how many WebGL implementations zero-initialize very different from classic GL or GLES. App writers are liable to find those issues with their shader if they run on regular GL or GLES.) Also, there are cases in which initializing everything does add extra instructions to the shader that the compiler cannot get rid of so I'd like to not enforce drivers to make worse shaders.

kenrussell commented 8 years ago

The browsers will enforce this and not require the drivers to do so. It's just not yet risen to the top of the priority stack yet to spec and, more importantly, test yet.

gfxstrand commented 8 years ago

Glad to hear that you plan to do it in the browser and that it's still on your radar. Consider the above post a big "yes please!" from me. :-)