Name APPLE_framebuffer_multisample Name Strings GL_APPLE_framebuffer_multisample Contributors Contributors to EXT_framebuffer_multisample and EXT_framebuffer_blit desktop OpenGL extensions from which this extension borrows heavily. Contacts Benj Lipchak, Apple (lipchak 'at' apple.com) Status Complete Version Last Modified Date: February 24, 2011 Revision: #4 Number OpenGL ES Extension #78 Dependencies Requires GL_OES_framebuffer_object or OpenGL ES 2.0. Written based on the wording of the OpenGL ES 2.0 specification. OpenGL ES 1.1 affects the definition of this extension. EXT_discard_framebuffer affects the definition of this extension. Overview This extension extends the framebuffer object framework to enable multisample rendering. The new operation RenderbufferStorageMultisampleAPPLE() allocates storage for a renderbuffer object that can be used as a multisample buffer. A multisample render buffer image differs from a single-sample render buffer image in that a multisample image has a number of SAMPLES that is greater than zero. No method is provided for creating multisample texture images. All of the framebuffer-attachable images attached to a framebuffer object must have the same number of SAMPLES or else the framebuffer object is not "framebuffer complete". If a framebuffer object with multisample attachments is "framebuffer complete", then the framebuffer object behaves as if SAMPLE_BUFFERS is one. The resolve operation is affected by calling ResolveMultisampleFramebufferAPPLE where the source is a multisample application-created framebuffer object and the destination is a single-sample framebuffer object. Separate read and draw framebuffer object binding points are established to facilitate the resolve. Scissoring may be used in conjunction with ResolveMultisampleFramebufferAPPLE to resolve only a portion of the framebuffer. IP Status No known IP claims. New Procedures and Functions void RenderbufferStorageMultisampleAPPLE( enum target, sizei samples, enum internalformat, sizei width, sizei height); void ResolveMultisampleFramebufferAPPLE(void); New Tokens Accepted by the parameter of GetRenderbufferParameteriv: RENDERBUFFER_SAMPLES_APPLE 0x8CAB Returned by CheckFramebufferStatus: FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE 0x8D56 Accepted by the parameter of GetBooleanv, GetIntegerv, and GetFloatv: MAX_SAMPLES_APPLE 0x8D57 Accepted by the parameter of BindFramebuffer, CheckFramebufferStatus, FramebufferTexture2D, FramebufferRenderbuffer, and GetFramebufferAttachmentParameteriv: READ_FRAMEBUFFER_APPLE 0x8CA8 DRAW_FRAMEBUFFER_APPLE 0x8CA9 Accepted by the parameter of GetBooleanv, GetIntegerv, and GetFloatv: DRAW_FRAMEBUFFER_BINDING_APPLE 0x8CA6 // FRAMEBUFFER_BINDING READ_FRAMEBUFFER_BINDING_APPLE 0x8CAA Additions to Chapter 2 of the OpenGL ES 2.0 Specification (OpenGL ES Operation) None Additions to Chapter 3 of the OpenGL ES 2.0 Specification (Rasterization) None Additions to Chapter 4 of the OpenGL ES 2.0 Specification (Per-Fragment Operations and the Framebuffer) Change the first word of Chapter 4 from "The" to "A". Append to the introduction of Chapter 4: "Conceptually, the GL has two active framebuffers; the draw framebuffer is the destination for rendering operations, and the read framebuffer is the source for readback operations. The same framebuffer may be used for both drawing and reading. Section 4.4.1 describes the mechanism for controlling framebuffer usage." Modify the last paragraph of section 4.1.1 as follows: "While an application-created framebuffer object is bound to DRAW_FRAMEBUFFER_APPLE, the pixel ownership test always passes." Add to 4.3.2 (Reading Pixels), right before the subsection titled "Obtaining Pixels from the Framebuffer": "ReadPixels generates INVALID_FRAMEBUFFER_OPERATION if the object bound to READ_FRAMEBUFFER_APPLE is not framebuffer complete (see section 4.4.5). ReadPixels generates INVALID_OPERATION if the object bound to READ_FRAMEBUFFER_APPLE is framebuffer complete and the value of SAMPLE_BUFFERS for the read framebuffer is greater than zero." Replace the first paragraph of the subsection titled "Obtaining Pixels from the Framebuffer" with the following: "The buffer from which values are obtained is the color buffer used for reading. If READ_FRAMEBUFFER_BINDING_APPLE is non-zero, pixel values are read from the buffer attached as the COLOR_ATTACHMENT0 attachment to the currently bound read framebuffer object." Modify the beginning of section 4.4.1 as follows: "The operations described in chapter 4 affect the images attached to the framebuffer objects bound to targets READ_FRAMEBUFFER_APPLE and DRAW_FRAMEBUFFER_APPLE. By default, the framebuffer bound to these targets is zero, specifying the default implementation-dependent framebuffer provided by the windowing system. When the framebuffers bound to these targets is not zero, but instead names an application-created framebuffer object, then the operations described in chapter 4 affect the application-created framebuffer object rather than the default framebuffer. The namespace for framebuffer objects is the unsigned integers, with zero reserved by OpenGL ES to refer to the default framebuffer. A framebuffer object is created by binding an unused name to DRAW_FRAMEBUFFER_APPLE or READ_FRAMEBUFFER_APPLE. The binding is effected by calling void BindFramebuffer(enum target, uint framebuffer); with set to the desired framebuffer target and set to the unused name. The resulting framebuffer object is a new state vector. There is one color attachment points, plus one each for the depth and stencil attachment points. BindFramebuffer may also be used to bind an existing framebuffer object to . If the bind is successful no change is made to the state of the bound framebuffer object, and any previous binding to is broken. The current DRAW_FRAMEBUFFER_APPLE and READ_FRAMEBUFFER_APPLE bindings can be queried using GetIntegerv(DRAW_FRAMEBUFFER_BINDING_APPLE) and GetIntegerv(READ_FRAMEBUFFER_BINDING_APPLE), respectively. If a framebuffer object is bound to DRAW_FRAMEBUFFER_APPLE or READ_FRAMEBUFFER_APPLE, it becomes the destination of fragment operations or the source of pixel reads, respectively, until it is deleted or another framebuffer is bound to the corresponding bind point. Calling BindFramebuffer with set to FRAMEBUFFER binds the framebuffer to both DRAW_FRAMEBUFFER_APPLE and READ_FRAMEBUFFER_APPLE. While a framebuffer object is bound, OpenGL ES operations on the target to which it is bound affect the images attached to the bound framebuffer object, and queries of the target to which it is bound return state from the bound object. In particular, queries of the values specified in table 6.20 (Implementation Dependent Pixel Depths) are derived from the framebuffer object bound to DRAW_FRAMEBUFFER_APPLE. In the initial state, the reserved name zero is bound to the targets DRAW_FRAMEBUFFER_APPLE and READ_FRAMEBUFFER_APPLE. There is no application created framebuffer object corresponding to the name zero. Instead, the name zero refers to the window-system-provided framebuffer. All Queries and operations on the framebuffer while the name zero is bound to target DRAW_FRAMEBUFFER_APPLE or READ_FRAMEBUFFER_APPLE operate on this default framebuffer..." Change the description of DeleteFramebuffers as follows: " contains names of framebuffer objects to be deleted. After a framebuffer object is deleted, it has no attachments, and its name is again unused. If a framebuffer that is currently bound to one or more of the targets DRAW_FRAMEBUFFER_APPLE or READ_FRAMEBUFFER_APPLE is deleted, it is as though BindFramebuffer had been executed with the corresponding and of zero. Unused names in are silently ignored, as is the value zero." Add to section 4.4.3, just above the definition of RenderbufferStorage: "The command void RenderbufferStorageMultisampleAPPLE( enum target, sizei samples, enum internalformat, sizei width, sizei height); establishes the data storage, format, dimensions, and number of samples of a renderbuffer object's image. must be RENDERBUFFER. must be one of the color-renderable, depth-renderable, or stencil-renderable formats described in table 4.5. and are the dimensions in pixels of the renderbuffer. If either or is greater than the value of MAX_RENDERBUFFER_SIZE, or if is greater than MAX_SAMPLES_APPLE, then the error INVALID_VALUE is generated. If OpenGL ES is unable to create a data store of the requested size, the error OUT_OF_MEMORY is generated. RenderbufferStorageMultisampleAPPLE deletes any existing data store for the renderbuffer and the contents of the data store after calling RenderbufferStorageMultisampleAPPLE are undefined. If is zero, then RENDERBUFFER_SAMPLES_APPLE is set to zero. Otherwise represents a request for a desired minimum number of samples. Since different implementations may support different sample counts for multisampled rendering, the actual number of samples allocated for the renderbuffer image is implementation dependent. However, the resulting value for RENDERBUFFER_SAMPLES_APPLE is guaranteed to be greater than or equal to and no more than the next larger sample count supported by the implementation. An OpenGL ES implementation may vary its allocation of internal component resolution based on any RenderbufferStorageMultisampleAPPLE parameter (except target), but the allocation and chosen internal format must not be a function of any other state and cannot be changed once they are established. The actual resolution in bits of each component of the allocated image can be queried with GetRenderbufferParameteriv." Modify the definiton of RenderbufferStorage in section 4.4.3 as follows: "The command void RenderbufferStorage( enum target, enum internalformat, sizei width, sizei height); is equivalent to calling RenderbufferStorageMultisampleAPPLE with equal to zero." In section 4.4.3, modify the first two sentences of the description of FramebufferRenderbuffer as follows: " must be DRAW_FRAMEBUFFER_APPLE, READ_FRAMEBUFFER_APPLE, or FRAMEBUFFER. If is FRAMEBUFFER, it behaves as though DRAW_FRAMEBUFFER_APPLE were specified. INVALID_OPERATION is generated if the current value of the corresponding binding is zero when FramebufferRenderbuffer is called." In section 4.4.3, modify the first two sentences of the description of FramebufferTexture2D as follows: "The must be DRAW_FRAMEBUFFER_APPLE, READ_FRAMEBUFFER_APPLE, or FRAMEBUFFER. If is FRAMEBUFFER, it behaves as though DRAW_FRAMEBUFFER_APPLE were specified. INVALID_OPERATION is generated if the current value of the corresponding binding is zero when FramebufferTexture2D is called." In section 4.4.5, add an entry to the Framebuffer Completeness bullet list: "* All attached images have the same number of samples. FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE" In section 4.4.5, modify the first sentence of the description of CheckFramebufferStatus as follows: "If is not DRAW_FRAMEBUFFER_APPLE, READ_FRAMEBUFFER_APPLE, or FRAMEBUFFER, INVALID_ENUM is generated. If is FRAMEBUFFER, it behaves as though DRAW_FRAMEBUFFER_APPLE were specified." Modify the first sentence of the last paragraph of section 4.4.5 as follows: "If the currently bound draw or read framebuffer is not framebuffer complete, then it is an error to attempt to use the framebuffer for writing or reading, respectively." In section 4.4.6, replace references to FRAMEBUFFER_BINDING with DRAW_FRAMEBUFFER_BINDING_APPLE. Add new section titled "Multisample Resolves" to section 4.4: "The command void ResolveMultisampleFramebufferAPPLE(void); converts the samples corresponding to each pixel location in the read framebuffer's color attachment to a single sample before writing them to the draw framebuffer's color attachment. The pixel copy bypasses the fragment pipeline. The only fragment operations which affect the resolve are the pixel ownership test, the scissor test, and dithering. INVALID_OPERATION is generated if SAMPLE_BUFFERS for the read framebuffer is zero, or if SAMPLE_BUFFERS for the draw framebuffer is greater than zero, or if the read framebuffer or draw framebuffer does not have a color attachment, or if the dimensions of the read and draw framebuffers are not identical, or if the components in the format of the draw framebuffer's color attachment are not present in the format of the read framebuffer's color attachment. INVALID_FRAMEBUFFER_OPERATION is generated if the objects bound to DRAW_FRAMEBUFFER_APPLE and READ_FRAMEBUFFER_APPLE are not framebuffer complete (see section 4.4.5)." Additions to Chapter 5 of the OpenGL ES 2.0 Specification (Special Functions) None Additions to Chapter 6 of the OpenGL ES 2.0 Specification (State and State Requests) In section 6.1.3, modify the first sentence of the description of GetFramebufferAttachmentParameteriv as follows: " must be DRAW_FRAMEBUFFER_APPLE, READ_FRAMEBUFFER_APPLE or FRAMEBUFFER. If is FRAMEBUFFER, it behaves as though DRAW_FRAMEBUFFER_APPLE were specified." In section 6.1.3, modify the third paragraph of the description of GetRenderbufferParameteriv as follows: "Upon successful return from GetRenderbufferParameteriv, if is RENDERBUFFER_WIDTH, RENDERBUFFER_HEIGHT, RENDERBUFFER_INTERNAL_FORMAT, or RENDERBUFFER_SAMPLES_APPLE, then will contain the width in pixels, height in pixels, internal format, or number of samples, respectively, of the image of the renderbuffer currently bound to ." Move SAMPLES and SAMPLE_BUFFERS state to table 6.20. Dependencies on OpenGL ES 1.1 On an OpenGL ES 1.1 implementation, OES_framebuffer_object is required. Include GetFixedv where GetBooleanv, GetIntegerv and GetFloatv appear. Add OES suffixes to entrypoints and tokens introduced by OES_framebuffer_object. Dependencies on EXT_discard_framebuffer In the presence of EXT_discard_framebuffer, DiscardFramebufferEXT is modified to allow READ_FRAMEBUFFER_APPLE and DRAW_FRAMEBUFFER_APPLE as acceptable targets. If is FRAMEBUFFER, DiscardFramebufferEXT behaves as though DRAW_FRAMEBUFFER_APPLE were specified. Errors INVALID_FRAMEBUFFER_OPERATION is generated if DrawArrays, DrawElements, or ResolveMultisampleFramebufferAPPLE is called while the draw framebuffer is not framebuffer complete. INVALID_FRAMEBUFFER_OPERATION is generated if ReadPixels, CopyTex{Sub}Image*, or ResolveMultisampleFramebufferAPPLE is called while the read framebuffer is not framebuffer complete. INVALID_OPERATION is generated if ReadPixels, or CopyTex{Sub}Image* is called while READ_FRAMEBUFFER_BINDING_APPLE is non-zero, the read framebuffer is framebuffer complete, and the value of SAMPLE_BUFFERS for the read framebuffer is greater than zero. INVALID_OPERATION is generated by ResolveMultisampleFramebufferAPPLE if SAMPLE_BUFFERS for the read framebuffer is zero, or if SAMPLE_BUFFERS for the draw framebuffer is greater than zero, or if the read framebuffer or draw framebuffer does not have a color attachment, or if the dimensions of the read and draw framebuffers are not identical, or if the components in the format of the draw framebuffer's color attachment are not present in the format of the read framebuffer's color attachment. OUT_OF_MEMORY is generated when RenderbufferStorageMultisampleAPPLE cannot create storage of the specified size. INVALID_VALUE is generated if RenderbufferStorageMultisampleAPPLE is called with a value of that is greater than MAX_SAMPLES_APPLE or with a value of or that is greater than MAX_RENDERBUFFER_SIZE. New State Add to table 6.19 (Implementation Dependent Values (cont.)): Get Value Type Get Command Minimum Value Description Section --------- ---- ----------- ------------- ------------------- ------- MAX_SAMPLES_APPLE Z+ GetIntegerv 1 Maximum number of 4.4.3 samples supported for multisampling Add to table 6.22 (Renderbuffer State): Get Value Type Get Command Initial Value Description Section -------------------------- ---- -------------------------- ------------- -------------------- ------- RENDERBUFFER_SAMPLES_APPLE Z+ GetRenderbufferParameteriv 0 Renderbuffer samples 4.4.3 Remove reference to FRAMEBUFFER_BINDING from Table 6.23 (Framebuffer State) and replace with the following: Get Value Type Get Command Initial Value Description Section ------------------------------ ---- ----------- ------------- ------------------------- ------- DRAW_FRAMEBUFFER_BINDING_APPLE Z+ GetIntegerv 0 Framebuffer object bound 4.4.1 to DRAW_FRAMEBUFFER_APPLE READ_FRAMEBUFFER_BINDING_APPLE Z+ GetIntegerv 0 Framebuffer object 4.4.1 to READ_FRAMEBUFFER_APPLE Revision History #4, February 24, 2011: Benj Lipchak - assign extension number - clarify that dithering is still performed during resolve - clarify that only format conversions that drop components are allowed during resolve #3, January 5, 2010: Benj Lipchak - remove the error when read and draw color formats are not identical - add an error when missing a color attachment to the read or draw FBO #2, October 29, 2009: Benj Lipchak - add interaction with EXT_discard_framebuffer - mention that scissoring can be used for partial resolves #1, October 28, 2009: Benj Lipchak - first revision