Commit d30f1527 authored by Stefan Dösinger's avatar Stefan Dösinger Committed by Alexandre Julliard

wined3d: Implement IWineD3DDevice::Reset.

parent ccf078c1
......@@ -687,6 +687,150 @@ static void test_cursor(void)
ok(info.hCursor == cur, "The cursor handle is %p\n", info.hCursor); /* unchanged */
cleanup:
if(pDevice) IDirect3D9_Release(pDevice);
if(pD3d) IDirect3D9_Release(pD3d);
DestroyWindow( hwnd );
}
static void test_reset(void)
{
HRESULT hr;
HWND hwnd = NULL;
IDirect3D9 *pD3d = NULL;
IDirect3DDevice9 *pDevice = NULL;
D3DPRESENT_PARAMETERS d3dpp;
D3DDISPLAYMODE d3ddm;
D3DVIEWPORT9 vp;
DWORD width, orig_width = GetSystemMetrics(SM_CXSCREEN);
DWORD height, orig_height = GetSystemMetrics(SM_CYSCREEN);
IDirect3DSwapChain9 *pSwapchain;
pD3d = pDirect3DCreate9( D3D_SDK_VERSION );
ok(pD3d != NULL, "Failed to create IDirect3D9 object\n");
hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
ok(hwnd != NULL, "Failed to create window\n");
if (!pD3d || !hwnd) goto cleanup;
IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm );
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed = FALSE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferWidth = 800;
d3dpp.BackBufferHeight = 600;
d3dpp.BackBufferFormat = d3ddm.Format;
hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
ok(SUCCEEDED(hr), "Failed to create IDirect3D9Device (%s)\n", DXGetErrorString9(hr));
if (FAILED(hr)) goto cleanup;
width = GetSystemMetrics(SM_CXSCREEN);
height = GetSystemMetrics(SM_CYSCREEN);
ok(width == 800, "Screen width is %d\n", width);
ok(height == 600, "Screen height is %d\n", height);
hr = IDirect3DDevice9_GetViewport(pDevice, &vp);
ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %s\n", DXGetErrorString9(hr));
if(SUCCEEDED(hr))
{
ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
ok(vp.Y == 0, "D3DVIEWPORT->X = %d\n", vp.Y);
ok(vp.Width == 800, "D3DVIEWPORT->X = %d\n", vp.Width);
ok(vp.Height == 600, "D3DVIEWPORT->X = %d\n", vp.Height);
ok(vp.MinZ == 0, "D3DVIEWPORT->X = %d\n", vp.Height);
ok(vp.MaxZ == 1, "D3DVIEWPORT->X = %d\n", vp.Height);
}
vp.X = 10;
vp.X = 20;
vp.MinZ = 2;
vp.MaxZ = 3;
hr = IDirect3DDevice9_SetViewport(pDevice, &vp);
ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %s\n", DXGetErrorString9(hr));
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.Windowed = FALSE;
d3dpp.BackBufferWidth = 640;
d3dpp.BackBufferHeight = 480;
d3dpp.BackBufferFormat = d3ddm.Format;
hr = IDirect3DDevice9_Reset(pDevice, &d3dpp);
ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %s\n", DXGetErrorString9(hr));
ZeroMemory(&vp, sizeof(vp));
hr = IDirect3DDevice9_GetViewport(pDevice, &vp);
ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %s\n", DXGetErrorString9(hr));
if(SUCCEEDED(hr))
{
ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
ok(vp.Y == 0, "D3DVIEWPORT->X = %d\n", vp.Y);
ok(vp.Width == 640, "D3DVIEWPORT->X = %d\n", vp.Width);
ok(vp.Height == 480, "D3DVIEWPORT->X = %d\n", vp.Height);
ok(vp.MinZ == 0, "D3DVIEWPORT->X = %d\n", vp.Height);
ok(vp.MaxZ == 1, "D3DVIEWPORT->X = %d\n", vp.Height);
}
width = GetSystemMetrics(SM_CXSCREEN);
height = GetSystemMetrics(SM_CYSCREEN);
ok(width == 640, "Screen width is %d\n", width);
ok(height == 480, "Screen height is %d\n", height);
hr = IDirect3DDevice9_GetSwapChain(pDevice, 0, &pSwapchain);
ok(hr == D3D_OK, "IDirect3DDevice9_GetSwapChain returned %s\n", DXGetErrorString9(hr));
if(SUCCEEDED(hr))
{
ZeroMemory(&d3dpp, sizeof(d3dpp));
hr = IDirect3DSwapChain9_GetPresentParameters(pSwapchain, &d3dpp);
ok(hr == D3D_OK, "IDirect3DSwapChain9_GetPresentParameters returned %s\n", DXGetErrorString9(hr));
if(SUCCEEDED(hr))
{
ok(d3dpp.BackBufferWidth == 640, "Back buffer width is %d\n", d3dpp.BackBufferWidth);
ok(d3dpp.BackBufferHeight == 480, "Back buffer height is %d\n", d3dpp.BackBufferHeight);
}
IDirect3DSwapChain9_Release(pSwapchain);
}
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.Windowed = TRUE;
d3dpp.BackBufferWidth = 400;
d3dpp.BackBufferHeight = 300;
hr = IDirect3DDevice9_Reset(pDevice, &d3dpp);
ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %s\n", DXGetErrorString9(hr));
width = GetSystemMetrics(SM_CXSCREEN);
height = GetSystemMetrics(SM_CYSCREEN);
ok(width == orig_width, "Screen width is %d\n", width);
ok(height == orig_height, "Screen height is %d\n", height);
ZeroMemory(&vp, sizeof(vp));
hr = IDirect3DDevice9_GetViewport(pDevice, &vp);
ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %s\n", DXGetErrorString9(hr));
if(SUCCEEDED(hr))
{
ok(vp.X == 0, "D3DVIEWPORT->X = %d\n", vp.X);
ok(vp.Y == 0, "D3DVIEWPORT->X = %d\n", vp.Y);
ok(vp.Width == 400, "D3DVIEWPORT->X = %d\n", vp.Width);
ok(vp.Height == 300, "D3DVIEWPORT->X = %d\n", vp.Height);
ok(vp.MinZ == 0, "D3DVIEWPORT->X = %d\n", vp.Height);
ok(vp.MaxZ == 1, "D3DVIEWPORT->X = %d\n", vp.Height);
}
hr = IDirect3DDevice9_GetSwapChain(pDevice, 0, &pSwapchain);
ok(hr == D3D_OK, "IDirect3DDevice9_GetSwapChain returned %s\n", DXGetErrorString9(hr));
if(SUCCEEDED(hr))
{
ZeroMemory(&d3dpp, sizeof(d3dpp));
hr = IDirect3DSwapChain9_GetPresentParameters(pSwapchain, &d3dpp);
ok(hr == D3D_OK, "IDirect3DSwapChain9_GetPresentParameters returned %s\n", DXGetErrorString9(hr));
if(SUCCEEDED(hr))
{
ok(d3dpp.BackBufferWidth == 400, "Back buffer width is %d\n", d3dpp.BackBufferWidth);
ok(d3dpp.BackBufferHeight == 300, "Back buffer height is %d\n", d3dpp.BackBufferHeight);
}
IDirect3DSwapChain9_Release(pSwapchain);
}
cleanup:
if(pD3d) IDirect3D9_Release(pD3d);
if(pDevice) IDirect3D9_Release(pDevice);
}
......@@ -702,5 +846,6 @@ START_TEST(device)
test_refcount();
test_mipmap_levels();
test_cursor();
test_reset();
}
}
......@@ -1538,6 +1538,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevic
WARN("Failed to get a valid XVisuial ID for the window %p\n", object->win_handle);
return WINED3DERR_NOTAVAILABLE;
}
object->orig_width = GetSystemMetrics(SM_CXSCREEN);
object->orig_height = GetSystemMetrics(SM_CYSCREEN);
/**
* Create an opengl context for the display visual
* NOTE: the visual is chosen as the window is created and the glcontext cannot
......@@ -7514,14 +7518,152 @@ static HRESULT WINAPI IWineD3DDeviceImpl_EvictManagedResources(IWineD3DDevice*
return WINED3D_OK;
}
void updateSurfaceDesc(IWineD3DSurfaceImpl *surface, WINED3DPRESENT_PARAMETERS* pPresentationParameters) {
/* Reallocate proper memory for the front and back buffer and adjust their sizes */
if(surface->Flags & SFLAG_DIBSECTION) {
/* Release the DC */
SelectObject(surface->hDC, surface->dib.holdbitmap);
DeleteDC(surface->hDC);
/* Release the DIB section */
DeleteObject(surface->dib.DIBsection);
surface->dib.bitmap_data = NULL;
surface->resource.allocatedMemory = NULL;
surface->Flags &= ~SFLAG_DIBSECTION;
}
surface->currentDesc.Width = *pPresentationParameters->BackBufferWidth;
surface->currentDesc.Height = *pPresentationParameters->BackBufferHeight;
if (wined3d_settings.nonpower2_mode == NP2_NATIVE) {
surface->pow2Width = *pPresentationParameters->BackBufferWidth;
surface->pow2Height = *pPresentationParameters->BackBufferHeight;
} else {
surface->pow2Width = surface->pow2Height = 1;
while (surface->pow2Width < *pPresentationParameters->BackBufferWidth) surface->pow2Width <<= 1;
while (surface->pow2Height < *pPresentationParameters->BackBufferHeight) surface->pow2Height <<= 1;
}
if(surface->glDescription.textureName) {
ENTER_GL();
glDeleteTextures(1, &surface->glDescription.textureName);
LEAVE_GL();
surface->glDescription.textureName = 0;
}
if(surface->pow2Width != *pPresentationParameters->BackBufferWidth ||
surface->pow2Height != *pPresentationParameters->BackBufferHeight) {
surface->Flags |= SFLAG_NONPOW2;
} else {
surface->Flags &= ~SFLAG_NONPOW2;
}
HeapFree(GetProcessHeap(), 0, surface->resource.allocatedMemory);
surface->resource.size = IWineD3DSurface_GetPitch((IWineD3DSurface *) surface) * surface->pow2Width;
}
static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRESENT_PARAMETERS* pPresentationParameters) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
/** FIXME: Resource trascking needs to be done.
* in effect this pulls all non only default
* textures out of video memory and deletes all glTextures (glDeleteTextures)
* and should clear down the context and set it up according to pPresentationParameters
***********************************************************/
FIXME("(%p) : stub\n", This);
IWineD3DSwapChainImpl *swapchain;
HRESULT hr;
BOOL DisplayModeChanged = FALSE;
WINED3DDISPLAYMODE mode;
TRACE("(%p)\n", This);
hr = IWineD3DDevice_GetSwapChain(iface, 0, (IWineD3DSwapChain **) &swapchain);
if(FAILED(hr)) {
ERR("Failed to get the first implicit swapchain\n");
return hr;
}
/* Is it necessary to recreate the gl context? Actually every setting can be changed
* on an existing gl context, so there's no real need for recreation.
*
* TODO: Figure out how Reset influences resources in D3DPOOL_DEFAULT, D3DPOOL_SYSTEMMEMORY and D3DPOOL_MANAGED
*
* TODO: Figure out what happens to explicit swapchains, or if we have more than one implicit swapchain
*/
TRACE("New params:\n");
TRACE("BackBufferWidth = %d\n", *pPresentationParameters->BackBufferWidth);
TRACE("BackBufferHeight = %d\n", *pPresentationParameters->BackBufferHeight);
TRACE("BackBufferFormat = %s\n", debug_d3dformat(*pPresentationParameters->BackBufferFormat));
TRACE("BackBufferCount = %d\n", *pPresentationParameters->BackBufferCount);
TRACE("MultiSampleType = %d\n", *pPresentationParameters->MultiSampleType);
TRACE("MultiSampleQuality = %d\n", *pPresentationParameters->MultiSampleQuality);
TRACE("SwapEffect = %d\n", *pPresentationParameters->SwapEffect);
TRACE("hDeviceWindow = %p\n", *pPresentationParameters->hDeviceWindow);
TRACE("Windowed = %s\n", *pPresentationParameters->Windowed ? "true" : "false");
TRACE("EnableAutoDepthStencil = %s\n", *pPresentationParameters->EnableAutoDepthStencil ? "true" : "false");
TRACE("Flags = %08x\n", *pPresentationParameters->Flags);
TRACE("FullScreen_RefreshRateInHz = %d\n", *pPresentationParameters->FullScreen_RefreshRateInHz);
TRACE("PresentationInterval = %d\n", *pPresentationParameters->PresentationInterval);
/* No special treatment of these parameters. Just store them */
swapchain->presentParms.SwapEffect = *pPresentationParameters->SwapEffect;
swapchain->presentParms.Flags = *pPresentationParameters->Flags;
swapchain->presentParms.PresentationInterval = *pPresentationParameters->PresentationInterval;
swapchain->presentParms.FullScreen_RefreshRateInHz = *pPresentationParameters->FullScreen_RefreshRateInHz;
/* What to do about these? */
if(*pPresentationParameters->BackBufferCount != 0 &&
*pPresentationParameters->BackBufferCount != swapchain->presentParms.BackBufferCount) {
ERR("Cannot change the back buffer count yet\n");
}
if(*pPresentationParameters->BackBufferFormat != WINED3DFMT_UNKNOWN &&
*pPresentationParameters->BackBufferFormat != swapchain->presentParms.BackBufferFormat) {
ERR("Cannot change the back buffer format yet\n");
}
if(*pPresentationParameters->hDeviceWindow != NULL &&
*pPresentationParameters->hDeviceWindow != swapchain->presentParms.hDeviceWindow) {
ERR("Cannot change the device window yet\n");
}
if(*pPresentationParameters->EnableAutoDepthStencil != swapchain->presentParms.EnableAutoDepthStencil) {
ERR("What do do about a changed auto depth stencil parameter?\n");
}
if(*pPresentationParameters->Windowed) {
mode.Width = swapchain->orig_width;
mode.Height = swapchain->orig_height;
mode.RefreshRate = 0;
mode.Format = swapchain->presentParms.BackBufferFormat;
} else {
mode.Width = *pPresentationParameters->BackBufferWidth;
mode.Height = *pPresentationParameters->BackBufferHeight;
mode.RefreshRate = *pPresentationParameters->FullScreen_RefreshRateInHz;
mode.Format = swapchain->presentParms.BackBufferFormat;
}
/* Should Width == 800 && Height == 0 set 800x600? */
if(*pPresentationParameters->BackBufferWidth != 0 && *pPresentationParameters->BackBufferHeight != 0 &&
(*pPresentationParameters->BackBufferWidth != swapchain->presentParms.BackBufferWidth ||
*pPresentationParameters->BackBufferHeight != swapchain->presentParms.BackBufferHeight))
{
WINED3DVIEWPORT vp;
int i;
vp.X = 0;
vp.Y = 0;
vp.Width = *pPresentationParameters->BackBufferWidth;
vp.Height = *pPresentationParameters->BackBufferHeight;
vp.MinZ = 0;
vp.MaxZ = 1;
if(!*pPresentationParameters->Windowed) {
DisplayModeChanged = TRUE;
}
swapchain->presentParms.BackBufferWidth = *pPresentationParameters->BackBufferWidth;
swapchain->presentParms.BackBufferHeight = *pPresentationParameters->BackBufferHeight;
updateSurfaceDesc((IWineD3DSurfaceImpl *)swapchain->frontBuffer, pPresentationParameters);
for(i = 0; i < swapchain->presentParms.BackBufferCount; i++) {
updateSurfaceDesc((IWineD3DSurfaceImpl *)swapchain->backBuffer[i], pPresentationParameters);
}
/* Now set the new viewport */
IWineD3DDevice_SetViewport(iface, &vp);
}
if((*pPresentationParameters->Windowed && !swapchain->presentParms.Windowed) ||
(swapchain->presentParms.Windowed && !*pPresentationParameters->Windowed) ||
DisplayModeChanged) {
IWineD3DDevice_SetDisplayMode(iface, 0, &mode);
}
IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
return WINED3D_OK;
}
......
......@@ -1257,6 +1257,7 @@ typedef struct IWineD3DSwapChainImpl
IWineD3DSurface *frontBuffer;
BOOL wantsDepthStencilBuffer;
D3DPRESENT_PARAMETERS presentParms;
DWORD orig_width, orig_height;
/* TODO: move everything up to drawable off into a context manager
and store the 'data' in the contextManagerData interface.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment