Mapeamentos estão em um pool de blocos
Quando um recurso é criado com o sinalizador D3D11_RESOURCE_MISC_TILED , os blocos que compõem o recurso vêm de apontar para locais em um pool de blocos. Um pool de blocos é um pool de memória (sustentado por uma ou mais alocações nos bastidores - nunca vistos pelo app). O sistema operacional e o driver de vídeo gerenciam esse pool de memória, e o volume da memória é entendido facilmente por um app. Os recursos em bloco mapeiam regiões de 64 KB apontando para locais em um pool de blocos. Um resultado dessa configuração é permitir que vários recursos compartilhem e reutilizem os mesmos blocos, e também que os mesmos blocos sejam reutilizados em locais diferentes em um recurso, se desejado.
O custo da flexibilidade de preenchimento dos blocos de um recurso de um pool de blocos é que ele precisa definir e manter o mapeamento dos blocos no pool que representam aqueles necessários para o recurso. Os mapeamentos de blocos podem ser alterados. Além disso, nem todos os blocos em um recurso precisam ser mapeadas simultaneamente; um recurso pode ter mapeamentos NULOS. Um mapeamento NULO define um bloco como não disponível do ponto de vista do recurso que o acessa.
Vários pools de blocos podem ser criados e qualquer número de recursos em blocos pode ser mapeado para qualquer pool de blocos determinado ao mesmo tempo. Os pools de bloco também podem ser aumentados ou reduzidos. Para obter mais informações, consulte Redimensionamento do pool de blocos. Uma restrição que existe para simplificar a implementação do driver de exibição e do runtime é que um determinado recurso em bloco só pode ter mapeamentos em no máximo um pool de blocos por vez (em vez de ter mapeamento simultâneo para vários pools de blocos).
A quantidade de armazenamento associada a um recurso em bloco (ou seja, memória independente do pool de blocos) é aproximadamente proporcional ao número de blocos realmente mapeados para o pool a qualquer momento. No hardware, esse fato se resume ao dimensionamento do volume de memória para armazenamento da tabela de página aproximadamente com a quantidade de blocos mapeados (por exemplo, usando um esquema de tabela de vários níveis de página conforme apropriado).
O pool de blocos pode ser pensado como uma abstração de software que permite aos apps Direct3D estarem efetivamente prontos para programar as tabelas de página na unidade de processamento gráfico (GPU) sem precisar saber os detalhes de implementação de nível baixo (ou processar endereços de ponteiro diretamente). Os pools de blocos não se aplicam a quaisquer níveis adicionais de indireção no hardware. As otimizações de uma única tabela de página de nível único usando construções como diretórios de página são independentes do conceito de pool de blocos.
Vamos explorar qual armazenamento a tabela de página pode exigir na pior das hipóteses (embora na prática as implementações exigem apenas armazenamento aproximadamente proporcional ao que é mapeado).
Considere que cada entrada da tabela de página é de 64 bits.
Para o tamanho da tabela da página de pior caso atingido para uma única superfície, considerando os limites de recurso no Direct3D 11, suponha que um recurso em bloco seja criado com um formato de 128 bits por elemento (por exemplo, um float RGBA), portanto, um bloco de 64 KB contém apenas 4096 pixels. O tamanho máximo de Texture2DArray com suporte de 16384*16384*2048 (mas com apenas um único mipmap) exigiria cerca de 1 GB de armazenamento na tabela de página se totalmente preenchido (sem incluir mipmaps) usando entradas de tabela de 64 bits. A adição de mipmaps implica no crescimento do armazenamento de tabela de página totalmente mapeada (pior hipótese) em aproximadamente um terço, cerca de 1,3 GB.
Nesse caso, seria equivalente a fornecer acesso a aproximadamente 10,6 terabytes de memória endereçável. Pode haver um limite na quantidade de memória endereçável. Porém, isso reduziria esses valores, talvez próximos do intervalo de terabytes.
Outro caso a ser considerado é um único recurso em bloco Texture2D de 16384*16384 com um formato de 32 bits por elemento, incluindo mipmaps. O espaço necessário em uma tabela de página totalmente preenchida é de aproximadamente 170 KB com entradas de tabela de 64 bits.
Por fim, considere um exemplo usando um formato BC, diga BC7 com 128 bits por bloco de 4 x 4 pixels. Isso equivale a um byte por pixel. Uma Texture2DArray de 16384*16384*2048 incluindo mipmaps exigiria aproximadamente 85 MB para preencher totalmente essa memória em uma tabela de páginas. Isso não é ruim considerando que isso permite que um recurso em bloco abrange 550 gigapixels (512 GB de memória nesse caso).
Na prática, essa quantidade de mapeamentos totais não seria definido considerando que a quantidade de memória física disponível não permite que essa quantidade seja mapeada e referenciada ao mesmo tempo. No entanto, com um pool de blocos, os apps podem optar por reutilizar blocos (um exemplo simples, reutilizar um bloco colorido "preto" para grandes regiões de preto em uma imagem), usando efetivamente o pool de blocos (ou seja, os mapeamentos de tabela de página) como uma ferramenta de compactação de memória.
O conteúdo inicial da tabela da página é NULO para todas as entradas. Os apps também não podem passar dados iniciais do conteúdo da memória da superfície, pois já começa sem suporte da memória.
Nesta seção
Tópico | Descrição |
---|---|
Criação de pool de blocos |
Um pool de blocos é criado por meio da API ID3D11Device::CreateBuffer passando o sinalizador D3D11_RESOURCE_MISC_TILE_POOL no membro MiscFlags da estrutura D3D11_BUFFER_DESC para a qual o parâmetro pDesc aponta. |
Redimensionamento de pool de blocos |
Use a API ID3D11DeviceContext2::ResizeTilePool para aumentar um pool de blocos se o aplicativo precisar de mais conjunto de trabalho para o mapeamento de recursos em bloco ou reduzir se for necessário menos espaço. |
Controle de risco versus recursos de pool de blocos |
Para recursos não em bloco, o Direct3D pode evitar determinadas condições de risco durante a renderização, mas como o rastreamento de riscos estaria em um nível de bloco para recursos em bloco, acompanhar condições de risco durante a renderização de recursos em bloco pode ser muito caro. |