/*
 * IWineD3DSurface Implementation
 *
 * Copyright 2002-2005 Jason Edmeades
 * Copyright 2002-2003 Raphael Junqueira
 * Copyright 2004 Christian Costa
 * Copyright 2005 Oliver Stieber
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"
#include "wine/port.h"
#include "wined3d_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface);
#define GLINFO_LOCATION ((IWineD3DImpl *)(((IWineD3DDeviceImpl *)This->resource.wineD3DDevice)->wineD3D))->gl_info

/* *******************************************
   IWineD3DSurface IUnknown parts follow
   ******************************************* */
HRESULT WINAPI IWineD3DSurfaceImpl_QueryInterface(IWineD3DSurface *iface, REFIID riid, LPVOID *ppobj)
{
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
    /* Warn ,but be nice about things */
    TRACE("(%p)->(%s,%p)\n", This,debugstr_guid(riid),ppobj);
    if (riid == NULL) {
        ERR("Probably FIXME: Calling query interface with NULL riid\n");
    }
    if (IsEqualGUID(riid, &IID_IUnknown)
        || IsEqualGUID(riid, &IID_IWineD3DBase)
        || IsEqualGUID(riid, &IID_IWineD3DResource)
        || IsEqualGUID(riid, &IID_IWineD3DSurface)) {
        IUnknown_AddRef((IUnknown*)iface);
        *ppobj = This;
        return S_OK;
    }
    *ppobj = NULL;
    return E_NOINTERFACE;
}

ULONG WINAPI IWineD3DSurfaceImpl_AddRef(IWineD3DSurface *iface) {
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
    ULONG ref = InterlockedIncrement(&This->resource.ref);
    TRACE("(%p) : AddRef increasing from %ld\n", This,ref - 1);
    return ref;
}

ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface) {
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
    ULONG ref = InterlockedDecrement(&This->resource.ref);
    TRACE("(%p) : Releasing from %ld\n", This, ref + 1);
    if (ref == 0) {
        TRACE("(%p) : cleaning up\n", This);
        if (This->glDescription.textureName != 0) { /* release the openGL texture.. */
            ENTER_GL();
            TRACE("Deleting texture %d\n", This->glDescription.textureName);
            glDeleteTextures(1, &This->glDescription.textureName);
            LEAVE_GL();
        }
        IWineD3DResourceImpl_CleanUp((IWineD3DResource *)iface);

        TRACE("(%p) Released\n", This);
        HeapFree(GetProcessHeap(), 0, This);

    }
    return ref;
}

/* ****************************************************
   IWineD3DSurface IWineD3DResource parts follow
   **************************************************** */
HRESULT WINAPI IWineD3DSurfaceImpl_GetDevice(IWineD3DSurface *iface, IWineD3DDevice** ppDevice) {
    return IWineD3DResourceImpl_GetDevice((IWineD3DResource *)iface, ppDevice);
}

HRESULT WINAPI IWineD3DSurfaceImpl_SetPrivateData(IWineD3DSurface *iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
    return IWineD3DResourceImpl_SetPrivateData((IWineD3DResource *)iface, refguid, pData, SizeOfData, Flags);
}

HRESULT WINAPI IWineD3DSurfaceImpl_GetPrivateData(IWineD3DSurface *iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) {
    return IWineD3DResourceImpl_GetPrivateData((IWineD3DResource *)iface, refguid, pData, pSizeOfData);
}

HRESULT WINAPI IWineD3DSurfaceImpl_FreePrivateData(IWineD3DSurface *iface, REFGUID refguid) {
    return IWineD3DResourceImpl_FreePrivateData((IWineD3DResource *)iface, refguid);
}

DWORD   WINAPI IWineD3DSurfaceImpl_SetPriority(IWineD3DSurface *iface, DWORD PriorityNew) {
    return IWineD3DResourceImpl_SetPriority((IWineD3DResource *)iface, PriorityNew);
}

DWORD   WINAPI IWineD3DSurfaceImpl_GetPriority(IWineD3DSurface *iface) {
    return IWineD3DResourceImpl_GetPriority((IWineD3DResource *)iface);
}

void    WINAPI IWineD3DSurfaceImpl_PreLoad(IWineD3DSurface *iface) {
    /* TODO: re-write the way textures and managed,
    *  use a 'opengl context manager' to manage RenderTarget surfaces
    ** *********************************************************/

    /* TODO: check for locks */
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
    IWineD3DBaseTexture *baseTexture = NULL;
    TRACE("(%p)Checking to see if the container is a base texture\n", This);
    if (IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&baseTexture) == WINED3D_OK) {
        TRACE("Passing to conatiner\n");
        IWineD3DBaseTexture_PreLoad(baseTexture);
        IWineD3DBaseTexture_Release(baseTexture);
    } else {
    TRACE("(%p) : About to load surface\n", This);
    ENTER_GL();
#if 0 /* TODO: context manager support */
     IWineD3DContextManager_PushState(This->contextManager, GL_TEXTURE_2D, ENABLED, NOW /* make sure the state is applied now */);
#endif
    glEnable(This->glDescription.target);/* make sure texture support is enabled in this context */
    if (This->glDescription.level == 0 &&  This->glDescription.textureName == 0) {
          glGenTextures(1, &This->glDescription.textureName);
          checkGLcall("glGenTextures");
          TRACE("Surface %p given name %d\n", This, This->glDescription.textureName);
          glBindTexture(This->glDescription.target, This->glDescription.textureName);
          checkGLcall("glBindTexture");
          IWineD3DSurface_LoadTexture(iface);
          /* This is where we should be reducing the amount of GLMemoryUsed */
    } else {
        if (This->glDescription.level == 0) {
          glBindTexture(This->glDescription.target, This->glDescription.textureName);
          checkGLcall("glBindTexture");
          IWineD3DSurface_LoadTexture(iface);
        } else  if (This->glDescription.textureName != 0) { /* NOTE: the level 0 surface of a mpmapped texture must be loaded first! */
            /* assume this is a coding error not a real error for now */
            FIXME("Mipmap surface has a glTexture bound to it!\n");
        }
    }
    if (This->resource.pool == WINED3DPOOL_DEFAULT) {
       /* Tell opengl to try and keep this texture in video ram (well mostly) */
       GLclampf tmp;
       tmp = 0.9f;
        glPrioritizeTextures(1, &This->glDescription.textureName, &tmp);
    }
    /* TODO: disable texture support, if it wastn't enabled when we entered. */
#if 0 /* TODO: context manager support */
     IWineD3DContextManager_PopState(This->contextManager, GL_TEXTURE_2D, DISABLED,DELAYED
              /* we don't care when the state is disabled(if atall) */);
#endif
    LEAVE_GL();
    }
    return;
}

WINED3DRESOURCETYPE WINAPI IWineD3DSurfaceImpl_GetType(IWineD3DSurface *iface) {
    TRACE("(%p) : calling resourceimpl_GetType\n", iface);
    return IWineD3DResourceImpl_GetType((IWineD3DResource *)iface);
}

HRESULT WINAPI IWineD3DSurfaceImpl_GetParent(IWineD3DSurface *iface, IUnknown **pParent) {
    TRACE("(%p) : calling resourceimpl_GetParent\n", iface);
    return IWineD3DResourceImpl_GetParent((IWineD3DResource *)iface, pParent);
}

/* ******************************************************
   IWineD3DSurface IWineD3DSurface parts follow
   ****************************************************** */

