2 * IDirect3D8 implementation
4 * Copyright 2002-2004 Jason Edmeades
5 * Copyright 2003-2004 Raphael Junqueira
6 * Copyright 2004 Christian Costa
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #define NONAMELESSUNION
28 #define NONAMELESSSTRUCT
33 #include "wine/debug.h"
34 #include "wine/unicode.h"
36 #include "d3d8_private.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(d3d
);
39 WINE_DECLARE_DEBUG_CHANNEL(d3d_caps
);
41 /* x11drv GDI escapes */
42 #define X11DRV_ESCAPE 6789
43 enum x11drv_escape_codes
45 X11DRV_GET_DISPLAY
, /* get X11 display for a DC */
46 X11DRV_GET_DRAWABLE
, /* get current drawable for a DC */
47 X11DRV_GET_FONT
, /* get current X font for a DC */
51 static const D3DFORMAT device_formats
[NUM_FORMATS
] = {
61 static void IDirect3D8Impl_FillGLCaps(LPDIRECT3D8 iface
, Display
* display
);
64 /* retrieve the X display to use on a given DC */
65 inline static Display
*get_display( HDC hdc
)
68 enum x11drv_escape_codes escape
= X11DRV_GET_DISPLAY
;
70 if (!ExtEscape( hdc
, X11DRV_ESCAPE
, sizeof(escape
), (LPCSTR
)&escape
,
71 sizeof(display
), (LPSTR
)&display
)) display
= NULL
;
76 * Note: GL seems to trap if GetDeviceCaps is called before any HWND's created
77 * ie there is no GL Context - Get a default rendering context to enable the
78 * function query some info from GL
81 WineD3D_Context
* WineD3DCreateFakeGLContext(void) {
82 static WineD3D_Context ctx
= { NULL
, NULL
, NULL
, 0, 0 };
83 WineD3D_Context
* ret
= NULL
;
85 if (glXGetCurrentContext() == NULL
) {
86 BOOL gotContext
= FALSE
;
93 XWindowAttributes win_attr
;
95 TRACE_(d3d_caps
)("Creating Fake GL Context\n");
97 ctx
.drawable
= (Drawable
) GetPropA(GetDesktopWindow(), "__wine_x11_whole_window");
100 device_context
= GetDC(0);
101 ctx
.display
= get_display(device_context
);
102 ReleaseDC(0, device_context
);
104 /* Get the X visual */
106 if (XGetWindowAttributes(ctx
.display
, ctx
.drawable
, &win_attr
)) {
107 visual
= win_attr
.visual
;
109 visual
= DefaultVisual(ctx
.display
, DefaultScreen(ctx
.display
));
111 template.visualid
= XVisualIDFromVisual(visual
);
112 ctx
.visInfo
= XGetVisualInfo(ctx
.display
, VisualIDMask
, &template, &num
);
113 if (ctx
.visInfo
== NULL
) {
115 WARN_(d3d_caps
)("Error creating visual info for capabilities initialization\n");
119 /* Create a GL context */
121 ctx
.glCtx
= glXCreateContext(ctx
.display
, ctx
.visInfo
, NULL
, GL_TRUE
);
123 if (ctx
.glCtx
== NULL
) {
125 WARN_(d3d_caps
)("Error creating default context for capabilities initialization\n");
130 /* Make it the current GL context */
131 if (!failed
&& glXMakeCurrent(ctx
.display
, ctx
.drawable
, ctx
.glCtx
) == False
) {
132 glXDestroyContext(ctx
.display
, ctx
.glCtx
);
134 WARN_(d3d_caps
)("Error setting default context as current for capabilities initialization\n");
138 /* It worked! Wow... */
147 if (ctx
.ref
> 0) ret
= &ctx
;
150 if (NULL
!= ret
) ++ret
->ref
;
156 void WineD3DReleaseFakeGLContext(WineD3D_Context
* ctx
) {
157 /* If we created a dummy context, throw it away */
161 glXMakeCurrent(ctx
->display
, None
, NULL
);
162 glXDestroyContext(ctx
->display
, ctx
->glCtx
);
171 /* IDirect3D IUnknown parts follow: */
172 HRESULT WINAPI
IDirect3D8Impl_QueryInterface(LPDIRECT3D8 iface
,REFIID riid
,LPVOID
*ppobj
)
174 IDirect3D8Impl
*This
= (IDirect3D8Impl
*)iface
;
176 if (IsEqualGUID(riid
, &IID_IUnknown
)
177 || IsEqualGUID(riid
, &IID_IDirect3D8
)) {
178 IDirect3D8Impl_AddRef(iface
);
183 WARN("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppobj
);
184 return E_NOINTERFACE
;
187 ULONG WINAPI
IDirect3D8Impl_AddRef(LPDIRECT3D8 iface
) {
188 IDirect3D8Impl
*This
= (IDirect3D8Impl
*)iface
;
189 TRACE("(%p) : AddRef from %ld\n", This
, This
->ref
);
190 return ++(This
->ref
);
193 ULONG WINAPI
IDirect3D8Impl_Release(LPDIRECT3D8 iface
) {
194 IDirect3D8Impl
*This
= (IDirect3D8Impl
*)iface
;
195 ULONG ref
= --This
->ref
;
196 TRACE("(%p) : ReleaseRef to %ld\n", This
, This
->ref
);
198 IWineD3D_Release(This
->WineD3D
);
199 HeapFree(GetProcessHeap(), 0, This
);
204 /* IDirect3D Interface follow: */
205 HRESULT WINAPI
IDirect3D8Impl_RegisterSoftwareDevice (LPDIRECT3D8 iface
, void* pInitializeFunction
) {
206 IDirect3D8Impl
*This
= (IDirect3D8Impl
*)iface
;
207 return IWineD3D_RegisterSoftwareDevice(This
->WineD3D
, pInitializeFunction
);
210 UINT WINAPI
IDirect3D8Impl_GetAdapterCount (LPDIRECT3D8 iface
) {
211 IDirect3D8Impl
*This
= (IDirect3D8Impl
*)iface
;
212 return IWineD3D_GetAdapterCount(This
->WineD3D
);
215 HRESULT WINAPI
IDirect3D8Impl_GetAdapterIdentifier (LPDIRECT3D8 iface
,
216 UINT Adapter
, DWORD Flags
, D3DADAPTER_IDENTIFIER8
* pIdentifier
) {
217 IDirect3D8Impl
*This
= (IDirect3D8Impl
*)iface
;
218 WINED3DADAPTER_IDENTIFIER adapter_id
;
220 /* dx8 and dx9 have different structures to be filled in, with incompatible
221 layouts so pass in pointers to the places to be filled via an internal
223 adapter_id
.Driver
= pIdentifier
->Driver
;
224 adapter_id
.Description
= pIdentifier
->Description
;
225 adapter_id
.DeviceName
= NULL
;
226 adapter_id
.DriverVersion
= &pIdentifier
->DriverVersion
;
227 adapter_id
.VendorId
= &pIdentifier
->VendorId
;
228 adapter_id
.DeviceId
= &pIdentifier
->DeviceId
;
229 adapter_id
.SubSysId
= &pIdentifier
->SubSysId
;
230 adapter_id
.Revision
= &pIdentifier
->Revision
;
231 adapter_id
.DeviceIdentifier
= &pIdentifier
->DeviceIdentifier
;
232 adapter_id
.WHQLLevel
= &pIdentifier
->WHQLLevel
;
234 return IWineD3D_GetAdapterIdentifier(This
->WineD3D
, Adapter
, Flags
, &adapter_id
);
237 UINT WINAPI
IDirect3D8Impl_GetAdapterModeCount (LPDIRECT3D8 iface
,UINT Adapter
) {
238 IDirect3D8Impl
*This
= (IDirect3D8Impl
*)iface
;
239 return IWineD3D_GetAdapterModeCount(This
->WineD3D
, Adapter
, D3DFMT_UNKNOWN
);
242 HRESULT WINAPI
IDirect3D8Impl_EnumAdapterModes (LPDIRECT3D8 iface
, UINT Adapter
, UINT Mode
, D3DDISPLAYMODE
* pMode
) {
243 IDirect3D8Impl
*This
= (IDirect3D8Impl
*)iface
;
244 return IWineD3D_EnumAdapterModes(This
->WineD3D
, Adapter
, D3DFMT_UNKNOWN
, Mode
, pMode
);
247 HRESULT WINAPI
IDirect3D8Impl_GetAdapterDisplayMode (LPDIRECT3D8 iface
, UINT Adapter
, D3DDISPLAYMODE
* pMode
) {
248 IDirect3D8Impl
*This
= (IDirect3D8Impl
*)iface
;
249 return IWineD3D_GetAdapterDisplayMode(This
->WineD3D
, Adapter
, pMode
);
252 HRESULT WINAPI
IDirect3D8Impl_CheckDeviceType (LPDIRECT3D8 iface
,
253 UINT Adapter
, D3DDEVTYPE CheckType
, D3DFORMAT DisplayFormat
,
254 D3DFORMAT BackBufferFormat
, BOOL Windowed
) {
255 IDirect3D8Impl
*This
= (IDirect3D8Impl
*)iface
;
256 TRACE_(d3d_caps
)("(%p)->(Adptr:%d, CheckType:(%x,%s), DispFmt:(%x,%s), BackBuf:(%x,%s), Win?%d): stub\n",
259 CheckType
, debug_d3ddevicetype(CheckType
),
260 DisplayFormat
, debug_d3dformat(DisplayFormat
),
261 BackBufferFormat
, debug_d3dformat(BackBufferFormat
),
264 if (Adapter
>= IDirect3D8Impl_GetAdapterCount(iface
)) {
265 return D3DERR_INVALIDCALL
;
269 switch (DisplayFormat) {
270 case D3DFMT_A8R8G8B8:
271 return D3DERR_NOTAVAILABLE;
276 switch (DisplayFormat
) {
277 /*case D3DFMT_R5G6B5:*/
279 return D3DERR_NOTAVAILABLE
;
286 HRESULT WINAPI
IDirect3D8Impl_CheckDeviceFormat (LPDIRECT3D8 iface
,
287 UINT Adapter
, D3DDEVTYPE DeviceType
, D3DFORMAT AdapterFormat
,
288 DWORD Usage
, D3DRESOURCETYPE RType
, D3DFORMAT CheckFormat
) {
289 IDirect3D8Impl
*This
= (IDirect3D8Impl
*)iface
;
290 TRACE_(d3d_caps
)("(%p)->(Adptr:%d, DevType:(%u,%s), AdptFmt:(%u,%s), Use:(%lu,%s), ResTyp:(%x,%s), CheckFmt:(%u,%s)) ",
293 DeviceType
, debug_d3ddevicetype(DeviceType
),
294 AdapterFormat
, debug_d3dformat(AdapterFormat
),
295 Usage
, debug_d3dusage(Usage
),
296 RType
, debug_d3dressourcetype(RType
),
297 CheckFormat
, debug_d3dformat(CheckFormat
));
299 if (Adapter
>= IDirect3D8Impl_GetAdapterCount(iface
)) {
300 return D3DERR_INVALIDCALL
;
303 if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC
)) {
304 switch (CheckFormat
) {
308 TRACE_(d3d_caps
)("[OK]\n");
311 break; /* Avoid compiler warnings */
315 switch (CheckFormat
) {
317 * check supported using GL_SUPPORT
328 /*case D3DFMT_R5G6B5: */
329 /*case D3DFMT_X1R5G5B5:*/
330 /*case D3DFMT_A1R5G5B5: */
331 /*case D3DFMT_A4R4G4B4:*/
338 /*case D3DFMT_X8R8G8B8:*/
339 case D3DFMT_A8R3G3B2
:
356 case D3DFMT_X8L8V8U8
:
357 case D3DFMT_Q8W8V8U8
:
358 case D3DFMT_W11V11U10
:
361 * currently hard to support
366 /* Since we do not support these formats right now, don't pretend to. */
367 TRACE_(d3d_caps
)("[FAILED]\n");
368 return D3DERR_NOTAVAILABLE
;
373 TRACE_(d3d_caps
)("[OK]\n");
377 HRESULT WINAPI
IDirect3D8Impl_CheckDeviceMultiSampleType(LPDIRECT3D8 iface
,
378 UINT Adapter
, D3DDEVTYPE DeviceType
, D3DFORMAT SurfaceFormat
,
379 BOOL Windowed
, D3DMULTISAMPLE_TYPE MultiSampleType
) {
380 IDirect3D8Impl
*This
= (IDirect3D8Impl
*)iface
;
381 TRACE_(d3d_caps
)("(%p)->(Adptr:%d, DevType:(%x,%s), SurfFmt:(%x,%s), Win?%d, MultiSamp:%x)\n",
384 DeviceType
, debug_d3ddevicetype(DeviceType
),
385 SurfaceFormat
, debug_d3dformat(SurfaceFormat
),
389 if (Adapter
>= IDirect3D8Impl_GetAdapterCount(iface
)) {
390 return D3DERR_INVALIDCALL
;
393 if (D3DMULTISAMPLE_NONE
== MultiSampleType
)
395 return D3DERR_NOTAVAILABLE
;
398 HRESULT WINAPI
IDirect3D8Impl_CheckDepthStencilMatch(LPDIRECT3D8 iface
,
399 UINT Adapter
, D3DDEVTYPE DeviceType
, D3DFORMAT AdapterFormat
,
400 D3DFORMAT RenderTargetFormat
, D3DFORMAT DepthStencilFormat
) {
401 IDirect3D8Impl
*This
= (IDirect3D8Impl
*)iface
;
402 TRACE_(d3d_caps
)("(%p)->(Adptr:%d, DevType:(%x,%s), AdptFmt:(%x,%s), RendrTgtFmt:(%x,%s), DepthStencilFmt:(%x,%s))\n",
405 DeviceType
, debug_d3ddevicetype(DeviceType
),
406 AdapterFormat
, debug_d3dformat(AdapterFormat
),
407 RenderTargetFormat
, debug_d3dformat(RenderTargetFormat
),
408 DepthStencilFormat
, debug_d3dformat(DepthStencilFormat
));
410 if (Adapter
>= IDirect3D8Impl_GetAdapterCount(iface
)) {
411 return D3DERR_INVALIDCALL
;
415 switch (DepthStencilFormat
) {
421 * as i don't know how to really check hard caps of graphics cards
422 * i prefer to not permit 32bit zbuffers enumeration (as few cards can do it)
424 return D3DERR_NOTAVAILABLE
;
432 HRESULT WINAPI
IDirect3D8Impl_GetDeviceCaps(LPDIRECT3D8 iface
, UINT Adapter
, D3DDEVTYPE DeviceType
, D3DCAPS8
* pCaps
) {
434 BOOL gotContext
= FALSE
;
435 GLint gl_tex_size
= 0;
436 WineD3D_Context
* fake_ctx
= NULL
;
437 IDirect3D8Impl
*This
= (IDirect3D8Impl
*)iface
;
439 TRACE_(d3d_caps
)("(%p)->(Adptr:%d, DevType: %x, pCaps: %p)\n", This
, Adapter
, DeviceType
, pCaps
);
441 if (Adapter
>= IDirect3D8Impl_GetAdapterCount(iface
)) {
442 return D3DERR_INVALIDCALL
;
445 /* Note: GL seems to trap if GetDeviceCaps is called before any HWND's created
446 ie there is no GL Context - Get a default rendering context to enable the
447 function query some info from GL */
448 if (glXGetCurrentContext() == NULL
) {
449 fake_ctx
= WineD3DCreateFakeGLContext();
450 if (NULL
!= fake_ctx
) gotContext
= TRUE
;
455 if (gotContext
== FALSE
) {
457 FIXME_(d3d_caps
)("GetDeviceCaps called but no GL Context - Returning dummy values\n");
459 pCaps
->MaxTextureBlendStages
= 2;
460 pCaps
->MaxSimultaneousTextures
= 2;
461 pCaps
->MaxUserClipPlanes
= 8;
462 pCaps
->MaxActiveLights
= 8;
463 pCaps
->MaxVertexBlendMatrices
= 0;
464 pCaps
->MaxVertexBlendMatrixIndex
= 1;
465 pCaps
->MaxAnisotropy
= 0;
466 pCaps
->MaxPointSize
= 255.0;
468 glGetIntegerv(GL_MAX_TEXTURE_SIZE
, &gl_tex_size
);
471 /* If we don't know the device settings, go query them now */
472 if (This
->isGLInfoValid
== FALSE
) IDirect3D8Impl_FillGLCaps(iface
, NULL
);
474 pCaps
->DeviceType
= (DeviceType
== D3DDEVTYPE_HAL
) ? D3DDEVTYPE_HAL
: D3DDEVTYPE_REF
; /* Not quite true, but use h/w supported by opengl I suppose */
475 pCaps
->AdapterOrdinal
= Adapter
;
478 pCaps
->Caps2
= D3DCAPS2_CANRENDERWINDOWED
;
479 pCaps
->Caps3
= D3DDEVCAPS_HWTRANSFORMANDLIGHT
;
480 pCaps
->PresentationIntervals
= D3DPRESENT_INTERVAL_IMMEDIATE
;
482 pCaps
->CursorCaps
= 0;
484 pCaps
->DevCaps
= D3DDEVCAPS_DRAWPRIMTLVERTEX
|
485 D3DDEVCAPS_HWTRANSFORMANDLIGHT
|
486 D3DDEVCAPS_PUREDEVICE
;
488 pCaps
->PrimitiveMiscCaps
= D3DPMISCCAPS_CULLCCW
|
489 D3DPMISCCAPS_CULLCW
|
490 D3DPMISCCAPS_COLORWRITEENABLE
|
491 D3DPMISCCAPS_CLIPTLVERTS
|
492 D3DPMISCCAPS_CLIPPLANESCALEDPOINTS
|
494 /*NOT: D3DPMISCCAPS_TSSARGTEMP*/
496 pCaps
->RasterCaps
= D3DPRASTERCAPS_DITHER
|
498 D3DPRASTERCAPS_WFOG
|
499 D3DPRASTERCAPS_ZFOG
|
500 D3DPRASTERCAPS_FOGVERTEX
|
501 D3DPRASTERCAPS_FOGTABLE
|
502 D3DPRASTERCAPS_FOGRANGE
;
504 if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC
)) {
505 pCaps
->RasterCaps
|= D3DPRASTERCAPS_ANISOTROPY
;
508 D3DPRASTERCAPS_MIPMAPLODBIAS
510 D3DPRASTERCAPS_COLORPERSPECTIVE
511 D3DPRASTERCAPS_STRETCHBLTMULTISAMPLE
512 D3DPRASTERCAPS_ANTIALIASEDGES
513 D3DPRASTERCAPS_ZBUFFERLESSHSR
514 D3DPRASTERCAPS_WBUFFER */
516 pCaps
->ZCmpCaps
= D3DPCMPCAPS_ALWAYS
|
518 D3DPCMPCAPS_GREATER
|
519 D3DPCMPCAPS_GREATEREQUAL
|
521 D3DPCMPCAPS_LESSEQUAL
|
523 D3DPCMPCAPS_NOTEQUAL
;
525 pCaps
->SrcBlendCaps
= 0xFFFFFFFF; /*FIXME: Tidy up later */
526 pCaps
->DestBlendCaps
= 0xFFFFFFFF; /*FIXME: Tidy up later */
527 pCaps
->AlphaCmpCaps
= 0xFFFFFFFF; /*FIXME: Tidy up later */
529 pCaps
->ShadeCaps
= D3DPSHADECAPS_SPECULARGOURAUDRGB
|
530 D3DPSHADECAPS_COLORGOURAUDRGB
;
532 pCaps
->TextureCaps
= D3DPTEXTURECAPS_ALPHA
|
533 D3DPTEXTURECAPS_ALPHAPALETTE
|
534 D3DPTEXTURECAPS_POW2
|
535 D3DPTEXTURECAPS_VOLUMEMAP
|
536 D3DPTEXTURECAPS_MIPMAP
|
537 D3DPTEXTURECAPS_PROJECTED
;
539 if (GL_SUPPORT(ARB_TEXTURE_CUBE_MAP
)) {
540 pCaps
->TextureCaps
|= D3DPTEXTURECAPS_CUBEMAP
|
541 D3DPTEXTURECAPS_MIPCUBEMAP
|
542 D3DPTEXTURECAPS_CUBEMAP_POW2
;
545 pCaps
->TextureFilterCaps
= D3DPTFILTERCAPS_MAGFLINEAR
|
546 D3DPTFILTERCAPS_MAGFPOINT
|
547 D3DPTFILTERCAPS_MINFLINEAR
|
548 D3DPTFILTERCAPS_MINFPOINT
|
549 D3DPTFILTERCAPS_MIPFLINEAR
|
550 D3DPTFILTERCAPS_MIPFPOINT
;
552 pCaps
->CubeTextureFilterCaps
= 0;
553 pCaps
->VolumeTextureFilterCaps
= 0;
555 pCaps
->TextureAddressCaps
= D3DPTADDRESSCAPS_BORDER
|
556 D3DPTADDRESSCAPS_CLAMP
|
557 D3DPTADDRESSCAPS_WRAP
;
559 if (GL_SUPPORT(ARB_TEXTURE_BORDER_CLAMP
)) {
560 pCaps
->TextureAddressCaps
|= D3DPTADDRESSCAPS_BORDER
;
562 if (GL_SUPPORT(ARB_TEXTURE_MIRRORED_REPEAT
)) {
563 pCaps
->TextureAddressCaps
|= D3DPTADDRESSCAPS_MIRROR
;
565 if (GL_SUPPORT(ATI_TEXTURE_MIRROR_ONCE
)) {
566 pCaps
->TextureAddressCaps
|= D3DPTADDRESSCAPS_MIRRORONCE
;
569 pCaps
->VolumeTextureAddressCaps
= 0;
571 pCaps
->LineCaps
= D3DLINECAPS_TEXTURE
|
578 pCaps
->MaxTextureWidth
= gl_tex_size
;
579 pCaps
->MaxTextureHeight
= gl_tex_size
;
581 pCaps
->MaxVolumeExtent
= 0;
583 pCaps
->MaxTextureRepeat
= 32768;
584 pCaps
->MaxTextureAspectRatio
= 32768;
585 pCaps
->MaxVertexW
= 1.0;
587 pCaps
->GuardBandLeft
= 0;
588 pCaps
->GuardBandTop
= 0;
589 pCaps
->GuardBandRight
= 0;
590 pCaps
->GuardBandBottom
= 0;
592 pCaps
->ExtentsAdjust
= 0;
594 pCaps
->StencilCaps
= D3DSTENCILCAPS_DECRSAT
|
595 D3DSTENCILCAPS_INCRSAT
|
596 D3DSTENCILCAPS_INVERT
|
597 D3DSTENCILCAPS_KEEP
|
598 D3DSTENCILCAPS_REPLACE
|
600 if (GL_SUPPORT(EXT_STENCIL_WRAP
)) {
601 pCaps
->StencilCaps
|= D3DSTENCILCAPS_DECR
|
605 pCaps
->FVFCaps
= D3DFVFCAPS_PSIZE
| 0x0008; /* 8 texture coords */
607 pCaps
->TextureOpCaps
= D3DTEXOPCAPS_ADD
|
608 D3DTEXOPCAPS_ADDSIGNED
|
609 D3DTEXOPCAPS_ADDSIGNED2X
|
610 D3DTEXOPCAPS_MODULATE
|
611 D3DTEXOPCAPS_MODULATE2X
|
612 D3DTEXOPCAPS_MODULATE4X
|
613 D3DTEXOPCAPS_SELECTARG1
|
614 D3DTEXOPCAPS_SELECTARG2
|
615 D3DTEXOPCAPS_DISABLE
;
616 #if defined(GL_VERSION_1_3)
617 pCaps
->TextureOpCaps
|= D3DTEXOPCAPS_DOTPRODUCT3
|
618 D3DTEXOPCAPS_SUBTRACT
;
620 if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE
) ||
621 GL_SUPPORT(EXT_TEXTURE_ENV_COMBINE
) ||
622 GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4
)) {
623 pCaps
->TextureOpCaps
|= D3DTEXOPCAPS_BLENDDIFFUSEALPHA
|
624 D3DTEXOPCAPS_BLENDTEXTUREALPHA
|
625 D3DTEXOPCAPS_BLENDFACTORALPHA
|
626 D3DTEXOPCAPS_BLENDCURRENTALPHA
|
629 if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4
)) {
630 pCaps
->TextureOpCaps
|= D3DTEXOPCAPS_ADDSMOOTH
|
631 D3DTEXOPCAPS_MULTIPLYADD
|
632 D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR
|
633 D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA
|
634 D3DTEXOPCAPS_BLENDTEXTUREALPHAPM
;
638 pCaps
->TextureOpCaps
|= D3DTEXOPCAPS_BUMPENVMAP
;
640 D3DTEXOPCAPS_BUMPENVMAPLUMINANCE
641 D3DTEXOPCAPS_PREMODULATE */
647 #if defined(GL_VERSION_1_3)
648 glGetIntegerv(GL_MAX_TEXTURE_UNITS
, &gl_max
);
650 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB
, &gl_max
);
652 TRACE_(d3d_caps
)("GLCaps: GL_MAX_TEXTURE_UNITS_ARB=%d\n", gl_max
);
653 pCaps
->MaxTextureBlendStages
= min(8, gl_max
);
654 pCaps
->MaxSimultaneousTextures
= min(8, gl_max
);
656 glGetIntegerv(GL_MAX_CLIP_PLANES
, &gl_max
);
657 pCaps
->MaxUserClipPlanes
= min(MAX_CLIPPLANES
, gl_max
);
658 TRACE_(d3d_caps
)("GLCaps: GL_MAX_CLIP_PLANES=%ld\n", pCaps
->MaxUserClipPlanes
);
660 glGetIntegerv(GL_MAX_LIGHTS
, &gl_max
);
661 pCaps
->MaxActiveLights
= gl_max
;
662 TRACE_(d3d_caps
)("GLCaps: GL_MAX_LIGHTS=%ld\n", pCaps
->MaxActiveLights
);
664 if (GL_SUPPORT(ARB_VERTEX_BLEND
)) {
665 glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB
, &gl_max
);
666 pCaps
->MaxVertexBlendMatrices
= gl_max
;
667 pCaps
->MaxVertexBlendMatrixIndex
= 1;
669 pCaps
->MaxVertexBlendMatrices
= 0;
670 pCaps
->MaxVertexBlendMatrixIndex
= 1;
673 if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC
)) {
674 glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT
, &gl_max
);
675 checkGLcall("glGetInterv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT)");
676 pCaps
->MaxAnisotropy
= gl_max
;
678 pCaps
->MaxAnisotropy
= 0;
681 glGetFloatv(GL_POINT_SIZE_RANGE
, &gl_float
);
682 pCaps
->MaxPointSize
= gl_float
;
685 pCaps
->VertexProcessingCaps
= D3DVTXPCAPS_DIRECTIONALLIGHTS
|
686 D3DVTXPCAPS_MATERIALSOURCE7
|
687 D3DVTXPCAPS_POSITIONALLIGHTS
|
688 D3DVTXPCAPS_LOCALVIEWER
|
691 D3DVTXPCAPS_TWEENING */
693 pCaps
->MaxPrimitiveCount
= 0xFFFFFFFF;
694 pCaps
->MaxVertexIndex
= 0xFFFFFFFF;
695 pCaps
->MaxStreams
= MAX_STREAMS
;
696 pCaps
->MaxStreamStride
= 1024;
698 if (((vs_mode
== VS_HW
) && GL_SUPPORT(ARB_VERTEX_PROGRAM
)) || (vs_mode
== VS_SW
) || (DeviceType
== D3DDEVTYPE_REF
)) {
699 pCaps
->VertexShaderVersion
= D3DVS_VERSION(1,1);
701 if (This
->gl_info
.gl_vendor
== VENDOR_MESA
||
702 This
->gl_info
.gl_vendor
== VENDOR_WINE
) {
703 pCaps
->MaxVertexShaderConst
= 95;
705 pCaps
->MaxVertexShaderConst
= D3D8_VSHADER_MAX_CONSTANTS
;
708 pCaps
->VertexShaderVersion
= 0;
709 pCaps
->MaxVertexShaderConst
= 0;
712 if ((ps_mode
== PS_HW
) && GL_SUPPORT(ARB_FRAGMENT_PROGRAM
) && (DeviceType
!= D3DDEVTYPE_REF
)) {
713 pCaps
->PixelShaderVersion
= D3DPS_VERSION(1,4);
714 pCaps
->MaxPixelShaderValue
= 1.0;
716 pCaps
->PixelShaderVersion
= 0;
717 pCaps
->MaxPixelShaderValue
= 0.0;
720 /* If we created a dummy context, throw it away */
721 WineD3DReleaseFakeGLContext(fake_ctx
);
725 HMONITOR WINAPI
IDirect3D8Impl_GetAdapterMonitor(LPDIRECT3D8 iface
, UINT Adapter
) {
726 IDirect3D8Impl
*This
= (IDirect3D8Impl
*)iface
;
727 return IWineD3D_GetAdapterMonitor(This
->WineD3D
, Adapter
);
730 static void IDirect3D8Impl_FillGLCaps(LPDIRECT3D8 iface
, Display
* display
) {
731 const char *GL_Extensions
= NULL
;
732 const char *GLX_Extensions
= NULL
;
734 const char* gl_string
= NULL
;
735 const char* gl_string_cursor
= NULL
;
738 IDirect3D8Impl
*This
= (IDirect3D8Impl
*)iface
;
740 if (This
->gl_info
.bIsFilled
) return;
741 This
->gl_info
.bIsFilled
= 1;
743 TRACE_(d3d_caps
)("(%p, %p)\n", This
, display
);
745 if (NULL
!= display
) {
746 test
= glXQueryVersion(display
, &major
, &minor
);
747 This
->gl_info
.glx_version
= ((major
& 0x0000FFFF) << 16) | (minor
& 0x0000FFFF);
748 gl_string
= glXGetClientString(display
, GLX_VENDOR
);
750 gl_string
= glGetString(GL_VENDOR
);
753 if (strstr(gl_string
, "NVIDIA")) {
754 This
->gl_info
.gl_vendor
= VENDOR_NVIDIA
;
755 } else if (strstr(gl_string
, "ATI")) {
756 This
->gl_info
.gl_vendor
= VENDOR_ATI
;
758 This
->gl_info
.gl_vendor
= VENDOR_WINE
;
761 TRACE_(d3d_caps
)("found GL_VENDOR (%s)->(0x%04x)\n", debugstr_a(gl_string
), This
->gl_info
.gl_vendor
);
763 gl_string
= glGetString(GL_VERSION
);
764 switch (This
->gl_info
.gl_vendor
) {
766 gl_string_cursor
= strstr(gl_string
, "NVIDIA");
767 gl_string_cursor
= strstr(gl_string_cursor
, " ");
768 while (*gl_string_cursor
&& ' ' == *gl_string_cursor
) ++gl_string_cursor
;
769 if (*gl_string_cursor
) {
773 while (*gl_string_cursor
<= '9' && *gl_string_cursor
>= '0') {
774 tmp
[cursor
++] = *gl_string_cursor
;
780 if (*gl_string_cursor
!= '.') WARN_(d3d_caps
)("malformed GL_VERSION (%s)\n", debugstr_a(gl_string
));
783 while (*gl_string_cursor
<= '9' && *gl_string_cursor
>= '0') {
784 tmp
[cursor
++] = *gl_string_cursor
;
793 gl_string_cursor
= strchr(gl_string
, '-');
794 if (gl_string_cursor
++) {
796 /* Check if version number is of the form x.y.z */
797 if (*gl_string_cursor
> '9' && *gl_string_cursor
< '0')
799 if (!error
&& *(gl_string_cursor
+2) > '9' && *(gl_string_cursor
+2) < '0')
801 if (!error
&& *(gl_string_cursor
+4) > '9' && *(gl_string_cursor
+4) < '0')
803 if (!error
&& *(gl_string_cursor
+1) != '.' && *(gl_string_cursor
+3) != '.')
805 /* Mark version number as malformed */
807 gl_string_cursor
= 0;
809 if (!gl_string_cursor
)
810 WARN_(d3d_caps
)("malformed GL_VERSION (%s)\n", debugstr_a(gl_string
));
812 major
= *gl_string_cursor
- '0';
813 minor
= (*(gl_string_cursor
+2) - '0') * 256 + (*(gl_string_cursor
+4) - '0');
820 This
->gl_info
.gl_driver_version
= MAKEDWORD_VERSION(major
, minor
);
822 FIXME_(d3d_caps
)("found GL_VERSION (%s)->(0x%08lx)\n", debugstr_a(gl_string
), This
->gl_info
.gl_driver_version
);
824 gl_string
= glGetString(GL_RENDERER
);
825 strcpy(This
->gl_info
.gl_renderer
, gl_string
);
827 switch (This
->gl_info
.gl_vendor
) {
829 if (strstr(This
->gl_info
.gl_renderer
, "GeForce4 Ti")) {
830 This
->gl_info
.gl_card
= CARD_NVIDIA_GEFORCE4_TI4600
;
831 } else if (strstr(This
->gl_info
.gl_renderer
, "GeForceFX")) {
832 This
->gl_info
.gl_card
= CARD_NVIDIA_GEFORCEFX_5900ULTRA
;
834 This
->gl_info
.gl_card
= CARD_NVIDIA_GEFORCE4_TI4600
;
838 if (strstr(This
->gl_info
.gl_renderer
, "RADEON 9800 PRO")) {
839 This
->gl_info
.gl_card
= CARD_ATI_RADEON_9800PRO
;
840 } else if (strstr(This
->gl_info
.gl_renderer
, "RADEON 9700 PRO")) {
841 This
->gl_info
.gl_card
= CARD_ATI_RADEON_9700PRO
;
843 This
->gl_info
.gl_card
= CARD_ATI_RADEON_8500
;
847 This
->gl_info
.gl_card
= CARD_WINE
;
851 FIXME_(d3d_caps
)("found GL_RENDERER (%s)->(0x%04x)\n", debugstr_a(This
->gl_info
.gl_renderer
), This
->gl_info
.gl_card
);
854 * Initialize openGL extension related variables
855 * with Default values
857 memset(&This
->gl_info
.supported
, 0, sizeof(This
->gl_info
.supported
));
858 This
->gl_info
.max_textures
= 1;
859 This
->gl_info
.ps_arb_version
= PS_VERSION_NOT_SUPPORTED
;
860 This
->gl_info
.vs_arb_version
= VS_VERSION_NOT_SUPPORTED
;
861 This
->gl_info
.vs_nv_version
= VS_VERSION_NOT_SUPPORTED
;
862 This
->gl_info
.vs_ati_version
= VS_VERSION_NOT_SUPPORTED
;
864 #define USE_GL_FUNC(type, pfn) This->gl_info.pfn = NULL;
868 /* Retrieve opengl defaults */
869 glGetIntegerv(GL_MAX_CLIP_PLANES
, &gl_max
);
870 This
->gl_info
.max_clipplanes
= min(MAX_CLIPPLANES
, gl_max
);
871 TRACE_(d3d_caps
)("ClipPlanes support - num Planes=%d\n", gl_max
);
873 glGetIntegerv(GL_MAX_LIGHTS
, &gl_max
);
874 This
->gl_info
.max_lights
= gl_max
;
875 TRACE_(d3d_caps
)("Lights support - max lights=%d\n", gl_max
);
877 /* Parse the gl supported features, in theory enabling parts of our code appropriately */
878 GL_Extensions
= glGetString(GL_EXTENSIONS
);
879 TRACE_(d3d_caps
)("GL_Extensions reported:\n");
881 if (NULL
== GL_Extensions
) {
882 ERR(" GL_Extensions returns NULL\n");
884 while (*GL_Extensions
!= 0x00) {
885 const char *Start
= GL_Extensions
;
888 memset(ThisExtn
, 0x00, sizeof(ThisExtn
));
889 while (*GL_Extensions
!= ' ' && *GL_Extensions
!= 0x00) {
892 memcpy(ThisExtn
, Start
, (GL_Extensions
- Start
));
893 TRACE_(d3d_caps
)("- %s\n", ThisExtn
);
898 if (strcmp(ThisExtn
, "GL_ARB_fragment_program") == 0) {
899 This
->gl_info
.ps_arb_version
= PS_VERSION_11
;
900 TRACE_(d3d_caps
)(" FOUND: ARB Pixel Shader support - version=%02x\n", This
->gl_info
.ps_arb_version
);
901 This
->gl_info
.supported
[ARB_FRAGMENT_PROGRAM
] = TRUE
;
902 } else if (strcmp(ThisExtn
, "GL_ARB_multisample") == 0) {
903 TRACE_(d3d_caps
)(" FOUND: ARB Multisample support\n");
904 This
->gl_info
.supported
[ARB_MULTISAMPLE
] = TRUE
;
905 } else if (strcmp(ThisExtn
, "GL_ARB_multitexture") == 0) {
906 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB
, &gl_max
);
907 TRACE_(d3d_caps
)(" FOUND: ARB Multitexture support - GL_MAX_TEXTURE_UNITS_ARB=%u\n", gl_max
);
908 This
->gl_info
.supported
[ARB_MULTITEXTURE
] = TRUE
;
909 This
->gl_info
.max_textures
= min(8, gl_max
);
910 } else if (strcmp(ThisExtn
, "GL_ARB_texture_cube_map") == 0) {
911 TRACE_(d3d_caps
)(" FOUND: ARB Texture Cube Map support\n");
912 This
->gl_info
.supported
[ARB_TEXTURE_CUBE_MAP
] = TRUE
;
913 TRACE_(d3d_caps
)(" IMPLIED: NVIDIA (NV) Texture Gen Reflection support\n");
914 This
->gl_info
.supported
[NV_TEXGEN_REFLECTION
] = TRUE
;
915 } else if (strcmp(ThisExtn
, "GL_ARB_texture_compression") == 0) {
916 TRACE_(d3d_caps
)(" FOUND: ARB Texture Compression support\n");
917 This
->gl_info
.supported
[ARB_TEXTURE_COMPRESSION
] = TRUE
;
918 } else if (strcmp(ThisExtn
, "GL_ARB_texture_env_add") == 0) {
919 TRACE_(d3d_caps
)(" FOUND: ARB Texture Env Add support\n");
920 This
->gl_info
.supported
[ARB_TEXTURE_ENV_ADD
] = TRUE
;
921 } else if (strcmp(ThisExtn
, "GL_ARB_texture_env_combine") == 0) {
922 TRACE_(d3d_caps
)(" FOUND: ARB Texture Env combine support\n");
923 This
->gl_info
.supported
[ARB_TEXTURE_ENV_COMBINE
] = TRUE
;
924 } else if (strcmp(ThisExtn
, "GL_ARB_texture_env_dot3") == 0) {
925 TRACE_(d3d_caps
)(" FOUND: ARB Dot3 support\n");
926 This
->gl_info
.supported
[ARB_TEXTURE_ENV_DOT3
] = TRUE
;
927 } else if (strcmp(ThisExtn
, "GL_ARB_texture_border_clamp") == 0) {
928 TRACE_(d3d_caps
)(" FOUND: ARB Texture border clamp support\n");
929 This
->gl_info
.supported
[ARB_TEXTURE_BORDER_CLAMP
] = TRUE
;
930 } else if (strcmp(ThisExtn
, "GL_ARB_texture_mirrored_repeat") == 0) {
931 TRACE_(d3d_caps
)(" FOUND: ARB Texture mirrored repeat support\n");
932 This
->gl_info
.supported
[ARB_TEXTURE_MIRRORED_REPEAT
] = TRUE
;
933 } else if (strstr(ThisExtn
, "GL_ARB_vertex_program")) {
934 This
->gl_info
.vs_arb_version
= VS_VERSION_11
;
935 TRACE_(d3d_caps
)(" FOUND: ARB Vertex Shader support - version=%02x\n", This
->gl_info
.vs_arb_version
);
936 This
->gl_info
.supported
[ARB_VERTEX_PROGRAM
] = TRUE
;
941 } else if (strcmp(ThisExtn
, "GL_EXT_fog_coord") == 0) {
942 TRACE_(d3d_caps
)(" FOUND: EXT Fog coord support\n");
943 This
->gl_info
.supported
[EXT_FOG_COORD
] = TRUE
;
944 } else if (strcmp(ThisExtn
, "GL_EXT_paletted_texture") == 0) { /* handle paletted texture extensions */
945 TRACE_(d3d_caps
)(" FOUND: EXT Paletted texture support\n");
946 This
->gl_info
.supported
[EXT_PALETTED_TEXTURE
] = TRUE
;
947 } else if (strcmp(ThisExtn
, "GL_EXT_point_parameters") == 0) {
948 TRACE_(d3d_caps
)(" FOUND: EXT Point parameters support\n");
949 This
->gl_info
.supported
[EXT_POINT_PARAMETERS
] = TRUE
;
950 } else if (strcmp(ThisExtn
, "GL_EXT_secondary_color") == 0) {
951 TRACE_(d3d_caps
)(" FOUND: EXT Secondary coord support\n");
952 This
->gl_info
.supported
[EXT_SECONDARY_COLOR
] = TRUE
;
953 } else if (strcmp(ThisExtn
, "GL_EXT_stencil_wrap") == 0) {
954 TRACE_(d3d_caps
)(" FOUND: EXT Stencil wrap support\n");
955 This
->gl_info
.supported
[EXT_STENCIL_WRAP
] = TRUE
;
956 } else if (strcmp(ThisExtn
, "GL_EXT_texture_compression_s3tc") == 0) {
957 TRACE_(d3d_caps
)(" FOUND: EXT Texture S3TC compression support\n");
958 This
->gl_info
.supported
[EXT_TEXTURE_COMPRESSION_S3TC
] = TRUE
;
959 } else if (strcmp(ThisExtn
, "GL_EXT_texture_env_add") == 0) {
960 TRACE_(d3d_caps
)(" FOUND: EXT Texture Env Add support\n");
961 This
->gl_info
.supported
[EXT_TEXTURE_ENV_ADD
] = TRUE
;
962 } else if (strcmp(ThisExtn
, "GL_EXT_texture_env_combine") == 0) {
963 TRACE_(d3d_caps
)(" FOUND: EXT Texture Env combine support\n");
964 This
->gl_info
.supported
[EXT_TEXTURE_ENV_COMBINE
] = TRUE
;
965 } else if (strcmp(ThisExtn
, "GL_EXT_texture_env_dot3") == 0) {
966 TRACE_(d3d_caps
)(" FOUND: EXT Dot3 support\n");
967 This
->gl_info
.supported
[EXT_TEXTURE_ENV_DOT3
] = TRUE
;
968 } else if (strcmp(ThisExtn
, "GL_EXT_texture_filter_anisotropic") == 0) {
969 TRACE_(d3d_caps
)(" FOUND: EXT Texture Anisotropic filter support\n");
970 This
->gl_info
.supported
[EXT_TEXTURE_FILTER_ANISOTROPIC
] = TRUE
;
971 } else if (strcmp(ThisExtn
, "GL_EXT_texture_lod") == 0) {
972 TRACE_(d3d_caps
)(" FOUND: EXT Texture LOD support\n");
973 This
->gl_info
.supported
[EXT_TEXTURE_LOD
] = TRUE
;
974 } else if (strcmp(ThisExtn
, "GL_EXT_texture_lod_bias") == 0) {
975 TRACE_(d3d_caps
)(" FOUND: EXT Texture LOD bias support\n");
976 This
->gl_info
.supported
[EXT_TEXTURE_LOD_BIAS
] = TRUE
;
977 } else if (strcmp(ThisExtn
, "GL_EXT_vertex_weighting") == 0) {
978 TRACE_(d3d_caps
)(" FOUND: EXT Vertex weighting support\n");
979 This
->gl_info
.supported
[EXT_VERTEX_WEIGHTING
] = TRUE
;
984 } else if (strstr(ThisExtn
, "GL_NV_fog_distance")) {
985 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Fog Distance support\n");
986 This
->gl_info
.supported
[NV_FOG_DISTANCE
] = TRUE
;
987 } else if (strstr(ThisExtn
, "GL_NV_fragment_program")) {
988 This
->gl_info
.ps_nv_version
= PS_VERSION_11
;
989 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Pixel Shader support - version=%02x\n", This
->gl_info
.ps_nv_version
);
990 } else if (strcmp(ThisExtn
, "GL_NV_register_combiners") == 0) {
991 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Register combiners (1) support\n");
992 This
->gl_info
.supported
[NV_REGISTER_COMBINERS
] = TRUE
;
993 } else if (strcmp(ThisExtn
, "GL_NV_register_combiners2") == 0) {
994 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Register combiners (2) support\n");
995 This
->gl_info
.supported
[NV_REGISTER_COMBINERS2
] = TRUE
;
996 } else if (strcmp(ThisExtn
, "GL_NV_texgen_reflection") == 0) {
997 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Texture Gen Reflection support\n");
998 This
->gl_info
.supported
[NV_TEXGEN_REFLECTION
] = TRUE
;
999 } else if (strcmp(ThisExtn
, "GL_NV_texture_env_combine4") == 0) {
1000 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Texture Env combine (4) support\n");
1001 This
->gl_info
.supported
[NV_TEXTURE_ENV_COMBINE4
] = TRUE
;
1002 } else if (strcmp(ThisExtn
, "GL_NV_texture_shader") == 0) {
1003 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Texture Shader (1) support\n");
1004 This
->gl_info
.supported
[NV_TEXTURE_SHADER
] = TRUE
;
1005 } else if (strcmp(ThisExtn
, "GL_NV_texture_shader2") == 0) {
1006 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Texture Shader (2) support\n");
1007 This
->gl_info
.supported
[NV_TEXTURE_SHADER2
] = TRUE
;
1008 } else if (strcmp(ThisExtn
, "GL_NV_texture_shader3") == 0) {
1009 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Texture Shader (3) support\n");
1010 This
->gl_info
.supported
[NV_TEXTURE_SHADER3
] = TRUE
;
1011 } else if (strstr(ThisExtn
, "GL_NV_vertex_program")) {
1012 This
->gl_info
.vs_nv_version
= max(This
->gl_info
.vs_nv_version
, (0 == strcmp(ThisExtn
, "GL_NV_vertex_program1_1")) ? VS_VERSION_11
: VS_VERSION_10
);
1013 This
->gl_info
.vs_nv_version
= max(This
->gl_info
.vs_nv_version
, (0 == strcmp(ThisExtn
, "GL_NV_vertex_program2")) ? VS_VERSION_20
: VS_VERSION_10
);
1014 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Vertex Shader support - version=%02x\n", This
->gl_info
.vs_nv_version
);
1015 This
->gl_info
.supported
[NV_VERTEX_PROGRAM
] = TRUE
;
1021 } else if (strcmp(ThisExtn
, "GL_ATI_texture_env_combine3") == 0) {
1022 TRACE_(d3d_caps
)(" FOUND: ATI Texture Env combine (3) support\n");
1023 This
->gl_info
.supported
[ATI_TEXTURE_ENV_COMBINE3
] = TRUE
;
1024 } else if (strcmp(ThisExtn
, "GL_ATI_texture_mirror_once") == 0) {
1025 TRACE_(d3d_caps
)(" FOUND: ATI Texture Mirror Once support\n");
1026 This
->gl_info
.supported
[ATI_TEXTURE_MIRROR_ONCE
] = TRUE
;
1027 } else if (strcmp(ThisExtn
, "GL_EXT_vertex_shader") == 0) {
1028 This
->gl_info
.vs_ati_version
= VS_VERSION_11
;
1029 TRACE_(d3d_caps
)(" FOUND: ATI (EXT) Vertex Shader support - version=%02x\n", This
->gl_info
.vs_ati_version
);
1030 This
->gl_info
.supported
[EXT_VERTEX_SHADER
] = TRUE
;
1034 if (*GL_Extensions
== ' ') GL_Extensions
++;
1038 #define USE_GL_FUNC(type, pfn) This->gl_info.pfn = (type) glXGetProcAddressARB(#pfn);
1042 if (display
!= NULL
) {
1043 GLX_Extensions
= glXQueryExtensionsString(display
, DefaultScreen(display
));
1044 TRACE_(d3d_caps
)("GLX_Extensions reported:\n");
1046 if (NULL
== GLX_Extensions
) {
1047 ERR(" GLX_Extensions returns NULL\n");
1049 while (*GLX_Extensions
!= 0x00) {
1050 const char *Start
= GLX_Extensions
;
1053 memset(ThisExtn
, 0x00, sizeof(ThisExtn
));
1054 while (*GLX_Extensions
!= ' ' && *GLX_Extensions
!= 0x00) {
1057 memcpy(ThisExtn
, Start
, (GLX_Extensions
- Start
));
1058 TRACE_(d3d_caps
)("- %s\n", ThisExtn
);
1059 if (*GLX_Extensions
== ' ') GLX_Extensions
++;
1064 #define USE_GL_FUNC(type, pfn) This->gl_info.pfn = (type) glXGetProcAddressARB(#pfn);
1068 /* Only save the values obtained when a display is provided */
1069 if (display
!= NULL
) This
->isGLInfoValid
= TRUE
;
1073 HRESULT WINAPI
IDirect3D8Impl_CreateDevice (LPDIRECT3D8 iface
,
1074 UINT Adapter
, D3DDEVTYPE DeviceType
, HWND hFocusWindow
,
1075 DWORD BehaviourFlags
, D3DPRESENT_PARAMETERS
* pPresentationParameters
,
1076 IDirect3DDevice8
** ppReturnedDeviceInterface
) {
1077 IDirect3DDevice8Impl
*object
;
1080 XVisualInfo
template;
1083 IDirect3D8Impl
*This
= (IDirect3D8Impl
*)iface
;
1084 TRACE("(%p)->(Adptr:%d, DevType: %x, FocusHwnd: %p, BehFlags: %lx, PresParms: %p, RetDevInt: %p)\n", This
, Adapter
, DeviceType
,
1085 hFocusWindow
, BehaviourFlags
, pPresentationParameters
, ppReturnedDeviceInterface
);
1087 if (Adapter
>= IDirect3D8Impl_GetAdapterCount(iface
)) {
1088 return D3DERR_INVALIDCALL
;
1091 /* Allocate the storage for the device */
1092 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DDevice8Impl
));
1093 if (NULL
== object
) {
1094 return D3DERR_OUTOFVIDEOMEMORY
;
1096 object
->lpVtbl
= &Direct3DDevice8_Vtbl
;
1098 object
->direct3d8
= This
;
1099 /** The device AddRef the direct3d8 Interface else crash in propers clients codes */
1100 IDirect3D8_AddRef((LPDIRECT3D8
) object
->direct3d8
);
1102 /** use StateBlock Factory here, for creating the startup stateBlock */
1103 object
->StateBlock
= NULL
;
1104 IDirect3DDeviceImpl_CreateStateBlock(object
, D3DSBT_ALL
, NULL
);
1105 object
->UpdateStateBlock
= object
->StateBlock
;
1107 /* Save the creation parameters */
1108 object
->CreateParms
.AdapterOrdinal
= Adapter
;
1109 object
->CreateParms
.DeviceType
= DeviceType
;
1110 object
->CreateParms
.hFocusWindow
= hFocusWindow
;
1111 object
->CreateParms
.BehaviorFlags
= BehaviourFlags
;
1113 *ppReturnedDeviceInterface
= (LPDIRECT3DDEVICE8
) object
;
1115 /* Initialize settings */
1116 object
->PresentParms
.BackBufferCount
= 1; /* Opengl only supports one? */
1117 object
->adapterNo
= Adapter
;
1118 object
->devType
= DeviceType
;
1120 /* Initialize openGl - Note the visual is chosen as the window is created and the glcontext cannot
1121 use different properties after that point in time. FIXME: How to handle when requested format
1122 doesn't match actual visual? Cannot choose one here - code removed as it ONLY works if the one
1123 it chooses is identical to the one already being used! */
1124 /* FIXME: Handle stencil appropriately via EnableAutoDepthStencil / AutoDepthStencilFormat */
1126 /* Which hwnd are we using? */
1127 whichHWND
= pPresentationParameters
->hDeviceWindow
;
1129 whichHWND
= hFocusWindow
;
1131 object
->win_handle
= whichHWND
;
1132 object
->win
= (Window
)GetPropA( whichHWND
, "__wine_x11_client_window" );
1134 hDc
= GetDC(whichHWND
);
1135 object
->display
= get_display(hDc
);
1137 TRACE("(%p)->(DepthStencil:(%u,%s), BackBufferFormat:(%u,%s))\n", This
,
1138 pPresentationParameters
->AutoDepthStencilFormat
, debug_d3dformat(pPresentationParameters
->AutoDepthStencilFormat
),
1139 pPresentationParameters
->BackBufferFormat
, debug_d3dformat(pPresentationParameters
->BackBufferFormat
));
1143 /* Create a context based off the properties of the existing visual */
1144 template.visualid
= (VisualID
)GetPropA(GetDesktopWindow(), "__wine_x11_visual_id");
1145 object
->visInfo
= XGetVisualInfo(object
->display
, VisualIDMask
, &template, &num
);
1146 if (NULL
== object
->visInfo
) {
1147 ERR("cannot really get XVisual\n");
1149 return D3DERR_NOTAVAILABLE
;
1151 object
->glCtx
= glXCreateContext(object
->display
, object
->visInfo
, NULL
, GL_TRUE
);
1152 if (NULL
== object
->glCtx
) {
1153 ERR("cannot create glxContext\n");
1155 return D3DERR_NOTAVAILABLE
;
1159 ReleaseDC(whichHWND
, hDc
);
1161 if (object
->glCtx
== NULL
) {
1162 ERR("Error in context creation !\n");
1163 return D3DERR_INVALIDCALL
;
1165 TRACE("Context created (HWND=%p, glContext=%p, Window=%ld, VisInfo=%p)\n",
1166 whichHWND
, object
->glCtx
, object
->win
, object
->visInfo
);
1169 /* If not windowed, need to go fullscreen, and resize the HWND to the appropriate */
1171 if (!pPresentationParameters
->Windowed
) {
1176 memset(&devmode
, 0, sizeof(DEVMODEW
));
1177 devmode
.dmFields
= DM_BITSPERPEL
| DM_PELSWIDTH
| DM_PELSHEIGHT
;
1178 MultiByteToWideChar(CP_ACP
, 0, "Gamers CG", -1, devmode
.dmDeviceName
, CCHDEVICENAME
);
1179 hdc
= CreateDCA("DISPLAY", NULL
, NULL
, NULL
);
1180 bpp
= GetDeviceCaps(hdc
, BITSPIXEL
);
1182 devmode
.dmBitsPerPel
= (bpp
>= 24) ? 32 : bpp
;/*Stupid XVidMode cannot change bpp D3DFmtGetBpp(object, pPresentationParameters->BackBufferFormat);*/
1183 devmode
.dmPelsWidth
= pPresentationParameters
->BackBufferWidth
;
1184 devmode
.dmPelsHeight
= pPresentationParameters
->BackBufferHeight
;
1185 ChangeDisplaySettingsExW(devmode
.dmDeviceName
, &devmode
, object
->win_handle
, CDS_FULLSCREEN
, NULL
);
1187 FIXME("Requested full screen support not implemented, expect windowed operation\n");
1190 /* Make popup window */
1191 SetWindowLongA(whichHWND
, GWL_STYLE
, WS_POPUP
);
1192 SetWindowPos(object
->win_handle
, HWND_TOP
, 0, 0,
1193 pPresentationParameters
->BackBufferWidth
,
1194 pPresentationParameters
->BackBufferHeight
, SWP_SHOWWINDOW
| SWP_FRAMECHANGED
);
1197 TRACE("Creating back buffer\n");
1198 /* MSDN: If Windowed is TRUE and either of the BackBufferWidth/Height values is zero,
1199 then the corresponding dimension of the client area of the hDeviceWindow
1200 (or the focus window, if hDeviceWindow is NULL) is taken. */
1201 if (pPresentationParameters
->Windowed
&& ((pPresentationParameters
->BackBufferWidth
== 0) ||
1202 (pPresentationParameters
->BackBufferHeight
== 0))) {
1205 GetClientRect(whichHWND
, &Rect
);
1207 if (pPresentationParameters
->BackBufferWidth
== 0) {
1208 pPresentationParameters
->BackBufferWidth
= Rect
.right
;
1209 TRACE("Updating width to %d\n", pPresentationParameters
->BackBufferWidth
);
1211 if (pPresentationParameters
->BackBufferHeight
== 0) {
1212 pPresentationParameters
->BackBufferHeight
= Rect
.bottom
;
1213 TRACE("Updating height to %d\n", pPresentationParameters
->BackBufferHeight
);
1217 /* Save the presentation parms now filled in correctly */
1218 memcpy(&object
->PresentParms
, pPresentationParameters
, sizeof(D3DPRESENT_PARAMETERS
));
1221 IDirect3DDevice8Impl_CreateRenderTarget((LPDIRECT3DDEVICE8
) object
,
1222 pPresentationParameters
->BackBufferWidth
,
1223 pPresentationParameters
->BackBufferHeight
,
1224 pPresentationParameters
->BackBufferFormat
,
1225 pPresentationParameters
->MultiSampleType
,
1227 (LPDIRECT3DSURFACE8
*) &object
->frontBuffer
);
1229 IDirect3DDevice8Impl_CreateRenderTarget((LPDIRECT3DDEVICE8
) object
,
1230 pPresentationParameters
->BackBufferWidth
,
1231 pPresentationParameters
->BackBufferHeight
,
1232 pPresentationParameters
->BackBufferFormat
,
1233 pPresentationParameters
->MultiSampleType
,
1235 (LPDIRECT3DSURFACE8
*) &object
->backBuffer
);
1237 if (pPresentationParameters
->EnableAutoDepthStencil
) {
1238 IDirect3DDevice8Impl_CreateDepthStencilSurface((LPDIRECT3DDEVICE8
) object
,
1239 pPresentationParameters
->BackBufferWidth
,
1240 pPresentationParameters
->BackBufferHeight
,
1241 pPresentationParameters
->AutoDepthStencilFormat
,
1242 D3DMULTISAMPLE_NONE
,
1243 (LPDIRECT3DSURFACE8
*) &object
->depthStencilBuffer
);
1245 object
->depthStencilBuffer
= NULL
;
1247 TRACE("FrontBuf @ %p, BackBuf @ %p, DepthStencil @ %p\n",object
->frontBuffer
, object
->backBuffer
, object
->depthStencilBuffer
);
1249 /* init the default renderTarget management */
1250 object
->drawable
= object
->win
;
1251 object
->render_ctx
= object
->glCtx
;
1252 object
->renderTarget
= object
->backBuffer
;
1253 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8
) object
->renderTarget
);
1254 object
->stencilBufferTarget
= object
->depthStencilBuffer
;
1255 if (NULL
!= object
->stencilBufferTarget
) {
1256 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8
) object
->stencilBufferTarget
);
1261 if (glXMakeCurrent(object
->display
, object
->win
, object
->glCtx
) == False
) {
1262 ERR("Error in setting current context (context %p drawable %ld)!\n", object
->glCtx
, object
->win
);
1264 checkGLcall("glXMakeCurrent");
1266 /* Clear the screen */
1267 glClearColor(1.0, 0.0, 0.0, 0.0);
1268 checkGLcall("glClearColor");
1269 glColor3f(1.0, 1.0, 1.0);
1270 checkGLcall("glColor3f");
1272 glEnable(GL_LIGHTING
);
1273 checkGLcall("glEnable");
1275 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER
, GL_TRUE
);
1276 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);");
1278 glTexEnvf(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_COMBINE_EXT
);
1279 checkGLcall("glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);");
1281 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL
, GL_SEPARATE_SPECULAR_COLOR
);
1282 checkGLcall("glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);");
1285 * Initialize openGL extension related variables
1286 * with Default values
1288 IDirect3D8Impl_FillGLCaps(iface
, object
->display
);
1290 /* Setup all the devices defaults */
1291 IDirect3DDeviceImpl_InitStartupStateBlock(object
);
1295 { /* Set a default viewport */
1299 vp
.Width
= pPresentationParameters
->BackBufferWidth
;
1300 vp
.Height
= pPresentationParameters
->BackBufferHeight
;
1303 IDirect3DDevice8Impl_SetViewport((LPDIRECT3DDEVICE8
) object
, &vp
);
1306 /* Initialize the current view state */
1307 object
->modelview_valid
= 1;
1308 object
->proj_valid
= 0;
1309 object
->view_ident
= 1;
1310 object
->last_was_rhw
= 0;
1311 glGetIntegerv(GL_MAX_LIGHTS
, &object
->maxConcurrentLights
);
1312 TRACE("(%p,%d) All defaults now set up, leaving CreateDevice with %p\n", This
, Adapter
, object
);
1314 /* Clear the screen */
1315 IDirect3DDevice8Impl_Clear((LPDIRECT3DDEVICE8
) object
, 0, NULL
, D3DCLEAR_STENCIL
|D3DCLEAR_ZBUFFER
|D3DCLEAR_TARGET
, 0x00, 1.0, 0);
1320 IDirect3D8Vtbl Direct3D8_Vtbl
=
1322 IDirect3D8Impl_QueryInterface
,
1323 IDirect3D8Impl_AddRef
,
1324 IDirect3D8Impl_Release
,
1325 IDirect3D8Impl_RegisterSoftwareDevice
,
1326 IDirect3D8Impl_GetAdapterCount
,
1327 IDirect3D8Impl_GetAdapterIdentifier
,
1328 IDirect3D8Impl_GetAdapterModeCount
,
1329 IDirect3D8Impl_EnumAdapterModes
,
1330 IDirect3D8Impl_GetAdapterDisplayMode
,
1331 IDirect3D8Impl_CheckDeviceType
,
1332 IDirect3D8Impl_CheckDeviceFormat
,
1333 IDirect3D8Impl_CheckDeviceMultiSampleType
,
1334 IDirect3D8Impl_CheckDepthStencilMatch
,
1335 IDirect3D8Impl_GetDeviceCaps
,
1336 IDirect3D8Impl_GetAdapterMonitor
,
1337 IDirect3D8Impl_CreateDevice