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