Gráfico de mapeo de conceptos de DirectX / OpenGL (Vulkan)

32

A menudo, una función de hardware similar se expone a través de DirectX y OpenGL usando una terminología diferente.

Por ejemplo:
Constant Buffer / Uniform Buffer Object
RWBuffer / SSBO

Estoy buscando un cuadro exhaustivo que describa qué terminología de DirectX se utiliza para referirse a qué concepto de OpenGL, y viceversa.
¿Dónde puedo encontrar ese recurso?

wip
fuente
Los comentarios no son para discusión extendida; Esta conversación se ha movido al chat .
trichoplax

Respuestas:

55

No he podido encontrar este gráfico en la web, así que hice uno aquí. (Todos, siéntanse libres de agregar, elaborar o corregir cualquier error. Algunos de estos son solo las mejores conjeturas basadas en una comprensión parcial de la API y el hardware interno)

Conceptos básicos de API

D3D11                          OpenGL 4.x
-----                          ----------
device                         context
immediate context              (implicit; no specific name)
deferred context               (no cross-vendor equivalent, but see
                                GL_NV_command_list)
swap chain                     (implicit; no specific name)
(no cross-vendor equivalent)   extensions
debug layer; info queue        GL_KHR_debug extension

Sombreadores

D3D11              OpenGL 4.x
-----              ----------
pixel shader       fragment shader
hull shader        tessellation control shader
domain shader      tessellation evaluation shader
(vertex shader, geometry shader, and compute shader
 are called the same in both)

registers          binding points
semantics          interface layouts
SV_Foo semantics   gl_Foo builtin variables

class linkage      subroutines

(no equivalent)    program objects; program linking

(D3D11's normal
 behavior; no      separate shader objects
 specific name)

Geometria y Dibujo

D3D11              OpenGL 4.x
-----              ----------
vertex buffer      vertex attribute array buffer; vertex buffer object
index buffer       element array buffer
input layout       vertex array object (sort of)

Draw               glDrawArrays
DrawIndexed        glDrawElements
(instancing and indirect draw are called similarly in both)
(no equivalent)    multi-draw, e.g. glMultiDrawElements​

stream-out         transform feedback
DrawAuto           glDrawTransformFeedback​

predication        conditional rendering
(no equivalent)    sync objects

Tampones y Texturas

D3D11                    OpenGL 4.x
-----                    ----------
constant buffer          uniform buffer object
typed buffer             texture buffer
structured buffer        (no specific name; subset of SSBO features)
UAV buffer; RWBuffer     SSBO (shader storage buffer object)
UAV texture; RWTexture   image load/store

shader resource view     texture view
sampler state            sampler object

interlocked operations   atomic operations
append/consume buffer    SSBO + atomic counter

discard buffer/texture   invalidate buffer/texture
(no equivalent)          persistent mapping
(D3D11's normal
 behavior; no            immutable storage
 specific name)
(implicitly inserted     glMemoryBarrier; glTextureBarrier
 by the API)

Procesar objetivos

D3D11                     OpenGL 4.x
-----                     ----------
(no equivalent)           framebuffer object
render target view        framebuffer color attachment
depth-stencil view        framebuffer depth-stencil attachment
multisample resolve       blit multisampled buffer to non-multisampled one

multiple render targets   multiple color attachments
render target array       layered image

(no equivalent)           renderbuffer

Consultas

D3D11                       OpenGL 4.x
-----                       ----------
timestamp query             timer query
timestamp-disjoint query    (no equivalent)
(no equivalent)             time-elapsed query
occlusion query             samples-passed query
occlusion predicate query   any-samples-passed query
pipeline statistics query   (no equivalent in core, but see
                             GL_ARB_pipeline_statistics_query)
SO statistics query         primitives-generated/-written queries 
(no equivalent)             query buffer object

Calcular sombreadores

D3D11                     OpenGL 4.x
-----                     ----------
thread                    invocation
thread group              work group
thread group size         local size
threadgroup variable      shared variable

group sync                "plain" barrier
group memory barrier      shared memory barrier
device memory barrier     atomic+buffer+image memory barriers
all memory barrier        group memory barrier

Otros recursos

