michael@0: Name michael@0: michael@0: ANGLE_framebuffer_blit michael@0: michael@0: Name Strings michael@0: michael@0: GL_ANGLE_framebuffer_blit michael@0: michael@0: Contributors michael@0: michael@0: Contributors to EXT_framebuffer_blit michael@0: Daniel Koch, TransGaming Inc. michael@0: Shannon Woods, TransGaming Inc. michael@0: Kenneth Russell, Google Inc. michael@0: Vangelis Kokkevis, Google Inc. michael@0: michael@0: Contact michael@0: michael@0: Daniel Koch, TransGaming Inc. (daniel 'at' transgaming 'dot' com) michael@0: michael@0: Status michael@0: michael@0: Implemented in ANGLE ES2 michael@0: michael@0: Version michael@0: michael@0: Last Modified Date: Sept 22, 2012 michael@0: Author Revision: 4 michael@0: michael@0: Number michael@0: michael@0: OpenGL ES Extension #83 michael@0: michael@0: Dependencies michael@0: michael@0: OpenGL ES 2.0 is required. michael@0: michael@0: The extension is written against the OpenGL ES 2.0 specification. michael@0: michael@0: OES_texture_3D affects the definition of this extension. michael@0: michael@0: Overview michael@0: michael@0: This extension modifies framebuffer objects by splitting the michael@0: framebuffer object binding point into separate DRAW and READ michael@0: bindings. This allows copying directly from one framebuffer to michael@0: another. In addition, a new high performance blit function is michael@0: added to facilitate these blits and perform some data conversion michael@0: where allowed. michael@0: michael@0: IP Status michael@0: michael@0: No known IP claims. michael@0: michael@0: New Procedures and Functions michael@0: michael@0: void BlitFramebufferANGLE(int srcX0, int srcY0, int srcX1, int srcY1, michael@0: int dstX0, int dstY0, int dstX1, int dstY1, michael@0: bitfield mask, enum filter); michael@0: michael@0: New Tokens michael@0: michael@0: Accepted by the parameter of BindFramebuffer, michael@0: CheckFramebufferStatus, FramebufferTexture2D, FramebufferTexture3DOES, michael@0: FramebufferRenderbuffer, and michael@0: GetFramebufferAttachmentParameteriv: michael@0: michael@0: // (reusing the tokens from EXT_framebuffer_blit) michael@0: READ_FRAMEBUFFER_ANGLE 0x8CA8 michael@0: DRAW_FRAMEBUFFER_ANGLE 0x8CA9 michael@0: michael@0: Accepted by the parameters of GetIntegerv and GetFloatv: michael@0: michael@0: // (reusing the tokens from EXT_framebuffer_blit) michael@0: DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6 // alias FRAMEBUFFER_BINDING michael@0: READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA michael@0: michael@0: michael@0: Additions to Chapter 3 of the OpenGL ES 2.0 Specification (Rasterization) michael@0: michael@0: Change the last paragraph of section 3.7.2 (Alternate Texture Image michael@0: Specification Commands) to: michael@0: michael@0: "Calling CopyTexSubImage3DOES, CopyTexImage2D or CopyTexSubImage2D will michael@0: result in an INVALID_FRAMEBUFFER_OPERATION error if the object bound michael@0: to READ_FRAMEBUFFER_BINDING_ANGLE is not "framebuffer complete" michael@0: (section 4.4.4.2)." michael@0: michael@0: Additions to Chapter 4 of the OpenGL ES 2.0 Specification (Per-Fragment michael@0: Operations and the Framebuffer) michael@0: michael@0: Change the first word of Chapter 4 from "The" to "A". michael@0: michael@0: Append to the introduction of Chapter 4: michael@0: michael@0: "Conceptually, the GL has two active framebuffers; the draw michael@0: framebuffer is the destination for rendering operations, and the michael@0: read framebuffer is the source for readback operations. The same michael@0: framebuffer may be used for both drawing and reading. Section michael@0: 4.4.1 describes the mechanism for controlling framebuffer usage." michael@0: michael@0: Modify the first sentence of the last paragraph of section 4.1.1 as follows: michael@0: michael@0: "While an application-created framebuffer object is bound to michael@0: DRAW_FRAMEBUFFER_ANGLE, the pixel ownership test always passes." michael@0: michael@0: Add to 4.3.1 (Reading Pixels), right before the subsection titled michael@0: "Obtaining Pixels from the Framebuffer": michael@0: michael@0: "Calling ReadPixels generates INVALID_FRAMEBUFFER_OPERATION if michael@0: the object bound to READ_FRAMEBUFFER_BINDING_ANGLE is not "framebuffer michael@0: complete" (section 4.4.4.2). GetIntegerv generates an INVALID_OPERATION michael@0: error if the object bound to READ_FRAMEBUFFER_BINDING_ANGLE is not michael@0: framebuffer complete, or if the GL is using a framebuffer object michael@0: (i.e. READ_FRAMEBUFFER_BINDING_ANGLE is non-zero) and there is no color michael@0: attachment." michael@0: michael@0: Insert a new section 4.3.2 titled "Copying Pixels" and renumber the michael@0: subsequent sections. Add the following text: michael@0: michael@0: "BlitFramebufferANGLE transfers a rectangle of pixel values from one michael@0: region of the read framebuffer to another in the draw framebuffer. michael@0: michael@0: BlitFramebufferANGLE(int srcX0, int srcY0, int srcX1, int srcY1, michael@0: int dstX0, int dstY0, int dstX1, int dstY1, michael@0: bitfield mask, enum filter); michael@0: michael@0: is the bitwise OR of a number of values indicating which michael@0: buffers are to be copied. The values are COLOR_BUFFER_BIT, michael@0: DEPTH_BUFFER_BIT, and STENCIL_BUFFER_BIT, which are described in michael@0: section 4.2.3. The pixels corresponding to these buffers are michael@0: copied from the source rectangle, bound by the locations (srcX0, michael@0: srcY0) and (srcX1, srcY1), to the destination rectangle, bound by michael@0: the locations (dstX0, dstY0) and (dstX1, dstY1). The lower bounds michael@0: of the rectangle are inclusive, while the upper bounds are michael@0: exclusive. michael@0: michael@0: The actual region taken from the read framebuffer is limited to the michael@0: intersection of the source buffers being transferred, which may include michael@0: the color buffer, the depth buffer, and/or the stencil buffer depending on michael@0: . The actual region written to the draw framebuffer is limited to the michael@0: intersection of the destination buffers being written, which may include michael@0: the color buffer, the depth buffer, and/or the stencil buffer michael@0: depending on . Whether or not the source or destination regions are michael@0: altered due to these limits, the offset applied to pixels being transferred michael@0: is performed as though no such limits were present. michael@0: michael@0: Stretching and scaling during a copy are not supported. If the source michael@0: and destination rectangle dimensions do not match, no copy is michael@0: performed and an INVALID_OPERATION error is generated. michael@0: Because stretching is not supported, must be NEAREST and michael@0: no filtering is applied. michael@0: michael@0: Flipping during a copy is not supported. If either the source or michael@0: destination rectangle specifies a negative dimension, the error michael@0: INVALID_OPERATION is generated. If both the source and michael@0: destination rectangles specify a negative dimension for the same michael@0: direction, no reversal is required and the operation is supported. michael@0: michael@0: If the source and destination buffers are identical, and the michael@0: source and destination rectangles overlap, the result of the blit michael@0: operation is undefined. michael@0: michael@0: The pixel copy bypasses the fragment pipeline. The only fragment michael@0: operations which affect the blit are the pixel ownership test and michael@0: the scissor test. michael@0: michael@0: If a buffer is specified in and does not exist in both the michael@0: read and draw framebuffers, the corresponding bit is silently michael@0: ignored. michael@0: michael@0: Calling BlitFramebufferANGLE will result in an michael@0: INVALID_FRAMEBUFFER_OPERATION error if the objects bound to michael@0: DRAW_FRAMEBUFFER_BINDING_ANGLE and READ_FRAMEBUFFER_BINDING_ANGLE are michael@0: not "framebuffer complete" (section 4.4.4.2)." michael@0: michael@0: Calling BlitFramebufferANGLE will result in an INVALID_OPERATION michael@0: error if includes COLOR_BUFFER_BIT and the source and michael@0: destination color formats to not match. michael@0: michael@0: Calling BlitFramebufferANGLE will result in an INVALID_OPERATION michael@0: error if includes DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT michael@0: and the source and destination depth and stencil buffer formats do michael@0: not match. michael@0: michael@0: If includes DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT, only michael@0: complete buffers can be copied. If the source rectangle does not michael@0: specify the complete source buffer or the destination rectangle michael@0: (after factoring the scissor region, if applicable) does not specify michael@0: the complete destination buffer, an INVALID_OPERATION michael@0: error is generated. michael@0: michael@0: Modify the beginning of section 4.4.1 as follows: michael@0: michael@0: "The default framebuffer for rendering and readback operations is michael@0: provided by the windowing system. In addition, named framebuffer michael@0: objects can be created and operated upon. The namespace for michael@0: framebuffer objects is the unsigned integers, with zero reserved michael@0: by the GL for the default framebuffer. michael@0: michael@0: A framebuffer object is created by binding an unused name to michael@0: DRAW_FRAMEBUFFER_ANGLE or READ_FRAMEBUFFER_ANGLE. The binding is michael@0: effected by calling michael@0: michael@0: void BindFramebuffer(enum target, uint framebuffer); michael@0: michael@0: with set to the desired framebuffer target and michael@0: set to the unused name. The resulting framebuffer michael@0: object is a new state vector, comprising one set of the state values michael@0: listed in table 6.23 for each attachment point of the michael@0: framebuffer, set to the same initial values. There is one michael@0: color attachment point, plus one each michael@0: for the depth and stencil attachment points. michael@0: michael@0: BindFramebuffer may also be used to bind an existing michael@0: framebuffer object to DRAW_FRAMEBUFFER_ANGLE or michael@0: READ_FRAMEBUFFER_ANGLE. If the bind is successful no change is made michael@0: to the state of the bound framebuffer object, and any previous michael@0: binding to is broken. michael@0: michael@0: If a framebuffer object is bound to DRAW_FRAMEBUFFER_ANGLE or michael@0: READ_FRAMEBUFFER_ANGLE, it becomes the target for rendering or michael@0: readback operations, respectively, until it is deleted or another michael@0: framebuffer is bound to the corresponding bind point. Calling michael@0: BindFramebuffer with set to FRAMEBUFFER binds the michael@0: framebuffer to both DRAW_FRAMEBUFFER_ANGLE and READ_FRAMEBUFFER_ANGLE. michael@0: michael@0: While a framebuffer object is bound, GL operations on the target michael@0: to which it is bound affect the images attached to the bound michael@0: framebuffer object, and queries of the target to which it is bound michael@0: return state from the bound object. Queries of the values michael@0: specified in table 6.20 (Implementation Dependent Pixel Depths) michael@0: and table 6.yy (Framebuffer Dependent Values) are michael@0: derived from the framebuffer object bound to DRAW_FRAMEBUFFER_ANGLE. michael@0: michael@0: The initial state of DRAW_FRAMEBUFFER_ANGLE and READ_FRAMEBUFFER_ANGLE michael@0: refers to the default framebuffer provided by the windowing michael@0: system. In order that access to the default framebuffer is not michael@0: lost, it is treated as a framebuffer object with the name of 0. michael@0: The default framebuffer is therefore rendered to and read from michael@0: while 0 is bound to the corresponding targets. On some michael@0: implementations, the properties of the default framebuffer can michael@0: change over time (e.g., in response to windowing system events michael@0: such as attaching the context to a new windowing system drawable.)" michael@0: michael@0: Change the description of DeleteFramebuffers as follows: michael@0: michael@0: " contains names of framebuffer objects to be michael@0: deleted. After a framebuffer object is deleted, it has no michael@0: attachments, and its name is again unused. If a framebuffer that michael@0: is currently bound to one or more of the targets michael@0: DRAW_FRAMEBUFFER_ANGLE or READ_FRAMEBUFFER_ANGLE is deleted, it is as michael@0: though BindFramebuffer had been executed with the corresponding michael@0: and zero. Unused names in michael@0: are silently ignored, as is the value zero." michael@0: michael@0: michael@0: In section 4.4.3 (Renderbuffer Objects), modify the first two sentences michael@0: of the description of FramebufferRenderbuffer as follows: michael@0: michael@0: " must be DRAW_FRAMEBUFFER_ANGLE, READ_FRAMEBUFFER_ANGLE, or michael@0: FRAMEBUFFER. If is FRAMEBUFFER, it behaves as michael@0: though DRAW_FRAMEBUFFER_ANGLE was specified. The INVALID_OPERATION michael@0: error is generated if the value of the corresponding binding is zero." michael@0: michael@0: In section 4.4.3 (Renderbuffer Objects), modify the first two sentences michael@0: of the description of FramebufferTexture2D as follows: michael@0: michael@0: " must be DRAW_FRAMEBUFFER_ANGLE, michael@0: READ_FRAMEBUFFER_ANGLE, or FRAMEBUFFER. If is michael@0: FRAMEBUFFER, it behaves as though DRAW_FRAMEBUFFER_ANGLE was michael@0: specified. The INVALID_OPERATION error is generated if the value of the michael@0: corresponding binding is zero." michael@0: michael@0: In section 4.4.5 (Framebuffer Completeness), modify the first sentence michael@0: of the description of CheckFramebufferStatus as follows: michael@0: michael@0: "If is not DRAW_FRAMEBUFFER_ANGLE, READ_FRAMEBUFFER_ANGLE or michael@0: FRAMEBUFFER, the error INVALID_ENUM is generated. If is michael@0: FRAMEBUFFER, it behaves as though DRAW_FRAMEBUFFER_ANGLE was michael@0: specified." michael@0: michael@0: Modify the first sentence of the subsection titled "Effects of Framebuffer michael@0: Completeness on Framebuffer Operations" to be: michael@0: michael@0: "Attempting to render to or read from a framebuffer which is not michael@0: framebuffer complete will generate an michael@0: INVALID_FRAMEBUFFER_OPERATION error." michael@0: michael@0: michael@0: michael@0: Additions to Chapter 6 of the OpenGL 1.5 Specification (State and State michael@0: Requests) michael@0: michael@0: In section 6.1.3, modify the first sentence of the description of michael@0: GetFramebufferAttachmentParameteriv as follows: michael@0: michael@0: " must be DRAW_FRAMEBUFFER_ANGLE, READ_FRAMEBUFFER_ANGLE or michael@0: FRAMEBUFFER. If is FRAMEBUFFER, it behaves as michael@0: though DRAW_FRAMEBUFFER_ANGLE was specified." michael@0: michael@0: Modify the title of Table 6.23 (Framebuffer State) to be "Framebuffer michael@0: (state per attachment point)". michael@0: michael@0: michael@0: Dependencies on OES_texture_3D michael@0: michael@0: On an OpenGL ES implementation, in the absense of OES_texture_3D, michael@0: omit references to FramebufferTexture3DOES and CopyTexSubImage3DOES. michael@0: michael@0: Errors michael@0: michael@0: The error INVALID_FRAMEBUFFER_OPERATION is generated if michael@0: BlitFramebufferANGLE is called while the michael@0: draw framebuffer is not framebuffer complete. michael@0: michael@0: The error INVALID_FRAMEBUFFER_OPERATION is generated if michael@0: BlitFramebufferANGLE, ReadPixels, CopyTex{Sub}Image*, is called while the michael@0: read framebuffer is not framebuffer complete. michael@0: michael@0: The error INVALID_OPERATION is generated if GetIntegerv is called michael@0: while the read framebuffer is not framebuffer complete, or if there michael@0: is no color attachment present on the read framebuffer object. michael@0: michael@0: The error INVALID_VALUE is generated by BlitFramebufferANGLE if michael@0: has any bits set other than those named by michael@0: COLOR_BUFFER_BIT, DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT. michael@0: michael@0: The error INVALID_OPERATION is generated if BlitFramebufferANGLE is michael@0: called and includes DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT michael@0: and the source and destination depth or stencil buffer formats do michael@0: not match. michael@0: michael@0: The error INVALID_OPERATION is generated if BlitFramebufferANGLE is michael@0: called and any of the following conditions are true: michael@0: - the source and destination rectangle dimensions do not match michael@0: (ie scaling or flipping is required). michael@0: - includes COLOR_BUFFER_BIT and the source and destination michael@0: buffer formats do not match. michael@0: - includes DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT and the michael@0: source or destination rectangles do not specify the entire source michael@0: or destination buffer (after applying any scissor region). michael@0: michael@0: The error INVALID_ENUM is generated by BlitFramebufferANGLE if michael@0: is not NEAREST. michael@0: michael@0: The error INVALID_ENUM is generated if BindFramebuffer, michael@0: CheckFramebufferStatus, FramebufferTexture{2D|3DOES}, michael@0: FramebufferRenderbuffer, or michael@0: GetFramebufferAttachmentParameteriv is called and is michael@0: not DRAW_FRAMEBUFFER_ANGLE, READ_FRAMEBUFFER_ANGLE or FRAMEBUFFER. michael@0: michael@0: New State michael@0: michael@0: (Add a new table 6.xx, "Framebuffer (state per framebuffer target binding point)") michael@0: michael@0: Get Value Type Get Command Initial Value Description Section michael@0: ------------------------------ ---- ----------- -------------- ------------------- ------------ michael@0: DRAW_FRAMEBUFFER_BINDING_ANGLE Z+ GetIntegerv 0 framebuffer object bound 4.4.1 michael@0: to DRAW_FRAMEBUFFER_ANGLE michael@0: READ_FRAMEBUFFER_BINDING_ANGLE Z+ GetIntegerv 0 framebuffer object 4.4.1 michael@0: to READ_FRAMEBUFFER_ANGLE michael@0: michael@0: Remove reference to FRAMEBUFFER_BINDING from Table 6.23. michael@0: michael@0: (Add a new table 6.yy, "Framebuffer Dependent Values") michael@0: michael@0: Get Value Type Get Command Initial Value Description Section michael@0: ---------------------------- ---- ----------- -------------- ------------------- ------------ michael@0: SAMPLE_BUFFERS Z+ GetIntegerv 0 Number of multisample 3.2 michael@0: buffers michael@0: SAMPLES Z+ GetIntegerv 0 Coverage mask size 3.2 michael@0: michael@0: Remove the references to SAMPLE_BUFFERS and SAMPLES from Table 6.17. michael@0: michael@0: michael@0: Issues michael@0: michael@0: 1) What should we call this extension? michael@0: michael@0: Resolved: ANGLE_framebuffer_blit. michael@0: michael@0: This extension is a result of a collaboration between Google and michael@0: TransGaming for the open-source ANGLE project. Typically one would michael@0: label a multi-vendor extension as EXT, but EXT_framebuffer_blit michael@0: is already the name for this on Desktop GL. Additionally this michael@0: isn't truely a multi-vendor extension because there is only one michael@0: implementation of this. We'll follow the example of the open-source michael@0: MESA project which uses the project name for the vendor suffix. michael@0: michael@0: 2) Why is this done as a separate extension instead of just supporting michael@0: EXT_framebuffer_blit? michael@0: michael@0: To date, EXT_framebuffer_blit has not had interactions with OpenGL ES michael@0: specified and, as far as we know, it has not previously been exposed on michael@0: an ES 1.1 or ES 2.0 implementation. Because there are enough michael@0: differences between Desktop GL and OpenGL ES, and since OpenGL ES 2.0 michael@0: has already subsumed the EXT_framebuffer_object functionality (with michael@0: some changes) it was deemed a worthwhile exercise to fully specify the michael@0: interactions. Additionally, some of the choices in exactly which michael@0: functionality is supported by BlitFramebufferANGLE is dictated by michael@0: what is reasonable to support on a implementation which is michael@0: layered on Direct3D9. It is not expected that other implementations michael@0: will necessary have the same set of restrictions or requirements. michael@0: michael@0: 3) How does this extension differ from EXT_framebuffer_blit? michael@0: michael@0: This extension is designed to be a pure subset of the michael@0: EXT_framebuffer_blit functionality as applicable to OpenGL ES 2.0. michael@0: michael@0: Functionality that is unchanged: michael@0: - the split DRAW and READ framebuffer attachment points and related sematics. michael@0: - the token values for the DRAW/READ_FRAMEBUFFER and DRAW/READ_FRAMBUFFER_BINDING michael@0: - the signature of the BlitFramebuffer entry-point. michael@0: michael@0: Additional restrictions imposed by BlitFramebufferANGLE: michael@0: - no color conversions are supported michael@0: - no scaling, stretching or flipping are supported michael@0: - no filtering is supported (a consequence of no stretching) michael@0: - only whole depth and/or stencil buffers can be copied michael@0: michael@0: Revision History michael@0: michael@0: Revision 1, 2010/07/06 michael@0: - copied from revision 15 of EXT_framebuffer_object michael@0: - removed language that was clearly not relevant to ES2 michael@0: - rebased changes against the OpenGL ES 2.0 specification michael@0: - added ANGLE-specific restrictions michael@0: Revision 2, 2010/07/15 michael@0: - clarifications of implicit clamping to buffer sizes (from ARB_fbo) michael@0: - clarify that D/S restricts apply after the scissor is applied michael@0: - improve some error language michael@0: Revision 3, 2010/08/06 michael@0: - add additional contributors, update implementation status michael@0: Revision 4, 2012/09/22 michael@0: - document errors for GetIntegerv. michael@0: