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