1Name 2 3 NV_DX_interop 4 5Name Strings 6 7 WGL_NV_DX_interop 8 9Contributors 10 11 Michael Gold, NVIDIA 12 Nuno Subtil, NVIDIA 13 14Contact 15 16 Nuno Subtil, NVIDIA Corporation (nsubtil 'at' nvidia.com) 17 18Status 19 20 Complete. Shipping with NVIDIA release 265 drivers, November 2010. 21 22Version 23 24 Last Modified Date: 10/11/2010 25 Revision: 1 26 27Number 28 29 407 30 31Dependencies 32 33 OpenGL 2.1 is required. 34 35Overview 36 37 This extension allows OpenGL to directly access DirectX buffers 38 and surfaces. A DirectX vertex buffer may be shared as an OpenGL 39 buffer object and a DirectX surface may be shared as an OpenGL 40 texture or renderbuffer object. 41 42New Procedures and Functions 43 44 BOOL wglDXSetResourceShareHandleNV(void *dxObject, HANDLE shareHandle); 45 46 HANDLE wglDXOpenDeviceNV(void *dxDevice); 47 BOOL wglDXCloseDeviceNV(HANDLE hDevice); 48 HANDLE wglDXRegisterObjectNV(HANDLE hDevice, void *dxObject, 49 GLuint name, GLenum type, GLenum access); 50 BOOL wglDXUnregisterObjectNV(HANDLE hDevice, HANDLE hObject); 51 BOOL wglDXObjectAccessNV(HANDLE hObject, GLenum access); 52 BOOL wglDXLockObjectsNV(HANDLE hDevice, GLint count, HANDLE *hObjects); 53 BOOL wglDXUnlockObjectsNV(HANDLE hDevice, GLint count, HANDLE *hObjects); 54 55New Tokens 56 57 Accepted by the <access> parameters of wglDXRegisterObjectNV and 58 wglDXObjectAccessNV: 59 60 WGL_ACCESS_READ_ONLY_NV 0x0000 61 WGL_ACCESS_READ_WRITE_NV 0x0001 62 WGL_ACCESS_WRITE_DISCARD_NV 0x0002 63 64Additions to the WGL Specification 65 66 OpenGL may directly access textures, surfaces and buffers created 67 by DirectX. A DirectX device is prepared for interoperability 68 by calling 69 70 HANDLE wglDXOpenDeviceNV(void *dxDevice); 71 72 <dxDevice> is a pointer to a supported Direct3D device 73 object. Supported devices are listed in the wgl.devicetypes table, 74 along with applicable restrictions for each device. The return 75 value is a handle to a GL/DirectX interop device. 76 77 When wglDXOpenDeviceNV fails to open a Direct3D device, NULL is 78 returned. To get extended error information, call GetLastError. 79 Possible errors are as follows: 80 81 ERROR_OPEN_FAILED Could not open the Direct3D device. 82 83 ERROR_NOT_SUPPORTED The <dxDevice> is not supported. 84 This can be caused either by passing in 85 a device from an unsupported DirectX 86 version, or by passing in a device 87 referencing a display adapter that is 88 not accessible to the GL. 89 90 Calling this entrypoint with an invalid <dxDevice> pointer results 91 in undefined behavior and may result in data corruption or program 92 termination. 93 94 Versions of the operating system that support the Windows Display 95 Driver Model (WDDM) support a sharing mechanism for DirectX 96 resources that makes use of WDDM share handles. The application may 97 obtain a share handle from the operating system to share a surface 98 among several Direct3D devices. 99 100 This extension accommodates, but does not require use of WDDM share 101 handles. An application should only obtain a WDDM share handle at 102 resource creation time if it will share the resource with non-GL 103 clients. 104 105 As of today, all versions of Microsoft Windows starting with Windows 106 Vista use the Windows Display Driver Model, enabling the usage of 107 WDDM share handles. 108 109 If the application wishes to share a DirectX version 9 resource 110 under a WDDM operating system, it is required that the Direct3D 111 device that owns the resource be a Direct3D9Ex device. 112 113 ------------------------------------------------------------------------- 114 DirectX device type Device Restrictions 115 ------------------------------------------------------------------------- 116 IDirect3DDevice9 can not be used on WDDM operating systems; 117 D3DCREATE_MULTITHREADED behavior flag must be 118 set at device creation time 119 120 IDirect3DDevice9Ex D3DCREATE_MULTITHREADED behavior flag must be 121 set at device creation time 122 ------------------------------------------------------------------------- 123 Table wgl.devicetypes - Valid device types for the <dxDevice> parameter of 124 wglDXOpenDeviceNV and associated restrictions. 125 ------------------------------------------------------------------------- 126 127 If the application wishes to share a DirectX resource with GL and 128 non-GL clients, it should request a share handle for the 129 resource. It must also call 130 131 BOOL wglDXSetResourceShareHandleNV(void *dxResource, HANDLE shareHandle); 132 133 to associate the share handle with the DirectX resource prior to 134 registering it with the GL. <dxResource> is a pointer to the DirectX 135 resource that will be shared, <shareHandle> contains the share 136 handle that the OS generated for the resource. 137 138 The return value for wglDXSetResourceShareHandleNV is FALSE if 139 this function is called more than once for any resource; called 140 with an invalid <shareHandle> parameter; or called for a resource 141 that is already being shared with the GL; otherwise, the return 142 value is TRUE. On a version of the OS that does not support WDDM, 143 calling wglDXSetResourceShareHandleNV returns TRUE but has no 144 effect. 145 146 Results are undefined if the <dxResource> pointer is invalid and 147 may result in data corruption or program termination. 148 149 Calling 150 151 HANDLE wglDXRegisterObjectNV(HANDLE hDevice, void *dxResource, 152 GLuint name, GLenum type, GLenum access); 153 154 prepares a DirectX object for use by the GL. <hDevice> is a 155 GL/DirectX interop device handle, as returned by wglDXOpenDeviceNV. 156 157 <dxResource> is a pointer to a DirectX resource to be registered 158 with the GL. The resource must be of one of the types identified in 159 table wgl.objtypes and must also obey the restrictions specified for 160 that resource in table wgl.restrictions. 161 162 <type> identifies the GL object type that will map to the DirectX 163 resource being shared and must be one of the types enumerated in 164 table wgl.objtypes. <name> is the GL object name to be assigned 165 to the DirectX resource in the namespace of the objects identified 166 by <type> in the current GL context. The valid combinations of 167 <type> and <dxResource> are described in table wgl.objtypes. 168 169 <access> indicates the intended usage of the resource in GL and must 170 be one of the following: 171 172 WGL_ACCESS_READ_ONLY_NV indicates that GL will read the 173 DirectX resource but will not modify it. If GL attempts to 174 modify the data store of the resource, the result is undefined 175 and may include program termination. 176 177 WGL_ACCESS_READ_WRITE_NV indicates that GL may read or write 178 the data store of the resource. 179 180 WGL_ACCESS_WRITE_DISCARD_NV indicates that any previous 181 contents of the object may be discarded and GL may write to 182 the resource. Any data written by GL may be reliably read in 183 subsequent operations. The result of subsequently reading 184 data outside the region written by GL is undefined. 185 186 If the call is successful, the return value is a handle to a 187 GL/DirectX interop object. A return value of NULL indicates that 188 an error occurred. To obtain extended error information, call 189 GetLastError. Possible errors are as follows: 190 191 ERROR_INVALID_HANDLE No GL context is made current to the 192 calling thread. 193 194 ERROR_INVALID_DATA Incorrect <name> <type> or <access> 195 parameters. 196 197 ERROR_OPEN_FAILED Opening the Direct3D resource failed. 198 199 Calling wglDXRegisterObjectNV with an invalid <hDevice> handle 200 results in undefined behavior and may result in data corruption or 201 program termination. 202 203 If the application explicitly requests a share handle for a 204 DirectX resource, results are undefined (and may result in data 205 corruption, incorrect DirectX operation or program termination) if 206 wglDXRegisterObjectNV is called before calling 207 wglDXSetResourceShareHandleNV for the same resource. This 208 restriction does not apply to non-WDDM operating systems. 209 210 -------------------------------------------------------------------------- 211 <type> type of <name> Valid DirectX resource types 212 -------------------------------------------------------------------------- 213 TEXTURE_2D texture IDirect3DSurface9 214 IDirect3DTexture9 215 216 TEXTURE_3D texture IDirect3DVolumeTexture9 217 218 TEXTURE_CUBE_MAP texture IDirect3DCubeTexture9 219 220 TEXTURE_RECTANGLE texture IDirect3DSurface9 221 IDirect3DTexture9 222 223 RENDERBUFFER renderbuffer IDirect3DSurface9 224 225 NONE buffer IDirect3DIndexBuffer9 226 IDirect3DVertexBuffer9 227 -------------------------------------------------------------------------- 228 Table wgl.objtypes - Valid values for the <type> parameter of 229 wglDXRegisterObjectNV and associated object types for GL and 230 DirectX. 231 -------------------------------------------------------------------------- 232 233 -------------------------------------------------------------------------- 234 Resource Type Resource Restrictions 235 -------------------------------------------------------------------------- 236 IDirect3DSurface9 Must not be lockable 237 238 IDirect3DTexture9 Memory pool must be D3DPOOL_DEFAULT 239 240 IDirect3DCubeTexture9 Memory pool must be D3DPOOL_DEFAULT 241 242 IDirect3DVolumeTexture9 Memory pool must be D3DPOOL_DEFAULT 243 244 IDirect3DVertexBuffer9 Memory pool must be D3DPOOL_DEFAULT 245 246 IDirect3DIndexBuffer9 Memory pool must be D3DPOOL_DEFAULT 247 248 -------------------------------------------------------------------------- 249 Table wgl.restrictions - Restrictions on DirectX resources that can 250 be registered via wglDXRegisterObjectNV 251 -------------------------------------------------------------------------- 252 253 Before a GL object which is associated with a DirectX resource may 254 be used, it must be locked. The function 255 256 BOOL wglDXLockObjectsNV(HANDLE hDevice, GLint count, 257 HANDLE *hObjects); 258 259 attempts to lock an array of <count> interop objects. <hObjects> 260 is an array of length <count> containing the handles of the 261 objects to be locked. 262 263 A return value of TRUE indicates that all objects were 264 successfully locked. A return value of FALSE indicates an 265 error. To get extended error information, call 266 GetLastError. Possible errors are as follows: 267 268 ERROR_BUSY One or more of the objects in <hObjects> 269 was already locked. 270 271 ERROR_INVALID_DATA One or more of the objects in <hObjects> 272 does not belong to the interop device 273 specified by <hDevice>. 274 275 ERROR_LOCK_FAILED One or more of the objects in <hObjects> 276 failed to lock. 277 278 If the function returns FALSE, none of the objects will be locked. 279 280 Attempting to access an interop object via GL when the object is 281 not locked, or attempting to access the DirectX resource through 282 the DirectX API when it is locked by GL, will result in undefined 283 behavior and may result in data corruption or program 284 termination. Likewise, passing invalid interop device or object 285 handles to this function has undefined results, including program 286 termination. 287 288 Locked objects are available for operations which read or write 289 the data store, according to the access mode specified in 290 wglDXRegisterObjectNV. If a different access mode is required 291 after the object has been registered, the access mode may be 292 modified by calling 293 294 BOOL wglDXObjectAccessNV(HANDLE hObject, GLenum access); 295 296 <hObject> is an interop object handle returned by 297 wglDXRegisterObjectNV and identifies the interop object for which 298 the access mode should be modified. 299 300 <access> is a new access mode with the same meaning as the 301 <access> parameter of wglDXRegisterObjectNV. The access mode may 302 be modified only when an object is not locked and will affect 303 subsequent lock operations. 304 305 The return value is TRUE if the function succeeds. If an error 306 occurs, the return will be FALSE. To get extended error 307 information, call GetLastError. Possible errors are as follows: 308 309 ERROR_INVALID_DATA Invalid <access> parameter. 310 311 ERROR_BUSY <hObject> is currently locked for 312 GL access. 313 314 Operations which attempt to read or write an object in a manner 315 inconsistent with the specified access mode will result in 316 undefined behavior and may result in data corruption or program 317 termination. 318 319 Calling wglDXObjectAccessNV with an invalid <hObject> parameter 320 results in undefined behavior and may result in data corruption or 321 program termination. 322 323 In order to return control of an object to DirectX, it must be unlocked 324 by calling 325 326 BOOL wglDXUnlockObjectsNV(HANDLE hDevice, GLint count, 327 HANDLE *hObjects); 328 329 A return value of TRUE indicates that the objects were 330 successfully unlocked and DirectX may now safely access them. A 331 return value of FALSE indicates that an error occurred. To get 332 extended error information, call GetLastError. Possible errors are 333 as follows: 334 335 ERROR_NOT_LOCKED One or more of the objects in <hObjects> 336 was not locked. 337 338 ERROR_INVALID_DATA One or more of the objects in <hObjects> 339 does not belong to the interop device 340 identified by <hDevice>. 341 342 ERROR_LOCK_FAILED One or more of the objects in <hObjects> 343 failed to unlock. 344 345 If the function returns FALSE, none of the objects are unlocked. 346 347 Results are undefined if any of the handles in <hObjects> are 348 invalid and may result in data corruption or program termination. 349 350 When access to a DirectX resource from GL is no longer required, the 351 association between the GL object and the DirectX resource should be 352 terminated by calling 353 354 BOOL wglDXUnregisterObjectNV(HANDLE hObject); 355 356 where <hObject> is the interop object handle returned by 357 wglDXRegisterObjectNV. Any subsequent attempt to access 358 <hObject> will result in undefined behavior and may result in data 359 corruption or program termination. 360 361 A return value of TRUE indicates that the object was successfully 362 unregistered and <hObject> is now invalid. A return value of FALSE 363 indicates that an error occurred. To get extended error 364 information, call GetLastError. Possible errors are as follows: 365 366 ERROR_BUSY <hObject> is currently locked for access 367 by the GL 368 369 Results are undefined if <hObject> is invalid and may result in 370 program termination or data corruption. 371 372 When all interop operations have been completed, the connection 373 between OpenGL and DirectX may be terminated by calling 374 375 BOOL wglDXCloseDeviceNV(HANDLE hDevice); 376 377 where <hDevice> is the interop device handle returned by 378 wglDXOpenDeviceNV. Once the device is closed, any attempt to 379 access DirectX resources through associated GL handles will result 380 in undefined behavior and may result in data corruption or program 381 termination. 382 383 A return value of TRUE indicates that the device was successfully 384 closed and <hDevice> is now invalid. A return value of FALSE 385 indicates an error. To get extended error information, call 386 GetLastError. Possible errors are as follows: 387 388 ERROR_INVALID_DATA The Direct3D device failed to 389 close. 390 391 Calling this function with an invalid <hDevice> parameter results 392 in undefined behavior and may result in data corruption or program 393 termination. 394 395Issues 396 397 1) Should we support explicit usage of share handles under WDDM or 398 disallow it entirely? 399 400 RESOLUTION: We should support it. Implicit share handles are 401 useful when writing code that's meant to be portable between WDDM 402 and non-WDDM operating systems; explicit share handles are useful 403 when writing an application that needs to share resources with 404 non-GL clients. 405 406 2) Can DirectX and OpenGL render concurrently to the same DirectX 407 resource? 408 409 RESOLUTION: Concurrent rendering by OpenGL and DirectX to the same 410 resource is not supported. 411 412 DISCUSSION: The Lock/Unlock calls serve as synchronization points 413 between OpenGL and DirectX. They ensure that any rendering 414 operations that affect the resource on one driver are complete 415 before the other driver takes ownership of it. 416 417 When sharing a large resource, applications can potentially desire 418 concurrent access to different regions of the resource (e.g., if 419 the application is drawing a user interface in DirectX with an 420 OpenGL viewport occupying a region of it, where the UI and OpenGL 421 regions do not overlap). In this case, more fine-grained 422 synchronization could be achieved by not doing implicit 423 synchronization on the driver side and providing primitives to the 424 application to enable it to synchronize on it's own, for instance, 425 by allowing a DirectX 9 event query to be mapped and used as a GL 426 sync object. This is, however, beyond the scope of the current 427 extension. 428 429 3) If two GL contexts are sharing textures, what is the correct 430 way to access a DirectX resource from both contexts? 431 432 RESOLUTION: Sharing a DirectX resource among multiple GL contexts is 433 best achieved without having shared namespaces among the GL 434 contexts, by simply registering the texture on each GL context 435 separately. 436 437 If two GL contexts share namespaces, it is still necessary to lock 438 the DirectX resource for each GL context that needs to access 439 it. Note that only one GL context may hold the lock on the 440 resource at any given time --- concurrent access from multiple GL 441 contexts is not currently supported. 442 443 4) How do driver control panel settings regarding anti-aliasing 444 modes affect this extension? 445 446 DISCUSSION: User-configurable system settings may allow users to 447 force anti-aliasing for applications that do not support 448 it. Usually, this causes the implementation to create multisampled 449 surfaces for render targets that the application creates as 450 non-multisampled. 451 452 GL API semantics for textures can differ between multisample and 453 non-multisample textures. If the application creates a DirectX 454 render target that is to be bound as a GL texture, it will have no 455 way to know that the surface is actually multisampled, but GL will 456 require that it is bound to the TEXTURE_2D_MULTISAMPLE target 457 instead of the TEXTURE_2D target. Because of this, it is 458 recommended that render targets be bound to GL renderbuffers 459 instead. 460 461 Additionally, DirectX implementations are free to create render 462 targets that do not match the number of samples that the app 463 requested. Implementations are also free to create color and depth 464 render targets with incompatible multisample modes. This can 465 result in FBO completeness errors if incompatible color and depth 466 render targets are bound for rendering to the same FBO. This 467 problem also exists with pure DirectX applications and is not 468 specific to this extension. 469 470Sample Code 471 472 Render to Direct3D 9 multisample color and depth buffers with 473 OpenGL under WDDM: 474 475 // create the Direct3D9Ex device: 476 IDirect3D9Ex *direct3D; 477 IDirect3DDevice9Ex *device; 478 D3DPRESENT_PARAMETERS d3dpp; 479 480 direct3D = Direct3DCreate9Ex(D3D_SDK_VERSION, &direct3D); 481 482 <set appropriate device parameters in d3dpp> 483 484 direct3D->CreateDevice(D3DADAPTER_DEFAULT, 485 D3DDEVTYPE_HAL, 486 hWnd, 487 D3DCREATE_HARDWARE_VERTEXPROCESSING | 488 D3DCREATE_PUREDEVICE | 489 D3DCREATE_MULTITHREADED, 490 &d3dpp, 491 &device); 492 493 // create the Direct3D render targets 494 IDirect3DSurface9 *dxColorBuffer; 495 IDirect3DSurface9 *dxDepthBuffer; 496 497 device->CreateRenderTarget(width, height, 498 D3DFMT_A8R8G8B8, 499 D3DMULTISAMPLE_4_SAMPLES, 0, 500 FALSE, 501 &dxColorBuffer, 502 NULL); 503 504 device->CreateDepthStencilSurface(width, height, 505 D3DFMT_D24S8, 506 D3DMULTISAMPLE_4_SAMPLES, 0, 507 FALSE, 508 &dxDepthBuffer, 509 NULL); 510 511 // register the Direct3D device with GL 512 HANDLE gl_handleD3D; 513 gl_handleD3D = wglDXOpenDeviceNV(device); 514 515 // register the Direct3D color and depth/stencil buffers as 516 // 2D multisample textures in opengl 517 GLuint gl_names[2]; 518 HANDLE gl_handles[2]; 519 520 glGenTextures(2, gl_names); 521 522 gl_handles[0] = wglDXRegisterObjectNV(gl_handleD3D, dxColorBuffer, 523 gl_names[0], 524 GL_TEXTURE_2D_MULTISAMPLE, 525 WGL_ACCESS_READ_WRITE_NV); 526 527 gl_handles[1] = wglDXRegisterObjectNV(gl_handleD3D, dxDepthBuffer, 528 gl_names[1], 529 GL_TEXTURE_2D_MULTISAMPLE, 530 WGL_ACCESS_READ_WRITE_NV); 531 532 // attach the Direct3D buffers to an FBO 533 glBindFramebuffer(GL_FRAMEBUFFER, fbo); 534 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 535 GL_TEXTURE_2D_MULTISAMPLE, gl_names[0]); 536 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, 537 GL_TEXTURE_2D_MULTISAMPLE, gl_names[1]); 538 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, 539 GL_TEXTURE_2D_MULTISAMPLE, gl_names[1]); 540 541 // rendering loop 542 while (!done) { 543 <direct3d renders to the render targets> 544 545 // lock the render targets for GL access 546 wglDXLockObjectsNV(handleD3D, 2, gl_handles); 547 548 <opengl renders to the render targets> 549 550 // unlock the render targets 551 wglDXUnlockObjectsNV(handleD3D, 2, gl_handles); 552 553 <direct3d renders to the render targets and presents 554 the results on the screen> 555 } 556 557Revision History 558 559 Revision 1, 2010/11/10 560 - Initial public revision 561