Поделиться через


Функция D3DKMTCreateAllocation (d3dkmthk.h)

Функция D3DKMTCreateAllocation создает или добавляет выделение памяти системы или видео. Драйверы графических клиентов в режиме пользователя должны вызывать D3DKMTCreateAllocation2 (см. примечания).

Синтаксис

NTSTATUS D3DKMTCreateAllocation(
  D3DKMT_CREATEALLOCATION *unnamedParam1
);

Параметры

unnamedParam1

[in, out] pData: указатель на структуру D3DKMT_CREATEALLOCATION, содержащую сведения о создании выделений.

Возвращаемое значение

D3DKMTCreateAllocation возвращает STATUS_SUCCESS, если операция завершится успешно. В противном случае он может вернуть код NTSTATUS, например одно из следующих значений:

Возвращаемый код Описание
STATUS_DEVICE_REMOVED Графический адаптер был остановлен или устройство отображения было сброшено.
STATUS_INVALID_PARAMETER Параметры были проверены и определены как неверные.
STATUS_NO_MEMORY Эта подпрограмма не смогла завершиться из-за нехватки системной памяти.
STATUS_NO_VIDEO_MEMORY Эта подпрограмма не смогла завершиться из-за нехватки памяти видео. Диспетчер памяти видео пытается виртуализировать память видео. Однако если виртуализация завершается сбоем (например, при истечении виртуального адресного пространства), диспетчер памяти может вернуть этот код ошибки.

Замечания

Вместо этого драйверы графических клиентов в режиме пользователя должны вызывать D3DKMTCreateAllocation 2. Одна из причин заключается в том, что подсистема Windows для Linux (WSL) не поддерживает D3DKMTCreateAllocation(nf-d3dkmthk-d3dkmtcreateallocation2.md).

В пользовательском режиме (в данном случае среда выполнения D3D) вызывает D3DKMTCreateAllocation для создания выделений и ресурсов. Выделение может быть связано с ресурсом или может быть изолированным.

Когда режим пользователя вызывает D3DKMTCreateAllocation, UMD предоставляет данные частного драйвера, описывающие выделение. Dxgkrnl принимает эти данные частного драйвера и передает его в KMD, который затем заполняет описание каждого выделения таким образом, который понимается VidMm. Данные UMD содержат такие сведения, как тип ресурса (текстура, цепочка буферов и т. д.). KMD преобразует эти данные в такие вещи, как размер, выравнивание, набор сегментов памяти, которые можно найти, предпочтения для этих сегментов и т. д.

D3DKMTCreateAllocation также можно вызывать для добавления дополнительных выделений в ресурс в любое время. Единственными ограничениями являются то, что все общие выделения должны быть связаны с ресурсом, а дополнительные выделения нельзя добавить в существующий общий ресурс.

Примеры

Создание изолированного выделения в памяти видео, не связанной с ресурсом

В следующем примере кода показано, как можно использовать D3DKMTCreateAllocation для создания изолированного выделения в памяти видео, которая не связана с ресурсом.

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

Создание ресурса с выделением одной системной памяти

В следующем примере кода показано, как можно использовать D3DKMTCreateAllocation для создания ресурса с одним выделением памяти системы.

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

Создание стандартного выделения с помощью ExistingSysMem

В следующем примере кода показаны аргументы для передачи в D3DKMTCreateAllocation для создания стандартного выделения с ExistingSysMem. Существующий буфер памяти системы, который среда выполнения предоставляет ядру, должна быть выровнена по страницам и несколько размеров страниц; В противном случае ядро завершается сбоем вызова.

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

Ограничения аргументов для D3DKMTCreateAllocation:

  • ExistingSysMem (или ExistingSection) поддерживается только с StandardAllocation и наоборот.
  • поддерживается numAllocations 1.
  • Можно задать только одну из ExistingSysMem или ExistingSection.
  • При создании StandardAllocationвсегда необходимо задать флаги CreateShared и CrossAdapter.
  • ExistingSysMem (или ExistingSection) невозможно создать для существующего ресурса (D3DKMT_CREATALLOCATION::hResource).

Требования

Требование Ценность
минимальные поддерживаемые клиентские Windows Vista
целевая платформа Всеобщий
заголовка d3dkmthk.h (include D3dkmthk.h)
библиотеки Gdi32.lib
DLL Gdi32.dll

См. также

D3DKMT_CREATEALLOCATION

D3DKMTCreateAllocation2