Condividi tramite


Funzione D3DKMTCreateAllocation (d3dkmthk.h)

La funzione D3DKMTCreateAllocation crea o aggiunge allocazioni di memoria video o di sistema. I driver client grafici in modalità utente devono chiamare D3DKMTCreateAllocation2 (vedere la sezione Osservazioni).

Sintassi

NTSTATUS D3DKMTCreateAllocation(
  D3DKMT_CREATEALLOCATION *unnamedParam1
);

Parametri

unnamedParam1

[in, out] pData: puntatore a una struttura D3DKMT_CREATEALLOCATION che contiene informazioni per la creazione di allocazioni.

Valore restituito

D3DKMTCreateAllocation restituisce STATUS_SUCCESS se l'operazione ha esito positivo. In caso contrario, potrebbe restituire un NTSTATUS codice, ad esempio uno dei valori seguenti:

Codice restituito Descrizione
STATUS_DEVICE_REMOVED La scheda grafica è stata arrestata o il dispositivo di visualizzazione è stato reimpostato.
STATUS_INVALID_PARAMETER I parametri sono stati convalidati e sono stati determinati in modo che non siano corretti.
STATUS_NO_MEMORY Impossibile completare questa routine a causa di memoria di sistema insufficiente.
STATUS_NO_VIDEO_MEMORY Impossibile completare questa routine a causa di memoria video insufficiente. La gestione memoria video tenta di virtualizzare la memoria video. Tuttavia, se la virtualizzazione non riesce, ad esempio quando si esaurisce lo spazio degli indirizzi virtuali, il gestore della memoria potrebbe restituire questo codice di errore.

Osservazioni

I driver client grafici in modalità utente devono invece chiamare D3DKMTCreateAllocation2. Un motivo è che sottosistema Windows per Linux (WSL) non supporta D3DKMTCreateAllocation(nf-d3dkmthk-d3dkmtcreateallocation2.md).

La modalità utente (in questo caso, il runtime D3D) chiama D3DKMTCreateAllocation per creare allocazioni e risorse. Un'allocazione può essere associata a una risorsa o può essere autonoma.

Quando la modalità utente chiama D3DKMTCreateAllocation, UMD fornisce i dati del driver privato che descrivono l'allocazione. Dxgkrnl prende questi dati del driver privato e lo passa al KMD che quindi compila una descrizione di ogni allocazione in modo compreso da VidMm. I dati UMD contengono informazioni quali il tipo di risorsa (trama, swapchain e così via). Il KMD converte questi dati in elementi come dimensioni, allineamento, un set di segmenti di memoria che l'allocazione può essere individuata, preferenze per questi segmenti e così via.

D3DKMTCreateAllocation può anche essere chiamato per aggiungere altre allocazioni a una risorsa in qualsiasi momento. Le uniche restrizioni sono che tutte le allocazioni condivise devono essere associate a una risorsa e non è possibile aggiungere allocazioni aggiuntive a una risorsa condivisa esistente.

Esempi

Creazione di un'allocazione autonoma nella memoria video non associata a una risorsa

Nell'esempio di codice seguente viene illustrato come usare D3DKMTCreateAllocation per creare un'allocazione autonoma nella memoria video non associata a una risorsa.

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;
}

Creazione di una risorsa con un'allocazione di memoria di sistema singola

Nell'esempio di codice seguente viene illustrato come usare D3DKMTCreateAllocation per creare una risorsa con una singola allocazione di memoria di 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;
}

Creazione di un'allocazione standard con ExistingSysMem

Nell'esempio di codice seguente vengono illustrati gli argomenti da passare a D3DKMTCreateAllocation per creare un'allocazione standard con ExistingSysMem. Il buffer di memoria di sistema esistente fornito dal runtime al kernel deve essere allineato alla pagina e un multiplo delle dimensioni della pagina; in caso contrario, il kernel non riesce la chiamata.

    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);

Limitazioni degli argomenti per D3DKMTCreateAllocation:

  • ExistingSysMem (o ExistingSection) è supportato solo con StandardAllocation e viceversa.
  • NumAllocations supportato è 1.
  • È possibile impostare una sola ExistingSysMem o ExistingSection.
  • Quando si crea un StandardAllocation, i flag CreateShared e CrossAdapter devono essere sempre impostati.
  • non è possibile creare ExistingSysMem (o ExistingSection) in una risorsa esistente (D3DKMT_CREATALLOCATION::hResource).

Fabbisogno

Requisito Valore
client minimo supportato Windows Vista
piattaforma di destinazione Universale
intestazione d3dkmthk.h (include D3dkmthk.h)
libreria Gdi32.lib
dll Gdi32.dll

Vedere anche

D3DKMT_CREATEALLOCATION

D3DKMTCreateAllocation2