Partilhar via


PFND3DDDI_LOCKCB função de retorno de chamada (d3dumddi.h)

A função pfnLockCb bloqueia uma alocação e obtém um ponteiro para a alocação do driver de miniporto de exibição ou do gerenciador de memória de vídeo.

Sintaxe

PFND3DDDI_LOCKCB Pfnd3dddiLockcb;

HRESULT Pfnd3dddiLockcb(
  HANDLE hDevice,
  D3DDDICB_LOCK *unnamedParam2
)
{...}

Parâmetros

hDevice

Um identificador para o dispositivo de exibição (contexto gráfico).

unnamedParam2

pData [dentro, fora]

Um ponteiro para uma estrutura de D3DDDICB_LOCK que descreve a alocação a ser bloqueada.

Valor de retorno

pfnLockCb retorna um dos seguintes valores:

Código de retorno descrição
S_OK A alocação foi bloqueada com êxito.
D3DERR_NOTAVAILABLE Uma abertura não estava disponível.
D3DERR_WASSTILLDRAWING A alocação ainda estava sendo usada para renderização.
D3DDDIERR_CANTEVICTPINNEDALLOCATION A alocação não pôde ser bloqueada devido à indisponibilidade de uma abertura deswizzling e à incapacidade de remover a alocação porque ela foi fixada.
E_OUTOFMEMORY pfnLockCb não pôde ser concluída devido à memória insuficiente (essa situação ocorre quando o sistema está em uma situação de memória extrema baixa e não há espaço suficiente para alocar a matriz de páginas).
E_INVALIDARG Os parâmetros foram validados e determinados como incorretos.
D3DDDIERR_DEVICEREMOVED pfnLockCb não pôde fazer com que o gerenciador de memória de vídeo e o driver de miniporto executassem as ações apropriadas porque ocorreu uma parada de PnP (Plug and Play) ou um evento TDR (Detecção e Recuperação de Tempo limite). A função de driver de exibição do modo de usuário chamada pfnLockCb(normalmente, a função Lock ou ResourceMap) deve retornar esse código de erro para o runtime do Direct3D.
Direct3D Versão 9 Observação: para obter mais informações sobre como retornar códigos de erro, consulte Retornando códigos de erro recebidos de funções de runtime.
direct3D versões 10 e 11 Observação: se a função de driver não retornar um valor (ou seja, tem VOID para um tipo de parâmetro de retorno), a função de driver chama a função pfnSetErrorCb para enviar um código de erro de volta para o runtime. Para obter mais informações sobre como lidar com códigos de erro, consulte Tratamento de Erros.

Essa função também pode retornar outros valores HRESULT.

Observações

O driver de exibição no modo de usuário pode chamar a função pfnLockCb do runtime do Microsoft Direct3D para bloquear uma alocação e obter um ponteiro para a alocação do driver de miniporto de exibição ou do gerenciador de memória de vídeo. O driver de exibição no modo de usuário normalmente chama pfnLockCb em resposta a uma chamada para sua função de de bloqueio de ou resourceMap (ou outras variações de ResourceMap, como DynamicIABufferMapDiscard) para bloquear um recurso ou uma superfície dentro do recurso. Antes de retornar da chamada de Bloqueio de ou, o driver de exibição do modo de usuário deve primeiro mapear o recurso ou a superfície para a alocação apropriada e, em seguida, chamar pfnLockCb para bloquear a alocação. A alocação deve ser bloqueada antes de ser lida ou gravada porque está bloqueando:

  • Garante que o intervalo de endereços virtuais para a alocação permaneça inalterado, válido, legível e gravável durante o bloqueio. O gerenciador de memória de vídeo fornece essa garantia.
  • Fornece uma maneira de sincronizar as operações de leitura e gravação da alocação com acessos de hardware gráficos da alocação. O gerenciador de memória de vídeo e o driver de miniporto de exibição executam a sincronização.
