direct3d9: remove the secondary HWND storage
[vlc.git] / modules / video_chroma / d3d9_fmt.c
blobdd2694b18a4b924cdb2282151189b8df55f1e224
1 /*****************************************************************************
2 * d3d9_fmt.c : D3D9 helper calls
3 *****************************************************************************
4 * Copyright © 2017 VLC authors, VideoLAN and VideoLabs
6 * Authors: Steve Lhomme <robux4@gmail.com>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either version 2.1 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
22 #ifdef HAVE_CONFIG_H
23 # include "config.h"
24 #endif
26 #include <assert.h>
28 #include "d3d9_fmt.h"
30 #include "../codec/avcodec/va_surface.h"
32 picture_sys_t *ActivePictureSys(picture_t *p_pic)
34 struct va_pic_context *pic_ctx = (struct va_pic_context*)p_pic->context;
35 return pic_ctx ? &pic_ctx->picsys : p_pic->p_sys;
38 #undef D3D9_CreateDevice
39 HRESULT D3D9_CreateDevice(vlc_object_t *o, d3d9_handle_t *hd3d, HWND hwnd,
40 const video_format_t *source, d3d9_device_t *out)
42 HRESULT hr;
44 UINT AdapterToUse = D3DADAPTER_DEFAULT;
45 D3DDEVTYPE DeviceType = D3DDEVTYPE_HAL;
47 #ifndef NDEBUG
48 // Look for 'NVIDIA PerfHUD' adapter
49 // If it is present, override default settings
50 for (UINT Adapter=0; Adapter< IDirect3D9_GetAdapterCount(hd3d->obj); ++Adapter) {
51 D3DADAPTER_IDENTIFIER9 Identifier;
52 hr = IDirect3D9_GetAdapterIdentifier(hd3d->obj,Adapter,0,&Identifier);
53 if (SUCCEEDED(hr) && strstr(Identifier.Description,"PerfHUD") != 0) {
54 AdapterToUse = Adapter;
55 DeviceType = D3DDEVTYPE_REF;
56 break;
59 #endif
62 ** Get device capabilities
64 ZeroMemory(&out->caps, sizeof(out->caps));
65 hr = IDirect3D9_GetDeviceCaps(hd3d->obj, AdapterToUse, DeviceType, &out->caps);
66 if (FAILED(hr)) {
67 msg_Err(o, "Could not read adapter capabilities. (hr=0x%0lx)", hr);
68 return hr;
71 /* TODO: need to test device capabilities and select the right render function */
72 if (!(out->caps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES)) {
73 msg_Err(o, "Device does not support stretching from textures.");
74 return E_INVALIDARG;
77 if ( source->i_width > out->caps.MaxTextureWidth ||
78 source->i_height > out->caps.MaxTextureHeight )
80 msg_Err(o, "Textures too large %ux%u max possible: %ux%u",
81 source->i_width, source->i_height,
82 (unsigned) out->caps.MaxTextureWidth,
83 (unsigned) out->caps.MaxTextureHeight);
84 return E_INVALIDARG;
87 out->hwnd = hwnd;
88 if (D3D9_FillPresentationParameters(o, hd3d, AdapterToUse, source, out))
89 return E_INVALIDARG;
91 /* */
92 D3DADAPTER_IDENTIFIER9 d3dai;
93 if (FAILED(IDirect3D9_GetAdapterIdentifier(hd3d->obj, AdapterToUse,0, &d3dai))) {
94 msg_Warn(o, "IDirect3D9_GetAdapterIdentifier failed");
95 } else {
96 msg_Dbg(o, "Direct3d9 Device: %s %lu %lu %lu", d3dai.Description,
97 d3dai.VendorId, d3dai.DeviceId, d3dai.Revision );
100 DWORD creationFlags = D3DCREATE_MULTITHREADED;
101 if ( (out->caps.DevCaps & D3DDEVCAPS_DRAWPRIMTLVERTEX) &&
102 (out->caps.DevCaps & D3DDEVCAPS_HWRASTERIZATION) ) {
103 creationFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
104 } else if (out->caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) {
105 creationFlags |= D3DCREATE_MIXED_VERTEXPROCESSING;
106 } else {
107 creationFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
110 if (hd3d->use_ex)
111 hr = IDirect3D9Ex_CreateDeviceEx(hd3d->objex, AdapterToUse,
112 DeviceType, hwnd,
113 creationFlags,
114 &out->pp, NULL, &out->devex);
115 else
116 hr = IDirect3D9_CreateDevice(hd3d->obj, AdapterToUse,
117 DeviceType, hwnd,
118 creationFlags,
119 &out->pp, &out->dev);
121 if (SUCCEEDED(hr))
123 out->owner = true;
124 out->adapterId = AdapterToUse;
126 return hr;
129 void D3D9_ReleaseDevice(d3d9_device_t *d3d_dev)
131 if (d3d_dev->dev)
133 IDirect3DDevice9_Release(d3d_dev->dev);
134 d3d_dev->dev = NULL;
139 * It setup vout_display_sys_t::d3dpp and vout_display_sys_t::rect_display
140 * from the default adapter.
142 int D3D9_FillPresentationParameters(vlc_object_t *o, d3d9_handle_t *hd3d, UINT AdapterToUse,
143 const video_format_t *source, d3d9_device_t *out)
146 ** Get the current desktop display mode, so we can set up a back
147 ** buffer of the same format
149 D3DDISPLAYMODE d3ddm;
150 if (source->i_width)
152 HRESULT hr = IDirect3D9_GetAdapterDisplayMode(hd3d->obj, AdapterToUse, &d3ddm);
153 if (FAILED(hr)) {
154 msg_Err(o, "Could not read adapter display mode. (hr=0x%0lx)", hr);
155 return VLC_EGENERIC;
159 /* Set up the structure used to create the D3DDevice. */
160 D3DPRESENT_PARAMETERS *d3dpp = &out->pp;
161 ZeroMemory(d3dpp, sizeof(D3DPRESENT_PARAMETERS));
162 d3dpp->Flags = D3DPRESENTFLAG_VIDEO;
163 d3dpp->Windowed = TRUE;
164 d3dpp->MultiSampleType = D3DMULTISAMPLE_NONE;
165 d3dpp->PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
166 d3dpp->EnableAutoDepthStencil = FALSE;
167 if (source->i_width)
169 d3dpp->hDeviceWindow = out->hwnd;
170 d3dpp->SwapEffect = D3DSWAPEFFECT_COPY;
171 d3dpp->BackBufferFormat = d3ddm.Format;
172 d3dpp->BackBufferCount = 1;
173 d3dpp->BackBufferWidth = __MAX((unsigned int)GetSystemMetrics(SM_CXVIRTUALSCREEN),
174 source->i_width);
175 d3dpp->BackBufferHeight = __MAX((unsigned int)GetSystemMetrics(SM_CYVIRTUALSCREEN),
176 source->i_height);
178 else
180 d3dpp->hDeviceWindow = NULL;
181 d3dpp->SwapEffect = D3DSWAPEFFECT_DISCARD;
182 d3dpp->BackBufferCount = 0;
183 d3dpp->BackBufferFormat = D3DFMT_X8R8G8B8; /* FIXME what to put here */
186 return VLC_SUCCESS;
189 void D3D9_Destroy(d3d9_handle_t *hd3d)
191 if (hd3d->obj)
193 IDirect3D9_Release(hd3d->obj);
194 hd3d->obj = NULL;
196 if (hd3d->hdll)
198 FreeLibrary(hd3d->hdll);
199 hd3d->hdll = NULL;
204 * It initializes an instance of Direct3D9
206 #undef D3D9_Create
207 int D3D9_Create(vlc_object_t *o, d3d9_handle_t *hd3d)
209 hd3d->hdll = LoadLibrary(TEXT("D3D9.DLL"));
210 if (!hd3d->hdll) {
211 msg_Warn(o, "cannot load d3d9.dll, aborting");
212 return VLC_EGENERIC;
215 LPDIRECT3D9 (WINAPI *OurDirect3DCreate9)(UINT SDKVersion);
216 OurDirect3DCreate9 =
217 (void *)GetProcAddress(hd3d->hdll, "Direct3DCreate9");
218 if (!OurDirect3DCreate9) {
219 msg_Err(o, "Cannot locate reference to Direct3DCreate9 ABI in DLL");
220 goto error;
223 HRESULT (WINAPI *OurDirect3DCreate9Ex)(UINT SDKVersion, IDirect3D9Ex **ppD3D);
224 OurDirect3DCreate9Ex =
225 (void *)GetProcAddress(hd3d->hdll, "Direct3DCreate9Ex");
227 /* Create the D3D object. */
228 hd3d->use_ex = false;
229 if (OurDirect3DCreate9Ex) {
230 HRESULT hr = OurDirect3DCreate9Ex(D3D_SDK_VERSION, &hd3d->objex);
231 if(!FAILED(hr)) {
232 msg_Dbg(o, "Using Direct3D9 Extended API!");
233 hd3d->use_ex = true;
237 if (!hd3d->obj)
239 hd3d->obj = OurDirect3DCreate9(D3D_SDK_VERSION);
240 if (!hd3d->obj) {
241 msg_Err(o, "Could not create Direct3D9 instance.");
242 goto error;
245 return VLC_SUCCESS;
246 error:
247 D3D9_Destroy( hd3d );
248 return VLC_EGENERIC;