Hash :
dadd1986
Author :
Date :
2020-04-21T01:50:00
Implement GL_APPLE_clip_distance - Built-in variable gl_ClipDistance has been added to compiler. - Desktop GL: gl_ClipDistance is supported since GL 3.0. Enable/Disable each gl_ClipDistances[i] works out of the box via glEnable(). - Vulkan/Metal: Use uniform variable to control writing to each gl_ClipDistance. One bit flag controls one element in the gl_ClipDistance array. The writing to the disabled element in vertex shader will be ignored, and turned into zero assignment instead. - Direct3D/Mobile GL: Not implemented yet. - Added ClipDistanceTest to gl_tests and compiler unittests. - GL_APPLE_clip_distance is a subset of GL_EXT_clip_cull_distance, so GL_EXT_clip_cull_distance could be implemented in future if needed. Bug: angleproject:4452 Change-Id: I571ac8b56826989808a680226a04bec4cf59988e Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2084324 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: Jamie Madill <jmadill@chromium.org>
OpenGL GLSL’s gl_ClipDistance is supported by Vulkan. However, OpenGL supports disabling/enabling
individual gl_ClipDistance[i] on the API level side. Writing to gl_ClipDistance[i] in shader
will be ignored if it is disabled. Vulkan doesn’t have any equivalent API to disable/enable the
writing, though writing to a gl_ClipDistance[i] variable automatically enables it.
To implement this enabling/disabling API in Vulkan back-end:
gl_ClipDistance[i] assignment to an assignment to
ANGLEClipDistance[i] variable. clipDistancesEnabled will contain one bit flag for each
enabled gl_ClipDistance[i]. This variable supports up to 32 gl_ClipDistance indices. gl_ClipDistance[i] will be assigned the respective
value from ANGLEClipDistance[i]. On the other hand, those disabled elements will be assigned
zero value. This step is described in the following code: for (int index : arraylength(gl_ClipDistance))
{
if (ANGLEUniforms.clipDistancesEnabled & (0x1 << index))
gl_ClipDistance[index] = ANGLEClipDistance[index];
else
gl_ClipDistance[index] = 0;
}
gl_MaxClipDistances, then
the loop will have at most index+1 iterations. If there is at least one index not being
integral constant value known at compile time then declared size of gl_ClipDistance
will be the loop size. gl_ClipDistance, then all the steps above will be
omitted.
# gl_ClipDistance extension support in Vulkan back-end
OpenGL GLSL's `gl_ClipDistance` is supported by Vulkan. However, OpenGL supports disabling/enabling
individual `gl_ClipDistance[i]` on the API level side. Writing to `gl_ClipDistance[i]` in shader
will be ignored if it is disabled. Vulkan doesn't have any equivalent API to disable/enable the
writing, though writing to a `gl_ClipDistance[i]` variable automatically enables it.
To implement this enabling/disabling API in Vulkan back-end:
- The shader compiler will translate each `gl_ClipDistance[i]` assignment to an assignment to
`ANGLEClipDistance[i]` variable.
- A special driver uniform variable `clipDistancesEnabled` will contain one bit flag for each
enabled `gl_ClipDistance[i]`. This variable supports up to 32 `gl_ClipDistance` indices.
- At the end of vertex shader, the enabled `gl_ClipDistance[i]` will be assigned the respective
value from `ANGLEClipDistance[i]`. On the other hand, those disabled elements will be assigned
zero value. This step is described in the following code:
```
for (int index : arraylength(gl_ClipDistance))
{
if (ANGLEUniforms.clipDistancesEnabled & (0x1 << index))
gl_ClipDistance[index] = ANGLEClipDistance[index];
else
gl_ClipDistance[index] = 0;
}
```
- Some minor optimizations:
- Only those indices that are referenced in the original code will be used in if else block
above.
- Those elements whose index not referenced in the original code will be zeroised instead.
- If the original code only uses up to an index < `gl_MaxClipDistances`, then
the loop will have at most `index+1` iterations. If there is at least one index not being
integral constant value known at compile time then declared size of `gl_ClipDistance`
will be the loop size.
- Finally, if the original code doesn't use `gl_ClipDistance`, then all the steps above will be
omitted.