563 lines
11 KiB
C++
563 lines
11 KiB
C++
//
|
|
// 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()
|
|
{
|
|
|
|
}
|