blob: 283ebff650285e7672435fd271417ad6ebd2499b [file] [log] [blame]
Name
ARM_shader_framebuffer_fetch_depth_stencil
Name Strings
GL_ARM_shader_framebuffer_fetch_depth_stencil
Contributors
Jan-Harald Fredriksen
Michael Stokes
Sandeep Kakarlapudi
Tom Olson
Contact
Jan-Harald Fredriksen (jan-harald.fredriksen 'at' arm.com)
Status
Shipping.
Version
Revision 7
Last Modified Date: September 26, 2014
Number
TBD
Dependencies
OpenGL ES 2.0 or higher is required.
ESSL 1.00 or higher is required.
This extension is written against the OpenGL ES Shading Language
specification, Language Version 1.00, Document Revision 17 and revision
OpenGL ES 2.0.25 of the API specification.
This extension has a minor dependency on OpenGL ES 3.1.
EXT_shader_framebuffer_fetch and ARM_shader_framebuffer_fetch affect the
wording of this extension.
Overview
Existing extensions, such as EXT_shader_framebuffer_fetch, allow fragment
shaders to read existing framebuffer color data as input. This enables
use-cases such as programmable blending, and other operations that may not
be possible to implement with fixed-function blending.
This extension adds similar capabilities for depth and stencil values.
One use-case for this is soft depth-blending of particles. Normally, this
would require two render passes: one that writes out the depth values of the
background geometry to a depth texture, and one that renders the particles
while reading from the depth texture to do the blending. This extension
allows this to be done in a single pass.
New Procedures and Functions
None
New Tokens
None
New Macro Definitions
#define GL_ARM_shader_framebuffer_fetch_depth_stencil 1
New Built-in Variables
lowp int gl_LastFragStencilARM
If GL_FRAGMENT_PRECISION_HIGH is defined or __VERSION__ is 300 add:
highp float gl_LastFragDepthARM
otherwise add this:
mediump float gl_LastFragDepthARM
Changes to the OpenGL ES 2.0.25 Specification, Chapter 3
Remove the last sentence of Paragraph 2 of Chapter 3.8.1, page 86 ("These
built-in varying variables include [...]" and add:
"These built-in varying variables include the fragment's position, eye z
coordinate, and front-facing flag, as well as the current depth and stencil
values in the framebuffer.
If a shader reads from gl_LastFragDepthARM or gl_LastFragStencilARM and no
image is attached to the depth or stencil attachment, respectively,
results are undefined. No error is generated in this case."
Additions to Chapter 3 of the OpenGL ES Shading Language Specification
Remove Paragraph 2 of section 3.8, page 17, Identifiers ("Identifiers
starting with "gl_" are reserved [...]") and add:
"Identifiers starting with "gl_" are reserved for use by OpenGL ES, and
may not be declared in a shader as either a variable or a function.
However, as noted in the specification, certain predeclared "gl_" names
are allowed to be redeclared in a shader for the specific purpose of
changing their precision qualifier."
Additions to Chapter 7 of the OpenGL ES Shading Language Specification
In section 7.2 (Fragment Shader Special Variables), after the
8th paragraph ("If the shader executes the discard keyword,") and before
the paragraph on about gl_FragCoord, add:
"The fragment shader has access to the read-only built-in variables
gl_LastFragDepthARM and gl_LastFragStencilARM. These variables contain,
respectively, the current value of the depth and stencil buffer for
the pixel to which the current fragment is destined.
If multi-sampling, the values of gl_LastFragDepthARM and
gl_LastFragStencilARM depend on whether the fragment shader is invoked
per fragment or per covered sample. If the shader is invoked per
fragment, the values are an implementation-dependent combination of the
samples within the destination pixel that are covered by the current
fragment. The values will be between the minimum and maximum value of
the samples in the pixel. If the shader is invoked per covered sample,
separate values will be provided for each sample.
If no samples within the destination pixel are covered by the current
fragment, the values of gl_LastFragDepthARM and gl_LastFragStencilARM
are undefined.
Both gl_LastFragDepthARM and gl_LastFragStencilARM are declared with a
default precision qualifier. This can be changed by redeclaring the
corresponding variables with the desired precision qualifier.
Redeclarations must be at global scope and must not otherwise alter the
declared type of these variables.
Reads from gl_LastFragDepthARM and gl_LastFragStencilARM need to wait
for the processing of all previous fragments destined for the current
pixel to complete. For best performance, it is therefore recommended
that reads from either of these built-in variables are done as late in
the execution of the fragment shader as possible."
[[ The below paragraph only applies if ESSL 3.10 is supported ]]
It is not legal for a fragment shader to read from gl_LastFragDepthARM
and gl_LastFragStencilARM if the early_fragment_tests layout qualifier
is specified. This will result in a compile-time error.
Access to gl_LastFragDepthARM and gl_LastFragStencilARM is optional,
and must be enabled by:
#extension GL_ARM_shader_framebuffer_fetch_depth_stencil : <behavior>
Where <behavior> is as specified in section 3.4."
In section 7.2 (Fragment Shader Special Variables), at the end of
the list of built-in variables, add:
"lowp int gl_LastFragStencilARM"
If GL_FRAGMENT_PRECISION_HIGH is defined or __VERSION__ is 300 add:
"highp float gl_LastFragDepthARM"
otherwise add:
"mediump float gl_LastFragDepthARM"
Errors
None
New State
None
New Implementation Dependent State
None
Interactions with EXT_shader_framebuffer_fetch
As for color, when the value of SAMPLE_BUFFERS is 1 and the current
framebuffer depth or stencil is accessed in the fragment shader, the
fragment shader will be invoked separately for each covered sample and a
separate value for the previous framebuffer color will be provided for each
sample.
Interactions with ARM_shader_framebuffer_fetch
As for color, the fragment shader is invoked separately for each covered
sample if FETCH_PER_SAMPLE_ARM is enabled and current framebuffer values
are accessed in the fragment shader.
The presence of multiple color attachments does not affect whether reading
gl_LastFragDepthARM and gl_LastFragStencilARM returns a defined result.
Dependencies on OpenGL ES 3.1
If OpenGL ES 3.1 is not supported, remove all references to the
early_fragment_tests layout qualifier.
Issues
(1) When multisampling is enabled, does the shader run per sample?
RESOLVED.
This behavior is inherited from either EXT_shader_framebuffer_fetch or
ARM_shader_framebuffer_fetch as described in the interactions section.
If neither extension is supported, the shader runs once per fragment.
(2) How does this extension interact with conventional depth and stencil
testing?
RESOLVED: There is no interaction. The two remain orthogonal. The rest
of the pipeline continues as usual after the fragment shader stage.
(3) What should the precision of gl_LastFragDepthARM be?
RESOLVED.
Ideally, it should match the internal precision of the depth buffer, but
OpenGL ES 2.0 does not require highp support in the fragment shader, so
requiring highp may prevent some implementations from supporting this
extension.
Options include:
A) Define gl_LastFragDepth as mediump and return it as 16bit.
B) Define gl_LastFragDepth as mediump, but treat it as higher
precision internally.
C) Define gl_LastFragDepth as highp if the implementation supports
highp, else mediump.
D) Allow the precision of gl_LastFragDepth to be redeclared.
Currently, option C is chosen by default, but the precision can be
redeclared in the shader in the same manner as for gl_FragData in
EXT_shader_framebuffer_fetch
(4) What performance recommendations should the extension contain?
RESOLVED.
There is currently a recommendation to place the framebuffer
read as late as possible in the shader.
(5) Should the value read back include only the samples covered by the
current fragment?
RESOLVED.
Yes, only the samples covered by the current fragment will be read back.
The alternative would be to ignore the coverage mask when returning the
value, but this seems less desirable.
If the shader is run per sample both options would give the same result.
(6) What is meant by undefined results in this extension?
RESOLVED.
Reads from gl_LastFragDepthARM and gl_LastFragStencilARM may return
undefined results in some cases as described in the text. This means
that there is no guarantees on the exact values returned in these
cases. The values will typically be a GPU specific 'default' value,
or correspond to the API clear value. It is guaranteed that these values
will never originate from other GL contexts or applications.
(7) How do the built-in variables added by this extension interract with
the early_fragment_tests layout qualifier in ESSL 3.10?
RESOLVED.
Combining early fragment tests with reads from gl_LastFragDepthARM or
gl_LastFragStencilARM is an error.
The early_fragment_tests qualifier requires per-fragment tests to be
complete before shader execution, but the built-ins added by this
extension will only give predictable results if per-fragment tests are
done late. If this is not the case, later fragments may update the depth
and stencil buffer values before the current fragment reads them.
Revision History
Revision 7, 26/09/2014 (Jan-Harald Fredriksen)
Added interraction with OpenGL ES 3.10 per issue 7.
Revision 6, 25/11/2013 (Jan-Harald Fredriksen)
Clarified behavior when no depth or stencil buffer is bound.
Added and resolved issue 6.
Revision 5, 26/09/2013 (Jan-Harald Fredriksen)
Restricting redeclarations of built-in variables to global scope.
Revision 4, 15/07/2013 (Jan-Harald Fredriksen)
Minor clarification on interaction section.
Revision 3, 10/07/2013 (Jan-Harald Fredriksen)
Updated interactions with ARM_shader_framebuffer_fetch.
Revision 2, 06/05/2013 (Jan-Harald Fredriksen)
Language clarifications.
Revision 1, 02/05/2013 (Jan-Harald Fredriksen)
First draft that only adds depth and stencil fetches.