/*
 * state block implementation
 *
 * Copyright 2002 Raphael Junqueira
 * Copyright 2004 Jason Edmeades
 * Copyright 2005 Oliver Stieber
 * Copyright 2007 Stefan Dösinger for CodeWeavers
 * 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 "wined3d_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(d3d);
#define GLINFO_LOCATION This->wineD3DDevice->adapter->gl_info

static const DWORD pixel_states_render[] =
{
    WINED3DRS_ALPHABLENDENABLE,
    WINED3DRS_ALPHAFUNC,
    WINED3DRS_ALPHAREF,
    WINED3DRS_ALPHATESTENABLE,
    WINED3DRS_ANTIALIASEDLINEENABLE,
    WINED3DRS_BLENDFACTOR,
    WINED3DRS_BLENDOP,
    WINED3DRS_BLENDOPALPHA,
    WINED3DRS_CCW_STENCILFAIL,
    WINED3DRS_CCW_STENCILPASS,
    WINED3DRS_CCW_STENCILZFAIL,
    WINED3DRS_COLORWRITEENABLE,
    WINED3DRS_COLORWRITEENABLE1,
    WINED3DRS_COLORWRITEENABLE2,
    WINED3DRS_COLORWRITEENABLE3,
    WINED3DRS_DEPTHBIAS,
    WINED3DRS_DESTBLEND,
    WINED3DRS_DESTBLENDALPHA,
    WINED3DRS_DITHERENABLE,
    WINED3DRS_FILLMODE,
    WINED3DRS_FOGDENSITY,
    WINED3DRS_FOGEND,
    WINED3DRS_FOGSTART,
    WINED3DRS_LASTPIXEL,
    WINED3DRS_SCISSORTESTENABLE,
    WINED3DRS_SEPARATEALPHABLENDENABLE,
    WINED3DRS_SHADEMODE,
    WINED3DRS_SLOPESCALEDEPTHBIAS,
    WINED3DRS_SRCBLEND,
    WINED3DRS_SRCBLENDALPHA,
    WINED3DRS_SRGBWRITEENABLE,
    WINED3DRS_STENCILENABLE,
    WINED3DRS_STENCILFAIL,
    WINED3DRS_STENCILFUNC,
    WINED3DRS_STENCILMASK,
    WINED3DRS_STENCILPASS,
    WINED3DRS_STENCILREF,
    WINED3DRS_STENCILWRITEMASK,
    WINED3DRS_STENCILZFAIL,
    WINED3DRS_TEXTUREFACTOR,
    WINED3DRS_TWOSIDEDSTENCILMODE,
    WINED3DRS_WRAP0,
    WINED3DRS_WRAP1,
    WINED3DRS_WRAP10,
    WINED3DRS_WRAP11,
    WINED3DRS_WRAP12,
    WINED3DRS_WRAP13,
    WINED3DRS_WRAP14,
    WINED3DRS_WRAP15,
    WINED3DRS_WRAP2,
    WINED3DRS_WRAP3,
    WINED3DRS_WRAP4,
    WINED3DRS_WRAP5,
    WINED3DRS_WRAP6,
    WINED3DRS_WRAP7,
    WINED3DRS_WRAP8,
    WINED3DRS_WRAP9,
    WINED3DRS_ZENABLE,
    WINED3DRS_ZFUNC,
    WINED3DRS_ZWRITEENABLE,
};

static const DWORD pixel_states_texture[] =
{
    WINED3DTSS_ALPHAARG0,
    WINED3DTSS_ALPHAARG1,
    WINED3DTSS_ALPHAARG2,
    WINED3DTSS_ALPHAOP,
    WINED3DTSS_BUMPENVLOFFSET,
    WINED3DTSS_BUMPENVLSCALE,
    WINED3DTSS_BUMPENVMAT00,
    WINED3DTSS_BUMPENVMAT01,
    WINED3DTSS_BUMPENVMAT10,
    WINED3DTSS_BUMPENVMAT11,
    WINED3DTSS_COLORARG0,
    WINED3DTSS_COLORARG1,
    WINED3DTSS_COLORARG2,
    WINED3DTSS_COLOROP,
    WINED3DTSS_RESULTARG,
    WINED3DTSS_TEXCOORDINDEX,
    WINED3DTSS_TEXTURETRANSFORMFLAGS,
};

static const DWORD pixel_states_sampler[] =
{
    WINED3DSAMP_ADDRESSU,
    WINED3DSAMP_ADDRESSV,
    WINED3DSAMP_ADDRESSW,
    WINED3DSAMP_BORDERCOLOR,
    WINED3DSAMP_MAGFILTER,
    WINED3DSAMP_MINFILTER,
    WINED3DSAMP_MIPFILTER,
    WINED3DSAMP_MIPMAPLODBIAS,
    WINED3DSAMP_MAXMIPLEVEL,
    WINED3DSAMP_MAXANISOTROPY,
    WINED3DSAMP_SRGBTEXTURE,
    WINED3DSAMP_ELEMENTINDEX,
};

static const DWORD vertex_states_render[] =
{
    WINED3DRS_ADAPTIVETESS_W,
    WINED3DRS_ADAPTIVETESS_X,
    WINED3DRS_ADAPTIVETESS_Y,
    WINED3DRS_ADAPTIVETESS_Z,
    WINED3DRS_AMBIENT,
    WINED3DRS_AMBIENTMATERIALSOURCE,
    WINED3DRS_CLIPPING,
    WINED3DRS_CLIPPLANEENABLE,
    WINED3DRS_COLORVERTEX,
    WINED3DRS_CULLMODE,
    WINED3DRS_DIFFUSEMATERIALSOURCE,
    WINED3DRS_EMISSIVEMATERIALSOURCE,
    WINED3DRS_ENABLEADAPTIVETESSELLATION,
    WINED3DRS_FOGCOLOR,
    WINED3DRS_FOGDENSITY,
    WINED3DRS_FOGENABLE,
    WINED3DRS_FOGEND,
    WINED3DRS_FOGSTART,
    WINED3DRS_FOGTABLEMODE,
    WINED3DRS_FOGVERTEXMODE,
    WINED3DRS_INDEXEDVERTEXBLENDENABLE,
    WINED3DRS_LIGHTING,
    WINED3DRS_LOCALVIEWER,
    WINED3DRS_MAXTESSELLATIONLEVEL,
    WINED3DRS_MINTESSELLATIONLEVEL,
    WINED3DRS_MULTISAMPLEANTIALIAS,
    WINED3DRS_MULTISAMPLEMASK,
    WINED3DRS_NORMALDEGREE,
    WINED3DRS_NORMALIZENORMALS,
    WINED3DRS_PATCHEDGESTYLE,
    WINED3DRS_POINTSCALE_A,
    WINED3DRS_POINTSCALE_B,
    WINED3DRS_POINTSCALE_C,
    WINED3DRS_POINTSCALEENABLE,
    WINED3DRS_POINTSIZE,
    WINED3DRS_POINTSIZE_MAX,
    WINED3DRS_POINTSIZE_MIN,
    WINED3DRS_POINTSPRITEENABLE,
    WINED3DRS_POSITIONDEGREE,
    WINED3DRS_RANGEFOGENABLE,
    WINED3DRS_SHADEMODE,
    WINED3DRS_SPECULARENABLE,
    WINED3DRS_SPECULARMATERIALSOURCE,
    WINED3DRS_TWEENFACTOR,
    WINED3DRS_VERTEXBLEND,
};

static const DWORD vertex_states_texture[] =
{
    WINED3DTSS_TEXCOORDINDEX,
    WINED3DTSS_TEXTURETRANSFORMFLAGS,
};

static const DWORD vertex_states_sampler[] =
{
    WINED3DSAMP_DMAPOFFSET,
};

/* Allocates the correct amount of space for pixel and vertex shader constants,
 * along with their set/changed flags on the given stateblock object
 */
static HRESULT stateblock_allocate_shader_constants(IWineD3DStateBlockImpl *object)
{
    IWineD3DStateBlockImpl *This = object;

    /* Allocate space for floating point constants */
    object->pixelShaderConstantF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(float) * GL_LIMITS(pshader_constantsF) * 4);
    if (!object->pixelShaderConstantF) goto fail;

    object->changed.pixelShaderConstantsF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BOOL) * GL_LIMITS(pshader_constantsF));
    if (!object->changed.pixelShaderConstantsF) goto fail;

    object->vertexShaderConstantF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(float) * GL_LIMITS(vshader_constantsF) * 4);
    if (!object->vertexShaderConstantF) goto fail;

    object->changed.vertexShaderConstantsF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BOOL) * GL_LIMITS(vshader_constantsF));
    if (!object->changed.vertexShaderConstantsF) goto fail;

    object->contained_vs_consts_f = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD) * GL_LIMITS(vshader_constantsF));
    if (!object->contained_vs_consts_f) goto fail;

    object->contained_ps_consts_f = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD) * GL_LIMITS(pshader_constantsF));
    if (!object->contained_ps_consts_f) goto fail;

    return WINED3D_OK;

fail:
    ERR("Failed to allocate memory\n");
    HeapFree(GetProcessHeap(), 0, object->pixelShaderConstantF);
    HeapFree(GetProcessHeap(), 0, object->changed.pixelShaderConstantsF);
    HeapFree(GetProcessHeap(), 0, object->vertexShaderConstantF);
    HeapFree(GetProcessHeap(), 0, object->changed.vertexShaderConstantsF);
    HeapFree(GetProcessHeap(), 0, object->contained_vs_consts_f);
    HeapFree(GetProcessHeap(), 0, object->contained_ps_consts_f);
    return E_OUTOFMEMORY;
}

static inline void stateblock_set_bits(DWORD *map, UINT map_size)
{
    DWORD mask = (1 << (map_size & 0x1f)) - 1;
    memset(map, 0xff, (map_size >> 5) * sizeof(*map));
    if (mask) map[map_size >> 5] = mask;
}

/* Set all members of a stateblock savedstate to the given value */
static void stateblock_savedstates_set_all(SAVEDSTATES *states, const struct wined3d_gl_info *gl_info)
{
    unsigned int i;

    /* Single values */
    states->primitive_type = 1;
    states->indices = 1;
    states->material = 1;
    states->viewport = 1;
    states->vertexDecl = 1;
    states->pixelShader = 1;
    states->vertexShader = 1;
    states->scissorRect = 1;

    /* Fixed size arrays */
    states->streamSource = 0xffff;
    states->streamFreq = 0xffff;
    states->textures = 0xfffff;
    stateblock_set_bits(states->transform, HIGHEST_TRANSFORMSTATE + 1);
    stateblock_set_bits(states->renderState, WINEHIGHEST_RENDER_STATE + 1);
    for (i = 0; i < MAX_TEXTURES; ++i) states->textureState[i] = 0x3ffff;
    for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) states->samplerState[i] = 0x3fff;
    states->clipplane = 0xffffffff;
    states->pixelShaderConstantsB = 0xffff;
    states->pixelShaderConstantsI = 0xffff;
    states->vertexShaderConstantsB = 0xffff;
    states->vertexShaderConstantsI = 0xffff;

    /* Dynamically sized arrays */
    memset(states->pixelShaderConstantsF, TRUE, sizeof(BOOL) * gl_info->max_pshader_constantsF);
    memset(states->vertexShaderConstantsF, TRUE, sizeof(BOOL) * gl_info->max_vshader_constantsF);
}

