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