Skip to content

Commit 410a228

Browse files
sivileridvrogozh
authored andcommitted
vainfo: Add support for Win32 device enumeration and selection
1 parent 9985a16 commit 410a228

7 files changed

Lines changed: 195 additions & 67 deletions

File tree

common/meson.build

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ if use_wayland
1717
endif
1818

1919
if use_win32
20-
libva_display_src += [ 'va_display_win32.c' ]
20+
libva_display_src += [ 'va_display_win32.cpp' ]
2121
libva_display_deps += win32_deps
2222
endif
2323

common/va_display.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ static const VADisplayHooks *g_display_hooks_available[] = {
6060
};
6161

6262
static const char *g_display_name;
63-
const char *g_drm_device_name;
63+
const char *g_device_name;
6464

6565
static const char *
6666
get_display_name(int argc, char *argv[])
@@ -82,7 +82,7 @@ get_display_name(int argc, char *argv[])
8282
}
8383

8484
static const char *
85-
get_drm_device_name(int argc, char *argv[])
85+
get_device_name(int argc, char *argv[])
8686
{
8787
const char *device_name = NULL;
8888
int i;
@@ -136,8 +136,10 @@ va_init_display_args(int *argc, char *argv[])
136136
}
137137
g_display_name = display_name;
138138

139-
if (g_display_name && strcmp(g_display_name, "drm") == 0)
140-
g_drm_device_name = get_drm_device_name(*argc, argv);
139+
if (g_display_name &&
140+
((strcmp(g_display_name, "drm") == 0)
141+
|| (strcmp(g_display_name, "win32") == 0)))
142+
g_device_name = get_device_name(*argc, argv);
141143

142144
sanitize_args(argc, argv);
143145
}
@@ -200,5 +202,5 @@ va_print_display_options(FILE *stream)
200202
{
201203
fprintf(stream, "Display options:\n");
202204
fprintf(stream, "\t--display display | help Show information for the specified display, or the available display list \n");
203-
fprintf(stream, "\t--device device Set device name, only available under drm display\n");
205+
fprintf(stream, "\t--device device Set device name, only available under drm and win32 displays\n");
204206
}

common/va_display_drm.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
#include "va_display.h"
3737

3838
static int drm_fd = -1;
39-
extern const char *g_drm_device_name;
39+
extern const char *g_device_name;
4040

4141
static VADisplay
4242
va_open_display_drm(void)
@@ -52,8 +52,8 @@ va_open_display_drm(void)
5252
NULL
5353
};
5454