static void stateblock_savedstates_set_pixel(SAVEDSTATES *states, const struct wined3d_gl_info *gl_info)
{
    DWORD texture_mask = 0;
    WORD sampler_mask = 0;
    unsigned int i;

    states->pixelShader = 1;

    for (i = 0; i < sizeof(pixel_states_render) / sizeof(*pixel_states_render); ++i)
    {
        DWORD rs = pixel_states_render[i];
        states->renderState[rs >> 5] |= 1 << (rs & 0x1f);
    }

    for (i = 0; i < sizeof(pixel_states_texture) / sizeof(*pixel_states_texture); ++i)
        texture_mask |= 1 << pixel_states_texture[i];
    for (i = 0; i < MAX_TEXTURES; ++i) states->textureState[i] = texture_mask;
    for (i = 0; i < sizeof(pixel_states_sampler) / sizeof(*pixel_states_sampler); ++i)
        sampler_mask |= 1 << pixel_states_sampler[i];
    for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) states->samplerState[i] = sampler_mask;
    states->pixelShaderConstantsB = 0xffff;
    states->pixelShaderConstantsI = 0xffff;

    memset(states->pixelShaderConstantsF, TRUE, sizeof(BOOL) * gl_info->max_pshader_constantsF);
}

static void stateblock_savedstates_set_vertex(SAVEDSTATES *states, const struct wined3d_gl_info *gl_info)
{
    DWORD texture_mask = 0;
    WORD sampler_mask = 0;
    unsigned int i;

    states->vertexShader = 1;

    for (i = 0; i < sizeof(vertex_states_render) / sizeof(*vertex_states_render); ++i)
    {
        DWORD rs = vertex_states_render[i];
        states->renderState[rs >> 5] |= 1 << (rs & 0x1f);
    }

    for (i = 0; i < sizeof(vertex_states_texture) / sizeof(*vertex_states_texture); ++i)
        texture_mask |= 1 << vertex_states_texture[i];
    for (i = 0; i < MAX_TEXTURES; ++i) states->textureState[i] = texture_mask;
    for (i = 0; i < sizeof(vertex_states_sampler) / sizeof(*vertex_states_sampler); ++i)
        sampler_mask |= 1 << vertex_states_sampler[i];
    for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) states->samplerState[i] = sampler_mask;
    states->vertexShaderConstantsB = 0xffff;
    states->vertexShaderConstantsI = 0xffff;

    memset(states->vertexShaderConstantsF, TRUE, sizeof(BOOL) * gl_info->max_vshader_constantsF);
}

static void stateblock_copy_values(IWineD3DStateBlockImpl *dst, const IWineD3DStateBlockImpl *src,
        const struct wined3d_gl_info *gl_info)
{
    unsigned int l;

    /* Single items */
    dst->gl_primitive_type = src->gl_primitive_type;
    dst->vertexDecl = src->vertexDecl;
    dst->vertexShader = src->vertexShader;
    dst->streamIsUP = src->streamIsUP;
    dst->pIndexData = src->pIndexData;
    dst->IndexFmt = src->IndexFmt;
    dst->baseVertexIndex = src->baseVertexIndex;
    dst->clip_status = src->clip_status;
    dst->viewport = src->viewport;
    dst->material = src->material;
    dst->pixelShader = src->pixelShader;
    dst->scissorRect = src->scissorRect;

    /* Lights */
    memset(dst->activeLights, 0, sizeof(dst->activeLights));
    for (l = 0; l < LIGHTMAP_SIZE; ++l)
    {
        struct list *e1, *e2;
        LIST_FOR_EACH_SAFE(e1, e2, &dst->lightMap[l])
        {
            PLIGHTINFOEL *light = LIST_ENTRY(e1, PLIGHTINFOEL, entry);
            list_remove(&light->entry);
            HeapFree(GetProcessHeap(), 0, light);
        }

        LIST_FOR_EACH(e1, &src->lightMap[l])
        {
            PLIGHTINFOEL *light = LIST_ENTRY(e1, PLIGHTINFOEL, entry), *light2;
            light2 = HeapAlloc(GetProcessHeap(), 0, sizeof(*light));
            *light2 = *light;
            list_add_tail(&dst->lightMap[l], &light2->entry);
            if (light2->glIndex != -1) dst->activeLights[light2->glIndex] = light2;
        }
    }

    /* Fixed size arrays */
    memcpy(dst->vertexShaderConstantB, src->vertexShaderConstantB, sizeof(dst->vertexShaderConstantB));
    memcpy(dst->vertexShaderConstantI, src->vertexShaderConstantI, sizeof(dst->vertexShaderConstantI));
    memcpy(dst->pixelShaderConstantB, src->pixelShaderConstantB, sizeof(dst->pixelShaderConstantB));
    memcpy(dst->pixelShaderConstantI, src->pixelShaderConstantI, sizeof(dst->pixelShaderConstantI));

    memcpy(dst->streamStride, src->streamStride, sizeof(dst->streamStride));
    memcpy(dst->streamOffset, src->streamOffset, sizeof(dst->streamOffset));
    memcpy(dst->streamSource, src->streamSource, sizeof(dst->streamSource));
    memcpy(dst->streamFreq, src->streamFreq, sizeof(dst->streamFreq));
    memcpy(dst->streamFlags, src->streamFlags, sizeof(dst->streamFlags));
    memcpy(dst->transforms, src->transforms, sizeof(dst->transforms));
    memcpy(dst->clipplane, src->clipplane, sizeof(dst->clipplane));
    memcpy(dst->renderState, src->renderState, sizeof(dst->renderState));
    memcpy(dst->textures, src->textures, sizeof(dst->textures));
    memcpy(dst->textureState, src->textureState, sizeof(dst->textureState));
    memcpy(dst->samplerState, src->samplerState, sizeof(dst->samplerState));

    /* Dynamically sized arrays */
    memcpy(dst->vertexShaderConstantF, src->vertexShaderConstantF, sizeof(float) * gl_info->max_vshader_constantsF * 4);
    memcpy(dst->pixelShaderConstantF,  src->pixelShaderConstantF,  sizeof(float) * gl_info->max_pshader_constantsF * 4);
}

void stateblock_init_contained_states(IWineD3DStateBlockImpl *stateblock)
{
    const struct wined3d_gl_info *gl_info = &stateblock->wineD3DDevice->adapter->gl_info;
    unsigned int i, j;

    for (i = 0; i <= WINEHIGHEST_RENDER_STATE >> 5; ++i)
    {
        DWORD map = stateblock->changed.renderState[i];
        for (j = 0; map; map >>= 1, ++j)
        {
            if (!(map & 1)) continue;

            stateblock->contained_render_states[stateblock->num_contained_render_states] = (i << 5) | j;
            ++stateblock->num_contained_render_states;
        }
    }

    for (i = 0; i <= HIGHEST_TRANSFORMSTATE >> 5; ++i)
    {
        DWORD map = stateblock->changed.transform[i];
        for (j = 0; map; map >>= 1, ++j)
        {
            if (!(map & 1)) continue;

            stateblock->contained_transform_states[stateblock->num_contained_transform_states] = (i << 5) | j;
            ++stateblock->num_contained_transform_states;
        }
    }

    for (i = 0; i < gl_info->max_vshader_constantsF; ++i)
    {
        if (stateblock->changed.vertexShaderConstantsF[i])
        {
            stateblock->contained_vs_consts_f[stateblock->num_contained_vs_consts_f] = i;
            ++stateblock->num_contained_vs_consts_f;
        }
    }

    for (i = 0; i < MAX_CONST_I; ++i)
    {
        if (stateblock->changed.vertexShaderConstantsI & (1 << i))
        {
            stateblock->contained_vs_consts_i[stateblock->num_contained_vs_consts_i] = i;
            ++stateblock->num_contained_vs_consts_i;
        }
    }

    for (i = 0; i < MAX_CONST_B; ++i)
    {
        if (stateblock->changed.vertexShaderConstantsB & (1 << i))
        {
            stateblock->contained_vs_consts_b[stateblock->num_contained_vs_consts_b] = i;
            ++stateblock->num_contained_vs_consts_b;
        }
    }

    for (i = 0; i < gl_info->max_pshader_constantsF; ++i)
    {
        if (stateblock->changed.pixelShaderConstantsF[i])
        {
            stateblock->contained_ps_consts_f[stateblock->num_contained_ps_consts_f] = i;
            ++stateblock->num_contained_ps_consts_f;
        }
    }

    for (i = 0; i < MAX_CONST_I; ++i)
    {
        if (stateblock->changed.pixelShaderConstantsI & (1 << i))
        {
            stateblock->contained_ps_consts_i[stateblock->num_contained_ps_consts_i] = i;
            ++stateblock->num_contained_ps_consts_i;
        }
    }

    for (i = 0; i < MAX_CONST_B; ++i)
    {
        if (stateblock->changed.pixelShaderConstantsB & (1 << i))
        {
            stateblock->contained_ps_consts_b[stateblock->num_contained_ps_consts_b] = i;
            ++stateblock->num_contained_ps_consts_b;
        }
    }

    for (i = 0; i < MAX_TEXTURES; ++i)
    {
        DWORD map = stateblock->changed.textureState[i];

        for(j = 0; map; map >>= 1, ++j)
        {
            if (!(map & 1)) continue;

            stateblock->contained_tss_states[stateblock->num_contained_tss_states].stage = i;
            stateblock->contained_tss_states[stateblock->num_contained_tss_states].state = j;
            ++stateblock->num_contained_tss_states;
        }
    }

    for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
    {
        DWORD map = stateblock->changed.samplerState[i];

        for (j = 0; map; map >>= 1, ++j)
        {
            if (!(map & 1)) continue;

            stateblock->contained_sampler_states[stateblock->num_contained_sampler_states].stage = i;
            stateblock->contained_sampler_states[stateblock->num_contained_sampler_states].state = j;
            ++stateblock->num_contained_sampler_states;
        }
    }
}

/**********************************************************
 * IWineD3DStateBlockImpl IUnknown parts follows
 **********************************************************/
