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