Nathan Reed
fuente
3
Guau. Probablemente contratan mentes más difíciles del mundo para inventar los nombres más distintos para las mismas cosas.
narthex
Ese cuadro es excelente, ¡gracias por haberse tomado el tiempo de escribirlo!
wip
3
" matriz de textura - imagen en capas " OpenGL también los llama Texturas de matriz; el término "imagen en capas" se usa principalmente alrededor de sus archivos adjuntos en las FBO. Además, probablemente debería mencionar los objetos de muestra de OpenGL y su estado de muestra equivalente a D3D.
Nicol Bolas
2
@ CpCd0y Sí, se les llama coloquialmente así, pero mi intención aquí fue decir cómo se llaman esas cosas / cómo se representan en API-ese.
Nathan Reed
1
@NathanReed: MRT no se usa en la especificación de OpenGL, pero sí la "consulta de oclusión". El término "muestras pasadas" es simplemente un tipo de consulta de oclusión; también hay "cualquier muestra pasada" y "conservadora cualquier muestra pasada".
Nicol Bolas
28

Aquí hay una lista no exhaustiva de Vulkan y DirectX 12. Esto se combina usando criterios similares a los de Nathan.

En general, ambas API son sorprendentemente similares. Cosas como las etapas de sombreador permanecen sin cambios desde DX11 y OpenGL. Y obviamente, DirectX usa vistas para hacer que las cosas sean visibles para los sombreadores. Vulkan también usa vistas, pero son menos frecuentes.

El comportamiento de visibilidad del sombreador difiere un poco entre los dos. Vulkan usa una máscara para determinar si un descriptor es visible para las distintas etapas del sombreador. DX12 maneja esto un poco diferente, la visibilidad de los recursos se realiza en una sola etapa o en todas las etapas.

Rompí el conjunto de descriptores / parámetros del parámetro raíz lo mejor que pude. El manejo del descriptor es una de las áreas que varían mucho entre las dos API. Sin embargo, el resultado final es bastante similar.

Conceptos básicos de API

Vulkan                              DirectX 12
---------------                     ---------------
n/a                                 IDXGIFactory4
VkInstance                          n/a
VkPhysicalDevice                    IDXGIAdapter1
VkDevice                            ID3D12Device
VkQueue                             ID3D12CommandQueue
VkSwapchain                         IDXGISwapChain3
VkFormat                            DXGI_FORMAT
SPIR-V                              D3D12_SHADER_BYTECODE
VkFence                             fences
VkSemaphore                         n/a
VkEvent                             n/a

La capa WSI de Vulkan proporciona imágenes para la cadena de intercambio. DX12 requiere recursos de creación para representar la imagen.

El comportamiento general de la cola es bastante similar entre ambos. Hay un poco de idiosincrasia al enviar desde múltiples hilos.

Intentaré actualizar a medida que recuerdo más cosas ...

Comando Buffer y Pool

Vulkan                              DirectX 12
---------------                     ---------------
VkCommandPool                       ID3D12CommandAllocator
VkCommandBuffer                     ID3D12CommandList/ID3D12GraphicsCommandList

La palabrería sobre el grupo de comandos / asignador de documentos de Vulkan / DX12 establece el comportamiento en palabras muy diferentes, pero el comportamiento real es bastante similar. Los usuarios son libres de asignar muchos buffers / listas de comandos del grupo. Sin embargo, solo se puede grabar un búfer / lista de comandos del grupo. Las agrupaciones no se pueden compartir entre subprocesos. Por lo tanto, varios subprocesos requieren múltiples grupos. También puede comenzar a grabar inmediatamente después de enviar el comando buffer / list en ambos.

La lista de comandos DX12 se crea en un estado abierto. Esto me resulta un poco molesto ya que estoy acostumbrado a Vulkan. DX12 también requiere un reinicio explícito del asignador de comandos y la lista de comandos. Este es un comportamiento opcional en Vulkan.

Descriptores

Vulkan                              DirectX 12
---------------                     ---------------
VkDescriptorPool                    n/a
VkDescriptorSet                     n/a
VkDescriptorSetLayout               n/a
VkDescriptorSetLayoutBinding        RootParameter**
n/a                                 ID3D12DescriptorHeap

** RootParameter : no es un equivalente exacto de VkDescriptorSetLayoutBinding pero un pensamiento similar en la imagen más grande.

VkDescriptorPool y ID3D12DescriptorHeaps son algo similares (gracias Nicolas) en que ambos manejan la asignación de los descriptores ellos mismos.

