Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Com a lista de alocação desaparecendo, o gerenciador de memória de vídeo (VidMm) não tem mais visibilidade sobre as alocações que estão sendo referenciadas em um buffer de comando específico. Como resultado, o VidMm já não está em posição de monitorizar o uso da alocação e de lidar com a sincronização relacionada. Esta responsabilidade recai agora sobre o controlador de modo de utilizador (UMD). Em específico, o UMD precisa lidar com a sincronização no que diz respeito ao acesso direto da CPU à alocação e renomeação.
O VidMm adia de forma assíncrona a destruição da alocação de maneira segura, que não bloqueia a execução do fio de chamada e é eficiente em termos de desempenho. Como tal, um UMD não precisa se preocupar em ter que adiar a destruição da alocação. Quando o VidMm recebe uma solicitação de destruição de alocação, ele assume por padrão que os comandos enfileirados antes da solicitação de destruição podem potencialmente acessar a alocação que está sendo destruída. Assim, o VidMm adia a operação de destruição até que os comandos na fila terminem. Se o UMD souber que os comandos pendentes não acessam a alocação que está sendo destruída, ele pode instruir o VidMm a processar a solicitação sem esperar, definindo o sinalizador AssumeNotInUse ao chamar Deallocate2 ou DestroyAllocation2.
Fechadura2
O UMD é responsável por lidar com a sincronização adequada em relação ao acesso direto à CPU. Em particular, uma UMD é obrigada a:
Suporta semântica de bloqueio sem substituição e descarte, o que implica que o UMD precisa implementar seu próprio esquema de renomeação.
Para operações de mapa que exigem sincronização (ou seja, excluindo as operações de não-substituição ou descarte mencionadas acima):
- Retorne WasStillDrawing se for feita uma tentativa de acessar uma alocação que está atualmente ocupada e o chamador tiver solicitado que a operação Lock não bloqueie o thread de chamada (D3D11_MAP_FLAG_DO_NOT_WAIT).
- Ou, se o sinalizador D3D11_MAP_FLAG_DO_NOT_WAIT não estiver definido, aguarde até que uma alocação fique disponível para acesso à CPU. A UMD precisa implementar uma espera sem votação. A UMD utilizará o novo mecanismo de monitorização do contexto.
Por enquanto, o UMD continua a precisar chamar o LockCb/UnlockCb para que o VidMm configure uma alocação para acesso à CPU. Na maioria dos casos, o UMD é capaz de manter a alocação mapeada durante toda a sua vida útil. No entanto, no futuro, LockCb e UnlockCb serão preteridos em favor de novas chamadas Lock2Cb e Unlock2Cb . O objetivo desses retornos de chamada mais recentes é fornecer uma nova implementação limpa com um novo conjunto de argumentos e sinalizadores.
Os intervalos de oscilação são removidos do WDDM versão 2. É responsabilidade do desenvolvedor do driver remover a dependência de intervalos oscilantes de chamadas para LockCb à medida que eles avançam para uma implementação baseada em Lock2Cb.
Lock2Cb é apresentado como um método simples para obter um endereço virtual de uma alocação. Existem algumas restrições com base no tipo de alocação e no segmento em que está atualmente residente.
O driver indica se um segmento é acessível pela CPU através do sinalizador CpuVisible , que está no membro Flags da estrutura DXGK_SEGMENTDESCRIPTOR .
Para alocações acessíveis pela CPU:
- As alocações acessíveis à CPU armazenadas em cache devem residir dentro de um segmento de abertura ou não ser residentes para serem bloqueadas. Não podemos garantir a coerência do cache entre a CPU e um segmento de memória na unidade de processamento gráfico (GPU).
- As alocações acessíveis pela CPU localizadas em um segmento de memória totalmente acessível pela CPU (redimensionadas usando a barra redimensionável) têm a garantia de serem bloqueáveis e capazes de retornar um endereço virtual. Não são necessárias restrições especiais neste cenário.
- Alocações acessíveis pela CPU localizadas em um segmento de memória não acessível por CPU (com ou sem acesso a um CpuHostAperture) podem falhar em ser mapeadas para um endereço virtual da CPU por vários motivos. Se o CpuHostAperture estiver sem espaço disponível ou a alocação não especificar um segmento de abertura, um endereço virtual será impossível de obter. Por esse motivo, todas as alocações acessíveis pela CPU em segmentos de memória não acessíveis pela CPU devem conter um segmento de abertura em seu conjunto de segmentos suportados. Este requisito garante que o VidMm é capaz de colocar a alocação na memória do sistema e fornecer um endereço virtual.
- As alocações acessíveis pela CPU já localizadas na memória do sistema (e/ou mapeadas num segmento de abertura) têm a garantia de funcionar corretamente.
Para alocações não acessíveis pela CPU:
- As alocações acessíveis pela CPU são apoiadas por objetos de seção que não podem apontar diretamente para o buffer de quadros das GPUs. Para bloquear uma alocação não acessível pela CPU, a alocação deve suportar um segmento de abertura no conjunto de segmentos suportados ou já estar na memória do sistema (não deve ser residente no dispositivo).
Se uma alocação for bloqueada com êxito enquanto a alocação não for residente no dispositivo, mas não suportar um segmento de abertura, a alocação não deverá ser confirmada em um segmento de memória durante o período de bloqueio.
Lock2 atualmente não contém sinalizadores e os bits de sinalizador Reservados devem estar todos a 0.
CpuHostAperture
Para suportar melhor o bloqueio com segmentos de memória não acessíveis pela CPU quando o redimensionamento do BAR falha, um CpuHostAperture é fornecido na abertura PCI. O CpuHostAperture funciona como um gestor baseado em páginas, podendo então ser mapeado diretamente para regiões de memória de vídeo através da função de interface de driver de dispositivo (DDI) DxgkDdiMapCpuHostAperture. O VidMm pode então mapear um intervalo de espaço de endereço virtual diretamente para um intervalo não contíguo do CpuHostAperture, e fazer com que o CpuHostAperture seja mapeado para a memória de vídeo sem a necessidade de intervalos oscilantes.
A quantidade máxima de memória bloqueável que a CPU pode referenciar em segmentos de memória não acessíveis pela CPU é limitada ao tamanho do CpuHostAperture. Os detalhes para expor o CpuHostAperture ao kernel gráfico DirectX podem ser encontrados no CPU host aperture.
Coerência de E/S
Atualmente, em x86/x64, todas as GPUs devem suportar coerência de E/S sobre PCIe para permitir que uma GPU leia ou grave em uma superfície de memória do sistema em cache e mantenha a coerência com a CPU. Quando uma superfície é mapeada para ser coerente em cache do ponto de vista da GPU, a GPU precisa verificar os caches da CPU ao acessar a superfície. Essa forma de coerência é normalmente utilizada para recursos em que se prevê que a CPU faça leituras, como algumas superfícies de staging.
Em algumas plataformas Arm, a coerência de E/S não é suportada diretamente no hardware. Nessas plataformas, a coerência de E/S precisa ser emulada invalidando manualmente a hierarquia de cache da CPU. O VidMm faz isso rastreando as operações para uma alocação proveniente da GPU (operação de leitura/gravação da lista de alocação) e da CPU (operação de mapa, leitura/gravação). O VidMm emite uma invalidação de cache quando determina que o cache pode conter:
- Dados que precisam ser gravados de volta (gravação da CPU, leitura da GPU)
- Dados obsoletos que precisam ser invalidados (escrita na GPU, leitura pela CPU).
Em plataformas sem coerência de E/S, a responsabilidade de rastrear o acesso da CPU e GPU às alocações recai sobre o UMD. O kernel gráfico expõe um novo DDI de cache invalidadoque o UMD pode usar para gravar e invalidar o intervalo de endereços virtuais associado a uma alocação em cache. Em plataformas que não têm suporte para coerência de E/S, é necessário que o UMD chame esta função após a gravação da CPU e antes da leitura pela GPU, bem como após a gravação pela GPU e antes da leitura pela CPU. Este último pode parecer pouco intuitivo à primeira vista. Mas, como a CPU poderia ter lido dados especulativamente antes da escrita da GPU ser concluída na memória, é necessário invalidar todos os caches da CPU para garantir que a CPU releia os dados da RAM.