/*
 * IWineD3DSurface Implementation
 *
 * Copyright 1998 Lionel Ulmer
 * Copyright 2000-2001 TransGaming Technologies Inc.
 * Copyright 2002-2005 Jason Edmeades
 * Copyright 2002-2003 Raphael Junqueira
 * Copyright 2004 Christian Costa
 * Copyright 2005 Oliver Stieber
 * Copyright 2006-2008 Stefan Dösinger for CodeWeavers
 * Copyright 2007-2008 Henri Verbeet
 * Copyright 2006-2008 Roderick Colenbrander
 * Copyright 2009 Henri Verbeet for CodeWeavers
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

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

WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface);
WINE_DECLARE_DEBUG_CHANNEL(d3d);

#define GLINFO_LOCATION (*gl_info)

static void surface_cleanup(IWineD3DSurfaceImpl *This)
{
    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
    renderbuffer_entry_t *entry, *entry2;

    TRACE("(%p) : Cleaning up.\n", This);

    /* Need a context to destroy the texture. Use the currently active render
     * target, but only if the primary render target exists. Otherwise
     * lastActiveRenderTarget is garbage. When destroying the primary render
     * target, Uninit3D() will activate a context before doing anything. */
    if (device->render_targets && device->render_targets[0])
    {
        ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
    }

    ENTER_GL();

    if (This->texture_name)
    {
        /* Release the OpenGL texture. */
        TRACE("Deleting texture %u.\n", This->texture_name);
        glDeleteTextures(1, &This->texture_name);
    }

    if (This->Flags & SFLAG_PBO)
    {
        /* Delete the PBO. */
        GL_EXTCALL(glDeleteBuffersARB(1, &This->pbo));
    }

    LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &This->renderbuffers, renderbuffer_entry_t, entry)
    {
        gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
        HeapFree(GetProcessHeap(), 0, entry);
    }

    LEAVE_GL();

    if (This->Flags & SFLAG_DIBSECTION)
    {
        /* Release the DC. */
        SelectObject(This->hDC, This->dib.holdbitmap);
        DeleteDC(This->hDC);
        /* Release the DIB section. */
        DeleteObject(This->dib.DIBsection);
        This->dib.bitmap_data = NULL;
        This->resource.allocatedMemory = NULL;
    }

    if (This->Flags & SFLAG_USERPTR) IWineD3DSurface_SetMem((IWineD3DSurface *)This, NULL);
    if (This->overlay_dest) list_remove(&This->overlay_entry);

    HeapFree(GetProcessHeap(), 0, This->palette9);

    resource_cleanup((IWineD3DResource *)This);
}

UINT surface_calculate_size(const struct GlPixelFormatDesc *format_desc, UINT alignment, UINT width, UINT height)
{
    UINT size;

    if (format_desc->format == WINED3DFMT_UNKNOWN)
    {
        size = 0;
    }
    else if (format_desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
    {
        UINT row_block_count = (width + format_desc->block_width - 1) / format_desc->block_width;
        UINT row_count = (height + format_desc->block_height - 1) / format_desc->block_height;
        size = row_count * row_block_count * format_desc->block_byte_count;
    }
    else
    {
        /* The pitch is a multiple of 4 bytes. */
        size = height * (((width * format_desc->byte_count) + alignment - 1) & ~(alignment - 1));
    }

    if (format_desc->heightscale != 0.0f) size *= format_desc->heightscale;

    return size;
}

HRESULT surface_init(IWineD3DSurfaceImpl *surface, WINED3DSURFTYPE surface_type, UINT alignment,
        UINT width, UINT height, UINT level, BOOL lockable, BOOL discard, WINED3DMULTISAMPLE_TYPE multisample_type,
        UINT multisample_quality, IWineD3DDeviceImpl *device, DWORD usage, WINED3DFORMAT format,
        WINED3DPOOL pool, IUnknown *parent, const struct wined3d_parent_ops *parent_ops)
{
    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
    const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(format, &GLINFO_LOCATION);
    void (*cleanup)(IWineD3DSurfaceImpl *This);
    unsigned int resource_size;
    HRESULT hr;

    if (multisample_quality > 0)
    {
        FIXME("multisample_quality set to %u, substituting 0\n", multisample_quality);
        multisample_quality = 0;
    }

    /* FIXME: Check that the format is supported by the device. */

    resource_size = surface_calculate_size(format_desc, alignment, width, height);

    /* Look at the implementation and set the correct Vtable. */
    switch (surface_type)
    {
        case SURFACE_OPENGL:
            surface->lpVtbl = &IWineD3DSurface_Vtbl;
            cleanup = surface_cleanup;
            break;

        case SURFACE_GDI:
            surface->lpVtbl = &IWineGDISurface_Vtbl;
            cleanup = surface_gdi_cleanup;
            break;

        default:
            ERR("Requested unknown surface implementation %#x.\n", surface_type);
            return WINED3DERR_INVALIDCALL;
    }

    hr = resource_init((IWineD3DResource *)surface, WINED3DRTYPE_SURFACE,
            device, resource_size, usage, format_desc, pool, parent, parent_ops);
    if (FAILED(hr))
    {
        WARN("Failed to initialize resource, returning %#x.\n", hr);
        return hr;
    }

    /* "Standalone" surface. */
    IWineD3DSurface_SetContainer((IWineD3DSurface *)surface, NULL);

    surface->currentDesc.Width = width;
    surface->currentDesc.Height = height;
    surface->currentDesc.MultiSampleType = multisample_type;
    surface->currentDesc.MultiSampleQuality = multisample_quality;
    surface->texture_level = level;
    list_init(&surface->overlays);

    /* Flags */
    surface->Flags = SFLAG_NORMCOORD; /* Default to normalized coords. */
    if (discard) surface->Flags |= SFLAG_DISCARD;
    if (lockable || format == WINED3DFMT_D16_LOCKABLE) surface->Flags |= SFLAG_LOCKABLE;

    /* Quick lockable sanity check.
     * TODO: remove this after surfaces, usage and lockability have been debugged properly
     * this function is too deep to need to care about things like this.
     * Levels need to be checked too, since they all affect what can be done. */
    switch (pool)
    {
        case WINED3DPOOL_SCRATCH:
            if(!lockable)
            {
                FIXME("Called with a pool of SCRATCH and a lockable of FALSE "
                        "which are mutually exclusive, setting lockable to TRUE.\n");
                lockable = TRUE;
            }
            break;

        case WINED3DPOOL_SYSTEMMEM:
            if (!lockable)
                FIXME("Called with a pool of SYSTEMMEM and a lockable of FALSE, this is acceptable but unexpected.\n");
            break;

        case WINED3DPOOL_MANAGED:
            if (usage & WINED3DUSAGE_DYNAMIC)
                FIXME("Called with a pool of MANAGED and a usage of DYNAMIC which are mutually exclusive.\n");
            break;

        case WINED3DPOOL_DEFAULT:
            if (lockable && !(usage & (WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_DEPTHSTENCIL)))
                WARN("Creating a lockable surface with a POOL of DEFAULT, that doesn't specify DYNAMIC usage.\n");
            break;

        default:
            FIXME("Unknown pool %#x.\n", pool);
            break;
    };

    if (usage & WINED3DUSAGE_RENDERTARGET && pool != WINED3DPOOL_DEFAULT)
    {
        FIXME("Trying to create a render target that isn't in the default pool.\n");
    }

    /* Mark the texture as dirty so that it gets loaded first time around. */
    surface_add_dirty_rect((IWineD3DSurface *)surface, NULL);
    list_init(&surface->renderbuffers);

    TRACE("surface %p, memory %p, size %u\n", surface, surface->resource.allocatedMemory, surface->resource.size);

    /* Call the private setup routine */
    hr = IWineD3DSurface_PrivateSetup((IWineD3DSurface *)surface);
    if (FAILED(hr))
    {
        ERR("Private setup failed, returning %#x\n", hr);
        cleanup(surface);
        return hr;
    }

    return hr;
}

static void surface_force_reload(IWineD3DSurface *iface)
{
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;

    This->Flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED);
}

void surface_set_texture_name(IWineD3DSurface *iface, GLuint new_name, BOOL srgb)
{
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
    GLuint *name;
    DWORD flag;

    if(srgb)
    {
        name = &This->texture_name_srgb;
        flag = SFLAG_INSRGBTEX;
    }
    else
    {
        name = &This->texture_name;
        flag = SFLAG_INTEXTURE;
    }

    TRACE("(%p) : setting texture name %u\n", This, new_name);

    if (!*name && new_name)
    {
        /* FIXME: We shouldn't need to remove SFLAG_INTEXTURE if the
         * surface has no texture name yet. See if we can get rid of this. */
        if (This->Flags & flag)
            ERR("Surface has SFLAG_INTEXTURE set, but no texture name\n");
        IWineD3DSurface_ModifyLocation(iface, flag, FALSE);
    }

    *name = new_name;
    surface_force_reload(iface);
}

void surface_set_texture_target(IWineD3DSurface *iface, GLenum target)
{
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;

    TRACE("(%p) : setting target %#x\n", This, target);

    if (This->texture_target != target)
    {
        if (target == GL_TEXTURE_RECTANGLE_ARB)
        {
            This->Flags &= ~SFLAG_NORMCOORD;
        }
        else if (This->texture_target == GL_TEXTURE_RECTANGLE_ARB)
        {
            This->Flags |= SFLAG_NORMCOORD;
        }
    }
    This->texture_target = target;
    surface_force_reload(iface);
}

/* Context activation is done by the caller. */
static void surface_bind_and_dirtify(IWineD3DSurfaceImpl *This, BOOL srgb) {
    DWORD active_sampler;

    /* We don't need a specific texture unit, but after binding the texture the current unit is dirty.
     * Read the unit back instead of switching to 0, this avoids messing around with the state manager's
     * gl states. The current texture unit should always be a valid one.
     *
     * To be more specific, this is tricky because we can implicitly be called
     * from sampler() in state.c. This means we can't touch anything other than
     * whatever happens to be the currently active texture, or we would risk
     * marking already applied sampler states dirty again.
     *
     * TODO: Track the current active texture per GL context instead of using glGet
     */
    GLint active_texture;
    ENTER_GL();
    glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);
    LEAVE_GL();
    active_sampler = This->resource.wineD3DDevice->rev_tex_unit_map[active_texture - GL_TEXTURE0_ARB];

    if (active_sampler != WINED3D_UNMAPPED_STAGE)
    {
        IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_SAMPLER(active_sampler));
    }
    IWineD3DSurface_BindTexture((IWineD3DSurface *)This, srgb);
}

/* This function checks if the primary render target uses the 8bit paletted format. */
static BOOL primary_render_target_is_p8(IWineD3DDeviceImpl *device)
{
    if (device->render_targets && device->render_targets[0]) {
        IWineD3DSurfaceImpl* render_target = (IWineD3DSurfaceImpl*)device->render_targets[0];
        if ((render_target->resource.usage & WINED3DUSAGE_RENDERTARGET)
                && (render_target->resource.format_desc->format == WINED3DFMT_P8_UINT))
            return TRUE;
    }
    return FALSE;
}

#undef GLINFO_LOCATION

#define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info

/* This call just downloads data, the caller is responsible for binding the
 * correct texture. */
/* Context activation is done by the caller. */
static void surface_download_data(IWineD3DSurfaceImpl *This) {
    const struct GlPixelFormatDesc *format_desc = This->resource.format_desc;

    /* Only support read back of converted P8 surfaces */
    if (This->Flags & SFLAG_CONVERTED && format_desc->format != WINED3DFMT_P8_UINT)
    {
        FIXME("Read back converted textures unsupported, format=%s\n", debug_d3dformat(format_desc->format));
        return;
    }

    ENTER_GL();

    if (format_desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
    {
        TRACE("(%p) : Calling glGetCompressedTexImageARB level %d, format %#x, type %#x, data %p.\n",
                This, This->texture_level, format_desc->glFormat, format_desc->glType,
                This->resource.allocatedMemory);

        if (This->Flags & SFLAG_PBO)
        {
            GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, This->pbo));
            checkGLcall("glBindBufferARB");
            GL_EXTCALL(glGetCompressedTexImageARB(This->texture_target, This->texture_level, NULL));
            checkGLcall("glGetCompressedTexImageARB");
            GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0));
            checkGLcall("glBindBufferARB");
        }
        else
        {
            GL_EXTCALL(glGetCompressedTexImageARB(This->texture_target,
                    This->texture_level, This->resource.allocatedMemory));
            checkGLcall("glGetCompressedTexImageARB");
        }

        LEAVE_GL();
    } else {
        void *mem;
        GLenum format = format_desc->glFormat;
        GLenum type = format_desc->glType;
        int src_pitch = 0;
        int dst_pitch = 0;

        /* In case of P8 the index is stored in the alpha component if the primary render target uses P8 */
        if (format_desc->format == WINED3DFMT_P8_UINT && primary_render_target_is_p8(This->resource.wineD3DDevice))
        {
            format = GL_ALPHA;
            type = GL_UNSIGNED_BYTE;
        }

        if (This->Flags & SFLAG_NONPOW2) {
            unsigned char alignment = This->resource.wineD3DDevice->surface_alignment;
            src_pitch = format_desc->byte_count * This->pow2Width;
            dst_pitch = IWineD3DSurface_GetPitch((IWineD3DSurface *) This);
            src_pitch = (src_pitch + alignment - 1) & ~(alignment - 1);
            mem = HeapAlloc(GetProcessHeap(), 0, src_pitch * This->pow2Height);
        } else {
            mem = This->resource.allocatedMemory;
        }

        TRACE("(%p) : Calling glGetTexImage level %d, format %#x, type %#x, data %p\n",
                This, This->texture_level, format, type, mem);

        if(This->Flags & SFLAG_PBO) {
            GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, This->pbo));
            checkGLcall("glBindBufferARB");

            glGetTexImage(This->texture_target, This->texture_level, format, type, NULL);
            checkGLcall("glGetTexImage");

            GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0));
            checkGLcall("glBindBufferARB");
        } else {
            glGetTexImage(This->texture_target, This->texture_level, format, type, mem);
            checkGLcall("glGetTexImage");
        }
        LEAVE_GL();

        if (This->Flags & SFLAG_NONPOW2) {
            const BYTE *src_data;
            BYTE *dst_data;
            UINT y;
            /*
             * Some games (e.g. warhammer 40k) don't work properly with the odd pitches, 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 bpp * pow2width.
             *
             * We're 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
             * |                  |              |   \/
             * -----------------------------------
             *
             *
             * we're 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.
             *
             * Performance should not be an issue, because applications normally do not lock the surfaces when
             * rendering. If an app does, the SFLAG_DYNLOCK flag will kick in and the memory copy won't be released,
             * and doesn't have to be re-read.
             */
            src_data = mem;
            dst_data = This->resource.allocatedMemory;
            TRACE("(%p) : Repacking the surface data from pitch %d to pitch %d\n", This, src_pitch, dst_pitch);
            for (y = 1 ; y < This->currentDesc.Height; y++) {
                /* skip the first row */
                src_data += src_pitch;
                dst_data += dst_pitch;
                memcpy(dst_data, src_data, dst_pitch);
            }

            HeapFree(GetProcessHeap(), 0, mem);
        }
    }

    /* Surface has now been downloaded */
    This->Flags |= SFLAG_INSYSMEM;
}

/* This call just uploads data, the caller is responsible for binding the
 * correct texture. */
/* Context activation is done by the caller. */
static void surface_upload_data(IWineD3DSurfaceImpl *This, GLenum internal, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *data) {
    const struct GlPixelFormatDesc *format_desc = This->resource.format_desc;

    TRACE("This %p, internal %#x, width %d, height %d, format %#x, type %#x, data %p.\n",
            This, internal, width, height, format, type, data);
    TRACE("target %#x, level %u, resource size %u.\n",
            This->texture_target, This->texture_level, This->resource.size);

    if (format_desc->heightscale != 1.0f && format_desc->heightscale != 0.0f) height *= format_desc->heightscale;

    ENTER_GL();

    if (This->Flags & SFLAG_PBO)
    {
        GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->pbo));
        checkGLcall("glBindBufferARB");

        TRACE("(%p) pbo: %#x, data: %p.\n", This, This->pbo, data);
        data = NULL;
    }

    if (format_desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
    {
        TRACE("Calling glCompressedTexSubImage2DARB.\n");

        GL_EXTCALL(glCompressedTexSubImage2DARB(This->texture_target, This->texture_level,
                0, 0, width, height, internal, This->resource.size, data));
        checkGLcall("glCompressedTexSubImage2DARB");
    }
    else
    {
        TRACE("Calling glTexSubImage2D.\n");

        glTexSubImage2D(This->texture_target, This->texture_level,
                0, 0, width, height, format, type, data);
        checkGLcall("glTexSubImage2D");
    }

    if (This->Flags & SFLAG_PBO)
    {
        GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
        checkGLcall("glBindBufferARB");
    }

    LEAVE_GL();
}

/* This call just allocates the texture, the caller is responsible for binding
 * the correct texture. */
/* Context activation is done by the caller. */
static void surface_allocate_surface(IWineD3DSurfaceImpl *This, GLenum internal, GLsizei width, GLsizei height, GLenum format, GLenum type) {
    const struct GlPixelFormatDesc *format_desc = This->resource.format_desc;
    BOOL enable_client_storage = FALSE;
    const BYTE *mem = NULL;

    if (format_desc->heightscale != 1.0f && format_desc->heightscale != 0.0f) height *= format_desc->heightscale;

    TRACE("(%p) : Creating surface (target %#x)  level %d, d3d format %s, internal format %#x, width %d, height %d, gl format %#x, gl type=%#x\n",
            This, This->texture_target, This->texture_level, debug_d3dformat(format_desc->format),
            internal, width, height, format, type);

    ENTER_GL();

    if(GL_SUPPORT(APPLE_CLIENT_STORAGE)) {
        if(This->Flags & (SFLAG_NONPOW2 | SFLAG_DIBSECTION | SFLAG_OVERSIZE | SFLAG_CONVERTED) || This->resource.allocatedMemory == NULL) {
            /* In some cases we want to disable client storage.
             * SFLAG_NONPOW2 has a bigger opengl texture than the client memory, and different pitches
             * SFLAG_DIBSECTION: Dibsections may have read / write protections on the memory. Avoid issues...
             * SFLAG_OVERSIZE: The gl texture is smaller than the allocated memory
             * SFLAG_CONVERTED: The conversion destination memory is freed after loading the surface
             * allocatedMemory == NULL: Not defined in the extension. Seems to disable client storage effectively
             */
            glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
            checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE)");
            This->Flags &= ~SFLAG_CLIENT;
            enable_client_storage = TRUE;
        } else {
            This->Flags |= SFLAG_CLIENT;

            /* Point opengl to our allocated texture memory. Do not use resource.allocatedMemory here because
             * it might point into a pbo. Instead use heapMemory, but get the alignment right.
             */
            mem = (BYTE *)(((ULONG_PTR) This->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
        }
    }

    if (format_desc->Flags & WINED3DFMT_FLAG_COMPRESSED && mem)
    {
        GL_EXTCALL(glCompressedTexImage2DARB(This->texture_target, This->texture_level,
                internal, width, height, 0, This->resource.size, mem));
    }
    else
    {
        glTexImage2D(This->texture_target, This->texture_level,
                internal, width, height, 0, format, type, mem);
        checkGLcall("glTexImage2D");
    }

    if(enable_client_storage) {
        glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
        checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE)");
    }
    LEAVE_GL();
}

/* In D3D the depth stencil dimensions have to be greater than or equal to the
 * render target dimensions. With FBOs, the dimensions have to be an exact match. */
/* TODO: We should synchronize the renderbuffer's content with the texture's content. */
/* GL locking is done by the caller */
void surface_set_compatible_renderbuffer(IWineD3DSurface *iface, unsigned int width, unsigned int height) {
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
    const struct wined3d_gl_info *gl_info = &This->resource.wineD3DDevice->adapter->gl_info;
    renderbuffer_entry_t *entry;
    GLuint renderbuffer = 0;
    unsigned int src_width, src_height;

    src_width = This->pow2Width;
    src_height = This->pow2Height;

    /* A depth stencil smaller than the render target is not valid */
    if (width > src_width || height > src_height) return;

    /* Remove any renderbuffer set if the sizes match */
    if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
            || (width == src_width && height == src_height))
    {
        This->current_renderbuffer = NULL;
        return;
    }

    /* Look if we've already got a renderbuffer of the correct dimensions */
    LIST_FOR_EACH_ENTRY(entry, &This->renderbuffers, renderbuffer_entry_t, entry) {
        if (entry->width == width && entry->height == height) {
            renderbuffer = entry->id;
            This->current_renderbuffer = entry;
            break;
        }
    }

    if (!renderbuffer) {
        gl_info->fbo_ops.glGenRenderbuffers(1, &renderbuffer);
        gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
        gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER,
                This->resource.format_desc->glInternal, width, height);

        entry = HeapAlloc(GetProcessHeap(), 0, sizeof(renderbuffer_entry_t));
        entry->width = width;
        entry->height = height;
        entry->id = renderbuffer;
        list_add_head(&This->renderbuffers, &entry->entry);

        This->current_renderbuffer = entry;
    }

    checkGLcall("set_compatible_renderbuffer");
}

GLenum surface_get_gl_buffer(IWineD3DSurface *iface, IWineD3DSwapChain *swapchain) {
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
    IWineD3DSwapChainImpl *swapchain_impl = (IWineD3DSwapChainImpl *)swapchain;

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

    if (swapchain_impl->backBuffer && swapchain_impl->backBuffer[0] == iface) {
        TRACE("Returning GL_BACK\n");
        return GL_BACK;
    } else if (swapchain_impl->frontBuffer == iface) {
        TRACE("Returning GL_FRONT\n");
        return GL_FRONT;
    }

    FIXME("Higher back buffer, returning GL_BACK\n");
    return GL_BACK;
}

/* Slightly inefficient way to handle multiple dirty rects but it works :) */
void surface_add_dirty_rect(IWineD3DSurface *iface, const RECT *dirty_rect)
{
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
    IWineD3DBaseTexture *baseTexture = NULL;

    if (!(This->Flags & SFLAG_INSYSMEM) && (This->Flags & SFLAG_INTEXTURE))
        IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, NULL /* no partial locking for textures yet */);

    IWineD3DSurface_ModifyLocation(iface, SFLAG_INSYSMEM, TRUE);
    if (dirty_rect)
    {
        This->dirtyRect.left = min(This->dirtyRect.left, dirty_rect->left);
        This->dirtyRect.top = min(This->dirtyRect.top, dirty_rect->top);
        This->dirtyRect.right = max(This->dirtyRect.right, dirty_rect->right);
        This->dirtyRect.bottom = max(This->dirtyRect.bottom, dirty_rect->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: yes, Rect:(%d, %d, %d, %d)\n", This, This->dirtyRect.left,
            This->dirtyRect.top, This->dirtyRect.right, This->dirtyRect.bottom);

    /* if the container is a basetexture then mark it dirty. */
    if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&baseTexture)))
    {
        TRACE("Passing to container\n");
        IWineD3DBaseTexture_SetDirty(baseTexture, TRUE);
        IWineD3DBaseTexture_Release(baseTexture);
    }
}

static inline BOOL surface_can_stretch_rect(IWineD3DSurfaceImpl *src, IWineD3DSurfaceImpl *dst)
{
    return ((src->resource.format_desc->Flags & WINED3DFMT_FLAG_FBO_ATTACHABLE)
            || (src->resource.usage & WINED3DUSAGE_RENDERTARGET))
            && ((dst->resource.format_desc->Flags & WINED3DFMT_FLAG_FBO_ATTACHABLE)
            || (dst->resource.usage & WINED3DUSAGE_RENDERTARGET))
            && (src->resource.format_desc->format == dst->resource.format_desc->format
            || (is_identity_fixup(src->resource.format_desc->color_fixup)
            && is_identity_fixup(dst->resource.format_desc->color_fixup)));
}

static ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface)
{
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
    ULONG ref = InterlockedDecrement(&This->resource.ref);
    TRACE("(%p) : Releasing from %d\n", This, ref + 1);

    if (!ref)
    {
        surface_cleanup(This);
        This->resource.parent_ops->wined3d_object_destroyed(This->resource.parent);

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

    return ref;
}

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

void surface_internal_preload(IWineD3DSurface *iface, enum WINED3DSRGB srgb)
{
    /* TODO: check for locks */
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
    IWineD3DBaseTexture *baseTexture = NULL;
    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;

    TRACE("(%p)Checking to see if the container is a base texture\n", This);
    if (IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&baseTexture) == WINED3D_OK) {
        IWineD3DBaseTextureImpl *tex_impl = (IWineD3DBaseTextureImpl *) baseTexture;
        TRACE("Passing to container\n");
        tex_impl->baseTexture.internal_preload(baseTexture, srgb);
        IWineD3DBaseTexture_Release(baseTexture);
    } else {
        TRACE("(%p) : About to load surface\n", This);

        if(!device->isInDraw) {
            ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
        }

        if (This->resource.format_desc->format == WINED3DFMT_P8_UINT
                || This->resource.format_desc->format == WINED3DFMT_P8_UINT_A8_UNORM)
        {
            if(palette9_changed(This)) {
                TRACE("Reloading surface because the d3d8/9 palette was changed\n");
                /* TODO: This is not necessarily needed with hw palettized texture support */
                IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, NULL);
                /* Make sure the texture is reloaded because of the palette change, this kills performance though :( */
                IWineD3DSurface_ModifyLocation(iface, SFLAG_INTEXTURE, FALSE);
            }
        }

        IWineD3DSurface_LoadTexture(iface, srgb == SRGB_SRGB ? TRUE : FALSE);

        if (This->resource.pool == WINED3DPOOL_DEFAULT) {
            /* Tell opengl to try and keep this texture in video ram (well mostly) */
            GLclampf tmp;
            tmp = 0.9f;
            ENTER_GL();
            glPrioritizeTextures(1, &This->texture_name, &tmp);
            LEAVE_GL();
        }
    }
    return;
}

static void WINAPI IWineD3DSurfaceImpl_PreLoad(IWineD3DSurface *iface) {
    surface_internal_preload(iface, SRGB_ANY);
}

/* Context activation is done by the caller. */
static void surface_remove_pbo(IWineD3DSurfaceImpl *This) {
    This->resource.heapMemory = HeapAlloc(GetProcessHeap() ,0 , This->resource.size + RESOURCE_ALIGNMENT);
    This->resource.allocatedMemory =
            (BYTE *)(((ULONG_PTR) This->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));

    ENTER_GL();
    GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->pbo));
    checkGLcall("glBindBufferARB(GL_PIXEL_UNPACK_BUFFER, This->pbo)");
    GL_EXTCALL(glGetBufferSubDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0, This->resource.size, This->resource.allocatedMemory));
    checkGLcall("glGetBufferSubDataARB");
    GL_EXTCALL(glDeleteBuffersARB(1, &This->pbo));
    checkGLcall("glDeleteBuffersARB");
    LEAVE_GL();

    This->pbo = 0;
    This->Flags &= ~SFLAG_PBO;
}

static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface) {
    IWineD3DBaseTexture *texture = NULL;
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
    const struct wined3d_context *context;
    const struct wined3d_gl_info *gl_info;
    renderbuffer_entry_t *entry, *entry2;
    TRACE("(%p)\n", iface);

    if(This->resource.pool == WINED3DPOOL_DEFAULT) {
        /* Default pool resources are supposed to be destroyed before Reset is called.
         * Implicit resources stay however. So this means we have an implicit render target
         * or depth stencil. The content may be destroyed, but we still have to tear down
         * opengl resources, so we cannot leave early.
         *
         * Put the most up to date surface location into the drawable. D3D-wise this content
         * is undefined, so it would be nowhere, but that would make the location management
         * more complicated. The drawable is a sane location, because if we mark sysmem or
         * texture up to date, drawPrim will copy the uninitialized texture or sysmem to the
         * uninitialized drawable. That's pointless and we'd have to allocate the texture /
         * sysmem copy here.
         */
        if (This->resource.usage & WINED3DUSAGE_DEPTHSTENCIL) {
            IWineD3DSurface_ModifyLocation(iface, SFLAG_INSYSMEM, TRUE);
        } else {
            IWineD3DSurface_ModifyLocation(iface, SFLAG_INDRAWABLE, TRUE);
        }
    } else {
        /* Load the surface into system memory */
        IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, NULL);
        IWineD3DSurface_ModifyLocation(iface, SFLAG_INDRAWABLE, FALSE);
    }
    IWineD3DSurface_ModifyLocation(iface, SFLAG_INTEXTURE, FALSE);
    IWineD3DSurface_ModifyLocation(iface, SFLAG_INSRGBTEX, FALSE);
    This->Flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED);

    context = ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
    gl_info = context->gl_info;

    /* Destroy PBOs, but load them into real sysmem before */
    if(This->Flags & SFLAG_PBO) {
        surface_remove_pbo(This);
    }

    /* Destroy fbo render buffers. This is needed for implicit render targets, for
     * all application-created targets the application has to release the surface
     * before calling _Reset
     */
    LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &This->renderbuffers, renderbuffer_entry_t, entry) {
        ENTER_GL();
        gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
        LEAVE_GL();
        list_remove(&entry->entry);
        HeapFree(GetProcessHeap(), 0, entry);
    }
    list_init(&This->renderbuffers);
    This->current_renderbuffer = NULL;

    /* If we're in a texture, the texture name belongs to the texture. Otherwise,
     * destroy it
     */
    IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **) &texture);
    if(!texture) {
        ENTER_GL();
        glDeleteTextures(1, &This->texture_name);
        This->texture_name = 0;
        glDeleteTextures(1, &This->texture_name_srgb);
        This->texture_name_srgb = 0;
        LEAVE_GL();
    } else {
        IWineD3DBaseTexture_Release(texture);
    }
    return;
}

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

/* Read the framebuffer back into the surface */
static void read_from_framebuffer(IWineD3DSurfaceImpl *This, CONST RECT *rect, void *dest, UINT pitch) {
    IWineD3DSwapChainImpl *swapchain;
    IWineD3DDeviceImpl *myDevice = This->resource.wineD3DDevice;
    BYTE *mem;
    GLint fmt;
    GLint type;
    BYTE *row, *top, *bottom;
    int i;
    BOOL bpp;
    RECT local_rect;
    BOOL srcIsUpsideDown;
    GLint rowLen = 0;
    GLint skipPix = 0;
    GLint skipRow = 0;

    if(wined3d_settings.rendertargetlock_mode == RTL_DISABLE) {
        static BOOL warned = FALSE;
        if(!warned) {
            ERR("The application tries to lock the render target, but render target locking is disabled\n");
            warned = TRUE;
        }
        return;
    }

    /* Activate the surface. Set it up for blitting now, although not necessarily needed for LockRect.
     * Certain graphics drivers seem to dislike some enabled states when reading from opengl, the blitting usage
     * should help here. Furthermore unlockrect will need the context set up for blitting. The context manager will find
     * context->last_was_blit set on the unlock.
     */
    ActivateContext(myDevice, (IWineD3DSurface *) This, CTXUSAGE_BLIT);
    ENTER_GL();

    /* Select the correct read buffer, and give some debug output.
     * There is no need to keep track of the current read buffer or reset it, every part of the code
     * that reads sets the read buffer as desired.
     */
    if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *) This, &IID_IWineD3DSwapChain, (void **)&swapchain)))
    {
        GLenum buffer = surface_get_gl_buffer((IWineD3DSurface *) This, (IWineD3DSwapChain *)swapchain);
        TRACE("Locking %#x buffer\n", buffer);
        glReadBuffer(buffer);
        checkGLcall("glReadBuffer");

        IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
        srcIsUpsideDown = FALSE;
    } else {
        /* Locking the primary render target which is not on a swapchain(=offscreen render target).
         * Read from the back buffer
         */
        TRACE("Locking offscreen render target\n");
        glReadBuffer(myDevice->offscreenBuffer);
        srcIsUpsideDown = TRUE;
    }

    /* TODO: Get rid of the extra rectangle comparison and construction of a full surface rectangle */
    if(!rect) {
        local_rect.left = 0;
        local_rect.top = 0;
        local_rect.right = This->currentDesc.Width;
        local_rect.bottom = This->currentDesc.Height;
    } else {
        local_rect = *rect;
    }
    /* TODO: Get rid of the extra GetPitch call, LockRect does that too. Cache the pitch */

    switch(This->resource.format_desc->format)
    {
        case WINED3DFMT_P8_UINT:
        {
            if(primary_render_target_is_p8(myDevice)) {
                /* In case of P8 render targets the index is stored in the alpha component */
                fmt = GL_ALPHA;
                type = GL_UNSIGNED_BYTE;
                mem = dest;
                bpp = This->resource.format_desc->byte_count;
            } else {
                /* GL can't return palettized data, so read ARGB pixels into a
                 * separate block of memory and convert them into palettized format
                 * in software. Slow, but if the app means to use palettized render
                 * targets and locks it...
                 *
                 * Use GL_RGB, GL_UNSIGNED_BYTE to read the surface for performance reasons
                 * Don't use GL_BGR as in the WINED3DFMT_R8G8B8 case, instead watch out
                 * for the color channels when palettizing the colors.
                 */
                fmt = GL_RGB;
                type = GL_UNSIGNED_BYTE;
                pitch *= 3;
                mem = HeapAlloc(GetProcessHeap(), 0, This->resource.size * 3);
                if(!mem) {
                    ERR("Out of memory\n");
                    LEAVE_GL();
                    return;
                }
                bpp = This->resource.format_desc->byte_count * 3;
            }
        }
        break;

        default:
            mem = dest;
            fmt = This->resource.format_desc->glFormat;
            type = This->resource.format_desc->glType;
            bpp = This->resource.format_desc->byte_count;
    }

    if(This->Flags & SFLAG_PBO) {
        GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, This->pbo));
        checkGLcall("glBindBufferARB");
        if(mem != NULL) {
            ERR("mem not null for pbo -- unexpected\n");
            mem = NULL;
        }
    }

    /* Save old pixel store pack state */
    glGetIntegerv(GL_PACK_ROW_LENGTH, &rowLen);
    checkGLcall("glGetIntegerv");
    glGetIntegerv(GL_PACK_SKIP_PIXELS, &skipPix);
    checkGLcall("glGetIntegerv");
    glGetIntegerv(GL_PACK_SKIP_ROWS, &skipRow);
    checkGLcall("glGetIntegerv");

    /* Setup pixel store pack state -- to glReadPixels into the correct place */
    glPixelStorei(GL_PACK_ROW_LENGTH, This->currentDesc.Width);
    checkGLcall("glPixelStorei");
    glPixelStorei(GL_PACK_SKIP_PIXELS, local_rect.left);
    checkGLcall("glPixelStorei");
    glPixelStorei(GL_PACK_SKIP_ROWS, local_rect.top);
    checkGLcall("glPixelStorei");

    glReadPixels(local_rect.left, (!srcIsUpsideDown) ? (This->currentDesc.Height - local_rect.bottom) : local_rect.top ,
                 local_rect.right - local_rect.left,
                 local_rect.bottom - local_rect.top,
                 fmt, type, mem);
    checkGLcall("glReadPixels");

    /* Reset previous pixel store pack state */
    glPixelStorei(GL_PACK_ROW_LENGTH, rowLen);
    checkGLcall("glPixelStorei");
    glPixelStorei(GL_PACK_SKIP_PIXELS, skipPix);
    checkGLcall("glPixelStorei");
    glPixelStorei(GL_PACK_SKIP_ROWS, skipRow);
    checkGLcall("glPixelStorei");

    if(This->Flags & SFLAG_PBO) {
        GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0));
        checkGLcall("glBindBufferARB");

        /* Check if we need to flip the image. If we need to flip use glMapBufferARB
         * to get a pointer to it and perform the flipping in software. This is a lot
         * faster than calling glReadPixels for each line. In case we want more speed
         * we should rerender it flipped in a FBO and read the data back from the FBO. */
        if(!srcIsUpsideDown) {
            GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->pbo));
            checkGLcall("glBindBufferARB");

            mem = GL_EXTCALL(glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_READ_WRITE_ARB));
            checkGLcall("glMapBufferARB");
        }
    }

    /* TODO: Merge this with the palettization loop below for P8 targets */
    if(!srcIsUpsideDown) {
        UINT len, off;
        /* glReadPixels returns the image upside down, and there is no way to prevent this.
            Flip the lines in software */
        len = (local_rect.right - local_rect.left) * bpp;
        off = local_rect.left * bpp;

        row = HeapAlloc(GetProcessHeap(), 0, len);
        if(!row) {
            ERR("Out of memory\n");
            if (This->resource.format_desc->format == WINED3DFMT_P8_UINT) HeapFree(GetProcessHeap(), 0, mem);
            LEAVE_GL();
            return;
        }

        top = mem + pitch * local_rect.top;
        bottom = mem + pitch * (local_rect.bottom - 1);
        for(i = 0; i < (local_rect.bottom - local_rect.top) / 2; i++) {
            memcpy(row, top + off, len);
            memcpy(top + off, bottom + off, len);
            memcpy(bottom + off, row, len);
            top += pitch;
            bottom -= pitch;
        }
        HeapFree(GetProcessHeap(), 0, row);

        /* Unmap the temp PBO buffer */
        if(This->Flags & SFLAG_PBO) {
            GL_EXTCALL(glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB));
            GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
        }
    }

    LEAVE_GL();

    /* For P8 textures we need to perform an inverse palette lookup. This is done by searching for a palette
     * index which matches the RGB value. Note this isn't guaranteed to work when there are multiple entries for
     * the same color but we have no choice.
     * In case of P8 render targets, the index is stored in the alpha component so no conversion is needed.
     */
    if (This->resource.format_desc->format == WINED3DFMT_P8_UINT && !primary_render_target_is_p8(myDevice))
    {
        const PALETTEENTRY *pal = NULL;
        DWORD width = pitch / 3;
        int x, y, c;

        if(This->palette) {
            pal = This->palette->palents;
        } else {
            ERR("Palette is missing, cannot perform inverse palette lookup\n");
            HeapFree(GetProcessHeap(), 0, mem);
            return ;
        }

        for(y = local_rect.top; y < local_rect.bottom; y++) {
            for(x = local_rect.left; x < local_rect.right; x++) {
                /*                      start              lines            pixels      */
                const BYTE *blue = mem + y * pitch + x * (sizeof(BYTE) * 3);
                const BYTE *green = blue  + 1;
                const BYTE *red = green + 1;

                for(c = 0; c < 256; c++) {
                    if(*red   == pal[c].peRed   &&
                       *green == pal[c].peGreen &&
                       *blue  == pal[c].peBlue)
                    {
                        *((BYTE *) dest + y * width + x) = c;
                        break;
                    }
                }
            }
        }
        HeapFree(GetProcessHeap(), 0, mem);
    }
}

/* Read the framebuffer contents into a texture */
static void read_from_framebuffer_texture(IWineD3DSurfaceImpl *This, BOOL srgb)
{
    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
    IWineD3DSwapChainImpl *swapchain;
    int bpp;
    GLenum format, internal, type;
    CONVERT_TYPES convert;
    GLint prevRead;
    BOOL alloc_flag = srgb ? SFLAG_SRGBALLOCATED : SFLAG_ALLOCATED;

    d3dfmt_get_conv(This, TRUE /* We need color keying */, TRUE /* We will use textures */, &format, &internal, &type, &convert, &bpp, srgb);

    /* Activate the surface to read from. In some situations it isn't the currently active target(e.g. backbuffer
     * locking during offscreen rendering). RESOURCELOAD is ok because glCopyTexSubImage2D isn't affected by any
     * states in the stateblock, and no driver was found yet that had bugs in that regard.
     */
    ActivateContext(device, (IWineD3DSurface *) This, CTXUSAGE_RESOURCELOAD);
    surface_bind_and_dirtify(This, srgb);

    ENTER_GL();
    glGetIntegerv(GL_READ_BUFFER, &prevRead);
    LEAVE_GL();

    /* Select the correct read buffer, and give some debug output.
     * There is no need to keep track of the current read buffer or reset it, every part of the code
     * that reads sets the read buffer as desired.
     */
    if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)This, &IID_IWineD3DSwapChain, (void **)&swapchain)))
    {
        GLenum buffer = surface_get_gl_buffer((IWineD3DSurface *) This, (IWineD3DSwapChain *)swapchain);
        TRACE("Locking %#x buffer\n", buffer);

        ENTER_GL();
        glReadBuffer(buffer);
        checkGLcall("glReadBuffer");
        LEAVE_GL();

        IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
    } else {
        /* Locking the primary render target which is not on a swapchain(=offscreen render target).
         * Read from the back buffer
         */
        TRACE("Locking offscreen render target\n");
        ENTER_GL();
        glReadBuffer(device->offscreenBuffer);
        checkGLcall("glReadBuffer");
        LEAVE_GL();
    }

    if(!(This->Flags & alloc_flag)) {
        surface_allocate_surface(This, internal, This->pow2Width,
                                 This->pow2Height, format, type);
        This->Flags |= alloc_flag;
    }

    ENTER_GL();
    /* If !SrcIsUpsideDown we should flip the surface.
     * This can be done using glCopyTexSubImage2D but this
     * is VERY slow, so don't do that. We should prevent
     * this code from getting called in such cases or perhaps
     * we can use FBOs */

    glCopyTexSubImage2D(This->texture_target, This->texture_level,
            0, 0, 0, 0, This->currentDesc.Width, This->currentDesc.Height);
    checkGLcall("glCopyTexSubImage2D");

    glReadBuffer(prevRead);
    checkGLcall("glReadBuffer");

    LEAVE_GL();
    TRACE("Updated target %d\n", This->texture_target);
}

static void surface_prepare_system_memory(IWineD3DSurfaceImpl *This) {
    /* Performance optimization: Count how often a surface is locked, if it is locked regularly do not throw away the system memory copy.
     * This avoids the need to download the surface from opengl all the time. The surface is still downloaded if the opengl texture is
     * changed
     */
    if(!(This->Flags & SFLAG_DYNLOCK)) {
        This->lockCount++;
        /* MAXLOCKCOUNT is defined in wined3d_private.h */
        if(This->lockCount > MAXLOCKCOUNT) {
            TRACE("Surface is locked regularly, not freeing the system memory copy any more\n");
            This->Flags |= SFLAG_DYNLOCK;
        }
    }

    /* Create a PBO for dynamically locked surfaces but don't do it for converted or non-pow2 surfaces.
     * Also don't create a PBO for systemmem surfaces.
     */
    if(GL_SUPPORT(ARB_PIXEL_BUFFER_OBJECT) && (This->Flags & SFLAG_DYNLOCK) && !(This->Flags & (SFLAG_PBO | SFLAG_CONVERTED | SFLAG_NONPOW2)) && (This->resource.pool != WINED3DPOOL_SYSTEMMEM)) {
        GLenum error;
        IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;

        ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
        ENTER_GL();

        GL_EXTCALL(glGenBuffersARB(1, &This->pbo));
        error = glGetError();
        if(This->pbo == 0 || error != GL_NO_ERROR) {
            ERR("Failed to bind the PBO with error %s (%#x)\n", debug_glerror(error), error);
        }

        TRACE("Attaching pbo=%#x to (%p)\n", This->pbo, This);

        GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->pbo));
        checkGLcall("glBindBufferARB");

        GL_EXTCALL(glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->resource.size + 4, This->resource.allocatedMemory, GL_STREAM_DRAW_ARB));
        checkGLcall("glBufferDataARB");

        GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
        checkGLcall("glBindBufferARB");

        /* We don't need the system memory anymore and we can't even use it for PBOs */
        if(!(This->Flags & SFLAG_CLIENT)) {
            HeapFree(GetProcessHeap(), 0, This->resource.heapMemory);
            This->resource.heapMemory = NULL;
        }
        This->resource.allocatedMemory = NULL;
        This->Flags |= SFLAG_PBO;
        LEAVE_GL();
    } else if(!(This->resource.allocatedMemory || This->Flags & SFLAG_PBO)) {
        /* Whatever surface we have, make sure that there is memory allocated for the downloaded copy,
         * or a pbo to map
         */
        if(!This->resource.heapMemory) {
            This->resource.heapMemory = HeapAlloc(GetProcessHeap() ,0 , This->resource.size + RESOURCE_ALIGNMENT);
        }
        This->resource.allocatedMemory =
                (BYTE *)(((ULONG_PTR) This->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
        if(This->Flags & SFLAG_INSYSMEM) {
            ERR("Surface without memory or pbo has SFLAG_INSYSMEM set!\n");
        }
    }
}

static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) {
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
    IWineD3DDeviceImpl  *myDevice = This->resource.wineD3DDevice;
    const RECT *pass_rect = pRect;

    TRACE("(%p) : rect@%p flags(%08x), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, This->resource.allocatedMemory);

    /* This is also done in the base class, but we have to verify this before loading any data from
     * gl into the sysmem copy. The PBO may be mapped, a different rectangle locked, the discard flag
     * may interfere, and all other bad things may happen
     */
    if (This->Flags & SFLAG_LOCKED) {
        WARN("Surface is already locked, returning D3DERR_INVALIDCALL\n");
        return WINED3DERR_INVALIDCALL;
    }
    This->Flags |= SFLAG_LOCKED;

    if (!(This->Flags & SFLAG_LOCKABLE))
    {
        TRACE("Warning: trying to lock unlockable surf@%p\n", This);
    }

    if (Flags & WINED3DLOCK_DISCARD) {
        /* Set SFLAG_INSYSMEM, so we'll never try to download the data from the texture. */
        TRACE("WINED3DLOCK_DISCARD flag passed, marking local copy as up to date\n");
        surface_prepare_system_memory(This); /* Makes sure memory is allocated */
        This->Flags |= SFLAG_INSYSMEM;
        goto lock_end;
    }

    if (This->Flags & SFLAG_INSYSMEM) {
        TRACE("Local copy is up to date, not downloading data\n");
        surface_prepare_system_memory(This); /* Makes sure memory is allocated */
        goto lock_end;
    }

    /* IWineD3DSurface_LoadLocation() does not check if the rectangle specifies
     * the full surface. Most callers don't need that, so do it here. */
    if (pRect && pRect->top == 0 && pRect->left == 0
            && pRect->right == This->currentDesc.Width
            && pRect->bottom == This->currentDesc.Height)
    {
        pass_rect = NULL;
    }

    if (!(wined3d_settings.rendertargetlock_mode == RTL_DISABLE
            && ((This->Flags & SFLAG_SWAPCHAIN) || iface == myDevice->render_targets[0])))
    {
        IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, pass_rect);
    }

lock_end:
    if(This->Flags & SFLAG_PBO) {
        ActivateContext(myDevice, NULL, CTXUSAGE_RESOURCELOAD);
        ENTER_GL();
        GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->pbo));
        checkGLcall("glBindBufferARB");

        /* This shouldn't happen but could occur if some other function didn't handle the PBO properly */
        if(This->resource.allocatedMemory) {
            ERR("The surface already has PBO memory allocated!\n");
        }

        This->resource.allocatedMemory = GL_EXTCALL(glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_READ_WRITE_ARB));
        checkGLcall("glMapBufferARB");

        /* Make sure the pbo isn't set anymore in order not to break non-pbo calls */
        GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
        checkGLcall("glBindBufferARB");

        LEAVE_GL();
    }

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

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

    return IWineD3DBaseSurfaceImpl_LockRect(iface, pLockedRect, pRect, Flags);
}

