1Name 2 3 NV_coverage_sample 4 5Name Strings 6 7 GL_NV_coverage_sample 8 EGL_NV_coverage_sample 9 10Contact 11 12 Gary King, NVIDIA Corporation (gking 'at' nvidia.com) 13 14Notice 15 16 Copyright NVIDIA Corporation, 2005 - 2007 17 18Status 19 20 NVIDIA Proprietary 21 22Version 23 24 Last Modified Date: 2007/03/20 25 NVIDIA Revision: 1.0 26 27Number 28 29 EGL Extension #17 30 OpenGL ES Extension #72 31 32Dependencies 33 34 Written based on the wording of the OpenGL 2.0 specification 35 and the EXT_framebuffer_object specification. 36 37 Written based on the wording of the EGL 1.2 specification. 38 39 Requires OpenGL-ES 2.0 and OES_framebuffer_object. 40 41 Requires EGL 1.1. 42 43Overview 44 45 Anti-aliasing is a critical component for delivering high-quality 46 OpenGL rendering. Traditionally, OpenGL implementations have 47 implemented two anti-aliasing algorithms: edge anti-aliasing 48 and multisampling. 49 50 Edge anti-aliasing computes fractional fragment coverage for all 51 primitives in a rendered frame, and blends edges of abutting 52 and/or overlapping primitives to produce smooth results. The 53 image quality produced by this approach is exceptionally high; 54 however, applications are render their geometry perfectly ordered 55 back-to-front in order to avoid artifacts such as bleed-through. 56 Given the algorithmic complexity and performance cost of performing 57 exact geometric sorts, edge anti-aliasing has been used very 58 sparingly, and almost never in interactive games. 59 60 Multisampling, on the other hand, computes and stores subpixel 61 (a.k.a. "sample") coverage for rasterized fragments, and replicates 62 all post-alpha test operations (e.g., depth test, stencil test, 63 alpha blend) for each sample. After the entire scene is rendered, 64 the samples are filtered to compute the final anti-aliased image. 65 Because the post-alpha test operations are replicated for each sample, 66 all of the bleed-through and ordering artifacts that could occur with 67 edge anti-aliasing are avoided completely; however, since each sample 68 must be computed and stored separately, anti-aliasing quality is 69 limited by framebuffer storage and rendering performance. 70 71 This extension introduces a new anti-aliasing algorithm to OpenGL, 72 which dramatically improves multisampling quality without 73 adversely affecting multisampling's robustness or significantly 74 increasing the storage required, coverage sampling. 75 76 Coverage sampling adds an additional high-precision geometric 77 coverage buffer to the framebuffer, which is used to produce 78 high-quality filtered results (with or without the presence of a 79 multisample buffer). This coverage information is computed and stored 80 during rasterization; since applications may render objects where the 81 specified geometry does not correspond to the visual result (examples 82 include alpha-testing for "imposters," or extruded volume rendering 83 for stencil shadow volumes), coverage buffer updates may be masked 84 by the application, analagous to masking the depth buffer. 85 86IP Status 87 88 NVIDIA Proprietary 89 90New Procedures and Functions 91 92 void CoverageMaskNV( boolean mask ) 93 void CoverageOperationNV( enum operation ) 94 95New Tokens 96 97 98 Accepted by the <attrib_list> parameter of eglChooseConfig 99 and eglCreatePbufferSurface, and by the <attribute> 100 parameter of eglGetConfigAttrib 101 102 EGL_COVERAGE_BUFFERS_NV 0x30E0 103 EGL_COVERAGE_SAMPLES_NV 0x30E1 104 105 Accepted by the <internalformat> parameter of 106 RenderbufferStorageEXT and the <format> parameter of ReadPixels 107 108 COVERAGE_COMPONENT_NV 0x8ED0 109 110 Accepted by the <internalformat> parameter of 111 RenderbufferStorageEXT 112 113 COVERAGE_COMPONENT4_NV 0x8ED1 114 115 Accepted by the <operation> parameter of CoverageOperationNV 116 117 COVERAGE_ALL_FRAGMENTS_NV 0x8ED5 118 COVERAGE_EDGE_FRAGMENTS_NV 0x8ED6 119 COVERAGE_AUTOMATIC_NV 0x8ED7 120 121 Accepted by the <attachment> parameter of 122 FramebufferRenderbuffer, and GetFramebufferAttachmentParameteriv 123 124 COVERAGE_ATTACHMENT_NV 0x8ED2 125 126 Accepted by the <buf> parameter of Clear 127 128 COVERAGE_BUFFER_BIT_NV 0x8000 129 130 Accepted by the <pname> parameter of GetIntegerv 131 132 COVERAGE_BUFFERS_NV 0x8ED3 133 COVERAGE_SAMPLES_NV 0x8ED4 134 135Changes to Chapter 4 of the OpenGL 2.0 Specification 136 137 Insert a new section, after Section 3.2.1 (Multisampling) 138 139 "3.2.2 Coverage Sampling 140 141 Coverage sampling is a mechanism to antialias all GL primitives: points, 142 lines, polygons, bitmaps and images. The technique is similar to 143 multisampling, with all primitives being sampled multiple times at each 144 pixel, and a sample resolve applied to compute the color values stored 145 in the framebuffer's color buffers. As with multisampling, coverage 146 sampling resolves color sample and coverage values to a single, displayable 147 color each time a pixel is updated, so antialiasing appears to be automatic 148 at the application level. Coverage sampling may be used simultaneously 149 with multisampling; however, this is not required. 150 151 An additional buffer, called the coverage buffer, is added to 152 the framebuffer. This buffer stores additional coverage information 153 that may be used to produce higher-quality antialiasing than what is 154 provided by conventional multisampling. 155 156 When the framebuffer includes a multisample buffer (3.5.6), the 157 samples contain this coverage information, and the framebuffer 158 does not include the coverage buffer. 159 160 If the value of COVERAGE_BUFFERS_NV is one, the rasterization of 161 all primitives is changed, and is referred to as coverage sample 162 rasterization. Otherwise, primitive rasterization is referred to 163 as multisample rasterization (if SAMPLE_BUFFERS is one) or 164 single-sample rasterization (otherwise). The value of 165 COVERAGE_BUFFERS_NV is queried by calling GetIntegerv with <pname> 166 set to COVERAGE_BUFFERS_NV. 167 168 During coverage sample rasterization the pixel fragment contents 169 are modified to include COVERAGE_SAMPLES_NV coverage values. The 170 value of COVERAGE_SAMPLES_NV is an implementation-dependent 171 constant, and is queried by calling GetIntegerv with <pname> set 172 to COVERAGE_SAMPLES_NV. 173 174 The command 175 176 CoverageOperationNV(enum operation) 177 178 may be used to modify the manner in which coverage sampling is 179 performed for all primitives. If <operation> is 180 COVERAGE_ALL_FRAGMENTS_NV, coverage sampling will be performed and the 181 coverage buffer updated for all fragments generated during rasterization. 182 If <operation> is COVERAGE_EDGE_FRAGMENTS_NV, coverage sampling will 183 only be performed for fragments generated at the edge of the 184 primitive (by only updating fragments at the edges of primitives, 185 applications may get better visual results when rendering partially 186 transparent objects). If <operation> is COVERAGE_AUTOMATIC_NV, 187 the GL will automatically select the appropriate coverage operation, 188 dependent on the GL blend mode and the use of gl_LastFragColor / 189 gl_LastFragData in the bound fragment program. If blending is enabled, 190 or gl_LastFragColor / gl_LastFragData appears in the bound fragment 191 program, COVERAGE_AUTOMATIC_NV will behave identically to 192 COVERAGE_EDGE_FRAGMENTS_NV; otherwise, COVERAGE_AUTOMATIC_NV will behave 193 identically to COVERAGE_ALL_FRAGMENTS_NV. The default coverage operation 194 is COVERAGE_AUTOMATIC_NV." 195 196 Insert a new section, after Section 3.3.3 (Point Multisample 197 Rasterization) 198 199 "3.3.4 Point Coverage Sample Rasterization 200 201 If the value of COVERAGE_BUFFERS_NV is one, then points are 202 rasterized using the following algorithm, regardless of whether 203 point antialiasing (POINT_SMOOTH) is enabled or disabled. Point 204 rasterization produces fragments using the same algorithm described 205 in section 3.3.3; however, sample points are divided into SAMPLES 206 multisample points and COVERAGE_SAMPLES_NV coverage sample points. 207 208 Rasterization for multisample points uses the algorithm described 209 in section 3.3.3. Rasterization for coverage sample points uses 210 implementation-dependent algorithms, ultimately storing the results 211 in the coverage buffer." 212 213 Insert a new section, after Section 3.4.4 (Line Multisample 214 Rasterization) 215 216 "3.4.5 Line Coverage Sample Rasterization 217 218 If the value of COVERAGE_BUFFERS_NV is one, then lines are 219 rasterized using the following algorithm, regardless of whether 220 line antialiasing (LINE_SMOOTH) is enabled or disabled. Line 221 rasterization produces fragments using the same algorithm described 222 in section 3.4.4; however, sample points are divided into SAMPLES 223 multisample points and COVERAGE_SAMPLES_NV coverage sample points. 224 225 Rasterization for multisample points uses the algorithm described in 226 section 3.4.4. Rasterization for coverage sample points uses 227 implementation-dependent algorithms, ultimately storing results in 228 the coverage buffer." 229 230 Insert a new section, after Section 3.5.6 (Polygon Multisample 231 Rasterization) 232 233 "3.5.7 Polygon Coverage Sample Rasterization 234 235 If the value of COVERAGE_BUFFERS_NV is one, then polygons are 236 rasterized using the following algorithm, regardless of whether 237 polygon antialiasing (POLYGON_SMOOTH) is enabled or disabled. Polygon 238 rasterization produces fragments using the same algorithm described in 239 section 3.5.6; however, sample points are divided into SAMPLES multisample 240 points and COVERAGE_SAMPLES_NV coverage sample points. 241 242 Rasterization for multisample points uses the algorithm described in 243 section 3.5.7. Rasterization for coverage sample points uses 244 implementation-dependent algorithms, ultimately storing results in the 245 coverage buffer." 246 247 Insert a new section, after Section 3.6.6 (Pixel Rectangle Multisample 248 Rasterization) 249 250 "3.6.7 Pixel Rectangle Coverage Sample Rasterization 251 252 If the value of COVERAGE_BUFFERS_NV is one, then pixel rectangles are 253 rasterized using the algorithm described in section 3.6.6." 254 255 Modify the first sentence of the second-to-last paragraph of section 256 3.7 (Bitmaps) to read: 257 258 "Bitmap Multisample and Coverage Sample Rasterization 259 260 If MULTISAMPLE is enabled, and the value of SAMPLE_BUFFERS is one; 261 or if the value of COVERAGE_BUFFERS_NV is one, then bitmaps are 262 rasterized using the following algorithm. [...]" 263 264 Insert after the first paragraph of Section 4.2.2 (Fine Control of 265 Buffer Updates): 266 267 "The coverage buffer can be enabled or disabled for writing coverage 268 sample values using 269 270 void CoverageMaskNV( boolean mask ); 271 272 If <mask> is non-zero, the coverage buffer is enabled for writing; 273 otherwise, it is disabled. In the initial state, the coverage 274 buffer is enabled for writing." 275 276 And change the text of the last 2 paragraphs of Section 4.2.2 to read: 277 278 "The state required for the various masking operations is three 279 integers and two bits: an integer for color indices, an integer for 280 the front and back stencil values, a bit for depth values, and a 281 bit for coverage sample values. A set of four bits is also required 282 indicating which components of an RGBA value should be written. In the 283 initial state, the integer masks are all ones, as are the bits 284 controlling the depth value, coverage sample value and RGBA component 285 writing. 286 287 Fine Control of Multisample Buffer Updates 288 289 When the value of SAMPLE_BUFFERS is one, ColorMask, DepthMask, 290 CoverageMask, and StencilMask or StencilMaskSeparate control the 291 modification of values in the multisample buffer. [...]" 292 293 Change paragraph 2 of Section 4.2.3 (Clearing the Buffers) to read: 294 295 "is the bitwise OR of a number of values indicating which buffers are to 296 be cleared. The values are COLOR_BUFFER_BIT, DEPTH_BUFFER_BIT, 297 STENCIL_BUFFER_BIT, ACCUM_BUFFER_BIT and COVERAGE_BUFFER_BIT_NV, indicating 298 the buffers currently enabled for color writing, the depth buffer, 299 the stencil buffer, the accumulation buffer and the virtual-coverage 300 buffer, respectively. [...]" 301 302 Insert a new paragraph after paragraph 4 of Section 4.3.2 (Reading Pixels) 303 (beginning with "If there is a multisample buffer ..."): 304 305 "If the <format> is COVERAGE_COMPONENT_NV, then values are taken from the 306 coverage buffer; again, if there is no coverage buffer, the error 307 INVALID_OPERATION occurs. When <format> is COVERAGE_COMPONENT_NV, 308 <type> must be GL_UNSIGNED_BYTE. Any other value for <type> will 309 generate the error INVALID_ENUM. If there is a multisample buffer, the 310 values are undefined." 311 312 313 314Modifications to the OES_framebuffer_object specification 315 316 Add a new table at the end of Section 4.4.2.1 (Renderbuffer Objects) 317 318 "+-------------------------+-----------------------+-----------+ 319 | Sized internal format | Base Internal Format | C Samples | 320 +-------------------------+-----------------------+-----------+ 321 | COVERAGE_COMPONENT4_NV | COVERAGE_COMPONENT_NV | 4 | 322 +-------------------------+-----------------------+-----------+ 323 Table 1.ooo Desired component resolution for each sized internal 324 format that can be used only with renderbuffers" 325 326 Add to the bullet list in Section 4.4.4 (Framebuffer Completeness) 327 328 "An internal format is 'coverage-renderable' if it is COVERAGE_COMPONENT_NV 329 or one of the COVERAGE_COMPONENT_NV formats from table 1.ooo. No other 330 formats are coverage-renderable" 331 332 Add to the bullet list in Section 4.4.4.1 (Framebuffer Attachment 333 Completeness) 334 335 "If <attachment> is COVERAGE_ATTACHMENT_NV, then <image> must have a 336 coverage-renderable internal format." 337 338 Add a paragraph at the end of Section 4.4.4.2 (Framebuffer Completeness) 339 340 "The values of COVERAGE_BUFFERS_NV and COVERAGE_SAMPLES_NV are derived from 341 the attachments of the currently bound framebuffer object. If the current 342 FRAMEBUFFER_BINDING_OES is not 'framebuffer-complete', then both 343 COVERAGE_BUFFERS_NV and COVERAGE_SAMPLES_NV are undefined. Otherwise, 344 COVERAGE_SAMPLES_NV is equal to the number of coverage samples for the 345 image attached to COVERAGE_ATTACHMENT_NV, or zero if COVERAGE_ATTACHMENT_NV 346 is zero." 347 348Additions to the EGL 1.2 Specification 349 350 Add to Table 3.1 (EGLConfig attributes) 351 +---------------------------+---------+-----------------------------------+ 352 | Attribute | Type | Notes | 353 +---------------------------+---------+-----------------------------------+ 354 | EGL_COVERAGE_BUFFERS_NV | integer | number of coverage buffers | 355 | EGL_COVERAGE_SAMPLES_NV | integer | number of coverage samples per | 356 | | | pixel | 357 +---------------------------+---------+-----------------------------------+ 358 359 Modify the first sentence of the last paragraph of the "Buffer 360 Descriptions and Attributes" subsection of Section 3.4 (Configuration 361 Management), p. 16 362 363 "There are no single-sample depth, stencil or coverage buffers for a 364 multisample EGLConfig; the only depth, stencil and coverage buffers are 365 those in the multisample buffer. [...]" 366 367 And add the following text at the end of that paragraph: 368 369 "The <coverage buffer> is used only by OpenGL ES. It contains primitive 370 coverage information that is used to produce a high-quality anti-aliased 371 image. The format of the coverage buffer is not specified, and its 372 contents are not directly accessible. Only the existence of the coverage 373 buffer, and the number of coverage samples it contains, are exposed by EGL. 374 375 EGL_COVERAGE_BUFFERS_NV indicates the number of coverage buffers, which 376 must be zero or one. EGL_COVERAGE_SAMPLES_NV gives the number of coverage 377 samples per pixel; if EGL_COVERAGE_BUFFERS_NV is zero, then 378 EGL_COVERAGE_SAMPLES_NV will also be zero." 379 380 Add to Table 3.4 (Default values and match criteria for EGLConfig 381 attributes) 382 383 +---------------------------+-----------+-------------+---------+---------+ 384 | Attribute | Default | Selection | Sort | Sort | 385 | | | Criteria | Order | Priority| 386 +---------------------------+-----------+-------------+---------+---------+ 387 | EGL_COVERAGE_BUFFERS_NV | 0 | At Least | Smaller | 7 | 388 | EGL_COVERAGE_SAMPLES_NV | 0 | At Least | Smaller | 8 | 389 +---------------------------+-----------+-------------+---------+---------+ 390 And renumber existing sort priorities 7-11 as 9-13. 391 392 Modify the list in "Sorting of EGLConfigs" (Section 3.4.1, pg 20) 393 394 " [...] 395 5. Smaller EGL_SAMPLE_BUFFERS 396 6. Smaller EGL_SAMPLES 397 7. Smaller EGL_COVERAGE_BUFFERS_NV 398 8. Smaller EGL_COVERAGE_SAMPLES_NV 399 9. Smaller EGL_DEPTH_SIZE 400 10. Smaller EGL_STENCIL_SIZE 401 11. Smaller EGL_ALPHA_MASK_SIZE 402 12. Special: [...] 403 13. Smaller EGL_CONFIG_ID [...]" 404 405Usage Examples 406 407 (1) Basic Coverage Sample Rasterization 408 409 glCoverageMaskNV(GL_TRUE); 410 glDepthMask(GL_TRUE); 411 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 412 413 while (1) 414 { 415 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | 416 GL_COVERAGE_BUFFER_BIT_NV); 417 glDrawElements(...); 418 eglSwapBuffers(...); 419 } 420 421 (2) Multi-Pass Rendering Algorithms 422 423 while (1) 424 { 425 glDepthMask(GL_TRUE); 426 glCoverageMaskNV(GL_TRUE); 427 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 428 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | 429 GL_COVERAGE_BUFFER_BIT_NV); 430 431 // first render pass: render Z-only (occlusion surface), with 432 // coverage info. color writes are disabled 433 434 glCoverageMaskNV(GL_TRUE); 435 glDepthMask(GL_TRUE); 436 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 437 glDepthFunc(GL_LESS); 438 glDrawElements(...); 439 440 // second render pass: set Z test to Z-equals, disable Z-writes & 441 // coverage writes. enable color writes. coverage may be 442 // disabled, because subsequent rendering passes are rendering 443 // identical geometry -- since the final coverage buffer will be 444 // unchanged, we can disable coverage writes as an optimization. 445 446 glCoverageMaskNV(GL_FALSE); 447 glDepthMask(GL_FALSE); 448 glDepthFunc(GL_EQUAL); 449 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 450 glDrawElements(...); 451 452 eglSwapBuffers(); 453 } 454 455 (3) Rendering Translucent Objects on Top of Opaque Objects 456 457 while (1) 458 { 459 glDepthMask(GL_TRUE); 460 glCoverageMaskNV(GL_TRUE); 461 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 462 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | 463 GL_COVERAGE_BUFFER_BIT_NV); 464 465 // render opaque, Z-buffered geometry with coverage info for the 466 // entire primitive. Overwrite coverage data for all fragments, so 467 // that interior fragments do not get resolved incorrectly. 468 469 glDepthFunc(GL_LESS); 470 glCoverageOperationNV(GL_COVERAGE_ALL_FRAGMENTS_NV); 471 glDrawElements(...); 472 473 // render translucent, Z-buffered geometry. to ensure that visible 474 // edges of opaque geometry remain anti-aliased, change the 475 // coverage operation to just edge fragments. this will maintain 476 // the coverage information underneath the translucent geometry, 477 // except at translucent edges. 478 479 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 480 glCoverageOperationNV(GL_COVERAGE_EDGE_FRAGMENTS_NV); 481 glEnable(GL_BLEND); 482 glDrawElements(...); 483 glDisable(GL_BLEND); 484 485 eglSwapBuffers(); 486 } 487 488 (4) Rendering Opacity-Mapped Particle Systems & HUDs on Top of Opaque 489 Geometry 490 491 while (1) 492 { 493 glDepthMask(GL_TRUE); 494 glCoverageMaskNV(GL_TRUE); 495 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 496 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | 497 GL_COVERAGE_BUFFER_BIT_NV); 498 499 // render opaque, Z-buffered geometry, with coverage info. 500 glDepthFunc(GL_LESS); 501 glDrawElements(...); 502 503 // render opacity-mapped geometry. disable Z writes, enable alpha 504 // blending. also, disable coverage writes -- the edges of the 505 // geometry used for the HUD/particle system have alpha values 506 // tapering to zero, so edge coverage is uninteresting, and 507 // interior coverage should still refer to the underlying opaque 508 // geometry, so that opaque edges visible through the translucent 509 // regions remain anti-aliased. 510 511 glCoverageMaskNV(GL_FALSE); 512 glDepthMask(GL_FALSE); 513 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 514 glEnable(GL_BLEND); 515 glDrawElements(...); 516 glDisable(GL_BLEND); 517 518 eglSwapBuffers(); 519 } 520 521 522Issues 523 524 1. Is any specific discussion of coverage sampling resolves required, 525 particularly with respect to application-provided framebuffer objects? 526 527 RESOLVED: No. Because the coverage sampling resolve is an 528 implementation-dependent algorithm, it is always legal behavior for 529 framebuffer read / copy functions to return the value in the selected 530 ReadBuffer as if COVERAGE_BUFFERS_NV was zero. This allows 531 textures attached to the color attachment points of framebuffer objects 532 to behave predictably, even when COVERAGE_BUFFERS_NV is one. 533 534 Implementations are encouraged, whenever possible, to use the highest- 535 quality coverage sample resolve supported for calls to eglSwapBuffers, 536 eglCopyBuffers, ReadPixels, CopyPixels and CopyTex{Sub}Image. 537 538 2. Should all render buffer & texture types be legal sources for image 539 resolves and coverage attachment? 540 541 RESOLVED: This spec should not place any arbitrary limits on usage; 542 however, there are many reasons why implementers may not wish to 543 support coverage sampling for all surface types. 544 545 Implementations may return FRAMEBUFFER_UNSUPPORTED_OES from 546 CheckFramebufferStatusOES if an object bound to COVERAGE_ATTACHMENT_NV 547 is incompatible with one or more objects bound to DEPTH_ATTACHMENT_OES, 548 STENCIL_ATTACHMENT_OES, or COLOR_ATTACHMENTi_OES. 549 550Revision History 551 552#1.0 - 20.03.2007 553 554 Renumbered enumerants. Reformatted to 80 columns. 555