From a3e39528d4071c8db2fa8eb2e5cc81eebec9d982 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Sun, 6 Dec 2009 15:45:46 +0100 Subject: [PATCH 02/20] WineD3D: A function for checking if a surface is offscreen --- dlls/wined3d/device.c | 8 +++--- dlls/wined3d/surface.c | 58 ++++++++++++++++++++++++---------------- dlls/wined3d/wined3d_private.h | 1 + 3 files changed, 40 insertions(+), 27 deletions(-) diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 6ac60f1..12003d6 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -5676,7 +5676,7 @@ static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface, IWineD3DSwapChain *swapchain; swapchain = get_swapchain(surface); - if (swapchain) { + if (!surface_is_offscreen(surface)) { GLenum buffer; TRACE("Surface %p is onscreen\n", surface); @@ -5699,7 +5699,7 @@ static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface, if (rect) { glEnable(GL_SCISSOR_TEST); - if(!swapchain) { + if(surface_is_offscreen(surface)) { glScissor(rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1); } else { glScissor(rect->x1, ((IWineD3DSurfaceImpl *)surface)->currentDesc.Height - rect->y2, @@ -6088,7 +6088,7 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED gl_info = context->gl_info; - if (src_swapchain) { + if (!surface_is_offscreen(src_surface)) { GLenum buffer = surface_get_gl_buffer(src_surface, src_swapchain); TRACE("Source surface %p is onscreen\n", src_surface); @@ -6126,7 +6126,7 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED LEAVE_GL(); /* Attach dst surface to dst fbo */ - if (dst_swapchain) { + if (!surface_is_offscreen(dst_surface)) { GLenum buffer = surface_get_gl_buffer(dst_surface, dst_swapchain); TRACE("Destination surface %p is onscreen\n", dst_surface); diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 1463dd4..7c4551b 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -923,7 +923,6 @@ static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface) { /* Read the framebuffer back into the surface */ static void read_from_framebuffer(IWineD3DSurfaceImpl *This, CONST RECT *rect, void *dest, UINT pitch) { - IWineD3DSwapChainImpl *swapchain; IWineD3DDeviceImpl *myDevice = This->resource.wineD3DDevice; struct wined3d_context *context; BYTE *mem; @@ -959,16 +958,8 @@ static void read_from_framebuffer(IWineD3DSurfaceImpl *This, CONST RECT *rect, v * There is no need to keep track of the current read buffer or reset it, every part of the code * that reads sets the read buffer as desired. */ - if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *) This, &IID_IWineD3DSwapChain, (void **)&swapchain))) + if (surface_is_offscreen((IWineD3DSurface *) This)) { - GLenum buffer = surface_get_gl_buffer((IWineD3DSurface *) This, (IWineD3DSwapChain *)swapchain); - TRACE("Locking %#x buffer\n", buffer); - glReadBuffer(buffer); - checkGLcall("glReadBuffer"); - - IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain); - srcIsUpsideDown = FALSE; - } else { /* Locking the primary render target which is not on a swapchain(=offscreen render target). * Read from the back buffer */ @@ -976,6 +967,15 @@ static void read_from_framebuffer(IWineD3DSurfaceImpl *This, CONST RECT *rect, v glReadBuffer(myDevice->offscreenBuffer); srcIsUpsideDown = TRUE; } + else + { + /* Onscreen surfaces are always part of a swapchain */ + GLenum buffer = surface_get_gl_buffer((IWineD3DSurface *) This, (IWineD3DSwapChain *) This->container); + TRACE("Locking %#x buffer\n", buffer); + glReadBuffer(buffer); + checkGLcall("glReadBuffer"); + srcIsUpsideDown = FALSE; + } /* TODO: Get rid of the extra rectangle comparison and construction of a full surface rectangle */ if(!rect) { @@ -1770,7 +1770,7 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_ *internal = glDesc->glGammaInternal; } else if (This->resource.usage & WINED3DUSAGE_RENDERTARGET - && !(This->Flags & SFLAG_SWAPCHAIN)) + && surface_is_offscreen((IWineD3DSurface *) This)) { *internal = glDesc->rtInternal; } else { @@ -3102,7 +3102,7 @@ static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3D /* Bind the target texture */ glBindTexture(This->texture_target, This->texture_name); checkGLcall("glBindTexture"); - if(!swapchain) { + if(surface_is_offscreen(SrcSurface)) { TRACE("Reading from an offscreen target\n"); upsidedown = !upsidedown; glReadBuffer(myDevice->offscreenBuffer); @@ -3241,12 +3241,12 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine Src->Flags &= ~SFLAG_INTEXTURE; } - if(swapchain) { - glReadBuffer(surface_get_gl_buffer(SrcSurface, (IWineD3DSwapChain *)swapchain)); - } else { + if(surface_is_offscreen(SrcSurface)) { TRACE("Reading from an offscreen target\n"); upsidedown = !upsidedown; glReadBuffer(myDevice->offscreenBuffer); + } else { + glReadBuffer(surface_get_gl_buffer(SrcSurface, (IWineD3DSwapChain *)swapchain)); } /* TODO: Only back up the part that will be overwritten */ @@ -4562,13 +4562,15 @@ static void WINAPI IWineD3DSurfaceImpl_ModifyLocation(IWineD3DSurface *iface, DW persistent ? "TRUE" : "FALSE"); if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { - if (This->Flags & SFLAG_SWAPCHAIN) + if (surface_is_offscreen(iface)) { - TRACE("Surface %p is an onscreen surface\n", iface); - } else { /* With ORM_FBO, SFLAG_INTEXTURE and SFLAG_INDRAWABLE are the same for offscreen targets. */ if (flag & (SFLAG_INTEXTURE | SFLAG_INDRAWABLE)) flag |= (SFLAG_INTEXTURE | SFLAG_INDRAWABLE); } + else + { + TRACE("Surface %p is an onscreen surface\n", iface); + } } if(persistent) { @@ -4829,16 +4831,20 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D int width, pitch, outpitch; BYTE *mem; BOOL drawable_read_ok = TRUE; + BOOL in_fbo = FALSE; if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { - if (This->Flags & SFLAG_SWAPCHAIN) + if (surface_is_offscreen(iface)) { - TRACE("Surface %p is an onscreen surface\n", iface); - } else { /* With ORM_FBO, SFLAG_INTEXTURE and SFLAG_INDRAWABLE are the same for offscreen targets. * Prefer SFLAG_INTEXTURE. */ if (flag == SFLAG_INDRAWABLE) flag = SFLAG_INTEXTURE; drawable_read_ok = FALSE; + in_fbo = TRUE; + } + else + { + TRACE("Surface %p is an onscreen surface\n", iface); } } @@ -5063,8 +5069,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D This->Flags |= flag; } - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && !(This->Flags & SFLAG_SWAPCHAIN) - && (This->Flags & (SFLAG_INTEXTURE | SFLAG_INDRAWABLE))) { + if (in_fbo && (This->Flags & (SFLAG_INTEXTURE | SFLAG_INDRAWABLE))) { /* With ORM_FBO, SFLAG_INTEXTURE and SFLAG_INDRAWABLE are the same for offscreen targets. */ This->Flags |= (SFLAG_INTEXTURE | SFLAG_INDRAWABLE); } @@ -5121,6 +5126,13 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_DrawOverlay(IWineD3DSurface *iface) { return hr; } +BOOL surface_is_offscreen(IWineD3DSurface *iface) +{ + IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface; + + return !(This->Flags & SFLAG_SWAPCHAIN); +} + const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl = { /* IUnknown */ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index bd8e58f..4fb556c 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1727,6 +1727,7 @@ typedef struct IWineD3DBaseTextureClass void surface_internal_preload(IWineD3DSurface *iface, enum WINED3DSRGB srgb) DECLSPEC_HIDDEN; BOOL surface_init_sysmem(IWineD3DSurface *iface) DECLSPEC_HIDDEN; +BOOL surface_is_offscreen(IWineD3DSurface *iface) DECLSPEC_HIDDEN; typedef struct IWineD3DBaseTextureImpl { -- 1.6.4.4