HRESULT WINAPI IWineD3DSurfaceImpl_GetContainerParent(IWineD3DSurface* iface, IUnknown **ppContainerParent) {
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;

    TRACE("(%p) : ppContainerParent %p)\n", This, ppContainerParent);

    if (!ppContainerParent) {
        ERR("(%p) : Called without a valid ppContainerParent.\n", This);
    }

    if (This->container) {
        IWineD3DBase_GetParent(This->container, ppContainerParent);
        if (!ppContainerParent) {
            /* WineD3D objects should always have a parent */
            ERR("(%p) : GetParent returned NULL\n", This);
        }
        IUnknown_Release(*ppContainerParent); /* GetParent adds a reference; we want just the pointer */
    } else {
        *ppContainerParent = NULL;
    }

    return WINED3D_OK;
}

HRESULT WINAPI IWineD3DSurfaceImpl_GetContainer(IWineD3DSurface* iface, REFIID riid, void** ppContainer) {
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
    IWineD3DBase *container = 0;

    TRACE("(This %p, riid %s, ppContainer %p)\n", This, debugstr_guid(riid), ppContainer);

    if (!ppContainer) {
        ERR("Called without a valid ppContainer.\n");
    }

    /** From MSDN:
     * If the surface is created using CreateImageSurface/CreateOffscreenPlainSurface, CreateRenderTarget,
     * or CreateDepthStencilSurface, the surface is considered stand alone. In this case,
     * GetContainer will return the Direct3D device used to create the surface.
     */
    if (This->container) {
        container = This->container;
    } else {
        container = (IWineD3DBase *)This->resource.wineD3DDevice;
    }

    TRACE("Relaying to QueryInterface\n");
    if (IUnknown_QueryInterface(container, riid, ppContainer) != S_OK)
        return WINED3DERR_INVALIDCALL;

    return WINED3D_OK;
}

HRESULT WINAPI IWineD3DSurfaceImpl_GetDesc(IWineD3DSurface *iface, WINED3DSURFACE_DESC *pDesc) {
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;

    TRACE("(%p) : copying into %p\n", This, pDesc);
    if(pDesc->Format != NULL)             *(pDesc->Format) = This->resource.format;
    if(pDesc->Type != NULL)               *(pDesc->Type)   = This->resource.resourceType;
    if(pDesc->Usage != NULL)              *(pDesc->Usage)              = This->resource.usage;
    if(pDesc->Pool != NULL)               *(pDesc->Pool)               = This->resource.pool;
    if(pDesc->Size != NULL)               *(pDesc->Size)               = This->resource.size;   /* dx8 only */
    if(pDesc->MultiSampleType != NULL)    *(pDesc->MultiSampleType)    = This->currentDesc.MultiSampleType;
    if(pDesc->MultiSampleQuality != NULL) *(pDesc->MultiSampleQuality) = This->currentDesc.MultiSampleQuality;
    if(pDesc->Width != NULL)              *(pDesc->Width)              = This->currentDesc.Width;
    if(pDesc->Height != NULL)             *(pDesc->Height)             = This->currentDesc.Height;
    return WINED3D_OK;
}

void WINAPI IWineD3DSurfaceImpl_SetGlTextureDesc(IWineD3DSurface *iface, UINT textureName, int target) {
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
    TRACE("(%p) : setting textureName %u, target %i\n", This, textureName, target);
    if (This->glDescription.textureName == 0 && textureName != 0) {
        This->Flags |= SFLAG_DIRTY;
        IWineD3DSurface_AddDirtyRect(iface, NULL);
    }
    This->glDescription.textureName = textureName;
    This->glDescription.target      = target;
}

void WINAPI IWineD3DSurfaceImpl_GetGlDesc(IWineD3DSurface *iface, glDescriptor **glDescription) {
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
    TRACE("(%p) : returning %p\n", This, &This->glDescription);
    *glDescription = &This->glDescription;
}

/* TODO: think about moving this down to resource? */
const void *WINAPI IWineD3DSurfaceImpl_GetData(IWineD3DSurface *iface) {
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
    /* This should only be called for sysmem textures, it may be a good idea to extend this to all pools at some point in the futture  */
    if (This->resource.pool != WINED3DPOOL_SYSTEMMEM) {
        FIXME(" (%p)Attempting to get system memory for a non-system memory texture\n", iface);
    }
    return (CONST void*)(This->resource.allocatedMemory);
}

HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED3DLOCKED_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->Flags & (SFLAG_INTEXTURE | SFLAG_INPBUFFER)) ==
                      (SFLAG_INTEXTURE | SFLAG_INPBUFFER) ) {
        FIXME("Warning: Surface is in texture memory or pbuffer\n");
        This->Flags &= ~(SFLAG_INTEXTURE | SFLAG_INPBUFFER);
    }

    if (!(This->Flags & SFLAG_LOCKABLE)) {
        /* Note: UpdateTextures calls CopyRects which calls this routine to populate the
              texture regions, and since the destination is an unlockable region we need
              to tolerate this                                                           */
        TRACE("Warning: trying to lock unlockable surf@%p\n", This);
        /*return WINED3DERR_INVALIDCALL; */
    }

    if (This->resource.usage & WINED3DUSAGE_RENDERTARGET) {
        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 (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 == 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 == 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);
    }

    /* DXTn formats don't have exact pitches as they are to the new row of blocks,
         where each block is 4x4 pixels, 8 bytes (dxt1) and 16 bytes (dxt2/3/4/5)
          ie pitch = (width/4) * bytes per block                                  */
    if (This->resource.format == WINED3DFMT_DXT1) /* DXT1 is 8 bytes per block */
        pLockedRect->Pitch = (This->currentDesc.Width >> 2) << 3;
    else if (This->resource.format == WINED3DFMT_DXT2 || This->resource.format == WINED3DFMT_DXT3 ||
             This->resource.format == WINED3DFMT_DXT4 || This->resource.format == WINED3DFMT_DXT5) /* DXT2/3/4/5 is 16 bytes per block */
        pLockedRect->Pitch = (This->currentDesc.Width >> 2) << 4;
    else {
        if (NP2_REPACK == wined3d_settings.nonpower2_mode || This->resource.usage & WINED3DUSAGE_RENDERTARGET) {
            /* Front and back buffers are always lockes/unlocked on currentDesc.Width */
            pLockedRect->Pitch = This->bytesPerPixel * This->currentDesc.Width;  /* Bytes / row */
        } else {
            pLockedRect->Pitch = This->bytesPerPixel * This->pow2Width;
        }
    }

    if (NULL == pRect) {
        pLockedRect->pBits = This->resource.allocatedMemory;
        This->lockedRect.left   = 0;
        This->lockedRect.top    = 0;
        This->lockedRect.right  = This->currentDesc.Width;
        This->lockedRect.bottom = This->currentDesc.Height;
        TRACE("Locked Rect (%p) = l %ld, t %ld, r %ld, b %ld\n", &This->lockedRect, This->lockedRect.left, This->lockedRect.top, This->lockedRect.right, This->lockedRect.bottom);
    } else {
        TRACE("Lock Rect (%p) = l %ld, t %ld, r %ld, b %ld\n", pRect, pRect->left, pRect->top, pRect->right, pRect->bottom);

        if (This->resource.format == WINED3DFMT_DXT1) { /* DXT1 is half byte per pixel */
            pLockedRect->pBits = This->resource.allocatedMemory + (pLockedRect->Pitch * pRect->top) + ((pRect->left * This->bytesPerPixel / 2));
        } else {
            pLockedRect->pBits = This->resource.allocatedMemory + (pLockedRect->Pitch * pRect->top) + (pRect->left * This->bytesPerPixel);
        }
        This->lockedRect.left   = pRect->left;
        This->lockedRect.top    = pRect->top;
        This->lockedRect.right  = pRect->right;
        This->lockedRect.bottom = pRect->bottom;
    }

    if (This->Flags & SFLAG_NONPOW2) {
        TRACE("Locking non-power 2 texture\n");
    }

    if (0 == This->resource.usage || This->resource.usage & WINED3DUSAGE_DYNAMIC) {
        /* classic surface  TODO: non 2d surfaces?
        These resources may be POOL_SYSTEMMEM, so they must not access the device */
        TRACE("locking an ordinarary surface\n");
        /* Check to see if memory has already been allocated from the surface*/
        if (NULL == This->resource.allocatedMemory) { /* TODO: check to see if an update has been performed on the surface (an update could just clobber allocatedMemory */
            /* Non-system memory surfaces */

            /*Surface has no memory currently allocated to it!*/
            TRACE("(%p) Locking rect\n" , This);
            This->resource.allocatedMemory = HeapAlloc(GetProcessHeap() ,0 , This->pow2Size);
            if (0 != This->glDescription.textureName) {
                /* Now I have to copy thing bits back */
                This->Flags |= SFLAG_ACTIVELOCK; /* When this flag is set to true, loading the surface again won't free THis->resource.allocatedMemory */
                /* TODO: make activeLock a bit more intelligent, maybe implement a method to purge the texture memory. */
                ENTER_GL();
    
                /* Make sure that the texture is loaded */
                IWineD3DSurface_PreLoad(iface); /* Make sure there is a texture to bind! */
    
                TRACE("(%p) glGetTexImage level(%d), fmt(%d), typ(%d), mem(%p)\n" , This, This->glDescription.level,  This->glDescription.glFormat, This->glDescription.glType, This->resource.allocatedMemory);
    
                if (This->resource.format == WINED3DFMT_DXT1 ||
                    This->resource.format == WINED3DFMT_DXT2 ||
                    This->resource.format == WINED3DFMT_DXT3 ||
                    This->resource.format == WINED3DFMT_DXT4 ||
                    This->resource.format == WINED3DFMT_DXT5) {
                    TRACE("Locking a compressed texture\n");
                    if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) { /* we can assume this as the texture would not have been created otherwise */
                        GL_EXTCALL(glGetCompressedTexImageARB)(This->glDescription.target,
                                                            This->glDescription.level,
                                                            This->resource.allocatedMemory);
    
                    } else {
                        FIXME("(%p) attempting to lock a compressed texture when texture compression isn't supported by opengl\n", This);
                    }
                } else {
                    glGetTexImage(This->glDescription.target,
                                This->glDescription.level,
                                This->glDescription.glFormat,
                                This->glDescription.glType,
                                This->resource.allocatedMemory);
                    vcheckGLcall("glGetTexImage");
                    if (NP2_REPACK == wined3d_settings.nonpower2_mode) {
                        /* some games (e.g. warhammer 40k) don't work with the odd pitchs properly, preventing
                        the surface pitch from being used to box non-power2 textures. Instead we have to use a hack to
                        repack the texture so that the bpp * width pitch can be used instead of the bpp * pow2width.
        
                        Were doing this...
        
                        instead of boxing the texture :
                        |<-texture width ->|  -->pow2width|   /\
                        |111111111111111111|              |   |
                        |222 Texture 222222| boxed empty  | texture height
                        |3333 Data 33333333|              |   |
                        |444444444444444444|              |   \/
                        -----------------------------------   |
                        |     boxed  empty | boxed empty  | pow2height
                        |                  |              |   \/
                        -----------------------------------
        
        
                        were repacking the data to the expected texture width
        
                        |<-texture width ->|  -->pow2width|   /\
                        |111111111111111111222222222222222|   |
                        |222333333333333333333444444444444| texture height
                        |444444                           |   |
                        |                                 |   \/
                        |                                 |   |
                        |            empty                | pow2height
                        |                                 |   \/
                        -----------------------------------
        
                        == is the same as
        
                        |<-texture width ->|    /\
                        |111111111111111111|
                        |222222222222222222|texture height
                        |333333333333333333|
                        |444444444444444444|    \/
                        --------------------
        
                        this also means that any references to allocatedMemory should work with the data as if were a standard texture with a non-power2 width instead of texture boxed up to be a power2 texture.
        
                        internally the texture is still stored in a boxed format so any references to textureName will get a boxed texture with width pow2width and not a texture of width currentDesc.Width.
                        */
                        if (This->Flags & SFLAG_NONPOW2) {
                            BYTE* dataa, *datab;
                            int pitcha = 0, pitchb = 0;
                            int y;
                            pitcha = This->bytesPerPixel * This->currentDesc.Width;
                            pitchb = This->bytesPerPixel * This->pow2Width;
                            datab = dataa = This->resource.allocatedMemory;
                            FIXME("(%p) : Repacking the surface data from pitch %d to pitch %d\n", This, pitcha, pitchb);
                            for (y = 1 ; y < This->currentDesc.Height; y++) {
                                dataa += pitcha; /* skip the first row */
                                datab += pitchb;
                                memcpy(dataa, datab, pitcha);
                            }
                        }
                    }
                }
                LEAVE_GL();
            }
        } else { /* Nothing to do */
            TRACE("Memory %p already allocted for texture\n",  This->resource.allocatedMemory);
        }

        if (NULL == pRect) {
            pLockedRect->pBits = This->resource.allocatedMemory;
        }  else{
            if (This->resource.format == D3DFMT_DXT1) { /* DXT1 is half byte per pixel */
                pLockedRect->pBits = This->resource.allocatedMemory + (pLockedRect->Pitch * pRect->top) + ((pRect->left * This->bytesPerPixel / 2));
            } else {
                pLockedRect->pBits = This->resource.allocatedMemory + (pLockedRect->Pitch * pRect->top) + (pRect->left * This->bytesPerPixel);
            }
        }

    } else if (WINED3DUSAGE_RENDERTARGET & This->resource.usage && !(Flags&WINED3DLOCK_DISCARD)) { /* render surfaces */

        GLint  prev_store;
        GLint  prev_read;
        BOOL notInContext = FALSE;
        IWineD3DSwapChainImpl *targetSwapChain = NULL;


        ENTER_GL();

            /**
             * for render->surface copy begin to begin of allocatedMemory
             * unlock can be more easy
             */

        TRACE("locking a render target\n");

        if (This->resource.allocatedMemory == NULL)
                This->resource.allocatedMemory = HeapAlloc(GetProcessHeap() ,0 ,This->resource.size);

        This->Flags |= SFLAG_ACTIVELOCK; /*When this flag is set to true, loading the surface again won't free THis->resource.allocatedMemory*/
        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 implicit swapchain (because we're using a shared context model!)
            and use the front 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 implicit 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 implicit 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 */
            }
            IWineD3DSwapChain_Release((IWineD3DSwapChain *)implSwapChain);
        }
        if (swapchain != NULL)       IWineD3DSwapChain_Release((IWineD3DSwapChain *)swapchain);
        if (targetSwapChain != NULL) IWineD3DSwapChain_Release((IWineD3DSwapChain *)targetSwapChain);


        /** 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;
#if 0
            /* Bizarly it 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 dependent, 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,
                    This->glDescription.glFormat,
                    This->glDescription.glType,
                    (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,
                    This->glDescription.glFormat,
                    This->glDescription.glType,
                    (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, 
                                 This->lockedRect.right - This->lockedRect.left, 
                                 1,
                                 This->glDescription.glFormat,
                                 This->glDescription.glType,
                                 (char *)pLockedRect->pBits + (pLockedRect->Pitch * (j-This->lockedRect.top)));

                }
            }
            vcheckGLcall("glReadPixels");
            TRACE("Resetting buffer\n");
            glReadBuffer(prev_read);
            vcheckGLcall("glReadBuffer");
        }
        LEAVE_GL();

    } else if (WINED3DUSAGE_DEPTHSTENCIL & This->resource.usage) { /* stencil surfaces */

        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);
    }

    if (Flags & (WINED3DLOCK_NO_DIRTY_UPDATE | WINED3DLOCK_READONLY)) {
        /* Don't dirtify */
    } else {
        IWineD3DBaseTexture *pBaseTexture;
        /**
         * Dirtify on lock
         * as seen in msdn docs
         */
        IWineD3DSurface_AddDirtyRect(iface, &This->lockedRect);

        /** Dirtify Container if needed */
        if (WINED3D_OK == IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&pBaseTexture) && pBaseTexture != NULL) {
            TRACE("Making container dirty\n");
            IWineD3DBaseTexture_SetDirty(pBaseTexture, TRUE);
            IWineD3DBaseTexture_Release(pBaseTexture);
        } else {
            TRACE("Surface is standalone, no need to dirty the container\n");
        }
    }

    TRACE("returning memory@%p, pitch(%d) dirtyfied(%d)\n", pLockedRect->pBits, pLockedRect->Pitch, This->Flags & SFLAG_DIRTY ? 0 : 1);

    This->Flags |= SFLAG_LOCKED;
    return WINED3D_OK;
}

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 (!(This->Flags & SFLAG_LOCKED)) {
        WARN("trying to Unlock an unlocked surf@%p\n", This);
        return WINED3DERR_INVALIDCALL;
    }

    if (WINED3DUSAGE_RENDERTARGET & This->resource.usage) {
        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->Flags & SFLAG_DIRTY ? 1 : 0);

    if (!(This->Flags & SFLAG_DIRTY)) {
        TRACE("(%p) : Not Dirtified so nothing to do, return now\n", This);
        goto unlock_end;
    }

    if (0 == This->resource.usage) { /* classic surface */
        /**
         * nothing to do
         * waiting to reload the surface via IDirect3DDevice8::UpdateTexture
         */
    } else if (WINED3DUSAGE_RENDERTARGET & This->resource.usage) { /* render surfaces */

        /****************************
        * TODO: Render targets are 'special' and
        * ?some? locking needs to be passed onto the context manager
        * so that it becomes possible to use auxiliary 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;
            GLint  prev_draw;
            GLint  prev_rasterpos[4];

            ENTER_GL();

            glFlush();
            vcheckGLcall("glFlush");
            glGetIntegerv(GL_DRAW_BUFFER, &prev_draw);
            vcheckGLcall("glIntegerv");
            glGetIntegerv(GL_PACK_SWAP_BYTES, &prev_store);
            vcheckGLcall("glIntegerv");
            glGetIntegerv(GL_CURRENT_RASTER_POSITION, &prev_rasterpos[0]);
            vcheckGLcall("glIntegerv");
            glPixelZoom(1.0, -1.0);
            vcheckGLcall("glPixelZoom");

            /* 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 ( (!myDevice->last_was_rhw) || (myDevice->viewport_changed) ) {

                double X, Y, height, width, minZ, maxZ;
                myDevice->last_was_rhw = TRUE;
                myDevice->viewport_changed = FALSE;

                /* Transformed already into viewport coordinates, so we do not need transform
                   matrices. Reset all matrices to identity and leave the default matrix in world
                   mode.                                                                         */
                glMatrixMode(GL_MODELVIEW);
                checkGLcall("glMatrixMode");
                glLoadIdentity();
                checkGLcall("glLoadIdentity");

                glMatrixMode(GL_PROJECTION);
                checkGLcall("glMatrixMode");
                glLoadIdentity();
                checkGLcall("glLoadIdentity");

                /* Set up the viewport to be full viewport */
                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");

                /* Window Coord 0 is the middle of the first pixel, so translate by half
                   a pixel (See comment above glTranslate below)                         */
                glTranslatef(0.5, 0.5, 0);
                checkGLcall("glTranslatef(0.5, 0.5, 0)");
            }

            if (iface ==  implSwapChain->backBuffer || iface == myDevice->renderTarget) {
                glDrawBuffer(GL_BACK);
            } 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 */
            glGetIntegerv(GL_UNPACK_ROW_LENGTH, &skipBytes);
            glPixelStorei(GL_UNPACK_ROW_LENGTH, This->currentDesc.Width);

            /* And back buffers are not blended */
            glDisable(GL_BLEND);

            glRasterPos3i(This->lockedRect.left, This->lockedRect.top, 1);
            vcheckGLcall("glRasterPos2f");
            switch (This->resource.format) {
	    case WINED3DFMT_X4R4G4B4:
	        {
		    int size;
                    unsigned short *data;
                    data = (unsigned short *)This->resource.allocatedMemory;
                    size = (This->lockedRect.bottom - This->lockedRect.top) * (This->lockedRect.right - This->lockedRect.left);
                    while(size > 0) {
                            *data |= 0xF000;
                            data++;
                            size--;
                    }
		}
	    case WINED3DFMT_A4R4G4B4:
	        {
                    glDrawPixels(This->lockedRect.right - This->lockedRect.left, (This->lockedRect.bottom - This->lockedRect.top)-1,
                                 GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4_REV, This->resource.allocatedMemory);
                    vcheckGLcall("glDrawPixels");
	        }
		break;
            case WINED3DFMT_R5G6B5:
                {
                    glDrawPixels(This->lockedRect.right - This->lockedRect.left, (This->lockedRect.bottom - This->lockedRect.top)-1,
                                 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, This->resource.allocatedMemory);
                    vcheckGLcall("glDrawPixels");
                }
                break;
            case WINED3DFMT_X1R5G5B5:
                {
                    int size;
                    unsigned short *data;
                    data = (unsigned short *)This->resource.allocatedMemory;
                    size = (This->lockedRect.bottom - This->lockedRect.top) * (This->lockedRect.right - This->lockedRect.left);
                    while(size > 0) {
                            *data |= 0x8000;
                            data++;
                            size--;
                    }
                }
            case WINED3DFMT_A1R5G5B5:
                {
                    glDrawPixels(This->lockedRect.right - This->lockedRect.left, (This->lockedRect.bottom - This->lockedRect.top)-1,
                                 GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, This->resource.allocatedMemory);
                    vcheckGLcall("glDrawPixels");
                }
                break;
            case WINED3DFMT_R8G8B8:
                {
                    glDrawPixels(This->lockedRect.right - This->lockedRect.left, (This->lockedRect.bottom - This->lockedRect.top)-1,
                                 GL_RGB, GL_UNSIGNED_BYTE, This->resource.allocatedMemory);
                    vcheckGLcall("glDrawPixels");
                }
                break;
            case WINED3DFMT_X8R8G8B8: /* make sure the X byte is set to alpha on, since it 
                                        could be any random value this fixes the intro move in Pirates! */
                {
                    int size;
                    unsigned int *data;
                    data = (unsigned int *)This->resource.allocatedMemory;
                    size = (This->lockedRect.bottom - This->lockedRect.top) * (This->lockedRect.right - This->lockedRect.left);
                    while(size > 0) {
                            *data |= 0xFF000000;
                            data++;
                            size--;
                    }
                }
            case WINED3DFMT_A8R8G8B8:
                {
                    glPixelStorei(GL_PACK_SWAP_BYTES, TRUE);
                    vcheckGLcall("glPixelStorei");
                    glDrawPixels(This->lockedRect.right - This->lockedRect.left, (This->lockedRect.bottom - This->lockedRect.top)-1,
                                 GL_BGRA, GL_UNSIGNED_BYTE, This->resource.allocatedMemory);
                    vcheckGLcall("glDrawPixels");
                    glPixelStorei(GL_PACK_SWAP_BYTES, prev_store);
                    vcheckGLcall("glPixelStorei");
                }
                break;
            case WINED3DFMT_A2R10G10B10:
                {
                    glPixelStorei(GL_PACK_SWAP_BYTES, TRUE);
                    vcheckGLcall("glPixelStorei");
                    glDrawPixels(This->lockedRect.right - This->lockedRect.left, (This->lockedRect.bottom - This->lockedRect.top)-1,
                                 GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, This->resource.allocatedMemory);
                    vcheckGLcall("glDrawPixels");
                    glPixelStorei(GL_PACK_SWAP_BYTES, prev_store);
                    vcheckGLcall("glPixelStorei");
                }
                break;
            default:
                FIXME("Unsupported Format %u in locking func\n", This->resource.format);
            }

            glPixelZoom(1.0,1.0);
            vcheckGLcall("glPixelZoom");
            glDrawBuffer(prev_draw);
            vcheckGLcall("glDrawBuffer");
            glRasterPos3iv(&prev_rasterpos[0]);
            vcheckGLcall("glRasterPos3iv");

            /* Reset to previous pack row length / blending state */
            glPixelStorei(GL_UNPACK_ROW_LENGTH, skipBytes);
            if (myDevice->stateBlock->renderState[D3DRS_ALPHABLENDENABLE]) glEnable(GL_BLEND);

            LEAVE_GL();

            /** restore clean dirty state */
            IWineD3DSurface_CleanDirtyRect(iface);

        } else {
            FIXME("unsupported unlocking to Rendering surface surf@%p usage(%s)\n", This, debug_d3dusage(This->resource.usage));
        }
        IWineD3DSwapChain_Release((IWineD3DSwapChain *)implSwapChain);

    } else if (WINED3DUSAGE_DEPTHSTENCIL & This->resource.usage) { /* stencil surfaces */

        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);
        }

    } else {
        FIXME("unsupported unlocking to surface surf@%p usage(%s)\n", This, debug_d3dusage(This->resource.usage));
    }

    unlock_end:
    This->Flags &= ~SFLAG_LOCKED;
    memset(&This->lockedRect, 0, sizeof(RECT));
    return WINED3D_OK;
}

