blob: 01479af7db98a72848b118cc5783c5f450656f1e [file] [log] [blame]
Name
NV_conditional_render
Name Strings
GL_NV_conditional_render
Contact
Eric Werness, NVIDIA (ewerness 'at' nvidia.com)
Pat Brown, NVIDIA (pbrown 'at' nvidia.com)
Contributors
Daniel Koch, NVIDIA
Status
Shipping.
Version
Last Modified Date: 05/26/2014
NVIDIA Revision: 6
Number
OpenGL Extension #346
OpenGL ES Extension #198
Dependencies
The extension is written against the OpenGL 2.0 Specification.
ARB_occlusion_query or OpenGL 1.5 is required in an OpenGL
implementation.
This extension interacts with NVX_conditional_render.
This extension interacts with ARB_occlusion_query2.
This extension interacts with ARB_ES3_compatibility.
This extension interacts trivially with the OpenGL compatibility profile.
This extension interacts with OpenGL 3.0, 3.2, 3.3, and 4.3
EXT_occlusion_query_boolean or OpenGL ES 3.0 is required in an OpenGL ES
implementation.
This extension interacts with EXT_occlusion_query_boolean.
This extension interacts with NV_occlusion_query_samples.
This extension interacts with OpenGL ES 3.0.
Overview
This extension provides support for conditional rendering based on the
results of an occlusion query. This mechanism allows an application to
potentially reduce the latency between the completion of an occlusion
query and the rendering commands depending on its result. It additionally
allows the decision of whether to render to be made without application
intervention.
This extension defines two new functions, BeginConditionalRenderNV and
EndConditionalRenderNV, between which rendering commands may be discarded
based on the results of an occlusion query. If the specified occlusion
query returns a non-zero value, rendering commands between these calls are
executed. If the occlusion query returns a value of zero, all rendering
commands between the calls are discarded.
If the occlusion query results are not available when
BeginConditionalRenderNV is executed, the <mode> parameter specifies
whether the GL should wait for the query to complete or should simply
render the subsequent geometry unconditionally.
Additionally, the extension provides a set of "by region" modes, allowing
for implementations that divide rendering work by screen regions to
perform the conditional query test on a region-by-region basis without
checking the query results from other regions. Such a mode is useful for
cases like split-frame SLI, where a frame is divided between multiple
GPUs, each of which has its own occlusion query hardware.
New Procedures and Functions
void BeginConditionalRenderNV(uint id, enum mode);
void EndConditionalRenderNV(void);
New Tokens
Accepted by the <mode> parameter of BeginConditionalRenderNV:
QUERY_WAIT_NV 0x8E13
QUERY_NO_WAIT_NV 0x8E14
QUERY_BY_REGION_WAIT_NV 0x8E15
QUERY_BY_REGION_NO_WAIT_NV 0x8E16
Additions to Chapter 2 of the OpenGL 2.0 Specification (OpenGL Operation)
(Incorporate the spec edits from the EXT_transform_feedback specification
that move the "Occlusion Queries" Section 4.1.7 -- to between Section 2.11,
Coordinate Transforms and Section 2.12, Clipping, and rename it to
"Asynchronous Queries". Insert a new section immediately after the moved
"Asynchronous Queries" section. If EXT_transform_feedback is incorporated,
this section should be inserted prior the the "Transform Feedback"
section.)
(also modify the BeginQuery language to disallow BeginQuery while the
query object is being used for conditional rendering)
...
BeginQuery sets the active query object name for the query type given by
<target> to <id>. If BeginQuery is called with an <id> of zero, if the
active query object name for <target> is non-zero, if <id> is the active
query object name for any query type, or if <id> is the active query
object for condtional rendering (Section 2.X), the error INVALID OPERATION
is generated.
Section 2.X, Conditional Rendering
Conditional rendering can be used to discard rendering commands based on
the result of an occlusion query. Conditional rendering is started and
stopped using the commands
void BeginConditionalRenderNV(uint id, enum mode);
void EndConditionalRenderNV(void);
<id> specifies the name of an occlusion query object whose results are
used to determine if the rendering commands are discarded. If the result
(SAMPLES_PASSED) of the query is zero, or if the result
(ANY_SAMPLES_PASSED or ANY_SAMPLES_PASSED_CONSERVATIVE) is false, all
rendering commands between BeginConditionalRenderNV and the corresponding
EndConditionalRenderNV are discarded. In this case, Begin, End, all
vertex array commands performing an implicit Begin and End, DrawPixels
(section 3.6), Bitmap (section 3.7), Clear (section 4.2.3), Accum
(section 4.2.4), CopyPixels (section 4.3.3), EvalMesh1 and EvalMesh2
(section 5.1), BlitFramebuffer, ClearBuffer*, and DispatchCompute* have
no effect.
The effect of commands setting current vertex state (e.g., Color or
VertexAttrib) is undefined. If the result (SAMPLES_PASSED) of the
query is non-zero, or if the result (ANY_SAMPLES_PASSED or
ANY_SAMPLES_PASSED_CONSERVATIVE) is true, such commands are not discarded.
<mode> specifies how BeginConditionalRenderNV interprets the results of
the occlusion query given by <id>. If <mode> is QUERY_WAIT_NV, the GL
waits for the results of the query to be available and then uses the
results to determine if subsequent rendering commands are discarded. If
<mode> is QUERY_NO_WAIT_NV, the GL may choose to unconditionally execute
the subsequent rendering commands without waiting for the query to
complete.
If <mode> is QUERY_BY_REGION_WAIT_NV, the GL will also wait for occlusion
query results and discard rendering commands if the result of the
occlusion query is zero. If the query result is non-zero, subsequent
rendering commands are executed, but the GL may discard the results of the
commands for any region of the framebuffer that did not contribute to the
sample count in the specified occlusion query. Any such discarding is
done in an implementation-dependent manner, but the rendering command
results may not be discarded for any samples that contributed to the
occlusion query sample count. If <mode> is QUERY_BY_REGION_NO_WAIT_NV,
the GL operates as in QUERY_BY_REGION_WAIT_NV, but may choose to
unconditionally execute the subsequent rendering commands without waiting
for the query to complete.
If BeginConditionalRenderNV is called while conditional rendering is in
progress, or if EndConditionalRenderNV is called while conditional
rendering is not in progress, the error INVALID_OPERATION is generated.
The error INVALID_VALUE is generated if <id> is not the name of an
existing query object query. The error INVALID_OPERATION is generated if
<id> is the name of a query object with a target other than
SAMPLES_PASSED, ANY_SAMPLES_PASSED, or ANY_SAMPLES_PASSED_CONSERVATIVE, or
if <id> is the name of a query currently in progress.
Additions to Chapter 3 of the OpenGL 2.0 Specification (Rasterization)
None.
Additions to Chapter 4 of the OpenGL 2.0 Specification (Per-Fragment
Operations and the Frame Buffer)
None.
Additions to Chapter 5 of the OpenGL 2.0 Specification (Special Functions)
None.
Additions to Chapter 6 of the OpenGL 2.0 Specification (State and State
Requests)
None.
Additions to Appendix A of the OpenGL 2.0 Specification (Invariance)
None.
Additions to the AGL/GLX/WGL Specifications
None.
GLX Protocol
The following rendering commands are sent to the server as part of
glXRender requests:
BeginConditionalRenderNV
2 12 rendering command length
2 348 rendering command opcode
4 CARD32 id
4 ENUM mode
EndConditionalRenderNV
2 4 rendering command length
2 349 rendering command opcode
Dependencies on NVX_conditional_render
NVX_conditional_render was an early version of this extension. This
extension provides several conditional rendering modes (QUERY_WAIT_NV,
QUERY_NO_WAIT_NV, QUERY_BY_REGION_WAIT_NV, QUERY_BY_REGION_NO_WAIT_NV) not
present in the NVX extension. The NVX extension's commands:
glBeginConditionalRenderNVX(id);
glEndConditionalRenderNVX();
are equivalent to the following commands from this extension:
glBeginConditionalRenderNV(id, QUERY_WAIT_NV);
glEndConditionalRenderNV();
Dependencies on ARB_occlusion_query2 and OpenGL 3.3
If ARB_occlusion_query2 or OpenGL 3.3 is not supported in an OpenGL
implementation, ignore references to the ANY_SAMPLES_PASSED query type.
Dependencies on ARB_ES3_compatibility and OpenGL 4.3
If ARB_ES3_compatibility or OpenGL 4.3 is not supported in an OpenGL
implementation, ignore references to the ANY_SAMPLES_PASSED_CONSERVATIVE
query type.
Dependencies on the OpenGL compatibility profile
In contexts which support the core profile only (for GL) or OpenGL ES,
ignore references to the following commands: Begin, End, DrawPixels,
Bitmap, Accum, Color, CopyPixels, EvalMesh1 and EvalMesh2.
Dependencies on OpenGL 3.0 and OpenGL ES 3.0
If OpenGL 3.0 or OpenGL ES 3.0 is not supported, ignore references to
the BlitFramebuffer and ClearBuffer* commands, unless provided by
other extensions.
Dependencies on OpenGL 4.3 and OpenGL ES 3.1
If OpenGL 4.3 or OpenGL ES 3.1 is not supported, ignore references to
DispatchCompute* commands.
Dependencies on EXT_occlusion_query_boolean and OpenGL ES 3.0
In an OpenGL ES implementation, if OpenGL ES 3.0 is not supported
replace references to query functionality in OpenGL ES 3.0 with
the query functionality provided by EXT_occlusion_query_boolean.
Dependencies on NV_occlusion_query_samples
If NV_occlusion_query_samples is not supported in an OpenGL ES
implementation, ignore all references to SAMPLES_PASSED.
If NV_occlusion_query_samples is supported, replaces references to
SAMPLES_PASSED with SAMPLES_PASSED_NV.
Errors
INVALID_OPERATION is generated by BeginConditionalRenderNV if a previous
BeginConditionalRenderNV command has been executed without a
corresponding EndConditionalRenderNV command.
INVALID_OPERATION is generated by EndConditionalRenderNV if no
corresponding BeginConditionalRenderNV command has been executed.
INVALID_VALUE is generated by BeginConditionalRenderNV if <id> is not the
name of an existing occlusion query object.
INVALID_OPERATION is generated by BeginConditionalRenderNV if <id> is the
name of a query object with a <target> other than SAMPLES_PASSED,
ANY_SAMPLES_PASSED, or ANY_SAMPLES_PASSED_CONSERVATIVE.
INVALID_OPERATION is generated by BeginConditionalRenderNV if the query
identified by <id> is still in progress.
Issues
(1) How should rendering commands other than "normal" Begin/End-style
geometry be affected by conditional rendering?
RESOLVED: All rendering commands (DrawPixels, Bitmap, Clear, Accum,
etc...) are performed conditionally.
(2) What does NO_WAIT do, and why would anyone care?
RESOLVED: Hardware OpenGL implementations are heavily pipelined. After
vertices are transformed, they are assembled into primitives and
rasterized. While a GPU is rasterizing a primitive, it may be
simultaneously transforming the vertices of the next primitive provided
to the GL. At the same time, the CPU may be preparing hardware commands
to process primitives following that one.
Conditional rendering uses the results of rasterizing one primitive (an
occlusion query) to determine whether it will process subsequent ones.
In a pipelined implementation, the initial set of primitives may not be
finished drawing by the time the GL needs the occlusion query results.
Waiting for the query results will leave portions of the GPU temporarily
idle. It may be preferable to avoid the idle time by proceeding with a
conservative assumption that the primitives rendered during the
occlusion query will hit at least one sample. The NO_WAIT <mode>
parameter tells the driver move ahead in that case.
For best performance, applications should attempt to insert some amount
of non-dependent rendering between an occlusion query and the
conditionally-rendered primitives that depend on the query result.
(3) What does BY_REGION do, and why should anyone care?
RESOLVED: Conditional rendering may be used for a variety of effects.
Some of these use conditional rendering only for performance. One
common use would be to draw a bounding box for a primitive
unconditionally with an occlusion query active, and then conditionally
execute a DrawElements call to draw the full (complex) primitive. If
the bounding box is not visible, any work needed to process the full
primitive can be skipped in the conditional rendering pass.
In a split-screen SLI implementation, one GPU might draw the top half of
the scene while a second might draw the bottom half. The results of the
occlusion query would normally be obtained by combining individual
occlusion query results from each half of the screen. However, it is
not necessary to do this for the bounding box algorithm. We could skip
this synchronization point, and each region could instead use only its
local occlusion query results. If the bounding box hits only the bottom
half of the screen, the complex primitive need not be drawn on the top
half, because that portion is known not to be visible. The bottom half
would still be drawn, but the GPU used for the top half could skip it
and start drawing the next primitive specified. The
QUERY_BY_REGION_*_NV modes would be useful in that case.
However, some algorithms may require conditional rendering for
correctness. For example, an application may want to render a
post-processing effect that should be drawn if and only if a point is
visible in the scene. Drawing only half of such an effect due to
BY_REGION tests would not be desirable.
For QUERY_BY_REGION_NO_WAIT_NV, we expect that GL implementations using
region-based rendering will discard rendering commands in any region
where query results are available and the region's sample count is zero.
Rendering would proceed normally in all other regions. The spec
language doesn't require such behavior, however.
(4) Should the <mode> parameter passed to BeginConditionalRenderNV be
specified as a hint instead?
RESOLVED: The "wait" or "don't wait" portion of the <mode> parameter
could be a hint. But it doesn't fit nicely with the FASTEST or NICEST
values that are normally passed to Hint. Providing this functionality
via a <mode> parameter to BeginConditionalRenderNV seems to make the
most sense. Note that the <mode> parameter is specified such that
QUERY_NO_WAIT_NV can be implemented as though QUERY_WAIT_NV were
specified, which makes the "NO_WAIT" part of the mode a hint.
The "BY_REGION" part is also effectively a hint. These modes may be
implemented as though the equivalent non-BY_REGION mode were provided.
Many OpenGL implementations will do all of their processing in a single
region.
(5) What happens if BeginQuery is called while the specified occlusion
query is begin used for conditional rendering?
RESOLVED: An INVALID_OPERATION error is generated.
(6) Should conditional rendering work with any type of query other than
SAMPLES_PASSED (occlusion)?
RESOLVED: Not in this extension. The spec currently requires that <id>
be the name of an occlusion query. There might be other query types
where such an operation would make sense, but there aren't any in the
current OpenGL spec.
(7) What is the effect on current state for immediate mode attribute calls
(e.g., Color, VertexAttrib) made during conditional rendering if the
corresponding occlusion query failed?
RESOLVED: The effect of these calls is undefined. If subsequent
primitives depend on a vertex attribute set inside a conditional
rendering block, and application should re-send the values after
EndConditionalRenderNV.
(8) Should we provide any new query object types for conditional
rendering?
RESOLVED: No. It may be useful to some GL implementations to provide
an occlusion query type that only returns "zero" or "non-zero", or to
provide a query type that is used only for conditional rendering but
doesn't have to maintain results that can be returned to the
application. However, performing conditional rendering using only the
occlusion query mechanisms already in core OpenGL is sufficient for
the platforms targeted by this extension.
(9) What happens if QUERY_BY_REGION_* is used, and the application switches
between windows or FBOs between the occlusion query and conditional
rendering blocks? The "regions" used for the two operations may not be
identical.
RESOLVED: The spec language doesn't specifically address this issue, and
implementations may choose to define regions arbitrarily in this case.
We strongly recommend that applications using QUERY_BY_REGION_* should
not change windows or FBO configuration between the occlusion query and
the dependent rendering.
Usage Example
GLuint queryID = 0x12345678;
// Use an occlusion query while rendering the bounding box of the real
// object.
glBeginQuery(GL_SAMPLES_PASSED, queryID);
drawBoundingBox();
glEndQuery(GL_SAMPLES_PASSED);
// Do some unrelated rendering in hope that the query result will be
// available by the time we call glBeginConditionalRenderNV.
// Now conditionally render the real object if any portion of its
// bounding box is visible.
glBeginConditionalRenderNV(queryID, GL_QUERY_WAIT_NV);
drawComplicatedObject();
glEndConditionalRenderNV();
Revision History
Rev. Date Author Changes
---- -------- -------- --------------------------------------------
6 05/26/14 dkoch Add interactions with later GL extensions and
core versions.
Add interactions with OpenGL ES extensions
and versions.
5 08/07/12 pbrown Fix minor typos; added interaction with the
older NVX_conditional_render extension.
4 09/22/10 srahman Added GLX protocol.
3 02/19/08 pbrown Document the INVALID_OPERATION error from
calling BeginQuery while the query is used
for conditional rendering in the spec body.
2 11/29/07 ewerness First public release
1 Internal revisions