d3d9/tests: Make d3d9 tests Wcast-qual compliant.
[wine] / dlls / d3d8 / device.c
index 75f3b41..5adc2db 100644 (file)
@@ -1,7 +1,8 @@
 /*
  * IDirect3DDevice8 implementation
  *
- * Copyright 2002 Jason Edmeades
+ * Copyright 2002-2004 Jason Edmeades
+ * Copyright 2004 Christian Costa
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -15,7 +16,7 @@
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
 #include "config.h"
 #include "wingdi.h"
 #include "wine/debug.h"
 
-/** define  GL_GLEXT_PROTOTYPES for having extensions prototypes defined */
-/*#define GL_GLEXT_PROTOTYPES*/
-/*#undef  GLX_GLXEXT_LEGACY*/
 #include "d3d8_private.h"
 
-/** currently desactiving 1_4 support as mesa doesn't implement all 1_4 support while defining it */
-#undef GL_VERSION_1_4
+WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
 
-WINE_DEFAULT_DEBUG_CHANNEL(d3d);
-WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
-WINE_DECLARE_DEBUG_CHANNEL(fps);
-
-IDirect3DVertexShaderImpl*            VertexShaders[64];
-IDirect3DVertexShaderDeclarationImpl* VertexShaderDeclarations[64];
-IDirect3DPixelShaderImpl*             PixelShaders[64];
-
-/* Debugging aids: */
-#ifdef FRAME_DEBUGGING
-BOOL isOn             = FALSE;
-BOOL isDumpingFrames  = FALSE;
-LONG primCounter      = 0;
-#endif
-
-/*
- * Utility functions or macros
- */
-#define conv_mat(mat,gl_mat)                                                                \
-do {                                                                                        \
-    TRACE("%f %f %f %f\n", (mat)->u.s._11, (mat)->u.s._12, (mat)->u.s._13, (mat)->u.s._14); \
-    TRACE("%f %f %f %f\n", (mat)->u.s._21, (mat)->u.s._22, (mat)->u.s._23, (mat)->u.s._24); \
-    TRACE("%f %f %f %f\n", (mat)->u.s._31, (mat)->u.s._32, (mat)->u.s._33, (mat)->u.s._34); \
-    TRACE("%f %f %f %f\n", (mat)->u.s._41, (mat)->u.s._42, (mat)->u.s._43, (mat)->u.s._44); \
-    memcpy(gl_mat, (mat), 16 * sizeof(float));                                              \
-} while (0)
-
-/* Apply the current values to the specified texture stage */
-void setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage, DWORD Flags) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    int i = 0;
-    float col[4];
-    BOOL changeTexture = TRUE;
-
-    TRACE("-----------------------> Updating the texture at stage %ld to have new texture state information\n", Stage);
-    for (i = 1; i < HIGHEST_TEXTURE_STATE; i++) {
-
-        BOOL skip = FALSE;
-
-        switch (i) {
-        /* Performance: For texture states where multiples effect the outcome, only bother
-              applying the last one as it will pick up all the other values                */
-        case D3DTSS_COLORARG0:  /* Will be picked up when setting color op */
-        case D3DTSS_COLORARG1:  /* Will be picked up when setting color op */
-        case D3DTSS_COLORARG2:  /* Will be picked up when setting color op */
-        case D3DTSS_ALPHAARG0:  /* Will be picked up when setting alpha op */
-        case D3DTSS_ALPHAARG1:  /* Will be picked up when setting alpha op */
-        case D3DTSS_ALPHAARG2:  /* Will be picked up when setting alpha op */
-           skip = TRUE;
-           break;
-
-        /* Performance: If the texture states only impact settings for the texture unit 
-             (compared to the texture object) then there is no need to reapply them. The
-             only time they need applying is the first time, since we cheat and put the  
-             values into the stateblock without applying.                                
-             Per-texture unit: texture function (eg. combine), ops and args
-                               texture env color                                               
-                               texture generation settings                               
-           Note: Due to some special conditions there may be a need to do particular ones
-             of these, which is what the Flags allows                                     */
-        case D3DTSS_COLOROP:       
-        case D3DTSS_TEXCOORDINDEX:
-            if (!(Flags == REAPPLY_ALL)) skip=TRUE;
-            break;
-
-        case D3DTSS_ALPHAOP:       
-            if (!(Flags & REAPPLY_ALPHAOP)) skip=TRUE;
-            break;
-
-        default:
-            skip = FALSE;
-        }
-
-        if (skip == FALSE) {
-           /* Performance: Only change to this texture if we have to */
-           if (changeTexture) {
-               /* Make appropriate texture active */
-               if (GL_SUPPORT(ARB_MULTITEXTURE)) {
-#if defined(GL_VERSION_1_3)
-                   glActiveTexture(GL_TEXTURE0 + Stage);
-#else
-                   glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
-#endif
-                   checkGLcall("glActiveTextureARB");
-                } else if (Stage > 0) {
-                    FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
-                }
-                changeTexture = FALSE;
-           }
-
-           /* Now apply the change */
-           IDirect3DDevice8Impl_SetTextureStageState(iface, Stage, i, This->StateBlock->texture_state[Stage][i]);
-        }
+/* Shader handle functions */
+static shader_handle *alloc_shader_handle(IDirect3DDevice8Impl *This) {
+    if (This->free_shader_handles) {
+        /* Use a free handle */
+        shader_handle *handle = This->free_shader_handles;
+        This->free_shader_handles = *handle;
+        return handle;
     }
-
-    /* Note the D3DRS value applies to all textures, but GL has one
-     *  per texture, so apply it now ready to be used!
-     */
-    D3DCOLORTOGLFLOAT4(This->StateBlock->renderstate[D3DRS_TEXTUREFACTOR], col);
-    glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
-    checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
-
-    TRACE("-----------------------> Updated the texture at stage %ld to have new texture state information\n", Stage);
-}
-
-/* Convert the D3DLIGHT8 properties into equivalent gl lights */
-void setup_light(LPDIRECT3DDEVICE8 iface, LONG Index, PLIGHTINFOEL *lightInfo) {
-
-    float quad_att;
-    float colRGBA[] = {0.0, 0.0, 0.0, 0.0};
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-
-    /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
-    glMatrixMode(GL_MODELVIEW);
-    glPushMatrix();
-    glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
-
-    /* Diffuse: */
-    colRGBA[0] = lightInfo->OriginalParms.Diffuse.r;
-    colRGBA[1] = lightInfo->OriginalParms.Diffuse.g;
-    colRGBA[2] = lightInfo->OriginalParms.Diffuse.b;
-    colRGBA[3] = lightInfo->OriginalParms.Diffuse.a;
-    glLightfv(GL_LIGHT0+Index, GL_DIFFUSE, colRGBA);
-    checkGLcall("glLightfv");
-
-    /* Specular */
-    colRGBA[0] = lightInfo->OriginalParms.Specular.r;
-    colRGBA[1] = lightInfo->OriginalParms.Specular.g;
-    colRGBA[2] = lightInfo->OriginalParms.Specular.b;
-    colRGBA[3] = lightInfo->OriginalParms.Specular.a;
-    glLightfv(GL_LIGHT0+Index, GL_SPECULAR, colRGBA);
-    checkGLcall("glLightfv");
-
-    /* Ambient */
-    colRGBA[0] = lightInfo->OriginalParms.Ambient.r;
-    colRGBA[1] = lightInfo->OriginalParms.Ambient.g;
-    colRGBA[2] = lightInfo->OriginalParms.Ambient.b;
-    colRGBA[3] = lightInfo->OriginalParms.Ambient.a;
-    glLightfv(GL_LIGHT0+Index, GL_AMBIENT, colRGBA);
-    checkGLcall("glLightfv");
-
-    /* Attenuation - Are these right? guessing... */
-    glLightf(GL_LIGHT0+Index, GL_CONSTANT_ATTENUATION,  lightInfo->OriginalParms.Attenuation0);
-    checkGLcall("glLightf");
-    glLightf(GL_LIGHT0+Index, GL_LINEAR_ATTENUATION,    lightInfo->OriginalParms.Attenuation1);
-    checkGLcall("glLightf");
-
-    quad_att = 1.4/(lightInfo->OriginalParms.Range*lightInfo->OriginalParms.Range);
-    if (quad_att < lightInfo->OriginalParms.Attenuation2) quad_att = lightInfo->OriginalParms.Attenuation2;
-    glLightf(GL_LIGHT0+Index, GL_QUADRATIC_ATTENUATION, quad_att);
-    checkGLcall("glLightf");
-
-    switch (lightInfo->OriginalParms.Type) {
-    case D3DLIGHT_POINT:
-        /* Position */
-        glLightfv(GL_LIGHT0+Index, GL_POSITION, &lightInfo->lightPosn[0]);
-        checkGLcall("glLightfv");
-        glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
-        checkGLcall("glLightf");
-        /* FIXME: Range */
-        break;
-
-    case D3DLIGHT_SPOT:
-        /* Position */
-        glLightfv(GL_LIGHT0+Index, GL_POSITION, &lightInfo->lightPosn[0]);
-        checkGLcall("glLightfv");
-        /* Direction */
-        glLightfv(GL_LIGHT0+Index, GL_SPOT_DIRECTION, &lightInfo->lightDirn[0]);
-        checkGLcall("glLightfv");
-        glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, lightInfo->exponent);
-        checkGLcall("glLightf");
-        glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
-        checkGLcall("glLightf");
-        /* FIXME: Range */
-        break;
-
-    case D3DLIGHT_DIRECTIONAL:
-        /* Direction */
-        glLightfv(GL_LIGHT0+Index, GL_POSITION, &lightInfo->lightPosn[0]); /* Note gl uses w position of 0 for direction! */
-        checkGLcall("glLightfv");
-        glLightf(GL_LIGHT0+Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
-        checkGLcall("glLightf");
-        glLightf(GL_LIGHT0+Index, GL_SPOT_EXPONENT, 0.0f);
-        checkGLcall("glLightf");
-        break;
-
-    default:
-        FIXME("Unrecognized light type %d\n", lightInfo->OriginalParms.Type);
+    if (!(This->allocated_shader_handles < This->shader_handle_table_size)) {
+        /* Grow the table */
+        DWORD new_size = This->shader_handle_table_size + (This->shader_handle_table_size >> 1);
+        shader_handle *new_handles = HeapReAlloc(GetProcessHeap(), 0, This->shader_handles, new_size * sizeof(shader_handle));
+        if (!new_handles) return NULL;
+        This->shader_handles = new_handles;
+        This->shader_handle_table_size = new_size;
     }
 
-    /* Restore the modelview matrix */
-    glPopMatrix();
+    return &This->shader_handles[This->allocated_shader_handles++];
 }
 
-/* Setup this textures matrix */
-static void set_texture_matrix(float *smat, DWORD flags)
-{
-    float mat[16];
-
-    glMatrixMode(GL_TEXTURE);
-
-    if (flags == D3DTTFF_DISABLE) {
-        glLoadIdentity();
-        checkGLcall("glLoadIdentity()");
-        return;
-    }
-
-    if (flags == (D3DTTFF_COUNT1|D3DTTFF_PROJECTED)) {
-        ERR("Invalid texture transform flags: D3DTTFF_COUNT1|D3DTTFF_PROJECTED\n");
-        checkGLcall("glLoadIdentity()");
-        return;
-    }
-
-    memcpy(mat, smat, 16*sizeof(float));
-
-    switch (flags & ~D3DTTFF_PROJECTED) {
-    case D3DTTFF_COUNT1: mat[1] = mat[5] = mat[9] = mat[13] = 0;
-    case D3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
-    default: mat[3] = mat[7] = mat[11] = 0, mat[15] = 1;
-    }
-    
-    if (flags & D3DTTFF_PROJECTED) switch (flags & ~D3DTTFF_PROJECTED) {
-    case D3DTTFF_COUNT2:
-        mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
-        mat[1] = mat[5] = mat[9] = mat[13] = 0;
-        break;
-    case D3DTTFF_COUNT3:
-        mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
-        mat[2] = mat[6] = mat[10] = mat[14] = 0;
-        break;
-    }
-    glLoadMatrixf(mat);
-    checkGLcall("glLoadMatrixf(mat)");
+static void free_shader_handle(IDirect3DDevice8Impl *This, shader_handle *handle) {
+    *handle = This->free_shader_handles;
+    This->free_shader_handles = handle;
 }
 
 /* IDirect3D IUnknown parts follow: */
-HRESULT WINAPI IDirect3DDevice8Impl_QueryInterface(LPDIRECT3DDEVICE8 iface,REFIID riid,LPVOID *ppobj)
+static HRESULT WINAPI IDirect3DDevice8Impl_QueryInterface(LPDIRECT3DDEVICE8 iface,REFIID riid,LPVOID *ppobj)
 {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
 
     if (IsEqualGUID(riid, &IID_IUnknown)
         || IsEqualGUID(riid, &IID_IDirect3DDevice8)) {
-        IDirect3DDevice8Impl_AddRef(iface);
+        IUnknown_AddRef(iface);
         *ppobj = This;
-        return D3D_OK;
+        return S_OK;
     }
 
-    WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
+    WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
+    *ppobj = NULL;
     return E_NOINTERFACE;
 }
 
-ULONG WINAPI IDirect3DDevice8Impl_AddRef(LPDIRECT3DDEVICE8 iface) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    TRACE("(%p) : AddRef from %ld\n", This, This->ref);
-    return ++(This->ref);
+static ULONG WINAPI IDirect3DDevice8Impl_AddRef(LPDIRECT3DDEVICE8 iface) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    ULONG ref = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p) : AddRef from %ld\n", This, ref - 1);
+
+    return ref;
 }
 
-ULONG WINAPI IDirect3DDevice8Impl_Release(LPDIRECT3DDEVICE8 iface) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    ULONG ref = --This->ref;
-    TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref);
+static ULONG WINAPI IDirect3DDevice8Impl_Release(LPDIRECT3DDEVICE8 iface) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    ULONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p) : ReleaseRef to %ld\n", This, ref);
+
     if (ref == 0) {
-      IDirect3DDevice8Impl_CleanRender(iface);
-      HeapFree(GetProcessHeap(), 0, This);
+        TRACE("Releasing wined3d device %p\n", This->WineD3DDevice);
+        IWineD3DDevice_Uninit3D(This->WineD3DDevice);
+        IWineD3DDevice_Release(This->WineD3DDevice);
+        HeapFree(GetProcessHeap(), 0, This->shader_handles);
+        HeapFree(GetProcessHeap(), 0, This);
     }
     return ref;
 }
 
 /* IDirect3DDevice Interface follow: */
-HRESULT  WINAPI  IDirect3DDevice8Impl_TestCooperativeLevel(LPDIRECT3DDEVICE8 iface) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    TRACE("(%p) : stub\n", This);    /* No way of notifying yet! */
-    return D3D_OK;
-}
-
-UINT     WINAPI  IDirect3DDevice8Impl_GetAvailableTextureMem(LPDIRECT3DDEVICE8 iface) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    TRACE("(%p) : stub, emulating 32Mb for now\n", This);
-    /*
-     * pretend we have 32MB of any type of memory queried.
-     */
-    return (1024*1024*32);
-}
+static HRESULT WINAPI IDirect3DDevice8Impl_TestCooperativeLevel(LPDIRECT3DDEVICE8 iface) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
 
-HRESULT  WINAPI  IDirect3DDevice8Impl_ResourceManagerDiscardBytes(LPDIRECT3DDEVICE8 iface, DWORD Bytes) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    FIXME("(%p) : stub\n", This);    return D3D_OK;
+    TRACE("(%p) : Relay\n", This);
+    return IWineD3DDevice_TestCooperativeLevel(This->WineD3DDevice);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_GetDirect3D(LPDIRECT3DDEVICE8 iface, IDirect3D8** ppD3D8) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    TRACE("(%p) : returning %p\n", This, This->direct3d8);
 
-    /* Inc ref count */
-    IDirect3D8_AddRef((LPDIRECT3D8) This->direct3d8);
+static UINT WINAPI  IDirect3DDevice8Impl_GetAvailableTextureMem(LPDIRECT3DDEVICE8 iface) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
 
-    *ppD3D8 = (IDirect3D8 *)This->direct3d8;
-    return D3D_OK;
-}
-HRESULT  WINAPI  IDirect3DDevice8Impl_GetDeviceCaps(LPDIRECT3DDEVICE8 iface, D3DCAPS8* pCaps) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    FIXME("(%p) : stub, calling idirect3d for now\n", This);
-    IDirect3D8Impl_GetDeviceCaps((LPDIRECT3D8) This->direct3d8, This->adapterNo, This->devType, pCaps);
-    return D3D_OK;
+    TRACE("(%p) Relay\n", This);
+    return IWineD3DDevice_GetAvailableTextureMem(This->WineD3DDevice);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_GetDisplayMode(LPDIRECT3DDEVICE8 iface, D3DDISPLAYMODE* pMode) {
-
-    HDC hdc;
-    int bpp = 0;
-
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    pMode->Width        = GetSystemMetrics(SM_CXSCREEN);
-    pMode->Height       = GetSystemMetrics(SM_CYSCREEN);
-    pMode->RefreshRate  = 85; /*FIXME: How to identify? */
-
-    hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
-    bpp = GetDeviceCaps(hdc, BITSPIXEL);
-    DeleteDC(hdc);
-
-    switch (bpp) {
-    case  8: pMode->Format       = D3DFMT_R8G8B8; break;
-    case 16: pMode->Format       = D3DFMT_R5G6B5; break;
-    case 24: /*pMode->Format       = D3DFMT_R8G8B8; break; */
-    case 32: pMode->Format       = D3DFMT_A8R8G8B8; break;
-    default: 
-       FIXME("Unrecognized display mode format\n");
-       pMode->Format       = D3DFMT_UNKNOWN;
-    }
 
-    FIXME("(%p) : returning w(%d) h(%d) rr(%d) fmt(%u,%s)\n", This, pMode->Width, pMode->Height, pMode->RefreshRate, 
-         pMode->Format, debug_d3dformat(pMode->Format));
-    return D3D_OK;
-}
-HRESULT  WINAPI  IDirect3DDevice8Impl_GetCreationParameters(LPDIRECT3DDEVICE8 iface, D3DDEVICE_CREATION_PARAMETERS *pParameters) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    TRACE("(%p) copying to %p\n", This, pParameters);    
-    memcpy(pParameters, &This->CreateParms, sizeof(D3DDEVICE_CREATION_PARAMETERS));
-    return D3D_OK;
-}
-HRESULT  WINAPI  IDirect3DDevice8Impl_SetCursorProperties(LPDIRECT3DDEVICE8 iface, UINT XHotSpot, UINT YHotSpot, IDirect3DSurface8* pCursorBitmap) {
-    IDirect3DSurface8Impl* pSur = (IDirect3DSurface8Impl*) pCursorBitmap;
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    TRACE("(%p) : Spot Pos(%u,%u)\n", This, XHotSpot, YHotSpot);
-
-    if (D3DFMT_A8R8G8B8 != pSur->myDesc.Format) {
-      ERR("(%p) : surface(%p) have a invalid format\n", This, pCursorBitmap);
-      return D3DERR_INVALIDCALL;
-    }
-    if (32 != pSur->myDesc.Height || 32 != pSur->myDesc.Width) {
-      ERR("(%p) : surface(%p) have a invalid size\n", This, pCursorBitmap);
-      return D3DERR_INVALIDCALL;
-    }
+static HRESULT WINAPI IDirect3DDevice8Impl_ResourceManagerDiscardBytes(LPDIRECT3DDEVICE8 iface, DWORD Bytes) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
 
-    This->xHotSpot = XHotSpot;
-    This->yHotSpot = YHotSpot;
-    return D3D_OK;
-}
-void     WINAPI  IDirect3DDevice8Impl_SetCursorPosition(LPDIRECT3DDEVICE8 iface, UINT XScreenSpace, UINT YScreenSpace, DWORD Flags) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    TRACE("(%p) : SetPos to (%u,%u)\n", This, XScreenSpace, YScreenSpace);
-    This->xScreenSpace = XScreenSpace;
-    This->yScreenSpace = YScreenSpace;
-    return;
-}
-BOOL     WINAPI  IDirect3DDevice8Impl_ShowCursor(LPDIRECT3DDEVICE8 iface, BOOL bShow) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    TRACE("(%p) : visible(%d)\n", This, bShow); 
-    This->bCursorVisible = bShow;
-    return D3D_OK;
+    TRACE("(%p) : Relay bytes(%ld)\n", This, Bytes);
+    return IWineD3DDevice_EvictManagedResources(This->WineD3DDevice);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_CreateAdditionalSwapChain(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain8** pSwapChain) {
-    IDirect3DSwapChain8Impl* object;
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    FIXME("(%p) : stub\n", This);
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DDevice8Impl));
-    if (NULL == object) {
-      return D3DERR_OUTOFVIDEOMEMORY;
-    }
-    object->lpVtbl = &Direct3DSwapChain8_Vtbl;
-    object->ref = 1;
+static HRESULT WINAPI IDirect3DDevice8Impl_GetDirect3D(LPDIRECT3DDEVICE8 iface, IDirect3D8** ppD3D8) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    HRESULT hr = D3D_OK;
+    IWineD3D* pWineD3D;
 
-    TRACE("(%p)->(DepthStencil:(%u,%s), BackBufferFormat:(%u,%s))\n", This, 
-         pPresentationParameters->AutoDepthStencilFormat, debug_d3dformat(pPresentationParameters->AutoDepthStencilFormat),
-         pPresentationParameters->BackBufferFormat, debug_d3dformat(pPresentationParameters->BackBufferFormat));
-
-    if (pPresentationParameters->Windowed && ((pPresentationParameters->BackBufferWidth  == 0) ||
-                                              (pPresentationParameters->BackBufferHeight == 0))) {
-      RECT Rect;
-      
-      GetClientRect(This->win_handle, &Rect);
-      
-      if (pPresentationParameters->BackBufferWidth == 0) {
-       pPresentationParameters->BackBufferWidth = Rect.right;
-       TRACE("Updating width to %d\n", pPresentationParameters->BackBufferWidth);
-      }
-      if (pPresentationParameters->BackBufferHeight == 0) {
-       pPresentationParameters->BackBufferHeight = Rect.bottom;
-       TRACE("Updating height to %d\n", pPresentationParameters->BackBufferHeight);
-      }
-    }
-    
-    /* Save the presentation parms now filled in correctly */
-    memcpy(&object->PresentParms, pPresentationParameters, sizeof(D3DPRESENT_PARAMETERS));
-
-    IDirect3DDevice8Impl_CreateRenderTarget((LPDIRECT3DDEVICE8) object,
-                                            pPresentationParameters->BackBufferWidth,
-                                            pPresentationParameters->BackBufferHeight,
-                                            pPresentationParameters->BackBufferFormat,
-                                           pPresentationParameters->MultiSampleType,
-                                           TRUE,
-                                            (LPDIRECT3DSURFACE8*) &object->frontBuffer);
-    
-    IDirect3DDevice8Impl_CreateRenderTarget((LPDIRECT3DDEVICE8) object,
-                                            pPresentationParameters->BackBufferWidth,
-                                            pPresentationParameters->BackBufferHeight,
-                                            pPresentationParameters->BackBufferFormat,
-                                           pPresentationParameters->MultiSampleType,
-                                           TRUE,
-                                            (LPDIRECT3DSURFACE8*) &object->backBuffer);
-
-    if (pPresentationParameters->EnableAutoDepthStencil) {
-       IDirect3DDevice8Impl_CreateDepthStencilSurface((LPDIRECT3DDEVICE8) object,
-                                                     pPresentationParameters->BackBufferWidth,
-                                                     pPresentationParameters->BackBufferHeight,
-                                                     pPresentationParameters->AutoDepthStencilFormat,
-                                                     D3DMULTISAMPLE_NONE,
-                                                     (LPDIRECT3DSURFACE8*) &object->depthStencilBuffer);
-    } else {
-      object->depthStencilBuffer = NULL;
-    }
-
-    *pSwapChain = (IDirect3DSwapChain8*) object;
-    return D3D_OK;
-}
-HRESULT  WINAPI  IDirect3DDevice8Impl_Reset(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    FIXME("(%p) : stub\n", This);    return D3D_OK;
-}
-HRESULT  WINAPI  IDirect3DDevice8Impl_Present(LPDIRECT3DDEVICE8 iface, CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    TRACE("(%p) : complete stub!\n", This);
-
-    ENTER_GL();
+    TRACE("(%p) Relay\n", This);
 
-    glXSwapBuffers(This->display, This->drawable);
-    /* Dont call checkGLcall, as glGetError is not applicable here */
-    TRACE("glXSwapBuffers called, Starting new frame\n");
-
-    /* FPS support */
-    if (TRACE_ON(fps))
-    {
-        static long prev_time, frames;
-
-        DWORD time = GetTickCount();
-        frames++;
-        /* every 1.5 seconds */
-        if (time - prev_time > 1500) {
-            TRACE_(fps)("@ approx %.2ffps\n", 1000.0*frames/(time - prev_time));
-            prev_time = time;
-            frames = 0;
-        }
+    if (NULL == ppD3D8) {
+        return D3DERR_INVALIDCALL;
     }
-
-#if defined(FRAME_DEBUGGING)
-{
-    if (GetFileAttributesA("C:\\D3DTRACE") != INVALID_FILE_ATTRIBUTES) {
-        if (!isOn) {
-            isOn = TRUE;
-            FIXME("Enabling D3D Trace\n");
-            __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 1);
-#if defined(SHOW_FRAME_MAKEUP)
-            FIXME("Singe Frame snapshots Starting\n");
-            isDumpingFrames = TRUE;
-            glClear(GL_COLOR_BUFFER_BIT);
-#endif
-
-#if defined(SINGLE_FRAME_DEBUGGING)
-        } else {
-#if defined(SHOW_FRAME_MAKEUP)
-            FIXME("Singe Frame snapshots Finishing\n");
-            isDumpingFrames = FALSE;
-#endif
-            FIXME("Singe Frame trace complete\n");
-            DeleteFileA("C:\\D3DTRACE");
-            __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 0);
-#endif
-        }
+    hr = IWineD3DDevice_GetDirect3D(This->WineD3DDevice, &pWineD3D);
+    if (hr == D3D_OK && pWineD3D != NULL)
+    {
+        IWineD3DResource_GetParent((IWineD3DResource *)pWineD3D,(IUnknown **)ppD3D8);
+        IWineD3DResource_Release((IWineD3DResource *)pWineD3D);
     } else {
-        if (isOn) {
-            isOn = FALSE;
-#if defined(SHOW_FRAME_MAKEUP)
-            FIXME("Singe Frame snapshots Finishing\n");
-            isDumpingFrames = FALSE;
-#endif
-            FIXME("Disabling D3D Trace\n");
-            __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 0);
-        }
+        FIXME("Call to IWineD3DDevice_GetDirect3D failed\n");
+        *ppD3D8 = NULL;
     }
+    TRACE("(%p) returning %p\n",This , *ppD3D8);
+    return hr;
 }
-#endif
-
-    LEAVE_GL();
 
-    return D3D_OK;
-}
-HRESULT  WINAPI  IDirect3DDevice8Impl_GetBackBuffer(LPDIRECT3DDEVICE8 iface, UINT BackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface8** ppBackBuffer) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    *ppBackBuffer = (LPDIRECT3DSURFACE8) This->backBuffer;
-    TRACE("(%p) : BackBuf %d Type %d returning %p\n", This, BackBuffer, Type, *ppBackBuffer);
+static HRESULT WINAPI IDirect3DDevice8Impl_GetDeviceCaps(LPDIRECT3DDEVICE8 iface, D3DCAPS8* pCaps) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    HRESULT hrc = D3D_OK;
+    WINED3DCAPS *pWineCaps;
 
-    if (BackBuffer > This->PresentParms.BackBufferCount - 1) {
-        FIXME("Only one backBuffer currently supported\n");
+    TRACE("(%p) : Relay pCaps %p\n", This, pCaps);
+    if(NULL == pCaps){
         return D3DERR_INVALIDCALL;
     }
+    pWineCaps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINED3DCAPS));
+    if(pWineCaps == NULL){
+        return D3DERR_INVALIDCALL; /* well this is what MSDN says to return */
+    }
 
-    /* Note inc ref on returned surface */
-    IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppBackBuffer);
-
-    return D3D_OK;
-}
-HRESULT  WINAPI  IDirect3DDevice8Impl_GetRasterStatus(LPDIRECT3DDEVICE8 iface, D3DRASTER_STATUS* pRasterStatus) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    FIXME("(%p) : stub\n", This);    
-    return D3D_OK;
+    D3D8CAPSTOWINECAPS(pCaps, pWineCaps)
+    hrc = IWineD3DDevice_GetDeviceCaps(This->WineD3DDevice, pWineCaps);
+    HeapFree(GetProcessHeap(), 0, pWineCaps);
+    TRACE("Returning %p %p\n", This, pCaps);
+    return hrc;
 }
-void     WINAPI  IDirect3DDevice8Impl_SetGammaRamp(LPDIRECT3DDEVICE8 iface, DWORD Flags, CONST D3DGAMMARAMP* pRamp) {
-    HDC hDC;
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-
-    FIXME("(%p) : pRamp@%p\n", This, pRamp);
-    hDC = GetDC(This->win_handle);
-    SetDeviceGammaRamp(hDC, (LPVOID) pRamp);
-    ReleaseDC(This->win_handle, hDC);
-    return;
+
+static HRESULT WINAPI IDirect3DDevice8Impl_GetDisplayMode(LPDIRECT3DDEVICE8 iface, D3DDISPLAYMODE* pMode) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n", This);
+    return IWineD3DDevice_GetDisplayMode(This->WineD3DDevice, 0, (WINED3DDISPLAYMODE *) pMode);
 }
-void     WINAPI  IDirect3DDevice8Impl_GetGammaRamp(LPDIRECT3DDEVICE8 iface, D3DGAMMARAMP* pRamp) {
-    HDC hDC;
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-
-    FIXME("(%p) : pRamp@%p\n", This, pRamp);
-    hDC = GetDC(This->win_handle);
-    GetDeviceGammaRamp(hDC, pRamp);
-    ReleaseDC(This->win_handle, hDC);
-    return;
+
+static HRESULT WINAPI IDirect3DDevice8Impl_GetCreationParameters(LPDIRECT3DDEVICE8 iface, D3DDEVICE_CREATION_PARAMETERS *pParameters) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n", This);
+    return IWineD3DDevice_GetCreationParameters(This->WineD3DDevice, (WINED3DDEVICE_CREATION_PARAMETERS *) pParameters);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_CreateTexture(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, UINT Levels, DWORD Usage,
-                                                    D3DFORMAT Format, D3DPOOL Pool, IDirect3DTexture8** ppTexture) {
-    IDirect3DTexture8Impl *object;
-    int i;
-    UINT tmpW;
-    UINT tmpH;
 
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
+static HRESULT WINAPI IDirect3DDevice8Impl_SetCursorProperties(LPDIRECT3DDEVICE8 iface, UINT XHotSpot, UINT YHotSpot, IDirect3DSurface8* pCursorBitmap) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    IDirect3DSurface8Impl *pSurface = (IDirect3DSurface8Impl*)pCursorBitmap;
+    TRACE("(%p) Relay\n", This);
+    return IWineD3DDevice_SetCursorProperties(This->WineD3DDevice,XHotSpot,YHotSpot,(IWineD3DSurface*)pSurface->wineD3DSurface);
+}
 
-    /* Allocate the storage for the device */
-    TRACE("(%p) : W(%d) H(%d), Lvl(%d) Usage(%ld), Fmt(%u,%s), Pool(%d)\n", This, Width, Height, Levels, Usage, Format, debug_d3dformat(Format), Pool);
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DTexture8Impl));
-    object->lpVtbl = &Direct3DTexture8_Vtbl;
-    object->Device = This;
-    object->ResourceType = D3DRTYPE_TEXTURE;
-    object->ref = 1;
-    object->width = Width;
-    object->height = Height;
-    object->levels = Levels;
-    object->usage = Usage;
-    object->format = Format;
-
-    /* Calculate levels for mip mapping */
-    if (Levels == 0) {
-        object->levels++;
-        tmpW = Width;
-        tmpH = Height;
-        while (tmpW > 1 && tmpH > 1) {
-            tmpW = max(1, tmpW / 2);
-            tmpH = max(1, tmpH / 2);
-            object->levels++;
-        }
-        TRACE("Calculated levels = %d\n", object->levels);
-    }
+static void WINAPI IDirect3DDevice8Impl_SetCursorPosition(LPDIRECT3DDEVICE8 iface, UINT XScreenSpace, UINT YScreenSpace, DWORD Flags) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n", This);
+    return IWineD3DDevice_SetCursorPosition(This->WineD3DDevice, XScreenSpace, YScreenSpace, Flags);
+}
 
