/*
 * 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.device;
    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
    struct wined3d_context *context = NULL;
    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])
    {
        context = context_acquire(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);

    if (context) context_release(context);
}

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, gl_info);
    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.device->rev_tex_unit_map[active_texture - GL_TEXTURE0_ARB];

    if (active_sampler != WINED3D_UNMAPPED_STAGE)
    {
        IWineD3DDeviceImpl_MarkStateDirty(This->resource.device, 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.device->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.device))
        {
            format = GL_ALPHA;
            type = GL_UNSIGNED_BYTE;
        }

        if (This->Flags & SFLAG_NONPOW2) {
            unsigned char alignment = This->resource.device->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 wined3d_gl_info *gl_info = &This->resource.device->adapter->gl_info;
    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_info->supported[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.device->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)
{
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
    IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)This->container;

    TRACE("iface %p.\n", iface);

    if (!(This->Flags & SFLAG_SWAPCHAIN))
    {
        ERR("Surface %p is not on a swapchain.\n", iface);
        return GL_NONE;
    }

    if (swapchain->backBuffer && swapchain->backBuffer[0] == iface)
    {
        if (swapchain->render_to_fbo)
        {
            TRACE("Returning GL_COLOR_ATTACHMENT0\n");
            return GL_COLOR_ATTACHMENT0;
        }
        TRACE("Returning GL_BACK\n");
        return GL_BACK;
    }
    else if (swapchain->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;
    IWineD3DDeviceImpl *device = This->resource.device;
    IWineD3DBaseTexture *baseTexture = NULL;

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

        TRACE("(%p) : About to load surface\n", This);

        if (!device->isInDraw) context = context_acquire(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();
        }

        if (context) context_release(context);
    }
}

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

BOOL surface_init_sysmem(IWineD3DSurface *iface)
{
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;

    if(!This->resource.allocatedMemory)
    {
        This->resource.heapMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->resource.size + RESOURCE_ALIGNMENT);
        if(!This->resource.heapMemory)
        {
            ERR("Out of memory\n");
            return FALSE;
        }
        This->resource.allocatedMemory =
            (BYTE *)(((ULONG_PTR) This->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
    }
    else
    {
        memset(This->resource.allocatedMemory, 0, This->resource.size);
    }

    IWineD3DSurface_ModifyLocation(iface, SFLAG_INSYSMEM, TRUE);
    return TRUE;
}

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

    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 surfaces into sysmem, and reset the content. The D3D content is undefined,
         * but we can't set the sysmem INDRAWABLE because when we're rendering the swapchain
         * or the depth stencil into an FBO the texture or render buffer will be removed
         * and all flags get lost
         */
        surface_init_sysmem(iface);
    } 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 = context_acquire(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);
    }

    context_release(context);
}

