wined3d: Add a separate function for swapchain initialization.

This commit is contained in:
Henri Verbeet 2009-12-10 21:41:54 +01:00 committed by Alexandre Julliard
parent 75ef50e435
commit a9f2613d13
3 changed files with 303 additions and 305 deletions

View File

@ -951,9 +951,8 @@ static LONG fullscreen_exStyle(LONG orig_exStyle) {
return exStyle;
}
static void IWineD3DDeviceImpl_SetupFullscreenWindow(IWineD3DDevice *iface, HWND window, UINT w, UINT h) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
void IWineD3DDeviceImpl_SetupFullscreenWindow(IWineD3DDeviceImpl *This, HWND window, UINT w, UINT h)
{
LONG style, exStyle;
/* Don't do anything if an original style is stored.
* That shouldn't happen
@ -1030,314 +1029,36 @@ static void IWineD3DDeviceImpl_RestoreWindow(IWineD3DDevice *iface, HWND window)
SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);
}
/* example at http://www.fairyengine.com/articles/dxmultiviews.htm */
static HRESULT WINAPI IWineD3DDeviceImpl_CreateSwapChain(IWineD3DDevice *iface,
WINED3DPRESENT_PARAMETERS *pPresentationParameters, IWineD3DSwapChain **ppSwapChain,
WINED3DPRESENT_PARAMETERS *present_parameters, IWineD3DSwapChain **swapchain,
IUnknown *parent, WINED3DSURFTYPE surface_type)
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
IWineD3DSwapChainImpl *object;
HRESULT hr;
HDC hDc;
IWineD3DSwapChainImpl *object; /** NOTE: impl ref allowed since this is a create function **/
HRESULT hr;
BOOL displaymode_set = FALSE;
WINED3DDISPLAYMODE Mode;
const struct GlPixelFormatDesc *format_desc;
RECT client_rect;
TRACE("(%p) : Created Additional Swap Chain\n", This);
/** FIXME: Test under windows to find out what the life cycle of a swap chain is,
* does a device hold a reference to a swap chain giving them a lifetime of the device
* or does the swap chain notify the device of its destruction.
*******************************/
/* Check the params */
if(pPresentationParameters->BackBufferCount > WINED3DPRESENT_BACK_BUFFER_MAX) {
ERR("App requested %d back buffers, this is not supported for now\n", pPresentationParameters->BackBufferCount);
return WINED3DERR_INVALIDCALL;
} else if (pPresentationParameters->BackBufferCount > 1) {
FIXME("The app requests more than one back buffer, this can't be supported properly. Please configure the application to use double buffering(=1 back buffer) if possible\n");
}
TRACE("iface %p, present_parameters %p, swapchain %p, parent %p, surface_type %#x.\n",
iface, present_parameters, swapchain, parent, surface_type);
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
if(!object)
if (!object)
{
ERR("Out of memory\n");
*ppSwapChain = NULL;
return WINED3DERR_OUTOFVIDEOMEMORY;
ERR("Failed to allocate swapchain memory.\n");
return E_OUTOFMEMORY;
}
switch(surface_type) {
case SURFACE_GDI:
object->lpVtbl = &IWineGDISwapChain_Vtbl;
break;
case SURFACE_OPENGL:
object->lpVtbl = &IWineD3DSwapChain_Vtbl;
break;
case SURFACE_UNKNOWN:
FIXME("Caller tried to create a SURFACE_UNKNOWN swapchain\n");
HeapFree(GetProcessHeap(), 0, object);
return WINED3DERR_INVALIDCALL;
}
object->device = This;
object->parent = parent;
object->ref = 1;
*ppSwapChain = (IWineD3DSwapChain *)object;
/*********************
* Lookup the window Handle and the relating X window handle
********************/
/* Setup hwnd we are using, plus which display this equates to */
object->win_handle = pPresentationParameters->hDeviceWindow;
if (!object->win_handle) {
object->win_handle = This->createParms.hFocusWindow;
}
if(!pPresentationParameters->Windowed && object->win_handle) {
IWineD3DDeviceImpl_SetupFullscreenWindow(iface, object->win_handle,
pPresentationParameters->BackBufferWidth,
pPresentationParameters->BackBufferHeight);
}
hDc = GetDC(object->win_handle);
TRACE("Using hDc %p\n", hDc);
if (NULL == hDc) {
WARN("Failed to get a HDc for Window %p\n", object->win_handle);
return WINED3DERR_NOTAVAILABLE;
}
/* Get info on the current display setup */
IWineD3D_GetAdapterDisplayMode(This->wined3d, This->adapter->ordinal, &Mode);
object->orig_width = Mode.Width;
object->orig_height = Mode.Height;
object->orig_fmt = Mode.Format;
format_desc = getFormatDescEntry(Mode.Format, &This->adapter->gl_info);
GetClientRect(object->win_handle, &client_rect);
if (pPresentationParameters->Windowed &&
((pPresentationParameters->BackBufferWidth == 0) ||
(pPresentationParameters->BackBufferHeight == 0) ||
(pPresentationParameters->BackBufferFormat == WINED3DFMT_UNKNOWN))) {
if (pPresentationParameters->BackBufferWidth == 0) {
pPresentationParameters->BackBufferWidth = client_rect.right;
TRACE("Updating width to %d\n", pPresentationParameters->BackBufferWidth);
}
if (pPresentationParameters->BackBufferHeight == 0) {
pPresentationParameters->BackBufferHeight = client_rect.bottom;
TRACE("Updating height to %d\n", pPresentationParameters->BackBufferHeight);
}
if (pPresentationParameters->BackBufferFormat == WINED3DFMT_UNKNOWN) {
pPresentationParameters->BackBufferFormat = object->orig_fmt;
TRACE("Updating format to %s\n", debug_d3dformat(object->orig_fmt));
}
}
if(wined3d_settings.offscreen_rendering_mode == ORM_FBO)
hr = swapchain_init(object, surface_type, This, present_parameters, parent);
if (FAILED(hr))
{
if(pPresentationParameters->BackBufferWidth != client_rect.right ||
pPresentationParameters->BackBufferHeight != client_rect.bottom)
{
TRACE("Rendering to FBO. Backbuffer %ux%u, window %ux%u\n",
pPresentationParameters->BackBufferWidth,
pPresentationParameters->BackBufferHeight,
client_rect.right, client_rect.bottom);
object->render_to_fbo = TRUE;
}
else
{
TRACE("Rendering directly to GL_BACK\n");
}
WARN("Failed to initialize swapchain, hr %#x.\n", hr);
HeapFree(GetProcessHeap(), 0, object);
return hr;
}
/* Put the correct figures in the presentation parameters */
TRACE("Copying across presentation parameters\n");
object->presentParms = *pPresentationParameters;
TRACE("Created swapchain %p.\n", object);
*swapchain = (IWineD3DSwapChain *)object;
TRACE("calling rendertarget CB\n");
hr = IWineD3DDeviceParent_CreateRenderTarget(This->device_parent, parent,
object->presentParms.BackBufferWidth, object->presentParms.BackBufferHeight,
object->presentParms.BackBufferFormat, object->presentParms.MultiSampleType,
object->presentParms.MultiSampleQuality, TRUE /* Lockable */, &object->frontBuffer);
if (SUCCEEDED(hr)) {
IWineD3DSurface_SetContainer(object->frontBuffer, (IWineD3DBase *)object);
((IWineD3DSurfaceImpl *)object->frontBuffer)->Flags |= SFLAG_SWAPCHAIN;
if(surface_type == SURFACE_OPENGL) {
IWineD3DSurface_ModifyLocation(object->frontBuffer, SFLAG_INDRAWABLE, TRUE);
}
} else {
ERR("Failed to create the front buffer\n");
goto error;
}
/*********************
* Windowed / Fullscreen
*******************/
/**
* TODO: MSDN says that we are only allowed one fullscreen swapchain per device,
* so we should really check to see if there is a fullscreen swapchain already
* I think Windows and X have different ideas about fullscreen, does a single head count as full screen?
**************************************/
if (!pPresentationParameters->Windowed) {
WINED3DDISPLAYMODE mode;
/* Change the display settings */
mode.Width = pPresentationParameters->BackBufferWidth;
mode.Height = pPresentationParameters->BackBufferHeight;
mode.Format = pPresentationParameters->BackBufferFormat;
mode.RefreshRate = pPresentationParameters->FullScreen_RefreshRateInHz;
IWineD3DDevice_SetDisplayMode(iface, 0, &mode);
displaymode_set = TRUE;
}
/**
* Create an opengl context for the display visual
* NOTE: the visual is chosen as the window is created and the glcontext cannot
* use different properties after that point in time. FIXME: How to handle when requested format
* doesn't match actual visual? Cannot choose one here - code removed as it ONLY works if the one
* it chooses is identical to the one already being used!
**********************************/
/** FIXME: Handle stencil appropriately via EnableAutoDepthStencil / AutoDepthStencilFormat **/
object->context = HeapAlloc(GetProcessHeap(), 0, sizeof(object->context));
if(!object->context) {
ERR("Failed to create the context array\n");
hr = E_OUTOFMEMORY;
goto error;
}
object->num_contexts = 1;
if (surface_type == SURFACE_OPENGL)
{
object->context[0] = context_create(This, (IWineD3DSurfaceImpl *)object->frontBuffer,
object->win_handle, FALSE /* pbuffer */, pPresentationParameters);
if (!object->context[0]) {
ERR("Failed to create a new context\n");
hr = WINED3DERR_NOTAVAILABLE;
goto error;
} else {
TRACE("Context created (HWND=%p, glContext=%p)\n",
object->win_handle, object->context[0]->glCtx);
}
object->context[0]->render_offscreen = object->render_to_fbo;
}
else
{
object->context[0] = NULL;
}
/*********************
* Create the back, front and stencil buffers
*******************/
if(object->presentParms.BackBufferCount > 0) {
UINT i;
object->backBuffer = HeapAlloc(GetProcessHeap(), 0, sizeof(IWineD3DSurface *) * object->presentParms.BackBufferCount);
if(!object->backBuffer) {
ERR("Out of memory\n");
hr = E_OUTOFMEMORY;
goto error;
}
for(i = 0; i < object->presentParms.BackBufferCount; i++) {
TRACE("calling rendertarget CB\n");
hr = IWineD3DDeviceParent_CreateRenderTarget(This->device_parent, parent,
object->presentParms.BackBufferWidth, object->presentParms.BackBufferHeight,
object->presentParms.BackBufferFormat, object->presentParms.MultiSampleType,
object->presentParms.MultiSampleQuality, TRUE /* Lockable */, &object->backBuffer[i]);
if(SUCCEEDED(hr)) {
IWineD3DSurface_SetContainer(object->backBuffer[i], (IWineD3DBase *)object);
((IWineD3DSurfaceImpl *)object->backBuffer[i])->Flags |= SFLAG_SWAPCHAIN;
} else {
ERR("Cannot create new back buffer\n");
goto error;
}
if(surface_type == SURFACE_OPENGL) {
ENTER_GL();
glDrawBuffer(GL_BACK);
checkGLcall("glDrawBuffer(GL_BACK)");
LEAVE_GL();
}
}
} else {
object->backBuffer = NULL;
/* Single buffering - draw to front buffer */
if(surface_type == SURFACE_OPENGL) {
ENTER_GL();
glDrawBuffer(GL_FRONT);
checkGLcall("glDrawBuffer(GL_FRONT)");
LEAVE_GL();
}
}
if (object->context[0]) context_release(object->context[0]);
/* Under directX swapchains share the depth stencil, so only create one depth-stencil */
if (pPresentationParameters->EnableAutoDepthStencil && surface_type == SURFACE_OPENGL) {
TRACE("Creating depth stencil buffer\n");
if (This->auto_depth_stencil_buffer == NULL ) {
hr = IWineD3DDeviceParent_CreateDepthStencilSurface(This->device_parent, parent,
object->presentParms.BackBufferWidth, object->presentParms.BackBufferHeight,
object->presentParms.AutoDepthStencilFormat, object->presentParms.MultiSampleType,
object->presentParms.MultiSampleQuality, FALSE /* FIXME: Discard */,
&This->auto_depth_stencil_buffer);
if (SUCCEEDED(hr)) {
IWineD3DSurface_SetContainer(This->auto_depth_stencil_buffer, 0);
} else {
ERR("Failed to create the auto depth stencil\n");
goto error;
}
}
}
IWineD3DSwapChain_GetGammaRamp((IWineD3DSwapChain *) object, &object->orig_gamma);
TRACE("Created swapchain %p\n", object);
TRACE("FrontBuf @ %p, BackBuf @ %p, DepthStencil %d\n",object->frontBuffer, object->backBuffer ? object->backBuffer[0] : NULL, pPresentationParameters->EnableAutoDepthStencil);
return WINED3D_OK;
error:
if (displaymode_set) {
DEVMODEW devmode;
RECT clip_rc;
SetRect(&clip_rc, 0, 0, object->orig_width, object->orig_height);
ClipCursor(NULL);
/* Change the display settings */
memset(&devmode, 0, sizeof(devmode));
devmode.dmSize = sizeof(devmode);
devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
devmode.dmBitsPerPel = format_desc->byte_count * 8;
devmode.dmPelsWidth = object->orig_width;
devmode.dmPelsHeight = object->orig_height;
ChangeDisplaySettingsExW(This->adapter->DeviceName, &devmode, NULL, CDS_FULLSCREEN, NULL);
}
if (object->backBuffer) {
UINT i;
for(i = 0; i < object->presentParms.BackBufferCount; i++) {
if (object->backBuffer[i]) IWineD3DSurface_Release(object->backBuffer[i]);
}
HeapFree(GetProcessHeap(), 0, object->backBuffer);
object->backBuffer = NULL;
}
if(object->context && object->context[0])
{
context_release(object->context[0]);
context_destroy(This, object->context[0]);
}
if (object->frontBuffer) IWineD3DSurface_Release(object->frontBuffer);
HeapFree(GetProcessHeap(), 0, object);
return hr;
}
/** NOTE: These are ahead of the other getters and setters to save using a forward declaration **/
@ -6880,9 +6601,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE
if(swapchain->win_handle && !pPresentationParameters->Windowed) {
if(swapchain->presentParms.Windowed) {
/* switch from windowed to fs */
IWineD3DDeviceImpl_SetupFullscreenWindow(iface, swapchain->win_handle,
pPresentationParameters->BackBufferWidth,
pPresentationParameters->BackBufferHeight);
IWineD3DDeviceImpl_SetupFullscreenWindow(This, swapchain->win_handle,
pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight);
} else {
/* Fullscreen -> fullscreen mode change */
MoveWindow(swapchain->win_handle, 0, 0,
@ -6902,9 +6622,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE
*/
This->style = 0;
This->exStyle = 0;
IWineD3DDeviceImpl_SetupFullscreenWindow(iface, swapchain->win_handle,
pPresentationParameters->BackBufferWidth,
pPresentationParameters->BackBufferHeight);
IWineD3DDeviceImpl_SetupFullscreenWindow(This, swapchain->win_handle,
pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight);
This->style = style;
This->exStyle = exStyle;
}

View File

@ -536,7 +536,7 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_SetDestWindowOverride(IWineD3DSwapCh
return WINED3D_OK;
}
const IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl =
static const IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl =
{
/* IUnknown */
IWineD3DBaseSwapChainImpl_QueryInterface,
@ -557,6 +557,282 @@ const IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl =
IWineD3DBaseSwapChainImpl_GetGammaRamp
};
HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface_type,
IWineD3DDeviceImpl *device, WINED3DPRESENT_PARAMETERS *present_parameters, IUnknown *parent)
{
const struct wined3d_adapter *adapter = device->adapter;
const struct GlPixelFormatDesc *format_desc;
BOOL displaymode_set = FALSE;
WINED3DDISPLAYMODE mode;
RECT client_rect;
HWND window;
HRESULT hr;
UINT i;
if (present_parameters->BackBufferCount > WINED3DPRESENT_BACK_BUFFER_MAX)
{
FIXME("The application requested %u back buffers, this is not supported.\n",
present_parameters->BackBufferCount);
return WINED3DERR_INVALIDCALL;
}
if (present_parameters->BackBufferCount > 1)
{
FIXME("The application requested more than one back buffer, this is not properly supported.\n"
"Please configure the application to use double buffering (1 back buffer) if possible.\n");
}
switch (surface_type)
{
case SURFACE_GDI:
swapchain->lpVtbl = &IWineGDISwapChain_Vtbl;
break;
case SURFACE_OPENGL:
swapchain->lpVtbl = &IWineD3DSwapChain_Vtbl;
break;
case SURFACE_UNKNOWN:
FIXME("Caller tried to create a SURFACE_UNKNOWN swapchain.\n");
return WINED3DERR_INVALIDCALL;
}
window = present_parameters->hDeviceWindow ? present_parameters->hDeviceWindow : device->createParms.hFocusWindow;
swapchain->device = device;
swapchain->parent = parent;
swapchain->ref = 1;
swapchain->win_handle = window;
if (!present_parameters->Windowed && window)
{
IWineD3DDeviceImpl_SetupFullscreenWindow(device, window, present_parameters->BackBufferWidth,
present_parameters->BackBufferHeight);
}
IWineD3D_GetAdapterDisplayMode(device->wined3d, adapter->ordinal, &mode);
swapchain->orig_width = mode.Width;
swapchain->orig_height = mode.Height;
swapchain->orig_fmt = mode.Format;
format_desc = getFormatDescEntry(mode.Format, &adapter->gl_info);
GetClientRect(window, &client_rect);
if (present_parameters->Windowed
&& (!present_parameters->BackBufferWidth || !present_parameters->BackBufferHeight
|| present_parameters->BackBufferFormat == WINED3DFMT_UNKNOWN))
{
if (!present_parameters->BackBufferWidth)
{
present_parameters->BackBufferWidth = client_rect.right;
TRACE("Updating width to %u.\n", present_parameters->BackBufferWidth);
}
if (!present_parameters->BackBufferHeight)
{
present_parameters->BackBufferHeight = client_rect.bottom;
TRACE("Updating height to %u.\n", present_parameters->BackBufferHeight);
}
if (present_parameters->BackBufferFormat == WINED3DFMT_UNKNOWN)
{
present_parameters->BackBufferFormat = swapchain->orig_fmt;
TRACE("Updating format to %s.\n", debug_d3dformat(swapchain->orig_fmt));
}
}
swapchain->presentParms = *present_parameters;
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO
&& (present_parameters->BackBufferWidth != client_rect.right
|| present_parameters->BackBufferHeight != client_rect.bottom))
{
TRACE("Rendering to FBO. Backbuffer %ux%u, window %ux%u.\n",
present_parameters->BackBufferWidth,
present_parameters->BackBufferHeight,
client_rect.right, client_rect.bottom);
swapchain->render_to_fbo = TRUE;
}
TRACE("Creating front buffer.\n");
hr = IWineD3DDeviceParent_CreateRenderTarget(device->device_parent, parent,
swapchain->presentParms.BackBufferWidth, swapchain->presentParms.BackBufferHeight,
swapchain->presentParms.BackBufferFormat, swapchain->presentParms.MultiSampleType,
swapchain->presentParms.MultiSampleQuality, TRUE /* Lockable */, &swapchain->frontBuffer);
if (FAILED(hr))
{
WARN("Failed to create front buffer, hr %#x.\n", hr);
goto err;
}
IWineD3DSurface_SetContainer(swapchain->frontBuffer, (IWineD3DBase *)swapchain);
((IWineD3DSurfaceImpl *)swapchain->frontBuffer)->Flags |= SFLAG_SWAPCHAIN;
if (surface_type == SURFACE_OPENGL)
{
IWineD3DSurface_ModifyLocation(swapchain->frontBuffer, SFLAG_INDRAWABLE, TRUE);
}
/* MSDN says we're only allowed a single fullscreen swapchain per device,
* so we should really check to see if there is a fullscreen swapchain
* already. Does a single head count as full screen? */
if (!present_parameters->Windowed)
{
WINED3DDISPLAYMODE mode;
/* Change the display settings */
mode.Width = present_parameters->BackBufferWidth;
mode.Height = present_parameters->BackBufferHeight;
mode.Format = present_parameters->BackBufferFormat;
mode.RefreshRate = present_parameters->FullScreen_RefreshRateInHz;
hr = IWineD3DDevice_SetDisplayMode((IWineD3DDevice *)device, 0, &mode);
if (FAILED(hr))
{
WARN("Failed to set display mode, hr %#x.\n", hr);
goto err;
}
displaymode_set = TRUE;
}
swapchain->context = HeapAlloc(GetProcessHeap(), 0, sizeof(swapchain->context));
if (!swapchain->context)
{
ERR("Failed to create the context array.\n");
hr = E_OUTOFMEMORY;
goto err;
}
swapchain->num_contexts = 1;
if (surface_type == SURFACE_OPENGL)
{
swapchain->context[0] = context_create(device, (IWineD3DSurfaceImpl *)swapchain->frontBuffer,
window, FALSE /* pbuffer */, present_parameters);
if (!swapchain->context[0])
{
WARN("Failed to create context.\n");
hr = WINED3DERR_NOTAVAILABLE;
goto err;
}
swapchain->context[0]->render_offscreen = swapchain->render_to_fbo;
}
else
{
swapchain->context[0] = NULL;
}
if (swapchain->presentParms.BackBufferCount > 0)
{
swapchain->backBuffer = HeapAlloc(GetProcessHeap(), 0,
sizeof(*swapchain->backBuffer) * swapchain->presentParms.BackBufferCount);
if (!swapchain->backBuffer)
{
ERR("Failed to allocate backbuffer array memory.\n");
hr = E_OUTOFMEMORY;
goto err;
}
for (i = 0; i < swapchain->presentParms.BackBufferCount; ++i)
{
TRACE("Creating back buffer %u.\n", i);
hr = IWineD3DDeviceParent_CreateRenderTarget(device->device_parent, parent,
swapchain->presentParms.BackBufferWidth, swapchain->presentParms.BackBufferHeight,
swapchain->presentParms.BackBufferFormat, swapchain->presentParms.MultiSampleType,
swapchain->presentParms.MultiSampleQuality, TRUE /* Lockable */, &swapchain->backBuffer[i]);
if (FAILED(hr))
{
WARN("Failed to create back buffer %u, hr %#x.\n", i, hr);
goto err;
}
IWineD3DSurface_SetContainer(swapchain->backBuffer[i], (IWineD3DBase *)swapchain);
((IWineD3DSurfaceImpl *)swapchain->backBuffer[i])->Flags |= SFLAG_SWAPCHAIN;
if (surface_type == SURFACE_OPENGL)
{
ENTER_GL();
glDrawBuffer(GL_BACK);
checkGLcall("glDrawBuffer(GL_BACK)");
LEAVE_GL();
}
}
}
else
{
/* Single buffering - draw to front buffer */
if (surface_type == SURFACE_OPENGL)
{
ENTER_GL();
glDrawBuffer(GL_FRONT);
checkGLcall("glDrawBuffer(GL_FRONT)");
LEAVE_GL();
}
}
if (swapchain->context[0]) context_release(swapchain->context[0]);
/* Swapchains share the depth/stencil buffer, so only create a single depthstencil surface. */
if (present_parameters->EnableAutoDepthStencil && surface_type == SURFACE_OPENGL)
{
TRACE("Creating depth/stencil buffer.\n");
if (!device->auto_depth_stencil_buffer)
{
hr = IWineD3DDeviceParent_CreateDepthStencilSurface(device->device_parent, parent,
swapchain->presentParms.BackBufferWidth, swapchain->presentParms.BackBufferHeight,
swapchain->presentParms.AutoDepthStencilFormat, swapchain->presentParms.MultiSampleType,
swapchain->presentParms.MultiSampleQuality, FALSE /* FIXME: Discard */,
&device->auto_depth_stencil_buffer);
if (FAILED(hr))
{
WARN("Failed to create the auto depth stencil, hr %#x.\n", hr);
goto err;
}
IWineD3DSurface_SetContainer(device->auto_depth_stencil_buffer, NULL);
}
}
IWineD3DSwapChain_GetGammaRamp((IWineD3DSwapChain *)swapchain, &swapchain->orig_gamma);
return WINED3D_OK;
err:
if (displaymode_set)
{
DEVMODEW devmode;
ClipCursor(NULL);
/* Change the display settings */
memset(&devmode, 0, sizeof(devmode));
devmode.dmSize = sizeof(devmode);
devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
devmode.dmBitsPerPel = format_desc->byte_count * 8;
devmode.dmPelsWidth = swapchain->orig_width;
devmode.dmPelsHeight = swapchain->orig_height;
ChangeDisplaySettingsExW(adapter->DeviceName, &devmode, NULL, CDS_FULLSCREEN, NULL);
}
if (swapchain->backBuffer)
{
for (i = 0; i < swapchain->presentParms.BackBufferCount; ++i)
{
if (swapchain->backBuffer[i]) IWineD3DSurface_Release(swapchain->backBuffer[i]);
}
HeapFree(GetProcessHeap(), 0, swapchain->backBuffer);
}
if (swapchain->context && swapchain->context[0])
{
context_release(swapchain->context[0]);
context_destroy(device, swapchain->context[0]);
}
if (swapchain->frontBuffer) IWineD3DSurface_Release(swapchain->frontBuffer);
return hr;
}
struct wined3d_context *swapchain_create_context_for_thread(IWineD3DSwapChain *iface)
{
IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *) iface;

