• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Name
2
3    EXT_primitive_bounding_box
4
5Name Strings
6
7    GL_EXT_primitive_bounding_box
8
9Contact
10
11    Jesse Hall (jessehall 'at' google.com)
12
13Contributors
14
15    Alex Chalfin, ARM
16    Jan-Harald Fredriksen, ARM
17    Dan Stoza, Google
18    Cass Everitt, NVIDIA
19    Daniel Koch, NVIDIA
20    Jeff Bolz, NVIDIA
21    Pat Brown, NVIDIA
22    Bill Licea-Kane, Qualcomm
23    Maurice Ribble, Qualcomm
24    Vineet Goel, Qualcomm
25
26Status
27
28    Complete
29
30Version
31
32    Last Modified Date: February 13, 2018
33    Revision: 8
34
35Number
36
37    OpenGL ES Extension #186
38
39Dependencies
40
41    OpenGL ES 3.1 and OpenGL ES Shading Language 3.10 are required.
42
43    This specification is written against the OpenGL ES 3.1 (March 17,
44    2014) and OpenGL ES 3.10 Shading Language (March 17, 2014)
45    Specifications.
46
47    This extension interacts with the OpenGL ES 3.20 Shading Language.
48
49    This extension interacts with EXT_tessellation_shader.
50
51    EXT_geometry_shader trivially affects the definition of this extension.
52
53Overview
54
55    On tile-based architectures, transformed primitives are generally written
56    out to memory before rasterization, and then read back from memory for each
57    tile they intersect. When geometry expands during transformation due to
58    tessellation or one-to-many geometry shaders, the external bandwidth
59    required grows proportionally. This extension provides a way for
60    implementations to know which tiles incoming geometry will intersect before
61    fully transforming (and expanding) the geometry. This allows them to only
62    store the unexpanded geometry in memory, and perform expansion on-chip for
63    each intersected tile.
64
65    New state is added to hold an axis-aligned bounding box which is assumed to
66    contain any geometry submitted. An implementation is allowed to ignore any
67    portions of primitives outside the bounding box; thus if a primitive extends
68    outside of a tile into a neighboring tile that the bounding box didn't
69    intersect, the implementation is not required to render those portions. The
70    tessellation control shader is optionally able to specify a per-patch
71    bounding box that overrides the bounding box state for primitives generated
72    from that patch, in order to provide tighter bounds.
73
74    The typical usage is that an application will have an object-space bounding
75    volume for a primitive or group of primitives, either calculated at runtime
76    or provided with the mesh by the authoring tool or content pipeline. It will
77    transform this volume to clip space, compute an axis-aligned bounding box
78    that contains the transformed bounding volume, and provide that at either
79    per-patch or per-draw granularity.
80
81IP Status
82
83    No known IP claims.
84
85New Procedures and Functions
86
87    void PrimitiveBoundingBoxEXT(float minX, float minY, float minZ, float minW,
88                                 float maxX, float maxY, float maxZ, float maxW);
89
90New Tokens
91
92    Accepted by the <pname> parameter of GetBooleanv, GetFloatv, GetIntegerv,
93    and GetInteger64v:
94
95        PRIMITIVE_BOUNDING_BOX_EXT                          0x92BE
96
97Additions to the OpenGL ES 3.1 Specification
98
99    Modify section 11.1ts.1.2.3, "Tessellation Control Shader Outputs", as added
100    by EXT_tessellation_shader:
101
102    In the second paragraph, add gl_BoundingBoxEXT[] to the list of built-in
103    per-patch output arrays:
104
105    Tessellation shaders additionally have three built-in per-patch output
106    arrays, gl_TessLevelOuter[], gl_TessLevelInner[], and gl_BoundingBoxEXT[].
107    These arrays ... as discussed in the following section. gl_BoundingBoxEXT[]
108    is an array of two vec4 values that should be used instead of the value of
109    PRIMITIVE_BOUNDING_BOX_EXT as the primitive bounding box (see Section
110    13.1pbb) for primitives generated from the output patch.
111
112    Modify the sixth paragraph of the section to state that gl_BoundingBoxEXT[]
113    counts against the per-patch limit:
114
115    ... The built-in outputs gl_TessLevelOuter[] and gl_TessLevelInner[] are not
116    counted against the per-patch limit. The built-in output
117    gl_BoundingBoxEXT[], if statically assigned by the shader, is counted
118    against the per-patch limit. The total number of components...
119
120
121    Modify section 11.1ts.3.3, "Tessellation Evaluation Shader Inputs", as added
122    by EXT_tessellation_shader:
123
124    Insert a new paragraph after the list of special input variables in
125    paragraph 2:
126
127    The special tessellation control shader output gl_BoundingBoxEXT[] is
128    consumed by the tessellation primitive generator, and is not available as an
129    input to the tessellation evaluation shader.
130
131
132    Add new section 13.1pbb following section 13.1, "Discarding Primitives
133    Before Rasterization" on p. 288:
134
135    13.1pbb, Primitive Bounding Box
136
137    Implementations may be able to optimize performance if the application
138    provides bounds of primitives that will be generated by the tessellation
139    primitive generator or the geometry shader prior to executing those stages.
140    If the provided bounds are incorrect and primitives extend beyond them, the
141    rasterizer may or may not generate fragments for the portions of primitives
142    outside the bounds.
143
144    The primitive bounding box is specified using
145
146        void PrimitiveBoundingBoxEXT(float minX, float minY, float minZ, float minW,
147                                     float maxX, float maxY, float maxZ, float maxW);
148
149    where <minX>, <minY>, <minZ>, and <minW> specify the minimum clip space
150    coordinate of the bounding box and <maxX>, <maxY>, <maxZ>, and <maxW>
151    specify the maximum coordinate.
152
153    If tessellation is active, each invocation of the tessellation control
154    shader may re-specify the bounding box by writing to the built-in
155    gl_BoundingBoxEXT[] variable. If the shader statically assigns a value to
156    any part of this variable, then gl_BoundingBoxEXT[0] is used instead of
157    <minX>, <minY>, <minZ>, <minW>, and gl_BoundingBoxEXT[1] is used instead of
158    <maxX>, <maxY>, <maxZ>, <maxW>.  If the shader contains a static assignment
159    to gl_BoundingBoxEXT[] and there is an execution path through the shader
160    that does not write all components of gl_BoundingBoxEXT[], the value of
161    unwritten components and corresponding bounding box coordinates is undefined
162    for executions of the shader that take that path.
163
164    If the tessellation control shader re-specifies the bounding box, the re-
165    specified value is used for primitives generated from the output patch by
166    the primitive generator, any primitives emitted by the geometry shader
167    invocations for those generated primitives, and any primitives further
168    introduced during clipping.
169
170    The bounding box in clip space is composed of 16 vertices formed by all
171    combinations of the minimum and maximum values for each dimension. This
172    bounding box is clipped against w_c > 0, and projected to three dimensions
173    by dividing x_c, y_c, and z_c by w_c for each vertex. The viewport transform
174    is then applied to each vertex to produce a three-dimensional bounding
175    volume in window coordinates.
176
177    The window space bounding volume is expanded in the X and Y dimensions to
178    accomodate the rasterization rules for the primitive type, and to fall on
179    fragment boundaries:
180        min_wc' = floor(min_wc - size/2.0)
181        max_wc' = ceil(max_wc + size/2.0)
182    where the min_wc rule is used for x and y window coordinates of bounding
183    volume vertices formed from minX and minY respectively, and the max_wc rule
184    is used for x and y window coordinates of bounding volume vertices formed
185    from maxX and maxY respectively. For point primitives, size is the per-
186    primitive point size after clamping to the implementation-defined maximum
187    point size as described in section 13.3. For line primitives, size is the
188    line width, after rounding and clamping as described in section 13.4.2.1.
189    For triangle primitives, size is zero.
190
191    During rasterization, the rasterizer will generate fragments with
192    window coordinates inside the windows space bounding volume, but may or may
193    not generate fragments with window coordinates outside the bounding volume.
194
195
196Dependencies on EXT_tessellation_shader
197
198    If EXT_tessellation_shader is not supported, ignore all references to the
199    gl_BoundingBoxEXT[] built-in per-patch variable in tessellation control and
200    evaluation shaders, and remove references to the tessellation primitive
201    generator.
202
203Dependencies on EXT_geometry_shader
204
205    If EXT_geometry_shader is not supported, remove all references to it. Since
206    EXT_tessellation_shader requires EXT_geometry_shader, if EXT_geometry_shader
207    is not supported there is probably no benefit to supporting this extension.
208
209New State
210
211    Add to state values in Table 6.5, Transformation State:
212
213                                                  Default
214    Get Value                  Type  Get Command  Value        Description       Sec.
215    -------------------------- ----  -----------  ------------ ----------------- --------
216    PRIMITIVE_BOUNDING_BOX_EXT 8xR   GetFloatv    -1,-1,-1, 1, Default primitive 13.1pbb
217                                                   1, 1, 1, 1  bounding box
218
219
220Additions to the OpenGL ES Shading Language 3.10 Specification
221
222    Including the following line in a shader can be used to control the
223    language features described in this extension:
224
225      #extension GL_EXT_primitive_bounding_box : <behavior>
226
227    where <behavior> is as specified in section 3.4.
228
229    A new preprocessor #define is added to the OpenGL ES Shading Language:
230
231      #define GL_EXT_primitive_bounding_box 1
232
233
234    Modify subsection 7.1ts1 "Tessellation Control Special Variables" as added
235    by EXT_tessellation_shader:
236
237    Add a new built-in variable intrinsic declaration after the
238    gl_TessLevelOuter and gl_TessLevelInner declarations:
239
240      patch out highp vec4 gl_BoundingBoxEXT[2];
241
242    Add the following paragraph to subsection 7.1ts1.2 "Tessellation Control
243    Output Variables" as added by EXT_tessellation_shader, after the paragraph
244    describing gl_TessLevelOuter and gl_TessLevelInner:
245
246      The values written to gl_BoundingBoxEXT specify the minimum and maximum
247      clip-space extents of a bounding box containing all primitives generated
248      from the patch by the primitive generator, geometry shader, and clipping.
249      Fragments may or may not be generated for portions of these primitives
250      that extend outside the window-coordinate projection of this bounding
251      box.
252
253
254Dependencies on the OpenGL ES 3.20 Shading Language Specification
255
256    If GL_EXT_primitive_bounding_box is enabled in an OpenGL ES 3.20 shader,
257    gl_BoundingBoxEXT is an alias for gl_BoundingBox: the last value written
258    to either variable will be used for bounding box optimizations and for
259    reads from both variables.
260
261
262Issues
263
264    (1) What coordinate space should the bounding box be specified in?
265
266    RESOLVED: The bounding box is specified in clip coordinates.
267
268    Using clip coordinates is consistent with vertex positions, allowing apps
269    to use the same transformations. Another option was NDC, but NDC is not
270    used directly by application or shader code anywhere else in the API, and
271    many developers are unfamiliar with it. Using clip coordinates gives
272    implementations the maximum amount of flexibility in how they implement the
273    subsequent transforms and bounding box test.
274
275    (2) Should the bounds be 3D or 2D? The goal of optimizing tiling
276    architectures only appears to need 2D.
277
278    RESOLVED: The bounds are 3D. Depth bounds could be useful for culling
279    patches prior to primitive generation if all the generated primitives would
280    fail the depth test.
281
282    (3) With the bounding box in clip coordinates, what happens when w <= 0?
283
284    RESOLVED: Clip the bounding box against the w > 0 plane.
285
286    This effectively pushes the front face of the bounding box forward until it
287    is just in front of the camera. It is relatively simple in that no new
288    vertices will be introduced and no connectivity will change.
289
290    Note that, as with Issue #5, since false-positives are allowed, an
291    implementation may be able to avoid this clipping altogether. As an extreme
292    example, if either min or max w is <= 0, the implementation could disable
293    bounding box optimizations.
294
295    (4) What happens if a primitive extends outside the bounding box? Is
296    behavior undefined for the whole primitive, or only for the portions outside
297    the bounds? What restrictions can we place on the undefined behavior?
298
299    RESOLVED: In the interest of limiting the scope of undefined behavior as
300    much as possible without requiring precise clipping or scissoring, specify
301    that portions of the primitive inside the bounding box generate fragments
302    normally, and that the rasterizer may or may not generate fragments for
303    portions of the primitive outside the bounding box.
304
305    (5) What space should the bounding box test happen in, and how should it
306    be specified?
307
308    RESOLVED: The proposed resolution to Issue #4 is that fragments outside the
309    bounds may or may not be generated. That makes window space the most natural
310    place to specify the test. If that issue were resolved differently,
311    specifying the bounds test in NDC space might have been simpler and more
312    natural.
313
314    In practice, implementations will probably do the test conservatively at an
315    earlier stage than rasterization.  Because false-positives are allowed,
316    implementations have a lot of flexibility in where and how precisely they
317    perform the test, so the primary requirement for this spec is to provide
318    useful and understandable guarantees about what parts of the primitive
319    definitely will be rendered.
320
321    (6) Should the bounding box test apply even when tessellation isn't active?
322
323    RESOLVED: Yes. Having it apply in VS+GS+FS pipelines is useful to allow
324    implementations to run the GS after binning, since like tessellation it can
325    greatly magnify the amount of geometry. Unlike tessellation, because the
326    expansion happens in the geometry shader, there isn't a natural way for the
327    geometry shader itself to specify the bounding box for its own output
328    primitives.
329
330    Because the bounding box is no longer a tessellation-specific feature, it
331    is now a separate extension from EXT_tessellation_shader.
332
333    (7) What should the initial value of the bounding box state be?
334
335    RESOLVED: The initial value is {(-1,-1,-1,1), (1,1,1,1)}. This corresponds
336    to the entire view frustum, so by default the bounding box test won't reject
337    any fragments that would otherwise have been drawn.
338
339    Another proposed option was to use positive and negative infinity values;
340    that has no benefits over positive and negative one, and infinity values can
341    be hard to generate in C code if an application wanted to return to the
342    initial state.
343
344    (8) Do we really need a 16-vertex bounding volume? Do we need the vertices
345    with (minZ, maxW) or (maxZ, minW)?
346
347    RESOLVED: Specify 16 vertices for generality.  Implementations may be able
348    to avoid forming or transforming all of them explicitly.
349
350    With standard orthographic (w==1) or perspective projections (such as those
351    produced by glFrustum) and "normal" vertices, an eight-vertex bounding
352    volume is sufficient because of the restricted relationships between z_c and
353    w_c.  However, OpenGL ES does not require this restricted relationship, and
354    in the general case all 16 vertices are needed. It's possible that
355    applications attempting to bloat the bounding box to account for
356    displacement mapping, gl_FragDepth modifications, etc. may break the
357    standard relationship and require all 16 vertices.
358
359    (9) Do we need a way to bloat the bounding volume in window space to account
360    for things like point size, line width, etc.? Applying this bloat in clip
361    space may be difficult or overly conservative.
362
363    RESOLVED: Automatically expand the bounding volume in window space by the
364    point size or line width.
365
366    Another option considered was to add state for the application to specify a
367    window-space expansion. This would impose an extra burden on the application
368    to update the state to match line width or maximum point size being
369    rendered, and strongly constrains implementations.
370
371    (10) Should the TES be able to read gl_BoundingBoxEXT[]?
372
373    RESOLVED: No. The bounding box is consumed by the primitive generator.
374
375    Being able to read gl_BoundingBoxEXT[] in the TES doesn't seem particularly
376    useful. It raises the question of what value it gets when the TCS doesn't
377    write the bounding box (undefined, or the PRIMITIVE_BOUNDING_BOX_EXT
378    state?), and whether the TES is required to declare it when the TCS and TES
379    are in different program objects. More importantly, reading the bounding box
380    in the TES may impose surprising costs on some implementations where it is
381    consumed by the fixed-function primitive generation stage.
382
383
384Revision History
385
386    Rev.    Date    Author    Changes
387    ----  --------  --------- -------------------------------------------------
388      8   02/13/18  jessehall
389       - Added a description of gl_BoundingBoxEXT to the shading language
390         specification.
391
392      7   09/07/16  jessehall
393        - Added interaction with the OpenGL ES 3.20 Shading Language.
394
395      6   05/15/14  jessehall
396        - Added missing EXT suffix to gl_BoundingBox[].
397        - Added issue 10, and removed the ability for the TES to read the
398          bounding box.
399
400      5   05/02/14  jessehall
401        - Accept the proposed resolutions for issues 3, 4, 5, 8, and 9.
402        - Assign enumerant (Nvidia volunteered one of theirs)
403
404      4   04/04/14  jessehall
405        - Add language for proposed resolution of issue #9.
406
407      3   03/31/14  jessehall
408        - Rebase on ES 3.1 specs.
409        - Describe interactions with EXT_tessellation_shader and
410          EXT_geometry_shader.
411
412      2   03/14/14  jessehall
413        - Deleted issue #8, which was entirely bogus.
414        - Added new issue #8 and switched from an eight to 16 vertex bounding
415          volume.
416        - Added issue #9.
417        - Simplified the bounding box transformation and clipping language.
418        - Made presence of gl_BoundingBoxEXT[] based on static assignment rather
419          than "any reference", and clarified that components not written on
420          an execution path are undefined.
421        - Reworded "primitives generated from output patch" language.
422
423      1   03/13/14  jessehall
424        - Initial draft based on language from Jan-Harald and Pat, and
425          conversations with other contributors.
426