static void flush_to_framebuffer_drawpixels(IWineD3DSurfaceImpl *This, GLenum fmt, GLenum type, UINT bpp, const BYTE *mem) {
    GLint  prev_store;
    GLint  prev_rasterpos[4];
    GLint skipBytes = 0;
    UINT pitch = IWineD3DSurface_GetPitch((IWineD3DSurface *) This);    /* target is argb, 4 byte */
    IWineD3DDeviceImpl *myDevice = This->resource.wineD3DDevice;
    IWineD3DSwapChainImpl *swapchain;

    /* Activate the correct context for the render target */
    ActivateContext(myDevice, (IWineD3DSurface *) This, CTXUSAGE_BLIT);
    ENTER_GL();

    if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)This, &IID_IWineD3DSwapChain, (void **)&swapchain))) {
        GLenum buffer = surface_get_gl_buffer((IWineD3DSurface *) This, (IWineD3DSwapChain *)swapchain);
        TRACE("Unlocking %#x buffer\n", buffer);
        glDrawBuffer(buffer);
        checkGLcall("glDrawBuffer");

        IWineD3DSwapChain_Release((IWineD3DSwapChain *)swapchain);
    } else {
        /* Primary offscreen render target */
        TRACE("Offscreen render target\n");
        glDrawBuffer(myDevice->offscreenBuffer);
        checkGLcall("glDrawBuffer(myDevice->offscreenBuffer)");
    }

    glGetIntegerv(GL_PACK_SWAP_BYTES, &prev_store);
    checkGLcall("glGetIntegerv");
    glGetIntegerv(GL_CURRENT_RASTER_POSITION, &prev_rasterpos[0]);
    checkGLcall("glGetIntegerv");
    glPixelZoom(1.0f, -1.0f);
    checkGLcall("glPixelZoom");

    /* 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);

    glRasterPos3i(This->lockedRect.left, This->lockedRect.top, 1);
    checkGLcall("glRasterPos3i");

    /* Some drivers(radeon dri, others?) don't like exceptions during
     * glDrawPixels. If the surface is a DIB section, it might be in GDIMode
     * after ReleaseDC. Reading it will cause an exception, which x11drv will
     * catch to put the dib section in InSync mode, which leads to a crash
     * and a blocked x server on my radeon card.
     *
     * The following lines read the dib section so it is put in InSync mode
     * before glDrawPixels is called and the crash is prevented. There won't
     * be any interfering gdi accesses, because UnlockRect is called from
     * ReleaseDC, and the app won't use the dc any more afterwards.
     */
    if((This->Flags & SFLAG_DIBSECTION) && !(This->Flags & SFLAG_PBO)) {
        volatile BYTE read;
        read = This->resource.allocatedMemory[0];
    }

    if(This->Flags & SFLAG_PBO) {
        GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->pbo));
        checkGLcall("glBindBufferARB");
    }

    /* When the surface is locked we only have to refresh the locked part else we need to update the whole image */
    if(This->Flags & SFLAG_LOCKED) {
        glDrawPixels(This->lockedRect.right - This->lockedRect.left,
                     (This->lockedRect.bottom - This->lockedRect.top)-1,
                     fmt, type,
                     mem + bpp * This->lockedRect.left + pitch * This->lockedRect.top);
        checkGLcall("glDrawPixels");
    } else {
        glDrawPixels(This->currentDesc.Width,
                     This->currentDesc.Height,
                     fmt, type, mem);
        checkGLcall("glDrawPixels");
    }

    if(This->Flags & SFLAG_PBO) {
        GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
        checkGLcall("glBindBufferARB");
    }

    glPixelZoom(1.0f, 1.0f);
    checkGLcall("glPixelZoom");

    glRasterPos3iv(&prev_rasterpos[0]);
    checkGLcall("glRasterPos3iv");

    /* Reset to previous pack row length */
    glPixelStorei(GL_UNPACK_ROW_LENGTH, skipBytes);
    checkGLcall("glPixelStorei(GL_UNPACK_ROW_LENGTH)");

    if(!swapchain) {
        glDrawBuffer(myDevice->offscreenBuffer);
        checkGLcall("glDrawBuffer(myDevice->offscreenBuffer)");
    } else if(swapchain->backBuffer) {
        glDrawBuffer(GL_BACK);
        checkGLcall("glDrawBuffer(GL_BACK)");
    } else {
        glDrawBuffer(GL_FRONT);
        checkGLcall("glDrawBuffer(GL_FRONT)");
    }
    LEAVE_GL();

    return;
}

static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) {
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
    IWineD3DDeviceImpl  *myDevice = This->resource.wineD3DDevice;
    BOOL fullsurface;

    if (!(This->Flags & SFLAG_LOCKED)) {
        WARN("trying to Unlock an unlocked surf@%p\n", This);
        return WINEDDERR_NOTLOCKED;
    }

    if (This->Flags & SFLAG_PBO) {
        TRACE("Freeing PBO memory\n");
        ActivateContext(myDevice, NULL, CTXUSAGE_RESOURCELOAD);
        ENTER_GL();
        GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->pbo));
        GL_EXTCALL(glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB));
        GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
        checkGLcall("glUnmapBufferARB");
        LEAVE_GL();
        This->resource.allocatedMemory = NULL;
    }

    TRACE("(%p) : dirtyfied(%d)\n", This, This->Flags & (SFLAG_INDRAWABLE | SFLAG_INTEXTURE) ? 0 : 1);

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

    if ((This->Flags & SFLAG_SWAPCHAIN) || (myDevice->render_targets && iface == myDevice->render_targets[0]))
    {
        if(wined3d_settings.rendertargetlock_mode == RTL_DISABLE) {
            static BOOL warned = FALSE;
            if(!warned) {
                ERR("The application tries to write to the render target, but render target locking is disabled\n");
                warned = TRUE;
            }
            goto unlock_end;
        }

        if(This->dirtyRect.left   == 0 &&
           This->dirtyRect.top    == 0 &&
           This->dirtyRect.right  == This->currentDesc.Width &&
           This->dirtyRect.bottom == This->currentDesc.Height) {
            fullsurface = TRUE;
        } else {
            /* TODO: Proper partial rectangle tracking */
            fullsurface = FALSE;
            This->Flags |= SFLAG_INSYSMEM;
        }

        switch(wined3d_settings.rendertargetlock_mode) {
            case RTL_READTEX:
                IWineD3DSurface_LoadLocation(iface, SFLAG_INTEXTURE, NULL /* partial texture loading not supported yet */);
                /* drop through */

            case RTL_READDRAW:
                IWineD3DSurface_LoadLocation(iface, SFLAG_INDRAWABLE, fullsurface ? NULL : &This->dirtyRect);
                break;
        }

        if(!fullsurface) {
            /* Partial rectangle tracking is not commonly implemented, it is only done for render targets. Overwrite
             * the flags to bring them back into a sane state. INSYSMEM was set before to tell LoadLocation where
             * to read the rectangle from. Indrawable is set because all modifications from the partial sysmem copy
             * are written back to the drawable, thus the surface is merged again in the drawable. The sysmem copy is
             * not fully up to date because only a subrectangle was read in LockRect.
             */
            This->Flags &= ~SFLAG_INSYSMEM;
            This->Flags |= SFLAG_INDRAWABLE;
        }

        This->dirtyRect.left   = This->currentDesc.Width;
        This->dirtyRect.top    = This->currentDesc.Height;
        This->dirtyRect.right  = 0;
        This->dirtyRect.bottom = 0;
    } else if(iface == myDevice->stencilBufferTarget) {
        FIXME("Depth Stencil buffer locking is not implemented\n");
    } else {
        /* The rest should be a normal texture */
        IWineD3DBaseTextureImpl *impl;
        /* Check if the texture is bound, if yes dirtify the sampler to force a re-upload of the texture
         * Can't load the texture here because PreLoad may destroy and recreate the gl texture, so sampler
         * states need resetting
         */
        if(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&impl) == WINED3D_OK) {
            if(impl->baseTexture.bindCount) {
                IWineD3DDeviceImpl_MarkStateDirty(myDevice, STATE_SAMPLER(impl->baseTexture.sampler));
            }
            IWineD3DBaseTexture_Release((IWineD3DBaseTexture *) impl);
        }
    }

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

    /* Overlays have to be redrawn manually after changes with the GL implementation */
    if(This->overlay_dest) {
        IWineD3DSurface_DrawOverlay(iface);
    }
    return WINED3D_OK;
}

static HRESULT WINAPI IWineD3DSurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHDC)
{
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
    WINED3DLOCKED_RECT lock;
    HRESULT hr;
    RGBQUAD col[256];

    TRACE("(%p)->(%p)\n",This,pHDC);

    if(This->Flags & SFLAG_USERPTR) {
        ERR("Not supported on surfaces with an application-provided surfaces\n");
        return WINEDDERR_NODC;
    }

    /* Give more detailed info for ddraw */
    if (This->Flags & SFLAG_DCINUSE)
        return WINEDDERR_DCALREADYCREATED;

    /* Can't GetDC if the surface is locked */
    if (This->Flags & SFLAG_LOCKED)
        return WINED3DERR_INVALIDCALL;

    memset(&lock, 0, sizeof(lock)); /* To be sure */

    /* Create a DIB section if there isn't a hdc yet */
    if(!This->hDC) {
        hr = IWineD3DBaseSurfaceImpl_CreateDIBSection(iface);
        if(FAILED(hr)) return WINED3DERR_INVALIDCALL;
        if(This->Flags & SFLAG_CLIENT) {
            surface_internal_preload(iface, SRGB_RGB);
        }

        /* Use the dib section from now on if we are not using a PBO */
        if(!(This->Flags & SFLAG_PBO))
            This->resource.allocatedMemory = This->dib.bitmap_data;
    }

    /* Lock the surface */
    hr = IWineD3DSurface_LockRect(iface,
                                  &lock,
                                  NULL,
                                  0);

    if(This->Flags & SFLAG_PBO) {
        /* Sync the DIB with the PBO. This can't be done earlier because LockRect activates the allocatedMemory */
        memcpy(This->dib.bitmap_data, This->resource.allocatedMemory, This->dib.bitmap_size);
    }

    if(FAILED(hr)) {
        ERR("IWineD3DSurface_LockRect failed with hr = %08x\n", hr);
        /* keep the dib section */
        return hr;
    }

    if (This->resource.format_desc->format == WINED3DFMT_P8_UINT
            || This->resource.format_desc->format == WINED3DFMT_P8_UINT_A8_UNORM)
    {
        /* GetDC on palettized formats is unsupported in D3D9, and the method is missing in
            D3D8, so this should only be used for DX <=7 surfaces (with non-device palettes) */
        unsigned int n;
        const PALETTEENTRY *pal = NULL;

        if(This->palette) {
            pal = This->palette->palents;
        } else {
            IWineD3DSurfaceImpl *dds_primary;
            IWineD3DSwapChainImpl *swapchain;
            swapchain = (IWineD3DSwapChainImpl *)This->resource.wineD3DDevice->swapchains[0];
            dds_primary = (IWineD3DSurfaceImpl *)swapchain->frontBuffer;
            if (dds_primary && dds_primary->palette)
                pal = dds_primary->palette->palents;
        }

        if (pal) {
            for (n=0; n<256; n++) {
                col[n].rgbRed   = pal[n].peRed;
                col[n].rgbGreen = pal[n].peGreen;
                col[n].rgbBlue  = pal[n].peBlue;
                col[n].rgbReserved = 0;
            }
            SetDIBColorTable(This->hDC, 0, 256, col);
        }
    }

    *pHDC = This->hDC;
    TRACE("returning %p\n",*pHDC);
    This->Flags |= SFLAG_DCINUSE;

    return WINED3D_OK;
}

static HRESULT WINAPI IWineD3DSurfaceImpl_ReleaseDC(IWineD3DSurface *iface, HDC hDC)
{
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;

    TRACE("(%p)->(%p)\n",This,hDC);

    if (!(This->Flags & SFLAG_DCINUSE))
        return WINEDDERR_NODC;

    if (This->hDC !=hDC) {
        WARN("Application tries to release an invalid DC(%p), surface dc is %p\n", hDC, This->hDC);
        return WINEDDERR_NODC;
    }

    if((This->Flags & SFLAG_PBO) && This->resource.allocatedMemory) {
        /* Copy the contents of the DIB over to the PBO */
        memcpy(This->resource.allocatedMemory, This->dib.bitmap_data, This->dib.bitmap_size);
    }

    /* we locked first, so unlock now */
    IWineD3DSurface_UnlockRect(iface);

    This->Flags &= ~SFLAG_DCINUSE;

    return WINED3D_OK;
}

/* ******************************************************
   IWineD3DSurface Internal (No mapping to directx api) parts follow
   ****************************************************** */

HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_texturing, GLenum *format, GLenum *internal, GLenum *type, CONVERT_TYPES *convert, int *target_bpp, BOOL srgb_mode) {
    BOOL colorkey_active = need_alpha_ck && (This->CKeyFlags & WINEDDSD_CKSRCBLT);
    const struct GlPixelFormatDesc *glDesc = This->resource.format_desc;
    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;

    /* Default values: From the surface */
    *format = glDesc->glFormat;
    *type = glDesc->glType;
    *convert = NO_CONVERSION;
    *target_bpp = glDesc->byte_count;

    if(srgb_mode) {
        *internal = glDesc->glGammaInternal;
    }
    else if (This->resource.usage & WINED3DUSAGE_RENDERTARGET
            && !(This->Flags & SFLAG_SWAPCHAIN))
    {
        *internal = glDesc->rtInternal;
    } else {
        *internal = glDesc->glInternal;
    }

    /* Ok, now look if we have to do any conversion */
    switch(This->resource.format_desc->format)
    {
        case WINED3DFMT_P8_UINT:
            /* ****************
                Paletted Texture
                **************** */

             /* Use conversion when the paletted texture extension OR fragment shaders are available. When either
             * of the two is available make sure texturing is requested as neither of the two works in
             * conjunction with calls like glDraw-/glReadPixels. Further also use conversion in case of color keying.
             * Paletted textures can be emulated using shaders but only do that for 2D purposes e.g. situations
             * in which the main render target uses p8. Some games like GTA Vice City use P8 for texturing which
             * conflicts with this.
             */
            if( !(GL_SUPPORT(EXT_PALETTED_TEXTURE) ||
                  (GL_SUPPORT(ARB_FRAGMENT_PROGRAM) &&
                   device->render_targets &&
                   This == (IWineD3DSurfaceImpl*)device->render_targets[0])) ||
                colorkey_active || !use_texturing ) {
                *format = GL_RGBA;
                *internal = GL_RGBA;
                *type = GL_UNSIGNED_BYTE;
                *target_bpp = 4;
                if(colorkey_active) {
                    *convert = CONVERT_PALETTED_CK;
                } else {
                    *convert = CONVERT_PALETTED;
                }
            }
            else if(!GL_SUPPORT(EXT_PALETTED_TEXTURE) && GL_SUPPORT(ARB_FRAGMENT_PROGRAM)) {
                *format = GL_ALPHA;
                *type = GL_UNSIGNED_BYTE;
                *target_bpp = 1;
            }

            break;

        case WINED3DFMT_B2G3R3_UNORM:
            /* **********************
                GL_UNSIGNED_BYTE_3_3_2
                ********************** */
            if (colorkey_active) {
                /* This texture format will never be used.. So do not care about color keying
                    up until the point in time it will be needed :-) */
                FIXME(" ColorKeying not supported in the RGB 332 format !\n");
            }
            break;

        case WINED3DFMT_B5G6R5_UNORM:
            if (colorkey_active) {
                *convert = CONVERT_CK_565;
                *format = GL_RGBA;
                *internal = GL_RGB5_A1;
                *type = GL_UNSIGNED_SHORT_5_5_5_1;
            }
            break;

        case WINED3DFMT_B5G5R5X1_UNORM:
            if (colorkey_active) {
                *convert = CONVERT_CK_5551;
                *format = GL_BGRA;
                *internal = GL_RGB5_A1;
                *type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
            }
            break;

        case WINED3DFMT_B8G8R8_UNORM:
            if (colorkey_active) {
                *convert = CONVERT_CK_RGB24;
                *format = GL_RGBA;
                *internal = GL_RGBA8;
                *type = GL_UNSIGNED_INT_8_8_8_8;
                *target_bpp = 4;
            }
            break;

        case WINED3DFMT_B8G8R8X8_UNORM:
            if (colorkey_active) {
                *convert = CONVERT_RGB32_888;
                *format = GL_RGBA;
                *internal = GL_RGBA8;
                *type = GL_UNSIGNED_INT_8_8_8_8;
            }
            break;

        case WINED3DFMT_R8G8_SNORM:
            if (GL_SUPPORT(NV_TEXTURE_SHADER)) break;
            *convert = CONVERT_V8U8;
            *format = GL_BGR;
            *type = GL_UNSIGNED_BYTE;
            *target_bpp = 3;
            break;

        case WINED3DFMT_R5G5_SNORM_L6_UNORM:
            *convert = CONVERT_L6V5U5;
            if(GL_SUPPORT(NV_TEXTURE_SHADER)) {
                *target_bpp = 3;
                /* Use format and types from table */
            } else {
                /* Load it into unsigned R5G6B5, swap L and V channels, and revert that in the shader */
                *target_bpp = 2;
                *format = GL_RGB;
                *type = GL_UNSIGNED_SHORT_5_6_5;
            }
            break;

        case WINED3DFMT_R8G8_SNORM_L8X8_UNORM:
            *convert = CONVERT_X8L8V8U8;
            *target_bpp = 4;
            if(GL_SUPPORT(NV_TEXTURE_SHADER)) {
                /* Use formats from gl table. It is a bit unfortunate, but the conversion
                 * is needed to set the X format to 255 to get 1.0 for alpha when sampling
                 * the texture. OpenGL can't use GL_DSDT8_MAG8_NV as internal format with
                 * the needed type and format parameter, so the internal format contains a
                 * 4th component, which is returned as alpha
                 */
            } else {
                *format = GL_BGRA;
                *type = GL_UNSIGNED_INT_8_8_8_8_REV;
            }
            break;

        case WINED3DFMT_R8G8B8A8_SNORM:
            if (GL_SUPPORT(NV_TEXTURE_SHADER)) break;
            *convert = CONVERT_Q8W8V8U8;
            *format = GL_BGRA;
            *type = GL_UNSIGNED_BYTE;
            *target_bpp = 4;
            break;

        case WINED3DFMT_R16G16_SNORM:
            if (GL_SUPPORT(NV_TEXTURE_SHADER)) break;
            *convert = CONVERT_V16U16;
            *format = GL_BGR;
            *type = GL_UNSIGNED_SHORT;
            *target_bpp = 6;
            break;

        case WINED3DFMT_L4A4_UNORM:
            /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not
             * format+type combination to load it. Thus convert it to A8L8, then load it
             * with A4L4 internal, but A8L8 format+type
             */
            *convert = CONVERT_A4L4;
            *format = GL_LUMINANCE_ALPHA;
            *type = GL_UNSIGNED_BYTE;
            *target_bpp = 2;
            break;

        case WINED3DFMT_R16G16_UNORM:
            *convert = CONVERT_G16R16;
            *format = GL_RGB;
            *type = GL_UNSIGNED_SHORT;
            *target_bpp = 6;
            break;

        case WINED3DFMT_R16G16_FLOAT:
            *convert = CONVERT_R16G16F;
            *format = GL_RGB;
            *type = GL_HALF_FLOAT_ARB;
            *target_bpp = 6;
            break;

        case WINED3DFMT_R32G32_FLOAT:
            *convert = CONVERT_R32G32F;
            *format = GL_RGB;
            *type = GL_FLOAT;
            *target_bpp = 12;
            break;

        case WINED3DFMT_S1_UINT_D15_UNORM:
            if (GL_SUPPORT(ARB_FRAMEBUFFER_OBJECT)
                    || GL_SUPPORT(EXT_PACKED_DEPTH_STENCIL))
            {
                *convert = CONVERT_D15S1;
                *target_bpp = 4;
            }
            break;

        case WINED3DFMT_S4X4_UINT_D24_UNORM:
            if (GL_SUPPORT(ARB_FRAMEBUFFER_OBJECT)
                    || GL_SUPPORT(EXT_PACKED_DEPTH_STENCIL))
            {
                *convert = CONVERT_D24X4S4;
            }
            break;

        case WINED3DFMT_S8_UINT_D24_FLOAT:
            if (GL_SUPPORT(ARB_DEPTH_BUFFER_FLOAT))
            {
                *convert = CONVERT_D24FS8;
                *target_bpp = 8;
            }
            break;

        default:
            break;
    }

    return WINED3D_OK;
}

static void d3dfmt_p8_init_palette(IWineD3DSurfaceImpl *This, BYTE table[256][4], BOOL colorkey)
{
    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
    IWineD3DPaletteImpl *pal = This->palette;
    BOOL index_in_alpha = FALSE;
    unsigned int i;

    /* Old games like StarCraft, C&C, Red Alert and others use P8 render targets.
     * Reading back the RGB output each lockrect (each frame as they lock the whole screen)
     * is slow. Further RGB->P8 conversion is not possible because palettes can have
     * duplicate entries. Store the color key in the unused alpha component to speed the
     * download up and to make conversion unneeded. */
    index_in_alpha = primary_render_target_is_p8(device);

    if (!pal)
    {
        UINT dxVersion = ((IWineD3DImpl *)device->wineD3D)->dxVersion;

        /* In DirectDraw the palette is a property of the surface, there are no such things as device palettes. */
        if (dxVersion <= 7)
        {
            ERR("This code should never get entered for DirectDraw!, expect problems\n");
            if (index_in_alpha)
            {
                /* Guarantees that memory representation remains correct after sysmem<->texture transfers even if
                 * there's no palette at this time. */
                for (i = 0; i < 256; i++) table[i][3] = i;
            }
        }
        else
        {
            /* Direct3D >= 8 palette usage style: P8 textures use device palettes, palette entry format is A8R8G8B8,
             * alpha is stored in peFlags and may be used by the app if D3DPTEXTURECAPS_ALPHAPALETTE device
             * capability flag is present (wine does advertise this capability) */
            for (i = 0; i < 256; ++i)
            {
                table[i][0] = device->palettes[device->currentPalette][i].peRed;
                table[i][1] = device->palettes[device->currentPalette][i].peGreen;
                table[i][2] = device->palettes[device->currentPalette][i].peBlue;
                table[i][3] = device->palettes[device->currentPalette][i].peFlags;
            }
        }
    }
    else
    {
        TRACE("Using surface palette %p\n", pal);
        /* Get the surface's palette */
        for (i = 0; i < 256; ++i)
        {
            table[i][0] = pal->palents[i].peRed;
            table[i][1] = pal->palents[i].peGreen;
            table[i][2] = pal->palents[i].peBlue;

            /* When index_in_alpha is set the palette index is stored in the
             * alpha component. In case of a readback we can then read
             * GL_ALPHA. Color keying is handled in BltOverride using a
             * GL_ALPHA_TEST using GL_NOT_EQUAL. In case of index_in_alpha the
             * color key itself is passed to glAlphaFunc in other cases the
             * alpha component of pixels that should be masked away is set to 0. */
            if (index_in_alpha)
            {
                table[i][3] = i;
            }
            else if (colorkey && (i >= This->SrcBltCKey.dwColorSpaceLowValue)
                    && (i <= This->SrcBltCKey.dwColorSpaceHighValue))
            {
                table[i][3] = 0x00;
            }
            else if(pal->Flags & WINEDDPCAPS_ALPHA)
            {
                table[i][3] = pal->palents[i].peFlags;
            }
            else
            {
                table[i][3] = 0xFF;
            }
        }
    }
}

