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


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

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

Синтаксис

NTSTATUS D3DKMTCreateAllocation(
  D3DKMT_CREATEALLOCATION *unnamedParam1
);

Параметры

unnamedParam1

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

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

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

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

Комментарии

Клиентские драйверы графического режима пользователя должны вызывать D3DKMTCreateAllocation2 . Одна из причин заключается в том, что подсистема 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 и наоборот.
  • Числовычисления поддерживаются: 1.
  • Можно задать только один из ExistingSysMem или ExistingSection .
  • При создании StandardAllocation всегда должны быть установлены флаги CreateShared и CrossAdapter .
  • ExistingSysMem (или ExistingSection) невозможно создать для существующего ресурса (D3DKMT_CREATALLOCATION::hResource).

Требования

Требование Значение
Минимальная версия клиента Windows Vista
Целевая платформа Универсальное
Верхняя часть d3dkmthk.h (включая D3dkmthk.h)
Библиотека Gdi32.lib
DLL Gdi32.dll

См. также раздел

D3DKMT_CREATEALLOCATION

D3DKMTCreateAllocation2