static HRESULT  WINAPI IWineD3DStateBlockImpl_QueryInterface(IWineD3DStateBlock *iface,REFIID riid,LPVOID *ppobj)
{
    IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
    TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
    if (IsEqualGUID(riid, &IID_IUnknown)
        || IsEqualGUID(riid, &IID_IWineD3DBase)
        || IsEqualGUID(riid, &IID_IWineD3DStateBlock)){
        IUnknown_AddRef(iface);
        *ppobj = This;
        return S_OK;
    }
    *ppobj = NULL;
    return E_NOINTERFACE;
}

static ULONG  WINAPI IWineD3DStateBlockImpl_AddRef(IWineD3DStateBlock *iface) {
    IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
    ULONG refCount = InterlockedIncrement(&This->ref);

    TRACE("(%p) : AddRef increasing from %d\n", This, refCount - 1);
    return refCount;
}

static ULONG  WINAPI IWineD3DStateBlockImpl_Release(IWineD3DStateBlock *iface) {
    IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
    ULONG refCount = InterlockedDecrement(&This->ref);

    TRACE("(%p) : Releasing from %d\n", This, refCount + 1);

    if (!refCount) {
        int counter;

        if (This->vertexDecl) IWineD3DVertexDeclaration_Release(This->vertexDecl);

        for (counter = 0; counter < MAX_COMBINED_SAMPLERS; counter++)
        {
            if (This->textures[counter]) IWineD3DBaseTexture_Release(This->textures[counter]);
        }

        for (counter = 0; counter < MAX_STREAMS; counter++) {
            if(This->streamSource[counter]) {
                if (IWineD3DBuffer_Release(This->streamSource[counter]))
                {
                    TRACE("Vertex buffer still referenced by stateblock, applications has leaked Stream %u, buffer %p\n", counter, This->streamSource[counter]);
                }
            }
        }
        if(This->pIndexData) IWineD3DBuffer_Release(This->pIndexData);
        if(This->vertexShader) IWineD3DVertexShader_Release(This->vertexShader);
        if(This->pixelShader) IWineD3DPixelShader_Release(This->pixelShader);

        for(counter = 0; counter < LIGHTMAP_SIZE; counter++) {
            struct list *e1, *e2;
            LIST_FOR_EACH_SAFE(e1, e2, &This->lightMap[counter]) {
                PLIGHTINFOEL *light = LIST_ENTRY(e1, PLIGHTINFOEL, entry);
                list_remove(&light->entry);
                HeapFree(GetProcessHeap(), 0, light);
            }
        }

        HeapFree(GetProcessHeap(), 0, This->vertexShaderConstantF);
        HeapFree(GetProcessHeap(), 0, This->changed.vertexShaderConstantsF);
        HeapFree(GetProcessHeap(), 0, This->pixelShaderConstantF);
        HeapFree(GetProcessHeap(), 0, This->changed.pixelShaderConstantsF);
        HeapFree(GetProcessHeap(), 0, This->contained_vs_consts_f);
        HeapFree(GetProcessHeap(), 0, This->contained_ps_consts_f);
        HeapFree(GetProcessHeap(), 0, This);
    }
    return refCount;
}

/**********************************************************
 * IWineD3DStateBlockImpl parts follows
 **********************************************************/
static HRESULT  WINAPI IWineD3DStateBlockImpl_GetParent(IWineD3DStateBlock *iface, IUnknown **pParent) {
    IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
    IUnknown_AddRef(This->parent);
    *pParent = This->parent;
    return WINED3D_OK;
}

static HRESULT  WINAPI IWineD3DStateBlockImpl_GetDevice(IWineD3DStateBlock *iface, IWineD3DDevice** ppDevice){

    IWineD3DStateBlockImpl *This   = (IWineD3DStateBlockImpl *)iface;

    *ppDevice = (IWineD3DDevice*)This->wineD3DDevice;
    IWineD3DDevice_AddRef(*ppDevice);
    return WINED3D_OK;

}

static void record_lights(IWineD3DStateBlockImpl *This, const IWineD3DStateBlockImpl *targetStateBlock)
{
    UINT i;

    /* Lights... For a recorded state block, we just had a chain of actions to perform,
     * so we need to walk that chain and update any actions which differ
     */
    for(i = 0; i < LIGHTMAP_SIZE; i++) {
        struct list *e, *f;
        LIST_FOR_EACH(e, &This->lightMap[i]) {
            BOOL updated = FALSE;
            PLIGHTINFOEL *src = LIST_ENTRY(e, PLIGHTINFOEL, entry), *realLight;
            if (!src->changed && !src->enabledChanged) continue;

            /* Look up the light in the destination */
            LIST_FOR_EACH(f, &targetStateBlock->lightMap[i]) {
                realLight = LIST_ENTRY(f, PLIGHTINFOEL, entry);
                if(realLight->OriginalIndex == src->OriginalIndex) {
                    if(src->changed) {
                        src->OriginalParms = realLight->OriginalParms;
                    }
                    if(src->enabledChanged) {
                            /* Need to double check because enabledChanged does not catch enabled -> disabled -> enabled
                        * or disabled -> enabled -> disabled changes
                            */
                        if(realLight->glIndex == -1 && src->glIndex != -1) {
                            /* Light disabled */
                            This->activeLights[src->glIndex] = NULL;
                        } else if(realLight->glIndex != -1 && src->glIndex == -1){
                            /* Light enabled */
                            This->activeLights[realLight->glIndex] = src;
                        }
                        src->glIndex = realLight->glIndex;
                    }
                    updated = TRUE;
                    break;
                }
            }

            if(updated) {
                /* Found a light, all done, proceed with next hash entry */
                continue;
            } else if(src->changed) {
                /* Otherwise assign defaul params */
                src->OriginalParms = WINED3D_default_light;
            } else {
                /* Not enabled by default */
                src->glIndex = -1;
            }
        }
    }
}