HRESULT WINAPI IWineD3DSurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHDC) {
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
    FIXME("No support for GetDC yet for surface %p\n", This);
    return WINED3DERR_INVALIDCALL;
}

HRESULT WINAPI IWineD3DSurfaceImpl_ReleaseDC(IWineD3DSurface *iface, HDC hDC) {
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
    FIXME("No support for ReleaseDC yet for surface %p\n", This);
    return WINED3DERR_INVALIDCALL;
}

/* ******************************************************
   IWineD3DSurface Internal (No mapping to directx api) parts follow
   ****************************************************** */
HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface) {
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;

    if (This->Flags & SFLAG_INTEXTURE) {
        TRACE("Surface already in texture\n");
        return WINED3D_OK;
    }
    if (!(This->Flags & SFLAG_DIRTY)) {
        TRACE("surface isn't dirty\n");
        return WINED3D_OK;
    }

    This->Flags &= ~SFLAG_DIRTY;

    /* Resources are placed in system RAM and do not need to be recreated when a device is lost.
    *  These resources are not bound by device size or format restrictions. Because of this,
    *  these resources cannot be accessed by the Direct3D device nor set as textures or render targets.
    *  However, these resources can always be created, locked, and copied.
    *  In general never store scratch or system mem textures in the video ram. However it is allowed
    *  for system memory textures when WINED3DDEVCAPS_TEXTURESYSTEMMEMORY is set but it isn't right now.
    */
    if (This->resource.pool == WINED3DPOOL_SCRATCH || This->resource.pool == WINED3DPOOL_SYSTEMMEM)
    {
        FIXME("(%p) Operation not supported for scratch or SYSTEMMEM textures\n",This);
        return WINED3DERR_INVALIDCALL;
    }

    if (This->Flags & SFLAG_INPBUFFER) {
        ENTER_GL();

        if (This->glDescription.level != 0)
            FIXME("Surface in texture is only supported for level 0\n");
        else if (This->resource.format == WINED3DFMT_P8 || This->resource.format == WINED3DFMT_A8P8 ||
                 This->resource.format == WINED3DFMT_DXT1 || This->resource.format == WINED3DFMT_DXT2 ||
                 This->resource.format == WINED3DFMT_DXT3 || This->resource.format == WINED3DFMT_DXT4 ||
                 This->resource.format == WINED3DFMT_DXT5)
            FIXME("Format %d not supported\n", This->resource.format);
        else {
            GLint prevRead;
            glGetIntegerv(GL_READ_BUFFER, &prevRead);
            vcheckGLcall("glGetIntegerv");
            glReadBuffer(GL_BACK);
            vcheckGLcall("glReadBuffer");

            glCopyTexImage2D(This->glDescription.target,
                             This->glDescription.level,
                             This->glDescription.glFormatInternal,
                             0,
                             0,
                             This->currentDesc.Width,
                             This->currentDesc.Height,
                             0);

            checkGLcall("glCopyTexImage2D");
            glReadBuffer(prevRead);
            vcheckGLcall("glReadBuffer");
            TRACE("Updating target %d\n", This->glDescription.target);
            This->Flags |= SFLAG_INTEXTURE;
        }
        LEAVE_GL();
        return WINED3D_OK;
    }

    if ((This->resource.format == WINED3DFMT_P8 || This->resource.format == WINED3DFMT_A8P8) &&
        !GL_SUPPORT(EXT_PALETTED_TEXTURE)) {
        /**
         * wanted a paletted texture and not really support it in HW
         * so software emulation code begin
         */
        UINT i;
        PALETTEENTRY* pal = This->resource.wineD3DDevice->palettes[This->resource.wineD3DDevice->currentPalette];
        VOID* surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->currentDesc.Width * This->currentDesc.Height * sizeof(DWORD));
        BYTE* dst = (BYTE*) surface;
        BYTE* src = (BYTE*) This->resource.allocatedMemory;

        for (i = 0; i < This->currentDesc.Width * This->currentDesc.Height; i++) {
            BYTE color = *src++;
            *dst++ = pal[color].peRed;
            *dst++ = pal[color].peGreen;
            *dst++ = pal[color].peBlue;
            if (This->resource.format == WINED3DFMT_A8P8)
                *dst++ = pal[color].peFlags;
            else
                *dst++ = 0xFF;
        }

        ENTER_GL();

        TRACE("Calling glTexImage2D %x i=%d, intfmt=%x, w=%d, h=%d,0=%d, glFmt=%x, glType=%x, Mem=%p\n",
              This->glDescription.target,
              This->glDescription.level,
              GL_RGBA,
              This->currentDesc.Width,
              This->currentDesc.Height,
              0,
              GL_RGBA,
              GL_UNSIGNED_BYTE,
              surface);
        glTexImage2D(This->glDescription.target,
                     This->glDescription.level,
                     GL_RGBA,
                     This->currentDesc.Width,
                     This->currentDesc.Height,
                     0,
                     GL_RGBA,
                     GL_UNSIGNED_BYTE,
                     surface);
        checkGLcall("glTexImage2D");
        HeapFree(GetProcessHeap(), 0, surface);

        LEAVE_GL();

        return WINED3D_OK;
    }

    /* TODO: Compressed non-power 2 support */

    if (This->resource.format == WINED3DFMT_DXT1 ||
        This->resource.format == WINED3DFMT_DXT2 ||
        This->resource.format == WINED3DFMT_DXT3 ||
        This->resource.format == WINED3DFMT_DXT4 ||
        This->resource.format == WINED3DFMT_DXT5) {
        if (!GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
            FIXME("Using DXT1/3/5 without advertized support\n");
        } else if (This->resource.allocatedMemory) {
            TRACE("Calling glCompressedTexImage2D %x i=%d, intfmt=%x, w=%d, h=%d,0=%d, sz=%d, Mem=%p\n",
                  This->glDescription.target,
                  This->glDescription.level,
                  This->glDescription.glFormatInternal,
                  This->currentDesc.Width,
                  This->currentDesc.Height,
                  0,
                  This->resource.size,
                  This->resource.allocatedMemory);

            ENTER_GL();

            GL_EXTCALL(glCompressedTexImage2DARB)(This->glDescription.target,
                                                  This->glDescription.level,
                                                  This->glDescription.glFormatInternal,
                                                  This->currentDesc.Width,
                                                  This->currentDesc.Height,
                                                  0,
                                                  This->resource.size,
                                                  This->resource.allocatedMemory);
            checkGLcall("glCommpressedTexImage2D");

            LEAVE_GL();

            if(!(This->Flags & SFLAG_DONOTFREE)){
                HeapFree(GetProcessHeap(), 0, This->resource.allocatedMemory);
                This->resource.allocatedMemory = NULL;
            }
        }
    } else {

       /* TODO: possibly use texture rectangle (though we are probably more compatible without it) */
        if (NP2_REPACK == wined3d_settings.nonpower2_mode && (This->Flags & SFLAG_NONPOW2)) {


            TRACE("non power of two support\n");
            ENTER_GL();
            TRACE("(%p) Calling 2 glTexImage2D %x i=%d, d3dfmt=%s, intfmt=%x, w=%d, h=%d,0=%d, glFmt=%x, glType=%x, Mem=%p\n", This,
                This->glDescription.target,
                This->glDescription.level,
                debug_d3dformat(This->resource.format),
                This->glDescription.glFormatInternal,
                This->pow2Width,
                This->pow2Height,
                0,
                This->glDescription.glFormat,
                This->glDescription.glType,
                NULL);

            glTexImage2D(This->glDescription.target,
                         This->glDescription.level,
                         This->glDescription.glFormatInternal,
                         This->pow2Width,
                         This->pow2Height,
                         0/*border*/,
                         This->glDescription.glFormat,
                         This->glDescription.glType,
                         NULL);

            checkGLcall("glTexImage2D");
            if (This->resource.allocatedMemory != NULL) {
                TRACE("(%p) Calling glTexSubImage2D w(%d) h(%d) mem(%p)\n", This, This->currentDesc.Width, This->currentDesc.Height, This->resource.allocatedMemory);
                /* And map the non-power two data into the top left corner */
                glTexSubImage2D(
                    This->glDescription.target,
                    This->glDescription.level,
                    0 /* xoffset */,
                    0 /* ysoffset */ ,
                    This->currentDesc.Width,
                    This->currentDesc.Height,
                    This->glDescription.glFormat,
                    This->glDescription.glType,
                    This->resource.allocatedMemory
                );
                checkGLcall("glTexSubImage2D");
            }
            LEAVE_GL();

        } else {

            TRACE("Calling 2 glTexImage2D %x i=%d, d3dfmt=%s, intfmt=%x, w=%d, h=%d,0=%d, glFmt=%x, glType=%x, Mem=%p\n",
                This->glDescription.target,
                This->glDescription.level,
                debug_d3dformat(This->resource.format),
                This->glDescription.glFormatInternal,
                This->pow2Width,
                This->pow2Height,
                0,
                This->glDescription.glFormat,
                This->glDescription.glType,
                This->resource.allocatedMemory);

            ENTER_GL();
            glTexImage2D(This->glDescription.target,
                        This->glDescription.level,
                        This->glDescription.glFormatInternal,
                        This->pow2Width,
                        This->pow2Height,
                        0 /* border */,
                        This->glDescription.glFormat,
                        This->glDescription.glType,
                        This->resource.allocatedMemory);
            checkGLcall("glTexImage2D");
            LEAVE_GL();
        }

#if 0
        {
            static unsigned int gen = 0;
            char buffer[4096];
            ++gen;
            if ((gen % 10) == 0) {
                snprintf(buffer, sizeof(buffer), "/tmp/surface%p_type%u_level%u_%u.ppm", This, This->glDescription.target, This->glDescription.level, gen);
                IWineD3DSurfaceImpl_SaveSnapshot(iface, buffer);
            }
            /*
             * debugging crash code
            if (gen == 250) {
              void** test = NULL;
              *test = 0;
            }
            */
        }
#endif
        if(!(This->Flags & SFLAG_DONOTFREE)){
            HeapFree(GetProcessHeap(),0,This->resource.allocatedMemory);
            This->resource.allocatedMemory = NULL;
        }

    }

    return WINED3D_OK;
}

