• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Name
2
3    NV_memory_attachment
4
5Name Strings
6
7    GL_NV_memory_attachment
8
9Contributors
10
11    Carsten Rohde, NVIDIA
12    Christoph Kubisch, NVIDIA
13    James Jones, NVIDIA
14
15Contact
16
17    Carsten Rohde, NVIDIA (crohde 'at' nvidia.com)
18
19Status
20
21    Complete
22
23Version
24
25    Last Modified Date: Aug 27, 2018
26    Revision: 2
27
28Number
29
30    524
31    OpenGL ES Extension #305
32
33Dependencies
34
35    Requires GL_EXT_memory_object and ARB_texture_storage or a version of
36    OpenGL or OpenGL ES that incorporates it.
37
38    Written against the OpenGL 4.6 and OpenGL ES 3.2 specifications.
39
40    Interacts with ARB_direct_state_access (OpenGL) when OpenGL < 4.5 is used.
41
42    Interacts with NV_shader_buffer_load.
43
44    Interacts with NV_bindless_texture and ARB_bindless_texture.
45
46Overview
47
48    This extension extends the memory objects introduced with EXT_memory_object
49    to allow existing textures and buffers to be migrated to an imported memory
50    allocation.  The primary use-case of this extension is plug-in development
51    where resource management (creation, deletion, sizing etc.) is handled by
52    inaccessible host application code.
53
54New Procedures and Functions
55
56    If the GL_NV_memory_attachment string is reported, the following
57    commands are added:
58
59        void GetMemoryObjectDetachedResourcesuivNV(uint memory,
60                                                   enum pname,
61                                                   int first,
62                                                   sizei count,
63                                                   uint *params)
64
65        void ResetMemoryObjectParameterNV(uint memory,
66                                          enum pname);
67
68        void TexAttachMemoryNV(enum target,
69                               uint memory,
70                               uint64 offset);
71
72        void BufferAttachMemoryNV(enum target,
73                                  uint memory,
74                                  uint64 offset);
75
76        [[ The following are added if direct state access is supported ]]
77
78        void TextureAttachMemoryNV(uint texture,
79                                   uint memory,
80                                   uint64 offset);
81
82        void NamedBufferAttachMemoryNV(uint buffer,
83                                       uint memory,
84                                       uint64 offset);
85
86New Tokens
87
88    If the GL_NV_memory_attachment string is reported, the following tokens
89    are added:
90
91    Accepted by the <pname> parameter of TexParameter{ifx}{v},
92    TexParameterI{i ui}v, TextureParameter{if}{v}, TextureParameterI{i ui}v,
93    GetTexParameter{if}v, GetTexParameterI{i ui}v, GetTextureParameter{if}v,
94    GetTextureParameterI{i ui}v, GetBufferParameter{i|i64}v and
95    GetNamedBufferParameter{i|i64}v:
96
97      ATTACHED_MEMORY_OBJECT_NV           0x95A4
98      ATTACHED_MEMORY_OFFSET_NV           0x95A5
99      MEMORY_ATTACHABLE_ALIGNMENT_NV      0x95A6
100      MEMORY_ATTACHABLE_SIZE_NV           0x95A7
101      MEMORY_ATTACHABLE_NV                0x95A8
102
103    Accepted by the <pname> parameter of GetBooleanv, GetDoublev, GetFloatv,
104    GetIntegerv, GetInteger64v, GetUnsignedBytevEXT,
105    GetMemoryObjectParameterivEXT, and the <target> parameter of GetBooleani_v,
106    GetIntegeri_v,GetFloati_v, GetDoublei_v, GetInteger64i_v and
107    GetUnsignedBytei_vEXT:
108
109      DETACHED_MEMORY_INCARNATION_NV      0x95A9
110
111    Accepted by the <pname> parameter of GetMemoryObjectParameterivEXT,
112    GetMemoryObjectDetachedResourcesuivNV and ResetMemoryObjectParameterNV:
113
114      DETACHED_TEXTURES_NV                0x95AA
115      DETACHED_BUFFERS_NV                 0x95AB
116
117    Accepted by the <pname> parameter of MemoryObjectParameterivEXT,
118    GetMemoryObjectParameterivEXT:
119
120      MAX_DETACHED_TEXTURES_NV            0x95AC
121      MAX_DETACHED_BUFFERS_NV             0x95AD
122
123
124Additions to Chapter 6 of the EXT_external_objects Specification
125(Memory Objects)
126
127    Add a new sections after 6.2 (Memory object parameters)
128
129        6.3 Attaching memory to existing resources
130
131        MEMORY_ATTACHABLE_NV should be used to query if it is valid to attach
132        a memory object to an existing resource (buffer or texture).  The
133        memory region size and offset alignment required by a resource can be
134        queried using MEMORY_ATTACHABLE_SIZE_NV and
135        MEMORY_ATTACHABLE_ALIGNMENT_NV respectively.  The current attached
136        memory object and the used offset for a resource can be queried by
137        ATTACHED_MEMORY_OBJECT_NV and ATTACHED_MEMORY_OFFSET_NV.
138
139        If a resource which has memory attached is resized, the attached memory
140        will be detached and a new data store will be allocated.  If a resource
141        which has memory attached is deleted, the attached memory will first be
142        detached.  If any such detachment occurs, a global incarnation counter
143        will be increased and the current value will be stored in the detached
144        memory object.  The incarnation counter can be queried by
145        DETACHED_MEMORY_INCARNATION_EXT either globally or for a specific
146        memory object.
147
148        The command
149
150            void GetMemoryObjectDetachedResourcesuivNV(uint memory,
151                                                       enum pname,
152                                                       int first,
153                                                       sizei count,
154                                                       uint *params)
155
156        will return a list of detached buffers (if <pname> is
157        DETACHED_BUFFERS_NV) or textures (if <pname> is DETACHED_TEXTURES_NV)
158        in <params> for memory object <memory>.  It will return <count> items
159        beginning with <first> item.  The number of available items can be
160        queried by calling GetMemoryObjectParameterivEXT with <pname> set to
161        DETACHED_TEXTURES_NV or DETACHED_BUFFERS_NV.  An INVALID_VALUE error is
162        generated by GetMemoryObjectDetachedResourcesuivNV if <memory> is 0.
163        An INVALID_OPERATION error is generated if <memory> names a valid
164        memory object which has no associated memory.  An INVALID_VALUE error
165        is generated if <pname> is neither DETACHED_BUFFERS_NV nor
166        DETACHED_TEXTURES_NV.  An INVALID_VALUE error is generated if
167        <first> + <count> is greater than the number of available items in the
168        list.  An INVALID_VALUE error is generated if <params> is NULL.
169        MemoryObjectParameterivEXT must be called with <pname> set to
170        MAX_DETACHED_TEXTURES_NV or MAX_DETACHED_BUFFERS_NV before calling
171        GetMemoryObjectDetachedResourcesuivNV to set the maximum number of
172        items in the list of detached textures or buffers.  The default values
173        are 0 which means that tracking of detached textures and buffers is
174        disabled by default.
175
176        The command
177
178        void ResetMemoryObjectParameterNV(uint memory,
179                                          enum pname);
180
181        will reset the list of detached buffers (if <pname> is
182        DETACHED_BUFFERS_NV) or textures (if <pname> is DETACHED_TEXTURES_NV)
183        for memory object <memory>.  An INVALID_VALUE error is generated by
184        ResetMemoryObjectParameterNV if <memory> is 0.  An INVALID_OPERATION
185        error is generated if <memory> names a valid memory object which has
186        no associated memory.  An INVALID_VALUE error is generated if <pname>
187        is neither DETACHED_BUFFERS_NV nor DETACHED_TEXTURES_NV.
188
189
190Additions to Chapter 6 of the OpenGL 4.6 Specification (Buffer Objects)
191
192    Add a new section after 6.2.1 (Clearing Buffer Object Data Stores)
193
194        6.2.2 Attaching a memory object to a buffer object
195
196        The commands
197
198            void BufferAttachMemoryNV(enum target,
199                                      uint memory,
200                                      uint64 offset);
201
202            void NamedBufferAttachMemoryNV(uint buffer,
203                                           uint memory,
204                                           uint64 offset);
205
206        will attach a region of a memory object to a buffer object.  For
207        BufferAttachMemoryNV, the buffer object is that bound to <target>,
208        which must be one of the values listed in table 6.1.  For
209        NamedBufferAttachMemoryNV, <buffer> is the name of the buffer
210        object.  <memory> and <offset> define a region of memory that will
211        replace the data store for <buffer>. The content of the original data
212        store will be preserved by a server side copy and the original data
213        store will be deleted after that copy.  The implementation may restrict
214        which values of <offset> are valid for a given memory object and buffer
215        parameter combination.  These restrictions are outside the scope of
216        this extension and must be determined by querying the API or mechanism
217        which created the resource which <memory> refers to.  If an invalid
218        offset is specified an INVALID_VALUE error is generated.  An
219        INVALID_VALUE error is generated by BufferAttachMemoryNV and
220        NamedBufferAttachMemoryNV if <memory> is 0. An INVALID_OPERATION error
221        is generated if <memory> names a valid memory object which has no
222        associated memory.  An INVALID_OPERATION error is generated if the
223        specified buffer was created with MAP_PERSISTENT_BIT flag.  An
224        INVALID_OPERATION error is generated if the specified buffer is
225        currently mapped by client.
226
227Additions to Chapter 8 of the OpenGL 4.6 Specification (Textures and
228Samplers)
229
230    Add a new section between sections 8.19, "Immutable-Format Texture Images"
231    and section 8.20, "Invalidating Texture Image Data"
232
233        8.20 Attaching a memory object to a texture image
234
235        The commands
236
237            void TexAttachMemoryNV(enum target,
238                                   uint memory,
239                                   uint64 offset);
240
241            void TextureAttachMemoryNV(uint texture,
242                                       uint memory,
243                                       uint64 offset);
244
245        will attach a region of a memory object to a texture.  For
246        TexAttachMemoryNV, the texture is that bound to <target>, which must be
247        one of TEXTURE_1D, TEXTURE_2D, TEXTURE_3D, TEXTURE_1D_ARRAY,
248        TEXTURE_2D_ARRAY, TEXTURE_RECTANGLE, TEXTURE_CUBE_MAP,
249        TEXTURE_CUBE_MAP_ARRAY, TEXTURE_2D_MULTISAMPLE, or
250        TEXTURE_2D_MULTISAMPLE_ARRAY.  For TextureAttachMemoryNV, <texture> is
251        the name of the texture.  <memory> and <offset> define a region of
252        memory that will replace the data store for <texture>. The content of
253        the original data store will be preserved by a server side copy and the
254        original data store will be deleted after that copy.  The
255        implementation may restrict which values of <offset> are valid for a
256        given memory object and texture parameter combination.  These
257        restrictions are outside the scope of this extension and must be
258        determined by querying the API or mechanism which created the resource
259        which <memory> refers to.  If an invalid offset is specified an
260        INVALID_VALUE error is generated.  An INVALID_VALUE error is generated
261        by TexAttachMemoryNV and TextureAttachMemoryNV if <memory> is 0.  An
262        INVALID_OPERATION error is generated if <memory> names a valid memory
263        object which has no associated memory.
264
265Errors
266
267New State
268
269Sample
270
271    // host: code not visible to the plug-in developer
272    // plug-in: code written by plug-in developer
273
274    uint tex0;
275    uint tex1;
276
277    // host
278    {
279        // sets up textures as usual
280    }
281
282    // plug-in
283    {
284        int attachable0;
285        int attachable1;
286        GetTextureParameteriv(tex0, MEMORY_ATTACHABLE_NV, &attachable0);
287        GetTextureParameteriv(tex1, MEMORY_ATTACHABLE_NV, &attachable1);
288
289        if (attachable0 && attachable1){
290
291            // allocate memory within vulkan and import it as specified in
292            // EXT_memory_object
293
294            // attach imported vulkan memory
295            TextureAttachMemoryNV(tex0, memobj, memoffset0);
296
297            // ... do same for tex1
298            TextureAttachMemoryNV(tex1, memobj, memoffset1);
299        }
300    }
301
302    ///////////////////////////////
303    // Querying mutations by host
304
305    int incarnationExpected;
306
307    // plug-in
308    {
309        // global query
310        GetIntegerv(DETACHED_MEMORY_INCARNATION_NV, &incarnationExpected);
311
312        // if we have multiple memory objects
313        for each memobj {
314          GetMemoryObjectParameterivEXT(memobj.id,
315                                        DETACHED_MEMORY_INCARNATION_NV,
316                                        &memobj.incarnation);
317          GLint maxDetachedTextures = 64;
318          MemoryObjectParameterivEXT(memobj.id,
319                                     MAX_DETACHED_TEXTURES_NV,
320                                     &maxDetachedTextures);
321        }
322    }
323
324    // host
325    {
326        // deletion triggers a detach
327        glDeleteTextures(1, &tex1);
328    }
329
330    // plug-in
331    {
332        // global query if resources of context were affected
333        int incarnation;
334        GetIntegerv(DETACHED_MEMORY_INCARNATION_NV, &incarnation);
335
336        if (incarnation != incarnationExpected) {
337            incarnationExpected = incarnation;
338
339            // narrow down search which memory object was affected
340            for each memobj {
341                GetMemoryObjectParameterivEXT(memobj.id,
342                                              DETACHED_MEMORY_INCARNATION_NV,
343                                              &incarnation);
344
345                if (incarnation != memobj.incarnation) {
346                    memobj.incarnation = incarnation;
347
348                    int removedTexCount;
349                    GetMemoryObjectParameterivEXT(memobj.id,
350                                                  DETACHED_TEXTURES_NV,
351                                                  &removedTexCount);
352
353                    std::vector<uint> removedTexs(removedTexCount);
354
355                    GetMemoryObjectDetachedResourcesuivNV(
356                        memobj.id,
357                        DETACHED_TEXTURES_NV,
358                        0, removedTexCount,
359                        removedTexs.data());
360
361                    for (int i = 0; i < removedTexCount; i++) {
362                        uint tex = removedTexs[i];
363                        // look up tex in custom allocator and
364                        // mark its memory as available again
365                    }
366
367                    ResetMemoryObjectParameter(memobj.id,
368                                               DETACHED_TEXTURES_NV);
369                }
370            }
371        }
372    }
373
374Issues
375
376    1)  Do we need to introduce allocation done within OpenGL
377        or is attaching existing resources to imported allocation
378        sufficient?
379
380        RESOLVED: No.  No need to duplicate work which has already been done
381        in Vulkan.
382
383    2)  Should binding memory only work on immutable resources?
384
385        RESOLVED: No.  To improve compatibility with existing GL resources,
386        allow mutable resources as well. A global and local incarnation counter
387        was introduced to test against changes, as well as detecting the
388        detached resources.
389
390    3)  Do we support client-mappable resources?
391
392        RESOLVED: Yes.  Client-mappable resources are supported but not
393        when they are persistent. When memory is attached resource must be
394        unmapped.
395
396    4)  What are the affects on TextureViews?
397
398        RESOLVED: TextureViews inherit the memory state.
399
400    5)  Do bindless resources change?
401
402        RESOLVED: Yes.  The existing handles and GPU addresses become invalid
403        when memory is attached and must be queried afterwards.
404
405    6)  Should we support resources that were migrated to host memory by driver?
406
407        RESOLVED: Yes, but the attached memory is independ from this state.
408
409    7)  Do we need an "attachable" per-resource state?
410
411        RESOLVED: Yes.
412
413    8)  How is bindless residency affected?
414
415        RESOLVED: A memory object becomes resident if at least one attached
416        resource is resident.
417
418
419Revision History
420
421    Revision 2, 2018-08-20 (Carsten Rohde, Christoph Kubisch)
422        - Added spec body describing new commands.
423        - Added non-DSA functions
424        - Resolve issues
425
426    Revision 1, 2018-05-07 (Carsten Rohde, Christoph Kubisch)
427        - Initial draft.
428