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