| // |
| // Copyright (c) 2017 The Khronos Group Inc. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| #include "wrappers.h" |
| #include "harness/errorHelpers.h" |
| |
| LPCTSTR CDeviceWrapper::WINDOW_TITLE = _T( "cl_khr_dx9_media_sharing" ); |
| const int CDeviceWrapper::WINDOW_WIDTH = 256; |
| const int CDeviceWrapper::WINDOW_HEIGHT = 256; |
| CDeviceWrapper::TAccelerationType CDeviceWrapper::accelerationType = |
| CDeviceWrapper::ACCELERATION_HW; |
| |
| #if defined(_WIN32) |
| const D3DFORMAT CDXVAWrapper::RENDER_TARGET_FORMAT = D3DFMT_X8R8G8B8; |
| const D3DFORMAT CDXVAWrapper::VIDEO_FORMAT = D3DFMT_X8R8G8B8; |
| const unsigned int CDXVAWrapper::VIDEO_FPS = 60; |
| #endif |
| |
| #if defined(_WIN32) |
| static LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) |
| { |
| switch (msg) |
| { |
| case WM_DESTROY: PostQuitMessage(0); return 0; |
| case WM_PAINT: ValidateRect(hWnd, 0); return 0; |
| default: break; |
| } |
| |
| return DefWindowProc(hWnd, msg, wParam, lParam); |
| } |
| #endif |
| |
| CDeviceWrapper::CDeviceWrapper() |
| #if defined(_WIN32) |
| : _hInstance(NULL), _hWnd(NULL) |
| #endif |
| {} |
| |
| void CDeviceWrapper::WindowInit() |
| { |
| #if defined(_WIN32) |
| _hInstance = GetModuleHandle(NULL); |
| static WNDCLASSEX wc = { |
| sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, |
| _hInstance, NULL, NULL, NULL, NULL, |
| WINDOW_TITLE, NULL |
| }; |
| |
| RegisterClassEx(&wc); |
| |
| _hWnd = CreateWindow(WINDOW_TITLE, WINDOW_TITLE, WS_OVERLAPPEDWINDOW, 0, 0, |
| WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, wc.hInstance, |
| NULL); |
| |
| if (!_hWnd) |
| { |
| log_error("Failed to create window"); |
| return; |
| } |
| |
| ShowWindow(_hWnd, SW_SHOWDEFAULT); |
| UpdateWindow(_hWnd); |
| #endif |
| } |
| |
| void CDeviceWrapper::WindowDestroy() |
| { |
| #if defined(_WIN32) |
| if (_hWnd) DestroyWindow(_hWnd); |
| _hWnd = NULL; |
| #endif |
| } |
| |
| #if defined(_WIN32) |
| HWND CDeviceWrapper::WindowHandle() const { return _hWnd; } |
| #endif |
| |
| int CDeviceWrapper::WindowWidth() const { return WINDOW_WIDTH; } |
| |
| int CDeviceWrapper::WindowHeight() const { return WINDOW_HEIGHT; } |
| |
| CDeviceWrapper::TAccelerationType CDeviceWrapper::AccelerationType() |
| { |
| return accelerationType; |
| } |
| |
| void CDeviceWrapper::AccelerationType(TAccelerationType accelerationTypeNew) |
| { |
| accelerationType = accelerationTypeNew; |
| } |
| |
| CDeviceWrapper::~CDeviceWrapper() { WindowDestroy(); } |
| |
| #if defined(_WIN32) |
| CD3D9Wrapper::CD3D9Wrapper() |
| : _d3d9(NULL), _d3dDevice(NULL), _status(DEVICE_PASS), _adapterIdx(0), |
| _adapterFound(false) |
| { |
| WindowInit(); |
| |
| _d3d9 = Direct3DCreate9(D3D_SDK_VERSION); |
| if (!_d3d9) |
| { |
| log_error("Direct3DCreate9 failed\n"); |
| _status = DEVICE_FAIL; |
| } |
| } |
| |
| CD3D9Wrapper::~CD3D9Wrapper() |
| { |
| Destroy(); |
| |
| if (_d3d9) _d3d9->Release(); |
| _d3d9 = 0; |
| } |
| |
| void CD3D9Wrapper::Destroy() |
| { |
| if (_d3dDevice) _d3dDevice->Release(); |
| _d3dDevice = 0; |
| } |
| |
| cl_int CD3D9Wrapper::Init() |
| { |
| if (!WindowHandle()) |
| { |
| log_error("D3D9: Window is not created\n"); |
| _status = DEVICE_FAIL; |
| return DEVICE_FAIL; |
| } |
| |
| if (!_d3d9 || DEVICE_PASS != _status || !_adapterFound) return false; |
| |
| _d3d9->GetAdapterDisplayMode(_adapterIdx - 1, &_d3ddm); |
| |
| D3DPRESENT_PARAMETERS d3dParams; |
| ZeroMemory(&d3dParams, sizeof(d3dParams)); |
| |
| d3dParams.Windowed = TRUE; |
| d3dParams.BackBufferCount = 1; |
| d3dParams.SwapEffect = D3DSWAPEFFECT_DISCARD; |
| d3dParams.hDeviceWindow = WindowHandle(); |
| d3dParams.BackBufferWidth = WindowWidth(); |
| d3dParams.BackBufferHeight = WindowHeight(); |
| d3dParams.BackBufferFormat = _d3ddm.Format; |
| |
| DWORD processingType = (AccelerationType() == ACCELERATION_HW) |
| ? D3DCREATE_HARDWARE_VERTEXPROCESSING |
| : D3DCREATE_SOFTWARE_VERTEXPROCESSING; |
| |
| if (FAILED(_d3d9->CreateDevice(_adapterIdx - 1, D3DDEVTYPE_HAL, |
| WindowHandle(), processingType, &d3dParams, |
| &_d3dDevice))) |
| { |
| log_error("CreateDevice failed\n"); |
| _status = DEVICE_FAIL; |
| return DEVICE_FAIL; |
| } |
| |
| _d3dDevice->BeginScene(); |
| _d3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, 0, 1.0f, 0); |
| _d3dDevice->EndScene(); |
| |
| return true; |
| } |
| |
| void *CD3D9Wrapper::D3D() const { return _d3d9; } |
| |
| void *CD3D9Wrapper::Device() const { return _d3dDevice; } |
| |
| D3DFORMAT CD3D9Wrapper::Format() { return _d3ddm.Format; } |
| |
| D3DADAPTER_IDENTIFIER9 CD3D9Wrapper::Adapter() { return _adapter; } |
| |
| TDeviceStatus CD3D9Wrapper::Status() const { return _status; } |
| |
| bool CD3D9Wrapper::AdapterNext() |
| { |
| if (DEVICE_PASS != _status) return false; |
| |
| _adapterFound = false; |
| for (; _adapterIdx < _d3d9->GetAdapterCount();) |
| { |
| ++_adapterIdx; |
| D3DCAPS9 caps; |
| if (FAILED( |
| _d3d9->GetDeviceCaps(_adapterIdx - 1, D3DDEVTYPE_HAL, &caps))) |
| continue; |
| |
| if (FAILED(_d3d9->GetAdapterIdentifier(_adapterIdx - 1, 0, &_adapter))) |
| { |
| log_error("D3D9: GetAdapterIdentifier failed\n"); |
| _status = DEVICE_FAIL; |
| return false; |
| } |
| |
| _adapterFound = true; |
| |
| Destroy(); |
| if (!Init()) |
| { |
| _status = DEVICE_FAIL; |
| _adapterFound = false; |
| } |
| break; |
| } |
| |
| return _adapterFound; |
| } |
| |
| unsigned int CD3D9Wrapper::AdapterIdx() const { return _adapterIdx - 1; } |
| |
| |
| CD3D9ExWrapper::CD3D9ExWrapper() |
| : _d3d9Ex(NULL), _d3dDeviceEx(NULL), _status(DEVICE_PASS), _adapterIdx(0), |
| _adapterFound(false) |
| { |
| WindowInit(); |
| |
| HRESULT result = Direct3DCreate9Ex(D3D_SDK_VERSION, &_d3d9Ex); |
| if (FAILED(result) || !_d3d9Ex) |
| { |
| log_error("Direct3DCreate9Ex failed\n"); |
| _status = DEVICE_FAIL; |
| } |
| } |
| |
| CD3D9ExWrapper::~CD3D9ExWrapper() |
| { |
| Destroy(); |
| |
| if (_d3d9Ex) _d3d9Ex->Release(); |
| _d3d9Ex = 0; |
| } |
| |
| void *CD3D9ExWrapper::D3D() const { return _d3d9Ex; } |
| |
| void *CD3D9ExWrapper::Device() const { return _d3dDeviceEx; } |
| |
| D3DFORMAT CD3D9ExWrapper::Format() { return _d3ddmEx.Format; } |
| |
| D3DADAPTER_IDENTIFIER9 CD3D9ExWrapper::Adapter() { return _adapter; } |
| |
| cl_int CD3D9ExWrapper::Init() |
| { |
| if (!WindowHandle()) |
| { |
| log_error("D3D9EX: Window is not created\n"); |
| _status = DEVICE_FAIL; |
| return DEVICE_FAIL; |
| } |
| |
| if (!_d3d9Ex || DEVICE_FAIL == _status || !_adapterFound) |
| return DEVICE_FAIL; |
| |
| RECT rect; |
| GetClientRect(WindowHandle(), &rect); |
| |
| D3DPRESENT_PARAMETERS d3dParams; |
| ZeroMemory(&d3dParams, sizeof(d3dParams)); |
| |
| d3dParams.Windowed = TRUE; |
| d3dParams.SwapEffect = D3DSWAPEFFECT_FLIP; |
| d3dParams.BackBufferFormat = D3DFMT_X8R8G8B8; |
| d3dParams.BackBufferWidth = WindowWidth(); |
| d3dParams.BackBufferHeight = WindowHeight(); |
| |
| d3dParams.BackBufferCount = 1; |
| d3dParams.hDeviceWindow = WindowHandle(); |
| |
| DWORD processingType = (AccelerationType() == ACCELERATION_HW) |
| ? D3DCREATE_HARDWARE_VERTEXPROCESSING |
| : D3DCREATE_SOFTWARE_VERTEXPROCESSING; |
| |
| if (FAILED(_d3d9Ex->CreateDeviceEx(_adapterIdx - 1, D3DDEVTYPE_HAL, |
| WindowHandle(), processingType, |
| &d3dParams, NULL, &_d3dDeviceEx))) |
| { |
| log_error("CreateDeviceEx failed\n"); |
| _status = DEVICE_FAIL; |
| return DEVICE_FAIL; |
| } |
| |
| _d3dDeviceEx->BeginScene(); |
| _d3dDeviceEx->Clear(0, NULL, D3DCLEAR_TARGET, 0, 1.0f, 0); |
| _d3dDeviceEx->EndScene(); |
| |
| return DEVICE_PASS; |
| } |
| |
| void CD3D9ExWrapper::Destroy() |
| { |
| if (_d3dDeviceEx) _d3dDeviceEx->Release(); |
| _d3dDeviceEx = 0; |
| } |
| |
| TDeviceStatus CD3D9ExWrapper::Status() const { return _status; } |
| |
| bool CD3D9ExWrapper::AdapterNext() |
| { |
| if (DEVICE_FAIL == _status) return false; |
| |
| _adapterFound = false; |
| for (; _adapterIdx < _d3d9Ex->GetAdapterCount();) |
| { |
| ++_adapterIdx; |
| D3DCAPS9 caps; |
| if (FAILED( |
| _d3d9Ex->GetDeviceCaps(_adapterIdx - 1, D3DDEVTYPE_HAL, &caps))) |
| continue; |
| |
| if (FAILED( |
| _d3d9Ex->GetAdapterIdentifier(_adapterIdx - 1, 0, &_adapter))) |
| { |
| log_error("D3D9EX: GetAdapterIdentifier failed\n"); |
| _status = DEVICE_FAIL; |
| return false; |
| } |
| |
| _adapterFound = true; |
| Destroy(); |
| if (!Init()) |
| { |
| _status = DEVICE_FAIL; |
| _adapterFound = _status; |
| } |
| |
| break; |
| } |
| |
| return _adapterFound; |
| } |
| |
| unsigned int CD3D9ExWrapper::AdapterIdx() const { return _adapterIdx - 1; } |
| |
| CDXVAWrapper::CDXVAWrapper() |
| : _dxvaDevice(NULL), _status(DEVICE_PASS), _adapterFound(false) |
| { |
| _status = _d3d9.Status(); |
| } |
| |
| CDXVAWrapper::~CDXVAWrapper() { DXVAHDDestroy(); } |
| |
| void *CDXVAWrapper::Device() const { return _dxvaDevice; } |
| |
| TDeviceStatus CDXVAWrapper::Status() const |
| { |
| if (_status == DEVICE_FAIL || _d3d9.Status() == DEVICE_FAIL) |
| return DEVICE_FAIL; |
| else if (_status == DEVICE_NOTSUPPORTED |
| || _d3d9.Status() == DEVICE_NOTSUPPORTED) |
| return DEVICE_NOTSUPPORTED; |
| else |
| return DEVICE_PASS; |
| } |
| |
| bool CDXVAWrapper::AdapterNext() |
| { |
| if (DEVICE_PASS != _status) return false; |
| |
| _adapterFound = _d3d9.AdapterNext(); |
| _status = _d3d9.Status(); |
| if (DEVICE_PASS != _status) |
| { |
| _adapterFound = false; |
| return false; |
| } |
| |
| if (!_adapterFound) return false; |
| |
| DXVAHDDestroy(); |
| _status = DXVAHDInit(); |
| if (DEVICE_PASS != _status) |
| { |
| _adapterFound = false; |
| return false; |
| } |
| |
| return true; |
| } |
| |
| TDeviceStatus CDXVAWrapper::DXVAHDInit() |
| { |
| if ((_status == DEVICE_FAIL) || (_d3d9.Status() == DEVICE_FAIL) |
| || !_adapterFound) |
| return DEVICE_FAIL; |
| |
| DXVAHD_RATIONAL fps = { VIDEO_FPS, 1 }; |
| |
| DXVAHD_CONTENT_DESC desc; |
| desc.InputFrameFormat = DXVAHD_FRAME_FORMAT_PROGRESSIVE; |
| desc.InputFrameRate = fps; |
| desc.InputWidth = WindowWidth(); |
| desc.InputHeight = WindowHeight(); |
| desc.OutputFrameRate = fps; |
| desc.OutputWidth = WindowWidth(); |
| desc.OutputHeight = WindowHeight(); |
| |
| #ifdef USE_SOFTWARE_PLUGIN |
| _status = DEVICE_FAIL; |
| return DEVICE_FAIL; |
| #endif |
| |
| HRESULT hr = DXVAHD_CreateDevice( |
| static_cast<IDirect3DDevice9Ex *>(_d3d9.Device()), &desc, |
| DXVAHD_DEVICE_USAGE_PLAYBACK_NORMAL, NULL, &_dxvaDevice); |
| if (FAILED(hr)) |
| { |
| if (hr == E_NOINTERFACE) |
| { |
| log_error( |
| "DXVAHD_CreateDevice skipped due to no supported devices!\n"); |
| _status = DEVICE_NOTSUPPORTED; |
| } |
| else |
| { |
| log_error("DXVAHD_CreateDevice failed\n"); |
| _status = DEVICE_FAIL; |
| } |
| } |
| |
| return _status; |
| } |
| |
| void CDXVAWrapper::DXVAHDDestroy() |
| { |
| if (_dxvaDevice) _dxvaDevice->Release(); |
| _dxvaDevice = 0; |
| } |
| |
| void *CDXVAWrapper::D3D() const { return _d3d9.D3D(); } |
| |
| unsigned int CDXVAWrapper::AdapterIdx() const { return _d3d9.AdapterIdx(); } |
| |
| const CD3D9ExWrapper &CDXVAWrapper::D3D9() const { return _d3d9; } |
| |
| CD3D9SurfaceWrapper::CD3D9SurfaceWrapper(): mMem(NULL) {} |
| |
| CD3D9SurfaceWrapper::CD3D9SurfaceWrapper(IDirect3DSurface9 *mem): mMem(mem) {} |
| |
| CD3D9SurfaceWrapper::~CD3D9SurfaceWrapper() |
| { |
| if (mMem != NULL) mMem->Release(); |
| mMem = NULL; |
| } |
| |
| #endif |
| |
| CSurfaceWrapper::CSurfaceWrapper() {} |
| |
| CSurfaceWrapper::~CSurfaceWrapper() {} |