#include <errno.h>
#include <stdio.h>
HRESULT WINAPI IWineD3DSurfaceImpl_SaveSnapshot(IWineD3DSurface *iface, const char* filename) {
    FILE* f = NULL;
    UINT i, y;
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
    char *allocatedMemory;
    char *textureRow;
    IWineD3DSwapChain *swapChain = NULL;
    int width, height;
    GLuint tmpTexture;
    DWORD color;
    /*FIXME:
    Textures my not be stored in ->allocatedgMemory and a GlTexture
    so we should lock the surface before saving a snapshot, or at least check that
    */
    /* TODO: Compressed texture images can be obtained from the GL in uncompressed form
    by calling GetTexImage and in compressed form by calling
    GetCompressedTexImageARB.  Queried compressed images can be saved and
    later reused by calling CompressedTexImage[123]DARB.  Pre-compressed
    texture images do not need to be processed by the GL and should
    significantly improve texture loading performance relative to uncompressed
    images. */

/* Setup the width and height to be the internal texture width and height. */
    width  = This->pow2Width;
    height = This->pow2Height;
/* check to see if were a 'virtual' texture e.g. were not a pbuffer of texture were a back buffer*/
    IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapChain);

    if (swapChain || (This->Flags & SFLAG_INPBUFFER)) { /* if were not a real texture then read the back buffer into a real texture*/
/* we don't want to interfere with the back buffer so read the data into a temporary texture and then save the data out of the temporary texture */
        GLint prevRead;
        ENTER_GL();
        FIXME("(%p) This surface needs to be locked before a snapshot can be taken\n", This);
        glEnable(GL_TEXTURE_2D);

        glGenTextures(1, &tmpTexture);
        glBindTexture(GL_TEXTURE_2D, tmpTexture);

        glTexImage2D(GL_TEXTURE_2D,
                        0,
                        GL_RGBA,
                        width,
                        height,
                        0/*border*/,
                        GL_RGBA,
                        GL_UNSIGNED_INT_8_8_8_8_REV,
                        NULL);

        glGetIntegerv(GL_READ_BUFFER, &prevRead);
        vcheckGLcall("glGetIntegerv");
        glReadBuffer(GL_BACK);
        vcheckGLcall("glReadBuffer");
        glCopyTexImage2D(GL_TEXTURE_2D,
                            0,
                            GL_RGBA,
                            0,
                            0,
                            width,
                            height,
                            0);

        checkGLcall("glCopyTexImage2D");
        glReadBuffer(prevRead);
        LEAVE_GL();

    } else { /* bind the real texture */
        IWineD3DSurface_PreLoad(iface);
    }
    allocatedMemory = HeapAlloc(GetProcessHeap(), 0, width  * height * 4);
    ENTER_GL();
    FIXME("Saving texture level %d width %d height %d\n", This->glDescription.level, width, height);
    glGetTexImage(GL_TEXTURE_2D,
                This->glDescription.level,
                GL_RGBA,
                GL_UNSIGNED_INT_8_8_8_8_REV,
                allocatedMemory);
    checkGLcall("glTexImage2D");
    if (tmpTexture) {
        glBindTexture(GL_TEXTURE_2D, 0);
        glDeleteTextures(1, &tmpTexture);
    }
    LEAVE_GL();

    f = fopen(filename, "w+");
    if (NULL == f) {
        ERR("opening of %s failed with: %s\n", filename, strerror(errno));
        return WINED3DERR_INVALIDCALL;
    }
