Implement render targets using either textures, swapchains or
standalone surfaces.

diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index d57f989..e1f3f67 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -374,53 +374,61 @@
 /* TODO: move to wineD3D */
 HRESULT  WINAPI  IDirect3DDevice9Impl_SetRenderTarget(LPDIRECT3DDEVICE9 iface, DWORD RenderTargetIndex, IDirect3DSurface9* pRenderTarget) {
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
-    HRESULT hr = S_OK;
-
-    /* If pRenderTarget == NULL, it seems to default to back buffer */
-    if (pRenderTarget == NULL) pRenderTarget = (IDirect3DSurface9*) This->backBuffer;
- 
-    /* If we are trying to set what we already have, don't bother */
-    if ((IDirect3DSurface9Impl*) pRenderTarget == This->renderTarget) {
-      TRACE("Trying to do a NOP SetRenderTarget operation\n");
-    } else {
-      /* Otherwise, set the render target up */
-      TRACE("(%p) : newRender@%p (default is backbuffer=(%p))\n", This, pRenderTarget, This->backBuffer);
-      hr = E_FAIL; /* not supported yet */
-    }
-
-   return hr;
+    IDirect3DSurface9Impl *pSurface = (IDirect3DSurface9Impl*)pRenderTarget;
+    TRACE("(%p) Relay\n" , This);
+    return IWineD3DDevice_SetRenderTarget(This->WineD3DDevice,RenderTargetIndex,(IWineD3DSurface*)pSurface->wineD3DSurface);
 }
 
-/* TODO: move to wineD3D */
-HRESULT  WINAPI  IDirect3DDevice9Impl_GetRenderTarget(LPDIRECT3DDEVICE9 iface, DWORD RenderTargetIndex, IDirect3DSurface9** ppRenderTarget) {
+HRESULT  WINAPI  IDirect3DDevice9Impl_GetRenderTarget(LPDIRECT3DDEVICE9 iface, DWORD RenderTargetIndex, IDirect3DSurface9 **ppRenderTarget) {
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
-    TRACE("(%p)->returning (%p) default is backbuffer=(%p)\n", This, This->renderTarget, This->backBuffer);
-    *ppRenderTarget = (LPDIRECT3DSURFACE9) This->renderTarget;
-    IDirect3DSurface9Impl_AddRef((LPDIRECT3DSURFACE9) *ppRenderTarget);
-    return D3D_OK;
+    HRESULT hr = D3D_OK;
+    IWineD3DSurface *pRenderTarget;
+
+    TRACE("(%p) Relay\n" , This);
+
+    if (ppRenderTarget == NULL) {
+        return D3DERR_INVALIDCALL;
+    }
+    hr=IWineD3DDevice_GetRenderTarget(This->WineD3DDevice,RenderTargetIndex,&pRenderTarget);
+
+    if (hr == D3D_OK && pRenderTarget != NULL) {
+        IWineD3DResource_GetParent((IWineD3DResource *)pRenderTarget,(IUnknown**)ppRenderTarget);
+        IWineD3DResource_Release((IWineD3DResource *)pRenderTarget);
+    } else {
+        FIXME("Call to IWineD3DDevice_GetRenderTarget failed\n");
+        *ppRenderTarget = NULL;
+    }
+    return hr;
 }
 
-/* TODO: move to wineD3D */
 HRESULT  WINAPI  IDirect3DDevice9Impl_SetDepthStencilSurface(LPDIRECT3DDEVICE9 iface, IDirect3DSurface9* pZStencilSurface) {
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
-    HRESULT hr = S_OK;
-    /* If we are trying to set what we already have, don't bother */
-    if ((IDirect3DSurface9Impl*) pZStencilSurface == This->stencilBufferTarget) {
-      TRACE("Trying to do a NOP SetDepthStencilSurface operation\n");
-    } else {
-      /* Otherwise, set the target up */
-      TRACE("(%p) : newDepthStencil@%p (default is stencilbuffer=(%p))\n", This, pZStencilSurface, This->depthStencilBuffer);
-      hr = E_FAIL; /* not supported yet */
-    }
-    return D3D_OK;
+    IDirect3DSurface9Impl *pSurface;
+
+    TRACE("(%p) Relay\n" , This);
+
+    pSurface = (IDirect3DSurface9Impl*)pZStencilSurface;
+    return IWineD3DDevice_SetDepthStencilSurface(This->WineD3DDevice,NULL==pSurface?NULL:(IWineD3DSurface*)pSurface->wineD3DSurface);
 }
 
-/* TODO: move to wineD3D */
-HRESULT  WINAPI  IDirect3DDevice9Impl_GetDepthStencilSurface(LPDIRECT3DDEVICE9 iface, IDirect3DSurface9** ppZStencilSurface) {
+HRESULT  WINAPI  IDirect3DDevice9Impl_GetDepthStencilSurface(LPDIRECT3DDEVICE9 iface, IDirect3DSurface9 **ppZStencilSurface) {
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
-    TRACE("(%p)->returning (%p) default is stencilbuffer=(%p)\n", This, This->stencilBufferTarget, This->depthStencilBuffer);
-    *ppZStencilSurface = (LPDIRECT3DSURFACE9) This->stencilBufferTarget;
-    if (NULL != *ppZStencilSurface) IDirect3DSurface9Impl_AddRef((LPDIRECT3DSURFACE9) *ppZStencilSurface);
+    HRESULT hr = D3D_OK;
+    IWineD3DSurface *pZStencilSurface;
+
+    TRACE("(%p) Relay\n" , This);
+    if(ppZStencilSurface == NULL){
+        return D3DERR_INVALIDCALL;
+    }
+
+    hr=IWineD3DDevice_GetDepthStencilSurface(This->WineD3DDevice,&pZStencilSurface);
+    if(hr == D3D_OK && pZStencilSurface != NULL){
+        IWineD3DResource_GetParent((IWineD3DResource *)pZStencilSurface,(IUnknown**)ppZStencilSurface);
+        IWineD3DResource_Release((IWineD3DResource *)pZStencilSurface);
+    }else{
+        FIXME("Call to IWineD3DDevice_GetRenderTarget failed\n");
+        *ppZStencilSurface = NULL;
+    }
     return D3D_OK;
 }
 
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index cd4ad15..5c226f3 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -4355,7 +4355,7 @@
         /* If the container of the rendertarget is a texture then we need to save the data from the pbuffer */
         IUnknown *targetContainer = NULL;
         if (D3D_OK == IWineD3DSurface_GetContainer(This->renderTarget, &IID_IWineD3DBaseTexture, (void **)&targetContainer)) {
-            TRACE("RenderTarget is either standalone of a texture.\n");
+            TRACE("(%p) : Texture rendertarget %p\n", This ,This->renderTarget);
             /** always dirtify for now. we must find a better way to see that surface have been modified
             (Modifications should will only occur via draw-primitive, but we do need better locking
             switching to render-to-texture should remove the overhead though.
@@ -4365,6 +4365,15 @@
             IWineD3DBaseTexture_PreLoad((IWineD3DBaseTexture *)targetContainer);
             IWineD3DSurface_SetPBufferState(This->renderTarget, FALSE /* inPBuffer */, FALSE /* inTexture */);
             IUnknown_Release(targetContainer);
+        } else
+        if (D3D_OK == IWineD3DSurface_GetContainer(This->renderTarget, &IID_IWineD3DDevice, (void **)&targetContainer)){
+                /* The surface is stand-alone, so doesn't currently have a context of it's own */
+                TRACE("(%p) : standalone rendertarget %p\n", This, This->renderTarget);
+                IWineD3DSurface_SetPBufferState(This->renderTarget, TRUE /* inPBuffer */, FALSE /* inTexture */);
+                IWineD3DSurface_AddDirtyRect(This->renderTarget, NULL);
+                IWineD3DSurface_PreLoad(This->renderTarget);
+                IWineD3DSurface_SetPBufferState(This->renderTarget, FALSE /* inPBuffer */, FALSE /* inTexture */);
+                IUnknown_Release(targetContainer);
         }
 
     }
