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 由于视频内存不足,此例程无法完成。 视频内存管理器尝试虚拟化视频内存。 但是,如果虚拟化失败(例如虚拟地址空间耗尽时),内存管理器可能会返回此错误代码。

言论

用户模式图形客户端驱动程序应改为调用 D3DKMTCreateAllocation2。 一个原因是 Windows Subsystem for 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。
  • 只能设置 ExistingSysMemExistingSection 之一。
  • 创建 StandardAllocation时,必须始终设置 CreateSharedCrossAdapter 标志。
  • 无法针对现有资源(D3DKMT_CREATALLOCATION::hResource)创建 ExistingSysMem(或 ExistingSection)。

要求

要求 价值
最低支持的客户端 Windows Vista
目标平台 普遍
标头 d3dkmthk.h (包括 D3dkmthk.h)
Gdi32.lib
DLL Gdi32.dll

另请参阅

D3DKMT_CREATEALLOCATION

D3DKMTCreateAllocation2