1 //
2 // Copyright (c) 2017 The Khronos Group Inc.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 #include "wrappers.h"
17 #include "harness/errorHelpers.h"
18
19 LPCTSTR CDeviceWrapper::WINDOW_TITLE = _T( "cl_khr_dx9_media_sharing" );
20 const int CDeviceWrapper::WINDOW_WIDTH = 256;
21 const int CDeviceWrapper::WINDOW_HEIGHT = 256;
22 CDeviceWrapper::TAccelerationType CDeviceWrapper::accelerationType =
23 CDeviceWrapper::ACCELERATION_HW;
24
25 #if defined(_WIN32)
26 const D3DFORMAT CDXVAWrapper::RENDER_TARGET_FORMAT = D3DFMT_X8R8G8B8;
27 const D3DFORMAT CDXVAWrapper::VIDEO_FORMAT = D3DFMT_X8R8G8B8;
28 const unsigned int CDXVAWrapper::VIDEO_FPS = 60;
29 #endif
30
31 #if defined(_WIN32)
WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)32 static LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
33 {
34 switch (msg)
35 {
36 case WM_DESTROY: PostQuitMessage(0); return 0;
37 case WM_PAINT: ValidateRect(hWnd, 0); return 0;
38 default: break;
39 }
40
41 return DefWindowProc(hWnd, msg, wParam, lParam);
42 }
43 #endif
44
CDeviceWrapper()45 CDeviceWrapper::CDeviceWrapper()
46 #if defined(_WIN32)
47 : _hInstance(NULL), _hWnd(NULL)
48 #endif
49 {}
50
WindowInit()51 void CDeviceWrapper::WindowInit()
52 {
53 #if defined(_WIN32)
54 _hInstance = GetModuleHandle(NULL);
55 static WNDCLASSEX wc = {
56 sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L,
57 _hInstance, NULL, NULL, NULL, NULL,
58 WINDOW_TITLE, NULL
59 };
60
61 RegisterClassEx(&wc);
62
63 _hWnd = CreateWindow(WINDOW_TITLE, WINDOW_TITLE, WS_OVERLAPPEDWINDOW, 0, 0,
64 WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, wc.hInstance,
65 NULL);
66
67 if (!_hWnd)
68 {
69 log_error("Failed to create window");
70 return;
71 }
72
73 ShowWindow(_hWnd, SW_SHOWDEFAULT);
74 UpdateWindow(_hWnd);
75 #endif
76 }
77
WindowDestroy()78 void CDeviceWrapper::WindowDestroy()
79 {
80 #if defined(_WIN32)
81 if (_hWnd) DestroyWindow(_hWnd);
82 _hWnd = NULL;
83 #endif
84 }
85
86 #if defined(_WIN32)
WindowHandle() const87 HWND CDeviceWrapper::WindowHandle() const { return _hWnd; }
88 #endif
89
WindowWidth() const90 int CDeviceWrapper::WindowWidth() const { return WINDOW_WIDTH; }
91
WindowHeight() const92 int CDeviceWrapper::WindowHeight() const { return WINDOW_HEIGHT; }
93
AccelerationType()94 CDeviceWrapper::TAccelerationType CDeviceWrapper::AccelerationType()
95 {
96 return accelerationType;
97 }
98
AccelerationType(TAccelerationType accelerationTypeNew)99 void CDeviceWrapper::AccelerationType(TAccelerationType accelerationTypeNew)
100 {
101 accelerationType = accelerationTypeNew;
102 }
103
~CDeviceWrapper()104 CDeviceWrapper::~CDeviceWrapper() { WindowDestroy(); }
105
106 #if defined(_WIN32)
CD3D9Wrapper()107 CD3D9Wrapper::CD3D9Wrapper()
108 : _d3d9(NULL), _d3dDevice(NULL), _status(DEVICE_PASS), _adapterIdx(0),
109 _adapterFound(false)
110 {
111 WindowInit();
112
113 _d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
114 if (!_d3d9)
115 {
116 log_error("Direct3DCreate9 failed\n");
117 _status = DEVICE_FAIL;
118 }
119 }
120
~CD3D9Wrapper()121 CD3D9Wrapper::~CD3D9Wrapper()
122 {
123 Destroy();
124
125 if (_d3d9) _d3d9->Release();
126 _d3d9 = 0;
127 }
128
Destroy()129 void CD3D9Wrapper::Destroy()
130 {
131 if (_d3dDevice) _d3dDevice->Release();
132 _d3dDevice = 0;
133 }
134
Init()135 cl_int CD3D9Wrapper::Init()
136 {
137 if (!WindowHandle())
138 {
139 log_error("D3D9: Window is not created\n");
140 _status = DEVICE_FAIL;
141 return DEVICE_FAIL;
142 }
143
144 if (!_d3d9 || DEVICE_PASS != _status || !_adapterFound) return false;
145
146 _d3d9->GetAdapterDisplayMode(_adapterIdx - 1, &_d3ddm);
147
148 D3DPRESENT_PARAMETERS d3dParams;
149 ZeroMemory(&d3dParams, sizeof(d3dParams));
150
151 d3dParams.Windowed = TRUE;
152 d3dParams.BackBufferCount = 1;
153 d3dParams.SwapEffect = D3DSWAPEFFECT_DISCARD;
154 d3dParams.hDeviceWindow = WindowHandle();
155 d3dParams.BackBufferWidth = WindowWidth();
156 d3dParams.BackBufferHeight = WindowHeight();
157 d3dParams.BackBufferFormat = _d3ddm.Format;
158
159 DWORD processingType = (AccelerationType() == ACCELERATION_HW)
160 ? D3DCREATE_HARDWARE_VERTEXPROCESSING
161 : D3DCREATE_SOFTWARE_VERTEXPROCESSING;
162
163 if (FAILED(_d3d9->CreateDevice(_adapterIdx - 1, D3DDEVTYPE_HAL,
164 WindowHandle(), processingType, &d3dParams,
165 &_d3dDevice)))
166 {
167 log_error("CreateDevice failed\n");
168 _status = DEVICE_FAIL;
169 return DEVICE_FAIL;
170 }
171
172 _d3dDevice->BeginScene();
173 _d3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, 0, 1.0f, 0);
174 _d3dDevice->EndScene();
175
176 return true;
177 }
178
D3D() const179 void *CD3D9Wrapper::D3D() const { return _d3d9; }
180
Device() const181 void *CD3D9Wrapper::Device() const { return _d3dDevice; }
182
Format()183 D3DFORMAT CD3D9Wrapper::Format() { return _d3ddm.Format; }
184
Adapter()185 D3DADAPTER_IDENTIFIER9 CD3D9Wrapper::Adapter() { return _adapter; }
186
Status() const187 TDeviceStatus CD3D9Wrapper::Status() const { return _status; }
188
AdapterNext()189 bool CD3D9Wrapper::AdapterNext()
190 {
191 if (DEVICE_PASS != _status) return false;
192
193 _adapterFound = false;
194 for (; _adapterIdx < _d3d9->GetAdapterCount();)
195 {
196 ++_adapterIdx;
197 D3DCAPS9 caps;
198 if (FAILED(
199 _d3d9->GetDeviceCaps(_adapterIdx - 1, D3DDEVTYPE_HAL, &caps)))
200 continue;
201
202 if (FAILED(_d3d9->GetAdapterIdentifier(_adapterIdx - 1, 0, &_adapter)))
203 {
204 log_error("D3D9: GetAdapterIdentifier failed\n");
205 _status = DEVICE_FAIL;
206 return false;
207 }
208
209 _adapterFound = true;
210
211 Destroy();
212 if (!Init())
213 {
214 _status = DEVICE_FAIL;
215 _adapterFound = false;
216 }
217 break;
218 }
219
220 return _adapterFound;
221 }
222
AdapterIdx() const223 unsigned int CD3D9Wrapper::AdapterIdx() const { return _adapterIdx - 1; }
224
225
CD3D9ExWrapper()226 CD3D9ExWrapper::CD3D9ExWrapper()
227 : _d3d9Ex(NULL), _d3dDeviceEx(NULL), _status(DEVICE_PASS), _adapterIdx(0),
228 _adapterFound(false)
229 {
230 WindowInit();
231
232 HRESULT result = Direct3DCreate9Ex(D3D_SDK_VERSION, &_d3d9Ex);
233 if (FAILED(result) || !_d3d9Ex)
234 {
235 log_error("Direct3DCreate9Ex failed\n");
236 _status = DEVICE_FAIL;
237 }
238 }
239
~CD3D9ExWrapper()240 CD3D9ExWrapper::~CD3D9ExWrapper()
241 {
242 Destroy();
243
244 if (_d3d9Ex) _d3d9Ex->Release();
245 _d3d9Ex = 0;
246 }
247
D3D() const248 void *CD3D9ExWrapper::D3D() const { return _d3d9Ex; }
249
Device() const250 void *CD3D9ExWrapper::Device() const { return _d3dDeviceEx; }
251
Format()252 D3DFORMAT CD3D9ExWrapper::Format() { return _d3ddmEx.Format; }
253
Adapter()254 D3DADAPTER_IDENTIFIER9 CD3D9ExWrapper::Adapter() { return _adapter; }
255
Init()256 cl_int CD3D9ExWrapper::Init()
257 {
258 if (!WindowHandle())
259 {
260 log_error("D3D9EX: Window is not created\n");
261 _status = DEVICE_FAIL;
262 return DEVICE_FAIL;
263 }
264
265 if (!_d3d9Ex || DEVICE_FAIL == _status || !_adapterFound)
266 return DEVICE_FAIL;
267
268 RECT rect;
269 GetClientRect(WindowHandle(), &rect);
270
271 D3DPRESENT_PARAMETERS d3dParams;
272 ZeroMemory(&d3dParams, sizeof(d3dParams));
273
274 d3dParams.Windowed = TRUE;
275 d3dParams.SwapEffect = D3DSWAPEFFECT_FLIP;
276 d3dParams.BackBufferFormat = D3DFMT_X8R8G8B8;
277 d3dParams.BackBufferWidth = WindowWidth();
278 d3dParams.BackBufferHeight = WindowHeight();
279
280 d3dParams.BackBufferCount = 1;
281 d3dParams.hDeviceWindow = WindowHandle();
282
283 DWORD processingType = (AccelerationType() == ACCELERATION_HW)
284 ? D3DCREATE_HARDWARE_VERTEXPROCESSING
285 : D3DCREATE_SOFTWARE_VERTEXPROCESSING;
286
287 if (FAILED(_d3d9Ex->CreateDeviceEx(_adapterIdx - 1, D3DDEVTYPE_HAL,
288 WindowHandle(), processingType,
289 &d3dParams, NULL, &_d3dDeviceEx)))
290 {
291 log_error("CreateDeviceEx failed\n");
292 _status = DEVICE_FAIL;
293 return DEVICE_FAIL;
294 }
295
296 _d3dDeviceEx->BeginScene();
297 _d3dDeviceEx->Clear(0, NULL, D3DCLEAR_TARGET, 0, 1.0f, 0);
298 _d3dDeviceEx->EndScene();
299
300 return DEVICE_PASS;
301 }
302
Destroy()303 void CD3D9ExWrapper::Destroy()
304 {
305 if (_d3dDeviceEx) _d3dDeviceEx->Release();
306 _d3dDeviceEx = 0;
307 }
308
Status() const309 TDeviceStatus CD3D9ExWrapper::Status() const { return _status; }
310
AdapterNext()311 bool CD3D9ExWrapper::AdapterNext()
312 {
313 if (DEVICE_FAIL == _status) return false;
314
315 _adapterFound = false;
316 for (; _adapterIdx < _d3d9Ex->GetAdapterCount();)
317 {
318 ++_adapterIdx;
319 D3DCAPS9 caps;
320 if (FAILED(
321 _d3d9Ex->GetDeviceCaps(_adapterIdx - 1, D3DDEVTYPE_HAL, &caps)))
322 continue;
323
324 if (FAILED(
325 _d3d9Ex->GetAdapterIdentifier(_adapterIdx - 1, 0, &_adapter)))
326 {
327 log_error("D3D9EX: GetAdapterIdentifier failed\n");
328 _status = DEVICE_FAIL;
329 return false;
330 }
331
332 _adapterFound = true;
333 Destroy();
334 if (!Init())
335 {
336 _status = DEVICE_FAIL;
337 _adapterFound = _status;
338 }
339
340 break;
341 }
342
343 return _adapterFound;
344 }
345
AdapterIdx() const346 unsigned int CD3D9ExWrapper::AdapterIdx() const { return _adapterIdx - 1; }
347
CDXVAWrapper()348 CDXVAWrapper::CDXVAWrapper()
349 : _dxvaDevice(NULL), _status(DEVICE_PASS), _adapterFound(false)
350 {
351 _status = _d3d9.Status();
352 }
353
~CDXVAWrapper()354 CDXVAWrapper::~CDXVAWrapper() { DXVAHDDestroy(); }
355
Device() const356 void *CDXVAWrapper::Device() const { return _dxvaDevice; }
357
Status() const358 TDeviceStatus CDXVAWrapper::Status() const
359 {
360 if (_status == DEVICE_FAIL || _d3d9.Status() == DEVICE_FAIL)
361 return DEVICE_FAIL;
362 else if (_status == DEVICE_NOTSUPPORTED
363 || _d3d9.Status() == DEVICE_NOTSUPPORTED)
364 return DEVICE_NOTSUPPORTED;
365 else
366 return DEVICE_PASS;
367 }
368
AdapterNext()369 bool CDXVAWrapper::AdapterNext()
370 {
371 if (DEVICE_PASS != _status) return false;
372
373 _adapterFound = _d3d9.AdapterNext();
374 _status = _d3d9.Status();
375 if (DEVICE_PASS != _status)
376 {
377 _adapterFound = false;
378 return false;
379 }
380
381 if (!_adapterFound) return false;
382
383 DXVAHDDestroy();
384 _status = DXVAHDInit();
385 if (DEVICE_PASS != _status)
386 {
387 _adapterFound = false;
388 return false;
389 }
390
391 return true;
392 }
393
DXVAHDInit()394 TDeviceStatus CDXVAWrapper::DXVAHDInit()
395 {
396 if ((_status == DEVICE_FAIL) || (_d3d9.Status() == DEVICE_FAIL)
397 || !_adapterFound)
398 return DEVICE_FAIL;
399
400 DXVAHD_RATIONAL fps = { VIDEO_FPS, 1 };
401
402 DXVAHD_CONTENT_DESC desc;
403 desc.InputFrameFormat = DXVAHD_FRAME_FORMAT_PROGRESSIVE;
404 desc.InputFrameRate = fps;
405 desc.InputWidth = WindowWidth();
406 desc.InputHeight = WindowHeight();
407 desc.OutputFrameRate = fps;
408 desc.OutputWidth = WindowWidth();
409 desc.OutputHeight = WindowHeight();
410
411 #ifdef USE_SOFTWARE_PLUGIN
412 _status = DEVICE_FAIL;
413 return DEVICE_FAIL;
414 #endif
415
416 HRESULT hr = DXVAHD_CreateDevice(
417 static_cast<IDirect3DDevice9Ex *>(_d3d9.Device()), &desc,
418 DXVAHD_DEVICE_USAGE_PLAYBACK_NORMAL, NULL, &_dxvaDevice);
419 if (FAILED(hr))
420 {
421 if (hr == E_NOINTERFACE)
422 {
423 log_error(
424 "DXVAHD_CreateDevice skipped due to no supported devices!\n");
425 _status = DEVICE_NOTSUPPORTED;
426 }
427 else
428 {
429 log_error("DXVAHD_CreateDevice failed\n");
430 _status = DEVICE_FAIL;
431 }
432 }
433
434 return _status;
435 }
436
DXVAHDDestroy()437 void CDXVAWrapper::DXVAHDDestroy()
438 {
439 if (_dxvaDevice) _dxvaDevice->Release();
440 _dxvaDevice = 0;
441 }
442
D3D() const443 void *CDXVAWrapper::D3D() const { return _d3d9.D3D(); }
444
AdapterIdx() const445 unsigned int CDXVAWrapper::AdapterIdx() const { return _d3d9.AdapterIdx(); }
446
D3D9() const447 const CD3D9ExWrapper &CDXVAWrapper::D3D9() const { return _d3d9; }
448
CD3D9SurfaceWrapper()449 CD3D9SurfaceWrapper::CD3D9SurfaceWrapper(): mMem(NULL) {}
450
CD3D9SurfaceWrapper(IDirect3DSurface9 * mem)451 CD3D9SurfaceWrapper::CD3D9SurfaceWrapper(IDirect3DSurface9 *mem): mMem(mem) {}
452
~CD3D9SurfaceWrapper()453 CD3D9SurfaceWrapper::~CD3D9SurfaceWrapper()
454 {
455 if (mMem != NULL) mMem->Release();
456 mMem = NULL;
457 }
458
459 #endif
460
CSurfaceWrapper()461 CSurfaceWrapper::CSurfaceWrapper() {}
462
~CSurfaceWrapper()463 CSurfaceWrapper::~CSurfaceWrapper() {}
464