-    /* Generate all the surfaces */
-    tmpW = Width;
-    tmpH = Height;
-    for (i = 0; i < object->levels; i++) 
-    {
-        IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpH, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[i]);
-        object->surfaces[i]->Container = (IUnknown*) object;
-        object->surfaces[i]->myDesc.Usage = Usage;
-        object->surfaces[i]->myDesc.Pool = Pool;
-       /** 
-        * As written in msdn in IDirect3DTexture8::LockRect
-        *  Textures created in D3DPOOL_DEFAULT are not lockable.
-        */
-       if (D3DPOOL_DEFAULT == Pool) {
-         object->surfaces[i]->lockable = FALSE;
-       }
-
-        TRACE("Created surface level %d @ %p, memory at %p\n", i, object->surfaces[i], object->surfaces[i]->allocatedMemory);
-        tmpW = max(1, tmpW / 2);
-        tmpH = max(1, tmpH / 2);
-    }
+static BOOL WINAPI IDirect3DDevice8Impl_ShowCursor(LPDIRECT3DDEVICE8 iface, BOOL bShow) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n", This);
 
-    *ppTexture = (LPDIRECT3DTEXTURE8) object;
-    TRACE("(%p) : Created texture %p\n", This, object);
-    return D3D_OK;
+    return IWineD3DDevice_ShowCursor(This->WineD3DDevice, bShow);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_CreateVolumeTexture(LPDIRECT3DDEVICE8 iface, 
-                                                          UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, 
-                                                          D3DFORMAT Format, D3DPOOL Pool, IDirect3DVolumeTexture8** ppVolumeTexture) {
-
-    IDirect3DVolumeTexture8Impl *object;
-    int i;
-    UINT tmpW;
-    UINT tmpH;
-    UINT tmpD;
 
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
+static HRESULT WINAPI IDirect3DDevice8Impl_CreateAdditionalSwapChain(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain8** pSwapChain) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    IDirect3DSwapChain8Impl* object;
+    HRESULT hrc = D3D_OK;
+    WINED3DPRESENT_PARAMETERS localParameters;
 
-    /* Allocate the storage for it */
-    TRACE("(%p) : W(%d) H(%d) D(%d), Lvl(%d) Usage(%ld), Fmt(%u,%s), Pool(%s)\n", This, Width, Height, Depth, Levels, Usage, Format, debug_d3dformat(Format), debug_d3dpool(Pool));
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolumeTexture8Impl));
-    object->lpVtbl = &Direct3DVolumeTexture8_Vtbl;
-    object->ResourceType = D3DRTYPE_VOLUMETEXTURE;
-    object->Device = This;
-    object->ref = 1;
+    TRACE("(%p) Relay\n", This);
 
-    object->width = Width;
-    object->height = Height;
-    object->depth = Depth;
-    object->levels = Levels;
-    object->usage = Usage;
-    object->format = Format;
-
-    /* Calculate levels for mip mapping */
-    if (Levels == 0) {
-        object->levels++;
-        tmpW = Width;
-        tmpH = Height;
-        tmpD = Depth;
-        while (tmpW > 1 && tmpH > 1 && tmpD > 1) {
-            tmpW = max(1, tmpW / 2);
-            tmpH = max(1, tmpH / 2);
-            tmpD = max(1, tmpD / 2);
-            object->levels++;
-        }
-        TRACE("Calculated levels = %d\n", object->levels);
+    /* Fix the back buffer count */
+    if(pPresentationParameters->BackBufferCount == 0) {
+        pPresentationParameters->BackBufferCount = 1;
     }
 
-    /* Generate all the surfaces */
-    tmpW = Width;
-    tmpH = Height;
-    tmpD = Depth;
-
-    for (i = 0; i < object->levels; i++) 
-    {
-        IDirect3DVolume8Impl* volume;
-
-        /* Create the volume - No entry point for this seperately?? */
-        volume  = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolume8Impl));
-        object->volumes[i] = (IDirect3DVolume8Impl *) volume;
-
-        volume->lpVtbl = &Direct3DVolume8_Vtbl;
-        volume->Device = This;
-        volume->ResourceType = D3DRTYPE_VOLUME;
-        volume->Container = (IUnknown*) object;
-        volume->ref = 1;
-
-        volume->myDesc.Width  = Width;
-        volume->myDesc.Height = Height;
-        volume->myDesc.Depth  = Depth;
-        volume->myDesc.Format = Format;
-        volume->myDesc.Type   = D3DRTYPE_VOLUME;
-        volume->myDesc.Pool   = Pool;
-        volume->myDesc.Usage  = Usage;
-        volume->bytesPerPixel   = D3DFmtGetBpp(This, Format);
-        /* Note: Volume textures cannot be dxtn, hence no need to check here */
-        volume->myDesc.Size     = (Width * volume->bytesPerPixel) * Height * Depth; 
-        volume->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, volume->myDesc.Size);
-
-       volume->lockable = TRUE;
-       volume->locked = FALSE;
-       memset(&volume->lockedBox, 0, sizeof(D3DBOX));
-       volume->Dirty = FALSE;
-       IDirect3DVolume8Impl_CleanDirtyBox((LPDIRECT3DVOLUME8) volume);
-
-        TRACE("(%p) : Volume at w(%d) h(%d) d(%d) fmt(%u,%s) surf@%p, surfmem@%p, %d bytes\n", 
-              This, Width, Height, Depth, Format, debug_d3dformat(Format),
-              volume, volume->allocatedMemory, volume->myDesc.Size);
-
-        tmpW = max(1, tmpW / 2);
-        tmpH = max(1, tmpH / 2);
-        tmpD = max(1, tmpD / 2);
+    object = HeapAlloc(GetProcessHeap(),  HEAP_ZERO_MEMORY, sizeof(*object));
+    if (NULL == object) {
+        FIXME("Allocation of memory failed\n");
+        *pSwapChain = NULL;
+        return D3DERR_OUTOFVIDEOMEMORY;
     }
+    object->ref = 1;
+    object->lpVtbl = &Direct3DSwapChain8_Vtbl;
 
-    *ppVolumeTexture = (LPDIRECT3DVOLUMETEXTURE8) object;
-    TRACE("(%p) : Created volume texture %p\n", This, object);
-    return D3D_OK;
-}
-HRESULT  WINAPI  IDirect3DDevice8Impl_CreateCubeTexture(LPDIRECT3DDEVICE8 iface, UINT EdgeLength, UINT Levels, DWORD Usage, 
-                                                        D3DFORMAT Format, D3DPOOL Pool, IDirect3DCubeTexture8** ppCubeTexture) {
-
-    IDirect3DCubeTexture8Impl *object;
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    int i,j;
-    UINT tmpW;
+    /* Allocate an associated WineD3DDevice object */
+    localParameters.BackBufferWidth                = &pPresentationParameters->BackBufferWidth;
+    localParameters.BackBufferHeight               = &pPresentationParameters->BackBufferHeight;
+    localParameters.BackBufferFormat               = (WINED3DFORMAT *)&pPresentationParameters->BackBufferFormat;
+    localParameters.BackBufferCount                = &pPresentationParameters->BackBufferCount;
+    localParameters.MultiSampleType                = (WINED3DMULTISAMPLE_TYPE *) &pPresentationParameters->MultiSampleType;
+    localParameters.MultiSampleQuality             = NULL; /* d3d9 only */
+    localParameters.SwapEffect                     = (WINED3DSWAPEFFECT *) &pPresentationParameters->SwapEffect;
+    localParameters.hDeviceWindow                  = &pPresentationParameters->hDeviceWindow;
+    localParameters.Windowed                       = &pPresentationParameters->Windowed;
+    localParameters.EnableAutoDepthStencil         = &pPresentationParameters->EnableAutoDepthStencil;
+    localParameters.AutoDepthStencilFormat         = (WINED3DFORMAT *)&pPresentationParameters->AutoDepthStencilFormat;
+    localParameters.Flags                          = &pPresentationParameters->Flags;
+    localParameters.FullScreen_RefreshRateInHz     = &pPresentationParameters->FullScreen_RefreshRateInHz;
+    localParameters.PresentationInterval           = &pPresentationParameters->FullScreen_PresentationInterval;
+
+
+    hrc = IWineD3DDevice_CreateAdditionalSwapChain(This->WineD3DDevice, &localParameters, &object->wineD3DSwapChain, (IUnknown*)object, D3D8CB_CreateRenderTarget, D3D8CB_CreateDepthStencilSurface);
+    if (hrc != D3D_OK) {
+        FIXME("(%p) call to IWineD3DDevice_CreateAdditionalSwapChain failed\n", This);
+        HeapFree(GetProcessHeap(), 0 , object);
+        *pSwapChain = NULL;
+    }else{
+        IUnknown_AddRef(iface);
+        object->parentDevice = iface;
+        *pSwapChain = (IDirect3DSwapChain8 *)object;
+    }
+    TRACE("(%p) returning %p\n", This, *pSwapChain);
+    return hrc;
+}
+
+static HRESULT WINAPI IDirect3DDevice8Impl_Reset(LPDIRECT3DDEVICE8 iface, D3DPRESENT_PARAMETERS* pPresentationParameters) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    WINED3DPRESENT_PARAMETERS localParameters;
+    TRACE("(%p) Relay pPresentationParameters(%p)\n", This, pPresentationParameters);
+/* FINDME: FIXME: */
+    localParameters.BackBufferWidth                = &pPresentationParameters->BackBufferWidth;
+    localParameters.BackBufferHeight               = &pPresentationParameters->BackBufferHeight;
+    localParameters.BackBufferFormat               = (WINED3DFORMAT *)&pPresentationParameters->BackBufferFormat;
+    localParameters.BackBufferCount                = &pPresentationParameters->BackBufferCount;
+    localParameters.MultiSampleType                = (WINED3DMULTISAMPLE_TYPE *) &pPresentationParameters->MultiSampleType;
+    localParameters.MultiSampleQuality             = NULL; /* D3d9 only */
+    localParameters.SwapEffect                     = (WINED3DSWAPEFFECT *) &pPresentationParameters->SwapEffect;
+    localParameters.hDeviceWindow                  = &pPresentationParameters->hDeviceWindow;
+    localParameters.Windowed                       = &pPresentationParameters->Windowed;
+    localParameters.EnableAutoDepthStencil         = &pPresentationParameters->EnableAutoDepthStencil;
+    localParameters.AutoDepthStencilFormat         = (WINED3DFORMAT *)&pPresentationParameters->AutoDepthStencilFormat;
+    localParameters.Flags                          = &pPresentationParameters->Flags;
+    localParameters.FullScreen_RefreshRateInHz     = &pPresentationParameters->FullScreen_RefreshRateInHz;
+    localParameters.PresentationInterval           = &pPresentationParameters->FullScreen_PresentationInterval;
+    return IWineD3DDevice_Reset(This->WineD3DDevice, &localParameters);
+}
+
+static HRESULT WINAPI IDirect3DDevice8Impl_Present(LPDIRECT3DDEVICE8 iface, CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n", This);
+    return IWineD3DDevice_Present(This->WineD3DDevice, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
+}
+
+static HRESULT WINAPI IDirect3DDevice8Impl_GetBackBuffer(LPDIRECT3DDEVICE8 iface, UINT BackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface8** ppBackBuffer) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    IWineD3DSurface *retSurface = NULL;
+    HRESULT rc = D3D_OK;
 
-    /* Allocate the storage for it */
-    TRACE("(%p) : Len(%d), Lvl(%d) Usage(%ld), Fmt(%u,%s), Pool(%s)\n", This, EdgeLength, Levels, Usage, Format, debug_d3dformat(Format), debug_d3dpool(Pool));
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DCubeTexture8Impl));
-    object->lpVtbl = &Direct3DCubeTexture8_Vtbl;
-    object->ref = 1;
-    object->Device = This;
-    object->ResourceType = D3DRTYPE_CUBETEXTURE;
-
-    object->edgeLength = EdgeLength;
-    object->levels = Levels;
-    object->usage = Usage;
-    object->format = Format;
-
-    /* Calculate levels for mip mapping */
-    if (Levels == 0) {
-        object->levels++;
-        tmpW = EdgeLength;
-        while (tmpW > 1) {
-            tmpW = max(1, tmpW / 2);
-            object->levels++;
-        }
-        TRACE("Calculated levels = %d\n", object->levels);
-    }
+    TRACE("(%p) Relay\n", This);
 
-    /* Generate all the surfaces */
-    tmpW = EdgeLength;
-    for (i = 0; i < object->levels; i++) {
-        /* Create the 6 faces */
-        for (j = 0; j < 6; j++) {
-           IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpW, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[j][i]);
-           object->surfaces[j][i]->Container = (IUnknown*) object;
-           object->surfaces[j][i]->myDesc.Usage = Usage;
-           object->surfaces[j][i]->myDesc.Pool = Pool;
-          /** 
-           * As written in msdn in IDirect3DCubeTexture8::LockRect
-           *  Textures created in D3DPOOL_DEFAULT are not lockable.
-           */
-          if (D3DPOOL_DEFAULT == Pool) {
-            object->surfaces[j][i]->lockable = FALSE;
-          }
-
-           TRACE("Created surface level %d @ %p, memory at %p\n", i, object->surfaces[j][i], object->surfaces[j][i]->allocatedMemory);
-        }
-        tmpW = max(1, tmpW / 2);
+    rc = IWineD3DDevice_GetBackBuffer(This->WineD3DDevice, 0, BackBuffer, (WINED3DBACKBUFFER_TYPE) Type, (IWineD3DSurface **)&retSurface);
+    if (rc == D3D_OK && NULL != retSurface && NULL != ppBackBuffer) {
+        IWineD3DSurface_GetParent(retSurface, (IUnknown **)ppBackBuffer);
+        IWineD3DSurface_Release(retSurface);
     }
-
-    TRACE("(%p) : Iface@%p\n", This, object);
-    *ppCubeTexture = (LPDIRECT3DCUBETEXTURE8) object;
-    return D3D_OK;
+    return rc;
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_CreateVertexBuffer(LPDIRECT3DDEVICE8 iface, UINT Size, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer8** ppVertexBuffer) {
-    IDirect3DVertexBuffer8Impl *object;
-
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
 
-    /* Allocate the storage for the device */
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBuffer8Impl));
-    object->lpVtbl = &Direct3DVertexBuffer8_Vtbl;
-    object->Device = This;
-    object->ResourceType = D3DRTYPE_VERTEXBUFFER;
-    object->ref = 1;
-    object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Size);
-    object->currentDesc.Usage = Usage;
-    object->currentDesc.Pool  = Pool;
-    object->currentDesc.FVF   = FVF;
-    object->currentDesc.Size  = Size;
+static HRESULT WINAPI IDirect3DDevice8Impl_GetRasterStatus(LPDIRECT3DDEVICE8 iface, D3DRASTER_STATUS* pRasterStatus) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n", This);
 
-    TRACE("(%p) : Size=%d, Usage=%ld, FVF=%lx, Pool=%d - Memory@%p, Iface@%p\n", This, Size, Usage, FVF, Pool, object->allocatedMemory, object);
+    return IWineD3DDevice_GetRasterStatus(This->WineD3DDevice, 0, (WINED3DRASTER_STATUS *) pRasterStatus);
+}
 
-    *ppVertexBuffer = (LPDIRECT3DVERTEXBUFFER8) object;
+static void WINAPI IDirect3DDevice8Impl_SetGammaRamp(LPDIRECT3DDEVICE8 iface, DWORD Flags, CONST D3DGAMMARAMP* pRamp) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n", This);
 
-    return D3D_OK;
+    return IWineD3DDevice_SetGammaRamp(This->WineD3DDevice, 0, Flags, (WINED3DGAMMARAMP *) pRamp);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_CreateIndexBuffer(LPDIRECT3DDEVICE8 iface, UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer8** ppIndexBuffer) {
-    IDirect3DIndexBuffer8Impl *object;
-
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    TRACE("(%p) : Len=%d, Use=%lx, Format=(%u,%s), Pool=%d\n", This, Length, Usage, Format, debug_d3dformat(Format), Pool);
 
-    /* Allocate the storage for the device */
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DIndexBuffer8Impl));
-    object->lpVtbl = &Direct3DIndexBuffer8_Vtbl;
-    object->Device = This;
-    object->ref = 1;
-    object->ResourceType = D3DRTYPE_INDEXBUFFER;
+static void WINAPI IDirect3DDevice8Impl_GetGammaRamp(LPDIRECT3DDEVICE8 iface, D3DGAMMARAMP* pRamp) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n", This);
 
-    object->currentDesc.Type = D3DRTYPE_INDEXBUFFER;
-    object->currentDesc.Usage = Usage;
-    object->currentDesc.Pool  = Pool;
-    object->currentDesc.Format  = Format;
-    object->currentDesc.Size  = Length;
+    return IWineD3DDevice_GetGammaRamp(This->WineD3DDevice, 0, (WINED3DGAMMARAMP *) pRamp);
+}
 
-    object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Length);
+static HRESULT WINAPI IDirect3DDevice8Impl_CreateTexture(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, UINT Levels, DWORD Usage,
+                                                    D3DFORMAT Format, D3DPOOL Pool, IDirect3DTexture8 **ppTexture) {
+    IDirect3DTexture8Impl *object;
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    HRESULT hrc = D3D_OK;
 
-    TRACE("(%p) : Iface@%p allocatedMem @ %p\n", This, object, object->allocatedMemory);
+    TRACE("(%p) : W(%d) H(%d), Lvl(%d) d(%ld), Fmt(%u), Pool(%d)\n", This, Width, Height, Levels, Usage, Format,  Pool);
 
-    *ppIndexBuffer = (LPDIRECT3DINDEXBUFFER8) object;
+    /* Allocate the storage for the device */
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DTexture8Impl));
 
-    return D3D_OK;
-}
-HRESULT  WINAPI  IDirect3DDevice8Impl_CreateRenderTarget(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, BOOL Lockable, IDirect3DSurface8** ppSurface) {
-    IDirect3DSurface8Impl *object;
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    
-    object  = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl));
     if (NULL == object) {
-      *ppSurface = NULL;
-      return D3DERR_OUTOFVIDEOMEMORY;
+        FIXME("Allocation of memory failed\n");
+/*        *ppTexture = NULL; */
+        return D3DERR_OUTOFVIDEOMEMORY;
     }
-    *ppSurface = (LPDIRECT3DSURFACE8) object;
-    object->lpVtbl = &Direct3DSurface8_Vtbl;
-    object->Device = This;
-    object->ResourceType = D3DRTYPE_SURFACE;
-    object->Container = (IUnknown*) This;
 
+    object->lpVtbl = &Direct3DTexture8_Vtbl;
     object->ref = 1;
-    object->myDesc.Width  = Width;
-    object->myDesc.Height = Height;
-    object->myDesc.Format = Format;
-    object->myDesc.Type = D3DRTYPE_SURFACE;
-    object->myDesc.Usage = D3DUSAGE_RENDERTARGET;
-    object->myDesc.Pool = D3DPOOL_DEFAULT;
-    object->myDesc.MultiSampleType = MultiSample;
-    object->bytesPerPixel = D3DFmtGetBpp(This, Format);
-    if (Format == D3DFMT_DXT1) { 
-        object->myDesc.Size = (Width * object->bytesPerPixel)/2 * Height;  /* DXT1 is half byte per pixel */
-    } else {
-        object->myDesc.Size = (Width * object->bytesPerPixel) * Height;
-    }
-    object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->myDesc.Size);
-    object->lockable = Lockable;
-    object->locked = FALSE;
-    memset(&object->lockedRect, 0, sizeof(RECT));
-    IDirect3DSurface8Impl_CleanDirtyRect((LPDIRECT3DSURFACE8) object);
+    hrc = IWineD3DDevice_CreateTexture(This->WineD3DDevice, Width, Height, Levels, Usage & WINED3DUSAGE_MASK,
+                                 (WINED3DFORMAT)Format, (WINED3DPOOL) Pool, &object->wineD3DTexture, NULL, (IUnknown *)object, D3D8CB_CreateSurface);
 
-    TRACE("(%p) : w(%d) h(%d) fmt(%d,%s) lockable(%d) surf@%p, surfmem@%p, %d bytes\n", This, Width, Height, Format, debug_d3dformat(Format), Lockable, *ppSurface, object->allocatedMemory, object->myDesc.Size);
-    return D3D_OK;
+    if (FAILED(hrc)) {
+        /* free up object */ 
+        FIXME("(%p) call to IWineD3DDevice_CreateTexture failed\n", This);
+        HeapFree(GetProcessHeap(), 0, object);
+/*      *ppTexture = NULL; */
+   } else {
+        IUnknown_AddRef(iface);
+        object->parentDevice = iface;
+        *ppTexture = (LPDIRECT3DTEXTURE8) object;
+   }
+
+   TRACE("(%p) Created Texture %p, %p\n",This,object,object->wineD3DTexture);
+   return hrc;
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_CreateDepthStencilSurface(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, IDirect3DSurface8** ppSurface) {
-    IDirect3DSurface8Impl *object;
 
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
+static HRESULT WINAPI IDirect3DDevice8Impl_CreateVolumeTexture(LPDIRECT3DDEVICE8 iface, 
+                                                          UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, 
+                                                          D3DFORMAT Format, D3DPOOL Pool, IDirect3DVolumeTexture8** ppVolumeTexture) {
+
+    IDirect3DVolumeTexture8Impl *object;
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    HRESULT hrc = D3D_OK;
+
+    TRACE("(%p) Relay\n", This);
 
-    object  = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl));
+    /* Allocate the storage for the device */
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolumeTexture8Impl));
     if (NULL == object) {
-      *ppSurface = NULL;
-      return D3DERR_OUTOFVIDEOMEMORY;
+        FIXME("(%p) allocation of memory failed\n", This);
+        *ppVolumeTexture = NULL;
+        return D3DERR_OUTOFVIDEOMEMORY;
     }
-    *ppSurface = (LPDIRECT3DSURFACE8) object;
-    object->lpVtbl = &Direct3DSurface8_Vtbl;
-    object->Device = This;
-    object->ResourceType = D3DRTYPE_SURFACE;
-    object->Container = (IUnknown*) This;
 
+    object->lpVtbl = &Direct3DVolumeTexture8_Vtbl;
     object->ref = 1;
