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