2 * IWineD3D 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
23 /* Compile time diagnostics: */
25 /* Uncomment this to force only a single display mode to be exposed: */
26 /*#define DEBUG_SINGLE_MODE*/
30 #include "wined3d_private.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(d3d
);
33 WINE_DECLARE_DEBUG_CHANNEL(d3d_caps
);
34 #define GLINFO_LOCATION This->gl_info
36 /**********************************************************
37 * Utility functions follow
38 **********************************************************/
40 /* x11drv GDI escapes */
41 #define X11DRV_ESCAPE 6789
42 enum x11drv_escape_codes
44 X11DRV_GET_DISPLAY
, /* get X11 display for a DC */
45 X11DRV_GET_DRAWABLE
, /* get current drawable for a DC */
46 X11DRV_GET_FONT
, /* get current X font for a DC */
49 /* retrieve the X display to use on a given DC */
50 inline static Display
*get_display( HDC hdc
)
53 enum x11drv_escape_codes escape
= X11DRV_GET_DISPLAY
;
55 if (!ExtEscape( hdc
, X11DRV_ESCAPE
, sizeof(escape
), (LPCSTR
)&escape
,
56 sizeof(display
), (LPSTR
)&display
)) display
= NULL
;
61 * Note: GL seems to trap if GetDeviceCaps is called before any HWND's created
62 * ie there is no GL Context - Get a default rendering context to enable the
63 * function query some info from GL
65 static WineD3D_Context
* WineD3D_CreateFakeGLContext(void) {
66 static WineD3D_Context ctx
= { NULL
, NULL
, NULL
, 0, 0 };
67 WineD3D_Context
* ret
= NULL
;
69 if (glXGetCurrentContext() == NULL
) {
70 BOOL gotContext
= FALSE
;
77 XWindowAttributes win_attr
;
79 TRACE_(d3d_caps
)("Creating Fake GL Context\n");
81 ctx
.drawable
= (Drawable
) GetPropA(GetDesktopWindow(), "__wine_x11_whole_window");
84 device_context
= GetDC(0);
85 ctx
.display
= get_display(device_context
);
86 ReleaseDC(0, device_context
);
88 /* Get the X visual */
90 if (XGetWindowAttributes(ctx
.display
, ctx
.drawable
, &win_attr
)) {
91 visual
= win_attr
.visual
;
93 visual
= DefaultVisual(ctx
.display
, DefaultScreen(ctx
.display
));
95 template.visualid
= XVisualIDFromVisual(visual
);
96 ctx
.visInfo
= XGetVisualInfo(ctx
.display
, VisualIDMask
, &template, &num
);
97 if (ctx
.visInfo
== NULL
) {
99 WARN_(d3d_caps
)("Error creating visual info for capabilities initialization\n");
103 /* Create a GL context */
105 ctx
.glCtx
= glXCreateContext(ctx
.display
, ctx
.visInfo
, NULL
, GL_TRUE
);
107 if (ctx
.glCtx
== NULL
) {
109 WARN_(d3d_caps
)("Error creating default context for capabilities initialization\n");
114 /* Make it the current GL context */
115 if (!failed
&& glXMakeCurrent(ctx
.display
, ctx
.drawable
, ctx
.glCtx
) == False
) {
116 glXDestroyContext(ctx
.display
, ctx
.glCtx
);
118 WARN_(d3d_caps
)("Error setting default context as current for capabilities initialization\n");
122 /* It worked! Wow... */
132 if (ctx
.ref
> 0) ret
= &ctx
;
135 if (NULL
!= ret
) InterlockedIncrement(&ret
->ref
);
139 static void WineD3D_ReleaseFakeGLContext(WineD3D_Context
* ctx
) {
140 /* If we created a dummy context, throw it away */
142 if (0 == InterlockedDecrement(&ctx
->ref
)) {
143 glXMakeCurrent(ctx
->display
, None
, NULL
);
144 glXDestroyContext(ctx
->display
, ctx
->glCtx
);
152 static BOOL
IWineD3DImpl_FillGLCaps(WineD3D_GL_Info
*gl_info
, Display
* display
) {
153 const char *GL_Extensions
= NULL
;
154 const char *GLX_Extensions
= NULL
;
155 const char *gl_string
= NULL
;
156 const char *gl_string_cursor
= NULL
;
161 TRACE_(d3d_caps
)("(%p, %p)\n", gl_info
, display
);
163 /* Fill in the GL info retrievable depending on the display */
164 if (NULL
!= display
) {
165 test
= glXQueryVersion(display
, &major
, &minor
);
166 gl_info
->glx_version
= ((major
& 0x0000FFFF) << 16) | (minor
& 0x0000FFFF);
167 gl_string
= glXGetClientString(display
, GLX_VENDOR
);
169 gl_string
= glGetString(GL_VENDOR
);
172 /* Fill in the GL vendor */
173 if (strstr(gl_string
, "NVIDIA")) {
174 gl_info
->gl_vendor
= VENDOR_NVIDIA
;
175 } else if (strstr(gl_string
, "ATI")) {
176 gl_info
->gl_vendor
= VENDOR_ATI
;
178 gl_info
->gl_vendor
= VENDOR_WINE
;
181 TRACE_(d3d_caps
)("found GL_VENDOR (%s)->(0x%04x)\n", debugstr_a(gl_string
), gl_info
->gl_vendor
);
183 /* Parse the GL_VERSION field into major and minor information */
184 gl_string
= glGetString(GL_VERSION
);
185 switch (gl_info
->gl_vendor
) {
187 gl_string_cursor
= strstr(gl_string
, "NVIDIA");
188 gl_string_cursor
= strstr(gl_string_cursor
, " ");
189 while (*gl_string_cursor
&& ' ' == *gl_string_cursor
) ++gl_string_cursor
;
190 if (*gl_string_cursor
) {
194 while (*gl_string_cursor
<= '9' && *gl_string_cursor
>= '0') {
195 tmp
[cursor
++] = *gl_string_cursor
;
201 if (*gl_string_cursor
!= '.') WARN_(d3d_caps
)("malformed GL_VERSION (%s)\n", debugstr_a(gl_string
));
204 while (*gl_string_cursor
<= '9' && *gl_string_cursor
>= '0') {
205 tmp
[cursor
++] = *gl_string_cursor
;
215 gl_string_cursor
= strchr(gl_string
, '-');
216 if (gl_string_cursor
) {
220 /* Check if version number is of the form x.y.z */
221 if (*gl_string_cursor
> '9' && *gl_string_cursor
< '0')
223 if (!error
&& *(gl_string_cursor
+2) > '9' && *(gl_string_cursor
+2) < '0')
225 if (!error
&& *(gl_string_cursor
+4) > '9' && *(gl_string_cursor
+4) < '0')
227 if (!error
&& *(gl_string_cursor
+1) != '.' && *(gl_string_cursor
+3) != '.')
230 /* Mark version number as malformed */
232 gl_string_cursor
= 0;
235 if (!gl_string_cursor
)
236 WARN_(d3d_caps
)("malformed GL_VERSION (%s)\n", debugstr_a(gl_string
));
238 major
= *gl_string_cursor
- '0';
239 minor
= (*(gl_string_cursor
+2) - '0') * 256 + (*(gl_string_cursor
+4) - '0');
247 gl_info
->gl_driver_version
= MAKEDWORD_VERSION(major
, minor
);
248 TRACE_(d3d_caps
)("found GL_VERSION (%s)->(0x%08lx)\n", debugstr_a(gl_string
), gl_info
->gl_driver_version
);
250 /* Fill in the renderer information */
251 gl_string
= glGetString(GL_RENDERER
);
252 strcpy(gl_info
->gl_renderer
, gl_string
);
254 switch (gl_info
->gl_vendor
) {
256 if (strstr(gl_info
->gl_renderer
, "GeForce4 Ti")) {
257 gl_info
->gl_card
= CARD_NVIDIA_GEFORCE4_TI4600
;
258 } else if (strstr(gl_info
->gl_renderer
, "GeForceFX")) {
259 gl_info
->gl_card
= CARD_NVIDIA_GEFORCEFX_5900ULTRA
;
261 gl_info
->gl_card
= CARD_NVIDIA_GEFORCE4_TI4600
;
266 if (strstr(gl_info
->gl_renderer
, "RADEON 9800 PRO")) {
267 gl_info
->gl_card
= CARD_ATI_RADEON_9800PRO
;
268 } else if (strstr(gl_info
->gl_renderer
, "RADEON 9700 PRO")) {
269 gl_info
->gl_card
= CARD_ATI_RADEON_9700PRO
;
271 gl_info
->gl_card
= CARD_ATI_RADEON_8500
;
276 gl_info
->gl_card
= CARD_WINE
;
280 TRACE_(d3d_caps
)("found GL_RENDERER (%s)->(0x%04x)\n", debugstr_a(gl_info
->gl_renderer
), gl_info
->gl_card
);
283 * Initialize openGL extension related variables
284 * with Default values
286 memset(&gl_info
->supported
, 0, sizeof(gl_info
->supported
));
287 gl_info
->max_textures
= 1;
288 gl_info
->ps_arb_version
= PS_VERSION_NOT_SUPPORTED
;
289 gl_info
->vs_arb_version
= VS_VERSION_NOT_SUPPORTED
;
290 gl_info
->vs_nv_version
= VS_VERSION_NOT_SUPPORTED
;
291 gl_info
->vs_ati_version
= VS_VERSION_NOT_SUPPORTED
;
293 /* Now work out what GL support this card really has */
294 #define USE_GL_FUNC(type, pfn) gl_info->pfn = NULL;
298 /* Retrieve opengl defaults */
299 glGetIntegerv(GL_MAX_CLIP_PLANES
, &gl_max
);
300 gl_info
->max_clipplanes
= min(D3DMAXUSERCLIPPLANES
, gl_max
);
301 TRACE_(d3d_caps
)("ClipPlanes support - num Planes=%d\n", gl_max
);
303 glGetIntegerv(GL_MAX_LIGHTS
, &gl_max
);
304 gl_info
->max_lights
= gl_max
;
305 TRACE_(d3d_caps
)("Lights support - max lights=%d\n", gl_max
);
307 /* Parse the gl supported features, in theory enabling parts of our code appropriately */
308 GL_Extensions
= glGetString(GL_EXTENSIONS
);
309 TRACE_(d3d_caps
)("GL_Extensions reported:\n");
311 if (NULL
== GL_Extensions
) {
312 ERR(" GL_Extensions returns NULL\n");
314 while (*GL_Extensions
!= 0x00) {
315 const char *Start
= GL_Extensions
;
318 memset(ThisExtn
, 0x00, sizeof(ThisExtn
));
319 while (*GL_Extensions
!= ' ' && *GL_Extensions
!= 0x00) {
322 memcpy(ThisExtn
, Start
, (GL_Extensions
- Start
));
323 TRACE_(d3d_caps
)("- %s\n", ThisExtn
);
328 if (strcmp(ThisExtn
, "GL_ARB_fragment_program") == 0) {
329 gl_info
->ps_arb_version
= PS_VERSION_11
;
330 TRACE_(d3d_caps
)(" FOUND: ARB Pixel Shader support - version=%02x\n", gl_info
->ps_arb_version
);
331 gl_info
->supported
[ARB_FRAGMENT_PROGRAM
] = TRUE
;
332 } else if (strcmp(ThisExtn
, "GL_ARB_multisample") == 0) {
333 TRACE_(d3d_caps
)(" FOUND: ARB Multisample support\n");
334 gl_info
->supported
[ARB_MULTISAMPLE
] = TRUE
;
335 } else if (strcmp(ThisExtn
, "GL_ARB_multitexture") == 0) {
336 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB
, &gl_max
);
337 TRACE_(d3d_caps
)(" FOUND: ARB Multitexture support - GL_MAX_TEXTURE_UNITS_ARB=%u\n", gl_max
);
338 gl_info
->supported
[ARB_MULTITEXTURE
] = TRUE
;
339 gl_info
->max_textures
= min(8, gl_max
);
340 } else if (strcmp(ThisExtn
, "GL_ARB_texture_cube_map") == 0) {
341 TRACE_(d3d_caps
)(" FOUND: ARB Texture Cube Map support\n");
342 gl_info
->supported
[ARB_TEXTURE_CUBE_MAP
] = TRUE
;
343 TRACE_(d3d_caps
)(" IMPLIED: NVIDIA (NV) Texture Gen Reflection support\n");
344 gl_info
->supported
[NV_TEXGEN_REFLECTION
] = TRUE
;
345 } else if (strcmp(ThisExtn
, "GL_ARB_texture_compression") == 0) {
346 TRACE_(d3d_caps
)(" FOUND: ARB Texture Compression support\n");
347 gl_info
->supported
[ARB_TEXTURE_COMPRESSION
] = TRUE
;
348 } else if (strcmp(ThisExtn
, "GL_ARB_texture_env_add") == 0) {
349 TRACE_(d3d_caps
)(" FOUND: ARB Texture Env Add support\n");
350 gl_info
->supported
[ARB_TEXTURE_ENV_ADD
] = TRUE
;
351 } else if (strcmp(ThisExtn
, "GL_ARB_texture_env_combine") == 0) {
352 TRACE_(d3d_caps
)(" FOUND: ARB Texture Env combine support\n");
353 gl_info
->supported
[ARB_TEXTURE_ENV_COMBINE
] = TRUE
;
354 } else if (strcmp(ThisExtn
, "GL_ARB_texture_env_dot3") == 0) {
355 TRACE_(d3d_caps
)(" FOUND: ARB Dot3 support\n");
356 gl_info
->supported
[ARB_TEXTURE_ENV_DOT3
] = TRUE
;
357 } else if (strcmp(ThisExtn
, "GL_ARB_texture_border_clamp") == 0) {
358 TRACE_(d3d_caps
)(" FOUND: ARB Texture border clamp support\n");
359 gl_info
->supported
[ARB_TEXTURE_BORDER_CLAMP
] = TRUE
;
360 } else if (strcmp(ThisExtn
, "GL_ARB_texture_mirrored_repeat") == 0) {
361 TRACE_(d3d_caps
)(" FOUND: ARB Texture mirrored repeat support\n");
362 gl_info
->supported
[ARB_TEXTURE_MIRRORED_REPEAT
] = TRUE
;
363 } else if (strstr(ThisExtn
, "GL_ARB_vertex_program")) {
364 gl_info
->vs_arb_version
= VS_VERSION_11
;
365 TRACE_(d3d_caps
)(" FOUND: ARB Vertex Shader support - version=%02x\n", gl_info
->vs_arb_version
);
366 gl_info
->supported
[ARB_VERTEX_PROGRAM
] = TRUE
;
367 } else if (strcmp(ThisExtn
, "GL_ARB_vertex_blend") == 0) {
368 TRACE_(d3d_caps
)(" FOUND: ARB Vertex Blend support\n");
369 gl_info
->supported
[ARB_VERTEX_BLEND
] = TRUE
;
370 } else if (strcmp(ThisExtn
, "GL_ARB_vertex_buffer_object") == 0) {
371 TRACE_(d3d_caps
)(" FOUND: ARB Vertex Buffer support\n");
372 gl_info
->supported
[ARB_VERTEX_BUFFER_OBJECT
] = TRUE
;
377 } else if (strcmp(ThisExtn
, "GL_EXT_fog_coord") == 0) {
378 TRACE_(d3d_caps
)(" FOUND: EXT Fog coord support\n");
379 gl_info
->supported
[EXT_FOG_COORD
] = TRUE
;
380 } else if (strcmp(ThisExtn
, "GL_EXT_paletted_texture") == 0) { /* handle paletted texture extensions */
381 TRACE_(d3d_caps
)(" FOUND: EXT Paletted texture support\n");
382 gl_info
->supported
[EXT_PALETTED_TEXTURE
] = TRUE
;
383 } else if (strcmp(ThisExtn
, "GL_EXT_point_parameters") == 0) {
384 TRACE_(d3d_caps
)(" FOUND: EXT Point parameters support\n");
385 gl_info
->supported
[EXT_POINT_PARAMETERS
] = TRUE
;
386 } else if (strcmp(ThisExtn
, "GL_EXT_secondary_color") == 0) {
387 TRACE_(d3d_caps
)(" FOUND: EXT Secondary coord support\n");
388 gl_info
->supported
[EXT_SECONDARY_COLOR
] = TRUE
;
389 } else if (strcmp(ThisExtn
, "GL_EXT_stencil_wrap") == 0) {
390 TRACE_(d3d_caps
)(" FOUND: EXT Stencil wrap support\n");
391 gl_info
->supported
[EXT_STENCIL_WRAP
] = TRUE
;
392 } else if (strcmp(ThisExtn
, "GL_EXT_texture_compression_s3tc") == 0) {
393 TRACE_(d3d_caps
)(" FOUND: EXT Texture S3TC compression support\n");
394 gl_info
->supported
[EXT_TEXTURE_COMPRESSION_S3TC
] = TRUE
;
395 } else if (strcmp(ThisExtn
, "GL_EXT_texture_env_add") == 0) {
396 TRACE_(d3d_caps
)(" FOUND: EXT Texture Env Add support\n");
397 gl_info
->supported
[EXT_TEXTURE_ENV_ADD
] = TRUE
;
398 } else if (strcmp(ThisExtn
, "GL_EXT_texture_env_combine") == 0) {
399 TRACE_(d3d_caps
)(" FOUND: EXT Texture Env combine support\n");
400 gl_info
->supported
[EXT_TEXTURE_ENV_COMBINE
] = TRUE
;
401 } else if (strcmp(ThisExtn
, "GL_EXT_texture_env_dot3") == 0) {
402 TRACE_(d3d_caps
)(" FOUND: EXT Dot3 support\n");
403 gl_info
->supported
[EXT_TEXTURE_ENV_DOT3
] = TRUE
;
404 } else if (strcmp(ThisExtn
, "GL_EXT_texture_filter_anisotropic") == 0) {
405 TRACE_(d3d_caps
)(" FOUND: EXT Texture Anisotropic filter support\n");
406 gl_info
->supported
[EXT_TEXTURE_FILTER_ANISOTROPIC
] = TRUE
;
407 } else if (strcmp(ThisExtn
, "GL_EXT_texture_lod") == 0) {
408 TRACE_(d3d_caps
)(" FOUND: EXT Texture LOD support\n");
409 gl_info
->supported
[EXT_TEXTURE_LOD
] = TRUE
;
410 } else if (strcmp(ThisExtn
, "GL_EXT_texture_lod_bias") == 0) {
411 TRACE_(d3d_caps
)(" FOUND: EXT Texture LOD bias support\n");
412 gl_info
->supported
[EXT_TEXTURE_LOD_BIAS
] = TRUE
;
413 } else if (strcmp(ThisExtn
, "GL_EXT_vertex_weighting") == 0) {
414 TRACE_(d3d_caps
)(" FOUND: EXT Vertex weighting support\n");
415 gl_info
->supported
[EXT_VERTEX_WEIGHTING
] = TRUE
;
420 } else if (strstr(ThisExtn
, "GL_NV_fog_distance")) {
421 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Fog Distance support\n");
422 gl_info
->supported
[NV_FOG_DISTANCE
] = TRUE
;
423 } else if (strstr(ThisExtn
, "GL_NV_fragment_program")) {
424 gl_info
->ps_nv_version
= PS_VERSION_11
;
425 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Pixel Shader support - version=%02x\n", gl_info
->ps_nv_version
);
426 } else if (strcmp(ThisExtn
, "GL_NV_register_combiners") == 0) {
427 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Register combiners (1) support\n");
428 gl_info
->supported
[NV_REGISTER_COMBINERS
] = TRUE
;
429 } else if (strcmp(ThisExtn
, "GL_NV_register_combiners2") == 0) {
430 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Register combiners (2) support\n");
431 gl_info
->supported
[NV_REGISTER_COMBINERS2
] = TRUE
;
432 } else if (strcmp(ThisExtn
, "GL_NV_texgen_reflection") == 0) {
433 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Texture Gen Reflection support\n");
434 gl_info
->supported
[NV_TEXGEN_REFLECTION
] = TRUE
;
435 } else if (strcmp(ThisExtn
, "GL_NV_texture_env_combine4") == 0) {
436 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Texture Env combine (4) support\n");
437 gl_info
->supported
[NV_TEXTURE_ENV_COMBINE4
] = TRUE
;
438 } else if (strcmp(ThisExtn
, "GL_NV_texture_shader") == 0) {
439 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Texture Shader (1) support\n");
440 gl_info
->supported
[NV_TEXTURE_SHADER
] = TRUE
;
441 } else if (strcmp(ThisExtn
, "GL_NV_texture_shader2") == 0) {
442 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Texture Shader (2) support\n");
443 gl_info
->supported
[NV_TEXTURE_SHADER2
] = TRUE
;
444 } else if (strcmp(ThisExtn
, "GL_NV_texture_shader3") == 0) {
445 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Texture Shader (3) support\n");
446 gl_info
->supported
[NV_TEXTURE_SHADER3
] = TRUE
;
447 } else if (strstr(ThisExtn
, "GL_NV_vertex_program")) {
448 gl_info
->vs_nv_version
= max(gl_info
->vs_nv_version
, (0 == strcmp(ThisExtn
, "GL_NV_vertex_program1_1")) ? VS_VERSION_11
: VS_VERSION_10
);
449 gl_info
->vs_nv_version
= max(gl_info
->vs_nv_version
, (0 == strcmp(ThisExtn
, "GL_NV_vertex_program2")) ? VS_VERSION_20
: VS_VERSION_10
);
450 TRACE_(d3d_caps
)(" FOUND: NVIDIA (NV) Vertex Shader support - version=%02x\n", gl_info
->vs_nv_version
);
451 gl_info
->supported
[NV_VERTEX_PROGRAM
] = TRUE
;
457 } else if (strcmp(ThisExtn
, "GL_ATI_texture_env_combine3") == 0) {
458 TRACE_(d3d_caps
)(" FOUND: ATI Texture Env combine (3) support\n");
459 gl_info
->supported
[ATI_TEXTURE_ENV_COMBINE3
] = TRUE
;
460 } else if (strcmp(ThisExtn
, "GL_ATI_texture_mirror_once") == 0) {
461 TRACE_(d3d_caps
)(" FOUND: ATI Texture Mirror Once support\n");
462 gl_info
->supported
[ATI_TEXTURE_MIRROR_ONCE
] = TRUE
;
463 } else if (strcmp(ThisExtn
, "GL_EXT_vertex_shader") == 0) {
464 gl_info
->vs_ati_version
= VS_VERSION_11
;
465 TRACE_(d3d_caps
)(" FOUND: ATI (EXT) Vertex Shader support - version=%02x\n", gl_info
->vs_ati_version
);
466 gl_info
->supported
[EXT_VERTEX_SHADER
] = TRUE
;
470 if (*GL_Extensions
== ' ') GL_Extensions
++;
474 #define USE_GL_FUNC(type, pfn) gl_info->pfn = (type) glXGetProcAddressARB(#pfn);
478 if (display
!= NULL
) {
479 GLX_Extensions
= glXQueryExtensionsString(display
, DefaultScreen(display
));
480 TRACE_(d3d_caps
)("GLX_Extensions reported:\n");
482 if (NULL
== GLX_Extensions
) {
483 ERR(" GLX_Extensions returns NULL\n");
485 while (*GLX_Extensions
!= 0x00) {
486 const char *Start
= GLX_Extensions
;
489 memset(ThisExtn
, 0x00, sizeof(ThisExtn
));
490 while (*GLX_Extensions
!= ' ' && *GLX_Extensions
!= 0x00) {
493 memcpy(ThisExtn
, Start
, (GLX_Extensions
- Start
));
494 TRACE_(d3d_caps
)("- %s\n", ThisExtn
);
495 if (*GLX_Extensions
== ' ') GLX_Extensions
++;
500 #define USE_GL_FUNC(type, pfn) gl_info->pfn = (type) glXGetProcAddressARB(#pfn);
504 /* Only save the values obtained when a display is provided */
505 if (display
!= NULL
) {
512 /**********************************************************
513 * IWineD3D implementation follows
514 **********************************************************/
516 UINT WINAPI
IWineD3DImpl_GetAdapterCount (IWineD3D
*iface
) {
517 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
519 /* FIXME: Set to one for now to imply the display */
520 TRACE_(d3d_caps
)("(%p): Mostly stub, only returns primary display\n", This
);
524 HRESULT WINAPI
IWineD3DImpl_RegisterSoftwareDevice(IWineD3D
*iface
, void* pInitializeFunction
) {
525 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
526 FIXME("(%p)->(%p): stub\n", This
, pInitializeFunction
);
530 HMONITOR WINAPI
IWineD3DImpl_GetAdapterMonitor(IWineD3D
*iface
, UINT Adapter
) {
531 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
532 FIXME_(d3d_caps
)("(%p)->(Adptr:%d)\n", This
, Adapter
);
533 if (Adapter
>= IWineD3DImpl_GetAdapterCount(iface
)) {
539 /* FIXME: GetAdapterModeCount and EnumAdapterModes currently only returns modes
540 of the same bpp but different resolutions */
542 /* Note: dx9 supplies a format. Calls from d3d8 supply D3DFMT_UNKNOWN */
543 UINT WINAPI
IWineD3DImpl_GetAdapterModeCount(IWineD3D
*iface
, UINT Adapter
, D3DFORMAT Format
) {
544 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
545 TRACE_(d3d_caps
)("(%p}->(Adapter: %d, Format: %s)\n", This
, Adapter
, debug_d3dformat(Format
));
547 if (Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
551 if (Adapter
== 0) { /* Display */
554 #if !defined( DEBUG_SINGLE_MODE )
557 /* Work out the current screen bpp */
558 HDC hdc
= CreateDCA("DISPLAY", NULL
, NULL
, NULL
);
559 int bpp
= GetDeviceCaps(hdc
, BITSPIXEL
);
562 while (EnumDisplaySettingsExW(NULL
, j
, &DevModeW
, 0)) {
569 case D3DFMT_X8R8G8B8
:
570 case D3DFMT_A8R8G8B8
:
571 if (min(DevModeW
.dmBitsPerPel
, bpp
) == 32) i
++;
572 if (min(DevModeW
.dmBitsPerPel
, bpp
) == 24) i
++;
574 case D3DFMT_X1R5G5B5
:
575 case D3DFMT_A1R5G5B5
:
577 if (min(DevModeW
.dmBitsPerPel
, bpp
) == 16) i
++;
580 /* Skip other modes as they do not match requested format */
588 TRACE_(d3d_caps
)("(%p}->(Adapter: %d) => %d (out of %d)\n", This
, Adapter
, i
, j
);
591 FIXME_(d3d_caps
)("Adapter not primary display\n");
596 /* Note: dx9 supplies a format. Calls from d3d8 supply D3DFMT_UNKNOWN */
597 HRESULT WINAPI
IWineD3DImpl_EnumAdapterModes(IWineD3D
*iface
, UINT Adapter
, D3DFORMAT Format
, UINT Mode
, D3DDISPLAYMODE
* pMode
) {
598 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
599 TRACE_(d3d_caps
)("(%p}->(Adapter:%d, mode:%d, pMode:%p, format:%s)\n", This
, Adapter
, Mode
, pMode
, debug_d3dformat(Format
));
601 /* Validate the parameters as much as possible */
603 Adapter
>= IWineD3DImpl_GetAdapterCount(iface
) ||
604 Mode
>= IWineD3DImpl_GetAdapterModeCount(iface
, Adapter
, Format
)) {
605 return D3DERR_INVALIDCALL
;
608 if (Adapter
== 0) { /* Display */
609 #if !defined( DEBUG_SINGLE_MODE )
613 /* Work out the current screen bpp */
614 HDC hdc
= CreateDCA("DISPLAY", NULL
, NULL
, NULL
);
615 int bpp
= GetDeviceCaps(hdc
, BITSPIXEL
);
618 /* If we are filtering to a specific format, then need to skip all unrelated
619 modes, but if mode is irrelevant, then we can use the index directly */
620 if (Format
== D3DFMT_UNKNOWN
)
626 DEVMODEW DevModeWtmp
;
629 while (i
<(Mode
+1) && EnumDisplaySettingsExW(NULL
, j
, &DevModeWtmp
, 0)) {
636 case D3DFMT_X8R8G8B8
:
637 case D3DFMT_A8R8G8B8
:
638 if (min(DevModeWtmp
.dmBitsPerPel
, bpp
) == 32) i
++;
639 if (min(DevModeWtmp
.dmBitsPerPel
, bpp
) == 24) i
++;
641 case D3DFMT_X1R5G5B5
:
642 case D3DFMT_A1R5G5B5
:
644 if (min(DevModeWtmp
.dmBitsPerPel
, bpp
) == 16) i
++;
647 /* Skip other modes as they do not match requested format */
654 /* Now get the display mode via the calculated index */
655 if (EnumDisplaySettingsExW(NULL
, ModeIdx
, &DevModeW
, 0))
657 pMode
->Width
= DevModeW
.dmPelsWidth
;
658 pMode
->Height
= DevModeW
.dmPelsHeight
;
659 bpp
= min(DevModeW
.dmBitsPerPel
, bpp
);
660 pMode
->RefreshRate
= D3DADAPTER_DEFAULT
;
661 if (DevModeW
.dmFields
&DM_DISPLAYFREQUENCY
)
663 pMode
->RefreshRate
= DevModeW
.dmDisplayFrequency
;
666 if (Format
== D3DFMT_UNKNOWN
)
669 case 8: pMode
->Format
= D3DFMT_R3G3B2
; break;
670 case 16: pMode
->Format
= D3DFMT_R5G6B5
; break;
671 case 24: /* pMode->Format = D3DFMT_R5G6B5; break;*/ /* Make 24bit appear as 32 bit */
672 case 32: pMode
->Format
= D3DFMT_A8R8G8B8
; break;
673 default: pMode
->Format
= D3DFMT_UNKNOWN
;
676 pMode
->Format
= Format
;
681 TRACE_(d3d_caps
)("Requested mode out of range %d\n", Mode
);
682 return D3DERR_INVALIDCALL
;
686 /* Return one setting of the format requested */
687 if (Mode
> 0) return D3DERR_INVALIDCALL
;
690 pMode
->RefreshRate
= D3DADAPTER_DEFAULT
;
691 pMode
->Format
= (Format
==D3DFMT_UNKNOWN
)?D3DFMT_A8R8G8B8
:Format
;
694 TRACE_(d3d_caps
)("W %d H %d rr %d fmt (%x - %s) bpp %u\n", pMode
->Width
, pMode
->Height
,
695 pMode
->RefreshRate
, pMode
->Format
, debug_d3dformat(pMode
->Format
), bpp
);
698 FIXME_(d3d_caps
)("Adapter not primary display\n");
704 HRESULT WINAPI
IWineD3DImpl_GetAdapterDisplayMode(IWineD3D
*iface
, UINT Adapter
, D3DDISPLAYMODE
* pMode
) {
705 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
706 TRACE_(d3d_caps
)("(%p}->(Adapter: %d, pMode: %p)\n", This
, Adapter
, pMode
);
709 Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
710 return D3DERR_INVALIDCALL
;
713 if (Adapter
== 0) { /* Display */
717 EnumDisplaySettingsExW(NULL
, (DWORD
)-1, &DevModeW
, 0);
718 pMode
->Width
= DevModeW
.dmPelsWidth
;
719 pMode
->Height
= DevModeW
.dmPelsHeight
;
720 bpp
= DevModeW
.dmBitsPerPel
;
721 pMode
->RefreshRate
= D3DADAPTER_DEFAULT
;
722 if (DevModeW
.dmFields
&DM_DISPLAYFREQUENCY
)
724 pMode
->RefreshRate
= DevModeW
.dmDisplayFrequency
;
728 case 8: pMode
->Format
= D3DFMT_R3G3B2
; break;
729 case 16: pMode
->Format
= D3DFMT_R5G6B5
; break;
730 case 24: /*pMode->Format = D3DFMT_R5G6B5; break;*/ /* Make 24bit appear as 32 bit */
731 case 32: pMode
->Format
= D3DFMT_A8R8G8B8
; break;
732 default: pMode
->Format
= D3DFMT_UNKNOWN
;
736 FIXME_(d3d_caps
)("Adapter not primary display\n");
739 TRACE_(d3d_caps
)("returning w:%d, h:%d, ref:%d, fmt:%s\n", pMode
->Width
,
740 pMode
->Height
, pMode
->RefreshRate
, debug_d3dformat(pMode
->Format
));
744 /* Note due to structure differences between dx8 and dx9 D3DADAPTER_IDENTIFIER,
745 and fields being inserted in the middle, a new structure is used in place */
746 HRESULT WINAPI
IWineD3DImpl_GetAdapterIdentifier(IWineD3D
*iface
, UINT Adapter
, DWORD Flags
,
747 WINED3DADAPTER_IDENTIFIER
* pIdentifier
) {
748 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
750 TRACE_(d3d_caps
)("(%p}->(Adapter: %d, Flags: %lx, pId=%p)\n", This
, Adapter
, Flags
, pIdentifier
);
752 if (Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
753 return D3DERR_INVALIDCALL
;
756 if (Adapter
== 0) { /* Display - only device supported for now */
758 BOOL isGLInfoValid
= This
->isGLInfoValid
;
760 /* FillGLCaps updates gl_info, but we only want to store and
761 reuse the values once we have a context which is valid. Values from
762 a temporary context may differ from the final ones */
763 if (isGLInfoValid
== FALSE
) {
765 /* If we don't know the device settings, go query them now via a
767 WineD3D_Context
* ctx
= WineD3D_CreateFakeGLContext();
769 isGLInfoValid
= IWineD3DImpl_FillGLCaps(&This
->gl_info
, ctx
->display
);
770 WineD3D_ReleaseFakeGLContext(ctx
);
774 /* If it worked, return the information requested */
776 TRACE_(d3d_caps
)("device/Vendor Name and Version detection using FillGLCaps\n");
777 strcpy(pIdentifier
->Driver
, "Display");
778 strcpy(pIdentifier
->Description
, "Direct3D HAL");
780 /* Note dx8 doesn't supply a DeviceName */
781 if (NULL
!= pIdentifier
->DeviceName
) strcpy(pIdentifier
->DeviceName
, "\\\\.\\DISPLAY"); /* FIXME: May depend on desktop? */
782 pIdentifier
->DriverVersion
->u
.HighPart
= 0xa;
783 pIdentifier
->DriverVersion
->u
.LowPart
= This
->gl_info
.gl_driver_version
;
784 *(pIdentifier
->VendorId
) = This
->gl_info
.gl_vendor
;
785 *(pIdentifier
->DeviceId
) = This
->gl_info
.gl_card
;
786 *(pIdentifier
->SubSysId
) = 0;
787 *(pIdentifier
->Revision
) = 0;
791 /* If it failed, return dummy values from an NVidia driver */
792 WARN_(d3d_caps
)("Cannot get GLCaps for device/Vendor Name and Version detection using FillGLCaps, currently using NVIDIA identifiers\n");
793 strcpy(pIdentifier
->Driver
, "Display");
794 strcpy(pIdentifier
->Description
, "Direct3D HAL");
795 if (NULL
!= pIdentifier
->DeviceName
) strcpy(pIdentifier
->DeviceName
, "\\\\.\\DISPLAY"); /* FIXME: May depend on desktop? */
796 pIdentifier
->DriverVersion
->u
.HighPart
= 0xa;
797 pIdentifier
->DriverVersion
->u
.LowPart
= MAKEDWORD_VERSION(53, 96); /* last Linux Nvidia drivers */
798 *(pIdentifier
->VendorId
) = VENDOR_NVIDIA
;
799 *(pIdentifier
->DeviceId
) = CARD_NVIDIA_GEFORCE4_TI4600
;
800 *(pIdentifier
->SubSysId
) = 0;
801 *(pIdentifier
->Revision
) = 0;
804 /*FIXME: memcpy(&pIdentifier->DeviceIdentifier, ??, sizeof(??GUID)); */
805 if (Flags
& D3DENUM_NO_WHQL_LEVEL
) {
806 *(pIdentifier
->WHQLLevel
) = 0;
808 *(pIdentifier
->WHQLLevel
) = 1;
812 FIXME_(d3d_caps
)("Adapter not primary display\n");
818 HRESULT WINAPI
IWineD3DImpl_CheckDepthStencilMatch(IWineD3D
*iface
, UINT Adapter
, D3DDEVTYPE DeviceType
,
819 D3DFORMAT AdapterFormat
, D3DFORMAT RenderTargetFormat
, D3DFORMAT DepthStencilFormat
) {
820 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
821 WARN_(d3d_caps
)("(%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), AdptFmt:(%x,%s), RendrTgtFmt:(%x,%s), DepthStencilFmt:(%x,%s))\n",
823 DeviceType
, debug_d3ddevicetype(DeviceType
),
824 AdapterFormat
, debug_d3dformat(AdapterFormat
),
825 RenderTargetFormat
, debug_d3dformat(RenderTargetFormat
),
826 DepthStencilFormat
, debug_d3dformat(DepthStencilFormat
));
828 if (Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
829 return D3DERR_INVALIDCALL
;
835 HRESULT WINAPI
IWineD3DImpl_CheckDeviceMultiSampleType(IWineD3D
*iface
,
836 UINT Adapter
, D3DDEVTYPE DeviceType
, D3DFORMAT SurfaceFormat
,
837 BOOL Windowed
, D3DMULTISAMPLE_TYPE MultiSampleType
, DWORD
* pQualityLevels
) {
839 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
840 TRACE_(d3d_caps
)("(%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), SurfFmt:(%x,%s), Win?%d, MultiSamp:%x, pQual:%p)\n",
843 DeviceType
, debug_d3ddevicetype(DeviceType
),
844 SurfaceFormat
, debug_d3dformat(SurfaceFormat
),
849 if (Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
850 return D3DERR_INVALIDCALL
;
853 if (pQualityLevels
!= NULL
) {
854 static int s_single_shot
= 0;
855 if (!s_single_shot
) {
856 FIXME("Quality levels unsupported at present\n");
859 *pQualityLevels
= 1; /* Guess at a value! */
862 if (D3DMULTISAMPLE_NONE
== MultiSampleType
)
864 return D3DERR_NOTAVAILABLE
;
867 HRESULT WINAPI
IWineD3DImpl_CheckDeviceType(IWineD3D
*iface
,
868 UINT Adapter
, D3DDEVTYPE CheckType
, D3DFORMAT DisplayFormat
,
869 D3DFORMAT BackBufferFormat
, BOOL Windowed
) {
871 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
872 TRACE_(d3d_caps
)("(%p)-> (STUB) (Adptr:%d, CheckType:(%x,%s), DispFmt:(%x,%s), BackBuf:(%x,%s), Win?%d): stub\n",
875 CheckType
, debug_d3ddevicetype(CheckType
),
876 DisplayFormat
, debug_d3dformat(DisplayFormat
),
877 BackBufferFormat
, debug_d3dformat(BackBufferFormat
),
880 if (Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
881 return D3DERR_INVALIDCALL
;
884 switch (DisplayFormat
) {
885 /*case D3DFMT_R5G6B5:*/
887 return D3DERR_NOTAVAILABLE
;
894 HRESULT WINAPI
IWineD3DImpl_CheckDeviceFormat(IWineD3D
*iface
,
895 UINT Adapter
, D3DDEVTYPE DeviceType
, D3DFORMAT AdapterFormat
,
896 DWORD Usage
, D3DRESOURCETYPE RType
, D3DFORMAT CheckFormat
) {
897 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
898 TRACE_(d3d_caps
)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), AdptFmt:(%u,%s), Use:(%lu,%s), ResTyp:(%x,%s), CheckFmt:(%u,%s)) ",
901 DeviceType
, debug_d3ddevicetype(DeviceType
),
902 AdapterFormat
, debug_d3dformat(AdapterFormat
),
903 Usage
, debug_d3dusage(Usage
),
904 RType
, debug_d3dresourcetype(RType
),
905 CheckFormat
, debug_d3dformat(CheckFormat
));
907 if (Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
908 return D3DERR_INVALIDCALL
;
911 if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC
)) {
912 switch (CheckFormat
) {
916 TRACE_(d3d_caps
)("[OK]\n");
919 break; /* Avoid compiler warnings */
923 switch (CheckFormat
) {
925 * check supported using GL_SUPPORT
936 /*case D3DFMT_R5G6B5: */
937 /*case D3DFMT_X1R5G5B5:*/
938 /*case D3DFMT_A1R5G5B5: */
939 /*case D3DFMT_A4R4G4B4:*/
946 /*case D3DFMT_X8R8G8B8:*/
947 case D3DFMT_A8R3G3B2
:
964 case D3DFMT_X8L8V8U8
:
965 case D3DFMT_Q8W8V8U8
:
966 case D3DFMT_W11V11U10
:
969 * currently hard to support
974 /* Since we do not support these formats right now, don't pretend to. */
975 TRACE_(d3d_caps
)("[FAILED]\n");
976 return D3DERR_NOTAVAILABLE
;
981 TRACE_(d3d_caps
)("[OK]\n");
985 HRESULT WINAPI
IWineD3DImpl_CheckDeviceFormatConversion(IWineD3D
*iface
, UINT Adapter
, D3DDEVTYPE DeviceType
, D3DFORMAT SourceFormat
, D3DFORMAT TargetFormat
) {
986 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
988 FIXME_(d3d_caps
)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), SrcFmt:(%u,%s), TgtFmt:(%u,%s))",
991 DeviceType
, debug_d3ddevicetype(DeviceType
),
992 SourceFormat
, debug_d3dformat(SourceFormat
),
993 TargetFormat
, debug_d3dformat(TargetFormat
));
997 /* Note: d3d8 passes in a pointer to a D3DCAPS8 structure, which is a true
998 subset of a D3DCAPS9 structure. However, it has to come via a void *
999 as the d3d8 interface cannot import the d3d9 header */
1000 HRESULT WINAPI
IWineD3DImpl_GetDeviceCaps(IWineD3D
*iface
, UINT Adapter
, D3DDEVTYPE DeviceType
, WINED3DCAPS
* pCapsIn
) {
1002 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
1003 BOOL gotContext
= FALSE
;
1004 GLint gl_tex_size
= 0;
1005 WineD3D_Context
*fake_ctx
= NULL
;
1006 D3DCAPS9
*pCaps
= (D3DCAPS9
*)pCapsIn
;
1008 TRACE_(d3d_caps
)("(%p)->(Adptr:%d, DevType: %x, pCaps: %p)\n", This
, Adapter
, DeviceType
, pCaps
);
1010 if (Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
1011 return D3DERR_INVALIDCALL
;
1014 /* Note: GL seems to trap if GetDeviceCaps is called before any HWND's created
1015 ie there is no GL Context - Get a default rendering context to enable the
1016 function query some info from GL */
1017 if (glXGetCurrentContext() == NULL
) {
1018 fake_ctx
= WineD3D_CreateFakeGLContext();
1019 if (NULL
!= fake_ctx
) gotContext
= TRUE
;
1024 if (gotContext
== FALSE
) {
1026 FIXME_(d3d_caps
)("GetDeviceCaps called but no GL Context - Returning dummy values\n");
1028 pCaps
->MaxTextureBlendStages
= 2;
1029 pCaps
->MaxSimultaneousTextures
= 2;
1030 pCaps
->MaxUserClipPlanes
= 8;
1031 pCaps
->MaxActiveLights
= 8;
1032 pCaps
->MaxVertexBlendMatrices
= 0;
1033 pCaps
->MaxVertexBlendMatrixIndex
= 1;
1034 pCaps
->MaxAnisotropy
= 0;
1035 pCaps
->MaxPointSize
= 255.0;
1037 glGetIntegerv(GL_MAX_TEXTURE_SIZE
, &gl_tex_size
);
1040 /* If we don't know the device settings, go query them now */
1041 if (This
->isGLInfoValid
== FALSE
) {
1042 BOOL rc
= IWineD3DImpl_FillGLCaps(&This
->gl_info
, NULL
);
1044 /* If we are running off a real context, save the values */
1045 if (rc
&& ((NULL
!= fake_ctx
))) This
->isGLInfoValid
= TRUE
;
1048 /* ------------------------------------------------
1049 The following fields apply to both d3d8 and d3d9
1050 ------------------------------------------------ */
1051 pCaps
->DeviceType
= (DeviceType
== D3DDEVTYPE_HAL
) ? D3DDEVTYPE_HAL
: D3DDEVTYPE_REF
; /* Not quite true, but use h/w supported by opengl I suppose */
1052 pCaps
->AdapterOrdinal
= Adapter
;
1055 pCaps
->Caps2
= D3DCAPS2_CANRENDERWINDOWED
;
1056 pCaps
->Caps3
= D3DDEVCAPS_HWTRANSFORMANDLIGHT
;
1057 pCaps
->PresentationIntervals
= D3DPRESENT_INTERVAL_IMMEDIATE
;
1059 pCaps
->CursorCaps
= 0;
1061 pCaps
->DevCaps
= D3DDEVCAPS_DRAWPRIMTLVERTEX
|
1062 D3DDEVCAPS_HWTRANSFORMANDLIGHT
|
1063 D3DDEVCAPS_PUREDEVICE
;
1065 pCaps
->PrimitiveMiscCaps
= D3DPMISCCAPS_CULLCCW
|
1066 D3DPMISCCAPS_CULLCW
|
1067 D3DPMISCCAPS_COLORWRITEENABLE
|
1068 D3DPMISCCAPS_CLIPTLVERTS
|
1069 D3DPMISCCAPS_CLIPPLANESCALEDPOINTS
|
1071 /*NOT: D3DPMISCCAPS_TSSARGTEMP*/
1073 pCaps
->RasterCaps
= D3DPRASTERCAPS_DITHER
|
1074 D3DPRASTERCAPS_PAT
|
1075 D3DPRASTERCAPS_WFOG
|
1076 D3DPRASTERCAPS_ZFOG
|
1077 D3DPRASTERCAPS_FOGVERTEX
|
1078 D3DPRASTERCAPS_FOGTABLE
|
1079 D3DPRASTERCAPS_FOGRANGE
;
1081 if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC
)) {
1082 pCaps
->RasterCaps
|= D3DPRASTERCAPS_ANISOTROPY
;
1085 D3DPRASTERCAPS_MIPMAPLODBIAS
1086 D3DPRASTERCAPS_ZBIAS
1087 D3DPRASTERCAPS_COLORPERSPECTIVE
1088 D3DPRASTERCAPS_STRETCHBLTMULTISAMPLE
1089 D3DPRASTERCAPS_ANTIALIASEDGES
1090 D3DPRASTERCAPS_ZBUFFERLESSHSR
1091 D3DPRASTERCAPS_WBUFFER */
1093 pCaps
->ZCmpCaps
= D3DPCMPCAPS_ALWAYS
|
1095 D3DPCMPCAPS_GREATER
|
1096 D3DPCMPCAPS_GREATEREQUAL
|
1098 D3DPCMPCAPS_LESSEQUAL
|
1100 D3DPCMPCAPS_NOTEQUAL
;
1102 pCaps
->SrcBlendCaps
= 0xFFFFFFFF; /*FIXME: Tidy up later */
1103 pCaps
->DestBlendCaps
= 0xFFFFFFFF; /*FIXME: Tidy up later */
1104 pCaps
->AlphaCmpCaps
= 0xFFFFFFFF; /*FIXME: Tidy up later */
1106 pCaps
->ShadeCaps
= D3DPSHADECAPS_SPECULARGOURAUDRGB
|
1107 D3DPSHADECAPS_COLORGOURAUDRGB
;
1109 pCaps
->TextureCaps
= D3DPTEXTURECAPS_ALPHA
|
1110 D3DPTEXTURECAPS_ALPHAPALETTE
|
1111 D3DPTEXTURECAPS_POW2
|
1112 D3DPTEXTURECAPS_VOLUMEMAP
|
1113 D3DPTEXTURECAPS_MIPMAP
|
1114 D3DPTEXTURECAPS_PROJECTED
;
1116 if (GL_SUPPORT(ARB_TEXTURE_CUBE_MAP
)) {
1117 pCaps
->TextureCaps
|= D3DPTEXTURECAPS_CUBEMAP
|
1118 D3DPTEXTURECAPS_MIPCUBEMAP
|
1119 D3DPTEXTURECAPS_CUBEMAP_POW2
;
1122 pCaps
->TextureFilterCaps
= D3DPTFILTERCAPS_MAGFLINEAR
|
1123 D3DPTFILTERCAPS_MAGFPOINT
|
1124 D3DPTFILTERCAPS_MINFLINEAR
|
1125 D3DPTFILTERCAPS_MINFPOINT
|
1126 D3DPTFILTERCAPS_MIPFLINEAR
|
1127 D3DPTFILTERCAPS_MIPFPOINT
;
1129 pCaps
->CubeTextureFilterCaps
= 0;
1130 pCaps
->VolumeTextureFilterCaps
= 0;
1132 pCaps
->TextureAddressCaps
= D3DPTADDRESSCAPS_BORDER
|
1133 D3DPTADDRESSCAPS_CLAMP
|
1134 D3DPTADDRESSCAPS_WRAP
;
1136 if (GL_SUPPORT(ARB_TEXTURE_BORDER_CLAMP
)) {
1137 pCaps
->TextureAddressCaps
|= D3DPTADDRESSCAPS_BORDER
;
1139 if (GL_SUPPORT(ARB_TEXTURE_MIRRORED_REPEAT
)) {
1140 pCaps
->TextureAddressCaps
|= D3DPTADDRESSCAPS_MIRROR
;
1142 if (GL_SUPPORT(ATI_TEXTURE_MIRROR_ONCE
)) {
1143 pCaps
->TextureAddressCaps
|= D3DPTADDRESSCAPS_MIRRORONCE
;
1146 pCaps
->VolumeTextureAddressCaps
= 0;
1148 pCaps
->LineCaps
= D3DLINECAPS_TEXTURE
|
1152 D3DLINECAPS_ALPHACMP
1155 pCaps
->MaxTextureWidth
= gl_tex_size
;
1156 pCaps
->MaxTextureHeight
= gl_tex_size
;
1158 pCaps
->MaxVolumeExtent
= 0;
1160 pCaps
->MaxTextureRepeat
= 32768;
1161 pCaps
->MaxTextureAspectRatio
= 32768;
1162 pCaps
->MaxVertexW
= 1.0;
1164 pCaps
->GuardBandLeft
= 0;
1165 pCaps
->GuardBandTop
= 0;
1166 pCaps
->GuardBandRight
= 0;
1167 pCaps
->GuardBandBottom
= 0;
1169 pCaps
->ExtentsAdjust
= 0;
1171 pCaps
->StencilCaps
= D3DSTENCILCAPS_DECRSAT
|
1172 D3DSTENCILCAPS_INCRSAT
|
1173 D3DSTENCILCAPS_INVERT
|
1174 D3DSTENCILCAPS_KEEP
|
1175 D3DSTENCILCAPS_REPLACE
|
1176 D3DSTENCILCAPS_ZERO
;
1177 if (GL_SUPPORT(EXT_STENCIL_WRAP
)) {
1178 pCaps
->StencilCaps
|= D3DSTENCILCAPS_DECR
|
1179 D3DSTENCILCAPS_INCR
;
1182 pCaps
->FVFCaps
= D3DFVFCAPS_PSIZE
| 0x0008; /* 8 texture coords */
1184 pCaps
->TextureOpCaps
= D3DTEXOPCAPS_ADD
|
1185 D3DTEXOPCAPS_ADDSIGNED
|
1186 D3DTEXOPCAPS_ADDSIGNED2X
|
1187 D3DTEXOPCAPS_MODULATE
|
1188 D3DTEXOPCAPS_MODULATE2X
|
1189 D3DTEXOPCAPS_MODULATE4X
|
1190 D3DTEXOPCAPS_SELECTARG1
|
1191 D3DTEXOPCAPS_SELECTARG2
|
1192 D3DTEXOPCAPS_DISABLE
;
1193 #if defined(GL_VERSION_1_3)
1194 pCaps
->TextureOpCaps
|= D3DTEXOPCAPS_DOTPRODUCT3
|
1195 D3DTEXOPCAPS_SUBTRACT
;
1197 if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE
) ||
1198 GL_SUPPORT(EXT_TEXTURE_ENV_COMBINE
) ||
1199 GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4
)) {
1200 pCaps
->TextureOpCaps
|= D3DTEXOPCAPS_BLENDDIFFUSEALPHA
|
1201 D3DTEXOPCAPS_BLENDTEXTUREALPHA
|
1202 D3DTEXOPCAPS_BLENDFACTORALPHA
|
1203 D3DTEXOPCAPS_BLENDCURRENTALPHA
|
1206 if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4
)) {
1207 pCaps
->TextureOpCaps
|= D3DTEXOPCAPS_ADDSMOOTH
|
1208 D3DTEXOPCAPS_MULTIPLYADD
|
1209 D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR
|
1210 D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA
|
1211 D3DTEXOPCAPS_BLENDTEXTUREALPHAPM
;
1215 pCaps
->TextureOpCaps
|= D3DTEXOPCAPS_BUMPENVMAP
;
1217 D3DTEXOPCAPS_BUMPENVMAPLUMINANCE
1218 D3DTEXOPCAPS_PREMODULATE */
1224 #if defined(GL_VERSION_1_3)
1225 glGetIntegerv(GL_MAX_TEXTURE_UNITS
, &gl_max
);
1227 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB
, &gl_max
);
1229 TRACE_(d3d_caps
)("GLCaps: GL_MAX_TEXTURE_UNITS_ARB=%d\n", gl_max
);
1230 pCaps
->MaxTextureBlendStages
= min(8, gl_max
);
1231 pCaps
->MaxSimultaneousTextures
= min(8, gl_max
);
1233 glGetIntegerv(GL_MAX_CLIP_PLANES
, &gl_max
);
1234 pCaps
->MaxUserClipPlanes
= min(D3DMAXUSERCLIPPLANES
, gl_max
);
1235 TRACE_(d3d_caps
)("GLCaps: GL_MAX_CLIP_PLANES=%ld\n", pCaps
->MaxUserClipPlanes
);
1237 glGetIntegerv(GL_MAX_LIGHTS
, &gl_max
);
1238 pCaps
->MaxActiveLights
= gl_max
;
1239 TRACE_(d3d_caps
)("GLCaps: GL_MAX_LIGHTS=%ld\n", pCaps
->MaxActiveLights
);
1241 if (GL_SUPPORT(ARB_VERTEX_BLEND
)) {
1242 glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB
, &gl_max
);
1243 pCaps
->MaxVertexBlendMatrices
= gl_max
;
1244 pCaps
->MaxVertexBlendMatrixIndex
= 1;
1246 pCaps
->MaxVertexBlendMatrices
= 0;
1247 pCaps
->MaxVertexBlendMatrixIndex
= 1;
1250 if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC
)) {
1251 glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT
, &gl_max
);
1252 pCaps
->MaxAnisotropy
= gl_max
;
1254 pCaps
->MaxAnisotropy
= 0;
1257 glGetFloatv(GL_POINT_SIZE_RANGE
, &gl_float
);
1258 pCaps
->MaxPointSize
= gl_float
;
1261 pCaps
->VertexProcessingCaps
= D3DVTXPCAPS_DIRECTIONALLIGHTS
|
1262 D3DVTXPCAPS_MATERIALSOURCE7
|
1263 D3DVTXPCAPS_POSITIONALLIGHTS
|
1264 D3DVTXPCAPS_LOCALVIEWER
|
1267 D3DVTXPCAPS_TWEENING */
1269 pCaps
->MaxPrimitiveCount
= 0xFFFFFFFF;
1270 pCaps
->MaxVertexIndex
= 0xFFFFFFFF;
1271 pCaps
->MaxStreams
= MAX_STREAMS
;
1272 pCaps
->MaxStreamStride
= 1024;
1274 if (((vs_mode
== VS_HW
) && GL_SUPPORT(ARB_VERTEX_PROGRAM
)) || (vs_mode
== VS_SW
) || (DeviceType
== D3DDEVTYPE_REF
)) {
1275 pCaps
->VertexShaderVersion
= D3DVS_VERSION(1,1);
1277 if (This
->gl_info
.gl_vendor
== VENDOR_MESA
||
1278 This
->gl_info
.gl_vendor
== VENDOR_WINE
) {
1279 pCaps
->MaxVertexShaderConst
= 95;
1281 pCaps
->MaxVertexShaderConst
= WINED3D_VSHADER_MAX_CONSTANTS
;
1284 pCaps
->VertexShaderVersion
= 0;
1285 pCaps
->MaxVertexShaderConst
= 0;
1288 if ((ps_mode
== PS_HW
) && GL_SUPPORT(ARB_FRAGMENT_PROGRAM
) && (DeviceType
!= D3DDEVTYPE_REF
)) {
1289 pCaps
->PixelShaderVersion
= D3DPS_VERSION(1,4);
1290 pCaps
->MaxPixelShaderValue
= 1.0;
1292 pCaps
->PixelShaderVersion
= 0;
1293 pCaps
->MaxPixelShaderValue
= 0.0;
1296 /* ------------------------------------------------
1297 The following fields apply to d3d9 only
1298 ------------------------------------------------ */
1299 if (This
->dxVersion
> 8) {
1300 FIXME("Caps support for directx9 is nonexistent at the moment!\n");
1301 pCaps
->DevCaps2
= 0;
1302 pCaps
->MaxNpatchTessellationLevel
= 0;
1303 pCaps
->MasterAdapterOrdinal
= 0;
1304 pCaps
->AdapterOrdinalInGroup
= 0;
1305 pCaps
->NumberOfAdaptersInGroup
= 1;
1306 pCaps
->DeclTypes
= 0;
1307 pCaps
->NumSimultaneousRTs
= 0;
1308 pCaps
->StretchRectFilterCaps
= 0;
1309 pCaps
->VS20Caps
.Caps
= 0;
1310 pCaps
->PS20Caps
.Caps
= 0;
1311 pCaps
->VertexTextureFilterCaps
= 0;
1312 pCaps
->MaxVShaderInstructionsExecuted
= 0;
1313 pCaps
->MaxPShaderInstructionsExecuted
= 0;
1314 pCaps
->MaxVertexShader30InstructionSlots
= 0;
1315 pCaps
->MaxPixelShader30InstructionSlots
= 0;
1318 /* If we created a dummy context, throw it away */
1319 if (NULL
!= fake_ctx
) WineD3D_ReleaseFakeGLContext(fake_ctx
);
1323 /* Note due to structure differences between dx8 and dx9 D3DPRESENT_PARAMETERS,
1324 and fields being inserted in the middle, a new structure is used in place */
1325 HRESULT WINAPI
IWineD3DImpl_CreateDevice(IWineD3D
*iface
, UINT Adapter
, D3DDEVTYPE DeviceType
, HWND hFocusWindow
,
1326 DWORD BehaviourFlags
, WINED3DPRESENT_PARAMETERS
* pPresentationParameters
,
1327 IWineD3DDevice
** ppReturnedDeviceInterface
, IUnknown
*parent
, D3DCB_CREATERENDERTARGETFN D3DCB_CreateRenderTarget
) {
1331 IWineD3DDeviceImpl
*object
= NULL
;
1332 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
1334 XVisualInfo
template;
1336 /* Validate the adapter number */
1337 if (Adapter
>= IWineD3D_GetAdapterCount(iface
)) {
1338 return D3DERR_INVALIDCALL
;
1341 /* Create a WineD3DDevice object */
1342 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IWineD3DDeviceImpl
));
1343 *ppReturnedDeviceInterface
= (IWineD3DDevice
*)object
;
1344 TRACE("Created WineD3DDevice object @ %p \n", object
);
1345 if (NULL
== object
) {
1346 return D3DERR_OUTOFVIDEOMEMORY
;
1349 /* Set up initial COM information */
1350 object
->lpVtbl
= &IWineD3DDevice_Vtbl
;
1352 object
->wineD3D
= iface
;
1353 IWineD3D_AddRef(object
->wineD3D
);
1354 object
->parent
= parent
;
1356 TRACE("(%p)->(Adptr:%d, DevType: %x, FocusHwnd: %p, BehFlags: %lx, PresParms: %p, RetDevInt: %p)\n", This
, Adapter
, DeviceType
,
1357 hFocusWindow
, BehaviourFlags
, pPresentationParameters
, ppReturnedDeviceInterface
);
1358 TRACE("(%p)->(DepthStencil:(%u,%s), BackBufferFormat:(%u,%s))\n", This
,
1359 *(pPresentationParameters
->AutoDepthStencilFormat
), debug_d3dformat(*(pPresentationParameters
->AutoDepthStencilFormat
)),
1360 *(pPresentationParameters
->BackBufferFormat
), debug_d3dformat(*(pPresentationParameters
->BackBufferFormat
)));
1362 /* Save the creation parameters */
1363 object
->createParms
.AdapterOrdinal
= Adapter
;
1364 object
->createParms
.DeviceType
= DeviceType
;
1365 object
->createParms
.hFocusWindow
= hFocusWindow
;
1366 object
->createParms
.BehaviorFlags
= BehaviourFlags
;
1368 /* Initialize other useful values */
1369 object
->presentParms
.BackBufferCount
= 1; /* Opengl only supports one? */
1370 object
->adapterNo
= Adapter
;
1371 object
->devType
= DeviceType
;
1373 /* Setup hwnd we are using, plus which display this equates to */
1374 whichHWND
= *(pPresentationParameters
->hDeviceWindow
);
1376 whichHWND
= hFocusWindow
;
1378 object
->win_handle
= whichHWND
;
1379 object
->win
= (Window
)GetPropA( whichHWND
, "__wine_x11_whole_window" );
1380 hDc
= GetDC(whichHWND
);
1381 object
->display
= get_display(hDc
);
1382 ReleaseDC(whichHWND
, hDc
);
1384 /* FIXME: Use for dx8 code eventually too! */
1385 /* Deliberately no indentation here, as this if will be removed when dx8 support merged in */
1386 if (This
->dxVersion
> 8) {
1388 /* Create a context based off the properties of the existing visual */
1389 /* Note the visual is chosen as the window is created and the glcontext cannot
1390 use different properties after that point in time. FIXME: How to handle when requested format
1391 doesn't match actual visual? Cannot choose one here - code removed as it ONLY works if the one
1392 it chooses is identical to the one already being used! */
1393 /* FIXME: Handle stencil appropriately via EnableAutoDepthStencil / AutoDepthStencilFormat */
1395 template.visualid
= (VisualID
)GetPropA(GetDesktopWindow(), "__wine_x11_visual_id");
1396 object
->visInfo
= XGetVisualInfo(object
->display
, VisualIDMask
, &template, &num
);
1397 if (NULL
== object
->visInfo
) {
1398 ERR("cannot really get XVisual\n");
1400 return D3DERR_NOTAVAILABLE
;
1402 object
->glCtx
= glXCreateContext(object
->display
, object
->visInfo
, NULL
, GL_TRUE
);
1403 if (NULL
== object
->glCtx
) {
1404 ERR("cannot create glxContext\n");
1406 return D3DERR_NOTAVAILABLE
;
1410 if (object
->glCtx
== NULL
) {
1411 ERR("Error in context creation !\n");
1412 return D3DERR_INVALIDCALL
;
1414 TRACE("Context created (HWND=%p, glContext=%p, Window=%ld, VisInfo=%p)\n",
1415 whichHWND
, object
->glCtx
, object
->win
, object
->visInfo
);
1418 /* If not windowed, need to go fullscreen, and resize the HWND to the appropriate */
1420 if (!*(pPresentationParameters
->Windowed
)) {
1426 /* Get info on the current display setup */
1427 hdc
= CreateDCA("DISPLAY", NULL
, NULL
, NULL
);
1428 bpp
= GetDeviceCaps(hdc
, BITSPIXEL
);
1431 /* Change the display settings */
1432 memset(&devmode
, 0, sizeof(DEVMODEW
));
1433 devmode
.dmFields
= DM_BITSPERPEL
| DM_PELSWIDTH
| DM_PELSHEIGHT
;
1434 devmode
.dmBitsPerPel
= (bpp
>= 24) ? 32 : bpp
; /*Stupid XVidMode cannot change bpp D3DFmtGetBpp(object, pPresentationParameters->BackBufferFormat);*/
1435 devmode
.dmPelsWidth
= *(pPresentationParameters
->BackBufferWidth
);
1436 devmode
.dmPelsHeight
= *(pPresentationParameters
->BackBufferHeight
);
1437 MultiByteToWideChar(CP_ACP
, 0, "Gamers CG", -1, devmode
.dmDeviceName
, CCHDEVICENAME
);
1438 ChangeDisplaySettingsExW(devmode
.dmDeviceName
, &devmode
, object
->win_handle
, CDS_FULLSCREEN
, NULL
);
1440 /* Make popup window */
1441 SetWindowLongA(whichHWND
, GWL_STYLE
, WS_POPUP
);
1442 SetWindowPos(object
->win_handle
, HWND_TOP
, 0, 0,
1443 *(pPresentationParameters
->BackBufferWidth
),
1444 *(pPresentationParameters
->BackBufferHeight
), SWP_SHOWWINDOW
| SWP_FRAMECHANGED
);
1447 /* MSDN: If Windowed is TRUE and either of the BackBufferWidth/Height values is zero,
1448 then the corresponding dimension of the client area of the hDeviceWindow
1449 (or the focus window, if hDeviceWindow is NULL) is taken. */
1450 if (*(pPresentationParameters
->Windowed
) &&
1451 ((*(pPresentationParameters
->BackBufferWidth
) == 0) ||
1452 (*(pPresentationParameters
->BackBufferHeight
) == 0))) {
1455 GetClientRect(whichHWND
, &Rect
);
1457 if (*(pPresentationParameters
->BackBufferWidth
) == 0) {
1458 *(pPresentationParameters
->BackBufferWidth
) = Rect
.right
;
1459 TRACE("Updating width to %d\n", *(pPresentationParameters
->BackBufferWidth
));
1461 if (*(pPresentationParameters
->BackBufferHeight
) == 0) {
1462 *(pPresentationParameters
->BackBufferHeight
) = Rect
.bottom
;
1463 TRACE("Updating height to %d\n", *(pPresentationParameters
->BackBufferHeight
));
1467 /* Save the presentation parms now filled in correctly */
1468 object
->presentParms
.BackBufferWidth
= *(pPresentationParameters
->BackBufferWidth
);
1469 object
->presentParms
.BackBufferHeight
= *(pPresentationParameters
->BackBufferHeight
);
1470 object
->presentParms
.BackBufferFormat
= *(pPresentationParameters
->BackBufferFormat
);
1471 object
->presentParms
.BackBufferCount
= *(pPresentationParameters
->BackBufferCount
);
1472 object
->presentParms
.MultiSampleType
= *(pPresentationParameters
->MultiSampleType
);
1473 object
->presentParms
.MultiSampleQuality
= *(pPresentationParameters
->MultiSampleQuality
);
1474 object
->presentParms
.SwapEffect
= *(pPresentationParameters
->SwapEffect
);
1475 object
->presentParms
.hDeviceWindow
= *(pPresentationParameters
->hDeviceWindow
);
1476 object
->presentParms
.Windowed
= *(pPresentationParameters
->Windowed
);
1477 object
->presentParms
.EnableAutoDepthStencil
= *(pPresentationParameters
->EnableAutoDepthStencil
);
1478 object
->presentParms
.AutoDepthStencilFormat
= *(pPresentationParameters
->AutoDepthStencilFormat
);
1479 object
->presentParms
.Flags
= *(pPresentationParameters
->Flags
);
1480 object
->presentParms
.FullScreen_RefreshRateInHz
= *(pPresentationParameters
->FullScreen_RefreshRateInHz
);
1481 object
->presentParms
.PresentationInterval
= *(pPresentationParameters
->PresentationInterval
);
1483 /* Creating the startup stateBlock - Note Special Case: 0 => Don't fill in yet! */
1484 IWineD3DDevice_CreateStateBlock((IWineD3DDevice
*)object
,
1485 (D3DSTATEBLOCKTYPE
) 0,
1486 (IWineD3DStateBlock
**)&object
->stateBlock
,
1487 NULL
); /* Note: No parent needed for initial internal stateblock */
1488 object
->updateStateBlock
= object
->stateBlock
;
1490 /* Setup surfaces for the backbuffer, frontbuffer and depthstencil buffer */
1491 TRACE("Creating initial device surfaces\n");
1493 /* We need to 'magic' either d3d8 or d3d9 surfaces for the front and backbuuffer
1494 but the respective CreateRenderTarget functions take a differing number of
1495 parms. Fix this by passing in a function to call which takes identical parms
1496 and handles the differences at the d3dx layer, and returns the IWineD3DSurface
1497 pointer rather than the created D3D8/9 one */
1498 D3DCB_CreateRenderTarget((IUnknown
*) parent
,
1499 *(pPresentationParameters
->BackBufferWidth
),
1500 *(pPresentationParameters
->BackBufferHeight
),
1501 *(pPresentationParameters
->BackBufferFormat
),
1502 *(pPresentationParameters
->MultiSampleType
),
1503 *(pPresentationParameters
->MultiSampleQuality
),
1505 (IWineD3DSurface
**) &object
->frontBuffer
,
1508 D3DCB_CreateRenderTarget((IUnknown
*) parent
,
1509 *(pPresentationParameters
->BackBufferWidth
),
1510 *(pPresentationParameters
->BackBufferHeight
),
1511 *(pPresentationParameters
->BackBufferFormat
),
1512 *(pPresentationParameters
->MultiSampleType
),
1513 *(pPresentationParameters
->MultiSampleQuality
),
1515 (IWineD3DSurface
**) &object
->backBuffer
,
1519 if (*(pPresentationParameters->EnableAutoDepthStencil)) {
1520 IWineD3DDevice_CreateDepthStencilSurface((IWineD3DDevice *) object,
1521 *(pPresentationParameters->BackBufferWidth),
1522 *(pPresentationParameters->BackBufferHeight),
1523 *(pPresentationParameters->AutoDepthStencilFormat,
1524 D3DMULTISAMPLE_NONE,
1525 (IWineD3DSurface *) &object->depthStencilBuffer);
1527 object->depthStencilBuffer = NULL;
1529 TRACE("FrontBuf @ %p, BackBuf @ %p, DepthStencil @ %p\n",object->frontBuffer, object->backBuffer, object->depthStencilBuffer);
1532 /* init the default renderTarget management */
1533 object
->drawable
= object
->win
;
1534 object
->render_ctx
= object
->glCtx
;
1535 object
->renderTarget
= object
->backBuffer
;
1537 IWineD3DSurface_AddRef((IWineD3DSurface
*) object
->renderTarget
);
1538 /* TODO: Depth Stencil support
1539 object->stencilBufferTarget = object->depthStencilBuffer;
1540 if (NULL != object->stencilBufferTarget) {
1541 IDirect3DSurface8Impl_AddRef((LPDIRECT3DSURFACE8) object->stencilBufferTarget);
1545 /* Set up some starting GL setup */
1548 if (glXMakeCurrent(object
->display
, object
->win
, object
->glCtx
) == False
) {
1549 ERR("Error in setting current context (context %p drawable %ld)!\n", object
->glCtx
, object
->win
);
1551 checkGLcall("glXMakeCurrent");
1553 /* Clear the screen */
1554 glClearColor(1.0, 0.0, 0.0, 0.0);
1555 checkGLcall("glClearColor");
1556 glColor3f(1.0, 1.0, 1.0);
1557 checkGLcall("glColor3f");
1559 glEnable(GL_LIGHTING
);
1560 checkGLcall("glEnable");
1562 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER
, GL_TRUE
);
1563 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);");
1565 glTexEnvf(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_COMBINE_EXT
);
1566 checkGLcall("glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);");
1568 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL
, GL_SEPARATE_SPECULAR_COLOR
);
1569 checkGLcall("glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);");
1572 * Initialize openGL extension related variables
1573 * with Default values
1575 This
->isGLInfoValid
= IWineD3DImpl_FillGLCaps(&This
->gl_info
, object
->display
);
1577 /* Setup all the devices defaults */
1578 IWineD3DStateBlock_InitStartupStateBlock((IWineD3DStateBlock
*)object
->stateBlock
);
1582 { /* Set a default viewport */
1586 vp
.Width
= *(pPresentationParameters
->BackBufferWidth
);
1587 vp
.Height
= *(pPresentationParameters
->BackBufferHeight
);
1590 IWineD3DDevice_SetViewport((IWineD3DDevice
*)object
, &vp
);
1593 /* Initialize the current view state */
1594 object
->modelview_valid
= 1;
1595 object
->proj_valid
= 0;
1596 object
->view_ident
= 1;
1597 object
->last_was_rhw
= 0;
1598 glGetIntegerv(GL_MAX_LIGHTS
, &object
->maxConcurrentLights
);
1599 TRACE("(%p,%d) All defaults now set up, leaving CreateDevice with %p\n", This
, Adapter
, object
);
1601 /* Clear the screen */
1602 IWineD3DDevice_Clear((IWineD3DDevice
*) object
, 0, NULL
, D3DCLEAR_STENCIL
|D3DCLEAR_ZBUFFER
|D3DCLEAR_TARGET
, 0x00, 1.0, 0);
1604 } /* End of FIXME: remove when dx8 merged in */
1609 HRESULT WINAPI
IWineD3DImpl_GetParent(IWineD3D
*iface
, IUnknown
**pParent
) {
1610 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
1611 IUnknown_AddRef(This
->parent
);
1612 *pParent
= This
->parent
;
1616 /**********************************************************
1617 * IUnknown parts follows
1618 **********************************************************/
1620 HRESULT WINAPI
IWineD3DImpl_QueryInterface(IWineD3D
*iface
,REFIID riid
,LPVOID
*ppobj
)
1622 return E_NOINTERFACE
;
1625 ULONG WINAPI
IWineD3DImpl_AddRef(IWineD3D
*iface
) {
1626 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
1627 ULONG refCount
= InterlockedIncrement(&This
->ref
);
1629 TRACE("(%p) : AddRef increasing from %ld\n", This
, refCount
- 1);
1633 ULONG WINAPI
IWineD3DImpl_Release(IWineD3D
*iface
) {
1634 IWineD3DImpl
*This
= (IWineD3DImpl
*)iface
;
1635 ULONG refCount
= InterlockedDecrement(&This
->ref
);
1637 TRACE("(%p) : Releasing from %ld\n", This
, refCount
+ 1);
1639 if (!refCount
) HeapFree(GetProcessHeap(), 0, This
);
1643 /**********************************************************
1644 * IWineD3D VTbl follows
1645 **********************************************************/
1647 IWineD3DVtbl IWineD3D_Vtbl
=
1649 IWineD3DImpl_QueryInterface
,
1650 IWineD3DImpl_AddRef
,
1651 IWineD3DImpl_Release
,
1652 IWineD3DImpl_GetParent
,
1653 IWineD3DImpl_GetAdapterCount
,
1654 IWineD3DImpl_RegisterSoftwareDevice
,
1655 IWineD3DImpl_GetAdapterMonitor
,
1656 IWineD3DImpl_GetAdapterModeCount
,
1657 IWineD3DImpl_EnumAdapterModes
,
1658 IWineD3DImpl_GetAdapterDisplayMode
,
1659 IWineD3DImpl_GetAdapterIdentifier
,
1660 IWineD3DImpl_CheckDeviceMultiSampleType
,
1661 IWineD3DImpl_CheckDepthStencilMatch
,
1662 IWineD3DImpl_CheckDeviceType
,
1663 IWineD3DImpl_CheckDeviceFormat
,
1664 IWineD3DImpl_CheckDeviceFormatConversion
,
1665 IWineD3DImpl_GetDeviceCaps
,
1666 IWineD3DImpl_CreateDevice