Mapeando endereços virtuais para um segmento de memória
O driver de miniporto de exibição pode especificar, para cada segmento de espaço de memória ou espaço de abertura que ele define, se os endereços virtuais da CPU podem ser mapeados diretamente para uma alocação localizada no segmento definindo o sinalizador de campo de bit CpuVisible no membro Flags da estrutura DXGK_SEGMENTDESCRIPTOR para o segmento.
Para mapear um endereço virtual de CPU para um segmento, o segmento deve ter acesso linear por meio da abertura PCI. Em outras palavras, o deslocamento de qualquer alocação dentro do segmento deve ser o mesmo que o deslocamento na abertura PCI. Portanto, o gerenciador de memória de vídeo pode calcular o endereço físico relativo ao barramento de qualquer alocação com base no deslocamento da alocação dentro do segmento fornecido.
O diagrama a seguir ilustra como os endereços virtuais são mapeados para um segmento de espaço de memória linear.
O diagrama a seguir ilustra como os endereços virtuais são mapeados para as páginas subjacentes de um segmento de espaço de abertura linear.
Antes de mapear um endereço virtual para uma parte do segmento, o gerenciador de memória de vídeo chama a função DxgkDdiAcquireSwizzlingRange do driver de exibição para que o driver possa configurar a abertura usada para acessar bits da alocação que podem ser girados. O driver não pode alterar nem o deslocamento para a abertura PCI em que a alocação é acessada nem a quantidade de espaço que a alocação ocupa na abertura. Se o driver não puder tornar a alocação acessível pela CPU devido a essas restrições (por exemplo, o hardware possivelmente ficou sem abertura deswizzling), o gerenciador de memória de vídeo removerá a alocação para a memória do sistema e permitirá que o aplicativo acesse os bits lá.
Se o conteúdo de uma alocação criada anteriormente estiver na memória do sistema quando o driver de exibição do modo de usuário chamar a função pfnLockCb para solicitar acesso direto à memória, o gerenciador de memória de vídeo retornará o buffer de memória do sistema para o driver de exibição do modo de usuário e o driver de miniporto de exibição não estará envolvido no acesso à alocação. Portanto, o conteúdo da alocação não é modificado pelo driver de miniporto de exibição e permanece no formato deswizzled. Isso implica que, quando uma alocação acessível por CPU é removida da memória de vídeo, o driver de miniporto de exibição deve deswizzle a alocação para que os bits de memória resultantes do sistema possam ser acessados diretamente pelo aplicativo.
Se os recursos de GPU associados a uma alocação atualmente mapeada para acesso direto ao aplicativo forem removidos, o conteúdo da alocação será transferido para a memória do sistema para que o aplicativo possa continuar a acessar o conteúdo no mesmo endereço virtual, mas meio físico diferente. Para configurar a transferência, o gerenciador de memória de vídeo chama a função DxgkDdiBuildPagingBuffer do driver de vídeo para criar um buffer de paginação e o agendador de GPU chama a função DxgkDdiSubmitCommand do driver para enfileirar o buffer de paginação para a unidade de execução da GPU. O comando de transferência específico do hardware está no buffer de paginação. Para obter mais informações, consulte Enviando um buffer de comando. O gerenciador de memória de vídeo garante que a transição do vídeo para a memória do sistema seja invisível para o aplicativo. No entanto, o driver deve garantir que a ordenação de bytes de uma alocação por meio da abertura PCI corresponda exatamente à ordenação de bytes da alocação quando a alocação é removida.
Para segmentos de espaço de abertura, os bits subjacentes da alocação já estão na memória do sistema, portanto, nenhuma transferência (deswizzling) de dados durante o processo de remoção é necessária. Portanto, uma alocação acessível à CPU localizada em um segmento de espaço de abertura não poderá ser girada se for acessada diretamente por um aplicativo.
Se uma superfície for diretamente acessível por meio da CPU por um aplicativo, mas for girada em um segmento de espaço de abertura, os drivers de exibição deverão implementar a superfície como duas alocações diferentes. Quando o driver de exibição do modo de usuário cria essa superfície, ele pode chamar a função pfnAllocateCb e pode definir o membro NumAllocations da estrutura D3DDDICB_ALLOCATE como 2 e os membros pPrivateDriverData das estruturas de D3DDDI_ALLOCATIONINFO na matriz pAllocationInfo de D3DDDICB_ALLOCATE apontar para dados privados sobre as alocações (como seus formatos deswizzled e deswizzled). A alocação que será usada pela GPU contém bits no formato de swizzled e a alocação que será acessada pelo aplicativo contém os bits em formato sem janelas. O gerenciador de memória de vídeo chama a função DxgkDdiCreateAllocation do driver de miniporto de exibição para criar as alocações. O driver de miniporto de exibição interpreta os dados privados (no membro pPrivateDriverData da estrutura DXGK_ALLOCATIONINFO para cada alocação) que são passados do driver de exibição do modo de usuário. O gerenciador de memória de vídeo não está ciente do formato das alocações; ele apenas aloca blocos de memória de determinados tamanhos e alinhamentos para as alocações. Uma chamada para a função Lock do driver de exibição do modo de usuário para bloquear a superfície para processamento causa as seguintes ações:
O driver de exibição do modo de usuário chama a função pfnRenderCb para enviar a operação deswizzle no buffer de comando para o runtime do Direct3D e para o driver de miniporto de exibição.
O driver de exibição do modo de usuário chama a função pfnLockCb para bloquear a alocação deswizzled. Observe que o driver de exibição do modo de usuário não deve definir o sinalizador D3DDDILOCKCB_DONOTWAIT no membro Flags da estrutura D3DDDICB_LOCK.
A função pfnLockCb aguarda até que a transferência (deswizzling) entre alocações seja executada.
A função pfnLockCb solicita que o driver de miniporto de exibição obtenha um endereço virtual para a alocação deswizzled e retorna o endereço virtual para o driver de exibição do modo de usuário no membro pData do D3DDDICB_LOCK.
O driver de exibição do modo de usuário retorna o endereço virtual da alocação deswizzled para o aplicativo no membro pSurfData do D3DDDIARG_LOCK.