1 /* GStreamer
2 * Copyright (C) 2021 Seungha Yang <seungha@centricular.com>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <gst/gst.h>
25 #include <gst/check/gstcheck.h>
26 #include <gst/d3d11/gstd3d11.h>
27 #include <wrl.h>
28
29 /* *INDENT-OFF* */
30 using namespace Microsoft::WRL;
31 /* *INDENT-ON* */
32
33 static gboolean have_multiple_adapters = FALSE;
34
GST_START_TEST(test_device_new)35 GST_START_TEST (test_device_new)
36 {
37 GstD3D11Device *device = nullptr;
38 guint adapter_index = G_MAXINT;
39
40 device = gst_d3d11_device_new (0, 0);
41 fail_unless (GST_IS_D3D11_DEVICE (device));
42
43 g_object_get (device, "adapter", &adapter_index, nullptr);
44 fail_unless_equals_int (adapter_index, 0);
45 gst_clear_object (&device);
46
47 if (have_multiple_adapters) {
48 device = gst_d3d11_device_new (1, 0);
49 fail_unless (GST_IS_D3D11_DEVICE (device));
50
51 g_object_get (device, "adapter", &adapter_index, nullptr);
52 fail_unless_equals_int (adapter_index, 1);
53 }
54
55 gst_clear_object (&device);
56 }
57
58 GST_END_TEST;
59
GST_START_TEST(test_device_for_adapter_luid)60 GST_START_TEST (test_device_for_adapter_luid)
61 {
62 GstD3D11Device *device = nullptr;
63 HRESULT hr;
64 ComPtr < IDXGIAdapter1 > adapter;
65 ComPtr < IDXGIFactory1 > factory;
66 DXGI_ADAPTER_DESC desc;
67 guint adapter_index = G_MAXINT;
68 gint64 adapter_luid = 0;
69 gint64 luid;
70
71 hr = CreateDXGIFactory1 (IID_PPV_ARGS (&factory));
72 if (SUCCEEDED (hr))
73 hr = factory->EnumAdapters1 (0, &adapter);
74
75 if (SUCCEEDED (hr))
76 hr = adapter->GetDesc (&desc);
77
78 if (SUCCEEDED (hr)) {
79 luid = gst_d3d11_luid_to_int64 (&desc.AdapterLuid);
80 device = gst_d3d11_device_new_for_adapter_luid (luid, 0);
81 fail_unless (GST_IS_D3D11_DEVICE (device));
82
83 g_object_get (device, "adapter", &adapter_index, "adapter-luid",
84 &adapter_luid, nullptr);
85
86 /* adapter_luid is corresponding to the first enumerated adapter,
87 * so adapter index should be zero here */
88 fail_unless_equals_int (adapter_index, 0);
89 fail_unless_equals_int64 (adapter_luid, luid);
90 }
91
92 gst_clear_object (&device);
93 adapter = nullptr;
94
95 if (have_multiple_adapters) {
96 if (SUCCEEDED (hr))
97 hr = factory->EnumAdapters1 (1, &adapter);
98
99 if (SUCCEEDED (hr))
100 hr = adapter->GetDesc (&desc);
101
102 if (SUCCEEDED (hr)) {
103 luid = gst_d3d11_luid_to_int64 (&desc.AdapterLuid);
104 device = gst_d3d11_device_new_for_adapter_luid (luid, 0);
105 fail_unless (GST_IS_D3D11_DEVICE (device));
106
107 g_object_get (device, "adapter", &adapter_index, "adapter-luid",
108 &adapter_luid, nullptr);
109
110 fail_unless_equals_int (adapter_index, 1);
111 fail_unless_equals_int64 (adapter_luid, luid);
112 }
113 }
114
115 gst_clear_object (&device);
116 }
117
118 GST_END_TEST;
119
GST_START_TEST(test_device_new_wrapped)120 GST_START_TEST (test_device_new_wrapped)
121 {
122 GstD3D11Device *device = nullptr;
123 GstD3D11Device *device_clone = nullptr;
124 ID3D11Device *device_handle, *device_handle_clone;
125 ID3D11DeviceContext *context_handle, *context_handle_clone;
126 guint adapter_index = 0;
127 guint index;
128 gint64 luid, luid_clone;
129
130 if (have_multiple_adapters)
131 adapter_index = 1;
132
133 device = gst_d3d11_device_new (adapter_index, 0);
134 fail_unless (GST_IS_D3D11_DEVICE (device));
135
136 device_handle = gst_d3d11_device_get_device_handle (device);
137 fail_unless (device_handle != nullptr);
138
139 context_handle = gst_d3d11_device_get_device_context_handle (device);
140 fail_unless (context_handle != nullptr);
141
142 g_object_get (device, "adapter", &index, "adapter-luid", &luid, nullptr);
143 fail_unless_equals_int (index, adapter_index);
144
145 device_clone = gst_d3d11_device_new_wrapped (device_handle);
146 fail_unless (GST_IS_D3D11_DEVICE (device_clone));
147
148 device_handle_clone = gst_d3d11_device_get_device_handle (device_clone);
149 fail_unless_equals_pointer (device_handle, device_handle_clone);
150
151 context_handle_clone =
152 gst_d3d11_device_get_device_context_handle (device_clone);
153 fail_unless_equals_pointer (context_handle, context_handle_clone);
154
155 g_object_get (device_clone,
156 "adapter", &index, "adapter-luid", &luid_clone, nullptr);
157 fail_unless_equals_int (index, adapter_index);
158 fail_unless_equals_int64 (luid, luid_clone);
159
160 gst_clear_object (&device);
161 gst_clear_object (&device_clone);
162 }
163
164 GST_END_TEST;
165
166 static gboolean
check_d3d11_available(void)167 check_d3d11_available (void)
168 {
169 HRESULT hr;
170 ComPtr < IDXGIAdapter1 > adapter;
171 ComPtr < IDXGIFactory1 > factory;
172
173 hr = CreateDXGIFactory1 (IID_PPV_ARGS (&factory));
174 if (FAILED (hr))
175 return FALSE;
176
177 hr = factory->EnumAdapters1 (0, &adapter);
178 if (FAILED (hr))
179 return FALSE;
180
181 adapter = nullptr;
182 hr = factory->EnumAdapters1 (1, &adapter);
183 if (SUCCEEDED (hr))
184 have_multiple_adapters = TRUE;
185
186 return TRUE;
187 }
188
189 static Suite *
d3d11device_suite(void)190 d3d11device_suite (void)
191 {
192 Suite *s = suite_create ("d3d11device");
193 TCase *tc_basic = tcase_create ("general");
194
195 suite_add_tcase (s, tc_basic);
196
197 if (!check_d3d11_available ())
198 goto out;
199
200 tcase_add_test (tc_basic, test_device_new);
201 tcase_add_test (tc_basic, test_device_for_adapter_luid);
202 tcase_add_test (tc_basic, test_device_new_wrapped);
203
204 out:
205 return s;
206 }
207
208 GST_CHECK_MAIN (d3d11device);
209