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