2 * Copyright 2008 Henri Verbeet for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
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 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "wine/port.h"
23 #include "dxgi_private.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(dxgi
);
27 static inline struct dxgi_factory
*impl_from_IWineDXGIFactory(IWineDXGIFactory
*iface
)
29 return CONTAINING_RECORD(iface
, struct dxgi_factory
, IWineDXGIFactory_iface
);
32 static HRESULT STDMETHODCALLTYPE
dxgi_factory_QueryInterface(IWineDXGIFactory
*iface
, REFIID iid
, void **out
)
34 struct dxgi_factory
*factory
= impl_from_IWineDXGIFactory(iface
);
36 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
38 if (IsEqualGUID(iid
, &IID_IWineDXGIFactory
)
39 || IsEqualGUID(iid
, &IID_IDXGIFactory5
)
40 || IsEqualGUID(iid
, &IID_IDXGIFactory4
)
41 || IsEqualGUID(iid
, &IID_IDXGIFactory3
)
42 || IsEqualGUID(iid
, &IID_IDXGIFactory2
)
43 || (factory
->extended
&& IsEqualGUID(iid
, &IID_IDXGIFactory1
))
44 || IsEqualGUID(iid
, &IID_IDXGIFactory
)
45 || IsEqualGUID(iid
, &IID_IDXGIObject
)
46 || IsEqualGUID(iid
, &IID_IUnknown
))
48 IUnknown_AddRef(iface
);
53 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
59 static ULONG STDMETHODCALLTYPE
dxgi_factory_AddRef(IWineDXGIFactory
*iface
)
61 struct dxgi_factory
*factory
= impl_from_IWineDXGIFactory(iface
);
62 ULONG refcount
= InterlockedIncrement(&factory
->refcount
);
64 TRACE("%p increasing refcount to %u.\n", iface
, refcount
);
69 static ULONG STDMETHODCALLTYPE
dxgi_factory_Release(IWineDXGIFactory
*iface
)
71 struct dxgi_factory
*factory
= impl_from_IWineDXGIFactory(iface
);
72 ULONG refcount
= InterlockedDecrement(&factory
->refcount
);
74 TRACE("%p decreasing refcount to %u.\n", iface
, refcount
);
78 if (factory
->device_window
)
79 DestroyWindow(factory
->device_window
);
82 wined3d_decref(factory
->wined3d
);
83 wined3d_mutex_unlock();
84 wined3d_private_store_cleanup(&factory
->private_store
);
91 static HRESULT STDMETHODCALLTYPE
dxgi_factory_SetPrivateData(IWineDXGIFactory
*iface
,
92 REFGUID guid
, UINT data_size
, const void *data
)
94 struct dxgi_factory
*factory
= impl_from_IWineDXGIFactory(iface
);
96 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
98 return dxgi_set_private_data(&factory
->private_store
, guid
, data_size
, data
);
101 static HRESULT STDMETHODCALLTYPE
dxgi_factory_SetPrivateDataInterface(IWineDXGIFactory
*iface
,
102 REFGUID guid
, const IUnknown
*object
)
104 struct dxgi_factory
*factory
= impl_from_IWineDXGIFactory(iface
);
106 TRACE("iface %p, guid %s, object %p.\n", iface
, debugstr_guid(guid
), object
);
108 return dxgi_set_private_data_interface(&factory
->private_store
, guid
, object
);
111 static HRESULT STDMETHODCALLTYPE
dxgi_factory_GetPrivateData(IWineDXGIFactory
*iface
,
112 REFGUID guid
, UINT
*data_size
, void *data
)
114 struct dxgi_factory
*factory
= impl_from_IWineDXGIFactory(iface
);
116 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
118 return dxgi_get_private_data(&factory
->private_store
, guid
, data_size
, data
);
121 static HRESULT STDMETHODCALLTYPE
dxgi_factory_GetParent(IWineDXGIFactory
*iface
, REFIID iid
, void **parent
)
123 WARN("iface %p, iid %s, parent %p.\n", iface
, debugstr_guid(iid
), parent
);
127 return E_NOINTERFACE
;
130 static HRESULT STDMETHODCALLTYPE
dxgi_factory_EnumAdapters1(IWineDXGIFactory
*iface
,
131 UINT adapter_idx
, IDXGIAdapter1
**adapter
)
133 struct dxgi_factory
*factory
= impl_from_IWineDXGIFactory(iface
);
134 struct dxgi_adapter
*adapter_object
;
138 TRACE("iface %p, adapter_idx %u, adapter %p.\n", iface
, adapter_idx
, adapter
);
141 return DXGI_ERROR_INVALID_CALL
;
143 wined3d_mutex_lock();
144 adapter_count
= wined3d_get_adapter_count(factory
->wined3d
);
145 wined3d_mutex_unlock();
147 if (adapter_idx
>= adapter_count
)
150 return DXGI_ERROR_NOT_FOUND
;
153 if (FAILED(hr
= dxgi_adapter_create(factory
, adapter_idx
, &adapter_object
)))
159 *adapter
= (IDXGIAdapter1
*)&adapter_object
->IWineDXGIAdapter_iface
;
161 TRACE("Returning adapter %p.\n", *adapter
);
166 static HRESULT STDMETHODCALLTYPE
dxgi_factory_EnumAdapters(IWineDXGIFactory
*iface
,
167 UINT adapter_idx
, IDXGIAdapter
**adapter
)
169 TRACE("iface %p, adapter_idx %u, adapter %p.\n", iface
, adapter_idx
, adapter
);
171 return dxgi_factory_EnumAdapters1(iface
, adapter_idx
, (IDXGIAdapter1
**)adapter
);
174 static HRESULT STDMETHODCALLTYPE
dxgi_factory_MakeWindowAssociation(IWineDXGIFactory
*iface
,
175 HWND window
, UINT flags
)
177 FIXME("iface %p, window %p, flags %#x stub!\n", iface
, window
, flags
);
182 static HRESULT STDMETHODCALLTYPE
dxgi_factory_GetWindowAssociation(IWineDXGIFactory
*iface
, HWND
*window
)
184 FIXME("iface %p, window %p stub!\n", iface
, window
);
189 static HRESULT STDMETHODCALLTYPE
dxgi_factory_CreateSwapChain(IWineDXGIFactory
*iface
,
190 IUnknown
*device
, DXGI_SWAP_CHAIN_DESC
*desc
, IDXGISwapChain
**swapchain
)
192 struct dxgi_factory
*factory
= impl_from_IWineDXGIFactory(iface
);
193 DXGI_SWAP_CHAIN_FULLSCREEN_DESC fullscreen_desc
;
194 DXGI_SWAP_CHAIN_DESC1 swapchain_desc
;
196 TRACE("iface %p, device %p, desc %p, swapchain %p.\n", iface
, device
, desc
, swapchain
);
200 WARN("Invalid pointer.\n");
201 return DXGI_ERROR_INVALID_CALL
;
204 swapchain_desc
.Width
= desc
->BufferDesc
.Width
;
205 swapchain_desc
.Height
= desc
->BufferDesc
.Height
;
206 swapchain_desc
.Format
= desc
->BufferDesc
.Format
;
207 swapchain_desc
.Stereo
= FALSE
;
208 swapchain_desc
.SampleDesc
= desc
->SampleDesc
;
209 swapchain_desc
.BufferUsage
= desc
->BufferUsage
;
210 swapchain_desc
.BufferCount
= desc
->BufferCount
;
211 swapchain_desc
.Scaling
= DXGI_SCALING_STRETCH
;
212 swapchain_desc
.SwapEffect
= desc
->SwapEffect
;
213 swapchain_desc
.AlphaMode
= DXGI_ALPHA_MODE_IGNORE
;
214 swapchain_desc
.Flags
= desc
->Flags
;
216 fullscreen_desc
.RefreshRate
= desc
->BufferDesc
.RefreshRate
;
217 fullscreen_desc
.ScanlineOrdering
= desc
->BufferDesc
.ScanlineOrdering
;
218 fullscreen_desc
.Scaling
= desc
->BufferDesc
.Scaling
;
219 fullscreen_desc
.Windowed
= desc
->Windowed
;
221 return IWineDXGIFactory_CreateSwapChainForHwnd(&factory
->IWineDXGIFactory_iface
,
222 device
, desc
->OutputWindow
, &swapchain_desc
, &fullscreen_desc
, NULL
,
223 (IDXGISwapChain1
**)swapchain
);
226 static HRESULT STDMETHODCALLTYPE
dxgi_factory_CreateSoftwareAdapter(IWineDXGIFactory
*iface
,
227 HMODULE swrast
, IDXGIAdapter
**adapter
)
229 FIXME("iface %p, swrast %p, adapter %p stub!\n", iface
, swrast
, adapter
);
234 static BOOL STDMETHODCALLTYPE
dxgi_factory_IsCurrent(IWineDXGIFactory
*iface
)
236 FIXME("iface %p stub!\n", iface
);
241 static BOOL STDMETHODCALLTYPE
dxgi_factory_IsWindowedStereoEnabled(IWineDXGIFactory
*iface
)
243 FIXME("iface %p stub!\n", iface
);
248 static HRESULT STDMETHODCALLTYPE
dxgi_factory_CreateSwapChainForHwnd(IWineDXGIFactory
*iface
,
249 IUnknown
*device
, HWND window
, const DXGI_SWAP_CHAIN_DESC1
*swapchain_desc
,
250 const DXGI_SWAP_CHAIN_FULLSCREEN_DESC
*fullscreen_desc
,
251 IDXGIOutput
*output
, IDXGISwapChain1
**swapchain
)
253 struct wined3d_swapchain
*wined3d_swapchain
;
254 struct wined3d_swapchain_desc wined3d_desc
;
255 unsigned int min_buffer_count
;
256 IWineDXGIDevice
*dxgi_device
;
259 TRACE("iface %p, device %p, window %p, swapchain_desc %p, fullscreen_desc %p, "
260 "output %p, swapchain %p.\n",
261 iface
, device
, window
, swapchain_desc
, fullscreen_desc
, output
, swapchain
);
263 if (!device
|| !window
|| !swapchain_desc
|| !swapchain
)
265 WARN("Invalid pointer.\n");
266 return DXGI_ERROR_INVALID_CALL
;
269 if (swapchain_desc
->Stereo
)
271 FIXME("Stereo swapchains are not supported.\n");
272 return DXGI_ERROR_UNSUPPORTED
;
275 switch (swapchain_desc
->SwapEffect
)
277 case DXGI_SWAP_EFFECT_DISCARD
:
278 wined3d_desc
.swap_effect
= WINED3D_SWAP_EFFECT_DISCARD
;
279 min_buffer_count
= 1;
282 case DXGI_SWAP_EFFECT_SEQUENTIAL
:
283 wined3d_desc
.swap_effect
= WINED3D_SWAP_EFFECT_SEQUENTIAL
;
284 min_buffer_count
= 1;
287 case DXGI_SWAP_EFFECT_FLIP_DISCARD
:
288 wined3d_desc
.swap_effect
= WINED3D_SWAP_EFFECT_FLIP_DISCARD
;
289 min_buffer_count
= 2;
292 case DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
:
293 wined3d_desc
.swap_effect
= WINED3D_SWAP_EFFECT_FLIP_SEQUENTIAL
;
294 min_buffer_count
= 2;
298 WARN("Invalid swap effect %u used.\n", swapchain_desc
->SwapEffect
);
299 return DXGI_ERROR_INVALID_CALL
;
302 if (swapchain_desc
->BufferCount
< min_buffer_count
|| swapchain_desc
->BufferCount
> 16)
304 WARN("BufferCount is %u.\n", swapchain_desc
->BufferCount
);
305 return DXGI_ERROR_INVALID_CALL
;
308 if (FAILED(hr
= IUnknown_QueryInterface(device
, &IID_IWineDXGIDevice
, (void **)&dxgi_device
)))
310 ERR("This is not the device we're looking for\n");
314 if (swapchain_desc
->Scaling
!= DXGI_SCALING_STRETCH
)
315 FIXME("Ignoring scaling %#x.\n", swapchain_desc
->Scaling
);
316 if (swapchain_desc
->AlphaMode
!= DXGI_ALPHA_MODE_IGNORE
)
317 FIXME("Ignoring alpha mode %#x.\n", swapchain_desc
->AlphaMode
);
318 if (fullscreen_desc
&& fullscreen_desc
->ScanlineOrdering
)
319 FIXME("Unhandled scanline ordering %#x.\n", fullscreen_desc
->ScanlineOrdering
);
320 if (fullscreen_desc
&& fullscreen_desc
->Scaling
)
321 FIXME("Unhandled mode scaling %#x.\n", fullscreen_desc
->Scaling
);
323 wined3d_desc
.backbuffer_width
= swapchain_desc
->Width
;
324 wined3d_desc
.backbuffer_height
= swapchain_desc
->Height
;
325 wined3d_desc
.backbuffer_format
= wined3dformat_from_dxgi_format(swapchain_desc
->Format
);
326 wined3d_desc
.backbuffer_count
= swapchain_desc
->BufferCount
;
327 wined3d_desc
.backbuffer_usage
= wined3d_usage_from_dxgi_usage(swapchain_desc
->BufferUsage
);
328 wined3d_sample_desc_from_dxgi(&wined3d_desc
.multisample_type
,
329 &wined3d_desc
.multisample_quality
, &swapchain_desc
->SampleDesc
);
330 wined3d_desc
.device_window
= window
;
331 wined3d_desc
.windowed
= fullscreen_desc
? fullscreen_desc
->Windowed
: TRUE
;
332 wined3d_desc
.enable_auto_depth_stencil
= FALSE
;
333 wined3d_desc
.auto_depth_stencil_format
= 0;
334 wined3d_desc
.flags
= wined3d_swapchain_flags_from_dxgi(swapchain_desc
->Flags
);
335 wined3d_desc
.refresh_rate
= fullscreen_desc
? dxgi_rational_to_uint(&fullscreen_desc
->RefreshRate
) : 0;
336 wined3d_desc
.swap_interval
= WINED3DPRESENT_INTERVAL_DEFAULT
;
337 wined3d_desc
.auto_restore_display_mode
= TRUE
;
339 hr
= IWineDXGIDevice_create_swapchain(dxgi_device
, &wined3d_desc
, FALSE
, &wined3d_swapchain
);
340 IWineDXGIDevice_Release(dxgi_device
);
343 WARN("Failed to create swapchain, hr %#x.\n", hr
);
347 wined3d_mutex_lock();
348 *swapchain
= wined3d_swapchain_get_parent(wined3d_swapchain
);
349 wined3d_mutex_unlock();
354 static HRESULT STDMETHODCALLTYPE
dxgi_factory_CreateSwapChainForCoreWindow(IWineDXGIFactory
*iface
,
355 IUnknown
*device
, IUnknown
*window
, const DXGI_SWAP_CHAIN_DESC1
*desc
,
356 IDXGIOutput
*output
, IDXGISwapChain1
**swapchain
)
358 FIXME("iface %p, device %p, window %p, desc %p, output %p, swapchain %p stub!\n",
359 iface
, device
, window
, desc
, output
, swapchain
);
364 static HRESULT STDMETHODCALLTYPE
dxgi_factory_GetSharedResourceAdapterLuid(IWineDXGIFactory
*iface
,
365 HANDLE resource
, LUID
*luid
)
367 FIXME("iface %p, resource %p, luid %p stub!\n", iface
, resource
, luid
);
372 static HRESULT STDMETHODCALLTYPE
dxgi_factory_RegisterOcclusionStatusWindow(IWineDXGIFactory
*iface
,
373 HWND window
, UINT message
, DWORD
*cookie
)
375 FIXME("iface %p, window %p, message %#x, cookie %p stub!\n",
376 iface
, window
, message
, cookie
);
381 static HRESULT STDMETHODCALLTYPE
dxgi_factory_RegisterStereoStatusEvent(IWineDXGIFactory
*iface
,
382 HANDLE event
, DWORD
*cookie
)
384 FIXME("iface %p, event %p, cookie %p stub!\n", iface
, event
, cookie
);
389 static void STDMETHODCALLTYPE
dxgi_factory_UnregisterStereoStatus(IWineDXGIFactory
*iface
, DWORD cookie
)
391 FIXME("iface %p, cookie %#x stub!\n", iface
, cookie
);
394 static HRESULT STDMETHODCALLTYPE
dxgi_factory_RegisterStereoStatusWindow(IWineDXGIFactory
*iface
,
395 HWND window
, UINT message
, DWORD
*cookie
)
397 FIXME("iface %p, window %p, message %#x, cookie %p stub!\n",
398 iface
, window
, message
, cookie
);
403 static HRESULT STDMETHODCALLTYPE
dxgi_factory_RegisterOcclusionStatusEvent(IWineDXGIFactory
*iface
,
404 HANDLE event
, DWORD
*cookie
)
406 FIXME("iface %p, event %p, cookie %p stub!\n", iface
, event
, cookie
);
411 static void STDMETHODCALLTYPE
dxgi_factory_UnregisterOcclusionStatus(IWineDXGIFactory
*iface
, DWORD cookie
)
413 FIXME("iface %p, cookie %#x stub!\n", iface
, cookie
);
416 static HRESULT STDMETHODCALLTYPE
dxgi_factory_CreateSwapChainForComposition(IWineDXGIFactory
*iface
,
417 IUnknown
*device
, const DXGI_SWAP_CHAIN_DESC1
*desc
, IDXGIOutput
*output
, IDXGISwapChain1
**swapchain
)
419 FIXME("iface %p, device %p, desc %p, output %p, swapchain %p stub!\n",
420 iface
, device
, desc
, output
, swapchain
);
425 static UINT STDMETHODCALLTYPE
dxgi_factory_GetCreationFlags(IWineDXGIFactory
*iface
)
427 FIXME("iface %p stub!\n", iface
);
432 static HRESULT STDMETHODCALLTYPE
dxgi_factory_EnumAdapterByLuid(IWineDXGIFactory
*iface
,
433 LUID luid
, REFIID iid
, void **adapter
)
435 unsigned int adapter_index
;
436 DXGI_ADAPTER_DESC1 desc
;
437 IDXGIAdapter1
*adapter1
;
440 TRACE("iface %p, luid %08x:%08x, iid %s, adapter %p.\n",
441 iface
, luid
.HighPart
, luid
.LowPart
, debugstr_guid(iid
), adapter
);
444 while ((hr
= dxgi_factory_EnumAdapters1(iface
, adapter_index
, &adapter1
)) == S_OK
)
446 if (FAILED(hr
= IDXGIAdapter1_GetDesc1(adapter1
, &desc
)))
448 WARN("Failed to get adapter %u desc, hr %#x.\n", adapter_index
, hr
);
453 if (desc
.AdapterLuid
.LowPart
== luid
.LowPart
454 && desc
.AdapterLuid
.HighPart
== luid
.HighPart
)
456 hr
= IDXGIAdapter1_QueryInterface(adapter1
, iid
, adapter
);
457 IDXGIAdapter1_Release(adapter1
);
461 IDXGIAdapter1_Release(adapter1
);
464 if (hr
!= DXGI_ERROR_NOT_FOUND
)
465 WARN("Failed to enumerate adapters, hr %#x.\n", hr
);
467 WARN("Adapter could not be found.\n");
468 return DXGI_ERROR_NOT_FOUND
;
471 static HRESULT STDMETHODCALLTYPE
dxgi_factory_EnumWarpAdapter(IWineDXGIFactory
*iface
,
472 REFIID iid
, void **adapter
)
474 FIXME("iface %p, iid %s, adapter %p stub!\n", iface
, debugstr_guid(iid
), adapter
);
479 static HRESULT STDMETHODCALLTYPE
dxgi_factory_CheckFeatureSupport(IWineDXGIFactory
*iface
,
480 DXGI_FEATURE feature
, void *feature_data
, UINT data_size
)
482 FIXME("iface %p, feature %#x, feature_data %p, data_size %u stub!\n",
483 iface
, feature
, feature_data
, data_size
);
488 static const struct IWineDXGIFactoryVtbl dxgi_factory_vtbl
=
490 dxgi_factory_QueryInterface
,
492 dxgi_factory_Release
,
493 dxgi_factory_SetPrivateData
,
494 dxgi_factory_SetPrivateDataInterface
,
495 dxgi_factory_GetPrivateData
,
496 dxgi_factory_GetParent
,
497 dxgi_factory_EnumAdapters
,
498 dxgi_factory_MakeWindowAssociation
,
499 dxgi_factory_GetWindowAssociation
,
500 dxgi_factory_CreateSwapChain
,
501 dxgi_factory_CreateSoftwareAdapter
,
502 /* IDXGIFactory1 methods */
503 dxgi_factory_EnumAdapters1
,
504 dxgi_factory_IsCurrent
,
505 /* IDXGIFactory2 methods */
506 dxgi_factory_IsWindowedStereoEnabled
,
507 dxgi_factory_CreateSwapChainForHwnd
,
508 dxgi_factory_CreateSwapChainForCoreWindow
,
509 dxgi_factory_GetSharedResourceAdapterLuid
,
510 dxgi_factory_RegisterOcclusionStatusWindow
,
511 dxgi_factory_RegisterStereoStatusEvent
,
512 dxgi_factory_UnregisterStereoStatus
,
513 dxgi_factory_RegisterStereoStatusWindow
,
514 dxgi_factory_RegisterOcclusionStatusEvent
,
515 dxgi_factory_UnregisterOcclusionStatus
,
516 dxgi_factory_CreateSwapChainForComposition
,
517 /* IDXGIFactory3 methods */
518 dxgi_factory_GetCreationFlags
,
519 /* IDXGIFactory4 methods */
520 dxgi_factory_EnumAdapterByLuid
,
521 dxgi_factory_EnumWarpAdapter
,
522 /* IDXIGFactory5 methods */
523 dxgi_factory_CheckFeatureSupport
,
526 struct dxgi_factory
*unsafe_impl_from_IDXGIFactory(IDXGIFactory
*iface
)
528 IWineDXGIFactory
*wine_factory
;
529 struct dxgi_factory
*factory
;
534 if (FAILED(hr
= IDXGIFactory_QueryInterface(iface
, &IID_IWineDXGIFactory
, (void **)&wine_factory
)))
536 ERR("Failed to get IWineDXGIFactory interface, hr %#x.\n", hr
);
539 assert(wine_factory
->lpVtbl
== &dxgi_factory_vtbl
);
540 factory
= CONTAINING_RECORD(wine_factory
, struct dxgi_factory
, IWineDXGIFactory_iface
);
541 IWineDXGIFactory_Release(wine_factory
);
545 static HRESULT
dxgi_factory_init(struct dxgi_factory
*factory
, BOOL extended
)
547 factory
->IWineDXGIFactory_iface
.lpVtbl
= &dxgi_factory_vtbl
;
548 factory
->refcount
= 1;
549 wined3d_private_store_init(&factory
->private_store
);
551 wined3d_mutex_lock();
552 factory
->wined3d
= wined3d_create(0);
553 wined3d_mutex_unlock();
554 if (!factory
->wined3d
)
556 wined3d_private_store_cleanup(&factory
->private_store
);
557 return DXGI_ERROR_UNSUPPORTED
;
560 factory
->extended
= extended
;
565 HRESULT
dxgi_factory_create(REFIID riid
, void **factory
, BOOL extended
)
567 struct dxgi_factory
*object
;
570 if (!(object
= heap_alloc_zero(sizeof(*object
))))
571 return E_OUTOFMEMORY
;
573 if (FAILED(hr
= dxgi_factory_init(object
, extended
)))
575 WARN("Failed to initialize factory, hr %#x.\n", hr
);
580 TRACE("Created factory %p.\n", object
);
582 hr
= IWineDXGIFactory_QueryInterface(&object
->IWineDXGIFactory_iface
, riid
, factory
);
583 IWineDXGIFactory_Release(&object
->IWineDXGIFactory_iface
);
587 HWND
dxgi_factory_get_device_window(struct dxgi_factory
*factory
)
589 wined3d_mutex_lock();
591 if (!factory
->device_window
)
593 if (!(factory
->device_window
= CreateWindowA("static", "DXGI device window",
594 WS_DISABLED
, 0, 0, 0, 0, NULL
, NULL
, NULL
, NULL
)))
596 wined3d_mutex_unlock();
597 ERR("Failed to create a window.\n");
600 TRACE("Created device window %p for factory %p.\n", factory
->device_window
, factory
);
603 wined3d_mutex_unlock();
605 return factory
->device_window
;