• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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