Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendevice.c
Go to the documentation of this file.
00001 /* 00002 * Copyright (c) 1998-2004 Lionel Ulmer 00003 * Copyright (c) 2002-2005 Christian Costa 00004 * Copyright (c) 2006 Stefan Dösinger 00005 * Copyright (c) 2008 Alexander Dorofeyev 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 * IDirect3DDevice implementation, version 1, 2, 3 and 7. Rendering is relayed 00022 * to WineD3D, some minimal DirectDraw specific management is handled here. 00023 * The Direct3DDevice is NOT the parent of the WineD3DDevice, because d3d 00024 * is initialized when DirectDraw creates the primary surface. 00025 * Some type management is necessary, because some D3D types changed between 00026 * D3D7 and D3D9. 00027 * 00028 */ 00029 00030 #include "config.h" 00031 #include "wine/port.h" 00032 00033 #include "ddraw_private.h" 00034 00035 WINE_DEFAULT_DEBUG_CHANNEL(ddraw); 00036 00037 /* The device ID */ 00038 const GUID IID_D3DDEVICE_WineD3D = { 00039 0xaef72d43, 00040 0xb09a, 00041 0x4b7b, 00042 { 0xb7,0x98,0xc6,0x8a,0x77,0x2d,0x72,0x2a } 00043 }; 00044 00045 static inline void set_fpu_control_word(WORD fpucw) 00046 { 00047 #if defined(__i386__) && defined(__GNUC__) 00048 __asm__ volatile ("fldcw %0" : : "m" (fpucw)); 00049 #elif defined(__i386__) && defined(_MSC_VER) 00050 __asm fldcw fpucw; 00051 #endif 00052 } 00053 00054 static inline WORD d3d_fpu_setup(void) 00055 { 00056 WORD oldcw; 00057 00058 #if defined(__i386__) && defined(__GNUC__) 00059 __asm__ volatile ("fnstcw %0" : "=m" (oldcw)); 00060 #elif defined(__i386__) && defined(_MSC_VER) 00061 __asm fnstcw oldcw; 00062 #else 00063 static BOOL warned = FALSE; 00064 if(!warned) 00065 { 00066 FIXME("FPUPRESERVE not implemented for this platform / compiler\n"); 00067 warned = TRUE; 00068 } 00069 return 0; 00070 #endif 00071 00072 set_fpu_control_word(0x37f); 00073 00074 return oldcw; 00075 } 00076 00077 /***************************************************************************** 00078 * IUnknown Methods. Common for Version 1, 2, 3 and 7 00079 *****************************************************************************/ 00080 00081 /***************************************************************************** 00082 * IDirect3DDevice7::QueryInterface 00083 * 00084 * Used to query other interfaces from a Direct3DDevice interface. 00085 * It can return interface pointers to all Direct3DDevice versions as well 00086 * as IDirectDraw and IDirect3D. For a link to QueryInterface 00087 * rules see ddraw.c, IDirectDraw7::QueryInterface 00088 * 00089 * Exists in Version 1, 2, 3 and 7 00090 * 00091 * Params: 00092 * refiid: Interface ID queried for 00093 * obj: Used to return the interface pointer 00094 * 00095 * Returns: 00096 * D3D_OK or E_NOINTERFACE 00097 * 00098 *****************************************************************************/ 00099 static HRESULT WINAPI 00100 IDirect3DDeviceImpl_7_QueryInterface(IDirect3DDevice7 *iface, 00101 REFIID refiid, 00102 void **obj) 00103 { 00104 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 00105 00106 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(refiid), obj); 00107 00108 /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */ 00109 *obj = NULL; 00110 00111 if(!refiid) 00112 return DDERR_INVALIDPARAMS; 00113 00114 if ( IsEqualGUID( &IID_IUnknown, refiid ) ) 00115 { 00116 *obj = iface; 00117 } 00118 00119 /* Check DirectDraw Interfaces. */ 00120 else if( IsEqualGUID( &IID_IDirectDraw7, refiid ) ) 00121 { 00122 *obj = &This->ddraw->IDirectDraw7_iface; 00123 TRACE("(%p) Returning IDirectDraw7 interface at %p\n", This, *obj); 00124 } 00125 else if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) 00126 { 00127 *obj = &This->ddraw->IDirectDraw4_iface; 00128 TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This, *obj); 00129 } 00130 else if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) 00131 { 00132 *obj = &This->ddraw->IDirectDraw2_iface; 00133 TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This, *obj); 00134 } 00135 else if( IsEqualGUID( &IID_IDirectDraw, refiid ) ) 00136 { 00137 *obj = &This->ddraw->IDirectDraw_iface; 00138 TRACE("(%p) Returning IDirectDraw interface at %p\n", This, *obj); 00139 } 00140 00141 /* Direct3D */ 00142 else if ( IsEqualGUID( &IID_IDirect3D , refiid ) ) 00143 { 00144 *obj = &This->ddraw->IDirect3D_iface; 00145 TRACE("(%p) Returning IDirect3D interface at %p\n", This, *obj); 00146 } 00147 else if ( IsEqualGUID( &IID_IDirect3D2 , refiid ) ) 00148 { 00149 *obj = &This->ddraw->IDirect3D2_iface; 00150 TRACE("(%p) Returning IDirect3D2 interface at %p\n", This, *obj); 00151 } 00152 else if ( IsEqualGUID( &IID_IDirect3D3 , refiid ) ) 00153 { 00154 *obj = &This->ddraw->IDirect3D3_iface; 00155 TRACE("(%p) Returning IDirect3D3 interface at %p\n", This, *obj); 00156 } 00157 else if ( IsEqualGUID( &IID_IDirect3D7 , refiid ) ) 00158 { 00159 *obj = &This->ddraw->IDirect3D7_iface; 00160 TRACE("(%p) Returning IDirect3D7 interface at %p\n", This, *obj); 00161 } 00162 00163 /* Direct3DDevice */ 00164 else if ( IsEqualGUID( &IID_IDirect3DDevice , refiid ) ) 00165 { 00166 *obj = &This->IDirect3DDevice_iface; 00167 TRACE("(%p) Returning IDirect3DDevice interface at %p\n", This, *obj); 00168 } 00169 else if ( IsEqualGUID( &IID_IDirect3DDevice2 , refiid ) ) { 00170 *obj = &This->IDirect3DDevice2_iface; 00171 TRACE("(%p) Returning IDirect3DDevice2 interface at %p\n", This, *obj); 00172 } 00173 else if ( IsEqualGUID( &IID_IDirect3DDevice3 , refiid ) ) { 00174 *obj = &This->IDirect3DDevice3_iface; 00175 TRACE("(%p) Returning IDirect3DDevice3 interface at %p\n", This, *obj); 00176 } 00177 else if ( IsEqualGUID( &IID_IDirect3DDevice7 , refiid ) ) { 00178 *obj = This; 00179 TRACE("(%p) Returning IDirect3DDevice7 interface at %p\n", This, *obj); 00180 } 00181 00182 /* DirectDrawSurface */ 00183 else if (IsEqualGUID(&IID_IDirectDrawSurface, refiid) && This->from_surface) 00184 { 00185 *obj = &This->target->IDirectDrawSurface_iface; 00186 TRACE("Returning IDirectDrawSurface interface %p.\n", *obj); 00187 } 00188 00189 /* Unknown interface */ 00190 else 00191 { 00192 ERR("(%p)->(%s, %p): No interface found\n", This, debugstr_guid(refiid), obj); 00193 return E_NOINTERFACE; 00194 } 00195 00196 /* AddRef the returned interface */ 00197 IUnknown_AddRef( (IUnknown *) *obj); 00198 return D3D_OK; 00199 } 00200 00201 static HRESULT WINAPI IDirect3DDeviceImpl_3_QueryInterface(IDirect3DDevice3 *iface, REFIID riid, 00202 void **obj) 00203 { 00204 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 00205 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), obj); 00206 00207 return IDirect3DDevice7_QueryInterface(&This->IDirect3DDevice7_iface, riid, obj); 00208 } 00209 00210 static HRESULT WINAPI IDirect3DDeviceImpl_2_QueryInterface(IDirect3DDevice2 *iface, REFIID riid, 00211 void **obj) 00212 { 00213 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 00214 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), obj); 00215 00216 return IDirect3DDevice7_QueryInterface(&This->IDirect3DDevice7_iface, riid, obj); 00217 } 00218 00219 static HRESULT WINAPI IDirect3DDeviceImpl_1_QueryInterface(IDirect3DDevice *iface, REFIID riid, 00220 void **obp) 00221 { 00222 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface); 00223 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), obp); 00224 00225 return IDirect3DDevice7_QueryInterface(&This->IDirect3DDevice7_iface, riid, obp); 00226 } 00227 00228 /***************************************************************************** 00229 * IDirect3DDevice7::AddRef 00230 * 00231 * Increases the refcount.... 00232 * The most exciting Method, definitely 00233 * 00234 * Exists in Version 1, 2, 3 and 7 00235 * 00236 * Returns: 00237 * The new refcount 00238 * 00239 *****************************************************************************/ 00240 static ULONG WINAPI 00241 IDirect3DDeviceImpl_7_AddRef(IDirect3DDevice7 *iface) 00242 { 00243 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 00244 ULONG ref = InterlockedIncrement(&This->ref); 00245 00246 TRACE("%p increasing refcount to %u.\n", This, ref); 00247 00248 return ref; 00249 } 00250 00251 static ULONG WINAPI IDirect3DDeviceImpl_3_AddRef(IDirect3DDevice3 *iface) 00252 { 00253 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 00254 TRACE("iface %p.\n", iface); 00255 00256 return IDirect3DDevice7_AddRef(&This->IDirect3DDevice7_iface); 00257 } 00258 00259 static ULONG WINAPI IDirect3DDeviceImpl_2_AddRef(IDirect3DDevice2 *iface) 00260 { 00261 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 00262 TRACE("iface %p.\n", iface); 00263 00264 return IDirect3DDevice7_AddRef(&This->IDirect3DDevice7_iface); 00265 } 00266 00267 static ULONG WINAPI IDirect3DDeviceImpl_1_AddRef(IDirect3DDevice *iface) 00268 { 00269 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface); 00270 TRACE("iface %p.\n", iface); 00271 00272 return IDirect3DDevice7_AddRef(&This->IDirect3DDevice7_iface); 00273 } 00274 00275 /***************************************************************************** 00276 * IDirect3DDevice7::Release 00277 * 00278 * Decreases the refcount of the interface 00279 * When the refcount is reduced to 0, the object is destroyed. 00280 * 00281 * Exists in Version 1, 2, 3 and 7 00282 * 00283 * Returns:d 00284 * The new refcount 00285 * 00286 *****************************************************************************/ 00287 static ULONG WINAPI 00288 IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface) 00289 { 00290 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 00291 ULONG ref = InterlockedDecrement(&This->ref); 00292 00293 TRACE("%p decreasing refcount to %u.\n", This, ref); 00294 00295 /* This method doesn't destroy the WineD3DDevice, because it's still in use for 00296 * 2D rendering. IDirectDrawSurface7::Release will destroy the WineD3DDevice 00297 * when the render target is released 00298 */ 00299 if (ref == 0) 00300 { 00301 DWORD i; 00302 00303 wined3d_mutex_lock(); 00304 00305 /* There is no need to unset any resources here, wined3d will take 00306 * care of that on Uninit3D(). */ 00307 00308 /* Free the index buffer. */ 00309 wined3d_buffer_decref(This->indexbuffer); 00310 00311 /* Set the device up to render to the front buffer since the back 00312 * buffer will vanish soon. */ 00313 wined3d_device_set_render_target(This->wined3d_device, 0, 00314 This->ddraw->wined3d_frontbuffer, TRUE); 00315 00316 /* Release the WineD3DDevice. This won't destroy it. */ 00317 if (!wined3d_device_decref(This->wined3d_device)) 00318 ERR("The wined3d device (%p) was destroyed unexpectedly.\n", This->wined3d_device); 00319 00320 /* The texture handles should be unset by now, but there might be some bits 00321 * missing in our reference counting(needs test). Do a sanity check. */ 00322 for (i = 0; i < This->handle_table.entry_count; ++i) 00323 { 00324 struct ddraw_handle_entry *entry = &This->handle_table.entries[i]; 00325 00326 switch (entry->type) 00327 { 00328 case DDRAW_HANDLE_FREE: 00329 break; 00330 00331 case DDRAW_HANDLE_MATERIAL: 00332 { 00333 IDirect3DMaterialImpl *m = entry->object; 00334 FIXME("Material handle %#x (%p) not unset properly.\n", i + 1, m); 00335 m->Handle = 0; 00336 break; 00337 } 00338 00339 case DDRAW_HANDLE_MATRIX: 00340 { 00341 /* No FIXME here because this might happen because of sloppy applications. */ 00342 WARN("Leftover matrix handle %#x (%p), deleting.\n", i + 1, entry->object); 00343 IDirect3DDevice_DeleteMatrix(&This->IDirect3DDevice_iface, i + 1); 00344 break; 00345 } 00346 00347 case DDRAW_HANDLE_STATEBLOCK: 00348 { 00349 /* No FIXME here because this might happen because of sloppy applications. */ 00350 WARN("Leftover stateblock handle %#x (%p), deleting.\n", i + 1, entry->object); 00351 IDirect3DDevice7_DeleteStateBlock(iface, i + 1); 00352 break; 00353 } 00354 00355 case DDRAW_HANDLE_SURFACE: 00356 { 00357 IDirectDrawSurfaceImpl *surf = entry->object; 00358 FIXME("Texture handle %#x (%p) not unset properly.\n", i + 1, surf); 00359 surf->Handle = 0; 00360 break; 00361 } 00362 00363 default: 00364 FIXME("Handle %#x (%p) has unknown type %#x.\n", i + 1, entry->object, entry->type); 00365 break; 00366 } 00367 } 00368 00369 ddraw_handle_table_destroy(&This->handle_table); 00370 00371 TRACE("Releasing target %p.\n", This->target); 00372 /* Release the render target and the WineD3D render target 00373 * (See IDirect3D7::CreateDevice for more comments on this) 00374 */ 00375 IDirectDrawSurface7_Release(&This->target->IDirectDrawSurface7_iface); 00376 TRACE("Target release done\n"); 00377 00378 This->ddraw->d3ddevice = NULL; 00379 00380 /* Now free the structure */ 00381 HeapFree(GetProcessHeap(), 0, This); 00382 wined3d_mutex_unlock(); 00383 } 00384 00385 TRACE("Done\n"); 00386 return ref; 00387 } 00388 00389 static ULONG WINAPI IDirect3DDeviceImpl_3_Release(IDirect3DDevice3 *iface) 00390 { 00391 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 00392 TRACE("iface %p.\n", iface); 00393 00394 return IDirect3DDevice7_Release(&This->IDirect3DDevice7_iface); 00395 } 00396 00397 static ULONG WINAPI IDirect3DDeviceImpl_2_Release(IDirect3DDevice2 *iface) 00398 { 00399 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 00400 TRACE("iface %p.\n", iface); 00401 00402 return IDirect3DDevice7_Release(&This->IDirect3DDevice7_iface); 00403 } 00404 00405 static ULONG WINAPI IDirect3DDeviceImpl_1_Release(IDirect3DDevice *iface) 00406 { 00407 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface); 00408 TRACE("iface %p.\n", iface); 00409 00410 return IDirect3DDevice7_Release(&This->IDirect3DDevice7_iface); 00411 } 00412 00413 /***************************************************************************** 00414 * IDirect3DDevice Methods 00415 *****************************************************************************/ 00416 00417 /***************************************************************************** 00418 * IDirect3DDevice::Initialize 00419 * 00420 * Initializes a Direct3DDevice. This implementation is a no-op, as all 00421 * initialization is done at create time. 00422 * 00423 * Exists in Version 1 00424 * 00425 * Parameters: 00426 * No idea what they mean, as the MSDN page is gone 00427 * 00428 * Returns: DD_OK 00429 * 00430 *****************************************************************************/ 00431 static HRESULT WINAPI 00432 IDirect3DDeviceImpl_1_Initialize(IDirect3DDevice *iface, 00433 IDirect3D *Direct3D, GUID *guid, 00434 D3DDEVICEDESC *Desc) 00435 { 00436 /* It shouldn't be crucial, but print a FIXME, I'm interested if 00437 * any game calls it and when. */ 00438 FIXME("iface %p, d3d %p, guid %s, device_desc %p nop!\n", 00439 iface, Direct3D, debugstr_guid(guid), Desc); 00440 00441 return D3D_OK; 00442 } 00443 00444 /***************************************************************************** 00445 * IDirect3DDevice7::GetCaps 00446 * 00447 * Retrieves the device's capabilities 00448 * 00449 * This implementation is used for Version 7 only, the older versions have 00450 * their own implementation. 00451 * 00452 * Parameters: 00453 * Desc: Pointer to a D3DDEVICEDESC7 structure to fill 00454 * 00455 * Returns: 00456 * D3D_OK on success 00457 * D3DERR_* if a problem occurs. See WineD3D 00458 * 00459 *****************************************************************************/ 00460 static HRESULT 00461 IDirect3DDeviceImpl_7_GetCaps(IDirect3DDevice7 *iface, 00462 D3DDEVICEDESC7 *Desc) 00463 { 00464 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 00465 D3DDEVICEDESC OldDesc; 00466 00467 TRACE("iface %p, device_desc %p.\n", iface, Desc); 00468 00469 if (!Desc) 00470 { 00471 WARN("Desc is NULL, returning DDERR_INVALIDPARAMS.\n"); 00472 return DDERR_INVALIDPARAMS; 00473 } 00474 00475 /* Call the same function used by IDirect3D, this saves code */ 00476 return IDirect3DImpl_GetCaps(This->ddraw->wined3d, &OldDesc, Desc); 00477 } 00478 00479 static HRESULT WINAPI 00480 IDirect3DDeviceImpl_7_GetCaps_FPUSetup(IDirect3DDevice7 *iface, 00481 D3DDEVICEDESC7 *Desc) 00482 { 00483 return IDirect3DDeviceImpl_7_GetCaps(iface, Desc); 00484 } 00485 00486 static HRESULT WINAPI 00487 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve(IDirect3DDevice7 *iface, 00488 D3DDEVICEDESC7 *Desc) 00489 { 00490 HRESULT hr; 00491 WORD old_fpucw; 00492 00493 old_fpucw = d3d_fpu_setup(); 00494 hr = IDirect3DDeviceImpl_7_GetCaps(iface, Desc); 00495 set_fpu_control_word(old_fpucw); 00496 00497 return hr; 00498 } 00499 /***************************************************************************** 00500 * IDirect3DDevice3::GetCaps 00501 * 00502 * Retrieves the capabilities of the hardware device and the emulation 00503 * device. For Wine, hardware and emulation are the same (it's all HW). 00504 * 00505 * This implementation is used for Version 1, 2, and 3. Version 7 has its own 00506 * 00507 * Parameters: 00508 * HWDesc: Structure to fill with the HW caps 00509 * HelDesc: Structure to fill with the hardware emulation caps 00510 * 00511 * Returns: 00512 * D3D_OK on success 00513 * D3DERR_* if a problem occurs. See WineD3D 00514 * 00515 *****************************************************************************/ 00516 00517 /* There are 3 versions of D3DDEVICEDESC. All 3 share the same name because 00518 * Microsoft just expanded the existing structure without naming them 00519 * D3DDEVICEDESC2 and D3DDEVICEDESC3. Which version is used have depends 00520 * on the version of the DirectX SDK. DirectX 6+ and Wine use the latest 00521 * one with 252 bytes. 00522 * 00523 * All 3 versions are allowed as parameters and only the specified amount of 00524 * bytes is written. 00525 * 00526 * Note that Direct3D7 and earlier are not available in native Win64 00527 * ddraw.dll builds, so possible size differences between 32 bit and 00528 * 64 bit are a non-issue. 00529 */ 00530 static inline BOOL check_d3ddevicedesc_size(DWORD size) 00531 { 00532 if (size == FIELD_OFFSET(D3DDEVICEDESC, dwMinTextureWidth) /* 172 */ 00533 || size == FIELD_OFFSET(D3DDEVICEDESC, dwMaxTextureRepeat) /* 204 */ 00534 || size == sizeof(D3DDEVICEDESC) /* 252 */) return TRUE; 00535 return FALSE; 00536 } 00537 00538 static HRESULT WINAPI 00539 IDirect3DDeviceImpl_3_GetCaps(IDirect3DDevice3 *iface, 00540 D3DDEVICEDESC *HWDesc, 00541 D3DDEVICEDESC *HelDesc) 00542 { 00543 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 00544 D3DDEVICEDESC oldDesc; 00545 D3DDEVICEDESC7 newDesc; 00546 HRESULT hr; 00547 00548 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface, HWDesc, HelDesc); 00549 00550 if (!HWDesc) 00551 { 00552 WARN("HWDesc is NULL, returning DDERR_INVALIDPARAMS.\n"); 00553 return DDERR_INVALIDPARAMS; 00554 } 00555 if (!check_d3ddevicedesc_size(HWDesc->dwSize)) 00556 { 00557 WARN("HWDesc->dwSize is %u, returning DDERR_INVALIDPARAMS.\n", HWDesc->dwSize); 00558 return DDERR_INVALIDPARAMS; 00559 } 00560 if (!HelDesc) 00561 { 00562 WARN("HelDesc is NULL, returning DDERR_INVALIDPARAMS.\n"); 00563 return DDERR_INVALIDPARAMS; 00564 } 00565 if (!check_d3ddevicedesc_size(HelDesc->dwSize)) 00566 { 00567 WARN("HelDesc->dwSize is %u, returning DDERR_INVALIDPARAMS.\n", HelDesc->dwSize); 00568 return DDERR_INVALIDPARAMS; 00569 } 00570 00571 hr = IDirect3DImpl_GetCaps(This->ddraw->wined3d, &oldDesc, &newDesc); 00572 if(hr != D3D_OK) return hr; 00573 00574 DD_STRUCT_COPY_BYSIZE(HWDesc, &oldDesc); 00575 DD_STRUCT_COPY_BYSIZE(HelDesc, &oldDesc); 00576 return D3D_OK; 00577 } 00578 00579 static HRESULT WINAPI IDirect3DDeviceImpl_2_GetCaps(IDirect3DDevice2 *iface, 00580 D3DDEVICEDESC *D3DHWDevDesc, D3DDEVICEDESC *D3DHELDevDesc) 00581 { 00582 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 00583 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface, D3DHWDevDesc, D3DHELDevDesc); 00584 return IDirect3DDevice3_GetCaps(&This->IDirect3DDevice3_iface, D3DHWDevDesc, D3DHELDevDesc); 00585 } 00586 00587 static HRESULT WINAPI IDirect3DDeviceImpl_1_GetCaps(IDirect3DDevice *iface, 00588 D3DDEVICEDESC *D3DHWDevDesc, D3DDEVICEDESC *D3DHELDevDesc) 00589 { 00590 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface); 00591 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface, D3DHWDevDesc, D3DHELDevDesc); 00592 return IDirect3DDevice3_GetCaps(&This->IDirect3DDevice3_iface, D3DHWDevDesc, D3DHELDevDesc); 00593 } 00594 00595 /***************************************************************************** 00596 * IDirect3DDevice2::SwapTextureHandles 00597 * 00598 * Swaps the texture handles of 2 Texture interfaces. Version 1 and 2 00599 * 00600 * Parameters: 00601 * Tex1, Tex2: The 2 Textures to swap 00602 * 00603 * Returns: 00604 * D3D_OK 00605 * 00606 *****************************************************************************/ 00607 static HRESULT WINAPI 00608 IDirect3DDeviceImpl_2_SwapTextureHandles(IDirect3DDevice2 *iface, 00609 IDirect3DTexture2 *Tex1, 00610 IDirect3DTexture2 *Tex2) 00611 { 00612 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 00613 IDirectDrawSurfaceImpl *surf1 = unsafe_impl_from_IDirect3DTexture2(Tex1); 00614 IDirectDrawSurfaceImpl *surf2 = unsafe_impl_from_IDirect3DTexture2(Tex2); 00615 DWORD h1, h2; 00616 00617 TRACE("iface %p, tex1 %p, tex2 %p.\n", iface, Tex1, Tex2); 00618 00619 wined3d_mutex_lock(); 00620 00621 h1 = surf1->Handle - 1; 00622 h2 = surf2->Handle - 1; 00623 This->handle_table.entries[h1].object = surf2; 00624 This->handle_table.entries[h2].object = surf1; 00625 surf2->Handle = h1 + 1; 00626 surf1->Handle = h2 + 1; 00627 00628 wined3d_mutex_unlock(); 00629 00630 return D3D_OK; 00631 } 00632 00633 static HRESULT WINAPI IDirect3DDeviceImpl_1_SwapTextureHandles(IDirect3DDevice *iface, 00634 IDirect3DTexture *D3DTex1, IDirect3DTexture *D3DTex2) 00635 { 00636 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface); 00637 IDirectDrawSurfaceImpl *surf1 = unsafe_impl_from_IDirect3DTexture(D3DTex1); 00638 IDirectDrawSurfaceImpl *surf2 = unsafe_impl_from_IDirect3DTexture(D3DTex2); 00639 IDirect3DTexture2 *t1 = surf1 ? &surf1->IDirect3DTexture2_iface : NULL; 00640 IDirect3DTexture2 *t2 = surf2 ? &surf2->IDirect3DTexture2_iface : NULL; 00641 00642 TRACE("iface %p, tex1 %p, tex2 %p.\n", iface, D3DTex1, D3DTex2); 00643 00644 return IDirect3DDevice2_SwapTextureHandles(&This->IDirect3DDevice2_iface, t1, t2); 00645 } 00646 00647 /***************************************************************************** 00648 * IDirect3DDevice3::GetStats 00649 * 00650 * This method seems to retrieve some stats from the device. 00651 * The MSDN documentation doesn't exist any more, but the D3DSTATS 00652 * structure suggests that the amount of drawn primitives and processed 00653 * vertices is returned. 00654 * 00655 * Exists in Version 1, 2 and 3 00656 * 00657 * Parameters: 00658 * Stats: Pointer to a D3DSTATS structure to be filled 00659 * 00660 * Returns: 00661 * D3D_OK on success 00662 * DDERR_INVALIDPARAMS if Stats == NULL 00663 * 00664 *****************************************************************************/ 00665 static HRESULT WINAPI 00666 IDirect3DDeviceImpl_3_GetStats(IDirect3DDevice3 *iface, 00667 D3DSTATS *Stats) 00668 { 00669 FIXME("iface %p, stats %p stub!\n", iface, Stats); 00670 00671 if(!Stats) 00672 return DDERR_INVALIDPARAMS; 00673 00674 /* Fill the Stats with 0 */ 00675 Stats->dwTrianglesDrawn = 0; 00676 Stats->dwLinesDrawn = 0; 00677 Stats->dwPointsDrawn = 0; 00678 Stats->dwSpansDrawn = 0; 00679 Stats->dwVerticesProcessed = 0; 00680 00681 return D3D_OK; 00682 } 00683 00684 static HRESULT WINAPI IDirect3DDeviceImpl_2_GetStats(IDirect3DDevice2 *iface, D3DSTATS *Stats) 00685 { 00686 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 00687 00688 TRACE("iface %p, stats %p.\n", iface, Stats); 00689 00690 return IDirect3DDevice3_GetStats(&This->IDirect3DDevice3_iface, Stats); 00691 } 00692 00693 static HRESULT WINAPI IDirect3DDeviceImpl_1_GetStats(IDirect3DDevice *iface, D3DSTATS *Stats) 00694 { 00695 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface); 00696 00697 TRACE("iface %p, stats %p.\n", iface, Stats); 00698 00699 return IDirect3DDevice3_GetStats(&This->IDirect3DDevice3_iface, Stats); 00700 } 00701 00702 /***************************************************************************** 00703 * IDirect3DDevice::CreateExecuteBuffer 00704 * 00705 * Creates an IDirect3DExecuteBuffer, used for rendering with a 00706 * Direct3DDevice. 00707 * 00708 * Version 1 only. 00709 * 00710 * Params: 00711 * Desc: Buffer description 00712 * ExecuteBuffer: Address to return the Interface pointer at 00713 * UnkOuter: Must be NULL. Basically for aggregation, which ddraw doesn't 00714 * support 00715 * 00716 * Returns: 00717 * CLASS_E_NOAGGREGATION if UnkOuter != NULL 00718 * DDERR_OUTOFMEMORY if we ran out of memory 00719 * D3D_OK on success 00720 * 00721 *****************************************************************************/ 00722 static HRESULT WINAPI 00723 IDirect3DDeviceImpl_1_CreateExecuteBuffer(IDirect3DDevice *iface, 00724 D3DEXECUTEBUFFERDESC *Desc, 00725 IDirect3DExecuteBuffer **ExecuteBuffer, 00726 IUnknown *UnkOuter) 00727 { 00728 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface); 00729 IDirect3DExecuteBufferImpl* object; 00730 HRESULT hr; 00731 00732 TRACE("iface %p, buffer_desc %p, buffer %p, outer_unknown %p.\n", 00733 iface, Desc, ExecuteBuffer, UnkOuter); 00734 00735 if(UnkOuter) 00736 return CLASS_E_NOAGGREGATION; 00737 00738 /* Allocate the new Execute Buffer */ 00739 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DExecuteBufferImpl)); 00740 if(!object) 00741 { 00742 ERR("Out of memory when allocating a IDirect3DExecuteBufferImpl structure\n"); 00743 return DDERR_OUTOFMEMORY; 00744 } 00745 00746 hr = d3d_execute_buffer_init(object, This, Desc); 00747 if (FAILED(hr)) 00748 { 00749 WARN("Failed to initialize execute buffer, hr %#x.\n", hr); 00750 HeapFree(GetProcessHeap(), 0, object); 00751 return hr; 00752 } 00753 00754 *ExecuteBuffer = &object->IDirect3DExecuteBuffer_iface; 00755 00756 TRACE(" Returning IDirect3DExecuteBuffer at %p, implementation is at %p\n", *ExecuteBuffer, object); 00757 00758 return D3D_OK; 00759 } 00760 00761 /***************************************************************************** 00762 * IDirect3DDevice::Execute 00763 * 00764 * Executes all the stuff in an execute buffer. 00765 * 00766 * Params: 00767 * ExecuteBuffer: The buffer to execute 00768 * Viewport: The viewport used for rendering 00769 * Flags: Some flags 00770 * 00771 * Returns: 00772 * DDERR_INVALIDPARAMS if ExecuteBuffer == NULL 00773 * D3D_OK on success 00774 * 00775 *****************************************************************************/ 00776 static HRESULT WINAPI IDirect3DDeviceImpl_1_Execute(IDirect3DDevice *iface, 00777 IDirect3DExecuteBuffer *ExecuteBuffer, IDirect3DViewport *Viewport, DWORD Flags) 00778 { 00779 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface); 00780 IDirect3DExecuteBufferImpl *buffer = unsafe_impl_from_IDirect3DExecuteBuffer(ExecuteBuffer); 00781 IDirect3DViewportImpl *Direct3DViewportImpl = unsafe_impl_from_IDirect3DViewport(Viewport); 00782 HRESULT hr; 00783 00784 TRACE("iface %p, buffer %p, viewport %p, flags %#x.\n", iface, ExecuteBuffer, Viewport, Flags); 00785 00786 if(!buffer) 00787 return DDERR_INVALIDPARAMS; 00788 00789 /* Execute... */ 00790 wined3d_mutex_lock(); 00791 hr = d3d_execute_buffer_execute(buffer, This, Direct3DViewportImpl); 00792 wined3d_mutex_unlock(); 00793 00794 return hr; 00795 } 00796 00797 /***************************************************************************** 00798 * IDirect3DDevice3::AddViewport 00799 * 00800 * Add a Direct3DViewport to the device's viewport list. These viewports 00801 * are wrapped to IDirect3DDevice7 viewports in viewport.c 00802 * 00803 * Exists in Version 1, 2 and 3. Note that IDirect3DViewport 1, 2 and 3 00804 * are the same interfaces. 00805 * 00806 * Params: 00807 * Viewport: The viewport to add 00808 * 00809 * Returns: 00810 * DDERR_INVALIDPARAMS if Viewport == NULL 00811 * D3D_OK on success 00812 * 00813 *****************************************************************************/ 00814 static HRESULT WINAPI 00815 IDirect3DDeviceImpl_3_AddViewport(IDirect3DDevice3 *iface, 00816 IDirect3DViewport3 *Viewport) 00817 { 00818 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 00819 IDirect3DViewportImpl *vp = unsafe_impl_from_IDirect3DViewport3(Viewport); 00820 00821 TRACE("iface %p, viewport %p.\n", iface, Viewport); 00822 00823 /* Sanity check */ 00824 if(!vp) 00825 return DDERR_INVALIDPARAMS; 00826 00827 wined3d_mutex_lock(); 00828 list_add_head(&This->viewport_list, &vp->entry); 00829 vp->active_device = This; /* Viewport must be usable for Clear() after AddViewport, 00830 so set active_device here. */ 00831 wined3d_mutex_unlock(); 00832 00833 return D3D_OK; 00834 } 00835 00836 static HRESULT WINAPI IDirect3DDeviceImpl_2_AddViewport(IDirect3DDevice2 *iface, 00837 IDirect3DViewport2 *Direct3DViewport2) 00838 { 00839 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 00840 IDirect3DViewportImpl *vp = unsafe_impl_from_IDirect3DViewport2(Direct3DViewport2); 00841 00842 TRACE("iface %p, viewport %p.\n", iface, Direct3DViewport2); 00843 00844 return IDirect3DDevice3_AddViewport(&This->IDirect3DDevice3_iface, &vp->IDirect3DViewport3_iface); 00845 } 00846 00847 static HRESULT WINAPI IDirect3DDeviceImpl_1_AddViewport(IDirect3DDevice *iface, 00848 IDirect3DViewport *Direct3DViewport) 00849 { 00850 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface); 00851 IDirect3DViewportImpl *vp = unsafe_impl_from_IDirect3DViewport(Direct3DViewport); 00852 00853 TRACE("iface %p, viewport %p.\n", iface, Direct3DViewport); 00854 00855 return IDirect3DDevice3_AddViewport(&This->IDirect3DDevice3_iface, &vp->IDirect3DViewport3_iface); 00856 } 00857 00858 /***************************************************************************** 00859 * IDirect3DDevice3::DeleteViewport 00860 * 00861 * Deletes a Direct3DViewport from the device's viewport list. 00862 * 00863 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions 00864 * are equal. 00865 * 00866 * Params: 00867 * Viewport: The viewport to delete 00868 * 00869 * Returns: 00870 * D3D_OK on success 00871 * DDERR_INVALIDPARAMS if the viewport wasn't found in the list 00872 * 00873 *****************************************************************************/ 00874 static HRESULT WINAPI IDirect3DDeviceImpl_3_DeleteViewport(IDirect3DDevice3 *iface, IDirect3DViewport3 *viewport) 00875 { 00876 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 00877 IDirect3DViewportImpl *vp = unsafe_impl_from_IDirect3DViewport3(viewport); 00878 00879 TRACE("iface %p, viewport %p.\n", iface, viewport); 00880 00881 wined3d_mutex_lock(); 00882 00883 if (vp->active_device != This) 00884 { 00885 WARN("Viewport %p active device is %p.\n", vp, vp->active_device); 00886 wined3d_mutex_unlock(); 00887 return DDERR_INVALIDPARAMS; 00888 } 00889 00890 vp->active_device = NULL; 00891 list_remove(&vp->entry); 00892 00893 wined3d_mutex_unlock(); 00894 00895 return D3D_OK; 00896 } 00897 00898 static HRESULT WINAPI IDirect3DDeviceImpl_2_DeleteViewport(IDirect3DDevice2 *iface, 00899 IDirect3DViewport2 *Direct3DViewport2) 00900 { 00901 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 00902 IDirect3DViewportImpl *vp = unsafe_impl_from_IDirect3DViewport2(Direct3DViewport2); 00903 00904 TRACE("iface %p, viewport %p.\n", iface, Direct3DViewport2); 00905 00906 return IDirect3DDevice3_DeleteViewport(&This->IDirect3DDevice3_iface, &vp->IDirect3DViewport3_iface); 00907 } 00908 00909 static HRESULT WINAPI IDirect3DDeviceImpl_1_DeleteViewport(IDirect3DDevice *iface, 00910 IDirect3DViewport *Direct3DViewport) 00911 { 00912 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface); 00913 IDirect3DViewportImpl *vp = unsafe_impl_from_IDirect3DViewport(Direct3DViewport); 00914 00915 TRACE("iface %p, viewport %p.\n", iface, Direct3DViewport); 00916 00917 return IDirect3DDevice3_DeleteViewport(&This->IDirect3DDevice3_iface, &vp->IDirect3DViewport3_iface); 00918 } 00919 00920 /***************************************************************************** 00921 * IDirect3DDevice3::NextViewport 00922 * 00923 * Returns a viewport from the viewport list, depending on the 00924 * passed viewport and the flags. 00925 * 00926 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions 00927 * are equal. 00928 * 00929 * Params: 00930 * Viewport: Viewport to use for beginning the search 00931 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL 00932 * 00933 * Returns: 00934 * D3D_OK on success 00935 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL 00936 * 00937 *****************************************************************************/ 00938 static HRESULT WINAPI 00939 IDirect3DDeviceImpl_3_NextViewport(IDirect3DDevice3 *iface, 00940 IDirect3DViewport3 *Viewport3, 00941 IDirect3DViewport3 **lplpDirect3DViewport3, 00942 DWORD Flags) 00943 { 00944 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 00945 IDirect3DViewportImpl *vp = unsafe_impl_from_IDirect3DViewport3(Viewport3); 00946 IDirect3DViewportImpl *next; 00947 struct list *entry; 00948 00949 TRACE("iface %p, viewport %p, next %p, flags %#x.\n", 00950 iface, Viewport3, lplpDirect3DViewport3, Flags); 00951 00952 if(!vp) 00953 { 00954 *lplpDirect3DViewport3 = NULL; 00955 return DDERR_INVALIDPARAMS; 00956 } 00957 00958 00959 wined3d_mutex_lock(); 00960 switch (Flags) 00961 { 00962 case D3DNEXT_NEXT: 00963 entry = list_next(&This->viewport_list, &vp->entry); 00964 break; 00965 00966 case D3DNEXT_HEAD: 00967 entry = list_head(&This->viewport_list); 00968 break; 00969 00970 case D3DNEXT_TAIL: 00971 entry = list_tail(&This->viewport_list); 00972 break; 00973 00974 default: 00975 WARN("Invalid flags %#x.\n", Flags); 00976 *lplpDirect3DViewport3 = NULL; 00977 wined3d_mutex_unlock(); 00978 return DDERR_INVALIDPARAMS; 00979 } 00980 00981 if (entry) 00982 { 00983 next = LIST_ENTRY(entry, IDirect3DViewportImpl, entry); 00984 *lplpDirect3DViewport3 = &next->IDirect3DViewport3_iface; 00985 } 00986 else 00987 *lplpDirect3DViewport3 = NULL; 00988 00989 wined3d_mutex_unlock(); 00990 00991 return D3D_OK; 00992 } 00993 00994 static HRESULT WINAPI IDirect3DDeviceImpl_2_NextViewport(IDirect3DDevice2 *iface, 00995 IDirect3DViewport2 *Viewport2, IDirect3DViewport2 **lplpDirect3DViewport2, DWORD Flags) 00996 { 00997 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 00998 IDirect3DViewportImpl *vp = unsafe_impl_from_IDirect3DViewport2(Viewport2); 00999 IDirect3DViewport3 *res; 01000 HRESULT hr; 01001 01002 TRACE("iface %p, viewport %p, next %p, flags %#x.\n", 01003 iface, Viewport2, lplpDirect3DViewport2, Flags); 01004 01005 hr = IDirect3DDevice3_NextViewport(&This->IDirect3DDevice3_iface, 01006 &vp->IDirect3DViewport3_iface, &res, Flags); 01007 *lplpDirect3DViewport2 = (IDirect3DViewport2 *)res; 01008 return hr; 01009 } 01010 01011 static HRESULT WINAPI IDirect3DDeviceImpl_1_NextViewport(IDirect3DDevice *iface, 01012 IDirect3DViewport *Viewport, IDirect3DViewport **lplpDirect3DViewport, DWORD Flags) 01013 { 01014 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface); 01015 IDirect3DViewportImpl *vp = unsafe_impl_from_IDirect3DViewport(Viewport); 01016 IDirect3DViewport3 *res; 01017 HRESULT hr; 01018 01019 TRACE("iface %p, viewport %p, next %p, flags %#x.\n", 01020 iface, Viewport, lplpDirect3DViewport, Flags); 01021 01022 hr = IDirect3DDevice3_NextViewport(&This->IDirect3DDevice3_iface, 01023 &vp->IDirect3DViewport3_iface, &res, Flags); 01024 *lplpDirect3DViewport = (IDirect3DViewport *)res; 01025 return hr; 01026 } 01027 01028 /***************************************************************************** 01029 * IDirect3DDevice::Pick 01030 * 01031 * Executes an execute buffer without performing rendering. Instead, a 01032 * list of primitives that intersect with (x1,y1) of the passed rectangle 01033 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve 01034 * this list. 01035 * 01036 * Version 1 only 01037 * 01038 * Params: 01039 * ExecuteBuffer: Buffer to execute 01040 * Viewport: Viewport to use for execution 01041 * Flags: None are defined, according to the SDK 01042 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used, 01043 * x2 and y2 are ignored. 01044 * 01045 * Returns: 01046 * D3D_OK because it's a stub 01047 * 01048 *****************************************************************************/ 01049 static HRESULT WINAPI 01050 IDirect3DDeviceImpl_1_Pick(IDirect3DDevice *iface, 01051 IDirect3DExecuteBuffer *ExecuteBuffer, 01052 IDirect3DViewport *Viewport, 01053 DWORD Flags, 01054 D3DRECT *Rect) 01055 { 01056 FIXME("iface %p, buffer %p, viewport %p, flags %#x, rect %s stub!\n", 01057 iface, ExecuteBuffer, Viewport, Flags, wine_dbgstr_rect((RECT *)Rect)); 01058 01059 return D3D_OK; 01060 } 01061 01062 /***************************************************************************** 01063 * IDirect3DDevice::GetPickRecords 01064 * 01065 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords 01066 * 01067 * Version 1 only 01068 * 01069 * Params: 01070 * Count: Pointer to a DWORD containing the numbers of pick records to 01071 * retrieve 01072 * D3DPickRec: Address to store the resulting D3DPICKRECORD array. 01073 * 01074 * Returns: 01075 * D3D_OK, because it's a stub 01076 * 01077 *****************************************************************************/ 01078 static HRESULT WINAPI 01079 IDirect3DDeviceImpl_1_GetPickRecords(IDirect3DDevice *iface, 01080 DWORD *Count, 01081 D3DPICKRECORD *D3DPickRec) 01082 { 01083 FIXME("iface %p, count %p, records %p stub!\n", iface, Count, D3DPickRec); 01084 01085 return D3D_OK; 01086 } 01087 01088 /***************************************************************************** 01089 * IDirect3DDevice7::EnumTextureformats 01090 * 01091 * Enumerates the supported texture formats. It has a list of all possible 01092 * formats and calls IWineD3D::CheckDeviceFormat for each format to see if 01093 * WineD3D supports it. If so, then it is passed to the app. 01094 * 01095 * This is for Version 7 and 3, older versions have a different 01096 * callback function and their own implementation 01097 * 01098 * Params: 01099 * Callback: Callback to call for each enumerated format 01100 * Arg: Argument to pass to the callback 01101 * 01102 * Returns: 01103 * D3D_OK on success 01104 * DDERR_INVALIDPARAMS if Callback == NULL 01105 * 01106 *****************************************************************************/ 01107 static HRESULT 01108 IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7 *iface, 01109 LPD3DENUMPIXELFORMATSCALLBACK Callback, 01110 void *Arg) 01111 { 01112 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 01113 struct wined3d_display_mode mode; 01114 HRESULT hr; 01115 unsigned int i; 01116 01117 static const enum wined3d_format_id FormatList[] = 01118 { 01119 /* 16 bit */ 01120 WINED3DFMT_B5G5R5X1_UNORM, 01121 WINED3DFMT_B5G5R5A1_UNORM, 01122 WINED3DFMT_B4G4R4A4_UNORM, 01123 WINED3DFMT_B5G6R5_UNORM, 01124 /* 32 bit */ 01125 WINED3DFMT_B8G8R8X8_UNORM, 01126 WINED3DFMT_B8G8R8A8_UNORM, 01127 /* 8 bit */ 01128 WINED3DFMT_B2G3R3_UNORM, 01129 WINED3DFMT_P8_UINT, 01130 /* FOURCC codes */ 01131 WINED3DFMT_DXT1, 01132 WINED3DFMT_DXT3, 01133 WINED3DFMT_DXT5, 01134 }; 01135 01136 static const enum wined3d_format_id BumpFormatList[] = 01137 { 01138 WINED3DFMT_R8G8_SNORM, 01139 WINED3DFMT_R5G5_SNORM_L6_UNORM, 01140 WINED3DFMT_R8G8_SNORM_L8X8_UNORM, 01141 WINED3DFMT_R16G16_SNORM, 01142 WINED3DFMT_R10G11B11_SNORM, 01143 WINED3DFMT_R10G10B10_SNORM_A2_UNORM 01144 }; 01145 01146 TRACE("iface %p, callback %p, context %p.\n", iface, Callback, Arg); 01147 01148 if(!Callback) 01149 return DDERR_INVALIDPARAMS; 01150 01151 wined3d_mutex_lock(); 01152 01153 memset(&mode, 0, sizeof(mode)); 01154 hr = wined3d_device_get_display_mode(This->ddraw->wined3d_device, 0, &mode); 01155 if (FAILED(hr)) 01156 { 01157 wined3d_mutex_unlock(); 01158 WARN("Cannot get the current adapter format\n"); 01159 return hr; 01160 } 01161 01162 for (i = 0; i < sizeof(FormatList) / sizeof(*FormatList); ++i) 01163 { 01164 hr = wined3d_check_device_format(This->ddraw->wined3d, WINED3DADAPTER_DEFAULT, WINED3D_DEVICE_TYPE_HAL, 01165 mode.format_id, 0, WINED3D_RTYPE_TEXTURE, FormatList[i], SURFACE_OPENGL); 01166 if (hr == D3D_OK) 01167 { 01168 DDPIXELFORMAT pformat; 01169 01170 memset(&pformat, 0, sizeof(pformat)); 01171 pformat.dwSize = sizeof(pformat); 01172 PixelFormat_WineD3DtoDD(&pformat, FormatList[i]); 01173 01174 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]); 01175 hr = Callback(&pformat, Arg); 01176 if(hr != DDENUMRET_OK) 01177 { 01178 TRACE("Format enumeration cancelled by application\n"); 01179 wined3d_mutex_unlock(); 01180 return D3D_OK; 01181 } 01182 } 01183 } 01184 01185 for (i = 0; i < sizeof(BumpFormatList) / sizeof(*BumpFormatList); ++i) 01186 { 01187 hr = wined3d_check_device_format(This->ddraw->wined3d, WINED3DADAPTER_DEFAULT, 01188 WINED3D_DEVICE_TYPE_HAL, mode.format_id, WINED3DUSAGE_QUERY_LEGACYBUMPMAP, 01189 WINED3D_RTYPE_TEXTURE, BumpFormatList[i], SURFACE_OPENGL); 01190 if (hr == D3D_OK) 01191 { 01192 DDPIXELFORMAT pformat; 01193 01194 memset(&pformat, 0, sizeof(pformat)); 01195 pformat.dwSize = sizeof(pformat); 01196 PixelFormat_WineD3DtoDD(&pformat, BumpFormatList[i]); 01197 01198 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList[i]); 01199 hr = Callback(&pformat, Arg); 01200 if(hr != DDENUMRET_OK) 01201 { 01202 TRACE("Format enumeration cancelled by application\n"); 01203 wined3d_mutex_unlock(); 01204 return D3D_OK; 01205 } 01206 } 01207 } 01208 TRACE("End of enumeration\n"); 01209 wined3d_mutex_unlock(); 01210 01211 return D3D_OK; 01212 } 01213 01214 static HRESULT WINAPI 01215 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup(IDirect3DDevice7 *iface, 01216 LPD3DENUMPIXELFORMATSCALLBACK Callback, 01217 void *Arg) 01218 { 01219 return IDirect3DDeviceImpl_7_EnumTextureFormats(iface, Callback, Arg); 01220 } 01221 01222 static HRESULT WINAPI 01223 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve(IDirect3DDevice7 *iface, 01224 LPD3DENUMPIXELFORMATSCALLBACK Callback, 01225 void *Arg) 01226 { 01227 HRESULT hr; 01228 WORD old_fpucw; 01229 01230 old_fpucw = d3d_fpu_setup(); 01231 hr = IDirect3DDeviceImpl_7_EnumTextureFormats(iface, Callback, Arg); 01232 set_fpu_control_word(old_fpucw); 01233 01234 return hr; 01235 } 01236 01237 static HRESULT WINAPI IDirect3DDeviceImpl_3_EnumTextureFormats(IDirect3DDevice3 *iface, 01238 LPD3DENUMPIXELFORMATSCALLBACK Callback, void *Arg) 01239 { 01240 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 01241 01242 TRACE("iface %p, callback %p, context %p.\n", iface, Callback, Arg); 01243 01244 return IDirect3DDevice7_EnumTextureFormats(&This->IDirect3DDevice7_iface, Callback, Arg); 01245 } 01246 01247 /***************************************************************************** 01248 * IDirect3DDevice2::EnumTextureformats 01249 * 01250 * EnumTextureFormats for Version 1 and 2, see 01251 * IDirect3DDevice7::EnumTexureFormats for a more detailed description. 01252 * 01253 * This version has a different callback and does not enumerate FourCC 01254 * formats 01255 * 01256 *****************************************************************************/ 01257 static HRESULT WINAPI 01258 IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2 *iface, 01259 LPD3DENUMTEXTUREFORMATSCALLBACK Callback, 01260 void *Arg) 01261 { 01262 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 01263 struct wined3d_display_mode mode; 01264 HRESULT hr; 01265 unsigned int i; 01266 01267 static const enum wined3d_format_id FormatList[] = 01268 { 01269 /* 16 bit */ 01270 WINED3DFMT_B5G5R5X1_UNORM, 01271 WINED3DFMT_B5G5R5A1_UNORM, 01272 WINED3DFMT_B4G4R4A4_UNORM, 01273 WINED3DFMT_B5G6R5_UNORM, 01274 /* 32 bit */ 01275 WINED3DFMT_B8G8R8X8_UNORM, 01276 WINED3DFMT_B8G8R8A8_UNORM, 01277 /* 8 bit */ 01278 WINED3DFMT_B2G3R3_UNORM, 01279 WINED3DFMT_P8_UINT, 01280 /* FOURCC codes - Not in this version*/ 01281 }; 01282 01283 TRACE("iface %p, callback %p, context %p.\n", iface, Callback, Arg); 01284 01285 if(!Callback) 01286 return DDERR_INVALIDPARAMS; 01287 01288 wined3d_mutex_lock(); 01289 01290 memset(&mode, 0, sizeof(mode)); 01291 hr = wined3d_device_get_display_mode(This->ddraw->wined3d_device, 0, &mode); 01292 if (FAILED(hr)) 01293 { 01294 wined3d_mutex_unlock(); 01295 WARN("Cannot get the current adapter format\n"); 01296 return hr; 01297 } 01298 01299 for (i = 0; i < sizeof(FormatList) / sizeof(*FormatList); ++i) 01300 { 01301 hr = wined3d_check_device_format(This->ddraw->wined3d, 0, WINED3D_DEVICE_TYPE_HAL, 01302 mode.format_id, 0, WINED3D_RTYPE_TEXTURE, FormatList[i], SURFACE_OPENGL); 01303 if (hr == D3D_OK) 01304 { 01305 DDSURFACEDESC sdesc; 01306 01307 memset(&sdesc, 0, sizeof(sdesc)); 01308 sdesc.dwSize = sizeof(sdesc); 01309 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS; 01310 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE; 01311 sdesc.ddpfPixelFormat.dwSize = sizeof(sdesc.ddpfPixelFormat); 01312 PixelFormat_WineD3DtoDD(&sdesc.ddpfPixelFormat, FormatList[i]); 01313 01314 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]); 01315 hr = Callback(&sdesc, Arg); 01316 if(hr != DDENUMRET_OK) 01317 { 01318 TRACE("Format enumeration cancelled by application\n"); 01319 wined3d_mutex_unlock(); 01320 return D3D_OK; 01321 } 01322 } 01323 } 01324 TRACE("End of enumeration\n"); 01325 wined3d_mutex_unlock(); 01326 01327 return D3D_OK; 01328 } 01329 01330 static HRESULT WINAPI IDirect3DDeviceImpl_1_EnumTextureFormats(IDirect3DDevice *iface, 01331 LPD3DENUMTEXTUREFORMATSCALLBACK Callback, void *Arg) 01332 { 01333 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface); 01334 01335 TRACE("iface %p, callback %p, context %p.\n", iface, Callback, Arg); 01336 01337 return IDirect3DDevice2_EnumTextureFormats(&This->IDirect3DDevice2_iface, Callback, Arg); 01338 } 01339 01340 /***************************************************************************** 01341 * IDirect3DDevice::CreateMatrix 01342 * 01343 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is 01344 * allocated for the handle. 01345 * 01346 * Version 1 only 01347 * 01348 * Params 01349 * D3DMatHandle: Address to return the handle at 01350 * 01351 * Returns: 01352 * D3D_OK on success 01353 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL 01354 * 01355 *****************************************************************************/ 01356 static HRESULT WINAPI 01357 IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE *D3DMatHandle) 01358 { 01359 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface); 01360 D3DMATRIX *Matrix; 01361 DWORD h; 01362 01363 TRACE("iface %p, matrix_handle %p.\n", iface, D3DMatHandle); 01364 01365 if(!D3DMatHandle) 01366 return DDERR_INVALIDPARAMS; 01367 01368 Matrix = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(D3DMATRIX)); 01369 if(!Matrix) 01370 { 01371 ERR("Out of memory when allocating a D3DMATRIX\n"); 01372 return DDERR_OUTOFMEMORY; 01373 } 01374 01375 wined3d_mutex_lock(); 01376 01377 h = ddraw_allocate_handle(&This->handle_table, Matrix, DDRAW_HANDLE_MATRIX); 01378 if (h == DDRAW_INVALID_HANDLE) 01379 { 01380 ERR("Failed to allocate a matrix handle.\n"); 01381 HeapFree(GetProcessHeap(), 0, Matrix); 01382 wined3d_mutex_unlock(); 01383 return DDERR_OUTOFMEMORY; 01384 } 01385 01386 *D3DMatHandle = h + 1; 01387 01388 TRACE(" returning matrix handle %d\n", *D3DMatHandle); 01389 01390 wined3d_mutex_unlock(); 01391 01392 return D3D_OK; 01393 } 01394 01395 /***************************************************************************** 01396 * IDirect3DDevice::SetMatrix 01397 * 01398 * Sets a matrix for a matrix handle. The matrix is copied into the memory 01399 * allocated for the handle 01400 * 01401 * Version 1 only 01402 * 01403 * Params: 01404 * D3DMatHandle: Handle to set the matrix to 01405 * D3DMatrix: Matrix to set 01406 * 01407 * Returns: 01408 * D3D_OK on success 01409 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix 01410 * to set is NULL 01411 * 01412 *****************************************************************************/ 01413 static HRESULT WINAPI 01414 IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice *iface, 01415 D3DMATRIXHANDLE D3DMatHandle, 01416 D3DMATRIX *D3DMatrix) 01417 { 01418 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface); 01419 D3DMATRIX *m; 01420 01421 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface, D3DMatHandle, D3DMatrix); 01422 01423 if (!D3DMatrix) return DDERR_INVALIDPARAMS; 01424 01425 wined3d_mutex_lock(); 01426 01427 m = ddraw_get_object(&This->handle_table, D3DMatHandle - 1, DDRAW_HANDLE_MATRIX); 01428 if (!m) 01429 { 01430 WARN("Invalid matrix handle.\n"); 01431 wined3d_mutex_unlock(); 01432 return DDERR_INVALIDPARAMS; 01433 } 01434 01435 if (TRACE_ON(ddraw)) 01436 dump_D3DMATRIX(D3DMatrix); 01437 01438 *m = *D3DMatrix; 01439 01440 if (D3DMatHandle == This->world) 01441 wined3d_device_set_transform(This->wined3d_device, 01442 WINED3D_TS_WORLD_MATRIX(0), (struct wined3d_matrix *)D3DMatrix); 01443 01444 if (D3DMatHandle == This->view) 01445 wined3d_device_set_transform(This->wined3d_device, 01446 WINED3D_TS_VIEW, (struct wined3d_matrix *)D3DMatrix); 01447 01448 if (D3DMatHandle == This->proj) 01449 wined3d_device_set_transform(This->wined3d_device, 01450 WINED3D_TS_PROJECTION, (struct wined3d_matrix *)D3DMatrix); 01451 01452 wined3d_mutex_unlock(); 01453 01454 return D3D_OK; 01455 } 01456 01457 /***************************************************************************** 01458 * IDirect3DDevice::GetMatrix 01459 * 01460 * Returns the content of a D3DMATRIX handle 01461 * 01462 * Version 1 only 01463 * 01464 * Params: 01465 * D3DMatHandle: Matrix handle to read the content from 01466 * D3DMatrix: Address to store the content at 01467 * 01468 * Returns: 01469 * D3D_OK on success 01470 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL 01471 * 01472 *****************************************************************************/ 01473 static HRESULT WINAPI 01474 IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice *iface, 01475 D3DMATRIXHANDLE D3DMatHandle, 01476 D3DMATRIX *D3DMatrix) 01477 { 01478 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface); 01479 D3DMATRIX *m; 01480 01481 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface, D3DMatHandle, D3DMatrix); 01482 01483 if (!D3DMatrix) return DDERR_INVALIDPARAMS; 01484 01485 wined3d_mutex_lock(); 01486 01487 m = ddraw_get_object(&This->handle_table, D3DMatHandle - 1, DDRAW_HANDLE_MATRIX); 01488 if (!m) 01489 { 01490 WARN("Invalid matrix handle.\n"); 01491 wined3d_mutex_unlock(); 01492 return DDERR_INVALIDPARAMS; 01493 } 01494 01495 *D3DMatrix = *m; 01496 01497 wined3d_mutex_unlock(); 01498 01499 return D3D_OK; 01500 } 01501 01502 /***************************************************************************** 01503 * IDirect3DDevice::DeleteMatrix 01504 * 01505 * Destroys a Matrix handle. Frees the memory and unsets the handle data 01506 * 01507 * Version 1 only 01508 * 01509 * Params: 01510 * D3DMatHandle: Handle to destroy 01511 * 01512 * Returns: 01513 * D3D_OK on success 01514 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid 01515 * 01516 *****************************************************************************/ 01517 static HRESULT WINAPI 01518 IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice *iface, 01519 D3DMATRIXHANDLE D3DMatHandle) 01520 { 01521 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface); 01522 D3DMATRIX *m; 01523 01524 TRACE("iface %p, matrix_handle %#x.\n", iface, D3DMatHandle); 01525 01526 wined3d_mutex_lock(); 01527 01528 m = ddraw_free_handle(&This->handle_table, D3DMatHandle - 1, DDRAW_HANDLE_MATRIX); 01529 if (!m) 01530 { 01531 WARN("Invalid matrix handle.\n"); 01532 wined3d_mutex_unlock(); 01533 return DDERR_INVALIDPARAMS; 01534 } 01535 01536 wined3d_mutex_unlock(); 01537 01538 HeapFree(GetProcessHeap(), 0, m); 01539 01540 return D3D_OK; 01541 } 01542 01543 /***************************************************************************** 01544 * IDirect3DDevice7::BeginScene 01545 * 01546 * This method must be called before any rendering is performed. 01547 * IDirect3DDevice::EndScene has to be called after the scene is complete 01548 * 01549 * Version 1, 2, 3 and 7 01550 * 01551 * Returns: 01552 * D3D_OK on success, for details see IWineD3DDevice::BeginScene 01553 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already 01554 * started scene). 01555 * 01556 *****************************************************************************/ 01557 static HRESULT 01558 IDirect3DDeviceImpl_7_BeginScene(IDirect3DDevice7 *iface) 01559 { 01560 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 01561 HRESULT hr; 01562 01563 TRACE("iface %p.\n", iface); 01564 01565 wined3d_mutex_lock(); 01566 hr = wined3d_device_begin_scene(This->wined3d_device); 01567 wined3d_mutex_unlock(); 01568 01569 if(hr == WINED3D_OK) return D3D_OK; 01570 else return D3DERR_SCENE_IN_SCENE; /* TODO: Other possible causes of failure */ 01571 } 01572 01573 static HRESULT WINAPI 01574 IDirect3DDeviceImpl_7_BeginScene_FPUSetup(IDirect3DDevice7 *iface) 01575 { 01576 return IDirect3DDeviceImpl_7_BeginScene(iface); 01577 } 01578 01579 static HRESULT WINAPI 01580 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve(IDirect3DDevice7 *iface) 01581 { 01582 HRESULT hr; 01583 WORD old_fpucw; 01584 01585 old_fpucw = d3d_fpu_setup(); 01586 hr = IDirect3DDeviceImpl_7_BeginScene(iface); 01587 set_fpu_control_word(old_fpucw); 01588 01589 return hr; 01590 } 01591 01592 static HRESULT WINAPI IDirect3DDeviceImpl_3_BeginScene(IDirect3DDevice3 *iface) 01593 { 01594 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 01595 TRACE("iface %p.\n", iface); 01596 01597 return IDirect3DDevice7_BeginScene(&This->IDirect3DDevice7_iface); 01598 } 01599 01600 static HRESULT WINAPI IDirect3DDeviceImpl_2_BeginScene(IDirect3DDevice2 *iface) 01601 { 01602 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 01603 TRACE("iface %p.\n", iface); 01604 01605 return IDirect3DDevice7_BeginScene(&This->IDirect3DDevice7_iface); 01606 } 01607 01608 static HRESULT WINAPI IDirect3DDeviceImpl_1_BeginScene(IDirect3DDevice *iface) 01609 { 01610 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface); 01611 TRACE("iface %p.\n", iface); 01612 01613 return IDirect3DDevice7_BeginScene(&This->IDirect3DDevice7_iface); 01614 } 01615 01616 /***************************************************************************** 01617 * IDirect3DDevice7::EndScene 01618 * 01619 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene. 01620 * This method must be called after rendering is finished. 01621 * 01622 * Version 1, 2, 3 and 7 01623 * 01624 * Returns: 01625 * D3D_OK on success, for details see IWineD3DDevice::EndScene 01626 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does 01627 * that only if the scene was already ended. 01628 * 01629 *****************************************************************************/ 01630 static HRESULT 01631 IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7 *iface) 01632 { 01633 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 01634 HRESULT hr; 01635 01636 TRACE("iface %p.\n", iface); 01637 01638 wined3d_mutex_lock(); 01639 hr = wined3d_device_end_scene(This->wined3d_device); 01640 wined3d_mutex_unlock(); 01641 01642 if(hr == WINED3D_OK) return D3D_OK; 01643 else return D3DERR_SCENE_NOT_IN_SCENE; 01644 } 01645 01646 static HRESULT WINAPI DECLSPEC_HOTPATCH 01647 IDirect3DDeviceImpl_7_EndScene_FPUSetup(IDirect3DDevice7 *iface) 01648 { 01649 return IDirect3DDeviceImpl_7_EndScene(iface); 01650 } 01651 01652 static HRESULT WINAPI DECLSPEC_HOTPATCH 01653 IDirect3DDeviceImpl_7_EndScene_FPUPreserve(IDirect3DDevice7 *iface) 01654 { 01655 HRESULT hr; 01656 WORD old_fpucw; 01657 01658 old_fpucw = d3d_fpu_setup(); 01659 hr = IDirect3DDeviceImpl_7_EndScene(iface); 01660 set_fpu_control_word(old_fpucw); 01661 01662 return hr; 01663 } 01664 01665 static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3 *iface) 01666 { 01667 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 01668 TRACE("iface %p.\n", iface); 01669 01670 return IDirect3DDevice7_EndScene(&This->IDirect3DDevice7_iface); 01671 } 01672 01673 static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2 *iface) 01674 { 01675 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 01676 TRACE("iface %p.\n", iface); 01677 01678 return IDirect3DDevice7_EndScene(&This->IDirect3DDevice7_iface); 01679 } 01680 01681 static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice *iface) 01682 { 01683 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface); 01684 TRACE("iface %p.\n", iface); 01685 01686 return IDirect3DDevice7_EndScene(&This->IDirect3DDevice7_iface); 01687 } 01688 01689 /***************************************************************************** 01690 * IDirect3DDevice7::GetDirect3D 01691 * 01692 * Returns the IDirect3D(= interface to the DirectDraw object) used to create 01693 * this device. 01694 * 01695 * Params: 01696 * Direct3D7: Address to store the interface pointer at 01697 * 01698 * Returns: 01699 * D3D_OK on success 01700 * DDERR_INVALIDPARAMS if Direct3D7 == NULL 01701 * 01702 *****************************************************************************/ 01703 static HRESULT WINAPI 01704 IDirect3DDeviceImpl_7_GetDirect3D(IDirect3DDevice7 *iface, 01705 IDirect3D7 **Direct3D7) 01706 { 01707 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 01708 01709 TRACE("iface %p, d3d %p.\n", iface, Direct3D7); 01710 01711 if(!Direct3D7) 01712 return DDERR_INVALIDPARAMS; 01713 01714 *Direct3D7 = &This->ddraw->IDirect3D7_iface; 01715 IDirect3D7_AddRef(*Direct3D7); 01716 01717 TRACE(" returning interface %p\n", *Direct3D7); 01718 return D3D_OK; 01719 } 01720 01721 static HRESULT WINAPI IDirect3DDeviceImpl_3_GetDirect3D(IDirect3DDevice3 *iface, 01722 IDirect3D3 **Direct3D3) 01723 { 01724 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 01725 01726 TRACE("iface %p, d3d %p.\n", iface, Direct3D3); 01727 01728 if(!Direct3D3) 01729 return DDERR_INVALIDPARAMS; 01730 01731 IDirect3D3_AddRef(&This->ddraw->IDirect3D3_iface); 01732 *Direct3D3 = &This->ddraw->IDirect3D3_iface; 01733 TRACE(" returning interface %p\n", *Direct3D3); 01734 return D3D_OK; 01735 } 01736 01737 static HRESULT WINAPI IDirect3DDeviceImpl_2_GetDirect3D(IDirect3DDevice2 *iface, 01738 IDirect3D2 **Direct3D2) 01739 { 01740 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 01741 01742 TRACE("iface %p, d3d %p.\n", iface, Direct3D2); 01743 01744 if(!Direct3D2) 01745 return DDERR_INVALIDPARAMS; 01746 01747 IDirect3D2_AddRef(&This->ddraw->IDirect3D2_iface); 01748 *Direct3D2 = &This->ddraw->IDirect3D2_iface; 01749 TRACE(" returning interface %p\n", *Direct3D2); 01750 return D3D_OK; 01751 } 01752 01753 static HRESULT WINAPI IDirect3DDeviceImpl_1_GetDirect3D(IDirect3DDevice *iface, 01754 IDirect3D **Direct3D) 01755 { 01756 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface); 01757 01758 TRACE("iface %p, d3d %p.\n", iface, Direct3D); 01759 01760 if(!Direct3D) 01761 return DDERR_INVALIDPARAMS; 01762 01763 IDirect3D_AddRef(&This->ddraw->IDirect3D_iface); 01764 *Direct3D = &This->ddraw->IDirect3D_iface; 01765 TRACE(" returning interface %p\n", *Direct3D); 01766 return D3D_OK; 01767 } 01768 01769 /***************************************************************************** 01770 * IDirect3DDevice3::SetCurrentViewport 01771 * 01772 * Sets a Direct3DViewport as the current viewport. 01773 * For the thunks note that all viewport interface versions are equal 01774 * 01775 * Params: 01776 * Direct3DViewport3: The viewport to set 01777 * 01778 * Version 2 and 3 01779 * 01780 * Returns: 01781 * D3D_OK on success 01782 * (Is a NULL viewport valid?) 01783 * 01784 *****************************************************************************/ 01785 static HRESULT WINAPI 01786 IDirect3DDeviceImpl_3_SetCurrentViewport(IDirect3DDevice3 *iface, 01787 IDirect3DViewport3 *Direct3DViewport3) 01788 { 01789 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 01790 IDirect3DViewportImpl *vp = unsafe_impl_from_IDirect3DViewport3(Direct3DViewport3); 01791 01792 TRACE("iface %p, viewport %p.\n", iface, Direct3DViewport3); 01793 01794 wined3d_mutex_lock(); 01795 /* Do nothing if the specified viewport is the same as the current one */ 01796 if (This->current_viewport == vp ) 01797 { 01798 wined3d_mutex_unlock(); 01799 return D3D_OK; 01800 } 01801 01802 if (vp->active_device != This) 01803 { 01804 WARN("Viewport %p active device is %p.\n", vp, vp->active_device); 01805 wined3d_mutex_unlock(); 01806 return DDERR_INVALIDPARAMS; 01807 } 01808 01809 /* Release previous viewport and AddRef the new one */ 01810 if (This->current_viewport) 01811 { 01812 TRACE("ViewportImpl is at %p, interface is at %p\n", This->current_viewport, 01813 &This->current_viewport->IDirect3DViewport3_iface); 01814 IDirect3DViewport3_Release(&This->current_viewport->IDirect3DViewport3_iface); 01815 } 01816 IDirect3DViewport3_AddRef(Direct3DViewport3); 01817 01818 /* Set this viewport as the current viewport */ 01819 This->current_viewport = vp; 01820 01821 /* Activate this viewport */ 01822 viewport_activate(This->current_viewport, FALSE); 01823 01824 wined3d_mutex_unlock(); 01825 01826 return D3D_OK; 01827 } 01828 01829 static HRESULT WINAPI IDirect3DDeviceImpl_2_SetCurrentViewport(IDirect3DDevice2 *iface, 01830 IDirect3DViewport2 *Direct3DViewport2) 01831 { 01832 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 01833 IDirect3DViewportImpl *vp = unsafe_impl_from_IDirect3DViewport2(Direct3DViewport2); 01834 01835 TRACE("iface %p, viewport %p.\n", iface, Direct3DViewport2); 01836 01837 return IDirect3DDevice3_SetCurrentViewport(&This->IDirect3DDevice3_iface, 01838 &vp->IDirect3DViewport3_iface); 01839 } 01840 01841 /***************************************************************************** 01842 * IDirect3DDevice3::GetCurrentViewport 01843 * 01844 * Returns the currently active viewport. 01845 * 01846 * Version 2 and 3 01847 * 01848 * Params: 01849 * Direct3DViewport3: Address to return the interface pointer at 01850 * 01851 * Returns: 01852 * D3D_OK on success 01853 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL 01854 * 01855 *****************************************************************************/ 01856 static HRESULT WINAPI 01857 IDirect3DDeviceImpl_3_GetCurrentViewport(IDirect3DDevice3 *iface, 01858 IDirect3DViewport3 **Direct3DViewport3) 01859 { 01860 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 01861 01862 TRACE("iface %p, viewport %p.\n", iface, Direct3DViewport3); 01863 01864 if(!Direct3DViewport3) 01865 return DDERR_INVALIDPARAMS; 01866 01867 wined3d_mutex_lock(); 01868 *Direct3DViewport3 = &This->current_viewport->IDirect3DViewport3_iface; 01869 01870 /* AddRef the returned viewport */ 01871 if(*Direct3DViewport3) IDirect3DViewport3_AddRef(*Direct3DViewport3); 01872 01873 TRACE(" returning interface %p\n", *Direct3DViewport3); 01874 01875 wined3d_mutex_unlock(); 01876 01877 return D3D_OK; 01878 } 01879 01880 static HRESULT WINAPI IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2 *iface, 01881 IDirect3DViewport2 **Direct3DViewport2) 01882 { 01883 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 01884 HRESULT hr; 01885 01886 TRACE("iface %p, viewport %p.\n", iface, Direct3DViewport2); 01887 01888 hr = IDirect3DDevice3_GetCurrentViewport(&This->IDirect3DDevice3_iface, 01889 (IDirect3DViewport3 **)Direct3DViewport2); 01890 if(hr != D3D_OK) return hr; 01891 return D3D_OK; 01892 } 01893 01894 /***************************************************************************** 01895 * IDirect3DDevice7::SetRenderTarget 01896 * 01897 * Sets the render target for the Direct3DDevice. 01898 * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and 01899 * IDirectDrawSurface3 == IDirectDrawSurface 01900 * 01901 * Version 2, 3 and 7 01902 * 01903 * Params: 01904 * NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new 01905 * render target 01906 * Flags: Some flags 01907 * 01908 * Returns: 01909 * D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget 01910 * 01911 *****************************************************************************/ 01912 static HRESULT d3d_device_set_render_target(IDirect3DDeviceImpl *This, IDirectDrawSurfaceImpl *Target) 01913 { 01914 HRESULT hr; 01915 01916 wined3d_mutex_lock(); 01917 01918 if(This->target == Target) 01919 { 01920 TRACE("No-op SetRenderTarget operation, not doing anything\n"); 01921 wined3d_mutex_unlock(); 01922 return D3D_OK; 01923 } 01924 This->target = Target; 01925 hr = wined3d_device_set_render_target(This->wined3d_device, 0, 01926 Target ? Target->wined3d_surface : NULL, FALSE); 01927 if(hr != D3D_OK) 01928 { 01929 wined3d_mutex_unlock(); 01930 return hr; 01931 } 01932 IDirect3DDeviceImpl_UpdateDepthStencil(This); 01933 01934 wined3d_mutex_unlock(); 01935 01936 return D3D_OK; 01937 } 01938 01939 static HRESULT 01940 IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7 *iface, 01941 IDirectDrawSurface7 *NewTarget, 01942 DWORD Flags) 01943 { 01944 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 01945 IDirectDrawSurfaceImpl *Target = unsafe_impl_from_IDirectDrawSurface7(NewTarget); 01946 01947 TRACE("iface %p, target %p, flags %#x.\n", iface, NewTarget, Flags); 01948 /* Flags: Not used */ 01949 01950 IDirectDrawSurface7_AddRef(NewTarget); 01951 IDirectDrawSurface7_Release(&This->target->IDirectDrawSurface7_iface); 01952 return d3d_device_set_render_target(This, Target); 01953 } 01954 01955 static HRESULT WINAPI 01956 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup(IDirect3DDevice7 *iface, 01957 IDirectDrawSurface7 *NewTarget, 01958 DWORD Flags) 01959 { 01960 return IDirect3DDeviceImpl_7_SetRenderTarget(iface, NewTarget, Flags); 01961 } 01962 01963 static HRESULT WINAPI 01964 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve(IDirect3DDevice7 *iface, 01965 IDirectDrawSurface7 *NewTarget, 01966 DWORD Flags) 01967 { 01968 HRESULT hr; 01969 WORD old_fpucw; 01970 01971 old_fpucw = d3d_fpu_setup(); 01972 hr = IDirect3DDeviceImpl_7_SetRenderTarget(iface, NewTarget, Flags); 01973 set_fpu_control_word(old_fpucw); 01974 01975 return hr; 01976 } 01977 01978 static HRESULT WINAPI IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3 *iface, 01979 IDirectDrawSurface4 *NewRenderTarget, DWORD Flags) 01980 { 01981 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 01982 IDirectDrawSurfaceImpl *Target = unsafe_impl_from_IDirectDrawSurface4(NewRenderTarget); 01983 01984 TRACE("iface %p, target %p, flags %#x.\n", iface, NewRenderTarget, Flags); 01985 01986 IDirectDrawSurface4_AddRef(NewRenderTarget); 01987 IDirectDrawSurface4_Release(&This->target->IDirectDrawSurface4_iface); 01988 return d3d_device_set_render_target(This, Target); 01989 } 01990 01991 static HRESULT WINAPI IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2 *iface, 01992 IDirectDrawSurface *NewRenderTarget, DWORD Flags) 01993 { 01994 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 01995 IDirectDrawSurfaceImpl *Target = unsafe_impl_from_IDirectDrawSurface(NewRenderTarget); 01996 01997 TRACE("iface %p, target %p, flags %#x.\n", iface, NewRenderTarget, Flags); 01998 01999 IDirectDrawSurface_AddRef(NewRenderTarget); 02000 IDirectDrawSurface_Release(&This->target->IDirectDrawSurface_iface); 02001 return d3d_device_set_render_target(This, Target); 02002 } 02003 02004 /***************************************************************************** 02005 * IDirect3DDevice7::GetRenderTarget 02006 * 02007 * Returns the current render target. 02008 * This is handled locally, because the WineD3D render target's parent 02009 * is an IParent 02010 * 02011 * Version 2, 3 and 7 02012 * 02013 * Params: 02014 * RenderTarget: Address to store the surface interface pointer 02015 * 02016 * Returns: 02017 * D3D_OK on success 02018 * DDERR_INVALIDPARAMS if RenderTarget == NULL 02019 * 02020 *****************************************************************************/ 02021 static HRESULT WINAPI 02022 IDirect3DDeviceImpl_7_GetRenderTarget(IDirect3DDevice7 *iface, 02023 IDirectDrawSurface7 **RenderTarget) 02024 { 02025 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 02026 02027 TRACE("iface %p, target %p.\n", iface, RenderTarget); 02028 02029 if(!RenderTarget) 02030 return DDERR_INVALIDPARAMS; 02031 02032 wined3d_mutex_lock(); 02033 *RenderTarget = &This->target->IDirectDrawSurface7_iface; 02034 IDirectDrawSurface7_AddRef(*RenderTarget); 02035 wined3d_mutex_unlock(); 02036 02037 return D3D_OK; 02038 } 02039 02040 static HRESULT WINAPI IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3 *iface, 02041 IDirectDrawSurface4 **RenderTarget) 02042 { 02043 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 02044 IDirectDrawSurface7 *RenderTarget7; 02045 IDirectDrawSurfaceImpl *RenderTargetImpl; 02046 HRESULT hr; 02047 02048 TRACE("iface %p, target %p.\n", iface, RenderTarget); 02049 02050 if(!RenderTarget) 02051 return DDERR_INVALIDPARAMS; 02052 02053 hr = IDirect3DDevice7_GetRenderTarget(&This->IDirect3DDevice7_iface, &RenderTarget7); 02054 if(hr != D3D_OK) return hr; 02055 RenderTargetImpl = impl_from_IDirectDrawSurface7(RenderTarget7); 02056 *RenderTarget = &RenderTargetImpl->IDirectDrawSurface4_iface; 02057 IDirectDrawSurface4_AddRef(*RenderTarget); 02058 IDirectDrawSurface7_Release(RenderTarget7); 02059 return D3D_OK; 02060 } 02061 02062 static HRESULT WINAPI IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2 *iface, 02063 IDirectDrawSurface **RenderTarget) 02064 { 02065 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 02066 IDirectDrawSurface7 *RenderTarget7; 02067 IDirectDrawSurfaceImpl *RenderTargetImpl; 02068 HRESULT hr; 02069 02070 TRACE("iface %p, target %p.\n", iface, RenderTarget); 02071 02072 if(!RenderTarget) 02073 return DDERR_INVALIDPARAMS; 02074 02075 hr = IDirect3DDevice7_GetRenderTarget(&This->IDirect3DDevice7_iface, &RenderTarget7); 02076 if(hr != D3D_OK) return hr; 02077 RenderTargetImpl = impl_from_IDirectDrawSurface7(RenderTarget7); 02078 *RenderTarget = &RenderTargetImpl->IDirectDrawSurface_iface; 02079 IDirectDrawSurface_AddRef(*RenderTarget); 02080 IDirectDrawSurface7_Release(RenderTarget7); 02081 return D3D_OK; 02082 } 02083 02084 /***************************************************************************** 02085 * IDirect3DDevice3::Begin 02086 * 02087 * Begins a description block of vertices. This is similar to glBegin() 02088 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices 02089 * described with IDirect3DDevice::Vertex are drawn. 02090 * 02091 * Version 2 and 3 02092 * 02093 * Params: 02094 * PrimitiveType: The type of primitives to draw 02095 * VertexTypeDesc: A flexible vertex format description of the vertices 02096 * Flags: Some flags.. 02097 * 02098 * Returns: 02099 * D3D_OK on success 02100 * 02101 *****************************************************************************/ 02102 static HRESULT WINAPI 02103 IDirect3DDeviceImpl_3_Begin(IDirect3DDevice3 *iface, 02104 D3DPRIMITIVETYPE PrimitiveType, 02105 DWORD VertexTypeDesc, 02106 DWORD Flags) 02107 { 02108 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 02109 02110 TRACE("iface %p, primitive_type %#x, FVF %#x, flags %#x.\n", 02111 iface, PrimitiveType, VertexTypeDesc, Flags); 02112 02113 wined3d_mutex_lock(); 02114 This->primitive_type = PrimitiveType; 02115 This->vertex_type = VertexTypeDesc; 02116 This->render_flags = Flags; 02117 This->vertex_size = get_flexible_vertex_size(This->vertex_type); 02118 This->nb_vertices = 0; 02119 wined3d_mutex_unlock(); 02120 02121 return D3D_OK; 02122 } 02123 02124 static HRESULT WINAPI IDirect3DDeviceImpl_2_Begin(IDirect3DDevice2 *iface, D3DPRIMITIVETYPE d3dpt, 02125 D3DVERTEXTYPE dwVertexTypeDesc, DWORD dwFlags) 02126 { 02127 DWORD FVF; 02128 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 02129 02130 TRACE("iface %p, primitive_type %#x, vertex_type %#x, flags %#x.\n", 02131 iface, d3dpt, dwVertexTypeDesc, dwFlags); 02132 02133 switch(dwVertexTypeDesc) 02134 { 02135 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break; 02136 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break; 02137 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break; 02138 default: 02139 ERR("Unexpected vertex type %d\n", dwVertexTypeDesc); 02140 return DDERR_INVALIDPARAMS; /* Should never happen */ 02141 }; 02142 02143 return IDirect3DDevice3_Begin(&This->IDirect3DDevice3_iface, d3dpt, FVF, dwFlags); 02144 } 02145 02146 /***************************************************************************** 02147 * IDirect3DDevice3::BeginIndexed 02148 * 02149 * Draws primitives based on vertices in a vertex array which are specified 02150 * by indices. 02151 * 02152 * Version 2 and 3 02153 * 02154 * Params: 02155 * PrimitiveType: Primitive type to draw 02156 * VertexType: A FVF description of the vertex format 02157 * Vertices: pointer to an array containing the vertices 02158 * NumVertices: The number of vertices in the vertex array 02159 * Flags: Some flags ... 02160 * 02161 * Returns: 02162 * D3D_OK, because it's a stub 02163 * 02164 *****************************************************************************/ 02165 static HRESULT WINAPI 02166 IDirect3DDeviceImpl_3_BeginIndexed(IDirect3DDevice3 *iface, 02167 D3DPRIMITIVETYPE PrimitiveType, 02168 DWORD VertexType, 02169 void *Vertices, 02170 DWORD NumVertices, 02171 DWORD Flags) 02172 { 02173 FIXME("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x stub!\n", 02174 iface, PrimitiveType, VertexType, Vertices, NumVertices, Flags); 02175 02176 return D3D_OK; 02177 } 02178 02179 02180 static HRESULT WINAPI IDirect3DDeviceImpl_2_BeginIndexed(IDirect3DDevice2 *iface, 02181 D3DPRIMITIVETYPE d3dptPrimitiveType, D3DVERTEXTYPE d3dvtVertexType, 02182 void *lpvVertices, DWORD dwNumVertices, DWORD dwFlags) 02183 { 02184 DWORD FVF; 02185 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 02186 02187 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x stub!\n", 02188 iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwNumVertices, dwFlags); 02189 02190 switch(d3dvtVertexType) 02191 { 02192 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break; 02193 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break; 02194 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break; 02195 default: 02196 ERR("Unexpected vertex type %d\n", d3dvtVertexType); 02197 return DDERR_INVALIDPARAMS; /* Should never happen */ 02198 }; 02199 02200 return IDirect3DDevice3_BeginIndexed(&This->IDirect3DDevice3_iface, 02201 d3dptPrimitiveType, FVF, lpvVertices, dwNumVertices, dwFlags); 02202 } 02203 02204 /***************************************************************************** 02205 * IDirect3DDevice3::Vertex 02206 * 02207 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all 02208 * drawn vertices in a vertex buffer. If the buffer is too small, its 02209 * size is increased. 02210 * 02211 * Version 2 and 3 02212 * 02213 * Params: 02214 * Vertex: Pointer to the vertex 02215 * 02216 * Returns: 02217 * D3D_OK, on success 02218 * DDERR_INVALIDPARAMS if Vertex is NULL 02219 * 02220 *****************************************************************************/ 02221 static HRESULT WINAPI 02222 IDirect3DDeviceImpl_3_Vertex(IDirect3DDevice3 *iface, 02223 void *Vertex) 02224 { 02225 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 02226 02227 TRACE("iface %p, vertex %p.\n", iface, Vertex); 02228 02229 if(!Vertex) 02230 return DDERR_INVALIDPARAMS; 02231 02232 wined3d_mutex_lock(); 02233 if ((This->nb_vertices+1)*This->vertex_size > This->buffer_size) 02234 { 02235 BYTE *old_buffer; 02236 This->buffer_size = This->buffer_size ? This->buffer_size * 2 : This->vertex_size * 3; 02237 old_buffer = This->vertex_buffer; 02238 This->vertex_buffer = HeapAlloc(GetProcessHeap(), 0, This->buffer_size); 02239 if (old_buffer) 02240 { 02241 CopyMemory(This->vertex_buffer, old_buffer, This->nb_vertices * This->vertex_size); 02242 HeapFree(GetProcessHeap(), 0, old_buffer); 02243 } 02244 } 02245 02246 CopyMemory(This->vertex_buffer + This->nb_vertices++ * This->vertex_size, Vertex, This->vertex_size); 02247 wined3d_mutex_unlock(); 02248 02249 return D3D_OK; 02250 } 02251 02252 static HRESULT WINAPI IDirect3DDeviceImpl_2_Vertex(IDirect3DDevice2 *iface, void *lpVertexType) 02253 { 02254 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 02255 02256 TRACE("iface %p, vertex %p.\n", iface, lpVertexType); 02257 02258 return IDirect3DDevice3_Vertex(&This->IDirect3DDevice3_iface, lpVertexType); 02259 } 02260 02261 /***************************************************************************** 02262 * IDirect3DDevice3::Index 02263 * 02264 * Specifies an index to a vertex to be drawn. The vertex array has to 02265 * be specified with BeginIndexed first. 02266 * 02267 * Parameters: 02268 * VertexIndex: The index of the vertex to draw 02269 * 02270 * Returns: 02271 * D3D_OK because it's a stub 02272 * 02273 *****************************************************************************/ 02274 static HRESULT WINAPI 02275 IDirect3DDeviceImpl_3_Index(IDirect3DDevice3 *iface, 02276 WORD VertexIndex) 02277 { 02278 FIXME("iface %p, index %#x stub!\n", iface, VertexIndex); 02279 02280 return D3D_OK; 02281 } 02282 02283 static HRESULT WINAPI IDirect3DDeviceImpl_2_Index(IDirect3DDevice2 *iface, WORD wVertexIndex) 02284 { 02285 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 02286 02287 TRACE("iface %p, index %#x.\n", iface, wVertexIndex); 02288 02289 return IDirect3DDevice3_Index(&This->IDirect3DDevice3_iface, wVertexIndex); 02290 } 02291 02292 /***************************************************************************** 02293 * IDirect3DDevice3::End 02294 * 02295 * Ends a draw begun with IDirect3DDevice3::Begin or 02296 * IDirect3DDevice::BeginIndexed. The vertices specified with 02297 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using 02298 * the IDirect3DDevice7::DrawPrimitive method. So far only 02299 * non-indexed mode is supported 02300 * 02301 * Version 2 and 3 02302 * 02303 * Params: 02304 * Flags: Some flags, as usual. Don't know which are defined 02305 * 02306 * Returns: 02307 * The return value of IDirect3DDevice7::DrawPrimitive 02308 * 02309 *****************************************************************************/ 02310 static HRESULT WINAPI 02311 IDirect3DDeviceImpl_3_End(IDirect3DDevice3 *iface, 02312 DWORD Flags) 02313 { 02314 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 02315 02316 TRACE("iface %p, flags %#x.\n", iface, Flags); 02317 02318 return IDirect3DDevice7_DrawPrimitive(&This->IDirect3DDevice7_iface, This->primitive_type, 02319 This->vertex_type, This->vertex_buffer, This->nb_vertices, This->render_flags); 02320 } 02321 02322 static HRESULT WINAPI IDirect3DDeviceImpl_2_End(IDirect3DDevice2 *iface, DWORD dwFlags) 02323 { 02324 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 02325 02326 TRACE("iface %p, flags %#x.\n", iface, dwFlags); 02327 02328 return IDirect3DDevice3_End(&This->IDirect3DDevice3_iface, dwFlags); 02329 } 02330 02331 /***************************************************************************** 02332 * IDirect3DDevice7::GetRenderState 02333 * 02334 * Returns the value of a render state. The possible render states are 02335 * defined in include/d3dtypes.h 02336 * 02337 * Version 2, 3 and 7 02338 * 02339 * Params: 02340 * RenderStateType: Render state to return the current setting of 02341 * Value: Address to store the value at 02342 * 02343 * Returns: 02344 * D3D_OK on success, for details see IWineD3DDevice::GetRenderState 02345 * DDERR_INVALIDPARAMS if Value == NULL 02346 * 02347 *****************************************************************************/ 02348 static HRESULT IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7 *iface, 02349 D3DRENDERSTATETYPE RenderStateType, DWORD *Value) 02350 { 02351 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 02352 HRESULT hr; 02353 02354 TRACE("iface %p, state %#x, value %p.\n", iface, RenderStateType, Value); 02355 02356 if(!Value) 02357 return DDERR_INVALIDPARAMS; 02358 02359 wined3d_mutex_lock(); 02360 switch(RenderStateType) 02361 { 02362 case D3DRENDERSTATE_TEXTUREMAG: 02363 { 02364 enum wined3d_texture_filter_type tex_mag; 02365 02366 hr = wined3d_device_get_sampler_state(This->wined3d_device, 0, WINED3D_SAMP_MAG_FILTER, &tex_mag); 02367 02368 switch (tex_mag) 02369 { 02370 case WINED3D_TEXF_POINT: 02371 *Value = D3DFILTER_NEAREST; 02372 break; 02373 case WINED3D_TEXF_LINEAR: 02374 *Value = D3DFILTER_LINEAR; 02375 break; 02376 default: 02377 ERR("Unhandled texture mag %d !\n",tex_mag); 02378 *Value = 0; 02379 } 02380 break; 02381 } 02382 02383 case D3DRENDERSTATE_TEXTUREMIN: 02384 { 02385 enum wined3d_texture_filter_type tex_min; 02386 enum wined3d_texture_filter_type tex_mip; 02387 02388 hr = wined3d_device_get_sampler_state(This->wined3d_device, 02389 0, WINED3D_SAMP_MIN_FILTER, &tex_min); 02390 if (FAILED(hr)) 02391 { 02392 wined3d_mutex_unlock(); 02393 return hr; 02394 } 02395 hr = wined3d_device_get_sampler_state(This->wined3d_device, 02396 0, WINED3D_SAMP_MIP_FILTER, &tex_mip); 02397 02398 switch (tex_min) 02399 { 02400 case WINED3D_TEXF_POINT: 02401 switch (tex_mip) 02402 { 02403 case WINED3D_TEXF_NONE: 02404 *Value = D3DFILTER_NEAREST; 02405 break; 02406 case WINED3D_TEXF_POINT: 02407 *Value = D3DFILTER_MIPNEAREST; 02408 break; 02409 case WINED3D_TEXF_LINEAR: 02410 *Value = D3DFILTER_LINEARMIPNEAREST; 02411 break; 02412 default: 02413 ERR("Unhandled mip filter %#x.\n", tex_mip); 02414 *Value = D3DFILTER_NEAREST; 02415 break; 02416 } 02417 break; 02418 case WINED3D_TEXF_LINEAR: 02419 switch (tex_mip) 02420 { 02421 case WINED3D_TEXF_NONE: 02422 *Value = D3DFILTER_LINEAR; 02423 break; 02424 case WINED3D_TEXF_POINT: 02425 *Value = D3DFILTER_MIPLINEAR; 02426 break; 02427 case WINED3D_TEXF_LINEAR: 02428 *Value = D3DFILTER_LINEARMIPLINEAR; 02429 break; 02430 default: 02431 ERR("Unhandled mip filter %#x.\n", tex_mip); 02432 *Value = D3DFILTER_LINEAR; 02433 break; 02434 } 02435 break; 02436 default: 02437 ERR("Unhandled texture min filter %#x.\n",tex_min); 02438 *Value = D3DFILTER_NEAREST; 02439 break; 02440 } 02441 break; 02442 } 02443 02444 case D3DRENDERSTATE_TEXTUREADDRESS: 02445 case D3DRENDERSTATE_TEXTUREADDRESSU: 02446 hr = wined3d_device_get_sampler_state(This->wined3d_device, 02447 0, WINED3D_SAMP_ADDRESS_U, Value); 02448 break; 02449 case D3DRENDERSTATE_TEXTUREADDRESSV: 02450 hr = wined3d_device_get_sampler_state(This->wined3d_device, 02451 0, WINED3D_SAMP_ADDRESS_V, Value); 02452 break; 02453 02454 case D3DRENDERSTATE_BORDERCOLOR: 02455 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n"); 02456 hr = E_NOTIMPL; 02457 break; 02458 02459 case D3DRENDERSTATE_TEXTUREHANDLE: 02460 case D3DRENDERSTATE_TEXTUREMAPBLEND: 02461 WARN("Render state %#x is invalid in d3d7.\n", RenderStateType); 02462 hr = DDERR_INVALIDPARAMS; 02463 break; 02464 02465 case D3DRENDERSTATE_ZBIAS: 02466 hr = wined3d_device_get_render_state(This->wined3d_device, WINED3D_RS_DEPTHBIAS, Value); 02467 break; 02468 02469 default: 02470 if (RenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00 02471 && RenderStateType <= D3DRENDERSTATE_STIPPLEPATTERN31) 02472 { 02473 FIXME("Unhandled stipple pattern render state (%#x).\n", 02474 RenderStateType); 02475 hr = E_NOTIMPL; 02476 break; 02477 } 02478 hr = wined3d_device_get_render_state(This->wined3d_device, RenderStateType, Value); 02479 } 02480 wined3d_mutex_unlock(); 02481 02482 return hr; 02483 } 02484 02485 static HRESULT WINAPI 02486 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup(IDirect3DDevice7 *iface, 02487 D3DRENDERSTATETYPE RenderStateType, 02488 DWORD *Value) 02489 { 02490 return IDirect3DDeviceImpl_7_GetRenderState(iface, RenderStateType, Value); 02491 } 02492 02493 static HRESULT WINAPI 02494 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve(IDirect3DDevice7 *iface, 02495 D3DRENDERSTATETYPE RenderStateType, 02496 DWORD *Value) 02497 { 02498 HRESULT hr; 02499 WORD old_fpucw; 02500 02501 old_fpucw = d3d_fpu_setup(); 02502 hr = IDirect3DDeviceImpl_7_GetRenderState(iface, RenderStateType, Value); 02503 set_fpu_control_word(old_fpucw); 02504 02505 return hr; 02506 } 02507 02508 static HRESULT WINAPI 02509 IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3 *iface, 02510 D3DRENDERSTATETYPE dwRenderStateType, 02511 DWORD *lpdwRenderState) 02512 { 02513 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 02514 HRESULT hr; 02515 02516 TRACE("iface %p, state %#x, value %p.\n", iface, dwRenderStateType, lpdwRenderState); 02517 02518 switch(dwRenderStateType) 02519 { 02520 case D3DRENDERSTATE_TEXTUREHANDLE: 02521 { 02522 /* This state is wrapped to SetTexture in SetRenderState, so 02523 * it has to be wrapped to GetTexture here. */ 02524 struct wined3d_texture *tex = NULL; 02525 *lpdwRenderState = 0; 02526 02527 wined3d_mutex_lock(); 02528 hr = wined3d_device_get_texture(This->wined3d_device, 0, &tex); 02529 if (SUCCEEDED(hr) && tex) 02530 { 02531 /* The parent of the texture is the IDirectDrawSurface7 02532 * interface of the ddraw surface. */ 02533 IDirectDrawSurfaceImpl *parent = wined3d_texture_get_parent(tex); 02534 if (parent) *lpdwRenderState = parent->Handle; 02535 wined3d_texture_decref(tex); 02536 } 02537 wined3d_mutex_unlock(); 02538 02539 return hr; 02540 } 02541 02542 case D3DRENDERSTATE_TEXTUREMAPBLEND: 02543 { 02544 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse 02545 the mapping to get the value. */ 02546 DWORD colorop, colorarg1, colorarg2; 02547 DWORD alphaop, alphaarg1, alphaarg2; 02548 02549 wined3d_mutex_lock(); 02550 02551 This->legacyTextureBlending = TRUE; 02552 02553 wined3d_device_get_texture_stage_state(This->wined3d_device, 0, WINED3D_TSS_COLOR_OP, &colorop); 02554 wined3d_device_get_texture_stage_state(This->wined3d_device, 0, WINED3D_TSS_COLOR_ARG1, &colorarg1); 02555 wined3d_device_get_texture_stage_state(This->wined3d_device, 0, WINED3D_TSS_COLOR_ARG2, &colorarg2); 02556 wined3d_device_get_texture_stage_state(This->wined3d_device, 0, WINED3D_TSS_ALPHA_OP, &alphaop); 02557 wined3d_device_get_texture_stage_state(This->wined3d_device, 0, WINED3D_TSS_ALPHA_ARG1, &alphaarg1); 02558 wined3d_device_get_texture_stage_state(This->wined3d_device, 0, WINED3D_TSS_ALPHA_ARG2, &alphaarg2); 02559 02560 if (colorop == WINED3D_TOP_SELECT_ARG1 && colorarg1 == WINED3DTA_TEXTURE 02561 && alphaop == WINED3D_TOP_SELECT_ARG1 && alphaarg1 == WINED3DTA_TEXTURE) 02562 *lpdwRenderState = D3DTBLEND_DECAL; 02563 else if (colorop == WINED3D_TOP_SELECT_ARG1 && colorarg1 == WINED3DTA_TEXTURE 02564 && alphaop == WINED3D_TOP_MODULATE 02565 && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT) 02566 *lpdwRenderState = D3DTBLEND_DECALALPHA; 02567 else if (colorop == WINED3D_TOP_MODULATE 02568 && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT 02569 && alphaop == WINED3D_TOP_MODULATE 02570 && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT) 02571 *lpdwRenderState = D3DTBLEND_MODULATEALPHA; 02572 else 02573 { 02574 struct wined3d_texture *tex = NULL; 02575 HRESULT hr; 02576 BOOL tex_alpha = FALSE; 02577 DDPIXELFORMAT ddfmt; 02578 02579 hr = wined3d_device_get_texture(This->wined3d_device, 0, &tex); 02580 02581 if(hr == WINED3D_OK && tex) 02582 { 02583 struct wined3d_resource *sub_resource; 02584 02585 if ((sub_resource = wined3d_texture_get_sub_resource(tex, 0))) 02586 { 02587 struct wined3d_resource_desc desc; 02588 02589 wined3d_resource_get_desc(sub_resource, &desc); 02590 ddfmt.dwSize = sizeof(ddfmt); 02591 PixelFormat_WineD3DtoDD(&ddfmt, desc.format); 02592 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE; 02593 } 02594 02595 wined3d_texture_decref(tex); 02596 } 02597 02598 if (!(colorop == WINED3D_TOP_MODULATE 02599 && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT 02600 && alphaop == (tex_alpha ? WINED3D_TOP_SELECT_ARG1 : WINED3D_TOP_SELECT_ARG2) 02601 && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)) 02602 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous.\n"); 02603 02604 *lpdwRenderState = D3DTBLEND_MODULATE; 02605 } 02606 02607 wined3d_mutex_unlock(); 02608 02609 return D3D_OK; 02610 } 02611 02612 default: 02613 return IDirect3DDevice7_GetRenderState(&This->IDirect3DDevice7_iface, dwRenderStateType, lpdwRenderState); 02614 } 02615 } 02616 02617 static HRESULT WINAPI IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2 *iface, 02618 D3DRENDERSTATETYPE dwRenderStateType, DWORD *lpdwRenderState) 02619 { 02620 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 02621 02622 TRACE("iface %p, state %#x, value %p.\n", iface, dwRenderStateType, lpdwRenderState); 02623 02624 return IDirect3DDevice3_GetRenderState(&This->IDirect3DDevice3_iface, 02625 dwRenderStateType, lpdwRenderState); 02626 } 02627 02628 /***************************************************************************** 02629 * IDirect3DDevice7::SetRenderState 02630 * 02631 * Sets a render state. The possible render states are defined in 02632 * include/d3dtypes.h 02633 * 02634 * Version 2, 3 and 7 02635 * 02636 * Params: 02637 * RenderStateType: State to set 02638 * Value: Value to assign to that state 02639 * 02640 * Returns: 02641 * D3D_OK on success, 02642 * for details see IWineD3DDevice::SetRenderState 02643 * 02644 *****************************************************************************/ 02645 static HRESULT 02646 IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface, 02647 D3DRENDERSTATETYPE RenderStateType, 02648 DWORD Value) 02649 { 02650 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 02651 HRESULT hr; 02652 02653 TRACE("iface %p, state %#x, value %#x.\n", iface, RenderStateType, Value); 02654 02655 wined3d_mutex_lock(); 02656 /* Some render states need special care */ 02657 switch(RenderStateType) 02658 { 02659 /* 02660 * The ddraw texture filter mapping works like this: 02661 * D3DFILTER_NEAREST Point min/mag, no mip 02662 * D3DFILTER_MIPNEAREST Point min/mag, point mip 02663 * D3DFILTER_LINEARMIPNEAREST: Point min/mag, linear mip 02664 * 02665 * D3DFILTER_LINEAR Linear min/mag, no mip 02666 * D3DFILTER_MIPLINEAR Linear min/mag, point mip 02667 * D3DFILTER_LINEARMIPLINEAR Linear min/mag, linear mip 02668 * 02669 * This is the opposite of the GL naming convention, 02670 * D3DFILTER_LINEARMIPNEAREST corresponds to GL_NEAREST_MIPMAP_LINEAR. 02671 */ 02672 case D3DRENDERSTATE_TEXTUREMAG: 02673 { 02674 enum wined3d_texture_filter_type tex_mag; 02675 02676 switch (Value) 02677 { 02678 case D3DFILTER_NEAREST: 02679 case D3DFILTER_MIPNEAREST: 02680 case D3DFILTER_LINEARMIPNEAREST: 02681 tex_mag = WINED3D_TEXF_POINT; 02682 break; 02683 case D3DFILTER_LINEAR: 02684 case D3DFILTER_MIPLINEAR: 02685 case D3DFILTER_LINEARMIPLINEAR: 02686 tex_mag = WINED3D_TEXF_LINEAR; 02687 break; 02688 default: 02689 tex_mag = WINED3D_TEXF_POINT; 02690 ERR("Unhandled texture mag %d !\n",Value); 02691 break; 02692 } 02693 02694 hr = wined3d_device_set_sampler_state(This->wined3d_device, 0, WINED3D_SAMP_MAG_FILTER, tex_mag); 02695 break; 02696 } 02697 02698 case D3DRENDERSTATE_TEXTUREMIN: 02699 { 02700 enum wined3d_texture_filter_type tex_min; 02701 enum wined3d_texture_filter_type tex_mip; 02702 02703 switch ((D3DTEXTUREFILTER)Value) 02704 { 02705 case D3DFILTER_NEAREST: 02706 tex_min = WINED3D_TEXF_POINT; 02707 tex_mip = WINED3D_TEXF_NONE; 02708 break; 02709 case D3DFILTER_LINEAR: 02710 tex_min = WINED3D_TEXF_LINEAR; 02711 tex_mip = WINED3D_TEXF_NONE; 02712 break; 02713 case D3DFILTER_MIPNEAREST: 02714 tex_min = WINED3D_TEXF_POINT; 02715 tex_mip = WINED3D_TEXF_POINT; 02716 break; 02717 case D3DFILTER_MIPLINEAR: 02718 tex_min = WINED3D_TEXF_LINEAR; 02719 tex_mip = WINED3D_TEXF_POINT; 02720 break; 02721 case D3DFILTER_LINEARMIPNEAREST: 02722 tex_min = WINED3D_TEXF_POINT; 02723 tex_mip = WINED3D_TEXF_LINEAR; 02724 break; 02725 case D3DFILTER_LINEARMIPLINEAR: 02726 tex_min = WINED3D_TEXF_LINEAR; 02727 tex_mip = WINED3D_TEXF_LINEAR; 02728 break; 02729 02730 default: 02731 ERR("Unhandled texture min %d !\n",Value); 02732 tex_min = WINED3D_TEXF_POINT; 02733 tex_mip = WINED3D_TEXF_NONE; 02734 break; 02735 } 02736 02737 wined3d_device_set_sampler_state(This->wined3d_device, 02738 0, WINED3D_SAMP_MIP_FILTER, tex_mip); 02739 hr = wined3d_device_set_sampler_state(This->wined3d_device, 02740 0, WINED3D_SAMP_MIN_FILTER, tex_min); 02741 break; 02742 } 02743 02744 case D3DRENDERSTATE_TEXTUREADDRESS: 02745 wined3d_device_set_sampler_state(This->wined3d_device, 02746 0, WINED3D_SAMP_ADDRESS_V, Value); 02747 /* Drop through */ 02748 case D3DRENDERSTATE_TEXTUREADDRESSU: 02749 hr = wined3d_device_set_sampler_state(This->wined3d_device, 02750 0, WINED3D_SAMP_ADDRESS_U, Value); 02751 break; 02752 case D3DRENDERSTATE_TEXTUREADDRESSV: 02753 hr = wined3d_device_set_sampler_state(This->wined3d_device, 02754 0, WINED3D_SAMP_ADDRESS_V, Value); 02755 break; 02756 02757 case D3DRENDERSTATE_BORDERCOLOR: 02758 /* This should probably just forward to the corresponding sampler 02759 * state. Needs tests. */ 02760 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n"); 02761 hr = E_NOTIMPL; 02762 break; 02763 02764 case D3DRENDERSTATE_TEXTUREHANDLE: 02765 case D3DRENDERSTATE_TEXTUREMAPBLEND: 02766 WARN("Render state %#x is invalid in d3d7.\n", RenderStateType); 02767 hr = DDERR_INVALIDPARAMS; 02768 break; 02769 02770 case D3DRENDERSTATE_ZBIAS: 02771 hr = wined3d_device_set_render_state(This->wined3d_device, WINED3D_RS_DEPTHBIAS, Value); 02772 break; 02773 02774 default: 02775 if (RenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00 02776 && RenderStateType <= D3DRENDERSTATE_STIPPLEPATTERN31) 02777 { 02778 FIXME("Unhandled stipple pattern render state (%#x).\n", 02779 RenderStateType); 02780 hr = E_NOTIMPL; 02781 break; 02782 } 02783 02784 hr = wined3d_device_set_render_state(This->wined3d_device, RenderStateType, Value); 02785 break; 02786 } 02787 wined3d_mutex_unlock(); 02788 02789 return hr; 02790 } 02791 02792 static HRESULT WINAPI 02793 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup(IDirect3DDevice7 *iface, 02794 D3DRENDERSTATETYPE RenderStateType, 02795 DWORD Value) 02796 { 02797 return IDirect3DDeviceImpl_7_SetRenderState(iface, RenderStateType, Value); 02798 } 02799 02800 static HRESULT WINAPI 02801 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve(IDirect3DDevice7 *iface, 02802 D3DRENDERSTATETYPE RenderStateType, 02803 DWORD Value) 02804 { 02805 HRESULT hr; 02806 WORD old_fpucw; 02807 02808 old_fpucw = d3d_fpu_setup(); 02809 hr = IDirect3DDeviceImpl_7_SetRenderState(iface, RenderStateType, Value); 02810 set_fpu_control_word(old_fpucw); 02811 02812 return hr; 02813 } 02814 02815 static HRESULT WINAPI 02816 IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3 *iface, 02817 D3DRENDERSTATETYPE RenderStateType, 02818 DWORD Value) 02819 { 02820 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values 02821 for this state can be directly mapped to texture stage colorop and alphaop, but 02822 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha 02823 from diffuse otherwise. So changing the texture must be monitored in SetTexture to modify 02824 alphaarg when needed. 02825 02826 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation 02827 02828 Legacy texture blending (TEXTUREMAPBLEND) and texture stage states: directx6 docs state that 02829 TEXTUREMAPBLEND is deprecated, yet can still be used. Games must not use both or results 02830 are undefined. D3DTBLEND_MODULATE mode in particular is dependent on texture pixel format and 02831 requires fixup of stage 0 texture states when texture changes, but this fixup can interfere 02832 with games not using this deprecated state. So a flag 'legacyTextureBlending' has to be kept 02833 in device - TRUE if the app is using TEXTUREMAPBLEND. 02834 02835 Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by 02836 GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok, 02837 unless some broken game will be found that cares. */ 02838 02839 HRESULT hr; 02840 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 02841 02842 TRACE("iface %p, state %#x, value %#x.\n", iface, RenderStateType, Value); 02843 02844 wined3d_mutex_lock(); 02845 02846 switch(RenderStateType) 02847 { 02848 case D3DRENDERSTATE_TEXTUREHANDLE: 02849 { 02850 IDirectDrawSurfaceImpl *surf; 02851 02852 if(Value == 0) 02853 { 02854 hr = wined3d_device_set_texture(This->wined3d_device, 0, NULL); 02855 break; 02856 } 02857 02858 surf = ddraw_get_object(&This->handle_table, Value - 1, DDRAW_HANDLE_SURFACE); 02859 if (!surf) 02860 { 02861 WARN("Invalid texture handle.\n"); 02862 hr = DDERR_INVALIDPARAMS; 02863 break; 02864 } 02865 02866 hr = IDirect3DDevice3_SetTexture(iface, 0, &surf->IDirect3DTexture2_iface); 02867 break; 02868 } 02869 02870 case D3DRENDERSTATE_TEXTUREMAPBLEND: 02871 { 02872 This->legacyTextureBlending = TRUE; 02873 02874 switch ( (D3DTEXTUREBLEND) Value) 02875 { 02876 case D3DTBLEND_MODULATE: 02877 { 02878 struct wined3d_texture *tex = NULL; 02879 BOOL tex_alpha = FALSE; 02880 DDPIXELFORMAT ddfmt; 02881 02882 hr = wined3d_device_get_texture(This->wined3d_device, 0, &tex); 02883 02884 if(hr == WINED3D_OK && tex) 02885 { 02886 struct wined3d_resource *sub_resource; 02887 02888 if ((sub_resource = wined3d_texture_get_sub_resource(tex, 0))) 02889 { 02890 struct wined3d_resource_desc desc; 02891 02892 wined3d_resource_get_desc(sub_resource, &desc); 02893 ddfmt.dwSize = sizeof(ddfmt); 02894 PixelFormat_WineD3DtoDD(&ddfmt, desc.format); 02895 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE; 02896 } 02897 02898 wined3d_texture_decref(tex); 02899 } 02900 02901 if (tex_alpha) 02902 wined3d_device_set_texture_stage_state(This->wined3d_device, 02903 0, WINED3D_TSS_ALPHA_OP, WINED3D_TOP_SELECT_ARG1); 02904 else 02905 wined3d_device_set_texture_stage_state(This->wined3d_device, 02906 0, WINED3D_TSS_ALPHA_OP, WINED3D_TOP_SELECT_ARG2); 02907 wined3d_device_set_texture_stage_state(This->wined3d_device, 02908 0, WINED3D_TSS_ALPHA_ARG1, WINED3DTA_TEXTURE); 02909 wined3d_device_set_texture_stage_state(This->wined3d_device, 02910 0, WINED3D_TSS_ALPHA_ARG2, WINED3DTA_CURRENT); 02911 wined3d_device_set_texture_stage_state(This->wined3d_device, 02912 0, WINED3D_TSS_COLOR_ARG1, WINED3DTA_TEXTURE); 02913 wined3d_device_set_texture_stage_state(This->wined3d_device, 02914 0, WINED3D_TSS_COLOR_ARG2, WINED3DTA_CURRENT); 02915 wined3d_device_set_texture_stage_state(This->wined3d_device, 02916 0, WINED3D_TSS_COLOR_OP, WINED3D_TOP_MODULATE); 02917 break; 02918 } 02919 02920 case D3DTBLEND_ADD: 02921 wined3d_device_set_texture_stage_state(This->wined3d_device, 02922 0, WINED3D_TSS_COLOR_OP, WINED3D_TOP_ADD); 02923 wined3d_device_set_texture_stage_state(This->wined3d_device, 02924 0, WINED3D_TSS_COLOR_ARG1, WINED3DTA_TEXTURE); 02925 wined3d_device_set_texture_stage_state(This->wined3d_device, 02926 0, WINED3D_TSS_COLOR_ARG2, WINED3DTA_CURRENT); 02927 wined3d_device_set_texture_stage_state(This->wined3d_device, 02928 0, WINED3D_TSS_ALPHA_OP, WINED3D_TOP_SELECT_ARG2); 02929 wined3d_device_set_texture_stage_state(This->wined3d_device, 02930 0, WINED3D_TSS_ALPHA_ARG2, WINED3DTA_CURRENT); 02931 break; 02932 02933 case D3DTBLEND_MODULATEALPHA: 02934 wined3d_device_set_texture_stage_state(This->wined3d_device, 02935 0, WINED3D_TSS_COLOR_ARG1, WINED3DTA_TEXTURE); 02936 wined3d_device_set_texture_stage_state(This->wined3d_device, 02937 0, WINED3D_TSS_ALPHA_ARG1, WINED3DTA_TEXTURE); 02938 wined3d_device_set_texture_stage_state(This->wined3d_device, 02939 0, WINED3D_TSS_COLOR_ARG2, WINED3DTA_CURRENT); 02940 wined3d_device_set_texture_stage_state(This->wined3d_device, 02941 0, WINED3D_TSS_ALPHA_ARG2, WINED3DTA_CURRENT); 02942 wined3d_device_set_texture_stage_state(This->wined3d_device, 02943 0, WINED3D_TSS_COLOR_OP, WINED3D_TOP_MODULATE); 02944 wined3d_device_set_texture_stage_state(This->wined3d_device, 02945 0, WINED3D_TSS_ALPHA_OP, WINED3D_TOP_MODULATE); 02946 break; 02947 02948 case D3DTBLEND_COPY: 02949 case D3DTBLEND_DECAL: 02950 wined3d_device_set_texture_stage_state(This->wined3d_device, 02951 0, WINED3D_TSS_COLOR_ARG1, WINED3DTA_TEXTURE); 02952 wined3d_device_set_texture_stage_state(This->wined3d_device, 02953 0, WINED3D_TSS_ALPHA_ARG1, WINED3DTA_TEXTURE); 02954 wined3d_device_set_texture_stage_state(This->wined3d_device, 02955 0, WINED3D_TSS_COLOR_OP, WINED3D_TOP_SELECT_ARG1); 02956 wined3d_device_set_texture_stage_state(This->wined3d_device, 02957 0, WINED3D_TSS_ALPHA_OP, WINED3D_TOP_SELECT_ARG1); 02958 break; 02959 02960 case D3DTBLEND_DECALALPHA: 02961 wined3d_device_set_texture_stage_state(This->wined3d_device, 02962 0, WINED3D_TSS_COLOR_OP, WINED3D_TOP_BLEND_TEXTURE_ALPHA); 02963 wined3d_device_set_texture_stage_state(This->wined3d_device, 02964 0, WINED3D_TSS_COLOR_ARG1, WINED3DTA_TEXTURE); 02965 wined3d_device_set_texture_stage_state(This->wined3d_device, 02966 0, WINED3D_TSS_COLOR_ARG2, WINED3DTA_CURRENT); 02967 wined3d_device_set_texture_stage_state(This->wined3d_device, 02968 0, WINED3D_TSS_ALPHA_OP, WINED3D_TOP_SELECT_ARG2); 02969 wined3d_device_set_texture_stage_state(This->wined3d_device, 02970 0, WINED3D_TSS_ALPHA_ARG2, WINED3DTA_CURRENT); 02971 break; 02972 02973 default: 02974 ERR("Unhandled texture environment %d !\n",Value); 02975 } 02976 02977 hr = D3D_OK; 02978 break; 02979 } 02980 02981 default: 02982 hr = IDirect3DDevice7_SetRenderState(&This->IDirect3DDevice7_iface, RenderStateType, Value); 02983 break; 02984 } 02985 wined3d_mutex_unlock(); 02986 02987 return hr; 02988 } 02989 02990 static HRESULT WINAPI IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2 *iface, 02991 D3DRENDERSTATETYPE RenderStateType, DWORD Value) 02992 { 02993 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 02994 02995 TRACE("iface %p, state %#x, value %#x.\n", iface, RenderStateType, Value); 02996 02997 return IDirect3DDevice3_SetRenderState(&This->IDirect3DDevice3_iface, RenderStateType, Value); 02998 } 02999 03000 /***************************************************************************** 03001 * Direct3DDevice3::SetLightState 03002 * 03003 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The 03004 * light states are forwarded to Direct3DDevice7 render states 03005 * 03006 * Version 2 and 3 03007 * 03008 * Params: 03009 * LightStateType: The light state to change 03010 * Value: The value to assign to that light state 03011 * 03012 * Returns: 03013 * D3D_OK on success 03014 * DDERR_INVALIDPARAMS if the parameters were incorrect 03015 * Also check IDirect3DDevice7::SetRenderState 03016 * 03017 *****************************************************************************/ 03018 static HRESULT WINAPI 03019 IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3 *iface, 03020 D3DLIGHTSTATETYPE LightStateType, 03021 DWORD Value) 03022 { 03023 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 03024 HRESULT hr; 03025 03026 TRACE("iface %p, state %#x, value %#x.\n", iface, LightStateType, Value); 03027 03028 if (!LightStateType || (LightStateType > D3DLIGHTSTATE_COLORVERTEX)) 03029 { 03030 TRACE("Unexpected Light State Type\n"); 03031 return DDERR_INVALIDPARAMS; 03032 } 03033 03034 wined3d_mutex_lock(); 03035 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */) 03036 { 03037 IDirect3DMaterialImpl *m = ddraw_get_object(&This->handle_table, Value - 1, DDRAW_HANDLE_MATERIAL); 03038 if (!m) 03039 { 03040 WARN("Invalid material handle.\n"); 03041 wined3d_mutex_unlock(); 03042 return DDERR_INVALIDPARAMS; 03043 } 03044 03045 TRACE(" activating material %p.\n", m); 03046 material_activate(m); 03047 03048 This->material = Value; 03049 } 03050 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */) 03051 { 03052 switch (Value) 03053 { 03054 case D3DCOLOR_MONO: 03055 ERR("DDCOLOR_MONO should not happen!\n"); 03056 break; 03057 case D3DCOLOR_RGB: 03058 /* We are already in this mode */ 03059 TRACE("Setting color model to RGB (no-op).\n"); 03060 break; 03061 default: 03062 ERR("Unknown color model!\n"); 03063 wined3d_mutex_unlock(); 03064 return DDERR_INVALIDPARAMS; 03065 } 03066 } 03067 else 03068 { 03069 D3DRENDERSTATETYPE rs; 03070 switch (LightStateType) 03071 { 03072 case D3DLIGHTSTATE_AMBIENT: /* 2 */ 03073 rs = D3DRENDERSTATE_AMBIENT; 03074 break; 03075 case D3DLIGHTSTATE_FOGMODE: /* 4 */ 03076 rs = D3DRENDERSTATE_FOGVERTEXMODE; 03077 break; 03078 case D3DLIGHTSTATE_FOGSTART: /* 5 */ 03079 rs = D3DRENDERSTATE_FOGSTART; 03080 break; 03081 case D3DLIGHTSTATE_FOGEND: /* 6 */ 03082 rs = D3DRENDERSTATE_FOGEND; 03083 break; 03084 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */ 03085 rs = D3DRENDERSTATE_FOGDENSITY; 03086 break; 03087 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */ 03088 rs = D3DRENDERSTATE_COLORVERTEX; 03089 break; 03090 default: 03091 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType); 03092 wined3d_mutex_unlock(); 03093 return DDERR_INVALIDPARAMS; 03094 } 03095 03096 hr = IDirect3DDevice7_SetRenderState(&This->IDirect3DDevice7_iface, rs, Value); 03097 wined3d_mutex_unlock(); 03098 return hr; 03099 } 03100 wined3d_mutex_unlock(); 03101 03102 return D3D_OK; 03103 } 03104 03105 static HRESULT WINAPI IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2 *iface, 03106 D3DLIGHTSTATETYPE LightStateType, DWORD Value) 03107 { 03108 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 03109 03110 TRACE("iface %p, state %#x, value %#x.\n", iface, LightStateType, Value); 03111 03112 return IDirect3DDevice3_SetLightState(&This->IDirect3DDevice3_iface, LightStateType, Value); 03113 } 03114 03115 /***************************************************************************** 03116 * IDirect3DDevice3::GetLightState 03117 * 03118 * Returns the current setting of a light state. The state is read from 03119 * the Direct3DDevice7 render state. 03120 * 03121 * Version 2 and 3 03122 * 03123 * Params: 03124 * LightStateType: The light state to return 03125 * Value: The address to store the light state setting at 03126 * 03127 * Returns: 03128 * D3D_OK on success 03129 * DDDERR_INVALIDPARAMS if the parameters were incorrect 03130 * Also see IDirect3DDevice7::GetRenderState 03131 * 03132 *****************************************************************************/ 03133 static HRESULT WINAPI 03134 IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3 *iface, 03135 D3DLIGHTSTATETYPE LightStateType, 03136 DWORD *Value) 03137 { 03138 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 03139 HRESULT hr; 03140 03141 TRACE("iface %p, state %#x, value %p.\n", iface, LightStateType, Value); 03142 03143 if (!LightStateType || (LightStateType > D3DLIGHTSTATE_COLORVERTEX)) 03144 { 03145 TRACE("Unexpected Light State Type\n"); 03146 return DDERR_INVALIDPARAMS; 03147 } 03148 03149 if(!Value) 03150 return DDERR_INVALIDPARAMS; 03151 03152 wined3d_mutex_lock(); 03153 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */) 03154 { 03155 *Value = This->material; 03156 } 03157 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */) 03158 { 03159 *Value = D3DCOLOR_RGB; 03160 } 03161 else 03162 { 03163 D3DRENDERSTATETYPE rs; 03164 switch (LightStateType) 03165 { 03166 case D3DLIGHTSTATE_AMBIENT: /* 2 */ 03167 rs = D3DRENDERSTATE_AMBIENT; 03168 break; 03169 case D3DLIGHTSTATE_FOGMODE: /* 4 */ 03170 rs = D3DRENDERSTATE_FOGVERTEXMODE; 03171 break; 03172 case D3DLIGHTSTATE_FOGSTART: /* 5 */ 03173 rs = D3DRENDERSTATE_FOGSTART; 03174 break; 03175 case D3DLIGHTSTATE_FOGEND: /* 6 */ 03176 rs = D3DRENDERSTATE_FOGEND; 03177 break; 03178 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */ 03179 rs = D3DRENDERSTATE_FOGDENSITY; 03180 break; 03181 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */ 03182 rs = D3DRENDERSTATE_COLORVERTEX; 03183 break; 03184 default: 03185 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType); 03186 wined3d_mutex_unlock(); 03187 return DDERR_INVALIDPARAMS; 03188 } 03189 03190 hr = IDirect3DDevice7_GetRenderState(&This->IDirect3DDevice7_iface, rs, Value); 03191 wined3d_mutex_unlock(); 03192 return hr; 03193 } 03194 wined3d_mutex_unlock(); 03195 03196 return D3D_OK; 03197 } 03198 03199 static HRESULT WINAPI IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2 *iface, 03200 D3DLIGHTSTATETYPE LightStateType, DWORD *Value) 03201 { 03202 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 03203 03204 TRACE("iface %p, state %#x, value %p.\n", iface, LightStateType, Value); 03205 03206 return IDirect3DDevice3_GetLightState(&This->IDirect3DDevice3_iface, LightStateType, Value); 03207 } 03208 03209 /***************************************************************************** 03210 * IDirect3DDevice7::SetTransform 03211 * 03212 * Assigns a D3DMATRIX to a transform type. The transform types are defined 03213 * in include/d3dtypes.h. 03214 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0) 03215 * (=255) for wined3d, because the 1 transform state was removed in d3d8 03216 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0) 03217 * 03218 * Version 2, 3 and 7 03219 * 03220 * Params: 03221 * TransformStateType: transform state to set 03222 * Matrix: Matrix to assign to the state 03223 * 03224 * Returns: 03225 * D3D_OK on success 03226 * DDERR_INVALIDPARAMS if Matrix == NULL 03227 * For details see IWineD3DDevice::SetTransform 03228 * 03229 *****************************************************************************/ 03230 static HRESULT 03231 IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7 *iface, 03232 D3DTRANSFORMSTATETYPE TransformStateType, 03233 D3DMATRIX *Matrix) 03234 { 03235 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 03236 D3DTRANSFORMSTATETYPE type; 03237 HRESULT hr; 03238 03239 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, Matrix); 03240 03241 switch (TransformStateType) 03242 { 03243 case D3DTRANSFORMSTATE_WORLD: 03244 type = WINED3D_TS_WORLD_MATRIX(0); 03245 break; 03246 case D3DTRANSFORMSTATE_WORLD1: 03247 type = WINED3D_TS_WORLD_MATRIX(1); 03248 break; 03249 case D3DTRANSFORMSTATE_WORLD2: 03250 type = WINED3D_TS_WORLD_MATRIX(2); 03251 break; 03252 case D3DTRANSFORMSTATE_WORLD3: 03253 type = WINED3D_TS_WORLD_MATRIX(3); 03254 break; 03255 default: 03256 type = TransformStateType; 03257 } 03258 03259 if (!Matrix) 03260 return DDERR_INVALIDPARAMS; 03261 03262 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */ 03263 wined3d_mutex_lock(); 03264 hr = wined3d_device_set_transform(This->wined3d_device, type, (struct wined3d_matrix *)Matrix); 03265 wined3d_mutex_unlock(); 03266 03267 return hr; 03268 } 03269 03270 static HRESULT WINAPI 03271 IDirect3DDeviceImpl_7_SetTransform_FPUSetup(IDirect3DDevice7 *iface, 03272 D3DTRANSFORMSTATETYPE TransformStateType, 03273 D3DMATRIX *Matrix) 03274 { 03275 return IDirect3DDeviceImpl_7_SetTransform(iface, TransformStateType, Matrix); 03276 } 03277 03278 static HRESULT WINAPI 03279 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve(IDirect3DDevice7 *iface, 03280 D3DTRANSFORMSTATETYPE TransformStateType, 03281 D3DMATRIX *Matrix) 03282 { 03283 HRESULT hr; 03284 WORD old_fpucw; 03285 03286 old_fpucw = d3d_fpu_setup(); 03287 hr = IDirect3DDeviceImpl_7_SetTransform(iface, TransformStateType, Matrix); 03288 set_fpu_control_word(old_fpucw); 03289 03290 return hr; 03291 } 03292 03293 static HRESULT WINAPI IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3 *iface, 03294 D3DTRANSFORMSTATETYPE state, D3DMATRIX *matrix) 03295 { 03296 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 03297 03298 TRACE("iface %p, state %#x, matrix %p.\n", iface, state, matrix); 03299 03300 if (!matrix) 03301 return DDERR_INVALIDPARAMS; 03302 03303 if (state == D3DTRANSFORMSTATE_PROJECTION) 03304 { 03305 D3DMATRIX projection; 03306 HRESULT hr; 03307 03308 wined3d_mutex_lock(); 03309 multiply_matrix(&projection, &This->legacy_clipspace, matrix); 03310 hr = wined3d_device_set_transform(This->wined3d_device, 03311 WINED3D_TS_PROJECTION, (struct wined3d_matrix *)&projection); 03312 if (SUCCEEDED(hr)) 03313 This->legacy_projection = *matrix; 03314 wined3d_mutex_unlock(); 03315 03316 return hr; 03317 } 03318 03319 return IDirect3DDevice7_SetTransform(&This->IDirect3DDevice7_iface, state, matrix); 03320 } 03321 03322 static HRESULT WINAPI IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2 *iface, 03323 D3DTRANSFORMSTATETYPE TransformStateType, D3DMATRIX *D3DMatrix) 03324 { 03325 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 03326 03327 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, D3DMatrix); 03328 03329 return IDirect3DDevice7_SetTransform(&This->IDirect3DDevice7_iface, TransformStateType, D3DMatrix); 03330 } 03331 03332 /***************************************************************************** 03333 * IDirect3DDevice7::GetTransform 03334 * 03335 * Returns the matrix assigned to a transform state 03336 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see 03337 * SetTransform 03338 * 03339 * Params: 03340 * TransformStateType: State to read the matrix from 03341 * Matrix: Address to store the matrix at 03342 * 03343 * Returns: 03344 * D3D_OK on success 03345 * DDERR_INVALIDPARAMS if Matrix == NULL 03346 * For details, see IWineD3DDevice::GetTransform 03347 * 03348 *****************************************************************************/ 03349 static HRESULT 03350 IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7 *iface, 03351 D3DTRANSFORMSTATETYPE TransformStateType, 03352 D3DMATRIX *Matrix) 03353 { 03354 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 03355 D3DTRANSFORMSTATETYPE type; 03356 HRESULT hr; 03357 03358 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, Matrix); 03359 03360 switch(TransformStateType) 03361 { 03362 case D3DTRANSFORMSTATE_WORLD: 03363 type = WINED3D_TS_WORLD_MATRIX(0); 03364 break; 03365 case D3DTRANSFORMSTATE_WORLD1: 03366 type = WINED3D_TS_WORLD_MATRIX(1); 03367 break; 03368 case D3DTRANSFORMSTATE_WORLD2: 03369 type = WINED3D_TS_WORLD_MATRIX(2); 03370 break; 03371 case D3DTRANSFORMSTATE_WORLD3: 03372 type = WINED3D_TS_WORLD_MATRIX(3); 03373 break; 03374 default: 03375 type = TransformStateType; 03376 } 03377 03378 if(!Matrix) 03379 return DDERR_INVALIDPARAMS; 03380 03381 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */ 03382 wined3d_mutex_lock(); 03383 hr = wined3d_device_get_transform(This->wined3d_device, type, (struct wined3d_matrix *)Matrix); 03384 wined3d_mutex_unlock(); 03385 03386 return hr; 03387 } 03388 03389 static HRESULT WINAPI 03390 IDirect3DDeviceImpl_7_GetTransform_FPUSetup(IDirect3DDevice7 *iface, 03391 D3DTRANSFORMSTATETYPE TransformStateType, 03392 D3DMATRIX *Matrix) 03393 { 03394 return IDirect3DDeviceImpl_7_GetTransform(iface, TransformStateType, Matrix); 03395 } 03396 03397 static HRESULT WINAPI 03398 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve(IDirect3DDevice7 *iface, 03399 D3DTRANSFORMSTATETYPE TransformStateType, 03400 D3DMATRIX *Matrix) 03401 { 03402 HRESULT hr; 03403 WORD old_fpucw; 03404 03405 old_fpucw = d3d_fpu_setup(); 03406 hr = IDirect3DDeviceImpl_7_GetTransform(iface, TransformStateType, Matrix); 03407 set_fpu_control_word(old_fpucw); 03408 03409 return hr; 03410 } 03411 03412 static HRESULT WINAPI IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3 *iface, 03413 D3DTRANSFORMSTATETYPE state, D3DMATRIX *matrix) 03414 { 03415 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 03416 03417 TRACE("iface %p, state %#x, matrix %p.\n", iface, state, matrix); 03418 03419 if (!matrix) 03420 return DDERR_INVALIDPARAMS; 03421 03422 if (state == D3DTRANSFORMSTATE_PROJECTION) 03423 { 03424 wined3d_mutex_lock(); 03425 *matrix = This->legacy_projection; 03426 wined3d_mutex_unlock(); 03427 return DD_OK; 03428 } 03429 03430 return IDirect3DDevice7_GetTransform(&This->IDirect3DDevice7_iface, state, matrix); 03431 } 03432 03433 static HRESULT WINAPI IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2 *iface, 03434 D3DTRANSFORMSTATETYPE TransformStateType, D3DMATRIX *D3DMatrix) 03435 { 03436 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 03437 03438 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, D3DMatrix); 03439 03440 return IDirect3DDevice7_GetTransform(&This->IDirect3DDevice7_iface, TransformStateType, D3DMatrix); 03441 } 03442 03443 /***************************************************************************** 03444 * IDirect3DDevice7::MultiplyTransform 03445 * 03446 * Multiplies the already-set transform matrix of a transform state 03447 * with another matrix. For the world matrix, see SetTransform 03448 * 03449 * Version 2, 3 and 7 03450 * 03451 * Params: 03452 * TransformStateType: Transform state to multiply 03453 * D3DMatrix Matrix to multiply with. 03454 * 03455 * Returns 03456 * D3D_OK on success 03457 * DDERR_INVALIDPARAMS if D3DMatrix is NULL 03458 * For details, see IWineD3DDevice::MultiplyTransform 03459 * 03460 *****************************************************************************/ 03461 static HRESULT 03462 IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7 *iface, 03463 D3DTRANSFORMSTATETYPE TransformStateType, 03464 D3DMATRIX *D3DMatrix) 03465 { 03466 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 03467 HRESULT hr; 03468 D3DTRANSFORMSTATETYPE type; 03469 03470 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, D3DMatrix); 03471 03472 switch(TransformStateType) 03473 { 03474 case D3DTRANSFORMSTATE_WORLD: 03475 type = WINED3D_TS_WORLD_MATRIX(0); 03476 break; 03477 case D3DTRANSFORMSTATE_WORLD1: 03478 type = WINED3D_TS_WORLD_MATRIX(1); 03479 break; 03480 case D3DTRANSFORMSTATE_WORLD2: 03481 type = WINED3D_TS_WORLD_MATRIX(2); 03482 break; 03483 case D3DTRANSFORMSTATE_WORLD3: 03484 type = WINED3D_TS_WORLD_MATRIX(3); 03485 break; 03486 default: 03487 type = TransformStateType; 03488 } 03489 03490 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */ 03491 wined3d_mutex_lock(); 03492 hr = wined3d_device_multiply_transform(This->wined3d_device, 03493 type, (struct wined3d_matrix *)D3DMatrix); 03494 wined3d_mutex_unlock(); 03495 03496 return hr; 03497 } 03498 03499 static HRESULT WINAPI 03500 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup(IDirect3DDevice7 *iface, 03501 D3DTRANSFORMSTATETYPE TransformStateType, 03502 D3DMATRIX *D3DMatrix) 03503 { 03504 return IDirect3DDeviceImpl_7_MultiplyTransform(iface, TransformStateType, D3DMatrix); 03505 } 03506 03507 static HRESULT WINAPI 03508 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve(IDirect3DDevice7 *iface, 03509 D3DTRANSFORMSTATETYPE TransformStateType, 03510 D3DMATRIX *D3DMatrix) 03511 { 03512 HRESULT hr; 03513 WORD old_fpucw; 03514 03515 old_fpucw = d3d_fpu_setup(); 03516 hr = IDirect3DDeviceImpl_7_MultiplyTransform(iface, TransformStateType, D3DMatrix); 03517 set_fpu_control_word(old_fpucw); 03518 03519 return hr; 03520 } 03521 03522 static HRESULT WINAPI IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3 *iface, 03523 D3DTRANSFORMSTATETYPE state, D3DMATRIX *matrix) 03524 { 03525 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 03526 03527 TRACE("iface %p, state %#x, matrix %p.\n", iface, state, matrix); 03528 03529 if (state == D3DTRANSFORMSTATE_PROJECTION) 03530 { 03531 D3DMATRIX projection, tmp; 03532 HRESULT hr; 03533 03534 wined3d_mutex_lock(); 03535 multiply_matrix(&tmp, &This->legacy_projection, matrix); 03536 multiply_matrix(&projection, &This->legacy_clipspace, &tmp); 03537 hr = wined3d_device_set_transform(This->wined3d_device, 03538 WINED3D_TS_PROJECTION, (struct wined3d_matrix *)&projection); 03539 if (SUCCEEDED(hr)) 03540 This->legacy_projection = tmp; 03541 wined3d_mutex_unlock(); 03542 03543 return hr; 03544 } 03545 03546 return IDirect3DDevice7_MultiplyTransform(&This->IDirect3DDevice7_iface, state, matrix); 03547 } 03548 03549 static HRESULT WINAPI IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2 *iface, 03550 D3DTRANSFORMSTATETYPE TransformStateType, D3DMATRIX *D3DMatrix) 03551 { 03552 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 03553 03554 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, D3DMatrix); 03555 03556 return IDirect3DDevice7_MultiplyTransform(&This->IDirect3DDevice7_iface, TransformStateType, D3DMatrix); 03557 } 03558 03559 /***************************************************************************** 03560 * IDirect3DDevice7::DrawPrimitive 03561 * 03562 * Draws primitives based on vertices in an application-provided pointer 03563 * 03564 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into 03565 * an FVF format for D3D7 03566 * 03567 * Params: 03568 * PrimitiveType: The type of the primitives to draw 03569 * Vertex type: Flexible vertex format vertex description 03570 * Vertices: Pointer to the vertex array 03571 * VertexCount: The number of vertices to draw 03572 * Flags: As usual a few flags 03573 * 03574 * Returns: 03575 * D3D_OK on success 03576 * DDERR_INVALIDPARAMS if Vertices is NULL 03577 * For details, see IWineD3DDevice::DrawPrimitiveUP 03578 * 03579 *****************************************************************************/ 03580 static HRESULT 03581 IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7 *iface, 03582 D3DPRIMITIVETYPE PrimitiveType, 03583 DWORD VertexType, 03584 void *Vertices, 03585 DWORD VertexCount, 03586 DWORD Flags) 03587 { 03588 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 03589 UINT stride; 03590 HRESULT hr; 03591 03592 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x.\n", 03593 iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags); 03594 03595 if(!Vertices) 03596 return DDERR_INVALIDPARAMS; 03597 03598 /* Get the stride */ 03599 stride = get_flexible_vertex_size(VertexType); 03600 03601 /* Set the FVF */ 03602 wined3d_mutex_lock(); 03603 hr = wined3d_device_set_vertex_declaration(This->wined3d_device, ddraw_find_decl(This->ddraw, VertexType)); 03604 if(hr != D3D_OK) 03605 { 03606 wined3d_mutex_unlock(); 03607 return hr; 03608 } 03609 03610 /* This method translates to the user pointer draw of WineD3D */ 03611 wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType); 03612 hr = wined3d_device_draw_primitive_up(This->wined3d_device, VertexCount, Vertices, stride); 03613 wined3d_mutex_unlock(); 03614 03615 return hr; 03616 } 03617 03618 static HRESULT WINAPI 03619 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup(IDirect3DDevice7 *iface, 03620 D3DPRIMITIVETYPE PrimitiveType, 03621 DWORD VertexType, 03622 void *Vertices, 03623 DWORD VertexCount, 03624 DWORD Flags) 03625 { 03626 return IDirect3DDeviceImpl_7_DrawPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags); 03627 } 03628 03629 static HRESULT WINAPI 03630 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve(IDirect3DDevice7 *iface, 03631 D3DPRIMITIVETYPE PrimitiveType, 03632 DWORD VertexType, 03633 void *Vertices, 03634 DWORD VertexCount, 03635 DWORD Flags) 03636 { 03637 HRESULT hr; 03638 WORD old_fpucw; 03639 03640 old_fpucw = d3d_fpu_setup(); 03641 hr = IDirect3DDeviceImpl_7_DrawPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags); 03642 set_fpu_control_word(old_fpucw); 03643 03644 return hr; 03645 } 03646 03647 static HRESULT WINAPI IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3 *iface, 03648 D3DPRIMITIVETYPE PrimitiveType, DWORD VertexType, void *Vertices, DWORD VertexCount, 03649 DWORD Flags) 03650 { 03651 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 03652 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x.\n", 03653 iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags); 03654 03655 return IDirect3DDevice7_DrawPrimitive(&This->IDirect3DDevice7_iface, 03656 PrimitiveType, VertexType, Vertices, VertexCount, Flags); 03657 } 03658 03659 static HRESULT WINAPI IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2 *iface, 03660 D3DPRIMITIVETYPE PrimitiveType, D3DVERTEXTYPE VertexType, void *Vertices, 03661 DWORD VertexCount, DWORD Flags) 03662 { 03663 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 03664 DWORD FVF; 03665 03666 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x.\n", 03667 iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags); 03668 03669 switch(VertexType) 03670 { 03671 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break; 03672 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break; 03673 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break; 03674 default: 03675 ERR("Unexpected vertex type %d\n", VertexType); 03676 return DDERR_INVALIDPARAMS; /* Should never happen */ 03677 } 03678 03679 return IDirect3DDevice7_DrawPrimitive(&This->IDirect3DDevice7_iface, 03680 PrimitiveType, FVF, Vertices, VertexCount, Flags); 03681 } 03682 03683 /***************************************************************************** 03684 * IDirect3DDevice7::DrawIndexedPrimitive 03685 * 03686 * Draws vertices from an application-provided pointer, based on the index 03687 * numbers in a WORD array. 03688 * 03689 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into 03690 * an FVF format for D3D7 03691 * 03692 * Params: 03693 * PrimitiveType: The primitive type to draw 03694 * VertexType: The FVF vertex description 03695 * Vertices: Pointer to the vertex array 03696 * VertexCount: ? 03697 * Indices: Pointer to the index array 03698 * IndexCount: Number of indices = Number of vertices to draw 03699 * Flags: As usual, some flags 03700 * 03701 * Returns: 03702 * D3D_OK on success 03703 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL 03704 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP 03705 * 03706 *****************************************************************************/ 03707 static HRESULT 03708 IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7 *iface, 03709 D3DPRIMITIVETYPE PrimitiveType, 03710 DWORD VertexType, 03711 void *Vertices, 03712 DWORD VertexCount, 03713 WORD *Indices, 03714 DWORD IndexCount, 03715 DWORD Flags) 03716 { 03717 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 03718 HRESULT hr; 03719 03720 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n", 03721 iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags); 03722 03723 /* Set the D3DDevice's FVF */ 03724 wined3d_mutex_lock(); 03725 hr = wined3d_device_set_vertex_declaration(This->wined3d_device, ddraw_find_decl(This->ddraw, VertexType)); 03726 if(FAILED(hr)) 03727 { 03728 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr); 03729 wined3d_mutex_unlock(); 03730 return hr; 03731 } 03732 03733 wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType); 03734 hr = wined3d_device_draw_indexed_primitive_up(This->wined3d_device, IndexCount, Indices, 03735 WINED3DFMT_R16_UINT, Vertices, get_flexible_vertex_size(VertexType)); 03736 wined3d_mutex_unlock(); 03737 03738 return hr; 03739 } 03740 03741 static HRESULT WINAPI 03742 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup(IDirect3DDevice7 *iface, 03743 D3DPRIMITIVETYPE PrimitiveType, 03744 DWORD VertexType, 03745 void *Vertices, 03746 DWORD VertexCount, 03747 WORD *Indices, 03748 DWORD IndexCount, 03749 DWORD Flags) 03750 { 03751 return IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags); 03752 } 03753 03754 static HRESULT WINAPI 03755 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve(IDirect3DDevice7 *iface, 03756 D3DPRIMITIVETYPE PrimitiveType, 03757 DWORD VertexType, 03758 void *Vertices, 03759 DWORD VertexCount, 03760 WORD *Indices, 03761 DWORD IndexCount, 03762 DWORD Flags) 03763 { 03764 HRESULT hr; 03765 WORD old_fpucw; 03766 03767 old_fpucw = d3d_fpu_setup(); 03768 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags); 03769 set_fpu_control_word(old_fpucw); 03770 03771 return hr; 03772 } 03773 03774 static HRESULT WINAPI IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3 *iface, 03775 D3DPRIMITIVETYPE PrimitiveType, DWORD VertexType, void *Vertices, DWORD VertexCount, 03776 WORD *Indices, DWORD IndexCount, DWORD Flags) 03777 { 03778 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 03779 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n", 03780 iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags); 03781 03782 return IDirect3DDevice7_DrawIndexedPrimitive(&This->IDirect3DDevice7_iface, 03783 PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags); 03784 } 03785 03786 static HRESULT WINAPI IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2 *iface, 03787 D3DPRIMITIVETYPE PrimitiveType, D3DVERTEXTYPE VertexType, void *Vertices, 03788 DWORD VertexCount, WORD *Indices, DWORD IndexCount, DWORD Flags) 03789 { 03790 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 03791 DWORD FVF; 03792 03793 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n", 03794 iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags); 03795 03796 switch(VertexType) 03797 { 03798 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break; 03799 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break; 03800 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break; 03801 default: 03802 ERR("Unexpected vertex type %d\n", VertexType); 03803 return DDERR_INVALIDPARAMS; /* Should never happen */ 03804 } 03805 03806 return IDirect3DDevice7_DrawIndexedPrimitive(&This->IDirect3DDevice7_iface, 03807 PrimitiveType, FVF, Vertices, VertexCount, Indices, IndexCount, Flags); 03808 } 03809 03810 /***************************************************************************** 03811 * IDirect3DDevice7::SetClipStatus 03812 * 03813 * Sets the clip status. This defines things as clipping conditions and 03814 * the extents of the clipping region. 03815 * 03816 * Version 2, 3 and 7 03817 * 03818 * Params: 03819 * ClipStatus: 03820 * 03821 * Returns: 03822 * D3D_OK because it's a stub 03823 * (DDERR_INVALIDPARAMS if ClipStatus == NULL) 03824 * 03825 *****************************************************************************/ 03826 static HRESULT WINAPI 03827 IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7 *iface, 03828 D3DCLIPSTATUS *ClipStatus) 03829 { 03830 FIXME("iface %p, clip_status %p stub!\n", iface, ClipStatus); 03831 03832 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them 03833 * Perhaps this needs a new data type and an additional IWineD3DDevice method 03834 */ 03835 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/ 03836 return D3D_OK; 03837 } 03838 03839 static HRESULT WINAPI IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3 *iface, 03840 D3DCLIPSTATUS *ClipStatus) 03841 { 03842 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 03843 TRACE("iface %p, clip_status %p.\n", iface, ClipStatus); 03844 03845 return IDirect3DDevice7_SetClipStatus(&This->IDirect3DDevice7_iface, ClipStatus); 03846 } 03847 03848 static HRESULT WINAPI IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2 *iface, 03849 D3DCLIPSTATUS *ClipStatus) 03850 { 03851 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 03852 TRACE("iface %p, clip_status %p.\n", iface, ClipStatus); 03853 03854 return IDirect3DDevice7_SetClipStatus(&This->IDirect3DDevice7_iface, ClipStatus); 03855 } 03856 03857 /***************************************************************************** 03858 * IDirect3DDevice7::GetClipStatus 03859 * 03860 * Returns the clip status 03861 * 03862 * Params: 03863 * ClipStatus: Address to write the clip status to 03864 * 03865 * Returns: 03866 * D3D_OK because it's a stub 03867 * 03868 *****************************************************************************/ 03869 static HRESULT WINAPI 03870 IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7 *iface, 03871 D3DCLIPSTATUS *ClipStatus) 03872 { 03873 FIXME("iface %p, clip_status %p stub!\n", iface, ClipStatus); 03874 03875 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */ 03876 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/ 03877 return D3D_OK; 03878 } 03879 03880 static HRESULT WINAPI IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3 *iface, 03881 D3DCLIPSTATUS *ClipStatus) 03882 { 03883 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 03884 TRACE("iface %p, clip_status %p.\n", iface, ClipStatus); 03885 03886 return IDirect3DDevice7_GetClipStatus(&This->IDirect3DDevice7_iface, ClipStatus); 03887 } 03888 03889 static HRESULT WINAPI IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2 *iface, 03890 D3DCLIPSTATUS *ClipStatus) 03891 { 03892 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface); 03893 TRACE("iface %p, clip_status %p.\n", iface, ClipStatus); 03894 03895 return IDirect3DDevice7_GetClipStatus(&This->IDirect3DDevice7_iface, ClipStatus); 03896 } 03897 03898 /***************************************************************************** 03899 * IDirect3DDevice::DrawPrimitiveStrided 03900 * 03901 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure. 03902 * 03903 * Version 3 and 7 03904 * 03905 * Params: 03906 * PrimitiveType: The primitive type to draw 03907 * VertexType: The FVF description of the vertices to draw (for the stride??) 03908 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing 03909 * the vertex data locations 03910 * VertexCount: The number of vertices to draw 03911 * Flags: Some flags 03912 * 03913 * Returns: 03914 * D3D_OK, because it's a stub 03915 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL) 03916 * (For details, see IWineD3DDevice::DrawPrimitiveStrided) 03917 * 03918 *****************************************************************************/ 03919 static HRESULT 03920 IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7 *iface, 03921 D3DPRIMITIVETYPE PrimitiveType, 03922 DWORD VertexType, 03923 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData, 03924 DWORD VertexCount, 03925 DWORD Flags) 03926 { 03927 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 03928 struct wined3d_strided_data wined3d_strided; 03929 DWORD i; 03930 HRESULT hr; 03931 03932 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n", 03933 iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags); 03934 03935 memset(&wined3d_strided, 0, sizeof(wined3d_strided)); 03936 /* Get the strided data right. the wined3d structure is a bit bigger 03937 * Watch out: The contents of the strided data are determined by the fvf, 03938 * not by the members set in D3DDrawPrimStrideData. So it's valid 03939 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is 03940 * not set in the fvf. 03941 */ 03942 if(VertexType & D3DFVF_POSITION_MASK) 03943 { 03944 wined3d_strided.position.format = WINED3DFMT_R32G32B32_FLOAT; 03945 wined3d_strided.position.data = D3DDrawPrimStrideData->position.lpvData; 03946 wined3d_strided.position.stride = D3DDrawPrimStrideData->position.dwStride; 03947 if (VertexType & D3DFVF_XYZRHW) 03948 { 03949 wined3d_strided.position.format = WINED3DFMT_R32G32B32A32_FLOAT; 03950 wined3d_strided.position_transformed = TRUE; 03951 } 03952 else 03953 { 03954 wined3d_strided.position_transformed = FALSE; 03955 } 03956 } 03957 03958 if (VertexType & D3DFVF_NORMAL) 03959 { 03960 wined3d_strided.normal.format = WINED3DFMT_R32G32B32_FLOAT; 03961 wined3d_strided.normal.data = D3DDrawPrimStrideData->normal.lpvData; 03962 wined3d_strided.normal.stride = D3DDrawPrimStrideData->normal.dwStride; 03963 } 03964 03965 if (VertexType & D3DFVF_DIFFUSE) 03966 { 03967 wined3d_strided.diffuse.format = WINED3DFMT_B8G8R8A8_UNORM; 03968 wined3d_strided.diffuse.data = D3DDrawPrimStrideData->diffuse.lpvData; 03969 wined3d_strided.diffuse.stride = D3DDrawPrimStrideData->diffuse.dwStride; 03970 } 03971 03972 if (VertexType & D3DFVF_SPECULAR) 03973 { 03974 wined3d_strided.specular.format = WINED3DFMT_B8G8R8A8_UNORM; 03975 wined3d_strided.specular.data = D3DDrawPrimStrideData->specular.lpvData; 03976 wined3d_strided.specular.stride = D3DDrawPrimStrideData->specular.dwStride; 03977 } 03978 03979 for (i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); ++i) 03980 { 03981 switch (GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i)) 03982 { 03983 case 1: wined3d_strided.tex_coords[i].format = WINED3DFMT_R32_FLOAT; break; 03984 case 2: wined3d_strided.tex_coords[i].format = WINED3DFMT_R32G32_FLOAT; break; 03985 case 3: wined3d_strided.tex_coords[i].format = WINED3DFMT_R32G32B32_FLOAT; break; 03986 case 4: wined3d_strided.tex_coords[i].format = WINED3DFMT_R32G32B32A32_FLOAT; break; 03987 default: ERR("Unexpected texture coordinate size %d\n", 03988 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i)); 03989 } 03990 wined3d_strided.tex_coords[i].data = D3DDrawPrimStrideData->textureCoords[i].lpvData; 03991 wined3d_strided.tex_coords[i].stride = D3DDrawPrimStrideData->textureCoords[i].dwStride; 03992 } 03993 03994 /* WineD3D doesn't need the FVF here */ 03995 wined3d_mutex_lock(); 03996 wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType); 03997 hr = wined3d_device_draw_primitive_strided(This->wined3d_device, VertexCount, &wined3d_strided); 03998 wined3d_mutex_unlock(); 03999 04000 return hr; 04001 } 04002 04003 static HRESULT WINAPI 04004 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup(IDirect3DDevice7 *iface, 04005 D3DPRIMITIVETYPE PrimitiveType, 04006 DWORD VertexType, 04007 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData, 04008 DWORD VertexCount, 04009 DWORD Flags) 04010 { 04011 return IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags); 04012 } 04013 04014 static HRESULT WINAPI 04015 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve(IDirect3DDevice7 *iface, 04016 D3DPRIMITIVETYPE PrimitiveType, 04017 DWORD VertexType, 04018 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData, 04019 DWORD VertexCount, 04020 DWORD Flags) 04021 { 04022 HRESULT hr; 04023 WORD old_fpucw; 04024 04025 old_fpucw = d3d_fpu_setup(); 04026 hr = IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags); 04027 set_fpu_control_word(old_fpucw); 04028 04029 return hr; 04030 } 04031 04032 static HRESULT WINAPI IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3 *iface, 04033 D3DPRIMITIVETYPE PrimitiveType, DWORD VertexType, 04034 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData, DWORD VertexCount, DWORD Flags) 04035 { 04036 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 04037 04038 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n", 04039 iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags); 04040 04041 return IDirect3DDevice7_DrawPrimitiveStrided(&This->IDirect3DDevice7_iface, 04042 PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags); 04043 } 04044 04045 /***************************************************************************** 04046 * IDirect3DDevice7::DrawIndexedPrimitiveStrided 04047 * 04048 * Draws primitives specified by strided data locations based on indices 04049 * 04050 * Version 3 and 7 04051 * 04052 * Params: 04053 * PrimitiveType: 04054 * 04055 * Returns: 04056 * D3D_OK, because it's a stub 04057 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL) 04058 * (DDERR_INVALIDPARAMS if Indices is NULL) 04059 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided) 04060 * 04061 *****************************************************************************/ 04062 static HRESULT 04063 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface, 04064 D3DPRIMITIVETYPE PrimitiveType, 04065 DWORD VertexType, 04066 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData, 04067 DWORD VertexCount, 04068 WORD *Indices, 04069 DWORD IndexCount, 04070 DWORD Flags) 04071 { 04072 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 04073 struct wined3d_strided_data wined3d_strided; 04074 DWORD i; 04075 HRESULT hr; 04076 04077 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n", 04078 iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags); 04079 04080 memset(&wined3d_strided, 0, sizeof(wined3d_strided)); 04081 /* Get the strided data right. the wined3d structure is a bit bigger 04082 * Watch out: The contents of the strided data are determined by the fvf, 04083 * not by the members set in D3DDrawPrimStrideData. So it's valid 04084 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is 04085 * not set in the fvf. */ 04086 if (VertexType & D3DFVF_POSITION_MASK) 04087 { 04088 wined3d_strided.position.format = WINED3DFMT_R32G32B32_FLOAT; 04089 wined3d_strided.position.data = D3DDrawPrimStrideData->position.lpvData; 04090 wined3d_strided.position.stride = D3DDrawPrimStrideData->position.dwStride; 04091 if (VertexType & D3DFVF_XYZRHW) 04092 { 04093 wined3d_strided.position.format = WINED3DFMT_R32G32B32A32_FLOAT; 04094 wined3d_strided.position_transformed = TRUE; 04095 } 04096 else 04097 { 04098 wined3d_strided.position_transformed = FALSE; 04099 } 04100 } 04101 04102 if (VertexType & D3DFVF_NORMAL) 04103 { 04104 wined3d_strided.normal.format = WINED3DFMT_R32G32B32_FLOAT; 04105 wined3d_strided.normal.data = D3DDrawPrimStrideData->normal.lpvData; 04106 wined3d_strided.normal.stride = D3DDrawPrimStrideData->normal.dwStride; 04107 } 04108 04109 if (VertexType & D3DFVF_DIFFUSE) 04110 { 04111 wined3d_strided.diffuse.format = WINED3DFMT_B8G8R8A8_UNORM; 04112 wined3d_strided.diffuse.data = D3DDrawPrimStrideData->diffuse.lpvData; 04113 wined3d_strided.diffuse.stride = D3DDrawPrimStrideData->diffuse.dwStride; 04114 } 04115 04116 if (VertexType & D3DFVF_SPECULAR) 04117 { 04118 wined3d_strided.specular.format = WINED3DFMT_B8G8R8A8_UNORM; 04119 wined3d_strided.specular.data = D3DDrawPrimStrideData->specular.lpvData; 04120 wined3d_strided.specular.stride = D3DDrawPrimStrideData->specular.dwStride; 04121 } 04122 04123 for (i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); ++i) 04124 { 04125 switch (GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i)) 04126 { 04127 case 1: wined3d_strided.tex_coords[i].format = WINED3DFMT_R32_FLOAT; break; 04128 case 2: wined3d_strided.tex_coords[i].format = WINED3DFMT_R32G32_FLOAT; break; 04129 case 3: wined3d_strided.tex_coords[i].format = WINED3DFMT_R32G32B32_FLOAT; break; 04130 case 4: wined3d_strided.tex_coords[i].format = WINED3DFMT_R32G32B32A32_FLOAT; break; 04131 default: ERR("Unexpected texture coordinate size %d\n", 04132 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i)); 04133 } 04134 wined3d_strided.tex_coords[i].data = D3DDrawPrimStrideData->textureCoords[i].lpvData; 04135 wined3d_strided.tex_coords[i].stride = D3DDrawPrimStrideData->textureCoords[i].dwStride; 04136 } 04137 04138 /* WineD3D doesn't need the FVF here */ 04139 wined3d_mutex_lock(); 04140 wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType); 04141 hr = wined3d_device_draw_indexed_primitive_strided(This->wined3d_device, 04142 IndexCount, &wined3d_strided, VertexCount, Indices, WINED3DFMT_R16_UINT); 04143 wined3d_mutex_unlock(); 04144 04145 return hr; 04146 } 04147 04148 static HRESULT WINAPI 04149 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup(IDirect3DDevice7 *iface, 04150 D3DPRIMITIVETYPE PrimitiveType, 04151 DWORD VertexType, 04152 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData, 04153 DWORD VertexCount, 04154 WORD *Indices, 04155 DWORD IndexCount, 04156 DWORD Flags) 04157 { 04158 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags); 04159 } 04160 04161 static HRESULT WINAPI 04162 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve(IDirect3DDevice7 *iface, 04163 D3DPRIMITIVETYPE PrimitiveType, 04164 DWORD VertexType, 04165 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData, 04166 DWORD VertexCount, 04167 WORD *Indices, 04168 DWORD IndexCount, 04169 DWORD Flags) 04170 { 04171 HRESULT hr; 04172 WORD old_fpucw; 04173 04174 old_fpucw = d3d_fpu_setup(); 04175 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags); 04176 set_fpu_control_word(old_fpucw); 04177 04178 return hr; 04179 } 04180 04181 static HRESULT WINAPI IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3 *iface, 04182 D3DPRIMITIVETYPE PrimitiveType, DWORD VertexType, 04183 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData, DWORD VertexCount, WORD *Indices, 04184 DWORD IndexCount, DWORD Flags) 04185 { 04186 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 04187 04188 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n", 04189 iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags); 04190 04191 return IDirect3DDevice7_DrawIndexedPrimitiveStrided(&This->IDirect3DDevice7_iface, 04192 PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags); 04193 } 04194 04195 /***************************************************************************** 04196 * IDirect3DDevice7::DrawPrimitiveVB 04197 * 04198 * Draws primitives from a vertex buffer to the screen. 04199 * 04200 * Version 3 and 7 04201 * 04202 * Params: 04203 * PrimitiveType: Type of primitive to be rendered. 04204 * D3DVertexBuf: Source Vertex Buffer 04205 * StartVertex: Index of the first vertex from the buffer to be rendered 04206 * NumVertices: Number of vertices to be rendered 04207 * Flags: Can be D3DDP_WAIT to wait until rendering has finished 04208 * 04209 * Return values 04210 * D3D_OK on success 04211 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL 04212 * 04213 *****************************************************************************/ 04214 static HRESULT 04215 IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7 *iface, 04216 D3DPRIMITIVETYPE PrimitiveType, 04217 IDirect3DVertexBuffer7 *D3DVertexBuf, 04218 DWORD StartVertex, 04219 DWORD NumVertices, 04220 DWORD Flags) 04221 { 04222 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 04223 IDirect3DVertexBufferImpl *vb = unsafe_impl_from_IDirect3DVertexBuffer7(D3DVertexBuf); 04224 HRESULT hr; 04225 DWORD stride; 04226 04227 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n", 04228 iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags); 04229 04230 /* Sanity checks */ 04231 if(!vb) 04232 { 04233 ERR("(%p) No Vertex buffer specified\n", This); 04234 return DDERR_INVALIDPARAMS; 04235 } 04236 stride = get_flexible_vertex_size(vb->fvf); 04237 04238 wined3d_mutex_lock(); 04239 hr = wined3d_device_set_vertex_declaration(This->wined3d_device, vb->wineD3DVertexDeclaration); 04240 if (FAILED(hr)) 04241 { 04242 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr); 04243 wined3d_mutex_unlock(); 04244 return hr; 04245 } 04246 04247 /* Set the vertex stream source */ 04248 hr = wined3d_device_set_stream_source(This->wined3d_device, 0, vb->wineD3DVertexBuffer, 0, stride); 04249 if(hr != D3D_OK) 04250 { 04251 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr); 04252 wined3d_mutex_unlock(); 04253 return hr; 04254 } 04255 04256 /* Now draw the primitives */ 04257 wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType); 04258 hr = wined3d_device_draw_primitive(This->wined3d_device, StartVertex, NumVertices); 04259 wined3d_mutex_unlock(); 04260 04261 return hr; 04262 } 04263 04264 static HRESULT WINAPI 04265 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup(IDirect3DDevice7 *iface, 04266 D3DPRIMITIVETYPE PrimitiveType, 04267 IDirect3DVertexBuffer7 *D3DVertexBuf, 04268 DWORD StartVertex, 04269 DWORD NumVertices, 04270 DWORD Flags) 04271 { 04272 return IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags); 04273 } 04274 04275 static HRESULT WINAPI 04276 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve(IDirect3DDevice7 *iface, 04277 D3DPRIMITIVETYPE PrimitiveType, 04278 IDirect3DVertexBuffer7 *D3DVertexBuf, 04279 DWORD StartVertex, 04280 DWORD NumVertices, 04281 DWORD Flags) 04282 { 04283 HRESULT hr; 04284 WORD old_fpucw; 04285 04286 old_fpucw = d3d_fpu_setup(); 04287 hr = IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags); 04288 set_fpu_control_word(old_fpucw); 04289 04290 return hr; 04291 } 04292 04293 static HRESULT WINAPI IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3 *iface, 04294 D3DPRIMITIVETYPE PrimitiveType, IDirect3DVertexBuffer *D3DVertexBuf, DWORD StartVertex, 04295 DWORD NumVertices, DWORD Flags) 04296 { 04297 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 04298 IDirect3DVertexBufferImpl *vb = unsafe_impl_from_IDirect3DVertexBuffer(D3DVertexBuf); 04299 04300 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n", 04301 iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags); 04302 04303 return IDirect3DDevice7_DrawPrimitiveVB(&This->IDirect3DDevice7_iface, 04304 PrimitiveType, &vb->IDirect3DVertexBuffer7_iface, StartVertex, NumVertices, Flags); 04305 } 04306 04307 04308 /***************************************************************************** 04309 * IDirect3DDevice7::DrawIndexedPrimitiveVB 04310 * 04311 * Draws primitives from a vertex buffer to the screen 04312 * 04313 * Params: 04314 * PrimitiveType: Type of primitive to be rendered. 04315 * D3DVertexBuf: Source Vertex Buffer 04316 * StartVertex: Index of the first vertex from the buffer to be rendered 04317 * NumVertices: Number of vertices to be rendered 04318 * Indices: Array of DWORDs used to index into the Vertices 04319 * IndexCount: Number of indices in Indices 04320 * Flags: Can be D3DDP_WAIT to wait until rendering has finished 04321 * 04322 * Return values 04323 * 04324 *****************************************************************************/ 04325 static HRESULT 04326 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface, 04327 D3DPRIMITIVETYPE PrimitiveType, 04328 IDirect3DVertexBuffer7 *D3DVertexBuf, 04329 DWORD StartVertex, 04330 DWORD NumVertices, 04331 WORD *Indices, 04332 DWORD IndexCount, 04333 DWORD Flags) 04334 { 04335 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 04336 IDirect3DVertexBufferImpl *vb = unsafe_impl_from_IDirect3DVertexBuffer7(D3DVertexBuf); 04337 DWORD stride = get_flexible_vertex_size(vb->fvf); 04338 struct wined3d_resource *wined3d_resource; 04339 struct wined3d_resource_desc desc; 04340 WORD *LockedIndices; 04341 HRESULT hr; 04342 04343 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, indices %p, index_count %u, flags %#x.\n", 04344 iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Indices, IndexCount, Flags); 04345 04346 /* Steps: 04347 * 1) Upload the Indices to the index buffer 04348 * 2) Set the index source 04349 * 3) Set the Vertex Buffer as the Stream source 04350 * 4) Call IWineD3DDevice::DrawIndexedPrimitive 04351 */ 04352 04353 wined3d_mutex_lock(); 04354 04355 hr = wined3d_device_set_vertex_declaration(This->wined3d_device, vb->wineD3DVertexDeclaration); 04356 if (FAILED(hr)) 04357 { 04358 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr); 04359 wined3d_mutex_unlock(); 04360 return hr; 04361 } 04362 04363 /* check that the buffer is large enough to hold the indices, 04364 * reallocate if necessary. */ 04365 wined3d_resource = wined3d_buffer_get_resource(This->indexbuffer); 04366 wined3d_resource_get_desc(wined3d_resource, &desc); 04367 if (desc.size < IndexCount * sizeof(WORD)) 04368 { 04369 UINT size = max(desc.size * 2, IndexCount * sizeof(WORD)); 04370 struct wined3d_buffer *buffer; 04371 04372 TRACE("Growing index buffer to %u bytes\n", size); 04373 04374 hr = wined3d_buffer_create_ib(This->wined3d_device, size, WINED3DUSAGE_DYNAMIC /* Usage */, 04375 WINED3D_POOL_DEFAULT, NULL, &ddraw_null_wined3d_parent_ops, &buffer); 04376 if (FAILED(hr)) 04377 { 04378 ERR("(%p) IWineD3DDevice::CreateIndexBuffer failed with hr = %08x\n", This, hr); 04379 wined3d_mutex_unlock(); 04380 return hr; 04381 } 04382 04383 wined3d_buffer_decref(This->indexbuffer); 04384 This->indexbuffer = buffer; 04385 } 04386 04387 /* Copy the index stream into the index buffer. A new IWineD3DDevice 04388 * method could be created which takes an user pointer containing the 04389 * indices or a SetData-Method for the index buffer, which overrides the 04390 * index buffer data with our pointer. */ 04391 hr = wined3d_buffer_map(This->indexbuffer, 0, IndexCount * sizeof(WORD), 04392 (BYTE **)&LockedIndices, 0); 04393 if (FAILED(hr)) 04394 { 04395 ERR("Failed to map buffer, hr %#x.\n", hr); 04396 wined3d_mutex_unlock(); 04397 return hr; 04398 } 04399 memcpy(LockedIndices, Indices, IndexCount * sizeof(WORD)); 04400 wined3d_buffer_unmap(This->indexbuffer); 04401 04402 /* Set the index stream */ 04403 wined3d_device_set_base_vertex_index(This->wined3d_device, StartVertex); 04404 hr = wined3d_device_set_index_buffer(This->wined3d_device, This->indexbuffer, WINED3DFMT_R16_UINT); 04405 04406 /* Set the vertex stream source */ 04407 hr = wined3d_device_set_stream_source(This->wined3d_device, 0, vb->wineD3DVertexBuffer, 0, stride); 04408 if (FAILED(hr)) 04409 { 04410 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr); 04411 wined3d_mutex_unlock(); 04412 return hr; 04413 } 04414 04415 04416 wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType); 04417 hr = wined3d_device_draw_indexed_primitive(This->wined3d_device, 0, IndexCount); 04418 04419 wined3d_mutex_unlock(); 04420 04421 return hr; 04422 } 04423 04424 static HRESULT WINAPI 04425 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup(IDirect3DDevice7 *iface, 04426 D3DPRIMITIVETYPE PrimitiveType, 04427 IDirect3DVertexBuffer7 *D3DVertexBuf, 04428 DWORD StartVertex, 04429 DWORD NumVertices, 04430 WORD *Indices, 04431 DWORD IndexCount, 04432 DWORD Flags) 04433 { 04434 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Indices, IndexCount, Flags); 04435 } 04436 04437 static HRESULT WINAPI 04438 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve(IDirect3DDevice7 *iface, 04439 D3DPRIMITIVETYPE PrimitiveType, 04440 IDirect3DVertexBuffer7 *D3DVertexBuf, 04441 DWORD StartVertex, 04442 DWORD NumVertices, 04443 WORD *Indices, 04444 DWORD IndexCount, 04445 DWORD Flags) 04446 { 04447 HRESULT hr; 04448 WORD old_fpucw; 04449 04450 old_fpucw = d3d_fpu_setup(); 04451 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Indices, IndexCount, Flags); 04452 set_fpu_control_word(old_fpucw); 04453 04454 return hr; 04455 } 04456 04457 static HRESULT WINAPI IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3 *iface, 04458 D3DPRIMITIVETYPE PrimitiveType, IDirect3DVertexBuffer *D3DVertexBuf, WORD *Indices, 04459 DWORD IndexCount, DWORD Flags) 04460 { 04461 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 04462 IDirect3DVertexBufferImpl *vb = unsafe_impl_from_IDirect3DVertexBuffer(D3DVertexBuf); 04463 04464 TRACE("iface %p, primitive_type %#x, vb %p, indices %p, index_count %u, flags %#x.\n", 04465 iface, PrimitiveType, D3DVertexBuf, Indices, IndexCount, Flags); 04466 04467 return IDirect3DDevice7_DrawIndexedPrimitiveVB(&This->IDirect3DDevice7_iface, 04468 PrimitiveType, &vb->IDirect3DVertexBuffer7_iface, 0, IndexCount, Indices, IndexCount, 04469 Flags); 04470 } 04471 04472 /***************************************************************************** 04473 * IDirect3DDevice7::ComputeSphereVisibility 04474 * 04475 * Calculates the visibility of spheres in the current viewport. The spheres 04476 * are passed in the Centers and Radii arrays, the results are passed back 04477 * in the ReturnValues array. Return values are either completely visible, 04478 * partially visible or completely invisible. 04479 * The return value consist of a combination of D3DCLIP_* flags, or it's 04480 * 0 if the sphere is completely visible(according to the SDK, not checked) 04481 * 04482 * Version 3 and 7 04483 * 04484 * Params: 04485 * Centers: Array containing the sphere centers 04486 * Radii: Array containing the sphere radii 04487 * NumSpheres: The number of centers and radii in the arrays 04488 * Flags: Some flags 04489 * ReturnValues: Array to write the results to 04490 * 04491 * Returns: 04492 * D3D_OK 04493 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL) 04494 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix 04495 * is singular) 04496 * 04497 *****************************************************************************/ 04498 04499 static DWORD in_plane(UINT plane, D3DVECTOR normal, D3DVALUE origin_plane, D3DVECTOR center, D3DVALUE radius) 04500 { 04501 float distance, norm; 04502 04503 norm = sqrt( normal.u1.x * normal.u1.x + normal.u2.y * normal.u2.y + normal.u3.z * normal.u3.z ); 04504 distance = ( origin_plane + normal.u1.x * center.u1.x + normal.u2.y * center.u2.y + normal.u3.z * center.u3.z ) / norm; 04505 04506 if ( fabs( distance ) < radius ) return D3DSTATUS_CLIPUNIONLEFT << plane; 04507 if ( distance < -radius ) return (D3DSTATUS_CLIPUNIONLEFT | D3DSTATUS_CLIPINTERSECTIONLEFT) << plane; 04508 return 0; 04509 } 04510 04511 static HRESULT WINAPI 04512 IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7 *iface, 04513 D3DVECTOR *Centers, 04514 D3DVALUE *Radii, 04515 DWORD NumSpheres, 04516 DWORD Flags, 04517 DWORD *ReturnValues) 04518 { 04519 D3DMATRIX m, temp; 04520 D3DVALUE origin_plane[6]; 04521 D3DVECTOR vec[6]; 04522 HRESULT hr; 04523 UINT i, j; 04524 04525 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n", 04526 iface, Centers, Radii, NumSpheres, Flags, ReturnValues); 04527 04528 hr = IDirect3DDeviceImpl_7_GetTransform(iface, D3DTRANSFORMSTATE_WORLD, &m); 04529 if ( hr != DD_OK ) return DDERR_INVALIDPARAMS; 04530 hr = IDirect3DDeviceImpl_7_GetTransform(iface, D3DTRANSFORMSTATE_VIEW, &temp); 04531 if ( hr != DD_OK ) return DDERR_INVALIDPARAMS; 04532 multiply_matrix(&m, &temp, &m); 04533 04534 hr = IDirect3DDeviceImpl_7_GetTransform(iface, D3DTRANSFORMSTATE_PROJECTION, &temp); 04535 if ( hr != DD_OK ) return DDERR_INVALIDPARAMS; 04536 multiply_matrix(&m, &temp, &m); 04537 04538 /* Left plane */ 04539 vec[0].u1.x = m._14 + m._11; 04540 vec[0].u2.y = m._24 + m._21; 04541 vec[0].u3.z = m._34 + m._31; 04542 origin_plane[0] = m._44 + m._41; 04543 04544 /* Right plane */ 04545 vec[1].u1.x = m._14 - m._11; 04546 vec[1].u2.y = m._24 - m._21; 04547 vec[1].u3.z = m._34 - m._31; 04548 origin_plane[1] = m._44 - m._41; 04549 04550 /* Top plane */ 04551 vec[2].u1.x = m._14 - m._12; 04552 vec[2].u2.y = m._24 - m._22; 04553 vec[2].u3.z = m._34 - m._32; 04554 origin_plane[2] = m._44 - m._42; 04555 04556 /* Bottom plane */ 04557 vec[3].u1.x = m._14 + m._12; 04558 vec[3].u2.y = m._24 + m._22; 04559 vec[3].u3.z = m._34 + m._32; 04560 origin_plane[3] = m._44 + m._42; 04561 04562 /* Front plane */ 04563 vec[4].u1.x = m._13; 04564 vec[4].u2.y = m._23; 04565 vec[4].u3.z = m._33; 04566 origin_plane[4] = m._43; 04567 04568 /* Back plane*/ 04569 vec[5].u1.x = m._14 - m._13; 04570 vec[5].u2.y = m._24 - m._23; 04571 vec[5].u3.z = m._34 - m._33; 04572 origin_plane[5] = m._44 - m._43; 04573 04574 for(i=0; i<NumSpheres; i++) 04575 { 04576 ReturnValues[i] = 0; 04577 for(j=0; j<6; j++) ReturnValues[i] |= in_plane(j, vec[j], origin_plane[j], Centers[i], Radii[i]); 04578 } 04579 04580 return D3D_OK; 04581 } 04582 04583 static HRESULT WINAPI IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3 *iface, 04584 D3DVECTOR *Centers, D3DVALUE *Radii, DWORD NumSpheres, DWORD Flags, DWORD *ReturnValues) 04585 { 04586 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 04587 04588 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n", 04589 iface, Centers, Radii, NumSpheres, Flags, ReturnValues); 04590 04591 return IDirect3DDevice7_ComputeSphereVisibility(&This->IDirect3DDevice7_iface, 04592 Centers, Radii, NumSpheres, Flags, ReturnValues); 04593 } 04594 04595 /***************************************************************************** 04596 * IDirect3DDevice7::GetTexture 04597 * 04598 * Returns the texture interface handle assigned to a texture stage. 04599 * The returned texture is AddRefed. This is taken from old ddraw, 04600 * not checked in Windows. 04601 * 04602 * Version 3 and 7 04603 * 04604 * Params: 04605 * Stage: Texture stage to read the texture from 04606 * Texture: Address to store the interface pointer at 04607 * 04608 * Returns: 04609 * D3D_OK on success 04610 * DDERR_INVALIDPARAMS if Texture is NULL 04611 * For details, see IWineD3DDevice::GetTexture 04612 * 04613 *****************************************************************************/ 04614 static HRESULT 04615 IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7 *iface, 04616 DWORD Stage, 04617 IDirectDrawSurface7 **Texture) 04618 { 04619 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 04620 struct wined3d_texture *wined3d_texture; 04621 HRESULT hr; 04622 04623 TRACE("iface %p, stage %u, texture %p.\n", iface, Stage, Texture); 04624 04625 if(!Texture) 04626 { 04627 TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n"); 04628 return DDERR_INVALIDPARAMS; 04629 } 04630 04631 wined3d_mutex_lock(); 04632 hr = wined3d_device_get_texture(This->wined3d_device, Stage, &wined3d_texture); 04633 if (FAILED(hr) || !wined3d_texture) 04634 { 04635 *Texture = NULL; 04636 wined3d_mutex_unlock(); 04637 return hr; 04638 } 04639 04640 *Texture = wined3d_texture_get_parent(wined3d_texture); 04641 IDirectDrawSurface7_AddRef(*Texture); 04642 wined3d_texture_decref(wined3d_texture); 04643 wined3d_mutex_unlock(); 04644 04645 return hr; 04646 } 04647 04648 static HRESULT WINAPI 04649 IDirect3DDeviceImpl_7_GetTexture_FPUSetup(IDirect3DDevice7 *iface, 04650 DWORD Stage, 04651 IDirectDrawSurface7 **Texture) 04652 { 04653 return IDirect3DDeviceImpl_7_GetTexture(iface, Stage, Texture); 04654 } 04655 04656 static HRESULT WINAPI 04657 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve(IDirect3DDevice7 *iface, 04658 DWORD Stage, 04659 IDirectDrawSurface7 **Texture) 04660 { 04661 HRESULT hr; 04662 WORD old_fpucw; 04663 04664 old_fpucw = d3d_fpu_setup(); 04665 hr = IDirect3DDeviceImpl_7_GetTexture(iface, Stage, Texture); 04666 set_fpu_control_word(old_fpucw); 04667 04668 return hr; 04669 } 04670 04671 static HRESULT WINAPI IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3 *iface, DWORD Stage, 04672 IDirect3DTexture2 **Texture2) 04673 { 04674 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 04675 HRESULT ret; 04676 IDirectDrawSurface7 *ret_val; 04677 IDirectDrawSurfaceImpl *ret_val_impl; 04678 04679 TRACE("iface %p, stage %u, texture %p.\n", iface, Stage, Texture2); 04680 04681 ret = IDirect3DDevice7_GetTexture(&This->IDirect3DDevice7_iface, Stage, &ret_val); 04682 04683 ret_val_impl = unsafe_impl_from_IDirectDrawSurface7(ret_val); 04684 *Texture2 = ret_val_impl ? &ret_val_impl->IDirect3DTexture2_iface : NULL; 04685 04686 TRACE("Returning texture %p.\n", *Texture2); 04687 04688 return ret; 04689 } 04690 04691 /***************************************************************************** 04692 * IDirect3DDevice7::SetTexture 04693 * 04694 * Assigns a texture to a texture stage. Is the texture AddRef-ed? 04695 * 04696 * Version 3 and 7 04697 * 04698 * Params: 04699 * Stage: The stage to assign the texture to 04700 * Texture: Interface pointer to the texture surface 04701 * 04702 * Returns 04703 * D3D_OK on success 04704 * For details, see IWineD3DDevice::SetTexture 04705 * 04706 *****************************************************************************/ 04707 static HRESULT 04708 IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7 *iface, 04709 DWORD Stage, 04710 IDirectDrawSurface7 *Texture) 04711 { 04712 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 04713 IDirectDrawSurfaceImpl *surf = unsafe_impl_from_IDirectDrawSurface7(Texture); 04714 HRESULT hr; 04715 04716 TRACE("iface %p, stage %u, texture %p.\n", iface, Stage, Texture); 04717 04718 /* Texture may be NULL here */ 04719 wined3d_mutex_lock(); 04720 hr = wined3d_device_set_texture(This->wined3d_device, 04721 Stage, surf ? surf->wined3d_texture : NULL); 04722 wined3d_mutex_unlock(); 04723 04724 return hr; 04725 } 04726 04727 static HRESULT WINAPI 04728 IDirect3DDeviceImpl_7_SetTexture_FPUSetup(IDirect3DDevice7 *iface, 04729 DWORD Stage, 04730 IDirectDrawSurface7 *Texture) 04731 { 04732 return IDirect3DDeviceImpl_7_SetTexture(iface, Stage, Texture); 04733 } 04734 04735 static HRESULT WINAPI 04736 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve(IDirect3DDevice7 *iface, 04737 DWORD Stage, 04738 IDirectDrawSurface7 *Texture) 04739 { 04740 HRESULT hr; 04741 WORD old_fpucw; 04742 04743 old_fpucw = d3d_fpu_setup(); 04744 hr = IDirect3DDeviceImpl_7_SetTexture(iface, Stage, Texture); 04745 set_fpu_control_word(old_fpucw); 04746 04747 return hr; 04748 } 04749 04750 static HRESULT WINAPI 04751 IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3 *iface, 04752 DWORD Stage, 04753 IDirect3DTexture2 *Texture2) 04754 { 04755 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 04756 IDirectDrawSurfaceImpl *tex = unsafe_impl_from_IDirect3DTexture2(Texture2); 04757 DWORD texmapblend; 04758 HRESULT hr; 04759 04760 TRACE("iface %p, stage %u, texture %p.\n", iface, Stage, Texture2); 04761 04762 wined3d_mutex_lock(); 04763 04764 if (This->legacyTextureBlending) 04765 IDirect3DDevice3_GetRenderState(iface, D3DRENDERSTATE_TEXTUREMAPBLEND, &texmapblend); 04766 04767 hr = IDirect3DDevice7_SetTexture(&This->IDirect3DDevice7_iface, Stage, &tex->IDirectDrawSurface7_iface); 04768 04769 if (This->legacyTextureBlending && texmapblend == D3DTBLEND_MODULATE) 04770 { 04771 /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states. 04772 See IDirect3DDeviceImpl_3_SetRenderState for details. */ 04773 struct wined3d_texture *tex = NULL; 04774 BOOL tex_alpha = FALSE; 04775 DDPIXELFORMAT ddfmt; 04776 HRESULT result; 04777 04778 result = wined3d_device_get_texture(This->wined3d_device, 0, &tex); 04779 if (result == WINED3D_OK && tex) 04780 { 04781 struct wined3d_resource *sub_resource; 04782 04783 if ((sub_resource = wined3d_texture_get_sub_resource(tex, 0))) 04784 { 04785 struct wined3d_resource_desc desc; 04786 04787 wined3d_resource_get_desc(sub_resource, &desc); 04788 ddfmt.dwSize = sizeof(ddfmt); 04789 PixelFormat_WineD3DtoDD(&ddfmt, desc.format); 04790 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE; 04791 } 04792 04793 wined3d_texture_decref(tex); 04794 } 04795 04796 /* Arg 1/2 are already set to WINED3DTA_TEXTURE/WINED3DTA_CURRENT in case of D3DTBLEND_MODULATE */ 04797 if (tex_alpha) 04798 wined3d_device_set_texture_stage_state(This->wined3d_device, 04799 0, WINED3D_TSS_ALPHA_OP, WINED3D_TOP_SELECT_ARG1); 04800 else 04801 wined3d_device_set_texture_stage_state(This->wined3d_device, 04802 0, WINED3D_TSS_ALPHA_OP, WINED3D_TOP_SELECT_ARG2); 04803 } 04804 04805 wined3d_mutex_unlock(); 04806 04807 return hr; 04808 } 04809 04810 static const struct tss_lookup 04811 { 04812 BOOL sampler_state; 04813 enum wined3d_texture_stage_state state; 04814 } 04815 tss_lookup[] = 04816 { 04817 {FALSE, WINED3D_TSS_INVALID}, /* 0, unused */ 04818 {FALSE, WINED3D_TSS_COLOR_OP}, /* 1, D3DTSS_COLOROP */ 04819 {FALSE, WINED3D_TSS_COLOR_ARG1}, /* 2, D3DTSS_COLORARG1 */ 04820 {FALSE, WINED3D_TSS_COLOR_ARG2}, /* 3, D3DTSS_COLORARG2 */ 04821 {FALSE, WINED3D_TSS_ALPHA_OP}, /* 4, D3DTSS_ALPHAOP */ 04822 {FALSE, WINED3D_TSS_ALPHA_ARG1}, /* 5, D3DTSS_ALPHAARG1 */ 04823 {FALSE, WINED3D_TSS_ALPHA_ARG2}, /* 6, D3DTSS_ALPHAARG2 */ 04824 {FALSE, WINED3D_TSS_BUMPENV_MAT00}, /* 7, D3DTSS_BUMPENVMAT00 */ 04825 {FALSE, WINED3D_TSS_BUMPENV_MAT01}, /* 8, D3DTSS_BUMPENVMAT01 */ 04826 {FALSE, WINED3D_TSS_BUMPENV_MAT10}, /* 9, D3DTSS_BUMPENVMAT10 */ 04827 {FALSE, WINED3D_TSS_BUMPENV_MAT11}, /* 10, D3DTSS_BUMPENVMAT11 */ 04828 {FALSE, WINED3D_TSS_TEXCOORD_INDEX}, /* 11, D3DTSS_TEXCOORDINDEX */ 04829 {TRUE, WINED3D_SAMP_ADDRESS_U}, /* 12, D3DTSS_ADDRESS */ 04830 {TRUE, WINED3D_SAMP_ADDRESS_U}, /* 13, D3DTSS_ADDRESSU */ 04831 {TRUE, WINED3D_SAMP_ADDRESS_V}, /* 14, D3DTSS_ADDRESSV */ 04832 {TRUE, WINED3D_SAMP_BORDER_COLOR}, /* 15, D3DTSS_BORDERCOLOR */ 04833 {TRUE, WINED3D_SAMP_MAG_FILTER}, /* 16, D3DTSS_MAGFILTER */ 04834 {TRUE, WINED3D_SAMP_MIN_FILTER}, /* 17, D3DTSS_MINFILTER */ 04835 {TRUE, WINED3D_SAMP_MIP_FILTER}, /* 18, D3DTSS_MIPFILTER */ 04836 {TRUE, WINED3D_SAMP_MIPMAP_LOD_BIAS}, /* 19, D3DTSS_MIPMAPLODBIAS */ 04837 {TRUE, WINED3D_SAMP_MAX_MIP_LEVEL}, /* 20, D3DTSS_MAXMIPLEVEL */ 04838 {TRUE, WINED3D_SAMP_MAX_ANISOTROPY}, /* 21, D3DTSS_MAXANISOTROPY */ 04839 {FALSE, WINED3D_TSS_BUMPENV_LSCALE}, /* 22, D3DTSS_BUMPENVLSCALE */ 04840 {FALSE, WINED3D_TSS_BUMPENV_LOFFSET}, /* 23, D3DTSS_BUMPENVLOFFSET */ 04841 {FALSE, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */ 04842 }; 04843 04844 /***************************************************************************** 04845 * IDirect3DDevice7::GetTextureStageState 04846 * 04847 * Retrieves a state from a texture stage. 04848 * 04849 * Version 3 and 7 04850 * 04851 * Params: 04852 * Stage: The stage to retrieve the state from 04853 * TexStageStateType: The state type to retrieve 04854 * State: Address to store the state's value at 04855 * 04856 * Returns: 04857 * D3D_OK on success 04858 * DDERR_INVALIDPARAMS if State is NULL 04859 * For details, see IWineD3DDevice::GetTextureStageState 04860 * 04861 *****************************************************************************/ 04862 static HRESULT 04863 IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7 *iface, 04864 DWORD Stage, 04865 D3DTEXTURESTAGESTATETYPE TexStageStateType, 04866 DWORD *State) 04867 { 04868 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 04869 HRESULT hr; 04870 const struct tss_lookup *l; 04871 04872 TRACE("iface %p, stage %u, state %#x, value %p.\n", 04873 iface, Stage, TexStageStateType, State); 04874 04875 if(!State) 04876 return DDERR_INVALIDPARAMS; 04877 04878 if (TexStageStateType > D3DTSS_TEXTURETRANSFORMFLAGS) 04879 { 04880 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType); 04881 return DD_OK; 04882 } 04883 04884 l = &tss_lookup[TexStageStateType]; 04885 04886 wined3d_mutex_lock(); 04887 04888 if (l->sampler_state) 04889 { 04890 hr = wined3d_device_get_sampler_state(This->wined3d_device, Stage, l->state, State); 04891 04892 switch(TexStageStateType) 04893 { 04894 /* Mipfilter is a sampler state with different values */ 04895 case D3DTSS_MIPFILTER: 04896 { 04897 switch(*State) 04898 { 04899 case WINED3D_TEXF_NONE: 04900 *State = D3DTFP_NONE; 04901 break; 04902 case WINED3D_TEXF_POINT: 04903 *State = D3DTFP_POINT; 04904 break; 04905 case WINED3D_TEXF_LINEAR: 04906 *State = D3DTFP_LINEAR; 04907 break; 04908 default: 04909 ERR("Unexpected mipfilter value %#x\n", *State); 04910 *State = D3DTFP_NONE; 04911 break; 04912 } 04913 break; 04914 } 04915 04916 /* Magfilter has slightly different values */ 04917 case D3DTSS_MAGFILTER: 04918 { 04919 switch(*State) 04920 { 04921 case WINED3D_TEXF_POINT: 04922 *State = D3DTFG_POINT; 04923 break; 04924 case WINED3D_TEXF_LINEAR: 04925 *State = D3DTFG_LINEAR; 04926 break; 04927 case WINED3D_TEXF_ANISOTROPIC: 04928 *State = D3DTFG_ANISOTROPIC; 04929 break; 04930 case WINED3D_TEXF_FLAT_CUBIC: 04931 *State = D3DTFG_FLATCUBIC; 04932 break; 04933 case WINED3D_TEXF_GAUSSIAN_CUBIC: 04934 *State = D3DTFG_GAUSSIANCUBIC; 04935 break; 04936 default: 04937 ERR("Unexpected wined3d mag filter value %#x\n", *State); 04938 *State = D3DTFG_POINT; 04939 break; 04940 } 04941 break; 04942 } 04943 04944 default: 04945 break; 04946 } 04947 } 04948 else 04949 { 04950 hr = wined3d_device_get_texture_stage_state(This->wined3d_device, Stage, l->state, State); 04951 } 04952 04953 wined3d_mutex_unlock(); 04954 04955 return hr; 04956 } 04957 04958 static HRESULT WINAPI 04959 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup(IDirect3DDevice7 *iface, 04960 DWORD Stage, 04961 D3DTEXTURESTAGESTATETYPE TexStageStateType, 04962 DWORD *State) 04963 { 04964 return IDirect3DDeviceImpl_7_GetTextureStageState(iface, Stage, TexStageStateType, State); 04965 } 04966 04967 static HRESULT WINAPI 04968 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve(IDirect3DDevice7 *iface, 04969 DWORD Stage, 04970 D3DTEXTURESTAGESTATETYPE TexStageStateType, 04971 DWORD *State) 04972 { 04973 HRESULT hr; 04974 WORD old_fpucw; 04975 04976 old_fpucw = d3d_fpu_setup(); 04977 hr = IDirect3DDeviceImpl_7_GetTextureStageState(iface, Stage, TexStageStateType, State); 04978 set_fpu_control_word(old_fpucw); 04979 04980 return hr; 04981 } 04982 04983 static HRESULT WINAPI IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3 *iface, 04984 DWORD Stage, D3DTEXTURESTAGESTATETYPE TexStageStateType, DWORD *State) 04985 { 04986 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 04987 04988 TRACE("iface %p, stage %u, state %#x, value %p.\n", 04989 iface, Stage, TexStageStateType, State); 04990 04991 return IDirect3DDevice7_GetTextureStageState(&This->IDirect3DDevice7_iface, 04992 Stage, TexStageStateType, State); 04993 } 04994 04995 /***************************************************************************** 04996 * IDirect3DDevice7::SetTextureStageState 04997 * 04998 * Sets a texture stage state. Some stage types need to be handled specially, 04999 * because they do not exist in WineD3D and were moved to another place 05000 * 05001 * Version 3 and 7 05002 * 05003 * Params: 05004 * Stage: The stage to modify 05005 * TexStageStateType: The state to change 05006 * State: The new value for the state 05007 * 05008 * Returns: 05009 * D3D_OK on success 05010 * For details, see IWineD3DDevice::SetTextureStageState 05011 * 05012 *****************************************************************************/ 05013 static HRESULT 05014 IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7 *iface, 05015 DWORD Stage, 05016 D3DTEXTURESTAGESTATETYPE TexStageStateType, 05017 DWORD State) 05018 { 05019 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 05020 const struct tss_lookup *l; 05021 HRESULT hr; 05022 05023 TRACE("iface %p, stage %u, state %#x, value %#x.\n", 05024 iface, Stage, TexStageStateType, State); 05025 05026 if (TexStageStateType > D3DTSS_TEXTURETRANSFORMFLAGS) 05027 { 05028 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType); 05029 return DD_OK; 05030 } 05031 05032 l = &tss_lookup[TexStageStateType]; 05033 05034 wined3d_mutex_lock(); 05035 05036 if (l->sampler_state) 05037 { 05038 switch(TexStageStateType) 05039 { 05040 /* Mipfilter is a sampler state with different values */ 05041 case D3DTSS_MIPFILTER: 05042 { 05043 switch(State) 05044 { 05045 case D3DTFP_NONE: 05046 State = WINED3D_TEXF_NONE; 05047 break; 05048 case D3DTFP_POINT: 05049 State = WINED3D_TEXF_POINT; 05050 break; 05051 case 0: /* Unchecked */ 05052 case D3DTFP_LINEAR: 05053 State = WINED3D_TEXF_LINEAR; 05054 break; 05055 default: 05056 ERR("Unexpected mipfilter value %d\n", State); 05057 State = WINED3D_TEXF_NONE; 05058 break; 05059 } 05060 break; 05061 } 05062 05063 /* Magfilter has slightly different values */ 05064 case D3DTSS_MAGFILTER: 05065 { 05066 switch(State) 05067 { 05068 case D3DTFG_POINT: 05069 State = WINED3D_TEXF_POINT; 05070 break; 05071 case D3DTFG_LINEAR: 05072 State = WINED3D_TEXF_LINEAR; 05073 break; 05074 case D3DTFG_FLATCUBIC: 05075 State = WINED3D_TEXF_FLAT_CUBIC; 05076 break; 05077 case D3DTFG_GAUSSIANCUBIC: 05078 State = WINED3D_TEXF_GAUSSIAN_CUBIC; 05079 break; 05080 case D3DTFG_ANISOTROPIC: 05081 State = WINED3D_TEXF_ANISOTROPIC; 05082 break; 05083 default: 05084 ERR("Unexpected d3d7 mag filter type %d\n", State); 05085 State = WINED3D_TEXF_POINT; 05086 break; 05087 } 05088 break; 05089 } 05090 05091 case D3DTSS_ADDRESS: 05092 wined3d_device_set_sampler_state(This->wined3d_device, Stage, WINED3D_SAMP_ADDRESS_V, State); 05093 break; 05094 05095 default: 05096 break; 05097 } 05098 05099 hr = wined3d_device_set_sampler_state(This->wined3d_device, Stage, l->state, State); 05100 } 05101 else 05102 { 05103 hr = wined3d_device_set_texture_stage_state(This->wined3d_device, Stage, l->state, State); 05104 } 05105 05106 wined3d_mutex_unlock(); 05107 05108 return hr; 05109 } 05110 05111 static HRESULT WINAPI 05112 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup(IDirect3DDevice7 *iface, 05113 DWORD Stage, 05114 D3DTEXTURESTAGESTATETYPE TexStageStateType, 05115 DWORD State) 05116 { 05117 return IDirect3DDeviceImpl_7_SetTextureStageState(iface, Stage, TexStageStateType, State); 05118 } 05119 05120 static HRESULT WINAPI 05121 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve(IDirect3DDevice7 *iface, 05122 DWORD Stage, 05123 D3DTEXTURESTAGESTATETYPE TexStageStateType, 05124 DWORD State) 05125 { 05126 HRESULT hr; 05127 WORD old_fpucw; 05128 05129 old_fpucw = d3d_fpu_setup(); 05130 hr = IDirect3DDeviceImpl_7_SetTextureStageState(iface, Stage, TexStageStateType, State); 05131 set_fpu_control_word(old_fpucw); 05132 05133 return hr; 05134 } 05135 05136 static HRESULT WINAPI IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3 *iface, 05137 DWORD Stage, D3DTEXTURESTAGESTATETYPE TexStageStateType, DWORD State) 05138 { 05139 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 05140 05141 TRACE("iface %p, stage %u, state %#x, value %#x.\n", 05142 iface, Stage, TexStageStateType, State); 05143 05144 return IDirect3DDevice7_SetTextureStageState(&This->IDirect3DDevice7_iface, 05145 Stage, TexStageStateType, State); 05146 } 05147 05148 /***************************************************************************** 05149 * IDirect3DDevice7::ValidateDevice 05150 * 05151 * SDK: "Reports the device's ability to render the currently set 05152 * texture-blending operations in a single pass". Whatever that means 05153 * exactly... 05154 * 05155 * Version 3 and 7 05156 * 05157 * Params: 05158 * NumPasses: Address to write the number of necessary passes for the 05159 * desired effect to. 05160 * 05161 * Returns: 05162 * D3D_OK on success 05163 * See IWineD3DDevice::ValidateDevice for more details 05164 * 05165 *****************************************************************************/ 05166 static HRESULT 05167 IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7 *iface, 05168 DWORD *NumPasses) 05169 { 05170 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 05171 HRESULT hr; 05172 05173 TRACE("iface %p, pass_count %p.\n", iface, NumPasses); 05174 05175 wined3d_mutex_lock(); 05176 hr = wined3d_device_validate_device(This->wined3d_device, NumPasses); 05177 wined3d_mutex_unlock(); 05178 05179 return hr; 05180 } 05181 05182 static HRESULT WINAPI 05183 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup(IDirect3DDevice7 *iface, 05184 DWORD *NumPasses) 05185 { 05186 return IDirect3DDeviceImpl_7_ValidateDevice(iface, NumPasses); 05187 } 05188 05189 static HRESULT WINAPI 05190 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve(IDirect3DDevice7 *iface, 05191 DWORD *NumPasses) 05192 { 05193 HRESULT hr; 05194 WORD old_fpucw; 05195 05196 old_fpucw = d3d_fpu_setup(); 05197 hr = IDirect3DDeviceImpl_7_ValidateDevice(iface, NumPasses); 05198 set_fpu_control_word(old_fpucw); 05199 05200 return hr; 05201 } 05202 05203 static HRESULT WINAPI IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3 *iface, DWORD *Passes) 05204 { 05205 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface); 05206 05207 TRACE("iface %p, pass_count %p.\n", iface, Passes); 05208 05209 return IDirect3DDevice7_ValidateDevice(&This->IDirect3DDevice7_iface, Passes); 05210 } 05211 05212 /***************************************************************************** 05213 * IDirect3DDevice7::Clear 05214 * 05215 * Fills the render target, the z buffer and the stencil buffer with a 05216 * clear color / value 05217 * 05218 * Version 7 only 05219 * 05220 * Params: 05221 * Count: Number of rectangles in Rects must be 0 if Rects is NULL 05222 * Rects: Rectangles to clear. If NULL, the whole surface is cleared 05223 * Flags: Some flags, as usual 05224 * Color: Clear color for the render target 05225 * Z: Clear value for the Z buffer 05226 * Stencil: Clear value to store in each stencil buffer entry 05227 * 05228 * Returns: 05229 * D3D_OK on success 05230 * For details, see IWineD3DDevice::Clear 05231 * 05232 *****************************************************************************/ 05233 static HRESULT IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7 *iface, DWORD count, 05234 D3DRECT *rects, DWORD flags, D3DCOLOR color, D3DVALUE z, DWORD stencil) 05235 { 05236 const struct wined3d_color c = 05237 { 05238 ((color >> 16) & 0xff) / 255.0f, 05239 ((color >> 8) & 0xff) / 255.0f, 05240 (color & 0xff) / 255.0f, 05241 ((color >> 24) & 0xff) / 255.0f, 05242 }; 05243 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 05244 HRESULT hr; 05245 05246 TRACE("iface %p, count %u, rects %p, flags %#x, color 0x%08x, z %.8e, stencil %#x.\n", 05247 iface, count, rects, flags, color, z, stencil); 05248 05249 wined3d_mutex_lock(); 05250 hr = wined3d_device_clear(This->wined3d_device, count, (RECT *)rects, flags, &c, z, stencil); 05251 wined3d_mutex_unlock(); 05252 05253 return hr; 05254 } 05255 05256 static HRESULT WINAPI 05257 IDirect3DDeviceImpl_7_Clear_FPUSetup(IDirect3DDevice7 *iface, 05258 DWORD Count, 05259 D3DRECT *Rects, 05260 DWORD Flags, 05261 D3DCOLOR Color, 05262 D3DVALUE Z, 05263 DWORD Stencil) 05264 { 05265 return IDirect3DDeviceImpl_7_Clear(iface, Count, Rects, Flags, Color, Z, Stencil); 05266 } 05267 05268 static HRESULT WINAPI 05269 IDirect3DDeviceImpl_7_Clear_FPUPreserve(IDirect3DDevice7 *iface, 05270 DWORD Count, 05271 D3DRECT *Rects, 05272 DWORD Flags, 05273 D3DCOLOR Color, 05274 D3DVALUE Z, 05275 DWORD Stencil) 05276 { 05277 HRESULT hr; 05278 WORD old_fpucw; 05279 05280 old_fpucw = d3d_fpu_setup(); 05281 hr = IDirect3DDeviceImpl_7_Clear(iface, Count, Rects, Flags, Color, Z, Stencil); 05282 set_fpu_control_word(old_fpucw); 05283 05284 return hr; 05285 } 05286 05287 /***************************************************************************** 05288 * IDirect3DDevice7::SetViewport 05289 * 05290 * Sets the current viewport. 05291 * 05292 * Version 7 only, but IDirect3DViewport uses this call for older 05293 * versions 05294 * 05295 * Params: 05296 * Data: The new viewport to set 05297 * 05298 * Returns: 05299 * D3D_OK on success 05300 * DDERR_INVALIDPARAMS if Data is NULL 05301 * For more details, see IWineDDDevice::SetViewport 05302 * 05303 *****************************************************************************/ 05304 static HRESULT 05305 IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7 *iface, 05306 D3DVIEWPORT7 *Data) 05307 { 05308 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 05309 HRESULT hr; 05310 05311 TRACE("iface %p, viewport %p.\n", iface, Data); 05312 05313 if(!Data) 05314 return DDERR_INVALIDPARAMS; 05315 05316 /* Note: D3DVIEWPORT7 is compatible with struct wined3d_viewport. */ 05317 wined3d_mutex_lock(); 05318 hr = wined3d_device_set_viewport(This->wined3d_device, (struct wined3d_viewport *)Data); 05319 wined3d_mutex_unlock(); 05320 05321 return hr; 05322 } 05323 05324 static HRESULT WINAPI 05325 IDirect3DDeviceImpl_7_SetViewport_FPUSetup(IDirect3DDevice7 *iface, 05326 D3DVIEWPORT7 *Data) 05327 { 05328 return IDirect3DDeviceImpl_7_SetViewport(iface, Data); 05329 } 05330 05331 static HRESULT WINAPI 05332 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve(IDirect3DDevice7 *iface, 05333 D3DVIEWPORT7 *Data) 05334 { 05335 HRESULT hr; 05336 WORD old_fpucw; 05337 05338 old_fpucw = d3d_fpu_setup(); 05339 hr = IDirect3DDeviceImpl_7_SetViewport(iface, Data); 05340 set_fpu_control_word(old_fpucw); 05341 05342 return hr; 05343 } 05344 05345 /***************************************************************************** 05346 * IDirect3DDevice::GetViewport 05347 * 05348 * Returns the current viewport 05349 * 05350 * Version 7 05351 * 05352 * Params: 05353 * Data: D3D7Viewport structure to write the viewport information to 05354 * 05355 * Returns: 05356 * D3D_OK on success 05357 * DDERR_INVALIDPARAMS if Data is NULL 05358 * For more details, see IWineD3DDevice::GetViewport 05359 * 05360 *****************************************************************************/ 05361 static HRESULT 05362 IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7 *iface, 05363 D3DVIEWPORT7 *Data) 05364 { 05365 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 05366 HRESULT hr; 05367 05368 TRACE("iface %p, viewport %p.\n", iface, Data); 05369 05370 if(!Data) 05371 return DDERR_INVALIDPARAMS; 05372 05373 /* Note: D3DVIEWPORT7 is compatible with struct wined3d_viewport. */ 05374 wined3d_mutex_lock(); 05375 hr = wined3d_device_get_viewport(This->wined3d_device, (struct wined3d_viewport *)Data); 05376 wined3d_mutex_unlock(); 05377 05378 return hr_ddraw_from_wined3d(hr); 05379 } 05380 05381 static HRESULT WINAPI 05382 IDirect3DDeviceImpl_7_GetViewport_FPUSetup(IDirect3DDevice7 *iface, 05383 D3DVIEWPORT7 *Data) 05384 { 05385 return IDirect3DDeviceImpl_7_GetViewport(iface, Data); 05386 } 05387 05388 static HRESULT WINAPI 05389 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve(IDirect3DDevice7 *iface, 05390 D3DVIEWPORT7 *Data) 05391 { 05392 HRESULT hr; 05393 WORD old_fpucw; 05394 05395 old_fpucw = d3d_fpu_setup(); 05396 hr = IDirect3DDeviceImpl_7_GetViewport(iface, Data); 05397 set_fpu_control_word(old_fpucw); 05398 05399 return hr; 05400 } 05401 05402 /***************************************************************************** 05403 * IDirect3DDevice7::SetMaterial 05404 * 05405 * Sets the Material 05406 * 05407 * Version 7 05408 * 05409 * Params: 05410 * Mat: The material to set 05411 * 05412 * Returns: 05413 * D3D_OK on success 05414 * DDERR_INVALIDPARAMS if Mat is NULL. 05415 * For more details, see IWineD3DDevice::SetMaterial 05416 * 05417 *****************************************************************************/ 05418 static HRESULT 05419 IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7 *iface, 05420 D3DMATERIAL7 *Mat) 05421 { 05422 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 05423 HRESULT hr; 05424 05425 TRACE("iface %p, material %p.\n", iface, Mat); 05426 05427 if (!Mat) return DDERR_INVALIDPARAMS; 05428 05429 wined3d_mutex_lock(); 05430 /* Note: D3DMATERIAL7 is compatible with struct wined3d_material. */ 05431 hr = wined3d_device_set_material(This->wined3d_device, (struct wined3d_material *)Mat); 05432 wined3d_mutex_unlock(); 05433 05434 return hr_ddraw_from_wined3d(hr); 05435 } 05436 05437 static HRESULT WINAPI 05438 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup(IDirect3DDevice7 *iface, 05439 D3DMATERIAL7 *Mat) 05440 { 05441 return IDirect3DDeviceImpl_7_SetMaterial(iface, Mat); 05442 } 05443 05444 static HRESULT WINAPI 05445 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve(IDirect3DDevice7 *iface, 05446 D3DMATERIAL7 *Mat) 05447 { 05448 HRESULT hr; 05449 WORD old_fpucw; 05450 05451 old_fpucw = d3d_fpu_setup(); 05452 hr = IDirect3DDeviceImpl_7_SetMaterial(iface, Mat); 05453 set_fpu_control_word(old_fpucw); 05454 05455 return hr; 05456 } 05457 05458 /***************************************************************************** 05459 * IDirect3DDevice7::GetMaterial 05460 * 05461 * Returns the current material 05462 * 05463 * Version 7 05464 * 05465 * Params: 05466 * Mat: D3DMATERIAL7 structure to write the material parameters to 05467 * 05468 * Returns: 05469 * D3D_OK on success 05470 * DDERR_INVALIDPARAMS if Mat is NULL 05471 * For more details, see IWineD3DDevice::GetMaterial 05472 * 05473 *****************************************************************************/ 05474 static HRESULT 05475 IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7 *iface, 05476 D3DMATERIAL7 *Mat) 05477 { 05478 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 05479 HRESULT hr; 05480 05481 TRACE("iface %p, material %p.\n", iface, Mat); 05482 05483 wined3d_mutex_lock(); 05484 /* Note: D3DMATERIAL7 is compatible with struct wined3d_material. */ 05485 hr = wined3d_device_get_material(This->wined3d_device, (struct wined3d_material *)Mat); 05486 wined3d_mutex_unlock(); 05487 05488 return hr_ddraw_from_wined3d(hr); 05489 } 05490 05491 static HRESULT WINAPI 05492 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup(IDirect3DDevice7 *iface, 05493 D3DMATERIAL7 *Mat) 05494 { 05495 return IDirect3DDeviceImpl_7_GetMaterial(iface, Mat); 05496 } 05497 05498 static HRESULT WINAPI 05499 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve(IDirect3DDevice7 *iface, 05500 D3DMATERIAL7 *Mat) 05501 { 05502 HRESULT hr; 05503 WORD old_fpucw; 05504 05505 old_fpucw = d3d_fpu_setup(); 05506 hr = IDirect3DDeviceImpl_7_GetMaterial(iface, Mat); 05507 set_fpu_control_word(old_fpucw); 05508 05509 return hr; 05510 } 05511 05512 /***************************************************************************** 05513 * IDirect3DDevice7::SetLight 05514 * 05515 * Assigns a light to a light index, but doesn't activate it yet. 05516 * 05517 * Version 7, IDirect3DLight uses this method for older versions 05518 * 05519 * Params: 05520 * LightIndex: The index of the new light 05521 * Light: A D3DLIGHT7 structure describing the light 05522 * 05523 * Returns: 05524 * D3D_OK on success 05525 * For more details, see IWineD3DDevice::SetLight 05526 * 05527 *****************************************************************************/ 05528 static HRESULT 05529 IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7 *iface, 05530 DWORD LightIndex, 05531 D3DLIGHT7 *Light) 05532 { 05533 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 05534 HRESULT hr; 05535 05536 TRACE("iface %p, light_idx %u, light %p.\n", iface, LightIndex, Light); 05537 05538 wined3d_mutex_lock(); 05539 /* Note: D3DLIGHT7 is compatible with struct wined3d_light. */ 05540 hr = wined3d_device_set_light(This->wined3d_device, LightIndex, (struct wined3d_light *)Light); 05541 wined3d_mutex_unlock(); 05542 05543 return hr_ddraw_from_wined3d(hr); 05544 } 05545 05546 static HRESULT WINAPI 05547 IDirect3DDeviceImpl_7_SetLight_FPUSetup(IDirect3DDevice7 *iface, 05548 DWORD LightIndex, 05549 D3DLIGHT7 *Light) 05550 { 05551 return IDirect3DDeviceImpl_7_SetLight(iface, LightIndex, Light); 05552 } 05553 05554 static HRESULT WINAPI 05555 IDirect3DDeviceImpl_7_SetLight_FPUPreserve(IDirect3DDevice7 *iface, 05556 DWORD LightIndex, 05557 D3DLIGHT7 *Light) 05558 { 05559 HRESULT hr; 05560 WORD old_fpucw; 05561 05562 old_fpucw = d3d_fpu_setup(); 05563 hr = IDirect3DDeviceImpl_7_SetLight(iface, LightIndex, Light); 05564 set_fpu_control_word(old_fpucw); 05565 05566 return hr; 05567 } 05568 05569 /***************************************************************************** 05570 * IDirect3DDevice7::GetLight 05571 * 05572 * Returns the light assigned to a light index 05573 * 05574 * Params: 05575 * Light: Structure to write the light information to 05576 * 05577 * Returns: 05578 * D3D_OK on success 05579 * DDERR_INVALIDPARAMS if Light is NULL 05580 * For details, see IWineD3DDevice::GetLight 05581 * 05582 *****************************************************************************/ 05583 static HRESULT 05584 IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7 *iface, 05585 DWORD LightIndex, 05586 D3DLIGHT7 *Light) 05587 { 05588 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 05589 HRESULT rc; 05590 05591 TRACE("iface %p, light_idx %u, light %p.\n", iface, LightIndex, Light); 05592 05593 wined3d_mutex_lock(); 05594 /* Note: D3DLIGHT7 is compatible with struct wined3d_light. */ 05595 rc = wined3d_device_get_light(This->wined3d_device, LightIndex, (struct wined3d_light *)Light); 05596 wined3d_mutex_unlock(); 05597 05598 /* Translate the result. WineD3D returns other values than D3D7 */ 05599 return hr_ddraw_from_wined3d(rc); 05600 } 05601 05602 static HRESULT WINAPI 05603 IDirect3DDeviceImpl_7_GetLight_FPUSetup(IDirect3DDevice7 *iface, 05604 DWORD LightIndex, 05605 D3DLIGHT7 *Light) 05606 { 05607 return IDirect3DDeviceImpl_7_GetLight(iface, LightIndex, Light); 05608 } 05609 05610 static HRESULT WINAPI 05611 IDirect3DDeviceImpl_7_GetLight_FPUPreserve(IDirect3DDevice7 *iface, 05612 DWORD LightIndex, 05613 D3DLIGHT7 *Light) 05614 { 05615 HRESULT hr; 05616 WORD old_fpucw; 05617 05618 old_fpucw = d3d_fpu_setup(); 05619 hr = IDirect3DDeviceImpl_7_GetLight(iface, LightIndex, Light); 05620 set_fpu_control_word(old_fpucw); 05621 05622 return hr; 05623 } 05624 05625 /***************************************************************************** 05626 * IDirect3DDevice7::BeginStateBlock 05627 * 05628 * Begins recording to a stateblock 05629 * 05630 * Version 7 05631 * 05632 * Returns: 05633 * D3D_OK on success 05634 * For details see IWineD3DDevice::BeginStateBlock 05635 * 05636 *****************************************************************************/ 05637 static HRESULT 05638 IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7 *iface) 05639 { 05640 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 05641 HRESULT hr; 05642 05643 TRACE("iface %p.\n", iface); 05644 05645 wined3d_mutex_lock(); 05646 hr = wined3d_device_begin_stateblock(This->wined3d_device); 05647 wined3d_mutex_unlock(); 05648 05649 return hr_ddraw_from_wined3d(hr); 05650 } 05651 05652 static HRESULT WINAPI 05653 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup(IDirect3DDevice7 *iface) 05654 { 05655 return IDirect3DDeviceImpl_7_BeginStateBlock(iface); 05656 } 05657 05658 static HRESULT WINAPI 05659 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve(IDirect3DDevice7 *iface) 05660 { 05661 HRESULT hr; 05662 WORD old_fpucw; 05663 05664 old_fpucw = d3d_fpu_setup(); 05665 hr = IDirect3DDeviceImpl_7_BeginStateBlock(iface); 05666 set_fpu_control_word(old_fpucw); 05667 05668 return hr; 05669 } 05670 05671 /***************************************************************************** 05672 * IDirect3DDevice7::EndStateBlock 05673 * 05674 * Stops recording to a state block and returns the created stateblock 05675 * handle. 05676 * 05677 * Version 7 05678 * 05679 * Params: 05680 * BlockHandle: Address to store the stateblock's handle to 05681 * 05682 * Returns: 05683 * D3D_OK on success 05684 * DDERR_INVALIDPARAMS if BlockHandle is NULL 05685 * See IWineD3DDevice::EndStateBlock for more details 05686 * 05687 *****************************************************************************/ 05688 static HRESULT 05689 IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7 *iface, 05690 DWORD *BlockHandle) 05691 { 05692 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 05693 struct wined3d_stateblock *wined3d_sb; 05694 HRESULT hr; 05695 DWORD h; 05696 05697 TRACE("iface %p, stateblock %p.\n", iface, BlockHandle); 05698 05699 if(!BlockHandle) 05700 { 05701 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n"); 05702 return DDERR_INVALIDPARAMS; 05703 } 05704 05705 wined3d_mutex_lock(); 05706 05707 hr = wined3d_device_end_stateblock(This->wined3d_device, &wined3d_sb); 05708 if (FAILED(hr)) 05709 { 05710 WARN("Failed to end stateblock, hr %#x.\n", hr); 05711 wined3d_mutex_unlock(); 05712 *BlockHandle = 0; 05713 return hr_ddraw_from_wined3d(hr); 05714 } 05715 05716 h = ddraw_allocate_handle(&This->handle_table, wined3d_sb, DDRAW_HANDLE_STATEBLOCK); 05717 if (h == DDRAW_INVALID_HANDLE) 05718 { 05719 ERR("Failed to allocate a stateblock handle.\n"); 05720 wined3d_stateblock_decref(wined3d_sb); 05721 wined3d_mutex_unlock(); 05722 *BlockHandle = 0; 05723 return DDERR_OUTOFMEMORY; 05724 } 05725 05726 wined3d_mutex_unlock(); 05727 *BlockHandle = h + 1; 05728 05729 return hr_ddraw_from_wined3d(hr); 05730 } 05731 05732 static HRESULT WINAPI 05733 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup(IDirect3DDevice7 *iface, 05734 DWORD *BlockHandle) 05735 { 05736 return IDirect3DDeviceImpl_7_EndStateBlock(iface, BlockHandle); 05737 } 05738 05739 static HRESULT WINAPI 05740 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve(IDirect3DDevice7 *iface, 05741 DWORD *BlockHandle) 05742 { 05743 HRESULT hr; 05744 WORD old_fpucw; 05745 05746 old_fpucw = d3d_fpu_setup(); 05747 hr = IDirect3DDeviceImpl_7_EndStateBlock(iface, BlockHandle); 05748 set_fpu_control_word(old_fpucw); 05749 05750 return hr; 05751 } 05752 05753 /***************************************************************************** 05754 * IDirect3DDevice7::PreLoad 05755 * 05756 * Allows the app to signal that a texture will be used soon, to allow 05757 * the Direct3DDevice to load it to the video card in the meantime. 05758 * 05759 * Version 7 05760 * 05761 * Params: 05762 * Texture: The texture to preload 05763 * 05764 * Returns: 05765 * D3D_OK on success 05766 * DDERR_INVALIDPARAMS if Texture is NULL 05767 * See IWineD3DSurface::PreLoad for details 05768 * 05769 *****************************************************************************/ 05770 static HRESULT 05771 IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7 *iface, 05772 IDirectDrawSurface7 *Texture) 05773 { 05774 IDirectDrawSurfaceImpl *surf = unsafe_impl_from_IDirectDrawSurface7(Texture); 05775 05776 TRACE("iface %p, texture %p.\n", iface, Texture); 05777 05778 if(!Texture) 05779 return DDERR_INVALIDPARAMS; 05780 05781 wined3d_mutex_lock(); 05782 wined3d_surface_preload(surf->wined3d_surface); 05783 wined3d_mutex_unlock(); 05784 05785 return D3D_OK; 05786 } 05787 05788 static HRESULT WINAPI 05789 IDirect3DDeviceImpl_7_PreLoad_FPUSetup(IDirect3DDevice7 *iface, 05790 IDirectDrawSurface7 *Texture) 05791 { 05792 return IDirect3DDeviceImpl_7_PreLoad(iface, Texture); 05793 } 05794 05795 static HRESULT WINAPI 05796 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve(IDirect3DDevice7 *iface, 05797 IDirectDrawSurface7 *Texture) 05798 { 05799 HRESULT hr; 05800 WORD old_fpucw; 05801 05802 old_fpucw = d3d_fpu_setup(); 05803 hr = IDirect3DDeviceImpl_7_PreLoad(iface, Texture); 05804 set_fpu_control_word(old_fpucw); 05805 05806 return hr; 05807 } 05808 05809 /***************************************************************************** 05810 * IDirect3DDevice7::ApplyStateBlock 05811 * 05812 * Activates the state stored in a state block handle. 05813 * 05814 * Params: 05815 * BlockHandle: The stateblock handle to activate 05816 * 05817 * Returns: 05818 * D3D_OK on success 05819 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL 05820 * 05821 *****************************************************************************/ 05822 static HRESULT 05823 IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7 *iface, 05824 DWORD BlockHandle) 05825 { 05826 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 05827 struct wined3d_stateblock *wined3d_sb; 05828 HRESULT hr; 05829 05830 TRACE("iface %p, stateblock %#x.\n", iface, BlockHandle); 05831 05832 wined3d_mutex_lock(); 05833 wined3d_sb = ddraw_get_object(&This->handle_table, BlockHandle - 1, DDRAW_HANDLE_STATEBLOCK); 05834 if (!wined3d_sb) 05835 { 05836 WARN("Invalid stateblock handle.\n"); 05837 wined3d_mutex_unlock(); 05838 return D3DERR_INVALIDSTATEBLOCK; 05839 } 05840 05841 hr = wined3d_stateblock_apply(wined3d_sb); 05842 wined3d_mutex_unlock(); 05843 05844 return hr_ddraw_from_wined3d(hr); 05845 } 05846 05847 static HRESULT WINAPI 05848 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup(IDirect3DDevice7 *iface, 05849 DWORD BlockHandle) 05850 { 05851 return IDirect3DDeviceImpl_7_ApplyStateBlock(iface, BlockHandle); 05852 } 05853 05854 static HRESULT WINAPI 05855 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve(IDirect3DDevice7 *iface, 05856 DWORD BlockHandle) 05857 { 05858 HRESULT hr; 05859 WORD old_fpucw; 05860 05861 old_fpucw = d3d_fpu_setup(); 05862 hr = IDirect3DDeviceImpl_7_ApplyStateBlock(iface, BlockHandle); 05863 set_fpu_control_word(old_fpucw); 05864 05865 return hr; 05866 } 05867 05868 /***************************************************************************** 05869 * IDirect3DDevice7::CaptureStateBlock 05870 * 05871 * Updates a stateblock's values to the values currently set for the device 05872 * 05873 * Version 7 05874 * 05875 * Params: 05876 * BlockHandle: Stateblock to update 05877 * 05878 * Returns: 05879 * D3D_OK on success 05880 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL 05881 * See IWineD3DDevice::CaptureStateBlock for more details 05882 * 05883 *****************************************************************************/ 05884 static HRESULT 05885 IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7 *iface, 05886 DWORD BlockHandle) 05887 { 05888 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 05889 struct wined3d_stateblock *wined3d_sb; 05890 HRESULT hr; 05891 05892 TRACE("iface %p, stateblock %#x.\n", iface, BlockHandle); 05893 05894 wined3d_mutex_lock(); 05895 wined3d_sb = ddraw_get_object(&This->handle_table, BlockHandle - 1, DDRAW_HANDLE_STATEBLOCK); 05896 if (!wined3d_sb) 05897 { 05898 WARN("Invalid stateblock handle.\n"); 05899 wined3d_mutex_unlock(); 05900 return D3DERR_INVALIDSTATEBLOCK; 05901 } 05902 05903 hr = wined3d_stateblock_capture(wined3d_sb); 05904 wined3d_mutex_unlock(); 05905 05906 return hr_ddraw_from_wined3d(hr); 05907 } 05908 05909 static HRESULT WINAPI 05910 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup(IDirect3DDevice7 *iface, 05911 DWORD BlockHandle) 05912 { 05913 return IDirect3DDeviceImpl_7_CaptureStateBlock(iface, BlockHandle); 05914 } 05915 05916 static HRESULT WINAPI 05917 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve(IDirect3DDevice7 *iface, 05918 DWORD BlockHandle) 05919 { 05920 HRESULT hr; 05921 WORD old_fpucw; 05922 05923 old_fpucw = d3d_fpu_setup(); 05924 hr = IDirect3DDeviceImpl_7_CaptureStateBlock(iface, BlockHandle); 05925 set_fpu_control_word(old_fpucw); 05926 05927 return hr; 05928 } 05929 05930 /***************************************************************************** 05931 * IDirect3DDevice7::DeleteStateBlock 05932 * 05933 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock 05934 * 05935 * Version 7 05936 * 05937 * Params: 05938 * BlockHandle: Stateblock handle to delete 05939 * 05940 * Returns: 05941 * D3D_OK on success 05942 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0 05943 * 05944 *****************************************************************************/ 05945 static HRESULT 05946 IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7 *iface, 05947 DWORD BlockHandle) 05948 { 05949 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 05950 struct wined3d_stateblock *wined3d_sb; 05951 ULONG ref; 05952 05953 TRACE("iface %p, stateblock %#x.\n", iface, BlockHandle); 05954 05955 wined3d_mutex_lock(); 05956 05957 wined3d_sb = ddraw_free_handle(&This->handle_table, BlockHandle - 1, DDRAW_HANDLE_STATEBLOCK); 05958 if (!wined3d_sb) 05959 { 05960 WARN("Invalid stateblock handle.\n"); 05961 wined3d_mutex_unlock(); 05962 return D3DERR_INVALIDSTATEBLOCK; 05963 } 05964 05965 if ((ref = wined3d_stateblock_decref(wined3d_sb))) 05966 { 05967 ERR("Something is still holding stateblock %p (refcount %u).\n", wined3d_sb, ref); 05968 } 05969 05970 wined3d_mutex_unlock(); 05971 05972 return D3D_OK; 05973 } 05974 05975 static HRESULT WINAPI 05976 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup(IDirect3DDevice7 *iface, 05977 DWORD BlockHandle) 05978 { 05979 return IDirect3DDeviceImpl_7_DeleteStateBlock(iface, BlockHandle); 05980 } 05981 05982 static HRESULT WINAPI 05983 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve(IDirect3DDevice7 *iface, 05984 DWORD BlockHandle) 05985 { 05986 HRESULT hr; 05987 WORD old_fpucw; 05988 05989 old_fpucw = d3d_fpu_setup(); 05990 hr = IDirect3DDeviceImpl_7_DeleteStateBlock(iface, BlockHandle); 05991 set_fpu_control_word(old_fpucw); 05992 05993 return hr; 05994 } 05995 05996 /***************************************************************************** 05997 * IDirect3DDevice7::CreateStateBlock 05998 * 05999 * Creates a new state block handle. 06000 * 06001 * Version 7 06002 * 06003 * Params: 06004 * Type: The state block type 06005 * BlockHandle: Address to write the created handle to 06006 * 06007 * Returns: 06008 * D3D_OK on success 06009 * DDERR_INVALIDPARAMS if BlockHandle is NULL 06010 * 06011 *****************************************************************************/ 06012 static HRESULT 06013 IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7 *iface, 06014 D3DSTATEBLOCKTYPE Type, 06015 DWORD *BlockHandle) 06016 { 06017 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 06018 struct wined3d_stateblock *wined3d_sb; 06019 HRESULT hr; 06020 DWORD h; 06021 06022 TRACE("iface %p, type %#x, stateblock %p.\n", iface, Type, BlockHandle); 06023 06024 if(!BlockHandle) 06025 { 06026 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n"); 06027 return DDERR_INVALIDPARAMS; 06028 } 06029 if(Type != D3DSBT_ALL && Type != D3DSBT_PIXELSTATE && 06030 Type != D3DSBT_VERTEXSTATE ) { 06031 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n"); 06032 return DDERR_INVALIDPARAMS; 06033 } 06034 06035 wined3d_mutex_lock(); 06036 06037 /* The D3DSTATEBLOCKTYPE enum is fine here. */ 06038 hr = wined3d_stateblock_create(This->wined3d_device, Type, &wined3d_sb); 06039 if (FAILED(hr)) 06040 { 06041 WARN("Failed to create stateblock, hr %#x.\n", hr); 06042 wined3d_mutex_unlock(); 06043 return hr_ddraw_from_wined3d(hr); 06044 } 06045 06046 h = ddraw_allocate_handle(&This->handle_table, wined3d_sb, DDRAW_HANDLE_STATEBLOCK); 06047 if (h == DDRAW_INVALID_HANDLE) 06048 { 06049 ERR("Failed to allocate stateblock handle.\n"); 06050 wined3d_stateblock_decref(wined3d_sb); 06051 wined3d_mutex_unlock(); 06052 return DDERR_OUTOFMEMORY; 06053 } 06054 06055 *BlockHandle = h + 1; 06056 wined3d_mutex_unlock(); 06057 06058 return hr_ddraw_from_wined3d(hr); 06059 } 06060 06061 static HRESULT WINAPI 06062 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup(IDirect3DDevice7 *iface, 06063 D3DSTATEBLOCKTYPE Type, 06064 DWORD *BlockHandle) 06065 { 06066 return IDirect3DDeviceImpl_7_CreateStateBlock(iface, Type, BlockHandle); 06067 } 06068 06069 static HRESULT WINAPI 06070 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve(IDirect3DDevice7 *iface, 06071 D3DSTATEBLOCKTYPE Type, 06072 DWORD *BlockHandle) 06073 { 06074 HRESULT hr; 06075 WORD old_fpucw; 06076 06077 old_fpucw = d3d_fpu_setup(); 06078 hr =IDirect3DDeviceImpl_7_CreateStateBlock(iface, Type, BlockHandle); 06079 set_fpu_control_word(old_fpucw); 06080 06081 return hr; 06082 } 06083 06084 /* Helper function for IDirect3DDeviceImpl_7_Load. */ 06085 static BOOL is_mip_level_subset(IDirectDrawSurfaceImpl *dest, 06086 IDirectDrawSurfaceImpl *src) 06087 { 06088 IDirectDrawSurfaceImpl *src_level, *dest_level; 06089 IDirectDrawSurface7 *temp; 06090 DDSURFACEDESC2 ddsd; 06091 BOOL levelFound; /* at least one suitable sublevel in dest found */ 06092 06093 /* To satisfy "destination is mip level subset of source" criteria (regular texture counts as 1 level), 06094 * 1) there must be at least one mip level in destination that matched dimensions of some mip level in source and 06095 * 2) there must be no destination levels that don't match any levels in source. Otherwise it's INVALIDPARAMS. 06096 */ 06097 levelFound = FALSE; 06098 06099 src_level = src; 06100 dest_level = dest; 06101 06102 for (;src_level && dest_level;) 06103 { 06104 if (src_level->surface_desc.dwWidth == dest_level->surface_desc.dwWidth && 06105 src_level->surface_desc.dwHeight == dest_level->surface_desc.dwHeight) 06106 { 06107 levelFound = TRUE; 06108 06109 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE; 06110 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL; 06111 IDirectDrawSurface7_GetAttachedSurface(&dest_level->IDirectDrawSurface7_iface, &ddsd.ddsCaps, &temp); 06112 06113 if (dest_level != dest) IDirectDrawSurface7_Release(&dest_level->IDirectDrawSurface7_iface); 06114 06115 dest_level = unsafe_impl_from_IDirectDrawSurface7(temp); 06116 } 06117 06118 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE; 06119 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL; 06120 IDirectDrawSurface7_GetAttachedSurface(&src_level->IDirectDrawSurface7_iface, &ddsd.ddsCaps, &temp); 06121 06122 if (src_level != src) IDirectDrawSurface7_Release(&src_level->IDirectDrawSurface7_iface); 06123 06124 src_level = unsafe_impl_from_IDirectDrawSurface7(temp); 06125 } 06126 06127 if (src_level && src_level != src) IDirectDrawSurface7_Release(&src_level->IDirectDrawSurface7_iface); 06128 if (dest_level && dest_level != dest) IDirectDrawSurface7_Release(&dest_level->IDirectDrawSurface7_iface); 06129 06130 return !dest_level && levelFound; 06131 } 06132 06133 /* Helper function for IDirect3DDeviceImpl_7_Load. */ 06134 static void copy_mipmap_chain(IDirect3DDeviceImpl *device, 06135 IDirectDrawSurfaceImpl *dest, 06136 IDirectDrawSurfaceImpl *src, 06137 const POINT *DestPoint, 06138 const RECT *SrcRect) 06139 { 06140 IDirectDrawSurfaceImpl *src_level, *dest_level; 06141 IDirectDrawSurface7 *temp; 06142 DDSURFACEDESC2 ddsd; 06143 POINT point; 06144 RECT src_rect; 06145 HRESULT hr; 06146 IDirectDrawPalette *pal = NULL, *pal_src = NULL; 06147 DWORD ckeyflag; 06148 DDCOLORKEY ddckey; 06149 06150 /* Copy palette, if possible. */ 06151 IDirectDrawSurface7_GetPalette(&src->IDirectDrawSurface7_iface, &pal_src); 06152 IDirectDrawSurface7_GetPalette(&dest->IDirectDrawSurface7_iface, &pal); 06153 06154 if (pal_src != NULL && pal != NULL) 06155 { 06156 PALETTEENTRY palent[256]; 06157 06158 IDirectDrawPalette_GetEntries(pal_src, 0, 0, 256, palent); 06159 IDirectDrawPalette_SetEntries(pal, 0, 0, 256, palent); 06160 } 06161 06162 if (pal) IDirectDrawPalette_Release(pal); 06163 if (pal_src) IDirectDrawPalette_Release(pal_src); 06164 06165 /* Copy colorkeys, if present. */ 06166 for (ckeyflag = DDCKEY_DESTBLT; ckeyflag <= DDCKEY_SRCOVERLAY; ckeyflag <<= 1) 06167 { 06168 hr = IDirectDrawSurface7_GetColorKey(&src->IDirectDrawSurface7_iface, ckeyflag, &ddckey); 06169 06170 if (SUCCEEDED(hr)) 06171 { 06172 IDirectDrawSurface7_SetColorKey(&dest->IDirectDrawSurface7_iface, ckeyflag, &ddckey); 06173 } 06174 } 06175 06176 src_level = src; 06177 dest_level = dest; 06178 06179 point = *DestPoint; 06180 src_rect = *SrcRect; 06181 06182 for (;src_level && dest_level;) 06183 { 06184 if (src_level->surface_desc.dwWidth == dest_level->surface_desc.dwWidth && 06185 src_level->surface_desc.dwHeight == dest_level->surface_desc.dwHeight) 06186 { 06187 UINT src_w = src_rect.right - src_rect.left; 06188 UINT src_h = src_rect.bottom - src_rect.top; 06189 RECT dst_rect = {point.x, point.y, point.x + src_w, point.y + src_h}; 06190 06191 if (FAILED(hr = wined3d_surface_blt(dest_level->wined3d_surface, &dst_rect, 06192 src_level->wined3d_surface, &src_rect, 0, NULL, WINED3D_TEXF_POINT))) 06193 ERR("Blit failed, hr %#x.\n", hr); 06194 06195 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE; 06196 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL; 06197 IDirectDrawSurface7_GetAttachedSurface(&dest_level->IDirectDrawSurface7_iface, &ddsd.ddsCaps, &temp); 06198 06199 if (dest_level != dest) IDirectDrawSurface7_Release(&dest_level->IDirectDrawSurface7_iface); 06200 06201 dest_level = unsafe_impl_from_IDirectDrawSurface7(temp); 06202 } 06203 06204 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE; 06205 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL; 06206 IDirectDrawSurface7_GetAttachedSurface(&src_level->IDirectDrawSurface7_iface, &ddsd.ddsCaps, &temp); 06207 06208 if (src_level != src) IDirectDrawSurface7_Release(&src_level->IDirectDrawSurface7_iface); 06209 06210 src_level = unsafe_impl_from_IDirectDrawSurface7(temp); 06211 06212 point.x /= 2; 06213 point.y /= 2; 06214 06215 src_rect.top /= 2; 06216 src_rect.left /= 2; 06217 src_rect.right = (src_rect.right + 1) / 2; 06218 src_rect.bottom = (src_rect.bottom + 1) / 2; 06219 } 06220 06221 if (src_level && src_level != src) IDirectDrawSurface7_Release(&src_level->IDirectDrawSurface7_iface); 06222 if (dest_level && dest_level != dest) IDirectDrawSurface7_Release(&dest_level->IDirectDrawSurface7_iface); 06223 } 06224 06225 /***************************************************************************** 06226 * IDirect3DDevice7::Load 06227 * 06228 * Loads a rectangular area from the source into the destination texture. 06229 * It can also copy the source to the faces of a cubic environment map 06230 * 06231 * Version 7 06232 * 06233 * Params: 06234 * DestTex: Destination texture 06235 * DestPoint: Point in the destination where the source image should be 06236 * written to 06237 * SrcTex: Source texture 06238 * SrcRect: Source rectangle 06239 * Flags: Cubemap faces to load (DDSCAPS2_CUBEMAP_ALLFACES, DDSCAPS2_CUBEMAP_POSITIVEX, 06240 * DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY, 06241 * DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ) 06242 * 06243 * Returns: 06244 * D3D_OK on success 06245 * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL, broken coordinates or anything unexpected. 06246 * 06247 * 06248 *****************************************************************************/ 06249 06250 static HRESULT 06251 IDirect3DDeviceImpl_7_Load(IDirect3DDevice7 *iface, 06252 IDirectDrawSurface7 *DestTex, 06253 POINT *DestPoint, 06254 IDirectDrawSurface7 *SrcTex, 06255 RECT *SrcRect, 06256 DWORD Flags) 06257 { 06258 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 06259 IDirectDrawSurfaceImpl *dest = unsafe_impl_from_IDirectDrawSurface7(DestTex); 06260 IDirectDrawSurfaceImpl *src = unsafe_impl_from_IDirectDrawSurface7(SrcTex); 06261 POINT destpoint; 06262 RECT srcrect; 06263 06264 TRACE("iface %p, dst_texture %p, dst_pos %s, src_texture %p, src_rect %s, flags %#x.\n", 06265 iface, DestTex, wine_dbgstr_point(DestPoint), SrcTex, wine_dbgstr_rect(SrcRect), Flags); 06266 06267 if( (!src) || (!dest) ) 06268 return DDERR_INVALIDPARAMS; 06269 06270 wined3d_mutex_lock(); 06271 06272 if (SrcRect) srcrect = *SrcRect; 06273 else 06274 { 06275 srcrect.left = srcrect.top = 0; 06276 srcrect.right = src->surface_desc.dwWidth; 06277 srcrect.bottom = src->surface_desc.dwHeight; 06278 } 06279 06280 if (DestPoint) destpoint = *DestPoint; 06281 else 06282 { 06283 destpoint.x = destpoint.y = 0; 06284 } 06285 /* Check bad dimensions. DestPoint is validated against src, not dest, because 06286 * destination can be a subset of mip levels, in which case actual coordinates used 06287 * for it may be divided. If any dimension of dest is larger than source, it can't be 06288 * mip level subset, so an error can be returned early. 06289 */ 06290 if (srcrect.left >= srcrect.right || srcrect.top >= srcrect.bottom || 06291 srcrect.right > src->surface_desc.dwWidth || 06292 srcrect.bottom > src->surface_desc.dwHeight || 06293 destpoint.x + srcrect.right - srcrect.left > src->surface_desc.dwWidth || 06294 destpoint.y + srcrect.bottom - srcrect.top > src->surface_desc.dwHeight || 06295 dest->surface_desc.dwWidth > src->surface_desc.dwWidth || 06296 dest->surface_desc.dwHeight > src->surface_desc.dwHeight) 06297 { 06298 wined3d_mutex_unlock(); 06299 return DDERR_INVALIDPARAMS; 06300 } 06301 06302 /* Must be top level surfaces. */ 06303 if (src->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL || 06304 dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL) 06305 { 06306 wined3d_mutex_unlock(); 06307 return DDERR_INVALIDPARAMS; 06308 } 06309 06310 if (src->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP) 06311 { 06312 DWORD src_face_flag, dest_face_flag; 06313 IDirectDrawSurfaceImpl *src_face, *dest_face; 06314 IDirectDrawSurface7 *temp; 06315 DDSURFACEDESC2 ddsd; 06316 int i; 06317 06318 if (!(dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)) 06319 { 06320 wined3d_mutex_unlock(); 06321 return DDERR_INVALIDPARAMS; 06322 } 06323 06324 /* Iterate through cube faces 2 times. First time is just to check INVALIDPARAMS conditions, second 06325 * time it's actual surface loading. */ 06326 for (i = 0; i < 2; i++) 06327 { 06328 dest_face = dest; 06329 src_face = src; 06330 06331 for (;dest_face && src_face;) 06332 { 06333 src_face_flag = src_face->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES; 06334 dest_face_flag = dest_face->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES; 06335 06336 if (src_face_flag == dest_face_flag) 06337 { 06338 if (i == 0) 06339 { 06340 /* Destination mip levels must be subset of source mip levels. */ 06341 if (!is_mip_level_subset(dest_face, src_face)) 06342 { 06343 wined3d_mutex_unlock(); 06344 return DDERR_INVALIDPARAMS; 06345 } 06346 } 06347 else if (Flags & dest_face_flag) 06348 { 06349 copy_mipmap_chain(This, dest_face, src_face, &destpoint, &srcrect); 06350 } 06351 06352 if (src_face_flag < DDSCAPS2_CUBEMAP_NEGATIVEZ) 06353 { 06354 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE; 06355 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | (src_face_flag << 1); 06356 IDirectDrawSurface7_GetAttachedSurface(&src->IDirectDrawSurface7_iface, &ddsd.ddsCaps, &temp); 06357 06358 if (src_face != src) IDirectDrawSurface7_Release(&src_face->IDirectDrawSurface7_iface); 06359 06360 src_face = unsafe_impl_from_IDirectDrawSurface7(temp); 06361 } 06362 else 06363 { 06364 if (src_face != src) IDirectDrawSurface7_Release(&src_face->IDirectDrawSurface7_iface); 06365 06366 src_face = NULL; 06367 } 06368 } 06369 06370 if (dest_face_flag < DDSCAPS2_CUBEMAP_NEGATIVEZ) 06371 { 06372 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE; 06373 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | (dest_face_flag << 1); 06374 IDirectDrawSurface7_GetAttachedSurface(&dest->IDirectDrawSurface7_iface, &ddsd.ddsCaps, &temp); 06375 06376 if (dest_face != dest) IDirectDrawSurface7_Release(&dest_face->IDirectDrawSurface7_iface); 06377 06378 dest_face = unsafe_impl_from_IDirectDrawSurface7(temp); 06379 } 06380 else 06381 { 06382 if (dest_face != dest) IDirectDrawSurface7_Release(&dest_face->IDirectDrawSurface7_iface); 06383 06384 dest_face = NULL; 06385 } 06386 } 06387 06388 if (i == 0) 06389 { 06390 /* Native returns error if src faces are not subset of dest faces. */ 06391 if (src_face) 06392 { 06393 wined3d_mutex_unlock(); 06394 return DDERR_INVALIDPARAMS; 06395 } 06396 } 06397 } 06398 06399 wined3d_mutex_unlock(); 06400 return D3D_OK; 06401 } 06402 else if (dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP) 06403 { 06404 wined3d_mutex_unlock(); 06405 return DDERR_INVALIDPARAMS; 06406 } 06407 06408 /* Handle non cube map textures. */ 06409 06410 /* Destination mip levels must be subset of source mip levels. */ 06411 if (!is_mip_level_subset(dest, src)) 06412 { 06413 wined3d_mutex_unlock(); 06414 return DDERR_INVALIDPARAMS; 06415 } 06416 06417 copy_mipmap_chain(This, dest, src, &destpoint, &srcrect); 06418 06419 wined3d_mutex_unlock(); 06420 06421 return D3D_OK; 06422 } 06423 06424 static HRESULT WINAPI 06425 IDirect3DDeviceImpl_7_Load_FPUSetup(IDirect3DDevice7 *iface, 06426 IDirectDrawSurface7 *DestTex, 06427 POINT *DestPoint, 06428 IDirectDrawSurface7 *SrcTex, 06429 RECT *SrcRect, 06430 DWORD Flags) 06431 { 06432 return IDirect3DDeviceImpl_7_Load(iface, DestTex, DestPoint, SrcTex, SrcRect, Flags); 06433 } 06434 06435 static HRESULT WINAPI 06436 IDirect3DDeviceImpl_7_Load_FPUPreserve(IDirect3DDevice7 *iface, 06437 IDirectDrawSurface7 *DestTex, 06438 POINT *DestPoint, 06439 IDirectDrawSurface7 *SrcTex, 06440 RECT *SrcRect, 06441 DWORD Flags) 06442 { 06443 HRESULT hr; 06444 WORD old_fpucw; 06445 06446 old_fpucw = d3d_fpu_setup(); 06447 hr = IDirect3DDeviceImpl_7_Load(iface, DestTex, DestPoint, SrcTex, SrcRect, Flags); 06448 set_fpu_control_word(old_fpucw); 06449 06450 return hr; 06451 } 06452 06453 /***************************************************************************** 06454 * IDirect3DDevice7::LightEnable 06455 * 06456 * Enables or disables a light 06457 * 06458 * Version 7, IDirect3DLight uses this method too. 06459 * 06460 * Params: 06461 * LightIndex: The index of the light to enable / disable 06462 * Enable: Enable or disable the light 06463 * 06464 * Returns: 06465 * D3D_OK on success 06466 * For more details, see IWineD3DDevice::SetLightEnable 06467 * 06468 *****************************************************************************/ 06469 static HRESULT 06470 IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7 *iface, 06471 DWORD LightIndex, 06472 BOOL Enable) 06473 { 06474 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 06475 HRESULT hr; 06476 06477 TRACE("iface %p, light_idx %u, enabled %#x.\n", iface, LightIndex, Enable); 06478 06479 wined3d_mutex_lock(); 06480 hr = wined3d_device_set_light_enable(This->wined3d_device, LightIndex, Enable); 06481 wined3d_mutex_unlock(); 06482 06483 return hr_ddraw_from_wined3d(hr); 06484 } 06485 06486 static HRESULT WINAPI 06487 IDirect3DDeviceImpl_7_LightEnable_FPUSetup(IDirect3DDevice7 *iface, 06488 DWORD LightIndex, 06489 BOOL Enable) 06490 { 06491 return IDirect3DDeviceImpl_7_LightEnable(iface, LightIndex, Enable); 06492 } 06493 06494 static HRESULT WINAPI 06495 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve(IDirect3DDevice7 *iface, 06496 DWORD LightIndex, 06497 BOOL Enable) 06498 { 06499 HRESULT hr; 06500 WORD old_fpucw; 06501 06502 old_fpucw = d3d_fpu_setup(); 06503 hr = IDirect3DDeviceImpl_7_LightEnable(iface, LightIndex, Enable); 06504 set_fpu_control_word(old_fpucw); 06505 06506 return hr; 06507 } 06508 06509 /***************************************************************************** 06510 * IDirect3DDevice7::GetLightEnable 06511 * 06512 * Retrieves if the light with the given index is enabled or not 06513 * 06514 * Version 7 06515 * 06516 * Params: 06517 * LightIndex: Index of desired light 06518 * Enable: Pointer to a BOOL which contains the result 06519 * 06520 * Returns: 06521 * D3D_OK on success 06522 * DDERR_INVALIDPARAMS if Enable is NULL 06523 * See IWineD3DDevice::GetLightEnable for more details 06524 * 06525 *****************************************************************************/ 06526 static HRESULT 06527 IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7 *iface, 06528 DWORD LightIndex, 06529 BOOL* Enable) 06530 { 06531 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 06532 HRESULT hr; 06533 06534 TRACE("iface %p, light_idx %u, enabled %p.\n", iface, LightIndex, Enable); 06535 06536 if(!Enable) 06537 return DDERR_INVALIDPARAMS; 06538 06539 wined3d_mutex_lock(); 06540 hr = wined3d_device_get_light_enable(This->wined3d_device, LightIndex, Enable); 06541 wined3d_mutex_unlock(); 06542 06543 return hr_ddraw_from_wined3d(hr); 06544 } 06545 06546 static HRESULT WINAPI 06547 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup(IDirect3DDevice7 *iface, 06548 DWORD LightIndex, 06549 BOOL* Enable) 06550 { 06551 return IDirect3DDeviceImpl_7_GetLightEnable(iface, LightIndex, Enable); 06552 } 06553 06554 static HRESULT WINAPI 06555 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve(IDirect3DDevice7 *iface, 06556 DWORD LightIndex, 06557 BOOL* Enable) 06558 { 06559 HRESULT hr; 06560 WORD old_fpucw; 06561 06562 old_fpucw = d3d_fpu_setup(); 06563 hr = IDirect3DDeviceImpl_7_GetLightEnable(iface, LightIndex, Enable); 06564 set_fpu_control_word(old_fpucw); 06565 06566 return hr; 06567 } 06568 06569 /***************************************************************************** 06570 * IDirect3DDevice7::SetClipPlane 06571 * 06572 * Sets custom clipping plane 06573 * 06574 * Version 7 06575 * 06576 * Params: 06577 * Index: The index of the clipping plane 06578 * PlaneEquation: An equation defining the clipping plane 06579 * 06580 * Returns: 06581 * D3D_OK on success 06582 * DDERR_INVALIDPARAMS if PlaneEquation is NULL 06583 * See IWineD3DDevice::SetClipPlane for more details 06584 * 06585 *****************************************************************************/ 06586 static HRESULT 06587 IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7 *iface, 06588 DWORD Index, 06589 D3DVALUE* PlaneEquation) 06590 { 06591 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 06592 HRESULT hr; 06593 06594 TRACE("iface %p, idx %u, plane %p.\n", iface, Index, PlaneEquation); 06595 06596 if(!PlaneEquation) 06597 return DDERR_INVALIDPARAMS; 06598 06599 wined3d_mutex_lock(); 06600 hr = wined3d_device_set_clip_plane(This->wined3d_device, Index, PlaneEquation); 06601 wined3d_mutex_unlock(); 06602 06603 return hr; 06604 } 06605 06606 static HRESULT WINAPI 06607 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup(IDirect3DDevice7 *iface, 06608 DWORD Index, 06609 D3DVALUE* PlaneEquation) 06610 { 06611 return IDirect3DDeviceImpl_7_SetClipPlane(iface, Index, PlaneEquation); 06612 } 06613 06614 static HRESULT WINAPI 06615 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve(IDirect3DDevice7 *iface, 06616 DWORD Index, 06617 D3DVALUE* PlaneEquation) 06618 { 06619 HRESULT hr; 06620 WORD old_fpucw; 06621 06622 old_fpucw = d3d_fpu_setup(); 06623 hr = IDirect3DDeviceImpl_7_SetClipPlane(iface, Index, PlaneEquation); 06624 set_fpu_control_word(old_fpucw); 06625 06626 return hr; 06627 } 06628 06629 /***************************************************************************** 06630 * IDirect3DDevice7::GetClipPlane 06631 * 06632 * Returns the clipping plane with a specific index 06633 * 06634 * Params: 06635 * Index: The index of the desired plane 06636 * PlaneEquation: Address to store the plane equation to 06637 * 06638 * Returns: 06639 * D3D_OK on success 06640 * DDERR_INVALIDPARAMS if PlaneEquation is NULL 06641 * See IWineD3DDevice::GetClipPlane for more details 06642 * 06643 *****************************************************************************/ 06644 static HRESULT 06645 IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7 *iface, 06646 DWORD Index, 06647 D3DVALUE* PlaneEquation) 06648 { 06649 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface); 06650 HRESULT hr; 06651 06652 TRACE("iface %p, idx %u, plane %p.\n", iface, Index, PlaneEquation); 06653 06654 if(!PlaneEquation) 06655 return DDERR_INVALIDPARAMS; 06656 06657 wined3d_mutex_lock(); 06658 hr = wined3d_device_get_clip_plane(This->wined3d_device, Index, PlaneEquation); 06659 wined3d_mutex_unlock(); 06660 06661 return hr; 06662 } 06663 06664 static HRESULT WINAPI 06665 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup(IDirect3DDevice7 *iface, 06666 DWORD Index, 06667 D3DVALUE* PlaneEquation) 06668 { 06669 return IDirect3DDeviceImpl_7_GetClipPlane(iface, Index, PlaneEquation); 06670 } 06671 06672 static HRESULT WINAPI 06673 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve(IDirect3DDevice7 *iface, 06674 DWORD Index, 06675 D3DVALUE* PlaneEquation) 06676 { 06677 HRESULT hr; 06678 WORD old_fpucw; 06679 06680 old_fpucw = d3d_fpu_setup(); 06681 hr = IDirect3DDeviceImpl_7_GetClipPlane(iface, Index, PlaneEquation); 06682 set_fpu_control_word(old_fpucw); 06683 06684 return hr; 06685 } 06686 06687 /***************************************************************************** 06688 * IDirect3DDevice7::GetInfo 06689 * 06690 * Retrieves some information about the device. The DirectX sdk says that 06691 * this version returns S_FALSE for all retail builds of DirectX, that's what 06692 * this implementation does. 06693 * 06694 * Params: 06695 * DevInfoID: Information type requested 06696 * DevInfoStruct: Pointer to a structure to store the info to 06697 * Size: Size of the structure 06698 * 06699 * Returns: 06700 * S_FALSE, because it's a non-debug driver 06701 * 06702 *****************************************************************************/ 06703 static HRESULT WINAPI 06704 IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7 *iface, 06705 DWORD DevInfoID, 06706 void *DevInfoStruct, 06707 DWORD Size) 06708 { 06709 TRACE("iface %p, info_id %#x, info %p, info_size %u.\n", 06710 iface, DevInfoID, DevInfoStruct, Size); 06711 06712 if (TRACE_ON(ddraw)) 06713 { 06714 TRACE(" info requested : "); 06715 switch (DevInfoID) 06716 { 06717 case D3DDEVINFOID_TEXTUREMANAGER: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break; 06718 case D3DDEVINFOID_D3DTEXTUREMANAGER: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break; 06719 case D3DDEVINFOID_TEXTURING: TRACE("D3DDEVINFOID_TEXTURING\n"); break; 06720 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS; 06721 } 06722 } 06723 06724 return S_FALSE; /* According to MSDN, this is valid for a non-debug driver */ 06725 } 06726 06727 /* For performance optimization, devices created in FPUSETUP and FPUPRESERVE modes 06728 * have separate vtables. Simple functions where this doesn't matter like GetDirect3D 06729 * are not duplicated. 06730 06731 * Device created with DDSCL_FPUSETUP (d3d7 default) - device methods assume that FPU 06732 * has already been setup for optimal d3d operation. 06733 06734 * Device created with DDSCL_FPUPRESERVE - resets and restores FPU mode when necessary in 06735 * d3d calls (FPU may be in a mode non-suitable for d3d when the app calls d3d). Required 06736 * by Sacrifice (game). */ 06737 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_setup_vtbl = 06738 { 06739 /*** IUnknown Methods ***/ 06740 IDirect3DDeviceImpl_7_QueryInterface, 06741 IDirect3DDeviceImpl_7_AddRef, 06742 IDirect3DDeviceImpl_7_Release, 06743 /*** IDirect3DDevice7 ***/ 06744 IDirect3DDeviceImpl_7_GetCaps_FPUSetup, 06745 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup, 06746 IDirect3DDeviceImpl_7_BeginScene_FPUSetup, 06747 IDirect3DDeviceImpl_7_EndScene_FPUSetup, 06748 IDirect3DDeviceImpl_7_GetDirect3D, 06749 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup, 06750 IDirect3DDeviceImpl_7_GetRenderTarget, 06751 IDirect3DDeviceImpl_7_Clear_FPUSetup, 06752 IDirect3DDeviceImpl_7_SetTransform_FPUSetup, 06753 IDirect3DDeviceImpl_7_GetTransform_FPUSetup, 06754 IDirect3DDeviceImpl_7_SetViewport_FPUSetup, 06755 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup, 06756 IDirect3DDeviceImpl_7_GetViewport_FPUSetup, 06757 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup, 06758 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup, 06759 IDirect3DDeviceImpl_7_SetLight_FPUSetup, 06760 IDirect3DDeviceImpl_7_GetLight_FPUSetup, 06761 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup, 06762 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup, 06763 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup, 06764 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup, 06765 IDirect3DDeviceImpl_7_PreLoad_FPUSetup, 06766 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup, 06767 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup, 06768 IDirect3DDeviceImpl_7_SetClipStatus, 06769 IDirect3DDeviceImpl_7_GetClipStatus, 06770 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup, 06771 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup, 06772 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup, 06773 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup, 06774 IDirect3DDeviceImpl_7_ComputeSphereVisibility, 06775 IDirect3DDeviceImpl_7_GetTexture_FPUSetup, 06776 IDirect3DDeviceImpl_7_SetTexture_FPUSetup, 06777 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup, 06778 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup, 06779 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup, 06780 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup, 06781 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup, 06782 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup, 06783 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup, 06784 IDirect3DDeviceImpl_7_Load_FPUSetup, 06785 IDirect3DDeviceImpl_7_LightEnable_FPUSetup, 06786 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup, 06787 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup, 06788 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup, 06789 IDirect3DDeviceImpl_7_GetInfo 06790 }; 06791 06792 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_preserve_vtbl = 06793 { 06794 /*** IUnknown Methods ***/ 06795 IDirect3DDeviceImpl_7_QueryInterface, 06796 IDirect3DDeviceImpl_7_AddRef, 06797 IDirect3DDeviceImpl_7_Release, 06798 /*** IDirect3DDevice7 ***/ 06799 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve, 06800 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve, 06801 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve, 06802 IDirect3DDeviceImpl_7_EndScene_FPUPreserve, 06803 IDirect3DDeviceImpl_7_GetDirect3D, 06804 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve, 06805 IDirect3DDeviceImpl_7_GetRenderTarget, 06806 IDirect3DDeviceImpl_7_Clear_FPUPreserve, 06807 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve, 06808 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve, 06809 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve, 06810 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve, 06811 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve, 06812 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve, 06813 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve, 06814 IDirect3DDeviceImpl_7_SetLight_FPUPreserve, 06815 IDirect3DDeviceImpl_7_GetLight_FPUPreserve, 06816 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve, 06817 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve, 06818 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve, 06819 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve, 06820 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve, 06821 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve, 06822 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve, 06823 IDirect3DDeviceImpl_7_SetClipStatus, 06824 IDirect3DDeviceImpl_7_GetClipStatus, 06825 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve, 06826 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve, 06827 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve, 06828 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve, 06829 IDirect3DDeviceImpl_7_ComputeSphereVisibility, 06830 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve, 06831 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve, 06832 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve, 06833 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve, 06834 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve, 06835 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve, 06836 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve, 06837 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve, 06838 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve, 06839 IDirect3DDeviceImpl_7_Load_FPUPreserve, 06840 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve, 06841 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve, 06842 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve, 06843 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve, 06844 IDirect3DDeviceImpl_7_GetInfo 06845 }; 06846 06847 static const struct IDirect3DDevice3Vtbl d3d_device3_vtbl = 06848 { 06849 /*** IUnknown Methods ***/ 06850 IDirect3DDeviceImpl_3_QueryInterface, 06851 IDirect3DDeviceImpl_3_AddRef, 06852 IDirect3DDeviceImpl_3_Release, 06853 /*** IDirect3DDevice3 ***/ 06854 IDirect3DDeviceImpl_3_GetCaps, 06855 IDirect3DDeviceImpl_3_GetStats, 06856 IDirect3DDeviceImpl_3_AddViewport, 06857 IDirect3DDeviceImpl_3_DeleteViewport, 06858 IDirect3DDeviceImpl_3_NextViewport, 06859 IDirect3DDeviceImpl_3_EnumTextureFormats, 06860 IDirect3DDeviceImpl_3_BeginScene, 06861 IDirect3DDeviceImpl_3_EndScene, 06862 IDirect3DDeviceImpl_3_GetDirect3D, 06863 IDirect3DDeviceImpl_3_SetCurrentViewport, 06864 IDirect3DDeviceImpl_3_GetCurrentViewport, 06865 IDirect3DDeviceImpl_3_SetRenderTarget, 06866 IDirect3DDeviceImpl_3_GetRenderTarget, 06867 IDirect3DDeviceImpl_3_Begin, 06868 IDirect3DDeviceImpl_3_BeginIndexed, 06869 IDirect3DDeviceImpl_3_Vertex, 06870 IDirect3DDeviceImpl_3_Index, 06871 IDirect3DDeviceImpl_3_End, 06872 IDirect3DDeviceImpl_3_GetRenderState, 06873 IDirect3DDeviceImpl_3_SetRenderState, 06874 IDirect3DDeviceImpl_3_GetLightState, 06875 IDirect3DDeviceImpl_3_SetLightState, 06876 IDirect3DDeviceImpl_3_SetTransform, 06877 IDirect3DDeviceImpl_3_GetTransform, 06878 IDirect3DDeviceImpl_3_MultiplyTransform, 06879 IDirect3DDeviceImpl_3_DrawPrimitive, 06880 IDirect3DDeviceImpl_3_DrawIndexedPrimitive, 06881 IDirect3DDeviceImpl_3_SetClipStatus, 06882 IDirect3DDeviceImpl_3_GetClipStatus, 06883 IDirect3DDeviceImpl_3_DrawPrimitiveStrided, 06884 IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided, 06885 IDirect3DDeviceImpl_3_DrawPrimitiveVB, 06886 IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB, 06887 IDirect3DDeviceImpl_3_ComputeSphereVisibility, 06888 IDirect3DDeviceImpl_3_GetTexture, 06889 IDirect3DDeviceImpl_3_SetTexture, 06890 IDirect3DDeviceImpl_3_GetTextureStageState, 06891 IDirect3DDeviceImpl_3_SetTextureStageState, 06892 IDirect3DDeviceImpl_3_ValidateDevice 06893 }; 06894 06895 static const struct IDirect3DDevice2Vtbl d3d_device2_vtbl = 06896 { 06897 /*** IUnknown Methods ***/ 06898 IDirect3DDeviceImpl_2_QueryInterface, 06899 IDirect3DDeviceImpl_2_AddRef, 06900 IDirect3DDeviceImpl_2_Release, 06901 /*** IDirect3DDevice2 ***/ 06902 IDirect3DDeviceImpl_2_GetCaps, 06903 IDirect3DDeviceImpl_2_SwapTextureHandles, 06904 IDirect3DDeviceImpl_2_GetStats, 06905 IDirect3DDeviceImpl_2_AddViewport, 06906 IDirect3DDeviceImpl_2_DeleteViewport, 06907 IDirect3DDeviceImpl_2_NextViewport, 06908 IDirect3DDeviceImpl_2_EnumTextureFormats, 06909 IDirect3DDeviceImpl_2_BeginScene, 06910 IDirect3DDeviceImpl_2_EndScene, 06911 IDirect3DDeviceImpl_2_GetDirect3D, 06912 IDirect3DDeviceImpl_2_SetCurrentViewport, 06913 IDirect3DDeviceImpl_2_GetCurrentViewport, 06914 IDirect3DDeviceImpl_2_SetRenderTarget, 06915 IDirect3DDeviceImpl_2_GetRenderTarget, 06916 IDirect3DDeviceImpl_2_Begin, 06917 IDirect3DDeviceImpl_2_BeginIndexed, 06918 IDirect3DDeviceImpl_2_Vertex, 06919 IDirect3DDeviceImpl_2_Index, 06920 IDirect3DDeviceImpl_2_End, 06921 IDirect3DDeviceImpl_2_GetRenderState, 06922 IDirect3DDeviceImpl_2_SetRenderState, 06923 IDirect3DDeviceImpl_2_GetLightState, 06924 IDirect3DDeviceImpl_2_SetLightState, 06925 IDirect3DDeviceImpl_2_SetTransform, 06926 IDirect3DDeviceImpl_2_GetTransform, 06927 IDirect3DDeviceImpl_2_MultiplyTransform, 06928 IDirect3DDeviceImpl_2_DrawPrimitive, 06929 IDirect3DDeviceImpl_2_DrawIndexedPrimitive, 06930 IDirect3DDeviceImpl_2_SetClipStatus, 06931 IDirect3DDeviceImpl_2_GetClipStatus 06932 }; 06933 06934 static const struct IDirect3DDeviceVtbl d3d_device1_vtbl = 06935 { 06936 /*** IUnknown Methods ***/ 06937 IDirect3DDeviceImpl_1_QueryInterface, 06938 IDirect3DDeviceImpl_1_AddRef, 06939 IDirect3DDeviceImpl_1_Release, 06940 /*** IDirect3DDevice1 ***/ 06941 IDirect3DDeviceImpl_1_Initialize, 06942 IDirect3DDeviceImpl_1_GetCaps, 06943 IDirect3DDeviceImpl_1_SwapTextureHandles, 06944 IDirect3DDeviceImpl_1_CreateExecuteBuffer, 06945 IDirect3DDeviceImpl_1_GetStats, 06946 IDirect3DDeviceImpl_1_Execute, 06947 IDirect3DDeviceImpl_1_AddViewport, 06948 IDirect3DDeviceImpl_1_DeleteViewport, 06949 IDirect3DDeviceImpl_1_NextViewport, 06950 IDirect3DDeviceImpl_1_Pick, 06951 IDirect3DDeviceImpl_1_GetPickRecords, 06952 IDirect3DDeviceImpl_1_EnumTextureFormats, 06953 IDirect3DDeviceImpl_1_CreateMatrix, 06954 IDirect3DDeviceImpl_1_SetMatrix, 06955 IDirect3DDeviceImpl_1_GetMatrix, 06956 IDirect3DDeviceImpl_1_DeleteMatrix, 06957 IDirect3DDeviceImpl_1_BeginScene, 06958 IDirect3DDeviceImpl_1_EndScene, 06959 IDirect3DDeviceImpl_1_GetDirect3D 06960 }; 06961 06962 IDirect3DDeviceImpl *unsafe_impl_from_IDirect3DDevice7(IDirect3DDevice7 *iface) 06963 { 06964 if (!iface) return NULL; 06965 assert((iface->lpVtbl == &d3d_device7_fpu_preserve_vtbl) || (iface->lpVtbl == &d3d_device7_fpu_setup_vtbl)); 06966 return CONTAINING_RECORD(iface, IDirect3DDeviceImpl, IDirect3DDevice7_iface); 06967 } 06968 06969 IDirect3DDeviceImpl *unsafe_impl_from_IDirect3DDevice3(IDirect3DDevice3 *iface) 06970 { 06971 if (!iface) return NULL; 06972 assert(iface->lpVtbl == &d3d_device3_vtbl); 06973 return CONTAINING_RECORD(iface, IDirect3DDeviceImpl, IDirect3DDevice3_iface); 06974 } 06975 06976 IDirect3DDeviceImpl *unsafe_impl_from_IDirect3DDevice2(IDirect3DDevice2 *iface) 06977 { 06978 if (!iface) return NULL; 06979 assert(iface->lpVtbl == &d3d_device2_vtbl); 06980 return CONTAINING_RECORD(iface, IDirect3DDeviceImpl, IDirect3DDevice2_iface); 06981 } 06982 06983 IDirect3DDeviceImpl *unsafe_impl_from_IDirect3DDevice(IDirect3DDevice *iface) 06984 { 06985 if (!iface) return NULL; 06986 assert(iface->lpVtbl == &d3d_device1_vtbl); 06987 return CONTAINING_RECORD(iface, IDirect3DDeviceImpl, IDirect3DDevice_iface); 06988 } 06989 06990 /***************************************************************************** 06991 * IDirect3DDeviceImpl_UpdateDepthStencil 06992 * 06993 * Checks the current render target for attached depth stencils and sets the 06994 * WineD3D depth stencil accordingly. 06995 * 06996 * Returns: 06997 * The depth stencil state to set if creating the device 06998 * 06999 *****************************************************************************/ 07000 enum wined3d_depth_buffer_type IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DDeviceImpl *This) 07001 { 07002 IDirectDrawSurface7 *depthStencil = NULL; 07003 IDirectDrawSurfaceImpl *dsi; 07004 static DDSCAPS2 depthcaps = { DDSCAPS_ZBUFFER, 0, 0, {0} }; 07005 07006 IDirectDrawSurface7_GetAttachedSurface(&This->target->IDirectDrawSurface7_iface, &depthcaps, &depthStencil); 07007 if(!depthStencil) 07008 { 07009 TRACE("Setting wined3d depth stencil to NULL\n"); 07010 wined3d_device_set_depth_stencil(This->wined3d_device, NULL); 07011 return WINED3D_ZB_FALSE; 07012 } 07013 07014 dsi = impl_from_IDirectDrawSurface7(depthStencil); 07015 TRACE("Setting wined3d depth stencil to %p (wined3d %p)\n", dsi, dsi->wined3d_surface); 07016 wined3d_device_set_depth_stencil(This->wined3d_device, dsi->wined3d_surface); 07017 07018 IDirectDrawSurface7_Release(depthStencil); 07019 return WINED3D_ZB_TRUE; 07020 } 07021 07022 HRESULT d3d_device_init(IDirect3DDeviceImpl *device, IDirectDrawImpl *ddraw, IDirectDrawSurfaceImpl *target) 07023 { 07024 static const D3DMATRIX ident = 07025 { 07026 1.0f, 0.0f, 0.0f, 0.0f, 07027 0.0f, 1.0f, 0.0f, 0.0f, 07028 0.0f, 0.0f, 1.0f, 0.0f, 07029 0.0f, 0.0f, 0.0f, 1.0f, 07030 }; 07031 HRESULT hr; 07032 07033 if (ddraw->cooperative_level & DDSCL_FPUPRESERVE) 07034 device->IDirect3DDevice7_iface.lpVtbl = &d3d_device7_fpu_preserve_vtbl; 07035 else 07036 device->IDirect3DDevice7_iface.lpVtbl = &d3d_device7_fpu_setup_vtbl; 07037 07038 device->IDirect3DDevice3_iface.lpVtbl = &d3d_device3_vtbl; 07039 device->IDirect3DDevice2_iface.lpVtbl = &d3d_device2_vtbl; 07040 device->IDirect3DDevice_iface.lpVtbl = &d3d_device1_vtbl; 07041 device->ref = 1; 07042 device->ddraw = ddraw; 07043 device->target = target; 07044 list_init(&device->viewport_list); 07045 07046 if (!ddraw_handle_table_init(&device->handle_table, 64)) 07047 { 07048 ERR("Failed to initialize handle table.\n"); 07049 return DDERR_OUTOFMEMORY; 07050 } 07051 07052 device->legacyTextureBlending = FALSE; 07053 device->legacy_projection = ident; 07054 device->legacy_clipspace = ident; 07055 07056 /* Create an index buffer, it's needed for indexed drawing */ 07057 hr = wined3d_buffer_create_ib(ddraw->wined3d_device, 0x40000 /* Length. Don't know how long it should be */, 07058 WINED3DUSAGE_DYNAMIC /* Usage */, WINED3D_POOL_DEFAULT, NULL, 07059 &ddraw_null_wined3d_parent_ops, &device->indexbuffer); 07060 if (FAILED(hr)) 07061 { 07062 ERR("Failed to create an index buffer, hr %#x.\n", hr); 07063 ddraw_handle_table_destroy(&device->handle_table); 07064 return hr; 07065 } 07066 07067 /* This is for convenience. */ 07068 device->wined3d_device = ddraw->wined3d_device; 07069 wined3d_device_incref(ddraw->wined3d_device); 07070 07071 /* Render to the back buffer */ 07072 hr = wined3d_device_set_render_target(ddraw->wined3d_device, 0, target->wined3d_surface, TRUE); 07073 if (FAILED(hr)) 07074 { 07075 ERR("Failed to set render target, hr %#x.\n", hr); 07076 wined3d_buffer_decref(device->indexbuffer); 07077 ddraw_handle_table_destroy(&device->handle_table); 07078 return hr; 07079 } 07080 07081 /* FIXME: This is broken. The target AddRef() makes some sense, because 07082 * we store a pointer during initialization, but then that's also where 07083 * the AddRef() should be. We don't store ddraw->d3d_target anywhere. */ 07084 /* AddRef the render target. Also AddRef the render target from ddraw, 07085 * because if it is released before the app releases the D3D device, the 07086 * D3D capabilities of wined3d will be uninitialized, which has bad effects. 07087 * 07088 * In most cases, those surfaces are the same anyway, but this will simply 07089 * add another ref which is released when the device is destroyed. */ 07090 IDirectDrawSurface7_AddRef(&target->IDirectDrawSurface7_iface); 07091 07092 ddraw->d3ddevice = device; 07093 07094 wined3d_device_set_render_state(ddraw->wined3d_device, WINED3D_RS_ZENABLE, 07095 IDirect3DDeviceImpl_UpdateDepthStencil(device)); 07096 07097 return D3D_OK; 07098 } Generated on Sat May 26 2012 04:19:56 for ReactOS by
1.7.6.1
|