sync with OpenBSD -current
This commit is contained in:
parent
b5b25afdb8
commit
2c72e27ed2
147 changed files with 41128 additions and 10 deletions
208
lib/libva/va/win32/va_win32.c
Normal file
208
lib/libva/va/win32/va_win32.c
Normal file
|
@ -0,0 +1,208 @@
|
|||
/*
|
||||
* Copyright © Microsoft Corporation
|
||||
* Copyright (c) 2023 Emil Velikov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "va.h"
|
||||
#include "va_backend.h"
|
||||
#include "va_internal.h"
|
||||
#include "va_trace.h"
|
||||
#include "va_win32.h"
|
||||
#include "compat_win32.h"
|
||||
|
||||
/*
|
||||
* Initialize default driver to the VAOn12 driver implementation
|
||||
* which will be selected when provided with an adapter LUID which
|
||||
* does not have a registered VA driver
|
||||
*/
|
||||
const char VAAPI_DEFAULT_DRIVER_NAME[] = "vaon12";
|
||||
|
||||
typedef struct _VADisplayContextWin32 {
|
||||
char registry_driver_name[MAX_PATH];
|
||||
bool registry_driver_available_flag;
|
||||
} VADisplayContextWin32;
|
||||
|
||||
static void LoadDriverNameFromRegistry(const LUID* adapter_luid, VADisplayContextWin32* pWin32Ctx)
|
||||
{
|
||||
HMODULE hGdi32 = LoadLibraryA("gdi32.dll");
|
||||
if (!hGdi32)
|
||||
return;
|
||||
|
||||
D3DKMT_OPENADAPTERFROMLUID OpenArgs = { .AdapterLuid = *adapter_luid };
|
||||
D3DDDI_QUERYREGISTRY_INFO RegistryInfo = {
|
||||
.QueryType = D3DDDI_QUERYREGISTRY_ADAPTERKEY,
|
||||
.QueryFlags.TranslatePath = true,
|
||||
.ValueName = L"VAAPIDriverName",
|
||||
.ValueType = REG_SZ,
|
||||
};
|
||||
D3DDDI_QUERYREGISTRY_INFO *pRegistryInfo = &RegistryInfo;
|
||||
#ifndef _WIN64
|
||||
BOOL isWowProcess = false;
|
||||
if (IsWow64Process(GetCurrentProcess(), &isWowProcess) && isWowProcess)
|
||||
wcscpy(RegistryInfo.ValueName, L"VAAPIDriverNameWow");
|
||||
#endif
|
||||
D3DKMT_QUERYADAPTERINFO QAI = {
|
||||
.Type = KMTQAITYPE_QUERYREGISTRY,
|
||||
.pPrivateDriverData = &RegistryInfo,
|
||||
.PrivateDriverDataSize = sizeof(RegistryInfo),
|
||||
};
|
||||
|
||||
PFND3DKMT_OPENADAPTERFROMLUID pfnOpenAdapterFromLuid = (PFND3DKMT_OPENADAPTERFROMLUID)GetProcAddress(hGdi32, "D3DKMTOpenAdapterFromLuid");
|
||||
PFND3DKMT_CLOSEADAPTER pfnCloseAdapter = (PFND3DKMT_CLOSEADAPTER)GetProcAddress(hGdi32, "D3DKMTCloseAdapter");
|
||||
PFND3DKMT_QUERYADAPTERINFO pfnQueryAdapterInfo = (PFND3DKMT_QUERYADAPTERINFO)GetProcAddress(hGdi32, "D3DKMTQueryAdapterInfo");
|
||||
if (!pfnOpenAdapterFromLuid || !pfnCloseAdapter || !pfnQueryAdapterInfo)
|
||||
goto cleanup;
|
||||
|
||||
if (!NT_SUCCESS(pfnOpenAdapterFromLuid(&OpenArgs)))
|
||||
goto cleanup;
|
||||
|
||||
QAI.hAdapter = OpenArgs.hAdapter;
|
||||
if (!NT_SUCCESS(pfnQueryAdapterInfo(&QAI)) ||
|
||||
pRegistryInfo->Status != D3DDDI_QUERYREGISTRY_STATUS_BUFFER_OVERFLOW)
|
||||
goto cleanup;
|
||||
|
||||
size_t RegistryInfoSize = sizeof(RegistryInfo) + RegistryInfo.OutputValueSize;
|
||||
pRegistryInfo = malloc(RegistryInfoSize);
|
||||
if (!pRegistryInfo)
|
||||
goto cleanup;
|
||||
|
||||
memcpy(pRegistryInfo, &RegistryInfo, sizeof(RegistryInfo));
|
||||
QAI.pPrivateDriverData = pRegistryInfo;
|
||||
QAI.PrivateDriverDataSize = RegistryInfoSize;
|
||||
if (!NT_SUCCESS(pfnQueryAdapterInfo(&QAI)) ||
|
||||
pRegistryInfo->Status != D3DDDI_QUERYREGISTRY_STATUS_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
if (!WideCharToMultiByte(CP_ACP, 0, pRegistryInfo->OutputString,
|
||||
RegistryInfo.OutputValueSize / sizeof(wchar_t),
|
||||
pWin32Ctx->registry_driver_name,
|
||||
sizeof(pWin32Ctx->registry_driver_name),
|
||||
NULL, NULL))
|
||||
goto cleanup;
|
||||
|
||||
pWin32Ctx->registry_driver_available_flag = true;
|
||||
|
||||
cleanup:
|
||||
if (pRegistryInfo && pRegistryInfo != &RegistryInfo)
|
||||
free(pRegistryInfo);
|
||||
if (pfnCloseAdapter && OpenArgs.hAdapter) {
|
||||
D3DKMT_CLOSEADAPTER Close = { OpenArgs.hAdapter };
|
||||
/* The explicit negation is a no-op, yet required to silence the
|
||||
* Wunused-result warning.
|
||||
*/
|
||||
(void) !pfnCloseAdapter(&Close);
|
||||
}
|
||||
FreeLibrary(hGdi32);
|
||||
}
|
||||
|
||||
static void va_DisplayContextDestroy(
|
||||
VADisplayContextP pDisplayContext
|
||||
)
|
||||
{
|
||||
if (pDisplayContext == NULL)
|
||||
return;
|
||||
|
||||
if (pDisplayContext->pDriverContext
|
||||
&& pDisplayContext->pDriverContext->native_dpy)
|
||||
free(pDisplayContext->pDriverContext->native_dpy);
|
||||
|
||||
free(pDisplayContext->pDriverContext);
|
||||
free(pDisplayContext->opaque);
|
||||
free(pDisplayContext);
|
||||
}
|
||||
|
||||
static VAStatus va_DisplayContextGetDriverNames(
|
||||
VADisplayContextP pDisplayContext,
|
||||
char **drivers,
|
||||
unsigned *num_drivers
|
||||
)
|
||||
{
|
||||
const LUID * const adapter = pDisplayContext->pDriverContext->native_dpy;
|
||||
const VADisplayContextWin32 * const pWin32Ctx = pDisplayContext->opaque;
|
||||
unsigned count = 0;
|
||||
|
||||
/* Always prefer the adapter registered driver name as first option */
|
||||
if (adapter && pWin32Ctx->registry_driver_available_flag) {
|
||||
drivers[count] = _strdup(pWin32Ctx->registry_driver_name);
|
||||
count++;
|
||||
}
|
||||
/* Provide the default driver name as a fallback option */
|
||||
if (*num_drivers > count) {
|
||||
drivers[count] = _strdup(VAAPI_DEFAULT_DRIVER_NAME);
|
||||
count++;
|
||||
}
|
||||
|
||||
*num_drivers = count;
|
||||
|
||||
return VA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VADisplay vaGetDisplayWin32(
|
||||
/* Can be null for adapter autoselection in the VA driver */
|
||||
const LUID* adapter_luid
|
||||
)
|
||||
{
|
||||
VADisplayContextP pDisplayContext;
|
||||
VADriverContextP pDriverContext;
|
||||
|
||||
pDisplayContext = va_newDisplayContext();
|
||||
if (!pDisplayContext)
|
||||
return NULL;
|
||||
|
||||
pDisplayContext->vaDestroy = va_DisplayContextDestroy;
|
||||
pDisplayContext->vaGetDriverNames = va_DisplayContextGetDriverNames;
|
||||
pDisplayContext->opaque = calloc(1, sizeof(VADisplayContextWin32));
|
||||
if (!pDisplayContext->opaque) {
|
||||
va_DisplayContextDestroy(pDisplayContext);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VADisplayContextWin32* pWin32Ctx = (VADisplayContextWin32*) pDisplayContext->opaque;
|
||||
if (adapter_luid) {
|
||||
/* Load the preferred driver name from the driver registry if available */
|
||||
LoadDriverNameFromRegistry(adapter_luid, pWin32Ctx);
|
||||
#ifdef _DEBUG
|
||||
if (pWin32Ctx->registry_driver_available_flag) {
|
||||
fprintf(stderr, "VA_Win32: Found driver %s in the registry for LUID %ld %ld \n", pWin32Ctx->registry_driver_name, adapter_luid->LowPart, adapter_luid->HighPart);
|
||||
} else {
|
||||
fprintf(stderr, "VA_Win32: Couldn't find a driver in the registry for LUID %ld %ld. Using default driver: %s \n", adapter_luid->LowPart, adapter_luid->HighPart, VAAPI_DEFAULT_DRIVER_NAME);
|
||||
}
|
||||
#endif // _DEBUG
|
||||
}
|
||||
|
||||
pDriverContext = va_newDriverContext(pDisplayContext);
|
||||
if (!pDriverContext) {
|
||||
va_DisplayContextDestroy(pDisplayContext);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pDriverContext->display_type = VA_DISPLAY_WIN32;
|
||||
|
||||
if (adapter_luid) {
|
||||
/* Copy LUID information to driver context */
|
||||
pDriverContext->native_dpy = calloc(1, sizeof(*adapter_luid));
|
||||
memcpy(pDriverContext->native_dpy, adapter_luid, sizeof(*adapter_luid));
|
||||
}
|
||||
|
||||
return (VADisplay)pDisplayContext;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue