| Name |
| |
| ANGLE_multiview |
| |
| Name Strings |
| |
| GL_ANGLE_multiview |
| |
| Contributors |
| |
| Martin Radev, NVIDIA Corporation |
| Olli Etuaho, NVIDIA Corporation |
| Corentin Wallez, Google |
| Geoff Lang, Google |
| Jamie Madill, Google |
| |
| Contact |
| |
| Olli Etuaho (oetuaho 'at' nvidia.com) |
| |
| Status |
| |
| Incomplete |
| |
| Version |
| |
| Last Modified Date: December 8, 2018 |
| Author Revision: 1 |
| |
| Number |
| |
| OpenGL ES Extension XX |
| |
| Dependencies |
| |
| OpenGL ES 3.0 is required. |
| |
| Overview |
| |
| Multi-view rendering, achieved through the functionality exposed by |
| ANGLE, expects the user to issue for each view almost the same |
| drawing commands and state changes sequentially. This rendering |
| method scales with the number of views and can be detrimental for |
| performance in scenes with many draw calls. |
| |
| This extension addresses the issue by adding means for multi-view |
| side-by-side rendering onto a single 2D texture and layered |
| rendering onto the many layers of a 2D texture array. The new vertex |
| and fragment shader built-in - ViewID_OVR - is added which signifies |
| the view for which the current vertex or fragment is being |
| processed, so that per-view transformations can be applied. |
| |
| IP Status |
| |
| No known IP claims. |
| |
| New Tokens |
| |
| Accepted by the <pname> parameter of GetFramebufferAttachmentParameteriv: |
| |
| FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE 0x9630 |
| FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE 0x969B |
| FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE 0x9632 |
| FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE 0x969C |
| |
| Returned in <params> by GetFramebufferAttachmentParameteriv: |
| |
| FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE 0x969D |
| FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE 0x969E |
| |
| Accepted by the <pname> parameter of GetIntegerv: |
| |
| MAX_VIEWS_ANGLE 0x9631 |
| |
| Returned by CheckFramebufferStatus: |
| |
| FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_ANGLE 0x9633 |
| |
| New Procedures and Functions |
| |
| void FramebufferTextureMultiviewLayeredANGLE(enum target, |
| enum attachment, |
| uint texture, |
| int level, |
| int baseViewIndex, |
| sizei numViews); |
| void FramebufferTextureMultiviewSideBySideANGLE(enum target, |
| enum attachment, |
| uint texture, |
| int level, |
| sizei numViews, |
| const int *viewportOffsets); |
| |
| Additions to Chapter 2 of the OpenGL ES 3.0 Specification (OpenGL ES Operation) |
| |
| Modify section 2.9.3 Drawing commands, p. 28 |
| |
| Append to the end of the section: |
| |
| " |
| If any drawing command is called the number of views specified in the |
| program must match the number of views in the draw framebuffer. If |
| there is a mismatch, an INVALID_OPERATION error is generated. |
| |
| If the active draw framebuffer has a side-by-side multi-view layout |
| and the scissor test is not enabled, the result of any draw command |
| is undefined, but is not followed by program termination. |
| " |
| |
| Modify section 2.15.2 Transform Feedback Primitive Capture, p. 91 |
| |
| In the list just after "The error INVALID_OPERATION is generated:" |
| do the following: |
| |
| - Add another bullet point: |
| " |
| * by any Draw* command if the number of views in the draw |
| framebuffer is greater than 1 and there is an active and not |
| paused transform feedback object. |
| " |
| |
| Additions to Chapter 3 of the OpenGL ES 3.0 Specification (Rasterization) |
| |
| Modify section 3.8.5 (Alternate Texture Image Specification Commands), |
| p. 145 |
| |
| Add at the end of the section: |
| |
| "Calling CopyTexSubImage3D, CopyTexImage2D, or CopyTexSubImage2D will |
| result in an INVALID_FRAMEBUFFER_OPERATION error if the multi-view |
| layout of the current read framebuffer is |
| FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of views in the |
| current read framebuffer is more than one." |
| |
| Additions to Chapter 4 of the OpenGL ES 3.0 Specification |
| (Per-Fragment Operations and the Framebuffer) |
| |
| Modify section 4.1.6 (Occlusion queries), p. 177 |
| |
| Replace the first sentence with: |
| |
| "Occlusion queries use query objects to track whether any fragments |
| or samples pass the depth test for any of the views." |
| |
| Append to the sentence |
| |
| "While that occlusion query is active, the samples-boolean state is |
| set to TRUE if any fragment or sample passes the depth test" |
| |
| the text |
| |
| " for any of the views." |
| |
| Modify section 4.2.3 (Clearing the Buffers), p. 190 |
| |
| Add a new subsection at the end: |
| |
| "4.2.3.2 Clearing Multi-view Buffers |
| |
| Clearing commands are applied to each view in the current multi-view |
| framebuffer object and have the same constraints as described |
| in section 4.2.3 Clearing the Buffers. |
| |
| If the active draw framebuffer has a side-by-side multi-view layout |
| and the scissor test is not enabled, the clearing command clears |
| the whole content of the specified buffers. |
| " |
| |
| Modify section 4.3.2 (Reading pixels), p. 193 |
| |
| Add to the end of the section: |
| |
| " ReadPixels generates an INVALID_FRAMEBUFFER_OPERATION error if |
| the multi-view layout of the current read framebuffer is |
| FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of views in the |
| current read framebuffer is more than one." |
| |
| Modify section 4.3.3 (Copying pixels), p. 198 |
| |
| After the paragraph |
| |
| "Calling BlitFramebuffer will result in an INVALID_OPERATION error |
| if filter is LINEAR and read buffer contains integer data." |
| |
| add a new paragraph: |
| |
| "Calling BlitFramebuffer will result in an INVALID_FRAMEBUFFER_OPERATION |
| error if the multi-view layout of the current draw framebuffer is not NONE, |
| or the multi-view layout of the current read framebuffer is |
| FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE, or the number of views in the |
| current read framebuffer is more than one." |
| |
| |
| Modify section 4.4.2 (Attaching Images to Framebuffer Objects), p. 202 |
| |
| Add the following bullet point: |
| |
| "* Layers of a two-dimensional array texture which can be used for |
| multi-view rendering." |
| |
| Modify section 4.4.2.4 (Attaching Texture Images to a Framebuffer), p. 207 |
| |
| Add just before the sentence "Effects of Attaching a Texture Image": |
| |
| " |
| The command |
| |
| SelectView( id ); |
| |
| does not exist in the GL, but it is used to describe the multi-view |
| functionality in the rest of this section. The effect of this function |
| is to select the view specified by <id> and set the value to the vertex |
| and fragment shader built-in gl_ViewID_OVR. |
| |
| The command |
| |
| void FramebufferTextureMultiviewLayeredANGLE(enum target, |
| enum attachment, |
| uint texture, |
| int level, |
| int baseViewIndex, |
| sizei numViews); |
| |
| can be used to attach a 2D texture array object as one of the logical |
| buffers of a framebuffer object which is to be used for layered |
| multi-view rendering. |
| |
| basicViewIndex specifies the View-id offset. |
| numViews specifies the number of views associated with the attachment. |
| |
| Any <Draw> command, while a layered multi-view framebuffer is bound, |
| has the same effect as: |
| |
| for( int id = 0; i < numViews; id++ ) { |
| for ( framebufferAttachment : framebuffer.getAllAttachments() ) |
| { |
| attachment = framebufferAttachment.attachment |
| texture = framebufferAttachment.texture |
| level = framebufferAttachment.level |
| baseViewIndex = framebufferAttachment.baseViewIndex |
| FramebufferTextureLayer( target, attachment, texture, level, |
| baseViewIndex + id ); |
| } |
| SelectView( id ); |
| <Draw> |
| } |
| |
| Errors: |
| An INVALID_ENUM error is generated if target is not DRAW_FRAMEBUFFER, |
| READ_FRAMEBUFFER, or FRAMEBUFFER. |
| An INVALID_OPERATION error is generated if attachment is |
| COLOR_ATTACHMENTm where m is greater than or equal to the value |
| of MAX_COLOR_ATTACHMENTS. |
| An INVALID_ENUM error is generated if attachment is not one of |
| the attachments in table 4.6, and attachment is not |
| COLOR_ATTACHMENTm where m is greater than or equal to the value |
| of MAX_COLOR_ATTACHMENTS. |
| An INVALID_OPERATION error is generated if zero is bound to target. |
| An INVALID_VALUE error is generated if texture is not zero, and |
| level is less than zero or greater than log2 of the value of |
| MAX_TEXTURE_SIZE. |
| An INVALID_OPERATION error is generated if texture is not zero, |
| and does not name an existing texture object of type TEXTURE_2D_ARRAY. |
| An INVALID_OPERATION error is generated if texture is not zero, |
| and names a texture with a compressed texture format. |
| An INVALID_VALUE error is generated if texture is not zero, and |
| baseViewIndex+numViews is greater than GL_MAX_ARRAY_TEXTURE_LAYERS. |
| An INVALID_VALUE error is generated if texture is not zero, and |
| numViews is less than 1 or greater than MAX_VIEWS_ANGLE. |
| An INVALID_VALUE error is generated if texture is not zero, and |
| baseViewIndex is less than 0. |
| |
| The command |
| |
| void FramebufferTextureMultiviewSideBySideANGLE(enum target, |
| enum attachment, |
| uint texture, |
| int level, |
| sizei numViews, |
| const int *viewportOffsets); |
| |
| can be used to attach a 2D texture object as one of the logical buffers |
| of a framebuffer object which is to be used for side-by-side multi-view |
| rendering. |
| |
| numViews specifies the number of views associated with the attachment. |
| viewportOffsets specifies the address of an array of integers containing |
| the x and y viewport offset of each view. |
| |
| Any <Draw> command, while a side-by-side multi-view framebuffer is bound, |
| has the same effect as: |
| |
| // Retrieve viewport and scissor state. |
| Rectangle viewport |
| GetIntegerv(VIEWPORT, viewport) |
| Rectangle scissor |
| GetIntegerv(SCISSOR_BOX, scissor) |
| for ( int id = 0; id < numViews; id++ ) |
| { |
| // Setup view state. |
| for ( framebufferAttachment : framebuffer.getAllAttachments() ) |
| { |
| attachment = framebufferAttachment.attachment |
| texture = framebufferAttachment.texture |
| level = framebufferAttachment.level |
| FramebufferTexture2D( target, attachment, TEXTURE_2D, texture, |
| level ) |
| } |
| Viewport(viewport.x + viewportOffsets[id].x, |
| viewport.y + viewportOffsets[id].y, |
| viewport.width, viewport.height) |
| Scissor(scissor.x + viewportOffsets[id].x, |
| scissor.y + viewportOffsets[id].y, |
| scissor.width, scissor.height) |
| SelectView(id) |
| // Draw. |
| <Draw> |
| } |
| // Restore viewport and scissor state. |
| Viewport(viewport.x, viewport.y, viewport.width, viewport.height) |
| Scissor(scissor.x, scissor.y, scissor.width, scissor.height) |
| |
| Errors: |
| An INVALID_ENUM error is generated if target is not DRAW_FRAMEBUFFER, |
| READ_FRAMEBUFFER, or FRAMEBUFFER. |
| An INVALID_OPERATION error is generated if attachment is |
| COLOR_ATTACHMENTm where m is greater than or equal to the value |
| of MAX_COLOR_ATTACHMENTS. |
| An INVALID_ENUM error is generated if attachment is not one of |
| the attachments in table 4.6, and attachment is not |
| COLOR_ATTACHMENTm where m is greater than or equal to the value |
| of MAX_COLOR_ATTACHMENTS. |
| An INVALID_OPERATION error is generated if zero is bound to target. |
| An INVALID_VALUE error is generated if texture is not zero and |
| level is less than zero or greater than log2 of the value of |
| MAX_TEXTURE_SIZE. |
| An INVALID_OPERATION error is generated if texture is not zero, |
| and does not name an existing texture object of type TEXTURE_2D. |
| An INVALID_OPERATION error is generated if texture is not zero, |
| and names a texture with a compressed texture format. |
| An INVALID_VALUE error is generated if texture is not zero, and |
| numViews is less than 1 or greater than MAX_VIEWS_ANGLE. |
| An INVALID_VALUE error is generated if texture is not zero, and |
| any of the first numViews * 2 values in viewportOffsets is negative. |
| |
| Having overlapping scissor rectangles after viewport offsets are |
| applied causes undefined behavior. |
| " |
| |
| Add the following bullet points in the list after |
| "Effects of Attaching a Texture Image": |
| |
| " * The value of FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE is |
| set to <numViews>. |
| * The value of FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE |
| is set to: |
| ** FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE if the texture |
| is attached via a call to |
| FramebufferTextureMultiviewSideBySideANGLE. |
| ** FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE if the texture is |
| attached via a call to FramebufferTextureMultiviewLayeredANGLE. |
| ** NONE otherwise. |
| * The value of FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE |
| is set to <baseViewIndex> if FramebufferTextureMultiviewLayeredANGLE |
| is called. Otherwise, the default value remains. |
| * The value of FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE |
| is set to <viewportOffsets>. |
| " |
| |
| Modify section 4.4.4.1 (Framebuffer Attachment Completeness), p. 213 |
| |
| Add a bullet point to the end of the list: |
| |
| "If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is TEXTURE and |
| the value of FRAMEBUFFER_ATTACHMENT_OBJECT_NAME names a two-dimensional |
| array texture, then the sum of FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE |
| and FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE must be less |
| than the number of layers in the texture." |
| |
| Modify section 4.4.4.2 (Whole Framebuffer Completeness), p. 214 |
| |
| Add a bullet point after "{ FRAMEBUFFER_INCOMPLETE_MULTISAMPLE }": |
| |
| " |
| * All populated framebuffer attachments have the same number of views, |
| same multi-view layout and same viewport offsets. |
| { FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_ANGLE } |
| " |
| |
| Additions to Chapter 5 of the OpenGL ES 3.0 Specification (Special Functions) |
| |
| None |
| |
| Additions to Chapter 6 of the OpenGL ES 3.0 Specification |
| (State and State Requests) |
| |
| Modify section 6.1.13 (Framebuffer Object Queries), p. 242 |
| |
| Add a bullet point to the first list: |
| |
| " * If <pname> is FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE, |
| then <params> will contain the number of views for the specified |
| attachment. |
| * If <pname> is FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE, |
| then <params> will contain the viewport offsets for the specified |
| attachment. It is undefined behavior to provide an array with size |
| less than 2 x <num views>. |
| * If <pname> is FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE, |
| then <params> will contain FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE, |
| FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE or NONE. |
| * If <pname> is FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE, |
| then <params> will contain the base view index offset for the |
| specified attachment." |
| |
| Changes to table 6.14, p. 259 (Framebuffer (state per attachment point)) |
| |
| Get Value Type Get Command Value Description Sec. |
| --------- ----- ----------- ------- ----------- ---- |
| FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE Z+ GetFramebuffer- |
| Attachment- 1 Number of views 4.4.2.4 |
| Parameteriv |
| |
| FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE n x Z^{2} GetFramebuffer- 0,0 Viewport offset 4.4.2.4 |
| Attachment- of each view |
| Parameteriv |
| |
| FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE Z+ GetFramebuffer- NONE Layout type - 4.4.2.4 |
| Attachment- non-multiview, |
| Parameteriv layered or |
| side-by-side |
| |
| FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE Z GetFramebuffer- 0 Base view offset 4.4.2.4 |
| Attachment- |
| Parameteriv |
| |
| Changes to table 6.28, p. 273 (Implementation Dependent Values): |
| |
| Add the following entry after MAX_VIEWPORT_DIMS: |
| |
| Get Value Type Get Command Value Description Sec. |
| --------- ----- ----------- ------- ----------- ---- |
| MAX_VIEWS_ANGLE Z+ GetIntegerv 4 Maximum number of 4.4 |
| views |
| |
| Additions to the OpenGL ES 3.0 Shading Language Specification |
| |
| Including the following line in a shader can be used to control the |
| language features described in this extension: |
| |
| #extension GL_OVR_multiview : <behavior> |
| |
| where <behavior> is as specified in section 3.5. |
| |
| New preprocessor #defines are added to the OpenGL Shading Language: |
| |
| #define GL_OVR_multiview 1 |
| |
| Modify section 4.3.8.1 (Input Layout Qualifiers) |
| |
| Replace the first sentence by: |
| |
| "Input variable declarations in the vertex shader can have input |
| layout qualifiers." |
| |
| Add the following text just before the sentence "Fragment shaders |
| cannot ...": |
| |
| "The number of views to which to the program must render to is |
| specified through the num_views layout qualifier: |
| |
| layout-qualifier-id |
| num_views = integer-constant |
| |
| For example, the following declaration in a vertex shader |
| |
| layout (num_views=4) in; |
| |
| is used to specify that the program renders to 4 views. |
| |
| If num_views is less than 1 or greater than the maximum number of |
| supported views, a compile-time error is generated. |
| If the layout qualifier is declared multiple times and not all |
| declarations specify the same number of views, a compile-time error |
| is generated." |
| |
| Modify section 7.1 (Vertex Shader Special Variables) |
| |
| Add to the list of built-ins just after the entry for gl_InstanceID: |
| |
| " in highp uint gl_ViewID_OVR;" |
| |
| Add a description for gl_ViewID_OVR just after the paragraph for |
| gl_InstanceID: |
| |
| "The variable gl_ViewID_OVR is a vertex shader input variable that |
| holds the view id which designates the view which the current |
| vertex is being processed for." |
| |
| Modify section 7.2 (Fragment Shader Special Variables) |
| |
| Add to the list of built-ins just after the entry for gl_InstanceID: |
| |
| " in highp uint gl_ViewID_OVR;" |
| |
| Add a description for gl_ViewID_OVR just after the paragraph for |
| gl_PointCoord: |
| |
| "The variable gl_ViewID_OVR is a fragment shader input variable that |
| holds the view id which designates the view which the current |
| fragment is being processed for." |
| |
| Additions to Chapter 10 of the OpenGL ES 3.1 Specification |
| (Vertex Specification and Drawing Commands) |
| |
| Modify section 10.5 (Drawing Commands Using Vertex Arrays), p. 254 |
| |
| Append to the list of errors for the command DrawArraysIndirect: |
| |
| "* An INVALID_OPERATION if the number of views in the draw framebuffer |
| is greater than 1." |
| |
| Append to the list of errors for the command DrawElementsIndirect: |
| |
| "* An INVALID_OPERATION if the number of views in the draw framebuffer |
| is greater than 1." |
| |
| Additions to the AGL/EGL/GLX/WGL Specifications |
| |
| None |
| |
| Interactions with EXT_disjoint_timer_query |
| |
| An INVALID_OPERATION error is generated by any Draw* command and the Clear |
| command if there is an active query object for target TIME_ELAPSED_EXT and |
| the number of views in the draw framebuffer is greater than 1. |
| |
| Errors |
| |
| None |
| |
| Issues |