d3d8: Set the FPU control word on device creation.
This commit is contained in:
parent
e2cb88ec2d
commit
7d5666e084
|
@ -2764,6 +2764,19 @@ static const IWineD3DDeviceParentVtbl d3d8_wined3d_device_parent_vtbl =
|
||||||
device_parent_CreateSwapChain,
|
device_parent_CreateSwapChain,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void setup_fpu(void)
|
||||||
|
{
|
||||||
|
WORD cw;
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||||
|
__asm__ volatile ("fnstcw %0" : "=m" (cw));
|
||||||
|
cw = (cw & ~0xf3f) | 0x3f;
|
||||||
|
__asm__ volatile ("fldcw %0" : : "m" (cw));
|
||||||
|
#else
|
||||||
|
FIXME("FPU setup not implemented for this platform.\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT device_init(IDirect3DDevice8Impl *device, IWineD3D *wined3d, UINT adapter,
|
HRESULT device_init(IDirect3DDevice8Impl *device, IWineD3D *wined3d, UINT adapter,
|
||||||
D3DDEVTYPE device_type, HWND focus_window, DWORD flags, D3DPRESENT_PARAMETERS *parameters)
|
D3DDEVTYPE device_type, HWND focus_window, DWORD flags, D3DPRESENT_PARAMETERS *parameters)
|
||||||
{
|
{
|
||||||
|
@ -2782,6 +2795,8 @@ HRESULT device_init(IDirect3DDevice8Impl *device, IWineD3D *wined3d, UINT adapte
|
||||||
}
|
}
|
||||||
device->handle_table.table_size = D3D8_INITIAL_HANDLE_TABLE_SIZE;
|
device->handle_table.table_size = D3D8_INITIAL_HANDLE_TABLE_SIZE;
|
||||||
|
|
||||||
|
if (!(flags & D3DCREATE_FPU_PRESERVE)) setup_fpu();
|
||||||
|
|
||||||
wined3d_mutex_lock();
|
wined3d_mutex_lock();
|
||||||
hr = IWineD3D_CreateDevice(wined3d, adapter, device_type, focus_window, flags, (IUnknown *)device,
|
hr = IWineD3D_CreateDevice(wined3d, adapter, device_type, focus_window, flags, (IUnknown *)device,
|
||||||
(IWineD3DDeviceParent *)&device->device_parent_vtbl, &device->WineD3DDevice);
|
(IWineD3DDeviceParent *)&device->device_parent_vtbl, &device->WineD3DDevice);
|
||||||
|
|
|
@ -1797,6 +1797,89 @@ done:
|
||||||
UnregisterClassA("d3d8_test_wndproc_wc", GetModuleHandleA(NULL));
|
UnregisterClassA("d3d8_test_wndproc_wc", GetModuleHandleA(NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void set_fpu_cw(WORD cw)
|
||||||
|
{
|
||||||
|
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||||
|
__asm__ volatile ("fnclex");
|
||||||
|
__asm__ volatile ("fldcw %0" : : "m" (cw));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline WORD get_fpu_cw(void)
|
||||||
|
{
|
||||||
|
WORD cw = 0;
|
||||||
|
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||||
|
__asm__ volatile ("fnstcw %0" : "=m" (cw));
|
||||||
|
#endif
|
||||||
|
return cw;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_fpu_setup(void)
|
||||||
|
{
|
||||||
|
D3DPRESENT_PARAMETERS present_parameters;
|
||||||
|
IDirect3DDevice8 *device;
|
||||||
|
D3DDISPLAYMODE d3ddm;
|
||||||
|
HWND window = NULL;
|
||||||
|
IDirect3D8 *d3d8;
|
||||||
|
HRESULT hr;
|
||||||
|
WORD cw;
|
||||||
|
|
||||||
|
d3d8 = pDirect3DCreate8(D3D_SDK_VERSION);
|
||||||
|
ok(!!d3d8, "Failed to create a d3d8 object.\n");
|
||||||
|
if (!d3d8) return;
|
||||||
|
|
||||||
|
window = CreateWindowA("static", "d3d8_test", WS_CAPTION, 0, 0, 640, 480, 0, 0, 0, 0);
|
||||||
|
ok(!!window, "Failed to create a window.\n");
|
||||||
|
if (!window) goto done;
|
||||||
|
|
||||||
|
hr = IDirect3D8_GetAdapterDisplayMode(d3d8, D3DADAPTER_DEFAULT, &d3ddm);
|
||||||
|
ok(SUCCEEDED(hr), "GetAdapterDisplayMode failed, hr %#x.\n", hr);
|
||||||
|
|
||||||
|
memset(&present_parameters, 0, sizeof(present_parameters));
|
||||||
|
present_parameters.Windowed = TRUE;
|
||||||
|
present_parameters.hDeviceWindow = window;
|
||||||
|
present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||||
|
present_parameters.BackBufferFormat = d3ddm.Format;
|
||||||
|
|
||||||
|
set_fpu_cw(0xf60);
|
||||||
|
cw = get_fpu_cw();
|
||||||
|
ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
|
||||||
|
|
||||||
|
hr = IDirect3D8_CreateDevice(d3d8, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
|
||||||
|
D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
skip("Failed to create a device, hr %#x.\n", hr);
|
||||||
|
set_fpu_cw(0x37f);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
cw = get_fpu_cw();
|
||||||
|
ok(cw == 0x7f, "cw is %#x, expected 0x7f.\n", cw);
|
||||||
|
|
||||||
|
IDirect3DDevice8_Release(device);
|
||||||
|
|
||||||
|
cw = get_fpu_cw();
|
||||||
|
ok(cw == 0x7f, "cw is %#x, expected 0x7f.\n", cw);
|
||||||
|
set_fpu_cw(0xf60);
|
||||||
|
cw = get_fpu_cw();
|
||||||
|
ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
|
||||||
|
|
||||||
|
hr = IDirect3D8_CreateDevice(d3d8, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
|
||||||
|
D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, &present_parameters, &device);
|
||||||
|
ok(SUCCEEDED(hr), "CreateDevice failed, hr %#x.\n", hr);
|
||||||
|
|
||||||
|
cw = get_fpu_cw();
|
||||||
|
ok(cw == 0xf60, "cw is %#x, expected 0xf60.\n", cw);
|
||||||
|
set_fpu_cw(0x37f);
|
||||||
|
|
||||||
|
IDirect3DDevice8_Release(device);
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (window) DestroyWindow(window);
|
||||||
|
if (d3d8) IDirect3D8_Release(d3d8);
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(device)
|
START_TEST(device)
|
||||||
{
|
{
|
||||||
HMODULE d3d8_handle = LoadLibraryA( "d3d8.dll" );
|
HMODULE d3d8_handle = LoadLibraryA( "d3d8.dll" );
|
||||||
|
@ -1819,6 +1902,9 @@ START_TEST(device)
|
||||||
}
|
}
|
||||||
IDirect3D8_Release(d3d8);
|
IDirect3D8_Release(d3d8);
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||||
|
test_fpu_setup();
|
||||||
|
#endif
|
||||||
test_display_modes();
|
test_display_modes();
|
||||||
test_shader_versions();
|
test_shader_versions();
|
||||||
test_swapchain();
|
test_swapchain();
|
||||||
|
|
Loading…
Reference in New Issue