diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index ea3d1309125..6d40caead17 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -7362,3 +7362,29 @@ void IWineD3DDeviceImpl_MarkStateDirty(IWineD3DDeviceImpl *This, DWORD state) { context->isStateDirty[idx] |= (1 << shift); } } + +void get_drawable_size_pbuffer(IWineD3DSurfaceImpl *This, UINT *width, UINT *height) { + IWineD3DDeviceImpl *dev = This->resource.wineD3DDevice; + /* The drawable size of a pbuffer render target is the current pbuffer size + */ + *width = dev->pbufferWidth; + *height = dev->pbufferHeight; +} + +void get_drawable_size_fbo(IWineD3DSurfaceImpl *This, UINT *width, UINT *height) { + /* The drawable size of a fbo target is the opengl texture size, which is the power of two size + */ + *width = This->pow2Width; + *height = This->pow2Height; +} + +void get_drawable_size_backbuffer(IWineD3DSurfaceImpl *This, UINT *width, UINT *height) { + IWineD3DDeviceImpl *dev = This->resource.wineD3DDevice; + /* The drawable size of a backbuffer / aux buffer offscreen target is the size of the + * current context's drawable, which is the size of the back buffer of the swapchain + * the active context belongs to. The back buffer of the swapchain is stored as the + * surface the context belongs to. + */ + *width = ((IWineD3DSurfaceImpl *) dev->activeContext->surface)->currentDesc.Width; + *height = ((IWineD3DSurfaceImpl *) dev->activeContext->surface)->currentDesc.Height; +} diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 0ff1bc7cf8e..6d451648e95 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -3480,6 +3480,14 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_PrivateSetup(IWineD3DSurface *iface) { This->glRect.bottom = This->pow2Height; } + if(This->resource.usage & WINED3DUSAGE_RENDERTARGET) { + switch(wined3d_settings.offscreen_rendering_mode) { + case ORM_FBO: This->get_drawable_size = get_drawable_size_fbo; break; + case ORM_PBUFFER: This->get_drawable_size = get_drawable_size_pbuffer; break; + case ORM_BACKBUFFER: This->get_drawable_size = get_drawable_size_backbuffer; break; + } + } + This->Flags |= SFLAG_INSYSMEM; return WINED3D_OK; @@ -3877,6 +3885,28 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D return WINED3D_OK; } +HRESULT WINAPI IWineD3DSurfaceImpl_SetContainer(IWineD3DSurface *iface, IWineD3DBase *container) { + IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface; + IWineD3DSwapChain *swapchain = NULL; + + /* Update the drawable size method */ + if(container) { + IWineD3DBase_QueryInterface(container, &IID_IWineD3DSwapChain, (void **) &swapchain); + } + if(swapchain) { + This->get_drawable_size = get_drawable_size_swapchain; + IWineD3DSwapChain_Release(swapchain); + } else if(This->resource.usage & WINED3DUSAGE_RENDERTARGET) { + switch(wined3d_settings.offscreen_rendering_mode) { + case ORM_FBO: This->get_drawable_size = get_drawable_size_fbo; break; + case ORM_PBUFFER: This->get_drawable_size = get_drawable_size_pbuffer; break; + case ORM_BACKBUFFER: This->get_drawable_size = get_drawable_size_backbuffer; break; + } + } + + return IWineD3DBaseSurfaceImpl_SetContainer(iface, container); +} + const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl = { /* IUnknown */ @@ -3924,7 +3954,7 @@ const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl = IWineD3DSurfaceImpl_LoadTexture, IWineD3DSurfaceImpl_BindTexture, IWineD3DSurfaceImpl_SaveSnapshot, - IWineD3DBaseSurfaceImpl_SetContainer, + IWineD3DSurfaceImpl_SetContainer, IWineD3DSurfaceImpl_SetGlTextureDesc, IWineD3DSurfaceImpl_GetGlDesc, IWineD3DSurfaceImpl_GetData, diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index 2eaa81258ef..d27e7077a5d 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -585,3 +585,11 @@ WineD3DContext *IWineD3DSwapChainImpl_CreateContextForThread(IWineD3DSwapChain * TRACE("Returning context %p\n", ctx); return ctx; } + +void get_drawable_size_swapchain(IWineD3DSurfaceImpl *This, UINT *width, UINT *height) { + /* The drawable size of an onscreen drawable is the surface size. + * (Actually: The window size, but the surface is created in window size) + */ + *width = This->currentDesc.Width; + *height = This->currentDesc.Height; +} diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 3b87fa0ecf7..c0e12652fa1 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1087,6 +1087,9 @@ struct IWineD3DSurfaceImpl UINT pow2Width; UINT pow2Height; + /* A method to retrieve the drawable size. Not in the Vtable to make it changeable */ + void (*get_drawable_size)(IWineD3DSurfaceImpl *This, UINT *width, UINT *height); + /* Oversized texture */ RECT glRect; @@ -1162,6 +1165,11 @@ void WINAPI IWineD3DBaseSurfaceImpl_BindTexture(IWineD3DSurface *iface); const void *WINAPI IWineD3DSurfaceImpl_GetData(IWineD3DSurface *iface); +void get_drawable_size_swapchain(IWineD3DSurfaceImpl *This, UINT *width, UINT *height); +void get_drawable_size_backbuffer(IWineD3DSurfaceImpl *This, UINT *width, UINT *height); +void get_drawable_size_pbuffer(IWineD3DSurfaceImpl *This, UINT *width, UINT *height); +void get_drawable_size_fbo(IWineD3DSurfaceImpl *This, UINT *width, UINT *height); + /* Surface flags: */ #define SFLAG_OVERSIZE 0x00000001 /* Surface is bigger than gl size, blts only */ #define SFLAG_CONVERTED 0x00000002 /* Converted for color keying or Palettized */