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