Name EXT_framebuffer_blit Name Strings GL_EXT_framebuffer_blit Contributors Michael Gold Evan Hart Jeff Juliano Jon Leech Bill Licea-Kane Barthold Lichtenbelt Brian Paul Ian Romanick John Rosasco Jeremy Sandmel Eskil Steenberg Contact Michael Gold, NVIDIA Corporation (gold 'at' nvidia.com) Status Complete. Approved by the ARB "superbuffers" working group on November 8, 2005. Version Last Modified Date: April 5, 2007 Author Revision: 15 Number 316 Dependencies OpenGL 1.1 is required. EXT_framebuffer_object is required. The extension is written against the OpenGL 1.5 specification. ARB_color_buffer_float affects the definition of this extension. Overview This extension modifies EXT_framebuffer_object by splitting the framebuffer object binding point into separate DRAW and READ bindings. This allows copying directly from one framebuffer to another. In addition, a new high performance blit function is added to facilitate these blits and perform some data conversion where allowed. IP Status No known IP claims. New Procedures and Functions void BlitFramebufferEXT(int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, bitfield mask, enum filter); New Tokens Accepted by the parameter of BindFramebufferEXT, CheckFramebufferStatusEXT, FramebufferTexture{1D|2D|3D}EXT, FramebufferRenderbufferEXT, and GetFramebufferAttachmentParameterivEXT: READ_FRAMEBUFFER_EXT 0x8CA8 DRAW_FRAMEBUFFER_EXT 0x8CA9 Accepted by the parameters of GetIntegerv, GetFloatv, and GetDoublev: DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6 // alias FRAMEBUFFER_BINDING_EXT READ_FRAMEBUFFER_BINDING_EXT 0x8CAA Additions to Chapter 2 of the OpenGL 1.5 Specification (OpenGL Operation) Append the following to section 2.6.1: "Calling Begin will result in an INVALID_FRAMEBUFFER_OPERATION_EXT error if the object bound to DRAW_FRAMEBUFFER_BINDING_EXT is not "framebuffer complete" (section 4.4.4.2)." Additions to Chapter 3 of the OpenGL 1.5 Specification (Rasterization) Add to section 3.6.3, at the end of the subsection titled "Alternate Color Table Specification Commands": "Calling CopyColorTable or CopyColorSubTable will result in an INVALID_FRAMEBUFFER_OPERATION_EXT error if the object bound to READ_FRAMEBUFFER_BINDING_EXT is not "framebuffer complete" (section 4.4.4.2)." Add to section 3.6.3, at the end of the subsection titled "Alternate Convolution Filter Specification Commands": "Calling CopyConvolutionFilter1D or CopyConvolutionFilter2D will result in an INVALID_FRAMEBUFFER_OPERATION_EXT error if the object bound to READ_FRAMEBUFFER_BINDING_EXT is not "framebuffer complete" (section 4.4.4.2)." In section 3.6.4, modify the final paragraph of the definition of DrawPixels as follows: "Calling DrawPixels will result in an INVALID_FRAMEBUFFER_OPERATION_EXT error if the object bound to DRAW_FRAMEBUFFER_BINDING_EXT is not "framebuffer complete" (section 4.4.4.2)." Add the following to section 3.7, following the description of Bitmap: "Calling Bitmap will result in an INVALID_FRAMEBUFFER_OPERATION_EXT error if the object bound to DRAW_FRAMEBUFFER_BINDING_EXT is not "framebuffer complete" (section 4.4.4.2)." Append the following to section 3.8.2: "Calling CopyTexSubImage3D, CopyTexImage2D, CopyTexSubImage2D, CopyTexImage1D or CopyTexSubImage1D will result in an INVALID_FRAMEBUFFER_OPERATION_EXT error if the object bound to READ_FRAMEBUFFER_BINDING_EXT is not "framebuffer complete" (section 4.4.4.2)." Additions to Chapter 4 of the OpenGL 1.5 Specification (Per-Fragment Operations and the Frame Buffer) 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_EXT, the pixel ownership test always passes." Modify the last sentence of the second to last paragraph of section 4.2.4 as follows: "If there is no accumulation buffer, or if the DRAW_FRAMEBUFFER_EXT and READ_FRAMEBUFFER_EXT bindings (section 4.4.4.2) do not refer to the same object, or if the GL is in color index mode, Accum generates the error INVALID_OPERATION." Add to 4.3.2 (Reading Pixels), right before the subsection titled "Obtaining Pixels from the Framebuffer": "Calling ReadPixels generates INVALID_FRAMEBUFFER_OPERATION_EXT if the object bound to READ_FRAMEBUFFER_BINDING_EXT is not "framebuffer complete" (section 4.4.4.2)." In section 4.3.2, modify the definition of ReadBuffer as follows: "The command void ReadBuffer( enum src ); takes a symbolic constant as argument. must be one of the values from tables 4.4 or 10.nnn. Otherwise, INVALID_ENUM is generated. Further, the acceptable values for depend on whether the GL is using the default window-system-provided framebuffer (i.e., READ_FRAMEBUFFER_BINDING_EXT is zero), or an application-created framebuffer object (i.e., READ_FRAMEBUFFER_BINDING_EXT is non-zero). For more information about application-created framebuffer objects, see section 4.4. When READ_FRAMEBUFFER_BINDING_EXT is zero, i.e. the default window-system-provided framebuffer, must be one of the values listed in table 4.4. FRONT and LEFT refer to the front left buffer, BACK refers to the back left buffer, and RIGHT refers to the front right buffer. The other constants correspond directly to the buffers that they name. If the requested buffer is missing, then the error INVALID_OPERATION is generated. For the default window-system-provided framebuffer, the initial setting for ReadBuffer is FRONT if there is no back buffer and BACK otherwise. Modify the first sentence of section 4.3.3 as follows: "CopyPixels transfers a rectangle of pixel values from one region of the read framebuffer to another in the draw framebuffer." Add the following text to section 4.3.3, page 194, inside the definition of CopyPixels: "Finally, the behavior of several GL operations is specified "as if the arguments were passed to CopyPixels." These operations include: CopyTex{Sub}Image*, CopyColor{Sub}Table, and CopyConvolutionFilter*. INVALID_FRAMEBUFFER_OPERATION_EXT will be generated if an attempt is made to execute one of these operations, or CopyPixels, while the object bound to READ_FRAMEBUFFER_BINDING_EXT is not "framebuffer complete" (as defined in section 4.4.4.2). Furthermore, an attempt to execute CopyPixels will generate INVALID_FRAMEBUFFER_OPERATION_EXT while the object bound to DRAW_FRAMEBUFFER_BINDING_EXT is not "framebuffer complete"." Append to section 4.3.3: "BlitFramebufferEXT transfers a rectangle of pixel values from one region of the read framebuffer to another in the draw framebuffer. There are some important distinctions from CopyPixels, as described below. BlitFramebufferEXT(int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, bitfield mask, enum filter); is the bitwise OR of a number of values indicating which buffers are to be copied. The values are COLOR_BUFFER_BIT, DEPTH_BUFFER_BIT, and STENCIL_BUFFER_BIT, which are described in section 4.2.3. The pixels corresponding to these buffers are copied from the source rectangle, bound by the locations (srcX0, srcY0) and (srcX1, srcY1), to the destination rectangle, bound by the locations (dstX0, dstY0) and (dstX1, dstY1). The lower bounds of the rectangle are inclusive, while the upper bounds are exclusive. If the source and destination rectangle dimensions do not match, the source image is stretched to fit the destination rectangle. must be LINEAR or NEAREST and specifies the method of interpolation to be applied if the image is stretched. LINEAR filtering is allowed only for the color buffer; if includes DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT, and filter is not NEAREST, no copy is performed and an INVALID_OPERATION error is generated. If the source and destination dimensions are identical, no filtering is applied. If either the source or destination rectangle specifies a negative dimension, the image is reversed in the corresponding direction. If both the source and destination rectangles specify a negative dimension for the same direction, no reversal is performed. If the source and destination buffers are identical, and the source and destination rectangles overlap, the result of the blit operation is undefined. The pixel copy bypasses the fragment pipeline. The only fragment operations which affect the blit are the pixel ownership test and the scissor test. If a buffer is specified in and does not exist in both the read and draw framebuffers, the corresponding bit is silently ignored. If the color formats of the read and draw framebuffers do not match, and includes COLOR_BUFFER_BIT, the pixel groups are converted to match the destination format as in CopyPixels, except that no pixel transfer operations apply and clamping behaves as if CLAMP_FRAGMENT_COLOR_ARB is set to FIXED_ONLY_ARB. Calling CopyPixels or BlitFramebufferEXT will result in an INVALID_FRAMEBUFFER_OPERATION_EXT error if the objects bound to DRAW_FRAMEBUFFER_BINDING_EXT and READ_FRAMEBUFFER_BINDING_EXT are not "framebuffer complete" (section 4.4.4.2)." Calling BlitFramebufferEXT will result in an INVALID_OPERATION error if includes DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT and the source and destination depth and stencil buffer formats do not match. Modify the beginning of section 4.4.1 as follows: "The default framebuffer for rendering and readback operations is provided by the windowing system. In addition, named framebuffer objects can be created and operated upon. The namespace for framebuffer objects is the unsigned integers, with zero reserved by the GL for the default framebuffer. A framebuffer object is created by binding an unused name to DRAW_FRAMEBUFFER_EXT or READ_FRAMEBUFFER_EXT. The binding is effected by calling void BindFramebufferEXT(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, comprising all the state values listed in table 4.nnn, as well as one set of the state values listed in table 5.nnn for each attachment point of the framebuffer, set to the same initial values. There are MAX_COLOR_ATTACHMENTS_EXT color attachment points, plus one each for the depth and stencil attachment points. BindFramebufferEXT may also be used to bind an existing framebuffer object to DRAW_FRAMEBUFFER_EXT or READ_FRAMEBUFFER_EXT. If the bind is successful no change is made to the state of the bound framebuffer object, and any previous binding to is broken. If a framebuffer object is bound to DRAW_FRAMEBUFFER_EXT or READ_FRAMEBUFFER_EXT, it becomes the target for rendering or readback operations, respectively, until it is deleted or another framebuffer is bound to the corresponding bind point. Calling BindFramebufferEXT with set to FRAMEBUFFER_EXT binds the framebuffer to both DRAW_FRAMEBUFFER_EXT and READ_FRAMEBUFFER_EXT. While a framebuffer object is bound, GL 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. Queries of the values specified in table 6.31 (Implementation Dependent Pixel Depths) and table 8.nnn (Framebuffer-Dependent State Variables) are derived from the framebuffer object bound to DRAW_FRAMEBUFFER_EXT. The initial state of DRAW_FRAMEBUFFER_EXT and READ_FRAMEBUFFER_EXT refers to the default framebuffer provided by the windowing system. In order that access to the default framebuffer is not lost, it is treated as a framebuffer object with the name of 0. The default framebuffer is therefore rendered to and read from while 0 is bound to the corresponding targets. On some implementations, the properties of the default framebuffer can change over time (e.g., in response to windowing system events such as attaching the context to a new windowing system drawable.)" Change the description of DeleteFramebuffersEXT 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_EXT or READ_FRAMEBUFFER_EXT is deleted, it is as though BindFramebufferEXT had been executed with the corresponding and zero. Unused names in are silently ignored, as is the value zero." In section 4.4.2.2, modify the first two sentences of the description of FramebufferRenderbufferEXT as follows: " must be DRAW_FRAMEBUFFER_EXT, READ_FRAMEBUFFER_EXT, or FRAMEBUFFER_EXT. If is FRAMEBUFFER_EXT, it behaves as though DRAW_FRAMEBUFFER_EXT was specified. INVALID_OPERATION is generated if the value of the corresponding binding is zero." In section 4.4.2.3, modify the first two sentences of the description of FramebufferTexturexDEXT as follows: "In all three routines, must be DRAW_FRAMEBUFFER_EXT, READ_FRAMEBUFFER_EXT, or FRAMEBUFFER_EXT. If is FRAMEBUFFER_EXT, it behaves as though DRAW_FRAMEBUFFER_EXT was specified. INVALID_OPERATION is generated if the value of the corresponding binding is zero." In section 4.4.4.2, modify the first sentence of the description of CheckFramebufferStatusEXT as follows: "If is not DRAW_FRAMEBUFFER_EXT, READ_FRAMEBUFFER_EXT or FRAMEBUFFER_EXT, INVALID_ENUM is generated. If is FRAMEBUFFER_EXT, it behaves as though DRAW_FRAMEBUFFER_EXT was specified." Modify section 4.4.4.3 as follows: "Attempting to render to or read from a framebuffer which is not framebuffer complete will generate an INVALID_FRAMEBUFFER_OPERATION_EXT error." Additions to Chapter 6 of the OpenGL 1.5 Specification (State and State Requests) In section 6.1.3, modify the first sentence of the description of GetFramebufferAttachmentParameterivEXT as follows: " must be DRAW_FRAMEBUFFER_EXT, READ_FRAMEBUFFER_EXT or FRAMEBUFFER_EXT. If is FRAMEBUFFER_EXT, it behaves as though DRAW_FRAMEBUFFER_EXT was specified." GLX Protocol BlitFramebufferEXT 2 44 rendering command length 2 4330 rendering command opcode 4 CARD32 source X0 4 CARD32 source Y0 4 CARD32 source X1 4 CARD32 source Y1 4 CARD32 destination X0 4 CARD32 destination Y0 4 CARD32 destination X1 4 CARD32 destination Y1 4 CARD32 mask 4 ENUM filter Dependencies on ARB_color_buffer_float The reference to CLAMP_FRAGMENT_COLOR_ARB in section 4.3.3 applies only if ARB_color_buffer_float is supported. Errors The error INVALID_FRAMEBUFFER_OPERATION_EXT is generated if BlitFramebufferEXT, DrawPixels, or CopyPixels is called while the draw framebuffer is not framebuffer complete. The error INVALID_FRAMEBUFFER_OPERATION_EXT is generated if BlitFramebufferEXT, ReadPixels, CopyPixels, CopyTex{Sub}Image*, CopyColor{Sub}Table, or CopyConvolutionFilter* is called while the read framebuffer is not framebuffer complete. The error INVALID_VALUE is generated by BlitFramebufferEXT if has any bits set other than those named by COLOR_BUFFER_BIT, DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT. The error INVALID_OPERATION is generated if BlitFramebufferEXT is called and includes DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT and is not NEAREST. The error INVALID_OPERATION is generated if BlitFramebufferEXT is called and includes DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT and the source and destination depth or stencil buffer formats do not match. The error INVALID_ENUM is generated by BlitFramebufferEXT if is not LINEAR or NEAREST. The error INVALID_OPERATION is generated if BlitFramebufferEXT is called within a Begin/End pair. The error INVALID_ENUM is generated if BindFramebufferEXT, CheckFramebufferStatusEXT, FramebufferTexture{1D|2D|3D}EXT, FramebufferRenderbufferEXT, or GetFramebufferAttachmentParameterivEXT is called and is not DRAW_FRAMEBUFFER_EXT, READ_FRAMEBUFFER_EXT or FRAMEBUFFER_EXT. New State (modify table 3.nnn, "Framebuffer (state per framebuffer target binding point)") Get Value Type Get Command Initial Value Description Section Attribute ---------------------------- ---- ----------- -------------- ------------------- ------------ --------- DRAW_FRAMEBUFFER_BINDING_EXT Z+ GetIntegerv 0 framebuffer object bound 4.4.1 - to DRAW_FRAMEBUFFER_EXT READ_FRAMEBUFFER_BINDING_EXT Z+ GetIntegerv 0 framebuffer object 4.4.1 - to READ_FRAMEBUFFER_EXT Remove reference to FRAMEBUFFER_BINDING_EXT. Sample Code /* Render to framebuffer object 2 */ BindFramebufferEXT(DRAW_FRAMEBUFFER_EXT, 2); RenderScene(); /* Blit contents of color buffer, depth buffer and stencil buffer * from framebuffer object 2 to framebuffer object 1. */ BindFramebufferEXT(READ_FRAMEBUFFER_EXT, 2); BindFramebufferEXT(DRAW_FRAMEBUFFER_EXT, 1); BlitFramebufferEXT(0, 0, 640, 480, 0, 0, 640, 480, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); /* Blit contents of color buffer from framebuffer object 1 to * framebuffer object 2, inverting the image in the X direction. */ BindFramebufferEXT(READ_FRAMEBUFFER_EXT, 1); BindFramebufferEXT(DRAW_FRAMEBUFFER_EXT, 2); BlitFramebufferEXT(0, 0, 640, 480, 640, 0, 0, 480, GL_COLOR_BUFFER_BIT, GL_NEAREST); /* Blit color buffer from framebuffer object 1 to framebuffer * object 3 with a 2X zoom and linear filtering. */ BindFramebufferEXT(READ_FRAMEBUFFER_EXT, 1); BindFramebufferEXT(DRAW_FRAMEBUFFER_EXT, 3); BlitFramebufferEXT(0, 0, 640, 480, 0, 0, 1280, 960, GL_COLOR_BUFFER_BIT, GL_LINEAR); Issues 1) Should we pass in explicit source/dest rects instead of using the rasterpos/pixelzoom? Resolved: use explicit rects, so we don't need to perform multiple state changes. 2) Should rects be (start,size) or (start,end)? Resolved: use (start,end). This is a break from the past (scissor, viewport) but is more intuitive than allowing a negative size where mirrored zooms are desireable. 3) What should we call the blit function? Resolved: BlitFramebufferEXT 4) Should filtering apply to depth or stencil values? Resolved: No 5) What happens if LINEAR is specified and DEPTH or STENCIL is in the mask? Resolved: Generate ERROR_INVALID_OPERATION 6) What happens if READ_FRAMEBUFFER is NONE and a read is attempted? Resolved: Generate ERROR_INVALID_OPERATION 7) Should we generalize binding point assignment with a single entry point and a parameter specifying read/write/whatever? Resolved: concensus leans toward separate Read/Draw entry points. 8) Should we define READ_FRAMEBUFFER and DRAW_FRAMEBUFFER targets for BindFramebuffer instead of introducing a new level of indirection? Resolved: Yes. Binding to the legacy target FRAMEBUFFER sets both DRAW_FRAMEBUFFER and READ_FRAMEBUFFER. Querying FRAMEBUFFER_BINDING return the DRAW_FRAMEBUFFER_BINDING. 9) What happens when a user queries framebuffer attributes, e.g. Get(RED_BITS)? Is the result returned from READ_FRAMEBUFFER or DRAW_FRAMEBUFFER? Do we need a new query? e.g. GetFramebufferParameteriv(int target, enum pname, int* value) Resolved: always return the value associated with the DRAW_FRAMEBUFFER. Do not add a new query. 10) How does Accum behave in the presence of separate READ/DRAW framebuffers? Resolved: Accum returns INVALID_OPERATION if the READ_FRAMEBUFFER and DRAW_FRAMEBUFFER bindings are not identical. 11) Should blits be allowed between buffers of different bit sizes? Resolved: Yes, for color buffers only. Attempting to blit between depth or stencil buffers of different size generates INVALID_OPERATION. 12) Should we add support for multiple ReadBuffers, so that multiple color buffers may be copied with a single call to BlitFramebuffer? Resolved: No, we considered this but the behavior is awkward to define and the functionality is of limited use. 13) How should BlitFramebuffer color space conversion be specified? Do we allow context clamp state to affect the blit? Resolved: Blitting to a fixed point buffer always clamps, blitting to a floating point buffer never clamps. The context state is ignored. 14) Should overlapped blits be allowed? Should they be guaranteed to work? Resolved: Overlapping blits are allowed but are undefined. Revision History Revision 15, 2007/4/6 - Removed language left over from ReadBuffers. - Removed reference to nonexistent 'CopyTexImage3D'. Revision 14, 2006/09/29 - Changed the resolution of issue 12 to reflect the working group decision to abandon ReadBuffers. - Eliminated issues 15, 16 and 17 as they are no longer relevent. - Changed the resolution of issue 14 and the corresponding spec language to indicate that the result of an overlapping blit is undefined. - Changed the spec language to clarify that the lower bound of a blit rectangle is inclusive while the upper bound is exclusive. - Added a sample showing an inverted blit, to clarify the pixel addressing rules. - Clarified spec language and error behavior to indicate that blitting DEPTH and STENCIL buffers with LINEAR filtering is always disallowed, whether or not the blit is scaling. Revision 13, 2006/06/01 (Jeff Juliano) - Clarify errors generated when read and draw framebuffers are incomplete. Revision 12, 2005/12/22 (Jon Leech) - Assigned enumerant values. Add return type to BlitFramebufferEXT. Note INVALID_ENUM error if filter is not LINEAR or NEAREST. Revision 11, 2005/12/14 - Added several missing conditions to the Errors section. - Changed status to "Complete". Revision 10, 2005/11/6 - Removed all ReadBuffers discussion, as this functionality will be deferred. Issues 15-17 are hereafter irrelevent. Revision 9, 2005/10/31 - Resolved issue 16 and updated language to reflect this decision. - Minor language changes per feedback. - Added issue 17 and resolution, although language does not reflect this. Revision 8, 2005/10/20 - Added ReadBuffersEXT language - Removed some redundant language in ReadBuffer - Re-opened issue 15 for further consideration - Added issue 16 Revision 7, 2005/10/7 - Added issues 13 and 14, and resolution for 11, 13, and 14. - Added dependency on ARB_color_buffer_float. - Removed multisample language, now covered in EXT_framebuffer_multisample. - Added framebuffer incomplete error language to spec proper. - Alias DRAW_FRAMEBUFFER_BINDING_EXT to FRAMEBUFFER_BINDING_EXT. - Updated Overview text to reflect the resolution to issue 8. Revision 6, 2005/9/26 - Moved issues to the end, per new conventions. - Added new language referring to DRAW_FRAMEBUFFER and READ_FRAMEBUFFER bind points to sections 4.1.1, 4.4.1, 4.4.2.2, 4.4.2.3, 4.4.4.2, 6.1.3 and Errors, and updated the example code, per resolution of issue 8. - Added language in section 4.4.1 specifying Get behavior, per resolution of issue 9. - Added language to section 4.2.4 describing new error behavior for Accum, per resolution of issue 10. - Added language to section 4.3.3 describing color format conversion, per resolution of issue 11. Revision 5, 2005/9/6 - Added issues 8 - 11 - Minor edits from reviewer feedback Revision 4, 2005/9/5 - Added chapter 4 intro section - Added errors and state table information - Added sample code - fixed typos Revision 3, 2005/8/29 - Converted to spec template Revision 2, 2005/7/18 - Lots of new issues added and resolved Revision 1, 2005/7/5 - Initial draft