| Name |
| |
| NV_viewport_array2 |
| |
| Name Strings |
| |
| GL_NV_viewport_array2 |
| |
| Contact |
| |
| Jeff Bolz, NVIDIA Corporation (jbolz 'at' nvidia.com) |
| Pat Brown, NVIDIA Corporation (pbrown 'at' nvidia.com) |
| |
| Contributors |
| |
| Pat Brown, NVIDIA |
| Mathias Heyer, NVIDIA |
| |
| Status |
| |
| Shipping |
| |
| Version |
| |
| Last Modified Date: March 27, 2015 |
| Revision: 2 |
| |
| Number |
| |
| OpenGL Extension #476 |
| OpenGL ES Extension #237 |
| |
| Dependencies |
| |
| This extension is written against the OpenGL 4.3 specification |
| (Compatibility Profile). |
| |
| This extension interacts with the OpenGL ES 3.1 (March 17, 2014) |
| specification. |
| |
| If implemented in OpenGL ES, NV_viewport_array, EXT_geometry_shader |
| and EXT_shader_io_blocks are required. |
| |
| This extension interacts with EXT_tessellation_shader. |
| |
| This extension interacts with NV_geometry_shader_passthrough. |
| |
| This extension interacts with NV_gpu_program4. |
| |
| Overview |
| |
| This extension provides new support allowing a single primitive to be |
| broadcast to multiple viewports and/or multiple layers. A shader output |
| gl_ViewportMask[] is provided, allowing a single primitive to be output to |
| multiple viewports simultaneously. Also, a new shader option is provided |
| to control whether the effective viewport index is added into gl_Layer. |
| These capabilities allow a single primitive to be output to multiple |
| layers simultaneously. |
| |
| The gl_ViewportMask[] output is available in vertex, tessellation |
| control, tessellation evaluation, and geometry shaders. gl_ViewportIndex |
| and gl_Layer are also made available in all these shader stages. The |
| actual viewport index or mask and render target layer values are taken |
| from the last active shader stage from this set of stages. |
| |
| This extension is a superset of the GL_AMD_vertex_shader_layer and |
| GL_AMD_vertex_shader_viewport_index extensions, and thus those extension |
| strings are expected to be exported if GL_NV_viewport_array2 is |
| supported. This extension includes the edits for those extensions, recast |
| against the reorganized OpenGL 4.3 specification. |
| |
| New Procedures and Functions |
| |
| None. |
| |
| New Tokens |
| |
| None. |
| |
| Additions to Chapter 11 of the OpenGL 4.3 (Compatibility Profile) Specification |
| (Programmable Vertex Processing) |
| |
| Add to Section 11.1.3.10 (Shader Outputs) |
| |
| The built-in output variables gl_ViewportIndex, gl_ViewportMask[], and |
| gl_Layer hold the viewport index/mask and render target layer, as described |
| in Section 11.4 (Viewport Index and Layer). |
| |
| Add to Section 11.2.1.2.3 (Tessellation Control Shader Outputs) |
| |
| The built-in output variables gl_ViewportIndex, gl_ViewportMask[], and |
| gl_Layer hold the viewport index/mask and render target layer, as described |
| in Section 11.4 (Viewport Index and Layer). |
| |
| Add to Section 11.2.3.4 (Tessellation Evaluation Shader Outputs) |
| |
| The built-in output variables gl_ViewportIndex, gl_ViewportMask[], and |
| gl_Layer hold the viewport index/mask and render target layer, as described |
| in Section 11.4 (Viewport Index and Layer). |
| |
| Modify Section 11.3.4.5 (Geometry Shader Outputs) |
| |
| Replace the paragraph about gl_ViewportIndex: |
| |
| The built-in output variables gl_ViewportIndex, gl_ViewportMask[], and |
| gl_Layer hold the viewport index/mask and render target layer, as described |
| in Section 11.4 (Viewport Index and Layer). |
| |
| Replace Section 11.3.4.6 (Layer and Viewport Selection) with new Section |
| 11.4 (Layer and Viewport Selection) |
| |
| Geometry may be rendered to one of several different layers of cube map |
| textures, three-dimensional textures, or one- or two-dimensional texture |
| arrays. This functionality allows an application to bind an entire complex |
| texture to a framebuffer object, and render primitives to arbitrary layers |
| computed at run time. For example, it can be used render a scene into |
| multiple layers of an array texture in one pass, or to select a particular |
| layer to render to in shader code. The layer to render to is specified by |
| writing to the built-in output variable gl_Layer. Layered rendering |
| requires the use of framebuffer objects (see section 9.8). |
| |
| Shaders may also direct each primitive to zero or more viewports. The |
| destination viewports for a primitive may be selected in the shader by |
| writing to the built-in output variable gl_ViewportIndex (selecting a |
| single viewport) or gl_ViewportMask[] (selecting multiple viewports). |
| This functionality allows a shader to direct its output to different |
| viewports for each primitive, or to draw multiple versions of a primitive |
| into several different viewports. |
| |
| The specific vertex of a primitive used to select the rendering layer or |
| viewport index/mask is implementation-dependent and thus portable |
| applications will assign the same layer and viewport index for all |
| vertices in a primitive. The vertex conventions followed for gl_Layer and |
| gl_ViewportIndex/gl_ViewportMask[] may be determined by calling |
| GetIntegerv with the symbolic constants LAYER_PROVOKING_VERTEX and |
| VIEWPORT_INDEX_PROVOKING_VERTEX, respectively. For either query, if the |
| value returned is PROVOKING_VERTEX, then vertex selection follows the |
| convention specified by ProvokingVertex (see section 13.4). If the value |
| returned is FIRST_VERTEX_CONVENTION, selection is always taken from the |
| first vertex of a primitive. If the value returned is |
| LAST_VERTEX_CONVENTION, the selection is always taken from the last vertex |
| of a primitive. If the value returned is UNDEFINED_VERTEX, the selection |
| is not guaranteed to be taken from any specific vertex in the |
| primitive. The vertex considered the provoking vertex for particular |
| primitive types is given in table 13.2. |
| |
| The layer selection may be made a function of the viewport index, as |
| described in Section 7.1 of the GLSL specification. |
| |
| The viewport index, viewport mask, and layer outputs are available in |
| vertex, tessellation control, tessellation evaluation, and geometry |
| shaders. Only the last active shader stage (in pipeline order) from this |
| list controls the viewport index/mask and layer; outputs in previous |
| shader stages are not used, even if the last stage fails to write one of |
| the outputs. |
| |
| |
| Additions to Chapter 13 of the OpenGL 4.3 (Compatibility Profile) Specification |
| (Fixed-Function Vertex Post-Processing) |
| |
| Modify Section 13.2 (Transform Feedback), p. 453 |
| |
| Modify the first paragraph: |
| |
| ...The vertices are fed back after vertex color clamping, but before |
| viewport mask expansion, flatshading, and clipping. ... |
| |
| |
| Modify Section 13.6.1 (Controlling the Viewport) |
| |
| Multiple viewports are available and are numbered zero through the value |
| of MAX_VIEWPORTS minus one. If last active vertex, tessellation, or |
| geometry shader writes to gl_ViewportIndex, the primitive is emitted to |
| the viewport corresponding to the value assigned to gl_ViewportIndex, as |
| taken from an implementation-dependent provoking vertex. The primitive is |
| then transformed using the state of the selected viewport. If the value |
| of the viewport index is outside the range zero to the value of |
| MAX_VIEWPORTS minus one, the results of the viewport transformation are |
| undefined. |
| |
| If last active vertex, tessellation, or geometry shader writes to |
| gl_ViewportMask[], the primitive is emitted to zero or more viewports. If |
| bit <i> is set in the mask, the primitive is emitted to viewport <i> and |
| transformed using the state of viewport <i>. However, each primitive will |
| still be captured by transform feedback and counted by primitive queries |
| only once. If bits of gl_ViewportMask[] greater than or equal to the |
| value of MAX_VIEWPORTS are set, the number of times the primitive is |
| emitted and which viewport transformations are used are undefined. |
| |
| If neither gl_ViewportIndex nor gl_ViewportMask[] are written, the |
| viewport numbered zero is used by the viewport transformation. |
| |
| |
| Modify Section 14.5.2.1 (Line Stipple) |
| |
| (add to the end of the section) |
| |
| When rasterizing line segments that could be sent to multiple viewports |
| via the gl_ViewportMask[] built-in geometry shader output (section |
| 13.6.1), the line stipple pattern is not guaranteed to be continuous if |
| segments are sent to multiple viewports. If a line segment is not an |
| independent line segment and is not the first in a series of connected |
| segments (where the stipple counter <s> is reset to 0), the initial value |
| of <s> for the segment is undefined unless that line segment and all |
| previous segments in the series were sent to the same single viewport. |
| |
| New Implementation Dependent State |
| |
| None. |
| |
| New State |
| |
| None. |
| |
| Additions to the AGL/GLX/WGL Specifications |
| |
| None. |
| |
| GLX Protocol |
| |
| None. |
| |
| Modifications to the OpenGL Shading Language Specification, Version 4.30 |
| |
| Including the following line in a shader can be used to control the |
| language features described in this extension: |
| |
| #extension GL_NV_viewport_array2 : <behavior> |
| |
| where <behavior> is as specified in section 3.3. |
| |
| New preprocessor #defines are added to the OpenGL Shading Language: |
| |
| #define GL_NV_viewport_array2 1 |
| |
| Modify Section 7.1 (Built-In Language Variables), p. 116 |
| |
| Add to the list of vertex shader built-ins: |
| |
| out gl_PerVertex { |
| highp int gl_ViewportIndex; |
| highp int gl_ViewportMask[]; |
| highp int gl_Layer; |
| }; |
| |
| Add to the list of geometry shader built-ins: |
| |
| out highp int gl_ViewportMask[]; |
| |
| Add to the list of tessellation control shader built-ins: |
| |
| out gl_PerVertex { |
| highp int gl_ViewportIndex; |
| highp int gl_ViewportMask[]; |
| highp int gl_Layer; |
| } gl_out[]; |
| |
| Add to the list of tessellation evaluation shader built-ins: |
| |
| out gl_PerVertex { |
| highp int gl_ViewportIndex; |
| highp int gl_ViewportMask[]; |
| highp int gl_Layer; |
| }; |
| |
| Modify descriptions of gl_Layer and gl_ViewportIndex as follows: |
| |
| The variable gl_Layer is available as an output variable in the vertex, |
| tessellation, and geometry (VTG) languages and an input variable in the |
| fragment language. In the VTG languages, it is used to select a specific |
| layer (or face and layer of a cube map) of a multi-layer framebuffer |
| attachment. The actual layer used will come from one of the vertices in |
| the primitive being shaded. Which vertex the layer comes from is undefined, |
| so it is best to write the same layer value for all vertices of a |
| primitive. If a shader statically assigns a value to gl_Layer, layered |
| rendering mode is enabled. See section 11.4 "Layer and Viewport Selection" |
| and section 9.4.9 "Layered Framebuffers" of the OpenGL Graphics System |
| Specification for more information. If a shader statically assigns a value |
| to gl_Layer, and there is an execution path through the shader that does |
| not set gl_Layer, then the value of gl_Layer is undefined for executions |
| of the shader that take that path. |
| |
| ... |
| |
| The input variable gl_Layer in the fragment language will have the same |
| value that was written to the output variable gl_Layer in the VTG |
| languages. If the final VTG stage does not dynamically assign a value to |
| gl_Layer, the value of gl_Layer in the fragment stage will be undefined. |
| If the final VTG stage makes no static assignment to gl_Layer, the input |
| gl_Value in the fragment stage will be zero. Otherwise, the fragment stage |
| will read the same value written by the final VTG stage, even if that value |
| is out of range. If a fragment shader contains a static access to gl_Layer, |
| it will count against the implementation defined limit for the maximum |
| number of inputs to the fragment stage. |
| |
| The variable gl_ViewportIndex is available as an output variable in the |
| VTG languages and an input variable in the fragment language. In the |
| geometry language, it provides the index of the viewport to which the next |
| primitive emitted from the geometry shader should be drawn. In the vertex |
| and tessellation languages, it provides the index of the viewport |
| associated with the vertex being shaded. Primitives will undergo viewport |
| transformation and scissor testing using the viewport transformation and |
| scissor rectangle selected by the value of gl_ViewportIndex. The viewport |
| index used will come from one of the vertices in the primitive being |
| shaded. However, which vertex the viewport index comes from is |
| implementation-dependent, so it is best to use the same viewport index for |
| all vertices of the primitive. If the final VTG stage does not assign a |
| value to gl_ViewportIndex or gl_ViewportMask[], viewport transform and |
| scissor rectangle zero will be used. If a shader statically assigns a value |
| to gl_ViewportIndex and there is a path through the shader that does not |
| assign a value to gl_ViewportIndex, the value of gl_ViewportIndex is |
| undefined for executions of the shader that take that path. See section |
| 11.4 "Layer and Viewport Selection" of the OpenGL Graphics System |
| Specification for more information. |
| |
| The input variable gl_ViewportIndex in the fragment stage will have the |
| same value that was written to the output variable gl_ViewportIndex in the |
| final VTG stage. If the final VTG stage does not dynamically assign to |
| gl_ViewportIndex, the value of gl_ViewportIndex in the fragment shader will |
| be undefined. If the final VTG stage makes no static assignment to |
| gl_ViewportIndex, the fragment stage will read zero. Otherwise, the |
| fragment stage will read the same value written by the final VTG stage, |
| even if that value is out of range. If a fragment shader contains a static |
| access to gl_ViewportIndex, it will count against the implementation |
| defined limit for the maximum number of inputs to the fragment stage. |
| |
| The variable gl_ViewportMask[] is available as an output variable in the |
| VTG languages. The array has ceil(v/32) elements where v is the maximum |
| number of viewports supported by the implementation. When a shader writes |
| this variable, bit B of element M controls whether the primitive is |
| emitted to viewport 32*M+B. If gl_ViewportIndex is written by the final |
| VTG stage, then gl_ViewportIndex in the fragment stage will have the same |
| value. If gl_ViewportMask[] is written by the final VTG stage, then |
| gl_ViewportIndex in the fragment stage will have the index of the viewport |
| that was used in generating that fragment. |
| |
| If a shader statically assigns a value to gl_ViewportIndex, it may not |
| assign a value to any element of gl_ViewportMask[]. If a shader |
| statically writes a value to any element of gl_ViewportMask[], it may |
| not assign a value to gl_ViewportIndex. That is, a shader may assign |
| values to either gl_ViewportIndex or gl_ViewportMask[], but not |
| both. Multiple shaders linked together must also consistently write just |
| one of these variables. These incorrect usages all generate compile-time |
| or link-time errors. |
| |
| The shader output gl_Layer may be redeclared with a layout qualifer |
| <viewport_relative> as follows: |
| |
| layout (viewport_relative) out highp int gl_Layer; |
| |
| If gl_Layer is <viewport_relative>, then the viewport index is added to |
| the layer used for rendering (and available in the fragment shader). If |
| the shader writes gl_ViewportMask[], then gl_Layer has a different value |
| for each viewport the primitive is rendered to. If gl_Layer is |
| <viewport_relative> and the shader writes neither gl_ViewportIndex nor |
| gl_ViewportMask[], a link-error will result. |
| |
| Modify Section 8.15 (Geometry Shader Functions) |
| |
| The function EmitStreamVertex() specifies that a vertex is completed. A |
| vertex is added to the current output primitive in vertex stream <stream> |
| using the current values of all output variables associated with <stream>. |
| These include gl_PointSize, gl_ClipDistance, gl_Layer, gl_Position, |
| gl_PrimitiveID, gl_ViewportIndex, and gl_ViewportMask[]. The values of |
| all output variables for all output streams are undefined after a call to |
| EmitStreamVertex(). |
| |
| Errors |
| |
| None. |
| |
| Interactions with OpenGL ES 3.1 |
| |
| Unless functionality similar to ARB_provoking_vertex is supported, remove |
| references to PROVOKING_VERTEX and ProvokingVertex(). Also remove |
| reference to 'vertex color clamping'. The modifications to Line Stippling |
| don't apply. |
| |
| Interactions with EXT_tessellation_shader |
| |
| If implemented on OpenGL ES and EXT_tessellation_shader is not supported, |
| remove all language referring to the tesselation control and tessellation |
| evaluation pipeline stages. |
| |
| Interactions with NV_geometry_shader_passthrough |
| |
| If NV_geometry_shader_passthrough is supported, the NV_gpu_program4 and |
| NV_geometry_program4 language describing the PASSTHROUGH declaration |
| statement should be modified to state that "result.viewportmask" may not |
| be used in such a declaration. |
| |
| Interactions with NV_gpu_program4 |
| |
| If NV_gpu_program4 is supported and the "NV_viewport_array2" program |
| option is specified, vertex, tessellation control/evaluation, and geometry |
| program result variable "result.viewportmask" can be used to specify the |
| mask of viewports that the primitive will be emitted to, "result.viewport" |
| can be used to specify the index of the viewport that the primitive will |
| be emitted to, and "result.layer" can be used to specify the layer of a |
| layered framebuffer attachment that the primitive will be emitted to. |
| |
| (add the following rule to the NV_gpu_program4 grammar) |
| |
| <resultBasic> ::= ... |
| | <resPrefix> "viewportmask" arrayMemAbs |
| | <resPrefix> "viewport" |
| | <resPrefix> "layer" |
| |
| (add the following to the tables of Vertex, Geometry, and Tessellation |
| Control/Eval Program Result Variable Bindings) |
| |
| Binding Components Description |
| ----------------------------- ---------- ---------------------------- |
| result.viewportmask[] (v,*,*,*) viewport array mask |
| result.viewport (v,*,*,*) viewport array index |
| result.layer (l,*,*,*) layer for cube/array/3D FBOs |
| |
| (add the following to Section 2.X.2, Program Grammar) |
| |
| If a result variable binding matches "result.viewportmask", updates to the |
| "x" component of the result variable provide a single integer that serves |
| as a mask of viewport indices. The mask must be written as an integer |
| value; writing a floating-point value will produce undefined results. |
| If the value has bits greater than or equal to MAX_VIEWPORTS set, the |
| number of viewports the primitive is emitted to and which viewports are |
| used are undefined. If the "NV_viewport_array2" program option is not |
| specified, the "result.viewportmask" binding is unavailable. |
| |
| If both "result.viewport" and "result.viewportmask" are written, |
| compilation will fail. |
| |
| (add the following to Section 2.X.6.Y, Program Options) |
| |
| + Viewport Mask (NV_viewport_array2) |
| |
| If a vertex, geometry, tessellation control, or tessellation evaluation |
| program specifies the "NV_viewport_array2" option, the result binding |
| "result.viewportmask" will be available to specify the mask of viewports |
| to use for primitive viewport transformations and scissoring as described |
| in section 2.X.2. Additionally, the "result.viewport" and "result.layer" |
| result bindings will be available in these same shader stages. |
| |
| If a program specifies the "NV_layer_viewport_relative" option, the |
| result.layer will have the viewport index automatically added to it. If |
| the result.viewportmask is used, the result.layer will be different for |
| each viewport the primitive is emitted to. |
| |
| Issues |
| |
| (1) Where does the viewport mask broadcast occur? |
| |
| RESOLVED: This operation could potentially be performed before or after |
| transform feedback, but feeding back several viewports worth of primitives |
| doesn't seem particularly useful. This specification applies the viewport |
| mask after transform feedback, and makes primitive queries only count each |
| primitive once. |
| |
| Note that it is possible to capture viewport mask shader outputs when |
| transform feedback is active. |
| |
| (2) How does the gl_ViewportIndex fragment input behave? |
| |
| RESOLVED: Whether viewport mask or viewport indices are used in VTG |
| shaders, the fragment shader input gl_ViewportIndex will contain the |
| viewport number for the primitive generating each fragment. If the |
| viewport mask is used to broadcast a single primitive to multiple |
| viewports, and the same pixel is covered by the primitive in each |
| viewport, multiple fragment shader invocations for that pixel will be |
| generated, each with a different value of gl_ViewportIndex. |
| |
| This extension provides no gl_ViewportMask[] input, so a fragment shader |
| is not able to see the original viewport mask for the primitive generating |
| the fragment. If necessary, this value could be passed by a separate |
| shader variable qualified with "flat". |
| |
| (3) How does the viewport mask interact with line stipple? |
| |
| RESOLVED: With viewport mask, it's possible to broadcast line strips to |
| multiple viewports. If line stipple is enabled in the OpenGL |
| compatibility profile, implementations are required to maintain a |
| continuous stipple pattern across the strip. When primitives are |
| broadcast via viewport mask, implementations will not always be able to |
| buffer an entire strip and send it to each viewport in turn. So it will |
| often be necessary to break up a long strip, and send segments to |
| alternating viewports. An implementation could handle this by breaking up |
| the strip and keeping N independent stipple counters, but that seems like |
| overkill. |
| |
| We relax normal spec requirements and require a continuous stipple pattern |
| only if the entire strip if sent to exactly one viewport. If any segment |
| in the strip is sent to multiple viewports, no viewports, or a different |
| viewport than previous segments, the stipple counter for that segment and |
| subsequent segments in the strip is undefined. |
| |
| (4) Can a viewport index or mask written by vertex or tessellation shader |
| be read by downstream tessellation or geometry shaders? |
| |
| RESOLVED: No. The fragment shader is able to read the viewport index, but |
| this extension provides no built-in input allowing VTG shaders to see a |
| viewport index or mask written by a previous shader stage. |
| |
| (5) Can this extension be used to "kill" primitives in a passthrough |
| geometry shader (NV_geometry_shader_passthrough)? |
| |
| RESOLVED: Yes. In regular geometry shaders, input primitives can be |
| killed by returning without emitting any vertices. That's not possible |
| with passthrough geometry shaders, however it is possible to code a |
| passthrough geometry shader like: |
| |
| void main() |
| { |
| if (shouldKillPrimitive()) { |
| // Set the viewport mask to zero. A primitive will still be |
| // emitted from the geometry shader stage, however it will be sent |
| // to no viewports and thus be discarded. Any other per-primitive |
| // outputs will be undefined. |
| gl_ViewportMask[0] = 0; |
| return; |
| } |
| |
| // Since the shader writes the viewport mask in the "kill" path, it |
| // also needs to write it in the non-"kill" path; otherwise, its |
| // value would be undefined and the primitive will be sent to an |
| // undefined set of viewports. Setting the mask to 1 will always |
| // send a primitive to viewport zero. |
| gl_ViewportMask[0] = 1; |
| |
| ... |
| } |
| |
| Without the viewport mask or a similar feature, it is not possible to kill |
| primitives in a passthrough geometry shader. |
| |
| Revision History |
| |
| Revision 2, 2015/03/27 |
| - Add ES interactions |
| |
| Revision 1 |
| - Internal revisions. |