Direct3D Versão 9 Observação:

O driver de exibição no modo de usuário geralmente chama as funções pfnLockCb e pfnUnlockCb que correspondem a cada chamada às funções Lock e Unlock, respectivamente, exceto quando o driver manipula recursos nos quais o sinalizador de campo de bits dinâmico foi definido no Flags membro da estrutura D3DDDIARG_CREATERESOURCE quando os recursos foram criados. O runtime solicita frequentemente que o driver bloqueie esses tipos de recursos, geralmente com o sinalizador NoOverwrite de campo de bits definido no Flags membro da estrutura D3DDDIARG_LOCK. Como os dados nesses recursos não devem ser modificados (conforme indicado por NoOverwrite), chamar pfnLockCb para cada solicitação de bloqueio consome tempo excessivo de processamento. Para impedir a chamada pfnLockCb para cada solicitação de bloqueio, o driver pode armazenar em cache o ponteiro de memória virtual que retorna no pSurfData membro do D3DDDIARG_LOCK quando sua função Lock é chamada com o conjunto de sinalizadores de campo de bit NoOverwrite. No entanto, o driver pode continuar a chamar pfnLockCb sempre que sua função Lock for chamada com o sinalizador de Descartar de campo de bits definido ou sem sinalizadores definidos.

direct3D versões 10 e 11 Observação:

O driver de exibição do modo de usuário geralmente chama as funções pfnLockCb e pfnUnlockCb que correspondem a cada chamada às suas funções do ResourceMap e ResourceUnmap (ou outras variações dessas funções). Isso não acontece quando o driver manipula recursos nos quais o valor do D3D10_DDI_USAGE_DYNAMIC foi definido no membro uso da estrutura D3D10DDIARG_CREATERESOURCE ou D3D11DDIARG_CREATERESOURCE quando os recursos foram criados. O runtime solicita frequentemente que o driver bloqueie esses tipos de recursos, geralmente passando o valor D3D10_DDI_MAP_WRITE_NOOVERWRITE para o parâmetro DDIMap na chamada para ResourceMap. Como os dados nesses recursos não devem ser modificados (conforme indicado por D3D10_DDI_MAP_WRITE_NOOVERWRITE), chamar pfnLockCb para cada solicitação de bloqueio consome tempo excessivo de processamento. Para impedir a chamada pfnLockCb para cada solicitação de bloqueio, o driver pode armazenar em cache o ponteiro de memória virtual que retorna no parâmetro pMappedSubResource quando sua função resourcemap é chamada com D3D10_DDI_MAP_WRITE_NOOVERWRITE. No entanto, o driver pode continuar a chamar pfnLockCb sempre que sua função ResourceMap for chamada com o valor D3D10_DDI_MAP_WRITE_DISCARD ou 0 passado para o parâmetro DDIMap.

Embora o aplicativo não mantenha um bloqueio pendente no recurso associado ao ponteiro de memória virtual, o driver normalmente desaparata o ponteiro de memória virtual chamando a função pfnUnlockCb antes que o driver chame a função pfnRenderCb . Se o bloqueio não for não armazenado em cache ou se o bloqueio não puder ser armazenado em cache porque o aplicativo ainda tem o recurso bloqueado, o hardware poderá ser renderizado de uma alocação bloqueada. O gerenciador de memória de vídeo não poderá dar suporte a esse modo de operação se a alocação estiver na memória de vídeo local; portanto, o gerenciador de memória remove a alocação para a memória do sistema ou do AGP quando o gerenciador de memória detecta essa situação. Se não houver suporte para a alocação no segmento de memória do sistema ou do AGP, o gerenciador de memória falhará na chamada para pfnRenderCb com D3DDDIERR_CANTRENDERLOCKEDALLOCATION. Portanto, as alocações de buffer de vértice e índice alocadas em resposta à criação de recursos nos quais o sinalizador de campo de bits Dinâmico é definido no Flags membro de D3DDDIARG_CREATERESOURCE (ou o valor D3D10_DDI_USAGE_DYNAMIC é definido no membro de Uso de D3D10DDIARG_CREATERESOURCE ou D3D11DDIARG_CREATERESOURCE) deve ser compatível em segmentos de sistema ou AGP.

Definir o sinalizador de Descartar campo de bits no Flags membro do D3DDDICB_LOCK em uma chamada para pfnLockCb faz com que o gerenciador de memória de vídeo crie uma nova instância da alocação que está sendo bloqueada. O gerenciador de memória de vídeo representa a nova instância retornando um novo identificador para o driver de exibição do modo de usuário no hAllocation membro do D3DDDICB_LOCK.

Observação A função DxgkDdiCreateAllocation do driver de exibição não é chamada quando uma nova instância de uma alocação é criada. As instâncias aparecem no driver de miniporto de exibição como alocações que são simultaneamente paginada em vários locais diferentes.
 
O gerenciador de memória de vídeo pode falhar em um bloqueio no qual o sinalizador de Descartar campo de bits é definido porque o gerenciador de memória de vídeo não pode criar uma nova instância ou reutilizar uma instância existente de uma alocação. Quando essa falha ocorre, o driver de exibição no modo de usuário deve chamar a função pfnRenderCb para liberar seu buffer de comando atual para o kernel. Essa liberação do buffer de comando pode desativar algumas instâncias da alocação que não puderam ser bloqueadas usando o sinalizador de Descartar campo de bits.

Depois de liberar o buffer de comando, o driver de exibição do modo de usuário deve tentar bloquear a superfície novamente usando os sinalizadores de Descartar e NoExistingReference sinalizadores de campo de bit. A NoExistingReference sinalizador de campo de bit indica ao gerenciador de memória de vídeo que o driver não tem atualmente uma referência a nenhuma instância da alocação que está sendo bloqueada na fila em seu buffer de comando. O gerenciador de memória de vídeo pode reutilizar qualquer instância da alocação para lidar com o bloqueio, incluindo a instância atual.

Após uma chamada para pfnLockCb em que o sinalizador de Descartar campo de bits é definido, o driver de exibição no modo de usuário sempre deve verificar se há um valor de identificador atualizado no hAllocation membro do D3DDDICB_LOCK. Se um novo identificador de alocação for fornecido, o driver de exibição no modo de usuário deverá atualizar sua estrutura de dados interna para fazer referência ao novo identificador de alocação. O driver de exibição do modo de usuário também deve adicionar uma versão programada novamente do endereço base de alocação bloqueado ao buffer de comando atual (porque as instâncias de alocação contêm endereços base diferentes). O gerenciador de memória de vídeo valida o uso de instâncias de alocação usadas pelo driver e rejeita buffers DMA que usam as instâncias de alocação incorretamente (ou seja, chamadas para pfnPresentCb e pfnRenderCb falhar se eles usarem incorretamente instâncias de alocação). Depois que o driver faz referência a uma instância específica de uma alocação, o driver não pode mais referenciar uma instância anterior da mesma alocação. Por exemplo, se um buffer de comando usa a alocação A e atualmente usa as instâncias A0 e A1, assim que a A1 é usada (ou seja, aparece na lista de locais de patch) o A0 se torna inválido. O driver de miniporto de exibição pode gerar uma lista de locais de patch que faz referência a A0 e A1. No entanto, as referências devem ser ordenadas (ou seja, A0 pode ser usado primeiro; A0 torna-se inválido quando a A2 é usada; A1 torna-se inválido quando A2 é usado e assim por diante).

O driver de exibição do modo de usuário pode chamar pfnLockCb para alocações de memória do sistema, mesmo que a memória não tenha sido pré-alocada, porque o driver de miniporto de exibição pode realmente estar em processo de envio, por meio de DMA ou transferência assíncrona dessas alocações para hardware gráfico. Portanto, antes que um aplicativo tenha permissão para gravar na superfície, o driver de miniporto de exibição e o gerenciador de memória de vídeo devem ser notificados para que possam bloquear o bloqueio, se necessário.

