Функция 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 |