Alocação de buffer de vértice e comando

Há três tipos de buffers usados no Direct3D:

  • Buffers de vértice implícitos, que são criados somente para uso interno; ou seja, os aplicativos não estão cientes deles. Um buffer de vértice implícito é sempre criado após a criação do contexto e o Direct3D armazena dados de vértice neles.

  • Buffers de vértice explícitos, que são criados somente em resposta a uma solicitação de aplicativo. Em seguida, o Direct3D armazena dados de vértice em buffers de vértice explícitos.

  • Buffers de comando, que são criados somente para uso interno; ou seja, os aplicativos não estão cientes dos buffers de comando. O Direct3D armazena dados de comando em buffers de comando.

Buffers de vértice implícitos são buffers de vértice especiais usados internamente pelo Direct3D para envio em lote. Eles são criados durante a inicialização do dispositivo e podem ser multibuffered. Eles são sempre leitura/gravação, portanto, não devem ser colocados na memória de vídeo (para o Microsoft DirectX 6.0 e as versões posteriores). Esse tipo de buffer é marcado pela ausência dos sinalizadores DDSCAPS2_VERTEXBUFFER e DDSCAPS2_COMMANDBUFFER.

Buffers de vértice explícitos são criados e controlados pelo aplicativo. Eles não podem ser multibuffered e não podem ser colocados na memória de vídeo local ou não local, a menos que o sinalizador DDSCAPS_WRITEONLY esteja definido. Buffers de vértice explícitos são marcados com DDSCAPS_VERTEXBUFFER.

Os buffers de comando são usados pelo Direct3D para comandos em lote. Eles podem ser multibuffered e são usados para todas as APIs, exceto para TLVERTEX ou chamadas de API de execução de buffer não mapeadas. Esse tipo de buffer é marcado pelo sinalizador DDSCAPS2_COMMANDBUFFER. Eles são sempre somente gravação, embora nenhum sinalizador explícito esteja definido e nunca contenham instruções inválidas.

Por padrão, o runtime do Direct3D aloca todos esses buffers. Buffers de vértice implícitos e buffers de comando são acessados por meio das superfícies às quais estão associados. Todos os buffers são passados para o retorno de chamada D3dDrawPrimitives2 do driver.

Vértice alocado pelo driver e buffers de comando

Opcionalmente, um driver Direct3D executa a alocação de buffers de vértice e comando fornecendo funções de retorno de chamada. Para fornecer essas funções de retorno de chamada, o driver Direct3D preenche uma estrutura DD_D3DBUFCALLBACKS e aponta o membro lpD3DBufCallbacks da estrutura DD_HALINFO para ela. DD_HALINFO é retornado por DrvGetDirectDrawInfo em resposta à inicialização do componente DirectDraw do driver. Os retornos de chamada relatados na estrutura DD_D3DBUFCALLBACKS são:

Essas funções são chamadas da mesma forma que os retornos de chamada DdXxxSurface (como DdCanCreateSurface) e somente quando o sinalizador DDSCAPS_EXECUTEBUFFER é definido. Os sinalizadores de criação de buffer são DDSCAPS_WRITEONLY, DDSCAPS2_VERTEXBUFFER e DDSCAPS2_COMMANDBUFFER.

Os drivers determinam o tipo de buffer que está sendo solicitado verificando o membro ddsCaps da estrutura DD_SURFACE_LOCAL passada para o retorno de chamada CanCreateExecuteBuffer e CreateExecuteBuffer para os seguintes sinalizadores:

  • DDSCAPS_VERTEXBUFFER indica que o driver deve alocar um buffer de vértice explícito.

  • DDSCAPS_COMMANDBUFFER indica que o driver deve alocar um buffer de comando.

  • Se nenhum sinalizador for definido, o driver deverá alocar um buffer de vértice implícito.

O driver aloca internamente buffers de vértice e comando e percorre esses buffers. O Direct3D preenche um determinado par enquanto o hardware é renderizado de forma assíncrona dos outros buffers enfileirados. Isso é muito útil com o DMA (acesso direto à memória).

Buffers em um conjunto de vários buffers podem estar em diferentes tipos de memória, ou seja, na memória do sistema ou vídeo. Quando o driver é chamado para criar o primeiro buffer, ele cria o conjunto imediatamente e retorna o primeiro buffer no definido como Direct3D. O driver usa sinalizadores para especificar o tipo de memória que ele usou para alocar cada buffer no conjunto. O driver deverá retornar um novo buffer na memória do sistema para cada chamada para D3dDrawPrimitives2 se o sinalizador D3DHALDP2_SWAPVERTEXBUFFER ou D3DHALDP2_SWAPCOMMANDBUFFER estiver definido. Se o buffer retornado estiver na memória de vídeo, o sinalizador de D3DHALDP2_VIDMEMVERTEXBUF ou D3DHALDP2_VIDMEMCOMMANDBUF correspondente deverá ser definido.

Ocasionalmente, o Direct3D solicita o tamanho mínimo para o próximo buffer. Se o tamanho for muito grande, o driver deverá alocar o buffer na memória do sistema (uma superfície de suporte). Se o tamanho for muito pequeno, o driver terá permissão para fornecer um buffer maior. O driver deve acompanhar quantos buffers e quais tipos de memória eles são e limpo tudo na saída.