static HRESULT  WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface){

    IWineD3DStateBlockImpl *This             = (IWineD3DStateBlockImpl *)iface;
    IWineD3DStateBlockImpl *targetStateBlock = This->wineD3DDevice->stateBlock;
    unsigned int i, j;
    DWORD map;

    TRACE("(%p) : Updating state block %p ------------------v\n", targetStateBlock, This);

    /* If not recorded, then update can just recapture */
    if (This->blockType == WINED3DSBT_RECORDED) {

        /* Recorded => Only update 'changed' values */
        if (This->changed.vertexShader && This->vertexShader != targetStateBlock->vertexShader) {
            TRACE("Updating vertex shader from %p to %p\n", This->vertexShader, targetStateBlock->vertexShader);

            if(targetStateBlock->vertexShader) IWineD3DVertexShader_AddRef(targetStateBlock->vertexShader);
            if(This->vertexShader) IWineD3DVertexShader_Release(This->vertexShader);
            This->vertexShader = targetStateBlock->vertexShader;
        }

        /* Vertex Shader Float Constants */
        for (j = 0; j < This->num_contained_vs_consts_f; ++j) {
            i = This->contained_vs_consts_f[j];
            TRACE("Setting %p from %p %u to {%f, %f, %f, %f}\n", This, targetStateBlock, i,
                    targetStateBlock->vertexShaderConstantF[i * 4],
                    targetStateBlock->vertexShaderConstantF[i * 4 + 1],
                    targetStateBlock->vertexShaderConstantF[i * 4 + 2],
                    targetStateBlock->vertexShaderConstantF[i * 4 + 3]);

            This->vertexShaderConstantF[i * 4]      = targetStateBlock->vertexShaderConstantF[i * 4];
            This->vertexShaderConstantF[i * 4 + 1]  = targetStateBlock->vertexShaderConstantF[i * 4 + 1];
            This->vertexShaderConstantF[i * 4 + 2]  = targetStateBlock->vertexShaderConstantF[i * 4 + 2];
            This->vertexShaderConstantF[i * 4 + 3]  = targetStateBlock->vertexShaderConstantF[i * 4 + 3];
        }

        /* Vertex Shader Integer Constants */
        for (j = 0; j < This->num_contained_vs_consts_i; ++j) {
            i = This->contained_vs_consts_i[j];
            TRACE("Setting %p from %p %u to {%d, %d, %d, %d}\n", This, targetStateBlock, i,
                    targetStateBlock->vertexShaderConstantI[i * 4],
                    targetStateBlock->vertexShaderConstantI[i * 4 + 1],
                    targetStateBlock->vertexShaderConstantI[i * 4 + 2],
                    targetStateBlock->vertexShaderConstantI[i * 4 + 3]);

            This->vertexShaderConstantI[i * 4]      = targetStateBlock->vertexShaderConstantI[i * 4];
            This->vertexShaderConstantI[i * 4 + 1]  = targetStateBlock->vertexShaderConstantI[i * 4 + 1];
            This->vertexShaderConstantI[i * 4 + 2]  = targetStateBlock->vertexShaderConstantI[i * 4 + 2];
            This->vertexShaderConstantI[i * 4 + 3]  = targetStateBlock->vertexShaderConstantI[i * 4 + 3];
        }

        /* Vertex Shader Boolean Constants */
        for (j = 0; j < This->num_contained_vs_consts_b; ++j) {
            i = This->contained_vs_consts_b[j];
            TRACE("Setting %p from %p %u to %s\n", This, targetStateBlock, i,
                    targetStateBlock->vertexShaderConstantB[i] ? "TRUE" : "FALSE");

            This->vertexShaderConstantB[i] =  targetStateBlock->vertexShaderConstantB[i];
        }

        /* Pixel Shader Float Constants */
        for (j = 0; j < This->num_contained_ps_consts_f; ++j) {
            i = This->contained_ps_consts_f[j];
            TRACE("Setting %p from %p %u to {%f, %f, %f, %f}\n", This, targetStateBlock, i,
                    targetStateBlock->pixelShaderConstantF[i * 4],
                    targetStateBlock->pixelShaderConstantF[i * 4 + 1],
                    targetStateBlock->pixelShaderConstantF[i * 4 + 2],
                    targetStateBlock->pixelShaderConstantF[i * 4 + 3]);

            This->pixelShaderConstantF[i * 4]      = targetStateBlock->pixelShaderConstantF[i * 4];
            This->pixelShaderConstantF[i * 4 + 1]  = targetStateBlock->pixelShaderConstantF[i * 4 + 1];
            This->pixelShaderConstantF[i * 4 + 2]  = targetStateBlock->pixelShaderConstantF[i * 4 + 2];
            This->pixelShaderConstantF[i * 4 + 3]  = targetStateBlock->pixelShaderConstantF[i * 4 + 3];
        }

        /* Pixel Shader Integer Constants */
        for (j = 0; j < This->num_contained_ps_consts_i; ++j) {
            i = This->contained_ps_consts_i[j];
            TRACE("Setting %p from %p %u to {%d, %d, %d, %d}\n", This, targetStateBlock, i,
                    targetStateBlock->pixelShaderConstantI[i * 4],
                    targetStateBlock->pixelShaderConstantI[i * 4 + 1],
                    targetStateBlock->pixelShaderConstantI[i * 4 + 2],
                    targetStateBlock->pixelShaderConstantI[i * 4 + 3]);

            This->pixelShaderConstantI[i * 4]      = targetStateBlock->pixelShaderConstantI[i * 4];
            This->pixelShaderConstantI[i * 4 + 1]  = targetStateBlock->pixelShaderConstantI[i * 4 + 1];
            This->pixelShaderConstantI[i * 4 + 2]  = targetStateBlock->pixelShaderConstantI[i * 4 + 2];
            This->pixelShaderConstantI[i * 4 + 3]  = targetStateBlock->pixelShaderConstantI[i * 4 + 3];
        }

        /* Pixel Shader Boolean Constants */
        for (j = 0; j < This->num_contained_ps_consts_b; ++j) {
            i = This->contained_ps_consts_b[j];
            TRACE("Setting %p from %p %u to %s\n", This, targetStateBlock, i,
                    targetStateBlock->pixelShaderConstantB[i] ? "TRUE" : "FALSE");

            This->pixelShaderConstantB[i] =  targetStateBlock->pixelShaderConstantB[i];
        }

        /* Others + Render & Texture */
        for (i = 0; i < This->num_contained_transform_states; i++) {
            TRACE("Updating transform %u\n", i);
            This->transforms[This->contained_transform_states[i]] =
                targetStateBlock->transforms[This->contained_transform_states[i]];
        }

        if (This->changed.primitive_type) This->gl_primitive_type = targetStateBlock->gl_primitive_type;

        if (This->changed.indices && ((This->pIndexData != targetStateBlock->pIndexData)
                        || (This->baseVertexIndex != targetStateBlock->baseVertexIndex)
                        || (This->IndexFmt != targetStateBlock->IndexFmt))) {
            TRACE("Updating pIndexData to %p, baseVertexIndex to %d\n",
                    targetStateBlock->pIndexData, targetStateBlock->baseVertexIndex);
            if(targetStateBlock->pIndexData) IWineD3DBuffer_AddRef(targetStateBlock->pIndexData);
            if(This->pIndexData) IWineD3DBuffer_Release(This->pIndexData);
            This->pIndexData = targetStateBlock->pIndexData;
            This->baseVertexIndex = targetStateBlock->baseVertexIndex;
            This->IndexFmt = targetStateBlock->IndexFmt;
        }

        if(This->changed.vertexDecl && This->vertexDecl != targetStateBlock->vertexDecl){
            TRACE("Updating vertex declaration from %p to %p\n", This->vertexDecl, targetStateBlock->vertexDecl);

            if (targetStateBlock->vertexDecl) IWineD3DVertexDeclaration_AddRef(targetStateBlock->vertexDecl);
            if (This->vertexDecl) IWineD3DVertexDeclaration_Release(This->vertexDecl);
            This->vertexDecl = targetStateBlock->vertexDecl;
        }

        if (This->changed.material && memcmp(&targetStateBlock->material,
                                                    &This->material,
                                                    sizeof(WINED3DMATERIAL)) != 0) {
            TRACE("Updating material\n");
            This->material = targetStateBlock->material;
        }

        if (This->changed.viewport && memcmp(&targetStateBlock->viewport,
                                                    &This->viewport,
                                                    sizeof(WINED3DVIEWPORT)) != 0) {
            TRACE("Updating viewport\n");
            This->viewport = targetStateBlock->viewport;
        }

        if(This->changed.scissorRect && memcmp(&targetStateBlock->scissorRect,
                                           &This->scissorRect,
                                           sizeof(targetStateBlock->scissorRect)))
        {
            TRACE("Updating scissor rect\n");
            targetStateBlock->scissorRect = This->scissorRect;
        }

        map = This->changed.streamSource;
        for (i = 0; map; map >>= 1, ++i)
        {
            if (!(map & 1)) continue;

            if (This->streamStride[i] != targetStateBlock->streamStride[i]
                    || This->streamSource[i] != targetStateBlock->streamSource[i])
            {
                TRACE("Updating stream source %u to %p, stride to %u\n",
                        i, targetStateBlock->streamSource[i], targetStateBlock->streamStride[i]);
                This->streamStride[i] = targetStateBlock->streamStride[i];
                if (targetStateBlock->streamSource[i]) IWineD3DBuffer_AddRef(targetStateBlock->streamSource[i]);
                if (This->streamSource[i]) IWineD3DBuffer_Release(This->streamSource[i]);
                This->streamSource[i] = targetStateBlock->streamSource[i];
            }
        }

        map = This->changed.streamFreq;
        for (i = 0; map; map >>= 1, ++i)
        {
            if (!(map & 1)) continue;

            if (This->streamFreq[i] != targetStateBlock->streamFreq[i]
                    || This->streamFlags[i] != targetStateBlock->streamFlags[i])
            {
                TRACE("Updating stream frequency %u to %u flags to %#x\n",
                        i, targetStateBlock->streamFreq[i], targetStateBlock->streamFlags[i]);
                This->streamFreq[i] = targetStateBlock->streamFreq[i];
                This->streamFlags[i] = targetStateBlock->streamFlags[i];
            }
        }

        map = This->changed.clipplane;
        for (i = 0; map; map >>= 1, ++i)
        {
            if (!(map & 1)) continue;

            if (memcmp(targetStateBlock->clipplane[i], This->clipplane[i], sizeof(*This->clipplane)))
            {
                TRACE("Updating clipplane %u\n", i);
                memcpy(This->clipplane[i], targetStateBlock->clipplane[i], sizeof(*This->clipplane));
            }
        }

        /* Render */
        for (i = 0; i < This->num_contained_render_states; i++) {
            TRACE("Updating renderState %u to %u\n", This->contained_render_states[i],
                    targetStateBlock->renderState[This->contained_render_states[i]]);
            This->renderState[This->contained_render_states[i]] = targetStateBlock->renderState[This->contained_render_states[i]];
        }

        /* Texture states */
        for (j = 0; j < This->num_contained_tss_states; j++) {
            DWORD stage = This->contained_tss_states[j].stage;
            DWORD state = This->contained_tss_states[j].state;

            TRACE("Updating texturestage state %u, %u to %u (was %u)\n", stage, state,
                    targetStateBlock->textureState[stage][state], This->textureState[stage][state]);
            This->textureState[stage][state] = targetStateBlock->textureState[stage][state];
        }

        /* Samplers */
        map = This->changed.textures;
        for (i = 0; map; map >>= 1, ++i)
        {
            if (!(map & 1)) continue;

            TRACE("Updating texture %u to %p (was %p)\n", i, targetStateBlock->textures[i], This->textures[i]);
            if (targetStateBlock->textures[i]) IWineD3DBaseTexture_AddRef(targetStateBlock->textures[i]);
            if (This->textures[i]) IWineD3DBaseTexture_Release(This->textures[i]);
            This->textures[i] = targetStateBlock->textures[i];
        }

        for (j = 0; j < This->num_contained_sampler_states; j++) {
            DWORD stage = This->contained_sampler_states[j].stage;
            DWORD state = This->contained_sampler_states[j].state;
            TRACE("Updating sampler state %u, %u to %u (was %u)\n", stage, state,
                    targetStateBlock->samplerState[stage][state], This->samplerState[stage][state]);
            This->samplerState[stage][state] = targetStateBlock->samplerState[stage][state];
        }
        if(This->changed.pixelShader && This->pixelShader != targetStateBlock->pixelShader) {
            if(targetStateBlock->pixelShader) IWineD3DPixelShader_AddRef(targetStateBlock->pixelShader);
            if(This->pixelShader) IWineD3DPixelShader_Release(This->pixelShader);
            This->pixelShader = targetStateBlock->pixelShader;
        }

        record_lights(This, targetStateBlock);
    } else if(This->blockType == WINED3DSBT_ALL) {
        memcpy(This->vertexShaderConstantB, targetStateBlock->vertexShaderConstantB, sizeof(This->vertexShaderConstantI));
        memcpy(This->vertexShaderConstantI, targetStateBlock->vertexShaderConstantI, sizeof(This->vertexShaderConstantF));
        memcpy(This->vertexShaderConstantF, targetStateBlock->vertexShaderConstantF, sizeof(float) * GL_LIMITS(vshader_constantsF) * 4);
        This->gl_primitive_type = targetStateBlock->gl_primitive_type;
        memcpy(This->streamStride, targetStateBlock->streamStride, sizeof(This->streamStride));
        memcpy(This->streamOffset, targetStateBlock->streamOffset, sizeof(This->streamOffset));
        memcpy(This->streamFreq, targetStateBlock->streamFreq, sizeof(This->streamFreq));
        memcpy(This->streamFlags, targetStateBlock->streamFlags, sizeof(This->streamFlags));
        This->baseVertexIndex = targetStateBlock->baseVertexIndex;
        memcpy(This->transforms, targetStateBlock->transforms, sizeof(This->transforms));
        record_lights(This, targetStateBlock);
        memcpy(This->clipplane, targetStateBlock->clipplane, sizeof(This->clipplane));
        This->clip_status = targetStateBlock->clip_status;
        This->viewport = targetStateBlock->viewport;
        This->material = targetStateBlock->material;
        memcpy(This->pixelShaderConstantB, targetStateBlock->pixelShaderConstantB, sizeof(This->pixelShaderConstantI));
        memcpy(This->pixelShaderConstantI, targetStateBlock->pixelShaderConstantI, sizeof(This->pixelShaderConstantF));
        memcpy(This->pixelShaderConstantF, targetStateBlock->pixelShaderConstantF, sizeof(float) * GL_LIMITS(pshader_constantsF) * 4);
        memcpy(This->renderState, targetStateBlock->renderState, sizeof(This->renderState));
        memcpy(This->textureState, targetStateBlock->textureState, sizeof(This->textureState));
        memcpy(This->samplerState, targetStateBlock->samplerState, sizeof(This->samplerState));
        This->scissorRect = targetStateBlock->scissorRect;

        if (This->vertexDecl != targetStateBlock->vertexDecl)
        {
            if (targetStateBlock->vertexDecl) IWineD3DVertexDeclaration_AddRef(targetStateBlock->vertexDecl);
            if (This->vertexDecl) IWineD3DVertexDeclaration_Release(This->vertexDecl);
            This->vertexDecl = targetStateBlock->vertexDecl;
        }

        for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
        {
            if (targetStateBlock->textures[i] != This->textures[i])
            {
                if (targetStateBlock->textures[i]) IWineD3DBaseTexture_AddRef(targetStateBlock->textures[i]);
                if (This->textures[i]) IWineD3DBaseTexture_Release(This->textures[i]);
                This->textures[i] = targetStateBlock->textures[i];
            }
        }

        if(targetStateBlock->pIndexData != This->pIndexData ||
           targetStateBlock->IndexFmt != This->IndexFmt) {
            if (targetStateBlock->pIndexData) IWineD3DBuffer_AddRef(targetStateBlock->pIndexData);
            if (This->pIndexData) IWineD3DBuffer_Release(This->pIndexData);
            This->pIndexData = targetStateBlock->pIndexData;
            This->IndexFmt = targetStateBlock->IndexFmt;
        }
        for(i = 0; i < MAX_STREAMS; i++) {
            if(targetStateBlock->streamSource[i] != This->streamSource[i]) {
                if(targetStateBlock->streamSource[i]) IWineD3DBuffer_AddRef(targetStateBlock->streamSource[i]);
                if(This->streamSource[i]) IWineD3DBuffer_Release(This->streamSource[i]);
                This->streamSource[i] = targetStateBlock->streamSource[i];
            }
        }
        if(This->vertexShader != targetStateBlock->vertexShader) {
            if(targetStateBlock->vertexShader) IWineD3DVertexShader_AddRef(targetStateBlock->vertexShader);
            if(This->vertexShader) IWineD3DVertexShader_Release(This->vertexShader);
            This->vertexShader = targetStateBlock->vertexShader;
        }
        if(This->pixelShader != targetStateBlock->pixelShader) {
            if(targetStateBlock->pixelShader) IWineD3DPixelShader_AddRef(targetStateBlock->pixelShader);
            if(This->pixelShader) IWineD3DPixelShader_Release(This->pixelShader);
            This->pixelShader = targetStateBlock->pixelShader;
        }
    } else if(This->blockType == WINED3DSBT_VERTEXSTATE) {
        memcpy(This->vertexShaderConstantB, targetStateBlock->vertexShaderConstantB, sizeof(This->vertexShaderConstantI));
        memcpy(This->vertexShaderConstantI, targetStateBlock->vertexShaderConstantI, sizeof(This->vertexShaderConstantF));
        memcpy(This->vertexShaderConstantF, targetStateBlock->vertexShaderConstantF, sizeof(float) * GL_LIMITS(vshader_constantsF) * 4);
        record_lights(This, targetStateBlock);
        for (i = 0; i < sizeof(vertex_states_render) / sizeof(*vertex_states_render); ++i)
        {
            This->renderState[vertex_states_render[i]] = targetStateBlock->renderState[vertex_states_render[i]];
        }
        for (j = 0; j < MAX_COMBINED_SAMPLERS; j++) {
            for (i = 0; i < sizeof(vertex_states_sampler) / sizeof(*vertex_states_sampler); ++i)
            {
                This->samplerState[j][vertex_states_sampler[i]] = targetStateBlock->samplerState[j][vertex_states_sampler[i]];
            }
        }
        for (j = 0; j < MAX_TEXTURES; j++) {
            for (i = 0; i < sizeof(vertex_states_render) / sizeof(*vertex_states_render); ++i)
            {
                This->textureState[j][vertex_states_render[i]] = targetStateBlock->textureState[j][vertex_states_render[i]];
            }
        }
        for(i = 0; i < MAX_STREAMS; i++) {
            if(targetStateBlock->streamSource[i] != This->streamSource[i]) {
                if (targetStateBlock->streamSource[i]) IWineD3DBuffer_AddRef(targetStateBlock->streamSource[i]);
                if (This->streamSource[i]) IWineD3DBuffer_Release(This->streamSource[i]);
                This->streamSource[i] = targetStateBlock->streamSource[i];
            }
        }
        if(This->vertexShader != targetStateBlock->vertexShader) {
            if(targetStateBlock->vertexShader) IWineD3DVertexShader_AddRef(targetStateBlock->vertexShader);
            if(This->vertexShader) IWineD3DVertexShader_Release(This->vertexShader);
            This->vertexShader = targetStateBlock->vertexShader;
        }
    } else if(This->blockType == WINED3DSBT_PIXELSTATE) {
        memcpy(This->pixelShaderConstantB, targetStateBlock->pixelShaderConstantB, sizeof(This->pixelShaderConstantI));
        memcpy(This->pixelShaderConstantI, targetStateBlock->pixelShaderConstantI, sizeof(This->pixelShaderConstantF));
        memcpy(This->pixelShaderConstantF, targetStateBlock->pixelShaderConstantF, sizeof(float) * GL_LIMITS(pshader_constantsF) * 4);
        for (i = 0; i < sizeof(pixel_states_render) / sizeof(*pixel_states_render); ++i)
        {
            This->renderState[pixel_states_render[i]] = targetStateBlock->renderState[pixel_states_render[i]];
        }
        for (j = 0; j < MAX_COMBINED_SAMPLERS; j++) {
            for (i = 0; i < sizeof(pixel_states_sampler) / sizeof(*pixel_states_sampler); ++i)
            {
                This->samplerState[j][pixel_states_sampler[i]] = targetStateBlock->samplerState[j][pixel_states_sampler[i]];
            }
        }
        for (j = 0; j < MAX_TEXTURES; j++) {
            for (i = 0; i < sizeof(pixel_states_render) / sizeof(*pixel_states_render); ++i)
            {
                This->textureState[j][pixel_states_render[i]] = targetStateBlock->textureState[j][pixel_states_render[i]];
            }
        }
        if(This->pixelShader != targetStateBlock->pixelShader) {
            if(targetStateBlock->pixelShader) IWineD3DPixelShader_AddRef(targetStateBlock->pixelShader);
            if(This->pixelShader) IWineD3DPixelShader_Release(This->pixelShader);
            This->pixelShader = targetStateBlock->pixelShader;
        }
    }

    TRACE("(%p) : Updated state block %p ------------------^\n", targetStateBlock, This);

    return WINED3D_OK;
}