static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UINT width,
        UINT height, UINT outpitch, CONVERT_TYPES convert, IWineD3DSurfaceImpl *This)
{
    const BYTE *source;
    BYTE *dest;
    TRACE("(%p)->(%p),(%d,%d,%d,%d,%p)\n", src, dst, pitch, height, outpitch, convert,This);

    switch (convert) {
        case NO_CONVERSION:
        {
            memcpy(dst, src, pitch * height);
            break;
        }
        case CONVERT_PALETTED:
        case CONVERT_PALETTED_CK:
        {
            IWineD3DPaletteImpl* pal = This->palette;
            BYTE table[256][4];
            unsigned int x, y;

            if( pal == NULL) {
                /* TODO: If we are a sublevel, try to get the palette from level 0 */
            }

            d3dfmt_p8_init_palette(This, table, (convert == CONVERT_PALETTED_CK));

            for (y = 0; y < height; y++)
            {
                source = src + pitch * y;
                dest = dst + outpitch * y;
                /* This is an 1 bpp format, using the width here is fine */
                for (x = 0; x < width; x++) {
                    BYTE color = *source++;
                    *dest++ = table[color][0];
                    *dest++ = table[color][1];
                    *dest++ = table[color][2];
                    *dest++ = table[color][3];
                }
            }
        }
        break;

        case CONVERT_CK_565:
        {
            /* Converting the 565 format in 5551 packed to emulate color-keying.

              Note : in all these conversion, it would be best to average the averaging
                      pixels to get the color of the pixel that will be color-keyed to
                      prevent 'color bleeding'. This will be done later on if ever it is
                      too visible.

              Note2: Nvidia documents say that their driver does not support alpha + color keying
                     on the same surface and disables color keying in such a case
            */
            unsigned int x, y;
            const WORD *Source;
            WORD *Dest;

            TRACE("Color keyed 565\n");

            for (y = 0; y < height; y++) {
                Source = (const WORD *)(src + y * pitch);
                Dest = (WORD *) (dst + y * outpitch);
                for (x = 0; x < width; x++ ) {
                    WORD color = *Source++;
                    *Dest = ((color & 0xFFC0) | ((color & 0x1F) << 1));
                    if ((color < This->SrcBltCKey.dwColorSpaceLowValue) ||
                        (color > This->SrcBltCKey.dwColorSpaceHighValue)) {
                        *Dest |= 0x0001;
                    }
                    Dest++;
                }
            }
        }
        break;

        case CONVERT_CK_5551:
        {
            /* Converting X1R5G5B5 format to R5G5B5A1 to emulate color-keying. */
            unsigned int x, y;
            const WORD *Source;
            WORD *Dest;
            TRACE("Color keyed 5551\n");
            for (y = 0; y < height; y++) {
                Source = (const WORD *)(src + y * pitch);
                Dest = (WORD *) (dst + y * outpitch);
                for (x = 0; x < width; x++ ) {
                    WORD color = *Source++;
                    *Dest = color;
                    if ((color < This->SrcBltCKey.dwColorSpaceLowValue) ||
                        (color > This->SrcBltCKey.dwColorSpaceHighValue)) {
                        *Dest |= (1 << 15);
                    }
                    else {
                        *Dest &= ~(1 << 15);
                    }
                    Dest++;
                }
            }
        }
        break;

        case CONVERT_CK_RGB24:
        {
            /* Converting R8G8B8 format to R8G8B8A8 with color-keying. */
            unsigned int x, y;
            for (y = 0; y < height; y++)
            {
                source = src + pitch * y;
                dest = dst + outpitch * y;
                for (x = 0; x < width; x++) {
                    DWORD color = ((DWORD)source[0] << 16) + ((DWORD)source[1] << 8) + (DWORD)source[2] ;
                    DWORD dstcolor = color << 8;
                    if ((color < This->SrcBltCKey.dwColorSpaceLowValue) ||
                        (color > This->SrcBltCKey.dwColorSpaceHighValue)) {
                        dstcolor |= 0xff;
                    }
                    *(DWORD*)dest = dstcolor;
                    source += 3;
                    dest += 4;
                }
            }
        }
        break;

        case CONVERT_RGB32_888:
        {
            /* Converting X8R8G8B8 format to R8G8B8A8 with color-keying. */
            unsigned int x, y;
            for (y = 0; y < height; y++)
            {
                source = src + pitch * y;
                dest = dst + outpitch * y;
                for (x = 0; x < width; x++) {
                    DWORD color = 0xffffff & *(const DWORD*)source;
                    DWORD dstcolor = color << 8;
                    if ((color < This->SrcBltCKey.dwColorSpaceLowValue) ||
                        (color > This->SrcBltCKey.dwColorSpaceHighValue)) {
                        dstcolor |= 0xff;
                    }
                    *(DWORD*)dest = dstcolor;
                    source += 4;
                    dest += 4;
                }
            }
        }
        break;

        case CONVERT_V8U8:
        {
            unsigned int x, y;
            const short *Source;
            unsigned char *Dest;
            for(y = 0; y < height; y++) {
                Source = (const short *)(src + y * pitch);
                Dest = dst + y * outpitch;
                for (x = 0; x < width; x++ ) {
                    long color = (*Source++);
                    /* B */ Dest[0] = 0xff;
                    /* G */ Dest[1] = (color >> 8) + 128; /* V */
                    /* R */ Dest[2] = (color) + 128;      /* U */
                    Dest += 3;
                }
            }
            break;
        }

        case CONVERT_V16U16:
        {
            unsigned int x, y;
            const DWORD *Source;
            unsigned short *Dest;
            for(y = 0; y < height; y++) {
                Source = (const DWORD *)(src + y * pitch);
                Dest = (unsigned short *) (dst + y * outpitch);
                for (x = 0; x < width; x++ ) {
                    DWORD color = (*Source++);
                    /* B */ Dest[0] = 0xffff;
                    /* G */ Dest[1] = (color >> 16) + 32768; /* V */
                    /* R */ Dest[2] = (color      ) + 32768; /* U */
                    Dest += 3;
                }
            }
            break;
        }

        case CONVERT_Q8W8V8U8:
        {
            unsigned int x, y;
            const DWORD *Source;
            unsigned char *Dest;
            for(y = 0; y < height; y++) {
                Source = (const DWORD *)(src + y * pitch);
                Dest = dst + y * outpitch;
                for (x = 0; x < width; x++ ) {
                    long color = (*Source++);
                    /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */
                    /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
                    /* R */ Dest[2] = (color         & 0xff) + 128; /* U */
                    /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */
                    Dest += 4;
                }
            }
            break;
        }

        case CONVERT_L6V5U5:
        {
            unsigned int x, y;
            const WORD *Source;
            unsigned char *Dest;

            if(GL_SUPPORT(NV_TEXTURE_SHADER)) {
                /* This makes the gl surface bigger(24 bit instead of 16), but it works with
                 * fixed function and shaders without further conversion once the surface is
                 * loaded
                 */
                for(y = 0; y < height; y++) {
                    Source = (const WORD *)(src + y * pitch);
                    Dest = dst + y * outpitch;
                    for (x = 0; x < width; x++ ) {
                        short color = (*Source++);
                        unsigned char l = ((color >> 10) & 0xfc);
                                  char v = ((color >>  5) & 0x3e);
                                  char u = ((color      ) & 0x1f);

                        /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign
                         * and doubles the positive range. Thus shift left only once, gl does the 2nd
                         * shift. GL reads a signed value and converts it into an unsigned value.
                         */
                        /* M */ Dest[2] = l << 1;

                        /* Those are read as signed, but kept signed. Just left-shift 3 times to scale
                         * from 5 bit values to 8 bit values.
                         */
                        /* V */ Dest[1] = v << 3;
                        /* U */ Dest[0] = u << 3;
                        Dest += 3;
                    }
                }
            } else {
                for(y = 0; y < height; y++) {
                    unsigned short *Dest_s = (unsigned short *) (dst + y * outpitch);
                    Source = (const WORD *)(src + y * pitch);
                    for (x = 0; x < width; x++ ) {
                        short color = (*Source++);
                        unsigned char l = ((color >> 10) & 0xfc);
                                 short v = ((color >>  5) & 0x3e);
                                 short u = ((color      ) & 0x1f);
                        short v_conv = v + 16;
                        short u_conv = u + 16;

                        *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f);
                        Dest_s += 1;
                    }
                }
            }
            break;
        }

        case CONVERT_X8L8V8U8:
        {
            unsigned int x, y;
            const DWORD *Source;
            unsigned char *Dest;

            if(GL_SUPPORT(NV_TEXTURE_SHADER)) {
                /* This implementation works with the fixed function pipeline and shaders
                 * without further modification after converting the surface.
                 */
                for(y = 0; y < height; y++) {
                    Source = (const DWORD *)(src + y * pitch);
                    Dest = dst + y * outpitch;
                    for (x = 0; x < width; x++ ) {
                        long color = (*Source++);
                        /* L */ Dest[2] = ((color >> 16) & 0xff);   /* L */
                        /* V */ Dest[1] = ((color >> 8 ) & 0xff);   /* V */
                        /* U */ Dest[0] = (color         & 0xff);   /* U */
                        /* I */ Dest[3] = 255;                      /* X */
                        Dest += 4;
                    }
                }
            } else {
                /* Doesn't work correctly with the fixed function pipeline, but can work in
                 * shaders if the shader is adjusted. (There's no use for this format in gl's
                 * standard fixed function pipeline anyway).
                 */
                for(y = 0; y < height; y++) {
                    Source = (const DWORD *)(src + y * pitch);
                    Dest = dst + y * outpitch;
                    for (x = 0; x < width; x++ ) {
                        long color = (*Source++);
                        /* B */ Dest[0] = ((color >> 16) & 0xff);       /* L */
                        /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
                        /* R */ Dest[2] = (color         & 0xff) + 128;  /* U */
                        Dest += 4;
                    }
                }
            }
            break;
        }

        case CONVERT_A4L4:
        {
            unsigned int x, y;
            const unsigned char *Source;
            unsigned char *Dest;
            for(y = 0; y < height; y++) {
                Source = src + y * pitch;
                Dest = dst + y * outpitch;
                for (x = 0; x < width; x++ ) {
                    unsigned char color = (*Source++);
                    /* A */ Dest[1] = (color & 0xf0) << 0;
                    /* L */ Dest[0] = (color & 0x0f) << 4;
                    Dest += 2;
                }
            }
            break;
        }

        case CONVERT_G16R16:
        case CONVERT_R16G16F:
        {
            unsigned int x, y;
            const WORD *Source;
            WORD *Dest;

            for(y = 0; y < height; y++) {
                Source = (const WORD *)(src + y * pitch);
                Dest = (WORD *) (dst + y * outpitch);
                for (x = 0; x < width; x++ ) {
                    WORD green = (*Source++);
                    WORD red = (*Source++);
                    Dest[0] = green;
                    Dest[1] = red;
                    /* Strictly speaking not correct for R16G16F, but it doesn't matter because the
                     * shader overwrites it anyway
                     */
                    Dest[2] = 0xffff;
                    Dest += 3;
                }
            }
            break;
        }

        case CONVERT_R32G32F:
        {
            unsigned int x, y;
            const float *Source;
            float *Dest;
            for(y = 0; y < height; y++) {
                Source = (const float *)(src + y * pitch);
                Dest = (float *) (dst + y * outpitch);
                for (x = 0; x < width; x++ ) {
                    float green = (*Source++);
                    float red = (*Source++);
                    Dest[0] = green;
                    Dest[1] = red;
                    Dest[2] = 1.0f;
                    Dest += 3;
                }
            }
            break;
        }

        case CONVERT_D15S1:
        {
            unsigned int x, y;

            for (y = 0; y < height; ++y)
            {
                const WORD *source = (const WORD *)(src + y * pitch);
                DWORD *dest = (DWORD *)(dst + y * outpitch);

                for (x = 0; x < width; ++x)
                {
                    /* The depth data is normalized, so needs to be scaled,
                     * the stencil data isn't.  Scale depth data by
                     *      (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */
                    WORD d15 = source[x] >> 1;
                    DWORD d24 = (d15 << 9) + (d15 >> 6);
                    dest[x] = (d24 << 8) | (source[x] & 0x1);
                }
            }
            break;
        }

        case CONVERT_D24X4S4:
        {
            unsigned int x, y;

            for (y = 0; y < height; ++y)
            {
                const DWORD *source = (const DWORD *)(src + y * pitch);
                DWORD *dest = (DWORD *)(dst + y * outpitch);

                for (x = 0; x < width; ++x)
                {
                    /* Just need to clear out the X4 part. */
                    dest[x] = source[x] & ~0xf0;
                }
            }
            break;
        }

        case CONVERT_D24FS8:
        {
            unsigned int x, y;

            for (y = 0; y < height; ++y)
            {
                const DWORD *source = (const DWORD *)(src + y * pitch);
                float *dest_f = (float *)(dst + y * outpitch);
                DWORD *dest_s = (DWORD *)(dst + y * outpitch);

                for (x = 0; x < width; ++x)
                {
                    dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8);
                    dest_s[x * 2 + 1] = source[x] & 0xff;
                }
            }
            break;
        }

        default:
            ERR("Unsupported conversion type %#x.\n", convert);
    }
    return WINED3D_OK;
}

/* This function is used in case of 8bit paletted textures to upload the palette.
   It supports GL_EXT_paletted_texture and GL_ARB_fragment_program, support for other
   extensions like ATI_fragment_shaders is possible.
*/
/* Context activation is done by the caller. */
static void d3dfmt_p8_upload_palette(IWineD3DSurface *iface, CONVERT_TYPES convert) {
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
    BYTE table[256][4];
    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;

    d3dfmt_p8_init_palette(This, table, (convert == CONVERT_PALETTED_CK));

    /* Try to use the paletted texture extension */
    if(GL_SUPPORT(EXT_PALETTED_TEXTURE))
    {
        TRACE("Using GL_EXT_PALETTED_TEXTURE for 8-bit paletted texture support\n");
        ENTER_GL();
        GL_EXTCALL(glColorTableEXT(This->texture_target, GL_RGBA, 256, GL_RGBA, GL_UNSIGNED_BYTE, table));
        LEAVE_GL();
    }
    else
    {
        /* Let a fragment shader do the color conversion by uploading the palette to a 1D texture.
         * The 8bit pixel data will be used as an index in this palette texture to retrieve the final color. */
        TRACE("Using fragment shaders for emulating 8-bit paletted texture support\n");

        ENTER_GL();

        /* Create the fragment program if we don't have it */
        if(!device->paletteConversionShader)
        {
            const char *fragment_palette_conversion =
                "!!ARBfp1.0\n"
                "TEMP index;\n"
                /* { 255/256, 0.5/255*255/256, 0, 0 } */
                "PARAM constants = { 0.996, 0.00195, 0, 0 };\n"
                /* The alpha-component contains the palette index */
                "TEX index, fragment.texcoord[0], texture[0], 2D;\n"
                /* Scale the index by 255/256 and add a bias of '0.5' in order to sample in the middle */
                "MAD index.a, index.a, constants.x, constants.y;\n"
                /* Use the alpha-component as an index in the palette to get the final color */
                "TEX result.color, index.a, texture[1], 1D;\n"
                "END";

            glEnable(GL_FRAGMENT_PROGRAM_ARB);
            GL_EXTCALL(glGenProgramsARB(1, &device->paletteConversionShader));
            GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, device->paletteConversionShader));
            GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(fragment_palette_conversion), fragment_palette_conversion));
            glDisable(GL_FRAGMENT_PROGRAM_ARB);
        }

        glEnable(GL_FRAGMENT_PROGRAM_ARB);
        GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, device->paletteConversionShader));

        GL_EXTCALL(glActiveTextureARB(GL_TEXTURE1));
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

        glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); /* Make sure we have discrete color levels. */
        glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, table); /* Upload the palette */

        /* Switch back to unit 0 in which the 2D texture will be stored. */
        GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0));

        /* Rebind the texture because it isn't bound anymore */
        glBindTexture(This->texture_target, This->texture_name);

        LEAVE_GL();
    }
}

BOOL palette9_changed(IWineD3DSurfaceImpl *This) {
    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;

    if (This->palette || (This->resource.format_desc->format != WINED3DFMT_P8_UINT
            && This->resource.format_desc->format != WINED3DFMT_P8_UINT_A8_UNORM))
    {
        /* If a ddraw-style palette is attached assume no d3d9 palette change.
         * Also the palette isn't interesting if the surface format isn't P8 or A8P8
         */
        return FALSE;
    }

    if(This->palette9) {
        if(memcmp(This->palette9, &device->palettes[device->currentPalette], sizeof(PALETTEENTRY) * 256) == 0) {
            return FALSE;
        }
    } else {
        This->palette9 = HeapAlloc(GetProcessHeap(), 0, sizeof(PALETTEENTRY) * 256);
    }
    memcpy(This->palette9, &device->palettes[device->currentPalette], sizeof(PALETTEENTRY) * 256);
    return TRUE;
}

static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface, BOOL srgb_mode) {
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
    DWORD flag = srgb_mode ? SFLAG_INSRGBTEX : SFLAG_INTEXTURE;

    if (!(This->Flags & flag)) {
        TRACE("Reloading because surface is dirty\n");
    } else if(/* Reload: gl texture has ck, now no ckey is set OR */
              ((This->Flags & SFLAG_GLCKEY) && (!(This->CKeyFlags & WINEDDSD_CKSRCBLT))) ||
              /* Reload: vice versa  OR */
              ((!(This->Flags & SFLAG_GLCKEY)) && (This->CKeyFlags & WINEDDSD_CKSRCBLT)) ||
              /* Also reload: Color key is active AND the color key has changed */
              ((This->CKeyFlags & WINEDDSD_CKSRCBLT) && (
                (This->glCKey.dwColorSpaceLowValue != This->SrcBltCKey.dwColorSpaceLowValue) ||
                (This->glCKey.dwColorSpaceHighValue != This->SrcBltCKey.dwColorSpaceHighValue)))) {
        TRACE("Reloading because of color keying\n");
        /* To perform the color key conversion we need a sysmem copy of
         * the surface. Make sure we have it
         */

        IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, NULL);
        /* Make sure the texture is reloaded because of the color key change, this kills performance though :( */
        /* TODO: This is not necessarily needed with hw palettized texture support */
        IWineD3DSurface_ModifyLocation(iface, SFLAG_INSYSMEM, TRUE);
    } else {
        TRACE("surface is already in texture\n");
        return WINED3D_OK;
    }

    /* 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.
     */
    if (This->resource.pool == WINED3DPOOL_SCRATCH )
    {
        FIXME("(%p) Operation not supported for scratch textures\n",This);
        return WINED3DERR_INVALIDCALL;
    }

    IWineD3DSurface_LoadLocation(iface, flag, NULL /* no partial locking for textures yet */);

#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->texture_target, This->texture_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.heapMemory);
        This->resource.allocatedMemory = NULL;
        This->resource.heapMemory = NULL;
        IWineD3DSurface_ModifyLocation(iface, SFLAG_INSYSMEM, FALSE);
    }

    return WINED3D_OK;
}

/* Context activation is done by the caller. */
static void WINAPI IWineD3DSurfaceImpl_BindTexture(IWineD3DSurface *iface, BOOL srgb) {
    /* TODO: check for locks */
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
    IWineD3DBaseTexture *baseTexture = NULL;
    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;

    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 container\n");
        IWineD3DBaseTexture_BindTexture(baseTexture, srgb);
        IWineD3DBaseTexture_Release(baseTexture);
    } else {
        GLuint *name;
        TRACE("(%p) : Binding surface\n", This);

        name = srgb ? &This->texture_name_srgb : &This->texture_name;
        if(!device->isInDraw) {
            ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
        }

        ENTER_GL();

        if (!This->texture_level)
        {
            if (!*name) {
                glGenTextures(1, name);
                checkGLcall("glGenTextures");
                TRACE("Surface %p given name %d\n", This, *name);

                glBindTexture(This->texture_target, *name);
                checkGLcall("glBindTexture");
                glTexParameteri(This->texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
                checkGLcall("glTexParameteri(dimension, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)");
                glTexParameteri(This->texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
                checkGLcall("glTexParameteri(dimension, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)");
                glTexParameteri(This->texture_target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
                checkGLcall("glTexParameteri(dimension, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE)");
                glTexParameteri(This->texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
                checkGLcall("glTexParameteri(dimension, GL_TEXTURE_MIN_FILTER, GL_NEAREST)");
                glTexParameteri(This->texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
                checkGLcall("glTexParameteri(dimension, GL_TEXTURE_MAG_FILTER, GL_NEAREST)");
            }
            /* This is where we should be reducing the amount of GLMemoryUsed */
        } else if (*name) {
            /* Mipmap surfaces should have a base texture container */
            ERR("Mipmap surface has a glTexture bound to it!\n");
        }

        glBindTexture(This->texture_target, *name);
        checkGLcall("glBindTexture");

        LEAVE_GL();
    }
    return;
}

#include <errno.h>
#include <stdio.h>
static HRESULT WINAPI IWineD3DSurfaceImpl_SaveSnapshot(IWineD3DSurface *iface, const char* filename)
{
    FILE* f = NULL;
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
    char *allocatedMemory;
    const char *textureRow;
    IWineD3DSwapChain *swapChain = NULL;
    int width, height, i, y;
    GLuint tmpTexture = 0;
    DWORD color;
    /*FIXME:
    Textures may 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 we're a 'virtual' texture, e.g. we're not a pbuffer of texture, we're a back buffer*/
    IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapChain);

    if (This->Flags & SFLAG_INDRAWABLE && !(This->Flags & SFLAG_INTEXTURE)) {
        /* 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();
        TRACE("(%p) Reading render target into texture\n", This);

        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);
        checkGLcall("glGetIntegerv");
        glReadBuffer(swapChain ? GL_BACK : This->resource.wineD3DDevice->offscreenBuffer);
        checkGLcall("glReadBuffer");
        glCopyTexImage2D(GL_TEXTURE_2D,
                            0,
                            GL_RGBA,
                            0,
                            0,
                            width,
                            height,
                            0);

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

    } else { /* bind the real texture, and make sure it up to date */
        surface_internal_preload(iface, SRGB_RGB);
        surface_bind_and_dirtify(This, FALSE);
    }
    allocatedMemory = HeapAlloc(GetProcessHeap(), 0, width  * height * 4);
    ENTER_GL();
    FIXME("Saving texture level %d width %d height %d\n", This->texture_level, width, height);
    glGetTexImage(GL_TEXTURE_2D, This->texture_level, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, allocatedMemory);
    checkGLcall("glGetTexImage");
    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 data out to a TGA file because 1: it's an easy raw format, 2: it supports an alpha channel */
    TRACE("(%p) opened %s with format %s\n", This, filename, debug_d3dformat(This->resource.format_desc->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 = *((const 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;
}

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

    TRACE("(%p) : Calling base function first\n", This);
    hr = IWineD3DBaseSurfaceImpl_SetFormat(iface, format);
    if(SUCCEEDED(hr)) {
        This->Flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED);
        TRACE("(%p) : glFormat %d, glFormatInternal %d, glType %d\n", This, This->resource.format_desc->glFormat,
                This->resource.format_desc->glInternal, This->resource.format_desc->glType);
    }
    return hr;
}

static HRESULT WINAPI IWineD3DSurfaceImpl_SetMem(IWineD3DSurface *iface, void *Mem) {
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;

    if(This->Flags & (SFLAG_LOCKED | SFLAG_DCINUSE)) {
        WARN("Surface is locked or the HDC is in use\n");
        return WINED3DERR_INVALIDCALL;
    }

    if(Mem && Mem != This->resource.allocatedMemory) {
        void *release = NULL;

        /* Do I have to copy the old surface content? */
        if(This->Flags & SFLAG_DIBSECTION) {
                /* Release the DC. No need to hold the critical section for the update
                 * Thread because this thread runs only on front buffers, but this method
                 * fails for render targets in the check above.
                 */
                SelectObject(This->hDC, This->dib.holdbitmap);
                DeleteDC(This->hDC);
                /* Release the DIB section */
                DeleteObject(This->dib.DIBsection);
                This->dib.bitmap_data = NULL;
                This->resource.allocatedMemory = NULL;
                This->hDC = NULL;
                This->Flags &= ~SFLAG_DIBSECTION;
        } else if(!(This->Flags & SFLAG_USERPTR)) {
            release = This->resource.heapMemory;
            This->resource.heapMemory = NULL;
        }
        This->resource.allocatedMemory = Mem;
        This->Flags |= SFLAG_USERPTR | SFLAG_INSYSMEM;

        /* Now the surface memory is most up do date. Invalidate drawable and texture */
        IWineD3DSurface_ModifyLocation(iface, SFLAG_INSYSMEM, TRUE);

        /* For client textures opengl has to be notified */
        if(This->Flags & SFLAG_CLIENT) {
            DWORD oldFlags = This->Flags;
            This->Flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED);
            if(oldFlags & SFLAG_ALLOCATED) surface_internal_preload(iface, SRGB_RGB);
            if(oldFlags & SFLAG_SRGBALLOCATED) surface_internal_preload(iface, SRGB_SRGB);
            /* And hope that the app behaves correctly and did not free the old surface memory before setting a new pointer */
        }

        /* Now free the old memory if any */
        HeapFree(GetProcessHeap(), 0, release);
    } else if(This->Flags & SFLAG_USERPTR) {
        /* LockRect and GetDC will re-create the dib section and allocated memory */
        This->resource.allocatedMemory = NULL;
        /* HeapMemory should be NULL already */
        if(This->resource.heapMemory != NULL) ERR("User pointer surface has heap memory allocated\n");
        This->Flags &= ~SFLAG_USERPTR;

        if(This->Flags & SFLAG_CLIENT) {
            DWORD oldFlags = This->Flags;
            This->Flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED);
            /* This respecifies an empty texture and opengl knows that the old memory is gone */
            if(oldFlags & SFLAG_ALLOCATED) surface_internal_preload(iface, SRGB_RGB);
            if(oldFlags & SFLAG_SRGBALLOCATED) surface_internal_preload(iface, SRGB_SRGB);
        }
    }
    return WINED3D_OK;
}

void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back) {

    /* Flip the surface contents */
    /* Flip the DC */
    {
        HDC tmp;
        tmp = front->hDC;
        front->hDC = back->hDC;
        back->hDC = tmp;
    }

    /* Flip the DIBsection */
    {
        HBITMAP tmp;
        BOOL hasDib = front->Flags & SFLAG_DIBSECTION;
        tmp = front->dib.DIBsection;
        front->dib.DIBsection = back->dib.DIBsection;
        back->dib.DIBsection = tmp;

        if(back->Flags & SFLAG_DIBSECTION) front->Flags |= SFLAG_DIBSECTION;
        else front->Flags &= ~SFLAG_DIBSECTION;
        if(hasDib) back->Flags |= SFLAG_DIBSECTION;
        else back->Flags &= ~SFLAG_DIBSECTION;
    }

    /* Flip the surface data */
    {
        void* tmp;

        tmp = front->dib.bitmap_data;
        front->dib.bitmap_data = back->dib.bitmap_data;
        back->dib.bitmap_data = tmp;

        tmp = front->resource.allocatedMemory;
        front->resource.allocatedMemory = back->resource.allocatedMemory;
        back->resource.allocatedMemory = tmp;

        tmp = front->resource.heapMemory;
        front->resource.heapMemory = back->resource.heapMemory;
        back->resource.heapMemory = tmp;
    }

    /* Flip the PBO */
    {
        GLuint tmp_pbo = front->pbo;
        front->pbo = back->pbo;
        back->pbo = tmp_pbo;
    }

    /* client_memory should not be different, but just in case */
    {
        BOOL tmp;
        tmp = front->dib.client_memory;
        front->dib.client_memory = back->dib.client_memory;
        back->dib.client_memory = tmp;
    }

    /* Flip the opengl texture */
    {
        GLuint tmp;

        tmp = back->texture_name;
        back->texture_name = front->texture_name;
        front->texture_name = tmp;

        tmp = back->texture_name_srgb;
        back->texture_name_srgb = front->texture_name_srgb;
        front->texture_name_srgb = tmp;
    }

    {
        DWORD tmp_flags = back->Flags;
        back->Flags = front->Flags;
        front->Flags = tmp_flags;
    }
}

static HRESULT WINAPI IWineD3DSurfaceImpl_Flip(IWineD3DSurface *iface, IWineD3DSurface *override, DWORD Flags) {
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
    IWineD3DSwapChainImpl *swapchain = NULL;
    HRESULT hr;
    TRACE("(%p)->(%p,%x)\n", This, override, Flags);

    /* Flipping is only supported on RenderTargets and overlays*/
    if( !(This->resource.usage & (WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_OVERLAY)) ) {
        WARN("Tried to flip a non-render target, non-overlay surface\n");
        return WINEDDERR_NOTFLIPPABLE;
    }

    if(This->resource.usage & WINED3DUSAGE_OVERLAY) {
        flip_surface(This, (IWineD3DSurfaceImpl *) override);

        /* Update the overlay if it is visible */
        if(This->overlay_dest) {
            return IWineD3DSurface_DrawOverlay((IWineD3DSurface *) This);
        } else {
            return WINED3D_OK;
        }
    }

    if(override) {
        /* DDraw sets this for the X11 surfaces, so don't confuse the user
         * FIXME("(%p) Target override is not supported by now\n", This);
         * Additionally, it isn't really possible to support triple-buffering
         * properly on opengl at all
         */
    }

    IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **) &swapchain);
    if(!swapchain) {
        ERR("Flipped surface is not on a swapchain\n");
        return WINEDDERR_NOTFLIPPABLE;
    }

    /* Just overwrite the swapchain presentation interval. This is ok because only ddraw apps can call Flip,
     * and only d3d8 and d3d9 apps specify the presentation interval
     */
    if((Flags & (WINEDDFLIP_NOVSYNC | WINEDDFLIP_INTERVAL2 | WINEDDFLIP_INTERVAL3 | WINEDDFLIP_INTERVAL4)) == 0) {
        /* Most common case first to avoid wasting time on all the other cases */
        swapchain->presentParms.PresentationInterval = WINED3DPRESENT_INTERVAL_ONE;
    } else if(Flags & WINEDDFLIP_NOVSYNC) {
        swapchain->presentParms.PresentationInterval = WINED3DPRESENT_INTERVAL_IMMEDIATE;
    } else if(Flags & WINEDDFLIP_INTERVAL2) {
        swapchain->presentParms.PresentationInterval = WINED3DPRESENT_INTERVAL_TWO;
    } else if(Flags & WINEDDFLIP_INTERVAL3) {
        swapchain->presentParms.PresentationInterval = WINED3DPRESENT_INTERVAL_THREE;
    } else {
        swapchain->presentParms.PresentationInterval = WINED3DPRESENT_INTERVAL_FOUR;
    }

    /* Flipping a OpenGL surface -> Use WineD3DDevice::Present */
    hr = IWineD3DSwapChain_Present((IWineD3DSwapChain *) swapchain, NULL, NULL, 0, NULL, 0);
    IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
    return hr;
}

