ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

device.c
Go to the documentation of this file.
00001 /*
00002  * IDirect3DDevice9 implementation
00003  *
00004  * Copyright 2002-2005 Jason Edmeades
00005  * Copyright 2002-2005 Raphael Junqueira
00006  * Copyright 2005 Oliver Stieber
00007  *
00008  * This library is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2.1 of the License, or (at your option) any later version.
00012  *
00013  * This library is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with this library; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00021  */
00022 
00023 #include "config.h"
00024 #include "d3d9_private.h"
00025 
00026 WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
00027 
00028 D3DFORMAT d3dformat_from_wined3dformat(enum wined3d_format_id format)
00029 {
00030     BYTE *c = (BYTE *)&format;
00031 
00032     /* Don't translate FOURCC formats */
00033     if (isprint(c[0]) && isprint(c[1]) && isprint(c[2]) && isprint(c[3])) return format;
00034 
00035     switch(format)
00036     {
00037         case WINED3DFMT_UNKNOWN: return D3DFMT_UNKNOWN;
00038         case WINED3DFMT_B8G8R8_UNORM: return D3DFMT_R8G8B8;
00039         case WINED3DFMT_B8G8R8A8_UNORM: return D3DFMT_A8R8G8B8;
00040         case WINED3DFMT_B8G8R8X8_UNORM: return D3DFMT_X8R8G8B8;
00041         case WINED3DFMT_B5G6R5_UNORM: return D3DFMT_R5G6B5;
00042         case WINED3DFMT_B5G5R5X1_UNORM: return D3DFMT_X1R5G5B5;
00043         case WINED3DFMT_B5G5R5A1_UNORM: return D3DFMT_A1R5G5B5;
00044         case WINED3DFMT_B4G4R4A4_UNORM: return D3DFMT_A4R4G4B4;
00045         case WINED3DFMT_B2G3R3_UNORM: return D3DFMT_R3G3B2;
00046         case WINED3DFMT_A8_UNORM: return D3DFMT_A8;
00047         case WINED3DFMT_B2G3R3A8_UNORM: return D3DFMT_A8R3G3B2;
00048         case WINED3DFMT_B4G4R4X4_UNORM: return D3DFMT_X4R4G4B4;
00049         case WINED3DFMT_R10G10B10A2_UNORM: return D3DFMT_A2B10G10R10;
00050         case WINED3DFMT_R8G8B8A8_UNORM: return D3DFMT_A8B8G8R8;
00051         case WINED3DFMT_R8G8B8X8_UNORM: return D3DFMT_X8B8G8R8;
00052         case WINED3DFMT_R16G16_UNORM: return D3DFMT_G16R16;
00053         case WINED3DFMT_B10G10R10A2_UNORM: return D3DFMT_A2R10G10B10;
00054         case WINED3DFMT_R16G16B16A16_UNORM: return D3DFMT_A16B16G16R16;
00055         case WINED3DFMT_P8_UINT_A8_UNORM: return D3DFMT_A8P8;
00056         case WINED3DFMT_P8_UINT: return D3DFMT_P8;
00057         case WINED3DFMT_L8_UNORM: return D3DFMT_L8;
00058         case WINED3DFMT_L8A8_UNORM: return D3DFMT_A8L8;
00059         case WINED3DFMT_L4A4_UNORM: return D3DFMT_A4L4;
00060         case WINED3DFMT_R8G8_SNORM: return D3DFMT_V8U8;
00061         case WINED3DFMT_R5G5_SNORM_L6_UNORM: return D3DFMT_L6V5U5;
00062         case WINED3DFMT_R8G8_SNORM_L8X8_UNORM: return D3DFMT_X8L8V8U8;
00063         case WINED3DFMT_R8G8B8A8_SNORM: return D3DFMT_Q8W8V8U8;
00064         case WINED3DFMT_R16G16_SNORM: return D3DFMT_V16U16;
00065         case WINED3DFMT_R10G10B10_SNORM_A2_UNORM: return D3DFMT_A2W10V10U10;
00066         case WINED3DFMT_D16_LOCKABLE: return D3DFMT_D16_LOCKABLE;
00067         case WINED3DFMT_D32_UNORM: return D3DFMT_D32;
00068         case WINED3DFMT_S1_UINT_D15_UNORM: return D3DFMT_D15S1;
00069         case WINED3DFMT_D24_UNORM_S8_UINT: return D3DFMT_D24S8;
00070         case WINED3DFMT_X8D24_UNORM: return D3DFMT_D24X8;
00071         case WINED3DFMT_S4X4_UINT_D24_UNORM: return D3DFMT_D24X4S4;
00072         case WINED3DFMT_D16_UNORM: return D3DFMT_D16;
00073         case WINED3DFMT_L16_UNORM: return D3DFMT_L16;
00074         case WINED3DFMT_D32_FLOAT: return D3DFMT_D32F_LOCKABLE;
00075         case WINED3DFMT_S8_UINT_D24_FLOAT: return D3DFMT_D24FS8;
00076         case WINED3DFMT_VERTEXDATA: return D3DFMT_VERTEXDATA;
00077         case WINED3DFMT_R16_UINT: return D3DFMT_INDEX16;
00078         case WINED3DFMT_R32_UINT: return D3DFMT_INDEX32;
00079         case WINED3DFMT_R16G16B16A16_SNORM: return D3DFMT_Q16W16V16U16;
00080         case WINED3DFMT_R16_FLOAT: return D3DFMT_R16F;
00081         case WINED3DFMT_R16G16_FLOAT: return D3DFMT_G16R16F;
00082         case WINED3DFMT_R16G16B16A16_FLOAT: return D3DFMT_A16B16G16R16F;
00083         case WINED3DFMT_R32_FLOAT: return D3DFMT_R32F;
00084         case WINED3DFMT_R32G32_FLOAT: return D3DFMT_G32R32F;
00085         case WINED3DFMT_R32G32B32A32_FLOAT: return D3DFMT_A32B32G32R32F;
00086         case WINED3DFMT_R8G8_SNORM_Cx: return D3DFMT_CxV8U8;
00087         default:
00088             FIXME("Unhandled wined3d format %#x.\n", format);
00089             return D3DFMT_UNKNOWN;
00090     }
00091 }
00092 
00093 enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format)
00094 {
00095     BYTE *c = (BYTE *)&format;
00096 
00097     /* Don't translate FOURCC formats */
00098     if (isprint(c[0]) && isprint(c[1]) && isprint(c[2]) && isprint(c[3])) return format;
00099 
00100     switch(format)
00101     {
00102         case D3DFMT_UNKNOWN: return WINED3DFMT_UNKNOWN;
00103         case D3DFMT_R8G8B8: return WINED3DFMT_B8G8R8_UNORM;
00104         case D3DFMT_A8R8G8B8: return WINED3DFMT_B8G8R8A8_UNORM;
00105         case D3DFMT_X8R8G8B8: return WINED3DFMT_B8G8R8X8_UNORM;
00106         case D3DFMT_R5G6B5: return WINED3DFMT_B5G6R5_UNORM;
00107         case D3DFMT_X1R5G5B5: return WINED3DFMT_B5G5R5X1_UNORM;
00108         case D3DFMT_A1R5G5B5: return WINED3DFMT_B5G5R5A1_UNORM;
00109         case D3DFMT_A4R4G4B4: return WINED3DFMT_B4G4R4A4_UNORM;
00110         case D3DFMT_R3G3B2: return WINED3DFMT_B2G3R3_UNORM;
00111         case D3DFMT_A8: return WINED3DFMT_A8_UNORM;
00112         case D3DFMT_A8R3G3B2: return WINED3DFMT_B2G3R3A8_UNORM;
00113         case D3DFMT_X4R4G4B4: return WINED3DFMT_B4G4R4X4_UNORM;
00114         case D3DFMT_A2B10G10R10: return WINED3DFMT_R10G10B10A2_UNORM;
00115         case D3DFMT_A8B8G8R8: return WINED3DFMT_R8G8B8A8_UNORM;
00116         case D3DFMT_X8B8G8R8: return WINED3DFMT_R8G8B8X8_UNORM;
00117         case D3DFMT_G16R16: return WINED3DFMT_R16G16_UNORM;
00118         case D3DFMT_A2R10G10B10: return WINED3DFMT_B10G10R10A2_UNORM;
00119         case D3DFMT_A16B16G16R16: return WINED3DFMT_R16G16B16A16_UNORM;
00120         case D3DFMT_A8P8: return WINED3DFMT_P8_UINT_A8_UNORM;
00121         case D3DFMT_P8: return WINED3DFMT_P8_UINT;
00122         case D3DFMT_L8: return WINED3DFMT_L8_UNORM;
00123         case D3DFMT_A8L8: return WINED3DFMT_L8A8_UNORM;
00124         case D3DFMT_A4L4: return WINED3DFMT_L4A4_UNORM;
00125         case D3DFMT_V8U8: return WINED3DFMT_R8G8_SNORM;
00126         case D3DFMT_L6V5U5: return WINED3DFMT_R5G5_SNORM_L6_UNORM;
00127         case D3DFMT_X8L8V8U8: return WINED3DFMT_R8G8_SNORM_L8X8_UNORM;
00128         case D3DFMT_Q8W8V8U8: return WINED3DFMT_R8G8B8A8_SNORM;
00129         case D3DFMT_V16U16: return WINED3DFMT_R16G16_SNORM;
00130         case D3DFMT_A2W10V10U10: return WINED3DFMT_R10G10B10_SNORM_A2_UNORM;
00131         case D3DFMT_D16_LOCKABLE: return WINED3DFMT_D16_LOCKABLE;
00132         case D3DFMT_D32: return WINED3DFMT_D32_UNORM;
00133         case D3DFMT_D15S1: return WINED3DFMT_S1_UINT_D15_UNORM;
00134         case D3DFMT_D24S8: return WINED3DFMT_D24_UNORM_S8_UINT;
00135         case D3DFMT_D24X8: return WINED3DFMT_X8D24_UNORM;
00136         case D3DFMT_D24X4S4: return WINED3DFMT_S4X4_UINT_D24_UNORM;
00137         case D3DFMT_D16: return WINED3DFMT_D16_UNORM;
00138         case D3DFMT_L16: return WINED3DFMT_L16_UNORM;
00139         case D3DFMT_D32F_LOCKABLE: return WINED3DFMT_D32_FLOAT;
00140         case D3DFMT_D24FS8: return WINED3DFMT_S8_UINT_D24_FLOAT;
00141         case D3DFMT_VERTEXDATA: return WINED3DFMT_VERTEXDATA;
00142         case D3DFMT_INDEX16: return WINED3DFMT_R16_UINT;
00143         case D3DFMT_INDEX32: return WINED3DFMT_R32_UINT;
00144         case D3DFMT_Q16W16V16U16: return WINED3DFMT_R16G16B16A16_SNORM;
00145         case D3DFMT_R16F: return WINED3DFMT_R16_FLOAT;
00146         case D3DFMT_G16R16F: return WINED3DFMT_R16G16_FLOAT;
00147         case D3DFMT_A16B16G16R16F: return WINED3DFMT_R16G16B16A16_FLOAT;
00148         case D3DFMT_R32F: return WINED3DFMT_R32_FLOAT;
00149         case D3DFMT_G32R32F: return WINED3DFMT_R32G32_FLOAT;
00150         case D3DFMT_A32B32G32R32F: return WINED3DFMT_R32G32B32A32_FLOAT;
00151         case D3DFMT_CxV8U8: return WINED3DFMT_R8G8_SNORM_Cx;
00152         default:
00153             FIXME("Unhandled D3DFORMAT %#x\n", format);
00154             return WINED3DFMT_UNKNOWN;
00155     }
00156 }
00157 
00158 static UINT vertex_count_from_primitive_count(D3DPRIMITIVETYPE primitive_type, UINT primitive_count)
00159 {
00160     switch(primitive_type)
00161     {
00162         case D3DPT_POINTLIST:
00163             return primitive_count;
00164 
00165         case D3DPT_LINELIST:
00166             return primitive_count * 2;
00167 
00168         case D3DPT_LINESTRIP:
00169             return primitive_count + 1;
00170 
00171         case D3DPT_TRIANGLELIST:
00172             return primitive_count * 3;
00173 
00174         case D3DPT_TRIANGLESTRIP:
00175         case D3DPT_TRIANGLEFAN:
00176             return primitive_count + 2;
00177 
00178         default:
00179             FIXME("Unhandled primitive type %#x\n", primitive_type);
00180             return 0;
00181     }
00182 }
00183 
00184 static inline IDirect3DDevice9Impl *impl_from_IDirect3DDevice9Ex(IDirect3DDevice9Ex *iface)
00185 {
00186     return CONTAINING_RECORD(iface, IDirect3DDevice9Impl, IDirect3DDevice9Ex_iface);
00187 }
00188 
00189 static HRESULT WINAPI IDirect3DDevice9Impl_QueryInterface(IDirect3DDevice9Ex *iface, REFIID riid,
00190         void **ppobj)
00191 {
00192     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
00193     IDirect3D9 *d3d;
00194     IDirect3D9Impl *d3dimpl;
00195 
00196     TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), ppobj);
00197 
00198     if (IsEqualGUID(riid, &IID_IUnknown)
00199         || IsEqualGUID(riid, &IID_IDirect3DDevice9)) {
00200         IDirect3DDevice9Ex_AddRef(iface);
00201         *ppobj = This;
00202         TRACE("Returning IDirect3DDevice9 interface at %p\n", *ppobj);
00203         return S_OK;
00204     } else if(IsEqualGUID(riid, &IID_IDirect3DDevice9Ex)) {
00205         /* Find out if the creating d3d9 interface was created with Direct3DCreate9Ex.
00206          * It doesn't matter with which function the device was created.
00207          */
00208         IDirect3DDevice9_GetDirect3D(iface, &d3d);
00209         d3dimpl = (IDirect3D9Impl *) d3d;
00210 
00211         if(d3dimpl->extended) {
00212             *ppobj = iface;
00213             IDirect3DDevice9Ex_AddRef((IDirect3DDevice9Ex *) *ppobj);
00214             IDirect3D9_Release(d3d);
00215             TRACE("Returning IDirect3DDevice9Ex interface at %p\n", *ppobj);
00216             return S_OK;
00217         } else {
00218             WARN("IDirect3D9 instance wasn't created with CreateDirect3D9Ex, returning E_NOINTERFACE\n");
00219             IDirect3D9_Release(d3d);
00220             *ppobj = NULL;
00221             return E_NOINTERFACE;
00222         }
00223     }
00224 
00225     WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
00226     *ppobj = NULL;
00227     return E_NOINTERFACE;
00228 }
00229 
00230 static ULONG WINAPI IDirect3DDevice9Impl_AddRef(IDirect3DDevice9Ex *iface)
00231 {
00232     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
00233     ULONG ref = InterlockedIncrement(&This->ref);
00234 
00235     TRACE("%p increasing refcount to %u.\n", iface, ref);
00236 
00237     return ref;
00238 }
00239 
00240 static ULONG WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_Release(IDirect3DDevice9Ex *iface)
00241 {
00242     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
00243     ULONG ref;
00244 
00245     if (This->inDestruction) return 0;
00246     ref = InterlockedDecrement(&This->ref);
00247 
00248     TRACE("%p decreasing refcount to %u.\n", iface, ref);
00249 
00250     if (ref == 0) {
00251       unsigned i;
00252       This->inDestruction = TRUE;
00253 
00254       wined3d_mutex_lock();
00255       for(i = 0; i < This->numConvertedDecls; i++) {
00256           /* Unless Wine is buggy or the app has a bug the refcount will be 0, because decls hold a reference to the
00257            * device
00258            */
00259           IDirect3DVertexDeclaration9Impl_Destroy(This->convertedDecls[i]);
00260       }
00261       HeapFree(GetProcessHeap(), 0, This->convertedDecls);
00262 
00263       wined3d_device_uninit_3d(This->wined3d_device);
00264       wined3d_device_release_focus_window(This->wined3d_device);
00265       wined3d_device_decref(This->wined3d_device);
00266       wined3d_mutex_unlock();
00267 
00268       IDirect3D9_Release(This->d3d_parent);
00269 
00270       HeapFree(GetProcessHeap(), 0, This);
00271     }
00272     return ref;
00273 }
00274 
00275 static HRESULT WINAPI IDirect3DDevice9Impl_TestCooperativeLevel(IDirect3DDevice9Ex *iface)
00276 {
00277     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
00278 
00279     TRACE("iface %p.\n", iface);
00280 
00281     if (This->notreset)
00282     {
00283         TRACE("D3D9 device is marked not reset.\n");
00284         return D3DERR_DEVICENOTRESET;
00285     }
00286 
00287     return D3D_OK;
00288 }
00289 
00290 static UINT WINAPI IDirect3DDevice9Impl_GetAvailableTextureMem(IDirect3DDevice9Ex *iface)
00291 {
00292     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
00293     HRESULT hr;
00294 
00295     TRACE("iface %p.\n", iface);
00296 
00297     wined3d_mutex_lock();
00298     hr = wined3d_device_get_available_texture_mem(This->wined3d_device);
00299     wined3d_mutex_unlock();
00300 
00301     return hr;
00302 }
00303 
00304 static HRESULT WINAPI IDirect3DDevice9Impl_EvictManagedResources(IDirect3DDevice9Ex *iface)
00305 {
00306     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
00307 
00308     TRACE("iface %p.\n", iface);
00309 
00310     wined3d_mutex_lock();
00311     wined3d_device_evict_managed_resources(This->wined3d_device);
00312     wined3d_mutex_unlock();
00313 
00314     return D3D_OK;
00315 }
00316 
00317 static HRESULT WINAPI IDirect3DDevice9Impl_GetDirect3D(IDirect3DDevice9Ex *iface,
00318         IDirect3D9 **ppD3D9)
00319 {
00320     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
00321 
00322     TRACE("iface %p, d3d9 %p.\n", iface, ppD3D9);
00323 
00324     if (NULL == ppD3D9) {
00325         return D3DERR_INVALIDCALL;
00326     }
00327 
00328     return IDirect3D9Ex_QueryInterface(This->d3d_parent, &IID_IDirect3D9, (void **)ppD3D9);
00329 }
00330 
00331 static HRESULT WINAPI IDirect3DDevice9Impl_GetDeviceCaps(IDirect3DDevice9Ex *iface, D3DCAPS9 *pCaps)
00332 {
00333     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
00334     HRESULT hrc = D3D_OK;
00335     WINED3DCAPS *pWineCaps;
00336 
00337     TRACE("iface %p, caps %p.\n", iface, pCaps);
00338 
00339     if(NULL == pCaps){
00340         return D3DERR_INVALIDCALL;
00341     }
00342     pWineCaps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINED3DCAPS));
00343     if(pWineCaps == NULL){
00344         return D3DERR_INVALIDCALL; /* well this is what MSDN says to return */
00345     }
00346 
00347     memset(pCaps, 0, sizeof(*pCaps));
00348 
00349     wined3d_mutex_lock();
00350     hrc = wined3d_device_get_device_caps(This->wined3d_device, pWineCaps);
00351     wined3d_mutex_unlock();
00352 
00353     WINECAPSTOD3D9CAPS(pCaps, pWineCaps)
00354     HeapFree(GetProcessHeap(), 0, pWineCaps);
00355 
00356     /* Some functionality is implemented in d3d9.dll, not wined3d.dll. Add the needed caps */
00357     pCaps->DevCaps2 |= D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES;
00358 
00359     filter_caps(pCaps);
00360 
00361     TRACE("Returning %p %p\n", This, pCaps);
00362     return hrc;
00363 }
00364 
00365 static HRESULT WINAPI IDirect3DDevice9Impl_GetDisplayMode(IDirect3DDevice9Ex *iface,
00366         UINT iSwapChain, D3DDISPLAYMODE *pMode)
00367 {
00368     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
00369     HRESULT hr;
00370 
00371     TRACE("iface %p, swapchain %u, mode %p.\n", iface, iSwapChain, pMode);
00372 
00373     wined3d_mutex_lock();
00374     hr = wined3d_device_get_display_mode(This->wined3d_device, iSwapChain, (struct wined3d_display_mode *)pMode);
00375     wined3d_mutex_unlock();
00376 
00377     if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
00378 
00379     return hr;
00380 }
00381 
00382 static HRESULT WINAPI IDirect3DDevice9Impl_GetCreationParameters(IDirect3DDevice9Ex *iface,
00383         D3DDEVICE_CREATION_PARAMETERS *pParameters)
00384 {
00385     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
00386     HRESULT hr;
00387 
00388     TRACE("iface %p, parameters %p.\n", iface, pParameters);
00389 
00390     wined3d_mutex_lock();
00391     hr = wined3d_device_get_creation_parameters(This->wined3d_device,
00392             (struct wined3d_device_creation_parameters *)pParameters);
00393     wined3d_mutex_unlock();
00394 
00395     return hr;
00396 }
00397 
00398 static HRESULT WINAPI IDirect3DDevice9Impl_SetCursorProperties(IDirect3DDevice9Ex *iface,
00399         UINT XHotSpot, UINT YHotSpot, IDirect3DSurface9 *pCursorBitmap)
00400 {
00401     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
00402     IDirect3DSurface9Impl *pSurface = unsafe_impl_from_IDirect3DSurface9(pCursorBitmap);
00403     HRESULT hr;
00404 
00405     TRACE("iface %p, hotspot_x %u, hotspot_y %u, bitmap %p.\n",
00406             iface, XHotSpot, YHotSpot, pCursorBitmap);
00407 
00408     if (!pCursorBitmap)
00409     {
00410         WARN("No cursor bitmap, returning D3DERR_INVALIDCALL.\n");
00411         return D3DERR_INVALIDCALL;
00412     }
00413 
00414     wined3d_mutex_lock();
00415     hr = wined3d_device_set_cursor_properties(This->wined3d_device, XHotSpot, YHotSpot, pSurface->wined3d_surface);
00416     wined3d_mutex_unlock();
00417 
00418     return hr;
00419 }
00420 
00421 static void WINAPI IDirect3DDevice9Impl_SetCursorPosition(IDirect3DDevice9Ex *iface,
00422         int XScreenSpace, int YScreenSpace, DWORD Flags)
00423 {
00424     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
00425 
00426     TRACE("iface %p, x %u, y %u, flags %#x.\n", iface, XScreenSpace, YScreenSpace, Flags);
00427 
00428     wined3d_mutex_lock();
00429     wined3d_device_set_cursor_position(This->wined3d_device, XScreenSpace, YScreenSpace, Flags);
00430     wined3d_mutex_unlock();
00431 }
00432 
00433 static BOOL WINAPI IDirect3DDevice9Impl_ShowCursor(IDirect3DDevice9Ex *iface, BOOL bShow)
00434 {
00435     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
00436     BOOL ret;
00437 
00438     TRACE("iface %p, show %#x.\n", iface, bShow);
00439 
00440     wined3d_mutex_lock();
00441     ret = wined3d_device_show_cursor(This->wined3d_device, bShow);
00442     wined3d_mutex_unlock();
00443 
00444     return ret;
00445 }
00446 
00447 static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_CreateAdditionalSwapChain(IDirect3DDevice9Ex *iface,
00448         D3DPRESENT_PARAMETERS *present_parameters, IDirect3DSwapChain9 **swapchain)
00449 {
00450     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
00451     IDirect3DSwapChain9Impl *object;
00452     HRESULT hr;
00453 
00454     TRACE("iface %p, present_parameters %p, swapchain %p.\n",
00455             iface, present_parameters, swapchain);
00456 
00457     object = HeapAlloc(GetProcessHeap(),  HEAP_ZERO_MEMORY, sizeof(*object));
00458     if (!object)
00459     {
00460         ERR("Failed to allocate swapchain memory.\n");
00461         return E_OUTOFMEMORY;
00462     }
00463 
00464     hr = swapchain_init(object, This, present_parameters);
00465     if (FAILED(hr))
00466     {
00467         WARN("Failed to initialize swapchain, hr %#x.\n", hr);
00468         HeapFree(GetProcessHeap(), 0, object);
00469         return hr;
00470     }
00471 
00472     TRACE("Created swapchain %p.\n", object);
00473     *swapchain = (IDirect3DSwapChain9 *)object;
00474 
00475     return D3D_OK;
00476 }
00477 
00478 static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_GetSwapChain(IDirect3DDevice9Ex *iface,
00479         UINT swapchain_idx, IDirect3DSwapChain9 **swapchain)
00480 {
00481     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
00482     struct wined3d_swapchain *wined3d_swapchain = NULL;
00483     HRESULT hr;
00484 
00485     TRACE("iface %p, swapchain_idx %u, swapchain %p.\n", iface, swapchain_idx, swapchain);
00486 
00487     wined3d_mutex_lock();
00488     hr = wined3d_device_get_swapchain(This->wined3d_device, swapchain_idx, &wined3d_swapchain);
00489     if (SUCCEEDED(hr) && wined3d_swapchain)
00490     {
00491        *swapchain = wined3d_swapchain_get_parent(wined3d_swapchain);
00492        IDirect3DSwapChain9_AddRef(*swapchain);
00493        wined3d_swapchain_decref(wined3d_swapchain);
00494     }
00495     else
00496     {
00497         *swapchain = NULL;
00498     }
00499     wined3d_mutex_unlock();
00500 
00501     return hr;
00502 }
00503 
00504 static UINT WINAPI IDirect3DDevice9Impl_GetNumberOfSwapChains(IDirect3DDevice9Ex *iface)
00505 {
00506     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
00507     UINT count;
00508 
00509     TRACE("iface %p.\n", iface);
00510 
00511     wined3d_mutex_lock();
00512     count = wined3d_device_get_swapchain_count(This->wined3d_device);
00513     wined3d_mutex_unlock();
00514 
00515     return count;
00516 }
00517 
00518 static HRESULT CDECL reset_enum_callback(struct wined3d_resource *resource)
00519 {
00520     struct wined3d_resource_desc desc;
00521 
00522     wined3d_resource_get_desc(resource, &desc);
00523     if (desc.pool == WINED3D_POOL_DEFAULT)
00524     {
00525         IDirect3DSurface9 *surface;
00526 
00527         if (desc.resource_type != WINED3D_RTYPE_SURFACE)
00528         {
00529             WARN("Resource %p in pool D3DPOOL_DEFAULT blocks the Reset call.\n", resource);
00530             return D3DERR_INVALIDCALL;
00531         }
00532 
00533         surface = wined3d_resource_get_parent(resource);
00534 
00535         IDirect3DSurface9_AddRef(surface);
00536         if (IDirect3DSurface9_Release(surface))
00537         {
00538             WARN("Surface %p (resource %p) in pool D3DPOOL_DEFAULT blocks the Reset call.\n", surface, resource);
00539             return D3DERR_INVALIDCALL;
00540         }
00541 
00542         WARN("Surface %p (resource %p) is an implicit resource with ref 0.\n", surface, resource);
00543     }
00544 
00545     return D3D_OK;
00546 }
00547 
00548 static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_Reset(IDirect3DDevice9Ex *iface,
00549         D3DPRESENT_PARAMETERS *pPresentationParameters)
00550 {
00551     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
00552     struct wined3d_swapchain_desc swapchain_desc;
00553     HRESULT hr;
00554 
00555     TRACE("iface %p, present_parameters %p.\n", iface, pPresentationParameters);
00556 
00557     /* Reset states that hold a COM object. WineD3D holds an internal reference to set objects, because
00558      * such objects can still be used for rendering after their external d3d9 object has been destroyed.
00559      * These objects must not be enumerated. Unsetting them tells WineD3D that the application will not
00560      * make use of the hidden reference and destroys the objects.
00561      *
00562      * Unsetting them is no problem, because the states are supposed to be reset anyway. If the validation
00563      * below fails, the device is considered "lost", and _Reset and _Release are the only allowed calls
00564      */
00565     wined3d_mutex_lock();
00566 
00567     swapchain_desc.backbuffer_width = pPresentationParameters->BackBufferWidth;
00568     swapchain_desc.backbuffer_height = pPresentationParameters->BackBufferHeight;
00569     swapchain_desc.backbuffer_format = wined3dformat_from_d3dformat(pPresentationParameters->BackBufferFormat);
00570     swapchain_desc.backbuffer_count = pPresentationParameters->BackBufferCount;
00571     swapchain_desc.multisample_type = pPresentationParameters->MultiSampleType;
00572     swapchain_desc.multisample_quality = pPresentationParameters->MultiSampleQuality;
00573     swapchain_desc.swap_effect = pPresentationParameters->SwapEffect;
00574     swapchain_desc.device_window = pPresentationParameters->hDeviceWindow;
00575     swapchain_desc.windowed = pPresentationParameters->Windowed;
00576     swapchain_desc.enable_auto_depth_stencil = pPresentationParameters->EnableAutoDepthStencil;
00577     swapchain_desc.auto_depth_stencil_format = wined3dformat_from_d3dformat(pPresentationParameters->AutoDepthStencilFormat);
00578     swapchain_desc.flags = pPresentationParameters->Flags;
00579     swapchain_desc.refresh_rate = pPresentationParameters->FullScreen_RefreshRateInHz;
00580     swapchain_desc.swap_interval = pPresentationParameters->PresentationInterval;
00581     swapchain_desc.auto_restore_display_mode = TRUE;
00582 
00583     hr = wined3d_device_reset(This->wined3d_device, &swapchain_desc, reset_enum_callback);
00584     if (FAILED(hr))
00585         This->notreset = TRUE;
00586     else
00587         This->notreset = FALSE;
00588 
00589     wined3d_mutex_unlock();
00590 
00591     return hr;
00592 }
00593 
00594 static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_Present(IDirect3DDevice9Ex *iface,
00595         const RECT *pSourceRect, const RECT *pDestRect, HWND hDestWindowOverride,
00596         const RGNDATA *pDirtyRegion)
00597 {
00598     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
00599     HRESULT hr;
00600 
00601     TRACE("iface %p, src_rect %p, dst_rect %p, dst_window_override %p, dirty_region %p.\n",
00602             iface, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
00603 
00604     wined3d_mutex_lock();
00605     hr = wined3d_device_present(This->wined3d_device, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
00606     wined3d_mutex_unlock();
00607 
00608     return hr;
00609  }
00610 
00611 static HRESULT WINAPI IDirect3DDevice9Impl_GetBackBuffer(IDirect3DDevice9Ex *iface,
00612         UINT iSwapChain, UINT BackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface9 **ppBackBuffer)
00613 {
00614     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
00615     struct wined3d_surface *wined3d_surface = NULL;
00616     HRESULT hr;
00617 
00618     TRACE("iface %p, swapchain %u, backbuffer_idx %u, backbuffer_type %#x, backbuffer %p.\n",
00619             iface, iSwapChain, BackBuffer, Type, ppBackBuffer);
00620 
00621     wined3d_mutex_lock();
00622     hr = wined3d_device_get_back_buffer(This->wined3d_device, iSwapChain,
00623             BackBuffer, (enum wined3d_backbuffer_type)Type, &wined3d_surface);
00624     if (SUCCEEDED(hr) && wined3d_surface && ppBackBuffer)
00625     {
00626         *ppBackBuffer = wined3d_surface_get_parent(wined3d_surface);
00627         IDirect3DSurface9_AddRef(*ppBackBuffer);
00628         wined3d_surface_decref(wined3d_surface);
00629     }
00630     wined3d_mutex_unlock();
00631 
00632     return hr;
00633 }
00634 static HRESULT WINAPI IDirect3DDevice9Impl_GetRasterStatus(IDirect3DDevice9Ex *iface,
00635         UINT iSwapChain, D3DRASTER_STATUS *pRasterStatus)
00636 {
00637     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
00638     HRESULT hr;
00639 
00640     TRACE("iface %p, swapchain %u, raster_status %p.\n", iface, iSwapChain, pRasterStatus);
00641 
00642     wined3d_mutex_lock();
00643     hr = wined3d_device_get_raster_status(This->wined3d_device,
00644             iSwapChain, (struct wined3d_raster_status *)pRasterStatus);
00645     wined3d_mutex_unlock();
00646 
00647     return hr;
00648 }
00649 
00650 static HRESULT WINAPI IDirect3DDevice9Impl_SetDialogBoxMode(IDirect3DDevice9Ex *iface,
00651         BOOL bEnableDialogs)
00652 {
00653     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
00654     HRESULT hr;
00655 
00656     TRACE("iface %p, enable %#x.\n", iface, bEnableDialogs);
00657 
00658     wined3d_mutex_lock();
00659     hr = wined3d_device_set_dialog_box_mode(This->wined3d_device, bEnableDialogs);
00660     wined3d_mutex_unlock();
00661 
00662     return hr;
00663 }
00664 
00665 static void WINAPI IDirect3DDevice9Impl_SetGammaRamp(IDirect3DDevice9Ex *iface, UINT iSwapChain,
00666         DWORD Flags, const D3DGAMMARAMP *pRamp)
00667 {
00668     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
00669 
00670     TRACE("iface %p, swapchain %u, flags %#x, ramp %p.\n", iface, iSwapChain, Flags, pRamp);
00671 
00672     /* Note: D3DGAMMARAMP is compatible with struct wined3d_gamma_ramp. */
00673     wined3d_mutex_lock();
00674     wined3d_device_set_gamma_ramp(This->wined3d_device, iSwapChain, Flags, (const struct wined3d_gamma_ramp *)pRamp);
00675     wined3d_mutex_unlock();
00676 }
00677 
00678 static void WINAPI IDirect3DDevice9Impl_GetGammaRamp(IDirect3DDevice9Ex *iface, UINT iSwapChain,
00679         D3DGAMMARAMP *pRamp)
00680 {
00681     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
00682 
00683     TRACE("iface %p, swapchain %u, ramp %p.\n", iface, iSwapChain, pRamp);
00684 
00685     /* Note: D3DGAMMARAMP is compatible with struct wined3d_gamma_ramp. */
00686     wined3d_mutex_lock();
00687     wined3d_device_get_gamma_ramp(This->wined3d_device, iSwapChain, (struct wined3d_gamma_ramp *)pRamp);
00688     wined3d_mutex_unlock();
00689 }
00690 
00691 static HRESULT WINAPI IDirect3DDevice9Impl_CreateTexture(IDirect3DDevice9Ex *iface,
00692         UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format,
00693         D3DPOOL pool, IDirect3DTexture9 **texture, HANDLE *shared_handle)
00694 {
00695     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
00696     IDirect3DTexture9Impl *object;
00697     BOOL set_mem = FALSE;
00698     HRESULT hr;
00699 
00700     TRACE("iface %p, width %u, height %u, levels %u, usage %#x, format %#x, pool %#x, texture %p, shared_handle %p.\n",
00701             iface, width, height, levels, usage, format, pool, texture, shared_handle);
00702 
00703     if (shared_handle)
00704     {
00705         if (pool == D3DPOOL_SYSTEMMEM)
00706         {
00707             if (levels != 1)
00708                 return D3DERR_INVALIDCALL;
00709             set_mem = TRUE;
00710         }
00711         else
00712             FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
00713     }
00714 
00715     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
00716     if (!object)
00717     {
00718         ERR("Failed to allocate texture memory.\n");
00719         return D3DERR_OUTOFVIDEOMEMORY;
00720     }
00721 
00722     hr = texture_init(object, This, width, height, levels, usage, format, pool);
00723     if (FAILED(hr))
00724     {
00725         WARN("Failed to initialize texture, hr %#x.\n", hr);
00726         HeapFree(GetProcessHeap(), 0, object);
00727         return hr;
00728     }
00729 
00730     if (set_mem)
00731     {
00732         struct wined3d_resource *resource;
00733         IDirect3DSurface9Impl *surface;
00734 
00735         resource = wined3d_texture_get_sub_resource(object->wined3d_texture, 0);
00736         surface = wined3d_resource_get_parent(resource);
00737         wined3d_surface_set_mem(surface->wined3d_surface, *shared_handle);
00738     }
00739 
00740     TRACE("Created texture %p.\n", object);
00741     *texture = &object->IDirect3DTexture9_iface;
00742 
00743     return D3D_OK;
00744 }
00745 
00746 static HRESULT WINAPI IDirect3DDevice9Impl_CreateVolumeTexture(IDirect3DDevice9Ex *iface,
00747         UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format,
00748         D3DPOOL pool, IDirect3DVolumeTexture9 **texture, HANDLE *shared_handle)
00749 {
00750     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
00751     IDirect3DVolumeTexture9Impl *object;
00752     HRESULT hr;
00753 
00754     TRACE("iface %p, width %u, height %u, depth %u, levels %u\n",
00755             iface, width, height, depth, levels);
00756     TRACE("usage %#x, format %#x, pool %#x, texture %p, shared_handle %p.\n",
00757             usage, format, pool, texture, shared_handle);
00758 
00759     if (shared_handle)
00760         FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
00761 
00762     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
00763     if (!object)
00764     {
00765         ERR("Failed to allocate volume texture memory.\n");
00766         return D3DERR_OUTOFVIDEOMEMORY;
00767     }
00768 
00769     hr = volumetexture_init(object, This, width, height, depth, levels, usage, format, pool);
00770     if (FAILED(hr))
00771     {
00772         WARN("Failed to initialize volume texture, hr %#x.\n", hr);
00773         HeapFree(GetProcessHeap(), 0, object);
00774         return hr;
00775     }
00776 
00777     TRACE("Created volume texture %p.\n", object);
00778     *texture = &object->IDirect3DVolumeTexture9_iface;
00779 
00780     return D3D_OK;
00781 }
00782 
00783 static HRESULT WINAPI IDirect3DDevice9Impl_CreateCubeTexture(IDirect3DDevice9Ex *iface,
00784         UINT edge_length, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool,
00785         IDirect3DCubeTexture9 **texture, HANDLE *shared_handle)
00786 {
00787     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
00788     IDirect3DCubeTexture9Impl *object;
00789     HRESULT hr;
00790 
00791     TRACE("iface %p, edge_length %u, levels %u, usage %#x, format %#x, pool %#x, texture %p, shared_handle %p.\n",
00792             iface, edge_length, levels, usage, format, pool, texture, shared_handle);
00793 
00794     if (shared_handle)
00795         FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
00796 
00797     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
00798     if (!object)
00799     {
00800         ERR("Failed to allocate cube texture memory.\n");
00801         return D3DERR_OUTOFVIDEOMEMORY;
00802     }
00803 
00804     hr = cubetexture_init(object, This, edge_length, levels, usage, format, pool);
00805     if (FAILED(hr))
00806     {
00807         WARN("Failed to initialize cube texture, hr %#x.\n", hr);
00808         HeapFree(GetProcessHeap(), 0, object);
00809         return hr;
00810     }
00811 
00812     TRACE("Created cube texture %p.\n", object);
00813     *texture = &object->IDirect3DCubeTexture9_iface;
00814 
00815     return D3D_OK;
00816 }
00817 
00818 static HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexBuffer(IDirect3DDevice9Ex *iface, UINT size,
00819         DWORD usage, DWORD fvf, D3DPOOL pool, IDirect3DVertexBuffer9 **buffer,
00820         HANDLE *shared_handle)
00821 {
00822     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
00823     IDirect3DVertexBuffer9Impl *object;
00824     HRESULT hr;
00825 
00826     TRACE("iface %p, size %u, usage %#x, fvf %#x, pool %#x, buffer %p, shared_handle %p.\n",
00827             iface, size, usage, fvf, pool, buffer, shared_handle);
00828 
00829     if (shared_handle)
00830         FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
00831 
00832     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
00833     if (!object)
00834     {
00835         ERR("Failed to allocate buffer memory.\n");
00836         return D3DERR_OUTOFVIDEOMEMORY;
00837     }
00838 
00839     hr = vertexbuffer_init(object, This, size, usage, fvf, pool);
00840     if (FAILED(hr))
00841     {
00842         WARN("Failed to initialize vertex buffer, hr %#x.\n", hr);
00843         HeapFree(GetProcessHeap(), 0, object);
00844         return hr;
00845     }
00846 
00847     TRACE("Created vertex buffer %p.\n", object);
00848     *buffer = &object->IDirect3DVertexBuffer9_iface;
00849 
00850     return D3D_OK;
00851 }
00852 
00853 static HRESULT WINAPI IDirect3DDevice9Impl_CreateIndexBuffer(IDirect3DDevice9Ex *iface, UINT size,
00854         DWORD usage, D3DFORMAT format, D3DPOOL pool, IDirect3DIndexBuffer9 **buffer,
00855         HANDLE *shared_handle)
00856 {
00857     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
00858     IDirect3DIndexBuffer9Impl *object;
00859     HRESULT hr;
00860 
00861     TRACE("iface %p, size %u, usage %#x, format %#x, pool %#x, buffer %p, shared_handle %p.\n",
00862             iface, size, usage, format, pool, buffer, shared_handle);
00863 
00864     if (shared_handle)
00865         FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
00866 
00867     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
00868     if (!object)
00869     {
00870         ERR("Failed to allocate buffer memory.\n");
00871         return D3DERR_OUTOFVIDEOMEMORY;
00872     }
00873 
00874     hr = indexbuffer_init(object, This, size, usage, format, pool);
00875     if (FAILED(hr))
00876     {
00877         WARN("Failed to initialize index buffer, hr %#x.\n", hr);
00878         HeapFree(GetProcessHeap(), 0, object);
00879         return hr;
00880     }
00881 
00882     TRACE("Created index buffer %p.\n", object);
00883     *buffer = &object->IDirect3DIndexBuffer9_iface;
00884 
00885     return D3D_OK;
00886 }
00887 
00888 static HRESULT IDirect3DDevice9Impl_CreateSurface(IDirect3DDevice9Impl *device, UINT Width,
00889         UINT Height, D3DFORMAT Format, BOOL Lockable, BOOL Discard, UINT Level,
00890         IDirect3DSurface9 **ppSurface, UINT Usage, D3DPOOL Pool, D3DMULTISAMPLE_TYPE MultiSample,
00891         DWORD MultisampleQuality)
00892 {
00893     IDirect3DSurface9Impl *object;
00894     HRESULT hr;
00895 
00896     TRACE("device %p, width %u, height %u, format %#x, lockable %#x, discard %#x, level %u, surface %p.\n"
00897             "usage %#x, pool %#x, multisample_type %#x, multisample_quality %u.\n",
00898             device, Width, Height, Format, Lockable, Discard, Level, ppSurface, Usage, Pool,
00899             MultiSample, MultisampleQuality);
00900 
00901     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface9Impl));
00902     if (!object)
00903     {
00904         FIXME("Failed to allocate surface memory.\n");
00905         return D3DERR_OUTOFVIDEOMEMORY;
00906     }
00907 
00908     hr = surface_init(object, device, Width, Height, Format, Lockable, Discard, Level, Usage, Pool,
00909             MultiSample, MultisampleQuality);
00910     if (FAILED(hr))
00911     {
00912         WARN("Failed to initialize surface, hr %#x.\n", hr);
00913         HeapFree(GetProcessHeap(), 0, object);
00914         return hr;
00915     }
00916 
00917     TRACE("Created surface %p.\n", object);
00918     *ppSurface = &object->IDirect3DSurface9_iface;
00919 
00920     return D3D_OK;
00921 }
00922 
00923 static HRESULT WINAPI IDirect3DDevice9Impl_CreateRenderTarget(IDirect3DDevice9Ex *iface, UINT Width,
00924         UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality,
00925         BOOL Lockable, IDirect3DSurface9 **ppSurface, HANDLE *shared_handle)
00926 {
00927     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
00928     HRESULT hr;
00929 
00930     TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u.\n"
00931             "lockable %#x, surface %p, shared_handle %p.\n",
00932             iface, Width, Height, Format, MultiSample, MultisampleQuality,
00933             Lockable, ppSurface, shared_handle);
00934 
00935     if (shared_handle)
00936         FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
00937 
00938     hr = IDirect3DDevice9Impl_CreateSurface(This, Width, Height, Format, Lockable,
00939             FALSE /* Discard */, 0 /* Level */, ppSurface, D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT,
00940             MultiSample, MultisampleQuality);
00941 
00942     return hr;
00943 }
00944 
00945 static HRESULT WINAPI IDirect3DDevice9Impl_CreateDepthStencilSurface(IDirect3DDevice9Ex *iface,
00946         UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample,
00947         DWORD MultisampleQuality, BOOL Discard, IDirect3DSurface9 **ppSurface,
00948         HANDLE *shared_handle)
00949 {
00950     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
00951     HRESULT hr;
00952 
00953     TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u.\n"
00954             "discard %#x, surface %p, shared_handle %p.\n",
00955             iface, Width, Height, Format, MultiSample, MultisampleQuality,
00956             Discard, ppSurface, shared_handle);
00957 
00958     if (shared_handle)
00959         FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
00960 
00961     hr = IDirect3DDevice9Impl_CreateSurface(This, Width, Height, Format, TRUE /* Lockable */,
00962             Discard, 0 /* Level */, ppSurface, D3DUSAGE_DEPTHSTENCIL, D3DPOOL_DEFAULT, MultiSample,
00963             MultisampleQuality);
00964 
00965     return hr;
00966 }
00967 
00968 
00969 static HRESULT WINAPI IDirect3DDevice9Impl_UpdateSurface(IDirect3DDevice9Ex *iface,
00970         IDirect3DSurface9 *pSourceSurface, const RECT *pSourceRect,
00971         IDirect3DSurface9 *pDestinationSurface, const POINT *pDestPoint)
00972 {
00973     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
00974     IDirect3DSurface9Impl *src = unsafe_impl_from_IDirect3DSurface9(pSourceSurface);
00975     IDirect3DSurface9Impl *dst = unsafe_impl_from_IDirect3DSurface9(pDestinationSurface);
00976     HRESULT hr;
00977 
00978     TRACE("iface %p, src_surface %p, src_rect %p, dst_surface %p, dst_point %p.\n",
00979             iface, pSourceSurface, pSourceRect, pDestinationSurface, pDestPoint);
00980 
00981     wined3d_mutex_lock();
00982     hr = wined3d_device_update_surface(This->wined3d_device, src->wined3d_surface, pSourceRect,
00983             dst->wined3d_surface, pDestPoint);
00984     wined3d_mutex_unlock();
00985 
00986     return hr;
00987 }
00988 
00989 static HRESULT WINAPI IDirect3DDevice9Impl_UpdateTexture(IDirect3DDevice9Ex *iface,
00990         IDirect3DBaseTexture9 *src_texture, IDirect3DBaseTexture9 *dst_texture)
00991 {
00992     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
00993     HRESULT hr;
00994 
00995     TRACE("iface %p, src_texture %p, dst_texture %p.\n", iface, src_texture, dst_texture);
00996 
00997     wined3d_mutex_lock();
00998     hr = wined3d_device_update_texture(This->wined3d_device,
00999             ((IDirect3DBaseTexture9Impl *)src_texture)->wined3d_texture,
01000             ((IDirect3DBaseTexture9Impl *)dst_texture)->wined3d_texture);
01001     wined3d_mutex_unlock();
01002 
01003     return hr;
01004 }
01005 
01006 static HRESULT WINAPI IDirect3DDevice9Impl_GetRenderTargetData(IDirect3DDevice9Ex *iface,
01007         IDirect3DSurface9 *pRenderTarget, IDirect3DSurface9 *pDestSurface)
01008 {
01009     IDirect3DSurface9Impl *renderTarget = unsafe_impl_from_IDirect3DSurface9(pRenderTarget);
01010     IDirect3DSurface9Impl *destSurface = unsafe_impl_from_IDirect3DSurface9(pDestSurface);
01011     HRESULT hr;
01012 
01013     TRACE("iface %p, render_target %p, dst_surface %p.\n", iface, pRenderTarget, pDestSurface);
01014 
01015     wined3d_mutex_lock();
01016     hr = wined3d_surface_get_render_target_data(destSurface->wined3d_surface, renderTarget->wined3d_surface);
01017     wined3d_mutex_unlock();
01018 
01019     return hr;
01020 }
01021 
01022 static HRESULT WINAPI IDirect3DDevice9Impl_GetFrontBufferData(IDirect3DDevice9Ex *iface,
01023         UINT iSwapChain, IDirect3DSurface9 *pDestSurface)
01024 {
01025     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01026     IDirect3DSurface9Impl *destSurface = unsafe_impl_from_IDirect3DSurface9(pDestSurface);
01027     HRESULT hr;
01028 
01029     TRACE("iface %p, swapchain %u, dst_surface %p.\n", iface, iSwapChain, pDestSurface);
01030 
01031     wined3d_mutex_lock();
01032     hr = wined3d_device_get_front_buffer_data(This->wined3d_device, iSwapChain, destSurface->wined3d_surface);
01033     wined3d_mutex_unlock();
01034 
01035     return hr;
01036 }
01037 
01038 static HRESULT WINAPI IDirect3DDevice9Impl_StretchRect(IDirect3DDevice9Ex *iface, IDirect3DSurface9 *pSourceSurface,
01039         const RECT *pSourceRect, IDirect3DSurface9 *pDestSurface, const RECT *pDestRect, D3DTEXTUREFILTERTYPE Filter)
01040 {
01041     IDirect3DSurface9Impl *src = unsafe_impl_from_IDirect3DSurface9(pSourceSurface);
01042     IDirect3DSurface9Impl *dst = unsafe_impl_from_IDirect3DSurface9(pDestSurface);
01043     HRESULT hr;
01044 
01045     TRACE("iface %p, src_surface %p, src_rect %p, dst_surface %p, dst_rect %p, filter %#x.\n",
01046             iface, pSourceSurface, pSourceRect, pDestSurface, pDestRect, Filter);
01047 
01048     wined3d_mutex_lock();
01049     hr = wined3d_surface_blt(dst->wined3d_surface, pDestRect, src->wined3d_surface, pSourceRect, 0, NULL, Filter);
01050     if (hr == WINEDDERR_INVALIDRECT)
01051         hr = D3DERR_INVALIDCALL;
01052     wined3d_mutex_unlock();
01053 
01054     return hr;
01055 }
01056 
01057 static HRESULT WINAPI IDirect3DDevice9Impl_ColorFill(IDirect3DDevice9Ex *iface,
01058         IDirect3DSurface9 *pSurface, const RECT *pRect, D3DCOLOR color)
01059 {
01060     const struct wined3d_color c =
01061     {
01062         ((color >> 16) & 0xff) / 255.0f,
01063         ((color >>  8) & 0xff) / 255.0f,
01064         (color & 0xff) / 255.0f,
01065         ((color >> 24) & 0xff) / 255.0f,
01066     };
01067     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01068     IDirect3DSurface9Impl *surface = unsafe_impl_from_IDirect3DSurface9(pSurface);
01069     struct wined3d_resource *wined3d_resource;
01070     struct wined3d_resource_desc desc;
01071     HRESULT hr;
01072 
01073     TRACE("iface %p, surface %p, rect %p, color 0x%08x.\n", iface, pSurface, pRect, color);
01074 
01075     wined3d_mutex_lock();
01076 
01077     wined3d_resource = wined3d_surface_get_resource(surface->wined3d_surface);
01078     wined3d_resource_get_desc(wined3d_resource, &desc);
01079 
01080     /* This method is only allowed with surfaces that are render targets, or
01081      * offscreen plain surfaces in D3DPOOL_DEFAULT. */
01082     if (!(desc.usage & WINED3DUSAGE_RENDERTARGET) && desc.pool != WINED3D_POOL_DEFAULT)
01083     {
01084         wined3d_mutex_unlock();
01085         WARN("Surface is not a render target, or not a stand-alone D3DPOOL_DEFAULT surface\n");
01086         return D3DERR_INVALIDCALL;
01087     }
01088 
01089     /* Colorfill can only be used on rendertarget surfaces, or offscreen plain surfaces in D3DPOOL_DEFAULT */
01090     hr = wined3d_device_color_fill(This->wined3d_device, surface->wined3d_surface, pRect, &c);
01091 
01092     wined3d_mutex_unlock();
01093 
01094     return hr;
01095 }
01096 
01097 static HRESULT  WINAPI  IDirect3DDevice9Impl_CreateOffscreenPlainSurface(IDirect3DDevice9Ex *iface,
01098         UINT Width, UINT Height, D3DFORMAT Format, D3DPOOL Pool, IDirect3DSurface9 **ppSurface,
01099         HANDLE *shared_handle)
01100 {
01101     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01102     HRESULT hr;
01103 
01104     TRACE("iface %p, width %u, height %u, format %#x, pool %#x, surface %p, shared_handle %p.\n",
01105             iface, Width, Height, Format, Pool, ppSurface, shared_handle);
01106 
01107     if (shared_handle)
01108         FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
01109 
01110     if (Pool == D3DPOOL_MANAGED)
01111     {
01112         FIXME("Attempting to create a managed offscreen plain surface\n");
01113         return D3DERR_INVALIDCALL;
01114     }
01115         /*
01116         'Off-screen plain surfaces are always lockable, regardless of their pool types.'
01117         but then...
01118         D3DPOOL_DEFAULT is the appropriate pool for use with the IDirect3DDevice9::StretchRect and IDirect3DDevice9::ColorFill.
01119         Why, their always lockable?
01120         should I change the usage to dynamic?
01121         */
01122     hr = IDirect3DDevice9Impl_CreateSurface(This, Width, Height, Format, TRUE /* Lockable */,
01123             FALSE /* Discard */, 0 /* Level */, ppSurface, 0 /* Usage (undefined/none) */,
01124             Pool, D3DMULTISAMPLE_NONE, 0 /* MultisampleQuality */);
01125 
01126     return hr;
01127 }
01128 
01129 /* TODO: move to wineD3D */
01130 static HRESULT WINAPI IDirect3DDevice9Impl_SetRenderTarget(IDirect3DDevice9Ex *iface,
01131         DWORD RenderTargetIndex, IDirect3DSurface9 *pRenderTarget)
01132 {
01133     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01134     IDirect3DSurface9Impl *pSurface = unsafe_impl_from_IDirect3DSurface9(pRenderTarget);
01135     HRESULT hr;
01136 
01137     TRACE("iface %p, idx %u, surface %p.\n", iface, RenderTargetIndex, pRenderTarget);
01138 
01139     if (RenderTargetIndex >= D3D9_MAX_SIMULTANEOUS_RENDERTARGETS)
01140     {
01141         WARN("Invalid index %u specified.\n", RenderTargetIndex);
01142         return D3DERR_INVALIDCALL;
01143     }
01144 
01145     wined3d_mutex_lock();
01146     hr = wined3d_device_set_render_target(This->wined3d_device, RenderTargetIndex,
01147             pSurface ? pSurface->wined3d_surface : NULL, TRUE);
01148     wined3d_mutex_unlock();
01149 
01150     return hr;
01151 }
01152 
01153 static HRESULT WINAPI IDirect3DDevice9Impl_GetRenderTarget(IDirect3DDevice9Ex *iface,
01154         DWORD RenderTargetIndex, IDirect3DSurface9 **ppRenderTarget)
01155 {
01156     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01157     struct wined3d_surface *wined3d_surface;
01158     HRESULT hr;
01159 
01160     TRACE("iface %p, idx %u, surface %p.\n", iface, RenderTargetIndex, ppRenderTarget);
01161 
01162     if (ppRenderTarget == NULL) {
01163         return D3DERR_INVALIDCALL;
01164     }
01165 
01166     if (RenderTargetIndex >= D3D9_MAX_SIMULTANEOUS_RENDERTARGETS)
01167     {
01168         WARN("Invalid index %u specified.\n", RenderTargetIndex);
01169         return D3DERR_INVALIDCALL;
01170     }
01171 
01172     wined3d_mutex_lock();
01173     hr = wined3d_device_get_render_target(This->wined3d_device, RenderTargetIndex, &wined3d_surface);
01174     if (SUCCEEDED(hr))
01175     {
01176         *ppRenderTarget = wined3d_surface_get_parent(wined3d_surface);
01177         IDirect3DSurface9_AddRef(*ppRenderTarget);
01178         wined3d_surface_decref(wined3d_surface);
01179     }
01180     else
01181     {
01182         if (hr != WINED3DERR_NOTFOUND)
01183             WARN("Failed to get render target %u, hr %#x.\n", RenderTargetIndex, hr);
01184         *ppRenderTarget = NULL;
01185     }
01186     wined3d_mutex_unlock();
01187 
01188     return hr;
01189 }
01190 
01191 static HRESULT WINAPI IDirect3DDevice9Impl_SetDepthStencilSurface(IDirect3DDevice9Ex *iface,
01192         IDirect3DSurface9 *pZStencilSurface)
01193 {
01194     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01195     IDirect3DSurface9Impl *pSurface = unsafe_impl_from_IDirect3DSurface9(pZStencilSurface);
01196     HRESULT hr;
01197 
01198     TRACE("iface %p, depth_stencil %p.\n", iface, pZStencilSurface);
01199 
01200     wined3d_mutex_lock();
01201     hr = wined3d_device_set_depth_stencil(This->wined3d_device, pSurface ? pSurface->wined3d_surface : NULL);
01202     wined3d_mutex_unlock();
01203 
01204     return hr;
01205 }
01206 
01207 static HRESULT WINAPI IDirect3DDevice9Impl_GetDepthStencilSurface(IDirect3DDevice9Ex *iface,
01208         IDirect3DSurface9 **ppZStencilSurface)
01209 {
01210     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01211     struct wined3d_surface *wined3d_surface;
01212     HRESULT hr;
01213 
01214     TRACE("iface %p, depth_stencil %p.\n", iface, ppZStencilSurface);
01215 
01216     if(ppZStencilSurface == NULL){
01217         return D3DERR_INVALIDCALL;
01218     }
01219 
01220     wined3d_mutex_lock();
01221     hr = wined3d_device_get_depth_stencil(This->wined3d_device, &wined3d_surface);
01222     if (SUCCEEDED(hr))
01223     {
01224         *ppZStencilSurface = wined3d_surface_get_parent(wined3d_surface);
01225         IDirect3DSurface9_AddRef(*ppZStencilSurface);
01226         wined3d_surface_decref(wined3d_surface);
01227     }
01228     else
01229     {
01230         if (hr != WINED3DERR_NOTFOUND)
01231                 WARN("Call to IWineD3DDevice_GetDepthStencilSurface failed with 0x%08x\n", hr);
01232         *ppZStencilSurface = NULL;
01233     }
01234     wined3d_mutex_unlock();
01235 
01236     return hr;
01237 }
01238 
01239 static HRESULT WINAPI IDirect3DDevice9Impl_BeginScene(IDirect3DDevice9Ex *iface)
01240 {
01241     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01242     HRESULT hr;
01243 
01244     TRACE("iface %p.\n", iface);
01245 
01246     wined3d_mutex_lock();
01247     hr = wined3d_device_begin_scene(This->wined3d_device);
01248     wined3d_mutex_unlock();
01249 
01250     return hr;
01251 }
01252 
01253 static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_EndScene(IDirect3DDevice9Ex *iface)
01254 {
01255     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01256     HRESULT hr;
01257 
01258     TRACE("iface %p.\n", iface);
01259 
01260     wined3d_mutex_lock();
01261     hr = wined3d_device_end_scene(This->wined3d_device);
01262     wined3d_mutex_unlock();
01263 
01264     return hr;
01265 }
01266 
01267 static HRESULT WINAPI IDirect3DDevice9Impl_Clear(IDirect3DDevice9Ex *iface, DWORD rect_count,
01268         const D3DRECT *rects, DWORD flags, D3DCOLOR color, float z, DWORD stencil)
01269 {
01270     const struct wined3d_color c =
01271     {
01272         ((color >> 16) & 0xff) / 255.0f,
01273         ((color >>  8) & 0xff) / 255.0f,
01274         (color & 0xff) / 255.0f,
01275         ((color >> 24) & 0xff) / 255.0f,
01276     };
01277     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01278     HRESULT hr;
01279 
01280     TRACE("iface %p, rect_count %u, rects %p, flags %#x, color 0x%08x, z %.8e, stencil %u.\n",
01281             iface, rect_count, rects, flags, color, z, stencil);
01282 
01283     wined3d_mutex_lock();
01284     hr = wined3d_device_clear(This->wined3d_device, rect_count, (const RECT *)rects, flags, &c, z, stencil);
01285     wined3d_mutex_unlock();
01286 
01287     return hr;
01288 }
01289 
01290 static HRESULT WINAPI IDirect3DDevice9Impl_SetTransform(IDirect3DDevice9Ex *iface,
01291         D3DTRANSFORMSTATETYPE State, const D3DMATRIX *lpMatrix)
01292 {
01293     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01294     HRESULT hr;
01295 
01296     TRACE("iface %p, state %#x, matrix %p.\n", iface, State, lpMatrix);
01297 
01298     /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
01299     wined3d_mutex_lock();
01300     hr = wined3d_device_set_transform(This->wined3d_device, State, (const struct wined3d_matrix *)lpMatrix);
01301     wined3d_mutex_unlock();
01302 
01303     return hr;
01304 }
01305 
01306 static HRESULT WINAPI IDirect3DDevice9Impl_GetTransform(IDirect3DDevice9Ex *iface,
01307         D3DTRANSFORMSTATETYPE State, D3DMATRIX *pMatrix)
01308 {
01309     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01310     HRESULT hr;
01311 
01312     TRACE("iface %p, state %#x, matrix %p.\n", iface, State, pMatrix);
01313 
01314     /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
01315     wined3d_mutex_lock();
01316     hr = wined3d_device_get_transform(This->wined3d_device, State, (struct wined3d_matrix *)pMatrix);
01317     wined3d_mutex_unlock();
01318 
01319     return hr;
01320 }
01321 
01322 static HRESULT WINAPI IDirect3DDevice9Impl_MultiplyTransform(IDirect3DDevice9Ex *iface,
01323         D3DTRANSFORMSTATETYPE State, const D3DMATRIX *pMatrix)
01324 {
01325     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01326     HRESULT hr;
01327 
01328     TRACE("iface %p, state %#x, matrix %p.\n", iface, State, pMatrix);
01329 
01330     /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
01331     wined3d_mutex_lock();
01332     hr = wined3d_device_multiply_transform(This->wined3d_device, State, (const struct wined3d_matrix *)pMatrix);
01333     wined3d_mutex_unlock();
01334 
01335     return hr;
01336 }
01337 
01338 static HRESULT WINAPI IDirect3DDevice9Impl_SetViewport(IDirect3DDevice9Ex *iface,
01339         const D3DVIEWPORT9 *pViewport)
01340 {
01341     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01342     HRESULT hr;
01343 
01344     TRACE("iface %p, viewport %p.\n", iface, pViewport);
01345 
01346     /* Note: D3DVIEWPORT9 is compatible with struct wined3d_viewport. */
01347     wined3d_mutex_lock();
01348     hr = wined3d_device_set_viewport(This->wined3d_device, (const struct wined3d_viewport *)pViewport);
01349     wined3d_mutex_unlock();
01350 
01351     return hr;
01352 }
01353 
01354 static HRESULT WINAPI IDirect3DDevice9Impl_GetViewport(IDirect3DDevice9Ex *iface,
01355         D3DVIEWPORT9 *pViewport)
01356 {
01357     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01358     HRESULT hr;
01359 
01360     TRACE("iface %p, viewport %p.\n", iface, pViewport);
01361 
01362     /* Note: D3DVIEWPORT9 is compatible with struct wined3d_viewport. */
01363     wined3d_mutex_lock();
01364     hr = wined3d_device_get_viewport(This->wined3d_device, (struct wined3d_viewport *)pViewport);
01365     wined3d_mutex_unlock();
01366 
01367     return hr;
01368 }
01369 
01370 static HRESULT WINAPI IDirect3DDevice9Impl_SetMaterial(IDirect3DDevice9Ex *iface,
01371         const D3DMATERIAL9 *pMaterial)
01372 {
01373     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01374     HRESULT hr;
01375 
01376     TRACE("iface %p, material %p.\n", iface, pMaterial);
01377 
01378     /* Note: D3DMATERIAL9 is compatible with struct wined3d_material. */
01379     wined3d_mutex_lock();
01380     hr = wined3d_device_set_material(This->wined3d_device, (const struct wined3d_material *)pMaterial);
01381     wined3d_mutex_unlock();
01382 
01383     return hr;
01384 }
01385 
01386 static HRESULT WINAPI IDirect3DDevice9Impl_GetMaterial(IDirect3DDevice9Ex *iface,
01387         D3DMATERIAL9 *pMaterial)
01388 {
01389     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01390     HRESULT hr;
01391 
01392     TRACE("iface %p, material %p.\n", iface, pMaterial);
01393 
01394     /* Note: D3DMATERIAL9 is compatible with struct wined3d_material. */
01395     wined3d_mutex_lock();
01396     hr = wined3d_device_get_material(This->wined3d_device, (struct wined3d_material *)pMaterial);
01397     wined3d_mutex_unlock();
01398 
01399     return hr;
01400 }
01401 
01402 static HRESULT WINAPI IDirect3DDevice9Impl_SetLight(IDirect3DDevice9Ex *iface, DWORD Index,
01403         const D3DLIGHT9 *pLight)
01404 {
01405     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01406     HRESULT hr;
01407 
01408     TRACE("iface %p, index %u, light %p.\n", iface, Index, pLight);
01409 
01410     /* Note: D3DLIGHT9 is compatible with struct wined3d_light. */
01411     wined3d_mutex_lock();
01412     hr = wined3d_device_set_light(This->wined3d_device, Index, (const struct wined3d_light *)pLight);
01413     wined3d_mutex_unlock();
01414 
01415     return hr;
01416 }
01417 
01418 static HRESULT WINAPI IDirect3DDevice9Impl_GetLight(IDirect3DDevice9Ex *iface, DWORD Index,
01419         D3DLIGHT9 *pLight)
01420 {
01421     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01422     HRESULT hr;
01423 
01424     TRACE("iface %p, index %u, light %p.\n", iface, Index, pLight);
01425 
01426     /* Note: D3DLIGHT9 is compatible with struct wined3d_light. */
01427     wined3d_mutex_lock();
01428     hr = wined3d_device_get_light(This->wined3d_device, Index, (struct wined3d_light *)pLight);
01429     wined3d_mutex_unlock();
01430 
01431     return hr;
01432 }
01433 
01434 static HRESULT WINAPI IDirect3DDevice9Impl_LightEnable(IDirect3DDevice9Ex *iface, DWORD Index,
01435         BOOL Enable)
01436 {
01437     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01438     HRESULT hr;
01439 
01440     TRACE("iface %p, index %u, enable %#x.\n", iface, Index, Enable);
01441 
01442     wined3d_mutex_lock();
01443     hr = wined3d_device_set_light_enable(This->wined3d_device, Index, Enable);
01444     wined3d_mutex_unlock();
01445 
01446     return hr;
01447 }
01448 
01449 static HRESULT WINAPI IDirect3DDevice9Impl_GetLightEnable(IDirect3DDevice9Ex *iface, DWORD Index,
01450         BOOL *pEnable)
01451 {
01452     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01453     HRESULT hr;
01454 
01455     TRACE("iface %p, index %u, enable %p.\n", iface, Index, pEnable);
01456 
01457     wined3d_mutex_lock();
01458     hr = wined3d_device_get_light_enable(This->wined3d_device, Index, pEnable);
01459     wined3d_mutex_unlock();
01460 
01461     return hr;
01462 }
01463 
01464 static HRESULT WINAPI IDirect3DDevice9Impl_SetClipPlane(IDirect3DDevice9Ex *iface, DWORD Index,
01465         const float *pPlane)
01466 {
01467     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01468     HRESULT hr;
01469 
01470     TRACE("iface %p, index %u, plane %p.\n", iface, Index, pPlane);
01471 
01472     wined3d_mutex_lock();
01473     hr = wined3d_device_set_clip_plane(This->wined3d_device, Index, pPlane);
01474     wined3d_mutex_unlock();
01475 
01476     return hr;
01477 }
01478 
01479 static HRESULT WINAPI IDirect3DDevice9Impl_GetClipPlane(IDirect3DDevice9Ex *iface, DWORD Index,
01480         float *pPlane)
01481 {
01482     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01483     HRESULT hr;
01484 
01485     TRACE("iface %p, index %u, plane %p.\n", iface, Index, pPlane);
01486 
01487     wined3d_mutex_lock();
01488     hr = wined3d_device_get_clip_plane(This->wined3d_device, Index, pPlane);
01489     wined3d_mutex_unlock();
01490 
01491     return hr;
01492 }
01493 
01494 static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_SetRenderState(IDirect3DDevice9Ex *iface,
01495         D3DRENDERSTATETYPE State, DWORD Value)
01496 {
01497     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01498     HRESULT hr;
01499 
01500     TRACE("iface %p, state %#x, value %#x.\n", iface, State, Value);
01501 
01502     wined3d_mutex_lock();
01503     hr = wined3d_device_set_render_state(This->wined3d_device, State, Value);
01504     wined3d_mutex_unlock();
01505 
01506     return hr;
01507 }
01508 
01509 static HRESULT WINAPI IDirect3DDevice9Impl_GetRenderState(IDirect3DDevice9Ex *iface,
01510         D3DRENDERSTATETYPE State, DWORD *pValue)
01511 {
01512     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01513     HRESULT hr;
01514 
01515     TRACE("iface %p, state %#x, value %p.\n", iface, State, pValue);
01516 
01517     wined3d_mutex_lock();
01518     hr = wined3d_device_get_render_state(This->wined3d_device, State, pValue);
01519     wined3d_mutex_unlock();
01520 
01521     return hr;
01522 }
01523 
01524 static HRESULT WINAPI IDirect3DDevice9Impl_CreateStateBlock(IDirect3DDevice9Ex *iface,
01525         D3DSTATEBLOCKTYPE type, IDirect3DStateBlock9 **stateblock)
01526 {
01527     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01528     IDirect3DStateBlock9Impl *object;
01529     HRESULT hr;
01530 
01531     TRACE("iface %p, type %#x, stateblock %p.\n", iface, type, stateblock);
01532 
01533     if (type != D3DSBT_ALL && type != D3DSBT_PIXELSTATE && type != D3DSBT_VERTEXSTATE)
01534     {
01535         WARN("Unexpected stateblock type, returning D3DERR_INVALIDCALL.\n");
01536         return D3DERR_INVALIDCALL;
01537     }
01538 
01539     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
01540     if (!object)
01541     {
01542         ERR("Failed to allocate stateblock memory.\n");
01543         return E_OUTOFMEMORY;
01544     }
01545 
01546     hr = stateblock_init(object, This, type, NULL);
01547     if (FAILED(hr))
01548     {
01549         WARN("Failed to initialize stateblock, hr %#x.\n", hr);
01550         HeapFree(GetProcessHeap(), 0, object);
01551         return hr;
01552     }
01553 
01554     TRACE("Created stateblock %p.\n", object);
01555     *stateblock = &object->IDirect3DStateBlock9_iface;
01556 
01557     return D3D_OK;
01558 }
01559 
01560 static HRESULT WINAPI IDirect3DDevice9Impl_BeginStateBlock(IDirect3DDevice9Ex *iface)
01561 {
01562     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01563     HRESULT hr;
01564 
01565     TRACE("iface %p.\n", iface);
01566 
01567     wined3d_mutex_lock();
01568     hr = wined3d_device_begin_stateblock(This->wined3d_device);
01569     wined3d_mutex_unlock();
01570 
01571     return hr;
01572 }
01573 
01574 static HRESULT WINAPI IDirect3DDevice9Impl_EndStateBlock(IDirect3DDevice9Ex *iface,
01575         IDirect3DStateBlock9 **stateblock)
01576 {
01577     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01578     struct wined3d_stateblock *wined3d_stateblock;
01579     IDirect3DStateBlock9Impl *object;
01580     HRESULT hr;
01581 
01582     TRACE("iface %p, stateblock %p.\n", iface, stateblock);
01583 
01584     wined3d_mutex_lock();
01585     hr = wined3d_device_end_stateblock(This->wined3d_device, &wined3d_stateblock);
01586     wined3d_mutex_unlock();
01587     if (FAILED(hr))
01588     {
01589        WARN("IWineD3DDevice_EndStateBlock() failed, hr %#x.\n", hr);
01590        return hr;
01591     }
01592 
01593     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
01594     if (!object)
01595     {
01596         ERR("Failed to allocate stateblock memory.\n");
01597         wined3d_mutex_lock();
01598         wined3d_stateblock_decref(wined3d_stateblock);
01599         wined3d_mutex_unlock();
01600         return E_OUTOFMEMORY;
01601     }
01602 
01603     hr = stateblock_init(object, This, 0, wined3d_stateblock);
01604     if (FAILED(hr))
01605     {
01606         WARN("Failed to initialize stateblock, hr %#x.\n", hr);
01607         wined3d_mutex_lock();
01608         wined3d_stateblock_decref(wined3d_stateblock);
01609         wined3d_mutex_unlock();
01610         HeapFree(GetProcessHeap(), 0, object);
01611         return hr;
01612     }
01613 
01614     TRACE("Created stateblock %p.\n", object);
01615     *stateblock = &object->IDirect3DStateBlock9_iface;
01616 
01617     return D3D_OK;
01618 }
01619 
01620 static HRESULT WINAPI IDirect3DDevice9Impl_SetClipStatus(IDirect3DDevice9Ex *iface,
01621         const D3DCLIPSTATUS9 *pClipStatus)
01622 {
01623     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01624     HRESULT hr;
01625 
01626     TRACE("iface %p, clip_status %p.\n", iface, pClipStatus);
01627 
01628     wined3d_mutex_lock();
01629     hr = wined3d_device_set_clip_status(This->wined3d_device, (const struct wined3d_clip_status *)pClipStatus);
01630     wined3d_mutex_unlock();
01631 
01632     return hr;
01633 }
01634 
01635 static HRESULT WINAPI IDirect3DDevice9Impl_GetClipStatus(IDirect3DDevice9Ex *iface,
01636         D3DCLIPSTATUS9 *pClipStatus)
01637 {
01638     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01639     HRESULT hr;
01640 
01641     TRACE("iface %p, clip_status %p.\n", iface, pClipStatus);
01642 
01643     wined3d_mutex_lock();
01644     hr = wined3d_device_get_clip_status(This->wined3d_device, (struct wined3d_clip_status *)pClipStatus);
01645     wined3d_mutex_unlock();
01646 
01647     return hr;
01648 }
01649 
01650 static HRESULT WINAPI IDirect3DDevice9Impl_GetTexture(IDirect3DDevice9Ex *iface, DWORD Stage,
01651         IDirect3DBaseTexture9 **ppTexture)
01652 {
01653     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01654     struct wined3d_texture *wined3d_texture = NULL;
01655     HRESULT hr;
01656 
01657     TRACE("iface %p, stage %u, texture %p.\n", iface, Stage, ppTexture);
01658 
01659     if(ppTexture == NULL){
01660         return D3DERR_INVALIDCALL;
01661     }
01662 
01663     wined3d_mutex_lock();
01664     hr = wined3d_device_get_texture(This->wined3d_device, Stage, &wined3d_texture);
01665     if (SUCCEEDED(hr) && wined3d_texture)
01666     {
01667         *ppTexture = wined3d_texture_get_parent(wined3d_texture);
01668         IDirect3DBaseTexture9_AddRef(*ppTexture);
01669         wined3d_texture_decref(wined3d_texture);
01670     }
01671     else
01672     {
01673         if (FAILED(hr))
01674         {
01675             WARN("Call to get texture (%u) failed (%p).\n", Stage, wined3d_texture);
01676         }
01677         *ppTexture = NULL;
01678     }
01679     wined3d_mutex_unlock();
01680 
01681     return hr;
01682 }
01683 
01684 static HRESULT WINAPI IDirect3DDevice9Impl_SetTexture(IDirect3DDevice9Ex *iface, DWORD stage,
01685         IDirect3DBaseTexture9 *texture)
01686 {
01687     IDirect3DDevice9Impl *device = impl_from_IDirect3DDevice9Ex(iface);
01688     HRESULT hr;
01689 
01690     TRACE("iface %p, stage %u, texture %p.\n", iface, stage, texture);
01691 
01692     wined3d_mutex_lock();
01693     hr = wined3d_device_set_texture(device->wined3d_device, stage,
01694             texture ? ((IDirect3DBaseTexture9Impl *)texture)->wined3d_texture : NULL);
01695     wined3d_mutex_unlock();
01696 
01697     return hr;
01698 }
01699 
01700 static const enum wined3d_texture_stage_state tss_lookup[] =
01701 {
01702     WINED3D_TSS_INVALID,                    /*  0, unused */
01703     WINED3D_TSS_COLOR_OP,                   /*  1, D3DTSS_COLOROP */
01704     WINED3D_TSS_COLOR_ARG1,                 /*  2, D3DTSS_COLORARG1 */
01705     WINED3D_TSS_COLOR_ARG2,                 /*  3, D3DTSS_COLORARG2 */
01706     WINED3D_TSS_ALPHA_OP,                   /*  4, D3DTSS_ALPHAOP */
01707     WINED3D_TSS_ALPHA_ARG1,                 /*  5, D3DTSS_ALPHAARG1 */
01708     WINED3D_TSS_ALPHA_ARG2,                 /*  6, D3DTSS_ALPHAARG2 */
01709     WINED3D_TSS_BUMPENV_MAT00,              /*  7, D3DTSS_BUMPENVMAT00 */
01710     WINED3D_TSS_BUMPENV_MAT01,              /*  8, D3DTSS_BUMPENVMAT01 */
01711     WINED3D_TSS_BUMPENV_MAT10,              /*  9, D3DTSS_BUMPENVMAT10 */
01712     WINED3D_TSS_BUMPENV_MAT11,              /* 10, D3DTSS_BUMPENVMAT11 */
01713     WINED3D_TSS_TEXCOORD_INDEX,             /* 11, D3DTSS_TEXCOORDINDEX */
01714     WINED3D_TSS_INVALID,                    /* 12, unused */
01715     WINED3D_TSS_INVALID,                    /* 13, unused */
01716     WINED3D_TSS_INVALID,                    /* 14, unused */
01717     WINED3D_TSS_INVALID,                    /* 15, unused */
01718     WINED3D_TSS_INVALID,                    /* 16, unused */
01719     WINED3D_TSS_INVALID,                    /* 17, unused */
01720     WINED3D_TSS_INVALID,                    /* 18, unused */
01721     WINED3D_TSS_INVALID,                    /* 19, unused */
01722     WINED3D_TSS_INVALID,                    /* 20, unused */
01723     WINED3D_TSS_INVALID,                    /* 21, unused */
01724     WINED3D_TSS_BUMPENV_LSCALE,             /* 22, D3DTSS_BUMPENVLSCALE */
01725     WINED3D_TSS_BUMPENV_LOFFSET,            /* 23, D3DTSS_BUMPENVLOFFSET */
01726     WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS,    /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
01727     WINED3D_TSS_INVALID,                    /* 25, unused */
01728     WINED3D_TSS_COLOR_ARG0,                 /* 26, D3DTSS_COLORARG0 */
01729     WINED3D_TSS_ALPHA_ARG0,                 /* 27, D3DTSS_ALPHAARG0 */
01730     WINED3D_TSS_RESULT_ARG,                 /* 28, D3DTSS_RESULTARG */
01731     WINED3D_TSS_INVALID,                    /* 29, unused */
01732     WINED3D_TSS_INVALID,                    /* 30, unused */
01733     WINED3D_TSS_INVALID,                    /* 31, unused */
01734     WINED3D_TSS_CONSTANT,                   /* 32, D3DTSS_CONSTANT */
01735 };
01736 
01737 static HRESULT WINAPI IDirect3DDevice9Impl_GetTextureStageState(IDirect3DDevice9Ex *iface,
01738         DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD *pValue)
01739 {
01740     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01741     HRESULT hr;
01742 
01743     TRACE("iface %p, stage %u, state %#x, value %p.\n", iface, Stage, Type, pValue);
01744 
01745     if (Type >= sizeof(tss_lookup) / sizeof(*tss_lookup))
01746     {
01747         WARN("Invalid Type %#x passed.\n", Type);
01748         return D3D_OK;
01749     }
01750 
01751     wined3d_mutex_lock();
01752     hr = wined3d_device_get_texture_stage_state(This->wined3d_device, Stage, tss_lookup[Type], pValue);
01753     wined3d_mutex_unlock();
01754 
01755     return hr;
01756 }
01757 
01758 static HRESULT WINAPI IDirect3DDevice9Impl_SetTextureStageState(IDirect3DDevice9Ex *iface,
01759         DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value)
01760 {
01761     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01762     HRESULT hr;
01763 
01764     TRACE("iface %p, stage %u, state %#x, value %#x.\n", iface, Stage, Type, Value);
01765 
01766     if (Type >= sizeof(tss_lookup) / sizeof(*tss_lookup))
01767     {
01768         WARN("Invalid Type %#x passed.\n", Type);
01769         return D3D_OK;
01770     }
01771 
01772     wined3d_mutex_lock();
01773     hr = wined3d_device_set_texture_stage_state(This->wined3d_device, Stage, tss_lookup[Type], Value);
01774     wined3d_mutex_unlock();
01775 
01776     return hr;
01777 }
01778 
01779 static HRESULT WINAPI IDirect3DDevice9Impl_GetSamplerState(IDirect3DDevice9Ex *iface, DWORD Sampler,
01780         D3DSAMPLERSTATETYPE Type, DWORD *pValue)
01781 {
01782     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01783     HRESULT hr;
01784 
01785     TRACE("iface %p, sampler %u, state %#x, value %p.\n", iface, Sampler, Type, pValue);
01786 
01787     wined3d_mutex_lock();
01788     hr = wined3d_device_get_sampler_state(This->wined3d_device, Sampler, Type, pValue);
01789     wined3d_mutex_unlock();
01790 
01791     return hr;
01792 }
01793 
01794 static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_SetSamplerState(IDirect3DDevice9Ex *iface,
01795         DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value)
01796 {
01797     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01798     HRESULT hr;
01799 
01800     TRACE("iface %p, sampler %u, state %#x, value %#x.\n", iface, Sampler, Type, Value);
01801 
01802     wined3d_mutex_lock();
01803     hr = wined3d_device_set_sampler_state(This->wined3d_device, Sampler, Type, Value);
01804     wined3d_mutex_unlock();
01805 
01806     return hr;
01807 }
01808 
01809 static HRESULT WINAPI IDirect3DDevice9Impl_ValidateDevice(IDirect3DDevice9Ex *iface,
01810         DWORD *pNumPasses)
01811 {
01812     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01813     HRESULT hr;
01814 
01815     TRACE("iface %p, pass_count %p.\n", iface, pNumPasses);
01816 
01817     wined3d_mutex_lock();
01818     hr = wined3d_device_validate_device(This->wined3d_device, pNumPasses);
01819     wined3d_mutex_unlock();
01820 
01821     return hr;
01822 }
01823 
01824 static HRESULT WINAPI IDirect3DDevice9Impl_SetPaletteEntries(IDirect3DDevice9Ex *iface,
01825         UINT PaletteNumber, const PALETTEENTRY *pEntries)
01826 {
01827     FIXME("iface %p, palette_idx %u, entries %p unimplemented.\n", iface, PaletteNumber, pEntries);
01828 
01829     return D3DERR_INVALIDCALL;
01830 }
01831 
01832 static HRESULT WINAPI IDirect3DDevice9Impl_GetPaletteEntries(IDirect3DDevice9Ex *iface,
01833         UINT PaletteNumber, PALETTEENTRY *pEntries)
01834 {
01835     FIXME("iface %p, palette_idx %u, entries %p unimplemented.\n", iface, PaletteNumber, pEntries);
01836 
01837     return D3DERR_INVALIDCALL;
01838 }
01839 
01840 static HRESULT WINAPI IDirect3DDevice9Impl_SetCurrentTexturePalette(IDirect3DDevice9Ex *iface,
01841         UINT PaletteNumber)
01842 {
01843     FIXME("iface %p, palette_idx %u unimplemented.\n", iface, PaletteNumber);
01844 
01845     return D3DERR_INVALIDCALL;
01846 }
01847 
01848 static HRESULT WINAPI IDirect3DDevice9Impl_GetCurrentTexturePalette(IDirect3DDevice9Ex *iface,
01849         UINT *PaletteNumber)
01850 {
01851     FIXME("iface %p, palette_idx %p.\n", iface, PaletteNumber);
01852 
01853     return D3DERR_INVALIDCALL;
01854 }
01855 
01856 static HRESULT WINAPI IDirect3DDevice9Impl_SetScissorRect(IDirect3DDevice9Ex *iface,
01857         const RECT *pRect)
01858 {
01859     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01860     HRESULT hr;
01861 
01862     TRACE("iface %p, rect %p.\n", iface, pRect);
01863 
01864     wined3d_mutex_lock();
01865     hr = wined3d_device_set_scissor_rect(This->wined3d_device, pRect);
01866     wined3d_mutex_unlock();
01867 
01868     return hr;
01869 }
01870 
01871 static HRESULT WINAPI IDirect3DDevice9Impl_GetScissorRect(IDirect3DDevice9Ex *iface, RECT *pRect)
01872 {
01873     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01874     HRESULT hr;
01875 
01876     TRACE("iface %p, rect %p.\n", iface, pRect);
01877 
01878     wined3d_mutex_lock();
01879     hr = wined3d_device_get_scissor_rect(This->wined3d_device, pRect);
01880     wined3d_mutex_unlock();
01881 
01882     return hr;
01883 }
01884 
01885 static HRESULT WINAPI IDirect3DDevice9Impl_SetSoftwareVertexProcessing(IDirect3DDevice9Ex *iface,
01886         BOOL bSoftware)
01887 {
01888     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01889     HRESULT hr;
01890 
01891     TRACE("iface %p, software %#x.\n", iface, bSoftware);
01892 
01893     wined3d_mutex_lock();
01894     hr = wined3d_device_set_software_vertex_processing(This->wined3d_device, bSoftware);
01895     wined3d_mutex_unlock();
01896 
01897     return hr;
01898 }
01899 
01900 static BOOL WINAPI IDirect3DDevice9Impl_GetSoftwareVertexProcessing(IDirect3DDevice9Ex *iface)
01901 {
01902     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01903     BOOL ret;
01904 
01905     TRACE("iface %p.\n", iface);
01906 
01907     wined3d_mutex_lock();
01908     ret = wined3d_device_get_software_vertex_processing(This->wined3d_device);
01909     wined3d_mutex_unlock();
01910 
01911     return ret;
01912 }
01913 
01914 static HRESULT WINAPI IDirect3DDevice9Impl_SetNPatchMode(IDirect3DDevice9Ex *iface, float nSegments)
01915 {
01916     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01917     HRESULT hr;
01918 
01919     TRACE("iface %p, segment_count %.8e.\n", iface, nSegments);
01920 
01921     wined3d_mutex_lock();
01922     hr = wined3d_device_set_npatch_mode(This->wined3d_device, nSegments);
01923     wined3d_mutex_unlock();
01924 
01925     return hr;
01926 }
01927 
01928 static float WINAPI IDirect3DDevice9Impl_GetNPatchMode(IDirect3DDevice9Ex *iface)
01929 {
01930     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01931     float ret;
01932 
01933     TRACE("iface %p.\n", iface);
01934 
01935     wined3d_mutex_lock();
01936     ret = wined3d_device_get_npatch_mode(This->wined3d_device);
01937     wined3d_mutex_unlock();
01938 
01939     return ret;
01940 }
01941 
01942 static HRESULT WINAPI IDirect3DDevice9Impl_DrawPrimitive(IDirect3DDevice9Ex *iface,
01943         D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount)
01944 {
01945     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01946     HRESULT hr;
01947 
01948     TRACE("iface %p, primitive_type %#x, start_vertex %u, primitive_count %u.\n",
01949             iface, PrimitiveType, StartVertex, PrimitiveCount);
01950 
01951     wined3d_mutex_lock();
01952     wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType);
01953     hr = wined3d_device_draw_primitive(This->wined3d_device, StartVertex,
01954             vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount));
01955     wined3d_mutex_unlock();
01956 
01957     return hr;
01958 }
01959 
01960 static HRESULT WINAPI IDirect3DDevice9Impl_DrawIndexedPrimitive(IDirect3DDevice9Ex *iface,
01961         D3DPRIMITIVETYPE PrimitiveType, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices,
01962         UINT startIndex, UINT primCount)
01963 {
01964     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01965     HRESULT hr;
01966 
01967     TRACE("iface %p, primitive_type %#x, base_vertex_idx %u, min_vertex_idx %u,\n"
01968             "vertex_count %u, start_idx %u, primitive_count %u.\n",
01969             iface, PrimitiveType, BaseVertexIndex, MinVertexIndex,
01970             NumVertices, startIndex, primCount);
01971 
01972     wined3d_mutex_lock();
01973     wined3d_device_set_base_vertex_index(This->wined3d_device, BaseVertexIndex);
01974     wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType);
01975     hr = wined3d_device_draw_indexed_primitive(This->wined3d_device, startIndex,
01976             vertex_count_from_primitive_count(PrimitiveType, primCount));
01977     wined3d_mutex_unlock();
01978 
01979     return hr;
01980 }
01981 
01982 static HRESULT WINAPI IDirect3DDevice9Impl_DrawPrimitiveUP(IDirect3DDevice9Ex *iface,
01983         D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, const void *pVertexStreamZeroData,
01984         UINT VertexStreamZeroStride)
01985 {
01986     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
01987     HRESULT hr;
01988 
01989     TRACE("iface %p, primitive_type %#x, primitive_count %u, data %p, stride %u.\n",
01990             iface, PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride);
01991 
01992     wined3d_mutex_lock();
01993     wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType);
01994     hr = wined3d_device_draw_primitive_up(This->wined3d_device,
01995             vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount),
01996             pVertexStreamZeroData, VertexStreamZeroStride);
01997     wined3d_mutex_unlock();
01998 
01999     return hr;
02000 }
02001 
02002 static HRESULT WINAPI IDirect3DDevice9Impl_DrawIndexedPrimitiveUP(IDirect3DDevice9Ex *iface,
02003         D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertexIndices,
02004         UINT PrimitiveCount, const void *pIndexData, D3DFORMAT IndexDataFormat,
02005         const void *pVertexStreamZeroData, UINT VertexStreamZeroStride)
02006 {
02007     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02008     HRESULT hr;
02009 
02010     TRACE("iface %p, primitive_type %#x, min_vertex_idx %u, index_count %u, primitive_count %u,\n"
02011             "index_data %p, index_format %#x, vertex_data %p, vertex_stride %u.\n",
02012             iface, PrimitiveType, MinVertexIndex, NumVertexIndices, PrimitiveCount,
02013             pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride);
02014 
02015     wined3d_mutex_lock();
02016     wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType);
02017     hr = wined3d_device_draw_indexed_primitive_up(This->wined3d_device,
02018             vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount), pIndexData,
02019             wined3dformat_from_d3dformat(IndexDataFormat), pVertexStreamZeroData, VertexStreamZeroStride);
02020     wined3d_mutex_unlock();
02021 
02022     return hr;
02023 }
02024 
02025 static HRESULT WINAPI IDirect3DDevice9Impl_ProcessVertices(IDirect3DDevice9Ex *iface,
02026         UINT SrcStartIndex, UINT DestIndex, UINT VertexCount, IDirect3DVertexBuffer9 *pDestBuffer,
02027         IDirect3DVertexDeclaration9 *pVertexDecl, DWORD Flags)
02028 {
02029     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02030     IDirect3DVertexBuffer9Impl *dest = unsafe_impl_from_IDirect3DVertexBuffer9(pDestBuffer);
02031     IDirect3DVertexDeclaration9Impl *Decl = (IDirect3DVertexDeclaration9Impl *) pVertexDecl;
02032     HRESULT hr;
02033 
02034     TRACE("iface %p, src_start_idx %u, dst_idx %u, vertex_count %u, dst_buffer %p, declaration %p, flags %#x.\n",
02035             iface, SrcStartIndex, DestIndex, VertexCount, pDestBuffer, pVertexDecl, Flags);
02036 
02037     wined3d_mutex_lock();
02038     hr = wined3d_device_process_vertices(This->wined3d_device, SrcStartIndex, DestIndex, VertexCount,
02039             dest->wineD3DVertexBuffer, Decl ? Decl->wineD3DVertexDeclaration : NULL, Flags, dest->fvf);
02040     wined3d_mutex_unlock();
02041 
02042     return hr;
02043 }
02044 
02045 static HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexDeclaration(IDirect3DDevice9Ex *iface,
02046         const D3DVERTEXELEMENT9 *elements, IDirect3DVertexDeclaration9 **declaration)
02047 {
02048     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02049     IDirect3DVertexDeclaration9Impl *object;
02050     HRESULT hr;
02051 
02052     TRACE("iface %p, elements %p, declaration %p.\n", iface, elements, declaration);
02053 
02054     if (!declaration)
02055     {
02056         WARN("Caller passed a NULL declaration, returning D3DERR_INVALIDCALL.\n");
02057         return D3DERR_INVALIDCALL;
02058     }
02059 
02060     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
02061     if (!object)
02062     {
02063         ERR("Failed to allocate vertex declaration memory.\n");
02064         return E_OUTOFMEMORY;
02065     }
02066 
02067     hr = vertexdeclaration_init(object, This, elements);
02068     if (FAILED(hr))
02069     {
02070         WARN("Failed to initialize vertex declaration, hr %#x.\n", hr);
02071         HeapFree(GetProcessHeap(), 0, object);
02072         return hr;
02073     }
02074 
02075     TRACE("Created vertex declaration %p.\n", object);
02076     *declaration = (IDirect3DVertexDeclaration9 *)object;
02077 
02078     return D3D_OK;
02079 }
02080 
02081 static HRESULT WINAPI IDirect3DDevice9Impl_SetVertexDeclaration(IDirect3DDevice9Ex *iface,
02082         IDirect3DVertexDeclaration9 *declaration)
02083 {
02084     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02085     HRESULT hr;
02086 
02087     TRACE("iface %p, declaration %p.\n", iface, declaration);
02088 
02089     wined3d_mutex_lock();
02090     hr = wined3d_device_set_vertex_declaration(This->wined3d_device,
02091             declaration ? ((IDirect3DVertexDeclaration9Impl *)declaration)->wineD3DVertexDeclaration : NULL);
02092     wined3d_mutex_unlock();
02093 
02094     return hr;
02095 }
02096 
02097 static HRESULT WINAPI IDirect3DDevice9Impl_GetVertexDeclaration(IDirect3DDevice9Ex *iface,
02098         IDirect3DVertexDeclaration9 **declaration)
02099 {
02100     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02101     struct wined3d_vertex_declaration *wined3d_declaration = NULL;
02102     HRESULT hr;
02103 
02104     TRACE("iface %p, declaration %p.\n", iface, declaration);
02105 
02106     if (!declaration) return D3DERR_INVALIDCALL;
02107 
02108     wined3d_mutex_lock();
02109     hr = wined3d_device_get_vertex_declaration(This->wined3d_device, &wined3d_declaration);
02110     if (SUCCEEDED(hr) && wined3d_declaration)
02111     {
02112         *declaration = wined3d_vertex_declaration_get_parent(wined3d_declaration);
02113         IDirect3DVertexDeclaration9_AddRef(*declaration);
02114         wined3d_vertex_declaration_decref(wined3d_declaration);
02115     }
02116     else
02117     {
02118         *declaration = NULL;
02119     }
02120     wined3d_mutex_unlock();
02121 
02122     TRACE("Returning %p.\n", *declaration);
02123     return hr;
02124 }
02125 
02126 static IDirect3DVertexDeclaration9 *getConvertedDecl(IDirect3DDevice9Impl *This, DWORD fvf) {
02127     HRESULT hr;
02128     D3DVERTEXELEMENT9* elements = NULL;
02129     IDirect3DVertexDeclaration9* pDecl = NULL;
02130     int p, low, high; /* deliberately signed */
02131     IDirect3DVertexDeclaration9  **convertedDecls = This->convertedDecls;
02132 
02133     TRACE("Searching for declaration for fvf %08x... ", fvf);
02134 
02135     low = 0;
02136     high = This->numConvertedDecls - 1;
02137     while(low <= high) {
02138         p = (low + high) >> 1;
02139         TRACE("%d ", p);
02140         if(((IDirect3DVertexDeclaration9Impl *) convertedDecls[p])->convFVF == fvf) {
02141             TRACE("found %p\n", convertedDecls[p]);
02142             return convertedDecls[p];
02143         } else if(((IDirect3DVertexDeclaration9Impl *) convertedDecls[p])->convFVF < fvf) {
02144             low = p + 1;
02145         } else {
02146             high = p - 1;
02147         }
02148     }
02149     TRACE("not found. Creating and inserting at position %d.\n", low);
02150 
02151     hr = vdecl_convert_fvf(fvf, &elements);
02152     if (hr != S_OK) return NULL;
02153 
02154     hr = IDirect3DDevice9Impl_CreateVertexDeclaration(&This->IDirect3DDevice9Ex_iface, elements,
02155             &pDecl);
02156     HeapFree(GetProcessHeap(), 0, elements); /* CreateVertexDeclaration makes a copy */
02157     if (hr != S_OK) return NULL;
02158 
02159     if(This->declArraySize == This->numConvertedDecls) {
02160         int grow = max(This->declArraySize / 2, 8);
02161         convertedDecls = HeapReAlloc(GetProcessHeap(), 0, convertedDecls,
02162                                      sizeof(convertedDecls[0]) * (This->numConvertedDecls + grow));
02163         if(!convertedDecls) {
02164             /* This will destroy it */
02165             IDirect3DVertexDeclaration9_Release(pDecl);
02166             return NULL;
02167         }
02168         This->convertedDecls = convertedDecls;
02169         This->declArraySize += grow;
02170     }
02171 
02172     memmove(convertedDecls + low + 1, convertedDecls + low, sizeof(IDirect3DVertexDeclaration9Impl *) * (This->numConvertedDecls - low));
02173     convertedDecls[low] = pDecl;
02174     This->numConvertedDecls++;
02175 
02176     /* Will prevent the decl from being destroyed */
02177     ((IDirect3DVertexDeclaration9Impl *) pDecl)->convFVF = fvf;
02178     IDirect3DVertexDeclaration9_Release(pDecl); /* Does not destroy now */
02179 
02180     TRACE("Returning %p. %d decls in array\n", pDecl, This->numConvertedDecls);
02181     return pDecl;
02182 }
02183 
02184 static HRESULT WINAPI IDirect3DDevice9Impl_SetFVF(IDirect3DDevice9Ex *iface, DWORD FVF)
02185 {
02186     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02187     IDirect3DVertexDeclaration9 *decl;
02188     HRESULT hr;
02189 
02190     TRACE("iface %p, fvf %#x.\n", iface, FVF);
02191 
02192     if (!FVF)
02193     {
02194         WARN("%#x is not a valid FVF\n", FVF);
02195         return D3D_OK;
02196     }
02197 
02198     wined3d_mutex_lock();
02199     decl = getConvertedDecl(This, FVF);
02200     wined3d_mutex_unlock();
02201 
02202     if (!decl)
02203     {
02204          /* Any situation when this should happen, except out of memory? */
02205          ERR("Failed to create a converted vertex declaration\n");
02206          return D3DERR_DRIVERINTERNALERROR;
02207     }
02208 
02209     hr = IDirect3DDevice9Impl_SetVertexDeclaration(iface, decl);
02210     if (FAILED(hr)) ERR("Failed to set vertex declaration\n");
02211 
02212     return hr;
02213 }
02214 
02215 static HRESULT WINAPI IDirect3DDevice9Impl_GetFVF(IDirect3DDevice9Ex *iface, DWORD *pFVF)
02216 {
02217     IDirect3DVertexDeclaration9 *decl;
02218     HRESULT hr;
02219 
02220     TRACE("iface %p, fvf %p.\n", iface, pFVF);
02221 
02222     hr = IDirect3DDevice9_GetVertexDeclaration(iface, &decl);
02223     if (FAILED(hr))
02224     {
02225         WARN("Failed to get vertex declaration, %#x\n", hr);
02226         *pFVF = 0;
02227         return hr;
02228     }
02229 
02230     if (decl)
02231     {
02232         *pFVF = ((IDirect3DVertexDeclaration9Impl *)decl)->convFVF;
02233         IDirect3DVertexDeclaration9_Release(decl);
02234     }
02235     else
02236     {
02237         *pFVF = 0;
02238     }
02239 
02240     TRACE("Returning FVF %#x\n", *pFVF);
02241 
02242     return hr;
02243 }
02244 
02245 static HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexShader(IDirect3DDevice9Ex *iface,
02246         const DWORD *byte_code, IDirect3DVertexShader9 **shader)
02247 {
02248     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02249     IDirect3DVertexShader9Impl *object;
02250     HRESULT hr;
02251 
02252     TRACE("iface %p, byte_code %p, shader %p.\n", iface, byte_code, shader);
02253 
02254     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
02255     if (!object)
02256     {
02257         ERR("Failed to allocate vertex shader memory.\n");
02258         return E_OUTOFMEMORY;
02259     }
02260 
02261     hr = vertexshader_init(object, This, byte_code);
02262     if (FAILED(hr))
02263     {
02264         WARN("Failed to initialize vertex shader, hr %#x.\n", hr);
02265         HeapFree(GetProcessHeap(), 0, object);
02266         return hr;
02267     }
02268 
02269     TRACE("Created vertex shader %p.\n", object);
02270     *shader = &object->IDirect3DVertexShader9_iface;
02271 
02272     return D3D_OK;
02273 }
02274 
02275 static HRESULT WINAPI IDirect3DDevice9Impl_SetVertexShader(IDirect3DDevice9Ex *iface,
02276         IDirect3DVertexShader9 *shader)
02277 {
02278     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02279     IDirect3DVertexShader9Impl *shader_obj = unsafe_impl_from_IDirect3DVertexShader9(shader);
02280     HRESULT hr;
02281 
02282     TRACE("iface %p, shader %p.\n", iface, shader);
02283 
02284     wined3d_mutex_lock();
02285     hr =  wined3d_device_set_vertex_shader(This->wined3d_device,
02286             shader_obj ? shader_obj->wined3d_shader : NULL);
02287     wined3d_mutex_unlock();
02288 
02289     return hr;
02290 }
02291 
02292 static HRESULT WINAPI IDirect3DDevice9Impl_GetVertexShader(IDirect3DDevice9Ex *iface,
02293         IDirect3DVertexShader9 **shader)
02294 {
02295     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02296     struct wined3d_shader *wined3d_shader;
02297 
02298     TRACE("iface %p, shader %p.\n", iface, shader);
02299 
02300     wined3d_mutex_lock();
02301     wined3d_shader = wined3d_device_get_vertex_shader(This->wined3d_device);
02302     if (wined3d_shader)
02303     {
02304         *shader = wined3d_shader_get_parent(wined3d_shader);
02305         IDirect3DVertexShader9_AddRef(*shader);
02306         wined3d_shader_decref(wined3d_shader);
02307     }
02308     else
02309     {
02310         *shader = NULL;
02311     }
02312     wined3d_mutex_unlock();
02313 
02314     TRACE("Returning %p.\n", *shader);
02315 
02316     return D3D_OK;
02317 }
02318 
02319 static HRESULT WINAPI IDirect3DDevice9Impl_SetVertexShaderConstantF(IDirect3DDevice9Ex *iface,
02320         UINT reg_idx, const float *data, UINT count)
02321 {
02322     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02323     HRESULT hr;
02324 
02325     TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
02326 
02327     if (reg_idx + count > D3D9_MAX_VERTEX_SHADER_CONSTANTF)
02328     {
02329         WARN("Trying to access %u constants, but d3d9 only supports %u\n",
02330              reg_idx + count, D3D9_MAX_VERTEX_SHADER_CONSTANTF);
02331         return D3DERR_INVALIDCALL;
02332     }
02333 
02334     wined3d_mutex_lock();
02335     hr = wined3d_device_set_vs_consts_f(This->wined3d_device, reg_idx, data, count);
02336     wined3d_mutex_unlock();
02337 
02338     return hr;
02339 }
02340 
02341 static HRESULT WINAPI IDirect3DDevice9Impl_GetVertexShaderConstantF(IDirect3DDevice9Ex *iface,
02342         UINT reg_idx, float *data, UINT count)
02343 {
02344     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02345     HRESULT hr;
02346 
02347     TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
02348 
02349     if (reg_idx + count > D3D9_MAX_VERTEX_SHADER_CONSTANTF)
02350     {
02351         WARN("Trying to access %u constants, but d3d9 only supports %u\n",
02352              reg_idx + count, D3D9_MAX_VERTEX_SHADER_CONSTANTF);
02353         return D3DERR_INVALIDCALL;
02354     }
02355 
02356     wined3d_mutex_lock();
02357     hr = wined3d_device_get_vs_consts_f(This->wined3d_device, reg_idx, data, count);
02358     wined3d_mutex_unlock();
02359 
02360     return hr;
02361 }
02362 
02363 static HRESULT WINAPI IDirect3DDevice9Impl_SetVertexShaderConstantI(IDirect3DDevice9Ex *iface,
02364         UINT reg_idx, const int *data, UINT count)
02365 {
02366     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02367     HRESULT hr;
02368 
02369     TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
02370 
02371     wined3d_mutex_lock();
02372     hr = wined3d_device_set_vs_consts_i(This->wined3d_device, reg_idx, data, count);
02373     wined3d_mutex_unlock();
02374 
02375     return hr;
02376 }
02377 
02378 static HRESULT WINAPI IDirect3DDevice9Impl_GetVertexShaderConstantI(IDirect3DDevice9Ex *iface,
02379         UINT reg_idx, int *data, UINT count)
02380 {
02381     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02382     HRESULT hr;
02383 
02384     TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
02385 
02386     wined3d_mutex_lock();
02387     hr = wined3d_device_get_vs_consts_i(This->wined3d_device, reg_idx, data, count);
02388     wined3d_mutex_unlock();
02389 
02390     return hr;
02391 }
02392 
02393 static HRESULT WINAPI IDirect3DDevice9Impl_SetVertexShaderConstantB(IDirect3DDevice9Ex *iface,
02394         UINT reg_idx, const BOOL *data, UINT count)
02395 {
02396     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02397     HRESULT hr;
02398 
02399     TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
02400 
02401     wined3d_mutex_lock();
02402     hr = wined3d_device_set_vs_consts_b(This->wined3d_device, reg_idx, data, count);
02403     wined3d_mutex_unlock();
02404 
02405     return hr;
02406 }
02407 
02408 static HRESULT WINAPI IDirect3DDevice9Impl_GetVertexShaderConstantB(IDirect3DDevice9Ex *iface,
02409         UINT reg_idx, BOOL *data, UINT count)
02410 {
02411     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02412     HRESULT hr;
02413 
02414     TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
02415 
02416     wined3d_mutex_lock();
02417     hr = wined3d_device_get_vs_consts_b(This->wined3d_device, reg_idx, data, count);
02418     wined3d_mutex_unlock();
02419 
02420     return hr;
02421 }
02422 
02423 static HRESULT WINAPI IDirect3DDevice9Impl_SetStreamSource(IDirect3DDevice9Ex *iface,
02424         UINT StreamNumber, IDirect3DVertexBuffer9 *pStreamData, UINT OffsetInBytes, UINT Stride)
02425 {
02426     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02427     IDirect3DVertexBuffer9Impl *streamdata = unsafe_impl_from_IDirect3DVertexBuffer9(pStreamData);
02428     HRESULT hr;
02429 
02430     TRACE("iface %p, stream_idx %u, buffer %p, offset %u, stride %u.\n",
02431             iface, StreamNumber, pStreamData, OffsetInBytes, Stride);
02432 
02433     wined3d_mutex_lock();
02434     hr = wined3d_device_set_stream_source(This->wined3d_device, StreamNumber,
02435             streamdata ? streamdata->wineD3DVertexBuffer : NULL,
02436             OffsetInBytes, Stride);
02437     wined3d_mutex_unlock();
02438 
02439     return hr;
02440 }
02441 
02442 static HRESULT WINAPI IDirect3DDevice9Impl_GetStreamSource(IDirect3DDevice9Ex *iface,
02443         UINT StreamNumber, IDirect3DVertexBuffer9 **pStream, UINT *OffsetInBytes, UINT *pStride)
02444 {
02445     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02446     struct wined3d_buffer *retStream = NULL;
02447     HRESULT hr;
02448 
02449     TRACE("iface %p, stream_idx %u, buffer %p, offset %p, stride %p.\n",
02450             iface, StreamNumber, pStream, OffsetInBytes, pStride);
02451 
02452     if(pStream == NULL){
02453         return D3DERR_INVALIDCALL;
02454     }
02455 
02456     wined3d_mutex_lock();
02457     hr = wined3d_device_get_stream_source(This->wined3d_device, StreamNumber, &retStream, OffsetInBytes, pStride);
02458     if (SUCCEEDED(hr) && retStream)
02459     {
02460         *pStream = wined3d_buffer_get_parent(retStream);
02461         IDirect3DVertexBuffer9_AddRef(*pStream);
02462         wined3d_buffer_decref(retStream);
02463     }
02464     else
02465     {
02466         if (FAILED(hr))
02467         {
02468             FIXME("Call to GetStreamSource failed %p %p\n", OffsetInBytes, pStride);
02469         }
02470         *pStream = NULL;
02471     }
02472     wined3d_mutex_unlock();
02473 
02474     return hr;
02475 }
02476 
02477 static HRESULT WINAPI IDirect3DDevice9Impl_SetStreamSourceFreq(IDirect3DDevice9Ex *iface,
02478         UINT StreamNumber, UINT Divider)
02479 {
02480     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02481     HRESULT hr;
02482 
02483     TRACE("iface %p, stream_idx %u, freq %u.\n", iface, StreamNumber, Divider);
02484 
02485     wined3d_mutex_lock();
02486     hr = wined3d_device_set_stream_source_freq(This->wined3d_device, StreamNumber, Divider);
02487     wined3d_mutex_unlock();
02488 
02489     return hr;
02490 }
02491 
02492 static HRESULT WINAPI IDirect3DDevice9Impl_GetStreamSourceFreq(IDirect3DDevice9Ex *iface,
02493         UINT StreamNumber, UINT *Divider)
02494 {
02495     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02496     HRESULT hr;
02497 
02498     TRACE("iface %p, stream_idx %u, freq %p.\n", iface, StreamNumber, Divider);
02499 
02500     wined3d_mutex_lock();
02501     hr = wined3d_device_get_stream_source_freq(This->wined3d_device, StreamNumber, Divider);
02502     wined3d_mutex_unlock();
02503 
02504     return hr;
02505 }
02506 
02507 static HRESULT WINAPI IDirect3DDevice9Impl_SetIndices(IDirect3DDevice9Ex *iface,
02508         IDirect3DIndexBuffer9 *pIndexData)
02509 {
02510     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02511     IDirect3DIndexBuffer9Impl *ib = unsafe_impl_from_IDirect3DIndexBuffer9(pIndexData);
02512     HRESULT hr;
02513 
02514     TRACE("iface %p, buffer %p.\n", iface, pIndexData);
02515 
02516     wined3d_mutex_lock();
02517     hr = wined3d_device_set_index_buffer(This->wined3d_device,
02518             ib ? ib->wineD3DIndexBuffer : NULL,
02519             ib ? ib->format : WINED3DFMT_UNKNOWN);
02520     wined3d_mutex_unlock();
02521 
02522     return hr;
02523 }
02524 
02525 static HRESULT WINAPI IDirect3DDevice9Impl_GetIndices(IDirect3DDevice9Ex *iface,
02526         IDirect3DIndexBuffer9 **ppIndexData)
02527 {
02528     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02529     struct wined3d_buffer *retIndexData = NULL;
02530     HRESULT hr;
02531 
02532     TRACE("iface %p, buffer %p.\n", iface, ppIndexData);
02533 
02534     if(ppIndexData == NULL){
02535         return D3DERR_INVALIDCALL;
02536     }
02537 
02538     wined3d_mutex_lock();
02539     hr = wined3d_device_get_index_buffer(This->wined3d_device, &retIndexData);
02540     if (SUCCEEDED(hr) && retIndexData)
02541     {
02542         *ppIndexData = wined3d_buffer_get_parent(retIndexData);
02543         IDirect3DIndexBuffer9_AddRef(*ppIndexData);
02544         wined3d_buffer_decref(retIndexData);
02545     }
02546     else
02547     {
02548         if (FAILED(hr)) FIXME("Call to GetIndices failed\n");
02549         *ppIndexData = NULL;
02550     }
02551     wined3d_mutex_unlock();
02552 
02553     return hr;
02554 }
02555 
02556 static HRESULT WINAPI IDirect3DDevice9Impl_CreatePixelShader(IDirect3DDevice9Ex *iface,
02557         const DWORD *byte_code, IDirect3DPixelShader9 **shader)
02558 {
02559     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02560     IDirect3DPixelShader9Impl *object;
02561     HRESULT hr;
02562 
02563     TRACE("iface %p, byte_code %p, shader %p.\n", iface, byte_code, shader);
02564 
02565     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
02566     if (!object)
02567     {
02568         FIXME("Failed to allocate pixel shader memory.\n");
02569         return E_OUTOFMEMORY;
02570     }
02571 
02572     hr = pixelshader_init(object, This, byte_code);
02573     if (FAILED(hr))
02574     {
02575         WARN("Failed to initialize pixel shader, hr %#x.\n", hr);
02576         HeapFree(GetProcessHeap(), 0, object);
02577         return hr;
02578     }
02579 
02580     TRACE("Created pixel shader %p.\n", object);
02581     *shader = &object->IDirect3DPixelShader9_iface;
02582 
02583     return D3D_OK;
02584 }
02585 
02586 static HRESULT WINAPI IDirect3DDevice9Impl_SetPixelShader(IDirect3DDevice9Ex *iface,
02587         IDirect3DPixelShader9 *shader)
02588 {
02589     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02590     IDirect3DPixelShader9Impl *shader_obj = unsafe_impl_from_IDirect3DPixelShader9(shader);
02591     HRESULT hr;
02592 
02593     TRACE("iface %p, shader %p.\n", iface, shader);
02594 
02595     wined3d_mutex_lock();
02596     hr = wined3d_device_set_pixel_shader(This->wined3d_device,
02597             shader_obj ? shader_obj->wined3d_shader : NULL);
02598     wined3d_mutex_unlock();
02599 
02600     return hr;
02601 }
02602 
02603 static HRESULT WINAPI IDirect3DDevice9Impl_GetPixelShader(IDirect3DDevice9Ex *iface,
02604         IDirect3DPixelShader9 **shader)
02605 {
02606     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02607     struct wined3d_shader *wined3d_shader;
02608 
02609     TRACE("iface %p, shader %p.\n", iface, shader);
02610 
02611     if (!shader) return D3DERR_INVALIDCALL;
02612 
02613     wined3d_mutex_lock();
02614     wined3d_shader = wined3d_device_get_pixel_shader(This->wined3d_device);
02615     if (wined3d_shader)
02616     {
02617         *shader = wined3d_shader_get_parent(wined3d_shader);
02618         IDirect3DPixelShader9_AddRef(*shader);
02619         wined3d_shader_decref(wined3d_shader);
02620     }
02621     else
02622     {
02623         *shader = NULL;
02624     }
02625     wined3d_mutex_unlock();
02626 
02627     TRACE("Returning %p.\n", *shader);
02628 
02629     return D3D_OK;
02630 }
02631 
02632 static HRESULT WINAPI IDirect3DDevice9Impl_SetPixelShaderConstantF(IDirect3DDevice9Ex *iface,
02633         UINT reg_idx, const float *data, UINT count)
02634 {
02635     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02636     HRESULT hr;
02637 
02638     TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
02639 
02640     wined3d_mutex_lock();
02641     hr = wined3d_device_set_ps_consts_f(This->wined3d_device, reg_idx, data, count);
02642     wined3d_mutex_unlock();
02643 
02644     return hr;
02645 }
02646 
02647 static HRESULT WINAPI IDirect3DDevice9Impl_GetPixelShaderConstantF(IDirect3DDevice9Ex *iface,
02648         UINT reg_idx, float *data, UINT count)
02649 {
02650     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02651     HRESULT hr;
02652 
02653     TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
02654 
02655     wined3d_mutex_lock();
02656     hr = wined3d_device_get_ps_consts_f(This->wined3d_device, reg_idx, data, count);
02657     wined3d_mutex_unlock();
02658 
02659     return hr;
02660 }
02661 
02662 static HRESULT WINAPI IDirect3DDevice9Impl_SetPixelShaderConstantI(IDirect3DDevice9Ex *iface,
02663         UINT reg_idx, const int *data, UINT count)
02664 {
02665     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02666     HRESULT hr;
02667 
02668     TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
02669 
02670     wined3d_mutex_lock();
02671     hr = wined3d_device_set_ps_consts_i(This->wined3d_device, reg_idx, data, count);
02672     wined3d_mutex_unlock();
02673 
02674     return hr;
02675 }
02676 
02677 static HRESULT WINAPI IDirect3DDevice9Impl_GetPixelShaderConstantI(IDirect3DDevice9Ex *iface,
02678         UINT reg_idx, int *data, UINT count)
02679 {
02680     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02681     HRESULT hr;
02682 
02683     TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
02684 
02685     wined3d_mutex_lock();
02686     hr = wined3d_device_get_ps_consts_i(This->wined3d_device, reg_idx, data, count);
02687     wined3d_mutex_unlock();
02688 
02689     return hr;
02690 }
02691 
02692 static HRESULT WINAPI IDirect3DDevice9Impl_SetPixelShaderConstantB(IDirect3DDevice9Ex *iface,
02693         UINT reg_idx, const BOOL *data, UINT count)
02694 {
02695     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02696     HRESULT hr;
02697 
02698     TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
02699 
02700     wined3d_mutex_lock();
02701     hr = wined3d_device_set_ps_consts_b(This->wined3d_device, reg_idx, data, count);
02702     wined3d_mutex_unlock();
02703 
02704     return hr;
02705 }
02706 
02707 static HRESULT WINAPI IDirect3DDevice9Impl_GetPixelShaderConstantB(IDirect3DDevice9Ex *iface,
02708         UINT reg_idx, BOOL *data, UINT count)
02709 {
02710     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02711     HRESULT hr;
02712 
02713     TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
02714 
02715     wined3d_mutex_lock();
02716     hr = wined3d_device_get_ps_consts_b(This->wined3d_device, reg_idx, data, count);
02717     wined3d_mutex_unlock();
02718 
02719     return hr;
02720 }
02721 
02722 static HRESULT WINAPI IDirect3DDevice9Impl_DrawRectPatch(IDirect3DDevice9Ex *iface, UINT Handle,
02723         const float *pNumSegs, const D3DRECTPATCH_INFO *pRectPatchInfo)
02724 {
02725     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02726     HRESULT hr;
02727 
02728     TRACE("iface %p, handle %#x, segment_count %p, patch_info %p.\n",
02729             iface, Handle, pNumSegs, pRectPatchInfo);
02730 
02731     wined3d_mutex_lock();
02732     hr = wined3d_device_draw_rect_patch(This->wined3d_device, Handle,
02733             pNumSegs, (const struct wined3d_rect_patch_info *)pRectPatchInfo);
02734     wined3d_mutex_unlock();
02735 
02736     return hr;
02737 }
02738 
02739 static HRESULT WINAPI IDirect3DDevice9Impl_DrawTriPatch(IDirect3DDevice9Ex *iface, UINT Handle,
02740         const float *pNumSegs, const D3DTRIPATCH_INFO *pTriPatchInfo)
02741 {
02742     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02743     HRESULT hr;
02744 
02745     TRACE("iface %p, handle %#x, segment_count %p, patch_info %p.\n",
02746             iface, Handle, pNumSegs, pTriPatchInfo);
02747 
02748     wined3d_mutex_lock();
02749     hr = wined3d_device_draw_tri_patch(This->wined3d_device, Handle,
02750             pNumSegs, (const struct wined3d_tri_patch_info *)pTriPatchInfo);
02751     wined3d_mutex_unlock();
02752 
02753     return hr;
02754 }
02755 
02756 static HRESULT WINAPI IDirect3DDevice9Impl_DeletePatch(IDirect3DDevice9Ex *iface, UINT Handle)
02757 {
02758     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02759     HRESULT hr;
02760 
02761     TRACE("iface %p, handle %#x.\n", iface, Handle);
02762 
02763     wined3d_mutex_lock();
02764     hr = wined3d_device_delete_patch(This->wined3d_device, Handle);
02765     wined3d_mutex_unlock();
02766 
02767     return hr;
02768 }
02769 
02770 static HRESULT WINAPI IDirect3DDevice9Impl_CreateQuery(IDirect3DDevice9Ex *iface, D3DQUERYTYPE type,
02771         IDirect3DQuery9 **query)
02772 {
02773     IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
02774     IDirect3DQuery9Impl *object;
02775     HRESULT hr;
02776 
02777     TRACE("iface %p, type %#x, query %p.\n", iface, type, query);
02778 
02779     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
02780     if (!object)
02781     {
02782         ERR("Failed to allocate query memory.\n");
02783         return E_OUTOFMEMORY;
02784     }
02785 
02786     hr = query_init(object, This, type);
02787     if (FAILED(hr))
02788     {
02789         WARN("Failed to initialize query, hr %#x.\n", hr);
02790         HeapFree(GetProcessHeap(), 0, object);
02791         return hr;
02792     }
02793 
02794     TRACE("Created query %p.\n", object);
02795     if (query) *query = &object->IDirect3DQuery9_iface;
02796     else IDirect3DQuery9_Release(&object->IDirect3DQuery9_iface);
02797 
02798     return D3D_OK;
02799 }
02800 
02801 static HRESULT WINAPI IDirect3DDevice9ExImpl_SetConvolutionMonoKernel(IDirect3DDevice9Ex *iface,
02802         UINT width, UINT height, float *rows, float *columns)
02803 {
02804     FIXME("iface %p, width %u, height %u, rows %p, columns %p stub!\n",
02805             iface, width, height, rows, columns);
02806 
02807     return E_NOTIMPL;
02808 }
02809 
02810 static HRESULT WINAPI IDirect3DDevice9ExImpl_ComposeRects(IDirect3DDevice9Ex *iface,
02811         IDirect3DSurface9 *src_surface, IDirect3DSurface9 *dst_surface, IDirect3DVertexBuffer9 *src_descs,
02812         UINT rect_count, IDirect3DVertexBuffer9 *dst_descs, D3DCOMPOSERECTSOP operation, INT offset_x, INT offset_y)
02813 {
02814     FIXME("iface %p, src_surface %p, dst_surface %p, src_descs %p, rect_count %u,\n"
02815             "dst_descs %p, operation %#x, offset_x %u, offset_y %u stub!\n",
02816             iface, src_surface, dst_surface, src_descs, rect_count,
02817             dst_descs, operation, offset_x, offset_y);
02818 
02819     return E_NOTIMPL;
02820 }
02821 
02822 static HRESULT WINAPI IDirect3DDevice9ExImpl_PresentEx(IDirect3DDevice9Ex *iface,
02823         const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override,
02824         const RGNDATA *dirty_region, DWORD flags)
02825 {
02826     FIXME("iface %p, src_rect %p, dst_rect %p, dst_window_override %p, dirty_region %p, flags %#x stub!\n",
02827             iface, src_rect, dst_rect, dst_window_override, dirty_region, flags);
02828 
02829     return E_NOTIMPL;
02830 }
02831 
02832 static HRESULT WINAPI IDirect3DDevice9ExImpl_GetGPUThreadPriority(IDirect3DDevice9Ex *iface, INT *priority)
02833 {
02834     FIXME("iface %p, priority %p stub!\n", iface, priority);
02835 
02836     return E_NOTIMPL;
02837 }
02838 
02839 static HRESULT WINAPI IDirect3DDevice9ExImpl_SetGPUThreadPriority(IDirect3DDevice9Ex *iface, INT priority)
02840 {
02841     FIXME("iface %p, priority %d stub!\n", iface, priority);
02842 
02843     return E_NOTIMPL;
02844 }
02845 
02846 static HRESULT WINAPI IDirect3DDevice9ExImpl_WaitForVBlank(IDirect3DDevice9Ex *iface, UINT swapchain_idx)
02847 {
02848     FIXME("iface %p, swapchain_idx %u stub!\n", iface, swapchain_idx);
02849 
02850     return E_NOTIMPL;
02851 }
02852 
02853 static HRESULT WINAPI IDirect3DDevice9ExImpl_CheckResourceResidency(IDirect3DDevice9Ex *iface,
02854         IDirect3DResource9 **resources, UINT32 resource_count)
02855 {
02856     FIXME("iface %p, resources %p, resource_count %u stub!\n",
02857             iface, resources, resource_count);
02858 
02859     return E_NOTIMPL;
02860 }
02861 
02862 static HRESULT WINAPI IDirect3DDevice9ExImpl_SetMaximumFrameLatency(IDirect3DDevice9Ex *iface, UINT max_latency)
02863 {
02864     FIXME("iface %p, max_latency %u stub!\n", iface, max_latency);
02865 
02866     return E_NOTIMPL;
02867 }
02868 
02869 static HRESULT WINAPI IDirect3DDevice9ExImpl_GetMaximumFrameLatency(IDirect3DDevice9Ex *iface, UINT *max_latency)
02870 {
02871     FIXME("iface %p, max_latency %p stub!\n", iface, max_latency);
02872 
02873     *max_latency = 2;
02874 
02875     return E_NOTIMPL;
02876 }
02877 
02878 static HRESULT WINAPI IDirect3DDevice9ExImpl_CheckDeviceState(IDirect3DDevice9Ex *iface, HWND dst_window)
02879 {
02880     static int i;
02881 
02882     TRACE("iface %p, dst_window %p stub!\n", iface, dst_window);
02883 
02884     if (!i++)
02885         FIXME("iface %p, dst_window %p stub!\n", iface, dst_window);
02886 
02887     return D3D_OK;
02888 }
02889 
02890 static HRESULT WINAPI IDirect3DDevice9ExImpl_CreateRenderTargetEx(IDirect3DDevice9Ex *iface,
02891         UINT width, UINT height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality,
02892         BOOL lockable, IDirect3DSurface9 **surface, HANDLE *shared_handle, DWORD usage)
02893 {
02894     FIXME("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u,\n"
02895             "lockable %#x, surface %p, shared_handle %p, usage %#x stub!\n",
02896             iface, width, height, format, multisample_type, multisample_quality,
02897             lockable, surface, shared_handle, usage);
02898 
02899     if (shared_handle)
02900         FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
02901 
02902     return E_NOTIMPL;
02903 }
02904 
02905 static HRESULT WINAPI IDirect3DDevice9ExImpl_CreateOffscreenPlainSurfaceEx(IDirect3DDevice9Ex *iface,
02906         UINT width, UINT height, D3DFORMAT format, D3DPOOL pool, IDirect3DSurface9 **surface,
02907         HANDLE *shared_handle, DWORD usage)
02908 {
02909     FIXME("iface %p, width %u, height %u, format %#x, pool %#x, surface %p, shared_handle %p, usage %#x stub!\n",
02910             iface, width, height, format, pool, surface, shared_handle, usage);
02911 
02912     return E_NOTIMPL;
02913 }
02914 
02915 static HRESULT WINAPI IDirect3DDevice9ExImpl_CreateDepthStencilSurfaceEx(IDirect3DDevice9Ex *iface,
02916         UINT width, UINT height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality,
02917         BOOL discard, IDirect3DSurface9 **surface, HANDLE *shared_handle, DWORD usage)
02918 {
02919     FIXME("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u,\n"
02920             "discard %#x, surface %p, shared_handle %p, usage %#x stub!\n",
02921             iface, width, height, format, multisample_type, multisample_quality,
02922             discard, surface, shared_handle, usage);
02923 
02924     if (shared_handle)
02925         FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
02926 
02927     return E_NOTIMPL;
02928 }
02929 
02930 static HRESULT WINAPI IDirect3DDevice9ExImpl_ResetEx(IDirect3DDevice9Ex *iface,
02931         D3DPRESENT_PARAMETERS *present_parameters, D3DDISPLAYMODEEX *mode)
02932 {
02933     FIXME("iface %p, present_parameters %p, mode %p stub!\n", iface, present_parameters, mode);
02934 
02935     return E_NOTIMPL;
02936 }
02937 
02938 static HRESULT  WINAPI  IDirect3DDevice9ExImpl_GetDisplayModeEx(IDirect3DDevice9Ex *iface,
02939         UINT swapchain_idx, D3DDISPLAYMODEEX *mode, D3DDISPLAYROTATION *rotation)
02940 {
02941     FIXME("iface %p, swapchain_idx %u, mode %p, rotation %p stub!\n", iface, swapchain_idx, mode, rotation);
02942 
02943     return E_NOTIMPL;
02944 }
02945 
02946 static const IDirect3DDevice9ExVtbl Direct3DDevice9_Vtbl =
02947 {
02948     /* IUnknown */
02949     IDirect3DDevice9Impl_QueryInterface,
02950     IDirect3DDevice9Impl_AddRef,
02951     IDirect3DDevice9Impl_Release,
02952     /* IDirect3DDevice9 */
02953     IDirect3DDevice9Impl_TestCooperativeLevel,
02954     IDirect3DDevice9Impl_GetAvailableTextureMem,
02955     IDirect3DDevice9Impl_EvictManagedResources,
02956     IDirect3DDevice9Impl_GetDirect3D,
02957     IDirect3DDevice9Impl_GetDeviceCaps,
02958     IDirect3DDevice9Impl_GetDisplayMode,
02959     IDirect3DDevice9Impl_GetCreationParameters,
02960     IDirect3DDevice9Impl_SetCursorProperties,
02961     IDirect3DDevice9Impl_SetCursorPosition,
02962     IDirect3DDevice9Impl_ShowCursor,
02963     IDirect3DDevice9Impl_CreateAdditionalSwapChain,
02964     IDirect3DDevice9Impl_GetSwapChain,
02965     IDirect3DDevice9Impl_GetNumberOfSwapChains,
02966     IDirect3DDevice9Impl_Reset,
02967     IDirect3DDevice9Impl_Present,
02968     IDirect3DDevice9Impl_GetBackBuffer,
02969     IDirect3DDevice9Impl_GetRasterStatus,
02970     IDirect3DDevice9Impl_SetDialogBoxMode,
02971     IDirect3DDevice9Impl_SetGammaRamp,
02972     IDirect3DDevice9Impl_GetGammaRamp,
02973     IDirect3DDevice9Impl_CreateTexture,
02974     IDirect3DDevice9Impl_CreateVolumeTexture,
02975     IDirect3DDevice9Impl_CreateCubeTexture,
02976     IDirect3DDevice9Impl_CreateVertexBuffer,
02977     IDirect3DDevice9Impl_CreateIndexBuffer,
02978     IDirect3DDevice9Impl_CreateRenderTarget,
02979     IDirect3DDevice9Impl_CreateDepthStencilSurface,
02980     IDirect3DDevice9Impl_UpdateSurface,
02981     IDirect3DDevice9Impl_UpdateTexture,
02982     IDirect3DDevice9Impl_GetRenderTargetData,
02983     IDirect3DDevice9Impl_GetFrontBufferData,
02984     IDirect3DDevice9Impl_StretchRect,
02985     IDirect3DDevice9Impl_ColorFill,
02986     IDirect3DDevice9Impl_CreateOffscreenPlainSurface,
02987     IDirect3DDevice9Impl_SetRenderTarget,
02988     IDirect3DDevice9Impl_GetRenderTarget,
02989     IDirect3DDevice9Impl_SetDepthStencilSurface,
02990     IDirect3DDevice9Impl_GetDepthStencilSurface,
02991     IDirect3DDevice9Impl_BeginScene,
02992     IDirect3DDevice9Impl_EndScene,
02993     IDirect3DDevice9Impl_Clear,
02994     IDirect3DDevice9Impl_SetTransform,
02995     IDirect3DDevice9Impl_GetTransform,
02996     IDirect3DDevice9Impl_MultiplyTransform,
02997     IDirect3DDevice9Impl_SetViewport,
02998     IDirect3DDevice9Impl_GetViewport,
02999     IDirect3DDevice9Impl_SetMaterial,
03000     IDirect3DDevice9Impl_GetMaterial,
03001     IDirect3DDevice9Impl_SetLight,
03002     IDirect3DDevice9Impl_GetLight,
03003     IDirect3DDevice9Impl_LightEnable,
03004     IDirect3DDevice9Impl_GetLightEnable,
03005     IDirect3DDevice9Impl_SetClipPlane,
03006     IDirect3DDevice9Impl_GetClipPlane,
03007     IDirect3DDevice9Impl_SetRenderState,
03008     IDirect3DDevice9Impl_GetRenderState,
03009     IDirect3DDevice9Impl_CreateStateBlock,
03010     IDirect3DDevice9Impl_BeginStateBlock,
03011     IDirect3DDevice9Impl_EndStateBlock,
03012     IDirect3DDevice9Impl_SetClipStatus,
03013     IDirect3DDevice9Impl_GetClipStatus,
03014     IDirect3DDevice9Impl_GetTexture,
03015     IDirect3DDevice9Impl_SetTexture,
03016     IDirect3DDevice9Impl_GetTextureStageState,
03017     IDirect3DDevice9Impl_SetTextureStageState,
03018     IDirect3DDevice9Impl_GetSamplerState,
03019     IDirect3DDevice9Impl_SetSamplerState,
03020     IDirect3DDevice9Impl_ValidateDevice,
03021     IDirect3DDevice9Impl_SetPaletteEntries,
03022     IDirect3DDevice9Impl_GetPaletteEntries,
03023     IDirect3DDevice9Impl_SetCurrentTexturePalette,
03024     IDirect3DDevice9Impl_GetCurrentTexturePalette,
03025     IDirect3DDevice9Impl_SetScissorRect,
03026     IDirect3DDevice9Impl_GetScissorRect,
03027     IDirect3DDevice9Impl_SetSoftwareVertexProcessing,
03028     IDirect3DDevice9Impl_GetSoftwareVertexProcessing,
03029     IDirect3DDevice9Impl_SetNPatchMode,
03030     IDirect3DDevice9Impl_GetNPatchMode,
03031     IDirect3DDevice9Impl_DrawPrimitive,
03032     IDirect3DDevice9Impl_DrawIndexedPrimitive,
03033     IDirect3DDevice9Impl_DrawPrimitiveUP,
03034     IDirect3DDevice9Impl_DrawIndexedPrimitiveUP,
03035     IDirect3DDevice9Impl_ProcessVertices,
03036     IDirect3DDevice9Impl_CreateVertexDeclaration,
03037     IDirect3DDevice9Impl_SetVertexDeclaration,
03038     IDirect3DDevice9Impl_GetVertexDeclaration,
03039     IDirect3DDevice9Impl_SetFVF,
03040     IDirect3DDevice9Impl_GetFVF,
03041     IDirect3DDevice9Impl_CreateVertexShader,
03042     IDirect3DDevice9Impl_SetVertexShader,
03043     IDirect3DDevice9Impl_GetVertexShader,
03044     IDirect3DDevice9Impl_SetVertexShaderConstantF,
03045     IDirect3DDevice9Impl_GetVertexShaderConstantF,
03046     IDirect3DDevice9Impl_SetVertexShaderConstantI,
03047     IDirect3DDevice9Impl_GetVertexShaderConstantI,
03048     IDirect3DDevice9Impl_SetVertexShaderConstantB,
03049     IDirect3DDevice9Impl_GetVertexShaderConstantB,
03050     IDirect3DDevice9Impl_SetStreamSource,
03051     IDirect3DDevice9Impl_GetStreamSource,
03052     IDirect3DDevice9Impl_SetStreamSourceFreq,
03053     IDirect3DDevice9Impl_GetStreamSourceFreq,
03054     IDirect3DDevice9Impl_SetIndices,
03055     IDirect3DDevice9Impl_GetIndices,
03056     IDirect3DDevice9Impl_CreatePixelShader,
03057     IDirect3DDevice9Impl_SetPixelShader,
03058     IDirect3DDevice9Impl_GetPixelShader,
03059     IDirect3DDevice9Impl_SetPixelShaderConstantF,
03060     IDirect3DDevice9Impl_GetPixelShaderConstantF,
03061     IDirect3DDevice9Impl_SetPixelShaderConstantI,
03062     IDirect3DDevice9Impl_GetPixelShaderConstantI,
03063     IDirect3DDevice9Impl_SetPixelShaderConstantB,
03064     IDirect3DDevice9Impl_GetPixelShaderConstantB,
03065     IDirect3DDevice9Impl_DrawRectPatch,
03066     IDirect3DDevice9Impl_DrawTriPatch,
03067     IDirect3DDevice9Impl_DeletePatch,
03068     IDirect3DDevice9Impl_CreateQuery,
03069     /* IDirect3DDevice9Ex */
03070     IDirect3DDevice9ExImpl_SetConvolutionMonoKernel,
03071     IDirect3DDevice9ExImpl_ComposeRects,
03072     IDirect3DDevice9ExImpl_PresentEx,
03073     IDirect3DDevice9ExImpl_GetGPUThreadPriority,
03074     IDirect3DDevice9ExImpl_SetGPUThreadPriority,
03075     IDirect3DDevice9ExImpl_WaitForVBlank,
03076     IDirect3DDevice9ExImpl_CheckResourceResidency,
03077     IDirect3DDevice9ExImpl_SetMaximumFrameLatency,
03078     IDirect3DDevice9ExImpl_GetMaximumFrameLatency,
03079     IDirect3DDevice9ExImpl_CheckDeviceState,
03080     IDirect3DDevice9ExImpl_CreateRenderTargetEx,
03081     IDirect3DDevice9ExImpl_CreateOffscreenPlainSurfaceEx,
03082     IDirect3DDevice9ExImpl_CreateDepthStencilSurfaceEx,
03083     IDirect3DDevice9ExImpl_ResetEx,
03084     IDirect3DDevice9ExImpl_GetDisplayModeEx
03085 };
03086 
03087 static inline struct IDirect3DDevice9Impl *device_from_device_parent(struct wined3d_device_parent *device_parent)
03088 {
03089     return CONTAINING_RECORD(device_parent, struct IDirect3DDevice9Impl, device_parent);
03090 }
03091 
03092 static void CDECL device_parent_wined3d_device_created(struct wined3d_device_parent *device_parent,
03093         struct wined3d_device *device)
03094 {
03095     TRACE("device_parent %p, device %p.\n", device_parent, device);
03096 }
03097 
03098 static void CDECL device_parent_mode_changed(struct wined3d_device_parent *device_parent)
03099 {
03100     TRACE("device_parent %p.\n", device_parent);
03101 }
03102 
03103 static HRESULT CDECL device_parent_create_surface(struct wined3d_device_parent *device_parent,
03104         void *container_parent, UINT width, UINT height, enum wined3d_format_id format, DWORD usage,
03105         enum wined3d_pool pool, UINT level, enum wined3d_cubemap_face face, struct wined3d_surface **surface)
03106 {
03107     struct IDirect3DDevice9Impl *device = device_from_device_parent(device_parent);
03108     IDirect3DSurface9Impl *d3d_surface;
03109     BOOL lockable = TRUE;
03110     HRESULT hr;
03111 
03112     TRACE("device_parent %p, container_parent %p, width %u, height %u, format %#x, usage %#x,\n"
03113             "\tpool %#x, level %u, face %u, surface %p.\n",
03114             device_parent, container_parent, width, height, format, usage, pool, level, face, surface);
03115 
03116     if (pool == WINED3D_POOL_DEFAULT && !(usage & D3DUSAGE_DYNAMIC))
03117         lockable = FALSE;
03118 
03119     hr = IDirect3DDevice9Impl_CreateSurface(device, width, height,
03120             d3dformat_from_wined3dformat(format), lockable, FALSE /* Discard */, level,
03121             (IDirect3DSurface9 **)&d3d_surface, usage, pool, D3DMULTISAMPLE_NONE, 0 /* MultisampleQuality */);
03122     if (FAILED(hr))
03123     {
03124         WARN("Failed to create surface, hr %#x.\n", hr);
03125         return hr;
03126     }
03127 
03128     *surface = d3d_surface->wined3d_surface;
03129     wined3d_surface_incref(*surface);
03130 
03131     d3d_surface->container = container_parent;
03132     IDirect3DDevice9Ex_Release(d3d_surface->parentDevice);
03133     d3d_surface->parentDevice = NULL;
03134 
03135     IDirect3DSurface9_Release(&d3d_surface->IDirect3DSurface9_iface);
03136     d3d_surface->forwardReference = container_parent;
03137 
03138     return hr;
03139 }
03140 
03141 static HRESULT CDECL device_parent_create_rendertarget(struct wined3d_device_parent *device_parent,
03142         void *container_parent, UINT width, UINT height, enum wined3d_format_id format,
03143         enum wined3d_multisample_type multisample_type, DWORD multisample_quality, BOOL lockable,
03144         struct wined3d_surface **surface)
03145 {
03146     struct IDirect3DDevice9Impl *device = device_from_device_parent(device_parent);
03147     IDirect3DSurface9Impl *d3d_surface;
03148     HRESULT hr;
03149 
03150     TRACE("device_parent %p, container_parent %p, width %u, height %u, format %#x, multisample_type %#x,\n"
03151             "\tmultisample_quality %u, lockable %u, surface %p.\n",
03152             device_parent, container_parent, width, height, format, multisample_type,
03153             multisample_quality, lockable, surface);
03154 
03155     hr = IDirect3DDevice9Impl_CreateRenderTarget(&device->IDirect3DDevice9Ex_iface, width, height,
03156             d3dformat_from_wined3dformat(format), multisample_type, multisample_quality, lockable,
03157             (IDirect3DSurface9 **)&d3d_surface, NULL);
03158     if (FAILED(hr))
03159     {
03160         WARN("Failed to create rendertarget, hr %#x.\n", hr);
03161         return hr;
03162     }
03163 
03164     *surface = d3d_surface->wined3d_surface;
03165     wined3d_surface_incref(*surface);
03166 
03167     d3d_surface->container = container_parent;
03168     /* Implicit surfaces are created with an refcount of 0 */
03169     IDirect3DSurface9_Release(&d3d_surface->IDirect3DSurface9_iface);
03170 
03171     return hr;
03172 }
03173 
03174 static HRESULT CDECL device_parent_create_depth_stencil(struct wined3d_device_parent *device_parent,
03175         UINT width, UINT height, enum wined3d_format_id format, enum wined3d_multisample_type multisample_type,
03176         DWORD multisample_quality, BOOL discard, struct wined3d_surface **surface)
03177 {
03178     struct IDirect3DDevice9Impl *device = device_from_device_parent(device_parent);
03179     IDirect3DSurface9Impl *d3d_surface;
03180     HRESULT hr;
03181 
03182     TRACE("device_parent %p, width %u, height %u, format %#x, multisample_type %#x,\n"
03183             "\tmultisample_quality %u, discard %u, surface %p.\n",
03184             device_parent, width, height, format, multisample_type, multisample_quality, discard, surface);
03185 
03186     hr = IDirect3DDevice9Impl_CreateDepthStencilSurface(&device->IDirect3DDevice9Ex_iface, width,
03187             height, d3dformat_from_wined3dformat(format), multisample_type, multisample_quality,
03188             discard, (IDirect3DSurface9 **)&d3d_surface, NULL);
03189     if (FAILED(hr))
03190     {
03191         WARN("Failed to create depth/stencil surface, hr %#x.\n", hr);
03192         return hr;
03193     }
03194 
03195     *surface = d3d_surface->wined3d_surface;
03196     wined3d_surface_incref(*surface);
03197     d3d_surface->container = (IUnknown *)&device->IDirect3DDevice9Ex_iface;
03198     /* Implicit surfaces are created with an refcount of 0 */
03199     IDirect3DSurface9_Release(&d3d_surface->IDirect3DSurface9_iface);
03200 
03201     return hr;
03202 }
03203 
03204 static HRESULT CDECL device_parent_create_volume(struct wined3d_device_parent *device_parent,
03205         void *container_parent, UINT width, UINT height, UINT depth, enum wined3d_format_id format,
03206         enum wined3d_pool pool, DWORD usage, struct wined3d_volume **volume)
03207 {
03208     struct IDirect3DDevice9Impl *device = device_from_device_parent(device_parent);
03209     IDirect3DVolume9Impl *object;
03210     HRESULT hr;
03211 
03212     TRACE("device_parent %p, container_parent %p, width %u, height %u, depth %u, "
03213             "format %#x, pool %#x, usage %#x, volume %p\n",
03214             device_parent, container_parent, width, height, depth,
03215             format, pool, usage, volume);
03216 
03217     /* Allocate the storage for the device */
03218     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
03219     if (!object)
03220     {
03221         FIXME("Allocation of memory failed\n");
03222         *volume = NULL;
03223         return D3DERR_OUTOFVIDEOMEMORY;
03224     }
03225 
03226     hr = volume_init(object, device, width, height, depth, usage, format, pool);
03227     if (FAILED(hr))
03228     {
03229         WARN("Failed to initialize volume, hr %#x.\n", hr);
03230         HeapFree(GetProcessHeap(), 0, object);
03231         return hr;
03232     }
03233 
03234     *volume = object->wined3d_volume;
03235     wined3d_volume_incref(*volume);
03236     IDirect3DVolume9_Release(&object->IDirect3DVolume9_iface);
03237 
03238     object->container = container_parent;
03239     object->forwardReference = container_parent;
03240 
03241     TRACE("Created volume %p.\n", object);
03242 
03243     return hr;
03244 }
03245 
03246 static HRESULT CDECL device_parent_create_swapchain(struct wined3d_device_parent *device_parent,
03247         struct wined3d_swapchain_desc *desc, struct wined3d_swapchain **swapchain)
03248 {
03249     struct IDirect3DDevice9Impl *device = device_from_device_parent(device_parent);
03250     D3DPRESENT_PARAMETERS local_parameters;
03251     IDirect3DSwapChain9 *d3d_swapchain;
03252     HRESULT hr;
03253 
03254     TRACE("device_parent %p, desc %p, swapchain %p\n", device_parent, desc, swapchain);
03255 
03256     /* Copy the presentation parameters */
03257     local_parameters.BackBufferWidth = desc->backbuffer_width;
03258     local_parameters.BackBufferHeight = desc->backbuffer_height;
03259     local_parameters.BackBufferFormat = d3dformat_from_wined3dformat(desc->backbuffer_format);
03260     local_parameters.BackBufferCount = desc->backbuffer_count;
03261     local_parameters.MultiSampleType = desc->multisample_type;
03262     local_parameters.MultiSampleQuality = desc->multisample_quality;
03263     local_parameters.SwapEffect = desc->swap_effect;
03264     local_parameters.hDeviceWindow = desc->device_window;
03265     local_parameters.Windowed = desc->windowed;
03266     local_parameters.EnableAutoDepthStencil = desc->enable_auto_depth_stencil;
03267     local_parameters.AutoDepthStencilFormat = d3dformat_from_wined3dformat(desc->auto_depth_stencil_format);
03268     local_parameters.Flags = desc->flags;
03269     local_parameters.FullScreen_RefreshRateInHz = desc->refresh_rate;
03270     local_parameters.PresentationInterval = desc->swap_interval;
03271 
03272     hr = IDirect3DDevice9Impl_CreateAdditionalSwapChain(&device->IDirect3DDevice9Ex_iface,
03273             &local_parameters, &d3d_swapchain);
03274     if (FAILED(hr))
03275     {
03276         WARN("Failed to create swapchain, hr %#x.\n", hr);
03277         *swapchain = NULL;
03278         return hr;
03279     }
03280 
03281     *swapchain = ((IDirect3DSwapChain9Impl *)d3d_swapchain)->wined3d_swapchain;
03282     wined3d_swapchain_incref(*swapchain);
03283     IDirect3DSwapChain9_Release((IDirect3DSwapChain9 *)d3d_swapchain);
03284 
03285     /* Copy back the presentation parameters */
03286     desc->backbuffer_width = local_parameters.BackBufferWidth;
03287     desc->backbuffer_height = local_parameters.BackBufferHeight;
03288     desc->backbuffer_format = wined3dformat_from_d3dformat(local_parameters.BackBufferFormat);
03289     desc->backbuffer_count = local_parameters.BackBufferCount;
03290     desc->multisample_type = local_parameters.MultiSampleType;
03291     desc->multisample_quality = local_parameters.MultiSampleQuality;
03292     desc->swap_effect = local_parameters.SwapEffect;
03293     desc->device_window = local_parameters.hDeviceWindow;
03294     desc->windowed = local_parameters.Windowed;
03295     desc->enable_auto_depth_stencil = local_parameters.EnableAutoDepthStencil;
03296     desc->auto_depth_stencil_format = wined3dformat_from_d3dformat(local_parameters.AutoDepthStencilFormat);
03297     desc->flags = local_parameters.Flags;
03298     desc->refresh_rate = local_parameters.FullScreen_RefreshRateInHz;
03299     desc->swap_interval = local_parameters.PresentationInterval;
03300 
03301     return hr;
03302 }
03303 
03304 static const struct wined3d_device_parent_ops d3d9_wined3d_device_parent_ops =
03305 {
03306     device_parent_wined3d_device_created,
03307     device_parent_mode_changed,
03308     device_parent_create_surface,
03309     device_parent_create_rendertarget,
03310     device_parent_create_depth_stencil,
03311     device_parent_create_volume,
03312     device_parent_create_swapchain,
03313 };
03314 
03315 static void setup_fpu(void)
03316 {
03317 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
03318     WORD cw;
03319     __asm__ volatile ("fnstcw %0" : "=m" (cw));
03320     cw = (cw & ~0xf3f) | 0x3f;
03321     __asm__ volatile ("fldcw %0" : : "m" (cw));
03322 #elif defined(__i386__) && defined(_MSC_VER)
03323     WORD cw;
03324     __asm fnstcw cw;
03325     cw = (cw & ~0xf3f) | 0x3f;
03326     __asm fldcw cw;
03327 #else
03328     FIXME("FPU setup not implemented for this platform.\n");
03329 #endif
03330 }
03331 
03332 HRESULT device_init(IDirect3DDevice9Impl *device, IDirect3D9Impl *parent, struct wined3d *wined3d,
03333         UINT adapter, D3DDEVTYPE device_type, HWND focus_window, DWORD flags,
03334         D3DPRESENT_PARAMETERS *parameters, D3DDISPLAYMODEEX *mode)
03335 {
03336     struct wined3d_swapchain_desc *swapchain_desc;
03337     UINT i, count = 1;
03338     HRESULT hr;
03339 
03340     if (mode)
03341         FIXME("Ignoring display mode.\n");
03342 
03343     device->IDirect3DDevice9Ex_iface.lpVtbl = &Direct3DDevice9_Vtbl;
03344     device->device_parent.ops = &d3d9_wined3d_device_parent_ops;
03345     device->ref = 1;
03346 
03347     if (!(flags & D3DCREATE_FPU_PRESERVE)) setup_fpu();
03348 
03349     wined3d_mutex_lock();
03350     hr = wined3d_device_create(wined3d, adapter, device_type, focus_window, flags, 4,
03351             &device->device_parent, &device->wined3d_device);
03352     if (FAILED(hr))
03353     {
03354         WARN("Failed to create wined3d device, hr %#x.\n", hr);
03355         wined3d_mutex_unlock();
03356         return hr;
03357     }
03358 
03359     if (flags & D3DCREATE_ADAPTERGROUP_DEVICE)
03360     {
03361         WINED3DCAPS caps;
03362 
03363         wined3d_get_device_caps(wined3d, adapter, device_type, &caps);
03364         count = caps.NumberOfAdaptersInGroup;
03365     }
03366 
03367     if (flags & D3DCREATE_MULTITHREADED)
03368         wined3d_device_set_multithreaded(device->wined3d_device);
03369 
03370     if (!parameters->Windowed)
03371     {
03372         if (!focus_window)
03373             focus_window = parameters->hDeviceWindow;
03374         if (FAILED(hr = wined3d_device_acquire_focus_window(device->wined3d_device, focus_window)))
03375         {
03376             ERR("Failed to acquire focus window, hr %#x.\n", hr);
03377             wined3d_device_decref(device->wined3d_device);
03378             wined3d_mutex_unlock();
03379             return hr;
03380         }
03381 
03382         for (i = 0; i < count; ++i)
03383         {
03384             HWND device_window = parameters[i].hDeviceWindow;
03385 
03386             if (!device_window) device_window = focus_window;
03387             wined3d_device_setup_fullscreen_window(device->wined3d_device, device_window,
03388                     parameters[i].BackBufferWidth,
03389                     parameters[i].BackBufferHeight);
03390         }
03391     }
03392 
03393     swapchain_desc = HeapAlloc(GetProcessHeap(), 0, sizeof(*swapchain_desc) * count);
03394     if (!swapchain_desc)
03395     {
03396         ERR("Failed to allocate wined3d parameters.\n");
03397         wined3d_device_decref(device->wined3d_device);
03398         wined3d_mutex_unlock();
03399         return E_OUTOFMEMORY;
03400     }
03401 
03402     for (i = 0; i < count; ++i)
03403     {
03404         swapchain_desc[i].backbuffer_width = parameters[i].BackBufferWidth;
03405         swapchain_desc[i].backbuffer_height = parameters[i].BackBufferHeight;
03406         swapchain_desc[i].backbuffer_format = wined3dformat_from_d3dformat(parameters[i].BackBufferFormat);
03407         swapchain_desc[i].backbuffer_count = parameters[i].BackBufferCount;
03408         swapchain_desc[i].multisample_type = parameters[i].MultiSampleType;
03409         swapchain_desc[i].multisample_quality = parameters[i].MultiSampleQuality;
03410         swapchain_desc[i].swap_effect = parameters[i].SwapEffect;
03411         swapchain_desc[i].device_window = parameters[i].hDeviceWindow;
03412         swapchain_desc[i].windowed = parameters[i].Windowed;
03413         swapchain_desc[i].enable_auto_depth_stencil = parameters[i].EnableAutoDepthStencil;
03414         swapchain_desc[i].auto_depth_stencil_format =
03415                 wined3dformat_from_d3dformat(parameters[i].AutoDepthStencilFormat);
03416         swapchain_desc[i].flags = parameters[i].Flags;
03417         swapchain_desc[i].refresh_rate = parameters[i].FullScreen_RefreshRateInHz;
03418         swapchain_desc[i].swap_interval = parameters[i].PresentationInterval;
03419         swapchain_desc[i].auto_restore_display_mode = TRUE;
03420     }
03421 
03422     hr = wined3d_device_init_3d(device->wined3d_device, swapchain_desc);
03423     if (FAILED(hr))
03424     {
03425         WARN("Failed to initialize 3D, hr %#x.\n", hr);
03426         wined3d_device_release_focus_window(device->wined3d_device);
03427         HeapFree(GetProcessHeap(), 0, swapchain_desc);
03428         wined3d_device_decref(device->wined3d_device);
03429         wined3d_mutex_unlock();
03430         return hr;
03431     }
03432 
03433     wined3d_mutex_unlock();
03434 
03435     for (i = 0; i < count; ++i)
03436     {
03437         parameters[i].BackBufferWidth = swapchain_desc[i].backbuffer_width;
03438         parameters[i].BackBufferHeight = swapchain_desc[i].backbuffer_height;
03439         parameters[i].BackBufferFormat = d3dformat_from_wined3dformat(swapchain_desc[i].backbuffer_format);
03440         parameters[i].BackBufferCount = swapchain_desc[i].backbuffer_count;
03441         parameters[i].MultiSampleType = swapchain_desc[i].multisample_type;
03442         parameters[i].MultiSampleQuality = swapchain_desc[i].multisample_quality;
03443         parameters[i].SwapEffect = swapchain_desc[i].swap_effect;
03444         parameters[i].hDeviceWindow = swapchain_desc[i].device_window;
03445         parameters[i].Windowed = swapchain_desc[i].windowed;
03446         parameters[i].EnableAutoDepthStencil = swapchain_desc[i].enable_auto_depth_stencil;
03447         parameters[i].AutoDepthStencilFormat =
03448                 d3dformat_from_wined3dformat(swapchain_desc[i].auto_depth_stencil_format);
03449         parameters[i].Flags = swapchain_desc[i].flags;
03450         parameters[i].FullScreen_RefreshRateInHz = swapchain_desc[i].refresh_rate;
03451         parameters[i].PresentationInterval = swapchain_desc[i].swap_interval;
03452     }
03453     HeapFree(GetProcessHeap(), 0, swapchain_desc);
03454 
03455     /* Initialize the converted declaration array. This creates a valid pointer
03456      * and when adding decls HeapReAlloc() can be used without further checking. */
03457     device->convertedDecls = HeapAlloc(GetProcessHeap(), 0, 0);
03458     if (!device->convertedDecls)
03459     {
03460         ERR("Failed to allocate FVF vertex declaration map memory.\n");
03461         wined3d_mutex_lock();
03462         wined3d_device_uninit_3d(device->wined3d_device);
03463         wined3d_device_release_focus_window(device->wined3d_device);
03464         wined3d_device_decref(device->wined3d_device);
03465         wined3d_mutex_unlock();
03466         return E_OUTOFMEMORY;
03467     }
03468 
03469     device->d3d_parent = &parent->IDirect3D9Ex_iface;
03470     IDirect3D9_AddRef(device->d3d_parent);
03471 
03472     return D3D_OK;
03473 }

Generated on Mon May 28 2012 04:20:47 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.