/* Save the dat out to a TGA file because 1: it's an easy raw format, 2: it supports an alpha chanel*/
    TRACE("(%p) opened %s with format %s\n", This, filename, debug_d3dformat(This->resource.format));
/* TGA header */
    fputc(0,f);
    fputc(0,f);
    fputc(2,f);
    fputc(0,f);
    fputc(0,f);
    fputc(0,f);
    fputc(0,f);
    fputc(0,f);
    fputc(0,f);
    fputc(0,f);
    fputc(0,f);
    fputc(0,f);
/* short width*/
    fwrite(&width,2,1,f);
/* short height */
    fwrite(&height,2,1,f);
/* format rgba */
    fputc(0x20,f);
    fputc(0x28,f);
/* raw data */
    /* if  the data is upside down if we've fetched it from a back buffer, so it needs flipping again to make it the correct way up*/
    if(swapChain)
        textureRow = allocatedMemory + (width * (height - 1) *4);
    else
        textureRow = allocatedMemory;
    for (y = 0 ; y < height; y++) {
        for (i = 0; i < width;  i++) {
            color = *((DWORD*)textureRow);
            fputc((color >> 16) & 0xFF, f); /* B */
            fputc((color >>  8) & 0xFF, f); /* G */
            fputc((color >>  0) & 0xFF, f); /* R */
            fputc((color >> 24) & 0xFF, f); /* A */
            textureRow += 4;
        }
        /* take two rows of the pointer to the texture memory */
        if(swapChain)
            (textureRow-= width << 3);

    }
    TRACE("Closing file\n");
    fclose(f);

    if(swapChain) {
        IWineD3DSwapChain_Release(swapChain);
    }
    HeapFree(GetProcessHeap(), 0, allocatedMemory);
    return WINED3D_OK;
}

