1Name 2 3 APPLE_framebuffer_multisample 4 5Name Strings 6 7 GL_APPLE_framebuffer_multisample 8 9Contributors 10 11 Contributors to EXT_framebuffer_multisample and EXT_framebuffer_blit 12 desktop OpenGL extensions from which this extension borrows heavily. 13 14Contacts 15 16 Benj Lipchak, Apple (lipchak 'at' apple.com) 17 18Status 19 20 Complete 21 22Version 23 24 Last Modified Date: February 24, 2011 25 Revision: #4 26 27Number 28 29 OpenGL ES Extension #78 30 31Dependencies 32 33 Requires GL_OES_framebuffer_object or OpenGL ES 2.0. 34 35 Written based on the wording of the OpenGL ES 2.0 specification. 36 37 OpenGL ES 1.1 affects the definition of this extension. 38 39 EXT_discard_framebuffer affects the definition of this extension. 40 41Overview 42 43 This extension extends the framebuffer object framework to 44 enable multisample rendering. 45 46 The new operation RenderbufferStorageMultisampleAPPLE() allocates 47 storage for a renderbuffer object that can be used as a multisample 48 buffer. A multisample render buffer image differs from a 49 single-sample render buffer image in that a multisample image has a 50 number of SAMPLES that is greater than zero. No method is provided 51 for creating multisample texture images. 52 53 All of the framebuffer-attachable images attached to a framebuffer 54 object must have the same number of SAMPLES or else the framebuffer 55 object is not "framebuffer complete". If a framebuffer object with 56 multisample attachments is "framebuffer complete", then the 57 framebuffer object behaves as if SAMPLE_BUFFERS is one. 58 59 The resolve operation is affected by calling 60 ResolveMultisampleFramebufferAPPLE where the source is a multisample 61 application-created framebuffer object and the destination is a 62 single-sample framebuffer object. Separate read and draw framebuffer 63 object binding points are established to facilitate the resolve. 64 65 Scissoring may be used in conjunction with 66 ResolveMultisampleFramebufferAPPLE to resolve only a portion of the 67 framebuffer. 68 69IP Status 70 71 No known IP claims. 72 73New Procedures and Functions 74 75 void RenderbufferStorageMultisampleAPPLE( 76 enum target, sizei samples, 77 enum internalformat, 78 sizei width, sizei height); 79 80 void ResolveMultisampleFramebufferAPPLE(void); 81 82New Tokens 83 84 Accepted by the <pname> parameter of GetRenderbufferParameteriv: 85 86 RENDERBUFFER_SAMPLES_APPLE 0x8CAB 87 88 Returned by CheckFramebufferStatus: 89 90 FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE 0x8D56 91 92 Accepted by the <pname> parameter of GetBooleanv, GetIntegerv, and 93 GetFloatv: 94 95 MAX_SAMPLES_APPLE 0x8D57 96 97 Accepted by the <target> parameter of BindFramebuffer, 98 CheckFramebufferStatus, FramebufferTexture2D, FramebufferRenderbuffer, and 99 GetFramebufferAttachmentParameteriv: 100 101 READ_FRAMEBUFFER_APPLE 0x8CA8 102 DRAW_FRAMEBUFFER_APPLE 0x8CA9 103 104 Accepted by the <pname> parameter of GetBooleanv, GetIntegerv, and 105 GetFloatv: 106 107 DRAW_FRAMEBUFFER_BINDING_APPLE 0x8CA6 // FRAMEBUFFER_BINDING 108 READ_FRAMEBUFFER_BINDING_APPLE 0x8CAA 109 110Additions to Chapter 2 of the OpenGL ES 2.0 Specification (OpenGL ES Operation) 111 112 None 113 114Additions to Chapter 3 of the OpenGL ES 2.0 Specification (Rasterization) 115 116 None 117 118Additions to Chapter 4 of the OpenGL ES 2.0 Specification (Per-Fragment 119Operations and the Framebuffer) 120 121 Change the first word of Chapter 4 from "The" to "A". 122 123 Append to the introduction of Chapter 4: 124 125 "Conceptually, the GL has two active framebuffers; the draw 126 framebuffer is the destination for rendering operations, and the 127 read framebuffer is the source for readback operations. The same 128 framebuffer may be used for both drawing and reading. Section 129 4.4.1 describes the mechanism for controlling framebuffer usage." 130 131 Modify the last paragraph of section 4.1.1 as follows: 132 133 "While an application-created framebuffer object is bound to 134 DRAW_FRAMEBUFFER_APPLE, the pixel ownership test always passes." 135 136 Add to 4.3.2 (Reading Pixels), right before the subsection titled 137 "Obtaining Pixels from the Framebuffer": 138 139 "ReadPixels generates INVALID_FRAMEBUFFER_OPERATION if the object bound to 140 READ_FRAMEBUFFER_APPLE is not framebuffer complete (see section 4.4.5). 141 142 ReadPixels generates INVALID_OPERATION if the object bound to 143 READ_FRAMEBUFFER_APPLE is framebuffer complete and the value of 144 SAMPLE_BUFFERS for the read framebuffer is greater than zero." 145 146 Replace the first paragraph of the subsection titled "Obtaining Pixels 147 from the Framebuffer" with the following: 148 149 "The buffer from which values are obtained is the color buffer used for 150 reading. If READ_FRAMEBUFFER_BINDING_APPLE is non-zero, pixel values are 151 read from the buffer attached as the COLOR_ATTACHMENT0 attachment to the 152 currently bound read framebuffer object." 153 154 Modify the beginning of section 4.4.1 as follows: 155 156 "The operations described in chapter 4 affect the images attached to the 157 framebuffer objects bound to targets READ_FRAMEBUFFER_APPLE and 158 DRAW_FRAMEBUFFER_APPLE. By default, the framebuffer bound to these 159 targets is zero, specifying the default implementation-dependent 160 framebuffer provided by the windowing system. When the framebuffers bound 161 to these targets is not zero, but instead names an application-created 162 framebuffer object, then the operations described in chapter 4 affect the 163 application-created framebuffer object rather than the default framebuffer. 164 165 The namespace for framebuffer objects is the unsigned integers, with zero 166 reserved by OpenGL ES to refer to the default framebuffer. A framebuffer 167 object is created by binding an unused name to DRAW_FRAMEBUFFER_APPLE or 168 READ_FRAMEBUFFER_APPLE. The binding is effected by calling 169 170 void BindFramebuffer(enum target, uint framebuffer); 171 172 with <target> set to the desired framebuffer target and 173 <framebuffer> set to the unused name. The resulting framebuffer 174 object is a new state vector. There is one color attachment points, plus 175 one each for the depth and stencil attachment points. 176 177 BindFramebuffer may also be used to bind an existing framebuffer object to 178 <target>. If the bind is successful no change is made to the state of the 179 bound framebuffer object, and any previous binding to <target> is broken. 180 The current DRAW_FRAMEBUFFER_APPLE and READ_FRAMEBUFFER_APPLE bindings can 181 be queried using GetIntegerv(DRAW_FRAMEBUFFER_BINDING_APPLE) and 182 GetIntegerv(READ_FRAMEBUFFER_BINDING_APPLE), respectively. 183 184 If a framebuffer object is bound to DRAW_FRAMEBUFFER_APPLE or 185 READ_FRAMEBUFFER_APPLE, it becomes the destination of fragment operations 186 or the source of pixel reads, respectively, until it is deleted or another 187 framebuffer is bound to the corresponding bind point. Calling 188 BindFramebuffer with <target> set to FRAMEBUFFER binds the 189 framebuffer to both DRAW_FRAMEBUFFER_APPLE and READ_FRAMEBUFFER_APPLE. 190 191 While a framebuffer object is bound, OpenGL ES operations on the target 192 to which it is bound affect the images attached to the bound 193 framebuffer object, and queries of the target to which it is bound 194 return state from the bound object. In particular, queries of the values 195 specified in table 6.20 (Implementation Dependent Pixel Depths) are 196 derived from the framebuffer object bound to DRAW_FRAMEBUFFER_APPLE. 197 198 In the initial state, the reserved name zero is bound to the targets 199 DRAW_FRAMEBUFFER_APPLE and READ_FRAMEBUFFER_APPLE. There is no application 200 created framebuffer object corresponding to the name zero. Instead, the 201 name zero refers to the window-system-provided framebuffer. All Queries 202 and operations on the framebuffer while the name zero is bound to target 203 DRAW_FRAMEBUFFER_APPLE or READ_FRAMEBUFFER_APPLE operate on this default 204 framebuffer..." 205 206 Change the description of DeleteFramebuffers as follows: 207 208 "<framebuffers> contains <n> names of framebuffer objects to be 209 deleted. After a framebuffer object is deleted, it has no 210 attachments, and its name is again unused. If a framebuffer that 211 is currently bound to one or more of the targets 212 DRAW_FRAMEBUFFER_APPLE or READ_FRAMEBUFFER_APPLE is deleted, it is as 213 though BindFramebuffer had been executed with the corresponding 214 <target> and <framebuffer> of zero. Unused names in <framebuffers> 215 are silently ignored, as is the value zero." 216 217 Add to section 4.4.3, just above the definition of RenderbufferStorage: 218 219 "The command 220 221 void RenderbufferStorageMultisampleAPPLE( 222 enum target, sizei samples, 223 enum internalformat, 224 sizei width, sizei height); 225 226 establishes the data storage, format, dimensions, and number of 227 samples of a renderbuffer object's image. <target> must be 228 RENDERBUFFER. <internalformat> must be one of the color-renderable, 229 depth-renderable, or stencil-renderable formats described in table 4.5. 230 <width> and <height> are the dimensions in pixels of the renderbuffer. If 231 either <width> or <height> is greater than the value of 232 MAX_RENDERBUFFER_SIZE, or if <samples> is greater than MAX_SAMPLES_APPLE, 233 then the error INVALID_VALUE is generated. If OpenGL ES is unable to 234 create a data store of the requested size, the error OUT_OF_MEMORY is 235 generated. RenderbufferStorageMultisampleAPPLE deletes any existing 236 data store for the renderbuffer and the contents of the data store after 237 calling RenderbufferStorageMultisampleAPPLE are undefined. 238 239 If <samples> is zero, then RENDERBUFFER_SAMPLES_APPLE is set to zero. 240 Otherwise <samples> represents a request for a desired minimum 241 number of samples. Since different implementations may support 242 different sample counts for multisampled rendering, the actual 243 number of samples allocated for the renderbuffer image is 244 implementation dependent. However, the resulting value for 245 RENDERBUFFER_SAMPLES_APPLE is guaranteed to be greater than or equal 246 to <samples> and no more than the next larger sample count supported 247 by the implementation. 248 249 An OpenGL ES implementation may vary its allocation of internal component 250 resolution based on any RenderbufferStorageMultisampleAPPLE parameter 251 (except target), but the allocation and chosen internal format must not be 252 a function of any other state and cannot be changed once they are 253 established. The actual resolution in bits of each component of the 254 allocated image can be queried with GetRenderbufferParameteriv." 255 256 Modify the definiton of RenderbufferStorage in section 4.4.3 as follows: 257 258 "The command 259 260 void RenderbufferStorage( 261 enum target, enum internalformat, 262 sizei width, sizei height); 263 264 is equivalent to calling RenderbufferStorageMultisampleAPPLE with 265 <samples> equal to zero." 266 267 In section 4.4.3, modify the first two sentences of the 268 description of FramebufferRenderbuffer as follows: 269 270 "<target> must be DRAW_FRAMEBUFFER_APPLE, READ_FRAMEBUFFER_APPLE, or 271 FRAMEBUFFER. If <target> is FRAMEBUFFER, it behaves as 272 though DRAW_FRAMEBUFFER_APPLE were specified. INVALID_OPERATION is 273 generated if the current value of the corresponding binding is zero 274 when FramebufferRenderbuffer is called." 275 276 In section 4.4.3, modify the first two sentences of the 277 description of FramebufferTexture2D as follows: 278 279 "The <target> must be DRAW_FRAMEBUFFER_APPLE, READ_FRAMEBUFFER_APPLE, or 280 FRAMEBUFFER. If <target> is FRAMEBUFFER, it behaves as though 281 DRAW_FRAMEBUFFER_APPLE were specified. INVALID_OPERATION is generated if 282 the current value of the corresponding binding is zero when 283 FramebufferTexture2D is called." 284 285 In section 4.4.5, add an entry to the Framebuffer Completeness bullet list: 286 287 "* All attached images have the same number of samples. 288 289 FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE" 290 291 In section 4.4.5, modify the first sentence of the description 292 of CheckFramebufferStatus as follows: 293 294 "If <target> is not DRAW_FRAMEBUFFER_APPLE, READ_FRAMEBUFFER_APPLE, or 295 FRAMEBUFFER, INVALID_ENUM is generated. If <target> is FRAMEBUFFER, it 296 behaves as though DRAW_FRAMEBUFFER_APPLE were specified." 297 298 Modify the first sentence of the last paragraph of section 4.4.5 as 299 follows: 300 301 "If the currently bound draw or read framebuffer is not framebuffer 302 complete, then it is an error to attempt to use the framebuffer for 303 writing or reading, respectively." 304 305 In section 4.4.6, replace references to FRAMEBUFFER_BINDING with 306 DRAW_FRAMEBUFFER_BINDING_APPLE. 307 308 Add new section titled "Multisample Resolves" to section 4.4: 309 310 "The command 311 312 void ResolveMultisampleFramebufferAPPLE(void); 313 314 converts the samples corresponding to each pixel location in the 315 read framebuffer's color attachment to a single sample before writing 316 them to the draw framebuffer's color attachment. 317 318 The pixel copy bypasses the fragment pipeline. The only fragment 319 operations which affect the resolve are the pixel ownership test, 320 the scissor test, and dithering. 321 322 INVALID_OPERATION is generated if SAMPLE_BUFFERS for the read framebuffer 323 is zero, or if SAMPLE_BUFFERS for the draw framebuffer is greater than 324 zero, or if the read framebuffer or draw framebuffer does not have a color 325 attachment, or if the dimensions of the read and draw framebuffers 326 are not identical, or if the components in the format of the draw 327 framebuffer's color attachment are not present in the format of the read 328 framebuffer's color attachment. 329 330 INVALID_FRAMEBUFFER_OPERATION is generated if the objects bound to 331 DRAW_FRAMEBUFFER_APPLE and READ_FRAMEBUFFER_APPLE are not framebuffer 332 complete (see section 4.4.5)." 333 334Additions to Chapter 5 of the OpenGL ES 2.0 Specification (Special Functions) 335 336 None 337 338Additions to Chapter 6 of the OpenGL ES 2.0 Specification (State and State 339Requests) 340 341 In section 6.1.3, modify the first sentence of the description of 342 GetFramebufferAttachmentParameteriv as follows: 343 344 "<target> must be DRAW_FRAMEBUFFER_APPLE, READ_FRAMEBUFFER_APPLE or 345 FRAMEBUFFER. If <target> is FRAMEBUFFER, it behaves as though 346 DRAW_FRAMEBUFFER_APPLE were specified." 347 348 In section 6.1.3, modify the third paragraph of the description of 349 GetRenderbufferParameteriv as follows: 350 351 "Upon successful return from GetRenderbufferParameteriv, if 352 <pname> is RENDERBUFFER_WIDTH, RENDERBUFFER_HEIGHT, 353 RENDERBUFFER_INTERNAL_FORMAT, or RENDERBUFFER_SAMPLES_APPLE, then <params> 354 will contain the width in pixels, height in pixels, internal format, or 355 number of samples, respectively, of the image of the renderbuffer 356 currently bound to <target>." 357 358 Move SAMPLES and SAMPLE_BUFFERS state to table 6.20. 359 360Dependencies on OpenGL ES 1.1 361 362 On an OpenGL ES 1.1 implementation, OES_framebuffer_object is required. 363 Include GetFixedv where GetBooleanv, GetIntegerv and GetFloatv appear. 364 Add OES suffixes to entrypoints and tokens introduced by 365 OES_framebuffer_object. 366 367Dependencies on EXT_discard_framebuffer 368 369 In the presence of EXT_discard_framebuffer, DiscardFramebufferEXT is 370 modified to allow READ_FRAMEBUFFER_APPLE and DRAW_FRAMEBUFFER_APPLE 371 as acceptable targets. If <target> is FRAMEBUFFER, DiscardFramebufferEXT 372 behaves as though DRAW_FRAMEBUFFER_APPLE were specified. 373 374Errors 375 376 INVALID_FRAMEBUFFER_OPERATION is generated if DrawArrays, DrawElements, or 377 ResolveMultisampleFramebufferAPPLE is called while the draw framebuffer is 378 not framebuffer complete. 379 380 INVALID_FRAMEBUFFER_OPERATION is generated if ReadPixels, 381 CopyTex{Sub}Image*, or ResolveMultisampleFramebufferAPPLE is called while 382 the read framebuffer is not framebuffer complete. 383 384 INVALID_OPERATION is generated if ReadPixels, or CopyTex{Sub}Image* is 385 called while READ_FRAMEBUFFER_BINDING_APPLE is non-zero, the read 386 framebuffer is framebuffer complete, and the value of SAMPLE_BUFFERS for 387 the read framebuffer is greater than zero. 388 389 INVALID_OPERATION is generated by ResolveMultisampleFramebufferAPPLE if 390 SAMPLE_BUFFERS for the read framebuffer is zero, or if SAMPLE_BUFFERS for 391 the draw framebuffer is greater than zero, or if the read framebuffer or 392 draw framebuffer does not have a color attachment, or if the dimensions of 393 the read and draw framebuffers are not identical, or if the components in 394 the format of the draw framebuffer's color attachment are not present in 395 the format of the read framebuffer's color attachment. 396 397 OUT_OF_MEMORY is generated when RenderbufferStorageMultisampleAPPLE cannot 398 create storage of the specified size. 399 400 INVALID_VALUE is generated if RenderbufferStorageMultisampleAPPLE is 401 called with a value of <samples> that is greater than MAX_SAMPLES_APPLE 402 or with a value of <width> or <height> that is greater than 403 MAX_RENDERBUFFER_SIZE. 404 405New State 406 407 Add to table 6.19 (Implementation Dependent Values (cont.)): 408 409 Get Value Type Get Command Minimum Value Description Section 410 --------- ---- ----------- ------------- ------------------- ------- 411 MAX_SAMPLES_APPLE Z+ GetIntegerv 1 Maximum number of 4.4.3 412 samples supported 413 for multisampling 414 415 Add to table 6.22 (Renderbuffer State): 416 417 Get Value Type Get Command Initial Value Description Section 418 -------------------------- ---- -------------------------- ------------- -------------------- ------- 419 RENDERBUFFER_SAMPLES_APPLE Z+ GetRenderbufferParameteriv 0 Renderbuffer samples 4.4.3 420 421 422 Remove reference to FRAMEBUFFER_BINDING from Table 6.23 (Framebuffer State) 423 and replace with the following: 424 425 Get Value Type Get Command Initial Value Description Section 426 ------------------------------ ---- ----------- ------------- ------------------------- ------- 427 DRAW_FRAMEBUFFER_BINDING_APPLE Z+ GetIntegerv 0 Framebuffer object bound 4.4.1 428 to DRAW_FRAMEBUFFER_APPLE 429 READ_FRAMEBUFFER_BINDING_APPLE Z+ GetIntegerv 0 Framebuffer object 4.4.1 430 to READ_FRAMEBUFFER_APPLE 431 432 433 434Revision History 435 436 #4, February 24, 2011: Benj Lipchak 437 - assign extension number 438 - clarify that dithering is still performed during resolve 439 - clarify that only format conversions that drop components are allowed 440 during resolve 441 #3, January 5, 2010: Benj Lipchak 442 - remove the error when read and draw color formats are not identical 443 - add an error when missing a color attachment to the read or draw FBO 444 #2, October 29, 2009: Benj Lipchak 445 - add interaction with EXT_discard_framebuffer 446 - mention that scissoring can be used for partial resolves 447 #1, October 28, 2009: Benj Lipchak 448 - first revision 449