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 。 一个原因是适用于 Linux 的 Windows 子系统 (WSL) 不支持 D3DKMTCreateAllocation (nf-d3dkmthk-d3dkmtcreateallocation2.md) 。
在这种情况下,用户模式 (,D3D 运行时) 调用 D3DKMTCreateAllocation 来创建分配和资源。 分配可以与资源相关联,也可以独立分配。
当用户模式调用 D3DKMTCreateAllocation 时,UMD 提供描述分配的专用驱动程序数据。 Dxgkrnl 获取此专用驱动程序数据并将其传递给 KMD,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 的参数限制:
- 只有 StandardAllocation 支持 ExistingSysMem (或 ExistingSection) ,反之亦然。
- 支持的 NumAllocations 为 1。
- 只能设置 ExistingSysMem 或 ExistingSection 中的 一个。
- 创建 StandardAllocation 时,必须始终设置 CreateShared 和 CrossAdapter 标志。
- 无法针对现有资源 (D3DKMT_CREATALLOCATION::hResource) 创建 ExistingSysMem (或 ExistingSection) 。
要求
要求 | 值 |
---|---|
最低受支持的客户端 | Windows Vista |
目标平台 | 通用 |
标头 | d3dkmthk.h (包括 D3dkmthk.h) |
Library | Gdi32.lib |
DLL | Gdi32.dll |