/* Does a direct frame buffer -> texture copy. Stretching is done
 * with single pixel copy calls
 */
static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3DSurface *SrcSurface,
        IWineD3DSwapChainImpl *swapchain, const WINED3DRECT *srect, const WINED3DRECT *drect,
        BOOL upsidedown, WINED3DTEXTUREFILTERTYPE Filter)
{
    IWineD3DDeviceImpl *myDevice = This->resource.wineD3DDevice;
    float xrel, yrel;
    UINT row;
    IWineD3DSurfaceImpl *Src = (IWineD3DSurfaceImpl *) SrcSurface;


    ActivateContext(myDevice, SrcSurface, CTXUSAGE_BLIT);
    surface_internal_preload((IWineD3DSurface *) This, SRGB_RGB);
    ENTER_GL();

    /* Bind the target texture */
    glBindTexture(This->texture_target, This->texture_name);
    checkGLcall("glBindTexture");
    if(!swapchain) {
        TRACE("Reading from an offscreen target\n");
        upsidedown = !upsidedown;
        glReadBuffer(myDevice->offscreenBuffer);
    } else {
        GLenum buffer = surface_get_gl_buffer(SrcSurface, (IWineD3DSwapChain *)swapchain);
        glReadBuffer(buffer);
    }
    checkGLcall("glReadBuffer");

    xrel = (float) (srect->x2 - srect->x1) / (float) (drect->x2 - drect->x1);
    yrel = (float) (srect->y2 - srect->y1) / (float) (drect->y2 - drect->y1);

    if ((xrel - 1.0f < -eps) || (xrel - 1.0f > eps))
    {
        FIXME("Doing a pixel by pixel copy from the framebuffer to a texture, expect major performance issues\n");

        if(Filter != WINED3DTEXF_NONE && Filter != WINED3DTEXF_POINT) {
            ERR("Texture filtering not supported in direct blit\n");
        }
    }
    else if ((Filter != WINED3DTEXF_NONE && Filter != WINED3DTEXF_POINT)
            && ((yrel - 1.0f < -eps) || (yrel - 1.0f > eps)))
    {
        ERR("Texture filtering not supported in direct blit\n");
    }

    if (upsidedown
            && !((xrel - 1.0f < -eps) || (xrel - 1.0f > eps))
            && !((yrel - 1.0f < -eps) || (yrel - 1.0f > eps)))
    {
        /* Upside down copy without stretching is nice, one glCopyTexSubImage call will do */

        glCopyTexSubImage2D(This->texture_target, This->texture_level,
                drect->x1 /*xoffset */, drect->y1 /* y offset */,
                srect->x1, Src->currentDesc.Height - srect->y2,
                drect->x2 - drect->x1, drect->y2 - drect->y1);
    } else {
        UINT yoffset = Src->currentDesc.Height - srect->y1 + drect->y1 - 1;
        /* I have to process this row by row to swap the image,
         * otherwise it would be upside down, so stretching in y direction
         * doesn't cost extra time
         *
         * However, stretching in x direction can be avoided if not necessary
         */
        for(row = drect->y1; row < drect->y2; row++) {
            if ((xrel - 1.0f < -eps) || (xrel - 1.0f > eps))
            {
                /* Well, that stuff works, but it's very slow.
                 * find a better way instead
                 */
                UINT col;

                for(col = drect->x1; col < drect->x2; col++) {
                    glCopyTexSubImage2D(This->texture_target, This->texture_level,
                            drect->x1 + col /* x offset */, row /* y offset */,
                            srect->x1 + col * xrel, yoffset - (int) (row * yrel), 1, 1);
                }
            } else {
                glCopyTexSubImage2D(This->texture_target, This->texture_level,
                        drect->x1 /* x offset */, row /* y offset */,
                        srect->x1, yoffset - (int) (row * yrel), drect->x2-drect->x1, 1);
            }
        }
    }
    checkGLcall("glCopyTexSubImage2D");

    LEAVE_GL();

    /* The texture is now most up to date - If the surface is a render target and has a drawable, this
     * path is never entered
     */
    IWineD3DSurface_ModifyLocation((IWineD3DSurface *) This, SFLAG_INTEXTURE, TRUE);
}

/* Uses the hardware to stretch and flip the image */
static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWineD3DSurface *SrcSurface,
        IWineD3DSwapChainImpl *swapchain, const WINED3DRECT *srect, const WINED3DRECT *drect,
        BOOL upsidedown, WINED3DTEXTUREFILTERTYPE Filter)
{
    GLuint src, backup = 0;
    IWineD3DDeviceImpl *myDevice = This->resource.wineD3DDevice;
    IWineD3DSurfaceImpl *Src = (IWineD3DSurfaceImpl *) SrcSurface;
    float left, right, top, bottom; /* Texture coordinates */
    UINT fbwidth = Src->currentDesc.Width;
    UINT fbheight = Src->currentDesc.Height;
    struct wined3d_context *context;
    GLenum drawBuffer = GL_BACK;
    GLenum texture_target;
    BOOL noBackBufferBackup;

    TRACE("Using hwstretch blit\n");
    /* Activate the Proper context for reading from the source surface, set it up for blitting */
    context = ActivateContext(myDevice, SrcSurface, CTXUSAGE_BLIT);
    surface_internal_preload((IWineD3DSurface *) This, SRGB_RGB);

    noBackBufferBackup = !swapchain && wined3d_settings.offscreen_rendering_mode == ORM_FBO;
    if (!noBackBufferBackup && !Src->texture_name)
    {
        /* Get it a description */
        surface_internal_preload(SrcSurface, SRGB_RGB);
    }
    ENTER_GL();

    /* Try to use an aux buffer for drawing the rectangle. This way it doesn't need restoring.
     * This way we don't have to wait for the 2nd readback to finish to leave this function.
     */
    if (context->aux_buffers >= 2)
    {
        /* Got more than one aux buffer? Use the 2nd aux buffer */
        drawBuffer = GL_AUX1;
    }
    else if ((swapchain || myDevice->offscreenBuffer == GL_BACK) && context->aux_buffers >= 1)
    {
        /* Only one aux buffer, but it isn't used (Onscreen rendering, or non-aux orm)? Use it! */
        drawBuffer = GL_AUX0;
    }

    if(noBackBufferBackup) {
        glGenTextures(1, &backup);
        checkGLcall("glGenTextures");
        glBindTexture(GL_TEXTURE_2D, backup);
        checkGLcall("glBindTexture(GL_TEXTURE_2D, backup)");
        texture_target = GL_TEXTURE_2D;
    } else {
        /* Backup the back buffer and copy the source buffer into a texture to draw an upside down stretched quad. If
         * we are reading from the back buffer, the backup can be used as source texture
         */
        texture_target = Src->texture_target;
        glBindTexture(texture_target, Src->texture_name);
        checkGLcall("glBindTexture(texture_target, Src->texture_name)");
        glEnable(texture_target);
        checkGLcall("glEnable(texture_target)");

        /* For now invalidate the texture copy of the back buffer. Drawable and sysmem copy are untouched */
        Src->Flags &= ~SFLAG_INTEXTURE;
    }

    if(swapchain) {
        glReadBuffer(surface_get_gl_buffer(SrcSurface, (IWineD3DSwapChain *)swapchain));
    } else {
        TRACE("Reading from an offscreen target\n");
        upsidedown = !upsidedown;
        glReadBuffer(myDevice->offscreenBuffer);
    }

    /* TODO: Only back up the part that will be overwritten */
    glCopyTexSubImage2D(texture_target, 0,
                        0, 0 /* read offsets */,
                        0, 0,
                        fbwidth,
                        fbheight);

    checkGLcall("glCopyTexSubImage2D");

    /* No issue with overriding these - the sampler is dirty due to blit usage */
    glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER,
            wined3d_gl_mag_filter(magLookup, Filter));
    checkGLcall("glTexParameteri");
    glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER,
            wined3d_gl_min_mip_filter(minMipLookup, Filter, WINED3DTEXF_NONE));
    checkGLcall("glTexParameteri");

    if(!swapchain || (IWineD3DSurface *) Src == swapchain->backBuffer[0]) {
        src = backup ? backup : Src->texture_name;
    } else {
        glReadBuffer(GL_FRONT);
        checkGLcall("glReadBuffer(GL_FRONT)");

        glGenTextures(1, &src);
        checkGLcall("glGenTextures(1, &src)");
        glBindTexture(GL_TEXTURE_2D, src);
        checkGLcall("glBindTexture(GL_TEXTURE_2D, src)");

        /* TODO: Only copy the part that will be read. Use srect->x1, srect->y2 as origin, but with the width watch
         * out for power of 2 sizes
         */
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Src->pow2Width, Src->pow2Height, 0,
                    GL_RGBA, GL_UNSIGNED_BYTE, NULL);
        checkGLcall("glTexImage2D");
        glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
                            0, 0 /* read offsets */,
                            0, 0,
                            fbwidth,
                            fbheight);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        checkGLcall("glTexParameteri");
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        checkGLcall("glTexParameteri");

        glReadBuffer(GL_BACK);
        checkGLcall("glReadBuffer(GL_BACK)");

        if(texture_target != GL_TEXTURE_2D) {
            glDisable(texture_target);
            glEnable(GL_TEXTURE_2D);
            texture_target = GL_TEXTURE_2D;
        }
    }
    checkGLcall("glEnd and previous");

    left = srect->x1;
    right = srect->x2;

    if(upsidedown) {
        top = Src->currentDesc.Height - srect->y1;
        bottom = Src->currentDesc.Height - srect->y2;
    } else {
        top = Src->currentDesc.Height - srect->y2;
        bottom = Src->currentDesc.Height - srect->y1;
    }

    if(Src->Flags & SFLAG_NORMCOORD) {
        left /= Src->pow2Width;
        right /= Src->pow2Width;
        top /= Src->pow2Height;
        bottom /= Src->pow2Height;
    }

    /* draw the source texture stretched and upside down. The correct surface is bound already */
    glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP);

    glDrawBuffer(drawBuffer);
    glReadBuffer(drawBuffer);

    glBegin(GL_QUADS);
        /* bottom left */
        glTexCoord2f(left, bottom);
        glVertex2i(0, fbheight);

        /* top left */
        glTexCoord2f(left, top);
        glVertex2i(0, fbheight - drect->y2 - drect->y1);

        /* top right */
        glTexCoord2f(right, top);
        glVertex2i(drect->x2 - drect->x1, fbheight - drect->y2 - drect->y1);

        /* bottom right */
        glTexCoord2f(right, bottom);
        glVertex2i(drect->x2 - drect->x1, fbheight);
    glEnd();
    checkGLcall("glEnd and previous");

    if (texture_target != This->texture_target)
    {
        glDisable(texture_target);
        glEnable(This->texture_target);
        texture_target = This->texture_target;
    }

    /* Now read the stretched and upside down image into the destination texture */
    glBindTexture(texture_target, This->texture_name);
    checkGLcall("glBindTexture");
    glCopyTexSubImage2D(texture_target,
                        0,
                        drect->x1, drect->y1, /* xoffset, yoffset */
                        0, 0, /* We blitted the image to the origin */
                        drect->x2 - drect->x1, drect->y2 - drect->y1);
    checkGLcall("glCopyTexSubImage2D");

    if(drawBuffer == GL_BACK) {
        /* Write the back buffer backup back */
        if(backup) {
            if(texture_target != GL_TEXTURE_2D) {
                glDisable(texture_target);
                glEnable(GL_TEXTURE_2D);
                texture_target = GL_TEXTURE_2D;
            }
            glBindTexture(GL_TEXTURE_2D, backup);
            checkGLcall("glBindTexture(GL_TEXTURE_2D, backup)");
        } else {
            if (texture_target != Src->texture_target)
            {
                glDisable(texture_target);
                glEnable(Src->texture_target);
                texture_target = Src->texture_target;
            }
            glBindTexture(Src->texture_target, Src->texture_name);
            checkGLcall("glBindTexture(Src->texture_target, Src->texture_name)");
        }

        glBegin(GL_QUADS);
            /* top left */
            glTexCoord2f(0.0f, (float)fbheight / (float)Src->pow2Height);
            glVertex2i(0, 0);

            /* bottom left */
            glTexCoord2f(0.0f, 0.0f);
            glVertex2i(0, fbheight);

            /* bottom right */
            glTexCoord2f((float)fbwidth / (float)Src->pow2Width, 0.0f);
            glVertex2i(fbwidth, Src->currentDesc.Height);

            /* top right */
            glTexCoord2f((float) fbwidth / (float) Src->pow2Width, (float) fbheight / (float) Src->pow2Height);
            glVertex2i(fbwidth, 0);
        glEnd();
    } else {
        /* Restore the old draw buffer */
        glDrawBuffer(GL_BACK);
    }
    glDisable(texture_target);
    checkGLcall("glDisable(texture_target)");

    /* Cleanup */
    if (src != Src->texture_name && src != backup)
    {
        glDeleteTextures(1, &src);
        checkGLcall("glDeleteTextures(1, &src)");
    }
    if(backup) {
        glDeleteTextures(1, &backup);
        checkGLcall("glDeleteTextures(1, &backup)");
    }

    LEAVE_GL();

    /* The texture is now most up to date - If the surface is a render target and has a drawable, this
     * path is never entered
     */
    IWineD3DSurface_ModifyLocation((IWineD3DSurface *) This, SFLAG_INTEXTURE, TRUE);
}

