• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Name
2
3    ARB_viewport_array
4
5Name Strings
6
7    GL_ARB_viewport_array
8
9Contributors
10
11    Graham Sellers, AMD
12    Mark Young, AMD
13    Nick Haemel, AMD
14    Bill Licea-Kane, AMD
15    Jeff Bolz, NVIDIA
16    Daniel Koch, TransGaming
17    Pat Brown, NVIDIA
18    Bruce Merry, ARM
19    Ian Stewart, NVIDIA
20
21Contact
22
23    Graham Sellers, AMD (graham.sellers 'at' amd.com)
24
25Notice
26
27    Copyright (c) 2010-2013 The Khronos Group Inc. Copyright terms at
28        http://www.khronos.org/registry/speccopyright.html
29
30Specification Update Policy
31
32    Khronos-approved extension specifications are updated in response to
33    issues and bugs prioritized by the Khronos OpenGL Working Group. For
34    extensions which have been promoted to a core Specification, fixes will
35    first appear in the latest version of that core Specification, and will
36    eventually be backported to the extension document. This policy is
37    described in more detail at
38        https://www.khronos.org/registry/OpenGL/docs/update_policy.php
39
40Status
41
42    Complete. Approved by the ARB on June 9, 2010.
43    Approved by the Khronos Board of Promoters on July 23, 2010.
44
45Version
46
47    Last Modified Date:         06/25/2012
48    Author Revision:            18
49
50Number
51
52    ARB Extension #100
53
54Dependencies
55
56    OpenGL 1.0 is required.
57
58    OpenGL 3.2 or the EXT_geometry_shader4 or ARB_geometry_shader4 extensions
59    are required.
60
61    This extension is written against the OpenGL 3.2 (Compatibility)
62    Specification.
63
64    This extension is written against the OpenGL Shading Language Specification
65    version 1.50.09.
66
67Overview
68
69    OpenGL is modeled on a pipeline of operations. The final stage in this
70    pipeline before rasterization is the viewport transformation. This stage
71    transforms vertices from view space into window coordinates and allows the
72    application to specify a rectangular region of screen space into which
73    OpenGL should draw primitives. Unextended OpenGL implementations provide a
74    single viewport per context. In order to draw primitives into multiple
75    viewports, the OpenGL viewport may be changed between several draw calls.
76    With the advent of Geometry Shaders, it has become possible for an
77    application to amplify geometry and produce multiple output primitives
78    for each primitive input to the Geometry Shader. It is possible to direct
79    these primitives to render into a selected render target. However, all
80    render targets share the same, global OpenGL viewport.
81
82    This extension enhances OpenGL by providing a mechanism to expose multiple
83    viewports. Each viewport is specified as a rectangle. The destination
84    viewport may be selected per-primitive by the geometry shader. This allows
85    the Geometry Shader to produce different versions of primitives destined
86    for separate viewport rectangles on the same surface. Additionally, when
87    combined with multiple framebuffer attachments, it allows a different
88    viewport rectangle to be selected for each. This extension also exposes a
89    separate scissor rectangle for each viewport. Finally, the viewport bounds
90    are now floating point quantities allowing fractional pixel offsets to be
91    applied during the viewport transform.
92
93IP Status
94
95    No known IP claims.
96
97New Procedures and Functions
98
99    void ViewportArrayv(uint first, sizei count, const float * v);
100    void ViewportIndexedf(uint index, float x, float y, float w, float h);
101    void ViewportIndexedfv(uint index, const float * v);
102    void ScissorArrayv(uint first, sizei count, const int * v);
103    void ScissorIndexed(uint index, int left, int bottom, sizei width, sizei height);
104    void ScissorIndexedv(uint index, const int * v);
105    void DepthRangeArrayv(uint first, sizei count, const clampd * v);
106    void DepthRangeIndexed(uint index, clampd n, clampd f);
107    void GetFloati_v(enum target, uint index, float *data);
108    void GetDoublei_v(enum target, uint index, double *data);
109
110    void GetIntegerIndexedvEXT(enum target, uint index, int * v);
111    void EnableIndexedEXT(enum target, uint index);
112    void DisableIndexedEXT(enum target, uint index);
113    boolean IsEnabledIndexedEXT(enum target, uint index);
114
115    Note that GetIntegerIndexedvEXT, EnableIndexedEXT, DisableIndexedEXT and
116    IsEnabledIndexedEXT are introduced by other OpenGL extensions such as
117    EXT_draw_buffers2. If this extension is implemented against an earlier
118    version of OpenGL that does not support GetIntegeri_v and so on, the
119    'Indexed' versions of these functions may be used in their place.
120
121New Tokens
122
123    Accepted by the <pname> parameter of GetBooleanv, GetIntegerv, GetFloatv,
124    GetDoublev and GetInteger64v:
125
126        MAX_VIEWPORTS                                   0x825B
127        VIEWPORT_SUBPIXEL_BITS                          0x825C
128        VIEWPORT_BOUNDS_RANGE                           0x825D
129        LAYER_PROVOKING_VERTEX                          0x825E
130        VIEWPORT_INDEX_PROVOKING_VERTEX                 0x825F
131
132    Accepted by the <pname> parameter of GetIntegeri_v:
133
134        SCISSOR_BOX                                     0x0C10
135
136    Accepted by the <pname> parameter of GetFloati_v:
137
138        VIEWPORT                                        0x0BA2
139
140    Accepted by the <pname> parameter of GetDoublei_v:
141
142        DEPTH_RANGE                                     0x0B70
143
144    Accepted by the <pname> parameter of Enablei, Disablei, and IsEnabledi:
145
146        SCISSOR_TEST                                    0x0C11
147
148    Returned in the <data> parameter from a Get query with a <pname> of
149    LAYER_PROVOKING_VERTEX or VIEWPORT_INDEX_PROVOKING_VERTEX:
150
151        FIRST_VERTEX_CONVENTION                         0x8E4D
152        LAST_VERTEX_CONVENTION                          0x8E4E
153        PROVOKING_VERTEX                                0x8E4F
154        UNDEFINED_VERTEX                                0x8260
155
156Additions to Chapter 2 of the OpenGL 3.2 (Compatibility) Specification (OpenGL
157Operation)
158
159    Modifications to Section 2.15.4, Geometry Shader Execution Environment
160
161    Add a paragraph after the description of gl_Layer, page 124.
162
163    The built-in special variable gl_ViewportIndex is used to direct
164    rendering to one of several viewports and is discussed in the section
165    entitled "Layer and Viewport Selection", below.
166
167    Rename the the "Layered Rendering" subsection to "Layer and Viewport
168    Selection" and append the following:
169
170    Geometry shaders may also select the destination viewport for each
171    output primitive. The destination viewport for a primitive may be
172    selected in the geometry shader by writing to the built-in output
173    variable gl_ViewportIndex. This functionality allows a geometry
174    shader to direct its output to a different viewport for each
175    primitive, or to draw multiple versions of a primitive into several
176    different viewports.
177
178    The specific vertex of a primitive that is used to select the
179    rendering layer or viewport index is implementation-dependent and
180    thus portable applications will assign the same layer and viewport
181    index for all vertices in a primitive. The vertex conventions
182    followed for gl_Layer and gl_ViewportIndex may be determined by
183    calling GetIntegerv with the symbolic constants
184    LAYER_PROVOKING_VERTEX and VIEWPORT_INDEX_PROVOKING_VERTEX,
185    respectively. For either value, if the value returned is
186    PROVOKING_VERTEX, then vertex selection follows the convention
187    specified by ProvokingVertex (see section 2.21). If the value
188    returned is FIRST_VERTEX_CONVENTION, selection is always taken from
189    the first vertex of a primitive. If the value returned is
190    LAST_VERTEX_CONVENTION, the selection is always taken from the last
191    vertex of a primitive. If the value returned is UNDEFINED_VERTEX,
192    the selection is not guaranteed to be taken from any specific vertex
193    in the primitive. The vertex considered the provoking vertex for
194    particular primitive types is given in Table 2.15.
195
196    Modify section 2.16.1 "Controlling the Viewport", page 126.
197
198    Change the first paragraph of section 2.16.1 to read
199
200    The viewport transformation is determined by the selected viewport's
201    width and height in pixels, p_x and p_y, respectively, and its
202    center (o_x,o_y) (also in pixels) ...
203
204        { leave equations intact }
205
206    Multiple viewports are available and are numbered zero through the
207    value of MAX_VIEWPORTS minus one. If a geometry shader is active and
208    writes to gl_ViewportIndex, the viewport transformation uses the
209    viewport corresponding to the value assigned to gl_ViewportIndex
210    taken from an implementation-dependent primitive vertex. If the
211    value of the viewport index is outside the range zero to the value
212    of MAX_VIEWPORTS minus one, the results of the viewport
213    transformation are undefined. If no geometry shader is active, or if
214    the active geometry shader does not write to gl_ViewportIndex, the
215    viewport numbered zero is used by the viewport transformation.
216
217    A single vertex may be used in more than one individual primitive, in
218    primitives such as TRIANGLE_STRIP.  In this case, the viewport
219    transformation is applied separately for each primitive.
220
221    The factor and offset applied to Z_d for each viewport encoded by n
222    and f are set using
223
224        void DepthRangeArrayv(uint first, sizei count, const clampd * v);
225        void DepthRangeIndexed(uint index, clampd n, clampd f);
226        void DepthRange(clampd n, clampd f);
227
228    DepthRangeArrayv is used to specify the depth range for multiple
229    viewports simultaneously. <first> specifies the index of the first
230    viewport to modify and <count> specifies the number of viewports. If
231    (<first> + <count>) is greater than the value of MAX_VIEWPORTS then
232    an INVALID_VALUE error will be generated. Viewports whose indices
233    lie outside the range [<first>, <first> + <count>) are not modified.
234    The <v> parameter contains the address of an array of clampd types
235    specifying near (n) and far (f) for each viewport in that order.
236
237    DepthRangeIndexed specifies the depth range for a single viewport
238    and is equivalent (assuming no errors are generated) to:
239
240        clampd v[] = { n, f };
241        DepthRangeArrayv(index, 1, v);
242
243    DepthRange sets the depth range for all viewports to the same values
244    and is equivalent (assuming no errors are generated) to:
245
246        for (uint i = 0; i < MAX_VIEWPORTS; i++)
247            DepthRangeIndexed(i, n, f);
248
249    Z_w is represented as either ...
250
251    Replace the end of section 2.16.1, starting from "Viewport transformation
252    parameters are specified using..."
253
254    Viewport transformation parameters are specified using
255
256        void ViewportArrayv(uint first, sizei count, const float * v);
257        void Viewport(int x, int y, sizei w, sizei h);
258        void ViewportIndexedf(uint index, float x, float y, float w, float h);
259        void ViewportIndexedfv(uint index, const float * v);
260
261    ViewportArrayv specifies parameters for multiple viewports
262    simultaneously. <first> specifies the index of the first viewport to
263    modify and <count> specifies the number of viewports. If (<first> +
264    <count>) is greater than the value of MAX_VIEWPORTS then an
265    INVALID_VALUE error will be generated. Viewports whose indices lie
266    outside the range [<first>, <first> + <count>) are not modified.
267    <v> contains the address of an array of floating point values
268    specifying the left (x), bottom (y), width (w) and height (h) of
269    each viewport, in that order. <x> and <y> give the location of the
270    viewport's lower left corner and <w> and <h> give the viewport's
271    width and height, respectively.
272
273    ViewportIndexedf and ViewportIndexedfv specify parameters for a
274    single viewport and are equivalent (assuming no errors are
275    generated) to:
276
277        float v[4] = { x, y, w, h };
278        ViewportArrayv(index, 1, v);
279
280    and
281
282        ViewportArrayv(index, 1, v);
283
284    respectively.
285
286    Viewport sets the parameters for all viewports to the same values
287    and is equivalent (assuming no errors are generated) to:
288
289        for (uint i = 0; i < MAX_VIEWPORTS; i++)
290            ViewportIndexedf(i, 1, (float)x, (float)y, (float)w, (float)h);
291
292    The viewport parameters shown in the above equations are found from these
293    values as
294
295        o_x = x + w /2,
296        o_y = y + h / 2,
297        p_x = w,
298        p  = h.
299
300    The location of the viewport's bottom-left corner, given by (x,y), are
301    clamped to be within the implementation-dependent viewport bounds range.
302    The viewport bounds range [min, max] tuple may be determined by
303    calling GetFloatv with the symbolic constant VIEWPORT_BOUNDS_RANGE
304    (see section 6.1).
305
306    Viewport width and height are clamped to implementation-dependent maximums
307    when specified. The maximum width and height may be found by calling
308    GetFloatv with the symbolic constant MAX_VIEWPORT_DIMS. The maximum
309    viewport dimensions must be greater than or equal to the larger of
310    the visible dimensions of the display being rendered to (if a
311    display exists), and the largest renderbuffer image which can be
312    successfully created and attached to a framebuffer object (see
313    chapter 4). INVALID_VALUE is generated if either w or h is negative.
314
315    The state required to implement the viewport transformations is four
316    floating-point values and two clamped floating-point values for each
317    viewport. In the initial state, w and h for each viewport are set to
318    the width and height, respectively, of the window into which the GL
319    is to do its rendering. If the default framebuffer is bound but no
320    default framebuffer is associated with the GL context (see chapter
321    4), then w and h are initially set to zero. o_x and o_y are set to
322    w/2 and h/2, respectively. n and f are set to 0.0 and 1.0,
323    respectively.
324
325    The precision with which the GL interprets the floating point viewport
326    bounds is implementation-dependent and may be determined by querying the
327    implementation-defined constant VIEWPORT_SUBPIXEL_BITS.
328
329Additions to Chapter 3 of the OpenGL 3.2 (Compatibility) Specification
330(Rasterization)
331
332    None.
333
334Additions to Chapter 4 of the OpenGL 3.2 (Compatibility) Specification (Per-
335Fragment Operations and the Framebuffer)
336
337    Replace section 4.1.2 "Scissor Test", page 284.
338
339    The scissor test determines if (xw, yw) lies within the scissor rectangle
340    defined by four values for each viewport. These values are set with
341
342        void ScissorArrayv(uint first, sizei count, const int * v);
343        void ScissorIndexed(uint index, int left, int bottom, sizei width, sizei height);
344        void ScissorIndexedv(uint index, int * v);
345        void Scissor(int left, int bottom, sizei width, sizei height);
346
347    ScissorArrayv defines a set of scissor rectangles that are each
348    applied to the corresponding viewport (see section 2.16.1
349    "Controlling the Viewport"). <first> specifies the index of the
350    first scissor rectangle to modify, and <count> specifies the number
351    of scissor rectangles. If (<first> + <count>) is greater than the
352    value of MAX_VIEWPORTS, then an INVALID_VALUE error is generated.
353    <v> contains the address of an array of integers containing the
354    left, bottom, width and height of the scissor rectangles, in that
355    order.
356
357    If left <= x_w < left + width and bottom <= y_w < bottom + height
358    for the selected scissor rectangle, then the scissor test passes.
359    Otherwise, the test fails and the fragment is discarded. For points,
360    lines, and polygons, the scissor rectangle for a primitive is
361    selected in the same manner as the viewport (see section 2.16.1).
362    For pixel rectangles and bitmaps, the scissor rectangle numbered
363    zero is used for the scissor test.
364
365    The scissor test is enabled or disabled for all viewports using
366    Enable or Disable with the symbolic constant SCISSOR_TEST. The test
367    is enabled or disabled for a specific viewport using Enablei or
368    Disablei with the constant SCISSOR_TEST and the index of the
369    selected viewport. When disabled, it is as if the scissor test
370    always passes. The value of the scissor test enable for viewport <i>
371    can be queried by calling IsEnabledi with <target> SCISSOR_TEST and
372    <index> <i>. The value of the scissor test enable for viewport zero
373    may also be queried by calling IsEnabled with the same symbolic
374    constant, but no <index> parameter. If either width or height is
375    less than zero for any scissor rectangle, then an INVALID_VALUE
376    error is generated. If the viewport index specified to Enablei,
377    Disablei or IsEnabledi is greater or equal to the value of
378    MAX_VIEWPORTS, then an INVALID_VALUE error is generated.
379
380    The state required consists of four integer values per viewport, and
381    a bit indicating whether the test is enabled or disabled for each
382    viewport. In the initial state, left = bottom = 0, and width and
383    height are determined by the size of the window into which the GL is
384    to do its rendering for all viewports. If the default framebuffer is
385    bound but no default framebuffer is associated with the GL context
386    (see chapter 4), then with and height are initially set to zero.
387    Initially, the scissor test is disabled for all viewports.
388
389    ScissorIndexed and ScissorIndexedv specify the scissor rectangle for
390    a single viewport and are equivalent (assuming no errors are
391    generated) to:
392
393        int v[] = { left, bottom, width, height };
394        ScissorArrayv(index, 1, v);
395
396    and
397
398        ScissorArrayv(index, 1, v);
399
400    respectively.
401
402    Scissor sets the scissor rectangle for all viewports to the same
403    values and is equivalent (assuming no errors are generated) to:
404
405        for (uint i = 0; i < MAX_VIEWPORTS; i++) {
406            ScissorIndexed(i, left, bottom, width, height);
407        }
408
409    Calling Enable or Disable with the symbolic constant SCISSOR_TEST is
410    equivalent, assuming no errors, to:
411
412    for (uint i = 0; i < MAX_VIEWPORTS; i++) {
413        Enablei(SCISSOR_TEST, i);
414        /* or */
415        Disablei(SCISSOR_TEST, i);
416    }
417
418Additions to Chapter 5 of the OpenGL 3.2 (Compatibility) Specification (Special
419Functions)
420
421    None.
422
423Additions to Chapter 6 of the OpenGL 3.2 (Compatibility) Specification (State
424and State Requests)
425
426    Modifications to Section 6.1.1 Simple Queries
427
428        Add to the list of indexed query functions:
429
430        void GetFloati_v(enum target, uint index, float *data);
431        void GetDoublei_v(enum target, uint index, float *data);
432
433Additions to the OpenGL Shading Language Version 1.50.09 Specification
434
435    Add a new Section 3.3.x, GL_ARB_viewport_array Extension (p. 13)
436
437    3.3.x GL_ARB_viewport_array Extension
438
439    To use the GL_ARB_viewport_array extension in a shader it must be
440    enabled using the #extension directive.
441
442    The shading language preprocessor #define GL_ARB_viewport_array will
443    be defined to 1 if the GL_ARB_viewport_array extension is supported.
444
445    Additions to Section 7.1 "Vertex and Geometry Shader Special Variables"
446
447    Add a paragraph after the paragraph describing gl_Layer, starting "The
448    built-in output variable gl_Layer is available only in the geometry
449    language, and provides the number of the layer of textures attached to a
450    FBO to direct rendering to.":
451
452    The built-in output variable gl_ViewportIndex is available only in the
453    geometry language, and provides the index of the viewport to which the
454    next primitive emitted from the geometry shader should be drawn. Primitives
455    generated by the geometry shader will undergo viewport transformation and
456    scissor testing using the viewport transformation and scissor rectangle
457    selected by the value of gl_ViewportIndex. The viewport index used will
458    come from one of the vertices in the primitive being shaded. Which vertex
459    the viewport index comes from is implementation-dependent, so it is best to
460    use the same viewport index for all vertices of the primitive. If a geometry
461    shader does not assign a value to gl_ViewportIndex, viewport transform
462    and scissor rectangle zero will be used. If a geometry shader assigns a
463    value to gl_ViewportIndex and there is a path through the shader that
464    does not set gl_ViewportIndex, then the value of gl_ViewportIndex is
465    undefined for executions of the shader that take that path. See section
466    2.15.4, under "Geometry Shader Outputs" for more information.
467
468    Add to the list of geometry shader built-in variables on p. 69:
469
470        out int gl_ViewportIndex;    // may be written to
471
472    Modify the description of EmitVertex() in Section 8.10, "Geometry Shader
473    Functions", page 104:
474
475    The function EmitVertex() specifies that a vertex is completed. A vertex
476    is added to the current output primitive using the current values of the
477    geometry shader's output variables, including gl_PointSize, gl_ClipDistance,
478    gl_Layer, gl_Position, gl_PrimitiveID and gl_ViewportIndex. The values
479    of all these...
480
481    Add to the list of built in constants available to geometry shaders in
482    Section 7.4:
483
484        const int gl_MaxViewports = 16;
485
486Additions to the AGL/GLX/WGL Specifications
487
488    None.
489
490GLX Protocol
491
492    TBD.
493
494Errors
495
496    INVALID_VALUE is generated by ViewportArrayv if <first> + <count> is
497    greater than or equal to the value of MAX_VIEWPORTS, or if any
498    viewport's width or height is less than 0.
499
500    INVALID_VALUE is generated by ScissorArrayv if <first> + <count> is
501    greater than or equal to the value of MAX_VIEWPORTS, or if any
502    scissor rectangle's width or height is less than zero.
503
504    INVALID_VALUE is generated by DepthRangeArrayv if <first> + <count> is
505    greater than or equal to the vaue of MAX_VIEWPORTS.
506
507    INVALID_VALUE is generated by Enablei, Disablei and IsEnabledi if
508    <index> is greater than or equal to the value of MAX_VIEWPORTS.
509
510New State
511
512    Table 6.13 (p. 405)
513
514    Get Value                 Type             Get Command       Initial Value   Description               Sec    Attribute
515    ------------------------  ---------------- ------------      -------------   ------------------------  -----  ---------
516    VIEWPORT                  16* x 4 x R      GetFloati_v       See 2.11.1      Viewport origin & extent  2.11.1 viewport
517    DEPTH_RANGE               16* x 2 x R[0,1] GetDoublei_v      See 2.16.1      Depth range near & far    2.16.1 viewport
518
519NOTE: The changes are that VIEWPORT and DEPTH_RANGE are extended to
520accommodate 16* copies and now consist of floating-point and
521double-precision values, respectively.
522
523    Table 6.26 (p. 418)
524
525    Get Value                 Type        Get Command           Initial Value   Description               Sec    Attribute
526    ------------------------  ----------  -------------         -------------   -------------------       -----  ---------
527    SCISSOR_TEST              16* x B     IsEnabledi            FALSE           Scissoring enabled        4.1.2  scissor/enable
528    SCISSOR_BOX               16* x 4 x Z GetIntegeri_v         See 4.1.2       Scissor box               4.1.2  scissor
529
530NOTE: The only change is that SCISSOR_TEST and SCISSOR_BOX are extended
531to accommodate 16* copies.
532
533New Implementation Dependent State
534
535    Get Value                        Type   Get Command     Minimum Value   Description                     Sec.
536    ---------                        ----   -----------     -------------   -------------------             -----
537    MAX_VIEWPORT_DIMS (NOTE 1)       2 x Z+ GetFloatv       See 2.16.1      Maximum viewport dimensions     2.16.1
538    MAX_VIEWPORTS                    Z+     GetIntegerv     16              Maximum number of               2.16.1
539                                                                            active viewports
540    VIEWPORT_SUBPIXEL_BITS           Z+     GetIntegerv     0               Number of bits of sub-pixel     2.16.1
541                                                                            precision for viewport bounds
542    VIEWPORT_BOUNDS_RANGE            2 x R  GetFloatv       (NOTE 2)        Viewport bounds range [min,max] 2.16.1
543    LAYER_PROVOKING_VERTEX           Z_4    GetIntegerv     -- (NOTE 3)     vertex convention followed by   2.15.4
544                                                                            the gl_Layer GLSL variable
545    VIEWPORT_INDEX_PROVOKING_VERTEX  Z_4    GetIntegerv     -- (NOTE 3)     vertex convention followed by   2.15.4
546                                                                            the gl_ViewportIndex GLSL
547                                                                            variable
548
549NOTE 1: The recommended get command is changed from GetIntegerv to GetFloatv.
550NOTE 2: range for viewport bounds:
551  * On GL3-capable hardware the VIEWPORT_BOUNDS_RANGE should be at least
552    [-16384, 16383].
553  * On GL4-capable hardware the VIEWPORT_BOUNDS_RANGE should be at least
554    [-32768, 32767].
555NOTE 3: Valid values are: FIRST_VERTEX_CONVENTION,
556LAST_VERTEX_CONVENTION, PROVOKING_VERTEX, UNDEFINED_VERTEX.
557
558Interactions with NV_depth_buffer_float
559
560    If NV_depth_buffer_float is supported, add the following commands:
561
562        void DepthRangeArraydvNV(uint first, sizei count, const double * v);
563        void DepthRangeIndexeddNV(uint index, double n, double f);
564
565    These functions are equivalent to the corresponding DepthRange*
566    functions, except the the parameters are clamped to [0, 1] when using
567    DepthRange*, but not when using DepthRange*dNV.  When <n> and <f> are
568    applied to <z_d>, they are clamped to the range appropriate given the
569    depth buffer's representation.
570
571Interactions with ARB_provoking_vertex, EXT_provoking_vertex, and OpenGL 3.2 or later
572
573    If none of ARB_provoking_vertex, EXT_provoking_vertex or OpenGL 3.2
574    or later are supported, ignore all references to ProvokingVertex and
575    PROVOKING_VERTEX. This extension will continue to require support
576    for the LAYER_PROVOKING_VERTEX and VIEWPORT_INDEX_PROVOKING_VERTEX
577    queries, but only FIRST_VERTEX_CONVENTION, LAST_VERTEX_CONVENTION,
578    or UNDEFINED_VERTEX will be enumerated.
579
580Dependencies on compatibitliy profile contexts
581
582    Pixel rectangle primitives and bitmaps are available only in
583    compatibility profile contexts. In the core profile, references to
584    pixel rectangles and bitmaps are removed from the description of
585    scissor rectangles in section 4.1.2.
586
587Interactions with NV_geometry_program4
588
589    If NV_geometry_program4 is supported and the "ARB_viewport_array" program
590    option is specified, geometry result variable "result.viewport" can be
591    used to specify the viewport array index to use for primitive viewport
592    transformations and scissoring.
593
594    (add the following rule to the NV_geometry_program4 grammar)
595
596    <resultBasic>      ::= ...
597                         | <resPrefix> "viewport"
598
599    (add the following to Table X.3, Geometry Program Result Variable Bindings)
600
601      Binding                        Components  Description
602      -----------------------------  ----------  ----------------------------
603      result.viewport                (v,*,*,*)   viewport array index
604
605    (add the following to Section 2.X.2, Program Grammar)
606
607    If a result variable binding matches "result.viewport", updates to the "x"
608    component of the result variable provide a single integer that serves as a
609    viewport index specifier for viewport arrays. The index must be written as
610    an integer value; writing a floating-point value will produce undefined
611    results. If a value outside the range [0, MAX_VIEWPORTS-1] is given, the
612    behavior is to proceed as if viewport index 0 was selected. If the
613    "ARB_viewport_array" program option is not specified, the "result.viewport"
614    binding is unavailable.
615
616    (add the following to Section 2.X.6.Y, Geometry Program Options)
617
618    + Viewport Array (ARB_viewport_array)
619
620    If a geometry program specifies the "ARB_viewport_array" option, the
621    result binding "result.viewport" will be available to specify the viewport
622    index to use for primitive viewport transformations and scissoring as
623    described in section 2.X.2.
624
625Issues
626
627    1) The name glViewportArray infers dynamic behavior and that the GL
628       may use values that present in the array at draw time. Would it be
629       more consistent to call this glViewportiv or glViewportv?
630
631       UNRESOLVED: For now, we'll leave it as glViewportArray.
632
633    2) Should we provide a mechanism to write gl_ViewportIndex in the vertex
634       shader? This would allow an application to assign gl_ViewportIndex
635       based on the value of a uniform, or from data read through an attribute,
636       for example.
637
638       RESOLVED: No. While it may be possible, there is no compelling use case,
639       and gl_Layer whose precedent we follow here, is not writable in the
640       vertex shader.
641
642    3) Does legacy glViewport update just the first viewport, or all of them?
643
644       RESOLVED: glViewport is equivalent to calling glViewportArray with
645       an array containing a single viewport once for each supported viewport.
646       It therefore defines all viewports in a single call. This is also true
647       for the legacy glScissor, glDepthRange, glEnable and glDisable functions.
648
649    4) When EXT_provoking_vertex is supported, is the provoking vertex convention
650       honored when selecting which vertex the gl_ViewportIndex property is to use?
651
652       RESOLVED: It is desirable that the provoking vertex convention
653       should be honored when selecting the vertex which gl_ViewportIndex is
654       obtained from (and similarly for gl_Layer). Other APIs require that these
655       properties should be taken from the "leading vertex", and this for
656       maximum content portability, it is desireable to be able to configure the
657       pipeline in the same way. However, there exists hardware which would
658       otherwise be able to support these features which does not have the
659       capability to configure which vertex this is selected from (even though
660       it may be doing so in a content-portable way). The
661       LAYER_PROVOKING_VERTEX and VIEWPORT_INDEX_PROVOKING_VERTEX
662       queries have been added to allow applications to determine if the
663       provoking vertex convention is being followed, and if not, which
664       convention is being used (if any). Note that applications which are
665       creating new content are advised that writing the same
666       gl_ViewportIndex and gl_Layer to all the vertices of a primitive is
667       the only portable solution.
668
669    5) Why glViewportIndex rather than glEnablei, and so on?
670
671       DISCUSSION: This extension follows the precedent of extensions such as
672       EXT_draw_buffers2, which introduced glEnableIndexed. These 'indexed'
673       functions since have been promoted to core OpenGL as glEnablei. If
674       this extension is used on an implementation supporting the glEnablei style
675       indexed functions, those may be used instead of, or in conjunction with
676       the glXXXXIndexed style indexed functions.
677
678    6) What happens if the viewport bounds lie on exact half-pixel coordinates?
679       For example, on a multi-sample surface, which samples should be considered
680       'inside' the viewport?
681
682       DISCUSSION: The viewport transformation includes clipping. Assuming this
683       clipping has similar precision to the viewport transform itself, then
684       the resulting clipped primitives should cut through partial pixels,
685       lighting only some of the samples within the pixel.
686
687       FEEDBACK FROM PAT:
688
689This discussion is technically incorrect -- the viewport
690transformation technically does *NOT* include any clipping.  However, for
691geometric primitives, the viewport transformation is applied to vertices
692post-clipping (despite the fact that it precedes clipping in the spec), so
693there is some clipping in the vicinity of the viewport transformation.
694
695"Guardband clipping" is an alternate implementation, producing nearly
696equivalent results to those specified by OpenGL.  When using guardband
697clipping, primitives are not clipped tightly to the view volume in X/Y:
698
699  -w <= x <= w
700  -w <= y <= w
701
702Instead, looser (or no) clipping is applied, for example:
703
704  -8w <= x <= 8w
705  -8w <= y <= 8w
706
707Since primitives are clipped far less aggressively, something has to be done
708to produce results similar to those with aggressive clipping.  To do this,
709such implementations will enable per-pixel scissoring to the viewport
710rectangle.
711
712There are several areas of difference that implementations using guardband
713clipping need to deal with (or ignore):
714
715* line- and point-mode polygons:  The OpenGL spec says that lines should be
716  drawn along the edges of polygons clipped to the frustum.  If you don't clip
717  tightly, you can't draw those edges.  (NOTE:  The behavior specified by
718  OpenGL ends up being somewhat shitty.  Let's say you have a line-mode
719  primitive clipped by both the left and right side of the frustum, which
720  implies that you should have vertical edges on the left and right side of
721  the viewport.  With integer viewport coordinates, both edges will be exactly
722  between pixel centers.  In practice, implementations' tiebreaking rules will
723  have either the left or right edge light up pixels outside the viewport.  If
724  the viewport is the full window, this means that one of those lines won't be
725  visible.
726
727* wide points and lines:  According to the OpenGL spec, line or point
728  primitives on or near the edge of the viewport should technically extend
729  outside the viewport.  For example, a four-pixel point on the left edge of
730  the viewport should light up eight pixels (2x4) outside the left edge of the
731  viewport.  The scissoring used for guardband clipping will discard those
732  pixels.  In my opinion, the scissored results are preferable to those called
733  for by the spec.  Of course, with the OpenGL spec behavior, there are no
734  visible artifacts if:  (a) the viewport covers the entire window or (b) the
735  application scissors manually itself.
736
737Fractional viewports make things more complicated, particularly if the
738implementation doesn't scissor at a per-sample granularity.  In this case,
739tight view volume clipping will result in primitives that are fully contained
740within the fractional viewport (to the limits of clipping math, at least).
741Guardband clipping will have primitives that extend beyond the viewport and
742probably cover full pixels at the boundary of the viewport.  (This discussion
743assumes that a guardband implementation with fractional viewports extends its
744viewport clip to pass on pixels containing any fraction of the floating-point
745viewport.)
746
747Direct3D 11 specifies that rasterization along the one-pixel edges of
748fractional viewports to be undefined.  If implementations want defined
749behavior with fractional viewports, they can program a slightly wider viewport
750and scissor away the pixels along the edge of the expanded viewport.
751
752My recommendation is as follows:
753
754(1) Edit the clipping section of the spec to explicitly permit implementations
755to clip to larger view volume extents in (x,y) and instead scissor to the
756viewport rectangle.  Note that this scissor rectangle needs to either be
757separate from the API-level scissor rectangle, or intersected with it.  This
758scissoring would always have to be enabled, regardless of the SCISSOR enabled.
759
760(2) Edit the viewport section of the spec to briefly discuss the implications
761of fractional viewports on the newly permitted scissoring.
762
763    7) What is the VIEWPORT_SUBPIXEL_BITS implementation defined value for?
764
765       This allows an application to query the precision of the viewport
766       transform. More specifically, if VIEWPORT_SUBPIXEL_BITS is zero, then
767       this indicates that the viewport bounds are likely implemented using
768       integers in hardware. If there are more bits (such as fixed point) then
769       this value will be non-zero. If the implementation truely has floating
770       point viewport bounds, it may report a sufficiently high value to
771       indicate this.
772
773    8) What happened to glGetIntegerv(GL_VIEWPORT, v)?
774
775       It still works. You can query floating point state with an integer query.
776       You'll get a rounded version of the state. You can also query indexed
777       state with a non-indexed query - you'll get the state for index 0. Thus
778       glGetIntegerv(GL_VIEWPORT, v) is the same as
779       glGetIntegeri_v(GL_VIEWPORT, 0, v), which is legal.
780
781Revision History
782
783    Rev.    Date      Author    Changes
784    ----  --------    --------  -----------------------------------------
785    18    06/25/2012  Jon Leech Fixed GetIntegerIndexedivEXT ->
786                                GetIntegerIndexedvEXT typo (Bug 6694).
787    17    07/25/2010  Jon Leech Fix typo in ViewportArrayv pseudocode
788                                (Bug 6682).
789    16    07/19/2010  Jon Leech Add GetDoublei_v entry point and change
790                                state for DEPTH_RANGE to be indexed and
791                                queryable with this command (Bug 6495).
792                                Reflow a few paragraphs and sync
793                                language with 4.1 API spec.
794    15    06/16/2010  istewart  Add interaction with NV_geometry_program4.
795    14    05/26/2010  Jon Leech Fix minor typos, remove tabs, make language
796                                more consistent with GL core spec in
797                                some places, and reflow paragraphs
798                                following changes.
799    13    05/18/2010  gsellers  Rename to ARB_viewport_array.
800                                ARBify. Remove suffixes for Core 4.1.
801    12    05/17/2010  gsellers  Error is not generated for viewport bounds
802                                outside VIEWPORT_BOUNDS_RANGE.
803                                Incoporate feedback from pbrown.
804    11    05/11/2010  gsellers  Incorporate feedback from bmerry.
805    10    05/10/2010  dgkoch    allow UNDEFINED_VERTEX_EXT for compatibility
806     9    05/10/2010  dgkoch    add VIEWPORT_BOUNDS_RANGE and clarify the
807                                valid values for the viewport location.
808                                added queries to determing layer and viewport
809                                index provoking vertex convention.
810                                updated issue 4.
811     8    05/06/2010  gsellers  Remove error if viewport > MAX_VIEWPORT_DIMS.
812                                Fix typo in definition of glScissorIndexedv.
813                                Update description of ViewportArrayv to accept
814                                an array of floats, rather than an array of
815                                integers.
816     7    04/29/2010  gsellers  Updates and clarifications.
817     6    04/15/2010  gsellers  Add interaction with NV_depth_range.
818                                Change viewport bounds to floating point values.
819                                Add viewport subpixel precision query.
820                                Chage function names to ...Indexed.
821                                Add issues 6 and 7.
822     5    01/07/2010  gsellers  Change from AMD to EXT
823                                Change function prototypes
824                                Add glViewporti{_v}.
825                                Add glScissorArray, glScissori{_v}.
826                                Add glDepthRangeArrayv, glDepthRangei.
827     4    07/16/2009  gsellers  Document EXT_provoking_vertex interaction.
828                                Change 'leading vertex' to 'provoking vertex'.
829                                Clarify interaction with glViewport.
830                                Add multiple scissor rectangles.
831     3    07/14/2009  gsellers  Updates from nickh and wwlk
832     2    07/08/2009  gsellers  Updates from myoung
833     1    07/06/2009  gsellers  Initial draft
834