OpenGL vs DirectX

The War Is Far From Over

I’ve chosen the title based on the popular article that tries to prove that OpenGL lost the war against Direct3D. To be honest, I didn’t really like the article at all. First, because it compared OpenGL 3 which targeted Shader Model 4.0 hardware and DirectX 11 which targeted Shader Model 5.0 hardware. Besides that, as we will see, the war is really far from over… This article aims to list the most important features introduced by OpenGL 3.x, OpenGL 4.x, Direct3D 10, Direct3D 11 and we will also talk about the promised features of the upcoming Direct3D 11.1 to be fair with DirectX :)

After I wrote my article about the latest features introduced in OpenGL someone asked me whether I can write an article about the comparison of the hardware features exposed by OpenGL and Direct3D. Instead of a long explanation, I decided to simply create a table of the features introduced by the APIs. Please note that the list focuses on hardware features and does not discuss API feature differences between the two APIs. The list may be far from complete and I’m happy to get feedback about what is missing from the table so that I can extend it. Also there are features for which I did not find whether an equivalent exists in D3D and are marked with a question mark. If anybody can point me to the answer, I would be happy, but I did not find a specification of the HLSL versions.

HARDWARE FEATURES EXPOSED
Draw command related features
GL 3.x GL 4.x DX 10 DX 11 DX 11.1
Conditional/predicated rendering based on the result of occlusion queries (NV_conditional_render)
Basic geometry instancing support and instanced draw commands (ARB_draw_instanced)
Geometry instancing with the ability to specify instanced vertex attributes (ARB_instanced_arrays)
Primitive restart (cut index) feature for batching multiple strips together (NV_primitive_restart)
Draw commands allowing modification of the base vertex index (ARB_draw_elements_base_vertex)
Indirect draw commands that source their parameters from server side buffers (ARB_draw_indirect)
New shader type related features
GL 3.x GL 4.x DX 10 DX 11 DX 11.1
Geometry shader support and adjacency primitive support (ARB_geometry_shader4)
Instanced geometry shader support with fixed number of invocations (ARB_gpu_shader5)
Tessellation control and evaluation (hull and domain) shader support (ARB_tessellation_shader)
Transform feedback (stream-output) related features
GL 3.x GL 4.x DX 10 DX 11 DX 11.1
Basic transform feedback (stream-output) support (EXT_transform_feedback)
Transform feedback support without a geometry shader being active (EXT_transform_feedback)
Support for pausing and resuming transform feedback (stream-output) (ARB_transform_feedback2)
Auto-draw support (feed back the contents of the transform feedback buffer) (ARB_transform_feedback2)
Instanced auto-draw support (transform feedback buffer drawing with instancing support) (ARB_transform_feedback_instanced)
Support for outputting multiple primitive streams using transform feedback (stream-output) (ARB_transform_feedback3)
Asynchronous queries and related features
GL 3.x GL 4.x DX 10 DX 11 DX 11.1
Support for occlusion query for getting number of samples passed (ARB_occlusion_query)
Support for occlusion query for getting only a boolean value about visibility (ARB_occlusion_query2)
Support to query the number vertices processed and the number of vertex shader invocations [1]
Support to query the number of geometry shader invocations in case a geometry shader is active [1]
Support to query the number of primitives output by the geometry shader (EXT_transform_feedback)
Support to query the number of primitives that were sent to the rasterizer (EXT_transform_feedback)
Support to query the number of primitives that were passing clipping and were actually rendered [1]
Support to query the number of times a fragment/pixel shader was invoked [1]
Support to query the number of primitives written during transform feedback (stream-output) (EXT_transform_feedback)
Support to query the number of primitives generated during transform feedback (stream-output) (EXT_transform_feedback)
Support to query a server side high resolution timestamp (ARB_timer_query)
Support to query the completeness of rendering commands (ARB_sync)
Texture, vertex and renderbuffer format related features
GL 3.x GL 4.x DX 10 DX 11 DX 11.1
Floating point color and depth formats for textures and render buffers (various extensions)
Cube map textures with depth component internal format (EXT_gpu_shader4)
Half-float (16-bit) vertex and pixel data support (NV_half_float, ARB_half_float_pixel)
Non-normalized integer color formats for textures and renderbuffers (EXT_texture_integer)
Packed depth/stencil texture and renderbuffer formats (EXT_packed_depth_stencil)
RGTC texture compression for two-component textures (EXT_texture_compression_rgtc)
Signed normalized texture component formats (EXT_texture_snorm)
Seamless cube map filtering support (to hide artifacts at cube map edges) (ARB_seamless_cube_map)
Support for swizzling the components of a texture (ARB_texture_swizzle)
BPTC texture compression for floating point and unsigned normalized textures (ARB_texture_compression_bptc)
64-bit floating point vertex attribute formats (ARB_vertex_attrib_64bit)
New texture type related features
GL 3.x GL 4.x DX 10 DX 11 DX 11.1
One- and two-dimensional layered array textures (EXT_texture_array)
Cube map array textures as special two-dimensional array textures (ARB_texture_cube_map_array))
Rectangular textures with no mipmap support and that are accessed with integer coordinates (ARB_texture_rectangle)
Multisampled textures and support for fetching specific sample locations (ARB_texture_multisample)
Casting a texture’s interpreted internal format to another internal format [4] [4]
Uniform buffer (constant buffer) related features
GL 3.x GL 4.x DX 10 DX 11 DX 11.1
Basic uniform buffer (constant buffer) support (ARB_uniform_buffer_object)
Support for large uniform buffers and binding subranges (ARB_uniform_buffer_object)
Framebuffer and texture rendering related features
GL 3.x GL 4.x DX 10 DX 11 DX 11.1
Rendering to textures and renderbuffers (EXT_framebuffer_object)
Multisample stretch blit functionality (EXT_framebuffer_multisample, EXT_framebuffer_blit)
sRGB rendering and blending support for framebuffers (EXT_framebuffer_sRGB)
Support for enabling or disabling clamping of the depth of fragments (ARB_depth_clamp)
Support for logical operations on integer render targets (supported for a decade in OpenGL)
Blending related features
GL 3.x GL 4.x DX 10 DX 11 DX 11.1
Support for alpha-to-coverage when using multisampling (ARB_multisample)
Per-color-buffer blend enables and color writemasks (EXT_draw_buffers2)
Dual-source color blending support based on a secondary output of the fragment shader (ARB_blend_func_extended)
Individual blend equations and blend functions support for each color output (ARB_draw_buffers_blend)
Shader related features
GL 3.x GL 4.x DX 10 DX 11 DX 11.1
Texture lookup functions to access individual texels of a LOD using integer coordinates (EXT_gpu_shader4)
Query the dimensions of a specific LOD of a texture in shaders (EXT_gpu_shader4)
Ability to apply integer offsets to the texel location during texture lookup (EXT_gpu_shader4)
Ability to explicitly pass in derivative values that are used to compute LOD during texture lookup (EXT_gpu_shader4)
Control over varying variable interpolation: non-perspective, flat, centroid sampling, etc. (EXT_gpu_shader4)
Full signed and unsigned integer support in shaders (EXT_gpu_shader4)
Vertex ID built-in variable available in vertex shader (EXT_gpu_shader4)
Primitive ID built-in variable available in geometry and fragment shader (EXT_gpu_shader4)
Instance ID built-in variable available in vertex shader (ARB_draw_instanced)
Shader fragment coordinate convention control (ARB_fragment_coord_conventions)
Provoking vertex control (for flat shaded varying value selection) (ARB_provoking_vertex)
Support for encoding and decoding floating point values from and to integers (ARB_shader_bit_encoding)
Support for get the results of the automatic LOD computations in shaders (ARB_texture_query_lod)
Support for coherent indexing into arrays of samplers using non-constant indices (addressable samplers) (ARB_gpu_shader5)
Support for indexing into arrays of uniform blocks (addressable constant buffers) (ARB_gpu_shader5)
Gathered texture fetches over a 2×2 footprint (with custom offsets) (ARB_texture_gather)
Invocation ID built-in variable available in geometry shader (ARB_gpu_shader5)
Support for double-precision floating-point data types in shaders (ARB_gpu_shader_fp64)
Support for sample-frequency fragment shader execution (ARB_sample_shading)
Support indirect subroutine calls in all shader stages (ARB_shader_subroutine)
Support for selecting from multiple viewports using a geometry shader (ARB_viewport_array)
Support for dedicated atomic counters in shaders (ARB_shader_atomic_counters) [2] [2]
Support for backing up dedicated atomic counters with buffers (ARB_shader_atomic_counters) [5] [5]
Support for load/store (read/write) buffers and textures in shaders (ARB_shader_image_load_store) [3]
Support for atomic operations on load/store buffers and textures (ARB_shader_image_load_store)
Support for disabling or forcing early depth test (ARB_shader_image_load_store)
Support for conservative depth (enabling safe early tests even when modifying depth) (ARB_conservative_depth)
Support for coverage as input to the fragment shader (ARB_gpu_shader5)
Miscellaneous features
GL 3.x GL 4.x DX 10 DX 11 DX 11.1
Support for floating point viewport specification (ARB_viewport_array)
Per-texture mipmap clamping (supported since the very early versions of OpenGL)
Support to use a single depth texture for depth testing and as texture input (when depth writes are disabled)

[1] There is no support for these counters in OpenGL, however they can be implemented with the help of shader atomic counters.
[2] There is no support in Direct3D to use the dedicated atomic counter hardware (supported currently only by AMD GPUs) only by using an append/consume buffer. Though, as atomic counters are the part of UAVs and arbitrary number of UAVs can be attached to a single resource, the same functionality is supported indirectly.
[3] There is read/write buffer and texture support in Direct3D 11, however it is available only in the fragment (pixel) shader. Direct3D 11.1 plans to remove this restriction.
[4] There is no support for texture format casting in OpenGL, conversion, however, can be done by doing a copy preferably using pixel buffer objects.
[5] There is no support for automatic storage of atomic counter values in buffers in Direct3D, however, their value can be manually copied to arbitrary resources.

As a conclusion, I would like to say just one thing: even though there are some features that are not supported by either OpenGL or Direct3D, we really can say that the two APIs are on par with the number of hardware features they expose.

(Sorry in advance for any mistakes, it took quite some time to create this table and I may became too tired at the end)