static void apply_lights(IWineD3DDevice *pDevice, const IWineD3DStateBlockImpl *This)
{
    UINT i;
    for(i = 0; i < LIGHTMAP_SIZE; i++) {
        struct list *e;

        LIST_FOR_EACH(e, &This->lightMap[i]) {
            const PLIGHTINFOEL *light = LIST_ENTRY(e, PLIGHTINFOEL, entry);

            if(light->changed) {
                IWineD3DDevice_SetLight(pDevice, light->OriginalIndex, &light->OriginalParms);
            }
            if(light->enabledChanged) {
                IWineD3DDevice_SetLightEnable(pDevice, light->OriginalIndex, light->glIndex != -1);
            }
        }
    }
}

static HRESULT  WINAPI IWineD3DStateBlockImpl_Apply(IWineD3DStateBlock *iface){
    IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
    IWineD3DDevice*        pDevice     = (IWineD3DDevice*)This->wineD3DDevice;

/*Copy thing over to updateBlock is isRecording otherwise StateBlock,
should really perform a delta so that only the changes get updated*/

    UINT i;
    UINT j;
    DWORD map;

    TRACE("(%p) : Applying state block %p ------------------v\n", This, pDevice);

    TRACE("Blocktype: %d\n", This->blockType);

    if(This->blockType == WINED3DSBT_RECORDED) {
        if (This->changed.vertexShader) {
            IWineD3DDevice_SetVertexShader(pDevice, This->vertexShader);
        }
        /* Vertex Shader Constants */
        for (i = 0; i < This->num_contained_vs_consts_f; i++) {
            IWineD3DDevice_SetVertexShaderConstantF(pDevice, This->contained_vs_consts_f[i],
                    This->vertexShaderConstantF + This->contained_vs_consts_f[i] * 4, 1);
        }
        for (i = 0; i < This->num_contained_vs_consts_i; i++) {
            IWineD3DDevice_SetVertexShaderConstantI(pDevice, This->contained_vs_consts_i[i],
                    This->vertexShaderConstantI + This->contained_vs_consts_i[i] * 4, 1);
        }
        for (i = 0; i < This->num_contained_vs_consts_b; i++) {
            IWineD3DDevice_SetVertexShaderConstantB(pDevice, This->contained_vs_consts_b[i],
                    This->vertexShaderConstantB + This->contained_vs_consts_b[i], 1);
        }

        apply_lights(pDevice, This);

        if (This->changed.pixelShader) {
            IWineD3DDevice_SetPixelShader(pDevice, This->pixelShader);
        }
        /* Pixel Shader Constants */
        for (i = 0; i < This->num_contained_ps_consts_f; i++) {
            IWineD3DDevice_SetPixelShaderConstantF(pDevice, This->contained_ps_consts_f[i],
                    This->pixelShaderConstantF + This->contained_ps_consts_f[i] * 4, 1);
        }
        for (i = 0; i < This->num_contained_ps_consts_i; i++) {
            IWineD3DDevice_SetPixelShaderConstantI(pDevice, This->contained_ps_consts_i[i],
                    This->pixelShaderConstantI + This->contained_ps_consts_i[i] * 4, 1);
        }
        for (i = 0; i < This->num_contained_ps_consts_b; i++) {
            IWineD3DDevice_SetPixelShaderConstantB(pDevice, This->contained_ps_consts_b[i],
                    This->pixelShaderConstantB + This->contained_ps_consts_b[i], 1);
        }

        /* Render */
        for (i = 0; i <= This->num_contained_render_states; i++) {
            IWineD3DDevice_SetRenderState(pDevice, This->contained_render_states[i],
                                          This->renderState[This->contained_render_states[i]]);
        }
        /* Texture states */
        for (i = 0; i < This->num_contained_tss_states; i++) {
            DWORD stage = This->contained_tss_states[i].stage;
            DWORD state = This->contained_tss_states[i].state;
            ((IWineD3DDeviceImpl *)pDevice)->stateBlock->textureState[stage][state]         = This->textureState[stage][state];
            ((IWineD3DDeviceImpl *)pDevice)->stateBlock->changed.textureState[stage] |= 1 << state;
            /* TODO: Record a display list to apply all gl states. For now apply by brute force */
            IWineD3DDeviceImpl_MarkStateDirty((IWineD3DDeviceImpl *)pDevice, STATE_TEXTURESTAGE(stage, state));
        }
        /* Sampler states */
        for (i = 0; i < This->num_contained_sampler_states; i++) {
            DWORD stage = This->contained_sampler_states[i].stage;
            DWORD state = This->contained_sampler_states[i].state;
            ((IWineD3DDeviceImpl *)pDevice)->stateBlock->samplerState[stage][state]         = This->samplerState[stage][state];
            ((IWineD3DDeviceImpl *)pDevice)->stateBlock->changed.samplerState[stage] |= 1 << state;
            IWineD3DDeviceImpl_MarkStateDirty((IWineD3DDeviceImpl *)pDevice, STATE_SAMPLER(stage));
        }

        for (i = 0; i < This->num_contained_transform_states; i++) {
            IWineD3DDevice_SetTransform(pDevice, This->contained_transform_states[i],
                                        &This->transforms[This->contained_transform_states[i]]);
        }

        if (This->changed.primitive_type)
        {
                This->wineD3DDevice->updateStateBlock->changed.primitive_type = TRUE;
                This->wineD3DDevice->updateStateBlock->gl_primitive_type = This->gl_primitive_type;
        }

        if (This->changed.indices)
        {
            IWineD3DDevice_SetIndexBuffer(pDevice, This->pIndexData, This->IndexFmt);
            IWineD3DDevice_SetBaseVertexIndex(pDevice, This->baseVertexIndex);
        }

        if (This->changed.vertexDecl) {
            IWineD3DDevice_SetVertexDeclaration(pDevice, This->vertexDecl);
        }

        if (This->changed.material ) {
            IWineD3DDevice_SetMaterial(pDevice, &This->material);
        }

        if (This->changed.viewport) {
            IWineD3DDevice_SetViewport(pDevice, &This->viewport);
        }

        if (This->changed.scissorRect) {
            IWineD3DDevice_SetScissorRect(pDevice, &This->scissorRect);
        }

        /* TODO: Proper implementation using SetStreamSource offset (set to 0 for the moment)\n") */
        map = This->changed.streamSource;
        for (i = 0; map; map >>= 1, ++i)
        {
            if (map & 1) IWineD3DDevice_SetStreamSource(pDevice, i, This->streamSource[i], 0, This->streamStride[i]);
        }

        map = This->changed.streamFreq;
        for (i = 0; map; map >>= 1, ++i)
        {
            if (map & 1) IWineD3DDevice_SetStreamSourceFreq(pDevice, i, This->streamFreq[i] | This->streamFlags[i]);
        }

        map = This->changed.textures;
        for (i = 0; map; map >>= 1, ++i)
        {
            if (!(map & 1)) continue;

            if (i < MAX_FRAGMENT_SAMPLERS) IWineD3DDevice_SetTexture(pDevice, i, This->textures[i]);
            else IWineD3DDevice_SetTexture(pDevice, WINED3DVERTEXTEXTURESAMPLER0 + i - MAX_FRAGMENT_SAMPLERS,
                    This->textures[i]);
        }

        map = This->changed.clipplane;
        for (i = 0; map; map >>= 1, ++i)
        {
            float clip[4];

            if (!(map & 1)) continue;

            clip[0] = This->clipplane[i][0];
            clip[1] = This->clipplane[i][1];
            clip[2] = This->clipplane[i][2];
            clip[3] = This->clipplane[i][3];
            IWineD3DDevice_SetClipPlane(pDevice, i, clip);
        }
    } else if(This->blockType == WINED3DSBT_VERTEXSTATE) {
        IWineD3DDevice_SetVertexShader(pDevice, This->vertexShader);
        for (i = 0; i < GL_LIMITS(vshader_constantsF); i++) {
            IWineD3DDevice_SetVertexShaderConstantF(pDevice, i,
                    This->vertexShaderConstantF + i * 4, 1);
        }
        for (i = 0; i < MAX_CONST_I; i++) {
            IWineD3DDevice_SetVertexShaderConstantI(pDevice, i,
                    This->vertexShaderConstantI + i * 4, 1);
        }
        for (i = 0; i < MAX_CONST_B; i++) {
            IWineD3DDevice_SetVertexShaderConstantB(pDevice, i,
                    This->vertexShaderConstantB + i, 1);
        }

        apply_lights(pDevice, This);

        for (i = 0; i < sizeof(vertex_states_render) / sizeof(*vertex_states_render); ++i)
        {
            IWineD3DDevice_SetRenderState(pDevice, vertex_states_render[i], This->renderState[vertex_states_render[i]]);
        }
        for(j = 0; j < MAX_TEXTURES; j++) {
            for (i = 0; i < sizeof(vertex_states_texture) / sizeof(*vertex_states_texture); ++i)
            {
                IWineD3DDevice_SetTextureStageState(pDevice, j, vertex_states_texture[i],
                        This->textureState[j][vertex_states_texture[i]]);
            }
        }

        for(j = 0; j < MAX_FRAGMENT_SAMPLERS; j++) {
            for (i = 0; i < sizeof(vertex_states_sampler) / sizeof(*vertex_states_sampler); ++i)
            {
                IWineD3DDevice_SetSamplerState(pDevice, j, vertex_states_sampler[i],
                        This->samplerState[j][vertex_states_sampler[i]]);
            }
        }
        for(j = MAX_FRAGMENT_SAMPLERS; j < MAX_COMBINED_SAMPLERS; j++) {
            for (i = 0; i < sizeof(vertex_states_sampler) / sizeof(*vertex_states_sampler); ++i)
            {
                IWineD3DDevice_SetSamplerState(pDevice, WINED3DVERTEXTEXTURESAMPLER0 + j - MAX_FRAGMENT_SAMPLERS,
                        vertex_states_sampler[i], This->samplerState[j][vertex_states_sampler[i]]);
            }
        }
    } else if(This->blockType == WINED3DSBT_PIXELSTATE) {
        IWineD3DDevice_SetPixelShader(pDevice, This->pixelShader);
        for (i = 0; i < GL_LIMITS(pshader_constantsF); i++) {
            IWineD3DDevice_SetPixelShaderConstantF(pDevice, i,
                    This->pixelShaderConstantF + i * 4, 1);
        }
        for (i = 0; i < MAX_CONST_I; i++) {
            IWineD3DDevice_SetPixelShaderConstantI(pDevice, i,
                    This->pixelShaderConstantI + i * 4, 1);
        }
        for (i = 0; i < MAX_CONST_B; i++) {
            IWineD3DDevice_SetPixelShaderConstantB(pDevice, i,
                    This->pixelShaderConstantB + i, 1);
        }

        for (i = 0; i < sizeof(pixel_states_render) / sizeof(*pixel_states_render); ++i)
        {
            IWineD3DDevice_SetRenderState(pDevice, pixel_states_render[i], This->renderState[pixel_states_render[i]]);
        }
        for(j = 0; j < MAX_TEXTURES; j++) {
            for (i = 0; i < sizeof(pixel_states_texture) / sizeof(*pixel_states_texture); ++i)
            {
                IWineD3DDevice_SetTextureStageState(pDevice, j, pixel_states_texture[i],
                        This->textureState[j][pixel_states_texture[i]]);
            }
        }

        for(j = 0; j < MAX_FRAGMENT_SAMPLERS; j++) {
            for (i = 0; i < sizeof(pixel_states_sampler) / sizeof(*pixel_states_sampler); ++i)
            {
                IWineD3DDevice_SetSamplerState(pDevice, j, pixel_states_sampler[i],
                        This->samplerState[j][pixel_states_sampler[i]]);
            }
        }
        for(j = MAX_FRAGMENT_SAMPLERS; j < MAX_COMBINED_SAMPLERS; j++) {
            for (i = 0; i < sizeof(pixel_states_sampler) / sizeof(*pixel_states_sampler); ++i)
            {
                IWineD3DDevice_SetSamplerState(pDevice, WINED3DVERTEXTEXTURESAMPLER0 + j - MAX_FRAGMENT_SAMPLERS,
                        pixel_states_sampler[i], This->samplerState[j][pixel_states_sampler[i]]);
            }
        }
    } else if(This->blockType == WINED3DSBT_ALL) {
        IWineD3DDevice_SetVertexShader(pDevice, This->vertexShader);
        for (i = 0; i < GL_LIMITS(vshader_constantsF); i++) {
            IWineD3DDevice_SetVertexShaderConstantF(pDevice, i,
                    This->vertexShaderConstantF + i * 4, 1);
        }
        for (i = 0; i < MAX_CONST_I; i++) {
            IWineD3DDevice_SetVertexShaderConstantI(pDevice, i,
                    This->vertexShaderConstantI + i * 4, 1);
        }
        for (i = 0; i < MAX_CONST_B; i++) {
            IWineD3DDevice_SetVertexShaderConstantB(pDevice, i,
                    This->vertexShaderConstantB + i, 1);
        }

        IWineD3DDevice_SetPixelShader(pDevice, This->pixelShader);
        for (i = 0; i < GL_LIMITS(pshader_constantsF); i++) {
            IWineD3DDevice_SetPixelShaderConstantF(pDevice, i,
                    This->pixelShaderConstantF + i * 4, 1);
        }
        for (i = 0; i < MAX_CONST_I; i++) {
            IWineD3DDevice_SetPixelShaderConstantI(pDevice, i,
                    This->pixelShaderConstantI + i * 4, 1);
        }
        for (i = 0; i < MAX_CONST_B; i++) {
            IWineD3DDevice_SetPixelShaderConstantB(pDevice, i,
                    This->pixelShaderConstantB + i, 1);
        }

        apply_lights(pDevice, This);

        for(i = 1; i <= WINEHIGHEST_RENDER_STATE; i++) {
            IWineD3DDevice_SetRenderState(pDevice, i, This->renderState[i]);
        }
        for(j = 0; j < MAX_TEXTURES; j++) {
            for (i = 0; i <= WINED3D_HIGHEST_TEXTURE_STATE; ++i)
            {
                IWineD3DDevice_SetTextureStageState(pDevice, j, i, This->textureState[j][i]);
            }
        }

        /* Skip unused values between TEXTURE8 and WORLD0 ? */
        for(i = 1; i <= HIGHEST_TRANSFORMSTATE; i++) {
            IWineD3DDevice_SetTransform(pDevice, i, &This->transforms[i]);
        }
        This->wineD3DDevice->updateStateBlock->gl_primitive_type = This->gl_primitive_type;
        IWineD3DDevice_SetIndexBuffer(pDevice, This->pIndexData, This->IndexFmt);
        IWineD3DDevice_SetBaseVertexIndex(pDevice, This->baseVertexIndex);
        IWineD3DDevice_SetVertexDeclaration(pDevice, This->vertexDecl);
        IWineD3DDevice_SetMaterial(pDevice, &This->material);
        IWineD3DDevice_SetViewport(pDevice, &This->viewport);
        IWineD3DDevice_SetScissorRect(pDevice, &This->scissorRect);

        /* TODO: Proper implementation using SetStreamSource offset (set to 0 for the moment)\n") */
        for (i=0; i<MAX_STREAMS; i++) {
            IWineD3DDevice_SetStreamSource(pDevice, i, This->streamSource[i], 0, This->streamStride[i]);
            IWineD3DDevice_SetStreamSourceFreq(pDevice, i, This->streamFreq[i] | This->streamFlags[i]);
        }
        for (j = 0 ; j < MAX_COMBINED_SAMPLERS; j++){
            UINT sampler = j < MAX_FRAGMENT_SAMPLERS ? j : WINED3DVERTEXTEXTURESAMPLER0 + j - MAX_FRAGMENT_SAMPLERS;

            IWineD3DDevice_SetTexture(pDevice, sampler, This->textures[j]);
            for (i = 1; i <= WINED3D_HIGHEST_SAMPLER_STATE; ++i)
            {
                IWineD3DDevice_SetSamplerState(pDevice, sampler, i, This->samplerState[j][i]);
            }
        }
        for (i = 0; i < GL_LIMITS(clipplanes); i++) {
            float clip[4];

            clip[0] = This->clipplane[i][0];
            clip[1] = This->clipplane[i][1];
            clip[2] = This->clipplane[i][2];
            clip[3] = This->clipplane[i][3];
            IWineD3DDevice_SetClipPlane(pDevice, i, clip);
        }
    }

    ((IWineD3DDeviceImpl *)pDevice)->stateBlock->lowest_disabled_stage = MAX_TEXTURES - 1;
    for(j = 0; j < MAX_TEXTURES - 1; j++) {
        if(((IWineD3DDeviceImpl *)pDevice)->stateBlock->textureState[j][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
            ((IWineD3DDeviceImpl *)pDevice)->stateBlock->lowest_disabled_stage = j;
            break;
        }
    }
    TRACE("(%p) : Applied state block %p ------------------^\n", This, pDevice);

    return WINED3D_OK;
}

static HRESULT  WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStateBlock* iface) {
    IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
    IWineD3DDevice         *device = (IWineD3DDevice *)This->wineD3DDevice;
    IWineD3DDeviceImpl     *ThisDevice = (IWineD3DDeviceImpl *)device;
    union {
        WINED3DLINEPATTERN lp;
        DWORD d;
    } lp;
    union {
        float f;
        DWORD d;
    } tmpfloat;
    unsigned int i;
    IWineD3DSwapChain *swapchain;
    IWineD3DSurface *backbuffer;
    HRESULT hr;

    /* Note this may have a large overhead but it should only be executed
       once, in order to initialize the complete state of the device and
       all opengl equivalents                                            */
    TRACE("(%p) -----------------------> Setting up device defaults... %p\n", This, This->wineD3DDevice);
    /* TODO: make a special stateblock type for the primary stateblock (it never gets applied so it doesn't need a real type) */
    This->blockType = WINED3DSBT_INIT;

    /* Set some of the defaults for lights, transforms etc */
    memcpy(&This->transforms[WINED3DTS_PROJECTION], identity, sizeof(identity));
    memcpy(&This->transforms[WINED3DTS_VIEW], identity, sizeof(identity));
    for (i = 0; i < 256; ++i) {
      memcpy(&This->transforms[WINED3DTS_WORLDMATRIX(i)], identity, sizeof(identity));
    }

    TRACE("Render states\n");
    /* Render states: */
    if (ThisDevice->auto_depth_stencil_buffer != NULL) {
       IWineD3DDevice_SetRenderState(device, WINED3DRS_ZENABLE,       WINED3DZB_TRUE);
    } else {
       IWineD3DDevice_SetRenderState(device, WINED3DRS_ZENABLE,       WINED3DZB_FALSE);
    }
    IWineD3DDevice_SetRenderState(device, WINED3DRS_FILLMODE,         WINED3DFILL_SOLID);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_SHADEMODE,        WINED3DSHADE_GOURAUD);
    lp.lp.wRepeatFactor = 0;
    lp.lp.wLinePattern  = 0;
    IWineD3DDevice_SetRenderState(device, WINED3DRS_LINEPATTERN,      lp.d);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_ZWRITEENABLE,     TRUE);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_ALPHATESTENABLE,  FALSE);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_LASTPIXEL,        TRUE);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_SRCBLEND,         WINED3DBLEND_ONE);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_DESTBLEND,        WINED3DBLEND_ZERO);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_CULLMODE,         WINED3DCULL_CCW);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_ZFUNC,            WINED3DCMP_LESSEQUAL);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_ALPHAFUNC,        WINED3DCMP_ALWAYS);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_ALPHAREF,         0);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_DITHERENABLE,     FALSE);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_ALPHABLENDENABLE, FALSE);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGENABLE,        FALSE);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_SPECULARENABLE,   FALSE);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_ZVISIBLE,         0);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGCOLOR,         0);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGTABLEMODE,     WINED3DFOG_NONE);
    tmpfloat.f = 0.0f;
    IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGSTART,         tmpfloat.d);
    tmpfloat.f = 1.0f;
    IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGEND,           tmpfloat.d);
    tmpfloat.f = 1.0f;
    IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGDENSITY,       tmpfloat.d);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_EDGEANTIALIAS,    FALSE);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_ZBIAS,            0);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_RANGEFOGENABLE,   FALSE);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILENABLE,    FALSE);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILFAIL,      WINED3DSTENCILOP_KEEP);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILZFAIL,     WINED3DSTENCILOP_KEEP);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILPASS,      WINED3DSTENCILOP_KEEP);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILREF,       0);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILMASK,      0xFFFFFFFF);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILFUNC,      WINED3DCMP_ALWAYS);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILWRITEMASK, 0xFFFFFFFF);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_TEXTUREFACTOR,    0xFFFFFFFF);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP0, 0);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP1, 0);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP2, 0);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP3, 0);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP4, 0);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP5, 0);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP6, 0);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP7, 0);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_CLIPPING,                 TRUE);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_LIGHTING,                 TRUE);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_AMBIENT,                  0);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGVERTEXMODE,            WINED3DFOG_NONE);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_COLORVERTEX,              TRUE);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_LOCALVIEWER,              TRUE);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_NORMALIZENORMALS,         FALSE);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_DIFFUSEMATERIALSOURCE,    WINED3DMCS_COLOR1);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_SPECULARMATERIALSOURCE,   WINED3DMCS_COLOR2);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_AMBIENTMATERIALSOURCE,    WINED3DMCS_MATERIAL);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_EMISSIVEMATERIALSOURCE,   WINED3DMCS_MATERIAL);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_VERTEXBLEND,              WINED3DVBF_DISABLE);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_CLIPPLANEENABLE,          0);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
    tmpfloat.f = 1.0f;
    IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSIZE,                tmpfloat.d);
    tmpfloat.f = ((IWineD3DImpl *)This->wineD3DDevice->wineD3D)->dxVersion < 9 ? 0.0f : 1.0f;
    IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSIZE_MIN,            tmpfloat.d);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSPRITEENABLE,        FALSE);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSCALEENABLE,         FALSE);
    tmpfloat.f = 1.0f;
    IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSCALE_A,             tmpfloat.d);
    tmpfloat.f = 0.0f;
    IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSCALE_B,             tmpfloat.d);
    tmpfloat.f = 0.0f;
    IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSCALE_C,             tmpfloat.d);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_MULTISAMPLEANTIALIAS,     TRUE);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_MULTISAMPLEMASK,          0xFFFFFFFF);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_PATCHEDGESTYLE,           WINED3DPATCHEDGE_DISCRETE);
    tmpfloat.f = 1.0f;
    IWineD3DDevice_SetRenderState(device, WINED3DRS_PATCHSEGMENTS,            tmpfloat.d);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_DEBUGMONITORTOKEN,        0xbaadcafe);
    tmpfloat.f = GL_LIMITS(pointsize);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSIZE_MAX,            tmpfloat.d);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_COLORWRITEENABLE,         0x0000000F);
    tmpfloat.f = 0.0f;
    IWineD3DDevice_SetRenderState(device, WINED3DRS_TWEENFACTOR,              tmpfloat.d);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_BLENDOP,                  WINED3DBLENDOP_ADD);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_POSITIONDEGREE,           WINED3DDEGREE_CUBIC);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_NORMALDEGREE,             WINED3DDEGREE_LINEAR);
    /* states new in d3d9 */
    IWineD3DDevice_SetRenderState(device, WINED3DRS_SCISSORTESTENABLE,        FALSE);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_SLOPESCALEDEPTHBIAS,      0);
    tmpfloat.f = 1.0f;
    IWineD3DDevice_SetRenderState(device, WINED3DRS_MINTESSELLATIONLEVEL,     tmpfloat.d);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_MAXTESSELLATIONLEVEL,     tmpfloat.d);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_ANTIALIASEDLINEENABLE,    FALSE);
    tmpfloat.f = 0.0f;
    IWineD3DDevice_SetRenderState(device, WINED3DRS_ADAPTIVETESS_X,           tmpfloat.d);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_ADAPTIVETESS_Y,           tmpfloat.d);
    tmpfloat.f = 1.0f;
    IWineD3DDevice_SetRenderState(device, WINED3DRS_ADAPTIVETESS_Z,           tmpfloat.d);
    tmpfloat.f = 0.0f;
    IWineD3DDevice_SetRenderState(device, WINED3DRS_ADAPTIVETESS_W,           tmpfloat.d);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_ENABLEADAPTIVETESSELLATION, FALSE);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_TWOSIDEDSTENCILMODE,      FALSE);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_CCW_STENCILFAIL,          WINED3DSTENCILOP_KEEP);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_CCW_STENCILZFAIL,         WINED3DSTENCILOP_KEEP);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_CCW_STENCILPASS,          WINED3DSTENCILOP_KEEP);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_CCW_STENCILFUNC,          WINED3DCMP_ALWAYS);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_COLORWRITEENABLE1,        0x0000000F);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_COLORWRITEENABLE2,        0x0000000F);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_COLORWRITEENABLE3,        0x0000000F);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_BLENDFACTOR,              0xFFFFFFFF);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_SRGBWRITEENABLE,          0);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_DEPTHBIAS,                0);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP8,  0);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP9,  0);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP10, 0);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP11, 0);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP12, 0);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP13, 0);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP14, 0);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP15, 0);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_SEPARATEALPHABLENDENABLE, FALSE);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_SRCBLENDALPHA,            WINED3DBLEND_ONE);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_DESTBLENDALPHA,           WINED3DBLEND_ZERO);
    IWineD3DDevice_SetRenderState(device, WINED3DRS_BLENDOPALPHA,             WINED3DBLENDOP_ADD);

    /* clipping status */
    This->clip_status.ClipUnion = 0;
    This->clip_status.ClipIntersection = 0xFFFFFFFF;

    /* Texture Stage States - Put directly into state block, we will call function below */
    for (i = 0; i < MAX_TEXTURES; i++) {
        TRACE("Setting up default texture states for texture Stage %d\n", i);
        memcpy(&This->transforms[WINED3DTS_TEXTURE0 + i], identity, sizeof(identity));
        This->textureState[i][WINED3DTSS_COLOROP               ] = (i==0)? WINED3DTOP_MODULATE :  WINED3DTOP_DISABLE;
        This->textureState[i][WINED3DTSS_COLORARG1             ] = WINED3DTA_TEXTURE;
        This->textureState[i][WINED3DTSS_COLORARG2             ] = WINED3DTA_CURRENT;
        This->textureState[i][WINED3DTSS_ALPHAOP               ] = (i==0)? WINED3DTOP_SELECTARG1 :  WINED3DTOP_DISABLE;
        This->textureState[i][WINED3DTSS_ALPHAARG1             ] = WINED3DTA_TEXTURE;
        This->textureState[i][WINED3DTSS_ALPHAARG2             ] = WINED3DTA_CURRENT;
        This->textureState[i][WINED3DTSS_BUMPENVMAT00          ] = 0;
        This->textureState[i][WINED3DTSS_BUMPENVMAT01          ] = 0;
        This->textureState[i][WINED3DTSS_BUMPENVMAT10          ] = 0;
        This->textureState[i][WINED3DTSS_BUMPENVMAT11          ] = 0;
        This->textureState[i][WINED3DTSS_TEXCOORDINDEX         ] = i;
        This->textureState[i][WINED3DTSS_BUMPENVLSCALE         ] = 0;
        This->textureState[i][WINED3DTSS_BUMPENVLOFFSET        ] = 0;
        This->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS ] = WINED3DTTFF_DISABLE;
        This->textureState[i][WINED3DTSS_COLORARG0             ] = WINED3DTA_CURRENT;
        This->textureState[i][WINED3DTSS_ALPHAARG0             ] = WINED3DTA_CURRENT;
        This->textureState[i][WINED3DTSS_RESULTARG             ] = WINED3DTA_CURRENT;
    }
    This->lowest_disabled_stage = 1;

        /* Sampler states*/
    for (i = 0 ; i <  MAX_COMBINED_SAMPLERS; i++) {
        TRACE("Setting up default samplers states for sampler %d\n", i);
        This->samplerState[i][WINED3DSAMP_ADDRESSU         ] = WINED3DTADDRESS_WRAP;
        This->samplerState[i][WINED3DSAMP_ADDRESSV         ] = WINED3DTADDRESS_WRAP;
        This->samplerState[i][WINED3DSAMP_ADDRESSW         ] = WINED3DTADDRESS_WRAP;
        This->samplerState[i][WINED3DSAMP_BORDERCOLOR      ] = 0x00;
        This->samplerState[i][WINED3DSAMP_MAGFILTER        ] = WINED3DTEXF_POINT;
        This->samplerState[i][WINED3DSAMP_MINFILTER        ] = WINED3DTEXF_POINT;
        This->samplerState[i][WINED3DSAMP_MIPFILTER        ] = WINED3DTEXF_NONE;
        This->samplerState[i][WINED3DSAMP_MIPMAPLODBIAS    ] = 0;
        This->samplerState[i][WINED3DSAMP_MAXMIPLEVEL      ] = 0;
        This->samplerState[i][WINED3DSAMP_MAXANISOTROPY    ] = 1;
        This->samplerState[i][WINED3DSAMP_SRGBTEXTURE      ] = 0;
        This->samplerState[i][WINED3DSAMP_ELEMENTINDEX     ] = 0; /* TODO: Indicates which element of a  multielement texture to use */
        This->samplerState[i][WINED3DSAMP_DMAPOFFSET       ] = 0; /* TODO: Vertex offset in the presampled displacement map */
    }

    for(i = 0; i < GL_LIMITS(textures); i++) {
        /* Note: This avoids calling SetTexture, so pretend it has been called */
        This->changed.textures |= 1 << i;
        This->textures[i]         = NULL;
    }

    /* check the return values, because the GetBackBuffer call isn't valid for ddraw */
    hr = IWineD3DDevice_GetSwapChain(device, 0, &swapchain);
    if( hr == WINED3D_OK && swapchain != NULL) {
        WINED3DVIEWPORT vp;

        hr = IWineD3DSwapChain_GetBackBuffer(swapchain, 0, WINED3DBACKBUFFER_TYPE_MONO, &backbuffer);
        if (SUCCEEDED(hr) && backbuffer)
        {
            WINED3DSURFACE_DESC desc;
            RECT scissorrect;

            IWineD3DSurface_GetDesc(backbuffer, &desc);
            IWineD3DSurface_Release(backbuffer);

            /* Set the default scissor rect values */
            scissorrect.left = 0;
            scissorrect.right = desc.width;
            scissorrect.top = 0;
            scissorrect.bottom = desc.height;
            hr = IWineD3DDevice_SetScissorRect(device, &scissorrect);
            if (FAILED(hr)) ERR("This should never happen, expect rendering issues!\n");
        }

        /* Set the default viewport */
        vp.X      = 0;
        vp.Y      = 0;
        vp.Width  = ((IWineD3DSwapChainImpl *)swapchain)->presentParms.BackBufferWidth;
        vp.Height = ((IWineD3DSwapChainImpl *)swapchain)->presentParms.BackBufferHeight;
        vp.MinZ   = 0.0f;
        vp.MaxZ   = 1.0f;
        IWineD3DDevice_SetViewport(device, &vp);

        IWineD3DSwapChain_Release(swapchain);
    }

    TRACE("-----------------------> Device defaults now set up...\n");
    return WINED3D_OK;
}