-    object->myDesc.Width  = Width;
-    object->myDesc.Height = Height;
-    object->myDesc.Format = Format;
-    object->myDesc.Type = D3DRTYPE_SURFACE;
-    object->myDesc.Usage = D3DUSAGE_DEPTHSTENCIL;
-    object->myDesc.Pool = D3DPOOL_DEFAULT;
-    object->myDesc.MultiSampleType = MultiSample;
-    object->bytesPerPixel = D3DFmtGetBpp(This, Format);
-    if (Format == D3DFMT_DXT1) { 
-        object->myDesc.Size = (Width * object->bytesPerPixel)/2 * Height; /* DXT1 is half byte per pixel */
-    } else {
-        object->myDesc.Size = (Width * object->bytesPerPixel) * Height;
-    }
-    object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->myDesc.Size);
-    object->lockable = (D3DFMT_D16_LOCKABLE == Format) ? TRUE : FALSE;
-    object->locked = FALSE;
-    memset(&object->lockedRect, 0, sizeof(RECT));
-    IDirect3DSurface8Impl_CleanDirtyRect((LPDIRECT3DSURFACE8) object);
-
-    TRACE("(%p) : w(%d) h(%d) fmt(%d,%s) surf@%p, surfmem@%p, %d bytes\n", This, Width, Height, Format, debug_d3dformat(Format), *ppSurface, object->allocatedMemory, object->myDesc.Size);
-    return D3D_OK;
-}
-HRESULT  WINAPI  IDirect3DDevice8Impl_CreateImageSurface(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, IDirect3DSurface8** ppSurface) {
-    IDirect3DSurface8Impl *object;
+    hrc = IWineD3DDevice_CreateVolumeTexture(This->WineD3DDevice, Width, Height, Depth, Levels, Usage & WINED3DUSAGE_MASK,
+                                 (WINED3DFORMAT)Format, (WINED3DPOOL) Pool, &object->wineD3DVolumeTexture, NULL,
+                                 (IUnknown *)object, D3D8CB_CreateVolume);
 
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-
-    object  = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl));
-    *ppSurface = (LPDIRECT3DSURFACE8) object;
-    object->lpVtbl = &Direct3DSurface8_Vtbl;
-    object->Device = This;
-    object->ResourceType = D3DRTYPE_SURFACE;
-    object->Container = (IUnknown*) This;
+    if (hrc != D3D_OK) {
 
-    object->ref = 1;
-    object->myDesc.Width  = Width;
-    object->myDesc.Height = Height;
-    object->myDesc.Format = Format;
-    object->myDesc.Type = D3DRTYPE_SURFACE;
-    object->myDesc.Usage = 0;
-    object->myDesc.Pool = D3DPOOL_SYSTEMMEM;
-    object->bytesPerPixel = D3DFmtGetBpp(This, Format);
-    /* DXTn mipmaps use the same number of 'levels' down to eg. 8x1, but since
-       it is based around 4x4 pixel blocks it requires padding, so allocate enough
-       space!                                                                      */
-    if (Format == D3DFMT_DXT1) { 
-        object->myDesc.Size = ((max(Width,4) * object->bytesPerPixel) * max(Height,4)) / 2; /* DXT1 is half byte per pixel */
-    } else if (Format == D3DFMT_DXT2 || Format == D3DFMT_DXT3 || 
-               Format == D3DFMT_DXT4 || Format == D3DFMT_DXT5) { 
-        object->myDesc.Size = ((max(Width,4) * object->bytesPerPixel) * max(Height,4));
+        /* free up object */
+        FIXME("(%p) call to IWineD3DDevice_CreateVolumeTexture failed\n", This);
+        HeapFree(GetProcessHeap(), 0, object);
+        *ppVolumeTexture = NULL;
     } else {
-        object->myDesc.Size = (Width * object->bytesPerPixel) * Height;
+        IUnknown_AddRef(iface);
+        object->parentDevice = iface;
+        *ppVolumeTexture = (LPDIRECT3DVOLUMETEXTURE8) object;
     }
-    object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->myDesc.Size);
-    object->lockable = TRUE;
-    object->locked = FALSE;
-    memset(&object->lockedRect, 0, sizeof(RECT));
-    IDirect3DSurface8Impl_CleanDirtyRect((LPDIRECT3DSURFACE8) object);
-
-    TRACE("(%p) : w(%d) h(%d) fmt(%d,%s) surf@%p, surfmem@%p, %d bytes\n", This, Width, Height, Format, debug_d3dformat(Format), *ppSurface, object->allocatedMemory, object->myDesc.Size);
-    return D3D_OK;
+    TRACE("(%p)  returning %p\n", This , *ppVolumeTexture);
+    return hrc;
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_CopyRects(LPDIRECT3DDEVICE8 iface, 
-                                                IDirect3DSurface8* pSourceSurface, CONST RECT* pSourceRectsArray, UINT cRects,
-                                                IDirect3DSurface8* pDestinationSurface, CONST POINT* pDestPointsArray) {
-
-    HRESULT rc = D3D_OK;
-    IDirect3DBaseTexture8* texture = NULL;
-
-
-    IDirect3DSurface8Impl* src = (IDirect3DSurface8Impl*) pSourceSurface;
-    IDirect3DSurface8Impl* dst = (IDirect3DSurface8Impl*) pDestinationSurface;
-
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    TRACE("(%p) pSrcSur=%p, pSourceRects=%p, cRects=%d, pDstSur=%p, pDestPtsArr=%p\n", This,
-          pSourceSurface, pSourceRectsArray, cRects, pDestinationSurface, pDestPointsArray);
-
-    /* Note: Not sure about the d3dfmt_unknown bit, but seems to avoid a problem inside
-         a sample and doesnt seem to break anything as far as I can tell               */
-    if (src->myDesc.Format != dst->myDesc.Format && (dst->myDesc.Format != D3DFMT_UNKNOWN)) {
-        TRACE("Formats do not match (%x,%s) / (%x,%s)\n", 
-               src->myDesc.Format, debug_d3dformat(src->myDesc.Format), 
-               dst->myDesc.Format, debug_d3dformat(dst->myDesc.Format));
-        rc = D3DERR_INVALIDCALL;
-
-    } else if (dst->myDesc.Format == D3DFMT_UNKNOWN) {
-        TRACE("Converting dest to same format as source, since dest was unknown\n");
-        dst->myDesc.Format = src->myDesc.Format;
-
-        /* Convert container as well */
-        IDirect3DSurface8Impl_GetContainer((LPDIRECT3DSURFACE8) dst, &IID_IDirect3DBaseTexture8, (void**) &texture); /* FIXME: Which refid? */
-        if (texture != NULL) {
-            ((IDirect3DBaseTexture8Impl*) texture)->format = src->myDesc.Format;
-           /** Releasing texture after GetContainer */
-           IDirect3DBaseTexture8_Release(texture);
-           texture = NULL;
-        }
-    }
-
-    /* Quick if complete copy ... */
-    if (rc == D3D_OK && cRects == 0 && pSourceRectsArray == NULL && pDestPointsArray == NULL) {
-
-      if (src->myDesc.Width == dst->myDesc.Width && src->myDesc.Height == dst->myDesc.Height) {
-
-        D3DLOCKED_RECT lrSrc;
-        D3DLOCKED_RECT lrDst;
-        IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8) src, &lrSrc, NULL, D3DLOCK_READONLY);
-       IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8) dst, &lrDst, NULL, 0L);
-        TRACE("Locked src and dst, Direct copy as surfaces are equal, w=%d, h=%d\n", dst->myDesc.Width, dst->myDesc.Height);
-
-       memcpy(lrDst.pBits, lrSrc.pBits, src->myDesc.Size);
-        IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8) src);
-        rc = IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8) dst);
-        TRACE("Unlocked src and dst\n");
-
-      } else {
-
-       FIXME("Wanted to copy all surfaces but size not compatible\n");
-        rc = D3DERR_INVALIDCALL;
-
-      }
-
-    } else {
 
-      if (NULL != pSourceRectsArray && NULL != pDestPointsArray) {
-
-        int bytesPerPixel = ((IDirect3DSurface8Impl*) pSourceSurface)->bytesPerPixel;
-        int i;
-
-        /* Copy rect by rect */
-        for (i = 0; i < cRects; i++) {
-            CONST RECT*  r = &pSourceRectsArray[i];
-            CONST POINT* p = &pDestPointsArray[i];
-            int copyperline;
-            int j;
-            D3DLOCKED_RECT lrSrc;
-            D3DLOCKED_RECT lrDst;
-            RECT dest_rect;
-
-            TRACE("Copying rect %d (%ld,%ld),(%ld,%ld) -> (%ld,%ld)\n", i, r->left, r->top, r->right, r->bottom, p->x, p->y);
-            if (src->myDesc.Format == D3DFMT_DXT1) { 
-                copyperline = ((r->right - r->left) * bytesPerPixel)/2; /* DXT1 is half byte per pixel */
-            } else {
-                copyperline = ((r->right - r->left) * bytesPerPixel);
-            }
-            IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8) src, &lrSrc, r, D3DLOCK_READONLY);
-            dest_rect.left  = p->x;
-            dest_rect.top   = p->y;
-            dest_rect.right = p->x + (r->right - r->left);
-            dest_rect.left  = p->y + (r->bottom - r->top);
-            IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8) dst, &lrDst, &dest_rect, 0L);
-            TRACE("Locked src and dst\n");
-
-            /* Find where to start */
-           for (j = 0; j < (r->bottom - r->top); j++) {
-               memcpy((char*) lrDst.pBits + (j * lrDst.Pitch), (char*) lrSrc.pBits + (j * lrSrc.Pitch), copyperline);
-           }
-
-            IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8) src);
-            rc = IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8) dst);
-            TRACE("Unlocked src and dst\n");
-        }
-      
-      } else {
-      
-       FIXME("Wanted to copy partial surfaces not implemented\n");
-        rc = D3DERR_INVALIDCALL;       
-       
-      }
-    }
+static HRESULT WINAPI IDirect3DDevice8Impl_CreateCubeTexture(LPDIRECT3DDEVICE8 iface, UINT EdgeLength, UINT Levels, DWORD Usage, 
+                                                        D3DFORMAT Format, D3DPOOL Pool, IDirect3DCubeTexture8** ppCubeTexture) {
 
-    return rc;
-}
-HRESULT  WINAPI  IDirect3DDevice8Impl_UpdateTexture(LPDIRECT3DDEVICE8 iface, IDirect3DBaseTexture8* pSourceTexture, IDirect3DBaseTexture8* pDestinationTexture) {
-    IDirect3DBaseTexture8Impl* src = (IDirect3DBaseTexture8Impl*) pSourceTexture;
-    IDirect3DBaseTexture8Impl* dst = (IDirect3DBaseTexture8Impl*) pDestinationTexture;
-    D3DRESOURCETYPE srcType;
-    D3DRESOURCETYPE dstType;
+    IDirect3DCubeTexture8Impl *object;
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    HRESULT hr = D3D_OK;
 
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    TRACE("(%p) : first try\n", This);
+    TRACE("(%p) : ELen(%d) Lvl(%d) Usage(%ld) fmt(%u), Pool(%d)\n" , This, EdgeLength, Levels, Usage, Format, Pool);
 
-    srcType = IDirect3DBaseTexture8Impl_GetType(pSourceTexture);
-    dstType = IDirect3DBaseTexture8Impl_GetType(pDestinationTexture);
+    /* Allocate the storage for the device */
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
 
-    if (srcType != dstType) {
-      return D3DERR_INVALIDCALL;
-    }
-    if (D3DPOOL_SYSTEMMEM != IDirect3DResource8Impl_GetPool((LPDIRECT3DRESOURCE8) src)) {
-      return D3DERR_INVALIDCALL;
-    }
-    if (D3DPOOL_DEFAULT != IDirect3DResource8Impl_GetPool((LPDIRECT3DRESOURCE8) dst)) {
-      return D3DERR_INVALIDCALL;
-    }
-    if (IDirect3DBaseTexture8Impl_IsDirty(pSourceTexture)) {
-      /** Only copy Dirty textures */
-      DWORD srcLevelCnt = IDirect3DBaseTexture8Impl_GetLevelCount(pSourceTexture);
-      DWORD dstLevelCnt = IDirect3DBaseTexture8Impl_GetLevelCount(pDestinationTexture);
-      DWORD skipLevels = (dstLevelCnt < srcLevelCnt) ? srcLevelCnt - dstLevelCnt : 0;
-      UINT i, j;
-
-      for (i = skipLevels; i < srcLevelCnt; ++i) {
-       HRESULT hr;
-
-       switch (srcType) { 
-       case D3DRTYPE_TEXTURE:
-         {
-           IDirect3DSurface8* srcSur = NULL;
-           IDirect3DSurface8* dstSur = NULL;
-           hr = IDirect3DTexture8Impl_GetSurfaceLevel((LPDIRECT3DTEXTURE8) src, i, &srcSur);
-           hr = IDirect3DTexture8Impl_GetSurfaceLevel((LPDIRECT3DTEXTURE8) dst, i - skipLevels, &dstSur);
-
-            /* Fixme: Work out how to just do the dirty regions (src or dst dirty region, and what
-                        about dst with less levels than the source?)                               */
-           IDirect3DDevice8Impl_CopyRects(iface, srcSur, NULL, 0, dstSur, NULL);
-
-           IDirect3DSurface8Impl_Release(srcSur);
-           IDirect3DSurface8Impl_Release(dstSur);
-         }
-         break;
-       case D3DRTYPE_VOLUMETEXTURE:
-         {
-           FIXME("D3DRTYPE_VOLUMETEXTURE reload currently not implemented\n");
-         }
-         break;
-       case D3DRTYPE_CUBETEXTURE:
-         {
-           IDirect3DSurface8* srcSur = NULL;
-           IDirect3DSurface8* dstSur = NULL;
-           for (j = 0; j < 5; ++j) {
-             hr = IDirect3DCubeTexture8Impl_GetCubeMapSurface((LPDIRECT3DCUBETEXTURE8) src, j, i, &srcSur);
-             hr = IDirect3DCubeTexture8Impl_GetCubeMapSurface((LPDIRECT3DCUBETEXTURE8) dst, j, i - skipLevels, &srcSur);
-             FIXME("D3DRTYPE_CUBETEXTURE does not support UpdateTexture yet\n");
-             IDirect3DSurface8Impl_Release(srcSur);
-             IDirect3DSurface8Impl_Release(dstSur);
-           }
-         }
-         break;
-       default:
-         break;
-       }
-      }
-      IDirect3DBaseTexture8Impl_SetDirty(pSourceTexture, FALSE);
+    if (NULL == object) {
+        FIXME("(%p) allocation of CubeTexture failed\n", This);
+        *ppCubeTexture = NULL;
+        return D3DERR_OUTOFVIDEOMEMORY;
     }
-    
-    return D3D_OK;
-}
-HRESULT  WINAPI  IDirect3DDevice8Impl_GetFrontBuffer(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pDestSurface) {
-    HRESULT hr;
-    D3DLOCKED_RECT lockedRect;
-    RECT wantedRect;
-    GLint  prev_store;
-    GLenum prev_read;
 
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-
-    FIXME("(%p) : see if behavior correct\n", This);
+    object->lpVtbl = &Direct3DCubeTexture8_Vtbl;
+    object->ref = 1;
+    hr = IWineD3DDevice_CreateCubeTexture(This->WineD3DDevice, EdgeLength, Levels, Usage & WINED3DUSAGE_MASK,
+                                 (WINED3DFORMAT)Format, (WINED3DPOOL) Pool, &object->wineD3DCubeTexture, NULL, (IUnknown*)object,
+                                 D3D8CB_CreateSurface);
 
-    if (D3DFMT_A8R8G8B8 != ((IDirect3DSurface8Impl*) pDestSurface)->myDesc.Format) {
-      ERR("(%p) : surface(%p) have a invalid format\n", This, pDestSurface);
-      return D3DERR_INVALIDCALL;
-    }
-    
-    wantedRect.left = 0;
-    wantedRect.top = 0;
-    wantedRect.right = This->PresentParms.BackBufferWidth;
-    wantedRect.bottom = This->PresentParms.BackBufferHeight;
-    
-    hr = IDirect3DSurface8Impl_LockRect(pDestSurface, &lockedRect, &wantedRect, 0);
-    if (FAILED(hr)) {
-      ERR("(%p) : cannot lock surface\n", This);
-      return D3DERR_INVALIDCALL;
-    }
+    if (hr != D3D_OK){
 
-    ENTER_GL();
-
-    glFlush();
-    vcheckGLcall("glFlush");
-    glGetIntegerv(GL_READ_BUFFER, &prev_read);
-    vcheckGLcall("glIntegerv");
-    glGetIntegerv(GL_PACK_SWAP_BYTES, &prev_store);
-    vcheckGLcall("glIntegerv");
-    glReadBuffer(GL_FRONT);
-    vcheckGLcall("glReadBuffer");
-    glPixelStorei(GL_PACK_SWAP_BYTES, TRUE);
-    vcheckGLcall("glPixelStorei");
-    /* stupid copy */
-    {
-      long j;
-      for (j = 0; j < This->PresentParms.BackBufferHeight; ++j) {
-       /*memcpy(lockedRect.pBits + (j * lockedRect.Pitch), This->frontBuffer->allocatedMemory + (j * i), i);*/
-       glReadPixels(0, This->PresentParms.BackBufferHeight - j - 1, This->PresentParms.BackBufferWidth, 1,
-                    GL_BGRA, GL_UNSIGNED_BYTE, ((char*) lockedRect.pBits) + (j * lockedRect.Pitch));
-       vcheckGLcall("glReadPixels");
-      }
+        /* free up object */
+        FIXME("(%p) call to IWineD3DDevice_CreateCubeTexture failed\n", This);
+        HeapFree(GetProcessHeap(), 0, object);
+        *ppCubeTexture = NULL;
+    } else {
+        IUnknown_AddRef(iface);
+        object->parentDevice = iface;
+        *ppCubeTexture = (LPDIRECT3DCUBETEXTURE8) object;
     }
-    glPixelStorei(GL_PACK_SWAP_BYTES, prev_store);
-    vcheckGLcall("glPixelStorei");
-    glReadBuffer(prev_read);
-    vcheckGLcall("glReadBuffer");
-
-    LEAVE_GL();
 
-    hr = IDirect3DSurface8Impl_UnlockRect(pDestSurface);
+    TRACE("(%p) returning %p\n",This, *ppCubeTexture);
     return hr;
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_SetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pRenderTarget, IDirect3DSurface8* pNewZStencil) {
-    HRESULT hr;
 
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
+static HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexBuffer(LPDIRECT3DDEVICE8 iface, UINT Size, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer8** ppVertexBuffer) {
+    IDirect3DVertexBuffer8Impl *object;
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    HRESULT hrc = D3D_OK;
 
-    if ((IDirect3DSurface8Impl*) pRenderTarget == This->renderTarget && (IDirect3DSurface8Impl*) pNewZStencil == This->stencilBufferTarget) {
-      TRACE("Trying to do a NOP SetRenderTarget operation\n");
-      return D3D_OK;
+    TRACE("(%p) Relay\n", This);
+    /* Allocate the storage for the device */
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBuffer8Impl));
+    if (NULL == object) {
+        FIXME("Allocation of memory failed\n");
+        *ppVertexBuffer = NULL;
+        return D3DERR_OUTOFVIDEOMEMORY;
     }
 
-    IDirect3DDevice8Impl_CleanRender(iface);
-
-    if ((IDirect3DSurface8Impl*) pRenderTarget == This->frontBuffer && (IDirect3DSurface8Impl*) pNewZStencil == This->depthStencilBuffer) {
-      IDirect3DSurface8Impl* tmp;
-
-      TRACE("retoring SetRenderTarget defaults\n");
+    object->lpVtbl = &Direct3DVertexBuffer8_Vtbl;
+    object->ref = 1;
+    hrc = IWineD3DDevice_CreateVertexBuffer(This->WineD3DDevice, Size, Usage & WINED3DUSAGE_MASK, FVF, (WINED3DPOOL) Pool, &(object->wineD3DVertexBuffer), NULL, (IUnknown *)object);
 
-      tmp = This->renderTarget;
-      This->renderTarget = (IDirect3DSurface8Impl*) This->frontBuffer;
-      IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) This->renderTarget);
-      IDirect3DSurface8Impl_Release((LPDIRECT3DSURFACE8) tmp);
-      
-      tmp = This->stencilBufferTarget;
-      This->stencilBufferTarget = (IDirect3DSurface8Impl*) This->depthStencilBuffer;
-      if (NULL != This->stencilBufferTarget) IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) This->stencilBufferTarget);
-      if (NULL != tmp) IDirect3DSurface8Impl_Release((LPDIRECT3DSURFACE8) tmp);
+    if (D3D_OK != hrc) {
 
-      return D3D_OK;
+        /* free up object */
+        FIXME("(%p) call to IWineD3DDevice_CreateVertexBuffer failed\n", This);
+        HeapFree(GetProcessHeap(), 0, object);
+        *ppVertexBuffer = NULL;
+    } else {
+        IUnknown_AddRef(iface);
+        object->parentDevice = iface;
+        *ppVertexBuffer = (LPDIRECT3DVERTEXBUFFER8) object;
     }
-
-    TRACE("(%p) : expect crash newRender@%p newZStencil@%p\n", This, pRenderTarget, pNewZStencil);
-
-    hr = IDirect3DDevice8Impl_ActiveRender(iface, pRenderTarget, pNewZStencil);
-    
-    return hr;
-}
-
-HRESULT  WINAPI  IDirect3DDevice8Impl_GetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppRenderTarget) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-
-    TRACE("(%p)->(%p) default(%p)\n", This, This->renderTarget, This->frontBuffer);
-    
-    *ppRenderTarget = (LPDIRECT3DSURFACE8) This->renderTarget;
-    IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppRenderTarget);
-    
-    return D3D_OK;
+    return hrc;
 }
 
-HRESULT  WINAPI  IDirect3DDevice8Impl_GetDepthStencilSurface(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppZStencilSurface) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
+static HRESULT WINAPI IDirect3DDevice8Impl_CreateIndexBuffer(LPDIRECT3DDEVICE8 iface, UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer8** ppIndexBuffer) {
+    IDirect3DIndexBuffer8Impl *object;
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    HRESULT hrc = D3D_OK;
 
-    TRACE("(%p)->(%p) default(%p)\n", This, This->stencilBufferTarget, This->depthStencilBuffer);
-    
-    /* Note inc ref on returned surface */
-    *ppZStencilSurface = (LPDIRECT3DSURFACE8) This->stencilBufferTarget;
-    if (NULL != *ppZStencilSurface) IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) *ppZStencilSurface);
+    TRACE("(%p) Relay\n", This);
+    /* Allocate the storage for the device */
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+    if (NULL == object) {
+        FIXME("Allocation of memory failed\n");
+        *ppIndexBuffer = NULL;
+        return D3DERR_OUTOFVIDEOMEMORY;
+    }
 
-    return D3D_OK;
-}
+    object->lpVtbl = &Direct3DIndexBuffer8_Vtbl;
+    object->ref = 1;
+    TRACE("Calling wined3d create index buffer\n");
+    hrc = IWineD3DDevice_CreateIndexBuffer(This->WineD3DDevice, Length, Usage & WINED3DUSAGE_MASK, Format, (WINED3DPOOL) Pool, &object->wineD3DIndexBuffer, NULL, (IUnknown *)object);
 
-HRESULT  WINAPI  IDirect3DDevice8Impl_BeginScene(LPDIRECT3DDEVICE8 iface) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    TRACE("(%p) : stub\n", This);
-    return D3D_OK;
-}
-HRESULT  WINAPI  IDirect3DDevice8Impl_EndScene(LPDIRECT3DDEVICE8 iface) {
-    IDirect3DBaseTexture8* cont = NULL;
-    HRESULT hr;
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    TRACE("(%p)\n", This);
-
-    ENTER_GL();
-
-    glFlush();
-    checkGLcall("glFlush");
-
-    /* Useful for debugging sometimes!
-    printf("Hit Enter ...\n");
-    getchar(); */
-
-    if (This->frontBuffer != This->renderTarget) {
-      {
-       GLenum prev_read;
-       glGetIntegerv(GL_READ_BUFFER, &prev_read);
-       vcheckGLcall("glIntegerv");
-       glReadBuffer(GL_BACK);
-       vcheckGLcall("glReadBuffer");
-       {
-         long j;
-         long pitch = This->renderTarget->myDesc.Width * This->renderTarget->bytesPerPixel;
-
-          if (This->renderTarget->myDesc.Format == D3DFMT_DXT1) /* DXT1 is half byte per pixel */
-              pitch = pitch / 2;
-
-         for (j = 0; j < This->renderTarget->myDesc.Height; ++j) {
-           glReadPixels(0, 
-                        This->renderTarget->myDesc.Height - j - 1, 
-                        This->renderTarget->myDesc.Width, 
-                        1,
-                        D3DFmt2GLFmt(This, This->renderTarget->myDesc.Format), 
-                        D3DFmt2GLType(This, This->renderTarget->myDesc.Format), 
-                        This->renderTarget->allocatedMemory + j * pitch);
-           vcheckGLcall("glReadPixels");
-         }
-       }      
-       glReadBuffer(prev_read);
-       vcheckGLcall("glReadBuffer");
-      }
-
-      hr = IDirect3DSurface8_GetContainer((LPDIRECT3DSURFACE8) This->renderTarget, &IID_IDirect3DBaseTexture8, (void**) &cont);
-      if (SUCCEEDED(hr) && NULL != cont) {
-       /** always dirtify for now. we must find a better way to see that surface have been modified */
-       IDirect3DBaseTexture8Impl_SetDirty(cont, TRUE);
-       IDirect3DBaseTexture8_PreLoad(cont);
-       IDirect3DBaseTexture8Impl_Release(cont);
-       cont = NULL;
-      }
-    }
+    if (D3D_OK != hrc) {
 
-    LEAVE_GL();
-    return D3D_OK;
-}
-HRESULT  WINAPI  IDirect3DDevice8Impl_Clear(LPDIRECT3DDEVICE8 iface, DWORD Count, CONST D3DRECT* pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-
-    /* TODO: From MSDN This method fails if you specify the D3DCLEAR_ZBUFFER or D3DCLEAR_STENCIL flags when the
-      render target does not have an attached depth buffer. Similarly, if you specify the D3DCLEAR_STENCIL flag
-      when the depth-buffer format does not contain stencil buffer information, this method fails. */
-    GLbitfield glMask = 0;
-    GLboolean old_ztest;
-    GLfloat old_z_clear_value;
-    GLint   old_stencil_clear_value;
-    GLfloat old_color_clear_value[4];
-    int i;
-    CONST D3DRECT* curRect;
-
-    TRACE("(%p) Count (%ld), pRects (%p), Flags (%lx), Z (%f), Stencil (%ld)\n", This,
-          Count, pRects, Flags, Z, Stencil);
-
-    ENTER_GL();
-    glEnable(GL_SCISSOR_TEST);
-    checkGLcall("glEnable GL_SCISSOR_TEST");
-    if (Count > 0 && pRects) {
-        glEnable(GL_SCISSOR_TEST);
-        checkGLcall("glEnable GL_SCISSOR_TEST");
-        curRect = pRects;
+        /* free up object */
+        FIXME("(%p) call to IWineD3DDevice_CreateIndexBuffer failed\n", This);
+        HeapFree(GetProcessHeap(), 0, object);
+        *ppIndexBuffer = NULL;
     } else {
-        curRect = NULL;
+        IUnknown_AddRef(iface);
+        object->parentDevice = iface;
+        *ppIndexBuffer = (LPDIRECT3DINDEXBUFFER8)object;
     }
+    return hrc;
+}
 
-    /* Only set the values up once, as they are not changing */
-    if (Flags & D3DCLEAR_STENCIL) {    
-        glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &old_stencil_clear_value);
-        glClearStencil(Stencil);
-        checkGLcall("glClearStencil");
-        glMask = glMask | GL_STENCIL_BUFFER_BIT;
+static HRESULT WINAPI IDirect3DDevice8Impl_CreateSurface(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, BOOL Lockable, BOOL Discard, UINT Level, IDirect3DSurface8 **ppSurface,D3DRESOURCETYPE Type, UINT Usage,D3DPOOL Pool, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality)  {
+    HRESULT hrc;
+    IDirect3DSurface8Impl *object;
+    IDirect3DDevice8Impl  *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n", This);
+    if(MultisampleQuality < 0) { 
+        FIXME("MultisampleQuality out of range %ld, substituting 0\n", MultisampleQuality);
+        /*FIXME: Find out what windows does with a MultisampleQuality < 0 */
+        MultisampleQuality=0;
     }
 
-    if (Flags & D3DCLEAR_ZBUFFER) {
-        glGetBooleanv(GL_DEPTH_WRITEMASK, &old_ztest);
-        glDepthMask(GL_TRUE); 
-        glGetFloatv(GL_DEPTH_CLEAR_VALUE, &old_z_clear_value);
-        glClearDepth(Z);
-        checkGLcall("glClearDepth");
-        glMask = glMask | GL_DEPTH_BUFFER_BIT;
+    if(MultisampleQuality > 0){
+        FIXME("MultisampleQuality set to %ld, substituting 0\n" , MultisampleQuality);
+        /*
+        MultisampleQuality
+        [in] Quality level. The valid range is between zero and one less than the level returned by pQualityLevels used by IDirect3D8::CheckDeviceMultiSampleType. Passing a larger value returns the error D3DERR_INVALIDCALL. The MultisampleQuality values of paired render targets, depth stencil surfaces, and the MultiSample type must all match.
+        */
+        MultisampleQuality=0;
     }
+    /*FIXME: Check MAX bounds of MultisampleQuality*/
 
-    if (Flags & D3DCLEAR_TARGET) {
-        TRACE("Clearing screen with glClear to color %lx\n", Color);
-        glGetFloatv(GL_COLOR_CLEAR_VALUE, old_color_clear_value);
-        glClearColor(((Color >> 16) & 0xFF) / 255.0f, 
-                    ((Color >>  8) & 0xFF) / 255.0f,
-                     ((Color >>  0) & 0xFF) / 255.0f, 
-                    ((Color >> 24) & 0xFF) / 255.0f);
-        checkGLcall("glClearColor");
-        glMask = glMask | GL_COLOR_BUFFER_BIT;
+    /* Allocate the storage for the device */
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl));
+    if (NULL == object) {
+        FIXME("Allocation of memory failed\n");
+        *ppSurface = NULL;
+        return D3DERR_OUTOFVIDEOMEMORY;
     }
 
-    /* Now process each rect in turn */
-    for (i = 0; i < Count || i == 0; i++) {
-
-        if (curRect) {
-            /* Note gl uses lower left, width/height */
-            TRACE("(%p) %p Rect=(%ld,%ld)->(%ld,%ld) glRect=(%ld,%ld), len=%ld, hei=%ld\n", This, curRect,
-                  curRect->x1, curRect->y1, curRect->x2, curRect->y2,
-                  curRect->x1, (This->PresentParms.BackBufferHeight - curRect->y2), 
-                  curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
-            glScissor(curRect->x1, (This->PresentParms.BackBufferHeight - curRect->y2), 
-                      curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
-            checkGLcall("glScissor");
-        } else {
-            glScissor(This->StateBlock->viewport.X, 
-                      (This->PresentParms.BackBufferHeight - (This->StateBlock->viewport.Y + This->StateBlock->viewport.Height)), 
-                      This->StateBlock->viewport.Width, 
-                      This->StateBlock->viewport.Height);
-            checkGLcall("glScissor");
-        }
-
-        /* Clear the selected rectangle (or full screen) */
-        glClear(glMask);
-        checkGLcall("glClear");
+    object->lpVtbl = &Direct3DSurface8_Vtbl;
+    object->ref = 1;
 
-        /* Step to the next rectangle */
-        if (curRect) curRect = curRect + sizeof(D3DRECT);
-    }
+    TRACE("(%p) : w(%d) h(%d) fmt(%d) surf@%p\n", This, Width, Height, Format, *ppSurface);
 
-    /* Restore the old values (why..?) */
-    if (Flags & D3DCLEAR_STENCIL) {
-        glClearStencil(old_stencil_clear_value);
-    }    
-    if (Flags & D3DCLEAR_ZBUFFER) {
-        glDepthMask(old_ztest);
-        glClearDepth(old_z_clear_value);
-    }
-    if (Flags & D3DCLEAR_TARGET) {
-        glClearColor(old_color_clear_value[0], 
-                     old_color_clear_value[1],
-                     old_color_clear_value[2], 
-                     old_color_clear_value[3]);
+    hrc = IWineD3DDevice_CreateSurface(This->WineD3DDevice, Width, Height, Format, Lockable, Discard, Level,  &object->wineD3DSurface, Type, Usage & WINED3DUSAGE_MASK, (WINED3DPOOL) Pool,MultiSample,MultisampleQuality, NULL, SURFACE_OPENGL, (IUnknown *)object);
+    if (hrc != D3D_OK || NULL == object->wineD3DSurface) {
+       /* free up object */
+        FIXME("(%p) call to IWineD3DDevice_CreateSurface failed\n", This);
+        HeapFree(GetProcessHeap(), 0, object);
+        *ppSurface = NULL;
+    } else {
+        IUnknown_AddRef(iface);
+        object->parentDevice = iface;
+        *ppSurface = (LPDIRECT3DSURFACE8) object;
     }
+    return hrc;
+}
 
-    if (Count > 0 && pRects) {
-        glDisable(GL_SCISSOR_TEST);
-        checkGLcall("glDisable");
-    }
-    LEAVE_GL();
+static HRESULT WINAPI IDirect3DDevice8Impl_CreateRenderTarget(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, BOOL Lockable, IDirect3DSurface8** ppSurface) {
+    TRACE("Relay\n");
 
-    return D3D_OK;
+    return IDirect3DDevice8Impl_CreateSurface(iface, Width, Height, Format, Lockable, FALSE /* Discard */, 0 /* Level */ , ppSurface, D3DRTYPE_SURFACE, D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT, MultiSample, 0);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_SetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE d3dts, CONST D3DMATRIX* lpmatrix) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    int k;
-
-    /* Most of this routine, comments included copied from ddraw tree initially: */
-    TRACE("(%p) : State=%d\n", This, d3dts);
-
-    /* Handle recording of state blocks */
-    if (This->isRecordingState) {
-        TRACE("Recording... not performing anything\n");
-        This->UpdateStateBlock->Changed.transform[d3dts] = TRUE;
-        This->UpdateStateBlock->Set.transform[d3dts] = TRUE;
-        memcpy(&This->UpdateStateBlock->transforms[d3dts], lpmatrix, sizeof(D3DMATRIX));
-        return D3D_OK;
-    }
-
-    /*
-     * if the new matrix is the same as the current one,
-     * we cut off any further processing. this seems to be a reasonable
-     * optimization because as was noticed, some apps (warcraft3 for example)
-     * tend towards setting the same matrix repeatedly for some dumb reason.
-     *
-     * From here on we assume that the new matrix is different, wherever it matters
-     * but note
-     */
-    if (!memcmp(&This->StateBlock->transforms[d3dts].u.m[0][0], lpmatrix, sizeof(D3DMATRIX))) {
-        TRACE("The app is setting the same matrix over again\n");
-        return D3D_OK;
-    } else {
-        conv_mat(lpmatrix, &This->StateBlock->transforms[d3dts].u.m[0][0]);
-    }
 
-    /*
-       ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
-       where ViewMat = Camera space, WorldMat = world space.
+static HRESULT WINAPI IDirect3DDevice8Impl_CreateDepthStencilSurface(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, IDirect3DSurface8** ppSurface) {
+    TRACE("Relay\n");
+    /* TODO: Verify that Discard is false */
+    return IDirect3DDevice8Impl_CreateSurface(iface, Width, Height, Format, TRUE /* Lockable */, FALSE, 0 /* Level */
+                                               ,ppSurface, D3DRTYPE_SURFACE, D3DUSAGE_DEPTHSTENCIL,
+                                                D3DPOOL_DEFAULT, MultiSample, 0);
+}
 
-       In OpenGL, camera and world space is combined into GL_MODELVIEW
-       matrix.  The Projection matrix stay projection matrix. 
-     */
+static HRESULT WINAPI IDirect3DDevice8Impl_CreateImageSurface(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, IDirect3DSurface8** ppSurface) {
+    TRACE("Relay\n");
 
-    /* Capture the times we can just ignore the change */
-    if (d3dts == D3DTS_WORLDMATRIX(0)) {
-        This->modelview_valid = FALSE;
-        return D3D_OK;
-
-    } else if (d3dts == D3DTS_PROJECTION) {
-        This->proj_valid = FALSE;
-        return D3D_OK;
-
-    } else if (d3dts >= D3DTS_WORLDMATRIX(1) && d3dts <= D3DTS_WORLDMATRIX(255)) { /* Indexed Vertex Blending Matrices 256 -> 511  */
-        /* Use arb_vertex_blend or NV_VERTEX_WEIGHTING? */
-        FIXME("D3DTS_WORLDMATRIX(1..255) not handled\n");
-        return D3D_OK;
-    } 
-    
-    /* Chances are we really are going to have to change a matrix */
-    ENTER_GL();
-
-    if (d3dts >= D3DTS_TEXTURE0 && d3dts <= D3DTS_TEXTURE7) { /* handle texture matrices */
-        if (d3dts < GL_LIMITS(textures)) {
-            int tex = d3dts - D3DTS_TEXTURE0;
-#if defined(GL_VERSION_1_3)
-            glActiveTexture(GL_TEXTURE0 + tex);
-#else 
-            glActiveTextureARB(GL_TEXTURE0_ARB + tex);
-#endif
-            set_texture_matrix((float *)lpmatrix, This->UpdateStateBlock->texture_state[tex][D3DTSS_TEXTURETRANSFORMFLAGS]);
-        }
+    return IDirect3DDevice8Impl_CreateSurface(iface, Width, Height, Format, TRUE /* Loackable */ , FALSE /*Discard*/ , 0 /* Level */ , ppSurface, D3DRTYPE_SURFACE, 0 /* Usage (undefined/none) */ , D3DPOOL_SCRATCH, D3DMULTISAMPLE_NONE, 0 /* MultisampleQuality */);
+}
 
-    } else if (d3dts == D3DTS_VIEW) { /* handle the VIEW matrice */
-
-        PLIGHTINFOEL *lightChain = NULL;
-        float identity[16] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1};
-        This->modelview_valid = FALSE;
-        This->view_ident = !memcmp(lpmatrix, identity, 16*sizeof(float));
-        glMatrixMode(GL_MODELVIEW);
-        checkGLcall("glMatrixMode(GL_MODELVIEW)");
-        glPushMatrix();
-        glLoadMatrixf((float *)lpmatrix);
-        checkGLcall("glLoadMatrixf(...)");
-
-        /* If we are changing the View matrix, reset the light and clipping planes to the new view   
-         * NOTE: We have to reset the positions even if the light/plane is not currently
-         *       enabled, since the call to enable it will not reset the position.                 
-         * NOTE2: Apparently texture transforms do NOT need reapplying
-         */
-
-        /* Reset lights */
-        lightChain = This->StateBlock->lights;
-        while (lightChain && lightChain->glIndex != -1) {
-            glLightfv(GL_LIGHT0 + lightChain->glIndex, GL_POSITION, lightChain->lightPosn);
-            checkGLcall("glLightfv posn");
-            glLightfv(GL_LIGHT0 + lightChain->glIndex, GL_SPOT_DIRECTION, lightChain->lightDirn);
-            checkGLcall("glLightfv dirn");
-            lightChain = lightChain->next;
-        }
-        /* Reset Clipping Planes if clipping is enabled */
-        for (k = 0; k < GL_LIMITS(clipplanes); k++) {
-            glClipPlane(GL_CLIP_PLANE0 + k, This->StateBlock->clipplane[k]);
-            checkGLcall("glClipPlane");
-        }
-        glPopMatrix();
+static HRESULT WINAPI IDirect3DDevice8Impl_CopyRects(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8 *pSourceSurface, CONST RECT *pSourceRects, UINT cRects, IDirect3DSurface8 *pDestinationSurface, CONST POINT *pDestPoints) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
 
-    } else { /* What was requested!?? */
-        WARN("invalid matrix specified: %i\n", d3dts);
+    TRACE("(%p) Relay\n" , This);
 
-    }
+    return IWineD3DDevice_CopyRects(This->WineD3DDevice, pSourceSurface == NULL ? NULL : ((IDirect3DSurface8Impl *)pSourceSurface)->wineD3DSurface,
+            pSourceRects, cRects, pDestinationSurface == NULL ? NULL : ((IDirect3DSurface8Impl *)pDestinationSurface)->wineD3DSurface, pDestPoints);
+}
 
-    /* Release lock, all done */
-    LEAVE_GL();
-    return D3D_OK;
+static HRESULT WINAPI IDirect3DDevice8Impl_UpdateTexture(LPDIRECT3DDEVICE8 iface, IDirect3DBaseTexture8* pSourceTexture, IDirect3DBaseTexture8* pDestinationTexture) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n" , This);
 
-}
-HRESULT  WINAPI  IDirect3DDevice8Impl_GetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State,D3DMATRIX* pMatrix) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    TRACE("(%p) : for State %d\n", This, State);
-    memcpy(pMatrix, &This->StateBlock->transforms[State], sizeof(D3DMATRIX));
-    return D3D_OK;
+    return IWineD3DDevice_UpdateTexture(This->WineD3DDevice,  ((IDirect3DBaseTexture8Impl *)pSourceTexture)->wineD3DBaseTexture, ((IDirect3DBaseTexture8Impl *)pDestinationTexture)->wineD3DBaseTexture);
 }
 
