swapchain.c revision dce32b5ab44d19932db4c40310f864dab2b5df26
e35e9d6317da2985728e7510bea9337b9893b66evboxsync *IDirect3DSwapChain9 implementation
e35e9d6317da2985728e7510bea9337b9893b66evboxsync *Copyright 2002-2003 Jason Edmeades
e35e9d6317da2985728e7510bea9337b9893b66evboxsync *Copyright 2002-2003 Raphael Junqueira
e35e9d6317da2985728e7510bea9337b9893b66evboxsync *Copyright 2005 Oliver Stieber
e35e9d6317da2985728e7510bea9337b9893b66evboxsync *Copyright 2007-2008 Stefan Dösinger for CodeWeavers
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync *This library is free software; you can redistribute it and/or
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync *modify it under the terms of the GNU Lesser General Public
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync *License as published by the Free Software Foundation; either
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync *version 2.1 of the License, or (at your option) any later version.
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync *This library is distributed in the hope that it will be useful,
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync *but WITHOUT ANY WARRANTY; without even the implied warranty of
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync *Lesser General Public License for more details.
e35e9d6317da2985728e7510bea9337b9893b66evboxsync *You should have received a copy of the GNU Lesser General Public
e35e9d6317da2985728e7510bea9337b9893b66evboxsync *License along with this library; if not, write to the Free Software
f52596ee352b88100d0a2abd044c8edd3c542bd7vboxsync *Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
e35e9d6317da2985728e7510bea9337b9893b66evboxsync * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
08122b11035de1e54ce1e665dff7260fc548db72vboxsync * a choice of LGPL license versions is made available with the language indicating
08122b11035de1e54ce1e665dff7260fc548db72vboxsync * that LGPLv2 or any later version may be used, or where a choice of which version
b5b8f3d0d95893edd81062c1b5d0bc455cc79bc1vboxsync * of the LGPL is applied is otherwise unspecified.
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync/*TODO: some of the additional parameters may be required to
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync set the gamma ramp (for some weird reason microsoft have left swap gammaramp in device
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync but it operates on a swapchain, it may be a good idea to move it to IWineD3DSwapChain for IWineD3D)*/
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync#define GLINFO_LOCATION This->device->adapter->gl_info
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsyncIWineD3DSwapChainImpl * swapchain_find(IWineD3DDeviceImpl *pDevice, HWND hWnd)
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync IWineD3DSwapChainImpl *pSwapchain = (IWineD3DSwapChainImpl*)pDevice->swapchains[i];
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsyncstatic VOID swapchain_cleanup_rt_refs(IWineD3DSwapChainImpl *pSwapchain, IWineD3DSurface *rt, int iBb)
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync IWineD3DSwapChainImpl *pDefaultSwapchain = (IWineD3DSwapChainImpl*)device->swapchains[0];
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i)
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync newRt = pDefaultSwapchain->backBuffer ? pDefaultSwapchain->backBuffer[0] : pDefaultSwapchain->frontBuffer;
e35e9d6317da2985728e7510bea9337b9893b66evboxsync IWineD3DDevice_SetRenderTarget((IWineD3DDevice*)device, i, newRt, TRUE);
2561352ae77d8f2f825526a6cbafa34b45f16972vboxsyncstatic VOID swapchain_cleanup_refs(IWineD3DSwapChainImpl *pSwapchain)
6eb6707c9fc46c66988caf4b4224b874985d9c2dvboxsync /* first make sure the swapchain is not used by anyone */
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync /* pretty hacky, @todo: check if the context is acquired and re-acquire it with the new swapchain */
e35e9d6317da2985728e7510bea9337b9893b66evboxsync swapchain_cleanup_rt_refs(pSwapchain, pSwapchain->frontBuffer, -1);
e35e9d6317da2985728e7510bea9337b9893b66evboxsync for (j = 0; j < pSwapchain->presentParms.BackBufferCount; ++j)
c2e62d39261f9f69ab4e14b2bbd986bf1b1faaf9vboxsync swapchain_cleanup_rt_refs(pSwapchain, pSwapchain->backBuffer[j], j);
c2e62d39261f9f69ab4e14b2bbd986bf1b1faaf9vboxsyncstatic VOID swapchain_invalidate(IWineD3DSwapChainImpl *pSwapchain)
aaa80e9df329609078dea844a11f2611443b677avboxsync/*IWineD3DSwapChain parts follow: */
08e715a5fb97536a462b199124a0c6e925cfa76cvboxsyncstatic void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface)
c2e62d39261f9f69ab4e14b2bbd986bf1b1faaf9vboxsync IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
c2e62d39261f9f69ab4e14b2bbd986bf1b1faaf9vboxsync unsigned int i;
c2e62d39261f9f69ab4e14b2bbd986bf1b1faaf9vboxsync IWineD3DSwapChain_SetGammaRamp(iface, 0, &This->orig_gamma);
c2e62d39261f9f69ab4e14b2bbd986bf1b1faaf9vboxsync /* first remove swapchain from a list to ensure context is properly acquired
c2e62d39261f9f69ab4e14b2bbd986bf1b1faaf9vboxsync * & gl resources are properly cleared on last swapchain destruction */
c2e62d39261f9f69ab4e14b2bbd986bf1b1faaf9vboxsync IWineD3DDevice_RemoveSwapChain((IWineD3DDevice*)This->device, (IWineD3DSwapChain*)This);
c2e62d39261f9f69ab4e14b2bbd986bf1b1faaf9vboxsync /* Release the swapchain's draw buffers. Make sure This->backBuffer[0] is
c2e62d39261f9f69ab4e14b2bbd986bf1b1faaf9vboxsync * the last buffer to be destroyed, FindContext() depends on that. */
c2e62d39261f9f69ab4e14b2bbd986bf1b1faaf9vboxsync IWineD3DSurface_SetContainer(This->frontBuffer, 0);
c2e62d39261f9f69ab4e14b2bbd986bf1b1faaf9vboxsync WARN("(%p) Something's still holding the front buffer (%p).\n",
a7f701e8c51193f7c21137cc173ea5f86e53cac2vboxsync while (i--)
a7f701e8c51193f7c21137cc173ea5f86e53cac2vboxsync IWineD3DSurface_SetContainer(This->backBuffer[i], 0);
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync WARN("(%p) Something's still holding back buffer %u (%p).\n",
c2e62d39261f9f69ab4e14b2bbd986bf1b1faaf9vboxsync IWineD3DSurfaceImpl *old = (IWineD3DSurfaceImpl*)This->presentRt;
e35e9d6317da2985728e7510bea9337b9893b66evboxsync IWineD3DDevice_RemoveSwapChain((IWineD3DDevice*)This->device, (IWineD3DSwapChain*)This);
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync /* Restore the screen resolution if we rendered in fullscreen
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync * This will restore the screen resolution to what it was before creating the swapchain. In case of d3d8 and d3d9
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync * this will be the original desktop resolution. In case of d3d7 this will be a NOP because ddraw sets the resolution
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync * before starting up Direct3D, thus orig_width and orig_height will be equal to the modes in the presentation params
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync if(This->presentParms.Windowed == FALSE && This->presentParms.AutoRestoreDisplayMode) {
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync IWineD3DDevice_SetDisplayMode((IWineD3DDevice *)This->device, 0, &mode);
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync/* A GL context is provided by the caller */
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsyncstatic void swapchain_blit(IWineD3DSwapChainImpl *This, struct wined3d_context *context,
5cb8545771849c97101a5ee9bb57d0fdac922c44vboxsync IWineD3DSurfaceImpl *backbuffer = ((IWineD3DSurfaceImpl *) This->backBuffer[0]);
e35e9d6317da2985728e7510bea9337b9893b66evboxsync const struct wined3d_gl_info *gl_info = context->gl_info;
e35e9d6317da2985728e7510bea9337b9893b66evboxsync TRACE("swapchain %p, context %p, src_rect %s, dst_rect %s.\n",
e35e9d6317da2985728e7510bea9337b9893b66evboxsync This, context, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect));
e35e9d6317da2985728e7510bea9337b9893b66evboxsync if (src_w == dst_rect->right - dst_rect->left && src_h == dst_rect->bottom - dst_rect->top)
e35e9d6317da2985728e7510bea9337b9893b66evboxsync if (0 && gl_info->fbo_ops.glBlitFramebuffer && is_identity_fixup(backbuffer->resource.format_desc->color_fixup))
e35e9d6317da2985728e7510bea9337b9893b66evboxsync context_bind_fbo(context, GL_READ_FRAMEBUFFER, &context->src_fbo);
e35e9d6317da2985728e7510bea9337b9893b66evboxsync context_attach_surface_fbo(context, GL_READ_FRAMEBUFFER, 0, backbuffer);
e35e9d6317da2985728e7510bea9337b9893b66evboxsync context_attach_depth_stencil_fbo(context, GL_READ_FRAMEBUFFER, NULL, FALSE);
e35e9d6317da2985728e7510bea9337b9893b66evboxsync context_bind_fbo(context, GL_DRAW_FRAMEBUFFER, NULL);
e35e9d6317da2985728e7510bea9337b9893b66evboxsync IWineD3DDeviceImpl_MarkStateDirty(This->device, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE));
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync /* Note that the texture is upside down */
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync gl_info->fbo_ops.glBlitFramebuffer(src_rect->left, src_rect->top, src_rect->right, src_rect->bottom,
e35e9d6317da2985728e7510bea9337b9893b66evboxsync dst_rect->left, dst_rect->bottom, dst_rect->right, dst_rect->top,
e35e9d6317da2985728e7510bea9337b9893b66evboxsync checkGLcall("Swapchain present blit(EXT_framebuffer_blit)\n");
e35e9d6317da2985728e7510bea9337b9893b66evboxsync context2 = context_acquire(This->device, This->backBuffer[0], CTXUSAGE_BLIT);
e35e9d6317da2985728e7510bea9337b9893b66evboxsync if (is_complex_fixup(backbuffer->resource.format_desc->color_fixup))
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync context_bind_fbo(context2, GL_DRAW_FRAMEBUFFER, NULL);
e35e9d6317da2985728e7510bea9337b9893b66evboxsync /* Set up the texture. The surface is not in a IWineD3D*Texture container,
e35e9d6317da2985728e7510bea9337b9893b66evboxsync * so there are no d3d texture settings to dirtify
e35e9d6317da2985728e7510bea9337b9893b66evboxsync device->blitter->set_shader((IWineD3DDevice *) device, backbuffer);
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync glTexParameteri(backbuffer->texture_target, GL_TEXTURE_MIN_FILTER, gl_filter);
e35e9d6317da2985728e7510bea9337b9893b66evboxsync glTexParameteri(backbuffer->texture_target, GL_TEXTURE_MAG_FILTER, gl_filter);
e35e9d6317da2985728e7510bea9337b9893b66evboxsync /* Set the viewport to the destination rectandle, disable any projection
e35e9d6317da2985728e7510bea9337b9893b66evboxsync * transformation set up by CTXUSAGE_BLIT, and draw a (-1,-1)-(1,1) quad.
e35e9d6317da2985728e7510bea9337b9893b66evboxsync * Back up viewport and matrix to avoid breaking last_was_blit
e35e9d6317da2985728e7510bea9337b9893b66evboxsync * Note that CTXUSAGE_BLIT set up viewport and ortho to match the surface
e35e9d6317da2985728e7510bea9337b9893b66evboxsync * size - we want the GL drawable(=window) size.
e35e9d6317da2985728e7510bea9337b9893b66evboxsync glViewport(dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom);
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync /* bottom left */
e35e9d6317da2985728e7510bea9337b9893b66evboxsync /* top left */
e35e9d6317da2985728e7510bea9337b9893b66evboxsync /* top right */
e35e9d6317da2985728e7510bea9337b9893b66evboxsync /* bottom right */
e35e9d6317da2985728e7510bea9337b9893b66evboxsync device->blitter->unset_shader((IWineD3DDevice *) device);
e35e9d6317da2985728e7510bea9337b9893b66evboxsyncstatic HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion, DWORD dwFlags) {
e35e9d6317da2985728e7510bea9337b9893b66evboxsync IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync unsigned int sync;
e35e9d6317da2985728e7510bea9337b9893b66evboxsync /* quickly sort out invalid swapchains */
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync IWineD3DSwapChain_SetDestWindowOverride(iface, hDestWindowOverride);
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync context = context_acquire(This->device, This->backBuffer[0], CTXUSAGE_RESOURCELOAD);
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync /* Render the cursor onto the back buffer, using our nifty directdraw blitting code :-) */
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync if (This->device->bCursorVisible && This->device->cursorTexture)
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync This->device->xScreenSpace - This->device->xHotSpot,
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync This->device->yScreenSpace - This->device->yHotSpot,
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync This->device->xScreenSpace + This->device->cursorWidth - This->device->xHotSpot,
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync This->device->yScreenSpace + This->device->cursorHeight - This->device->yHotSpot,
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync TRACE("Rendering the cursor. Creating fake surface at %p\n", &cursor);
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync /* Build a fake surface to call the Blitting code. It is not possible to use the interface passed by
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync * the application because we are only supposed to copy the information out. Using a fake surface
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync * allows to use the Blitting engine and avoid copying the whole texture -> render target blitting code.
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync cursor.resource.format_desc = getFormatDescEntry(WINED3DFMT_B8G8R8A8_UNORM, context->gl_info);
50c3ee6cc6a9f816790595907558b355769f9c44vboxsync cursor.resource.resourceType = WINED3DRTYPE_SURFACE;
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync cursor.currentDesc.Width = This->device->cursorWidth;
50c3ee6cc6a9f816790595907558b355769f9c44vboxsync cursor.currentDesc.Height = This->device->cursorHeight;
50c3ee6cc6a9f816790595907558b355769f9c44vboxsync /* The cursor must have pow2 sizes */
50c3ee6cc6a9f816790595907558b355769f9c44vboxsync /* The surface is in the texture */
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync /* DDBLT_KEYSRC will cause BltOverride to enable the alpha test with GL_NOTEQUAL, 0.0,
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync * which is exactly what we want :-)
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync /* @todo: can we actualy be here? */
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync MapWindowPoints(NULL, This->win_handle, (LPPOINT)&destRect, 2);
50c3ee6cc6a9f816790595907558b355769f9c44vboxsync IWineD3DSurface_Blt(This->backBuffer[0], &destRect, (IWineD3DSurface *)&cursor,
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync /* Blit the logo into the upper left corner of the drawable. */
50c3ee6cc6a9f816790595907558b355769f9c44vboxsync IWineD3DSurface_BltFast(This->backBuffer[0], 0, 0, This->device->logo_surface, NULL, WINEDDBLTFAST_SRCCOLORKEY);
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync TRACE("Presenting HDC %p.\n", context->currentSwapchain->hDC);
e35e9d6317da2985728e7510bea9337b9893b66evboxsync if (!render_to_fbo && (src_rect.left || src_rect.top
e35e9d6317da2985728e7510bea9337b9893b66evboxsync || src_rect.right != This->presentParms.BackBufferWidth
e35e9d6317da2985728e7510bea9337b9893b66evboxsync || src_rect.bottom != This->presentParms.BackBufferHeight))
e35e9d6317da2985728e7510bea9337b9893b66evboxsync src_rect.right = This->presentParms.BackBufferWidth;
e35e9d6317da2985728e7510bea9337b9893b66evboxsync src_rect.bottom = This->presentParms.BackBufferHeight;
e35e9d6317da2985728e7510bea9337b9893b66evboxsync if (!render_to_fbo && (dst_rect.left || dst_rect.top
ebb33f3aef3b410579a2865109426b798b9d4a9dvboxsync || dst_rect.right != This->presentParms.BackBufferWidth
ebb33f3aef3b410579a2865109426b798b9d4a9dvboxsync || dst_rect.bottom != This->presentParms.BackBufferHeight))
e35e9d6317da2985728e7510bea9337b9893b66evboxsync dst_rect.right = This->presentParms.BackBufferWidth;
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync dst_rect.bottom = This->presentParms.BackBufferHeight;
ebb33f3aef3b410579a2865109426b798b9d4a9dvboxsync /* Rendering to a window of different size, presenting partial rectangles,
ebb33f3aef3b410579a2865109426b798b9d4a9dvboxsync * or rendering to a different window needs help from FBO_blit or a textured
ebb33f3aef3b410579a2865109426b798b9d4a9dvboxsync * draw. Render the swapchain to a FBO in the future.
e35e9d6317da2985728e7510bea9337b9893b66evboxsync * Note that FBO_blit from the backbuffer to the frontbuffer cannot solve
e35e9d6317da2985728e7510bea9337b9893b66evboxsync * all these issues - this fails if the window is smaller than the backbuffer.
e35e9d6317da2985728e7510bea9337b9893b66evboxsync if (!This->render_to_fbo && render_to_fbo && wined3d_settings.offscreen_rendering_mode == ORM_FBO)
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync IWineD3DSurface_LoadLocation(This->backBuffer[0], SFLAG_INTEXTURE, NULL);
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync IWineD3DSurface_ModifyLocation(This->backBuffer[0], SFLAG_INDRAWABLE, FALSE);
e35e9d6317da2985728e7510bea9337b9893b66evboxsync /* Force the context manager to update the render target configuration next draw. */
3eef14636dd78f6e25610b89aec40879e657caf4vboxsync /* This codepath should only be hit with the COPY swapeffect. Otherwise a backbuffer-
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync * window size mismatch is impossible(fullscreen) and src and dst rectangles are
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync * not allowed(they need the COPY swapeffect)
e35e9d6317da2985728e7510bea9337b9893b66evboxsync * The DISCARD swap effect is ok as well since any backbuffer content is allowed after
08122b11035de1e54ce1e665dff7260fc548db72vboxsync if(This->presentParms.SwapEffect == WINED3DSWAPEFFECT_FLIP )
e35e9d6317da2985728e7510bea9337b9893b66evboxsync FIXME("Render-to-fbo with WINED3DSWAPEFFECT_FLIP\n");
3eef14636dd78f6e25610b89aec40879e657caf4vboxsync swapchain_blit(This, context, &src_rect, &dst_rect);
3eef14636dd78f6e25610b89aec40879e657caf4vboxsync HWND wnd = WindowFromDC(context->currentSwapchain->hDC);
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync Assert(wnd == context->currentSwapchain->win_handle);
3eef14636dd78f6e25610b89aec40879e657caf4vboxsync /* We're directly using wglMakeCurrent calls skipping GDI layer, which causes GDI SwapBuffers to fail trying to
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync * call glFinish, which doesn't have any context set. So we use wglSwapLayerBuffers directly as well.
3eef14636dd78f6e25610b89aec40879e657caf4vboxsync pwglSwapLayerBuffers(context->currentSwapchain->hDC, WGL_SWAP_MAIN_PLANE);
3eef14636dd78f6e25610b89aec40879e657caf4vboxsync pwglSwapLayerBuffers(context->hdc, WGL_SWAP_MAIN_PLANE);
3eef14636dd78f6e25610b89aec40879e657caf4vboxsync SwapBuffers(context->hdc); /* TODO: cycle through the swapchain buffers */
1d96c25e994a2160c1697208bb398d79ca117c4avboxsync /* FPS support */
2ea0ec406117609d51bd5ac51cbb3d4f0de9a16dvboxsync /* every 1.5 seconds */
08122b11035de1e54ce1e665dff7260fc548db72vboxsync TRACE_(fps)("%p @ approx %.2ffps\n", This, 1000.0*This->frames/(time - This->prev_time));
1d27f9d208503988168cd9a8a902a0f48cf52a12vboxsync if (GetFileAttributesA("C:\\D3DTRACE") != INVALID_FILE_ATTRIBUTES) {
2fd917a77df587742609eaa229c7cf4922458ae8vboxsync __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 1);
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 0);
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 0);
36a0cf44771c76b56b4a6489136e3adf0343df0bvboxsync /* This is disabled, but the code left in for debug purposes.
36a0cf44771c76b56b4a6489136e3adf0343df0bvboxsync * Since we're allowed to modify the new back buffer on a D3DSWAPEFFECT_DISCARD flip,
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync * we can clear it with some ugly color to make bad drawing visible and ease debugging.
a23d9b6011c292ab4d858fc7d83a2216843cd54evboxsync * The Debug runtime does the same on Windows. However, a few games do not redraw the
e9802cd9ee289e494f01f2c37e714911d120cd30vboxsync * screen properly, like Max Payne 2, which leaves a few pixels undefined.
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync * Tests show that the content of the back buffer after a discard flip is indeed not
e9802cd9ee289e494f01f2c37e714911d120cd30vboxsync * reliable, so no game can depend on the exact content. However, it resembles the
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync * old contents in some way, for example by showing fragments at other locations. In
36a0cf44771c76b56b4a6489136e3adf0343df0bvboxsync * general, the color theme is still intact. So Max payne, which draws rather dark scenes
a23d9b6011c292ab4d858fc7d83a2216843cd54evboxsync * gets a dark background image. If we clear it with a bright ugly color, the game's
ebb33f3aef3b410579a2865109426b798b9d4a9dvboxsync * bug shows up much more than it does on Windows, and the players see single pixels
ebb33f3aef3b410579a2865109426b798b9d4a9dvboxsync * with wrong colors.
ebb33f3aef3b410579a2865109426b798b9d4a9dvboxsync * (The Max Payne bug has been confirmed on Windows with the debug runtime)
e9802cd9ee289e494f01f2c37e714911d120cd30vboxsync if (FALSE && This->presentParms.SwapEffect == WINED3DSWAPEFFECT_DISCARD) {
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync TRACE("Clearing the color buffer with cyan color\n");
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync IWineD3DDevice_Clear((IWineD3DDevice *)This->device, 0, NULL,
a23d9b6011c292ab4d858fc7d83a2216843cd54evboxsync ( ((IWineD3DSurfaceImpl *) This->frontBuffer)->Flags & SFLAG_INSYSMEM ||
36a0cf44771c76b56b4a6489136e3adf0343df0bvboxsync ((IWineD3DSurfaceImpl *) This->backBuffer[0])->Flags & SFLAG_INSYSMEM ) ) {
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync /* Both memory copies of the surfaces are ok, flip them around too instead of dirtifying
ee231a249824f0a96643fb8b705f5b6cf3617b46vboxsync * Doesn't work with render_to_fbo because we're not flipping
ee231a249824f0a96643fb8b705f5b6cf3617b46vboxsync IWineD3DSurfaceImpl *front = (IWineD3DSurfaceImpl *) This->frontBuffer;
ee231a249824f0a96643fb8b705f5b6cf3617b46vboxsync IWineD3DSurfaceImpl *back = (IWineD3DSurfaceImpl *) This->backBuffer[0];
c792fe5d6a56055c4d060db36316c4dac5311c7evboxsync /* Tell the front buffer surface that is has been modified. However,
619da14dbf1f40ada039a6ebceedec8a6abe7696vboxsync * the other locations were preserved during that, so keep the flags.
8952a4a0ea65bcb9926a1da734c1828baff52f54vboxsync * This serves to update the emulated overlay, if any
8952a4a0ea65bcb9926a1da734c1828baff52f54vboxsync IWineD3DSurface_ModifyLocation(This->frontBuffer, SFLAG_INDRAWABLE, TRUE);
8952a4a0ea65bcb9926a1da734c1828baff52f54vboxsync IWineD3DSurface_ModifyLocation((IWineD3DSurface *) front, SFLAG_INDRAWABLE, TRUE);
8952a4a0ea65bcb9926a1da734c1828baff52f54vboxsync IWineD3DSurface_ModifyLocation((IWineD3DSurface *) back, SFLAG_INDRAWABLE, TRUE);
619da14dbf1f40ada039a6ebceedec8a6abe7696vboxsync IWineD3DSurface_ModifyLocation(This->frontBuffer, SFLAG_INDRAWABLE, TRUE);
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync /* If the swapeffect is DISCARD, the back buffer is undefined. That means the SYSMEM
ee231a249824f0a96643fb8b705f5b6cf3617b46vboxsync * and INTEXTURE copies can keep their old content if they have any defined content.
ee231a249824f0a96643fb8b705f5b6cf3617b46vboxsync * If the swapeffect is COPY, the content remains the same. If it is FLIP however,
ee231a249824f0a96643fb8b705f5b6cf3617b46vboxsync * the texture / sysmem copy needs to be reloaded from the drawable
ee231a249824f0a96643fb8b705f5b6cf3617b46vboxsync if(This->presentParms.SwapEffect == WINED3DSWAPEFFECT_FLIP) {
ee231a249824f0a96643fb8b705f5b6cf3617b46vboxsync IWineD3DSurface_ModifyLocation(This->backBuffer[0], SFLAG_INDRAWABLE, TRUE);
36a0cf44771c76b56b4a6489136e3adf0343df0bvboxsync if (This->presentParms.Flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL
36a0cf44771c76b56b4a6489136e3adf0343df0bvboxsync || ((IWineD3DSurfaceImpl *)This->device->stencilBufferTarget)->Flags & SFLAG_DISCARD)
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync surface_modify_ds_location(This->device->stencilBufferTarget, SFLAG_DS_DISCARDED);
c792fe5d6a56055c4d060db36316c4dac5311c7evboxsync if (This->presentParms.PresentationInterval != WINED3DPRESENT_INTERVAL_IMMEDIATE
e35e9d6317da2985728e7510bea9337b9893b66evboxsync ERR("glXGetVideoSyncSGI failed(retval = %d\n", retval);
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync retval = GL_EXTCALL(glXWaitVideoSyncSGI(1, 0, &This->vSyncCounter));
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync retval = GL_EXTCALL(glXWaitVideoSyncSGI(2, This->vSyncCounter & 0x1, &This->vSyncCounter));
50c3ee6cc6a9f816790595907558b355769f9c44vboxsync retval = GL_EXTCALL(glXWaitVideoSyncSGI(3, This->vSyncCounter % 0x3, &This->vSyncCounter));
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync retval = GL_EXTCALL(glXWaitVideoSyncSGI(4, This->vSyncCounter & 0x3, &This->vSyncCounter));
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync FIXME("Unknown presentation interval %08x\n", This->presentParms.PresentationInterval);
50c3ee6cc6a9f816790595907558b355769f9c44vboxsyncstatic HRESULT WINAPI IWineD3DSwapChainImpl_SetDestWindowOverride(IWineD3DSwapChain *iface, HWND window)
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)iface;
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync if (window == swapchain->win_handle) return WINED3D_OK;
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync TRACE("Setting swapchain %p window from %p to %p\n", swapchain, swapchain->win_handle, window);
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsyncstatic HRESULT IWineD3DBaseSwapChainImpl_PresentRtPerform(IWineD3DSwapChainImpl* This)
e35e9d6317da2985728e7510bea9337b9893b66evboxsync HRESULT hr = IWineD3DSurface_Blt(pBb, NULL, This->presentRt, NULL, 0, NULL, 0);
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync hr = IWineD3DSwapChainImpl_Present((IWineD3DSwapChain*)This, NULL, NULL, NULL, NULL, 0);
08122b11035de1e54ce1e665dff7260fc548db72vboxsyncHRESULT WINAPI IWineD3DBaseSwapChainImpl_Flush(IWineD3DSwapChain* This)
08122b11035de1e54ce1e665dff7260fc548db72vboxsync /* @todo: if we're in PresentRt mode, check whether the current present rt is updated
08122b11035de1e54ce1e665dff7260fc548db72vboxsync * and do present to frontbuffer if needed */
36a0cf44771c76b56b4a6489136e3adf0343df0bvboxsyncHRESULT WINAPI IWineD3DBaseSwapChainImpl_PresentRt(IWineD3DSwapChain* iface, IWineD3DSurface* surf)
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl*)iface;
08122b11035de1e54ce1e665dff7260fc548db72vboxsync IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)surf;
5c41f17e15c70a02e57fd39155f6394ebd9add66vboxsync IWineD3DBaseSwapChainImpl_PresentRt(surface->presentSwapchain, NULL);
5c41f17e15c70a02e57fd39155f6394ebd9add66vboxsync IWineD3DSurfaceImpl *old = (IWineD3DSurfaceImpl*)This->presentRt;
c792fe5d6a56055c4d060db36316c4dac5311c7evboxsync return IWineD3DBaseSwapChainImpl_PresentRtPerform(This);
c792fe5d6a56055c4d060db36316c4dac5311c7evboxsyncstatic const IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl =
c792fe5d6a56055c4d060db36316c4dac5311c7evboxsync /* IUnknown */
e35e9d6317da2985728e7510bea9337b9893b66evboxsync /* IWineD3DSwapChain */
50c3ee6cc6a9f816790595907558b355769f9c44vboxsync /* Make sure the window is managed, otherwise we won't get keyboard input. */
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync /* Filter out window decorations. */
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsyncvoid swapchain_setup_fullscreen_window(IWineD3DSwapChainImpl *swapchain, UINT w, UINT h)
e35e9d6317da2985728e7510bea9337b9893b66evboxsync TRACE("Setting up window %p for fullscreen mode.\n", window);
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync ERR("Changing the window style for window %p, but another style (%08x, %08x) is already stored.\n",
08122b11035de1e54ce1e665dff7260fc548db72vboxsync device->exStyle = GetWindowLongW(window, GWL_EXSTYLE);
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync TRACE("Old style was %08x, %08x, setting to %08x, %08x.\n",
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync SetWindowPos(window, HWND_TOP, 0, 0, w, h, SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOACTIVATE);
e35e9d6317da2985728e7510bea9337b9893b66evboxsyncvoid swapchain_restore_fullscreen_window(IWineD3DSwapChainImpl *swapchain)
08122b11035de1e54ce1e665dff7260fc548db72vboxsync TRACE("Restoring window style of window %p to %08x, %08x.\n",
619da14dbf1f40ada039a6ebceedec8a6abe7696vboxsync /* Only restore the style if the application didn't modify it during the
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync * fullscreen phase. Some applications change it before calling Reset()
619da14dbf1f40ada039a6ebceedec8a6abe7696vboxsync * when switching between windowed and fullscreen modes (HL2), some
c792fe5d6a56055c4d060db36316c4dac5311c7evboxsync * depend on the original style (Eve Online). */
c2e62d39261f9f69ab4e14b2bbd986bf1b1faaf9vboxsync if (style == fullscreen_style(device->style) && exstyle == fullscreen_exstyle(device->exStyle))
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync SetWindowLongW(window, GWL_EXSTYLE, device->exStyle);
e35e9d6317da2985728e7510bea9337b9893b66evboxsync SetWindowPos(window, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync /* Delete the old values. */
e35e9d6317da2985728e7510bea9337b9893b66evboxsyncHRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface_type,
e35e9d6317da2985728e7510bea9337b9893b66evboxsync IWineD3DDeviceImpl *device, WINED3DPRESENT_PARAMETERS *present_parameters, IUnknown *parent)
e35e9d6317da2985728e7510bea9337b9893b66evboxsync const struct wined3d_adapter *adapter = device->adapter;
e35e9d6317da2985728e7510bea9337b9893b66evboxsync if (present_parameters->BackBufferCount > WINED3DPRESENT_BACK_BUFFER_MAX)
e35e9d6317da2985728e7510bea9337b9893b66evboxsync ERR("The application requested %u back buffers, this is not supported.\n",
e35e9d6317da2985728e7510bea9337b9893b66evboxsync FIXME("The application requested more than one back buffer, this is not properly supported.\n"
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync "Please configure the application to use double buffering (1 back buffer) if possible.\n");
e35e9d6317da2985728e7510bea9337b9893b66evboxsync FIXME("Caller tried to create a SURFACE_UNKNOWN swapchain.\n");
e35e9d6317da2985728e7510bea9337b9893b66evboxsync overridenSwapchain = swapchain_find(device, present_parameters->hDeviceWindow);
e35e9d6317da2985728e7510bea9337b9893b66evboxsync hr = VBoxExtWndCreate(present_parameters->BackBufferWidth, present_parameters->BackBufferHeight, &window, &hDC);
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync window = present_parameters->hDeviceWindow ? present_parameters->hDeviceWindow : device->createParms.hFocusWindow;
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync swapchain_setup_fullscreen_window(swapchain, present_parameters->BackBufferWidth,
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync IWineD3D_GetAdapterDisplayMode(device->wined3d, adapter->ordinal, &mode);
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync format_desc = getFormatDescEntry(mode.Format, &adapter->gl_info);
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync client_rect.right = present_parameters->BackBufferWidth;
e35e9d6317da2985728e7510bea9337b9893b66evboxsync client_rect.bottom = present_parameters->BackBufferHeight;
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync && (!present_parameters->BackBufferWidth || !present_parameters->BackBufferHeight
e35e9d6317da2985728e7510bea9337b9893b66evboxsync || present_parameters->BackBufferFormat == WINED3DFMT_UNKNOWN))
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync present_parameters->BackBufferWidth = client_rect.right;
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync TRACE("Updating width to %u.\n", present_parameters->BackBufferWidth);
e35e9d6317da2985728e7510bea9337b9893b66evboxsync present_parameters->BackBufferHeight = client_rect.bottom;
e35e9d6317da2985728e7510bea9337b9893b66evboxsync TRACE("Updating height to %u.\n", present_parameters->BackBufferHeight);
e35e9d6317da2985728e7510bea9337b9893b66evboxsync if (present_parameters->BackBufferFormat == WINED3DFMT_UNKNOWN)
08122b11035de1e54ce1e665dff7260fc548db72vboxsync present_parameters->BackBufferFormat = swapchain->orig_fmt;
e35e9d6317da2985728e7510bea9337b9893b66evboxsync TRACE("Updating format to %s.\n", debug_d3dformat(swapchain->orig_fmt));
e35e9d6317da2985728e7510bea9337b9893b66evboxsync if (wined3d_settings.offscreen_rendering_mode == ORM_FBO
e35e9d6317da2985728e7510bea9337b9893b66evboxsync && (present_parameters->BackBufferWidth != client_rect.right
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync || present_parameters->BackBufferHeight != client_rect.bottom))
e35e9d6317da2985728e7510bea9337b9893b66evboxsync TRACE("Rendering to FBO. Backbuffer %ux%u, window %ux%u.\n",
e35e9d6317da2985728e7510bea9337b9893b66evboxsync hr = IWineD3DDeviceParent_CreateRenderTarget(device->device_parent, parent,
e35e9d6317da2985728e7510bea9337b9893b66evboxsync swapchain->presentParms.BackBufferWidth, swapchain->presentParms.BackBufferHeight,
e35e9d6317da2985728e7510bea9337b9893b66evboxsync swapchain->presentParms.BackBufferFormat, swapchain->presentParms.MultiSampleType,
e35e9d6317da2985728e7510bea9337b9893b66evboxsync swapchain->presentParms.MultiSampleQuality, TRUE /* Lockable */, &swapchain->frontBuffer);
e35e9d6317da2985728e7510bea9337b9893b66evboxsync WARN("Failed to create front buffer, hr %#x.\n", hr);
e35e9d6317da2985728e7510bea9337b9893b66evboxsync IWineD3DSurface_SetContainer(swapchain->frontBuffer, (IWineD3DBase *)swapchain);
e35e9d6317da2985728e7510bea9337b9893b66evboxsync ((IWineD3DSurfaceImpl *)swapchain->frontBuffer)->Flags |= SFLAG_SWAPCHAIN;
e35e9d6317da2985728e7510bea9337b9893b66evboxsync IWineD3DSurface_ModifyLocation(swapchain->frontBuffer, SFLAG_INDRAWABLE, TRUE);
c792fe5d6a56055c4d060db36316c4dac5311c7evboxsync /* MSDN says we're only allowed a single fullscreen swapchain per device,
e35e9d6317da2985728e7510bea9337b9893b66evboxsync * so we should really check to see if there is a fullscreen swapchain
e35e9d6317da2985728e7510bea9337b9893b66evboxsync * already. Does a single head count as full screen? */
c792fe5d6a56055c4d060db36316c4dac5311c7evboxsync /* Change the display settings */
e8061cc98e3d41ea42f0f835db3501d58c26e7fbvboxsync mode.Height = present_parameters->BackBufferHeight;
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync mode.Format = present_parameters->BackBufferFormat;
d6bdf8a836b8e7d95eec19c254cd39161731d48fvboxsync mode.RefreshRate = present_parameters->FullScreen_RefreshRateInHz;
e35e9d6317da2985728e7510bea9337b9893b66evboxsync hr = IWineD3DDevice_SetDisplayMode((IWineD3DDevice *)device, 0, &mode);
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync swapchain->context = HeapAlloc(GetProcessHeap(), 0, sizeof(swapchain->context));
e35e9d6317da2985728e7510bea9337b9893b66evboxsync const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
e35e9d6317da2985728e7510bea9337b9893b66evboxsync /* In WGL both color, depth and stencil are features of a pixel format. In case of D3D they are separate.
e35e9d6317da2985728e7510bea9337b9893b66evboxsync * You are able to add a depth + stencil surface at a later stage when you need it.
e35e9d6317da2985728e7510bea9337b9893b66evboxsync * In order to support this properly in WineD3D we need the ability to recreate the opengl context and
e35e9d6317da2985728e7510bea9337b9893b66evboxsync * drawable when this is required. This is very tricky as we need to reapply ALL opengl states for the new
15eedc898539502083b8ce6db7c3d53d805fb9advboxsync * context, need torecreate shaders, textures and other resources.
20606357beeba9ef9025b662f5e3d178dd37d559vboxsync * The context manager already takes care of the state problem and for the other tasks code from Reset
20606357beeba9ef9025b662f5e3d178dd37d559vboxsync * can be used. These changes are way to risky during the 1.0 code freeze which is taking place right now.
20606357beeba9ef9025b662f5e3d178dd37d559vboxsync * Likely a lot of other new bugs will be exposed. For that reason request a depth stencil surface all the
ebb33f3aef3b410579a2865109426b798b9d4a9dvboxsync * time. It can cause a slight performance hit but fixes a lot of regressions. A fixme reminds of that this
ebb33f3aef3b410579a2865109426b798b9d4a9dvboxsync * issue needs to be fixed. */
15eedc898539502083b8ce6db7c3d53d805fb9advboxsync || swapchain->presentParms.AutoDepthStencilFormat != WINED3DFMT_D24_UNORM_S8_UINT)
20606357beeba9ef9025b662f5e3d178dd37d559vboxsync FIXME("Add OpenGL context recreation support to context_validate_onscreen_formats\n");
ebb33f3aef3b410579a2865109426b798b9d4a9dvboxsync swapchain->ds_format = getFormatDescEntry(WINED3DFMT_D24_UNORM_S8_UINT, gl_info);
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync swapchainContext = context_find_create(device, swapchain, (IWineD3DSurfaceImpl *)swapchain->frontBuffer,
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync swapchain->context[0] = context_create(swapchain, (IWineD3DSurfaceImpl *)swapchain->frontBuffer,
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync swapchain->backBuffer = HeapAlloc(GetProcessHeap(), 0,
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync sizeof(*swapchain->backBuffer) * swapchain->presentParms.BackBufferCount);
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync ERR("Failed to allocate backbuffer array memory.\n");
50c3ee6cc6a9f816790595907558b355769f9c44vboxsync for (i = 0; i < swapchain->presentParms.BackBufferCount; ++i)
50c3ee6cc6a9f816790595907558b355769f9c44vboxsync hr = IWineD3DDeviceParent_CreateRenderTarget(device->device_parent, parent,
50c3ee6cc6a9f816790595907558b355769f9c44vboxsync swapchain->presentParms.BackBufferWidth, swapchain->presentParms.BackBufferHeight,
50c3ee6cc6a9f816790595907558b355769f9c44vboxsync swapchain->presentParms.BackBufferFormat, swapchain->presentParms.MultiSampleType,
50c3ee6cc6a9f816790595907558b355769f9c44vboxsync swapchain->presentParms.MultiSampleQuality, TRUE /* Lockable */, &swapchain->backBuffer[i]);
50c3ee6cc6a9f816790595907558b355769f9c44vboxsync WARN("Failed to create back buffer %u, hr %#x.\n", i, hr);
50c3ee6cc6a9f816790595907558b355769f9c44vboxsync IWineD3DSurface_SetContainer(swapchain->backBuffer[i], (IWineD3DBase *)swapchain);
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync ((IWineD3DSurfaceImpl *)swapchain->backBuffer[i])->Flags |= SFLAG_SWAPCHAIN;
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync /* Swapchains share the depth/stencil buffer, so only create a single depthstencil surface. */
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync if (present_parameters->EnableAutoDepthStencil && surface_type == SURFACE_OPENGL)
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync hr = IWineD3DDeviceParent_CreateDepthStencilSurface(device->device_parent, parent,
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync swapchain->presentParms.BackBufferWidth, swapchain->presentParms.BackBufferHeight,
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync swapchain->presentParms.AutoDepthStencilFormat, swapchain->presentParms.MultiSampleType,
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync swapchain->presentParms.MultiSampleQuality, FALSE /* FIXME: Discard */,
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync WARN("Failed to create the auto depth stencil, hr %#x.\n", hr);
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync IWineD3DSurface_SetContainer(device->auto_depth_stencil_buffer, NULL);
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync IWineD3DSwapChain_GetGammaRamp((IWineD3DSwapChain *)swapchain, &swapchain->orig_gamma);
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync /* Change the display settings */
15fe3cf8212d4ca73ea0a4fe547892bcddef6e16vboxsync devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
a253309ecf51232be71a5c0f7b888e03f51906a3vboxsync devmode.dmBitsPerPel = format_desc->byte_count * 8;
50c3ee6cc6a9f816790595907558b355769f9c44vboxsync ChangeDisplaySettingsExW(adapter->DeviceName, &devmode, NULL, CDS_FULLSCREEN, NULL);
#ifdef VBOX_WITH_WDDM
#ifdef VBOX_WITH_WDDM
return hr;
#ifndef VBOX_WITH_WDDM
#ifdef VBOX_WITH_WDDM
#ifdef VBOX_WITH_WDDM
return NULL;
#ifdef VBOX_WITH_WDDM
/* no need to do anything since context gets added to the device context list within the context_create call */
if(!newArray) {
return NULL;
return ctx;