Fixed header dependencies to be fully compatible with the Windows
[wine/multimedia.git] / dlls / ddraw / direct3d / mesa.c
blob77ef7fbc5dd7adccf86022f11c4cb8804637cf19
1 /*
2 * Copyright 2000 Marcus Meissner
3 * Copyright 2000 Peter Hunnisett
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include "config.h"
22 #include <assert.h>
23 #ifdef HAVE_UNISTD_H
24 # include <unistd.h>
25 #endif
26 #include <fcntl.h>
27 #include <string.h>
28 #include <stdarg.h>
29 #include <stdio.h>
31 #define NONAMELESSUNION
32 #define NONAMELESSSTRUCT
33 #include "windef.h"
34 #include "winbase.h"
35 #include "wingdi.h"
36 #include "d3d.h"
37 #include "ddraw.h"
38 #include "winerror.h"
40 #include "ddraw_private.h"
41 #include "d3d_private.h"
42 #include "mesa_private.h"
43 #include "main.h"
45 #include "wine/debug.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
49 HRESULT WINAPI
50 GL_IDirect3DImpl_1_EnumDevices(LPDIRECT3D iface,
51 LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback,
52 LPVOID lpUserArg)
54 ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D, iface);
55 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpEnumDevicesCallback, lpUserArg);
57 /* Call functions defined in d3ddevices.c */
58 if (d3ddevice_enumerate(lpEnumDevicesCallback, lpUserArg, 1) != D3DENUMRET_OK)
59 return D3D_OK;
61 return D3D_OK;
64 HRESULT WINAPI
65 GL_IDirect3DImpl_3_2T_EnumDevices(LPDIRECT3D3 iface,
66 LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback,
67 LPVOID lpUserArg)
69 ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
70 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpEnumDevicesCallback, lpUserArg);
72 /* Call functions defined in d3ddevices.c */
73 if (d3ddevice_enumerate(lpEnumDevicesCallback, lpUserArg, 3) != D3DENUMRET_OK)
74 return D3D_OK;
76 return D3D_OK;
79 HRESULT WINAPI
80 GL_IDirect3DImpl_3_2T_1T_CreateLight(LPDIRECT3D3 iface,
81 LPDIRECT3DLIGHT* lplpDirect3DLight,
82 IUnknown* pUnkOuter)
84 ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
85 IDirect3DGLImpl *glThis = (IDirect3DGLImpl *) This;
86 int fl;
87 IDirect3DLightImpl *d3dlimpl;
88 HRESULT ret_value;
90 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lplpDirect3DLight, pUnkOuter);
91 for (fl = 0; fl < MAX_LIGHTS; fl++) {
92 if ((glThis->free_lights & (0x01 << fl)) != 0) {
93 glThis->free_lights &= ~(0x01 << fl);
94 break;
97 if (fl == MAX_LIGHTS) {
98 return DDERR_INVALIDPARAMS; /* No way to say 'max lights reached' ... */
100 ret_value = d3dlight_create(&d3dlimpl, This, GL_LIGHT0 + fl);
101 *lplpDirect3DLight = ICOM_INTERFACE(d3dlimpl, IDirect3DLight);
103 return ret_value;
106 HRESULT WINAPI
107 GL_IDirect3DImpl_3_2T_1T_CreateMaterial(LPDIRECT3D3 iface,
108 LPDIRECT3DMATERIAL3* lplpDirect3DMaterial3,
109 IUnknown* pUnkOuter)
111 IDirect3DMaterialImpl *D3Dmat_impl;
112 HRESULT ret_value;
113 ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
115 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lplpDirect3DMaterial3, pUnkOuter);
116 ret_value = d3dmaterial_create(&D3Dmat_impl, This);
118 *lplpDirect3DMaterial3 = ICOM_INTERFACE(D3Dmat_impl, IDirect3DMaterial3);
120 return ret_value;
123 HRESULT WINAPI
124 GL_IDirect3DImpl_3_2T_1T_CreateViewport(LPDIRECT3D3 iface,
125 LPDIRECT3DVIEWPORT3* lplpD3DViewport3,
126 IUnknown* pUnkOuter)
128 IDirect3DViewportImpl *D3Dvp_impl;
129 HRESULT ret_value;
130 ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
132 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lplpD3DViewport3, pUnkOuter);
133 ret_value = d3dviewport_create(&D3Dvp_impl, This);
135 *lplpD3DViewport3 = ICOM_INTERFACE(D3Dvp_impl, IDirect3DViewport3);
137 return ret_value;
140 static HRESULT
141 create_device_helper(IDirectDrawImpl *This,
142 REFCLSID iid,
143 IDirectDrawSurfaceImpl *lpDDS,
144 void **obj,
145 int version) {
146 IDirect3DDeviceImpl *lpd3ddev;
147 HRESULT ret_value;
149 ret_value = d3ddevice_create(&lpd3ddev, This, lpDDS);
150 if (FAILED(ret_value)) return ret_value;
152 if ((iid == NULL) ||
153 (IsEqualGUID(&IID_D3DDEVICE_OpenGL, iid)) ||
154 (IsEqualGUID(&IID_IDirect3DHALDevice, iid)) ||
155 (IsEqualGUID(&IID_IDirect3DTnLHalDevice, iid)) ||
156 (IsEqualGUID(&IID_IDirect3DRefDevice, iid))) {
157 switch (version) {
158 case 1:
159 *obj = ICOM_INTERFACE(lpd3ddev, IDirect3DDevice);
160 TRACE(" returning OpenGL D3DDevice %p.\n", *obj);
161 return D3D_OK;
163 case 2:
164 *obj = ICOM_INTERFACE(lpd3ddev, IDirect3DDevice2);
165 TRACE(" returning OpenGL D3DDevice2 %p.\n", *obj);
166 return D3D_OK;
168 case 3:
169 *obj = ICOM_INTERFACE(lpd3ddev, IDirect3DDevice3);
170 TRACE(" returning OpenGL D3DDevice3 %p.\n", *obj);
171 return D3D_OK;
173 case 7:
174 *obj = ICOM_INTERFACE(lpd3ddev, IDirect3DDevice7);
175 TRACE(" returning OpenGL D3DDevice7 %p.\n", *obj);
176 return D3D_OK;
180 *obj = NULL;
181 ERR(" Interface unknown when creating D3DDevice (%s)\n", debugstr_guid(iid));
182 IDirect3DDevice7_Release(ICOM_INTERFACE(lpd3ddev, IDirect3DDevice7));
183 return DDERR_INVALIDPARAMS;
187 HRESULT WINAPI
188 GL_IDirect3DImpl_2_CreateDevice(LPDIRECT3D2 iface,
189 REFCLSID rclsid,
190 LPDIRECTDRAWSURFACE lpDDS,
191 LPDIRECT3DDEVICE2* lplpD3DDevice2)
193 ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D2, iface);
194 IDirectDrawSurfaceImpl *ddsurfaceimpl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface3, lpDDS);
195 TRACE("(%p/%p)->(%s,%p,%p)\n", This, iface, debugstr_guid(rclsid), lpDDS, lplpD3DDevice2);
196 return create_device_helper(This, rclsid, ddsurfaceimpl, (void **) lplpD3DDevice2, 2);
199 HRESULT WINAPI
200 GL_IDirect3DImpl_3_CreateDevice(LPDIRECT3D3 iface,
201 REFCLSID rclsid,
202 LPDIRECTDRAWSURFACE4 lpDDS,
203 LPDIRECT3DDEVICE3* lplpD3DDevice3,
204 LPUNKNOWN lpUnk)
206 ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
207 IDirectDrawSurfaceImpl *ddsurfaceimpl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, lpDDS);
208 TRACE("(%p/%p)->(%s,%p,%p)\n", This, iface, debugstr_guid(rclsid), lpDDS, lplpD3DDevice3);
209 return create_device_helper(This, rclsid, ddsurfaceimpl, (void **) lplpD3DDevice3, 3);
212 HRESULT WINAPI
213 GL_IDirect3DImpl_3_2T_1T_FindDevice(LPDIRECT3D3 iface,
214 LPD3DFINDDEVICESEARCH lpD3DDFS,
215 LPD3DFINDDEVICERESULT lpD3DFDR)
217 ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface);
218 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DDFS, lpD3DFDR);
219 return d3ddevice_find(This, lpD3DDFS, lpD3DFDR);
222 HRESULT WINAPI
223 GL_IDirect3DImpl_7_3T_EnumZBufferFormats(LPDIRECT3D7 iface,
224 REFCLSID riidDevice,
225 LPD3DENUMPIXELFORMATSCALLBACK lpEnumCallback,
226 LPVOID lpContext)
228 ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface);
229 DDPIXELFORMAT pformat;
231 TRACE("(%p/%p)->(%s,%p,%p)\n", This, iface, debugstr_guid(riidDevice), lpEnumCallback, lpContext);
233 memset(&pformat, 0, sizeof(pformat));
234 pformat.dwSize = sizeof(DDPIXELFORMAT);
235 pformat.dwFourCC = 0;
236 TRACE("Enumerating dummy ZBuffer format (16 bits)\n");
237 pformat.dwFlags = DDPF_ZBUFFER;
238 pformat.u1.dwZBufferBitDepth = 16;
239 pformat.u3.dwZBitMask = 0x0000FFFF;
240 pformat.u5.dwRGBZBitMask = 0x0000FFFF;
242 /* Whatever the return value, stop here.. */
243 lpEnumCallback(&pformat, lpContext);
245 return D3D_OK;
248 HRESULT WINAPI
249 GL_IDirect3DImpl_7_EnumDevices(LPDIRECT3D7 iface,
250 LPD3DENUMDEVICESCALLBACK7 lpEnumDevicesCallback,
251 LPVOID lpUserArg)
253 ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface);
254 TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpEnumDevicesCallback, lpUserArg);
256 if (d3ddevice_enumerate7(lpEnumDevicesCallback, lpUserArg) != D3DENUMRET_OK)
257 return D3D_OK;
259 return D3D_OK;
262 HRESULT WINAPI
263 GL_IDirect3DImpl_7_CreateDevice(LPDIRECT3D7 iface,
264 REFCLSID rclsid,
265 LPDIRECTDRAWSURFACE7 lpDDS,
266 LPDIRECT3DDEVICE7* lplpD3DDevice)
268 ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface);
269 IDirectDrawSurfaceImpl *ddsurfaceimpl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, lpDDS);
270 TRACE("(%p/%p)->(%s,%p,%p)\n", This, iface, debugstr_guid(rclsid), lpDDS, lplpD3DDevice);
271 return create_device_helper(This, rclsid, ddsurfaceimpl, (void **) lplpD3DDevice, 7);
274 HRESULT WINAPI
275 GL_IDirect3DImpl_7_3T_CreateVertexBuffer(LPDIRECT3D7 iface,
276 LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc,
277 LPDIRECT3DVERTEXBUFFER7* lplpD3DVertBuf,
278 DWORD dwFlags)
280 ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface);
281 IDirect3DVertexBufferImpl *vbimpl;
282 HRESULT res;
284 TRACE("(%p/%p)->(%p,%p,%08lx)\n", This, iface, lpD3DVertBufDesc, lplpD3DVertBuf, dwFlags);
286 res = d3dvertexbuffer_create(&vbimpl, This, lpD3DVertBufDesc, dwFlags);
288 *lplpD3DVertBuf = ICOM_INTERFACE(vbimpl, IDirect3DVertexBuffer7);
290 return res;
293 static void light_released(IDirectDrawImpl *This, GLenum light_num)
295 IDirect3DGLImpl *glThis = (IDirect3DGLImpl *) This;
296 glThis->free_lights |= (light_num - GL_LIGHT0);
299 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
300 # define XCAST(fun) (typeof(VTABLE_IDirect3D7.fun))
301 #else
302 # define XCAST(fun) (void*)
303 #endif
305 ICOM_VTABLE(IDirect3D7) VTABLE_IDirect3D7 =
307 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
308 XCAST(QueryInterface) Thunk_IDirect3DImpl_7_QueryInterface,
309 XCAST(AddRef) Thunk_IDirect3DImpl_7_AddRef,
310 XCAST(Release) Thunk_IDirect3DImpl_7_Release,
311 XCAST(EnumDevices) GL_IDirect3DImpl_7_EnumDevices,
312 XCAST(CreateDevice) GL_IDirect3DImpl_7_CreateDevice,
313 XCAST(CreateVertexBuffer) GL_IDirect3DImpl_7_3T_CreateVertexBuffer,
314 XCAST(EnumZBufferFormats) GL_IDirect3DImpl_7_3T_EnumZBufferFormats,
315 XCAST(EvictManagedTextures) Main_IDirect3DImpl_7_3T_EvictManagedTextures,
318 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
319 #undef XCAST
320 #endif
323 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
324 # define XCAST(fun) (typeof(VTABLE_IDirect3D3.fun))
325 #else
326 # define XCAST(fun) (void*)
327 #endif
329 ICOM_VTABLE(IDirect3D3) VTABLE_IDirect3D3 =
331 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
332 XCAST(QueryInterface) Thunk_IDirect3DImpl_3_QueryInterface,
333 XCAST(AddRef) Thunk_IDirect3DImpl_3_AddRef,
334 XCAST(Release) Thunk_IDirect3DImpl_3_Release,
335 XCAST(EnumDevices) GL_IDirect3DImpl_3_2T_EnumDevices,
336 XCAST(CreateLight) GL_IDirect3DImpl_3_2T_1T_CreateLight,
337 XCAST(CreateMaterial) GL_IDirect3DImpl_3_2T_1T_CreateMaterial,
338 XCAST(CreateViewport) GL_IDirect3DImpl_3_2T_1T_CreateViewport,
339 XCAST(FindDevice) GL_IDirect3DImpl_3_2T_1T_FindDevice,
340 XCAST(CreateDevice) GL_IDirect3DImpl_3_CreateDevice,
341 XCAST(CreateVertexBuffer) Thunk_IDirect3DImpl_3_CreateVertexBuffer,
342 XCAST(EnumZBufferFormats) Thunk_IDirect3DImpl_3_EnumZBufferFormats,
343 XCAST(EvictManagedTextures) Thunk_IDirect3DImpl_3_EvictManagedTextures,
346 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
347 #undef XCAST
348 #endif
351 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
352 # define XCAST(fun) (typeof(VTABLE_IDirect3D2.fun))
353 #else
354 # define XCAST(fun) (void*)
355 #endif
357 ICOM_VTABLE(IDirect3D2) VTABLE_IDirect3D2 =
359 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
360 XCAST(QueryInterface) Thunk_IDirect3DImpl_2_QueryInterface,
361 XCAST(AddRef) Thunk_IDirect3DImpl_2_AddRef,
362 XCAST(Release) Thunk_IDirect3DImpl_2_Release,
363 XCAST(EnumDevices) Thunk_IDirect3DImpl_2_EnumDevices,
364 XCAST(CreateLight) Thunk_IDirect3DImpl_2_CreateLight,
365 XCAST(CreateMaterial) Thunk_IDirect3DImpl_2_CreateMaterial,
366 XCAST(CreateViewport) Thunk_IDirect3DImpl_2_CreateViewport,
367 XCAST(FindDevice) Thunk_IDirect3DImpl_2_FindDevice,
368 XCAST(CreateDevice) GL_IDirect3DImpl_2_CreateDevice,
371 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
372 #undef XCAST
373 #endif
376 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
377 # define XCAST(fun) (typeof(VTABLE_IDirect3D.fun))
378 #else
379 # define XCAST(fun) (void*)
380 #endif
382 ICOM_VTABLE(IDirect3D) VTABLE_IDirect3D =
384 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
385 XCAST(QueryInterface) Thunk_IDirect3DImpl_1_QueryInterface,
386 XCAST(AddRef) Thunk_IDirect3DImpl_1_AddRef,
387 XCAST(Release) Thunk_IDirect3DImpl_1_Release,
388 XCAST(Initialize) Main_IDirect3DImpl_1_Initialize,
389 XCAST(EnumDevices) GL_IDirect3DImpl_1_EnumDevices,
390 XCAST(CreateLight) Thunk_IDirect3DImpl_1_CreateLight,
391 XCAST(CreateMaterial) Thunk_IDirect3DImpl_1_CreateMaterial,
392 XCAST(CreateViewport) Thunk_IDirect3DImpl_1_CreateViewport,
393 XCAST(FindDevice) Thunk_IDirect3DImpl_1_FindDevice,
396 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
397 #undef XCAST
398 #endif
400 static HRESULT d3d_add_device(IDirectDrawImpl *This, IDirect3DDeviceImpl *device)
402 if (This->current_device == NULL) {
403 /* Create delayed textures now that we have an OpenGL context...
404 For that, go through all surface attached to our DDraw object and create
405 OpenGL textures for all textures.. */
406 IDirectDrawSurfaceImpl *surf = This->surfaces;
408 while (surf != NULL) {
409 if (surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_TEXTURE) {
410 /* Found a texture.. Now create the OpenGL part */
411 d3dtexture_create(This, surf, FALSE, surf->mip_main);
413 surf = surf->next_ddraw;
416 /* For the moment, only one device 'supported'... */
417 This->current_device = device;
419 return DD_OK;
422 static HRESULT d3d_remove_device(IDirectDrawImpl *This, IDirect3DDeviceImpl *device)
424 This->current_device = NULL;
425 return DD_OK;
428 HRESULT direct3d_create(IDirectDrawImpl *This)
430 IDirect3DGLImpl *globject;
432 globject = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DGLImpl));
433 if (globject == NULL) return DDERR_OUTOFMEMORY;
435 This->d3d_create_texture = d3dtexture_create;
436 This->d3d_added_device = d3d_add_device;
437 This->d3d_removed_device = d3d_remove_device;
439 ICOM_INIT_INTERFACE(This, IDirect3D, VTABLE_IDirect3D);
440 ICOM_INIT_INTERFACE(This, IDirect3D2, VTABLE_IDirect3D2);
441 ICOM_INIT_INTERFACE(This, IDirect3D3, VTABLE_IDirect3D3);
442 ICOM_INIT_INTERFACE(This, IDirect3D7, VTABLE_IDirect3D7);
444 globject->free_lights = (0x01 << MAX_LIGHTS) - 1; /* There are, in total, 8 lights in OpenGL */
445 globject->light_released = light_released;
447 This->d3d_private = globject;
449 TRACE(" creating Mesa private storage at %p.\n", globject);
451 return D3D_OK;