HRESULT WINAPI IWineD3DSurfaceImpl_CleanDirtyRect(IWineD3DSurface *iface) {
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
    This->Flags &= ~SFLAG_DIRTY;
    This->dirtyRect.left   = This->currentDesc.Width;
    This->dirtyRect.top    = This->currentDesc.Height;
    This->dirtyRect.right  = 0;
    This->dirtyRect.bottom = 0;
    TRACE("(%p) : Dirty?%d, Rect:(%ld,%ld,%ld,%ld)\n", This, This->Flags & SFLAG_DIRTY ? 1 : 0, This->dirtyRect.left,
          This->dirtyRect.top, This->dirtyRect.right, This->dirtyRect.bottom);
    return WINED3D_OK;
}

/**
 *   Slightly inefficient way to handle multiple dirty rects but it works :)
 */
extern HRESULT WINAPI IWineD3DSurfaceImpl_AddDirtyRect(IWineD3DSurface *iface, CONST RECT* pDirtyRect) {
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
    IWineD3DBaseTexture *baseTexture = NULL;
    This->Flags |= SFLAG_DIRTY;
    if (NULL != pDirtyRect) {
        This->dirtyRect.left   = min(This->dirtyRect.left,   pDirtyRect->left);
        This->dirtyRect.top    = min(This->dirtyRect.top,    pDirtyRect->top);
        This->dirtyRect.right  = max(This->dirtyRect.right,  pDirtyRect->right);
        This->dirtyRect.bottom = max(This->dirtyRect.bottom, pDirtyRect->bottom);
    } else {
        This->dirtyRect.left   = 0;
        This->dirtyRect.top    = 0;
        This->dirtyRect.right  = This->currentDesc.Width;
        This->dirtyRect.bottom = This->currentDesc.Height;
    }
    TRACE("(%p) : Dirty?%d, Rect:(%ld,%ld,%ld,%ld)\n", This, This->Flags & SFLAG_DIRTY, This->dirtyRect.left,
          This->dirtyRect.top, This->dirtyRect.right, This->dirtyRect.bottom);
    /* if the container is a basetexture then mark it dirty. */
    if (IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&baseTexture) == WINED3D_OK) {
        TRACE("Passing to conatiner\n");
        IWineD3DBaseTexture_SetDirty(baseTexture, TRUE);
        IWineD3DBaseTexture_Release(baseTexture);
    }
    return WINED3D_OK;
}

HRESULT WINAPI IWineD3DSurfaceImpl_SetContainer(IWineD3DSurface *iface, IWineD3DBase *container) {
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;

    TRACE("This %p, container %p\n", This, container);

    /* We can't keep a reference to the container, since the container already keeps a reference to us. */

    TRACE("Setting container to %p from %p\n", container, This->container);
    This->container = container;

    return WINED3D_OK;
}

HRESULT WINAPI IWineD3DSurfaceImpl_SetFormat(IWineD3DSurface *iface, WINED3DFORMAT format) {
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;

    if (This->resource.format != WINED3DFMT_UNKNOWN) {
        FIXME("(%p) : The foramt of the surface must be WINED3DFORMAT_UNKNOWN\n", This);
        return WINED3DERR_INVALIDCALL;
    }

    TRACE("(%p) : Setting texture foramt to (%d,%s)\n", This, format, debug_d3dformat(format));
    if (format == WINED3DFMT_UNKNOWN) {
        This->resource.size = 0;
    } else if (format == WINED3DFMT_DXT1) {
        /* DXT1 is half byte per pixel */
        This->resource.size = ((max(This->pow2Width, 4) * D3DFmtGetBpp(This->resource.wineD3DDevice, format)) * max(This->pow2Height, 4)) >> 1;

    } else if (format == WINED3DFMT_DXT2 || format == WINED3DFMT_DXT3 ||
               format == WINED3DFMT_DXT4 || format == WINED3DFMT_DXT5) {
        This->resource.size = ((max(This->pow2Width, 4) * D3DFmtGetBpp(This->resource.wineD3DDevice, format)) * max(This->pow2Height, 4));
    } else {
        This->resource.size = (This->pow2Width * D3DFmtGetBpp(This->resource.wineD3DDevice, format)) * This->pow2Height;
    }


    /* Setup some glformat defaults */
    if (format != WINED3DFMT_UNKNOWN) {
        This->glDescription.glFormat         = D3DFmt2GLFmt(This->resource.wineD3DDevice, format);
        This->glDescription.glFormatInternal = D3DFmt2GLIntFmt(This->resource.wineD3DDevice, format);
        This->glDescription.glType           = D3DFmt2GLType(This->resource.wineD3DDevice, format);
    } else {
        This->glDescription.glFormat         = 0;
        This->glDescription.glFormatInternal = 0;
        This->glDescription.glType           = 0;
    }

    if (format != WINED3DFMT_UNKNOWN) {
        This->bytesPerPixel = D3DFmtGetBpp(This->resource.wineD3DDevice, format);
        This->pow2Size      = (This->pow2Width * This->bytesPerPixel) * This->pow2Height;
    } else {
        This->bytesPerPixel = 0;
        This->pow2Size      = 0;
    }

    This->Flags |= (WINED3DFMT_D16_LOCKABLE == format) ? SFLAG_LOCKABLE : 0;

    This->resource.format = format;

    TRACE("(%p) : Size %d, pow2Size %d, bytesPerPixel %d, glFormat %d, glFotmatInternal %d, glType %d\n", This, This->resource.size, This->pow2Size, This->bytesPerPixel, This->glDescription.glFormat, This->glDescription.glFormatInternal, This->glDescription.glType);

    return WINED3D_OK;
}