View File

@ -1598,6 +1598,8 @@ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfac
const WINED3DRECT *pRects, DWORD Flags, WINED3DCOLOR Color, float Z, DWORD Stencil) DECLSPEC_HIDDEN;
void IWineD3DDeviceImpl_FindTexUnitMap(IWineD3DDeviceImpl *This) DECLSPEC_HIDDEN;
void IWineD3DDeviceImpl_MarkStateDirty(IWineD3DDeviceImpl *This, DWORD state) DECLSPEC_HIDDEN;
void IWineD3DDeviceImpl_SetupFullscreenWindow(IWineD3DDeviceImpl *This, HWND window, UINT w, UINT h) DECLSPEC_HIDDEN;
static inline BOOL isStateDirty(struct wined3d_context *context, DWORD state)
{
DWORD idx = state >> 5;
@ -2423,7 +2425,6 @@ typedef struct IWineD3DSwapChainImpl
HWND win_handle;
} IWineD3DSwapChainImpl;
extern const IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl DECLSPEC_HIDDEN;
const IWineD3DSwapChainVtbl IWineGDISwapChain_Vtbl DECLSPEC_HIDDEN;
void x11_copy_to_screen(IWineD3DSwapChainImpl *This, const RECT *rc) DECLSPEC_HIDDEN;
@ -2450,6 +2451,8 @@ HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetGammaRamp(IWineD3DSwapChain *iface,
WINED3DGAMMARAMP *pRamp) DECLSPEC_HIDDEN;
struct wined3d_context *swapchain_create_context_for_thread(IWineD3DSwapChain *iface) DECLSPEC_HIDDEN;
HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface_type,
IWineD3DDeviceImpl *device, WINED3DPRESENT_PARAMETERS *present_parameters, IUnknown *parent) DECLSPEC_HIDDEN;
#define DEFAULT_REFRESH_RATE 0