Função D3DKMTCreateAllocation (d3dkmthk.h)

A função D3DKMTCreateAllocation cria ou adiciona alocações de memória de sistema ou vídeo. Em vez disso, os drivers de cliente de gráficos no modo de usuário devem chamar D3DKMTCreateAllocation2 (consulte Comentários).

Sintaxe

NTSTATUS D3DKMTCreateAllocation(
  D3DKMT_CREATEALLOCATION *unnamedParam1
);

Parâmetros

unnamedParam1

[in, out] pData: um ponteiro para uma estrutura D3DKMT_CREATEALLOCATION que contém informações para criar alocações.

Retornar valor

D3DKMTCreateAllocation retornará STATUS_SUCCESS se a operação for bem-sucedida. Caso contrário, ele poderá retornar um código NTSTATUS , como um dos seguintes valores:

Código de retorno Descrição
STATUS_DEVICE_REMOVED O adaptador gráfico foi interrompido ou o dispositivo de exibição foi redefinido.
STATUS_INVALID_PARAMETER Os parâmetros foram validados e determinados como incorretos.
STATUS_NO_MEMORY Essa rotina não pôde ser concluída devido à memória insuficiente do sistema.
STATUS_NO_VIDEO_MEMORY Essa rotina não pôde ser concluída devido à memória de vídeo insuficiente. O gerenciador de memória de vídeo tenta virtualizar a memória de vídeo. No entanto, se a virtualização falhar (como quando o espaço de endereço virtual se esgotar), o gerenciador de memória poderá retornar esse código de erro.

Comentários

Em vez disso, os drivers de cliente de gráficos no modo de usuário devem chamar D3DKMTCreateAllocation2 . Um dos motivos é que o WSL (Subsistema do Windows para Linux) não dá suporte a D3DKMTCreateAllocation(nf-d3dkmthk-d3dkmtcreateallocation2.md).

O modo de usuário (nesse caso, o runtime D3D) chama D3DKMTCreateAllocation para criar alocações e recursos. Uma alocação pode ser associada a um recurso ou pode ficar sozinha.

Quando o modo de usuário chama D3DKMTCreateAllocation, o UMD fornece dados de driver privados que descrevem a alocação. O Dxgkrnl usa esses dados de driver privados e os passa para o KMD, que preenche uma descrição de cada alocação de maneira compreendida pelo VidMm. Os dados UMD contêm informações como o tipo de recurso (textura, swapchain etc.). O KMD converte esses dados em itens como tamanho, alinhamento, um conjunto de segmentos de memória que a alocação pode estar localizada, preferências para esses segmentos e assim por diante.

D3DKMTCreateAllocation também pode ser chamado para adicionar alocações adicionais a um recurso a qualquer momento. As únicas restrições são que todas as alocações compartilhadas devem ser associadas a um recurso e alocações adicionais não podem ser adicionadas a um recurso compartilhado existente.

Exemplos

Criando uma alocação autônoma na memória de vídeo que não está associada a um recurso

O exemplo de código a seguir demonstra como D3DKMTCreateAllocation pode ser usado para criar uma alocação autônoma na memória de vídeo que não está associada a um recurso.

D3DKMT_HANDLE CreateStandAloneAllocation(D3DKMT_HANDLE hDevice, VOID* pPrivateAllocationInfo, UINT Size)
{
    D3DKMT_CREATEALLOCATION CreateAllocation;
    D3DDDI_ALLOCATIONINFO AllocationInfo;

    memset(&CreateAllocation, 0, sizeof(CreateAllocation));
    CreateAllocation.hDevice = hDevice;
    CreateAllocation.NumAllocations = 1;
    CreateAllocation.pAllocationInfo = &AllocationInfo;

    AllocationInfo.hAllocation = NULL;
    AllocationInfo.pSystemMem = NULL;  // Vidmem allocation
    AllocationInfo.pPrivateDriverData = pPrivateAllocationInfo;  // Contains format, size, and so on.
    AllocationInfo.PrivateDriverDataSize = Size;

    if (NT_SUCCESS((*pfnKTCreateAllocation)(&CreateAllocation))) {
        return AllocationInfo.hAllocation;
    }
    return 0;
}

Criando um recurso com uma única alocação de memória do sistema