55-
if (g_drm_device_name) {
56-
drm_fd = open(g_drm_device_name, O_RDWR);
55+
if (g_device_name) {
56+
drm_fd = open(g_device_name, O_RDWR);
5757
if (drm_fd < 0) {
5858
printf("Failed to open the given device!\n");
5959
exit(1);

common/va_display_win32.c

Lines changed: 0 additions & 57 deletions
This file was deleted.

common/va_display_win32.cpp

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
/*
2+
* Copyright © Microsoft Corporation
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a
5+
* copy of this software and associated documentation files (the "Software"),
6+
* to deal in the Software without restriction, including without limitation
7+
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+
* and/or sell copies of the Software, and to permit persons to whom the
9+
* Software is furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice (including the next
12+
* paragraph) shall be included in all copies or substantial portions of the
13+
* Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18+
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21+
* IN THE SOFTWARE.
22+
*/
23+
24+
#include <stdio.h>
25+
#include <stdbool.h>
26+
#include <va/va_win32.h>
27+
#include "va_display.h"
28+
#include <directx/dxcore_interface.h>
29+
30+
extern "C" const char *g_device_name;
31+
32+
void dxcore_resolve_adapter(const char *adapter_string, /*out*/ bool* ptr_device_found, /*out*/ LUID* ptr_adapter_luid)
33+
{
34+
int selected_adapter_index = -1;
35+
IDXCoreAdapterFactory *factory = nullptr;
36+
IDXCoreAdapterList *adapter_list = nullptr;
37+
IDXCoreAdapter *adapter = nullptr;
38+
typedef HRESULT(WINAPI *PFN_CREATE_DXCORE_ADAPTER_FACTORY)(REFIID riid, void **ppFactory);
39+
PFN_CREATE_DXCORE_ADAPTER_FACTORY DXCoreCreateAdapterFactory;
40+
HRESULT hr = S_OK;
41+
42+
memset(ptr_adapter_luid, 0, sizeof(LUID));
43+
*ptr_device_found = false;
44+
45+
HMODULE dxcore_mod = LoadLibrary("DXCore.DLL");
46+
if (!dxcore_mod) {
47+
fprintf(stderr, "Failed to load DXCore.DLL to enumerate adapters.\n");
48+
goto fail;
49+
}
50+
51+
DXCoreCreateAdapterFactory = (PFN_CREATE_DXCORE_ADAPTER_FACTORY)GetProcAddress(dxcore_mod, "DXCoreCreateAdapterFactory");
52+
if (!DXCoreCreateAdapterFactory) {
53+
fprintf(stderr, "Failed to load DXCoreCreateAdapterFactory from DXCore.DLL.\n");
54+
goto fail;
55+
}
56+
57+
hr = DXCoreCreateAdapterFactory(IID_IDXCoreAdapterFactory, (void **)&factory);
58+
if (FAILED(hr)) {
59+
fprintf(stderr, "DXCoreCreateAdapterFactory failed: %lx\n", hr);
60+
goto fail;
61+
}
62+
63+
hr = factory->CreateAdapterList(1, &DXCORE_ADAPTER_ATTRIBUTE_D3D12_GRAPHICS, IID_IDXCoreAdapterList, (void **)&adapter_list);
64+
if (FAILED(hr)) {
65+
fprintf(stderr, "CreateAdapterList failed: %lx\n", hr);
66+
goto fail;
67+
}
68+
69+
if (adapter_string && (sscanf_s(adapter_string, "%d", &selected_adapter_index) != 1)) {
70+
fprintf(stderr, "Invalid device index received for -hwaccel_device %s\n", adapter_string ? adapter_string : "");
71+
}
72+
73+
if (!adapter_string) fprintf(stdout, "Available devices for --display win32:\n");
74+
for (int i=0; i < adapter_list->GetAdapterCount(); i++) {
75+
if (SUCCEEDED(adapter_list->GetAdapter(i, IID_IDXCoreAdapter, (void **)&adapter))) {
76+
size_t desc_size = 0;
77+
if (FAILED(adapter->GetPropertySize(DXCoreAdapterProperty::DriverDescription, &desc_size))) {
78+
adapter->Release();
79+
continue;
80+
}
81+
82+
char *adapter_name = (char*)malloc(desc_size);
83+
if (!adapter_name) {
84+
adapter->Release();
85+
continue;
86+
}
87+
88+
if (FAILED(adapter->GetProperty(DXCoreAdapterProperty::DriverDescription, desc_size, adapter_name))) {
89+
free(adapter_name);
90+
adapter->Release();
91+
continue;
92+
}
93+
94+
LUID cur_adapter_luid = { 0, 0 };
95+
if (FAILED(adapter->GetProperty(DXCoreAdapterProperty::InstanceLuid, &cur_adapter_luid))) {
96+
free(adapter_name);
97+
adapter->Release();
98+
continue;
99+
}
100+
101+
if (selected_adapter_index == i) {
102+
*ptr_adapter_luid = cur_adapter_luid;
103+
*ptr_device_found = true;
104+
}
105+
106+
if (!adapter_string) fprintf(stdout, "\tDevice Index: %d Device LUID: %lu %ld - Device Name: %s\n", i, cur_adapter_luid.LowPart, cur_adapter_luid.HighPart, adapter_name);
107+
free(adapter_name);
108+
adapter->Release();
109+
}
110+
}
111+
112+
fail:
113+
if (adapter_list)
114+
adapter_list->Release();
115+
if (factory)
116+
factory->Release();
117+
if (dxcore_mod)
118+
FreeLibrary(dxcore_mod);
119+
}
120+
121+
static VADisplay
122+
va_open_display_win32(void)
123+
{
124+
LUID adapter_luid = {0, 0};
125+
bool device_found = false;
126+
if (g_device_name) {
127+
bool print_devices = (0 == strcmp(g_device_name, "help"));
128+
dxcore_resolve_adapter(print_devices ? NULL : g_device_name, &device_found, &adapter_luid);
129+
if (print_devices) {
130+
exit(0);
131+
} else if (g_device_name && !device_found) {
132+
fprintf(stderr, "Could not find device %s for --display win32. Please try --device help for a list of available devices.\n", g_device_name);
133+
exit(0);
134+
}
135+
}
136+
137+
// Adapter automatic selection supported by sending NULL adapter to vaGetDisplayWin32
138+
return vaGetDisplayWin32(device_found ? &adapter_luid : NULL);
139+
}
140+
141+
static void
142+
va_close_display_win32(VADisplay va_dpy)
143+
{
144+
}
145+
146+
static VAStatus
147+
va_put_surface_win32(
148+
VADisplay va_dpy,
149+
VASurfaceID surface,
150+
const VARectangle *src_rect,
151+
const VARectangle *dst_rect
152+
)
153+
{
154+
return VA_STATUS_ERROR_OPERATION_FAILED;
155+
}
156+
157+
#ifdef __cplusplus
158+
extern "C" {
159+
#endif
160+
161+
extern const VADisplayHooks va_display_hooks_win32 = {
162+
"win32",
163+
va_open_display_win32,
164+
va_close_display_win32,
165+
va_put_surface_win32,
166+
};
167+
168+
#ifdef __cplusplus
169+
}
170+
#endif

meson.build

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,14 @@ if get_option('win32') != 'false'
8787
use_win32 = dependency('libva-win32', required: require_win32).found()
8888
if use_win32
8989
libva_utils_flags = [ '-DHAVE_VA_WIN32=1', '-DNOMINMAX']
90+
dep_dxheaders = dependency('directx-headers', required : false)
91+
if not dep_dxheaders.found()
92+
dep_dxheaders = dependency('DirectX-Headers',
93+
version : '>= v1.0.2',
94+
fallback : ['DirectX-Headers', 'dep_dxheaders'],
95+
required : use_win32
96+
)
97+
endif
9098
endif
9199
endif
92100

@@ -95,7 +103,7 @@ add_project_arguments(libva_utils_flags,
95103

96104
if use_win32
97105
subdir('getopt')
98-
win32_deps = [ dependency('libva-win32', required: require_win32), idep_getopt ]
106+
win32_deps = [ dependency('libva-win32', required: require_win32), idep_getopt, dep_dxheaders]
99107
endif
100108

101109
subdir('common') # Uses win32_deps

subprojects/DirectX-Headers.wrap

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[wrap-git]
2+
directory = DirectX-Headers-1.0
3+
4+
url = https://github.com/microsoft/DirectX-Headers.git
5+
revision = v1.0.2

0 commit comments

Comments
 (0)