Escolhendo um recurso
Um recurso é uma coleção de dados usada pelo pipeline 3D. Criar recursos e definir seu comportamento é o primeiro passo para programar seu aplicativo. Este guia aborda tópicos básicos para escolher os recursos exigidos pelo seu aplicativo.
Identifique os estágios do pipeline que precisam de recursos
A primeira etapa é escolher o estágio (ou estágios) do pipeline gráfico que usará um recurso. Ou seja, identifique cada estágio que lerá dados de um recurso, bem como os estágios que gravarão dados em um recurso. Conhecer os estágios do pipeline em que os recursos serão usados determina as APIs que serão chamadas para associar o recurso ao estágio.
Esta tabela lista os tipos de recursos que podem ser associados a cada estágio do pipeline. Inclui se o recurso pode ser associado como uma entrada ou uma saída.
Estágio do pipeline | Entrada/saída | Recurso | Tipo de recurso |
---|---|---|---|
Entrada do assembler | Em | Buffer de vértice | Buffer |
Entrada do assembler | Em | Buffer de índice | Buffer |
Estágios de sombreamento | Em | Shader-ResourceView | Buffer, Texture1D, Texture2D, Texture3D |
Estágios de sombreamento | Em | Buffer constante de sombreador | Buffer |
Saída de fluxo | Saída | Buffer | Buffer |
Fusão de saída | Saída | Visualização de destino de renderização | Buffer, Texture1D, Texture2D, Texture3D |
Fusão de saída | Saída | Visualização de profundidade/estêncil | Textura1D, Textura2D |
Identifique como cada recurso será usado
Depois de escolher os estágios do pipeline que seu aplicativo usará (e, portanto, os recursos que cada estágio exigirá), a próxima etapa é determinar como cada recurso será usado, ou seja, se um recurso pode ser acessado pela CPU ou pela GPU.
O hardware em que seu aplicativo está sendo executado terá no mínimo uma CPU e uma GPU. Para escolher um valor de uso, considere qual tipo de processador precisa ler ou gravar no recurso entre as opções a seguir.
Uso de recurso | Pode ser atualizado por | Frequência de atualização |
---|---|---|
Padrão | GPU | raramente |
Dinâmico | CPU | frequente |
Staging | GPU | N/D |
Imutável | CPU (somente no momento da criação do recurso) | N/D |
O uso padrão deve ser usado para um recurso que deve ser atualizado pela CPU com pouca frequência (menos de uma vez por quadro). Idealmente, a CPU nunca gravaria diretamente em um recurso com uso padrão para evitar possíveis penalidades de desempenho.
O uso dinâmico deve ser usado para um recurso que a CPU atualiza com relativa frequência (uma ou mais vezes por quadro). Um cenário típico para um recurso dinâmico seria criar buffers dinâmicos de vértice e índice que seriam preenchidos em tempo de execução com dados sobre a geometria visível do ponto de vista do usuário para cada quadro. Esses buffers seriam usados para renderizar apenas a geometria visível para o usuário para esse quadro.
O uso de preparo deve ser usado para copiar dados de e para outros recursos. Um cenário típico seria copiar dados em um recurso com uso padrão (que a CPU não pode acessar) para um recurso com uso de preparo (que a CPU pode acessar).
Os recursos imutáveis devem ser usados quando os dados no recurso nunca forem alterados.
Outra maneira de ver a mesma ideia é pensar no que um aplicativo faz com um recurso.
Como o Aplicativo usa o Recurso | Uso de recurso |
---|---|
Carregar uma vez e nunca atualizar | Imutável ou padrão |
O aplicativo preenche o recurso repetidamente | Dinâmico |
Renderizar para textura | Padrão |
Acesso da CPU aos dados da GPU | Staging |
Se você não tiver certeza de qual uso escolher, comece com o uso padrão, pois espera-se que seja o caso mais comum. Um buffer Shader-Constant é o único tipo de recurso que sempre deve ter uso padrão.
Associando recursos a estágios de pipeline
Um recurso pode ser associado a mais de um estágio de pipeline ao mesmo tempo, desde que as restrições especificadas quando o recurso foi criado sejam atendidas. Essas restrições são especificadas como sinalizadores de uso, sinalizadores de ligação ou sinalizadores de acesso à CPU. Mais especificamente, um recurso pode ser associado como entrada e saída simultaneamente, desde que a leitura e a gravação de parte de um recurso não possam ocorrer ao mesmo tempo.
Ao associar um recurso, pense em como a GPU e a CPU acessarão o recurso. Os recursos projetados para uma única finalidade (não use vários sinalizadores de uso, associação e acesso à CPU) provavelmente resultarão em melhor desempenho.
Por exemplo, considere o caso de um destino de renderização usado como uma textura várias vezes. Pode ser mais rápido ter dois recursos: um destino de renderização e uma textura usada como um recurso de sombreador. Cada recurso usaria apenas um sinalizador de associação, indicando "destino de renderização" ou "recurso de sombreador". Os dados seriam copiados da textura de destino de renderização para a textura do sombreador.
Essa técnica neste exemplo pode melhorar o desempenho isolando a gravação de destino de renderização da leitura de textura do sombreador. A única maneira de ter certeza é implementar ambas as abordagens e medir a diferença de desempenho em seu aplicativo específico.
Tópicos relacionados