-HRESULT  WINAPI  IDirect3DDevice8Impl_MultiplyTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix) {
-    D3DMATRIX *mat = NULL;
-    D3DMATRIX temp;
+static HRESULT WINAPI IDirect3DDevice8Impl_GetFrontBuffer(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pDestSurface) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    IDirect3DSurface8Impl *destSurface = (IDirect3DSurface8Impl *)pDestSurface;
 
-    /* Note: Using UpdateStateBlock means it would be recorded in a state block change,
-        but works regardless of recording being on. 
-        If this is found to be wrong, change to StateBlock.                             */
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    TRACE("(%p) : For state %u\n", This, State);
+    TRACE("(%p) Relay\n" , This);
 
-    if (State < HIGHEST_TRANSFORMSTATE)
-    {
-        mat = &This->UpdateStateBlock->transforms[State];
-    } else {
-        FIXME("Unhandled transform state!!\n");
+    if (pDestSurface == NULL) {
+        WARN("(%p) : Caller passed NULL as pDestSurface returning D3DERR_INVALIDCALL\n", This);
+        return D3DERR_INVALIDCALL;
     }
 
-    /* Copied from ddraw code:  */
-    temp.u.s._11 = (mat->u.s._11 * pMatrix->u.s._11) + (mat->u.s._21 * pMatrix->u.s._12) + (mat->u.s._31 * pMatrix->u.s._13) + (mat->u.s._41 * pMatrix->u.s._14);
-    temp.u.s._21 = (mat->u.s._11 * pMatrix->u.s._21) + (mat->u.s._21 * pMatrix->u.s._22) + (mat->u.s._31 * pMatrix->u.s._23) + (mat->u.s._41 * pMatrix->u.s._24);
-    temp.u.s._31 = (mat->u.s._11 * pMatrix->u.s._31) + (mat->u.s._21 * pMatrix->u.s._32) + (mat->u.s._31 * pMatrix->u.s._33) + (mat->u.s._41 * pMatrix->u.s._34);
-    temp.u.s._41 = (mat->u.s._11 * pMatrix->u.s._41) + (mat->u.s._21 * pMatrix->u.s._42) + (mat->u.s._31 * pMatrix->u.s._43) + (mat->u.s._41 * pMatrix->u.s._44);
-
-    temp.u.s._12 = (mat->u.s._12 * pMatrix->u.s._11) + (mat->u.s._22 * pMatrix->u.s._12) + (mat->u.s._32 * pMatrix->u.s._13) + (mat->u.s._42 * pMatrix->u.s._14);
-    temp.u.s._22 = (mat->u.s._12 * pMatrix->u.s._21) + (mat->u.s._22 * pMatrix->u.s._22) + (mat->u.s._32 * pMatrix->u.s._23) + (mat->u.s._42 * pMatrix->u.s._24);
-    temp.u.s._32 = (mat->u.s._12 * pMatrix->u.s._31) + (mat->u.s._22 * pMatrix->u.s._32) + (mat->u.s._32 * pMatrix->u.s._33) + (mat->u.s._42 * pMatrix->u.s._34);
-    temp.u.s._42 = (mat->u.s._12 * pMatrix->u.s._41) + (mat->u.s._22 * pMatrix->u.s._42) + (mat->u.s._32 * pMatrix->u.s._43) + (mat->u.s._42 * pMatrix->u.s._44);
-
-    temp.u.s._13 = (mat->u.s._13 * pMatrix->u.s._11) + (mat->u.s._23 * pMatrix->u.s._12) + (mat->u.s._33 * pMatrix->u.s._13) + (mat->u.s._43 * pMatrix->u.s._14);
-    temp.u.s._23 = (mat->u.s._13 * pMatrix->u.s._21) + (mat->u.s._23 * pMatrix->u.s._22) + (mat->u.s._33 * pMatrix->u.s._23) + (mat->u.s._43 * pMatrix->u.s._24);
-    temp.u.s._33 = (mat->u.s._13 * pMatrix->u.s._31) + (mat->u.s._23 * pMatrix->u.s._32) + (mat->u.s._33 * pMatrix->u.s._33) + (mat->u.s._43 * pMatrix->u.s._34);
-    temp.u.s._43 = (mat->u.s._13 * pMatrix->u.s._41) + (mat->u.s._23 * pMatrix->u.s._42) + (mat->u.s._33 * pMatrix->u.s._43) + (mat->u.s._43 * pMatrix->u.s._44);
-
-    temp.u.s._14 = (mat->u.s._14 * pMatrix->u.s._11) + (mat->u.s._24 * pMatrix->u.s._12) + (mat->u.s._34 * pMatrix->u.s._13) + (mat->u.s._44 * pMatrix->u.s._14);
-    temp.u.s._24 = (mat->u.s._14 * pMatrix->u.s._21) + (mat->u.s._24 * pMatrix->u.s._22) + (mat->u.s._34 * pMatrix->u.s._23) + (mat->u.s._44 * pMatrix->u.s._24);
-    temp.u.s._34 = (mat->u.s._14 * pMatrix->u.s._31) + (mat->u.s._24 * pMatrix->u.s._32) + (mat->u.s._34 * pMatrix->u.s._33) + (mat->u.s._44 * pMatrix->u.s._34);
-    temp.u.s._44 = (mat->u.s._14 * pMatrix->u.s._41) + (mat->u.s._24 * pMatrix->u.s._42) + (mat->u.s._34 * pMatrix->u.s._43) + (mat->u.s._44 * pMatrix->u.s._44);
-
-    /* Apply change via set transform - will reapply to eg. lights this way */
-    IDirect3DDevice8Impl_SetTransform(iface, State, &temp);
-    return D3D_OK;
+    return IWineD3DDevice_GetFrontBufferData(This->WineD3DDevice, 0, destSurface->wineD3DSurface);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_SetViewport(LPDIRECT3DDEVICE8 iface, CONST D3DVIEWPORT8* pViewport) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-
-    TRACE("(%p)\n", This);
-    This->UpdateStateBlock->Changed.viewport = TRUE;
-    This->UpdateStateBlock->Set.viewport = TRUE;
-    memcpy(&This->UpdateStateBlock->viewport, pViewport, sizeof(D3DVIEWPORT8));
-
-    /* Handle recording of state blocks */
-    if (This->isRecordingState) {
-        TRACE("Recording... not performing anything\n");
-        return D3D_OK;
-    }
-
-    ENTER_GL();
-
-    TRACE("(%p) : x=%ld, y=%ld, wid=%ld, hei=%ld, minz=%f, maxz=%f\n", This,
-          pViewport->X, pViewport->Y, pViewport->Width, pViewport->Height, pViewport->MinZ, pViewport->MaxZ);
-
-    glDepthRange(pViewport->MinZ, pViewport->MaxZ);
-    checkGLcall("glDepthRange");
-    /* Note: GL requires lower left, DirectX supplies upper left */
-    glViewport(pViewport->X, (This->PresentParms.BackBufferHeight - (pViewport->Y + pViewport->Height)), 
-               pViewport->Width, pViewport->Height);
-    checkGLcall("glViewport");
 
-    LEAVE_GL();
+static HRESULT WINAPI IDirect3DDevice8Impl_SetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8* pRenderTarget, IDirect3DSurface8* pNewZStencil) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    IDirect3DSurface8Impl *pSurface = (IDirect3DSurface8Impl *)pRenderTarget;
+    IDirect3DSurface8Impl *pZSurface = (IDirect3DSurface8Impl *)pNewZStencil;
+    TRACE("(%p) Relay\n" , This);
 
-    return D3D_OK;
+    IWineD3DDevice_SetDepthStencilSurface(This->WineD3DDevice, NULL == pZSurface ? NULL : (IWineD3DSurface *)pZSurface->wineD3DSurface);
 
-}
-HRESULT  WINAPI  IDirect3DDevice8Impl_GetViewport(LPDIRECT3DDEVICE8 iface, D3DVIEWPORT8* pViewport) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    TRACE("(%p)\n", This);
-    memcpy(pViewport, &This->StateBlock->viewport, sizeof(D3DVIEWPORT8));
-    return D3D_OK;
+    return IWineD3DDevice_SetRenderTarget(This->WineD3DDevice, 0, pSurface ? (IWineD3DSurface *)pSurface->wineD3DSurface : NULL);
 }
 
-HRESULT  WINAPI  IDirect3DDevice8Impl_SetMaterial(LPDIRECT3DDEVICE8 iface, CONST D3DMATERIAL8* pMaterial) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
+static HRESULT  WINAPI  IDirect3DDevice8Impl_GetRenderTarget(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppRenderTarget) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    HRESULT hr = D3D_OK;
+    IWineD3DSurface *pRenderTarget;
 
-    This->UpdateStateBlock->Changed.material = TRUE;
-    This->UpdateStateBlock->Set.material = TRUE;
-    memcpy(&This->UpdateStateBlock->material, pMaterial, sizeof(D3DMATERIAL8));
+    TRACE("(%p) Relay\n" , This);
 
-    /* Handle recording of state blocks */
-    if (This->isRecordingState) {
-        TRACE("Recording... not performing anything\n");
-        return D3D_OK;
+    if (ppRenderTarget == NULL) {
+        return D3DERR_INVALIDCALL;
     }
+    hr = IWineD3DDevice_GetRenderTarget(This->WineD3DDevice, 0, &pRenderTarget);
 
-    ENTER_GL();
-    TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This, pMaterial->Diffuse.r, pMaterial->Diffuse.g, pMaterial->Diffuse.b, pMaterial->Diffuse.a);
-    TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This, pMaterial->Ambient.r, pMaterial->Ambient.g, pMaterial->Ambient.b, pMaterial->Ambient.a);
-    TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This, pMaterial->Specular.r, pMaterial->Specular.g, pMaterial->Specular.b, pMaterial->Specular.a);
-    TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This, pMaterial->Emissive.r, pMaterial->Emissive.g, pMaterial->Emissive.b, pMaterial->Emissive.a);
-    TRACE("(%p) : Power (%f)\n", This, pMaterial->Power);
-
-    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*) &This->UpdateStateBlock->material.Ambient);
-    checkGLcall("glMaterialfv");
-    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*) &This->UpdateStateBlock->material.Diffuse);
-    checkGLcall("glMaterialfv");
-
-    /* Only change material color if specular is enabled, otherwise it is set to black */
-    if (This->StateBlock->renderstate[D3DRS_SPECULARENABLE]) {
-       glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*) &This->UpdateStateBlock->material.Specular);
-       checkGLcall("glMaterialfv");
+    if (hr == D3D_OK && pRenderTarget != NULL) {
+        IWineD3DResource_GetParent((IWineD3DResource *)pRenderTarget,(IUnknown**)ppRenderTarget);
+        IWineD3DResource_Release((IWineD3DResource *)pRenderTarget);
     } else {
-       float black[4] = {0.0f, 0.0f, 0.0f, 0.0f};
-       glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
-       checkGLcall("glMaterialfv");
+        FIXME("Call to IWineD3DDevice_GetRenderTarget failed\n");
+        *ppRenderTarget = NULL;
     }
-    glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float*) &This->UpdateStateBlock->material.Emissive);
-    checkGLcall("glMaterialfv");
-    glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, This->UpdateStateBlock->material.Power);
-    checkGLcall("glMaterialf");
 
-    LEAVE_GL();
-    return D3D_OK;
-}
-HRESULT  WINAPI  IDirect3DDevice8Impl_GetMaterial(LPDIRECT3DDEVICE8 iface, D3DMATERIAL8* pMaterial) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    memcpy(pMaterial, &This->UpdateStateBlock->material, sizeof (D3DMATERIAL8));
-    TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", This, pMaterial->Diffuse.r, pMaterial->Diffuse.g, pMaterial->Diffuse.b, pMaterial->Diffuse.a);
-    TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", This, pMaterial->Ambient.r, pMaterial->Ambient.g, pMaterial->Ambient.b, pMaterial->Ambient.a);
-    TRACE("(%p) : Specular (%f,%f,%f,%f)\n", This, pMaterial->Specular.r, pMaterial->Specular.g, pMaterial->Specular.b, pMaterial->Specular.a);
-    TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", This, pMaterial->Emissive.r, pMaterial->Emissive.g, pMaterial->Emissive.b, pMaterial->Emissive.a);
-    TRACE("(%p) : Power (%f)\n", This, pMaterial->Power);
-    return D3D_OK;
+    return hr;
 }
 
-/* Note lights are real special cases. Although the device caps state only eg. 8 are supported,
-   you can reference any indexes you want as long as that number max are enabled are any
-   one point in time! Therefore since the indexes can be anything, we need a linked list of them.
-   However, this causes stateblock problems. When capturing the state block, I duplicate the list,
-   but when recording, just build a chain pretty much of commands to be replayed.                  */
-   
-HRESULT  WINAPI  IDirect3DDevice8Impl_SetLight(LPDIRECT3DDEVICE8 iface, DWORD Index, CONST D3DLIGHT8* pLight) {
-    float rho;
-    PLIGHTINFOEL *object, *temp;
-
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    TRACE("(%p) : Idx(%ld), pLight(%p)\n", This, Index, pLight);
-
-    /* If recording state block, just add to end of lights chain */
-    if (This->isRecordingState) {
-        object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PLIGHTINFOEL));
-        if (NULL == object) {
-            return D3DERR_OUTOFVIDEOMEMORY;
-        }
-        memcpy(&object->OriginalParms, pLight, sizeof(D3DLIGHT8));
-        object->OriginalIndex = Index;
-        object->glIndex = -1;
-        object->changed = TRUE;
-
-        /* Add to the END of the chain of lights changes to be replayed */
-        if (This->UpdateStateBlock->lights == NULL) {
-            This->UpdateStateBlock->lights = object;
-        } else {
-            temp = This->UpdateStateBlock->lights;
-            while (temp->next != NULL) temp=temp->next;
-            temp->next = object;
-        }
-        TRACE("Recording... not performing anything more\n");
-        return D3D_OK;
-    }
-
-    /* Ok, not recording any longer so do real work */
-    object = This->StateBlock->lights;
-    while (object != NULL && object->OriginalIndex != Index) object = object->next;
-
-    /* If we didnt find it in the list of lights, time to add it */
-    if (object == NULL) {
-        PLIGHTINFOEL *insertAt,*prevPos;
-
-        object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PLIGHTINFOEL));
-        if (NULL == object) {
-            return D3DERR_OUTOFVIDEOMEMORY;
-        }
-        object->OriginalIndex = Index;
-        object->glIndex = -1;
-
-        /* Add it to the front of list with the idea that lights will be changed as needed 
-           BUT after any lights currently assigned GL indexes                             */
-        insertAt = This->StateBlock->lights;
-        prevPos  = NULL;
-        while (insertAt != NULL && insertAt->glIndex != -1) {
-            prevPos  = insertAt;
-            insertAt = insertAt->next;
-        }
-
-        if (insertAt == NULL && prevPos == NULL) { /* Start of list */
-            This->StateBlock->lights = object;
-        } else if (insertAt == NULL) { /* End of list */
-            prevPos->next = object;
-            object->prev = prevPos;
-        } else { /* Middle of chain */
-            if (prevPos == NULL) {
-                This->StateBlock->lights = object;
-            } else {
-                prevPos->next = object;
-            }
-            object->prev = prevPos;
-            object->next = insertAt;
-            insertAt->prev = object;
-        }
-    }
-
-    /* Initialze the object */
-    TRACE("Light %ld setting to type %d, Diffuse(%f,%f,%f,%f), Specular(%f,%f,%f,%f), Ambient(%f,%f,%f,%f)\n", Index, pLight->Type,
-          pLight->Diffuse.r, pLight->Diffuse.g, pLight->Diffuse.b, pLight->Diffuse.a,
-          pLight->Specular.r, pLight->Specular.g, pLight->Specular.b, pLight->Specular.a,
-          pLight->Ambient.r, pLight->Ambient.g, pLight->Ambient.b, pLight->Ambient.a);
-    TRACE("... Pos(%f,%f,%f), Dirn(%f,%f,%f)\n", pLight->Position.x, pLight->Position.y, pLight->Position.z,
-          pLight->Direction.x, pLight->Direction.y, pLight->Direction.z);
-    TRACE("... Range(%f), Falloff(%f), Theta(%f), Phi(%f)\n", pLight->Range, pLight->Falloff, pLight->Theta, pLight->Phi);
-
-    /* Save away the information */
-    memcpy(&object->OriginalParms, pLight, sizeof(D3DLIGHT8));
-
-    switch (pLight->Type) {
-    case D3DLIGHT_POINT:
-        /* Position */
-        object->lightPosn[0] = pLight->Position.x;
-        object->lightPosn[1] = pLight->Position.y;
-        object->lightPosn[2] = pLight->Position.z;
-        object->lightPosn[3] = 1.0f;
-        object->cutoff = 180.0f;
-        /* FIXME: Range */
-        break;
-
-    case D3DLIGHT_SPOT:
-        /* Position */
-        object->lightPosn[0] = pLight->Position.x;
-        object->lightPosn[1] = pLight->Position.y;
-        object->lightPosn[2] = pLight->Position.z;
-        object->lightPosn[3] = 1.0;
-
-        /* Direction */
-        object->lightDirn[0] = pLight->Direction.x;
-        object->lightDirn[1] = pLight->Direction.y;
-        object->lightDirn[2] = pLight->Direction.z;
-        object->lightDirn[3] = 1.0;
-
-        /*
-         * opengl-ish and d3d-ish spot lights use too different models for the
-         * light "intensity" as a function of the angle towards the main light direction,
-         * so we only can approximate very roughly.
-         * however spot lights are rather rarely used in games (if ever used at all).
-         * furthermore if still used, probably nobody pays attention to such details.
-         */
-        if (pLight->Falloff == 0) {
-            rho = 6.28f;
-        } else {
-            rho = pLight->Theta + (pLight->Phi - pLight->Theta)/(2*pLight->Falloff);
-        }
-        if (rho < 0.0001) rho = 0.0001f;
-        object->exponent = -0.3/log(cos(rho/2));
-        object->cutoff = pLight->Phi*90/M_PI;
-
-        /* FIXME: Range */
-        break;
+static HRESULT  WINAPI  IDirect3DDevice8Impl_GetDepthStencilSurface(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8** ppZStencilSurface) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    HRESULT hr = D3D_OK;
+    IWineD3DSurface *pZStencilSurface;
 
-    case D3DLIGHT_DIRECTIONAL:
-        /* Direction */
-        object->lightPosn[0] = -pLight->Direction.x;
-        object->lightPosn[1] = -pLight->Direction.y;
-        object->lightPosn[2] = -pLight->Direction.z;
-        object->lightPosn[3] = 0.0;
-        object->exponent     = 0.0f;
-        object->cutoff       = 180.0f;
-        break;
-
-    default:
-        FIXME("Unrecognized light type %d\n", pLight->Type);
-    }
-
-    /* Update the live definitions if the light is currently assigned a glIndex */
-    if (object->glIndex != -1) {
-        setup_light(iface, object->glIndex, object);
-    }
-    return D3D_OK;
-}
-HRESULT  WINAPI  IDirect3DDevice8Impl_GetLight(LPDIRECT3DDEVICE8 iface, DWORD Index,D3DLIGHT8* pLight) {
-    PLIGHTINFOEL *lightInfo = NULL;
-    ICOM_THIS(IDirect3DDevice8Impl,iface); 
-    TRACE("(%p) : Idx(%ld), pLight(%p)\n", This, Index, pLight);
-    
-    /* Locate the light in the live lights */
-    lightInfo = This->StateBlock->lights;
-    while (lightInfo != NULL && lightInfo->OriginalIndex != Index) lightInfo = lightInfo->next;
-
-    if (lightInfo == NULL) {
-        TRACE("Light information requested but light not defined\n");
+    TRACE("(%p) Relay\n" , This);
+    if(ppZStencilSurface == NULL){
         return D3DERR_INVALIDCALL;
     }
 
-    memcpy(pLight, &lightInfo->OriginalParms, sizeof(D3DLIGHT8));
-    return D3D_OK;
-}
-HRESULT  WINAPI  IDirect3DDevice8Impl_LightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL Enable) {
-    PLIGHTINFOEL *lightInfo = NULL;
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    TRACE("(%p) : Idx(%ld), enable? %d\n", This, Index, Enable);
-
-    /* If recording state block, just add to end of lights chain with changedEnable set to true */
-    if (This->isRecordingState) {
-        lightInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PLIGHTINFOEL));
-        if (NULL == lightInfo) {
-            return D3DERR_OUTOFVIDEOMEMORY;
-        }
-        lightInfo->OriginalIndex = Index;
-        lightInfo->glIndex = -1;
-        lightInfo->enabledChanged = TRUE;
-
-        /* Add to the END of the chain of lights changes to be replayed */
-        if (This->UpdateStateBlock->lights == NULL) {
-            This->UpdateStateBlock->lights = lightInfo;
-        } else {
-            PLIGHTINFOEL *temp = This->UpdateStateBlock->lights;
-            while (temp->next != NULL) temp=temp->next;
-            temp->next = lightInfo;
-        }
-        TRACE("Recording... not performing anything more\n");
-        return D3D_OK;
-    }
-
-    /* Not recording... So, locate the light in the live lights */
-    lightInfo = This->StateBlock->lights;
-    while (lightInfo != NULL && lightInfo->OriginalIndex != Index) lightInfo = lightInfo->next;
-
-    /* Special case - enabling an undefined light creates one with a strict set of parms! */
-    if (lightInfo == NULL) {
-        D3DLIGHT8 lightParms;
-        /* Warning - untested code :-) Prob safe to change fixme to a trace but
-             wait until someone confirms it seems to work!                     */
-        TRACE("Light enabled requested but light not defined, so defining one!\n"); 
-        lightParms.Type = D3DLIGHT_DIRECTIONAL;
-        lightParms.Diffuse.r = 1.0;
-        lightParms.Diffuse.g = 1.0;
-        lightParms.Diffuse.b = 1.0;
-        lightParms.Diffuse.a = 0.0;
-        lightParms.Specular.r = 0.0;
-        lightParms.Specular.g = 0.0;
-        lightParms.Specular.b = 0.0;
-        lightParms.Specular.a = 0.0;
-        lightParms.Ambient.r = 0.0;
-        lightParms.Ambient.g = 0.0;
-        lightParms.Ambient.b = 0.0;
-        lightParms.Ambient.a = 0.0;
-        lightParms.Position.x = 0.0;
-        lightParms.Position.y = 0.0;
-        lightParms.Position.z = 0.0;
-        lightParms.Direction.x = 0.0;
-        lightParms.Direction.y = 0.0;
-        lightParms.Direction.z = 1.0;
-        lightParms.Range = 0.0;
-        lightParms.Falloff = 0.0;
-        lightParms.Attenuation0 = 0.0;
-        lightParms.Attenuation1 = 0.0;
-        lightParms.Attenuation2 = 0.0;
-        lightParms.Theta = 0.0;
-        lightParms.Phi = 0.0;
-        IDirect3DDevice8Impl_SetLight(iface, Index, &lightParms);
-
-        /* Search for it again! Should be fairly quick as near head of list */
-        lightInfo = This->StateBlock->lights;
-        while (lightInfo != NULL && lightInfo->OriginalIndex != Index) lightInfo = lightInfo->next;
-        if (lightInfo == NULL) {
-            FIXME("Adding default lights has failed dismally\n");
-            return D3DERR_INVALIDCALL;
-        }
+    hr=IWineD3DDevice_GetDepthStencilSurface(This->WineD3DDevice,&pZStencilSurface);
+    if(hr == D3D_OK && pZStencilSurface != NULL){
+        IWineD3DResource_GetParent((IWineD3DResource *)pZStencilSurface,(IUnknown**)ppZStencilSurface);
+        IWineD3DResource_Release((IWineD3DResource *)pZStencilSurface);
+    }else{
+        FIXME("Call to IWineD3DDevice_GetRenderTarget failed\n");
+        *ppZStencilSurface = NULL;
     }
 
-    /* OK, we now have a light... */
-    if (Enable == FALSE) {
-
-        /* If we are disabling it, check it was enabled, and
-           still only do something if it has assigned a glIndex (which it should have!)   */
-        if ((lightInfo->lightEnabled == TRUE) && (lightInfo->glIndex != -1)) {
-            TRACE("Disabling light set up at gl idx %ld\n", lightInfo->glIndex);
-            ENTER_GL();
-            glDisable(GL_LIGHT0 + lightInfo->glIndex);
-            checkGLcall("glDisable GL_LIGHT0+Index");
-            LEAVE_GL();
-        } else {
-            TRACE("Nothing to do as light was not enabled\n");
-        }
-        lightInfo->lightEnabled = FALSE;
-    } else {
-
-        /* We are enabling it. If it is enabled, its really simple */
-        if (lightInfo->lightEnabled == TRUE) {
-            /* nop */
-            TRACE("Nothing to do as light was enabled\n");
-
-        /* If it already has a glIndex, its still simple */
-        } else if (lightInfo->glIndex != -1) {
-            TRACE("Reusing light as already set up at gl idx %ld\n", lightInfo->glIndex);
-            lightInfo->lightEnabled = TRUE;
-            ENTER_GL();
-            glEnable(GL_LIGHT0 + lightInfo->glIndex);
-            checkGLcall("glEnable GL_LIGHT0+Index already setup");
-            LEAVE_GL();
-
-        /* Otherwise got to find space - lights are ordered gl indexes first */
-        } else {
-            PLIGHTINFOEL *bsf  = NULL;
-            PLIGHTINFOEL *pos  = This->StateBlock->lights;
-            PLIGHTINFOEL *prev = NULL;
-            int           Index= 0;
-            int           glIndex = -1;
-
-            /* Try to minimize changes as much as possible */
-            while (pos != NULL && pos->glIndex != -1 && Index < This->maxConcurrentLights) {
-
-                /* Try to remember which index can be replaced if necessary */
-                if (bsf==NULL && pos->lightEnabled == FALSE) {
-                    /* Found a light we can replace, save as best replacement */
-                    bsf = pos;
-                }
-
-                /* Step to next space */
-                prev = pos;
-                pos = pos->next;
-                Index ++;
-            }
-
-            /* If we have too many active lights, fail the call */
-            if ((Index == This->maxConcurrentLights) && (bsf == NULL)) {
-                FIXME("Program requests too many concurrent lights\n");
-                return D3DERR_INVALIDCALL;
-
-            /* If we have allocated all lights, but not all are enabled,
-               reuse one which is not enabled                           */
-            } else if (Index == This->maxConcurrentLights) {
-                /* use bsf - Simply swap the new light and the BSF one */
-                PLIGHTINFOEL *bsfNext = bsf->next;
-                PLIGHTINFOEL *bsfPrev = bsf->prev;
-
-                /* Sort out ends */
-                if (lightInfo->next != NULL) lightInfo->next->prev = bsf;
-                if (bsf->prev != NULL) {
-                    bsf->prev->next = lightInfo;
-                } else {
-                    This->StateBlock->lights = lightInfo;
-                }
-
-                /* If not side by side, lots of chains to update */
-                if (bsf->next != lightInfo) {
-                    lightInfo->prev->next = bsf;
-                    bsf->next->prev = lightInfo;
-                    bsf->next       = lightInfo->next;
-                    bsf->prev       = lightInfo->prev;
-                    lightInfo->next = bsfNext;
-                    lightInfo->prev = bsfPrev;
-
-                } else {
-                    /* Simple swaps */
-                    bsf->prev = lightInfo;
-                    bsf->next = lightInfo->next;
-                    lightInfo->next = bsf;
-                    lightInfo->prev = bsfPrev;
-                }
-
-
-                /* Update states */
-                glIndex = bsf->glIndex;
-                bsf->glIndex = -1;
-                lightInfo->glIndex = glIndex;
-                lightInfo->lightEnabled = TRUE;
-
-                /* Finally set up the light in gl itself */
-                TRACE("Replacing light which was set up at gl idx %ld\n", lightInfo->glIndex);
-                ENTER_GL();
-                setup_light(iface, glIndex, lightInfo);
-                glEnable(GL_LIGHT0 + glIndex);
-                checkGLcall("glEnable GL_LIGHT0 new setup");
-                LEAVE_GL();
-
-            /* If we reached the end of the allocated lights, with space in the
-               gl lights, setup a new light                                     */
-            } else if (pos->glIndex == -1) {
-
-                /* We reached the end of the allocated gl lights, so already 
-                    know the index of the next one!                          */
-                glIndex = Index;
-                lightInfo->glIndex = glIndex;
-                lightInfo->lightEnabled = TRUE;
-
-                /* In an ideal world, its already in the right place */
-                if (lightInfo->prev == NULL || lightInfo->prev->glIndex!=-1) {
-                   /* No need to move it */
-                } else {
-                    /* Remove this light from the list */
-                    lightInfo->prev->next = lightInfo->next;
-                    if (lightInfo->next != NULL) {
-                        lightInfo->next->prev = lightInfo->prev;
-                    }
-
-                    /* Add in at appropriate place (inbetween prev and pos) */
-                    lightInfo->prev = prev;
-                    lightInfo->next = pos;
-                    if (prev == NULL) {
-                        This->StateBlock->lights = lightInfo;
-                    } else {
-                        prev->next = lightInfo;
-                    }
-                    if (pos != NULL) {
-                        pos->prev = lightInfo;
-                    }
-                }
-
-                /* Finally set up the light in gl itself */
-                TRACE("Defining new light at gl idx %ld\n", lightInfo->glIndex);
-                ENTER_GL();
-                setup_light(iface, glIndex, lightInfo);
-                glEnable(GL_LIGHT0 + glIndex);
-                checkGLcall("glEnable GL_LIGHT0 new setup");
-                LEAVE_GL();
-                
-            }
-        }
-    }
-    return D3D_OK;
-}
-HRESULT  WINAPI  IDirect3DDevice8Impl_GetLightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL* pEnable) {
-
-    PLIGHTINFOEL *lightInfo = NULL;
-    ICOM_THIS(IDirect3DDevice8Impl,iface); 
-    TRACE("(%p) : for idx(%ld)\n", This, Index);
-    
-    /* Locate the light in the live lights */
-    lightInfo = This->StateBlock->lights;
-    while (lightInfo != NULL && lightInfo->OriginalIndex != Index) lightInfo = lightInfo->next;
-
-    if (lightInfo == NULL) {
-        TRACE("Light enabled state requested but light not defined\n");
-        return D3DERR_INVALIDCALL;
-    }
-    *pEnable = lightInfo->lightEnabled;
     return D3D_OK;
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_SetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,CONST float* pPlane) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    TRACE("(%p) : for idx %ld, %p\n", This, Index, pPlane);
 
