| Name |
| |
| EXT_shader_pixel_local_storage2 |
| |
| Name Strings |
| |
| GL_EXT_shader_pixel_local_storage2 |
| |
| Contributors |
| |
| Jan-Harald Fredriksen, ARM |
| Sandeep Kakarlapudi, ARM |
| James Glanville, Imagination Technologies |
| Tobias Hector, Imagination Technologies |
| |
| Contact |
| |
| Tobias Hector (tobias.hector 'at' imgtec.com) |
| |
| Status |
| |
| Complete |
| |
| Version |
| |
| Revision 0.13 |
| Last Modified Date: October 28, 2015 |
| |
| Number |
| |
| OpenGL ES Extension #253 |
| |
| Dependencies |
| |
| OpenGL ES 3.0 and GLSL ES 3.0 are required. |
| |
| EXT_shader_pixel_local_storage is required. |
| |
| This extension has interactions with EXT_color_buffer_float and |
| EXT_color_buffer_half_float |
| |
| This extension is written against the OpenGL ES Shading Language |
| specification, Language Version 3.00, Document Revision 4 and revision |
| OpenGL ES 3.0.2 of the API specification. |
| |
| Overview |
| |
| This extension builds on EXT_shader_pixel_local_storage by lifting the |
| restriction that pixel local storage is not supported when rendering to |
| multiple draw buffers. |
| |
| Moreover, pixel local storage values are no longer lost when writing to |
| user-defined fragment outputs, and, correspondingly, framebuffer pixel |
| values do not always become undefined when the shader writes to pixel local |
| storage. |
| |
| This extension adds the following capabilities: |
| - support for pixel local storage in combination with multiple user- |
| defined fragment outputs |
| - support for clearing pixel local storage variables |
| - support for multi-word pixel local storage variables |
| |
| New Procedures and Functions |
| |
| void FramebufferPixelLocalStorageSizeEXT(uint target, sizei size); |
| sizei GetFramebufferPixelLocalStorageSizeEXT(uint target); |
| void ClearPixelLocalStorageuiEXT(sizei offset, sizei n, const uint *values); |
| |
| New Tokens |
| |
| Accepted by the <pname> parameters of GetBooleanv, GetIntegerv, |
| GetInteger64v, or GetFloatv: |
| |
| MAX_SHADER_COMBINED_LOCAL_STORAGE_FAST_SIZE_EXT 0x9650 |
| MAX_SHADER_COMBINED_LOCAL_STORAGE_SIZE_EXT 0x9651 |
| |
| Returned by CheckFramebufferStatus: |
| |
| FRAMEBUFFER_INCOMPLETE_INSUFFICIENT_SHADER_COMBINED_LOCAL_STORAGE_EXT 0x9652 |
| |
| New Macro Definitions |
| |
| #define GL_EXT_shader_pixel_local_storage2 1 |
| |
| New Built-in Variables |
| |
| None |
| |
| Changes to the OpenGL ES 3.0 Specification, Chapter 3 |
| |
| In Section 3.9.2, at the end of the last sub-section ("Shader Outputs"), |
| modify the three paragraphs added by GL_EXT_shader_pixel_local_storage, |
| such that it reads: |
| |
| "Fragment data values may also be written to pixel local storage blocks. |
| These values are available for reading in subsequent shader invocations |
| covering the same pixel. Data values written to pixel local storage block |
| members are converted to the storage format specified in the shader. |
| |
| If GL_EXT_shader_pixel_local_storage2 is supported a shader may write |
| to both user-defined fragment outputs and to pixel local storage blocks. |
| |
| If GL_EXT_shader_pixel_local_storage2 is not supported and a shader |
| writes to any user-defined fragment output, the pixel local storage values |
| for that fragment are lost, and their values in subsequent shader |
| invocations are undefined. Similarly, if a shader writes to pixel local |
| storage blocks, the value of the framebuffer pixel covered by that fragment |
| becomes undefined." |
| |
| Changes to the OpenGL ES 3.0 Specification, Chapter 4 |
| |
| In Section 4.1.7 ("Blending"), modify the paragraph added by GL_EXT_shader- |
| _pixel_local_storage to read: |
| |
| "Blending only applies to user-defined fragment outputs. No blending is |
| performed for outputs to pixel local storage blocks. If the fragment |
| shader outputs only to pixel local storage blocks, proceed to the next |
| operation." |
| |
| In Section 4.1.9 ("Dithering), modify the paragraph added by GL_EXT_shader- |
| _pixel_local_storage to read: |
| |
| "Dithering only applies to user-defined fragment outputs. No dithering |
| is performed on outputs to pixel local storage blocks." |
| |
| In Section 4.2.3 ("Clearing the Buffers") add the following: |
| |
| "The command |
| |
| void ClearPixelLocalStorageuiEXT(sizei offset, sizei n, const uint *values); |
| |
| clears a consecutive region of the pixel local storage to a specified set |
| of values. <offset> is the start offset of the region in 32-bit words. <n> |
| is the number of 32-bit words to clear. <values> is an array of <n> 32-bit |
| words that specifies the values the pixel local storage should be cleared |
| to. The words in <n> are packed with the first component in the least |
| significant bits of the word. The most significant bit of each component is |
| packed in the most significant bit location of its location in the word. If |
| <values> is NULL, all pixel local storage in the supplied range has every |
| bit set to 0. |
| |
| Clearing the pixel local storage will clear all values stored in the |
| specified range. This will have the effect of making the value of any user- |
| defined fragment output in this range undefined. Applications can determine |
| the fragment output or pixel local storage variables the range |
| corresponds to by the locations declared in the shader and by the storage |
| sizes described in section 4.3.8.2 ("Output Layout Qualifiers") of the |
| OpenGL ES Shading Language Specification. Further, an implementation is |
| required to allocate variables in storage the following order: pixel local |
| variables first, then fragment outputs. |
| |
| When ClearPixelLocalStorageuiEXT is called, no per-fragment operations or |
| mask operations are applied. |
| |
| An INVALID_VALUE error will be generated if the sum of <offset> and <n> |
| exceeds the total amount pixel local storage available to a shader. An |
| INVALID_OPERATION error will be generated if ClearPixelLocalStorageuiEXT is |
| called while pixel local storage is disabled." |
| |
| Replace Section 4.4.3 ("Enabling pixel local storage") with the following: |
| |
| "4.4.3 Enabling pixel local storage |
| |
| Fragment shaders have access to pixel local storage blocks, but this access |
| must be enabled prior to use and disabled after use. |
| |
| Pixel local storage for the current draw framebuffer is enabled by calling |
| Enable with SHADER_PIXEL_LOCAL_STORAGE_EXT. |
| |
| The content of the pixel local storage for a pixel is initially undefined. |
| |
| The contents of the pixel local storage persist until color data is flushed |
| to the framebuffer. After such an event, data in the pixel local storage |
| is lost and the contents are undefined. Events that cause a flush include: |
| * calling the GL commands Flush, Finish, and ClientWaitSync |
| * calling commands such as TexSubImage2D, CopyTexSubImage2D, and |
| BlitFramebuffer to update a texture that is also attached to the current |
| draw framebuffer while pixel local storage is enabled |
| * disabling pixel local storage by calling Disable with SHADER_PIXEL_- |
| LOCAL_STORAGE_EXT. |
| |
| If pixel local storage is not enabled, an INVALID_OPERATION error will be |
| generated if any rendering command is issued while a program object that |
| accesses pixel local storage is bound. |
| |
| While pixel local storage is enabled, an INVALID_OPERATION error will be |
| generated if any of the current draw framebuffer's attachment points are |
| modified, including changes to the underlying storage backing of objects |
| attached to these attachment points. An INVALID_OPERATION error will also |
| be generated on attempts to bind a different framebuffer object, to delete |
| the currently bound draw framebuffer, or change color buffer selection via |
| DrawBuffers while pixel local storage is enabled. |
| |
| Pixel local storage is not supported in combination with multisample |
| rasterization. Attempting to enable pixel local storage while the value of |
| SAMPLE_BUFFERS is one will generate an INVALID_OPERATION error. |
| |
| An INVALID_FRAMEBUFFER_OPERATION error will be generated when attempting to |
| enable pixel local storage while the current draw framebuffer is incomplete. |
| |
| The maximum number of bytes of pixel local storage available to a shader is |
| specified by the value of the implementation-dependent constant MAX_- |
| SHADER_PIXEL_LOCAL_STORAGE_SIZE_EXT. A compile-time error will be generated |
| if an attempt is made to utilize more than the space available for pixel |
| local storage variables. An implementation may choose to subdivide the |
| amount of pixel local storage into a region for fast access and a region |
| for normal access. As many pixel local storage variables as possible will |
| be stored, in order of declaration, in the fast region before any variables |
| will be allocated in the normal region. The number of bytes available for |
| fast access is specified by the value of the implementation-dependent |
| constant MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT. This value will |
| always be less than or equal to the total amount of pixel local storage. |
| |
| The maximum number of bytes of combined storage per pixel available to a |
| shader is specified by the value of the implementation-dependent constant |
| MAX_SHADER_COMBINED_LOCAL_STORAGE_SIZE_EXT. This value is the combined |
| storage of color attachments and pixel local storage. A compile-time error |
| will be generated if an attempt is made to utilize more than the combined |
| space for local storage. An INVALID_OPERATION error is generated by any |
| command that draws geometry if the combined storage required for the |
| current draw framebuffer and the pixel local storage of the current program |
| is greater than this value. As for the total amount of pixel local storage, |
| an implementation may choose to subdivide the amount of combined storage |
| into a region for fast access and a region for normal access. The number of |
| bytes available for fast access is specified by the value of the |
| implementation-dependent constant MAX_SHADER_COMBINED_LOCAL_STORAGE_FAST_- |
| SIZE_EXT. This value will always be less than or equal to the total amount |
| of combined storage." |
| |
| Pixel local storage is disabled by calling Disable with SHADER_PIXEL_- |
| LOCAL_STORAGE_EXT. |
| |
| In the initial state, SHADER_PIXEL_LOCAL_STORAGE_EXT is disabled. |
| |
| If EXT_shader_pixel_local_storage2 is to be used, then the amount of pixel |
| local storage must be known to the framebuffer before pixel local storage |
| is enabled, similar to a framebuffer attachment. |
| |
| The command |
| |
| void FramebufferPixelLocalStorageSizeEXT(uint target, sizei size); |
| |
| specifies the amount of storage required for pixel local variables whilst |
| SHADER_PIXEL_LOCAL_STORAGE_EXT is enabled. <target> specifies the |
| framebuffer that is modified by this function. <size> determines the size, |
| in bytes, required for pixel local storage. An INVALID_VALUE error is |
| generated if <size> is greater than MAX_SHADER_PIXEL_LOCAL_STORAGE_SIZE_- |
| EXT, or if it is not a multiple of 4. An INVALID_OPERATION error is |
| generated if an application tries to call this function whilst SHADER_- |
| PIXEL_LOCAL_STORAGE_EXT is enabled. |
| |
| The amount of storage required for pixel local variables can be |
| determined by the storage sizes described in section 4.3.8.2 ("Output |
| Layout Qualifiers") of the OpenGL ES Shading Language Specification. |
| |
| If the default framebuffer is bound to <target>, then calling this |
| function does not affect framebuffer completeness. |
| |
| The command |
| |
| sizei GetFramebufferPixelLocalStorageSizeEXT(uint target); |
| |
| returns the size of pixel local storage previously set on the framebuffer |
| bound to <target> by FramebufferPixelLocalStorageSizeEXT." |
| |
| Add the following to the list of framebuffer complete conditions in |
| sub-section "Whole Framebuffer Completeness" in section 4.4.4: |
| |
| " - The amount of pixel local storage specified by |
| FramebufferPixelLocalStorageSizeEXT is zero, or the combined size of |
| pixel local storage and fragment outputs is less than MAX_SHADER_- |
| COMBINED_LOCAL_STORAGE_SIZE_EXT. |
| |
| { FRAMEBUFFER_INCOMPLETE_INSUFFICIENT_SHADER_COMBINED_LOCAL_STORAGE_EXT }" |
| |
| Add the following to the list of functions that can affect framebuffer |
| completeness sub-section "Whole Framebuffer Completeness" in section 4.4.4: |
| |
| " - Changing the size of shader pixel local storage with |
| FramebufferPixelLocalStorageSizeEXT." |
| |
| Errors |
| |
| Remove the following error added in EXT_shader_pixel_local_storage: |
| |
| INVALID_OPERATION is generated if the application attempts to enable pixel |
| local storage while the current draw framebuffer is a user-defined frame- |
| buffer object and has an image attached to any color attachment other than |
| color attachment zero. |
| |
| Add the following errors: |
| |
| INVALID_VALUE is generated by ClearPixelLocalStorageuiEXT if the sum of |
| <offset> and <n> exceeds the total amount pixel local storage available to a |
| shader. |
| |
| INVALID_OPERATION is generated if ClearPixelLocalStorageuiEXT is called while |
| pixel local storage is disabled. |
| |
| INVALID_OPERATION is generated by any command that draws geometry if the |
| combined storage required for the current draw framebuffer and the pixel |
| local storage of the current program is is greater than the value of MAX_- |
| SHADER_COMBINED_LOCAL_STORAGE_SIZE_EXT. |
| |
| New State |
| |
| Add to Table 6.13 Framebuffer (state per framebuffer object) |
| |
| State Type Get Command Initial Value Description Sec. |
| --------------- ---- ------------ ------------- ----------- ----- |
| Z+ GetFramebuffer- 0 Amount of pixel 4.4.3 |
| PixelLocal- local storage |
| StorageSizeEXT specified for |
| the framebuffer. |
| |
| New Implementation Dependent State |
| |
| Add to Table 6.32 Implementation Dependent Fragment Shader Limits |
| |
| State Type Get Command Minimum Value Description Sec. |
| --------------- ---- ------------ ------------- ----------- ----- |
| MAX_SHADER_COMBINED- Z+ GetIntegerv 16 Amount of fast 4.4.3 |
| LOCAL_STORAGE_FAST- storage in units |
| _SIZE_EXT of bytes available |
| for per-pixel |
| storage. |
| |
| MAX_SHADER_COMBINED- Z+ GetIntegerv 16 Amount of total 4.4.3 |
| LOCAL_STORAGE_SIZE- storage in units |
| _EXT of bytes available |
| for per-pixel |
| storage. |
| |
| Additions to Chapter 4 ("Variables and Types") of the OpenGL ES Shading Language Specification |
| |
| Replace section "4.3.7 Pixel Local Variables" with the following: |
| |
| "4.3.7 Pixel Local Variables |
| |
| The __pixel_localEXT, __pixel_local_inEXT, and __pixel_local_outEXT, |
| qualifiers are used to declare variables whose values are persistent across |
| fragment shader invocations covering the same pixel, collectively referred |
| to as pixel local variables. Pixel local variables do not have any backing |
| store allocated through the OpenGL API and are not accessible to the API. |
| |
| Variables declared with the __pixel_localEXT qualifier can be read and |
| written from the same fragment shader invocation. Variables declared with |
| the __pixel_local_inEXT qualifier can only be read. Variables declared |
| with the __pixel_local_outEXT qualifier can only be written. |
| |
| Pixel local storage variable reads and writes within a single shader |
| invocation are processed in order. |
| |
| It is legal for a shader to write to both user-defined fragment outputs and |
| pixel local storage variables. |
| |
| Pixel local storage variables may not have initializers and their contents |
| are undefined until written to from a shader or initialized via the API. If |
| a pixel local storage variable is not written to in a fragment shader, the |
| value of that variable is undefined unless it was declared as part of a |
| __pixel_localEXT block. |
| |
| Pixel local storage variables may be qualified with layout qualifiers |
| affecting how the values are stored in and retrieved from the underlying |
| storage, as described in section 4.3.8.4 "Pixel Local Block Layout |
| Qualifiers". |
| |
| When reading from a pixel local storage variable, the in-storage value is |
| implicitly converted from the storage format specified by the layout |
| qualifier to the variable type. Similarly, when writing to a pixel local |
| storage variable, the value of the member is implicitly converted to the |
| storage format specified by the layout qualifier. |
| |
| Pixel local storage variables may only be declared inside interface blocks |
| (section 4.3.7, "Interface Blocks"), which are then referred to as shader |
| pixel local storage blocks. It is a compile-time error to declare pixel |
| local storage variables at global scope (outside a block). |
| |
| Pixel local storage blocks must be declared at global scope. |
| |
| Pixel local storage variables declared inside pixel local storage |
| blocks will be laid out in local storage in monotonically increasing order |
| based on their location in the declaration. All pixel local variables |
| consume integer multiples of 4 bytes, as specified in section 4.3.8.4. |
| |
| Pixel local storage blocks may be allocated from the same storage as any |
| user-defined color outputs, but do not alias. Writing to pixel local |
| variables has no effect on any user-defined outputs, and pixel local |
| variables are not affected by writes to any user-defined outputs. |
| |
| A shader may only declare a single input and a single output pixel local |
| storage block. A pixel local storage block declared using the __pixel_- |
| localEXT qualifier is counted as both an input and an output block. Thus, |
| it is a compile-time error for a shader to declare more than one pixel |
| storage block, with the exception that it is legal to declare one pixel |
| local storage block using the __pixel_local_inEXT qualifier and one with |
| the __pixel_local_outEXT qualifier. |
| |
| Modify the start of Section 4.3.7 (Interface Blocks) to read: |
| |
| "Uniform and pixel local storage variable declarations can be grouped into |
| named interface blocks to provide coarser granularity backing than is |
| achievable with individual declarations. They can have an optional instance |
| name, used in the shader to reference their members. A uniform block is |
| backed by the application with a buffer object. A block of pixel local |
| storage variables is not backed by any object. |
| |
| GLSL ES 3.0 does not support interface blocks for shader inputs or outputs. |
| |
| An interface block is started by a uniform or pixel local keyword, followed |
| by a block name, followed by an open curly brace ( { ) as follows: |
| |
| interface-block: |
| layout-qualifieropt interface-qualifier block-name { member-list } instance-nameopt; |
| |
| interface-qualifier: |
| in |
| out |
| uniform |
| __pixel_localEXT |
| __pixel_local_inEXT |
| __pixel_local_outEXT |
| " |
| |
| Modify the sentence: |
| "Repeating the uniform interface qualifier for a member's storage qualifier |
| is optional." |
| To read: |
| "Repeating the uniform, __pixel_localEXT, __pixel_local_inEXT, or |
| __pixel_local_outEXT interface qualifier for a member's storage qualifier |
| is optional." |
| |
| Add a new paragraph after the one starting with: |
| "For uniform blocks, the application uses the block name to identify the |
| block." |
| That reads: |
| "For __pixel_localEXT, __pixel_local_inEXT, and __pixel_local_outEXT storage |
| blocks, the block name is not used." |
| |
| In section 4.3.8.2, "Output Layout Qualifiers", add the following to the |
| list of layout qualifiers applicable to fragment outputs only: |
| |
| layout-qualifier-id |
| float-output-format-qualifier |
| int-output-format-qualifier |
| uint-output-format-qualifier |
| generic-output-format-qualifier |
| |
| float-pixel-local-format-qualifier |
| rgb565 |
| r8 |
| rg8 |
| rgb8 |
| rgba8 |
| srgb8_a8 |
| rgb5_a1 |
| rgba4 |
| rgb10_a2 |
| |
| [[ Only if EXT_color_buffer_float is supported ]] |
| r32f |
| rg32f |
| r11f_g11f_b10f |
| rgba32f |
| |
| [[ Only if EXT_color_buffer_half_float or EXT_color_buffer_float is supported ]] |
| r16f |
| rg16f |
| rgba16f |
| |
| [[ Only if EXT_color_buffer_half_float is supported ]] |
| rgb16f |
| |
| int-pixel-local-format-qualifier |
| r8i |
| r16i |
| r32i |
| rg8i |
| rg16i |
| rg32i |
| rgba8i |
| rgba16i |
| rgba32i |
| |
| uint-pixel-local-format-qualifier |
| r8ui |
| r16ui |
| r32ui |
| rg8ui |
| rg16ui |
| rg32ui |
| rgba8ui |
| rgb10_a2ui |
| rgba16ui |
| rgba32ui |
| |
| generic-output-format-qualifier |
| implementation_defined |
| |
| Add the following paragraphs to the end of this section: |
| |
| "The output format qualifiers are optional and must be enabled by calling |
| |
| #extension GL_EXT_shader_pixel_local_storage2: <behavior> |
| |
| before use, where <behavior> is as specified in section 3.4. |
| |
| Each output-format-qualifier specifies the format which each of the |
| user-defined fragment outputs is stored at the end of shader execution. |
| The values are packed to the specified format and stored as raw bits in |
| fragment output storage. |
| |
| By default, the format for each output is set to "implementation_defined", |
| and the underlying implementation will make a decision about how to |
| store it. If any output is set to a format other than implementation_- |
| defined, all formats must be specified. |
| |
| The output-format-qualifier format must match the base type and the |
| number of components of the variable declaration. It is a compile-time |
| error to declare a user-defined output variable where the format qualifier |
| does not match the variable type and the number of components. |
| |
| If EXT_pixel_local_storage2 is enabled, the format of every user-defined |
| fragment output variable should be specified in order to use pixel local |
| storage blocks. Any outputs set as implementation_defined (the default) |
| behave as if consuming all available local storage, leaving no space for |
| pixel local variables, causing a compile time error if pixel local storage |
| blocks also exist in the shader. |
| |
| The specified output-format-qualifier does not need to be constant |
| between shader invocations, but any resolves to the final framebuffer will |
| treat the data as being of the format specified on the active frame- |
| buffer's color attachment rather than the shader defined format. This |
| implies that color attachment values are undefined if the format of the |
| color attachment does not match the format specified in the shader. The |
| number of user-defined outputs and the size specified by their format |
| qualifier must remain consistent between shader invocations, or the values |
| will be undefined. |
| |
| Each user-defined fragment output variable uses memory local to the |
| shading processor. Each format takes up a predetermined number of bytes |
| of storage, as specified in the table below. |
| |
| |----------------|-------| |
| | Format | Bytes | |
| |----------------|-------| |
| | r8 | 4 | |
| | r8ui | 4 | |
| | r8i | 4 | |
| | r16ui | 4 | |
| | r16i | 4 | |
| | r32ui | 4 | |
| | r32i | 4 | |
| | rg8 | 4 | |
| | rg8ui | 4 | |
| | rg8i | 4 | |
| | rg16ui | 4 | |
| | rg16i | 4 | |
| | rg32ui | 8 | |
| | rg32i | 8 | |
| | rgb8 | 4 | |
| | rgb565 | 4 | |
| | rgba8 | 4 | |
| | srgb8_a8 | 4 | |
| | rgb5_a1 | 4 | |
| | rgba4 | 4 | |
| | rgb10_a2 | 4 | |
| | rgba8ui | 4 | |
| | rgba8i | 4 | |
| | rgb10_a2ui | 4 | |
| | rgba16ui | 8 | |
| | rgba16i | 8 | |
| | rgba32ui | 16 | |
| | rgba32i | 16 | |
| | r32f | 4 | |
| | rg32f | 8 | |
| | r11f_g11f_b10f | 4 | |
| | rgba32f | 16 | |
| | r16f | 4 | |
| | rg16f | 4 | |
| | rgb16f | 8 | |
| | rgba16f | 8 | |
| |----------------|-------| |
| |
| The total amount of memory used by a pixel local storage block or a user- |
| defined fragment output can be determined by the size of each variable's |
| format as in the equation below. n is the number of pixel local storage |
| members or output variables in each case. |
| |
| n |
| \¯ |
| /_ i = sizeof(format-qualifier) |
| i=0 |
| |
| The total combined amount of memory used by fragment outputs and pixel |
| local storage can be worked out simply via the following: |
| |
| total memory = sizeof(pixel local storage) + sizeof(fragment outputs)" |
| |
| The total number of bytes of fragment output local storage available is |
| specified by the value of the implementation-dependent constant |
| gl_MaxShaderCombinedLocalStorageSizeEXT. A compile-time error will be |
| generated if the declared outputs use more storage than this value. |
| |
| An implementation may choose to subdivide the amount of local storage into |
| a region for fast access and a region for normal access. As many local |
| variables as possible are allocated into the fast access region before any |
| are allocated into the normal access. Pixel local variables are |
| prioritized and are fully allocated into combined local storage before any |
| fragment output variables are allocated. The number of total bytes |
| available for fast access is specified by the value of the implementation- |
| dependent constant gl_MaxShaderCombinedLocalStorageFastSizeEXT. This value |
| will always be less than or equal to the total amount of combined local |
| storage." |
| |
| In Section 4.3.8.4 ("Pixel Local Block Layout Qualifiers"), add the following |
| |
| (add the following to the list of layout qualifiers for pixel local storage |
| variables) |
| float-pixel-local-format-qualifier |
| rg32f |
| rgba32f |
| rgba16f |
| |
| int-pixel-local-format-qualifier |
| rgba16i |
| r32i |
| rg32i |
| rgba32i |
| |
| uint-pixel-local-format-qualifier |
| rg32ui |
| rgba16ui |
| rgba32ui |
| |
| (add to the end of the description of the pixel local block layout qualifiers) |
| |
| "The size of each pixel local format qualifier is equivalent to that |
| specified for the output format qualifiers in section 4.3.8.2." |
| |
| Additions to Chapter 6 of the OpenGL ES Shading Language Specification |
| |
| In Section 6.4 (Jumps), change the sentence about the discard keyword that |
| currently reads: |
| |
| 'This keyword causes the fragment to be discarded and no updates to the |
| framebuffer will occur.' |
| |
| to: |
| |
| 'This keyword causes the fragment to be discarded and no updates to the |
| framebuffer or any pixel local storage variables will occur.' |
| |
| Additions to Chapter 7 of the OpenGL ES Shading Language Specification |
| |
| In Section 7.3 (Built-In Constants), add new entries: |
| |
| const mediump int gl_MaxShaderCombinedLocalStorageFastSizeEXT = 16 |
| const mediump int gl_MaxShaderCombinedLocalStorageSizeEXT = 16 |
| |
| Examples |
| (1) G-buffer creation pass |
| |
| #version 300 es |
| #extension GL_EXT_shader_pixel_local_storage2 : enable |
| |
| varying vec2 coord; |
| varying vec3 normal; |
| uniform sampler2D albedo_metallicness_texture; |
| uniform sampler2D roughness_texture; |
| |
| uniform float roughness; |
| uniform float albedo; |
| uniform vec3 metallicness; |
| |
| __pixel_localEXT FragDataLocal { |
| layout (r32f) highp float depth; |
| layout (rgba8ui) highp vec4 normal_roughness; |
| layout (rgba8ui) highp vec4 albedo_metallicness; |
| } gbuf; |
| |
| void main() |
| { |
| // Write to pls values |
| gbuf.depth = gl_FragCoord.z; |
| gbuf.normal_roughness = vec4(normal, texture2d(roughness_texture).r); |
| gbuf.albedo_metallicness = texture2d(albedo_metallicness_texture, coord); |
| } |
| |
| (2) Light accumulation step (multiple lights can hit the same pixel) |
| |
| #version 300 es |
| #extension GL_EXT_shader_pixel_local_storage2 : enable |
| |
| uniform vec4 light_position; |
| |
| __pixel_localEXT FragDataLocal { |
| layout (r32f) highp float depth; |
| layout (rgba8ui) highp vec4 normal_roughness; |
| layout (rgba8ui) highp vec4 albedo_metallicness; |
| } gbuf; |
| |
| layout(location = 0, rgba10_a2) out highp vec4 accumulationBuffer; |
| |
| void main() |
| { |
| // Accumulate to the accumulationBuffer, without invalidating the pls data |
| accumulationBuffer = do_lighting(gbuf.depth, gbuf.normal_roughness, gbuf.albedo_metallicness, light_position); |
| } |
| |
| Issues |
| |
| (1) Should there be a way to dumping the PLS contents to memory for |
| debugging purposes? |
| |
| RESOLVED: Not in this extension. |
| |
| A couple of ways this could be supported: |
| A) Reuse ReadPixels. Allow a new combination of <format> and <type> |
| parameters, say, "SHADER_PIXEL_LOCAL_STORAGE" and UNSIGNED_INT. |
| B) Add a new function, say glReadPixelLocalStorage. This would be |
| as the above, except that the <format> and <type> parameters |
| would be implicit. |
| |
| Either approach would probably need a query function to determine |
| the amount of storage used, or a way to specify the amount of storage |
| to retrieve. |
| |
| (2) How are local storage values initialized? |
| |
| RESOLVED: Using ClearPixelLocalStorageuiEXT. |
| |
| EXT_shader_pixel_local_storage stated: |
| "All pixel local storage variables are guaranteed to be zero if |
| all color components of the framebuffer are set to zero." |
| |
| But with this extension, color data and pixel local storage are |
| distinct, so while this guarantee could be made, it may not be the |
| most efficient approach. |
| |
| This is solved by adding an explicit API: ClearPixelLocalStorageuiEXT. |
| |
| (3) Is the proposed resolution to (2) a compatibility break with EXT_- |
| shader_pixel_local_storage? |
| |
| RESOLVED: No. |
| |
| EXT_shader_pixel_local_storage guaranteed that the pixel local |
| storage was initialized to zero if all color components of the |
| framebuffer were set to zero. Given that this only applied to the |
| aliased pixel local storage in the original extension, and aliasing |
| is no longer present, the resolution is not a compatibility break, |
| as the spec itself is a compatibility break. |
| |
| (4) Do we need to know the render target count at compile time? |
| |
| RESOLVED. |
| |
| Yes. Implementations will need to know the render target count and |
| the storage size of each render target in order to allocate and |
| partition the pixel local storage. |
| |
| (5) Do we want to explicitly alias some pixel local storage variables onto |
| color rendertargets? |
| |
| RESOLVED. |
| |
| See Issue 7. |
| |
| (6) Should the maximum PLS storage queries be per framebuffer? |
| |
| RESOLVED: No - glGetInteger with a MAX_COMBINED_LOCAL_STORAGE_SIZE. |
| |
| Dynamic, per framebuffer, queries will have all necessary information, |
| but applications can not access this information until the framebuffer |
| object has been created, which seems undesirable. |
| |
| EXT_shader_pixel_local_storage specified static queries for the |
| amount of available pixel local storage. With this extension, the |
| semantics of that query changes since color and pixel local storage |
| no longer alias. Given that change, we need a query for the |
| total amount of storage available for pixel local storage and color |
| attachments. |
| |
| (7) Do we want to keep the aliasing of pixel local storage variables onto |
| color rendertargets? |
| |
| RESOLVED: No |
| |
| The main benefit of aliasing was that it potentially allows more (fast) |
| local storage. Instead of sharing the local storage between color |
| render targets and pixel local storage variables, all local storage can |
| be allocated to pixel local storage initially. In this case, we expect |
| all pixel local storage to be resolved (and become undefined) when any |
| user-defined color output is written to (and vice versa). |
| |
| However, given the existance (and support) of framebuffer fetch, it |
| seems unnecessary to continue using this - the same effect can be |
| achieved with side-by-side framebuffer fetch and pixel local storage, |
| without the drawback of requiring explicit resolves. |
| |
| (8) Do we want the full range of framebuffer formats to work with this |
| extension? If so, how do we define the sizes of, say rgb565? Does it |
| take up 16bits or is it assumed to be padded to 32 bits? |
| |
| RESOLVED: Add all formats, but storage for all formats is padded |
| to multiples of 32-bits. |
| |
| (9) Do the usual per-fragment operations apply to color outputs in this |
| extension? |
| |
| RESOLVED: Yes. All values written to user-defined color outputs pass |
| through per-fragment operations (including blending, alpha to coverage, |
| etc.) as normal. |
| |
| Revision History |
| |
| Revision 0.13, 28/10/2015 (Tobias Hector) |
| Added enumerant values |
| |
| Revision 0.12, 08/10/2015 (Tobias Hector) |
| Added PLS interactions with the discard keyword. |
| |
| Revision 0.11, 07/10/2015 (Tobias Hector) |
| Specified that PLS variables are undefined if they're not written to, |
| unless they were defined as both input and output (in which case they |
| are preserved). |
| |
| Revision 0.10, 13/07/2015 (Tobias Hector) |
| Re-added error about multisampled rendering |
| |
| Revision 0.9, 10/07/2015 (Tobias Hector) |
| Corrected ClearPixelLocalStorageuiEXT to accept a uint value, instead of int |
| Changed language about combined local storage to be clearer. |
| |
| Revision 0.8, 03/07/2015 (Tobias Hector) |
| Added wording that disallows the default framebuffer becoming incomplete. |
| Added language allowing NULL to be passed into ClearPixelLocalStorageuiEXT |
| Added word alignment to size parameter of FramebufferPixelLocalStorageSizeEXT |
| |
| Revision 0.7, 02/07/2015 (Tobias Hector) |
| Folded in updates from external review. |
| Added interactions with EXT_color_buffer_float and half_float |
| Added multi-word pixel local storage formats |
| Added framebuffer pixel local storage size specification |
| Added framebuffer completeness checks |
| Updated issues list to match updated spec. |
| |
| Revision 0.6, 03/10/2014 (Jan-Harald Fredriksen) |
| Extended padding for all color outputs to 4 bytes. |
| Resolved and updated proposed resolutions for several issues. |
| Added Issue 10 and Issue 11. |
| |
| Revision 0.5, 25/09/2014 (Jan-Harald Fredriksen) |
| Integrated a subset of IMG_fragment_output_format. |
| |
| Revision 0.4, 20/06/2014 (Jan-Harald Fredriksen) |
| Minor wording changes. |
| |
| Revision 0.3, 27/05/2014 (Jan-Harald Fredriksen) |
| Adding Issue 7. |
| |
| Revision 0.2, 18/05/2014 (Jan-Harald Fredriksen) |
| Adding some issues and a new query. |
| |
| Revision 0.1, 21/03/2014 (Jan-Harald Fredriksen) |
| Second internal draft. |
| Adding missing changes compared to EXT_shader_pixel_local_storage. |
| Added proposed resolution of Issue 1. |
| Added Issue 2, Issue 3, and Issue 4. |
| |
| Revision 0, 19/11/2013 (Jan-Harald Fredriksen) |
| First internal draft. |