From 0b24db5db5468808d29b69036dc09492b86e1b9b Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Mon, 16 Aug 2010 20:00:25 +0200 Subject: [PATCH] wined3d: Also store the subresource container type. --- dlls/wined3d/arb_program_shader.c | 3 ++- dlls/wined3d/context.c | 9 +++++---- dlls/wined3d/cubetexture.c | 4 ++-- dlls/wined3d/device.c | 12 ++++++------ dlls/wined3d/surface.c | 28 +++++++++++----------------- dlls/wined3d/surface_base.c | 2 +- dlls/wined3d/swapchain.c | 10 +++++----- dlls/wined3d/swapchain_gdi.c | 4 ++-- dlls/wined3d/texture.c | 4 ++-- dlls/wined3d/wined3d_private.h | 22 ++++++++++++++++++++-- 10 files changed, 56 insertions(+), 42 deletions(-) diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index ef7822778cc..03443b45c3e 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -7144,7 +7144,8 @@ HRESULT arbfp_blit_surface(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *src_ * Also beware of the origin difference(top left vs bottom left). * Also beware that the front buffer's surface size is screen width x screen height, * whereas the real gl drawable size is the size of the window. */ - dst_swapchain = (dst_surface->Flags & SFLAG_SWAPCHAIN) ? (IWineD3DSwapChainImpl *)dst_surface->container : NULL; + dst_swapchain = dst_surface->container.type == WINED3D_CONTAINER_SWAPCHAIN + ? dst_surface->container.u.swapchain : NULL; if (dst_swapchain && dst_surface == dst_swapchain->front_buffer) surface_translate_frontbuffer_coords(dst_surface, context->win_handle, &dst_rect); diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index d7f2cf3a1ed..d94c0ad62fd 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -1898,7 +1898,6 @@ static struct wined3d_context *findThreadContextForSwapChain(IWineD3DSwapChain * *****************************************************************************/ static struct wined3d_context *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target) { - IWineD3DSwapChain *swapchain = NULL; struct wined3d_context *current_context = context_get_current(); DWORD tid = GetCurrentThreadId(); struct wined3d_context *context; @@ -1927,11 +1926,13 @@ static struct wined3d_context *FindContext(IWineD3DDeviceImpl *This, IWineD3DSur return current_context; } - if (target->Flags & SFLAG_SWAPCHAIN) + if (target->container.type == WINED3D_CONTAINER_SWAPCHAIN) { + IWineD3DSwapChain *swapchain; + TRACE("Rendering onscreen\n"); - swapchain = (IWineD3DSwapChain *)target->container; + swapchain = (IWineD3DSwapChain *)target->container.u.swapchain; context = findThreadContextForSwapChain(swapchain, tid); } else @@ -2078,7 +2079,7 @@ static void context_validate_onscreen_formats(IWineD3DDeviceImpl *device, struct wined3d_context *context, IWineD3DSurfaceImpl *depth_stencil) { /* Onscreen surfaces are always in a swapchain */ - IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)context->current_rt->container; + IWineD3DSwapChainImpl *swapchain = context->current_rt->container.u.swapchain; if (context->render_offscreen || !depth_stencil) return; if (match_depth_stencil_format(swapchain->ds_format, depth_stencil->resource.format_desc)) return; diff --git a/dlls/wined3d/cubetexture.c b/dlls/wined3d/cubetexture.c index d10da4930b7..acdf4d339f5 100644 --- a/dlls/wined3d/cubetexture.c +++ b/dlls/wined3d/cubetexture.c @@ -127,7 +127,7 @@ static void cubetexture_cleanup(IWineD3DCubeTextureImpl *This) surface_set_texture_name(surface, 0, TRUE); surface_set_texture_name(surface, 0, FALSE); surface_set_texture_target(surface, 0); - surface_set_container(surface, NULL); + surface_set_container(surface, WINED3D_CONTAINER_NONE, NULL); IWineD3DSurface_Release((IWineD3DSurface *)surface); } } @@ -558,7 +558,7 @@ HRESULT cubetexture_init(IWineD3DCubeTextureImpl *texture, UINT edge_length, UIN return hr; } - surface_set_container((IWineD3DSurfaceImpl *)surface, (IWineD3DBase *)texture); + surface_set_container((IWineD3DSurfaceImpl *)surface, WINED3D_CONTAINER_TEXTURE, (IWineD3DBase *)texture); surface_set_texture_target((IWineD3DSurfaceImpl *)surface, cube_targets[j]); texture->baseTexture.sub_resources[idx] = (IWineD3DResourceImpl *)surface; TRACE("Created surface level %u @ %p.\n", i, surface); diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index ac282268a03..057c1074a45 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -804,8 +804,8 @@ HRESULT device_clear_render_targets(IWineD3DDeviceImpl *device, UINT rt_count, I LEAVE_GL(); - if (wined3d_settings.strict_draw_ordering || ((target->Flags & SFLAG_SWAPCHAIN) - && ((IWineD3DSwapChainImpl *)target->container)->front_buffer == target)) + if (wined3d_settings.strict_draw_ordering || (target->container.type == WINED3D_CONTAINER_SWAPCHAIN + && target->container.u.swapchain->front_buffer == target)) wglFlush(); /* Flush to ensure ordering across contexts. */ context_release(context); @@ -5651,14 +5651,14 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetFrontBackBuffers(IWineD3DDevice *ifa if (swapchain->front_buffer) { - surface_set_container(swapchain->front_buffer, NULL); + surface_set_container(swapchain->front_buffer, WINED3D_CONTAINER_NONE, NULL); swapchain->front_buffer->Flags &= ~SFLAG_SWAPCHAIN; } swapchain->front_buffer = front_impl; if (front_impl) { - surface_set_container(front_impl, (IWineD3DBase *)swapchain); + surface_set_container(front_impl, WINED3D_CONTAINER_SWAPCHAIN, (IWineD3DBase *)swapchain); front_impl->Flags |= SFLAG_SWAPCHAIN; } } @@ -5669,7 +5669,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetFrontBackBuffers(IWineD3DDevice *ifa if (swapchain->back_buffers[0]) { - surface_set_container(swapchain->back_buffers[0], NULL); + surface_set_container(swapchain->back_buffers[0], WINED3D_CONTAINER_TEXTURE, NULL); swapchain->back_buffers[0]->Flags &= ~SFLAG_SWAPCHAIN; } swapchain->back_buffers[0] = back_impl; @@ -5681,7 +5681,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetFrontBackBuffers(IWineD3DDevice *ifa swapchain->presentParms.BackBufferFormat = back_impl->resource.format_desc->format; swapchain->presentParms.BackBufferCount = 1; - surface_set_container(back_impl, (IWineD3DBase *)swapchain); + surface_set_container(back_impl, WINED3D_CONTAINER_SWAPCHAIN, (IWineD3DBase *)swapchain); back_impl->Flags |= SFLAG_SWAPCHAIN; } else diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 20c7685efc4..f9771bab58b 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -92,20 +92,13 @@ static void surface_cleanup(IWineD3DSurfaceImpl *This) resource_cleanup((IWineD3DResource *)This); } -void surface_set_container(IWineD3DSurfaceImpl *surface, IWineD3DBase *container) +void surface_set_container(IWineD3DSurfaceImpl *surface, enum wined3d_container_type type, IWineD3DBase *container) { - IWineD3DSwapChain *swapchain = NULL; - TRACE("surface %p, container %p.\n", surface, container); - if (container) - { - IWineD3DBase_QueryInterface(container, &IID_IWineD3DSwapChain, (void **)&swapchain); - } - if (swapchain) + if (type == WINED3D_CONTAINER_SWAPCHAIN) { surface->get_drawable_size = get_drawable_size_swapchain; - IWineD3DSwapChain_Release(swapchain); } else { @@ -125,7 +118,8 @@ void surface_set_container(IWineD3DSurfaceImpl *surface, IWineD3DBase *container } } - surface->container = container; + surface->container.type = type; + surface->container.u.base = container; } struct blt_info @@ -396,7 +390,7 @@ HRESULT surface_init(IWineD3DSurfaceImpl *surface, WINED3DSURFTYPE surface_type, } /* "Standalone" surface. */ - surface_set_container(surface, NULL); + surface_set_container(surface, WINED3D_CONTAINER_NONE, NULL); surface->currentDesc.Width = width; surface->currentDesc.Height = height; @@ -928,11 +922,11 @@ void surface_set_compatible_renderbuffer(IWineD3DSurfaceImpl *surface, unsigned GLenum surface_get_gl_buffer(IWineD3DSurfaceImpl *surface) { - IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)surface->container; + IWineD3DSwapChainImpl *swapchain = surface->container.u.swapchain; TRACE("surface %p.\n", surface); - if (!(surface->Flags & SFLAG_SWAPCHAIN)) + if (surface->container.type != WINED3D_CONTAINER_SWAPCHAIN) { ERR("Surface %p is not on a swapchain.\n", surface); return GL_NONE; @@ -4359,7 +4353,8 @@ static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This, const RECT dst_rect = src_rect; } - if ((This->Flags & SFLAG_SWAPCHAIN) && This == ((IWineD3DSwapChainImpl *)This->container)->front_buffer) + swapchain = This->container.type == WINED3D_CONTAINER_SWAPCHAIN ? This->container.u.swapchain : NULL; + if (swapchain && This == swapchain->front_buffer) surface_translate_frontbuffer_coords(This, context->win_handle, &dst_rect); device->blitter->set_shader((IWineD3DDevice *) device, This); @@ -4370,7 +4365,6 @@ static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This, const RECT device->blitter->unset_shader((IWineD3DDevice *) device); - swapchain = (This->Flags & SFLAG_SWAPCHAIN) ? (IWineD3DSwapChainImpl *)This->container : NULL; if (wined3d_settings.strict_draw_ordering || (swapchain && (This == swapchain->front_buffer || swapchain->num_contexts > 1))) wglFlush(); /* Flush to ensure ordering across contexts. */ @@ -4708,10 +4702,10 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_DrawOverlay(IWineD3DSurface *iface) { BOOL surface_is_offscreen(IWineD3DSurfaceImpl *surface) { - IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)surface->container; + IWineD3DSwapChainImpl *swapchain = surface->container.u.swapchain; /* Not on a swapchain - must be offscreen */ - if (!(surface->Flags & SFLAG_SWAPCHAIN)) return TRUE; + if (surface->container.type != WINED3D_CONTAINER_SWAPCHAIN) return TRUE; /* The front buffer is always onscreen */ if (surface == swapchain->front_buffer) return FALSE; diff --git a/dlls/wined3d/surface_base.c b/dlls/wined3d/surface_base.c index a215176808b..a7ac270b4ee 100644 --- a/dlls/wined3d/surface_base.c +++ b/dlls/wined3d/surface_base.c @@ -159,7 +159,7 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetContainer(IWineD3DSurface* iface, REFI } /* Standalone surfaces return the device as container. */ - if (This->container) container = This->container; + if (This->container.u.base) container = This->container.u.base; else container = (IWineD3DBase *)This->resource.device; TRACE("Relaying to QueryInterface\n"); diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index 7657552f347..ea38bf107aa 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -48,7 +48,7 @@ static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface) * the last buffer to be destroyed, FindContext() depends on that. */ if (This->front_buffer) { - surface_set_container(This->front_buffer, NULL); + surface_set_container(This->front_buffer, WINED3D_CONTAINER_NONE, NULL); if (IWineD3DSurface_Release((IWineD3DSurface *)This->front_buffer)) { WARN("(%p) Something's still holding the front buffer (%p).\n", @@ -63,7 +63,7 @@ static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface) while (i--) { - surface_set_container(This->back_buffers[i], NULL); + surface_set_container(This->back_buffers[i], WINED3D_CONTAINER_NONE, NULL); if (IWineD3DSurface_Release((IWineD3DSurface *)This->back_buffers[i])) WARN("(%p) Something's still holding back buffer %u (%p).\n", This, i, This->back_buffers[i]); @@ -731,7 +731,7 @@ HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface goto err; } - surface_set_container(swapchain->front_buffer, (IWineD3DBase *)swapchain); + surface_set_container(swapchain->front_buffer, WINED3D_CONTAINER_SWAPCHAIN, (IWineD3DBase *)swapchain); swapchain->front_buffer->Flags |= SFLAG_SWAPCHAIN; if (surface_type == SURFACE_OPENGL) { @@ -847,7 +847,7 @@ HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface goto err; } - surface_set_container(swapchain->back_buffers[i], (IWineD3DBase *)swapchain); + surface_set_container(swapchain->back_buffers[i], WINED3D_CONTAINER_SWAPCHAIN, (IWineD3DBase *)swapchain); swapchain->back_buffers[i]->Flags |= SFLAG_SWAPCHAIN; } } @@ -869,7 +869,7 @@ HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface goto err; } - surface_set_container(device->auto_depth_stencil, NULL); + surface_set_container(device->auto_depth_stencil, WINED3D_CONTAINER_NONE, NULL); } } diff --git a/dlls/wined3d/swapchain_gdi.c b/dlls/wined3d/swapchain_gdi.c index a270b81298c..250485b06a3 100644 --- a/dlls/wined3d/swapchain_gdi.c +++ b/dlls/wined3d/swapchain_gdi.c @@ -39,7 +39,7 @@ static void WINAPI IWineGDISwapChainImpl_Destroy(IWineD3DSwapChain *iface) /* release the ref to the front and back buffer parents */ if (This->front_buffer) { - surface_set_container(This->front_buffer, NULL); + surface_set_container(This->front_buffer, WINED3D_CONTAINER_NONE, NULL); if (IWineD3DSurface_Release((IWineD3DSurface *)This->front_buffer) > 0) { WARN("(%p) Something's still holding the front buffer\n",This); @@ -51,7 +51,7 @@ static void WINAPI IWineGDISwapChainImpl_Destroy(IWineD3DSwapChain *iface) UINT i; for (i = 0; i < This->presentParms.BackBufferCount; ++i) { - surface_set_container(This->back_buffers[i], NULL); + surface_set_container(This->back_buffers[i], WINED3D_CONTAINER_NONE, NULL); if (IWineD3DSurface_Release((IWineD3DSurface *)This->back_buffers[i])) { WARN("(%p) Something's still holding the back buffer\n",This); diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 71478504009..e3c0bb50e24 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -119,7 +119,7 @@ static void texture_cleanup(IWineD3DTextureImpl *This) surface_set_texture_name(surface, 0, TRUE); surface_set_texture_name(surface, 0, FALSE); surface_set_texture_target(surface, 0); - surface_set_container(surface, NULL); + surface_set_container(surface, WINED3D_CONTAINER_NONE, NULL); IWineD3DSurface_Release((IWineD3DSurface *)surface); } } @@ -611,7 +611,7 @@ HRESULT texture_init(IWineD3DTextureImpl *texture, UINT width, UINT height, UINT return hr; } - surface_set_container((IWineD3DSurfaceImpl *)surface, (IWineD3DBase *)texture); + surface_set_container((IWineD3DSurfaceImpl *)surface, WINED3D_CONTAINER_TEXTURE, (IWineD3DBase *)texture); surface_set_texture_target((IWineD3DSurfaceImpl *)surface, texture->target); texture->baseTexture.sub_resources[i] = (IWineD3DResourceImpl *)surface; TRACE("Created surface level %u @ %p.\n", i, surface); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 7f59d2423d2..384af7db2a9 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2000,6 +2000,23 @@ typedef struct IWineD3DClipperImpl HWND hWnd; } IWineD3DClipperImpl; +enum wined3d_container_type +{ + WINED3D_CONTAINER_NONE = 0, + WINED3D_CONTAINER_SWAPCHAIN, + WINED3D_CONTAINER_TEXTURE, +}; + +struct wined3d_subresource_container +{ + enum wined3d_container_type type; + union + { + struct IWineD3DBase *base; + struct IWineD3DSwapChainImpl *swapchain; + struct IWineD3DBaseTextureImpl *texture; + } u; +}; /***************************************************************************** * IWineD3DSurface implementation structure @@ -2011,7 +2028,7 @@ struct IWineD3DSurfaceImpl IWineD3DResourceClass resource; /* IWineD3DSurface fields */ - IWineD3DBase *container; + struct wined3d_subresource_container container; WINED3DSURFACET_DESC currentDesc; IWineD3DPaletteImpl *palette; /* D3D7 style palette handling */ PALETTEENTRY *palette9; /* D3D8/9 style palette handling */ @@ -2087,7 +2104,8 @@ void surface_prepare_texture(IWineD3DSurfaceImpl *surface, const struct wined3d_gl_info *gl_info, BOOL srgb) DECLSPEC_HIDDEN; void surface_set_compatible_renderbuffer(IWineD3DSurfaceImpl *surface, unsigned int width, unsigned int height) DECLSPEC_HIDDEN; -void surface_set_container(IWineD3DSurfaceImpl *surface, IWineD3DBase *container) DECLSPEC_HIDDEN; +void surface_set_container(IWineD3DSurfaceImpl *surface, + enum wined3d_container_type type, IWineD3DBase *container) DECLSPEC_HIDDEN; void surface_set_texture_name(IWineD3DSurfaceImpl *surface, GLuint name, BOOL srgb_name) DECLSPEC_HIDDEN; void surface_set_texture_target(IWineD3DSurfaceImpl *surface, GLenum target) DECLSPEC_HIDDEN; void surface_translate_frontbuffer_coords(IWineD3DSurfaceImpl *surface, HWND window, RECT *rect) DECLSPEC_HIDDEN; -- 2.11.4.GIT