O driver de exibição do modo de usuário também pode bloquear sub-regiões de uma alocação. Esse tipo de bloqueio normalmente não é necessário quando uma abertura de hardware desorganização ou linearização está disponível porque, nessa situação, o driver de exibição do modo de usuário pode converter um bloqueio em toda a alocação para a sub-região, compensando o ponteiro. No entanto, quando pfnLockCb falha usando D3DERR_NOTAVAILABLE para indicar que uma abertura não está disponível, o gerenciador de memória solicita que o driver de exibição no modo de usuário copie o conteúdo da memória do vídeo. O driver de exibição do modo de usuário deswizzles ou lineariza o conteúdo da memória de vídeo ao copiá-los para outra área da memória. Nessa situação, o driver de exibição no modo de usuário pode fornecer uma lista de páginas a serem copiadas para salvar grandes quantidades de cópia ao bloquear pequenas sub-regiões em uma alocação grande. Observe que o gerenciador de memória falhará em uma chamada para pfnLockCb com D3DERR_NOTAVAILABLE se o driver de exibição no modo de usuário não tiver definido o sinalizador LockEntire de campo de bits no membro sinalizadores do da estrutura D3DDDICB_LOCK e não especificou uma lista de páginas no membro pPages do D3DDDICB_LOCK. Se o driver de exibição do modo de usuário definir o sinalizador LockEntire campo de bits, ele também deverá definir o NumPages e pPages membros de D3DDDICB_LOCK como 0 e NULL, respectivamente. O driver de exibição no modo de usuário sempre deve fornecer uma lista de páginas em pPages ao bloquear uma alocação que foi criada com um repositório de backup permanente. Nessa situação, o gerenciador de memória usa a lista de páginas para marcar apenas como páginas específicas sujas e não é necessário copiar toda a alocação do repositório de backup quando ela é usada para renderização.

O driver de exibição no modo de usuário pode chamar pfnLockCb para adquirir vários intervalos de swizzling para uma única alocação (por exemplo, um intervalo de swizzling para cada nível de MIP). Se o driver não puder adquirir um dos intervalos, o runtime do Direct3D removerá toda a alocação para lidar com o bloqueio (todos os níveis de MIP) e recuperará todos os intervalos de swizzling.

Quando o driver de exibição do modo de usuário solicita que um intervalo de swizzling seja atribuído à alocação, o driver solicita efetivamente acesso aos bits deswizzled da alocação. Para essas solicitações, o gerenciador de memória de vídeo ou as páginas na alocação em um segmento de memória e configura um intervalo giratório para acessar a alocação ou páginas na alocação em um segmento de memória e, em seguida, remove a alocação para a memória do sistema, solicitando que o driver deswizzle a alocação no caminho para a memória do sistema. Uma alocação que foi deswizzled para a memória do sistema é reswizzled (por ser paginado na memória de vídeo) antes que a GPU use a alocação novamente. Como resultado, o driver não pode solicitar um bloqueio de tipo sem substituição (definindo o DonotWait sinalizador de campo de bit) quando ele adquire um intervalo de swizzling. Da mesma forma, o driver não pode referenciar um bloqueio de alocação de tal forma em um buffer DMA que é enviado para a GPU (porque o buffer de DMA será rejeitado).

O driver de exibição do modo de usuário poderá bloquear uma alocação girada sem adquirir um intervalo de swizzling se o driver precisar acessar os bits da alocação em um formato girado. Nessa situação, o gerenciador de memória de vídeo fornece ao driver um ponteiro para os bits giratórios da alocação. No entanto, o driver não pode solicitar um ponteiro para os bits giratórios da alocação enquanto uma solicitação para os bits deswizzled está pendente e vice-versa (ou seja, um bloqueio está atualmente pendente na alocação com um intervalo de swizzling adquirido).

