Venus é um driver virtual Vulkan com base no protocolo Virtio-GPU. Basicamente, é um protocolo em cima de outro protocolo. Ele define a serialização de comandos Vulkan entre convidado e host. Esta postagem abordará detalhes do driver Venus, seus componentes e suas relações no contexto de extensões. Em outras palavras, o driver virtual Venus facilita funcionamento do Vulkan. Conheça a seguir mais detalhes a partir de relatos da equipe Collabora.
Quando se trata de aplicativos e bibliotecas Vulkan, você terá dificuldade em escrevê-los sem aproveitar a lista cada vez maior de extensões Vulkan disponibilizadas para aproveitar as peculiaridades e recursos que o hardware gráfico tem a oferecer. Em resumo, as extensões Vulkan são adendos à especificação Vulkan que os drivers não precisam suportar. Eles permitem que os fornecedores expandam a API existente para permitir o uso de recursos que podem ser exclusivos de um determinado fornecedor ou geração de dispositivos sem precisar adaptar a API principal.
Mesmo em ambientes virtualizados, o uso de funcionalidade estendida para aplicativos acelerados por hardware pode ser fundamental para o desempenho. De fato, é algo que os drivers gráficos virtuais, como o Venus, devem levar em consideração.
Driver virtual Venus facilita funcionamento do Vulkan
Muitos elementos compreendem o caminho do pipeline de uma chamada de API Vulkan no Venus. A partir de um aplicativo no convidado, a chamada da API é despachada para o ponto de entrada apropriado no driver Venus Mesa.
O driver Mesa prepara um comando definido pelo Protocolo Venus para ser enviado ao host por meio do driver Virtio-GPU do kernel convidado e da VM. O comando é recebido e decodificado no host pelo Virglrenderer, por meio do qual é despachado para o driver Vulkan do host que executa o trabalho real definido pela chamada da API original. Se um valor de retorno for esperado, o mesmo processo será repetido, mas ao contrário.
Para adicionar extensões, precisamos apenas nos preocupar com três componentes desse pipeline: o driver Mesa, o protocolo e o Virglrenderer.
Driver mesa
Esta parte reside no host e é a biblioteca que configura nossos pontos de entrada da API Vulkan em conjunto com o carregador.
É uma camada relativamente fina cujo objetivo central é serializar comandos e parâmetros do Vulkan. Grande parte da serialização e comunicação com o Virglrenderer é tratada pelo código C gerado. Vamos dar uma olhada neste código gerado mais tarde neste post. Atualmente, pode-se encontrar o código gerado a partir do Protocolo Venus no diretório Mesa src/virtio/venus-protocol.
Por motivos de desempenho e largura de banda, o driver Venus Mesa tenta evitar ao máximo a comunicação com o host armazenando em cache determinados resultados e agrupando comandos em lote quando possível. Por exemplo, ao chamar vkGetPhysicalDeviceFeatures2(), os recursos de todos os dispositivos disponíveis já teriam sido buscados e armazenados em cache de uma chamada anterior para vkEnumeratePhysicalDevices() ou vkEnumeratePhysicalDeviceGroups().
Nesse caso, vkGetPhysicalDeviceFeatures2()apenas retornaria os valores armazenados em cache em vez de viajar para o host.
Virglrenderer
Este componente fica no host e gerencia vários contextos de clientes possíveis decodificando seus comandos, despachando-os para o driver/dispositivo apropriado e enviando de volta os resultados, se necessário.
O próprio Virglrenderer é bastante complexo, e a maior parte da complexidade reside nas partes que lidam com coisas como contexto, memória, etc.
A boa notícia é que não precisamos lidar com contexto para adicionar uma nova extensão. O código que lida com os comandos geralmente é bastante direto porque a maior parte do trabalho pesado é feito pelo código gerado pelo Venus-Protocol.
Protocolo Venus
Venus-protocol é o repositório com um conjunto de arquivos XMLs que juntos compõem a especificação e as ferramentas para gerar código a partir da especificação.
A especificação define como comandos, sombreadores, buffers, eventos e respostas serão serializados e desserializados pelo convidado e pelo host.
No protocolo Venus, geramos (mencionado na seção anterior) código para Mesa e VirglRenderer para lidar com todas essas operações. Os arquivos gerados a partir de vn_protocol_driver_são para o projeto Mesa e vn_protocol_renderer_Virglrenderer. Esses arquivos contêm o respectivo codificador e decodificador para cada função Vulkan suportada.
Todos os comandos especificados pelo protocolo Venus contêm em seus cabeçalhos um identificador que especifica que tipo de carga útil eles carregam e qual identificador gerado irá decodificá-los do outro lado.
Todas as estruturas, enumerações, funções, extensões, versões de API e muito mais são definidas em XMLs. Esses XMLs são analisados por scripts python para gerar os respectivos arquivos .h
.
Para adicionar uma extensão, acesse esta postagem no blog Collabora.