/* Not called from the VTable */
static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const RECT *DestRect,
        IWineD3DSurface *SrcSurface, const RECT *SrcRect, DWORD Flags, const WINEDDBLTFX *DDBltFx,
        WINED3DTEXTUREFILTERTYPE Filter)
{
    WINED3DRECT rect;
    IWineD3DDeviceImpl *myDevice = This->resource.wineD3DDevice;
    IWineD3DSwapChainImpl *srcSwapchain = NULL, *dstSwapchain = NULL;
    IWineD3DSurfaceImpl *Src = (IWineD3DSurfaceImpl *) SrcSurface;

    TRACE("(%p)->(%p,%p,%p,%08x,%p)\n", This, DestRect, SrcSurface, SrcRect, Flags, DDBltFx);

    /* Get the swapchain. One of the surfaces has to be a primary surface */
    if(This->resource.pool == WINED3DPOOL_SYSTEMMEM) {
        WARN("Destination is in sysmem, rejecting gl blt\n");
        return WINED3DERR_INVALIDCALL;
    }
    IWineD3DSurface_GetContainer( (IWineD3DSurface *) This, &IID_IWineD3DSwapChain, (void **)&dstSwapchain);
    if(dstSwapchain) IWineD3DSwapChain_Release((IWineD3DSwapChain *) dstSwapchain);
    if(Src) {
        if(Src->resource.pool == WINED3DPOOL_SYSTEMMEM) {
            WARN("Src is in sysmem, rejecting gl blt\n");
            return WINED3DERR_INVALIDCALL;
        }
        IWineD3DSurface_GetContainer( (IWineD3DSurface *) Src, &IID_IWineD3DSwapChain, (void **)&srcSwapchain);
        if(srcSwapchain) IWineD3DSwapChain_Release((IWineD3DSwapChain *) srcSwapchain);
    }

    /* Early sort out of cases where no render target is used */
    if(!dstSwapchain && !srcSwapchain &&
        SrcSurface != myDevice->render_targets[0] && This != (IWineD3DSurfaceImpl *) myDevice->render_targets[0]) {
        TRACE("No surface is render target, not using hardware blit. Src = %p, dst = %p\n", Src, This);
        return WINED3DERR_INVALIDCALL;
    }

    /* No destination color keying supported */
    if(Flags & (WINEDDBLT_KEYDEST | WINEDDBLT_KEYDESTOVERRIDE)) {
        /* Can we support that with glBlendFunc if blitting to the frame buffer? */
        TRACE("Destination color key not supported in accelerated Blit, falling back to software\n");
        return WINED3DERR_INVALIDCALL;
    }

    if (DestRect) {
        rect.x1 = DestRect->left;
        rect.y1 = DestRect->top;
        rect.x2 = DestRect->right;
        rect.y2 = DestRect->bottom;
    } else {
        rect.x1 = 0;
        rect.y1 = 0;
        rect.x2 = This->currentDesc.Width;
        rect.y2 = This->currentDesc.Height;
    }

    /* The only case where both surfaces on a swapchain are supported is a back buffer -> front buffer blit on the same swapchain */
    if(dstSwapchain && dstSwapchain == srcSwapchain && dstSwapchain->backBuffer &&
       ((IWineD3DSurface *) This == dstSwapchain->frontBuffer) && SrcSurface == dstSwapchain->backBuffer[0]) {
        /* Half-life does a Blt from the back buffer to the front buffer,
         * Full surface size, no flags... Use present instead
         *
         * This path will only be entered for d3d7 and ddraw apps, because d3d8/9 offer no way to blit TO the front buffer
         */

        /* Check rects - IWineD3DDevice_Present doesn't handle them */
        while(1)
        {
            RECT mySrcRect;
            TRACE("Looking if a Present can be done...\n");
            /* Source Rectangle must be full surface */
            if( SrcRect ) {
                if(SrcRect->left != 0 || SrcRect->top != 0 ||
                   SrcRect->right != Src->currentDesc.Width || SrcRect->bottom != Src->currentDesc.Height) {
                    TRACE("No, Source rectangle doesn't match\n");
                    break;
                }
            }
            mySrcRect.left = 0;
            mySrcRect.top = 0;
            mySrcRect.right = Src->currentDesc.Width;
            mySrcRect.bottom = Src->currentDesc.Height;

            /* No stretching may occur */
            if(mySrcRect.right != rect.x2 - rect.x1 ||
               mySrcRect.bottom != rect.y2 - rect.y1) {
                TRACE("No, stretching is done\n");
                break;
            }

            /* Destination must be full surface or match the clipping rectangle */
            if(This->clipper && ((IWineD3DClipperImpl *) This->clipper)->hWnd)
            {
                RECT cliprect;
                POINT pos[2];
                GetClientRect(((IWineD3DClipperImpl *) This->clipper)->hWnd, &cliprect);
                pos[0].x = rect.x1;
                pos[0].y = rect.y1;
                pos[1].x = rect.x2;
                pos[1].y = rect.y2;
                MapWindowPoints(GetDesktopWindow(), ((IWineD3DClipperImpl *) This->clipper)->hWnd,
                                pos, 2);

                if(pos[0].x != cliprect.left  || pos[0].y != cliprect.top   ||
                   pos[1].x != cliprect.right || pos[1].y != cliprect.bottom)
                {
                    TRACE("No, dest rectangle doesn't match(clipper)\n");
                    TRACE("Clip rect at (%d,%d)-(%d,%d)\n", cliprect.left, cliprect.top, cliprect.right, cliprect.bottom);
                    TRACE("Blt dest: (%d,%d)-(%d,%d)\n", rect.x1, rect.y1, rect.x2, rect.y2);
                    break;
                }
            }
            else
            {
                if(rect.x1 != 0 || rect.y1 != 0 ||
                   rect.x2 != This->currentDesc.Width || rect.y2 != This->currentDesc.Height) {
                    TRACE("No, dest rectangle doesn't match(surface size)\n");
                    break;
                }
            }

            TRACE("Yes\n");

            /* These flags are unimportant for the flag check, remove them */
            if((Flags & ~(WINEDDBLT_DONOTWAIT | WINEDDBLT_WAIT)) == 0) {
                WINED3DSWAPEFFECT orig_swap = dstSwapchain->presentParms.SwapEffect;

                /* The idea behind this is that a glReadPixels and a glDrawPixels call
                    * take very long, while a flip is fast.
                    * This applies to Half-Life, which does such Blts every time it finished
                    * a frame, and to Prince of Persia 3D, which uses this to draw at least the main
                    * menu. This is also used by all apps when they do windowed rendering
                    *
                    * The problem is that flipping is not really the same as copying. After a
                    * Blt the front buffer is a copy of the back buffer, and the back buffer is
                    * untouched. Therefore it's necessary to override the swap effect
                    * and to set it back after the flip.
                    *
                    * Windowed Direct3D < 7 apps do the same. The D3D7 sdk demos are nice
                    * testcases.
                    */

                dstSwapchain->presentParms.SwapEffect = WINED3DSWAPEFFECT_COPY;
                dstSwapchain->presentParms.PresentationInterval = WINED3DPRESENT_INTERVAL_IMMEDIATE;

                TRACE("Full screen back buffer -> front buffer blt, performing a flip instead\n");
                IWineD3DSwapChain_Present((IWineD3DSwapChain *) dstSwapchain, NULL, NULL, 0, NULL, 0);

                dstSwapchain->presentParms.SwapEffect = orig_swap;

                return WINED3D_OK;
            }
            break;
        }

        TRACE("Unsupported blit between buffers on the same swapchain\n");
        return WINED3DERR_INVALIDCALL;
    } else if(dstSwapchain && dstSwapchain == srcSwapchain) {
        FIXME("Implement hardware blit between two surfaces on the same swapchain\n");
        return WINED3DERR_INVALIDCALL;
    } else if(dstSwapchain && srcSwapchain) {
        FIXME("Implement hardware blit between two different swapchains\n");
        return WINED3DERR_INVALIDCALL;
    } else if(dstSwapchain) {
        if(SrcSurface == myDevice->render_targets[0]) {
            TRACE("Blit from active render target to a swapchain\n");
            /* Handled with regular texture -> swapchain blit */
        }
    } else if(srcSwapchain && This == (IWineD3DSurfaceImpl *) myDevice->render_targets[0]) {
        FIXME("Implement blit from a swapchain to the active render target\n");
        return WINED3DERR_INVALIDCALL;
    }

    if((srcSwapchain || SrcSurface == myDevice->render_targets[0]) && !dstSwapchain) {
        /* Blit from render target to texture */
        WINED3DRECT srect;
        BOOL upsideDown, stretchx;
        BOOL paletteOverride = FALSE;

        if(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE)) {
            TRACE("Color keying not supported by frame buffer to texture blit\n");
            return WINED3DERR_INVALIDCALL;
            /* Destination color key is checked above */
        }

        /* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag
         * glCopyTexSubImage is a bit picky about the parameters we pass to it
         */
        if(SrcRect) {
            if(SrcRect->top < SrcRect->bottom) {
                srect.y1 = SrcRect->top;
                srect.y2 = SrcRect->bottom;
                upsideDown = FALSE;
            } else {
                srect.y1 = SrcRect->bottom;
                srect.y2 = SrcRect->top;
                upsideDown = TRUE;
            }
            srect.x1 = SrcRect->left;
            srect.x2 = SrcRect->right;
        } else {
            srect.x1 = 0;
            srect.y1 = 0;
            srect.x2 = Src->currentDesc.Width;
            srect.y2 = Src->currentDesc.Height;
            upsideDown = FALSE;
        }
        if(rect.x1 > rect.x2) {
            UINT tmp = rect.x2;
            rect.x2 = rect.x1;
            rect.x1 = tmp;
            upsideDown = !upsideDown;
        }

        if(rect.x2 - rect.x1 != srect.x2 - srect.x1) {
            stretchx = TRUE;
        } else {
            stretchx = FALSE;
        }

        /* When blitting from a render target a texture, the texture isn't required to have a palette.
         * In this case grab the palette from the render target. */
        if (This->resource.format_desc->format == WINED3DFMT_P8_UINT && !This->palette)
        {
            paletteOverride = TRUE;
            TRACE("Source surface (%p) lacks palette, overriding palette with palette %p of destination surface (%p)\n", Src, This->palette, This);
            This->palette = Src->palette;
        }

        /* Blt is a pretty powerful call, while glCopyTexSubImage2D is not. glCopyTexSubImage cannot
         * flip the image nor scale it.
         *
         * -> If the app asks for a unscaled, upside down copy, just perform one glCopyTexSubImage2D call
         * -> If the app wants a image width an unscaled width, copy it line per line
         * -> If the app wants a image that is scaled on the x axis, and the destination rectangle is smaller
         *    than the frame buffer, draw an upside down scaled image onto the fb, read it back and restore the
         *    back buffer. This is slower than reading line per line, thus not used for flipping
         * -> If the app wants a scaled image with a dest rect that is bigger than the fb, it has to be copied
         *    pixel by pixel
         *
         * If EXT_framebuffer_blit is supported that can be used instead. Note that EXT_framebuffer_blit implies
         * FBO support, so it doesn't really make sense to try and make it work with different offscreen rendering
         * backends.
         */
        if (wined3d_settings.offscreen_rendering_mode == ORM_FBO
                && myDevice->adapter->gl_info.fbo_ops.glBlitFramebuffer
                && surface_can_stretch_rect(Src, This))
        {
            stretch_rect_fbo((IWineD3DDevice *)myDevice, SrcSurface, &srect,
                    (IWineD3DSurface *)This, &rect, Filter, upsideDown);
        } else if((!stretchx) || rect.x2 - rect.x1 > Src->currentDesc.Width ||
                                    rect.y2 - rect.y1 > Src->currentDesc.Height) {
            TRACE("No stretching in x direction, using direct framebuffer -> texture copy\n");
            fb_copy_to_texture_direct(This, SrcSurface, srcSwapchain, &srect, &rect, upsideDown, Filter);
        } else {
            TRACE("Using hardware stretching to flip / stretch the texture\n");
            fb_copy_to_texture_hwstretch(This, SrcSurface, srcSwapchain, &srect, &rect, upsideDown, Filter);
        }

        /* Clear the palette as the surface didn't have a palette attached, it would confuse GetPalette and other calls */
        if(paletteOverride)
            This->palette = NULL;

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

        return WINED3D_OK;
    } else if(Src) {
        /* Blit from offscreen surface to render target */
        float glTexCoord[4];
        DWORD oldCKeyFlags = Src->CKeyFlags;
        WINEDDCOLORKEY oldBltCKey = Src->SrcBltCKey;
        RECT SourceRectangle;
        BOOL paletteOverride = FALSE;

        TRACE("Blt from surface %p to rendertarget %p\n", Src, This);

        if(SrcRect) {
            SourceRectangle.left = SrcRect->left;
            SourceRectangle.right = SrcRect->right;
            SourceRectangle.top = SrcRect->top;
            SourceRectangle.bottom = SrcRect->bottom;
        } else {
            SourceRectangle.left = 0;
            SourceRectangle.right = Src->currentDesc.Width;
            SourceRectangle.top = 0;
            SourceRectangle.bottom = Src->currentDesc.Height;
        }

        /* When blitting from an offscreen surface to a rendertarget, the source
         * surface is not required to have a palette. Our rendering / conversion
         * code further down the road retrieves the palette from the surface, so
         * it must have a palette set. */
        if (Src->resource.format_desc->format == WINED3DFMT_P8_UINT && !Src->palette)
        {
            paletteOverride = TRUE;
            TRACE("Source surface (%p) lacks palette, overriding palette with palette %p of destination surface (%p)\n", Src, This->palette, This);
            Src->palette = This->palette;
        }

        if (wined3d_settings.offscreen_rendering_mode == ORM_FBO
                && myDevice->adapter->gl_info.fbo_ops.glBlitFramebuffer
                && !(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE))
                && surface_can_stretch_rect(Src, This))
        {
            TRACE("Using stretch_rect_fbo\n");
            /* The source is always a texture, but never the currently active render target, and the texture
             * contents are never upside down
             */
            stretch_rect_fbo((IWineD3DDevice *)myDevice, SrcSurface, (WINED3DRECT *) &SourceRectangle,
                              (IWineD3DSurface *)This, &rect, Filter, FALSE);

            /* Clear the palette as the surface didn't have a palette attached, it would confuse GetPalette and other calls */
            if(paletteOverride)
                Src->palette = NULL;
            return WINED3D_OK;
        }

        if(!CalculateTexRect(Src, &SourceRectangle, glTexCoord)) {
            /* Fall back to software */
            WARN("(%p) Source texture area (%d,%d)-(%d,%d) is too big\n", Src,
                    SourceRectangle.left, SourceRectangle.top,
                    SourceRectangle.right, SourceRectangle.bottom);
            return WINED3DERR_INVALIDCALL;
        }

        /* Color keying: Check if we have to do a color keyed blt,
         * and if not check if a color key is activated.
         *
         * Just modify the color keying parameters in the surface and restore them afterwards
         * The surface keeps track of the color key last used to load the opengl surface.
         * PreLoad will catch the change to the flags and color key and reload if necessary.
         */
        if(Flags & WINEDDBLT_KEYSRC) {
            /* Use color key from surface */
        } else if(Flags & WINEDDBLT_KEYSRCOVERRIDE) {
            /* Use color key from DDBltFx */
            Src->CKeyFlags |= WINEDDSD_CKSRCBLT;
            Src->SrcBltCKey = DDBltFx->ddckSrcColorkey;
        } else {
            /* Do not use color key */
            Src->CKeyFlags &= ~WINEDDSD_CKSRCBLT;
        }

        /* Now load the surface */
        surface_internal_preload((IWineD3DSurface *) Src, SRGB_RGB);

        /* Activate the destination context, set it up for blitting */
        ActivateContext(myDevice, (IWineD3DSurface *) This, CTXUSAGE_BLIT);

        /* The coordinates of the ddraw front buffer are always fullscreen ('screen coordinates',
         * while OpenGL coordinates are window relative.
         * Also beware of the origin difference(top left vs bottom left).
         * Also beware that the front buffer's surface size is screen width x screen height,
         * whereas the real gl drawable size is the size of the window.
         */
        if (dstSwapchain && (IWineD3DSurface *)This == dstSwapchain->frontBuffer) {
            RECT windowsize;
            POINT offset = {0,0};
            UINT h;
            ClientToScreen(dstSwapchain->win_handle, &offset);
            GetClientRect(dstSwapchain->win_handle, &windowsize);
            h = windowsize.bottom - windowsize.top;
            rect.x1 -= offset.x; rect.x2 -=offset.x;
            rect.y1 -= offset.y; rect.y2 -=offset.y;
            rect.y1 += This->currentDesc.Height - h; rect.y2 += This->currentDesc.Height - h;
        }

        if (!is_identity_fixup(This->resource.format_desc->color_fixup))
        {
            FIXME("Destination format %s has a fixup, this is not supported.\n",
                    debug_d3dformat(This->resource.format_desc->format));
            dump_color_fixup_desc(This->resource.format_desc->color_fixup);
        }

        if (!myDevice->blitter->color_fixup_supported(Src->resource.format_desc->color_fixup))
        {
            FIXME("Source format %s has an unsupported fixup:\n",
                    debug_d3dformat(Src->resource.format_desc->format));
            dump_color_fixup_desc(Src->resource.format_desc->color_fixup);
        }

        myDevice->blitter->set_shader((IWineD3DDevice *) myDevice, Src->resource.format_desc,
                Src->texture_target, Src->pow2Width, Src->pow2Height);

        ENTER_GL();

        /* Bind the texture */
        glBindTexture(Src->texture_target, Src->texture_name);
        checkGLcall("glBindTexture");

        /* Filtering for StretchRect */
        glTexParameteri(Src->texture_target, GL_TEXTURE_MAG_FILTER,
                wined3d_gl_mag_filter(magLookup, Filter));
        checkGLcall("glTexParameteri");
        glTexParameteri(Src->texture_target, GL_TEXTURE_MIN_FILTER,
                wined3d_gl_min_mip_filter(minMipLookup, Filter, WINED3DTEXF_NONE));
        checkGLcall("glTexParameteri");
        glTexParameteri(Src->texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP);
        glTexParameteri(Src->texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP);
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
        checkGLcall("glTexEnvi");

        /* This is for color keying */
        if(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE)) {
            glEnable(GL_ALPHA_TEST);
            checkGLcall("glEnable(GL_ALPHA_TEST)");

            /* When the primary render target uses P8, the alpha component contains the palette index.
             * Which means that the colorkey is one of the palette entries. In other cases pixels that
             * should be masked away have alpha set to 0. */
            if(primary_render_target_is_p8(myDevice))
                glAlphaFunc(GL_NOTEQUAL, (float)Src->SrcBltCKey.dwColorSpaceLowValue / 256.0f);
            else
                glAlphaFunc(GL_NOTEQUAL, 0.0f);
            checkGLcall("glAlphaFunc");
        } else {
            glDisable(GL_ALPHA_TEST);
            checkGLcall("glDisable(GL_ALPHA_TEST)");
        }

        /* Draw a textured quad
         */
        glBegin(GL_QUADS);

        glColor3f(1.0f, 1.0f, 1.0f);
        glTexCoord2f(glTexCoord[0], glTexCoord[2]);
        glVertex3f(rect.x1, rect.y1, 0.0f);

        glTexCoord2f(glTexCoord[0], glTexCoord[3]);
        glVertex3f(rect.x1, rect.y2, 0.0f);

        glTexCoord2f(glTexCoord[1], glTexCoord[3]);
        glVertex3f(rect.x2, rect.y2, 0.0f);

        glTexCoord2f(glTexCoord[1], glTexCoord[2]);
        glVertex3f(rect.x2, rect.y1, 0.0f);

        glEnd();
        checkGLcall("glEnd");

        if(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE)) {
            glDisable(GL_ALPHA_TEST);
            checkGLcall("glDisable(GL_ALPHA_TEST)");
        }

        glBindTexture(Src->texture_target, 0);
        checkGLcall("glBindTexture(Src->texture_target, 0)");

        /* Restore the color key parameters */
        Src->CKeyFlags = oldCKeyFlags;
        Src->SrcBltCKey = oldBltCKey;

        /* Clear the palette as the surface didn't have a palette attached, it would confuse GetPalette and other calls */
        if(paletteOverride)
            Src->palette = NULL;

        LEAVE_GL();

        /* Leave the opengl state valid for blitting */
        myDevice->blitter->unset_shader((IWineD3DDevice *) myDevice);

        /* Flush in case the drawable is used by multiple GL contexts */
        if(dstSwapchain && (This == (IWineD3DSurfaceImpl *) dstSwapchain->frontBuffer || dstSwapchain->num_contexts >= 2))
            wglFlush();

        /* TODO: If the surface is locked often, perform the Blt in software on the memory instead */
        /* The surface is now in the drawable. On onscreen surfaces or without fbos the texture
         * is outdated now
         */
        IWineD3DSurface_ModifyLocation((IWineD3DSurface *) This, SFLAG_INDRAWABLE, TRUE);

        return WINED3D_OK;
    } else {
        /* Source-Less Blit to render target */
        if (Flags & WINEDDBLT_COLORFILL) {
            /* This is easy to handle for the D3D Device... */
            DWORD color;

            TRACE("Colorfill\n");

            /* This == (IWineD3DSurfaceImpl *) myDevice->render_targets[0] || dstSwapchain
                must be true if we are here */
            if (This != (IWineD3DSurfaceImpl *) myDevice->render_targets[0] &&
                    !(This == (IWineD3DSurfaceImpl*) dstSwapchain->frontBuffer ||
                      (dstSwapchain->backBuffer && This == (IWineD3DSurfaceImpl*) dstSwapchain->backBuffer[0]))) {
                TRACE("Surface is higher back buffer, falling back to software\n");
                return WINED3DERR_INVALIDCALL;
            }

            /* The color as given in the Blt function is in the format of the frame-buffer...
             * 'clear' expect it in ARGB format => we need to do some conversion :-)
             */
            if (This->resource.format_desc->format == WINED3DFMT_P8_UINT)
            {
                DWORD alpha;

                if (primary_render_target_is_p8(myDevice)) alpha = DDBltFx->u5.dwFillColor << 24;
                else alpha = 0xFF000000;

                if (This->palette) {
                    color = (alpha |
                            (This->palette->palents[DDBltFx->u5.dwFillColor].peRed << 16) |
                            (This->palette->palents[DDBltFx->u5.dwFillColor].peGreen << 8) |
                            (This->palette->palents[DDBltFx->u5.dwFillColor].peBlue));
                } else {
                    color = alpha;
                }
            }
            else if (This->resource.format_desc->format == WINED3DFMT_B5G6R5_UNORM)
            {
                if (DDBltFx->u5.dwFillColor == 0xFFFF) {
                    color = 0xFFFFFFFF;
                } else {
                    color = ((0xFF000000) |
                            ((DDBltFx->u5.dwFillColor & 0xF800) << 8) |
                            ((DDBltFx->u5.dwFillColor & 0x07E0) << 5) |
                            ((DDBltFx->u5.dwFillColor & 0x001F) << 3));
                }
            }
            else if (This->resource.format_desc->format == WINED3DFMT_B8G8R8_UNORM
                    || This->resource.format_desc->format == WINED3DFMT_B8G8R8X8_UNORM)
            {
                color = 0xFF000000 | DDBltFx->u5.dwFillColor;
            }
            else if (This->resource.format_desc->format == WINED3DFMT_B8G8R8A8_UNORM)
            {
                color = DDBltFx->u5.dwFillColor;
            }
            else {
                ERR("Wrong surface type for BLT override(Format doesn't match) !\n");
                return WINED3DERR_INVALIDCALL;
            }

            TRACE("(%p) executing Render Target override, color = %x\n", This, color);
            IWineD3DDeviceImpl_ClearSurface(myDevice, This, 1 /* Number of rectangles */,
                    &rect, WINED3DCLEAR_TARGET, color, 0.0f /* Z */, 0 /* Stencil */);
            return WINED3D_OK;
        }
    }

    /* Default: Fall back to the generic blt. Not an error, a TRACE is enough */
    TRACE("Didn't find any usable render target setup for hw blit, falling back to software\n");
    return WINED3DERR_INVALIDCALL;
}

static HRESULT IWineD3DSurfaceImpl_BltZ(IWineD3DSurfaceImpl *This, const RECT *DestRect,
        IWineD3DSurface *SrcSurface, const RECT *SrcRect, DWORD Flags, const WINEDDBLTFX *DDBltFx)
{
    IWineD3DDeviceImpl *myDevice = This->resource.wineD3DDevice;
    float depth;

    if (Flags & WINEDDBLT_DEPTHFILL) {
        switch(This->resource.format_desc->format)
        {
            case WINED3DFMT_D16_UNORM:
                depth = (float) DDBltFx->u5.dwFillDepth / (float) 0x0000ffff;
                break;
            case WINED3DFMT_S1_UINT_D15_UNORM:
                depth = (float) DDBltFx->u5.dwFillDepth / (float) 0x0000fffe;
                break;
            case WINED3DFMT_S8_UINT_D24_UNORM:
            case WINED3DFMT_X8D24_UNORM:
                depth = (float) DDBltFx->u5.dwFillDepth / (float) 0x00ffffff;
                break;
            case WINED3DFMT_D32_UNORM:
                depth = (float) DDBltFx->u5.dwFillDepth / (float) 0xffffffff;
                break;
            default:
                depth = 0.0f;
                ERR("Unexpected format for depth fill: %s\n", debug_d3dformat(This->resource.format_desc->format));
        }

        return IWineD3DDevice_Clear((IWineD3DDevice *) myDevice,
                                    DestRect == NULL ? 0 : 1,
                                    (const WINED3DRECT *)DestRect,
                                    WINED3DCLEAR_ZBUFFER,
                                    0x00000000,
                                    depth,
                                    0x00000000);
    }

    FIXME("(%p): Unsupp depthstencil blit\n", This);
    return WINED3DERR_INVALIDCALL;
}

static HRESULT WINAPI IWineD3DSurfaceImpl_Blt(IWineD3DSurface *iface, const RECT *DestRect, IWineD3DSurface *SrcSurface,
        const RECT *SrcRect, DWORD Flags, const WINEDDBLTFX *DDBltFx, WINED3DTEXTUREFILTERTYPE Filter) {
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
    IWineD3DSurfaceImpl *Src = (IWineD3DSurfaceImpl *) SrcSurface;
    IWineD3DDeviceImpl *myDevice = This->resource.wineD3DDevice;
    TRACE("(%p)->(%p,%p,%p,%x,%p)\n", This, DestRect, SrcSurface, SrcRect, Flags, DDBltFx);
    TRACE("(%p): Usage is %s\n", This, debug_d3dusage(This->resource.usage));

    if ( (This->Flags & SFLAG_LOCKED) || ((Src != NULL) && (Src->Flags & SFLAG_LOCKED)))
    {
        WARN(" Surface is busy, returning DDERR_SURFACEBUSY\n");
        return WINEDDERR_SURFACEBUSY;
    }

    /* Accessing the depth stencil is supposed to fail between a BeginScene and EndScene pair,
     * except depth blits, which seem to work
     */
    if(iface == myDevice->stencilBufferTarget || (SrcSurface && SrcSurface == myDevice->stencilBufferTarget)) {
        if(myDevice->inScene && !(Flags & WINEDDBLT_DEPTHFILL)) {
            TRACE("Attempt to access the depth stencil surface in a BeginScene / EndScene pair, returning WINED3DERR_INVALIDCALL\n");
            return WINED3DERR_INVALIDCALL;
        } else if(IWineD3DSurfaceImpl_BltZ(This, DestRect, SrcSurface, SrcRect, Flags, DDBltFx) == WINED3D_OK) {
            TRACE("Z Blit override handled the blit\n");
            return WINED3D_OK;
        }
    }

    /* Special cases for RenderTargets */
    if( (This->resource.usage & WINED3DUSAGE_RENDERTARGET) ||
        ( Src && (Src->resource.usage & WINED3DUSAGE_RENDERTARGET) )) {
        if(IWineD3DSurfaceImpl_BltOverride(This, DestRect, SrcSurface, SrcRect, Flags, DDBltFx, Filter) == WINED3D_OK) return WINED3D_OK;
    }

    /* For the rest call the X11 surface implementation.
     * For RenderTargets this should be implemented OpenGL accelerated in BltOverride,
     * other Blts are rather rare
     */
    return IWineD3DBaseSurfaceImpl_Blt(iface, DestRect, SrcSurface, SrcRect, Flags, DDBltFx, Filter);
}