Cabe señalar que DX12 solo admite como máximo dos montones de descriptores vinculados a una lista de comandos en un momento dado. Un CBVSRVUAV y una muestra. Puede tener tantas tablas de descriptores como desee haciendo referencia a estos montones.

En el lado de Vulkan, hay un límite estricto para el número máximo de conjuntos de descriptores que le dice al grupo de descriptores. En ambos, debe realizar un poco de contabilidad manual sobre el número de descriptores por tipo que puede tener el grupo / montón. Vulkan también es más explícito con el tipo de descriptores. Mientras que en DX12 los descriptores son CBVSRVUAV o muestreador.

DX12 también tiene una función en la que puede vincular un CBV sobre la marcha utilizando SetGraphicsRootConstantBufferView. Sin embargo, la versión SRV de esto, SetGraphicsRootShaderResourceView, no funciona en texturas. Está en los documentos, pero también puede tomarle un par de horas para resolver esto si no es un lector cuidadoso.

Tubería

Vulkan                              DirectX 12
---------------                     ---------------
VkPipelineLayout                    RootSignature***
VkPipeline                          ID3D12PipelineState
VkVertexInputAttributeDescription   D3D12_INPUT_ELEMENT_DESC
VkVertexInputBindingDescription     "

* ** RootSignature : no es un equivalente exacto de VkPipelineLayout .

DX12 combina el atributo de vértice y el enlace en una sola descripción.

Imágenes y Buffers

Vulkan                              DirectX 12
---------------                     ---------------
VkImage                             ID3D12Resource
VkBuffer                            ID3D12Resource
uniform buffer                      constant buffer
index buffer                        index buffer
vertex buffer                       vertex buffer
VkSampler                           sampler
barriers/transitions                barriers/transitions

Las barreras en ambas API se descomponen un poco diferentes, pero tienen un resultado neto similar.

RenderPasses / RenderTargets

Vulkan                              DirectX 12
---------------                     ---------------
VkRenderPass                        render pass
VkFramebuffer                       collection of ID3D12Resource
subpass                             n/a
n/a                                 render target

Los pases de render Vulkan tienen una buena característica de resolución automática. DX12 no tiene este AFIAK. Ambas API proporcionan funciones para la resolución manual.

No hay una equivalencia directa entre VkFramebuffer y ningún objeto en DX12. Una colección de ID3D12Resource que se asigna a los RTV es una similitud suelta.

VkFramebuffer actúa más o menos como un grupo de archivos adjuntos a los que VkRenderPass hace referencia mediante un índice. Los subpasos dentro de un VkRenderPass pueden hacer referencia a cualquiera de los archivos adjuntos en un VkFramebuffer, suponiendo que el mismo archivo adjunto no esté referenciado más de una vez por subpaso. El número máximo de archivos adjuntos de color utilizados a la vez está limitado a VkPhysicalDeviceLimits.maxColorAttachments.

Los objetivos de representación de DX12 son solo RTV respaldados por objetos ID3D12Resource. El número máximo de archivos adjuntos de color utilizados a la vez está limitado a D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT (8).

Ambas API requieren que especifique los objetivos / pasos de representación en la creación de los objetos de canalización. Sin embargo, Vulkan le permite usar pases de renderizado compatibles, por lo que no está bloqueado en los que especifique durante la creación de la tubería. No lo he probado en DX12, pero supongo que ya que es solo un RTV, esto también es cierto en DX12.

codingforlove
fuente
¡Bien, este es un gran trabajo!
wip
Creo que sería justo decir eso VkDescriptorPooly ID3D12DescriptorHeapson similares en función (en la forma en que se asignan los descriptores), pero de forma bastante diferente, debido a las diferencias en la forma general en que los descriptores se manejan entre las API. Además, me imagino que el equivalente a D3D12 VkBufferViewes buffers tipeados, al igual que para D3D11.
Nicol Bolas
Tienes razón en el montón de descriptores. Actualizado. En cuanto a las vistas de búfer, ambas API tienen un concepto de vistas. No podría decir si DX12 se ha separado de la convención DX1 de buffers mecanografiados o no, ya que no tengo mucha experiencia con DX11.
codingforlove
¿Podría decir que los objetivos de renderizado D3D12 son equivalentes a VkFramebuffer?
Jorge Rodriguez
2
Inspirado por este tema, escribí implementaciones de encabezado único de renderizadores Vulkan y DX12: renderizadores: github.com/chaoticbob/tinyrenderers
codingforlove