/**********************************************************
 * IWineD3DStateBlock VTbl follows
 **********************************************************/

static const IWineD3DStateBlockVtbl IWineD3DStateBlock_Vtbl =
{
    /* IUnknown */
    IWineD3DStateBlockImpl_QueryInterface,
    IWineD3DStateBlockImpl_AddRef,
    IWineD3DStateBlockImpl_Release,
    /* IWineD3DStateBlock */
    IWineD3DStateBlockImpl_GetParent,
    IWineD3DStateBlockImpl_GetDevice,
    IWineD3DStateBlockImpl_Capture,
    IWineD3DStateBlockImpl_Apply,
    IWineD3DStateBlockImpl_InitStartupStateBlock
};

HRESULT stateblock_init(IWineD3DStateBlockImpl *stateblock, IWineD3DDeviceImpl *device,
        WINED3DSTATEBLOCKTYPE type, IUnknown *parent)
{
    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
    unsigned int i;
    HRESULT hr;

    stateblock->lpVtbl = &IWineD3DStateBlock_Vtbl;
    stateblock->ref = 1;
    stateblock->parent = parent;
    stateblock->wineD3DDevice = device;
    stateblock->blockType = type;

    for (i = 0; i < LIGHTMAP_SIZE; i++)
    {
        list_init(&stateblock->lightMap[i]);
    }

    hr = stateblock_allocate_shader_constants(stateblock);
    if (FAILED(hr)) return hr;

    /* The WINED3DSBT_INIT stateblock type is used during initialization to
     * produce a placeholder stateblock so other functions called can update a
     * state block. */
    if (type == WINED3DSBT_INIT || type == WINED3DSBT_RECORDED) return WINED3D_OK;

    /* Otherwise, might as well set the whole state block to the appropriate values  */
    if (device->stateBlock)
    {
        /* Saved values */
        stateblock_copy_values(stateblock, device->stateBlock, gl_info);
    }
    else
    {
        memset(stateblock->streamFreq, 1, sizeof(stateblock->streamFreq));
    }

    TRACE("Updating changed flags appropriate for type %#x.\n", type);

    if (type == WINED3DSBT_ALL)
    {
        TRACE("ALL => Pretend everything has changed.\n");

        stateblock_savedstates_set_all(&stateblock->changed, gl_info);
        stateblock_init_contained_states(stateblock);

        /* Lights are not part of the changed / set structure. */
        for (i = 0; i < LIGHTMAP_SIZE; ++i)
        {
            struct list *e;
            LIST_FOR_EACH(e, &stateblock->lightMap[i])
            {
                PLIGHTINFOEL *light = LIST_ENTRY(e, PLIGHTINFOEL, entry);
                light->changed = TRUE;
                light->enabledChanged = TRUE;
            }
        }

        for (i = 0; i < MAX_STREAMS; ++i)
        {
            if (stateblock->streamSource[i]) IWineD3DBuffer_AddRef(stateblock->streamSource[i]);
        }

        for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
        {
            if (stateblock->textures[i]) IWineD3DBaseTexture_AddRef(stateblock->textures[i]);
        }

        if (stateblock->vertexDecl) IWineD3DVertexDeclaration_AddRef(stateblock->vertexDecl);
        if (stateblock->pIndexData) IWineD3DBuffer_AddRef(stateblock->pIndexData);
        if (stateblock->vertexShader) IWineD3DVertexShader_AddRef(stateblock->vertexShader);
        if (stateblock->pixelShader) IWineD3DPixelShader_AddRef(stateblock->pixelShader);
    }
    else if (type == WINED3DSBT_PIXELSTATE)
    {
        TRACE("PIXELSTATE => Pretend all pixel states have changed.\n");

        stateblock_savedstates_set_pixel(&stateblock->changed, gl_info);
        stateblock_init_contained_states(stateblock);

        if (stateblock->pixelShader) IWineD3DPixelShader_AddRef(stateblock->pixelShader);

        /* Pixel state blocks do not contain vertex buffers. Set them to NULL
         * to avoid wrong refcounting on them. This makes releasing the buffer
         * easier. */
        for (i = 0; i < MAX_STREAMS; ++i)
        {
            stateblock->streamSource[i] = NULL;
        }

        for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
        {
            stateblock->textures[i] = NULL;
        }

        stateblock->vertexDecl = NULL;
        stateblock->pIndexData = NULL;
        stateblock->vertexShader = NULL;
    }
    else if (type == WINED3DSBT_VERTEXSTATE)
    {
        TRACE("VERTEXSTATE => Pretend all vertex shates have changed.\n");

        stateblock_savedstates_set_vertex(&stateblock->changed, gl_info);
        stateblock_init_contained_states(stateblock);

        for (i = 0; i < LIGHTMAP_SIZE; ++i)
        {
            struct list *e;
            LIST_FOR_EACH(e, &stateblock->lightMap[i])
            {
                PLIGHTINFOEL *light = LIST_ENTRY(e, PLIGHTINFOEL, entry);
                light->changed = TRUE;
                light->enabledChanged = TRUE;
            }
        }

        for (i = 0; i < MAX_STREAMS; ++i)
        {
            if (stateblock->streamSource[i]) IWineD3DBuffer_AddRef(stateblock->streamSource[i]);
        }

        for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
        {
            stateblock->textures[i] = NULL;
        }

        if (stateblock->vertexShader) IWineD3DVertexShader_AddRef(stateblock->vertexShader);

        stateblock->vertexDecl = NULL;
        stateblock->pIndexData = NULL;
        stateblock->pixelShader = NULL;
    }
    else
    {
        FIXME("Unrecognized state block type %#x.\n", type);
    }

    return WINED3D_OK;
}