static HRESULT WINAPI IWineD3DSurfaceImpl_BltFast(IWineD3DSurface *iface, DWORD dstx, DWORD dsty,
        IWineD3DSurface *Source, const RECT *rsrc, DWORD trans)
{
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
    IWineD3DSurfaceImpl *srcImpl = (IWineD3DSurfaceImpl *) Source;
    IWineD3DDeviceImpl *myDevice = This->resource.wineD3DDevice;
    TRACE("(%p)->(%d, %d, %p, %p, %08x\n", iface, dstx, dsty, Source, rsrc, trans);

    if ( (This->Flags & SFLAG_LOCKED) || ((srcImpl != NULL) && (srcImpl->Flags & SFLAG_LOCKED)))
    {
        WARN(" Surface is busy, returning DDERR_SURFACEBUSY\n");
        return WINEDDERR_SURFACEBUSY;
    }

    if(myDevice->inScene &&
       (iface == myDevice->stencilBufferTarget ||
       (Source && Source == myDevice->stencilBufferTarget))) {
        TRACE("Attempt to access the depth stencil surface in a BeginScene / EndScene pair, returning WINED3DERR_INVALIDCALL\n");
        return WINED3DERR_INVALIDCALL;
    }

    /* Special cases for RenderTargets */
    if( (This->resource.usage & WINED3DUSAGE_RENDERTARGET) ||
        ( srcImpl && (srcImpl->resource.usage & WINED3DUSAGE_RENDERTARGET) )) {

        RECT SrcRect, DstRect;
        DWORD Flags=0;

        if(rsrc) {
            SrcRect.left = rsrc->left;
            SrcRect.top= rsrc->top;
            SrcRect.bottom = rsrc->bottom;
            SrcRect.right = rsrc->right;
        } else {
            SrcRect.left = 0;
            SrcRect.top = 0;
            SrcRect.right = srcImpl->currentDesc.Width;
            SrcRect.bottom = srcImpl->currentDesc.Height;
        }

        DstRect.left = dstx;
        DstRect.top=dsty;
        DstRect.right = dstx + SrcRect.right - SrcRect.left;
        DstRect.bottom = dsty + SrcRect.bottom - SrcRect.top;

        /* Convert BltFast flags into Btl ones because it is called from SurfaceImpl_Blt as well */
        if(trans & WINEDDBLTFAST_SRCCOLORKEY)
            Flags |= WINEDDBLT_KEYSRC;
        if(trans & WINEDDBLTFAST_DESTCOLORKEY)
            Flags |= WINEDDBLT_KEYDEST;
        if(trans & WINEDDBLTFAST_WAIT)
            Flags |= WINEDDBLT_WAIT;
        if(trans & WINEDDBLTFAST_DONOTWAIT)
            Flags |= WINEDDBLT_DONOTWAIT;

        if(IWineD3DSurfaceImpl_BltOverride(This, &DstRect, Source, &SrcRect, Flags, NULL, WINED3DTEXF_POINT) == WINED3D_OK) return WINED3D_OK;
    }


    return IWineD3DBaseSurfaceImpl_BltFast(iface, dstx, dsty, Source, rsrc, trans);
}

static HRESULT WINAPI IWineD3DSurfaceImpl_RealizePalette(IWineD3DSurface *iface)
{
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
    RGBQUAD col[256];
    IWineD3DPaletteImpl *pal = This->palette;
    unsigned int n;
    TRACE("(%p)\n", This);

    if (!pal) return WINED3D_OK;

    if (This->resource.format_desc->format == WINED3DFMT_P8_UINT
            || This->resource.format_desc->format == WINED3DFMT_P8_UINT_A8_UNORM)
    {
        int bpp;
        GLenum format, internal, type;
        CONVERT_TYPES convert;

        /* Check if we are using a RTL mode which uses texturing for uploads */
        BOOL use_texture = (wined3d_settings.rendertargetlock_mode == RTL_READTEX);

        /* Check if we have hardware palette conversion if we have convert is set to NO_CONVERSION */
        d3dfmt_get_conv(This, TRUE, use_texture, &format, &internal, &type, &convert, &bpp, FALSE);

        if((This->resource.usage & WINED3DUSAGE_RENDERTARGET) && (convert == NO_CONVERSION))
        {
            IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;

            /* Make sure the texture is up to date. This call doesn't do anything if the texture is already up to date. */
            IWineD3DSurface_LoadLocation(iface, SFLAG_INTEXTURE, NULL);

            /* We want to force a palette refresh, so mark the drawable as not being up to date */
            IWineD3DSurface_ModifyLocation(iface, SFLAG_INDRAWABLE, FALSE);

            /* Re-upload the palette */
            ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
            d3dfmt_p8_upload_palette(iface, convert);
        } else {
            if(!(This->Flags & SFLAG_INSYSMEM)) {
                TRACE("Palette changed with surface that does not have an up to date system memory copy\n");
                IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, NULL);
            }
            TRACE("Dirtifying surface\n");
            IWineD3DSurface_ModifyLocation(iface, SFLAG_INSYSMEM, TRUE);
        }
    }

    if(This->Flags & SFLAG_DIBSECTION) {
        TRACE("(%p): Updating the hdc's palette\n", This);
        for (n=0; n<256; n++) {
            col[n].rgbRed   = pal->palents[n].peRed;
            col[n].rgbGreen = pal->palents[n].peGreen;
            col[n].rgbBlue  = pal->palents[n].peBlue;
            col[n].rgbReserved = 0;
        }
        SetDIBColorTable(This->hDC, 0, 256, col);
    }

    /* Propagate the changes to the drawable when we have a palette. */
    if(This->resource.usage & WINED3DUSAGE_RENDERTARGET)
        IWineD3DSurface_LoadLocation(iface, SFLAG_INDRAWABLE, NULL);

    return WINED3D_OK;
}

static HRESULT WINAPI IWineD3DSurfaceImpl_PrivateSetup(IWineD3DSurface *iface) {
    /** Check against the maximum texture sizes supported by the video card **/
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
    unsigned int pow2Width, pow2Height;

    This->texture_name = 0;
    This->texture_target = GL_TEXTURE_2D;

    /* Non-power2 support */
    if (GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO) || GL_SUPPORT(WINE_NORMALIZED_TEXRECT)) {
        pow2Width = This->currentDesc.Width;
        pow2Height = This->currentDesc.Height;
    } else {
        /* Find the nearest pow2 match */
        pow2Width = pow2Height = 1;
        while (pow2Width < This->currentDesc.Width) pow2Width <<= 1;
        while (pow2Height < This->currentDesc.Height) pow2Height <<= 1;
    }
    This->pow2Width  = pow2Width;
    This->pow2Height = pow2Height;

    if (pow2Width > This->currentDesc.Width || pow2Height > This->currentDesc.Height) {
        /** TODO: add support for non power two compressed textures **/
        if (This->resource.format_desc->Flags & WINED3DFMT_FLAG_COMPRESSED)
        {
            FIXME("(%p) Compressed non-power-two textures are not supported w(%d) h(%d)\n",
                  This, This->currentDesc.Width, This->currentDesc.Height);
            return WINED3DERR_NOTAVAILABLE;
        }
    }

    if(pow2Width != This->currentDesc.Width ||
       pow2Height != This->currentDesc.Height) {
        This->Flags |= SFLAG_NONPOW2;
    }

    TRACE("%p\n", This);
    if ((This->pow2Width > GL_LIMITS(texture_size) || This->pow2Height > GL_LIMITS(texture_size)) && !(This->resource.usage & (WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_DEPTHSTENCIL))) {
        /* one of three options
        1: Do the same as we do with nonpow 2 and scale the texture, (any texture ops would require the texture to be scaled which is potentially slow)
        2: Set the texture to the maximum size (bad idea)
        3:    WARN and return WINED3DERR_NOTAVAILABLE;
        4: Create the surface, but allow it to be used only for DirectDraw Blts. Some apps(e.g. Swat 3) create textures with a Height of 16 and a Width > 3000 and blt 16x16 letter areas from them to the render target.
        */
        WARN("(%p) Creating an oversized surface: %ux%u (texture is %ux%u)\n",
             This, This->pow2Width, This->pow2Height, This->currentDesc.Width, This->currentDesc.Height);
        This->Flags |= SFLAG_OVERSIZE;

        /* This will be initialized on the first blt */
        This->glRect.left = 0;
        This->glRect.top = 0;
        This->glRect.right = 0;
        This->glRect.bottom = 0;
    } else {
        /* Check this after the oversize check - do not make an oversized surface a texture_rectangle one.
           Second also don't use ARB_TEXTURE_RECTANGLE in case the surface format is P8 and EXT_PALETTED_TEXTURE
           is used in combination with texture uploads (RTL_READTEX/RTL_TEXTEX). The reason is that EXT_PALETTED_TEXTURE
           doesn't work in combination with ARB_TEXTURE_RECTANGLE.
        */
        if (This->Flags & SFLAG_NONPOW2 && GL_SUPPORT(ARB_TEXTURE_RECTANGLE)
                && !(This->resource.format_desc->format == WINED3DFMT_P8_UINT && GL_SUPPORT(EXT_PALETTED_TEXTURE)
                && wined3d_settings.rendertargetlock_mode == RTL_READTEX))
        {
            This->texture_target = GL_TEXTURE_RECTANGLE_ARB;
            This->pow2Width  = This->currentDesc.Width;
            This->pow2Height = This->currentDesc.Height;
            This->Flags &= ~(SFLAG_NONPOW2 | SFLAG_NORMCOORD);
        }

        /* No oversize, gl rect is the full texture size */
        This->Flags &= ~SFLAG_OVERSIZE;
        This->glRect.left = 0;
        This->glRect.top = 0;
        This->glRect.right = This->pow2Width;
        This->glRect.bottom = This->pow2Height;
    }

    if(This->resource.usage & WINED3DUSAGE_RENDERTARGET) {
        switch(wined3d_settings.offscreen_rendering_mode) {
            case ORM_FBO:        This->get_drawable_size = get_drawable_size_fbo;        break;
            case ORM_PBUFFER:    This->get_drawable_size = get_drawable_size_pbuffer;    break;
            case ORM_BACKBUFFER: This->get_drawable_size = get_drawable_size_backbuffer; break;
        }
    }

    This->Flags |= SFLAG_INSYSMEM;

    return WINED3D_OK;
}

struct depth_blt_info
{
    GLenum binding;
    GLenum bind_target;
    enum tex_types tex_type;
    GLfloat coords[4][3];
};

static void surface_get_depth_blt_info(GLenum target, GLsizei w, GLsizei h, struct depth_blt_info *info)
{
    GLfloat (*coords)[3] = info->coords;

    switch (target)
    {
        default:
            FIXME("Unsupported texture target %#x\n", target);
            /* Fall back to GL_TEXTURE_2D */
        case GL_TEXTURE_2D:
            info->binding = GL_TEXTURE_BINDING_2D;
            info->bind_target = GL_TEXTURE_2D;
            info->tex_type = tex_2d;
            coords[0][0] = 0.0f;    coords[0][1] = 1.0f;    coords[0][2] = 0.0f;
            coords[1][0] = 1.0f;    coords[1][1] = 1.0f;    coords[1][2] = 0.0f;
            coords[2][0] = 0.0f;    coords[2][1] = 0.0f;    coords[2][2] = 0.0f;
            coords[3][0] = 1.0f;    coords[3][1] = 0.0f;    coords[3][2] = 0.0f;
            break;

        case GL_TEXTURE_RECTANGLE_ARB:
            info->binding = GL_TEXTURE_BINDING_RECTANGLE_ARB;
            info->bind_target = GL_TEXTURE_RECTANGLE_ARB;
            info->tex_type = tex_rect;
            coords[0][0] = 0.0f;    coords[0][1] = h;       coords[0][2] = 0.0f;
            coords[1][0] = w;       coords[1][1] = h;       coords[1][2] = 0.0f;
            coords[2][0] = 0.0f;    coords[2][1] = 0.0f;    coords[2][2] = 0.0f;
            coords[3][0] = w;       coords[3][1] = 0.0f;    coords[3][2] = 0.0f;
            break;

        case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
            info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB;
            info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
            info->tex_type = tex_cube;
            coords[0][0] =  1.0f;   coords[0][1] = -1.0f;   coords[0][2] =  1.0f;
            coords[1][0] =  1.0f;   coords[1][1] = -1.0f;   coords[1][2] = -1.0f;
            coords[2][0] =  1.0f;   coords[2][1] =  1.0f;   coords[2][2] =  1.0f;
            coords[3][0] =  1.0f;   coords[3][1] =  1.0f;   coords[3][2] = -1.0f;

        case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
            info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB;
            info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
            info->tex_type = tex_cube;
            coords[0][0] = -1.0f;   coords[0][1] = -1.0f;   coords[0][2] = -1.0f;
            coords[1][0] = -1.0f;   coords[1][1] = -1.0f;   coords[1][2] =  1.0f;
            coords[2][0] = -1.0f;   coords[2][1] =  1.0f;   coords[2][2] = -1.0f;
            coords[3][0] = -1.0f;   coords[3][1] =  1.0f;   coords[3][2] =  1.0f;

        case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
            info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB;
            info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
            info->tex_type = tex_cube;
            coords[0][0] = -1.0f;   coords[0][1] =  1.0f;   coords[0][2] =  1.0f;
            coords[1][0] =  1.0f;   coords[1][1] =  1.0f;   coords[1][2] =  1.0f;
            coords[2][0] = -1.0f;   coords[2][1] =  1.0f;   coords[2][2] = -1.0f;
            coords[3][0] =  1.0f;   coords[3][1] =  1.0f;   coords[3][2] = -1.0f;

        case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
            info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB;
            info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
            info->tex_type = tex_cube;
            coords[0][0] = -1.0f;   coords[0][1] = -1.0f;   coords[0][2] = -1.0f;
            coords[1][0] =  1.0f;   coords[1][1] = -1.0f;   coords[1][2] = -1.0f;
            coords[2][0] = -1.0f;   coords[2][1] = -1.0f;   coords[2][2] =  1.0f;
            coords[3][0] =  1.0f;   coords[3][1] = -1.0f;   coords[3][2] =  1.0f;

        case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
            info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB;
            info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
            info->tex_type = tex_cube;
            coords[0][0] = -1.0f;   coords[0][1] = -1.0f;   coords[0][2] =  1.0f;
            coords[1][0] =  1.0f;   coords[1][1] = -1.0f;   coords[1][2] =  1.0f;
            coords[2][0] = -1.0f;   coords[2][1] =  1.0f;   coords[2][2] =  1.0f;
            coords[3][0] =  1.0f;   coords[3][1] =  1.0f;   coords[3][2] =  1.0f;

        case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
            info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB;
            info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
            info->tex_type = tex_cube;
            coords[0][0] =  1.0f;   coords[0][1] = -1.0f;   coords[0][2] = -1.0f;
            coords[1][0] = -1.0f;   coords[1][1] = -1.0f;   coords[1][2] = -1.0f;
            coords[2][0] =  1.0f;   coords[2][1] =  1.0f;   coords[2][2] = -1.0f;
            coords[3][0] = -1.0f;   coords[3][1] =  1.0f;   coords[3][2] = -1.0f;
    }
}

/* GL locking is done by the caller */
static void surface_depth_blt(IWineD3DSurfaceImpl *This, GLuint texture, GLsizei w, GLsizei h, GLenum target)
{
    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
    struct depth_blt_info info;
    GLint old_binding = 0;

    glPushAttrib(GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_VIEWPORT_BIT);

    glDisable(GL_CULL_FACE);
    glDisable(GL_BLEND);
    glDisable(GL_ALPHA_TEST);
    glDisable(GL_SCISSOR_TEST);
    glDisable(GL_STENCIL_TEST);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_ALWAYS);
    glDepthMask(GL_TRUE);
    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
    glViewport(0, 0, w, h);

    surface_get_depth_blt_info(target, w, h, &info);
    GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB));
    glGetIntegerv(info.binding, &old_binding);
    glBindTexture(info.bind_target, texture);

    device->shader_backend->shader_select_depth_blt((IWineD3DDevice *)device, info.tex_type);

    glBegin(GL_TRIANGLE_STRIP);
    glTexCoord3fv(info.coords[0]);
    glVertex2f(-1.0f, -1.0f);
    glTexCoord3fv(info.coords[1]);
    glVertex2f(1.0f, -1.0f);
    glTexCoord3fv(info.coords[2]);
    glVertex2f(-1.0f, 1.0f);
    glTexCoord3fv(info.coords[3]);
    glVertex2f(1.0f, 1.0f);
    glEnd();

    glBindTexture(info.bind_target, old_binding);

    glPopAttrib();

    device->shader_backend->shader_deselect_depth_blt((IWineD3DDevice *)device);
}

void surface_modify_ds_location(IWineD3DSurface *iface, DWORD location) {
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;

    TRACE("(%p) New location %#x\n", This, location);

    if (location & ~SFLAG_DS_LOCATIONS) {
        FIXME("(%p) Invalid location (%#x) specified\n", This, location);
    }

    This->Flags &= ~SFLAG_DS_LOCATIONS;
    This->Flags |= location;
}

/* Context activation is done by the caller. */
void surface_load_ds_location(IWineD3DSurface *iface, struct wined3d_context *context, DWORD location)
{
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
    const struct wined3d_gl_info *gl_info = context->gl_info;

    TRACE("(%p) New location %#x\n", This, location);

    /* TODO: Make this work for modes other than FBO */
    if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) return;

    if (This->Flags & location) {
        TRACE("(%p) Location (%#x) is already up to date\n", This, location);
        return;
    }

    if (This->current_renderbuffer) {
        FIXME("(%p) Not supported with fixed up depth stencil\n", This);
        return;
    }

    if (location == SFLAG_DS_OFFSCREEN) {
        if (This->Flags & SFLAG_DS_ONSCREEN) {
            GLint old_binding = 0;
            GLenum bind_target;

            TRACE("(%p) Copying onscreen depth buffer to depth texture\n", This);

            ENTER_GL();

            if (!device->depth_blt_texture) {
                glGenTextures(1, &device->depth_blt_texture);
            }

            /* Note that we use depth_blt here as well, rather than glCopyTexImage2D
             * directly on the FBO texture. That's because we need to flip. */
            context_bind_fbo(context, GL_FRAMEBUFFER, NULL);
            if (This->texture_target == GL_TEXTURE_RECTANGLE_ARB)
            {
                glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding);
                bind_target = GL_TEXTURE_RECTANGLE_ARB;
            } else {
                glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_binding);
                bind_target = GL_TEXTURE_2D;
            }
            glBindTexture(bind_target, device->depth_blt_texture);
            glCopyTexImage2D(bind_target, This->texture_level, This->resource.format_desc->glInternal,
                    0, 0, This->currentDesc.Width, This->currentDesc.Height, 0);
            glTexParameteri(bind_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            glTexParameteri(bind_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
            glTexParameteri(bind_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
            glTexParameteri(bind_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
            glTexParameteri(bind_target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
            glTexParameteri(bind_target, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
            glBindTexture(bind_target, old_binding);

            /* Setup the destination */
            if (!device->depth_blt_rb) {
                gl_info->fbo_ops.glGenRenderbuffers(1, &device->depth_blt_rb);
                checkGLcall("glGenRenderbuffersEXT");
            }
            if (device->depth_blt_rb_w != This->currentDesc.Width
                    || device->depth_blt_rb_h != This->currentDesc.Height) {
                gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, device->depth_blt_rb);
                checkGLcall("glBindRenderbufferEXT");
                gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8,
                        This->currentDesc.Width, This->currentDesc.Height);
                checkGLcall("glRenderbufferStorageEXT");
                device->depth_blt_rb_w = This->currentDesc.Width;
                device->depth_blt_rb_h = This->currentDesc.Height;
            }

            context_bind_fbo(context, GL_FRAMEBUFFER, &context->dst_fbo);
            gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER,
                    GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, device->depth_blt_rb);
            checkGLcall("glFramebufferRenderbufferEXT");
            context_attach_depth_stencil_fbo(context, GL_FRAMEBUFFER, iface, FALSE);

            /* Do the actual blit */
            surface_depth_blt(This, device->depth_blt_texture, This->currentDesc.Width, This->currentDesc.Height, bind_target);
            checkGLcall("depth_blt");

            if (context->current_fbo) context_bind_fbo(context, GL_FRAMEBUFFER, &context->current_fbo->id);
            else context_bind_fbo(context, GL_FRAMEBUFFER, NULL);

            LEAVE_GL();
        } else {
            FIXME("No up to date depth stencil location\n");
        }
    } else if (location == SFLAG_DS_ONSCREEN) {
        if (This->Flags & SFLAG_DS_OFFSCREEN) {
            TRACE("(%p) Copying depth texture to onscreen depth buffer\n", This);

            ENTER_GL();

            context_bind_fbo(context, GL_FRAMEBUFFER, NULL);
            surface_depth_blt(This, This->texture_name, This->currentDesc.Width,
                    This->currentDesc.Height, This->texture_target);
            checkGLcall("depth_blt");

            if (context->current_fbo) context_bind_fbo(context, GL_FRAMEBUFFER, &context->current_fbo->id);

            LEAVE_GL();
        } else {
            FIXME("No up to date depth stencil location\n");
        }
    } else {
        ERR("(%p) Invalid location (%#x) specified\n", This, location);
    }

    This->Flags |= location;
}

static void WINAPI IWineD3DSurfaceImpl_ModifyLocation(IWineD3DSurface *iface, DWORD flag, BOOL persistent) {
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
    IWineD3DBaseTexture *texture;
    IWineD3DSurfaceImpl *overlay;

    TRACE("(%p)->(%s, %s)\n", iface, debug_surflocation(flag),
          persistent ? "TRUE" : "FALSE");

    if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
        if (This->Flags & SFLAG_SWAPCHAIN)
        {
            TRACE("Surface %p is an onscreen surface\n", iface);
        } else {
            /* With ORM_FBO, SFLAG_INTEXTURE and SFLAG_INDRAWABLE are the same for offscreen targets. */
            if (flag & (SFLAG_INTEXTURE | SFLAG_INDRAWABLE)) flag |= (SFLAG_INTEXTURE | SFLAG_INDRAWABLE);
        }
    }

    if(persistent) {
        if(((This->Flags & SFLAG_INTEXTURE) && !(flag & SFLAG_INTEXTURE)) ||
           ((This->Flags & SFLAG_INSRGBTEX) && !(flag & SFLAG_INSRGBTEX))) {
            if (IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&texture) == WINED3D_OK) {
                TRACE("Passing to container\n");
                IWineD3DBaseTexture_SetDirty(texture, TRUE);
                IWineD3DBaseTexture_Release(texture);
            }
        }
        This->Flags &= ~SFLAG_LOCATIONS;
        This->Flags |= flag;

        /* Redraw emulated overlays, if any */
        if(flag & SFLAG_INDRAWABLE && !list_empty(&This->overlays)) {
            LIST_FOR_EACH_ENTRY(overlay, &This->overlays, IWineD3DSurfaceImpl, overlay_entry) {
                IWineD3DSurface_DrawOverlay((IWineD3DSurface *) overlay);
            }
        }
    } else {
        if((This->Flags & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX)) && (flag & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX))) {
            if (IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&texture) == WINED3D_OK) {
                TRACE("Passing to container\n");
                IWineD3DBaseTexture_SetDirty(texture, TRUE);
                IWineD3DBaseTexture_Release(texture);
            }
        }
        This->Flags &= ~flag;
    }

    if(!(This->Flags & SFLAG_LOCATIONS)) {
        ERR("%p: Surface does not have any up to date location\n", This);
    }
}

struct coords {
    GLfloat x, y, z;
};

struct float_rect
{
    float l;
    float t;
    float r;
    float b;
};

static inline void cube_coords_float(const RECT *r, UINT w, UINT h, struct float_rect *f)
{
    f->l = ((r->left * 2.0f) / w) - 1.0f;
    f->t = ((r->top * 2.0f) / h) - 1.0f;
    f->r = ((r->right * 2.0f) / w) - 1.0f;
    f->b = ((r->bottom * 2.0f) / h) - 1.0f;
}

