[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Public WebGL] WebGL spec modifications for D3D




Following up on a request made during the weekly WebGL teleconference, I'm reposting a list of spec changes we think are necessary to get WebGL implemented on top of D3D9.  Please let me know if you have any strong preferences regarding the options for #1 and #4. 

****
With great input from Daniel Koch of TransGaming we compiled a list of proposed modifications to the WebGL spec that will allow for a reasonable implementation of the API on top of Direct3D 9.0.  Please take a look and let me know if there are any objections to the proposed changes or stuff we've missed:

1. Restrict allowable arguments to stencilMaskSeparate and stencilFuncSeparate.  The underlying issue here is that D3D9 isn't as flexible as GL when it comes to supplying different stencil masks and functions to front and back facing triangles. More specifically here's a listing of the GL stencil related functions/parameters and what portions can be supported via D3D9:

Stencil Separate (Write) Mask:
void StencilMask( uint mask );
void StencilMaskSeparate( enum face, uint mask );
    mask ==> D3DRS_STENCILWRITEMASK  (no FRONT/BACK support)
There is no equivalent separate mask state in D3D.  Spec change:
a)  Remove StencilMaskSeparate.  -or-
b)  StencilMaskSeparate returns INVALID_VALUE if face is not FRONT_AND_BACK. -or- 
c)  Draw returns INVALID_OPERATION if FRONT mask != BACK mask.

Stencil Function Separate Ref & Mask:
void StencilFunc( enum func, int ref, uint mask ); 
void StencilFuncSeparate( enum face, enum func, int ref, uint mask ); 
    FRONT func ==> D3DRS_STENCILFUNC
    BACK func ==> D3DRS_CCW_STENCILFUNC
    ref ==> D3DRS_STENCILREF  (no FRONT/BACK support)
    mask ==> D3DRS_STENCILMASK (no FRONT/BACK support)
In D3D there is separate stencil state for func, but not for ref and mask.  Separate func is genuinely useful, and thus removing StencilFuncSeparate is not a good option.  Spec change: Draw returns INVALID_OPERATION if FRONT ref  != BACK ref or FRONT mask != BACK mask.

Stencil Separate Operation:
void StencilOp( enum sfail, enum dpfail, enum dppass ); 
void StencilOpSeparate( enum face, enum sfail, enum dpfail, enum dppass );
    FRONT sfail ==> D3DRS_STENCILFAIL
    BACK sfail ==>  D3DRS_CCW_STENCILFAIL
    FRONT dpfail ==> D3DRS_STENCILZFAIL
    BACK dpfail ==> D3DRS_CCW_STENCILZFAIL
    FRONT dppass ==> D3DRS_STENCILPASS
    BACK dppass ==> D3DRS_CCW_STENCILPASS
D3D has corresponding state for all of these, so no changes are required for this.

2. Limit vertex stride to 255. Spec change:  vertexAttribPointer raises a GL_INVALID_VALUE error if stride parameter value exceeds 255.

3. Viewport depth range.  D3D doesn't support  "far < near", and this would be very annoying to have to emulate. I believe there was buy-in at the F2F to limit valid parameters to glDepthRangef to  "near <= far".   Spec  change:   glDepthRangef returns GL_INVALID_OPERATION if f < n.

4. Conflicting constant color usage. In D3D we can't directly support alpha blending for the cases where the source blend function is set to GL_CONSTANT_ALPHA (or GL_ONE_MINUS_CONSTANT_ALPHA), and the destination blend function is set to GL_CONSTANT_COLOR, or vice versa. That's because GL_CONSTANT_ALPHA has no D3D9 equivalent and if we replicate the alpha to the RGB components we can no longer use the RGB components for the other blend function.  Spec change: 
  a) completely remove support for GL_CONSTANT_ALPHA and ONE_MINUS_CONSTANT_ALPHA (ie return GL_INVALID_VALUE), -or-
  b) glBlendFunc/Separate sets GL_INVALID_OPERATION if a source function is GL_CONSTANT_ALPHA or GL_ONE_MINUS_CONSTANT_ALPHA and the corresponding destination function is GL_CONSTANT_COLOR or or GL_ONE_MINUS_CONSTANT_COLOR, or vice versa.

5. Shader invariance as described in GLSL ES spec (http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf) sections 4.6.1 and enforced by the "invariant" qualifier and #pragma STDGL invariant(all) cannot be guaranteed in D3D9.  Spec change: No guarantees are made about invariance in shader outputs the invariant qualifier and #pragma are ignored.