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

[Public WebGL] Proposed WebGL spec modifications for a D3D implementation

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 us 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:
  Remove StencilMaskSeparate.  -or-
   StencilMaskSeparate returns INVALID_VALID if face is not FRONT_AND_BACK. -or- 
        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 ); 
    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 );
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_VALUE 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 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 and the invariant qualifier and #pragma are ignored.