• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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