-    /* Validate Index */
-    if (Index >= GL_LIMITS(clipplanes)) {
-        TRACE("Application has requested clipplane this device doesnt support\n");
-        return D3DERR_INVALIDCALL;
-    }
-
-    This->UpdateStateBlock->Changed.clipplane[Index] = TRUE;
-    This->UpdateStateBlock->Set.clipplane[Index] = TRUE;
-    This->UpdateStateBlock->clipplane[Index][0] = pPlane[0];
-    This->UpdateStateBlock->clipplane[Index][1] = pPlane[1];
-    This->UpdateStateBlock->clipplane[Index][2] = pPlane[2];
-    This->UpdateStateBlock->clipplane[Index][3] = pPlane[3];
-
-    /* Handle recording of state blocks */
-    if (This->isRecordingState) {
-        TRACE("Recording... not performing anything\n");
-        return D3D_OK;
-    }
-
-    /* Apply it */
-
-    ENTER_GL();
-
-    /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
-    glMatrixMode(GL_MODELVIEW);
-    glPushMatrix();
-    glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
-
-    TRACE("Clipplane [%f,%f,%f,%f]\n", 
-         This->UpdateStateBlock->clipplane[Index][0], 
-         This->UpdateStateBlock->clipplane[Index][1],
-          This->UpdateStateBlock->clipplane[Index][2], 
-         This->UpdateStateBlock->clipplane[Index][3]);
-    glClipPlane(GL_CLIP_PLANE0 + Index, This->UpdateStateBlock->clipplane[Index]);
-    checkGLcall("glClipPlane");
-
-    glPopMatrix();
-
-    LEAVE_GL();
-
-    return D3D_OK;
+static HRESULT WINAPI IDirect3DDevice8Impl_BeginScene(LPDIRECT3DDEVICE8 iface) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    return IWineD3DDevice_BeginScene(This->WineD3DDevice);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_GetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,float* pPlane) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    TRACE("(%p) : for idx %ld\n", This, Index);
 
-    /* Validate Index */
-    if (Index >= GL_LIMITS(clipplanes)) {
-        TRACE("Application has requested clipplane this device doesnt support\n");
-        return D3DERR_INVALIDCALL;
-    }
+static HRESULT WINAPI IDirect3DDevice8Impl_EndScene(LPDIRECT3DDEVICE8 iface) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n" , This);
 
-    pPlane[0] = This->StateBlock->clipplane[Index][0];
-    pPlane[1] = This->StateBlock->clipplane[Index][1];
-    pPlane[2] = This->StateBlock->clipplane[Index][2];
-    pPlane[3] = This->StateBlock->clipplane[Index][3];
-    return D3D_OK;
+    return IWineD3DDevice_EndScene(This->WineD3DDevice);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD Value) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    DWORD OldValue = This->StateBlock->renderstate[State];
-        
-    TRACE("(%p)->state = %s(%d), value = %ld\n", This, debug_d3drenderstate(State), State, Value);
-    This->UpdateStateBlock->Changed.renderstate[State] = TRUE;
-    This->UpdateStateBlock->Set.renderstate[State] = TRUE;
-    This->UpdateStateBlock->renderstate[State] = Value;
-
-    /* Handle recording of state blocks */
-    if (This->isRecordingState) {
-        TRACE("Recording... not performing anything\n");
-        return D3D_OK;
-    }
-
-    ENTER_GL();
-
-    switch (State) {
-    case D3DRS_FILLMODE                  :
-        switch ((D3DFILLMODE) Value) {
-        case D3DFILL_POINT               : glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); break;
-        case D3DFILL_WIREFRAME           : glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); break;
-        case D3DFILL_SOLID               : glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); break;
-        default:
-            FIXME("Unrecognized D3DRS_FILLMODE value %ld\n", Value);
-        }
-        checkGLcall("glPolygonMode (fillmode)");
-        break;
-
-    case D3DRS_LIGHTING                  :
-        if (Value) {
-            glEnable(GL_LIGHTING);
-            checkGLcall("glEnable GL_LIGHTING");
-        } else {
-            glDisable(GL_LIGHTING);
-            checkGLcall("glDisable GL_LIGHTING");
-        }
-        break;
-
-    case D3DRS_ZENABLE                   :
-        switch ((D3DZBUFFERTYPE) Value) {
-        case D3DZB_FALSE:
-            glDisable(GL_DEPTH_TEST);
-            checkGLcall("glDisable GL_DEPTH_TEST");
-            break;
-        case D3DZB_TRUE:
-            glEnable(GL_DEPTH_TEST);
-            checkGLcall("glEnable GL_DEPTH_TEST");
-            break;
-
-        case D3DZB_USEW:
-        default:
-            FIXME("Unrecognized/Unhandled D3DZBUFFERTYPE value %ld\n", Value);
-        }
-        break;
-
-    case D3DRS_CULLMODE                  :
-
-        /* If we are culling "back faces with clockwise vertices" then
-           set front faces to be counter clockwise and enable culling  
-           of back faces                                               */
-        switch ((D3DCULL) Value) {
-        case D3DCULL_NONE:
-            glDisable(GL_CULL_FACE);
-            checkGLcall("glDisable GL_CULL_FACE");
-            break;
-        case D3DCULL_CW:
-            glEnable(GL_CULL_FACE);
-            checkGLcall("glEnable GL_CULL_FACE");
-            glFrontFace(GL_CCW);
-            checkGLcall("glFrontFace GL_CCW");
-            glCullFace(GL_BACK);
-            break;
-        case D3DCULL_CCW:
-            glEnable(GL_CULL_FACE);
-            checkGLcall("glEnable GL_CULL_FACE");
-            glFrontFace(GL_CW); 
-            checkGLcall("glFrontFace GL_CW");
-            glCullFace(GL_BACK);
-            break;
-        default:
-            FIXME("Unrecognized/Unhandled D3DCULL value %ld\n", Value);
-        }
-        break;
-
-    case D3DRS_SHADEMODE                 :
-        switch ((D3DSHADEMODE) Value) {
-        case D3DSHADE_FLAT:
-            glShadeModel(GL_FLAT);
-            checkGLcall("glShadeModel");
-            break;
-        case D3DSHADE_GOURAUD:
-            glShadeModel(GL_SMOOTH);
-            checkGLcall("glShadeModel");
-            break;
-        case D3DSHADE_PHONG:
-            FIXME("D3DSHADE_PHONG isnt supported?\n");
-
-           LEAVE_GL();
-            return D3DERR_INVALIDCALL;
-        default:
-            FIXME("Unrecognized/Unhandled D3DSHADEMODE value %ld\n", Value);
-        }
-        break;
-
-    case D3DRS_DITHERENABLE              :
-        if (Value) {
-            glEnable(GL_DITHER);
-            checkGLcall("glEnable GL_DITHER");
-        } else {
-            glDisable(GL_DITHER);
-            checkGLcall("glDisable GL_DITHER");
-        }
-        break;
-
-    case D3DRS_ZWRITEENABLE              :
-        if (Value) {
-            glDepthMask(1);
-            checkGLcall("glDepthMask");
-        } else {
-            glDepthMask(0);
-            checkGLcall("glDepthMask");
-        }
-        break;
-
-    case D3DRS_ZFUNC                     :
-        {
-            int glParm = GL_LESS;
-
-            switch ((D3DCMPFUNC) Value) {
-            case D3DCMP_NEVER:         glParm=GL_NEVER; break;
-            case D3DCMP_LESS:          glParm=GL_LESS; break;
-            case D3DCMP_EQUAL:         glParm=GL_EQUAL; break;
-            case D3DCMP_LESSEQUAL:     glParm=GL_LEQUAL; break;
-            case D3DCMP_GREATER:       glParm=GL_GREATER; break;
-            case D3DCMP_NOTEQUAL:      glParm=GL_NOTEQUAL; break;
-            case D3DCMP_GREATEREQUAL:  glParm=GL_GEQUAL; break;
-            case D3DCMP_ALWAYS:        glParm=GL_ALWAYS; break;
-            default:
-                FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
-            }
-            glDepthFunc(glParm);
-            checkGLcall("glDepthFunc");
-        }
-        break;
-
-    case D3DRS_AMBIENT                   :
-        {
-            float col[4];
-           D3DCOLORTOGLFLOAT4(Value, col);
-            TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0], col[1], col[2], col[3]);
-            glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
-            checkGLcall("glLightModel for MODEL_AMBIENT");
-
-        }
-        break;
-
-    case D3DRS_ALPHABLENDENABLE          :
-        if (Value) {
-            glEnable(GL_BLEND);
-            checkGLcall("glEnable GL_BLEND");
-        } else {
-            glDisable(GL_BLEND);
-            checkGLcall("glDisable GL_BLEND");
-        };
-        break;
-
-    case D3DRS_SRCBLEND                  :
-    case D3DRS_DESTBLEND                 :
-        {
-            int newVal = GL_ZERO;
-            switch (Value) {
-            case D3DBLEND_ZERO               : newVal = GL_ZERO;  break;
-            case D3DBLEND_ONE                : newVal = GL_ONE;  break;
-            case D3DBLEND_SRCCOLOR           : newVal = GL_SRC_COLOR;  break;
-            case D3DBLEND_INVSRCCOLOR        : newVal = GL_ONE_MINUS_SRC_COLOR;  break;
-            case D3DBLEND_SRCALPHA           : newVal = GL_SRC_ALPHA;  break;
-            case D3DBLEND_INVSRCALPHA        : newVal = GL_ONE_MINUS_SRC_ALPHA;  break;
-            case D3DBLEND_DESTALPHA          : newVal = GL_DST_ALPHA;  break;
-            case D3DBLEND_INVDESTALPHA       : newVal = GL_ONE_MINUS_DST_ALPHA;  break;
-            case D3DBLEND_DESTCOLOR          : newVal = GL_DST_COLOR;  break;
-            case D3DBLEND_INVDESTCOLOR       : newVal = GL_ONE_MINUS_DST_COLOR;  break;
-            case D3DBLEND_SRCALPHASAT        : newVal = GL_SRC_ALPHA_SATURATE;  break;
-
-            case D3DBLEND_BOTHSRCALPHA       : newVal = GL_SRC_ALPHA;
-                This->srcBlend = newVal;
-                This->dstBlend = newVal;
-                break;
-
-            case D3DBLEND_BOTHINVSRCALPHA    : newVal = GL_ONE_MINUS_SRC_ALPHA;
-                This->srcBlend = newVal;
-                This->dstBlend = newVal;
-                break;
-            default:
-                FIXME("Unrecognized src/dest blend value %ld (%d)\n", Value, State);
-            }
-
-            if (State == D3DRS_SRCBLEND) This->srcBlend = newVal;
-            if (State == D3DRS_DESTBLEND) This->dstBlend = newVal;
-            TRACE("glBlendFunc src=%x, dst=%x\n", This->srcBlend, This->dstBlend);
-            glBlendFunc(This->srcBlend, This->dstBlend);
-
-            checkGLcall("glBlendFunc");
-        }
-        break;
-
-    case D3DRS_ALPHATESTENABLE           :
-        if (Value) {
-            glEnable(GL_ALPHA_TEST);
-            checkGLcall("glEnable GL_ALPHA_TEST");
-        } else {
-            glDisable(GL_ALPHA_TEST);
-            checkGLcall("glDisable GL_ALPHA_TEST");
-        }
-        break;
-
-    case D3DRS_ALPHAFUNC                 :
-        {
-            int glParm = GL_LESS;
-            float ref = ((float) This->StateBlock->renderstate[D3DRS_ALPHAREF]) / 255.0f;
-
-            switch ((D3DCMPFUNC) Value) {
-            case D3DCMP_NEVER:         glParm = GL_NEVER; break;
-            case D3DCMP_LESS:          glParm = GL_LESS; break;
-            case D3DCMP_EQUAL:         glParm = GL_EQUAL; break;
-            case D3DCMP_LESSEQUAL:     glParm = GL_LEQUAL; break;
-            case D3DCMP_GREATER:       glParm = GL_GREATER; break;
-            case D3DCMP_NOTEQUAL:      glParm = GL_NOTEQUAL; break;
-            case D3DCMP_GREATEREQUAL:  glParm = GL_GEQUAL; break;
-            case D3DCMP_ALWAYS:        glParm = GL_ALWAYS; break;
-            default:
-                FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
-            }
-            TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm, ref);
-            glAlphaFunc(glParm, ref);
-            This->alphafunc = glParm;
-            checkGLcall("glAlphaFunc");
-        }
-        break;
-
-    case D3DRS_ALPHAREF                  :
-        {
-            int glParm = This->alphafunc;
-            float ref = 1.0f;
-
-            ref = ((float) Value) / 255.0f;
-            TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm, ref);
-            glAlphaFunc(glParm, ref);
-            checkGLcall("glAlphaFunc");
-        }
-        break;
-
-    case D3DRS_CLIPPLANEENABLE           :
-    case D3DRS_CLIPPING                  :
-        {
-            /* Ensure we only do the changed clip planes */
-            DWORD enable  = 0xFFFFFFFF;
-            DWORD disable = 0x00000000;
-            
-            /* If enabling / disabling all */
-            if (State == D3DRS_CLIPPING) {
-                if (Value) {
-                    enable  = This->StateBlock->renderstate[D3DRS_CLIPPLANEENABLE];
-                    disable = 0x00;
-                } else {
-                    disable = This->StateBlock->renderstate[D3DRS_CLIPPLANEENABLE];
-                    enable  = 0x00;
-                }
-            } else {
-                enable =   Value & ~OldValue;
-                disable = ~Value &  OldValue;
-            }
-            
-            if (enable & D3DCLIPPLANE0)  { glEnable(GL_CLIP_PLANE0);  checkGLcall("glEnable(clip plane 0)"); }
-            if (enable & D3DCLIPPLANE1)  { glEnable(GL_CLIP_PLANE1);  checkGLcall("glEnable(clip plane 1)"); }
-            if (enable & D3DCLIPPLANE2)  { glEnable(GL_CLIP_PLANE2);  checkGLcall("glEnable(clip plane 2)"); }
-            if (enable & D3DCLIPPLANE3)  { glEnable(GL_CLIP_PLANE3);  checkGLcall("glEnable(clip plane 3)"); }
-            if (enable & D3DCLIPPLANE4)  { glEnable(GL_CLIP_PLANE4);  checkGLcall("glEnable(clip plane 4)"); }
-            if (enable & D3DCLIPPLANE5)  { glEnable(GL_CLIP_PLANE5);  checkGLcall("glEnable(clip plane 5)"); }
-            
-            if (disable & D3DCLIPPLANE0) { glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); }
-            if (disable & D3DCLIPPLANE1) { glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); }
-            if (disable & D3DCLIPPLANE2) { glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); }
-            if (disable & D3DCLIPPLANE3) { glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); }
-            if (disable & D3DCLIPPLANE4) { glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); }
-            if (disable & D3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); }
-        }
-        break;
-
-    case D3DRS_BLENDOP                   :
-        {
-            int glParm = GL_FUNC_ADD;
-
-            switch ((D3DBLENDOP) Value) {
-            case D3DBLENDOP_ADD              : glParm = GL_FUNC_ADD;              break;
-            case D3DBLENDOP_SUBTRACT         : glParm = GL_FUNC_SUBTRACT;         break;
-            case D3DBLENDOP_REVSUBTRACT      : glParm = GL_FUNC_REVERSE_SUBTRACT; break;
-            case D3DBLENDOP_MIN              : glParm = GL_MIN;                   break;
-            case D3DBLENDOP_MAX              : glParm = GL_MAX;                   break;
-            default:
-                FIXME("Unrecognized/Unhandled D3DBLENDOP value %ld\n", Value);
-            }
-            TRACE("glBlendEquation(%x)\n", glParm);
-            glBlendEquation(glParm);
-            checkGLcall("glBlendEquation");
-        }
-        break;
-
-    case D3DRS_TEXTUREFACTOR             :
-        {
-            int i;
-
-            /* Note the texture color applies to all textures whereas 
-               GL_TEXTURE_ENV_COLOR applies to active only */
-            float col[4];
-           D3DCOLORTOGLFLOAT4(Value, col);
-            /* Set the default alpha blend color */
-            glBlendColor(col[0], col[1], col[2], col[3]);
-            checkGLcall("glBlendColor");
-
-            /* And now the default texture color as well */
-            for (i = 0; i < GL_LIMITS(textures); i++) {
-
-                /* Note the D3DRS value applies to all textures, but GL has one
-                   per texture, so apply it now ready to be used!               */
-                if (GL_SUPPORT(ARB_MULTITEXTURE)) {
-#if defined(GL_VERSION_1_3)
-                    glActiveTexture(GL_TEXTURE0 + i);
-#else
-                    glActiveTextureARB(GL_TEXTURE0_ARB + i);
-#endif
-                    checkGLcall("Activate texture.. to update const color");
-                } else if (i>0) {
-                    FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
-                }
-
-                glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
-                checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
-            }
-        }
-        break;
-
-    case D3DRS_SPECULARENABLE            : 
-        {
-            /* Originally this used glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
-               and (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR) to swap between enabled/disabled
-               specular color. This is wrong:
-               Separate specular color means the specular colour is maintained separately, whereas
-               single color means it is merged in. However in both cases they are being used to
-               some extent.
-               To disable specular color, set it explicitly to black and turn off GL_COLOR_SUM_EXT
-               NOTE: If not supported dont give FIXME as very minimal impact and very few people are
-                  yet running 1.4!
-             */
-              if (Value) {
-                glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*) &This->UpdateStateBlock->material.Specular);
-                checkGLcall("glMaterialfv");
-               if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
-                 glEnable(GL_COLOR_SUM_EXT);
-               } else {
-                 TRACE("Specular colors cannot be enabled in this version of opengl\n");
-               }
-                checkGLcall("glEnable(GL_COLOR_SUM)");
-              } else {
-                float black[4] = {0.0f, 0.0f, 0.0f, 0.0f};
-
-                /* for the case of enabled lighting: */
-                glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
-                checkGLcall("glMaterialfv");
-
-                /* for the case of disabled lighting: */
-               if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
-                 glDisable(GL_COLOR_SUM_EXT);
-               } else {
-                 TRACE("Specular colors cannot be disabled in this version of opengl\n");
-               }
-                checkGLcall("glDisable(GL_COLOR_SUM)");
-             }
-        }
-        break;
-
-    case D3DRS_STENCILENABLE             :
-        if (Value) {
-            glEnable(GL_STENCIL_TEST);
-            checkGLcall("glEnable GL_STENCIL_TEST");
-        } else {
-            glDisable(GL_STENCIL_TEST);
-            checkGLcall("glDisable GL_STENCIL_TEST");
-        }
-        break;
-
-    case D3DRS_STENCILFUNC               :
-        {
-           int glParm = GL_ALWAYS;
-           int ref = This->StateBlock->renderstate[D3DRS_STENCILREF];
-           GLuint mask = This->StateBlock->renderstate[D3DRS_STENCILMASK];
-
-           switch ((D3DCMPFUNC) Value) {
-           case D3DCMP_NEVER:         glParm=GL_NEVER; break;
-           case D3DCMP_LESS:          glParm=GL_LESS; break;
-           case D3DCMP_EQUAL:         glParm=GL_EQUAL; break;
-           case D3DCMP_LESSEQUAL:     glParm=GL_LEQUAL; break;
-           case D3DCMP_GREATER:       glParm=GL_GREATER; break;
-           case D3DCMP_NOTEQUAL:      glParm=GL_NOTEQUAL; break;
-           case D3DCMP_GREATEREQUAL:  glParm=GL_GEQUAL; break;
-           case D3DCMP_ALWAYS:        glParm=GL_ALWAYS; break;
-           default:
-               FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
-           }
-           TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
-          This->stencilfunc = glParm;
-          glStencilFunc(glParm, ref, mask);
-           checkGLcall("glStencilFunc");
-        }
-        break;
-
-    case D3DRS_STENCILREF                :
-        {
-           int glParm = This->stencilfunc;
-           int ref = 0;
-           GLuint mask = This->StateBlock->renderstate[D3DRS_STENCILMASK];
-
-           ref = Value;
-           TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
-           glStencilFunc(glParm, ref, mask);
-           checkGLcall("glStencilFunc");
-        }
-        break;
-
-    case D3DRS_STENCILMASK               :
-        {
-           int glParm = This->stencilfunc;
-           int ref = This->StateBlock->renderstate[D3DRS_STENCILREF];
-           GLuint mask = Value;
-
-           TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
-           glStencilFunc(glParm, ref, mask);
-           checkGLcall("glStencilFunc");
-        }
-        break;
-
-    case D3DRS_STENCILFAIL               :
-        {
-            GLenum fail  ; 
-            GLenum zpass ; 
-            GLenum zfail ; 
-
-            fail = StencilOp(Value);
-            glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);
-            checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
-            glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);
-            checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
-
-            TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
-            glStencilOp(fail, zfail, zpass);
-            checkGLcall("glStencilOp(fail, zfail, zpass);");
-        }
-        break;
-    case D3DRS_STENCILZFAIL              :
-        {
-            GLenum fail  ; 
-            GLenum zpass ; 
-            GLenum zfail ; 
-
-            glGetIntegerv(GL_STENCIL_FAIL, &fail);
-            checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
-            glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);
-            checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
-            zfail = StencilOp(Value);
-
-            TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
-            glStencilOp(fail, zfail, zpass);
-            checkGLcall("glStencilOp(fail, zfail, zpass);");
-        }
-        break;
-    case D3DRS_STENCILPASS               :
-        {
-            GLenum fail  ; 
-            GLenum zpass ; 
-            GLenum zfail ; 
-
-            glGetIntegerv(GL_STENCIL_FAIL, &fail);
-            checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
-            zpass = StencilOp(Value);
-            glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);
-            checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
-
-            TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
-            glStencilOp(fail, zfail, zpass);
-            checkGLcall("glStencilOp(fail, zfail, zpass);");
-        }
-        break;
-
-    case D3DRS_STENCILWRITEMASK          :
-        {
-            glStencilMask(Value);
-            TRACE("glStencilMask(%lu)\n", Value);
-            checkGLcall("glStencilMask");
-        }
-        break;
-
-    case D3DRS_FOGENABLE                 :
-        {
-            if (Value && This->StateBlock->renderstate[D3DRS_FOGTABLEMODE] != D3DFOG_NONE) {
-               glEnable(GL_FOG);
-               checkGLcall("glEnable GL_FOG");
-            } else {
-               glDisable(GL_FOG);
-               checkGLcall("glDisable GL_FOG");
-            }
-        }
-        break;
-
-    case D3DRS_FOGCOLOR                  :
-        {
-            float col[4];
-           D3DCOLORTOGLFLOAT4(Value, col);
-            /* Set the default alpha blend color */
-            glFogfv(GL_FOG_COLOR, &col[0]);
-            checkGLcall("glFog GL_FOG_COLOR");
-        }
-        break;
-
-    case D3DRS_FOGTABLEMODE              :
-        {
-         switch (Value) {
-         case D3DFOG_NONE:    /* I don't know what to do here */ break;
-         case D3DFOG_EXP:     glFogi(GL_FOG_MODE, GL_EXP); checkGLcall("glFogi(GL_FOG_MODE, GL_EXP"); break; 
-         case D3DFOG_EXP2:    glFogi(GL_FOG_MODE, GL_EXP2); checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2"); break; 
-         case D3DFOG_LINEAR:  glFogi(GL_FOG_MODE, GL_LINEAR); checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR"); break; 
-         default:
-           FIXME("Unsupported Value(%lu) for D3DRS_FOGTABLEMODE!\n", Value);
-         }
-        }
-       break;
-
-    case D3DRS_FOGSTART                  :
-        {
-            float *f = (float*) &Value;
-            glFogfv(GL_FOG_START, f);
-            checkGLcall("glFogf(GL_FOG_START, (float) Value)");
-            TRACE("Fog Start == %f\n", *f);
-        }
-        break;
-
-    case D3DRS_FOGEND                    :
-        {
-            float *f = (float*) &Value;
-            glFogfv(GL_FOG_END, f);
-            checkGLcall("glFogf(GL_FOG_END, (float) Value)");
-            TRACE("Fog End == %f\n", *f);
-        }
-        break;
-
-    case D3DRS_FOGDENSITY                :
-        {
-            float *f = (float*) &Value;
-            glFogfv(GL_FOG_DENSITY, f);
-            checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
-        }
-        break;
-
-    case D3DRS_VERTEXBLEND               :
-        {
-         This->UpdateStateBlock->vertex_blend = (D3DVERTEXBLENDFLAGS) Value;
-         TRACE("Vertex Blending state to %ld\n",  Value);
-        }
-       break;
-
-    case D3DRS_TWEENFACTOR               :
-        {
-         This->UpdateStateBlock->tween_factor = *((float*) &Value);
-         TRACE("Vertex Blending Tween Factor to %f\n", This->UpdateStateBlock->tween_factor);
-        }
-       break;
-
-    case D3DRS_INDEXEDVERTEXBLENDENABLE  :
-        {
-         TRACE("Indexed Vertex Blend Enable to %ul\n", (BOOL) Value);
-        }
-       break;
-
-    case D3DRS_COLORVERTEX               :
-    case D3DRS_DIFFUSEMATERIALSOURCE     :
-    case D3DRS_SPECULARMATERIALSOURCE    :
-    case D3DRS_AMBIENTMATERIALSOURCE     :
-    case D3DRS_EMISSIVEMATERIALSOURCE    :
-        {
-            GLenum Parm = GL_AMBIENT_AND_DIFFUSE;
-
-            if (This->StateBlock->renderstate[D3DRS_COLORVERTEX]) {
-                TRACE("diff %ld, amb %ld, emis %ld, spec %ld\n",
-                      This->StateBlock->renderstate[D3DRS_DIFFUSEMATERIALSOURCE],
-                      This->StateBlock->renderstate[D3DRS_AMBIENTMATERIALSOURCE],
-                      This->StateBlock->renderstate[D3DRS_EMISSIVEMATERIALSOURCE],
-                      This->StateBlock->renderstate[D3DRS_SPECULARMATERIALSOURCE]);
-
-                if (This->StateBlock->renderstate[D3DRS_DIFFUSEMATERIALSOURCE] == D3DMCS_COLOR1) {
-                    if (This->StateBlock->renderstate[D3DRS_AMBIENTMATERIALSOURCE] == D3DMCS_COLOR1) {
-                        Parm = GL_AMBIENT_AND_DIFFUSE;
-                    } else {
-                        Parm = GL_DIFFUSE;
-                    }
-                } else if (This->StateBlock->renderstate[D3DRS_AMBIENTMATERIALSOURCE] == D3DMCS_COLOR1) {
-                    Parm = GL_AMBIENT;
-                } else if (This->StateBlock->renderstate[D3DRS_EMISSIVEMATERIALSOURCE] == D3DMCS_COLOR1) {
-                    Parm = GL_EMISSION;
-                } else if (This->StateBlock->renderstate[D3DRS_SPECULARMATERIALSOURCE] == D3DMCS_COLOR1) {
-                    Parm = GL_SPECULAR;
-                } else {
-                    Parm = -1;
-                }
-
-                if (Parm == -1) {
-                    if (This->tracking_color != DISABLED_TRACKING) This->tracking_color = NEEDS_DISABLE;
-                } else {
-                    This->tracking_color = NEEDS_TRACKING;
-                    This->tracking_parm  = Parm;
-                }
-
-            } else {
-                if (This->tracking_color != DISABLED_TRACKING) This->tracking_color = NEEDS_DISABLE;
-            }
-        }
-        break; 
-
-    case D3DRS_LINEPATTERN               :
-        {
-            D3DLINEPATTERN *pattern = (D3DLINEPATTERN *)&Value;
-            TRACE("Line pattern: repeat %d bits %x\n", pattern->wRepeatFactor, pattern->wLinePattern);
-
-            if (pattern->wRepeatFactor) {
-                glLineStipple(pattern->wRepeatFactor, pattern->wLinePattern);
-                checkGLcall("glLineStipple(repeat, linepattern)");
-                glEnable(GL_LINE_STIPPLE);
-                checkGLcall("glEnable(GL_LINE_STIPPLE);");
-            } else {
-                glDisable(GL_LINE_STIPPLE);
-                checkGLcall("glDisable(GL_LINE_STIPPLE);");
-            }
-        }
-        break;
-
-    case D3DRS_ZBIAS                     :
-        {
-            if (Value) {
-                TRACE("ZBias value %f\n", *((float*)&Value));
-                glPolygonOffset(0, -*((float*)&Value));
-                checkGLcall("glPolygonOffset(0, -Value)");
-                glEnable(GL_POLYGON_OFFSET_FILL);
-                checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL);");
-                glEnable(GL_POLYGON_OFFSET_LINE);
-                checkGLcall("glEnable(GL_POLYGON_OFFSET_LINE);");
-                glEnable(GL_POLYGON_OFFSET_POINT);
-                checkGLcall("glEnable(GL_POLYGON_OFFSET_POINT);");
-            } else {
-                glDisable(GL_POLYGON_OFFSET_FILL);
-                checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL);");
-                glDisable(GL_POLYGON_OFFSET_LINE);
-                checkGLcall("glDisable(GL_POLYGON_OFFSET_LINE);");
-                glDisable(GL_POLYGON_OFFSET_POINT);
-                checkGLcall("glDisable(GL_POLYGON_OFFSET_POINT);");
-            }
-        }
-        break;
-
-    case D3DRS_NORMALIZENORMALS          :
-        if (Value) {
-            glEnable(GL_NORMALIZE);
-            checkGLcall("glEnable(GL_NORMALIZE);");
-        } else {
-            glDisable(GL_NORMALIZE);
-            checkGLcall("glDisable(GL_NORMALIZE);");
-        }
-        break;
-
-    case D3DRS_POINTSIZE                 :
-        TRACE("Set point size to %f\n", *((float*)&Value));
-        glPointSize(*((float*)&Value));
-        checkGLcall("glPointSize(...);");
-        break;
-
-    case D3DRS_POINTSIZE_MIN             :
-        if (GL_SUPPORT(EXT_POINT_PARAMETERS)) {
-         GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MIN_EXT, *((float*)&Value));
-         checkGLcall("glPointParameterfEXT(...);");
-       } else {
-         FIXME("D3DRS_POINTSIZE_MIN not supported on this opengl\n");
-       }
-        break;
-
-    case D3DRS_POINTSIZE_MAX             :
-        if (GL_SUPPORT(EXT_POINT_PARAMETERS)) {
-         GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MAX_EXT, *((float*)&Value));
-         checkGLcall("glPointParameterfEXT(...);");
-       } else {
-         FIXME("D3DRS_POINTSIZE_MAX not supported on this opengl\n");
-       }
-        break;
 
