Document directory
- State object
- Compute shader
- Multithreading
- Summary
Reprinted please indicate the source for the klayge game engine, this article address for http://www.klayge.org/2011/07/20/%e8%b7%a8%e8%b6%8aopengl%e5%92%8cd3d%e7%9a%84%e9%b8%bf%e6%b2%9f%ef%bc%88%e4%b8%89%ef%bc%89%ef%bc%9a%e4%ba%a4%e9%9b%86%ef%bc%9f%e5%b9%b6%e9%9b%86%ef%bc%9f/
The previous article discussed how to fill in the differences between OpenGL and d3d that were originally considered to be at the underlying layer. This article analyzes the functional similarities and differences between the two APIs and the possibility of direct mutual access.
Function
D3d9 has already been covered by OpenGL 2.0. You can find a lot of information on the Internet. This article focuses on new GPU features. The following table lists the new functions of d3d10 + and the OpenGL extensions or cores required to implement this function.
D3d 10 Functions |
Corresponding to OpenGL |
Geomrtry shader |
Gl_arb_geometry_shader4 or OpenGL 3 |
Stream output |
Gl_ext_transform_feedback or OpenGL 3 |
State object |
None. gl_ext_direct_state_access needs to be encapsulated on the upper layer. |
Constant Buffer |
Gl_arb_uniform_buffer_object or OpenGL 3 |
Texture array and new resource format |
Gl_ext_texture_array + Gl_arb_texture_compression_rgtc + Gl_arb_texture_rg + Gl_arb_texture_rgb10_a2ui + Gl_ext_texture_integer or OpenGL 3 |
Texture and sampler |
Gl_arb_sampler_objects or OpenGL 3 |
Perform integer and bit operations in the shader |
Gl_arb_shader_bit_encoding or OpenGL 3 |
Multisampled alpha-to-coverage |
Gl_nv_multisample_coverage or OpenGL 3 |
Functions of d3d 10.1 |
Corresponding to OpenGL |
Read the multisample depth/stencel texture |
Gl_arb_texture_multisample or OpenGL 3 |
Cubemap Array |
Gl_arb_texture_cube_map_array or OpenGL 4 |
Gather4 |
Gl_arb_texture_gather or OpenGL 4 |
D3d 11 Functions |
Corresponding to OpenGL |
Compute shader |
Gl_arb_cl_event + opencl |
Dynamic shader Linkage |
Gl_arb_gpu_shader5 or OpenGL 4 |
Multithreading |
None |
Tessellation |
Gl_arb_tessellation_shader or OpenGL 4 |
These are all functions mentioned in the dx sdk documentation. Other small functions can easily find the corresponding OpenGL. From the table above, we can see that almost all d3d functions can be directly replaced by corresponding OpenGL functions without any performance loss. Some exceptions need to be discussed:
State object
D3d 10 adds a State object, which can greatly reduce the number of system calls required to change the rendering state. There is no State object in OpenGL, so it can only be encapsulated on the upper layer. Although there is some performance loss, the interface can be integrated with d3d. ARB has had a long-standing discussion on OpenGL State objects, and the major vendors have not reached an agreement. However, this is a trend. It is believed that there will be related extensions in the near future. Then the difference will be perfectly filled out.
Compute shader
D3d 11 introduces compute shader, which directly provides gpgpu capabilities in d3d. OpenGL does not add a shader, but enhances the interoperability with opencl. OpenGL and opencl can directly share texture and buffer, and play the same function as compute shader. Similar to the relationship between glsl and HLSL, there are different shader languages, and no CG can be used as a bridge. Currently, only two pieces of code can be written.
Multithreading
The multithreading capability of d3d 11 allows multiple contexts to call the d3d11 API. The called API stream stored in each context can be executed in the main context sequentially. Currently, OpenGL does not introduce this mechanism, which must be implemented on the upper layer. In other words, all current video card drivers do not implement multithreading, so all multi-context is implemented by the d3d runtime software and does not achieve the desired speed-up effect. You can implement a command list by yourself to achieve that performance. We still hope that one day multithreading can become one of OpenGL functions and simplify the upper-layer work.
Summary
Therefore, the intersection of OpenGL and d3d functions is almost the Union of them, and it does not lose a lot of functionality because it needs to be compatible with the two. Functionally, the differences between OpenGL and d3d are even less than those between OpenGL and OpenGL ES. The first rumor 4 was cracked.
Interoperability
The emergence of the magic extension wgl_nv_dx_interop allows OpenGL to formally interact with d3d. (Strictly speaking, interoperability comes from its predecessor wgl_nvx_dx_interop, but it is best to be careful when using it because it is an extension of the nvx experiment .) The purpose of this extension is to create a resource in d3d and access it in OpenGL. Currently, d3d9 supports texture, render target, and VB reading and writing. D3d10 + support will be added in the future. The synchronization between the two APIS is also completed automatically.
Examples of mutual Rendering using wgl_nv_dx_interop are as follows:
// Build d3d devices and resources as usual
D3d-> createdevice (..., & d3ddevice );
D3ddevice-> createrendertarget (width, height, d3dfmt_a8r8g8b8,
D3dmultisample_4_samples, 0,
False, & dxcolorbuffer, null );
D3ddevice-> createdepthstencilsurface (width, height, d3dfmt_d24s8,
D3dmultisample_4_samples, 0,
False, & dxdepthbuffer, null );
// Register the d3d device with OpenGL
Handle gl_handled3d = wgldxopendevicenv (d3ddevice );
// Register d3drender target as an OpenGL texture object
Gluint Names [2];
Handle handles [2];
Handles [0] = wgldxregisterobjectnv (gl_handled3d, dxcolorbuffer,
Names [0], gl_texture_2d_multisample, wgl_access_read_write_nv );
Handles [1] = wgldxregisterobjectnv (gl_handled3d, dxdepthbuffer,
Names [0], gl_texture_2d_multisample, wgl_access_read_write_nv );
// Now the texture can be used as a normal OpenGL texture.
// D3d and OpenGL merge to the same render target
Direct3d_render_pass (); // perform d3d rendering as usual
// Lock the render target and hand it to OpenGL
Wgldxlockobjectsnv (handled3d, 2, handles );
Opengl_render_pass (); // perform OpenGL rendering as usual
Wgldxunlockobjectsnv (handled3d, 2, handles );
Direct3d_swap_buffers (); // d3d present
In this way, the two APIs can coexist harmoniously, but this extension is currently limited to NV cards.
This article discusses the functional intersection and union of the two APIs, as well as the interoperability methods. The next article is the end of this series. It will discuss some platform-related issues and give a systematic summary.