1Name 2 3 NV_shader_texture_footprint 4 5Name Strings 6 7 GL_NV_shader_texture_footprint 8 9Contact 10 11 Chris Lentini, NVIDIA (clentini 'at' nvidia.com) 12 Pat Brown, NVIDIA (pbrown 'at' nvidia.com) 13 14Contributors 15 16 Jeff Bolz, NVIDIA 17 Daniel Koch, NVIDIA 18 19Status 20 21 Shipping 22 23Version 24 25 Last Modified Date: February 8, 2018 26 NVIDIA Revision: 2 27 28Number 29 30 OpenGL Extension #530 31 OpenGL ES Extension #313 32 33Dependencies 34 35 This extension is written against the OpenGL 4.6 Specification 36 (Compatibility Profile), dated July 30, 2017. 37 38 OpenGL 4.5 or OpenGL ES 3.2 is required. 39 40 This extension requires support for the OpenGL Shading Language (GLSL) 41 extension "NV_shader_texture_footprint", which can be found at the Khronos 42 Group Github site here: 43 44 https://github.com/KhronosGroup/GLSL 45 46Overview 47 48 This extension adds OpenGL API support for the OpenGL Shading Language 49 (GLSL) extension "NV_shader_texture_footprint". That extension adds a new 50 set of texture query functions ("textureFootprint*NV") to GLSL. These 51 built-in functions prepare to perform a filtered texture lookup based on 52 coordinates and other parameters passed in by the calling code. However, 53 instead of returning data from the provided texture image, these query 54 functions instead return data identifying the _texture footprint_ for an 55 equivalent texture access. The texture footprint identifies a set of 56 texels that may be accessed in order to return a filtered result for the 57 texture access. 58 59 The footprint itself is a structure that includes integer values that 60 identify a small neighborhood of texels in the texture being accessed and 61 a bitfield that indicates which texels in that neighborhood would be used. 62 Each bit in the returned bitfield identifies whether any texel in a small 63 aligned block of texels would be fetched by the texture lookup. The size 64 of each block is specified by an access _granularity_ provided by the 65 shader. The minimum granularity supported by this extension is 2x2 (for 66 2D textures) and 2x2x2 (for 3D textures); the maximum granularity is 67 256x256 (for 2D textures) or 64x32x32 (for 3D textures). Each footprint 68 query returns the footprint from a single texture level. When using 69 minification filters that combine accesses from multiple mipmap levels, 70 shaders must perform separate queries for the two levels accessed ("fine" 71 and "coarse"). The footprint query also returns a flag indicating if the 72 texture lookup would access texels from only one mipmap level or from two 73 neighboring levels. 74 75 This extension should be useful for multi-pass rendering operations that 76 do an initial expensive rendering pass to produce a first image that is 77 then used as a texture for a second pass. If the second pass ends up 78 accessing only portions of the first image (e.g., due to visibility), the 79 work spent rendering the non-accessed portion of the first image was 80 wasted. With this feature, an application can limit this waste using an 81 initial pass over the geometry in the second image that performs a 82 footprint query for each visible pixel to determine the set of pixels that 83 it needs from the first image. This pass would accumulate an aggregate 84 footprint of all visible pixels into a separate "footprint texture" using 85 shader atomics. Then, when rendering the first image, the application can 86 kill all shading work for pixels not in this aggregate footprint. 87 88 The implementation of this extension has a number of limitations. The 89 texture footprint query functions are only supported for two- and 90 three-dimensional textures (TEXTURE_2D, TEXTURE_3D). Texture footprint 91 evaluation only supports the CLAMP_TO_EDGE wrap mode; results are 92 undefined for all other wrap modes. The implementation supports only a 93 limited set of granularity values and does not support separate coverage 94 information for each texel in the original texture. 95 96 97New Procedures and Functions 98 99 None 100 101New Tokens 102 103 None 104 105Additions to Chapter 8 of the OpenGL 4.6 (Compatibility Profile) Specification 106(Textures and Samplers) 107 108 (add a new section immediately after section 8.15, Texture Magnification) 109 110 Section 8.X, Texture Footprint Queries 111 112 The OpenGL Shading Language provides a collection of built-in functions, 113 all beginning with "textureFootprint", that allow shaders to query a 114 _texture footprint_. The texture footprint is a set of texels belonging 115 to a single texture level that would be accessed when performing a 116 filtered texture lookup. The shader code calling the footprint query 117 functions passes in a _granularity_ value, which is used to subdivide a 118 texture level into an array of fixed-size _texel groups_ whose size is 119 given by the granularity. The texture footprint query functions return 120 the footprint using a built-in GLSL data structure that identifies the set 121 of texel groups containing one or more texels that would be accessed in an 122 equivalent texture lookup. Texture footprint queries are only supported 123 for two- and three-dimensional textures (targets TEXTURE_2D and 124 TEXTURE_3D). Additionally, footprint queries require the use of the 125 CLAMP_TO_EDGE sampler wrap mode in all relevant dimensions; the results of 126 the footprint query are undefined if any other wrap mode is used. 127 128 Each texture footprint query built-in function accepts a set of texture 129 coordinates and any additional parameters (e.g., explicit level of detail, 130 level of detail bias, or derivatives) needed to specify a normal texture 131 lookup operation whose footprint should be evaluated. The footprint query 132 functions also accept a <granularity> parameter and a <coarse> flag used 133 to select the level of detail whose footprint is returned. The 134 granularity parameter identifies the size of the texel groups used for the 135 footprint query as described in Table X.1. The <coarse> flag is used to 136 select between the two levels of detail used when minifying using a filter 137 (NEAREST_MIPMAP_LINEAR, LINEAR_MIPMAP_LINEAR) that averages texels from 138 multiple levels of detail. When such minification is performed, a value 139 of "false" requests the footprint in the higher-resolution (fine) level of 140 detail, while "true" requests the footprint in the lower-resolution 141 (coarse) level of detail. When a texture access uses only a single level 142 of detail, its footprint will be returned for queries with <coarse> set to 143 false, while queries with <coarse> set to true will return an empty 144 footprint. Since many texture accesses may use only a single level, the 145 footprint query functions return a boolean value, which will be true if 146 and only if all accessed texels are in a single level of detail. 147 148 Granularity Value | TEXTURE_2D | TEXTURE_3D 149 ------------------+---------------+---------------- 150 0 | unsupported | unsupported 151 1 | 2x2 | 2x2x2 152 2 | 4x2 | unsupported 153 3 | 4x4 | 4x4x2 154 4 | 8x4 | unsupported 155 5 | 8x8 | unsupported 156 6 | 16x8 | unsupported 157 7 | 16x16 | unsupported 158 8 | unsupported | unsupported 159 9 | unsupported | unsupported 160 10 | unsupported | 16x16x16 161 11 | 64x64 | 32x16x16 162 12 | 128x64 | 32x32x16 163 13 | 128x128 | 32x32x32 164 14 | 256x128 | 64x32x32 165 15 | 256x256 | unsupported 166 167 Table X.1: Supported granularities for texture footprint queries, for 168 two-dimensional (TEXTURE_2D) and three-dimensional (TEXTURE_3D) 169 accesses. Granularity values not listed in the table or listed as 170 "unsupported" are not supported by this extension and result in 171 undefined behavior if used. 172 173 In addition to the boolean result, texture footprint queries return 174 footprint data in a structure of the type gl_TextureFootprint2DNV (for 175 two-dimensional textures) or gl_TextureFootprint3DNV (for 176 three-dimensional textures). In either structure, the member <lod> 177 specifies the level-of-detail number used for the footprint. The 178 members <anchor> and <offset> identify a small neighborhood of texel 179 groups in the texture used by the query. The member <mask> specifies 64 180 bits of data indicating which texel groups in the neighborhood are part 181 of the footprint. The member <granularity> returns information on the 182 size of the texel groups in the footprint, which is sometimes larger 183 than the requested granularity, as described below. 184 185 For two-dimensional footprint queries, the neighborhood returned by the 186 query is an 8x8 array of texel groups, where each texel group in 187 neighborhood is identified by a coordinate (x,y), where <x> and <y> are 188 integer values in the range [0,7]. Each texel group corresponds to a 189 set of texels whose (u,v) coordinates satisfy the inequalities: 190 191 u1 <= u <= u2 192 v1 <= v <= v2 193 194 computed using the following logic: 195 196 // The footprint logic returns a mask whose bits are aligned to 8x8 197 // sets of texel groups. This allows shaders to use atomics to 198 // efficiently accumulate footprint results across many invocations, 199 // storing an 8x8 array of bits for each group into one RG32UI texel. 200 // The texel group number in the neighborhood is treated as an offset 201 // relative to the anchor point. 202 uvec2 texel_group = 8 * result.anchor + uvec2(x,y); 203 204 // If the neighborhood crosses the boundaries of an 8x8 set, the bits 205 // of the mask are effectively split across multiple sets (up to 206 // four for 2D). The "offset" parameter returned by the query 207 // identifies which x/y group values in the neighborhood are 208 // assigned to which set. An all-zero offset indicates that the 209 // footprint is fully contained in a single 8x8 set at the anchor. 210 // "Low" x/y values identify texel groups at the beginning of the 8x8 211 // set identified by the anchor, while "high" values correspond to 212 // texel groups at the end of the previous set. The offset 213 // indicates the number of texel groups assigned to the previous set. 214 if (x + result.offset.x >= 8) { 215 texel_group.x -= 8; 216 } 217 if (y + result.offset.y >= 8) { 218 texel_group.y -= 8; 219 } 220 221 // Once we have a group number, u/v texel number ranges are generated by 222 // multiplying by the texel group size. 223 uint u1 = texel_group.x * granularity_x; 224 uint u2 = u1 + granularity_x - 1; 225 uint v1 = texel_group.y * granularity_y; 226 uint v2 = v1 + granularity_y - 1; 227 228 In the equations above, <granularity_x> and <granularity_y> refer to the 229 texel group size as in Table X.1. result.anchor and result.offset 230 specify the <anchor> and <offset> members of the returned structure, and 231 <x> and <y> specify the texel group number in the neighborhood. 232 233 Each bit in the <mask> member of the returned structure corresponds to 234 one of the texel groups in the 8x8 neighborhood. That bit will be set 235 if and only if any of the texels in the texel group is covered by the 236 footprint. The texel group (x,y) is considered to be covered if and 237 only if the following logic computes true for <covered>: 238 239 uint64_t mask = result.mask.x | (result.mask.y << 32); 240 uint32_t bit = y * 8 + x; 241 bool covered = (0 != ((mask >> bit) & 1)); 242 243 For three-dimensional footprint queries, the logic is very similar, 244 except that the neighborhood returned by the query is a 4x4x4 array of 245 texel groups. Each texel group in neighborhood is identified by a 246 coordinate (x,y,z), where <x>, <y>, and <z> are integer values in the 247 range [0,3]. Each texel group corresponds to a set of texels whose 248 (u,v,w) coordinates satisfy the inequalities: 249 250 u1 <= u <= u2 251 v1 <= v <= v2 252 w1 <= w <= w2 253 254 computed using the following logic: 255 256 uvec3 texel_group = 4 * result.anchor + uvec3(x,y,z); 257 if (x + result.offset.x >= 4) { 258 texel_group.x -= 4; 259 } 260 if (y + result.offset.y >= 4) { 261 texel_group.y -= 4; 262 } 263 if (z + result.offset.z >= 4) { 264 texel_group.z -= 4; 265 } 266 uint u1 = texel_group.x * granularity_x; 267 uint u2 = u1 + granularity_x - 1; 268 uint v1 = texel_group.y * granularity_y; 269 uint v2 = v1 + granularity_y - 1; 270 uint w1 = texel_group.z * granularity_z; 271 uint w2 = w1 + granularity_z - 1; 272 273 As in the two-dimensional logic, <granularity_x>, <granularity_y>, and 274 <granularity_z> refer to the texel group size as in Table X.1. 275 result.anchor and result.offset specify the <anchor> and <offset> 276 members of the returned structure, and <x>, <y>, and <z> specify the 277 texel group number in the neighborhood. 278 279 Each bit in the <mask> member of the returned structure corresponds to 280 one of the texel groups in the 4x4x4 neighborhood. That bit will be set 281 if and only if any of the texels in the texel group is covered by the 282 footprint. The texel group (x,y,z) is considered to be covered if and 283 only if the following logic computes true for <covered>: 284 285 uint64_t mask = result.mask.x | (result.mask.y << 32); 286 uint32_t bit = z * 16 + y * 4 + x; 287 bool covered = (0 != ((mask >> bit) & 1)); 288 289 In most cases, the texel group sizes used by the footprint query will 290 match the value passed to the query, as interpreted according to Table 291 X.1. However, in some cases, the footprint may be too large to be 292 expressed as a collection of 8x8 or 4x4x4 set of texel groups using the 293 requested granularity. In this case, the implementation uses a texel 294 group size that is larger than the requested granularity. If a larger 295 texel group size is used, the implementation will return the texel group 296 size used in the <granularity> member of the footprint structure, which 297 should also be interpreted according to Table X.1. If the requested 298 texel group size is used, the implementation will return zero in 299 <granularity>. The texel group size will only be increased by the 300 implementation if anisotropic filtering is used. If the texture and 301 sampler objects used by the footprint query do not enable anisotropic 302 texture filtering, the footprint query will always use the original 303 requested granularity and return zero in the <granularity> member. 304 305Errors 306 307 None 308 309New State 310 311 None 312 313New Implementation Dependent State 314 315 None 316 317Issues 318 319 None, but please refer to issues in the GLSL extension specification. 320 321Revision History 322 323 Revision 2 (pknowles) 324 - Add ES interactions. 325 326 Revision 1 (clentini, pbrown) 327 - Internal revisions. 328