/* TODO: replace this function with context management routines */
HRESULT WINAPI IWineD3DSurfaceImpl_SetPBufferState(IWineD3DSurface *iface, BOOL inPBuffer, BOOL  inTexture) {
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;

    if(inPBuffer) {
        This->Flags |= SFLAG_INPBUFFER;
    } else {
        This->Flags &= ~SFLAG_INPBUFFER;
    }

    if(inTexture) {
        This->Flags |= SFLAG_INTEXTURE;
    } else {
        This->Flags &= ~SFLAG_INTEXTURE;
    }

    return WINED3D_OK;
}

HRESULT WINAPI IWineD3DSurfaceImpl_Flip(IWineD3DSurface *iface, IWineD3DSurface *override, DWORD Flags) {
    FIXME("This is unimplemented for now(d3d7 merge)\n");
    return WINED3DERR_INVALIDCALL;
}

HRESULT WINAPI IWineD3DSurfaceImpl_Blt(IWineD3DSurface *iface, RECT *DestRect, IWineD3DSurface *SrcSurface, RECT *SrcRect, DWORD Flags, DDBLTFX *DDBltFx) {
    FIXME("This is unimplemented for now(d3d7 merge)\n");
    return WINED3DERR_INVALIDCALL;
}

HRESULT WINAPI IWineD3DSurfaceImpl_GetBltStatus(IWineD3DSurface *iface, DWORD Flags) {
    FIXME("This is unimplemented for now(d3d7 merge)\n");
    return WINED3DERR_INVALIDCALL;
}

HRESULT WINAPI IWineD3DSurfaceImpl_GetFlipStatus(IWineD3DSurface *iface, DWORD Flags) {
    FIXME("This is unimplemented for now(d3d7 merge)\n");
    return WINED3DERR_INVALIDCALL;
}

HRESULT WINAPI IWineD3DSurfaceImpl_IsLost(IWineD3DSurface *iface) {
    FIXME("This is unimplemented for now(d3d7 merge)\n");
    return WINED3DERR_INVALIDCALL;
}

HRESULT WINAPI IWineD3DSurfaceImpl_Restore(IWineD3DSurface *iface) {
    FIXME("This is unimplemented for now(d3d7 merge)\n");
    return WINED3DERR_INVALIDCALL;
}

HRESULT WINAPI IWineD3DSurfaceImpl_BltFast(IWineD3DSurface *iface, DWORD dstx, DWORD dsty, IWineD3DSurface *Source, RECT *rsrc, DWORD trans) {
    FIXME("This is unimplemented for now(d3d7 merge)\n");
    return WINED3DERR_INVALIDCALL;
}

HRESULT WINAPI IWineD3DSurfaceImpl_SetPixelFormat(IWineD3DSurface *iface, WINED3DFORMAT Format, BYTE *Surface, DWORD Size) {
    FIXME("This is unimplemented for now(d3d7 merge)\n");
    return WINED3DERR_INVALIDCALL;
}

HRESULT WINAPI IWineD3DSurfaceImpl_GetPalette(IWineD3DSurface *iface, IWineD3DPalette **Pal) {
    FIXME("This is unimplemented for now(d3d7 merge)\n");
    return WINED3DERR_INVALIDCALL;
}

HRESULT WINAPI IWineD3DSurfaceImpl_RealizePalette(IWineD3DSurface *iface) {
    FIXME("This is unimplemented for now(d3d7 merge)\n");
    return WINED3DERR_INVALIDCALL;
}

HRESULT WINAPI IWineD3DSurfaceImpl_SetPalette(IWineD3DSurface *iface, IWineD3DPalette *Pal) {
    FIXME("This is unimplemented for now(d3d7 merge)\n");
    return WINED3DERR_INVALIDCALL;
}

HRESULT WINAPI IWineD3DSurfaceImpl_SetColorKey(IWineD3DSurface *iface, DWORD Flags, DDCOLORKEY *CKey) {
    FIXME("This is unimplemented for now(d3d7 merge)\n");
    return WINED3DERR_INVALIDCALL;
}

HRESULT WINAPI IWineD3DSurfaceImpl_PrivateSetup(IWineD3DSurface *iface) {
    /* Nothing to do for now */
    return WINED3D_OK;
}

const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl =
{
    /* IUnknown */
    IWineD3DSurfaceImpl_QueryInterface,
    IWineD3DSurfaceImpl_AddRef,
    IWineD3DSurfaceImpl_Release,
    /* IWineD3DResource */
    IWineD3DSurfaceImpl_GetParent,
    IWineD3DSurfaceImpl_GetDevice,
    IWineD3DSurfaceImpl_SetPrivateData,
    IWineD3DSurfaceImpl_GetPrivateData,
    IWineD3DSurfaceImpl_FreePrivateData,
    IWineD3DSurfaceImpl_SetPriority,
    IWineD3DSurfaceImpl_GetPriority,
    IWineD3DSurfaceImpl_PreLoad,
    IWineD3DSurfaceImpl_GetType,
    /* IWineD3DSurface */
    IWineD3DSurfaceImpl_GetContainerParent,
    IWineD3DSurfaceImpl_GetContainer,
    IWineD3DSurfaceImpl_GetDesc,
    IWineD3DSurfaceImpl_LockRect,
    IWineD3DSurfaceImpl_UnlockRect,
    IWineD3DSurfaceImpl_GetDC,
    IWineD3DSurfaceImpl_ReleaseDC,
    IWineD3DSurfaceImpl_Flip,
    IWineD3DSurfaceImpl_Blt,
    IWineD3DSurfaceImpl_GetBltStatus,
    IWineD3DSurfaceImpl_GetFlipStatus,
    IWineD3DSurfaceImpl_IsLost,
    IWineD3DSurfaceImpl_Restore,
    IWineD3DSurfaceImpl_BltFast,
    IWineD3DSurfaceImpl_SetPixelFormat,
    IWineD3DSurfaceImpl_GetPalette,
    IWineD3DSurfaceImpl_SetPalette,
    IWineD3DSurfaceImpl_RealizePalette,
    IWineD3DSurfaceImpl_SetColorKey,
    /* Internal use: */
    IWineD3DSurfaceImpl_CleanDirtyRect,
    IWineD3DSurfaceImpl_AddDirtyRect,
    IWineD3DSurfaceImpl_LoadTexture,
    IWineD3DSurfaceImpl_SaveSnapshot,
    IWineD3DSurfaceImpl_SetContainer,
    IWineD3DSurfaceImpl_SetPBufferState,
    IWineD3DSurfaceImpl_SetGlTextureDesc,
    IWineD3DSurfaceImpl_GetGlDesc,
    IWineD3DSurfaceImpl_GetData,
    IWineD3DSurfaceImpl_SetFormat,
    IWineD3DSurfaceImpl_PrivateSetup
};
