APIs de recurso lado a lado
As APIs descritas nesta seção funcionam com recursos lado a lado e pool de blocos.
- Atribuindo blocos de um pool de blocos a um recurso
- Consultando blocos de recursos e suporte
- Copiando dados lado a lado
- Redimensionar pool de blocos
- Barreira de recursos lado a lado
- Tópicos relacionados
Atribuindo blocos de um pool de blocos a um recurso
As APIs ID3D11DeviceContext2::UpdateTileMappings e ID3D11DeviceContext2::CopyTileMappings manipulam e consultam mapeamentos de blocos. As chamadas de atualização afetam apenas os blocos identificados na chamada e outros são deixados conforme definido anteriormente.
Qualquer bloco de um pool de blocos pode ser mapeado para vários locais em um recurso e até mesmo para vários recursos. Esse mapeamento inclui blocos em um recurso que têm um layout escolhido pela implementação (empacotamento mipmap) em que vários mipmaps são empacotados juntos em um único bloco. A captura é que, se os dados forem gravados no bloco por meio de um mapeamento, mas lidos por meio de um mapeamento configurado de forma diferente, os resultados serão indefinidos. No entanto, o uso cuidadoso dessa flexibilidade ainda pode ser útil para um aplicativo, como compartilhar um bloco entre recursos que não serão usados simultaneamente, em que o conteúdo do bloco é sempre inicializado por meio do mesmo mapeamento de recursos do qual eles serão lidos posteriormente. Da mesma forma, um bloco mapeado para conter os mipmaps empacotados de vários recursos diferentes com as mesmas dimensões de superfície funcionará bem - os dados aparecerão da mesma forma em ambos os mapeamentos.
As alterações nas atribuições de bloco para um recurso podem ser feitas a qualquer momento em um contexto imediato ou adiado.
Consultando blocos de recursos e suporte
Para consultar blocos de recursos, use ID3D11Device2::GetResourceTiling.
Para obter suporte a outros recursos lado a lado, use ID3D11Device2::CheckMultisampleQualityLevels1.
Copiando dados lado a lado
Todos os métodos no Direct3D para mover dados em torno do trabalho com recursos lado a lado como se não estivessem lado a lado, exceto que as gravações em áreas não mapeadas são descartadas e as leituras de áreas não mapeadas produzem 0. Se uma operação de cópia envolver a gravação no mesmo local de memória várias vezes porque vários locais no recurso de destino são mapeados para a mesma memória de bloco, as gravações resultantes em blocos multi mapeados são não determinísticas e não repetíveis. Ou seja, os acessos acontecem em qualquer ordem em que o hardware executa a cópia.
O Direct3D 11.2 apresenta métodos para estas maneiras adicionais de copiar:
- Copiar entre blocos em um recurso lado a lado (com granularidade de bloco de 64 KB) e (de/para) um buffer na memória da GPU (unidade de processamento gráfico) (ou recurso de preparo) – ID3D11DeviceContext2::CopyTiles
- Copiar da memória fornecida pelo aplicativo para blocos em um recurso lado a lado – ID3D11DeviceContext2::UpdateTiles
Esses métodos giram/deswizzle conforme necessário e permitem um sinalizador D3D11_TILE_COPY_NO_OVERWRITE quando o chamador promete que a memória de destino não é referenciada pelo trabalho de GPU que está em andamento.
Os blocos envolvidos na cópia não podem incluir blocos que contenham mipmaps empacotados ou que tenham resultados indefinidos. Para transferir dados de/para mipmaps que o hardware empacota em um bloco, você deve usar as APIs de Cópia/Atualização padrão (não específicas de bloco) ou ID3D11DeviceContext::GenerateMips para toda a cadeia de mip.
Observação em GenerateMips: o uso de ID3D11DeviceContext::GenerateMips em um recurso com blocos parcialmente mapeados produzirá resultados que simplesmente seguem as regras para ler e gravar NULL aplicadas a qualquer algoritmo que o driver de hardware e exibição usar para GenerateMips. Portanto, não é particularmente útil para um aplicativo se preocupar em fazer isso, a menos que, de alguma forma, as áreas com mapeamentos NULL (e seu efeito em outros mips durante a fase de geração) não tenham nenhuma consequência nas partes da superfície com as quais o aplicativo se importa.
Copiar dados de bloco de uma superfície de preparo ou da memória do aplicativo seria a maneira de carregar blocos que podem ter sido transmitidos para fora do disco, por exemplo. Uma variação ao transmitir para fora do disco é carregar algum tipo de dados compactados na memória da GPU e, em seguida, decodificar na GPU. O destino de decodificação pode ser um recurso de buffer na memória gpu, do qual CopyTiles copia para o recurso lado a lado real. Essa etapa de cópia permite que a GPU gire quando o padrão de swizzle não é conhecido. O giro não será necessário se o recurso lado a lado for um recurso de buffer (por exemplo, em vez de uma Textura).
O layout de memória dos blocos no lado do recurso de buffer não lado a lado da cópia é simplesmente linear na memória dentro de blocos de 64 KB, que o driver de hardware e de exibição giraria/deswizzle por bloco conforme apropriado ao transferir de/para um recurso lado a lado. Para superfícies msaa (suavização de várias amostras), os exemplos de cada pixel são percorridos em ordem de índice de exemplo antes de passar para o próximo pixel. Para blocos parcialmente preenchidos no lado direito (para uma superfície que tem uma largura que não é um múltiplo de largura de bloco em pixels), a inclinação/passo para baixo de uma linha é o tamanho total em bytes dos pixels numéricos que caberiam no bloco se o bloco estivesse cheio. Portanto, pode haver uma lacuna entre cada linha de pixels na memória. Para simplificar a especificação, mipmaps menores que um bloco não são empacotados juntos no layout linear. Isso parece ser um desperdício de espaço de memória, mas, conforme mencionado, copiar para mips que os pacotes de hardware juntos não é permitido por meio de CopyTiles ou UpdateTiles. O aplicativo pode usar apenas APIs genéricas UpdateSubresource*() ou CopySubresource*() para copiar mips pequenos individualmente, embora no caso de CopySubresource*() isso significa que a memória linear deve ser a mesma dimensão que o recurso lado a lado - CopySubresource*() não pode copiar de um recurso de buffer para um Texture2D, por exemplo.
Se um swizzle padrão de hardware for definido, os sinalizadores poderão ser adicionados para indicar que os dados no buffer devem ser interpretados nesse formato (nenhum swizzle necessário na transferência), embora abordagens alternativas para carregar dados também possam fazer sentido nesse caso, como permitir que aplicativos acessem diretamente a memória do pool de blocos.
A cópia de operações pode ser feita em um contexto imediato ou adiado.
Redimensionar pool de blocos
Para redimensionar um pool de blocos, use ID3D11DeviceContext2::ResizeTilePool.
Barreira de recursos lado a lado
Para especificar uma restrição de ordenação de acesso a dados entre vários recursos lado a lado, use ID3D11DeviceContext2::TiledResourceBarrier.
Tópicos relacionados