O driver de exibição do modo de usuário deve passar o sinalizador de Descartar campo de bits no Flags membro do D3DDDICB_LOCK na chamada pfnLockCb nas seguintes situações:

  • Quando o runtime do Direct3D passa o sinalizador de Descartar campo de bits no Flags membro da estrutura D3DDDIARG_LOCK na chamada para a função Lock do driver de exibição no modo de usuário
  • Quando o runtime passa o valor D3D10_DDI_MAP_WRITE_DISCARD para o parâmetro DDIMap na chamada para a função ResourceMap do driver
Definir o sinalizador de Descartar campo de bits faz com que o gerenciador de memória determine se ele deve renomear a alocação ou deve fazer com que o thread do aplicativo seja interrompido até que a alocação esteja ociosa. Para obter mais informações sobre como renomear uma alocação, consulte Solicitando renomear umde alocação. O driver pode usar seu próprio suporte de renomeação ou o suporte de renomeação do gerenciador de memória. Para usar seu próprio suporte de renomeação, o driver define o sinalizador DonotWait campo de bits, em resposta a uma chamada Bloquear com o sinalizador de Descartar de campo de bits definido ou em resposta a uma chamada do ResourceMap com o conjunto de valores D3D10_DDI_MAP_WRITE_DISCARD. Definir o sinalizador DonotWait campo de bits faz com que o gerenciador de memória falhe na chamada para pfnLockCb com D3DERR_WASSTILLDRAWING se o hardware gráfico ainda estiver usando a alocação. Essa falha indica ao driver de exibição do modo de usuário renomear ou fazer buffer múltiplo da alocação.
Observação o sinalizador DonotWait campo de bits não terá efeito no gerenciador de memória se o sinalizador de Descartar campo de bits também estiver definido.
 
O driver de exibição do modo de usuário deve definir a o sinalizador ignoreSync campo de bits no Flags membro do D3DDDICB_LOCK quando não exigir que o gerenciador de memória verifique se o hardware gráfico está usando a alocação. O driver de exibição do modo de usuário deve sincronizar corretamente o acesso à alocação. Se o sinalizador DonotWait campo de bits não for especificado com o sinalizador IgnoreSync campo de bits, o gerenciador de memória ignorará o sinalizador de IgnoreSync campo de bits.
Observação o sinalizador ignoreSync de campo de bits do não terá efeito no gerenciador de memória se o sinalizador Descartar campo de bits também estiver definido.
 
exemplo

O exemplo de código a seguir mostra como o sinalizador Descartar campo de bits é usado em uma chamada para pfnLockCb.

HRESULT hr;
D3DDDICB_LOCK LockData;
LockData.hAllocation = AllocationToLock;
LockData.Flags.Discard = TRUE;
hr = pfnLockCb(&LockData)
if (FAILED(hr)) {
    FlushAccumulatedCommandBufferToKernel();
    LockData.Flags.Discard = TRUE;
    LockData.Flags.NoExistingReference = TRUE;
    hr = pfnLockCb(&LockData);
    if (FAILED(hr)) {
        // Fails the lock to the application
    }
}
UpdateAllocationHandleInUMDDataStructure(LockData.hAllocation);
ProgramSurfaceBaseAddressInCurrentCommandBuffer(LockData.hAllocation);

Requisitos

Requisito Valor
de cliente com suporte mínimo Disponível no Windows Vista e versões posteriores dos sistemas operacionais Windows.
da Plataforma de Destino Área de trabalho
cabeçalho d3dumddi.h (inclua D3dumddi.h)

Consulte também

D3D10DDIARG_CREATERESOURCE

D3D11DDIARG_CREATERESOURCE

D3DDDIARG_LOCK

D3DDDICB_LOCK

D3DDDI_DEVICECALLBACKS

bloquear

do ResourceMap

ResourceUnmap