blob: 11d4495a5c52ffb3e4bbfe7a5346196c83db9bad [file] [log] [blame]
Name
OES_viewport_array
Name Strings
GL_OES_viewport_array
Contributors
Contributors to NV_viewport_array
Daniel Koch, NVIDIA
Jeff Leger, Qualcomm
Contact
Tobias Hector, Imagination Technologies (tobias.hector 'at' imgtec.com)
Notice
Copyright (c) 2010-2016 The Khronos Group Inc. Copyright terms at
http://www.khronos.org/registry/speccopyright.html
Specification Update Policy
Khronos-approved extension specifications are updated in response to
issues and bugs prioritized by the Khronos OpenGL ES Working Group. For
extensions which have been promoted to a core Specification, fixes will
first appear in the latest version of that core Specification, and will
eventually be backported to the extension document. This policy is
described in more detail at
https://www.khronos.org/registry/OpenGL/docs/update_policy.php
Status
Approved by the OpenGL ES Working Group on April 20, 2016
Ratified by the Khronos Board of Promoters on July 22, 2016
Version
Last Modified Date: 2016/04/19
Author Revision: 5
Number
Open GL ES Extension #267
Dependencies
OpenGL ES 3.2, EXT_geometry_shader or OES_geometry_shader is required.
This extension is written against the OpenGL ES 3.2 Specification (August
10, 2015)
This extension is written against the OpenGL ES Shading Language 3.20.2
Specification (August 6, 2015)
This extension has interactions with EXT_draw_buffers_indexed, OES_draw_buffers_indexed and ES3.2
Overview
OpenGL ES is modeled on a pipeline of operations. The final stage in this
pipeline before rasterization is the viewport transformation. This stage
transforms vertices from view space into window coordinates and allows the
application to specify a rectangular region of screen space into which
OpenGL ES should draw primitives. Unextended OpenGL ES implementations provide a
single viewport per context. In order to draw primitives into multiple
viewports, the OpenGL ES viewport may be changed between several draw calls.
With the advent of Geometry Shaders, it has become possible for an
application to amplify geometry and produce multiple output primitives
for each primitive input to the Geometry Shader. It is possible to direct
these primitives to render into a selected render target. However, all
render targets share the same, global OpenGL ES viewport.
This extension enhances OpenGL ES by providing a mechanism to expose multiple
viewports. Each viewport is specified as a rectangle. The destination
viewport may be selected per-primitive by the geometry shader. This allows
the Geometry Shader to produce different versions of primitives destined
for separate viewport rectangles on the same surface. Additionally, when
combined with multiple framebuffer attachments, it allows a different
viewport rectangle to be selected for each. This extension also exposes a
separate scissor rectangle for each viewport. Finally, the viewport bounds
are now floating point quantities allowing fractional pixel offsets to be
applied during the viewport transform.
IP Status
No known IP claims.
New Procedures and Functions
void ViewportArrayvOES(uint first, sizei count, const float * v);
void ViewportIndexedfOES(uint index, float x, float y, float w, float h);
void ViewportIndexedfvOES(uint index, const float * v);
void ScissorArrayvOES(uint first, sizei count, const int * v);
void ScissorIndexedOES(uint index, int left, int bottom, sizei width, sizei height);
void ScissorIndexedvOES(uint index, const int * v);
void DepthRangeArrayfvOES(uint first, sizei count, const float * v);
void DepthRangeIndexedfOES(uint index, float n, float f);
void GetFloati_vOES(enum target, uint index, float *data);
[[If none of OpenGL ES 3.2, EXT_draw_buffers_indexed or OES_draw_buffers_indexed are supported]]
void EnableiOES(enum target, uint index);
void DisableiOES(enum target, uint index);
boolean IsEnablediOES(enum target, uint index);
New Tokens
Accepted by the <pname> parameter of GetBooleanv, GetIntegerv, GetFloatv,
and GetInteger64v:
MAX_VIEWPORTS_OES 0x825B
VIEWPORT_SUBPIXEL_BITS_OES 0x825C
VIEWPORT_BOUNDS_RANGE_OES 0x825D
VIEWPORT_INDEX_PROVOKING_VERTEX_OES 0x825F
Accepted by the <pname> parameter of GetIntegeri_v:
SCISSOR_BOX 0x0C10
Accepted by the <pname> parameter of GetFloati_vOES:
VIEWPORT 0x0BA2
DEPTH_RANGE 0x0B70
Accepted by the <pname> parameter of Enablei, Disablei, and IsEnabledi:
SCISSOR_TEST 0x0C11
Additions to Chapter 11 of the OpenGL ES 3.2 Specification (Programmable Vertex
Post-Processing)
Modifications to Section 11.3.4.5, Layer Selection
Rename the section to "Layer and Viewport Selection".
Add the following paragraph after the first paragraph:
Geometry shaders may also select the destination viewport for each
output primitive. The destination viewport for a primitive may be
selected in the geometry shader by writing to the built-in output
variable gl_ViewportIndex. This functionality allows a geometry
shader to direct its output to a different viewport for each
primitive, or to draw multiple versions of a primitive into several
different viewports.
Replace the first two sentences of the last paragraph with:
The specific vertex of a primitive that is used to select the
rendering layer or viewport index 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 may be determined by
calling GetIntegerv with the symbolic constants
LAYER_PROVOKING_VERTEX and VIEWPORT_INDEX_PROVOKING_VERTEX_OES,
respectively.
Additions to Chapter 12 of the OpenGL ES 3.2 Specification (Fixed-Function
Vertex Post-Processing)
Modifications to section 12.5.1 "Controlling the Viewport"
Replace the entire section to read:
The viewport transformation is determined by the selected viewport's
width and height in pixels, p_x and p_y, respectively, and its
center (o_x,o_y) (also in pixels) ...
{ leave equations intact }
Multiple viewports are available and are numbered zero through the
value of MAX_VIEWPORTS_OES minus one. If a geometry shader is active
and writes to gl_ViewportIndex, the viewport transformation uses the
viewport corresponding to the value assigned to gl_ViewportIndex
taken from an implementation-dependent primitive vertex. If the
value of the viewport index is outside the range zero to the value
of MAX_VIEWPORTS_OES minus one, the results of the viewport
transformation are undefined. If no geometry shader is active, or if
the active geometry shader does not write to gl_ViewportIndex, the
viewport numbered zero is used by the viewport transformation.
A single vertex may be used in more than one individual primitive, in
primitives such as TRIANGLE_STRIP. In this case, the viewport
transformation is applied separately for each primitive.
The factor and offset applied to Z_d for each viewport encoded by n
and f are set using
void DepthRangeArrayfvOES(uint first, sizei count, const float * v);
void DepthRangeIndexedfOES(uint index, float n, float f);
void DepthRangef(float n, float f);
DepthRangeArrayfvOES is used to specify the depth range for multiple
viewports simultaneously. <first> specifies the index of the first
viewport to modify and <count> specifies the number of viewports.
Viewports whose indices lie outside the range [<first>, <first> + <count>)
are not modified. The <v> parameter contains the address of an array of
float types specifying near (n) and far (f) for each viewport in that
order. Values in <v> and the parameters <n> and <f> are clamped to
the range [0, 1] when specified.
DepthRangeIndexedfOES specifies the depth range for a single viewport
and is equivalent (assuming no errors are generated) to:
float v[] = { n, f };
DepthRangeArrayfvOES(index, 1, v);
DepthRangef sets the depth range for all viewports to the same values
and is equivalent (assuming no errors are generated) to:
for (uint i = 0; i < MAX_VIEWPORTS_OES; i++)
DepthRangeIndexedfOES(i, n, f);
Z_w is represented as either ...
Errors
An INVALID_VALUE error is generated if the sum of <first> and <count> is
greater than the value of MAX_VIEWPORTS_OES.
An INVALID_VALUE error is generated if <count> is negative.
An INVALID_VALUE error is generated if <index> is greater than or equal to
the value of MAX_VIEWPORTS_OES.
Viewport transformation parameters are specified using
void ViewportArrayvOES(uint first, sizei count, const float * v);
void Viewport(int x, int y, sizei w, sizei h);
void ViewportIndexedfOES(uint index, float x, float y, float w, float h);
void ViewportIndexedfvOES(uint index, const float * v);
ViewportArrayvOES specifies parameters for multiple viewports
simultaneously. <first> specifies the index of the first viewport to
modify and <count> specifies the number of viewports. Viewports whose
indices lie outside the range [<first>, <first> + <count>) are not modified.
<v> contains the address of an array of floating point values
specifying the left (x), bottom (y), width (w) and height (h) of
each viewport, in that order. <x> and <y> give the location of the
viewport's lower left corner and <w> and <h> give the viewport's
width and height, respectively.
ViewportIndexedfOES and ViewportIndexedfvOES specify parameters for a
single viewport and are equivalent (assuming no errors are
generated) to:
float v[4] = { x, y, w, h };
ViewportArrayvOES(index, 1, v);
and
ViewportArrayvOES(index, 1, v);
respectively.
Viewport sets the parameters for all viewports to the same values
and is equivalent (assuming no errors are generated) to:
for (uint i = 0; i < MAX_VIEWPORTS_OES; i++)
ViewportIndexedfOES(i, (float)x, (float)y, (float)w, (float)h);
The viewport parameters shown in the above equations are found from these
values as
o_x = x + w /2,
o_y = y + h / 2,
p_x = w,
p_y = h.
The location of the viewport's bottom-left corner, given by (x,y), are
clamped to be within the implementation-dependent viewport bounds range.
The viewport bounds range [min, max] tuple may be determined by
calling GetFloatv with the symbolic constant VIEWPORT_BOUNDS_RANGE_OES
(see chapter 20).
Viewport width and height are clamped to implementation-dependent maximums
when specified. The maximum width and height may be found by calling
GetFloatv with the symbolic constant MAX_VIEWPORT_DIMS. The maximum
viewport dimensions must be greater than or equal to the larger of
the visible dimensions of the display being rendered to (if a
display exists), and the largest renderbuffer image which can be
successfully created and attached to a framebuffer object (see
chapter 9).
Errors
An INVALID_VALUE error is generated if the sum of <first> and <count> is
greater than the value of MAX_VIEWPORTS_OES.
An INVALID_VALUE error is generated if <count> is negative>.
An INVALID_VALUE error is generated if <index> is greater than or equal to
the value of MAX_VIEWPORTS_OES.
An INVALID_VALUE error is generated if any <w> or <h> value is negative.
The state required to implement the viewport transformations is four
floating-point values and two clamped floating-point values for each
viewport. In the initial state, w and h for each viewport are set to
the width and height, respectively, of the window into which the GL
is to do its rendering. If the default framebuffer is bound but no
default framebuffer is associated with the GL context (see chapter
9), then w and h are initially set to zero. o_x and o_y are set to
w/2 and h/2, respectively. n and f are set to 0.0 and 1.0,
respectively.
The precision with which the GL interprets the floating point viewport
bounds is implementation-dependent and may be determined by querying the
implementation-defined constant VIEWPORT_SUBPIXEL_BITS_OES.
Additions to Chapter 13 of the OpenGL ES 3.2 Specification (Fixed-Function
Primitive Assembly and Rasterization)
Replace section 13.8.2 "Scissor Test" with the following:
The scissor test determines if (x_w, y_w) lies within the scissor rectangle
defined by four values for each viewport. These values are set with
void ScissorArrayvOES(uint first, sizei count, const int * v);
void ScissorIndexedOES(uint index, int left, int bottom, sizei width, sizei height);
void ScissorIndexedvOES(uint index, int * v);
void Scissor(int left, int bottom, sizei width, sizei height);
ScissorArrayvOES defines a set of scissor rectangles that are each
applied to the corresponding viewport (see section 12.5.1
"Controlling the Viewport"). <first> specifies the index of the
first scissor rectangle to modify, and <count> specifies the number
of scissor rectangles. <v> contains the address of an array of
integers containing the left, bottom, width and height of the
scissor rectangles, in that order.
If left <= x_w < left + width and bottom <= y_w < bottom + height
for the selected scissor rectangle, then the scissor test passes.
Otherwise, the test fails and the fragment is discarded. For points,
lines, and polygons, the scissor rectangle for a primitive is
selected in the same manner as the viewport (see section 12.5.1).
The scissor test is enabled or disabled for all viewports using
Enable or Disable with the symbolic constant SCISSOR_TEST. The test
is enabled or disabled for a specific viewport using Enablei or
Disablei with the constant SCISSOR_TEST and the index of the
selected viewport. When disabled, it is as if the scissor test
always passes. The value of the scissor test enable for viewport <i>
can be queried by calling IsEnabledi with <target> SCISSOR_TEST and
<index> <i>. The value of the scissor test enable for viewport zero
may also be queried by calling IsEnabled with the same <target>,
but no <index> parameter.
ScissorIndexedOES and ScissorIndexedvOES specify the scissor rectangle for
a single viewport and are equivalent (assuming no errors are
generated) to:
int v[] = { left, bottom, width, height };
ScissorArrayvOES(index, 1, v);
and
ScissorArrayvOES(index, 1, v);
respectively.
Scissor sets the scissor rectangle for all viewports to the same
values and is equivalent (assuming no errors are generated) to:
for (uint i = 0; i < MAX_VIEWPORTS_OES; i++) {
ScissorIndexedOES(i, left, bottom, width, height);
}
Calling Enable or Disable with <target> SCISSOR_TEST is
equivalent, assuming no errors, to:
for (uint i = 0; i < MAX_VIEWPORTS_OES; i++) {
Enablei(SCISSOR_TEST, i);
/* or */
Disablei(SCISSOR_TEST, i);
}
Errors
An INVALID_VALUE error is generated if the sum of <first> and <count> is
greater than the value of MAX_VIEWPORTS_OES.
An INVALID_VALUE error is generated if <index> is greater than or equal to
the value of MAX_VIEWPORTS_OES.
An INVALID_VALUE error is generated if any <width> or <height> value is
negative.
The state required consists of four integer values per viewport, and
a bit indicating whether the test is enabled or disabled for each
viewport. In the initial state, left = bottom = 0, and width and
height are determined by the size of the window into which the GL is
to do its rendering for all viewports. If the default framebuffer is
bound but no default framebuffer is associated with the GL context
(see chapter 9), then with and height are initially set to zero.
Initially, the scissor test is disabled for all viewports.
Additions to Chapter 20 of the OpenGL ES 3.2 Specification (Context State
Queries)
Modifications to Section 20.1 Simple Queries
Add to the list of indexed query functions:
void GetFloati_vOES(enum target, uint index, float *data);
Additions to Chapter 3 of the OpenGL ES Shading Language Specification
Add a new Section 3.4.x, GL_OES_viewport_array Extension
3.4.x GL_OES_viewport_array Extension
To use the GL_OES_viewport_array extension in a shader it must be
enabled using the #extension directive.
The shading language preprocessor #define GL_OES_viewport_array will
be defined to 1 if the GL_OES_viewport_array extension is supported.
Additions to Chapter 7 of the OpenGL ES Shading Language Specification
Add the following built-in to section 7.1.4, Geometry Shader Special
Variables:
out highp int gl_ViewportIndex;
Add the following paragraph to the end of Section 7.1.4.2, Geometry Shader
Output Variables:
gl_ViewportIndex provides the index of the viewport to which the next
primitive emitted from the geometry shader should be drawn. Primitives
generated by the geometry shader will undergo viewport transformation and
scissor 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. Which vertex the viewport index
comes from is determined as discussed in section 11.3.4.5 of the OpenGL ES
Specification, but may be undefined, so it is best to write the same
viewport index for all vertices of the primitive. If a geometry shader does
not assign a value to gl_ViewportIndex, viewport transform and scissor
rectangle zero will be used. If a geometry shader statically assigns a value to
gl_ViewportIndex and there is a path through the shader that does not set
gl_ViewportIndex, then the value of gl_ViewportIndex is undefined for
executions of the shader that take that path. See section 11.3.4.5 "Layer
and Viewport Selection" of the OpenGL ES Specification for more information.
Add the following build-in to section 7.1.5 "Fragment Shader Special
Variables:
in highp int gl_ViewportIndex;
Add the following paragraph to the end of section 7.1.5 "Fragment Shader
Special Variables:
The input variable gl_ViewportIndex will have the same value that was
written to the output variable gl_ViewportIndex in the geometry stage. If
the geometry stage does not dynamically assign to gl_ViewportIndex, the
value of gl_ViewportIndex in the fragment shader will be undefined. If the
geometry stage makes no static assignment to gl_ViewportIndex, the value
in the fragment stage is undefined. Otherwise, the fragment stage will read
the same value written by the geometry 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.
Add the following built-in to section 7.2 "Built-In Constants":
const highp int gl_MaxViewports = 16;
Errors
INVALID_VALUE is generated by ViewportArrayvOES if <first> + <count> is
greater than or equal to the value of MAX_VIEWPORTS_OES, or if any
viewport's width or height is less than 0.
INVALID_VALUE is generated by ScissorArrayvOES if <first> + <count> is
greater than or equal to the value of MAX_VIEWPORTS_OES, or if any
scissor rectangle's width or height is less than zero.
INVALID_VALUE is generated by DepthRangeArrayfvOES if <first> + <count> is
greater than or equal to the vaue of MAX_VIEWPORTS_OES.
An INVALID_VALUE error is generated by Enablei, Disablei and IsEnabledi if
<target> is SCISSOR_TEST and <index> is greater than or equal to the value
of MAX_VIEWPORTS_OES
New State
Table 21.6:
Get Value Type Get Command Initial Value Description Sec
------------------------ ---------------- -------------- ------------- ------------------------ -----
VIEWPORT 16* x 4 x R GetFloati_vOES See 12.5.1 Viewport origin & extent 12.5.1
DEPTH_RANGE 16* x 2 x R[0,1] GetFloati_vOES See 12.5.1 Depth range near & far 12.5.1
NOTE: The changes are that VIEWPORT and DEPTH_RANGE are extended to
accommodate 16* copies. Viewport now consists of floating-point values.
Table 21.13:
Get Value Type Get Command Initial Value Description Sec
------------------------ ---------- ------------- ------------- ------------------- ------
SCISSOR_TEST 16* x B IsEnabledi FALSE Scissoring enabled 13.8.2
SCISSOR_BOX 16* x 4 x Z GetIntegeri_v See 13.8.2 Scissor box 13.8.2
NOTE: The only change is that SCISSOR_TEST and SCISSOR_BOX are extended
to accommodate 16* copies.
New Implementation Dependent State
Get Value Type Get Command Minimum Value Description Sec.
--------- ---- ----------- ------------- ------------------- -----
MAX_VIEWPORT_DIMS (NOTE 1) 2 x Z+ GetFloatv See 12.5.1 Maximum viewport dimensions 12.5.1
MAX_VIEWPORTS_OES Z+ GetIntegerv 16 Maximum number of 12.5.1
active viewports
VIEWPORT_SUBPIXEL_BITS_OES Z+ GetIntegerv 0 Number of bits of sub-pixel 12.5.1
precision for viewport bounds
VIEWPORT_BOUNDS_RANGE_OES 2 x R GetFloatv [-32768, 32767] Viewport bounds range [min,max] 12.5.1
VIEWPORT_INDEX_PROVOKING_VERTEX_OES Z_4 GetIntegerv -- (NOTE 2) vertex convention followed by 12.5.1
the gl_ViewportIndex GLSL
variable
NOTE 1: The recommended get command is changed from GetIntegerv to GetFloatv.
NOTE 2: Valid values are: FIRST_VERTEX_CONVENTION,
LAST_VERTEX_CONVENTION, PROVOKING_VERTEX, UNDEFINED_VERTEX.
Interactions with EXT_draw_buffers_indexed, OES_draw_buffers_indexed and OpenGL ES 3.2
If EXT_draw_buffers_indexed is supported, EnableiEXT, DisableiEXT and
IsEnablediEXT can be used in place of their core counterparts.
If only EXT_draw_buffers_indexed is supported, replace all mentions
of Enablei, Disablei and IsEnabledi with their EXT suffixed counterparts.
If OES_draw_buffers_indexed is supported, EnableiOES, DisableiOES and
IsEnablediOES can be used in place of their core counterparts.
If only OES_draw_buffers_indexed is supported, replace all mentions
of Enablei, Disablei and IsEnabledi with their OES suffixed counterparts.
If none of these are supported, then the EnableiOES, DisableiOES and
IsEnablediOES functions are added, with exactly the same specification as
the equivalently named core functions in OpenGL ES 3.2. Replace all mentions
of Enablei, Disablei and IsEnabledi with their OES suffixed counterparts.
Issues
See issues section in ARB_viewport_array.
#1 What are the differences from ARB_viewport_array?
- OpenGL ES does not support the double datatype. The changed interfaces of
glDepthRangeArrayfvOES and DepthRangeIndexedfOES reflect that. 'float' is
being used instead of 'clampf', with additional constraints in the text
that the values will get clamped.
- The ability to access gl_ViewportIndex from the fragment shader was added
from ARB_fragment_layer_viewport.
- Unlike ARB_fragment_layer_viewport, the value of gl_ViewportIndex is undefined
if it wasn't written by the geometry shader.
Revision History
Rev. Date Author Changes
---- -------- -------- -----------------------------------------
1 10/12/2015 thector Initial draft
2 23/03/2016 thector Changed to EXT
3 06/04/2016 thector Made gl_ViewportIndex undefined in a fragment shader if not previously written
4 13/04/2016 thector Changed to OES
Added interactions with OES_draw_buffers_indexed
Allowed dependency on OES_geometry_shader as well as EXT_geometry_shader
5 19/04/2016 dkoch Typographical fixes.
Sync some additional language with GL 4.5 and GLSL 4.50.