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