Tipos de recursos (Direct3D 10)
Todos os recursos usados pelo pipeline Direct3D derivam de dois tipos básicos de recursos: buffers e texturas. Um buffer é uma coleção de dados brutos (elementos); Uma textura é uma coleção de texels (elementos de textura).
Há duas maneiras de especificar totalmente o layout (ou o espaço ocupado pela memória) de um recurso:
Item | Descrição |
---|---|
Digitado |
Especifique totalmente o tipo quando o recurso for criado. |
Sem tipo |
Especifique totalmente o tipo quando o recurso estiver vinculado ao pipeline. |
Recursos de buffer
Um recurso de buffer é uma coleção de dados totalmente tipados; Internamente, um buffer contém elementos. Um elemento é composto de 1 a 4 componentes. Exemplos de tipos de dados de elemento incluem: um valor de dados compactado (como R8G8B8A8), um único inteiro de 8 bits, quatro valores flutuantes de 32 bits. Esses tipos de dados são usados para armazenar dados, como um vetor de posição, um vetor normal, uma coordenada de textura em um buffer de vértice, um índice em um buffer de índice ou o estado do dispositivo.
Um buffer é criado como um recurso não estruturado. Como não é estruturado, um buffer não pode conter níveis de mipmap, não é filtrado quando lido e não pode ser multiamostrado.
Tipos de buffer
Buffer de vértice
Um buffer é uma coleção de elementos; Um buffer de vértice contém dados por vértice. O exemplo mais simples é um buffer de vértice que contém um tipo de dados, como dados de posição. Ele pode ser visualizado como a ilustração a seguir.
Mais frequentemente, um buffer de vértice contém todos os dados necessários para especificar totalmente os vértices 3D. Um exemplo disso pode ser um buffer de vértice que contém coordenadas por posição de vértice, normal e de textura. Esses dados geralmente são organizados como conjuntos de elementos por vértice, conforme mostrado na ilustração a seguir.
Esse buffer de vértice contém dados por vértice para oito vértices; Cada vértice armazena três elementos (coordenadas de posição, normal e textura). A posição e o normal são normalmente especificados usando três flutuadores de 32 bits (DXGI_FORMAT_R32G32B32_FLOAT) e as coordenadas de textura usando dois flutuadores de 32 bits (DXGI_FORMAT_R32G32_FLOAT).
Para acessar dados de um buffer de vértice, você precisa saber qual vértice acessar e esses outros parâmetros de buffer:
- Deslocamento - o número de bytes desde o início do buffer até os dados do primeiro vértice. O deslocamento é fornecido para IASetVertexBuffers.
- BaseVertexLocation - o número de bytes do deslocamento para o primeiro vértice usado pela chamada de desenho apropriada (consulte Métodos de desenho).
Antes de criar um buffer de vértice, você precisa definir seu layout criando um objeto de layout de entrada, isso é feito chamando CreateInputLayout. Depois que o objeto input-layout for criado, vincule-o ao estágio input-assembler chamando IASetInputLayout.
Para criar um buffer de vértice, chame CreateBuffer.
Buffer de índice
Um buffer de índice contém um conjunto sequencial de índices de 16 bits ou 32 bits; Cada índice é usado para identificar um vértice em um buffer de vértice. O uso de um buffer de índice com um ou mais buffers de vértice para fornecer dados ao estágio IA é chamado de indexação. Um buffer de índice pode ser visualizado como a ilustração a seguir.
Os índices sequenciais armazenados em um buffer de índice estão localizados com os seguintes parâmetros:
- Deslocamento - o número de bytes do início do buffer até o primeiro índice. O deslocamento é fornecido para IASetIndexBuffer.
- StartIndexLocation - o número de bytes do deslocamento para o primeiro vértice usado pela chamada de desenho apropriada (consulte Métodos de desenho).
- IndexCount - o número de índices a serem renderizados.
Para criar um buffer de índice, chame CreateBuffer.
Um buffer de índice pode costurar várias faixas de linha ou triângulo separando cada uma com um índice de corte de faixa. Um índice de strip-cut permite que várias linhas ou triângulos sejam desenhados com uma única chamada de desenho. Um índice strip-cut é simplesmente o valor máximo possível para o índice (0xffff para um índice de 16 bits, 0xffffffff para um índice de 32 bits). O índice de corte de tiras redefine a ordem de enrolamento em primitivas indexadas e pode ser usado para remover a necessidade de triângulos degenerados que, de outra forma, podem ser necessários para manter a ordem de enrolamento adequada em uma faixa de triângulo. A ilustração a seguir mostra um exemplo de um índice de strip-cut.
Buffer constante
O Direct3D 10 introduziu um novo buffer para fornecer constantes de sombreador chamado buffer constante de sombreador ou simplesmente buffer constante. Conceitualmente, ele se parece com um buffer de vértice de elemento único, conforme mostrado na ilustração a seguir.
Cada elemento armazena uma constante de componente de 1 a 4, determinada pelo formato dos dados armazenados.
Os buffers de constantes reduzem a largura de banda necessária para atualizar as constantes de sombreador, permitindo que as constantes de sombreador sejam agrupadas e confirmadas ao mesmo tempo, em vez de fazer chamadas individuais para confirmar cada constante separadamente.
Para criar um buffer constante de sombreador, chame CreateBuffer e especifique o sinalizador de ligação de buffer constante D3D10_BIND_CONSTANT_BUFFER (consulte D3D10_BIND_FLAG).
Para vincular um buffer constante de sombreador ao pipeline, chame um destes métodos: GSSetConstantBuffers, PSSetConstantBuffers ou VSSetConstantBuffers.
Observe que, ao usar a interface ID3D10Effect Interface, o processo de criação, vinculação e confirmação de um buffer constante é manipulado pela instância ID3D10Effect Interface. Nesse caso, é necessário apenas obter a variável do efeito com um dos métodos GetVariable como GetVariableByName e atualizar a variável com um dos métodos SetVariable como SetMatrix. Para obter um exemplo de como usar ID3D10Effect Interface para gerenciar um buffer constante, consulte o tutorial 07.
Um sombreador continua a ler variáveis em um buffer constante diretamente pelo nome da variável da mesma maneira que as variáveis que não fazem parte de um buffer constante são lidas.
Cada estágio de sombreador permite até 15 buffers constantes de sombreador; Cada buffer pode conter até 4096 constantes.
Use um buffer constante para armazenar os resultados do estágio de saída de fluxo.
Consulte Constantes de sombreador (DirectX HLSL) para obter um exemplo de declaração de um buffer constante em um sombreador.
Recursos de textura
Um recurso de textura é uma coleção estruturada de dados projetada para armazenar texels. Ao contrário dos buffers, as texturas podem ser filtradas por amostradores de textura à medida que são lidas por unidades de sombreador. O tipo de textura afeta a forma como a textura é filtrada. Um texel representa a menor unidade de uma textura que pode ser lida ou gravada pelo pipeline. Cada texel contém 1 a 4 componentes, organizados em um dos formatos DXGI (veja DXGI_FORMAT).
As texturas são criadas como um recurso estruturado para que seu tamanho seja conhecido. No entanto, cada textura pode ser digitada ou digitar menos no momento da criação do recurso, desde que o tipo seja totalmente especificado usando um modo de exibição quando a textura estiver vinculada ao pipeline.
Tipos de textura
Existem vários tipos de texturas: 1D, 2D, 3D, cada uma das quais pode ser criada com ou sem mipmaps. O Direct3D 10 também oferece suporte a matrizes de textura e texturas com várias amostras.
Textura 1D
Uma textura 1D em sua forma mais simples contém dados de textura que podem ser endereçados com uma única coordenada de textura; Ele pode ser visualizado como uma matriz de Texels, como mostrado na ilustração a seguir.
Cada texel contém um número de componentes de cor, dependendo do formato dos dados armazenados. Adicionando mais complexidade, você pode criar uma textura 1D com níveis mipmap, conforme mostrado na ilustração a seguir.
Um nível mipmap é uma textura que é um poder de dois menor do que o nível acima dele. O nível mais alto contém mais detalhes, cada nível subsequente é menor; para um mipmap 1D, o menor nível contém um texel. Os diferentes níveis são identificados por um índice chamado LOD (level-of-detail); você pode usar o LOD para acessar uma textura menor ao renderizar geometria que não esteja tão próxima da câmera.
Matriz de textura 1D
O Direct3D 10 também tem uma nova estrutura de dados para uma matriz de texturas. Uma matriz de texturas 1D se parece conceitualmente com a ilustração a seguir.
Essa matriz de textura contém três texturas. Cada uma das três texturas tem uma largura de textura de 5 (que é o número de elementos na primeira camada). Cada textura também contém um mipmap de 3 camadas.
Todas as matrizes de textura no Direct3D são uma matriz homogênea de texturas; Isso significa que cada textura em uma matriz de textura deve ter o mesmo formato e tamanho de dados (incluindo largura de textura e número de níveis MIPMAP). Você pode criar matrizes de textura de tamanhos diferentes, desde que todas as texturas em cada matriz correspondam em tamanho.
Textura 2D e matriz de textura 2D
Um recurso Texture2D contém uma grade 2D de texels. Cada texel é endereçável por um vetor u, v. Por ser um recurso de textura, ele pode conter níveis e subrecursos de mipmap. Um recurso de textura 2D totalmente preenchido se parece com a ilustração a seguir.
Este recurso de textura contém uma única textura 3x5 com três níveis de mipmap.
Um recurso Texture2DArray é uma matriz homogênea de texturas 2D; ou seja, cada textura tem o mesmo formato de dados e dimensões (incluindo níveis mipmap). Ele tem um layout semelhante ao da matriz de textura 1D, exceto que as texturas agora contêm dados 2D e, portanto, se parece com a ilustração a seguir.
Essa matriz de textura contém três texturas; Cada textura é 3x5 com dois níveis MIPMAP.
Usando um Texture2DArray como um cubo de textura
Um cubo de textura é uma matriz de textura 2D que contém 6 texturas, uma para cada face do cubo. Um cubo de textura totalmente preenchido se parece com a ilustração a seguir.
Uma matriz de textura 2D que contém 6 texturas pode ser lida de dentro de sombreadores com as funções intrínsecas do mapa de cubo, depois que elas são vinculadas ao pipeline com uma exibição de textura de cubo. Os cubos de textura são endereçados a partir do sombreador com um vetor 3D apontando para fora do centro do cubo de textura.
Textura 3D
Um recurso Texture3D (também conhecido como textura de volume) contém um volume 3D de texels. Como é um recurso de textura, ele pode conter níveis de mipmap. Uma textura 3D totalmente preenchida se parece com a ilustração a seguir.
Quando uma fatia mipmap de textura 3D é vinculada como uma saída de destino de renderização (com uma exibição de destino de renderização), a textura 3D se comporta de forma idêntica a uma matriz de textura 2D com n fatias. A fatia de renderização específica é escolhida a partir do estágio de sombreador de geometria, declarando um componente escalar de dados de saída como o SV_RenderTargetArrayIndex valor do sistema.
Não existe o conceito de uma matriz de textura 3D; portanto, um subrecurso de textura 3D é um único nível de mipmap.
Sub-recursos
A API do Direct3D 10 faz referência a recursos inteiros ou subconjuntos de recursos. Para especificar parte dos recursos, o Direct3D cunhou o termo subrecursos, que significa um subconjunto de um recurso.
Um buffer é definido como um único subrecurso. As texturas são um pouco mais complicadas, pois existem vários tipos de texturas diferentes (1D, 2D, etc.) alguns dos quais suportam níveis de mipmap e/ou matrizes de textura. Começando com o caso mais simples, uma textura 1D é definida como um único subrecurso, conforme mostrado na ilustração a seguir.
Isso significa que a matriz de texels que compõem uma textura 1D está contida em um único subrecurso.
Se você expandir uma textura 1D com três níveis de mipmap, ela poderá ser visualizada assim.
Pense nisso como uma única textura que é composta por três subtexturas. Cada subtextura é contada como um subrecurso, portanto, essa textura 1D contém 3 subrecursos. Uma subtextura (ou subrecurso) pode ser indexada usando o nível de detalhe (LOD) para uma única textura. Ao usar uma matriz de texturas, acessar uma subtextura específica requer o LOD e a textura específica. Como alternativa, a API combina essas duas informações em um único índice de subrecursos baseado em zero, conforme mostrado aqui.
Selecionando subrecursos
Algumas APIs acessam um recurso inteiro (por exemplo, CopyResource), outras acessam uma parte de um recurso (por exemplo, UpdateSubresource ou CopySubresourceRegion). As APIs que acessam uma parte de um recurso geralmente usam uma descrição de exibição (como D3D10_TEX2D_ARRAY_DSV) para especificar os subrecursos a serem acessados.
Essas figuras ilustram os termos usados por uma descrição de exibição ao acessar uma matriz de texturas.
Fatia de matriz
Dada uma matriz de texturas, cada textura com mipmaps, uma fatia de matriz (representada pelo retângulo branco) inclui uma textura e todas as suas subtexturas, conforme mostrado na ilustração a seguir.
Mip Fatia
Uma fatia mip (representada pelo retângulo branco) inclui um nível mipmap para cada textura em uma matriz, conforme mostrado na ilustração a seguir.
Selecionando um único subrecurso
Você pode usar esses dois tipos de fatias para escolher um único subrecurso, conforme mostrado na ilustração a seguir.
Selecionando vários subrecursos
Ou você pode usar esses dois tipos de fatias com o número de níveis de mipmap e/ou número de texturas, para escolher vários subrecursos.
Independentemente do tipo de textura que você está usando, com ou sem mipmaps, com ou sem uma matriz de textura, você pode usar a função auxiliar, D3D10CalcSubresource, para calcular o índice de um subrecurso específico.
Digitação forte x fraca
A criação de um recurso totalmente tipado restringe o recurso ao formato com o qual foi criado. Isso permite que o tempo de execução otimize o acesso, especialmente se o recurso for criado com sinalizadores indicando que ele não pode ser mapeado pelo aplicativo. Os recursos criados com um tipo específico não podem ser reinterpretados usando o mecanismo de exibição.
Em um recurso sem tipo, o tipo de dados é desconhecido quando o recurso é criado pela primeira vez. O aplicativo deve escolher entre os formatos de tipo menos disponíveis (consulte DXGI_FORMAT). Você deve especificar o tamanho da memória a ser alocada e se o tempo de execução precisará gerar as subtexturas em um mipmap. No entanto, o formato exato de dados (se a memória será interpretada como inteiros, valores de ponto flutuante, inteiros não assinados etc.) não é determinado até que o recurso seja vinculado ao pipeline com uma exibição. Como o formato de textura permanece flexível até que a textura seja vinculada ao pipeline, o recurso é chamado de armazenamento de tipo fraco. O armazenamento de tipos fracos tem a vantagem de poder ser reutilizado ou reinterpretado (em outro formato), desde que o bit do componente do novo formato corresponda à contagem de bits do formato antigo.
Um único recurso pode ser vinculado a vários estágios de pipeline, desde que cada um tenha uma exibição exclusiva, o que qualifica totalmente os formatos em cada local. Por exemplo, um recurso criado com o formato DXGI_FORMAT_R32G32B32A32_TYPELESS pode ser usado como um DXGI_FORMAT_R32G32B32A32_FLOAT e um DXGI_FORMAT_R32G32B32A32_UINT em diferentes locais no pipeline simultaneamente.
Tópicos relacionados