/* ******************************************************
   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)
{
    IWineD3DDeviceImpl *myDevice = This->resource.device;
    struct wined3d_context *context;
    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.
     */
    context = context_acquire(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 (surface_is_offscreen((IWineD3DSurface *) This))
    {
        /* 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;
    }
    else
    {
        /* Onscreen surfaces are always part of a swapchain */
        GLenum buffer = surface_get_gl_buffer((IWineD3DSurface *)This);
        TRACE("Locking %#x buffer\n", buffer);
        glReadBuffer(buffer);
        checkGLcall("glReadBuffer");
        srcIsUpsideDown = FALSE;
    }

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

    /* 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.device;
    struct wined3d_context *context;
    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.
     */
    context = context_acquire(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 (!surface_is_offscreen((IWineD3DSurface *)This))
    {
        GLenum buffer = surface_get_gl_buffer((IWineD3DSurface *)This);
        TRACE("Locking %#x buffer\n", buffer);

        ENTER_GL();
        glReadBuffer(buffer);
        checkGLcall("glReadBuffer");
        LEAVE_GL();
    }
    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();

    context_release(context);

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

static void surface_prepare_system_memory(IWineD3DSurfaceImpl *This)
{
    IWineD3DDeviceImpl *device = This->resource.device;
    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;

    /* 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_info->supported[ARB_PIXEL_BUFFER_OBJECT] && (This->Flags & SFLAG_DYNLOCK)
            && !(This->Flags & (SFLAG_PBO | SFLAG_CONVERTED | SFLAG_NONPOW2))
            && (This->resource.pool != WINED3DPOOL_SYSTEMMEM))
    {
        GLenum error;
        struct wined3d_context *context;

        context = context_acquire(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();
        context_release(context);
    }
    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.device;
    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)
    {
        struct wined3d_context *context;

        context = context_acquire(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();
        context_release(context);
    }

    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.device;
    struct wined3d_context *context;

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

    if (!surface_is_offscreen((IWineD3DSurface *)This))
    {
        GLenum buffer = surface_get_gl_buffer((IWineD3DSurface *)This);
        TRACE("Unlocking %#x buffer.\n", buffer);
        context_set_draw_buffer(context, buffer);
    }
    else
    {
        /* Primary offscreen render target */
        TRACE("Offscreen render target.\n");
        context_set_draw_buffer(context, 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)");

    LEAVE_GL();
    context_release(context);
}

static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) {
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
    IWineD3DDeviceImpl *myDevice = This->resource.device;
    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)
    {
        struct wined3d_context *context;

        TRACE("Freeing PBO memory\n");

        context = context_acquire(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();
        context_release(context);

        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 void surface_release_client_storage(IWineD3DSurface *iface)
{
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
    struct wined3d_context *context;

    context = context_acquire(This->resource.device, NULL, CTXUSAGE_RESOURCELOAD);

    ENTER_GL();
    glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
    if(This->texture_name)
    {
        surface_bind_and_dirtify(This, FALSE);
        glTexImage2D(This->texture_target, This->texture_level,
                     GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
    }
    if(This->texture_name_srgb)
    {
        surface_bind_and_dirtify(This, TRUE);
        glTexImage2D(This->texture_target, This->texture_level,
                     GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
    }
    glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);

    LEAVE_GL();
    context_release(context);

    IWineD3DSurface_ModifyLocation(iface, SFLAG_INSRGBTEX, FALSE);
    IWineD3DSurface_ModifyLocation(iface, SFLAG_INTEXTURE, FALSE);
    surface_force_reload(iface);
}

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) {
        if(This->Flags & SFLAG_CLIENT) {
            IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, NULL);
            surface_release_client_storage(iface);
        }
        hr = IWineD3DBaseSurfaceImpl_CreateDIBSection(iface);
        if(FAILED(hr)) return WINED3DERR_INVALIDCALL;

        /* 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.device->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.device;
    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;

    /* 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
            && surface_is_offscreen((IWineD3DSurface *) This))
    {
        *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_info->supported[EXT_PALETTED_TEXTURE] || (gl_info->supported[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_info->supported[EXT_PALETTED_TEXTURE] && gl_info->supported[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_info->supported[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_info->supported[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_info->supported[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_info->supported[NV_TEXTURE_SHADER]) break;
            *convert = CONVERT_Q8W8V8U8;
            *format = GL_BGRA;
            *type = GL_UNSIGNED_BYTE;
            *target_bpp = 4;
            break;

        case WINED3DFMT_R16G16_SNORM:
            if (gl_info->supported[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_info->supported[ARB_FRAMEBUFFER_OBJECT]
                    || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
            {
                *convert = CONVERT_D15S1;
                *target_bpp = 4;
            }
            break;

        case WINED3DFMT_S4X4_UINT_D24_UNORM:
            if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
                    || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
            {
                *convert = CONVERT_D24X4S4;
            }
            break;

        case WINED3DFMT_S8_UINT_D24_FLOAT:
            if (gl_info->supported[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.device;
    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)
{
    IWineD3DDeviceImpl *device = This->resource.device;
    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
    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_info->supported[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_info->supported[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.device;
    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;

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

    /* Try to use the paletted texture extension */
    if (gl_info->supported[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.device;

    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))
        {
            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;
    IWineD3DDeviceImpl *device = This->resource.device;
    IWineD3DBaseTexture *baseTexture = NULL;

    TRACE("(%p)Checking to see if the container is a base texture\n", This);
    if (IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&baseTexture) == WINED3D_OK) {
        TRACE("Passing to container\n");
        IWineD3DBaseTexture_BindTexture(baseTexture, srgb);
        IWineD3DBaseTexture_Release(baseTexture);
    }
    else
    {
        struct wined3d_context *context = NULL;
        GLuint *name;

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

        name = srgb ? &This->texture_name_srgb : &This->texture_name;
        if (!device->isInDraw) context = context_acquire(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();

        if (context) context_release(context);
    }
}

#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.device->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) {
            surface_release_client_storage(iface);
        }

        /* 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) {
            surface_release_client_storage(iface);
        }
    }
    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,
        const WINED3DRECT *srect, const WINED3DRECT *drect, BOOL upsidedown, WINED3DTEXTUREFILTERTYPE Filter)
{
    IWineD3DDeviceImpl *myDevice = This->resource.device;
    float xrel, yrel;
    UINT row;
    IWineD3DSurfaceImpl *Src = (IWineD3DSurfaceImpl *) SrcSurface;
    struct wined3d_context *context;


    context = context_acquire(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(surface_is_offscreen(SrcSurface)) {
        TRACE("Reading from an offscreen target\n");
        upsidedown = !upsidedown;
        glReadBuffer(myDevice->offscreenBuffer);
    }
    else
    {
        glReadBuffer(surface_get_gl_buffer(SrcSurface));
    }
    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();
    context_release(context);

    /* 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)
{
    IWineD3DDeviceImpl *myDevice = This->resource.device;
    GLuint src, backup = 0;
    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;
    BOOL src_offscreen;

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

    src_offscreen = surface_is_offscreen(SrcSurface);
    noBackBufferBackup = src_offscreen && 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 ((!src_offscreen || 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 (src_offscreen)
    {
        TRACE("Reading from an offscreen target\n");
        upsidedown = !upsidedown;
        glReadBuffer(myDevice->offscreenBuffer);
    }
    else
    {
        glReadBuffer(surface_get_gl_buffer(SrcSurface));
    }

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

    context_set_draw_buffer(context, 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();
    }
    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();
    context_release(context);

    /* 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)
{
    IWineD3DDeviceImpl *myDevice = This->resource.device;
    WINED3DRECT rect;
    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, &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;
        struct wined3d_context *context;
        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 */
        context = context_acquire(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();

        context_release(context);

        /* 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.device;
    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_D24_UNORM_S8_UINT:
            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.device;

    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.device;

    TRACE("(%p)->(%d, %d, %p, %p, %08x\n", iface, dstx, dsty, Source, rsrc, trans);

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

    if(myDevice->inScene &&
       (iface == myDevice->stencilBufferTarget ||
       (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->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.device;
            struct wined3d_context *context;

            /* 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 */
            context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
            d3dfmt_p8_upload_palette(iface, convert);
            context_release(context);
        } 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;
    const struct wined3d_gl_info *gl_info = &This->resource.device->adapter->gl_info;
    unsigned int pow2Width, pow2Height;

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

    /* Non-power2 support */
    if (gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] || gl_info->supported[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_info->limits.texture_size || This->pow2Height > gl_info->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_info->supported[ARB_TEXTURE_RECTANGLE]
                && !(This->resource.format_desc->format == WINED3DFMT_P8_UINT
                && gl_info->supported[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.device;
    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.device;
    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 (surface_is_offscreen(iface))
        {
            /* 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);
        }
        else
        {
            TRACE("Surface %p is an onscreen surface\n", iface);
        }
    }

    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)
{
    IWineD3DDeviceImpl *device = This->resource.device;
    struct wined3d_context *context;
    struct coords coords[4];
    RECT rect;
    IWineD3DSwapChain *swapchain;
    IWineD3DBaseTexture *texture;
    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 = context_acquire(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);
        }
    }

    context_release(context);
}

/*****************************************************************************
 * 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.device;
    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
    GLenum format, internal, type;
    CONVERT_TYPES convert;
    int bpp;
    int width, pitch, outpitch;
    BYTE *mem;
    BOOL drawable_read_ok = TRUE;
    BOOL in_fbo = FALSE;

    if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
        if (surface_is_offscreen(iface))
        {
            /* 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;
            in_fbo = TRUE;
        }
        else
        {
            TRACE("Surface %p is an onscreen surface\n", iface);
        }
    }

    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))
        {
            struct wined3d_context *context = NULL;

            if (!device->isInDraw) context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);

            surface_bind_and_dirtify(This, !(This->Flags & SFLAG_INTEXTURE));
            surface_download_data(This);

            if (context) context_release(context);
        }
        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))
            {
                struct wined3d_context *context = NULL;

                TRACE("Removing the pbo attached to surface %p\n", This);

                if (!device->isInDraw) context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
                surface_remove_pbo(This);
                if (context) context_release(context);
            }

            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;
            struct wined3d_context *context = NULL;

            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) context = context_acquire(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);
                    if (context) context_release(context);
                    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_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[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();

            if (context) context_release(context);

            /* 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 (in_fbo && (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;
}

BOOL surface_is_offscreen(IWineD3DSurface *iface)
{
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
    IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *) This->container;

    /* Not on a swapchain - must be offscreen */
    if (!(This->Flags & SFLAG_SWAPCHAIN)) return TRUE;

    /* The front buffer is always onscreen */
    if(iface == swapchain->frontBuffer) return FALSE;

    /* If the swapchain is rendered to an FBO, the backbuffer is
     * offscreen, otherwise onscreen */
    return swapchain->render_to_fbo;
}

const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl =
{
    /* IUnknown */
    IWineD3DBaseSurfaceImpl_QueryInterface,
    IWineD3DBaseSurfaceImpl_AddRef,
    IWineD3DSurfaceImpl_Release,
    /* IWineD3DResource */
    IWineD3DBaseSurfaceImpl_GetParent,
    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;
    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;

    ENTER_GL();
    glDisable(GL_TEXTURE_2D);
    checkGLcall("glDisable(GL_TEXTURE_2D)");
    if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
    {
        glDisable(GL_TEXTURE_CUBE_MAP_ARB);
        checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
    }
    if (gl_info->supported[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
};
