Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendevice.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
1.7.6.1
|