O exemplo de código a seguir demonstra como D3DKMTCreateAllocation pode ser usado para criar um recurso com uma única alocação de memória do sistema.

HRESULT CreateSysmemResource(D3DKMT_HANDLE hDevice, 
                             UINT AllocationSize, 
                             VOID* pResourceData, 
                             UINT ResourceDataSize,
                             VOID* pAllocationData, 
                             UINT AllocationDataSize,
                             D3DKMT_HANDLE* phResource,
                             D3DKMT_HANDLE* phAllocation)
{
    D3DKMT_CREATEALLOCATION CreateAllocation;
    D3DDDI_ALLOCATIONINFO AllocationInfo;
    VOID* pSysMem;

    *phResource = NULL;
    *phAllocation = NULL;

    // For a sysmem allocation, preallocate the memory.
    pSysMem = MemAlloc(AllocationSize);
    if (pSysMem == NULL) {
        return E_OUTOFMEMORY;
    }
 
    memset(&CreateAllocation, 0, sizeof(CreateAllocation));
    CreateAllocation.hDevice = hDevice;
    CreateAllocation.Flags.CreateResource = TRUE;
    CreateAllocation.pPrivateDriverData = pResourceData;
    CreateAllocation.PrivateDriverDataSize = ResourceDataSize;
    CreateAllocation.NumAllocations = 1;
    CreateAllocation.pAllocationInfo = &AllocationInfo;

    AllocationInfo.hAllocation = NULL;
    AllocationInfo.pSystemMem = pSysMem;
    AllocationInfo.pPrivateDriverData = pAllocationData;
    AllocationInfo.PrivateDriverDataSize = AllocationDataSize;

    if (NT_SUCCESS((*pfnKTCreateAllocation)(&CreateAllocation))) {
        *phResource = CreateAllocation.hResource;
        *phAllocation = AllocationInfo.hAllocation;
        return S_OK;
    }
    MemFree(pSysMem);
    return E_FAIL;
}

Criando uma alocação padrão com ExistingSysMem

O exemplo de código a seguir mostra os argumentos a serem passados para D3DKMTCreateAllocation para criar uma alocação padrão com ExistingSysMem. O buffer de memória do sistema existente que o runtime fornece ao kernel deve ser alinhado à página e um múltiplo do tamanho da página; caso contrário, o kernel falhará na chamada.

    UINT PrivateDriverDataEstimate = 2048;

    D3DDDI_ALLOCATIONINFO2 AllocInfo = {};
    AllocInfo.pSystemMem = SomeValidPageAlignedSysMem;
    AllocInfo.VidPnSourceId = SomeVidPnSourceId;

    D3DKMDT_CREATESTANDARDALLOCATION StandardAlloc = {};
    StandardAlloc.Type = D3DKMT_STANDARDALLOCATIONTYPE_EXISTINGHEAP;
    StandardAlloc.ExistingHeapData.Size = SizeOfSystemMemBuffer; // Multiple of PAGE SIZE

    D3DKMT_CREATEALLOCATION CreateAlloc = {};
    CreateAlloc.hDevice = SomeDevice;
    CreateAlloc.NumAllocations = 1;
    CreateAlloc.pAllocationInfo2 = &AllocInfo;
    CreateAlloc.pStandardAllocation = &StandardAlloc;
    CreateAlloc.Flags.ExistingSysMem = TRUE;

    ntStatus = D3DKMTCreateAllocation(&CreateAlloc);

Limitações de argumento para D3DKMTCreateAllocation:

  • ExistingSysMem (ou ExistingSection) só tem suporte com StandardAllocation e vice-versa.
  • NumAllocations com suporte é 1.
  • Somente um de ExistingSysMem ou ExistingSection pode ser definido.
  • Ao criar uma StandardAllocation, os sinalizadores CreateShared e CrossAdapter sempre devem ser definidos.
  • ExistingSysMem (ou ExistingSection) não pode ser criado em um recurso existente (D3DKMT_CREATALLOCATION::hResource).

Requisitos

Requisito Valor
Cliente mínimo com suporte Windows Vista
Plataforma de Destino Universal
Cabeçalho d3dkmthk.h (inclua D3dkmthk.h)
Biblioteca Gdi32.lib
DLL Gdi32.dll

Confira também

D3DKMT_CREATEALLOCATION

D3DKMTCreateAllocation2