@@ -4804,18 +4813,486 @@
     return D3D_OK;
 }
 
-HRESULT WINAPI IWineD3DDeviceImpl_SetRenderTarget(IWineD3DDevice *iface, DWORD RenderTargetIndex, IWineD3DSurface *pRenderTarget){
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
+/* internal static helper functions */
+HRESULT WINAPI static IWineD3DDeviceImpl_ActiveRender(IWineD3DDevice* iface,
+                                                IWineD3DSurface *RenderSurface);
 
-    FIXME("(%p) : stub\n", This);
-    return D3D_OK;
+HRESULT WINAPI static IWineD3DDeviceImpl_CleanRender(IWineD3DDevice* iface, IWineD3DSwapChainImpl *swapchain);
+
+HRESULT WINAPI IWineD3DDeviceImpl_SetRenderTarget(IWineD3DDevice *iface, DWORD RenderTargetIndex, IWineD3DSurface *pRenderTarget){
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+    HRESULT  hr = D3D_OK;
+    WINED3DVIEWPORT viewport;
+
+    TRACE("(%p) Swapping rendertarget\n",This);
+    if (RenderTargetIndex>0) {
+        FIXME("(%p) Render targets other than the first are not supported\n",This);
+        RenderTargetIndex=0;
+    }
+
+    /* MSDN says that null disables the render target
+    but a device must always be associatated with a render target
+    nope MSDN says that we return invalid call to a null rendertarget with an index of 0
+
+    see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/programmingguide/AdvancedTopics/PixelPipe/MultipleRenderTarget.asp
+    for more details
+    */
+    if (RenderTargetIndex == 0 && pRenderTarget == NULL) {
+        FIXME("Trying to set render target 0 to NULL\n");
+        return D3DERR_INVALIDCALL;
+    }
+    /* TODO: raplce Impl* usage with interface usage */
+    if (!((IWineD3DSurfaceImpl *)pRenderTarget)->resource.usage & D3DUSAGE_RENDERTARGET) {
+        FIXME("(%p)Trying to set the render target to a surface(%p) that wasn't created with a usage of D3DUSAGE_RENDERTARGET\n",This ,pRenderTarget);
+        return D3DERR_INVALIDCALL;
+    }
+    /** TODO: check that the depth stencil format matches the render target, this is only done in debug
+     *        builds, but I think wine counts as a 'debug' build for now.
+      ******************************/
+    /* If we are trying to set what we already have, don't bother */
+    if (pRenderTarget == This->renderTarget) {
+        TRACE("Trying to do a NOP SetRenderTarget operation\n");
+    } else {
+        /* Otherwise, set the render target up */
+        TRACE("clearing renderer\n");
+        /* IWineD3DDeviceImpl_CleanRender(iface); */
+        /* OpenGL doesn't support 'sharing' of the stencilBuffer so we may incure an extra memory overhead
+        depending on the renter target implemenattion being used.
+        A shared context implementation will share all buffers between all rendertargets (including swapchains),
+        implemenations that use serperate pbuffers for different swapchains or rendertargets will have to duplicate the
+        stencil buffer and incure an extra memory overhead */
+        hr = IWineD3DDeviceImpl_ActiveRender(iface, pRenderTarget);
+    }
+
+    if (SUCCEEDED(hr)) {
+        /* Finally, reset the viewport as the MSDN states. */
+        /* TODO: Repalace impl usage */
+        viewport.Height = ((IWineD3DSurfaceImpl *)This->renderTarget)->currentDesc.Height;
+        viewport.Width  = ((IWineD3DSurfaceImpl *)This->renderTarget)->currentDesc.Width;
+        viewport.X      = 0;
+        viewport.Y      = 0;
+        viewport.MaxZ   = 1.0f;
+        viewport.MinZ   = 0.0f;
+        IWineD3DDeviceImpl_SetViewport(iface, &viewport);
+    }else{
+        FIXME("Unknown error setting the render target\n");
+    }
+    return hr;
 }
 
 HRESULT WINAPI IWineD3DDeviceImpl_SetDepthStencilSurface(IWineD3DDevice *iface, IWineD3DSurface *pNewZStencil){
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+    HRESULT  hr = D3D_OK;
+    WINED3DVIEWPORT viewport;
+    IWineD3DSurface *tmp;
 
-    FIXME("(%p) : stub\n", This);
-    return D3D_OK;
+    TRACE("(%p) Swapping z-buffer\n",This);
+
+    if (pNewZStencil == This->stencilBufferTarget){
+        TRACE("Trying to do a NOP SetRenderTarget operation\n");
+    }else{
+        /** OpenGL doesn't support 'sharing' of the stencilBuffer so we may incure an extra memory overhead
+        * depending on the renter target implemenattion being used.
+        * A shared context implementation will share all buffers between all rendertargets (including swapchains),
+        * implemenations that use serperate pbuffers for different swapchains or rendertargets will have to duplicate the
+        * stencil buffer and incure an extra memory overhead
+         ******************************************************/
+
+
+        tmp = This->stencilBufferTarget;
+        This->stencilBufferTarget = pNewZStencil;
+        /* should we be calling the parent or the wined3d surface? */
+        if (NULL != This->stencilBufferTarget) IWineD3DSurface_AddRef(This->stencilBufferTarget);
+        if (NULL != tmp) IWineD3DSurface_Release(tmp);
+        hr = D3D_OK;
+        /** TODO: glEnable/glDisable on depth/stencil    depending on
+         *   pNewZStencil is NULL and the depth/stencil is enabled in d3d
+          **********************************************************/
+    }
+
+    if (SUCCEEDED(hr)) {
+        /* Finally, reset the viewport as the MSDN states.*/
+        /* TODO: get ridd of Impl usage */
+        viewport.Height = ((IWineD3DSurfaceImpl *)This->renderTarget)->currentDesc.Height;
+        viewport.Width  = ((IWineD3DSurfaceImpl *)This->renderTarget)->currentDesc.Width;
+        viewport.X      = 0;
+        viewport.Y      = 0;
+        viewport.MaxZ   = 1.0f;
+        viewport.MinZ   = 0.0f;
+        IWineD3DDeviceImpl_SetViewport(iface, &viewport);
+    }
+
+    return hr;
+}
+
+
+/* Internal functions not in DirectX */
+ /** TODO: move this off to the opengl context manager
+ *(the swapchain doesn't need to know anything about offscreen rendering!)
+  ****************************************************/
+
+HRESULT WINAPI IWineD3DDeviceImpl_CleanRender(IWineD3DDevice* iface, IWineD3DSwapChainImpl *swapchain)
+{
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+#if defined(GL_VERSION_1_3) /* @see comments on ActiveRender */
+
+    TRACE("(%p), %p\n", This, swapchain);
+
+    if (swapchain->win != swapchain->drawable) {
+        ENTER_GL();
+        if (swapchain->glCtx != swapchain->render_ctx) {
+            FIXME("Destroying context %p \n", swapchain->render_ctx);
+            glXDestroyContext(swapchain->display, swapchain->render_ctx);
+
+        }
+        FIXME("glXDestroyPbuffer %ld \n", swapchain->drawable);
+        glXDestroyPbuffer(swapchain->display, swapchain->drawable);
+#endif
+        LEAVE_GL();
+        /* Set everything back to the way that it ws */
+        swapchain->render_ctx = swapchain->glCtx;
+        swapchain->drawable = swapchain->win;
+    }
+  return D3D_OK;
+}
+
+/** FIXME: This is currently used called whenever SetRenderTarget or SetStencilBuffer are called
+* the functiolaity needs splitting up so that we don't do more than we should do.
+* this only seems to affect performance a little.
+ ******************************/
+HRESULT WINAPI IWineD3DDeviceImpl_ActiveRender(IWineD3DDevice* iface,
+                                               IWineD3DSurface *RenderSurface) {
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+#ifndef USE_RENDER_MANAGER
+
+  IWineD3DSurface *StencilSurface = This->stencilBufferTarget;
+  HRESULT ret =  D3DERR_INVALIDCALL;
+  /**
+   * Currently only active for GLX >= 1.3
+   * for others versions we'll have to use GLXPixmaps
+   *
+   * normally we must test GLX_VERSION_1_3 but nvidia headers are not correct
+   * as they implements GLX 1.3 but only define GLX_VERSION_1_2
+   * so only check OpenGL version
+   * ..........................
+   * I don't belive that it is a problem with NVidia headers,
+   * XFree only supports GLX1.2, nVidia (and ATI to some extent) provide 1.3 functions
+   * in GLX 1.2, there is no mention of the correct way to tell if the extensions are provided.
+   * ATI Note:
+   * Your application will report GLX version 1.2 on glXQueryVersion.
+   * However, it is safe to call the GLX 1.3 functions as described below.
+   */
+#if defined(GL_VERSION_1_3)
+
+    /** TODO: we only need to look up the configuration !IF! we are setting the target to a texture **/
+    GLXFBConfig* cfgs = NULL;
+    int nCfgs = 0;
+    int attribs[256];
+    int nAttribs = 0;
+    IWineD3DSwapChain     *currentSwapchain;
+    IWineD3DSwapChainImpl *swapchain;
+    /** TODO: get rid of Impl usage we should always create a zbuffer/stencil with our contexts if pussible,
+    * but switch them off if the StencilSurface is set to NULL
+    ** *********************************************************/
+    D3DFORMAT BackBufferFormat = ((IWineD3DSurfaceImpl *) RenderSurface)->resource.format;
+    D3DFORMAT StencilBufferFormat = (NULL != StencilSurface) ? ((IWineD3DSurfaceImpl *) StencilSurface)->resource.format : 0;
+#if 0
+    UINT Width = ((IWineD3DSurfaceImpl *) RenderSurface)->currentDesc.Width;
+    UINT Height = ((IWineD3DSurfaceImpl *) RenderSurface)->currentDesc.Height;
+#endif
+    IWineD3DSurface *tmp;
+
+    /**TODO:
+        if StencilSurface == NULL && zBufferTarget != NULL then swtich the zbuffer off,
+        it StencilSurface != NULL && zBufferTarget == NULL switch it on
+    */
+
+#define PUSH1(att)        attribs[nAttribs++] = (att);
+#define PUSH2(att,value)  attribs[nAttribs++] = (att); attribs[nAttribs++] = (value);
+
+    /* PUSH2(GLX_BIND_TO_TEXTURE_RGBA_ATI, True); examples of this are few and far between (but I've got a nice working one!)*/
+
+    /** TODO: remove the reff to Impl (context manager should fis this!) **/
+    IWineD3DSwapChainImpl *impSwapChain;
+    IWineD3DDevice_GetSwapChain(iface, 0, (IWineD3DSwapChain **)&impSwapChain);
+    if (NULL == impSwapChain){ /* NOTE: This should NEVER fail */
+        ERR("(%p) Failed to get a the implicite swapchain\n", iface);
+    }
+
+    ENTER_GL();
+
+    PUSH2(GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT);
+    PUSH2(GLX_X_RENDERABLE,  TRUE);
+    PUSH2(GLX_DOUBLEBUFFER, TRUE);
+    TRACE("calling makeglcfg\n");
+    D3DFmtMakeGlCfg(BackBufferFormat, StencilBufferFormat, attribs, &nAttribs, FALSE /* alternate */);
+
+    PUSH1(None);
+
+
+    TRACE("calling chooseFGConfig\n");
+    cfgs = glXChooseFBConfig(impSwapChain->display, DefaultScreen(impSwapChain->display),
+                                                     attribs, &nCfgs);
+
+    if (!cfgs){ /* OK we didn't find the exact config, so use any reasonably match */
+        /* TODO: fill in the 'requested' and 'current' depths, also make sure that's
+           why we failed and only show this message once! */
+        MESSAGE("Failed to find exact match, finding alternative but you may suffer performance issues, try changing xfree's depth to match the requested depth\n"); /**/
+        nAttribs = 0;
+        PUSH2(GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT);
+       /* PUSH2(GLX_X_RENDERABLE,  TRUE); */
+        PUSH2(GLX_RENDER_TYPE,   GLX_RGBA_BIT);
+        PUSH2(GLX_DOUBLEBUFFER, FALSE);
+        TRACE("calling makeglcfg\n");
+        D3DFmtMakeGlCfg(BackBufferFormat, StencilBufferFormat, attribs, &nAttribs, TRUE /* alternate */);
+        PUSH1(None);
+        cfgs = glXChooseFBConfig(impSwapChain->display, DefaultScreen(impSwapChain->display),
+                                                        attribs, &nCfgs);
+    }
+
+#if 0
+#ifdef EXTRA_TRACES
+        int i;
+        for (i = 0; i < nCfgs; ++i) {
+            TRACE("for (%u,%s)/(%u,%s) found config[%d]@%p\n", BackBufferFormat,
+            debug_d3dformat(BackBufferFormat), StencilBufferFormat,
+            debug_d3dformat(StencilBufferFormat), i, cfgs[i]);
+        }
+#endif
+#endif
+    if (NULL != This->renderTarget) {
+#ifdef EXTRA_TRACES
+        glFlush();
+        vcheckGLcall("glFlush");
+        /** This is only usefuly if the old render target was a swapchain,
+        * we need to supercede this with a function that displays
+        * the current buffer on the screen. This is easy to do in glx1.3 but
+        * we need to do copy-write pixels in glx 1.2.
+         ************************************************/
+        glXSwapBuffers(impSwapChain->display, impSwapChain->drawable);
+
+        printf("Hit Enter to get next frame ...\n");
+        getchar();
+#endif
+    }
+
+    if (IWineD3DSurface_GetContainer(This->renderTarget, &IID_IWineD3DSwapChain, (void **)&currentSwapchain) != D3D_OK){
+        /* the selected render target doesn't belong to a swapchain, so use the devices implicite swapchain */
+        IWineD3DDevice_GetSwapChain(iface, 0, &currentSwapchain);
+    }
+
+    /**
+    * TODO: remove the use of IWineD3DSwapChainImpl, a context manager will help since it will replace the
+    *  renderTarget = swapchain->backBuffer bit and anything to do with *glContexts
+     **********************************************************************/
+    if (IWineD3DSurface_GetContainer(RenderSurface, &IID_IWineD3DSwapChain, (void **)&swapchain) == D3D_OK){
+        /* We also need to make sure that the lights &co are also in the context of the swapchains */
+        /* FIXME: If the render target gets sent to the frontBuffer should be be presenting it raw? */
+        TRACE("making swapchain active\n");
+        if (RenderSurface != This->renderTarget){
+            if (RenderSurface ==  swapchain->backBuffer){
+            } else {
+                /* This could be flagged so that some operations work directly with the front buffer */
+                FIXME("Attempting to set the  renderTarget to the frontBuffer\n");
+            }
+            if (glXMakeCurrent(swapchain->display, swapchain->win, swapchain->glCtx)
+            == False) {
+                TRACE("Error in setting current context: context %p drawable %ld !\n",
+                       impSwapChain->glCtx, impSwapChain->win);
+            }
+
+
+#if 0 /* TODO: apply the state block to the 'possibly' new context. */
+            BOOL oldRecording;
+            IWineD3DStateBlockImpl *oldUpdateStateBlock;
+            oldUpdateStateBlock = This->updateStateBlock;
+            oldRecording= This->isRecordingState;
+            This->isRecordingState = FALSE;
+            This->updateStateBlock = This->stateBlock;
+            IWineD3DStateBlock_Apply((IWineD3DStateBlock *)This->stateBlock);
+
+            This->isRecordingState = oldRecording;
+            This->updateStateBlock = oldUpdateStateBlock;
+#endif
+
+            IWineD3DDeviceImpl_CleanRender(iface, (IWineD3DSwapChainImpl *)currentSwapchain);
+        }
+        checkGLcall("glXMakeContextCurrent");
+
+        IWineD3DSwapChain_Release((IWineD3DSwapChain *)swapchain);
+    }
+#if 0
+    else
+    if (NULL != cfgs  &&
+               (((IWineD3DSwapChainImpl *)currentSwapchain)->drawable == ((IWineD3DSwapChainImpl *)currentSwapchain)->win
+                ||  BackBufferFormat != ((IWineD3DSurfaceImpl *)This->renderTarget)->currentDesc.Format
+                || (Width > ((IWineD3DSurfaceImpl *)This->renderTarget)->currentDesc.Width
+                ||  Height > ((IWineD3DSurfaceImpl *)This->renderTarget)->currentDesc.Height))) {
+
+        /** ********************************************************************
+        * This code is far too leaky to be usefull IWineD3DDeviceImpl_CleanRender
+        * doesn't seem to work properly and creating a new context Every time is 'extream' overkill.
+        * The code does however work, and should be moved to a context manager to
+        * manage caching of pbuffers or render to texture are appropriate.
+        *
+        * There are some real speed vs compatability issues here:
+        *    we should really use a new context for every texture, but that eats ram.
+        *    we should also be restoring the texture to the pbuffer but that eats CPU
+        *    we can also 'reuse' the current pbuffer if the size is larger than the requested buffer,
+        *    but if this means reusing the display backbuffer then we need to make sure that
+        *    states are correctly preserved.
+        * In many cases I would expect that we can 'skip' some functions, such as preserving states,
+        * and gain a good performance increase at the cost of compatability.
+        * I would suggest that, when this is the case, a user configurable flag be made
+        * available, alowing the user to choose the best emmulated experiance for them.
+         *********************************************************************/
+
+        /**
+        * TODO: support for faces of cube textures, possibly volumes
+        * (this should be easy for ATI as I have examples)
+        **/
+
+        GLXContext  newContext;
+        Drawable    newDrawable;
+        XVisualInfo *visinfo;
+
+        TRACE("making new buffer\n");
+        nAttribs = 0;
+        PUSH2(GLX_PBUFFER_WIDTH,  Width);
+        PUSH2(GLX_PBUFFER_HEIGHT, Height);
+
+#if 0 /* ATI render to texture support */
+        PUSH2(GLX_LARGEST_PBUFFER, True);/* This is ignored by ATI */
+        PUSH2(GLX_TEXTURE_FORMAT_ATI, GLX_TEXTURE_RGBA_ATI);
+        PUSH2(GLX_TEXTURE_TARGET_ATI, cubemap? GLX_TEXTURE_CUBE_MAP_ATI : GLX_TEXTURE_2D_ATI);
+        PUSH2(GLX_MIPMAP_TEXTURE_ATI, mipmapped? True : False);
+#endif
+
+#if 0
+        /* TODO: discardable Pbuffer */
+        PUSH2(GLX_PRESERVED_CONTENTS, FALSE);
+#endif
+
+        PUSH1(None);
+        newDrawable = glXCreatePbuffer(impSwapChain->display, cfgs[0], attribs);
+
+        /** ****************************************
+        *GLX1.3 isn't supported by XFree 'yet' untill that point ATI emulates pBuffers
+        *they note:
+        *   In future releases, we may provide the calls glXCreateNewContext,
+        *   glXQueryDrawable and glXMakeContextCurrent.
+        *    so until then we have to use glXGetVisualFromFBConfig &co..
+         ********************************************/
+
+
+            visinfo = glXGetVisualFromFBConfig(impSwapChain->display, cfgs[0]);
+            if (!visinfo) {
+                ERR("Error: couldn't get an RGBA, double-buffered visual\n");
+            }
+            newContext = glXCreateContext(impSwapChain->display, visinfo, impSwapChain->glCtx,  GL_TRUE);
+            XFree(visinfo);
+
+        /* Make sure that the sorface exists as a glTexture */
+        IWineD3DSurface_PreLoad(RenderSurface);
+
+        newContext = glXCreateNewContext(impSwapChain->display, cfgs[0], GLX_RGBA_TYPE, impSwapChain->glCtx, TRUE);
+
+        if (NULL == newContext) {
+            ERR("cannot create glxContext\n");
+        }else{
+            /* Debug logging, (this function leaks), change to a TRACE when the leak is plugged */
+            FIXME("Created context %p drawable %ld \n", newContext, newDrawable);
+
+                if (glXMakeCurrent(impSwapChain->display, newDrawable, newContext) == False) {
+
+            TRACE("Error in setting current context: context %p drawable %ld\n", newContext, newDrawable);
+        }
+
+        /* TODO: find out what of the current context needs to be coppied accross */
+
+        checkGLcall("glXMakeContextCurrent");
+
+        /* clean renderer should become part of the context manager so I'm not goint to put in in SwapChain just to remove it */
+        IWineD3DDeviceImpl_CleanRender(iface, (IWineD3DSwapChainImpl *)currentSwapchain);
+        /** TODO: We may need to copy the bits into the buffer,
+        * this should !!ONLY!! be done if an operation is performed on the target
+        * without it being cleared and the buffer is not discardable.
+        * (basicly only bother preserving the contents if there's a possiblity that it will be reused)
+        ** *********************************************************************/
+        impSwapChain->drawable = newDrawable;
+        impSwapChain->render_ctx = newContext;
+
+        }
+
+    }
+#endif
+    /* clean up the current rendertargets swapchain (if it belonged to one) */
+    if (currentSwapchain != NULL){
+        IWineD3DSwapChain_Release((IWineD3DSwapChain *)currentSwapchain);
+    }
+
+    /* Were done with the opengl context management, setup the rendertargets */
+
+    tmp = This->renderTarget;
+    This->renderTarget = RenderSurface;
+    IWineD3DSurface_AddRef(This->renderTarget);
+    IWineD3DSurface_Release(tmp);
+
+
+
+    {
+        DWORD value;
+        /* The surface must be rendered upside down to cancel the flip produce by glCopyTexImage */
+        /* Check that the container is not a swapchain member */
+
+        IWineD3DSwapChain *tmpSwapChain;
+        if (D3D_OK != IWineD3DSurface_GetContainer(This->renderTarget, &IID_IWineD3DSwapChain, (void **)&tmpSwapChain)){
+            This->renderUpsideDown = TRUE;
+        }else{
+            This->renderUpsideDown = FALSE;
+            IWineD3DSwapChain_Release(tmpSwapChain);
+        }
+        /* Force updating the cull mode */
+        TRACE("setting render state\n");
+        IWineD3DDevice_GetRenderState(iface, WINED3DRS_CULLMODE, &value);
+        IWineD3DDevice_SetRenderState(iface, WINED3DRS_CULLMODE, value);
+
+        /* Force updating projection matrix */
+        This->last_was_rhw = FALSE;
+        This->proj_valid = FALSE;
+    }
+
+    ret = D3D_OK;
+
+    if (cfgs != NULL){
+        XFree(cfgs);
+    } else {
+        ERR("cannot get valides GLXFBConfig for (%u,%s)/(%u,%s)\n", BackBufferFormat,
+            debug_d3dformat(BackBufferFormat), StencilBufferFormat, debug_d3dformat(StencilBufferFormat));
+    }
+
+#undef PUSH1
+#undef PUSH2
+    if ( NULL != impSwapChain) {
+        IWineD3DSwapChain_Release((IWineD3DSwapChain *)impSwapChain);
+    }
+    LEAVE_GL();
+
+#endif
+#else
+
+    IWineD3DSurface *tmp;
+    /* This should be handled outside of this function */
+    tmp = This->renderTarget;
+    This->renderTarget = RenderSurface;
+    IWineD3DSurface_AddRef(This->renderTarget);
+    IWineD3DSurface_Release( tmp);
+    tmp = This->stencilBufferTarget;
+    This->stencilBufferTarget = StencilSurface;
+
+#endif
+    return ret;
+
 }
 
 HRESULT  WINAPI  IWineD3DDeviceImpl_SetCursorProperties(IWineD3DDevice* iface, UINT XHotSpot,
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 4938c88..d77151c 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -1572,7 +1572,6 @@
     object->createParms.BehaviorFlags  = BehaviourFlags;
 
     /* Initialize other useful values */
-    object->presentParms.BackBufferCount = 1; /* Opengl only supports one? */
     object->adapterNo                    = Adapter;
     object->devType                      = DeviceType;
 
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 9b9a2c5..7b4d4df 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -201,6 +201,9 @@
 
 HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, D3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
+    IWineD3DDeviceImpl  *myDevice = This->resource.wineD3DDevice;
+    IWineD3DSwapChainImpl *swapchain = NULL;
+    static UINT messages = 0; /* holds flags to disable fixme messages */
 
     /* fixme: should we really lock as such? */
     if (This->inTexture && This->inPBuffer) {
@@ -217,17 +220,23 @@
         /*return D3DERR_INVALIDCALL; */
     }
 
-    if (iface == This->resource.wineD3DDevice->backBuffer || iface == This->resource.wineD3DDevice->renderTarget || 
-		    iface == This->resource.wineD3DDevice->frontBuffer || iface == This->resource.wineD3DDevice->depthStencilBuffer) {
-        if (iface == This->resource.wineD3DDevice->backBuffer) {
+    IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapchain);
+
+    if (swapchain != NULL ||  iface == myDevice->renderTarget || iface == myDevice->depthStencilBuffer) {
+        if (swapchain != NULL && iface ==  swapchain->backBuffer) {
             TRACE("(%p, backBuffer) : rect@%p flags(%08lx), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, This->resource.allocatedMemory);
-        } else if (iface == This->resource.wineD3DDevice->frontBuffer) {
+        } else if (swapchain != NULL && iface ==  swapchain->frontBuffer) {
             TRACE("(%p, frontBuffer) : rect@%p flags(%08lx), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, This->resource.allocatedMemory);
-        } else if (iface == This->resource.wineD3DDevice->renderTarget) {
+        } else if (iface == myDevice->renderTarget) {
             TRACE("(%p, renderTarget) : rect@%p flags(%08lx), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, This->resource.allocatedMemory);
-        } else if (iface == This->resource.wineD3DDevice->depthStencilBuffer) {
+        } else if (iface == myDevice->depthStencilBuffer) {
             TRACE("(%p, stencilBuffer) : rect@%p flags(%08lx), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, This->resource.allocatedMemory);
         }
+
+        if (NULL != swapchain) {
+            IWineD3DSwapChain_Release((IWineD3DSwapChain *)swapchain);
+        }
+        swapchain = NULL;
     } else {
         TRACE("(%p) : rect@%p flags(%08lx), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, This->resource.allocatedMemory);
     }
@@ -240,7 +249,7 @@
     else if (This->resource.format == WINED3DFMT_DXT3 || This->resource.format == WINED3DFMT_DXT5) /* DXT3/5 is 16 bytes per block */
         pLockedRect->Pitch = (This->currentDesc.Width >> 2) << 4;
     else
-        pLockedRect->Pitch = This->bytesPerPixel * This->currentDesc.Width;  /* Bytes / row */    
+        pLockedRect->Pitch = This->bytesPerPixel * This->currentDesc.Width;  /* Bytes / row */
 
     if (NULL == pRect) {
         pLockedRect->pBits = This->resource.allocatedMemory;
@@ -270,38 +279,129 @@
 
     } else if (D3DUSAGE_RENDERTARGET & This->resource.usage && !(Flags&D3DLOCK_DISCARD)) { /* render surfaces */
 
-        if (iface == This->resource.wineD3DDevice->backBuffer || iface == This->resource.wineD3DDevice->renderTarget || iface == This->resource.wineD3DDevice->frontBuffer) {
-            GLint  prev_store;
-            GLenum prev_read;
+        GLint  prev_store;
+        GLenum prev_read;
+        BOOL notInContext = FALSE;
+        IWineD3DSwapChainImpl *targetSwapChain = NULL;
 
-            ENTER_GL();
+
+        ENTER_GL();
 
             /**
              * for render->surface copy begin to begin of allocatedMemory
              * unlock can be more easy
              */
-            pLockedRect->pBits = This->resource.allocatedMemory;
 
-            glFlush();
-            vcheckGLcall("glFlush");
-            glGetIntegerv(GL_READ_BUFFER, &prev_read);
-            vcheckGLcall("glIntegerv");
-            glGetIntegerv(GL_PACK_SWAP_BYTES, &prev_store);
-            vcheckGLcall("glIntegerv");
+        TRACE("locking a render target\n");
 
-            if (iface == This->resource.wineD3DDevice->backBuffer) {
-                glReadBuffer(GL_BACK);
-            } else if (iface == This->resource.wineD3DDevice->frontBuffer || iface == This->resource.wineD3DDevice->renderTarget) {
-                glReadBuffer(GL_FRONT);
-            } else if (iface == This->resource.wineD3DDevice->depthStencilBuffer) {
-                ERR("Stencil Buffer lock unsupported for now\n");
+        if (This->resource.allocatedMemory == NULL)
+                This->resource.allocatedMemory = HeapAlloc(GetProcessHeap() ,0 ,This->resource.size);
+
+        pLockedRect->pBits = This->resource.allocatedMemory;
+
+        glFlush();
+        vcheckGLcall("glFlush");
+        glGetIntegerv(GL_READ_BUFFER, &prev_read);
+        vcheckGLcall("glIntegerv");
+        glGetIntegerv(GL_PACK_SWAP_BYTES, &prev_store);
+        vcheckGLcall("glIntegerv");
+
+ /* Here's what we have to do:
+            See if the swapchain has the same context as the renderTarget or the surface is the render target.
+            Otherwise, see if were sharing a context with the implicite swapchain (because were using a shared context model!)
+            and use the fron back buffer as required.
+            if not, we need to switch contexts and then switchback at the end.
+         */
+        IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapchain);
+        IWineD3DSurface_GetContainer(myDevice->renderTarget, &IID_IWineD3DSwapChain, (void **)&targetSwapChain);
+
+        /* NOTE: In a shared context environment the renderTarget will use the same context as the implicite swapchain (we're not in a shared environment yet! */
+        if ((swapchain == targetSwapChain && targetSwapChain != NULL) || iface == myDevice->renderTarget) {
+                if (iface == myDevice->renderTarget || iface == swapchain->backBuffer) {
+                    TRACE("locking back buffer\n");
+                   glReadBuffer(GL_BACK);
+                }else if (iface == swapchain->frontBuffer) {
+                   TRACE("locking front\n");
+                   glReadBuffer(GL_FRONT);
+                }else if (iface == myDevice->depthStencilBuffer) {
+                    FIXME("Stencil Buffer lock unsupported for now\n");
+                } else{
+                   FIXME("(%p) Shouldn't have got here!\n", This);
+                   glReadBuffer(GL_BACK);
+                }
+        }else if (swapchain != NULL) {
+            IWineD3DSwapChainImpl *implSwapChain;
+            IWineD3DDevice_GetSwapChain((IWineD3DDevice *)myDevice, 0, (IWineD3DSwapChain **)&implSwapChain);
+            if (swapchain->glCtx == implSwapChain->render_ctx && swapchain->drawable == implSwapChain->win) {
+                    /* This will fail for the implicite swapchain, which is why there needs to be a context manager */
+                    if (iface == swapchain->backBuffer) {
+                        glReadBuffer(GL_BACK);
+                    }else if (iface == swapchain->frontBuffer) {
+                        glReadBuffer(GL_FRONT);
+                    } else if (iface == myDevice->depthStencilBuffer) {
+                        FIXME("Stencil Buffer lock unsupported for now\n");
+                    } else{
+                        FIXME("Should have got here!\n");
+                        glReadBuffer(GL_BACK);
+                    }
+            }else{
+                /* We need to switch contexts to be able to read the buffer!!! */
+                FIXME("The buffer requested isn't in the current openGL context\n");
+                notInContext = TRUE;
+                /* TODO: check the contexts, to see if were shared with the current context */
             }
-            vcheckGLcall("glReadBuffer");
+            IWineD3DSwapChain_Release((IWineD3DSwapChain *)implSwapChain);
+        }
+        if (swapchain != NULL)       IWineD3DSwapChain_Release((IWineD3DSwapChain *)swapchain);
+        if (targetSwapChain != NULL) IWineD3DSwapChain_Release((IWineD3DSwapChain *)targetSwapChain);
 
-            {
-                long j;
-                GLenum format = D3DFmt2GLFmt(This->resource.wineD3DDevice, This->resource.format);
-                GLenum type   = D3DFmt2GLType(This->resource.wineD3DDevice, This->resource.format);
+
+        /** the depth stencil in openGL has a format of GL_FLOAT
+        * which should be good for WINED3DFMT_D16_LOCKABLE
+        * and WINED3DFMT_D16
+        * it is unclear what format the stencil buffer is in except.
+        * 'Each index is converted to fixed point...
+        * If GL_MAP_STENCIL is GL_TRUE, indices are replaced by their
+        * mappings in the table GL_PIXEL_MAP_S_TO_S.
+        * glReadPixels(This->lockedRect.left,
+        *             This->lockedRect.bottom - j - 1,
+        *             This->lockedRect.right - This->lockedRect.left,
+        *             1,
+        *             GL_DEPTH_COMPONENT,
+        *             type,
+        *             (char *)pLockedRect->pBits + (pLockedRect->Pitch * (j-This->lockedRect.top)));
+            *****************************************/
+        if (!notInContext) { /* Only read the buffer if it's in the current context */
+            long j;
+            GLenum format = D3DFmt2GLFmt(myDevice, This->resource.format);
+            GLenum type   = D3DFmt2GLType(myDevice, This->resource.format);
+#if 0
+            /* Bizarly it's takes 120 millseconds to get an 800x600 region a line at a time, but only 10 to get the whole lot every time,
+            *  This is on an ATI9600, and may be format dependant, anyhow this hack makes this demo dx9_2d_demo_game
+            *  run ten times faster!
+            * ************************************/
+            BOOL ati_performance_hack = FALSE;
+            ati_performance_hack = (This->lockedRect.bottom - This->lockedRect.top > 10) || (This->lockedRect.right - This->lockedRect.left > 10)? TRUE: FALSE;
+#endif
+            if ((This->lockedRect.left ==0 &&  This->lockedRect.top ==0 &&
+                This->lockedRect.right == This->currentDesc.Width
+                && This->lockedRect.bottom ==  This->currentDesc.Height)) {
+                    glReadPixels(0, 0,
+                    This->currentDesc.Width,
+                    This->currentDesc.Height,
+                    format,
+                    type,
+                    (char *)pLockedRect->pBits);
+            }else if (This->lockedRect.left ==0 &&  This->lockedRect.right == This->currentDesc.Width) {
+                    glReadPixels(0,
+                    This->lockedRect.top,
+                    This->currentDesc.Width,
+                    This->currentDesc.Height,
+                    format,
+                    type,
+                    (char *)pLockedRect->pBits);
+            } else{
+
                 for (j = This->lockedRect.top; j < This->lockedRect.bottom - This->lockedRect.top; ++j) {
                     glReadPixels(This->lockedRect.left, 
                                  This->lockedRect.bottom - j - 1, 
@@ -310,23 +410,32 @@
                                  format, 
                                  type, 
                                  (char *)pLockedRect->pBits + (pLockedRect->Pitch * (j-This->lockedRect.top)));
-                    vcheckGLcall("glReadPixels");
+
                 }
             }
-
+            vcheckGLcall("glReadPixels");
+            TRACE("Resetting buffer\n");
             glReadBuffer(prev_read);
             vcheckGLcall("glReadBuffer");
-
-            LEAVE_GL();
-
-        } else {
-            FIXME("unsupported locking to Rendering surface surf@%p usage(%lu)\n", This, This->resource.usage);
         }
+        LEAVE_GL();
 
     } else if (D3DUSAGE_DEPTHSTENCIL & This->resource.usage) { /* stencil surfaces */
 
-        FIXME("TODO stencil depth surface locking surf@%p usage(%lu)\n", This, This->resource.usage);
+        if(!messages & 1){
+            FIXME("TODO stencil depth surface locking surf%p usage(%lu)\n", This, This->resource.usage);
+            /*
 
+            glReadPixels(This->lockedRect.left,
+            This->lockedRect.bottom - j - 1, 
+            This->lockedRect.right - This->lockedRect.left,
+            1,
+            GL_STENCIL_INDEX or GL_DEPTH_COMPONENT
+
+            )
+            */
+            messages |=1;
+        }
     } else {
         FIXME("unsupported locking to surface surf@%p usage(%lu)\n", This, This->resource.usage);
     }
@@ -341,10 +450,10 @@
          */
         IWineD3DSurface_AddDirtyRect(iface, &This->lockedRect);
 
-        /** Dirtify Container if needed */        
+        /** Dirtify Container if needed */
         if (D3D_OK == IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&pBaseTexture) && pBaseTexture != NULL) {
             TRACE("Making container dirty\n");
-            IWineD3DBaseTexture_SetDirty(pBaseTexture, TRUE);            
+            IWineD3DBaseTexture_SetDirty(pBaseTexture, TRUE);
             IWineD3DBaseTexture_Release(pBaseTexture);
         }else{
             TRACE("Surface is standalone, no need to dirty the container\n");
@@ -360,27 +469,33 @@
 HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) {
     GLint skipBytes = 0;
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
+    IWineD3DDeviceImpl  *myDevice = This->resource.wineD3DDevice;
+    const char *buffername = "";
+    IWineD3DSwapChainImpl *swapchain = NULL;
 
     if (FALSE == This->locked) {
-        ERR("trying to Unlock an unlocked surf@%p\n", This);  
+        WARN("trying to Unlock an unlocked surf@%p\n", This);
         return D3DERR_INVALIDCALL;
     }
 
-    if (iface== This->resource.wineD3DDevice->backBuffer || iface == This->resource.wineD3DDevice->frontBuffer || 
-		    iface == This->resource.wineD3DDevice->depthStencilBuffer || iface == This->resource.wineD3DDevice->renderTarget) {
-        if (iface == This->resource.wineD3DDevice->backBuffer) {
-            TRACE("(%p, backBuffer) : dirtyfied(%d)\n", This, This->Dirty);
-        } else if (iface == This->resource.wineD3DDevice->frontBuffer) {
-            TRACE("(%p, frontBuffer) : dirtyfied(%d)\n", This, This->Dirty);
-        } else if (iface == This->resource.wineD3DDevice->depthStencilBuffer) {
-            TRACE("(%p, stencilBuffer) : dirtyfied(%d)\n", This, This->Dirty);
-        } else if (iface == This->resource.wineD3DDevice->renderTarget) {
-            TRACE("(%p, renderTarget) : dirtyfied(%d)\n", This, This->Dirty);
-        }
-    } else {
-        TRACE("(%p) : dirtyfied(%d)\n", This, This->Dirty);
+    IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapchain);
+
+    if ((swapchain != NULL) &&  iface ==  swapchain->backBuffer) {
+            buffername = "backBuffer";
+    } else if ((swapchain != NULL) && iface ==  swapchain->frontBuffer) {
+            buffername = "frontBuffer";
+    } else if (iface == myDevice->depthStencilBuffer) {
+            buffername = "depthStencilBuffer";
+    } else if (iface == myDevice->renderTarget) {
+            buffername = "renderTarget";
     }
 
+    if (swapchain != NULL) {
+        IWineD3DSwapChain_Release((IWineD3DSwapChain *)swapchain);
+    }
+
+    TRACE("(%p %s) : dirtyfied(%d)\n", This, buffername, This->Dirty);
+
     if (FALSE == This->Dirty) {
         TRACE("(%p) : Not Dirtified so nothing to do, return now\n", This);
         goto unlock_end;
@@ -393,7 +508,16 @@
          */
     } else if (D3DUSAGE_RENDERTARGET & This->resource.usage) { /* render surfaces */
 
-        if (iface == This->resource.wineD3DDevice->backBuffer || iface == This->resource.wineD3DDevice->frontBuffer || iface == This->resource.wineD3DDevice->renderTarget) {
+        /****************************
+        * TODO: Render targets are 'special' and
+        * ?some? locking needs to be passed onto the context manager
+        * so that it becomes possible to use auxilary buffers, pbuffers
+        * render-to-texture, shared, cached contexts etc...
+        * ****************************/
+        IWineD3DSwapChainImpl *implSwapChain;
+        IWineD3DDevice_GetSwapChain((IWineD3DDevice *)myDevice, 0, (IWineD3DSwapChain **)&implSwapChain);
+
+        if (iface ==  implSwapChain->backBuffer || iface ==  implSwapChain->frontBuffer || iface == myDevice->renderTarget) {
             GLint  prev_store;
             GLenum prev_draw;
             GLint  prev_rasterpos[4];
@@ -414,10 +538,10 @@
             /* glDrawPixels transforms the raster position as though it was a vertex -
                we want to draw at screen position 0,0 - Set up ortho (rhw) mode as   
                per drawprim (and leave set - it will sort itself out due to last_was_rhw */
-            if (!This->resource.wineD3DDevice->last_was_rhw) {
+            if (!myDevice->last_was_rhw) {
 
                 double X, Y, height, width, minZ, maxZ;
-                This->resource.wineD3DDevice->last_was_rhw = TRUE;
+                myDevice->last_was_rhw = TRUE;
 
                 /* Transformed already into viewport coordinates, so we do not need transform
                    matrices. Reset all matrices to identity and leave the default matrix in world 
@@ -433,12 +557,12 @@
                 checkGLcall("glLoadIdentity");
 
                 /* Set up the viewport to be full viewport */
-                X      = This->resource.wineD3DDevice->stateBlock->viewport.X;
-                Y      = This->resource.wineD3DDevice->stateBlock->viewport.Y;
-                height = This->resource.wineD3DDevice->stateBlock->viewport.Height;
-                width  = This->resource.wineD3DDevice->stateBlock->viewport.Width;
-                minZ   = This->resource.wineD3DDevice->stateBlock->viewport.MinZ;
-                maxZ   = This->resource.wineD3DDevice->stateBlock->viewport.MaxZ;
+                X      = myDevice->stateBlock->viewport.X;
+                Y      = myDevice->stateBlock->viewport.Y;
+                height = myDevice->stateBlock->viewport.Height;
+                width  = myDevice->stateBlock->viewport.Width;
+                minZ   = myDevice->stateBlock->viewport.MinZ;
+                maxZ   = myDevice->stateBlock->viewport.MaxZ;
                 TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
                 glOrtho(X, X + width, Y + height, Y, -minZ, -maxZ);
                 checkGLcall("glOrtho");
@@ -449,11 +573,12 @@
                 checkGLcall("glTranslatef(0.5, 0.5, 0)");
             }
 
-            if (iface == This->resource.wineD3DDevice->backBuffer) {
+            if (iface ==  implSwapChain->backBuffer || iface == myDevice->renderTarget) {
                 glDrawBuffer(GL_BACK);
-            } else if (iface == This->resource.wineD3DDevice->frontBuffer || iface == This->resource.wineD3DDevice->renderTarget) {
+            } else if (iface ==  implSwapChain->frontBuffer) {
                 glDrawBuffer(GL_FRONT);
             }
+
             vcheckGLcall("glDrawBuffer");
 
             /* If not fullscreen, we need to skip a number of bytes to find the next row of data */
@@ -505,7 +630,7 @@
 
             /* Reset to previous pack row length / blending state */
             glPixelStorei(GL_UNPACK_ROW_LENGTH, skipBytes);
-            if (This->resource.wineD3DDevice->stateBlock->renderState[D3DRS_ALPHABLENDENABLE]) glEnable(GL_BLEND);
+            if (myDevice->stateBlock->renderState[D3DRS_ALPHABLENDENABLE]) glEnable(GL_BLEND);
 
             LEAVE_GL();
 
@@ -515,10 +640,11 @@
         } else {
             FIXME("unsupported unlocking to Rendering surface surf@%p usage(%lu)\n", This, This->resource.usage);
         }
+        IWineD3DSwapChain_Release((IWineD3DSwapChain *)implSwapChain);
 
     } else if (D3DUSAGE_DEPTHSTENCIL & This->resource.usage) { /* stencil surfaces */
 
-        if (iface == This->resource.wineD3DDevice->depthStencilBuffer) {
+        if (iface == myDevice->depthStencilBuffer) {
             FIXME("TODO stencil depth surface unlocking surf@%p usage(%lu)\n", This, This->resource.usage);
         } else {
             FIXME("unsupported unlocking to StencilDepth surface surf@%p usage(%lu)\n", This, This->resource.usage);
@@ -699,7 +825,7 @@
             ++gen;
             if ((gen % 10) == 0) {
                 snprintf(buffer, sizeof(buffer), "/tmp/surface%p_type%u_level%u_%u.ppm", This, gl_target, gl_level, gen);
-                IWineD3DSurfaceImpl_SaveSnapshot((LPDIRECT3DSURFACE8) This, buffer);
+                IWineD3DSurfaceImpl_SaveSnapshot((IWineD3DSurface *) This, buffer);
             }
             /*
              * debugging crash code
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 5df2f2e..ad15e72 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -1761,4 +1761,138 @@
     TRACE("bytes/Pxl for fmt(%u,%s) = %d\n", fmt, debug_d3dformat(fmt), retVal);
     return retVal;
 }
+
+/* Convertes a D3D format into a OpenGL configuration format */
+int D3DFmtMakeGlCfg(D3DFORMAT BackBufferFormat, D3DFORMAT StencilBufferFormat, int *attribs, int* nAttribs, BOOL alternate){
+#define PUSH1(att)        attribs[(*nAttribs)++] = (att); 
+#define PUSH2(att,value)  attribs[(*nAttribs)++] = (att); attribs[(*nAttribs)++] = (value);
+    /*We need to do some Card specific stuff in here at some point, 
+    D3D now support floating point format buffers, and their are a number of different OpelGl ways on managing thease e.g.
+    GLX_ATI_pixel_format_float
+    */
+    switch (BackBufferFormat) {
+        /* color buffer */
+    case WINED3DFMT_P8:
+        PUSH2(GLX_RENDER_TYPE,  GLX_COLOR_INDEX_BIT);
+        PUSH2(GLX_BUFFER_SIZE,  8);
+        PUSH2(GLX_DOUBLEBUFFER, TRUE);
+        break;
+
+    case WINED3DFMT_R3G3B2:
+        PUSH2(GLX_RENDER_TYPE,  GLX_RGBA_BIT);
+        PUSH2(GLX_RED_SIZE,     3);
+        PUSH2(GLX_GREEN_SIZE,   3);
+        PUSH2(GLX_BLUE_SIZE,    2);
+        break;
+
+    case WINED3DFMT_A1R5G5B5:
+        PUSH2(GLX_ALPHA_SIZE,   1);
+    case WINED3DFMT_X1R5G5B5:
+        PUSH2(GLX_RED_SIZE,     5);
+        PUSH2(GLX_GREEN_SIZE,   5);
+        PUSH2(GLX_BLUE_SIZE,    5);
+        break;
+
+    case WINED3DFMT_R5G6B5:
+        PUSH2(GLX_RED_SIZE,     5);
+        PUSH2(GLX_GREEN_SIZE,   6);
+        PUSH2(GLX_BLUE_SIZE,    5);
+        break;
+
+    case WINED3DFMT_A4R4G4B4:
+        PUSH2(GLX_ALPHA_SIZE,   4);
+    case WINED3DFMT_X4R4G4B4:
+        PUSH2(GLX_RED_SIZE,     4);
+        PUSH2(GLX_GREEN_SIZE,   4);
+        PUSH2(GLX_BLUE_SIZE,    4);
+        break;
+
+    case WINED3DFMT_A8R8G8B8:
+        PUSH2(GLX_ALPHA_SIZE,   8);
+    case WINED3DFMT_R8G8B8:
+    case WINED3DFMT_X8R8G8B8:
+        PUSH2(GLX_RED_SIZE,     8);
+        PUSH2(GLX_GREEN_SIZE,   8);
+        PUSH2(GLX_BLUE_SIZE,    8);
+        break;
+
+    default:
+        break;
+    }
+    if(!alternate){
+        switch (StencilBufferFormat) { 
+    case WINED3DFMT_D16_LOCKABLE:
+    case WINED3DFMT_D16:
+        PUSH2(GLX_DEPTH_SIZE,   16);
+        break;
+
+    case WINED3DFMT_D15S1:
+        PUSH2(GLX_DEPTH_SIZE,   15);
+        PUSH2(GLX_STENCIL_SIZE, 1);
+        /*Does openGl support a 1bit stencil?, I've seen it used elsewhere 
+        e.g. http://www.ks.uiuc.edu/Research/vmd/doxygen/OpenGLDisplayDevice_8C-source.html*/
+        break;
+
+    case WINED3DFMT_D24X8:
+        PUSH2(GLX_DEPTH_SIZE,   24);
+        break;
+
+    case WINED3DFMT_D24X4S4:
+        PUSH2(GLX_DEPTH_SIZE,   24);
+        PUSH2(GLX_STENCIL_SIZE, 4);
+        break;
+
+    case WINED3DFMT_D24S8:
+        PUSH2(GLX_DEPTH_SIZE,   24);
+        PUSH2(GLX_STENCIL_SIZE, 8);
+        break;
+
+    case WINED3DFMT_D32:
+        PUSH2(GLX_DEPTH_SIZE,   32);
+        break;
+
+    default:
+        break;
+    }
+
+    }else{ /* it the device doesn't support the 'exact' format, try to find something close */
+        switch (StencilBufferFormat) { 
+        case WINED3DFMT_D16_LOCKABLE:
+        case WINED3DFMT_D16:
+            PUSH2(GLX_DEPTH_SIZE,   1);
+            break;
+
+        case WINED3DFMT_D15S1:
+            PUSH2(GLX_DEPTH_SIZE,   1);
+            PUSH2(GLX_STENCIL_SIZE, 1);
+            /*Does openGl support a 1bit stencil?, I've seen it used elsewhere 
+            e.g. http://www.ks.uiuc.edu/Research/vmd/doxygen/OpenGLDisplayDevice_8C-source.html*/
+            break;
+
+        case WINED3DFMT_D24X8:
+            PUSH2(GLX_DEPTH_SIZE,   1);
+            break;
+
+        case WINED3DFMT_D24X4S4:
+            PUSH2(GLX_DEPTH_SIZE,   1);
+            PUSH2(GLX_STENCIL_SIZE, 1);
+            break;
+
+        case WINED3DFMT_D24S8:
+            PUSH2(GLX_DEPTH_SIZE,   1);
+            PUSH2(GLX_STENCIL_SIZE, 1);
+            break;
+
+        case WINED3DFMT_D32:
+            PUSH2(GLX_DEPTH_SIZE,   1);
+            break;
+
+        default:
+            break;
+        }
+    }
+
+    return *nAttribs;
+}
+
 #undef GLINFO_LOCATION
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index e634437..4513697 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -394,7 +394,6 @@
 
     /* Internal use fields  */
     D3DDEVICE_CREATION_PARAMETERS   createParms;
-    D3DPRESENT_PARAMETERS           presentParms;
     UINT                            adapterNo;
     D3DDEVTYPE                      devType;
 
@@ -403,8 +402,6 @@
     int                     numberOfSwapChains;
 
     /* Render Target Support */
-    IWineD3DSurface        *frontBuffer;
-    IWineD3DSurface        *backBuffer;
     IWineD3DSurface        *depthStencilBuffer;
 
     IWineD3DSurface        *renderTarget;
@@ -850,6 +847,9 @@
 GLenum D3DFmt2GLType(IWineD3DDeviceImpl *This, D3DFORMAT fmt);
 GLint  D3DFmt2GLIntFmt(IWineD3DDeviceImpl* This, D3DFORMAT fmt);
 
+int D3DFmtMakeGlCfg(D3DFORMAT BackBufferFormat, D3DFORMAT StencilBufferFormat, int *attribs, int* nAttribs, BOOL alternate);
+
+
 /*****************************************************************************
  * To enable calling of inherited functions, requires prototypes 
  *