• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Name
2
3    OES_viewport_array
4
5Name Strings
6
7    GL_OES_viewport_array
8
9Contributors
10
11    Contributors to NV_viewport_array
12    Daniel Koch, NVIDIA
13    Jeff Leger, Qualcomm
14
15Contact
16
17    Tobias Hector, Imagination Technologies (tobias.hector 'at' imgtec.com)
18
19Notice
20
21    Copyright (c) 2010-2016 The Khronos Group Inc. Copyright terms at
22        http://www.khronos.org/registry/speccopyright.html
23
24Specification Update Policy
25
26    Khronos-approved extension specifications are updated in response to
27    issues and bugs prioritized by the Khronos OpenGL ES Working Group. For
28    extensions which have been promoted to a core Specification, fixes will
29    first appear in the latest version of that core Specification, and will
30    eventually be backported to the extension document. This policy is
31    described in more detail at
32        https://www.khronos.org/registry/OpenGL/docs/update_policy.php
33
34Status
35
36    Approved by the OpenGL ES Working Group on April 20, 2016
37    Ratified by the Khronos Board of Promoters on July 22, 2016
38
39Version
40
41    Last Modified Date:         2016/04/19
42    Author Revision:            5
43
44Number
45
46    Open GL ES Extension #267
47
48Dependencies
49
50    OpenGL ES 3.2, EXT_geometry_shader or OES_geometry_shader is required.
51
52    This extension is written against the OpenGL ES 3.2 Specification (August
53    10, 2015)
54
55    This extension is written against the OpenGL ES Shading Language 3.20.2
56    Specification (August 6, 2015)
57
58    This extension has interactions with EXT_draw_buffers_indexed, OES_draw_buffers_indexed and ES3.2
59
60Overview
61
62    OpenGL ES is modeled on a pipeline of operations. The final stage in this
63    pipeline before rasterization is the viewport transformation. This stage
64    transforms vertices from view space into window coordinates and allows the
65    application to specify a rectangular region of screen space into which
66    OpenGL ES should draw primitives. Unextended OpenGL ES implementations provide a
67    single viewport per context. In order to draw primitives into multiple
68    viewports, the OpenGL ES viewport may be changed between several draw calls.
69    With the advent of Geometry Shaders, it has become possible for an
70    application to amplify geometry and produce multiple output primitives
71    for each primitive input to the Geometry Shader. It is possible to direct
72    these primitives to render into a selected render target. However, all
73    render targets share the same, global OpenGL ES viewport.
74
75    This extension enhances OpenGL ES by providing a mechanism to expose multiple
76    viewports. Each viewport is specified as a rectangle. The destination
77    viewport may be selected per-primitive by the geometry shader. This allows
78    the Geometry Shader to produce different versions of primitives destined
79    for separate viewport rectangles on the same surface. Additionally, when
80    combined with multiple framebuffer attachments, it allows a different
81    viewport rectangle to be selected for each. This extension also exposes a
82    separate scissor rectangle for each viewport. Finally, the viewport bounds
83    are now floating point quantities allowing fractional pixel offsets to be
84    applied during the viewport transform.
85
86IP Status
87
88    No known IP claims.
89
90New Procedures and Functions
91
92    void ViewportArrayvOES(uint first, sizei count, const float * v);
93    void ViewportIndexedfOES(uint index, float x, float y, float w, float h);
94    void ViewportIndexedfvOES(uint index, const float * v);
95    void ScissorArrayvOES(uint first, sizei count, const int * v);
96    void ScissorIndexedOES(uint index, int left, int bottom, sizei width, sizei height);
97    void ScissorIndexedvOES(uint index, const int * v);
98    void DepthRangeArrayfvOES(uint first, sizei count, const float * v);
99    void DepthRangeIndexedfOES(uint index, float n, float f);
100    void GetFloati_vOES(enum target, uint index, float *data);
101
102    [[If none of OpenGL ES 3.2, EXT_draw_buffers_indexed or OES_draw_buffers_indexed are supported]]
103    void EnableiOES(enum target, uint index);
104    void DisableiOES(enum target, uint index);
105    boolean IsEnablediOES(enum target, uint index);
106
107New Tokens
108
109    Accepted by the <pname> parameter of GetBooleanv, GetIntegerv, GetFloatv,
110    and GetInteger64v:
111
112        MAX_VIEWPORTS_OES                               0x825B
113        VIEWPORT_SUBPIXEL_BITS_OES                      0x825C
114        VIEWPORT_BOUNDS_RANGE_OES                       0x825D
115        VIEWPORT_INDEX_PROVOKING_VERTEX_OES             0x825F
116
117    Accepted by the <pname> parameter of GetIntegeri_v:
118
119        SCISSOR_BOX                                     0x0C10
120
121    Accepted by the <pname> parameter of GetFloati_vOES:
122
123        VIEWPORT                                        0x0BA2
124        DEPTH_RANGE                                     0x0B70
125
126    Accepted by the <pname> parameter of Enablei, Disablei, and IsEnabledi:
127
128        SCISSOR_TEST                                    0x0C11
129
130Additions to Chapter 11 of the OpenGL ES 3.2 Specification (Programmable Vertex
131Post-Processing)
132
133    Modifications to Section 11.3.4.5, Layer Selection
134
135    Rename the section to "Layer and Viewport Selection".
136
137    Add the following paragraph after the first paragraph:
138
139    Geometry shaders may also select the destination viewport for each
140    output primitive. The destination viewport for a primitive may be
141    selected in the geometry shader by writing to the built-in output
142    variable gl_ViewportIndex. This functionality allows a geometry
143    shader to direct its output to a different viewport for each
144    primitive, or to draw multiple versions of a primitive into several
145    different viewports.
146
147    Replace the first two sentences of the last paragraph with:
148
149    The specific vertex of a primitive that is used to select the
150    rendering layer or viewport index is implementation-dependent and
151    thus portable applications will assign the same layer and viewport
152    index for all vertices in a primitive. The vertex conventions
153    followed for gl_Layer and gl_ViewportIndex may be determined by
154    calling GetIntegerv with the symbolic constants
155    LAYER_PROVOKING_VERTEX and VIEWPORT_INDEX_PROVOKING_VERTEX_OES,
156    respectively.
157
158Additions to Chapter 12 of the OpenGL ES 3.2 Specification (Fixed-Function
159Vertex Post-Processing)
160
161    Modifications to section 12.5.1 "Controlling the Viewport"
162
163    Replace the entire section to read:
164
165    The viewport transformation is determined by the selected viewport's
166    width and height in pixels, p_x and p_y, respectively, and its
167    center (o_x,o_y) (also in pixels) ...
168
169        { leave equations intact }
170
171    Multiple viewports are available and are numbered zero through the
172    value of MAX_VIEWPORTS_OES minus one. If a geometry shader is active
173    and writes to gl_ViewportIndex, the viewport transformation uses the
174    viewport corresponding to the value assigned to gl_ViewportIndex
175    taken from an implementation-dependent primitive vertex. If the
176    value of the viewport index is outside the range zero to the value
177    of MAX_VIEWPORTS_OES minus one, the results of the viewport
178    transformation are undefined. If no geometry shader is active, or if
179    the active geometry shader does not write to gl_ViewportIndex, the
180    viewport numbered zero is used by the viewport transformation.
181
182    A single vertex may be used in more than one individual primitive, in
183    primitives such as TRIANGLE_STRIP.  In this case, the viewport
184    transformation is applied separately for each primitive.
185
186    The factor and offset applied to Z_d for each viewport encoded by n
187    and f are set using
188
189        void DepthRangeArrayfvOES(uint first, sizei count, const float * v);
190        void DepthRangeIndexedfOES(uint index, float n, float f);
191        void DepthRangef(float n, float f);
192
193    DepthRangeArrayfvOES is used to specify the depth range for multiple
194    viewports simultaneously. <first> specifies the index of the first
195    viewport to modify and <count> specifies the number of viewports.
196    Viewports whose indices lie outside the range [<first>, <first> + <count>)
197    are not modified. The <v> parameter contains the address of an array of
198    float types specifying near (n) and far (f) for each viewport in that
199    order. Values in <v> and the parameters <n> and <f> are clamped to
200    the range [0, 1] when specified.
201
202    DepthRangeIndexedfOES specifies the depth range for a single viewport
203    and is equivalent (assuming no errors are generated) to:
204
205        float v[] = { n, f };
206        DepthRangeArrayfvOES(index, 1, v);
207
208    DepthRangef sets the depth range for all viewports to the same values
209    and is equivalent (assuming no errors are generated) to:
210
211        for (uint i = 0; i < MAX_VIEWPORTS_OES; i++)
212            DepthRangeIndexedfOES(i, n, f);
213
214    Z_w is represented as either ...
215
216    Errors
217
218        An INVALID_VALUE error is generated if the sum of <first> and <count> is
219        greater than the value of MAX_VIEWPORTS_OES.
220
221        An INVALID_VALUE error is generated if <count> is negative.
222
223        An INVALID_VALUE error is generated if <index> is greater than or equal to
224        the value of MAX_VIEWPORTS_OES.
225
226    Viewport transformation parameters are specified using
227
228        void ViewportArrayvOES(uint first, sizei count, const float * v);
229        void Viewport(int x, int y, sizei w, sizei h);
230        void ViewportIndexedfOES(uint index, float x, float y, float w, float h);
231        void ViewportIndexedfvOES(uint index, const float * v);
232
233    ViewportArrayvOES specifies parameters for multiple viewports
234    simultaneously. <first> specifies the index of the first viewport to
235    modify and <count> specifies the number of viewports. Viewports whose
236    indices lie outside the range [<first>, <first> + <count>) are not modified.
237    <v> contains the address of an array of floating point values
238    specifying the left (x), bottom (y), width (w) and height (h) of
239    each viewport, in that order. <x> and <y> give the location of the
240    viewport's lower left corner and <w> and <h> give the viewport's
241    width and height, respectively.
242
243    ViewportIndexedfOES and ViewportIndexedfvOES specify parameters for a
244    single viewport and are equivalent (assuming no errors are
245    generated) to:
246
247        float v[4] = { x, y, w, h };
248        ViewportArrayvOES(index, 1, v);
249
250    and
251
252        ViewportArrayvOES(index, 1, v);
253
254    respectively.
255
256    Viewport sets the parameters for all viewports to the same values
257    and is equivalent (assuming no errors are generated) to:
258
259        for (uint i = 0; i < MAX_VIEWPORTS_OES; i++)
260            ViewportIndexedfOES(i, (float)x, (float)y, (float)w, (float)h);
261
262    The viewport parameters shown in the above equations are found from these
263    values as
264
265        o_x = x + w /2,
266        o_y = y + h / 2,
267        p_x = w,
268        p_y = h.
269
270    The location of the viewport's bottom-left corner, given by (x,y), are
271    clamped to be within the implementation-dependent viewport bounds range.
272    The viewport bounds range [min, max] tuple may be determined by
273    calling GetFloatv with the symbolic constant VIEWPORT_BOUNDS_RANGE_OES
274    (see chapter 20).
275
276    Viewport width and height are clamped to implementation-dependent maximums
277    when specified. The maximum width and height may be found by calling
278    GetFloatv with the symbolic constant MAX_VIEWPORT_DIMS. The maximum
279    viewport dimensions must be greater than or equal to the larger of
280    the visible dimensions of the display being rendered to (if a
281    display exists), and the largest renderbuffer image which can be
282    successfully created and attached to a framebuffer object (see
283    chapter 9).
284
285    Errors
286
287        An INVALID_VALUE error is generated if the sum of <first> and <count> is
288        greater than the value of MAX_VIEWPORTS_OES.
289
290        An INVALID_VALUE error is generated if <count> is negative>.
291
292        An INVALID_VALUE error is generated if <index> is greater than or equal to
293        the value of MAX_VIEWPORTS_OES.
294
295        An INVALID_VALUE error is generated if any <w> or <h> value is negative.
296
297    The state required to implement the viewport transformations is four
298    floating-point values and two clamped floating-point values for each
299    viewport. In the initial state, w and h for each viewport are set to
300    the width and height, respectively, of the window into which the GL
301    is to do its rendering. If the default framebuffer is bound but no
302    default framebuffer is associated with the GL context (see chapter
303    9), then w and h are initially set to zero. o_x and o_y are set to
304    w/2 and h/2, respectively. n and f are set to 0.0 and 1.0,
305    respectively.
306
307    The precision with which the GL interprets the floating point viewport
308    bounds is implementation-dependent and may be determined by querying the
309    implementation-defined constant VIEWPORT_SUBPIXEL_BITS_OES.
310
311Additions to Chapter 13 of the OpenGL ES 3.2 Specification (Fixed-Function
312Primitive Assembly and Rasterization)
313
314    Replace section 13.8.2 "Scissor Test" with the following:
315
316    The scissor test determines if (x_w, y_w) lies within the scissor rectangle
317    defined by four values for each viewport. These values are set with
318
319        void ScissorArrayvOES(uint first, sizei count, const int * v);
320        void ScissorIndexedOES(uint index, int left, int bottom, sizei width, sizei height);
321        void ScissorIndexedvOES(uint index, int * v);
322        void Scissor(int left, int bottom, sizei width, sizei height);
323
324    ScissorArrayvOES defines a set of scissor rectangles that are each
325    applied to the corresponding viewport (see section 12.5.1
326    "Controlling the Viewport"). <first> specifies the index of the
327    first scissor rectangle to modify, and <count> specifies the number
328    of scissor rectangles.  <v> contains the address of an array of
329    integers containing the left, bottom, width and height of the
330    scissor rectangles, in that order.
331
332    If left <= x_w < left + width and bottom <= y_w < bottom + height
333    for the selected scissor rectangle, then the scissor test passes.
334    Otherwise, the test fails and the fragment is discarded. For points,
335    lines, and polygons, the scissor rectangle for a primitive is
336    selected in the same manner as the viewport (see section 12.5.1).
337
338    The scissor test is enabled or disabled for all viewports using
339    Enable or Disable with the symbolic constant SCISSOR_TEST. The test
340    is enabled or disabled for a specific viewport using Enablei or
341    Disablei with the constant SCISSOR_TEST and the index of the
342    selected viewport. When disabled, it is as if the scissor test
343    always passes. The value of the scissor test enable for viewport <i>
344    can be queried by calling IsEnabledi with <target> SCISSOR_TEST and
345    <index> <i>. The value of the scissor test enable for viewport zero
346    may also be queried by calling IsEnabled with the same <target>,
347    but no <index> parameter.
348
349    ScissorIndexedOES and ScissorIndexedvOES specify the scissor rectangle for
350    a single viewport and are equivalent (assuming no errors are
351    generated) to:
352
353        int v[] = { left, bottom, width, height };
354        ScissorArrayvOES(index, 1, v);
355
356    and
357
358        ScissorArrayvOES(index, 1, v);
359
360    respectively.
361
362    Scissor sets the scissor rectangle for all viewports to the same
363    values and is equivalent (assuming no errors are generated) to:
364
365        for (uint i = 0; i < MAX_VIEWPORTS_OES; i++) {
366            ScissorIndexedOES(i, left, bottom, width, height);
367        }
368
369    Calling Enable or Disable with <target> SCISSOR_TEST is
370    equivalent, assuming no errors, to:
371
372    for (uint i = 0; i < MAX_VIEWPORTS_OES; i++) {
373        Enablei(SCISSOR_TEST, i);
374        /* or */
375        Disablei(SCISSOR_TEST, i);
376    }
377
378    Errors
379
380        An INVALID_VALUE error is generated if the sum of <first> and <count> is
381        greater than the value of MAX_VIEWPORTS_OES.
382
383        An INVALID_VALUE error is generated if <index> is greater than or equal to
384        the value of MAX_VIEWPORTS_OES.
385
386        An INVALID_VALUE error is generated if any <width> or <height> value is
387        negative.
388
389    The state required consists of four integer values per viewport, and
390    a bit indicating whether the test is enabled or disabled for each
391    viewport. In the initial state, left = bottom = 0, and width and
392    height are determined by the size of the window into which the GL is
393    to do its rendering for all viewports. If the default framebuffer is
394    bound but no default framebuffer is associated with the GL context
395    (see chapter 9), then with and height are initially set to zero.
396    Initially, the scissor test is disabled for all viewports.
397
398Additions to Chapter 20 of the OpenGL ES 3.2 Specification (Context State
399Queries)
400
401    Modifications to Section 20.1 Simple Queries
402
403        Add to the list of indexed query functions:
404
405        void GetFloati_vOES(enum target, uint index, float *data);
406
407Additions to Chapter 3 of the OpenGL ES Shading Language Specification
408
409    Add a new Section 3.4.x, GL_OES_viewport_array Extension
410
411    3.4.x GL_OES_viewport_array Extension
412
413    To use the GL_OES_viewport_array extension in a shader it must be
414    enabled using the #extension directive.
415
416    The shading language preprocessor #define GL_OES_viewport_array will
417    be defined to 1 if the GL_OES_viewport_array extension is supported.
418
419Additions to Chapter 7 of the OpenGL ES Shading Language Specification
420
421    Add the following built-in to section 7.1.4, Geometry Shader Special
422    Variables:
423
424        out highp int gl_ViewportIndex;
425
426    Add the following paragraph to the end of Section 7.1.4.2, Geometry Shader
427    Output Variables:
428
429    gl_ViewportIndex provides the index of the viewport to which the next
430    primitive emitted from the geometry shader should be drawn. Primitives
431    generated by the geometry shader will undergo viewport transformation and
432    scissor scissor testing using the viewport transformation and scissor
433    rectangle selected by the value of gl_ViewportIndex.
434    The viewport index used will come from one of the
435    vertices in the primitive being shaded. Which vertex the viewport index
436    comes from is determined as discussed in section 11.3.4.5 of the OpenGL ES
437    Specification, but may be undefined, so it is best to write the same
438    viewport index for all vertices of the primitive. If a geometry shader does
439    not assign a value to gl_ViewportIndex, viewport transform and scissor
440    rectangle zero will be used. If a geometry shader statically assigns a value to
441    gl_ViewportIndex and there is a path through the shader that does not set
442    gl_ViewportIndex, then the value of gl_ViewportIndex is undefined for
443    executions of the shader that take that path. See section 11.3.4.5 "Layer
444    and Viewport Selection" of the OpenGL ES Specification for more information.
445
446    Add the following build-in to section 7.1.5 "Fragment Shader Special
447    Variables:
448
449        in highp int gl_ViewportIndex;
450
451    Add the following paragraph to the end of section 7.1.5 "Fragment Shader
452    Special Variables:
453
454    The input variable gl_ViewportIndex will have the same value that was
455    written to the output variable gl_ViewportIndex in the geometry stage. If
456    the geometry stage does not dynamically assign to gl_ViewportIndex, the
457    value of gl_ViewportIndex in the fragment shader will be undefined. If the
458    geometry stage makes no static assignment to gl_ViewportIndex, the value
459    in the fragment stage is undefined. Otherwise, the fragment stage will read
460    the same value written by the geometry stage, even if that value is out of
461    range. If a fragment shader contains a static access to gl_ViewportIndex,
462    it will count against the implementation defined limit for the maximum
463    number of inputs to the fragment stage.
464
465    Add the following built-in to section 7.2 "Built-In Constants":
466
467        const highp int gl_MaxViewports = 16;
468
469Errors
470
471    INVALID_VALUE is generated by ViewportArrayvOES if <first> + <count> is
472    greater than or equal to the value of MAX_VIEWPORTS_OES, or if any
473    viewport's width or height is less than 0.
474
475    INVALID_VALUE is generated by ScissorArrayvOES if <first> + <count> is
476    greater than or equal to the value of MAX_VIEWPORTS_OES, or if any
477    scissor rectangle's width or height is less than zero.
478
479    INVALID_VALUE is generated by DepthRangeArrayfvOES if <first> + <count> is
480    greater than or equal to the vaue of MAX_VIEWPORTS_OES.
481
482    An INVALID_VALUE error is generated by Enablei, Disablei and IsEnabledi if
483    <target> is SCISSOR_TEST and <index> is greater than or equal to the value
484    of MAX_VIEWPORTS_OES
485
486New State
487
488    Table 21.6:
489
490    Get Value                 Type             Get Command       Initial Value   Description                 Sec
491    ------------------------  ---------------- --------------    -------------   ------------------------  -----
492    VIEWPORT                  16* x 4 x R      GetFloati_vOES    See 12.5.1      Viewport origin & extent  12.5.1
493    DEPTH_RANGE               16* x 2 x R[0,1] GetFloati_vOES    See 12.5.1      Depth range near & far    12.5.1
494
495NOTE: The changes are that VIEWPORT and DEPTH_RANGE are extended to
496accommodate 16* copies. Viewport now consists of floating-point values.
497
498    Table 21.13:
499
500    Get Value                 Type        Get Command           Initial Value   Description               Sec
501    ------------------------  ----------  -------------         -------------   -------------------       ------
502    SCISSOR_TEST              16* x B     IsEnabledi            FALSE           Scissoring enabled        13.8.2
503    SCISSOR_BOX               16* x 4 x Z GetIntegeri_v         See 13.8.2      Scissor box               13.8.2
504
505NOTE: The only change is that SCISSOR_TEST and SCISSOR_BOX are extended
506to accommodate 16* copies.
507
508New Implementation Dependent State
509
510    Get Value                            Type   Get Command     Minimum Value   Description                     Sec.
511    ---------                            ----   -----------     -------------   -------------------             -----
512    MAX_VIEWPORT_DIMS (NOTE 1)           2 x Z+ GetFloatv       See 12.5.1      Maximum viewport dimensions     12.5.1
513    MAX_VIEWPORTS_OES                    Z+     GetIntegerv     16              Maximum number of               12.5.1
514                                                                                active viewports
515    VIEWPORT_SUBPIXEL_BITS_OES           Z+     GetIntegerv     0               Number of bits of sub-pixel     12.5.1
516                                                                                precision for viewport bounds
517    VIEWPORT_BOUNDS_RANGE_OES            2 x R  GetFloatv       [-32768, 32767] Viewport bounds range [min,max] 12.5.1
518    VIEWPORT_INDEX_PROVOKING_VERTEX_OES  Z_4    GetIntegerv     -- (NOTE 2)     vertex convention followed by   12.5.1
519                                                                                the gl_ViewportIndex GLSL
520                                                                                variable
521
522NOTE 1: The recommended get command is changed from GetIntegerv to GetFloatv.
523NOTE 2: Valid values are: FIRST_VERTEX_CONVENTION,
524LAST_VERTEX_CONVENTION, PROVOKING_VERTEX, UNDEFINED_VERTEX.
525
526Interactions with EXT_draw_buffers_indexed, OES_draw_buffers_indexed and OpenGL ES 3.2
527
528    If EXT_draw_buffers_indexed is supported, EnableiEXT, DisableiEXT and
529    IsEnablediEXT can be used in place of their core counterparts.
530
531    If only EXT_draw_buffers_indexed is supported, replace all mentions
532    of Enablei, Disablei and IsEnabledi with their EXT suffixed counterparts.
533
534    If OES_draw_buffers_indexed is supported, EnableiOES, DisableiOES and
535    IsEnablediOES can be used in place of their core counterparts.
536
537    If only OES_draw_buffers_indexed is supported, replace all mentions
538    of Enablei, Disablei and IsEnabledi with their OES suffixed counterparts.
539
540    If none of these are supported, then the EnableiOES, DisableiOES and
541    IsEnablediOES functions are added, with exactly the same specification as
542    the equivalently named core functions in OpenGL ES 3.2. Replace all mentions
543    of Enablei, Disablei and IsEnabledi with their OES suffixed counterparts.
544
545Issues
546
547    See issues section in ARB_viewport_array.
548
549    #1 What are the differences from ARB_viewport_array?
550
551    - OpenGL ES does not support the double datatype. The changed interfaces of
552    glDepthRangeArrayfvOES and DepthRangeIndexedfOES reflect that. 'float' is
553    being used instead of 'clampf', with additional constraints in the text
554    that the values will get clamped.
555    - The ability to access gl_ViewportIndex from the fragment shader was added
556    from ARB_fragment_layer_viewport.
557    - Unlike ARB_fragment_layer_viewport, the value of gl_ViewportIndex is undefined
558    if it wasn't written by the geometry shader.
559
560
561Revision History
562
563    Rev.    Date      Author    Changes
564    ----  --------    --------  -----------------------------------------
565     1    10/12/2015  thector   Initial draft
566     2    23/03/2016  thector   Changed to EXT
567     3    06/04/2016  thector   Made gl_ViewportIndex undefined in a fragment shader if not previously written
568     4    13/04/2016  thector   Changed to OES
569                                Added interactions with OES_draw_buffers_indexed
570                                Allowed dependency on OES_geometry_shader as well as EXT_geometry_shader
571     5    19/04/2016  dkoch     Typographical fixes.
572                                Sync some additional language with GL 4.5 and GLSL 4.50.
573