-    case D3DRS_POINTSCALE_A              :
-    case D3DRS_POINTSCALE_B              :
-    case D3DRS_POINTSCALE_C              :
-    case D3DRS_POINTSCALEENABLE          :
-        {
-            /* If enabled, supply the parameters, otherwise fall back to defaults */
-            if (This->StateBlock->renderstate[D3DRS_POINTSCALEENABLE]) {
-                GLfloat att[3] = {1.0f, 0.0f, 0.0f};
-                att[0] = *((float*)&This->StateBlock->renderstate[D3DRS_POINTSCALE_A]);
-                att[1] = *((float*)&This->StateBlock->renderstate[D3DRS_POINTSCALE_B]);
-                att[2] = *((float*)&This->StateBlock->renderstate[D3DRS_POINTSCALE_C]);
-
-               if (GL_SUPPORT(EXT_POINT_PARAMETERS)) {
-                  GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
-                 checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...);");
-               } else {
-                 TRACE("D3DRS_POINTSCALEENABLE not supported on this opengl\n");
-               }
-            } else {
-                GLfloat att[3] = {1.0f, 0.0f, 0.0f};
-               if (GL_SUPPORT(EXT_POINT_PARAMETERS)) {
-                 GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
-                 checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...);");
-               } else {
-                 TRACE("D3DRS_POINTSCALEENABLE not supported, but not on either\n");
-               }
-           }
-            break;
-        }
+static HRESULT WINAPI IDirect3DDevice8Impl_Clear(LPDIRECT3DDEVICE8 iface, DWORD Count, CONST D3DRECT* pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n" , This);
 
-    case D3DRS_COLORWRITEENABLE          :
-        TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n", 
-             Value & D3DCOLORWRITEENABLE_RED   ? 1 : 0,
-             Value & D3DCOLORWRITEENABLE_GREEN ? 1 : 0,
-             Value & D3DCOLORWRITEENABLE_BLUE  ? 1 : 0,
-             Value & D3DCOLORWRITEENABLE_ALPHA ? 1 : 0); 
-       glColorMask(Value & D3DCOLORWRITEENABLE_RED, 
-                    Value & D3DCOLORWRITEENABLE_GREEN,
-                   Value & D3DCOLORWRITEENABLE_BLUE, 
-                    Value & D3DCOLORWRITEENABLE_ALPHA);
-        checkGLcall("glColorMask(...)");
-               break;
-
-        /* Unhandled yet...! */
-    case D3DRS_LASTPIXEL                 :
-    case D3DRS_ZVISIBLE                  :
-    case D3DRS_EDGEANTIALIAS             :
-    case D3DRS_RANGEFOGENABLE            :
-    case D3DRS_WRAP0                     :
-    case D3DRS_WRAP1                     :
-    case D3DRS_WRAP2                     :
-    case D3DRS_WRAP3                     :
-    case D3DRS_WRAP4                     :
-    case D3DRS_WRAP5                     :
-    case D3DRS_WRAP6                     :
-    case D3DRS_WRAP7                     :
-    case D3DRS_FOGVERTEXMODE             :
-    case D3DRS_LOCALVIEWER               :
-    case D3DRS_SOFTWAREVERTEXPROCESSING  :
-    case D3DRS_POINTSPRITEENABLE         :
-    case D3DRS_MULTISAMPLEANTIALIAS      :
-    case D3DRS_MULTISAMPLEMASK           :
-    case D3DRS_PATCHEDGESTYLE            :
-    case D3DRS_PATCHSEGMENTS             :
-    case D3DRS_DEBUGMONITORTOKEN         :
-    case D3DRS_POSITIONORDER             :
-    case D3DRS_NORMALORDER               :
-        /*Put back later: FIXME("(%p)->(%d,%ld) not handled yet\n", This, State, Value); */
-        TRACE("(%p)->(%d,%ld) not handled yet\n", This, State, Value);
-        break;
-    default:
-        FIXME("(%p)->(%d,%ld) unrecognized\n", This, State, Value);
-    }
+    return IWineD3DDevice_Clear(This->WineD3DDevice, Count, pRects, Flags, Color, Z, Stencil);
+}
 
-    LEAVE_GL();
+static HRESULT WINAPI IDirect3DDevice8Impl_SetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* lpMatrix) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n" , This);
 
-    return D3D_OK;
+    return IWineD3DDevice_SetTransform(This->WineD3DDevice, State, lpMatrix);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_GetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD* pValue) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    TRACE("(%p) for State %d = %ld\n", This, State, This->UpdateStateBlock->renderstate[State]);
-    *pValue = This->StateBlock->renderstate[State];
-    return D3D_OK;
+
+static HRESULT WINAPI IDirect3DDevice8Impl_GetTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State,D3DMATRIX* pMatrix) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n" , This);
+
+    return IWineD3DDevice_GetTransform(This->WineD3DDevice, State, pMatrix);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_BeginStateBlock(LPDIRECT3DDEVICE8 iface) {
-  ICOM_THIS(IDirect3DDevice8Impl,iface);
-  
-  TRACE("(%p)\n", This);
-  
-  return IDirect3DDeviceImpl_BeginStateBlock(This);
+
+static HRESULT WINAPI IDirect3DDevice8Impl_MultiplyTransform(LPDIRECT3DDEVICE8 iface, D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n" , This);
+
+    return IWineD3DDevice_MultiplyTransform(This->WineD3DDevice, State, pMatrix);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_EndStateBlock(LPDIRECT3DDEVICE8 iface, DWORD* pToken) {
-  IDirect3DStateBlockImpl* pSB;
-  ICOM_THIS(IDirect3DDevice8Impl,iface);
-  HRESULT res;
 
-  TRACE("(%p)\n", This);
+static HRESULT WINAPI IDirect3DDevice8Impl_SetViewport(LPDIRECT3DDEVICE8 iface, CONST D3DVIEWPORT8* pViewport) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n" , This);
 
-  res = IDirect3DDeviceImpl_EndStateBlock(This, &pSB);
-  *pToken = (DWORD) pSB;
-  return res;
+    return IWineD3DDevice_SetViewport(This->WineD3DDevice, (const WINED3DVIEWPORT *)pViewport);
 }
 
-HRESULT  WINAPI  IDirect3DDevice8Impl_ApplyStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
-  IDirect3DStateBlockImpl* pSB = (IDirect3DStateBlockImpl*) Token;
-  ICOM_THIS(IDirect3DDevice8Impl,iface);
+static HRESULT WINAPI IDirect3DDevice8Impl_GetViewport(LPDIRECT3DDEVICE8 iface, D3DVIEWPORT8* pViewport) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n" , This);
 
-  TRACE("(%p)\n", This);
+    return IWineD3DDevice_GetViewport(This->WineD3DDevice, (WINED3DVIEWPORT *)pViewport);
+}
 
-  return IDirect3DDeviceImpl_ApplyStateBlock(This, pSB);
+static HRESULT WINAPI IDirect3DDevice8Impl_SetMaterial(LPDIRECT3DDEVICE8 iface, CONST D3DMATERIAL8* pMaterial) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n" , This);
+/* FIXME: Verify that D3DMATERIAL8 ~= WINED3DMATERIAL */
+    return IWineD3DDevice_SetMaterial(This->WineD3DDevice, (const WINED3DMATERIAL *)pMaterial);
+}
 
+static HRESULT WINAPI IDirect3DDevice8Impl_GetMaterial(LPDIRECT3DDEVICE8 iface, D3DMATERIAL8* pMaterial) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n" , This);
+/* FIXME: Verify that D3DMATERIAL8 ~= WINED3DMATERIAL */
+    return IWineD3DDevice_GetMaterial(This->WineD3DDevice, (WINED3DMATERIAL *)pMaterial);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_CaptureStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
-  IDirect3DStateBlockImpl* pSB = (IDirect3DStateBlockImpl*) Token;
-  ICOM_THIS(IDirect3DDevice8Impl,iface);
 
-  TRACE("(%p)\n", This);
+static HRESULT WINAPI IDirect3DDevice8Impl_SetLight(LPDIRECT3DDEVICE8 iface, DWORD Index, CONST D3DLIGHT8* pLight) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n" , This);
+/* FIXME: Verify that D3DLIGHT8 ~= WINED3DLIGHT */
+    return IWineD3DDevice_SetLight(This->WineD3DDevice, Index, (const WINED3DLIGHT *)pLight);
+}
 
-  return IDirect3DDeviceImpl_CaptureStateBlock(This, pSB);
+static HRESULT WINAPI IDirect3DDevice8Impl_GetLight(LPDIRECT3DDEVICE8 iface, DWORD Index,D3DLIGHT8* pLight) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n" , This);
+/* FIXME: Verify that D3DLIGHT8 ~= WINED3DLIGHT */
+    return IWineD3DDevice_GetLight(This->WineD3DDevice, Index, (WINED3DLIGHT *)pLight);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_DeleteStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
-  IDirect3DStateBlockImpl* pSB = (IDirect3DStateBlockImpl*) Token;
-  ICOM_THIS(IDirect3DDevice8Impl,iface);
 
-  TRACE("(%p)\n", This);
+static HRESULT WINAPI IDirect3DDevice8Impl_LightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL Enable) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n" , This);
 
-  return IDirect3DDeviceImpl_DeleteStateBlock(This, pSB);
+    return IWineD3DDevice_SetLightEnable(This->WineD3DDevice, Index, Enable);
 }
 
-HRESULT  WINAPI  IDirect3DDevice8Impl_CreateStateBlock(LPDIRECT3DDEVICE8 iface, D3DSTATEBLOCKTYPE Type, DWORD* pToken) {
-  IDirect3DStateBlockImpl* pSB;
-  ICOM_THIS(IDirect3DDevice8Impl,iface);
-  HRESULT res;
+static HRESULT WINAPI IDirect3DDevice8Impl_GetLightEnable(LPDIRECT3DDEVICE8 iface, DWORD Index,BOOL* pEnable) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n" , This);
 
-  TRACE("(%p) : for type %d\n", This, Type);
+    return IWineD3DDevice_GetLightEnable(This->WineD3DDevice, Index, pEnable);
+}
+
+static HRESULT WINAPI IDirect3DDevice8Impl_SetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,CONST float* pPlane) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n" , This);
 
-  res = IDirect3DDeviceImpl_CreateStateBlock(This, Type, &pSB);
-  *pToken = (DWORD) pSB;
-  return res;
+    return IWineD3DDevice_SetClipPlane(This->WineD3DDevice, Index, pPlane);
 }
 
-HRESULT  WINAPI  IDirect3DDevice8Impl_SetClipStatus(LPDIRECT3DDEVICE8 iface, CONST D3DCLIPSTATUS8* pClipStatus) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    FIXME("(%p) : stub\n", This);    return D3D_OK;
+static HRESULT WINAPI IDirect3DDevice8Impl_GetClipPlane(LPDIRECT3DDEVICE8 iface, DWORD Index,float* pPlane) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n" , This);
+
+    return IWineD3DDevice_GetClipPlane(This->WineD3DDevice, Index, pPlane);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_GetClipStatus(LPDIRECT3DDEVICE8 iface, D3DCLIPSTATUS8* pClipStatus) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    FIXME("(%p) : stub\n", This);    return D3D_OK;
+
+static HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD Value) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n" , This);
+
+    return IWineD3DDevice_SetRenderState(This->WineD3DDevice, State, Value);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_GetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8** ppTexture) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    TRACE("(%p) : returning %p for stage %ld\n", This, This->UpdateStateBlock->textures[Stage], Stage);
-    *ppTexture = (LPDIRECT3DBASETEXTURE8) This->UpdateStateBlock->textures[Stage];
-    IDirect3DBaseTexture8Impl_AddRef(*ppTexture);
-    return D3D_OK;
+
+static HRESULT WINAPI IDirect3DDevice8Impl_GetRenderState(LPDIRECT3DDEVICE8 iface, D3DRENDERSTATETYPE State,DWORD* pValue) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n" , This);
+
+    return IWineD3DDevice_GetRenderState(This->WineD3DDevice, State, pValue);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage, IDirect3DBaseTexture8* pTexture) {
 
-    IDirect3DBaseTexture8 *oldTxt;
-    BOOL reapplyStates = TRUE;
-    DWORD oldTextureDimensions = -1;
-    DWORD reapplyFlags = 0;
+static HRESULT WINAPI IDirect3DDevice8Impl_BeginStateBlock(LPDIRECT3DDEVICE8 iface) {
+  IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
 
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    D3DRESOURCETYPE textureType;
+  TRACE("(%p)\n", This);
 
-    oldTxt = This->UpdateStateBlock->textures[Stage];
-    TRACE("(%p) : Stage(%ld), Texture (%p)\n", This, Stage, pTexture);
+  return IWineD3DDevice_BeginStateBlock(This->WineD3DDevice);
+}
 
-    /* Reject invalid texture units */
-    if (Stage >= GL_LIMITS(textures)) {
-        TRACE("Attempt to access invalid texture rejected\n");
-        return D3DERR_INVALIDCALL;
-    }
+static HRESULT WINAPI IDirect3DDevice8Impl_EndStateBlock(LPDIRECT3DDEVICE8 iface, DWORD* pToken) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    HRESULT hr;
+    IWineD3DStateBlock* wineD3DStateBlock;
+    IDirect3DStateBlock8Impl* object;
 
-    This->UpdateStateBlock->Set.textures[Stage] = TRUE;
-    This->UpdateStateBlock->Changed.textures[Stage] = TRUE;
-    This->UpdateStateBlock->textures[Stage] = pTexture;
+    TRACE("(%p) Relay\n", This);
 
-    /* Handle recording of state blocks */
-    if (This->isRecordingState) {
-        TRACE("Recording... not performing anything\n");
-        return D3D_OK;
+    /* Tell wineD3D to endstatablock before anything else (in case we run out
+     * of memory later and cause locking problems)
+     */
+    hr = IWineD3DDevice_EndStateBlock(This->WineD3DDevice , &wineD3DStateBlock);
+    if (hr != D3D_OK) {
+       FIXME("IWineD3DDevice_EndStateBlock returned an error\n");
+       return hr;
     }
 
-    oldTextureDimensions = This->UpdateStateBlock->textureDimensions[Stage];
-    ENTER_GL();
-
-    /* Make appropriate texture active */
-    if (GL_SUPPORT(ARB_MULTITEXTURE)) {
-#if defined(GL_VERSION_1_3)
-        glActiveTexture(GL_TEXTURE0 + Stage);
-#else
-        glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
-#endif
-        checkGLcall("glActiveTextureARB");
-    } else if (Stage>0) {
-        FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
-    }
+    /* allocate a new IDirectD3DStateBlock */
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY ,sizeof(IDirect3DStateBlock8Impl));
+    object->ref = 1;
+    object->lpVtbl = &Direct3DStateBlock8_Vtbl;
 
-    /* Decrement the count of the previous texture */
-    if (NULL != oldTxt) {
-        IDirect3DBaseTexture8Impl_Release(oldTxt);
-    }
+    object->wineD3DStateBlock = wineD3DStateBlock;
 
-    if (NULL != pTexture) {
-        IDirect3DBaseTexture8Impl_AddRef((LPDIRECT3DBASETEXTURE8) This->UpdateStateBlock->textures[Stage]);
-
-        /* Now setup the texture appropraitly */
-        textureType = IDirect3DBaseTexture8Impl_GetType(pTexture);
-
-        if (textureType == D3DRTYPE_TEXTURE) {
-          if (oldTxt == pTexture && TRUE == IDirect3DBaseTexture8Impl_IsDirty(pTexture)) {
-            TRACE("Skipping setting texture as old == new\n");
-            reapplyStates = FALSE;
-          } else {
-            /* Standard 2D texture */
-            TRACE("Standard 2d texture\n");
-            This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_2D;
-
-            /* Load up the texture now */
-            IDirect3DTexture8Impl_PreLoad((LPDIRECT3DTEXTURE8) pTexture);
-          }
-        } else if (textureType == D3DRTYPE_VOLUMETEXTURE) {
-         if (oldTxt == pTexture && TRUE == IDirect3DBaseTexture8Impl_IsDirty(pTexture)) {
-           TRACE("Skipping setting texture as old == new\n");
-           reapplyStates = FALSE;
-          } else {
-           /* Standard 3D (volume) texture */
-            TRACE("Standard 3d texture\n");
-            This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_3D;
-
-            /* Load up the texture now */
-           IDirect3DVolumeTexture8Impl_PreLoad((LPDIRECT3DVOLUMETEXTURE8) pTexture);
-         }
-        } else if (textureType == D3DRTYPE_CUBETEXTURE) {
-         if (oldTxt == pTexture && TRUE == IDirect3DBaseTexture8Impl_IsDirty(pTexture)) {
-           TRACE("Skipping setting texture as old == new\n");
-           reapplyStates = FALSE;
-          } else {
-           /* Standard Cube texture */
-           TRACE("Standard Cube texture\n");
-           This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_CUBE_MAP_ARB;
-
-           /* Load up the texture now */
-           IDirect3DCubeTexture8Impl_PreLoad((LPDIRECT3DCUBETEXTURE8) pTexture);
-         }
-       } else {
-            FIXME("(%p) : Incorrect type for a texture : (%d,%s)\n", This, textureType, debug_d3dressourcetype(textureType));
-        }
-    } else {
-        TRACE("Setting to no texture (ie default texture)\n");
-        This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_1D;
-        glBindTexture(GL_TEXTURE_1D, This->dummyTextureName[Stage]);
-        checkGLcall("glBindTexture");
-        TRACE("Bound dummy Texture to stage %ld (gl name %d)\n", Stage, This->dummyTextureName[Stage]);
-    }
+    *pToken = (DWORD)object;
+    TRACE("(%p)Returning %p %p\n", This, object, wineD3DStateBlock);
 
-    /* Disable the old texture binding and enable the new one (unless operations are disabled) */
-    if (oldTextureDimensions != This->UpdateStateBlock->textureDimensions[Stage]) {
-       glDisable(oldTextureDimensions);
-       checkGLcall("Disable oldTextureDimensions");
-       if (This->StateBlock->texture_state[Stage][D3DTSS_COLOROP] != D3DTOP_DISABLE) {
-          glEnable(This->UpdateStateBlock->textureDimensions[Stage]);
-          checkGLcall("glEnable new texture dimensions");
-       }
-
-       /* If Alpha arg1 is texture then handle the special case when there changes between a
-          texture and no texture - See comments in set_tex_op                                  */
-       if ((This->StateBlock->texture_state[Stage][D3DTSS_ALPHAARG1] == D3DTA_TEXTURE) && 
-           (((oldTxt == NULL) && (pTexture != NULL)) || ((pTexture == NULL) && (oldTxt != NULL))))
-       {
-           reapplyFlags |= REAPPLY_ALPHAOP;
-       }
-    }
+    return hr;
+}
 
+static HRESULT WINAPI IDirect3DDevice8Impl_ApplyStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
+    IDirect3DStateBlock8Impl *pSB  = (IDirect3DStateBlock8Impl*) Token;
+    IDirect3DDevice8Impl     *This = (IDirect3DDevice8Impl *)iface;
 
-    /* Even if the texture has been set to null, reapply the stages as a null texture to directx requires
-       a dummy texture in opengl, and we always need to ensure the current view of the TextureStates apply */
-    if (reapplyStates) {
-       setupTextureStates(iface, Stage, reapplyFlags);
-    }
+    TRACE("(%p) %p Relay\n", This, pSB);
 
-    LEAVE_GL();   
+    return  IWineD3DStateBlock_Apply(pSB->wineD3DStateBlock);
+}
 
-    return D3D_OK;
+static HRESULT WINAPI IDirect3DDevice8Impl_CaptureStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
+    IDirect3DStateBlock8Impl* pSB = (IDirect3DStateBlock8Impl *)Token;
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+
+    TRACE("(%p) %p Relay\n", This, pSB);
+
+    return IWineD3DStateBlock_Capture(pSB->wineD3DStateBlock);
 }
 
-HRESULT  WINAPI  IDirect3DDevice8Impl_GetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD* pValue) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    TRACE("(%p) : requesting Stage %ld, Type %d getting %ld\n", This, Stage, Type, This->UpdateStateBlock->texture_state[Stage][Type]);
-    *pValue = This->UpdateStateBlock->texture_state[Stage][Type];
+static HRESULT WINAPI IDirect3DDevice8Impl_DeleteStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
+    IDirect3DStateBlock8Impl* pSB = (IDirect3DStateBlock8Impl *)Token;
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+
+    TRACE("(%p) Relay\n", This);
+
+    while(IUnknown_Release((IUnknown *)pSB));
+
     return D3D_OK;
 }
 
-HRESULT  WINAPI  IDirect3DDevice8Impl_SetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
+static HRESULT WINAPI IDirect3DDevice8Impl_CreateStateBlock(LPDIRECT3DDEVICE8 iface, D3DSTATEBLOCKTYPE Type, DWORD* pToken) {
+   IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+   IDirect3DStateBlock8Impl *object;
+   HRESULT hrc = D3D_OK;
 
-    /* FIXME: Handle 3d textures? What if TSS value set before set texture? Need to reapply all values? */
-   
-    TRACE("(%p) : Stage=%ld, Type=%s(%d), Value=%ld\n", This, Stage, debug_d3dtexturestate(Type), Type, Value);
+   TRACE("(%p) Relay\n", This);
 
-    /* Reject invalid texture units */
-    if (Stage >= GL_LIMITS(textures)) {
-        TRACE("Attempt to access invalid texture rejected\n");
-        return D3DERR_INVALIDCALL;
-    }
+   object  = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DStateBlock8Impl));
+   if (NULL == object) {
+      *pToken = 0;
+      return E_OUTOFMEMORY;
+   }
+   object->lpVtbl = &Direct3DStateBlock8_Vtbl;
+   object->ref = 1;
+
+   hrc = IWineD3DDevice_CreateStateBlock(This->WineD3DDevice, (WINED3DSTATEBLOCKTYPE)Type, &object->wineD3DStateBlock, (IUnknown *)object);
+   if(D3D_OK != hrc){
+       FIXME("(%p) Call to IWineD3DDevice_CreateStateBlock failed.\n", This);
+       HeapFree(GetProcessHeap(), 0, object);
+       *pToken = 0;
+   } else {
+       *pToken = (DWORD)object;
+   }
+   TRACE("(%p) returning token (ptr to stateblock) of %p\n", This, object);
+
+   return hrc;
+}
 
-    This->UpdateStateBlock->Changed.texture_state[Stage][Type] = TRUE;
-    This->UpdateStateBlock->Set.texture_state[Stage][Type] = TRUE;
-    This->UpdateStateBlock->texture_state[Stage][Type] = Value;
+static HRESULT WINAPI IDirect3DDevice8Impl_SetClipStatus(LPDIRECT3DDEVICE8 iface, CONST D3DCLIPSTATUS8* pClipStatus) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n" , This);
+/* FIXME: Verify that D3DCLIPSTATUS8 ~= WINED3DCLIPSTATUS */
+    return IWineD3DDevice_SetClipStatus(This->WineD3DDevice, (const WINED3DCLIPSTATUS *)pClipStatus);
+}
+
+static HRESULT WINAPI IDirect3DDevice8Impl_GetClipStatus(LPDIRECT3DDEVICE8 iface, D3DCLIPSTATUS8* pClipStatus) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n" , This);
+
+    return IWineD3DDevice_GetClipStatus(This->WineD3DDevice, (WINED3DCLIPSTATUS *)pClipStatus);
+}
 
-    /* Handle recording of state blocks */
-    if (This->isRecordingState) {
-        TRACE("Recording... not performing anything\n");
-        return D3D_OK;
+static HRESULT WINAPI IDirect3DDevice8Impl_GetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8** ppTexture) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    IWineD3DBaseTexture *retTexture = NULL;
+    HRESULT rc = D3D_OK;
+
+    TRACE("(%p) Relay\n" , This);
+
+    if(ppTexture == NULL){
+        return D3DERR_INVALIDCALL;
     }
 
-    ENTER_GL();
-
-    /* Make appropriate texture active */
-    VTRACE(("Activating appropriate texture state %ld\n", Stage));
-    if (GL_SUPPORT(ARB_MULTITEXTURE)) {
-#if defined(GL_VERSION_1_3)
-        glActiveTexture(GL_TEXTURE0 + Stage);
-        vcheckGLcall("glActiveTexture");
-#else
-        glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
-        vcheckGLcall("glActiveTextureARB");
-#endif
-    } else if (Stage > 0) {
-        FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
+    rc = IWineD3DDevice_GetTexture(This->WineD3DDevice, Stage, (IWineD3DBaseTexture **)&retTexture);
+    if (rc == D3D_OK && NULL != retTexture) {
+        IWineD3DBaseTexture_GetParent(retTexture, (IUnknown **)ppTexture);
+        IWineD3DBaseTexture_Release(retTexture);
+    } else {
+        FIXME("Call to get texture  (%ld) failed (%p)\n", Stage, retTexture);
+        *ppTexture = NULL;
     }
 
-    switch (Type) {
-
-    case D3DTSS_MINFILTER             :
-    case D3DTSS_MIPFILTER             :
-        {
-            DWORD ValueMIN = This->StateBlock->texture_state[Stage][D3DTSS_MINFILTER];
-            DWORD ValueMIP = This->StateBlock->texture_state[Stage][D3DTSS_MIPFILTER];
-            GLint realVal = GL_LINEAR;
-
-            if (ValueMIN == D3DTEXF_POINT) {
-                /* GL_NEAREST_* */
-                if (ValueMIP == D3DTEXF_POINT) {
-                    realVal = GL_NEAREST_MIPMAP_NEAREST;
-                } else if (ValueMIP == D3DTEXF_LINEAR) {
-                    realVal = GL_NEAREST_MIPMAP_LINEAR;
-                } else if (ValueMIP == D3DTEXF_NONE) {
-                    realVal = GL_NEAREST;
-                } else {
-                    FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP);
-                    realVal = GL_NEAREST_MIPMAP_LINEAR;
-                }
-            } else if (ValueMIN == D3DTEXF_LINEAR) {
-                /* GL_LINEAR_* */
-                if (ValueMIP == D3DTEXF_POINT) {
-                    realVal = GL_LINEAR_MIPMAP_NEAREST;
-                } else if (ValueMIP == D3DTEXF_LINEAR) {
-                    realVal = GL_LINEAR_MIPMAP_LINEAR;
-                } else if (ValueMIP == D3DTEXF_NONE) {
-                    realVal = GL_LINEAR;
-                } else {
-                    FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP);
-                    realVal = GL_LINEAR_MIPMAP_LINEAR;
-                }
-            } else if (ValueMIN == D3DTEXF_NONE) {
-                /* Doesnt really make sense - Windows just seems to disable
-                   mipmapping when this occurs                              */
-                FIXME("Odd - minfilter of none, just disabling mipmaps\n");
-                realVal = GL_LINEAR;
+    return rc;
+}
 
-            } else {
-                FIXME("Unhandled D3DTSS_MINFILTER value of %ld\n", ValueMIN);
-                realVal = GL_LINEAR_MIPMAP_LINEAR;
-            }
+static HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage, IDirect3DBaseTexture8* pTexture) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay %ld %p\n" , This, Stage, pTexture);
 
-            TRACE("ValueMIN=%ld, ValueMIP=%ld, setting MINFILTER to %x\n", ValueMIN, ValueMIP, realVal);
-            glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_MIN_FILTER, realVal);
-            checkGLcall("glTexParameter GL_TEXTURE_MINFILTER, ...");
-        }
-        break;
+    return IWineD3DDevice_SetTexture(This->WineD3DDevice, Stage,
+                                     pTexture==NULL ? NULL : ((IDirect3DBaseTexture8Impl *)pTexture)->wineD3DBaseTexture);
+}
 
-    case D3DTSS_MAXANISOTROPY         :
-      {        
-       if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
-         glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_MAX_ANISOTROPY_EXT, This->StateBlock->texture_state[Stage][D3DTSS_MAXANISOTROPY]);
-         checkGLcall("glTexParameteri GL_TEXTURE_MAX_ANISOTROPY_EXT ...");
-       }
-      }
-      break;
-
-    case D3DTSS_MAGFILTER             :
-        if (Value == D3DTEXF_POINT) {
-            glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-            checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_NEAREST");
-        } else if (Value == D3DTEXF_LINEAR) {
-            glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-            checkGLcall("glTexParameter GL_TEXTURE_MAGFILTER, GL_LINEAR");
-        } else {
-            FIXME("Unhandled D3DTSS_MAGFILTER value of %ld\n", Value);
-        }
+static HRESULT  WINAPI  IDirect3DDevice8Impl_GetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD* pValue) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n" , This);
+
+    switch(Type) {
+    case D3DTSS_ADDRESSU:
+        Type = WINED3DSAMP_ADDRESSU;
+        break;
+    case D3DTSS_ADDRESSV:
+        Type = WINED3DSAMP_ADDRESSV;
+        break;
+    case D3DTSS_ADDRESSW:
+        Type = WINED3DSAMP_ADDRESSW;
+        break;
+    case D3DTSS_BORDERCOLOR:
+        Type = WINED3DSAMP_BORDERCOLOR;
+        break;
+    case D3DTSS_MAGFILTER:
+        Type = WINED3DSAMP_MAGFILTER;
+        break;
+    case D3DTSS_MAXANISOTROPY:
+        Type = WINED3DSAMP_MAXANISOTROPY;
         break;
+    case D3DTSS_MAXMIPLEVEL:
+        Type = WINED3DSAMP_MAXMIPLEVEL;
+        break;
+    case D3DTSS_MINFILTER:
+        Type = WINED3DSAMP_MINFILTER;
+        break;
+    case D3DTSS_MIPFILTER:
+        Type = WINED3DSAMP_MIPFILTER;
+        break;
+    case D3DTSS_MIPMAPLODBIAS:
+        Type = WINED3DSAMP_MIPMAPLODBIAS;
+        break;
+    default:
+        return IWineD3DDevice_GetTextureStageState(This->WineD3DDevice, Stage, Type, pValue);
+    }
 
-    case D3DTSS_ALPHAOP               :
-    case D3DTSS_COLOROP               :
-        {
-
-            if ((Value == D3DTOP_DISABLE) && (Type == D3DTSS_COLOROP)) {
-                /* TODO: Disable by making this and all later levels disabled */
-                glDisable(GL_TEXTURE_1D);
-                checkGLcall("Disable GL_TEXTURE_1D");
-                glDisable(GL_TEXTURE_2D);
-                checkGLcall("Disable GL_TEXTURE_2D");
-                glDisable(GL_TEXTURE_3D);
-                checkGLcall("Disable GL_TEXTURE_3D");
-                break; /* Dont bother setting the texture operations */
-            } else {
-                /* Enable only the appropriate texture dimension */
-                if (Type == D3DTSS_COLOROP) {
-                    if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_1D) {
-                        glEnable(GL_TEXTURE_1D);
-                        checkGLcall("Enable GL_TEXTURE_1D");
-                    } else {
-                        glDisable(GL_TEXTURE_1D);
-                        checkGLcall("Disable GL_TEXTURE_1D");
-                    } 
-                    if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_2D) {
-                        glEnable(GL_TEXTURE_2D);
-                        checkGLcall("Enable GL_TEXTURE_2D");
-                    } else {
-                        glDisable(GL_TEXTURE_2D);
-                        checkGLcall("Disable GL_TEXTURE_2D");
-                    }
-                    if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_3D) {
-                        glEnable(GL_TEXTURE_3D);
-                        checkGLcall("Enable GL_TEXTURE_3D");
-                    } else {
-                        glDisable(GL_TEXTURE_3D);
-                        checkGLcall("Disable GL_TEXTURE_3D");
-                    }
-                    if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_CUBE_MAP_ARB) {
-                        glEnable(GL_TEXTURE_CUBE_MAP_ARB);
-                        checkGLcall("Enable GL_TEXTURE_CUBE_MAP");
-                    } else {
-                        glDisable(GL_TEXTURE_CUBE_MAP_ARB);
-                        checkGLcall("Disable GL_TEXTURE_CUBE_MAP");
-                    }
-                }
-            }
-            /* Drop through... (Except disable case) */
-        case D3DTSS_COLORARG0             :
-        case D3DTSS_COLORARG1             :
-        case D3DTSS_COLORARG2             :
-        case D3DTSS_ALPHAARG0             :
-        case D3DTSS_ALPHAARG1             :
-        case D3DTSS_ALPHAARG2             :
-            {
-                BOOL isAlphaArg = (Type == D3DTSS_ALPHAOP || Type == D3DTSS_ALPHAARG1 || 
-                                   Type == D3DTSS_ALPHAARG2 || Type == D3DTSS_ALPHAARG0);
-                if (isAlphaArg) {
-                    set_tex_op(iface, TRUE, Stage, This->StateBlock->texture_state[Stage][D3DTSS_ALPHAOP],
-                               This->StateBlock->texture_state[Stage][D3DTSS_ALPHAARG1], 
-                               This->StateBlock->texture_state[Stage][D3DTSS_ALPHAARG2], 
-                               This->StateBlock->texture_state[Stage][D3DTSS_ALPHAARG0]);
-                } else {
-                    set_tex_op(iface, FALSE, Stage, This->StateBlock->texture_state[Stage][D3DTSS_COLOROP],
-                               This->StateBlock->texture_state[Stage][D3DTSS_COLORARG1], 
-                               This->StateBlock->texture_state[Stage][D3DTSS_COLORARG2], 
-                               This->StateBlock->texture_state[Stage][D3DTSS_COLORARG0]);
-                }
-            }
-            break;
-        }
+    return IWineD3DDevice_GetSamplerState(This->WineD3DDevice, Stage, Type, pValue);
+}
 
