1Name 2 3 EXT_shader_pixel_local_storage 4 5Name Strings 6 7 GL_EXT_shader_pixel_local_storage 8 9Contributors 10 11 Jan-Harald Fredriksen, ARM 12 Sandeep Kakarlapudi, ARM 13 Marius Bjorge, ARM 14 Alexander Galazin, ARM 15 Tobias Hector, Imagination Technologies 16 Ilya Zaytsev, ARM 17 Shahbaz Youssefi, Google 18 19Contact 20 21 Jan-Harald Fredriksen (jan-harald.fredriksen 'at' arm.com) 22 23Status 24 25 Shipping. 26 27Version 28 29 Revision 7 30 Last Modified Date: Sep 06, 2022 31 32Number 33 34 OpenGL ES Extension #167 35 36Dependencies 37 38 OpenGL ES 3.0 is required. 39 40 This extension is written against the OpenGL ES Shading Language 41 specification, Language Version 3.00, Document Revision 3 and revision 42 OpenGL ES 3.0 of the API specification. 43 44Overview 45 46 Techniques such as deferred shading and deferred lighting are often 47 implemented by attaching multiple color render targets to a framebuffer 48 object, rendering the required intermediate data, and then sampling from 49 this data as textures. While flexible, this approach consumes a large 50 amount of external memory bandwidth, which is at a premium on mobile 51 devices. 52 53 Observing that the intermediate or "G-buffer" data is often only written to 54 and read by shaders executing for the same pixel position, tile-based 55 renderers can offer a more efficient alternative by keeping the data on-GPU. 56 This allows large amounts of data to be kept per-pixel, with zero external 57 memory bandwidth impact. 58 59 This extension provides a way for applications to pass information between 60 fragment shader invocations covering the same pixel by introducing the 61 concept of pixel local storage. Pixel local storage is an on-chip memory 62 storage that can be efficiently accessed by fragments being processed by 63 the GL. The format of data stored in the pixel local storage is independent 64 of the format of the currently attached framebuffer. The data in pixel local 65 storage is not written back to main memory. Access to pixel local storage 66 is controlled via glEnable and glDisable. If commands that implicitly or 67 explicitly flush the GL command stream are issued when pixel local storage 68 is enabled then the contents of the pixel local storage becomes undefined 69 for subsequent commands. 70 71New Procedures and Functions 72 73 None 74 75New Tokens 76 77 Accepted by the <pname> parameters of GetBooleanv, GetIntegerv, 78 GetInteger64v, or GetFloatv: 79 80 MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT 0x8F63 81 MAX_SHADER_PIXEL_LOCAL_STORAGE_SIZE_EXT 0x8F67 82 83 Accepted by the <pname> parameters of IsEnabled, GetBooleanv, GetIntegerv, 84 GetInteger64v, or GetFloatv: 85 86 SHADER_PIXEL_LOCAL_STORAGE_EXT 0x8F64 87 88New Macro Definitions 89 90 #define GL_EXT_shader_pixel_local_storage 1 91 92Additions to Chapter 4 of the OpenGL ES Shading Language Specification 93 94 In Section 4.3 (Storage Qualifiers), add a qualifiers to the table: 95 96 "Qualifier Meaning 97 -------- ------- 98 __pixel_localEXT fragment shader only; storage can be read and written 99 and is persistent across shader invocations covering 100 the same pixel 101 102 __pixel_local_inEXT fragment shader only; storage can be read and is 103 persistent across shader invocations covering the same 104 pixel; storage can be written in another shader 105 invocation declaring __pixel_localEXT or __pixel_- 106 local_outEXT storage. 107 108 __pixel_local_outEXT fragment shader only; storage can be written and is 109 persistent across shader invocations covering the same 110 pixel; storage is read in another shader invocation 111 declaring __pixel_localEXT or __pixel_local_inEXT 112 storage. 113 " 114 115 Then add a new paragraph at the end of the section: 116 "The __pixel_localEXT, __pixel_local_inEXT, and __pixel_local_outEXT 117 qualifiers are optional and must be enabled by calling 118 119 #extension GL_EXT_shader_pixel_local_storage : <behavior> 120 121 before use, where <behavior> is as specified in section 3.4." 122 123 After Section 4.3.6 (Output Variables), add a new paragraph: 124 125 "4.3.7 Pixel Local Variables 126 127 The __pixel_localEXT, __pixel_local_inEXT, and __pixel_local_outEXT 128 qualifiers are used to declare variables whose values are persistent across 129 fragment shader invocations covering the same pixel, collectively referred 130 to as pixel storage variables. Pixel local storage variables do not have any 131 backing store allocated through the OpenGL API and are not accessible to the 132 API. 133 134 Variables declared with the __pixel_localEXT qualifier can be read and 135 written from the same fragment shader invocation. Variables declared with 136 the __pixel_local_inEXT and __pixel_local_outEXT qualifiers can only be read 137 and written, respectively. 138 139 Pixel local storage variable reads and writes within a single shader 140 invocation are processed in order. 141 142 It is a compile-time error for a shader to statically write to both regular 143 user-defined fragment outputs and to pixel local storage variables. Reading 144 from pixel local storage variables and writing to user-defined fragment 145 outputs is, however, legal. 146 147 Pixel local storage variables may not have initializers and their contents 148 are undefined until written to from a shader. 149 150 Pixel local storage variables may be qualified with layout qualifiers 151 affecting how the values are stored in and retrieved from the underlying 152 storage, as described in section 4.3.8.4 "Pixel Local Block Layout 153 Qualifiers". 154 155 When reading from a pixel local storage variable, the in-storage value is 156 implicitly converted from the storage format specified by the layout 157 qualifier to the variable type. Similarly, when writing to a pixel local 158 storage variable, the value of the member is implicitly converted to the 159 storage format specified by the layout qualifier. 160 161 Pixel local storage variables may only be declared inside interface blocks 162 (section 4.3.7, "Interface Blocks"), which are then referred to as shader 163 pixel local storage blocks. It is a compile-time error to declare pixel 164 local storage variables at global scope (outside a block). 165 166 Pixel local storage blocks must be declared at global scope. 167 168 Pixel local storage variables declared inside pixel local storage 169 blocks will be laid out in local storage in monotonically increasing order 170 based on their location in the declaration. All pixel local storage 171 variables consume exactly 4 bytes of storage. 172 173 A shader may only declare a single input and a single output pixel local 174 storage block. A pixel local storage block declared using the __pixel_- 175 localEXT qualifier is counted as both an input and an output block. Thus, 176 it is a compile-time error for a shader to declare more than one pixel 177 storage block, with the exception that it is legal to declare one pixel 178 local storage block using the __pixel_local_inEXT qualifier and one with 179 the __pixel_local_outEXT qualifier. 180 181 Modify the start of Section 4.3.7 (Interface Blocks) to read: 182 183 "Uniform and pixel local storage variable declarations can be grouped into 184 named interface blocks to provide coarser granularity backing than is 185 achievable with individual declarations. They can have an optional instance 186 name, used in the shader to reference their members. A uniform block is 187 backed by the application with a buffer object. A block of pixel local 188 storage variables is not backed by any object. 189 190 GLSL ES 3.0 does not support interface blocks for shader inputs or outputs. 191 192 An interface block is started by a uniform or pixel local keyword, followed 193 by a block name, followed by an open curly brace ( { ) as follows: 194 195 interface-block: 196 layout-qualifieropt interface-qualifier block-name { member-list } instance-nameopt; 197 198 interface-qualifier: 199 in 200 out 201 uniform 202 __pixel_localEXT 203 __pixel_local_inEXT 204 __pixel_local_outEXT 205 " 206 207 Modify the sentence: 208 "Repeating the uniform interface qualifier for a member's storage qualifier 209 is optional." 210 To read: 211 "Repeating the uniform, __pixel_localEXT, __pixel_local_inEXT, or 212 __pixel_local_outEXT interface qualifier for a member's storage qualifier 213 is optional." 214 215 Add a new paragraph after the one starting with: 216 "For uniform blocks, the application uses the block name to identify the 217 block." 218 That reads: 219 "For __pixel_localEXT, __pixel_local_inEXT, and __pixel_local_outEXT storage 220 blocks, the block name is not used." 221 222 Modify the first paragraph of 4.3.8 (Layout Qualifiers) to read: 223 224 "Layout qualifiers can appear in several forms of declaration. They can 225 appear as part of an interface block definition or block member, as shown 226 in the grammar in the previous section. They can also appear with just an 227 interface qualifier (a storage qualifier that is in, out, uniform, 228 __pixel_localEXT, __pixel_local_inEXT, or __pixel_local_outEXT) to 229 establish layouts of other declarations made with that interface qualifier: 230 231 layout-qualifier interface-qualifier ; 232 " 233 234 Then remove paragraph starting with "Interface qualifiers are a subset of 235 storage qualifiers:" and the subsequent grammar for the interface-qualifier. 236 This is now described in section 4.3.7. 237 238 Add a new paragraph: 239 " 240 4.3.8.4 Pixel Local Block Layout Qualifiers 241 242 Layout qualifiers can be used for pixel local storage variables. The layout 243 qualifier identifiers for pixel local storage variables are: 244 245 layout-qualifier-id 246 float-pixel-local-format-qualifier 247 int-pixel-local-format-qualifier 248 uint-pixel-local-format-qualifier 249 250 float-pixel-local-format-qualifier 251 r11f_g11f_b10f 252 r32f 253 rg16f 254 rgb10_a2 255 rgba8 256 rg16 257 int-pixel-local-format-qualifier 258 rgba8i 259 rg16i 260 uint-pixel-local-format-qualifier 261 rgb10_a2ui 262 rgba8ui 263 rg16ui 264 r32ui 265 266 None of these have any semantic affect at all on the usage of the variables 267 being declared; they only describe how data is laid out in the underlying 268 storage. 269 270 The component format must match the base type and the number of components 271 of member declarations. It is a compile-time error to declare a pixel local 272 member where the format qualifier does not match the member type and the 273 number of components. 274 275 Pixel local storage layout qualifiers can be declared for global scope, on 276 a single pixel local storage block, or on a single pixel local storage block 277 member declaration. 278 279 Default layouts are established at global scope for pixel local storage 280 blocks as 281 282 layout(layout-qualifier-id-list) __pixel_localEXT; 283 layout(layout-qualifier-id-list) __pixel_local_inEXT; 284 layout(layout-qualifier-id-list) __pixel_local_outEXT; 285 286 The initial state of compilation is as if the following were declared: 287 288 layout(r32ui) __pixel_localEXT; 289 layout(r32ui) __pixel_local_inEXT; 290 layout(r32ui) __pixel_local_outEXT; 291 292 Pixel local storage blocks can be declared with optional layout qualifiers, 293 and so can their individual member declarations. Such block layout 294 qualification is scoped only to the content of the block. As with global 295 layout declarations, block layout qualification first inherits from 296 the current default qualification and then overrides it. Similarly, 297 individual member layout qualification is scoped just to the member 298 declaration, and inherits from and overrides the block's qualification. 299 300 The float-pixel-local-format-qualifier, the int-pixel-local-format- 301 qualifier, and the uint-pixel-local-format-qualifier overrides any previous 302 any previous use of any of these qualifiers; other qualifiers are inherited. 303 304 When multiple arguments are listed in a layout declaration, the effect will 305 be the same as if they were declared one at a time, in order from left to 306 right, each in turn inheriting from and overriding the result from the 307 previous qualification. 308 309 Example with per-member qualifiers: 310 311 __pixel_localEXT FragDataLocal { 312 layout(r11f_g11f_b10f) mediump vec3 normal; 313 layout(rgb10_a2ui) mediump uvec4 color; 314 layout(r32ui) highp uint flags; 315 }; 316 317 Example with inherited qualifiers: 318 319 layout(rgba8ui) __pixel_localEXT FragDataLocal { 320 layout(rgb10_a2, r11f_g11f_b10f) mediump vec3 normal; // storage is r11f_g11f_b10f 321 layout(rgb10_a2ui) mediump uvec4 color; 322 mediump uvec4 flags; // storage is rgba8ui 323 }; 324 325 Example of invalid local block declaration: 326 327 layout(rgba8ui) __pixel_localEXT FragDataLocal { 328 layout(r11f_g11f_b10f) mediump float normal; // error, component counts must match 329 layout(rgb10_a2ui) mediump vec4 color; // error, base types must match 330 }; 331 " 332 333Additions to Chapter 7 of the OpenGL ES Shading Language Specification 334 335 In Section 7.3 (Built-In Constants), add a new entry: 336 337 const mediump int gl_MaxShaderPixelLocalStorageFastSizeEXT = 16 338 const mediump int gl_MaxShaderPixelLocalStorageSizeEXT = 16 339 340Changes to the OpenGL ES 3.0 Specification, Chapter 3 341 342 In Section 3.9, at the end of the last sub-section ("Shader Outputs") add: 343 344 "Fragment data values may also be written to pixel local storage blocks. 345 These values are available for reading in subsequent shader invocations 346 covering the same pixel. Data values written to pixel local storage block 347 members are converted to the storage format specified in the shader. 348 349 If a shader writes to any user-defined fragment output, the pixel local 350 storage values for that fragment are lost, and their values in subsequent 351 shader invocations are undefined. 352 353 Similarly, if a shader writes to pixel local storage blocks, the value of 354 the framebuffer pixel covered by that fragment becomes undefined." 355 356Changes to the OpenGL ES 3.0 Specification, Chapter 4 357 358 In Section 4.1.7 ("Blending"), add after the fourth paragraph ("Blending 359 applies only if ..."): 360 361 "Blending only applies for user-defined fragment outputs. If the fragment 362 shader outputs to pixel local storage blocks, proceed to the next 363 operation." 364 365 In Section 4.1.9 ("Dithering), add after the second paragraph ("Many 366 dithering selection ..."): 367 368 "If the fragment shader outputs to pixel local storage blocks, no dithering 369 is performed." 370 371 In Section 4.4 ("Framebuffer Objects") modify the sentence: 372 373 "In particular, a framebuffer object encapsulates state necessary to 374 describe a collection of color, depth, and stencil logical buffers (other 375 types of buffers are not allowed)." 376 377 to read: 378 "In particular, a framebuffer object encapsulates state necessary to 379 describe a collection of color, depth, and stencil logical buffers (other 380 types of buffers cannot be attached)." 381 382 Then add the following paragraph to the end of the Section (before 4.4.1): 383 384 "A set of pixel local storage values may also be associated with the 385 framebuffer. These values are not backed by any framebuffer-attachable 386 image. This allows the GL to pass information between fragment shader 387 invocations covering the same pixel without requiring an attached object 388 to provide the underlying storage backing. The pixel local storage is only 389 valid while it is enabled as described in section 4.4.3." 390 391 Add a new section after 4.4.2 "Attaching Images to Framebuffer Objects" and 392 increase the section number for the the following subsections: 393 394 "4.4.3 Enabling pixel local storage 395 396 Fragment shaders have access to pixel local storage blocks, but this access 397 must be enabled prior to use and disabled after use. 398 399 Pixel local storage for the current draw framebuffer is enabled by calling 400 Enable with SHADER_PIXEL_LOCAL_STORAGE_EXT. 401 402 The contents of the pixel local storage for a pixel are initially an 403 implementation-defined function of the current value of the pixel in the 404 framebuffer. All pixel local storage variables are guaranteed to be zero if 405 all color components of the framebuffer are set to zero. 406 407 The contents of the pixel local storage persist until color data is flushed 408 to the framebuffer. After such an event, data in the pixel local storage 409 is lost and the contents are undefined. Events that cause a flush include: 410 * calling the GL commands Flush, Finish, and ClientWaitSync 411 * calling commands such as TexSubImage2D, CopyTexSubImage2D, and 412 BlitFramebuffer to update a texture that is also attached to the current 413 draw framebuffer while pixel local storage is enabled 414 * disabling pixel local storage by calling Disable with SHADER_PIXEL_- 415 LOCAL_STORAGE_EXT. 416 417 If pixel local storage is not enabled, an INVALID_OPERATION error will be 418 generated if any rendering command is issued while a program object that 419 accesses pixel local storage is bound. 420 421 While pixel local storage is enabled, an INVALID_OPERATION error will be 422 generated if any of the current draw framebuffer's attachment points are 423 modified, including changes to the underlying storage backing of objects 424 attached to these attachment points. An INVALID_OPERATION error will also be 425 generated on attempts to bind a different framebuffer object, to delete the 426 currently bound draw framebuffer, or change color buffer selection via 427 DrawBuffers while pixel local storage is enabled. 428 429 Pixel local storage is not supported in combination with multisample 430 rasterization. Attempting to enable pixel local storage while the value of 431 SAMPLE_BUFFERS is one will generate an INVALID_OPERATION error. 432 433 Pixel local storage is not supported when rendering to multiple draw 434 buffers. Attempting to enable pixel local storage while the current draw 435 framebuffer is a user-defined framebuffer and has an image attached to any 436 color attachment other than color attachment zero will generate an INVALID_- 437 OPERATION error. Similarly, attempting to enable pixel local storage while 438 the draw buffer for any color output other than color output zero is not 439 NONE will generate an INVALID_OPERATION error. 440 441 An INVALID_FRAMEBUFFER_OPERATION error will be generated when attempting to 442 enable pixel local storage while the current draw framebuffer is incomplete. 443 444 The total number of bytes of pixel local storage available to a shader is 445 specified by the value of the implementation-dependent constant MAX_SHADER_- 446 PIXEL_LOCAL_STORAGE_SIZE_EXT. A compile-time error will be generated if an 447 attempt is made to utilize more than the space available for pixel local 448 storage variables. An implementation may choose to subdivide the amount 449 of pixel local storage into a region for fast access and a region for normal 450 access. As many pixel local storage variables as possible will be stored, 451 in order of declaration, in the fast region before any variables will be 452 allocated in the normal region. The number of bytes available for fast 453 access is specified by the value of the implementation-dependent constant 454 MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT. This value will always be less 455 than or equal to the total amount of pixel local storage. 456 457 Pixel local storage is disabled by calling Disable with SHADER_PIXEL_- 458 LOCAL_STORAGE_EXT. 459 460 In the initial state, SHADER_PIXEL_LOCAL_STORAGE_EXT is disabled. 461 " 462 463Errors 464 465 INVALID_OPERATION is generated if the application attempts enable pixel 466 local storage while the value of SAMPLE_BUFFERS is one. 467 468 469 INVALID_OPERATION is generated if the application attempts to enable pixel 470 local storage while the current draw framebuffer is a user-defined frame- 471 buffer object and has an image attached to any color attachment other than 472 color attachment zero. 473 474 INVALID_OPERATION is generated if the application attempts to enable pixel 475 local storage while the current draw framebuffer is a user-defined frame- 476 buffer and the draw buffer for any color output other than color 477 output zero is not NONE. 478 479 INVALID_FRAMEBUFFER_OPERATION is generated if the application attempts to 480 enable pixel local storage while the current draw framebuffer is incomplete. 481 482 INVALID_OPERATION is generated if pixel local storage is disabled and the 483 application attempts to issue a rendering command while a program object 484 that accesses pixel local storage is bound. 485 486 INVALID_OPERATION is generated if pixel local storage is enabled and the 487 application attempts to bind a new draw framebuffer, delete the currently 488 bound draw framebuffer, change color buffer selection via DrawBuffers, or 489 modify any attachment of the currently bound draw framebuffer including 490 their underlying storage. 491 492New State 493 494 Add to Table 6.12 Framebuffer Control 495 496 Get Value Type Get Command Initial Value Description Sec. 497 --------------- ---- ------------ ------------- ----------- ----- 498 SHADER_PIXEL_LOCAL- B IsEnabled FALSE Pixel local 4.4.3 499 STORAGE_EXT storage. 500 501New Implementation Dependent State 502 503 Add to Table 6.32 Implementation Dependent Fragment Shader Limits 504 505 State Type Get Command Minimum Value Description Sec. 506 --------------- ---- ------------ ------------- ----------- ----- 507 MAX_SHADER_PIXEL- Z+ GetIntegerv 16 Amount of fast 4.4.3 508 LOCAL_STORAGE_FAST- storage in units 509 _SIZE_EXT of bytes available 510 for pixel local 511 storage variables. 512 513 MAX_SHADER_- Z+ GetIntegerv 16 Amount of total 4.4.3 514 PIXEL_LOCAL_STORAGE- storage in units 515 _SIZE_EXT of bytes available 516 for pixel local 517 storage variables. 518 519Examples 520 521 (1) Use the extension to write data. 522 523 #version 300 es 524 #extension GL_EXT_shader_pixel_local_storage : enable 525 526 __pixel_localEXT FragDataLocal { 527 layout(r11f_g11f_b10f) mediump vec3 normal; 528 layout(rgb10_a2) highp vec4 color; 529 layout(rgba8ui) mediump uvec4 flags; 530 } gbuf; 531 532 void main() 533 { 534 /* .... */ 535 gbuf.normal = v; 536 gbuf.color = texture(sampler, coord); 537 gbuf.flags = material_id; 538 } 539 540 (2) Use the extension to resolve the data. 541 542 #version 300 es 543 #extension GL_EXT_shader_pixel_local_storage : enable 544 545 __pixel_localEXT FragDataLocal { 546 layout(r11f_g11f_b10f) mediump vec3 normal; 547 layout(rgb10_a2) highp vec4 color; 548 layout(rgba8ui) mediump uvec4 flags; 549 } gbuf; 550 551 out highp vec4 fragColor; 552 553 void main() 554 { 555 fragColor = do_lighting(gbuf.normal, gbuf.color, gbuf.flags, light_pos); 556 } 557 558Issues 559 560 (1) Should errors be raised when this extension is used in combination with 561 blending and dithering? 562 563 RESOLVED. 564 565 No. Blending and dithering should be ignored when the shader outputs raw 566 values. 567 568 (2) Should errors be raised when this extension is used in combination with 569 multisampling? 570 571 RESOLVED. 572 573 Yes. This can be trivially detected when the pixel local storage is 574 enabled. 575 576 The alternative is that it results in undefined results. As long as the 577 shader is only run once per fragment, this should sort of work except 578 the coverage mask could mask out some bits. 579 580 (3) Should explicit packing functions be supported? 581 582 RESOLVED. 583 584 No. 585 586 Early versions of this extensions required explicit packing functions 587 to be used when writing to and reading from the pixel local storage. 588 This version of the extension does implicit conversions in of these 589 cases so packing functions are not required. 590 591 (4) What is the initial values of local variables? 592 593 RESOLVED. 594 595 On a cleared framebuffer, the values of pixel local variables will be 596 some function of the clear color value. But the function may be 597 different depending on the format of the framebuffer. This makes the 598 value effectively undefined unless the framebuffer has been cleared to 599 zero. 600 601 See also Issue 5. 602 603 (5) Do we need an API to initialize the pixel local variables? 604 605 RESOLVED. 606 607 No. This is deferred to a future extension. 608 609 Given Issue 4, there is no convenient way to initialize these variables 610 to anything other than zero. 611 612 Applications can initialize it by drawing a fullscreen quad that writes 613 to the local outputs, but that may not be the most efficient way. 614 615 An alternative solution is to define a new API to clear the framebuffer 616 along the lines of: 617 ClearLocaluiEXT(enum buffer, uint n, const T *values); 618 619 (6) Should the raw storage alias the fragment color? 620 621 RESOLVED. 622 623 Applications may want to mix shaders using pixel local storage and user- 624 defined outputs. This could be supported if we reserve a number of bits 625 (where the number depends on the framebuffer format) for the user- 626 defined outputs. 627 628 This approach may make it possible to support this functionality on 629 non-tile based renderers by directing raw values to a separate buffer 630 in memory. 631 632 This extension currently aliases the storage. Applications can manually 633 preserve the framebuffer value by using ARM_shader_framebuffer_fetch, 634 EXT_shader_framebuffer_fetch, or similar extensions to retrieve the 635 color value and then store this as a local value. 636 637 (7) Is there a way to salvage some aspect of multisampling? 638 639 RESOLVED. 640 641 Multisampling is clearly a desirable feature. The most likely 642 implementation of this extension, however, is to reuse the pixel local 643 storage normally used for multisample data to store application-specific 644 data, thus making this extension incompatible with multisampled 645 rasterization. 646 647 Support for multisampling is left to a future extension. 648 649 (8) Should pixel local variables be allowed declared outside interface 650 blocks? 651 652 RESOLVED. 653 654 No. This makes the pixel local storage much more difficult to manage. 655 The ESSL compiler would have to enforce ordering rules shaders to make 656 sure that all shaders see the pixel local storage declarations in the 657 same order. This seems to add implementation complexity for no obvious 658 benefit. 659 660 (9) Should packUnitVector3 be added in a separate extension? 661 662 RESOLVED. 663 664 Extended packing functions is only indirectly related to the core 665 feature exposed by this extension. They could potentially have other 666 use-cases. This could be added in the future if needed. See Issue 15. 667 668 (10) What happens to the local storage after eglSwapBuffers? 669 670 RESOLVED. 671 672 The contents of the pixel local storage are lost after a call to 673 eglSwapBuffers. In this respect, pixel local storage acts as an 674 ancillary buffer than cannot be preserved. 675 676 (11) Can pixel local storage variables be arrays? 677 678 RESOLVED. 679 680 Yes. There's no reason not to support this. 681 682 (12) Are variables declared with the pixel local qualifiers preserved? 683 684 RESOLVED. 685 686 There are two options: A) the implementation implicitly preserves all 687 unwritten pixel local variables, and B) the shader must explicitly 688 preserve unwritten pixel local variables. 689 690 Consider the following local storage block: 691 __pixel_localEXT FragDataLocal { 692 layout(r11f_g11f_b10f) mediump vec3 normal; 693 layout(rgb10_a2) highp vec4 color; 694 layout(rgba8ui) mediump uvec4 flags; 695 } gbuf; 696 If a shader only writes to 'color', option B would make 'normal and 697 'flags' undefined unless the shader also manually assigned these 698 variables to themselves. This would certainly be unexpected. If a 699 shader wants to reduce the data, e.g., by only preserving the 'normal' 700 variable, it can do so by declaring separate __pixel_local_inEXT and 701 __pixel_local_outEXT blocks. 702 703 Option A is chosen. 704 705 (13) Can CopyTex[Sub]Image, ReadPixels, and BlitFramebuffer be called 706 while pixel local storage is enabled? 707 708 RESOLVED. 709 710 These calls are all supported, but may not be very useful. 711 712 For CopyTex[Sub]Image and ReadPixels, the contents of the color buffer 713 will have undefined contents if the pixel local storage variables have 714 not yet been resolved. 715 716 BlitFramebuffer implicitly writes to the color buffer of the draw 717 framebuffer and will thus make all pixel local storage variables 718 associated with it undefined. 719 720 (14) What does 'undefined' mean for a pixel local storage variable 721 or a color value? 722 723 RESOLVED. 724 725 It simply means that the value has no well-defined meaning to an 726 application. It does _not_ mean that the value is random nor that it 727 could have been leaked from other contexts, processes, or memory other 728 than the framebuffer attachments. 729 730 (15) Do we need a built-in function to pack unit vectors? 731 732 RESOLVED. 733 734 No, there is no need for this. 735 736 Earlier drafts of this extensions added ESSL built-in functions to pack 737 and unpack unit vectors (packUnitVector3EXT, unpackUnitVector3EXT). 738 These would, however, only be useful if they gave performance 739 improvements over plain ESSL code, which they do not. 740 741 The following packing functions have been found to generate equivalent 742 code to the proposed built-in functions: 743 744 highp uint packUnitVector3(mediump vec3 n) 745 { 746 highp float p = sqrt(2.0) * sqrt(n.z + 1.0); 747 return packHalf2x16(n.xy / p); 748 } 749 750 mediump vec3 unpackUnitVector3(highp uint p) 751 { 752 highp vec2 fenc = unpackHalf2x16(p); 753 highp float f = dot(fenc, fenc); 754 highp float g = sqrt(1.0 - f); 755 highp vec3 n; 756 n.xy = 2.0*fenc*g; 757 n.z = 1.0 - 2.0*f; 758 return n; 759 } 760 761 (16) When writing to a single output value in a shader, do all local 762 storage values become invalid immediately? And vice versa? 763 764 E.g: 765 fragmentOutputValue = localstorage.value; 766 // Does a further access return an undefined value? 767 fragmentOutputValue += localstorage.value; 768 769 RESOLVED: No, these variables retain their values for the life of the 770 shader. 771 772 Fragment outputs and local storage variables are treated as temporary 773 variables during execution of a shader, rather than accessing the 774 underlying storage directly. Final values are only written to underlying 775 storage at the end of a shader's execution. Within a shader instance, 776 these variables can be read or written safely in any order. 777 778Revision History 779 780 Revision 7, 06/09/2022 (Shahbaz Youssefi) 781 Clarified that undefined value does not allow leaks between draw calls 782 from memory outside of the framebuffer attachments. 783 784 Revision 6, 12/03/2014 (Jan-Harald Fredriksen) 785 Added Issue 16. 786 787 Revision 5, 18/02/2014 (Jan-Harald Fredriksen) 788 Clarified that pixel local storage is undefined after flush commands. 789 Updated error conditions for MRT to cover the default framebuffer. 790 Minor wording changes. 791 Resolved Issue 7. 792 Expanded Issue 15. 793 Updated resolution of Issue 3. 794 795 Revision 4, 22/12/2013 (Jan-Harald Fredriksen) 796 Changed name to EXT_shader_pixel_local_storage. 797 Added MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT. 798 Clarified memory layouts within local storage blocks. 799 800 Revision 3, 14/10/2013 (Jan-Harald Fredriksen) 801 Fixed a typo. 802 Modified error conditions with multiple draw buffers. 803 804 Revision 2, 27/09/2013 (Jan-Harald Fredriksen) 805 Increased minimum maximum storage to 16 bytes. 806 Fixed a couple of typos. 807 Added Issues 13 and 14. 808 Added an error condition when enabling pixel local storage on an 809 incomplete FBO. 810 Restricted local storage to color attachment zero. 811 Disallowed changing buffer selection DrawBuffers while pixel local 812 storage is enabled. 813 Removed packUnitVector3/unpackUnitVector3 and added Issue 15. 814 815 Revision 1, 29/07/2013 (Jan-Harald Fredriksen) 816 First external draft. 817