- import ddraw from Wine and use it for now
authorKamil Hornicek <kamil.hornicek@reactos.org>
Sun, 5 Apr 2009 13:52:15 +0000 (13:52 +0000)
committerKamil Hornicek <kamil.hornicek@reactos.org>
Sun, 5 Apr 2009 13:52:15 +0000 (13:52 +0000)
- sync wined3d, d3d8, d3d9 with Wine HEAD

svn path=/trunk/; revision=40370

100 files changed:
reactos/dll/directx/directx.rbuild
reactos/dll/directx/wine/d3d8/Makefile.in [deleted file]
reactos/dll/directx/wine/d3d8/basetexture.c [deleted file]
reactos/dll/directx/wine/d3d8/cubetexture.c
reactos/dll/directx/wine/d3d8/d3d8.rbuild
reactos/dll/directx/wine/d3d8/d3d8_private.h
reactos/dll/directx/wine/d3d8/device.c
reactos/dll/directx/wine/d3d8/directx.c
reactos/dll/directx/wine/d3d8/indexbuffer.c
reactos/dll/directx/wine/d3d8/pixelshader.c
reactos/dll/directx/wine/d3d8/resource.c [deleted file]
reactos/dll/directx/wine/d3d8/stateblock.c
reactos/dll/directx/wine/d3d8/surface.c
reactos/dll/directx/wine/d3d8/texture.c
reactos/dll/directx/wine/d3d8/vertexbuffer.c
reactos/dll/directx/wine/d3d8/vertexdeclaration.c
reactos/dll/directx/wine/d3d8/vertexshader.c
reactos/dll/directx/wine/d3d8/volume.c
reactos/dll/directx/wine/d3d8/volumetexture.c
reactos/dll/directx/wine/d3d9/basetexture.c [deleted file]
reactos/dll/directx/wine/d3d9/cubetexture.c
reactos/dll/directx/wine/d3d9/d3d9.rbuild
reactos/dll/directx/wine/d3d9/d3d9_private.h
reactos/dll/directx/wine/d3d9/device.c
reactos/dll/directx/wine/d3d9/directx.c
reactos/dll/directx/wine/d3d9/indexbuffer.c
reactos/dll/directx/wine/d3d9/pixelshader.c
reactos/dll/directx/wine/d3d9/resource.c [deleted file]
reactos/dll/directx/wine/d3d9/stateblock.c
reactos/dll/directx/wine/d3d9/surface.c
reactos/dll/directx/wine/d3d9/swapchain.c
reactos/dll/directx/wine/d3d9/texture.c
reactos/dll/directx/wine/d3d9/vertexbuffer.c
reactos/dll/directx/wine/d3d9/vertexdeclaration.c
reactos/dll/directx/wine/d3d9/volume.c
reactos/dll/directx/wine/d3d9/volumetexture.c
reactos/dll/directx/wine/ddraw/clipper.c [new file with mode: 0644]
reactos/dll/directx/wine/ddraw/ddcomimpl.h [new file with mode: 0644]
reactos/dll/directx/wine/ddraw/ddraw.c [new file with mode: 0644]
reactos/dll/directx/wine/ddraw/ddraw.rbuild [new file with mode: 0644]
reactos/dll/directx/wine/ddraw/ddraw.spec [new file with mode: 0644]
reactos/dll/directx/wine/ddraw/ddraw_private.h [new file with mode: 0644]
reactos/dll/directx/wine/ddraw/ddraw_thunks.c [new file with mode: 0644]
reactos/dll/directx/wine/ddraw/device.c [new file with mode: 0644]
reactos/dll/directx/wine/ddraw/direct3d.c [new file with mode: 0644]
reactos/dll/directx/wine/ddraw/executebuffer.c [new file with mode: 0644]
reactos/dll/directx/wine/ddraw/gamma.c [new file with mode: 0644]
reactos/dll/directx/wine/ddraw/light.c [new file with mode: 0644]
reactos/dll/directx/wine/ddraw/main.c [new file with mode: 0644]
reactos/dll/directx/wine/ddraw/material.c [new file with mode: 0644]
reactos/dll/directx/wine/ddraw/palette.c [new file with mode: 0644]
reactos/dll/directx/wine/ddraw/parent.c [new file with mode: 0644]
reactos/dll/directx/wine/ddraw/regsvr.c [new file with mode: 0644]
reactos/dll/directx/wine/ddraw/surface.c [new file with mode: 0644]
reactos/dll/directx/wine/ddraw/surface_thunks.c [new file with mode: 0644]
reactos/dll/directx/wine/ddraw/texture.c [new file with mode: 0644]
reactos/dll/directx/wine/ddraw/utils.c [new file with mode: 0644]
reactos/dll/directx/wine/ddraw/version.rc [new file with mode: 0644]
reactos/dll/directx/wine/ddraw/vertexbuffer.c [new file with mode: 0644]
reactos/dll/directx/wine/ddraw/viewport.c [new file with mode: 0644]
reactos/dll/directx/wine/wine.rbuild
reactos/dll/directx/wine/wined3d/Makefile.in [deleted file]
reactos/dll/directx/wine/wined3d/arb_program_shader.c
reactos/dll/directx/wine/wined3d/ati_fragment_shader.c
reactos/dll/directx/wine/wined3d/baseshader.c
reactos/dll/directx/wine/wined3d/basetexture.c
reactos/dll/directx/wine/wined3d/buffer.c [new file with mode: 0644]
reactos/dll/directx/wine/wined3d/context.c
reactos/dll/directx/wine/wined3d/cubetexture.c
reactos/dll/directx/wine/wined3d/device.c
reactos/dll/directx/wine/wined3d/directx.c
reactos/dll/directx/wine/wined3d/drawprim.c
reactos/dll/directx/wine/wined3d/glsl_shader.c
reactos/dll/directx/wine/wined3d/indexbuffer.c [deleted file]
reactos/dll/directx/wine/wined3d/nvidia_texture_shader.c
reactos/dll/directx/wine/wined3d/pixelshader.c
reactos/dll/directx/wine/wined3d/resource.c
reactos/dll/directx/wine/wined3d/state.c
reactos/dll/directx/wine/wined3d/stateblock.c
reactos/dll/directx/wine/wined3d/surface.c
reactos/dll/directx/wine/wined3d/surface_base.c
reactos/dll/directx/wine/wined3d/surface_gdi.c
reactos/dll/directx/wine/wined3d/swapchain.c
reactos/dll/directx/wine/wined3d/texture.c
reactos/dll/directx/wine/wined3d/utils.c
reactos/dll/directx/wine/wined3d/vertexbuffer.c [deleted file]
reactos/dll/directx/wine/wined3d/vertexdeclaration.c
reactos/dll/directx/wine/wined3d/vertexshader.c
reactos/dll/directx/wine/wined3d/view.c [new file with mode: 0644]
reactos/dll/directx/wine/wined3d/volume.c
reactos/dll/directx/wine/wined3d/volumetexture.c
reactos/dll/directx/wine/wined3d/wined3d.def [deleted file]
reactos/dll/directx/wine/wined3d/wined3d.rbuild
reactos/dll/directx/wine/wined3d/wined3d_gl.h
reactos/dll/directx/wine/wined3d/wined3d_main.c
reactos/dll/directx/wine/wined3d/wined3d_private.h
reactos/dll/directx/wine/wined3d/wined3d_private_types.h
reactos/include/dxsdk/d3dcaps.h
reactos/include/dxsdk/ddraw.h
reactos/include/reactos/wine/wined3d.idl

index 4cee3b3..a72e51b 100644 (file)
@@ -4,9 +4,6 @@
        <directory name="d3d8thk">
                <xi:include href="d3d8thk/d3d8thk.rbuild" />
        </directory>
-       <directory name="ddraw">
-               <xi:include href="ddraw/ddraw.rbuild" />
-       </directory>
        <directory name="devenum">
                <xi:include href="devenum/devenum.rbuild" />
        </directory>
diff --git a/reactos/dll/directx/wine/d3d8/Makefile.in b/reactos/dll/directx/wine/d3d8/Makefile.in
deleted file mode 100644 (file)
index 11a46fc..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-TOPSRCDIR = @top_srcdir@
-TOPOBJDIR = ../..
-SRCDIR    = @srcdir@
-VPATH     = @srcdir@
-MODULE    = d3d8.dll
-IMPORTLIB = d3d8
-IMPORTS   = dxguid uuid wined3d kernel32
-
-C_SRCS = \
-       basetexture.c \
-       cubetexture.c \
-       d3d8_main.c \
-       device.c \
-       directx.c \
-       indexbuffer.c \
-       pixelshader.c \
-       resource.c \
-       stateblock.c \
-       surface.c \
-       swapchain.c \
-       texture.c \
-       vertexbuffer.c \
-       vertexdeclaration.c \
-       vertexshader.c \
-       volume.c \
-       volumetexture.c
-
-RC_SRCS = version.rc
-
-@MAKE_DLL_RULES@
-
-@DEPENDENCIES@  # everything below this line is overwritten by make depend
diff --git a/reactos/dll/directx/wine/d3d8/basetexture.c b/reactos/dll/directx/wine/d3d8/basetexture.c
deleted file mode 100644 (file)
index 122c22d..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * IDirect3DBaseTexture8 implementation
- *
- * Copyright 2005 Oliver Stieber
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-#include "d3d8_private.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
-
-/* IDirect3DBaseTexture8 IUnknown parts follow: */
-static HRESULT WINAPI IDirect3DBaseTexture8Impl_QueryInterface(LPDIRECT3DBASETEXTURE8 iface, REFIID riid, LPVOID *ppobj) {
-    IDirect3DBaseTexture8Impl *This = (IDirect3DBaseTexture8Impl *)iface;
-    TRACE("(%p) Relay\n" , This);
-    if (IsEqualGUID(riid, &IID_IUnknown)
-        || IsEqualGUID(riid, &IID_IDirect3DResource8)
-        || IsEqualGUID(riid, &IID_IDirect3DBaseTexture8)) {
-        IUnknown_AddRef(iface);
-        *ppobj = This;
-        return S_OK;
-    }
-
-    WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
-
-    *ppobj = NULL;
-    return E_NOINTERFACE;
-}
-
-static ULONG WINAPI IDirect3DBaseTexture8Impl_AddRef(LPDIRECT3DBASETEXTURE8 iface) {
-    IDirect3DBaseTexture8Impl *This = (IDirect3DBaseTexture8Impl *)iface;
-    ULONG ref = InterlockedIncrement(&This->ref);
-
-    TRACE("(%p) : AddRef from %d\n", This, ref - 1);
-
-    return ref;
-}
-
-static ULONG WINAPI IDirect3DBaseTexture8Impl_Release(LPDIRECT3DBASETEXTURE8 iface) {
-    IDirect3DBaseTexture8Impl *This = (IDirect3DBaseTexture8Impl *)iface;
-    ULONG ref = InterlockedDecrement(&This->ref);
-
-    TRACE("(%p) : ReleaseRef to %d\n", This, ref);
-
-    if (ref == 0) {
-        IWineD3DBaseTexture_Release(This->wineD3DBaseTexture);
-        HeapFree(GetProcessHeap(), 0, This);
-    }
-
-    return ref;
-}
-
-/* IDirect3DBaseTexture8 IDirect3DResource8 Interface follow: */
-static HRESULT WINAPI IDirect3DBaseTexture8Impl_GetDevice(LPDIRECT3DBASETEXTURE8 iface, IDirect3DDevice8 **ppDevice) {
-    IDirect3DBaseTexture8Impl *This = (IDirect3DBaseTexture8Impl *)iface;
-    TRACE("(%p) Relay\n" , This);
-
-    return IDirect3DResource8Impl_GetDevice((LPDIRECT3DRESOURCE8) This, ppDevice);
-}
-
-static HRESULT WINAPI IDirect3DBaseTexture8Impl_SetPrivateData(LPDIRECT3DBASETEXTURE8 iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
-    IDirect3DBaseTexture8Impl *This = (IDirect3DBaseTexture8Impl *)iface;
-    TRACE("(%p) Relay\n" , This);
-
-    return IWineD3DBaseTexture_SetPrivateData(This->wineD3DBaseTexture, refguid, pData, SizeOfData, Flags);
-}
-
-static HRESULT WINAPI IDirect3DBaseTexture8Impl_GetPrivateData(LPDIRECT3DBASETEXTURE8 iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) {
-    IDirect3DBaseTexture8Impl *This = (IDirect3DBaseTexture8Impl *)iface;
-    TRACE("(%p) Relay\n" , This);
-
-    return IWineD3DBaseTexture_GetPrivateData(This->wineD3DBaseTexture, refguid, pData, pSizeOfData);
-}
-
-static HRESULT WINAPI IDirect3DBaseTexture8Impl_FreePrivateData(LPDIRECT3DBASETEXTURE8 iface, REFGUID refguid) {
-    IDirect3DBaseTexture8Impl *This = (IDirect3DBaseTexture8Impl *)iface;
-    TRACE("(%p) Relay\n" , This);
-
-    return IWineD3DBaseTexture_FreePrivateData(This->wineD3DBaseTexture, refguid);
-}
-
-static DWORD WINAPI IDirect3DBaseTexture8Impl_SetPriority(LPDIRECT3DBASETEXTURE8 iface, DWORD PriorityNew) {
-    IDirect3DBaseTexture8Impl *This = (IDirect3DBaseTexture8Impl *)iface;
-    TRACE("(%p) Relay\n" , This);
-
-    return IWineD3DBaseTexture_SetPriority(This->wineD3DBaseTexture, PriorityNew);
-}
-
-static DWORD WINAPI IDirect3DBaseTexture8Impl_GetPriority(LPDIRECT3DBASETEXTURE8 iface) {
-    IDirect3DBaseTexture8Impl *This = (IDirect3DBaseTexture8Impl *)iface;
-    TRACE("(%p) Relay\n" , This);
-
-    return IWineD3DBaseTexture_GetPriority(This->wineD3DBaseTexture);
-}
-
-static void WINAPI IDirect3DBaseTexture8Impl_PreLoad(LPDIRECT3DBASETEXTURE8 iface) {
-    IDirect3DBaseTexture8Impl *This = (IDirect3DBaseTexture8Impl *)iface;
-    TRACE("(%p) Relay\n" , This);
-
-    IWineD3DBaseTexture_PreLoad(This->wineD3DBaseTexture);
-    return;
-}
-
-static D3DRESOURCETYPE WINAPI IDirect3DBaseTexture8Impl_GetType(LPDIRECT3DBASETEXTURE8 iface) {
-    IDirect3DBaseTexture8Impl *This = (IDirect3DBaseTexture8Impl *)iface;
-    TRACE("(%p) Relay\n" , This);
-
-    return IWineD3DBaseTexture_GetType(This->wineD3DBaseTexture);
-}
-
-/* IDirect3DBaseTexture8 Interface follow: */
-static DWORD WINAPI IDirect3DBaseTexture8Impl_SetLOD(LPDIRECT3DBASETEXTURE8 iface, DWORD LODNew) {
-    IDirect3DBaseTexture8Impl *This = (IDirect3DBaseTexture8Impl *)iface;
-    TRACE("(%p) Relay\n" , This);
-
-    return IWineD3DBaseTexture_SetLOD(This->wineD3DBaseTexture, LODNew);
-}
-
-static DWORD WINAPI IDirect3DBaseTexture8Impl_GetLOD(LPDIRECT3DBASETEXTURE8 iface) {
-    IDirect3DBaseTexture8Impl *This = (IDirect3DBaseTexture8Impl *)iface;
-    TRACE("(%p) Relay\n" , This);
-
-    return IWineD3DBaseTexture_GetLOD(This->wineD3DBaseTexture);
-}
-
-static DWORD WINAPI IDirect3DBaseTexture8Impl_GetLevelCount(LPDIRECT3DBASETEXTURE8 iface) {
-    IDirect3DBaseTexture8Impl *This = (IDirect3DBaseTexture8Impl *)iface;
-    TRACE("(%p) Relay\n" , This);
-
-    return IWineD3DBaseTexture_GetLevelCount(This->wineD3DBaseTexture);
-}
-
-const IDirect3DBaseTexture8Vtbl Direct3DBaseTexture8_Vtbl =
-{
-    IDirect3DBaseTexture8Impl_QueryInterface,
-    IDirect3DBaseTexture8Impl_AddRef,
-    IDirect3DBaseTexture8Impl_Release,
-    IDirect3DBaseTexture8Impl_GetDevice,
-    IDirect3DBaseTexture8Impl_SetPrivateData,
-    IDirect3DBaseTexture8Impl_GetPrivateData,
-    IDirect3DBaseTexture8Impl_FreePrivateData,
-    IDirect3DBaseTexture8Impl_SetPriority,
-    IDirect3DBaseTexture8Impl_GetPriority,
-    IDirect3DBaseTexture8Impl_PreLoad,
-    IDirect3DBaseTexture8Impl_GetType,
-
-    IDirect3DBaseTexture8Impl_SetLOD,
-    IDirect3DBaseTexture8Impl_GetLOD,
-    IDirect3DBaseTexture8Impl_GetLevelCount
-};
index ae343bb..32511d6 100644 (file)
@@ -69,11 +69,17 @@ static ULONG WINAPI IDirect3DCubeTexture8Impl_Release(LPDIRECT3DCUBETEXTURE8 ifa
 /* IDirect3DCubeTexture8 IDirect3DResource8 Interface follow: */
 static HRESULT WINAPI IDirect3DCubeTexture8Impl_GetDevice(LPDIRECT3DCUBETEXTURE8 iface, IDirect3DDevice8 **ppDevice) {
     IDirect3DCubeTexture8Impl *This = (IDirect3DCubeTexture8Impl *)iface;
+    IWineD3DDevice *wined3d_device;
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IDirect3DResource8Impl_GetDevice((LPDIRECT3DRESOURCE8) This, ppDevice);
+    hr = IWineD3DCubeTexture_GetDevice(This->wineD3DCubeTexture, &wined3d_device);
+    if (SUCCEEDED(hr))
+    {
+        IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
+        IWineD3DDevice_Release(wined3d_device);
+    }
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
@@ -209,6 +215,9 @@ static HRESULT WINAPI IDirect3DCubeTexture8Impl_GetLevelDesc(LPDIRECT3DCUBETEXTU
     EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DCubeTexture_GetLevelDesc(This->wineD3DCubeTexture, Level, &wined3ddesc);
     LeaveCriticalSection(&d3d8_cs);
+
+    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(pDesc->Format);
+
     return hr;
 }
 
index 13ccdac..dcece7b 100644 (file)
        <library>uuid</library>
        <library>wine</library>
        <library>user32</library>
-       <library>opengl32</library>
        <library>gdi32</library>
        <library>advapi32</library>
-       <library>kernel32</library>
        <library>wined3d</library>
 
-       <file>basetexture.c</file>
        <file>cubetexture.c</file>
        <file>d3d8_main.c</file>
        <file>device.c</file>
        <file>directx.c</file>
        <file>indexbuffer.c</file>
        <file>pixelshader.c</file>
-       <file>resource.c</file>
        <file>stateblock.c</file>
        <file>surface.c</file>
        <file>swapchain.c</file>
index 98d5c7f..cbd6f76 100644 (file)
@@ -35,9 +35,6 @@
 #include "d3d8.h"
 #include "wine/wined3d.h"
 
-/* Device caps */
-#define INITIAL_SHADER_HANDLE_TABLE_SIZE        64
-
 /* CreateVertexShader can return > 0xFFFF */
 #define VS_HIGHESTFIXEDFXF 0xF0000000
 
@@ -166,7 +163,16 @@ extern const IWineD3DDeviceParentVtbl d3d8_wined3d_device_parent_vtbl;
  * IDirect3DDevice8 implementation structure
  */
 
-typedef void * shader_handle;
+#define D3D8_INITIAL_HANDLE_TABLE_SIZE 64
+#define D3D8_INVALID_HANDLE ~0U
+
+struct d3d8_handle_table
+{
+    void **entries;
+    void **free_entries;
+    UINT table_size;
+    UINT entry_count;
+};
 
 struct FvfToDecl
 {
@@ -182,10 +188,7 @@ struct IDirect3DDevice8Impl
     LONG                         ref;
 /* But what about baseVertexIndex in state blocks? hmm... it may be a better idea to pass this to wined3d */
     IWineD3DDevice               *WineD3DDevice;
-    DWORD                         shader_handle_table_size;
-    DWORD                         allocated_shader_handles;
-    shader_handle                *shader_handles;
-    shader_handle                *free_shader_handles;
+    struct d3d8_handle_table handle_table;
 
     /* FVF management */
     struct FvfToDecl       *decls;
@@ -299,7 +302,6 @@ struct IDirect3DResource8Impl
     /* IDirect3DResource8 fields */
     IWineD3DResource             *wineD3DResource;
 };
-extern HRESULT WINAPI IDirect3DResource8Impl_GetDevice(LPDIRECT3DRESOURCE8 iface, IDirect3DDevice8** ppDevice);
 
 /* ---------------------- */
 /* IDirect3DVertexBuffer8 */
@@ -320,7 +322,7 @@ struct IDirect3DVertexBuffer8Impl
     LONG                              ref;
 
     /* IDirect3DResource8 fields */
-    IWineD3DVertexBuffer             *wineD3DVertexBuffer;
+    IWineD3DBuffer *wineD3DVertexBuffer;
 
     /* Parent reference */
     LPDIRECT3DDEVICE8                 parentDevice;
@@ -622,6 +624,8 @@ typedef struct IDirect3DPixelShader8Impl {
  *
  * to see how not defined it here
  */
+D3DFORMAT d3dformat_from_wined3dformat(WINED3DFORMAT format);
+WINED3DFORMAT wined3dformat_from_d3dformat(D3DFORMAT format);
 void load_local_constants(const DWORD *d3d8_elements, IWineD3DVertexShader *wined3d_vertex_shader);
 UINT convert_to_wined3d_declaration(const DWORD *d3d8_elements, DWORD *d3d8_elements_size, WINED3DVERTEXELEMENT **wined3d_elements);
 size_t parse_token(const DWORD* pToken);
index 9e3fb69..0e8c480 100644 (file)
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
 
-/* Shader handle functions */
-static shader_handle *alloc_shader_handle(IDirect3DDevice8Impl *This) {
-    if (This->free_shader_handles) {
+D3DFORMAT d3dformat_from_wined3dformat(WINED3DFORMAT format)
+{
+    BYTE *c = (BYTE *)&format;
+
+    /* Don't translate FOURCC formats */
+    if (isprint(c[0]) && isprint(c[1]) && isprint(c[2]) && isprint(c[3])) return format;
+
+    switch(format)
+    {
+        case WINED3DFMT_UNKNOWN: return D3DFMT_UNKNOWN;
+        case WINED3DFMT_R8G8B8: return D3DFMT_R8G8B8;
+        case WINED3DFMT_A8R8G8B8: return D3DFMT_A8R8G8B8;
+        case WINED3DFMT_X8R8G8B8: return D3DFMT_X8R8G8B8;
+        case WINED3DFMT_R5G6B5: return D3DFMT_R5G6B5;
+        case WINED3DFMT_X1R5G5B5: return D3DFMT_X1R5G5B5;
+        case WINED3DFMT_A1R5G5B5: return D3DFMT_A1R5G5B5;
+        case WINED3DFMT_A4R4G4B4: return D3DFMT_A4R4G4B4;
+        case WINED3DFMT_R3G3B2: return D3DFMT_R3G3B2;
+        case WINED3DFMT_A8_UNORM: return D3DFMT_A8;
+        case WINED3DFMT_A8R3G3B2: return D3DFMT_A8R3G3B2;
+        case WINED3DFMT_X4R4G4B4: return D3DFMT_X4R4G4B4;
+        case WINED3DFMT_R10G10B10A2_UNORM: return D3DFMT_A2B10G10R10;
+        case WINED3DFMT_R16G16_UNORM: return D3DFMT_G16R16;
+        case WINED3DFMT_A8P8: return D3DFMT_A8P8;
+        case WINED3DFMT_P8: return D3DFMT_P8;
+        case WINED3DFMT_L8: return D3DFMT_L8;
+        case WINED3DFMT_A8L8: return D3DFMT_A8L8;
+        case WINED3DFMT_A4L4: return D3DFMT_A4L4;
+        case WINED3DFMT_R8G8_SNORM: return D3DFMT_V8U8;
+        case WINED3DFMT_L6V5U5: return D3DFMT_L6V5U5;
+        case WINED3DFMT_X8L8V8U8: return D3DFMT_X8L8V8U8;
+        case WINED3DFMT_R8G8B8A8_SNORM: return D3DFMT_Q8W8V8U8;
+        case WINED3DFMT_R16G16_SNORM: return D3DFMT_V16U16;
+        case WINED3DFMT_A2W10V10U10: return D3DFMT_A2W10V10U10;
+        case WINED3DFMT_D16_LOCKABLE: return D3DFMT_D16_LOCKABLE;
+        case WINED3DFMT_D32: return D3DFMT_D32;
+        case WINED3DFMT_D15S1: return D3DFMT_D15S1;
+        case WINED3DFMT_D24S8: return D3DFMT_D24S8;
+        case WINED3DFMT_D24X8: return D3DFMT_D24X8;
+        case WINED3DFMT_D24X4S4: return D3DFMT_D24X4S4;
+        case WINED3DFMT_D16_UNORM: return D3DFMT_D16;
+        case WINED3DFMT_VERTEXDATA: return D3DFMT_VERTEXDATA;
+        case WINED3DFMT_R16_UINT: return D3DFMT_INDEX16;
+        case WINED3DFMT_R32_UINT: return D3DFMT_INDEX32;
+        default:
+            FIXME("Unhandled WINED3DFORMAT %#x\n", format);
+            return D3DFMT_UNKNOWN;
+    }
+}
+
+WINED3DFORMAT wined3dformat_from_d3dformat(D3DFORMAT format)
+{
+    BYTE *c = (BYTE *)&format;
+
+    /* Don't translate FOURCC formats */
+    if (isprint(c[0]) && isprint(c[1]) && isprint(c[2]) && isprint(c[3])) return format;
+
+    switch(format)
+    {
+        case D3DFMT_UNKNOWN: return WINED3DFMT_UNKNOWN;
+        case D3DFMT_R8G8B8: return WINED3DFMT_R8G8B8;
+        case D3DFMT_A8R8G8B8: return WINED3DFMT_A8R8G8B8;
+        case D3DFMT_X8R8G8B8: return WINED3DFMT_X8R8G8B8;
+        case D3DFMT_R5G6B5: return WINED3DFMT_R5G6B5;
+        case D3DFMT_X1R5G5B5: return WINED3DFMT_X1R5G5B5;
+        case D3DFMT_A1R5G5B5: return WINED3DFMT_A1R5G5B5;
+        case D3DFMT_A4R4G4B4: return WINED3DFMT_A4R4G4B4;
+        case D3DFMT_R3G3B2: return WINED3DFMT_R3G3B2;
+        case D3DFMT_A8: return WINED3DFMT_A8_UNORM;
+        case D3DFMT_A8R3G3B2: return WINED3DFMT_A8R3G3B2;
+        case D3DFMT_X4R4G4B4: return WINED3DFMT_X4R4G4B4;
+        case D3DFMT_A2B10G10R10: return WINED3DFMT_R10G10B10A2_UNORM;
+        case D3DFMT_G16R16: return WINED3DFMT_R16G16_UNORM;
+        case D3DFMT_A8P8: return WINED3DFMT_A8P8;
+        case D3DFMT_P8: return WINED3DFMT_P8;
+        case D3DFMT_L8: return WINED3DFMT_L8;
+        case D3DFMT_A8L8: return WINED3DFMT_A8L8;
+        case D3DFMT_A4L4: return WINED3DFMT_A4L4;
+        case D3DFMT_V8U8: return WINED3DFMT_R8G8_SNORM;
+        case D3DFMT_L6V5U5: return WINED3DFMT_L6V5U5;
+        case D3DFMT_X8L8V8U8: return WINED3DFMT_X8L8V8U8;
+        case D3DFMT_Q8W8V8U8: return WINED3DFMT_R8G8B8A8_SNORM;
+        case D3DFMT_V16U16: return WINED3DFMT_R16G16_SNORM;
+        case D3DFMT_A2W10V10U10: return WINED3DFMT_A2W10V10U10;
+        case D3DFMT_D16_LOCKABLE: return WINED3DFMT_D16_LOCKABLE;
+        case D3DFMT_D32: return WINED3DFMT_D32;
+        case D3DFMT_D15S1: return WINED3DFMT_D15S1;
+        case D3DFMT_D24S8: return WINED3DFMT_D24S8;
+        case D3DFMT_D24X8: return WINED3DFMT_D24X8;
+        case D3DFMT_D24X4S4: return WINED3DFMT_D24X4S4;
+        case D3DFMT_D16: return WINED3DFMT_D16_UNORM;
+        case D3DFMT_VERTEXDATA: return WINED3DFMT_VERTEXDATA;
+        case D3DFMT_INDEX16: return WINED3DFMT_R16_UINT;
+        case D3DFMT_INDEX32: return WINED3DFMT_R32_UINT;
+        default:
+            FIXME("Unhandled D3DFORMAT %#x\n", format);
+            return WINED3DFMT_UNKNOWN;
+    }
+}
+
+static UINT vertex_count_from_primitive_count(D3DPRIMITIVETYPE primitive_type, UINT primitive_count)
+{
+    switch(primitive_type)
+    {
+        case D3DPT_POINTLIST:
+            return primitive_count;
+
+        case D3DPT_LINELIST:
+            return primitive_count * 2;
+
+        case D3DPT_LINESTRIP:
+            return primitive_count + 1;
+
+        case D3DPT_TRIANGLELIST:
+            return primitive_count * 3;
+
+        case D3DPT_TRIANGLESTRIP:
+        case D3DPT_TRIANGLEFAN:
+            return primitive_count + 2;
+
+        default:
+            FIXME("Unhandled primitive type %#x\n", primitive_type);
+            return 0;
+    }
+}
+
+/* Handle table functions */
+static DWORD d3d8_allocate_handle(struct d3d8_handle_table *t, void *object)
+{
+    if (t->free_entries)
+    {
         /* Use a free handle */
-        shader_handle *handle = This->free_shader_handles;
-        This->free_shader_handles = *handle;
-        return handle;
+        void **entry = t->free_entries;
+        t->free_entries = *entry;
+        *entry = object;
+        return entry - t->entries;
     }
-    if (!(This->allocated_shader_handles < This->shader_handle_table_size)) {
+
+    if (!(t->entry_count < t->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;
+        UINT new_size = t->table_size + (t->table_size >> 1);
+        void **new_entries = HeapReAlloc(GetProcessHeap(), 0, t->entries, new_size * sizeof(void *));
+        if (!new_entries) return D3D8_INVALID_HANDLE;
+        t->entries = new_entries;
+        t->table_size = new_size;
     }
 
-    return &This->shader_handles[This->allocated_shader_handles++];
+    t->entries[t->entry_count] = object;
+    return t->entry_count++;
 }
 
-static void free_shader_handle(IDirect3DDevice8Impl *This, shader_handle *handle) {
-    *handle = This->free_shader_handles;
-    This->free_shader_handles = handle;
+static void *d3d8_free_handle(struct d3d8_handle_table *t, DWORD handle)
+{
+    void **entry, *object;
+
+    if (handle >= t->entry_count) return NULL;
+
+    entry = &t->entries[handle];
+    object = *entry;
+    *entry = t->free_entries;
+    t->free_entries = entry;
+
+    return object;
+}
+
+static void *d3d8_get_object(struct d3d8_handle_table *t, DWORD handle)
+{
+    if (handle >= t->entry_count) return NULL;
+    return t->entries[handle];
 }
 
 /* IDirect3D IUnknown parts follow: */
@@ -117,7 +264,7 @@ static ULONG WINAPI IDirect3DDevice8Impl_Release(LPDIRECT3DDEVICE8 iface) {
 
         IWineD3DDevice_Uninit3D(This->WineD3DDevice, D3D8CB_DestroyDepthStencilSurface, D3D8CB_DestroySwapChain);
         IWineD3DDevice_Release(This->WineD3DDevice);
-        HeapFree(GetProcessHeap(), 0, This->shader_handles);
+        HeapFree(GetProcessHeap(), 0, This->handle_table.entries);
         HeapFree(GetProcessHeap(), 0, This);
         LeaveCriticalSection(&d3d8_cs);
     }
@@ -225,6 +372,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetDisplayMode(LPDIRECT3DDEVICE8 ifac
     EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_GetDisplayMode(This->WineD3DDevice, 0, (WINED3DDISPLAYMODE *) pMode);
     LeaveCriticalSection(&d3d8_cs);
+
+    if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
+
     return hr;
 }
 
@@ -300,7 +450,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateAdditionalSwapChain(LPDIRECT3DD
     /* Allocate an associated WineD3DDevice object */
     localParameters.BackBufferWidth                             = pPresentationParameters->BackBufferWidth;
     localParameters.BackBufferHeight                            = pPresentationParameters->BackBufferHeight;
-    localParameters.BackBufferFormat                            = pPresentationParameters->BackBufferFormat;
+    localParameters.BackBufferFormat                            = wined3dformat_from_d3dformat(pPresentationParameters->BackBufferFormat);
     localParameters.BackBufferCount                             = pPresentationParameters->BackBufferCount;
     localParameters.MultiSampleType                             = pPresentationParameters->MultiSampleType;
     localParameters.MultiSampleQuality                          = 0; /* d3d9 only */
@@ -308,7 +458,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateAdditionalSwapChain(LPDIRECT3DD
     localParameters.hDeviceWindow                               = pPresentationParameters->hDeviceWindow;
     localParameters.Windowed                                    = pPresentationParameters->Windowed;
     localParameters.EnableAutoDepthStencil                      = pPresentationParameters->EnableAutoDepthStencil;
-    localParameters.AutoDepthStencilFormat                      = pPresentationParameters->AutoDepthStencilFormat;
+    localParameters.AutoDepthStencilFormat                      = wined3dformat_from_d3dformat(pPresentationParameters->AutoDepthStencilFormat);
     localParameters.Flags                                       = pPresentationParameters->Flags;
     localParameters.FullScreen_RefreshRateInHz                  = pPresentationParameters->FullScreen_RefreshRateInHz;
     localParameters.PresentationInterval                        = pPresentationParameters->FullScreen_PresentationInterval;
@@ -321,14 +471,14 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateAdditionalSwapChain(LPDIRECT3DD
 
     pPresentationParameters->BackBufferWidth                    = localParameters.BackBufferWidth;
     pPresentationParameters->BackBufferHeight                   = localParameters.BackBufferHeight;
-    pPresentationParameters->BackBufferFormat                   = localParameters.BackBufferFormat;
+    pPresentationParameters->BackBufferFormat                   = d3dformat_from_wined3dformat(localParameters.BackBufferFormat);
     pPresentationParameters->BackBufferCount                    = localParameters.BackBufferCount;
     pPresentationParameters->MultiSampleType                    = localParameters.MultiSampleType;
     pPresentationParameters->SwapEffect                         = localParameters.SwapEffect;
     pPresentationParameters->hDeviceWindow                      = localParameters.hDeviceWindow;
     pPresentationParameters->Windowed                           = localParameters.Windowed;
     pPresentationParameters->EnableAutoDepthStencil             = localParameters.EnableAutoDepthStencil;
-    pPresentationParameters->AutoDepthStencilFormat             = localParameters.AutoDepthStencilFormat;
+    pPresentationParameters->AutoDepthStencilFormat             = d3dformat_from_wined3dformat(localParameters.AutoDepthStencilFormat);
     pPresentationParameters->Flags                              = localParameters.Flags;
     pPresentationParameters->FullScreen_RefreshRateInHz         = localParameters.FullScreen_RefreshRateInHz;
     pPresentationParameters->FullScreen_PresentationInterval    = localParameters.PresentationInterval;
@@ -355,7 +505,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_Reset(LPDIRECT3DDEVICE8 iface, D3DPRE
 
     localParameters.BackBufferWidth                             = pPresentationParameters->BackBufferWidth;
     localParameters.BackBufferHeight                            = pPresentationParameters->BackBufferHeight;
-    localParameters.BackBufferFormat                            = pPresentationParameters->BackBufferFormat;
+    localParameters.BackBufferFormat                            = wined3dformat_from_d3dformat(pPresentationParameters->BackBufferFormat);
     localParameters.BackBufferCount                             = pPresentationParameters->BackBufferCount;
     localParameters.MultiSampleType                             = pPresentationParameters->MultiSampleType;
     localParameters.MultiSampleQuality                          = 0; /* d3d9 only */
@@ -363,7 +513,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_Reset(LPDIRECT3DDEVICE8 iface, D3DPRE
     localParameters.hDeviceWindow                               = pPresentationParameters->hDeviceWindow;
     localParameters.Windowed                                    = pPresentationParameters->Windowed;
     localParameters.EnableAutoDepthStencil                      = pPresentationParameters->EnableAutoDepthStencil;
-    localParameters.AutoDepthStencilFormat                      = pPresentationParameters->AutoDepthStencilFormat;
+    localParameters.AutoDepthStencilFormat                      = wined3dformat_from_d3dformat(pPresentationParameters->AutoDepthStencilFormat);
     localParameters.Flags                                       = pPresentationParameters->Flags;
     localParameters.FullScreen_RefreshRateInHz                  = pPresentationParameters->FullScreen_RefreshRateInHz;
     localParameters.PresentationInterval                        = pPresentationParameters->FullScreen_PresentationInterval;
@@ -375,14 +525,14 @@ static HRESULT WINAPI IDirect3DDevice8Impl_Reset(LPDIRECT3DDEVICE8 iface, D3DPRE
 
     pPresentationParameters->BackBufferWidth                    = localParameters.BackBufferWidth;
     pPresentationParameters->BackBufferHeight                   = localParameters.BackBufferHeight;
-    pPresentationParameters->BackBufferFormat                   = localParameters.BackBufferFormat;
+    pPresentationParameters->BackBufferFormat                   = d3dformat_from_wined3dformat(localParameters.BackBufferFormat);
     pPresentationParameters->BackBufferCount                    = localParameters.BackBufferCount;
     pPresentationParameters->MultiSampleType                    = localParameters.MultiSampleType;
     pPresentationParameters->SwapEffect                         = localParameters.SwapEffect;
     pPresentationParameters->hDeviceWindow                      = localParameters.hDeviceWindow;
     pPresentationParameters->Windowed                           = localParameters.Windowed;
     pPresentationParameters->EnableAutoDepthStencil             = localParameters.EnableAutoDepthStencil;
-    pPresentationParameters->AutoDepthStencilFormat             = localParameters.AutoDepthStencilFormat;
+    pPresentationParameters->AutoDepthStencilFormat             = d3dformat_from_wined3dformat(localParameters.AutoDepthStencilFormat);
     pPresentationParameters->Flags                              = localParameters.Flags;
     pPresentationParameters->FullScreen_RefreshRateInHz         = localParameters.FullScreen_RefreshRateInHz;
     pPresentationParameters->FullScreen_PresentationInterval    = localParameters.PresentationInterval;
@@ -470,7 +620,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateTexture(LPDIRECT3DDEVICE8 iface
     object->ref = 1;
     EnterCriticalSection(&d3d8_cs);
     hrc = IWineD3DDevice_CreateTexture(This->WineD3DDevice, Width, Height, Levels, Usage & WINED3DUSAGE_MASK,
-            Format, Pool, &object->wineD3DTexture, NULL, (IUnknown *)object);
+            wined3dformat_from_d3dformat(Format), Pool, &object->wineD3DTexture, NULL, (IUnknown *)object);
     LeaveCriticalSection(&d3d8_cs);
 
     if (FAILED(hrc)) {
@@ -510,7 +660,8 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateVolumeTexture(LPDIRECT3DDEVICE8
     object->ref = 1;
     EnterCriticalSection(&d3d8_cs);
     hrc = IWineD3DDevice_CreateVolumeTexture(This->WineD3DDevice, Width, Height, Depth, Levels,
-            Usage & WINED3DUSAGE_MASK, Format, Pool, &object->wineD3DVolumeTexture, NULL, (IUnknown *)object);
+            Usage & WINED3DUSAGE_MASK, wined3dformat_from_d3dformat(Format), Pool,
+            &object->wineD3DVolumeTexture, NULL, (IUnknown *)object);
     LeaveCriticalSection(&d3d8_cs);
 
     if (hrc != D3D_OK) {
@@ -550,7 +701,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateCubeTexture(LPDIRECT3DDEVICE8 i
     object->ref = 1;
     EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_CreateCubeTexture(This->WineD3DDevice, EdgeLength, Levels, Usage & WINED3DUSAGE_MASK,
-            Format, Pool, &object->wineD3DCubeTexture, NULL, (IUnknown *)object);
+            wined3dformat_from_d3dformat(Format), Pool, &object->wineD3DCubeTexture, NULL, (IUnknown *)object);
     LeaveCriticalSection(&d3d8_cs);
 
     if (hr != D3D_OK){
@@ -621,7 +772,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateIndexBuffer(LPDIRECT3DDEVICE8 i
     object->ref = 1;
     TRACE("Calling wined3d create index buffer\n");
     EnterCriticalSection(&d3d8_cs);
-    hrc = IWineD3DDevice_CreateIndexBuffer(This->WineD3DDevice, Length, Usage & WINED3DUSAGE_MASK, Format, (WINED3DPOOL) Pool, &object->wineD3DIndexBuffer, NULL, (IUnknown *)object);
+    hrc = IWineD3DDevice_CreateIndexBuffer(This->WineD3DDevice, Length, Usage & WINED3DUSAGE_MASK,
+            wined3dformat_from_d3dformat(Format), (WINED3DPOOL) Pool, &object->wineD3DIndexBuffer,
+            NULL, (IUnknown *)object);
     LeaveCriticalSection(&d3d8_cs);
 
     if (D3D_OK != hrc) {
@@ -667,8 +820,11 @@ static HRESULT IDirect3DDevice8Impl_CreateSurface(LPDIRECT3DDEVICE8 iface, UINT
 
     TRACE("(%p) : w(%d) h(%d) fmt(%d) surf@%p\n", This, Width, Height, Format, *ppSurface);
 
-    /* Not called from the VTable, no locking needed */
-    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);
+    EnterCriticalSection(&d3d8_cs);
+    hrc = IWineD3DDevice_CreateSurface(This->WineD3DDevice, Width, Height, wined3dformat_from_d3dformat(Format),
+            Lockable, Discard, Level,  &object->wineD3DSurface, Type, Usage & WINED3DUSAGE_MASK,
+            (WINED3DPOOL)Pool, MultiSample,MultisampleQuality, NULL, SURFACE_OPENGL, (IUnknown *)object);
+    LeaveCriticalSection(&d3d8_cs);
     if (hrc != D3D_OK || NULL == object->wineD3DSurface) {
        /* free up object */
         FIXME("(%p) call to IWineD3DDevice_CreateSurface failed\n", This);
@@ -686,9 +842,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateRenderTarget(LPDIRECT3DDEVICE8
     HRESULT hr;
     TRACE("Relay\n");
 
-    EnterCriticalSection(&d3d8_cs);
     hr = IDirect3DDevice8Impl_CreateSurface(iface, Width, Height, Format, Lockable, FALSE /* Discard */, 0 /* Level */ , ppSurface, D3DRTYPE_SURFACE, D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT, MultiSample, 0);
-    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
@@ -697,11 +851,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateDepthStencilSurface(LPDIRECT3DD
     TRACE("Relay\n");
 
     /* TODO: Verify that Discard is false */
-    EnterCriticalSection(&d3d8_cs);
     hr = IDirect3DDevice8Impl_CreateSurface(iface, Width, Height, Format, TRUE /* Lockable */, FALSE, 0 /* Level */
                                                ,ppSurface, D3DRTYPE_SURFACE, D3DUSAGE_DEPTHSTENCIL,
                                                 D3DPOOL_DEFAULT, MultiSample, 0);
-    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
@@ -710,10 +862,8 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateImageSurface(LPDIRECT3DDEVICE8
     HRESULT hr;
     TRACE("Relay\n");
 
-    EnterCriticalSection(&d3d8_cs);
     hr = IDirect3DDevice8Impl_CreateSurface(iface, Width, Height, Format, TRUE /* Loackable */ , FALSE /*Discard*/ , 0 /* Level */ , ppSurface,
                                             D3DRTYPE_SURFACE, 0 /* Usage (undefined/none) */ , D3DPOOL_SYSTEMMEM, D3DMULTISAMPLE_NONE, 0 /* MultisampleQuality */);
-    LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
@@ -739,13 +889,13 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CopyRects(LPDIRECT3DDEVICE8 iface, ID
     winedesc.Width  = &srcWidth;
     winedesc.Height = &srcHeight;
     winedesc.Size   = &srcSize;
+    EnterCriticalSection(&d3d8_cs);
     IWineD3DSurface_GetDesc(Source->wineD3DSurface, &winedesc);
 
     winedesc.Format = &destFormat;
     winedesc.Width  = &destWidth;
     winedesc.Height = &destHeight;
     winedesc.Size   = NULL;
-    EnterCriticalSection(&d3d8_cs);
     IWineD3DSurface_GetDesc(Dest->wineD3DSurface, &winedesc);
 
     /* Check that the source and destination formats match */
@@ -1128,86 +1278,138 @@ static HRESULT WINAPI IDirect3DDevice8Impl_EndStateBlock(LPDIRECT3DDEVICE8 iface
 
     object->wineD3DStateBlock = wineD3DStateBlock;
 
-    *pToken = (DWORD)object;
-    TRACE("(%p)Returning %p %p\n", This, object, wineD3DStateBlock);
-
+    *pToken = d3d8_allocate_handle(&This->handle_table, object);
     LeaveCriticalSection(&d3d8_cs);
+
+    if (*pToken == D3D8_INVALID_HANDLE)
+    {
+        ERR("Failed to create a handle\n");
+        IDirect3DStateBlock8_Release((IDirect3DStateBlock8 *)object);
+        return E_FAIL;
+    }
+    ++*pToken;
+
+    TRACE("Returning %#x (%p).\n", *pToken, object);
+
     return hr;
 }
 
 static HRESULT WINAPI IDirect3DDevice8Impl_ApplyStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
-    IDirect3DStateBlock8Impl *pSB  = (IDirect3DStateBlock8Impl*) Token;
     IDirect3DDevice8Impl     *This = (IDirect3DDevice8Impl *)iface;
+    IDirect3DStateBlock8Impl *pSB;
     HRESULT hr;
 
-    TRACE("(%p) %p Relay\n", This, pSB);
+    TRACE("(%p) %#x Relay\n", This, Token);
 
     EnterCriticalSection(&d3d8_cs);
+    pSB = d3d8_get_object(&This->handle_table, Token - 1);
+    if (!pSB)
+    {
+        WARN("Invalid handle (%#x) passed.\n", Token);
+        LeaveCriticalSection(&d3d8_cs);
+        return D3DERR_INVALIDCALL;
+    }
     hr = IWineD3DStateBlock_Apply(pSB->wineD3DStateBlock);
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
 static HRESULT WINAPI IDirect3DDevice8Impl_CaptureStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
-    IDirect3DStateBlock8Impl* pSB = (IDirect3DStateBlock8Impl *)Token;
     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    IDirect3DStateBlock8Impl *pSB;
     HRESULT hr;
 
-    TRACE("(%p) %p Relay\n", This, pSB);
+    TRACE("(%p) %#x Relay\n", This, Token);
 
     EnterCriticalSection(&d3d8_cs);
+    pSB = d3d8_get_object(&This->handle_table, Token - 1);
+    if (!pSB)
+    {
+        WARN("Invalid handle (%#x) passed.\n", Token);
+        LeaveCriticalSection(&d3d8_cs);
+        return D3DERR_INVALIDCALL;
+    }
     hr = IWineD3DStateBlock_Capture(pSB->wineD3DStateBlock);
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
 static HRESULT WINAPI IDirect3DDevice8Impl_DeleteStateBlock(LPDIRECT3DDEVICE8 iface, DWORD Token) {
-    IDirect3DStateBlock8Impl* pSB = (IDirect3DStateBlock8Impl *)Token;
     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    IDirect3DStateBlock8Impl *pSB;
 
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    while(IUnknown_Release((IUnknown *)pSB));
+    pSB = d3d8_free_handle(&This->handle_table, Token - 1);
     LeaveCriticalSection(&d3d8_cs);
 
+    if (!pSB)
+    {
+        WARN("Invalid handle (%#x) passed.\n", Token);
+        return D3DERR_INVALIDCALL;
+    }
+
+    if (IUnknown_Release((IUnknown *)pSB))
+    {
+        ERR("Stateblock %p has references left, this shouldn't happen.\n", pSB);
+    }
+
     return D3D_OK;
 }
 
-static HRESULT WINAPI IDirect3DDevice8Impl_CreateStateBlock(LPDIRECT3DDEVICE8 iface, D3DSTATEBLOCKTYPE Type, DWORD* pToken) {
-   IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
-   IDirect3DStateBlock8Impl *object;
-   HRESULT hrc = D3D_OK;
+static HRESULT WINAPI IDirect3DDevice8Impl_CreateStateBlock(IDirect3DDevice8 *iface,
+        D3DSTATEBLOCKTYPE Type, DWORD *handle)
+{
+    IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    IDirect3DStateBlock8Impl *object;
+    HRESULT hr;
 
-   TRACE("(%p) Relay\n", This);
+    TRACE("(%p) Relay\n", This);
 
-   if(Type != D3DSBT_ALL         && Type != D3DSBT_PIXELSTATE &&
-      Type != D3DSBT_VERTEXSTATE                              ) {
-       WARN("Unexpected stateblock type, returning D3DERR_INVALIDCALL\n");
-       return D3DERR_INVALIDCALL;
-   }
+    if (Type != D3DSBT_ALL
+            && Type != D3DSBT_PIXELSTATE
+            && Type != D3DSBT_VERTEXSTATE)
+    {
+        WARN("Unexpected stateblock type, returning D3DERR_INVALIDCALL\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;
-
-   EnterCriticalSection(&d3d8_cs);
-   hrc = IWineD3DDevice_CreateStateBlock(This->WineD3DDevice, (WINED3DSTATEBLOCKTYPE)Type, &object->wineD3DStateBlock, (IUnknown *)object);
-   LeaveCriticalSection(&d3d8_cs);
-   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);
-   }
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DStateBlock8Impl));
+    if (!object)
+    {
+        ERR("Failed to allocate memory.\n");
+        return E_OUTOFMEMORY;
+    }
 
-   return hrc;
+    object->lpVtbl = &Direct3DStateBlock8_Vtbl;
+    object->ref = 1;
+
+    EnterCriticalSection(&d3d8_cs);
+    hr = IWineD3DDevice_CreateStateBlock(This->WineD3DDevice, (WINED3DSTATEBLOCKTYPE)Type,
+            &object->wineD3DStateBlock, (IUnknown *)object);
+    if (FAILED(hr))
+    {
+        LeaveCriticalSection(&d3d8_cs);
+        ERR("IWineD3DDevice_CreateStateBlock failed, hr %#x\n", hr);
+        HeapFree(GetProcessHeap(), 0, object);
+        return hr;
+    }
+
+    *handle = d3d8_allocate_handle(&This->handle_table, object);
+    LeaveCriticalSection(&d3d8_cs);
+
+    if (*handle == D3D8_INVALID_HANDLE)
+    {
+        ERR("Failed to allocate a handle.\n");
+        IDirect3DStateBlock8_Release((IDirect3DStateBlock8 *)object);
+        return E_FAIL;
+    }
+    ++*handle;
+
+    TRACE("Returning %#x (%p).\n", *handle, object);
+
+    return hr;
 }
 
 static HRESULT WINAPI IDirect3DDevice8Impl_SetClipStatus(LPDIRECT3DDEVICE8 iface, CONST D3DCLIPSTATUS8* pClipStatus) {
@@ -1404,7 +1606,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitive(LPDIRECT3DDEVICE8 iface
     TRACE("(%p) Relay\n" , This);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IWineD3DDevice_DrawPrimitive(This->WineD3DDevice, PrimitiveType, StartVertex, PrimitiveCount);
+    IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
+    hr = IWineD3DDevice_DrawPrimitive(This->WineD3DDevice, StartVertex,
+            vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount));
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
@@ -1416,7 +1620,9 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE
     TRACE("(%p) Relay\n" , This);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IWineD3DDevice_DrawIndexedPrimitive(This->WineD3DDevice, PrimitiveType, MinVertexIndex, NumVertices, startIndex, primCount);
+    IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
+    hr = IWineD3DDevice_DrawIndexedPrimitive(This->WineD3DDevice, MinVertexIndex, NumVertices,
+            startIndex, vertex_count_from_primitive_count(PrimitiveType, primCount));
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
@@ -1427,7 +1633,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE8 ifa
     TRACE("(%p) Relay\n" , This);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IWineD3DDevice_DrawPrimitiveUP(This->WineD3DDevice, PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride);
+    IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
+    hr = IWineD3DDevice_DrawPrimitiveUP(This->WineD3DDevice,
+            vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount),
+            pVertexStreamZeroData, VertexStreamZeroStride);
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
@@ -1441,8 +1650,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVI
     TRACE("(%p) Relay\n" , This);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->WineD3DDevice, PrimitiveType, MinVertexIndex, NumVertexIndices, PrimitiveCount,
-                                               pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride);
+    IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
+    hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->WineD3DDevice, MinVertexIndex, NumVertexIndices,
+            vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount), pIndexData,
+            wined3dformat_from_d3dformat(IndexDataFormat), pVertexStreamZeroData, VertexStreamZeroStride);
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
@@ -1513,7 +1724,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8
     IDirect3DVertexShader8Impl *object;
     IWineD3DVertexDeclaration *wined3d_vertex_declaration;
     const DWORD *token = pDeclaration;
-    shader_handle *handle;
+    DWORD handle;
 
     /* Test if the vertex declaration is valid */
     while (D3DVSD_END() != *token) {
@@ -1543,18 +1754,17 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8
     object->ref = 1;
     object->lpVtbl = &Direct3DVertexShader8_Vtbl;
 
-    EnterCriticalSection(&d3d8_cs);
     hrc = IDirect3DDevice8Impl_CreateVertexDeclaration(iface, pDeclaration, &object->vertex_declaration);
     if (FAILED(hrc)) {
         ERR("(%p) : IDirect3DDeviceImpl_CreateVertexDeclaration call failed\n", This);
-        LeaveCriticalSection(&d3d8_cs);
         HeapFree(GetProcessHeap(), 0, object);
         *ppShader = 0;
         return D3DERR_INVALIDCALL;
     }
 
-    handle = alloc_shader_handle(This);
-    if (!handle)
+    EnterCriticalSection(&d3d8_cs);
+    handle = d3d8_allocate_handle(&This->handle_table, object);
+    if (handle == D3D8_INVALID_HANDLE)
     {
         ERR("Failed to allocate shader handle\n");
         LeaveCriticalSection(&d3d8_cs);
@@ -1565,8 +1775,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8
     }
     else
     {
-        DWORD shader_handle = (handle - This->shader_handles) + VS_HIGHESTFIXEDFXF + 1;
-        *handle = object;
+        DWORD shader_handle = handle + VS_HIGHESTFIXEDFXF + 1;
         *ppShader = ((IDirect3DVertexDeclaration8Impl *)object->vertex_declaration)->shader_handle = shader_handle;
     }
 
@@ -1582,7 +1791,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8
         {
             /* free up object */
             FIXME("Call to IWineD3DDevice_CreateVertexShader failed\n");
-            free_shader_handle(This, handle);
+            d3d8_free_handle(&This->handle_table, handle);
             IDirect3DVertexDeclaration8_Release(object->vertex_declaration);
             HeapFree(GetProcessHeap(), 0, object);
             *ppShader = 0;
@@ -1670,108 +1879,114 @@ static IDirect3DVertexDeclaration8Impl *IDirect3DDevice8Impl_FindDecl(IDirect3DD
 
 static HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD pShader) {
     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
-    HRESULT hrc = D3D_OK;
+    IDirect3DVertexShader8Impl *shader;
+    HRESULT hr;
 
     TRACE("(%p) : Relay\n", This);
-    EnterCriticalSection(&d3d8_cs);
+
     if (VS_HIGHESTFIXEDFXF >= pShader) {
         TRACE("Setting FVF, %#x\n", pShader);
+
+        EnterCriticalSection(&d3d8_cs);
         IWineD3DDevice_SetVertexDeclaration(This->WineD3DDevice,
                 IDirect3DDevice8Impl_FindDecl(This, pShader)->wined3d_vertex_declaration);
         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)];
-
-            if (shader)
-            {
-                hrc = IWineD3DDevice_SetVertexDeclaration(This->WineD3DDevice,
-                        ((IDirect3DVertexDeclaration8Impl *)shader->vertex_declaration)->wined3d_vertex_declaration);
-                if (SUCCEEDED(hrc))
-                    hrc = IWineD3DDevice_SetVertexShader(This->WineD3DDevice, shader->wineD3DVertexShader);
-            }
-            else
-            {
-                hrc = IWineD3DDevice_SetVertexDeclaration(This->WineD3DDevice, NULL);
-                if (SUCCEEDED(hrc)) hrc = IWineD3DDevice_SetVertexShader(This->WineD3DDevice, NULL);
-            }
-        }
+        LeaveCriticalSection(&d3d8_cs);
+        return D3D_OK;
     }
-    TRACE("(%p) : returning hr(%u)\n", This, hrc);
+
+    TRACE("Setting shader\n");
+
+    EnterCriticalSection(&d3d8_cs);
+    shader = d3d8_get_object(&This->handle_table, pShader - (VS_HIGHESTFIXEDFXF + 1));
+    if (!shader)
+    {
+        WARN("Invalid handle (%#x) passed.\n", pShader);
+        LeaveCriticalSection(&d3d8_cs);
+        return D3DERR_INVALIDCALL;
+    }
+
+    hr = IWineD3DDevice_SetVertexDeclaration(This->WineD3DDevice,
+            ((IDirect3DVertexDeclaration8Impl *)shader->vertex_declaration)->wined3d_vertex_declaration);
+    if (SUCCEEDED(hr)) hr = IWineD3DDevice_SetVertexShader(This->WineD3DDevice, shader->wineD3DVertexShader);
     LeaveCriticalSection(&d3d8_cs);
 
-    return hrc;
+    TRACE("Returning hr %#x\n", hr);
+
+    return hr;
 }
 
 static HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShader(LPDIRECT3DDEVICE8 iface, DWORD* ppShader) {
     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
     IWineD3DVertexDeclaration *wined3d_declaration;
+    IDirect3DVertexDeclaration8 *d3d8_declaration;
     HRESULT hrc;
 
     TRACE("(%p) : Relay  device@%p\n", This, This->WineD3DDevice);
     EnterCriticalSection(&d3d8_cs);
 
     hrc = IWineD3DDevice_GetVertexDeclaration(This->WineD3DDevice, &wined3d_declaration);
-    if (SUCCEEDED(hrc))
-    {
-        if (wined3d_declaration)
-        {
-            IDirect3DVertexDeclaration8 *d3d8_declaration;
-            hrc = IWineD3DVertexDeclaration_GetParent(wined3d_declaration, (IUnknown **)&d3d8_declaration);
-            IWineD3DVertexDeclaration_Release(wined3d_declaration);
-            if (SUCCEEDED(hrc))
-            {
-                *ppShader = ((IDirect3DVertexDeclaration8Impl *)d3d8_declaration)->shader_handle;
-                IDirect3DVertexDeclaration8_Release(d3d8_declaration);
-            }
-        }
-        else
-        {
-            *ppShader = 0;
-            hrc = D3D_OK;
-        }
-    }
-    else
+    if (FAILED(hrc))
     {
+        LeaveCriticalSection(&d3d8_cs);
         WARN("(%p) : Call to IWineD3DDevice_GetVertexDeclaration failed %#x (device %p)\n",
                 This, hrc, This->WineD3DDevice);
+        return hrc;
     }
-    TRACE("(%p) : returning %#x\n", This, *ppShader);
+
+    if (!wined3d_declaration)
+    {
+        LeaveCriticalSection(&d3d8_cs);
+        *ppShader = 0;
+        return D3D_OK;
+    }
+
+    hrc = IWineD3DVertexDeclaration_GetParent(wined3d_declaration, (IUnknown **)&d3d8_declaration);
+    IWineD3DVertexDeclaration_Release(wined3d_declaration);
     LeaveCriticalSection(&d3d8_cs);
+    if (SUCCEEDED(hrc))
+    {
+        *ppShader = ((IDirect3DVertexDeclaration8Impl *)d3d8_declaration)->shader_handle;
+        IDirect3DVertexDeclaration8_Release(d3d8_declaration);
+    }
+
+    TRACE("(%p) : returning %#x\n", This, *ppShader);
 
     return hrc;
 }
 
 static HRESULT  WINAPI  IDirect3DDevice8Impl_DeleteVertexShader(LPDIRECT3DDEVICE8 iface, DWORD pShader) {
     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    IDirect3DVertexShader8Impl *shader;
+    IWineD3DVertexShader *cur = NULL;
 
     TRACE("(%p) : pShader %#x\n", This, pShader);
 
     EnterCriticalSection(&d3d8_cs);
-    if (pShader <= VS_HIGHESTFIXEDFXF || This->allocated_shader_handles <= pShader - (VS_HIGHESTFIXEDFXF + 1)) {
-        ERR("(%p) : Trying to delete an invalid handle\n", This);
+
+    shader = d3d8_free_handle(&This->handle_table, pShader - (VS_HIGHESTFIXEDFXF + 1));
+    if (!shader)
+    {
+        WARN("Invalid handle (%#x) passed.\n", pShader);
         LeaveCriticalSection(&d3d8_cs);
         return D3DERR_INVALIDCALL;
-    } else {
-        IWineD3DVertexShader *cur = NULL;
-        shader_handle *handle = &This->shader_handles[pShader - (VS_HIGHESTFIXEDFXF + 1)];
-        IDirect3DVertexShader8Impl *shader = *handle;
-
-        IWineD3DDevice_GetVertexShader(This->WineD3DDevice, &cur);
-        if(cur) {
-            if(cur == shader->wineD3DVertexShader) IDirect3DDevice8_SetVertexShader(iface, 0);
-            IWineD3DVertexShader_Release(cur);
-        }
+    }
 
-        while(IUnknown_Release((IUnknown *)shader));
-        free_shader_handle(This, handle);
+    IWineD3DDevice_GetVertexShader(This->WineD3DDevice, &cur);
+
+    if (cur)
+    {
+        if (cur == shader->wineD3DVertexShader) IDirect3DDevice8_SetVertexShader(iface, 0);
+        IWineD3DVertexShader_Release(cur);
     }
+
     LeaveCriticalSection(&d3d8_cs);
 
+    if (IUnknown_Release((IUnknown *)shader))
+    {
+        ERR("Shader %p has references left, this shouldn't happen.\n", shader);
+    }
+
     return D3D_OK;
 }
 
@@ -1800,24 +2015,24 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderConstant(LPDIRECT3DDEV
 static HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderDeclaration(LPDIRECT3DDEVICE8 iface, DWORD pVertexShader, void* pData, DWORD* pSizeOfData) {
     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
     IDirect3DVertexDeclaration8Impl *declaration;
-    IDirect3DVertexShader8Impl *shader = NULL;
+    IDirect3DVertexShader8Impl *shader;
 
     TRACE("(%p) : pVertexShader 0x%08x, pData %p, *pSizeOfData %u\n", This, pVertexShader, pData, *pSizeOfData);
 
     EnterCriticalSection(&d3d8_cs);
-    if (pVertexShader <= VS_HIGHESTFIXEDFXF || This->allocated_shader_handles <= pVertexShader - (VS_HIGHESTFIXEDFXF + 1)) {
-        ERR("Passed an invalid shader handle.\n");
-        LeaveCriticalSection(&d3d8_cs);
+
+    shader = d3d8_get_object(&This->handle_table, pVertexShader - (VS_HIGHESTFIXEDFXF + 1));
+    LeaveCriticalSection(&d3d8_cs);
+    if (!shader)
+    {
+        WARN("Invalid handle (%#x) passed.\n", pVertexShader);
         return D3DERR_INVALIDCALL;
     }
-
-    shader = This->shader_handles[pVertexShader - (VS_HIGHESTFIXEDFXF + 1)];
     declaration = (IDirect3DVertexDeclaration8Impl *)shader->vertex_declaration;
 
     /* If pData is NULL, we just return the required size of the buffer. */
     if (!pData) {
         *pSizeOfData = declaration->elements_size;
-        LeaveCriticalSection(&d3d8_cs);
         return D3D_OK;
     }
 
@@ -1825,12 +2040,10 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderDeclaration(LPDIRECT3D
      * we should write the required size and return D3DERR_MOREDATA.
      * That's not actually true. */
     if (*pSizeOfData < declaration->elements_size) {
-        LeaveCriticalSection(&d3d8_cs);
         return D3DERR_INVALIDCALL;
     }
 
     CopyMemory(pData, declaration->elements, declaration->elements_size);
-    LeaveCriticalSection(&d3d8_cs);
 
     return D3D_OK;
 }
@@ -1843,23 +2056,24 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderFunction(LPDIRECT3DDEV
     TRACE("(%p) : pVertexShader %#x, pData %p, pSizeOfData %p\n", This, pVertexShader, pData, pSizeOfData);
 
     EnterCriticalSection(&d3d8_cs);
-    if (pVertexShader <= VS_HIGHESTFIXEDFXF || This->allocated_shader_handles <= pVertexShader - (VS_HIGHESTFIXEDFXF + 1)) {
-        ERR("Passed an invalid shader handle.\n");
+
+    shader = d3d8_get_object(&This->handle_table, pVertexShader - (VS_HIGHESTFIXEDFXF + 1));
+    if (!shader)
+    {
+        WARN("Invalid handle (%#x) passed.\n", pVertexShader);
         LeaveCriticalSection(&d3d8_cs);
         return D3DERR_INVALIDCALL;
     }
 
-    shader = This->shader_handles[pVertexShader - (VS_HIGHESTFIXEDFXF + 1)];
-    if (shader->wineD3DVertexShader)
-    {
-        hr = IWineD3DVertexShader_GetFunction(shader->wineD3DVertexShader, pData, pSizeOfData);
-    }
-    else
+    if (!shader->wineD3DVertexShader)
     {
+        LeaveCriticalSection(&d3d8_cs);
         *pSizeOfData = 0;
-        hr = D3D_OK;
+        return D3D_OK;
     }
 
+    hr = IWineD3DVertexShader_GetFunction(shader->wineD3DVertexShader, pData, pSizeOfData);
+
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
@@ -1912,7 +2126,8 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, I
 static HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pFunction, DWORD* ppShader) {
     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
     IDirect3DPixelShader8Impl *object;
-    HRESULT hrc = D3D_OK;
+    DWORD handle;
+    HRESULT hr;
 
     TRACE("(%p) : pFunction(%p), ppShader(%p)\n", This, pFunction, ppShader);
 
@@ -1920,55 +2135,70 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 i
         TRACE("(%p) Invalid call\n", This);
         return D3DERR_INVALIDCALL;
     }
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
 
-    if (NULL == object) {
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+    if (!object)
+    {
+        ERR("Failed to allocate memmory.\n");
         return E_OUTOFMEMORY;
-    } else {
-        EnterCriticalSection(&d3d8_cs);
+    }
 
-        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 {
-                *handle = object;
-                object->handle = (handle - This->shader_handles) + VS_HIGHESTFIXEDFXF + 1;
-                *ppShader = object->handle;
-                TRACE("(%p) : returning %p (handle %#x)\n", This, object, *ppShader);
-            }
-        }
+    object->ref    = 1;
+    object->lpVtbl = &Direct3DPixelShader8_Vtbl;
+
+    EnterCriticalSection(&d3d8_cs);
+    hr = IWineD3DDevice_CreatePixelShader(This->WineD3DDevice, pFunction,
+            &object->wineD3DPixelShader, (IUnknown *)object);
+    if (FAILED(hr))
+    {
         LeaveCriticalSection(&d3d8_cs);
+        FIXME("(%p) call to IWineD3DDevice_CreatePixelShader failed\n", This);
+        HeapFree(GetProcessHeap(), 0 , object);
+        *ppShader = 0;
+        return hr;
     }
 
-    return hrc;
+    handle = d3d8_allocate_handle(&This->handle_table, object);
+    LeaveCriticalSection(&d3d8_cs);
+    if (handle == D3D8_INVALID_HANDLE)
+    {
+        ERR("Failed to allocate shader handle\n");
+        IDirect3DVertexShader8_Release((IUnknown *)object);
+        return E_OUTOFMEMORY;
+    }
+
+    *ppShader = object->handle = handle + VS_HIGHESTFIXEDFXF + 1;
+    TRACE("(%p) : returning %p (handle %#x)\n", This, object, *ppShader);
+
+    return hr;
 }
 
 static HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD pShader) {
     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
-    IDirect3DPixelShader8Impl *shader = NULL;
+    IDirect3DPixelShader8Impl *shader;
     HRESULT hr;
 
     TRACE("(%p) : pShader %#x\n", This, pShader);
 
     EnterCriticalSection(&d3d8_cs);
-    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");
+
+    if (!pShader)
+    {
+        hr = IWineD3DDevice_SetPixelShader(This->WineD3DDevice, NULL);
+        LeaveCriticalSection(&d3d8_cs);
+        return hr;
+    }
+
+    shader = d3d8_get_object(&This->handle_table, pShader - (VS_HIGHESTFIXEDFXF + 1));
+    if (!shader)
+    {
+        WARN("Invalid handle (%#x) passed.\n", pShader);
+        LeaveCriticalSection(&d3d8_cs);
+        return D3DERR_INVALIDCALL;
     }
 
     TRACE("(%p) : Setting shader %p\n", This, shader);
-    hr = IWineD3DDevice_SetPixelShader(This->WineD3DDevice, shader == NULL ? NULL :shader->wineD3DPixelShader);
+    hr = IWineD3DDevice_SetPixelShader(This->WineD3DDevice, shader->wineD3DPixelShader);
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
@@ -1991,6 +2221,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShader(LPDIRECT3DDEVICE8 ifac
         hrc = IWineD3DPixelShader_GetParent(object, (IUnknown **)&d3d8_shader);
         IWineD3DPixelShader_Release(object);
         *ppShader = d3d8_shader->handle;
+        IDirect3DPixelShader8_Release((IDirect3DPixelShader8 *)d3d8_shader);
     } else {
         *ppShader = 0;
     }
@@ -2002,30 +2233,36 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShader(LPDIRECT3DDEVICE8 ifac
 
 static HRESULT WINAPI IDirect3DDevice8Impl_DeletePixelShader(LPDIRECT3DDEVICE8 iface, DWORD pShader) {
     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
+    IDirect3DPixelShader8Impl *shader;
+    IWineD3DPixelShader *cur = NULL;
 
     TRACE("(%p) : pShader %#x\n", This, pShader);
 
     EnterCriticalSection(&d3d8_cs);
-    if (pShader <= VS_HIGHESTFIXEDFXF || This->allocated_shader_handles <= pShader - (VS_HIGHESTFIXEDFXF + 1)) {
-        ERR("(%p) : Trying to delete an invalid handle\n", This);
+
+    shader = d3d8_free_handle(&This->handle_table, pShader - (VS_HIGHESTFIXEDFXF + 1));
+    if (!shader)
+    {
+        WARN("Invalid handle (%#x) passed.\n", pShader);
         LeaveCriticalSection(&d3d8_cs);
         return D3DERR_INVALIDCALL;
-    } else {
-        IWineD3DPixelShader *cur = NULL;
-        shader_handle *handle = &This->shader_handles[pShader - (VS_HIGHESTFIXEDFXF + 1)];
-        IDirect3DPixelShader8Impl *shader = *handle;
-
-        IWineD3DDevice_GetPixelShader(This->WineD3DDevice, &cur);
-        if(cur) {
-            if(cur == shader->wineD3DPixelShader) IDirect3DDevice8_SetPixelShader(iface, 0);
-            IWineD3DPixelShader_Release(cur);
-        }
+    }
 
-        while(IUnknown_Release((IUnknown *)shader));
-        free_shader_handle(This, handle);
+    IWineD3DDevice_GetPixelShader(This->WineD3DDevice, &cur);
+
+    if (cur)
+    {
+        if (cur == shader->wineD3DPixelShader) IDirect3DDevice8_SetPixelShader(iface, 0);
+        IWineD3DPixelShader_Release(cur);
     }
+
     LeaveCriticalSection(&d3d8_cs);
 
+    if (IUnknown_Release((IUnknown *)shader))
+    {
+        ERR("Shader %p has references left, this shouldn't happen.\n", shader);
+    }
+
     return D3D_OK;
 }
 
@@ -2059,13 +2296,14 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderFunction(LPDIRECT3DDEVI
     TRACE("(%p) : pPixelShader %#x, pData %p, pSizeOfData %p\n", This, pPixelShader, pData, pSizeOfData);
 
     EnterCriticalSection(&d3d8_cs);
-    if (pPixelShader <= VS_HIGHESTFIXEDFXF || This->allocated_shader_handles <= pPixelShader - (VS_HIGHESTFIXEDFXF + 1)) {
-        ERR("Passed an invalid shader handle.\n");
+    shader = d3d8_get_object(&This->handle_table, pPixelShader - (VS_HIGHESTFIXEDFXF + 1));
+    if (!shader)
+    {
+        WARN("Invalid handle (%#x) passed.\n", pPixelShader);
         LeaveCriticalSection(&d3d8_cs);
         return D3DERR_INVALIDCALL;
     }
 
-    shader = This->shader_handles[pPixelShader - (VS_HIGHESTFIXEDFXF + 1)];
     hr = IWineD3DPixelShader_GetFunction(shader->wineD3DPixelShader, pData, pSizeOfData);
     LeaveCriticalSection(&d3d8_cs);
     return hr;
@@ -2119,7 +2357,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetStreamSource(LPDIRECT3DDEVICE8 ifa
 
 static HRESULT WINAPI IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8** pStream,UINT* pStride) {
     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
-    IWineD3DVertexBuffer *retStream = NULL;
+    IWineD3DBuffer *retStream = NULL;
     HRESULT rc = D3D_OK;
 
     TRACE("(%p) Relay\n" , This);
@@ -2131,8 +2369,8 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 ifa
     EnterCriticalSection(&d3d8_cs);
     rc = IWineD3DDevice_GetStreamSource(This->WineD3DDevice, StreamNumber, &retStream, 0 /* Offset in bytes */, pStride);
     if (rc == D3D_OK  && NULL != retStream) {
-        IWineD3DVertexBuffer_GetParent(retStream, (IUnknown **)pStream);
-        IWineD3DVertexBuffer_Release(retStream);
+        IWineD3DBuffer_GetParent(retStream, (IUnknown **)pStream);
+        IWineD3DBuffer_Release(retStream);
     }else{
         if (rc != D3D_OK){
             FIXME("Call to GetStreamSource failed %p\n",  pStride);
@@ -2285,6 +2523,11 @@ static ULONG STDMETHODCALLTYPE device_parent_Release(IWineD3DDeviceParent *iface
 
 /* IWineD3DDeviceParent methods */
 
+static void STDMETHODCALLTYPE device_parent_WineD3DDeviceCreated(IWineD3DDeviceParent *iface, IWineD3DDevice *device)
+{
+    TRACE("iface %p, device %p\n", iface, device);
+}
+
 static HRESULT STDMETHODCALLTYPE device_parent_CreateSurface(IWineD3DDeviceParent *iface,
         IUnknown *superior, UINT width, UINT height, WINED3DFORMAT format, DWORD usage,
         WINED3DPOOL pool, UINT level, WINED3DCUBEMAP_FACES face, IWineD3DSurface **surface)
@@ -2302,8 +2545,9 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateSurface(IWineD3DDeviceParen
     if (pool == WINED3DPOOL_DEFAULT && !(usage & WINED3DUSAGE_DYNAMIC)) lockable = FALSE;
 
     hr = IDirect3DDevice8Impl_CreateSurface((IDirect3DDevice8 *)This, width, height,
-            format, lockable, FALSE /* Discard */, level, (IDirect3DSurface8 **)&d3d_surface,
-            D3DRTYPE_SURFACE, usage, pool, D3DMULTISAMPLE_NONE, 0 /* MultisampleQuality */);
+            d3dformat_from_wined3dformat(format), lockable, FALSE /* Discard */, level,
+            (IDirect3DSurface8 **)&d3d_surface, D3DRTYPE_SURFACE, usage, pool,
+            D3DMULTISAMPLE_NONE, 0 /* MultisampleQuality */);
     if (FAILED(hr))
     {
         ERR("(%p) CreateSurface failed, returning %#x\n", iface, hr);
@@ -2331,8 +2575,8 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateRenderTarget(IWineD3DDevice
             "\tmultisample_quality %u, lockable %u, surface %p\n",
             iface, superior, width, height, format, multisample_type, multisample_quality, lockable, surface);
 
-    hr = IDirect3DDevice8_CreateRenderTarget((IDirect3DDevice8 *)This, width, height, format,
-            multisample_type, lockable, (IDirect3DSurface8 **)&d3d_surface);
+    hr = IDirect3DDevice8_CreateRenderTarget((IDirect3DDevice8 *)This, width, height,
+            d3dformat_from_wined3dformat(format), multisample_type, lockable, (IDirect3DSurface8 **)&d3d_surface);
     if (FAILED(hr))
     {
         ERR("(%p) CreateRenderTarget failed, returning %#x\n", iface, hr);
@@ -2360,8 +2604,8 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateDepthStencilSurface(IWineD3
             "\tmultisample_quality %u, discard %u, surface %p\n",
             iface, superior, width, height, format, multisample_type, multisample_quality, discard, surface);
 
-    hr = IDirect3DDevice8_CreateDepthStencilSurface((IDirect3DDevice8 *)This, width, height, format,
-            multisample_type, (IDirect3DSurface8 **)&d3d_surface);
+    hr = IDirect3DDevice8_CreateDepthStencilSurface((IDirect3DDevice8 *)This, width, height,
+            d3dformat_from_wined3dformat(format), multisample_type, (IDirect3DSurface8 **)&d3d_surface);
     if (FAILED(hr))
     {
         ERR("(%p) CreateDepthStencilSurface failed, returning %#x\n", iface, hr);
@@ -2431,14 +2675,14 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateSwapChain(IWineD3DDevicePar
     /* Copy the presentation parameters */
     local_parameters.BackBufferWidth = present_parameters->BackBufferWidth;
     local_parameters.BackBufferHeight = present_parameters->BackBufferHeight;
-    local_parameters.BackBufferFormat = present_parameters->BackBufferFormat;
+    local_parameters.BackBufferFormat = d3dformat_from_wined3dformat(present_parameters->BackBufferFormat);
     local_parameters.BackBufferCount = present_parameters->BackBufferCount;
     local_parameters.MultiSampleType = present_parameters->MultiSampleType;
     local_parameters.SwapEffect = present_parameters->SwapEffect;
     local_parameters.hDeviceWindow = present_parameters->hDeviceWindow;
     local_parameters.Windowed = present_parameters->Windowed;
     local_parameters.EnableAutoDepthStencil = present_parameters->EnableAutoDepthStencil;
-    local_parameters.AutoDepthStencilFormat = present_parameters->AutoDepthStencilFormat;
+    local_parameters.AutoDepthStencilFormat = d3dformat_from_wined3dformat(present_parameters->AutoDepthStencilFormat);
     local_parameters.Flags = present_parameters->Flags;
     local_parameters.FullScreen_RefreshRateInHz = present_parameters->FullScreen_RefreshRateInHz;
     local_parameters.FullScreen_PresentationInterval = present_parameters->PresentationInterval;
@@ -2459,14 +2703,14 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateSwapChain(IWineD3DDevicePar
     /* Copy back the presentation parameters */
     present_parameters->BackBufferWidth = local_parameters.BackBufferWidth;
     present_parameters->BackBufferHeight = local_parameters.BackBufferHeight;
-    present_parameters->BackBufferFormat = local_parameters.BackBufferFormat;
+    present_parameters->BackBufferFormat = wined3dformat_from_d3dformat(local_parameters.BackBufferFormat);
     present_parameters->BackBufferCount = local_parameters.BackBufferCount;
     present_parameters->MultiSampleType = local_parameters.MultiSampleType;
     present_parameters->SwapEffect = local_parameters.SwapEffect;
     present_parameters->hDeviceWindow = local_parameters.hDeviceWindow;
     present_parameters->Windowed = local_parameters.Windowed;
     present_parameters->EnableAutoDepthStencil = local_parameters.EnableAutoDepthStencil;
-    present_parameters->AutoDepthStencilFormat = local_parameters.AutoDepthStencilFormat;
+    present_parameters->AutoDepthStencilFormat = wined3dformat_from_d3dformat(local_parameters.AutoDepthStencilFormat);
     present_parameters->Flags = local_parameters.Flags;
     present_parameters->FullScreen_RefreshRateInHz = local_parameters.FullScreen_RefreshRateInHz;
     present_parameters->PresentationInterval = local_parameters.FullScreen_PresentationInterval;
@@ -2481,6 +2725,7 @@ const IWineD3DDeviceParentVtbl d3d8_wined3d_device_parent_vtbl =
     device_parent_AddRef,
     device_parent_Release,
     /* IWineD3DDeviceParent methods */
+    device_parent_WineD3DDeviceCreated,
     device_parent_CreateSurface,
     device_parent_CreateRenderTarget,
     device_parent_CreateDepthStencilSurface,
index 72ccb3d..45d914b 100644 (file)
@@ -71,7 +71,9 @@ static ULONG WINAPI IDirect3D8Impl_Release(LPDIRECT3D8 iface) {
 
     if (ref == 0) {
         TRACE("Releasing wined3d %p\n", This->WineD3D);
+        EnterCriticalSection(&d3d8_cs);
         IWineD3D_Release(This->WineD3D);
+        LeaveCriticalSection(&d3d8_cs);
         HeapFree(GetProcessHeap(), 0, This);
     }
 
@@ -147,6 +149,9 @@ static HRESULT WINAPI IDirect3D8Impl_EnumAdapterModes (LPDIRECT3D8 iface, UINT A
     EnterCriticalSection(&d3d8_cs);
     hr = IWineD3D_EnumAdapterModes(This->WineD3D, Adapter, WINED3DFMT_UNKNOWN, Mode, (WINED3DDISPLAYMODE *) pMode);
     LeaveCriticalSection(&d3d8_cs);
+
+    if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
+
     return hr;
 }
 
@@ -158,6 +163,9 @@ static HRESULT WINAPI IDirect3D8Impl_GetAdapterDisplayMode (LPDIRECT3D8 iface, U
     EnterCriticalSection(&d3d8_cs);
     hr = IWineD3D_GetAdapterDisplayMode(This->WineD3D, Adapter, (WINED3DDISPLAYMODE *) pMode);
     LeaveCriticalSection(&d3d8_cs);
+
+    if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
+
     return hr;
 }
 
@@ -169,8 +177,8 @@ static HRESULT  WINAPI  IDirect3D8Impl_CheckDeviceType            (LPDIRECT3D8 i
     TRACE("(%p)->(%d, %d, %d, %d, %s)\n", This, Adapter, CheckType, DisplayFormat, BackBufferFormat, Windowed ? "true" : "false");
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IWineD3D_CheckDeviceType(This->WineD3D, Adapter, CheckType, DisplayFormat,
-                                    BackBufferFormat, Windowed);
+    hr = IWineD3D_CheckDeviceType(This->WineD3D, Adapter, CheckType, wined3dformat_from_d3dformat(DisplayFormat),
+            wined3dformat_from_d3dformat(BackBufferFormat), Windowed);
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
@@ -183,8 +191,8 @@ static HRESULT  WINAPI  IDirect3D8Impl_CheckDeviceFormat          (LPDIRECT3D8 i
     TRACE("(%p)->(%d, %d, %d, %08x, %d, %d)\n", This, Adapter, DeviceType, AdapterFormat, Usage, RType, CheckFormat);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IWineD3D_CheckDeviceFormat(This->WineD3D, Adapter, DeviceType, AdapterFormat,
-                                    Usage, RType, CheckFormat, SURFACE_OPENGL);
+    hr = IWineD3D_CheckDeviceFormat(This->WineD3D, Adapter, DeviceType, wined3dformat_from_d3dformat(AdapterFormat),
+            Usage, RType, wined3dformat_from_d3dformat(CheckFormat), SURFACE_OPENGL);
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
@@ -197,8 +205,8 @@ static HRESULT  WINAPI  IDirect3D8Impl_CheckDeviceMultiSampleType(LPDIRECT3D8 if
     TRACE("(%p)-<(%d, %d, %d, %s, %d)\n", This, Adapter, DeviceType, SurfaceFormat, Windowed ? "true" : "false", MultiSampleType);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IWineD3D_CheckDeviceMultiSampleType(This->WineD3D, Adapter, DeviceType, SurfaceFormat,
-                                               Windowed, (WINED3DMULTISAMPLE_TYPE) MultiSampleType, NULL);
+    hr = IWineD3D_CheckDeviceMultiSampleType(This->WineD3D, Adapter, DeviceType,
+            wined3dformat_from_d3dformat(SurfaceFormat), Windowed, (WINED3DMULTISAMPLE_TYPE) MultiSampleType, NULL);
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
@@ -211,8 +219,9 @@ static HRESULT  WINAPI  IDirect3D8Impl_CheckDepthStencilMatch(LPDIRECT3D8 iface,
     TRACE("(%p)-<(%d, %d, %d, %d, %d)\n", This, Adapter, DeviceType, AdapterFormat, RenderTargetFormat, DepthStencilFormat);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IWineD3D_CheckDepthStencilMatch(This->WineD3D, Adapter, DeviceType, AdapterFormat,
-                                           RenderTargetFormat, DepthStencilFormat);
+    hr = IWineD3D_CheckDepthStencilMatch(This->WineD3D, Adapter, DeviceType,
+            wined3dformat_from_d3dformat(AdapterFormat), wined3dformat_from_d3dformat(RenderTargetFormat),
+            wined3dformat_from_d3dformat(DepthStencilFormat));
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
@@ -316,8 +325,9 @@ static HRESULT WINAPI IDirect3D8Impl_CreateDevice(LPDIRECT3D8 iface, UINT Adapte
     object->lpVtbl = &Direct3DDevice8_Vtbl;
     object->device_parent_vtbl = &d3d8_wined3d_device_parent_vtbl;
     object->ref = 1;
-    object->shader_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, INITIAL_SHADER_HANDLE_TABLE_SIZE * sizeof(shader_handle));
-    object->shader_handle_table_size = INITIAL_SHADER_HANDLE_TABLE_SIZE;
+    object->handle_table.entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+            D3D8_INITIAL_HANDLE_TABLE_SIZE * sizeof(*object->handle_table.entries));
+    object->handle_table.table_size = D3D8_INITIAL_HANDLE_TABLE_SIZE;
     *ppReturnedDeviceInterface = (IDirect3DDevice8 *)object;
 
     /* Allocate an associated WineD3DDevice object */
@@ -336,7 +346,7 @@ static HRESULT WINAPI IDirect3D8Impl_CreateDevice(LPDIRECT3D8 iface, UINT Adapte
 
     localParameters.BackBufferWidth                             = pPresentationParameters->BackBufferWidth;
     localParameters.BackBufferHeight                            = pPresentationParameters->BackBufferHeight;
-    localParameters.BackBufferFormat                            = pPresentationParameters->BackBufferFormat;
+    localParameters.BackBufferFormat                            = wined3dformat_from_d3dformat(pPresentationParameters->BackBufferFormat);
     localParameters.BackBufferCount                             = pPresentationParameters->BackBufferCount;
     localParameters.MultiSampleType                             = pPresentationParameters->MultiSampleType;
     localParameters.MultiSampleQuality                          = 0; /* d3d9 only */
@@ -344,7 +354,7 @@ static HRESULT WINAPI IDirect3D8Impl_CreateDevice(LPDIRECT3D8 iface, UINT Adapte
     localParameters.hDeviceWindow                               = pPresentationParameters->hDeviceWindow;
     localParameters.Windowed                                    = pPresentationParameters->Windowed;
     localParameters.EnableAutoDepthStencil                      = pPresentationParameters->EnableAutoDepthStencil;
-    localParameters.AutoDepthStencilFormat                      = pPresentationParameters->AutoDepthStencilFormat;
+    localParameters.AutoDepthStencilFormat                      = wined3dformat_from_d3dformat(pPresentationParameters->AutoDepthStencilFormat);
     localParameters.Flags                                       = pPresentationParameters->Flags;
     localParameters.FullScreen_RefreshRateInHz                  = pPresentationParameters->FullScreen_RefreshRateInHz;
     localParameters.PresentationInterval                        = pPresentationParameters->FullScreen_PresentationInterval;
@@ -359,14 +369,14 @@ static HRESULT WINAPI IDirect3D8Impl_CreateDevice(LPDIRECT3D8 iface, UINT Adapte
 
     pPresentationParameters->BackBufferWidth                    = localParameters.BackBufferWidth;
     pPresentationParameters->BackBufferHeight                   = localParameters.BackBufferHeight;
-    pPresentationParameters->BackBufferFormat                   = localParameters.BackBufferFormat;
+    pPresentationParameters->BackBufferFormat                   = d3dformat_from_wined3dformat(localParameters.BackBufferFormat);
     pPresentationParameters->BackBufferCount                    = localParameters.BackBufferCount;
     pPresentationParameters->MultiSampleType                    = localParameters.MultiSampleType;
     pPresentationParameters->SwapEffect                         = localParameters.SwapEffect;
     pPresentationParameters->hDeviceWindow                      = localParameters.hDeviceWindow;
     pPresentationParameters->Windowed                           = localParameters.Windowed;
     pPresentationParameters->EnableAutoDepthStencil             = localParameters.EnableAutoDepthStencil;
-    pPresentationParameters->AutoDepthStencilFormat             = localParameters.AutoDepthStencilFormat;
+    pPresentationParameters->AutoDepthStencilFormat             = d3dformat_from_wined3dformat(localParameters.AutoDepthStencilFormat);
     pPresentationParameters->Flags                              = localParameters.Flags;
     pPresentationParameters->FullScreen_RefreshRateInHz         = localParameters.FullScreen_RefreshRateInHz;
     pPresentationParameters->FullScreen_PresentationInterval    = localParameters.PresentationInterval;
@@ -381,7 +391,9 @@ static HRESULT WINAPI IDirect3D8Impl_CreateDevice(LPDIRECT3D8 iface, UINT Adapte
     object->decls = HeapAlloc(GetProcessHeap(), 0, object->declArraySize * sizeof(*object->decls));
     if(!object->decls) {
         ERR("Out of memory\n");
+        EnterCriticalSection(&d3d8_cs);
         IWineD3DDevice_Release(object->WineD3DDevice);
+        LeaveCriticalSection(&d3d8_cs);
         HeapFree(GetProcessHeap(), 0, object);
         *ppReturnedDeviceInterface = NULL;
         hr = E_OUTOFMEMORY;
index c4bd833..8a0a155 100644 (file)
@@ -68,11 +68,17 @@ static ULONG WINAPI IDirect3DIndexBuffer8Impl_Release(LPDIRECT3DINDEXBUFFER8 ifa
 /* IDirect3DIndexBuffer8 IDirect3DResource8 Interface follow: */
 static HRESULT WINAPI IDirect3DIndexBuffer8Impl_GetDevice(LPDIRECT3DINDEXBUFFER8 iface, IDirect3DDevice8 **ppDevice) {
     IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface;
+    IWineD3DDevice *wined3d_device;
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IDirect3DResource8Impl_GetDevice((LPDIRECT3DRESOURCE8) This, ppDevice);
+    hr = IWineD3DIndexBuffer_GetDevice(This->wineD3DIndexBuffer, &wined3d_device);
+    if (SUCCEEDED(hr))
+    {
+        IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
+        IWineD3DDevice_Release(wined3d_device);
+    }
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
@@ -183,6 +189,9 @@ static HRESULT WINAPI IDirect3DIndexBuffer8Impl_GetDesc(LPDIRECT3DINDEXBUFFER8 i
     EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DIndexBuffer_GetDesc(This->wineD3DIndexBuffer, (WINED3DINDEXBUFFER_DESC *) pDesc);
     LeaveCriticalSection(&d3d8_cs);
+
+    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(pDesc->Format);
+
     return hr;
 }
 
index 5cfb0ca..ae8d15f 100644 (file)
@@ -56,7 +56,9 @@ static ULONG WINAPI IDirect3DPixelShader8Impl_Release(IDirect3DPixelShader8 * if
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
+        EnterCriticalSection(&d3d8_cs);
         IWineD3DPixelShader_Release(This->wineD3DPixelShader);
+        LeaveCriticalSection(&d3d8_cs);
         HeapFree(GetProcessHeap(), 0, This);
     }
     return ref;
diff --git a/reactos/dll/directx/wine/d3d8/resource.c b/reactos/dll/directx/wine/d3d8/resource.c
deleted file mode 100644 (file)
index 7cf4089..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * IDirect3DResource8 implementation
- *
- * Copyright 2005 Oliver Stieber
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-#include "d3d8_private.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
-
-/* IDirect3DResource8 IUnknown parts follow: */
-static HRESULT WINAPI IDirect3DResource8Impl_QueryInterface(LPDIRECT3DRESOURCE8 iface, REFIID riid, LPVOID* ppobj) {
-    IDirect3DResource8Impl *This = (IDirect3DResource8Impl *)iface;
-
-    if (IsEqualGUID(riid, &IID_IUnknown)
-        || IsEqualGUID(riid, &IID_IDirect3DResource8)) {
-        IUnknown_AddRef(iface);
-        *ppobj = This;
-        return S_OK;
-    }
-
-    WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
-    *ppobj = NULL;
-    return E_NOINTERFACE;
-}
-
-static ULONG WINAPI IDirect3DResource8Impl_AddRef(LPDIRECT3DRESOURCE8 iface) {
-    IDirect3DResource8Impl *This = (IDirect3DResource8Impl *)iface;
-    ULONG ref = InterlockedIncrement(&This->ref);
-
-    TRACE("(%p) : AddRef from %d\n", This, ref - 1);
-
-    return ref;
-}
-
-static ULONG WINAPI IDirect3DResource8Impl_Release(LPDIRECT3DRESOURCE8 iface) {
-    IDirect3DResource8Impl *This = (IDirect3DResource8Impl *)iface;
-    ULONG ref = InterlockedDecrement(&This->ref);
-
-    TRACE("(%p) : ReleaseRef to %d\n", This, ref);
-
-    if (ref == 0) {
-        IWineD3DResource_Release(This->wineD3DResource);
-        HeapFree(GetProcessHeap(), 0, This);
-    }
-    return ref;
-}
-
-/* IDirect3DResource8 Interface follow: */
-HRESULT WINAPI IDirect3DResource8Impl_GetDevice(LPDIRECT3DRESOURCE8 iface, IDirect3DDevice8** ppDevice) {
-    IDirect3DResource8Impl *This = (IDirect3DResource8Impl *)iface;
-    IWineD3DDevice *myDevice = NULL;
-
-    TRACE("(%p) Relay\n", This);
-
-    IWineD3DResource_GetDevice(This->wineD3DResource, &myDevice);
-    IWineD3DDevice_GetParent(myDevice, (IUnknown **)ppDevice);
-    IWineD3DDevice_Release(myDevice);
-    return D3D_OK;
-}
-
-static HRESULT WINAPI IDirect3DResource8Impl_SetPrivateData(LPDIRECT3DRESOURCE8 iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
-    IDirect3DResource8Impl *This = (IDirect3DResource8Impl *)iface;
-    TRACE("(%p) Relay\n", This);
-    return IWineD3DResource_SetPrivateData(This->wineD3DResource, refguid, pData, SizeOfData, Flags);
-}
-
-static HRESULT WINAPI IDirect3DResource8Impl_GetPrivateData(LPDIRECT3DRESOURCE8 iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) {
-    IDirect3DResource8Impl *This = (IDirect3DResource8Impl *)iface;
-    TRACE("(%p) Relay\n", This);
-    return IWineD3DResource_GetPrivateData(This->wineD3DResource, refguid, pData, pSizeOfData);
-}
-
-static HRESULT WINAPI IDirect3DResource8Impl_FreePrivateData(LPDIRECT3DRESOURCE8 iface, REFGUID refguid) {
-    IDirect3DResource8Impl *This = (IDirect3DResource8Impl *)iface;
-    TRACE("(%p) Relay\n", This);
-    return IWineD3DResource_FreePrivateData(This->wineD3DResource, refguid);
-}
-
-static DWORD  WINAPI IDirect3DResource8Impl_SetPriority(LPDIRECT3DRESOURCE8 iface, DWORD PriorityNew) {
-    IDirect3DResource8Impl *This = (IDirect3DResource8Impl *)iface;
-    TRACE("(%p) Relay\n", This);
-    return IWineD3DResource_SetPriority(This->wineD3DResource, PriorityNew);
-}
-
-static DWORD WINAPI IDirect3DResource8Impl_GetPriority(LPDIRECT3DRESOURCE8 iface) {
-    IDirect3DResource8Impl *This = (IDirect3DResource8Impl *)iface;
-    TRACE("(%p) Relay\n", This);
-    return IWineD3DResource_GetPriority(This->wineD3DResource);
-}
-
-static void WINAPI IDirect3DResource8Impl_PreLoad(LPDIRECT3DRESOURCE8 iface) {
-    IDirect3DResource8Impl *This = (IDirect3DResource8Impl *)iface;
-    TRACE("(%p) Relay\n", This);
-    IWineD3DResource_PreLoad(This->wineD3DResource);
-    return;
-}
-
-static D3DRESOURCETYPE WINAPI IDirect3DResource8Impl_GetType(LPDIRECT3DRESOURCE8 iface) {
-    IDirect3DResource8Impl *This = (IDirect3DResource8Impl *)iface;
-    TRACE("(%p) Relay\n", This);
-    return IWineD3DResource_GetType(This->wineD3DResource);
-}
-
-const IDirect3DResource8Vtbl Direct3DResource8_Vtbl =
-{
-    IDirect3DResource8Impl_QueryInterface,
-    IDirect3DResource8Impl_AddRef,
-    IDirect3DResource8Impl_Release,
-    IDirect3DResource8Impl_GetDevice,
-    IDirect3DResource8Impl_SetPrivateData,
-    IDirect3DResource8Impl_GetPrivateData,
-    IDirect3DResource8Impl_FreePrivateData,
-    IDirect3DResource8Impl_SetPriority,
-    IDirect3DResource8Impl_GetPriority,
-    IDirect3DResource8Impl_PreLoad,
-    IDirect3DResource8Impl_GetType
-};
index ac2cdbe..ace9211 100644 (file)
@@ -58,7 +58,9 @@ static ULONG WINAPI IDirect3DStateBlock8Impl_Release(IDirect3DStateBlock8 *iface
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
+        EnterCriticalSection(&d3d8_cs);
         IWineD3DStateBlock_Release(This->wineD3DStateBlock);
+        LeaveCriticalSection(&d3d8_cs);
         HeapFree(GetProcessHeap(), 0, This);
     }
     return ref;
@@ -67,20 +69,53 @@ static ULONG WINAPI IDirect3DStateBlock8Impl_Release(IDirect3DStateBlock8 *iface
 /* IDirect3DStateBlock8 Interface follow: */
 static HRESULT WINAPI IDirect3DStateBlock8Impl_GetDevice(IDirect3DStateBlock8 *iface, IDirect3DDevice8 **ppDevice) {
     IDirect3DStateBlock8Impl *This = (IDirect3DStateBlock8Impl *)iface;
-    TRACE("(%p) Relay\n", This); 
-    return IDirect3DResource8Impl_GetDevice((LPDIRECT3DRESOURCE8) This, ppDevice);
+    IWineD3DDevice *wined3d_device;
+    HRESULT hr;
+
+    TRACE("(%p) Relay\n", This);
+
+    EnterCriticalSection(&d3d8_cs);
+
+    hr = IWineD3DStateBlock_GetDevice(This->wineD3DStateBlock, &wined3d_device);
+    if (SUCCEEDED(hr))
+    {
+        IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
+        IWineD3DDevice_Release(wined3d_device);
+    }
+
+    LeaveCriticalSection(&d3d8_cs);
+
+    return hr;
 }
 
 static HRESULT WINAPI IDirect3DStateBlock8Impl_Capture(IDirect3DStateBlock8 *iface) {
     IDirect3DStateBlock8Impl *This = (IDirect3DStateBlock8Impl *)iface;
-    TRACE("(%p) Relay\n", This); 
-    return IWineD3DStateBlock_Capture(This->wineD3DStateBlock);
+    HRESULT hr;
+
+    TRACE("(%p) Relay\n", This);
+
+    EnterCriticalSection(&d3d8_cs);
+
+    hr = IWineD3DStateBlock_Capture(This->wineD3DStateBlock);
+
+    LeaveCriticalSection(&d3d8_cs);
+
+    return hr;
 }
 
 static HRESULT WINAPI IDirect3DStateBlock8Impl_Apply(IDirect3DStateBlock8 *iface) {
     IDirect3DStateBlock8Impl *This = (IDirect3DStateBlock8Impl *)iface;
-    TRACE("(%p) Relay\n", This); 
-    return IWineD3DStateBlock_Apply(This->wineD3DStateBlock);
+    HRESULT hr;
+
+    TRACE("(%p) Relay\n", This);
+
+    EnterCriticalSection(&d3d8_cs);
+
+    hr = IWineD3DStateBlock_Apply(This->wineD3DStateBlock);
+
+    LeaveCriticalSection(&d3d8_cs);
+
+    return hr;
 }
 
 const IDirect3DStateBlock8Vtbl Direct3DStateBlock8_Vtbl =
index 0d06da2..4b382ec 100644 (file)
@@ -90,11 +90,17 @@ static ULONG WINAPI IDirect3DSurface8Impl_Release(LPDIRECT3DSURFACE8 iface) {
 /* IDirect3DSurface8 IDirect3DResource8 Interface follow: */
 static HRESULT WINAPI IDirect3DSurface8Impl_GetDevice(LPDIRECT3DSURFACE8 iface, IDirect3DDevice8 **ppDevice) {
     IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
+    IWineD3DDevice *wined3d_device;
     HRESULT hr;
     TRACE("(%p)->(%p)\n", This, ppDevice);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IDirect3DResource8Impl_GetDevice((LPDIRECT3DRESOURCE8) This, ppDevice);
+    hr = IWineD3DSurface_GetDevice(This->wineD3DSurface, &wined3d_device);
+    if (SUCCEEDED(hr))
+    {
+        IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
+        IWineD3DDevice_Release(wined3d_device);
+    }
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
@@ -167,6 +173,9 @@ static HRESULT WINAPI IDirect3DSurface8Impl_GetDesc(LPDIRECT3DSURFACE8 iface, D3
     EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DSurface_GetDesc(This->wineD3DSurface, &wined3ddesc);
     LeaveCriticalSection(&d3d8_cs);
+
+    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(pDesc->Format);
+
     return hr;
 }
 
index 03f26d5..c1bb91e 100644 (file)
@@ -69,10 +69,16 @@ static ULONG WINAPI IDirect3DTexture8Impl_Release(LPDIRECT3DTEXTURE8 iface) {
 /* IDirect3DTexture8 IDirect3DResource8 Interface follow: */
 static HRESULT WINAPI IDirect3DTexture8Impl_GetDevice(LPDIRECT3DTEXTURE8 iface, IDirect3DDevice8 **ppDevice) {
     IDirect3DTexture8Impl *This = (IDirect3DTexture8Impl *)iface;
+    IWineD3DDevice *wined3d_device;
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
     EnterCriticalSection(&d3d8_cs);
-    hr = IDirect3DResource8Impl_GetDevice((LPDIRECT3DRESOURCE8) This, ppDevice);
+    hr = IWineD3DTexture_GetDevice(This->wineD3DTexture, &wined3d_device);
+    if (SUCCEEDED(hr))
+    {
+        IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
+        IWineD3DDevice_Release(wined3d_device);
+    }
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
@@ -208,6 +214,9 @@ static HRESULT WINAPI IDirect3DTexture8Impl_GetLevelDesc(LPDIRECT3DTEXTURE8 ifac
     EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DTexture_GetLevelDesc(This->wineD3DTexture, Level, &wined3ddesc);
     LeaveCriticalSection(&d3d8_cs);
+
+    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(pDesc->Format);
+
     return hr;
 }
 
index 5dda94f..74d6dca 100644 (file)
@@ -58,7 +58,7 @@ static ULONG WINAPI IDirect3DVertexBuffer8Impl_Release(LPDIRECT3DVERTEXBUFFER8 i
 
     if (ref == 0) {
         EnterCriticalSection(&d3d8_cs);
-        IWineD3DVertexBuffer_Release(This->wineD3DVertexBuffer);
+        IWineD3DBuffer_Release(This->wineD3DVertexBuffer);
         LeaveCriticalSection(&d3d8_cs);
         IUnknown_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
@@ -70,11 +70,17 @@ static ULONG WINAPI IDirect3DVertexBuffer8Impl_Release(LPDIRECT3DVERTEXBUFFER8 i
 /* IDirect3DVertexBuffer8 IDirect3DResource8 Interface follow: */
 static HRESULT WINAPI IDirect3DVertexBuffer8Impl_GetDevice(LPDIRECT3DVERTEXBUFFER8 iface, IDirect3DDevice8 **ppDevice) {
     IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface;
+    IWineD3DDevice *wined3d_device;
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IDirect3DResource8Impl_GetDevice((LPDIRECT3DRESOURCE8) This, ppDevice);
+    hr = IWineD3DBuffer_GetDevice(This->wineD3DVertexBuffer, &wined3d_device);
+    if (SUCCEEDED(hr))
+    {
+        IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
+        IWineD3DDevice_Release(wined3d_device);
+    }
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
@@ -85,7 +91,7 @@ static HRESULT WINAPI IDirect3DVertexBuffer8Impl_SetPrivateData(LPDIRECT3DVERTEX
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IWineD3DVertexBuffer_SetPrivateData(This->wineD3DVertexBuffer, refguid, pData, SizeOfData, Flags);
+    hr = IWineD3DBuffer_SetPrivateData(This->wineD3DVertexBuffer, refguid, pData, SizeOfData, Flags);
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
@@ -96,7 +102,7 @@ static HRESULT WINAPI IDirect3DVertexBuffer8Impl_GetPrivateData(LPDIRECT3DVERTEX
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IWineD3DVertexBuffer_GetPrivateData(This->wineD3DVertexBuffer, refguid, pData, pSizeOfData);
+    hr = IWineD3DBuffer_GetPrivateData(This->wineD3DVertexBuffer, refguid, pData, pSizeOfData);
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
@@ -107,7 +113,7 @@ static HRESULT WINAPI IDirect3DVertexBuffer8Impl_FreePrivateData(LPDIRECT3DVERTE
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IWineD3DVertexBuffer_FreePrivateData(This->wineD3DVertexBuffer, refguid);
+    hr = IWineD3DBuffer_FreePrivateData(This->wineD3DVertexBuffer, refguid);
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
@@ -118,7 +124,7 @@ static DWORD WINAPI IDirect3DVertexBuffer8Impl_SetPriority(LPDIRECT3DVERTEXBUFFE
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    ret = IWineD3DVertexBuffer_SetPriority(This->wineD3DVertexBuffer, PriorityNew);
+    ret = IWineD3DBuffer_SetPriority(This->wineD3DVertexBuffer, PriorityNew);
     LeaveCriticalSection(&d3d8_cs);
     return ret;
 }
@@ -129,7 +135,7 @@ static DWORD WINAPI IDirect3DVertexBuffer8Impl_GetPriority(LPDIRECT3DVERTEXBUFFE
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    ret = IWineD3DVertexBuffer_GetPriority(This->wineD3DVertexBuffer);
+    ret = IWineD3DBuffer_GetPriority(This->wineD3DVertexBuffer);
     LeaveCriticalSection(&d3d8_cs);
     return ret;
 }
@@ -139,7 +145,7 @@ static void WINAPI IDirect3DVertexBuffer8Impl_PreLoad(LPDIRECT3DVERTEXBUFFER8 if
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    IWineD3DVertexBuffer_PreLoad(This->wineD3DVertexBuffer);
+    IWineD3DBuffer_PreLoad(This->wineD3DVertexBuffer);
     LeaveCriticalSection(&d3d8_cs);
 }
 
@@ -149,7 +155,7 @@ static D3DRESOURCETYPE WINAPI IDirect3DVertexBuffer8Impl_GetType(LPDIRECT3DVERTE
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    type = IWineD3DVertexBuffer_GetType(This->wineD3DVertexBuffer);
+    type = IWineD3DBuffer_GetType(This->wineD3DVertexBuffer);
     LeaveCriticalSection(&d3d8_cs);
     return type;
 }
@@ -161,7 +167,7 @@ static HRESULT WINAPI IDirect3DVertexBuffer8Impl_Lock(LPDIRECT3DVERTEXBUFFER8 if
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IWineD3DVertexBuffer_Lock(This->wineD3DVertexBuffer, OffsetToLock, SizeToLock, ppbData, Flags);
+    hr = IWineD3DBuffer_Map(This->wineD3DVertexBuffer, OffsetToLock, SizeToLock, ppbData, Flags);
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
@@ -172,7 +178,7 @@ static HRESULT WINAPI IDirect3DVertexBuffer8Impl_Unlock(LPDIRECT3DVERTEXBUFFER8
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IWineD3DVertexBuffer_Unlock(This->wineD3DVertexBuffer);
+    hr = IWineD3DBuffer_Unmap(This->wineD3DVertexBuffer);
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
@@ -183,8 +189,11 @@ static HRESULT WINAPI IDirect3DVertexBuffer8Impl_GetDesc(LPDIRECT3DVERTEXBUFFER8
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IWineD3DVertexBuffer_GetDesc(This->wineD3DVertexBuffer, (WINED3DVERTEXBUFFER_DESC *) pDesc);
+    hr = IWineD3DBuffer_GetDesc(This->wineD3DVertexBuffer, (WINED3DVERTEXBUFFER_DESC *)pDesc);
     LeaveCriticalSection(&d3d8_cs);
+
+    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(pDesc->Format);
+
     return hr;
 }
 
index debeca0..e9d56d0 100644 (file)
@@ -61,7 +61,9 @@ static ULONG WINAPI IDirect3DVertexDeclaration8Impl_Release(IDirect3DVertexDecla
     TRACE("(%p) : Releasing to %d\n", This, ref_count);
 
     if (!ref_count) {
+        EnterCriticalSection(&d3d8_cs);
         IWineD3DVertexDeclaration_Release(This->wined3d_vertex_declaration);
+        LeaveCriticalSection(&d3d8_cs);
         HeapFree(GetProcessHeap(), 0, This->elements);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -226,7 +228,8 @@ void load_local_constants(const DWORD *d3d8_elements, IWineD3DVertexShader *wine
 }
 
 /* NOTE: Make sure these are in the correct numerical order. (see /include/wined3d_types.h) */
-static const size_t wined3d_type_sizes[WINED3DDECLTYPE_UNUSED] = {
+static const size_t wined3d_type_sizes[] =
+{
     /*WINED3DDECLTYPE_FLOAT1*/    1 * sizeof(float),
     /*WINED3DDECLTYPE_FLOAT2*/    2 * sizeof(float),
     /*WINED3DDECLTYPE_FLOAT3*/    3 * sizeof(float),
@@ -246,6 +249,27 @@ static const size_t wined3d_type_sizes[WINED3DDECLTYPE_UNUSED] = {
     /*WINED3DDECLTYPE_FLOAT16_4*/ 4 * sizeof(short int)
 };
 
+static const WINED3DFORMAT wined3d_format_lookup[] =
+{
+    /*WINED3DDECLTYPE_FLOAT1*/    WINED3DFMT_R32_FLOAT,
+    /*WINED3DDECLTYPE_FLOAT2*/    WINED3DFMT_R32G32_FLOAT,
+    /*WINED3DDECLTYPE_FLOAT3*/    WINED3DFMT_R32G32B32_FLOAT,
+    /*WINED3DDECLTYPE_FLOAT4*/    WINED3DFMT_R32G32B32A32_FLOAT,
+    /*WINED3DDECLTYPE_D3DCOLOR*/  WINED3DFMT_A8R8G8B8,
+    /*WINED3DDECLTYPE_UBYTE4*/    WINED3DFMT_R8G8B8A8_UINT,
+    /*WINED3DDECLTYPE_SHORT2*/    WINED3DFMT_R16G16_SINT,
+    /*WINED3DDECLTYPE_SHORT4*/    WINED3DFMT_R16G16B16A16_SINT,
+    /*WINED3DDECLTYPE_UBYTE4N*/   WINED3DFMT_R8G8B8A8_UNORM,
+    /*WINED3DDECLTYPE_SHORT2N*/   WINED3DFMT_R16G16_SNORM,
+    /*WINED3DDECLTYPE_SHORT4N*/   WINED3DFMT_R16G16B16A16_SNORM,
+    /*WINED3DDECLTYPE_USHORT2N*/  WINED3DFMT_R16G16_UNORM,
+    /*WINED3DDECLTYPE_USHORT4N*/  WINED3DFMT_R16G16B16A16_UNORM,
+    /*WINED3DDECLTYPE_UDEC3*/     WINED3DFMT_R10G10B10A2_UINT,
+    /*WINED3DDECLTYPE_DEC3N*/     WINED3DFMT_R10G10B10A2_SNORM,
+    /*WINED3DDECLTYPE_FLOAT16_2*/ WINED3DFMT_R16G16_FLOAT,
+    /*WINED3DDECLTYPE_FLOAT16_4*/ WINED3DFMT_R16G16B16A16_FLOAT,
+};
+
 typedef struct {
     BYTE usage;
     BYTE usage_idx;
@@ -300,13 +324,13 @@ UINT convert_to_wined3d_declaration(const DWORD *d3d8_elements, DWORD *d3d8_elem
             TRACE("Adding element %d:\n", element_count);
 
             element = *wined3d_elements + element_count++;
-            element->Stream = stream;
-            element->Method = WINED3DDECLMETHOD_DEFAULT;
-            element->Usage = wined3d_usage_lookup[reg].usage;
-            element->UsageIndex = wined3d_usage_lookup[reg].usage_idx;
-            element->Type = type;
-            element->Offset = offset;
-            element->Reg = reg;
+            element->format = wined3d_format_lookup[type];
+            element->input_slot = stream;
+            element->offset = offset;
+            element->output_slot = reg;
+            element->method = WINED3DDECLMETHOD_DEFAULT;
+            element->usage = wined3d_usage_lookup[reg].usage;
+            element->usage_idx = wined3d_usage_lookup[reg].usage_idx;
 
             offset += wined3d_type_sizes[type];
         } else if (token_type == D3DVSD_TOKEN_STREAMDATA && (token_type & 0x10000000)) {
@@ -322,11 +346,6 @@ UINT convert_to_wined3d_declaration(const DWORD *d3d8_elements, DWORD *d3d8_elem
         token += parse_token(token);
     }
 
-    /* END */
-    element = *wined3d_elements + element_count++;
-    element->Stream = 0xFF;
-    element->Type = WINED3DDECLTYPE_UNUSED;
-
     *d3d8_elements_size = (++token - d3d8_elements) * sizeof(DWORD);
 
     return element_count;
index 8cd822b..4ea8b52 100644 (file)
@@ -57,7 +57,12 @@ static ULONG WINAPI IDirect3DVertexShader8Impl_Release(IDirect3DVertexShader8 *i
 
     if (ref == 0) {
         IDirect3DVertexDeclaration8_Release(This->vertex_declaration);
-        if (This->wineD3DVertexShader) IWineD3DVertexShader_Release(This->wineD3DVertexShader);
+        if (This->wineD3DVertexShader)
+        {
+            EnterCriticalSection(&d3d8_cs);
+            IWineD3DVertexShader_Release(This->wineD3DVertexShader);
+            LeaveCriticalSection(&d3d8_cs);
+        }
         HeapFree(GetProcessHeap(), 0, This);
     }
     return ref;
index 87c4172..474aad8 100644 (file)
@@ -167,6 +167,9 @@ static HRESULT WINAPI IDirect3DVolume8Impl_GetDesc(LPDIRECT3DVOLUME8 iface, D3DV
     EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DVolume_GetDesc(This->wineD3DVolume, &wined3ddesc);
     LeaveCriticalSection(&d3d8_cs);
+
+    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(pDesc->Format);
+
     return hr;
 }
 
index fc35f3d..098827a 100644 (file)
@@ -69,11 +69,17 @@ static ULONG WINAPI IDirect3DVolumeTexture8Impl_Release(LPDIRECT3DVOLUMETEXTURE8
 /* IDirect3DVolumeTexture8 IDirect3DResource8 Interface follow: */
 static HRESULT WINAPI IDirect3DVolumeTexture8Impl_GetDevice(LPDIRECT3DVOLUMETEXTURE8 iface, IDirect3DDevice8 **ppDevice) {
     IDirect3DVolumeTexture8Impl *This = (IDirect3DVolumeTexture8Impl *)iface;
+    IWineD3DDevice *wined3d_device;
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IDirect3DResource8Impl_GetDevice((LPDIRECT3DRESOURCE8) This, ppDevice);
+    hr = IWineD3DVolumeTexture_GetDevice(This->wineD3DVolumeTexture, &wined3d_device);
+    if (SUCCEEDED(hr))
+    {
+        IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
+        IWineD3DDevice_Release(wined3d_device);
+    }
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
@@ -209,6 +215,9 @@ static HRESULT WINAPI IDirect3DVolumeTexture8Impl_GetLevelDesc(LPDIRECT3DVOLUMET
     EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DVolumeTexture_GetLevelDesc(This->wineD3DVolumeTexture, Level, &wined3ddesc);
     LeaveCriticalSection(&d3d8_cs);
+
+    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(pDesc->Format);
+
     return hr;
 }
 
diff --git a/reactos/dll/directx/wine/d3d9/basetexture.c b/reactos/dll/directx/wine/d3d9/basetexture.c
deleted file mode 100644 (file)
index b349f51..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * IDirect3DBaseTexture9 implementation
- *
- * Copyright 2002-2004 Jason Edmeades
- *                     Raphael Junqueira
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-#include "d3d9_private.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
-
-/* IDirect3DBaseTexture9 IUnknown parts follow: */
-static HRESULT WINAPI IDirect3DBaseTexture9Impl_QueryInterface(LPDIRECT3DBASETEXTURE9 iface, REFIID riid, LPVOID* ppobj) {
-    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
-    TRACE("(%p) Relay\n" , This);
-    if (IsEqualGUID(riid, &IID_IUnknown)
-        || IsEqualGUID(riid, &IID_IDirect3DResource9)
-        || IsEqualGUID(riid, &IID_IDirect3DBaseTexture9)) {
-        IDirect3DBaseTexture9_AddRef(iface);
-        *ppobj = This;
-        return S_OK;
-    }
-
-    WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
-    *ppobj = NULL;
-    return E_NOINTERFACE;
-}
-
-static ULONG WINAPI IDirect3DBaseTexture9Impl_AddRef(LPDIRECT3DBASETEXTURE9 iface) {
-    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
-    ULONG ref = InterlockedIncrement(&This->ref);
-
-    TRACE("(%p) : AddRef from %d\n", This, ref - 1);
-
-    return ref;
-}
-
-static ULONG WINAPI IDirect3DBaseTexture9Impl_Release(LPDIRECT3DBASETEXTURE9 iface) {
-    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
-    ULONG ref = InterlockedDecrement(&This->ref);
-
-    TRACE("(%p) : ReleaseRef to %d\n", This, ref);
-
-    if (ref == 0) {
-        IWineD3DBaseTexture_Release(This->wineD3DBaseTexture);
-        HeapFree(GetProcessHeap(), 0, This);
-    }
-    return ref;
-}
-
-/* IDirect3DBaseTexture9 IDirect3DResource9 Interface follow: */
-static HRESULT WINAPI IDirect3DBaseTexture9Impl_GetDevice(LPDIRECT3DBASETEXTURE9 iface, IDirect3DDevice9** ppDevice) {
-    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
-    TRACE("(%p) Relay\n" , This);
-    return IDirect3DResource9Impl_GetDevice((LPDIRECT3DRESOURCE9) This, ppDevice);
-}
-
-static HRESULT WINAPI IDirect3DBaseTexture9Impl_SetPrivateData(LPDIRECT3DBASETEXTURE9 iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
-    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
-    TRACE("(%p) Relay\n" , This);
-    return IWineD3DBaseTexture_SetPrivateData(This->wineD3DBaseTexture, refguid, pData, SizeOfData, Flags);
-}
-
-static HRESULT WINAPI IDirect3DBaseTexture9Impl_GetPrivateData(LPDIRECT3DBASETEXTURE9 iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) {
-    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
-    TRACE("(%p) Relay\n" , This);
-    return IWineD3DBaseTexture_GetPrivateData(This->wineD3DBaseTexture, refguid, pData, pSizeOfData);
-}
-
-static HRESULT WINAPI IDirect3DBaseTexture9Impl_FreePrivateData(LPDIRECT3DBASETEXTURE9 iface, REFGUID refguid) {
-    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
-    TRACE("(%p) Relay\n" , This);
-    return IWineD3DBaseTexture_FreePrivateData(This->wineD3DBaseTexture, refguid);
-}
-
-static DWORD WINAPI IDirect3DBaseTexture9Impl_SetPriority(LPDIRECT3DBASETEXTURE9 iface, DWORD PriorityNew) {
-    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
-    TRACE("(%p) Relay\n" , This);
-    return IWineD3DBaseTexture_SetPriority(This->wineD3DBaseTexture, PriorityNew);
-}
-
-static DWORD WINAPI IDirect3DBaseTexture9Impl_GetPriority(LPDIRECT3DBASETEXTURE9 iface) {
-    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
-    TRACE("(%p) Relay\n" , This);
-    return IWineD3DBaseTexture_GetPriority(This->wineD3DBaseTexture);
-}
-
-static void WINAPI IDirect3DBaseTexture9Impl_PreLoad(LPDIRECT3DBASETEXTURE9 iface) {
-    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
-    TRACE("(%p) Relay\n" , This);
-    IWineD3DBaseTexture_PreLoad(This->wineD3DBaseTexture);
-    return ;
-}
-
-static D3DRESOURCETYPE WINAPI IDirect3DBaseTexture9Impl_GetType(LPDIRECT3DBASETEXTURE9 iface) {
-    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
-    TRACE("(%p) Relay\n" , This);
-    return IWineD3DBaseTexture_GetType(This->wineD3DBaseTexture);
-}
-
-/* IDirect3DBaseTexture9 Interface follow: */
-static DWORD  WINAPI IDirect3DBaseTexture9Impl_SetLOD(LPDIRECT3DBASETEXTURE9 iface, DWORD LODNew) {
-    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
-    TRACE("(%p) Relay\n" , This);
-    return IWineD3DBaseTexture_SetLOD(This->wineD3DBaseTexture, LODNew);
-}
-
-DWORD WINAPI IDirect3DBaseTexture9Impl_GetLOD(LPDIRECT3DBASETEXTURE9 iface) {
-    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
-    TRACE("(%p) Relay\n" , This);
-    return IWineD3DBaseTexture_GetLOD(This->wineD3DBaseTexture);
-}
-
-static DWORD WINAPI IDirect3DBaseTexture9Impl_GetLevelCount(LPDIRECT3DBASETEXTURE9 iface) {
-    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
-    TRACE("(%p) Relay\n" , This);
-    return IWineD3DBaseTexture_GetLevelCount(This->wineD3DBaseTexture);
-}
-
-static HRESULT WINAPI IDirect3DBaseTexture9Impl_SetAutoGenFilterType(LPDIRECT3DBASETEXTURE9 iface, D3DTEXTUREFILTERTYPE FilterType) {
-    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
-    TRACE("(%p) Relay\n" , This);
-    return IWineD3DBaseTexture_SetAutoGenFilterType(This->wineD3DBaseTexture, (WINED3DTEXTUREFILTERTYPE) FilterType);
-}
-
-static D3DTEXTUREFILTERTYPE WINAPI IDirect3DBaseTexture9Impl_GetAutoGenFilterType(LPDIRECT3DBASETEXTURE9 iface) {
-    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
-    TRACE("(%p) Relay\n" , This);
-    return (D3DTEXTUREFILTERTYPE) IWineD3DBaseTexture_GetAutoGenFilterType(This->wineD3DBaseTexture);
-}
-
-static void WINAPI IDirect3DBaseTexture9Impl_GenerateMipSubLevels(LPDIRECT3DBASETEXTURE9 iface) {
-    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
-    TRACE("(%p) Relay\n" , This);
-    IWineD3DBaseTexture_GenerateMipSubLevels(This->wineD3DBaseTexture);
-}
-
-const IDirect3DBaseTexture9Vtbl Direct3DBaseTexture9_Vtbl =
-{
-    IDirect3DBaseTexture9Impl_QueryInterface,
-    IDirect3DBaseTexture9Impl_AddRef,
-    IDirect3DBaseTexture9Impl_Release,
-    IDirect3DBaseTexture9Impl_GetDevice,
-    IDirect3DBaseTexture9Impl_SetPrivateData,
-    IDirect3DBaseTexture9Impl_GetPrivateData,
-    IDirect3DBaseTexture9Impl_FreePrivateData,
-    IDirect3DBaseTexture9Impl_SetPriority,
-    IDirect3DBaseTexture9Impl_GetPriority,
-    IDirect3DBaseTexture9Impl_PreLoad,
-    IDirect3DBaseTexture9Impl_GetType,
-    IDirect3DBaseTexture9Impl_SetLOD,
-    IDirect3DBaseTexture9Impl_GetLOD,
-    IDirect3DBaseTexture9Impl_GetLevelCount,
-    IDirect3DBaseTexture9Impl_SetAutoGenFilterType,
-    IDirect3DBaseTexture9Impl_GetAutoGenFilterType,
-    IDirect3DBaseTexture9Impl_GenerateMipSubLevels   
-};
index 533770f..c4b4860 100644 (file)
@@ -74,11 +74,17 @@ static ULONG WINAPI IDirect3DCubeTexture9Impl_Release(LPDIRECT3DCUBETEXTURE9 ifa
 /* IDirect3DCubeTexture9 IDirect3DResource9 Interface follow: */
 static HRESULT WINAPI IDirect3DCubeTexture9Impl_GetDevice(LPDIRECT3DCUBETEXTURE9 iface, IDirect3DDevice9** ppDevice) {
     IDirect3DCubeTexture9Impl *This = (IDirect3DCubeTexture9Impl *)iface;
+    IWineD3DDevice *wined3d_device;
     HRESULT hr;
     TRACE("(%p) Relay\n" , This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IDirect3DResource9Impl_GetDevice((LPDIRECT3DRESOURCE9) This, ppDevice);
+    hr = IWineD3DCubeTexture_GetDevice(This->wineD3DCubeTexture, &wined3d_device);
+    if (SUCCEEDED(hr))
+    {
+        IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
+        IWineD3DDevice_Release(wined3d_device);
+    }
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -176,7 +182,7 @@ static DWORD WINAPI IDirect3DCubeTexture9Impl_GetLOD(LPDIRECT3DCUBETEXTURE9 ifac
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    ret = IDirect3DBaseTexture9Impl_GetLOD((LPDIRECT3DBASETEXTURE9) This);
+    ret = IWineD3DCubeTexture_GetLOD(This->wineD3DCubeTexture);
     LeaveCriticalSection(&d3d9_cs);
     return ret;
 }
@@ -228,12 +234,13 @@ static HRESULT WINAPI IDirect3DCubeTexture9Impl_GetLevelDesc(LPDIRECT3DCUBETEXTU
     IDirect3DCubeTexture9Impl *This = (IDirect3DCubeTexture9Impl *)iface;
     WINED3DSURFACE_DESC    wined3ddesc;
     UINT                   tmpInt = -1;
+    WINED3DFORMAT format;
     HRESULT hr;
 
     TRACE("(%p) Relay\n", This);
 
     /* As d3d8 and d3d9 structures differ, pass in ptrs to where data needs to go */
-    wined3ddesc.Format              = (WINED3DFORMAT *)&pDesc->Format;
+    wined3ddesc.Format              = &format;
     wined3ddesc.Type                = (WINED3DRESOURCETYPE *) &pDesc->Type;
     wined3ddesc.Usage               = &pDesc->Usage;
     wined3ddesc.Pool                = (WINED3DPOOL *) &pDesc->Pool;
@@ -246,6 +253,9 @@ static HRESULT WINAPI IDirect3DCubeTexture9Impl_GetLevelDesc(LPDIRECT3DCUBETEXTU
     EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DCubeTexture_GetLevelDesc(This->wineD3DCubeTexture, Level, &wined3ddesc);
     LeaveCriticalSection(&d3d9_cs);
+
+    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(format);
+
     return hr;
 }
 
@@ -355,7 +365,8 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_CreateCubeTexture(LPDIRECT3DDEVICE9EX ifac
     object->ref = 1;
     EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_CreateCubeTexture(This->WineD3DDevice, EdgeLength, Levels, Usage,
-            Format, Pool, &object->wineD3DCubeTexture, pSharedHandle, (IUnknown*)object);
+            wined3dformat_from_d3dformat(Format), Pool, &object->wineD3DCubeTexture,
+            pSharedHandle, (IUnknown*)object);
     LeaveCriticalSection(&d3d9_cs);
 
     if (hr != D3D_OK){
index 6576c0b..290ea51 100644 (file)
        <library>uuid</library>
        <library>wine</library>
        <library>user32</library>
-       <library>opengl32</library>
        <library>gdi32</library>
        <library>advapi32</library>
-       <library>kernel32</library>
        <library>wined3d</library>
 
-       <file>basetexture.c</file>
        <file>cubetexture.c</file>
        <file>d3d9_main.c</file>
        <file>device.c</file>
@@ -24,7 +21,6 @@
        <file>indexbuffer.c</file>
        <file>pixelshader.c</file>
        <file>query.c</file>
-       <file>resource.c</file>
        <file>stateblock.c</file>
        <file>surface.c</file>
        <file>swapchain.c</file>
index b78f09a..ac6cfaa 100644 (file)
@@ -45,6 +45,8 @@ extern HRESULT vdecl_convert_fvf(
     DWORD FVF,
     D3DVERTEXELEMENT9** ppVertexElements);
 extern CRITICAL_SECTION d3d9_cs;
+D3DFORMAT d3dformat_from_wined3dformat(WINED3DFORMAT format);
+WINED3DFORMAT wined3dformat_from_d3dformat(D3DFORMAT format);
 
 /* ===========================================================================
     Macros
@@ -275,26 +277,6 @@ typedef struct IDirect3DSwapChain9Impl
     BOOL                        isImplicit;
 } IDirect3DSwapChain9Impl;
 
-/* ------------------ */
-/* IDirect3DResource9 */
-/* ------------------ */
-
-/*****************************************************************************
- * IDirect3DResource9 implementation structure
- */
-typedef struct IDirect3DResource9Impl
-{
-    /* IUnknown fields */
-    const IDirect3DResource9Vtbl *lpVtbl;
-    LONG                    ref;
-
-    /* IDirect3DResource9 fields */
-    IWineD3DResource       *wineD3DResource;
-} IDirect3DResource9Impl;
-
-extern HRESULT  WINAPI        IDirect3DResource9Impl_GetDevice(LPDIRECT3DRESOURCE9 iface, IDirect3DDevice9** ppDevice);
-
-
 /* ----------------- */
 /* IDirect3DSurface9 */
 /* ----------------- */
@@ -343,7 +325,7 @@ typedef struct IDirect3DVertexBuffer9Impl
     LONG                    ref;
 
     /* IDirect3DResource9 fields */
-    IWineD3DVertexBuffer   *wineD3DVertexBuffer;
+    IWineD3DBuffer *wineD3DVertexBuffer;
 
     /* Parent reference */
     LPDIRECT3DDEVICE9EX       parentDevice;
@@ -387,8 +369,6 @@ typedef struct IDirect3DBaseTexture9Impl
     
 } IDirect3DBaseTexture9Impl;
 
-extern DWORD    WINAPI        IDirect3DBaseTexture9Impl_GetLOD(LPDIRECT3DBASETEXTURE9 iface);
-
 /* --------------------- */
 /* IDirect3DCubeTexture9 */
 /* --------------------- */
index b68caab..a917884 100644 (file)
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
 
+D3DFORMAT d3dformat_from_wined3dformat(WINED3DFORMAT format)
+{
+    BYTE *c = (BYTE *)&format;
+
+    /* Don't translate FOURCC formats */
+    if (isprint(c[0]) && isprint(c[1]) && isprint(c[2]) && isprint(c[3])) return format;
+
+    switch(format)
+    {
+        case WINED3DFMT_UNKNOWN: return D3DFMT_UNKNOWN;
+        case WINED3DFMT_R8G8B8: return D3DFMT_R8G8B8;
+        case WINED3DFMT_A8R8G8B8: return D3DFMT_A8R8G8B8;
+        case WINED3DFMT_X8R8G8B8: return D3DFMT_X8R8G8B8;
+        case WINED3DFMT_R5G6B5: return D3DFMT_R5G6B5;
+        case WINED3DFMT_X1R5G5B5: return D3DFMT_X1R5G5B5;
+        case WINED3DFMT_A1R5G5B5: return D3DFMT_A1R5G5B5;
+        case WINED3DFMT_A4R4G4B4: return D3DFMT_A4R4G4B4;
+        case WINED3DFMT_R3G3B2: return D3DFMT_R3G3B2;
+        case WINED3DFMT_A8_UNORM: return D3DFMT_A8;
+        case WINED3DFMT_A8R3G3B2: return D3DFMT_A8R3G3B2;
+        case WINED3DFMT_X4R4G4B4: return D3DFMT_X4R4G4B4;
+        case WINED3DFMT_R10G10B10A2_UNORM: return D3DFMT_A2B10G10R10;
+        case WINED3DFMT_R8G8B8A8_UNORM: return D3DFMT_A8B8G8R8;
+        case WINED3DFMT_X8B8G8R8: return D3DFMT_X8B8G8R8;
+        case WINED3DFMT_R16G16_UNORM: return D3DFMT_G16R16;
+        case WINED3DFMT_A2R10G10B10: return D3DFMT_A2R10G10B10;
+        case WINED3DFMT_R16G16B16A16_UNORM: return D3DFMT_A16B16G16R16;
+        case WINED3DFMT_A8P8: return D3DFMT_A8P8;
+        case WINED3DFMT_P8: return D3DFMT_P8;
+        case WINED3DFMT_L8: return D3DFMT_L8;
+        case WINED3DFMT_A8L8: return D3DFMT_A8L8;
+        case WINED3DFMT_A4L4: return D3DFMT_A4L4;
+        case WINED3DFMT_R8G8_SNORM: return D3DFMT_V8U8;
+        case WINED3DFMT_L6V5U5: return D3DFMT_L6V5U5;
+        case WINED3DFMT_X8L8V8U8: return D3DFMT_X8L8V8U8;
+        case WINED3DFMT_R8G8B8A8_SNORM: return D3DFMT_Q8W8V8U8;
+        case WINED3DFMT_R16G16_SNORM: return D3DFMT_V16U16;
+        case WINED3DFMT_A2W10V10U10: return D3DFMT_A2W10V10U10;
+        case WINED3DFMT_D16_LOCKABLE: return D3DFMT_D16_LOCKABLE;
+        case WINED3DFMT_D32: return D3DFMT_D32;
+        case WINED3DFMT_D15S1: return D3DFMT_D15S1;
+        case WINED3DFMT_D24S8: return D3DFMT_D24S8;
+        case WINED3DFMT_D24X8: return D3DFMT_D24X8;
+        case WINED3DFMT_D24X4S4: return D3DFMT_D24X4S4;
+        case WINED3DFMT_D16_UNORM: return D3DFMT_D16;
+        case WINED3DFMT_L16: return D3DFMT_L16;
+        case WINED3DFMT_D32F_LOCKABLE: return D3DFMT_D32F_LOCKABLE;
+        case WINED3DFMT_D24FS8: return D3DFMT_D24FS8;
+        case WINED3DFMT_VERTEXDATA: return D3DFMT_VERTEXDATA;
+        case WINED3DFMT_R16_UINT: return D3DFMT_INDEX16;
+        case WINED3DFMT_R32_UINT: return D3DFMT_INDEX32;
+        case WINED3DFMT_R16G16B16A16_SNORM: return D3DFMT_Q16W16V16U16;
+        case WINED3DFMT_R16_FLOAT: return D3DFMT_R16F;
+        case WINED3DFMT_R16G16_FLOAT: return D3DFMT_G16R16F;
+        case WINED3DFMT_R16G16B16A16_FLOAT: return D3DFMT_A16B16G16R16F;
+        case WINED3DFMT_R32_FLOAT: return D3DFMT_R32F;
+        case WINED3DFMT_R32G32_FLOAT: return D3DFMT_G32R32F;
+        case WINED3DFMT_R32G32B32A32_FLOAT: return D3DFMT_A32B32G32R32F;
+        case WINED3DFMT_CxV8U8: return D3DFMT_CxV8U8;
+        default:
+            FIXME("Unhandled WINED3DFORMAT %#x\n", format);
+            return D3DFMT_UNKNOWN;
+    }
+}
+
+WINED3DFORMAT wined3dformat_from_d3dformat(D3DFORMAT format)
+{
+    BYTE *c = (BYTE *)&format;
+
+    /* Don't translate FOURCC formats */
+    if (isprint(c[0]) && isprint(c[1]) && isprint(c[2]) && isprint(c[3])) return format;
+
+    switch(format)
+    {
+        case D3DFMT_UNKNOWN: return WINED3DFMT_UNKNOWN;
+        case D3DFMT_R8G8B8: return WINED3DFMT_R8G8B8;
+        case D3DFMT_A8R8G8B8: return WINED3DFMT_A8R8G8B8;
+        case D3DFMT_X8R8G8B8: return WINED3DFMT_X8R8G8B8;
+        case D3DFMT_R5G6B5: return WINED3DFMT_R5G6B5;
+        case D3DFMT_X1R5G5B5: return WINED3DFMT_X1R5G5B5;
+        case D3DFMT_A1R5G5B5: return WINED3DFMT_A1R5G5B5;
+        case D3DFMT_A4R4G4B4: return WINED3DFMT_A4R4G4B4;
+        case D3DFMT_R3G3B2: return WINED3DFMT_R3G3B2;
+        case D3DFMT_A8: return WINED3DFMT_A8_UNORM;
+        case D3DFMT_A8R3G3B2: return WINED3DFMT_A8R3G3B2;
+        case D3DFMT_X4R4G4B4: return WINED3DFMT_X4R4G4B4;
+        case D3DFMT_A2B10G10R10: return WINED3DFMT_R10G10B10A2_UNORM;
+        case D3DFMT_A8B8G8R8: return WINED3DFMT_R8G8B8A8_UNORM;
+        case D3DFMT_X8B8G8R8: return WINED3DFMT_X8B8G8R8;
+        case D3DFMT_G16R16: return WINED3DFMT_R16G16_UNORM;
+        case D3DFMT_A2R10G10B10: return WINED3DFMT_A2R10G10B10;
+        case D3DFMT_A16B16G16R16: return WINED3DFMT_R16G16B16A16_UNORM;
+        case D3DFMT_A8P8: return WINED3DFMT_A8P8;
+        case D3DFMT_P8: return WINED3DFMT_P8;
+        case D3DFMT_L8: return WINED3DFMT_L8;
+        case D3DFMT_A8L8: return WINED3DFMT_A8L8;
+        case D3DFMT_A4L4: return WINED3DFMT_A4L4;
+        case D3DFMT_V8U8: return WINED3DFMT_R8G8_SNORM;
+        case D3DFMT_L6V5U5: return WINED3DFMT_L6V5U5;
+        case D3DFMT_X8L8V8U8: return WINED3DFMT_X8L8V8U8;
+        case D3DFMT_Q8W8V8U8: return WINED3DFMT_R8G8B8A8_SNORM;
+        case D3DFMT_V16U16: return WINED3DFMT_R16G16_SNORM;
+        case D3DFMT_A2W10V10U10: return WINED3DFMT_A2W10V10U10;
+        case D3DFMT_D16_LOCKABLE: return WINED3DFMT_D16_LOCKABLE;
+        case D3DFMT_D32: return WINED3DFMT_D32;
+        case D3DFMT_D15S1: return WINED3DFMT_D15S1;
+        case D3DFMT_D24S8: return WINED3DFMT_D24S8;
+        case D3DFMT_D24X8: return WINED3DFMT_D24X8;
+        case D3DFMT_D24X4S4: return WINED3DFMT_D24X4S4;
+        case D3DFMT_D16: return WINED3DFMT_D16_UNORM;
+        case D3DFMT_L16: return WINED3DFMT_L16;
+        case D3DFMT_D32F_LOCKABLE: return WINED3DFMT_D32F_LOCKABLE;
+        case D3DFMT_D24FS8: return WINED3DFMT_D24FS8;
+        case D3DFMT_VERTEXDATA: return WINED3DFMT_VERTEXDATA;
+        case D3DFMT_INDEX16: return WINED3DFMT_R16_UINT;
+        case D3DFMT_INDEX32: return WINED3DFMT_R32_UINT;
+        case D3DFMT_Q16W16V16U16: return WINED3DFMT_R16G16B16A16_SNORM;
+        case D3DFMT_R16F: return WINED3DFMT_R16_FLOAT;
+        case D3DFMT_G16R16F: return WINED3DFMT_R16G16_FLOAT;
+        case D3DFMT_A16B16G16R16F: return WINED3DFMT_R16G16B16A16_FLOAT;
+        case D3DFMT_R32F: return WINED3DFMT_R32_FLOAT;
+        case D3DFMT_G32R32F: return WINED3DFMT_R32G32_FLOAT;
+        case D3DFMT_A32B32G32R32F: return WINED3DFMT_R32G32B32A32_FLOAT;
+        case D3DFMT_CxV8U8: return WINED3DFMT_CxV8U8;
+        default:
+            FIXME("Unhandled D3DFORMAT %#x\n", format);
+            return WINED3DFMT_UNKNOWN;
+    }
+}
+
+static UINT vertex_count_from_primitive_count(D3DPRIMITIVETYPE primitive_type, UINT primitive_count)
+{
+    switch(primitive_type)
+    {
+        case D3DPT_POINTLIST:
+            return primitive_count;
+
+        case D3DPT_LINELIST:
+            return primitive_count * 2;
+
+        case D3DPT_LINESTRIP:
+            return primitive_count + 1;
+
+        case D3DPT_TRIANGLELIST:
+            return primitive_count * 3;
+
+        case D3DPT_TRIANGLESTRIP:
+        case D3DPT_TRIANGLEFAN:
+            return primitive_count + 2;
+
+        default:
+            FIXME("Unhandled primitive type %#x\n", primitive_type);
+            return 0;
+    }
+}
 
 /* IDirect3D IUnknown parts follow: */
 static HRESULT WINAPI IDirect3DDevice9Impl_QueryInterface(LPDIRECT3DDEVICE9EX iface, REFIID riid, LPVOID* ppobj) {
@@ -213,6 +368,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetDisplayMode(LPDIRECT3DDEVICE9EX
     EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_GetDisplayMode(This->WineD3DDevice, iSwapChain, (WINED3DDISPLAYMODE *) pMode);
     LeaveCriticalSection(&d3d9_cs);
+
+    if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
+
     return hr;
 }
 
@@ -312,7 +470,7 @@ static HRESULT WINAPI reset_enum_callback(IWineD3DResource *resource, void *data
             break;
 
         case WINED3DRTYPE_VERTEXBUFFER:
-            IWineD3DVertexBuffer_GetDesc((IWineD3DVertexBuffer *) resource, &vertex_desc);
+            IWineD3DBuffer_GetDesc((IWineD3DBuffer *)resource, &vertex_desc);
             pool = vertex_desc.Pool;
             break;
 
@@ -355,6 +513,8 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_Reset(LPDIRECT3DDEVICE9EX iface, D3
      * Unsetting them is no problem, because the states are supposed to be reset anyway. If the validation
      * below fails, the device is considered "lost", and _Reset and _Release are the only allowed calls
      */
+    EnterCriticalSection(&d3d9_cs);
+
     IWineD3DDevice_SetIndices(This->WineD3DDevice, NULL);
     for(i = 0; i < 16; i++) {
         IWineD3DDevice_SetStreamSource(This->WineD3DDevice, i, NULL, 0, 0);
@@ -367,12 +527,13 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_Reset(LPDIRECT3DDEVICE9EX iface, D3
     if(!resources_ok) {
         WARN("The application is holding D3DPOOL_DEFAULT resources, rejecting reset\n");
         This->notreset = TRUE;
+        LeaveCriticalSection(&d3d9_cs);
         return WINED3DERR_INVALIDCALL;
     }
 
     localParameters.BackBufferWidth                     = pPresentationParameters->BackBufferWidth;
     localParameters.BackBufferHeight                    = pPresentationParameters->BackBufferHeight;
-    localParameters.BackBufferFormat                    = pPresentationParameters->BackBufferFormat;
+    localParameters.BackBufferFormat                    = wined3dformat_from_d3dformat(pPresentationParameters->BackBufferFormat);
     localParameters.BackBufferCount                     = pPresentationParameters->BackBufferCount;
     localParameters.MultiSampleType                     = pPresentationParameters->MultiSampleType;
     localParameters.MultiSampleQuality                  = pPresentationParameters->MultiSampleQuality;
@@ -380,21 +541,19 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_Reset(LPDIRECT3DDEVICE9EX iface, D3
     localParameters.hDeviceWindow                       = pPresentationParameters->hDeviceWindow;
     localParameters.Windowed                            = pPresentationParameters->Windowed;
     localParameters.EnableAutoDepthStencil              = pPresentationParameters->EnableAutoDepthStencil;
-    localParameters.AutoDepthStencilFormat              = pPresentationParameters->AutoDepthStencilFormat;
+    localParameters.AutoDepthStencilFormat              = wined3dformat_from_d3dformat(pPresentationParameters->AutoDepthStencilFormat);
     localParameters.Flags                               = pPresentationParameters->Flags;
     localParameters.FullScreen_RefreshRateInHz          = pPresentationParameters->FullScreen_RefreshRateInHz;
     localParameters.PresentationInterval                = pPresentationParameters->PresentationInterval;
     localParameters.AutoRestoreDisplayMode              = TRUE;
 
-    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_Reset(This->WineD3DDevice, &localParameters);
-    LeaveCriticalSection(&d3d9_cs);
     if(FAILED(hr)) {
         This->notreset = TRUE;
 
         pPresentationParameters->BackBufferWidth            = localParameters.BackBufferWidth;
         pPresentationParameters->BackBufferHeight           = localParameters.BackBufferHeight;
-        pPresentationParameters->BackBufferFormat           = localParameters.BackBufferFormat;
+        pPresentationParameters->BackBufferFormat           = d3dformat_from_wined3dformat(localParameters.BackBufferFormat);
         pPresentationParameters->BackBufferCount            = localParameters.BackBufferCount;
         pPresentationParameters->MultiSampleType            = localParameters.MultiSampleType;
         pPresentationParameters->MultiSampleQuality         = localParameters.MultiSampleQuality;
@@ -402,7 +561,7 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_Reset(LPDIRECT3DDEVICE9EX iface, D3
         pPresentationParameters->hDeviceWindow              = localParameters.hDeviceWindow;
         pPresentationParameters->Windowed                   = localParameters.Windowed;
         pPresentationParameters->EnableAutoDepthStencil     = localParameters.EnableAutoDepthStencil;
-        pPresentationParameters->AutoDepthStencilFormat     = localParameters.AutoDepthStencilFormat;
+        pPresentationParameters->AutoDepthStencilFormat     = d3dformat_from_wined3dformat(localParameters.AutoDepthStencilFormat);
         pPresentationParameters->Flags                      = localParameters.Flags;
         pPresentationParameters->FullScreen_RefreshRateInHz = localParameters.FullScreen_RefreshRateInHz;
         pPresentationParameters->PresentationInterval       = localParameters.PresentationInterval;
@@ -410,6 +569,8 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_Reset(LPDIRECT3DDEVICE9EX iface, D3
         This->notreset = FALSE;
     }
 
+    LeaveCriticalSection(&d3d9_cs);
+
     return hr;
 }
 
@@ -511,11 +672,15 @@ static HRESULT IDirect3DDevice9Impl_CreateSurface(LPDIRECT3DDEVICE9EX iface, UIN
 
     object->lpVtbl = &Direct3DSurface9_Vtbl;
     object->ref = 1;
-    
+
     TRACE("(%p) : w(%d) h(%d) fmt(%d) surf@%p\n", This, Width, Height, Format, *ppSurface);
-           
-    hrc = IWineD3DDevice_CreateSurface(This->WineD3DDevice, Width, Height, Format, Lockable, Discard, Level,  &object->wineD3DSurface, Type, Usage & WINED3DUSAGE_MASK, (WINED3DPOOL) Pool,MultiSample,MultisampleQuality,pSharedHandle,SURFACE_OPENGL,(IUnknown *)object);
-    
+
+    EnterCriticalSection(&d3d9_cs);
+    hrc = IWineD3DDevice_CreateSurface(This->WineD3DDevice, Width, Height, wined3dformat_from_d3dformat(Format),
+            Lockable, Discard, Level, &object->wineD3DSurface, Type, Usage & WINED3DUSAGE_MASK, (WINED3DPOOL)Pool,
+            MultiSample, MultisampleQuality, pSharedHandle, SURFACE_OPENGL, (IUnknown *)object);
+    LeaveCriticalSection(&d3d9_cs);
+
     if (hrc != D3D_OK || NULL == object->wineD3DSurface) {
 
        /* free up object */
@@ -539,10 +704,7 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_CreateRenderTarget(LPDIRECT3DDEVICE
     HRESULT hr;
     TRACE("Relay\n");
 
-   /* Is this correct? */
-   EnterCriticalSection(&d3d9_cs);
    hr = IDirect3DDevice9Impl_CreateSurface(iface,Width,Height,Format,Lockable,FALSE/*Discard*/, 0/*Level*/, ppSurface,D3DRTYPE_SURFACE,D3DUSAGE_RENDERTARGET,D3DPOOL_DEFAULT,MultiSample,MultisampleQuality,pSharedHandle);
-   LeaveCriticalSection(&d3d9_cs);
    return hr;
 }
 
@@ -553,11 +715,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_CreateDepthStencilSurface(LPDIRECT3
     HRESULT hr;
     TRACE("Relay\n");
 
-     EnterCriticalSection(&d3d9_cs);
      hr = IDirect3DDevice9Impl_CreateSurface(iface,Width,Height,Format,TRUE/* Lockable */,Discard, 0/* Level */
                                                ,ppSurface,D3DRTYPE_SURFACE,D3DUSAGE_DEPTHSTENCIL,
                                                 D3DPOOL_DEFAULT,MultiSample,MultisampleQuality,pSharedHandle);
-     LeaveCriticalSection(&d3d9_cs);
      return hr;
 }
 
@@ -636,19 +796,21 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_ColorFill(LPDIRECT3DDEVICE9EX iface
     desc.Usage = &usage;
     desc.Pool = &pool;
     desc.Type = &restype;
+
+    EnterCriticalSection(&d3d9_cs);
     IWineD3DSurface_GetDesc(surface->wineD3DSurface, &desc);
 
     /* This method is only allowed with surfaces that are render targets, or offscreen plain surfaces
      * in D3DPOOL_DEFAULT
      */
     if(!(usage & WINED3DUSAGE_RENDERTARGET) && (pool != D3DPOOL_DEFAULT || restype != D3DRTYPE_SURFACE)) {
+        LeaveCriticalSection(&d3d9_cs);
         WARN("Surface is not a render target, or not a stand-alone D3DPOOL_DEFAULT surface\n");
         return D3DERR_INVALIDCALL;
     }
 
     /* Colorfill can only be used on rendertarget surfaces, or offscreen plain surfaces in D3DPOOL_DEFAULT */
     /* Note: D3DRECT is compatible with WINED3DRECT */
-    EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_ColorFill(This->WineD3DDevice, surface->wineD3DSurface, (CONST WINED3DRECT*)pRect, color);
     LeaveCriticalSection(&d3d9_cs);
     return hr;
@@ -668,9 +830,8 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_CreateOffscreenPlainSurface(LPDIREC
         Why, their always lockable?
         should I change the usage to dynamic?        
         */
-    EnterCriticalSection(&d3d9_cs);
     hr = IDirect3DDevice9Impl_CreateSurface(iface,Width,Height,Format,TRUE/*Loackable*/,FALSE/*Discard*/,0/*Level*/ , ppSurface,D3DRTYPE_SURFACE, 0/*Usage (undefined/none)*/,(WINED3DPOOL) Pool,D3DMULTISAMPLE_NONE,0/*MultisampleQuality*/,pSharedHandle);
-    LeaveCriticalSection(&d3d9_cs);
+
     return hr;
 }
 
@@ -798,10 +959,16 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_SetTransform(LPDIRECT3DDEVICE9EX if
 
 static HRESULT  WINAPI  IDirect3DDevice9Impl_GetTransform(LPDIRECT3DDEVICE9EX iface, D3DTRANSFORMSTATETYPE State, D3DMATRIX* pMatrix) {
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
+    HRESULT hr;
+
     TRACE("(%p) Relay\n" , This);
 
+    EnterCriticalSection(&d3d9_cs);
     /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
-    return IWineD3DDevice_GetTransform(This->WineD3DDevice, State, (WINED3DMATRIX*) pMatrix);
+    hr = IWineD3DDevice_GetTransform(This->WineD3DDevice, State, (WINED3DMATRIX*) pMatrix);
+    LeaveCriticalSection(&d3d9_cs);
+
+    return hr;
 }
 
 static HRESULT  WINAPI  IDirect3DDevice9Impl_MultiplyTransform(LPDIRECT3DDEVICE9EX iface, D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix) {
@@ -1223,7 +1390,9 @@ static HRESULT WINAPI IDirect3DDevice9Impl_DrawPrimitive(LPDIRECT3DDEVICE9EX ifa
     TRACE("(%p) Relay\n" , This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3DDevice_DrawPrimitive(This->WineD3DDevice, PrimitiveType, StartVertex, PrimitiveCount);
+    IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
+    hr = IWineD3DDevice_DrawPrimitive(This->WineD3DDevice, StartVertex,
+            vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount));
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -1237,7 +1406,9 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_DrawIndexedPrimitive(LPDIRECT3DDEVI
     /* D3D8 passes the baseVertexIndex in SetIndices, and due to the stateblock functions wined3d has to work that way */
     EnterCriticalSection(&d3d9_cs);
     IWineD3DDevice_SetBaseVertexIndex(This->WineD3DDevice, BaseVertexIndex);
-    hr = IWineD3DDevice_DrawIndexedPrimitive(This->WineD3DDevice, PrimitiveType, MinVertexIndex, NumVertices, startIndex, primCount);
+    IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
+    hr = IWineD3DDevice_DrawIndexedPrimitive(This->WineD3DDevice, MinVertexIndex, NumVertices,
+            startIndex, vertex_count_from_primitive_count(PrimitiveType, primCount));
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -1248,7 +1419,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_DrawPrimitiveUP(LPDIRECT3DDEVICE9EX
     TRACE("(%p) Relay\n" , This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3DDevice_DrawPrimitiveUP(This->WineD3DDevice, PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride);
+    IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
+    hr = IWineD3DDevice_DrawPrimitiveUP(This->WineD3DDevice,
+            vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount),
+            pVertexStreamZeroData, VertexStreamZeroStride);
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -1261,8 +1435,10 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDE
     TRACE("(%p) Relay\n" , This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->WineD3DDevice, PrimitiveType, MinVertexIndex, NumVertexIndices, PrimitiveCount,
-                                                 pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride);
+    IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
+    hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->WineD3DDevice, MinVertexIndex, NumVertexIndices,
+            vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount), pIndexData,
+            wined3dformat_from_d3dformat(IndexDataFormat), pVertexStreamZeroData, VertexStreamZeroStride);
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -1338,27 +1514,30 @@ static IDirect3DVertexDeclaration9 *getConvertedDecl(IDirect3DDevice9Impl *This,
 
 static HRESULT WINAPI IDirect3DDevice9Impl_SetFVF(LPDIRECT3DDEVICE9EX iface, DWORD FVF) {
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
-    HRESULT hr = S_OK;
+    IDirect3DVertexDeclaration9 *decl;
+    HRESULT hr;
+
     TRACE("(%p) Relay\n" , This);
 
-    EnterCriticalSection(&d3d9_cs);
-    if (0 != FVF) {
-         IDirect3DVertexDeclaration9* pDecl = getConvertedDecl(This, FVF);
+    if (!FVF)
+    {
+        WARN("%#x is not a valid FVF\n", FVF);
+        return D3D_OK;
+    }
 
-         if(!pDecl) {
-             /* Any situation when this should happen, except out of memory? */
-             ERR("Failed to create a converted vertex declaration\n");
-             LeaveCriticalSection(&d3d9_cs);
-             return D3DERR_DRIVERINTERNALERROR;
-         }
+    EnterCriticalSection(&d3d9_cs);
+    decl = getConvertedDecl(This, FVF);
+    LeaveCriticalSection(&d3d9_cs);
 
-         hr = IDirect3DDevice9Impl_SetVertexDeclaration(iface, pDecl);
-         if (hr != S_OK) {
-             LeaveCriticalSection(&d3d9_cs);
-             return hr;
-         }
+    if (!decl)
+    {
+         /* Any situation when this should happen, except out of memory? */
+         ERR("Failed to create a converted vertex declaration\n");
+         return D3DERR_DRIVERINTERNALERROR;
     }
-    LeaveCriticalSection(&d3d9_cs);
+
+    hr = IDirect3DDevice9Impl_SetVertexDeclaration(iface, decl);
+    if (FAILED(hr)) ERR("Failed to set vertex declaration\n");
 
     return hr;
 }
@@ -1407,7 +1586,7 @@ static HRESULT WINAPI IDirect3DDevice9Impl_SetStreamSource(LPDIRECT3DDEVICE9EX i
 
 static HRESULT WINAPI IDirect3DDevice9Impl_GetStreamSource(LPDIRECT3DDEVICE9EX iface, UINT StreamNumber, IDirect3DVertexBuffer9 **pStream, UINT* OffsetInBytes, UINT* pStride) {
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
-    IWineD3DVertexBuffer *retStream = NULL;
+    IWineD3DBuffer *retStream = NULL;
     HRESULT rc = D3D_OK;
 
     TRACE("(%p) Relay\n" , This);
@@ -1419,8 +1598,8 @@ static HRESULT WINAPI IDirect3DDevice9Impl_GetStreamSource(LPDIRECT3DDEVICE9EX i
     EnterCriticalSection(&d3d9_cs);
     rc = IWineD3DDevice_GetStreamSource(This->WineD3DDevice, StreamNumber, &retStream, OffsetInBytes, pStride);
     if (rc == D3D_OK  && NULL != retStream) {
-        IWineD3DVertexBuffer_GetParent(retStream, (IUnknown **)pStream);
-        IWineD3DVertexBuffer_Release(retStream);
+        IWineD3DBuffer_GetParent(retStream, (IUnknown **)pStream);
+        IWineD3DBuffer_Release(retStream);
     }else{
         if (rc != D3D_OK){
             FIXME("Call to GetStreamSource failed %p %p\n", OffsetInBytes, pStride);
@@ -1794,6 +1973,11 @@ static ULONG STDMETHODCALLTYPE device_parent_Release(IWineD3DDeviceParent *iface
 
 /* IWineD3DDeviceParent methods */
 
+static void STDMETHODCALLTYPE device_parent_WineD3DDeviceCreated(IWineD3DDeviceParent *iface, IWineD3DDevice *device)
+{
+    TRACE("iface %p, device %p\n", iface, device);
+}
+
 static HRESULT STDMETHODCALLTYPE device_parent_CreateSurface(IWineD3DDeviceParent *iface,
         IUnknown *superior, UINT width, UINT height, WINED3DFORMAT format, DWORD usage,
         WINED3DPOOL pool, UINT level, WINED3DCUBEMAP_FACES face, IWineD3DSurface **surface)
@@ -1810,8 +1994,9 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateSurface(IWineD3DDeviceParen
     if (pool == D3DPOOL_DEFAULT && !(usage & D3DUSAGE_DYNAMIC)) lockable = FALSE;
 
     hr = IDirect3DDevice9Impl_CreateSurface((IDirect3DDevice9Ex *)This, width, height,
-            format, lockable, FALSE /* Discard */, level, (IDirect3DSurface9 **)&d3d_surface,
-            D3DRTYPE_SURFACE, usage, pool, D3DMULTISAMPLE_NONE, 0 /* MultisampleQuality */, NULL);
+            d3dformat_from_wined3dformat(format), lockable, FALSE /* Discard */, level,
+            (IDirect3DSurface9 **)&d3d_surface, D3DRTYPE_SURFACE, usage, pool,
+            D3DMULTISAMPLE_NONE, 0 /* MultisampleQuality */, NULL);
     if (FAILED(hr))
     {
         ERR("(%p) CreateSurface failed, returning %#x\n", iface, hr);
@@ -1839,8 +2024,9 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateRenderTarget(IWineD3DDevice
             "\tmultisample_quality %u, lockable %u, surface %p\n",
             iface, superior, width, height, format, multisample_type, multisample_quality, lockable, surface);
 
-    hr = IDirect3DDevice9Impl_CreateRenderTarget((IDirect3DDevice9Ex *)This, width, height, format,
-            multisample_type, multisample_quality, lockable, (IDirect3DSurface9 **)&d3d_surface, NULL);
+    hr = IDirect3DDevice9Impl_CreateRenderTarget((IDirect3DDevice9Ex *)This, width, height,
+            d3dformat_from_wined3dformat(format), multisample_type, multisample_quality, lockable,
+            (IDirect3DSurface9 **)&d3d_surface, NULL);
     if (FAILED(hr))
     {
         ERR("(%p) CreateRenderTarget failed, returning %#x\n", iface, hr);
@@ -1868,8 +2054,9 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateDepthStencilSurface(IWineD3
             "\tmultisample_quality %u, discard %u, surface %p\n",
             iface, superior, width, height, format, multisample_type, multisample_quality, discard, surface);
 
-    hr = IDirect3DDevice9Impl_CreateDepthStencilSurface((IDirect3DDevice9Ex *)This, width, height, format,
-            multisample_type, multisample_quality, discard, (IDirect3DSurface9 **)&d3d_surface, NULL);
+    hr = IDirect3DDevice9Impl_CreateDepthStencilSurface((IDirect3DDevice9Ex *)This, width, height,
+            d3dformat_from_wined3dformat(format), multisample_type, multisample_quality, discard,
+            (IDirect3DSurface9 **)&d3d_surface, NULL);
     if (FAILED(hr))
     {
         ERR("(%p) CreateDepthStencilSurface failed, returning %#x\n", iface, hr);
@@ -1939,7 +2126,7 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateSwapChain(IWineD3DDevicePar
     /* Copy the presentation parameters */
     local_parameters.BackBufferWidth = present_parameters->BackBufferWidth;
     local_parameters.BackBufferHeight = present_parameters->BackBufferHeight;
-    local_parameters.BackBufferFormat = present_parameters->BackBufferFormat;
+    local_parameters.BackBufferFormat = d3dformat_from_wined3dformat(present_parameters->BackBufferFormat);
     local_parameters.BackBufferCount = present_parameters->BackBufferCount;
     local_parameters.MultiSampleType = present_parameters->MultiSampleType;
     local_parameters.MultiSampleQuality = present_parameters->MultiSampleQuality;
@@ -1947,7 +2134,7 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateSwapChain(IWineD3DDevicePar
     local_parameters.hDeviceWindow = present_parameters->hDeviceWindow;
     local_parameters.Windowed = present_parameters->Windowed;
     local_parameters.EnableAutoDepthStencil = present_parameters->EnableAutoDepthStencil;
-    local_parameters.AutoDepthStencilFormat = present_parameters->AutoDepthStencilFormat;
+    local_parameters.AutoDepthStencilFormat = d3dformat_from_wined3dformat(present_parameters->AutoDepthStencilFormat);
     local_parameters.Flags = present_parameters->Flags;
     local_parameters.FullScreen_RefreshRateInHz = present_parameters->FullScreen_RefreshRateInHz;
     local_parameters.PresentationInterval = present_parameters->PresentationInterval;
@@ -1969,7 +2156,7 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateSwapChain(IWineD3DDevicePar
     /* Copy back the presentation parameters */
     present_parameters->BackBufferWidth = local_parameters.BackBufferWidth;
     present_parameters->BackBufferHeight = local_parameters.BackBufferHeight;
-    present_parameters->BackBufferFormat = local_parameters.BackBufferFormat;
+    present_parameters->BackBufferFormat = wined3dformat_from_d3dformat(local_parameters.BackBufferFormat);
     present_parameters->BackBufferCount = local_parameters.BackBufferCount;
     present_parameters->MultiSampleType = local_parameters.MultiSampleType;
     present_parameters->MultiSampleQuality = local_parameters.MultiSampleQuality;
@@ -1977,7 +2164,7 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateSwapChain(IWineD3DDevicePar
     present_parameters->hDeviceWindow = local_parameters.hDeviceWindow;
     present_parameters->Windowed = local_parameters.Windowed;
     present_parameters->EnableAutoDepthStencil = local_parameters.EnableAutoDepthStencil;
-    present_parameters->AutoDepthStencilFormat = local_parameters.AutoDepthStencilFormat;
+    present_parameters->AutoDepthStencilFormat = wined3dformat_from_d3dformat(local_parameters.AutoDepthStencilFormat);
     present_parameters->Flags = local_parameters.Flags;
     present_parameters->FullScreen_RefreshRateInHz = local_parameters.FullScreen_RefreshRateInHz;
     present_parameters->PresentationInterval = local_parameters.PresentationInterval;
@@ -1992,6 +2179,7 @@ const IWineD3DDeviceParentVtbl d3d9_wined3d_device_parent_vtbl =
     device_parent_AddRef,
     device_parent_Release,
     /* IWineD3DDeviceParent methods */
+    device_parent_WineD3DDeviceCreated,
     device_parent_CreateSurface,
     device_parent_CreateRenderTarget,
     device_parent_CreateDepthStencilSurface,
index bd9ba59..96fea01 100644 (file)
@@ -137,7 +137,7 @@ static UINT WINAPI IDirect3D9Impl_GetAdapterModeCount(LPDIRECT3D9EX iface, UINT
     }
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3D_GetAdapterModeCount(This->WineD3D, Adapter, Format);
+    hr = IWineD3D_GetAdapterModeCount(This->WineD3D, Adapter, wined3dformat_from_d3dformat(Format));
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -148,18 +148,30 @@ static HRESULT WINAPI IDirect3D9Impl_EnumAdapterModes(LPDIRECT3D9EX iface, UINT
     TRACE("(%p)->(%d, %d, %d, %p)\n", This, Adapter, Format, Mode, pMode);
     /* We can't pass this to WineD3D, otherwise it'll think it came from D3D8 or DDraw.
        It's supposed to fail anyway, so no harm returning failure. */
-    if(Format != WINED3DFMT_X8R8G8B8 && Format != WINED3DFMT_R5G6B5)
+    if(Format != D3DFMT_X8R8G8B8 && Format != D3DFMT_R5G6B5)
         return D3DERR_INVALIDCALL;
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3D_EnumAdapterModes(This->WineD3D, Adapter, Format, Mode, (WINED3DDISPLAYMODE *) pMode);
+    hr = IWineD3D_EnumAdapterModes(This->WineD3D, Adapter, wined3dformat_from_d3dformat(Format),
+            Mode, (WINED3DDISPLAYMODE *) pMode);
     LeaveCriticalSection(&d3d9_cs);
+
+    if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
+
     return hr;
 }
 
 static HRESULT WINAPI IDirect3D9Impl_GetAdapterDisplayMode(LPDIRECT3D9EX iface, UINT Adapter, D3DDISPLAYMODE* pMode) {
     IDirect3D9Impl *This = (IDirect3D9Impl *)iface;
-    return IWineD3D_GetAdapterDisplayMode(This->WineD3D, Adapter, (WINED3DDISPLAYMODE *) pMode);
+    HRESULT hr;
+
+    EnterCriticalSection(&d3d9_cs);
+    hr = IWineD3D_GetAdapterDisplayMode(This->WineD3D, Adapter, (WINED3DDISPLAYMODE *) pMode);
+    LeaveCriticalSection(&d3d9_cs);
+
+    if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
+
+    return hr;
 }
 
 static HRESULT WINAPI IDirect3D9Impl_CheckDeviceType(LPDIRECT3D9EX iface,
@@ -171,8 +183,8 @@ static HRESULT WINAPI IDirect3D9Impl_CheckDeviceType(LPDIRECT3D9EX iface,
           BackBufferFormat, Windowed ? "true" : "false");
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3D_CheckDeviceType(This->WineD3D, Adapter, CheckType, DisplayFormat,
-                                    BackBufferFormat, Windowed);
+    hr = IWineD3D_CheckDeviceType(This->WineD3D, Adapter, CheckType, wined3dformat_from_d3dformat(DisplayFormat),
+            wined3dformat_from_d3dformat(BackBufferFormat), Windowed);
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -185,8 +197,8 @@ static HRESULT WINAPI IDirect3D9Impl_CheckDeviceFormat(LPDIRECT3D9EX iface,
     TRACE("%p\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3D_CheckDeviceFormat(This->WineD3D, Adapter, DeviceType, AdapterFormat,
-                                    Usage, RType, CheckFormat, SURFACE_OPENGL);
+    hr = IWineD3D_CheckDeviceFormat(This->WineD3D, Adapter, DeviceType, wined3dformat_from_d3dformat(AdapterFormat),
+            Usage, RType, wined3dformat_from_d3dformat(CheckFormat), SURFACE_OPENGL);
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -199,8 +211,8 @@ static HRESULT WINAPI IDirect3D9Impl_CheckDeviceMultiSampleType(LPDIRECT3D9EX if
     TRACE("%p\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3D_CheckDeviceMultiSampleType(This->WineD3D, Adapter, DeviceType, SurfaceFormat,
-                                               Windowed, MultiSampleType, pQualityLevels);
+    hr = IWineD3D_CheckDeviceMultiSampleType(This->WineD3D, Adapter, DeviceType,
+            wined3dformat_from_d3dformat(SurfaceFormat), Windowed, MultiSampleType, pQualityLevels);
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -213,8 +225,9 @@ static HRESULT WINAPI IDirect3D9Impl_CheckDepthStencilMatch(LPDIRECT3D9EX iface,
     TRACE("%p\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3D_CheckDepthStencilMatch(This->WineD3D, Adapter, DeviceType, AdapterFormat,
-                                           RenderTargetFormat, DepthStencilFormat);
+    hr = IWineD3D_CheckDepthStencilMatch(This->WineD3D, Adapter, DeviceType,
+            wined3dformat_from_d3dformat(AdapterFormat), wined3dformat_from_d3dformat(RenderTargetFormat),
+            wined3dformat_from_d3dformat(DepthStencilFormat));
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -225,8 +238,8 @@ static HRESULT WINAPI IDirect3D9Impl_CheckDeviceFormatConversion(LPDIRECT3D9EX i
     TRACE("%p\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3D_CheckDeviceFormatConversion(This->WineD3D, Adapter, DeviceType, SourceFormat,
-                                                TargetFormat);
+    hr = IWineD3D_CheckDeviceFormatConversion(This->WineD3D, Adapter, DeviceType,
+            wined3dformat_from_d3dformat(SourceFormat), wined3dformat_from_d3dformat(TargetFormat));
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -366,7 +379,8 @@ static HRESULT WINAPI IDirect3D9Impl_CreateDevice(LPDIRECT3D9EX iface, UINT Adap
 
     IDirect3D9Impl       *This   = (IDirect3D9Impl *)iface;
     IDirect3DDevice9Impl *object = NULL;
-    WINED3DPRESENT_PARAMETERS localParameters;
+    WINED3DPRESENT_PARAMETERS *localParameters;
+    UINT i, count = 1;
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
@@ -402,49 +416,64 @@ static HRESULT WINAPI IDirect3D9Impl_CreateDevice(LPDIRECT3D9EX iface, UINT Adap
 
     TRACE("(%p) : Created Device %p\n", This, object);
 
-    localParameters.BackBufferWidth                     = pPresentationParameters->BackBufferWidth;
-    localParameters.BackBufferHeight                    = pPresentationParameters->BackBufferHeight;
-    localParameters.BackBufferFormat                    = pPresentationParameters->BackBufferFormat;
-    localParameters.BackBufferCount                     = pPresentationParameters->BackBufferCount;
-    localParameters.MultiSampleType                     = pPresentationParameters->MultiSampleType;
-    localParameters.MultiSampleQuality                  = pPresentationParameters->MultiSampleQuality;
-    localParameters.SwapEffect                          = pPresentationParameters->SwapEffect;
-    localParameters.hDeviceWindow                       = pPresentationParameters->hDeviceWindow;
-    localParameters.Windowed                            = pPresentationParameters->Windowed;
-    localParameters.EnableAutoDepthStencil              = pPresentationParameters->EnableAutoDepthStencil;
-    localParameters.AutoDepthStencilFormat              = pPresentationParameters->AutoDepthStencilFormat;
-    localParameters.Flags                               = pPresentationParameters->Flags;
-    localParameters.FullScreen_RefreshRateInHz          = pPresentationParameters->FullScreen_RefreshRateInHz;
-    localParameters.PresentationInterval                = pPresentationParameters->PresentationInterval;
-    localParameters.AutoRestoreDisplayMode              = TRUE;
+    if (BehaviourFlags & D3DCREATE_ADAPTERGROUP_DEVICE)
+    {
+        WINED3DCAPS caps;
+
+        IWineD3D_GetDeviceCaps(This->WineD3D, Adapter, DeviceType, &caps);
+        count = caps.NumberOfAdaptersInGroup;
+    }
 
     if(BehaviourFlags & D3DCREATE_MULTITHREADED) {
         IWineD3DDevice_SetMultithreaded(object->WineD3DDevice);
     }
 
-    hr = IWineD3DDevice_Init3D(object->WineD3DDevice, &localParameters);
-
-    pPresentationParameters->BackBufferWidth            = localParameters.BackBufferWidth;
-    pPresentationParameters->BackBufferHeight           = localParameters.BackBufferHeight;
-    pPresentationParameters->BackBufferFormat           = localParameters.BackBufferFormat;
-    pPresentationParameters->BackBufferCount            = localParameters.BackBufferCount;
-    pPresentationParameters->MultiSampleType            = localParameters.MultiSampleType;
-    pPresentationParameters->MultiSampleQuality         = localParameters.MultiSampleQuality;
-    pPresentationParameters->SwapEffect                 = localParameters.SwapEffect;
-    pPresentationParameters->hDeviceWindow              = localParameters.hDeviceWindow;
-    pPresentationParameters->Windowed                   = localParameters.Windowed;
-    pPresentationParameters->EnableAutoDepthStencil     = localParameters.EnableAutoDepthStencil;
-    pPresentationParameters->AutoDepthStencilFormat     = localParameters.AutoDepthStencilFormat;
-    pPresentationParameters->Flags                      = localParameters.Flags;
-    pPresentationParameters->FullScreen_RefreshRateInHz = localParameters.FullScreen_RefreshRateInHz;
-    pPresentationParameters->PresentationInterval       = localParameters.PresentationInterval;
+    localParameters = HeapAlloc(GetProcessHeap(), 0, sizeof(*localParameters) * count);
+    for (i = 0; i < count; ++i)
+    {
+        localParameters[i].BackBufferWidth = pPresentationParameters[i].BackBufferWidth;
+        localParameters[i].BackBufferHeight = pPresentationParameters[i].BackBufferHeight;
+        localParameters[i].BackBufferFormat = wined3dformat_from_d3dformat(pPresentationParameters[i].BackBufferFormat);
+        localParameters[i].BackBufferCount = pPresentationParameters[i].BackBufferCount;
+        localParameters[i].MultiSampleType = pPresentationParameters[i].MultiSampleType;
+        localParameters[i].MultiSampleQuality = pPresentationParameters[i].MultiSampleQuality;
+        localParameters[i].SwapEffect = pPresentationParameters[i].SwapEffect;
+        localParameters[i].hDeviceWindow = pPresentationParameters[i].hDeviceWindow;
+        localParameters[i].Windowed = pPresentationParameters[i].Windowed;
+        localParameters[i].EnableAutoDepthStencil = pPresentationParameters[i].EnableAutoDepthStencil;
+        localParameters[i].AutoDepthStencilFormat = wined3dformat_from_d3dformat(pPresentationParameters[i].AutoDepthStencilFormat);
+        localParameters[i].Flags = pPresentationParameters[i].Flags;
+        localParameters[i].FullScreen_RefreshRateInHz = pPresentationParameters[i].FullScreen_RefreshRateInHz;
+        localParameters[i].PresentationInterval = pPresentationParameters[i].PresentationInterval;
+        localParameters[i].AutoRestoreDisplayMode = TRUE;
+    }
 
+    hr = IWineD3DDevice_Init3D(object->WineD3DDevice, localParameters);
     if (hr != D3D_OK) {
         FIXME("(%p) D3D Initialization failed for WineD3DDevice %p\n", This, object->WineD3DDevice);
         HeapFree(GetProcessHeap(), 0, object);
         *ppReturnedDeviceInterface = NULL;
     }
 
+    for (i = 0; i < count; ++i)
+    {
+        pPresentationParameters[i].BackBufferWidth = localParameters[i].BackBufferWidth;
+        pPresentationParameters[i].BackBufferHeight = localParameters[i].BackBufferHeight;
+        pPresentationParameters[i].BackBufferFormat = d3dformat_from_wined3dformat(localParameters[i].BackBufferFormat);
+        pPresentationParameters[i].BackBufferCount = localParameters[i].BackBufferCount;
+        pPresentationParameters[i].MultiSampleType = localParameters[i].MultiSampleType;
+        pPresentationParameters[i].MultiSampleQuality = localParameters[i].MultiSampleQuality;
+        pPresentationParameters[i].SwapEffect = localParameters[i].SwapEffect;
+        pPresentationParameters[i].hDeviceWindow = localParameters[i].hDeviceWindow;
+        pPresentationParameters[i].Windowed = localParameters[i].Windowed;
+        pPresentationParameters[i].EnableAutoDepthStencil = localParameters[i].EnableAutoDepthStencil;
+        pPresentationParameters[i].AutoDepthStencilFormat = d3dformat_from_wined3dformat(localParameters[i].AutoDepthStencilFormat);
+        pPresentationParameters[i].Flags = localParameters[i].Flags;
+        pPresentationParameters[i].FullScreen_RefreshRateInHz = localParameters[i].FullScreen_RefreshRateInHz;
+        pPresentationParameters[i].PresentationInterval = localParameters[i].PresentationInterval;
+    }
+    HeapFree(GetProcessHeap(), 0, localParameters);
+
     /* Initialize the converted declaration array. This creates a valid pointer and when adding decls HeapReAlloc
      * can be used without further checking
      */
index c1860ff..2f3ca64 100644 (file)
@@ -69,11 +69,17 @@ static ULONG WINAPI IDirect3DIndexBuffer9Impl_Release(LPDIRECT3DINDEXBUFFER9 ifa
 /* IDirect3DIndexBuffer9 IDirect3DResource9 Interface follow: */
 static HRESULT WINAPI IDirect3DIndexBuffer9Impl_GetDevice(LPDIRECT3DINDEXBUFFER9 iface, IDirect3DDevice9** ppDevice) {
     IDirect3DIndexBuffer9Impl *This = (IDirect3DIndexBuffer9Impl *)iface;
+    IWineD3DDevice *wined3d_device;
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IDirect3DResource9Impl_GetDevice((LPDIRECT3DRESOURCE9) This, ppDevice);
+    hr = IWineD3DIndexBuffer_GetDevice(This->wineD3DIndexBuffer, &wined3d_device);
+    if (SUCCEEDED(hr))
+    {
+        IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
+        IWineD3DDevice_Release(wined3d_device);
+    }
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -184,6 +190,9 @@ static HRESULT  WINAPI        IDirect3DIndexBuffer9Impl_GetDesc(LPDIRECT3DINDEXB
     EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DIndexBuffer_GetDesc(This->wineD3DIndexBuffer, (WINED3DINDEXBUFFER_DESC *) pDesc);
     LeaveCriticalSection(&d3d9_cs);
+
+    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(pDesc->Format);
+
     return hr;
 }
 
@@ -230,7 +239,11 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateIndexBuffer(LPDIRECT3DDEVICE9EX iface,
     object->lpVtbl = &Direct3DIndexBuffer9_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, pSharedHandle, (IUnknown *)object);
+    EnterCriticalSection(&d3d9_cs);
+    hrc = IWineD3DDevice_CreateIndexBuffer(This->WineD3DDevice, Length, Usage & WINED3DUSAGE_MASK,
+            wined3dformat_from_d3dformat(Format), (WINED3DPOOL)Pool, &object->wineD3DIndexBuffer,
+            pSharedHandle, (IUnknown *)object);
+    LeaveCriticalSection(&d3d9_cs);
     if (hrc != D3D_OK) {
 
         /* free up object */
index dddda28..9c528d9 100644 (file)
@@ -205,8 +205,15 @@ HRESULT WINAPI IDirect3DDevice9Impl_SetPixelShaderConstantF(LPDIRECT3DDEVICE9EX
 
 HRESULT WINAPI IDirect3DDevice9Impl_GetPixelShaderConstantF(LPDIRECT3DDEVICE9EX iface, UINT Register, float* pConstantData, UINT Vector4fCount) {
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
+    HRESULT hr;
+
     TRACE("(%p) Relay\n", This);
-    return IWineD3DDevice_GetPixelShaderConstantF(This->WineD3DDevice, Register, pConstantData, Vector4fCount);
+
+    EnterCriticalSection(&d3d9_cs);
+    hr = IWineD3DDevice_GetPixelShaderConstantF(This->WineD3DDevice, Register, pConstantData, Vector4fCount);
+    LeaveCriticalSection(&d3d9_cs);
+
+    return hr;
 }
 
 HRESULT WINAPI IDirect3DDevice9Impl_SetPixelShaderConstantI(LPDIRECT3DDEVICE9EX iface, UINT Register, CONST int* pConstantData, UINT Vector4iCount) {
diff --git a/reactos/dll/directx/wine/d3d9/resource.c b/reactos/dll/directx/wine/d3d9/resource.c
deleted file mode 100644 (file)
index fac2570..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * IDirect3DResource9 implementation
- *
- * Copyright 2002-2004 Jason Edmeades
- *                     Raphael Junqueira
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-#include "d3d9_private.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
-
-/* IDirect3DResource9 IUnknown parts follow: */
-static HRESULT WINAPI IDirect3DResource9Impl_QueryInterface(LPDIRECT3DRESOURCE9 iface, REFIID riid, LPVOID* ppobj) {
-    IDirect3DResource9Impl *This = (IDirect3DResource9Impl *)iface;
-
-    if (IsEqualGUID(riid, &IID_IUnknown)
-        || IsEqualGUID(riid, &IID_IDirect3DResource9)) {
-        IDirect3DResource9_AddRef(iface);
-        *ppobj = This;
-        return S_OK;
-    }
-
-    WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
-    *ppobj = NULL;
-    return E_NOINTERFACE;
-}
-
-static ULONG WINAPI IDirect3DResource9Impl_AddRef(LPDIRECT3DRESOURCE9 iface) {
-    IDirect3DResource9Impl *This = (IDirect3DResource9Impl *)iface;
-    ULONG ref = InterlockedIncrement(&This->ref);
-
-    TRACE("(%p) : AddRef from %d\n", This, ref - 1);
-
-    return ref;
-}
-
-static ULONG WINAPI IDirect3DResource9Impl_Release(LPDIRECT3DRESOURCE9 iface) {
-    IDirect3DResource9Impl *This = (IDirect3DResource9Impl *)iface;
-    ULONG ref = InterlockedDecrement(&This->ref);
-
-    TRACE("(%p) : ReleaseRef to %d\n", This, ref);
-
-    if (ref == 0) {
-        IWineD3DResource_Release(This->wineD3DResource);
-        HeapFree(GetProcessHeap(), 0, This);
-    }
-    return ref;
-}
-
-/* IDirect3DResource9 Interface follow: */
-HRESULT WINAPI IDirect3DResource9Impl_GetDevice(LPDIRECT3DRESOURCE9 iface, IDirect3DDevice9** ppDevice) {
-    IDirect3DResource9Impl *This = (IDirect3DResource9Impl *)iface;
-    IWineD3DDevice *myDevice = NULL;
-
-    TRACE("(%p) Relay\n", This);
-
-    IWineD3DResource_GetDevice(This->wineD3DResource, &myDevice);
-    IWineD3DDevice_GetParent(myDevice, (IUnknown **)ppDevice);
-    IWineD3DDevice_Release(myDevice);
-    return D3D_OK;
-}
-
-static HRESULT WINAPI IDirect3DResource9Impl_SetPrivateData(LPDIRECT3DRESOURCE9 iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
-    IDirect3DResource9Impl *This = (IDirect3DResource9Impl *)iface;
-    TRACE("(%p) Relay\n", This);
-    return IWineD3DResource_SetPrivateData(This->wineD3DResource, refguid, pData, SizeOfData, Flags);
-}
-
-static HRESULT WINAPI IDirect3DResource9Impl_GetPrivateData(LPDIRECT3DRESOURCE9 iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) {
-    IDirect3DResource9Impl *This = (IDirect3DResource9Impl *)iface;
-    TRACE("(%p) Relay\n", This);
-    return IWineD3DResource_GetPrivateData(This->wineD3DResource, refguid, pData, pSizeOfData);
-}
-
-static HRESULT WINAPI IDirect3DResource9Impl_FreePrivateData(LPDIRECT3DRESOURCE9 iface, REFGUID refguid) {
-    IDirect3DResource9Impl *This = (IDirect3DResource9Impl *)iface;
-    TRACE("(%p) Relay\n", This);
-    return IWineD3DResource_FreePrivateData(This->wineD3DResource, refguid);
-}
-
-static DWORD  WINAPI IDirect3DResource9Impl_SetPriority(LPDIRECT3DRESOURCE9 iface, DWORD PriorityNew) {
-    IDirect3DResource9Impl *This = (IDirect3DResource9Impl *)iface;
-    TRACE("(%p) Relay\n", This);
-    return IWineD3DResource_SetPriority(This->wineD3DResource, PriorityNew);
-}
-
-static DWORD WINAPI IDirect3DResource9Impl_GetPriority(LPDIRECT3DRESOURCE9 iface) {
-    IDirect3DResource9Impl *This = (IDirect3DResource9Impl *)iface;
-    TRACE("(%p) Relay\n", This);
-    return IWineD3DResource_GetPriority(This->wineD3DResource);
-}
-
-static void WINAPI IDirect3DResource9Impl_PreLoad(LPDIRECT3DRESOURCE9 iface) {
-    IDirect3DResource9Impl *This = (IDirect3DResource9Impl *)iface;
-    TRACE("(%p) Relay\n", This);
-    IWineD3DResource_PreLoad(This->wineD3DResource);
-    return;
-}
-
-static D3DRESOURCETYPE WINAPI IDirect3DResource9Impl_GetType(LPDIRECT3DRESOURCE9 iface) {
-    IDirect3DResource9Impl *This = (IDirect3DResource9Impl *)iface;
-    TRACE("(%p) Relay\n", This);
-    return IWineD3DResource_GetType(This->wineD3DResource);
-}
-
-
-const IDirect3DResource9Vtbl Direct3DResource9_Vtbl =
-{
-    IDirect3DResource9Impl_QueryInterface,
-    IDirect3DResource9Impl_AddRef,
-    IDirect3DResource9Impl_Release,
-    IDirect3DResource9Impl_GetDevice,
-    IDirect3DResource9Impl_SetPrivateData,
-    IDirect3DResource9Impl_GetPrivateData,
-    IDirect3DResource9Impl_FreePrivateData,
-    IDirect3DResource9Impl_SetPriority,
-    IDirect3DResource9Impl_GetPriority,
-    IDirect3DResource9Impl_PreLoad,
-    IDirect3DResource9Impl_GetType
-};
index bf3f598..d17233f 100644 (file)
@@ -69,11 +69,17 @@ static ULONG WINAPI IDirect3DStateBlock9Impl_Release(LPDIRECT3DSTATEBLOCK9 iface
 /* IDirect3DStateBlock9 Interface follow: */
 static HRESULT WINAPI IDirect3DStateBlock9Impl_GetDevice(LPDIRECT3DSTATEBLOCK9 iface, IDirect3DDevice9** ppDevice) {
     IDirect3DStateBlock9Impl *This = (IDirect3DStateBlock9Impl *)iface;
+    IWineD3DDevice *wined3d_device;
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IDirect3DResource9Impl_GetDevice((LPDIRECT3DRESOURCE9) This, ppDevice);
+    hr = IWineD3DStateBlock_GetDevice(This->wineD3DStateBlock, &wined3d_device);
+    if (SUCCEEDED(hr))
+    {
+        IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
+        IWineD3DDevice_Release(wined3d_device);
+    }
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
index a626049..f95c387 100644 (file)
@@ -92,11 +92,17 @@ static ULONG WINAPI IDirect3DSurface9Impl_Release(LPDIRECT3DSURFACE9 iface) {
 /* IDirect3DSurface9 IDirect3DResource9 Interface follow: */
 static HRESULT WINAPI IDirect3DSurface9Impl_GetDevice(LPDIRECT3DSURFACE9 iface, IDirect3DDevice9** ppDevice) {
     IDirect3DSurface9Impl *This = (IDirect3DSurface9Impl *)iface;
+    IWineD3DDevice *wined3d_device;
     HRESULT hr;
     TRACE("(%p)->(%p)\n", This, ppDevice);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IDirect3DResource9Impl_GetDevice((LPDIRECT3DRESOURCE9) This, ppDevice);
+    hr = IWineD3DSurface_GetDevice(This->wineD3DSurface, &wined3d_device);
+    if (SUCCEEDED(hr))
+    {
+        IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
+        IWineD3DDevice_Release(wined3d_device);
+    }
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -201,11 +207,12 @@ static HRESULT WINAPI IDirect3DSurface9Impl_GetDesc(LPDIRECT3DSURFACE9 iface, D3
     IDirect3DSurface9Impl *This = (IDirect3DSurface9Impl *)iface;
     WINED3DSURFACE_DESC    wined3ddesc;
     UINT                   tmpInt = -1;
+    WINED3DFORMAT format;
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     /* As d3d8 and d3d9 structures differ, pass in ptrs to where data needs to go */
-    wined3ddesc.Format              = (WINED3DFORMAT *)&pDesc->Format;
+    wined3ddesc.Format              = &format;
     wined3ddesc.Type                = (WINED3DRESOURCETYPE *)&pDesc->Type;
     wined3ddesc.Usage               = &pDesc->Usage;
     wined3ddesc.Pool                = (WINED3DPOOL *) &pDesc->Pool;
@@ -218,6 +225,9 @@ static HRESULT WINAPI IDirect3DSurface9Impl_GetDesc(LPDIRECT3DSURFACE9 iface, D3
     EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DSurface_GetDesc(This->wineD3DSurface, &wined3ddesc);
     LeaveCriticalSection(&d3d9_cs);
+
+    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(format);
+
     return hr;
 }
 
index c14cc6d..4f639b1 100644 (file)
@@ -74,8 +74,15 @@ static ULONG WINAPI IDirect3DSwapChain9Impl_Release(LPDIRECT3DSWAPCHAIN9 iface)
 /* IDirect3DSwapChain9 parts follow: */
 static HRESULT WINAPI IDirect3DSwapChain9Impl_Present(LPDIRECT3DSWAPCHAIN9 iface, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion, DWORD dwFlags) {
     IDirect3DSwapChain9Impl *This = (IDirect3DSwapChain9Impl *)iface;
+    HRESULT hr;
+
     TRACE("(%p) Relay\n", This);
-    return IWineD3DSwapChain_Present(This->wineD3DSwapChain, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion, dwFlags);
+
+    EnterCriticalSection(&d3d9_cs);
+    hr = IWineD3DSwapChain_Present(This->wineD3DSwapChain, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion, dwFlags);
+    LeaveCriticalSection(&d3d9_cs);
+
+    return hr;
 }
 
 static HRESULT WINAPI IDirect3DSwapChain9Impl_GetFrontBufferData(LPDIRECT3DSWAPCHAIN9 iface, IDirect3DSurface9* pDestSurface) {
@@ -126,6 +133,9 @@ static HRESULT WINAPI IDirect3DSwapChain9Impl_GetDisplayMode(LPDIRECT3DSWAPCHAIN
     EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DSwapChain_GetDisplayMode(This->wineD3DSwapChain, (WINED3DDISPLAYMODE *) pMode);
     LeaveCriticalSection(&d3d9_cs);
+
+    if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
+
     return hr;
 }
 
@@ -159,7 +169,7 @@ static HRESULT WINAPI IDirect3DSwapChain9Impl_GetPresentParameters(LPDIRECT3DSWA
 
     pPresentationParameters->BackBufferWidth            = winePresentParameters.BackBufferWidth;
     pPresentationParameters->BackBufferHeight           = winePresentParameters.BackBufferHeight;
-    pPresentationParameters->BackBufferFormat           = winePresentParameters.BackBufferFormat;
+    pPresentationParameters->BackBufferFormat           = d3dformat_from_wined3dformat(winePresentParameters.BackBufferFormat);
     pPresentationParameters->BackBufferCount            = winePresentParameters.BackBufferCount;
     pPresentationParameters->MultiSampleType            = winePresentParameters.MultiSampleType;
     pPresentationParameters->MultiSampleQuality         = winePresentParameters.MultiSampleQuality;
@@ -167,6 +177,7 @@ static HRESULT WINAPI IDirect3DSwapChain9Impl_GetPresentParameters(LPDIRECT3DSWA
     pPresentationParameters->hDeviceWindow              = winePresentParameters.hDeviceWindow;
     pPresentationParameters->Windowed                   = winePresentParameters.Windowed;
     pPresentationParameters->EnableAutoDepthStencil     = winePresentParameters.EnableAutoDepthStencil;
+    pPresentationParameters->AutoDepthStencilFormat     = d3dformat_from_wined3dformat(winePresentParameters.AutoDepthStencilFormat);
     pPresentationParameters->Flags                      = winePresentParameters.Flags;
     pPresentationParameters->FullScreen_RefreshRateInHz = winePresentParameters.FullScreen_RefreshRateInHz;
     pPresentationParameters->PresentationInterval       = winePresentParameters.PresentationInterval;
@@ -215,7 +226,7 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_CreateAdditionalSwapChain(LPDIRECT3DDEVICE
     /* Allocate an associated WineD3DDevice object */
     localParameters.BackBufferWidth                     = pPresentationParameters->BackBufferWidth;
     localParameters.BackBufferHeight                    = pPresentationParameters->BackBufferHeight;
-    localParameters.BackBufferFormat                    = pPresentationParameters->BackBufferFormat;
+    localParameters.BackBufferFormat                    = wined3dformat_from_d3dformat(pPresentationParameters->BackBufferFormat);
     localParameters.BackBufferCount                     = pPresentationParameters->BackBufferCount;
     localParameters.MultiSampleType                     = pPresentationParameters->MultiSampleType;
     localParameters.MultiSampleQuality                  = pPresentationParameters->MultiSampleQuality;
@@ -223,7 +234,7 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_CreateAdditionalSwapChain(LPDIRECT3DDEVICE
     localParameters.hDeviceWindow                       = pPresentationParameters->hDeviceWindow;
     localParameters.Windowed                            = pPresentationParameters->Windowed;
     localParameters.EnableAutoDepthStencil              = pPresentationParameters->EnableAutoDepthStencil;
-    localParameters.AutoDepthStencilFormat              = pPresentationParameters->AutoDepthStencilFormat;
+    localParameters.AutoDepthStencilFormat              = wined3dformat_from_d3dformat(pPresentationParameters->AutoDepthStencilFormat);
     localParameters.Flags                               = pPresentationParameters->Flags;
     localParameters.FullScreen_RefreshRateInHz          = pPresentationParameters->FullScreen_RefreshRateInHz;
     localParameters.PresentationInterval                = pPresentationParameters->PresentationInterval;
@@ -236,7 +247,7 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_CreateAdditionalSwapChain(LPDIRECT3DDEVICE
 
     pPresentationParameters->BackBufferWidth            = localParameters.BackBufferWidth;
     pPresentationParameters->BackBufferHeight           = localParameters.BackBufferHeight;
-    pPresentationParameters->BackBufferFormat           = localParameters.BackBufferFormat;
+    pPresentationParameters->BackBufferFormat           = d3dformat_from_wined3dformat(localParameters.BackBufferFormat);
     pPresentationParameters->BackBufferCount            = localParameters.BackBufferCount;
     pPresentationParameters->MultiSampleType            = localParameters.MultiSampleType;
     pPresentationParameters->MultiSampleQuality         = localParameters.MultiSampleQuality;
@@ -244,7 +255,7 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_CreateAdditionalSwapChain(LPDIRECT3DDEVICE
     pPresentationParameters->hDeviceWindow              = localParameters.hDeviceWindow;
     pPresentationParameters->Windowed                   = localParameters.Windowed;
     pPresentationParameters->EnableAutoDepthStencil     = localParameters.EnableAutoDepthStencil;
-    pPresentationParameters->AutoDepthStencilFormat     = localParameters.AutoDepthStencilFormat;
+    pPresentationParameters->AutoDepthStencilFormat     = d3dformat_from_wined3dformat(localParameters.AutoDepthStencilFormat);
     pPresentationParameters->Flags                      = localParameters.Flags;
     pPresentationParameters->FullScreen_RefreshRateInHz = localParameters.FullScreen_RefreshRateInHz;
     pPresentationParameters->PresentationInterval       = localParameters.PresentationInterval;
index 21f6cf1..e128350 100644 (file)
@@ -71,11 +71,17 @@ static ULONG WINAPI IDirect3DTexture9Impl_Release(LPDIRECT3DTEXTURE9 iface) {
 /* IDirect3DTexture9 IDirect3DResource9 Interface follow: */
 static HRESULT WINAPI IDirect3DTexture9Impl_GetDevice(LPDIRECT3DTEXTURE9 iface, IDirect3DDevice9** ppDevice) {
     IDirect3DTexture9Impl *This = (IDirect3DTexture9Impl *)iface;
+    IWineD3DDevice *wined3d_device;
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IDirect3DResource9Impl_GetDevice((LPDIRECT3DRESOURCE9) This, ppDevice);
+    hr = IWineD3DTexture_GetDevice(This->wineD3DTexture, &wined3d_device);
+    if (SUCCEEDED(hr))
+    {
+        IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
+        IWineD3DDevice_Release(wined3d_device);
+    }
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -227,10 +233,12 @@ static HRESULT WINAPI IDirect3DTexture9Impl_GetLevelDesc(LPDIRECT3DTEXTURE9 ifac
     WINED3DSURFACE_DESC    wined3ddesc;
     UINT                   tmpInt = -1;
     HRESULT                hr;
+    WINED3DFORMAT format;
+
     TRACE("(%p) Relay\n", This);
 
     /* As d3d8 and d3d9 structures differ, pass in ptrs to where data needs to go */
-    wined3ddesc.Format              = (WINED3DFORMAT *)&pDesc->Format;
+    wined3ddesc.Format              = &format;
     wined3ddesc.Type                = (WINED3DRESOURCETYPE *)&pDesc->Type;
     wined3ddesc.Usage               = &pDesc->Usage;
     wined3ddesc.Pool                = (WINED3DPOOL *) &pDesc->Pool;
@@ -243,6 +251,9 @@ static HRESULT WINAPI IDirect3DTexture9Impl_GetLevelDesc(LPDIRECT3DTEXTURE9 ifac
     EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DTexture_GetLevelDesc(This->wineD3DTexture, Level, &wined3ddesc);
     LeaveCriticalSection(&d3d9_cs);
+
+    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(format);
+
     return hr;
 }
 
@@ -347,7 +358,7 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_CreateTexture(LPDIRECT3DDEVICE9EX iface, U
     object->ref = 1;
     EnterCriticalSection(&d3d9_cs);
     hrc = IWineD3DDevice_CreateTexture(This->WineD3DDevice, Width, Height, Levels, Usage & WINED3DUSAGE_MASK,
-            Format, Pool, &object->wineD3DTexture, pSharedHandle, (IUnknown *)object);
+            wined3dformat_from_d3dformat(Format), Pool, &object->wineD3DTexture, pSharedHandle, (IUnknown *)object);
     LeaveCriticalSection(&d3d9_cs);
     if (FAILED(hrc)) {
 
index 002052e..1a41c01 100644 (file)
@@ -59,7 +59,7 @@ static ULONG WINAPI IDirect3DVertexBuffer9Impl_Release(LPDIRECT3DVERTEXBUFFER9 i
 
     if (ref == 0) {
         EnterCriticalSection(&d3d9_cs);
-        IWineD3DVertexBuffer_Release(This->wineD3DVertexBuffer);
+        IWineD3DBuffer_Release(This->wineD3DVertexBuffer);
         LeaveCriticalSection(&d3d9_cs);
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
@@ -70,19 +70,32 @@ static ULONG WINAPI IDirect3DVertexBuffer9Impl_Release(LPDIRECT3DVERTEXBUFFER9 i
 /* IDirect3DVertexBuffer9 IDirect3DResource9 Interface follow: */
 static HRESULT WINAPI IDirect3DVertexBuffer9Impl_GetDevice(LPDIRECT3DVERTEXBUFFER9 iface, IDirect3DDevice9** ppDevice) {
     IDirect3DVertexBuffer9Impl *This = (IDirect3DVertexBuffer9Impl *)iface;
+    IWineD3DDevice *wined3d_device;
     HRESULT hr;
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IDirect3DResource9Impl_GetDevice((LPDIRECT3DRESOURCE9) This, ppDevice);
+    hr = IWineD3DBuffer_GetDevice(This->wineD3DVertexBuffer, &wined3d_device);
+    if (SUCCEEDED(hr))
+    {
+        IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
+        IWineD3DDevice_Release(wined3d_device);
+    }
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
 static HRESULT WINAPI IDirect3DVertexBuffer9Impl_SetPrivateData(LPDIRECT3DVERTEXBUFFER9 iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
     IDirect3DVertexBuffer9Impl *This = (IDirect3DVertexBuffer9Impl *)iface;
+    HRESULT hr;
+
     TRACE("(%p) Relay\n", This);
-    return IWineD3DVertexBuffer_SetPrivateData(This->wineD3DVertexBuffer, refguid, pData, SizeOfData, Flags);
+
+    EnterCriticalSection(&d3d9_cs);
+    hr = IWineD3DBuffer_SetPrivateData(This->wineD3DVertexBuffer, refguid, pData, SizeOfData, Flags);
+    LeaveCriticalSection(&d3d9_cs);
+
+    return hr;
 }
 
 static HRESULT WINAPI IDirect3DVertexBuffer9Impl_GetPrivateData(LPDIRECT3DVERTEXBUFFER9 iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) {
@@ -91,7 +104,7 @@ static HRESULT WINAPI IDirect3DVertexBuffer9Impl_GetPrivateData(LPDIRECT3DVERTEX
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3DVertexBuffer_GetPrivateData(This->wineD3DVertexBuffer, refguid, pData, pSizeOfData);
+    hr = IWineD3DBuffer_GetPrivateData(This->wineD3DVertexBuffer, refguid, pData, pSizeOfData);
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -102,7 +115,7 @@ static HRESULT WINAPI IDirect3DVertexBuffer9Impl_FreePrivateData(LPDIRECT3DVERTE
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3DVertexBuffer_FreePrivateData(This->wineD3DVertexBuffer, refguid);
+    hr = IWineD3DBuffer_FreePrivateData(This->wineD3DVertexBuffer, refguid);
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -113,7 +126,7 @@ static DWORD WINAPI IDirect3DVertexBuffer9Impl_SetPriority(LPDIRECT3DVERTEXBUFFE
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3DVertexBuffer_SetPriority(This->wineD3DVertexBuffer, PriorityNew);
+    hr = IWineD3DBuffer_SetPriority(This->wineD3DVertexBuffer, PriorityNew);
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -124,7 +137,7 @@ static DWORD WINAPI IDirect3DVertexBuffer9Impl_GetPriority(LPDIRECT3DVERTEXBUFFE
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3DVertexBuffer_GetPriority(This->wineD3DVertexBuffer);
+    hr = IWineD3DBuffer_GetPriority(This->wineD3DVertexBuffer);
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -134,7 +147,7 @@ static void WINAPI IDirect3DVertexBuffer9Impl_PreLoad(LPDIRECT3DVERTEXBUFFER9 if
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    IWineD3DVertexBuffer_PreLoad(This->wineD3DVertexBuffer);
+    IWineD3DBuffer_PreLoad(This->wineD3DVertexBuffer);
     LeaveCriticalSection(&d3d9_cs);
     return ;
 }
@@ -145,7 +158,7 @@ static D3DRESOURCETYPE WINAPI IDirect3DVertexBuffer9Impl_GetType(LPDIRECT3DVERTE
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    ret = IWineD3DVertexBuffer_GetType(This->wineD3DVertexBuffer);
+    ret = IWineD3DBuffer_GetType(This->wineD3DVertexBuffer);
     LeaveCriticalSection(&d3d9_cs);
     return ret;
 }
@@ -157,7 +170,7 @@ static HRESULT WINAPI IDirect3DVertexBuffer9Impl_Lock(LPDIRECT3DVERTEXBUFFER9 if
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3DVertexBuffer_Lock(This->wineD3DVertexBuffer, OffsetToLock, SizeToLock, (BYTE **)ppbData, Flags);
+    hr = IWineD3DBuffer_Map(This->wineD3DVertexBuffer, OffsetToLock, SizeToLock, (BYTE **)ppbData, Flags);
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -168,7 +181,7 @@ static HRESULT WINAPI IDirect3DVertexBuffer9Impl_Unlock(LPDIRECT3DVERTEXBUFFER9
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3DVertexBuffer_Unlock(This->wineD3DVertexBuffer);
+    hr = IWineD3DBuffer_Unmap(This->wineD3DVertexBuffer);
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -179,8 +192,11 @@ static HRESULT WINAPI IDirect3DVertexBuffer9Impl_GetDesc(LPDIRECT3DVERTEXBUFFER9
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3DVertexBuffer_GetDesc(This->wineD3DVertexBuffer, (WINED3DVERTEXBUFFER_DESC *) pDesc);
+    hr = IWineD3DBuffer_GetDesc(This->wineD3DVertexBuffer, (WINED3DVERTEXBUFFER_DESC *)pDesc);
     LeaveCriticalSection(&d3d9_cs);
+
+    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(pDesc->Format);
+
     return hr;
 }
 
index 86403fd..38f0751 100644 (file)
@@ -26,28 +26,29 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
 
 typedef struct _D3DDECLTYPE_INFO {
     D3DDECLTYPE d3dType;
+    WINED3DFORMAT format;
     int         size;
     int         typesize;
 } D3DDECLTYPE_INFO;
 
 static D3DDECLTYPE_INFO const d3d_dtype_lookup[D3DDECLTYPE_UNUSED] = {
-   {D3DDECLTYPE_FLOAT1,    1, sizeof(float)},
-   {D3DDECLTYPE_FLOAT2,    2, sizeof(float)},
-   {D3DDECLTYPE_FLOAT3,    3, sizeof(float)},
-   {D3DDECLTYPE_FLOAT4,    4, sizeof(float)},
-   {D3DDECLTYPE_D3DCOLOR,  4, sizeof(BYTE)},
-   {D3DDECLTYPE_UBYTE4,    4, sizeof(BYTE)},
-   {D3DDECLTYPE_SHORT2,    2, sizeof(short int)},
-   {D3DDECLTYPE_SHORT4,    4, sizeof(short int)},
-   {D3DDECLTYPE_UBYTE4N,   4, sizeof(BYTE)},
-   {D3DDECLTYPE_SHORT2N,   2, sizeof(short int)},
-   {D3DDECLTYPE_SHORT4N,   4, sizeof(short int)},
-   {D3DDECLTYPE_USHORT2N,  2, sizeof(short int)},
-   {D3DDECLTYPE_USHORT4N,  4, sizeof(short int)},
-   {D3DDECLTYPE_UDEC3,     3, sizeof(short int)},
-   {D3DDECLTYPE_DEC3N,     3, sizeof(short int)},
-   {D3DDECLTYPE_FLOAT16_2, 2, sizeof(short int)},
-   {D3DDECLTYPE_FLOAT16_4, 4, sizeof(short int)}};
+   {D3DDECLTYPE_FLOAT1,    WINED3DFMT_R32_FLOAT,          1, sizeof(float)},
+   {D3DDECLTYPE_FLOAT2,    WINED3DFMT_R32G32_FLOAT,       2, sizeof(float)},
+   {D3DDECLTYPE_FLOAT3,    WINED3DFMT_R32G32B32_FLOAT,    3, sizeof(float)},
+   {D3DDECLTYPE_FLOAT4,    WINED3DFMT_R32G32B32A32_FLOAT, 4, sizeof(float)},
+   {D3DDECLTYPE_D3DCOLOR,  WINED3DFMT_A8R8G8B8,           4, sizeof(BYTE)},
+   {D3DDECLTYPE_UBYTE4,    WINED3DFMT_R8G8B8A8_UINT,      4, sizeof(BYTE)},
+   {D3DDECLTYPE_SHORT2,    WINED3DFMT_R16G16_SINT,        2, sizeof(short int)},
+   {D3DDECLTYPE_SHORT4,    WINED3DFMT_R16G16B16A16_SINT,  4, sizeof(short int)},
+   {D3DDECLTYPE_UBYTE4N,   WINED3DFMT_R8G8B8A8_UNORM,     4, sizeof(BYTE)},
+   {D3DDECLTYPE_SHORT2N,   WINED3DFMT_R16G16_SNORM,       2, sizeof(short int)},
+   {D3DDECLTYPE_SHORT4N,   WINED3DFMT_R16G16B16A16_SNORM, 4, sizeof(short int)},
+   {D3DDECLTYPE_USHORT2N,  WINED3DFMT_R16G16_UNORM,       2, sizeof(short int)},
+   {D3DDECLTYPE_USHORT4N,  WINED3DFMT_R16G16B16A16_UNORM, 4, sizeof(short int)},
+   {D3DDECLTYPE_UDEC3,     WINED3DFMT_R10G10B10A2_UINT,   3, sizeof(short int)},
+   {D3DDECLTYPE_DEC3N,     WINED3DFMT_R10G10B10A2_SNORM,  3, sizeof(short int)},
+   {D3DDECLTYPE_FLOAT16_2, WINED3DFMT_R16G16_FLOAT,       2, sizeof(short int)},
+   {D3DDECLTYPE_FLOAT16_4, WINED3DFMT_R16G16B16A16_FLOAT, 4, sizeof(short int)}};
 
 #define D3D_DECL_SIZE(type)          d3d_dtype_lookup[type].size
 #define D3D_DECL_TYPESIZE(type)      d3d_dtype_lookup[type].typesize
@@ -301,32 +302,49 @@ static const IDirect3DVertexDeclaration9Vtbl Direct3DVertexDeclaration9_Vtbl =
     IDirect3DVertexDeclaration9Impl_GetDeclaration
 };
 
-static UINT convert_to_wined3d_declaration(const D3DVERTEXELEMENT9* d3d9_elements, WINED3DVERTEXELEMENT **wined3d_elements) {
+static HRESULT convert_to_wined3d_declaration(const D3DVERTEXELEMENT9* d3d9_elements,
+        WINED3DVERTEXELEMENT **wined3d_elements, UINT *element_count)
+{
     const D3DVERTEXELEMENT9* element;
-    UINT element_count = 1;
+    UINT count = 1;
     UINT i;
 
     TRACE("d3d9_elements %p, wined3d_elements %p\n", d3d9_elements, wined3d_elements);
 
     element = d3d9_elements;
-    while (element++->Stream != 0xff && element_count++ < 128);
+    while (element++->Stream != 0xff && count++ < 128);
 
-    if (element_count == 128) {
-        return 0;
-    }
+    if (count == 128) return E_FAIL;
+
+    /* Skip the END element */
+    --count;
 
-    *wined3d_elements = HeapAlloc(GetProcessHeap(), 0, element_count * sizeof(WINED3DVERTEXELEMENT));
+    *wined3d_elements = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WINED3DVERTEXELEMENT));
     if (!*wined3d_elements) {
         FIXME("Memory allocation failed\n");
-        return 0;
+        return D3DERR_OUTOFVIDEOMEMORY;
     }
 
-    for (i = 0; i < element_count; ++i) {
-        CopyMemory(*wined3d_elements + i, d3d9_elements + i, sizeof(D3DVERTEXELEMENT9));
-        (*wined3d_elements)[i].Reg = -1;
+    for (i = 0; i < count; ++i)
+    {
+        if (d3d9_elements[i].Type >= (sizeof(d3d_dtype_lookup) / sizeof(*d3d_dtype_lookup)))
+        {
+            WARN("Invalid element type %#x.\n", d3d9_elements[i].Type);
+            HeapFree(GetProcessHeap(), 0, *wined3d_elements);
+            return E_FAIL;
+        }
+        (*wined3d_elements)[i].format = d3d_dtype_lookup[d3d9_elements[i].Type].format;
+        (*wined3d_elements)[i].input_slot = d3d9_elements[i].Stream;
+        (*wined3d_elements)[i].offset = d3d9_elements[i].Offset;
+        (*wined3d_elements)[i].output_slot = ~0U;
+        (*wined3d_elements)[i].method = d3d9_elements[i].Method;
+        (*wined3d_elements)[i].usage = d3d9_elements[i].Usage;
+        (*wined3d_elements)[i].usage_idx = d3d9_elements[i].UsageIndex;
     }
 
-    return element_count;
+    *element_count = count;
+
+    return D3D_OK;
 }
 
 /* IDirect3DDevice9 IDirect3DVertexDeclaration9 Methods follow: */
@@ -335,8 +353,9 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_CreateVertexDeclaration(LPDIRECT3DDEVICE9E
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     IDirect3DVertexDeclaration9Impl *object = NULL;
     WINED3DVERTEXELEMENT* wined3d_elements;
+    UINT wined3d_element_count;
     UINT element_count;
-    HRESULT hr = D3D_OK;
+    HRESULT hr;
 
     TRACE("(%p) : Relay\n", iface);
     if (NULL == ppDecl) {
@@ -344,10 +363,11 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_CreateVertexDeclaration(LPDIRECT3DDEVICE9E
         return D3DERR_INVALIDCALL;
     }
 
-    element_count = convert_to_wined3d_declaration(pVertexElements, &wined3d_elements);
-    if (!element_count) {
-        FIXME("(%p) : Error parsing vertex declaration\n", This);
-        return D3DERR_INVALIDCALL;
+    hr = convert_to_wined3d_declaration(pVertexElements, &wined3d_elements, &wined3d_element_count);
+    if (FAILED(hr))
+    {
+        WARN("(%p) : Error parsing vertex declaration\n", This);
+        return hr;
     }
 
     /* Allocate the storage for the device */
@@ -361,6 +381,7 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_CreateVertexDeclaration(LPDIRECT3DDEVICE9E
     object->lpVtbl = &Direct3DVertexDeclaration9_Vtbl;
     object->ref = 0;
 
+    element_count = wined3d_element_count + 1;
     object->elements = HeapAlloc(GetProcessHeap(), 0, element_count * sizeof(D3DVERTEXELEMENT9));
     if (!object->elements) {
         HeapFree(GetProcessHeap(), 0, wined3d_elements);
@@ -372,7 +393,8 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_CreateVertexDeclaration(LPDIRECT3DDEVICE9E
     object->element_count = element_count;
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3DDevice_CreateVertexDeclaration(This->WineD3DDevice, &object->wineD3DVertexDeclaration, (IUnknown *)object, wined3d_elements, element_count);
+    hr = IWineD3DDevice_CreateVertexDeclaration(This->WineD3DDevice, &object->wineD3DVertexDeclaration,
+            (IUnknown *)object, wined3d_elements, wined3d_element_count);
     LeaveCriticalSection(&d3d9_cs);
 
     HeapFree(GetProcessHeap(), 0, wined3d_elements);
index fbdddb1..93b06b5 100644 (file)
@@ -72,7 +72,9 @@ static ULONG WINAPI IDirect3DVolume9Impl_Release(LPDIRECT3DVOLUME9 iface) {
         TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
         if (ref == 0) {
+            EnterCriticalSection(&d3d9_cs);
             IWineD3DVolume_Release(This->wineD3DVolume);
+            LeaveCriticalSection(&d3d9_cs);
             HeapFree(GetProcessHeap(), 0, This);
         }
 
@@ -85,28 +87,62 @@ static HRESULT WINAPI IDirect3DVolume9Impl_GetDevice(LPDIRECT3DVOLUME9 iface, ID
     IDirect3DVolume9Impl *This = (IDirect3DVolume9Impl *)iface;
     IWineD3DDevice       *myDevice = NULL;
 
+    TRACE("iface %p, ppDevice %p\n", iface, ppDevice);
+
+    EnterCriticalSection(&d3d9_cs);
+
     IWineD3DVolume_GetDevice(This->wineD3DVolume, &myDevice);
     IWineD3DDevice_GetParent(myDevice, (IUnknown **)ppDevice);
     IWineD3DDevice_Release(myDevice);
+
+    LeaveCriticalSection(&d3d9_cs);
+
     return D3D_OK;
 }
 
 static HRESULT WINAPI IDirect3DVolume9Impl_SetPrivateData(LPDIRECT3DVOLUME9 iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
     IDirect3DVolume9Impl *This = (IDirect3DVolume9Impl *)iface;
+    HRESULT hr;
+
     TRACE("(%p) Relay\n", This);
-    return IWineD3DVolume_SetPrivateData(This->wineD3DVolume, refguid, pData, SizeOfData, Flags);
+
+    EnterCriticalSection(&d3d9_cs);
+
+    hr = IWineD3DVolume_SetPrivateData(This->wineD3DVolume, refguid, pData, SizeOfData, Flags);
+
+    LeaveCriticalSection(&d3d9_cs);
+
+    return hr;
 }
 
 static HRESULT WINAPI IDirect3DVolume9Impl_GetPrivateData(LPDIRECT3DVOLUME9 iface, REFGUID  refguid, void* pData, DWORD* pSizeOfData) {
     IDirect3DVolume9Impl *This = (IDirect3DVolume9Impl *)iface;
+    HRESULT hr;
+
     TRACE("(%p) Relay\n", This);
-    return IWineD3DVolume_GetPrivateData(This->wineD3DVolume, refguid, pData, pSizeOfData);
+
+    EnterCriticalSection(&d3d9_cs);
+
+    hr = IWineD3DVolume_GetPrivateData(This->wineD3DVolume, refguid, pData, pSizeOfData);
+
+    LeaveCriticalSection(&d3d9_cs);
+
+    return hr;
 }
 
 static HRESULT WINAPI IDirect3DVolume9Impl_FreePrivateData(LPDIRECT3DVOLUME9 iface, REFGUID refguid) {
     IDirect3DVolume9Impl *This = (IDirect3DVolume9Impl *)iface;
+    HRESULT hr;
+
     TRACE("(%p) Relay\n", This);
-    return IWineD3DVolume_FreePrivateData(This->wineD3DVolume, refguid);
+
+    EnterCriticalSection(&d3d9_cs);
+
+    hr = IWineD3DVolume_FreePrivateData(This->wineD3DVolume, refguid);
+
+    LeaveCriticalSection(&d3d9_cs);
+
+    return hr;
 }
 
 static HRESULT WINAPI IDirect3DVolume9Impl_GetContainer(LPDIRECT3DVOLUME9 iface, REFIID riid, void** ppContainer) {
@@ -132,11 +168,13 @@ static HRESULT WINAPI IDirect3DVolume9Impl_GetDesc(LPDIRECT3DVOLUME9 iface, D3DV
     IDirect3DVolume9Impl *This = (IDirect3DVolume9Impl *)iface;
     WINED3DVOLUME_DESC     wined3ddesc;
     UINT                   tmpInt = -1;
+    WINED3DFORMAT format;
+    HRESULT hr;
 
     TRACE("(%p) Relay\n", This);
 
     /* As d3d8 and d3d9 structures differ, pass in ptrs to where data needs to go */
-    wined3ddesc.Format              = (WINED3DFORMAT *)&pDesc->Format;
+    wined3ddesc.Format              = &format;
     wined3ddesc.Type                = (WINED3DRESOURCETYPE *)&pDesc->Type;
     wined3ddesc.Usage               = &pDesc->Usage;
     wined3ddesc.Pool                = (WINED3DPOOL *) &pDesc->Pool;
@@ -145,19 +183,46 @@ static HRESULT WINAPI IDirect3DVolume9Impl_GetDesc(LPDIRECT3DVOLUME9 iface, D3DV
     wined3ddesc.Height              = &pDesc->Height;
     wined3ddesc.Depth               = &pDesc->Depth;
 
-    return IWineD3DVolume_GetDesc(This->wineD3DVolume, &wined3ddesc);
+    EnterCriticalSection(&d3d9_cs);
+
+    hr = IWineD3DVolume_GetDesc(This->wineD3DVolume, &wined3ddesc);
+
+    LeaveCriticalSection(&d3d9_cs);
+
+    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(format);
+
+    return hr;
 }
 
 static HRESULT WINAPI IDirect3DVolume9Impl_LockBox(LPDIRECT3DVOLUME9 iface, D3DLOCKED_BOX* pLockedVolume, CONST D3DBOX* pBox, DWORD Flags) {
     IDirect3DVolume9Impl *This = (IDirect3DVolume9Impl *)iface;
+    HRESULT hr;
+
     TRACE("(%p) relay %p %p %p %d\n", This, This->wineD3DVolume, pLockedVolume, pBox, Flags);
-    return IWineD3DVolume_LockBox(This->wineD3DVolume, (WINED3DLOCKED_BOX *)pLockedVolume, (CONST WINED3DBOX *)pBox, Flags);
+
+    EnterCriticalSection(&d3d9_cs);
+
+    hr = IWineD3DVolume_LockBox(This->wineD3DVolume, (WINED3DLOCKED_BOX *)pLockedVolume,
+            (const WINED3DBOX *)pBox, Flags);
+
+    LeaveCriticalSection(&d3d9_cs);
+
+    return hr;
 }
 
 static HRESULT WINAPI IDirect3DVolume9Impl_UnlockBox(LPDIRECT3DVOLUME9 iface) {
     IDirect3DVolume9Impl *This = (IDirect3DVolume9Impl *)iface;
+    HRESULT hr;
+
     TRACE("(%p) relay %p\n", This, This->wineD3DVolume);
-    return IWineD3DVolume_UnlockBox(This->wineD3DVolume);
+
+    EnterCriticalSection(&d3d9_cs);
+
+    hr = IWineD3DVolume_UnlockBox(This->wineD3DVolume);
+
+    LeaveCriticalSection(&d3d9_cs);
+
+    return hr;
 }
 
 const IDirect3DVolume9Vtbl Direct3DVolume9_Vtbl =
index df1f6e2..81327cd 100644 (file)
@@ -58,7 +58,9 @@ static ULONG WINAPI IDirect3DVolumeTexture9Impl_Release(LPDIRECT3DVOLUMETEXTURE9
     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
 
     if (ref == 0) {
+        EnterCriticalSection(&d3d9_cs);
         IWineD3DVolumeTexture_Destroy(This->wineD3DVolumeTexture, D3D9CB_DestroyVolume);
+        LeaveCriticalSection(&d3d9_cs);
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -68,87 +70,211 @@ static ULONG WINAPI IDirect3DVolumeTexture9Impl_Release(LPDIRECT3DVOLUMETEXTURE9
 /* IDirect3DVolumeTexture9 IDirect3DResource9 Interface follow: */
 static HRESULT WINAPI IDirect3DVolumeTexture9Impl_GetDevice(LPDIRECT3DVOLUMETEXTURE9 iface, IDirect3DDevice9** ppDevice) {
     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
+    IWineD3DDevice *wined3d_device;
+    HRESULT hr;
+
     TRACE("(%p) Relay\n", This);
-    return IDirect3DResource9Impl_GetDevice((LPDIRECT3DRESOURCE9) This, ppDevice);
+
+    EnterCriticalSection(&d3d9_cs);
+    hr = IWineD3DStateBlock_GetDevice(This->wineD3DVolumeTexture, &wined3d_device);
+    if (SUCCEEDED(hr))
+    {
+        IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
+        IWineD3DDevice_Release(wined3d_device);
+    }
+    LeaveCriticalSection(&d3d9_cs);
+
+    return hr;
 }
 
 static HRESULT WINAPI IDirect3DVolumeTexture9Impl_SetPrivateData(LPDIRECT3DVOLUMETEXTURE9 iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
+    HRESULT hr;
+
     TRACE("(%p) Relay\n", This);
-    return IWineD3DVolumeTexture_SetPrivateData(This->wineD3DVolumeTexture, refguid, pData, SizeOfData, Flags);
+
+    EnterCriticalSection(&d3d9_cs);
+
+    hr = IWineD3DVolumeTexture_SetPrivateData(This->wineD3DVolumeTexture, refguid, pData, SizeOfData, Flags);
+
+    LeaveCriticalSection(&d3d9_cs);
+
+    return hr;
 }
 
 static HRESULT WINAPI IDirect3DVolumeTexture9Impl_GetPrivateData(LPDIRECT3DVOLUMETEXTURE9 iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) {
     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
+    HRESULT hr;
+
     TRACE("(%p) Relay\n", This);
-    return IWineD3DVolumeTexture_GetPrivateData(This->wineD3DVolumeTexture, refguid, pData, pSizeOfData);
+
+    EnterCriticalSection(&d3d9_cs);
+
+    hr = IWineD3DVolumeTexture_GetPrivateData(This->wineD3DVolumeTexture, refguid, pData, pSizeOfData);
+
+    LeaveCriticalSection(&d3d9_cs);
+
+    return hr;
 }
 
 static HRESULT WINAPI IDirect3DVolumeTexture9Impl_FreePrivateData(LPDIRECT3DVOLUMETEXTURE9 iface, REFGUID refguid) {
     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
+    HRESULT hr;
+
     TRACE("(%p) Relay\n", This);
-    return IWineD3DVolumeTexture_FreePrivateData(This->wineD3DVolumeTexture, refguid);
+
+    EnterCriticalSection(&d3d9_cs);
+
+    hr = IWineD3DVolumeTexture_FreePrivateData(This->wineD3DVolumeTexture, refguid);
+
+    LeaveCriticalSection(&d3d9_cs);
+
+    return hr;
 }
 
 static DWORD WINAPI IDirect3DVolumeTexture9Impl_SetPriority(LPDIRECT3DVOLUMETEXTURE9 iface, DWORD PriorityNew) {
     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
+    DWORD priority;
+
     TRACE("(%p) Relay\n", This);
-    return IWineD3DVolumeTexture_SetPriority(This->wineD3DVolumeTexture, PriorityNew);
+
+    EnterCriticalSection(&d3d9_cs);
+
+    priority = IWineD3DVolumeTexture_SetPriority(This->wineD3DVolumeTexture, PriorityNew);
+
+    LeaveCriticalSection(&d3d9_cs);
+
+    return priority;
 }
 
 static DWORD WINAPI IDirect3DVolumeTexture9Impl_GetPriority(LPDIRECT3DVOLUMETEXTURE9 iface) {
     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
+    DWORD priority;
+
     TRACE("(%p) Relay\n", This);
-    return IWineD3DVolumeTexture_GetPriority(This->wineD3DVolumeTexture);
+
+    EnterCriticalSection(&d3d9_cs);
+
+    priority = IWineD3DVolumeTexture_GetPriority(This->wineD3DVolumeTexture);
+
+    LeaveCriticalSection(&d3d9_cs);
+
+    return priority;
 }
 
 static void WINAPI IDirect3DVolumeTexture9Impl_PreLoad(LPDIRECT3DVOLUMETEXTURE9 iface) {
     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
+
     TRACE("(%p) Relay\n", This);
+
+    EnterCriticalSection(&d3d9_cs);
+
     IWineD3DVolumeTexture_PreLoad(This->wineD3DVolumeTexture);
+
+    LeaveCriticalSection(&d3d9_cs);
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DVolumeTexture9Impl_GetType(LPDIRECT3DVOLUMETEXTURE9 iface) {
     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
+    D3DRESOURCETYPE type;
+
     TRACE("(%p) Relay\n", This);
-    return IWineD3DVolumeTexture_GetType(This->wineD3DVolumeTexture);
+
+    EnterCriticalSection(&d3d9_cs);
+
+    type = IWineD3DVolumeTexture_GetType(This->wineD3DVolumeTexture);
+
+    LeaveCriticalSection(&d3d9_cs);
+
+    return type;
 }
 
 /* IDirect3DVolumeTexture9 IDirect3DBaseTexture9 Interface follow: */
 static DWORD WINAPI IDirect3DVolumeTexture9Impl_SetLOD(LPDIRECT3DVOLUMETEXTURE9 iface, DWORD LODNew) {
     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
+    DWORD lod;
+
     TRACE("(%p) Relay\n", This);
-    return IWineD3DVolumeTexture_SetLOD(This->wineD3DVolumeTexture, LODNew);
+
+    EnterCriticalSection(&d3d9_cs);
+
+    lod = IWineD3DVolumeTexture_SetLOD(This->wineD3DVolumeTexture, LODNew);
+
+    LeaveCriticalSection(&d3d9_cs);
+
+    return lod;
 }
 
 static DWORD WINAPI IDirect3DVolumeTexture9Impl_GetLOD(LPDIRECT3DVOLUMETEXTURE9 iface) {
     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
+    DWORD lod;
+
     TRACE("(%p) Relay\n", This);
-    return IWineD3DVolumeTexture_GetLOD(This->wineD3DVolumeTexture);
+
+    EnterCriticalSection(&d3d9_cs);
+
+    lod = IWineD3DVolumeTexture_GetLOD(This->wineD3DVolumeTexture);
+
+    LeaveCriticalSection(&d3d9_cs);
+
+    return lod;
 }
 
 static DWORD WINAPI IDirect3DVolumeTexture9Impl_GetLevelCount(LPDIRECT3DVOLUMETEXTURE9 iface) {
     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
+    DWORD level_count;
+
     TRACE("(%p) Relay\n", This);
-    return IWineD3DVolumeTexture_GetLevelCount(This->wineD3DVolumeTexture);
+
+    EnterCriticalSection(&d3d9_cs);
+
+    level_count = IWineD3DVolumeTexture_GetLevelCount(This->wineD3DVolumeTexture);
+
+    LeaveCriticalSection(&d3d9_cs);
+
+    return level_count;
 }
 
 static HRESULT WINAPI IDirect3DVolumeTexture9Impl_SetAutoGenFilterType(LPDIRECT3DVOLUMETEXTURE9 iface, D3DTEXTUREFILTERTYPE FilterType) {
     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
+    HRESULT hr;
+
     TRACE("(%p) Relay\n", This);
-    return IWineD3DVolumeTexture_SetAutoGenFilterType(This->wineD3DVolumeTexture, (WINED3DTEXTUREFILTERTYPE) FilterType);
+
+    EnterCriticalSection(&d3d9_cs);
+
+    hr = IWineD3DVolumeTexture_SetAutoGenFilterType(This->wineD3DVolumeTexture, (WINED3DTEXTUREFILTERTYPE) FilterType);
+
+    LeaveCriticalSection(&d3d9_cs);
+
+    return hr;
 }
 
 static D3DTEXTUREFILTERTYPE WINAPI IDirect3DVolumeTexture9Impl_GetAutoGenFilterType(LPDIRECT3DVOLUMETEXTURE9 iface) {
     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
+    D3DTEXTUREFILTERTYPE filter_type;
+
     TRACE("(%p) Relay\n", This);
-    return (D3DTEXTUREFILTERTYPE) IWineD3DVolumeTexture_GetAutoGenFilterType(This->wineD3DVolumeTexture);
+
+    EnterCriticalSection(&d3d9_cs);
+
+    filter_type = (D3DTEXTUREFILTERTYPE)IWineD3DVolumeTexture_GetAutoGenFilterType(This->wineD3DVolumeTexture);
+
+    LeaveCriticalSection(&d3d9_cs);
+
+    return filter_type;
 }
 
 static void WINAPI IDirect3DVolumeTexture9Impl_GenerateMipSubLevels(LPDIRECT3DVOLUMETEXTURE9 iface) {
     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
+
     TRACE("(%p) Relay\n", This);
+
+    EnterCriticalSection(&d3d9_cs);
+
     IWineD3DVolumeTexture_GenerateMipSubLevels(This->wineD3DVolumeTexture);
+
+    LeaveCriticalSection(&d3d9_cs);
 }
 
 /* IDirect3DVolumeTexture9 Interface follow: */
@@ -156,11 +282,13 @@ static HRESULT WINAPI IDirect3DVolumeTexture9Impl_GetLevelDesc(LPDIRECT3DVOLUMET
     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
     WINED3DVOLUME_DESC     wined3ddesc;
     UINT                   tmpInt = -1;
+    WINED3DFORMAT format;
+    HRESULT hr;
 
     TRACE("(%p) Relay\n", This);
 
     /* As d3d8 and d3d9 structures differ, pass in ptrs to where data needs to go */
-    wined3ddesc.Format              = (WINED3DFORMAT *)&pDesc->Format;
+    wined3ddesc.Format              = &format;
     wined3ddesc.Type                = (WINED3DRESOURCETYPE *)&pDesc->Type;
     wined3ddesc.Usage               = &pDesc->Usage;
     wined3ddesc.Pool                = (WINED3DPOOL *) &pDesc->Pool;
@@ -169,7 +297,15 @@ static HRESULT WINAPI IDirect3DVolumeTexture9Impl_GetLevelDesc(LPDIRECT3DVOLUMET
     wined3ddesc.Height              = &pDesc->Height;
     wined3ddesc.Depth               = &pDesc->Depth;
 
-    return IWineD3DVolumeTexture_GetLevelDesc(This->wineD3DVolumeTexture, Level, &wined3ddesc);
+    EnterCriticalSection(&d3d9_cs);
+
+    hr = IWineD3DVolumeTexture_GetLevelDesc(This->wineD3DVolumeTexture, Level, &wined3ddesc);
+
+    LeaveCriticalSection(&d3d9_cs);
+
+    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(format);
+
+    return hr;
 }
 
 static HRESULT WINAPI IDirect3DVolumeTexture9Impl_GetVolumeLevel(LPDIRECT3DVOLUMETEXTURE9 iface, UINT Level, IDirect3DVolume9** ppVolumeLevel) {
@@ -179,30 +315,63 @@ static HRESULT WINAPI IDirect3DVolumeTexture9Impl_GetVolumeLevel(LPDIRECT3DVOLUM
 
     TRACE("(%p) Relay\n", This);
 
+    EnterCriticalSection(&d3d9_cs);
+
     hrc = IWineD3DVolumeTexture_GetVolumeLevel(This->wineD3DVolumeTexture, Level, &myVolume);
     if (hrc == D3D_OK && NULL != ppVolumeLevel) {
        IWineD3DVolumeTexture_GetParent(myVolume, (IUnknown **)ppVolumeLevel);
        IWineD3DVolumeTexture_Release(myVolume);
     }
+
+    LeaveCriticalSection(&d3d9_cs);
+
     return hrc;
 }
 
 static HRESULT WINAPI IDirect3DVolumeTexture9Impl_LockBox(LPDIRECT3DVOLUMETEXTURE9 iface, UINT Level, D3DLOCKED_BOX* pLockedVolume, CONST D3DBOX* pBox, DWORD Flags) {
     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
+    HRESULT hr;
+
     TRACE("(%p) Relay %p %p %p %d\n", This, This->wineD3DVolumeTexture, pLockedVolume, pBox,Flags);
-    return IWineD3DVolumeTexture_LockBox(This->wineD3DVolumeTexture, Level, (WINED3DLOCKED_BOX *)pLockedVolume, (CONST WINED3DBOX *)pBox, Flags);
+
+    EnterCriticalSection(&d3d9_cs);
+
+    hr = IWineD3DVolumeTexture_LockBox(This->wineD3DVolumeTexture, Level, (WINED3DLOCKED_BOX *)pLockedVolume,
+            (const WINED3DBOX *)pBox, Flags);
+
+    LeaveCriticalSection(&d3d9_cs);
+
+    return hr;
 }
 
 static HRESULT WINAPI IDirect3DVolumeTexture9Impl_UnlockBox(LPDIRECT3DVOLUMETEXTURE9 iface, UINT Level) {
     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
+    HRESULT hr;
+
     TRACE("(%p) Relay %p %d\n", This, This->wineD3DVolumeTexture, Level);
-    return IWineD3DVolumeTexture_UnlockBox(This->wineD3DVolumeTexture, Level);
+
+    EnterCriticalSection(&d3d9_cs);
+
+    hr = IWineD3DVolumeTexture_UnlockBox(This->wineD3DVolumeTexture, Level);
+
+    LeaveCriticalSection(&d3d9_cs);
+
+    return hr;
 }
 
 static HRESULT WINAPI IDirect3DVolumeTexture9Impl_AddDirtyBox(LPDIRECT3DVOLUMETEXTURE9 iface, CONST D3DBOX* pDirtyBox) {
     IDirect3DVolumeTexture9Impl *This = (IDirect3DVolumeTexture9Impl *)iface;
+    HRESULT hr;
+
     TRACE("(%p) Relay\n", This);
-    return IWineD3DVolumeTexture_AddDirtyBox(This->wineD3DVolumeTexture, (CONST WINED3DBOX *)pDirtyBox);
+
+    EnterCriticalSection(&d3d9_cs);
+
+    hr = IWineD3DVolumeTexture_AddDirtyBox(This->wineD3DVolumeTexture, (CONST WINED3DBOX *)pDirtyBox);
+
+    LeaveCriticalSection(&d3d9_cs);
+
+    return hr;
 }
 
 
@@ -258,8 +427,15 @@ HRESULT  WINAPI  IDirect3DDevice9Impl_CreateVolumeTexture(LPDIRECT3DDEVICE9EX if
 
     object->lpVtbl = &Direct3DVolumeTexture9_Vtbl;
     object->ref = 1;
+
+    EnterCriticalSection(&d3d9_cs);
+
     hrc = IWineD3DDevice_CreateVolumeTexture(This->WineD3DDevice, Width, Height, Depth, Levels,
-            Usage & WINED3DUSAGE_MASK, Format, Pool, &object->wineD3DVolumeTexture, pSharedHandle, (IUnknown *)object);
+            Usage & WINED3DUSAGE_MASK, wined3dformat_from_d3dformat(Format), Pool,
+            &object->wineD3DVolumeTexture, pSharedHandle, (IUnknown *)object);
+
+    LeaveCriticalSection(&d3d9_cs);
+
     if (hrc != D3D_OK) {
 
         /* free up object */
diff --git a/reactos/dll/directx/wine/ddraw/clipper.c b/reactos/dll/directx/wine/ddraw/clipper.c
new file mode 100644 (file)
index 0000000..4fa4c36
--- /dev/null
@@ -0,0 +1,312 @@
+/* DirectDrawClipper implementation
+ *
+ * Copyright 2000 (c) Marcus Meissner
+ * Copyright 2000 (c) TransGaming Technologies Inc.
+ * Copyright 2006 (c) Stefan Dösinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define COBJMACROS
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "ddraw.h"
+#include "winerror.h"
+
+#include "ddraw_private.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
+
+/*****************************************************************************
+ * IUnknown methods
+ *****************************************************************************/
+
+/*****************************************************************************
+ * IDirectDrawClipper::QueryInterface
+ *
+ * Can query the IUnknown and IDirectDrawClipper interface from a
+ * Clipper object. The IUnknown Interface is equal to the IDirectDrawClipper
+ * interface. Can't create other interfaces.
+ *
+ * Arguments:
+ *  riid: Interface id asked for
+ *  ppvObj: Returns the pointer to the interface
+ *
+ * Return values:
+ *  DD_OK on success
+ *  E_NOINTERFACE if the requested interface wasn't found.
+ *
+ *****************************************************************************/
+static HRESULT WINAPI IDirectDrawClipperImpl_QueryInterface(
+    LPDIRECTDRAWCLIPPER iface, REFIID riid, LPVOID* ppvObj
+) {
+    if (IsEqualGUID(&IID_IUnknown, riid)
+       || IsEqualGUID(&IID_IDirectDrawClipper, riid))
+    {
+        IUnknown_AddRef(iface);
+        *ppvObj = iface;
+        return S_OK;
+    }
+    else
+    {
+       return E_NOINTERFACE;
+    }
+}
+
+/*****************************************************************************
+ * IDirectDrawClipper::AddRef
+ *
+ * Increases the reference count of the interface, returns the new count
+ *
+ *****************************************************************************/
+static ULONG WINAPI IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface )
+{
+    IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
+    ULONG ref = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p)->() incrementing from %u.\n", This, ref - 1);
+
+    return ref;
+}
+
+/*****************************************************************************
+ * IDirectDrawClipper::Release
+ *
+ * Decreases the reference count of the interface, returns the new count
+ * If the refcount is decreased to 0, the interface is destroyed.
+ *
+ *****************************************************************************/
+static ULONG WINAPI IDirectDrawClipperImpl_Release(IDirectDrawClipper *iface) {
+    IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
+    ULONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p)->() decrementing from %u.\n", This, ref + 1);
+
+    if (ref == 0)
+    {
+        EnterCriticalSection(&ddraw_cs);
+        IWineD3DClipper_Release(This->wineD3DClipper);
+        HeapFree(GetProcessHeap(), 0, This);
+        LeaveCriticalSection(&ddraw_cs);
+        return 0;
+    }
+    else return ref;
+}
+
+/*****************************************************************************
+ * IDirectDrawClipper::SetHwnd
+ *
+ * Assigns a hWnd to the clipper interface.
+ *
+ * Arguments:
+ *  Flags: Unsupported so far
+ *  hWnd: The hWnd to set
+ *
+ * Return values:
+ *  DD_OK on success
+ *  DDERR_INVALIDPARAMS if Flags was != 0
+ *
+ *****************************************************************************/
+
+static HRESULT WINAPI IDirectDrawClipperImpl_SetHwnd(
+    LPDIRECTDRAWCLIPPER iface, DWORD dwFlags, HWND hWnd
+) {
+    IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
+    HRESULT hr;
+    TRACE("(%p)->(%08x,%p)\n", This, dwFlags, hWnd);
+
+    EnterCriticalSection(&ddraw_cs);
+    hr = IWineD3DClipper_SetHWnd(This->wineD3DClipper,
+                                 dwFlags,
+                                 hWnd);
+    LeaveCriticalSection(&ddraw_cs);
+    switch(hr)
+    {
+        case WINED3DERR_INVALIDCALL:        return DDERR_INVALIDPARAMS;
+        default:                            return hr;
+    }
+}
+
+/*****************************************************************************
+ * IDirectDrawClipper::GetClipList
+ *
+ * Retrieve a copy of the clip list
+ *
+ * Arguments:
+ *  Rect: Rectangle to be used to clip the clip list or NULL for the
+ *        entire clip list
+ *  ClipList: structure for the resulting copy of the clip list.
+ *            If NULL, fills Size up to the number of bytes necessary to hold
+ *            the entire clip.
+ *  Size: Size of resulting clip list; size of the buffer at ClipList
+ *        or, if ClipList is NULL, receives the required size of the buffer
+ *        in bytes
+ *
+ * RETURNS
+ *  Either DD_OK or DDERR_*
+ ************************************************************************/
+static HRESULT WINAPI IDirectDrawClipperImpl_GetClipList(
+    LPDIRECTDRAWCLIPPER iface, LPRECT lpRect, LPRGNDATA lpClipList,
+    LPDWORD lpdwSize)
+{
+    IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
+    HRESULT hr;
+    TRACE("(%p,%p,%p,%p)\n", This, lpRect, lpClipList, lpdwSize);
+
+    EnterCriticalSection(&ddraw_cs);
+    hr = IWineD3DClipper_GetClipList(This->wineD3DClipper,
+                                     lpRect,
+                                     lpClipList,
+                                     lpdwSize);
+    LeaveCriticalSection(&ddraw_cs);
+    return hr;
+}
+
+/*****************************************************************************
+ * IDirectDrawClipper::SetClipList
+ *
+ * Sets or deletes (if lprgn is NULL) the clip list
+ *
+ * This implementation is a stub and returns DD_OK always to make the app
+ * happy.
+ *
+ * PARAMS
+ *  lprgn   Pointer to a LRGNDATA structure or NULL
+ *  dwFlags not used, must be 0
+ * RETURNS
+ *  Either DD_OK or DDERR_*
+ *****************************************************************************/
+static HRESULT WINAPI IDirectDrawClipperImpl_SetClipList(
+    LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD dwFlag
+) {
+    IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
+    HRESULT hr;
+
+    EnterCriticalSection(&ddraw_cs);
+    hr = IWineD3DClipper_SetClipList(This->wineD3DClipper,
+                                     lprgn,
+                                     dwFlag);
+    LeaveCriticalSection(&ddraw_cs);
+    return hr;
+}
+
+/*****************************************************************************
+ * IDirectDrawClipper::GetHwnd
+ *
+ * Returns the hwnd assigned with SetHwnd
+ *
+ * Arguments:
+ *  hWndPtr: Address to store the HWND at
+ *
+ * Return values:
+ *  Always returns DD_OK;
+ *****************************************************************************/
+static HRESULT WINAPI IDirectDrawClipperImpl_GetHWnd(
+    LPDIRECTDRAWCLIPPER iface, HWND* hWndPtr
+) {
+    IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
+    HRESULT hr;
+    TRACE("(%p)->(%p)\n", This, hWndPtr);
+
+    EnterCriticalSection(&ddraw_cs);
+    hr =  IWineD3DClipper_GetHWnd(This->wineD3DClipper,
+                                  hWndPtr);
+    LeaveCriticalSection(&ddraw_cs);
+    return hr;
+}
+
+/*****************************************************************************
+ * IDirectDrawClipper::Initialize
+ *
+ * Initializes the interface. Well, there isn't much to do for this
+ * implementation, but it stores the DirectDraw Interface.
+ *
+ * Arguments:
+ *  DD: Pointer to a IDirectDraw interface
+ *  Flags: Unsupported by now
+ *
+ * Return values:
+ *  DD_OK on success
+ *  DDERR_ALREADYINITIALIZED if this interface isn't initialized already
+ *****************************************************************************/
+static HRESULT WINAPI IDirectDrawClipperImpl_Initialize(
+     LPDIRECTDRAWCLIPPER iface, LPDIRECTDRAW lpDD, DWORD dwFlags
+) {
+    IDirectDrawImpl* pOwner;
+    IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
+    TRACE("(%p)->(%p,0x%08x)\n", This, lpDD, dwFlags);
+
+    EnterCriticalSection(&ddraw_cs);
+    if (This->ddraw_owner != NULL)
+    {
+        LeaveCriticalSection(&ddraw_cs);
+        return DDERR_ALREADYINITIALIZED;
+    }
+
+    pOwner = lpDD ? ddraw_from_ddraw1(lpDD) : NULL;
+    This->ddraw_owner = pOwner;
+
+    LeaveCriticalSection(&ddraw_cs);
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDrawClipper::IsClipListChanged
+ *
+ * This function is a stub
+ *
+ * Arguments:
+ *  Changed:
+ *
+ * Return values:
+ *  DD_OK, because it's a stub
+ *****************************************************************************/
+static HRESULT WINAPI IDirectDrawClipperImpl_IsClipListChanged(
+    LPDIRECTDRAWCLIPPER iface, BOOL* lpbChanged
+) {
+    IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
+    FIXME("(%p)->(%p),stub!\n",This,lpbChanged);
+
+    /* XXX What is safest? */
+    *lpbChanged = FALSE;
+
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * The VTable
+ *****************************************************************************/
+const IDirectDrawClipperVtbl IDirectDrawClipper_Vtbl =
+{
+    IDirectDrawClipperImpl_QueryInterface,
+    IDirectDrawClipperImpl_AddRef,
+    IDirectDrawClipperImpl_Release,
+    IDirectDrawClipperImpl_GetClipList,
+    IDirectDrawClipperImpl_GetHWnd,
+    IDirectDrawClipperImpl_Initialize,
+    IDirectDrawClipperImpl_IsClipListChanged,
+    IDirectDrawClipperImpl_SetClipList,
+    IDirectDrawClipperImpl_SetHwnd
+};
diff --git a/reactos/dll/directx/wine/ddraw/ddcomimpl.h b/reactos/dll/directx/wine/ddraw/ddcomimpl.h
new file mode 100644 (file)
index 0000000..553d29f
--- /dev/null
@@ -0,0 +1,58 @@
+/* A few helpful macros for implementing COM objects.
+ *
+ * Copyright 2000 TransGaming Technologies Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _DDCOMIMPL_H_
+#define _DDCOMIMPL_H_
+
+#include <stddef.h>
+
+/* Generates the name for a vtable pointer for a given interface. */
+/* The canonical name for a single interface is "lpVtbl". */
+#define ICOM_VFIELD_MULTI_NAME2(iface) ITF_##iface
+#define ICOM_VFIELD_MULTI_NAME(iface) ICOM_VFIELD_MULTI_NAME2(iface)
+
+/* Declares a vtable pointer field in an implementation. */
+#define ICOM_VFIELD_MULTI(iface) \
+       iface ICOM_VFIELD_MULTI_NAME(iface)
+
+/* Returns the offset of a vtable pointer within an implementation object. */
+#define ICOM_VFIELD_OFFSET(impltype, iface) \
+       offsetof(impltype, ICOM_VFIELD_MULTI_NAME(iface))
+
+/* Given an interface pointer, returns the implementation pointer. */
+#define ICOM_OBJECT(impltype, ifacename, ifaceptr)             \
+       (impltype*)((ifaceptr) == NULL ? NULL                   \
+                 : (char*)(ifaceptr) - ICOM_VFIELD_OFFSET(impltype,ifacename))
+
+#define ICOM_THIS_FROM(impltype, ifacename, ifaceptr) \
+       impltype* This = ICOM_OBJECT(impltype, ifacename, ifaceptr)
+
+/* Given an object and interface name, returns a pointer to that interface. */
+#define ICOM_INTERFACE(implobj, iface) \
+       (implobj == NULL ? NULL :&((implobj)->ICOM_VFIELD_MULTI_NAME(iface)))
+
+#define ICOM_INIT_INTERFACE(implobj, ifacename, vtblname) \
+       do { \
+         (implobj)->ICOM_VFIELD_MULTI_NAME(ifacename).lpVtbl = &(vtblname); \
+       } while (0)
+
+#define COM_INTERFACE_CAST(impltype, ifnamefrom, ifnameto, ifaceptr)   \
+       ICOM_INTERFACE(ICOM_OBJECT(impltype, ifnamefrom, ifaceptr), ifnameto)
+
+#endif /* _DDCOMIMPL_H_ */
diff --git a/reactos/dll/directx/wine/ddraw/ddraw.c b/reactos/dll/directx/wine/ddraw/ddraw.c
new file mode 100644 (file)
index 0000000..5e2717e
--- /dev/null
@@ -0,0 +1,3638 @@
+/*
+ * Copyright 1997-2000 Marcus Meissner
+ * Copyright 1998-2000 Lionel Ulmer
+ * Copyright 2000-2001 TransGaming Technologies Inc.
+ * Copyright 2006 Stefan Dösinger
+ * Copyright 2008 Denver Gingerich
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <assert.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define COBJMACROS
+#define NONAMELESSUNION
+
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "wingdi.h"
+#include "wine/exception.h"
+
+#include "ddraw.h"
+#include "d3d.h"
+
+#include "ddraw_private.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
+
+static BOOL IDirectDrawImpl_DDSD_Match(const DDSURFACEDESC2* requested, const DDSURFACEDESC2* provided);
+static HRESULT IDirectDrawImpl_AttachD3DDevice(IDirectDrawImpl *This, IDirectDrawSurfaceImpl *primary);
+static HRESULT IDirectDrawImpl_CreateNewSurface(IDirectDrawImpl *This, DDSURFACEDESC2 *pDDSD, IDirectDrawSurfaceImpl **ppSurf, UINT level);
+static HRESULT IDirectDrawImpl_CreateGDISwapChain(IDirectDrawImpl *This, IDirectDrawSurfaceImpl *primary);
+
+/* Device identifier. Don't relay it to WineD3D */
+static const DDDEVICEIDENTIFIER2 deviceidentifier =
+{
+    "display",
+    "DirectDraw HAL",
+    { { 0x00010001, 0x00010001 } },
+    0, 0, 0, 0,
+    /* a8373c10-7ac4-4deb-849a-009844d08b2d */
+    {0xa8373c10,0x7ac4,0x4deb, {0x84,0x9a,0x00,0x98,0x44,0xd0,0x8b,0x2d}},
+    0
+};
+
+/*****************************************************************************
+ * IUnknown Methods
+ *****************************************************************************/
+
+/*****************************************************************************
+ * IDirectDraw7::QueryInterface
+ *
+ * Queries different interfaces of the DirectDraw object. It can return
+ * IDirectDraw interfaces in version 1, 2, 4 and 7, and IDirect3D interfaces
+ * in version 1, 2, 3 and 7. An IDirect3DDevice can be created with this
+ * method.
+ * The returned interface is AddRef()-ed before it's returned
+ *
+ * Used for version 1, 2, 4 and 7
+ *
+ * Params:
+ *  refiid: Interface ID asked for
+ *  obj: Used to return the interface pointer
+ *
+ * Returns:
+ *  S_OK if an interface was found
+ *  E_NOINTERFACE if the requested interface wasn't found
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_QueryInterface(IDirectDraw7 *iface,
+                               REFIID refiid,
+                               void **obj)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+
+    TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(refiid), obj);
+
+    /* Can change surface impl type */
+    EnterCriticalSection(&ddraw_cs);
+
+    /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
+    *obj = NULL;
+
+    if(!refiid)
+    {
+        LeaveCriticalSection(&ddraw_cs);
+        return DDERR_INVALIDPARAMS;
+    }
+
+    /* Check DirectDraw Interfaces */
+    if ( IsEqualGUID( &IID_IUnknown, refiid ) ||
+         IsEqualGUID( &IID_IDirectDraw7, refiid ) )
+    {
+        *obj = This;
+        TRACE("(%p) Returning IDirectDraw7 interface at %p\n", This, *obj);
+    }
+    else if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) )
+    {
+        *obj = &This->IDirectDraw4_vtbl;
+        TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This, *obj);
+    }
+    else if ( IsEqualGUID( &IID_IDirectDraw3, refiid ) )
+    {
+        /* This Interface exists in ddrawex.dll, it is implemented in a wrapper */
+        WARN("IDirectDraw3 is not valid in ddraw.dll\n");
+        *obj = NULL;
+        LeaveCriticalSection(&ddraw_cs);
+        return E_NOINTERFACE;
+    }
+    else if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) )
+    {
+        *obj = &This->IDirectDraw2_vtbl;
+        TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This, *obj);
+    }
+    else if ( IsEqualGUID( &IID_IDirectDraw, refiid ) )
+    {
+        *obj = &This->IDirectDraw_vtbl;
+        TRACE("(%p) Returning IDirectDraw interface at %p\n", This, *obj);
+    }
+
+    /* Direct3D
+     * The refcount unit test revealed that an IDirect3D7 interface can only be queried
+     * from a DirectDraw object that was created as an IDirectDraw7 interface. No idea
+     * who had this idea and why. The older interfaces can query and IDirect3D version
+     * because they are all created as IDirectDraw(1). This isn't really crucial behavior,
+     * and messy to implement with the common creation function, so it has been left out here.
+     */
+    else if ( IsEqualGUID( &IID_IDirect3D  , refiid ) ||
+              IsEqualGUID( &IID_IDirect3D2 , refiid ) ||
+              IsEqualGUID( &IID_IDirect3D3 , refiid ) ||
+              IsEqualGUID( &IID_IDirect3D7 , refiid ) )
+    {
+        /* Check the surface implementation */
+        if(This->ImplType == SURFACE_UNKNOWN)
+        {
+            /* Apps may create the IDirect3D Interface before the primary surface.
+             * set the surface implementation */
+            This->ImplType = SURFACE_OPENGL;
+            TRACE("(%p) Choosing OpenGL surfaces because a Direct3D interface was requested\n", This);
+        }
+        else if(This->ImplType != SURFACE_OPENGL && DefaultSurfaceType == SURFACE_UNKNOWN)
+        {
+            ERR("(%p) The App is requesting a D3D device, but a non-OpenGL surface type was choosen. Prepare for trouble!\n", This);
+            ERR(" (%p) You may want to contact wine-devel for help\n", This);
+            /* Should I assert(0) here??? */
+        }
+        else if(This->ImplType != SURFACE_OPENGL)
+        {
+            WARN("The app requests a Direct3D interface, but non-opengl surfaces where set in winecfg\n");
+            /* Do not abort here, only reject 3D Device creation */
+        }
+
+        if ( IsEqualGUID( &IID_IDirect3D  , refiid ) )
+        {
+            This->d3dversion = 1;
+            *obj = &This->IDirect3D_vtbl;
+            TRACE(" returning Direct3D interface at %p.\n", *obj);
+        }
+        else if ( IsEqualGUID( &IID_IDirect3D2  , refiid ) )
+        {
+            This->d3dversion = 2;
+            *obj = &This->IDirect3D2_vtbl;
+            TRACE(" returning Direct3D2 interface at %p.\n", *obj);
+        }
+        else if ( IsEqualGUID( &IID_IDirect3D3  , refiid ) )
+        {
+            This->d3dversion = 3;
+            *obj = &This->IDirect3D3_vtbl;
+            TRACE(" returning Direct3D3 interface at %p.\n", *obj);
+        }
+        else if(IsEqualGUID( &IID_IDirect3D7  , refiid ))
+        {
+            This->d3dversion = 7;
+            *obj = &This->IDirect3D7_vtbl;
+            TRACE(" returning Direct3D7 interface at %p.\n", *obj);
+        }
+    }
+    else if (IsEqualGUID(refiid, &IID_IWineD3DDeviceParent))
+    {
+        *obj = &This->device_parent_vtbl;
+    }
+
+    /* Unknown interface */
+    else
+    {
+        ERR("(%p)->(%s, %p): No interface found\n", This, debugstr_guid(refiid), obj);
+        LeaveCriticalSection(&ddraw_cs);
+        return E_NOINTERFACE;
+    }
+
+    IUnknown_AddRef( (IUnknown *) *obj );
+    LeaveCriticalSection(&ddraw_cs);
+    return S_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::AddRef
+ *
+ * Increases the interfaces refcount, basically
+ *
+ * DDraw refcounting is a bit tricky. The different DirectDraw interface
+ * versions have individual refcounts, but the IDirect3D interfaces do not.
+ * All interfaces are from one object, that means calling QueryInterface on an
+ * IDirectDraw7 interface for an IDirectDraw4 interface does not create a new
+ * IDirectDrawImpl object.
+ *
+ * That means all AddRef and Release implementations of IDirectDrawX work
+ * with their own counter, and IDirect3DX::AddRef thunk to IDirectDraw (1),
+ * except of IDirect3D7 which thunks to IDirectDraw7
+ *
+ * Returns: The new refcount
+ *
+ *****************************************************************************/
+static ULONG WINAPI
+IDirectDrawImpl_AddRef(IDirectDraw7 *iface)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    ULONG ref = InterlockedIncrement(&This->ref7);
+
+    TRACE("(%p) : incrementing IDirectDraw7 refcount from %u.\n", This, ref -1);
+
+    if(ref == 1) InterlockedIncrement(&This->numIfaces);
+
+    return ref;
+}
+
+/*****************************************************************************
+ * IDirectDrawImpl_Destroy
+ *
+ * Destroys a ddraw object if all refcounts are 0. This is to share code
+ * between the IDirectDrawX::Release functions
+ *
+ * Params:
+ *  This: DirectDraw object to destroy
+ *
+ *****************************************************************************/
+void
+IDirectDrawImpl_Destroy(IDirectDrawImpl *This)
+{
+    /* Clear the cooplevel to restore window and display mode */
+    IDirectDraw7_SetCooperativeLevel((IDirectDraw7 *)This, NULL, DDSCL_NORMAL);
+
+    /* Destroy the device window if we created one */
+    if(This->devicewindow != 0)
+    {
+        TRACE(" (%p) Destroying the device window %p\n", This, This->devicewindow);
+        DestroyWindow(This->devicewindow);
+        This->devicewindow = 0;
+    }
+
+    /* Unregister the window class */
+    UnregisterClassA(This->classname, 0);
+
+    EnterCriticalSection(&ddraw_cs);
+    list_remove(&This->ddraw_list_entry);
+    LeaveCriticalSection(&ddraw_cs);
+
+    /* Release the attached WineD3D stuff */
+    IWineD3DDevice_Release(This->wineD3DDevice);
+    IWineD3D_Release(This->wineD3D);
+
+    /* Now free the object */
+    HeapFree(GetProcessHeap(), 0, This);
+}
+
+/*****************************************************************************
+ * IDirectDraw7::Release
+ *
+ * Decreases the refcount. If the refcount falls to 0, the object is destroyed
+ *
+ * Returns: The new refcount
+ *****************************************************************************/
+static ULONG WINAPI
+IDirectDrawImpl_Release(IDirectDraw7 *iface)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    ULONG ref = InterlockedDecrement(&This->ref7);
+
+    TRACE("(%p)->() decrementing IDirectDraw7 refcount from %u.\n", This, ref +1);
+
+    if(ref == 0)
+    {
+        ULONG ifacecount = InterlockedDecrement(&This->numIfaces);
+        if(ifacecount == 0) IDirectDrawImpl_Destroy(This);
+    }
+
+    return ref;
+}
+
+/*****************************************************************************
+ * IDirectDraw methods
+ *****************************************************************************/
+
+/*****************************************************************************
+ * IDirectDraw7::SetCooperativeLevel
+ *
+ * Sets the cooperative level for the DirectDraw object, and the window
+ * assigned to it. The cooperative level determines the general behavior
+ * of the DirectDraw application
+ *
+ * Warning: This is quite tricky, as it's not really documented which
+ * cooperative levels can be combined with each other. If a game fails
+ * after this function, try to check the cooperative levels passed on
+ * Windows, and if it returns something different.
+ *
+ * If you think that this function caused the failure because it writes a
+ * fixme, be sure to run again with a +ddraw trace.
+ *
+ * What is known about cooperative levels (See the ddraw modes test):
+ * DDSCL_EXCLUSIVE and DDSCL_FULLSCREEN must be used with each other
+ * DDSCL_NORMAL is not compatible with DDSCL_EXCLUSIVE or DDSCL_FULLSCREEN
+ * DDSCL_SETFOCUSWINDOW can be passed only in DDSCL_NORMAL mode, but after that
+ * DDSCL_FULLSCREEN can be activated
+ * DDSCL_SETFOCUSWINDOW may only be used with DDSCL_NOWINDOWCHANGES
+ *
+ * Handled flags: DDSCL_NORMAL, DDSCL_FULLSCREEN, DDSCL_EXCLUSIVE,
+ *                DDSCL_SETFOCUSWINDOW (partially),
+ *                DDSCL_MULTITHREADED (work in progress)
+ *
+ * Unhandled flags, which should be implemented
+ *  DDSCL_SETDEVICEWINDOW: Sets a window specially used for rendering (I don't
+ *  expect any difference to a normal window for wine)
+ *  DDSCL_CREATEDEVICEWINDOW: Tells ddraw to create its own window for
+ *  rendering (Possible test case: Half-life)
+ *
+ * Unsure about these: DDSCL_FPUSETUP DDSCL_FPURESERVE
+ *
+ * These don't seem very important for wine:
+ *  DDSCL_ALLOWREBOOT, DDSCL_NOWINDOWCHANGES, DDSCL_ALLOWMODEX
+ *
+ * Returns:
+ *  DD_OK if the cooperative level was set successfully
+ *  DDERR_INVALIDPARAMS if the passed cooperative level combination is invalid
+ *  DDERR_HWNDALREADYSET if DDSCL_SETFOCUSWINDOW is passed in exclusive mode
+ *   (Probably others too, have to investigate)
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_SetCooperativeLevel(IDirectDraw7 *iface,
+                                    HWND hwnd,
+                                    DWORD cooplevel)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    HWND window;
+
+    TRACE("(%p)->(%p,%08x)\n",This,hwnd,cooplevel);
+    DDRAW_dump_cooperativelevel(cooplevel);
+
+    EnterCriticalSection(&ddraw_cs);
+
+    /* Get the old window */
+    window = This->dest_window;
+
+    /* Tests suggest that we need one of them: */
+    if(!(cooplevel & (DDSCL_SETFOCUSWINDOW |
+                      DDSCL_NORMAL         |
+                      DDSCL_EXCLUSIVE      )))
+    {
+        TRACE("Incorrect cooplevel flags, returning DDERR_INVALIDPARAMS\n");
+        LeaveCriticalSection(&ddraw_cs);
+        return DDERR_INVALIDPARAMS;
+    }
+
+    /* Handle those levels first which set various hwnds */
+    if(cooplevel & DDSCL_SETFOCUSWINDOW)
+    {
+        /* This isn't compatible with a lot of flags */
+        if(cooplevel & ( DDSCL_MULTITHREADED   |
+                         DDSCL_FPUSETUP        |
+                         DDSCL_FPUPRESERVE     |
+                         DDSCL_ALLOWREBOOT     |
+                         DDSCL_ALLOWMODEX      |
+                         DDSCL_SETDEVICEWINDOW |
+                         DDSCL_NORMAL          |
+                         DDSCL_EXCLUSIVE       |
+                         DDSCL_FULLSCREEN      ) )
+        {
+            TRACE("Called with incompatible flags, returning DDERR_INVALIDPARAMS\n");
+            LeaveCriticalSection(&ddraw_cs);
+            return DDERR_INVALIDPARAMS;
+        }
+        else if( (This->cooperative_level & DDSCL_FULLSCREEN) && window)
+        {
+            TRACE("Setting DDSCL_SETFOCUSWINDOW with an already set window, returning DDERR_HWNDALREADYSET\n");
+            LeaveCriticalSection(&ddraw_cs);
+            return DDERR_HWNDALREADYSET;
+        }
+
+        This->focuswindow = hwnd;
+        /* Won't use the hwnd param for anything else */
+        hwnd = NULL;
+
+        /* Use the focus window for drawing too */
+        This->dest_window = This->focuswindow;
+
+        /* Destroy the device window, if we have one */
+        if(This->devicewindow)
+        {
+            DestroyWindow(This->devicewindow);
+            This->devicewindow = NULL;
+        }
+    }
+    /* DDSCL_NORMAL or DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE */
+    if(cooplevel & DDSCL_NORMAL)
+    {
+        /* Can't coexist with fullscreen or exclusive */
+        if(cooplevel & (DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE) )
+        {
+            TRACE("(%p) DDSCL_NORMAL is not compative with DDSCL_FULLSCREEN or DDSCL_EXCLUSIVE\n", This);
+            LeaveCriticalSection(&ddraw_cs);
+            return DDERR_INVALIDPARAMS;
+        }
+
+        /* Switching from fullscreen? */
+        if(This->cooperative_level & DDSCL_FULLSCREEN)
+        {
+            /* Restore the display mode */
+            IDirectDraw7_RestoreDisplayMode(iface);
+
+            This->cooperative_level &= ~DDSCL_FULLSCREEN;
+            This->cooperative_level &= ~DDSCL_EXCLUSIVE;
+            This->cooperative_level &= ~DDSCL_ALLOWMODEX;
+        }
+
+        /* Don't override focus windows or private device windows */
+        if( hwnd &&
+            !(This->focuswindow) &&
+            !(This->devicewindow) &&
+            (hwnd != window) )
+        {
+            This->dest_window = hwnd;
+        }
+    }
+    else if(cooplevel & DDSCL_FULLSCREEN)
+    {
+        /* Needs DDSCL_EXCLUSIVE */
+        if(!(cooplevel & DDSCL_EXCLUSIVE) )
+        {
+            TRACE("(%p) DDSCL_FULLSCREEN needs DDSCL_EXCLUSIVE\n", This);
+            LeaveCriticalSection(&ddraw_cs);
+            return DDERR_INVALIDPARAMS;
+        }
+        /* Need a HWND
+        if(hwnd == 0)
+        {
+            TRACE("(%p) DDSCL_FULLSCREEN needs a HWND\n", This);
+            return DDERR_INVALIDPARAMS;
+        }
+        */
+
+        This->cooperative_level &= ~DDSCL_NORMAL;
+
+        /* Don't override focus windows or private device windows */
+        if( hwnd &&
+            !(This->focuswindow) &&
+            !(This->devicewindow) &&
+            (hwnd != window) )
+        {
+            This->dest_window = hwnd;
+        }
+    }
+    else if(cooplevel & DDSCL_EXCLUSIVE)
+    {
+        TRACE("(%p) DDSCL_EXCLUSIVE needs DDSCL_FULLSCREEN\n", This);
+        LeaveCriticalSection(&ddraw_cs);
+        return DDERR_INVALIDPARAMS;
+    }
+
+    if(cooplevel & DDSCL_CREATEDEVICEWINDOW)
+    {
+        /* Don't create a device window if a focus window is set */
+        if( !(This->focuswindow) )
+        {
+            HWND devicewindow = CreateWindowExA(0, This->classname, "DDraw device window",
+                                                WS_POPUP, 0, 0,
+                                                GetSystemMetrics(SM_CXSCREEN),
+                                                GetSystemMetrics(SM_CYSCREEN),
+                                                NULL, NULL, GetModuleHandleA(0), NULL);
+
+            ShowWindow(devicewindow, SW_SHOW);   /* Just to be sure */
+            TRACE("(%p) Created a DDraw device window. HWND=%p\n", This, devicewindow);
+
+            This->devicewindow = devicewindow;
+            This->dest_window = devicewindow;
+        }
+    }
+
+    if(cooplevel & DDSCL_MULTITHREADED && !(This->cooperative_level & DDSCL_MULTITHREADED))
+    {
+        /* Enable thread safety in wined3d */
+        IWineD3DDevice_SetMultithreaded(This->wineD3DDevice);
+    }
+
+    /* Unhandled flags */
+    if(cooplevel & DDSCL_ALLOWREBOOT)
+        WARN("(%p) Unhandled flag DDSCL_ALLOWREBOOT, harmless\n", This);
+    if(cooplevel & DDSCL_ALLOWMODEX)
+        WARN("(%p) Unhandled flag DDSCL_ALLOWMODEX, harmless\n", This);
+    if(cooplevel & DDSCL_FPUSETUP)
+        WARN("(%p) Unhandled flag DDSCL_FPUSETUP, harmless\n", This);
+
+    /* Store the cooperative_level */
+    This->cooperative_level |= cooplevel;
+    TRACE("SetCooperativeLevel retuning DD_OK\n");
+    LeaveCriticalSection(&ddraw_cs);
+    return DD_OK;
+}
+
+/*****************************************************************************
+ *
+ * Helper function for SetDisplayMode and RestoreDisplayMode
+ *
+ * Implements DirectDraw's SetDisplayMode, but ignores the value of
+ * ForceRefreshRate, since it is already handled by
+ * IDirectDrawImpl_SetDisplayMode.  RestoreDisplayMode can use this function
+ * without worrying that ForceRefreshRate will override the refresh rate.  For
+ * argument and return value documentation, see
+ * IDirectDrawImpl_SetDisplayMode.
+ *
+ *****************************************************************************/
+static HRESULT
+IDirectDrawImpl_SetDisplayModeNoOverride(IDirectDraw7 *iface,
+                                         DWORD Width,
+                                         DWORD Height,
+                                         DWORD BPP,
+                                         DWORD RefreshRate,
+                                         DWORD Flags)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    WINED3DDISPLAYMODE Mode;
+    HRESULT hr;
+    TRACE("(%p)->(%d,%d,%d,%d,%x): Relay!\n", This, Width, Height, BPP, RefreshRate, Flags);
+
+    EnterCriticalSection(&ddraw_cs);
+    if( !Width || !Height )
+    {
+        ERR("Width=%d, Height=%d, what to do?\n", Width, Height);
+        /* It looks like Need for Speed Porsche Unleashed expects DD_OK here */
+        LeaveCriticalSection(&ddraw_cs);
+        return DD_OK;
+    }
+
+    /* Check the exclusive mode
+    if(!(This->cooperative_level & DDSCL_EXCLUSIVE))
+        return DDERR_NOEXCLUSIVEMODE;
+     * This is WRONG. Don't know if the SDK is completely
+     * wrong and if there are any conditions when DDERR_NOEXCLUSIVE
+     * is returned, but Half-Life 1.1.1.1 (Steam version)
+     * depends on this
+     */
+
+    Mode.Width = Width;
+    Mode.Height = Height;
+    Mode.RefreshRate = RefreshRate;
+    switch(BPP)
+    {
+        case 8:  Mode.Format = WINED3DFMT_P8;       break;
+        case 15: Mode.Format = WINED3DFMT_X1R5G5B5; break;
+        case 16: Mode.Format = WINED3DFMT_R5G6B5;   break;
+        case 24: Mode.Format = WINED3DFMT_R8G8B8;   break;
+        case 32: Mode.Format = WINED3DFMT_X8R8G8B8; break;
+    }
+
+    /* TODO: The possible return values from msdn suggest that
+     * the screen mode can't be changed if a surface is locked
+     * or some drawing is in progress
+     */
+
+    /* TODO: Lose the primary surface */
+    hr = IWineD3DDevice_SetDisplayMode(This->wineD3DDevice,
+                                       0, /* First swapchain */
+                                       &Mode);
+    LeaveCriticalSection(&ddraw_cs);
+    switch(hr)
+    {
+        case WINED3DERR_NOTAVAILABLE:       return DDERR_UNSUPPORTED;
+        default:                            return hr;
+    }
+}
+
+/*****************************************************************************
+ * IDirectDraw7::SetDisplayMode
+ *
+ * Sets the display screen resolution, color depth and refresh frequency
+ * when in fullscreen mode (in theory).
+ * Possible return values listed in the SDK suggest that this method fails
+ * when not in fullscreen mode, but this is wrong. Windows 2000 happily sets
+ * the display mode in DDSCL_NORMAL mode without an hwnd specified.
+ * It seems to be valid to pass 0 for With and Height, this has to be tested
+ * It could mean that the current video mode should be left as-is. (But why
+ * call it then?)
+ *
+ * Params:
+ *  Height, Width: Screen dimension
+ *  BPP: Color depth in Bits per pixel
+ *  Refreshrate: Screen refresh rate
+ *  Flags: Other stuff
+ *
+ * Returns
+ *  DD_OK on success
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_SetDisplayMode(IDirectDraw7 *iface,
+                               DWORD Width,
+                               DWORD Height,
+                               DWORD BPP,
+                               DWORD RefreshRate,
+                               DWORD Flags)
+{
+    if (force_refresh_rate != 0)
+    {
+        TRACE("ForceRefreshRate overriding passed-in refresh rate (%d Hz) to %d Hz\n", RefreshRate, force_refresh_rate);
+        RefreshRate = force_refresh_rate;
+    }
+
+    return IDirectDrawImpl_SetDisplayModeNoOverride(iface, Width, Height, BPP,
+                                                    RefreshRate, Flags);
+}
+
+/*****************************************************************************
+ * IDirectDraw7::RestoreDisplayMode
+ *
+ * Restores the display mode to what it was at creation time. Basically.
+ *
+ * A problem arises when there are 2 DirectDraw objects using the same hwnd:
+ *  -> DD_1 finds the screen at 1400x1050x32 when created, sets it to 640x480x16
+ *  -> DD_2 is created, finds the screen at 640x480x16, sets it to 1024x768x32
+ *  -> DD_1 is released. The screen should be left at 1024x768x32.
+ *  -> DD_2 is released. The screen should be set to 1400x1050x32
+ * This case is unhandled right now, but Empire Earth does it this way.
+ * (But perhaps there is something in SetCooperativeLevel to prevent this)
+ *
+ * The msdn says that this method resets the display mode to what it was before
+ * SetDisplayMode was called. What if SetDisplayModes is called 2 times??
+ *
+ * Returns
+ *  DD_OK on success
+ *  DDERR_NOEXCLUSIVE mode if the device isn't in fullscreen mode
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_RestoreDisplayMode(IDirectDraw7 *iface)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    TRACE("(%p)\n", This);
+
+    return IDirectDrawImpl_SetDisplayModeNoOverride(iface,
+            This->orig_width, This->orig_height, This->orig_bpp, 0, 0);
+}
+
+/*****************************************************************************
+ * IDirectDraw7::GetCaps
+ *
+ * Returns the drives capabilities
+ *
+ * Used for version 1, 2, 4 and 7
+ *
+ * Params:
+ *  DriverCaps: Structure to write the Hardware accelerated caps to
+ *  HelCaps: Structure to write the emulation caps to
+ *
+ * Returns
+ *  This implementation returns DD_OK only
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_GetCaps(IDirectDraw7 *iface,
+                        DDCAPS *DriverCaps,
+                        DDCAPS *HELCaps)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    DDCAPS caps;
+    WINED3DCAPS winecaps;
+    HRESULT hr;
+    DDSCAPS2 ddscaps = {0, 0, 0, {0}};
+    TRACE("(%p)->(%p,%p)\n", This, DriverCaps, HELCaps);
+
+    /* One structure must be != NULL */
+    if( (!DriverCaps) && (!HELCaps) )
+    {
+        ERR("(%p) Invalid params to IDirectDrawImpl_GetCaps\n", This);
+        return DDERR_INVALIDPARAMS;
+    }
+
+    memset(&caps, 0, sizeof(caps));
+    memset(&winecaps, 0, sizeof(winecaps));
+    caps.dwSize = sizeof(caps);
+    EnterCriticalSection(&ddraw_cs);
+    hr = IWineD3DDevice_GetDeviceCaps(This->wineD3DDevice, &winecaps);
+    if(FAILED(hr)) {
+        WARN("IWineD3DDevice::GetDeviceCaps failed\n");
+        LeaveCriticalSection(&ddraw_cs);
+        return hr;
+    }
+
+    hr = IDirectDraw7_GetAvailableVidMem(iface, &ddscaps, &caps.dwVidMemTotal, &caps.dwVidMemFree);
+    LeaveCriticalSection(&ddraw_cs);
+    if(FAILED(hr)) {
+        WARN("IDirectDraw7::GetAvailableVidMem failed\n");
+        return hr;
+    }
+
+    caps.dwCaps = winecaps.DirectDrawCaps.Caps;
+    caps.dwCaps2 = winecaps.DirectDrawCaps.Caps2;
+    caps.dwCKeyCaps = winecaps.DirectDrawCaps.CKeyCaps;
+    caps.dwFXCaps = winecaps.DirectDrawCaps.FXCaps;
+    caps.dwPalCaps = winecaps.DirectDrawCaps.PalCaps;
+    caps.ddsCaps.dwCaps = winecaps.DirectDrawCaps.ddsCaps;
+    caps.dwSVBCaps = winecaps.DirectDrawCaps.SVBCaps;
+    caps.dwSVBCKeyCaps = winecaps.DirectDrawCaps.SVBCKeyCaps;
+    caps.dwSVBFXCaps = winecaps.DirectDrawCaps.SVBFXCaps;
+    caps.dwVSBCaps = winecaps.DirectDrawCaps.VSBCaps;
+    caps.dwVSBCKeyCaps = winecaps.DirectDrawCaps.VSBCKeyCaps;
+    caps.dwVSBFXCaps = winecaps.DirectDrawCaps.VSBFXCaps;
+    caps.dwSSBCaps = winecaps.DirectDrawCaps.SSBCaps;
+    caps.dwSSBCKeyCaps = winecaps.DirectDrawCaps.SSBCKeyCaps;
+    caps.dwSSBFXCaps = winecaps.DirectDrawCaps.SSBFXCaps;
+
+    /* Even if WineD3D supports 3D rendering, remove the cap if ddraw is configured
+     * not to use it
+     */
+    if(DefaultSurfaceType == SURFACE_GDI) {
+        caps.dwCaps &= ~DDCAPS_3D;
+        caps.ddsCaps.dwCaps &= ~(DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER);
+    }
+    if(winecaps.DirectDrawCaps.StrideAlign != 0) {
+        caps.dwCaps |= DDCAPS_ALIGNSTRIDE;
+        caps.dwAlignStrideAlign = winecaps.DirectDrawCaps.StrideAlign;
+    }
+
+    if(DriverCaps)
+    {
+        DD_STRUCT_COPY_BYSIZE(DriverCaps, &caps);
+        if (TRACE_ON(ddraw))
+        {
+            TRACE("Driver Caps :\n");
+            DDRAW_dump_DDCAPS(DriverCaps);
+        }
+
+    }
+    if(HELCaps)
+    {
+        DD_STRUCT_COPY_BYSIZE(HELCaps, &caps);
+        if (TRACE_ON(ddraw))
+        {
+            TRACE("HEL Caps :\n");
+            DDRAW_dump_DDCAPS(HELCaps);
+        }
+    }
+
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::Compact
+ *
+ * No idea what it does, MSDN says it's not implemented.
+ *
+ * Returns
+ *  DD_OK, but this is unchecked
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_Compact(IDirectDraw7 *iface)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    TRACE("(%p)\n", This);
+
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::GetDisplayMode
+ *
+ * Returns information about the current display mode
+ *
+ * Exists in Version 1, 2, 4 and 7
+ *
+ * Params:
+ *  DDSD: Address of a surface description structure to write the info to
+ *
+ * Returns
+ *  DD_OK
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_GetDisplayMode(IDirectDraw7 *iface,
+                               DDSURFACEDESC2 *DDSD)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    HRESULT hr;
+    WINED3DDISPLAYMODE Mode;
+    DWORD Size;
+    TRACE("(%p)->(%p): Relay\n", This, DDSD);
+
+    EnterCriticalSection(&ddraw_cs);
+    /* This seems sane */
+    if(!DDSD) 
+    {
+        LeaveCriticalSection(&ddraw_cs);
+        return DDERR_INVALIDPARAMS;
+    }
+
+    /* The necessary members of LPDDSURFACEDESC and LPDDSURFACEDESC2 are equal,
+     * so one method can be used for all versions (Hopefully)
+     */
+    hr = IWineD3DDevice_GetDisplayMode(This->wineD3DDevice,
+                                      0 /* swapchain 0 */,
+                                      &Mode);
+    if( hr != D3D_OK )
+    {
+        ERR(" (%p) IWineD3DDevice::GetDisplayMode returned %08x\n", This, hr);
+        LeaveCriticalSection(&ddraw_cs);
+        return hr;
+    }
+
+    Size = DDSD->dwSize;
+    memset(DDSD, 0, Size);
+
+    DDSD->dwSize = Size;
+    DDSD->dwFlags |= DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_PITCH | DDSD_REFRESHRATE;
+    DDSD->dwWidth = Mode.Width;
+    DDSD->dwHeight = Mode.Height; 
+    DDSD->u2.dwRefreshRate = 60;
+    DDSD->ddsCaps.dwCaps = 0;
+    DDSD->u4.ddpfPixelFormat.dwSize = sizeof(DDSD->u4.ddpfPixelFormat);
+    PixelFormat_WineD3DtoDD(&DDSD->u4.ddpfPixelFormat, Mode.Format);
+    DDSD->u1.lPitch = Mode.Width * DDSD->u4.ddpfPixelFormat.u1.dwRGBBitCount / 8;
+
+    if(TRACE_ON(ddraw))
+    {
+        TRACE("Returning surface desc :\n");
+        DDRAW_dump_surface_desc(DDSD);
+    }
+
+    LeaveCriticalSection(&ddraw_cs);
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::GetFourCCCodes
+ *
+ * Returns an array of supported FourCC codes.
+ *
+ * Exists in Version 1, 2, 4 and 7
+ *
+ * Params:
+ *  NumCodes: Contains the number of Codes that Codes can carry. Returns the number
+ *            of enumerated codes
+ *  Codes: Pointer to an array of DWORDs where the supported codes are written
+ *         to
+ *
+ * Returns
+ *  Always returns DD_OK, as it's a stub for now
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_GetFourCCCodes(IDirectDraw7 *iface,
+                               DWORD *NumCodes, DWORD *Codes)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    WINED3DFORMAT formats[] = {
+        WINED3DFMT_YUY2, WINED3DFMT_UYVY, WINED3DFMT_YV12,
+        WINED3DFMT_DXT1, WINED3DFMT_DXT2, WINED3DFMT_DXT3, WINED3DFMT_DXT4, WINED3DFMT_DXT5,
+        WINED3DFMT_ATI2N, WINED3DFMT_NVHU, WINED3DFMT_NVHS
+    };
+    DWORD count = 0, i, outsize;
+    HRESULT hr;
+    WINED3DDISPLAYMODE d3ddm;
+    WINED3DSURFTYPE type = This->ImplType;
+    TRACE("(%p)->(%p, %p)\n", This, NumCodes, Codes);
+
+    IWineD3DDevice_GetDisplayMode(This->wineD3DDevice,
+                                  0 /* swapchain 0 */,
+                                  &d3ddm);
+
+    outsize = NumCodes && Codes ? *NumCodes : 0;
+
+    if(type == SURFACE_UNKNOWN) type = SURFACE_GDI;
+
+    for(i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) {
+        hr = IWineD3D_CheckDeviceFormat(This->wineD3D,
+                                        WINED3DADAPTER_DEFAULT,
+                                        WINED3DDEVTYPE_HAL,
+                                        d3ddm.Format /* AdapterFormat */,
+                                        0 /* usage */,
+                                        WINED3DRTYPE_SURFACE,
+                                        formats[i],
+                                        type);
+        if(SUCCEEDED(hr)) {
+            if(count < outsize) {
+                Codes[count] = formats[i];
+            }
+            count++;
+        }
+    }
+    if(NumCodes) {
+        TRACE("Returning %u FourCC codes\n", count);
+        *NumCodes = count;
+    }
+
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::GetMonitorFrequency
+ *
+ * Returns the monitor's frequency
+ *
+ * Exists in Version 1, 2, 4 and 7
+ *
+ * Params:
+ *  Freq: Pointer to a DWORD to write the frequency to
+ *
+ * Returns
+ *  Always returns DD_OK
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_GetMonitorFrequency(IDirectDraw7 *iface,
+                                    DWORD *Freq)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    TRACE("(%p)->(%p)\n", This, Freq);
+
+    /* Ideally this should be in WineD3D, as it concerns the screen setup,
+     * but for now this should make the games happy
+     */
+    *Freq = 60;
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::GetVerticalBlankStatus
+ *
+ * Returns the Vertical blank status of the monitor. This should be in WineD3D
+ * too basically, but as it's a semi stub, I didn't create a function there
+ *
+ * Params:
+ *  status: Pointer to a BOOL to be filled with the vertical blank status
+ *
+ * Returns
+ *  DD_OK on success
+ *  DDERR_INVALIDPARAMS if status is NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_GetVerticalBlankStatus(IDirectDraw7 *iface,
+                                       BOOL *status)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    TRACE("(%p)->(%p)\n", This, status);
+
+    /* This looks sane, the MSDN suggests it too */
+    EnterCriticalSection(&ddraw_cs);
+    if(!status)
+    {
+        LeaveCriticalSection(&ddraw_cs);
+        return DDERR_INVALIDPARAMS;
+    }
+
+    *status = This->fake_vblank;
+    This->fake_vblank = !This->fake_vblank;
+    LeaveCriticalSection(&ddraw_cs);
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::GetAvailableVidMem
+ *
+ * Returns the total and free video memory
+ *
+ * Params:
+ *  Caps: Specifies the memory type asked for
+ *  total: Pointer to a DWORD to be filled with the total memory
+ *  free: Pointer to a DWORD to be filled with the free memory
+ *
+ * Returns
+ *  DD_OK on success
+ *  DDERR_INVALIDPARAMS of free and total are NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_GetAvailableVidMem(IDirectDraw7 *iface, DDSCAPS2 *Caps, DWORD *total, DWORD *free)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    TRACE("(%p)->(%p, %p, %p)\n", This, Caps, total, free);
+
+    if(TRACE_ON(ddraw))
+    {
+        TRACE("(%p) Asked for memory with description: ", This);
+        DDRAW_dump_DDSCAPS2(Caps);
+    }
+    EnterCriticalSection(&ddraw_cs);
+
+    /* Todo: System memory vs local video memory vs non-local video memory
+     * The MSDN also mentions differences between texture memory and other
+     * resources, but that's not important
+     */
+
+    if( (!total) && (!free) )
+    {
+        LeaveCriticalSection(&ddraw_cs);
+        return DDERR_INVALIDPARAMS;
+    }
+
+    if(total) *total = This->total_vidmem;
+    if(free) *free = IWineD3DDevice_GetAvailableTextureMem(This->wineD3DDevice);
+
+    LeaveCriticalSection(&ddraw_cs);
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::Initialize
+ *
+ * Initializes a DirectDraw interface.
+ *
+ * Params:
+ *  GUID: Interface identifier. Well, don't know what this is really good
+ *   for
+ *
+ * Returns
+ *  Returns DD_OK on the first call,
+ *  DDERR_ALREADYINITIALIZED on repeated calls
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_Initialize(IDirectDraw7 *iface,
+                           GUID *Guid)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    TRACE("(%p)->(%s): No-op\n", This, debugstr_guid(Guid));
+
+    if(This->initialized)
+    {
+        return DDERR_ALREADYINITIALIZED;
+    }
+    else
+    {
+        return DD_OK;
+    }
+}
+
+/*****************************************************************************
+ * IDirectDraw7::FlipToGDISurface
+ *
+ * "Makes the surface that the GDI writes to the primary surface"
+ * Looks like some windows specific thing we don't have to care about.
+ * According to MSDN it permits GDI dialog boxes in FULLSCREEN mode. Good to
+ * show error boxes ;)
+ * Well, just return DD_OK.
+ *
+ * Returns:
+ *  Always returns DD_OK
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_FlipToGDISurface(IDirectDraw7 *iface)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    TRACE("(%p)\n", This);
+
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::WaitForVerticalBlank
+ *
+ * This method allows applications to get in sync with the vertical blank
+ * interval.
+ * The wormhole demo in the DirectX 7 sdk uses this call, and it doesn't
+ * redraw the screen, most likely because of this stub
+ *
+ * Parameters:
+ *  Flags: one of DDWAITVB_BLOCKBEGIN, DDWAITVB_BLOCKBEGINEVENT
+ *         or DDWAITVB_BLOCKEND
+ *  h: Not used, according to MSDN
+ *
+ * Returns:
+ *  Always returns DD_OK
+ *
+ *****************************************************************************/ 
+static HRESULT WINAPI
+IDirectDrawImpl_WaitForVerticalBlank(IDirectDraw7 *iface,
+                                     DWORD Flags,
+                                     HANDLE h)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    static BOOL hide = FALSE;
+
+    /* This function is called often, so print the fixme only once */
+    if(!hide)
+    {
+        FIXME("(%p)->(%x,%p): Stub\n", This, Flags, h);
+        hide = TRUE;
+    }
+
+    /* MSDN says DDWAITVB_BLOCKBEGINEVENT is not supported */
+    if(Flags & DDWAITVB_BLOCKBEGINEVENT)
+        return DDERR_UNSUPPORTED; /* unchecked */
+
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::GetScanLine
+ *
+ * Returns the scan line that is being drawn on the monitor
+ *
+ * Parameters:
+ *  Scanline: Address to write the scan line value to
+ *
+ * Returns:
+ *  Always returns DD_OK
+ *
+ *****************************************************************************/ 
+static HRESULT WINAPI IDirectDrawImpl_GetScanLine(IDirectDraw7 *iface, DWORD *Scanline)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    static BOOL hide = FALSE;
+    WINED3DDISPLAYMODE Mode;
+
+    /* This function is called often, so print the fixme only once */
+    EnterCriticalSection(&ddraw_cs);
+    if(!hide)
+    {
+        FIXME("(%p)->(%p): Semi-Stub\n", This, Scanline);
+        hide = TRUE;
+    }
+
+    IWineD3DDevice_GetDisplayMode(This->wineD3DDevice,
+                                  0,
+                                  &Mode);
+
+    /* Fake the line sweeping of the monitor */
+    /* FIXME: We should synchronize with a source to keep the refresh rate */ 
+    *Scanline = This->cur_scanline++;
+    /* Assume 20 scan lines in the vertical blank */
+    if (This->cur_scanline >= Mode.Height + 20)
+        This->cur_scanline = 0;
+
+    LeaveCriticalSection(&ddraw_cs);
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::TestCooperativeLevel
+ *
+ * Informs the application about the state of the video adapter, depending
+ * on the cooperative level
+ *
+ * Returns:
+ *  DD_OK if the device is in a sane state
+ *  DDERR_NOEXCLUSIVEMODE or DDERR_EXCLUSIVEMODEALREADYSET
+ *  if the state is not correct(See below)
+ *
+ *****************************************************************************/ 
+static HRESULT WINAPI
+IDirectDrawImpl_TestCooperativeLevel(IDirectDraw7 *iface)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    HRESULT hr;
+    TRACE("(%p)\n", This);
+
+    EnterCriticalSection(&ddraw_cs);
+    /* Description from MSDN:
+     * For fullscreen apps return DDERR_NOEXCLUSIVEMODE if the user switched
+     * away from the app with e.g. alt-tab. Windowed apps receive 
+     * DDERR_EXCLUSIVEMODEALREADYSET if another application created a 
+     * DirectDraw object in exclusive mode. DDERR_WRONGMODE is returned,
+     * when the video mode has changed
+     */
+
+    hr =  IWineD3DDevice_TestCooperativeLevel(This->wineD3DDevice);
+
+    /* Fix the result value. These values are mapped from their
+     * d3d9 counterpart.
+     */
+    switch(hr)
+    {
+        case WINED3DERR_DEVICELOST:
+            if(This->cooperative_level & DDSCL_EXCLUSIVE)
+            {
+                LeaveCriticalSection(&ddraw_cs);
+                return DDERR_NOEXCLUSIVEMODE;
+            }
+            else
+            {
+                LeaveCriticalSection(&ddraw_cs);
+                return DDERR_EXCLUSIVEMODEALREADYSET;
+            }
+
+        case WINED3DERR_DEVICENOTRESET:
+            LeaveCriticalSection(&ddraw_cs);
+            return DD_OK;
+
+        case WINED3D_OK:
+            LeaveCriticalSection(&ddraw_cs);
+            return DD_OK;
+
+        case WINED3DERR_DRIVERINTERNALERROR:
+        default:
+            ERR("(%p) Unexpected return value %08x from wineD3D, "
+                " returning DD_OK\n", This, hr);
+    }
+
+    LeaveCriticalSection(&ddraw_cs);
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::GetGDISurface
+ *
+ * Returns the surface that GDI is treating as the primary surface.
+ * For Wine this is the front buffer
+ *
+ * Params:
+ *  GDISurface: Address to write the surface pointer to
+ *
+ * Returns:
+ *  DD_OK if the surface was found
+ *  DDERR_NOTFOUND if the GDI surface wasn't found
+ *
+ *****************************************************************************/ 
+static HRESULT WINAPI
+IDirectDrawImpl_GetGDISurface(IDirectDraw7 *iface,
+                              IDirectDrawSurface7 **GDISurface)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    IWineD3DSurface *Surf;
+    IDirectDrawSurface7 *ddsurf;
+    HRESULT hr;
+    DDSCAPS2 ddsCaps;
+    TRACE("(%p)->(%p)\n", This, GDISurface);
+
+    /* Get the back buffer from the wineD3DDevice and search its
+     * attached surfaces for the front buffer
+     */
+    EnterCriticalSection(&ddraw_cs);
+    hr = IWineD3DDevice_GetBackBuffer(This->wineD3DDevice,
+                                      0, /* SwapChain */
+                                      0, /* first back buffer*/
+                                      WINED3DBACKBUFFER_TYPE_MONO,
+                                      &Surf);
+
+    if( (hr != D3D_OK) ||
+        (!Surf) )
+    {
+        ERR("IWineD3DDevice::GetBackBuffer failed\n");
+        LeaveCriticalSection(&ddraw_cs);
+        return DDERR_NOTFOUND;
+    }
+
+    /* GetBackBuffer AddRef()ed the surface, release it */
+    IWineD3DSurface_Release(Surf);
+
+    IWineD3DSurface_GetParent(Surf,
+                              (IUnknown **) &ddsurf);
+    IDirectDrawSurface7_Release(ddsurf);  /* For the GetParent */
+
+    /* Find the front buffer */
+    ddsCaps.dwCaps = DDSCAPS_FRONTBUFFER;
+    hr = IDirectDrawSurface7_GetAttachedSurface(ddsurf,
+                                                &ddsCaps,
+                                                GDISurface);
+    if(hr != DD_OK)
+    {
+        ERR("IDirectDrawSurface7::GetAttachedSurface failed, hr = %x\n", hr);
+    }
+
+    /* The AddRef is OK this time */
+    LeaveCriticalSection(&ddraw_cs);
+    return hr;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::EnumDisplayModes
+ *
+ * Enumerates the supported Display modes. The modes can be filtered with
+ * the DDSD parameter.
+ *
+ * Params:
+ *  Flags: can be DDEDM_REFRESHRATES and DDEDM_STANDARDVGAMODES
+ *  DDSD: Surface description to filter the modes
+ *  Context: Pointer passed back to the callback function
+ *  cb: Application-provided callback function
+ *
+ * Returns:
+ *  DD_OK on success
+ *  DDERR_INVALIDPARAMS if the callback wasn't set
+ *
+ *****************************************************************************/ 
+static HRESULT WINAPI
+IDirectDrawImpl_EnumDisplayModes(IDirectDraw7 *iface,
+                                 DWORD Flags,
+                                 DDSURFACEDESC2 *DDSD,
+                                 void *Context,
+                                 LPDDENUMMODESCALLBACK2 cb)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    unsigned int modenum, fmt;
+    WINED3DFORMAT pixelformat = WINED3DFMT_UNKNOWN;
+    WINED3DDISPLAYMODE mode;
+    DDSURFACEDESC2 callback_sd;
+    WINED3DDISPLAYMODE *enum_modes = NULL;
+    unsigned enum_mode_count = 0, enum_mode_array_size = 0;
+
+    WINED3DFORMAT checkFormatList[] =
+    {
+        WINED3DFMT_R8G8B8,
+        WINED3DFMT_A8R8G8B8,
+        WINED3DFMT_X8R8G8B8,
+        WINED3DFMT_R5G6B5,
+        WINED3DFMT_X1R5G5B5,
+        WINED3DFMT_A1R5G5B5,
+        WINED3DFMT_A4R4G4B4,
+        WINED3DFMT_R3G3B2,
+        WINED3DFMT_A8R3G3B2,
+        WINED3DFMT_X4R4G4B4,
+        WINED3DFMT_R10G10B10A2_UNORM,
+        WINED3DFMT_R8G8B8A8_UNORM,
+        WINED3DFMT_X8B8G8R8,
+        WINED3DFMT_A2R10G10B10,
+        WINED3DFMT_A8P8,
+        WINED3DFMT_P8
+    };
+
+    TRACE("(%p)->(%p,%p,%p): Relay\n", This, DDSD, Context, cb);
+
+    EnterCriticalSection(&ddraw_cs);
+    /* This looks sane */
+    if(!cb)
+    {
+        LeaveCriticalSection(&ddraw_cs);
+        return DDERR_INVALIDPARAMS;
+    }
+
+    if(DDSD)
+    {
+        if ((DDSD->dwFlags & DDSD_PIXELFORMAT) && (DDSD->u4.ddpfPixelFormat.dwFlags & DDPF_RGB) )
+            pixelformat = PixelFormat_DD2WineD3D(&DDSD->u4.ddpfPixelFormat);
+    }
+
+    if(!(Flags & DDEDM_REFRESHRATES))
+    {
+        enum_mode_array_size = 16;
+        enum_modes = HeapAlloc(GetProcessHeap(), 0, sizeof(WINED3DDISPLAYMODE) * enum_mode_array_size);
+        if (!enum_modes)
+        {
+            ERR("Out of memory\n");
+            LeaveCriticalSection(&ddraw_cs);
+            return DDERR_OUTOFMEMORY;
+        }
+    }
+
+    for(fmt = 0; fmt < (sizeof(checkFormatList) / sizeof(checkFormatList[0])); fmt++)
+    {
+        if(pixelformat != WINED3DFMT_UNKNOWN && checkFormatList[fmt] != pixelformat)
+        {
+            continue;
+        }
+
+        modenum = 0;
+        while(IWineD3D_EnumAdapterModes(This->wineD3D,
+                                        WINED3DADAPTER_DEFAULT,
+                                        checkFormatList[fmt],
+                                        modenum++,
+                                        &mode) == WINED3D_OK)
+        {
+            if(DDSD)
+            {
+                if(DDSD->dwFlags & DDSD_WIDTH && mode.Width != DDSD->dwWidth) continue;
+                if(DDSD->dwFlags & DDSD_HEIGHT && mode.Height != DDSD->dwHeight) continue;
+            }
+
+            if(!(Flags & DDEDM_REFRESHRATES))
+            {
+                /* DX docs state EnumDisplayMode should return only unique modes. If DDEDM_REFRESHRATES is not set, refresh
+                 * rate doesn't matter when determining if the mode is unique. So modes only differing in refresh rate have
+                 * to be reduced to a single unique result in such case.
+                 */
+                BOOL found = FALSE;
+                unsigned i;
+
+                for (i = 0; i < enum_mode_count; i++)
+                {
+                    if(enum_modes[i].Width == mode.Width && enum_modes[i].Height == mode.Height &&
+                       enum_modes[i].Format == mode.Format)
+                    {
+                        found = TRUE;
+                        break;
+                    }
+                }
+
+                if(found) continue;
+            }
+
+            memset(&callback_sd, 0, sizeof(callback_sd));
+            callback_sd.dwSize = sizeof(callback_sd);
+            callback_sd.u4.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
+
+            callback_sd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_PITCH;
+            if(Flags & DDEDM_REFRESHRATES)
+            {
+                callback_sd.dwFlags |= DDSD_REFRESHRATE;
+                callback_sd.u2.dwRefreshRate = mode.RefreshRate;
+            }
+
+            callback_sd.dwWidth = mode.Width;
+            callback_sd.dwHeight = mode.Height;
+
+            PixelFormat_WineD3DtoDD(&callback_sd.u4.ddpfPixelFormat, mode.Format);
+
+            /* Calc pitch and DWORD align like MSDN says */
+            callback_sd.u1.lPitch = (callback_sd.u4.ddpfPixelFormat.u1.dwRGBBitCount / 8) * mode.Width;
+            callback_sd.u1.lPitch = (callback_sd.u1.lPitch + 3) & ~3;
+
+            TRACE("Enumerating %dx%dx%d @%d\n", callback_sd.dwWidth, callback_sd.dwHeight, callback_sd.u4.ddpfPixelFormat.u1.dwRGBBitCount,
+              callback_sd.u2.dwRefreshRate);
+
+            if(cb(&callback_sd, Context) == DDENUMRET_CANCEL)
+            {
+                TRACE("Application asked to terminate the enumeration\n");
+                HeapFree(GetProcessHeap(), 0, enum_modes);
+                LeaveCriticalSection(&ddraw_cs);
+                return DD_OK;
+            }
+
+            if(!(Flags & DDEDM_REFRESHRATES))
+            {
+                if (enum_mode_count == enum_mode_array_size)
+                {
+                    WINED3DDISPLAYMODE *new_enum_modes;
+
+                    enum_mode_array_size *= 2;
+                    new_enum_modes = HeapReAlloc(GetProcessHeap(), 0, enum_modes, sizeof(WINED3DDISPLAYMODE) * enum_mode_array_size);
+
+                    if (!new_enum_modes)
+                    {
+                        ERR("Out of memory\n");
+                        HeapFree(GetProcessHeap(), 0, enum_modes);
+                        LeaveCriticalSection(&ddraw_cs);
+                        return DDERR_OUTOFMEMORY;
+                    }
+
+                    enum_modes = new_enum_modes;
+                }
+
+                enum_modes[enum_mode_count++] = mode;
+            }
+        }
+    }
+
+    TRACE("End of enumeration\n");
+    HeapFree(GetProcessHeap(), 0, enum_modes);
+    LeaveCriticalSection(&ddraw_cs);
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::EvaluateMode
+ *
+ * Used with IDirectDraw7::StartModeTest to test video modes.
+ * EvaluateMode is used to pass or fail a mode, and continue with the next
+ * mode
+ *
+ * Params:
+ *  Flags: DDEM_MODEPASSED or DDEM_MODEFAILED
+ *  Timeout: Returns the amount of seconds left before the mode would have
+ *           been failed automatically
+ *
+ * Returns:
+ *  This implementation always DD_OK, because it's a stub
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_EvaluateMode(IDirectDraw7 *iface,
+                             DWORD Flags,
+                             DWORD *Timeout)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    FIXME("(%p)->(%d,%p): Stub!\n", This, Flags, Timeout);
+
+    /* When implementing this, implement it in WineD3D */
+
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::GetDeviceIdentifier
+ *
+ * Returns the device identifier, which gives information about the driver
+ * Our device identifier is defined at the beginning of this file.
+ *
+ * Params:
+ *  DDDI: Address for the returned structure
+ *  Flags: Can be DDGDI_GETHOSTIDENTIFIER
+ *
+ * Returns:
+ *  On success it returns DD_OK
+ *  DDERR_INVALIDPARAMS if DDDI is NULL
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_GetDeviceIdentifier(IDirectDraw7 *iface,
+                                    DDDEVICEIDENTIFIER2 *DDDI,
+                                    DWORD Flags)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    TRACE("(%p)->(%p,%08x)\n", This, DDDI, Flags);
+
+    if(!DDDI)
+        return DDERR_INVALIDPARAMS;
+
+    /* The DDGDI_GETHOSTIDENTIFIER returns the information about the 2D
+     * host adapter, if there's a secondary 3D adapter. This doesn't apply
+     * to any modern hardware, nor is it interesting for Wine, so ignore it
+     */
+
+    *DDDI = deviceidentifier;
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::GetSurfaceFromDC
+ *
+ * Returns the Surface for a GDI device context handle.
+ * Is this related to IDirectDrawSurface::GetDC ???
+ *
+ * Params:
+ *  hdc: hdc to return the surface for
+ *  Surface: Address to write the surface pointer to
+ *
+ * Returns:
+ *  Always returns DD_OK because it's a stub
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_GetSurfaceFromDC(IDirectDraw7 *iface,
+                                 HDC hdc,
+                                 IDirectDrawSurface7 **Surface)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    FIXME("(%p)->(%p,%p): Stub!\n", This, hdc, Surface);
+
+    /* Implementation idea if needed: Loop through all surfaces and compare
+     * their hdc with hdc. Implement it in WineD3D! */
+    return DDERR_NOTFOUND;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::RestoreAllSurfaces
+ *
+ * Calls the restore method of all surfaces
+ *
+ * Params:
+ *
+ * Returns:
+ *  Always returns DD_OK because it's a stub
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_RestoreAllSurfaces(IDirectDraw7 *iface)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    FIXME("(%p): Stub\n", This);
+
+    /* This isn't hard to implement: Enumerate all WineD3D surfaces,
+     * get their parent and call their restore method. Do not implement
+     * it in WineD3D, as restoring a surface means re-creating the
+     * WineD3DDSurface
+     */
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::StartModeTest
+ *
+ * Tests the specified video modes to update the system registry with
+ * refresh rate information. StartModeTest starts the mode test,
+ * EvaluateMode is used to fail or pass a mode. If EvaluateMode
+ * isn't called within 15 seconds, the mode is failed automatically
+ *
+ * As refresh rates are handled by the X server, I don't think this
+ * Method is important
+ *
+ * Params:
+ *  Modes: An array of mode specifications
+ *  NumModes: The number of modes in Modes
+ *  Flags: Some flags...
+ *
+ * Returns:
+ *  Returns DDERR_TESTFINISHED if flags contains DDSMT_ISTESTREQUIRED,
+ *  if no modes are passed, DDERR_INVALIDPARAMS is returned,
+ *  otherwise DD_OK
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_StartModeTest(IDirectDraw7 *iface,
+                              SIZE *Modes,
+                              DWORD NumModes,
+                              DWORD Flags)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    WARN("(%p)->(%p, %d, %x): Semi-Stub, most likely harmless\n", This, Modes, NumModes, Flags);
+
+    /* This looks sane */
+    if( (!Modes) || (NumModes == 0) ) return DDERR_INVALIDPARAMS;
+
+    /* DDSMT_ISTESTREQUIRED asks if a mode test is necessary.
+     * As it is not, DDERR_TESTFINISHED is returned
+     * (hopefully that's correct
+     *
+    if(Flags & DDSMT_ISTESTREQUIRED) return DDERR_TESTFINISHED;
+     * well, that value doesn't (yet) exist in the wine headers, so ignore it
+     */
+
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDrawImpl_RecreateSurfacesCallback
+ *
+ * Enumeration callback for IDirectDrawImpl_RecreateAllSurfaces.
+ * It re-recreates the WineD3DSurface. It's pretty straightforward
+ *
+ *****************************************************************************/
+HRESULT WINAPI
+IDirectDrawImpl_RecreateSurfacesCallback(IDirectDrawSurface7 *surf,
+                                         DDSURFACEDESC2 *desc,
+                                         void *Context)
+{
+    IDirectDrawSurfaceImpl *surfImpl = (IDirectDrawSurfaceImpl *)surf;
+    IDirectDrawImpl *This = surfImpl->ddraw;
+    IUnknown *Parent;
+    IParentImpl *parImpl = NULL;
+    IWineD3DSurface *wineD3DSurface;
+    IWineD3DSwapChain *swapchain;
+    HRESULT hr;
+    void *tmp;
+    IWineD3DClipper *clipper = NULL;
+
+    WINED3DSURFACE_DESC     Desc;
+    WINED3DFORMAT           Format;
+    WINED3DRESOURCETYPE     Type;
+    DWORD                   Usage;
+    WINED3DPOOL             Pool;
+    UINT                    Size;
+
+    WINED3DMULTISAMPLE_TYPE MultiSampleType;
+    DWORD                   MultiSampleQuality;
+    UINT                    Width;
+    UINT                    Height;
+
+    TRACE("(%p): Enumerated Surface %p\n", This, surfImpl);
+
+    /* For the enumeration */
+    IDirectDrawSurface7_Release(surf);
+
+    if(surfImpl->ImplType == This->ImplType) return DDENUMRET_OK; /* Continue */
+
+    /* Get the objects */
+    swapchain = surfImpl->wineD3DSwapChain;
+    surfImpl->wineD3DSwapChain = NULL;
+    wineD3DSurface = surfImpl->WineD3DSurface;
+    IWineD3DSurface_GetParent(wineD3DSurface, &Parent);
+    IUnknown_Release(Parent); /* For the getParent */
+
+    /* Is the parent an IParent interface? */
+    if(IUnknown_QueryInterface(Parent, &IID_IParent, &tmp) == S_OK)
+    {
+        /* It is a IParent interface! */
+        IUnknown_Release(Parent); /* For the QueryInterface */
+        parImpl = (IParentImpl *)Parent;
+        /* Release the reference the parent interface is holding */
+        IWineD3DSurface_Release(wineD3DSurface);
+    }
+
+    /* get the clipper */
+    IWineD3DSurface_GetClipper(wineD3DSurface, &clipper);
+
+    /* Get the surface properties */
+    Desc.Format = &Format;
+    Desc.Type = &Type;
+    Desc.Usage = &Usage;
+    Desc.Pool = &Pool;
+    Desc.Size = &Size;
+    Desc.MultiSampleType = &MultiSampleType;
+    Desc.MultiSampleQuality = &MultiSampleQuality;
+    Desc.Width = &Width;
+    Desc.Height = &Height;
+
+    hr = IWineD3DSurface_GetDesc(wineD3DSurface, &Desc);
+    if(hr != D3D_OK) return hr;
+
+    if(swapchain) {
+        /* If there's a swapchain, it owns the IParent interface. Create a new one for the
+         * new surface
+         */
+        parImpl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*parImpl));
+        parImpl->lpVtbl = &IParent_Vtbl;
+        parImpl->ref = 1;
+
+        Parent = (IUnknown *) parImpl;
+    }
+
+    /* Create the new surface */
+    hr = IWineD3DDevice_CreateSurface(This->wineD3DDevice,
+                                      Width, Height, Format,
+                                      TRUE /* Lockable */,
+                                      FALSE /* Discard */,
+                                      surfImpl->mipmap_level,
+                                      &surfImpl->WineD3DSurface,
+                                      Type,
+                                      Usage,
+                                      Pool,
+                                      MultiSampleType,
+                                      MultiSampleQuality,
+                                      0 /* SharedHandle */,
+                                      This->ImplType,
+                                      Parent);
+
+    if(hr != D3D_OK)
+        return hr;
+
+    IWineD3DSurface_SetClipper(surfImpl->WineD3DSurface, clipper);
+
+    /* Update the IParent if it exists */
+    if(parImpl)
+    {
+        parImpl->child = (IUnknown *) surfImpl->WineD3DSurface;
+        /* Add a reference for the IParent */
+        IWineD3DSurface_AddRef(surfImpl->WineD3DSurface);
+    }
+    /* TODO: Copy the surface content, except for render targets */
+
+    /* If there's a swapchain, it owns the wined3d surfaces. So Destroy
+     * the swapchain
+     */
+    if(swapchain) {
+        /* The backbuffers have the swapchain set as well, but the primary
+         * owns it and destroys it
+         */
+        if(surfImpl->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) {
+            IWineD3DDevice_UninitGDI(This->wineD3DDevice, D3D7CB_DestroySwapChain);
+        }
+        surfImpl->isRenderTarget = FALSE;
+    } else {
+        if(IWineD3DSurface_Release(wineD3DSurface) == 0)
+            TRACE("Surface released successful, next surface\n");
+        else
+            ERR("Something's still holding the old WineD3DSurface\n");
+    }
+
+    surfImpl->ImplType = This->ImplType;
+
+    if(clipper)
+    {
+        IWineD3DClipper_Release(clipper);
+    }
+    return DDENUMRET_OK;
+}
+
+/*****************************************************************************
+ * IDirectDrawImpl_RecreateAllSurfaces
+ *
+ * A function, that converts all wineD3DSurfaces to the new implementation type
+ * It enumerates all surfaces with IWineD3DDevice::EnumSurfaces, creates a
+ * new WineD3DSurface, copies the content and releases the old surface
+ *
+ *****************************************************************************/
+static HRESULT
+IDirectDrawImpl_RecreateAllSurfaces(IDirectDrawImpl *This)
+{
+    DDSURFACEDESC2 desc;
+    TRACE("(%p): Switch to implementation %d\n", This, This->ImplType);
+
+    if(This->ImplType != SURFACE_OPENGL && This->d3d_initialized)
+    {
+        /* Should happen almost never */
+        FIXME("(%p) Switching to non-opengl surfaces with d3d started. Is this a bug?\n", This);
+        /* Shutdown d3d */
+        IWineD3DDevice_Uninit3D(This->wineD3DDevice, D3D7CB_DestroyDepthStencilSurface, D3D7CB_DestroySwapChain);
+    }
+    /* Contrary: D3D starting is handled by the caller, because it knows the render target */
+
+    memset(&desc, 0, sizeof(desc));
+    desc.dwSize = sizeof(desc);
+
+    return IDirectDraw7_EnumSurfaces((IDirectDraw7 *)This, 0, &desc, This, IDirectDrawImpl_RecreateSurfacesCallback);
+}
+
+ULONG WINAPI D3D7CB_DestroySwapChain(IWineD3DSwapChain *pSwapChain) {
+    IUnknown* swapChainParent;
+    TRACE("(%p) call back\n", pSwapChain);
+
+    IWineD3DSwapChain_GetParent(pSwapChain, &swapChainParent);
+    IUnknown_Release(swapChainParent);
+    return IUnknown_Release(swapChainParent);
+}
+
+ULONG WINAPI D3D7CB_DestroyDepthStencilSurface(IWineD3DSurface *pSurface) {
+    IUnknown* surfaceParent;
+    TRACE("(%p) call back\n", pSurface);
+
+    IWineD3DSurface_GetParent(pSurface, &surfaceParent);
+    IUnknown_Release(surfaceParent);
+    return IUnknown_Release(surfaceParent);
+}
+
+/*****************************************************************************
+ * IDirectDrawImpl_CreateNewSurface
+ *
+ * A helper function for IDirectDraw7::CreateSurface. It creates a new surface
+ * with the passed parameters.
+ *
+ * Params:
+ *  DDSD: Description of the surface to create
+ *  Surf: Address to store the interface pointer at
+ *
+ * Returns:
+ *  DD_OK on success
+ *
+ *****************************************************************************/
+static HRESULT
+IDirectDrawImpl_CreateNewSurface(IDirectDrawImpl *This,
+                                 DDSURFACEDESC2 *pDDSD,
+                                 IDirectDrawSurfaceImpl **ppSurf,
+                                 UINT level)
+{
+    HRESULT hr;
+    UINT Width = 0, Height = 0;
+    WINED3DFORMAT Format = WINED3DFMT_UNKNOWN;
+    WINED3DRESOURCETYPE ResType = WINED3DRTYPE_SURFACE;
+    DWORD Usage = 0;
+    WINED3DSURFTYPE ImplType = This->ImplType;
+    WINED3DSURFACE_DESC Desc;
+    IUnknown *Parent;
+    IParentImpl *parImpl = NULL;
+    WINED3DPOOL Pool = WINED3DPOOL_DEFAULT;
+
+    /* Dummies for GetDesc */
+    WINED3DPOOL dummy_d3dpool;
+    WINED3DMULTISAMPLE_TYPE dummy_mst;
+    UINT dummy_uint;
+    DWORD dummy_dword;
+
+    if (TRACE_ON(ddraw))
+    {
+        TRACE(" (%p) Requesting surface desc :\n", This);
+        DDRAW_dump_surface_desc(pDDSD);
+    }
+
+    /* Select the surface type, if it wasn't choosen yet */
+    if(ImplType == SURFACE_UNKNOWN)
+    {
+        /* Use GL Surfaces if a D3DDEVICE Surface is requested */
+        if(pDDSD->ddsCaps.dwCaps & DDSCAPS_3DDEVICE)
+        {
+            TRACE("(%p) Choosing GL surfaces because a 3DDEVICE Surface was requested\n", This);
+            ImplType = SURFACE_OPENGL;
+        }
+
+        /* Otherwise use GDI surfaces for now */
+        else
+        {
+            TRACE("(%p) Choosing GDI surfaces for 2D rendering\n", This);
+            ImplType = SURFACE_GDI;
+        }
+
+        /* Policy if all surface implementations are available:
+         * First, check if a default type was set with winecfg. If not,
+         * try Xrender surfaces, and use them if they work. Next, check if
+         * accelerated OpenGL is available, and use GL surfaces in this
+         * case. If all else fails, use GDI surfaces. If a 3DDEVICE surface
+         * was created, always use OpenGL surfaces.
+         *
+         * (Note: Xrender surfaces are not implemented for now, the
+         * unaccelerated implementation uses GDI to render in Software)
+         */
+
+        /* Store the type. If it needs to be changed, all WineD3DSurfaces have to
+         * be re-created. This could be done with IDirectDrawSurface7::Restore
+         */
+        This->ImplType = ImplType;
+    }
+    else
+    {
+         if((pDDSD->ddsCaps.dwCaps & DDSCAPS_3DDEVICE ) && 
+            (This->ImplType != SURFACE_OPENGL ) && DefaultSurfaceType == SURFACE_UNKNOWN)
+        {
+            /* We have to change to OpenGL,
+             * and re-create all WineD3DSurfaces
+             */
+            ImplType = SURFACE_OPENGL;
+            This->ImplType = ImplType;
+            TRACE("(%p) Re-creating all surfaces\n", This);
+            IDirectDrawImpl_RecreateAllSurfaces(This);
+            TRACE("(%p) Done recreating all surfaces\n", This);
+        }
+        else if(This->ImplType != SURFACE_OPENGL && pDDSD->ddsCaps.dwCaps & DDSCAPS_3DDEVICE)
+        {
+            WARN("The application requests a 3D capable surface, but a non-opengl surface was set in the registry\n");
+            /* Do not fail surface creation, only fail 3D device creation */
+        }
+    }
+
+    if (!(pDDSD->ddsCaps.dwCaps & (DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY)) &&
+        !((pDDSD->ddsCaps.dwCaps & DDSCAPS_TEXTURE) && (pDDSD->ddsCaps.dwCaps2 & DDSCAPS2_TEXTUREMANAGE)) )
+    {
+        /* Tests show surfaces without memory flags get these flags added right after creation. */
+        pDDSD->ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY;
+    }
+    /* Get the correct wined3d usage */
+    if (pDDSD->ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE |
+                                 DDSCAPS_3DDEVICE       ) )
+    {
+        Usage |= WINED3DUSAGE_RENDERTARGET;
+
+        pDDSD->ddsCaps.dwCaps |= DDSCAPS_VISIBLE;
+    }
+    if (pDDSD->ddsCaps.dwCaps & (DDSCAPS_OVERLAY))
+    {
+        Usage |= WINED3DUSAGE_OVERLAY;
+    }
+    if(This->depthstencil || (pDDSD->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) )
+    {
+        /* The depth stencil creation callback sets this flag.
+         * Set the WineD3D usage to let it know that it's a depth
+         * Stencil surface.
+         */
+        Usage |= WINED3DUSAGE_DEPTHSTENCIL;
+    }
+    if(pDDSD->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)
+    {
+        Pool = WINED3DPOOL_SYSTEMMEM;
+    }
+    else if(pDDSD->ddsCaps.dwCaps2 & DDSCAPS2_TEXTUREMANAGE)
+    {
+        Pool = WINED3DPOOL_MANAGED;
+        /* Managed textures have the system memory flag set */
+        pDDSD->ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
+    }
+    else if(pDDSD->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)
+    {
+        /* Videomemory adds localvidmem, this is mutually exclusive with systemmemory
+         * and texturemanage
+         */
+        pDDSD->ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM;
+    }
+
+    Format = PixelFormat_DD2WineD3D(&pDDSD->u4.ddpfPixelFormat);
+    if(Format == WINED3DFMT_UNKNOWN)
+    {
+        ERR("Unsupported / Unknown pixelformat\n");
+        return DDERR_INVALIDPIXELFORMAT;
+    }
+
+    /* Create the Surface object */
+    *ppSurf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawSurfaceImpl));
+    if(!*ppSurf)
+    {
+        ERR("(%p) Error allocating memory for a surface\n", This);
+        return DDERR_OUTOFVIDEOMEMORY;
+    }
+    (*ppSurf)->lpVtbl = &IDirectDrawSurface7_Vtbl;
+    (*ppSurf)->IDirectDrawSurface3_vtbl = &IDirectDrawSurface3_Vtbl;
+    (*ppSurf)->IDirectDrawGammaControl_vtbl = &IDirectDrawGammaControl_Vtbl;
+    (*ppSurf)->IDirect3DTexture2_vtbl = &IDirect3DTexture2_Vtbl;
+    (*ppSurf)->IDirect3DTexture_vtbl = &IDirect3DTexture1_Vtbl;
+    (*ppSurf)->ref = 1;
+    (*ppSurf)->version = 7;
+    TRACE("%p->version = %d\n", (*ppSurf), (*ppSurf)->version);
+    (*ppSurf)->ddraw = This;
+    (*ppSurf)->surface_desc.dwSize = sizeof(DDSURFACEDESC2);
+    (*ppSurf)->surface_desc.u4.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
+    DD_STRUCT_COPY_BYSIZE(&(*ppSurf)->surface_desc, pDDSD);
+
+    /* Surface attachments */
+    (*ppSurf)->next_attached = NULL;
+    (*ppSurf)->first_attached = *ppSurf;
+
+    /* Needed to re-create the surface on an implementation change */
+    (*ppSurf)->ImplType = ImplType;
+
+    /* For D3DDevice creation */
+    (*ppSurf)->isRenderTarget = FALSE;
+
+    /* A trace message for debugging */
+    TRACE("(%p) Created IDirectDrawSurface implementation structure at %p\n", This, *ppSurf);
+
+    if(pDDSD->ddsCaps.dwCaps & ( DDSCAPS_PRIMARYSURFACE | DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE) )
+    {
+        /* Render targets and textures need a IParent interface,
+         * because WineD3D will destroy them when the swapchain
+         * is released
+         */
+        parImpl = HeapAlloc(GetProcessHeap(), 0, sizeof(IParentImpl));
+        if(!parImpl)
+        {
+            ERR("Out of memory when allocating memory for a IParent implementation\n");
+            return DDERR_OUTOFMEMORY;
+        }
+        parImpl->ref = 1;
+        parImpl->lpVtbl = &IParent_Vtbl;
+        Parent = (IUnknown *)parImpl;
+        TRACE("Using IParent interface %p as parent\n", parImpl);
+    }
+    else
+    {
+        /* Use the surface as parent */
+        Parent = (IUnknown *)*ppSurf;
+        TRACE("Using Surface interface %p as parent\n", *ppSurf);
+    }
+
+    /* Now create the WineD3D Surface */
+    hr = IWineD3DDevice_CreateSurface(This->wineD3DDevice,
+                                      pDDSD->dwWidth,
+                                      pDDSD->dwHeight,
+                                      Format,
+                                      TRUE /* Lockable */,
+                                      FALSE /* Discard */,
+                                      level,
+                                      &(*ppSurf)->WineD3DSurface,
+                                      ResType, Usage,
+                                      Pool,
+                                      WINED3DMULTISAMPLE_NONE,
+                                      0 /* MultiSampleQuality */,
+                                      0 /* SharedHandle */,
+                                      ImplType,
+                                      Parent);
+
+    if(hr != D3D_OK)
+    {
+        ERR("IWineD3DDevice::CreateSurface failed. hr = %08x\n", hr);
+        return hr;
+    }
+
+    /* Set the child of the parent implementation if it exists */
+    if(parImpl)
+    {
+        parImpl->child = (IUnknown *) (*ppSurf)->WineD3DSurface;
+        /* The IParent releases the WineD3DSurface, and
+         * the ddraw surface does that too. Hold a reference
+         */
+        IWineD3DSurface_AddRef((*ppSurf)->WineD3DSurface);
+    }
+
+    /* Increase the surface counter, and attach the surface */
+    InterlockedIncrement(&This->surfaces);
+    list_add_head(&This->surface_list, &(*ppSurf)->surface_list_entry);
+
+    /* Here we could store all created surfaces in the DirectDrawImpl structure,
+     * But this could also be delegated to WineDDraw, as it keeps track of all its
+     * resources. Not implemented for now, as there are more important things ;)
+     */
+
+    /* Get the pixel format of the WineD3DSurface and store it.
+     * Don't use the Format choosen above, WineD3D might have
+     * changed it
+     */
+    Desc.Format = &Format;
+    Desc.Type = &ResType;
+    Desc.Usage = &Usage;
+    Desc.Pool = &dummy_d3dpool;
+    Desc.Size = &dummy_uint;
+    Desc.MultiSampleType = &dummy_mst;
+    Desc.MultiSampleQuality = &dummy_dword;
+    Desc.Width = &Width;
+    Desc.Height = &Height;
+
+    (*ppSurf)->surface_desc.dwFlags |= DDSD_PIXELFORMAT;
+    hr = IWineD3DSurface_GetDesc((*ppSurf)->WineD3DSurface, &Desc);
+    if(hr != D3D_OK)
+    {
+        ERR("IWineD3DSurface::GetDesc failed\n");
+        IDirectDrawSurface7_Release( (IDirectDrawSurface7 *) *ppSurf);
+        return hr;
+    }
+
+    if(Format == WINED3DFMT_UNKNOWN)
+    {
+        FIXME("IWineD3DSurface::GetDesc returned WINED3DFMT_UNKNOWN\n");
+    }
+    PixelFormat_WineD3DtoDD( &(*ppSurf)->surface_desc.u4.ddpfPixelFormat, Format);
+
+    /* Anno 1602 stores the pitch right after surface creation, so make sure it's there.
+     * I can't LockRect() the surface here because if OpenGL surfaces are in use, the
+     * WineD3DDevice might not be usable for 3D yet, so an extra method was created.
+     * TODO: Test other fourcc formats
+     */
+    if(Format == WINED3DFMT_DXT1 || Format == WINED3DFMT_DXT2 || Format == WINED3DFMT_DXT3 ||
+       Format == WINED3DFMT_DXT4 || Format == WINED3DFMT_DXT5)
+    {
+        (*ppSurf)->surface_desc.dwFlags |= DDSD_LINEARSIZE;
+        if(Format == WINED3DFMT_DXT1)
+        {
+            (*ppSurf)->surface_desc.u1.dwLinearSize = max(4, Width) * max(4, Height) / 2;
+        }
+        else
+        {
+            (*ppSurf)->surface_desc.u1.dwLinearSize = max(4, Width) * max(4, Height);
+        }
+    }
+    else
+    {
+        (*ppSurf)->surface_desc.dwFlags |= DDSD_PITCH;
+        (*ppSurf)->surface_desc.u1.lPitch = IWineD3DSurface_GetPitch((*ppSurf)->WineD3DSurface);
+    }
+
+    /* Application passed a color key? Set it! */
+    if(pDDSD->dwFlags & DDSD_CKDESTOVERLAY)
+    {
+        IWineD3DSurface_SetColorKey((*ppSurf)->WineD3DSurface,
+                                    DDCKEY_DESTOVERLAY,
+                                    (WINEDDCOLORKEY *) &pDDSD->u3.ddckCKDestOverlay);
+    }
+    if(pDDSD->dwFlags & DDSD_CKDESTBLT)
+    {
+        IWineD3DSurface_SetColorKey((*ppSurf)->WineD3DSurface,
+                                    DDCKEY_DESTBLT,
+                                    (WINEDDCOLORKEY *) &pDDSD->ddckCKDestBlt);
+    }
+    if(pDDSD->dwFlags & DDSD_CKSRCOVERLAY)
+    {
+        IWineD3DSurface_SetColorKey((*ppSurf)->WineD3DSurface,
+                                    DDCKEY_SRCOVERLAY,
+                                    (WINEDDCOLORKEY *) &pDDSD->ddckCKSrcOverlay);
+    }
+    if(pDDSD->dwFlags & DDSD_CKSRCBLT)
+    {
+        IWineD3DSurface_SetColorKey((*ppSurf)->WineD3DSurface,
+                                    DDCKEY_SRCBLT,
+                                    (WINEDDCOLORKEY *) &pDDSD->ddckCKSrcBlt);
+    }
+    if ( pDDSD->dwFlags & DDSD_LPSURFACE)
+    {
+        hr = IWineD3DSurface_SetMem((*ppSurf)->WineD3DSurface, pDDSD->lpSurface);
+        if(hr != WINED3D_OK)
+        {
+            /* No need for a trace here, wined3d does that for us */
+            IDirectDrawSurface7_Release((IDirectDrawSurface7 *)*ppSurf);
+            return hr;
+        }
+    }
+
+    return DD_OK;
+}
+/*****************************************************************************
+ * CreateAdditionalSurfaces
+ *
+ * Creates a new mipmap chain.
+ *
+ * Params:
+ *  root: Root surface to attach the newly created chain to
+ *  count: number of surfaces to create
+ *  DDSD: Description of the surface. Intentionally not a pointer to avoid side
+ *        effects on the caller
+ *  CubeFaceRoot: Whether the new surface is a root of a cube map face. This
+ *                creates an additional surface without the mipmapping flags
+ *
+ *****************************************************************************/
+static HRESULT
+CreateAdditionalSurfaces(IDirectDrawImpl *This,
+                         IDirectDrawSurfaceImpl *root,
+                         UINT count,
+                         DDSURFACEDESC2 DDSD,
+                         BOOL CubeFaceRoot)
+{
+    UINT i, j, level = 0;
+    HRESULT hr;
+    IDirectDrawSurfaceImpl *last = root;
+
+    for(i = 0; i < count; i++)
+    {
+        IDirectDrawSurfaceImpl *object2 = NULL;
+
+        /* increase the mipmap level, but only if a mipmap is created
+         * In this case, also halve the size
+         */
+        if(DDSD.ddsCaps.dwCaps & DDSCAPS_MIPMAP && !CubeFaceRoot)
+        {
+            level++;
+            if(DDSD.dwWidth > 1) DDSD.dwWidth /= 2;
+            if(DDSD.dwHeight > 1) DDSD.dwHeight /= 2;
+            /* Set the mipmap sublevel flag according to msdn */
+            DDSD.ddsCaps.dwCaps2 |= DDSCAPS2_MIPMAPSUBLEVEL;
+        }
+        else
+        {
+            DDSD.ddsCaps.dwCaps2 &= ~DDSCAPS2_MIPMAPSUBLEVEL;
+        }
+        CubeFaceRoot = FALSE;
+
+        hr = IDirectDrawImpl_CreateNewSurface(This,
+                                              &DDSD,
+                                              &object2,
+                                              level);
+        if(hr != DD_OK)
+        {
+            return hr;
+        }
+
+        /* Add the new surface to the complex attachment array */
+        for(j = 0; j < MAX_COMPLEX_ATTACHED; j++)
+        {
+            if(last->complex_array[j]) continue;
+            last->complex_array[j] = object2;
+            break;
+        }
+        last = object2;
+
+        /* Remove the (possible) back buffer cap from the new surface description,
+         * because only one surface in the flipping chain is a back buffer, one
+         * is a front buffer, the others are just primary surfaces.
+         */
+        DDSD.ddsCaps.dwCaps &= ~DDSCAPS_BACKBUFFER;
+    }
+    return DD_OK;
+}
+
+/*****************************************************************************
+ * IDirectDraw7::CreateSurface
+ *
+ * Creates a new IDirectDrawSurface object and returns its interface.
+ *
+ * The surface connections with wined3d are a bit tricky. Basically it works
+ * like this:
+ *
+ * |------------------------|               |-----------------|
+ * | DDraw surface          |               | WineD3DSurface  |
+ * |                        |               |                 |
+ * |        WineD3DSurface  |-------------->|                 |
+ * |        Child           |<------------->| Parent          |
+ * |------------------------|               |-----------------|
+ *
+ * The DDraw surface is the parent of the wined3d surface, and it releases
+ * the WineD3DSurface when the ddraw surface is destroyed.
+ *
+ * However, for all surfaces which can be in a container in WineD3D,
+ * we have to do this. These surfaces are usually complex surfaces,
+ * so this concerns primary surfaces with a front and a back buffer,
+ * and textures.
+ *
+ * |------------------------|               |-----------------|
+ * | DDraw surface          |               | Container       |
+ * |                        |               |                 |
+ * |                  Child |<------------->| Parent          |
+ * |                Texture |<------------->|                 |
+ * |         WineD3DSurface |<----|         |          Levels |<--|
+ * | Complex connection     |     |         |                 |   |
+ * |------------------------|     |         |-----------------|   |
+ *  ^                             |                               |
+ *  |                             |                               |
+ *  |                             |                               |
+ *  |    |------------------|     |         |-----------------|   |
+ *  |    | IParent          |     |-------->| WineD3DSurface  |   |
+ *  |    |                  |               |                 |   |
+ *  |    |            Child |<------------->| Parent          |   |
+ *  |    |                  |               |       Container |<--|
+ *  |    |------------------|               |-----------------|   |
+ *  |                                                             |
+ *  |   |----------------------|                                  |
+ *  |   | DDraw surface 2      |                                  |
+ *  |   |                      |                                  |
+ *  |<->| Complex root   Child |                                  |
+ *  |   |              Texture |                                  |
+ *  |   |       WineD3DSurface |<----|                            |
+ *  |   |----------------------|     |                            |
+ *  |                                |                            |
+ *  |    |---------------------|     |      |-----------------|   |
+ *  |    | IParent             |     |----->| WineD3DSurface  |   |
+ *  |    |                     |            |                 |   |
+ *  |    |               Child |<---------->| Parent          |   |
+ *  |    |---------------------|            |       Container |<--|
+ *  |                                       |-----------------|   |
+ *  |                                                             |
+ *  |             ---More surfaces can follow---                  |
+ *
+ * The reason is that the IWineD3DSwapchain(render target container)
+ * and the IWineD3DTexure(Texture container) release the parents
+ * of their surface's children, but by releasing the complex root
+ * the surfaces which are complexly attached to it are destroyed
+ * too. See IDirectDrawSurface::Release for a more detailed
+ * explanation.
+ *
+ * Params:
+ *  DDSD: Description of the surface to create
+ *  Surf: Address to store the interface pointer at
+ *  UnkOuter: Basically for aggregation support, but ddraw doesn't support
+ *            aggregation, so it has to be NULL
+ *
+ * Returns:
+ *  DD_OK on success
+ *  CLASS_E_NOAGGREGATION if UnkOuter != NULL
+ *  DDERR_* if an error occurs
+ *
+ *****************************************************************************/
+static HRESULT WINAPI
+IDirectDrawImpl_CreateSurface(IDirectDraw7 *iface,
+                              DDSURFACEDESC2 *DDSD,
+                              IDirectDrawSurface7 **Surf,
+                              IUnknown *UnkOuter)
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    IDirectDrawSurfaceImpl *object = NULL;
+    HRESULT hr;
+    LONG extra_surfaces = 0;
+    DDSURFACEDESC2 desc2;
+    WINED3DDISPLAYMODE Mode;
+    const DWORD sysvidmem = DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY;
+
+    TRACE("(%p)->(%p,%p,%p)\n", This, DDSD, Surf, UnkOuter);
+
+    /* Some checks before we start */
+    if (TRACE_ON(ddraw))
+    {
+        TRACE(" (%p) Requesting surface desc :\n", This);
+        DDRAW_dump_surface_desc(DDSD);
+    }
+    EnterCriticalSection(&ddraw_cs);
+
+    if (UnkOuter != NULL)
+    {
+        FIXME("(%p) : outer != NULL?\n", This);
+        LeaveCriticalSection(&ddraw_cs);
+        return CLASS_E_NOAGGREGATION; /* unchecked */
+    }
+
+    if (Surf == NULL)
+    {
+        FIXME("(%p) You want to get back a surface? Don't give NULL ptrs!\n", This);
+        LeaveCriticalSection(&ddraw_cs);
+        return E_POINTER; /* unchecked */
+    }
+
+    if (!(DDSD->dwFlags & DDSD_CAPS))
+    {
+        /* DVIDEO.DLL does forget the DDSD_CAPS flag ... *sigh* */
+        DDSD->dwFlags |= DDSD_CAPS;
+    }
+
+    if (DDSD->ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD)
+    {
+        /* If the surface is of the 'alloconload' type, ignore the LPSURFACE field */
+        DDSD->dwFlags &= ~DDSD_LPSURFACE;
+    }
+
+    if ((DDSD->dwFlags & DDSD_LPSURFACE) && (DDSD->lpSurface == NULL))
+    {
+        /* Frank Herbert's Dune specifies a null pointer for the surface, ignore the LPSURFACE field */
+        WARN("(%p) Null surface pointer specified, ignore it!\n", This);
+        DDSD->dwFlags &= ~DDSD_LPSURFACE;
+    }
+
+    if((DDSD->ddsCaps.dwCaps & (DDSCAPS_FLIP | DDSCAPS_PRIMARYSURFACE)) == (DDSCAPS_FLIP | DDSCAPS_PRIMARYSURFACE) &&
+       !(This->cooperative_level & DDSCL_EXCLUSIVE))
+    {
+        TRACE("(%p): Attempt to create a flipable primary surface without DDSCL_EXCLUSIVE set\n", This);
+        *Surf = NULL;
+        LeaveCriticalSection(&ddraw_cs);
+        return DDERR_NOEXCLUSIVEMODE;
+    }
+
+    if(DDSD->ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER | DDSCAPS_BACKBUFFER)) {
+        WARN("Application tried to create an explicit front or back buffer\n");
+        LeaveCriticalSection(&ddraw_cs);
+        return DDERR_INVALIDCAPS;
+    }
+
+    if((DDSD->ddsCaps.dwCaps & sysvidmem) == sysvidmem)
+    {
+        /* This is a special switch in ddrawex.dll, but not allowed in ddraw.dll */
+        WARN("Application tries to put the surface in both system and video memory\n");
+        LeaveCriticalSection(&ddraw_cs);
+        *Surf = NULL;
+        return DDERR_INVALIDCAPS;
+    }
+
+    /* Check cube maps but only if the size includes them */
+    if (DDSD->dwSize >= sizeof(DDSURFACEDESC2))
+    {
+        if(DDSD->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES &&
+           !(DDSD->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP))
+        {
+            WARN("Cube map faces requested without cube map flag\n");
+            LeaveCriticalSection(&ddraw_cs);
+            return DDERR_INVALIDCAPS;
+        }
+        if(DDSD->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP &&
+           (DDSD->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES) == 0)
+        {
+            WARN("Cube map without faces requested\n");
+            LeaveCriticalSection(&ddraw_cs);
+            return DDERR_INVALIDPARAMS;
+        }
+
+        /* Quick tests confirm those can be created, but we don't do that yet */
+        if(DDSD->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP &&
+           (DDSD->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES) != DDSCAPS2_CUBEMAP_ALLFACES)
+        {
+            FIXME("Partial cube maps not supported yet\n");
+        }
+    }
+
+    /* According to the msdn this flag is ignored by CreateSurface */
+    if (DDSD->dwSize >= sizeof(DDSURFACEDESC2))
+        DDSD->ddsCaps.dwCaps2 &= ~DDSCAPS2_MIPMAPSUBLEVEL;
+
+    /* Modify some flags */
+    memset(&desc2, 0, sizeof(desc2));
+    desc2.dwSize = sizeof(desc2);   /* For the struct copy */
+    DD_STRUCT_COPY_BYSIZE(&desc2, DDSD);
+    desc2.dwSize = sizeof(desc2);   /* To override a possibly smaller size */
+    desc2.u4.ddpfPixelFormat.dwSize=sizeof(DDPIXELFORMAT); /* Just to be sure */
+
+    /* Get the video mode from WineD3D - we will need it */
+    hr = IWineD3DDevice_GetDisplayMode(This->wineD3DDevice,
+                                       0, /* Swapchain 0 */
+                                       &Mode);
+    if(FAILED(hr))
+    {
+        ERR("Failed to read display mode from wined3d\n");
+        switch(This->orig_bpp)
+        {
+            case 8:
+                Mode.Format = WINED3DFMT_P8;
+                break;
+
+            case 15:
+                Mode.Format = WINED3DFMT_X1R5G5B5;
+                break;
+
+            case 16:
+                Mode.Format = WINED3DFMT_R5G6B5;
+                break;
+
+            case 24:
+                Mode.Format = WINED3DFMT_R8G8B8;
+                break;
+
+            case 32:
+                Mode.Format = WINED3DFMT_X8R8G8B8;
+                break;
+        }
+        Mode.Width = This->orig_width;
+        Mode.Height = This->orig_height;
+    }
+
+    /* No pixelformat given? Use the current screen format */
+    if(!(desc2.dwFlags & DDSD_PIXELFORMAT))
+    {
+        desc2.dwFlags |= DDSD_PIXELFORMAT;
+        desc2.u4.ddpfPixelFormat.dwSize=sizeof(DDPIXELFORMAT);
+
+        /* Wait: It could be a Z buffer */
+        if(desc2.ddsCaps.dwCaps & DDSCAPS_ZBUFFER)
+        {
+            switch(desc2.u2.dwMipMapCount) /* Who had this glorious idea? */
+            {
+                case 15:
+                    PixelFormat_WineD3DtoDD(&desc2.u4.ddpfPixelFormat, WINED3DFMT_D15S1);
+                    break;
+                case 16:
+                    PixelFormat_WineD3DtoDD(&desc2.u4.ddpfPixelFormat, WINED3DFMT_D16_UNORM);
+                    break;
+                case 24:
+                    PixelFormat_WineD3DtoDD(&desc2.u4.ddpfPixelFormat, WINED3DFMT_D24X8);
+                    break;
+                case 32:
+                    PixelFormat_WineD3DtoDD(&desc2.u4.ddpfPixelFormat, WINED3DFMT_D32);
+                    break;
+                default:
+                    ERR("Unknown Z buffer bit depth\n");
+            }
+        }
+        else
+        {
+            PixelFormat_WineD3DtoDD(&desc2.u4.ddpfPixelFormat, Mode.Format);
+        }
+    }
+
+    /* No Width or no Height? Use the original screen size
+     */
+    if(!(desc2.dwFlags & DDSD_WIDTH) ||
+       !(desc2.dwFlags & DDSD_HEIGHT) )
+    {
+        /* Invalid for non-render targets */
+        if(!(desc2.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
+        {
+            WARN("Creating a non-Primary surface without Width or Height info, returning DDERR_INVALIDPARAMS\n");
+            *Surf = NULL;
+            LeaveCriticalSection(&ddraw_cs);
+            return DDERR_INVALIDPARAMS;
+        }
+
+        desc2.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT;
+        desc2.dwWidth = Mode.Width;
+        desc2.dwHeight = Mode.Height;
+    }
+
+    /* Mipmap count fixes */
+    if(desc2.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
+    {
+        if(desc2.ddsCaps.dwCaps & DDSCAPS_COMPLEX)
+        {
+            if(desc2.dwFlags & DDSD_MIPMAPCOUNT)
+            {
+                /* Mipmap count is given, should not be 0 */
+                if( desc2.u2.dwMipMapCount == 0 )
+                {
+                    LeaveCriticalSection(&ddraw_cs);
+                    return DDERR_INVALIDPARAMS;
+                }
+            }
+            else
+            {
+                /* Undocumented feature: Create sublevels until
+                 * either the width or the height is 1
+                 */
+                DWORD min = desc2.dwWidth < desc2.dwHeight ?
+                            desc2.dwWidth : desc2.dwHeight;
+                desc2.u2.dwMipMapCount = 0;
+                while( min )
+                {
+                    desc2.u2.dwMipMapCount += 1;
+                    min >>= 1;
+                }
+            }
+        }
+        else
+        {
+            /* Not-complex mipmap -> Mipmapcount = 1 */
+            desc2.u2.dwMipMapCount = 1;
+        }
+        extra_surfaces = desc2.u2.dwMipMapCount - 1;
+
+        /* There's a mipmap count in the created surface in any case */
+        desc2.dwFlags |= DDSD_MIPMAPCOUNT;
+    }
+    /* If no mipmap is given, the texture has only one level */
+
+    /* The first surface is a front buffer, the back buffer is created afterwards */
+    if( (desc2.dwFlags & DDSD_CAPS) && (desc2.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) )
+    {
+        desc2.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
+    }
+
+    /* The root surface in a cube map is positive x */
+    if(desc2.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
+    {
+        desc2.ddsCaps.dwCaps2 &= ~DDSCAPS2_CUBEMAP_ALLFACES;
+        desc2.ddsCaps.dwCaps2 |=  DDSCAPS2_CUBEMAP_POSITIVEX;
+    }
+
+    /* Create the first surface */
+    hr = IDirectDrawImpl_CreateNewSurface(This, &desc2, &object, 0);
+    if( hr != DD_OK)
+    {
+        ERR("IDirectDrawImpl_CreateNewSurface failed with %08x\n", hr);
+        LeaveCriticalSection(&ddraw_cs);
+        return hr;
+    }
+    object->is_complex_root = TRUE;
+
+    *Surf = (IDirectDrawSurface7 *)object;
+
+    /* Create Additional surfaces if necessary
+     * This applies to Primary surfaces which have a back buffer count
+     * set, but not to mipmap textures. In case of Mipmap textures,
+     * wineD3D takes care of the creation of additional surfaces
+     */
+    if(DDSD->dwFlags & DDSD_BACKBUFFERCOUNT)
+    {
+        extra_surfaces = DDSD->u5.dwBackBufferCount;
+        desc2.ddsCaps.dwCaps &= ~DDSCAPS_FRONTBUFFER; /* It's not a front buffer */
+        desc2.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
+    }
+
+    hr = DD_OK;
+    if(desc2.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
+    {
+        desc2.ddsCaps.dwCaps2 &= ~DDSCAPS2_CUBEMAP_ALLFACES;
+        desc2.ddsCaps.dwCaps2 |=  DDSCAPS2_CUBEMAP_NEGATIVEZ;
+        hr |= CreateAdditionalSurfaces(This, object, extra_surfaces + 1, desc2, TRUE);
+        desc2.ddsCaps.dwCaps2 &= ~DDSCAPS2_CUBEMAP_NEGATIVEZ;
+        desc2.ddsCaps.dwCaps2 |=  DDSCAPS2_CUBEMAP_POSITIVEZ;
+        hr |= CreateAdditionalSurfaces(This, object, extra_surfaces + 1, desc2, TRUE);
+        desc2.ddsCaps.dwCaps2 &= ~DDSCAPS2_CUBEMAP_POSITIVEZ;
+        desc2.ddsCaps.dwCaps2 |=  DDSCAPS2_CUBEMAP_NEGATIVEY;
+        hr |= CreateAdditionalSurfaces(This, object, extra_surfaces + 1, desc2, TRUE);
+        desc2.ddsCaps.dwCaps2 &= ~DDSCAPS2_CUBEMAP_NEGATIVEY;
+        desc2.ddsCaps.dwCaps2 |=  DDSCAPS2_CUBEMAP_POSITIVEY;
+        hr |= CreateAdditionalSurfaces(This, object, extra_surfaces + 1, desc2, TRUE);
+        desc2.ddsCaps.dwCaps2 &= ~DDSCAPS2_CUBEMAP_POSITIVEY;
+        desc2.ddsCaps.dwCaps2 |=  DDSCAPS2_CUBEMAP_NEGATIVEX;
+        hr |= CreateAdditionalSurfaces(This, object, extra_surfaces + 1, desc2, TRUE);
+        desc2.ddsCaps.dwCaps2 &= ~DDSCAPS2_CUBEMAP_NEGATIVEX;
+        desc2.ddsCaps.dwCaps2 |=  DDSCAPS2_CUBEMAP_POSITIVEX;
+    }
+
+    hr |= CreateAdditionalSurfaces(This, object, extra_surfaces, desc2, FALSE);
+    if(hr != DD_OK)
+    {
+        /* This destroys and possibly created surfaces too */
+        IDirectDrawSurface_Release((IDirectDrawSurface7 *)object);
+        LeaveCriticalSection(&ddraw_cs);
+        return hr;
+    }
+
+    /* If the implementation is OpenGL and there's no d3ddevice, attach a d3ddevice
+     * But attach the d3ddevice only if the currently created surface was
+     * a primary surface (2D app in 3D mode) or a 3DDEVICE surface (3D app)
+     * The only case I can think of where this doesn't apply is when a
+     * 2D app was configured by the user to run with OpenGL and it didn't create
+     * the render target as first surface. In this case the render target creation
+     * will cause the 3D init.
+     */
+    if( (This->ImplType == SURFACE_OPENGL) && !(This->d3d_initialized) &&
+        desc2.ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE) )
+    {
+        IDirectDrawSurfaceImpl *target = object, *surface;
+        struct list *entry;
+
+        /* Search for the primary to use as render target */
+        LIST_FOR_EACH(entry, &This->surface_list)
+        {
+            surface = LIST_ENTRY(entry, IDirectDrawSurfaceImpl, surface_list_entry);
+            if((surface->surface_desc.ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER)) ==
+               (DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER))
+            {
+                /* found */
+                target = surface;
+                TRACE("Using primary %p as render target\n", target);
+                break;
+            }
+        }
+
+        TRACE("(%p) Attaching a D3DDevice, rendertarget = %p\n", This, target);
+        hr = IDirectDrawImpl_AttachD3DDevice(This, target);
+        if(hr != D3D_OK)
+        {
+            IDirectDrawSurfaceImpl *release_surf;
+            ERR("IDirectDrawImpl_AttachD3DDevice failed, hr = %x\n", hr);
+            *Surf = NULL;
+
+            /* The before created surface structures are in an incomplete state here.
+             * WineD3D holds the reference on the IParents, and it released them on the failure
+             * already. So the regular release method implementation would fail on the attempt
+             * to destroy either the IParents or the swapchain. So free the surface here.
+             * The surface structure here is a list, not a tree, because onscreen targets
+             * cannot be cube textures
+             */
+            while(object)
+            {
+                release_surf = object;
+                object = object->complex_array[0];
+                IDirectDrawSurfaceImpl_Destroy(release_surf);
+            }
+            LeaveCriticalSection(&ddraw_cs);
+            return hr;
+        }
+    } else if(!(This->d3d_initialized) && desc2.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) {