-    case D3DTSS_ADDRESSU              :
-    case D3DTSS_ADDRESSV              :
-    case D3DTSS_ADDRESSW              :
-        {
-            GLint wrapParm = GL_REPEAT;
-            switch (Value) {
-            case D3DTADDRESS_WRAP:   wrapParm = GL_REPEAT; break;
-            case D3DTADDRESS_CLAMP:  wrapParm = GL_CLAMP_TO_EDGE; break;      
-            case D3DTADDRESS_BORDER: wrapParm = GL_REPEAT; break;      /* FIXME: Not right, but better */
-#if defined(GL_VERSION_1_4)
-            case D3DTADDRESS_MIRROR: wrapParm = GL_MIRRORED_REPEAT; break;
-#elif defined(GL_ARB_texture_mirrored_repeat)
-            case D3DTADDRESS_MIRROR: wrapParm = GL_MIRRORED_REPEAT_ARB; break;
-#else
-            case D3DTADDRESS_MIRROR:      /* Unsupported in OpenGL pre-1.4 */
-#endif
-            case D3DTADDRESS_MIRRORONCE:  /* Unsupported in OpenGL         */
-            default:
-                FIXME("Unrecognized or unsupported D3DTADDRESS_* value %ld, state %d\n", Value, Type);
-                wrapParm = GL_REPEAT; 
-            }
+static HRESULT WINAPI IDirect3DDevice8Impl_SetTextureStageState(LPDIRECT3DDEVICE8 iface, DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n" , This);
 
-            switch (Type) {
-            case D3DTSS_ADDRESSU:
-                TRACE("Setting WRAP_S to %d for %x\n", wrapParm, This->StateBlock->textureDimensions[Stage]);
-                glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_WRAP_S, wrapParm);
-                checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_S, wrapParm)");
-                break;
-            case D3DTSS_ADDRESSV:
-                TRACE("Setting WRAP_T to %d for %x\n", wrapParm, This->StateBlock->textureDimensions[Stage]);
-                glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_WRAP_T, wrapParm);
-                checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_T, wrapParm)");
-                break;
-            case D3DTSS_ADDRESSW:
-                TRACE("Setting WRAP_R to %d for %x\n", wrapParm, This->StateBlock->textureDimensions[Stage]);
-                glTexParameteri(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_WRAP_R, wrapParm);
-                checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_R, wrapParm)");
-                break;
-            default: /* nop */
-               break; /** stupic compilator */
-            }
-        }
+    switch(Type) {
+    case D3DTSS_ADDRESSU:
+        Type = WINED3DSAMP_ADDRESSU;
         break;
-
-    case D3DTSS_BORDERCOLOR           :
-        {
-            float col[4];
-           D3DCOLORTOGLFLOAT4(Value, col);
-            TRACE("Setting border color for %x to %lx\n", This->StateBlock->textureDimensions[Stage], Value); 
-            glTexParameterfv(This->StateBlock->textureDimensions[Stage], GL_TEXTURE_BORDER_COLOR, &col[0]);
-            checkGLcall("glTexParameteri(..., GL_TEXTURE_BORDER_COLOR, ...)");
-        }
+    case D3DTSS_ADDRESSV:
+        Type = WINED3DSAMP_ADDRESSV;
         break;
-
-    case D3DTSS_TEXCOORDINDEX         :
-        {
-            /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive */
-
-            /* FIXME: From MSDN: The D3DTSS_TCI_* flags are mutually exclusive. If you include 
-                  one flag, you can still specify an index value, which the system uses to 
-                  determine the texture wrapping mode.  
-                  eg. SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION | 1 );
-                  means use the vertex position (camera-space) as the input texture coordinates 
-                  for this texture stage, and the wrap mode set in the D3DRS_WRAP1 render 
-                  state. We do not (yet) support the D3DRENDERSTATE_WRAPx values, nor tie them up
-                  to the TEXCOORDINDEX value */
-          
-            /** 
-             * Be careful the value of the mask 0xF0000 come from d3d8types.h infos 
-             */
-            switch (Value & 0xFFFF0000) {
-            case D3DTSS_TCI_PASSTHRU:
-              /*Use the specified texture coordinates contained within the vertex format. This value resolves to zero.*/
-             glDisable(GL_TEXTURE_GEN_S);
-             glDisable(GL_TEXTURE_GEN_T);
-             glDisable(GL_TEXTURE_GEN_R);
-              checkGLcall("glDisable(GL_TEXTURE_GEN_S,T,R)");
-              break;
-
-            case D3DTSS_TCI_CAMERASPACEPOSITION:
-              /* CameraSpacePosition means use the vertex position, transformed to camera space, 
-                 as the input texture coordinates for this stage's texture transformation. This 
-                 equates roughly to EYE_LINEAR                                                  */
-              {
-                float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
-                float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
-                float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
-                float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
-                TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n");
-
-                glMatrixMode(GL_MODELVIEW);
-                glPushMatrix();
-                glLoadIdentity();
-                glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
-                glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
-                glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
-                glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
-                glPopMatrix();
-                
-                TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set GL_TEXTURE_GEN_x and GL_x, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR\n");
-                glEnable(GL_TEXTURE_GEN_S);
-                checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
-                glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
-                checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
-                glEnable(GL_TEXTURE_GEN_T);
-                checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
-                glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
-                checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
-                glEnable(GL_TEXTURE_GEN_R);
-                checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
-                glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
-                checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
-              }
-              break;
-
-#if defined(GL_ARB_texture_cube_map) || defined(GL_NV_texgen_reflection)
-           case D3DTSS_TCI_CAMERASPACENORMAL:
-             {
-               float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
-                float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
-                float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
-                float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
-                TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n");
-
-                glMatrixMode(GL_MODELVIEW);
-                glPushMatrix();
-                glLoadIdentity();
-                glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
-                glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
-                glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
-                glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
-                glPopMatrix();
-
-               glEnable(GL_TEXTURE_GEN_S);
-               checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
-               glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB);
-                checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB)");
-               glEnable(GL_TEXTURE_GEN_T);
-               checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
-               glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB);
-                checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB)");
-               glEnable(GL_TEXTURE_GEN_R);
-               checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
-               glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB);
-                checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB)");
-             }
-             break;
-#endif
-
-#if defined(GL_ARB_texture_cube_map) || defined(GL_NV_texgen_reflection)
-           case D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
-             {
-
-               float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
-                float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
-                float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
-                float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
-                TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n");
-
-                glMatrixMode(GL_MODELVIEW);
-                glPushMatrix();
-                glLoadIdentity();
-                glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
-                glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
-                glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
-                glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
-                glPopMatrix();
-               
-               glEnable(GL_TEXTURE_GEN_S);
-               checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
-               glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB);
-                checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB)");
-               glEnable(GL_TEXTURE_GEN_T);
-               checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
-               glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB);
-                checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB)");
-               glEnable(GL_TEXTURE_GEN_R);
-               checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
-               glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB);
-                checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB)");
-             }
-             break;
-#endif
-
-            /* Unhandled types: */
-            default:
-                /* Todo: */
-                /* ? disable GL_TEXTURE_GEN_n ? */ 
-               glDisable(GL_TEXTURE_GEN_S);
-               glDisable(GL_TEXTURE_GEN_T);
-               glDisable(GL_TEXTURE_GEN_R);
-                FIXME("Unhandled D3DTSS_TEXCOORDINDEX %lx\n", Value);
-                break;
-            }
-        }
+    case D3DTSS_ADDRESSW:
+        Type = WINED3DSAMP_ADDRESSW;
         break;
-
-        /* Unhandled */
-    case D3DTSS_BUMPENVMAT00          :
-    case D3DTSS_BUMPENVMAT01          :
-        TRACE("BUMPENVMAT0%u Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Type - D3DTSS_BUMPENVMAT00, Stage, Type, Value);
+    case D3DTSS_BORDERCOLOR:
+        Type = WINED3DSAMP_BORDERCOLOR;
         break;
-    case D3DTSS_BUMPENVMAT10          :
-    case D3DTSS_BUMPENVMAT11          :
-        TRACE("BUMPENVMAT1%u Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Type - D3DTSS_BUMPENVMAT10, Stage, Type, Value);
+    case D3DTSS_MAGFILTER:
+        Type = WINED3DSAMP_MAGFILTER;
+        break;
+    case D3DTSS_MAXANISOTROPY:
+        Type = WINED3DSAMP_MAXANISOTROPY;
+        break;
+    case D3DTSS_MAXMIPLEVEL:
+        Type = WINED3DSAMP_MAXMIPLEVEL;
+        break;
+    case D3DTSS_MINFILTER:
+        Type = WINED3DSAMP_MINFILTER;
+        break;
+    case D3DTSS_MIPFILTER:
+        Type = WINED3DSAMP_MIPFILTER;
+        break;
+    case D3DTSS_MIPMAPLODBIAS:
+        Type = WINED3DSAMP_MIPMAPLODBIAS;
         break;
-
-    case D3DTSS_TEXTURETRANSFORMFLAGS :
-        set_texture_matrix((float *)&This->StateBlock->transforms[D3DTS_TEXTURE0 + Stage].u.m[0][0], Value);
-        break; 
-
-    case D3DTSS_MIPMAPLODBIAS         :
-    case D3DTSS_MAXMIPLEVEL           :
-    case D3DTSS_BUMPENVLSCALE         :
-    case D3DTSS_BUMPENVLOFFSET        :
-    case D3DTSS_RESULTARG             :
     default:
-        /* Put back later: FIXME("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value); */
-        TRACE("Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage, Type, Value);
+        return IWineD3DDevice_SetTextureStageState(This->WineD3DDevice, Stage, Type, Value);
     }
 
-    LEAVE_GL();
-
-    return D3D_OK;
-}
-HRESULT  WINAPI  IDirect3DDevice8Impl_ValidateDevice(LPDIRECT3DDEVICE8 iface, DWORD* pNumPasses) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    TRACE("(%p) : stub\n", This);    /* FIXME: Needs doing, but called often and is harmless */
-    return D3D_OK;
-}
-HRESULT  WINAPI  IDirect3DDevice8Impl_GetInfo(LPDIRECT3DDEVICE8 iface, DWORD DevInfoID, void* pDevInfoStruct, DWORD DevInfoStructSize) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    FIXME("(%p) : stub\n", This);    
-    return D3D_OK;
+    return IWineD3DDevice_SetSamplerState(This->WineD3DDevice, Stage, Type, Value);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_SetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber, CONST PALETTEENTRY* pEntries) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    FIXME("(%p) : setting p[%u] <= RGBA(%02x,%02x,%02x,%02x)\n", This, PaletteNumber,
-          pEntries->peRed, pEntries->peGreen, pEntries->peBlue, pEntries->peFlags);
-    memcpy(This->palettes[PaletteNumber], pEntries, 256 * sizeof(PALETTEENTRY));
-    return D3D_OK;
+
+static HRESULT WINAPI IDirect3DDevice8Impl_ValidateDevice(LPDIRECT3DDEVICE8 iface, DWORD* pNumPasses) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n" , This);
+
+    return IWineD3DDevice_ValidateDevice(This->WineD3DDevice, pNumPasses);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_GetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber, PALETTEENTRY* pEntries) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    memcpy(pEntries, This->palettes[PaletteNumber], 256 * sizeof(PALETTEENTRY));
-    FIXME("(%p) : returning p[%u] => RGBA(%02x,%02x,%02x,%02x)\n", This, PaletteNumber,
-          pEntries->peRed, pEntries->peGreen, pEntries->peBlue, pEntries->peFlags);
+
+static HRESULT WINAPI IDirect3DDevice8Impl_GetInfo(LPDIRECT3DDEVICE8 iface, DWORD DevInfoID, void* pDevInfoStruct, DWORD DevInfoStructSize) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    FIXME("(%p) : stub\n", This);
     return D3D_OK;
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_SetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    FIXME("(%p) : Setting to (%u)\n", This, PaletteNumber);
-    This->currentPalette = PaletteNumber;
 
-#if defined(GL_EXT_paletted_texture)
-    if (GL_SUPPORT(EXT_PALETTED_TEXTURE)) {
+static HRESULT WINAPI IDirect3DDevice8Impl_SetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber, CONST PALETTEENTRY* pEntries) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n" , This);
 
-      ENTER_GL();
-
-      GL_EXTCALL(glColorTableEXT)(GL_TEXTURE_2D,    /* target */
-                                 GL_RGBA,          /* internal format */
-                                 256,              /* table size */
-                                 GL_RGBA,          /* table format */
-                                 GL_UNSIGNED_BYTE, /* table type */
-                                 This->palettes[PaletteNumber]);
-      checkGLcall("glColorTableEXT");
+    return IWineD3DDevice_SetPaletteEntries(This->WineD3DDevice, PaletteNumber, pEntries);
+}
 
-      LEAVE_GL();
+static HRESULT WINAPI IDirect3DDevice8Impl_GetPaletteEntries(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber, PALETTEENTRY* pEntries) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n" , This);
 
-    } else {
-      /* Delayed palette handling ... waiting for software emulation into preload code */
-    }
-#endif
-    return D3D_OK;
-}
-HRESULT  WINAPI  IDirect3DDevice8Impl_GetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT *PaletteNumber) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    *PaletteNumber = This->currentPalette;
-    FIXME("(%p) : Returning (%u)\n", This, *PaletteNumber);
-    return D3D_OK;
+    return IWineD3DDevice_GetPaletteEntries(This->WineD3DDevice, PaletteNumber, pEntries);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_DrawPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount) {
 
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    This->StateBlock->streamIsUP = FALSE;
+static HRESULT WINAPI IDirect3DDevice8Impl_SetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT PaletteNumber) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n" , This);
+
+    return IWineD3DDevice_SetCurrentTexturePalette(This->WineD3DDevice, PaletteNumber);
+}
 
-    TRACE("(%p) : Type=(%d,%s), Start=%d, Count=%d\n", This, PrimitiveType, debug_d3dprimitivetype(PrimitiveType), StartVertex, PrimitiveCount);
-    drawPrimitive(iface, PrimitiveType, PrimitiveCount, StartVertex, -1, 0, NULL, 0);
+static HRESULT  WINAPI  IDirect3DDevice8Impl_GetCurrentTexturePalette(LPDIRECT3DDEVICE8 iface, UINT *PaletteNumber) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n" , This);
 
-    return D3D_OK;
+    return IWineD3DDevice_GetCurrentTexturePalette(This->WineD3DDevice, PaletteNumber);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,
-                                                           UINT minIndex,UINT NumVertices,UINT startIndex,UINT primCount) {
-    UINT idxStride = 2;
-    IDirect3DIndexBuffer8      *pIB;
-    D3DINDEXBUFFER_DESC         IdxBufDsc;
-
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    pIB = This->StateBlock->pIndexData;
-    This->StateBlock->streamIsUP = FALSE;
-
-    TRACE("(%p) : Type=(%d,%s), min=%d, CountV=%d, startIdx=%d, countP=%d \n", This, 
-          PrimitiveType, debug_d3dprimitivetype(PrimitiveType),
-          minIndex, NumVertices, startIndex, primCount);
-
-    IDirect3DIndexBuffer8Impl_GetDesc(pIB, &IdxBufDsc);
-    if (IdxBufDsc.Format == D3DFMT_INDEX16) {
-        idxStride = 2;
-    } else {
-        idxStride = 4;
-    }
 
-    drawPrimitive(iface, PrimitiveType, primCount, This->StateBlock->baseVertexIndex, startIndex, idxStride, ((IDirect3DIndexBuffer8Impl *) pIB)->allocatedMemory,
-                   minIndex);
+static HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; 
+    TRACE("(%p) Relay\n" , This);
 
-    return D3D_OK;
+    return IWineD3DDevice_DrawPrimitive(This->WineD3DDevice, PrimitiveType, StartVertex, PrimitiveCount);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
 
-    TRACE("(%p) : Type=(%d,%s), pCount=%d, pVtxData=%p, Stride=%d\n", This, PrimitiveType, debug_d3dprimitivetype(PrimitiveType), 
-          PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride);
+static HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,
+                                                           UINT MinVertexIndex,UINT NumVertices,UINT startIndex,UINT primCount) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n" , This);
 
-    if (This->StateBlock->stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock->stream_source[0]);
+    return IWineD3DDevice_DrawIndexedPrimitive(This->WineD3DDevice, PrimitiveType, This->baseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount);
+}
 
-    /* Note in the following, its not this type, but thats the purpose of streamIsUP */
-    This->StateBlock->stream_source[0] = (IDirect3DVertexBuffer8 *)pVertexStreamZeroData; 
-    This->StateBlock->stream_stride[0] = VertexStreamZeroStride;
-    This->StateBlock->streamIsUP = TRUE;
-    drawPrimitive(iface, PrimitiveType, PrimitiveCount, 0, 0, 0, NULL, 0);
-    This->StateBlock->stream_stride[0] = 0;
-    This->StateBlock->stream_source[0] = NULL;
+static HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n" , This);
 
-    /*stream zero settings set to null at end */
-    return D3D_OK;
+    return IWineD3DDevice_DrawPrimitiveUP(This->WineD3DDevice, PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,
+
+static HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVICE8 iface, D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,
                                                              UINT NumVertexIndices,UINT PrimitiveCount,CONST void* pIndexData,
                                                              D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,
                                                              UINT VertexStreamZeroStride) {
-    int idxStride;
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    TRACE("(%p) : Type=(%d,%s), MinVtxIdx=%d, NumVIdx=%d, PCount=%d, pidxdata=%p, IdxFmt=%d, pVtxdata=%p, stride=%d\n", This, PrimitiveType, debug_d3dprimitivetype(PrimitiveType),
-          MinVertexIndex, NumVertexIndices, PrimitiveCount, pIndexData,  IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride);
-
-    if (This->StateBlock->stream_source[0] != NULL) IDirect3DVertexBuffer8Impl_Release(This->StateBlock->stream_source[0]);
-    if (IndexDataFormat == D3DFMT_INDEX16) {
-        idxStride = 2;
-    } else {
-        idxStride = 4;
-    }
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n" , This);
 
-    /* Note in the following, its not this type, but thats the purpose of streamIsUP */
-    This->StateBlock->stream_source[0] = (IDirect3DVertexBuffer8 *)pVertexStreamZeroData;
-    This->StateBlock->streamIsUP = TRUE;
-    This->StateBlock->stream_stride[0] = VertexStreamZeroStride;
-    drawPrimitive(iface, PrimitiveType, PrimitiveCount, This->StateBlock->baseVertexIndex, 0, idxStride, pIndexData, MinVertexIndex);
+    return IWineD3DDevice_DrawIndexedPrimitiveUP(This->WineD3DDevice, PrimitiveType, MinVertexIndex, NumVertexIndices, PrimitiveCount,
+                                                 pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride);
+}
 
-    /*stream zero settings set to null at end */
-    This->StateBlock->stream_source[0] = NULL;
-    This->StateBlock->stream_stride[0] = 0;
-    IDirect3DDevice8Impl_SetIndices(iface, NULL, 0);
+static HRESULT WINAPI IDirect3DDevice8Impl_ProcessVertices(LPDIRECT3DDEVICE8 iface, UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer8* pDestBuffer,DWORD Flags) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n" , This);
 
-    return D3D_OK;
+    return IWineD3DDevice_ProcessVertices(This->WineD3DDevice,SrcStartIndex, DestIndex, VertexCount, ((IDirect3DVertexBuffer8Impl *)pDestBuffer)->wineD3DVertexBuffer, NULL, Flags);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_ProcessVertices(LPDIRECT3DDEVICE8 iface, UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer8* pDestBuffer,DWORD Flags) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    FIXME("(%p) : stub\n", This);    return D3D_OK;
-}
-HRESULT  WINAPI  IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pDeclaration, CONST DWORD* pFunction, DWORD* pHandle, DWORD Usage) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    IDirect3DVertexShaderImpl* object;
-    IDirect3DVertexShaderDeclarationImpl* attached_decl;
-    HRESULT res;
-    UINT i;
-
-    TRACE_(d3d_shader)("(%p) : VertexShader not fully supported yet : Decl=%p, Func=%p, Usage=%lu\n", This, pDeclaration, pFunction, Usage);
-    if (NULL == pDeclaration || NULL == pHandle) { /* pFunction can be NULL see MSDN */
-      return D3DERR_INVALIDCALL;
+
+static HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pDeclaration, CONST DWORD* pFunction, DWORD* ppShader, DWORD Usage) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    HRESULT hrc = D3D_OK;
+    IDirect3DVertexShader8Impl *object;
+
+    /* Setup a stub object for now */
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+    TRACE("(%p) : pFunction(%p), ppShader(%p)\n", This, pFunction, ppShader);
+    if (NULL == object) {
+        FIXME("Allocation of memory failed\n");
+        *ppShader = 0;
+        return D3DERR_OUTOFVIDEOMEMORY;
     }
-    for (i = 1; NULL != VertexShaders[i] && i < sizeof(VertexShaders) / sizeof(IDirect3DVertexShaderImpl*); ++i) ;
-    if (i >= sizeof(VertexShaders) / sizeof(IDirect3DVertexShaderImpl*)) {
-      return D3DERR_OUTOFVIDEOMEMORY;
+
+    object->ref = 1;
+    object->lpVtbl = &Direct3DVertexShader8_Vtbl;
+    /* Usage is missing ..*/
+    hrc = IWineD3DDevice_CreateVertexShader(This->WineD3DDevice, pDeclaration, pFunction, &object->wineD3DVertexShader, (IUnknown *)object);
+
+    if (FAILED(hrc)) {
+        /* free up object */
+        FIXME("Call to IWineD3DDevice_CreateVertexShader failed\n");
+        HeapFree(GetProcessHeap(), 0, object);
+        *ppShader = 0;
+    } else {
+        /* TODO: Store the VS declarations locally so that they can be derefferenced with a value higher than VS_HIGHESTFIXEDFXF */
+        shader_handle *handle = alloc_shader_handle(This);
+        if (!handle) {
+            ERR("Failed to allocate shader handle\n");
+            IDirect3DVertexShader8_Release((IUnknown *)object);
+            hrc = E_OUTOFMEMORY;
+        } else {
+            object->handle = handle;
+            *handle = object;
+            *ppShader = (handle - This->shader_handles) + VS_HIGHESTFIXEDFXF + 1;
+        }
     }
+    TRACE("(%p) : returning %p (handle %#lx)\n", This, object, *ppShader);
 
-    /** Create the Vertex Shader */
-    res = IDirect3DDeviceImpl_CreateVertexShader(This, pFunction, Usage, &object);
-    /** TODO: check FAILED(res) */
+    return hrc;
+}
 
-    /** Create and Bind the Vertex Shader Declaration */
-    res = IDirect3DDeviceImpl_CreateVertexShaderDeclaration8(This, pDeclaration, &attached_decl);
-    /** TODO: check FAILED(res) */
+static HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD pShader) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    HRESULT hrc = D3D_OK;
 
-    VertexShaders[i] = object;
-    VertexShaderDeclarations[i] = attached_decl;
-    *pHandle = VS_HIGHESTFIXEDFXF + i;
-    TRACE("Finished creating vertex shader %lx\n", *pHandle);
+    TRACE("(%p) : Relay\n", This);
+    if (VS_HIGHESTFIXEDFXF >= pShader) {
+        TRACE("Setting FVF, %d %ld\n", VS_HIGHESTFIXEDFXF, pShader);
+        IWineD3DDevice_SetFVF(This->WineD3DDevice, pShader);
 
-    return D3D_OK;
-}
-HRESULT  WINAPI  IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-
-    This->UpdateStateBlock->VertexShader = Handle;
-    This->UpdateStateBlock->Changed.vertexShader = TRUE;
-    This->UpdateStateBlock->Set.vertexShader = TRUE;
-    
-    if (Handle > VS_HIGHESTFIXEDFXF) { /* only valid with non FVF shaders */
-      TRACE_(d3d_shader)("(%p) : Created shader, Handle=%lx\n", This, Handle);
-      This->UpdateStateBlock->vertexShaderDecl = VERTEX_SHADER_DECL(Handle);
-      This->UpdateStateBlock->Changed.vertexShaderDecl = TRUE;
-      This->UpdateStateBlock->Set.vertexShaderDecl = TRUE;
-    } else { /* use a fvf, so desactivate the vshader decl */
-      TRACE("(%p) : FVF Shader, Handle=%lx\n", This, Handle);
-      This->UpdateStateBlock->vertexShaderDecl = NULL;
-      This->UpdateStateBlock->Changed.vertexShaderDecl = TRUE;
-      This->UpdateStateBlock->Set.vertexShaderDecl = TRUE;
-    }
-    /* Handle recording of state blocks */
-    if (This->isRecordingState) {
-      TRACE("Recording... not performing anything\n");
-      return D3D_OK;
+       /* Call SetVertexShader with a NULL shader to set the vertexshader in the stateblock to NULL. */
+        IWineD3DDevice_SetVertexShader(This->WineD3DDevice, NULL);
+    } else {
+        TRACE("Setting shader\n");
+        if (This->allocated_shader_handles <= pShader - (VS_HIGHESTFIXEDFXF + 1)) {
+            FIXME("(%p) : Number of shaders exceeds the maximum number of possible shaders\n", This);
+            hrc = D3DERR_INVALIDCALL;
+        } else {
+            IDirect3DVertexShader8Impl *shader = This->shader_handles[pShader - (VS_HIGHESTFIXEDFXF + 1)];
+            hrc =  IWineD3DDevice_SetVertexShader(This->WineD3DDevice, 0 == shader ? NULL : shader->wineD3DVertexShader);
+        }
     }
-    /**
-     * TODO: merge HAL shaders context switching from prototype
-     */
-    return D3D_OK;
-}
-HRESULT  WINAPI  IDirect3DDevice8Impl_GetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    TRACE_(d3d_shader)("(%p) : GetVertexShader returning %ld\n", This, This->StateBlock->VertexShader);
-    *pHandle = This->StateBlock->VertexShader;
-    return D3D_OK;
+    TRACE("(%p) : returning hr(%lu)\n", This, hrc);
+
+    return hrc;
 }
 
-HRESULT  WINAPI  IDirect3DDevice8Impl_DeleteVertexShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    IDirect3DVertexShaderImpl* object; 
-    IDirect3DVertexShaderDeclarationImpl* attached_decl;
+static HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD* ppShader) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    IWineD3DVertexShader *pShader;
+    HRESULT hrc = D3D_OK;
+
+    TRACE("(%p) : Relay  device@%p\n", This, This->WineD3DDevice);
+    hrc = IWineD3DDevice_GetVertexShader(This->WineD3DDevice, &pShader);
+    if (D3D_OK == hrc) {
+        if(0 != pShader) {
+            IDirect3DVertexShader8Impl *d3d8_shader;
+            hrc = IWineD3DVertexShader_GetParent(pShader, (IUnknown **)&d3d8_shader);
+            IWineD3DVertexShader_Release(pShader);
+            *ppShader = (d3d8_shader->handle - This->shader_handles) + (VS_HIGHESTFIXEDFXF + 1);
+        } else {
+            WARN("(%p) : The shader has been set to NULL\n", This);
 
-    if (Handle <= VS_HIGHESTFIXEDFXF) { /* only delete user defined shaders */
-      return D3DERR_INVALIDCALL;
+            /* TODO: Find out what should be returned, e.g. the FVF */
+            *ppShader = 0;
+            hrc = D3DERR_INVALIDCALL;
+        }
+    } else {
+        WARN("(%p) : Call to IWineD3DDevice_GetVertexShader failed %lu (device %p)\n", This, hrc, This->WineD3DDevice);
     }
+    TRACE("(%p) : returning %#lx\n", This, *ppShader);
 
-    /**
-     * Delete Vertex Shader
-     */
-    object = VertexShaders[Handle - VS_HIGHESTFIXEDFXF];
-    if (NULL == object) {
-      return D3DERR_INVALIDCALL;
+    return hrc;
+}
+
+static HRESULT  WINAPI  IDirect3DDevice8Impl_DeleteVertexShader(LPDIRECT3DDEVICE8 iface, DWORD pShader) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+
+    TRACE("(%p) : pShader %#lx\n", This, pShader);
+
+    if (pShader <= VS_HIGHESTFIXEDFXF || This->allocated_shader_handles <= pShader - (VS_HIGHESTFIXEDFXF + 1)) {
+        ERR("(%p) : Trying to delete an invalid handle\n", This);
+        return D3DERR_INVALIDCALL;
+    } else {
+        shader_handle *handle = &This->shader_handles[pShader - (VS_HIGHESTFIXEDFXF + 1)];
+        IDirect3DVertexShader8Impl *shader = *handle;
+        while(IUnknown_Release((IUnknown *)shader));
+        free_shader_handle(This, handle);
     }
-    TRACE_(d3d_shader)("(%p) : freing VertexShader %p\n", This, object);
-    /* TODO: check validity of object */
-    if (NULL != object->function) HeapFree(GetProcessHeap(), 0, (void *)object->function);
-    HeapFree(GetProcessHeap(), 0, (void *)object->data);
-    HeapFree(GetProcessHeap(), 0, (void *)object);
-    VertexShaders[Handle - VS_HIGHESTFIXEDFXF] = NULL;
-
-    /**
-     * Delete Vertex Shader Declaration
-     */
-    attached_decl = VertexShaderDeclarations[Handle - VS_HIGHESTFIXEDFXF];
-    if (NULL == attached_decl) {
-      return D3DERR_INVALIDCALL;
-    } 
-    TRACE_(d3d_shader)("(%p) : freing VertexShaderDeclaration %p\n", This, attached_decl);
-    /* TODO: check validity of object */
-    HeapFree(GetProcessHeap(), 0, (void *)attached_decl->pDeclaration8);
-    HeapFree(GetProcessHeap(), 0, (void *)attached_decl);
-    VertexShaderDeclarations[Handle - VS_HIGHESTFIXEDFXF] = NULL;
 
     return D3D_OK;
 }
 
-HRESULT  WINAPI  IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, CONST void* pConstantData, DWORD ConstantCount) {
-  ICOM_THIS(IDirect3DDevice8Impl,iface);
+static HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, CONST void* pConstantData, DWORD ConstantCount) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) : Relay\n", This);
 
