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  * IDirect3DDevice8 implementation
00003  *
00004  * Copyright 2002-2004 Jason Edmeades
00005  * Copyright 2004 Christian Costa
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00020  */
00021 
00022 #include "config.h"
00023 
00024 #include <math.h>
00025 #include <stdarg.h>
00026 
00027 #define NONAMELESSUNION
00028 #define NONAMELESSSTRUCT
00029 #include "windef.h"
00030 #include "winbase.h"
00031 #include "winuser.h"
00032 #include "wingdi.h"
00033 #include "wine/debug.h"
00034 
00035 #include "d3d8_private.h"
00036 
00037 WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
00038 
00039 D3DFORMAT d3dformat_from_wined3dformat(enum wined3d_format_id format)
00040 {
00041     BYTE *c = (BYTE *)&format;
00042 
00043     /* Don't translate FOURCC formats */
00044     if (isprint(c[0]) && isprint(c[1]) && isprint(c[2]) && isprint(c[3])) return format;
00045 
00046     switch(format)
00047     {
00048         case WINED3DFMT_UNKNOWN: return D3DFMT_UNKNOWN;
00049         case WINED3DFMT_B8G8R8_UNORM: return D3DFMT_R8G8B8;
00050         case WINED3DFMT_B8G8R8A8_UNORM: return D3DFMT_A8R8G8B8;
00051         case WINED3DFMT_B8G8R8X8_UNORM: return D3DFMT_X8R8G8B8;
00052         case WINED3DFMT_B5G6R5_UNORM: return D3DFMT_R5G6B5;
00053         case WINED3DFMT_B5G5R5X1_UNORM: return D3DFMT_X1R5G5B5;
00054         case WINED3DFMT_B5G5R5A1_UNORM: return D3DFMT_A1R5G5B5;
00055         case WINED3DFMT_B4G4R4A4_UNORM: return D3DFMT_A4R4G4B4;
00056         case WINED3DFMT_B2G3R3_UNORM: return D3DFMT_R3G3B2;
00057         case WINED3DFMT_A8_UNORM: return D3DFMT_A8;
00058         case WINED3DFMT_B2G3R3A8_UNORM: return D3DFMT_A8R3G3B2;
00059         case WINED3DFMT_B4G4R4X4_UNORM: return D3DFMT_X4R4G4B4;
00060         case WINED3DFMT_R10G10B10A2_UNORM: return D3DFMT_A2B10G10R10;
00061         case WINED3DFMT_R16G16_UNORM: return D3DFMT_G16R16;
00062         case WINED3DFMT_P8_UINT_A8_UNORM: return D3DFMT_A8P8;
00063         case WINED3DFMT_P8_UINT: return D3DFMT_P8;
00064         case WINED3DFMT_L8_UNORM: return D3DFMT_L8;
00065         case WINED3DFMT_L8A8_UNORM: return D3DFMT_A8L8;
00066         case WINED3DFMT_L4A4_UNORM: return D3DFMT_A4L4;
00067         case WINED3DFMT_R8G8_SNORM: return D3DFMT_V8U8;
00068         case WINED3DFMT_R5G5_SNORM_L6_UNORM: return D3DFMT_L6V5U5;
00069         case WINED3DFMT_R8G8_SNORM_L8X8_UNORM: return D3DFMT_X8L8V8U8;
00070         case WINED3DFMT_R8G8B8A8_SNORM: return D3DFMT_Q8W8V8U8;
00071         case WINED3DFMT_R16G16_SNORM: return D3DFMT_V16U16;
00072         case WINED3DFMT_R10G11B11_SNORM: return D3DFMT_W11V11U10;
00073         case WINED3DFMT_R10G10B10_SNORM_A2_UNORM: return D3DFMT_A2W10V10U10;
00074         case WINED3DFMT_D16_LOCKABLE: return D3DFMT_D16_LOCKABLE;
00075         case WINED3DFMT_D32_UNORM: return D3DFMT_D32;
00076         case WINED3DFMT_S1_UINT_D15_UNORM: return D3DFMT_D15S1;
00077         case WINED3DFMT_D24_UNORM_S8_UINT: return D3DFMT_D24S8;
00078         case WINED3DFMT_X8D24_UNORM: return D3DFMT_D24X8;
00079         case WINED3DFMT_S4X4_UINT_D24_UNORM: return D3DFMT_D24X4S4;
00080         case WINED3DFMT_D16_UNORM: return D3DFMT_D16;
00081         case WINED3DFMT_VERTEXDATA: return D3DFMT_VERTEXDATA;
00082         case WINED3DFMT_R16_UINT: return D3DFMT_INDEX16;
00083         case WINED3DFMT_R32_UINT: return D3DFMT_INDEX32;
00084         default:
00085             FIXME("Unhandled wined3d format %#x.\n", format);
00086             return D3DFMT_UNKNOWN;
00087     }
00088 }
00089 
00090 enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format)
00091 {
00092     BYTE *c = (BYTE *)&format;
00093 
00094     /* Don't translate FOURCC formats */
00095     if (isprint(c[0]) && isprint(c[1]) && isprint(c[2]) && isprint(c[3])) return format;
00096 
00097     switch(format)
00098     {
00099         case D3DFMT_UNKNOWN: return WINED3DFMT_UNKNOWN;
00100         case D3DFMT_R8G8B8: return WINED3DFMT_B8G8R8_UNORM;
00101         case D3DFMT_A8R8G8B8: return WINED3DFMT_B8G8R8A8_UNORM;
00102         case D3DFMT_X8R8G8B8: return WINED3DFMT_B8G8R8X8_UNORM;
00103         case D3DFMT_R5G6B5: return WINED3DFMT_B5G6R5_UNORM;
00104         case D3DFMT_X1R5G5B5: return WINED3DFMT_B5G5R5X1_UNORM;
00105         case D3DFMT_A1R5G5B5: return WINED3DFMT_B5G5R5A1_UNORM;
00106         case D3DFMT_A4R4G4B4: return WINED3DFMT_B4G4R4A4_UNORM;
00107         case D3DFMT_R3G3B2: return WINED3DFMT_B2G3R3_UNORM;
00108         case D3DFMT_A8: return WINED3DFMT_A8_UNORM;
00109         case D3DFMT_A8R3G3B2: return WINED3DFMT_B2G3R3A8_UNORM;
00110         case D3DFMT_X4R4G4B4: return WINED3DFMT_B4G4R4X4_UNORM;
00111         case D3DFMT_A2B10G10R10: return WINED3DFMT_R10G10B10A2_UNORM;
00112         case D3DFMT_G16R16: return WINED3DFMT_R16G16_UNORM;
00113         case D3DFMT_A8P8: return WINED3DFMT_P8_UINT_A8_UNORM;
00114         case D3DFMT_P8: return WINED3DFMT_P8_UINT;
00115         case D3DFMT_L8: return WINED3DFMT_L8_UNORM;
00116         case D3DFMT_A8L8: return WINED3DFMT_L8A8_UNORM;
00117         case D3DFMT_A4L4: return WINED3DFMT_L4A4_UNORM;
00118         case D3DFMT_V8U8: return WINED3DFMT_R8G8_SNORM;
00119         case D3DFMT_L6V5U5: return WINED3DFMT_R5G5_SNORM_L6_UNORM;
00120         case D3DFMT_X8L8V8U8: return WINED3DFMT_R8G8_SNORM_L8X8_UNORM;
00121         case D3DFMT_Q8W8V8U8: return WINED3DFMT_R8G8B8A8_SNORM;
00122         case D3DFMT_V16U16: return WINED3DFMT_R16G16_SNORM;
00123         case D3DFMT_W11V11U10: return WINED3DFMT_R10G11B11_SNORM;
00124         case D3DFMT_A2W10V10U10: return WINED3DFMT_R10G10B10_SNORM_A2_UNORM;
00125         case D3DFMT_D16_LOCKABLE: return WINED3DFMT_D16_LOCKABLE;
00126         case D3DFMT_D32: return WINED3DFMT_D32_UNORM;
00127         case D3DFMT_D15S1: return WINED3DFMT_S1_UINT_D15_UNORM;
00128         case D3DFMT_D24S8: return WINED3DFMT_D24_UNORM_S8_UINT;
00129         case D3DFMT_D24X8: return WINED3DFMT_X8D24_UNORM;
00130         case D3DFMT_D24X4S4: return WINED3DFMT_S4X4_UINT_D24_UNORM;
00131         case D3DFMT_D16: return WINED3DFMT_D16_UNORM;
00132         case D3DFMT_VERTEXDATA: return WINED3DFMT_VERTEXDATA;
00133         case D3DFMT_INDEX16: return WINED3DFMT_R16_UINT;
00134         case D3DFMT_INDEX32: return WINED3DFMT_R32_UINT;
00135         default:
00136             FIXME("Unhandled D3DFORMAT %#x\n", format);
00137             return WINED3DFMT_UNKNOWN;
00138     }
00139 }
00140 
00141 static UINT vertex_count_from_primitive_count(D3DPRIMITIVETYPE primitive_type, UINT primitive_count)
00142 {
00143     switch(primitive_type)
00144     {
00145         case D3DPT_POINTLIST:
00146             return primitive_count;
00147 
00148         case D3DPT_LINELIST:
00149             return primitive_count * 2;
00150 
00151         case D3DPT_LINESTRIP:
00152             return primitive_count + 1;
00153 
00154         case D3DPT_TRIANGLELIST:
00155             return primitive_count * 3;
00156 
00157         case D3DPT_TRIANGLESTRIP:
00158         case D3DPT_TRIANGLEFAN:
00159             return primitive_count + 2;
00160 
00161         default:
00162             FIXME("Unhandled primitive type %#x\n", primitive_type);
00163             return 0;
00164     }
00165 }
00166 
00167 /* Handle table functions */
00168 static DWORD d3d8_allocate_handle(struct d3d8_handle_table *t, void *object, enum d3d8_handle_type type)
00169 {
00170     struct d3d8_handle_entry *entry;
00171 
00172     if (t->free_entries)
00173     {
00174         DWORD index = t->free_entries - t->entries;
00175         /* Use a free handle */
00176         entry = t->free_entries;
00177         if (entry->type != D3D8_HANDLE_FREE)
00178         {
00179             ERR("Handle %u(%p) is in the free list, but has type %#x.\n", index, entry, entry->type);
00180             return D3D8_INVALID_HANDLE;
00181         }
00182         t->free_entries = entry->object;
00183         entry->object = object;
00184         entry->type = type;
00185 
00186         return index;
00187     }
00188 
00189     if (!(t->entry_count < t->table_size))
00190     {
00191         /* Grow the table */
00192         UINT new_size = t->table_size + (t->table_size >> 1);
00193         struct d3d8_handle_entry *new_entries = HeapReAlloc(GetProcessHeap(),
00194                 0, t->entries, new_size * sizeof(*t->entries));
00195         if (!new_entries)
00196         {
00197             ERR("Failed to grow the handle table.\n");
00198             return D3D8_INVALID_HANDLE;
00199         }
00200         t->entries = new_entries;
00201         t->table_size = new_size;
00202     }
00203 
00204     entry = &t->entries[t->entry_count];
00205     entry->object = object;
00206     entry->type = type;
00207 
00208     return t->entry_count++;
00209 }
00210 
00211 static void *d3d8_free_handle(struct d3d8_handle_table *t, DWORD handle, enum d3d8_handle_type type)
00212 {
00213     struct d3d8_handle_entry *entry;
00214     void *object;
00215 
00216     if (handle == D3D8_INVALID_HANDLE || handle >= t->entry_count)
00217     {
00218         WARN("Invalid handle %u passed.\n", handle);
00219         return NULL;
00220     }
00221 
00222     entry = &t->entries[handle];
00223     if (entry->type != type)
00224     {
00225         WARN("Handle %u(%p) is not of type %#x.\n", handle, entry, type);
00226         return NULL;
00227     }
00228 
00229     object = entry->object;
00230     entry->object = t->free_entries;
00231     entry->type = D3D8_HANDLE_FREE;
00232     t->free_entries = entry;
00233 
00234     return object;
00235 }
00236 
00237 static void *d3d8_get_object(struct d3d8_handle_table *t, DWORD handle, enum d3d8_handle_type type)
00238 {
00239     struct d3d8_handle_entry *entry;
00240 
00241     if (handle == D3D8_INVALID_HANDLE || handle >= t->entry_count)
00242     {
00243         WARN("Invalid handle %u passed.\n", handle);
00244         return NULL;
00245     }
00246 
00247     entry = &t->entries[handle];
00248     if (entry->type != type)
00249     {
00250         WARN("Handle %u(%p) is not of type %#x.\n", handle, entry, type);
00251         return NULL;
00252     }
00253 
00254     return entry->object;
00255 }
00256 
00257 static inline IDirect3DDevice8Impl *impl_from_IDirect3DDevice8(IDirect3DDevice8 *iface)
00258 {
00259     return CONTAINING_RECORD(iface, IDirect3DDevice8Impl, IDirect3DDevice8_iface);
00260 }
00261 
00262 static HRESULT WINAPI IDirect3DDevice8Impl_QueryInterface(IDirect3DDevice8 *iface, REFIID riid,
00263         void **ppobj)
00264 {
00265     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
00266 
00267     TRACE("iface %p, riid %s, object %p.\n",
00268             iface, debugstr_guid(riid), ppobj);
00269 
00270     if (IsEqualGUID(riid, &IID_IUnknown)
00271         || IsEqualGUID(riid, &IID_IDirect3DDevice8)) {
00272         IUnknown_AddRef(iface);
00273         *ppobj = This;
00274         return S_OK;
00275     }
00276 
00277     WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
00278     *ppobj = NULL;
00279     return E_NOINTERFACE;
00280 }
00281 
00282 static ULONG WINAPI IDirect3DDevice8Impl_AddRef(IDirect3DDevice8 *iface)
00283 {
00284     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
00285     ULONG ref = InterlockedIncrement(&This->ref);
00286 
00287     TRACE("%p increasing refcount to %u.\n", iface, ref);
00288 
00289     return ref;
00290 }
00291 
00292 static ULONG WINAPI IDirect3DDevice8Impl_Release(IDirect3DDevice8 *iface)
00293 {
00294     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
00295     ULONG ref;
00296 
00297     if (This->inDestruction) return 0;
00298     ref = InterlockedDecrement(&This->ref);
00299 
00300     TRACE("%p decreasing refcount to %u.\n", iface, ref);
00301 
00302     if (ref == 0) {
00303         unsigned i;
00304         IDirect3D8 *parent = This->d3d_parent;
00305 
00306         TRACE("Releasing wined3d device %p.\n", This->wined3d_device);
00307 
00308         wined3d_mutex_lock();
00309 
00310         This->inDestruction = TRUE;
00311 
00312         for(i = 0; i < This->numConvertedDecls; i++) {
00313             IDirect3DVertexDeclaration8_Release(This->decls[i].decl);
00314         }
00315         HeapFree(GetProcessHeap(), 0, This->decls);
00316 
00317         wined3d_device_uninit_3d(This->wined3d_device);
00318         wined3d_device_release_focus_window(This->wined3d_device);
00319         wined3d_device_decref(This->wined3d_device);
00320         HeapFree(GetProcessHeap(), 0, This->handle_table.entries);
00321         HeapFree(GetProcessHeap(), 0, This);
00322 
00323         wined3d_mutex_unlock();
00324 
00325         IDirect3D8_Release(parent);
00326     }
00327     return ref;
00328 }
00329 
00330 /* IDirect3DDevice Interface follow: */
00331 static HRESULT WINAPI IDirect3DDevice8Impl_TestCooperativeLevel(IDirect3DDevice8 *iface)
00332 {
00333     IDirect3DDevice8Impl *device = impl_from_IDirect3DDevice8(iface);
00334 
00335     TRACE("iface %p.\n", iface);
00336 
00337     if (device->lost)
00338     {
00339         TRACE("Device is lost.\n");
00340         return D3DERR_DEVICENOTRESET;
00341     }
00342 
00343     return D3D_OK;
00344 }
00345 
00346 static UINT WINAPI  IDirect3DDevice8Impl_GetAvailableTextureMem(IDirect3DDevice8 *iface)
00347 {
00348     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
00349     HRESULT hr;
00350 
00351     TRACE("iface %p.\n", iface);
00352 
00353     wined3d_mutex_lock();
00354     hr = wined3d_device_get_available_texture_mem(This->wined3d_device);
00355     wined3d_mutex_unlock();
00356 
00357     return hr;
00358 }
00359 
00360 static HRESULT WINAPI IDirect3DDevice8Impl_ResourceManagerDiscardBytes(IDirect3DDevice8 *iface,
00361         DWORD Bytes)
00362 {
00363     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
00364 
00365     TRACE("iface %p, byte_count %u.\n", iface, Bytes);
00366     if (Bytes) FIXME("Byte count ignored.\n");
00367 
00368     wined3d_mutex_lock();
00369     wined3d_device_evict_managed_resources(This->wined3d_device);
00370     wined3d_mutex_unlock();
00371 
00372     return D3D_OK;
00373 }
00374 
00375 static HRESULT WINAPI IDirect3DDevice8Impl_GetDirect3D(IDirect3DDevice8 *iface, IDirect3D8 **ppD3D8)
00376 {
00377     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
00378 
00379     TRACE("iface %p, d3d8 %p.\n", iface, ppD3D8);
00380 
00381     if (NULL == ppD3D8) {
00382         return D3DERR_INVALIDCALL;
00383     }
00384 
00385     return IDirect3D8_QueryInterface(This->d3d_parent, &IID_IDirect3D8, (void **)ppD3D8);
00386 }
00387 
00388 static HRESULT WINAPI IDirect3DDevice8Impl_GetDeviceCaps(IDirect3DDevice8 *iface, D3DCAPS8 *pCaps)
00389 {
00390     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
00391     HRESULT hrc = D3D_OK;
00392     WINED3DCAPS *pWineCaps;
00393 
00394     TRACE("iface %p, caps %p.\n", iface, pCaps);
00395 
00396     if(NULL == pCaps){
00397         return D3DERR_INVALIDCALL;
00398     }
00399     pWineCaps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINED3DCAPS));
00400     if(pWineCaps == NULL){
00401         return D3DERR_INVALIDCALL; /* well this is what MSDN says to return */
00402     }
00403 
00404     wined3d_mutex_lock();
00405     hrc = wined3d_device_get_device_caps(This->wined3d_device, pWineCaps);
00406     wined3d_mutex_unlock();
00407 
00408     fixup_caps(pWineCaps);
00409     WINECAPSTOD3D8CAPS(pCaps, pWineCaps)
00410     HeapFree(GetProcessHeap(), 0, pWineCaps);
00411 
00412     TRACE("Returning %p %p\n", This, pCaps);
00413     return hrc;
00414 }
00415 
00416 static HRESULT WINAPI IDirect3DDevice8Impl_GetDisplayMode(IDirect3DDevice8 *iface,
00417         D3DDISPLAYMODE *pMode)
00418 {
00419     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
00420     HRESULT hr;
00421 
00422     TRACE("iface %p, mode %p.\n", iface, pMode);
00423 
00424     wined3d_mutex_lock();
00425     hr = wined3d_device_get_display_mode(This->wined3d_device, 0, (struct wined3d_display_mode *)pMode);
00426     wined3d_mutex_unlock();
00427 
00428     if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
00429 
00430     return hr;
00431 }
00432 
00433 static HRESULT WINAPI IDirect3DDevice8Impl_GetCreationParameters(IDirect3DDevice8 *iface,
00434         D3DDEVICE_CREATION_PARAMETERS *pParameters)
00435 {
00436     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
00437     HRESULT hr;
00438 
00439     TRACE("iface %p, parameters %p.\n", iface, pParameters);
00440 
00441     wined3d_mutex_lock();
00442     hr = wined3d_device_get_creation_parameters(This->wined3d_device,
00443             (struct wined3d_device_creation_parameters *)pParameters);
00444     wined3d_mutex_unlock();
00445 
00446     return hr;
00447 }
00448 
00449 static HRESULT WINAPI IDirect3DDevice8Impl_SetCursorProperties(IDirect3DDevice8 *iface,
00450         UINT XHotSpot, UINT YHotSpot, IDirect3DSurface8 *pCursorBitmap)
00451 {
00452     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
00453     IDirect3DSurface8Impl *pSurface = unsafe_impl_from_IDirect3DSurface8(pCursorBitmap);
00454     HRESULT hr;
00455 
00456     TRACE("iface %p, hotspot_x %u, hotspot_y %u, bitmap %p.\n",
00457             iface, XHotSpot, YHotSpot, pCursorBitmap);
00458 
00459     if (!pCursorBitmap)
00460     {
00461         WARN("No cursor bitmap, returning D3DERR_INVALIDCALL.\n");
00462         return D3DERR_INVALIDCALL;
00463     }
00464 
00465     wined3d_mutex_lock();
00466     hr = wined3d_device_set_cursor_properties(This->wined3d_device, XHotSpot, YHotSpot, pSurface->wined3d_surface);
00467     wined3d_mutex_unlock();
00468 
00469     return hr;
00470 }
00471 
00472 static void WINAPI IDirect3DDevice8Impl_SetCursorPosition(IDirect3DDevice8 *iface,
00473         UINT XScreenSpace, UINT YScreenSpace, DWORD Flags)
00474 {
00475     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
00476 
00477     TRACE("iface %p, x %u, y %u, flags %#x.\n",
00478             iface, XScreenSpace, YScreenSpace, Flags);
00479 
00480     wined3d_mutex_lock();
00481     wined3d_device_set_cursor_position(This->wined3d_device, XScreenSpace, YScreenSpace, Flags);
00482     wined3d_mutex_unlock();
00483 }
00484 
00485 static BOOL WINAPI IDirect3DDevice8Impl_ShowCursor(IDirect3DDevice8 *iface, BOOL bShow)
00486 {
00487     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
00488     BOOL ret;
00489 
00490     TRACE("iface %p, show %#x.\n", iface, bShow);
00491 
00492     wined3d_mutex_lock();
00493     ret = wined3d_device_show_cursor(This->wined3d_device, bShow);
00494     wined3d_mutex_unlock();
00495 
00496     return ret;
00497 }
00498 
00499 static HRESULT WINAPI IDirect3DDevice8Impl_CreateAdditionalSwapChain(IDirect3DDevice8 *iface,
00500         D3DPRESENT_PARAMETERS *present_parameters, IDirect3DSwapChain8 **swapchain)
00501 {
00502     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
00503     IDirect3DSwapChain8Impl *object;
00504     HRESULT hr;
00505 
00506     TRACE("iface %p, present_parameters %p, swapchain %p.\n",
00507             iface, present_parameters, swapchain);
00508 
00509     object = HeapAlloc(GetProcessHeap(),  HEAP_ZERO_MEMORY, sizeof(*object));
00510     if (!object)
00511     {
00512         ERR("Failed to allocate swapchain memory.\n");
00513         return E_OUTOFMEMORY;
00514     }
00515 
00516     hr = swapchain_init(object, This, present_parameters);
00517     if (FAILED(hr))
00518     {
00519         WARN("Failed to initialize swapchain, hr %#x.\n", hr);
00520         HeapFree(GetProcessHeap(), 0, object);
00521         return hr;
00522     }
00523 
00524     TRACE("Created swapchain %p.\n", object);
00525     *swapchain = &object->IDirect3DSwapChain8_iface;
00526 
00527     return D3D_OK;
00528 }
00529 
00530 static HRESULT CDECL reset_enum_callback(struct wined3d_resource *resource)
00531 {
00532     struct wined3d_resource_desc desc;
00533 
00534     wined3d_resource_get_desc(resource, &desc);
00535     if (desc.pool == WINED3D_POOL_DEFAULT)
00536     {
00537         IDirect3DSurface8 *surface;
00538 
00539         if (desc.resource_type != WINED3D_RTYPE_SURFACE)
00540         {
00541             WARN("Resource %p in pool D3DPOOL_DEFAULT blocks the Reset call.\n", resource);
00542             return D3DERR_DEVICELOST;
00543         }
00544 
00545         surface = wined3d_resource_get_parent(resource);
00546 
00547         IDirect3DSurface8_AddRef(surface);
00548         if (IDirect3DSurface8_Release(surface))
00549         {
00550             WARN("Surface %p (resource %p) in pool D3DPOOL_DEFAULT blocks the Reset call.\n", surface, resource);
00551             return D3DERR_DEVICELOST;
00552         }
00553 
00554         WARN("Surface %p (resource %p) is an implicit resource with ref 0.\n", surface, resource);
00555     }
00556 
00557     return D3D_OK;
00558 }
00559 
00560 static HRESULT WINAPI IDirect3DDevice8Impl_Reset(IDirect3DDevice8 *iface,
00561         D3DPRESENT_PARAMETERS *pPresentationParameters)
00562 {
00563     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
00564     struct wined3d_swapchain_desc swapchain_desc;
00565     HRESULT hr;
00566 
00567     TRACE("iface %p, present_parameters %p.\n", iface, pPresentationParameters);
00568 
00569     wined3d_mutex_lock();
00570 
00571     swapchain_desc.backbuffer_width = pPresentationParameters->BackBufferWidth;
00572     swapchain_desc.backbuffer_height = pPresentationParameters->BackBufferHeight;
00573     swapchain_desc.backbuffer_format = wined3dformat_from_d3dformat(pPresentationParameters->BackBufferFormat);
00574     swapchain_desc.backbuffer_count = pPresentationParameters->BackBufferCount;
00575     swapchain_desc.multisample_type = pPresentationParameters->MultiSampleType;
00576     swapchain_desc.multisample_quality = 0; /* d3d9 only */
00577     swapchain_desc.swap_effect = pPresentationParameters->SwapEffect;
00578     swapchain_desc.device_window = pPresentationParameters->hDeviceWindow;
00579     swapchain_desc.windowed = pPresentationParameters->Windowed;
00580     swapchain_desc.enable_auto_depth_stencil = pPresentationParameters->EnableAutoDepthStencil;
00581     swapchain_desc.auto_depth_stencil_format = wined3dformat_from_d3dformat(pPresentationParameters->AutoDepthStencilFormat);
00582     swapchain_desc.flags = pPresentationParameters->Flags;
00583     swapchain_desc.refresh_rate = pPresentationParameters->FullScreen_RefreshRateInHz;
00584     swapchain_desc.swap_interval = pPresentationParameters->FullScreen_PresentationInterval;
00585     swapchain_desc.auto_restore_display_mode = TRUE;
00586 
00587     hr = wined3d_device_reset(This->wined3d_device, &swapchain_desc, reset_enum_callback);
00588     if (SUCCEEDED(hr))
00589     {
00590         hr = wined3d_device_set_render_state(This->wined3d_device, WINED3D_RS_POINTSIZE_MIN, 0);
00591         This->lost = FALSE;
00592     }
00593     else
00594     {
00595         This->lost = TRUE;
00596     }
00597     wined3d_mutex_unlock();
00598 
00599     return hr;
00600 }
00601 
00602 static HRESULT WINAPI IDirect3DDevice8Impl_Present(IDirect3DDevice8 *iface, const RECT *pSourceRect,
00603         const RECT *pDestRect, HWND hDestWindowOverride, const RGNDATA *pDirtyRegion)
00604 {
00605     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
00606     HRESULT hr;
00607 
00608     TRACE("iface %p, src_rect %p, dst_rect %p, dst_window_override %p, dirty_region %p.\n",
00609             iface, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
00610 
00611     wined3d_mutex_lock();
00612     hr = wined3d_device_present(This->wined3d_device, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
00613     wined3d_mutex_unlock();
00614 
00615     return hr;
00616 }
00617 
00618 static HRESULT WINAPI IDirect3DDevice8Impl_GetBackBuffer(IDirect3DDevice8 *iface,
00619         UINT BackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface8 **ppBackBuffer)
00620 {
00621     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
00622     struct wined3d_surface *wined3d_surface = NULL;
00623     HRESULT hr;
00624 
00625     TRACE("iface %p, backbuffer_idx %u, backbuffer_type %#x, backbuffer %p.\n",
00626             iface, BackBuffer, Type, ppBackBuffer);
00627 
00628     wined3d_mutex_lock();
00629     hr = wined3d_device_get_back_buffer(This->wined3d_device, 0,
00630             BackBuffer, (enum wined3d_backbuffer_type)Type, &wined3d_surface);
00631     if (SUCCEEDED(hr) && wined3d_surface && ppBackBuffer)
00632     {
00633         *ppBackBuffer = wined3d_surface_get_parent(wined3d_surface);
00634         IDirect3DSurface8_AddRef(*ppBackBuffer);
00635         wined3d_surface_decref(wined3d_surface);
00636     }
00637     wined3d_mutex_unlock();
00638 
00639     return hr;
00640 }
00641 
00642 static HRESULT WINAPI IDirect3DDevice8Impl_GetRasterStatus(IDirect3DDevice8 *iface,
00643         D3DRASTER_STATUS *pRasterStatus)
00644 {
00645     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
00646     HRESULT hr;
00647 
00648     TRACE("iface %p, raster_status %p.\n", iface, pRasterStatus);
00649 
00650     wined3d_mutex_lock();
00651     hr = wined3d_device_get_raster_status(This->wined3d_device, 0, (struct wined3d_raster_status *)pRasterStatus);
00652     wined3d_mutex_unlock();
00653 
00654     return hr;
00655 }
00656 
00657 static void WINAPI IDirect3DDevice8Impl_SetGammaRamp(IDirect3DDevice8 *iface, DWORD Flags,
00658         const D3DGAMMARAMP *pRamp)
00659 {
00660     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
00661 
00662     TRACE("iface %p, flags %#x, ramp %p.\n", iface, Flags, pRamp);
00663 
00664     /* Note: D3DGAMMARAMP is compatible with struct wined3d_gamma_ramp. */
00665     wined3d_mutex_lock();
00666     wined3d_device_set_gamma_ramp(This->wined3d_device, 0, Flags, (const struct wined3d_gamma_ramp *)pRamp);
00667     wined3d_mutex_unlock();
00668 }
00669 
00670 static void WINAPI IDirect3DDevice8Impl_GetGammaRamp(IDirect3DDevice8 *iface, D3DGAMMARAMP *pRamp)
00671 {
00672     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
00673 
00674     TRACE("iface %p, ramp %p.\n", iface, pRamp);
00675 
00676     /* Note: D3DGAMMARAMP is compatible with struct wined3d_gamma_ramp. */
00677     wined3d_mutex_lock();
00678     wined3d_device_get_gamma_ramp(This->wined3d_device, 0, (struct wined3d_gamma_ramp *)pRamp);
00679     wined3d_mutex_unlock();
00680 }
00681 
00682 static HRESULT WINAPI IDirect3DDevice8Impl_CreateTexture(IDirect3DDevice8 *iface,
00683         UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format,
00684         D3DPOOL pool, IDirect3DTexture8 **texture)
00685 {
00686     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
00687     IDirect3DTexture8Impl *object;
00688     HRESULT hr;
00689 
00690     TRACE("iface %p, width %u, height %u, levels %u, usage %#x, format %#x, pool %#x, texture %p.\n",
00691             iface, width, height, levels, usage, format, pool, texture);
00692 
00693     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
00694     if (!object)
00695     {
00696         ERR("Failed to allocate texture memory.\n");
00697         return D3DERR_OUTOFVIDEOMEMORY;
00698     }
00699 
00700     hr = texture_init(object, This, width, height, levels, usage, format, pool);
00701     if (FAILED(hr))
00702     {
00703         WARN("Failed to initialize texture, hr %#x.\n", hr);
00704         HeapFree(GetProcessHeap(), 0, object);
00705         return hr;
00706     }
00707 
00708     TRACE("Created texture %p.\n", object);
00709     *texture = &object->IDirect3DTexture8_iface;
00710 
00711     return D3D_OK;
00712 }
00713 
00714 static HRESULT WINAPI IDirect3DDevice8Impl_CreateVolumeTexture(IDirect3DDevice8 *iface,
00715         UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format,
00716         D3DPOOL pool, IDirect3DVolumeTexture8 **texture)
00717 {
00718     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
00719     IDirect3DVolumeTexture8Impl *object;
00720     HRESULT hr;
00721 
00722     TRACE("iface %p, width %u, height %u, depth %u, levels %u, usage %#x, format %#x, pool %#x, texture %p.\n",
00723             iface, width, height, depth, levels, usage, format, pool, texture);
00724 
00725     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
00726     if (!object)
00727     {
00728         ERR("Failed to allocate volume texture memory.\n");
00729         return D3DERR_OUTOFVIDEOMEMORY;
00730     }
00731 
00732     hr = volumetexture_init(object, This, width, height, depth, levels, usage, format, pool);
00733     if (FAILED(hr))
00734     {
00735         WARN("Failed to initialize volume texture, hr %#x.\n", hr);
00736         HeapFree(GetProcessHeap(), 0, object);
00737         return hr;
00738     }
00739 
00740     TRACE("Created volume texture %p.\n", object);
00741     *texture = &object->IDirect3DVolumeTexture8_iface;
00742 
00743     return D3D_OK;
00744 }
00745 
00746 static HRESULT WINAPI IDirect3DDevice8Impl_CreateCubeTexture(IDirect3DDevice8 *iface, UINT edge_length,
00747         UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool, IDirect3DCubeTexture8 **texture)
00748 {
00749     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
00750     IDirect3DCubeTexture8Impl *object;
00751     HRESULT hr;
00752 
00753     TRACE("iface %p, edge_length %u, levels %u, usage %#x, format %#x, pool %#x, texture %p.\n",
00754             iface, edge_length, levels, usage, format, pool, texture);
00755 
00756     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
00757     if (!object)
00758     {
00759         ERR("Failed to allocate cube texture memory.\n");
00760         return D3DERR_OUTOFVIDEOMEMORY;
00761     }
00762 
00763     hr = cubetexture_init(object, This, edge_length, levels, usage, format, pool);
00764     if (FAILED(hr))
00765     {
00766         WARN("Failed to initialize cube texture, hr %#x.\n", hr);
00767         HeapFree(GetProcessHeap(), 0, object);
00768         return hr;
00769     }
00770 
00771     TRACE("Created cube texture %p.\n", object);
00772     *texture = &object->IDirect3DCubeTexture8_iface;
00773 
00774     return hr;
00775 }
00776 
00777 static HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexBuffer(IDirect3DDevice8 *iface, UINT size,
00778         DWORD usage, DWORD fvf, D3DPOOL pool, IDirect3DVertexBuffer8 **buffer)
00779 {
00780     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
00781     IDirect3DVertexBuffer8Impl *object;
00782     HRESULT hr;
00783 
00784     TRACE("iface %p, size %u, usage %#x, fvf %#x, pool %#x, buffer %p.\n",
00785             iface, size, usage, fvf, pool, buffer);
00786 
00787     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
00788     if (!object)
00789     {
00790         ERR("Failed to allocate buffer memory.\n");
00791         return D3DERR_OUTOFVIDEOMEMORY;
00792     }
00793 
00794     hr = vertexbuffer_init(object, This, size, usage, fvf, pool);
00795     if (FAILED(hr))
00796     {
00797         WARN("Failed to initialize vertex buffer, hr %#x.\n", hr);
00798         HeapFree(GetProcessHeap(), 0, object);
00799         return hr;
00800     }
00801 
00802     TRACE("Created vertex buffer %p.\n", object);
00803     *buffer = &object->IDirect3DVertexBuffer8_iface;
00804 
00805     return D3D_OK;
00806 }
00807 
00808 static HRESULT WINAPI IDirect3DDevice8Impl_CreateIndexBuffer(IDirect3DDevice8 *iface, UINT size,
00809         DWORD usage, D3DFORMAT format, D3DPOOL pool, IDirect3DIndexBuffer8 **buffer)
00810 {
00811     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
00812     IDirect3DIndexBuffer8Impl *object;
00813     HRESULT hr;
00814 
00815     TRACE("iface %p, size %u, usage %#x, format %#x, pool %#x, buffer %p.\n",
00816             iface, size, usage, format, pool, buffer);
00817 
00818     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
00819     if (!object)
00820     {
00821         ERR("Failed to allocate buffer memory.\n");
00822         return D3DERR_OUTOFVIDEOMEMORY;
00823     }
00824 
00825     hr = indexbuffer_init(object, This, size, usage, format, pool);
00826     if (FAILED(hr))
00827     {
00828         WARN("Failed to initialize index buffer, hr %#x.\n", hr);
00829         HeapFree(GetProcessHeap(), 0, object);
00830         return hr;
00831     }
00832 
00833     TRACE("Created index buffer %p.\n", object);
00834     *buffer = &object->IDirect3DIndexBuffer8_iface;
00835 
00836     return D3D_OK;
00837 }
00838 
00839 static HRESULT IDirect3DDevice8Impl_CreateSurface(IDirect3DDevice8Impl *device, UINT Width,
00840         UINT Height, D3DFORMAT Format, BOOL Lockable, BOOL Discard, UINT Level,
00841         IDirect3DSurface8 **ppSurface, UINT Usage, D3DPOOL Pool, D3DMULTISAMPLE_TYPE MultiSample,
00842         DWORD MultisampleQuality)
00843 {
00844     IDirect3DSurface8Impl *object;
00845     HRESULT hr;
00846 
00847     TRACE("device %p, width %u, height %u, format %#x, lockable %#x, discard %#x, level %u, surface %p,\n"
00848             "\tusage %#x, pool %#x, multisample_type %#x, multisample_quality %u.\n",
00849             device, Width, Height, Format, Lockable, Discard, Level, ppSurface,
00850             Usage, Pool, MultiSample, MultisampleQuality);
00851 
00852     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl));
00853     if (!object)
00854     {
00855         FIXME("Failed to allocate surface memory.\n");
00856         return D3DERR_OUTOFVIDEOMEMORY;
00857     }
00858 
00859     hr = surface_init(object, device, Width, Height, Format, Lockable, Discard, Level, Usage,
00860             Pool, MultiSample, MultisampleQuality);
00861     if (FAILED(hr))
00862     {
00863         WARN("Failed to initialize surface, hr %#x.\n", hr);
00864         HeapFree(GetProcessHeap(), 0, object);
00865         return hr;
00866     }
00867 
00868     TRACE("Created surface %p.\n", object);
00869     *ppSurface = &object->IDirect3DSurface8_iface;
00870 
00871     return D3D_OK;
00872 }
00873 
00874 static HRESULT WINAPI IDirect3DDevice8Impl_CreateRenderTarget(IDirect3DDevice8 *iface, UINT Width,
00875         UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, BOOL Lockable,
00876         IDirect3DSurface8 **ppSurface)
00877 {
00878     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
00879     HRESULT hr;
00880 
00881     TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, lockable %#x, surface %p.\n",
00882             iface, Width, Height, Format, MultiSample, Lockable, ppSurface);
00883 
00884     hr = IDirect3DDevice8Impl_CreateSurface(This, Width, Height, Format, Lockable,
00885             FALSE /* Discard */, 0 /* Level */, ppSurface, D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT,
00886             MultiSample, 0);
00887 
00888     return hr;
00889 }
00890 
00891 static HRESULT WINAPI IDirect3DDevice8Impl_CreateDepthStencilSurface(IDirect3DDevice8 *iface,
00892         UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample,
00893         IDirect3DSurface8 **ppSurface)
00894 {
00895     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
00896     HRESULT hr;
00897 
00898     TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, surface %p.\n",
00899             iface, Width, Height, Format, MultiSample, ppSurface);
00900 
00901     /* TODO: Verify that Discard is false */
00902     hr = IDirect3DDevice8Impl_CreateSurface(This, Width, Height, Format, TRUE /* Lockable */, FALSE,
00903             0 /* Level */, ppSurface, D3DUSAGE_DEPTHSTENCIL, D3DPOOL_DEFAULT, MultiSample, 0);
00904 
00905     return hr;
00906 }
00907 
00908 /*  IDirect3DDevice8Impl::CreateImageSurface returns surface with pool type SYSTEMMEM */
00909 static HRESULT WINAPI IDirect3DDevice8Impl_CreateImageSurface(IDirect3DDevice8 *iface, UINT Width,
00910         UINT Height, D3DFORMAT Format, IDirect3DSurface8 **ppSurface)
00911 {
00912     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
00913     HRESULT hr;
00914 
00915     TRACE("iface %p, width %u, height %u, format %#x, surface %p.\n",
00916             iface, Width, Height, Format, ppSurface);
00917 
00918     hr = IDirect3DDevice8Impl_CreateSurface(This, Width, Height, Format, TRUE /* Lockable */,
00919             FALSE /* Discard */, 0 /* Level */, ppSurface, 0 /* Usage (undefined/none) */,
00920             D3DPOOL_SYSTEMMEM, D3DMULTISAMPLE_NONE, 0 /* MultisampleQuality */);
00921 
00922     return hr;
00923 }
00924 
00925 static HRESULT WINAPI IDirect3DDevice8Impl_CopyRects(IDirect3DDevice8 *iface,
00926         IDirect3DSurface8 *pSourceSurface, const RECT *pSourceRects, UINT cRects,
00927         IDirect3DSurface8 *pDestinationSurface, const POINT *pDestPoints)
00928 {
00929     IDirect3DSurface8Impl *Source = unsafe_impl_from_IDirect3DSurface8(pSourceSurface);
00930     IDirect3DSurface8Impl *Dest = unsafe_impl_from_IDirect3DSurface8(pDestinationSurface);
00931     enum wined3d_format_id srcFormat, destFormat;
00932     struct wined3d_resource_desc wined3d_desc;
00933     struct wined3d_resource *wined3d_resource;
00934     UINT src_w, src_h;
00935     HRESULT hr;
00936 
00937     TRACE("iface %p, src_surface %p, src_rects %p, rect_count %u, dst_surface %p, dst_points %p.\n",
00938             iface, pSourceSurface, pSourceRects, cRects, pDestinationSurface, pDestPoints);
00939 
00940     /* Check that the source texture is in WINED3D_POOL_SYSTEM_MEM and the
00941      * destination texture is in WINED3D_POOL_DEFAULT. */
00942 
00943     wined3d_mutex_lock();
00944     wined3d_resource = wined3d_surface_get_resource(Source->wined3d_surface);
00945     wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
00946     srcFormat = wined3d_desc.format;
00947     src_w = wined3d_desc.width;
00948     src_h = wined3d_desc.height;
00949 
00950     wined3d_resource = wined3d_surface_get_resource(Dest->wined3d_surface);
00951     wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
00952     destFormat = wined3d_desc.format;
00953 
00954     /* Check that the source and destination formats match */
00955     if (srcFormat != destFormat && WINED3DFMT_UNKNOWN != destFormat)
00956     {
00957         WARN("Source %p format must match the dest %p format, returning D3DERR_INVALIDCALL.\n",
00958                 pSourceSurface, pDestinationSurface);
00959         wined3d_mutex_unlock();
00960         return D3DERR_INVALIDCALL;
00961     }
00962     else if (WINED3DFMT_UNKNOWN == destFormat)
00963     {
00964         TRACE("(%p) : Converting destination surface from WINED3DFMT_UNKNOWN to the source format\n", iface);
00965         if (FAILED(hr = wined3d_surface_update_desc(Dest->wined3d_surface, wined3d_desc.width, wined3d_desc.height,
00966                 srcFormat, wined3d_desc.multisample_type, wined3d_desc.multisample_quality)))
00967         {
00968             WARN("Failed to update surface desc, hr %#x.\n", hr);
00969             wined3d_mutex_unlock();
00970             return hr;
00971         }
00972     }
00973 
00974     /* Quick if complete copy ... */
00975     if (!cRects && !pSourceRects && !pDestPoints)
00976     {
00977         RECT rect = {0, 0, src_w, src_h};
00978         wined3d_surface_blt(Dest->wined3d_surface, &rect,
00979                 Source->wined3d_surface, &rect, 0, NULL, WINED3D_TEXF_POINT);
00980     }
00981     else
00982     {
00983         unsigned int i;
00984         /* Copy rect by rect */
00985         if (pSourceRects && pDestPoints)
00986         {
00987             for (i = 0; i < cRects; ++i)
00988             {
00989                 UINT w = pSourceRects[i].right - pSourceRects[i].left;
00990                 UINT h = pSourceRects[i].bottom - pSourceRects[i].top;
00991                 RECT dst_rect = {pDestPoints[i].x, pDestPoints[i].y,
00992                         pDestPoints[i].x + w, pDestPoints[i].y + h};
00993 
00994                 wined3d_surface_blt(Dest->wined3d_surface, &dst_rect,
00995                         Source->wined3d_surface, &pSourceRects[i], 0, NULL, WINED3D_TEXF_POINT);
00996             }
00997         }
00998         else
00999         {
01000             for (i = 0; i < cRects; ++i)
01001             {
01002                 UINT w = pSourceRects[i].right - pSourceRects[i].left;
01003                 UINT h = pSourceRects[i].bottom - pSourceRects[i].top;
01004                 RECT dst_rect = {0, 0, w, h};
01005 
01006                 wined3d_surface_blt(Dest->wined3d_surface, &dst_rect,
01007                         Source->wined3d_surface, &pSourceRects[i], 0, NULL, WINED3D_TEXF_POINT);
01008             }
01009         }
01010     }
01011     wined3d_mutex_unlock();
01012 
01013     return WINED3D_OK;
01014 }
01015 
01016 static HRESULT WINAPI IDirect3DDevice8Impl_UpdateTexture(IDirect3DDevice8 *iface,
01017         IDirect3DBaseTexture8 *src_texture, IDirect3DBaseTexture8 *dst_texture)
01018 {
01019     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01020     HRESULT hr;
01021 
01022     TRACE("iface %p, src_texture %p, dst_texture %p.\n", iface, src_texture, dst_texture);
01023 
01024     wined3d_mutex_lock();
01025     hr = wined3d_device_update_texture(This->wined3d_device,
01026             ((IDirect3DBaseTexture8Impl *)src_texture)->wined3d_texture,
01027             ((IDirect3DBaseTexture8Impl *)dst_texture)->wined3d_texture);
01028     wined3d_mutex_unlock();
01029 
01030     return hr;
01031 }
01032 
01033 static HRESULT WINAPI IDirect3DDevice8Impl_GetFrontBuffer(IDirect3DDevice8 *iface,
01034         IDirect3DSurface8 *pDestSurface)
01035 {
01036     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01037     IDirect3DSurface8Impl *destSurface = unsafe_impl_from_IDirect3DSurface8(pDestSurface);
01038     HRESULT hr;
01039 
01040     TRACE("iface %p, dst_surface %p.\n", iface, pDestSurface);
01041 
01042     if (pDestSurface == NULL) {
01043         WARN("(%p) : Caller passed NULL as pDestSurface returning D3DERR_INVALIDCALL\n", This);
01044         return D3DERR_INVALIDCALL;
01045     }
01046 
01047     wined3d_mutex_lock();
01048     hr = wined3d_device_get_front_buffer_data(This->wined3d_device, 0, destSurface->wined3d_surface);
01049     wined3d_mutex_unlock();
01050 
01051     return hr;
01052 }
01053 
01054 static HRESULT WINAPI IDirect3DDevice8Impl_SetRenderTarget(IDirect3DDevice8 *iface,
01055         IDirect3DSurface8 *pRenderTarget, IDirect3DSurface8 *pNewZStencil)
01056 {
01057     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01058     IDirect3DSurface8Impl *pSurface = unsafe_impl_from_IDirect3DSurface8(pRenderTarget);
01059     IDirect3DSurface8Impl *pZSurface = unsafe_impl_from_IDirect3DSurface8(pNewZStencil);
01060     struct wined3d_surface *original_ds = NULL;
01061     HRESULT hr;
01062 
01063     TRACE("iface %p, render_target %p, depth_stencil %p.\n", iface, pRenderTarget, pNewZStencil);
01064 
01065     wined3d_mutex_lock();
01066 
01067     if (pZSurface)
01068     {
01069         struct wined3d_resource_desc ds_desc, rt_desc;
01070         struct wined3d_resource *wined3d_resource;
01071         struct wined3d_surface *original_rt = NULL;
01072 
01073         /* If no render target is passed in check the size against the current RT */
01074         if (!pRenderTarget)
01075         {
01076             hr = wined3d_device_get_render_target(This->wined3d_device, 0, &original_rt);
01077             if (FAILED(hr) || !original_rt)
01078             {
01079                 wined3d_mutex_unlock();
01080                 return hr;
01081             }
01082             wined3d_resource = wined3d_surface_get_resource(original_rt);
01083             wined3d_surface_decref(original_rt);
01084         }
01085         else
01086             wined3d_resource = wined3d_surface_get_resource(pSurface->wined3d_surface);
01087         wined3d_resource_get_desc(wined3d_resource, &rt_desc);
01088 
01089         wined3d_resource = wined3d_surface_get_resource(pZSurface->wined3d_surface);
01090         wined3d_resource_get_desc(wined3d_resource, &ds_desc);
01091 
01092         if (ds_desc.width < rt_desc.width || ds_desc.height < rt_desc.height)
01093         {
01094             WARN("Depth stencil is smaller than the render target, returning D3DERR_INVALIDCALL\n");
01095             wined3d_mutex_unlock();
01096             return D3DERR_INVALIDCALL;
01097         }
01098     }
01099 
01100     hr = wined3d_device_get_depth_stencil(This->wined3d_device, &original_ds);
01101     if (hr == WINED3D_OK || hr == WINED3DERR_NOTFOUND)
01102     {
01103         hr = wined3d_device_set_depth_stencil(This->wined3d_device, pZSurface ? pZSurface->wined3d_surface : NULL);
01104         if (SUCCEEDED(hr) && pRenderTarget)
01105         {
01106             hr = wined3d_device_set_render_target(This->wined3d_device, 0, pSurface->wined3d_surface, TRUE);
01107             if (FAILED(hr))
01108                 wined3d_device_set_depth_stencil(This->wined3d_device, original_ds);
01109         }
01110     }
01111     if (original_ds)
01112         wined3d_surface_decref(original_ds);
01113 
01114     wined3d_mutex_unlock();
01115 
01116     return hr;
01117 }
01118 
01119 static HRESULT WINAPI IDirect3DDevice8Impl_GetRenderTarget(IDirect3DDevice8 *iface,
01120         IDirect3DSurface8 **ppRenderTarget)
01121 {
01122     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01123     struct wined3d_surface *wined3d_surface;
01124     HRESULT hr;
01125 
01126     TRACE("iface %p, render_target %p.\n", iface, ppRenderTarget);
01127 
01128     if (ppRenderTarget == NULL) {
01129         return D3DERR_INVALIDCALL;
01130     }
01131 
01132     wined3d_mutex_lock();
01133     hr = wined3d_device_get_render_target(This->wined3d_device, 0, &wined3d_surface);
01134     if (SUCCEEDED(hr) && wined3d_surface)
01135     {
01136         *ppRenderTarget = wined3d_surface_get_parent(wined3d_surface);
01137         IDirect3DSurface8_AddRef(*ppRenderTarget);
01138         wined3d_surface_decref(wined3d_surface);
01139     }
01140     else
01141     {
01142         FIXME("Call to IWineD3DDevice_GetRenderTarget failed\n");
01143         *ppRenderTarget = NULL;
01144     }
01145     wined3d_mutex_unlock();
01146 
01147     return hr;
01148 }
01149 
01150 static HRESULT WINAPI IDirect3DDevice8Impl_GetDepthStencilSurface(IDirect3DDevice8 *iface,
01151         IDirect3DSurface8 **ppZStencilSurface)
01152 {
01153     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01154     struct wined3d_surface *wined3d_surface;
01155     HRESULT hr;
01156 
01157     TRACE("iface %p, depth_stencil %p.\n", iface, ppZStencilSurface);
01158 
01159     if(ppZStencilSurface == NULL){
01160         return D3DERR_INVALIDCALL;
01161     }
01162 
01163     wined3d_mutex_lock();
01164     hr = wined3d_device_get_depth_stencil(This->wined3d_device, &wined3d_surface);
01165     if (SUCCEEDED(hr))
01166     {
01167         *ppZStencilSurface = wined3d_surface_get_parent(wined3d_surface);
01168         IDirect3DSurface8_AddRef(*ppZStencilSurface);
01169         wined3d_surface_decref(wined3d_surface);
01170     }
01171     else
01172     {
01173         if (hr != WINED3DERR_NOTFOUND)
01174                 FIXME("Call to IWineD3DDevice_GetDepthStencilSurface failed with 0x%08x\n", hr);
01175         *ppZStencilSurface = NULL;
01176     }
01177     wined3d_mutex_unlock();
01178 
01179     return hr;
01180 }
01181 
01182 static HRESULT WINAPI IDirect3DDevice8Impl_BeginScene(IDirect3DDevice8 *iface)
01183 {
01184     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01185     HRESULT hr;
01186 
01187     TRACE("iface %p.\n", iface);
01188 
01189     wined3d_mutex_lock();
01190     hr = wined3d_device_begin_scene(This->wined3d_device);
01191     wined3d_mutex_unlock();
01192 
01193     return hr;
01194 }
01195 
01196 static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice8Impl_EndScene(IDirect3DDevice8 *iface)
01197 {
01198     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01199     HRESULT hr;
01200 
01201     TRACE("iface %p.\n", iface);
01202 
01203     wined3d_mutex_lock();
01204     hr = wined3d_device_end_scene(This->wined3d_device);
01205     wined3d_mutex_unlock();
01206 
01207     return hr;
01208 }
01209 
01210 static HRESULT WINAPI IDirect3DDevice8Impl_Clear(IDirect3DDevice8 *iface, DWORD rect_count,
01211         const D3DRECT *rects, DWORD flags, D3DCOLOR color, float z, DWORD stencil)
01212 {
01213     const struct wined3d_color c =
01214     {
01215         ((color >> 16) & 0xff) / 255.0f,
01216         ((color >>  8) & 0xff) / 255.0f,
01217         (color & 0xff) / 255.0f,
01218         ((color >> 24) & 0xff) / 255.0f,
01219     };
01220     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01221     HRESULT hr;
01222 
01223     TRACE("iface %p, rect_count %u, rects %p, flags %#x, color 0x%08x, z %.8e, stencil %u.\n",
01224             iface, rect_count, rects, flags, color, z, stencil);
01225 
01226     wined3d_mutex_lock();
01227     hr = wined3d_device_clear(This->wined3d_device, rect_count, (const RECT *)rects, flags, &c, z, stencil);
01228     wined3d_mutex_unlock();
01229 
01230     return hr;
01231 }
01232 
01233 static HRESULT WINAPI IDirect3DDevice8Impl_SetTransform(IDirect3DDevice8 *iface,
01234         D3DTRANSFORMSTATETYPE State, const D3DMATRIX *lpMatrix)
01235 {
01236     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01237     HRESULT hr;
01238 
01239     TRACE("iface %p, state %#x, matrix %p.\n", iface, State, lpMatrix);
01240 
01241     /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
01242     wined3d_mutex_lock();
01243     hr = wined3d_device_set_transform(This->wined3d_device, State, (const struct wined3d_matrix *)lpMatrix);
01244     wined3d_mutex_unlock();
01245 
01246     return hr;
01247 }
01248 
01249 static HRESULT WINAPI IDirect3DDevice8Impl_GetTransform(IDirect3DDevice8 *iface,
01250         D3DTRANSFORMSTATETYPE State, D3DMATRIX *pMatrix)
01251 {
01252     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01253     HRESULT hr;
01254 
01255     TRACE("iface %p, state %#x, matrix %p.\n", iface, State, pMatrix);
01256 
01257     /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
01258     wined3d_mutex_lock();
01259     hr = wined3d_device_get_transform(This->wined3d_device, State, (struct wined3d_matrix *)pMatrix);
01260     wined3d_mutex_unlock();
01261 
01262     return hr;
01263 }
01264 
01265 static HRESULT WINAPI IDirect3DDevice8Impl_MultiplyTransform(IDirect3DDevice8 *iface,
01266         D3DTRANSFORMSTATETYPE State, const D3DMATRIX *pMatrix)
01267 {
01268     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01269     HRESULT hr;
01270 
01271     TRACE("iface %p, state %#x, matrix %p.\n", iface, State, pMatrix);
01272 
01273     /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
01274     wined3d_mutex_lock();
01275     hr = wined3d_device_multiply_transform(This->wined3d_device, State, (const struct wined3d_matrix *)pMatrix);
01276     wined3d_mutex_unlock();
01277 
01278     return hr;
01279 }
01280 
01281 static HRESULT WINAPI IDirect3DDevice8Impl_SetViewport(IDirect3DDevice8 *iface,
01282         const D3DVIEWPORT8 *pViewport)
01283 {
01284     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01285     HRESULT hr;
01286 
01287     TRACE("iface %p, viewport %p.\n", iface, pViewport);
01288 
01289     /* Note: D3DVIEWPORT8 is compatible with struct wined3d_viewport. */
01290     wined3d_mutex_lock();
01291     hr = wined3d_device_set_viewport(This->wined3d_device, (const struct wined3d_viewport *)pViewport);
01292     wined3d_mutex_unlock();
01293 
01294     return hr;
01295 }
01296 
01297 static HRESULT WINAPI IDirect3DDevice8Impl_GetViewport(IDirect3DDevice8 *iface,
01298         D3DVIEWPORT8 *pViewport)
01299 {
01300     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01301     HRESULT hr;
01302 
01303     TRACE("iface %p, viewport %p.\n", iface, pViewport);
01304 
01305     /* Note: D3DVIEWPORT8 is compatible with struct wined3d_viewport. */
01306     wined3d_mutex_lock();
01307     hr = wined3d_device_get_viewport(This->wined3d_device, (struct wined3d_viewport *)pViewport);
01308     wined3d_mutex_unlock();
01309 
01310     return hr;
01311 }
01312 
01313 static HRESULT WINAPI IDirect3DDevice8Impl_SetMaterial(IDirect3DDevice8 *iface,
01314         const D3DMATERIAL8 *pMaterial)
01315 {
01316     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01317     HRESULT hr;
01318 
01319     TRACE("iface %p, material %p.\n", iface, pMaterial);
01320 
01321     /* Note: D3DMATERIAL8 is compatible with struct wined3d_material. */
01322     wined3d_mutex_lock();
01323     hr = wined3d_device_set_material(This->wined3d_device, (const struct wined3d_material *)pMaterial);
01324     wined3d_mutex_unlock();
01325 
01326     return hr;
01327 }
01328 
01329 static HRESULT WINAPI IDirect3DDevice8Impl_GetMaterial(IDirect3DDevice8 *iface,
01330         D3DMATERIAL8 *pMaterial)
01331 {
01332     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01333     HRESULT hr;
01334 
01335     TRACE("iface %p, material %p.\n", iface, pMaterial);
01336 
01337     /* Note: D3DMATERIAL8 is compatible with struct wined3d_material. */
01338     wined3d_mutex_lock();
01339     hr = wined3d_device_get_material(This->wined3d_device, (struct wined3d_material *)pMaterial);
01340     wined3d_mutex_unlock();
01341 
01342     return hr;
01343 }
01344 
01345 static HRESULT WINAPI IDirect3DDevice8Impl_SetLight(IDirect3DDevice8 *iface, DWORD Index,
01346         const D3DLIGHT8 *pLight)
01347 {
01348     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01349     HRESULT hr;
01350 
01351     TRACE("iface %p, index %u, light %p.\n", iface, Index, pLight);
01352 
01353     /* Note: D3DLIGHT8 is compatible with struct wined3d_light. */
01354     wined3d_mutex_lock();
01355     hr = wined3d_device_set_light(This->wined3d_device, Index, (const struct wined3d_light *)pLight);
01356     wined3d_mutex_unlock();
01357 
01358     return hr;
01359 }
01360 
01361 static HRESULT WINAPI IDirect3DDevice8Impl_GetLight(IDirect3DDevice8 *iface, DWORD Index,
01362         D3DLIGHT8 *pLight)
01363 {
01364     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01365     HRESULT hr;
01366 
01367     TRACE("iface %p, index %u, light %p.\n", iface, Index, pLight);
01368 
01369     /* Note: D3DLIGHT8 is compatible with struct wined3d_light. */
01370     wined3d_mutex_lock();
01371     hr = wined3d_device_get_light(This->wined3d_device, Index, (struct wined3d_light *)pLight);
01372     wined3d_mutex_unlock();
01373 
01374     return hr;
01375 }
01376 
01377 static HRESULT WINAPI IDirect3DDevice8Impl_LightEnable(IDirect3DDevice8 *iface, DWORD Index,
01378         BOOL Enable)
01379 {
01380     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01381     HRESULT hr;
01382 
01383     TRACE("iface %p, index %u, enable %#x.\n", iface, Index, Enable);
01384 
01385     wined3d_mutex_lock();
01386     hr = wined3d_device_set_light_enable(This->wined3d_device, Index, Enable);
01387     wined3d_mutex_unlock();
01388 
01389     return hr;
01390 }
01391 
01392 static HRESULT WINAPI IDirect3DDevice8Impl_GetLightEnable(IDirect3DDevice8 *iface, DWORD Index,
01393         BOOL *pEnable)
01394 {
01395     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01396     HRESULT hr;
01397 
01398     TRACE("iface %p, index %u, enable %p.\n", iface, Index, pEnable);
01399 
01400     wined3d_mutex_lock();
01401     hr = wined3d_device_get_light_enable(This->wined3d_device, Index, pEnable);
01402     wined3d_mutex_unlock();
01403 
01404     return hr;
01405 }
01406 
01407 static HRESULT WINAPI IDirect3DDevice8Impl_SetClipPlane(IDirect3DDevice8 *iface, DWORD Index,
01408         const float *pPlane)
01409 {
01410     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01411     HRESULT hr;
01412 
01413     TRACE("iface %p, index %u, plane %p.\n", iface, Index, pPlane);
01414 
01415     wined3d_mutex_lock();
01416     hr = wined3d_device_set_clip_plane(This->wined3d_device, Index, pPlane);
01417     wined3d_mutex_unlock();
01418 
01419     return hr;
01420 }
01421 
01422 static HRESULT WINAPI IDirect3DDevice8Impl_GetClipPlane(IDirect3DDevice8 *iface, DWORD Index,
01423         float *pPlane)
01424 {
01425     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01426     HRESULT hr;
01427 
01428     TRACE("iface %p, index %u, plane %p.\n", iface, Index, pPlane);
01429 
01430     wined3d_mutex_lock();
01431     hr = wined3d_device_get_clip_plane(This->wined3d_device, Index, pPlane);
01432     wined3d_mutex_unlock();
01433 
01434     return hr;
01435 }
01436 
01437 static HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(IDirect3DDevice8 *iface,
01438         D3DRENDERSTATETYPE State, DWORD Value)
01439 {
01440     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01441     HRESULT hr;
01442 
01443     TRACE("iface %p, state %#x, value %#x.\n", iface, State, Value);
01444 
01445     wined3d_mutex_lock();
01446     switch (State)
01447     {
01448         case D3DRS_ZBIAS:
01449             hr = wined3d_device_set_render_state(This->wined3d_device, WINED3D_RS_DEPTHBIAS, Value);
01450             break;
01451 
01452         default:
01453             hr = wined3d_device_set_render_state(This->wined3d_device, State, Value);
01454     }
01455     wined3d_mutex_unlock();
01456 
01457     return hr;
01458 }
01459 
01460 static HRESULT WINAPI IDirect3DDevice8Impl_GetRenderState(IDirect3DDevice8 *iface,
01461         D3DRENDERSTATETYPE State, DWORD *pValue)
01462 {
01463     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01464     HRESULT hr;
01465 
01466     TRACE("iface %p, state %#x, value %p.\n", iface, State, pValue);
01467 
01468     wined3d_mutex_lock();
01469     switch (State)
01470     {
01471         case D3DRS_ZBIAS:
01472             hr = wined3d_device_get_render_state(This->wined3d_device, WINED3D_RS_DEPTHBIAS, pValue);
01473             break;
01474 
01475         default:
01476             hr = wined3d_device_get_render_state(This->wined3d_device, State, pValue);
01477     }
01478     wined3d_mutex_unlock();
01479 
01480     return hr;
01481 }
01482 
01483 static HRESULT WINAPI IDirect3DDevice8Impl_BeginStateBlock(IDirect3DDevice8 *iface)
01484 {
01485     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01486     HRESULT hr;
01487 
01488     TRACE("iface %p.\n", iface);
01489 
01490     wined3d_mutex_lock();
01491     hr = wined3d_device_begin_stateblock(This->wined3d_device);
01492     wined3d_mutex_unlock();
01493 
01494     return hr;
01495 }
01496 
01497 static HRESULT WINAPI IDirect3DDevice8Impl_EndStateBlock(IDirect3DDevice8 *iface, DWORD *pToken)
01498 {
01499     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01500     struct wined3d_stateblock *stateblock;
01501     HRESULT hr;
01502 
01503     TRACE("iface %p, token %p.\n", iface, pToken);
01504 
01505     /* Tell wineD3D to endstateblock before anything else (in case we run out
01506      * of memory later and cause locking problems)
01507      */
01508     wined3d_mutex_lock();
01509     hr = wined3d_device_end_stateblock(This->wined3d_device, &stateblock);
01510     if (FAILED(hr))
01511     {
01512         WARN("IWineD3DDevice_EndStateBlock returned an error\n");
01513         wined3d_mutex_unlock();
01514         return hr;
01515     }
01516 
01517     *pToken = d3d8_allocate_handle(&This->handle_table, stateblock, D3D8_HANDLE_SB);
01518     wined3d_mutex_unlock();
01519 
01520     if (*pToken == D3D8_INVALID_HANDLE)
01521     {
01522         ERR("Failed to create a handle\n");
01523         wined3d_mutex_lock();
01524         wined3d_stateblock_decref(stateblock);
01525         wined3d_mutex_unlock();
01526         return E_FAIL;
01527     }
01528     ++*pToken;
01529 
01530     TRACE("Returning %#x (%p).\n", *pToken, stateblock);
01531 
01532     return hr;
01533 }
01534 
01535 static HRESULT WINAPI IDirect3DDevice8Impl_ApplyStateBlock(IDirect3DDevice8 *iface, DWORD Token)
01536 {
01537     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01538     struct wined3d_stateblock *stateblock;
01539     HRESULT hr;
01540 
01541     TRACE("iface %p, token %#x.\n", iface, Token);
01542 
01543     if (!Token) return D3D_OK;
01544 
01545     wined3d_mutex_lock();
01546     stateblock = d3d8_get_object(&This->handle_table, Token - 1, D3D8_HANDLE_SB);
01547     if (!stateblock)
01548     {
01549         WARN("Invalid handle (%#x) passed.\n", Token);
01550         wined3d_mutex_unlock();
01551         return D3DERR_INVALIDCALL;
01552     }
01553     hr = wined3d_stateblock_apply(stateblock);
01554     wined3d_mutex_unlock();
01555 
01556     return hr;
01557 }
01558 
01559 static HRESULT WINAPI IDirect3DDevice8Impl_CaptureStateBlock(IDirect3DDevice8 *iface, DWORD Token)
01560 {
01561     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01562     struct wined3d_stateblock *stateblock;
01563     HRESULT hr;
01564 
01565     TRACE("iface %p, token %#x.\n", iface, Token);
01566 
01567     wined3d_mutex_lock();
01568     stateblock = d3d8_get_object(&This->handle_table, Token - 1, D3D8_HANDLE_SB);
01569     if (!stateblock)
01570     {
01571         WARN("Invalid handle (%#x) passed.\n", Token);
01572         wined3d_mutex_unlock();
01573         return D3DERR_INVALIDCALL;
01574     }
01575     hr = wined3d_stateblock_capture(stateblock);
01576     wined3d_mutex_unlock();
01577 
01578     return hr;
01579 }
01580 
01581 static HRESULT WINAPI IDirect3DDevice8Impl_DeleteStateBlock(IDirect3DDevice8 *iface, DWORD Token)
01582 {
01583     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01584     struct wined3d_stateblock *stateblock;
01585 
01586     TRACE("iface %p, token %#x.\n", iface, Token);
01587 
01588     wined3d_mutex_lock();
01589     stateblock = d3d8_free_handle(&This->handle_table, Token - 1, D3D8_HANDLE_SB);
01590 
01591     if (!stateblock)
01592     {
01593         WARN("Invalid handle (%#x) passed.\n", Token);
01594         wined3d_mutex_unlock();
01595         return D3DERR_INVALIDCALL;
01596     }
01597 
01598     if (wined3d_stateblock_decref(stateblock))
01599     {
01600         ERR("Stateblock %p has references left, this shouldn't happen.\n", stateblock);
01601     }
01602     wined3d_mutex_unlock();
01603 
01604     return D3D_OK;
01605 }
01606 
01607 static HRESULT WINAPI IDirect3DDevice8Impl_CreateStateBlock(IDirect3DDevice8 *iface,
01608         D3DSTATEBLOCKTYPE Type, DWORD *handle)
01609 {
01610     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01611     struct wined3d_stateblock *stateblock;
01612     HRESULT hr;
01613 
01614     TRACE("iface %p, type %#x, handle %p.\n", iface, Type, handle);
01615 
01616     if (Type != D3DSBT_ALL
01617             && Type != D3DSBT_PIXELSTATE
01618             && Type != D3DSBT_VERTEXSTATE)
01619     {
01620         WARN("Unexpected stateblock type, returning D3DERR_INVALIDCALL\n");
01621         return D3DERR_INVALIDCALL;
01622     }
01623 
01624     wined3d_mutex_lock();
01625     hr = wined3d_stateblock_create(This->wined3d_device, (enum wined3d_stateblock_type)Type, &stateblock);
01626     if (FAILED(hr))
01627     {
01628         wined3d_mutex_unlock();
01629         ERR("IWineD3DDevice_CreateStateBlock failed, hr %#x\n", hr);
01630         return hr;
01631     }
01632 
01633     *handle = d3d8_allocate_handle(&This->handle_table, stateblock, D3D8_HANDLE_SB);
01634     wined3d_mutex_unlock();
01635 
01636     if (*handle == D3D8_INVALID_HANDLE)
01637     {
01638         ERR("Failed to allocate a handle.\n");
01639         wined3d_mutex_lock();
01640         wined3d_stateblock_decref(stateblock);
01641         wined3d_mutex_unlock();
01642         return E_FAIL;
01643     }
01644     ++*handle;
01645 
01646     TRACE("Returning %#x (%p).\n", *handle, stateblock);
01647 
01648     return hr;
01649 }
01650 
01651 static HRESULT WINAPI IDirect3DDevice8Impl_SetClipStatus(IDirect3DDevice8 *iface,
01652         const D3DCLIPSTATUS8 *pClipStatus)
01653 {
01654     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01655     HRESULT hr;
01656 
01657     TRACE("iface %p, clip_status %p.\n", iface, pClipStatus);
01658     /* FIXME: Verify that D3DCLIPSTATUS8 ~= struct wined3d_clip_status. */
01659 
01660     wined3d_mutex_lock();
01661     hr = wined3d_device_set_clip_status(This->wined3d_device, (const struct wined3d_clip_status *)pClipStatus);
01662     wined3d_mutex_unlock();
01663 
01664     return hr;
01665 }
01666 
01667 static HRESULT WINAPI IDirect3DDevice8Impl_GetClipStatus(IDirect3DDevice8 *iface,
01668         D3DCLIPSTATUS8 *pClipStatus)
01669 {
01670     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01671     HRESULT hr;
01672 
01673     TRACE("iface %p, clip_status %p.\n", iface, pClipStatus);
01674 
01675     wined3d_mutex_lock();
01676     hr = wined3d_device_get_clip_status(This->wined3d_device, (struct wined3d_clip_status *)pClipStatus);
01677     wined3d_mutex_unlock();
01678 
01679     return hr;
01680 }
01681 
01682 static HRESULT WINAPI IDirect3DDevice8Impl_GetTexture(IDirect3DDevice8 *iface,
01683         DWORD Stage, IDirect3DBaseTexture8 **ppTexture)
01684 {
01685     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01686     struct wined3d_texture *wined3d_texture;
01687     HRESULT hr;
01688 
01689     TRACE("iface %p, stage %u, texture %p.\n", iface, Stage, ppTexture);
01690 
01691     if(ppTexture == NULL){
01692         return D3DERR_INVALIDCALL;
01693     }
01694 
01695     wined3d_mutex_lock();
01696     hr = wined3d_device_get_texture(This->wined3d_device, Stage, &wined3d_texture);
01697     if (FAILED(hr))
01698     {
01699         WARN("Failed to get texture for stage %u, hr %#x.\n", Stage, hr);
01700         wined3d_mutex_unlock();
01701         *ppTexture = NULL;
01702         return hr;
01703     }
01704 
01705     if (wined3d_texture)
01706     {
01707         *ppTexture = wined3d_texture_get_parent(wined3d_texture);
01708         IDirect3DBaseTexture8_AddRef(*ppTexture);
01709         wined3d_texture_decref(wined3d_texture);
01710     }
01711     else
01712     {
01713         *ppTexture = NULL;
01714     }
01715     wined3d_mutex_unlock();
01716 
01717     return D3D_OK;
01718 }
01719 
01720 static HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(IDirect3DDevice8 *iface, DWORD Stage,
01721         IDirect3DBaseTexture8 *pTexture)
01722 {
01723     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01724     HRESULT hr;
01725 
01726     TRACE("iface %p, stage %u, texture %p.\n", iface, Stage, pTexture);
01727 
01728     wined3d_mutex_lock();
01729     hr = wined3d_device_set_texture(This->wined3d_device, Stage,
01730             pTexture ? ((IDirect3DBaseTexture8Impl *)pTexture)->wined3d_texture : NULL);
01731     wined3d_mutex_unlock();
01732 
01733     return hr;
01734 }
01735 
01736 static const struct tss_lookup
01737 {
01738     BOOL sampler_state;
01739     enum wined3d_texture_stage_state state;
01740 }
01741 tss_lookup[] =
01742 {
01743     {FALSE, WINED3D_TSS_INVALID},                   /*  0, unused */
01744     {FALSE, WINED3D_TSS_COLOR_OP},                  /*  1, D3DTSS_COLOROP */
01745     {FALSE, WINED3D_TSS_COLOR_ARG1},                /*  2, D3DTSS_COLORARG1 */
01746     {FALSE, WINED3D_TSS_COLOR_ARG2},                /*  3, D3DTSS_COLORARG2 */
01747     {FALSE, WINED3D_TSS_ALPHA_OP},                  /*  4, D3DTSS_ALPHAOP */
01748     {FALSE, WINED3D_TSS_ALPHA_ARG1},                /*  5, D3DTSS_ALPHAARG1 */
01749     {FALSE, WINED3D_TSS_ALPHA_ARG2},                /*  6, D3DTSS_ALPHAARG2 */
01750     {FALSE, WINED3D_TSS_BUMPENV_MAT00},             /*  7, D3DTSS_BUMPENVMAT00 */
01751     {FALSE, WINED3D_TSS_BUMPENV_MAT01},             /*  8, D3DTSS_BUMPENVMAT01 */
01752     {FALSE, WINED3D_TSS_BUMPENV_MAT10},             /*  9, D3DTSS_BUMPENVMAT10 */
01753     {FALSE, WINED3D_TSS_BUMPENV_MAT11},             /* 10, D3DTSS_BUMPENVMAT11 */
01754     {FALSE, WINED3D_TSS_TEXCOORD_INDEX},            /* 11, D3DTSS_TEXCOORDINDEX */
01755     {FALSE, WINED3D_TSS_INVALID},                   /* 12, unused */
01756     {TRUE,  WINED3D_SAMP_ADDRESS_U},                /* 13, D3DTSS_ADDRESSU */
01757     {TRUE,  WINED3D_SAMP_ADDRESS_V},                /* 14, D3DTSS_ADDRESSV */
01758     {TRUE,  WINED3D_SAMP_BORDER_COLOR},             /* 15, D3DTSS_BORDERCOLOR */
01759     {TRUE,  WINED3D_SAMP_MAG_FILTER},               /* 16, D3DTSS_MAGFILTER */
01760     {TRUE,  WINED3D_SAMP_MIN_FILTER},               /* 17, D3DTSS_MINFILTER */
01761     {TRUE,  WINED3D_SAMP_MIP_FILTER},               /* 18, D3DTSS_MIPFILTER */
01762     {TRUE,  WINED3D_SAMP_MIPMAP_LOD_BIAS},          /* 19, D3DTSS_MIPMAPLODBIAS */
01763     {TRUE,  WINED3D_SAMP_MAX_MIP_LEVEL},            /* 20, D3DTSS_MAXMIPLEVEL */
01764     {TRUE,  WINED3D_SAMP_MAX_ANISOTROPY},           /* 21, D3DTSS_MAXANISOTROPY */
01765     {FALSE, WINED3D_TSS_BUMPENV_LSCALE},            /* 22, D3DTSS_BUMPENVLSCALE */
01766     {FALSE, WINED3D_TSS_BUMPENV_LOFFSET},           /* 23, D3DTSS_BUMPENVLOFFSET */
01767     {FALSE, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS},   /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
01768     {TRUE,  WINED3D_SAMP_ADDRESS_W},                /* 25, D3DTSS_ADDRESSW */
01769     {FALSE, WINED3D_TSS_COLOR_ARG0},                /* 26, D3DTSS_COLORARG0 */
01770     {FALSE, WINED3D_TSS_ALPHA_ARG0},                /* 27, D3DTSS_ALPHAARG0 */
01771     {FALSE, WINED3D_TSS_RESULT_ARG},                /* 28, D3DTSS_RESULTARG */
01772 };
01773 
01774 static HRESULT  WINAPI  IDirect3DDevice8Impl_GetTextureStageState(IDirect3DDevice8 *iface,
01775         DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD *pValue)
01776 {
01777     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01778     const struct tss_lookup *l;
01779     HRESULT hr;
01780 
01781     TRACE("iface %p, stage %u, state %#x, value %p.\n", iface, Stage, Type, pValue);
01782 
01783     if (Type >= sizeof(tss_lookup) / sizeof(*tss_lookup))
01784     {
01785         WARN("Invalid Type %#x passed.\n", Type);
01786         return D3D_OK;
01787     }
01788 
01789     l = &tss_lookup[Type];
01790 
01791     wined3d_mutex_lock();
01792     if (l->sampler_state)
01793         hr = wined3d_device_get_sampler_state(This->wined3d_device, Stage, l->state, pValue);
01794     else
01795         hr = wined3d_device_get_texture_stage_state(This->wined3d_device, Stage, l->state, pValue);
01796     wined3d_mutex_unlock();
01797 
01798     return hr;
01799 }
01800 
01801 static HRESULT WINAPI IDirect3DDevice8Impl_SetTextureStageState(IDirect3DDevice8 *iface,
01802         DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value)
01803 {
01804     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01805     const struct tss_lookup *l;
01806     HRESULT hr;
01807 
01808     TRACE("iface %p, stage %u, state %#x, value %#x.\n", iface, Stage, Type, Value);
01809 
01810     if (Type >= sizeof(tss_lookup) / sizeof(*tss_lookup))
01811     {
01812         WARN("Invalid Type %#x passed.\n", Type);
01813         return D3D_OK;
01814     }
01815 
01816     l = &tss_lookup[Type];
01817 
01818     wined3d_mutex_lock();
01819     if (l->sampler_state)
01820         hr = wined3d_device_set_sampler_state(This->wined3d_device, Stage, l->state, Value);
01821     else
01822         hr = wined3d_device_set_texture_stage_state(This->wined3d_device, Stage, l->state, Value);
01823     wined3d_mutex_unlock();
01824 
01825     return hr;
01826 }
01827 
01828 static HRESULT WINAPI IDirect3DDevice8Impl_ValidateDevice(IDirect3DDevice8 *iface,
01829         DWORD *pNumPasses)
01830 {
01831     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01832     HRESULT hr;
01833 
01834     TRACE("iface %p, pass_count %p.\n", iface, pNumPasses);
01835 
01836     wined3d_mutex_lock();
01837     hr = wined3d_device_validate_device(This->wined3d_device, pNumPasses);
01838     wined3d_mutex_unlock();
01839 
01840     return hr;
01841 }
01842 
01843 static HRESULT WINAPI IDirect3DDevice8Impl_GetInfo(IDirect3DDevice8 *iface,
01844         DWORD info_id, void *info, DWORD info_size)
01845 {
01846     FIXME("iface %p, info_id %#x, info %p, info_size %u stub!\n", iface, info_id, info, info_size);
01847 
01848     return D3D_OK;
01849 }
01850 
01851 static HRESULT WINAPI IDirect3DDevice8Impl_SetPaletteEntries(IDirect3DDevice8 *iface,
01852         UINT PaletteNumber, const PALETTEENTRY *pEntries)
01853 {
01854     FIXME("iface %p, palette_idx %u, entries %p unimplemented\n", iface, PaletteNumber, pEntries);
01855 
01856     /* GPUs stopped supporting palettized textures with the Shader Model 1 generation. Wined3d
01857      * does not have a d3d8/9-style palette API */
01858 
01859     return D3DERR_INVALIDCALL;
01860 }
01861 
01862 static HRESULT WINAPI IDirect3DDevice8Impl_GetPaletteEntries(IDirect3DDevice8 *iface,
01863         UINT PaletteNumber, PALETTEENTRY *pEntries)
01864 {
01865     FIXME("iface %p, palette_idx %u, entries %p unimplemented.\n", iface, PaletteNumber, pEntries);
01866 
01867     return D3DERR_INVALIDCALL;
01868 }
01869 
01870 static HRESULT WINAPI IDirect3DDevice8Impl_SetCurrentTexturePalette(IDirect3DDevice8 *iface,
01871         UINT PaletteNumber)
01872 {
01873     FIXME("iface %p, palette_idx %u unimplemented.\n", iface, PaletteNumber);
01874 
01875     return D3DERR_INVALIDCALL;
01876 }
01877 
01878 static HRESULT  WINAPI  IDirect3DDevice8Impl_GetCurrentTexturePalette(IDirect3DDevice8 *iface,
01879         UINT *PaletteNumber)
01880 {
01881     FIXME("iface %p, palette_idx %p unimplemented.\n", iface, PaletteNumber);
01882 
01883     return D3DERR_INVALIDCALL;
01884 }
01885 
01886 static HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitive(IDirect3DDevice8 *iface,
01887         D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount)
01888 {
01889     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01890     HRESULT hr;
01891 
01892     TRACE("iface %p, primitive_type %#x, start_vertex %u, primitive_count %u.\n",
01893             iface, PrimitiveType, StartVertex, PrimitiveCount);
01894 
01895     wined3d_mutex_lock();
01896     wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType);
01897     hr = wined3d_device_draw_primitive(This->wined3d_device, StartVertex,
01898             vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount));
01899     wined3d_mutex_unlock();
01900 
01901     return hr;
01902 }
01903 
01904 static HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitive(IDirect3DDevice8 *iface,
01905         D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertices, UINT startIndex,
01906         UINT primCount)
01907 {
01908     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01909     HRESULT hr;
01910 
01911     TRACE("iface %p, primitive_type %#x, min_vertex_idx %u, vertex_count %u, start_idx %u, primitive_count %u.\n",
01912             iface, PrimitiveType, MinVertexIndex, NumVertices, startIndex, primCount);
01913 
01914     wined3d_mutex_lock();
01915     wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType);
01916     hr = wined3d_device_draw_indexed_primitive(This->wined3d_device, startIndex,
01917             vertex_count_from_primitive_count(PrimitiveType, primCount));
01918     wined3d_mutex_unlock();
01919 
01920     return hr;
01921 }
01922 
01923 static HRESULT WINAPI IDirect3DDevice8Impl_DrawPrimitiveUP(IDirect3DDevice8 *iface,
01924         D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, const void *pVertexStreamZeroData,
01925         UINT VertexStreamZeroStride)
01926 {
01927     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01928     HRESULT hr;
01929 
01930     TRACE("iface %p, primitive_type %#x, primitive_count %u, data %p, stride %u.\n",
01931             iface, PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride);
01932 
01933     wined3d_mutex_lock();
01934     wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType);
01935     hr = wined3d_device_draw_primitive_up(This->wined3d_device,
01936             vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount),
01937             pVertexStreamZeroData, VertexStreamZeroStride);
01938     wined3d_mutex_unlock();
01939 
01940     return hr;
01941 }
01942 
01943 static HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitiveUP(IDirect3DDevice8 *iface,
01944         D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertexIndices,
01945         UINT PrimitiveCount, const void *pIndexData, D3DFORMAT IndexDataFormat,
01946         const void *pVertexStreamZeroData, UINT VertexStreamZeroStride)
01947 {
01948     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01949     HRESULT hr;
01950 
01951     TRACE("iface %p, primitive_type %#x, min_vertex_idx %u, index_count %u, primitive_count %u,\n"
01952             "index_data %p, index_format %#x, vertex_data %p, vertex_stride %u.\n",
01953             iface, PrimitiveType, MinVertexIndex, NumVertexIndices, PrimitiveCount,
01954             pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride);
01955 
01956     wined3d_mutex_lock();
01957     wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType);
01958     hr = wined3d_device_draw_indexed_primitive_up(This->wined3d_device,
01959             vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount), pIndexData,
01960             wined3dformat_from_d3dformat(IndexDataFormat), pVertexStreamZeroData, VertexStreamZeroStride);
01961     wined3d_mutex_unlock();
01962 
01963     return hr;
01964 }
01965 
01966 static HRESULT WINAPI IDirect3DDevice8Impl_ProcessVertices(IDirect3DDevice8 *iface,
01967         UINT SrcStartIndex, UINT DestIndex, UINT VertexCount, IDirect3DVertexBuffer8 *pDestBuffer,
01968         DWORD Flags)
01969 {
01970     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01971     IDirect3DVertexBuffer8Impl *dest = unsafe_impl_from_IDirect3DVertexBuffer8(pDestBuffer);
01972     HRESULT hr;
01973 
01974     TRACE("iface %p, src_start_idx %u, dst_idx %u, vertex_count %u, dst_buffer %p, flags %#x.\n",
01975             iface, SrcStartIndex, DestIndex, VertexCount, pDestBuffer, Flags);
01976 
01977     wined3d_mutex_lock();
01978     hr = wined3d_device_process_vertices(This->wined3d_device, SrcStartIndex, DestIndex,
01979             VertexCount, dest->wineD3DVertexBuffer, NULL, Flags, dest->fvf);
01980     wined3d_mutex_unlock();
01981 
01982     return hr;
01983 }
01984 
01985 static HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(IDirect3DDevice8 *iface,
01986         const DWORD *declaration, const DWORD *byte_code, DWORD *shader, DWORD usage)
01987 {
01988     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
01989     IDirect3DVertexShader8Impl *object;
01990     DWORD shader_handle;
01991     DWORD handle;
01992     HRESULT hr;
01993 
01994     TRACE("iface %p, declaration %p, byte_code %p, shader %p, usage %#x.\n",
01995             iface, declaration, byte_code, shader, usage);
01996 
01997     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
01998     if (!object)
01999     {
02000         ERR("Failed to allocate vertex shader memory.\n");
02001         *shader = 0;
02002         return E_OUTOFMEMORY;
02003     }
02004 
02005     wined3d_mutex_lock();
02006     handle = d3d8_allocate_handle(&This->handle_table, object, D3D8_HANDLE_VS);
02007     wined3d_mutex_unlock();
02008     if (handle == D3D8_INVALID_HANDLE)
02009     {
02010         ERR("Failed to allocate vertex shader handle.\n");
02011         HeapFree(GetProcessHeap(), 0, object);
02012         *shader = 0;
02013         return E_OUTOFMEMORY;
02014     }
02015 
02016     shader_handle = handle + VS_HIGHESTFIXEDFXF + 1;
02017 
02018     hr = vertexshader_init(object, This, declaration, byte_code, shader_handle, usage);
02019     if (FAILED(hr))
02020     {
02021         WARN("Failed to initialize vertex shader, hr %#x.\n", hr);
02022         wined3d_mutex_lock();
02023         d3d8_free_handle(&This->handle_table, handle, D3D8_HANDLE_VS);
02024         wined3d_mutex_unlock();
02025         HeapFree(GetProcessHeap(), 0, object);
02026         *shader = 0;
02027         return hr;
02028     }
02029 
02030     TRACE("Created vertex shader %p (handle %#x).\n", object, shader_handle);
02031     *shader = shader_handle;
02032 
02033     return D3D_OK;
02034 }
02035 
02036 static IDirect3DVertexDeclaration8Impl *IDirect3DDevice8Impl_FindDecl(IDirect3DDevice8Impl *This, DWORD fvf)
02037 {
02038     IDirect3DVertexDeclaration8Impl *d3d8_declaration;
02039     HRESULT hr;
02040     int p, low, high; /* deliberately signed */
02041     struct FvfToDecl *convertedDecls = This->decls;
02042 
02043     TRACE("Searching for declaration for fvf %08x... ", fvf);
02044 
02045     low = 0;
02046     high = This->numConvertedDecls - 1;
02047     while(low <= high) {
02048         p = (low + high) >> 1;
02049         TRACE("%d ", p);
02050         if(convertedDecls[p].fvf == fvf) {
02051             TRACE("found %p\n", convertedDecls[p].decl);
02052             return (IDirect3DVertexDeclaration8Impl *)convertedDecls[p].decl;
02053         } else if(convertedDecls[p].fvf < fvf) {
02054             low = p + 1;
02055         } else {
02056             high = p - 1;
02057         }
02058     }
02059     TRACE("not found. Creating and inserting at position %d.\n", low);
02060 
02061     d3d8_declaration = HeapAlloc(GetProcessHeap(), 0, sizeof(*d3d8_declaration));
02062     if (!d3d8_declaration)
02063     {
02064         ERR("Memory allocation failed.\n");
02065         return NULL;
02066     }
02067 
02068     hr = vertexdeclaration_init_fvf(d3d8_declaration, This, fvf);
02069     if (FAILED(hr))
02070     {
02071         WARN("Failed to initialize vertex declaration, hr %#x.\n", hr);
02072         HeapFree(GetProcessHeap(), 0, d3d8_declaration);
02073         return NULL;
02074     }
02075 
02076     if(This->declArraySize == This->numConvertedDecls) {
02077         int grow = This->declArraySize / 2;
02078         convertedDecls = HeapReAlloc(GetProcessHeap(), 0, convertedDecls,
02079                                      sizeof(convertedDecls[0]) * (This->numConvertedDecls + grow));
02080         if(!convertedDecls) {
02081             /* This will destroy it */
02082             IDirect3DVertexDeclaration8_Release((IDirect3DVertexDeclaration8 *)d3d8_declaration);
02083             return NULL;
02084         }
02085         This->decls = convertedDecls;
02086         This->declArraySize += grow;
02087     }
02088 
02089     memmove(convertedDecls + low + 1, convertedDecls + low, sizeof(convertedDecls[0]) * (This->numConvertedDecls - low));
02090     convertedDecls[low].decl = (IDirect3DVertexDeclaration8 *)d3d8_declaration;
02091     convertedDecls[low].fvf = fvf;
02092     This->numConvertedDecls++;
02093 
02094     TRACE("Returning %p. %u decls in array\n", d3d8_declaration, This->numConvertedDecls);
02095     return d3d8_declaration;
02096 }
02097 
02098 static HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShader(IDirect3DDevice8 *iface, DWORD pShader)
02099 {
02100     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
02101     IDirect3DVertexShader8Impl *shader;
02102     HRESULT hr;
02103 
02104     TRACE("iface %p, shader %#x.\n", iface, pShader);
02105 
02106     if (VS_HIGHESTFIXEDFXF >= pShader) {
02107         TRACE("Setting FVF, %#x\n", pShader);
02108 
02109         wined3d_mutex_lock();
02110         wined3d_device_set_vertex_declaration(This->wined3d_device,
02111                 IDirect3DDevice8Impl_FindDecl(This, pShader)->wined3d_vertex_declaration);
02112         wined3d_device_set_vertex_shader(This->wined3d_device, NULL);
02113         wined3d_mutex_unlock();
02114 
02115         return D3D_OK;
02116     }
02117 
02118     TRACE("Setting shader\n");
02119 
02120     wined3d_mutex_lock();
02121     shader = d3d8_get_object(&This->handle_table, pShader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_VS);
02122     if (!shader)
02123     {
02124         WARN("Invalid handle (%#x) passed.\n", pShader);
02125         wined3d_mutex_unlock();
02126 
02127         return D3DERR_INVALIDCALL;
02128     }
02129 
02130     hr = wined3d_device_set_vertex_declaration(This->wined3d_device,
02131             ((IDirect3DVertexDeclaration8Impl *)shader->vertex_declaration)->wined3d_vertex_declaration);
02132     if (SUCCEEDED(hr))
02133         hr = wined3d_device_set_vertex_shader(This->wined3d_device, shader->wined3d_shader);
02134     wined3d_mutex_unlock();
02135 
02136     TRACE("Returning hr %#x\n", hr);
02137 
02138     return hr;
02139 }
02140 
02141 static HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShader(IDirect3DDevice8 *iface, DWORD *ppShader)
02142 {
02143     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
02144     struct wined3d_vertex_declaration *wined3d_declaration;
02145     IDirect3DVertexDeclaration8 *d3d8_declaration;
02146     HRESULT hr;
02147 
02148     TRACE("iface %p, shader %p.\n", iface, ppShader);
02149 
02150     wined3d_mutex_lock();
02151     hr = wined3d_device_get_vertex_declaration(This->wined3d_device, &wined3d_declaration);
02152     if (FAILED(hr))
02153     {
02154         wined3d_mutex_unlock();
02155         WARN("(%p) : Call to IWineD3DDevice_GetVertexDeclaration failed %#x (device %p)\n",
02156                 This, hr, This->wined3d_device);
02157         return hr;
02158     }
02159 
02160     if (!wined3d_declaration)
02161     {
02162         wined3d_mutex_unlock();
02163         *ppShader = 0;
02164         return D3D_OK;
02165     }
02166 
02167     d3d8_declaration = wined3d_vertex_declaration_get_parent(wined3d_declaration);
02168     wined3d_vertex_declaration_decref(wined3d_declaration);
02169     wined3d_mutex_unlock();
02170     *ppShader = ((IDirect3DVertexDeclaration8Impl *)d3d8_declaration)->shader_handle;
02171 
02172     TRACE("(%p) : returning %#x\n", This, *ppShader);
02173 
02174     return hr;
02175 }
02176 
02177 static HRESULT WINAPI IDirect3DDevice8Impl_DeleteVertexShader(IDirect3DDevice8 *iface, DWORD pShader)
02178 {
02179     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
02180     IDirect3DVertexShader8Impl *shader;
02181     struct wined3d_shader *cur;
02182 
02183     TRACE("iface %p, shader %#x.\n", iface, pShader);
02184 
02185     wined3d_mutex_lock();
02186     shader = d3d8_free_handle(&This->handle_table, pShader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_VS);
02187     if (!shader)
02188     {
02189         WARN("Invalid handle (%#x) passed.\n", pShader);
02190         wined3d_mutex_unlock();
02191 
02192         return D3DERR_INVALIDCALL;
02193     }
02194 
02195     cur = wined3d_device_get_vertex_shader(This->wined3d_device);
02196     if (cur)
02197     {
02198         if (cur == shader->wined3d_shader)
02199             IDirect3DDevice8_SetVertexShader(iface, 0);
02200         wined3d_shader_decref(cur);
02201     }
02202 
02203     wined3d_mutex_unlock();
02204 
02205     if (IDirect3DVertexShader8_Release(&shader->IDirect3DVertexShader8_iface))
02206     {
02207         ERR("Shader %p has references left, this shouldn't happen.\n", shader);
02208     }
02209 
02210     return D3D_OK;
02211 }
02212 
02213 static HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShaderConstant(IDirect3DDevice8 *iface,
02214         DWORD Register, const void *pConstantData, DWORD ConstantCount)
02215 {
02216     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
02217     HRESULT hr;
02218 
02219     TRACE("iface %p, register %u, data %p, count %u.\n",
02220             iface, Register, pConstantData, ConstantCount);
02221 
02222     if(Register + ConstantCount > D3D8_MAX_VERTEX_SHADER_CONSTANTF) {
02223         WARN("Trying to access %u constants, but d3d8 only supports %u\n",
02224              Register + ConstantCount, D3D8_MAX_VERTEX_SHADER_CONSTANTF);
02225         return D3DERR_INVALIDCALL;
02226     }
02227 
02228     wined3d_mutex_lock();
02229     hr = wined3d_device_set_vs_consts_f(This->wined3d_device, Register, pConstantData, ConstantCount);
02230     wined3d_mutex_unlock();
02231 
02232     return hr;
02233 }
02234 
02235 static HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderConstant(IDirect3DDevice8 *iface,
02236         DWORD Register, void *pConstantData, DWORD ConstantCount)
02237 {
02238     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
02239     HRESULT hr;
02240 
02241     TRACE("iface %p, register %u, data %p, count %u.\n",
02242             iface, Register, pConstantData, ConstantCount);
02243 
02244     if(Register + ConstantCount > D3D8_MAX_VERTEX_SHADER_CONSTANTF) {
02245         WARN("Trying to access %u constants, but d3d8 only supports %u\n",
02246              Register + ConstantCount, D3D8_MAX_VERTEX_SHADER_CONSTANTF);
02247         return D3DERR_INVALIDCALL;
02248     }
02249 
02250     wined3d_mutex_lock();
02251     hr = wined3d_device_get_vs_consts_f(This->wined3d_device, Register, pConstantData, ConstantCount);
02252     wined3d_mutex_unlock();
02253 
02254     return hr;
02255 }
02256 
02257 static HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderDeclaration(IDirect3DDevice8 *iface,
02258         DWORD pVertexShader, void *pData, DWORD *pSizeOfData)
02259 {
02260     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
02261     IDirect3DVertexDeclaration8Impl *declaration;
02262     IDirect3DVertexShader8Impl *shader;
02263 
02264     TRACE("iface %p, shader %#x, data %p, data_size %p.\n",
02265             iface, pVertexShader, pData, pSizeOfData);
02266 
02267     wined3d_mutex_lock();
02268     shader = d3d8_get_object(&This->handle_table, pVertexShader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_VS);
02269     wined3d_mutex_unlock();
02270 
02271     if (!shader)
02272     {
02273         WARN("Invalid handle (%#x) passed.\n", pVertexShader);
02274         return D3DERR_INVALIDCALL;
02275     }
02276     declaration = (IDirect3DVertexDeclaration8Impl *)shader->vertex_declaration;
02277 
02278     /* If pData is NULL, we just return the required size of the buffer. */
02279     if (!pData) {
02280         *pSizeOfData = declaration->elements_size;
02281         return D3D_OK;
02282     }
02283 
02284     /* MSDN claims that if *pSizeOfData is smaller than the required size
02285      * we should write the required size and return D3DERR_MOREDATA.
02286      * That's not actually true. */
02287     if (*pSizeOfData < declaration->elements_size) {
02288         return D3DERR_INVALIDCALL;
02289     }
02290 
02291     CopyMemory(pData, declaration->elements, declaration->elements_size);
02292 
02293     return D3D_OK;
02294 }
02295 
02296 static HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderFunction(IDirect3DDevice8 *iface,
02297         DWORD pVertexShader, void *pData, DWORD *pSizeOfData)
02298 {
02299     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
02300     IDirect3DVertexShader8Impl *shader = NULL;
02301     HRESULT hr;
02302 
02303     TRACE("iface %p, shader %#x, data %p, data_size %p.\n",
02304             iface, pVertexShader, pData, pSizeOfData);
02305 
02306     wined3d_mutex_lock();
02307     shader = d3d8_get_object(&This->handle_table, pVertexShader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_VS);
02308     if (!shader)
02309     {
02310         WARN("Invalid handle (%#x) passed.\n", pVertexShader);
02311         wined3d_mutex_unlock();
02312 
02313         return D3DERR_INVALIDCALL;
02314     }
02315 
02316     if (!shader->wined3d_shader)
02317     {
02318         wined3d_mutex_unlock();
02319         *pSizeOfData = 0;
02320         return D3D_OK;
02321     }
02322 
02323     hr = wined3d_shader_get_byte_code(shader->wined3d_shader, pData, pSizeOfData);
02324     wined3d_mutex_unlock();
02325 
02326     return hr;
02327 }
02328 
02329 static HRESULT WINAPI IDirect3DDevice8Impl_SetIndices(IDirect3DDevice8 *iface,
02330         IDirect3DIndexBuffer8 *pIndexData, UINT baseVertexIndex)
02331 {
02332     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
02333     IDirect3DIndexBuffer8Impl *ib = unsafe_impl_from_IDirect3DIndexBuffer8(pIndexData);
02334     HRESULT hr;
02335 
02336     TRACE("iface %p, buffer %p, base_vertex_idx %u.\n", iface, pIndexData, baseVertexIndex);
02337 
02338     /* WineD3D takes an INT(due to d3d9), but d3d8 uses UINTs. Do I have to add a check here that
02339      * the UINT doesn't cause an overflow in the INT? It seems rather unlikely because such large
02340      * vertex buffers can't be created to address them with an index that requires the 32nd bit
02341      * (4 Byte minimum vertex size * 2^31-1 -> 8 gb buffer. The index sign would be the least
02342      * problem)
02343      */
02344     wined3d_mutex_lock();
02345     wined3d_device_set_base_vertex_index(This->wined3d_device, baseVertexIndex);
02346     hr = wined3d_device_set_index_buffer(This->wined3d_device,
02347             ib ? ib->wineD3DIndexBuffer : NULL,
02348             ib ? ib->format : WINED3DFMT_UNKNOWN);
02349     wined3d_mutex_unlock();
02350 
02351     return hr;
02352 }
02353 
02354 static HRESULT WINAPI IDirect3DDevice8Impl_GetIndices(IDirect3DDevice8 *iface,
02355         IDirect3DIndexBuffer8 **ppIndexData, UINT *pBaseVertexIndex)
02356 {
02357     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
02358     struct wined3d_buffer *retIndexData = NULL;
02359     HRESULT hr;
02360 
02361     TRACE("iface %p, buffer %p, base_vertex_index %p.\n", iface, ppIndexData, pBaseVertexIndex);
02362 
02363     if(ppIndexData == NULL){
02364         return D3DERR_INVALIDCALL;
02365     }
02366 
02367     /* The case from UINT to INT is safe because d3d8 will never set negative values */
02368     wined3d_mutex_lock();
02369     *pBaseVertexIndex = wined3d_device_get_base_vertex_index(This->wined3d_device);
02370     hr = wined3d_device_get_index_buffer(This->wined3d_device, &retIndexData);
02371     if (SUCCEEDED(hr) && retIndexData)
02372     {
02373         *ppIndexData = wined3d_buffer_get_parent(retIndexData);
02374         IDirect3DIndexBuffer8_AddRef(*ppIndexData);
02375         wined3d_buffer_decref(retIndexData);
02376     } else {
02377         if (FAILED(hr)) FIXME("Call to GetIndices failed\n");
02378         *ppIndexData = NULL;
02379     }
02380     wined3d_mutex_unlock();
02381 
02382     return hr;
02383 }
02384 
02385 static HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(IDirect3DDevice8 *iface,
02386         const DWORD *byte_code, DWORD *shader)
02387 {
02388     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
02389     IDirect3DPixelShader8Impl *object;
02390     DWORD shader_handle;
02391     DWORD handle;
02392     HRESULT hr;
02393 
02394     TRACE("iface %p, byte_code %p, shader %p.\n", iface, byte_code, shader);
02395 
02396     if (!shader)
02397     {
02398         TRACE("(%p) Invalid call\n", This);
02399         return D3DERR_INVALIDCALL;
02400     }
02401 
02402     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
02403     if (!object)
02404     {
02405         ERR("Failed to allocate pixel shader memmory.\n");
02406         return E_OUTOFMEMORY;
02407     }
02408 
02409     wined3d_mutex_lock();
02410     handle = d3d8_allocate_handle(&This->handle_table, object, D3D8_HANDLE_PS);
02411     wined3d_mutex_unlock();
02412     if (handle == D3D8_INVALID_HANDLE)
02413     {
02414         ERR("Failed to allocate pixel shader handle.\n");
02415         HeapFree(GetProcessHeap(), 0, object);
02416         return E_OUTOFMEMORY;
02417     }
02418 
02419     shader_handle = handle + VS_HIGHESTFIXEDFXF + 1;
02420 
02421     hr = pixelshader_init(object, This, byte_code, shader_handle);
02422     if (FAILED(hr))
02423     {
02424         WARN("Failed to initialize pixel shader, hr %#x.\n", hr);
02425         wined3d_mutex_lock();
02426         d3d8_free_handle(&This->handle_table, handle, D3D8_HANDLE_PS);
02427         wined3d_mutex_unlock();
02428         HeapFree(GetProcessHeap(), 0, object);
02429         *shader = 0;
02430         return hr;
02431     }
02432 
02433     TRACE("Created pixel shader %p (handle %#x).\n", object, shader_handle);
02434     *shader = shader_handle;
02435 
02436     return D3D_OK;
02437 }
02438 
02439 static HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShader(IDirect3DDevice8 *iface, DWORD pShader)
02440 {
02441     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
02442     IDirect3DPixelShader8Impl *shader;
02443     HRESULT hr;
02444 
02445     TRACE("iface %p, shader %#x.\n", iface, pShader);
02446 
02447     wined3d_mutex_lock();
02448 
02449     if (!pShader)
02450     {
02451         hr = wined3d_device_set_pixel_shader(This->wined3d_device, NULL);
02452         wined3d_mutex_unlock();
02453         return hr;
02454     }
02455 
02456     shader = d3d8_get_object(&This->handle_table, pShader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_PS);
02457     if (!shader)
02458     {
02459         WARN("Invalid handle (%#x) passed.\n", pShader);
02460         wined3d_mutex_unlock();
02461         return D3DERR_INVALIDCALL;
02462     }
02463 
02464     TRACE("(%p) : Setting shader %p\n", This, shader);
02465     hr = wined3d_device_set_pixel_shader(This->wined3d_device, shader->wined3d_shader);
02466     wined3d_mutex_unlock();
02467 
02468     return hr;
02469 }
02470 
02471 static HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShader(IDirect3DDevice8 *iface, DWORD *ppShader)
02472 {
02473     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
02474     struct wined3d_shader *object;
02475 
02476     TRACE("iface %p, shader %p.\n", iface, ppShader);
02477 
02478     if (NULL == ppShader) {
02479         TRACE("(%p) Invalid call\n", This);
02480         return D3DERR_INVALIDCALL;
02481     }
02482 
02483     wined3d_mutex_lock();
02484     object = wined3d_device_get_pixel_shader(This->wined3d_device);
02485     if (object)
02486     {
02487         IDirect3DPixelShader8Impl *d3d8_shader;
02488         d3d8_shader = wined3d_shader_get_parent(object);
02489         wined3d_shader_decref(object);
02490         *ppShader = d3d8_shader->handle;
02491     }
02492     else
02493     {
02494         *ppShader = 0;
02495     }
02496     wined3d_mutex_unlock();
02497 
02498     TRACE("(%p) : returning %#x\n", This, *ppShader);
02499 
02500     return D3D_OK;
02501 }
02502 
02503 static HRESULT WINAPI IDirect3DDevice8Impl_DeletePixelShader(IDirect3DDevice8 *iface, DWORD pShader)
02504 {
02505     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
02506     IDirect3DPixelShader8Impl *shader;
02507     struct wined3d_shader *cur;
02508 
02509     TRACE("iface %p, shader %#x.\n", iface, pShader);
02510 
02511     wined3d_mutex_lock();
02512 
02513     shader = d3d8_free_handle(&This->handle_table, pShader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_PS);
02514     if (!shader)
02515     {
02516         WARN("Invalid handle (%#x) passed.\n", pShader);
02517         wined3d_mutex_unlock();
02518         return D3DERR_INVALIDCALL;
02519     }
02520 
02521     cur = wined3d_device_get_pixel_shader(This->wined3d_device);
02522     if (cur)
02523     {
02524         if (cur == shader->wined3d_shader)
02525             IDirect3DDevice8_SetPixelShader(iface, 0);
02526         wined3d_shader_decref(cur);
02527     }
02528 
02529     wined3d_mutex_unlock();
02530 
02531     if (IDirect3DPixelShader8_Release(&shader->IDirect3DPixelShader8_iface))
02532     {
02533         ERR("Shader %p has references left, this shouldn't happen.\n", shader);
02534     }
02535 
02536     return D3D_OK;
02537 }
02538 
02539 static HRESULT  WINAPI  IDirect3DDevice8Impl_SetPixelShaderConstant(IDirect3DDevice8 *iface,
02540         DWORD Register, const void *pConstantData, DWORD ConstantCount)
02541 {
02542     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
02543     HRESULT hr;
02544 
02545     TRACE("iface %p, register %u, data %p, count %u.\n",
02546             iface, Register, pConstantData, ConstantCount);
02547 
02548     wined3d_mutex_lock();
02549     hr = wined3d_device_set_ps_consts_f(This->wined3d_device, Register, pConstantData, ConstantCount);
02550     wined3d_mutex_unlock();
02551 
02552     return hr;
02553 }
02554 
02555 static HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderConstant(IDirect3DDevice8 *iface,
02556         DWORD Register, void *pConstantData, DWORD ConstantCount)
02557 {
02558     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
02559     HRESULT hr;
02560 
02561     TRACE("iface %p, register %u, data %p, count %u.\n",
02562             iface, Register, pConstantData, ConstantCount);
02563 
02564     wined3d_mutex_lock();
02565     hr = wined3d_device_get_ps_consts_f(This->wined3d_device, Register, pConstantData, ConstantCount);
02566     wined3d_mutex_unlock();
02567 
02568     return hr;
02569 }
02570 
02571 static HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderFunction(IDirect3DDevice8 *iface,
02572         DWORD pPixelShader, void *pData, DWORD *pSizeOfData)
02573 {
02574     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
02575     IDirect3DPixelShader8Impl *shader = NULL;
02576     HRESULT hr;
02577 
02578     TRACE("iface %p, shader %#x, data %p, data_size %p.\n",
02579             iface, pPixelShader, pData, pSizeOfData);
02580 
02581     wined3d_mutex_lock();
02582     shader = d3d8_get_object(&This->handle_table, pPixelShader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_PS);
02583     if (!shader)
02584     {
02585         WARN("Invalid handle (%#x) passed.\n", pPixelShader);
02586         wined3d_mutex_unlock();
02587 
02588         return D3DERR_INVALIDCALL;
02589     }
02590 
02591     hr = wined3d_shader_get_byte_code(shader->wined3d_shader, pData, pSizeOfData);
02592     wined3d_mutex_unlock();
02593 
02594     return hr;
02595 }
02596 
02597 static HRESULT WINAPI IDirect3DDevice8Impl_DrawRectPatch(IDirect3DDevice8 *iface, UINT Handle,
02598         const float *pNumSegs, const D3DRECTPATCH_INFO *pRectPatchInfo)
02599 {
02600     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
02601     HRESULT hr;
02602 
02603     TRACE("iface %p, handle %#x, segment_count %p, patch_info %p.\n",
02604             iface, Handle, pNumSegs, pRectPatchInfo);
02605 
02606     wined3d_mutex_lock();
02607     hr = wined3d_device_draw_rect_patch(This->wined3d_device, Handle,
02608             pNumSegs, (const struct wined3d_rect_patch_info *)pRectPatchInfo);
02609     wined3d_mutex_unlock();
02610 
02611     return hr;
02612 }
02613 
02614 static HRESULT WINAPI IDirect3DDevice8Impl_DrawTriPatch(IDirect3DDevice8 *iface, UINT Handle,
02615         const float *pNumSegs, const D3DTRIPATCH_INFO *pTriPatchInfo)
02616 {
02617     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
02618     HRESULT hr;
02619 
02620     TRACE("iface %p, handle %#x, segment_count %p, patch_info %p.\n",
02621             iface, Handle, pNumSegs, pTriPatchInfo);
02622 
02623     wined3d_mutex_lock();
02624     hr = wined3d_device_draw_tri_patch(This->wined3d_device, Handle,
02625             pNumSegs, (const struct wined3d_tri_patch_info *)pTriPatchInfo);
02626     wined3d_mutex_unlock();
02627 
02628     return hr;
02629 }
02630 
02631 static HRESULT WINAPI IDirect3DDevice8Impl_DeletePatch(IDirect3DDevice8 *iface, UINT Handle)
02632 {
02633     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
02634     HRESULT hr;
02635 
02636     TRACE("iface %p, handle %#x.\n", iface, Handle);
02637 
02638     wined3d_mutex_lock();
02639     hr = wined3d_device_delete_patch(This->wined3d_device, Handle);
02640     wined3d_mutex_unlock();
02641 
02642     return hr;
02643 }
02644 
02645 static HRESULT WINAPI IDirect3DDevice8Impl_SetStreamSource(IDirect3DDevice8 *iface,
02646         UINT StreamNumber, IDirect3DVertexBuffer8 *pStreamData, UINT Stride)
02647 {
02648     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
02649     IDirect3DVertexBuffer8Impl *streamdata = unsafe_impl_from_IDirect3DVertexBuffer8(pStreamData);
02650     HRESULT hr;
02651 
02652     TRACE("iface %p, stream_idx %u, buffer %p, stride %u.\n",
02653             iface, StreamNumber, pStreamData, Stride);
02654 
02655     wined3d_mutex_lock();
02656     hr = wined3d_device_set_stream_source(This->wined3d_device, StreamNumber,
02657             streamdata ? streamdata->wineD3DVertexBuffer : NULL, 0/* Offset in bytes */, Stride);
02658     wined3d_mutex_unlock();
02659 
02660     return hr;
02661 }
02662 
02663 static HRESULT WINAPI IDirect3DDevice8Impl_GetStreamSource(IDirect3DDevice8 *iface,
02664         UINT StreamNumber, IDirect3DVertexBuffer8 **pStream, UINT *pStride)
02665 {
02666     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
02667     struct wined3d_buffer *retStream = NULL;
02668     HRESULT hr;
02669 
02670     TRACE("iface %p, stream_idx %u, buffer %p, stride %p.\n",
02671             iface, StreamNumber, pStream, pStride);
02672 
02673     if(pStream == NULL){
02674         return D3DERR_INVALIDCALL;
02675     }
02676 
02677     wined3d_mutex_lock();
02678     hr = wined3d_device_get_stream_source(This->wined3d_device, StreamNumber,
02679             &retStream, 0 /* Offset in bytes */, pStride);
02680     if (SUCCEEDED(hr) && retStream)
02681     {
02682         *pStream = wined3d_buffer_get_parent(retStream);
02683         IDirect3DVertexBuffer8_AddRef(*pStream);
02684         wined3d_buffer_decref(retStream);
02685     }
02686     else
02687     {
02688         if (FAILED(hr)) FIXME("Call to GetStreamSource failed, hr %#x.\n", hr);
02689         *pStream = NULL;
02690     }
02691     wined3d_mutex_unlock();
02692 
02693     return hr;
02694 }
02695 
02696 static const IDirect3DDevice8Vtbl Direct3DDevice8_Vtbl =
02697 {
02698     IDirect3DDevice8Impl_QueryInterface,
02699     IDirect3DDevice8Impl_AddRef,
02700     IDirect3DDevice8Impl_Release,
02701     IDirect3DDevice8Impl_TestCooperativeLevel,
02702     IDirect3DDevice8Impl_GetAvailableTextureMem,
02703     IDirect3DDevice8Impl_ResourceManagerDiscardBytes,
02704     IDirect3DDevice8Impl_GetDirect3D,
02705     IDirect3DDevice8Impl_GetDeviceCaps,
02706     IDirect3DDevice8Impl_GetDisplayMode,
02707     IDirect3DDevice8Impl_GetCreationParameters,
02708     IDirect3DDevice8Impl_SetCursorProperties,
02709     IDirect3DDevice8Impl_SetCursorPosition,
02710     IDirect3DDevice8Impl_ShowCursor,
02711     IDirect3DDevice8Impl_CreateAdditionalSwapChain,
02712     IDirect3DDevice8Impl_Reset,
02713     IDirect3DDevice8Impl_Present,
02714     IDirect3DDevice8Impl_GetBackBuffer,
02715     IDirect3DDevice8Impl_GetRasterStatus,
02716     IDirect3DDevice8Impl_SetGammaRamp,
02717     IDirect3DDevice8Impl_GetGammaRamp,
02718     IDirect3DDevice8Impl_CreateTexture,
02719     IDirect3DDevice8Impl_CreateVolumeTexture,
02720     IDirect3DDevice8Impl_CreateCubeTexture,
02721     IDirect3DDevice8Impl_CreateVertexBuffer,
02722     IDirect3DDevice8Impl_CreateIndexBuffer,
02723     IDirect3DDevice8Impl_CreateRenderTarget,
02724     IDirect3DDevice8Impl_CreateDepthStencilSurface,
02725     IDirect3DDevice8Impl_CreateImageSurface,
02726     IDirect3DDevice8Impl_CopyRects,
02727     IDirect3DDevice8Impl_UpdateTexture,
02728     IDirect3DDevice8Impl_GetFrontBuffer,
02729     IDirect3DDevice8Impl_SetRenderTarget,
02730     IDirect3DDevice8Impl_GetRenderTarget,
02731     IDirect3DDevice8Impl_GetDepthStencilSurface,
02732     IDirect3DDevice8Impl_BeginScene,
02733     IDirect3DDevice8Impl_EndScene,
02734     IDirect3DDevice8Impl_Clear,
02735     IDirect3DDevice8Impl_SetTransform,
02736     IDirect3DDevice8Impl_GetTransform,
02737     IDirect3DDevice8Impl_MultiplyTransform,
02738     IDirect3DDevice8Impl_SetViewport,
02739     IDirect3DDevice8Impl_GetViewport,
02740     IDirect3DDevice8Impl_SetMaterial,
02741     IDirect3DDevice8Impl_GetMaterial,
02742     IDirect3DDevice8Impl_SetLight,
02743     IDirect3DDevice8Impl_GetLight,
02744     IDirect3DDevice8Impl_LightEnable,
02745     IDirect3DDevice8Impl_GetLightEnable,
02746     IDirect3DDevice8Impl_SetClipPlane,
02747     IDirect3DDevice8Impl_GetClipPlane,
02748     IDirect3DDevice8Impl_SetRenderState,
02749     IDirect3DDevice8Impl_GetRenderState,
02750     IDirect3DDevice8Impl_BeginStateBlock,
02751     IDirect3DDevice8Impl_EndStateBlock,
02752     IDirect3DDevice8Impl_ApplyStateBlock,
02753     IDirect3DDevice8Impl_CaptureStateBlock,
02754     IDirect3DDevice8Impl_DeleteStateBlock,
02755     IDirect3DDevice8Impl_CreateStateBlock,
02756     IDirect3DDevice8Impl_SetClipStatus,
02757     IDirect3DDevice8Impl_GetClipStatus,
02758     IDirect3DDevice8Impl_GetTexture,
02759     IDirect3DDevice8Impl_SetTexture,
02760     IDirect3DDevice8Impl_GetTextureStageState,
02761     IDirect3DDevice8Impl_SetTextureStageState,
02762     IDirect3DDevice8Impl_ValidateDevice,
02763     IDirect3DDevice8Impl_GetInfo,
02764     IDirect3DDevice8Impl_SetPaletteEntries,
02765     IDirect3DDevice8Impl_GetPaletteEntries,
02766     IDirect3DDevice8Impl_SetCurrentTexturePalette,
02767     IDirect3DDevice8Impl_GetCurrentTexturePalette,
02768     IDirect3DDevice8Impl_DrawPrimitive,
02769     IDirect3DDevice8Impl_DrawIndexedPrimitive,
02770     IDirect3DDevice8Impl_DrawPrimitiveUP,
02771     IDirect3DDevice8Impl_DrawIndexedPrimitiveUP,
02772     IDirect3DDevice8Impl_ProcessVertices,
02773     IDirect3DDevice8Impl_CreateVertexShader,
02774     IDirect3DDevice8Impl_SetVertexShader,
02775     IDirect3DDevice8Impl_GetVertexShader,
02776     IDirect3DDevice8Impl_DeleteVertexShader,
02777     IDirect3DDevice8Impl_SetVertexShaderConstant,
02778     IDirect3DDevice8Impl_GetVertexShaderConstant,
02779     IDirect3DDevice8Impl_GetVertexShaderDeclaration,
02780     IDirect3DDevice8Impl_GetVertexShaderFunction,
02781     IDirect3DDevice8Impl_SetStreamSource,
02782     IDirect3DDevice8Impl_GetStreamSource,
02783     IDirect3DDevice8Impl_SetIndices,
02784     IDirect3DDevice8Impl_GetIndices,
02785     IDirect3DDevice8Impl_CreatePixelShader,
02786     IDirect3DDevice8Impl_SetPixelShader,
02787     IDirect3DDevice8Impl_GetPixelShader,
02788     IDirect3DDevice8Impl_DeletePixelShader,
02789     IDirect3DDevice8Impl_SetPixelShaderConstant,
02790     IDirect3DDevice8Impl_GetPixelShaderConstant,
02791     IDirect3DDevice8Impl_GetPixelShaderFunction,
02792     IDirect3DDevice8Impl_DrawRectPatch,
02793     IDirect3DDevice8Impl_DrawTriPatch,
02794     IDirect3DDevice8Impl_DeletePatch
02795 };
02796 
02797 static inline IDirect3DDevice8Impl *device_from_device_parent(struct wined3d_device_parent *device_parent)
02798 {
02799     return CONTAINING_RECORD(device_parent, IDirect3DDevice8Impl, device_parent);
02800 }
02801 
02802 static void CDECL device_parent_wined3d_device_created(struct wined3d_device_parent *device_parent,
02803         struct wined3d_device *device)
02804 {
02805     TRACE("device_parent %p, device %p\n", device_parent, device);
02806 }
02807 
02808 static void CDECL device_parent_mode_changed(struct wined3d_device_parent *device_parent)
02809 {
02810     TRACE("device_parent %p.\n", device_parent);
02811 }
02812 
02813 static HRESULT CDECL device_parent_create_surface(struct wined3d_device_parent *device_parent,
02814         void *container_parent, UINT width, UINT height, enum wined3d_format_id format, DWORD usage,
02815         enum wined3d_pool pool, UINT level, enum wined3d_cubemap_face face, struct wined3d_surface **surface)
02816 {
02817     IDirect3DDevice8Impl *device = device_from_device_parent(device_parent);
02818     IDirect3DSurface8Impl *d3d_surface;
02819     BOOL lockable = TRUE;
02820     HRESULT hr;
02821 
02822     TRACE("device_parent %p, container_parent %p, width %u, height %u, format %#x, usage %#x,\n"
02823             "\tpool %#x, level %u, face %u, surface %p.\n",
02824             device_parent, container_parent, width, height, format, usage, pool, level, face, surface);
02825 
02826 
02827     if (pool == WINED3D_POOL_DEFAULT && !(usage & WINED3DUSAGE_DYNAMIC))
02828         lockable = FALSE;
02829 
02830     hr = IDirect3DDevice8Impl_CreateSurface(device, width, height,
02831             d3dformat_from_wined3dformat(format), lockable, FALSE /* Discard */, level,
02832             (IDirect3DSurface8 **)&d3d_surface, usage, pool, D3DMULTISAMPLE_NONE, 0 /* MultisampleQuality */);
02833     if (FAILED(hr))
02834     {
02835         WARN("Failed to create surface, hr %#x.\n", hr);
02836         return hr;
02837     }
02838 
02839     *surface = d3d_surface->wined3d_surface;
02840     wined3d_surface_incref(*surface);
02841 
02842     d3d_surface->container = container_parent;
02843     IUnknown_Release(d3d_surface->parentDevice);
02844     d3d_surface->parentDevice = NULL;
02845 
02846     IDirect3DSurface8_Release(&d3d_surface->IDirect3DSurface8_iface);
02847     d3d_surface->forwardReference = container_parent;
02848 
02849     return hr;
02850 }
02851 
02852 static HRESULT CDECL device_parent_create_rendertarget(struct wined3d_device_parent *device_parent,
02853         void *container_parent, UINT width, UINT height, enum wined3d_format_id format,
02854         enum wined3d_multisample_type multisample_type, DWORD multisample_quality, BOOL lockable,
02855         struct wined3d_surface **surface)
02856 {
02857     IDirect3DDevice8Impl *device = device_from_device_parent(device_parent);
02858     IDirect3DSurface8Impl *d3d_surface;
02859     HRESULT hr;
02860 
02861     TRACE("device_parent %p, container_parent %p, width %u, height %u, format %#x, multisample_type %#x,\n"
02862             "\tmultisample_quality %u, lockable %u, surface %p.\n",
02863             device_parent, container_parent, width, height, format,
02864             multisample_type, multisample_quality, lockable, surface);
02865 
02866     hr = IDirect3DDevice8_CreateRenderTarget(&device->IDirect3DDevice8_iface, width, height,
02867             d3dformat_from_wined3dformat(format), multisample_type, lockable, (IDirect3DSurface8 **)&d3d_surface);
02868     if (FAILED(hr))
02869     {
02870         WARN("Failed to create rendertarget, hr %#x.\n", hr);
02871         return hr;
02872     }
02873 
02874     *surface = d3d_surface->wined3d_surface;
02875     wined3d_surface_incref(*surface);
02876 
02877     d3d_surface->container = (IUnknown *)&device->IDirect3DDevice8_iface;
02878     /* Implicit surfaces are created with an refcount of 0 */
02879     IDirect3DSurface8_Release(&d3d_surface->IDirect3DSurface8_iface);
02880 
02881     return hr;
02882 }
02883 
02884 static HRESULT CDECL device_parent_create_depth_stencil(struct wined3d_device_parent *device_parent,
02885         UINT width, UINT height, enum wined3d_format_id format, enum wined3d_multisample_type multisample_type,
02886         DWORD multisample_quality, BOOL discard, struct wined3d_surface **surface)
02887 {
02888     IDirect3DDevice8Impl *device = device_from_device_parent(device_parent);
02889     IDirect3DSurface8Impl *d3d_surface;
02890     HRESULT hr;
02891 
02892     TRACE("device_parent %p, width %u, height %u, format %#x, multisample_type %#x,\n"
02893             "\tmultisample_quality %u, discard %u, surface %p.\n",
02894             device_parent, width, height, format, multisample_type, multisample_quality, discard, surface);
02895 
02896     hr = IDirect3DDevice8_CreateDepthStencilSurface(&device->IDirect3DDevice8_iface, width, height,
02897             d3dformat_from_wined3dformat(format), multisample_type, (IDirect3DSurface8 **)&d3d_surface);
02898     if (FAILED(hr))
02899     {
02900         WARN("Failed to create depth/stencil surface, hr %#x.\n", hr);
02901         return hr;
02902     }
02903 
02904     *surface = d3d_surface->wined3d_surface;
02905     wined3d_surface_incref(*surface);
02906 
02907     d3d_surface->container = (IUnknown *)&device->IDirect3DDevice8_iface;
02908     /* Implicit surfaces are created with an refcount of 0 */
02909     IDirect3DSurface8_Release(&d3d_surface->IDirect3DSurface8_iface);
02910 
02911     return hr;
02912 }
02913 
02914 static HRESULT CDECL device_parent_create_volume(struct wined3d_device_parent *device_parent,
02915         void *container_parent, UINT width, UINT height, UINT depth, enum wined3d_format_id format,
02916         enum wined3d_pool pool, DWORD usage, struct wined3d_volume **volume)
02917 {
02918     IDirect3DDevice8Impl *device = device_from_device_parent(device_parent);
02919     IDirect3DVolume8Impl *object;
02920     HRESULT hr;
02921 
02922     TRACE("device_parent %p, container_parent %p, width %u, height %u, depth %u, "
02923             "format %#x, pool %#x, usage %#x, volume %p.\n",
02924             device_parent, container_parent, width, height, depth,
02925             format, pool, usage, volume);
02926 
02927     /* Allocate the storage for the device */
02928     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
02929     if (!object)
02930     {
02931         FIXME("Allocation of memory failed\n");
02932         *volume = NULL;
02933         return D3DERR_OUTOFVIDEOMEMORY;
02934     }
02935 
02936     hr = volume_init(object, device, width, height, depth, usage, format, pool);
02937     if (FAILED(hr))
02938     {
02939         WARN("Failed to initialize volume, hr %#x.\n", hr);
02940         HeapFree(GetProcessHeap(), 0, object);
02941         return hr;
02942     }
02943 
02944     *volume = object->wined3d_volume;
02945     wined3d_volume_incref(*volume);
02946     IDirect3DVolume8_Release(&object->IDirect3DVolume8_iface);
02947 
02948     object->container = container_parent;
02949     object->forwardReference = container_parent;
02950 
02951     TRACE("Created volume %p.\n", object);
02952 
02953     return hr;
02954 }
02955 
02956 static HRESULT CDECL device_parent_create_swapchain(struct wined3d_device_parent *device_parent,
02957         struct wined3d_swapchain_desc *desc, struct wined3d_swapchain **swapchain)
02958 {
02959     IDirect3DDevice8Impl *device = device_from_device_parent(device_parent);
02960     D3DPRESENT_PARAMETERS local_parameters;
02961     IDirect3DSwapChain8 *d3d_swapchain;
02962     HRESULT hr;
02963 
02964     TRACE("device_parent %p, desc %p, swapchain %p.\n", device_parent, desc, swapchain);
02965 
02966     /* Copy the presentation parameters */
02967     local_parameters.BackBufferWidth = desc->backbuffer_width;
02968     local_parameters.BackBufferHeight = desc->backbuffer_height;
02969     local_parameters.BackBufferFormat = d3dformat_from_wined3dformat(desc->backbuffer_format);
02970     local_parameters.BackBufferCount = desc->backbuffer_count;
02971     local_parameters.MultiSampleType = desc->multisample_type;
02972     local_parameters.SwapEffect = desc->swap_effect;
02973     local_parameters.hDeviceWindow = desc->device_window;
02974     local_parameters.Windowed = desc->windowed;
02975     local_parameters.EnableAutoDepthStencil = desc->enable_auto_depth_stencil;
02976     local_parameters.AutoDepthStencilFormat = d3dformat_from_wined3dformat(desc->auto_depth_stencil_format);
02977     local_parameters.Flags = desc->flags;
02978     local_parameters.FullScreen_RefreshRateInHz = desc->refresh_rate;
02979     local_parameters.FullScreen_PresentationInterval = desc->swap_interval;
02980 
02981     hr = IDirect3DDevice8_CreateAdditionalSwapChain(&device->IDirect3DDevice8_iface,
02982             &local_parameters, &d3d_swapchain);
02983     if (FAILED(hr))
02984     {
02985         WARN("Failed to create swapchain, hr %#x.\n", hr);
02986         *swapchain = NULL;
02987         return hr;
02988     }
02989 
02990     *swapchain = ((IDirect3DSwapChain8Impl *)d3d_swapchain)->wined3d_swapchain;
02991     wined3d_swapchain_incref(*swapchain);
02992     IDirect3DSwapChain8_Release(d3d_swapchain);
02993 
02994     /* Copy back the presentation parameters */
02995     desc->backbuffer_width = local_parameters.BackBufferWidth;
02996     desc->backbuffer_height = local_parameters.BackBufferHeight;
02997     desc->backbuffer_format = wined3dformat_from_d3dformat(local_parameters.BackBufferFormat);
02998     desc->backbuffer_count = local_parameters.BackBufferCount;
02999     desc->multisample_type = local_parameters.MultiSampleType;
03000     desc->swap_effect = local_parameters.SwapEffect;
03001     desc->device_window = local_parameters.hDeviceWindow;
03002     desc->windowed = local_parameters.Windowed;
03003     desc->enable_auto_depth_stencil = local_parameters.EnableAutoDepthStencil;
03004     desc->auto_depth_stencil_format = wined3dformat_from_d3dformat(local_parameters.AutoDepthStencilFormat);
03005     desc->flags = local_parameters.Flags;
03006     desc->refresh_rate = local_parameters.FullScreen_RefreshRateInHz;
03007     desc->swap_interval = local_parameters.FullScreen_PresentationInterval;
03008 
03009     return hr;
03010 }
03011 
03012 static const struct wined3d_device_parent_ops d3d8_wined3d_device_parent_ops =
03013 {
03014     device_parent_wined3d_device_created,
03015     device_parent_mode_changed,
03016     device_parent_create_surface,
03017     device_parent_create_rendertarget,
03018     device_parent_create_depth_stencil,
03019     device_parent_create_volume,
03020     device_parent_create_swapchain,
03021 };
03022 
03023 static void setup_fpu(void)
03024 {
03025 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
03026     WORD cw;
03027     __asm__ volatile ("fnstcw %0" : "=m" (cw));
03028     cw = (cw & ~0xf3f) | 0x3f;
03029     __asm__ volatile ("fldcw %0" : : "m" (cw));
03030 #elif defined(__i386__) && defined(_MSC_VER)
03031     WORD cw;
03032     __asm fnstcw cw;
03033     cw = (cw & ~0xf3f) | 0x3f;
03034     __asm fldcw cw;
03035 #else
03036     FIXME("FPU setup not implemented for this platform.\n");
03037 #endif
03038 }
03039 
03040 HRESULT device_init(IDirect3DDevice8Impl *device, IDirect3D8Impl *parent, struct wined3d *wined3d, UINT adapter,
03041         D3DDEVTYPE device_type, HWND focus_window, DWORD flags, D3DPRESENT_PARAMETERS *parameters)
03042 {
03043     struct wined3d_swapchain_desc swapchain_desc;
03044     HRESULT hr;
03045 
03046     device->IDirect3DDevice8_iface.lpVtbl = &Direct3DDevice8_Vtbl;
03047     device->device_parent.ops = &d3d8_wined3d_device_parent_ops;
03048     device->ref = 1;
03049     device->handle_table.entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
03050             D3D8_INITIAL_HANDLE_TABLE_SIZE * sizeof(*device->handle_table.entries));
03051     if (!device->handle_table.entries)
03052     {
03053         ERR("Failed to allocate handle table memory.\n");
03054         return E_OUTOFMEMORY;
03055     }
03056     device->handle_table.table_size = D3D8_INITIAL_HANDLE_TABLE_SIZE;
03057 
03058     if (!(flags & D3DCREATE_FPU_PRESERVE)) setup_fpu();
03059 
03060     wined3d_mutex_lock();
03061     hr = wined3d_device_create(wined3d, adapter, device_type, focus_window, flags, 4,
03062             &device->device_parent, &device->wined3d_device);
03063     if (FAILED(hr))
03064     {
03065         WARN("Failed to create wined3d device, hr %#x.\n", hr);
03066         wined3d_mutex_unlock();
03067         HeapFree(GetProcessHeap(), 0, device->handle_table.entries);
03068         return hr;
03069     }
03070 
03071     if (!parameters->Windowed)
03072     {
03073         HWND device_window = parameters->hDeviceWindow;
03074 
03075         if (!focus_window)
03076             focus_window = device_window;
03077         if (FAILED(hr = wined3d_device_acquire_focus_window(device->wined3d_device, focus_window)))
03078         {
03079             ERR("Failed to acquire focus window, hr %#x.\n", hr);
03080             wined3d_device_decref(device->wined3d_device);
03081             wined3d_mutex_unlock();
03082             HeapFree(GetProcessHeap(), 0, device->handle_table.entries);
03083             return hr;
03084         }
03085 
03086         if (!device_window)
03087             device_window = focus_window;
03088         wined3d_device_setup_fullscreen_window(device->wined3d_device, device_window,
03089                 parameters->BackBufferWidth,
03090                 parameters->BackBufferHeight);
03091     }
03092 
03093     if (flags & D3DCREATE_MULTITHREADED)
03094         wined3d_device_set_multithreaded(device->wined3d_device);
03095 
03096     swapchain_desc.backbuffer_width = parameters->BackBufferWidth;
03097     swapchain_desc.backbuffer_height = parameters->BackBufferHeight;
03098     swapchain_desc.backbuffer_format = wined3dformat_from_d3dformat(parameters->BackBufferFormat);
03099     swapchain_desc.backbuffer_count = parameters->BackBufferCount;
03100     swapchain_desc.multisample_type = parameters->MultiSampleType;
03101     swapchain_desc.multisample_quality = 0; /* d3d9 only */
03102     swapchain_desc.swap_effect = parameters->SwapEffect;
03103     swapchain_desc.device_window = parameters->hDeviceWindow;
03104     swapchain_desc.windowed = parameters->Windowed;
03105     swapchain_desc.enable_auto_depth_stencil = parameters->EnableAutoDepthStencil;
03106     swapchain_desc.auto_depth_stencil_format = wined3dformat_from_d3dformat(parameters->AutoDepthStencilFormat);
03107     swapchain_desc.flags = parameters->Flags;
03108     swapchain_desc.refresh_rate = parameters->FullScreen_RefreshRateInHz;
03109     swapchain_desc.swap_interval = parameters->FullScreen_PresentationInterval;
03110     swapchain_desc.auto_restore_display_mode = TRUE;
03111 
03112     hr = wined3d_device_init_3d(device->wined3d_device, &swapchain_desc);
03113     if (FAILED(hr))
03114     {
03115         WARN("Failed to initialize 3D, hr %#x.\n", hr);
03116         wined3d_device_release_focus_window(device->wined3d_device);
03117         wined3d_device_decref(device->wined3d_device);
03118         wined3d_mutex_unlock();
03119         HeapFree(GetProcessHeap(), 0, device->handle_table.entries);
03120         return hr;
03121     }
03122 
03123     hr = wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_POINTSIZE_MIN, 0);
03124     wined3d_mutex_unlock();
03125     if (FAILED(hr))
03126     {
03127         ERR("Failed to set minimum pointsize, hr %#x.\n", hr);
03128         goto err;
03129     }
03130 
03131     parameters->BackBufferWidth = swapchain_desc.backbuffer_width;
03132     parameters->BackBufferHeight = swapchain_desc.backbuffer_height;
03133     parameters->BackBufferFormat = d3dformat_from_wined3dformat(swapchain_desc.backbuffer_format);
03134     parameters->BackBufferCount = swapchain_desc.backbuffer_count;
03135     parameters->MultiSampleType = swapchain_desc.multisample_type;
03136     parameters->SwapEffect = swapchain_desc.swap_effect;
03137     parameters->hDeviceWindow = swapchain_desc.device_window;
03138     parameters->Windowed = swapchain_desc.windowed;
03139     parameters->EnableAutoDepthStencil = swapchain_desc.enable_auto_depth_stencil;
03140     parameters->AutoDepthStencilFormat = d3dformat_from_wined3dformat(swapchain_desc.auto_depth_stencil_format);
03141     parameters->Flags = swapchain_desc.flags;
03142     parameters->FullScreen_RefreshRateInHz = swapchain_desc.refresh_rate;
03143     parameters->FullScreen_PresentationInterval = swapchain_desc.swap_interval;
03144 
03145     device->declArraySize = 16;
03146     device->decls = HeapAlloc(GetProcessHeap(), 0, device->declArraySize * sizeof(*device->decls));
03147     if (!device->decls)
03148     {
03149         ERR("Failed to allocate FVF vertex declaration map memory.\n");
03150         hr = E_OUTOFMEMORY;
03151         goto err;
03152     }
03153 
03154     device->d3d_parent = &parent->IDirect3D8_iface;
03155     IDirect3D8_AddRef(device->d3d_parent);
03156 
03157     return D3D_OK;
03158 
03159 err:
03160     wined3d_mutex_lock();
03161     wined3d_device_uninit_3d(device->wined3d_device);
03162     wined3d_device_release_focus_window(device->wined3d_device);
03163     wined3d_device_decref(device->wined3d_device);
03164     wined3d_mutex_unlock();
03165     HeapFree(GetProcessHeap(), 0, device->handle_table.entries);
03166     return hr;
03167 }

Generated on Fri May 25 2012 04:19:14 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.