static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This, const RECT *rect_in)
{
    const struct wined3d_context *context;
    struct coords coords[4];
    RECT rect;
    IWineD3DSwapChain *swapchain;
    IWineD3DBaseTexture *texture;
    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
    GLenum bind_target;
    struct float_rect f;

    if(rect_in) {
        rect = *rect_in;
    } else {
        rect.left = 0;
        rect.top = 0;
        rect.right = This->currentDesc.Width;
        rect.bottom = This->currentDesc.Height;
    }

    switch (This->texture_target)
    {
        case GL_TEXTURE_2D:
            bind_target = GL_TEXTURE_2D;

            coords[0].x = (float)rect.left / This->pow2Width;
            coords[0].y = (float)rect.top / This->pow2Height;
            coords[0].z = 0;

            coords[1].x = (float)rect.left / This->pow2Width;
            coords[1].y = (float)rect.bottom / This->pow2Height;
            coords[1].z = 0;

            coords[2].x = (float)rect.right / This->pow2Width;
            coords[2].y = (float)rect.bottom / This->pow2Height;
            coords[2].z = 0;

            coords[3].x = (float)rect.right / This->pow2Width;
            coords[3].y = (float)rect.top / This->pow2Height;
            coords[3].z = 0;
            break;

        case GL_TEXTURE_RECTANGLE_ARB:
            bind_target = GL_TEXTURE_RECTANGLE_ARB;
            coords[0].x = rect.left;    coords[0].y = rect.top;     coords[0].z = 0;
            coords[1].x = rect.left;    coords[1].y = rect.bottom;  coords[1].z = 0;
            coords[2].x = rect.right;   coords[2].y = rect.bottom;  coords[2].z = 0;
            coords[3].x = rect.right;   coords[3].y = rect.top;     coords[3].z = 0;
            break;

        case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
            bind_target = GL_TEXTURE_CUBE_MAP_ARB;
            cube_coords_float(&rect, This->pow2Width, This->pow2Height, &f);
            coords[0].x =    1; coords[0].y = -f.t; coords[0].z = -f.l;
            coords[1].x =    1; coords[1].y = -f.b; coords[1].z = -f.l;
            coords[2].x =    1; coords[2].y = -f.b; coords[2].z = -f.r;
            coords[3].x =    1; coords[3].y = -f.t; coords[3].z = -f.r;
            break;

        case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
            bind_target = GL_TEXTURE_CUBE_MAP_ARB;
            cube_coords_float(&rect, This->pow2Width, This->pow2Height, &f);
            coords[0].x =   -1; coords[0].y = -f.t; coords[0].z =  f.l;
            coords[1].x =   -1; coords[1].y = -f.b; coords[1].z =  f.l;
            coords[2].x =   -1; coords[2].y = -f.b; coords[2].z =  f.r;
            coords[3].x =   -1; coords[3].y = -f.t; coords[3].z =  f.r;
            break;

        case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
            bind_target = GL_TEXTURE_CUBE_MAP_ARB;
            cube_coords_float(&rect, This->pow2Width, This->pow2Height, &f);
            coords[0].x =  f.l; coords[0].y =    1; coords[0].z =  f.t;
            coords[1].x =  f.l; coords[1].y =    1; coords[1].z =  f.b;
            coords[2].x =  f.r; coords[2].y =    1; coords[2].z =  f.b;
            coords[3].x =  f.r; coords[3].y =    1; coords[3].z =  f.t;
            break;

        case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
            bind_target = GL_TEXTURE_CUBE_MAP_ARB;
            cube_coords_float(&rect, This->pow2Width, This->pow2Height, &f);
            coords[0].x =  f.l; coords[0].y =   -1; coords[0].z = -f.t;
            coords[1].x =  f.l; coords[1].y =   -1; coords[1].z = -f.b;
            coords[2].x =  f.r; coords[2].y =   -1; coords[2].z = -f.b;
            coords[3].x =  f.r; coords[3].y =   -1; coords[3].z = -f.t;
            break;

        case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
            bind_target = GL_TEXTURE_CUBE_MAP_ARB;
            cube_coords_float(&rect, This->pow2Width, This->pow2Height, &f);
            coords[0].x =  f.l; coords[0].y = -f.t; coords[0].z =    1;
            coords[1].x =  f.l; coords[1].y = -f.b; coords[1].z =    1;
            coords[2].x =  f.r; coords[2].y = -f.b; coords[2].z =    1;
            coords[3].x =  f.r; coords[3].y = -f.t; coords[3].z =    1;
            break;

        case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
            bind_target = GL_TEXTURE_CUBE_MAP_ARB;
            cube_coords_float(&rect, This->pow2Width, This->pow2Height, &f);
            coords[0].x = -f.l; coords[0].y = -f.t; coords[0].z =   -1;
            coords[1].x = -f.l; coords[1].y = -f.b; coords[1].z =   -1;
            coords[2].x = -f.r; coords[2].y = -f.b; coords[2].z =   -1;
            coords[3].x = -f.r; coords[3].y = -f.t; coords[3].z =   -1;
            break;

        default:
            ERR("Unexpected texture target %#x\n", This->texture_target);
            return;
    }

    context = ActivateContext(device, (IWineD3DSurface*)This, CTXUSAGE_BLIT);

    ENTER_GL();

    glEnable(bind_target);
    checkGLcall("glEnable(bind_target)");
    glBindTexture(bind_target, This->texture_name);
    checkGLcall("glBindTexture(bind_target, This->texture_name)");
    glTexParameteri(bind_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    checkGLcall("glTexParameteri");
    glTexParameteri(bind_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    checkGLcall("glTexParameteri");

    if (context->render_offscreen)
    {
        LONG tmp = rect.top;
        rect.top = rect.bottom;
        rect.bottom = tmp;
    }

    glBegin(GL_QUADS);
    glTexCoord3fv(&coords[0].x);
    glVertex2i(rect.left, rect.top);

    glTexCoord3fv(&coords[1].x);
    glVertex2i(rect.left, rect.bottom);

    glTexCoord3fv(&coords[2].x);
    glVertex2i(rect.right, rect.bottom);

    glTexCoord3fv(&coords[3].x);
    glVertex2i(rect.right, rect.top);
    glEnd();
    checkGLcall("glEnd");

    glDisable(bind_target);
    checkGLcall("glDisable(bind_target)");

    LEAVE_GL();

    if(SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface*)This, &IID_IWineD3DSwapChain, (void **) &swapchain)))
    {
        /* Make sure to flush the buffers. This is needed in apps like Red Alert II and Tiberian SUN that use multiple WGL contexts. */
        if(((IWineD3DSwapChainImpl*)swapchain)->frontBuffer == (IWineD3DSurface*)This ||
           ((IWineD3DSwapChainImpl*)swapchain)->num_contexts >= 2)
            wglFlush();

        IWineD3DSwapChain_Release(swapchain);
    } else {
        /* We changed the filtering settings on the texture. Inform the container about this to get the filters
         * reset properly next draw
         */
        if(SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface*)This, &IID_IWineD3DBaseTexture, (void **) &texture)))
        {
            ((IWineD3DBaseTextureImpl *) texture)->baseTexture.texture_rgb.states[WINED3DTEXSTA_MAGFILTER] = WINED3DTEXF_POINT;
            ((IWineD3DBaseTextureImpl *) texture)->baseTexture.texture_rgb.states[WINED3DTEXSTA_MINFILTER] = WINED3DTEXF_POINT;
            ((IWineD3DBaseTextureImpl *) texture)->baseTexture.texture_rgb.states[WINED3DTEXSTA_MIPFILTER] = WINED3DTEXF_NONE;
            IWineD3DBaseTexture_Release(texture);
        }
    }
}

/*****************************************************************************
 * IWineD3DSurface::LoadLocation
 *
 * Copies the current surface data from wherever it is to the requested
 * location. The location is one of the surface flags, SFLAG_INSYSMEM,
 * SFLAG_INTEXTURE and SFLAG_INDRAWABLE. When the surface is current in
 * multiple locations, the gl texture is preferred over the drawable, which is
 * preferred over system memory. The PBO counts as system memory. If rect is
 * not NULL, only the specified rectangle is copied (only supported for
 * sysmem<->drawable copies at the moment). If rect is NULL, the destination
 * location is marked up to date after the copy.
 *
 * Parameters:
 *  flag: Surface location flag to be updated
 *  rect: rectangle to be copied
 *
 * Returns:
 *  WINED3D_OK on success
 *  WINED3DERR_DEVICELOST on an internal error
 *
 *****************************************************************************/
static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, DWORD flag, const RECT *rect) {
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
    GLenum format, internal, type;
    CONVERT_TYPES convert;
    int bpp;
    int width, pitch, outpitch;
    BYTE *mem;
    BOOL drawable_read_ok = TRUE;

    if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
        if (This->Flags & SFLAG_SWAPCHAIN)
        {
            TRACE("Surface %p is an onscreen surface\n", iface);
        } else {
            /* With ORM_FBO, SFLAG_INTEXTURE and SFLAG_INDRAWABLE are the same for offscreen targets.
             * Prefer SFLAG_INTEXTURE. */
            if (flag == SFLAG_INDRAWABLE) flag = SFLAG_INTEXTURE;
            drawable_read_ok = FALSE;
        }
    }

    TRACE("(%p)->(%s, %p)\n", iface, debug_surflocation(flag), rect);
    if(rect) {
        TRACE("Rectangle: (%d,%d)-(%d,%d)\n", rect->left, rect->top, rect->right, rect->bottom);
    }

    if(This->Flags & flag) {
        TRACE("Location already up to date\n");
        return WINED3D_OK;
    }

    if(!(This->Flags & SFLAG_LOCATIONS)) {
        ERR("%p: Surface does not have any up to date location\n", This);
        This->Flags |= SFLAG_LOST;
        return WINED3DERR_DEVICELOST;
    }

    if(flag == SFLAG_INSYSMEM) {
        surface_prepare_system_memory(This);

        /* Download the surface to system memory */
        if(This->Flags & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX)) {
            if (!device->isInDraw) ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
            surface_bind_and_dirtify(This, !(This->Flags & SFLAG_INTEXTURE));

            surface_download_data(This);
        } else {
            /* Note: It might be faster to download into a texture first. */
            read_from_framebuffer(This, rect,
                                  This->resource.allocatedMemory,
                                  IWineD3DSurface_GetPitch(iface));
        }
    } else if(flag == SFLAG_INDRAWABLE) {
        if(This->Flags & SFLAG_INTEXTURE) {
            surface_blt_to_drawable(This, rect);
        } else {
            if((This->Flags & SFLAG_LOCATIONS) == SFLAG_INSRGBTEX) {
                /* This needs a shader to convert the srgb data sampled from the GL texture into RGB
                 * values, otherwise we get incorrect values in the target. For now go the slow way
                 * via a system memory copy
                 */
                IWineD3DSurfaceImpl_LoadLocation(iface, SFLAG_INSYSMEM, rect);
            }

            d3dfmt_get_conv(This, TRUE /* We need color keying */, FALSE /* We won't use textures */, &format, &internal, &type, &convert, &bpp, FALSE);

            /* The width is in 'length' not in bytes */
            width = This->currentDesc.Width;
            pitch = IWineD3DSurface_GetPitch(iface);

            /* Don't use PBOs for converted surfaces. During PBO conversion we look at SFLAG_CONVERTED
             * but it isn't set (yet) in all cases it is getting called. */
            if((convert != NO_CONVERSION) && (This->Flags & SFLAG_PBO)) {
                TRACE("Removing the pbo attached to surface %p\n", This);
                if (!device->isInDraw) ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
                surface_remove_pbo(This);
            }

            if((convert != NO_CONVERSION) && This->resource.allocatedMemory) {
                int height = This->currentDesc.Height;

                /* Stick to the alignment for the converted surface too, makes it easier to load the surface */
                outpitch = width * bpp;
                outpitch = (outpitch + device->surface_alignment - 1) & ~(device->surface_alignment - 1);

                mem = HeapAlloc(GetProcessHeap(), 0, outpitch * height);
                if(!mem) {
                    ERR("Out of memory %d, %d!\n", outpitch, height);
                    return WINED3DERR_OUTOFVIDEOMEMORY;
                }
                d3dfmt_convert_surface(This->resource.allocatedMemory, mem, pitch, width, height, outpitch, convert, This);

                This->Flags |= SFLAG_CONVERTED;
            } else {
                This->Flags &= ~SFLAG_CONVERTED;
                mem = This->resource.allocatedMemory;
            }

            flush_to_framebuffer_drawpixels(This, format, type, bpp, mem);

            /* Don't delete PBO memory */
            if((mem != This->resource.allocatedMemory) && !(This->Flags & SFLAG_PBO))
                HeapFree(GetProcessHeap(), 0, mem);
        }
    } else /* if(flag & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX)) */ {
        if (drawable_read_ok && (This->Flags & SFLAG_INDRAWABLE)) {
            read_from_framebuffer_texture(This, flag == SFLAG_INSRGBTEX);
        } else { /* Upload from system memory */
            BOOL srgb = flag == SFLAG_INSRGBTEX;
            DWORD alloc_flag = srgb ? SFLAG_SRGBALLOCATED : SFLAG_ALLOCATED;
            d3dfmt_get_conv(This, TRUE /* We need color keying */, TRUE /* We will use textures */, &format, &internal, &type, &convert, &bpp, srgb);

            if(srgb) {
                if((This->Flags & (SFLAG_INTEXTURE | SFLAG_INSYSMEM)) == SFLAG_INTEXTURE) {
                    /* Performance warning ... */
                    FIXME("%p: Downloading rgb texture to reload it as srgb\n", This);
                    IWineD3DSurfaceImpl_LoadLocation(iface, SFLAG_INSYSMEM, rect);
                }
            } else {
                if((This->Flags & (SFLAG_INSRGBTEX | SFLAG_INSYSMEM)) == SFLAG_INSRGBTEX) {
                    /* Performance warning ... */
                    FIXME("%p: Downloading srgb texture to reload it as rgb\n", This);
                    IWineD3DSurfaceImpl_LoadLocation(iface, SFLAG_INSYSMEM, rect);
                }
            }
            if(!(This->Flags & SFLAG_INSYSMEM)) {
                /* Should not happen */
                ERR("Trying to load a texture from sysmem, but SFLAG_INSYSMEM is not set\n");
                /* Lets hope we get it from somewhere... */
                IWineD3DSurfaceImpl_LoadLocation(iface, SFLAG_INSYSMEM, rect);
            }

            if (!device->isInDraw) ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
            surface_bind_and_dirtify(This, srgb);

            if(This->CKeyFlags & WINEDDSD_CKSRCBLT) {
                This->Flags |= SFLAG_GLCKEY;
                This->glCKey = This->SrcBltCKey;
            }
            else This->Flags &= ~SFLAG_GLCKEY;

            /* The width is in 'length' not in bytes */
            width = This->currentDesc.Width;
            pitch = IWineD3DSurface_GetPitch(iface);

            /* Don't use PBOs for converted surfaces. During PBO conversion we look at SFLAG_CONVERTED
             * but it isn't set (yet) in all cases it is getting called. */
            if((convert != NO_CONVERSION) && (This->Flags & SFLAG_PBO)) {
                TRACE("Removing the pbo attached to surface %p\n", This);
                surface_remove_pbo(This);
            }

            if((convert != NO_CONVERSION) && This->resource.allocatedMemory) {
                int height = This->currentDesc.Height;

                /* Stick to the alignment for the converted surface too, makes it easier to load the surface */
                outpitch = width * bpp;
                outpitch = (outpitch + device->surface_alignment - 1) & ~(device->surface_alignment - 1);

                mem = HeapAlloc(GetProcessHeap(), 0, outpitch * height);
                if(!mem) {
                    ERR("Out of memory %d, %d!\n", outpitch, height);
                    return WINED3DERR_OUTOFVIDEOMEMORY;
                }
                d3dfmt_convert_surface(This->resource.allocatedMemory, mem, pitch, width, height, outpitch, convert, This);

                This->Flags |= SFLAG_CONVERTED;
            }
            else if (This->resource.format_desc->format == WINED3DFMT_P8_UINT
                    && (GL_SUPPORT(EXT_PALETTED_TEXTURE) || GL_SUPPORT(ARB_FRAGMENT_PROGRAM)))
            {
                d3dfmt_p8_upload_palette(iface, convert);
                This->Flags &= ~SFLAG_CONVERTED;
                mem = This->resource.allocatedMemory;
            } else {
                This->Flags &= ~SFLAG_CONVERTED;
                mem = This->resource.allocatedMemory;
            }

            /* Make sure the correct pitch is used */
            ENTER_GL();
            glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
            LEAVE_GL();

            if ((This->Flags & SFLAG_NONPOW2) && !(This->Flags & SFLAG_OVERSIZE)) {
                TRACE("non power of two support\n");
                if(!(This->Flags & alloc_flag)) {
                    surface_allocate_surface(This, internal, This->pow2Width, This->pow2Height, format, type);
                    This->Flags |= alloc_flag;
                }
                if (mem || (This->Flags & SFLAG_PBO)) {
                    surface_upload_data(This, internal, This->currentDesc.Width, This->currentDesc.Height, format, type, mem);
                }
            } else {
                /* When making the realloc conditional, keep in mind that GL_APPLE_client_storage may be in use, and This->resource.allocatedMemory
                 * changed. So also keep track of memory changes. In this case the texture has to be reallocated
                 */
                if(!(This->Flags & alloc_flag)) {
                    surface_allocate_surface(This, internal, This->glRect.right - This->glRect.left, This->glRect.bottom - This->glRect.top, format, type);
                    This->Flags |= alloc_flag;
                }
                if (mem || (This->Flags & SFLAG_PBO)) {
                    surface_upload_data(This, internal, This->glRect.right - This->glRect.left, This->glRect.bottom - This->glRect.top, format, type, mem);
                }
            }

            /* Restore the default pitch */
            ENTER_GL();
            glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
            LEAVE_GL();

            /* Don't delete PBO memory */
            if((mem != This->resource.allocatedMemory) && !(This->Flags & SFLAG_PBO))
                HeapFree(GetProcessHeap(), 0, mem);
        }
    }

    if(rect == NULL) {
        This->Flags |= flag;
    }

    if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && !(This->Flags & SFLAG_SWAPCHAIN)
            && (This->Flags & (SFLAG_INTEXTURE | SFLAG_INDRAWABLE))) {
        /* With ORM_FBO, SFLAG_INTEXTURE and SFLAG_INDRAWABLE are the same for offscreen targets. */
        This->Flags |= (SFLAG_INTEXTURE | SFLAG_INDRAWABLE);
    }

    return WINED3D_OK;
}

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

    /* Update the drawable size method */
    if(container) {
        IWineD3DBase_QueryInterface(container, &IID_IWineD3DSwapChain, (void **) &swapchain);
    }
    if(swapchain) {
        This->get_drawable_size = get_drawable_size_swapchain;
        IWineD3DSwapChain_Release(swapchain);
    } else if(This->resource.usage & WINED3DUSAGE_RENDERTARGET) {
        switch(wined3d_settings.offscreen_rendering_mode) {
            case ORM_FBO:        This->get_drawable_size = get_drawable_size_fbo;        break;
            case ORM_PBUFFER:    This->get_drawable_size = get_drawable_size_pbuffer;    break;
            case ORM_BACKBUFFER: This->get_drawable_size = get_drawable_size_backbuffer; break;
        }
    }

    return IWineD3DBaseSurfaceImpl_SetContainer(iface, container);
}

static WINED3DSURFTYPE WINAPI IWineD3DSurfaceImpl_GetImplType(IWineD3DSurface *iface) {
    return SURFACE_OPENGL;
}

static HRESULT WINAPI IWineD3DSurfaceImpl_DrawOverlay(IWineD3DSurface *iface) {
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
    HRESULT hr;

    /* If there's no destination surface there is nothing to do */
    if(!This->overlay_dest) return WINED3D_OK;

    /* Blt calls ModifyLocation on the dest surface, which in turn calls DrawOverlay to
     * update the overlay. Prevent an endless recursion
     */
    if(This->overlay_dest->Flags & SFLAG_INOVERLAYDRAW) {
        return WINED3D_OK;
    }
    This->overlay_dest->Flags |= SFLAG_INOVERLAYDRAW;
    hr = IWineD3DSurfaceImpl_Blt((IWineD3DSurface *) This->overlay_dest, &This->overlay_destrect,
                                 iface, &This->overlay_srcrect, WINEDDBLT_WAIT,
                                 NULL, WINED3DTEXF_LINEAR);
    This->overlay_dest->Flags &= ~SFLAG_INOVERLAYDRAW;

    return hr;
}

const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl =
{
    /* IUnknown */
    IWineD3DBaseSurfaceImpl_QueryInterface,
    IWineD3DBaseSurfaceImpl_AddRef,
    IWineD3DSurfaceImpl_Release,
    /* IWineD3DResource */
    IWineD3DBaseSurfaceImpl_GetParent,
    IWineD3DBaseSurfaceImpl_GetDevice,
    IWineD3DBaseSurfaceImpl_SetPrivateData,
    IWineD3DBaseSurfaceImpl_GetPrivateData,
    IWineD3DBaseSurfaceImpl_FreePrivateData,
    IWineD3DBaseSurfaceImpl_SetPriority,
    IWineD3DBaseSurfaceImpl_GetPriority,
    IWineD3DSurfaceImpl_PreLoad,
    IWineD3DSurfaceImpl_UnLoad,
    IWineD3DBaseSurfaceImpl_GetType,
    /* IWineD3DSurface */
    IWineD3DBaseSurfaceImpl_GetContainer,
    IWineD3DBaseSurfaceImpl_GetDesc,
    IWineD3DSurfaceImpl_LockRect,
    IWineD3DSurfaceImpl_UnlockRect,
    IWineD3DSurfaceImpl_GetDC,
    IWineD3DSurfaceImpl_ReleaseDC,
    IWineD3DSurfaceImpl_Flip,
    IWineD3DSurfaceImpl_Blt,
    IWineD3DBaseSurfaceImpl_GetBltStatus,
    IWineD3DBaseSurfaceImpl_GetFlipStatus,
    IWineD3DBaseSurfaceImpl_IsLost,
    IWineD3DBaseSurfaceImpl_Restore,
    IWineD3DSurfaceImpl_BltFast,
    IWineD3DBaseSurfaceImpl_GetPalette,
    IWineD3DBaseSurfaceImpl_SetPalette,
    IWineD3DSurfaceImpl_RealizePalette,
    IWineD3DBaseSurfaceImpl_SetColorKey,
    IWineD3DBaseSurfaceImpl_GetPitch,
    IWineD3DSurfaceImpl_SetMem,
    IWineD3DBaseSurfaceImpl_SetOverlayPosition,
    IWineD3DBaseSurfaceImpl_GetOverlayPosition,
    IWineD3DBaseSurfaceImpl_UpdateOverlayZOrder,
    IWineD3DBaseSurfaceImpl_UpdateOverlay,
    IWineD3DBaseSurfaceImpl_SetClipper,
    IWineD3DBaseSurfaceImpl_GetClipper,
    /* Internal use: */
    IWineD3DSurfaceImpl_LoadTexture,
    IWineD3DSurfaceImpl_BindTexture,
    IWineD3DSurfaceImpl_SaveSnapshot,
    IWineD3DSurfaceImpl_SetContainer,
    IWineD3DBaseSurfaceImpl_GetData,
    IWineD3DSurfaceImpl_SetFormat,
    IWineD3DSurfaceImpl_PrivateSetup,
    IWineD3DSurfaceImpl_ModifyLocation,
    IWineD3DSurfaceImpl_LoadLocation,
    IWineD3DSurfaceImpl_GetImplType,
    IWineD3DSurfaceImpl_DrawOverlay
};
#undef GLINFO_LOCATION

#define GLINFO_LOCATION device->adapter->gl_info
static HRESULT ffp_blit_alloc(IWineD3DDevice *iface) { return WINED3D_OK; }
/* Context activation is done by the caller. */
static void ffp_blit_free(IWineD3DDevice *iface) { }

/* Context activation is done by the caller. */
static HRESULT ffp_blit_set(IWineD3DDevice *iface, const struct GlPixelFormatDesc *format_desc,
        GLenum textype, UINT width, UINT height)
{
    ENTER_GL();
    glEnable(textype);
    checkGLcall("glEnable(textype)");
    LEAVE_GL();
    return WINED3D_OK;
}

/* Context activation is done by the caller. */
static void ffp_blit_unset(IWineD3DDevice *iface) {
    IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) iface;
    ENTER_GL();
    glDisable(GL_TEXTURE_2D);
    checkGLcall("glDisable(GL_TEXTURE_2D)");
    if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
        glDisable(GL_TEXTURE_CUBE_MAP_ARB);
        checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
    }
    if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
        glDisable(GL_TEXTURE_RECTANGLE_ARB);
        checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
    }
    LEAVE_GL();
}

static BOOL ffp_blit_color_fixup_supported(struct color_fixup_desc fixup)
{
    if (TRACE_ON(d3d_surface) && TRACE_ON(d3d))
    {
        TRACE("Checking support for fixup:\n");
        dump_color_fixup_desc(fixup);
    }

    /* We only support identity conversions. */
    if (is_identity_fixup(fixup))
    {
        TRACE("[OK]\n");
        return TRUE;
    }

    TRACE("[FAILED]\n");
    return FALSE;
}

const struct blit_shader ffp_blit =  {
    ffp_blit_alloc,
    ffp_blit_free,
    ffp_blit_set,
    ffp_blit_unset,
    ffp_blit_color_fixup_supported
};