-  if (Register + ConstantCount > D3D8_VSHADER_MAX_CONSTANTS) {
-    ERR_(d3d_shader)("(%p) : SetVertexShaderConstant C[%lu] invalid\n", This, Register);
-    return D3DERR_INVALIDCALL;
-  }
-  if (NULL == pConstantData) {
-    return D3DERR_INVALIDCALL;
-  }
-  if (ConstantCount > 1) {
-    FLOAT* f = (FLOAT*)pConstantData;
-    UINT i;
-    TRACE_(d3d_shader)("(%p) : SetVertexShaderConstant C[%lu..%lu]=\n", This, Register, Register + ConstantCount - 1);
-    for (i = 0; i < ConstantCount; ++i) {
-      TRACE_(d3d_shader)("{%f, %f, %f, %f}\n", f[0], f[1], f[2], f[3]);
-      f += 4;
-    }
-  } else { 
-    FLOAT* f = (FLOAT*) pConstantData;
-    TRACE_(d3d_shader)("(%p) : SetVertexShaderConstant, C[%lu]={%f, %f, %f, %f}\n", This, Register, f[0], f[1], f[2], f[3]);
-  }
-  This->UpdateStateBlock->Changed.vertexShaderConstant = TRUE;
-  memcpy(&This->UpdateStateBlock->vertexShaderConstant[Register], pConstantData, ConstantCount * 4 * sizeof(FLOAT));
-  return D3D_OK;
+    return IWineD3DDevice_SetVertexShaderConstantF(This->WineD3DDevice, Register, (CONST float *)pConstantData, ConstantCount);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_GetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, void* pConstantData, DWORD ConstantCount) {
-  ICOM_THIS(IDirect3DDevice8Impl,iface);
 
-  TRACE_(d3d_shader)("(%p) : C[%lu] count=%ld\n", This, Register, ConstantCount);
-  if (Register + ConstantCount > D3D8_VSHADER_MAX_CONSTANTS) {
-    return D3DERR_INVALIDCALL;
-  }
-  if (NULL == pConstantData) {
-    return D3DERR_INVALIDCALL;
-  }
-  memcpy(pConstantData, &This->UpdateStateBlock->vertexShaderConstant[Register], ConstantCount * 4 * sizeof(FLOAT));
-  return D3D_OK;
+static HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, void* pConstantData, DWORD ConstantCount) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) : Relay\n", This);
+
+    return IWineD3DDevice_GetVertexShaderConstantF(This->WineD3DDevice, Register, (float *)pConstantData, ConstantCount);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_GetVertexShaderDeclaration(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
-  /*ICOM_THIS(IDirect3DDevice8Impl,iface);*/
-  IDirect3DVertexShaderDeclarationImpl* attached_decl;
-  
-  attached_decl = VERTEX_SHADER_DECL(Handle);
-  if (NULL == attached_decl) {
+
+static HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderDeclaration(LPDIRECT3DDEVICE8 iface, DWORD pVertexShader, void* pData, DWORD* pSizeOfData) {
+    IDirect3DVertexShader8Impl *This = (IDirect3DVertexShader8Impl *)pVertexShader;
+
+    TRACE("(%p) : Relay\n", This);
+/*    return IWineD3DVertexShader_GetDeclaration(This->wineD3DVertexShader, pData, (UINT *)pSizeOfData); */
     return D3DERR_INVALIDCALL;
-  }
-  return IDirect3DVertexShaderDeclarationImpl_GetDeclaration8(attached_decl, pData, (UINT*) pSizeOfData);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_GetVertexShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
-  /*ICOM_THIS(IDirect3DDevice8Impl,iface);*/
-  IDirect3DVertexShaderImpl* object;
-  
-  object = VERTEX_SHADER(Handle);
-  if (NULL == object) {
-    return D3DERR_INVALIDCALL;
-  }
-  return IDirect3DVertexShaderImpl_GetFunction(object, pData, (UINT*) pSizeOfData);
+static HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD pVertexShader, void* pData, DWORD* pSizeOfData) {
+    IDirect3DVertexShader8Impl *This = (IDirect3DVertexShader8Impl *)pVertexShader;
+
+    TRACE("(%p) : Relay\n", This);
+    return IWineD3DVertexShader_GetFunction(This->wineD3DVertexShader, pData, (UINT *)pSizeOfData);
 }
 
-HRESULT  WINAPI  IDirect3DDevice8Impl_SetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8* pIndexData, UINT BaseVertexIndex) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    IDirect3DIndexBuffer8 *oldIdxs;
+static HRESULT WINAPI IDirect3DDevice8Impl_SetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8* pIndexData, UINT baseVertexIndex) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n", This);
+/* FIXME: store base vertex index properly */
+    This->baseVertexIndex = baseVertexIndex;
+    return IWineD3DDevice_SetIndices(This->WineD3DDevice,
+                                     NULL == pIndexData ? NULL : ((IDirect3DIndexBuffer8Impl *)pIndexData)->wineD3DIndexBuffer,
+                                     0);
+}
 
-    TRACE("(%p) : Setting to %p, base %d\n", This, pIndexData, BaseVertexIndex);
-    oldIdxs = This->StateBlock->pIndexData;
+static HRESULT WINAPI IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8** ppIndexData,UINT* pBaseVertexIndex) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    IWineD3DIndexBuffer *retIndexData = NULL;
+    HRESULT rc = D3D_OK;
+    UINT tmp;
 
-    This->UpdateStateBlock->Changed.Indices = TRUE;
-    This->UpdateStateBlock->Set.Indices = TRUE;
-    This->UpdateStateBlock->pIndexData = pIndexData;
-    This->UpdateStateBlock->baseVertexIndex = BaseVertexIndex;
+    TRACE("(%p) Relay\n", This);
 
-    /* Handle recording of state blocks */
-    if (This->isRecordingState) {
-        TRACE("Recording... not performing anything\n");
-        return D3D_OK;
+    if(ppIndexData == NULL){
+        return D3DERR_INVALIDCALL;
     }
 
-    if (oldIdxs) IDirect3DIndexBuffer8Impl_Release(oldIdxs);
-    if (pIndexData) IDirect3DIndexBuffer8Impl_AddRef(This->StateBlock->pIndexData);
-    return D3D_OK;
+    rc = IWineD3DDevice_GetIndices(This->WineD3DDevice, &retIndexData, &tmp);
+    if (D3D_OK == rc && NULL != retIndexData) {
+        IWineD3DVertexBuffer_GetParent(retIndexData, (IUnknown **)ppIndexData);
+        IWineD3DVertexBuffer_Release(retIndexData);
+    } else {
+        if(rc != D3D_OK)  FIXME("Call to GetIndices failed\n");
+        *ppIndexData = NULL;
+    }
+/* FIXME: store base vertex index properly */
+    *pBaseVertexIndex = This->baseVertexIndex;
+    return rc;
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8** ppIndexData,UINT* pBaseVertexIndex) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    FIXME("(%p) : stub\n", This);
+static HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pFunction, DWORD* ppShader) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    IDirect3DPixelShader8Impl *object;
+    HRESULT hrc = D3D_OK;
 
-    *ppIndexData = This->StateBlock->pIndexData;
-    /* up ref count on ppindexdata */
-    if (*ppIndexData) IDirect3DIndexBuffer8Impl_AddRef(*ppIndexData);
-    *pBaseVertexIndex = This->StateBlock->baseVertexIndex;
+    TRACE("(%p) : pFunction(%p), ppShader(%p)\n", This, pFunction, ppShader);
 
-    return D3D_OK;
-}
-HRESULT  WINAPI  IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pFunction, DWORD* pHandle) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    IDirect3DPixelShaderImpl* object;
-    HRESULT res;
-    UINT i;
-
-    TRACE_(d3d_shader)("(%p) : PixelShader not fully supported yet : Func=%p\n", This, pFunction);
-    if (NULL == pFunction || NULL == pHandle) {
-      return D3DERR_INVALIDCALL;
+    if (NULL == ppShader) {
+        TRACE("(%p) Invalid call\n", This);
+        return D3DERR_INVALIDCALL;
     }
-    for (i = 1; NULL != PixelShaders[i] && i < sizeof(PixelShaders) / sizeof(IDirect3DPixelShaderImpl*); ++i) ;
-    if (i >= sizeof(PixelShaders) / sizeof(IDirect3DPixelShaderImpl*)) {
-      return D3DERR_OUTOFVIDEOMEMORY;
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+
+    if (NULL == object) {
+        return E_OUTOFMEMORY;
+    } else {
+
+        object->ref    = 1;
+        object->lpVtbl = &Direct3DPixelShader8_Vtbl;
+        hrc = IWineD3DDevice_CreatePixelShader(This->WineD3DDevice, pFunction, &object->wineD3DPixelShader , (IUnknown *)object);
+        if (D3D_OK != hrc) {
+            FIXME("(%p) call to IWineD3DDevice_CreatePixelShader failed\n", This);
+            HeapFree(GetProcessHeap(), 0 , object);
+            *ppShader = 0;
+        } else {
+            shader_handle *handle = alloc_shader_handle(This);
+            if (!handle) {
+                ERR("Failed to allocate shader handle\n");
+                IDirect3DVertexShader8_Release((IUnknown *)object);
+                hrc = E_OUTOFMEMORY;
+            } else {
+                object->handle = handle;
+                *handle = object;
+                *ppShader = (handle - This->shader_handles) + VS_HIGHESTFIXEDFXF + 1;
+            }
+        }
+
     }
 
-    /** Create the Pixel Shader */
-    res = IDirect3DDeviceImpl_CreatePixelShader(This, pFunction, &object);
-    if (SUCCEEDED(res)) {
-      PixelShaders[i] = object;
-      *pHandle = VS_HIGHESTFIXEDFXF + i;
-      return D3D_OK;
-    } 
-    *pHandle = 0xFFFFFFFF;
-    return res;
+    TRACE("(%p) : returning %p (handle %#lx)\n", This, object, *ppShader);
+    return hrc;
+}
+
+static HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD pShader) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    IDirect3DPixelShader8Impl *shader = NULL;
+
+    TRACE("(%p) : pShader %#lx\n", This, pShader);
+
+    if (pShader > VS_HIGHESTFIXEDFXF && This->allocated_shader_handles > pShader - (VS_HIGHESTFIXEDFXF + 1)) {
+        shader = This->shader_handles[pShader - (VS_HIGHESTFIXEDFXF + 1)];
+    } else if (pShader) {
+        ERR("Trying to set an invalid handle.\n");
+    }
+
+    TRACE("(%p) : Setting shader %p\n", This, shader);
+    return IWineD3DDevice_SetPixelShader(This->WineD3DDevice, shader == NULL ? NULL :shader->wineD3DPixelShader);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_SetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
 
-    This->UpdateStateBlock->PixelShader = Handle;
-    This->UpdateStateBlock->Changed.pixelShader = TRUE;
-    This->UpdateStateBlock->Set.pixelShader = TRUE;
+static HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD* ppShader) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    IWineD3DPixelShader *object;
 
-    /* Handle recording of state blocks */
-    if (This->isRecordingState) {
-        TRACE_(d3d_shader)("Recording... not performing anything\n");
-        return D3D_OK;
+    HRESULT hrc = D3D_OK;
+    TRACE("(%p) Relay\n", This);
+    if (NULL == ppShader) {
+        TRACE("(%p) Invalid call\n", This);
+        return D3DERR_INVALIDCALL;
     }
 
-    /* FIXME: Quieten when not being used */
-    if (Handle != 0) {
-      FIXME_(d3d_shader)("(%p) : stub %ld\n", This, Handle);
+    hrc = IWineD3DDevice_GetPixelShader(This->WineD3DDevice, &object);
+    if (D3D_OK == hrc && NULL != object) {
+        IDirect3DPixelShader8Impl *d3d8_shader;
+        hrc = IWineD3DPixelShader_GetParent(object, (IUnknown **)&d3d8_shader);
+        IWineD3DPixelShader_Release(object);
+        *ppShader = (d3d8_shader->handle - This->shader_handles) + (VS_HIGHESTFIXEDFXF + 1);
     } else {
-      TRACE_(d3d_shader)("(%p) : stub %ld\n", This, Handle);
+        *ppShader = (DWORD)NULL;
     }
 
-    return D3D_OK;
-}
-HRESULT  WINAPI  IDirect3DDevice8Impl_GetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    TRACE_(d3d_shader)("(%p) : GetPixelShader returning %ld\n", This, This->StateBlock->PixelShader);
-    *pHandle = This->StateBlock->PixelShader;
-    return D3D_OK;
+    TRACE("(%p) : returning %#lx\n", This, *ppShader);
+    return hrc;
 }
 
-HRESULT  WINAPI  IDirect3DDevice8Impl_DeletePixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    IDirect3DPixelShaderImpl* object;   
+static HRESULT WINAPI IDirect3DDevice8Impl_DeletePixelShader(LPDIRECT3DDEVICE8 iface, DWORD pShader) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
 
-    if (Handle <= VS_HIGHESTFIXEDFXF) { /* only delete user defined shaders */
-      return D3DERR_INVALIDCALL;
+    TRACE("(%p) : pShader %#lx\n", This, pShader);
+
+    if (pShader <= VS_HIGHESTFIXEDFXF || This->allocated_shader_handles <= pShader - (VS_HIGHESTFIXEDFXF + 1)) {
+        ERR("(%p) : Trying to delete an invalid handle\n", This);
+        return D3DERR_INVALIDCALL;
+    } else {
+        shader_handle *handle = &This->shader_handles[pShader - (VS_HIGHESTFIXEDFXF + 1)];
+        IDirect3DPixelShader8Impl *shader = *handle;
+        while(IUnknown_Release((IUnknown *)shader));
+        free_shader_handle(This, handle);
     }
-    object = PixelShaders[Handle - VS_HIGHESTFIXEDFXF];
-    TRACE_(d3d_shader)("(%p) : freeing PixelShader %p\n", This, object);
-    /* TODO: check validity of object before free */
-    if (NULL != object->function) HeapFree(GetProcessHeap(), 0, (void *)object->function);
-    HeapFree(GetProcessHeap(), 0, (void *)object->data);
-    HeapFree(GetProcessHeap(), 0, (void *)object);
-    PixelShaders[Handle - VS_HIGHESTFIXEDFXF] = NULL;
 
     return D3D_OK;
 }
 
-HRESULT  WINAPI  IDirect3DDevice8Impl_SetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, CONST void* pConstantData, DWORD ConstantCount) {
-  ICOM_THIS(IDirect3DDevice8Impl,iface);
+static HRESULT  WINAPI  IDirect3DDevice8Impl_SetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, CONST void* pConstantData, DWORD ConstantCount) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n", This);
 
-  if (Register + ConstantCount > D3D8_PSHADER_MAX_CONSTANTS) {
-    ERR_(d3d_shader)("(%p) : SetPixelShaderConstant C[%lu] invalid\n", This, Register);
-    return D3DERR_INVALIDCALL;
-  }
-  if (NULL == pConstantData) {
-    return D3DERR_INVALIDCALL;
-  }
-  if (ConstantCount > 1) {
-    FLOAT* f = (FLOAT*)pConstantData;
-    UINT i;
-    TRACE_(d3d_shader)("(%p) : SetPixelShaderConstant C[%lu..%lu]=\n", This, Register, Register + ConstantCount - 1);
-    for (i = 0; i < ConstantCount; ++i) {
-      TRACE_(d3d_shader)("{%f, %f, %f, %f}\n", f[0], f[1], f[2], f[3]);
-      f += 4;
-    }
-  } else { 
-    FLOAT* f = (FLOAT*) pConstantData;
-    TRACE_(d3d_shader)("(%p) : SetPixelShaderConstant, C[%lu]={%f, %f, %f, %f}\n", This, Register, f[0], f[1], f[2], f[3]);
-  }
-  This->UpdateStateBlock->Changed.pixelShaderConstant = TRUE;
-  memcpy(&This->UpdateStateBlock->pixelShaderConstant[Register], pConstantData, ConstantCount * 4 * sizeof(FLOAT));
-  return D3D_OK;
+    return IWineD3DDevice_SetPixelShaderConstantF(This->WineD3DDevice, Register, (CONST float *)pConstantData, ConstantCount);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_GetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, void* pConstantData, DWORD ConstantCount) {
-  ICOM_THIS(IDirect3DDevice8Impl,iface);
 
-  TRACE_(d3d_shader)("(%p) : C[%lu] count=%ld\n", This, Register, ConstantCount);
-  if (Register + ConstantCount > D3D8_PSHADER_MAX_CONSTANTS) {
-    return D3DERR_INVALIDCALL;
-  }
-  if (NULL == pConstantData) {
-    return D3DERR_INVALIDCALL;
-  }
-  memcpy(pConstantData, &This->UpdateStateBlock->pixelShaderConstant[Register], ConstantCount * 4 * sizeof(FLOAT));
-  return D3D_OK;
+static HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, void* pConstantData, DWORD ConstantCount) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n", This);
+
+    return IWineD3DDevice_GetPixelShaderConstantF(This->WineD3DDevice, Register, (float *)pConstantData, ConstantCount);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_GetPixelShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
-    IDirect3DPixelShaderImpl* object;
 
-    object = PIXEL_SHADER(Handle);
-    if (NULL == object) {
-      return D3DERR_INVALIDCALL;
-    } 
-    return IDirect3DPixelShaderImpl_GetFunction(object, pData, (UINT*) pSizeOfData);
+static HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD pPixelShader, void* pData, DWORD* pSizeOfData) {
+    IDirect3DPixelShader8Impl *This = (IDirect3DPixelShader8Impl *)pPixelShader;
+
+    TRACE("(%p) : Relay\n", This);
+    return IWineD3DPixelShader_GetFunction(This->wineD3DPixelShader, pData, (UINT *)pSizeOfData);
+}
+
+static HRESULT WINAPI IDirect3DDevice8Impl_DrawRectPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n", This);
+
+    return IWineD3DDevice_DrawRectPatch(This->WineD3DDevice, Handle, pNumSegs, (WINED3DRECTPATCH_INFO *)pRectPatchInfo);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_DrawRectPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    FIXME("(%p) : stub\n", This);    return D3D_OK;
+
+static HRESULT WINAPI IDirect3DDevice8Impl_DrawTriPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DTRIPATCH_INFO* pTriPatchInfo) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n", This);
+
+    return IWineD3DDevice_DrawTriPatch(This->WineD3DDevice, Handle, pNumSegs, (WINED3DTRIPATCH_INFO *)pTriPatchInfo);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_DrawTriPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DTRIPATCH_INFO* pTriPatchInfo) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    FIXME("(%p) : stub\n", This);    return D3D_OK;
+
+static HRESULT WINAPI IDirect3DDevice8Impl_DeletePatch(LPDIRECT3DDEVICE8 iface, UINT Handle) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n", This);
+
+    return IWineD3DDevice_DeletePatch(This->WineD3DDevice, Handle);
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_DeletePatch(LPDIRECT3DDEVICE8 iface, UINT Handle) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    FIXME("(%p) : stub\n", This);    return D3D_OK;
+
+static HRESULT WINAPI IDirect3DDevice8Impl_SetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8* pStreamData,UINT Stride) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    TRACE("(%p) Relay\n" , This);
+
+    return IWineD3DDevice_SetStreamSource(This->WineD3DDevice, StreamNumber,
+                                          NULL == pStreamData ? NULL : ((IDirect3DVertexBuffer8Impl *)pStreamData)->wineD3DVertexBuffer,
+                                          0/* Offset in bytes */, Stride);
 }
 
-HRESULT  WINAPI  IDirect3DDevice8Impl_SetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8* pStreamData,UINT Stride) {
-    IDirect3DVertexBuffer8 *oldSrc;
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
+static HRESULT WINAPI IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8** pStream,UINT* pStride) {
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    IWineD3DVertexBuffer *retStream = NULL;
+    HRESULT rc = D3D_OK;
 
-    oldSrc = This->StateBlock->stream_source[StreamNumber];
-    TRACE("(%p) : StreamNo: %d, OldStream (%p), NewStream (%p), NewStride %d\n", This, StreamNumber, oldSrc, pStreamData, Stride);
+    TRACE("(%p) Relay\n" , This);
 
-    This->UpdateStateBlock->Changed.stream_source[StreamNumber] = TRUE;
-    This->UpdateStateBlock->Set.stream_source[StreamNumber] = TRUE;
-    This->UpdateStateBlock->stream_stride[StreamNumber] = Stride;
-    This->UpdateStateBlock->stream_source[StreamNumber] = pStreamData;
+    if(pStream == NULL){
+        return D3DERR_INVALIDCALL;
+    }
 
-    /* Handle recording of state blocks */
-    if (This->isRecordingState) {
-        TRACE("Recording... not performing anything\n");
-        return D3D_OK;
+    rc = IWineD3DDevice_GetStreamSource(This->WineD3DDevice, StreamNumber, (IWineD3DVertexBuffer **)&retStream, 0 /* Offset in bytes */, pStride);
+    if (rc == D3D_OK  && NULL != retStream) {
+        IWineD3DVertexBuffer_GetParent(retStream, (IUnknown **)pStream);
+        IWineD3DVertexBuffer_Release(retStream);
+    }else{
+         FIXME("Call to GetStreamSource failed %p\n",  pStride);
+        *pStream = NULL;
     }
 
-    if (oldSrc != NULL) IDirect3DVertexBuffer8Impl_Release(oldSrc);
-    if (pStreamData != NULL) IDirect3DVertexBuffer8Impl_AddRef(pStreamData);
-    return D3D_OK;
-}
-HRESULT  WINAPI  IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8** pStream,UINT* pStride) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    TRACE("(%p) : StreamNo: %d, Stream (%p), Stride %d\n", This, StreamNumber, This->StateBlock->stream_source[StreamNumber], This->StateBlock->stream_stride[StreamNumber]);
-    *pStream = This->StateBlock->stream_source[StreamNumber];
-    *pStride = This->StateBlock->stream_stride[StreamNumber];
-    IDirect3DVertexBuffer8Impl_AddRef((LPDIRECT3DVERTEXBUFFER8) *pStream);
-    return D3D_OK;
+    return rc;
 }
 
 
-ICOM_VTABLE(IDirect3DDevice8) Direct3DDevice8_Vtbl =
+const IDirect3DDevice8Vtbl Direct3DDevice8_Vtbl =
 {
-    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
     IDirect3DDevice8Impl_QueryInterface,
     IDirect3DDevice8Impl_AddRef,
     IDirect3DDevice8Impl_Release,
@@ -4175,239 +1536,27 @@ ICOM_VTABLE(IDirect3DDevice8) Direct3DDevice8_Vtbl =
     IDirect3DDevice8Impl_DeletePatch
 };
 
-HRESULT WINAPI IDirect3DDevice8Impl_CleanRender(LPDIRECT3DDEVICE8 iface)
-{
-#if defined(GL_VERSION_1_3) /* @see comments on ActiveRender */
-  ICOM_THIS(IDirect3DDevice8Impl,iface);
-
-  ENTER_GL();
-
-#if 0
-  if (This->glCtx != This->render_ctx) {
-    glXDestroyContext(This->display, This->render_ctx);
-    This->render_ctx = This->glCtx;
-  }
-#endif
-  if (This->win != This->drawable) {
-    glXDestroyPbuffer(This->display, This->drawable);
-    This->drawable = This->win;
-  }
-
-  LEAVE_GL();
-
-#endif
-  return D3D_OK;
-}
-
-HRESULT WINAPI IDirect3DDevice8Impl_ActiveRender(LPDIRECT3DDEVICE8 iface,
-                                               IDirect3DSurface8* RenderSurface, 
-                                               IDirect3DSurface8* StencilSurface) {
-
-  HRESULT ret =  D3DERR_INVALIDCALL; 
-  /**
-   * Currently only active for GLX >= 1.3
-   * for others versions we'll have to use GLXPixmaps
-   *
-   * normally we must test GLX_VERSION_1_3 but nvidia headers are not correct
-   * as they implements GLX 1.3 but only define GLX_VERSION_1_2
-   * so only check OpenGL version
-   */
-#if defined(GL_VERSION_1_3) 
-  GLXFBConfig* cfgs = NULL;
-  int nCfgs = 0;
-  int attribs[256];
-  int nAttribs = 0;
-  D3DFORMAT BackBufferFormat = ((IDirect3DSurface8Impl*) RenderSurface)->myDesc.Format;
-  D3DFORMAT StencilBufferFormat = (NULL != StencilSurface) ? ((IDirect3DSurface8Impl*) StencilSurface)->myDesc.Format : 0;
-  UINT Width = ((IDirect3DSurface8Impl*) RenderSurface)->myDesc.Width;
-  UINT Height = ((IDirect3DSurface8Impl*) RenderSurface)->myDesc.Height;
-  IDirect3DSurface8Impl* tmp;
-
-  ICOM_THIS(IDirect3DDevice8Impl,iface);
-#define PUSH1(att)        attribs[nAttribs++] = (att); 
-#define PUSH2(att,value)  attribs[nAttribs++] = (att); attribs[nAttribs++] = (value);
-
-  PUSH2(GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT | GLX_WINDOW | GLX_PBUFFER_BIT);
-  PUSH2(GLX_X_RENDERABLE,  TRUE);
-  PUSH2(GLX_DOUBLEBUFFER, TRUE);
-  
-  switch (BackBufferFormat) {
-    /* color buffer */
-  case D3DFMT_P8:
-    PUSH2(GLX_RENDER_TYPE,  GLX_COLOR_INDEX_BIT);
-    PUSH2(GLX_BUFFER_SIZE,  8);
-    PUSH2(GLX_DOUBLEBUFFER, TRUE);
-    break;
-    
-  case D3DFMT_R3G3B2:
-    PUSH2(GLX_RENDER_TYPE,  GLX_RGBA_BIT);
-    PUSH2(GLX_RED_SIZE,     3);
-    PUSH2(GLX_GREEN_SIZE,   3);
-    PUSH2(GLX_BLUE_SIZE,    2);
-    break;
-    
-  case D3DFMT_A1R5G5B5:
-    PUSH2(GLX_ALPHA_SIZE,   1);
-  case D3DFMT_X1R5G5B5:
-    PUSH2(GLX_RED_SIZE,     5);
-    PUSH2(GLX_GREEN_SIZE,   5);
-    PUSH2(GLX_BLUE_SIZE,    5);
-    break;
-    
-  case D3DFMT_R5G6B5:
-    PUSH2(GLX_RED_SIZE,     5);
-    PUSH2(GLX_GREEN_SIZE,   6);
-    PUSH2(GLX_BLUE_SIZE,    5);
-    break;
-    
-  case D3DFMT_A4R4G4B4:
-    PUSH2(GLX_ALPHA_SIZE,   4);
-  case D3DFMT_X4R4G4B4:
-    PUSH2(GLX_RED_SIZE,     4);
-    PUSH2(GLX_GREEN_SIZE,   4);
-    PUSH2(GLX_BLUE_SIZE,    4);
-    break;
-    
-  case D3DFMT_A8R8G8B8:
-    PUSH2(GLX_ALPHA_SIZE,   8);
-  case D3DFMT_R8G8B8:
-  case D3DFMT_X8R8G8B8:
-    PUSH2(GLX_RED_SIZE,     8);
-    PUSH2(GLX_GREEN_SIZE,   8);
-    PUSH2(GLX_BLUE_SIZE,    8);
-    break;
-
-  default:
-    break;
-  }
-   
-  switch (StencilBufferFormat) { 
-  case D3DFMT_D16_LOCKABLE:
-  case D3DFMT_D16:
-    PUSH2(GLX_DEPTH_SIZE,   16);
-    break;
-    
-  case D3DFMT_D15S1:
-    PUSH2(GLX_DEPTH_SIZE,   15);
-    break;
-    
-  case D3DFMT_D24X8:
-    PUSH2(GLX_DEPTH_SIZE,   24);
-    break;
-    
-  case D3DFMT_D24X4S4:
-    PUSH2(GLX_DEPTH_SIZE,   24);
-    PUSH2(GLX_STENCIL_SIZE, 4);
-    break;
-    
-  case D3DFMT_D24S8:
-    PUSH2(GLX_DEPTH_SIZE,   24);
-    PUSH2(GLX_STENCIL_SIZE, 8);
-    break;
-    
-  case D3DFMT_D32:
-    PUSH2(GLX_DEPTH_SIZE,   32);
-    break;
-
-  default:
-    break;
-  }
-
-  PUSH1(None);
-  
-  ENTER_GL();
-
-  cfgs = glXChooseFBConfig(This->display, DefaultScreen(This->display), attribs, &nCfgs);
-  if (NULL != cfgs) {
-#if 0
-    int i;
-    for (i = 0; i < nCfgs; ++i) {
-      TRACE("for (%u,%s)/(%u,%s) found config[%d]@%p\n", BackBufferFormat, debug_d3dformat(BackBufferFormat), StencilBufferFormat, debug_d3dformat(StencilBufferFormat), i, cfgs[i]);
-    }
-#endif
-
-    if (NULL != This->renderTarget) {
-      GLenum prev_read;      
-      glFlush();
-      vcheckGLcall("glFlush");
-
-#if 0
-      /** very very usefull debug code */
-      glXSwapBuffers(This->display, This->drawable);   
-      printf("Hit Enter to get next frame ...\n");
-      getchar();
-#endif
-
-      glGetIntegerv(GL_READ_BUFFER, &prev_read);
-      vcheckGLcall("glIntegerv");
-      glReadBuffer(GL_BACK);
-      vcheckGLcall("glReadBuffer");
-      {
-       long j;
-       long pitch = This->renderTarget->myDesc.Width * This->renderTarget->bytesPerPixel;
-
-        if (This->renderTarget->myDesc.Format == D3DFMT_DXT1) /* DXT1 is half byte per pixel */
-            pitch = pitch / 2;
-
-       for (j = 0; j < This->renderTarget->myDesc.Height; ++j) {
-         glReadPixels(0, 
-                      This->renderTarget->myDesc.Height - j - 1, 
-                      This->renderTarget->myDesc.Width, 
-                      1,
-                      D3DFmt2GLFmt(This, This->renderTarget->myDesc.Format), 
-                      D3DFmt2GLType(This, This->renderTarget->myDesc.Format), 
-                      This->renderTarget->allocatedMemory + j * pitch);
-         vcheckGLcall("glReadPixels");
-       }
-      }      
-      glReadBuffer(prev_read);
-      vcheckGLcall("glReadBuffer");
-    }
-
-    if (BackBufferFormat != This->renderTarget->myDesc.Format && 
-       StencilBufferFormat != This->stencilBufferTarget->myDesc.Format) {
-      nAttribs = 0;
-      PUSH2(GLX_PBUFFER_WIDTH,  Width);
-      PUSH2(GLX_PBUFFER_HEIGHT, Height);
-      PUSH1(None);
-      This->drawable = glXCreatePbuffer(This->display, cfgs[0], attribs);
-            
-      This->render_ctx = glXCreateNewContext(This->display, cfgs[0], GLX_RGBA_TYPE, This->glCtx, TRUE);
-      if (NULL == This->render_ctx) {
-       ERR("cannot create glxContext\n"); 
-      }
-
-      glFlush();
-      glXSwapBuffers(This->display, This->drawable);
-      if (glXMakeContextCurrent(This->display, This->drawable, This->drawable, This->render_ctx) == False) {
-       TRACE("Error in setting current context: context %p drawable %ld (default %ld)!\n", This->glCtx, This->drawable, This->win);
-      }
-      checkGLcall("glXMakeContextCurrent");
-    }
-
-    tmp = This->renderTarget;
-    This->renderTarget = (IDirect3DSurface8Impl*) RenderSurface;
-    IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) This->renderTarget);
-    IDirect3DSurface8Impl_Release((LPDIRECT3DSURFACE8) tmp);
-
-    tmp = This->stencilBufferTarget;
-    This->stencilBufferTarget = (IDirect3DSurface8Impl*) StencilSurface;
-    if (NULL != This->stencilBufferTarget) IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) This->stencilBufferTarget);
-    if (NULL != tmp) IDirect3DSurface8Impl_Release((LPDIRECT3DSURFACE8) tmp);
-
-    ret = D3D_OK;
-
-  } else {
-    ERR("cannot get valides GLXFBConfig for (%u,%s)/(%u,%s)\n", BackBufferFormat, debug_d3dformat(BackBufferFormat), StencilBufferFormat, debug_d3dformat(StencilBufferFormat));
-  }
+/* Internal function called back during the CreateDevice to create a render target  */
+HRESULT WINAPI D3D8CB_CreateSurface(IUnknown *device, UINT Width, UINT Height, 
+                                         WINED3DFORMAT Format, DWORD Usage, WINED3DPOOL Pool, UINT Level,
+                                         IWineD3DSurface **ppSurface, HANDLE *pSharedHandle) {
 
-#undef PUSH1
-#undef PUSH2
+    HRESULT res = D3D_OK;
+    IDirect3DSurface8Impl *d3dSurface = NULL;
+    BOOL Lockable = TRUE;
 
-  LEAVE_GL();
+    if((WINED3DPOOL_DEFAULT == Pool && WINED3DUSAGE_DYNAMIC != Usage))
+        Lockable = FALSE;
 
-#endif
+    TRACE("relay\n");
+    res = IDirect3DDevice8Impl_CreateSurface((IDirect3DDevice8 *)device, Width, Height, (D3DFORMAT)Format, Lockable, FALSE/*Discard*/, Level,  (IDirect3DSurface8 **)&d3dSurface, D3DRTYPE_SURFACE, Usage, Pool, D3DMULTISAMPLE_NONE, 0 /* MultisampleQuality */);
 
-  return ret;
+    if (SUCCEEDED(res)) {
+        *ppSurface = d3dSurface->wineD3DSurface;
+        IUnknown_Release(d3dSurface->parentDevice);
+        d3dSurface->parentDevice = NULL;
+    } else {
+        FIXME("(%p) IDirect3DDevice8_CreateSurface failed\n", device);
+    }
+    return res;
 }