#include "config.h" #include #include #include #include #include #include "d3d.h" #include "ddraw.h" #include "winerror.h" #include "ddraw_private.h" #include "mesa_private.h" #include "debugtools.h" DEFAULT_DEBUG_CHANNEL(ddraw); /******************************************************************************* * IDirect3D */ static HRESULT WINAPI MESA_IDirect3DImpl_QueryInterface( LPDIRECT3D iface,REFIID refiid,LPVOID *obj ) { ICOM_THIS(IDirect3DImpl,iface); /* FIXME: Not sure if this is correct */ TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj); if (( IsEqualGUID( &IID_IDirectDraw, refiid ) ) || ( IsEqualGUID (&IID_IDirectDraw2, refiid ) ) || ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) { *obj = This->ddraw; IDirect3D_AddRef(iface); TRACE(" Creating IDirectDrawX interface (%p)\n", *obj); return S_OK; } if (( IsEqualGUID( &IID_IDirect3D, refiid ) ) || ( IsEqualGUID( &IID_IUnknown, refiid ) ) ) { *obj = This; IDirect3D_AddRef(iface); TRACE(" Creating IDirect3D interface (%p)\n", *obj); return S_OK; } if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) { IDirect3D2Impl* d3d; d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d)); d3d->ref = 1; d3d->ddraw = This->ddraw; IDirect3D_AddRef(iface); ICOM_VTBL(d3d) = &mesa_d3d2vt; *obj = d3d; TRACE(" Creating IDirect3D2 interface (%p)\n", *obj); return S_OK; } FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid)); return OLE_E_ENUM_NOMORE; } static ULONG WINAPI MESA_IDirect3DImpl_Release(LPDIRECT3D iface) { ICOM_THIS(IDirect3DImpl,iface); TRACE("(%p)->() decrementing from %lu.\n", This, This->ref ); if (!--(This->ref)) { IDirectDraw2_Release((IDirectDraw2*)This->ddraw); HeapFree(GetProcessHeap(),0,This); return S_OK; } return This->ref; } static HRESULT WINAPI MESA_IDirect3DImpl_EnumDevices( LPDIRECT3D iface, LPD3DENUMDEVICESCALLBACK cb, LPVOID context ) { ICOM_THIS(IDirect3DImpl,iface); FIXME("(%p)->(%p,%p),stub!\n",This,cb,context); /* Call functions defined in d3ddevices.c */ if (!d3d_OpenGL_dx3(cb, context)) return D3D_OK; return D3D_OK; } static HRESULT WINAPI MESA_IDirect3DImpl_CreateLight( LPDIRECT3D iface, LPDIRECT3DLIGHT *lplight, IUnknown *lpunk ) { ICOM_THIS(IDirect3DImpl,iface); TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk); /* Call the creation function that is located in d3dlight.c */ *lplight = d3dlight_create_dx3(This); return D3D_OK; } static HRESULT WINAPI MESA_IDirect3DImpl_CreateMaterial( LPDIRECT3D iface, LPDIRECT3DMATERIAL *lpmaterial, IUnknown *lpunk ) { ICOM_THIS(IDirect3DImpl,iface); TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk); /* Call the creation function that is located in d3dviewport.c */ *lpmaterial = d3dmaterial_create(This); return D3D_OK; } static HRESULT WINAPI MESA_IDirect3DImpl_CreateViewport( LPDIRECT3D iface, LPDIRECT3DVIEWPORT *lpviewport, IUnknown *lpunk ) { ICOM_THIS(IDirect3DImpl,iface); TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk); /* Call the creation function that is located in d3dviewport.c */ *lpviewport = d3dviewport_create(This); return D3D_OK; } static HRESULT WINAPI MESA_IDirect3DImpl_FindDevice( LPDIRECT3D iface, LPD3DFINDDEVICESEARCH lpfinddevsrc, LPD3DFINDDEVICERESULT lpfinddevrst) { ICOM_THIS(IDirect3DImpl,iface); FIXME("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst); return D3D_OK; } ICOM_VTABLE(IDirect3D) mesa_d3dvt = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE MESA_IDirect3DImpl_QueryInterface, IDirect3DImpl_AddRef, MESA_IDirect3DImpl_Release, IDirect3DImpl_Initialize, MESA_IDirect3DImpl_EnumDevices, MESA_IDirect3DImpl_CreateLight, MESA_IDirect3DImpl_CreateMaterial, MESA_IDirect3DImpl_CreateViewport, MESA_IDirect3DImpl_FindDevice }; /******************************************************************************* * IDirect3D2 */ static HRESULT WINAPI MESA_IDirect3D2Impl_QueryInterface( LPDIRECT3D2 iface,REFIID refiid,LPVOID *obj) { ICOM_THIS(IDirect3D2Impl,iface); /* FIXME: Not sure if this is correct */ TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj); if ( ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) || ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) || ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) { *obj = This->ddraw; IDirect3D2_AddRef(iface); TRACE(" Creating IDirectDrawX interface (%p)\n", *obj); return S_OK; } if ( ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) || ( IsEqualGUID( &IID_IUnknown, refiid ) ) ) { *obj = This; IDirect3D2_AddRef(iface); TRACE(" Creating IDirect3D2 interface (%p)\n", *obj); return S_OK; } if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) { IDirect3DImpl* d3d; d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d)); d3d->ref = 1; d3d->ddraw = This->ddraw; IDirect3D2_AddRef(iface); ICOM_VTBL(d3d) = &mesa_d3dvt; *obj = d3d; TRACE(" Creating IDirect3D interface (%p)\n", *obj); return S_OK; } FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid)); return OLE_E_ENUM_NOMORE; } static ULONG WINAPI MESA_IDirect3D2Impl_Release(LPDIRECT3D2 iface) { ICOM_THIS(IDirect3D2Impl,iface); TRACE("(%p)->() decrementing from %lu.\n", This, This->ref ); if (!--(This->ref)) { IDirectDraw2_Release((IDirectDraw2*)This->ddraw); HeapFree(GetProcessHeap(),0,This); return S_OK; } return This->ref; } static HRESULT WINAPI MESA_IDirect3D2Impl_EnumDevices( LPDIRECT3D2 iface,LPD3DENUMDEVICESCALLBACK cb, LPVOID context ) { ICOM_THIS(IDirect3D2Impl,iface); FIXME("(%p)->(%p,%p),stub!\n",This,cb,context); /* Call functions defined in d3ddevices.c */ if (!d3d_OpenGL(cb, context)) return D3D_OK; return D3D_OK; } static HRESULT WINAPI MESA_IDirect3D2Impl_CreateLight( LPDIRECT3D2 iface, LPDIRECT3DLIGHT *lplight, IUnknown *lpunk ) { ICOM_THIS(IDirect3D2Impl,iface); TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk); /* Call the creation function that is located in d3dlight.c */ *lplight = d3dlight_create(This); return D3D_OK; } static HRESULT WINAPI MESA_IDirect3D2Impl_CreateMaterial( LPDIRECT3D2 iface, LPDIRECT3DMATERIAL2 *lpmaterial, IUnknown *lpunk ) { ICOM_THIS(IDirect3D2Impl,iface); TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk); /* Call the creation function that is located in d3dviewport.c */ *lpmaterial = d3dmaterial2_create(This); return D3D_OK; } static HRESULT WINAPI MESA_IDirect3D2Impl_CreateViewport( LPDIRECT3D2 iface, LPDIRECT3DVIEWPORT2 *lpviewport, IUnknown *lpunk ) { ICOM_THIS(IDirect3D2Impl,iface); TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk); /* Call the creation function that is located in d3dviewport.c */ *lpviewport = d3dviewport2_create(This); return D3D_OK; } static HRESULT WINAPI MESA_IDirect3D2Impl_FindDevice( LPDIRECT3D2 iface, LPD3DFINDDEVICESEARCH lpfinddevsrc, LPD3DFINDDEVICERESULT lpfinddevrst) { ICOM_THIS(IDirect3D2Impl,iface); FIXME("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst); return D3D_OK; } static HRESULT WINAPI MESA_IDirect3D2Impl_CreateDevice( LPDIRECT3D2 iface, REFCLSID rguid, LPDIRECTDRAWSURFACE surface, LPDIRECT3DDEVICE2 *device) { ICOM_THIS(IDirect3D2Impl,iface); FIXME("(%p)->(%s,%p,%p): stub\n",This,debugstr_guid(rguid),surface,device); if (is_OpenGL(rguid, (IDirectDrawSurfaceImpl*)surface, (IDirect3DDevice2Impl**)device, This)) { IDirect3D2_AddRef(iface); return D3D_OK; } return DDERR_INVALIDPARAMS; } ICOM_VTABLE(IDirect3D2) mesa_d3d2vt = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE MESA_IDirect3D2Impl_QueryInterface, IDirect3D2Impl_AddRef, MESA_IDirect3D2Impl_Release, MESA_IDirect3D2Impl_EnumDevices, MESA_IDirect3D2Impl_CreateLight, MESA_IDirect3D2Impl_CreateMaterial, MESA_IDirect3D2Impl_CreateViewport, MESA_IDirect3D2Impl_FindDevice, MESA_IDirect3D2Impl_CreateDevice }; static HRESULT WINAPI MESA_IDirect3D3Impl_CreateVertexBuffer( LPDIRECT3D3 iface, LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc, LPDIRECT3DVERTEXBUFFER* lplpD3DVertBuf, DWORD dwFlags, LPUNKNOWN lpUnk) { FIXME(":stub\n"); return D3D_OK; } static HRESULT WINAPI MESA_IDirect3D3Impl_EnumZBufferFormats( LPDIRECT3D3 iface, REFCLSID riidDevice, LPD3DENUMPIXELFORMATSCALLBACK lpEnumCallback, LPVOID lpContext) { FIXME(":stub\n"); return DDERR_NOZBUFFERHW; /* Pretend we don't have valid HW */ } static HRESULT WINAPI MESA_IDirect3D3Impl_EvictManagedTextures( LPDIRECT3D3 iface) { FIXME(":stub\n"); return D3D_OK; } #if !defined(__STRICT_ANSI__) && defined(__GNUC__) # define XCAST(fun) (typeof(mesa_d3d3vt.fun)) #else # define XCAST(fun) (void*) #endif ICOM_VTABLE(IDirect3D3) mesa_d3d3vt = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE XCAST(QueryInterface)MESA_IDirect3D2Impl_QueryInterface, XCAST(AddRef)IDirect3D2Impl_AddRef, XCAST(Release)MESA_IDirect3D2Impl_Release, XCAST(EnumDevices)MESA_IDirect3D2Impl_EnumDevices, XCAST(CreateLight)MESA_IDirect3D2Impl_CreateLight, XCAST(CreateMaterial)MESA_IDirect3D2Impl_CreateMaterial, XCAST(CreateViewport)MESA_IDirect3D2Impl_CreateViewport, XCAST(FindDevice)MESA_IDirect3D2Impl_FindDevice, XCAST(CreateDevice)MESA_IDirect3D2Impl_CreateDevice, XCAST(CreateVertexBuffer)MESA_IDirect3D3Impl_CreateVertexBuffer, XCAST(EnumZBufferFormats)MESA_IDirect3D3Impl_EnumZBufferFormats, XCAST(EvictManagedTextures)MESA_IDirect3D3Impl_EvictManagedTextures }; #if !defined(__STRICT_ANSI__) && defined(__GNUC__) #undef XCAST #endif HRESULT create_direct3d(LPVOID *obj,IDirectDrawImpl* ddraw) { IDirect3DImpl* d3d; d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d)); d3d->ref = 1; d3d->ddraw = (IDirectDrawImpl *) ddraw; d3d->private = NULL; /* unused for now */ IDirectDraw_AddRef((LPDIRECTDRAW)ddraw); ICOM_VTBL(d3d) = &mesa_d3dvt; *obj = (LPUNKNOWN)d3d; TRACE(" Created IDirect3D interface (%p)\n", *obj); return S_OK; } HRESULT create_direct3d2(LPVOID *obj,IDirectDrawImpl* ddraw) { IDirect3D2Impl* d3d; d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d)); d3d->ref = 1; d3d->ddraw = (IDirectDrawImpl *) ddraw; d3d->private = NULL; /* unused for now */ IDirectDraw_AddRef((LPDIRECTDRAW)ddraw); ICOM_VTBL(d3d) = &mesa_d3d2vt; *obj = (LPUNKNOWN)d3d; TRACE(" Creating IDirect3D2 interface (%p)\n", *obj); return S_OK; } HRESULT create_direct3d3(LPVOID *obj,IDirectDrawImpl* ddraw) { IDirect3D3Impl* d3d; d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d)); d3d->ref = 1; d3d->ddraw = (IDirectDrawImpl *) ddraw; d3d->private = NULL; /* unused for now */ IDirectDraw_AddRef((LPDIRECTDRAW)ddraw); ICOM_VTBL(d3d) = &mesa_d3d3vt; *obj = (LPUNKNOWN)d3d; TRACE(" Creating IDirect3D3 interface (%p)\n", *obj); return S_OK; }